@kedem/okdb 1.0.1 → 1.0.4
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/bin/okdb.js +1 -1
- package/keys/public.pem +3 -0
- package/okdb.js +1 -1
- package/package.json +2 -2
- package/public/admin-app.js +1 -1
- package/public/components/admin-route-host.ok.js +1 -1
- package/public/components/env-picker.ok.js +1 -1
- package/public/components/field-path-input.ok.js +1 -1
- package/public/components/field.html +154 -2
- package/public/components/geo-map.ok.js +1 -1
- package/public/components/ok-cron-input.ok.js +1 -1
- package/public/components/ok-dropzone.ok.js +1 -1
- package/public/components/ok-js-input.ok.js +1 -1
- package/public/components/ok-json-input.ok.js +1 -1
- package/public/components/ok-text-monaco-input.ok.js +1 -1
- package/public/components/theme-toggle.ok.js +1 -1
- package/public/index.html +29 -2
- package/public/layouts/_default.ok.html +1 -1
- package/public/layouts/okdb-cube.ok.html +1 -1
- package/public/login-app.js +1 -1
- package/public/login.html +205 -1
- package/public/modules/ok.js +1 -1
- package/public/sections/api/index.ok.html +1 -1
- package/public/sections/api/parts/api-endpoint.ok.js +1 -1
- package/public/sections/auth/index.ok.html +1 -1
- package/public/sections/auth/modals/create-token-modal.ok.js +1 -1
- package/public/sections/auth/modals/edit-token-modal.ok.js +1 -1
- package/public/sections/auth/modals/perm-info-popover.ok.js +1 -1
- package/public/sections/auth/parts/token-detail.ok.js +1 -1
- package/public/sections/auth/parts/token-list.ok.js +1 -1
- package/public/sections/db/index.ok.html +1 -1
- package/public/sections/db/modals/add-item-modal.ok.js +1 -1
- package/public/sections/db/modals/create-env-modal.ok.js +1 -1
- package/public/sections/db/modals/create-fts-modal.ok.js +1 -1
- package/public/sections/db/modals/create-index-modal.ok.js +1 -1
- package/public/sections/db/modals/create-pipeline-modal.ok.js +1 -1
- package/public/sections/db/modals/demo-env-modal.ok.js +1 -1
- package/public/sections/db/modals/remove-env-modal.ok.js +1 -1
- package/public/sections/db/modals/schema-edit-modal.ok.js +1 -1
- package/public/sections/db/parts/db-overview.ok.js +1 -1
- package/public/sections/db/parts/db-pipelines-panel.ok.js +1 -1
- package/public/sections/db/parts/edit-row.ok.js +1 -1
- package/public/sections/db/parts/tm-timeline.ok.js +1 -1
- package/public/sections/db/parts/type-changelog.ok.js +1 -1
- package/public/sections/db/parts/type-list.ok.js +1 -1
- package/public/sections/db/parts/type-pipelines-tab.ok.js +1 -1
- package/public/sections/db/parts/type-schema-tab.ok.js +1 -1
- package/public/sections/db/parts/type-viewer.ok.js +1 -1
- package/public/sections/db/parts/type-violations-tab.ok.js +1 -1
- package/public/sections/docs/index.ok.html +1 -1
- package/public/sections/embeddings/index.ok.html +1 -1
- package/public/sections/embeddings/modals/register-model-modal.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-create-panel.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-embedder-panel.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-engine-declaration-editor.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-engine-list.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-indexer-panel.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-lifecycle-bar.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-model-catalog.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-overview.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-search-panel.ok.js +1 -1
- package/public/sections/embeddings/parts/embed-worker-panel.ok.js +1 -1
- package/public/sections/embeddings/parts/embeddings-engine-panel.ok.js +1 -1
- package/public/sections/embeddings/parts/engines-overview.ok.js +1 -1
- package/public/sections/embeddings/parts/pipeline-create-panel.ok.js +1 -1
- package/public/sections/engines/engine-panel-shared-style.js +1 -1
- package/public/sections/engines/engine-ui-utils.js +1 -1
- package/public/sections/engines/index.ok.html +1 -1
- package/public/sections/engines/modals/engine-modal.ok.js +1 -1
- package/public/sections/engines/parts/engine-declaration-editor.ok.js +1 -1
- package/public/sections/engines/parts/engine-lifecycle-actions.ok.js +1 -1
- package/public/sections/engines/parts/engine-panel-shell.ok.js +1 -1
- package/public/sections/engines/parts/engine-resource-card.ok.js +1 -1
- package/public/sections/engines/parts/engine-row-item.ok.js +1 -1
- package/public/sections/engines/parts/generic-engine-panel.ok.js +1 -1
- package/public/sections/files/index.ok.html +1 -1
- package/public/sections/files/parts/files-blob-status.ok.js +1 -1
- package/public/sections/files/parts/files-collection-list.ok.js +1 -1
- package/public/sections/files/parts/files-collection-panel.ok.js +1 -1
- package/public/sections/files/parts/files-file-list.ok.js +1 -1
- package/public/sections/files/parts/files-overview.ok.js +1 -1
- package/public/sections/files/parts/files-path-browser.ok.js +1 -1
- package/public/sections/files/parts/files-upload-panel.ok.js +1 -1
- package/public/sections/functions/index.ok.html +1 -1
- package/public/sections/functions/modals/function-modal.ok.js +1 -1
- package/public/sections/functions/parts/function-detail.ok.js +1 -1
- package/public/sections/functions/parts/function-logs.ok.js +1 -1
- package/public/sections/functions/parts/function-runner.ok.js +1 -1
- package/public/sections/functions/parts/functions-list.ok.js +1 -1
- package/public/sections/license/index.ok.html +1 -1
- package/public/sections/license/parts/license-panel.ok.js +1 -1
- package/public/sections/processors/index.ok.html +1 -1
- package/public/sections/queue/index.ok.html +1 -1
- package/public/sections/queue/modals/create-bucket-modal.ok.js +1 -1
- package/public/sections/queue/modals/edit-bucket-modal.ok.js +1 -1
- package/public/sections/queue/modals/edit-job-modal.ok.js +1 -1
- package/public/sections/queue/modals/enqueue-job-modal.ok.js +1 -1
- package/public/sections/queue/modals/job-type-modal.ok.js +1 -1
- package/public/sections/queue/parts/ok-job-form.ok.js +1 -1
- package/public/sections/queue/parts/queue-buckets.ok.js +1 -1
- package/public/sections/queue/parts/queue-job-types.ok.js +1 -1
- package/public/sections/queue/parts/queue-jobs.ok.js +1 -1
- package/public/sections/queue/parts/queue-types.ok.js +1 -1
- package/public/sections/queue/parts/queue-workers.ok.js +1 -1
- package/public/sections/sync/index.ok.html +1 -1
- package/public/sections/sync/parts/sync-node-detail.ok.js +1 -1
- package/public/sections/sync/parts/sync-retention.ok.js +1 -1
- package/public/sections/sync/parts/sync-topology.ok.js +1 -1
- package/public/sections/system/index.ok.html +1 -1
- package/public/sections/system/modals/data-ops-modal.ok.js +1 -1
- package/public/sections/system/parts/system-api-panel.ok.js +1 -1
- package/public/sections/system/parts/system-auth-panel.ok.js +1 -1
- package/public/sections/system/parts/system-log-history.ok.js +1 -1
- package/public/sections/system/parts/system-log.ok.js +1 -1
- package/public/sections/system/parts/system-status.ok.js +1 -1
- package/public/sections/system/parts/system-sync-panel.ok.js +1 -1
- package/public/sections/views/index.ok.html +1 -1
- package/public/sections/views/modals/create-view-modal.ok.js +1 -1
- package/public/sections/views/parts/view-detail.ok.js +1 -1
- package/public/sections/views/parts/views-list.ok.js +1 -1
- package/public/sections/views/parts/views-overview.ok.js +1 -1
- package/public/setup-app.js +1 -1
- package/public/setup.html +189 -1
- package/public/stores/auth-store.js +1 -1
- package/public/stores/events-store.js +1 -1
- package/public/stores/functions-store.js +1 -1
- package/public/stores/okdb-store.js +1 -1
- package/public/stores/theme-store.js +1 -1
- package/public/test-cron-input.html +53 -3
- package/public/test-json-input.html +182 -3
- package/public/util/permissions.js +1 -1
- package/public/util/sift-schema.js +1 -1
- package/public/vendor/okjs/ok.esm.min.js +1 -2
- package/public/view-models/type-query-vm.js +1 -1
- package/okdb-data/default/data.mdb +0 -0
- package/okdb-data/default/lock.mdb +0 -0
- package/okdb-data/~log/data.mdb +0 -0
- package/okdb-data/~log/lock.mdb +0 -0
- package/okdb-data/~system/data.mdb +0 -0
- package/okdb-data/~system/lock.mdb +0 -0
- package/public/images/logo.png +0 -0
- package/public/images/logo.svg +0 -333
|
@@ -1 +1 @@
|
|
|
1
|
-
const _0x5f15ce=_0x3dca;function _0x19c4(){const _0x4e211b=['catch','additionalProps','key','676244sLZRMc','nullable','editDefinition','\x20more)','typesList','ref','const','Schema\x20removed','definition','string','isArray','_init','Schema\x20saved','shared','description','close','exclusiveMaximum','8rcSJkt','Inferring\x20from\x20','/types','items','5fGCTJT','parse','application/json','stringify','envApiBase','dirty','minItems','result','has','557082tNMrhU','name','mode','expanded','children','flat','status','maxItems','length','childrenAdditionalProps','loadTypesList','keys','schema-edit-modal','saveError','json','minLength','refType','entries','maxLength','types','onDelete','default','enforce','\x20documents…','297790gchXNC','26089525ubGBjM','includes','(item)','Property\x20\x22','$ok','value','\x22?\x20Validation\x20will\x20be\x20disabled.','trim','slice','statusText','required','info','exclusiveMinimum','newPropName','Schema\x20conflicts\x20with\x20existing\x20data','success','editEnforce','details','object','$attr','_extra','find','doc','\x0a<div\x20class=\x22sem-root\x22>\x0a\x0a\x20\x20<if\x20:=\x22saveBusy\x22>\x0a\x20\x20\x20\x20<ok-overlay>\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22loader-center\x22><ok-icon\x20name=\x22loader\x22\x20class=\x22spin\x22\x20style=\x22width:32px;height:32px;\x22></ok-icon></div>\x0a\x20\x20\x20\x20</ok-overlay>\x0a\x20\x20</if>\x0a\x0a\x20\x20<!--\x20Toolbar\x20-->\x0a\x20\x20<div\x20class=\x22sem-toolbar\x22>\x0a\x20\x20\x20\x20<div\x20class=\x22seg-toggle\x22>\x0a\x20\x20\x20\x20\x20\x20<button\x20:class=\x22mode\x20===\x20\x27visual\x27\x20?\x20\x27active\x27\x20:\x20\x27\x27\x22\x20@click=\x22switchToVisual()\x22>Visual</button>\x0a\x20\x20\x20\x20\x20\x20<button\x20:class=\x22mode\x20===\x20\x27json\x27\x20?\x20\x27active\x27\x20:\x20\x27\x27\x22\x20@click=\x22switchToJson()\x22>JSON</button>\x0a\x20\x20\x20\x20</div>\x0a\x0a\x20\x20\x20\x20<if\x20:=\x22!hideEnforce\x22>\x0a\x20\x20\x20\x20\x20\x20<label\x20style=\x22font-size:13px;\x20display:flex;\x20align-items:center;\x20gap:6px;\x20cursor:pointer;\x20user-select:none;\x20margin-left:16px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22checkbox\x22\x20:checked=\x22editEnforce\x22\x20@change=\x22setEditEnforce($event.target.checked)\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20Enforce\x20mode\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:11px;\x20opacity:.4;\x22>(reject\x20writes\x20that\x20violate)</span>\x0a\x20\x20\x20\x20\x20\x20</label>\x0a\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20<div\x20style=\x22margin-left:auto;\x20display:flex;\x20gap:8px;\x22>\x0a\x20\x20\x20\x20\x20\x20<button\x20@click=\x22generateFromData()\x22\x20class=\x22btn-icon\x22\x20style=\x22font-size:11px;\x20padding:3px\x2010px;\x20opacity:.75;\x22\x20title=\x22Sample\x20latest\x20documents\x20to\x20build\x20a\x20schema\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<ok-icon\x20name=\x22zap\x22></ok-icon>\x20Infer\x20from\x20data\x0a\x20\x20\x20\x20\x20\x20</button>\x0a\x20\x20\x20\x20</div>\x0a\x20\x20</div>\x0a\x0a\x20\x20<!--\x20═══════\x20Visual\x20mode\x20═══════\x20-->\x0a\x20\x20<if\x20:=\x22mode\x20===\x20\x27visual\x27\x22>\x0a\x20\x20<div\x20class=\x22sem-visual\x22>\x0a\x0a\x20\x20\x20\x20<!--\x20Properties\x20table\x20header\x20-->\x0a\x20\x20\x20\x20<div\x20class=\x22sem-props-hdr\x22>\x0a\x20\x20\x20\x20\x20\x20<div></div><div>Property</div><div>Type</div><div>Req</div><div>Null</div><div>Description</div><div></div>\x0a\x20\x20\x20\x20</div>\x0a\x0a\x20\x20\x20\x20<!--\x20Recursive\x20row\x20rendering\x20for\x20depth\x200\x20-->\x0a\x20\x20\x20\x20<each\x20:of=\x22rows\x22\x20let:item=\x22row\x22\x20let:index=\x22i\x22>\x0a\x0a\x20\x20\x20\x20\x20\x20<!--\x20Main\x20property\x20row\x20-->\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-props-row\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-expand-col\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20@click=\x22toggleRowExpanded(row)\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20class=\x22sem-expand-btn\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20:class=\x22row.expanded\x20?\x20\x27sem-expanded\x27\x20:\x20\x27\x27\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20title=\x22Toggle\x20details\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20>›</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-prop-name\x22><code>{{\x20row.name\x20}}</code></div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<select\x20:value=\x22row.type\x22\x20@change=\x22setRowField(row,\x20\x27type\x27,\x20$event.target.value)\x22\x20style=\x22min-width:90px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22string\x22>string</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22number\x22>number</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22integer\x22>integer</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22boolean\x22>boolean</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22object\x22>object</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22array\x22>array</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</select>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22text-align:center;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22checkbox\x22\x20:checked=\x22row.required\x22\x20@change=\x22toggleRowRequired(row)\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22text-align:center;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22checkbox\x22\x20:checked=\x22row.nullable\x22\x20@change=\x22toggleRowNullable(row)\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22overflow:hidden;\x20min-width:0;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22text\x22\x20:value=\x22row.description\x22\x20@input=\x22setRowField(row,\x20\x27description\x27,\x20$event.target.value)\x22\x20placeholder=\x22—\x22\x20style=\x22width:100%;\x20font-size:12px;\x20box-sizing:border-box;\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22display:flex;\x20align-items:center;\x20justify-content:center;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20@click=\x22removeProperty(rows,\x20i)\x22\x20style=\x22color:var(--okdb-danger);\x20background:none;\x20border:none;\x20cursor:pointer;\x20padding:2px\x206px;\x20font-size:14px;\x20line-height:1;\x22\x20title=\x22Remove\x20property\x22>×</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</div>\x0a\x0a\x20\x20\x20\x20\x20\x20<!--\x20──\x20Expanded\x20detail\x20panel\x20──\x20-->\x0a\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.expanded\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-detail-panel\x22>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<!--\x20──\x20String\x20constraints\x20──\x20-->\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.type\x20===\x20\x27string\x27\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-constraints-grid\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>Format</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<select\x20:value=\x22row.format\x20||\x20\x27\x27\x22\x20@change=\x22setRowConstraint(row,\x20\x27format\x27,\x20$event.target.value)\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22\x22>—</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22date-time\x22>date-time</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22date\x22>date</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22time\x22>time</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22email\x22>email</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22uri\x22>uri</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22uuid\x22>uuid</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22ipv4\x22>ipv4</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22ipv6\x22>ipv6</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22hostname\x22>hostname</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</select>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>Min\x20Length</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22number\x22\x20:value=\x22row.minLength\x20??\x20\x27\x27\x22\x20@input=\x22setRowConstraint(row,\x20\x27minLength\x27,\x20$event.target.value)\x22\x20min=\x220\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>Max\x20Length</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22number\x22\x20:value=\x22row.maxLength\x20??\x20\x27\x27\x22\x20@input=\x22setRowConstraint(row,\x20\x27maxLength\x27,\x20$event.target.value)\x22\x20min=\x220\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>Pattern</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22text\x22\x20:value=\x22row.pattern\x22\x20@input=\x22setRowConstraint(row,\x20\x27pattern\x27,\x20$event.target.value)\x22\x20placeholder=\x22regex…\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<!--\x20──\x20Number\x20/\x20Integer\x20constraints\x20──\x20-->\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.type\x20===\x20\x27number\x27\x20||\x20row.type\x20===\x20\x27integer\x27\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-constraints-grid\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>Minimum</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22number\x22\x20:value=\x22row.minimum\x20??\x20\x27\x27\x22\x20@input=\x22setRowConstraint(row,\x20\x27minimum\x27,\x20$event.target.value)\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>Maximum</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22number\x22\x20:value=\x22row.maximum\x20??\x20\x27\x27\x22\x20@input=\x22setRowConstraint(row,\x20\x27maximum\x27,\x20$event.target.value)\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>Excl.\x20Min</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22number\x22\x20:value=\x22row.exclusiveMinimum\x20??\x20\x27\x27\x22\x20@input=\x22setRowConstraint(row,\x20\x27exclusiveMinimum\x27,\x20$event.target.value)\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>Excl.\x20Max</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22number\x22\x20:value=\x22row.exclusiveMaximum\x20??\x20\x27\x27\x22\x20@input=\x22setRowConstraint(row,\x20\x27exclusiveMaximum\x27,\x20$event.target.value)\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>Multiple\x20Of</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22number\x22\x20:value=\x22row.multipleOf\x20??\x20\x27\x27\x22\x20@input=\x22setRowConstraint(row,\x20\x27multipleOf\x27,\x20$event.target.value)\x22\x20min=\x220\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<!--\x20──\x20Array\x20constraints\x20──\x20-->\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.type\x20===\x20\x27array\x27\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-constraints-grid\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>Min\x20Items</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22number\x22\x20:value=\x22row.minItems\x20??\x20\x27\x27\x22\x20@input=\x22setRowConstraint(row,\x20\x27minItems\x27,\x20$event.target.value)\x22\x20min=\x220\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>Max\x20Items</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22number\x22\x20:value=\x22row.maxItems\x20??\x20\x27\x27\x22\x20@input=\x22setRowConstraint(row,\x20\x27maxItems\x27,\x20$event.target.value)\x22\x20min=\x220\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>Unique</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label\x20style=\x22display:flex;\x20align-items:center;\x20gap:4px;\x20cursor:pointer;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22checkbox\x22\x20:checked=\x22row.uniqueItems\x22\x20@change=\x22setRowConstraint(row,\x20\x27uniqueItems\x27,\x20$event.target.checked)\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20unique\x20items\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<!--\x20──\x20Enum\x20(all\x20types)\x20──\x20-->\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-constraint-row\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>Enum</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22text\x22\x20:value=\x22enumToString(row.enum)\x22\x20@change=\x22setRowConstraint(row,\x20\x27enum\x27,\x20$event.target.value)\x22\x20placeholder=\x22comma-separated\x20values…\x22\x20style=\x22flex:1;\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22sem-hint\x22>e.g.\x20active,\x20inactive,\x20pending</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<!--\x20──\x20Foreign\x20Key\x20Reference\x20──\x20-->\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.type\x20===\x20\x27string\x27\x20||\x20row.type\x20===\x20\x27integer\x27\x20||\x20row.type\x20===\x20\x27number\x27\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-fk-section\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-fk-label\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<ok-icon\x20name=\x22link\x22\x20style=\x22width:12px;\x20height:12px;\x20opacity:.6;\x22></ok-icon>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20Foreign\x20Key\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-fk-row\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>Target\x20type</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<select\x20:value=\x22row.refType\x20||\x20\x27\x27\x22\x20@change=\x22setRowRef(row,\x20\x27refType\x27,\x20$event.target.value)\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22\x22>—\x20none\x20—</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<each\x20:of=\x22typesList\x22\x20let:item=\x22t\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20:value=\x22t\x22>{{\x20t\x20}}</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</each>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</select>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.refType\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label>On\x20delete</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<select\x20:value=\x22row.refOnDelete\x20||\x20\x27no_action\x27\x22\x20@change=\x22setRowRef(row,\x20\x27refOnDelete\x27,\x20$event.target.value)\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22no_action\x22>no\x20action</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22cascade\x22>cascade</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22set_null\x22>set\x20null</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22restrict\x22>restrict</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</select>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20@click=\x22clearRowRef(row)\x22\x20class=\x22sem-fk-clear\x22\x20title=\x22Remove\x20foreign\x20key\x22>×</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.refType\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-fk-hint\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20This\x20field\x20references\x20a\x20key\x20in\x20<strong>{{\x20row.refType\x20}}</strong>.\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.refOnDelete\x20===\x20\x27cascade\x27\x22>Deleting\x20the\x20target\x20will\x20delete\x20this\x20document.</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.refOnDelete\x20===\x20\x27set_null\x27\x22>Deleting\x20the\x20target\x20will\x20set\x20this\x20field\x20to\x20null.</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.refOnDelete\x20===\x20\x27restrict\x27\x22>Deleting\x20the\x20target\x20will\x20be\x20blocked\x20while\x20this\x20reference\x20exists.</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.refOnDelete\x20===\x20\x27no_action\x27\x22>Deleting\x20the\x20target\x20will\x20leave\x20this\x20field\x20as\x20a\x20dangling\x20reference.</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<!--\x20──\x20Array\x20items\x20schema\x20──\x20-->\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.type\x20===\x20\x27array\x27\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-nested-section\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-nested-label\x22>Item\x20Schema</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.items\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-nested-row\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<select\x20:value=\x22row.items.type\x22\x20@change=\x22setRowField(row.items,\x20\x27type\x27,\x20$event.target.value)\x22\x20style=\x22min-width:90px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22string\x22>string</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22number\x22>number</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22integer\x22>integer</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22boolean\x22>boolean</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22object\x22>object</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22array\x22>array</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</select>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.items.type\x20===\x20\x27string\x27\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<select\x20:value=\x22row.items.format\x20||\x20\x27\x27\x22\x20@change=\x22setRowConstraint(row.items,\x20\x27format\x27,\x20$event.target.value)\x22\x20title=\x22Format\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22\x22>no\x20format</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22date-time\x22>date-time</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22date\x22>date</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22email\x22>email</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22uri\x22>uri</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22uuid\x22>uuid</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</select>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<!--\x20If\x20items\x20type\x20is\x20object,\x20show\x20nested\x20properties\x20-->\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.items.type\x20===\x20\x27object\x27\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-nested-children\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<each\x20:of=\x22row.items.children\x22\x20let:item=\x22child\x22\x20let:index=\x22ci\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-nested-child-row\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<code\x20class=\x22sem-child-name\x22>{{\x20child.name\x20}}</code>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<select\x20:value=\x22child.type\x22\x20@change=\x22setRowField(child,\x20\x27type\x27,\x20$event.target.value)\x22\x20style=\x22min-width:80px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22string\x22>string</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22number\x22>number</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22integer\x22>integer</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22boolean\x22>boolean</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22object\x22>object</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22array\x22>array</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</select>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label\x20style=\x22font-size:11px;\x20display:flex;\x20align-items:center;\x20gap:3px;\x20cursor:pointer;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22checkbox\x22\x20:checked=\x22child.required\x22\x20@change=\x22toggleRowRequired(child)\x22\x20/>\x20req\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label\x20style=\x22font-size:11px;\x20display:flex;\x20align-items:center;\x20gap:3px;\x20cursor:pointer;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22checkbox\x22\x20:checked=\x22child.nullable\x22\x20@change=\x22toggleRowNullable(child)\x22\x20/>\x20null\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20@click=\x22removeProperty(row.items.children,\x20ci)\x22\x20style=\x22color:var(--okdb-danger);\x20background:none;\x20border:none;\x20cursor:pointer;\x20font-size:13px;\x22>×</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</each>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-add-child-row\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22text\x22\x20:value=\x22_newChildNames[\x27items_\x27\x20+\x20row.name]\x20||\x20\x27\x27\x22\x20@input=\x22_newChildNames[\x27items_\x27\x20+\x20row.name]\x20=\x20$event.target.value\x22\x20@keydown.enter=\x22addChildProperty(row.items,\x20\x27items_\x27\x20+\x20row.name)\x22\x20placeholder=\x22Add\x20item\x20property…\x22\x20style=\x22flex:1;\x20font-size:11px;\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20@click=\x22addChildProperty(row.items,\x20\x27items_\x27\x20+\x20row.name)\x22\x20class=\x22btn-icon\x22\x20style=\x22font-size:10px;\x20padding:2px\x208px;\x22>+</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<!--\x20──\x20Nested\x20object\x20properties\x20──\x20-->\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22row.type\x20===\x20\x27object\x27\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-nested-section\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-nested-label\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20Properties\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label\x20style=\x22font-size:11px;\x20display:flex;\x20align-items:center;\x20gap:4px;\x20cursor:pointer;\x20margin-left:auto;\x20font-weight:normal;\x20opacity:.6;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22checkbox\x22\x20:checked=\x22row.childrenAdditionalProps\x22\x20@change=\x22setChildrenAdditionalProps(row,\x20$event.target.checked)\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20allow\x20additional\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-nested-children\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<each\x20:of=\x22row.children\x22\x20let:item=\x22child\x22\x20let:index=\x22ci\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-nested-child-row\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<code\x20class=\x22sem-child-name\x22>{{\x20child.name\x20}}</code>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<select\x20:value=\x22child.type\x22\x20@change=\x22setRowField(child,\x20\x27type\x27,\x20$event.target.value)\x22\x20style=\x22min-width:80px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22string\x22>string</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22number\x22>number</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22integer\x22>integer</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22boolean\x22>boolean</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22object\x22>object</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22array\x22>array</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</select>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label\x20style=\x22font-size:11px;\x20display:flex;\x20align-items:center;\x20gap:3px;\x20cursor:pointer;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22checkbox\x22\x20:checked=\x22child.required\x22\x20@change=\x22toggleRowRequired(child)\x22\x20/>\x20req\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label\x20style=\x22font-size:11px;\x20display:flex;\x20align-items:center;\x20gap:3px;\x20cursor:pointer;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22checkbox\x22\x20:checked=\x22child.nullable\x22\x20@change=\x22toggleRowNullable(child)\x22\x20/>\x20null\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22text\x22\x20:value=\x22child.description\x22\x20@input=\x22setRowField(child,\x20\x27description\x27,\x20$event.target.value)\x22\x20placeholder=\x22desc\x22\x20style=\x22flex:1;\x20font-size:11px;\x20min-width:60px;\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20@click=\x22removeProperty(row.children,\x20ci)\x22\x20style=\x22color:var(--okdb-danger);\x20background:none;\x20border:none;\x20cursor:pointer;\x20font-size:13px;\x22>×</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<!--\x202nd-level\x20nested:\x20show\x20sub-properties\x20for\x20object\x20children\x20-->\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22child.type\x20===\x20\x27object\x27\x20&&\x20child.children.length\x20>\x200\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-nested-l2\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<each\x20:of=\x22child.children\x22\x20let:item=\x22gc\x22\x20let:index=\x22gci\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-nested-child-row\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<code\x20class=\x22sem-child-name\x22\x20style=\x22font-size:10px;\x22>{{\x20gc.name\x20}}</code>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<select\x20:value=\x22gc.type\x22\x20@change=\x22setRowField(gc,\x20\x27type\x27,\x20$event.target.value)\x22\x20style=\x22min-width:70px;\x20font-size:11px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22string\x22>string</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22number\x22>number</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22integer\x22>integer</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22boolean\x22>boolean</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22object\x22>object</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<option\x20value=\x22array\x22>array</option>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</select>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<label\x20style=\x22font-size:10px;\x20display:flex;\x20align-items:center;\x20gap:2px;\x20cursor:pointer;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22checkbox\x22\x20:checked=\x22gc.required\x22\x20@change=\x22toggleRowRequired(gc)\x22\x20/>\x20req\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</label>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20@click=\x22removeProperty(child.children,\x20gci)\x22\x20style=\x22color:var(--okdb-danger);\x20background:none;\x20border:none;\x20cursor:pointer;\x20font-size:12px;\x22>×</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</each>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-add-child-row\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22text\x22\x20:value=\x22_newChildNames[\x27l2_\x27\x20+\x20row.name\x20+\x20\x27.\x27\x20+\x20child.name]\x20||\x20\x27\x27\x22\x20@input=\x22_newChildNames[\x27l2_\x27\x20+\x20row.name\x20+\x20\x27.\x27\x20+\x20child.name]\x20=\x20$event.target.value\x22\x20@keydown.enter=\x22addChildProperty(child,\x20\x27l2_\x27\x20+\x20row.name\x20+\x20\x27.\x27\x20+\x20child.name)\x22\x20placeholder=\x22Add\x20sub-property…\x22\x20style=\x22flex:1;\x20font-size:10px;\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20@click=\x22addChildProperty(child,\x20\x27l2_\x27\x20+\x20row.name\x20+\x20\x27.\x27\x20+\x20child.name)\x22\x20class=\x22btn-icon\x22\x20style=\x22font-size:10px;\x20padding:2px\x206px;\x22>+</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22child.type\x20===\x20\x27object\x27\x20&&\x20child.children.length\x20===\x200\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-add-child-row\x22\x20style=\x22margin-left:24px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22text\x22\x20:value=\x22_newChildNames[\x27l2_\x27\x20+\x20row.name\x20+\x20\x27.\x27\x20+\x20child.name]\x20||\x20\x27\x27\x22\x20@input=\x22_newChildNames[\x27l2_\x27\x20+\x20row.name\x20+\x20\x27.\x27\x20+\x20child.name]\x20=\x20$event.target.value\x22\x20@keydown.enter=\x22addChildProperty(child,\x20\x27l2_\x27\x20+\x20row.name\x20+\x20\x27.\x27\x20+\x20child.name)\x22\x20placeholder=\x22Add\x20sub-property…\x22\x20style=\x22flex:1;\x20font-size:10px;\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20@click=\x22addChildProperty(child,\x20\x27l2_\x27\x20+\x20row.name\x20+\x20\x27.\x27\x20+\x20child.name)\x22\x20class=\x22btn-icon\x22\x20style=\x22font-size:10px;\x20padding:2px\x206px;\x22>+</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</each>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22sem-add-child-row\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<input\x20type=\x22text\x22\x20:value=\x22_newChildNames[\x27obj_\x27\x20+\x20row.name]\x20||\x20\x27\x27\x22\x20@input=\x22_newChildNames[\x27obj_\x27\x20+\x20row.name]\x20=\x20$event.target.value\x22\x20@keydown.enter=\x22addChildProperty(row,\x20\x27obj_\x27\x20+\x20row.name)\x22\x20placeholder=\x22Add\x20property…\x22\x20style=\x22flex:1;\x20font-size:11px;\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20@click=\x22addChildProperty(row,\x20\x27obj_\x27\x20+\x20row.name)\x22\x20class=\x22btn-icon\x22\x20style=\x22font-size:10px;\x20padding:2px\x208px;\x22>+</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20</each>\x0a\x0a\x20\x20\x20\x20<if\x20:=\x22rows.length\x20===\x200\x22>\x0a\x20\x20\x20\x20\x20\x20<div\x20style=\x22padding:16px\x200;\x20opacity:.4;\x20font-size:13px;\x22>No\x20properties\x20defined\x20yet.\x20Add\x20one\x20below.</div>\x0a\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20<!--\x20Add\x20property\x20-->\x0a\x20\x20\x20\x20<div\x20class=\x22sem-add-row\x22>\x0a\x20\x20\x20\x20\x20\x20<input\x20type=\x22text\x22\x20:value=\x22newPropName\x22\x20@input=\x22newPropName\x20=\x20$event.target.value\x22\x20@keydown.enter=\x22addProperty()\x22\x20placeholder=\x22New\x20property\x20name…\x22\x20style=\x22flex:1;\x20min-width:140px;\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20<button\x20@click=\x22addProperty()\x22\x20class=\x22btn-icon\x22\x20style=\x22font-size:12px;\x20padding:3px\x2012px;\x22\x20:disabled=\x22!newPropName.trim()\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<ok-icon\x20name=\x22plus\x22></ok-icon>Add\x0a\x20\x20\x20\x20\x20\x20</button>\x0a\x20\x20\x20\x20</div>\x0a\x0a\x20\x20\x20\x20<!--\x20Additional\x20properties\x20toggle\x20-->\x0a\x20\x20\x20\x20<label\x20style=\x22font-size:12px;\x20display:flex;\x20align-items:center;\x20gap:6px;\x20cursor:pointer;\x20user-select:none;\x20padding:8px\x200\x200;\x22>\x0a\x20\x20\x20\x20\x20\x20<input\x20type=\x22checkbox\x22\x20:checked=\x22additionalProps\x22\x20@change=\x22setAdditionalProps($event.target.checked)\x22\x20/>\x0a\x20\x20\x20\x20\x20\x20Allow\x20additional\x20properties\x0a\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:11px;\x20opacity:.4;\x22>(fields\x20not\x20listed\x20above)</span>\x0a\x20\x20\x20\x20</label>\x0a\x20\x20</div>\x0a\x20\x20</if>\x0a\x0a\x20\x20<!--\x20═══════\x20JSON\x20mode\x20═══════\x20-->\x0a\x20\x20<if\x20:=\x22mode\x20===\x20\x27json\x27\x22>\x0a\x20\x20<div\x20class=\x22sem-json\x22>\x0a\x20\x20\x20\x20<ok-json-input\x0a\x20\x20\x20\x20\x20\x20:value=\x22editDefinition\x22\x0a\x20\x20\x20\x20\x20\x20@change=\x22setEditDefinition($event.detail)\x22\x0a\x20\x20\x20\x20\x20\x20style=\x22min-height:300px;\x20flex:1;\x20width:100%;\x22>\x0a\x20\x20\x20\x20</ok-json-input>\x0a\x20\x20</div>\x0a\x20\x20</if>\x0a\x0a\x20\x20<!--\x20Save\x20error\x20-->\x0a\x20\x20<if\x20:=\x22saveError\x22>\x0a\x20\x20\x20\x20<div\x20class=\x22sem-error\x22>{{\x20saveError\x20}}</div>\x0a\x20\x20</if>\x0a\x0a\x20\x20<!--\x20Actions\x20-->\x0a\x20\x20<div\x20class=\x22sem-actions\x22>\x0a\x20\x20\x20\x20<button\x20@click=\x22cancel()\x22\x20style=\x22opacity:.7;\x22>Cancel</button>\x0a\x20\x20\x20\x20<if\x20:=\x22hasSchema\x22>\x0a\x20\x20\x20\x20\x20\x20<button\x20@click=\x22remove()\x22\x20class=\x22btn-icon\x22\x20style=\x22color:var(--okdb-danger);\x20opacity:.8;\x20font-size:12px;\x20padding:5px\x2012px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<ok-icon\x20name=\x22trash-2\x22></ok-icon>Remove\x20schema\x0a\x20\x20\x20\x20\x20\x20</button>\x0a\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20<button\x20@click=\x22save()\x22\x20:disabled=\x22saveBusy\x22\x20class=\x22btn-icon\x22\x20style=\x22font-size:12px;\x20padding:5px\x2014px;\x20margin-left:auto;\x22>\x0a\x20\x20\x20\x20\x20\x20<ok-icon\x20name=\x22save\x22></ok-icon>\x0a\x20\x20\x20\x20\x20\x20{{\x20hasSchema\x20?\x20\x27Update\x20Schema\x27\x20:\x20\x27Set\x20Schema\x27\x20}}\x0a\x20\x20\x20\x20</button>\x0a\x20\x20</div>\x0a</div>\x0a','pattern','join','no_action','uniqueItems','filter','$defs','74332sFmvet','minimum','enum','/type/','$ref','map','type','visual','null','format','push','toast','modal','\x22\x20already\x20exists','18ytScTs','samplesUrl','1379313wPRKXr','properties','saveUrl','PUT','77IbOMiZ','array','refOnDelete','startsWith','additionalProperties','schema','splice','POST','multipleOf','maximum','some','confirm','saveBusy','failures','message','\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-root\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20flex-direction:\x20column;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x2012px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20min-width:\x20640px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20max-width:\x20960px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20position:\x20relative;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-toolbar\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20flex-wrap:\x20wrap;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-visual\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20flex-direction:\x20column;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x200;\x0a\x20\x20\x20\x20\x20\x20\x20\x20max-height:\x2060vh;\x0a\x20\x20\x20\x20\x20\x20\x20\x20overflow:\x20auto;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-props-hdr\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20grid;\x0a\x20\x20\x20\x20\x20\x20\x20\x20grid-template-columns:\x2028px\x20minmax(100px,\x201.5fr)\x20110px\x2036px\x2036px\x201fr\x2032px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x200\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x200\x200\x206px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-bottom:\x201px\x20solid\x20var(--okdb-app-border);\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2011px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.4;\x0a\x20\x20\x20\x20\x20\x20\x20\x20text-transform:\x20uppercase;\x0a\x20\x20\x20\x20\x20\x20\x20\x20letter-spacing:\x20.04em;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-props-row\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20grid;\x0a\x20\x20\x20\x20\x20\x20\x20\x20grid-template-columns:\x2028px\x20minmax(100px,\x201.5fr)\x20110px\x2036px\x2036px\x201fr\x2032px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x200\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x206px\x200;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-bottom:\x201px\x20solid\x20var(--okdb-app-surface);\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-expand-col\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20justify-content:\x20center;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-expand-btn\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20none;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border:\x20none;\x0a\x20\x20\x20\x20\x20\x20\x20\x20color:\x20var(--okdb-app-fg-muted);\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2016px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20cursor:\x20pointer;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x200\x204px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20transition:\x20transform\x20.15s;\x0a\x20\x20\x20\x20\x20\x20\x20\x20line-height:\x201;\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.5;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-expand-btn:hover\x20{\x20opacity:\x201;\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-expand-btn.sem-expanded\x20{\x20transform:\x20rotate(90deg);\x20opacity:\x20.8;\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-prop-name\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20overflow:\x20hidden;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-prop-name\x20code\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2012px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20color:\x20var(--okdb-json-key);\x0a\x20\x20\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20\x20\x20/*\x20──\x20Detail\x20/\x20constraints\x20panel\x20──\x20*/\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-detail-panel\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x208px\x2012px\x2012px\x2036px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20var(--okdb-app-bg-deep);\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-bottom:\x201px\x20solid\x20var(--okdb-app-surface);\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20flex-direction:\x20column;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x2010px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-constraints-grid\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20grid;\x0a\x20\x20\x20\x20\x20\x20\x20\x20grid-template-columns:\x2080px\x201fr\x2080px\x201fr;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x206px\x2010px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2011px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-constraints-grid\x20label\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.55;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2011px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20white-space:\x20nowrap;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-constraints-grid\x20input,\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-constraints-grid\x20select\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2012px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x203px\x206px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-constraint-row\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2011px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-constraint-row\x20label\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.55;\x0a\x20\x20\x20\x20\x20\x20\x20\x20white-space:\x20nowrap;\x0a\x20\x20\x20\x20\x20\x20\x20\x20min-width:\x2040px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-hint\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.35;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2010px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20white-space:\x20nowrap;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20\x20\x20/*\x20──\x20Nested\x20object/array\x20section\x20──\x20*/\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-nested-section\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-left:\x202px\x20solid\x20var(--okdb-app-border);\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding-left:\x2012px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20margin-top:\x202px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-nested-label\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2011px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-weight:\x20600;\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.6;\x0a\x20\x20\x20\x20\x20\x20\x20\x20text-transform:\x20uppercase;\x0a\x20\x20\x20\x20\x20\x20\x20\x20letter-spacing:\x20.04em;\x0a\x20\x20\x20\x20\x20\x20\x20\x20margin-bottom:\x206px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x208px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-nested-row\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20margin-bottom:\x206px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-nested-children\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20flex-direction:\x20column;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x200;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-nested-child-row\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x204px\x200;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-bottom:\x201px\x20solid\x20color-mix(in\x20srgb,\x20var(--okdb-app-border)\x2040%,\x20transparent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2012px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-child-name\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2011px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20color:\x20var(--okdb-purple);\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-family:\x20monospace;\x0a\x20\x20\x20\x20\x20\x20\x20\x20min-width:\x2060px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20overflow:\x20hidden;\x0a\x20\x20\x20\x20\x20\x20\x20\x20text-overflow:\x20ellipsis;\x0a\x20\x20\x20\x20\x20\x20\x20\x20white-space:\x20nowrap;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-nested-l2\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20margin-left:\x2024px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-left:\x201px\x20solid\x20var(--okdb-app-border)66;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding-left:\x2010px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20margin-bottom:\x204px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-add-child-row\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x206px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x204px\x200;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-add-row\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2010px\x200\x200;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20\x20\x20/*\x20──\x20Foreign\x20key\x20section\x20──\x20*/\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-fk-section\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20#6366f133;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-radius:\x206px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x208px\x2010px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20#6366f108;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-fk-label\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2011px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-weight:\x20600;\x0a\x20\x20\x20\x20\x20\x20\x20\x20text-transform:\x20uppercase;\x0a\x20\x20\x20\x20\x20\x20\x20\x20letter-spacing:\x20.04em;\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.7;\x0a\x20\x20\x20\x20\x20\x20\x20\x20margin-bottom:\x206px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x205px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20color:\x20var(--okdb-indigo);\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-fk-row\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2012px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-fk-row\x20label\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.55;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2011px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20white-space:\x20nowrap;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-fk-row\x20select\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2012px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x203px\x206px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20min-width:\x20100px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-fk-clear\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20none;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border:\x20none;\x0a\x20\x20\x20\x20\x20\x20\x20\x20color:\x20var(--okdb-danger);\x0a\x20\x20\x20\x20\x20\x20\x20\x20cursor:\x20pointer;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2014px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x202px\x206px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20line-height:\x201;\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.7;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-fk-clear:hover\x20{\x20opacity:\x201;\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-fk-hint\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2011px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.5;\x0a\x20\x20\x20\x20\x20\x20\x20\x20margin-top:\x205px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20line-height:\x201.4;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-fk-hint\x20strong\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20color:\x20var(--okdb-indigo);\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x201;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-json\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20flex-direction:\x20column;\x0a\x20\x20\x20\x20\x20\x20\x20\x20min-height:\x20300px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-error\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20color:\x20var(--okdb-danger);\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2012px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x208px\x2010px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-radius:\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20color-mix(in\x20srgb,\x20var(--okdb-danger)\x2020%,\x20transparent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20color-mix(in\x20srgb,\x20var(--okdb-danger)\x204%,\x20transparent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20white-space:\x20pre-wrap;\x0a\x20\x20\x20\x20\x20\x20\x20\x20line-height:\x201.5;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20schema-edit-modal\x20.sem-actions\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding-top:\x204px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-top:\x201px\x20solid\x20var(--okdb-app-border);\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20','_newChildNames','No\x20documents\x20found\x20to\x20infer\x20schema\x20from.','hideEnforce','rows','payload','data','error','Failed\x20to\x20fetch\x20data','Failed\x20to\x20fetch\x20samples','Save\x20failed','370182vclZnU','onDone'];_0x19c4=function(){return _0x4e211b;};return _0x19c4();}(function(_0x283873,_0x1098dc){const _0x1db3ce=_0x3dca,_0x299afb=_0x283873();while(!![]){try{const _0x753d9b=parseInt(_0x1db3ce(0x22d))/0x1*(-parseInt(_0x1db3ce(0x23b))/0x2)+-parseInt(_0x1db3ce(0x23d))/0x3+parseInt(_0x1db3ce(0x1d8))/0x4*(-parseInt(_0x1db3ce(0x1ed))/0x5)+-parseInt(_0x1db3ce(0x1d3))/0x6*(parseInt(_0x1db3ce(0x241))/0x7)+parseInt(_0x1db3ce(0x1e9))/0x8*(-parseInt(_0x1db3ce(0x1f6))/0x9)+parseInt(_0x1db3ce(0x20e))/0xa+parseInt(_0x1db3ce(0x20f))/0xb;if(_0x753d9b===_0x1098dc)break;else _0x299afb['push'](_0x299afb['shift']());}catch(_0x32ea2f){_0x299afb['push'](_0x299afb['shift']());}}}(_0x19c4,0x58aa1));import _0x124042 from'@toolkit/elements/ok-icon.ok.js';import _0x16c28b from'@toolkit/core/ok-overlay.ok.js';import _0x204797 from'../../../components/ok-json-input.ok.js';function i(_0x329d7a){const _0x7e6304=_0x3dca;return null==_0x329d7a?_0x329d7a:JSON[_0x7e6304(0x1ee)](JSON['stringify'](_0x329d7a));}function _0x3dca(_0x8cc0d8,_0x4907ce){_0x8cc0d8=_0x8cc0d8-0x1c3;const _0x19c468=_0x19c4();let _0x3dcade=_0x19c468[_0x8cc0d8];return _0x3dcade;}function o(_0x22bcd3='',_0x5225bd=_0x5f15ce(0x1e1)){return{'name':_0x22bcd3,'type':_0x5225bd,'nullable':!0x1,'required':!0x1,'description':'','enum':null,'const':null,'format':'','minimum':null,'maximum':null,'exclusiveMinimum':null,'exclusiveMaximum':null,'multipleOf':null,'minLength':null,'maxLength':null,'pattern':'','minItems':null,'maxItems':null,'uniqueItems':!0x1,'refType':'','refOnDelete':'no_action','children':[],'childrenAdditionalProps':!0x0,'items':null,'expanded':!0x1,'_extra':{}};}function a(_0x5de97a,_0x569c36,_0x2f76b3,_0x34aa52=0x0){const _0x52fc60=_0x5f15ce,_0x469c76=_0x569c36['type'];let _0x1ed7eb,_0x39a366=!0x1;Array[_0x52fc60(0x1e2)](_0x469c76)?(_0x39a366=_0x469c76[_0x52fc60(0x210)](_0x52fc60(0x235)),_0x1ed7eb=_0x469c76[_0x52fc60(0x224)](_0x65fb45=>_0x52fc60(0x235)!==_0x65fb45)||'string'):_0x1ed7eb=_0x469c76||'string';const _0x1731d4=o(_0x5de97a,_0x1ed7eb);if(_0x1731d4[_0x52fc60(0x1d9)]=_0x39a366,_0x1731d4[_0x52fc60(0x219)]=_0x2f76b3,_0x1731d4[_0x52fc60(0x1e6)]=_0x569c36['description']||'',Array[_0x52fc60(0x1e2)](_0x569c36[_0x52fc60(0x22f)])&&(_0x1731d4[_0x52fc60(0x22f)]=_0x569c36[_0x52fc60(0x22f)]),void 0x0!==_0x569c36[_0x52fc60(0x1de)]&&(_0x1731d4['const']={'value':_0x569c36[_0x52fc60(0x1de)]}),_0x569c36[_0x52fc60(0x236)]&&(_0x1731d4['format']=_0x569c36['format']),void 0x0!==_0x569c36[_0x52fc60(0x22e)]&&(_0x1731d4[_0x52fc60(0x22e)]=_0x569c36[_0x52fc60(0x22e)]),void 0x0!==_0x569c36['maximum']&&(_0x1731d4['maximum']=_0x569c36[_0x52fc60(0x24a)]),void 0x0!==_0x569c36[_0x52fc60(0x21b)]&&(_0x1731d4[_0x52fc60(0x21b)]=_0x569c36[_0x52fc60(0x21b)]),void 0x0!==_0x569c36[_0x52fc60(0x1e8)]&&(_0x1731d4[_0x52fc60(0x1e8)]=_0x569c36['exclusiveMaximum']),void 0x0!==_0x569c36['multipleOf']&&(_0x1731d4[_0x52fc60(0x249)]=_0x569c36[_0x52fc60(0x249)]),void 0x0!==_0x569c36[_0x52fc60(0x205)]&&(_0x1731d4[_0x52fc60(0x205)]=_0x569c36[_0x52fc60(0x205)]),void 0x0!==_0x569c36[_0x52fc60(0x208)]&&(_0x1731d4['maxLength']=_0x569c36['maxLength']),_0x569c36[_0x52fc60(0x227)]&&(_0x1731d4[_0x52fc60(0x227)]=_0x569c36[_0x52fc60(0x227)]),void 0x0!==_0x569c36['minItems']&&(_0x1731d4[_0x52fc60(0x1f3)]=_0x569c36[_0x52fc60(0x1f3)]),void 0x0!==_0x569c36['maxItems']&&(_0x1731d4[_0x52fc60(0x1fd)]=_0x569c36['maxItems']),!0x0===_0x569c36[_0x52fc60(0x22a)]&&(_0x1731d4[_0x52fc60(0x22a)]=!0x0),_0x569c36[_0x52fc60(0x1dd)]&&_0x52fc60(0x221)==typeof _0x569c36['ref']&&_0x569c36[_0x52fc60(0x1dd)][_0x52fc60(0x233)]&&(_0x1731d4[_0x52fc60(0x206)]=_0x569c36[_0x52fc60(0x1dd)]['type'],_0x1731d4[_0x52fc60(0x243)]=_0x569c36[_0x52fc60(0x1dd)][_0x52fc60(0x20a)]||_0x52fc60(0x229)),'object'===_0x1ed7eb&&_0x569c36[_0x52fc60(0x23e)]&&_0x34aa52<0x4){const _0x1d522b=new Set(_0x569c36['required']||[]);_0x1731d4['children']=Object['entries'](_0x569c36[_0x52fc60(0x23e)])[_0x52fc60(0x232)](([_0x35e5ff,_0x370452])=>a(_0x35e5ff,_0x370452,_0x1d522b['has'](_0x35e5ff),_0x34aa52+0x1)),_0x1731d4[_0x52fc60(0x1ff)]=!0x1!==_0x569c36[_0x52fc60(0x245)];}_0x52fc60(0x242)===_0x1ed7eb&&_0x569c36[_0x52fc60(0x1ec)]&&_0x52fc60(0x221)==typeof _0x569c36['items']&&_0x34aa52<0x4&&(_0x1731d4[_0x52fc60(0x1ec)]=a(_0x52fc60(0x211),_0x569c36[_0x52fc60(0x1ec)],!0x1,_0x34aa52+0x1));const _0x579d50=new Set([_0x52fc60(0x233),_0x52fc60(0x1e6),'enum',_0x52fc60(0x1de),_0x52fc60(0x236),_0x52fc60(0x22e),'maximum',_0x52fc60(0x21b),_0x52fc60(0x1e8),_0x52fc60(0x249),_0x52fc60(0x205),_0x52fc60(0x208),_0x52fc60(0x227),_0x52fc60(0x1f3),_0x52fc60(0x1fd),'uniqueItems',_0x52fc60(0x23e),_0x52fc60(0x219),_0x52fc60(0x245),_0x52fc60(0x1ec),_0x52fc60(0x20b),_0x52fc60(0x231),_0x52fc60(0x22c),_0x52fc60(0x1dd)]);for(const _0x446c2e of Object[_0x52fc60(0x201)](_0x569c36))_0x579d50['has'](_0x446c2e)||(_0x1731d4[_0x52fc60(0x223)][_0x446c2e]=i(_0x569c36[_0x446c2e]));return _0x1731d4;}function r(_0x2aac8e){const _0x192ab8=_0x5f15ce,_0xb7ae69={};if(_0x2aac8e[_0x192ab8(0x1d9)]&&_0x192ab8(0x235)!==_0x2aac8e[_0x192ab8(0x233)]?_0xb7ae69[_0x192ab8(0x233)]=[_0x2aac8e['type'],_0x192ab8(0x235)]:_0xb7ae69[_0x192ab8(0x233)]=_0x2aac8e[_0x192ab8(0x233)],_0x2aac8e[_0x192ab8(0x1e6)]&&(_0xb7ae69[_0x192ab8(0x1e6)]=_0x2aac8e[_0x192ab8(0x1e6)]),_0x2aac8e[_0x192ab8(0x22f)]&&_0x2aac8e['enum'][_0x192ab8(0x1fe)]>0x0&&(_0xb7ae69[_0x192ab8(0x22f)]=_0x2aac8e[_0x192ab8(0x22f)]),null!==_0x2aac8e[_0x192ab8(0x1de)]&&void 0x0!==_0x2aac8e['const']&&(_0xb7ae69[_0x192ab8(0x1de)]=_0x2aac8e[_0x192ab8(0x1de)]['value']),_0x2aac8e[_0x192ab8(0x236)]&&(_0xb7ae69[_0x192ab8(0x236)]=_0x2aac8e[_0x192ab8(0x236)]),null!==_0x2aac8e[_0x192ab8(0x22e)]&&void 0x0!==_0x2aac8e[_0x192ab8(0x22e)]&&(_0xb7ae69['minimum']=_0x2aac8e['minimum']),null!==_0x2aac8e[_0x192ab8(0x24a)]&&void 0x0!==_0x2aac8e['maximum']&&(_0xb7ae69[_0x192ab8(0x24a)]=_0x2aac8e['maximum']),null!==_0x2aac8e[_0x192ab8(0x21b)]&&void 0x0!==_0x2aac8e['exclusiveMinimum']&&(_0xb7ae69[_0x192ab8(0x21b)]=_0x2aac8e[_0x192ab8(0x21b)]),null!==_0x2aac8e[_0x192ab8(0x1e8)]&&void 0x0!==_0x2aac8e[_0x192ab8(0x1e8)]&&(_0xb7ae69['exclusiveMaximum']=_0x2aac8e[_0x192ab8(0x1e8)]),null!==_0x2aac8e[_0x192ab8(0x249)]&&void 0x0!==_0x2aac8e['multipleOf']&&(_0xb7ae69['multipleOf']=_0x2aac8e['multipleOf']),null!==_0x2aac8e[_0x192ab8(0x205)]&&void 0x0!==_0x2aac8e['minLength']&&(_0xb7ae69[_0x192ab8(0x205)]=_0x2aac8e[_0x192ab8(0x205)]),null!==_0x2aac8e[_0x192ab8(0x208)]&&void 0x0!==_0x2aac8e['maxLength']&&(_0xb7ae69[_0x192ab8(0x208)]=_0x2aac8e['maxLength']),_0x2aac8e[_0x192ab8(0x227)]&&(_0xb7ae69[_0x192ab8(0x227)]=_0x2aac8e[_0x192ab8(0x227)]),null!==_0x2aac8e['minItems']&&void 0x0!==_0x2aac8e[_0x192ab8(0x1f3)]&&(_0xb7ae69[_0x192ab8(0x1f3)]=_0x2aac8e[_0x192ab8(0x1f3)]),null!==_0x2aac8e[_0x192ab8(0x1fd)]&&void 0x0!==_0x2aac8e[_0x192ab8(0x1fd)]&&(_0xb7ae69[_0x192ab8(0x1fd)]=_0x2aac8e[_0x192ab8(0x1fd)]),_0x2aac8e[_0x192ab8(0x22a)]&&(_0xb7ae69[_0x192ab8(0x22a)]=!0x0),_0x2aac8e[_0x192ab8(0x206)]&&(_0xb7ae69['ref']={'type':_0x2aac8e[_0x192ab8(0x206)]},_0x2aac8e['refOnDelete']&&_0x192ab8(0x229)!==_0x2aac8e[_0x192ab8(0x243)]&&(_0xb7ae69[_0x192ab8(0x1dd)]['onDelete']=_0x2aac8e['refOnDelete'])),_0x192ab8(0x221)===_0x2aac8e[_0x192ab8(0x233)]&&_0x2aac8e[_0x192ab8(0x1fa)][_0x192ab8(0x1fe)]>0x0){_0xb7ae69[_0x192ab8(0x23e)]={};const _0x32aca2=[];for(const _0x4dab2c of _0x2aac8e['children'])_0xb7ae69['properties'][_0x4dab2c[_0x192ab8(0x1f7)]]=r(_0x4dab2c),_0x4dab2c[_0x192ab8(0x219)]&&_0x32aca2[_0x192ab8(0x237)](_0x4dab2c[_0x192ab8(0x1f7)]);_0x32aca2[_0x192ab8(0x1fe)]>0x0&&(_0xb7ae69[_0x192ab8(0x219)]=_0x32aca2),_0xb7ae69[_0x192ab8(0x245)]=_0x2aac8e[_0x192ab8(0x1ff)];}if('array'===_0x2aac8e[_0x192ab8(0x233)]&&_0x2aac8e[_0x192ab8(0x1ec)]&&(_0xb7ae69['items']=r(_0x2aac8e[_0x192ab8(0x1ec)])),_0x2aac8e[_0x192ab8(0x223)]){for(const [_0x1a4c08,_0x118fab]of Object[_0x192ab8(0x207)](_0x2aac8e['_extra']))_0xb7ae69[_0x1a4c08]=i(_0x118fab);}return _0xb7ae69;}function l(_0x1a337a){const _0xa50982=_0x5f15ce;if(!_0x1a337a||!_0x1a337a[_0xa50982(0x23e)])return[];const _0x255b8d=new Set(_0x1a337a[_0xa50982(0x219)]||[]);return Object[_0xa50982(0x207)](_0x1a337a['properties'])[_0xa50982(0x232)](([_0x5359d8,_0x3e9cc7])=>a(_0x5359d8,_0x3e9cc7,_0x255b8d[_0xa50982(0x1f5)](_0x5359d8),0x0));}function s(_0x24affc,_0x583771){const _0x174538=_0x5f15ce,_0x5600fb={},_0x26f002=[];for(const _0x36b066 of _0x24affc)_0x5600fb[_0x36b066[_0x174538(0x1f7)]]=r(_0x36b066),_0x36b066['required']&&_0x26f002[_0x174538(0x237)](_0x36b066[_0x174538(0x1f7)]);const _0x315300={'type':_0x174538(0x221),'properties':_0x5600fb};return _0x26f002['length']>0x0&&(_0x315300[_0x174538(0x219)]=_0x26f002),_0x315300[_0x174538(0x245)]=_0x583771,_0x315300;}export default{'tag':_0x5f15ce(0x202),'dependencies':[_0x124042,_0x16c28b,_0x204797],'attr':{'modal':{},'type':{},'schema':{},'envApiBase':{},'onDone':{},'saveUrl':{},'samplesUrl':{},'hideEnforce':{}},'context':_0x842fd4=>({'mode':'visual','editDefinition':{},'editEnforce':!0x1,'rows':[],'additionalProps':!0x0,'saveBusy':!0x1,'saveError':null,'dirty':!0x1,'newPropName':'','_newChildNames':{},'typesList':[],get 'hasSchema'(){const _0xbaf12d=_0x5f15ce;return!!_0x842fd4[_0xbaf12d(0x222)][_0xbaf12d(0x246)];},get 'hideEnforce'(){const _0x3975aa=_0x5f15ce;return!!_0x842fd4[_0x3975aa(0x222)][_0x3975aa(0x1cb)];},'_init'(){const _0x21030a=_0x5f15ce,_0x27a4c5=_0x842fd4['$attr'][_0x21030a(0x246)];_0x27a4c5?.[_0x21030a(0x1e0)]?(this[_0x21030a(0x1da)]=i(_0x27a4c5[_0x21030a(0x1e0)]),this[_0x21030a(0x21f)]=_0x27a4c5[_0x21030a(0x20c)]??!0x1):(this['editDefinition']={'type':_0x21030a(0x221),'properties':{},'additionalProperties':!0x0},this[_0x21030a(0x21f)]=!0x1),this[_0x21030a(0x1cc)]=l(this[_0x21030a(0x1da)]),this['additionalProps']=!0x1!==this[_0x21030a(0x1da)]['additionalProperties'],this[_0x21030a(0x1f2)]=!0x1,this['saveError']=null;},'switchToVisual'(){const _0x19f588=_0x5f15ce;this[_0x19f588(0x1cc)]=l(this[_0x19f588(0x1da)]),this[_0x19f588(0x1d6)]=!0x1!==this['editDefinition'][_0x19f588(0x245)],this[_0x19f588(0x1f8)]=_0x19f588(0x234);},'switchToJson'(){const _0x593cee=_0x5f15ce;this[_0x593cee(0x1da)]=s(this[_0x593cee(0x1cc)],this['additionalProps']),this[_0x593cee(0x1f8)]=_0x593cee(0x204);},'addProperty'(){const _0x374ed4=_0x5f15ce,_0x9fd78b=(this[_0x374ed4(0x21c)]||'')[_0x374ed4(0x216)]();_0x9fd78b&&(this['rows'][_0x374ed4(0x1c3)](_0x3e4b97=>_0x3e4b97[_0x374ed4(0x1f7)]===_0x9fd78b)?_0x842fd4['$ok'][_0x374ed4(0x1e5)]?.[_0x374ed4(0x238)]?.[_0x374ed4(0x1cf)]?.(_0x374ed4(0x212)+_0x9fd78b+_0x374ed4(0x23a)):(this[_0x374ed4(0x1cc)][_0x374ed4(0x237)](o(_0x9fd78b)),this[_0x374ed4(0x21c)]='',this[_0x374ed4(0x1f2)]=!0x0));},'addChildProperty'(_0x2dffdb,_0x211a2f){const _0x1a8e78=_0x5f15ce,_0x488aa0=(this[_0x1a8e78(0x1c9)][_0x211a2f]||'')[_0x1a8e78(0x216)]();_0x488aa0&&(_0x2dffdb[_0x1a8e78(0x1fa)][_0x1a8e78(0x1c3)](_0xf6b7c8=>_0xf6b7c8['name']===_0x488aa0)?_0x842fd4['$ok'][_0x1a8e78(0x1e5)]?.[_0x1a8e78(0x238)]?.[_0x1a8e78(0x1cf)]?.(_0x1a8e78(0x212)+_0x488aa0+_0x1a8e78(0x23a)):(_0x2dffdb['children'][_0x1a8e78(0x237)](o(_0x488aa0)),this[_0x1a8e78(0x1c9)][_0x211a2f]='',this[_0x1a8e78(0x1f2)]=!0x0));},'removeProperty'(_0x58959d,_0x3e9f3c){const _0x26bfaa=_0x5f15ce;_0x58959d[_0x26bfaa(0x247)](_0x3e9f3c,0x1),this['dirty']=!0x0;},'setRowField'(_0x542f0d,_0x3a90bd,_0x2968cc){const _0x53402d=_0x5f15ce;_0x542f0d[_0x3a90bd]=_0x2968cc,_0x53402d(0x233)===_0x3a90bd&&(_0x53402d(0x221)===_0x2968cc&&0x0===_0x542f0d[_0x53402d(0x1fa)][_0x53402d(0x1fe)]&&(_0x542f0d[_0x53402d(0x1fa)]=[],_0x542f0d['childrenAdditionalProps']=!0x0),_0x53402d(0x242)!==_0x2968cc||_0x542f0d['items']||(_0x542f0d['items']=o('(item)',_0x53402d(0x1e1)))),this[_0x53402d(0x1f2)]=!0x0;},'toggleRowExpanded'(_0x533635){const _0x55d352=_0x5f15ce;_0x533635[_0x55d352(0x1f9)]=!_0x533635['expanded'];},'toggleRowRequired'(_0x18f136){const _0x3254ff=_0x5f15ce;_0x18f136[_0x3254ff(0x219)]=!_0x18f136[_0x3254ff(0x219)],this['dirty']=!0x0;},'toggleRowNullable'(_0x285ef3){const _0x3a8790=_0x5f15ce;_0x285ef3[_0x3a8790(0x1d9)]=!_0x285ef3[_0x3a8790(0x1d9)],this[_0x3a8790(0x1f2)]=!0x0;},'setChildrenAdditionalProps'(_0x43385d,_0x4d5d7d){const _0x17edfd=_0x5f15ce;_0x43385d[_0x17edfd(0x1ff)]=_0x4d5d7d,this['dirty']=!0x0;},'setRowConstraint'(_0x2a3d7f,_0x4bb6cc,_0x569ed9){const _0x25af62=_0x5f15ce;[_0x25af62(0x22e),_0x25af62(0x24a),_0x25af62(0x21b),'exclusiveMaximum',_0x25af62(0x249),_0x25af62(0x205),_0x25af62(0x208),_0x25af62(0x1f3),'maxItems'][_0x25af62(0x210)](_0x4bb6cc)?_0x2a3d7f[_0x4bb6cc]=''===_0x569ed9||null===_0x569ed9?null:Number(_0x569ed9):'uniqueItems'===_0x4bb6cc?_0x2a3d7f[_0x4bb6cc]=!!_0x569ed9:'enum'===_0x4bb6cc?_0x569ed9&&''!==_0x569ed9[_0x25af62(0x216)]()?_0x2a3d7f['enum']=_0x569ed9['split'](',')[_0x25af62(0x232)](_0x7c6754=>{const _0x34f4c8=_0x25af62;_0x7c6754=_0x7c6754['trim']();try{return JSON[_0x34f4c8(0x1ee)](_0x7c6754);}catch{return _0x7c6754;}}):_0x2a3d7f[_0x25af62(0x22f)]=null:_0x2a3d7f[_0x4bb6cc]=_0x569ed9,this[_0x25af62(0x1f2)]=!0x0;},'enumToString':_0x1fbacd=>_0x1fbacd&&Array['isArray'](_0x1fbacd)?_0x1fbacd[_0x5f15ce(0x232)](_0x1c17c2=>_0x5f15ce(0x1e1)==typeof _0x1c17c2?_0x1c17c2:JSON[_0x5f15ce(0x1f0)](_0x1c17c2))[_0x5f15ce(0x228)](',\x20'):'','setAdditionalProps'(_0xf70af2){const _0x2041d3=_0x5f15ce;this[_0x2041d3(0x1d6)]=_0xf70af2,this[_0x2041d3(0x1f2)]=!0x0;},async 'loadTypesList'(){const _0x1f2c6c=_0x5f15ce;try{const _0x37581f=await fetch(_0x842fd4[_0x1f2c6c(0x222)]['envApiBase']+_0x1f2c6c(0x1eb));if(_0x37581f['ok']){const _0x2d7aae=await _0x37581f[_0x1f2c6c(0x204)]();this[_0x1f2c6c(0x1dc)]=(_0x2d7aae[_0x1f2c6c(0x1f4)]??_0x2d7aae['data']??_0x2d7aae[_0x1f2c6c(0x209)]??[])[_0x1f2c6c(0x232)](_0x44a4b8=>_0x1f2c6c(0x1e1)==typeof _0x44a4b8?_0x44a4b8:_0x44a4b8['type']??_0x44a4b8['name'])['filter'](_0x2bb649=>_0x2bb649&&!_0x2bb649[_0x1f2c6c(0x244)]('~'))['sort']();}}catch{}},'setRowRef'(_0x421ccc,_0x2bd608,_0x725a69){const _0x5ad368=_0x5f15ce;_0x5ad368(0x206)===_0x2bd608?(_0x421ccc[_0x5ad368(0x206)]=_0x725a69,_0x725a69||(_0x421ccc[_0x5ad368(0x243)]=_0x5ad368(0x229))):_0x5ad368(0x243)===_0x2bd608&&(_0x421ccc[_0x5ad368(0x243)]=_0x725a69),this[_0x5ad368(0x1f2)]=!0x0;},'clearRowRef'(_0x374f46){const _0x46dadf=_0x5f15ce;_0x374f46[_0x46dadf(0x206)]='',_0x374f46[_0x46dadf(0x243)]=_0x46dadf(0x229),this[_0x46dadf(0x1f2)]=!0x0;},'setEditDefinition'(_0x216849){const _0x4f58e2=_0x5f15ce;this['editDefinition']=_0x216849,this[_0x4f58e2(0x1f2)]=!0x0;},'setEditEnforce'(_0x12f8d2){const _0x2fb021=_0x5f15ce;this[_0x2fb021(0x21f)]=_0x12f8d2,this['dirty']=!0x0;},async 'generateFromData'(){const _0x494815=_0x5f15ce;if(_0x842fd4[_0x494815(0x222)][_0x494815(0x233)]||_0x842fd4['$attr'][_0x494815(0x23c)])try{let _0x429060;if(_0x842fd4[_0x494815(0x222)][_0x494815(0x23c)]){const _0x2d8162=await fetch(_0x842fd4[_0x494815(0x222)][_0x494815(0x23c)]);if(!_0x2d8162['ok'])throw new Error(_0x494815(0x1d1));const _0x1a541d=await _0x2d8162[_0x494815(0x204)]();_0x429060=(_0x1a541d[_0x494815(0x1ce)]??_0x1a541d[_0x494815(0x1f4)]??[])[_0x494815(0x232)](_0x38ae0b=>_0x38ae0b[_0x494815(0x225)]??_0x38ae0b[_0x494815(0x1cd)]??_0x38ae0b['value']??_0x38ae0b);}else{const _0x1f5258=await fetch(_0x842fd4['$attr'][_0x494815(0x1f1)]+_0x494815(0x230)+encodeURIComponent(_0x842fd4[_0x494815(0x222)][_0x494815(0x233)])+'/query',{'method':_0x494815(0x248),'headers':{'Content-Type':'application/json'},'body':JSON[_0x494815(0x1f0)]({'filter':{},'options':{'limit':0x32}})});if(!_0x1f5258['ok'])throw new Error(_0x494815(0x1d0));const _0x2404e7=await _0x1f5258[_0x494815(0x204)]();_0x429060=(_0x2404e7['data']??_0x2404e7['result']??[])['map'](_0x3377ab=>_0x3377ab['doc']??_0x3377ab[_0x494815(0x214)]??_0x3377ab);}if(0x0===_0x429060[_0x494815(0x1fe)])return void _0x842fd4[_0x494815(0x213)][_0x494815(0x1e5)]?.['toast']?.[_0x494815(0x21a)]?.(_0x494815(0x1ca));_0x842fd4['$ok']['shared']?.['toast']?.[_0x494815(0x21a)]?.(_0x494815(0x1ea)+_0x429060['length']+_0x494815(0x20d));const _0x1d5393=this['_inferSchemaFromData'](_0x429060);this[_0x494815(0x1da)]=_0x1d5393,this['rows']=l(_0x1d5393),this[_0x494815(0x1d6)]=!0x1!==_0x1d5393['additionalProperties'],this['dirty']=!0x0;}catch(_0x2de92f){_0x842fd4['$ok']['shared']?.[_0x494815(0x238)]?.[_0x494815(0x1cf)]?.(_0x2de92f[_0x494815(0x1c7)]);}},'_inferSchemaFromData'(_0x305500){function _0x3c4617(_0x4eb24b){const _0x812814=_0x3dca;return null===_0x4eb24b?_0x812814(0x235):Array[_0x812814(0x1e2)](_0x4eb24b)?'array':_0x812814(0x221)==typeof _0x4eb24b?_0x812814(0x221):typeof _0x4eb24b;}return function _0x4b0788(_0x8b36d5){const _0x5153f6=_0x3dca;let _0x5d9dfa=[...new Set(_0x8b36d5[_0x5153f6(0x232)](_0x3c4617)[_0x5153f6(0x22b)](_0x5c80ae=>'undefined'!==_0x5c80ae))];if(0x0===_0x5d9dfa[_0x5153f6(0x1fe)])return{'type':_0x5153f6(0x1e1)};_0x5d9dfa[_0x5153f6(0x210)](_0x5153f6(0x235))&&_0x5d9dfa[_0x5153f6(0x1fe)]>0x1&&(_0x5d9dfa=_0x5d9dfa[_0x5153f6(0x22b)](_0xaa5ef4=>_0x5153f6(0x235)!==_0xaa5ef4));let _0x18fb55=0x1===_0x5d9dfa[_0x5153f6(0x1fe)]?{'type':_0x5d9dfa[0x0]}:{'type':_0x5d9dfa};if(_0x5d9dfa[_0x5153f6(0x210)]('object')){let _0x2c4dc0={},_0x59d271=new Set(_0x8b36d5[_0x5153f6(0x22b)](_0x2864c4=>'object'===_0x3c4617(_0x2864c4)&&null!==_0x2864c4)['flatMap'](Object['keys']));for(let _0x2e9e8b of _0x59d271){let _0x4f311c=_0x8b36d5['filter'](_0x273570=>_0x5153f6(0x221)===_0x3c4617(_0x273570)&&null!==_0x273570)[_0x5153f6(0x232)](_0x1bcc6c=>_0x1bcc6c[_0x2e9e8b]);_0x2c4dc0[_0x2e9e8b]=_0x4b0788(_0x4f311c);}_0x18fb55[_0x5153f6(0x23e)]=_0x2c4dc0,_0x18fb55['additionalProperties']=!0x1;}if(_0x5d9dfa[_0x5153f6(0x210)](_0x5153f6(0x242))){let _0x446b95=_0x8b36d5[_0x5153f6(0x22b)](_0xba58d9=>_0x5153f6(0x242)===_0x3c4617(_0xba58d9))[_0x5153f6(0x1fb)]();_0x446b95[_0x5153f6(0x1fe)]>0x0&&(_0x18fb55[_0x5153f6(0x1ec)]=_0x4b0788(_0x446b95));}return _0x18fb55;}(_0x305500);},async 'save'(){const _0x39051f=_0x5f15ce;this['saveBusy']=!0x0,this[_0x39051f(0x203)]=null;try{const _0x135b2a={'definition':'visual'===this[_0x39051f(0x1f8)]?s(this['rows'],this[_0x39051f(0x1d6)]):this[_0x39051f(0x1da)],'enforce':!!_0x842fd4[_0x39051f(0x222)][_0x39051f(0x1cb)]||this[_0x39051f(0x21f)]},_0x4d980b=_0x842fd4['$attr'][_0x39051f(0x23f)]??_0x842fd4[_0x39051f(0x222)][_0x39051f(0x1f1)]+_0x39051f(0x230)+encodeURIComponent(_0x842fd4[_0x39051f(0x222)][_0x39051f(0x233)])+'/schema',_0x3d4bd8=await fetch(_0x4d980b,{'method':_0x39051f(0x240),'headers':{'Content-Type':_0x39051f(0x1ef)},'body':JSON[_0x39051f(0x1f0)](_0x135b2a)});if(0x199===_0x3d4bd8[_0x39051f(0x1fc)]){const _0x450828=await _0x3d4bd8['json']()[_0x39051f(0x1d5)](()=>({})),_0x2bf2d=_0x450828?.[_0x39051f(0x1cf)]?.[_0x39051f(0x220)]?.[_0x39051f(0x1c6)]??_0x450828?.[_0x39051f(0x220)]?.[_0x39051f(0x1c6)]??_0x450828?.[_0x39051f(0x1cf)]?.[_0x39051f(0x1ce)]?.[_0x39051f(0x1c6)]??[];if(_0x2bf2d['length']>0x0){const _0x41524f=_0x2bf2d[_0x39051f(0x217)](0x0,0x5)[_0x39051f(0x232)](_0x2f5603=>_0x2f5603[_0x39051f(0x1d7)])[_0x39051f(0x228)](',\x20')+(_0x2bf2d[_0x39051f(0x1fe)]>0x5?'\x20…\x20(+'+(_0x2bf2d[_0x39051f(0x1fe)]-0x5)+_0x39051f(0x1db):'');this[_0x39051f(0x203)]='Cannot\x20enable\x20enforce\x20—\x20'+_0x2bf2d['length']+'\x20doc(s)\x20violate\x20the\x20schema:\x0a'+_0x41524f;}else this[_0x39051f(0x203)]=_0x450828?.['error']?.[_0x39051f(0x1c7)]||_0x450828?.['message']||_0x39051f(0x21d);return;}if(!_0x3d4bd8['ok']){const _0x31982d=await _0x3d4bd8[_0x39051f(0x204)]()['catch'](()=>({}));throw new Error(_0x31982d?.[_0x39051f(0x1cf)]?.[_0x39051f(0x1c7)]||_0x3d4bd8[_0x39051f(0x218)]);}_0x842fd4[_0x39051f(0x213)][_0x39051f(0x1e5)]?.[_0x39051f(0x238)]?.[_0x39051f(0x21e)]?.(_0x39051f(0x1e4)),await _0x842fd4['$attr']['modal'][_0x39051f(0x1e7)](),await _0x842fd4['$attr'][_0x39051f(0x1d4)]?.();}catch(_0x27b8c4){this['saveError']=_0x27b8c4[_0x39051f(0x1c7)]||_0x39051f(0x1d2);}finally{this[_0x39051f(0x1c5)]=!0x1;}},async 'remove'(){const _0x115083=_0x5f15ce;if(await _0x842fd4[_0x115083(0x213)][_0x115083(0x1e5)][_0x115083(0x239)][_0x115083(0x1c4)]('Remove\x20schema\x20from\x20\x22'+_0x842fd4[_0x115083(0x222)][_0x115083(0x233)]+_0x115083(0x215)))try{const _0x2dcf65=_0x842fd4[_0x115083(0x222)][_0x115083(0x23f)]??_0x842fd4[_0x115083(0x222)][_0x115083(0x1f1)]+_0x115083(0x230)+encodeURIComponent(_0x842fd4[_0x115083(0x222)][_0x115083(0x233)])+'/schema',_0x1218cb=await fetch(_0x2dcf65,{'method':'DELETE'});if(!_0x1218cb['ok']){const _0x2d9bc1=await _0x1218cb[_0x115083(0x204)]()[_0x115083(0x1d5)](()=>({}));throw new Error(_0x2d9bc1?.[_0x115083(0x1cf)]?.[_0x115083(0x1c7)]||_0x1218cb[_0x115083(0x218)]);}_0x842fd4[_0x115083(0x213)]['shared']?.[_0x115083(0x238)]?.[_0x115083(0x21a)]?.(_0x115083(0x1df)),await _0x842fd4[_0x115083(0x222)][_0x115083(0x239)][_0x115083(0x1e7)](),await _0x842fd4[_0x115083(0x222)][_0x115083(0x1d4)]?.();}catch(_0x58e776){_0x842fd4[_0x115083(0x213)][_0x115083(0x1e5)]?.[_0x115083(0x238)]?.[_0x115083(0x1cf)]?.(_0x58e776[_0x115083(0x1c7)]||'Remove\x20failed');}},'cancel'(){const _0x30c1b8=_0x5f15ce;_0x842fd4[_0x30c1b8(0x222)][_0x30c1b8(0x239)][_0x30c1b8(0x1e7)]();}}),'init'(){const _0x304d8b=_0x5f15ce;this[_0x304d8b(0x1e3)](),this[_0x304d8b(0x200)]();},'template':_0x5f15ce(0x226),'style':_0x5f15ce(0x1c8)};
|
|
1
|
+
import e from"@toolkit/elements/ok-icon.ok.js";import n from"@toolkit/core/ok-overlay.ok.js";import t from"../../../components/ok-json-input.ok.js";function i(e){return null==e?e:JSON.parse(JSON.stringify(e))}function o(e="",n="string"){return{name:e,type:n,nullable:!1,required:!1,description:"",enum:null,const:null,format:"",minimum:null,maximum:null,exclusiveMinimum:null,exclusiveMaximum:null,multipleOf:null,minLength:null,maxLength:null,pattern:"",minItems:null,maxItems:null,uniqueItems:!1,refType:"",refOnDelete:"no_action",children:[],childrenAdditionalProps:!0,items:null,expanded:!1,_extra:{}}}function a(e,n,t,r=0){const l=n.type;let s,d=!1;Array.isArray(l)?(d=l.includes("null"),s=l.find(e=>"null"!==e)||"string"):s=l||"string";const p=o(e,s);if(p.nullable=d,p.required=t,p.description=n.description||"",Array.isArray(n.enum)&&(p.enum=n.enum),void 0!==n.const&&(p.const={value:n.const}),n.format&&(p.format=n.format),void 0!==n.minimum&&(p.minimum=n.minimum),void 0!==n.maximum&&(p.maximum=n.maximum),void 0!==n.exclusiveMinimum&&(p.exclusiveMinimum=n.exclusiveMinimum),void 0!==n.exclusiveMaximum&&(p.exclusiveMaximum=n.exclusiveMaximum),void 0!==n.multipleOf&&(p.multipleOf=n.multipleOf),void 0!==n.minLength&&(p.minLength=n.minLength),void 0!==n.maxLength&&(p.maxLength=n.maxLength),n.pattern&&(p.pattern=n.pattern),void 0!==n.minItems&&(p.minItems=n.minItems),void 0!==n.maxItems&&(p.maxItems=n.maxItems),!0===n.uniqueItems&&(p.uniqueItems=!0),n.ref&&"object"==typeof n.ref&&n.ref.type&&(p.refType=n.ref.type,p.refOnDelete=n.ref.onDelete||"no_action"),"object"===s&&n.properties&&r<4){const e=new Set(n.required||[]);p.children=Object.entries(n.properties).map(([n,t])=>a(n,t,e.has(n),r+1)),p.childrenAdditionalProps=!1!==n.additionalProperties}"array"===s&&n.items&&"object"==typeof n.items&&r<4&&(p.items=a("(item)",n.items,!1,r+1));const c=new Set(["type","description","enum","const","format","minimum","maximum","exclusiveMinimum","exclusiveMaximum","multipleOf","minLength","maxLength","pattern","minItems","maxItems","uniqueItems","properties","required","additionalProperties","items","default","$ref","$defs","ref"]);for(const e of Object.keys(n))c.has(e)||(p._extra[e]=i(n[e]));return p}function r(e){const n={};if(e.nullable&&"null"!==e.type?n.type=[e.type,"null"]:n.type=e.type,e.description&&(n.description=e.description),e.enum&&e.enum.length>0&&(n.enum=e.enum),null!==e.const&&void 0!==e.const&&(n.const=e.const.value),e.format&&(n.format=e.format),null!==e.minimum&&void 0!==e.minimum&&(n.minimum=e.minimum),null!==e.maximum&&void 0!==e.maximum&&(n.maximum=e.maximum),null!==e.exclusiveMinimum&&void 0!==e.exclusiveMinimum&&(n.exclusiveMinimum=e.exclusiveMinimum),null!==e.exclusiveMaximum&&void 0!==e.exclusiveMaximum&&(n.exclusiveMaximum=e.exclusiveMaximum),null!==e.multipleOf&&void 0!==e.multipleOf&&(n.multipleOf=e.multipleOf),null!==e.minLength&&void 0!==e.minLength&&(n.minLength=e.minLength),null!==e.maxLength&&void 0!==e.maxLength&&(n.maxLength=e.maxLength),e.pattern&&(n.pattern=e.pattern),null!==e.minItems&&void 0!==e.minItems&&(n.minItems=e.minItems),null!==e.maxItems&&void 0!==e.maxItems&&(n.maxItems=e.maxItems),e.uniqueItems&&(n.uniqueItems=!0),e.refType&&(n.ref={type:e.refType},e.refOnDelete&&"no_action"!==e.refOnDelete&&(n.ref.onDelete=e.refOnDelete)),"object"===e.type&&e.children.length>0){n.properties={};const t=[];for(const i of e.children)n.properties[i.name]=r(i),i.required&&t.push(i.name);t.length>0&&(n.required=t),n.additionalProperties=e.childrenAdditionalProps}if("array"===e.type&&e.items&&(n.items=r(e.items)),e._extra)for(const[t,o]of Object.entries(e._extra))n[t]=i(o);return n}function l(e){if(!e||!e.properties)return[];const n=new Set(e.required||[]);return Object.entries(e.properties).map(([e,t])=>a(e,t,n.has(e),0))}function s(e,n){const t={},i=[];for(const n of e)t[n.name]=r(n),n.required&&i.push(n.name);const o={type:"object",properties:t};return i.length>0&&(o.required=i),o.additionalProperties=n,o}export default{tag:"schema-edit-modal",dependencies:[e,n,t],attr:{modal:{},type:{},schema:{},envApiBase:{},onDone:{},saveUrl:{},samplesUrl:{},hideEnforce:{}},context:e=>({mode:"visual",editDefinition:{},editEnforce:!1,rows:[],additionalProps:!0,saveBusy:!1,saveError:null,dirty:!1,newPropName:"",_newChildNames:{},typesList:[],get hasSchema(){return!!e.$attr.schema},get hideEnforce(){return!!e.$attr.hideEnforce},_init(){const n=e.$attr.schema;n?.definition?(this.editDefinition=i(n.definition),this.editEnforce=n.enforce??!1):(this.editDefinition={type:"object",properties:{},additionalProperties:!0},this.editEnforce=!1),this.rows=l(this.editDefinition),this.additionalProps=!1!==this.editDefinition.additionalProperties,this.dirty=!1,this.saveError=null},switchToVisual(){this.rows=l(this.editDefinition),this.additionalProps=!1!==this.editDefinition.additionalProperties,this.mode="visual"},switchToJson(){this.editDefinition=s(this.rows,this.additionalProps),this.mode="json"},addProperty(){const n=(this.newPropName||"").trim();n&&(this.rows.some(e=>e.name===n)?e.$ok.shared?.toast?.error?.(`Property "${n}" already exists`):(this.rows.push(o(n)),this.newPropName="",this.dirty=!0))},addChildProperty(n,t){const i=(this._newChildNames[t]||"").trim();i&&(n.children.some(e=>e.name===i)?e.$ok.shared?.toast?.error?.(`Property "${i}" already exists`):(n.children.push(o(i)),this._newChildNames[t]="",this.dirty=!0))},removeProperty(e,n){e.splice(n,1),this.dirty=!0},setRowField(e,n,t){e[n]=t,"type"===n&&("object"===t&&0===e.children.length&&(e.children=[],e.childrenAdditionalProps=!0),"array"!==t||e.items||(e.items=o("(item)","string"))),this.dirty=!0},toggleRowExpanded(e){e.expanded=!e.expanded},toggleRowRequired(e){e.required=!e.required,this.dirty=!0},toggleRowNullable(e){e.nullable=!e.nullable,this.dirty=!0},setChildrenAdditionalProps(e,n){e.childrenAdditionalProps=n,this.dirty=!0},setRowConstraint(e,n,t){["minimum","maximum","exclusiveMinimum","exclusiveMaximum","multipleOf","minLength","maxLength","minItems","maxItems"].includes(n)?e[n]=""===t||null===t?null:Number(t):"uniqueItems"===n?e[n]=!!t:"enum"===n?t&&""!==t.trim()?e.enum=t.split(",").map(e=>{e=e.trim();try{return JSON.parse(e)}catch{return e}}):e.enum=null:e[n]=t,this.dirty=!0},enumToString:e=>e&&Array.isArray(e)?e.map(e=>"string"==typeof e?e:JSON.stringify(e)).join(", "):"",setAdditionalProps(e){this.additionalProps=e,this.dirty=!0},async loadTypesList(){try{const n=await fetch(`${e.$attr.envApiBase}/types`);if(n.ok){const e=await n.json();this.typesList=(e.result??e.data??e.types??[]).map(e=>"string"==typeof e?e:e.type??e.name).filter(e=>e&&!e.startsWith("~")).sort()}}catch{}},setRowRef(e,n,t){"refType"===n?(e.refType=t,t||(e.refOnDelete="no_action")):"refOnDelete"===n&&(e.refOnDelete=t),this.dirty=!0},clearRowRef(e){e.refType="",e.refOnDelete="no_action",this.dirty=!0},setEditDefinition(e){this.editDefinition=e,this.dirty=!0},setEditEnforce(e){this.editEnforce=e,this.dirty=!0},async generateFromData(){if(e.$attr.type||e.$attr.samplesUrl)try{let n;if(e.$attr.samplesUrl){const t=await fetch(e.$attr.samplesUrl);if(!t.ok)throw new Error("Failed to fetch samples");const i=await t.json();n=(i.data??i.result??[]).map(e=>e.doc??e.payload??e.value??e)}else{const t=await fetch(`${e.$attr.envApiBase}/type/${encodeURIComponent(e.$attr.type)}/query`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filter:{},options:{limit:50}})});if(!t.ok)throw new Error("Failed to fetch data");const i=await t.json();n=(i.data??i.result??[]).map(e=>e.doc??e.value??e)}if(0===n.length)return void e.$ok.shared?.toast?.info?.("No documents found to infer schema from.");e.$ok.shared?.toast?.info?.(`Inferring from ${n.length} documents…`);const t=this._inferSchemaFromData(n);this.editDefinition=t,this.rows=l(t),this.additionalProps=!1!==t.additionalProperties,this.dirty=!0}catch(n){e.$ok.shared?.toast?.error?.(n.message)}},_inferSchemaFromData(e){function n(e){return null===e?"null":Array.isArray(e)?"array":"object"==typeof e?"object":typeof e}return function e(t){let i=[...new Set(t.map(n).filter(e=>"undefined"!==e))];if(0===i.length)return{type:"string"};i.includes("null")&&i.length>1&&(i=i.filter(e=>"null"!==e));let o=1===i.length?{type:i[0]}:{type:i};if(i.includes("object")){let i={},a=new Set(t.filter(e=>"object"===n(e)&&null!==e).flatMap(Object.keys));for(let o of a){let a=t.filter(e=>"object"===n(e)&&null!==e).map(e=>e[o]);i[o]=e(a)}o.properties=i,o.additionalProperties=!1}if(i.includes("array")){let i=t.filter(e=>"array"===n(e)).flat();i.length>0&&(o.items=e(i))}return o}(e)},async save(){this.saveBusy=!0,this.saveError=null;try{const n={definition:"visual"===this.mode?s(this.rows,this.additionalProps):this.editDefinition,enforce:!!e.$attr.hideEnforce||this.editEnforce},t=e.$attr.saveUrl??`${e.$attr.envApiBase}/type/${encodeURIComponent(e.$attr.type)}/schema`,i=await fetch(t,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)});if(409===i.status){const e=await i.json().catch(()=>({})),n=e?.error?.details?.failures??e?.details?.failures??e?.error?.data?.failures??[];if(n.length>0){const e=n.slice(0,5).map(e=>e.key).join(", ")+(n.length>5?` … (+${n.length-5} more)`:"");this.saveError=`Cannot enable enforce — ${n.length} doc(s) violate the schema:\n${e}`}else this.saveError=e?.error?.message||e?.message||"Schema conflicts with existing data";return}if(!i.ok){const e=await i.json().catch(()=>({}));throw new Error(e?.error?.message||i.statusText)}e.$ok.shared?.toast?.success?.("Schema saved"),await e.$attr.modal.close(),await(e.$attr.onDone?.())}catch(e){this.saveError=e.message||"Save failed"}finally{this.saveBusy=!1}},async remove(){if(await e.$ok.shared.modal.confirm(`Remove schema from "${e.$attr.type}"? Validation will be disabled.`))try{const n=e.$attr.saveUrl??`${e.$attr.envApiBase}/type/${encodeURIComponent(e.$attr.type)}/schema`,t=await fetch(n,{method:"DELETE"});if(!t.ok){const e=await t.json().catch(()=>({}));throw new Error(e?.error?.message||t.statusText)}e.$ok.shared?.toast?.info?.("Schema removed"),await e.$attr.modal.close(),await(e.$attr.onDone?.())}catch(n){e.$ok.shared?.toast?.error?.(n.message||"Remove failed")}},cancel(){e.$attr.modal.close()}}),init(){this._init(),this.loadTypesList()},template:'\n<div class="sem-root">\n\n <if :="saveBusy">\n <ok-overlay>\n <div class="loader-center"><ok-icon name="loader" class="spin" style="width:32px;height:32px;"></ok-icon></div>\n </ok-overlay>\n </if>\n\n \x3c!-- Toolbar --\x3e\n <div class="sem-toolbar">\n <div class="seg-toggle">\n <button :class="mode === \'visual\' ? \'active\' : \'\'" @click="switchToVisual()">Visual</button>\n <button :class="mode === \'json\' ? \'active\' : \'\'" @click="switchToJson()">JSON</button>\n </div>\n\n <if :="!hideEnforce">\n <label style="font-size:13px; display:flex; align-items:center; gap:6px; cursor:pointer; user-select:none; margin-left:16px;">\n <input type="checkbox" :checked="editEnforce" @change="setEditEnforce($event.target.checked)" />\n Enforce mode\n <span style="font-size:11px; opacity:.4;">(reject writes that violate)</span>\n </label>\n </if>\n\n <div style="margin-left:auto; display:flex; gap:8px;">\n <button @click="generateFromData()" class="btn-icon" style="font-size:11px; padding:3px 10px; opacity:.75;" title="Sample latest documents to build a schema">\n <ok-icon name="zap"></ok-icon> Infer from data\n </button>\n </div>\n </div>\n\n \x3c!-- ═══════ Visual mode ═══════ --\x3e\n <if :="mode === \'visual\'">\n <div class="sem-visual">\n\n \x3c!-- Properties table header --\x3e\n <div class="sem-props-hdr">\n <div></div><div>Property</div><div>Type</div><div>Req</div><div>Null</div><div>Description</div><div></div>\n </div>\n\n \x3c!-- Recursive row rendering for depth 0 --\x3e\n <each :of="rows" let:item="row" let:index="i">\n\n \x3c!-- Main property row --\x3e\n <div class="sem-props-row">\n <div class="sem-expand-col">\n <button\n @click="toggleRowExpanded(row)"\n class="sem-expand-btn"\n :class="row.expanded ? \'sem-expanded\' : \'\'"\n title="Toggle details"\n >›</button>\n </div>\n <div class="sem-prop-name"><code>{{ row.name }}</code></div>\n <div>\n <select :value="row.type" @change="setRowField(row, \'type\', $event.target.value)" style="min-width:90px;">\n <option value="string">string</option>\n <option value="number">number</option>\n <option value="integer">integer</option>\n <option value="boolean">boolean</option>\n <option value="object">object</option>\n <option value="array">array</option>\n </select>\n </div>\n <div style="text-align:center;">\n <input type="checkbox" :checked="row.required" @change="toggleRowRequired(row)" />\n </div>\n <div style="text-align:center;">\n <input type="checkbox" :checked="row.nullable" @change="toggleRowNullable(row)" />\n </div>\n <div style="overflow:hidden; min-width:0;">\n <input type="text" :value="row.description" @input="setRowField(row, \'description\', $event.target.value)" placeholder="—" style="width:100%; font-size:12px; box-sizing:border-box;" />\n </div>\n <div style="display:flex; align-items:center; justify-content:center;">\n <button @click="removeProperty(rows, i)" style="color:var(--okdb-danger); background:none; border:none; cursor:pointer; padding:2px 6px; font-size:14px; line-height:1;" title="Remove property">×</button>\n </div>\n </div>\n\n \x3c!-- ── Expanded detail panel ── --\x3e\n <if :="row.expanded">\n <div class="sem-detail-panel">\n\n \x3c!-- ── String constraints ── --\x3e\n <if :="row.type === \'string\'">\n <div class="sem-constraints-grid">\n <label>Format</label>\n <select :value="row.format || \'\'" @change="setRowConstraint(row, \'format\', $event.target.value)">\n <option value="">—</option>\n <option value="date-time">date-time</option>\n <option value="date">date</option>\n <option value="time">time</option>\n <option value="email">email</option>\n <option value="uri">uri</option>\n <option value="uuid">uuid</option>\n <option value="ipv4">ipv4</option>\n <option value="ipv6">ipv6</option>\n <option value="hostname">hostname</option>\n </select>\n <label>Min Length</label>\n <input type="number" :value="row.minLength ?? \'\'" @input="setRowConstraint(row, \'minLength\', $event.target.value)" min="0" />\n <label>Max Length</label>\n <input type="number" :value="row.maxLength ?? \'\'" @input="setRowConstraint(row, \'maxLength\', $event.target.value)" min="0" />\n <label>Pattern</label>\n <input type="text" :value="row.pattern" @input="setRowConstraint(row, \'pattern\', $event.target.value)" placeholder="regex…" />\n </div>\n </if>\n\n \x3c!-- ── Number / Integer constraints ── --\x3e\n <if :="row.type === \'number\' || row.type === \'integer\'">\n <div class="sem-constraints-grid">\n <label>Minimum</label>\n <input type="number" :value="row.minimum ?? \'\'" @input="setRowConstraint(row, \'minimum\', $event.target.value)" />\n <label>Maximum</label>\n <input type="number" :value="row.maximum ?? \'\'" @input="setRowConstraint(row, \'maximum\', $event.target.value)" />\n <label>Excl. Min</label>\n <input type="number" :value="row.exclusiveMinimum ?? \'\'" @input="setRowConstraint(row, \'exclusiveMinimum\', $event.target.value)" />\n <label>Excl. Max</label>\n <input type="number" :value="row.exclusiveMaximum ?? \'\'" @input="setRowConstraint(row, \'exclusiveMaximum\', $event.target.value)" />\n <label>Multiple Of</label>\n <input type="number" :value="row.multipleOf ?? \'\'" @input="setRowConstraint(row, \'multipleOf\', $event.target.value)" min="0" />\n </div>\n </if>\n\n \x3c!-- ── Array constraints ── --\x3e\n <if :="row.type === \'array\'">\n <div class="sem-constraints-grid">\n <label>Min Items</label>\n <input type="number" :value="row.minItems ?? \'\'" @input="setRowConstraint(row, \'minItems\', $event.target.value)" min="0" />\n <label>Max Items</label>\n <input type="number" :value="row.maxItems ?? \'\'" @input="setRowConstraint(row, \'maxItems\', $event.target.value)" min="0" />\n <label>Unique</label>\n <label style="display:flex; align-items:center; gap:4px; cursor:pointer;">\n <input type="checkbox" :checked="row.uniqueItems" @change="setRowConstraint(row, \'uniqueItems\', $event.target.checked)" />\n unique items\n </label>\n </div>\n </if>\n\n \x3c!-- ── Enum (all types) ── --\x3e\n <div class="sem-constraint-row">\n <label>Enum</label>\n <input type="text" :value="enumToString(row.enum)" @change="setRowConstraint(row, \'enum\', $event.target.value)" placeholder="comma-separated values…" style="flex:1;" />\n <span class="sem-hint">e.g. active, inactive, pending</span>\n </div>\n\n \x3c!-- ── Foreign Key Reference ── --\x3e\n <if :="row.type === \'string\' || row.type === \'integer\' || row.type === \'number\'">\n <div class="sem-fk-section">\n <div class="sem-fk-label">\n <ok-icon name="link" style="width:12px; height:12px; opacity:.6;"></ok-icon>\n Foreign Key\n </div>\n <div class="sem-fk-row">\n <label>Target type</label>\n <select :value="row.refType || \'\'" @change="setRowRef(row, \'refType\', $event.target.value)">\n <option value="">— none —</option>\n <each :of="typesList" let:item="t">\n <option :value="t">{{ t }}</option>\n </each>\n </select>\n <if :="row.refType">\n <label>On delete</label>\n <select :value="row.refOnDelete || \'no_action\'" @change="setRowRef(row, \'refOnDelete\', $event.target.value)">\n <option value="no_action">no action</option>\n <option value="cascade">cascade</option>\n <option value="set_null">set null</option>\n <option value="restrict">restrict</option>\n </select>\n <button @click="clearRowRef(row)" class="sem-fk-clear" title="Remove foreign key">×</button>\n </if>\n </div>\n <if :="row.refType">\n <div class="sem-fk-hint">\n This field references a key in <strong>{{ row.refType }}</strong>.\n <if :="row.refOnDelete === \'cascade\'">Deleting the target will delete this document.</if>\n <if :="row.refOnDelete === \'set_null\'">Deleting the target will set this field to null.</if>\n <if :="row.refOnDelete === \'restrict\'">Deleting the target will be blocked while this reference exists.</if>\n <if :="row.refOnDelete === \'no_action\'">Deleting the target will leave this field as a dangling reference.</if>\n </div>\n </if>\n </div>\n </if>\n\n \x3c!-- ── Array items schema ── --\x3e\n <if :="row.type === \'array\'">\n <div class="sem-nested-section">\n <div class="sem-nested-label">Item Schema</div>\n <if :="row.items">\n <div class="sem-nested-row">\n <select :value="row.items.type" @change="setRowField(row.items, \'type\', $event.target.value)" style="min-width:90px;">\n <option value="string">string</option>\n <option value="number">number</option>\n <option value="integer">integer</option>\n <option value="boolean">boolean</option>\n <option value="object">object</option>\n <option value="array">array</option>\n </select>\n <if :="row.items.type === \'string\'">\n <select :value="row.items.format || \'\'" @change="setRowConstraint(row.items, \'format\', $event.target.value)" title="Format">\n <option value="">no format</option>\n <option value="date-time">date-time</option>\n <option value="date">date</option>\n <option value="email">email</option>\n <option value="uri">uri</option>\n <option value="uuid">uuid</option>\n </select>\n </if>\n </div>\n\n \x3c!-- If items type is object, show nested properties --\x3e\n <if :="row.items.type === \'object\'">\n <div class="sem-nested-children">\n <each :of="row.items.children" let:item="child" let:index="ci">\n <div class="sem-nested-child-row">\n <code class="sem-child-name">{{ child.name }}</code>\n <select :value="child.type" @change="setRowField(child, \'type\', $event.target.value)" style="min-width:80px;">\n <option value="string">string</option>\n <option value="number">number</option>\n <option value="integer">integer</option>\n <option value="boolean">boolean</option>\n <option value="object">object</option>\n <option value="array">array</option>\n </select>\n <label style="font-size:11px; display:flex; align-items:center; gap:3px; cursor:pointer;">\n <input type="checkbox" :checked="child.required" @change="toggleRowRequired(child)" /> req\n </label>\n <label style="font-size:11px; display:flex; align-items:center; gap:3px; cursor:pointer;">\n <input type="checkbox" :checked="child.nullable" @change="toggleRowNullable(child)" /> null\n </label>\n <button @click="removeProperty(row.items.children, ci)" style="color:var(--okdb-danger); background:none; border:none; cursor:pointer; font-size:13px;">×</button>\n </div>\n </each>\n <div class="sem-add-child-row">\n <input type="text" :value="_newChildNames[\'items_\' + row.name] || \'\'" @input="_newChildNames[\'items_\' + row.name] = $event.target.value" @keydown.enter="addChildProperty(row.items, \'items_\' + row.name)" placeholder="Add item property…" style="flex:1; font-size:11px;" />\n <button @click="addChildProperty(row.items, \'items_\' + row.name)" class="btn-icon" style="font-size:10px; padding:2px 8px;">+</button>\n </div>\n </div>\n </if>\n </if>\n </div>\n </if>\n\n \x3c!-- ── Nested object properties ── --\x3e\n <if :="row.type === \'object\'">\n <div class="sem-nested-section">\n <div class="sem-nested-label">\n Properties\n <label style="font-size:11px; display:flex; align-items:center; gap:4px; cursor:pointer; margin-left:auto; font-weight:normal; opacity:.6;">\n <input type="checkbox" :checked="row.childrenAdditionalProps" @change="setChildrenAdditionalProps(row, $event.target.checked)" />\n allow additional\n </label>\n </div>\n <div class="sem-nested-children">\n <each :of="row.children" let:item="child" let:index="ci">\n <div class="sem-nested-child-row">\n <code class="sem-child-name">{{ child.name }}</code>\n <select :value="child.type" @change="setRowField(child, \'type\', $event.target.value)" style="min-width:80px;">\n <option value="string">string</option>\n <option value="number">number</option>\n <option value="integer">integer</option>\n <option value="boolean">boolean</option>\n <option value="object">object</option>\n <option value="array">array</option>\n </select>\n <label style="font-size:11px; display:flex; align-items:center; gap:3px; cursor:pointer;">\n <input type="checkbox" :checked="child.required" @change="toggleRowRequired(child)" /> req\n </label>\n <label style="font-size:11px; display:flex; align-items:center; gap:3px; cursor:pointer;">\n <input type="checkbox" :checked="child.nullable" @change="toggleRowNullable(child)" /> null\n </label>\n <input type="text" :value="child.description" @input="setRowField(child, \'description\', $event.target.value)" placeholder="desc" style="flex:1; font-size:11px; min-width:60px;" />\n <button @click="removeProperty(row.children, ci)" style="color:var(--okdb-danger); background:none; border:none; cursor:pointer; font-size:13px;">×</button>\n </div>\n\n \x3c!-- 2nd-level nested: show sub-properties for object children --\x3e\n <if :="child.type === \'object\' && child.children.length > 0">\n <div class="sem-nested-l2">\n <each :of="child.children" let:item="gc" let:index="gci">\n <div class="sem-nested-child-row">\n <code class="sem-child-name" style="font-size:10px;">{{ gc.name }}</code>\n <select :value="gc.type" @change="setRowField(gc, \'type\', $event.target.value)" style="min-width:70px; font-size:11px;">\n <option value="string">string</option>\n <option value="number">number</option>\n <option value="integer">integer</option>\n <option value="boolean">boolean</option>\n <option value="object">object</option>\n <option value="array">array</option>\n </select>\n <label style="font-size:10px; display:flex; align-items:center; gap:2px; cursor:pointer;">\n <input type="checkbox" :checked="gc.required" @change="toggleRowRequired(gc)" /> req\n </label>\n <button @click="removeProperty(child.children, gci)" style="color:var(--okdb-danger); background:none; border:none; cursor:pointer; font-size:12px;">×</button>\n </div>\n </each>\n <div class="sem-add-child-row">\n <input type="text" :value="_newChildNames[\'l2_\' + row.name + \'.\' + child.name] || \'\'" @input="_newChildNames[\'l2_\' + row.name + \'.\' + child.name] = $event.target.value" @keydown.enter="addChildProperty(child, \'l2_\' + row.name + \'.\' + child.name)" placeholder="Add sub-property…" style="flex:1; font-size:10px;" />\n <button @click="addChildProperty(child, \'l2_\' + row.name + \'.\' + child.name)" class="btn-icon" style="font-size:10px; padding:2px 6px;">+</button>\n </div>\n </div>\n </if>\n\n <if :="child.type === \'object\' && child.children.length === 0">\n <div class="sem-add-child-row" style="margin-left:24px;">\n <input type="text" :value="_newChildNames[\'l2_\' + row.name + \'.\' + child.name] || \'\'" @input="_newChildNames[\'l2_\' + row.name + \'.\' + child.name] = $event.target.value" @keydown.enter="addChildProperty(child, \'l2_\' + row.name + \'.\' + child.name)" placeholder="Add sub-property…" style="flex:1; font-size:10px;" />\n <button @click="addChildProperty(child, \'l2_\' + row.name + \'.\' + child.name)" class="btn-icon" style="font-size:10px; padding:2px 6px;">+</button>\n </div>\n </if>\n </each>\n <div class="sem-add-child-row">\n <input type="text" :value="_newChildNames[\'obj_\' + row.name] || \'\'" @input="_newChildNames[\'obj_\' + row.name] = $event.target.value" @keydown.enter="addChildProperty(row, \'obj_\' + row.name)" placeholder="Add property…" style="flex:1; font-size:11px;" />\n <button @click="addChildProperty(row, \'obj_\' + row.name)" class="btn-icon" style="font-size:10px; padding:2px 8px;">+</button>\n </div>\n </div>\n </div>\n </if>\n\n </div>\n </if>\n\n </each>\n\n <if :="rows.length === 0">\n <div style="padding:16px 0; opacity:.4; font-size:13px;">No properties defined yet. Add one below.</div>\n </if>\n\n \x3c!-- Add property --\x3e\n <div class="sem-add-row">\n <input type="text" :value="newPropName" @input="newPropName = $event.target.value" @keydown.enter="addProperty()" placeholder="New property name…" style="flex:1; min-width:140px;" />\n <button @click="addProperty()" class="btn-icon" style="font-size:12px; padding:3px 12px;" :disabled="!newPropName.trim()">\n <ok-icon name="plus"></ok-icon>Add\n </button>\n </div>\n\n \x3c!-- Additional properties toggle --\x3e\n <label style="font-size:12px; display:flex; align-items:center; gap:6px; cursor:pointer; user-select:none; padding:8px 0 0;">\n <input type="checkbox" :checked="additionalProps" @change="setAdditionalProps($event.target.checked)" />\n Allow additional properties\n <span style="font-size:11px; opacity:.4;">(fields not listed above)</span>\n </label>\n </div>\n </if>\n\n \x3c!-- ═══════ JSON mode ═══════ --\x3e\n <if :="mode === \'json\'">\n <div class="sem-json">\n <ok-json-input\n :value="editDefinition"\n @change="setEditDefinition($event.detail)"\n style="min-height:300px; flex:1; width:100%;">\n </ok-json-input>\n </div>\n </if>\n\n \x3c!-- Save error --\x3e\n <if :="saveError">\n <div class="sem-error">{{ saveError }}</div>\n </if>\n\n \x3c!-- Actions --\x3e\n <div class="sem-actions">\n <button @click="cancel()" style="opacity:.7;">Cancel</button>\n <if :="hasSchema">\n <button @click="remove()" class="btn-icon" style="color:var(--okdb-danger); opacity:.8; font-size:12px; padding:5px 12px;">\n <ok-icon name="trash-2"></ok-icon>Remove schema\n </button>\n </if>\n <button @click="save()" :disabled="saveBusy" class="btn-icon" style="font-size:12px; padding:5px 14px; margin-left:auto;">\n <ok-icon name="save"></ok-icon>\n {{ hasSchema ? \'Update Schema\' : \'Set Schema\' }}\n </button>\n </div>\n</div>\n',style:"\n schema-edit-modal .sem-root {\n display: flex;\n flex-direction: column;\n gap: 12px;\n min-width: 640px;\n max-width: 960px;\n position: relative;\n }\n schema-edit-modal .sem-toolbar {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n }\n schema-edit-modal .sem-visual {\n display: flex;\n flex-direction: column;\n gap: 0;\n max-height: 60vh;\n overflow: auto;\n }\n schema-edit-modal .sem-props-hdr {\n display: grid;\n grid-template-columns: 28px minmax(100px, 1.5fr) 110px 36px 36px 1fr 32px;\n gap: 0 8px;\n padding: 0 0 6px;\n border-bottom: 1px solid var(--okdb-app-border);\n font-size: 11px;\n opacity: .4;\n text-transform: uppercase;\n letter-spacing: .04em;\n }\n schema-edit-modal .sem-props-row {\n display: grid;\n grid-template-columns: 28px minmax(100px, 1.5fr) 110px 36px 36px 1fr 32px;\n gap: 0 8px;\n align-items: center;\n padding: 6px 0;\n border-bottom: 1px solid var(--okdb-app-surface);\n }\n schema-edit-modal .sem-expand-col {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n schema-edit-modal .sem-expand-btn {\n background: none;\n border: none;\n color: var(--okdb-app-fg-muted);\n font-size: 16px;\n cursor: pointer;\n padding: 0 4px;\n transition: transform .15s;\n line-height: 1;\n opacity: .5;\n }\n schema-edit-modal .sem-expand-btn:hover { opacity: 1; }\n schema-edit-modal .sem-expand-btn.sem-expanded { transform: rotate(90deg); opacity: .8; }\n schema-edit-modal .sem-prop-name {\n overflow: hidden;\n }\n schema-edit-modal .sem-prop-name code {\n font-size: 12px;\n color: var(--okdb-json-key);\n }\n\n /* ── Detail / constraints panel ── */\n schema-edit-modal .sem-detail-panel {\n padding: 8px 12px 12px 36px;\n background: var(--okdb-app-bg-deep);\n border-bottom: 1px solid var(--okdb-app-surface);\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n schema-edit-modal .sem-constraints-grid {\n display: grid;\n grid-template-columns: 80px 1fr 80px 1fr;\n gap: 6px 10px;\n align-items: center;\n font-size: 11px;\n }\n schema-edit-modal .sem-constraints-grid label {\n opacity: .55;\n font-size: 11px;\n white-space: nowrap;\n }\n schema-edit-modal .sem-constraints-grid input,\n schema-edit-modal .sem-constraints-grid select {\n font-size: 12px;\n padding: 3px 6px;\n }\n schema-edit-modal .sem-constraint-row {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 11px;\n }\n schema-edit-modal .sem-constraint-row label {\n opacity: .55;\n white-space: nowrap;\n min-width: 40px;\n }\n schema-edit-modal .sem-hint {\n opacity: .35;\n font-size: 10px;\n white-space: nowrap;\n }\n\n /* ── Nested object/array section ── */\n schema-edit-modal .sem-nested-section {\n border-left: 2px solid var(--okdb-app-border);\n padding-left: 12px;\n margin-top: 2px;\n }\n schema-edit-modal .sem-nested-label {\n font-size: 11px;\n font-weight: 600;\n opacity: .6;\n text-transform: uppercase;\n letter-spacing: .04em;\n margin-bottom: 6px;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n schema-edit-modal .sem-nested-row {\n display: flex;\n gap: 8px;\n align-items: center;\n margin-bottom: 6px;\n }\n schema-edit-modal .sem-nested-children {\n display: flex;\n flex-direction: column;\n gap: 0;\n }\n schema-edit-modal .sem-nested-child-row {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 4px 0;\n border-bottom: 1px solid color-mix(in srgb, var(--okdb-app-border) 40%, transparent);\n font-size: 12px;\n }\n schema-edit-modal .sem-child-name {\n font-size: 11px;\n color: var(--okdb-purple);\n font-family: monospace;\n min-width: 60px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n schema-edit-modal .sem-nested-l2 {\n margin-left: 24px;\n border-left: 1px solid var(--okdb-app-border)66;\n padding-left: 10px;\n margin-bottom: 4px;\n }\n schema-edit-modal .sem-add-child-row {\n display: flex;\n gap: 6px;\n align-items: center;\n padding: 4px 0;\n }\n\n schema-edit-modal .sem-add-row {\n display: flex;\n gap: 8px;\n align-items: center;\n padding: 10px 0 0;\n }\n\n /* ── Foreign key section ── */\n schema-edit-modal .sem-fk-section {\n border: 1px solid #6366f133;\n border-radius: 6px;\n padding: 8px 10px;\n background: #6366f108;\n }\n schema-edit-modal .sem-fk-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: .04em;\n opacity: .7;\n margin-bottom: 6px;\n display: flex;\n align-items: center;\n gap: 5px;\n color: var(--okdb-indigo);\n }\n schema-edit-modal .sem-fk-row {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 12px;\n }\n schema-edit-modal .sem-fk-row label {\n opacity: .55;\n font-size: 11px;\n white-space: nowrap;\n }\n schema-edit-modal .sem-fk-row select {\n font-size: 12px;\n padding: 3px 6px;\n min-width: 100px;\n }\n schema-edit-modal .sem-fk-clear {\n background: none;\n border: none;\n color: var(--okdb-danger);\n cursor: pointer;\n font-size: 14px;\n padding: 2px 6px;\n line-height: 1;\n opacity: .7;\n }\n schema-edit-modal .sem-fk-clear:hover { opacity: 1; }\n schema-edit-modal .sem-fk-hint {\n font-size: 11px;\n opacity: .5;\n margin-top: 5px;\n line-height: 1.4;\n }\n schema-edit-modal .sem-fk-hint strong {\n color: var(--okdb-indigo);\n opacity: 1;\n }\n\n schema-edit-modal .sem-json {\n display: flex;\n flex-direction: column;\n min-height: 300px;\n }\n schema-edit-modal .sem-error {\n color: var(--okdb-danger);\n font-size: 12px;\n padding: 8px 10px;\n border-radius: 8px;\n border: 1px solid color-mix(in srgb, var(--okdb-danger) 20%, transparent);\n background: color-mix(in srgb, var(--okdb-danger) 4%, transparent);\n white-space: pre-wrap;\n line-height: 1.5;\n }\n schema-edit-modal .sem-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n padding-top: 4px;\n border-top: 1px solid var(--okdb-app-border);\n }\n "};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const _0x13dc4f=_0x5def;function _0x5def(_0x47b6f7,_0x40270e){_0x47b6f7=_0x47b6f7-0xf9;const _0x513b2d=_0x513b();let _0x5def64=_0x513b2d[_0x47b6f7];return _0x5def64;}(function(_0x4b37ab,_0x270c82){const _0x3a8976=_0x5def,_0xfa1405=_0x4b37ab();while(!![]){try{const _0x548950=parseInt(_0x3a8976(0x18c))/0x1+-parseInt(_0x3a8976(0x101))/0x2*(parseInt(_0x3a8976(0x17c))/0x3)+parseInt(_0x3a8976(0x175))/0x4*(parseInt(_0x3a8976(0x158))/0x5)+-parseInt(_0x3a8976(0x10a))/0x6+-parseInt(_0x3a8976(0x15f))/0x7+parseInt(_0x3a8976(0x16a))/0x8*(-parseInt(_0x3a8976(0x156))/0x9)+parseInt(_0x3a8976(0x14a))/0xa;if(_0x548950===_0x270c82)break;else _0xfa1405['push'](_0xfa1405['shift']());}catch(_0x409706){_0xfa1405['push'](_0xfa1405['shift']());}}}(_0x513b,0xd3f72));function _0x513b(){const _0x48c45b=['keys','loadRecent','var(--okdb-sky)','join','db-overview','pipeline:delete','_unsubs','recentError','20208010KAvGVe','/env/','/time-machine/enable','toLowerCase','types','h\x20ago','Failed\x20to\x20load\x20changes','count','var(--okdb-accent)','engine:started','pipelinesError','/pipelines','9xiPJuB','replace','75265ZslxJQ','engines','reloadOverviewData','tmScanMsg','_reloadTypes','/time-machine/status','data','5382272SaMIUK','reloadTypes','indexes','open','online','\x0a<div\x20style=\x22display:flex;\x20flex-direction:column;\x20gap:20px;\x20max-width:860px;\x22>\x0a\x0a\x20\x20<!--\x20Header\x20-->\x0a\x20\x20<div\x20style=\x22display:flex;\x20align-items:center;\x20gap:10px;\x22>\x0a\x20\x20\x20\x20<div\x20style=\x22font-weight:600;\x20font-size:18px;\x22>Database\x20Overview</div>\x0a\x20\x20\x20\x20<if\x20:=\x22recentBusy\x22>\x0a\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:12px;\x20opacity:.4;\x22>updating…</span>\x0a\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20<div\x20style=\x22margin-left:auto;\x22>\x0a\x20\x20\x20\x20\x20\x20<button\x20@click=\x22loadRecent()\x22\x20:disabled=\x22recentBusy\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20style=\x22font-size:12px;\x20padding:5px\x2012px;\x20opacity:.75;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20↻\x20Refresh\x0a\x20\x20\x20\x20\x20\x20</button>\x0a\x20\x20\x20\x20</div>\x0a\x20\x20</div>\x0a\x0a\x20\x20<!--\x20Stat\x20cards\x20row\x20-->\x0a\x20\x20<div\x20class=\x22ov-stat-row\x22>\x0a\x20\x20\x20\x20<div\x20class=\x22ov-stat-card\x22>\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-stat-label\x22>DB\x20Size</div>\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-stat-value\x22\x20style=\x22color:var(--accent);\x22>{{\x20approxSize\x20}}</div>\x0a\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20<div\x20class=\x22ov-stat-card\x22>\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-stat-label\x22>Clock</div>\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-stat-value\x22\x20style=\x22font-family:monospace;\x20font-size:18px;\x22>{{\x20fmt(info?.clock)\x20}}</div>\x0a\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20<div\x20class=\x22ov-stat-card\x22>\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-stat-label\x22>User\x20Types</div>\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-stat-value\x22\x20style=\x22color:var(--okdb-purple);\x22>{{\x20types.length\x20}}</div>\x0a\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20<div\x20class=\x22ov-stat-card\x22>\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-stat-label\x22>Total\x20Records</div>\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-stat-value\x22\x20style=\x22color:var(--okdb-success);\x22>{{\x20fmt(totalRecords)\x20}}</div>\x0a\x20\x20\x20\x20</div>\x0a\x20\x20</div>\x0a\x0a\x20\x20<!--\x20Empty\x20state\x20-->\x0a\x20\x20<if\x20:=\x22types.length\x20===\x200\x22>\x0a\x20\x20\x20\x20<div\x20style=\x22display:flex;\x20flex-direction:column;\x20gap:14px;\x22>\x0a\x0a\x20\x20\x20\x20\x20\x20<!--\x20Standard\x20empty\x20hint\x20-->\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-empty\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22font-size:30px;\x20margin-bottom:12px;\x22>🗄️</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22font-weight:600;\x20font-size:15px;\x20margin-bottom:5px;\x22>No\x20types\x20registered\x20yet</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22font-size:13px;\x20opacity:.6;\x20line-height:1.7;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20Use\x20<b>Register\x20Type\x20+</b>\x20in\x20the\x20sidebar\x20to\x20create\x20your\x20first\x20collection.<br>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20Types\x20are\x20strongly-typed\x20document\x20collections\x20stored\x20in\x20LMDB.\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</div>\x0a\x0a\x20\x20\x20\x20\x20\x20<!--\x20Demo\x20data\x20card\x20-->\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-demo-card\x22\x20@click=\x22openDemoModal()\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-demo-card__aurora\x22></div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22position:relative;\x20z-index:1;\x20display:flex;\x20flex-direction:column;\x20align-items:center;\x20gap:10px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-demo-card__sparkle\x22>✦</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-demo-card__title\x22>Generate\x20Demo\x20Environment</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-demo-card__desc\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20Instantly\x20populate\x20a\x20new\x20environment\x20with\x20realistic\x20data,\x20indexes,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20and\x20full-text\x20search\x20—\x20ready\x20to\x20explore\x20in\x20seconds.\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-demo-card__badges\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22ov-demo-badge\x22\x20style=\x22color:var(--okdb-success);\x20border-color:color-mix(in\x20srgb,\x20var(--okdb-success)\x2020%,\x20transparent);\x20background:color-mix(in\x20srgb,\x20var(--okdb-success)\x207%,\x20transparent);\x22>🛒\x20E-Commerce</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22ov-demo-badge\x22\x20style=\x22color:var(--okdb-accent);\x20border-color:color-mix(in\x20srgb,\x20var(--okdb-accent)\x2020%,\x20transparent);\x20background:color-mix(in\x20srgb,\x20var(--okdb-accent)\x207%,\x20transparent);\x22>📊\x20Analytics</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22ov-demo-badge\x22\x20style=\x22color:var(--okdb-purple);\x20border-color:color-mix(in\x20srgb,\x20var(--okdb-purple)\x2020%,\x20transparent);\x20background:color-mix(in\x20srgb,\x20var(--okdb-purple)\x207%,\x20transparent);\x22>📝\x20Content\x20Hub</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22ov-demo-badge\x22\x20style=\x22color:var(--okdb-warning);\x20border-color:color-mix(in\x20srgb,\x20var(--okdb-warning)\x2020%,\x20transparent);\x20background:color-mix(in\x20srgb,\x20var(--okdb-warning)\x207%,\x20transparent);\x22>👥\x20Team\x20Directory</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22ov-demo-badge\x22\x20style=\x22color:var(--okdb-orange);\x20border-color:color-mix(in\x20srgb,\x20var(--okdb-orange)\x2020%,\x20transparent);\x20background:color-mix(in\x20srgb,\x20var(--okdb-orange)\x207%,\x20transparent);\x22>🗺️\x20City\x20Explorer</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-demo-card__cta\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span>Choose\x20a\x20preset</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22margin-left:6px;\x20font-size:14px;\x22>→</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</div>\x0a\x0a\x20\x20\x20\x20</div>\x0a\x20\x20</if>\x0a\x0a\x20\x20<!--\x20Types\x20table\x20-->\x0a\x20\x20<if\x20:=\x22types.length\x20>\x200\x22>\x0a\x20\x20\x20\x20<div\x20class=\x22ov-card\x22>\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-card-head\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-weight:600;\x20font-size:14px;\x22>Types</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:12px;\x20opacity:.45;\x20margin-left:auto;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{{\x20types.length\x20}}\x20user · {{\x20systemTypes.length\x20}}\x20system\x0a\x20\x20\x20\x20\x20\x20\x20\x20</span>\x0a\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20<table\x20class=\x22ov-table\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<thead>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<tr>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<th>Name</th>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<th\x20style=\x22text-align:right;\x22>Records</th>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<th\x20style=\x22text-align:right;\x22>Pages</th>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<th\x20style=\x22text-align:right;\x22>Indexes</th>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<th></th>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</tr>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</thead>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<tbody>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<tr\x20as=\x22repeat\x22\x20:of=\x22types\x22\x20let:item=\x22t\x22\x20class=\x22ov-row\x22\x20@click=\x22select(t)\x22\x20title=\x22Open\x20in\x20type\x20viewer\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-family:monospace;\x20font-size:13px;\x22>{{\x20t.type\x20}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td\x20style=\x22text-align:right;\x20color:var(--accent);\x20font-weight:600;\x22>{{\x20fmt(t.count)\x20}}</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td\x20style=\x22text-align:right;\x20opacity:.5;\x20font-size:12px;\x22>{{\x20fmt(typePages(t.type))\x20}}</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td\x20style=\x22text-align:right;\x20font-size:12px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22typeIndexCount(t.type)\x20>\x200\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20padding:1px\x207px;\x20border-radius:999px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20border:1px\x20solid\x20color-mix(in\x20srgb,\x20var(--okdb-purple)\x2033%,\x20transparent);\x20color:var(--okdb-purple);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-size:11px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22>{{\x20typeIndexCount(t.type)\x20}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22typeIndexCount(t.type)\x20===\x200\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22opacity:.3;\x22>—</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td\x20style=\x22text-align:right;\x20opacity:.3;\x20font-size:11px;\x20padding-right:16px;\x22>→</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</tr>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</tbody>\x0a\x20\x20\x20\x20\x20\x20</table>\x0a\x20\x20\x20\x20</div>\x0a\x20\x20</if>\x0a\x0a\x20\x20<!--\x20Violations\x20summary\x20-->\x0a\x20\x20<if\x20:=\x22totalViolations\x20>\x200\x20||\x20violationsBusy\x20||\x20violationsError\x22>\x0a\x20\x20\x20\x20<div\x20class=\x22ov-card\x22>\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-card-head\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-weight:600;\x20font-size:14px;\x22>Schema\x20Violations</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22totalViolations\x20>\x200\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:11px;\x20padding:2px\x2010px;\x20border-radius:999px;\x20border:1px\x20solid\x20color-mix(in\x20srgb,\x20var(--okdb-danger)\x2033%,\x20transparent);\x20color:var(--okdb-danger);\x20background:color-mix(in\x20srgb,\x20var(--okdb-danger)\x205%,\x20transparent);\x20font-weight:600;\x22>{{\x20totalViolations\x20}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:12px;\x20opacity:.45;\x20margin-left:auto;\x22>across\x20all\x20types\x20in\x20{{\x20envName\x20}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<button\x20@click=\x22loadViolations()\x22\x20:disabled=\x22violationsBusy\x22\x20style=\x22font-size:12px;\x20padding:5px\x2012px;\x20opacity:.75;\x22>↻</button>\x0a\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20<if\x20:=\x22violationsBusy\x20&&\x20violations.length\x20===\x200\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22padding:14px\x2016px;\x20font-size:12px;\x20opacity:.45;\x22>Loading…</div>\x0a\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20<if\x20:=\x22violationsError\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22padding:10px\x2016px;\x20color:var(--okdb-danger);\x20font-size:12px;\x22>{{\x20violationsError\x20}}</div>\x0a\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20<if\x20:=\x22!violationsBusy\x20&&\x20!violationsError\x20&&\x20violationsByType.length\x20===\x200\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22padding:14px\x2016px;\x20font-size:12px;\x20opacity:.4;\x22>No\x20violations.</div>\x0a\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20<if\x20:=\x22violationsByType.length\x20>\x200\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<each\x20:of=\x22violationsByType\x22\x20let:item=\x22grp\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<!--\x20type\x20group\x20header\x20-->\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-viol-group\x22\x20@click=\x22toggleViolationGroup(grp.type)\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22ov-viol-arrow\x22\x20:style=\x22expandedViolationType\x20===\x20grp.type\x20?\x20\x27transform:rotate(90deg)\x27\x20:\x20\x27\x27\x22>›</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-family:monospace;\x20font-size:13px;\x20flex:1;\x22>{{\x20grp.type\x20}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:11px;\x20padding:2px\x208px;\x20border-radius:999px;\x20border:1px\x20solid\x20color-mix(in\x20srgb,\x20var(--okdb-danger)\x2033%,\x20transparent);\x20color:var(--okdb-danger);\x20background:color-mix(in\x20srgb,\x20var(--okdb-danger)\x205%,\x20transparent);\x20margin-right:8px;\x22>{{\x20grp.count\x20}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20@click:stop=\x22navigateToType(grp.type)\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20style=\x22font-size:11px;\x20padding:2px\x208px;\x20border-radius:5px;\x20border:1px\x20solid\x20var(--okdb-app-border);\x20background:transparent;\x20color:var(--okdb-sky);\x20cursor:pointer;\x20opacity:.8;\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20title=\x22Open\x20Schema\x20tab\x20for\x20this\x20type\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20>Schema\x20→</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<!--\x20expanded\x20violations\x20for\x20this\x20type\x20-->\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22expandedViolationType\x20===\x20grp.type\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-viol-list\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<each\x20:of=\x22grp.items\x22\x20let:item=\x22v\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-viol-row\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-family:monospace;\x20font-size:11px;\x20color:var(--okdb-json-key);\x20flex:1;\x20overflow:hidden;\x20text-overflow:ellipsis;\x20white-space:nowrap;\x22>{{\x20v.key\x20}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:11px;\x20opacity:.45;\x20white-space:nowrap;\x20margin-left:8px;\x22>{{\x20(v.errors\x20??\x20[]).length\x20||\x20(v.errorCount\x20??\x200)\x20}}\x20error(s)</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</each>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</each>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20</div>\x0a\x20\x20</if>\x0a\x0a\x20\x20<!--\x20Time\x20Machine\x20card\x20-->\x0a\x20\x20<div\x20class=\x22card\x22>\x0a\x20\x20\x20\x20<div\x20style=\x22display:flex;\x20align-items:center;\x20justify-content:space-between;\x20margin-bottom:8px;\x22>\x0a\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-weight:600;\x20font-size:13px;\x22>⏱\x20Time\x20Machine</span>\x0a\x20\x20\x20\x20\x20\x20<if\x20:=\x22!tmStatus\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:11px;\x20opacity:.4;\x22>loading…</span>\x0a\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20<if\x20:=\x22tmStatus\x20&&\x20!tmBusy\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<button\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20@click=\x22tmStatus.enabled\x20?\x20disableTM()\x20:\x20enableTM()\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20:style=\x22\x27font-size:11px;\x20padding:2px\x2010px;\x20color:\x27\x20+\x20(tmStatus.enabled\x20?\x20\x27var(--okdb-danger)\x27\x20:\x20\x27var(--okdb-success)\x27)\x20+\x20\x27;\x20border-color:\x27\x20+\x20(tmStatus.enabled\x20?\x20\x27color-mix(in\x20srgb,\x20var(--okdb-danger)\x2033%,\x20transparent)\x27\x20:\x20\x27color-mix(in\x20srgb,\x20var(--okdb-success)\x2033%,\x20transparent)\x27)\x20+\x20\x27;\x27\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20>{{\x20tmStatus.enabled\x20?\x20\x27Disable\x27\x20:\x20\x27Enable\x27\x20}}</button>\x0a\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20<if\x20:=\x22tmBusy\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:11px;\x20opacity:.5;\x22>{{\x20tmScanMsg\x20||\x20\x27…\x27\x20}}</span>\x0a\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20<if\x20:=\x22tmStatus\x20&&\x20tmStatus.enabled\x22>\x0a\x20\x20\x20\x20\x20\x20<div\x20style=\x22font-size:12px;\x20opacity:.7;\x20display:flex;\x20flex-direction:column;\x20gap:3px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span>tracking\x20since\x20clock\x20{{\x20tmStatus.startClock\x20}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22tmStatus.lastProcessedClock\x20!==\x20tmStatus.envClock\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span>last\x20processed:\x20{{\x20tmStatus.lastProcessedClock\x20}}\x20·\x20env\x20at:\x20{{\x20tmStatus.envClock\x20}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22tmStatus.lastProcessedClock\x20===\x20tmStatus.envClock\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span>processed\x20through\x20clock\x20{{\x20tmStatus.lastProcessedClock\x20}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span>{{\x20tmStatus.headCount\x20}}\x20heads</span>\x0a\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20<if\x20:=\x22tmStatus\x20&&\x20!tmStatus.enabled\x22>\x0a\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:12px;\x20opacity:.4;\x22>disabled</span>\x0a\x20\x20\x20\x20</if>\x0a\x20\x20</div>\x0a\x0a\x20\x20<div\x20class=\x22ov-card\x22\x20style=\x22overflow:visible;\x22>\x0a\x20\x20\x20\x20<div\x20class=\x22ov-card-head\x22>\x0a\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-weight:600;\x20font-size:14px;\x22>Pipelines</span>\x0a\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:12px;\x20opacity:.45;\x20margin-left:auto;\x22>overview\x20highlights\x20for\x20the\x20current\x20environment</span>\x0a\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20<div\x20style=\x22padding:16px;\x20display:flex;\x20flex-direction:column;\x20gap:14px;\x22>\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-pipelines-headline\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22display:flex;\x20flex-direction:column;\x20gap:6px;\x20min-width:0;\x20flex:1;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22display:flex;\x20align-items:center;\x20gap:8px;\x20flex-wrap:wrap;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22font-size:15px;\x20font-weight:600;\x20color:var(--okdb-app-fg);\x22>{{\x20pipelineSummaryText\x20}}</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22pipelineHealthCounts.error\x20>\x200\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22ov-pipeline-pill\x22\x20:style=\x22\x27color:var(--okdb-danger);border-color:var(--okdb-danger-deep-border);background:#450a0a33;\x27\x22>{{\x20pipelineHealthCounts.error\x20}}\x20error</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22pipelineHealthCounts.degraded\x20>\x200\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22ov-pipeline-pill\x22\x20:style=\x22\x27color:#fcd34d;border-color:#854d0e;background:#451a0333;\x27\x22>{{\x20pipelineHealthCounts.degraded\x20}}\x20degraded</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22pipelineHealthCounts.online\x20>\x200\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20class=\x22ov-pipeline-pill\x22\x20:style=\x22\x27color:#86efac;border-color:#166534;background:#052e1633;\x27\x22>{{\x20pipelineHealthCounts.online\x20}}\x20online</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22font-size:12px;\x20color:var(--okdb-app-fg-muted);\x20line-height:1.6;\x20max-width:640px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20The\x20overview\x20should\x20only\x20surface\x20high-signal\x20pipeline\x20highlights.\x20Open\x20the\x20dedicated\x20workspace\x20when\x20you\x20want\x20the\x20full\x20grouped\x20pipeline\x20list\x20and\x20member\x20details.\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22display:flex;\x20gap:8px;\x20flex-wrap:wrap;\x20align-items:center;\x20justify-content:flex-end;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20@click=\x22loadPipelines()\x22\x20:disabled=\x22pipelinesBusy\x22\x20style=\x22font-size:12px;\x20padding:5px\x2012px;\x20opacity:.75;\x22>↻\x20Refresh</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20@click=\x22openPipelinesWorkspace()\x22\x20style=\x22font-size:12px;\x20padding:5px\x2012px;\x20border-color:color-mix(in\x20srgb,\x20var(--okdb-indigo)\x2033%,\x20transparent);\x20color:var(--okdb-indigo);\x22>Open\x20pipelines\x20workspace\x20→</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</div>\x0a\x0a\x20\x20\x20\x20\x20\x20<if\x20:=\x22pipelinesError\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-pipelines-error\x22>{{\x20pipelinesError\x20}}</div>\x0a\x20\x20\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20\x20\x20<if\x20:=\x22pipelinesBusy\x20&&\x20pipelines.length\x20===\x200\x20&&\x20!pipelinesError\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22font-size:12px;\x20opacity:.45;\x22>Loading\x20pipeline\x20highlights…</div>\x0a\x20\x20\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20\x20\x20<if\x20:=\x22!pipelinesBusy\x20&&\x20pipelines.length\x20===\x200\x20&&\x20!pipelinesError\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-pipelines-empty\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22font-size:24px;\x20opacity:.3;\x22>⛓</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22font-size:14px;\x20font-weight:600;\x20opacity:.78;\x22>No\x20pipelines\x20in\x20{{\x20envName\x20}}</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22font-size:12px;\x20opacity:.5;\x20max-width:520px;\x20line-height:1.7;\x20text-align:center;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20Pipelines\x20will\x20appear\x20here\x20once\x20created\x20or\x20synced.\x20This\x20frontpage\x20intentionally\x20stays\x20compact\x20and\x20only\x20shows\x20a\x20small\x20highlight\x20list.\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20\x20\x20<if\x20:=\x22pipelineHighlights.length\x20>\x200\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-pipelines-list\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<each\x20:of=\x22pipelineHighlights\x22\x20let:item=\x22pipeline\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20class=\x22ov-pipeline-highlight\x22\x20@click=\x22openPipelinesWorkspace(pipeline)\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22display:flex;\x20align-items:center;\x20gap:9px;\x20min-width:0;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20:style=\x22\x27width:8px;height:8px;border-radius:50%;flex-shrink:0;background:\x27\x20+\x20healthColor(pipeline.health)\x22></span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:13px;\x20font-weight:600;\x20overflow:hidden;\x20text-overflow:ellipsis;\x20white-space:nowrap;\x22>{{\x20pipelineLabel(pipeline)\x20}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20:style=\x22\x27font-size:11px;color:\x27\x20+\x20healthColor(pipeline.health)\x20+\x20\x27;opacity:.95;white-space:nowrap;\x27\x22>{{\x20pipeline.health\x20||\x20\x27unknown\x27\x20}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22display:flex;\x20gap:12px;\x20flex-wrap:wrap;\x20margin-top:6px;\x20font-size:11px;\x20color:var(--okdb-app-fg-muted);\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span><span\x20style=\x22opacity:.6;\x22>Members:</span>\x20<span\x20style=\x22color:var(--okdb-app-fg);\x22>{{\x20fmt(pipeline.engines?.length\x20||\x200)\x20}}</span></span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<if\x20:=\x22pipeline.status\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span><span\x20style=\x22opacity:.6;\x22>Status:</span>\x20<span\x20:style=\x22\x27color:\x27\x20+\x20statusColor(pipeline.status)\x22>{{\x20pipeline.status\x20}}</span></span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22overflow:hidden;\x20text-overflow:ellipsis;\x20white-space:nowrap;\x22>{{\x20pipelineRoleSummary(pipeline)\x20}}</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</each>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</if>\x0a\x0a\x20\x20\x20\x20\x20\x20<if\x20:=\x22pipelines.length\x20>\x20pipelineHighlights.length\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22font-size:11px;\x20color:var(--okdb-app-fg-muted);\x20opacity:.75;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20Showing\x20{{\x20pipelineHighlights.length\x20}}\x20of\x20{{\x20pipelines.length\x20}}\x20pipelines.\x20Open\x20the\x20dedicated\x20workspace\x20for\x20the\x20full\x20inventory.\x0a\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20</if>\x0a\x20\x20\x20\x20</div>\x0a\x20\x20</div>\x0a\x0a\x20\x20<!--\x20Recent\x20activity\x20-->\x0a\x20\x20<if\x20:=\x22recentChanges.length\x20>\x200\x22>\x0a\x20\x20\x20\x20<div\x20class=\x22ov-card\x22>\x0a\x20\x20\x20\x20\x20\x20<div\x20class=\x22ov-card-head\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-weight:600;\x20font-size:14px;\x22>Recent\x20Activity</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<span\x20style=\x22font-size:12px;\x20opacity:.4;\x20margin-left:auto;\x22>last\x20{{\x20recentChanges.length\x20}}\x20changes</span>\x0a\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20<table\x20style=\x22width:100%;\x20border-collapse:collapse;\x20font-size:12px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20<tbody>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<tr\x20as=\x22repeat\x22\x20:of=\x22recentChanges\x22\x20let:item=\x22ch\x22\x20class=\x22ov-row\x20ov-row--sm\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td\x20class=\x22ov-ch-td\x22\x20style=\x22text-align:right;\x20width:60px;\x20font-family:monospace;\x20opacity:.4;\x20padding-left:16px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{{\x20ch.clock\x20}}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td\x20class=\x22ov-ch-td\x22\x20style=\x22width:100px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<span\x20:style=\x22\x27font-size:10px;\x20padding:2px\x206px;\x20border-radius:3px;\x20border:1px\x20solid;\x20color:\x27+actionColor(ch.action)+\x27;\x20border-color:\x27+actionColor(ch.action)+\x2755;\x27\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{{\x20actionLabel(ch.action)\x20}}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</span>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td\x20class=\x22ov-ch-td\x22\x20style=\x22font-family:monospace;\x20font-size:11px;\x20opacity:.7;\x20max-width:110px;\x20overflow:hidden;\x20text-overflow:ellipsis;\x20white-space:nowrap;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{{\x20ch.type\x20||\x20\x27—\x27\x20}}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td\x20class=\x22ov-ch-td\x22\x20style=\x22font-family:monospace;\x20font-size:11px;\x20opacity:.45;\x20max-width:160px;\x20overflow:hidden;\x20text-overflow:ellipsis;\x20white-space:nowrap;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{{\x20ch.key\x20||\x20\x27\x27\x20}}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<td\x20class=\x22ov-ch-td\x22\x20style=\x22text-align:right;\x20opacity:.35;\x20white-space:nowrap;\x20font-size:11px;\x20padding-right:16px;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{{\x20relTime(ch.timestamp)\x20}}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</td>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</tr>\x0a\x20\x20\x20\x20\x20\x20\x20\x20</tbody>\x0a\x20\x20\x20\x20\x20\x20</table>\x0a\x20\x20\x20\x20</div>\x0a\x20\x20</if>\x0a\x0a</div>\x0a','get','tmBusy','tmStatus','index:drop','type:registered','9733384buejsm','DELETE','loadViolations','shared','message','building','\x20·\x20','index:registered','_scheduleReload','engine:uninstalled','add','440MbCMxG','pipelinesBusy','item:remove','pipeline:stop','No\x20members','role','s\x20ago','309189OYePOm','violationsBusy','isArray','envName','system:clock_change','Failed\x20to\x20load\x20violations','health','$watch','length','$dispatch','okdb','stores','recentBusy','env','meta','var(--okdb-danger)','891296LWCvPN','stopped','violationsError','all','sync:apply','var(--okdb-success)','POST','scanning…','_reloadTimer','API','apiBase','22CvpWdN','json','map','resolve','reloadEnvs','success','system:poke','engine:error','\x20pipeline','3482730sStoOQ','info','selectedEnv','pipelineLabel','error','var(--okdb-warning)','pipelineSeverity','pipeline:start','toast','item:create','/engines','push','localeCompare','filter','/changelog?limit=10','catch','type','toLocaleString','toFixed','round','/violations','idle','name','status','expandedViolationType','set','startsWith','result','pageSize','pages','$ok','lastProcessedClock','loadPipelines','label','Failed\x20to\x20load\x20pipelines','pipelines','loadTMStatus','just\x20now','reduce','degraded','slice','violations','now','default','sort','Unnamed\x20pipeline','$vars','key','reloadInfo','entries','\x20engine','includes','var(--okdb-app-fg-muted)','running','has','$router'];_0x513b=function(){return _0x48c45b;};return _0x513b();}import _0x549d2d from'../../../stores/events-store.js';import _0x2eefd5 from'../modals/demo-env-modal.ok.js';export default{'tag':_0x13dc4f(0x146),'dependencies':[_0x2eefd5],'attr':{'stats':{}},'context':_0x926488=>({'recentChanges':[],'recentBusy':!0x1,'recentError':null,'pipelines':[],'pipelinesBusy':!0x1,'pipelinesError':null,'violations':[],'violationsBusy':!0x1,'violationsError':null,'expandedViolationType':null,'tmStatus':null,'tmBusy':!0x1,'tmScanMsg':'',get 'info'(){const _0x40bb28=_0x13dc4f;return _0x926488[_0x40bb28(0x128)][_0x40bb28(0x187)][_0x40bb28(0x186)][_0x40bb28(0x10b)];},get 'types'(){const _0x4b56a8=_0x13dc4f;return(_0x926488[_0x4b56a8(0x128)][_0x4b56a8(0x187)][_0x4b56a8(0x186)][_0x4b56a8(0x14e)]||[])[_0x4b56a8(0x117)](_0x976b87=>!_0x976b87['type'][_0x4b56a8(0x124)]('~'))[_0x4b56a8(0x136)]((_0x26bb97,_0x3dceb2)=>_0x26bb97[_0x4b56a8(0x11a)][_0x4b56a8(0x116)](_0x3dceb2[_0x4b56a8(0x11a)]));},get 'systemTypes'(){const _0x39200e=_0x13dc4f;return(_0x926488[_0x39200e(0x128)][_0x39200e(0x187)][_0x39200e(0x186)][_0x39200e(0x14e)]||[])['filter'](_0x937170=>_0x937170[_0x39200e(0x11a)]['startsWith']('~'));},get 'envName'(){const _0x3c8c4b=_0x13dc4f;return _0x926488[_0x3c8c4b(0x128)][_0x3c8c4b(0x187)][_0x3c8c4b(0x186)][_0x3c8c4b(0x10c)]||_0x3c8c4b(0x135);},get 'totalRecords'(){const _0x12e899=_0x13dc4f;return(_0x926488[_0x12e899(0x128)][_0x12e899(0x187)][_0x12e899(0x186)]['types']||[])[_0x12e899(0x117)](_0x1cea3f=>!_0x1cea3f[_0x12e899(0x11a)]['startsWith']('~'))[_0x12e899(0x130)]((_0x1122aa,_0x386777)=>_0x1122aa+(_0x386777[_0x12e899(0x151)]||0x0),0x0);},get 'approxSize'(){const _0x3d2dde=_0x13dc4f,_0x13c82d=this[_0x3d2dde(0x10b)]?.['lastPageNumber'],_0x307351=this[_0x3d2dde(0x10b)]?.[_0x3d2dde(0x126)];if(!_0x13c82d||!_0x307351)return'--';let _0x4f6475=_0x13c82d*_0x307351;const _0x48f46d=['B','KB','MB','GB','TB'];let _0x46233f=0x0;for(;_0x4f6475>=0x400&&_0x46233f<_0x48f46d[_0x3d2dde(0x184)]-0x1;)_0x4f6475/=0x400,_0x46233f++;return _0x4f6475[_0x3d2dde(0x11c)](0x2)+'\x20'+_0x48f46d[_0x46233f];},'typeIndexCount'(_0x156bca){const _0x35b067=_0x13dc4f,_0xc269d9=this[_0x35b067(0x10b)]?.[_0x35b067(0x14e)]?.[_0x156bca]?.[_0x35b067(0x161)];return _0xc269d9?Object[_0x35b067(0x142)](_0xc269d9)[_0x35b067(0x184)]:0x0;},'typePages'(_0x1b20ef){const _0x30c293=_0x13dc4f;return this[_0x30c293(0x10b)]?.['types']?.[_0x1b20ef]?.[_0x30c293(0x15e)]?.[_0x30c293(0x127)]??null;},'select'(_0x2849fd){const _0x3ef11e=_0x13dc4f;_0x926488[_0x3ef11e(0x185)]('select',_0x2849fd);},async 'loadRecent'(){const _0x19738d=_0x13dc4f;this[_0x19738d(0x188)]=!0x0,this[_0x19738d(0x149)]=null;try{const _0x392dd7=await fetch(_0x926488[_0x19738d(0x128)][_0x19738d(0x187)]['okdb'][_0x19738d(0x100)]+_0x19738d(0x118));if(_0x392dd7['ok']){const _0x49f689=await _0x392dd7['json']();this['recentChanges']=_0x49f689[_0x19738d(0x15e)]??[];}}catch(_0x30667c){this['recentError']=_0x30667c?.[_0x19738d(0x16e)]||_0x19738d(0x150);}finally{this['recentBusy']=!0x1;}},'actionColor':_0x37e83f=>({'put':_0x13dc4f(0xfb),'remove':'var(--okdb-danger)','type_register':_0x13dc4f(0x152),'type_drop':_0x13dc4f(0x18b),'index_register':'var(--okdb-purple)','index_drop':'var(--okdb-warning)'}[_0x37e83f]||_0x13dc4f(0x13e)),'actionLabel':_0x575814=>(_0x575814||'')[_0x13dc4f(0x157)](/_/g,'\x20'),'relTime'(_0xcdea4){const _0xb8a06c=_0x13dc4f;if(!_0xcdea4)return'—';const _0x3464c4=Date[_0xb8a06c(0x134)]()-_0xcdea4;return _0x3464c4<0x1388?_0xb8a06c(0x12f):_0x3464c4<0xea60?Math['round'](_0x3464c4/0x3e8)+_0xb8a06c(0x17b):_0x3464c4<0x36ee80?Math[_0xb8a06c(0x11d)](_0x3464c4/0xea60)+'m\x20ago':_0x3464c4<0x5265c00?Math['round'](_0x3464c4/0x36ee80)+_0xb8a06c(0x14f):new Date(_0xcdea4)['toLocaleDateString']();},'fmt':_0x2a20c5=>null==_0x2a20c5?'--':Number(_0x2a20c5)[_0x13dc4f(0x11b)](),'healthColor':_0x3846ca=>_0x13dc4f(0x163)===_0x3846ca?_0x13dc4f(0xfb):'degraded'===_0x3846ca?_0x13dc4f(0x10f):_0x13dc4f(0x10e)===_0x3846ca?_0x13dc4f(0x18b):_0x13dc4f(0x18d)===_0x3846ca?_0x13dc4f(0x13e):_0x13dc4f(0x144),'statusColor':_0x58a4b2=>'running'===_0x58a4b2||_0x13dc4f(0x163)===_0x58a4b2?'var(--okdb-success)':_0x13dc4f(0x16f)===_0x58a4b2||_0x13dc4f(0x131)===_0x58a4b2?'var(--okdb-warning)':_0x13dc4f(0x10e)===_0x58a4b2?_0x13dc4f(0x18b):_0x13dc4f(0x18d)===_0x58a4b2||'idle'===_0x58a4b2?_0x13dc4f(0x13e):_0x13dc4f(0x144),'pipelineKey'(_0x5acd60){const _0x3f4dd4=_0x13dc4f;return(_0x5acd60?.['env']||this[_0x3f4dd4(0x17f)])+'::'+(_0x5acd60?.['name']||'');},'pipelineLabel':_0x38cf55=>_0x38cf55?.[_0x13dc4f(0x18a)]?.[_0x13dc4f(0x12b)]||_0x38cf55?.[_0x13dc4f(0x120)]||_0x13dc4f(0x137),'pipelineRoleSummary'(_0x4591a2){const _0x42d06f=_0x13dc4f,_0x2a6cac=Array[_0x42d06f(0x17e)](_0x4591a2?.[_0x42d06f(0x159)])?_0x4591a2[_0x42d06f(0x159)]:[];if(0x0===_0x2a6cac['length'])return _0x42d06f(0x179);const _0x74d43e=[];for(const _0x5c4f95 of _0x2a6cac){const _0x4b74b9=_0x5c4f95?.[_0x42d06f(0x17a)]||_0x5c4f95?.[_0x42d06f(0x11a)];if(_0x4b74b9&&!_0x74d43e[_0x42d06f(0x13d)](_0x4b74b9)&&(_0x74d43e[_0x42d06f(0x115)](_0x4b74b9),_0x74d43e[_0x42d06f(0x184)]>=0x3))break;}return _0x74d43e[_0x42d06f(0x145)](_0x42d06f(0x170));},'pipelineSeverity'(_0x441e54){const _0x40cfed=_0x13dc4f,_0x4ae47c=String(_0x441e54?.[_0x40cfed(0x182)]||'')[_0x40cfed(0x14d)](),_0x1981c6=String(_0x441e54?.[_0x40cfed(0x121)]||'')[_0x40cfed(0x14d)]();return _0x40cfed(0x10e)===_0x4ae47c||_0x40cfed(0x10e)===_0x1981c6?0x0:_0x40cfed(0x131)===_0x4ae47c||'degraded'===_0x1981c6||_0x40cfed(0x16f)===_0x1981c6?0x1:_0x40cfed(0x18d)===_0x4ae47c||_0x40cfed(0x18d)===_0x1981c6||_0x40cfed(0x11f)===_0x1981c6?0x2:_0x40cfed(0x163)===_0x4ae47c||_0x40cfed(0x13f)===_0x1981c6||_0x40cfed(0x163)===_0x1981c6?0x3:0x4;},get 'pipelineEngineCount'(){const _0x529155=_0x13dc4f,_0x218e55=new Set();for(const _0x4d23a5 of this[_0x529155(0x12d)])for(const _0x1a232b of _0x4d23a5?.[_0x529155(0x159)]||[]){const _0x430b04=_0x1a232b?.[_0x529155(0x139)]||(_0x1a232b?.[_0x529155(0x11a)]&&_0x1a232b?.[_0x529155(0x120)]?_0x1a232b[_0x529155(0x11a)]+'@'+_0x1a232b[_0x529155(0x120)]:_0x1a232b?.[_0x529155(0x120)])||null;_0x430b04&&_0x218e55[_0x529155(0x174)]((_0x4d23a5?.[_0x529155(0x189)]||this[_0x529155(0x17f)])+'::'+_0x430b04);}return _0x218e55['size'];},get 'pipelineHealthCounts'(){const _0x3f2808=_0x13dc4f,_0x129c47={'online':0x0,'degraded':0x0,'error':0x0,'stopped':0x0};for(const _0x1de4a of this['pipelines']){const _0x4f27c0=String(_0x1de4a?.[_0x3f2808(0x182)]||'')[_0x3f2808(0x14d)]();null!=_0x129c47[_0x4f27c0]&&(_0x129c47[_0x4f27c0]+=0x1);}return _0x129c47;},get 'pipelineSummaryText'(){const _0x2ffc1d=_0x13dc4f,_0x50d0c7=this[_0x2ffc1d(0x12d)][_0x2ffc1d(0x184)],_0xfb879d=this['pipelineEngineCount'];return _0x50d0c7+_0x2ffc1d(0x109)+(0x1===_0x50d0c7?'':'s')+'\x20·\x20'+_0xfb879d+_0x2ffc1d(0x13c)+(0x1===_0xfb879d?'':'s');},get 'pipelineHighlights'(){const _0x4a4824=_0x13dc4f;return[...this[_0x4a4824(0x12d)]]['sort']((_0x583a92,_0x225b25)=>{const _0x35562b=_0x4a4824,_0x9eb74b=this[_0x35562b(0x110)](_0x583a92)-this[_0x35562b(0x110)](_0x225b25);return 0x0!==_0x9eb74b?_0x9eb74b:this[_0x35562b(0x10d)](_0x583a92)[_0x35562b(0x116)](this[_0x35562b(0x10d)](_0x225b25));})[_0x4a4824(0x132)](0x0,0x4);},async 'loadPipelines'(){const _0x9f864=_0x13dc4f;this[_0x9f864(0x176)]=!0x0,this[_0x9f864(0x154)]=null;try{const _0x19ffad=await fetch(_0x926488['$ok'][_0x9f864(0x187)][_0x9f864(0x186)][_0x9f864(0x100)]+_0x9f864(0x155)),_0x2d3918=await _0x19ffad[_0x9f864(0x102)]()[_0x9f864(0x119)](()=>({}));if(!_0x19ffad['ok'])throw new Error(_0x2d3918?.['error']?.[_0x9f864(0x16e)]||_0x9f864(0x12c));this[_0x9f864(0x12d)]=_0x2d3918?.[_0x9f864(0x15e)]??_0x2d3918?.[_0x9f864(0x125)]??[];}catch(_0x5ccff7){this[_0x9f864(0x154)]=_0x5ccff7?.['message']||_0x9f864(0x12c),this['pipelines']=[];}finally{this[_0x9f864(0x176)]=!0x1;}},'openPipelinesWorkspace'(_0x84862e=null){const _0x5ee77f=_0x13dc4f,_0xca4400=_0x926488[_0x5ee77f(0x138)]?.[_0x5ee77f(0x141)];if(!_0xca4400?.[_0x5ee77f(0x104)]||!_0xca4400?.[_0x5ee77f(0x115)])return;const _0x482e47={'env':this['envName'],'mode':_0x5ee77f(0x12d)};_0x84862e?.[_0x5ee77f(0x120)]&&(_0x482e47['pipeline']=_0x84862e[_0x5ee77f(0x120)]),_0xca4400['push'](_0xca4400['resolve'](_0x5ee77f(0x114),_0x482e47));},async 'openDemoModal'(){const _0x3cd187=_0x13dc4f;await _0x926488['$ok'][_0x3cd187(0x16d)]['modal'][_0x3cd187(0x162)]({'owner':_0x926488,'title':'<span\x20style=\x22background:linear-gradient(135deg,var(--okdb-accent),var(--okdb-purple)\x2050%,var(--okdb-success));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;font-weight:700;font-size:15px;\x22>✦\x20Demo\x20Environment</span>','canDrag':!0x0,'content':'<demo-env-modal\x20:modal=\x22modal\x22\x20:on-done=\x22onDone\x22\x20/>','context':_0x3ca8f5=>({'modal':_0x3ca8f5,'onDone':async _0x55cbee=>{const _0x5614a0=_0x3cd187;_0x926488[_0x5614a0(0x128)][_0x5614a0(0x187)][_0x5614a0(0x186)]['selectEnv'](_0x55cbee),await _0x926488[_0x5614a0(0x128)][_0x5614a0(0x187)][_0x5614a0(0x186)][_0x5614a0(0x105)](),_0x926488[_0x5614a0(0x128)][_0x5614a0(0x16d)]?.[_0x5614a0(0x112)]?.[_0x5614a0(0x106)]?.('✦\x20Demo\x20environment\x20\x22'+_0x55cbee+'\x22\x20is\x20ready!');}})});},'_unsubs':[],'_reloadTimer':null,'_scheduleReload'(){const _0x1b08ec=_0x13dc4f;clearTimeout(this[_0x1b08ec(0xfe)]),this['_reloadTimer']=setTimeout(()=>this[_0x1b08ec(0x143)](),0x258);},async '_reloadTypes'(){const _0xa6add0=_0x13dc4f;await Promise[_0xa6add0(0xf9)]([_0x926488[_0xa6add0(0x128)][_0xa6add0(0x187)]['okdb'][_0xa6add0(0x160)](),_0x926488[_0xa6add0(0x128)][_0xa6add0(0x187)][_0xa6add0(0x186)][_0xa6add0(0x13a)]()]);},async 'loadViolations'(){const _0x5e75ee=_0x13dc4f;this[_0x5e75ee(0x17d)]=!0x0,this['violationsError']=null;try{const _0x5651ac=await fetch(_0x926488[_0x5e75ee(0x128)]['stores'][_0x5e75ee(0x186)][_0x5e75ee(0x100)]+_0x5e75ee(0x11e));if(0x194===_0x5651ac[_0x5e75ee(0x121)])return void(this[_0x5e75ee(0x133)]=[]);if(!_0x5651ac['ok']){const _0x561335=await _0x5651ac['json']()[_0x5e75ee(0x119)](()=>({}));throw new Error(_0x561335?.[_0x5e75ee(0x10e)]?.[_0x5e75ee(0x16e)]||_0x5e75ee(0x181));}const _0x1ce8db=await _0x5651ac[_0x5e75ee(0x102)]();this[_0x5e75ee(0x133)]=_0x1ce8db?.['data']?.[_0x5e75ee(0x133)]??_0x1ce8db?.[_0x5e75ee(0x125)]?.[_0x5e75ee(0x133)]??[];}catch(_0x309e5a){this[_0x5e75ee(0x18e)]=_0x309e5a?.['message']||'Failed\x20to\x20load\x20violations',this[_0x5e75ee(0x133)]=[];}finally{this[_0x5e75ee(0x17d)]=!0x1;}},get 'violationsByType'(){const _0x542111=_0x13dc4f,_0x238c3f=new Map();for(const _0x3b0fdc of this[_0x542111(0x133)]){const _0x50b8d3=_0x3b0fdc[_0x542111(0x11a)]||'?';_0x238c3f[_0x542111(0x140)](_0x50b8d3)||_0x238c3f[_0x542111(0x123)](_0x50b8d3,[]),_0x238c3f[_0x542111(0x165)](_0x50b8d3)[_0x542111(0x115)](_0x3b0fdc);}return[..._0x238c3f[_0x542111(0x13b)]()][_0x542111(0x103)](([_0x53137a,_0x239ec1])=>({'type':_0x53137a,'count':_0x239ec1[_0x542111(0x184)],'items':_0x239ec1}))[_0x542111(0x136)]((_0x489afb,_0x32ea90)=>_0x32ea90[_0x542111(0x151)]-_0x489afb[_0x542111(0x151)]);},get 'totalViolations'(){const _0x5d4a0a=_0x13dc4f;return this[_0x5d4a0a(0x133)][_0x5d4a0a(0x184)];},'toggleViolationGroup'(_0x8b6151){const _0x415ee8=_0x13dc4f;this['expandedViolationType']=this[_0x415ee8(0x122)]===_0x8b6151?null:_0x8b6151;},'navigateToType'(_0x46e0d7){const _0x3b9d95=_0x13dc4f;_0x926488[_0x3b9d95(0x185)]('select',{'type':_0x46e0d7});},async 'reloadOverviewData'(){const _0x4dc829=_0x13dc4f;await Promise['all']([this['loadRecent'](),this[_0x4dc829(0x12a)](),this[_0x4dc829(0x16c)]()]);},async 'loadTMStatus'(){const _0x4bf6e9=_0x13dc4f;try{const _0x5e902f=_0x926488[_0x4bf6e9(0x128)][_0x4bf6e9(0x187)][_0x4bf6e9(0x186)]['selectedEnv']||'default',_0xf41309=await fetch(__ENV__[_0x4bf6e9(0xff)]+'/env/'+encodeURIComponent(_0x5e902f)+_0x4bf6e9(0x15d));if(!_0xf41309['ok'])return void(this[_0x4bf6e9(0x167)]={'enabled':!0x1});const _0x5ac8aa=await _0xf41309['json']();this[_0x4bf6e9(0x167)]=_0x5ac8aa[_0x4bf6e9(0x125)]??_0x5ac8aa[_0x4bf6e9(0x15e)]??{'enabled':!0x1};}catch{this['tmStatus']={'enabled':!0x1};}},async 'enableTM'(){const _0x56590d=_0x13dc4f;if(!this[_0x56590d(0x166)]){this['tmBusy']=!0x0,this[_0x56590d(0x15b)]=_0x56590d(0xfd);try{const _0x40a34e=_0x926488[_0x56590d(0x128)][_0x56590d(0x187)][_0x56590d(0x186)][_0x56590d(0x10c)]||_0x56590d(0x135);await fetch(__ENV__[_0x56590d(0xff)]+_0x56590d(0x14b)+encodeURIComponent(_0x40a34e)+_0x56590d(0x14c),{'method':_0x56590d(0xfc)});const _0x156c90=Date[_0x56590d(0x134)]()+0x2710;for(;Date[_0x56590d(0x134)]()<_0x156c90&&(await new Promise(_0x4b6c57=>setTimeout(_0x4b6c57,0x3e8)),await this[_0x56590d(0x12e)](),!(this['tmStatus']?.[_0x56590d(0x129)]>0x0)););}catch{}this[_0x56590d(0x166)]=!0x1,this[_0x56590d(0x15b)]='';}},async 'disableTM'(){const _0x2b5a29=_0x13dc4f;if(!this[_0x2b5a29(0x166)]){this['tmBusy']=!0x0;try{const _0x1a2fb0=_0x926488[_0x2b5a29(0x128)][_0x2b5a29(0x187)][_0x2b5a29(0x186)]['selectedEnv']||_0x2b5a29(0x135);await fetch(__ENV__[_0x2b5a29(0xff)]+'/env/'+encodeURIComponent(_0x1a2fb0)+_0x2b5a29(0x14c),{'method':_0x2b5a29(0x16b)}),await this['loadTMStatus']();}catch{}this[_0x2b5a29(0x166)]=!0x1;}}}),'init'(_0x190c0d){const _0x243098=_0x13dc4f;this[_0x243098(0x12e)](),_0x190c0d[_0x243098(0x183)](()=>_0x190c0d[_0x243098(0x128)][_0x243098(0x187)][_0x243098(0x186)][_0x243098(0x10c)],()=>{const _0x48ab1e=_0x243098;this[_0x48ab1e(0x15a)](),this[_0x48ab1e(0x12e)]();});},'mount'(){const _0x246282=_0x13dc4f;this[_0x246282(0x15a)]();const _0x51e189=()=>this[_0x246282(0x12a)]();this[_0x246282(0x148)]=[_0x549d2d['on'](_0x246282(0x169),()=>this[_0x246282(0x15c)]()),_0x549d2d['on']('type:drop',()=>this[_0x246282(0x15c)]()),_0x549d2d['on'](_0x246282(0x171),()=>this[_0x246282(0x15c)]()),_0x549d2d['on'](_0x246282(0x168),()=>this['_reloadTypes']()),_0x549d2d['on'](_0x246282(0x153),_0x51e189),_0x549d2d['on']('engine:stopped',_0x51e189),_0x549d2d['on'](_0x246282(0x108),_0x51e189),_0x549d2d['on']('engine:installed',_0x51e189),_0x549d2d['on'](_0x246282(0x173),_0x51e189),_0x549d2d['on'](_0x246282(0x111),_0x51e189),_0x549d2d['on'](_0x246282(0x178),_0x51e189),_0x549d2d['on'](_0x246282(0x147),_0x51e189),_0x549d2d['on'](_0x246282(0x113),()=>this['_scheduleReload']()),_0x549d2d['on']('item:update',()=>this[_0x246282(0x172)]()),_0x549d2d['on'](_0x246282(0x177),()=>this[_0x246282(0x172)]()),_0x549d2d['on'](_0x246282(0xfa),()=>this['_scheduleReload']()),_0x549d2d['on'](_0x246282(0x180),()=>this[_0x246282(0x172)]()),_0x549d2d['on'](_0x246282(0x107),()=>this['_scheduleReload']())];},'unmount'(){const _0x5408c9=_0x13dc4f;clearTimeout(this[_0x5408c9(0xfe)]);for(const _0x2c0a97 of this['_unsubs'])_0x2c0a97();this[_0x5408c9(0x148)]=[];},'template':_0x13dc4f(0x164),'style':'\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-stat-row\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20grid;\x0a\x20\x20\x20\x20\x20\x20\x20\x20grid-template-columns:\x20repeat(4,\x201fr);\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x2012px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-stat-card\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20var(--okdb-app-surface);\x0a\x20\x20\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20var(--okdb-app-border);\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-radius:\x2012px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2016px\x2018px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20flex-direction:\x20column;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x206px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20box-shadow:\x200\x202px\x208px\x20#0003;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-stat-label\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2011px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20text-transform:\x20uppercase;\x0a\x20\x20\x20\x20\x20\x20\x20\x20letter-spacing:\x20.06em;\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.5;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-stat-value\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2022px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-weight:\x20700;\x0a\x20\x20\x20\x20\x20\x20\x20\x20line-height:\x201;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-card\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20var(--okdb-app-surface);\x0a\x20\x20\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20var(--okdb-app-border);\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-radius:\x2012px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20overflow:\x20hidden;\x0a\x20\x20\x20\x20\x20\x20\x20\x20box-shadow:\x200\x202px\x208px\x20#0003;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-card-head\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2013px\x2016px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-bottom:\x201px\x20solid\x20var(--okdb-app-border);\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x2010px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-table\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20width:\x20100%;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-collapse:\x20collapse;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2013px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-table\x20th\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x207px\x2016px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20text-align:\x20left;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-weight:\x20500;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2010px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20text-transform:\x20uppercase;\x0a\x20\x20\x20\x20\x20\x20\x20\x20letter-spacing:\x20.05em;\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.4;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-bottom:\x201px\x20solid\x20var(--okdb-app-border);\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20var(--okdb-app-bg);\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-table\x20td\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x209px\x2016px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-bottom:\x201px\x20solid\x20var(--okdb-app-surface-2);\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-row\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20cursor:\x20pointer;\x0a\x20\x20\x20\x20\x20\x20\x20\x20transition:\x20background\x20.1s;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-row:hover\x20td\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20#ffffff07;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-table\x20tbody\x20tr:last-child\x20td\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-bottom:\x20none;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-ch-td\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x206px\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-bottom:\x201px\x20solid\x20var(--okdb-app-surface);\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-pipelines-headline\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20justify-content:\x20space-between;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x2012px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20flex-start;\x0a\x20\x20\x20\x20\x20\x20\x20\x20flex-wrap:\x20wrap;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-pipeline-pill\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2010px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x202px\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-radius:\x20999px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border:\x201px\x20solid;\x0a\x20\x20\x20\x20\x20\x20\x20\x20white-space:\x20nowrap;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-pipelines-error\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20color:\x20var(--okdb-danger);\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2012px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2010px\x2012px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-radius:\x2010px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20color-mix(in\x20srgb,\x20var(--okdb-danger)\x2033%,\x20transparent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20color-mix(in\x20srgb,\x20var(--okdb-danger)\x205%,\x20transparent);\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-pipelines-empty\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20border:\x201px\x20dashed\x20var(--okdb-app-border);\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-radius:\x2012px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2024px\x2020px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20flex-direction:\x20column;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x2010px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-pipelines-list\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20grid;\x0a\x20\x20\x20\x20\x20\x20\x20\x20grid-template-columns:\x20repeat(auto-fit,\x20minmax(240px,\x201fr));\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x2010px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-pipeline-highlight\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20width:\x20100%;\x0a\x20\x20\x20\x20\x20\x20\x20\x20text-align:\x20left;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-radius:\x2010px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20var(--okdb-app-border);\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20var(--okdb-app-bg-deep);\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2011px\x2012px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20cursor:\x20pointer;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-pipeline-highlight:hover\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-color:\x20var(--okdb-app-border-strong);\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20var(--okdb-app-bg-deep);\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20tbody\x20.ov-row--sm:last-child\x20.ov-ch-td\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-bottom:\x20none;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-viol-group\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x209px\x2016px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-bottom:\x201px\x20solid\x20var(--okdb-app-surface-2);\x0a\x20\x20\x20\x20\x20\x20\x20\x20cursor:\x20pointer;\x0a\x20\x20\x20\x20\x20\x20\x20\x20transition:\x20background\x20.1s;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-viol-group:hover\x20{\x20background:\x20#ffffff07;\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-viol-arrow\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20inline-block;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2014px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.5;\x0a\x20\x20\x20\x20\x20\x20\x20\x20transition:\x20transform\x20.15s;\x0a\x20\x20\x20\x20\x20\x20\x20\x20width:\x2014px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20flex-shrink:\x200;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-viol-list\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20var(--okdb-app-bg-deep);\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-bottom:\x201px\x20solid\x20var(--okdb-app-surface-2);\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-viol-row\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x206px\x2016px\x206px\x2038px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-bottom:\x201px\x20solid\x20var(--okdb-app-surface);\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2012px;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-viol-row:last-child\x20{\x20border-bottom:\x20none;\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-empty\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20border:\x201px\x20dashed\x20var(--okdb-app-border);\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-radius:\x2014px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2030px\x2032px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20text-align:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.7;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20/*\x20──\x20Demo\x20data\x20card\x20──\x20*/\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-demo-card\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20position:\x20relative;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border:\x201px\x20solid\x20var(--okdb-app-border);\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-radius:\x2016px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2028px\x2024px\x2024px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20text-align:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20cursor:\x20pointer;\x0a\x20\x20\x20\x20\x20\x20\x20\x20overflow:\x20hidden;\x0a\x20\x20\x20\x20\x20\x20\x20\x20transition:\x20border-color\x20.25s,\x20box-shadow\x20.25s,\x20transform\x20.2s;\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20var(--okdb-app-bg-deep);\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-demo-card:hover\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-color:\x20color-mix(in\x20srgb,\x20var(--okdb-accent)\x2053%,\x20transparent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20box-shadow:\x200\x200\x200\x201px\x20color-mix(in\x20srgb,\x20var(--okdb-accent)\x2013%,\x20transparent),\x200\x208px\x2040px\x20color-mix(in\x20srgb,\x20var(--okdb-accent)\x209%,\x20transparent),\x200\x200\x2080px\x20color-mix(in\x20srgb,\x20var(--okdb-purple)\x204%,\x20transparent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20transform:\x20translateY(-2px);\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-demo-card__aurora\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20position:\x20absolute;\x0a\x20\x20\x20\x20\x20\x20\x20\x20inset:\x200;\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20radial-gradient(ellipse\x20at\x2020%\x2050%,\x20color-mix(in\x20srgb,\x20var(--okdb-accent)\x204%,\x20transparent),\x20transparent\x2055%),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20radial-gradient(ellipse\x20at\x2080%\x2030%,\x20color-mix(in\x20srgb,\x20var(--okdb-purple)\x204%,\x20transparent),\x20transparent\x2055%),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20radial-gradient(ellipse\x20at\x2050%\x2090%,\x20color-mix(in\x20srgb,\x20var(--okdb-success)\x204%,\x20transparent),\x20transparent\x2055%);\x0a\x20\x20\x20\x20\x20\x20\x20\x20pointer-events:\x20none;\x0a\x20\x20\x20\x20\x20\x20\x20\x20animation:\x20ov-aurora\x208s\x20ease-in-out\x20infinite\x20alternate;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-demo-card__sparkle\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2026px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20linear-gradient(135deg,\x20var(--okdb-accent),\x20var(--okdb-purple)\x2040%,\x20var(--okdb-success));\x0a\x20\x20\x20\x20\x20\x20\x20\x20-webkit-background-clip:\x20text;\x0a\x20\x20\x20\x20\x20\x20\x20\x20-webkit-text-fill-color:\x20transparent;\x0a\x20\x20\x20\x20\x20\x20\x20\x20background-clip:\x20text;\x0a\x20\x20\x20\x20\x20\x20\x20\x20animation:\x20ov-hue\x206s\x20linear\x20infinite;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-demo-card__title\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2017px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-weight:\x20700;\x0a\x20\x20\x20\x20\x20\x20\x20\x20background:\x20linear-gradient(135deg,\x20var(--okdb-app-fg-strong),\x20var(--okdb-accent));\x0a\x20\x20\x20\x20\x20\x20\x20\x20-webkit-background-clip:\x20text;\x0a\x20\x20\x20\x20\x20\x20\x20\x20-webkit-text-fill-color:\x20transparent;\x0a\x20\x20\x20\x20\x20\x20\x20\x20background-clip:\x20text;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-demo-card__desc\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2013px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.55;\x0a\x20\x20\x20\x20\x20\x20\x20\x20max-width:\x20380px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20line-height:\x201.65;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-demo-card__badges\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20gap:\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20flex-wrap:\x20wrap;\x0a\x20\x20\x20\x20\x20\x20\x20\x20justify-content:\x20center;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-demo-badge\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20padding:\x203px\x2010px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border-radius:\x20999px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20border:\x201px\x20solid;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2011px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-weight:\x20500;\x0a\x20\x20\x20\x20\x20\x20\x20\x20transition:\x20transform\x20.15s;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-demo-card:hover\x20.ov-demo-badge\x20{\x20transform:\x20scale(1.05);\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-demo-card__cta\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20margin-top:\x204px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2013px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20font-weight:\x20600;\x0a\x20\x20\x20\x20\x20\x20\x20\x20color:\x20var(--okdb-accent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20opacity:\x20.8;\x0a\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20justify-content:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20transition:\x20opacity\x20.15s;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20db-overview\x20.ov-demo-card:hover\x20.ov-demo-card__cta\x20{\x20opacity:\x201;\x20}\x0a\x20\x20\x20\x20\x20\x20@keyframes\x20ov-hue\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20from\x20{\x20filter:\x20hue-rotate(0deg);\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20to\x20\x20\x20{\x20filter:\x20hue-rotate(360deg);\x20}\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20@keyframes\x20ov-aurora\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20from\x20{\x20opacity:\x20.7;\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20to\x20\x20\x20{\x20opacity:\x201.3;\x20}\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20'};
|
|
1
|
+
import e from"../../../stores/events-store.js";import n from"../modals/demo-env-modal.ok.js";export default{tag:"db-overview",dependencies:[n],attr:{stats:{}},context:e=>({recentChanges:[],recentBusy:!1,recentError:null,pipelines:[],pipelinesBusy:!1,pipelinesError:null,violations:[],violationsBusy:!1,violationsError:null,expandedViolationType:null,tmStatus:null,tmBusy:!1,tmScanMsg:"",get info(){return e.$ok.stores.okdb.info},get types(){return(e.$ok.stores.okdb.types||[]).filter(e=>!e.type.startsWith("~")).sort((e,n)=>e.type.localeCompare(n.type))},get systemTypes(){return(e.$ok.stores.okdb.types||[]).filter(e=>e.type.startsWith("~"))},get envName(){return e.$ok.stores.okdb.selectedEnv||"default"},get totalRecords(){return(e.$ok.stores.okdb.types||[]).filter(e=>!e.type.startsWith("~")).reduce((e,n)=>e+(n.count||0),0)},get approxSize(){const e=this.info?.lastPageNumber,n=this.info?.pageSize;if(!e||!n)return"--";let t=e*n;const o=["B","KB","MB","GB","TB"];let i=0;for(;t>=1024&&i<o.length-1;)t/=1024,i++;return t.toFixed(2)+" "+o[i]},typeIndexCount(e){const n=this.info?.types?.[e]?.indexes;return n?Object.keys(n).length:0},typePages(e){return this.info?.types?.[e]?.data?.pages??null},select(n){e.$dispatch("select",n)},async loadRecent(){this.recentBusy=!0,this.recentError=null;try{const n=await fetch(`${e.$ok.stores.okdb.apiBase}/changelog?limit=10`);if(n.ok){const e=await n.json();this.recentChanges=e.data??[]}}catch(e){this.recentError=e?.message||"Failed to load changes"}finally{this.recentBusy=!1}},actionColor:e=>({put:"var(--okdb-success)",remove:"var(--okdb-danger)",type_register:"var(--okdb-accent)",type_drop:"var(--okdb-danger)",index_register:"var(--okdb-purple)",index_drop:"var(--okdb-warning)"}[e]||"var(--okdb-app-fg-muted)"),actionLabel:e=>(e||"").replace(/_/g," "),relTime(e){if(!e)return"—";const n=Date.now()-e;return n<5e3?"just now":n<6e4?`${Math.round(n/1e3)}s ago`:n<36e5?`${Math.round(n/6e4)}m ago`:n<864e5?`${Math.round(n/36e5)}h ago`:new Date(e).toLocaleDateString()},fmt:e=>null==e?"--":Number(e).toLocaleString(),healthColor:e=>"online"===e?"var(--okdb-success)":"degraded"===e?"var(--okdb-warning)":"error"===e?"var(--okdb-danger)":"stopped"===e?"var(--okdb-app-fg-muted)":"var(--okdb-sky)",statusColor:e=>"running"===e||"online"===e?"var(--okdb-success)":"building"===e||"degraded"===e?"var(--okdb-warning)":"error"===e?"var(--okdb-danger)":"stopped"===e||"idle"===e?"var(--okdb-app-fg-muted)":"var(--okdb-sky)",pipelineKey(e){return`${e?.env||this.envName}::${e?.name||""}`},pipelineLabel:e=>e?.meta?.label||e?.name||"Unnamed pipeline",pipelineRoleSummary(e){const n=Array.isArray(e?.engines)?e.engines:[];if(0===n.length)return"No members";const t=[];for(const e of n){const n=e?.role||e?.type;if(n&&!t.includes(n)&&(t.push(n),t.length>=3))break}return t.join(" · ")},pipelineSeverity(e){const n=String(e?.health||"").toLowerCase(),t=String(e?.status||"").toLowerCase();return"error"===n||"error"===t?0:"degraded"===n||"degraded"===t||"building"===t?1:"stopped"===n||"stopped"===t||"idle"===t?2:"online"===n||"running"===t||"online"===t?3:4},get pipelineEngineCount(){const e=new Set;for(const n of this.pipelines)for(const t of n?.engines||[]){const o=t?.key||(t?.type&&t?.name?`${t.type}@${t.name}`:t?.name)||null;o&&e.add(`${n?.env||this.envName}::${o}`)}return e.size},get pipelineHealthCounts(){const e={online:0,degraded:0,error:0,stopped:0};for(const n of this.pipelines){const t=String(n?.health||"").toLowerCase();null!=e[t]&&(e[t]+=1)}return e},get pipelineSummaryText(){const e=this.pipelines.length,n=this.pipelineEngineCount;return`${e} pipeline${1===e?"":"s"} · ${n} engine${1===n?"":"s"}`},get pipelineHighlights(){return[...this.pipelines].sort((e,n)=>{const t=this.pipelineSeverity(e)-this.pipelineSeverity(n);return 0!==t?t:this.pipelineLabel(e).localeCompare(this.pipelineLabel(n))}).slice(0,4)},async loadPipelines(){this.pipelinesBusy=!0,this.pipelinesError=null;try{const n=await fetch(`${e.$ok.stores.okdb.apiBase}/pipelines`),t=await n.json().catch(()=>({}));if(!n.ok)throw new Error(t?.error?.message||"Failed to load pipelines");this.pipelines=t?.data??t?.result??[]}catch(e){this.pipelinesError=e?.message||"Failed to load pipelines",this.pipelines=[]}finally{this.pipelinesBusy=!1}},openPipelinesWorkspace(n=null){const t=e.$vars?.$router;if(!t?.resolve||!t?.push)return;const o={env:this.envName,mode:"pipelines"};n?.name&&(o.pipeline=n.name),t.push(t.resolve("/engines",o))},async openDemoModal(){await e.$ok.shared.modal.open({owner:e,title:'<span style="background:linear-gradient(135deg,var(--okdb-accent),var(--okdb-purple) 50%,var(--okdb-success));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;font-weight:700;font-size:15px;">✦ Demo Environment</span>',canDrag:!0,content:'<demo-env-modal :modal="modal" :on-done="onDone" />',context:n=>({modal:n,onDone:async n=>{e.$ok.stores.okdb.selectEnv(n),await e.$ok.stores.okdb.reloadEnvs(),e.$ok.shared?.toast?.success?.(`✦ Demo environment "${n}" is ready!`)}})})},_unsubs:[],_reloadTimer:null,_scheduleReload(){clearTimeout(this._reloadTimer),this._reloadTimer=setTimeout(()=>this.loadRecent(),600)},async _reloadTypes(){await Promise.all([e.$ok.stores.okdb.reloadTypes(),e.$ok.stores.okdb.reloadInfo()])},async loadViolations(){this.violationsBusy=!0,this.violationsError=null;try{const n=await fetch(`${e.$ok.stores.okdb.apiBase}/violations`);if(404===n.status)return void(this.violations=[]);if(!n.ok){const e=await n.json().catch(()=>({}));throw new Error(e?.error?.message||"Failed to load violations")}const t=await n.json();this.violations=t?.data?.violations??t?.result?.violations??[]}catch(e){this.violationsError=e?.message||"Failed to load violations",this.violations=[]}finally{this.violationsBusy=!1}},get violationsByType(){const e=new Map;for(const n of this.violations){const t=n.type||"?";e.has(t)||e.set(t,[]),e.get(t).push(n)}return[...e.entries()].map(([e,n])=>({type:e,count:n.length,items:n})).sort((e,n)=>n.count-e.count)},get totalViolations(){return this.violations.length},toggleViolationGroup(e){this.expandedViolationType=this.expandedViolationType===e?null:e},navigateToType(n){e.$dispatch("select",{type:n})},async reloadOverviewData(){await Promise.all([this.loadRecent(),this.loadPipelines(),this.loadViolations()])},async loadTMStatus(){try{const n=e.$ok.stores.okdb.selectedEnv||"default",t=await fetch(`${__ENV__.API}/env/${encodeURIComponent(n)}/time-machine/status`);if(!t.ok)return void(this.tmStatus={enabled:!1});const o=await t.json();this.tmStatus=o.result??o.data??{enabled:!1}}catch{this.tmStatus={enabled:!1}}},async enableTM(){if(!this.tmBusy){this.tmBusy=!0,this.tmScanMsg="scanning…";try{const n=e.$ok.stores.okdb.selectedEnv||"default";await fetch(`${__ENV__.API}/env/${encodeURIComponent(n)}/time-machine/enable`,{method:"POST"});const t=Date.now()+1e4;for(;Date.now()<t&&(await new Promise(e=>setTimeout(e,1e3)),await this.loadTMStatus(),!(this.tmStatus?.lastProcessedClock>0)););}catch{}this.tmBusy=!1,this.tmScanMsg=""}},async disableTM(){if(!this.tmBusy){this.tmBusy=!0;try{const n=e.$ok.stores.okdb.selectedEnv||"default";await fetch(`${__ENV__.API}/env/${encodeURIComponent(n)}/time-machine/enable`,{method:"DELETE"}),await this.loadTMStatus()}catch{}this.tmBusy=!1}}}),init(e){this.loadTMStatus(),e.$watch(()=>e.$ok.stores.okdb.selectedEnv,()=>{this.reloadOverviewData(),this.loadTMStatus()})},mount(){this.reloadOverviewData();const n=()=>this.loadPipelines();this._unsubs=[e.on("type:registered",()=>this._reloadTypes()),e.on("type:drop",()=>this._reloadTypes()),e.on("index:registered",()=>this._reloadTypes()),e.on("index:drop",()=>this._reloadTypes()),e.on("engine:started",n),e.on("engine:stopped",n),e.on("engine:error",n),e.on("engine:installed",n),e.on("engine:uninstalled",n),e.on("pipeline:start",n),e.on("pipeline:stop",n),e.on("pipeline:delete",n),e.on("item:create",()=>this._scheduleReload()),e.on("item:update",()=>this._scheduleReload()),e.on("item:remove",()=>this._scheduleReload()),e.on("sync:apply",()=>this._scheduleReload()),e.on("system:clock_change",()=>this._scheduleReload()),e.on("system:poke",()=>this._scheduleReload())]},unmount(){clearTimeout(this._reloadTimer);for(const e of this._unsubs)e();this._unsubs=[]},template:'\n<div style="display:flex; flex-direction:column; gap:20px; max-width:860px;">\n\n \x3c!-- Header --\x3e\n <div style="display:flex; align-items:center; gap:10px;">\n <div style="font-weight:600; font-size:18px;">Database Overview</div>\n <if :="recentBusy">\n <span style="font-size:12px; opacity:.4;">updating…</span>\n </if>\n <div style="margin-left:auto;">\n <button @click="loadRecent()" :disabled="recentBusy"\n style="font-size:12px; padding:5px 12px; opacity:.75;">\n ↻ Refresh\n </button>\n </div>\n </div>\n\n \x3c!-- Stat cards row --\x3e\n <div class="ov-stat-row">\n <div class="ov-stat-card">\n <div class="ov-stat-label">DB Size</div>\n <div class="ov-stat-value" style="color:var(--accent);">{{ approxSize }}</div>\n </div>\n <div class="ov-stat-card">\n <div class="ov-stat-label">Clock</div>\n <div class="ov-stat-value" style="font-family:monospace; font-size:18px;">{{ fmt(info?.clock) }}</div>\n </div>\n <div class="ov-stat-card">\n <div class="ov-stat-label">User Types</div>\n <div class="ov-stat-value" style="color:var(--okdb-purple);">{{ types.length }}</div>\n </div>\n <div class="ov-stat-card">\n <div class="ov-stat-label">Total Records</div>\n <div class="ov-stat-value" style="color:var(--okdb-success);">{{ fmt(totalRecords) }}</div>\n </div>\n </div>\n\n \x3c!-- Empty state --\x3e\n <if :="types.length === 0">\n <div style="display:flex; flex-direction:column; gap:14px;">\n\n \x3c!-- Standard empty hint --\x3e\n <div class="ov-empty">\n <div style="font-size:30px; margin-bottom:12px;">🗄️</div>\n <div style="font-weight:600; font-size:15px; margin-bottom:5px;">No types registered yet</div>\n <div style="font-size:13px; opacity:.6; line-height:1.7;">\n Use <b>Register Type +</b> in the sidebar to create your first collection.<br>\n Types are strongly-typed document collections stored in LMDB.\n </div>\n </div>\n\n \x3c!-- Demo data card --\x3e\n <div class="ov-demo-card" @click="openDemoModal()">\n <div class="ov-demo-card__aurora"></div>\n <div style="position:relative; z-index:1; display:flex; flex-direction:column; align-items:center; gap:10px;">\n <div class="ov-demo-card__sparkle">✦</div>\n <div class="ov-demo-card__title">Generate Demo Environment</div>\n <div class="ov-demo-card__desc">\n Instantly populate a new environment with realistic data, indexes,\n and full-text search — ready to explore in seconds.\n </div>\n <div class="ov-demo-card__badges">\n <span class="ov-demo-badge" style="color:var(--okdb-success); border-color:color-mix(in srgb, var(--okdb-success) 20%, transparent); background:color-mix(in srgb, var(--okdb-success) 7%, transparent);">🛒 E-Commerce</span>\n <span class="ov-demo-badge" style="color:var(--okdb-accent); border-color:color-mix(in srgb, var(--okdb-accent) 20%, transparent); background:color-mix(in srgb, var(--okdb-accent) 7%, transparent);">📊 Analytics</span>\n <span class="ov-demo-badge" style="color:var(--okdb-purple); border-color:color-mix(in srgb, var(--okdb-purple) 20%, transparent); background:color-mix(in srgb, var(--okdb-purple) 7%, transparent);">📝 Content Hub</span>\n <span class="ov-demo-badge" style="color:var(--okdb-warning); border-color:color-mix(in srgb, var(--okdb-warning) 20%, transparent); background:color-mix(in srgb, var(--okdb-warning) 7%, transparent);">👥 Team Directory</span>\n <span class="ov-demo-badge" style="color:var(--okdb-orange); border-color:color-mix(in srgb, var(--okdb-orange) 20%, transparent); background:color-mix(in srgb, var(--okdb-orange) 7%, transparent);">🗺️ City Explorer</span>\n </div>\n <div class="ov-demo-card__cta">\n <span>Choose a preset</span>\n <span style="margin-left:6px; font-size:14px;">→</span>\n </div>\n </div>\n </div>\n\n </div>\n </if>\n\n \x3c!-- Types table --\x3e\n <if :="types.length > 0">\n <div class="ov-card">\n <div class="ov-card-head">\n <span style="font-weight:600; font-size:14px;">Types</span>\n <span style="font-size:12px; opacity:.45; margin-left:auto;">\n {{ types.length }} user · {{ systemTypes.length }} system\n </span>\n </div>\n <table class="ov-table">\n <thead>\n <tr>\n <th>Name</th>\n <th style="text-align:right;">Records</th>\n <th style="text-align:right;">Pages</th>\n <th style="text-align:right;">Indexes</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n <tr as="repeat" :of="types" let:item="t" class="ov-row" @click="select(t)" title="Open in type viewer">\n <td>\n <span style="font-family:monospace; font-size:13px;">{{ t.type }}</span>\n </td>\n <td style="text-align:right; color:var(--accent); font-weight:600;">{{ fmt(t.count) }}</td>\n <td style="text-align:right; opacity:.5; font-size:12px;">{{ fmt(typePages(t.type)) }}</td>\n <td style="text-align:right; font-size:12px;">\n <if :="typeIndexCount(t.type) > 0">\n <span style="\n padding:1px 7px; border-radius:999px;\n border:1px solid color-mix(in srgb, var(--okdb-purple) 33%, transparent); color:var(--okdb-purple);\n font-size:11px;\n ">{{ typeIndexCount(t.type) }}</span>\n </if>\n <if :="typeIndexCount(t.type) === 0">\n <span style="opacity:.3;">—</span>\n </if>\n </td>\n <td style="text-align:right; opacity:.3; font-size:11px; padding-right:16px;">→</td>\n </tr>\n </tbody>\n </table>\n </div>\n </if>\n\n \x3c!-- Violations summary --\x3e\n <if :="totalViolations > 0 || violationsBusy || violationsError">\n <div class="ov-card">\n <div class="ov-card-head">\n <span style="font-weight:600; font-size:14px;">Schema Violations</span>\n <if :="totalViolations > 0">\n <span style="font-size:11px; padding:2px 10px; border-radius:999px; border:1px solid color-mix(in srgb, var(--okdb-danger) 33%, transparent); color:var(--okdb-danger); background:color-mix(in srgb, var(--okdb-danger) 5%, transparent); font-weight:600;">{{ totalViolations }}</span>\n </if>\n <span style="font-size:12px; opacity:.45; margin-left:auto;">across all types in {{ envName }}</span>\n <button @click="loadViolations()" :disabled="violationsBusy" style="font-size:12px; padding:5px 12px; opacity:.75;">↻</button>\n </div>\n <if :="violationsBusy && violations.length === 0">\n <div style="padding:14px 16px; font-size:12px; opacity:.45;">Loading…</div>\n </if>\n <if :="violationsError">\n <div style="padding:10px 16px; color:var(--okdb-danger); font-size:12px;">{{ violationsError }}</div>\n </if>\n <if :="!violationsBusy && !violationsError && violationsByType.length === 0">\n <div style="padding:14px 16px; font-size:12px; opacity:.4;">No violations.</div>\n </if>\n <if :="violationsByType.length > 0">\n <div>\n <each :of="violationsByType" let:item="grp">\n \x3c!-- type group header --\x3e\n <div class="ov-viol-group" @click="toggleViolationGroup(grp.type)">\n <span class="ov-viol-arrow" :style="expandedViolationType === grp.type ? \'transform:rotate(90deg)\' : \'\'">›</span>\n <span style="font-family:monospace; font-size:13px; flex:1;">{{ grp.type }}</span>\n <span style="font-size:11px; padding:2px 8px; border-radius:999px; border:1px solid color-mix(in srgb, var(--okdb-danger) 33%, transparent); color:var(--okdb-danger); background:color-mix(in srgb, var(--okdb-danger) 5%, transparent); margin-right:8px;">{{ grp.count }}</span>\n <button\n @click:stop="navigateToType(grp.type)"\n style="font-size:11px; padding:2px 8px; border-radius:5px; border:1px solid var(--okdb-app-border); background:transparent; color:var(--okdb-sky); cursor:pointer; opacity:.8;"\n title="Open Schema tab for this type"\n >Schema →</button>\n </div>\n \x3c!-- expanded violations for this type --\x3e\n <if :="expandedViolationType === grp.type">\n <div class="ov-viol-list">\n <each :of="grp.items" let:item="v">\n <div class="ov-viol-row">\n <span style="font-family:monospace; font-size:11px; color:var(--okdb-json-key); flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">{{ v.key }}</span>\n <span style="font-size:11px; opacity:.45; white-space:nowrap; margin-left:8px;">{{ (v.errors ?? []).length || (v.errorCount ?? 0) }} error(s)</span>\n </div>\n </each>\n </div>\n </if>\n </each>\n </div>\n </if>\n </div>\n </if>\n\n \x3c!-- Time Machine card --\x3e\n <div class="card">\n <div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:8px;">\n <span style="font-weight:600; font-size:13px;">⏱ Time Machine</span>\n <if :="!tmStatus">\n <span style="font-size:11px; opacity:.4;">loading…</span>\n </if>\n <if :="tmStatus && !tmBusy">\n <button\n @click="tmStatus.enabled ? disableTM() : enableTM()"\n :style="\'font-size:11px; padding:2px 10px; color:\' + (tmStatus.enabled ? \'var(--okdb-danger)\' : \'var(--okdb-success)\') + \'; border-color:\' + (tmStatus.enabled ? \'color-mix(in srgb, var(--okdb-danger) 33%, transparent)\' : \'color-mix(in srgb, var(--okdb-success) 33%, transparent)\') + \';\'"\n >{{ tmStatus.enabled ? \'Disable\' : \'Enable\' }}</button>\n </if>\n <if :="tmBusy">\n <span style="font-size:11px; opacity:.5;">{{ tmScanMsg || \'…\' }}</span>\n </if>\n </div>\n <if :="tmStatus && tmStatus.enabled">\n <div style="font-size:12px; opacity:.7; display:flex; flex-direction:column; gap:3px;">\n <span>tracking since clock {{ tmStatus.startClock }}</span>\n <if :="tmStatus.lastProcessedClock !== tmStatus.envClock">\n <span>last processed: {{ tmStatus.lastProcessedClock }} · env at: {{ tmStatus.envClock }}</span>\n </if>\n <if :="tmStatus.lastProcessedClock === tmStatus.envClock">\n <span>processed through clock {{ tmStatus.lastProcessedClock }}</span>\n </if>\n <span>{{ tmStatus.headCount }} heads</span>\n </div>\n </if>\n <if :="tmStatus && !tmStatus.enabled">\n <span style="font-size:12px; opacity:.4;">disabled</span>\n </if>\n </div>\n\n <div class="ov-card" style="overflow:visible;">\n <div class="ov-card-head">\n <span style="font-weight:600; font-size:14px;">Pipelines</span>\n <span style="font-size:12px; opacity:.45; margin-left:auto;">overview highlights for the current environment</span>\n </div>\n <div style="padding:16px; display:flex; flex-direction:column; gap:14px;">\n <div class="ov-pipelines-headline">\n <div style="display:flex; flex-direction:column; gap:6px; min-width:0; flex:1;">\n <div style="display:flex; align-items:center; gap:8px; flex-wrap:wrap;">\n <div style="font-size:15px; font-weight:600; color:var(--okdb-app-fg);">{{ pipelineSummaryText }}</div>\n <if :="pipelineHealthCounts.error > 0">\n <span class="ov-pipeline-pill" :style="\'color:var(--okdb-danger);border-color:var(--okdb-danger-deep-border);background:#450a0a33;\'">{{ pipelineHealthCounts.error }} error</span>\n </if>\n <if :="pipelineHealthCounts.degraded > 0">\n <span class="ov-pipeline-pill" :style="\'color:#fcd34d;border-color:#854d0e;background:#451a0333;\'">{{ pipelineHealthCounts.degraded }} degraded</span>\n </if>\n <if :="pipelineHealthCounts.online > 0">\n <span class="ov-pipeline-pill" :style="\'color:#86efac;border-color:#166534;background:#052e1633;\'">{{ pipelineHealthCounts.online }} online</span>\n </if>\n </div>\n <div style="font-size:12px; color:var(--okdb-app-fg-muted); line-height:1.6; max-width:640px;">\n The overview should only surface high-signal pipeline highlights. Open the dedicated workspace when you want the full grouped pipeline list and member details.\n </div>\n </div>\n <div style="display:flex; gap:8px; flex-wrap:wrap; align-items:center; justify-content:flex-end;">\n <button @click="loadPipelines()" :disabled="pipelinesBusy" style="font-size:12px; padding:5px 12px; opacity:.75;">↻ Refresh</button>\n <button @click="openPipelinesWorkspace()" style="font-size:12px; padding:5px 12px; border-color:color-mix(in srgb, var(--okdb-indigo) 33%, transparent); color:var(--okdb-indigo);">Open pipelines workspace →</button>\n </div>\n </div>\n\n <if :="pipelinesError">\n <div class="ov-pipelines-error">{{ pipelinesError }}</div>\n </if>\n\n <if :="pipelinesBusy && pipelines.length === 0 && !pipelinesError">\n <div style="font-size:12px; opacity:.45;">Loading pipeline highlights…</div>\n </if>\n\n <if :="!pipelinesBusy && pipelines.length === 0 && !pipelinesError">\n <div class="ov-pipelines-empty">\n <div style="font-size:24px; opacity:.3;">⛓</div>\n <div style="font-size:14px; font-weight:600; opacity:.78;">No pipelines in {{ envName }}</div>\n <div style="font-size:12px; opacity:.5; max-width:520px; line-height:1.7; text-align:center;">\n Pipelines will appear here once created or synced. This frontpage intentionally stays compact and only shows a small highlight list.\n </div>\n </div>\n </if>\n\n <if :="pipelineHighlights.length > 0">\n <div class="ov-pipelines-list">\n <each :of="pipelineHighlights" let:item="pipeline">\n <button class="ov-pipeline-highlight" @click="openPipelinesWorkspace(pipeline)">\n <div style="display:flex; align-items:center; gap:9px; min-width:0;">\n <span :style="\'width:8px;height:8px;border-radius:50%;flex-shrink:0;background:\' + healthColor(pipeline.health)"></span>\n <span style="font-size:13px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">{{ pipelineLabel(pipeline) }}</span>\n <span :style="\'font-size:11px;color:\' + healthColor(pipeline.health) + \';opacity:.95;white-space:nowrap;\'">{{ pipeline.health || \'unknown\' }}</span>\n </div>\n <div style="display:flex; gap:12px; flex-wrap:wrap; margin-top:6px; font-size:11px; color:var(--okdb-app-fg-muted);">\n <span><span style="opacity:.6;">Members:</span> <span style="color:var(--okdb-app-fg);">{{ fmt(pipeline.engines?.length || 0) }}</span></span>\n <if :="pipeline.status">\n <span><span style="opacity:.6;">Status:</span> <span :style="\'color:\' + statusColor(pipeline.status)">{{ pipeline.status }}</span></span>\n </if>\n <span style="overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">{{ pipelineRoleSummary(pipeline) }}</span>\n </div>\n </button>\n </each>\n </div>\n </if>\n\n <if :="pipelines.length > pipelineHighlights.length">\n <div style="font-size:11px; color:var(--okdb-app-fg-muted); opacity:.75;">\n Showing {{ pipelineHighlights.length }} of {{ pipelines.length }} pipelines. Open the dedicated workspace for the full inventory.\n </div>\n </if>\n </div>\n </div>\n\n \x3c!-- Recent activity --\x3e\n <if :="recentChanges.length > 0">\n <div class="ov-card">\n <div class="ov-card-head">\n <span style="font-weight:600; font-size:14px;">Recent Activity</span>\n <span style="font-size:12px; opacity:.4; margin-left:auto;">last {{ recentChanges.length }} changes</span>\n </div>\n <table style="width:100%; border-collapse:collapse; font-size:12px;">\n <tbody>\n <tr as="repeat" :of="recentChanges" let:item="ch" class="ov-row ov-row--sm">\n <td class="ov-ch-td" style="text-align:right; width:60px; font-family:monospace; opacity:.4; padding-left:16px;">\n {{ ch.clock }}\n </td>\n <td class="ov-ch-td" style="width:100px;">\n <span :style="\'font-size:10px; padding:2px 6px; border-radius:3px; border:1px solid; color:\'+actionColor(ch.action)+\'; border-color:\'+actionColor(ch.action)+\'55;\'">\n {{ actionLabel(ch.action) }}\n </span>\n </td>\n <td class="ov-ch-td" style="font-family:monospace; font-size:11px; opacity:.7; max-width:110px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">\n {{ ch.type || \'—\' }}\n </td>\n <td class="ov-ch-td" style="font-family:monospace; font-size:11px; opacity:.45; max-width:160px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">\n {{ ch.key || \'\' }}\n </td>\n <td class="ov-ch-td" style="text-align:right; opacity:.35; white-space:nowrap; font-size:11px; padding-right:16px;">\n {{ relTime(ch.timestamp) }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </if>\n\n</div>\n',style:"\n db-overview .ov-stat-row {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: 12px;\n }\n db-overview .ov-stat-card {\n background: var(--okdb-app-surface);\n border: 1px solid var(--okdb-app-border);\n border-radius: 12px;\n padding: 16px 18px;\n display: flex;\n flex-direction: column;\n gap: 6px;\n box-shadow: 0 2px 8px #0003;\n }\n db-overview .ov-stat-label {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .06em;\n opacity: .5;\n }\n db-overview .ov-stat-value {\n font-size: 22px;\n font-weight: 700;\n line-height: 1;\n }\n db-overview .ov-card {\n background: var(--okdb-app-surface);\n border: 1px solid var(--okdb-app-border);\n border-radius: 12px;\n overflow: hidden;\n box-shadow: 0 2px 8px #0003;\n }\n db-overview .ov-card-head {\n padding: 13px 16px;\n border-bottom: 1px solid var(--okdb-app-border);\n display: flex;\n align-items: center;\n gap: 10px;\n }\n db-overview .ov-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n db-overview .ov-table th {\n padding: 7px 16px;\n text-align: left;\n font-weight: 500;\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: .05em;\n opacity: .4;\n border-bottom: 1px solid var(--okdb-app-border);\n background: var(--okdb-app-bg);\n }\n db-overview .ov-table td {\n padding: 9px 16px;\n border-bottom: 1px solid var(--okdb-app-surface-2);\n }\n db-overview .ov-row {\n cursor: pointer;\n transition: background .1s;\n }\n db-overview .ov-row:hover td {\n background: #ffffff07;\n }\n db-overview .ov-table tbody tr:last-child td {\n border-bottom: none;\n }\n db-overview .ov-ch-td {\n padding: 6px 8px;\n border-bottom: 1px solid var(--okdb-app-surface);\n }\n db-overview .ov-pipelines-headline {\n display: flex;\n justify-content: space-between;\n gap: 12px;\n align-items: flex-start;\n flex-wrap: wrap;\n }\n db-overview .ov-pipeline-pill {\n font-size: 10px;\n padding: 2px 8px;\n border-radius: 999px;\n border: 1px solid;\n white-space: nowrap;\n }\n db-overview .ov-pipelines-error {\n color: var(--okdb-danger);\n font-size: 12px;\n padding: 10px 12px;\n border-radius: 10px;\n border: 1px solid color-mix(in srgb, var(--okdb-danger) 33%, transparent);\n background: color-mix(in srgb, var(--okdb-danger) 5%, transparent);\n }\n db-overview .ov-pipelines-empty {\n border: 1px dashed var(--okdb-app-border);\n border-radius: 12px;\n padding: 24px 20px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n align-items: center;\n }\n db-overview .ov-pipelines-list {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));\n gap: 10px;\n }\n db-overview .ov-pipeline-highlight {\n width: 100%;\n text-align: left;\n border-radius: 10px;\n border: 1px solid var(--okdb-app-border);\n background: var(--okdb-app-bg-deep);\n padding: 11px 12px;\n cursor: pointer;\n }\n db-overview .ov-pipeline-highlight:hover {\n border-color: var(--okdb-app-border-strong);\n background: var(--okdb-app-bg-deep);\n }\n db-overview tbody .ov-row--sm:last-child .ov-ch-td {\n border-bottom: none;\n }\n db-overview .ov-viol-group {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 9px 16px;\n border-bottom: 1px solid var(--okdb-app-surface-2);\n cursor: pointer;\n transition: background .1s;\n }\n db-overview .ov-viol-group:hover { background: #ffffff07; }\n db-overview .ov-viol-arrow {\n display: inline-block;\n font-size: 14px;\n opacity: .5;\n transition: transform .15s;\n width: 14px;\n flex-shrink: 0;\n }\n db-overview .ov-viol-list {\n background: var(--okdb-app-bg-deep);\n border-bottom: 1px solid var(--okdb-app-surface-2);\n }\n db-overview .ov-viol-row {\n display: flex;\n align-items: center;\n padding: 6px 16px 6px 38px;\n border-bottom: 1px solid var(--okdb-app-surface);\n font-size: 12px;\n }\n db-overview .ov-viol-row:last-child { border-bottom: none; }\n db-overview .ov-empty {\n border: 1px dashed var(--okdb-app-border);\n border-radius: 14px;\n padding: 30px 32px;\n text-align: center;\n opacity: .7;\n }\n /* ── Demo data card ── */\n db-overview .ov-demo-card {\n position: relative;\n border: 1px solid var(--okdb-app-border);\n border-radius: 16px;\n padding: 28px 24px 24px;\n text-align: center;\n cursor: pointer;\n overflow: hidden;\n transition: border-color .25s, box-shadow .25s, transform .2s;\n background: var(--okdb-app-bg-deep);\n }\n db-overview .ov-demo-card:hover {\n border-color: color-mix(in srgb, var(--okdb-accent) 53%, transparent);\n box-shadow: 0 0 0 1px color-mix(in srgb, var(--okdb-accent) 13%, transparent), 0 8px 40px color-mix(in srgb, var(--okdb-accent) 9%, transparent), 0 0 80px color-mix(in srgb, var(--okdb-purple) 4%, transparent);\n transform: translateY(-2px);\n }\n db-overview .ov-demo-card__aurora {\n position: absolute;\n inset: 0;\n background:\n radial-gradient(ellipse at 20% 50%, color-mix(in srgb, var(--okdb-accent) 4%, transparent), transparent 55%),\n radial-gradient(ellipse at 80% 30%, color-mix(in srgb, var(--okdb-purple) 4%, transparent), transparent 55%),\n radial-gradient(ellipse at 50% 90%, color-mix(in srgb, var(--okdb-success) 4%, transparent), transparent 55%);\n pointer-events: none;\n animation: ov-aurora 8s ease-in-out infinite alternate;\n }\n db-overview .ov-demo-card__sparkle {\n font-size: 26px;\n background: linear-gradient(135deg, var(--okdb-accent), var(--okdb-purple) 40%, var(--okdb-success));\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n animation: ov-hue 6s linear infinite;\n }\n db-overview .ov-demo-card__title {\n font-size: 17px;\n font-weight: 700;\n background: linear-gradient(135deg, var(--okdb-app-fg-strong), var(--okdb-accent));\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n }\n db-overview .ov-demo-card__desc {\n font-size: 13px;\n opacity: .55;\n max-width: 380px;\n line-height: 1.65;\n }\n db-overview .ov-demo-card__badges {\n display: flex;\n gap: 8px;\n flex-wrap: wrap;\n justify-content: center;\n }\n db-overview .ov-demo-badge {\n padding: 3px 10px;\n border-radius: 999px;\n border: 1px solid;\n font-size: 11px;\n font-weight: 500;\n transition: transform .15s;\n }\n db-overview .ov-demo-card:hover .ov-demo-badge { transform: scale(1.05); }\n db-overview .ov-demo-card__cta {\n margin-top: 4px;\n font-size: 13px;\n font-weight: 600;\n color: var(--okdb-accent);\n opacity: .8;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: opacity .15s;\n }\n db-overview .ov-demo-card:hover .ov-demo-card__cta { opacity: 1; }\n @keyframes ov-hue {\n from { filter: hue-rotate(0deg); }\n to { filter: hue-rotate(360deg); }\n }\n @keyframes ov-aurora {\n from { opacity: .7; }\n to { opacity: 1.3; }\n }\n "};
|