@livenetworks/ashlar 1.6.1 → 2.0.1

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 (559) hide show
  1. package/LICENSE +641 -0
  2. package/README.md +190 -86
  3. package/{js → components}/COMPONENTS.md +1116 -1108
  4. package/{js → components}/index.js +81 -58
  5. package/{js → components}/ln-accordion/README.md +7 -6
  6. package/components/ln-accordion/ln-accordion-dev.scss +8 -0
  7. package/components/ln-accordion/ln-accordion.js +1 -0
  8. package/components/ln-accordion/ln-accordion.schema.json +30 -0
  9. package/components/ln-accordion/ln-accordion.scss +8 -0
  10. package/{js → components}/ln-accordion/src/ln-accordion.js +8 -2
  11. package/{js → components}/ln-ajax/README.md +171 -160
  12. package/components/ln-ajax/ln-ajax-dev.scss +8 -0
  13. package/components/ln-ajax/ln-ajax.js +1 -0
  14. package/components/ln-ajax/ln-ajax.schema.json +30 -0
  15. package/{js → components}/ln-ajax/src/ln-ajax.js +65 -30
  16. package/{js → components}/ln-api-connector/README.md +27 -5
  17. package/components/ln-api-connector/ln-api-connector.js +1 -0
  18. package/components/ln-api-connector/ln-api-connector.schema.json +96 -0
  19. package/components/ln-api-connector/src/connector-core.js +97 -0
  20. package/components/ln-api-connector/src/ln-api-connector.js +447 -0
  21. package/{js → components}/ln-api-queue/README.md +12 -9
  22. package/components/ln-api-queue/ln-api-queue.js +1 -0
  23. package/components/ln-api-queue/ln-api-queue.schema.json +34 -0
  24. package/{js → components}/ln-api-queue/src/ln-api-queue.js +33 -14
  25. package/{js → components}/ln-api-queue/src/queue-storage.js +7 -3
  26. package/{js → components}/ln-autoresize/README.md +129 -127
  27. package/components/ln-autoresize/ln-autoresize-dev.scss +8 -0
  28. package/components/ln-autoresize/ln-autoresize.js +1 -0
  29. package/components/ln-autoresize/ln-autoresize.schema.json +22 -0
  30. package/{js → components}/ln-autoresize/src/ln-autoresize.js +8 -1
  31. package/{js → components}/ln-autosave/README.md +127 -124
  32. package/components/ln-autosave/ln-autosave-dev.scss +13 -0
  33. package/components/ln-autosave/ln-autosave.js +1 -0
  34. package/components/ln-autosave/ln-autosave.schema.json +48 -0
  35. package/components/ln-autosave/src/autosave-model.js +34 -0
  36. package/{js → components}/ln-autosave/src/ln-autosave.js +65 -58
  37. package/components/ln-chart/README.md +145 -0
  38. package/components/ln-chart/ln-chart-dev.scss +20 -0
  39. package/components/ln-chart/ln-chart.js +1 -0
  40. package/components/ln-chart/ln-chart.schema.json +146 -0
  41. package/components/ln-chart/ln-chart.scss +8 -0
  42. package/components/ln-chart/src/chart-model.js +154 -0
  43. package/components/ln-chart/src/ln-chart.js +176 -0
  44. package/{js → components}/ln-circular-progress/README.md +15 -14
  45. package/components/ln-circular-progress/ln-circular-progress-dev.scss +8 -0
  46. package/components/ln-circular-progress/ln-circular-progress.js +1 -0
  47. package/components/ln-circular-progress/ln-circular-progress.schema.json +42 -0
  48. package/{js → components}/ln-circular-progress/src/ln-circular-progress.js +32 -50
  49. package/{js → components}/ln-confirm/README.md +69 -18
  50. package/components/ln-confirm/ln-confirm-dev.scss +24 -0
  51. package/components/ln-confirm/ln-confirm.js +1 -0
  52. package/components/ln-confirm/ln-confirm.schema.json +66 -0
  53. package/components/ln-confirm/ln-confirm.scss +24 -0
  54. package/{js → components}/ln-confirm/src/ln-confirm.js +180 -171
  55. package/{js → components}/ln-core/README.md +374 -149
  56. package/components/ln-core/attrs.js +273 -0
  57. package/components/ln-core/compare.js +40 -0
  58. package/components/ln-core/crypto.js +265 -0
  59. package/components/ln-core/date.js +50 -0
  60. package/components/ln-core/dom.js +115 -0
  61. package/components/ln-core/events.js +122 -0
  62. package/components/ln-core/form.js +136 -0
  63. package/{js → components}/ln-core/hash.js +149 -92
  64. package/components/ln-core/helpers.js +33 -0
  65. package/components/ln-core/http.js +48 -0
  66. package/components/ln-core/index.js +11 -0
  67. package/components/ln-core/lifecycle.js +403 -0
  68. package/components/ln-core/ln-core.schema.json +109 -0
  69. package/components/ln-core/locale.js +55 -0
  70. package/components/ln-core/matching.js +78 -0
  71. package/components/ln-core/number.js +125 -0
  72. package/components/ln-core/progress.js +30 -0
  73. package/components/ln-core/template.js +206 -0
  74. package/{js → components}/ln-core/window-cache.js +247 -213
  75. package/{js → components}/ln-couchdb-connector/README.md +7 -5
  76. package/components/ln-couchdb-connector/ln-couchdb-connector.js +1 -0
  77. package/components/ln-couchdb-connector/ln-couchdb-connector.schema.json +50 -0
  78. package/{js → components}/ln-couchdb-connector/src/ln-couchdb-connector.js +29 -43
  79. package/{js → components}/ln-data-coordinator/README.md +109 -73
  80. package/components/ln-data-coordinator/ln-data-coordinator-dev.scss +8 -0
  81. package/components/ln-data-coordinator/ln-data-coordinator.js +1 -0
  82. package/components/ln-data-coordinator/ln-data-coordinator.schema.json +196 -0
  83. package/components/ln-data-coordinator/src/data-read-policy.js +41 -0
  84. package/{js → components}/ln-data-coordinator/src/ln-data-coordinator.js +411 -154
  85. package/{js → components}/ln-data-coordinator/src/mutation-receipts.js +0 -5
  86. package/{js → components}/ln-data-store/README.md +42 -17
  87. package/components/ln-data-store/ln-data-store-dev.scss +13 -0
  88. package/components/ln-data-store/ln-data-store.js +1 -0
  89. package/components/ln-data-store/ln-data-store.schema.json +84 -0
  90. package/components/ln-data-store/src/data-store-model.js +155 -0
  91. package/{js → components}/ln-data-store/src/ln-data-store.js +407 -105
  92. package/components/ln-data-store/src/window-index.js +119 -0
  93. package/{js → components}/ln-date/README.md +17 -7
  94. package/{js → components}/ln-date/ln-date-dev.scss +14 -14
  95. package/components/ln-date/ln-date.js +1 -0
  96. package/components/ln-date/ln-date.schema.json +92 -0
  97. package/components/ln-date/src/date-model.js +186 -0
  98. package/components/ln-date/src/ln-date.js +486 -0
  99. package/components/ln-debug/README.md +132 -0
  100. package/components/ln-debug/ln-debug.js +1 -0
  101. package/components/ln-debug/ln-debug.schema.json +28 -0
  102. package/components/ln-debug/src/console-sink.js +19 -0
  103. package/components/ln-debug/src/debug-verifier.js +331 -0
  104. package/components/ln-debug/src/gate.js +95 -0
  105. package/components/ln-debug/src/generated-attributes.js +299 -0
  106. package/components/ln-debug/src/ln-debug.js +60 -0
  107. package/{js → components}/ln-dropdown/README.md +150 -140
  108. package/components/ln-dropdown/ln-dropdown-dev.scss +13 -0
  109. package/components/ln-dropdown/ln-dropdown.js +1 -0
  110. package/components/ln-dropdown/ln-dropdown.schema.json +90 -0
  111. package/components/ln-dropdown/ln-dropdown.scss +18 -0
  112. package/{js → components}/ln-dropdown/src/ln-dropdown.js +114 -11
  113. package/{js → components}/ln-editor/README.md +11 -9
  114. package/components/ln-editor/ln-editor-dev.scss +18 -0
  115. package/components/ln-editor/ln-editor.js +1 -0
  116. package/components/ln-editor/ln-editor.schema.json +58 -0
  117. package/components/ln-editor/ln-editor.scss +13 -0
  118. package/{js → components}/ln-editor/src/ln-editor.js +59 -11
  119. package/{js → components}/ln-external-links/README.md +10 -8
  120. package/components/ln-external-links/ln-external-links.js +1 -0
  121. package/components/ln-external-links/ln-external-links.schema.json +18 -0
  122. package/{js → components}/ln-external-links/src/ln-external-links.js +13 -11
  123. package/{js → components}/ln-fill/README.md +6 -8
  124. package/components/ln-fill/ln-fill.js +1 -0
  125. package/components/ln-fill/ln-fill.schema.json +23 -0
  126. package/{js → components}/ln-fill/src/ln-fill.js +7 -1
  127. package/components/ln-filter/README.md +131 -0
  128. package/components/ln-filter/ln-filter-dev.scss +13 -0
  129. package/components/ln-filter/ln-filter.js +1 -0
  130. package/components/ln-filter/ln-filter.schema.json +153 -0
  131. package/components/ln-filter/src/filter-model.js +185 -0
  132. package/components/ln-filter/src/ln-filter.js +435 -0
  133. package/{js → components}/ln-form/README.md +260 -264
  134. package/components/ln-form/ln-form-dev.scss +8 -0
  135. package/components/ln-form/ln-form.js +1 -0
  136. package/components/ln-form/ln-form.schema.json +45 -0
  137. package/{js → components}/ln-form/src/ln-form.js +107 -99
  138. package/{js → components}/ln-http/README.md +11 -6
  139. package/components/ln-http/ln-http.js +1 -0
  140. package/components/ln-http/ln-http.schema.json +6 -0
  141. package/components/ln-http/src/http-core.js +51 -0
  142. package/{js → components}/ln-http/src/ln-http.js +28 -33
  143. package/{js → components}/ln-icon/README.md +16 -9
  144. package/components/ln-icon/ln-icon.schema.json +6 -0
  145. package/components/ln-include/README.md +75 -0
  146. package/components/ln-include/ln-include-dev.scss +13 -0
  147. package/components/ln-include/ln-include.js +1 -0
  148. package/components/ln-include/ln-include.schema.json +23 -0
  149. package/components/ln-include/src/ln-include.js +111 -0
  150. package/components/ln-key/README.md +130 -0
  151. package/components/ln-key/ln-key-dev.scss +18 -0
  152. package/components/ln-key/ln-key.js +1 -0
  153. package/components/ln-key/ln-key.schema.json +56 -0
  154. package/components/ln-key/src/key-model.js +146 -0
  155. package/components/ln-key/src/ln-key.js +201 -0
  156. package/{js → components}/ln-link/README.md +7 -9
  157. package/components/ln-link/ln-link-dev.scss +8 -0
  158. package/components/ln-link/ln-link.js +1 -0
  159. package/components/ln-link/ln-link.schema.json +22 -0
  160. package/{js → components}/ln-link/src/ln-link.js +16 -11
  161. package/components/ln-list/README.md +152 -0
  162. package/components/ln-list/ln-list-dev.scss +8 -0
  163. package/components/ln-list/ln-list.js +1 -0
  164. package/components/ln-list/ln-list.schema.json +166 -0
  165. package/components/ln-list/ln-list.scss +25 -0
  166. package/{js → components}/ln-list/src/ln-list.js +1301 -1216
  167. package/{js → components}/ln-modal/README.md +13 -10
  168. package/components/ln-modal/ln-modal-dev.scss +18 -0
  169. package/components/ln-modal/ln-modal.js +1 -0
  170. package/components/ln-modal/ln-modal.schema.json +54 -0
  171. package/components/ln-modal/ln-modal.scss +51 -0
  172. package/{js → components}/ln-modal/src/ln-modal.js +164 -137
  173. package/{js → components}/ln-nav/README.md +11 -11
  174. package/components/ln-nav/ln-nav.js +1 -0
  175. package/components/ln-nav/ln-nav.schema.json +25 -0
  176. package/{js → components}/ln-nav/src/ln-nav.js +25 -14
  177. package/components/ln-number/README.md +205 -0
  178. package/{js → components}/ln-number/ln-number-dev.scss +13 -13
  179. package/components/ln-number/ln-number.js +1 -0
  180. package/components/ln-number/ln-number.schema.json +63 -0
  181. package/components/ln-number/src/ln-number.js +400 -0
  182. package/components/ln-number/src/number-model.js +31 -0
  183. package/components/ln-obfuscator/README.md +60 -0
  184. package/components/ln-obfuscator/ln-obfuscator.js +1 -0
  185. package/components/ln-obfuscator/ln-obfuscator.schema.json +49 -0
  186. package/components/ln-obfuscator/src/ln-obfuscator.js +159 -0
  187. package/components/ln-obfuscator/src/obfuscator-model.js +250 -0
  188. package/{js → components}/ln-options/README.md +3 -1
  189. package/components/ln-options/ln-options-dev.scss +13 -0
  190. package/components/ln-options/ln-options.js +1 -0
  191. package/components/ln-options/ln-options.schema.json +41 -0
  192. package/{js → components}/ln-options/src/ln-options.js +13 -5
  193. package/components/ln-persist/README.md +151 -0
  194. package/components/ln-persist/ln-persist.js +1 -0
  195. package/components/ln-persist/ln-persist.schema.json +28 -0
  196. package/components/ln-persist/src/ln-persist.js +83 -0
  197. package/components/ln-picklist/README.md +230 -0
  198. package/components/ln-picklist/ln-picklist-dev.scss +22 -0
  199. package/components/ln-picklist/ln-picklist.js +1 -0
  200. package/components/ln-picklist/ln-picklist.schema.json +49 -0
  201. package/components/ln-picklist/src/ln-picklist.js +228 -0
  202. package/{js → components}/ln-popover/README.md +164 -162
  203. package/components/ln-popover/ln-popover-dev.scss +13 -0
  204. package/components/ln-popover/ln-popover.js +1 -0
  205. package/components/ln-popover/ln-popover.schema.json +82 -0
  206. package/components/ln-popover/ln-popover.scss +18 -0
  207. package/{js → components}/ln-popover/src/ln-popover.js +42 -36
  208. package/{js → components}/ln-progress/README.md +410 -413
  209. package/components/ln-progress/ln-progress-dev.scss +8 -0
  210. package/components/ln-progress/ln-progress.js +1 -0
  211. package/components/ln-progress/ln-progress.schema.json +40 -0
  212. package/components/ln-progress/src/ln-progress.js +91 -0
  213. package/components/ln-progress/src/progress-model.js +20 -0
  214. package/{js → components}/ln-router/README.md +443 -432
  215. package/components/ln-router/ln-router-dev.scss +13 -0
  216. package/components/ln-router/ln-router.js +1 -0
  217. package/components/ln-router/ln-router.schema.json +68 -0
  218. package/{js → components}/ln-router/src/ln-router.js +585 -539
  219. package/components/ln-router/src/router-model.js +50 -0
  220. package/components/ln-scroll/README.md +45 -0
  221. package/components/ln-scroll/ln-scroll.js +1 -0
  222. package/components/ln-scroll/ln-scroll.schema.json +85 -0
  223. package/components/ln-scroll/src/ln-scroll.js +150 -0
  224. package/components/ln-search/README.md +188 -0
  225. package/components/ln-search/ln-search-dev.scss +13 -0
  226. package/components/ln-search/ln-search.js +1 -0
  227. package/components/ln-search/ln-search.schema.json +103 -0
  228. package/components/ln-search/src/ln-search.js +330 -0
  229. package/{js → components}/ln-slug/README.md +6 -3
  230. package/components/ln-slug/ln-slug-dev.scss +18 -0
  231. package/components/ln-slug/ln-slug.js +1 -0
  232. package/components/ln-slug/ln-slug.schema.json +23 -0
  233. package/{js → components}/ln-slug/src/ln-slug.js +20 -13
  234. package/components/ln-slug/src/slug-model.js +21 -0
  235. package/{js → components}/ln-sort/README.md +178 -170
  236. package/{js → components}/ln-sort/ln-sort-dev.scss +8 -8
  237. package/components/ln-sort/ln-sort.js +1 -0
  238. package/components/ln-sort/ln-sort.schema.json +104 -0
  239. package/components/ln-sort/src/ln-sort.js +321 -0
  240. package/components/ln-sort/src/sort-model.js +117 -0
  241. package/{js → components}/ln-sortable/README.md +7 -11
  242. package/components/ln-sortable/ln-sortable-dev.scss +13 -0
  243. package/components/ln-sortable/ln-sortable.js +1 -0
  244. package/components/ln-sortable/ln-sortable.schema.json +36 -0
  245. package/{js → components}/ln-sortable/src/ln-sortable.js +8 -13
  246. package/{js → components}/ln-stat/README.md +3 -1
  247. package/components/ln-stat/ln-stat-dev.scss +8 -0
  248. package/components/ln-stat/ln-stat.js +1 -0
  249. package/components/ln-stat/ln-stat.schema.json +32 -0
  250. package/{js → components}/ln-stat/src/ln-stat.js +14 -18
  251. package/components/ln-stat/src/stat-model.js +28 -0
  252. package/{js → components}/ln-table/README.md +37 -24
  253. package/{js → components}/ln-table/ln-table-dev.scss +17 -17
  254. package/components/ln-table/ln-table.js +1 -0
  255. package/components/ln-table/ln-table.schema.json +211 -0
  256. package/components/ln-table/ln-table.scss +15 -0
  257. package/{js → components}/ln-table/src/ln-table.js +1365 -1493
  258. package/components/ln-table/src/table-model.js +98 -0
  259. package/components/ln-table-coordinator/README.md +61 -0
  260. package/components/ln-table-coordinator/ln-table-coordinator.js +1 -0
  261. package/components/ln-table-coordinator/ln-table-coordinator.schema.json +93 -0
  262. package/components/ln-table-coordinator/src/ln-table-coordinator.js +193 -0
  263. package/{js → components}/ln-tabs/README.md +32 -14
  264. package/components/ln-tabs/ln-tabs-dev.scss +24 -0
  265. package/components/ln-tabs/ln-tabs.js +1 -0
  266. package/components/ln-tabs/ln-tabs.schema.json +75 -0
  267. package/components/ln-tabs/ln-tabs.scss +8 -0
  268. package/components/ln-tabs/src/ln-tabs.js +207 -0
  269. package/components/ln-tabs/src/tabs-model.js +82 -0
  270. package/{js → components}/ln-time/README.md +96 -95
  271. package/components/ln-time/ln-time-dev.scss +13 -0
  272. package/components/ln-time/ln-time.js +1 -0
  273. package/components/ln-time/ln-time.schema.json +38 -0
  274. package/{js → components}/ln-time/src/ln-time.js +206 -223
  275. package/components/ln-time/src/time-model.js +64 -0
  276. package/{js → components}/ln-toast/README.md +23 -5
  277. package/components/ln-toast/ln-toast-dev.scss +8 -0
  278. package/components/ln-toast/ln-toast.js +1 -0
  279. package/components/ln-toast/ln-toast.schema.json +65 -0
  280. package/components/ln-toast/ln-toast.scss +59 -0
  281. package/{js → components}/ln-toast/src/ln-toast.js +233 -232
  282. package/{js → components}/ln-toggle/README.md +198 -196
  283. package/{js → components}/ln-toggle/ln-toggle-dev.scss +13 -13
  284. package/components/ln-toggle/ln-toggle.js +1 -0
  285. package/components/ln-toggle/ln-toggle.schema.json +52 -0
  286. package/components/ln-toggle/ln-toggle.scss +37 -0
  287. package/{js → components}/ln-toggle/src/ln-toggle.js +61 -46
  288. package/{js → components}/ln-tooltip/README.md +6 -6
  289. package/{js → components}/ln-tooltip/ln-tooltip-dev.scss +9 -9
  290. package/components/ln-tooltip/ln-tooltip.js +1 -0
  291. package/components/ln-tooltip/ln-tooltip.schema.json +86 -0
  292. package/components/ln-tooltip/ln-tooltip.scss +9 -0
  293. package/{js → components}/ln-tooltip/src/ln-tooltip.js +14 -3
  294. package/{js → components}/ln-translations/README.md +3 -1
  295. package/components/ln-translations/ln-translations-dev.scss +13 -0
  296. package/components/ln-translations/ln-translations.js +1 -0
  297. package/components/ln-translations/ln-translations.schema.json +120 -0
  298. package/{js → components}/ln-translations/src/ln-translations.js +25 -10
  299. package/components/ln-ui-coordinator/README.md +101 -0
  300. package/components/ln-ui-coordinator/ln-ui-coordinator-dev.scss +8 -0
  301. package/components/ln-ui-coordinator/ln-ui-coordinator.js +1 -0
  302. package/components/ln-ui-coordinator/ln-ui-coordinator.schema.json +60 -0
  303. package/{js/ln-modal-coordinator/src/ln-modal-coordinator.js → components/ln-ui-coordinator/src/ln-ui-coordinator.js} +403 -345
  304. package/components/ln-upload/README.md +133 -0
  305. package/components/ln-upload/ln-upload-dev.scss +18 -0
  306. package/components/ln-upload/ln-upload.js +1 -0
  307. package/components/ln-upload/ln-upload.schema.json +193 -0
  308. package/components/ln-upload/ln-upload.scss +20 -0
  309. package/components/ln-upload/src/ln-upload.js +652 -0
  310. package/components/ln-upload/src/upload-model.js +78 -0
  311. package/{js → components}/ln-validate/README.md +182 -180
  312. package/{js → components}/ln-validate/ln-validate-dev.scss +15 -15
  313. package/components/ln-validate/ln-validate.js +1 -0
  314. package/components/ln-validate/ln-validate.schema.json +50 -0
  315. package/components/ln-validate/ln-validate.scss +7 -0
  316. package/{js → components}/ln-validate/src/ln-validate.js +23 -45
  317. package/components/ln-validate/src/validate-model.js +64 -0
  318. package/components/ln-websocket-connector/README.md +166 -0
  319. package/components/ln-websocket-connector/ln-websocket-connector.js +1 -0
  320. package/components/ln-websocket-connector/ln-websocket-connector.schema.json +29 -0
  321. package/components/ln-websocket-connector/src/ln-websocket-connector.js +279 -0
  322. package/ln-ashlar.html-data.json +1796 -0
  323. package/package.json +84 -61
  324. package/{scss → theme}/base/_global.scss +1 -2
  325. package/{scss → theme}/base/_reset.scss +1 -1
  326. package/{scss → theme}/base/_typography.scss +2 -0
  327. package/theme/brand.css +73 -0
  328. package/{scss → theme}/components/_app-shell.scss +8 -0
  329. package/theme/components/_button.scss +24 -0
  330. package/theme/components/_chart.scss +5 -0
  331. package/theme/components/_confirm.scss +6 -0
  332. package/{scss → theme}/components/_date.scss +30 -22
  333. package/{scss → theme}/components/_dropdown.scss +6 -1
  334. package/theme/components/_form.scss +140 -0
  335. package/{scss → theme}/components/_layout.scss +6 -0
  336. package/{scss → theme}/components/_ln-table.scss +1 -6
  337. package/theme/components/_picklist.scss +3 -0
  338. package/{scss → theme}/components/_sort.scss +10 -10
  339. package/theme/components/_status-badge.scss +6 -0
  340. package/{scss → theme}/components/_table.scss +16 -0
  341. package/{scss → theme}/components/_tabs.scss +0 -4
  342. package/theme/components/_toast.scss +48 -0
  343. package/{scss → theme}/components/_toggle.scss +1 -1
  344. package/theme/components/_upload.scss +45 -0
  345. package/{scss → theme}/config/_breakpoints.scss +1 -1
  346. package/theme/config/_contrast.scss +128 -0
  347. package/{scss → theme}/config/_density.scss +191 -205
  348. package/theme/config/_palette.scss +274 -0
  349. package/theme/config/_theme.scss +293 -0
  350. package/{scss → theme}/config/_tokens.scss +285 -441
  351. package/{scss → theme}/config/mixins/_accordion.scss +1 -1
  352. package/{scss → theme}/config/mixins/_alert.scss +1 -0
  353. package/{scss → theme}/config/mixins/_app-shell.scss +4 -2
  354. package/{scss → theme}/config/mixins/_borders.scss +2 -0
  355. package/theme/config/mixins/_btn.scss +175 -0
  356. package/{scss → theme}/config/mixins/_card.scss +55 -46
  357. package/theme/config/mixins/_chart.scss +82 -0
  358. package/{scss → theme}/config/mixins/_collapsible.scss +2 -1
  359. package/{scss → theme}/config/mixins/_colors.scss +8 -14
  360. package/{scss → theme}/config/mixins/_diagnostics.scss +48 -48
  361. package/theme/config/mixins/_dropdown.scss +169 -0
  362. package/{scss → theme}/config/mixins/_editor.scss +0 -7
  363. package/{scss → theme}/config/mixins/_filter.scss +47 -47
  364. package/{scss → theme}/config/mixins/_footer.scss +1 -1
  365. package/{scss → theme}/config/mixins/_form.scss +49 -18
  366. package/{scss → theme}/config/mixins/_index.scss +62 -61
  367. package/{scss → theme}/config/mixins/_layout.scss +6 -2
  368. package/{scss → theme}/config/mixins/_ln-table.scss +31 -10
  369. package/{scss → theme}/config/mixins/_loader.scss +1 -1
  370. package/{scss → theme}/config/mixins/_modal.scss +145 -149
  371. package/{scss → theme}/config/mixins/_motion.scss +13 -0
  372. package/{scss → theme}/config/mixins/_nav.scss +7 -7
  373. package/theme/config/mixins/_picklist.scss +66 -0
  374. package/theme/config/mixins/_popover.scss +96 -0
  375. package/{scss → theme}/config/mixins/_sidebar.scss +7 -4
  376. package/{scss → theme}/config/mixins/_sort.scss +43 -42
  377. package/{scss → theme}/config/mixins/_status-badge.scss +15 -2
  378. package/{scss → theme}/config/mixins/_table.scss +25 -14
  379. package/{scss → theme}/config/mixins/_tabs.scss +1 -1
  380. package/{scss → theme}/config/mixins/_toast.scss +174 -179
  381. package/{scss → theme}/config/mixins/_tooltip.scss +2 -2
  382. package/{scss → theme}/config/mixins/_typography.scss +16 -5
  383. package/{scss → theme}/config/mixins/_upload.scss +8 -6
  384. package/theme/ln-ashlar-core.scss +24 -0
  385. package/theme/ln-ashlar-dev.scss +66 -0
  386. package/theme/ln-ashlar-landing.scss +56 -0
  387. package/{scss/ln-ashlar.scss → theme/ln-ashlar-theme.scss} +63 -69
  388. package/theme/ln-ashlar.scss +8 -0
  389. package/theme/presentation/_bento.scss +151 -0
  390. package/theme/presentation/_cta.scss +111 -0
  391. package/theme/presentation/_effects.scss +216 -0
  392. package/theme/presentation/_features.scss +108 -0
  393. package/theme/presentation/_footer.scss +129 -0
  394. package/theme/presentation/_hero.scss +158 -0
  395. package/theme/presentation/_layout.scss +170 -0
  396. package/theme/presentation/_navbar.scss +140 -0
  397. package/theme/presentation/_pricing.scss +262 -0
  398. package/theme/presentation/_stats.scss +87 -0
  399. package/theme/presentation/_testimonials.scss +124 -0
  400. package/theme/presentation/_tokens.scss +39 -0
  401. package/theme/presentation/_typography.scss +163 -0
  402. package/{scss → theme}/utilities/_animations.scss +38 -0
  403. package/{scss → theme}/utilities/_utilities.scss +6 -0
  404. package/web-types.json +2312 -0
  405. package/js/ln-accordion/ln-accordion.js +0 -1
  406. package/js/ln-ajax/ln-ajax.js +0 -1
  407. package/js/ln-api-connector/ln-api-connector.js +0 -1
  408. package/js/ln-api-connector/src/ln-api-connector.js +0 -368
  409. package/js/ln-api-queue/ln-api-queue.js +0 -1
  410. package/js/ln-autoresize/ln-autoresize.js +0 -1
  411. package/js/ln-autosave/ln-autosave.js +0 -1
  412. package/js/ln-circular-progress/ln-circular-progress.js +0 -1
  413. package/js/ln-confirm/_ln-confirm.scss +0 -24
  414. package/js/ln-confirm/ln-confirm.js +0 -1
  415. package/js/ln-core/crypto.js +0 -83
  416. package/js/ln-core/helpers.js +0 -788
  417. package/js/ln-core/index.js +0 -7
  418. package/js/ln-core/persist.js +0 -97
  419. package/js/ln-couchdb-connector/ln-couchdb-connector.js +0 -1
  420. package/js/ln-data-coordinator/ln-data-coordinator.js +0 -1
  421. package/js/ln-data-coordinator/src/data-read-policy.js +0 -18
  422. package/js/ln-data-store/ln-data-store.js +0 -1
  423. package/js/ln-date/ln-date.js +0 -1
  424. package/js/ln-date/src/ln-date.js +0 -603
  425. package/js/ln-debug/README.md +0 -58
  426. package/js/ln-debug/ln-debug.js +0 -1
  427. package/js/ln-debug/src/ln-debug.js +0 -19
  428. package/js/ln-dropdown/ln-dropdown.js +0 -1
  429. package/js/ln-dropdown/ln-dropdown.scss +0 -15
  430. package/js/ln-editor/ln-editor.js +0 -1
  431. package/js/ln-editor/ln-editor.scss +0 -43
  432. package/js/ln-external-links/ln-external-links.js +0 -1
  433. package/js/ln-fill/ln-fill.js +0 -1
  434. package/js/ln-filter/README.md +0 -189
  435. package/js/ln-filter/ln-filter-dev.scss +0 -8
  436. package/js/ln-filter/ln-filter.js +0 -1
  437. package/js/ln-filter/src/ln-filter.js +0 -419
  438. package/js/ln-form/ln-form.js +0 -1
  439. package/js/ln-http/ln-http.js +0 -1
  440. package/js/ln-link/ln-link.js +0 -1
  441. package/js/ln-list/README.md +0 -129
  442. package/js/ln-list/ln-list.js +0 -1
  443. package/js/ln-list/ln-list.scss +0 -28
  444. package/js/ln-modal/ln-modal-dev.scss +0 -13
  445. package/js/ln-modal/ln-modal.js +0 -1
  446. package/js/ln-modal/ln-modal.scss +0 -35
  447. package/js/ln-modal-coordinator/README.md +0 -99
  448. package/js/ln-modal-coordinator/ln-modal-coordinator-dev.scss +0 -8
  449. package/js/ln-modal-coordinator/ln-modal-coordinator.js +0 -1
  450. package/js/ln-nav/ln-nav.js +0 -1
  451. package/js/ln-number/README.md +0 -149
  452. package/js/ln-number/ln-number.js +0 -1
  453. package/js/ln-number/src/ln-number.js +0 -443
  454. package/js/ln-options/ln-options.js +0 -1
  455. package/js/ln-popover/ln-popover.js +0 -1
  456. package/js/ln-progress/ln-progress.js +0 -1
  457. package/js/ln-progress/src/ln-progress.js +0 -98
  458. package/js/ln-router/ln-router.js +0 -1
  459. package/js/ln-search/README.md +0 -158
  460. package/js/ln-search/ln-search-dev.scss +0 -8
  461. package/js/ln-search/ln-search.js +0 -1
  462. package/js/ln-search/src/ln-search.js +0 -117
  463. package/js/ln-slug/ln-slug.js +0 -1
  464. package/js/ln-sort/ln-sort.js +0 -1
  465. package/js/ln-sort/src/ln-sort.js +0 -178
  466. package/js/ln-sortable/ln-sortable.js +0 -1
  467. package/js/ln-stat/ln-stat.js +0 -1
  468. package/js/ln-table/ln-table.js +0 -1
  469. package/js/ln-table/ln-table.scss +0 -11
  470. package/js/ln-table-coordinator/README.md +0 -73
  471. package/js/ln-table-coordinator/ln-table-coordinator.js +0 -1
  472. package/js/ln-table-coordinator/src/ln-table-coordinator.js +0 -160
  473. package/js/ln-tabs/ln-tabs-dev.scss +0 -18
  474. package/js/ln-tabs/ln-tabs.js +0 -1
  475. package/js/ln-tabs/src/ln-tabs.js +0 -188
  476. package/js/ln-time/ln-time.js +0 -1
  477. package/js/ln-toast/ln-toast.js +0 -1
  478. package/js/ln-toggle/ln-toggle.js +0 -1
  479. package/js/ln-tooltip/ln-tooltip.js +0 -1
  480. package/js/ln-tooltip/ln-tooltip.scss +0 -9
  481. package/js/ln-translations/ln-translations.js +0 -1
  482. package/js/ln-upload/README.md +0 -255
  483. package/js/ln-upload/ln-upload.js +0 -1
  484. package/js/ln-upload/ln-upload.scss +0 -20
  485. package/js/ln-upload/src/ln-upload.js +0 -423
  486. package/js/ln-validate/ln-validate.js +0 -1
  487. package/scss/components/_button.scss +0 -20
  488. package/scss/components/_confirm.scss +0 -5
  489. package/scss/components/_form.scss +0 -107
  490. package/scss/components/_status-badge.scss +0 -4
  491. package/scss/components/_toast.scss +0 -68
  492. package/scss/components/_upload.scss +0 -51
  493. package/scss/config/_theme.scss +0 -216
  494. package/scss/config/mixins/_btn.scss +0 -179
  495. package/scss/config/mixins/_confirm.scss +0 -31
  496. package/scss/config/mixins/_dropdown.scss +0 -141
  497. package/scss/config/mixins/_popover.scss +0 -64
  498. package/scss/ln-ashlar-dev.scss +0 -39
  499. /package/{js → components}/ln-core/positioning.js +0 -0
  500. /package/{js → components}/ln-core/reactive.js +0 -0
  501. /package/{js → components}/ln-filter/ln-filter.scss +0 -0
  502. /package/{js → components}/ln-icon/ln-icon.js +0 -0
  503. /package/{js → components}/ln-icon/src/ln-icon.js +0 -0
  504. /package/{js → components}/ln-search/ln-search.scss +0 -0
  505. /package/{js → components}/ln-toast/template.html +0 -0
  506. /package/{scss → theme}/components/_accordion.scss +0 -0
  507. /package/{scss → theme}/components/_ajax.scss +0 -0
  508. /package/{scss → theme}/components/_alert.scss +0 -0
  509. /package/{scss → theme}/components/_avatar.scss +0 -0
  510. /package/{scss → theme}/components/_breadcrumbs.scss +0 -0
  511. /package/{scss → theme}/components/_card.scss +0 -0
  512. /package/{scss → theme}/components/_chip.scss +0 -0
  513. /package/{scss → theme}/components/_circular-progress.scss +0 -0
  514. /package/{scss → theme}/components/_editor.scss +0 -0
  515. /package/{scss → theme}/components/_empty-state.scss +0 -0
  516. /package/{scss → theme}/components/_filter.scss +0 -0
  517. /package/{scss → theme}/components/_link.scss +0 -0
  518. /package/{scss → theme}/components/_loader.scss +0 -0
  519. /package/{scss → theme}/components/_modal.scss +0 -0
  520. /package/{scss → theme}/components/_nav.scss +0 -0
  521. /package/{scss → theme}/components/_page-header.scss +0 -0
  522. /package/{scss → theme}/components/_popover.scss +0 -0
  523. /package/{scss → theme}/components/_progress.scss +0 -0
  524. /package/{scss → theme}/components/_prose.scss +0 -0
  525. /package/{scss → theme}/components/_scrollbar.scss +0 -0
  526. /package/{scss → theme}/components/_sections.scss +0 -0
  527. /package/{scss → theme}/components/_sidebar.scss +0 -0
  528. /package/{scss → theme}/components/_stat-card.scss +0 -0
  529. /package/{scss → theme}/components/_stepper.scss +0 -0
  530. /package/{scss → theme}/components/_timeline.scss +0 -0
  531. /package/{scss → theme}/components/_tooltip.scss +0 -0
  532. /package/{scss → theme}/components/_translations.scss +0 -0
  533. /package/{scss → theme}/config/_icons.scss +0 -0
  534. /package/{scss → theme}/config/_mixins.scss +0 -0
  535. /package/{scss → theme}/config/mixins/_ajax.scss +0 -0
  536. /package/{scss → theme}/config/mixins/_avatar.scss +0 -0
  537. /package/{scss → theme}/config/mixins/_breadcrumbs.scss +0 -0
  538. /package/{scss → theme}/config/mixins/_breakpoints.scss +0 -0
  539. /package/{scss → theme}/config/mixins/_chip.scss +0 -0
  540. /package/{scss → theme}/config/mixins/_circular-progress.scss +0 -0
  541. /package/{scss → theme}/config/mixins/_display.scss +0 -0
  542. /package/{scss → theme}/config/mixins/_empty-state.scss +0 -0
  543. /package/{scss → theme}/config/mixins/_focus.scss +0 -0
  544. /package/{scss → theme}/config/mixins/_interaction.scss +0 -0
  545. /package/{scss → theme}/config/mixins/_kbd.scss +0 -0
  546. /package/{scss → theme}/config/mixins/_link.scss +0 -0
  547. /package/{scss → theme}/config/mixins/_page-header.scss +0 -0
  548. /package/{scss → theme}/config/mixins/_position.scss +0 -0
  549. /package/{scss → theme}/config/mixins/_progress.scss +0 -0
  550. /package/{scss → theme}/config/mixins/_prose.scss +0 -0
  551. /package/{scss → theme}/config/mixins/_shadows.scss +0 -0
  552. /package/{scss → theme}/config/mixins/_sizing.scss +0 -0
  553. /package/{scss → theme}/config/mixins/_spacing.scss +0 -0
  554. /package/{scss → theme}/config/mixins/_stat-card.scss +0 -0
  555. /package/{scss → theme}/config/mixins/_stepper.scss +0 -0
  556. /package/{scss → theme}/config/mixins/_timeline.scss +0 -0
  557. /package/{scss → theme}/config/mixins/_transitions.scss +0 -0
  558. /package/{scss → theme}/config/mixins/_translations.scss +0 -0
  559. /package/{scss → theme}/tabler-icons.txt +0 -0
