@livenetworks/ashlar 1.6.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +641 -0
- package/README.md +202 -86
- package/{js → components}/COMPONENTS.md +1116 -1108
- package/{js → components}/index.js +81 -58
- package/{js → components}/ln-accordion/README.md +7 -6
- package/components/ln-accordion/ln-accordion-dev.scss +8 -0
- package/components/ln-accordion/ln-accordion.js +1 -0
- package/components/ln-accordion/ln-accordion.schema.json +30 -0
- package/components/ln-accordion/ln-accordion.scss +8 -0
- package/{js → components}/ln-accordion/src/ln-accordion.js +8 -2
- package/{js → components}/ln-ajax/README.md +171 -160
- package/components/ln-ajax/ln-ajax-dev.scss +8 -0
- package/components/ln-ajax/ln-ajax.js +1 -0
- package/components/ln-ajax/ln-ajax.schema.json +30 -0
- package/{js → components}/ln-ajax/src/ln-ajax.js +65 -30
- package/{js → components}/ln-api-connector/README.md +27 -5
- package/components/ln-api-connector/ln-api-connector.js +1 -0
- package/components/ln-api-connector/ln-api-connector.schema.json +96 -0
- package/components/ln-api-connector/src/connector-core.js +97 -0
- package/components/ln-api-connector/src/ln-api-connector.js +447 -0
- package/{js → components}/ln-api-queue/README.md +12 -9
- package/components/ln-api-queue/ln-api-queue.js +1 -0
- package/components/ln-api-queue/ln-api-queue.schema.json +34 -0
- package/{js → components}/ln-api-queue/src/ln-api-queue.js +33 -14
- package/{js → components}/ln-api-queue/src/queue-storage.js +7 -3
- package/{js → components}/ln-autoresize/README.md +129 -127
- package/components/ln-autoresize/ln-autoresize-dev.scss +8 -0
- package/components/ln-autoresize/ln-autoresize.js +1 -0
- package/components/ln-autoresize/ln-autoresize.schema.json +22 -0
- package/{js → components}/ln-autoresize/src/ln-autoresize.js +8 -1
- package/{js → components}/ln-autosave/README.md +127 -124
- package/components/ln-autosave/ln-autosave-dev.scss +13 -0
- package/components/ln-autosave/ln-autosave.js +1 -0
- package/components/ln-autosave/ln-autosave.schema.json +48 -0
- package/components/ln-autosave/src/autosave-model.js +34 -0
- package/{js → components}/ln-autosave/src/ln-autosave.js +65 -58
- package/components/ln-chart/README.md +145 -0
- package/components/ln-chart/ln-chart-dev.scss +20 -0
- package/components/ln-chart/ln-chart.js +1 -0
- package/components/ln-chart/ln-chart.schema.json +146 -0
- package/components/ln-chart/ln-chart.scss +8 -0
- package/components/ln-chart/src/chart-model.js +154 -0
- package/components/ln-chart/src/ln-chart.js +176 -0
- package/{js → components}/ln-circular-progress/README.md +15 -14
- package/components/ln-circular-progress/ln-circular-progress-dev.scss +8 -0
- package/components/ln-circular-progress/ln-circular-progress.js +1 -0
- package/components/ln-circular-progress/ln-circular-progress.schema.json +42 -0
- package/{js → components}/ln-circular-progress/src/ln-circular-progress.js +32 -50
- package/components/ln-confirm/README.md +216 -0
- package/components/ln-confirm/ln-confirm-dev.scss +24 -0
- package/components/ln-confirm/ln-confirm.js +1 -0
- package/components/ln-confirm/ln-confirm.schema.json +66 -0
- package/components/ln-confirm/ln-confirm.scss +24 -0
- package/{js → components}/ln-confirm/src/ln-confirm.js +180 -167
- package/{js → components}/ln-core/README.md +374 -149
- package/components/ln-core/attrs.js +273 -0
- package/components/ln-core/compare.js +40 -0
- package/components/ln-core/crypto.js +265 -0
- package/components/ln-core/date.js +50 -0
- package/components/ln-core/dom.js +115 -0
- package/components/ln-core/events.js +122 -0
- package/components/ln-core/form.js +136 -0
- package/{js → components}/ln-core/hash.js +149 -92
- package/components/ln-core/helpers.js +33 -0
- package/components/ln-core/http.js +48 -0
- package/components/ln-core/index.js +11 -0
- package/components/ln-core/lifecycle.js +403 -0
- package/components/ln-core/ln-core.schema.json +109 -0
- package/components/ln-core/locale.js +55 -0
- package/components/ln-core/matching.js +78 -0
- package/components/ln-core/number.js +125 -0
- package/components/ln-core/progress.js +30 -0
- package/components/ln-core/template.js +206 -0
- package/{js → components}/ln-core/window-cache.js +247 -213
- package/{js → components}/ln-couchdb-connector/README.md +7 -5
- package/components/ln-couchdb-connector/ln-couchdb-connector.js +1 -0
- package/components/ln-couchdb-connector/ln-couchdb-connector.schema.json +50 -0
- package/{js → components}/ln-couchdb-connector/src/ln-couchdb-connector.js +29 -43
- package/{js → components}/ln-data-coordinator/README.md +109 -73
- package/components/ln-data-coordinator/ln-data-coordinator-dev.scss +8 -0
- package/components/ln-data-coordinator/ln-data-coordinator.js +1 -0
- package/components/ln-data-coordinator/ln-data-coordinator.schema.json +196 -0
- package/components/ln-data-coordinator/src/data-read-policy.js +41 -0
- package/{js → components}/ln-data-coordinator/src/ln-data-coordinator.js +411 -154
- package/{js → components}/ln-data-coordinator/src/mutation-receipts.js +0 -5
- package/{js → components}/ln-data-store/README.md +42 -17
- package/components/ln-data-store/ln-data-store-dev.scss +13 -0
- package/components/ln-data-store/ln-data-store.js +1 -0
- package/components/ln-data-store/ln-data-store.schema.json +84 -0
- package/components/ln-data-store/src/data-store-model.js +155 -0
- package/{js → components}/ln-data-store/src/ln-data-store.js +407 -105
- package/components/ln-data-store/src/window-index.js +119 -0
- package/{js → components}/ln-date/README.md +17 -7
- package/{js → components}/ln-date/ln-date-dev.scss +14 -14
- package/components/ln-date/ln-date.js +1 -0
- package/components/ln-date/ln-date.schema.json +92 -0
- package/components/ln-date/src/date-model.js +186 -0
- package/components/ln-date/src/ln-date.js +486 -0
- package/components/ln-debug/README.md +132 -0
- package/components/ln-debug/ln-debug.js +1 -0
- package/components/ln-debug/ln-debug.schema.json +28 -0
- package/components/ln-debug/src/console-sink.js +19 -0
- package/components/ln-debug/src/debug-verifier.js +331 -0
- package/components/ln-debug/src/gate.js +95 -0
- package/components/ln-debug/src/generated-attributes.js +299 -0
- package/components/ln-debug/src/ln-debug.js +60 -0
- package/{js → components}/ln-dropdown/README.md +150 -140
- package/components/ln-dropdown/ln-dropdown-dev.scss +13 -0
- package/components/ln-dropdown/ln-dropdown.js +1 -0
- package/components/ln-dropdown/ln-dropdown.schema.json +90 -0
- package/components/ln-dropdown/ln-dropdown.scss +18 -0
- package/{js → components}/ln-dropdown/src/ln-dropdown.js +114 -11
- package/{js → components}/ln-editor/README.md +11 -9
- package/components/ln-editor/ln-editor-dev.scss +18 -0
- package/components/ln-editor/ln-editor.js +1 -0
- package/components/ln-editor/ln-editor.schema.json +58 -0
- package/components/ln-editor/ln-editor.scss +13 -0
- package/{js → components}/ln-editor/src/ln-editor.js +59 -11
- package/{js → components}/ln-external-links/README.md +10 -8
- package/components/ln-external-links/ln-external-links.js +1 -0
- package/components/ln-external-links/ln-external-links.schema.json +18 -0
- package/{js → components}/ln-external-links/src/ln-external-links.js +13 -11
- package/{js → components}/ln-fill/README.md +6 -8
- package/components/ln-fill/ln-fill.js +1 -0
- package/components/ln-fill/ln-fill.schema.json +23 -0
- package/{js → components}/ln-fill/src/ln-fill.js +7 -1
- package/components/ln-filter/README.md +131 -0
- package/components/ln-filter/ln-filter-dev.scss +13 -0
- package/components/ln-filter/ln-filter.js +1 -0
- package/components/ln-filter/ln-filter.schema.json +153 -0
- package/components/ln-filter/src/filter-model.js +185 -0
- package/components/ln-filter/src/ln-filter.js +435 -0
- package/{js → components}/ln-form/README.md +260 -264
- package/components/ln-form/ln-form-dev.scss +8 -0
- package/components/ln-form/ln-form.js +1 -0
- package/components/ln-form/ln-form.schema.json +45 -0
- package/{js → components}/ln-form/src/ln-form.js +107 -99
- package/{js → components}/ln-http/README.md +11 -6
- package/components/ln-http/ln-http.js +1 -0
- package/components/ln-http/ln-http.schema.json +6 -0
- package/components/ln-http/src/http-core.js +51 -0
- package/{js → components}/ln-http/src/ln-http.js +28 -33
- package/{js → components}/ln-icon/README.md +16 -9
- package/components/ln-icon/ln-icon.schema.json +6 -0
- package/components/ln-include/README.md +75 -0
- package/components/ln-include/ln-include-dev.scss +13 -0
- package/components/ln-include/ln-include.js +1 -0
- package/components/ln-include/ln-include.schema.json +23 -0
- package/components/ln-include/src/ln-include.js +111 -0
- package/components/ln-key/README.md +130 -0
- package/components/ln-key/ln-key-dev.scss +18 -0
- package/components/ln-key/ln-key.js +1 -0
- package/components/ln-key/ln-key.schema.json +56 -0
- package/components/ln-key/src/key-model.js +146 -0
- package/components/ln-key/src/ln-key.js +201 -0
- package/{js → components}/ln-link/README.md +7 -9
- package/components/ln-link/ln-link-dev.scss +8 -0
- package/components/ln-link/ln-link.js +1 -0
- package/components/ln-link/ln-link.schema.json +22 -0
- package/{js → components}/ln-link/src/ln-link.js +16 -11
- package/components/ln-list/README.md +152 -0
- package/components/ln-list/ln-list-dev.scss +8 -0
- package/components/ln-list/ln-list.js +1 -0
- package/components/ln-list/ln-list.schema.json +166 -0
- package/components/ln-list/ln-list.scss +25 -0
- package/{js → components}/ln-list/src/ln-list.js +1301 -1216
- package/{js → components}/ln-modal/README.md +13 -10
- package/components/ln-modal/ln-modal-dev.scss +18 -0
- package/components/ln-modal/ln-modal.js +1 -0
- package/components/ln-modal/ln-modal.schema.json +54 -0
- package/components/ln-modal/ln-modal.scss +51 -0
- package/{js → components}/ln-modal/src/ln-modal.js +164 -137
- package/{js → components}/ln-nav/README.md +11 -11
- package/components/ln-nav/ln-nav.js +1 -0
- package/components/ln-nav/ln-nav.schema.json +25 -0
- package/{js → components}/ln-nav/src/ln-nav.js +25 -14
- package/components/ln-number/README.md +205 -0
- package/{js → components}/ln-number/ln-number-dev.scss +13 -13
- package/components/ln-number/ln-number.js +1 -0
- package/components/ln-number/ln-number.schema.json +63 -0
- package/components/ln-number/src/ln-number.js +400 -0
- package/components/ln-number/src/number-model.js +31 -0
- package/components/ln-obfuscator/README.md +60 -0
- package/components/ln-obfuscator/ln-obfuscator.js +1 -0
- package/components/ln-obfuscator/ln-obfuscator.schema.json +49 -0
- package/components/ln-obfuscator/src/ln-obfuscator.js +159 -0
- package/components/ln-obfuscator/src/obfuscator-model.js +250 -0
- package/{js → components}/ln-options/README.md +3 -1
- package/components/ln-options/ln-options-dev.scss +13 -0
- package/components/ln-options/ln-options.js +1 -0
- package/components/ln-options/ln-options.schema.json +41 -0
- package/{js → components}/ln-options/src/ln-options.js +13 -5
- package/components/ln-persist/README.md +151 -0
- package/components/ln-persist/ln-persist.js +1 -0
- package/components/ln-persist/ln-persist.schema.json +28 -0
- package/components/ln-persist/src/ln-persist.js +83 -0
- package/components/ln-picklist/README.md +230 -0
- package/components/ln-picklist/ln-picklist-dev.scss +22 -0
- package/components/ln-picklist/ln-picklist.js +1 -0
- package/components/ln-picklist/ln-picklist.schema.json +49 -0
- package/components/ln-picklist/src/ln-picklist.js +228 -0
- package/{js → components}/ln-popover/README.md +164 -162
- package/components/ln-popover/ln-popover-dev.scss +13 -0
- package/components/ln-popover/ln-popover.js +1 -0
- package/components/ln-popover/ln-popover.schema.json +82 -0
- package/components/ln-popover/ln-popover.scss +18 -0
- package/{js → components}/ln-popover/src/ln-popover.js +42 -36
- package/{js → components}/ln-progress/README.md +410 -413
- package/components/ln-progress/ln-progress-dev.scss +8 -0
- package/components/ln-progress/ln-progress.js +1 -0
- package/components/ln-progress/ln-progress.schema.json +40 -0
- package/components/ln-progress/src/ln-progress.js +91 -0
- package/components/ln-progress/src/progress-model.js +20 -0
- package/{js → components}/ln-router/README.md +443 -432
- package/components/ln-router/ln-router-dev.scss +13 -0
- package/components/ln-router/ln-router.js +1 -0
- package/components/ln-router/ln-router.schema.json +68 -0
- package/{js → components}/ln-router/src/ln-router.js +585 -539
- package/components/ln-router/src/router-model.js +50 -0
- package/components/ln-scroll/README.md +45 -0
- package/components/ln-scroll/ln-scroll.js +1 -0
- package/components/ln-scroll/ln-scroll.schema.json +85 -0
- package/components/ln-scroll/src/ln-scroll.js +150 -0
- package/components/ln-search/README.md +188 -0
- package/components/ln-search/ln-search-dev.scss +13 -0
- package/components/ln-search/ln-search.js +1 -0
- package/components/ln-search/ln-search.schema.json +103 -0
- package/components/ln-search/src/ln-search.js +330 -0
- package/{js → components}/ln-slug/README.md +6 -3
- package/components/ln-slug/ln-slug-dev.scss +18 -0
- package/components/ln-slug/ln-slug.js +1 -0
- package/components/ln-slug/ln-slug.schema.json +23 -0
- package/{js → components}/ln-slug/src/ln-slug.js +20 -13
- package/components/ln-slug/src/slug-model.js +21 -0
- package/{js → components}/ln-sort/README.md +178 -170
- package/{js → components}/ln-sort/ln-sort-dev.scss +8 -8
- package/components/ln-sort/ln-sort.js +1 -0
- package/components/ln-sort/ln-sort.schema.json +104 -0
- package/components/ln-sort/src/ln-sort.js +321 -0
- package/components/ln-sort/src/sort-model.js +117 -0
- package/{js → components}/ln-sortable/README.md +7 -11
- package/components/ln-sortable/ln-sortable-dev.scss +13 -0
- package/components/ln-sortable/ln-sortable.js +1 -0
- package/components/ln-sortable/ln-sortable.schema.json +36 -0
- package/{js → components}/ln-sortable/src/ln-sortable.js +8 -13
- package/{js → components}/ln-stat/README.md +3 -1
- package/components/ln-stat/ln-stat-dev.scss +8 -0
- package/components/ln-stat/ln-stat.js +1 -0
- package/components/ln-stat/ln-stat.schema.json +32 -0
- package/{js → components}/ln-stat/src/ln-stat.js +14 -18
- package/components/ln-stat/src/stat-model.js +28 -0
- package/{js → components}/ln-table/README.md +37 -24
- package/{js → components}/ln-table/ln-table-dev.scss +17 -17
- package/components/ln-table/ln-table.js +1 -0
- package/components/ln-table/ln-table.schema.json +211 -0
- package/components/ln-table/ln-table.scss +15 -0
- package/{js → components}/ln-table/src/ln-table.js +1365 -1493
- package/components/ln-table/src/table-model.js +98 -0
- package/components/ln-table-coordinator/README.md +61 -0
- package/components/ln-table-coordinator/ln-table-coordinator.js +1 -0
- package/components/ln-table-coordinator/ln-table-coordinator.schema.json +93 -0
- package/components/ln-table-coordinator/src/ln-table-coordinator.js +193 -0
- package/{js → components}/ln-tabs/README.md +32 -14
- package/components/ln-tabs/ln-tabs-dev.scss +24 -0
- package/components/ln-tabs/ln-tabs.js +1 -0
- package/components/ln-tabs/ln-tabs.schema.json +75 -0
- package/components/ln-tabs/ln-tabs.scss +8 -0
- package/components/ln-tabs/src/ln-tabs.js +207 -0
- package/components/ln-tabs/src/tabs-model.js +82 -0
- package/{js → components}/ln-time/README.md +96 -95
- package/components/ln-time/ln-time-dev.scss +13 -0
- package/components/ln-time/ln-time.js +1 -0
- package/components/ln-time/ln-time.schema.json +38 -0
- package/{js → components}/ln-time/src/ln-time.js +206 -223
- package/components/ln-time/src/time-model.js +64 -0
- package/{js → components}/ln-toast/README.md +23 -5
- package/components/ln-toast/ln-toast-dev.scss +8 -0
- package/components/ln-toast/ln-toast.js +1 -0
- package/components/ln-toast/ln-toast.schema.json +65 -0
- package/components/ln-toast/ln-toast.scss +59 -0
- package/{js → components}/ln-toast/src/ln-toast.js +233 -232
- package/{js → components}/ln-toggle/README.md +198 -196
- package/{js → components}/ln-toggle/ln-toggle-dev.scss +13 -13
- package/components/ln-toggle/ln-toggle.js +1 -0
- package/components/ln-toggle/ln-toggle.schema.json +52 -0
- package/components/ln-toggle/ln-toggle.scss +37 -0
- package/{js → components}/ln-toggle/src/ln-toggle.js +61 -46
- package/{js → components}/ln-tooltip/README.md +6 -6
- package/{js → components}/ln-tooltip/ln-tooltip-dev.scss +9 -9
- package/components/ln-tooltip/ln-tooltip.js +1 -0
- package/components/ln-tooltip/ln-tooltip.schema.json +86 -0
- package/components/ln-tooltip/ln-tooltip.scss +9 -0
- package/{js → components}/ln-tooltip/src/ln-tooltip.js +14 -3
- package/{js → components}/ln-translations/README.md +3 -1
- package/components/ln-translations/ln-translations-dev.scss +13 -0
- package/components/ln-translations/ln-translations.js +1 -0
- package/components/ln-translations/ln-translations.schema.json +120 -0
- package/{js → components}/ln-translations/src/ln-translations.js +25 -10
- package/components/ln-ui-coordinator/README.md +101 -0
- package/components/ln-ui-coordinator/ln-ui-coordinator-dev.scss +8 -0
- package/components/ln-ui-coordinator/ln-ui-coordinator.js +1 -0
- package/components/ln-ui-coordinator/ln-ui-coordinator.schema.json +60 -0
- package/{js/ln-modal-coordinator/src/ln-modal-coordinator.js → components/ln-ui-coordinator/src/ln-ui-coordinator.js} +403 -345
- package/components/ln-upload/README.md +133 -0
- package/components/ln-upload/ln-upload-dev.scss +18 -0
- package/components/ln-upload/ln-upload.js +1 -0
- package/components/ln-upload/ln-upload.schema.json +193 -0
- package/components/ln-upload/ln-upload.scss +20 -0
- package/components/ln-upload/src/ln-upload.js +652 -0
- package/components/ln-upload/src/upload-model.js +78 -0
- package/{js → components}/ln-validate/README.md +182 -180
- package/{js → components}/ln-validate/ln-validate-dev.scss +15 -15
- package/components/ln-validate/ln-validate.js +1 -0
- package/components/ln-validate/ln-validate.schema.json +50 -0
- package/components/ln-validate/ln-validate.scss +7 -0
- package/{js → components}/ln-validate/src/ln-validate.js +23 -45
- package/components/ln-validate/src/validate-model.js +64 -0
- package/components/ln-websocket-connector/README.md +166 -0
- package/components/ln-websocket-connector/ln-websocket-connector.js +1 -0
- package/components/ln-websocket-connector/ln-websocket-connector.schema.json +29 -0
- package/components/ln-websocket-connector/src/ln-websocket-connector.js +279 -0
- package/ln-ashlar.html-data.json +1796 -0
- package/package.json +84 -61
- package/{scss → theme}/base/_global.scss +1 -2
- package/{scss → theme}/base/_reset.scss +1 -1
- package/{scss → theme}/base/_typography.scss +2 -0
- package/theme/brand.css +73 -0
- package/{scss → theme}/components/_app-shell.scss +8 -0
- package/theme/components/_button.scss +24 -0
- package/theme/components/_chart.scss +5 -0
- package/theme/components/_confirm.scss +6 -0
- package/{scss → theme}/components/_date.scss +30 -22
- package/{scss → theme}/components/_dropdown.scss +6 -1
- package/theme/components/_form.scss +140 -0
- package/{scss → theme}/components/_layout.scss +6 -0
- package/{scss → theme}/components/_ln-table.scss +1 -6
- package/theme/components/_picklist.scss +3 -0
- package/{scss → theme}/components/_sort.scss +10 -10
- package/theme/components/_status-badge.scss +6 -0
- package/{scss → theme}/components/_table.scss +16 -0
- package/{scss → theme}/components/_tabs.scss +0 -4
- package/theme/components/_toast.scss +48 -0
- package/{scss → theme}/components/_toggle.scss +1 -1
- package/theme/components/_upload.scss +45 -0
- package/{scss → theme}/config/_breakpoints.scss +1 -1
- package/theme/config/_contrast.scss +128 -0
- package/{scss → theme}/config/_density.scss +191 -205
- package/theme/config/_palette.scss +274 -0
- package/theme/config/_theme.scss +293 -0
- package/{scss → theme}/config/_tokens.scss +285 -441
- package/{scss → theme}/config/mixins/_accordion.scss +1 -1
- package/{scss → theme}/config/mixins/_alert.scss +1 -0
- package/{scss → theme}/config/mixins/_app-shell.scss +4 -2
- package/{scss → theme}/config/mixins/_borders.scss +2 -0
- package/theme/config/mixins/_btn.scss +175 -0
- package/{scss → theme}/config/mixins/_card.scss +55 -46
- package/theme/config/mixins/_chart.scss +82 -0
- package/{scss → theme}/config/mixins/_collapsible.scss +2 -1
- package/{scss → theme}/config/mixins/_colors.scss +8 -14
- package/{scss → theme}/config/mixins/_diagnostics.scss +48 -48
- package/theme/config/mixins/_dropdown.scss +169 -0
- package/{scss → theme}/config/mixins/_editor.scss +0 -7
- package/{scss → theme}/config/mixins/_filter.scss +47 -47
- package/{scss → theme}/config/mixins/_footer.scss +1 -1
- package/{scss → theme}/config/mixins/_form.scss +49 -18
- package/{scss → theme}/config/mixins/_index.scss +62 -61
- package/{scss → theme}/config/mixins/_layout.scss +6 -2
- package/{scss → theme}/config/mixins/_ln-table.scss +31 -10
- package/{scss → theme}/config/mixins/_loader.scss +1 -1
- package/{scss → theme}/config/mixins/_modal.scss +145 -149
- package/{scss → theme}/config/mixins/_motion.scss +13 -0
- package/{scss → theme}/config/mixins/_nav.scss +7 -7
- package/theme/config/mixins/_picklist.scss +66 -0
- package/theme/config/mixins/_popover.scss +96 -0
- package/{scss → theme}/config/mixins/_sidebar.scss +7 -4
- package/{scss → theme}/config/mixins/_sort.scss +43 -42
- package/{scss → theme}/config/mixins/_status-badge.scss +15 -2
- package/{scss → theme}/config/mixins/_table.scss +25 -14
- package/{scss → theme}/config/mixins/_tabs.scss +1 -1
- package/{scss → theme}/config/mixins/_toast.scss +174 -179
- package/{scss → theme}/config/mixins/_tooltip.scss +2 -2
- package/{scss → theme}/config/mixins/_typography.scss +16 -5
- package/{scss → theme}/config/mixins/_upload.scss +8 -6
- package/theme/ln-ashlar-core.scss +24 -0
- package/theme/ln-ashlar-dev.scss +66 -0
- package/theme/ln-ashlar-landing.scss +56 -0
- package/{scss/ln-ashlar.scss → theme/ln-ashlar-theme.scss} +63 -69
- package/theme/ln-ashlar.scss +8 -0
- package/theme/presentation/_bento.scss +151 -0
- package/theme/presentation/_cta.scss +111 -0
- package/theme/presentation/_effects.scss +216 -0
- package/theme/presentation/_features.scss +108 -0
- package/theme/presentation/_footer.scss +129 -0
- package/theme/presentation/_hero.scss +158 -0
- package/theme/presentation/_layout.scss +170 -0
- package/theme/presentation/_navbar.scss +140 -0
- package/theme/presentation/_pricing.scss +262 -0
- package/theme/presentation/_stats.scss +87 -0
- package/theme/presentation/_testimonials.scss +124 -0
- package/theme/presentation/_tokens.scss +39 -0
- package/theme/presentation/_typography.scss +163 -0
- package/{scss → theme}/utilities/_animations.scss +38 -0
- package/{scss → theme}/utilities/_utilities.scss +6 -0
- package/web-types.json +2312 -0
- package/js/ln-accordion/ln-accordion.js +0 -1
- package/js/ln-ajax/ln-ajax.js +0 -1
- package/js/ln-api-connector/ln-api-connector.js +0 -1
- package/js/ln-api-connector/src/ln-api-connector.js +0 -368
- package/js/ln-api-queue/ln-api-queue.js +0 -1
- package/js/ln-autoresize/ln-autoresize.js +0 -1
- package/js/ln-autosave/ln-autosave.js +0 -1
- package/js/ln-circular-progress/ln-circular-progress.js +0 -1
- package/js/ln-confirm/README.md +0 -162
- package/js/ln-confirm/_ln-confirm.scss +0 -24
- package/js/ln-confirm/ln-confirm.js +0 -1
- package/js/ln-core/crypto.js +0 -83
- package/js/ln-core/helpers.js +0 -788
- package/js/ln-core/index.js +0 -7
- package/js/ln-core/persist.js +0 -97
- package/js/ln-couchdb-connector/ln-couchdb-connector.js +0 -1
- package/js/ln-data-coordinator/ln-data-coordinator.js +0 -1
- package/js/ln-data-coordinator/src/data-read-policy.js +0 -18
- package/js/ln-data-store/ln-data-store.js +0 -1
- package/js/ln-date/ln-date.js +0 -1
- package/js/ln-date/src/ln-date.js +0 -603
- package/js/ln-debug/README.md +0 -58
- package/js/ln-debug/ln-debug.js +0 -1
- package/js/ln-debug/src/ln-debug.js +0 -19
- package/js/ln-dropdown/ln-dropdown.js +0 -1
- package/js/ln-dropdown/ln-dropdown.scss +0 -15
- package/js/ln-editor/ln-editor.js +0 -1
- package/js/ln-editor/ln-editor.scss +0 -43
- package/js/ln-external-links/ln-external-links.js +0 -1
- package/js/ln-fill/ln-fill.js +0 -1
- package/js/ln-filter/README.md +0 -189
- package/js/ln-filter/ln-filter-dev.scss +0 -8
- package/js/ln-filter/ln-filter.js +0 -1
- package/js/ln-filter/src/ln-filter.js +0 -419
- package/js/ln-form/ln-form.js +0 -1
- package/js/ln-http/ln-http.js +0 -1
- package/js/ln-link/ln-link.js +0 -1
- package/js/ln-list/README.md +0 -129
- package/js/ln-list/ln-list.js +0 -1
- package/js/ln-list/ln-list.scss +0 -28
- package/js/ln-modal/ln-modal-dev.scss +0 -13
- package/js/ln-modal/ln-modal.js +0 -1
- package/js/ln-modal/ln-modal.scss +0 -35
- package/js/ln-modal-coordinator/README.md +0 -99
- package/js/ln-modal-coordinator/ln-modal-coordinator-dev.scss +0 -8
- package/js/ln-modal-coordinator/ln-modal-coordinator.js +0 -1
- package/js/ln-nav/ln-nav.js +0 -1
- package/js/ln-number/README.md +0 -149
- package/js/ln-number/ln-number.js +0 -1
- package/js/ln-number/src/ln-number.js +0 -443
- package/js/ln-options/ln-options.js +0 -1
- package/js/ln-popover/ln-popover.js +0 -1
- package/js/ln-progress/ln-progress.js +0 -1
- package/js/ln-progress/src/ln-progress.js +0 -98
- package/js/ln-router/ln-router.js +0 -1
- package/js/ln-search/README.md +0 -158
- package/js/ln-search/ln-search-dev.scss +0 -8
- package/js/ln-search/ln-search.js +0 -1
- package/js/ln-search/src/ln-search.js +0 -117
- package/js/ln-slug/ln-slug.js +0 -1
- package/js/ln-sort/ln-sort.js +0 -1
- package/js/ln-sort/src/ln-sort.js +0 -178
- package/js/ln-sortable/ln-sortable.js +0 -1
- package/js/ln-stat/ln-stat.js +0 -1
- package/js/ln-table/ln-table.js +0 -1
- package/js/ln-table/ln-table.scss +0 -11
- package/js/ln-table-coordinator/README.md +0 -73
- package/js/ln-table-coordinator/ln-table-coordinator.js +0 -1
- package/js/ln-table-coordinator/src/ln-table-coordinator.js +0 -160
- package/js/ln-tabs/ln-tabs-dev.scss +0 -18
- package/js/ln-tabs/ln-tabs.js +0 -1
- package/js/ln-tabs/src/ln-tabs.js +0 -188
- package/js/ln-time/ln-time.js +0 -1
- package/js/ln-toast/ln-toast.js +0 -1
- package/js/ln-toggle/ln-toggle.js +0 -1
- package/js/ln-tooltip/ln-tooltip.js +0 -1
- package/js/ln-tooltip/ln-tooltip.scss +0 -9
- package/js/ln-translations/ln-translations.js +0 -1
- package/js/ln-upload/README.md +0 -255
- package/js/ln-upload/ln-upload.js +0 -1
- package/js/ln-upload/ln-upload.scss +0 -20
- package/js/ln-upload/src/ln-upload.js +0 -423
- package/js/ln-validate/ln-validate.js +0 -1
- package/scss/components/_button.scss +0 -20
- package/scss/components/_confirm.scss +0 -5
- package/scss/components/_form.scss +0 -107
- package/scss/components/_status-badge.scss +0 -4
- package/scss/components/_toast.scss +0 -68
- package/scss/components/_upload.scss +0 -51
- package/scss/config/_theme.scss +0 -216
- package/scss/config/mixins/_btn.scss +0 -179
- package/scss/config/mixins/_confirm.scss +0 -31
- package/scss/config/mixins/_dropdown.scss +0 -141
- package/scss/config/mixins/_popover.scss +0 -64
- package/scss/ln-ashlar-dev.scss +0 -39
- /package/{js → components}/ln-core/positioning.js +0 -0
- /package/{js → components}/ln-core/reactive.js +0 -0
- /package/{js → components}/ln-filter/ln-filter.scss +0 -0
- /package/{js → components}/ln-icon/ln-icon.js +0 -0
- /package/{js → components}/ln-icon/src/ln-icon.js +0 -0
- /package/{js → components}/ln-search/ln-search.scss +0 -0
- /package/{js → components}/ln-toast/template.html +0 -0
- /package/{scss → theme}/components/_accordion.scss +0 -0
- /package/{scss → theme}/components/_ajax.scss +0 -0
- /package/{scss → theme}/components/_alert.scss +0 -0
- /package/{scss → theme}/components/_avatar.scss +0 -0
- /package/{scss → theme}/components/_breadcrumbs.scss +0 -0
- /package/{scss → theme}/components/_card.scss +0 -0
- /package/{scss → theme}/components/_chip.scss +0 -0
- /package/{scss → theme}/components/_circular-progress.scss +0 -0
- /package/{scss → theme}/components/_editor.scss +0 -0
- /package/{scss → theme}/components/_empty-state.scss +0 -0
- /package/{scss → theme}/components/_filter.scss +0 -0
- /package/{scss → theme}/components/_link.scss +0 -0
- /package/{scss → theme}/components/_loader.scss +0 -0
- /package/{scss → theme}/components/_modal.scss +0 -0
- /package/{scss → theme}/components/_nav.scss +0 -0
- /package/{scss → theme}/components/_page-header.scss +0 -0
- /package/{scss → theme}/components/_popover.scss +0 -0
- /package/{scss → theme}/components/_progress.scss +0 -0
- /package/{scss → theme}/components/_prose.scss +0 -0
- /package/{scss → theme}/components/_scrollbar.scss +0 -0
- /package/{scss → theme}/components/_sections.scss +0 -0
- /package/{scss → theme}/components/_sidebar.scss +0 -0
- /package/{scss → theme}/components/_stat-card.scss +0 -0
- /package/{scss → theme}/components/_stepper.scss +0 -0
- /package/{scss → theme}/components/_timeline.scss +0 -0
- /package/{scss → theme}/components/_tooltip.scss +0 -0
- /package/{scss → theme}/components/_translations.scss +0 -0
- /package/{scss → theme}/config/_icons.scss +0 -0
- /package/{scss → theme}/config/_mixins.scss +0 -0
- /package/{scss → theme}/config/mixins/_ajax.scss +0 -0
- /package/{scss → theme}/config/mixins/_avatar.scss +0 -0
- /package/{scss → theme}/config/mixins/_breadcrumbs.scss +0 -0
- /package/{scss → theme}/config/mixins/_breakpoints.scss +0 -0
- /package/{scss → theme}/config/mixins/_chip.scss +0 -0
- /package/{scss → theme}/config/mixins/_circular-progress.scss +0 -0
- /package/{scss → theme}/config/mixins/_display.scss +0 -0
- /package/{scss → theme}/config/mixins/_empty-state.scss +0 -0
- /package/{scss → theme}/config/mixins/_focus.scss +0 -0
- /package/{scss → theme}/config/mixins/_interaction.scss +0 -0
- /package/{scss → theme}/config/mixins/_kbd.scss +0 -0
- /package/{scss → theme}/config/mixins/_link.scss +0 -0
- /package/{scss → theme}/config/mixins/_page-header.scss +0 -0
- /package/{scss → theme}/config/mixins/_position.scss +0 -0
- /package/{scss → theme}/config/mixins/_progress.scss +0 -0
- /package/{scss → theme}/config/mixins/_prose.scss +0 -0
- /package/{scss → theme}/config/mixins/_shadows.scss +0 -0
- /package/{scss → theme}/config/mixins/_sizing.scss +0 -0
- /package/{scss → theme}/config/mixins/_spacing.scss +0 -0
- /package/{scss → theme}/config/mixins/_stat-card.scss +0 -0
- /package/{scss → theme}/config/mixins/_stepper.scss +0 -0
- /package/{scss → theme}/config/mixins/_timeline.scss +0 -0
- /package/{scss → theme}/config/mixins/_transitions.scss +0 -0
- /package/{scss → theme}/config/mixins/_translations.scss +0 -0
- /package/{scss → theme}/tabler-icons.txt +0 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// ─── Windowed Store Position Index ────────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// In-memory sliding-window index mapping logical positions to record IDs
|
|
4
|
+
// for server-side virtualization. Holds logical/grand totals, request dedup,
|
|
5
|
+
// stale-guard queryGen, and LRU eviction using JS Map insertion order.
|
|
6
|
+
|
|
7
|
+
export function createWindowIndex(config = {}) {
|
|
8
|
+
let windowSize = config.windowSize > 0 ? config.windowSize : 1000;
|
|
9
|
+
let pageSize = config.pageSize > 0 ? config.pageSize : 200;
|
|
10
|
+
let fetchDebounce = config.fetchDebounce != null ? config.fetchDebounce : 120;
|
|
11
|
+
const requestPage = typeof config.requestPage === 'function' ? config.requestPage : () => {};
|
|
12
|
+
|
|
13
|
+
const map = new Map(); // logicalIndex → id (LRU by insertion order)
|
|
14
|
+
const inflight = new Set(); // offsets currently requested
|
|
15
|
+
let logicalTotal = 0, grandTotal = 0, queryGen = 0, hasLoaded = false, debounceId = null;
|
|
16
|
+
|
|
17
|
+
function touch(i, id) {
|
|
18
|
+
map.delete(i);
|
|
19
|
+
map.set(i, id);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Returns the ids that left residency, so the store can drop them from
|
|
23
|
+
// IndexedDB and windowSize bounds the records held, not just the positions.
|
|
24
|
+
// Only ids this index itself placed can ever be returned — a locally created
|
|
25
|
+
// record the server has not positioned is never in the map, so eviction can
|
|
26
|
+
// not reach it.
|
|
27
|
+
function evict() {
|
|
28
|
+
if (map.size <= windowSize) return [];
|
|
29
|
+
const dropped = [];
|
|
30
|
+
while (map.size > windowSize) {
|
|
31
|
+
const key = map.keys().next().value;
|
|
32
|
+
dropped.push(map.get(key));
|
|
33
|
+
map.delete(key);
|
|
34
|
+
}
|
|
35
|
+
// One id can occupy more than one position; it has only left residency
|
|
36
|
+
// once no remaining position refers to it.
|
|
37
|
+
const remaining = new Set(map.values());
|
|
38
|
+
return dropped.filter(id => !remaining.has(id));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function fire(offset, query) {
|
|
42
|
+
inflight.add(offset);
|
|
43
|
+
clearTimeout(debounceId);
|
|
44
|
+
debounceId = setTimeout(() => requestPage(offset, pageSize, query), fetchDebounce);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
get logicalTotal() { return logicalTotal; },
|
|
49
|
+
set logicalTotal(val) { logicalTotal = val; },
|
|
50
|
+
get grandTotal() { return grandTotal; },
|
|
51
|
+
set grandTotal(val) { grandTotal = val; },
|
|
52
|
+
get queryGen() { return queryGen; },
|
|
53
|
+
set queryGen(val) { queryGen = val; },
|
|
54
|
+
get size() { return map.size; },
|
|
55
|
+
// Whether a server ordering exists for the current query at all — false
|
|
56
|
+
// from reset() until the first ingest(). Distinct from a missing page.
|
|
57
|
+
get hasLoaded() { return hasLoaded; },
|
|
58
|
+
|
|
59
|
+
getId: i => {
|
|
60
|
+
if (!map.has(i)) return undefined;
|
|
61
|
+
const id = map.get(i);
|
|
62
|
+
touch(i, id);
|
|
63
|
+
return id;
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
ensure: (startRow, endRow, query) => {
|
|
67
|
+
if (!hasLoaded && !inflight.has(0)) return fire(0, query);
|
|
68
|
+
if (logicalTotal <= 0) return;
|
|
69
|
+
|
|
70
|
+
const start = Math.max(0, startRow);
|
|
71
|
+
const end = Math.min(logicalTotal, endRow);
|
|
72
|
+
|
|
73
|
+
for (let i = start; i < end; i++) {
|
|
74
|
+
if (!map.has(i)) {
|
|
75
|
+
const pageOffset = Math.floor(i / pageSize) * pageSize;
|
|
76
|
+
if (!inflight.has(pageOffset)) return fire(pageOffset, query);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
ingest: (offset, ids, total, filtered, qGen) => {
|
|
82
|
+
if (qGen != null && qGen !== queryGen) return [];
|
|
83
|
+
hasLoaded = true;
|
|
84
|
+
if (total != null) grandTotal = total;
|
|
85
|
+
if (filtered != null) logicalTotal = filtered;
|
|
86
|
+
|
|
87
|
+
for (let i = 0; i < ids.length; i++) {
|
|
88
|
+
touch(offset + i, ids[i]);
|
|
89
|
+
}
|
|
90
|
+
inflight.delete(offset);
|
|
91
|
+
return evict();
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
reset: function () {
|
|
95
|
+
queryGen++;
|
|
96
|
+
this.clear();
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
clear: () => {
|
|
100
|
+
hasLoaded = false;
|
|
101
|
+
map.clear();
|
|
102
|
+
inflight.clear();
|
|
103
|
+
clearTimeout(debounceId);
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
// Returns the ids evicted by a window shrink, same contract as ingest() —
|
|
107
|
+
// the caller must purge them from storage.
|
|
108
|
+
configure: (partial = {}) => {
|
|
109
|
+
let evicted = [];
|
|
110
|
+
if (partial.windowSize > 0 && partial.windowSize !== windowSize) {
|
|
111
|
+
windowSize = partial.windowSize;
|
|
112
|
+
evicted = evict();
|
|
113
|
+
}
|
|
114
|
+
if (partial.pageSize > 0) pageSize = partial.pageSize;
|
|
115
|
+
if (partial.fetchDebounce >= 0) fetchDebounce = partial.fetchDebounce;
|
|
116
|
+
return evicted;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# ln-date
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Applied to an `<input type="date" data-ln-date name="...">`. On initialization, it wraps the element in a
|
|
4
|
+
> `<span data-ln-date-field>` containing a visible text input, a hidden native date picker, a hidden `<input type="hidden" name="...">`
|
|
5
|
+
> for form submission, and a calendar button. On button `click`, it calls `showPicker()` on the date picker; on text input `blur`,
|
|
6
|
+
> it parses the entered string, updates the hidden ISO input, and reformats the visible text.
|
|
4
7
|
|
|
5
8
|
## Usage
|
|
6
9
|
|
|
@@ -59,7 +62,9 @@ The hidden input holds the ISO date string (YYYY-MM-DD) for form submission.
|
|
|
59
62
|
|
|
60
63
|
| Attribute | On | Description |
|
|
61
64
|
|-----------|-----|-------------|
|
|
62
|
-
| `data-ln-date` | `<input>` | Enables date formatting. Value = format (keyword or pattern). Default: `medium` |
|
|
65
|
+
| `data-ln-date` | `<input>`, `<time>`, `<td>` | Enables date formatting. Value = format (keyword or pattern). Default: `medium` |
|
|
66
|
+
| `datetime` | `<time>` | Native machine-readable date attribute; primary observable SSOT on `<time>` elements. |
|
|
67
|
+
| `data-ln-value` | `<td>`, `<span>`, `<input>` | Raw ISO date string or timestamp; acts as raw machine value for non-`<time>` elements. |
|
|
63
68
|
| `data-ln-date-label` | `<input>` | Optional. Translated `aria-label` for the injected calendar button. Default: `Open date picker` (dev fallback only). |
|
|
64
69
|
|
|
65
70
|
### Format Keywords (locale-aware via Intl.DateTimeFormat)
|
|
@@ -94,7 +99,6 @@ The hidden input holds the ISO date string (YYYY-MM-DD) for form submission.
|
|
|
94
99
|
| Event | Bubbles | Cancelable | Detail |
|
|
95
100
|
|-------|---------|------------|--------|
|
|
96
101
|
| `ln-date:change` | yes | no | `{ value: String (ISO), formatted: String, date: Date }` |
|
|
97
|
-
| `ln-date:destroyed` | yes | no | `{ target: Element }` |
|
|
98
102
|
|
|
99
103
|
## API
|
|
100
104
|
|
|
@@ -146,6 +150,12 @@ Locale is detected by walking up the DOM tree to find the nearest `[lang]` attri
|
|
|
146
150
|
<label for="hired">Hire Date</label>
|
|
147
151
|
<input type="date" id="hired" name="hired" value="2024-03-15" data-ln-date>
|
|
148
152
|
</div>
|
|
153
|
+
|
|
154
|
+
<!-- Semantic HTML5 time element (observable datetime SSOT, no data-ln-value needed) -->
|
|
155
|
+
<time datetime="2026-07-25" data-ln-date="medium">2026-07-25</time>
|
|
156
|
+
|
|
157
|
+
<!-- Table cell with explicit raw machine value -->
|
|
158
|
+
<td data-ln-value="2026-07-25" data-ln-date="dd.MM.yyyy">2026-07-25</td>
|
|
149
159
|
```
|
|
150
160
|
|
|
151
161
|
## Integration with ln-form
|
|
@@ -165,18 +175,18 @@ Include the main Ashlar bundle in your HTML. This bundle registers all Ashlar co
|
|
|
165
175
|
### 2. Standalone (Zero-Dependency IIFE)
|
|
166
176
|
If you only need date-formatting functionality without the rest of the Ashlar library, load the component's standalone IIFE script:
|
|
167
177
|
```html
|
|
168
|
-
<script src="
|
|
178
|
+
<script src="components/ln-date/ln-date.js" defer></script>
|
|
169
179
|
```
|
|
170
180
|
|
|
171
181
|
### 3. Source & Reference
|
|
172
|
-
* **Active Development Source**: [
|
|
173
|
-
* **Compiled Standalone Release**: [
|
|
182
|
+
* **Active Development Source**: [components/ln-date/src/ln-date.js](file:///c:/laragon/www/ln-ashlar/components/ln-date/src/ln-date.js) — The source of truth containing the ES module implementation.
|
|
183
|
+
* **Compiled Standalone Release**: [components/ln-date/ln-date.js](file:///c:/laragon/www/ln-ashlar/components/ln-date/ln-date.js) — The compiled IIFE distribution file.
|
|
174
184
|
|
|
175
185
|
---
|
|
176
186
|
|
|
177
187
|
## 🔧 Internals
|
|
178
188
|
|
|
179
|
-
Source: `
|
|
189
|
+
Source: `components/ln-date/ln-date.js`. Each `[data-ln-date]` gets a `_component` instance at `element.lnDate` (`dom` visible input, `_wrapper`, `_hidden` form input, `_picker` hidden native date input, `_btn` calendar button, `_lastISO` — the last known valid ISO value, used to revert on invalid typed input).
|
|
180
190
|
|
|
181
191
|
### Format resolution
|
|
182
192
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
@use '../../
|
|
2
|
-
|
|
3
|
-
[data-ln-debug] {
|
|
4
|
-
// 1. Date element misuse: data-ln-date belongs on <input>, <span>, <time>, or <td>
|
|
5
|
-
[data-ln-date]:not(input, span, time, td, p, div, b, strong, data) {
|
|
6
|
-
@include dev-inline-error("data-ln-date belongs on <input>, <span>, <time>, or <td>");
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// 2. Date input missing ID: input[data-ln-date] must have an id for proper labeling/association
|
|
10
|
-
input[data-ln-date]:not([id]) {
|
|
11
|
-
@include dev-inline-error("data-ln-date is missing required 'id' attribute");
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
1
|
+
@use '../../theme/config/mixins' as *;
|
|
2
|
+
|
|
3
|
+
[data-ln-debug] {
|
|
4
|
+
// 1. Date element misuse: data-ln-date belongs on <input>, <span>, <time>, or <td>
|
|
5
|
+
[data-ln-date]:not(input, span, time, td, p, div, b, strong, data) {
|
|
6
|
+
@include dev-inline-error("data-ln-date belongs on <input>, <span>, <time>, or <td>");
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// 2. Date input missing ID: input[data-ln-date] must have an id for proper labeling/association
|
|
10
|
+
input[data-ln-date]:not([id]) {
|
|
11
|
+
@include dev-inline-error("data-ln-date is missing required 'id' attribute");
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){"use strict";function q(){return typeof window>"u"?!1:window.lnDebug===!0||window.lnCore&&window.lnCore._debugSink?!0:typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug")||document.body.querySelector("[data-ln-debug]")!==null:!1}function N(t){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return t?window.lnCore._debugIsContained(t):window.lnCore._debugSink!==null;if(t&&t.closest){const e=t.closest("[data-ln-debug]");return!(!e||typeof document<"u"&&e===document.documentElement)}return typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug"):!1}if(typeof window<"u"&&(window.lnCore=window.lnCore||{},!window.lnCore._warnBound)){window.lnCore._warnBound=!0;const t=console.warn;console.warn=function(...e){if(typeof e[0]=="string"&&(e[0].startsWith("[ln-")||e[0].startsWith("[lnCore"))){let r=null;for(let o=1;o<e.length;o++)if(e[o]&&e[o].nodeType===1){r=e[o];break}if(!N(r))return}t.apply(console,e)}}function P(t,e,n){const r=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",e,t,r),t.dispatchEvent(new CustomEvent(e,{bubbles:!0,detail:r}))}function M(t,e){if(!document.body){document.addEventListener("DOMContentLoaded",function(){M(t,e)}),console.warn("["+e+'] Script loaded before <body> — add "defer" to your <script> tag');return}t()}function Z(t,e,{get:n,set:r}){Object.defineProperty(t,"value",{get:function(){return n?n.call(this):e.get.call(this)},set:function(o){r?r.call(this,o,l=>e.set.call(this,l)):e.set.call(this,o)},configurable:!0})}const j={};function tt(t,e){j[t]=e}function et(t){return j[t]||{ingress:e=>e,egress:e=>e}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=tt,window.lnCore.getDataMapper=et);function L(t){const e=t?t.closest("[lang]"):null,n=(e?e.getAttribute("lang")||e.lang:null)||(typeof document<"u"&&document.documentElement?document.documentElement.getAttribute("lang")||document.documentElement.lang:null)||(typeof navigator<"u"?navigator.language:null);return n?n.trim():"en-US"}function H(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,M(function(){new MutationObserver(function(){P(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const W={};function U(t,e){if(!t||typeof e!="object")return;const n=t.toLowerCase().split("-")[0];W[n]=e}function T(t){if(!t)return null;const e=t.toLowerCase().split("-")[0];return W[e]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=U,window.lnCore.getLocaleFallback=T,window.lnCore.ensureLocaleObserver=H);const F={};function nt(t,e){F[t]||(F[t]=document.querySelector('[data-ln-template="'+t+'"]'));const n=F[t];return n?n.content.cloneNode(!0):(console.warn("["+(e||"ln-core")+'] Template "'+t+'" not found'),null)}function K(t,e){if(!t||!e)return t;const n=t.querySelectorAll("[data-ln-field]");for(let s=0;s<n.length;s++){const u=n[s],c=u.getAttribute("data-ln-field");e[c]!=null&&(u.textContent=e[c])}const r=t.querySelectorAll("[data-ln-attr]");for(let s=0;s<r.length;s++){const u=r[s],c=u.getAttribute("data-ln-attr").split(",");for(let i=0;i<c.length;i++){const a=c[i].trim().split(":");if(a.length!==2)continue;const d=a[0].trim(),h=a[1].trim();e[h]!=null&&u.setAttribute(d,e[h])}}const o=t.querySelectorAll("[data-ln-show]");for(let s=0;s<o.length;s++){const u=o[s],c=u.getAttribute("data-ln-show");c in e&&u.classList.toggle("hidden",!e[c])}const l=t.querySelectorAll("[data-ln-class]");for(let s=0;s<l.length;s++){const u=l[s],c=u.getAttribute("data-ln-class").split(",");for(let i=0;i<c.length;i++){const a=c[i].trim().split(":");if(a.length!==2)continue;const d=a[0].trim(),h=a[1].trim();h in e&&u.classList.toggle(d,!!e[h])}}return t}function it(t,e){t.matches&&t.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",t,e??null),t.dispatchEvent(new CustomEvent("ln-fill",{detail:e??null,bubbles:!0})));const n=t.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let r=0;r<n.length;r++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[r],e??null),n[r].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)K(t.target,t.detail);else{const e=t.target.querySelectorAll("[data-ln-field]");for(let n=0;n<e.length;n++)e[n].textContent=""}})));function Y(t,e){if(!t||!e)return t;const n=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const l=n.currentNode;l.textContent.indexOf("{{")!==-1&&(l.textContent=l.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(s,u){return e[u]!==void 0?e[u]:""}))}const r=function(l,s){return e[s]!==void 0?e[s]:""},o=Array.from(t.querySelectorAll("*"));t.nodeType===1&&o.push(t);for(let l=0;l<o.length;l++){const s=o[l],u=s.attributes;for(let c=0;c<u.length;c++){const i=u[c];i.value.indexOf("{{")!==-1&&s.setAttribute(i.name,i.value.replace(/\{\{\s*(\w+)\s*\}\}/g,r))}}return t}function rt(t,e,n,r,o,l){const s={};for(let c=0;c<t.children.length;c++){const i=t.children[c],a=i.getAttribute("data-ln-render-key");a&&(s[a]=i)}const u=document.createDocumentFragment();for(let c=0;c<e.length;c++){const i=e[c],a=String(r(i));let d=s[a];if(d)o(d,i,c);else{const h=nt(n,l);if(!h||(Y(h,i),d=h.firstElementChild,!d))continue;d.setAttribute("data-ln-render-key",a),o(d,i,c)}u.appendChild(d)}t.textContent="",t.appendChild(u)}function ot(t,e){const n={},r=t.querySelectorAll("["+e+"]");for(let o=0;o<r.length;o++)n[r[o].getAttribute(e)]=r[o].textContent,r[o].remove();return n}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=Y,window.lnCore.fill=K,window.lnCore.lnFill=it,window.lnCore.renderList=rt);function Q(t,e,n,r,o){if(!t||e===null)return!0;const l=r||"ln-component",s=t.type;if(s==="trigger"||s==="marker"||s==="string"||s==="list"||!s||e===""&&t.fallback!==void 0)return!0;const u=c=>{o?console.warn(c,o):console.warn(c)};if(s==="boolean"){const c=e.trim().toLowerCase();return c!==""&&c!=="true"&&c!=="false"&&c!=="1"&&c!=="0"?(u(`[${l}] Invalid value "${e}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(s==="enum"){const c=t.values||[];return c.includes(e)?!0:(u(`[${l}] Invalid value "${e}" for attribute "${n}". Allowed: ${c.join(", ")}. Fallback: "${t.fallback}".`),!1)}if(s==="integer"){if(!/^-?\d+$/.test(e))return u(`[${l}] Invalid integer "${e}" for attribute "${n}". Fallback: ${t.fallback}.`),!1;const c=parseInt(e,10);return t.min!==void 0&&c<t.min?(u(`[${l}] Value ${c} for attribute "${n}" is less than min (${t.min}).`),!1):t.max!==void 0&&c>t.max?(u(`[${l}] Value ${c} for attribute "${n}" is greater than max (${t.max}).`),!1):!0}if(s==="float")return isNaN(Number(e))?(u(`[${l}] Invalid float "${e}" for attribute "${n}". Fallback: ${t.fallback}.`),!1):!0;if(s==="json")try{return JSON.parse(e),!0}catch(c){return u(`[${l}] Invalid JSON for attribute "${n}": ${c.message}. Fallback: ${t.fallback}.`),!1}return!0}function lt(t){const e={};for(const n in t){const r=t[n];r&&r.effect&&(e[n]=r.effect)}return Object.keys(e).length?e:null}function st(t){if(t.onAttrChange&&!t.declared)return null;const e=new Set;if(t.effects)for(const n in t.effects)e.add(n);if(t.onAttrChange&&t.declared)for(const n of t.declared)e.add(n);return e}function R(t,e,n,r){if(t.nodeType!==1)return;const l=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1?e:"["+e+"]",s=Array.from(t.querySelectorAll(l));t.matches&&t.matches(l)&&s.push(t);for(const u of s)if(!u[n]){window.lnCore._persistSink&&u.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(u,e);try{u[n]=new r(u)}catch(c){console.error("["+n+"] init failed",u,c)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function at(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function ct(t){typeof window<"u"?(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[],window.lnCore._bootHolds>0?window.lnCore._bootQueue.push(t):setTimeout(t,0)):t()}function G(){window.lnCore=window.lnCore||{};const t=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return t.byReactive=t.byReactive||new Map,t.reactiveWildcard=t.reactiveWildcard||[],t}function ut(t){const e=G(),n=t.observed||[];for(let r=0;r<n.length;r++){const o=n[r];e.byAttr.has(o)||e.byAttr.set(o,[]),e.byAttr.get(o).push(t)}if(e.byDeclaredAttr=e.byDeclaredAttr||new Map,t.attributes)for(const r in t.attributes){e.byDeclaredAttr.has(r)||e.byDeclaredAttr.set(r,[]);const o=e.byDeclaredAttr.get(r);o.some(l=>l.componentTag===t.componentTag)||o.push({spec:t.attributes[r],componentTag:t.componentTag})}if(t.onAttrChange||t.effects){e.reactive.push(t);const r=st(t);if(r===null)e.reactiveWildcard.push(t);else for(const o of r)e.byReactive.has(o)||e.byReactive.set(o,[]),e.byReactive.get(o).push(t)}t.persist&&e.persist.push(t)}function J(t,e,n,r){for(let o=0;o<t.length;o++){const l=t[o];if(!e[l.attribute])continue;const s=l.effects&&l.effects[n];s?s(e,n,r):l.onAttrChange&&(!l.declared||l.declared.has(n))&&l.onAttrChange(e,n,r)}}function dt(t){const e=t.target,n=t.attributeName;if(t.oldValue===e.getAttribute(n))return;const r=G(),o=r.byAttr.get(n);if(q()&&r.byDeclaredAttr&&r.byDeclaredAttr.has(n)&&N(e)){const l=r.byDeclaredAttr.get(n),s=e.getAttribute(n);for(let u=0;u<l.length;u++)Q(l[u].spec,s,n,l[u].componentTag,e)}if(window.lnCore._debugSink&&(n.indexOf("data-ln-")===0||o)&&window.lnCore._debugSink("attr",n,e,{oldValue:t.oldValue,newValue:e.getAttribute(n)}),n.indexOf("data-ln-")===0){const l=r.byReactive.get(n);l&&J(l,e,n,t.oldValue),r.reactiveWildcard.length&&J(r.reactiveWildcard,e,n,t.oldValue)}if(o)for(let l=0;l<o.length;l++){const s=o[l];if(s.handler){s.handler(e,n,t.oldValue);continue}s.onAttributeChange&&e[s.attribute]?s.onAttributeChange(e,n):(R(e,s.selector,s.attribute,s.ComponentFn),s.onInit&&s.onInit(e))}}function ft(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,M(function(){new MutationObserver(function(e){for(let n=0;n<e.length;n++)try{dt(e[n])}catch(r){console.error("[ln-core] mutation handler failed",e[n].target,r)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function X(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function ht(t){const e=X();if(e.length){if(t.target)for(let n=0;n<e.length;n++){const r=e[n];if(r.onSubtreeChange){const o=r.query,l=t.target.nodeType===1?t.target.matches(o)?t.target:t.target.closest(o):t.target.parentElement?t.target.parentElement.closest(o):null;l&&r.onSubtreeChange(l,t)}}for(let n=0;n<t.addedNodes.length;n++){const r=t.addedNodes[n];if(r.nodeType===1)for(let o=0;o<e.length;o++){const l=e[o];R(r,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(r)}}for(let n=0;n<t.removedNodes.length;n++){const r=t.removedNodes[n];if(r.nodeType===1)for(let o=0;o<e.length;o++){const l=e[o],s=l.query,u=Array.from(r.querySelectorAll(s));r.matches&&r.matches(s)&&u.push(r);for(let c=0;c<u.length;c++){const i=u[c];if(!document.contains(i)){const a=i[l.attribute];if(a&&typeof a.destroy=="function")try{a.destroy()}catch(d){console.error("["+l.attribute+"] destroy failed",i,d)}delete i[l.attribute]}}}}}}function mt(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,M(function(){new MutationObserver(function(e){for(let n=0;n<e.length;n++){const r=e[n];if(r.type==="childList")try{ht(r)}catch(o){console.error("[ln-core] lifecycle handler failed",r.target,o)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function gt(t,e,n,r,o={}){const l=o.extraAttributes||[],s=o.onAttributeChange||null,u=o.onSubtreeChange||null,c=o.onInit||null,i=o.onAttrChange||null,a=o.effects||null,d=o.attributes||null,h=d?lt(d):a,b=d?new Set(Object.keys(d)):null,p=o.persist||null;function w(m){const g=m||document.body;if(R(g,t,e,n),d&&q())for(const y in d){const A=d[y],v=Array.from(g.querySelectorAll("["+y+"]"));g.matches&&g.matches("["+y+"]")&&v.push(g);for(let D=0;D<v.length;D++){const k=v[D];N(k)&&Q(A,k.getAttribute(y),y,r,k)}}c&&c(g)}const C=[];if(t.indexOf("[")!==-1){const m=/\[([\w-]+)/g;let g;for(;(g=m.exec(t))!==null;)C.push(g[1])}else C.push(t);ut({selector:t,attribute:e,componentTag:r,attributes:d,ComponentFn:n,onInit:c,observed:C.concat(l),onAttributeChange:s,onAttrChange:i,effects:h,declared:b,persist:p}),ft();const O=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]";X().push({selector:t,attribute:e,ComponentFn:n,onInit:c,onSubtreeChange:u,query:O}),mt(),window[e]=w;function f(){at()>0?ct(function(){w(document.body)}):w(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",f):f(),w}function z(t){return(t||"").replace(/^#/,"")}function $(t){const e=t===void 0?location.hash:t,n={},r=z(e);if(!r)return n;const o=r.split("&");for(let l=0;l<o.length;l++){const s=o[l];if(!s)continue;const u=s.indexOf(":"),c=u>-1?s.slice(0,u):s,i=u>-1?s.slice(u+1):"";if(c)try{n[c]=decodeURIComponent(i)}catch{n[c]=i}}return n}function pt(t){if(!t)return null;const e=$();return t in e?e[t]:null}function wt(t,e){if(!t)return;const n=$();e==null?delete n[t]:n[t]=String(e);const o=Object.keys(n).map(function(l){const s=n[l];return s===""?l:l+":"+encodeURIComponent(s)}).join("&");z(location.hash)!==o&&(location.hash=o)}function bt(t){return t.button===1||t.ctrlKey||t.metaKey||t.shiftKey?!1:(t.preventDefault(),!0)}function yt(t,e){if(!t||!t.hasAttribute("data-ln-hash"))return null;const n=t.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const r=t.getAttribute("data-ln-sort")||t.getAttribute("data-ln-search-for")||t.getAttribute("data-ln-search")||t.getAttribute("data-ln-filter")||t.id;return r?e?r+"-"+e:r:e||null}function Ct(t,e){return!e||e==="none"||t===null||t===void 0?null:String(t)+"."+e}function _t(t){return!t||typeof t!="string"?null:t.endsWith(".asc")?{fieldOrColumn:t.slice(0,-4),direction:"asc"}:t.endsWith(".desc")?{fieldOrColumn:t.slice(0,-5),direction:"desc"}:null}function At(t,e){return!t||!Array.isArray(e)||e.length===0?null:t+":"+e.map(encodeURIComponent).join(",")}function vt(t){if(!t||typeof t!="string")return null;const e=t.indexOf(":");if(e===-1)return null;const n=t.slice(0,e),r=t.slice(e+1),o=r?r.split(",").map(function(l){try{return decodeURIComponent(l)}catch{return l}}).filter(Boolean):[];return{key:n,values:o}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=$,window.lnCore.hashGet=pt,window.lnCore.hashSet=wt,window.lnCore.hashLinkClick=bt,window.lnCore.resolveHashNamespace=yt,window.lnCore.hashSortEncode=Ct,window.lnCore.hashSortDecode=_t,window.lnCore.hashFilterEncode=At,window.lnCore.hashFilterDecode=vt);function _(t){if(t==null||t==="")return null;if(t instanceof Date)return isNaN(t.getTime())?null:t;const e=Number(t);if(!isNaN(e)&&e>0){const n=e<1e11?e*1e3:e,r=new Date(n);return isNaN(r.getTime())?null:r}if(typeof t=="string"){const n=t.trim();if(!n)return null;const r=/^(\d{4})-(\d{2})-(\d{2})$/.exec(n);if(r){const l=+r[1],s=+r[2],u=+r[3],c=new Date(l,s-1,u);return c.getFullYear()!==l||c.getMonth()!==s-1||c.getDate()!==u?null:c}const o=new Date(n);return isNaN(o.getTime())?null:o}return null}function E(t){if(!t||!(t instanceof Date)||isNaN(t.getTime()))return"";const e=t.getFullYear(),n=String(t.getMonth()+1).padStart(2,"0"),r=String(t.getDate()).padStart(2,"0");return e+"-"+n+"-"+r}const B=/^(short|medium|long)(\s+datetime)?$/,St={short:{dateStyle:"short"},medium:{dateStyle:"medium"},long:{dateStyle:"long"},"short datetime":{dateStyle:"short",timeStyle:"short"},"medium datetime":{dateStyle:"medium",timeStyle:"short"},"long datetime":{dateStyle:"long",timeStyle:"short"}};function Et(t){return!t||t===""?{dateStyle:"medium"}:String(t).trim().match(B)?St[t.trim()]:null}function x(t){if(!t||typeof t!="string")return null;const e=t.trim();if(e.length<6)return null;let n,r;if(e.indexOf(".")!==-1)n=".",r=e.split(".");else if(e.indexOf("/")!==-1)n="/",r=e.split("/");else if(e.indexOf("-")!==-1)n="-",r=e.split("-");else return null;if(r.length!==3)return null;const o=[];for(let i=0;i<3;i++){const a=parseInt(r[i],10);if(isNaN(a))return null;o.push(a)}let l,s,u;n==="."?(l=o[0],s=o[1],u=o[2]):n==="/"?(s=o[0],l=o[1],u=o[2]):r[0].length===4?(u=o[0],s=o[1],l=o[2]):(l=o[0],s=o[1],u=o[2]),u<100&&(u+=u<50?2e3:1900);const c=new Date(u,s-1,l);return c.getFullYear()!==u||c.getMonth()!==s-1||c.getDate()!==l?null:c}function V(t,e,n,r){if(!t||!(t instanceof Date)||isNaN(t.getTime())||!e||typeof e!="string")return"";const o=t.getDate(),l=t.getMonth(),s=t.getFullYear(),u=t.getHours(),c=t.getMinutes();let i,a;const d=(n||"").toLowerCase().split("-")[0];let h=!1;try{const w=new Intl.DateTimeFormat(n,{month:"long"}).resolvedOptions().locale.toLowerCase().split("-")[0];h=!!(r&&w!==d)}catch{h=!!r}if(h&&r&&r.monthsLong)i=r.monthsLong[l];else try{i=new Intl.DateTimeFormat(n,{month:"long"}).format(t)}catch{i=String(l+1)}if(h&&r&&r.monthsShort)a=r.monthsShort[l];else try{a=new Intl.DateTimeFormat(n,{month:"short"}).format(t)}catch{a=String(l+1)}const b={yyyy:String(s),yy:String(s).slice(-2),MMMM:i,MMM:a,MM:String(l+1).padStart(2,"0"),M:String(l+1),dd:String(o).padStart(2,"0"),d:String(o),HH:String(u).padStart(2,"0"),mm:String(c).padStart(2,"0")};return e.replace(/yyyy|yy|MMMM|MMM|MM|M|dd|d|HH|mm/g,function(p){return b[p]!==void 0?b[p]:p})}function I(t,e,n,r){if(!t||!(t instanceof Date)||isNaN(t.getTime()))return"";const o=Et(e);if(o)try{const l=new Intl.DateTimeFormat(n,o),s=(n||"").toLowerCase().split("-")[0],u=l.resolvedOptions().locale.toLowerCase().split("-")[0];return r&&u!==s?V(t,"dd.MM.yyyy",n,r):l.format(t)}catch{return V(t,"dd.MM.yyyy",n,r)}return V(t,e||"dd.MM.yyyy",n,r)}(function(){const t="data-ln-date",e="lnDate";if(window[e]!==void 0)return;function n(i){const a=i[e];if(a){if(a.isTextElement)a._initTextElement();else if(a.value){const d=_(a.value);d&&a._displayFormatted(d)}}}const r={"data-ln-date":{type:"enum",values:["short","medium","long","full","iso"],fallback:"medium",effect:n,description:"Date display style preset or activator"},"data-ln-date-format":{type:"string",effect:n,description:"Custom Intl.DateTimeFormat pattern or options"},"data-ln-date-locale":{type:"string",effect:n,description:"BCP 47 language tag override for date formatting"},"data-ln-value":{type:"string",effect:n,description:"Raw ISO date string or timestamp for non-time elements (td, span)"},"data-ln-date-dict":{type:"marker",description:"Container for date translation dictionary"},"data-ln-date-dict-key":{type:"string",description:"Dictionary key for relative time or custom date formatting"},"data-ln-date-field":{type:"string",description:"Field name mapping for date record binding"},"data-ln-date-label":{type:"string",description:"Accessible label text for the date input"}},o=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"value");function l(i,a,d){P(i.dom,"ln-date:change",{value:a,formatted:i.dom.value,date:d}),i.dom.dispatchEvent(new Event("change",{bubbles:!0}))}function s(i,a,d,h){i._setHiddenRaw(a),o.set.call(i._picker,a),i._lastISO=a,h!==void 0?(i._isFormatting=!0,i.dom.value=h,i._isFormatting=!1):d&&i._displayFormatted(d),l(i,a,d)}function u(i){i._setHiddenRaw(""),o.set.call(i._picker,""),i._isFormatting=!0,i.dom.value="",i._isFormatting=!1,i._lastISO="",l(i,"",null)}function c(i){if(i[e])return i[e];i[e]=this,this.dom=i;const a=this;if(this._onLocaleChange=function(){if(a.isTextElement)a._formatTextContent();else if(a.value){const f=_(a.value);f&&a._displayFormatted(f)}},H(),document.addEventListener("ln-core:locale-change",this._onLocaleChange),i.tagName!=="INPUT")return this.isTextElement=!0,this._initTextElement(),this;this.isTextElement=!1;const d=i.value,h=i.name,b=i.closest(".form-element, form")||i.parentNode;if(b){const f=b.querySelectorAll("[data-ln-date-dict]");for(let m=0;m<f.length;m++){const g=f[m].getAttribute("data-ln-date-dict");if(g){const y=ot(f[m],"data-ln-date-dict-key");y["months-long"]&&(y.monthsLong=y["months-long"].split(",").map(A=>A.trim())),y["months-short"]&&(y.monthsShort=y["months-short"].split(",").map(A=>A.trim())),U(g,y)}}}const p=document.createElement("span");p.setAttribute("data-ln-date-field",""),i.parentNode.insertBefore(p,i),p.appendChild(i),this._wrapper=p;const w=document.createElement("input");w.type="hidden",w.name=h,i.removeAttribute("name"),i.hasAttribute("data-ln-fill-as")&&w.setAttribute("data-ln-fill-as",i.getAttribute("data-ln-fill-as")),i.insertAdjacentElement("afterend",w),this._hidden=w;const C=document.createElement("input");C.type="date",C.tabIndex=-1,C.setAttribute("tabindex","-1"),C.setAttribute("aria-hidden","true"),C.setAttribute("aria-label",i.getAttribute("data-ln-date-label")||"Date picker"),C.style.cssText="position:absolute;opacity:0;width:0;height:0;overflow:hidden;pointer-events:none",w.insertAdjacentElement("afterend",C),this._picker=C,i.type="text";const S=document.createElement("button");S.type="button",S.setAttribute("aria-label",i.getAttribute("data-ln-date-label")||"Open date picker"),S.innerHTML='<svg class="ln-icon" aria-hidden="true"><use href="#ln-icon-calendar"></use></svg>',C.insertAdjacentElement("afterend",S),this._btn=S,this._lastISO="",Object.defineProperty(w,"value",{get:function(){return o.get.call(w)},set:function(f){if(o.set.call(w,f),f&&f!==""){const m=_(f);m&&s(a,f,m)}else f===""&&u(a)}}),Z(i,o,{get:function(){return o.get.call(i)},set:function(f,m){if(a._isFormatting){m(f);return}if(!f||f===""){m(""),u(a);return}const g=_(f)||x(f);if(g){const y=E(g),A=i.getAttribute(t)||"",v=L(i),D=T(v),k=I(g,A,v,D);m(k),s(a,y,g,k)}else m(String(f)),u(a)}}),this._onPickerChange=function(){const f=C.value;if(f){const m=_(f);m&&s(a,f,m)}else u(a)},C.addEventListener("change",this._onPickerChange),this._onBlur=function(){const f=a.dom.value.trim();if(f===""){a._lastISO!==""&&u(a);return}if(a._lastISO){const g=_(a._lastISO);if(g){const y=a.dom.getAttribute(t)||"",A=L(a.dom),v=T(A);if(f===I(g,y,A,v))return}}const m=x(f);if(m){const g=E(m);s(a,g,m)}else if(a._lastISO){const g=_(a._lastISO);g&&a._displayFormatted(g)}else a.dom.value=""},i.addEventListener("blur",this._onBlur),this._onBtnClick=function(){a._openPicker()},S.addEventListener("click",this._onBtnClick);const O=i.form;if(O&&(this._form=O,this._onFormReset=function(){setTimeout(function(){const f=a.dom.value;if(f){const m=_(f)||x(f);if(m){const g=E(m);s(a,g,m);return}}u(a)},0)},O.addEventListener("reset",this._onFormReset)),d&&d!==""){const f=_(d);f&&s(a,d,f)}return this}c.prototype._initTextElement=function(){const i=this.dom,a=i.getAttribute("data-ln-value"),d=i.getAttribute("data-ln-date"),h=i.getAttribute("datetime");let b=null;i.tagName==="TIME"&&h!==null&&h!==""?b=h:a!==null&&a!==""?b=a:h!==null&&h!==""?b=h:d!==null&&d!==""&&d!=="true"&&!B.test(d)?b=d:b=i.textContent.trim();const p=_(b)||x(b);if(p&&!isNaN(p.getTime())){const w=E(p);this._rawValue=w,i.tagName!=="TIME"&&!i.hasAttribute("data-ln-value")&&i.setAttribute("data-ln-value",w),this._formatTextContent()}else this._rawValue=null},c.prototype._formatTextContent=function(){if(this._rawValue){const i=_(this._rawValue);if(i){let d=this.dom.getAttribute("data-ln-date-format");if(!d){const p=this.dom.getAttribute("data-ln-date");p&&B.test(p)&&(d=p)}const h=L(this.dom),b=T(h);this.dom.textContent=I(i,d||"medium",h,b)}}},c.prototype._openPicker=function(){if(typeof this._picker.showPicker=="function")try{this._picker.showPicker()}catch{this._picker.click()}else this._picker.click()},c.prototype._setHiddenRaw=function(i){o.set.call(this._hidden,i)},c.prototype._displayFormatted=function(i){const a=this.dom.getAttribute(t)||"",d=L(this.dom),h=T(d);this._isFormatting=!0,this.dom.value=I(i,a,d,h),this._isFormatting=!1},Object.defineProperty(c.prototype,"value",{get:function(){return this.isTextElement?this._rawValue||"":o.get.call(this._hidden)},set:function(i){if(this.isTextElement){if(!i||i===""){this._rawValue=null,this.dom.removeAttribute("data-ln-value"),this.dom.tagName==="TIME"&&this.dom.removeAttribute("datetime"),this.dom.textContent="";return}const d=_(i)||x(i);if(!d)return;const h=E(d);this._rawValue=h,this.dom.tagName==="TIME"?this.dom.setAttribute("datetime",h):this.dom.setAttribute("data-ln-value",h),this._formatTextContent();return}if(!i||i===""){u(this);return}const a=_(i);a&&s(this,i,a)}}),Object.defineProperty(c.prototype,"date",{get:function(){const i=this.value;return i?_(i):null},set:function(i){if(!i||!(i instanceof Date)||isNaN(i.getTime())){this.value="";return}this.value=E(i)}}),Object.defineProperty(c.prototype,"formatted",{get:function(){return this.isTextElement?this.dom.textContent:this.dom.value}}),c.prototype.destroy=function(){if(!this.dom[e])return;if(this.isTextElement){delete this.dom[e];return}this._form&&this._onFormReset&&this._form.removeEventListener("reset",this._onFormReset),this._picker.removeEventListener("change",this._onPickerChange),this.dom.removeEventListener("blur",this._onBlur),this._btn.removeEventListener("click",this._onBtnClick);const i=this.value;this._hidden.remove(),this._picker.remove(),this._btn.remove(),this._wrapper&&this._wrapper.parentNode&&(this._wrapper.parentNode.insertBefore(this.dom,this._wrapper),this._wrapper.remove()),delete this.dom.value,this.dom.name=this._hidden.name,this.dom.type="date",i&&(this.dom.value=i),this._onLocaleChange&&document.removeEventListener("ln-core:locale-change",this._onLocaleChange),delete this.dom[e]},gt(t,e,c,"ln-date",{attributes:r,extraAttributes:["datetime","lang"],onAttributeChange:n})})()})();
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "This file is partly generated. The $comment, component, generator, and each attribute's direction, sources, type, values, fallback, and description keys are owned by the generator and synchronized from JS source code. All other keys are preserved and safe to hand-author. Regenerate with `npm run sync:ln-schemas`.",
|
|
3
|
+
"component": "ln-date",
|
|
4
|
+
"generator": "scripts/sync-ln-schemas.mjs",
|
|
5
|
+
"attributes": {
|
|
6
|
+
"data-ln-date": {
|
|
7
|
+
"direction": "author",
|
|
8
|
+
"sources": [
|
|
9
|
+
"ln-date-dev.scss",
|
|
10
|
+
"src/ln-date.js"
|
|
11
|
+
],
|
|
12
|
+
"type": "enum",
|
|
13
|
+
"values": [
|
|
14
|
+
"short",
|
|
15
|
+
"medium",
|
|
16
|
+
"long",
|
|
17
|
+
"full",
|
|
18
|
+
"iso"
|
|
19
|
+
],
|
|
20
|
+
"fallback": "medium",
|
|
21
|
+
"description": "Date display style preset or activator"
|
|
22
|
+
},
|
|
23
|
+
"data-ln-date-dict": {
|
|
24
|
+
"direction": "author",
|
|
25
|
+
"sources": [
|
|
26
|
+
"src/ln-date.js"
|
|
27
|
+
],
|
|
28
|
+
"type": "marker",
|
|
29
|
+
"description": "Container for date translation dictionary"
|
|
30
|
+
},
|
|
31
|
+
"data-ln-date-dict-key": {
|
|
32
|
+
"direction": null,
|
|
33
|
+
"sources": [
|
|
34
|
+
"src/ln-date.js"
|
|
35
|
+
],
|
|
36
|
+
"type": "string",
|
|
37
|
+
"description": "Dictionary key for relative time or custom date formatting"
|
|
38
|
+
},
|
|
39
|
+
"data-ln-date-field": {
|
|
40
|
+
"direction": "runtime",
|
|
41
|
+
"sources": [
|
|
42
|
+
"src/ln-date.js"
|
|
43
|
+
],
|
|
44
|
+
"type": "string",
|
|
45
|
+
"description": "Field name mapping for date record binding"
|
|
46
|
+
},
|
|
47
|
+
"data-ln-date-format": {
|
|
48
|
+
"direction": "author",
|
|
49
|
+
"sources": [
|
|
50
|
+
"src/ln-date.js"
|
|
51
|
+
],
|
|
52
|
+
"type": "string",
|
|
53
|
+
"description": "Custom Intl.DateTimeFormat pattern or options"
|
|
54
|
+
},
|
|
55
|
+
"data-ln-date-label": {
|
|
56
|
+
"direction": "both",
|
|
57
|
+
"sources": [
|
|
58
|
+
"src/ln-date.js"
|
|
59
|
+
],
|
|
60
|
+
"type": "string",
|
|
61
|
+
"description": "Accessible label text for the date input"
|
|
62
|
+
},
|
|
63
|
+
"data-ln-date-locale": {
|
|
64
|
+
"direction": null,
|
|
65
|
+
"sources": [
|
|
66
|
+
"src/ln-date.js"
|
|
67
|
+
],
|
|
68
|
+
"type": "string",
|
|
69
|
+
"description": "BCP 47 language tag override for date formatting"
|
|
70
|
+
},
|
|
71
|
+
"data-ln-debug": {
|
|
72
|
+
"direction": null,
|
|
73
|
+
"sources": [
|
|
74
|
+
"ln-date-dev.scss"
|
|
75
|
+
]
|
|
76
|
+
},
|
|
77
|
+
"data-ln-fill-as": {
|
|
78
|
+
"direction": "both",
|
|
79
|
+
"sources": [
|
|
80
|
+
"src/ln-date.js"
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
"data-ln-value": {
|
|
84
|
+
"direction": "both",
|
|
85
|
+
"sources": [
|
|
86
|
+
"src/ln-date.js"
|
|
87
|
+
],
|
|
88
|
+
"type": "string",
|
|
89
|
+
"description": "Raw ISO date string or timestamp for non-time elements (td, span)"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
export const KEYWORD_RE = /^(short|medium|long)(\s+datetime)?$/;
|
|
2
|
+
|
|
3
|
+
export const KEYWORD_OPTIONS = {
|
|
4
|
+
'short': { dateStyle: 'short' },
|
|
5
|
+
'medium': { dateStyle: 'medium' },
|
|
6
|
+
'long': { dateStyle: 'long' },
|
|
7
|
+
'short datetime': { dateStyle: 'short', timeStyle: 'short' },
|
|
8
|
+
'medium datetime': { dateStyle: 'medium', timeStyle: 'short' },
|
|
9
|
+
'long datetime': { dateStyle: 'long', timeStyle: 'short' }
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Returns Intl.DateTimeFormat options if format is a recognized keyword, or null for custom patterns.
|
|
14
|
+
* @param {string} format
|
|
15
|
+
* @returns {Intl.DateTimeFormatOptions|null}
|
|
16
|
+
*/
|
|
17
|
+
export function getIntlDateOptions(format) {
|
|
18
|
+
if (!format || format === '') return { dateStyle: 'medium' };
|
|
19
|
+
const match = String(format).trim().match(KEYWORD_RE);
|
|
20
|
+
if (match) {
|
|
21
|
+
return KEYWORD_OPTIONS[format.trim()];
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Parses user typed date strings (e.g. DD.MM.YYYY, MM/DD/YYYY, YYYY-MM-DD) into a valid Date object.
|
|
28
|
+
* @param {string} str
|
|
29
|
+
* @returns {Date|null}
|
|
30
|
+
*/
|
|
31
|
+
export function parseTypedDate(str) {
|
|
32
|
+
if (!str || typeof str !== 'string') return null;
|
|
33
|
+
const trimmed = str.trim();
|
|
34
|
+
if (trimmed.length < 6) return null;
|
|
35
|
+
|
|
36
|
+
let sep, parts;
|
|
37
|
+
if (trimmed.indexOf('.') !== -1) {
|
|
38
|
+
sep = '.';
|
|
39
|
+
parts = trimmed.split('.');
|
|
40
|
+
} else if (trimmed.indexOf('/') !== -1) {
|
|
41
|
+
sep = '/';
|
|
42
|
+
parts = trimmed.split('/');
|
|
43
|
+
} else if (trimmed.indexOf('-') !== -1) {
|
|
44
|
+
sep = '-';
|
|
45
|
+
parts = trimmed.split('-');
|
|
46
|
+
} else {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (parts.length !== 3) return null;
|
|
51
|
+
const nums = [];
|
|
52
|
+
for (let i = 0; i < 3; i++) {
|
|
53
|
+
const n = parseInt(parts[i], 10);
|
|
54
|
+
if (isNaN(n)) return null;
|
|
55
|
+
nums.push(n);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let day, month, year;
|
|
59
|
+
if (sep === '.') {
|
|
60
|
+
day = nums[0];
|
|
61
|
+
month = nums[1];
|
|
62
|
+
year = nums[2];
|
|
63
|
+
} else if (sep === '/') {
|
|
64
|
+
month = nums[0];
|
|
65
|
+
day = nums[1];
|
|
66
|
+
year = nums[2];
|
|
67
|
+
} else {
|
|
68
|
+
if (parts[0].length === 4) {
|
|
69
|
+
year = nums[0];
|
|
70
|
+
month = nums[1];
|
|
71
|
+
day = nums[2];
|
|
72
|
+
} else {
|
|
73
|
+
day = nums[0];
|
|
74
|
+
month = nums[1];
|
|
75
|
+
year = nums[2];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (year < 100) {
|
|
80
|
+
year += (year < 50) ? 2000 : 1900;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const date = new Date(year, month - 1, day);
|
|
84
|
+
if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
return date;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Formats a Date object using a custom pattern with token replacements.
|
|
92
|
+
* @param {Date} date
|
|
93
|
+
* @param {string} pattern Pattern with tokens (yyyy, yy, MMMM, MMM, MM, M, dd, d, HH, mm)
|
|
94
|
+
* @param {string} [locale]
|
|
95
|
+
* @param {object} [fallback] Custom locale fallback dictionary
|
|
96
|
+
* @returns {string}
|
|
97
|
+
*/
|
|
98
|
+
export function formatCustomDate(date, pattern, locale, fallback) {
|
|
99
|
+
if (!date || !(date instanceof Date) || isNaN(date.getTime())) return '';
|
|
100
|
+
if (!pattern || typeof pattern !== 'string') return '';
|
|
101
|
+
|
|
102
|
+
const day = date.getDate();
|
|
103
|
+
const month = date.getMonth();
|
|
104
|
+
const year = date.getFullYear();
|
|
105
|
+
const hours = date.getHours();
|
|
106
|
+
const minutes = date.getMinutes();
|
|
107
|
+
|
|
108
|
+
let mmmmVal, mmmVal;
|
|
109
|
+
const langPrefix = (locale || '').toLowerCase().split('-')[0];
|
|
110
|
+
|
|
111
|
+
let isFallbackNeeded = false;
|
|
112
|
+
try {
|
|
113
|
+
const fmt = new Intl.DateTimeFormat(locale, { month: 'long' });
|
|
114
|
+
const resolvedLocale = fmt.resolvedOptions().locale.toLowerCase().split('-')[0];
|
|
115
|
+
isFallbackNeeded = Boolean(fallback && resolvedLocale !== langPrefix);
|
|
116
|
+
} catch (e) {
|
|
117
|
+
isFallbackNeeded = Boolean(fallback);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (isFallbackNeeded && fallback && fallback.monthsLong) {
|
|
121
|
+
mmmmVal = fallback.monthsLong[month];
|
|
122
|
+
} else {
|
|
123
|
+
try {
|
|
124
|
+
mmmmVal = new Intl.DateTimeFormat(locale, { month: 'long' }).format(date);
|
|
125
|
+
} catch (e) {
|
|
126
|
+
mmmmVal = String(month + 1);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (isFallbackNeeded && fallback && fallback.monthsShort) {
|
|
131
|
+
mmmVal = fallback.monthsShort[month];
|
|
132
|
+
} else {
|
|
133
|
+
try {
|
|
134
|
+
mmmVal = new Intl.DateTimeFormat(locale, { month: 'short' }).format(date);
|
|
135
|
+
} catch (e) {
|
|
136
|
+
mmmVal = String(month + 1);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const tokens = {
|
|
141
|
+
'yyyy': String(year),
|
|
142
|
+
'yy': String(year).slice(-2),
|
|
143
|
+
'MMMM': mmmmVal,
|
|
144
|
+
'MMM': mmmVal,
|
|
145
|
+
'MM': String(month + 1).padStart(2, '0'),
|
|
146
|
+
'M': String(month + 1),
|
|
147
|
+
'dd': String(day).padStart(2, '0'),
|
|
148
|
+
'd': String(day),
|
|
149
|
+
'HH': String(hours).padStart(2, '0'),
|
|
150
|
+
'mm': String(minutes).padStart(2, '0')
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
return pattern.replace(/yyyy|yy|MMMM|MMM|MM|M|dd|d|HH|mm/g, function (m) {
|
|
154
|
+
return tokens[m] !== undefined ? tokens[m] : m;
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Formats a date value using either standard Intl options or a custom pattern.
|
|
160
|
+
* @param {Date} date
|
|
161
|
+
* @param {string} [format='medium']
|
|
162
|
+
* @param {string} [locale]
|
|
163
|
+
* @param {object} [fallback]
|
|
164
|
+
* @returns {string}
|
|
165
|
+
*/
|
|
166
|
+
export function formatDateValue(date, format, locale, fallback) {
|
|
167
|
+
if (!date || !(date instanceof Date) || isNaN(date.getTime())) return '';
|
|
168
|
+
|
|
169
|
+
const intlOptions = getIntlDateOptions(format);
|
|
170
|
+
if (intlOptions) {
|
|
171
|
+
try {
|
|
172
|
+
const formatter = new Intl.DateTimeFormat(locale, intlOptions);
|
|
173
|
+
const langPrefix = (locale || '').toLowerCase().split('-')[0];
|
|
174
|
+
const resolvedLocale = formatter.resolvedOptions().locale.toLowerCase().split('-')[0];
|
|
175
|
+
|
|
176
|
+
if (fallback && resolvedLocale !== langPrefix) {
|
|
177
|
+
return formatCustomDate(date, 'dd.MM.yyyy', locale, fallback);
|
|
178
|
+
}
|
|
179
|
+
return formatter.format(date);
|
|
180
|
+
} catch (e) {
|
|
181
|
+
return formatCustomDate(date, 'dd.MM.yyyy', locale, fallback);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return formatCustomDate(date, format || 'dd.MM.yyyy', locale, fallback);
|
|
186
|
+
}
|