@prolibu-suite/cobalt-core 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (515) hide show
  1. package/custom-elements.json +8266 -5138
  2. package/dist/cjs/co-action-bar.cjs.entry.js +89 -0
  3. package/dist/cjs/co-app-shell.cjs.entry.js +2 -2
  4. package/dist/cjs/co-audio-player.cjs.entry.js +279 -0
  5. package/dist/cjs/co-avatar_2.cjs.entry.js +3 -3
  6. package/dist/cjs/co-badge.cjs.entry.js +1 -1
  7. package/dist/cjs/co-bottom-sheet.cjs.entry.js +3 -3
  8. package/dist/cjs/co-breadcrumb-item.cjs.entry.js +2 -2
  9. package/dist/cjs/co-breadcrumb.cjs.entry.js +1 -1
  10. package/dist/cjs/co-button-group.cjs.entry.js +2 -2
  11. package/dist/cjs/co-button.cjs.entry.js +12 -5
  12. package/dist/cjs/co-calendar-month_2.cjs.entry.js +1601 -0
  13. package/dist/cjs/co-calendar_3.cjs.entry.js +9 -9
  14. package/dist/cjs/co-card.cjs.entry.js +2 -2
  15. package/dist/cjs/co-carousel-item.cjs.entry.js +1 -1
  16. package/dist/cjs/co-carousel.cjs.entry.js +3 -3
  17. package/dist/cjs/co-checkbox.cjs.entry.js +4 -4
  18. package/dist/cjs/co-chip_2.cjs.entry.js +95 -6
  19. package/dist/cjs/co-color-picker.cjs.entry.js +2 -2
  20. package/dist/cjs/co-column-picker.cjs.entry.js +2 -2
  21. package/dist/cjs/co-data-table-pagination.cjs.entry.js +4 -4
  22. package/dist/cjs/co-data-table.cjs.entry.js +1 -1
  23. package/dist/cjs/co-date-picker.cjs.entry.js +1 -1
  24. package/dist/cjs/co-date-range-picker.cjs.entry.js +2 -2
  25. package/dist/cjs/co-date-range.cjs.entry.js +1 -1
  26. package/dist/cjs/co-date-time-picker.cjs.entry.js +409 -0
  27. package/dist/cjs/co-drive-card.cjs.entry.js +1 -1
  28. package/dist/cjs/co-drop-zone.cjs.entry.js +1 -1
  29. package/dist/cjs/co-empty-state.cjs.entry.js +2 -2
  30. package/dist/cjs/co-event-calendar.cjs.entry.js +118 -17
  31. package/dist/cjs/co-event-popover.cjs.entry.js +132 -0
  32. package/dist/cjs/co-fab.cjs.entry.js +2 -2
  33. package/dist/cjs/co-file-field.cjs.entry.js +5 -5
  34. package/dist/cjs/co-file-type-tile.cjs.entry.js +2 -2
  35. package/dist/cjs/co-helper-text.cjs.entry.js +2 -2
  36. package/dist/cjs/co-icon-button.cjs.entry.js +1 -1
  37. package/dist/cjs/co-icon.cjs.entry.js +2 -2
  38. package/dist/cjs/co-json-field.cjs.entry.js +3 -3
  39. package/dist/cjs/co-lightbox.cjs.entry.js +5 -5
  40. package/dist/cjs/co-list-footer.cjs.entry.js +1 -1
  41. package/dist/cjs/co-list-item.cjs.entry.js +4 -4
  42. package/dist/cjs/co-media-thumb.cjs.entry.js +2 -2
  43. package/dist/cjs/co-menu-divider.cjs.entry.js +1 -1
  44. package/dist/cjs/co-menu-item.cjs.entry.js +2 -2
  45. package/dist/cjs/co-menu.cjs.entry.js +1 -1
  46. package/dist/cjs/co-modal.cjs.entry.js +2 -2
  47. package/dist/cjs/co-navbar.cjs.entry.js +2 -2
  48. package/dist/cjs/co-number-field.cjs.entry.js +2 -2
  49. package/dist/cjs/co-overlay.cjs.entry.js +1 -1
  50. package/dist/cjs/co-page-header.cjs.entry.js +1 -1
  51. package/dist/cjs/co-phone-field.cjs.entry.js +1 -1
  52. package/dist/cjs/co-popover.cjs.entry.js +1 -1
  53. package/dist/cjs/co-progress-bar.cjs.entry.js +2 -2
  54. package/dist/cjs/co-progress-circle.cjs.entry.js +2 -2
  55. package/dist/cjs/co-provider-logo_2.cjs.entry.js +72 -0
  56. package/dist/cjs/co-radio.cjs.entry.js +3 -3
  57. package/dist/cjs/co-rating.cjs.entry.js +3 -3
  58. package/dist/cjs/co-ref-field.cjs.entry.js +6 -2
  59. package/dist/cjs/co-rich-text-editor.cjs.entry.js +4 -4
  60. package/dist/cjs/co-rich-text-toolbar.cjs.entry.js +1 -1
  61. package/dist/cjs/co-row.cjs.entry.js +2 -2
  62. package/dist/cjs/co-select.cjs.entry.js +1 -1
  63. package/dist/cjs/co-separator.cjs.entry.js +1 -1
  64. package/dist/cjs/co-sidebar-nav.cjs.entry.js +12 -2
  65. package/dist/cjs/co-sidebar.cjs.entry.js +2 -2
  66. package/dist/cjs/co-slider.cjs.entry.js +2 -2
  67. package/dist/cjs/co-switch.cjs.entry.js +3 -3
  68. package/dist/cjs/co-tab-group.cjs.entry.js +19 -3
  69. package/dist/cjs/co-tab.cjs.entry.js +2 -2
  70. package/dist/cjs/co-tags-field.cjs.entry.js +5 -5
  71. package/dist/cjs/co-textarea.cjs.entry.js +4 -4
  72. package/dist/cjs/co-toggle-button-group.cjs.entry.js +2 -2
  73. package/dist/cjs/co-toggle-button.cjs.entry.js +2 -2
  74. package/dist/cjs/co-video.cjs.entry.js +2 -2
  75. package/dist/cjs/cobalt.cjs.js +1 -1
  76. package/dist/cjs/{dateI18n-BdiNAl0_.js → dateI18n-wblvKRq_.js} +21 -0
  77. package/dist/cjs/{dates-D8D-aS5d.js → dates-TQLHlFd2.js} +64 -13
  78. package/dist/cjs/index-kBiXCEE7.js +28 -12
  79. package/dist/cjs/loader.cjs.js +1 -1
  80. package/dist/cjs/{positioning-DwHW399W.js → positioning-DCj_AJ2T.js} +10 -0
  81. package/dist/cjs/time-LBHtzLHe.js +42 -0
  82. package/dist/cobalt/cobalt.esm.js +1 -1
  83. package/dist/cobalt/{p-616e4286.entry.js → p-00830b8c.entry.js} +1 -1
  84. package/dist/cobalt/{p-9994fcd8.entry.js → p-0769eee9.entry.js} +1 -1
  85. package/dist/cobalt/{p-9bf42bf4.entry.js → p-0f18c4d2.entry.js} +1 -1
  86. package/dist/cobalt/{p-cdedaa82.entry.js → p-0fc1edca.entry.js} +1 -1
  87. package/dist/cobalt/p-15852fec.entry.js +1 -0
  88. package/dist/cobalt/{p-eec1c44c.entry.js → p-195c67ee.entry.js} +1 -1
  89. package/dist/cobalt/{p-B6JZk8fL.js → p-1EK-COrb.js} +1 -1
  90. package/dist/cobalt/{p-2da09948.entry.js → p-1e9c9d46.entry.js} +1 -1
  91. package/dist/cobalt/{p-e1b468c1.entry.js → p-20bd3702.entry.js} +1 -1
  92. package/dist/cobalt/p-25f59046.entry.js +1 -0
  93. package/dist/cobalt/{p-b06af5c6.entry.js → p-260196cb.entry.js} +1 -1
  94. package/dist/cobalt/p-2bf44b2b.entry.js +1 -0
  95. package/dist/cobalt/{p-8155d781.entry.js → p-2c100914.entry.js} +1 -1
  96. package/dist/cobalt/p-2e1d930f.entry.js +1 -0
  97. package/dist/cobalt/{p-080f62e4.entry.js → p-35518aee.entry.js} +1 -1
  98. package/dist/cobalt/{p-28ab9cef.entry.js → p-38ae8bff.entry.js} +1 -1
  99. package/dist/cobalt/{p-f0a98453.entry.js → p-38cf47b6.entry.js} +1 -1
  100. package/dist/cobalt/p-39dea0c0.entry.js +1 -0
  101. package/dist/cobalt/{p-3c681e3a.entry.js → p-3a746267.entry.js} +1 -1
  102. package/dist/cobalt/p-3ae69426.entry.js +1 -0
  103. package/dist/cobalt/{p-9211e794.entry.js → p-3d4e697e.entry.js} +1 -1
  104. package/dist/cobalt/{p-264508ae.entry.js → p-445acc4c.entry.js} +1 -1
  105. package/dist/cobalt/p-4de9232a.entry.js +1 -0
  106. package/dist/cobalt/{p-7f78e45c.entry.js → p-50bbfad8.entry.js} +1 -1
  107. package/dist/cobalt/{p-54f8c68c.entry.js → p-51a1ad38.entry.js} +1 -1
  108. package/dist/cobalt/{p-75515a8e.entry.js → p-523aca9f.entry.js} +1 -1
  109. package/dist/cobalt/{p-2f6c7eb5.entry.js → p-52af222b.entry.js} +1 -1
  110. package/dist/cobalt/{p-0b7359bb.entry.js → p-59f7d44b.entry.js} +1 -1
  111. package/dist/cobalt/{p-4f615cbd.entry.js → p-5b984323.entry.js} +1 -1
  112. package/dist/cobalt/{p-8fe5b07e.entry.js → p-5bfaca70.entry.js} +1 -1
  113. package/dist/cobalt/p-5c1328ff.entry.js +1 -0
  114. package/dist/cobalt/p-5e21ca17.entry.js +1 -0
  115. package/dist/cobalt/p-61d5ca3c.entry.js +1 -0
  116. package/dist/cobalt/{p-64115d66.entry.js → p-6357d9dd.entry.js} +1 -1
  117. package/dist/cobalt/{p-0a294205.entry.js → p-6985a964.entry.js} +1 -1
  118. package/dist/cobalt/p-69b8d98e.entry.js +1 -0
  119. package/dist/cobalt/{p-532baca4.entry.js → p-6b089060.entry.js} +1 -1
  120. package/dist/cobalt/{p-ceb85838.entry.js → p-6b256d01.entry.js} +1 -1
  121. package/dist/cobalt/{p-c9528a5f.entry.js → p-7c6b3175.entry.js} +1 -1
  122. package/dist/cobalt/{p-431cec34.entry.js → p-7d077a7c.entry.js} +1 -1
  123. package/dist/cobalt/{p-cbac0a11.entry.js → p-7f4bf341.entry.js} +1 -1
  124. package/dist/cobalt/p-869c338a.entry.js +1 -0
  125. package/dist/cobalt/p-890296f9.entry.js +1 -0
  126. package/dist/cobalt/{p-7178113f.entry.js → p-8fe08257.entry.js} +1 -1
  127. package/dist/cobalt/p-913b2a14.entry.js +1 -0
  128. package/dist/cobalt/{p-5b84cf37.entry.js → p-959556f4.entry.js} +1 -1
  129. package/dist/cobalt/{p-331a0108.entry.js → p-99c1ff0f.entry.js} +1 -1
  130. package/dist/cobalt/p-BMdapAL8.js +1 -0
  131. package/dist/cobalt/p-BU7SQCje.js +1 -0
  132. package/dist/cobalt/p-CF8OB_TM.js +1 -0
  133. package/dist/cobalt/p-CnNpoKwg.js +1 -0
  134. package/dist/cobalt/{p-ba5c6aa7.entry.js → p-a04feb70.entry.js} +1 -1
  135. package/dist/cobalt/p-a4f39ba2.entry.js +1 -0
  136. package/dist/cobalt/{p-d3a1a604.entry.js → p-a7c23027.entry.js} +1 -1
  137. package/dist/cobalt/p-ab8e150e.entry.js +1 -0
  138. package/dist/cobalt/{p-69ce2269.entry.js → p-acdb68a7.entry.js} +1 -1
  139. package/dist/cobalt/{p-3b9be8a8.entry.js → p-afd957c0.entry.js} +1 -1
  140. package/dist/cobalt/{p-c3004e1c.entry.js → p-b45ea918.entry.js} +1 -1
  141. package/dist/cobalt/{p-eeed80ac.entry.js → p-bad7ce84.entry.js} +1 -1
  142. package/dist/cobalt/{p-bcd38114.entry.js → p-bebacee2.entry.js} +1 -1
  143. package/dist/cobalt/{p-ec9dd3a3.entry.js → p-c32949a5.entry.js} +1 -1
  144. package/dist/cobalt/p-cd5555d2.entry.js +1 -0
  145. package/dist/cobalt/p-cd96aabf.entry.js +1 -0
  146. package/dist/cobalt/{p-2661557c.entry.js → p-ce961fba.entry.js} +1 -1
  147. package/dist/cobalt/p-d56b8a1f.entry.js +1 -0
  148. package/dist/cobalt/{p-c7d9ff39.entry.js → p-d6fff135.entry.js} +1 -1
  149. package/dist/cobalt/{p-6b38e8fb.entry.js → p-d71b87d3.entry.js} +1 -1
  150. package/dist/cobalt/{p-ff581807.entry.js → p-d83e5189.entry.js} +1 -1
  151. package/dist/cobalt/{p-741cf623.entry.js → p-dc269096.entry.js} +1 -1
  152. package/dist/cobalt/{p-e4555fda.entry.js → p-dc8e88f4.entry.js} +1 -1
  153. package/dist/cobalt/p-de5a05fc.entry.js +1 -0
  154. package/dist/cobalt/{p-0110108f.entry.js → p-df63f23c.entry.js} +1 -1
  155. package/dist/cobalt/{p-9fab9c1f.entry.js → p-e2188319.entry.js} +1 -1
  156. package/dist/cobalt/p-f0c589ad.entry.js +1 -0
  157. package/dist/cobalt/p-f4370423.entry.js +1 -0
  158. package/dist/cobalt/{p-b87a2e7a.entry.js → p-f4e4bebf.entry.js} +1 -1
  159. package/dist/cobalt/p-f53b9536.entry.js +1 -0
  160. package/dist/cobalt/{p-bb00ae4a.entry.js → p-f7ae0228.entry.js} +1 -1
  161. package/dist/collection/collection-manifest.json +6 -0
  162. package/dist/collection/components/co-action-bar/co-action-bar.css +148 -0
  163. package/dist/collection/components/co-action-bar/co-action-bar.js +247 -0
  164. package/dist/collection/components/co-app-shell/co-app-shell.js +2 -2
  165. package/dist/collection/components/co-audio-player/co-audio-player.css +58 -0
  166. package/dist/collection/components/co-audio-player/co-audio-player.js +453 -0
  167. package/dist/collection/components/co-audio-player/co-audio-player.utils.js +44 -0
  168. package/dist/collection/components/co-badge/co-badge.js +1 -1
  169. package/dist/collection/components/co-bottom-sheet/co-bottom-sheet.js +3 -3
  170. package/dist/collection/components/co-breadcrumb/co-breadcrumb.js +1 -1
  171. package/dist/collection/components/co-breadcrumb-item/co-breadcrumb-item.js +2 -2
  172. package/dist/collection/components/co-button/co-button.css +19 -0
  173. package/dist/collection/components/co-button/co-button.js +31 -5
  174. package/dist/collection/components/co-button-group/co-button-group.js +2 -2
  175. package/dist/collection/components/co-calendar/co-calendar.js +1 -1
  176. package/dist/collection/components/co-calendar-month/co-calendar-month.css +52 -3
  177. package/dist/collection/components/co-calendar-month/co-calendar-month.js +238 -55
  178. package/dist/collection/components/co-calendar-timegrid/co-calendar-timegrid.css +265 -0
  179. package/dist/collection/components/co-calendar-timegrid/co-calendar-timegrid.js +1305 -0
  180. package/dist/collection/components/co-card/co-card.js +2 -2
  181. package/dist/collection/components/co-carousel/co-carousel.js +2 -2
  182. package/dist/collection/components/co-carousel-item/co-carousel-item.js +1 -1
  183. package/dist/collection/components/co-checkbox/co-checkbox.css +1 -1
  184. package/dist/collection/components/co-checkbox/co-checkbox.js +3 -3
  185. package/dist/collection/components/co-chip/co-chip.js +2 -2
  186. package/dist/collection/components/co-color-picker/co-color-picker.js +2 -2
  187. package/dist/collection/components/co-column-picker/co-column-picker.js +2 -2
  188. package/dist/collection/components/co-data-table/co-data-table.css +4 -4
  189. package/dist/collection/components/co-data-table-pagination/co-data-table-pagination.js +4 -4
  190. package/dist/collection/components/co-date-field/co-date-field.js +4 -4
  191. package/dist/collection/components/co-date-range/co-date-range.js +1 -1
  192. package/dist/collection/components/co-date-time-picker/co-date-time-picker.css +325 -0
  193. package/dist/collection/components/co-date-time-picker/co-date-time-picker.js +1079 -0
  194. package/dist/collection/components/co-drawer/co-drawer.css +46 -0
  195. package/dist/collection/components/co-drawer/co-drawer.js +1 -1
  196. package/dist/collection/components/co-drive-card/co-drive-card.js +1 -1
  197. package/dist/collection/components/co-drop-zone/co-drop-zone.js +1 -1
  198. package/dist/collection/components/co-empty-state/co-empty-state.js +2 -2
  199. package/dist/collection/components/co-event-calendar/co-event-calendar.css +19 -7
  200. package/dist/collection/components/co-event-calendar/co-event-calendar.js +342 -39
  201. package/dist/collection/components/co-event-popover/co-event-popover.css +26 -0
  202. package/dist/collection/components/co-event-popover/co-event-popover.js +326 -0
  203. package/dist/collection/components/co-fab/co-fab.js +2 -2
  204. package/dist/collection/components/co-file-field/co-file-field.js +5 -5
  205. package/dist/collection/components/co-file-type-tile/co-file-type-tile.js +2 -2
  206. package/dist/collection/components/co-helper-text/co-helper-text.js +2 -2
  207. package/dist/collection/components/co-icon/co-icon.js +2 -2
  208. package/dist/collection/components/co-icon-button/co-icon-button.js +1 -1
  209. package/dist/collection/components/co-json-field/co-json-field.js +3 -3
  210. package/dist/collection/components/co-lightbox/co-lightbox.js +4 -4
  211. package/dist/collection/components/co-list-footer/co-list-footer.js +1 -1
  212. package/dist/collection/components/co-list-item/co-list-item.js +4 -4
  213. package/dist/collection/components/co-media-thumb/co-media-thumb.js +2 -2
  214. package/dist/collection/components/co-menu/co-menu.js +1 -1
  215. package/dist/collection/components/co-menu-divider/co-menu-divider.js +1 -1
  216. package/dist/collection/components/co-menu-item/co-menu-item.css +21 -0
  217. package/dist/collection/components/co-menu-item/co-menu-item.js +20 -1
  218. package/dist/collection/components/co-modal/co-modal.js +2 -2
  219. package/dist/collection/components/co-navbar/co-navbar.js +2 -2
  220. package/dist/collection/components/co-number-field/co-number-field.js +2 -2
  221. package/dist/collection/components/co-option-list/co-option-list.css +18 -0
  222. package/dist/collection/components/co-option-list/co-option-list.js +127 -5
  223. package/dist/collection/components/co-option-list/optionListLogic.js +13 -0
  224. package/dist/collection/components/co-overlay/co-overlay.js +1 -1
  225. package/dist/collection/components/co-page-header/co-page-header.js +1 -1
  226. package/dist/collection/components/co-phone-field/co-phone-field.js +1 -1
  227. package/dist/collection/components/co-progress-bar/co-progress-bar.js +2 -2
  228. package/dist/collection/components/co-progress-circle/co-progress-circle.js +2 -2
  229. package/dist/collection/components/co-provider-logo/co-provider-logo.css +23 -0
  230. package/dist/collection/components/co-provider-logo/co-provider-logo.js +124 -0
  231. package/dist/collection/components/co-radio/co-radio.js +3 -3
  232. package/dist/collection/components/co-rating/co-rating.js +3 -3
  233. package/dist/collection/components/co-ref-field/co-ref-field.js +6 -2
  234. package/dist/collection/components/co-rich-text-editor/co-rich-text-editor.css +11 -0
  235. package/dist/collection/components/co-rich-text-editor/co-rich-text-editor.js +3 -3
  236. package/dist/collection/components/co-rich-text-toolbar/co-rich-text-toolbar.css +8 -0
  237. package/dist/collection/components/co-row/co-row.js +2 -2
  238. package/dist/collection/components/co-select/co-select.js +1 -1
  239. package/dist/collection/components/co-separator/co-separator.js +1 -1
  240. package/dist/collection/components/co-sidebar/co-sidebar.js +2 -2
  241. package/dist/collection/components/co-sidebar-nav/co-sidebar-nav.js +12 -2
  242. package/dist/collection/components/co-skeleton/co-skeleton.js +1 -1
  243. package/dist/collection/components/co-slider/co-slider.js +2 -2
  244. package/dist/collection/components/co-switch/co-switch.js +3 -3
  245. package/dist/collection/components/co-tab/co-tab.js +2 -2
  246. package/dist/collection/components/co-tab-group/co-tab-group.css +25 -0
  247. package/dist/collection/components/co-tab-group/co-tab-group.js +18 -2
  248. package/dist/collection/components/co-tags-field/co-tags-field.js +5 -5
  249. package/dist/collection/components/co-textarea/co-textarea.js +4 -4
  250. package/dist/collection/components/co-toggle-button/co-toggle-button.js +2 -2
  251. package/dist/collection/components/co-toggle-button-group/co-toggle-button-group.js +2 -2
  252. package/dist/collection/components/co-tooltip/co-tooltip.js +2 -2
  253. package/dist/collection/components/co-video/co-video.js +2 -2
  254. package/dist/collection/utils/dateI18n.js +21 -0
  255. package/dist/collection/utils/eventColor.js +52 -0
  256. package/dist/collection/utils/positioning.js +10 -0
  257. package/dist/components/co-accordion.js +1 -1
  258. package/dist/components/co-action-bar.d.ts +11 -0
  259. package/dist/components/co-action-bar.js +1 -0
  260. package/dist/components/co-app-shell.js +1 -1
  261. package/dist/components/co-audio-player.d.ts +11 -0
  262. package/dist/components/co-audio-player.js +1 -0
  263. package/dist/components/co-autocomplete.js +1 -1
  264. package/dist/components/co-avatar-group.js +1 -1
  265. package/dist/components/co-avatar.js +1 -1
  266. package/dist/components/co-badge.js +1 -1
  267. package/dist/components/co-bottom-sheet.js +1 -1
  268. package/dist/components/co-breadcrumb-item.js +1 -1
  269. package/dist/components/co-breadcrumb.js +1 -1
  270. package/dist/components/co-button-group.js +1 -1
  271. package/dist/components/co-button.js +1 -1
  272. package/dist/components/co-calendar-month.js +1 -1
  273. package/dist/components/co-calendar-timegrid.d.ts +11 -0
  274. package/dist/components/co-calendar-timegrid.js +1 -0
  275. package/dist/components/co-calendar.js +1 -1
  276. package/dist/components/co-card.js +1 -1
  277. package/dist/components/co-carousel-item.js +1 -1
  278. package/dist/components/co-carousel.js +1 -1
  279. package/dist/components/co-checkbox-group.js +1 -1
  280. package/dist/components/co-checkbox.js +1 -1
  281. package/dist/components/co-chip.js +1 -1
  282. package/dist/components/co-color-picker.js +1 -1
  283. package/dist/components/co-column-picker.js +1 -1
  284. package/dist/components/co-combobox.js +1 -1
  285. package/dist/components/co-command-search.js +1 -1
  286. package/dist/components/co-data-table-pagination.js +1 -1
  287. package/dist/components/co-data-table.js +1 -1
  288. package/dist/components/co-date-field.js +1 -1
  289. package/dist/components/co-date-picker.js +1 -1
  290. package/dist/components/co-date-range-picker.js +1 -1
  291. package/dist/components/co-date-range.js +1 -1
  292. package/dist/components/co-date-time-picker.d.ts +11 -0
  293. package/dist/components/co-date-time-picker.js +1 -0
  294. package/dist/components/co-drawer.js +1 -1
  295. package/dist/components/co-drive-card.js +1 -1
  296. package/dist/components/co-drop-zone.js +1 -1
  297. package/dist/components/co-empty-state.js +1 -1
  298. package/dist/components/co-event-calendar.js +1 -1
  299. package/dist/components/co-event-popover.d.ts +11 -0
  300. package/dist/components/co-event-popover.js +1 -0
  301. package/dist/components/co-fab.js +1 -1
  302. package/dist/components/co-file-field.js +1 -1
  303. package/dist/components/co-file-type-tile.js +1 -1
  304. package/dist/components/co-helper-text.js +1 -1
  305. package/dist/components/co-icon-button.js +1 -1
  306. package/dist/components/co-icon.js +1 -1
  307. package/dist/components/co-input.js +1 -1
  308. package/dist/components/co-json-field.js +1 -1
  309. package/dist/components/co-lightbox.js +1 -1
  310. package/dist/components/co-list-footer.js +1 -1
  311. package/dist/components/co-list-item.js +1 -1
  312. package/dist/components/co-media-thumb.js +1 -1
  313. package/dist/components/co-menu-divider.js +1 -1
  314. package/dist/components/co-menu-item.js +1 -1
  315. package/dist/components/co-menu.js +1 -1
  316. package/dist/components/co-modal.js +1 -1
  317. package/dist/components/co-navbar.js +1 -1
  318. package/dist/components/co-number-field.js +1 -1
  319. package/dist/components/co-option-list.js +1 -1
  320. package/dist/components/co-overlay.js +1 -1
  321. package/dist/components/co-page-header.js +1 -1
  322. package/dist/components/co-phone-field.js +1 -1
  323. package/dist/components/co-popover.js +1 -1
  324. package/dist/components/co-progress-bar.js +1 -1
  325. package/dist/components/co-progress-circle.js +1 -1
  326. package/dist/components/co-provider-logo.d.ts +11 -0
  327. package/dist/components/co-provider-logo.js +1 -0
  328. package/dist/components/co-radio-group.js +1 -1
  329. package/dist/components/co-radio.js +1 -1
  330. package/dist/components/co-rating.js +1 -1
  331. package/dist/components/co-ref-field.js +1 -1
  332. package/dist/components/co-rich-text-editor.js +1 -1
  333. package/dist/components/co-rich-text-toolbar.js +1 -1
  334. package/dist/components/co-row.js +1 -1
  335. package/dist/components/co-select.js +1 -1
  336. package/dist/components/co-separator.js +1 -1
  337. package/dist/components/co-sidebar-nav.js +1 -1
  338. package/dist/components/co-sidebar.js +1 -1
  339. package/dist/components/co-skeleton.js +1 -1
  340. package/dist/components/co-slider.js +1 -1
  341. package/dist/components/co-switch.js +1 -1
  342. package/dist/components/co-tab-group.js +1 -1
  343. package/dist/components/co-tab.js +1 -1
  344. package/dist/components/co-tags-field.js +1 -1
  345. package/dist/components/co-textarea.js +1 -1
  346. package/dist/components/co-toast.js +1 -1
  347. package/dist/components/co-toggle-button-group.js +1 -1
  348. package/dist/components/co-toggle-button.js +1 -1
  349. package/dist/components/co-tooltip.js +1 -1
  350. package/dist/components/co-transfer-list.js +1 -1
  351. package/dist/components/co-video.js +1 -1
  352. package/dist/components/p-B21rOC2Y.js +1 -0
  353. package/dist/components/{p-Cd3inFSL.js → p-BC6sxVVr.js} +1 -1
  354. package/dist/components/p-BMdapAL8.js +1 -0
  355. package/dist/components/p-BQFperIX.js +1 -0
  356. package/dist/components/{p-CQ-8domm.js → p-BXtiFFM2.js} +1 -1
  357. package/dist/components/{p-CmCsm4L-.js → p-BdArvV6T.js} +1 -1
  358. package/dist/components/p-BnkGlFYy.js +1 -0
  359. package/dist/components/p-C-5cLeKr.js +1 -0
  360. package/dist/components/p-CDWXNRpo.js +1 -0
  361. package/dist/components/p-CF8OB_TM.js +1 -0
  362. package/dist/components/{p-oV_1MoAN.js → p-CIWoKlGj.js} +1 -1
  363. package/dist/components/{p-Bul6EdDX.js → p-CVCEiwOS.js} +1 -1
  364. package/dist/components/{p-B0b9Etx4.js → p-CfeNhAHW.js} +1 -1
  365. package/dist/components/p-Ch837Ggl.js +1 -0
  366. package/dist/components/p-ChLib-si.js +1 -0
  367. package/dist/components/{p-DfpOEXHC.js → p-ChPooamL.js} +1 -1
  368. package/dist/components/p-CnNpoKwg.js +1 -0
  369. package/dist/components/{p-B7Yv00g9.js → p-D-3BTFRs.js} +1 -1
  370. package/dist/components/p-D0wrmRH8.js +1 -0
  371. package/dist/components/p-DZX7cEqP.js +1 -0
  372. package/dist/components/{p-B3U63yZw.js → p-DbISGXT_.js} +1 -1
  373. package/dist/components/p-Dxa7c4Ap.js +1 -0
  374. package/dist/components/p-T0MdU7sb.js +1 -0
  375. package/dist/components/{p-DwwxS5bY.js → p-W8Y8ZuPs.js} +1 -1
  376. package/dist/components/{p-9aNhJfTT.js → p-cteJszd-.js} +1 -1
  377. package/dist/components/p-e5KibEs8.js +1 -0
  378. package/dist/components/{p-Bzg5FPSA.js → p-mUoTCiYa.js} +1 -1
  379. package/dist/components/p-uZ2D6ESV.js +1 -0
  380. package/dist/components/{p-BtpRnpaF.js → p-ySi6UG0O.js} +1 -1
  381. package/dist/esm/co-action-bar.entry.js +87 -0
  382. package/dist/esm/co-app-shell.entry.js +2 -2
  383. package/dist/esm/co-audio-player.entry.js +277 -0
  384. package/dist/esm/co-avatar_2.entry.js +3 -3
  385. package/dist/esm/co-badge.entry.js +1 -1
  386. package/dist/esm/co-bottom-sheet.entry.js +3 -3
  387. package/dist/esm/co-breadcrumb-item.entry.js +2 -2
  388. package/dist/esm/co-breadcrumb.entry.js +1 -1
  389. package/dist/esm/co-button-group.entry.js +2 -2
  390. package/dist/esm/co-button.entry.js +12 -5
  391. package/dist/esm/co-calendar-month_2.entry.js +1598 -0
  392. package/dist/esm/co-calendar_3.entry.js +9 -9
  393. package/dist/esm/co-card.entry.js +2 -2
  394. package/dist/esm/co-carousel-item.entry.js +1 -1
  395. package/dist/esm/co-carousel.entry.js +3 -3
  396. package/dist/esm/co-checkbox.entry.js +4 -4
  397. package/dist/esm/co-chip_2.entry.js +95 -6
  398. package/dist/esm/co-color-picker.entry.js +2 -2
  399. package/dist/esm/co-column-picker.entry.js +2 -2
  400. package/dist/esm/co-data-table-pagination.entry.js +4 -4
  401. package/dist/esm/co-data-table.entry.js +1 -1
  402. package/dist/esm/co-date-picker.entry.js +1 -1
  403. package/dist/esm/co-date-range-picker.entry.js +2 -2
  404. package/dist/esm/co-date-range.entry.js +1 -1
  405. package/dist/esm/co-date-time-picker.entry.js +407 -0
  406. package/dist/esm/co-drive-card.entry.js +1 -1
  407. package/dist/esm/co-drop-zone.entry.js +1 -1
  408. package/dist/esm/co-empty-state.entry.js +2 -2
  409. package/dist/esm/co-event-calendar.entry.js +120 -19
  410. package/dist/esm/co-event-popover.entry.js +130 -0
  411. package/dist/esm/co-fab.entry.js +2 -2
  412. package/dist/esm/co-file-field.entry.js +5 -5
  413. package/dist/esm/co-file-type-tile.entry.js +2 -2
  414. package/dist/esm/co-helper-text.entry.js +2 -2
  415. package/dist/esm/co-icon-button.entry.js +1 -1
  416. package/dist/esm/co-icon.entry.js +2 -2
  417. package/dist/esm/co-json-field.entry.js +3 -3
  418. package/dist/esm/co-lightbox.entry.js +5 -5
  419. package/dist/esm/co-list-footer.entry.js +1 -1
  420. package/dist/esm/co-list-item.entry.js +4 -4
  421. package/dist/esm/co-media-thumb.entry.js +2 -2
  422. package/dist/esm/co-menu-divider.entry.js +1 -1
  423. package/dist/esm/co-menu-item.entry.js +2 -2
  424. package/dist/esm/co-menu.entry.js +1 -1
  425. package/dist/esm/co-modal.entry.js +2 -2
  426. package/dist/esm/co-navbar.entry.js +2 -2
  427. package/dist/esm/co-number-field.entry.js +2 -2
  428. package/dist/esm/co-overlay.entry.js +1 -1
  429. package/dist/esm/co-page-header.entry.js +1 -1
  430. package/dist/esm/co-phone-field.entry.js +1 -1
  431. package/dist/esm/co-popover.entry.js +1 -1
  432. package/dist/esm/co-progress-bar.entry.js +2 -2
  433. package/dist/esm/co-progress-circle.entry.js +2 -2
  434. package/dist/esm/co-provider-logo_2.entry.js +69 -0
  435. package/dist/esm/co-radio.entry.js +3 -3
  436. package/dist/esm/co-rating.entry.js +3 -3
  437. package/dist/esm/co-ref-field.entry.js +6 -2
  438. package/dist/esm/co-rich-text-editor.entry.js +4 -4
  439. package/dist/esm/co-rich-text-toolbar.entry.js +1 -1
  440. package/dist/esm/co-row.entry.js +2 -2
  441. package/dist/esm/co-select.entry.js +1 -1
  442. package/dist/esm/co-separator.entry.js +1 -1
  443. package/dist/esm/co-sidebar-nav.entry.js +12 -2
  444. package/dist/esm/co-sidebar.entry.js +2 -2
  445. package/dist/esm/co-slider.entry.js +2 -2
  446. package/dist/esm/co-switch.entry.js +3 -3
  447. package/dist/esm/co-tab-group.entry.js +19 -3
  448. package/dist/esm/co-tab.entry.js +2 -2
  449. package/dist/esm/co-tags-field.entry.js +5 -5
  450. package/dist/esm/co-textarea.entry.js +4 -4
  451. package/dist/esm/co-toggle-button-group.entry.js +2 -2
  452. package/dist/esm/co-toggle-button.entry.js +2 -2
  453. package/dist/esm/co-video.entry.js +2 -2
  454. package/dist/esm/cobalt.js +1 -1
  455. package/dist/esm/{dateI18n-C1DCLOEl.js → dateI18n-CnNpoKwg.js} +21 -0
  456. package/dist/esm/{dates-tPYikBRJ.js → dates-BU7SQCje.js} +64 -13
  457. package/dist/esm/index-BCEz3S-z.js +28 -12
  458. package/dist/esm/loader.js +1 -1
  459. package/dist/esm/{positioning-C2mZ7x_Y.js → positioning-BMdapAL8.js} +10 -0
  460. package/dist/esm/time-CF8OB_TM.js +37 -0
  461. package/dist/esm/{tz-B6JZk8fL.js → tz-1EK-COrb.js} +1 -1
  462. package/dist/types/components/co-action-bar/co-action-bar.d.ts +66 -0
  463. package/dist/types/components/co-audio-player/co-audio-player.d.ts +62 -0
  464. package/dist/types/components/co-audio-player/co-audio-player.utils.d.ts +11 -0
  465. package/dist/types/components/co-button/co-button.d.ts +18 -1
  466. package/dist/types/components/co-calendar-month/co-calendar-month.d.ts +33 -1
  467. package/dist/types/components/co-calendar-timegrid/co-calendar-timegrid.d.ts +178 -0
  468. package/dist/types/components/co-date-time-picker/co-date-time-picker.d.ts +131 -0
  469. package/dist/types/components/co-event-calendar/co-event-calendar.d.ts +61 -8
  470. package/dist/types/components/co-event-popover/co-event-popover.d.ts +45 -0
  471. package/dist/types/components/co-menu-item/co-menu-item.d.ts +3 -0
  472. package/dist/types/components/co-option-list/co-option-list.d.ts +23 -0
  473. package/dist/types/components/co-option-list/optionListLogic.d.ts +3 -0
  474. package/dist/types/components/co-provider-logo/co-provider-logo.d.ts +17 -0
  475. package/dist/types/components/co-ref-field/co-ref-field.d.ts +1 -0
  476. package/dist/types/components/co-tab-group/co-tab-group.d.ts +5 -0
  477. package/dist/types/components.d.ts +1245 -76
  478. package/dist/types/utils/dateI18n.d.ts +7 -0
  479. package/dist/types/utils/eventColor.d.ts +20 -0
  480. package/package.json +2 -2
  481. package/dist/cjs/co-calendar-month.cjs.entry.js +0 -381
  482. package/dist/cjs/co-skeleton.cjs.entry.js +0 -26
  483. package/dist/cobalt/p-037cc571.entry.js +0 -1
  484. package/dist/cobalt/p-0b92167a.entry.js +0 -1
  485. package/dist/cobalt/p-0bc5a962.entry.js +0 -1
  486. package/dist/cobalt/p-30c80e3a.entry.js +0 -1
  487. package/dist/cobalt/p-36ad3a96.entry.js +0 -1
  488. package/dist/cobalt/p-3ecbbe93.entry.js +0 -1
  489. package/dist/cobalt/p-3f1030fb.entry.js +0 -1
  490. package/dist/cobalt/p-3f7215e7.entry.js +0 -1
  491. package/dist/cobalt/p-54857f78.entry.js +0 -1
  492. package/dist/cobalt/p-585c132d.entry.js +0 -1
  493. package/dist/cobalt/p-59b114ab.entry.js +0 -1
  494. package/dist/cobalt/p-5d0510a5.entry.js +0 -1
  495. package/dist/cobalt/p-5e246304.entry.js +0 -1
  496. package/dist/cobalt/p-C1DCLOEl.js +0 -1
  497. package/dist/cobalt/p-C2mZ7x_Y.js +0 -1
  498. package/dist/cobalt/p-c589ae25.entry.js +0 -1
  499. package/dist/cobalt/p-c635417b.entry.js +0 -1
  500. package/dist/cobalt/p-cd28aa6d.entry.js +0 -1
  501. package/dist/cobalt/p-d71b800a.entry.js +0 -1
  502. package/dist/cobalt/p-df752f6e.entry.js +0 -1
  503. package/dist/cobalt/p-fffeb610.entry.js +0 -1
  504. package/dist/cobalt/p-tPYikBRJ.js +0 -1
  505. package/dist/components/p-BTa6ss5i.js +0 -1
  506. package/dist/components/p-C1DCLOEl.js +0 -1
  507. package/dist/components/p-C2mZ7x_Y.js +0 -1
  508. package/dist/components/p-CVeEoHr7.js +0 -1
  509. package/dist/components/p-CYi6V_Ss.js +0 -1
  510. package/dist/components/p-CuQjKAf5.js +0 -1
  511. package/dist/components/p-CyYF8IJE.js +0 -1
  512. package/dist/components/p-DKvTqEaf.js +0 -1
  513. package/dist/components/p-T0UfY6rA.js +0 -1
  514. package/dist/esm/co-calendar-month.entry.js +0 -379
  515. package/dist/esm/co-skeleton.entry.js +0 -24