@@ -1 +0,0 @@
1
- (function(){"use strict";if(typeof window<"u"){const l=console.warn;console.warn=function(...o){typeof o[0]=="string"&&(o[0].startsWith("[ln-")||o[0].startsWith("[lnCore"))&&!(document.documentElement.hasAttribute("data-ln-debug")||document.body&&document.body.hasAttribute("data-ln-debug"))||l.apply(console,o)}}const q={};function N(l,o){q[l]||(q[l]=document.querySelector('[data-ln-template="'+l+'"]'));const a=q[l];return a?a.content.cloneNode(!0):(console.warn("["+(o||"ln-core")+'] Template "'+l+'" not found'),null)}function T(l,o,a){l.dispatchEvent(new CustomEvent(o,{bubbles:!0,detail:a||{}}))}function Z(l,o,a){l._applyFilterAndSort(),l._vStart=-1,l._vEnd=-1,l._render(),l._updateFooter();const g={sort:l.currentSort,filters:l.currentFilters,search:l.currentSearch};g[a]=l.name,T(l.dom,o,g)}function W(l,o){if(!l||!o)return l;const a=l.querySelectorAll("[data-ln-field]");for(let f=0;f<a.length;f++){const h=a[f],p=h.getAttribute("data-ln-field");o[p]!=null&&(h.textContent=o[p])}const g=l.querySelectorAll("[data-ln-attr]");for(let f=0;f<g.length;f++){const h=g[f],p=h.getAttribute("data-ln-attr").split(",");for(let y=0;y<p.length;y++){const S=p[y].trim().split(":");if(S.length!==2)continue;const E=S[0].trim(),D=S[1].trim();o[D]!=null&&h.setAttribute(E,o[D])}}const A=l.querySelectorAll("[data-ln-show]");for(let f=0;f<A.length;f++){const h=A[f],p=h.getAttribute("data-ln-show");p in o&&h.classList.toggle("hidden",!o[p])}const v=l.querySelectorAll("[data-ln-class]");for(let f=0;f<v.length;f++){const h=v[f],p=h.getAttribute("data-ln-class").split(",");for(let y=0;y<p.length;y++){const S=p[y].trim().split(":");if(S.length!==2)continue;const E=S[0].trim(),D=S[1].trim();D in o&&h.classList.toggle(E,!!o[D])}}return l}function $(l,o){l.matches&&l.matches("[data-ln-form], [data-ln-fillable]")&&l.dispatchEvent(new CustomEvent("ln-fill",{detail:o??null,bubbles:!0}));const a=l.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let g=0;g<a.length;g++)a[g].dispatchEvent(new CustomEvent("ln-fill",{detail:o??null,bubbles:!0}));return l}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(l){if(!(!l.target.matches||!l.target.matches("[data-ln-fillable]")))if(l.detail)W(l.target,l.detail);else{const o=l.target.querySelectorAll("[data-ln-field]");for(let a=0;a<o.length;a++)o[a].textContent=""}})));function F(l,o){if(!l||!o)return l;const a=document.createTreeWalker(l,NodeFilter.SHOW_TEXT);for(;a.nextNode();){const v=a.currentNode;v.textContent.indexOf("{{")!==-1&&(v.textContent=v.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(f,h){return o[h]!==void 0?o[h]:""}))}const g=function(v,f){return o[f]!==void 0?o[f]:""},A=Array.from(l.querySelectorAll("*"));l.nodeType===1&&A.push(l);for(let v=0;v<A.length;v++){const f=A[v],h=f.attributes;for(let p=0;p<h.length;p++){const y=h[p];y.value.indexOf("{{")!==-1&&f.setAttribute(y.name,y.value.replace(/\{\{\s*(\w+)\s*\}\}/g,g))}}return l}function tt(l,o,a,g,A,v){const f={};for(let p=0;p<l.children.length;p++){const y=l.children[p],S=y.getAttribute("data-ln-key");S&&(f[S]=y)}const h=document.createDocumentFragment();for(let p=0;p<o.length;p++){const y=o[p],S=String(g(y));let E=f[S];if(E)A(E,y,p);else{const D=N(a,v);if(!D||(F(D,y),E=D.firstElementChild,!E))continue;E.setAttribute("data-ln-key",S),A(E,y,p)}h.appendChild(E)}l.textContent="",l.appendChild(h)}function P(l,o){if(!document.body){document.addEventListener("DOMContentLoaded",function(){P(l,o)}),console.warn("["+o+'] Script loaded before <body> — add "defer" to your <script> tag');return}l()}function z(l,o,a){if(l){const g=l.querySelector('[data-ln-template="'+o+'"]');if(g)return g.content.cloneNode(!0)}return N(o,a)}function O(l,o,a,g){if(l.nodeType!==1)return;const v=o.indexOf("[")!==-1||o.indexOf(".")!==-1||o.indexOf("#")!==-1?o:"["+o+"]",f=Array.from(l.querySelectorAll(v));l.matches&&l.matches(v)&&f.push(l);for(const h of f)h[a]||(h[a]=new g(h))}const V={mk:"mk-MK",de:"de-DE",fr:"fr-FR",es:"es-ES",it:"it-IT",nl:"nl-NL",pt:"pt-PT",ru:"ru-RU",bg:"bg-BG",hr:"hr-HR",sr:"sr-RS",sq:"sq-AL",el:"el-GR",en:"en-US"};function et(l){const o=l?l.closest("[lang]"):null,a=(o?o.getAttribute("lang")||o.lang:null)||(document.documentElement?document.documentElement.getAttribute("lang")||document.documentElement.lang:null)||navigator.language;if(!a)return"en-US";const g=a.trim().toLowerCase();return g.indexOf("-")===-1&&V[g]?V[g]:a}function B(l){return l.hasAttribute("data-ln-value")?l.getAttribute("data-ln-value"):l.textContent.trim()}function U(l){let o=!1;for(let a=0;a<l.length;a++){const g=l[a];if(!(g===""||g==null)&&(o=!0,!Number.isFinite(Number(g))))return"string"}return o?"number":"string"}function j(l,o,a,g){if(a==="number"){const f=parseFloat(l),h=parseFloat(o);return(isNaN(f)?0:f)-(isNaN(h)?0:h)}const A=l!=null?String(l):"",v=o!=null?String(o):"";return g?g.compare(A,v):A<v?-1:A>v?1:0}function nt(l,o,a,g,A={}){const v=A.extraAttributes||[],f=A.onAttributeChange||null,h=A.onInit||null;function p(y){const S=y||document.body;O(S,l,o,a),h&&h(S)}return P(function(){const y=new MutationObserver(function(E){for(let D=0;D<E.length;D++){const _=E[D];if(_.type==="childList"){for(let e=0;e<_.addedNodes.length;e++){const i=_.addedNodes[e];i.nodeType===1&&(O(i,l,o,a),h&&h(i))}for(let e=0;e<_.removedNodes.length;e++){const i=_.removedNodes[e];if(i.nodeType===1){const n=l.indexOf("[")!==-1||l.indexOf(".")!==-1||l.indexOf("#")!==-1?l:"["+l+"]",r=Array.from(i.querySelectorAll(n));i.matches&&i.matches(n)&&r.push(i);for(let c=0;c<r.length;c++){const b=r[c];if(!document.contains(b)){const u=b[o];u&&typeof u.destroy=="function"&&u.destroy()}}}}}else _.type==="attributes"&&(f&&_.target[o]?f(_.target,_.attributeName):(O(_.target,l,o,a),h&&h(_.target)))}});let S=[];if(l.indexOf("[")!==-1){const E=/\[([\w-]+)/g;let D;for(;(D=E.exec(l))!==null;)S.push(D[1])}else S.push(l);y.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:S.concat(v)})},g),window[o]=p,document.readyState==="loading"?document.addEventListener("DOMContentLoaded",function(){p(document.body)}):p(document.body),p}const G={};function lt(l,o){G[l]=o}function it(l){return G[l]||{ingress:o=>o,egress:o=>o}}const K={};function Y(l,o){if(!l||typeof o!="object")return;const a=l.toLowerCase().split("-")[0];K[a]=o}function st(l){if(!l)return null;const o=l.toLowerCase().split("-")[0];return K[o]||null}Y("mk",{monthsLong:["јануари","февруари","март","април","мај","јуни","јули","август","септември","октомври","ноември","декември"],monthsShort:["јан","фев","мар","апр","мај","јун","јул","авг","септ","окт","ноем","дек"],daysLong:["недела","понеделник","вторник","среда","четврток","петок","сабота"],daysShort:["нед","пон","вт","ср","чет","пет","саб"]}),typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=lt,window.lnCore.getDataMapper=it,window.lnCore.registerLocaleFallback=Y,window.lnCore.getLocaleFallback=st,window.lnCore.fillTemplate=F,window.lnCore.fill=W,window.lnCore.lnFill=$,window.lnCore.renderList=tt);function ot(l,o){let a=!1;return function(){a||(a=!0,queueMicrotask(function(){a=!1,l()}))}}function rt(l){l=l||{};let o=l.windowSize>0?l.windowSize:1e3,a=l.pageSize>0?l.pageSize:200,g=l.threshold!=null?l.threshold:25,A=l.fetchDebounce!=null?l.fetchDebounce:120;const v=typeof l.requestPage=="function"?l.requestPage:function(){},f=typeof l.onChange=="function"?l.onChange:function(){},h=new Map,p=new Map,y=new Set;let S=0,E=0,D=0,_={sort:null,filters:{},search:""},e=null,i=0,t=0,n=!1;function r(s){p.set(s,++i)}function c(){return!!(_&&(_.search||_.filters&&Object.keys(_.filters).length))}function b(){if(h.size<=o)return;const s=Array.from(h.keys()).sort(function(w,C){return(p.get(w)||0)-(p.get(C)||0)});let d=0;for(;h.size>o&&d<s.length;)h.delete(s[d]),p.delete(s[d]),d++}function u(s,d){y.add(s),v(_,s,d)}return{get:function(s){return h.get(s)},has:function(s){return h.has(s)},peek:function(){return h.size?h.values().next().value:void 0},get logicalTotal(){return S},get grandTotal(){return E},get queryGen(){return D},get size(){return h.size},ensure:function(s,d){clearTimeout(e),t=s;for(let R=s;R<d;R++)h.has(R)&&r(R);if(S<=0)return;const w=Math.max(0,s-g),C=Math.min(S,d+g),L=Math.floor(w/a),x=Math.floor(Math.max(0,C-1)/a);let m=-1,k=a;for(let R=L;R<=x;R++){const I=R*a,Q=Math.min(a,S-I);let J=!1;for(let M=I;M<I+Q;M++)if(!h.has(M)){J=!0;break}if(J&&!y.has(I)){m=I,k=Q;break}}m!==-1&&(e=setTimeout(function(){u(m,k)},A))},ingest:function(s){if(s=s||{},s.queryGen!=null&&s.queryGen!==D)return;n&&(h.clear(),p.clear(),n=!1),E=s.total!=null?s.total:E,S=s.filtered!=null?s.filtered:s.data?s.data.length:S;const d=s.offset||0,w=s.data||[];for(let C=0;C<w.length;C++)h.set(d+C,w[C]),r(d+C);y.delete(d),b(),f()},requestInitial:function(s){s&&(_=s),u(0,a)},invalidate:function(s){D++,y.clear(),clearTimeout(e),s&&(_=s),n=!0,u(0,a)},revalidate:function(){D++,y.clear(),clearTimeout(e),n=!0;const s=Math.max(0,Math.floor(t/a)*a),d=S>0?Math.min(a,Math.max(1,S-s)):a;u(s,d)},release:function(s){y.delete(s)},destroy:function(){clearTimeout(e),h.clear(),p.clear(),y.clear()},configure:function(s){s=s||{};let d=!1;if(s.windowSize!=null&&s.windowSize>0&&s.windowSize!==o){const w=s.windowSize<o;o=s.windowSize,w&&b(),d=!0}s.pageSize!=null&&s.pageSize>0&&(a=s.pageSize),s.threshold!=null&&s.threshold>=0&&(g=s.threshold),s.fetchDebounce!=null&&s.fetchDebounce>=0&&(A=s.fetchDebounce),d&&f()},setGrandTotal:function(s){s==null||isNaN(s)||s<0||(E=s,c()||(S=s),f())}}}function X(l){return(l||"").replace(/^#/,"")}function H(l){const o=l===void 0?location.hash:l,a={},g=X(o);if(!g)return a;const A=g.split("&");for(let v=0;v<A.length;v++){const f=A[v];if(!f)continue;const h=f.indexOf(":"),p=h>-1?f.slice(0,h):f,y=h>-1?f.slice(h+1):"";if(p)try{a[p]=decodeURIComponent(y)}catch{a[p]=y}}return a}function at(l){if(!l)return null;const o=H();return l in o?o[l]:null}function ct(l,o){if(!l)return;const a=H();o==null?delete a[l]:a[l]=String(o);const A=Object.keys(a).map(function(v){const f=a[v];return f===""?v:v+":"+encodeURIComponent(f)}).join("&");X(location.hash)!==A&&(location.hash=A)}function dt(l){return l.button===1||l.ctrlKey||l.metaKey||l.shiftKey?!1:(l.preventDefault(),!0)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=H,window.lnCore.hashGet=at,window.lnCore.hashSet=ct,window.lnCore.hashLinkClick=dt),(function(){const l="data-ln-table",o="lnTable",a="data-ln-table-empty";if(window[o]!==void 0)return;const p=typeof Intl<"u"?new Intl.Collator(document.documentElement.lang||void 0,{sensitivity:"base"}):null;function y(e,i){if(e==null||isNaN(e))return"";try{return new Intl.NumberFormat(et(i)).format(e)}catch{return String(e)}}function S(e){let i=e.parentElement;for(;i&&i!==document.body&&i!==document.documentElement;){const n=getComputedStyle(i).overflowY;if(n==="auto"||n==="scroll")return i;i=i.parentElement}return null}function E(e){const i=e._scrollContainer||S(e.dom);return{container:i,top:i?i.scrollTop:window.scrollY}}function D(e){e.container?e.container.scrollTop=e.top:window.scrollTo(window.scrollX,e.top)}function _(e){this.dom=e,this.table=e.querySelector("table"),this.tbody=e.querySelector("[data-ln-table-body]")||e.querySelector("tbody"),this.thead=e.querySelector("thead");const i=this.thead?this.thead.querySelector("tr:last-child"):null;this.ths=i?Array.from(i.querySelectorAll("th")):[],this._totalSpan=e.querySelector("[data-ln-table-total]"),this._filteredSpan=e.querySelector("[data-ln-table-filtered]"),this._filteredSpan&&(this._filteredWrap=this._filteredSpan.parentElement!==e?this._filteredSpan.parentElement:null),this._selectedSpan=e.querySelector("[data-ln-table-selected]"),this._selectedSpan&&(this._selectedWrap=this._selectedSpan.parentElement!==e?this._selectedSpan.parentElement:null),this.isDataDriven=e.hasAttribute("data-ln-table-source"),this.name=e.getAttribute(l)||"",this.source=e.getAttribute("data-ln-table-source")||"",this._data=[],this._filteredData=[],this._searchTerm="",this._sortCol=-1,this._sortDir=null,this._columnFilters={},this.selectedIds=new Set,this._virtual=!1,this._rowHeight=0,this._vStart=-1,this._vEnd=-1,this._rafId=null,this._scrollHandler=null,this._scrollContainer=null,this._colgroup=null;const t=this;return this._onSetSearch=function(n){const r=(n.detail&&n.detail.query!=null?n.detail.query:n.detail&&n.detail.term!=null?n.detail.term:"").trim();t.isDataDriven?(t.currentSearch=r,T(e,"ln-table:search",{table:t.name,query:t.currentSearch}),t._requestData()):(t._searchTerm=r.toLowerCase(),t._applyFilterAndSort(),t._vStart=-1,t._vEnd=-1,t._render(),t._updateFooter(),T(e,"ln-table:filter",{term:t._searchTerm,matched:t._filteredData.length,total:t._data.length}))},e.addEventListener("ln-table:set-search",this._onSetSearch),this._onSetFilter=function(n){if(!n.detail)return;const r=n.detail.key,c=n.detail.values;if(t.isDataDriven)!c||c.length===0?delete t.currentFilters[r]:t.currentFilters[r]=c,t._requestData();else{if(!c||c.length===0)delete t._columnFilters[r];else{const b=[];for(let u=0;u<c.length;u++)b.push(c[u].toLowerCase());t._columnFilters[r]=b}t._applyFilterAndSort(),t._vStart=-1,t._vEnd=-1,t._render(),T(e,"ln-table:filter",{term:t._searchTerm,matched:t._filteredData.length,total:t._data.length})}},e.addEventListener("ln-table:set-filter",this._onSetFilter),this._onRequestClearFilters=function(){t.isDataDriven?(t.currentFilters={},t.currentSearch="",T(e,"ln-table:clear-filters",{table:t.name}),t._requestData()):(t._searchTerm="",t._columnFilters={},t._applyFilterAndSort(),t._vStart=-1,t._vEnd=-1,t._render(),t._updateFooter(),T(e,"ln-table:filter",{term:"",matched:t._filteredData.length,total:t._data.length}))},e.addEventListener("ln-table:request-clear-filters",this._onRequestClearFilters),this._selectable=e.hasAttribute("data-ln-table-selectable"),this._selectableActive=!1,this._selectable&&this._enableSelection(),this.isDataDriven?(this.isLoaded=!1,this.totalCount=0,this.visibleCount=0,this.currentSort=null,this.currentFilters={},this.currentSearch="",this._lastTotal=0,this._lastFiltered=0,this._windowed=!1,this._cache=null,this.isDataDriven&&e.hasAttribute("data-ln-table-window")&&this._enterWindowedMode(),this._onSetData=function(n){const r=n.detail||{};if(t._windowed){e.classList.remove("ln-table--loading"),t._cache.ingest(r);return}t._data=r.data||[],t._lastTotal=r.total!=null?r.total:t._data.length,t._lastFiltered=r.filtered!=null?r.filtered:t._data.length,t.totalCount=t._lastTotal,t.visibleCount=t._lastFiltered,t.isLoaded=!0,e.classList.remove("ln-table--loading"),t._vStart=-1,t._vEnd=-1,t._applyFilterAndSort(),t._render(),t._updateFooter(),T(e,"ln-table:rendered",{table:t.name,total:t.totalCount,visible:t.visibleCount})},e.addEventListener("ln-table:set-data",this._onSetData),this._onSetLoading=function(n){const r=n.detail&&n.detail.loading;e.classList.toggle("ln-table--loading",!!r),r&&(t.isLoaded=!1)},e.addEventListener("ln-table:set-loading",this._onSetLoading),this._onPageFailed=function(n){!t._windowed||!t._cache||t._cache.release(n.detail&&n.detail.offset)},e.addEventListener("ln-table:page-failed",this._onPageFailed),this._onRequestRevalidate=function(){!t._windowed||!t._cache||t._cache.revalidate()},e.addEventListener("ln-table:request-revalidate",this._onRequestRevalidate),this._onSort=function(n){n.preventDefault(),t.currentSort=n.detail.direction==="none"?null:{field:n.detail.field,direction:n.detail.direction},t._requestData()},e.addEventListener("ln-sort:change",this._onSort),this._windowed&&this._selectable&&this._selectAllCheckbox&&this._selectAllCheckbox.classList.add("hidden"),this._onRowClick=function(n){if(n.target.closest("[data-ln-table-row-select]")||n.target.closest("[data-ln-table-row-action]")||n.target.closest("a")||n.target.closest("button")||n.ctrlKey||n.metaKey||n.button===1)return;const r=n.target.closest("[data-ln-table-row]");if(!r)return;const c=r.getAttribute("data-ln-table-row-id"),b=r._lnRecord||{};T(e,"ln-table:row-click",{table:t.name,id:c,record:b})},this.tbody&&this.tbody.addEventListener("click",this._onRowClick),this._onRowAction=function(n){const r=n.target.closest("[data-ln-table-row-action]");if(!r)return;n.stopPropagation();const c=r.closest("[data-ln-table-row]");if(!c)return;const b=r.getAttribute("data-ln-table-row-action"),u=c.getAttribute("data-ln-table-row-id"),s=c._lnRecord||{};T(e,"ln-table:row-action",{table:t.name,id:u,action:b,record:s})},this.tbody&&this.tbody.addEventListener("click",this._onRowAction),this._focusedRowIndex=-1,this._onKeydown=function(n){if(!e.contains(document.activeElement)&&document.activeElement!==document.body||document.activeElement&&(document.activeElement.tagName==="INPUT"||document.activeElement.tagName==="TEXTAREA"))return;const r=t.tbody?Array.from(t.tbody.querySelectorAll("[data-ln-table-row]")):[];if(r.length)switch(n.key){case"ArrowDown":n.preventDefault(),t._focusedRowIndex=Math.min(t._focusedRowIndex+1,r.length-1),t._focusRow(r);break;case"ArrowUp":n.preventDefault(),t._focusedRowIndex=Math.max(t._focusedRowIndex-1,0),t._focusRow(r);break;case"Home":n.preventDefault(),t._focusedRowIndex=0,t._focusRow(r);break;case"End":n.preventDefault(),t._focusedRowIndex=r.length-1,t._focusRow(r);break;case"Enter":if(t._focusedRowIndex>=0&&t._focusedRowIndex<r.length){n.preventDefault();const c=r[t._focusedRowIndex];T(e,"ln-table:row-click",{table:t.name,id:c.getAttribute("data-ln-table-row-id"),record:c._lnRecord||{}})}break;case" ":if(t._selectable&&t._focusedRowIndex>=0&&t._focusedRowIndex<r.length){n.preventDefault();const c=r[t._focusedRowIndex].querySelector("[data-ln-table-row-select]");c&&(c.checked=!c.checked,c.dispatchEvent(new Event("change",{bubbles:!0})))}break}},document.addEventListener("keydown",this._onKeydown),this.tbody&&this.tbody.rows.length>0&&this._parseRows(),this._windowed?this._kickWindowInitial():T(e,"ln-table:request-data",{table:this.name,sort:this.currentSort,filters:this.currentFilters,search:this.currentSearch})):(this._emptyTbodyObserver=null,this.tbody&&this.tbody.rows.length>0?this._parseRows():this.tbody&&(this._emptyTbodyObserver=new MutationObserver(function(){t.tbody.rows.length>0&&(t._emptyTbodyObserver.disconnect(),t._emptyTbodyObserver=null,t._parseRows())}),this._emptyTbodyObserver.observe(this.tbody,{childList:!0})),this._onSort=function(n){n.preventDefault();const r=n.detail.direction==="none"?null:n.detail.direction;t._sortCol=r===null?-1:n.detail.column,t._sortDir=r,t._applyFilterAndSort(),t._vStart=-1,t._vEnd=-1,t._render(),T(e,"ln-table:sorted",{column:n.detail.column,direction:n.detail.direction,matched:t._filteredData.length,total:t._data.length})},e.addEventListener("ln-sort:change",this._onSort),this._onSearchChange=function(n){n.preventDefault(),t._onSetSearch(n)},e.addEventListener("ln-search:change",this._onSearchChange)),this}_.prototype._parseRows=function(){const e=this.tbody.rows,i=this.ths;this._data=[],e.length>0&&(this._rowHeight=e[0].offsetHeight||40),this._lockColumnWidths();for(let t=0;t<e.length;t++){const n=e[t],r=[],c=[],b=[];for(let s=0;s<n.cells.length;s++){const d=n.cells[s],w=d.textContent.trim();r[s]=B(d),c[s]=w.toLowerCase(),s<n.cells.length-1&&b.push(w.toLowerCase())}let u=null;if(this.isDataDriven){u={};const s=n.getAttribute("data-ln-table-row-id");s!=null&&(u.id=s);for(let d=0;d<i.length;d++){const w=i[d].getAttribute("data-ln-table-col");if(w){const C=d;if(C<n.cells.length){const L=n.cells[C];u[w]=B(L)}}}}this._data.push({values:r,rawTexts:c,html:n.outerHTML,searchText:b.join(" "),id:this.isDataDriven&&u?u.id:void 0,...u})}this._filteredData=this._data.slice(),this.isDataDriven&&(this._lastTotal=this._data.length,this._lastFiltered=this._data.length,this.totalCount=this._data.length,this.visibleCount=this._data.length,this._updateFooter()),this._render(),T(this.dom,"ln-table:ready",{total:this._data.length})},_.prototype._applyFilterAndSort=function(){if(this.isDataDriven){const e=(this.currentSearch||"").trim().toLowerCase(),i=this.currentFilters||{},t=Object.keys(i).length>0;if(this._filteredData=this._data.filter(function(s){if(e){let d=!1;for(const w in s)if(s.hasOwnProperty(w)&&typeof s[w]=="string"&&w!=="html"&&w!=="searchText"&&s[w].toLowerCase().indexOf(e)!==-1){d=!0;break}if(!d)return!1}if(t)for(const d in i){const w=i[d];if(w&&w.length>0){const C=s[d],L=C!=null?String(C):"";if(w.indexOf(L)===-1)return!1}}return!0}),this.visibleCount=this._filteredData.length,!this.currentSort||!this.currentSort.field||!this.currentSort.direction)return;const n=this.currentSort.field,c=this.currentSort.direction==="desc"?-1:1,b=this._filteredData.map(function(s){return s[n]}),u=U(b);this._filteredData.sort(function(s,d){return j(s[n],d[n],u,p)*c})}else{const e=this._searchTerm,i=this._columnFilters,t=Object.keys(i).length>0,n=this.ths,r={};if(t)for(let d=0;d<n.length;d++){const w=n[d].getAttribute("data-ln-table-filter-col");w&&(r[w]=d)}if(!e&&!t?this._filteredData=this._data.slice():this._filteredData=this._data.filter(function(d){if(e&&d.searchText.indexOf(e)===-1)return!1;if(t)for(const w in i){const C=r[w];if(C!==void 0&&i[w].indexOf(d.rawTexts[C])===-1)return!1}return!0}),this._sortCol<0||!this._sortDir)return;const c=this._sortCol,b=this._sortDir==="desc"?-1:1,u=this._filteredData.map(function(d){return d.values[c]}),s=U(u);this._filteredData.sort(function(d,w){return j(d.values[c],w.values[c],s,p)*b})}},_.prototype._lockColumnWidths=function(){if(!this.table||!this.thead||this._colgroup)return;const e=document.createElement("colgroup");this.ths.forEach(function(i){const t=document.createElement("col");t.style.width=i.offsetWidth+"px",e.appendChild(t)}),this.table.insertBefore(e,this.table.firstChild),this.table.style.tableLayout="fixed",this._colgroup=e},_.prototype._render=function(){if(this.tbody)if(this.isDataDriven){if(this._windowed){this._renderWindowed();return}const e=this._lastTotal,i=this.visibleCount;if(e===0){this._disableVirtualScroll(),this._showEmptyState();return}if(this._filteredData.length===0||i===0){this._disableVirtualScroll(),this._showEmptyState();return}this._filteredData.length>200?(this._enableVirtualScroll(),this._renderVirtual()):(this._disableVirtualScroll(),this._renderAll())}else{const e=this._filteredData.length;e===0&&(this._searchTerm||Object.keys(this._columnFilters).length>0)?(this._disableVirtualScroll(),this._showEmptyState()):e>200?(this._enableVirtualScroll(),this._renderVirtual()):(this._disableVirtualScroll(),this._renderAll())}},_.prototype._renderAll=function(){if(this.isDataDriven){const e=this._filteredData,i=document.createDocumentFragment();for(let n=0;n<e.length;n++){const r=this._buildRow(e[n]);if(!r)break;i.appendChild(r)}const t=E(this);this.tbody.textContent="",this.tbody.appendChild(i),D(t),this._selectable&&this._updateSelectAll()}else{const e=[],i=this._filteredData;for(let n=0;n<i.length;n++)e.push(i[n].html);const t=E(this);this.tbody.innerHTML=e.join(""),D(t),this._selectable&&this._restoreSelection()}},_.prototype._enableVirtualScroll=function(){if(this._virtual)return;this._virtual=!0,this._vStart=-1,this._vEnd=-1;const e=this;if(!this._rowHeight)if(this._windowed){let t=null;const n=this._cache.peek();n?t=this._buildRow(n):t=this._buildPlaceholderRow(),t&&(this.tbody.textContent="",this.tbody.appendChild(t),this._rowHeight=t.offsetHeight||40,this.tbody.textContent="")}else if(this.isDataDriven){if(this._data.length>0){const t=this._buildRow(this._data[0]);t&&(this.tbody.textContent="",this.tbody.appendChild(t),this._rowHeight=t.offsetHeight||40,this.tbody.textContent="")}}else{const t=this.tbody?this.tbody.rows:[];t.length>0&&(this._rowHeight=t[0].offsetHeight||40)}this.isDataDriven?this._scrollContainer=S(this.dom):this._scrollContainer=null;const i=this._scrollContainer||window;this._scrollHandler=function(){e._rafId||(e._rafId=requestAnimationFrame(function(){e._rafId=null,e._windowed?e._renderWindowed():e._renderVirtual()}))},i.addEventListener("scroll",this._scrollHandler,{passive:!0}),window.addEventListener("resize",this._scrollHandler,{passive:!0})},_.prototype._disableVirtualScroll=function(){this._virtual&&(this._virtual=!1,this._scrollHandler&&((this._scrollContainer||window).removeEventListener("scroll",this._scrollHandler),window.removeEventListener("resize",this._scrollHandler),this._scrollHandler=null),this._scrollContainer=null,this._rafId&&(cancelAnimationFrame(this._rafId),this._rafId=null),this._vStart=-1,this._vEnd=-1)},_.prototype._renderVirtual=function(){const e=this._filteredData,i=e.length,t=this._rowHeight;if(!t||!i)return;const n=this.thead?this.thead.offsetHeight:0,r=this._scrollContainer;let c,b;if(r){const L=this.table.getBoundingClientRect(),x=r.getBoundingClientRect(),m=L.top-x.top+r.scrollTop+n;c=r.scrollTop-m,b=r.clientHeight}else{const m=this.table.getBoundingClientRect().top+window.scrollY+n;c=window.scrollY-m,b=window.innerHeight}let u=Math.max(0,Math.floor(c/t)-15);u=Math.min(u,i);const s=Math.min(u+Math.ceil(b/t)+30,i);if(u===this._vStart&&s===this._vEnd)return;this._vStart=u,this._vEnd=s;const d=this.ths.length||1,w=u*t,C=(i-s)*t;if(this.isDataDriven){const L=document.createDocumentFragment();if(w>0){const m=document.createElement("tr");m.className="ln-table__spacer",m.setAttribute("aria-hidden","true");const k=document.createElement("td");k.setAttribute("colspan",d),k.style.height=w+"px",m.appendChild(k),L.appendChild(m)}for(let m=u;m<s;m++){const k=this._buildRow(e[m]);k&&L.appendChild(k)}if(C>0){const m=document.createElement("tr");m.className="ln-table__spacer",m.setAttribute("aria-hidden","true");const k=document.createElement("td");k.setAttribute("colspan",d),k.style.height=C+"px",m.appendChild(k),L.appendChild(m)}const x=E(this);this.tbody.textContent="",this.tbody.appendChild(L),D(x),this._selectable&&this._updateSelectAll()}else{let L="";w>0&&(L+='<tr class="ln-table__spacer" aria-hidden="true"><td colspan="'+d+'" style="height:'+w+'px;padding:0;border:none"></td></tr>');for(let m=u;m<s;m++)L+=e[m].html;C>0&&(L+='<tr class="ln-table__spacer" aria-hidden="true"><td colspan="'+d+'" style="height:'+C+'px;padding:0;border:none"></td></tr>');const x=E(this);this.tbody.innerHTML=L,D(x),this._selectable&&this._restoreSelection()}},_.prototype._buildPlaceholderRow=function(){const e=document.createElement("tr");e.className="ln-table__placeholder",e.setAttribute("aria-hidden","true");const i=document.createElement("td");return i.setAttribute("colspan",this.ths.length||1),i.style.height=this._rowHeight+"px",e.appendChild(i),e},_.prototype._renderWindowed=function(){if(this.isLoaded&&this._cache.logicalTotal===0){this._disableVirtualScroll(),this._showEmptyState();return}this._virtual||this._enableVirtualScroll();const e=this._rowHeight;if(!e)return;const i=this._cache.logicalTotal,t=this.thead?this.thead.offsetHeight:0,n=this._scrollContainer;let r,c;if(n){const x=this.table.getBoundingClientRect(),m=n.getBoundingClientRect(),k=x.top-m.top+n.scrollTop+t;r=n.scrollTop-k,c=n.clientHeight}else{const k=this.table.getBoundingClientRect().top+window.scrollY+t;r=window.scrollY-k,c=window.innerHeight}let b=Math.max(0,Math.floor(r/e)-15);b=Math.min(b,i);const u=Math.min(b+Math.ceil(c/e)+30,i),s=this.ths.length||1,d=b*e,w=(i-u)*e,C=document.createDocumentFragment();if(d>0){const x=document.createElement("tr");x.className="ln-table__spacer",x.setAttribute("aria-hidden","true");const m=document.createElement("td");m.setAttribute("colspan",s),m.style.height=d+"px",x.appendChild(m),C.appendChild(x)}for(let x=b;x<u;x++)if(this._cache.has(x)){const m=this._buildRow(this._cache.get(x));m&&C.appendChild(m)}else C.appendChild(this._buildPlaceholderRow());if(w>0){const x=document.createElement("tr");x.className="ln-table__spacer",x.setAttribute("aria-hidden","true");const m=document.createElement("td");m.setAttribute("colspan",s),m.style.height=w+"px",x.appendChild(m),C.appendChild(x)}const L=E(this);this.tbody.textContent="",this.tbody.appendChild(C),D(L),this._vStart=b,this._vEnd=u,this._cache.ensure(b,u)},_.prototype._showEmptyState=function(){const e=this.ths.length||1;this.tbody.textContent="";let i=null;if(this.isDataDriven){const t=this._lastTotal!=null?this._lastTotal:this._data.length,n=this.visibleCount,r=(this.currentSearch||Object.keys(this.currentFilters).length>0)&&(n<t||n===0),c=r?this.name+"-empty-filtered":this.name+"-empty";if(i=z(this.dom,c,"ln-table"),!i){const b=this.dom.querySelector("template[data-ln-table-empty]");if(b){const u=r?"search":"initial",s=b.content.querySelector('[data-ln-table-empty-when="'+u+'"]')||b.content.firstElementChild;s&&(i=document.importNode(s,!0))}}if(i)if(i.tagName==="TR")this.tbody.appendChild(i);else{const b=document.createElement("td");b.setAttribute("colspan",String(e)),b.appendChild(i);const u=document.createElement("tr");u.className="ln-table__empty",u.appendChild(b),this.tbody.appendChild(u)}}else{const t=this.dom.querySelector("template["+a+"]"),n=document.createElement("td");n.setAttribute("colspan",String(e)),t&&n.appendChild(document.importNode(t.content,!0));const r=document.createElement("tr");r.className="ln-table__empty",r.appendChild(n),this.tbody.appendChild(r)}T(this.dom,"ln-table:empty",{term:this.isDataDriven?this.currentSearch||"":this._searchTerm,total:this.isDataDriven?this._lastTotal!=null?this._lastTotal:this._data.length:this._data.length})},_.prototype._fillRow=function(e,i){F(e,i);const t=e.querySelectorAll("[data-ln-table-cell-attr]");for(let n=0;n<t.length;n++){const r=t[n],c=r.getAttribute("data-ln-table-cell-attr").split(",");for(let b=0;b<c.length;b++){const u=c[b].trim().split(":");if(u.length!==2)continue;const s=u[0].trim(),d=u[1].trim();i[s]!=null&&r.setAttribute(d,i[s])}}},_.prototype._buildRow=function(e){const i=z(this.dom,this.name+"-row","ln-table");if(!i)return null;const t=i.querySelector("[data-ln-table-row]")||i.firstElementChild;if(!t)return null;if(this._fillRow(t,e),t._lnRecord=e,e.id!=null&&t.setAttribute("data-ln-table-row-id",e.id),this._selectable&&e.id!=null&&this.selectedIds.has(String(e.id))){t.classList.add("ln-row-selected");const n=t.querySelector("[data-ln-table-row-select]");n&&(n.checked=!0)}return t},_.prototype._requestData=function(){if(this._windowed){this.dom.classList.add("ln-table--loading"),this._cache.invalidate({sort:this.currentSort,filters:this.currentFilters,search:this.currentSearch});return}Z(this,"ln-table:request-data","table")},_.prototype._enterWindowedMode=function(){const e=this,i=this.dom,t=parseInt(i.getAttribute("data-ln-table-window"),10),n=parseInt(i.getAttribute("data-ln-table-window-page"),10),r=parseInt(i.getAttribute("data-ln-table-window-threshold"),10);this._onCacheChange=function(){!e._windowed||!e._cache||(e.totalCount=e._cache.grandTotal,e.visibleCount=e._cache.logicalTotal,e._lastTotal=e._cache.grandTotal,e.isLoaded=!0,e._vStart=-1,e._vEnd=-1,e._render(),e._updateFooter(),T(i,"ln-table:rendered",{table:e.name,total:e.totalCount,visible:e.visibleCount}))},this._renderBatch=ot(this._onCacheChange),this._cache=rt({windowSize:t>0?t:1e3,pageSize:n>0?n:200,threshold:r>=0?r:25,fetchDebounce:120,requestPage:function(c,b,u){T(i,"ln-table:request-data",{table:e.name,sort:c.sort,filters:c.filters,search:c.search,offset:b,limit:u,queryGen:e._cache.queryGen})},onChange:this._renderBatch}),this._windowed=!0,this._selectable&&this._selectAllCheckbox&&this._selectAllCheckbox.classList.add("hidden")},_.prototype._kickWindowInitial=function(){if(this._data.length>0){let e=parseInt(this.dom.getAttribute("data-ln-table-count"),10);if(isNaN(e)&&this._totalSpan){const t=this._totalSpan.textContent.replace(/[^\d]/g,"");t&&(e=parseInt(t,10))}const i=e>0?e:this._data.length;this._cache.ingest({data:this._data,offset:0,total:i,filtered:i})}else this.dom.classList.add("ln-table--loading"),this._cache.requestInitial({sort:this.currentSort,filters:this.currentFilters,search:this.currentSearch})},_.prototype._exitWindowedMode=function(){this._disableVirtualScroll(),this._cache&&this._cache.destroy(),this._cache=null,this._windowed=!1,this._renderBatch=null,this._onCacheChange=null,this._selectAllCheckbox&&this._selectAllCheckbox.classList.remove("hidden"),this._rowHeight=0,this._vStart=-1,this._vEnd=-1,this._data=[],this._filteredData=[],this.dom.classList.add("ln-table--loading"),this._requestData()},_.prototype._updateSelectAll=function(){if(!this._selectAllCheckbox||!this.tbody)return;const e=this.tbody.querySelectorAll("[data-ln-table-row]");let i=e.length>0;for(let t=0;t<e.length;t++){const n=e[t].getAttribute("data-ln-table-row-id");if(n!=null&&!this.selectedIds.has(n)){i=!1;break}}this._selectAllCheckbox.checked=i},_.prototype._restoreSelection=function(){if(!this.tbody)return;const e=this.tbody.querySelectorAll("[data-ln-table-row]");for(let i=0;i<e.length;i++){const t=e[i].getAttribute("data-ln-table-row-id"),n=t!=null&&this.selectedIds.has(t);e[i].classList.toggle("ln-row-selected",n);const r=e[i].querySelector("[data-ln-table-row-select]");r&&(r.checked=n)}this._updateSelectAll()},Object.defineProperty(_.prototype,"selectedCount",{get:function(){return this.selectedIds.size},set:function(){}}),_.prototype._enableSelection=function(){if(this._selectableActive)return;this._selectableActive=!0;const e=this;if(this._onSelectionChange=function(i){const t=i.target.closest("[data-ln-table-row-select]");if(!t)return;const n=t.closest("[data-ln-table-row]");if(!n)return;const r=n.getAttribute("data-ln-table-row-id");r!=null&&(t.checked?(e.selectedIds.add(r),n.classList.add("ln-row-selected")):(e.selectedIds.delete(r),n.classList.remove("ln-row-selected")),e.selectedCount=e.selectedIds.size,e._updateSelectAll(),e._updateFooter(),T(e.dom,"ln-table:select",{table:e.name,selectedIds:e.selectedIds,count:e.selectedCount}))},this.tbody&&this.tbody.addEventListener("change",this._onSelectionChange),this._selectAllCheckbox=this.dom.querySelector('[data-ln-table-col-select] input[type="checkbox"]')||this.dom.querySelector("[data-ln-table-col-select]"),this._selectAllCheckbox&&this._selectAllCheckbox.tagName==="TH"){const i=document.createElement("input");i.type="checkbox";const t=e.dom.querySelector('[data-ln-table-dict="select-all"]'),n=e.dom.getAttribute("data-ln-table-select-all-label")||(t?t.textContent.trim():null)||"Select all";i.setAttribute("aria-label",n),this._selectAllCheckbox.appendChild(i),this._selectAllCheckbox=i}if(this._selectAllCheckbox&&(this._onSelectAll=function(){const i=e._selectAllCheckbox.checked,t=e.tbody?e.tbody.querySelectorAll("[data-ln-table-row]"):[];for(let n=0;n<t.length;n++){const r=t[n].getAttribute("data-ln-table-row-id"),c=t[n].querySelector("[data-ln-table-row-select]");r!=null&&(i?(e.selectedIds.add(r),t[n].classList.add("ln-row-selected")):(e.selectedIds.delete(r),t[n].classList.remove("ln-row-selected")),c&&(c.checked=i))}e.selectedCount=e.selectedIds.size,T(e.dom,"ln-table:select-all",{table:e.name,selected:i}),T(e.dom,"ln-table:select",{table:e.name,selectedIds:e.selectedIds,count:e.selectedCount}),e._updateFooter()},this._selectAllCheckbox.addEventListener("change",this._onSelectAll)),this.tbody){const i=this.tbody.querySelectorAll("[data-ln-table-row]");for(let t=0;t<i.length;t++){const n=i[t].querySelector("[data-ln-table-row-select]"),r=i[t].getAttribute("data-ln-table-row-id");n&&n.checked&&r!=null&&(this.selectedIds.add(r),i[t].classList.add("ln-row-selected"))}this.selectedCount=this.selectedIds.size,this.selectedCount>0&&this._updateSelectAll()}},_.prototype._disableSelection=function(){if(!this._selectableActive)return;this._selectableActive=!1,this.tbody&&this._onSelectionChange&&this.tbody.removeEventListener("change",this._onSelectionChange),this._selectAllCheckbox&&this._onSelectAll&&this._selectAllCheckbox.removeEventListener("change",this._onSelectAll);const e=this.dom.querySelector("[data-ln-table-col-select]");if(e){const i=e.querySelector('input[type="checkbox"]');i&&i.remove()}if(this._selectAllCheckbox=null,this.selectedIds.clear(),this.selectedCount=0,this.tbody){const i=this.tbody.querySelectorAll("[data-ln-table-row]");for(let t=0;t<i.length;t++){i[t].classList.remove("ln-row-selected");const n=i[t].querySelector("[data-ln-table-row-select]");n&&(n.checked=!1)}}this._updateFooter()},_.prototype._updateFooter=function(){let e=0,i=0;this.isDataDriven?(e=this._lastTotal!=null?this._lastTotal:this._data.length,i=this.visibleCount):(e=this._data.length,i=this._filteredData.length);const t=i<e;if(this._totalSpan&&(this._totalSpan.textContent=y(e,this.dom)),this._filteredSpan&&(this._filteredSpan.textContent=t?y(i,this.dom):""),this._filteredWrap&&this._filteredWrap.classList.toggle("hidden",!t),this._selectedSpan){const n=this.selectedIds?this.selectedIds.size:0;this._selectedSpan.textContent=n>0?y(n,this.dom):"",this._selectedWrap&&this._selectedWrap.classList.toggle("hidden",n===0)}},_.prototype._focusRow=function(e){for(let i=0;i<e.length;i++)e[i].classList.remove("ln-row-focused"),e[i].removeAttribute("tabindex");if(this._focusedRowIndex>=0&&this._focusedRowIndex<e.length){const i=e[this._focusedRowIndex];i.classList.add("ln-row-focused"),i.setAttribute("tabindex","0"),i.focus(),i.scrollIntoView({block:"nearest"})}},_.prototype.destroy=function(){this.dom[o]&&(this._disableVirtualScroll(),this.dom.removeEventListener("ln-table:set-search",this._onSetSearch),this.dom.removeEventListener("ln-table:set-filter",this._onSetFilter),this.dom.removeEventListener("ln-table:request-clear-filters",this._onRequestClearFilters),this.isDataDriven?(this.dom.removeEventListener("ln-table:set-data",this._onSetData),this.dom.removeEventListener("ln-table:set-loading",this._onSetLoading),this.dom.removeEventListener("ln-table:page-failed",this._onPageFailed),this.dom.removeEventListener("ln-table:request-revalidate",this._onRequestRevalidate),this.dom.removeEventListener("ln-sort:change",this._onSort),document.removeEventListener("keydown",this._onKeydown),this.tbody&&(this.tbody.removeEventListener("click",this._onRowClick),this.tbody.removeEventListener("click",this._onRowAction)),this._cache&&this._cache.destroy()):(this._emptyTbodyObserver&&(this._emptyTbodyObserver.disconnect(),this._emptyTbodyObserver=null),this.dom.removeEventListener("ln-sort:change",this._onSort),this.dom.removeEventListener("ln-search:change",this._onSearchChange)),this._onSelectionChange&&this.tbody&&this.tbody.removeEventListener("change",this._onSelectionChange),this._selectAllCheckbox&&this._onSelectAll&&this._selectAllCheckbox.removeEventListener("change",this._onSelectAll),this._colgroup&&(this._colgroup.remove(),this._colgroup=null),this.table&&(this.table.style.tableLayout=""),this._data=[],this._filteredData=[],delete this.dom[o])},nt(l,o,_,"ln-table",{extraAttributes:["data-ln-table-window","data-ln-table-window-page","data-ln-table-window-threshold","data-ln-table-count"],onAttributeChange:function(e,i){const t=e[o];if(!(!t||!t.isDataDriven)){if(i==="data-ln-table-window"){const n=e.hasAttribute("data-ln-table-window");if(n&&!t._windowed)t._enterWindowedMode(),t._kickWindowInitial();else if(!n&&t._windowed)t._exitWindowedMode();else if(n&&t._windowed){const r=parseInt(e.getAttribute("data-ln-table-window"),10);r>0&&t._cache.configure({windowSize:r})}return}if(!(!t._windowed||!t._cache)){if(i==="data-ln-table-window-page"){const n=parseInt(e.getAttribute("data-ln-table-window-page"),10);n>0&&t._cache.configure({pageSize:n})}else if(i==="data-ln-table-window-threshold"){const n=parseInt(e.getAttribute("data-ln-table-window-threshold"),10);n>=0&&t._cache.configure({threshold:n})}else if(i==="data-ln-table-count"){const n=parseInt(e.getAttribute("data-ln-table-count"),10);n>=0&&t._cache.setGrandTotal(n)}}}}})})()})();
@@ -1,11 +0,0 @@
1
- // ── JS state: ln-table structural/state overrides ──
2
-
3
- // gls compat — remove when gls migrates to ln-popover filter pattern
4
- .content:has([data-ln-table]) {
5
- overflow: visible;
6
- }
7
-
8
- // Sort icon visibility toggled by JS (.hidden class)
9
- [data-ln-table] th[data-ln-sort] [data-ln-sort-icon].hidden {
10
- display: none;
11
- }
@@ -1,73 +0,0 @@
1
- # ln-table-coordinator
2
-
3
- A zero-dependency, per-instance, host-scoped coordinator component that wires external search hosts (`ln-search`), column filter popovers (`ln-filter`), header filter indicators, and clear button triggers to a single `ln-table`.
4
-
5
- `ln-table` itself is a Layer 1 primitive: it manages internal data state, virtual scroll rendering, pagination/windowing cache, row template cloning, cell formatting, and selection DOM state. `ln-table-coordinator` is the Layer 2 policy and mediator that wires external UI controls to `ln-table`.
6
-
7
- ---
8
-
9
- ## 🧭 Philosophy & Architecture
10
-
11
- 1. **Layer Separation.** `ln-table` manages its own internal table state and DOM subtree only — no external DOM querying, no external input mirroring, and no visual indicator class toggles on header buttons. `ln-table-coordinator` handles all project UI wiring on top.
12
- 2. **Host-Scoped, Per-Instance.** The coordinator is a real component: `[data-ln-table-coordinator]` is a **required wrapper**. Its handlers are bound to its own host element (`self.dom`), not `document`. The table, its `[data-ln-filter]` popovers, and its clear button(s) must all be descendants of the same coordinator host — outside its own subtree, the coordinator does not exist and does not look.
13
- 3. **Event-Driven Communication.** Communication with `ln-table` occurs strictly via CustomEvents (`ln-table:set-search`, `ln-table:set-filter`, `ln-table:request-clear-filters`).
14
-
15
- **Breaking change:** a data-driven table's search/filter/clear-all only works when wrapped in `[data-ln-table-coordinator]`. There is no page-wide fallback — the coordinator does not resolve a table by scanning the whole document.
16
-
17
- ---
18
-
19
- ## 🛠️ Declarative API & Wire Contract
20
-
21
- | Target / Trigger | Event / Trigger | Behavior |
22
- | :--- | :--- | :--- |
23
- | `[data-ln-search="tableId"]` (delivered by `ln-search` directly to the table) | `ln-search:change` | Guards `e.target` carries `data-ln-table` and `data-ln-table-source` (data-driven only), dispatches `ln-table:set-search`. |
24
- | `[data-ln-filter="tableId"]` (delivered by `ln-filter` directly to the table) | `ln-filter:changed` | Guards `e.target` carries `data-ln-table`, toggles `.ln-filter-active` indicator on filter button, dispatches `ln-table:set-filter`. |
25
- | `[data-ln-table-clear]`, `[data-ln-table-clear-all]` | `click` | Resolves the table structurally within this host, clears the linked search input and filter reset checkboxes, removes `.ln-filter-active` visual classes, dispatches `ln-table:request-clear-filters`. |
26
- | Document | `keydown` (`'/'`) | Focuses the search input inside the active coordinator wrapper on the page (or the first `[data-ln-search]` if none). |
27
-
28
- Column filters (`data-ln-table-filter-col`) and clear-all (`data-ln-table-clear` / `data-ln-table-clear-all`) route through `ln-table-coordinator` in both SSR and data-driven modes — an SSR table using them still requires the `[data-ln-table-coordinator]` wrapper, even though SSR search and sort do not (see below).
29
-
30
- Search is the one asymmetric control: the coordinator only intercepts search for **data-driven** tables. SSR tables self-bind `ln-search:change` directly (see [`js/ln-table/README.md`](../ln-table/README.md)) and never need the wrapper for search alone.
31
-
32
- ---
33
-
34
- ## ⚡ Consumed & Dispatched Events
35
-
36
- ### Consumed Events
37
- - `ln-search:change` (on `self.dom`, the coordinator host)
38
- - `ln-filter:changed` (on `self.dom`)
39
- - `click` (on `self.dom` — targets `[data-ln-table-clear]` and `[data-ln-table-clear-all]`)
40
- - `keydown` (`document` — key `'/'`, the sole document-level exception, see below)
41
-
42
- ### Dispatched Events
43
- - `ln-table:set-search` (Target: the table inside this host, Payload: `{ query, term, table }`)
44
- - `ln-table:set-filter` (Target: the table inside this host, Payload: `{ key, values, table }`)
45
- - `ln-table:request-clear-filters` (Target: the table inside this host, Payload: `{ table }`)
46
-
47
- The coordinator does not dispatch anything from its own host element — it has no outward/notification event. It only relays inward, to the table.
48
-
49
- ---
50
-
51
- ## 🔧 Internals
52
-
53
- Source: `js/ln-table-coordinator/src/ln-table-coordinator.js`. This is a real per-instance component: `_component(dom)` calls `_bindEvents(self)`, which stores its three listeners on `self._handlers` and attaches them to `self.dom` — mirroring the `js/ln-data-coordinator` idiom. `destroy()` removes all three symmetrically and clears `self._handlers`. `registerComponent` also supplies the `window.lnTableCoordinator` double-load guard.
54
-
55
- ### Search
56
-
57
- `ln-search` dispatches `ln-search:change` directly on its resolved target (`document.getElementById(targetId)`) — when that target IS the table, `e.target` already carries `data-ln-table`. The coordinator does no ID resolution for search, only a guard: `e.target` must carry both `data-ln-table` and `data-ln-table-source` (data-driven). An SSR table caught by this listener is a markup mistake — it self-binds `ln-search:change` on its own, and wrapping it in `[data-ln-table-coordinator]` would double-fire; the `data-ln-table-source` guard prevents that.
58
-
59
- ### Column-filter indicator
60
-
61
- `ln-filter` dispatches `ln-filter:changed` on both its own `<ul data-ln-filter>` root and, if different, directly on the table via `getElementById` — again, no ID resolution needed, only the `data-ln-table` guard. On a match, the coordinator finds the `th[data-ln-table-filter-col="key"]` and toggles `.ln-filter-active` on that header's `[data-ln-table-col-filter]` button based on `values.length > 0`, then dispatches `ln-table:set-filter`. This header-indicator class is Layer-2 policy — which is exactly why `ln-table` itself never sets it.
62
-
63
- ### Clear
64
-
65
- A `click` on `[data-ln-table-clear]` / `[data-ln-table-clear-all]` has no ID binding of its own, so it resolves structurally: `clearBtn.closest('[data-ln-table]')`, falling back to `dom.querySelector('[data-ln-table]')` — always scoped to this host, never document-wide. It then runs: (1) strip `.ln-filter-active` off every filter button in the table, (2) blank the linked search input (scoped to this host), (3) check each linked filter popover's `[data-ln-filter-reset]` and fire a bubbling `change`, (4) dispatch `ln-table:request-clear-filters`.
66
-
67
- ### `/` focus shortcut
68
-
69
- The sole deliberate exception to host-scoping. It remains a single `document`-level `keydown` listener registered once at module scope (outside `_component`/`_bindEvents`) — a page-level keyboard affordance, not coordination between a host and its children. Registering it per-instance would fire it once per coordinator on the page. It focuses the search input inside the active `[data-ln-table-coordinator]` wrapper, or the first `[data-ln-search]` on the page if none. Ignored when focus is already in an `INPUT`/`TEXTAREA`, or when the event was already `defaultPrevented`.
70
-
71
- ### Multi-coordinator isolation
72
-
73
- Each `_component(dom)` instance closures its handlers over its own `dom`; `addEventListener` on a specific host node only fires for events whose bubble path passes through that node. Two coordinator hosts on the same page cannot see each other's descendants' events — no shared/global state exists to leak. The `/` shortcut is the sole intentional exception to this isolation — it is document-scoped by design.
@@ -1 +0,0 @@
1
- (function(){"use strict";if(typeof window<"u"){const t=console.warn;console.warn=function(...e){typeof e[0]=="string"&&(e[0].startsWith("[ln-")||e[0].startsWith("[lnCore"))&&!(document.documentElement.hasAttribute("data-ln-debug")||document.body&&document.body.hasAttribute("data-ln-debug"))||t.apply(console,e)}}const b={};function O(t,e){b[t]||(b[t]=document.querySelector('[data-ln-template="'+t+'"]'));const i=b[t];return i?i.content.cloneNode(!0):(console.warn("["+(e||"ln-core")+'] Template "'+t+'" not found'),null)}function g(t,e,i){t.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:i||{}}))}function E(t,e){if(!t||!e)return t;const i=t.querySelectorAll("[data-ln-field]");for(let n=0;n<i.length;n++){const l=i[n],r=l.getAttribute("data-ln-field");e[r]!=null&&(l.textContent=e[r])}const f=t.querySelectorAll("[data-ln-attr]");for(let n=0;n<f.length;n++){const l=f[n],r=l.getAttribute("data-ln-attr").split(",");for(let a=0;a<r.length;a++){const d=r[a].trim().split(":");if(d.length!==2)continue;const u=d[0].trim(),c=d[1].trim();e[c]!=null&&l.setAttribute(u,e[c])}}const s=t.querySelectorAll("[data-ln-show]");for(let n=0;n<s.length;n++){const l=s[n],r=l.getAttribute("data-ln-show");r in e&&l.classList.toggle("hidden",!e[r])}const o=t.querySelectorAll("[data-ln-class]");for(let n=0;n<o.length;n++){const l=o[n],r=l.getAttribute("data-ln-class").split(",");for(let a=0;a<r.length;a++){const d=r[a].trim().split(":");if(d.length!==2)continue;const u=d[0].trim(),c=d[1].trim();c in e&&l.classList.toggle(u,!!e[c])}}return t}function D(t,e){t.matches&&t.matches("[data-ln-form], [data-ln-fillable]")&&t.dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0}));const i=t.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let f=0;f<i.length;f++)i[f].dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0}));return t}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(t){if(!(!t.target.matches||!t.target.matches("[data-ln-fillable]")))if(t.detail)E(t.target,t.detail);else{const e=t.target.querySelectorAll("[data-ln-field]");for(let i=0;i<e.length;i++)e[i].textContent=""}})));function S(t,e){if(!t||!e)return t;const i=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;i.nextNode();){const o=i.currentNode;o.textContent.indexOf("{{")!==-1&&(o.textContent=o.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(n,l){return e[l]!==void 0?e[l]:""}))}const f=function(o,n){return e[n]!==void 0?e[n]:""},s=Array.from(t.querySelectorAll("*"));t.nodeType===1&&s.push(t);for(let o=0;o<s.length;o++){const n=s[o],l=n.attributes;for(let r=0;r<l.length;r++){const a=l[r];a.value.indexOf("{{")!==-1&&n.setAttribute(a.name,a.value.replace(/\{\{\s*(\w+)\s*\}\}/g,f))}}return t}function I(t,e,i,f,s,o){const n={};for(let r=0;r<t.children.length;r++){const a=t.children[r],d=a.getAttribute("data-ln-key");d&&(n[d]=a)}const l=document.createDocumentFragment();for(let r=0;r<e.length;r++){const a=e[r],d=String(f(a));let u=n[d];if(u)s(u,a,r);else{const c=O(i,o);if(!c||(S(c,a),u=c.firstElementChild,!u))continue;u.setAttribute("data-ln-key",d),s(u,a,r)}l.appendChild(u)}t.textContent="",t.appendChild(l)}function L(t,e){if(!document.body){document.addEventListener("DOMContentLoaded",function(){L(t,e)}),console.warn("["+e+'] Script loaded before <body> — add "defer" to your <script> tag');return}t()}function y(t,e,i,f){if(t.nodeType!==1)return;const o=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]",n=Array.from(t.querySelectorAll(o));t.matches&&t.matches(o)&&n.push(t);for(const l of n)l[i]||(l[i]=new f(l))}function M(t,e,i,f,s={}){const o=s.extraAttributes||[],n=s.onAttributeChange||null,l=s.onInit||null;function r(a){const d=a||document.body;y(d,t,e,i),l&&l(d)}return L(function(){const a=new MutationObserver(function(u){for(let c=0;c<u.length;c++){const m=u[c];if(m.type==="childList"){for(let h=0;h<m.addedNodes.length;h++){const p=m.addedNodes[h];p.nodeType===1&&(y(p,t,e,i),l&&l(p))}for(let h=0;h<m.removedNodes.length;h++){const p=m.removedNodes[h];if(p.nodeType===1){const _=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",C=Array.from(p.querySelectorAll(_));p.matches&&p.matches(_)&&C.push(p);for(let v=0;v<C.length;v++){const N=C[v];if(!document.contains(N)){const A=N[e];A&&typeof A.destroy=="function"&&A.destroy()}}}}}else m.type==="attributes"&&(n&&m.target[e]?n(m.target,m.attributeName):(y(m.target,t,e,i),l&&l(m.target)))}});let d=[];if(t.indexOf("[")!==-1){const u=/\[([\w-]+)/g;let c;for(;(c=u.exec(t))!==null;)d.push(c[1])}else d.push(t);a.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:d.concat(o)})},f),window[e]=r,document.readyState==="loading"?document.addEventListener("DOMContentLoaded",function(){r(document.body)}):r(document.body),r}const T={};function j(t,e){T[t]=e}function B(t){return T[t]||{ingress:e=>e,egress:e=>e}}const q={};function x(t,e){if(!t||typeof e!="object")return;const i=t.toLowerCase().split("-")[0];q[i]=e}function R(t){if(!t)return null;const e=t.toLowerCase().split("-")[0];return q[e]||null}x("mk",{monthsLong:["јануари","февруари","март","април","мај","јуни","јули","август","септември","октомври","ноември","декември"],monthsShort:["јан","фев","мар","апр","мај","јун","јул","авг","септ","окт","ноем","дек"],daysLong:["недела","понеделник","вторник","среда","четврток","петок","сабота"],daysShort:["нед","пон","вт","ср","чет","пет","саб"]}),typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=j,window.lnCore.getDataMapper=B,window.lnCore.registerLocaleFallback=x,window.lnCore.getLocaleFallback=R,window.lnCore.fillTemplate=S,window.lnCore.fill=E,window.lnCore.lnFill=D,window.lnCore.renderList=I);function k(t){return(t||"").replace(/^#/,"")}function w(t){const e=t===void 0?location.hash:t,i={},f=k(e);if(!f)return i;const s=f.split("&");for(let o=0;o<s.length;o++){const n=s[o];if(!n)continue;const l=n.indexOf(":"),r=l>-1?n.slice(0,l):n,a=l>-1?n.slice(l+1):"";if(r)try{i[r]=decodeURIComponent(a)}catch{i[r]=a}}return i}function W(t){if(!t)return null;const e=w();return t in e?e[t]:null}function F(t,e){if(!t)return;const i=w();e==null?delete i[t]:i[t]=String(e);const s=Object.keys(i).map(function(o){const n=i[o];return n===""?o:o+":"+encodeURIComponent(n)}).join("&");k(location.hash)!==s&&(location.hash=s)}function U(t){return t.button===1||t.ctrlKey||t.metaKey||t.shiftKey?!1:(t.preventDefault(),!0)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=w,window.lnCore.hashGet=W,window.lnCore.hashSet=F,window.lnCore.hashLinkClick=U),(function(){const t="data-ln-table-coordinator",e="lnTableCoordinator";if(window[e]!==void 0)return;document.addEventListener("keydown",function(s){if(s.key!=="/"||s.defaultPrevented||document.activeElement&&(document.activeElement.tagName==="INPUT"||document.activeElement.tagName==="TEXTAREA"))return;const o=document.querySelector("["+t+"] [data-ln-search]")||document.querySelector("[data-ln-search]");if(!o)return;const n=o.tagName==="INPUT"||o.tagName==="TEXTAREA"?o:o.querySelector('input[type="search"], input[type="text"], input');n&&(s.preventDefault(),n.focus())});function i(s){return this.dom=s,f(this),this}function f(s){const o=s.dom;s._handlers={search:function(n){const l=n.target;if(!l.hasAttribute||!l.hasAttribute("data-ln-table")||!l.lnTable||!l.hasAttribute("data-ln-table-source"))return;n.preventDefault();const r=n.detail&&n.detail.term!=null?n.detail.term:"",a=l.lnTable.name||l.id;g(l,"ln-table:set-search",{query:r,term:r,table:a})},filter:function(n){if(!n.detail)return;const l=n.target;if(!l.hasAttribute||!l.hasAttribute("data-ln-table")||!l.lnTable)return;const r=n.detail.key,a=n.detail.values||[],d=l.lnTable.name||l.id,u=l.querySelectorAll("th");for(let c=0;c<u.length;c++)if(u[c].getAttribute("data-ln-table-filter-col")===r){const m=u[c].querySelector("[data-ln-table-col-filter]");m&&m.classList.toggle("ln-filter-active",a.length>0);break}g(l,"ln-table:set-filter",{key:r,values:a,table:d})},clear:function(n){const l=n.target.closest("[data-ln-table-clear], [data-ln-table-clear-all]");if(!l)return;const r=l.closest("[data-ln-table]")||o.querySelector("[data-ln-table]");if(!r||!r.lnTable)return;const a=r.lnTable.name||r.id,d=r.querySelectorAll("th");for(let h=0;h<d.length;h++){const p=d[h].querySelector("[data-ln-table-col-filter]");p&&p.classList.remove("ln-filter-active")}const u=r.id,c=u&&o.querySelector('[data-ln-search="'+u+'"]')||o.querySelector("[data-ln-search]");if(c){const h=c.tagName==="INPUT"||c.tagName==="TEXTAREA"?c:c.querySelector("input");h&&(h.value="")}const m=u&&o.querySelectorAll('[data-ln-filter="'+u+'"]')||o.querySelectorAll("[data-ln-filter]");for(let h=0;h<m.length;h++){const p=m[h].querySelector("[data-ln-filter-reset]");p&&(p.checked=!0,p.dispatchEvent(new Event("change",{bubbles:!0})))}g(r,"ln-table:request-clear-filters",{table:a})}},o.addEventListener("ln-search:change",s._handlers.search),o.addEventListener("ln-filter:changed",s._handlers.filter),o.addEventListener("click",s._handlers.clear)}i.prototype.destroy=function(){this.dom[e]&&(this._handlers&&(this.dom.removeEventListener("ln-search:change",this._handlers.search),this.dom.removeEventListener("ln-filter:changed",this._handlers.filter),this.dom.removeEventListener("click",this._handlers.clear),this._handlers=null),delete this.dom[e])},M(t,e,i,"ln-table-coordinator")})()})();
@@ -1,160 +0,0 @@
1
- import { registerComponent, dispatch } from '../../ln-core';
2
-
3
- (function () {
4
- const DOM_SELECTOR = 'data-ln-table-coordinator';
5
- const DOM_ATTRIBUTE = 'lnTableCoordinator';
6
-
7
- if (window[DOM_ATTRIBUTE] !== undefined) return;
8
-
9
- // ─── Keyboard Navigation Search Focus ('/' shortcut) ──
10
- // Deliberate, user-approved exception to host-scoping: this is a
11
- // page-level keyboard affordance, not coordination between a host and
12
- // its children, so it stays a single module-scope document listener
13
- // exactly as it behaves today (unchanged resolution order). Registering
14
- // it per-instance inside _bindEvents would fire it once per coordinator
15
- // on the page — this is why it lives outside _component/_bindEvents.
16
-
17
- document.addEventListener('keydown', function (e) {
18
- if (e.key !== '/') return;
19
- if (e.defaultPrevented) return;
20
- if (document.activeElement && (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA')) return;
21
-
22
- // Resolve search input inside active coordinator wrapper or first visible search
23
- const searchHost = document.querySelector('[' + DOM_SELECTOR + '] [data-ln-search]') || document.querySelector('[data-ln-search]');
24
- if (!searchHost) return;
25
-
26
- const input = (searchHost.tagName === 'INPUT' || searchHost.tagName === 'TEXTAREA')
27
- ? searchHost
28
- : searchHost.querySelector('input[type="search"], input[type="text"], input');
29
-
30
- if (input) {
31
- e.preventDefault();
32
- input.focus();
33
- }
34
- });
35
-
36
- // ─── Component Constructor ─────────────────────────────
37
-
38
- function _component(dom) {
39
- this.dom = dom;
40
- _bindEvents(this);
41
- return this;
42
- }
43
-
44
- // ─── Event Binding (host-scoped — own subtree only) ────
45
-
46
- function _bindEvents(self) {
47
- const dom = self.dom;
48
-
49
- self._handlers = {
50
- // ln-search dispatches ln-search:change directly on its resolved
51
- // target — when that target IS the table, e.target already carries
52
- // data-ln-table. No ID resolution needed here, only a guard.
53
- search: function (e) {
54
- const table = e.target;
55
- if (!table.hasAttribute || !table.hasAttribute('data-ln-table')) return;
56
- if (!table.lnTable) return;
57
- // SSR tables self-bind ln-search:change directly (see ln-table.js) —
58
- // the coordinator only owns the data-driven path. A table wrapped
59
- // here that happens to be SSR is a markup mistake (rule: coordinator
60
- // is data-driven-only); this guard prevents a double-fire rather
61
- // than silently mishandling it.
62
- if (!table.hasAttribute('data-ln-table-source')) return;
63
-
64
- e.preventDefault();
65
- const term = e.detail && e.detail.term != null ? e.detail.term : '';
66
- const name = table.lnTable.name || table.id;
67
-
68
- dispatch(table, 'ln-table:set-search', { query: term, term: term, table: name });
69
- },
70
-
71
- // ln-filter dispatches ln-filter:changed on both its own <ul> root
72
- // and (if different) directly on the table via getElementById — same
73
- // reasoning: no ID resolution needed, only a guard.
74
- filter: function (e) {
75
- if (!e.detail) return;
76
- const table = e.target;
77
- if (!table.hasAttribute || !table.hasAttribute('data-ln-table')) return;
78
- if (!table.lnTable) return;
79
-
80
- const key = e.detail.key;
81
- const values = e.detail.values || [];
82
- const name = table.lnTable.name || table.id;
83
-
84
- // Header filter-button indicator — Layer 2 policy; ln-table itself
85
- // never sets this class.
86
- const ths = table.querySelectorAll('th');
87
- for (let i = 0; i < ths.length; i++) {
88
- if (ths[i].getAttribute('data-ln-table-filter-col') === key) {
89
- const btn = ths[i].querySelector('[data-ln-table-col-filter]');
90
- if (btn) btn.classList.toggle('ln-filter-active', values.length > 0);
91
- break;
92
- }
93
- }
94
-
95
- dispatch(table, 'ln-table:set-filter', { key: key, values: values, table: name });
96
- },
97
-
98
- // Clear-all has no ID binding of its own — resolve structurally,
99
- // scoped to this host only (never document-wide).
100
- clear: function (e) {
101
- const clearBtn = e.target.closest('[data-ln-table-clear], [data-ln-table-clear-all]');
102
- if (!clearBtn) return;
103
-
104
- const table = clearBtn.closest('[data-ln-table]') || dom.querySelector('[data-ln-table]');
105
- if (!table || !table.lnTable) return;
106
-
107
- const name = table.lnTable.name || table.id;
108
-
109
- const ths = table.querySelectorAll('th');
110
- for (let i = 0; i < ths.length; i++) {
111
- const filterBtn = ths[i].querySelector('[data-ln-table-col-filter]');
112
- if (filterBtn) filterBtn.classList.remove('ln-filter-active');
113
- }
114
-
115
- const tableId = table.id;
116
- const searchEl = (tableId && dom.querySelector('[data-ln-search="' + tableId + '"]'))
117
- || dom.querySelector('[data-ln-search]');
118
- if (searchEl) {
119
- const input = (searchEl.tagName === 'INPUT' || searchEl.tagName === 'TEXTAREA')
120
- ? searchEl
121
- : searchEl.querySelector('input');
122
- if (input) input.value = '';
123
- }
124
-
125
- const filters = (tableId && dom.querySelectorAll('[data-ln-filter="' + tableId + '"]'))
126
- || dom.querySelectorAll('[data-ln-filter]');
127
- for (let i = 0; i < filters.length; i++) {
128
- const resetInput = filters[i].querySelector('[data-ln-filter-reset]');
129
- if (resetInput) {
130
- resetInput.checked = true;
131
- resetInput.dispatchEvent(new Event('change', { bubbles: true }));
132
- }
133
- }
134
-
135
- dispatch(table, 'ln-table:request-clear-filters', { table: name });
136
- }
137
- };
138
-
139
- dom.addEventListener('ln-search:change', self._handlers.search);
140
- dom.addEventListener('ln-filter:changed', self._handlers.filter);
141
- dom.addEventListener('click', self._handlers.clear);
142
- }
143
-
144
- // ─── Destroy ────────────────────────────────────────────
145
-
146
- _component.prototype.destroy = function () {
147
- if (!this.dom[DOM_ATTRIBUTE]) return;
148
-
149
- if (this._handlers) {
150
- this.dom.removeEventListener('ln-search:change', this._handlers.search);
151
- this.dom.removeEventListener('ln-filter:changed', this._handlers.filter);
152
- this.dom.removeEventListener('click', this._handlers.clear);
153
- this._handlers = null;
154
- }
155
-
156
- delete this.dom[DOM_ATTRIBUTE];
157
- };
158
-
159
- registerComponent(DOM_SELECTOR, DOM_ATTRIBUTE, _component, 'ln-table-coordinator');
160
- })();
@@ -1,18 +0,0 @@
1
- @use '../../scss/config/mixins' as *;
2
-
3
- [data-ln-debug] {
4
- // 1. Tabs Configuration Check: [data-ln-tabs] must have an id or data-ln-tabs-key
5
- [data-ln-tabs]:not([id]):not([data-ln-tabs-key]) {
6
- @include dev-dom-error("[data-ln-tabs] must have an 'id' or 'data-ln-tabs-key' for state tracking.");
7
- }
8
-
9
- // 2. Tab Trigger Type: triggers inside forms must be explicitly type="button" to prevent submit events
10
- form [data-ln-tabs-for]:not([type="button"]) {
11
- @include dev-inline-error("tab trigger within form must have type='button'");
12
- }
13
-
14
- // 3. Tab Trigger Nesting Check: [data-ln-tabs-for] must be nested inside a [data-ln-tabs] parent container
15
- [data-ln-tabs-for]:not([data-ln-tabs] *) {
16
- @include dev-inline-error("[data-ln-tabs-for] is orphaned (not inside a [data-ln-tabs] container)");
17
- }
18
- }
@@ -1 +0,0 @@
1
- (function(){"use strict";if(typeof window<"u"){const t=console.warn;console.warn=function(...e){typeof e[0]=="string"&&(e[0].startsWith("[ln-")||e[0].startsWith("[lnCore"))&&!(document.documentElement.hasAttribute("data-ln-debug")||document.body&&document.body.hasAttribute("data-ln-debug"))||t.apply(console,e)}}const g={};function P(t,e){g[t]||(g[t]=document.querySelector('[data-ln-template="'+t+'"]'));const o=g[t];return o?o.content.cloneNode(!0):(console.warn("["+(e||"ln-core")+'] Template "'+t+'" not found'),null)}function S(t,e,o){t.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:o||{}}))}function _(t,e){if(!t||!e)return t;const o=t.querySelectorAll("[data-ln-field]");for(let r=0;r<o.length;r++){const s=o[r],n=s.getAttribute("data-ln-field");e[n]!=null&&(s.textContent=e[n])}const a=t.querySelectorAll("[data-ln-attr]");for(let r=0;r<a.length;r++){const s=a[r],n=s.getAttribute("data-ln-attr").split(",");for(let l=0;l<n.length;l++){const c=n[l].trim().split(":");if(c.length!==2)continue;const f=c[0].trim(),d=c[1].trim();e[d]!=null&&s.setAttribute(f,e[d])}}const u=t.querySelectorAll("[data-ln-show]");for(let r=0;r<u.length;r++){const s=u[r],n=s.getAttribute("data-ln-show");n in e&&s.classList.toggle("hidden",!e[n])}const i=t.querySelectorAll("[data-ln-class]");for(let r=0;r<i.length;r++){const s=i[r],n=s.getAttribute("data-ln-class").split(",");for(let l=0;l<n.length;l++){const c=n[l].trim().split(":");if(c.length!==2)continue;const f=c[0].trim(),d=c[1].trim();d in e&&s.classList.toggle(f,!!e[d])}}return t}function R(t,e){t.matches&&t.matches("[data-ln-form], [data-ln-fillable]")&&t.dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0}));const o=t.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let a=0;a<o.length;a++)o[a].dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0}));return t}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(t){if(!(!t.target.matches||!t.target.matches("[data-ln-fillable]")))if(t.detail)_(t.target,t.detail);else{const e=t.target.querySelectorAll("[data-ln-field]");for(let o=0;o<e.length;o++)e[o].textContent=""}})));function x(t,e){if(!t||!e)return t;const o=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;o.nextNode();){const i=o.currentNode;i.textContent.indexOf("{{")!==-1&&(i.textContent=i.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(r,s){return e[s]!==void 0?e[s]:""}))}const a=function(i,r){return e[r]!==void 0?e[r]:""},u=Array.from(t.querySelectorAll("*"));t.nodeType===1&&u.push(t);for(let i=0;i<u.length;i++){const r=u[i],s=r.attributes;for(let n=0;n<s.length;n++){const l=s[n];l.value.indexOf("{{")!==-1&&r.setAttribute(l.name,l.value.replace(/\{\{\s*(\w+)\s*\}\}/g,a))}}return t}function j(t,e,o,a,u,i){const r={};for(let n=0;n<t.children.length;n++){const l=t.children[n],c=l.getAttribute("data-ln-key");c&&(r[c]=l)}const s=document.createDocumentFragment();for(let n=0;n<e.length;n++){const l=e[n],c=String(a(l));let f=r[c];if(f)u(f,l,n);else{const d=P(o,i);if(!d||(x(d,l),f=d.firstElementChild,!f))continue;f.setAttribute("data-ln-key",c),u(f,l,n)}s.appendChild(f)}t.textContent="",t.appendChild(s)}function k(t,e){if(!document.body){document.addEventListener("DOMContentLoaded",function(){k(t,e)}),console.warn("["+e+'] Script loaded before <body> — add "defer" to your <script> tag');return}t()}function w(t,e,o,a){if(t.nodeType!==1)return;const i=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]",r=Array.from(t.querySelectorAll(i));t.matches&&t.matches(i)&&r.push(t);for(const s of r)s[o]||(s[o]=new a(s))}function W(t,e,o,a,u={}){const i=u.extraAttributes||[],r=u.onAttributeChange||null,s=u.onInit||null;function n(l){const c=l||document.body;w(c,t,e,o),s&&s(c)}return k(function(){const l=new MutationObserver(function(f){for(let d=0;d<f.length;d++){const h=f[d];if(h.type==="childList"){for(let m=0;m<h.addedNodes.length;m++){const p=h.addedNodes[m];p.nodeType===1&&(w(p,t,e,o),s&&s(p))}for(let m=0;m<h.removedNodes.length;m++){const p=h.removedNodes[m];if(p.nodeType===1){const I=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",C=Array.from(p.querySelectorAll(I));p.matches&&p.matches(I)&&C.push(p);for(let v=0;v<C.length;v++){const M=C[v];if(!document.contains(M)){const L=M[e];L&&typeof L.destroy=="function"&&L.destroy()}}}}}else h.type==="attributes"&&(r&&h.target[e]?r(h.target,h.attributeName):(w(h.target,t,e,o),s&&s(h.target)))}});let c=[];if(t.indexOf("[")!==-1){const f=/\[([\w-]+)/g;let d;for(;(d=f.exec(t))!==null;)c.push(d[1])}else c.push(t);l.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:c.concat(i)})},a),window[e]=n,document.readyState==="loading"?document.addEventListener("DOMContentLoaded",function(){n(document.body)}):n(document.body),n}const E={};function H(t,e){E[t]=e}function B(t){return E[t]||{ingress:e=>e,egress:e=>e}}const T={};function q(t,e){if(!t||typeof e!="object")return;const o=t.toLowerCase().split("-")[0];T[o]=e}function U(t){if(!t)return null;const e=t.toLowerCase().split("-")[0];return T[e]||null}q("mk",{monthsLong:["јануари","февруари","март","април","мај","јуни","јули","август","септември","октомври","ноември","декември"],monthsShort:["јан","фев","мар","апр","мај","јун","јул","авг","септ","окт","ноем","дек"],daysLong:["недела","понеделник","вторник","среда","четврток","петок","сабота"],daysShort:["нед","пон","вт","ср","чет","пет","саб"]}),typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=H,window.lnCore.getDataMapper=B,window.lnCore.registerLocaleFallback=q,window.lnCore.getLocaleFallback=U,window.lnCore.fillTemplate=x,window.lnCore.fill=_,window.lnCore.lnFill=R,window.lnCore.renderList=j);const G="ln:";let b=null;function O(){if(b!==null)return b;try{if(typeof localStorage>"u")return b=!1,!1;const t="__ln_test__";localStorage.setItem(t,t),localStorage.removeItem(t),b=!0}catch{b=!1}return b}function J(){return location.pathname.replace(/\/+$/,"").toLowerCase()||"/"}function K(t,e){const o=e.getAttribute("data-ln-persist"),a=o!==null&&o!==""?o:e.id;return a?G+t+":"+J()+":"+a:(console.warn('[ln-persist] Element requires id or data-ln-persist="key"',e),null)}function X(t,e){if(!O())return null;const o=K(t,e);if(!o)return null;try{const a=localStorage.getItem(o);return a!==null?JSON.parse(a):null}catch{return null}}function $(t,e,o){if(!O())return;const a=K(t,e);if(a)try{o==null?localStorage.removeItem(a):localStorage.setItem(a,JSON.stringify(o))}catch{}}function N(t){return(t||"").replace(/^#/,"")}function y(t){const e=t===void 0?location.hash:t,o={},a=N(e);if(!a)return o;const u=a.split("&");for(let i=0;i<u.length;i++){const r=u[i];if(!r)continue;const s=r.indexOf(":"),n=s>-1?r.slice(0,s):r,l=s>-1?r.slice(s+1):"";if(n)try{o[n]=decodeURIComponent(l)}catch{o[n]=l}}return o}function A(t){if(!t)return null;const e=y();return t in e?e[t]:null}function D(t,e){if(!t)return;const o=y();e==null?delete o[t]:o[t]=String(e);const u=Object.keys(o).map(function(i){const r=o[i];return r===""?i:i+":"+encodeURIComponent(r)}).join("&");N(location.hash)!==u&&(location.hash=u)}function F(t){return t.button===1||t.ctrlKey||t.metaKey||t.shiftKey?!1:(t.preventDefault(),!0)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=y,window.lnCore.hashGet=A,window.lnCore.hashSet=D,window.lnCore.hashLinkClick=F),(function(){const t="data-ln-tabs",e="lnTabs";if(window[e]!==void 0&&window[e]!==null)return;function o(i,r){const s=(i.getAttribute("data-ln-tab")||"").toLowerCase().trim();if(s)return s;if(i.tagName!=="A")return"";const n=i.getAttribute("href")||"";if(!n.startsWith("#"))return"";const l=n.slice(1);if(!l)return"";const c=l.split("&");if(r)for(const h of c){const m=h.indexOf(":");if(m>0&&h.slice(0,m).toLowerCase().trim()===r)return h.slice(m+1).toLowerCase().trim()}const f=c[c.length-1]||"",d=f.indexOf(":");return(d>0?f.slice(d+1):f).toLowerCase().trim()}function a(i){return this.dom=i,u.call(this),this}function u(){this.tabs=Array.from(this.dom.querySelectorAll("[data-ln-tab]")),this.panels=Array.from(this.dom.querySelectorAll("[data-ln-panel]"));const i=this.tabs.filter(n=>n.tagName==="A"&&(n.getAttribute("href")||"").startsWith("#")),r=i.length>0&&i.length===this.tabs.length;this.nsKey=(this.dom.getAttribute("data-ln-tabs-key")||this.dom.id||"").toLowerCase().trim(),this.hashEnabled=r&&!!this.nsKey,i.length>0&&i.length!==this.tabs.length?console.warn('[ln-tabs] Mixed <a href="#…"> and <button> triggers in one group — using persist mode. Pick one: anchors for URL hash, buttons for localStorage persist.',this.dom):r&&!this.nsKey&&console.warn("[ln-tabs] Anchor triggers need a hash namespace — add id or data-ln-tabs-key to the wrapper. Falling back to non-hash mode.",this.dom),this.mapTabs={},this.mapPanels={};for(const n of this.tabs){const l=o(n,this.nsKey);l?this.mapTabs[l]=n:console.warn('[ln-tabs] Trigger has no resolvable key — needs `data-ln-tab="key"` or `<a href="#…">`.',n)}for(const n of this.panels){const l=(n.getAttribute("data-ln-panel")||"").toLowerCase().trim();l&&(this.mapPanels[l]=n)}this.defaultKey=(this.dom.getAttribute("data-ln-tabs-default")||"").toLowerCase().trim()||Object.keys(this.mapTabs)[0]||"",this.autoFocus=(this.dom.getAttribute("data-ln-tabs-focus")||"true").toLowerCase()!=="false";const s=this;this._clickHandlers=[];for(const n of this.tabs){if(n[e+"Trigger"])continue;const l=function(c){const f=n.tagName==="A";if(!f&&(c.ctrlKey||c.metaKey||c.button===1))return;const d=o(n,s.nsKey);d&&(f&&!F(c)||(s.hashEnabled?A(s.nsKey)===d?s.dom.setAttribute("data-ln-tabs-active",d):D(s.nsKey,d):s.dom.setAttribute("data-ln-tabs-active",d)))};n.addEventListener("click",l),n[e+"Trigger"]=l,s._clickHandlers.push({el:n,handler:l})}if(this._onRequestSelect=function(n){const l=n.detail&&(n.detail.key||n.detail.tab);l&&s.dom.setAttribute("data-ln-tabs-active",(l+"").toLowerCase().trim())},this.dom.addEventListener("ln-tabs:request-select",this._onRequestSelect),this.dom.addEventListener("ln-tabs:request-activate",this._onRequestSelect),this._hashHandler=function(){if(!s.hashEnabled)return;const n=A(s.nsKey);s.dom.setAttribute("data-ln-tabs-active",n!==null?n:s.defaultKey)},this.hashEnabled)window.addEventListener("hashchange",this._hashHandler),this._hashHandler();else{let n=this.defaultKey;if(this.dom.hasAttribute("data-ln-persist")&&!this.hashEnabled){const l=X("tabs",this.dom);l!==null&&l in this.mapPanels&&(n=l)}this.dom.setAttribute("data-ln-tabs-active",n)}}a.prototype._applyActive=function(i){var r;(!i||!(i in this.mapPanels))&&(i=this.defaultKey);for(const s in this.mapTabs){const n=this.mapTabs[s];s===i?(n.setAttribute("data-active",""),n.setAttribute("aria-selected","true")):(n.removeAttribute("data-active"),n.setAttribute("aria-selected","false"))}for(const s in this.mapPanels){const n=this.mapPanels[s],l=s===i;n.classList.toggle("hidden",!l),n.setAttribute("aria-hidden",l?"false":"true")}if(this.autoFocus){const s=(r=this.mapPanels[i])==null?void 0:r.querySelector('input,button,select,textarea,[tabindex]:not([tabindex="-1"])');s&&setTimeout(()=>s.focus({preventScroll:!0}),0)}S(this.dom,"ln-tabs:change",{key:i,tab:this.mapTabs[i],panel:this.mapPanels[i]}),this.dom.hasAttribute("data-ln-persist")&&!this.hashEnabled&&$("tabs",this.dom,i)},a.prototype.destroy=function(){if(this.dom[e]){this.dom.removeEventListener("ln-tabs:request-select",this._onRequestSelect),this.dom.removeEventListener("ln-tabs:request-activate",this._onRequestSelect);for(const{el:i,handler:r}of this._clickHandlers)i.removeEventListener("click",r),delete i[e+"Trigger"];this.hashEnabled&&window.removeEventListener("hashchange",this._hashHandler),S(this.dom,"ln-tabs:destroyed",{target:this.dom}),delete this.dom[e]}},W(t,e,a,"ln-tabs",{extraAttributes:["data-ln-tabs-active"],onAttributeChange:function(i){const r=i.getAttribute("data-ln-tabs-active");i[e]._applyActive(r)}})})()})();
@@ -1,188 +0,0 @@
1
- /* Live Networks - lnTabs (hash-aware tabs — supports <button> and <a href="#nsKey:key"> triggers) */
2
- import { registerComponent, dispatch } from '../../ln-core';
3
- import { persistGet, persistSet } from '../../ln-core';
4
- import { hashGet, hashSet, hashLinkClick } from '../../ln-core';
5
-
6
- (function () {
7
- const DOM_SELECTOR = "data-ln-tabs";
8
- const DOM_ATTRIBUTE = "lnTabs";
9
-
10
- if (window[DOM_ATTRIBUTE] !== undefined && window[DOM_ATTRIBUTE] !== null) return;
11
-
12
-
13
- function _keyFromTrigger(t, nsKey) {
14
- const explicit = (t.getAttribute("data-ln-tab") || "").toLowerCase().trim();
15
- if (explicit) return explicit;
16
- if (t.tagName !== "A") return "";
17
- const href = t.getAttribute("href") || "";
18
- if (!href.startsWith("#")) return "";
19
- const raw = href.slice(1);
20
- if (!raw) return "";
21
- const fragments = raw.split("&");
22
- if (nsKey) {
23
- for (const frag of fragments) {
24
- const sep = frag.indexOf(":");
25
- if (sep > 0 && frag.slice(0, sep).toLowerCase().trim() === nsKey) {
26
- return frag.slice(sep + 1).toLowerCase().trim();
27
- }
28
- }
29
- }
30
- const last = fragments[fragments.length - 1] || "";
31
- const sep = last.indexOf(":");
32
- return (sep > 0 ? last.slice(sep + 1) : last).toLowerCase().trim();
33
- }
34
-
35
- function _component(dom) { this.dom = dom; _init.call(this); return this; }
36
-
37
- function _init() {
38
- this.tabs = Array.from(this.dom.querySelectorAll("[data-ln-tab]"));
39
- this.panels = Array.from(this.dom.querySelectorAll("[data-ln-panel]"));
40
-
41
- // Mode is declared by the TRIGGER TYPE, not by presence of an id:
42
- // <a href="#…"> → URL hash sync (shareable, back/forward aware)
43
- // <button> → localStorage persist (opt-in via data-ln-persist)
44
- // This decouples the two axes that used to collide on `id`: now
45
- // `id`/`data-ln-tabs-key` only NAMESPACE the hash, and
46
- // `data-ln-persist` only names the storage key — neither selects the
47
- // mode. The markup does. Mixed triggers almost always signal a markup
48
- // mistake, so we fall back to persist and warn rather than guess.
49
- //
50
- // nsKey resolved BEFORE mapTabs build — anchor key derivation in
51
- // _keyFromTrigger needs nsKey to pick the right fragment.
52
- const anchorTabs = this.tabs.filter(t => t.tagName === "A" && (t.getAttribute("href") || "").startsWith("#"));
53
- const allAnchors = anchorTabs.length > 0 && anchorTabs.length === this.tabs.length;
54
- this.nsKey = (this.dom.getAttribute("data-ln-tabs-key") || this.dom.id || "").toLowerCase().trim();
55
- this.hashEnabled = allAnchors && !!this.nsKey;
56
-
57
- if (anchorTabs.length > 0 && anchorTabs.length !== this.tabs.length) {
58
- console.warn('[ln-tabs] Mixed <a href="#…"> and <button> triggers in one group — using persist mode. Pick one: anchors for URL hash, buttons for localStorage persist.', this.dom);
59
- } else if (allAnchors && !this.nsKey) {
60
- console.warn('[ln-tabs] Anchor triggers need a hash namespace — add id or data-ln-tabs-key to the wrapper. Falling back to non-hash mode.', this.dom);
61
- }
62
-
63
- this.mapTabs = {};
64
- this.mapPanels = {};
65
- for (const t of this.tabs) {
66
- const key = _keyFromTrigger(t, this.nsKey);
67
- if (key) {
68
- this.mapTabs[key] = t;
69
- } else {
70
- console.warn('[ln-tabs] Trigger has no resolvable key — needs `data-ln-tab="key"` or `<a href="#…">`.', t);
71
- }
72
- }
73
- for (const p of this.panels) {
74
- const key = (p.getAttribute("data-ln-panel") || "").toLowerCase().trim();
75
- if (key) this.mapPanels[key] = p;
76
- }
77
-
78
- this.defaultKey = (this.dom.getAttribute("data-ln-tabs-default") || "").toLowerCase().trim()
79
- || Object.keys(this.mapTabs)[0] || "";
80
- this.autoFocus = (this.dom.getAttribute("data-ln-tabs-focus") || "true").toLowerCase() !== "false";
81
-
82
- const self = this;
83
- this._clickHandlers = [];
84
- for (const t of this.tabs) {
85
- if (t[DOM_ATTRIBUTE + 'Trigger']) continue;
86
- const handler = function (e) {
87
- const isAnchor = t.tagName === "A";
88
- // Buttons keep their plain modifier/middle-click guard. Anchor
89
- // triggers route through the shared core hash-link helper, which
90
- // owns the guard (incl. shiftKey) AND the preventDefault — the
91
- // same path ln-modal uses, so anchor click handling is unified.
92
- if (!isAnchor && (e.ctrlKey || e.metaKey || e.button === 1)) return;
93
- const key = _keyFromTrigger(t, self.nsKey);
94
- if (!key) return;
95
- if (isAnchor && !hashLinkClick(e)) return;
96
- if (self.hashEnabled) {
97
- if (hashGet(self.nsKey) === key) self.dom.setAttribute('data-ln-tabs-active', key);
98
- else hashSet(self.nsKey, key);
99
- } else {
100
- self.dom.setAttribute('data-ln-tabs-active', key);
101
- }
102
- };
103
- t.addEventListener("click", handler);
104
- t[DOM_ATTRIBUTE + 'Trigger'] = handler;
105
- self._clickHandlers.push({ el: t, handler: handler });
106
- }
107
-
108
- this._onRequestSelect = function (e) {
109
- const key = e.detail && (e.detail.key || e.detail.tab);
110
- if (key) self.dom.setAttribute('data-ln-tabs-active', (key + '').toLowerCase().trim());
111
- };
112
- this.dom.addEventListener('ln-tabs:request-select', this._onRequestSelect);
113
- this.dom.addEventListener('ln-tabs:request-activate', this._onRequestSelect);
114
-
115
- this._hashHandler = function () {
116
- if (!self.hashEnabled) return;
117
- const val = hashGet(self.nsKey);
118
- self.dom.setAttribute('data-ln-tabs-active', val !== null ? val : self.defaultKey);
119
- };
120
-
121
- if (this.hashEnabled) {
122
- window.addEventListener("hashchange", this._hashHandler);
123
- this._hashHandler();
124
- } else {
125
- let initialKey = this.defaultKey;
126
- if (this.dom.hasAttribute('data-ln-persist') && !this.hashEnabled) {
127
- const saved = persistGet('tabs', this.dom);
128
- if (saved !== null && saved in this.mapPanels) {
129
- initialKey = saved;
130
- }
131
- }
132
- this.dom.setAttribute('data-ln-tabs-active', initialKey);
133
- }
134
- }
135
-
136
- _component.prototype._applyActive = function (key) {
137
- if (!key || !(key in this.mapPanels)) key = this.defaultKey;
138
- for (const k in this.mapTabs) {
139
- const btn = this.mapTabs[k];
140
- if (k === key) {
141
- btn.setAttribute("data-active", "");
142
- btn.setAttribute("aria-selected", "true");
143
- } else {
144
- btn.removeAttribute("data-active");
145
- btn.setAttribute("aria-selected", "false");
146
- }
147
- }
148
- for (const k in this.mapPanels) {
149
- const panel = this.mapPanels[k];
150
- const show = (k === key);
151
- panel.classList.toggle("hidden", !show);
152
- panel.setAttribute("aria-hidden", show ? "false" : "true");
153
- }
154
- if (this.autoFocus) {
155
- const first = this.mapPanels[key]?.querySelector('input,button,select,textarea,[tabindex]:not([tabindex="-1"])');
156
- if (first) setTimeout(() => first.focus({ preventScroll: true }), 0);
157
- }
158
- dispatch(this.dom, 'ln-tabs:change', { key: key, tab: this.mapTabs[key], panel: this.mapPanels[key] });
159
- if (this.dom.hasAttribute('data-ln-persist') && !this.hashEnabled) {
160
- persistSet('tabs', this.dom, key);
161
- }
162
- };
163
-
164
- _component.prototype.destroy = function () {
165
- if (!this.dom[DOM_ATTRIBUTE]) return;
166
- this.dom.removeEventListener('ln-tabs:request-select', this._onRequestSelect);
167
- this.dom.removeEventListener('ln-tabs:request-activate', this._onRequestSelect);
168
- for (const { el, handler } of this._clickHandlers) {
169
- el.removeEventListener("click", handler);
170
- delete el[DOM_ATTRIBUTE + 'Trigger'];
171
- }
172
- if (this.hashEnabled) {
173
- window.removeEventListener("hashchange", this._hashHandler);
174
- }
175
- dispatch(this.dom, 'ln-tabs:destroyed', { target: this.dom });
176
- delete this.dom[DOM_ATTRIBUTE];
177
- };
178
-
179
- // ─── Init ──────────────────────────────────────────────────
180
-
181
- registerComponent(DOM_SELECTOR, DOM_ATTRIBUTE, _component, 'ln-tabs', {
182
- extraAttributes: ['data-ln-tabs-active'],
183
- onAttributeChange: function (el) {
184
- const key = el.getAttribute('data-ln-tabs-active');
185
- el[DOM_ATTRIBUTE]._applyActive(key);
186
- }
187
- });
188
- })();