@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.
- package/LICENSE +641 -0
- package/README.md +190 -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/{js → components}/ln-confirm/README.md +69 -18
- 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 -171
- 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/_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
|
@@ -1,12 +1,27 @@
|
|
|
1
|
-
import { registerComponent, dispatch, buildUrl, getHeaders, parseHeaders } from '../../ln-core';
|
|
1
|
+
import { registerComponent, dispatch, buildUrl, getHeaders, parseHeaders, defineAttrs, attrSpec, attrStr } from '../../ln-core';
|
|
2
2
|
|
|
3
3
|
(function () {
|
|
4
4
|
const DOM_SELECTOR = 'data-ln-couchdb-connector';
|
|
5
5
|
const DOM_ATTRIBUTE = 'lnCouchDbConnector';
|
|
6
6
|
const DOM_ALIAS = 'lnConnector';
|
|
7
|
-
|
|
8
7
|
if (window[DOM_ATTRIBUTE] !== undefined) return;
|
|
9
8
|
|
|
9
|
+
// ─── Attribute Contract (SSOT) ──────────────────────────
|
|
10
|
+
function _syncAttribute(el) {
|
|
11
|
+
const instance = el[DOM_ATTRIBUTE];
|
|
12
|
+
if (!instance) return;
|
|
13
|
+
instance.refreshConfig();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const ATTRIBUTES = {
|
|
17
|
+
'data-ln-couchdb-connector': { type: 'marker', description: 'Mounts CouchDB/PouchDB connector bridging database and ln-ashlar data coordinators' },
|
|
18
|
+
'data-ln-couchdb-url': { prop: 'url', read: attrStr, type: 'string', fallback: '', effect: _syncAttribute, description: 'CouchDB server base endpoint URL' },
|
|
19
|
+
'data-ln-couchdb-db': { prop: 'db', read: attrStr, type: 'string', fallback: '', effect: _syncAttribute, description: 'Target CouchDB database name' },
|
|
20
|
+
'data-ln-couchdb-auth': { prop: 'auth', read: attrStr, type: 'string', fallback: '', effect: _syncAttribute, description: 'Authentication credentials for CouchDB requests' },
|
|
21
|
+
'data-ln-couchdb-headers': { effect: _syncAttribute, type: 'json', fallback: null, description: 'Custom HTTP headers in JSON or semicolon-separated format' }
|
|
22
|
+
};
|
|
23
|
+
const ATTR_SPEC = attrSpec(ATTRIBUTES);
|
|
24
|
+
|
|
10
25
|
// ─── Response Envelope Unwrap (presence-checked `{message, content}`) ──
|
|
11
26
|
// Raw CouchDB never sends this envelope (content=body, message=null — no-op).
|
|
12
27
|
// A proxy/gateway in front of CouchDB may wrap responses; this makes that
|
|
@@ -21,6 +36,7 @@ import { registerComponent, dispatch, buildUrl, getHeaders, parseHeaders } from
|
|
|
21
36
|
|
|
22
37
|
function _component(dom) {
|
|
23
38
|
this.dom = dom;
|
|
39
|
+
defineAttrs(this, dom, ATTR_SPEC);
|
|
24
40
|
dom[DOM_ATTRIBUTE] = this;
|
|
25
41
|
dom[DOM_ALIAS] = this; // Alias for 3-tier compatibility
|
|
26
42
|
|
|
@@ -36,9 +52,6 @@ import { registerComponent, dispatch, buildUrl, getHeaders, parseHeaders } from
|
|
|
36
52
|
_component.prototype.refreshConfig = function () {
|
|
37
53
|
const dom = this.dom;
|
|
38
54
|
|
|
39
|
-
this.url = dom.getAttribute('data-ln-couchdb-url') || '';
|
|
40
|
-
this.db = dom.getAttribute('data-ln-couchdb-db') || '';
|
|
41
|
-
this.auth = dom.getAttribute('data-ln-couchdb-auth') || '';
|
|
42
55
|
this.credentials = 'same-origin';
|
|
43
56
|
|
|
44
57
|
const rawHeaders = dom.getAttribute('data-ln-couchdb-headers') || '';
|
|
@@ -341,16 +354,11 @@ import { registerComponent, dispatch, buildUrl, getHeaders, parseHeaders } from
|
|
|
341
354
|
}
|
|
342
355
|
};
|
|
343
356
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
self.dom.addEventListener(ns + ':request-create', self._handlers.create);
|
|
350
|
-
self.dom.addEventListener(ns + ':request-update', self._handlers.update);
|
|
351
|
-
self.dom.addEventListener(ns + ':request-delete', self._handlers.delete);
|
|
352
|
-
self.dom.addEventListener(ns + ':request-bulk-delete', self._handlers.bulkDelete);
|
|
353
|
-
});
|
|
357
|
+
self.dom.addEventListener('ln-couchdb-connector:request-sync', self._handlers.sync);
|
|
358
|
+
self.dom.addEventListener('ln-couchdb-connector:request-create', self._handlers.create);
|
|
359
|
+
self.dom.addEventListener('ln-couchdb-connector:request-update', self._handlers.update);
|
|
360
|
+
self.dom.addEventListener('ln-couchdb-connector:request-delete', self._handlers.delete);
|
|
361
|
+
self.dom.addEventListener('ln-couchdb-connector:request-bulk-delete', self._handlers.bulkDelete);
|
|
354
362
|
}
|
|
355
363
|
|
|
356
364
|
_component.prototype.destroy = function () {
|
|
@@ -358,41 +366,19 @@ import { registerComponent, dispatch, buildUrl, getHeaders, parseHeaders } from
|
|
|
358
366
|
|
|
359
367
|
const self = this;
|
|
360
368
|
if (self._handlers) {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
self.dom.removeEventListener(ns + ':request-update', self._handlers.update);
|
|
367
|
-
self.dom.removeEventListener(ns + ':request-delete', self._handlers.delete);
|
|
368
|
-
self.dom.removeEventListener(ns + ':request-bulk-delete', self._handlers.bulkDelete);
|
|
369
|
-
});
|
|
369
|
+
self.dom.removeEventListener('ln-couchdb-connector:request-sync', self._handlers.sync);
|
|
370
|
+
self.dom.removeEventListener('ln-couchdb-connector:request-create', self._handlers.create);
|
|
371
|
+
self.dom.removeEventListener('ln-couchdb-connector:request-update', self._handlers.update);
|
|
372
|
+
self.dom.removeEventListener('ln-couchdb-connector:request-delete', self._handlers.delete);
|
|
373
|
+
self.dom.removeEventListener('ln-couchdb-connector:request-bulk-delete', self._handlers.bulkDelete);
|
|
370
374
|
self._handlers = null;
|
|
371
375
|
}
|
|
372
376
|
|
|
373
|
-
dispatch(this.dom, 'ln-couchdb-connector:destroyed', { target: this.dom });
|
|
374
|
-
|
|
375
377
|
delete this.dom[DOM_ATTRIBUTE];
|
|
376
378
|
delete this.dom[DOM_ALIAS];
|
|
377
379
|
};
|
|
378
380
|
|
|
379
|
-
// ─── Attribute Sync ────────────────────────────────────────
|
|
380
|
-
|
|
381
|
-
function _syncAttribute(el) {
|
|
382
|
-
const instance = el[DOM_ATTRIBUTE];
|
|
383
|
-
if (!instance) return;
|
|
384
|
-
instance.refreshConfig();
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// ─── Registration ──────────────────────────────────────
|
|
388
|
-
|
|
389
381
|
registerComponent(DOM_SELECTOR, DOM_ATTRIBUTE, _component, 'ln-couchdb-connector', {
|
|
390
|
-
|
|
391
|
-
'data-ln-couchdb-url',
|
|
392
|
-
'data-ln-couchdb-db',
|
|
393
|
-
'data-ln-couchdb-auth',
|
|
394
|
-
'data-ln-couchdb-headers'
|
|
395
|
-
],
|
|
396
|
-
onAttributeChange: _syncAttribute
|
|
382
|
+
attributes: ATTRIBUTES
|
|
397
383
|
});
|
|
398
384
|
})();
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# `data-ln-data-coordinator`
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
> Applied to a parent container (`<ul data-ln-data-coordinator hidden>`) enclosing a `data-ln-data-store` and a
|
|
4
|
+
> `data-ln-api-connector`. It catches store staleness and pagination requests to dispatch fetch events to the connector,
|
|
5
|
+
> populating the store with server responses (`request-populate`). On store data mutations, it executes local queries and
|
|
6
|
+
> dispatches `set-data` events directly to bound view elements (`data-ln-table-source`, `data-ln-list-source`).
|
|
6
7
|
|
|
7
8
|
---
|
|
8
9
|
|
|
@@ -12,12 +13,13 @@ Add these attributes to view elements to bind them to this coordinator's child s
|
|
|
12
13
|
|
|
13
14
|
| Attribute | Applied To | Description |
|
|
14
15
|
|---|---|---|
|
|
15
|
-
| `data-ln-table-
|
|
16
|
-
| `data-ln-list-
|
|
16
|
+
| `data-ln-table-source="<storeName>"` | `[data-ln-table]` | Binds a table — receives `ln-table:set-data` automatically. |
|
|
17
|
+
| `data-ln-list-source="<storeName>"` | `[data-ln-list]` | Binds a list — receives `ln-list:set-data` automatically. |
|
|
18
|
+
| `data-ln-chart-source="<storeName>"` | `[data-ln-chart]` | Binds a chart; receives `ln-chart:set-data` automatically. |
|
|
17
19
|
| `data-ln-options="<storeName>"` | `<select>` | Populated by `ln-options` via `ln-options:set-data`. |
|
|
18
20
|
| `data-ln-stat="<storeName>"` | Inline element | Receives count via `ln-stat:set-count`. |
|
|
19
21
|
|
|
20
|
-
`<storeName>` = the
|
|
22
|
+
`<storeName>` = the `id` of the coordinator's child store element. The presentation layer always addresses the **store**, never the coordinator. Multiple coordinators on one page each serve only their own store — isolated by the `_ownsStore(name)` guard.
|
|
21
23
|
|
|
22
24
|
### Presenter / Binder Split
|
|
23
25
|
|
|
@@ -26,21 +28,18 @@ Add these attributes to view elements to bind them to this coordinator's child s
|
|
|
26
28
|
|
|
27
29
|
Use `setPresenters` for fields like `updated_display`, `size_display`, `status_label`. The binder delivers them as-is.
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
The coordinator listens on `this.dom` for `ln-data-store:ready`, `loaded`, `created`, `updated`, `deleted`, and `synced` (only when `changed`). On any of these, `_refreshAll()` re-queries all bound view elements using their last cached query parameters.
|
|
31
|
+
The coordinator listens on `this.dom` for `ln-data-store:ready`, `loaded`, `created`, `updated`, `deleted`, `synced` (only when `changed`), `ln-data-store:query-changed`, and `ln-data-store:request-page`. On request-page, it converts page offsets into a `request-query` call on the paired connector's namespace (`ln-api-connector:request-query` or `ln-websocket-connector:request-query`, depending on which connector is present). On other store-change events, `_refreshAll()` re-queries all bound view elements using their last cached query parameters.
|
|
32
32
|
|
|
33
33
|
### Zero-JS Example
|
|
34
34
|
|
|
35
35
|
```html
|
|
36
|
-
<ul data-ln-data-coordinator hidden>
|
|
37
|
-
<li data-ln-data-store
|
|
38
|
-
<li data-ln-api-connector data-ln-api-
|
|
36
|
+
<ul id="people-module" data-ln-data-coordinator hidden>
|
|
37
|
+
<li id="people" data-ln-data-store></li>
|
|
38
|
+
<li data-ln-api-connector data-ln-api-connector-path="/api/people"></li>
|
|
39
39
|
</ul>
|
|
40
40
|
|
|
41
41
|
<section data-ln-table="people"
|
|
42
42
|
data-ln-table-source="people"
|
|
43
|
-
data-ln-table-store="people"
|
|
44
43
|
id="people-table">
|
|
45
44
|
<table>
|
|
46
45
|
<thead>
|
|
@@ -82,18 +81,18 @@ No `<script>` block needed. The coordinator wires everything.
|
|
|
82
81
|
The coordinator acts as a parent wrapper enclosing the database cache and transport connector:
|
|
83
82
|
|
|
84
83
|
```html
|
|
85
|
-
<ul data-ln-data-coordinator
|
|
86
|
-
data-ln-data-mapper="documents" hidden>
|
|
84
|
+
<ul id="documents-module" data-ln-data-coordinator
|
|
85
|
+
data-ln-data-coordinator-mapper="documents" hidden>
|
|
87
86
|
|
|
88
87
|
<!-- Tier 1: Local Cache Database (IndexedDB - pure and network-blind) -->
|
|
89
|
-
<li data-ln-data-store
|
|
88
|
+
<li id="documents" data-ln-data-store
|
|
90
89
|
data-ln-data-store-indexes="status,updated_at">
|
|
91
90
|
</li>
|
|
92
91
|
|
|
93
92
|
<!-- Tier 2: Transport Gateway (API / REST Connector) -->
|
|
94
93
|
<li data-ln-api-connector
|
|
95
|
-
data-ln-api-base-url="https://api.livenetworks.com/v1"
|
|
96
|
-
data-ln-api-path="/documents">
|
|
94
|
+
data-ln-api-connector-base-url="https://api.livenetworks.com/v1"
|
|
95
|
+
data-ln-api-connector-path="/documents">
|
|
97
96
|
</li>
|
|
98
97
|
</ul>
|
|
99
98
|
```
|
|
@@ -104,8 +103,44 @@ The coordinator acts as a parent wrapper enclosing the database cache and transp
|
|
|
104
103
|
|
|
105
104
|
| Attribute | Category | Description |
|
|
106
105
|
|-----------|----------|-------------|
|
|
107
|
-
| `
|
|
108
|
-
| `data-ln-data-
|
|
106
|
+
| `id="name"` | Identity | Unique identifier of the coordinator (the coordinator name/domain/scope). |
|
|
107
|
+
| `data-ln-data-coordinator` | Selector | Marker attribute to declare the component. Its value is the coordinator's name; falls back to `id`. Views and query controls address **this** name, never a child's. |
|
|
108
|
+
| `data-ln-data-coordinator-mapper` | Mapping | Reference to an externally registered data mapper name (e.g. `documents`). Defaults to `id` if omitted. |
|
|
109
|
+
| `data-ln-data-coordinator-scope` | Scope | Opts an external `<form>` into this coordinator's write intake loop. |
|
|
110
|
+
| `data-ln-data-coordinator-search` | Query | Current search term, a plain string. Absent or empty means no search. |
|
|
111
|
+
| `data-ln-data-coordinator-filters` | Query | Active filters as a URL query string. A multi-value filter is a **repeated key**: `status=open&status=pending&type=invoice`. Absent means no filters. |
|
|
112
|
+
| `data-ln-data-coordinator-sort-field` | Query | Field the result set is sorted by. Meaningful only together with `-sort-direction`. |
|
|
113
|
+
| `data-ln-data-coordinator-sort-direction` | Query | `asc` or `desc`. Both sort attributes are removed together when sorting is cleared. |
|
|
114
|
+
|
|
115
|
+
### The query lives here, in the form a browser would produce
|
|
116
|
+
|
|
117
|
+
The coordinator is the only participant guaranteed to be present in its layer — the cache,
|
|
118
|
+
the transport and the queue are all optional. The address and the query state are therefore
|
|
119
|
+
**its own**, never a child's. A query is not a property of the cache; the cache is one thing
|
|
120
|
+
that can *answer* a query.
|
|
121
|
+
|
|
122
|
+
```html
|
|
123
|
+
<ul data-ln-data-coordinator="documents"
|
|
124
|
+
data-ln-data-coordinator-search="acme"
|
|
125
|
+
data-ln-data-coordinator-sort-field="updated_at"
|
|
126
|
+
data-ln-data-coordinator-sort-direction="desc"
|
|
127
|
+
data-ln-data-coordinator-filters="status=open&status=pending&type=invoice" hidden>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Without JavaScript, a form does a `GET` and the browser lays the values out in a URL query
|
|
131
|
+
string. JS only enhances: it takes that same thing and forwards it over AJAX. Every flip of
|
|
132
|
+
representation between those two points is an unnecessary chance to get it wrong, so the
|
|
133
|
+
attribute carries the form the browser itself would produce — parsed with native
|
|
134
|
+
`URLSearchParams`, and a multi-value filter is the repeated key a checkbox group submits on
|
|
135
|
+
its own. Sort is two axes rather than the connector's `sort_field` / `sort_dir`, because
|
|
136
|
+
those names are transport configuration (overridable per connector via `paramKeys`) and do
|
|
137
|
+
not belong in the coordinator's contract.
|
|
138
|
+
|
|
139
|
+
All four are read **live** at the moment of use — never parsed once and cached in a JS field.
|
|
140
|
+
An author may seed them in markup as the initial query, and a script or devtools may write
|
|
141
|
+
them directly: an attribute write is honoured exactly like an `ln-search:change` event,
|
|
142
|
+
because the reaction is declared on the attribute, not on the event. Writes are batched, so
|
|
143
|
+
clearing a sort (two attribute removals) re-queries once, not twice.
|
|
109
144
|
|
|
110
145
|
---
|
|
111
146
|
|
|
@@ -114,33 +149,14 @@ The coordinator acts as a parent wrapper enclosing the database cache and transp
|
|
|
114
149
|
The coordinator is built to be highly dynamic, reacting to runtime modifications in its DOM subtree.
|
|
115
150
|
|
|
116
151
|
1. **Child Discovery**: The coordinator automatically locates its child components by querying its DOM subtree:
|
|
117
|
-
* **Store Cache**: Looks for `[data-ln-data-store]` and accesses `el.lnDataStore
|
|
118
|
-
* **Transport Connector**:
|
|
152
|
+
* **Store Cache**: Looks for `[data-ln-data-store]` and accesses `el.lnDataStore`.
|
|
153
|
+
* **Transport Connector**: The request connector is `[data-ln-api-connector]` or `[data-ln-couchdb-connector]` when present, otherwise `[data-ln-websocket-connector]`; the coordinator accesses the matching instance (`el.lnApiConnector`, `el.lnCouchDbConnector` or `el.lnWebsocketConnector`). The request event namespace (`ln-api-connector:*`, `ln-couchdb-connector:*` or `ln-websocket-connector:*`) is derived from whichever selector matched, not hardcoded. Responses are heard from all three namespaces, so a socket beside a REST connector still delivers its pushes (`:fetched`) to the store.
|
|
154
|
+
* **Live Socket Catch-up**: On every `ln-websocket-connector:connected` the coordinator runs `store.forceSync()` — a delta since `lastSyncedAt` over the request connector — so changes missed while the socket was down are fetched.
|
|
119
155
|
* **Offline Outbox (optional Child 3)**: Looks for `[data-ln-api-queue]` and accesses `el.lnApiQueue`. When present, write routing (below) enqueues instead of calling the connector directly. When absent, behavior is byte-for-byte the direct-connector path described in this document.
|
|
120
156
|
|
|
121
|
-
2. **Mapper Resolution**: The coordinator resolves mapping functions using
|
|
122
|
-
* **
|
|
123
|
-
|
|
124
|
-
<script type="application/javascript" data-ln-mapper>
|
|
125
|
-
({
|
|
126
|
-
ingress(serverRaw) {
|
|
127
|
-
return {
|
|
128
|
-
id: serverRaw.id,
|
|
129
|
-
title: serverRaw.title,
|
|
130
|
-
status: serverRaw.status,
|
|
131
|
-
updated_at: Date.parse(serverRaw.updated_at) / 1000
|
|
132
|
-
};
|
|
133
|
-
},
|
|
134
|
-
egress(localDb) {
|
|
135
|
-
return {
|
|
136
|
-
title: localDb.title,
|
|
137
|
-
status: localDb.status
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
})
|
|
141
|
-
</script>
|
|
142
|
-
```
|
|
143
|
-
* **External Registry (Reusability)**: If no inline script exists, it reads the `data-ln-data-mapper` attribute and looks up the mapper via `window.lnCore.getDataMapper(name)`.
|
|
157
|
+
2. **Mapper Resolution**: The coordinator resolves mapping functions securely using the registry:
|
|
158
|
+
* **External Registry (Recommended & Secure)**: Reads the `data-ln-data-coordinator-mapper` attribute — falling back to the host element's `id` when the attribute is absent — and looks up the mapper via `window.lnCore.getDataMapper(name)`. Mappers are registered via `window.lnCore.registerDataMapper(name, mapper)`.
|
|
159
|
+
* **Inline Script Deprecation**: Nested `<script data-ln-mapper>` tags are deprecated and disabled due to XSS vulnerability risks (unsafe-eval).
|
|
144
160
|
* **Fallback**: Defaults to a safe no-op mapper: `{ ingress: r => r, egress: r => r }`.
|
|
145
161
|
|
|
146
162
|
---
|
|
@@ -149,6 +165,31 @@ The coordinator is built to be highly dynamic, reacting to runtime modifications
|
|
|
149
165
|
|
|
150
166
|
Because all events dispatched by the child components bubble up, the coordinator listens directly on its own DOM boundary. It manages the following flows seamlessly:
|
|
151
167
|
|
|
168
|
+
### Query Intake — `ln-search:change` / `ln-filter:change` / `ln-sort:change`
|
|
169
|
+
|
|
170
|
+
Query controls announce a **speech act**; the coordinator stores the resulting **state**. The
|
|
171
|
+
handlers do exactly one thing: write the attribute. They never re-query directly.
|
|
172
|
+
|
|
173
|
+
| Event | `detail` read | Written to |
|
|
174
|
+
|---|---|---|
|
|
175
|
+
| `ln-search:change` | `term` | `data-ln-data-coordinator-search` |
|
|
176
|
+
| `ln-filter:change` | `key`, `values` | merged into `data-ln-data-coordinator-filters` |
|
|
177
|
+
| `ln-sort:change` | `field`, `direction` | `-sort-field` + `-sort-direction` |
|
|
178
|
+
|
|
179
|
+
Each handler calls `preventDefault()` to claim the event, and diffs against the current
|
|
180
|
+
attribute value first — a filter reset that was never set, or a re-click producing the same
|
|
181
|
+
sort, is not a query change and does nothing.
|
|
182
|
+
|
|
183
|
+
`ln-filter:change` carries **one key** per control, so the attribute accumulates keys across
|
|
184
|
+
however many filter controls are bound. An empty `values` array removes that key; when the
|
|
185
|
+
last key goes, the attribute is removed rather than left as an empty string. `ln-sort:change`
|
|
186
|
+
emits `direction: 'none'` to mean "sort removed", and `field` is `null` for a column-index
|
|
187
|
+
sort — both are treated as "no sort", since neither is a meaningful server sort key.
|
|
188
|
+
|
|
189
|
+
The re-query is **not** triggered from these handlers. It is declared once, as a reaction to
|
|
190
|
+
the four query attributes (`extraAttributes` + `onAttributeChange`), and batched — so one
|
|
191
|
+
sort change, which writes two attributes, still re-queries once.
|
|
192
|
+
|
|
152
193
|
### 0. Form Write Intake (native `submit`, claimed via `preventDefault()`)
|
|
153
194
|
|
|
154
195
|
The coordinator listens for the native `submit` event on `document`
|
|
@@ -157,7 +198,7 @@ the form itself always runs first). On every submit bubbling through:
|
|
|
157
198
|
|
|
158
199
|
1. `if (e.defaultPrevented) return` — either `ln-validate`'s validation
|
|
159
200
|
gate blocked an invalid submit, or another coordinator already claimed it.
|
|
160
|
-
2. Reads `data-ln-
|
|
201
|
+
2. Reads `data-ln-data-coordinator-scope` off `e.target` (the form). Absent → the
|
|
161
202
|
form never opted in; leave the native submit alone.
|
|
162
203
|
3. Claims it if either holds: scope value `=== this._name` (named
|
|
163
204
|
override), or the scope is empty and the form is a DOM descendant of
|
|
@@ -308,7 +349,7 @@ only when the queue later commands the coordinator to send.
|
|
|
308
349
|
The queue entry's opaque `meta.action` (the form's resource URL,
|
|
309
350
|
persisted across sessions) now rides into the connector request's `url`
|
|
310
351
|
field at send time; the connector executes the write against it, joined
|
|
311
|
-
with `data-ln-api-base-url` exactly like the `path` fallback.
|
|
352
|
+
with `data-ln-api-connector-base-url` exactly like the `path` fallback.
|
|
312
353
|
|
|
313
354
|
The coordinator listens for `ln-api-queue:send` on the queue element. It
|
|
314
355
|
maps `op` to the matching connector `:request-*` event (same egress/ingress flow as the
|
|
@@ -328,7 +369,7 @@ identity. The coordinator does not fall back to a possibly stale `meta.id`.
|
|
|
328
369
|
|
|
329
370
|
> Remap also rewrites `meta.action` if it contains the old key as a
|
|
330
371
|
> substring (string replace) — keeps a persisted per-record URL in sync
|
|
331
|
-
> after a create resolves. See `
|
|
372
|
+
> after a create resolves. See `components/ln-api-queue/README.md`.
|
|
332
373
|
|
|
333
374
|
Every success path also calls `_toastFromMessage(e.detail.message)` — see
|
|
334
375
|
Toasts below.
|
|
@@ -362,8 +403,8 @@ connector, no queue — is a first-class, supported configuration, not a
|
|
|
362
403
|
degraded fallback:
|
|
363
404
|
|
|
364
405
|
```html
|
|
365
|
-
<ul data-ln-data-coordinator
|
|
366
|
-
<li data-ln-data-store
|
|
406
|
+
<ul id="drafts-module" data-ln-data-coordinator hidden>
|
|
407
|
+
<li id="drafts" data-ln-data-store></li>
|
|
367
408
|
</ul>
|
|
368
409
|
```
|
|
369
410
|
|
|
@@ -424,9 +465,9 @@ ignored otherwise):
|
|
|
424
465
|
`buildDict()` helper `ln-upload` uses for its dictionary):
|
|
425
466
|
|
|
426
467
|
```html
|
|
427
|
-
<ul data-ln-data-coordinator
|
|
428
|
-
<li data-ln-data-store
|
|
429
|
-
<li data-ln-api-connector data-ln-api-base-url="/api" data-ln-api-path="/documents"></li>
|
|
468
|
+
<ul id="documents-module" data-ln-data-coordinator hidden>
|
|
469
|
+
<li id="documents" data-ln-data-store></li>
|
|
470
|
+
<li data-ln-api-connector data-ln-api-connector-base-url="/api" data-ln-api-connector-path="/documents"></li>
|
|
430
471
|
|
|
431
472
|
<!-- consumed once at init, then removed from the DOM -->
|
|
432
473
|
<span data-ln-data-coordinator-dict="auth" hidden>Your session expired — please sign in again.</span>
|
|
@@ -457,9 +498,9 @@ The coordinator — not the store — decides WHEN to sync:
|
|
|
457
498
|
* A module-level singleton wires **one shared** `window 'online'`,
|
|
458
499
|
`window 'offline'`, and `document 'visibilitychange'` listener set across
|
|
459
500
|
every coordinator instance on the page (not one per instance). On
|
|
460
|
-
`online`, dispatches `ln-data-
|
|
501
|
+
`online`, dispatches `ln-data-coordinator:online` on `document` once, then for each
|
|
461
502
|
coordinator with a loaded, non-syncing store: `store.forceSync()`. On
|
|
462
|
-
`offline`, dispatches `ln-data-
|
|
503
|
+
`offline`, dispatches `ln-data-coordinator:offline` on `document` once. On
|
|
463
504
|
`visibilitychange` (tab visible again), for each coordinator whose store
|
|
464
505
|
is stale: `store.forceSync()`.
|
|
465
506
|
|
|
@@ -474,18 +515,17 @@ view reads use the remote source directly.
|
|
|
474
515
|
| `data-ln-data-coordinator-stale` | Seconds threshold before the store is considered stale; falls back to the store's own `data-ln-data-store-stale`; default 300; `-1` / `never` = never stale. |
|
|
475
516
|
| `data-ln-data-coordinator-no-autosync` | Presence opts the coordinator out of online/visibility auto-sync; falls back to the store's own `data-ln-data-store-no-autosync`. |
|
|
476
517
|
|
|
477
|
-
`ln-data-
|
|
478
|
-
|
|
479
|
-
[ln-data-store README](../ln-data-store/README.md)).
|
|
518
|
+
`ln-data-coordinator:online` / `ln-data-coordinator:offline` indicate network status
|
|
519
|
+
for data coordination across the page.
|
|
480
520
|
|
|
481
521
|
---
|
|
482
522
|
|
|
483
523
|
## 💡 JS API (On the element)
|
|
484
524
|
|
|
485
|
-
Access the coordinator instance programmatically via the `lnDataCoordinator`
|
|
525
|
+
Access the coordinator instance programmatically via the `lnDataCoordinator` property:
|
|
486
526
|
|
|
487
527
|
```javascript
|
|
488
|
-
const coordinator = document.
|
|
528
|
+
const coordinator = document.getElementById('documents-module').lnDataCoordinator;
|
|
489
529
|
|
|
490
530
|
// Force a remote configuration refresh
|
|
491
531
|
coordinator.refreshConfig();
|
|
@@ -501,35 +541,31 @@ const { ingress, egress } = coordinator.mapper;
|
|
|
501
541
|
|
|
502
542
|
## 🔧 Internals — View-Binding Layer
|
|
503
543
|
|
|
504
|
-
Source: `
|
|
544
|
+
Source: `components/ln-data-coordinator/src/ln-data-coordinator.js`. The write pipeline (fan-out, sync, queue, toasts) is documented above; this section covers the coordinator's second role — serving live data to bound view components with zero application JS.
|
|
505
545
|
|
|
506
546
|
### Binding attributes
|
|
507
547
|
|
|
508
548
|
| Attribute | Applied to | Served by |
|
|
509
549
|
|---|---|---|
|
|
510
|
-
| `data-ln-table-
|
|
511
|
-
| `data-ln-list-
|
|
550
|
+
| `data-ln-table-source="<name>"` | `[data-ln-table]` | `ln-table:set-data` |
|
|
551
|
+
| `data-ln-list-source="<name>"` | `[data-ln-list]` | `ln-list:set-data` |
|
|
552
|
+
| `data-ln-chart-source="<name>"` | `[data-ln-chart]` | `ln-chart:set-data` |
|
|
512
553
|
| `data-ln-options="<name>"` | `<select>` | `ln-options:set-data` |
|
|
513
554
|
| `data-ln-stat="<name>"` | inline element | `ln-stat:set-count` |
|
|
514
555
|
|
|
515
|
-
`<name>` must match the coordinator's own child store's `
|
|
556
|
+
`<name>` must match the coordinator's own child store's `id` value. Every document-level handler guards with `_ownsStore(name)` first (`children.store && children.store._name === name`), so multiple coordinators on one page coexist without cross-talk.
|
|
516
557
|
|
|
517
558
|
### Presenter / binder split
|
|
518
559
|
|
|
519
560
|
Presenters (`store.setPresenters({computed})`) are registered once per store; computed display fields (`updated_display`, `status_label`, …) flow through `getAll → set-data` automatically. The coordinator is a pure binder — it transports whatever `getAll` produces to the requesting view element without transforming it.
|
|
520
561
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
and stores with `initializationError` route remote. When IndexedDB is
|
|
525
|
-
unavailable, table/list/options/stat responses are delivered directly to the
|
|
526
|
-
requesting view instead of being forced through the failed store. Query
|
|
527
|
-
failures clear loading and emit
|
|
528
|
-
`ln-data-coordinator:error {operation:'query', kind, store, target, error}`.
|
|
562
|
+
When querying, the coordinator composes the final query payload: the view element provides pagination and sorting (`offset`, `limit`, `sort`), while the store cache provides the active filters and search terms (`filters`, `search`).
|
|
563
|
+
|
|
564
|
+
The binder awaits `store.ready` before choosing a source. If the store is loaded and has no initialization error, reads use the local store; otherwise, connector-backed stores route remote. When IndexedDB is unavailable, table/list/chart/options/stat responses are delivered directly to the requesting view instead of being forced through the failed store. Query failures clear loading and emit `ln-data-coordinator:error {operation:'query', kind, store, target, error}`.
|
|
529
565
|
|
|
530
566
|
### Refresh trigger
|
|
531
567
|
|
|
532
|
-
On `ln-data-store:ready`/`loaded`/`created`/`updated`/`deleted`,
|
|
568
|
+
On `ln-data-store:ready`/`loaded`/`created`/`updated`/`deleted`, `synced` (only when `e.detail.changed`), and `ln-data-store:query-changed`, `_refreshAll()` re-queries every bound view element using its last cached query parameters (or defaults) — so a filter/sort/search a user set on a table survives a background sync.
|
|
533
569
|
|
|
534
570
|
### `data-ln-table-filter-options` — removed
|
|
535
571
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
@use '../../theme/config/mixins' as *;
|
|
2
|
+
|
|
3
|
+
[data-ln-debug] {
|
|
4
|
+
// 1. Child Store Check: data-ln-data-coordinator must contain a child [data-ln-data-store]
|
|
5
|
+
[data-ln-data-coordinator]:not(:has([data-ln-data-store])) {
|
|
6
|
+
@include dev-dom-error("[data-ln-data-coordinator] must contain a child [data-ln-data-store].");
|
|
7
|
+
}
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){"use strict";function J(){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 $(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 r=t.closest("[data-ln-debug]");return!(!r||typeof document<"u"&&r===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(...r){if(typeof r[0]=="string"&&(r[0].startsWith("[ln-")||r[0].startsWith("[lnCore"))){let a=null;for(let d=1;d<r.length;d++)if(r[d]&&r[d].nodeType===1){a=r[d];break}if(!$(a))return}t.apply(console,r)}}function h(t,r,i){const a=i||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",r,t,a),t.dispatchEvent(new CustomEvent(r,{bubbles:!0,detail:a}))}function N(t,r){if(!document.body){document.addEventListener("DOMContentLoaded",function(){N(t,r)}),console.warn("["+r+'] Script loaded before <body> — add "defer" to your <script> tag');return}t()}function le(t){const r=t.querySelector('input[name="_method"]');return((r&&r.value!==""?r.value:t.method)||"").toUpperCase()}function ce(t,r){const i={},a=t.elements;for(let d=0;d<a.length;d++){const l=a[d];if(!(!l.name||l.disabled||l.type==="file"||l.type==="submit"||l.type==="button"))if(l.type==="checkbox")i[l.name]||(i[l.name]=[]),l.checked&&i[l.name].push(l.value);else if(l.type==="radio")l.checked&&(i[l.name]=l.value);else if(l.type==="select-multiple"){i[l.name]=[];for(let u=0;u<l.options.length;u++)l.options[u].selected&&i[l.name].push(l.options[u].value)}else i[l.name]=l.value}return i}const X={};function ue(t,r){X[t]=r}function fe(t){return X[t]||{ingress:r=>r,egress:r=>r}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=ue,window.lnCore.getDataMapper=fe);function he(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,N(function(){new MutationObserver(function(){h(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const Y={};function pe(t,r){if(!t||typeof r!="object")return;const i=t.toLowerCase().split("-")[0];Y[i]=r}function me(t){if(!t)return null;const r=t.toLowerCase().split("-")[0];return Y[r]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=pe,window.lnCore.getLocaleFallback=me,window.lnCore.ensureLocaleObserver=he);const B={};function ye(t,r){B[t]||(B[t]=document.querySelector('[data-ln-template="'+t+'"]'));const i=B[t];return i?i.content.cloneNode(!0):(console.warn("["+(r||"ln-core")+'] Template "'+t+'" not found'),null)}function Z(t,r){if(!t||!r)return t;const i=t.querySelectorAll("[data-ln-field]");for(let u=0;u<i.length;u++){const m=i[u],p=m.getAttribute("data-ln-field");r[p]!=null&&(m.textContent=r[p])}const a=t.querySelectorAll("[data-ln-attr]");for(let u=0;u<a.length;u++){const m=a[u],p=m.getAttribute("data-ln-attr").split(",");for(let v=0;v<p.length;v++){const S=p[v].trim().split(":");if(S.length!==2)continue;const A=S[0].trim(),L=S[1].trim();r[L]!=null&&m.setAttribute(A,r[L])}}const d=t.querySelectorAll("[data-ln-show]");for(let u=0;u<d.length;u++){const m=d[u],p=m.getAttribute("data-ln-show");p in r&&m.classList.toggle("hidden",!r[p])}const l=t.querySelectorAll("[data-ln-class]");for(let u=0;u<l.length;u++){const m=l[u],p=m.getAttribute("data-ln-class").split(",");for(let v=0;v<p.length;v++){const S=p[v].trim().split(":");if(S.length!==2)continue;const A=S[0].trim(),L=S[1].trim();L in r&&m.classList.toggle(A,!!r[L])}}return t}function ge(t,r){t.matches&&t.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",t,r??null),t.dispatchEvent(new CustomEvent("ln-fill",{detail:r??null,bubbles:!0})));const i=t.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let a=0;a<i.length;a++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",i[a],r??null),i[a].dispatchEvent(new CustomEvent("ln-fill",{detail:r??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)Z(t.target,t.detail);else{const r=t.target.querySelectorAll("[data-ln-field]");for(let i=0;i<r.length;i++)r[i].textContent=""}})));function ee(t,r){if(!t||!r)return t;const i=document.createTreeWalker(t,NodeFilter.SHOW_TEXT);for(;i.nextNode();){const l=i.currentNode;l.textContent.indexOf("{{")!==-1&&(l.textContent=l.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(u,m){return r[m]!==void 0?r[m]:""}))}const a=function(l,u){return r[u]!==void 0?r[u]:""},d=Array.from(t.querySelectorAll("*"));t.nodeType===1&&d.push(t);for(let l=0;l<d.length;l++){const u=d[l],m=u.attributes;for(let p=0;p<m.length;p++){const v=m[p];v.value.indexOf("{{")!==-1&&u.setAttribute(v.name,v.value.replace(/\{\{\s*(\w+)\s*\}\}/g,a))}}return t}function be(t,r,i,a,d,l){const u={};for(let p=0;p<t.children.length;p++){const v=t.children[p],S=v.getAttribute("data-ln-render-key");S&&(u[S]=v)}const m=document.createDocumentFragment();for(let p=0;p<r.length;p++){const v=r[p],S=String(a(v));let A=u[S];if(A)d(A,v,p);else{const L=ye(i,l);if(!L||(ee(L,v),A=L.firstElementChild,!A))continue;A.setAttribute("data-ln-render-key",S),d(A,v,p)}m.appendChild(A)}t.textContent="",t.appendChild(m)}function we(t,r){const i={},a=t.querySelectorAll("["+r+"]");for(let d=0;d<a.length;d++)i[a[d].getAttribute(r)]=a[d].textContent,a[d].remove();return i}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=ee,window.lnCore.fill=Z,window.lnCore.lnFill=ge,window.lnCore.renderList=be);function te(t,r,i){const a=t.getAttribute(r);return a===null?i:a}function _e(t,r,i){const a=parseInt(t.getAttribute(r),10);return isNaN(a)?i:a}function qe(t,r,i=!1){const a=t.getAttribute(r);if(a===null)return!!i;const d=a.trim().toLowerCase();return!(d==="false"||d==="0")}function Ee(t,r){return(t.getAttribute(r)||"").split(",").map(i=>i.trim()).filter(Boolean)}const U=new Map;function ve(t,r){const i=(t?t.join("|"):"")+"::"+r;if(U.has(i))return U.get(i);const a=new Set(t||[]),d=function(l,u){const m=l.getAttribute(u);return m!==null&&a.has(m)?m:r};return U.set(i,d),d}function Ce(t,r,i){const a=parseFloat(t.getAttribute(r));return isNaN(a)?i:a}function Ae(t,r,i){const a=t.getAttribute(r);if(!a)return i;try{return JSON.parse(a)}catch{return i}}function ne(t,r,i,a,d){if(!t||r===null)return!0;const l=a||"ln-component",u=t.type;if(u==="trigger"||u==="marker"||u==="string"||u==="list"||!u||r===""&&t.fallback!==void 0)return!0;const m=p=>{d?console.warn(p,d):console.warn(p)};if(u==="boolean"){const p=r.trim().toLowerCase();return p!==""&&p!=="true"&&p!=="false"&&p!=="1"&&p!=="0"?(m(`[${l}] Invalid value "${r}" for boolean attribute "${i}". Allowed: "true", "false", or presence-only.`),!1):!0}if(u==="enum"){const p=t.values||[];return p.includes(r)?!0:(m(`[${l}] Invalid value "${r}" for attribute "${i}". Allowed: ${p.join(", ")}. Fallback: "${t.fallback}".`),!1)}if(u==="integer"){if(!/^-?\d+$/.test(r))return m(`[${l}] Invalid integer "${r}" for attribute "${i}". Fallback: ${t.fallback}.`),!1;const p=parseInt(r,10);return t.min!==void 0&&p<t.min?(m(`[${l}] Value ${p} for attribute "${i}" is less than min (${t.min}).`),!1):t.max!==void 0&&p>t.max?(m(`[${l}] Value ${p} for attribute "${i}" is greater than max (${t.max}).`),!1):!0}if(u==="float")return isNaN(Number(r))?(m(`[${l}] Invalid float "${r}" for attribute "${i}". Fallback: ${t.fallback}.`),!1):!0;if(u==="json")try{return JSON.parse(r),!0}catch(p){return m(`[${l}] Invalid JSON for attribute "${i}": ${p.message}. Fallback: ${t.fallback}.`),!1}return!0}function Se(t,r,i){for(const a in i){const[d,l,u]=i[a];Object.defineProperty(t,a,{get:function(){return d(r,l,u)},enumerable:!0,configurable:!0})}return t}function ke(t){const r={};for(const i in t){const a=t[i];if(!a||!a.prop)continue;let d=a.read;if(!d&&a.type)switch(a.type){case"enum":d=ve(a.values,a.fallback);break;case"integer":d=_e;break;case"float":d=Ce;break;case"boolean":d=qe;break;case"list":d=Ee;break;case"json":d=Ae;break;case"string":default:d=te;break}d||(d=te),r[a.prop]=[d,i,a.fallback]}return r}function Le(t){const r={};for(const i in t){const a=t[i];a&&a.effect&&(r[i]=a.effect)}return Object.keys(r).length?r:null}function xe(t){if(t.onAttrChange&&!t.declared)return null;const r=new Set;if(t.effects)for(const i in t.effects)r.add(i);if(t.onAttrChange&&t.declared)for(const i of t.declared)r.add(i);return r}function z(t,r,i,a){if(t.nodeType!==1)return;const l=r.indexOf("[")!==-1||r.indexOf(".")!==-1||r.indexOf("#")!==-1?r:"["+r+"]",u=Array.from(t.querySelectorAll(l));t.matches&&t.matches(l)&&u.push(t);for(const m of u)if(!m[i]){window.lnCore._persistSink&&m.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(m,r);try{m[i]=new a(m)}catch(p){console.error("["+i+"] init failed",m,p)}}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function De(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function Ie(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 re(){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 Oe(t){const r=re(),i=t.observed||[];for(let a=0;a<i.length;a++){const d=i[a];r.byAttr.has(d)||r.byAttr.set(d,[]),r.byAttr.get(d).push(t)}if(r.byDeclaredAttr=r.byDeclaredAttr||new Map,t.attributes)for(const a in t.attributes){r.byDeclaredAttr.has(a)||r.byDeclaredAttr.set(a,[]);const d=r.byDeclaredAttr.get(a);d.some(l=>l.componentTag===t.componentTag)||d.push({spec:t.attributes[a],componentTag:t.componentTag})}if(t.onAttrChange||t.effects){r.reactive.push(t);const a=xe(t);if(a===null)r.reactiveWildcard.push(t);else for(const d of a)r.byReactive.has(d)||r.byReactive.set(d,[]),r.byReactive.get(d).push(t)}t.persist&&r.persist.push(t)}function oe(t,r,i,a){for(let d=0;d<t.length;d++){const l=t[d];if(!r[l.attribute])continue;const u=l.effects&&l.effects[i];u?u(r,i,a):l.onAttrChange&&(!l.declared||l.declared.has(i))&&l.onAttrChange(r,i,a)}}function Re(t){const r=t.target,i=t.attributeName;if(t.oldValue===r.getAttribute(i))return;const a=re(),d=a.byAttr.get(i);if(J()&&a.byDeclaredAttr&&a.byDeclaredAttr.has(i)&&$(r)){const l=a.byDeclaredAttr.get(i),u=r.getAttribute(i);for(let m=0;m<l.length;m++)ne(l[m].spec,u,i,l[m].componentTag,r)}if(window.lnCore._debugSink&&(i.indexOf("data-ln-")===0||d)&&window.lnCore._debugSink("attr",i,r,{oldValue:t.oldValue,newValue:r.getAttribute(i)}),i.indexOf("data-ln-")===0){const l=a.byReactive.get(i);l&&oe(l,r,i,t.oldValue),a.reactiveWildcard.length&&oe(a.reactiveWildcard,r,i,t.oldValue)}if(d)for(let l=0;l<d.length;l++){const u=d[l];if(u.handler){u.handler(r,i,t.oldValue);continue}u.onAttributeChange&&r[u.attribute]?u.onAttributeChange(r,i):(z(r,u.selector,u.attribute,u.ComponentFn),u.onInit&&u.onInit(r))}}function Ge(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,N(function(){new MutationObserver(function(r){for(let i=0;i<r.length;i++)try{Re(r[i])}catch(a){console.error("[ln-core] mutation handler failed",r[i].target,a)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function ie(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function Te(t){const r=ie();if(r.length){if(t.target)for(let i=0;i<r.length;i++){const a=r[i];if(a.onSubtreeChange){const d=a.query,l=t.target.nodeType===1?t.target.matches(d)?t.target:t.target.closest(d):t.target.parentElement?t.target.parentElement.closest(d):null;l&&a.onSubtreeChange(l,t)}}for(let i=0;i<t.addedNodes.length;i++){const a=t.addedNodes[i];if(a.nodeType===1)for(let d=0;d<r.length;d++){const l=r[d];z(a,l.selector,l.attribute,l.ComponentFn),l.onInit&&l.onInit(a)}}for(let i=0;i<t.removedNodes.length;i++){const a=t.removedNodes[i];if(a.nodeType===1)for(let d=0;d<r.length;d++){const l=r[d],u=l.query,m=Array.from(a.querySelectorAll(u));a.matches&&a.matches(u)&&m.push(a);for(let p=0;p<m.length;p++){const v=m[p];if(!document.contains(v)){const S=v[l.attribute];if(S&&typeof S.destroy=="function")try{S.destroy()}catch(A){console.error("["+l.attribute+"] destroy failed",v,A)}delete v[l.attribute]}}}}}}function Me(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,N(function(){new MutationObserver(function(r){for(let i=0;i<r.length;i++){const a=r[i];if(a.type==="childList")try{Te(a)}catch(d){console.error("[ln-core] lifecycle handler failed",a.target,d)}}}).observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function Fe(t,r,i,a,d={}){const l=d.extraAttributes||[],u=d.onAttributeChange||null,m=d.onSubtreeChange||null,p=d.onInit||null,v=d.onAttrChange||null,S=d.effects||null,A=d.attributes||null,L=A?Le(A):S,M=A?new Set(Object.keys(A)):null,F=d.persist||null;function O(Q){const C=Q||document.body;if(z(C,t,r,i),A&&J())for(const q in A){const V=A[q],e=Array.from(C.querySelectorAll("["+q+"]"));C.matches&&C.matches("["+q+"]")&&e.push(C);for(let n=0;n<e.length;n++){const o=e[n];$(o)&&ne(V,o.getAttribute(q),q,a,o)}}p&&p(C)}const G=[];if(t.indexOf("[")!==-1){const Q=/\[([\w-]+)/g;let C;for(;(C=Q.exec(t))!==null;)G.push(C[1])}else G.push(t);Oe({selector:t,attribute:r,componentTag:a,attributes:A,ComponentFn:i,onInit:p,observed:G.concat(l),onAttributeChange:u,onAttrChange:v,effects:L,declared:M,persist:F}),Ge();const W=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]";ie().push({selector:t,attribute:r,ComponentFn:i,onInit:p,onSubtreeChange:m,query:W}),Me(),window[r]=O;function R(){De()>0?Ie(function(){O(document.body)}):O(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",R):R(),O}function Qe(t,r){let i=!1;return function(){i||(i=!0,queueMicrotask(function(){i=!1,t()}))}}function ae(t){return(t||"").replace(/^#/,"")}function K(t){const r=t===void 0?location.hash:t,i={},a=ae(r);if(!a)return i;const d=a.split("&");for(let l=0;l<d.length;l++){const u=d[l];if(!u)continue;const m=u.indexOf(":"),p=m>-1?u.slice(0,m):u,v=m>-1?u.slice(m+1):"";if(p)try{i[p]=decodeURIComponent(v)}catch{i[p]=v}}return i}function je(t){if(!t)return null;const r=K();return t in r?r[t]:null}function Ne(t,r){if(!t)return;const i=K();r==null?delete i[t]:i[t]=String(r);const d=Object.keys(i).map(function(l){const u=i[l];return u===""?l:l+":"+encodeURIComponent(u)}).join("&");ae(location.hash)!==d&&(location.hash=d)}function Pe(t){return t.button===1||t.ctrlKey||t.metaKey||t.shiftKey?!1:(t.preventDefault(),!0)}function $e(t,r){if(!t||!t.hasAttribute("data-ln-hash"))return null;const i=t.getAttribute("data-ln-hash");if(i&&i.trim()!=="")return i.trim();const a=t.getAttribute("data-ln-sort")||t.getAttribute("data-ln-search-for")||t.getAttribute("data-ln-search")||t.getAttribute("data-ln-filter")||t.id;return a?r?a+"-"+r:a:r||null}function Be(t,r){return!r||r==="none"||t===null||t===void 0?null:String(t)+"."+r}function Ue(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 ze(t,r){return!t||!Array.isArray(r)||r.length===0?null:t+":"+r.map(encodeURIComponent).join(",")}function Ke(t){if(!t||typeof t!="string")return null;const r=t.indexOf(":");if(r===-1)return null;const i=t.slice(0,r),a=t.slice(r+1),d=a?a.split(",").map(function(l){try{return decodeURIComponent(l)}catch{return l}}).filter(Boolean):[];return{key:i,values:d}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=K,window.lnCore.hashGet=je,window.lnCore.hashSet=Ne,window.lnCore.hashLinkClick=Pe,window.lnCore.resolveHashNamespace=$e,window.lnCore.hashSortEncode=Be,window.lnCore.hashSortDecode=Ue,window.lnCore.hashFilterEncode=ze,window.lnCore.hashFilterDecode=Ke);function We(t){return t=t||{},{sort:t.sort,filters:t.filters,search:t.search,offset:t.offset,limit:t.limit,queryGen:t.queryGen}}function j(t,r){const i=!t||!!t.initializationError,a=!!(t&&t.noLocalQuery&&!t.windowed);return r&&(i||!t.canServe||a)?"remote":t&&!t.initializationError?"store":"none"}function P(t,r,i){return i==="store"&&!!r&&!(t&&t.windowed)}function se(t,r){const i=Object.assign({},t);return r&&(i.filters=r.filters,i.search=r.search,i.sort=r.sort),i}class Ve{constructor(){this._pending=new Map}wait(r){return new Promise((i,a)=>{this._pending.set(r,{resolve:i,reject:a})})}resolve(r){return this._settle(r,!1)}reject(r){return this._settle(r,!0)}close(r){const i=r||new Error("Mutation receipt registry closed");for(const a of this._pending.values())a.reject(i);this._pending.clear()}_settle(r,i){const a=r&&r.requestId;if(!a)return!1;const d=this._pending.get(a);return d?(this._pending.delete(a),i?d.reject(r.error||new Error("Store mutation failed")):d.resolve(r),!0):!1}}(function(){const t="data-ln-data-coordinator",r="lnDataCoordinator",i="data-ln-data-coordinator-scope",a="data-ln-data-coordinator-search",d="data-ln-data-coordinator-filters",l="data-ln-data-coordinator-sort-field",u="data-ln-data-coordinator-sort-direction";if(window[r]!==void 0)return;function m(e){const n=e[r];n&&n.refreshMapper()}function p(e){const n=e[r];n&&n._queueQueryRefresh()}function v(e,n){return e.getAttribute(n)||e.id}const S={"data-ln-data-coordinator":{prop:"_name",type:"string",read:v,description:"Coordinator name or identifier for data routing"},"data-ln-data-coordinator-scope":{type:"string",description:"Scope name addressing the bound data store and connector"},"data-ln-data-coordinator-mapper":{type:"string",effect:m,description:"Name of the registered data mapper transform"},"data-ln-data-coordinator-search":{type:"string",effect:p,description:"Active search query term"},"data-ln-data-coordinator-filters":{type:"string",effect:p,description:"Active encoded filter parameters"},"data-ln-data-coordinator-sort-field":{type:"string",effect:p,description:"Active sort field property name"},"data-ln-data-coordinator-sort-direction":{type:"enum",values:["asc","desc"],fallback:"asc",effect:p,description:"Sort direction"},"data-ln-data-coordinator-stale":{type:"marker",description:"Flag indicating data needs re-synchronization"},"data-ln-data-coordinator-no-autosync":{type:"boolean",description:"Disables automatic synchronization upon state changes"},"data-ln-data-coordinator-dict":{type:"marker",description:"Marks dictionary container for coordinator translatable messages"}},A=ke(S),L=new Set;let M=!1,F=null,O=null,G=null;function de(){M||(M=!0,F=function(){h(document,"ln-data-coordinator:online",{}),L.forEach(function(e){e._maybeSync()})},O=function(){h(document,"ln-data-coordinator:offline",{})},G=function(){document.visibilityState==="visible"&&L.forEach(function(e){const n=e.findChildren(),o=n.store;o&&n.connector&&o.isInitialized&&!o.initializationError&&!o.isSyncing&&!e._noAutosync&&(!o.hasCache||e._isStale())&&o.forceSync()})},window.addEventListener("online",F),window.addEventListener("offline",O),document.addEventListener("visibilitychange",G))}function W(){M&&(L.size>0||(window.removeEventListener("online",F),window.removeEventListener("offline",O),document.removeEventListener("visibilitychange",G),F=null,O=null,G=null,M=!1))}function R(){try{return crypto.randomUUID()}catch{return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const o=Math.random()*16|0;return(n==="x"?o:o&3|8).toString(16)})}}const Q=["ln-api-connector","ln-couchdb-connector","ln-websocket-connector"];function C(e){return e?e.hasAttribute("data-ln-couchdb-connector")?"ln-couchdb-connector":e.hasAttribute("data-ln-websocket-connector")?"ln-websocket-connector":"ln-api-connector":"ln-api-connector"}function q(e){const n=this;return this.dom=e,Se(this,e,A),this._name||console.warn("[ln-data-coordinator] missing id — the coordinator cannot be addressed",e),e[r]=this,this._destroyed=!1,this.mapper=null,this._handlers=null,this._boundQueries=new WeakMap,this._boundDelivered=new WeakMap,this._queryGens=new WeakMap,this._mutationReceipts=new Ve,this._dict=we(e,"data-ln-data-coordinator-dict"),this._queueQueryRefresh=Qe(function(){n._destroyed||n._refreshAll(null,!0)}),this.refreshConfig(),V(this),L.add(this),de(),this._checkInitialSync(),this}Object.defineProperty(q.prototype,"_staleThreshold",{get:function(){const n=this.findChildren().storeEl,o=this.dom.getAttribute("data-ln-data-coordinator-stale")||(n?n.getAttribute("data-ln-data-store-stale"):null);if(o==="never"||o==="-1")return-1;const s=parseInt(o,10);return isNaN(s)?300:s}}),Object.defineProperty(q.prototype,"_noAutosync",{get:function(){const n=this.findChildren().storeEl;return this.dom.hasAttribute("data-ln-data-coordinator-no-autosync")||(n?n.hasAttribute("data-ln-data-store-no-autosync"):!1)}}),q.prototype.refreshConfig=function(){this.refreshMapper()},q.prototype._isStale=function(){if(this._staleThreshold===-1)return!1;const n=this.findChildren().store;return!n||!n.lastSyncedAt?!0:Date.now()/1e3-n.lastSyncedAt>this._staleThreshold},q.prototype._maybeSync=function(){const e=this.findChildren(),n=e.store;!n||n.initializationError||!e.connector||this._noAutosync||!n.isInitialized||n.isSyncing||(!n.hasCache||this._isStale())&&n.forceSync()},q.prototype._checkInitialSync=function(){const e=this,o=this.findChildren().store;o&&Promise.resolve(o.ready).then(function(){if(e._destroyed)return;const s=e.findChildren(),c=s.store;if(c&&c.initializationError){e._reportReconciliationError("store-initialize",c.initializationError,null);return}!c||!s.connector||e._noAutosync||c.isSyncing||(!c.hasCache||e._isStale())&&c.forceSync()}).catch(function(s){e._destroyed||e._reportReconciliationError("store-initialize",s,null)})},q.prototype.refreshMapper=function(){this.mapper=null,this.dom.querySelector("script[data-ln-mapper]")&&console.error("[ln-data-coordinator] Security Error: Inline script mappers using <script data-ln-mapper> are deprecated and disabled due to XSS vulnerability risks (unsafe-eval). Please register your mappers securely via window.lnCore.registerDataMapper() instead.");const n=this.dom.getAttribute("data-ln-data-coordinator-mapper")||this.dom.id;n&&window.lnCore&&typeof window.lnCore.getDataMapper=="function"&&(this.mapper=window.lnCore.getDataMapper(n)),this.mapper||(this.mapper={}),typeof this.mapper.ingress!="function"&&(this.mapper.ingress=function(o){return o}),typeof this.mapper.egress!="function"&&(this.mapper.egress=function(o){return o})},q.prototype.findChildren=function(){const e=this.dom.querySelector("[data-ln-data-store]"),n=this.dom.querySelector("[data-ln-api-connector], [data-ln-couchdb-connector]")||this.dom.querySelector("[data-ln-websocket-connector]"),o=this.dom.querySelector("[data-ln-api-queue]");return{storeEl:e,connectorEl:n,queueEl:o,store:e?e.lnDataStore:null,connector:n?n.lnApiConnector||n.lnCouchDbConnector||n.lnWebsocketConnector:null,queue:o?o.lnApiQueue:null}},q.prototype._handleSubmitRecord=function(e){const n=this.findChildren();if(!n.storeEl&&!n.connectorEl){console.warn('[ln-data-coordinator] form submit claimed but neither [data-ln-data-store] nor a connector child found in "'+(this._name||"")+'"');return}const o=e.data||{},s=o.id,c=o.expected_version,f=Object.assign({},o);delete f.id,delete f.expected_version;const g=e.method.toUpperCase();g==="POST"?this._fanOutCreate(n,f,e.action):(g==="PUT"||g==="PATCH")&&this._fanOutUpdate(n,s,f,c,e.action)},q.prototype._fanOutCreate=function(e,n,o){this.refreshMapper();const s="_temp_"+R();e.storeEl&&h(e.storeEl,"ln-data-store:request-create",{tempId:s,data:n}),e.queue?h(e.queueEl,"ln-api-queue:request-enqueue",{chainKey:s,op:"create",targetId:null,payload:this.mapper.egress(n),expectedVersion:null,meta:{tempId:s,action:o}}):e.connector&&h(e.connectorEl,C(e.connectorEl)+":request-create",{data:this.mapper.egress(n),url:o,meta:{entryId:R(),queued:!1,op:"create",tempId:s}})},q.prototype._fanOutUpdate=function(e,n,o,s,c){this.refreshMapper(),e.storeEl&&h(e.storeEl,"ln-data-store:request-update",{id:n,data:o}),e.queue?h(e.queueEl,"ln-api-queue:request-enqueue",{chainKey:n,op:"update",targetId:n,payload:this.mapper.egress(o),expectedVersion:s,meta:{id:n,action:c}}):e.connector&&h(e.connectorEl,C(e.connectorEl)+":request-update",{id:n,data:this.mapper.egress(o),expected_version:s,url:c,meta:{entryId:R(),queued:!1,op:"update",id:n}})},q.prototype._fanOutDelete=function(e,n){this.refreshMapper(),e.storeEl&&h(e.storeEl,"ln-data-store:request-delete",{id:n}),e.queue?h(e.queueEl,"ln-api-queue:request-enqueue",{chainKey:n,op:"delete",targetId:n,payload:null,expectedVersion:null,meta:{id:n}}):e.connector&&h(e.connectorEl,C(e.connectorEl)+":request-delete",{id:n,meta:{entryId:R(),queued:!1,op:"delete",id:n}})},q.prototype._fanOutBulkDelete=function(e,n){this.refreshMapper();const o=n.join(",");e.storeEl&&h(e.storeEl,"ln-data-store:request-bulk-delete",{ids:n}),e.queue?h(e.queueEl,"ln-api-queue:request-enqueue",{chainKey:o,op:"bulk-delete",targetId:null,payload:{ids:n},expectedVersion:null,meta:{bulkKey:o,ids:n}}):e.connector&&h(e.connectorEl,C(e.connectorEl)+":request-bulk-delete",{ids:n,meta:{entryId:R(),queued:!1,op:"bulk-delete",bulkKey:o}})},q.prototype._toastFromMessage=function(e){e&&h(window,"ln-toast:enqueue",{type:e.type||"success",title:e.title||"",message:e.body||""})},q.prototype._toastFromDict=function(e){const n=this._dict[e];n&&h(window,"ln-toast:enqueue",{type:"error",title:"",message:n})},q.prototype._requestStoreMutation=function(e,n,o){const s=e.storeEl;if(!s)return Promise.reject(new Error("Store element not found"));const c=R(),f=this._mutationReceipts.wait(c);return h(s,"ln-data-store:request-"+n,Object.assign({},o,{requestId:c})),f},q.prototype._reportReconciliationError=function(e,n,o){this._destroyed||h(this.dom,"ln-data-coordinator:error",{operation:e,error:n,meta:o||null})};function V(e){e._handlers={sync:function(n){e.refreshMapper();const o=e.findChildren();if(!o.store||!o.connector){console.warn("[ln-data-coordinator] Cannot sync: store or connector not found in subtree");return}h(o.connectorEl,C(o.connectorEl)+":request-sync",{since:n.detail.since,meta:{op:"sync"}})},requestPage:function(n){const o=e.findChildren();if(!o.connectorEl)return;const s=n.detail||{};h(o.connectorEl,C(o.connectorEl)+":request-query",{query:Object.assign({},s.query,{offset:s.offset,limit:s.limit,queryGen:s.queryGen})})},reqCreate:function(n){const o=e.findChildren();e._fanOutCreate(o,n.detail.data||{},n.detail.action)},reqUpdate:function(n){const o=e.findChildren();e._fanOutUpdate(o,n.detail.id,n.detail.data||{},n.detail.expected_version,n.detail.action)},reqDelete:function(n){const o=e.findChildren();e._fanOutDelete(o,n.detail.id)},reqBulkDelete:function(n){const o=e.findChildren();e._fanOutBulkDelete(o,n.detail.ids||[])},queueFailed:function(){e._toastFromDict("network")},queueSend:function(n){e.refreshMapper();const o=e.findChildren();if(!o.store||!o.connector||!o.queue)return;const s=n.detail||{},c=s.entryId,f=s.op,g=s.targetId,y=s.payload,b=s.expectedVersion,w=s.meta||{},E=w.action||null,_=s.idempotencyKey||c;f==="create"?h(o.connectorEl,C(o.connectorEl)+":request-create",{data:y,url:E,idempotencyKey:_,meta:{entryId:c,queued:!0,op:"create",tempId:w.tempId}}):f==="update"?h(o.connectorEl,C(o.connectorEl)+":request-update",{id:g,data:y,expected_version:b,url:E,idempotencyKey:_,meta:{entryId:c,queued:!0,op:"update",id:g}}):f==="delete"?h(o.connectorEl,C(o.connectorEl)+":request-delete",{id:g,idempotencyKey:_,meta:{entryId:c,queued:!0,op:"delete",id:g}}):f==="bulk-delete"?h(o.connectorEl,C(o.connectorEl)+":request-bulk-delete",{ids:y&&y.ids?y.ids:[],idempotencyKey:_,meta:{entryId:c,queued:!0,op:"bulk-delete",bulkKey:w.bulkKey}}):console.warn("[ln-data-coordinator] Unknown queue op:",f)},formSubmit:function(n){const o=n.target;if(n.defaultPrevented)return;const s=o.hasAttribute(i)?o.getAttribute(i):null;if(s===null)return;let c;if(s?c=e._owns(s):c=o.closest("[data-ln-data-coordinator]")===e.dom,!c)return;const f=le(o);if(f!=="POST"&&f!=="PUT"&&f!=="PATCH")return;n.preventDefault();const g=ce(o);delete g._method,delete g._token,e._handleSubmitRecord({data:g,method:f,action:o.getAttribute("action")||""})},connFetched:function(n){const o=n.detail.meta||{},s=e.findChildren();e.refreshMapper();const c=n.detail.data;let f=[],g=[],y=null;Array.isArray(c)?(f=c,y=Math.floor(Date.now()/1e3)):c&&(f=Array.isArray(c.data)?c.data:[],g=Array.isArray(c.deleted)?c.deleted:[],y=c.synced_at!==void 0?c.synced_at:c.since!==void 0?c.since:null);const b=f.map(w=>e.mapper.ingress(w));if(s.store&&!s.store.initializationError)o.kind?o.kind==="table"||o.kind==="list"||o.kind==="chart"?s.store.applyQuery(b,{total:n.detail.total}).then(function(w){o.queryGen!=null&&!e._isCurrentGen(o.targetEl,o.queryGen)||(h(o.targetEl,"ln-"+o.kind+":set-loading",{loading:!1}),h(o.targetEl,"ln-"+o.kind+":set-data",{data:w,total:n.detail.total!==void 0?n.detail.total:w.length,filtered:n.detail.filtered!==void 0?n.detail.filtered:w.length,offset:n.detail.offset,queryGen:n.detail.queryGen}),e._boundDelivered.set(o.targetEl,!0))}):o.kind==="options"?s.store.applyQuery(b,{total:n.detail.total}).then(function(){return s.store.getAll({})}).then(function(w){o.queryGen!=null&&!e._isCurrentGen(o.targetEl,o.queryGen)||h(o.targetEl,"ln-options:set-data",{data:w.data})}):o.kind==="stat"&&s.store.applyQuery(b,{total:n.detail.total}).then(function(){if(o.queryGen!=null&&!e._isCurrentGen(o.targetEl,o.queryGen))return;const w=n.detail.filtered!==void 0?n.detail.filtered:n.detail.total!==void 0?n.detail.total:b.length;h(o.targetEl,"ln-stat:set-count",{count:w})}):s.store.applySync(b,g,y||Math.floor(Date.now()/1e3),{total:n.detail.total,filtered:n.detail.filtered,offset:n.detail.offset,queryGen:n.detail.queryGen,targetEl:o.targetEl});else if(o.targetEl&&o.kind){if(o.kind==="table"||o.kind==="list"||o.kind==="chart")h(o.targetEl,"ln-"+o.kind+":set-loading",{loading:!1}),h(o.targetEl,"ln-"+o.kind+":set-data",{data:b,total:n.detail.total!==void 0?n.detail.total:b.length,filtered:n.detail.filtered!==void 0?n.detail.filtered:b.length,offset:n.detail.offset,queryGen:n.detail.queryGen}),e._boundDelivered.set(o.targetEl,!0);else if(o.kind==="options")h(o.targetEl,"ln-options:set-data",{data:b});else if(o.kind==="stat"){const w=n.detail.filtered!==void 0?n.detail.filtered:n.detail.total!==void 0?n.detail.total:b.length;h(o.targetEl,"ln-stat:set-count",{count:w})}}},connCreated:function(n){const o=e.findChildren(),s=n.detail.meta||{},c=e.mapper.ingress(n.detail.record);(o.storeEl?e._requestStoreMutation(o,"update",{id:s.tempId,data:c}):Promise.resolve()).then(function(){e._toastFromMessage(n.detail.message),s.queued&&o.queue&&h(o.queueEl,"ln-api-queue:resolve-create",{entryId:s.entryId,oldKey:s.tempId,newId:c.id})}).catch(function(g){e._reportReconciliationError("create-reconcile",g,s)})},connUpdated:function(n){const o=e.findChildren(),s=n.detail.meta||{},c=e.mapper.ingress(n.detail.record);(o.storeEl?e._requestStoreMutation(o,"update",{id:s.id,data:c}):Promise.resolve()).then(function(){e._toastFromMessage(n.detail.message),s.queued&&o.queue&&h(o.queueEl,"ln-api-queue:ack",{entryId:s.entryId})}).catch(function(g){e._reportReconciliationError("update-reconcile",g,s)})},connDeleted:function(n){const o=e.findChildren(),s=n.detail.meta||{};e._toastFromMessage(n.detail.message),s.queued&&o.queue&&h(o.queueEl,"ln-api-queue:ack",{entryId:s.entryId})},connBulkDeleted:function(n){const o=e.findChildren(),s=n.detail.meta||{};e._toastFromMessage(n.detail.message),s.queued&&o.queue&&h(o.queueEl,"ln-api-queue:ack",{entryId:s.entryId})},connError:function(n){const o=n.detail||{},s=o.meta||{},c=s.op||o.action,f=o.status||o.error&&o.error.status||0,g=e.findChildren();if(c==="sync"){g.storeEl&&h(g.storeEl,"ln-data-store:request-sync-failed",{error:o.error,status:f}),console.error("[ln-data-coordinator] Sync failed:",o.error);return}if(c==="query"){s.targetEl&&s.kind&&(h(s.targetEl,"ln-"+s.kind+":set-loading",{loading:!1}),(s.kind==="table"||s.kind==="list")&&h(s.targetEl,"ln-"+s.kind+":page-failed",{offset:s.offset})),e._reportReconciliationError("query",o.error||o,s);return}const y=f===401||f===419,b=f===0||f>=500,w=f===409||f===412;if(y){e._toastFromDict("auth"),s.queued&&g.queue&&h(g.queueEl,"ln-api-queue:nack",{entryId:s.entryId,reason:"auth"});return}if(b){s.queued&&g.queue?h(g.queueEl,"ln-api-queue:nack",{entryId:s.entryId,reason:"retry"}):e._toastFromDict("network");return}let E=Promise.resolve();if(w&&c==="update"){const _=o.data&&o.data.remote?e.mapper.ingress(o.data.remote):null;_&&g.storeEl&&(E=e._requestStoreMutation(g,"update",{id:s.id,data:_})),e._toastFromDict("conflict")}else c==="create"&&g.storeEl&&(E=e._requestStoreMutation(g,"delete",{id:s.tempId})),e._toastFromDict("rejected");s.queued&&g.queue?E.then(function(){h(g.queueEl,"ln-api-queue:nack",{entryId:s.entryId,reason:"drop"})}).catch(function(_){e._reportReconciliationError("deterministic-reconcile",_,s)}):E.catch(function(_){e._reportReconciliationError("deterministic-reconcile",_,s)})},storeInitialized:function(n){const o=e.findChildren(),s=o.store;if(!s||s.initializationError||!o.connector||e._noAutosync||s.isSyncing)return;(n.detail||{}).hasCache?e._isStale()&&s.forceSync():s.forceSync()},socketConnected:function(){const n=e.findChildren(),o=n.store;!o||o.initializationError||!n.connector||e._noAutosync||!o.isInitialized||o.isSyncing||o.forceSync()},reqTableData:function(n){e._serveData(n,"table")},reqListData:function(n){e._serveData(n,"list")},reqChartData:function(n){e._serveData(n,"chart")},reqOptions:function(n){e._serveOptions(n)},reqStat:function(n){e._serveStat(n)},refreshQuery:function(){e._refreshAll(null,!0)},refresh:function(n){e._mutationReceipts.resolve(n.detail),e._refreshAll(null,!1)},mutationError:function(n){e._mutationReceipts.reject(n.detail)},refreshSynced:function(n){n.detail&&n.detail.changed&&e._refreshAll(n.detail.meta,!1)},searchChange:function(n){n.preventDefault();const o=n.detail&&n.detail.term!=null?n.detail.term:"";o!==(e.dom.getAttribute(a)||"")&&e.dom.setAttribute(a,o)},filterChange:function(n){n.preventDefault();const o=n.detail&&n.detail.key;if(!o)return;const s=(n.detail.values||[]).slice(),c=e._currentQuery().filters,f=c[o];if(f?f.length===s.length&&f.every((w,E)=>w===s[E]):!s.length)return;s.length?c[o]=s:delete c[o];const y=new URLSearchParams;Object.keys(c).forEach(function(w){c[w].forEach(function(E){y.append(w,E)})});const b=y.toString();b?e.dom.setAttribute(d,b):e.dom.removeAttribute(d)},sortChange:function(n){n.preventDefault();const o=n.detail&&n.detail.field,s=n.detail&&n.detail.direction,c=o&&s&&s!=="none"?{field:o,direction:s}:null,f=e._currentQuery().sort;!f&&!c||f&&c&&f.field===c.field&&f.direction===c.direction||(c?(e.dom.setAttribute(l,c.field),e.dom.setAttribute(u,c.direction)):(e.dom.removeAttribute(l),e.dom.removeAttribute(u)))}},e.dom.addEventListener("ln-data-store:request-remote-sync",e._handlers.sync),e.dom.addEventListener("ln-data-store:request-page",e._handlers.requestPage),e.dom.addEventListener("ln-data-coordinator:request-create",e._handlers.reqCreate),e.dom.addEventListener("ln-data-coordinator:request-update",e._handlers.reqUpdate),e.dom.addEventListener("ln-data-coordinator:request-delete",e._handlers.reqDelete),e.dom.addEventListener("ln-data-coordinator:request-bulk-delete",e._handlers.reqBulkDelete),e.dom.addEventListener("ln-api-queue:send",e._handlers.queueSend),e.dom.addEventListener("ln-api-queue:failed",e._handlers.queueFailed),e.dom.addEventListener("ln-data-store:initialized",e._handlers.storeInitialized),e.dom.addEventListener("ln-websocket-connector:connected",e._handlers.socketConnected),document.addEventListener("submit",e._handlers.formSubmit),Q.forEach(function(n){e.dom.addEventListener(n+":fetched",e._handlers.connFetched),e.dom.addEventListener(n+":created",e._handlers.connCreated),e.dom.addEventListener(n+":updated",e._handlers.connUpdated),e.dom.addEventListener(n+":deleted",e._handlers.connDeleted),e.dom.addEventListener(n+":bulk-deleted",e._handlers.connBulkDeleted),e.dom.addEventListener(n+":error",e._handlers.connError)}),document.addEventListener("ln-table:request-data",e._handlers.reqTableData),document.addEventListener("ln-list:request-data",e._handlers.reqListData),document.addEventListener("ln-chart:request-data",e._handlers.reqChartData),document.addEventListener("ln-options:request-data",e._handlers.reqOptions),document.addEventListener("ln-stat:request-count",e._handlers.reqStat),e.dom.addEventListener("ln-data-store:ready",e._handlers.refresh),e.dom.addEventListener("ln-data-store:created",e._handlers.refresh),e.dom.addEventListener("ln-data-store:updated",e._handlers.refresh),e.dom.addEventListener("ln-data-store:deleted",e._handlers.refresh),e.dom.addEventListener("ln-data-store:mutation-error",e._handlers.mutationError),e.dom.addEventListener("ln-data-store:synced",e._handlers.refreshSynced),e.dom.addEventListener("ln-data-store:query-changed",e._handlers.refreshQuery),e.dom.addEventListener("ln-search:change",e._handlers.searchChange),e.dom.addEventListener("ln-filter:change",e._handlers.filterChange),e.dom.addEventListener("ln-sort:change",e._handlers.sortChange)}q.prototype._owns=function(e){return!!e&&e===this._name},q.prototype._currentQuery=function(){const e=this.dom.getAttribute(l),n=this.dom.getAttribute(u),o=new URLSearchParams(this.dom.getAttribute(d)||""),s={};for(const c of new Set(o.keys()))s[c]=o.getAll(c);return{search:this.dom.getAttribute(a)||"",filters:s,sort:e&&n?{field:e,direction:n}:null}},q.prototype._nextQueryGen=function(e){const n=(this._queryGens.get(e)||0)+1;return this._queryGens.set(e,n),n},q.prototype._isCurrentGen=function(e,n){return this._queryGens.get(e)===n},q.prototype._serveData=function(e,n){const o=e.target,s=n==="table"?"data-ln-table-source":n==="list"?"data-ln-list-source":"data-ln-chart-source",c=o.getAttribute(s);if(!c||!this._owns(c))return;const f=e.detail||{},g=We(f);this._boundQueries.set(o,g);const y=this.findChildren(),b=this,w=y.store;return(w&&w.ready?w.ready:Promise.resolve()).then(function(){if(b._destroyed)return;const _=j(w,y.connector),k=se(g,b._currentQuery());if(_==="remote"){const I=b._nextQueryGen(o);h(o,"ln-"+n+":set-loading",{loading:!0}),h(y.connectorEl,C(y.connectorEl)+":request-query",{query:k,meta:{targetEl:o,kind:n,offset:k.offset,limit:k.limit,queryGen:I}});return}if(_!=="store"){h(o,"ln-"+n+":set-loading",{loading:!1});return}const x=P(w,y.connector,_),D=x?b._nextQueryGen(o):null;return x&&h(y.connectorEl,C(y.connectorEl)+":request-query",{query:k,meta:{targetEl:o,kind:n,offset:k.offset,limit:k.limit,queryGen:D}}),w.getAll(k).then(function(I){if(b._destroyed||!b._boundDelivered||x&&!b._isCurrentGen(o,D))return;const H={data:I.data,total:I.total,filtered:I.filtered,offset:f.offset!==void 0?f.offset:I.offset,queryGen:f.queryGen!==void 0?f.queryGen:I.queryGen,provisional:x||I.provisional===!0};h(o,"ln-"+n+":set-data",H),b._boundDelivered.set(o,!0)})}).catch(function(_){b._destroyed||(h(o,"ln-"+n+":set-loading",{loading:!1}),h(b.dom,"ln-data-coordinator:error",{operation:"query",kind:n,store:c,target:o,error:_}))})},q.prototype._serveOptions=function(e){const n=e.target,o=n.getAttribute("data-ln-options");if(!this._owns(o))return;const s=this.findChildren(),c=s.store,f=c&&c.ready?c.ready:Promise.resolve(),g=this;return f.then(function(){if(g._destroyed)return;const y=j(c,s.connector);if(y==="remote"){const E=g._nextQueryGen(n);h(s.connectorEl,C(s.connectorEl)+":request-query",{query:{},meta:{targetEl:n,kind:"options",queryGen:E}});return}if(y!=="store")return;const b=P(c,s.connector,y),w=b?g._nextQueryGen(n):null;return b&&h(s.connectorEl,C(s.connectorEl)+":request-query",{query:{},meta:{targetEl:n,kind:"options",queryGen:w}}),c.getAll({}).then(function(E){g._destroyed||b&&!g._isCurrentGen(n,w)||h(n,"ln-options:set-data",{data:E.data})})}).catch(function(y){g._destroyed||g._reportReconciliationError("options-query",y,{targetEl:n,kind:"options"})})},q.prototype._serveStat=function(e){const n=e.target,o=n.getAttribute("data-ln-stat");if(!this._owns(o))return;const s=e.detail&&e.detail.filters?e.detail.filters:null,c=this.findChildren(),f=c.store,g=f&&f.ready?f.ready:Promise.resolve(),y=this;return g.then(function(){if(y._destroyed)return;const b=s&&Object.keys(s).length>0,w=!!(c.connector&&f&&(f.windowed&&b||f.noLocalQuery)),E=w?"remote":j(f,c.connector);if(E==="remote"){const x=y._nextQueryGen(n);h(c.connectorEl,C(c.connectorEl)+":request-query",{query:{filters:s},meta:{targetEl:n,kind:"stat",queryGen:x}});return}if(E!=="store")return;const _=!w&&P(f,c.connector,E),k=_?y._nextQueryGen(n):null;return _&&h(c.connectorEl,C(c.connectorEl)+":request-query",{query:{filters:s},meta:{targetEl:n,kind:"stat",queryGen:k}}),f.count(s).then(function(x){y._destroyed||_&&!y._isCurrentGen(n,k)||h(n,"ln-stat:set-count",{count:x})})}).catch(function(b){y._destroyed||y._reportReconciliationError("stat-query",b,{targetEl:n,kind:"stat"})})},q.prototype._refreshAll=function(e,n){const o=this,s=document.querySelectorAll("[data-ln-table-source],[data-ln-list-source],[data-ln-chart-source],[data-ln-options],[data-ln-stat]");for(let c=0;c<s.length;c++){const f=s[c];let g,y;if(f.hasAttribute("data-ln-table-source")?(g=f.getAttribute("data-ln-table-source"),y="table"):f.hasAttribute("data-ln-list-source")?(g=f.getAttribute("data-ln-list-source"),y="list"):f.hasAttribute("data-ln-chart-source")?(g=f.getAttribute("data-ln-chart-source"),y="chart"):f.hasAttribute("data-ln-options")?(g=f.getAttribute("data-ln-options"),y="options"):f.hasAttribute("data-ln-stat")&&(g=f.getAttribute("data-ln-stat"),y="stat"),!o._owns(g))continue;const b=o.findChildren(),w=b.store;if(y==="table"||y==="list"){const E=y==="table"?"data-ln-table-window":"data-ln-list-window";if(f.hasAttribute(E)){h(f,"ln-"+y+(n?":request-invalidate":":request-revalidate"),{});continue}}if(y==="table"||y==="list"||y==="chart"){const E=o._boundQueries.get(f)||{sort:null,filters:{},search:""},_=se(E,o._currentQuery());if(j(w,b.connector)==="remote"){const D=o._nextQueryGen(f);h(f,"ln-"+y+":set-loading",{loading:!0}),h(b.connectorEl,C(b.connectorEl)+":request-query",{query:_,meta:{targetEl:f,kind:y,offset:_.offset,limit:_.limit,queryGen:D}});continue}const k=P(w,b.connector,j(w,b.connector)),x=k?o._nextQueryGen(f):null;k&&h(b.connectorEl,C(b.connectorEl)+":request-query",{query:_,meta:{targetEl:f,kind:y,offset:_.offset,limit:_.limit,queryGen:x}}),(function(D,I,H,He){w.getAll(_).then(function(T){if(o._destroyed||!o._boundDelivered||H&&!o._isCurrentGen(D,He))return;const Je={data:T.data,total:e&&e.total!==void 0?e.total:T.total,filtered:e&&e.filtered!==void 0?e.filtered:T.filtered,offset:T.offset!==void 0?T.offset:e&&e.offset!==void 0?e.offset:E.offset,queryGen:T.queryGen!==void 0?T.queryGen:e&&e.queryGen!==void 0?e.queryGen:E.queryGen};h(D,"ln-"+I+":set-loading",{loading:!1}),h(D,"ln-"+I+":set-data",Je),o._boundDelivered.set(D,!0)}).catch(function(){})})(f,y,k,x)}else if(y==="options")(function(E){w.getAll({}).then(function(_){o._destroyed||h(E,"ln-options:set-data",{data:_.data})}).catch(function(){})})(f);else if(y==="stat"){const E=f.getAttribute("data-ln-stat-filter");let _=null;if(E){const k=E.indexOf(":");if(k!==-1){const x=E.slice(0,k).trim(),D=E.slice(k+1).trim();x&&(_={},_[x]=[D])}}(function(k,x){w.count(x).then(function(D){o._destroyed||h(k,"ln-stat:set-count",{count:D})}).catch(function(){})})(f,_)}}},q.prototype.destroy=function(){if(!this.dom[r])return;this._destroyed=!0;const e=this;e._handlers&&(e.dom.removeEventListener("ln-data-store:request-remote-sync",e._handlers.sync),e.dom.removeEventListener("ln-data-store:request-page",e._handlers.requestPage),e.dom.removeEventListener("ln-data-coordinator:request-create",e._handlers.reqCreate),e.dom.removeEventListener("ln-data-coordinator:request-update",e._handlers.reqUpdate),e.dom.removeEventListener("ln-data-coordinator:request-delete",e._handlers.reqDelete),e.dom.removeEventListener("ln-data-coordinator:request-bulk-delete",e._handlers.reqBulkDelete),e.dom.removeEventListener("ln-api-queue:send",e._handlers.queueSend),e.dom.removeEventListener("ln-api-queue:failed",e._handlers.queueFailed),e.dom.removeEventListener("ln-data-store:initialized",e._handlers.storeInitialized),e.dom.removeEventListener("ln-websocket-connector:connected",e._handlers.socketConnected),document.removeEventListener("submit",e._handlers.formSubmit),Q.forEach(function(n){e.dom.removeEventListener(n+":fetched",e._handlers.connFetched),e.dom.removeEventListener(n+":created",e._handlers.connCreated),e.dom.removeEventListener(n+":updated",e._handlers.connUpdated),e.dom.removeEventListener(n+":deleted",e._handlers.connDeleted),e.dom.removeEventListener(n+":bulk-deleted",e._handlers.connBulkDeleted),e.dom.removeEventListener(n+":error",e._handlers.connError)}),document.removeEventListener("ln-table:request-data",e._handlers.reqTableData),document.removeEventListener("ln-list:request-data",e._handlers.reqListData),document.removeEventListener("ln-chart:request-data",e._handlers.reqChartData),document.removeEventListener("ln-options:request-data",e._handlers.reqOptions),document.removeEventListener("ln-stat:request-count",e._handlers.reqStat),e.dom.removeEventListener("ln-data-store:ready",e._handlers.refresh),e.dom.removeEventListener("ln-data-store:created",e._handlers.refresh),e.dom.removeEventListener("ln-data-store:updated",e._handlers.refresh),e.dom.removeEventListener("ln-data-store:deleted",e._handlers.refresh),e.dom.removeEventListener("ln-data-store:mutation-error",e._handlers.mutationError),e.dom.removeEventListener("ln-data-store:synced",e._handlers.refreshSynced),e.dom.removeEventListener("ln-data-store:query-changed",e._handlers.refreshQuery),e.dom.removeEventListener("ln-search:change",e._handlers.searchChange),e.dom.removeEventListener("ln-filter:change",e._handlers.filterChange),e.dom.removeEventListener("ln-sort:change",e._handlers.sortChange),e._handlers=null),e._boundQueries=null,e._boundDelivered=null,e._queryGens=null,e._queueQueryRefresh=null,e._mutationReceipts.close(new Error("Data coordinator destroyed")),e._mutationReceipts=null,L.delete(this),W(),delete this.dom[r]},Fe(t,r,q,"ln-data-coordinator",{attributes:S})})()})();
|