@@ -0,0 +1,1305 @@
1
+ import { h } from "@stencil/core";
2
+ import { parseISO, compareYMD, todayYMD, getWeekdayLabels } from "@prolibu-suite/cobalt-date-utils";
3
+ import { layoutTimeGrid, layoutAllDay, minutesToFraction, snapMinutes, clampMinutes, zonedMinutesOfDay, zonedDateKey, wallClockToEpoch, toUtcISO, } from "@prolibu-suite/cobalt-calendar-utils";
4
+ import { readableTextToken } from "../../utils/eventColor";
5
+ const ALLDAY_LANE_H = 22; // px per all-day lane (bar 20px + 2px gap)
6
+ // Distancia (px) que el puntero debe recorrer tras el pointerdown para que un drag
7
+ // de evento se comprometa. Por debajo de esto el gesto es un CLICK: el drag no
8
+ // arranca, el chip conserva sus pointer-events y su click abre el popover. Sin este
9
+ // umbral, `startMove` entraba en modo interacting (pointer-events:none en los chips)
10
+ // en el pointerdown mismo y se comía el click de un evento arrastrable.
11
+ const DRAG_THRESHOLD_PX = 5;
12
+ /**
13
+ * co-calendar-timegrid — the Week/Day time-grid. The shell renders it with
14
+ * `dates` = 7 day-keys (week) or 1 (day). Presentation + interaction only; the
15
+ * host owns data (CONTROLLED). All instant math is delegated to the engine — the
16
+ * only timezone boundary is the `timeZone` prop (wall-clock render).
17
+ */
18
+ export class CoCalendarTimegrid {
19
+ constructor() {
20
+ this.events = [];
21
+ /** Visible day keys "YYYY-MM-DD" (7 = week, 1 = day). */
22
+ this.dates = [];
23
+ this.locale = 'es-CO';
24
+ this.editable = true;
25
+ this.selectable = true;
26
+ this.slotMinutes = 15;
27
+ this.snapMinutes = 15;
28
+ this.defaultDurationMinutes = 60;
29
+ this.scrollTime = '07:00';
30
+ this.nowIndicator = true;
31
+ /** Cargando: en vez de los eventos pinta bloques skeleton en las columnas.
32
+ * La grilla (eje de horas, líneas, cabecera de días, franja de todo-el-día)
33
+ * se mantiene: lo único que todavía no se sabe son los eventos. */
34
+ this.loading = false;
35
+ this.allDaySlot = true;
36
+ this.minTime = '00:00';
37
+ this.maxTime = '24:00';
38
+ /** Minute of "now" for the indicator; refreshed on a 60s timer. */
39
+ this.nowMinutes = 0;
40
+ this.nowDay = '';
41
+ /** Roving-tabindex focus position for keyboard navigation over slots. */
42
+ this.focusDate = '';
43
+ this.focusMin = 0;
44
+ this.selDate = null;
45
+ this.selStartMin = 0;
46
+ this.selEndMin = 0;
47
+ this.selecting = false;
48
+ /** Coords crudas del último pointermove: el getBoundingClientRect corre UNA vez
49
+ * por frame, dentro del rAF (antes corría a ~120Hz, en el move crudo). */
50
+ this.pendingSel = null;
51
+ this.selRaf = 0;
52
+ this.pendingDrag = null;
53
+ this.dragRaf = 0;
54
+ this.onWindowPointerUp = () => this.finishSelection();
55
+ this.dragId = null;
56
+ this.dragMode = null;
57
+ this.dragGrabOffsetMin = 0; // minutes between event start and the grab point (move)
58
+ this.dragDurationMin = 0; // preserved duration in minutes (move)
59
+ this.dragDate = null; // current target day (move can change columns)
60
+ this.dragStartMin = 0; // provisional new start (move) / fixed start (resize)
61
+ this.dragEndMin = 0; // provisional new end
62
+ this.origStartMin = 0; // pre-drag start minute (no-op comparison)
63
+ this.origEndMin = 0; // pre-drag end minute (no-op comparison)
64
+ this.origDate = null; // pre-drag day (no-op comparison)
65
+ this.suppressNextClick = false; // set right before coEventDrop so the trailing click no-ops
66
+ // Drag ARMADO pero aún no comprometido: `startMove`/`startResize` guardan el id y
67
+ // el punto de agarre acá; el drag pasa a activo (`dragId`) recién cuando el puntero
68
+ // cruza DRAG_THRESHOLD_PX. Así un click simple en un evento arrastrable no arranca
69
+ // drag y su popover abre.
70
+ this.dragArmedId = null;
71
+ this.dragStartPointer = null;
72
+ this.onWindowPointerMove = (e) => this.trackDrag(e);
73
+ this.onWindowPointerUpDrag = () => this.finishDrag();
74
+ /** Rects de las columnas cacheados AL AGARRAR: con esto el frame de drag es
75
+ * aritmética pura (antes: ~9 getBoundingClientRect + 2 querySelector/frame,
76
+ * que además forzaban reflow síncrono al escribir estilos en el mismo rAF). */
77
+ this.colRects = [];
78
+ this.gridRect = null;
79
+ this.onDragViewportChange = () => this.captureDragRects();
80
+ this.startSelection = (e, dateKey, colEl) => {
81
+ if (!this.selectable || !this.isDayInteractable(dateKey))
82
+ return;
83
+ // ignore clicks that land on an event box (those are handled in Task 4/5)
84
+ if (e.target.closest('.tg__event, .tg__allday-bar'))
85
+ return;
86
+ e.preventDefault();
87
+ const m = this.minutesFromPointer(e.clientY, colEl);
88
+ this.selecting = true;
89
+ this.selDate = dateKey;
90
+ this.selStartMin = m;
91
+ this.selEndMin = m;
92
+ this.setInteracting(true);
93
+ };
94
+ // pointermove llega ~120Hz y cada @State re-renderiza la grilla entera: sin
95
+ // batching el ghost persigue al puntero con lag. Un update por frame — el
96
+ // estado intermedio nunca se pinta, así que no se pierde nada. El gBCR (vía
97
+ // minutesFromPointer) también vive DENTRO del rAF: 1 por frame, no 1 por move.
98
+ this.extendSelection = (e, colEl) => {
99
+ if (!this.selecting)
100
+ return;
101
+ this.pendingSel = { y: e.clientY, colEl };
102
+ if (this.selRaf)
103
+ return;
104
+ this.selRaf = requestAnimationFrame(() => {
105
+ this.selRaf = 0;
106
+ const p = this.pendingSel;
107
+ this.pendingSel = null;
108
+ if (!p || !this.selecting)
109
+ return;
110
+ const min = this.minutesFromPointer(p.y, p.colEl);
111
+ if (min !== this.selEndMin)
112
+ this.selEndMin = min; // snap: la mayoría de los moves no cambian nada
113
+ });
114
+ };
115
+ this.startMove = (e, id) => {
116
+ const ev = this.eventById(id);
117
+ if (!ev || ev.allDay || !this.editable || ev.editable === false || ev.startEditable === false)
118
+ return;
119
+ // Sin preventDefault: en pointerdown CANCELA el click de compatibilidad del
120
+ // navegador, y entonces un evento ARRASTRABLE nunca podía abrir su popover
121
+ // (solo los externos, que no arrancan drag). Lo que preventDefault daba —no
122
+ // seleccionar texto, no scrollear en touch— lo dan `user-select`/
123
+ // `touch-action` en el CSS del bloque. El click POSTERIOR a un drag real
124
+ // sigue anulado por `suppressNextClick`.
125
+ e.stopPropagation();
126
+ const dateKey = zonedDateKey(ev.startMs, this.timeZone);
127
+ this.captureDragRects();
128
+ if (!this.gridRect || !this.colRects.some((c) => c.d === dateKey))
129
+ return;
130
+ const grabMin = this.minutesFromCachedY(e.clientY);
131
+ const startMin = zonedMinutesOfDay(ev.startMs, this.timeZone);
132
+ this.dragArmedId = id;
133
+ this.dragMode = 'move';
134
+ this.dragDate = dateKey;
135
+ this.dragGrabOffsetMin = grabMin - startMin;
136
+ this.dragDurationMin = Math.round((ev.endMs - ev.startMs) / 60000);
137
+ this.dragStartMin = startMin;
138
+ this.dragEndMin = startMin + this.dragDurationMin;
139
+ this.origStartMin = startMin;
140
+ this.origEndMin = startMin + this.dragDurationMin;
141
+ this.origDate = dateKey;
142
+ this.dragStartPointer = { x: e.clientX, y: e.clientY };
143
+ };
144
+ this.startResize = (e, id) => {
145
+ const ev = this.eventById(id);
146
+ if (!ev || ev.allDay || !this.editable || ev.editable === false || ev.durationEditable === false)
147
+ return;
148
+ e.stopPropagation();
149
+ const dateKey = zonedDateKey(ev.startMs, this.timeZone);
150
+ this.captureDragRects();
151
+ if (!this.gridRect || !this.colRects.some((c) => c.d === dateKey))
152
+ return;
153
+ this.dragArmedId = id;
154
+ this.dragMode = 'resize';
155
+ this.dragDate = dateKey;
156
+ this.dragStartMin = zonedMinutesOfDay(ev.startMs, this.timeZone);
157
+ this.dragEndMin = zonedMinutesOfDay(ev.endMs, this.timeZone);
158
+ this.origStartMin = this.dragStartMin;
159
+ this.origEndMin = this.dragEndMin;
160
+ this.origDate = dateKey;
161
+ this.dragStartPointer = { x: e.clientX, y: e.clientY };
162
+ };
163
+ /** Roving-tabindex keyboard nav: ↑/↓ by slot, ←/→ by day, Enter/Space to select. */
164
+ this.handleKeyDown = (e) => {
165
+ const step = this.slotMinutes;
166
+ let handled = true;
167
+ switch (e.key) {
168
+ case 'ArrowUp':
169
+ this.focusMin = clampMinutes(this.focusMin - step, this.minM, this.maxM - step);
170
+ break;
171
+ case 'ArrowDown':
172
+ this.focusMin = clampMinutes(this.focusMin + step, this.minM, this.maxM - step);
173
+ break;
174
+ case 'ArrowLeft':
175
+ this.focusDate = this.shiftFocusDate(-1);
176
+ break;
177
+ case 'ArrowRight':
178
+ this.focusDate = this.shiftFocusDate(1);
179
+ break;
180
+ case 'Enter':
181
+ case ' ': {
182
+ if (!this.isDayInteractable(this.focusDate))
183
+ break;
184
+ const start = this.toInstant(this.focusDate, this.focusMin);
185
+ const end = this.toInstant(this.focusDate, Math.min(this.focusMin + this.defaultDurationMinutes, this.maxM));
186
+ if (new Date(start).getTime() >= Date.now())
187
+ this.coRangeSelect.emit({ start, end });
188
+ break;
189
+ }
190
+ default:
191
+ handled = false;
192
+ }
193
+ if (handled) {
194
+ e.preventDefault();
195
+ e.stopPropagation();
196
+ }
197
+ };
198
+ }
199
+ componentWillLoad() {
200
+ this.refreshNow();
201
+ this.focusDate = (this.dates && this.dates[0]) || todayYMD();
202
+ this.focusMin = hhmmToMinutes(this.scrollTime, 420);
203
+ }
204
+ componentDidLoad() {
205
+ this.scrollToInitial();
206
+ this.nowTimer = window.setInterval(() => this.refreshNow(), 60000);
207
+ window.addEventListener('pointerup', this.onWindowPointerUp);
208
+ window.addEventListener('pointermove', this.onWindowPointerMove);
209
+ window.addEventListener('pointerup', this.onWindowPointerUpDrag);
210
+ }
211
+ disconnectedCallback() {
212
+ if (this.nowTimer)
213
+ window.clearInterval(this.nowTimer);
214
+ if (this.selRaf)
215
+ cancelAnimationFrame(this.selRaf);
216
+ if (this.dragRaf)
217
+ cancelAnimationFrame(this.dragRaf);
218
+ window.removeEventListener('pointerup', this.onWindowPointerUp);
219
+ window.removeEventListener('pointermove', this.onWindowPointerMove);
220
+ window.removeEventListener('pointerup', this.onWindowPointerUpDrag);
221
+ this.bindDragViewportListeners(false);
222
+ this.hideGhost();
223
+ this.colRects = [];
224
+ this.gridRect = null;
225
+ }
226
+ /** Limpia el resaltado persistente de selección (lo llama el host al cerrar
227
+ * su bubble/form de creación). */
228
+ async clearSelection() {
229
+ this.selDate = null;
230
+ }
231
+ /** Un refetch (post-save) invalida la referencia visual de la selección. */
232
+ onEventsChange() {
233
+ if (!this.selecting)
234
+ this.selDate = null;
235
+ }
236
+ refreshNow() {
237
+ const ms = Date.now();
238
+ this.nowDay = zonedDateKey(ms, this.timeZone);
239
+ this.nowMinutes = zonedMinutesOfDay(ms, this.timeZone);
240
+ }
241
+ get minM() {
242
+ return hhmmToMinutes(this.minTime, 0);
243
+ }
244
+ get maxM() {
245
+ return hhmmToMinutes(this.maxTime, 1440);
246
+ }
247
+ scrollToInitial() {
248
+ var _a, _b, _c;
249
+ const scroller = (_a = this.scrollEl) !== null && _a !== void 0 ? _a : (_b = this.el.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('.tg__scroll');
250
+ const body = (_c = this.el.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('.tg__body');
251
+ if (!scroller || !body)
252
+ return;
253
+ const frac = minutesToFraction(hhmmToMinutes(this.scrollTime, 420), this.minM, this.maxM);
254
+ scroller.scrollTop = frac * body.offsetHeight;
255
+ }
256
+ /** Visible day keys, with the same fallback the render uses. */
257
+ visibleDates() {
258
+ return this.dates.length ? this.dates : [todayYMD()];
259
+ }
260
+ /** Slot size guarded: ahora alimenta un `calc()` (un 0/NaN dejaría la grilla
261
+ * sin altura, silenciosamente). */
262
+ get slotM() {
263
+ return this.slotMinutes > 0 ? this.slotMinutes : 15;
264
+ }
265
+ /** Number of slot rows in the visible window (drives the body height). */
266
+ slotCount() {
267
+ return Math.max(1, Math.ceil((this.maxM - this.minM) / this.slotM));
268
+ }
269
+ /** Hour marks inside the visible window — one axis label each (was 1 div per
270
+ * slot with a label only on the hour). */
271
+ hourList() {
272
+ const out = [];
273
+ const first = Math.ceil(this.minM / 60) * 60;
274
+ for (let m = first; m < this.maxM; m += 60)
275
+ out.push(m);
276
+ return out;
277
+ }
278
+ /** Minutes-of-day at a clientY within a column element, snapped and clamped. */
279
+ minutesFromPointer(clientY, colEl) {
280
+ const rect = colEl.getBoundingClientRect();
281
+ return this.minutesAtFraction((clientY - rect.top) / rect.height);
282
+ }
283
+ /** Same math as minutesFromPointer but over the cached grid rect (drag path):
284
+ * cero lecturas de layout por frame. */
285
+ minutesFromCachedY(clientY) {
286
+ const g = this.gridRect;
287
+ if (!g || !g.height)
288
+ return this.minM;
289
+ return this.minutesAtFraction((clientY - g.top) / g.height);
290
+ }
291
+ minutesAtFraction(frac) {
292
+ const raw = this.minM + frac * (this.maxM - this.minM);
293
+ return clampMinutes(snapMinutes(raw, this.snapMinutes), this.minM, this.maxM);
294
+ }
295
+ /** Snapshot de la geometría de columnas al empezar un drag. Se re-toma solo
296
+ * cuando el viewport cambia (scroll del body / resize), nunca por frame. */
297
+ captureDragRects() {
298
+ const shadow = this.el.shadowRoot;
299
+ const colsEl = shadow === null || shadow === void 0 ? void 0 : shadow.querySelector('.tg__cols');
300
+ const cols = shadow === null || shadow === void 0 ? void 0 : shadow.querySelectorAll('.tg__col');
301
+ if (!colsEl || !cols || !cols.length) {
302
+ this.colRects = [];
303
+ this.gridRect = null;
304
+ return;
305
+ }
306
+ const box = colsEl.getBoundingClientRect();
307
+ this.gridRect = { top: box.top, height: box.height };
308
+ this.colRects = Array.from(cols).map((c) => {
309
+ var _a;
310
+ const r = c.getBoundingClientRect();
311
+ return { d: (_a = c.dataset.colDate) !== null && _a !== void 0 ? _a : '', left: r.left, right: r.right };
312
+ });
313
+ }
314
+ bindDragViewportListeners(on) {
315
+ const scroller = this.scrollEl;
316
+ if (on) {
317
+ scroller === null || scroller === void 0 ? void 0 : scroller.addEventListener('scroll', this.onDragViewportChange, { passive: true });
318
+ window.addEventListener('resize', this.onDragViewportChange);
319
+ }
320
+ else {
321
+ scroller === null || scroller === void 0 ? void 0 : scroller.removeEventListener('scroll', this.onDragViewportChange);
322
+ window.removeEventListener('resize', this.onDragViewportChange);
323
+ }
324
+ }
325
+ /** Marca la interacción en el root (hover/hit-testing off en los chips). No es
326
+ * @State a propósito: no debe disparar un render por drag. */
327
+ setInteracting(on) {
328
+ var _a;
329
+ (_a = this.rootEl) === null || _a === void 0 ? void 0 : _a.classList.toggle('tg--interacting', on);
330
+ }
331
+ /** Build an ISO instant (UTC) for a wall-clock minute-of-day on a given day. */
332
+ toInstant(dateKey, minutes) {
333
+ const [year, month, day] = dateKey.split('-').map(Number);
334
+ const epoch = wallClockToEpoch({ year, month, day, hour: Math.floor(minutes / 60), minute: minutes % 60, second: 0 }, this.timeZone);
335
+ return toUtcISO(epoch);
336
+ }
337
+ isDayInteractable(dateKey) {
338
+ if (this.minDate && dateKey < this.minDate)
339
+ return false;
340
+ if (this.maxDate && dateKey > this.maxDate)
341
+ return false;
342
+ return true;
343
+ }
344
+ finishSelection() {
345
+ if (!this.selecting)
346
+ return;
347
+ // Flush del frame pendiente: sin esto el rango emitido se quedaría un
348
+ // pointermove atrás del punto donde el usuario soltó.
349
+ if (this.selRaf) {
350
+ cancelAnimationFrame(this.selRaf);
351
+ this.selRaf = 0;
352
+ }
353
+ const pending = this.pendingSel;
354
+ this.pendingSel = null;
355
+ if (pending) {
356
+ const min = this.minutesFromPointer(pending.y, pending.colEl);
357
+ if (min !== this.selEndMin)
358
+ this.selEndMin = min;
359
+ }
360
+ this.selecting = false;
361
+ this.setInteracting(false);
362
+ const dateKey = this.selDate;
363
+ let a = Math.min(this.selStartMin, this.selEndMin);
364
+ let b = Math.max(this.selStartMin, this.selEndMin);
365
+ if (b - a < this.snapMinutes)
366
+ b = a + this.defaultDurationMinutes; // simple click → default duration
367
+ b = Math.min(b, this.maxM);
368
+ const rect = dateKey ? this.selectionRect(dateKey, a, b) : undefined;
369
+ if (!dateKey)
370
+ return;
371
+ const start = this.toInstant(dateKey, a);
372
+ const end = this.toInstant(dateKey, b);
373
+ if (new Date(start).getTime() < Date.now()) {
374
+ this.selDate = null; // past-block: no habrá create, limpiar el ghost
375
+ return;
376
+ }
377
+ // El ghost PERSISTE tras soltar (rango FINAL ajustado — un click simple muestra
378
+ // el bloque de duración default): referencia visual mientras el host tiene la
379
+ // bubble/form abiertos (paridad Google). Se limpia vía clearSelection() del
380
+ // host, al cambiar `events` (refetch post-save) o al iniciar otra selección.
381
+ this.selStartMin = a;
382
+ this.selEndMin = b;
383
+ this.coRangeSelect.emit({ start, end, rect });
384
+ }
385
+ /** Viewport rect of the selected span, mirroring the `.tg__selection` ghost's
386
+ * fraction math over the column's own bounding box. Never throws: falls back to
387
+ * the whole-column rect, or undefined if the column isn't in the DOM. */
388
+ selectionRect(dateKey, startMin, endMin) {
389
+ var _a;
390
+ const colEl = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`[data-col-date="${dateKey}"]`);
391
+ if (!colEl)
392
+ return undefined;
393
+ const colRect = colEl.getBoundingClientRect();
394
+ try {
395
+ const fracStart = minutesToFraction(startMin, this.minM, this.maxM);
396
+ const fracEnd = minutesToFraction(endMin, this.minM, this.maxM);
397
+ return {
398
+ top: colRect.top + fracStart * colRect.height,
399
+ left: colRect.left,
400
+ width: colRect.width,
401
+ height: (fracEnd - fracStart) * colRect.height,
402
+ };
403
+ }
404
+ catch (_b) {
405
+ return colRect;
406
+ }
407
+ }
408
+ eventById(id) {
409
+ return this.events.find((e) => e.id === id);
410
+ }
411
+ /** The day column under a clientX (week can drop across days) — resuelto por
412
+ * aritmética sobre los rects cacheados, sin tocar el DOM. */
413
+ dateKeyAtX(clientX) {
414
+ for (const c of this.colRects) {
415
+ if (clientX >= c.left && clientX < c.right)
416
+ return c.d || null;
417
+ }
418
+ return null;
419
+ }
420
+ beginDragInteraction() {
421
+ this.setInteracting(true);
422
+ this.bindDragViewportListeners(true);
423
+ this.paintGhost();
424
+ }
425
+ /** Ghost del drag escrito DIRECTO al DOM: el vdom no participa (los campos del
426
+ * drag son privados a propósito — promoverlos a @State volvería a re-renderizar
427
+ * la grilla entera por frame). */
428
+ paintGhost() {
429
+ const g = this.ghostEl;
430
+ if (!g)
431
+ return;
432
+ const nCols = this.colRects.length;
433
+ const idx = this.dragDate ? this.colRects.findIndex((c) => c.d === this.dragDate) : -1;
434
+ if (!nCols || idx < 0) {
435
+ g.style.display = 'none';
436
+ return;
437
+ }
438
+ const span = this.maxM - this.minM || 1;
439
+ const fracTop = (this.dragStartMin - this.minM) / span;
440
+ const fracH = (this.dragEndMin - this.dragStartMin) / span;
441
+ g.style.display = 'block';
442
+ g.style.left = `${(idx / nCols) * 100}%`;
443
+ g.style.width = `calc(${100 / nCols}% - 2px)`;
444
+ g.style.top = `${fracTop * 100}%`;
445
+ g.style.height = `${fracH * 100}%`;
446
+ }
447
+ hideGhost() {
448
+ if (this.ghostEl)
449
+ this.ghostEl.style.display = 'none';
450
+ }
451
+ /** Igual que extendSelection: un solo apply por frame (ver comentario allí). */
452
+ trackDrag(e) {
453
+ // Fase armado → activo: el drag se compromete recién al cruzar el umbral.
454
+ // Antes de eso NO se toca interacting/ghost, así el click de un evento
455
+ // arrastrable llega a su onClick y abre el popover.
456
+ if (this.dragArmedId && !this.dragId) {
457
+ const sp = this.dragStartPointer;
458
+ if (!sp)
459
+ return;
460
+ if (Math.hypot(e.clientX - sp.x, e.clientY - sp.y) < DRAG_THRESHOLD_PX)
461
+ return;
462
+ this.dragId = this.dragArmedId;
463
+ this.dragArmedId = null;
464
+ this.beginDragInteraction();
465
+ }
466
+ if (!this.dragId || !this.dragMode || !this.dragDate)
467
+ return;
468
+ this.pendingDrag = { x: e.clientX, y: e.clientY };
469
+ if (this.dragRaf)
470
+ return;
471
+ this.dragRaf = requestAnimationFrame(() => {
472
+ this.dragRaf = 0;
473
+ const p = this.pendingDrag;
474
+ this.pendingDrag = null;
475
+ if (p && this.dragId && this.dragMode && this.dragDate)
476
+ this.applyDrag(p.x, p.y);
477
+ });
478
+ }
479
+ applyDrag(clientX, clientY) {
480
+ var _a;
481
+ if (!this.dragId || !this.dragMode || !this.dragDate)
482
+ return;
483
+ if (!this.gridRect)
484
+ return;
485
+ const ptr = this.minutesFromCachedY(clientY);
486
+ if (this.dragMode === 'move') {
487
+ const targetDay = (_a = this.dateKeyAtX(clientX)) !== null && _a !== void 0 ? _a : this.dragDate;
488
+ let newStart = ptr - this.dragGrabOffsetMin;
489
+ newStart = clampMinutes(snapMinutes(newStart, this.snapMinutes), this.minM, this.maxM - this.dragDurationMin);
490
+ this.dragDate = targetDay;
491
+ this.dragStartMin = newStart;
492
+ this.dragEndMin = newStart + this.dragDurationMin;
493
+ }
494
+ else {
495
+ this.dragEndMin = Math.max(this.dragStartMin + this.slotMinutes, ptr);
496
+ }
497
+ this.paintGhost();
498
+ }
499
+ finishDrag() {
500
+ // pointerup habiendo solo ARMADO (sin cruzar el umbral) = fue un click, no un
501
+ // drag: desarmar en silencio y dejar pasar el click nativo → abre el popover.
502
+ if (this.dragArmedId && !this.dragId) {
503
+ this.dragArmedId = null;
504
+ this.dragStartPointer = null;
505
+ this.dragMode = null;
506
+ this.dragDate = null;
507
+ this.origDate = null;
508
+ return;
509
+ }
510
+ if (!this.dragId)
511
+ return; // pointerup sin drag activo (el listener es global)
512
+ // Flush del frame pendiente (mismo motivo que en finishSelection).
513
+ if (this.dragRaf) {
514
+ cancelAnimationFrame(this.dragRaf);
515
+ this.dragRaf = 0;
516
+ }
517
+ const pending = this.pendingDrag;
518
+ this.pendingDrag = null;
519
+ if (pending && this.dragMode && this.dragDate)
520
+ this.applyDrag(pending.x, pending.y);
521
+ this.setInteracting(false);
522
+ this.bindDragViewportListeners(false);
523
+ this.hideGhost();
524
+ this.colRects = [];
525
+ this.gridRect = null;
526
+ const id = this.dragId;
527
+ const mode = this.dragMode;
528
+ const date = this.dragDate;
529
+ const newStartMin = this.dragStartMin;
530
+ const newEndMin = this.dragEndMin;
531
+ const oStartMin = this.origStartMin;
532
+ const oEndMin = this.origEndMin;
533
+ const oDate = this.origDate;
534
+ this.dragId = null;
535
+ this.dragMode = null;
536
+ this.dragDate = null;
537
+ this.origDate = null;
538
+ this.dragStartPointer = null;
539
+ if (!id || !mode || !date)
540
+ return;
541
+ const ev = this.eventById(id);
542
+ if (!ev)
543
+ return;
544
+ // No-op detection by minutes/day (avoids ISO-canonicalization false negatives).
545
+ const changed = mode === 'move'
546
+ ? newStartMin !== oStartMin || date !== oDate
547
+ : newEndMin !== oEndMin;
548
+ if (!changed)
549
+ return;
550
+ const start = mode === 'move' ? this.toInstant(date, newStartMin) : ev.start;
551
+ const end = this.toInstant(date, newEndMin);
552
+ // Past-block on the edge actually being changed (move→start, resize→end).
553
+ const pastRef = mode === 'move' ? start : end;
554
+ if (new Date(pastRef).getTime() < Date.now())
555
+ return;
556
+ if (!this.isDayInteractable(date))
557
+ return;
558
+ this.suppressNextClick = true;
559
+ // Clear on the next macrotask: a same-target synthetic click fires before this
560
+ // (and is suppressed); a later unrelated click is not.
561
+ setTimeout(() => { this.suppressNextClick = false; }, 0);
562
+ this.coEventDrop.emit({
563
+ id,
564
+ start,
565
+ end,
566
+ oldStart: ev.start,
567
+ oldEnd: ev.end,
568
+ allDay: false,
569
+ });
570
+ }
571
+ shiftFocusDate(dir) {
572
+ const idx = this.dates.indexOf(this.focusDate);
573
+ const next = idx + dir;
574
+ if (next < 0 || next >= this.dates.length)
575
+ return this.focusDate;
576
+ return this.dates[next];
577
+ }
578
+ renderSelectionGhost() {
579
+ const a = Math.min(this.selStartMin, this.selEndMin);
580
+ const b = Math.max(this.selStartMin, this.selEndMin);
581
+ const top = minutesToFraction(a, this.minM, this.maxM);
582
+ const bottom = minutesToFraction(Math.max(b, a + this.snapMinutes), this.minM, this.maxM);
583
+ return (h("div", { class: "tg__selection", style: { top: `${top * 100}%`, height: `${(bottom - top) * 100}%` } }));
584
+ }
585
+ renderEventBox(box) {
586
+ var _a;
587
+ const ev = box.event;
588
+ const isPast = ev.endMs <= Date.now();
589
+ const isExternal = ((_a = ev.extendedProps) === null || _a === void 0 ? void 0 : _a.isExternal) === true;
590
+ const locked = !this.editable || ev.editable === false;
591
+ const widthPct = 100 / box.columnCount;
592
+ const leftPct = box.columnIndex * widthPct;
593
+ const style = {
594
+ top: `${box.topFraction * 100}%`,
595
+ height: `${box.heightFraction * 100}%`,
596
+ left: `${leftPct}%`,
597
+ width: `calc(${widthPct}% - 2px)`,
598
+ };
599
+ if (ev.backgroundColor) {
600
+ style['--co-cal-event-bg'] = ev.backgroundColor;
601
+ const textToken = readableTextToken(this.rootEl, ev.backgroundColor);
602
+ if (textToken)
603
+ style['--co-cal-event-text'] = textToken;
604
+ }
605
+ return (h("button", { type: "button", key: `${ev.id}-${box.dateKey}`, "data-event-id": ev.id, "data-date": box.dateKey, class: {
606
+ tg__event: true,
607
+ 'tg__event--past': isPast,
608
+ 'tg__event--external': isExternal,
609
+ 'tg__event--locked': locked,
610
+ 'tg__event--dragging': this.dragId === ev.id,
611
+ 'tg__event--tentative': ev.responseState === 'tentative',
612
+ 'tg__event--cancelled': ev.responseState === 'cancelled' || ev.responseState === 'declined',
613
+ }, style: style, title: ev.title, "aria-label": ev.title, onClick: (e) => {
614
+ e.stopPropagation();
615
+ if (this.suppressNextClick) {
616
+ this.suppressNextClick = false;
617
+ return;
618
+ }
619
+ this.coEventClick.emit({ id: ev.id, rect: e.currentTarget.getBoundingClientRect() });
620
+ }, onDblClick: (e) => {
621
+ e.stopPropagation();
622
+ this.coEventDblClick.emit({ id: ev.id, rect: e.currentTarget.getBoundingClientRect() });
623
+ }, onPointerDown: (e) => {
624
+ if (!locked)
625
+ this.startMove(e, ev.id);
626
+ } }, box.isStart && (h("span", { class: "tg__event-time" }, minutesToLabel(box.startMinutes, this.locale))), h("span", { class: "tg__event-title" }, ev.title || '—'), isExternal && (providerBrand(ev)
627
+ ? h("co-provider-logo", { provider: providerBrand(ev), size: 11, plated: true, class: "tg__event-ext" })
628
+ : h("co-icon", { name: "link", size: 11, class: "tg__event-ext" })), box.isEnd && !locked && ev.durationEditable !== false && (h("span", { class: "tg__event-resize", onPointerDown: (e) => this.startResize(e, ev.id) }))));
629
+ }
630
+ renderAllDayBar(seg, cols, byId) {
631
+ const ev = byId.get(seg.eventId);
632
+ if (!ev)
633
+ return null;
634
+ const left = (seg.startCol / cols) * 100;
635
+ const width = ((seg.endCol - seg.startCol + 1) / cols) * 100;
636
+ const style = {
637
+ left: `${left}%`,
638
+ width: `${width}%`,
639
+ top: `${seg.lane * ALLDAY_LANE_H}px`,
640
+ };
641
+ if (ev.backgroundColor) {
642
+ style['--co-cal-event-bg'] = ev.backgroundColor;
643
+ const textToken = readableTextToken(this.rootEl, ev.backgroundColor);
644
+ if (textToken)
645
+ style['--co-cal-event-text'] = textToken;
646
+ }
647
+ return (h("button", { type: "button", key: ev.id, "data-event-id": ev.id, class: {
648
+ 'tg__allday-bar': true,
649
+ 'tg__allday-bar--continues-before': seg.continuesBefore,
650
+ 'tg__allday-bar--continues-after': seg.continuesAfter,
651
+ 'tg__allday-bar--tentative': ev.responseState === 'tentative',
652
+ 'tg__allday-bar--cancelled': ev.responseState === 'cancelled' || ev.responseState === 'declined',
653
+ }, style: style, title: ev.title, onClick: (e) => {
654
+ e.stopPropagation();
655
+ this.coEventClick.emit({ id: ev.id, rect: e.currentTarget.getBoundingClientRect() });
656
+ }, onDblClick: (e) => {
657
+ e.stopPropagation();
658
+ this.coEventDblClick.emit({ id: ev.id, rect: e.currentTarget.getBoundingClientRect() });
659
+ } }, ev.title || '—'));
660
+ }
661
+ /** Los 3 cómputos de layout del render, memoizados por IDENTIDAD de inputs
662
+ * (`events` llega memoizado del shell): un re-render por drag/now-tick/focus
663
+ * no vuelve a empaquetar la semana. */
664
+ getLayouts(dates) {
665
+ const datesKey = dates.join(',');
666
+ const c = this.layoutCache;
667
+ if (c &&
668
+ c.events === this.events &&
669
+ c.datesKey === datesKey &&
670
+ c.tz === this.timeZone &&
671
+ c.minM === this.minM &&
672
+ c.maxM === this.maxM) {
673
+ return c;
674
+ }
675
+ const layout = layoutTimeGrid(this.events, dates, {
676
+ timeZone: this.timeZone,
677
+ minMinutes: this.minM,
678
+ maxMinutes: this.maxM,
679
+ });
680
+ const allDay = layoutAllDay(this.events, dates, { timeZone: this.timeZone });
681
+ const byId = new Map(this.events.map((e) => [e.id, e]));
682
+ this.layoutCache = {
683
+ events: this.events,
684
+ datesKey,
685
+ tz: this.timeZone,
686
+ minM: this.minM,
687
+ maxM: this.maxM,
688
+ layout,
689
+ allDay,
690
+ byId,
691
+ };
692
+ return this.layoutCache;
693
+ }
694
+ render() {
695
+ const dates = this.visibleDates();
696
+ const { layout, allDay, byId } = this.getLayouts(dates);
697
+ const short = getWeekdayLabels(this.locale, 0, 'short');
698
+ const colsTemplate = `repeat(${dates.length}, 1fr)`;
699
+ const today = todayYMD();
700
+ // La grilla ya no se dibuja con divs por slot: la altura es explícita y las
701
+ // líneas de hora salen de un background repetido (ver .tg__col en el CSS).
702
+ const bodyHeight = `calc(${this.slotCount()} * var(--co-cal-slot-h))`;
703
+ const hourVars = {
704
+ '--co-cal-hour-h': `calc(${60 / this.slotM} * var(--co-cal-slot-h))`,
705
+ '--co-cal-hour-offset': `calc(${((60 - (this.minM % 60)) % 60) / this.slotM} * var(--co-cal-slot-h))`,
706
+ };
707
+ return (h("div", { key: '6714fb717616dff758156f0fcf6d50370bcc52e0', class: "tg", tabIndex: 0, onKeyDown: this.handleKeyDown, ref: (el) => (this.rootEl = el) }, h("div", { key: '86aa3ebcc5c8c3e66fc200b25819b8806a8883fa', class: "tg__head" }, h("div", { key: '63353e0fb0765f90ecaf6942bad3323497638a17', class: "tg__head-spacer" }), h("div", { key: '842770c40be192de75e8e3d8635d2f78976ee492', class: "tg__head-days", style: { gridTemplateColumns: colsTemplate } }, dates.map((d) => {
708
+ const ymd = parseISO(d);
709
+ const dow = utcDayOfWeek(d);
710
+ return (h("div", { class: { 'tg__head-day': true, 'tg__head-day--today': compareYMD(d, today) === 0 } }, h("span", { class: "tg__head-dow" }, short[dow]), h("span", { class: "tg__head-num" }, ymd.day)));
711
+ }))), this.allDaySlot && (h("div", { key: 'f78e9159e84ecc4a0259c296e1120830b2a2513b', class: "tg__allday" }, h("div", { key: '255ad5c8e6a8c93377c2898acb8ecc06e0a0eb6d', class: "tg__allday-axis" }, gmtLabel(this.timeZone, dates[0])), h("div", { key: '5023271e34910ac5dead15f4b4a4bd4c588b6594', class: "tg__allday-lane", style: { height: `${Math.max(1, allDay.laneCount) * ALLDAY_LANE_H + 4}px` } }, allDay.segments.map((seg) => this.renderAllDayBar(seg, dates.length, byId))))), h("div", { key: '5d37824151562d8a53906ecb059d96afdee93d3e', class: "tg__scroll", ref: (el) => (this.scrollEl = el) }, h("div", { key: 'ebeac3733271bd3ebcaca2343a9f5f01285a7f05', class: "tg__body" }, h("div", { key: '9eed6c09dfe67a9613c0641dbc305ba594312166', class: "tg__axis", style: { height: bodyHeight } }, this.hourList().map((m) => (h("span", { class: "tg__axis-hour", style: { top: `${minutesToFraction(m, this.minM, this.maxM) * 100}%` } }, hourLabel(m, this.locale))))), h("div", { key: 'bc8f8c0e5bf00c8fc92bb6c823fa9ba6c321ad2c', class: "tg__cols", style: Object.assign({ gridTemplateColumns: colsTemplate, height: bodyHeight }, hourVars) }, dates.map((d, i) => {
712
+ var _a;
713
+ const isToday = compareYMD(d, today) === 0;
714
+ return (h("div", { class: { tg__col: true, 'tg__col--today': isToday }, "data-col-date": d, onPointerDown: (e) => this.startSelection(e, d, e.currentTarget), onPointerMove: (e) => this.extendSelection(e, e.currentTarget) }, this.loading
715
+ ? SKELETON_BOXES[i % SKELETON_BOXES.length].map(([top, height]) => (h("div", { class: "tg__event-skeleton", "aria-hidden": "true", style: { top: `${top}%`, height: `${height}%` } }, h("co-skeleton", { variant: "rect", width: "100%", height: "100%" }))))
716
+ : ((_a = layout.timed[d]) !== null && _a !== void 0 ? _a : []).map((box) => this.renderEventBox(box)), this.selDate === d && this.renderSelectionGhost(), this.focusDate === d && (h("div", { class: "tg__focus", style: {
717
+ top: `${minutesToFraction(this.focusMin, this.minM, this.maxM) * 100}%`,
718
+ height: `${(minutesToFraction(this.focusMin + this.slotMinutes, this.minM, this.maxM) - minutesToFraction(this.focusMin, this.minM, this.maxM)) * 100}%`,
719
+ } })), this.nowIndicator && this.nowDay === d && this.nowMinutes >= this.minM && this.nowMinutes < this.maxM && (h("div", { class: "tg__now", style: { top: `${minutesToFraction(this.nowMinutes, this.minM, this.maxM) * 100}%` } }))));
720
+ }), h("div", { class: "tg__drag-ghost", key: "tg-drag-ghost", ref: (el) => (this.ghostEl = el) }))))));
721
+ }
722
+ static get is() { return "co-calendar-timegrid"; }
723
+ static get encapsulation() { return "shadow"; }
724
+ static get originalStyleUrls() {
725
+ return {
726
+ "$": ["co-calendar-timegrid.css"]
727
+ };
728
+ }
729
+ static get styleUrls() {
730
+ return {
731
+ "$": ["co-calendar-timegrid.css"]
732
+ };
733
+ }
734
+ static get properties() {
735
+ return {
736
+ "events": {
737
+ "type": "unknown",
738
+ "mutable": false,
739
+ "complexType": {
740
+ "original": "NormalizedEvent[]",
741
+ "resolved": "NormalizedEvent[]",
742
+ "references": {
743
+ "NormalizedEvent": {
744
+ "location": "import",
745
+ "path": "@prolibu-suite/cobalt-calendar-utils",
746
+ "id": "../calendar-utils/dist/index.d.ts::NormalizedEvent",
747
+ "referenceLocation": "NormalizedEvent"
748
+ }
749
+ }
750
+ },
751
+ "required": false,
752
+ "optional": false,
753
+ "docs": {
754
+ "tags": [],
755
+ "text": ""
756
+ },
757
+ "getter": false,
758
+ "setter": false,
759
+ "defaultValue": "[]"
760
+ },
761
+ "dates": {
762
+ "type": "unknown",
763
+ "mutable": false,
764
+ "complexType": {
765
+ "original": "string[]",
766
+ "resolved": "string[]",
767
+ "references": {}
768
+ },
769
+ "required": false,
770
+ "optional": false,
771
+ "docs": {
772
+ "tags": [],
773
+ "text": "Visible day keys \"YYYY-MM-DD\" (7 = week, 1 = day)."
774
+ },
775
+ "getter": false,
776
+ "setter": false,
777
+ "defaultValue": "[]"
778
+ },
779
+ "locale": {
780
+ "type": "string",
781
+ "mutable": false,
782
+ "complexType": {
783
+ "original": "string",
784
+ "resolved": "string",
785
+ "references": {}
786
+ },
787
+ "required": false,
788
+ "optional": false,
789
+ "docs": {
790
+ "tags": [],
791
+ "text": ""
792
+ },
793
+ "getter": false,
794
+ "setter": false,
795
+ "reflect": false,
796
+ "attribute": "locale",
797
+ "defaultValue": "'es-CO'"
798
+ },
799
+ "timeZone": {
800
+ "type": "string",
801
+ "mutable": false,
802
+ "complexType": {
803
+ "original": "string",
804
+ "resolved": "string",
805
+ "references": {}
806
+ },
807
+ "required": true,
808
+ "optional": false,
809
+ "docs": {
810
+ "tags": [],
811
+ "text": ""
812
+ },
813
+ "getter": false,
814
+ "setter": false,
815
+ "reflect": false,
816
+ "attribute": "time-zone"
817
+ },
818
+ "editable": {
819
+ "type": "boolean",
820
+ "mutable": false,
821
+ "complexType": {
822
+ "original": "boolean",
823
+ "resolved": "boolean",
824
+ "references": {}
825
+ },
826
+ "required": false,
827
+ "optional": false,
828
+ "docs": {
829
+ "tags": [],
830
+ "text": ""
831
+ },
832
+ "getter": false,
833
+ "setter": false,
834
+ "reflect": false,
835
+ "attribute": "editable",
836
+ "defaultValue": "true"
837
+ },
838
+ "selectable": {
839
+ "type": "boolean",
840
+ "mutable": false,
841
+ "complexType": {
842
+ "original": "boolean",
843
+ "resolved": "boolean",
844
+ "references": {}
845
+ },
846
+ "required": false,
847
+ "optional": false,
848
+ "docs": {
849
+ "tags": [],
850
+ "text": ""
851
+ },
852
+ "getter": false,
853
+ "setter": false,
854
+ "reflect": false,
855
+ "attribute": "selectable",
856
+ "defaultValue": "true"
857
+ },
858
+ "minDate": {
859
+ "type": "string",
860
+ "mutable": false,
861
+ "complexType": {
862
+ "original": "string",
863
+ "resolved": "string | undefined",
864
+ "references": {}
865
+ },
866
+ "required": false,
867
+ "optional": true,
868
+ "docs": {
869
+ "tags": [],
870
+ "text": ""
871
+ },
872
+ "getter": false,
873
+ "setter": false,
874
+ "reflect": false,
875
+ "attribute": "min-date"
876
+ },
877
+ "maxDate": {
878
+ "type": "string",
879
+ "mutable": false,
880
+ "complexType": {
881
+ "original": "string",
882
+ "resolved": "string | undefined",
883
+ "references": {}
884
+ },
885
+ "required": false,
886
+ "optional": true,
887
+ "docs": {
888
+ "tags": [],
889
+ "text": ""
890
+ },
891
+ "getter": false,
892
+ "setter": false,
893
+ "reflect": false,
894
+ "attribute": "max-date"
895
+ },
896
+ "slotMinutes": {
897
+ "type": "number",
898
+ "mutable": false,
899
+ "complexType": {
900
+ "original": "number",
901
+ "resolved": "number",
902
+ "references": {}
903
+ },
904
+ "required": false,
905
+ "optional": false,
906
+ "docs": {
907
+ "tags": [],
908
+ "text": ""
909
+ },
910
+ "getter": false,
911
+ "setter": false,
912
+ "reflect": false,
913
+ "attribute": "slot-minutes",
914
+ "defaultValue": "15"
915
+ },
916
+ "snapMinutes": {
917
+ "type": "number",
918
+ "mutable": false,
919
+ "complexType": {
920
+ "original": "number",
921
+ "resolved": "number",
922
+ "references": {}
923
+ },
924
+ "required": false,
925
+ "optional": false,
926
+ "docs": {
927
+ "tags": [],
928
+ "text": ""
929
+ },
930
+ "getter": false,
931
+ "setter": false,
932
+ "reflect": false,
933
+ "attribute": "snap-minutes",
934
+ "defaultValue": "15"
935
+ },
936
+ "defaultDurationMinutes": {
937
+ "type": "number",
938
+ "mutable": false,
939
+ "complexType": {
940
+ "original": "number",
941
+ "resolved": "number",
942
+ "references": {}
943
+ },
944
+ "required": false,
945
+ "optional": false,
946
+ "docs": {
947
+ "tags": [],
948
+ "text": ""
949
+ },
950
+ "getter": false,
951
+ "setter": false,
952
+ "reflect": false,
953
+ "attribute": "default-duration-minutes",
954
+ "defaultValue": "60"
955
+ },
956
+ "scrollTime": {
957
+ "type": "string",
958
+ "mutable": false,
959
+ "complexType": {
960
+ "original": "string",
961
+ "resolved": "string",
962
+ "references": {}
963
+ },
964
+ "required": false,
965
+ "optional": false,
966
+ "docs": {
967
+ "tags": [],
968
+ "text": ""
969
+ },
970
+ "getter": false,
971
+ "setter": false,
972
+ "reflect": false,
973
+ "attribute": "scroll-time",
974
+ "defaultValue": "'07:00'"
975
+ },
976
+ "nowIndicator": {
977
+ "type": "boolean",
978
+ "mutable": false,
979
+ "complexType": {
980
+ "original": "boolean",
981
+ "resolved": "boolean",
982
+ "references": {}
983
+ },
984
+ "required": false,
985
+ "optional": false,
986
+ "docs": {
987
+ "tags": [],
988
+ "text": ""
989
+ },
990
+ "getter": false,
991
+ "setter": false,
992
+ "reflect": false,
993
+ "attribute": "now-indicator",
994
+ "defaultValue": "true"
995
+ },
996
+ "loading": {
997
+ "type": "boolean",
998
+ "mutable": false,
999
+ "complexType": {
1000
+ "original": "boolean",
1001
+ "resolved": "boolean",
1002
+ "references": {}
1003
+ },
1004
+ "required": false,
1005
+ "optional": false,
1006
+ "docs": {
1007
+ "tags": [],
1008
+ "text": "Cargando: en vez de los eventos pinta bloques skeleton en las columnas.\nLa grilla (eje de horas, l\u00EDneas, cabecera de d\u00EDas, franja de todo-el-d\u00EDa)\nse mantiene: lo \u00FAnico que todav\u00EDa no se sabe son los eventos."
1009
+ },
1010
+ "getter": false,
1011
+ "setter": false,
1012
+ "reflect": false,
1013
+ "attribute": "loading",
1014
+ "defaultValue": "false"
1015
+ },
1016
+ "allDaySlot": {
1017
+ "type": "boolean",
1018
+ "mutable": false,
1019
+ "complexType": {
1020
+ "original": "boolean",
1021
+ "resolved": "boolean",
1022
+ "references": {}
1023
+ },
1024
+ "required": false,
1025
+ "optional": false,
1026
+ "docs": {
1027
+ "tags": [],
1028
+ "text": ""
1029
+ },
1030
+ "getter": false,
1031
+ "setter": false,
1032
+ "reflect": false,
1033
+ "attribute": "all-day-slot",
1034
+ "defaultValue": "true"
1035
+ },
1036
+ "minTime": {
1037
+ "type": "string",
1038
+ "mutable": false,
1039
+ "complexType": {
1040
+ "original": "string",
1041
+ "resolved": "string",
1042
+ "references": {}
1043
+ },
1044
+ "required": false,
1045
+ "optional": false,
1046
+ "docs": {
1047
+ "tags": [],
1048
+ "text": ""
1049
+ },
1050
+ "getter": false,
1051
+ "setter": false,
1052
+ "reflect": false,
1053
+ "attribute": "min-time",
1054
+ "defaultValue": "'00:00'"
1055
+ },
1056
+ "maxTime": {
1057
+ "type": "string",
1058
+ "mutable": false,
1059
+ "complexType": {
1060
+ "original": "string",
1061
+ "resolved": "string",
1062
+ "references": {}
1063
+ },
1064
+ "required": false,
1065
+ "optional": false,
1066
+ "docs": {
1067
+ "tags": [],
1068
+ "text": ""
1069
+ },
1070
+ "getter": false,
1071
+ "setter": false,
1072
+ "reflect": false,
1073
+ "attribute": "max-time",
1074
+ "defaultValue": "'24:00'"
1075
+ }
1076
+ };
1077
+ }
1078
+ static get states() {
1079
+ return {
1080
+ "nowMinutes": {},
1081
+ "nowDay": {},
1082
+ "focusDate": {},
1083
+ "focusMin": {},
1084
+ "selDate": {},
1085
+ "selStartMin": {},
1086
+ "selEndMin": {},
1087
+ "dragId": {}
1088
+ };
1089
+ }
1090
+ static get events() {
1091
+ return [{
1092
+ "method": "coRangeSelect",
1093
+ "name": "coRangeSelect",
1094
+ "bubbles": false,
1095
+ "cancelable": true,
1096
+ "composed": false,
1097
+ "docs": {
1098
+ "tags": [],
1099
+ "text": "A time range was selected on an empty area (create request)."
1100
+ },
1101
+ "complexType": {
1102
+ "original": "{\n start: string;\n end: string;\n /** Viewport-anchored rect of the selected area, for the host to anchor a quick-create bubble. */\n rect?: { top: number; left: number; width: number; height: number };\n }",
1103
+ "resolved": "{ start: string; end: string; rect?: { top: number; left: number; width: number; height: number; } | undefined; }",
1104
+ "references": {}
1105
+ }
1106
+ }, {
1107
+ "method": "coEventClick",
1108
+ "name": "coEventClick",
1109
+ "bubbles": false,
1110
+ "cancelable": true,
1111
+ "composed": false,
1112
+ "docs": {
1113
+ "tags": [],
1114
+ "text": ""
1115
+ },
1116
+ "complexType": {
1117
+ "original": "{ id: string; rect?: DOMRect }",
1118
+ "resolved": "{ id: string; rect?: DOMRect | undefined; }",
1119
+ "references": {
1120
+ "DOMRect": {
1121
+ "location": "global",
1122
+ "id": "global::DOMRect"
1123
+ }
1124
+ }
1125
+ }
1126
+ }, {
1127
+ "method": "coEventDrop",
1128
+ "name": "coEventDrop",
1129
+ "bubbles": false,
1130
+ "cancelable": true,
1131
+ "composed": false,
1132
+ "docs": {
1133
+ "tags": [],
1134
+ "text": ""
1135
+ },
1136
+ "complexType": {
1137
+ "original": "{\n id: string; start: string; end: string; oldStart: string; oldEnd: string; allDay: boolean;\n }",
1138
+ "resolved": "{ id: string; start: string; end: string; oldStart: string; oldEnd: string; allDay: boolean; }",
1139
+ "references": {}
1140
+ }
1141
+ }, {
1142
+ "method": "coEventDblClick",
1143
+ "name": "coEventDblClick",
1144
+ "bubbles": false,
1145
+ "cancelable": true,
1146
+ "composed": false,
1147
+ "docs": {
1148
+ "tags": [],
1149
+ "text": "Doble activaci\u00F3n de un chip (direct-edit request del host)."
1150
+ },
1151
+ "complexType": {
1152
+ "original": "{ id: string; rect?: DOMRect }",
1153
+ "resolved": "{ id: string; rect?: DOMRect | undefined; }",
1154
+ "references": {
1155
+ "DOMRect": {
1156
+ "location": "global",
1157
+ "id": "global::DOMRect"
1158
+ }
1159
+ }
1160
+ }
1161
+ }];
1162
+ }
1163
+ static get methods() {
1164
+ return {
1165
+ "clearSelection": {
1166
+ "complexType": {
1167
+ "signature": "() => Promise<void>",
1168
+ "parameters": [],
1169
+ "references": {
1170
+ "Promise": {
1171
+ "location": "global",
1172
+ "id": "global::Promise"
1173
+ }
1174
+ },
1175
+ "return": "Promise<void>"
1176
+ },
1177
+ "docs": {
1178
+ "text": "Limpia el resaltado persistente de selecci\u00F3n (lo llama el host al cerrar\nsu bubble/form de creaci\u00F3n).",
1179
+ "tags": []
1180
+ }
1181
+ }
1182
+ };
1183
+ }
1184
+ static get elementRef() { return "el"; }
1185
+ static get watchers() {
1186
+ return [{
1187
+ "propName": "events",
1188
+ "methodName": "onEventsChange"
1189
+ }];
1190
+ }
1191
+ }
1192
+ // ── helpers ─────────────────────────────────────────────────────────────────
1193
+ function hhmmToMinutes(hhmm, fallback) {
1194
+ const m = /^(\d{1,2}):(\d{2})$/.exec(hhmm);
1195
+ if (!m)
1196
+ return fallback;
1197
+ return Number(m[1]) * 60 + Number(m[2]);
1198
+ }
1199
+ /** UTC day-of-week (0=Sun) of a date-only key — tz-independent. */
1200
+ function utcDayOfWeek(dateKey) {
1201
+ const [y, mo, d] = dateKey.split('-').map(Number);
1202
+ return new Date(Date.UTC(y, mo - 1, d)).getUTCDay();
1203
+ }
1204
+ // Intl.DateTimeFormat es caro de construir y estos tres labels se recalculan por
1205
+ // frame sobre un dominio ACOTADO (≤96 minutos distintos, ≤24 horas, 1-2 locales):
1206
+ // cacheamos el RESULTADO (y el formatter, para el miss). Higiene: clear a las 2000
1207
+ // entradas — inalcanzable en uso normal, solo protege de iteración patológica.
1208
+ const MINUTE_LABEL_CACHE = new Map();
1209
+ const MINUTE_FMT_CACHE = new Map();
1210
+ const HOUR_LABEL_CACHE = new Map();
1211
+ const HOUR_FMT_CACHE = new Map();
1212
+ const GMT_LABEL_CACHE = new Map();
1213
+ function minutesToLabel(minutes, locale) {
1214
+ const key = `${locale}|${minutes}`;
1215
+ const hit = MINUTE_LABEL_CACHE.get(key);
1216
+ if (hit !== undefined)
1217
+ return hit;
1218
+ let fmt = MINUTE_FMT_CACHE.get(locale);
1219
+ if (!fmt) {
1220
+ fmt = new Intl.DateTimeFormat(locale, { hour: 'numeric', minute: '2-digit' });
1221
+ MINUTE_FMT_CACHE.set(locale, fmt);
1222
+ }
1223
+ const h = Math.floor(minutes / 60);
1224
+ const m = minutes % 60;
1225
+ const out = fmt.format(new Date(2000, 0, 1, h, m));
1226
+ if (MINUTE_LABEL_CACHE.size > 2000)
1227
+ MINUTE_LABEL_CACHE.clear();
1228
+ MINUTE_LABEL_CACHE.set(key, out);
1229
+ return out;
1230
+ }
1231
+ /** Bloques del skeleton por columna, `[top%, alto%]` sobre el alto del día.
1232
+ * Patrón FIJO (jamás random: tiene que verse igual entre renders) y desparejo
1233
+ * entre columnas, como una agenda de verdad. */
1234
+ const SKELETON_BOXES = [
1235
+ [[26, 8], [42, 12]],
1236
+ [[30, 14]],
1237
+ [[24, 6], [38, 9], [56, 7]],
1238
+ [[34, 11], [52, 6]],
1239
+ [[28, 9]],
1240
+ [[40, 13], [60, 8]],
1241
+ [[32, 7], [46, 10]],
1242
+ ];
1243
+ /** Marca del evento externo (`co-provider-logo`), o '' si no se reconoce — el
1244
+ * llamador cae al ícono genérico de enlace. */
1245
+ function providerBrand(ev) {
1246
+ var _a, _b;
1247
+ const p = String((_b = (_a = ev.extendedProps) === null || _a === void 0 ? void 0 : _a.provider) !== null && _b !== void 0 ? _b : '').toLowerCase();
1248
+ if (p.includes('google'))
1249
+ return 'google';
1250
+ if (p.includes('microsoft') || p.includes('outlook'))
1251
+ return 'microsoft';
1252
+ return '';
1253
+ }
1254
+ /** Hour-only 12h label for the time axis, e.g. "10 a. m." / "1 p. m." (Google style).
1255
+ * hour12 forzado: locales 24h (p.ej. "es" pelado) darían números sueltos sin am/pm. */
1256
+ function hourLabel(minutes, locale) {
1257
+ const key = `${locale}|${minutes}`;
1258
+ const hit = HOUR_LABEL_CACHE.get(key);
1259
+ if (hit !== undefined)
1260
+ return hit;
1261
+ let fmt = HOUR_FMT_CACHE.get(locale);
1262
+ if (!fmt) {
1263
+ fmt = new Intl.DateTimeFormat(locale, { hour: 'numeric', hour12: true });
1264
+ HOUR_FMT_CACHE.set(locale, fmt);
1265
+ }
1266
+ const h = Math.floor(minutes / 60);
1267
+ const out = fmt.format(new Date(2000, 0, 1, h, 0));
1268
+ if (HOUR_LABEL_CACHE.size > 2000)
1269
+ HOUR_LABEL_CACHE.clear();
1270
+ HOUR_LABEL_CACHE.set(key, out);
1271
+ return out;
1272
+ }
1273
+ /** Timezone offset label for the axis corner, e.g. "GMT-05" (like Google Calendar). */
1274
+ function gmtLabel(timeZone, refYMD) {
1275
+ if (!timeZone)
1276
+ return '';
1277
+ const key = `${timeZone}|${refYMD !== null && refYMD !== void 0 ? refYMD : ''}`;
1278
+ const hit = GMT_LABEL_CACHE.get(key);
1279
+ if (hit !== undefined)
1280
+ return hit;
1281
+ const out = computeGmtLabel(timeZone, refYMD);
1282
+ if (GMT_LABEL_CACHE.size > 2000)
1283
+ GMT_LABEL_CACHE.clear();
1284
+ GMT_LABEL_CACHE.set(key, out);
1285
+ return out;
1286
+ }
1287
+ function computeGmtLabel(timeZone, refYMD) {
1288
+ var _a, _b;
1289
+ try {
1290
+ const d = new Date(`${refYMD !== null && refYMD !== void 0 ? refYMD : '2026-01-01'}T12:00:00Z`);
1291
+ const parts = new Intl.DateTimeFormat('en-US', {
1292
+ timeZone,
1293
+ timeZoneName: 'shortOffset',
1294
+ }).formatToParts(d);
1295
+ const raw = (_b = (_a = parts.find((p) => p.type === 'timeZoneName')) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : '';
1296
+ const m = raw.match(/GMT([+-])(\d{1,2})(?::(\d{2}))?/);
1297
+ if (!m)
1298
+ return raw;
1299
+ const hh = m[2].padStart(2, '0');
1300
+ return m[3] ? `GMT${m[1]}${hh}:${m[3]}` : `GMT${m[1]}${hh}`;
1301
+ }
1302
+ catch (_c) {
1303
+ return '';
1304
+ }
1305
+ }