@panphora/clayjs 1.19.0 → 1.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/all.js +1 -1
- package/dist/clay-dom.js +1 -1
- package/dist/clay-events.js +1 -1
- package/dist/clay-internals.js +1 -1
- package/dist/clay-options.js +1 -1
- package/dist/clay-router.js +1 -1
- package/dist/clay-ui.js +1 -1
- package/dist/clay-utils.js +1 -1
- package/dist/clay.js +1 -1
- package/dist/clay.standalone.js +8349 -8125
- package/dist/m/attrs/{refetch-on-save-ZUE7PSCI.js → refetch-on-save-DPGJJMGN.js} +1 -1
- package/dist/m/attrs/save-freeze-MTFVVYV5.js +1 -0
- package/dist/m/{c-DHUCEMXE.js → c-2VB555FG.js} +1 -1
- package/dist/m/{c-KGHVFRR3.js → c-3AXJDL2P.js} +1 -1
- package/dist/m/{c-FOOE4GML.js → c-3GJ4XARY.js} +1 -1
- package/dist/m/c-3TWCKFOP.js +1 -0
- package/dist/m/{c-LPCZOYTX.js → c-3YH6JSIL.js} +1 -1
- package/dist/m/{c-AIWN4QN4.js → c-44B5ODN7.js} +2 -2
- package/dist/m/{c-WQWIRWO3.js → c-5FEU5MMY.js} +1 -1
- package/dist/m/{c-S2U6NJU4.js → c-62HZW5DH.js} +1 -1
- package/dist/m/{c-ZGDYHKG3.js → c-67ILSNPR.js} +1 -1
- package/dist/m/c-67LGZ52V.js +20 -0
- package/dist/m/{c-ZRUQ5FSU.js → c-7SXYQCN4.js} +1 -1
- package/dist/m/{c-LACAAQFB.js → c-AL4RBJF2.js} +1 -1
- package/dist/m/{c-L42OLXWM.js → c-ANNFZFLN.js} +1 -1
- package/dist/m/{c-QO4HNGCQ.js → c-B4VYNXTQ.js} +1 -1
- package/dist/m/{c-7PRJCA3E.js → c-BJPZCWAV.js} +1 -1
- package/dist/m/{c-V52FE5FI.js → c-BTLFLLML.js} +1 -1
- package/dist/m/c-C4IIQZGJ.js +1 -0
- package/dist/m/{c-5T6NZHNM.js → c-CAWNFER6.js} +1 -1
- package/dist/m/c-CSNE5EIF.js +1 -0
- package/dist/m/{c-DVYGFTSK.js → c-DDDOKPI6.js} +2 -2
- package/dist/m/{c-2RARVIAK.js → c-DHXPDLW6.js} +1 -1
- package/dist/m/{c-WCXLG3MV.js → c-E4IBSAQM.js} +1 -1
- package/dist/m/{c-IVTRVENZ.js → c-EDSPKYMA.js} +1 -1
- package/dist/m/{c-2Y4DOHSY.js → c-EFD6QNTE.js} +1 -1
- package/dist/m/{c-7MG5RU63.js → c-EGTIAL6P.js} +1 -1
- package/dist/m/{c-FCNAO2MI.js → c-EOCKLMKX.js} +1 -1
- package/dist/m/{c-UXFUJEZO.js → c-EOCZ2YVL.js} +1 -1
- package/dist/m/{c-K72SY2TL.js → c-EZ7B5AZT.js} +1 -1
- package/dist/m/{c-UPD33ZPE.js → c-FDAXZ2PM.js} +1 -1
- package/dist/m/{c-P3CK66NT.js → c-FNVQAACK.js} +1 -1
- package/dist/m/c-FSWRGBVQ.js +1 -0
- package/dist/m/c-FTWGYI5E.js +1 -0
- package/dist/m/{c-WKNRJX3C.js → c-GKEATME6.js} +1 -1
- package/dist/m/{c-QINHDETP.js → c-GPGYKER7.js} +1 -1
- package/dist/m/{c-FWKHM4E7.js → c-GSRLXYWL.js} +1 -1
- package/dist/m/{c-B7J4K2AE.js → c-GVPNDIKJ.js} +2 -2
- package/dist/m/{c-D3E4WJ4M.js → c-HDWZEJHM.js} +49 -32
- package/dist/m/{c-FTQKI7SP.js → c-I2IFKJX2.js} +1 -1
- package/dist/m/c-ICMAOOGK.js +1 -0
- package/dist/m/{c-HUISJXHF.js → c-J3BXFTZS.js} +1 -1
- package/dist/m/{c-BIJALSRD.js → c-JDZDF2QM.js} +1 -1
- package/dist/m/{c-UDHIVLYH.js → c-JH5FF4NL.js} +1 -1
- package/dist/m/{c-OYRZ7XG2.js → c-JHJR5BQX.js} +1 -1
- package/dist/m/{c-V44KWI2L.js → c-JOH753EJ.js} +2 -2
- package/dist/m/{c-P3OFYUMA.js → c-JUE7B4OX.js} +1 -1
- package/dist/m/c-K76AUL4I.js +7 -0
- package/dist/m/{c-ZWIOJGMT.js → c-LA2BW7UY.js} +1 -1
- package/dist/m/{c-ICJYHABF.js → c-LDUNOR57.js} +1 -1
- package/dist/m/{c-XSZKP646.js → c-LIBE4HPD.js} +1 -1
- package/dist/m/c-LPUJXRXW.js +1 -0
- package/dist/m/{c-JK3PHE7J.js → c-LQU7TXIH.js} +1 -1
- package/dist/m/{c-5ZQV7KC4.js → c-LV5MABYD.js} +1 -1
- package/dist/m/{c-GWNC3UGL.js → c-M4FSPNQ2.js} +1 -1
- package/dist/m/{c-2KIEGNC4.js → c-MEWUGR4D.js} +1 -1
- package/dist/m/c-MIL4B2JQ.js +1 -0
- package/dist/m/{c-IVMD3FEM.js → c-N7Y52HJH.js} +1 -1
- package/dist/m/{c-O4JMKN6U.js → c-NFR673TL.js} +2 -2
- package/dist/m/{c-ZKNBMNN3.js → c-NLZ5AN4L.js} +1 -1
- package/dist/m/{c-RRZJWFLE.js → c-OABVRYOT.js} +1 -1
- package/dist/m/c-PIVIYLTY.js +1 -0
- package/dist/m/{c-L7JL5TL3.js → c-QY7F6EN6.js} +1 -1
- package/dist/m/{c-UY4QX42B.js → c-RG6XUZFA.js} +1 -1
- package/dist/m/c-RHMPKZZ7.js +1 -0
- package/dist/m/{c-TJAXGIRV.js → c-RQRMPZXD.js} +1 -1
- package/dist/m/{c-GY422N3Q.js → c-RS77ODLY.js} +1 -1
- package/dist/m/{c-BAUBNYXK.js → c-RT3C74GY.js} +1 -1
- package/dist/m/{c-CAS3NND4.js → c-S5IEIZCN.js} +1 -1
- package/dist/m/{c-HXPHZN7Q.js → c-SBSMJIPC.js} +1 -1
- package/dist/m/c-SFKI6OLM.js +2 -0
- package/dist/m/{c-4FJTBE6I.js → c-SJPD46ZO.js} +4 -4
- package/dist/m/{c-JCP3XDSJ.js → c-SO63UGPQ.js} +1 -1
- package/dist/m/{c-PLP4JKFC.js → c-TUGVINJR.js} +1 -1
- package/dist/m/{c-Q26MME6N.js → c-TWCXBWS3.js} +1 -1
- package/dist/m/{c-GNDL3TKB.js → c-U5X57T4L.js} +1 -1
- package/dist/m/{c-ZS4US2XV.js → c-UXEVJ63W.js} +1 -1
- package/dist/m/{c-KJJPV77R.js → c-V2J5C5MT.js} +1 -1
- package/dist/m/{c-7PYNAULW.js → c-VBLFAQD2.js} +1 -1
- package/dist/m/{c-ERQSNR6K.js → c-VQCEOGKH.js} +2 -2
- package/dist/m/{c-YVZ2L7CE.js → c-VSPAFOKU.js} +1 -1
- package/dist/m/{c-L6FLIUXP.js → c-VY6XRBOW.js} +1 -1
- package/dist/m/{c-2KL3BD52.js → c-W23KVGUO.js} +1 -1
- package/dist/m/{c-AXGY2WTB.js → c-W3K23S72.js} +1 -1
- package/dist/m/c-WFMRX5RZ.js +1 -0
- package/dist/m/{c-BWFVSBDF.js → c-WN3MXOLT.js} +1 -1
- package/dist/m/{c-MIKZEG5I.js → c-XD5MOROJ.js} +1 -1
- package/dist/m/{c-CQQDL6O4.js → c-XQSXKIKM.js} +1 -1
- package/dist/m/{c-I4MQHOEY.js → c-Y33LUUIQ.js} +1 -1
- package/dist/m/{c-JDARJDOT.js → c-YQUJ74R3.js} +1 -1
- package/dist/m/{c-F6G2OGYG.js → c-YSB6JKV2.js} +2 -2
- package/dist/m/{c-BHZYSHW4.js → c-ZJLU56DV.js} +1 -1
- package/dist/m/{c-DKLS74XB.js → c-ZQXNHZZT.js} +2 -2
- package/dist/m/{c-TNEM3RNM.js → c-ZSCBEB7I.js} +1 -1
- package/dist/m/core/{admin-attrs-YY7T5FGU.js → admin-attrs-ZG7R5V3E.js} +1 -1
- package/dist/m/core/{autosave-RVJPYLRT.js → autosave-VPORYJSE.js} +1 -1
- package/dist/m/core/{conflict-notice-2WGT52LH.js → conflict-notice-JMAZLVRX.js} +1 -1
- package/dist/m/core/{persist-UKXV5KLA.js → persist-3OPWJKZS.js} +1 -1
- package/dist/m/core/{recovery-ZOUOJVIX.js → recovery-DRFZRJED.js} +1 -1
- package/dist/m/core/{save-A5JXV6ME.js → save-AOJBDSOK.js} +1 -1
- package/dist/m/core/{save-core-MKRPSEEO.js → save-core-IOCMXO5L.js} +1 -1
- package/dist/m/core/{snapshot-NU3YM6GR.js → snapshot-O7II2AGG.js} +1 -1
- package/dist/m/core/unsaved-warning-U5VUJFOE.js +1 -0
- package/dist/m/events/{index-RN2JNGBV.js → index-B6TGDYMG.js} +1 -1
- package/dist/m/internals/{index-TGLQINN3.js → index-HDRANDWE.js} +1 -1
- package/dist/m/lib/{cache-bust-MUMFXZK6.js → cache-bust-NH7VBWHO.js} +1 -1
- package/dist/m/lib/{region-policy-SB2AWVG5.js → region-policy-KWBPROWF.js} +1 -1
- package/dist/m/{loader-34YPFKOH.js → loader-ZVPK4ZN3.js} +1 -1
- package/dist/m/manifest-5498AFD3.js +1 -0
- package/dist/m/manifest-edit-62A5A00F.js +1 -0
- package/dist/m/manifest.json +1215 -1171
- package/dist/m/options/{options-EJMS3K24.js → options-55LQHSJ4.js} +1 -1
- package/dist/m/page/{editor-WRQGHDSG.js → editor-EY2WAAGB.js} +2 -2
- package/dist/m/plugins/{ai-edit-X2L2KIEP.js → ai-edit-J5VLSW5I.js} +1 -1
- package/dist/m/plugins/{demo-OYO5GCAO.js → demo-42BSYQ7T.js} +1 -1
- package/dist/m/plugins/{derive-FRE5JJQE.js → derive-QVI3LI3A.js} +1 -1
- package/dist/m/plugins/{live-7C36XEI2.js → live-5EZN2EYP.js} +1 -1
- package/dist/m/plugins/menu-DM2JHPSR.js +1 -0
- package/dist/m/plugins/{page-BSW6MGDO.js → page-LVW5DWA4.js} +2 -2
- package/dist/m/plugins/{page-view-WFZVTPQK.js → page-view-5KQ76IJB.js} +1 -1
- package/dist/m/plugins/{sortable-4S6SQC3D.js → sortable-WJZZBM7R.js} +1 -1
- package/dist/m/plugins/{source-TJXOIOYY.js → source-CCEUM3OR.js} +1 -1
- package/dist/m/plugins/{undo-NLPGCJQY.js → undo-3JEYK5QY.js} +1 -1
- package/dist/m/plugins/{upgrade-HSUNDNJD.js → upgrade-NW556WJD.js} +1 -1
- package/dist/m/plugins/{upload-NHGJXZK2.js → upload-TTCQRIM5.js} +1 -1
- package/dist/m/plugins/{visitor-drafts-BW43DGY3.js → visitor-drafts-2AWNT23K.js} +2 -2
- package/dist/m/plugins/{visitor-drafts-owner-7ODQG7JX.js → visitor-drafts-owner-MZP45XSG.js} +1 -1
- package/dist/m/plugins/{wire-6OSIL3I7.js → wire-VRYPY6EJ.js} +1 -1
- package/dist/m/{reader-core-PLZYLYLT.js → reader-core-2GXY7SHY.js} +2 -2
- package/dist/m/sync/{live-sync-UXNI6ZF6.js → live-sync-SKPMFYOO.js} +1 -1
- package/dist/m/ui/{index-IVWN2QC4.js → index-QNIPDHXQ.js} +1 -1
- package/dist/m/vendor/{sap-core.vendor-RN4ZVY4X.js → sap-core.vendor-OA5SKL7Q.js} +1 -1
- package/dist/offline-manifest.json +650 -626
- package/docs/guide.md +38 -14
- package/entries/sap.js +1 -1
- package/package.json +3 -2
- package/src/core/conflict-download.js +8 -7
- package/src/core/conflict-notice-ui.js +4 -4
- package/src/core/copy-content.js +103 -0
- package/src/core/download.js +14 -2
- package/src/core/save-size-notice.js +2 -2
- package/src/core/upgrade-run.js +5 -1
- package/src/lib/region-policy.js +1 -1
- package/src/page/features/export-html.js +4 -4
- package/src/page/features/export-markdown.js +2 -2
- package/src/page/recovery-ui.js +2 -2
- package/src/page/save-states.js +4 -4
- package/src/plugins/menu/actions.js +1 -1
- package/src/plugins/menu/style.js +59 -31
- package/src/plugins/menu.js +131 -28
- package/src/plugins/page.js +4 -4
- package/src/plugins/visitor-drafts/prompt.js +12 -12
- package/src/plugins/wire.js +3 -1
- package/src/vendor/sap-core.vendor.js +1 -1
- package/dist/m/attrs/save-freeze-LWGF6XUN.js +0 -1
- package/dist/m/c-DCFSEJZG.js +0 -1
- package/dist/m/c-EXEDYU4H.js +0 -1
- package/dist/m/c-GRXHHFPO.js +0 -1
- package/dist/m/c-HT2DKBV2.js +0 -1
- package/dist/m/c-MCOOHCSG.js +0 -1
- package/dist/m/c-MMXKAX2W.js +0 -1
- package/dist/m/c-VE7RKNKZ.js +0 -7
- package/dist/m/c-VR2BJ4AN.js +0 -1
- package/dist/m/c-WGW764WX.js +0 -1
- package/dist/m/c-WNTYKCDG.js +0 -1
- package/dist/m/c-YBSS55KU.js +0 -20
- package/dist/m/core/unsaved-warning-4ZPEV7BF.js +0 -1
- package/dist/m/manifest-0D166F4F.js +0 -1
- package/dist/m/manifest-edit-3877153E.js +0 -1
- package/dist/m/plugins/menu-MFC4DI5E.js +0 -1
- /package/dist/m/{c-QTTJYJMA.js → c-FILLTJA7.js} +0 -0
- /package/dist/m/{c-5JLFROUB.js → c-X5LNHET5.js} +0 -0
- /package/dist/m/plugins/{people-JCHVPF7P.js → people-C7TVBBMR.js} +0 -0
package/docs/guide.md
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
# Building malleable documents with ClayJS
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
ClayJS is a script to give HTML files super powers.
|
|
4
4
|
|
|
5
|
-
It
|
|
5
|
+
It lets the file edit itself and save changes back into itself. With the sync plugin, it also merges edits from other tabs, other people, and agents. The file stays plain HTML.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
ClayJS is for people and AI agents to collaborate: a tracker, a board, a notes page, a dashboard a team edits. Saving needs a host that accepts saves: e.g. HTML Clay, Hyperclay Local, hyperclay.com.
|
|
8
|
+
|
|
9
|
+
Skip ClayJS if your file is static and not meant to be edited. Add ClayJS on the day someone needs to edit the HTML file and collaborate on it.
|
|
10
|
+
|
|
11
|
+
### How to read this guide
|
|
12
|
+
|
|
13
|
+
Open [the problem list](https://clayjs.com/docs/start/), pick the problems you are solving, and read those pages. Everything else can wait. The complete reference stays available as [one Markdown file](https://clayjs.com/guide.md) for the details.
|
|
14
|
+
|
|
15
|
+
Every behavior stated here was read from ClayJS 1.17.0 source or executed. The four example files below are complete, tested apps that this guide quotes. A [test suite](https://github.com/hyperspacesystems/clayjs/tree/main/tests/unit/guide-examples) boots each one in jsdom with the real loader and checks what it saves, how it merges a peer's edit, and what a viewer receives. Open any of them and view source, or download one and open it in HTML Clay to edit it:
|
|
8
16
|
|
|
9
17
|
| File | What it shows |
|
|
10
18
|
|---|---|
|
|
@@ -285,7 +293,7 @@ ClayJS runs in the page, while a **host** serves the file and accepts saves. The
|
|
|
285
293
|
Load ClayJS with a single `<script>` tag and select plugins in its query string:
|
|
286
294
|
|
|
287
295
|
```html
|
|
288
|
-
<script src="https://clayjs.com/v1/clay.js?plugins=sync,
|
|
296
|
+
<script src="https://clayjs.com/v1/clay.js?plugins=sync,undo,indicator,menu&exclude=richclay"></script>
|
|
289
297
|
```
|
|
290
298
|
|
|
291
299
|
- **Use a classic script with a `src`.** The loader reads `document.currentScript` to find its own URL and locate its modules. As `type="module"` or pasted inline, it logs an error and never boots.
|
|
@@ -330,14 +338,14 @@ Plugins add editing, sync, and UI features to `clay.js`. Most are off by default
|
|
|
330
338
|
- `exclude` wins over implications. `exclude=wire` also drops `ai-edit`.
|
|
331
339
|
- Load order is fixed regardless of how you list them.
|
|
332
340
|
- Use `exclude=richclay` when the app has no rich text. `exclude=source` saves one request and about 48 KB, at the cost of saves reprinting the whole document instead of keeping hand formatting.
|
|
333
|
-
- Nothing implies `undo`, on purpose: it
|
|
341
|
+
- Nothing implies `undo`, on purpose: name it when the page should have whole-page undo. It leaves Cmd+Z to text fields ([undo: whole-page undo](https://clayjs.com/docs/guide/components/#undo-whole-page-undo)).
|
|
334
342
|
- In view mode, `page` loads only its reader half and nothing it implies. A Document on `plugins=page` resolves to `page-view`, with no live data service, no generic `sync`, and no `upload`. Name `sync` as well (`plugins=page,sync`) when the reader should take its saved files from sync's lane instead of its own.
|
|
335
343
|
- `derive` loads automatically when the page has a `[sap]` root at boot, and stays idle when full sapjs is on the page. `exclude=derive` opts out; `plugins=derive` loads it for a page that adds its `[sap]` root later.
|
|
336
344
|
- `visitor-drafts` loads its draft store only in draft mode. A reader or an owner editing the original gets a small module that publishes an inert `clay.visitorDrafts` and, for the owner, the owner chip. On a page with no `visitor-drafts` slot, no `api` rules tag, or a rules tag this version cannot read (not `data-rules-version="1"`, or not JSON), it warns in the console and draws nothing. [Free documents for visitors](https://clayjs.com/docs/guide/free-documents/) covers the opt in.
|
|
337
345
|
|
|
338
346
|
Measure what each mode you ship downloads, and keep a byte budget and a test that fails when one grows: [Keep a byte budget per boot, and fail a test when it grows](https://clayjs.com/docs/practices/#keep-a-byte-budget-per-boot-and-fail-a-test-when-it-grows).
|
|
339
347
|
|
|
340
|
-
**A good default
|
|
348
|
+
**A good default:** `?plugins=sync,undo,indicator,menu&exclude=richclay`. It gives a page of plain text live sync, whole-page undo, a save status chip and an Edit switch. Then add by task: `sortable` for drag-to-reorder lists, and `upload` for images or attachments. For formatted text, drop `exclude=richclay` and use `editable`. A document opens in view even for its owner, which is why `menu` is in the default. Declare `<html opens-in="edit">` on a tool page that must edit as soon as it opens.
|
|
341
349
|
|
|
342
350
|
### 2.3 Satellites
|
|
343
351
|
|
|
@@ -892,7 +900,23 @@ Traps in this table:
|
|
|
892
900
|
- **Fill a scratchpad after `clay.ready`, and insert new ones empty.** The contents are captured when the element first appears. Content written before boot, or present in a cloned element when inserted, becomes its saved contents. Empty the scratchpads in a copied record before inserting it.
|
|
893
901
|
- **Create `editor-ui` roots at runtime from an unmarked `<template>` on every load.** An `editor-ui` root disappears from the saved file, so it cannot be authored in the file. Do not mark the blueprint inside the `<template>` as `editor-ui`, or the first save empties the template and leaves no chrome to clone on the next load. Leave the blueprint unmarked and set `clay="editor-ui"` on each clone as you insert it.
|
|
894
902
|
|
|
895
|
-
### 4.3 `
|
|
903
|
+
### 4.3 Copy policy: `no-copy` and `no-copy-unless:paid-forms`
|
|
904
|
+
|
|
905
|
+
Save and sync tokens govern the working document; copy-policy tokens on `clay` govern what travels into an explicit copy:
|
|
906
|
+
|
|
907
|
+
```html
|
|
908
|
+
<script src="/analytics.js" defer clay="no-copy"></script>
|
|
909
|
+
<header class="intro" clay="no-copy">…</header>
|
|
910
|
+
<form action="/_/message" method="post" clay="no-copy-unless:paid-forms">…</form>
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
- **Normal saves keep the original.** Ordinary saves, live sync, versions, and automatic recovery retain `no-copy` and conditional regions.
|
|
914
|
+
- **Explicit copies strip `no-copy` content, even for the owner.** Copies, duplicates, forks, HTML downloads, and ZIP exports remove `clay="no-copy"` elements (including inside `<template>` contents). User-requested recovery downloads filter visible HTML and embedded earlier HTML pages while preserving recovery records and edits.
|
|
915
|
+
- **Authored loaders vs runtime scripts.** An authored loader marked `clay="no-copy"` stays in original saves and disappears from copies. Any SDK `<script>` added at runtime uses `clay="no-save no-snapshot no-watch no-copy"` so it is not persisted. ClayJS core knows only generic copy policy, not any analytics provider.
|
|
916
|
+
- **Conditional paid forms.** `clay="no-copy-unless:paid-forms"` aliases legacy `data-paid-only="forms"` (still supported). Hosted copy/create checks the destination's existing `paid-forms` (`forms`) entitlement; offline downloads have no destination entitlement and strip optional conditional content. Reusable templates retain conditional regions for creation-time filtering, while unconditional `no-copy` regions are removed before owned template outputs. Exact case-sensitive matching fails closed, so an unknown conditional spelling cannot disguise a required paid feature.
|
|
917
|
+
- **Supporting hosts and raw file limits.** Enforced in ClayJS client downloads and recovery exports, Hyperclay hosted copy/create/download flows, and Hyperclay Local / HTML Clay copies and exports. Finder, `cp`, and browser Save Page As bypass app hooks and copy raw file bytes unchanged.
|
|
918
|
+
|
|
919
|
+
### 4.4 `persist`: form controls
|
|
896
920
|
|
|
897
921
|
Put `persist` on every `<input>`, `<textarea>`, and `<select>` whose value belongs to the record. A control's typed value is a property, not an attribute, and serialization only reads attributes. Without `persist`, a typed value is lost on save and the file keeps the authored `value`.
|
|
898
922
|
|
|
@@ -913,7 +937,7 @@ Put `persist` on every `<input>`, `<textarea>`, and `<select>` whose value belon
|
|
|
913
937
|
|
|
914
938
|
**After undo, redo, or a merge, ClayJS puts each control's display back in step with its attributes.** A control the user has touched shows its live property, not its attribute. A merge and the undo plugin copy `checked`, `value`, and `selected` back onto the property (undo does this for `persist` controls outside `no-undo` regions). A merge leaves the focused text field alone, while undo restores it too.
|
|
915
939
|
|
|
916
|
-
### 4.
|
|
940
|
+
### 4.5 Where to keep data that is not visible text
|
|
917
941
|
|
|
918
942
|
In order of preference:
|
|
919
943
|
|
|
@@ -935,7 +959,7 @@ In order of preference:
|
|
|
935
959
|
4. **A live JSON script (`clay="live"`)** for state that changes faster than a save: game boards, scores, cursors ([Live data: `clay="live"`](https://clayjs.com/docs/guide/live-sync/#live-data-clay-live)).
|
|
936
960
|
5. **`<template>` content: never for mutable data.** It is saved, but edits there never trigger autosave.
|
|
937
961
|
|
|
938
|
-
### 4.
|
|
962
|
+
### 4.6 Element identity: `data-id` and `id`
|
|
939
963
|
|
|
940
964
|
Live sync and undo pair elements across versions by **`data-id`, then `id`**, used only when the value is unique on its side and the tag names match. Without an id, elements pair by content, which works for distinct text and fails for identical new items.
|
|
941
965
|
|
|
@@ -956,11 +980,11 @@ Live sync and undo pair elements across versions by **`data-id`, then `id`**, us
|
|
|
956
980
|
- **A `data-id` is also what presence names.** A record target `{ kind: "record", id }` carries it, so a stable id is what lets a peer's badge find the row again after a reload or a merge ([Presence](https://clayjs.com/docs/guide/live-sync/#presence)).
|
|
957
981
|
- **Use ids to find records in commands:** `` board.querySelector(`.card[data-id="${CSS.escape(id)}"]`) ``. Never find a record by position.
|
|
958
982
|
|
|
959
|
-
### 4.
|
|
983
|
+
### 4.7 Assets
|
|
960
984
|
|
|
961
985
|
ClayJS saves an image through its `src`. Upload the file and write the returned URL ([upload and quickcrop](https://clayjs.com/docs/guide/components/#upload-and-quickcrop)). Every host returns a host path such as `/_/uploads/assets-<name>/photo-ab12.png`, which keeps working on that host when the document is renamed or moved. A document opened straight from disk shows those images broken; Export as zip takes a document with its files. Where the host cannot store files, embed a `data:` URL. Data URLs work anywhere, but every save carries the bytes, so keep embedded images small.
|
|
962
986
|
|
|
963
|
-
### 4.
|
|
987
|
+
### 4.8 Ephemeral state: per-tab state on saved elements
|
|
964
988
|
|
|
965
989
|
Use `ephemeral` for per-tab state on a saved element, such as a selected card, a row being dragged, or an open section. Toggling a normal class or attribute is an edit like any other: it marks the page unsaved, starts an autosave, adds an undo step, reaches every peer, and lands in the file. Mark it `ephemeral` instead:
|
|
966
990
|
|
|
@@ -982,7 +1006,7 @@ clay.ephemeral.toggle(card, "selected"); // add, remove, toggle(el, word, forc
|
|
|
982
1006
|
|
|
983
1007
|
Use `ephemeral` for state on one element. State that comes from the URL hash and spans many records (the open card, a filter) is still painted with a runtime stylesheet ([Per-tab state](https://clayjs.com/docs/guide/architecture/#per-tab-state)).
|
|
984
1008
|
|
|
985
|
-
### 4.
|
|
1009
|
+
### 4.9 A template is an ordinary record with a tag
|
|
986
1010
|
|
|
987
1011
|
A reusable template is a record like any other, marked with a tag. It stays editable, searchable, exported, synced and in a visitor's draft, and it needs no second store and no new format. The app reads the tag off the body it already has:
|
|
988
1012
|
|
|
@@ -992,7 +1016,7 @@ const templates = open => Entries.live().filter(a => a !== open && summary({ bod
|
|
|
992
1016
|
|
|
993
1017
|
The tag is matched outside code spans and fences, so a template entry that shows a `#template` example does not become a template itself. Using one copies its text into the page, and the new record is written by the same save as everything else.
|
|
994
1018
|
|
|
995
|
-
### 4.
|
|
1019
|
+
### 4.10 Keep a helper that reads the text beside the editor, in an `editor-ui` row
|
|
996
1020
|
|
|
997
1021
|
A helper that reacts to the text being written belongs in a row a script builds beside the editor, marked `clay="editor-ui"`, and refreshed on a debounce. Nothing it draws is saved, printed or synced, and no keystroke pays for it beyond the debounce:
|
|
998
1022
|
|
|
@@ -2334,7 +2358,7 @@ On hyperclay.com, every tab holds its own sync connection. Over HTTP/1.1, a brow
|
|
|
2334
2358
|
|
|
2335
2359
|
- **HTML Clay:** save the file as `name.htmlclay` and open it with HTML Clay 1.9.0 or newer. The extension changes nothing about the content. The file is ordinary HTML.
|
|
2336
2360
|
- **Hyperclay Local:** put the file in the synced folder and open it from the app.
|
|
2337
|
-
- **hyperclay.com:**
|
|
2361
|
+
- **hyperclay.com:** in your workspace, click **New**, choose **Import files…** and select the file. It becomes a document. An upload does not do this: it stores the file as a static file.
|
|
2338
2362
|
|
|
2339
2363
|
### 9.3 Privacy
|
|
2340
2364
|
|
package/entries/sap.js
CHANGED
|
@@ -6,7 +6,7 @@ var Sap=(()=>{var Qt=Object.defineProperty;var Bn=Object.getOwnPropertyDescripto
|
|
|
6
6
|
`)),i}error(e,r,n={}){let o=this.block(e,r,n);return this.errors.push(o),o}warn(e,r,n={}){let o=this.block(e,r,n);return this.warnings.push(o),o}report(){return{ok:this.errors.length===0&&!this.halted,app:this.appName,halted:this.halted,haltReason:this.haltReason,errors:this.errors.slice(),warnings:this.warnings.slice()}}};function V(t,e){t&&t.getAttribute("sap-error")!==e&&t.setAttribute("sap-error",e)}function ct(t){t&&t.hasAttribute("sap-error")&&t.removeAttribute("sap-error")}function wt(t,e){let r=null,n=3;for(let o of e){let i=Un(t,o);i<n&&(n=i,r=o)}return r}function Un(t,e){let r=t.length,n=e.length,o=Array.from({length:r+1},(i,s)=>[s,...new Array(n).fill(0)]);for(let i=0;i<=n;i++)o[0][i]=i;for(let i=1;i<=r;i++)for(let s=1;s<=n;s++)o[i][s]=Math.min(o[i-1][s]+1,o[i][s-1]+1,o[i-1][s-1]+(t[i-1]===e[s-1]?0:1));return o[r][n]}var Gn=new Set(ut),Yn={readonly:"readOnly",novalidate:"noValidate"},Xn=0,ge=new WeakMap;function Lt(t,e="sap"){let r=t.getAttribute("data-id");if(r)return r;if(t.id)return t.id;let n=ge.get(t);return n||(n=`${e}-${(Xn++).toString(36)}`,ge.set(t,n)),n}function we(t,e="row"){for(;;){let r=`${e}-${Math.random().toString(36).slice(2,8)}`;if(!t.getElementById(r)&&!t.querySelector(`[data-id="${r}"]`))return r}}function Kn(t){return t.hasAttribute("scope")||t.hasAttribute("items")||t.hasAttribute("detail")||t.hasAttribute("each")}function Jn(t){return t.tagName==="TEMPLATE"||t.hasAttribute("sap-ignore")||t.hasAttribute("template")||t.hasAttribute("cms-template")}function H(t,e){for(let n=t.firstElementChild;n;n=n.nextElementSibling)r(n);function r(n){if(Jn(n))return;let o=Kn(n);if(e(n,o),!o)for(let i=n.firstElementChild;i;i=i.nextElementSibling)r(i)}}function j(t){let e=t;for(;e;){if(e.hasAttribute("sap")||e.hasAttribute("scope")||e.hasAttribute("item")||e.hasAttribute("detail"))return e;e=e.parentElement}return null}function tt(t){for(let e=t;e&&e.nodeType===1;e=e.parentElement){if(e._sapEachRow)return e;if(e.hasAttribute("item")||e.hasAttribute("sap"))return null}return null}function Ct(t){let e=t;for(;e;){if(e.hasAttribute("detail")||e.hasAttribute("item"))return e;e=e.parentElement}return null}function yt(t){let e=t;for(;e;){if(e.hasAttribute("detail"))return e;e=e.parentElement}return null}function et(t,e){if(t.hasAttribute("item")&&t.getAttribute("bind")===e)return t;let r=null;return H(t,n=>{!r&&n.getAttribute("bind")===e&&(r=n)}),r}function ft(t,e){let r=null;return H(t,n=>{!r&&n.getAttribute("items")===e&&(r=n)}),r}function lt(t,e){return!t||t.nodeType!==1||!t.hasAttribute("item")?!1:et(t,e)||ft(t,e)?!0:W(t.getAttribute("state")||"").some(r=>r.name===e)}function ye(t){let e=t&&t.$el;return e&&e.nodeType===1&&e.isConnected&&e.hasAttribute("item")?e:null}function Dt(t){return!!t.closest("form[trigger-add]")}function G(t){let e=[];for(let r=t.firstElementChild;r;r=r.nextElementSibling)r.hasAttribute("item")&&!r.hasAttribute("template")&&!r.hasAttribute("cms-template")&&e.push(r);return e}function te(t,e){if(!t||!e)return null;let r=[...t.querySelectorAll(`template[items="${e}"]`)].find(o=>o.closest("[sap]")===t),n=r&&r.content.firstElementChild;return n&&n.hasAttribute("item")?n:null}function Ft(t){for(let e=t.firstElementChild;e;e=e.nextElementSibling)if(e.hasAttribute("item")&&e.hasAttribute("template"))return e;return te(t.closest("[sap]"),t.getAttribute("items"))}function W(t){let e=[];if(!t)return e;for(let r of t.trim().split(/\s+/)){if(!r)continue;let n=r,o,i=n.indexOf("=");i>=0&&(o=n.slice(i+1),n=n.slice(0,i));let s=n.split(":"),b=s[0],m="string",d=!1;for(let A of s.slice(1))A==="num"?m="num":A==="bool"?m="bool":A==="presence"?m="presence":A==="transient"&&(d=!0);let u=b,E=u.startsWith("data-")&&u.length>5?u.slice(5).replace(/-([a-z])/g,(A,N)=>N.toUpperCase()):u;e.push({name:E,attr:u,type:m,default:o,transient:d})}return e}function Z(t,e){if(e==="num"){if(t==null||t==="")return 0;let r=Number(t);return Number.isNaN(r)?0:r}return e==="bool"?t==="true"||t===""||t==="1":t??""}function ee(t,e){return e==="bool"?t?"true":"false":t==null?"":String(t)}function ne(t,e){return Gn.has(e)&&typeof t[Yn[e]||e]=="boolean"}function Y(t,e){return e.type==="presence"||e.type!=="num"&&ne(t,e.attr||e.name)}function At(t){return t.default!=null?t.default:t.type==="num"?"0":t.type==="bool"?"false":""}function Ae(t,e){let r=e.attr||e.name;if(Y(t,e))return t.hasAttribute(r);let n=t.getAttribute(r);return Z(n??At(e),e.type)}function ve(t,e){return Y(t,e)?e.default!=null?Z(e.default,"bool"):!1:Z(At(e),e.type)}function vt(t,e,r){let n=e.attr||e.name;if(Y(t,e)){r?t.hasAttribute(n)||t.setAttribute(n,""):t.hasAttribute(n)&&t.removeAttribute(n);return}t.setAttribute(n,ee(r,e.type))}function Mt(t,e){let r=e.attr||e.name,n=t._sapTransient||(t._sapTransient={});if(!(e.name in n)){let o=t.getAttribute(r);o==null&&(o=At(e)),n[e.name]=Z(o,e.type)}return t.hasAttribute(r)&&t.removeAttribute(r),n[e.name]}function Et(t,e,r){let n=e.attr||e.name;(t._sapTransient||(t._sapTransient={}))[e.name]=r,t.hasAttribute(n)&&t.removeAttribute(n)}function xt(t,e,r){let n=String(r).split("."),o=n[n.length-1];if(n.length===1){let b=Qn(e,o);return b||(t.getAttribute("items")===o?t:t.querySelector(`[items="${o}"]:not(template)`))}let i=n[n.length-2],s=[...t.querySelectorAll(`[scope="${i}"]`)].find(b=>ft(b,o));return s?ft(s,o):null}function Qn(t,e){let r=j(t);for(;r;){if(r.getAttribute("items")===e)return r;let n=ft(r,e);if(n)return n;r=j(r.parentElement)}return null}function q(t){if(typeof t=="number")return t;if(t==null||t==="")return 0;let e=Number(typeof t=="string"?t.replace(/[$,%\s]/g,""):t);return Number.isNaN(e)?0:e}function Ot(t,e){return Array.isArray(t)?e==null?t:t.map(r=>typeof e=="function"?e(r):r?.[e]):[]}function re(t,e){return Ot(t,e).reduce((r,n)=>r+q(n),0)}function Ee(t,e){return Array.isArray(t)?e==null?t.length:t.reduce((r,n)=>r+(e(n)?1:0),0):0}function xe(t,e){let r=Ot(t,e);return r.length?re(t,e)/r.length:0}function Se(t,e){let r=Ot(t,e).filter(n=>n!=null&&n!=="");return r.length?r.every(n=>typeof n=="number"||!Number.isNaN(Number(n)))?Math.min(...r.map(Number)):r.reduce((n,o)=>String(n)<=String(o)?n:o):0}function ke(t,e){let r=Ot(t,e).filter(n=>n!=null&&n!=="");return r.length?r.every(n=>typeof n=="number"||!Number.isNaN(Number(n)))?Math.max(...r.map(Number)):r.reduce((n,o)=>String(n)>=String(o)?n:o):0}function $e(t,e,r){let n=q(t)===1?e:r??e+"s";return`${t} ${n}`}function _e(t,e){let r=new Date(t),n=new Date(e);return Number.isNaN(+r)||Number.isNaN(+n)?0:Math.round((n-r)/864e5)}function U(t){return typeof t=="number"?t:Number(t)}var dt={usd:t=>"$"+U(t).toLocaleString("en-US",{maximumFractionDigits:0}),usd2:t=>"$"+U(t).toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}),pct:t=>Math.round(U(t))+"%",pct1:t=>U(t).toFixed(1)+"%",int:t=>Math.round(U(t)).toLocaleString("en-US"),num:t=>U(t).toLocaleString("en-US"),num2:t=>U(t).toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}),compact:t=>U(t).toLocaleString("en-US",{notation:"compact"}),date:t=>{let e=new Date(t);return Number.isNaN(+e)?String(t):e.toLocaleDateString("en-US")},clock:t=>{let e=U(t),r=Math.floor(e/100),n=r%10,o=Math.floor(r/10)%60;return`${Math.floor(r/600)}:${String(o).padStart(2,"0")}.${n}`}},Zn=new Set(["usd","usd2","pct","pct1","int","num","num2","compact","clock"]);function Te(t,e){if(!t)return e==null?"":String(e);let r=dt[t];if(typeof r!="function"){let n=new Error(`unknown format "${t}"`);throw n.sapCode="E22",n}if(Zn.has(t)){let n=typeof e=="number"?e:Number(e);if(!Number.isFinite(n)){let o=new Error(`format "${t}" received ${typeof e=="string"?`"${e}"`:e}`);throw o.sapCode="E22",o}}return r(e)}var tr=["state","item","el","root","fmt","num","sum","count","avg","min","max","plural","days"],Pt=new Map,Ne=/\bstate\.([a-z][a-z0-9_]*)/g,Re=/\bitem\.([a-z][a-z0-9_]*)/g;function er(t){let e=new Set,r=new Set,n;for(Ne.lastIndex=0;n=Ne.exec(t);)e.add(n[1]);for(Re.lastIndex=0;n=Re.exec(t);)r.add(n[1]);return{state:e,item:r}}function P(t,e=!1){let r=(e?"!":"")+t,n=Pt.get(r);if(n)return n;Pt.size>512&&Pt.clear();try{let o=e?`"use strict";
|
|
7
7
|
${t}`:`"use strict"; return (${t});`;n={fn:new Function(...tr,o),src:t,statement:e,deps:er(t),error:null}}catch(o){n={fn:null,src:t,statement:e,deps:{state:new Set,item:new Set},error:o}}return Pt.set(r,n),n}function nt(t,e){return z(t,e.state,e.item,e.el??null,e.root)}function z(t,e,r,n,o){if(t.error)throw t.error;return t.fn(e,r,n,o,dt,q,re,Ee,xe,Se,ke,$e,_e)}function Le(t){let e=new Map;for(let s of t)e.set(s.name,s);let r=[],n=new Map,o=[];function i(s){let b=n.get(s.name);if(b!==1){if(b===0){let m=[...o.slice(o.indexOf(s.name)),s.name].join(" -> "),d=new Error(`calc: cycle: ${m}`);throw d.sapCode="E07",d.cycle=m,d}n.set(s.name,0),o.push(s.name);for(let m of s.entry.deps.state){let d=e.get(m);d&&d!==s&&i(d)}for(let m of s.entry.deps.item){let d=e.get(m);d&&d!==s&&i(d)}o.pop(),n.set(s.name,1),r.push(s)}}for(let s of t)i(s);return r}var St={},rt=null,De=!0,Wt=!1;function Fe(){St={}}function Me(t){let e=Wt;return rt?oe(rt.takeRecords()):De&&nr(),Wt=!!rt&&t.getRootNode()===document,e}function Oe(t){Wt=t}function Bt(){rt&&oe(rt.takeRecords())}function nr(){if(typeof document>"u"||typeof MutationObserver!="function"){De=!1;return}rt=new MutationObserver(oe),rt.observe(document,{attributes:!0,childList:!0,subtree:!0})}function oe(t){for(let e of t)if(e.type==="attributes")e.target._sapPlan&&(e.target._sapPlan=null);else for(let r of e.addedNodes)r.nodeType===1&&Pe(r)}function Pe(t){t._sapPlan&&(t._sapPlan=null);for(let e=t.firstElementChild;e;e=e.nextElementSibling)Pe(e)}function X(t){if(!Wt)return Ce(t);let e=t._sapPlan;return e&&e.gen===St?e:t._sapPlan=Ce(t)}function Ce(t){let e={gen:St,inert:t.tagName==="TEMPLATE",template:!1,cms:!1,item:!1,scope:!1,items:!1,detail:!1,each:!1,boundary:null,bind:null,transient:!1,decls:null,calcs:null,paints:null,effects:null,invalids:null};for(let r of t.attributes){let n=r.name,o=r.value,i=n.indexOf(":");if(i<0){switch(n){case"sap-ignore":e.inert=!0;break;case"cms-template":e.inert=!0,e.cms=!0;break;case"template":e.inert=!0,e.template=!0;break;case"item":e.item=!0;break;case"scope":e.scope=!0;break;case"items":e.items=!0;break;case"detail":e.detail=!0;break;case"each":e.each=!0;break;case"bind":e.bind=o;break;case"transient":e.transient=!0;break;case"state":e.decls=W(o);break;case"text":(e.paints||(e.paints=[])).push({kind:"text",fmt:null,entry:P(o)});break;case"show":(e.paints||(e.paints=[])).push({kind:"show",entry:P(o)});break;case"effect":(e.effects||(e.effects=[])).push({entry:P(o,!0)});break;case"invalid":(e.invalids||(e.invalids=[])).push({entry:P(o)});break}continue}let s=n.slice(0,i),b=n.slice(i+1);switch(s){case"calc":(e.calcs||(e.calcs=[])).push({name:b,entry:P(o)});break;case"text":(e.paints||(e.paints=[])).push({kind:"text",fmt:b,entry:P(o)});break;case"attr":(e.paints||(e.paints=[])).push({kind:"attr",arg:b,entry:P(o)});break;case"class":(e.paints||(e.paints=[])).push({kind:"class",arg:b,entry:P(o)});break;case"css":(e.paints||(e.paints=[])).push({kind:"css",arg:b,entry:P(o)});break;case"show-when":case"option":(e.paints||(e.paints=[])).push({kind:"when",match:"show",field:b,values:o.split("|")});break;case"hide-when":(e.paints||(e.paints=[])).push({kind:"when",match:"hide",field:b,values:o.split("|")});break;case"option-not":(e.paints||(e.paints=[])).push({kind:"when",match:"show-not",field:b,values:o.split("|")});break}}return e.boundary=e.scope?"scope":e.items?"items":e.detail?"detail":e.each?"each":null,or(e)?rr():e}var It=null;function rr(){return(!It||It.gen!==St)&&(It=Object.freeze({gen:St,inert:!1,template:!1,cms:!1,item:!1,scope:!1,items:!1,detail:!1,each:!1,boundary:null,bind:null,transient:!1,decls:null,calcs:null,paints:null,effects:null,invalids:null})),It}function or(t){return!t.inert&&!t.item&&t.boundary===null&&t.bind===null&&!t.transient&&!t.decls&&!t.calcs&&!t.paints&&!t.effects&&!t.invalids}var ot=new WeakMap,it=new WeakMap,pt=null,K=!1;function We(){ot=new WeakMap,it=new WeakMap}function Ie(t){for(let e of t){let r=e.target.nodeType===1?e.target:e.target.parentElement;for(let n=r;n;n=n.parentElement)it.delete(n);if(e.type==="attributes"){ot.delete(e.target);continue}for(let n=r;n;n=n.parentElement)ot.delete(n);for(let n of e.addedNodes||[])if(n.nodeType===1){ot.delete(n),it.delete(n);for(let o of n.querySelectorAll("*"))ot.delete(o),it.delete(o)}}}function Be(){return K}function je(t){return K?it.get(t):void 0}function qe(t,e){K&&it.set(t,e)}function jt(t){it.delete(t)}function ze(t){let e=K;return!pt&&typeof MutationObserver=="function"&&(pt=new MutationObserver(Ie),pt.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})),pt&&Ie(pt.takeRecords()),K=!!pt&&t.getRootNode()===document,e}function He(t){K=t}function Ve(t){let e=ot.get(t);return e||ot.set(t,e={attrs:new Map,hasText:!1,text:""}),e}function Ue(t,e){if(!K)return t.getAttribute(e);let r=Ve(t);return r.attrs.has(e)||r.attrs.set(e,t.getAttribute(e)),r.attrs.get(e)}function Ge(t){if(!K)return t.textContent;let e=Ve(t);return e.hasText||(e.text=t.textContent,e.hasText=!0),e.text}function Ye(t){return(t.getAttribute("type")||"text").toLowerCase()}function mt(t){let e=t.tagName;if(e==="INPUT"){let r=Ye(t);r==="checkbox"||r==="radio"?t.checked?t.setAttribute("checked",""):t.removeAttribute("checked"):t.setAttribute("value",t.value);return}if(e==="TEXTAREA"){t.setAttribute("data-value",t.value);return}if(e==="SELECT"){let r=t.options;for(let n=0;n<r.length;n++)r[n].selected?r[n].setAttribute("selected",""):r[n].removeAttribute("selected")}}function Xe(t,e=t){let r=t.tagName;if(r==="INPUT"){let n=Ye(t);n==="checkbox"||n==="radio"?e.checked?t.hasAttribute("checked")||t.setAttribute("checked",""):t.removeAttribute("checked"):e.value!==(t.getAttribute("value")??"")&&t.setAttribute("value",e.value);return}if(r==="TEXTAREA"){let n=e.value.startsWith(`
|
|
8
8
|
`)?`
|
|
9
|
-
`+e.value:e.value;t.textContent!==n&&(t.textContent=n),t.removeAttribute("data-value");return}if(r==="SELECT"){let n=t.options,o=e.options;for(let i=0;i<n.length;i++)o[i]&&o[i].selected?n[i].hasAttribute("selected")||n[i].setAttribute("selected",""):n[i].removeAttribute("selected")}}function qt(t){t.tagName!=="TEXTAREA"||!t.hasAttribute("data-value")||t!==t.ownerDocument.activeElement&&(t.textContent=t.getAttribute("data-value"),t.removeAttribute("data-value"))}function O(t){if(typeof window>"u")return null;let e=window.clay,r=window.hyperclay;return t==="consent"?e?.confirm||r?.consent||null:e?.[t]||r?.[t]||null}function Ke(){let t=O("visitorDrafts");return!!(t&&typeof t.restored=="function"&&t.restored()?.restored)}var ie=["clay:mutation-ready","hyperclay:mutation-ready"],ir=["clay:sync-applied","hyperclay:livesync-applied"],sr=["clay:ready","hyperclay:ready"],ar=["clay:route"],ur=["clay:modechange"];function kt(t,e,r){let n=null,o=i=>{n!==null&&n!==i.type||(n=i.type,queueMicrotask(()=>{n=null}),r(i))};for(let i of e)t.addEventListener(i,o);return()=>{for(let i of e)t.removeEventListener(i,o)}}function Je(t){let e=typeof window<"u"&&window.clay&&window.clay.ready;e&&typeof e.then=="function"?e.then(()=>t(),()=>t()):t()}function zt(t){let e=O("region");return!e||typeof e.resolveRegionPolicy!="function"||typeof e.skipForPolicy!="function"?!1:e.skipForPolicy(e.resolveRegionPolicy(t),void 0,["no-save","freeze"])}function $t(){return typeof window>"u"?null:window.clay?.modeLifecycle||null}function F(t,{transient:e=!1}={}){if(e)return!0;let r=$t();return typeof r?.canWrite!="function"||O("region")?.resolveRegionPolicy?.(t)?.persist==="none"?!0:r.canWrite()}function Qe(){let t=O("consent");return typeof t=="function"?t:null}function Ze(t,e){if(typeof e!="function")throw new Error("Sap.batch(label, fn): fn must be a function");let r=O("undo");r&&r.flush&&r.flush();let n=e();if(n&&typeof n.then=="function")throw new Error("Sap.batch fn must be synchronous (it returned a promise)");return r&&r.commitCaptured&&r.commitCaptured(t),n}function tn(t){if(typeof window>"u"||typeof document>"u")return;let e=()=>{let A=!1;for(let N of t.apps())N.root.isConnected?t.runNow(N,"platform"):A=!0;A&&t.pruneDisconnected(),t.remountIfPresent()},r=O("derived"),n=r&&typeof r.register=="function"?r.register(e):null,o=typeof n=="function"?null:kt(document,ir,e),i=kt(document,ar,e),s=null,b=!1,m=()=>{let A=s;s=null,A&&(A[2](),A[3]())},d=()=>{if(b)return!1;let A=O("undo"),N=$t()?.state?.generation;if(s&&s[0]===A&&s[1]===N)return!0;if(m(),!A||typeof A.on!="function")return!1;let R=A.on("undo",e);if(typeof R!="function")return!1;let p=A.on("redo",e);return typeof p!="function"?(R(),!1):(s=[A,N,R,p],!0)};d();let u=[ie,sr,ur].map(A=>kt(document,A,d)),E=O("ready");return E&&typeof E.then=="function"&&E.then(d,()=>{}),()=>{b=!0,typeof n=="function"&&n(),o&&o(),i();for(let A of u)A();m()}}function _t(t){let e=t.tagName;if(e==="INPUT"){let r=(t.getAttribute("type")||"text").toLowerCase();return r==="checkbox"?"checkbox":r==="radio"?"radio":r==="number"||r==="range"?"number":r==="hidden"?"hidden":"text"}return e==="TEXTAREA"?"text":e==="SELECT"?t.multiple?"select-multiple":"select-one":"leaf"}function cr(t){if(t.validity&&t.validity.badInput)return t.hasAttribute("value")?Number(t.getAttribute("value"))||0:t._sapLastGood??0;if(t.value==="")return 0;let e=Number(t.value);return Number.isNaN(e)?t._sapLastGood??0:(t._sapLastGood=e,e)}function en(t,e){switch(e){case"checkbox":return t.checked;case"radio":return t.checked?t.value:void 0;case"number":return cr(t);case"select-one":return t.value;case"select-multiple":return[...t.selectedOptions].map(r=>r.value);case"hidden":case"text":return t.value;case"leaf":return t.textContent;default:return t.value}}function nn(t,e,r){switch(e){case"checkbox":t.checked=!!r;break;case"radio":t.checked=String(t.value)===String(r);break;case"number":case"text":case"hidden":t.value=r==null?"":String(r);break;case"select-one":t.value=r==null?"":String(r);break;case"select-multiple":{let n=new Set((Array.isArray(r)?r:[r]).map(String));for(let o of t.options)o.selected=n.has(o.value);break}case"leaf":t.textContent=r==null?"":String(r);break;default:t.value=r==null?"":String(r)}}function se(t){if(t.hasAttribute("transient")){t.removeAttribute("value"),t.removeAttribute("checked"),t.removeAttribute("data-value");return}zt(t)||mt(t)}function fr(t){t.dispatchEvent(new Event("input",{bubbles:!0})),t.dispatchEvent(new Event("change",{bubbles:!0}))}function Ht(t,e){return en(t,e)}function rn(t,e,r){nn(t,e,r),se(t)}function B(t){let e=_t(t);return{el:t,kind:e,read(){return en(t,e)},write(r,n={}){nn(t,e,r),n.noMirror||se(t),n.silent||fr(t)},mirror(){se(t)}}}var J=null,Ut=!1,ht=null;function on(t){let e=null;return{kind:"hub",subscribe(r){let n=t.onAnyChange({debounce:0,require:"observed"},r);typeof n=="function"&&(e=n)},suppress(r){t.pause();try{return r()}finally{t.resume()}},teardown(){if(e){try{e()}catch{}e=null}}}}function lr(){let t=null;return{kind:"native",subscribe(e){t=new MutationObserver(n=>e(dr(n)));let r=typeof document<"u"&&document.body||typeof document<"u"&&document.documentElement;r&&t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0})},suppress(e){let r=O("undo");r&&r.pause&&r.pause();try{return e()}finally{t&&t.takeRecords(),r&&r.resume&&r.resume()}},teardown(){t&&(t.disconnect(),t=null)}}}function dr(t){let e=[];for(let r of t)if(r.type==="attributes"){let n=r.target;n&&n.nodeType===1&&!Vt(n)&&e.push({type:"attribute",element:n})}else if(r.type==="characterData"){let n=r.target&&r.target.parentElement;n&&!Vt(n)&&e.push({type:"characterData",element:n})}else if(r.type==="childList"){for(let n of r.addedNodes)if(!(n.nodeType!==1||Vt(n))&&(e.push({type:"add",element:n}),n.querySelectorAll))for(let o of n.querySelectorAll("*"))Vt(o)||e.push({type:"add",element:o});for(let n of r.removedNodes)n.nodeType===1&&e.push({type:"remove",element:n,parent:r.target})}return e}function Vt(t){return!!(t.closest&&t.closest("[sap-ignore],[template],[cms-template]"))}function pr(t,e){t.pruneDisconnected();let r=new Set,n=!1;for(let o of e){let i=o.type==="remove"?o.parent:o.element,s=i&&t.appFor(i);s&&r.add(s),o.type==="add"&&o.element&&o.element.nodeType===1&&o.element.hasAttribute&&o.element.hasAttribute("sap")&&!(t.isRegistered&&t.isRegistered(o.element))&&(n=!0)}n&&t.remountIfPresent();for(let o of r)o.root.isConnected&&t.schedule(o,"mutation")}function sn(t){if(J)return J.suppress(t);let e=O("undo");if(e&&e.pause&&e.resume){e.pause();try{return t()}finally{e.resume()}}return t()}function ae(t,e){Ut=!0,J=t,t.subscribe(r=>pr(e,r))}function ue(t){if(Ut||typeof window>"u"||typeof document>"u")return;let e=O("Mutation");if(e&&typeof e.onAnyChange=="function"){ae(on(e),t);return}typeof MutationObserver=="function"&&(ae(lr(),t),ht=kt(document,ie,function(){let n=O("Mutation");n&&(ht(),ht=null,J&&J.teardown(),Ut=!1,ae(on(n),t))}))}function ce(){if(J)try{J.teardown()}catch{}ht&&typeof document<"u"&&ht(),J=null,Ut=!1,ht=null}var mr=new Set(ut),Gt=Object.freeze([]),Q=[],un={},cn={};function fn(t){Q.includes(t)||(Q.push(t),t.boundary&&Object.assign(un,t.boundary),t.paintKinds&&Object.assign(cn,t.paintKinds))}function bt(t,e={}){if(e.breaker){t.diag.error("E26",t.root,{problem:"recompute loop halted after 50 passes; recent triggers: "+(t._breakerRing||[]).join(", ")}),V(t.root,"loop");return}e.full&&(Fe(),We());let r=Me(t.root);try{sn(()=>hr(t,e))}finally{Oe(r)}t._viewsChanged&&(t._viewsChanged=!1,t.root.dispatchEvent(new CustomEvent("sap:views-updated",{bubbles:!0})))}function hr(t,e){let r=t.root,n={},o=[],i=[],s=new Set;t.diag.errors=[];let b={root:n,state:n,item:null,ownerEl:r,projection:!1},m=null;function d(f,S,k=!1){let $=S.attr||S.name,_=k?Ue(f,$):f.getAttribute($);return _==null&&(_=At(S),i.push({el:f,name:S.name,attr:$,value:ee(Z(_,S.type),S.type)})),Z(_,S.type)}function u(f,S,k,$){let _=S.decls;if(!_)return;let L=!!$.item&&!$.projection&&!$.view;for(let D of _){if(D.transient){m&&(m.pure=!1),k[D.name]=Mt(f,D);continue}if(Y(f,D)){k[D.name]=f.hasAttribute(D.attr);continue}k[D.name]=d(f,D,L)}}function E(f,S,k){let $=S.bind,_=k.item||k.state,L=_t(f);m&&(L!=="leaf"||S.transient)&&(m.pure=!1),L==="radio"?($ in _||(_[$]=""),f.checked&&(_[$]=f.value)):L==="leaf"&&k.item&&!k.projection&&!k.view?_[$]=Ge(f):_[$]=Ht(f,L),S.transient&&(f.removeAttribute("value"),f.removeAttribute("checked"))}function A(f,S,k){let $=!1;if(S.paints){$=!0;for(let _ of S.paints)_.kind==="when"&&s.add(_.field),o.push({def:_,el:f,ctx:k})}for(let _ of Q)_.collect&&_.collect(a,f,S,k)!==!1&&($=!0);m&&$&&(S.calcs&&(m.pure=!1),m.collects.push(f,S))}function N(f,S,k){Object.defineProperty(f,"$key",{value:Lt(S,"row"),enumerable:!1}),Object.defineProperty(f,"$index",{value:k,enumerable:!1,configurable:!0}),Object.defineProperty(f,"$el",{value:S,enumerable:!1})}function R(f,S,k){let $=X(f);u(f,$,S,k),f._sapScope=S,!k.projection&&$.bind!=null&&E(f,$,k),A(f,$,k),$.items?w(f,S,k):p(f,S,k)}function p(f,S,k){for(let $=f.firstElementChild;$;$=$.nextElementSibling)y($,S,k)}function y(f,S,k){let $=X(f);if(!$.inert){if($.boundary){m&&(m.pure=!1),$.boundary==="scope"?h(f,S,k):$.boundary==="items"?(A(f,$,k),w(f,S,k)):un[$.boundary](a,f,$,S,k);return}!k.projection&&!k.view&&$.bind!=null&&E(f,$,k),A(f,$,k);for(let _=f.firstElementChild;_;_=_.nextElementSibling)y(_,S,k)}}function h(f,S,k){let $=f.getAttribute("scope"),_={};S[$]=_;let L={root:k.root,state:_,item:null,ownerEl:f,projection:k.projection};R(f,_,L)}function w(f,S,k){m&&(m.pure=!1);let $=f.getAttribute("items"),_=[];S[$]=_,f._sapList=_;let L=!k.projection&&!k.view&&Be(),D=0;for(let M=f.firstElementChild;M;M=M.nextElementSibling){let C=X(M);if(!C.item||C.template||C.cms)continue;let I=L?je(M):void 0;_.push(I&&I.plan===C&&Object.isExtensible(I.obj)&&c(I,M,D,k)||x(M,C,D,k,L)),D++}}function x(f,S,k,$,_){let L={};N(L,f,k);let D={root:$.root,state:$.state,item:L,ownerEl:f,projection:$.projection};if(!_)return R(f,L,D),L;let M=m,C={plan:S,obj:L,fields:null,presence:Gt,pending:Gt,collects:[],pure:!0},I=i.length,Wn=t.diag.errors.length;m=C;try{R(f,L,D)}finally{m=M}if(!C.pure||t.halted||t.diag.errors.length!==Wn)return L;let he=[];for(let st of Object.keys(L)){let Jt=L[st];if(Jt!==null&&typeof Jt=="object")return L;he.push(st,Jt)}if(S.decls)for(let st of S.decls)Y(f,st)&&(C.presence===Gt?C.presence=[]:C.presence).push(st.name,st.attr);return i.length>I&&(C.pending=i.slice(I)),C.collects.length||(C.collects=Gt),C.fields=he,qe(f,C),L}function c(f,S,k,$){let _=f.obj;try{_.$index!==k&&Object.defineProperty(_,"$index",{value:k,enumerable:!1,configurable:!0});let M=f.presence;for(let I=0;I<M.length;I+=2)_[M[I]]=S.hasAttribute(M[I+1]);let C=f.fields;for(let I=0;I<C.length;I+=2)_[C[I]]=C[I+1]}catch{return jt(S),null}S._sapScope=_;let L=f.pending;for(let M=0;M<L.length;M++)i.push(L[M]);let D=f.collects;if(D.length){let M={root:$.root,state:$.state,item:_,ownerEl:S,projection:$.projection};for(let C=0;C<D.length;C+=2)A(D[C],D[C+1],M)}return _}let a={app:t,root:r,rootObj:n,paints:o,stats:{calcs:0,lists:0},resolveDefault:d,collectEl:A,walkScope:p};for(let f of Q)f.begin&&f.begin(a);let l=e.cacheReads===!1?null:ze(r);try{R(r,n,b)}finally{e.cacheReads!==!1&&He(l)}if(t.halted)return;for(let f of Q)f.afterIntake&&f.afterIntake(a);if(i.length&&s.size)for(let f of i)s.has(f.attr)&&f.el.getAttribute(f.attr)==null&&f.el.setAttribute(f.attr,f.value);for(let f of Q)f.compute&&f.compute(a);let g=0;for(let f of Q)f.reconcile&&(g+=f.reconcile(a));let v=0,T=g;for(let f of o){let S=gr(f,t);f.ctx.view?T+=S:v+=S}for(let f of Q)f.afterPaint&&f.afterPaint(a);t._state=n,t._stats={fields:Object.keys(n).filter(f=>typeof n[f]!="function").length,calcs:a.stats.calcs,paints:o.length,lists:a.stats.lists,writes:v,viewWrites:T},t._viewsChanged=T>0,t._lastPass={trigger:e.trigger||"refresh",writes:v},t._debug&&console.log(`sap pass \xB7 trigger: ${t._lastPass.trigger} \xB7 writes ${v}/${o.length}`)}function br(t){return t.kind==="text"?t.fmt?"text:"+t.fmt:"text":t.kind==="attr"?"attr:"+t.arg:t.kind==="class"?"class:"+t.arg:t.kind==="css"?"css:"+t.arg:t.kind==="when"?(t.match==="hide"?"hide-when:":t.match==="show-not"?"option-not:":"show-when:")+t.field:t.kind}function fe(t,e,r,n){let o=t;for(;o&&o.nodeType===1;){if(o.hasAttribute&&o.hasAttribute(e)){let i=r.includes(o.getAttribute(e));if(n?!i:i)return!0}o=o.parentElement}return!1}function gr(t,e){let r=t.def,n=t.el,o=cn[r.kind];if(o)return o(t,e);if(r.kind==="when")return an(r,n,null);try{let i=z(r.entry,t.ctx.state,t.ctx.item,n,t.ctx.root),s=an(r,n,i);return ct(n),s}catch(i){return e.diag.error(i.sapCode==="E22"?"E22":"E24",n,{attr:br(r),expr:r.entry&&r.entry.src,problem:String(i.message)}),V(n,i.sapCode||"E24"),0}}function an(t,e,r){switch(t.kind){case"text":{let n=t.fmt!=null?Te(t.fmt,r):r==null?"":String(r);return e.textContent!==n?(e.textContent=n,1):0}case"show":{let n=!r;return e.hidden!==n?(e.hidden=n,1):0}case"when":{let n=O("optionVisibility");if(n&&n._started)return e._sapWhen&&e.hidden?(e.hidden=!1,e._sapWhen=!1,1):0;let o;t.match==="hide"?o=!fe(e,t.field,t.values,!1):t.match==="show-not"?o=fe(e,t.field,t.values,!0):o=fe(e,t.field,t.values,!1),e._sapWhen=!0;let i=!o;return e.hidden!==i?(e.hidden=i,1):0}case"attr":{let n=t.arg;if((n==="checked"||n==="selected")&&typeof e[n]=="boolean"&&!e.hasAttribute("bind")&&!e.closest("select[bind]")){let i=0;return e[n]!==!!r&&(e[n]=!!r,i=1),!!r!==e.hasAttribute(n)&&(r?e.setAttribute(n,""):e.removeAttribute(n),i=1),i}if(mr.has(n)){let i=e.hasAttribute(n);return r&&!i?(e.setAttribute(n,""),1):!r&&i?(e.removeAttribute(n),1):0}let o=typeof r=="boolean"?String(r):r==null?"":String(r);return e.getAttribute(n)!==o?(e.setAttribute(n,o),1):0}case"class":{let n=!!r;return e.classList.contains(t.arg)!==n?(e.classList.toggle(t.arg,n),1):0}case"css":{let n=r==null?"":String(r);return e.style.getPropertyValue("--"+t.arg)!==n?(e.style.setProperty("--"+t.arg,n),1):0}default:return 0}}var wr=new Set(ut),ln=new Set(["calc","text","attr","class","css","set","move","sort","option","option-not","show-when","hide-when","editmode","viewmode"]),yr=new Set(["show-when","hide-when","option","option-not"]),Ar=/\b(?:state|item|root)\.|===|!==|&&|\|\||[()]|^\s*!/,dn=new Set(["sap","scope","items","item","template","bind","show","effect","invalid","detail","state","transient","confirm","default","persist","sortable","trigger-add","trigger-remove","trigger-reset","sap-ignore","sap-error","no-save","no-watch","no-undo","no-trigger-autosave","freeze","mutations-ignore","save-remove","save-ignore","save-freeze"]),de=[];function pn(t){de.includes(t)||de.push(t)}function vr(t){return t.tagName==="INPUT"||t.tagName==="SELECT"||t.tagName==="TEXTAREA"}function le(t){return t.hasAttribute("bind")}function Er(t,e){e(t);for(let n=t.firstElementChild;n;n=n.nextElementSibling)r(n);function r(n){if(!n.hasAttribute("sap-ignore")){if(n.tagName==="TEMPLATE"){if(n.hasAttribute("items"))for(let o=n.content.firstElementChild;o;o=o.nextElementSibling)r(o);return}e(n);for(let o=n.firstElementChild;o;o=o.nextElementSibling)r(o)}}}function Yt(t,e){let r=!1,n=(s,b,m)=>{e.error(s,b,m),r=!0},o=t.ownerDocument.createTreeWalker(t,4),i;for(;i=o.nextNode();)if(/\{\{.*\}\}/.test(i.nodeValue||"")){n("E02",i.parentElement||t,{problem:"moustaches in text content are not a Sap feature",fix:'move the expression onto the element: text="state.x"'});break}return Er(t,s=>{let b=new Set;for(let d of de)d(s,n,u=>b.add(u));let m=s.closest&&s.closest("[detail]");for(let d of[...s.attributes]){let u=d.name;if(b.has(u))continue;if(u.includes(":")){let A=u.slice(0,u.indexOf(":"));if(ln.has(A)){if(yr.has(A)&&Ar.test(d.value)){let N=u.slice(u.indexOf(":")+1);e.warn("W04",s,{attr:u,expr:d.value,problem:`${A}: compares the "${N}" attribute against a literal value, not a JS expression`,fix:`use show="${d.value}" for an expression, or a literal like ${A}:${N}="overview"`})}}else{let N=wt(A,[...ln]);e.warn("W03",s,{attr:u,problem:`unknown "${A}:" attribute`,didYouMean:N?`${N}:`:null})}}else if(!dn.has(u)&&!gt.has(u)&&!wr.has(u)&&!/^(data-|aria-|on)/.test(u)&&!(u in s)){let A=wt(u,[...dn]);A&&e.warn("W03",s,{attr:u,problem:`unknown "${u}" attribute`,didYouMean:A})}u==="attr:hidden"&&e.warn("W03",s,{attr:u,problem:"attr:hidden paints the wrong attribute",fix:'use show="expr"'});let E=le(s)||u==="attr:selected"&&s.tagName==="OPTION"&&!!s.closest("select[bind]");(u==="attr:value"||u==="attr:checked"||u==="attr:selected")&&E&&n("E30",s,{attr:u,problem:"attr: on a bound control collides with persist ownership",fix:"remove it; bind owns this attribute"}),u==="effect"&&le(s)&&/\b(value|checked)\s*=[^=]/.test(d.value)&&n("E30",s,{attr:u,expr:d.value,problem:"effect writes value/checked on a bound control (writes a stale value with no synthetic event)",fix:"write through onclick + Sap(this) instead"}),(u==="text"||u.startsWith("text:")||u==="show")&&vr(s)&&(u==="show"||n("E18",s,{attr:u,problem:"paint belongs on output elements, not form controls",fix:"move the paint to an <output> or <span>"}))}if(s.hasAttribute("state")){let d=W(s.getAttribute("state")),u=new Set;for(let E of d){E.name.includes("-")&&n("E08",s,{attr:"state",problem:`field "${E.name}" is not a valid identifier (the hyphen parses as subtraction)`,fix:`rename to ${E.name.replace(/-/g,"")}`}),u.has(E.name)&&n("E04",s,{attr:"state",problem:`field "${E.name}" is declared twice in one scope`}),u.add(E.name),Nt.has(E.attr)&&n("E05",s,{attr:"state",problem:`"${E.name}" is a reserved Sap word`}),gt.has(E.attr)&&n("E06",s,{attr:"state",problem:`"${E.name}" is a global HTML attribute name; pick another field name`}),E.name==="open"&&s.tagName==="DIALOG"&&n("E33",s,{attr:"state",problem:"dialog open is transient",fix:"use showModal() \u2014 declare state= only on <details> or popovers"});let A=ne(s,E.attr);A&&(E.attr==="checked"||E.attr==="selected")&&n("E35",s,{attr:"state",problem:`"${E.attr}" on a form control is the control's own state, not a declared field`,fix:'bind the control instead, e.g. <input type="checkbox" bind="done">'}),A&&E.type==="num"&&n("E35",s,{attr:"state",problem:`"${E.attr}" is an HTML boolean attribute; it cannot hold a number`,fix:`declare it bare: state="${E.attr}"`}),E.transient&&(A||E.type==="presence")&&n("E35",s,{attr:"state",problem:`"${E.name}" is carried by attribute presence, which transient would strip`,fix:"declare a separate name:bool:transient field and paint the attribute from it"})}}if(le(s)){if(s.hasAttribute("-"),s.tagName==="INPUT"){let d=(s.getAttribute("type")||"text").toLowerCase();d==="file"&&n("E32",s,{attr:"bind",problem:"files never serialize into an HTML file",fix:"use no-save + effect instead of bind"}),d==="password"&&!s.hasAttribute("transient")&&n("E31",s,{attr:"bind",problem:"a password must never serialize into a world-readable file",fix:"add transient to the password input"})}else if(s.tagName!=="SELECT"&&s.tagName!=="TEXTAREA"){let d=s.getAttribute("contenteditable");!(d!=null&&d!=="false")&&s.children.length>0&&n("E20",s,{attr:"bind",problem:"bind on a container element is not a control; a write would overwrite its children",fix:"bind a control (input/select/textarea), a contenteditable, or an empty text leaf"})}}if(s.hasAttribute("transient")&&s.hasAttribute("persist")&&n("E34",s,{problem:"transient and persist are opposite: persist forces the live value into the saved bytes, leaking exactly what transient drops",fix:"remove one \u2014 transient to keep it out of the file, or persist to save it"}),s.tagName==="DIALOG"&&s.hasAttribute("detail")&&!(s.parentElement&&s.parentElement.closest('[clay~="freeze"], [freeze], [save-freeze]'))&&e.warn("W31",s,{attr:"detail",problem:"a detail dialog writes open when it opens, and that attribute would be saved into the file",fix:'wrap the dialog in an element with clay="freeze" (not editor-ui, which removes it from the file), and make its key field transient'}),s.hasAttribute("item")&&!s.hasAttribute("template")&&s.parentNode&&s.parentNode.nodeType===1){let d=s.parentElement;(!d||!d.hasAttribute("items"))&&n("E10",s,{problem:"an [item] must be a direct child of an [items] list",fix:'wrap it in a container with items="name"'})}if(s.hasAttribute("items")&&m&&n("E17",s,{attr:"items",problem:"nested items inside a detail panel is a v1 mount error (nested collections ship in v1.1)"}),s.hasAttribute("items")){let d=t.querySelector(`[trigger-add="${s.getAttribute("items")}"]`);!Ft(s)&&!te(t,s.getAttribute("items"))&&G(s).length===0&&d&&n("E17",s,{attr:"items",problem:`trigger-add targets items="${s.getAttribute("items")}" but it has no [item template] to clone`})}}),r&&(e.halted=!0,e.haltReason=e.errors[0]?e.errors[0].code:"halt",V(t,e.haltReason)),!r}var mn="sap-styles",hn="[item][template]{display:none!important}[hidden]{display:none!important}[sap-error]{outline:2px solid #e5484d;outline-offset:1px}",pe=new WeakSet;function xr(t){if(pe.has(t))return;let e=t.defaultView,r=e&&e.CSSStyleSheet;if(r&&"adoptedStyleSheets"in t)try{let n=new r;n.replaceSync(hn),t.adoptedStyleSheets=[...t.adoptedStyleSheets,n],pe.add(t);return}catch{}if(!t.getElementById(mn)){let n=t.createElement("style");n.id=mn,n.textContent=hn,(t.head||t.documentElement).appendChild(n)}pe.add(t)}var Sr=0;function bn(){return typeof performance<"u"&&performance.now?performance.now():0}function me(t){let e=t.id||t.getAttribute("sap")||`app-${Sr++}`,r=new at(e),n={root:t,name:e,diag:r,_state:null,_stats:null,_lastPass:null,_passes:0,_broken:!1,_mountMs:0,_mountWrites:0};if(!Yt(t,r))return n.halted=!0,n;xr(t.ownerDocument);for(let s of t.querySelectorAll("textarea[data-value]"))qt(s);let i=bn();return bt(n,{trigger:"mount",full:!0}),n._mountMs=bn()-i,n._mountWrites=n._stats?n._stats.writes:0,n._mountWrites>0&&!Ke()&&!O("derived")&&r.warn("W30",t,{problem:`${n._mountWrites} paint(s) ran at mount; the saved file was out of sync with its declared state`,fix:"re-save once so the file mounts clean (a settled file writes nothing)"}),n}var gn=/^(set:|move:|sort:|trigger-add$|trigger-remove$|trigger-reset$)/;function Xt(t){return`${t.tagName.toLowerCase()}[sap]`}function kr(t){let e=0;for(let r of t.querySelectorAll("*"))for(let n of r.attributes)if(gn.test(n.name)){e++;break}for(let r of t.attributes)if(gn.test(r.name)){e++;break}return e}function wn(t){function e(b){let m=b._stats||{},d=b.root;return{root:Xt(d),fields:m.fields||0,calcs:m.calcs||0,paints:m.paints||0,actions:kr(d),lists:(d.hasAttribute("items")?1:0)+d.querySelectorAll("[items]").length,rows:d.querySelectorAll("[item]:not([template])").length,warnings:b.diag.warnings.length,errors:b.diag.errors.length,mountWrites:b._mountWrites||0,ms:Math.round((b._mountMs||0)*10)/10,passes:b._passes||0,lastPass:b._lastPass||null,ok:b.diag.errors.length===0&&!b.halted}}function r(){let b=t.apps().map(e);return{ok:b.every(m=>m.ok),apps:b}}function n(b){let m=e(b);return m.ok?`sap \u2713 ${m.root} \xB7 fields ${m.fields} \xB7 calcs ${m.calcs} \xB7 paints ${m.paints} \xB7 actions ${m.actions} \xB7 lists ${m.lists} \xB7 rows ${m.rows} \xB7 warnings ${m.warnings} \xB7 mount writes ${m.mountWrites} \xB7 ${m.ms}ms`:`sap \u2717 ${m.root} \xB7 errors ${m.errors} \xB7 warnings ${m.warnings} \xB7 ${m.ms}ms`}function o(){for(let b of t.apps()){let m=n(b);b.diag.errors.length||b.halted?console.error(m):console.log(m)}}function i(){let b=[],m=[];for(let d of t.apps())b.push(...d.diag.errors),m.push(...d.diag.warnings);return{ok:b.length===0,errors:b,warnings:m,counts:{errors:b.length,warnings:m.length}}}function s(b){let m=b===void 0?!0:!!b;for(let d of t.apps())d._debug=m;return console.log(`sap debug ${m?"on":"off"} \u2014 per-pass headers will ${m?"":"no longer "}log`),m}return{status:r,report:i,debug:s,greenLine:n,printGreenLines:o,REGISTRY:Zt}}var yn="0.7.0";function An({createAccessor:t,installInput:e,debugExtras:r}){let n=new Map,o=[],i=be(bt);function s(l){let g=l;for(;g;){if(g.nodeType===1&&g.hasAttribute&&g.hasAttribute("sap"))return n.get(g)||null;g=g.parentNode&&g.parentNode.host?g.parentNode.host:g.parentElement}return null}function b(){for(let l=o.length-1;l>=0;l--){let g=o[l];g.root.isConnected||(n.delete(g.root),o.splice(l,1))}}function m(l,g){if(l.moveBefore)try{l.moveBefore(g,null);return}catch{}l.appendChild(g)}function d(l,g){let v=g.parentElement;if(v){if(v.moveBefore)try{v.moveBefore(l,g);return}catch{}v.insertBefore(l,g)}}let u={apps:()=>o.slice(),appFor:s,isRegistered:l=>n.has(l),pruneDisconnected:b,schedule:(l,g)=>i.schedule(l,g),runNow:(l,g)=>i.runNow(l,g),moveInto:m,placeBefore:d,remountIfPresent:()=>x()},E=t(u),A=wn(u),N=r?r(u,A):{},R=!1,p=!1,y=null;function h(){R||(R=!0,e(u,E,document),y=tn(u))}function w(){let l=O("derived");l&&typeof l.mounted=="function"&&l.mounted()}function x(l=document){if(p)return[];h(),ue(u);let g=l.querySelectorAll("[sap]"),v=[];for(let T of g){if(n.has(T))continue;let f=me(T);n.set(T,f),o.push(f),v.push(f)}for(let T of v){let f=A.greenLine(T);T.diag.errors.length||T.halted?console.error(f):console.log(f)}return w(),v}function c(l){if(p)return null;if(h(),ue(u),!l)return x();let g=typeof l=="string"?document.querySelector(l):l;if(!g)return null;if(n.has(g))return n.get(g);let v=me(g);n.set(g,v),o.push(v);let T=A.greenLine(v);return v.diag.errors.length||v.halted?console.error(T):console.log(T),v}let a=E.Sap;return a.version=yn,a.refresh=function(){for(let g of o)g.root.isConnected&&i.runNow(g,"refresh")},a.batch=Ze,a.status=A.status,a.report=A.report,a.why=N.why,a.debug=A.debug,a.doctor=N.doctor,a.greenLine=A.greenLine,a.formats=dt,a.serializeControlToAttributes=mt,a.finalizeControlForSave=Xe,a.rehydrateControlFromAttributes=qt,a.mount=c,a.config=function(g={}){return g.formats&&Object.assign(dt,g.formats),a},a._registry=n,a._reset=function(){n.clear(),o.length=0,ce()},a.unmount=function(){p=!0,n.clear(),o.length=0,ce(),typeof y=="function"&&y()},{Sap:a,mountAll:x,mount:c,runtime:u}}function vn(t){if(typeof document>"u")return;let e=()=>Je(()=>t());document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e()}var $r=["for","form","list","headers","popovertarget","commandfor","anchor","aria-activedescendant","aria-controls","aria-describedby","aria-details","aria-errormessage","aria-flowto","aria-labelledby","aria-owns"];function _r(t,e){let r=null;return H(t,n=>{!r&&n.getAttribute("scope")===e&&(r=n)}),r}function En(t,e,r){let n=j(t)||e;for(;n;){for(let o of W(n.getAttribute("state")||""))if(o.name===r)return{el:n,decl:o};if(n.hasAttribute("sap"))break;n=j(n.parentElement)}return null}function Tr(t){return typeof t=="number"?"num":typeof t=="boolean"?"bool":"string"}function xn(t){function e(p){let y=t.appFor(p);if(!y)return null;let h=tt(p),w=h&&h._sapEachItem&&h._sapEachItem.$el;if(w&&w.isConnected)return{ctxEl:w,appRec:y,isRow:!0};let x=yt(p);if(x)return x._sapDetailRow?{ctxEl:x._sapDetailRow,appRec:y,isRow:!0}:{ctxEl:j(x.parentElement)||y.root,appRec:y,isRow:!1};let c=Ct(p);if(c&&c.hasAttribute("item"))return{ctxEl:c,appRec:y,isRow:!0};let a=j(p)||y.root;return{ctxEl:a,appRec:y,isRow:a.hasAttribute("item")}}function r(p){let y=typeof p=="string"?document.querySelector(p):p;if(!y||y.nodeType!==1)return null;let h=e(y);return h?R(h.ctxEl,h.appRec,h.isRow):null}function n(p,y){let h=tt(p);if(!h)return r(p);let w=t.appFor(p),x=h._sapEachItem&&h._sapEachItem.$el;if(x&&x.nodeType===1&&x.hasAttribute("item")&<(x,y))return x.isConnected?R(x,w,!0):null;let c=h.parentElement&&h.parentElement._sapDrawnEl;return!c||!c.isConnected?null:R(c,w,c.hasAttribute("item"))}function o(p,y,h){let w=et(p,h);if(w)return B(w).read();let x=ft(p,h);if(x)return G(x).map(g=>R(g,y,!0));let c=_r(p,h);if(c)return R(c,y,!1);let a=En(p,y.root,h);if(a)return a.decl.transient?Mt(a.el,a.decl):Ae(a.el,a.decl);let l=p._sapScope;return l?l[h]:void 0}function i(p,y,h,w,x){w.transient?Et(p,w,h):vt(p,w,h),t.schedule(x,"set:"+y)}function s(p,y){let h=new Set,w=j(p)||y;for(;w;){for(let x of W(w.getAttribute("state")||""))h.add(x.name);if(w.hasAttribute("sap"))break;w=j(w.parentElement)}return H(p,x=>{let c=x.getAttribute("bind");c&&h.add(c)}),h}function b(p,y,h,w){let x=et(p,h);if(x){if(!F(x))return;B(x).write(w);return}let c=p;for(;c;){for(let k of c.attributes)if(k.name==="calc:"+h){y.diag.error("E16",c,{attr:"calc:"+h,problem:`"${h}" is a computed field; computed fields are read-only`});return}if(c.hasAttribute("sap"))break;c=c.parentElement}let a=En(p,y.root,h);if(a){if(!F(a.el,{transient:a.decl.transient}))return;i(a.el,h,w,a.decl,y);return}let l=s(p,y.root);l.delete(h);let g=h.length>=4?wt(h,[...l]):null;if(g){y.diag.error("E12",p,{key:h,problem:`unknown state key "${h}"`,didYouMean:g});return}if(Nt.has(h)||gt.has(h)){y.diag.error("E15",p,{key:h,problem:`cannot write undeclared field "${h}" \u2014 it is a reserved/global name and cannot become state`,fix:"pick a different field name, or declare it explicitly in a state= attribute"});return}let v=y.root;if(!F(v))return;let T=Tr(w),f=v.getAttribute("state")||"",S=T==="string"?h:`${h}:${T}`;v.setAttribute("state",f?`${f} ${S}`:S),i(v,h,w,{name:h,attr:h,type:T,transient:!1},y)}function m(p){let y=p.ownerDocument,h=new Map,w=(x,c)=>{let a=we(y),l=x.getAttribute(c);l&&c==="id"&&h.set(l,a),x.setAttribute(c,a)};p.querySelectorAll("[id]").forEach(x=>w(x,"id")),p.querySelectorAll("[data-id]").forEach(x=>w(x,"data-id")),p.querySelectorAll("[sap-error]").forEach(x=>x.removeAttribute("sap-error")),p.removeAttribute("sap-error"),p.hasAttribute("data-id")?(p.removeAttribute("id"),w(p,"data-id")):w(p,"id");for(let x of[p,...p.querySelectorAll("*")])for(let c of $r){let a=x.getAttribute(c);if(a==null)continue;let l=a.split(/\s+/).map(g=>h.get(g)||g).join(" ");l!==a&&x.setAttribute(c,l)}}function d(p,y,h){let w=xt(y.root,p,h);if(!w)return y.diag.error("E17",p,{problem:`cannot resolve a list named "${h}" from here`}),null;if(!F(w))return null;let x=Ft(w);if(!x)return y.diag.error("E17",w,{problem:`items="${h}" has no [item template] to clone`}),null;let c=w.ownerDocument.importNode(x,!0);return c.removeAttribute("template"),m(c),w.appendChild(c),t.schedule(y,"trigger-add:"+h),R(c,y,!0)}function u(p,y){let h=W(p.getAttribute("state")||""),w=!0;H(p,x=>{x.hasAttribute("bind")&&!F(x)&&(w=!1)});for(let x of h)F(p,{transient:x.transient})||(w=!1);if(w){H(p,x=>{if(x.hasAttribute("bind")){let c=B(x),a=x.getAttribute("default");c.kind==="checkbox"||c.kind==="radio"?c.write(a!=null?a===""||a==="true"||x.value===a:x.hasAttribute("checked")):c.write(a??(x.getAttribute("value")||""))}});for(let x of h){let c=ve(p,x);x.transient?Et(p,x,c):vt(p,x,c)}t.schedule(y,"trigger-reset")}}function E(p,y){if(!p.isConnected)throw new Error("stale row handle: $remove() on a removed row");F(p)&&(p.remove(),t.schedule(y,"trigger-remove"))}function A(p,y,h){if(!p.isConnected)throw new Error("stale row handle: $move() on a removed row");let w=null;if(h&&h.nodeType===1?w=h:typeof h=="string"&&(w=xt(y.root,p,h)),!w){y.diag.error("E17",p,{problem:`$move() cannot resolve target "${h}"`});return}!F(p)||!F(w)||(t.moveInto(w,p),t.schedule(y,"trigger-move"))}function N(p){let y=p.parentElement;return y?G(y).indexOf(p):-1}function R(p,y,h){let w={get $el(){return p},get $key(){return Lt(p,h?"row":"scope")},get $index(){return N(p)},$add(c){return d(p,y,c)},$reset(){return u(p,y),x},$remove(){E(p,y)},$move(c){A(p,y,c)},get $appRec(){return y}},x=new Proxy(w,{get(c,a){return typeof a=="symbol"||a[0]==="$"?c[a]:o(p,y,a)},set(c,a,l){return typeof a=="string"&&a[0]==="$"?(c[a]=l,!0):(b(p,y,a,l),!0)},has(c,a){return typeof a=="string"&&a[0]==="$"?a in c:o(p,y,a)!==void 0}});return x}return{Sap:r,contextElFor:e,readField:o,writeField:b,makeProxy:R,writeTargetFor:n}}var Nr=["trigger-add","trigger-remove","trigger-reset"];function Rr(t){if(t.nodeType!==1)return!1;for(let e of t.attributes){let r=e.name;if(r.startsWith("set:")||r.startsWith("move:")||r.startsWith("sort:")||Nr.includes(r))return!0}return!1}function Lr(t,e){let r=t,n=e.parentElement;for(;r&&r!==n;){if(r.nodeType===1&&Rr(r)&&!(r.tagName==="FORM"&&r.hasAttribute("trigger-add")))return r;r=r.parentElement}return null}function Sn(t,e){let{Sap:r}=e;function n(c,a){let l=null,g=tt(c),v=yt(c);if(g)l=g._sapEachItem??null;else if(v&&v._sapDetailRow)l=v._sapDetailRow._sapScope||null;else{let S=Ct(c);S&&S.hasAttribute("item")&&(l=S._sapScope||null)}return{state:(j(c)||a.root)._sapScope||a._state||{},item:l,el:c,root:a._state||{}}}function o(c,a,l){if(!c.hasAttribute("confirm")){l();return}let g=c.getAttribute("confirm"),v=g,T=P(g);if(!T.error)try{let _=nt(T,n(c,a));(typeof _=="string"||typeof _=="number")&&(v=String(_))}catch{}let f=$t(),S=()=>{$t()===f&&l()},k=Qe();if(!k){window.confirm(v)&&S();return}if(c._sapGatePending)return;c._sapGatePending=!0;let $=()=>{c._sapGatePending=!1};k(v,()=>{$(),S()}).catch($)}function i(c,a){for(let l of c.attributes){if(!l.name.startsWith("set:"))continue;let g=l.name.slice(4),v=P(l.value);if(v.error){a.diag.error("E08",c,{attr:l.name,expr:l.value,problem:String(v.error.message)});continue}let T;try{T=nt(v,n(c,a))}catch(S){a.diag.error("E24",c,{attr:l.name,expr:l.value,problem:String(S.message)});continue}let f=e.writeTargetFor(c,g);f&&(f[g]=T)}}function s(c){let a=tt(c);if(!a)return c.closest("[item]");let l=a._sapEachItem&&a._sapEachItem.$el;return l&&l.nodeType===1&&l.hasAttribute("item")?l:null}function b(c,a){let l=s(c);if(!l||!F(l)||!F(l.parentElement))return;let g=G(l.parentElement),v=g.indexOf(l);a==="up"&&v>0?t.placeBefore(l,g[v-1]):a==="down"&&v<g.length-1&&t.placeBefore(g[v+1],l)}function m(c,a,l){if(a)return xt(l.root,c,a);let g=c;for(;g;){if(g.hasAttribute&&g.hasAttribute("items"))return g;g=g.parentElement}let v=j(c)||l.root,T=[];return H(v,f=>{f.hasAttribute("items")&&T.push(f)}),T[0]||null}function d(c,a){let l=c==null||c==="",g=a==null||a==="";if(l&&g)return 0;if(l)return 1;if(g)return-1;let v=Number(c),T=Number(a);return!Number.isNaN(v)&&!Number.isNaN(T)?v-T:String(c)<String(a)?-1:String(c)>String(a)?1:0}function u(c,a,l,g){let v=m(c,l,g);if(!v){g.diag.error("E17",c,{attr:"sort:"+a,problem:`no items list resolvable for sort:${a}`});return}if(!F(v))return;let T=G(v),f=_=>_._sapScope?_._sapScope[a]:void 0,S=[...T].sort((_,L)=>d(f(_),f(L))),$=S.every((_,L)=>_===T[L])?[...S].reverse():S;for(let _ of $)t.moveInto(v,_);t.schedule(g,"sort:"+a)}function E(c){if(!c||c.hidden)return;let a=c.querySelector("[bind]:not([type=hidden]), [contenteditable]");a&&typeof a.focus=="function"&&a.focus()}function A(c,a){o(c,a,()=>{let l=r(c);for(let g of[...c.attributes]){let v=g.name;if(v==="trigger-remove")l&&l.$remove();else if(v==="trigger-reset")l&&l.$reset();else if(v==="trigger-add"){let T=l&&l.$add(g.value);T&&E(T.$el)}else v==="move:up"?(b(c,"up"),t.schedule(a,"move:up")):v==="move:down"?(b(c,"down"),t.schedule(a,"move:down")):v.startsWith("move:to")?l&&l.$move(g.value):v.startsWith("sort:")&&u(c,v.slice(5),g.value,a)}[...c.attributes].some(g=>g.name.startsWith("set:"))&&i(c,a)})}function N(c){let a=c.target;if(!a||a.nodeType!==1)return;let l=t.appFor(a);if(!l)return;let g=Lr(a,l.root);g&&A(g,l)}function R(c){let a=B(c),l=c.getAttribute("default");a.kind==="checkbox"?a.write(l===""||l==="true"):a.write(l??"")}function p(c,a,l){let g=r(c);if(!g)return;let v=g.$add(l);if(!v)return;let T=[];H(c,f=>{f.hasAttribute("bind")&&T.push(f)});for(let f of T){if(f.type==="radio"&&!f.checked)continue;let S=f.getAttribute("bind"),k=et(v.$el,S);k?B(k).write(B(f).read()):lt(v.$el,S)&&(v[S]=B(f).read())}T.forEach(R),T.length?typeof T[0].focus=="function"&&T[0].focus():E(v.$el)}function y(c){let a=c.target;if(!a||!a.hasAttribute||!a.hasAttribute("trigger-add"))return;let l=t.appFor(a);l&&(c.preventDefault(),o(a,l,()=>p(a,l,a.getAttribute("trigger-add"))))}function h(c){let a=c.target;if(!a||a.tagName!=="DIALOG"||!a.hasAttribute("detail"))return;if(a._sapEngineClose){a._sapEngineClose=!1;return}if(a.open)return;let l=/^[\w.]+\s+by\s+state\.(\w+)\s*$/.exec(a.getAttribute("detail")||""),g=t.appFor(a);if(!l||!g)return;let v=W(a.getAttribute("state")||"").find(f=>f.name===l[1]);if(v){if(!F(a,{transient:v.transient}))return;v.transient?Et(a,v,""):vt(a,v,""),t.schedule(g,"close");return}let T=r(a.parentElement);T&&T[l[1]]!==""&&(T[l[1]]="")}function w(c,a){let l=c.hasAttribute("bind")&&Dt(c);if(!l&&c.hasAttribute("bind")&&tt(c)){let v=c.getAttribute("bind"),T=c._sapViewBind?e.writeTargetFor(c,v):null;return T&&(T[v]=B(c).read()),!0}let g=yt(c);if(g&&g._sapDetailRow&&c.hasAttribute("bind")&&!l){let v=g._sapDetailRow,T=c.getAttribute("bind"),f=et(v,T);if(f&&f!==c)return F(f)&&B(f).write(B(c).read()),!0;if(!f&&W(v.getAttribute("state")||"").some(S=>S.name===T))return e.writeField(v,a,T,B(c).read()),!0}return!1}function x(c=document){c.addEventListener("click",N),c.addEventListener("submit",y),c.addEventListener("close",h,!0)}return{install:x,routeInput:w}}function kn(t){let e=[];function r(m){let d=m.target;if(!d||d.nodeType!==1)return;let u=t.appFor(d);if(u){d.hasAttribute("persist")&&!zt(d)&&F(d)&&mt(d);for(let E of e)if(E(d,u))return;t.schedule(u,m.type+" "+(d.id||d.tagName.toLowerCase()))}}function n(m){let d=m.target,u=t.appFor(d);u&&[...d.querySelectorAll("[bind]")].every(E=>F(E))&&setTimeout(()=>{d.querySelectorAll("[bind]").forEach(E=>{E.dispatchEvent(new Event("input",{bubbles:!0})),E.dispatchEvent(new Event("change",{bubbles:!0}))}),t.schedule(u,"reset")},0)}function o(m){let d=t.appFor(m.target);d&&t.schedule(d,"toggle")}function i(m){let d=m.detail||{};for(let u of[d.from,d.to,m.target]){if(!u||u.nodeType!==1)continue;let E=t.appFor(u);E&&t.schedule(E,"sorted")}}function s(m){if(m.key!=="ArrowUp"&&m.key!=="ArrowDown")return;let d=m.target;if(!d||d.nodeType!==1||d.tagName!=="INPUT"||!d.hasAttribute("bind")||!d.hasAttribute("step"))return;let u=(d.getAttribute("type")||"text").toLowerCase();if(u!=="text"&&u!=="tel"&&u!=="search"||!t.appFor(d)||!F(d))return;m.preventDefault();let A=q(d.getAttribute("step"))||1,N=m.key==="ArrowUp"?1:-1,R=q(d.value)+A*(m.shiftKey?10:1)*N,p=d.getAttribute("min"),y=d.getAttribute("max");p!==null&&p!==""&&R<q(p)&&(R=q(p)),y!==null&&y!==""&&R>q(y)&&(R=q(y)),B(d).write(String(Number(R.toFixed(2))))}function b(m=document){m.addEventListener("reset",n),m.addEventListener("toggle",o,!0),m.addEventListener("input",r),m.addEventListener("change",r),m.addEventListener("clay:sorted",i),m.addEventListener("keydown",s)}return{install:b,addRouter:m=>e.push(m)}}function $n(t){let e=t.toLowerCase();return/^x-text$|^x-html$/.test(e)?'use text="state.x" (Sap paints text only)':/^x-show$|^v-show$|^v-if$/.test(e)?'use show="expr" (toggles native hidden)':/^x-model$|^v-model$/.test(e)?'use bind="field"':/^@|^x-on:|^v-on:|^on:/.test(e)?"use native onclick + Sap(this) (no event directive)":/^:|^x-bind:class$|^v-bind:class$/.test(e)?'use class:NAME="expr" or attr:NAME="expr"':/^x-for$|^v-for$/.test(e)?'use items="name" on the container and item template on the row':/^x-data$/.test(e)?"declare state with state= / bind / items (no JS state object)":/^x-init$/.test(e)?"use a <script> or onclick + Sap(this)":/^bind:/.test(e)?'use bind="field"; one-way paint is attr:NAME="expr"':/^x-/.test(e)||/^v-/.test(e)?"this is a foreign-dialect attribute; Sap has no x-/v- attributes":null}function _n(t){let e=[],r=n=>{for(let o of n.attributes){let i=o.name;(i.startsWith("calc:")||i==="text"||i.startsWith("text:")||i==="show"||i.startsWith("attr:")||i.startsWith("class:")||i.startsWith("css:")||i==="effect"||i==="invalid"||i.startsWith("set:")||i==="detail")&&e.push({el:n,attr:i,src:o.value})}};r(t);for(let n of t.querySelectorAll("*"))r(n);return e}function Tn(t){function e(o){return o?typeof o=="string"?document.querySelector(o):o.nodeType===1?o:null:null}function r(o,i){let s=e(o);if(!s)return console.warn("sap why: element not found"),null;let b=[`sap why <${s.tagName.toLowerCase()}> \u2014 ${Rt(s)}`],m=[...s.attributes].filter(u=>/^(bind|text|show|effect|invalid|detail|calc:|text:|attr:|class:|css:|set:|state|items|scope)/.test(u.name));for(let u of m)b.push(` ${u.name}="${u.value}"`);let d=s;for(;d&&!d._sapScope;)d=d.parentElement;if(d&&d._sapScope){let u=d._sapScope,E=i?[i]:Object.keys(u);b.push(" reads:");for(let A of E){let N=u[A];typeof N!="function"&&b.push(` ${A} = ${JSON.stringify(Array.isArray(N)?`[${N.length} rows]`:N)}`)}}return b.push(" serialization: textContent and value/checked attributes save with the file; reads live from properties"),console.log(b.join(`
|
|
9
|
+
`+e.value:e.value;t.textContent!==n&&(t.textContent=n),t.removeAttribute("data-value");return}if(r==="SELECT"){let n=t.options,o=e.options;for(let i=0;i<n.length;i++)o[i]&&o[i].selected?n[i].hasAttribute("selected")||n[i].setAttribute("selected",""):n[i].removeAttribute("selected")}}function qt(t){t.tagName!=="TEXTAREA"||!t.hasAttribute("data-value")||t!==t.ownerDocument.activeElement&&(t.textContent=t.getAttribute("data-value"),t.removeAttribute("data-value"))}function O(t){if(typeof window>"u")return null;let e=window.clay,r=window.hyperclay;return t==="consent"?e?.confirm||r?.consent||null:e?.[t]||r?.[t]||null}function Ke(){let t=O("visitorDrafts");return!!(t&&typeof t.restored=="function"&&t.restored()?.restored)}var ie=["clay:mutation-ready","hyperclay:mutation-ready"],ir=["clay:sync-applied","hyperclay:livesync-applied"],sr=["clay:ready","hyperclay:ready"],ar=["clay:route"],ur=["clay:modechange"];function kt(t,e,r){let n=null,o=i=>{n!==null&&n!==i.type||(n=i.type,queueMicrotask(()=>{n=null}),r(i))};for(let i of e)t.addEventListener(i,o);return()=>{for(let i of e)t.removeEventListener(i,o)}}function Je(t){let e=typeof window<"u"&&window.clay&&window.clay.ready;e&&typeof e.then=="function"?e.then(()=>t(),()=>t()):t()}function zt(t){let e=O("region");return!e||typeof e.resolveRegionPolicy!="function"||typeof e.skipForPolicy!="function"?!1:e.skipForPolicy(e.resolveRegionPolicy(t),void 0,["no-save","freeze"])}function $t(){return typeof window>"u"?null:window.clay?.modeLifecycle||null}function F(t,{transient:e=!1}={}){if(e)return!0;let r=$t();return typeof r?.canWrite!="function"||O("region")?.resolveRegionPolicy?.(t)?.persist==="none"?!0:r.canWrite()}function Qe(){let t=O("consent");return typeof t=="function"?t:null}function Ze(t,e){if(typeof e!="function")throw new Error("Sap.batch(label, fn): fn must be a function");let r=O("undo");r&&r.flush&&r.flush();let n=e();if(n&&typeof n.then=="function")throw new Error("Sap.batch fn must be synchronous (it returned a promise)");return r&&r.commitCaptured&&r.commitCaptured(t),n}function tn(t){if(typeof window>"u"||typeof document>"u")return;let e=()=>{let A=!1;for(let N of t.apps())N.root.isConnected?t.runNow(N,"platform"):A=!0;A&&t.pruneDisconnected(),t.remountIfPresent()},r=O("derived"),n=r&&typeof r.register=="function"?r.register(e):null,o=typeof n=="function"?null:kt(document,ir,e),i=kt(document,ar,e),s=null,b=!1,m=()=>{let A=s;s=null,A&&(A[2](),A[3]())},d=()=>{if(b)return!1;let A=O("undo"),N=$t()?.state?.generation;if(s&&s[0]===A&&s[1]===N)return!0;if(m(),!A||typeof A.on!="function")return!1;let R=A.on("undo",e);if(typeof R!="function")return!1;let p=A.on("redo",e);return typeof p!="function"?(R(),!1):(s=[A,N,R,p],!0)};d();let u=[ie,sr,ur].map(A=>kt(document,A,d)),E=O("ready");return E&&typeof E.then=="function"&&E.then(d,()=>{}),()=>{b=!0,typeof n=="function"&&n(),o&&o(),i();for(let A of u)A();m()}}function _t(t){let e=t.tagName;if(e==="INPUT"){let r=(t.getAttribute("type")||"text").toLowerCase();return r==="checkbox"?"checkbox":r==="radio"?"radio":r==="number"||r==="range"?"number":r==="hidden"?"hidden":"text"}return e==="TEXTAREA"?"text":e==="SELECT"?t.multiple?"select-multiple":"select-one":"leaf"}function cr(t){if(t.validity&&t.validity.badInput)return t.hasAttribute("value")?Number(t.getAttribute("value"))||0:t._sapLastGood??0;if(t.value==="")return 0;let e=Number(t.value);return Number.isNaN(e)?t._sapLastGood??0:(t._sapLastGood=e,e)}function en(t,e){switch(e){case"checkbox":return t.checked;case"radio":return t.checked?t.value:void 0;case"number":return cr(t);case"select-one":return t.value;case"select-multiple":return[...t.selectedOptions].map(r=>r.value);case"hidden":case"text":return t.value;case"leaf":return t.textContent;default:return t.value}}function nn(t,e,r){switch(e){case"checkbox":t.checked=!!r;break;case"radio":t.checked=String(t.value)===String(r);break;case"number":case"text":case"hidden":t.value=r==null?"":String(r);break;case"select-one":t.value=r==null?"":String(r);break;case"select-multiple":{let n=new Set((Array.isArray(r)?r:[r]).map(String));for(let o of t.options)o.selected=n.has(o.value);break}case"leaf":t.textContent=r==null?"":String(r);break;default:t.value=r==null?"":String(r)}}function se(t){if(t.hasAttribute("transient")){t.removeAttribute("value"),t.removeAttribute("checked"),t.removeAttribute("data-value");return}zt(t)||mt(t)}function fr(t){t.dispatchEvent(new Event("input",{bubbles:!0})),t.dispatchEvent(new Event("change",{bubbles:!0}))}function Ht(t,e){return en(t,e)}function rn(t,e,r){nn(t,e,r),se(t)}function B(t){let e=_t(t);return{el:t,kind:e,read(){return en(t,e)},write(r,n={}){nn(t,e,r),n.noMirror||se(t),n.silent||fr(t)},mirror(){se(t)}}}var J=null,Ut=!1,ht=null;function on(t){let e=null;return{kind:"hub",subscribe(r){let n=t.onAnyChange({debounce:0,require:"observed"},r);typeof n=="function"&&(e=n)},suppress(r){t.pause();try{return r()}finally{t.resume()}},teardown(){if(e){try{e()}catch{}e=null}}}}function lr(){let t=null;return{kind:"native",subscribe(e){t=new MutationObserver(n=>e(dr(n)));let r=typeof document<"u"&&document.body||typeof document<"u"&&document.documentElement;r&&t.observe(r,{childList:!0,subtree:!0,attributes:!0,characterData:!0})},suppress(e){let r=O("undo");r&&r.pause&&r.pause();try{return e()}finally{t&&t.takeRecords(),r&&r.resume&&r.resume()}},teardown(){t&&(t.disconnect(),t=null)}}}function dr(t){let e=[];for(let r of t)if(r.type==="attributes"){let n=r.target;n&&n.nodeType===1&&!Vt(n)&&e.push({type:"attribute",element:n})}else if(r.type==="characterData"){let n=r.target&&r.target.parentElement;n&&!Vt(n)&&e.push({type:"characterData",element:n})}else if(r.type==="childList"){for(let n of r.addedNodes)if(!(n.nodeType!==1||Vt(n))&&(e.push({type:"add",element:n}),n.querySelectorAll))for(let o of n.querySelectorAll("*"))Vt(o)||e.push({type:"add",element:o});for(let n of r.removedNodes)n.nodeType===1&&e.push({type:"remove",element:n,parent:r.target})}return e}function Vt(t){return!!(t.closest&&t.closest("[sap-ignore],[template],[cms-template]"))}function pr(t,e){t.pruneDisconnected();let r=new Set,n=!1;for(let o of e){let i=o.type==="remove"?o.parent:o.element,s=i&&t.appFor(i);s&&r.add(s),o.type==="add"&&o.element&&o.element.nodeType===1&&o.element.hasAttribute&&o.element.hasAttribute("sap")&&!(t.isRegistered&&t.isRegistered(o.element))&&(n=!0)}n&&t.remountIfPresent();for(let o of r)o.root.isConnected&&t.schedule(o,"mutation")}function sn(t){if(J)return J.suppress(t);let e=O("undo");if(e&&e.pause&&e.resume){e.pause();try{return t()}finally{e.resume()}}return t()}function ae(t,e){Ut=!0,J=t,t.subscribe(r=>pr(e,r))}function ue(t){if(Ut||typeof window>"u"||typeof document>"u")return;let e=O("Mutation");if(e&&typeof e.onAnyChange=="function"){ae(on(e),t);return}typeof MutationObserver=="function"&&(ae(lr(),t),ht=kt(document,ie,function(){let n=O("Mutation");n&&(ht(),ht=null,J&&J.teardown(),Ut=!1,ae(on(n),t))}))}function ce(){if(J)try{J.teardown()}catch{}ht&&typeof document<"u"&&ht(),J=null,Ut=!1,ht=null}var mr=new Set(ut),Gt=Object.freeze([]),Q=[],un={},cn={};function fn(t){Q.includes(t)||(Q.push(t),t.boundary&&Object.assign(un,t.boundary),t.paintKinds&&Object.assign(cn,t.paintKinds))}function bt(t,e={}){if(e.breaker){t.diag.error("E26",t.root,{problem:"recompute loop halted after 50 passes; recent triggers: "+(t._breakerRing||[]).join(", ")}),V(t.root,"loop");return}e.full&&(Fe(),We());let r=Me(t.root);try{sn(()=>hr(t,e))}finally{Oe(r)}t._viewsChanged&&(t._viewsChanged=!1,t.root.dispatchEvent(new CustomEvent("sap:views-updated",{bubbles:!0})))}function hr(t,e){let r=t.root,n={},o=[],i=[],s=new Set;t.diag.errors=[];let b={root:n,state:n,item:null,ownerEl:r,projection:!1},m=null;function d(f,S,k=!1){let $=S.attr||S.name,_=k?Ue(f,$):f.getAttribute($);return _==null&&(_=At(S),i.push({el:f,name:S.name,attr:$,value:ee(Z(_,S.type),S.type)})),Z(_,S.type)}function u(f,S,k,$){let _=S.decls;if(!_)return;let L=!!$.item&&!$.projection&&!$.view;for(let D of _){if(D.transient){m&&(m.pure=!1),k[D.name]=Mt(f,D);continue}if(Y(f,D)){k[D.name]=f.hasAttribute(D.attr);continue}k[D.name]=d(f,D,L)}}function E(f,S,k){let $=S.bind,_=k.item||k.state,L=_t(f);m&&(L!=="leaf"||S.transient)&&(m.pure=!1),L==="radio"?($ in _||(_[$]=""),f.checked&&(_[$]=f.value)):L==="leaf"&&k.item&&!k.projection&&!k.view?_[$]=Ge(f):_[$]=Ht(f,L),S.transient&&(f.removeAttribute("value"),f.removeAttribute("checked"))}function A(f,S,k){let $=!1;if(S.paints){$=!0;for(let _ of S.paints)_.kind==="when"&&s.add(_.field),o.push({def:_,el:f,ctx:k})}for(let _ of Q)_.collect&&_.collect(a,f,S,k)!==!1&&($=!0);m&&$&&(S.calcs&&(m.pure=!1),m.collects.push(f,S))}function N(f,S,k){Object.defineProperty(f,"$key",{value:Lt(S,"row"),enumerable:!1}),Object.defineProperty(f,"$index",{value:k,enumerable:!1,configurable:!0}),Object.defineProperty(f,"$el",{value:S,enumerable:!1})}function R(f,S,k){let $=X(f);u(f,$,S,k),f._sapScope=S,!k.projection&&$.bind!=null&&E(f,$,k),A(f,$,k),$.items?w(f,S,k):p(f,S,k)}function p(f,S,k){for(let $=f.firstElementChild;$;$=$.nextElementSibling)y($,S,k)}function y(f,S,k){let $=X(f);if(!$.inert){if($.boundary){m&&(m.pure=!1),$.boundary==="scope"?h(f,S,k):$.boundary==="items"?(A(f,$,k),w(f,S,k)):un[$.boundary](a,f,$,S,k);return}!k.projection&&!k.view&&$.bind!=null&&E(f,$,k),A(f,$,k);for(let _=f.firstElementChild;_;_=_.nextElementSibling)y(_,S,k)}}function h(f,S,k){let $=f.getAttribute("scope"),_={};S[$]=_;let L={root:k.root,state:_,item:null,ownerEl:f,projection:k.projection};R(f,_,L)}function w(f,S,k){m&&(m.pure=!1);let $=f.getAttribute("items"),_=[];S[$]=_,f._sapList=_;let L=!k.projection&&!k.view&&Be(),D=0;for(let M=f.firstElementChild;M;M=M.nextElementSibling){let C=X(M);if(!C.item||C.template||C.cms)continue;let I=L?je(M):void 0;_.push(I&&I.plan===C&&Object.isExtensible(I.obj)&&c(I,M,D,k)||x(M,C,D,k,L)),D++}}function x(f,S,k,$,_){let L={};N(L,f,k);let D={root:$.root,state:$.state,item:L,ownerEl:f,projection:$.projection};if(!_)return R(f,L,D),L;let M=m,C={plan:S,obj:L,fields:null,presence:Gt,pending:Gt,collects:[],pure:!0},I=i.length,Wn=t.diag.errors.length;m=C;try{R(f,L,D)}finally{m=M}if(!C.pure||t.halted||t.diag.errors.length!==Wn)return L;let he=[];for(let st of Object.keys(L)){let Jt=L[st];if(Jt!==null&&typeof Jt=="object")return L;he.push(st,Jt)}if(S.decls)for(let st of S.decls)Y(f,st)&&(C.presence===Gt?C.presence=[]:C.presence).push(st.name,st.attr);return i.length>I&&(C.pending=i.slice(I)),C.collects.length||(C.collects=Gt),C.fields=he,qe(f,C),L}function c(f,S,k,$){let _=f.obj;try{_.$index!==k&&Object.defineProperty(_,"$index",{value:k,enumerable:!1,configurable:!0});let M=f.presence;for(let I=0;I<M.length;I+=2)_[M[I]]=S.hasAttribute(M[I+1]);let C=f.fields;for(let I=0;I<C.length;I+=2)_[C[I]]=C[I+1]}catch{return jt(S),null}S._sapScope=_;let L=f.pending;for(let M=0;M<L.length;M++)i.push(L[M]);let D=f.collects;if(D.length){let M={root:$.root,state:$.state,item:_,ownerEl:S,projection:$.projection};for(let C=0;C<D.length;C+=2)A(D[C],D[C+1],M)}return _}let a={app:t,root:r,rootObj:n,paints:o,stats:{calcs:0,lists:0},resolveDefault:d,collectEl:A,walkScope:p};for(let f of Q)f.begin&&f.begin(a);let l=e.cacheReads===!1?null:ze(r);try{R(r,n,b)}finally{e.cacheReads!==!1&&He(l)}if(t.halted)return;for(let f of Q)f.afterIntake&&f.afterIntake(a);if(i.length&&s.size)for(let f of i)s.has(f.attr)&&f.el.getAttribute(f.attr)==null&&f.el.setAttribute(f.attr,f.value);for(let f of Q)f.compute&&f.compute(a);let g=0;for(let f of Q)f.reconcile&&(g+=f.reconcile(a));let v=0,T=g;for(let f of o){let S=gr(f,t);f.ctx.view?T+=S:v+=S}for(let f of Q)f.afterPaint&&f.afterPaint(a);t._state=n,t._stats={fields:Object.keys(n).filter(f=>typeof n[f]!="function").length,calcs:a.stats.calcs,paints:o.length,lists:a.stats.lists,writes:v,viewWrites:T},t._viewsChanged=T>0,t._lastPass={trigger:e.trigger||"refresh",writes:v},t._debug&&console.log(`sap pass \xB7 trigger: ${t._lastPass.trigger} \xB7 writes ${v}/${o.length}`)}function br(t){return t.kind==="text"?t.fmt?"text:"+t.fmt:"text":t.kind==="attr"?"attr:"+t.arg:t.kind==="class"?"class:"+t.arg:t.kind==="css"?"css:"+t.arg:t.kind==="when"?(t.match==="hide"?"hide-when:":t.match==="show-not"?"option-not:":"show-when:")+t.field:t.kind}function fe(t,e,r,n){let o=t;for(;o&&o.nodeType===1;){if(o.hasAttribute&&o.hasAttribute(e)){let i=r.includes(o.getAttribute(e));if(n?!i:i)return!0}o=o.parentElement}return!1}function gr(t,e){let r=t.def,n=t.el,o=cn[r.kind];if(o)return o(t,e);if(r.kind==="when")return an(r,n,null);try{let i=z(r.entry,t.ctx.state,t.ctx.item,n,t.ctx.root),s=an(r,n,i);return ct(n),s}catch(i){return e.diag.error(i.sapCode==="E22"?"E22":"E24",n,{attr:br(r),expr:r.entry&&r.entry.src,problem:String(i.message)}),V(n,i.sapCode||"E24"),0}}function an(t,e,r){switch(t.kind){case"text":{let n=t.fmt!=null?Te(t.fmt,r):r==null?"":String(r);return e.textContent!==n?(e.textContent=n,1):0}case"show":{let n=!r;return e.hidden!==n?(e.hidden=n,1):0}case"when":{let n=O("optionVisibility");if(n&&n._started)return e._sapWhen&&e.hidden?(e.hidden=!1,e._sapWhen=!1,1):0;let o;t.match==="hide"?o=!fe(e,t.field,t.values,!1):t.match==="show-not"?o=fe(e,t.field,t.values,!0):o=fe(e,t.field,t.values,!1),e._sapWhen=!0;let i=!o;return e.hidden!==i?(e.hidden=i,1):0}case"attr":{let n=t.arg;if((n==="checked"||n==="selected")&&typeof e[n]=="boolean"&&!e.hasAttribute("bind")&&!e.closest("select[bind]")){let i=0;return e[n]!==!!r&&(e[n]=!!r,i=1),!!r!==e.hasAttribute(n)&&(r?e.setAttribute(n,""):e.removeAttribute(n),i=1),i}if(mr.has(n)){let i=e.hasAttribute(n);return r&&!i?(e.setAttribute(n,""),1):!r&&i?(e.removeAttribute(n),1):0}let o=typeof r=="boolean"?String(r):r==null?"":String(r);return e.getAttribute(n)!==o?(e.setAttribute(n,o),1):0}case"class":{let n=!!r;return e.classList.contains(t.arg)!==n?(e.classList.toggle(t.arg,n),1):0}case"css":{let n=r==null?"":String(r);return e.style.getPropertyValue("--"+t.arg)!==n?(e.style.setProperty("--"+t.arg,n),1):0}default:return 0}}var wr=new Set(ut),ln=new Set(["calc","text","attr","class","css","set","move","sort","option","option-not","show-when","hide-when","editmode","viewmode"]),yr=new Set(["show-when","hide-when","option","option-not"]),Ar=/\b(?:state|item|root)\.|===|!==|&&|\|\||[()]|^\s*!/,dn=new Set(["sap","scope","items","item","template","bind","show","effect","invalid","detail","state","transient","confirm","default","persist","sortable","trigger-add","trigger-remove","trigger-reset","sap-ignore","sap-error","no-save","no-watch","no-undo","no-trigger-autosave","freeze","mutations-ignore","save-remove","save-ignore","save-freeze"]),de=[];function pn(t){de.includes(t)||de.push(t)}function vr(t){return t.tagName==="INPUT"||t.tagName==="SELECT"||t.tagName==="TEXTAREA"}function le(t){return t.hasAttribute("bind")}function Er(t,e){e(t);for(let n=t.firstElementChild;n;n=n.nextElementSibling)r(n);function r(n){if(!n.hasAttribute("sap-ignore")){if(n.tagName==="TEMPLATE"){if(n.hasAttribute("items"))for(let o=n.content.firstElementChild;o;o=o.nextElementSibling)r(o);return}e(n);for(let o=n.firstElementChild;o;o=o.nextElementSibling)r(o)}}}function Yt(t,e){let r=!1,n=(s,b,m)=>{e.error(s,b,m),r=!0},o=t.ownerDocument.createTreeWalker(t,4),i;for(;i=o.nextNode();)if(/\{\{.*\}\}/.test(i.nodeValue||"")){n("E02",i.parentElement||t,{problem:"moustaches in text content are not a Sap feature",fix:'move the expression onto the element: text="state.x"'});break}return Er(t,s=>{let b=new Set;for(let d of de)d(s,n,u=>b.add(u));let m=s.closest&&s.closest("[detail]");for(let d of[...s.attributes]){let u=d.name;if(b.has(u))continue;if(u.includes(":")){let A=u.slice(0,u.indexOf(":"));if(ln.has(A)){if(yr.has(A)&&Ar.test(d.value)){let N=u.slice(u.indexOf(":")+1);e.warn("W04",s,{attr:u,expr:d.value,problem:`${A}: compares the "${N}" attribute against a literal value, not a JS expression`,fix:`use show="${d.value}" for an expression, or a literal like ${A}:${N}="overview"`})}}else{let N=wt(A,[...ln]);e.warn("W03",s,{attr:u,problem:`unknown "${A}:" attribute`,didYouMean:N?`${N}:`:null})}}else if(!dn.has(u)&&!gt.has(u)&&!wr.has(u)&&!/^(data-|aria-|on)/.test(u)&&!(u in s)){let A=wt(u,[...dn]);A&&e.warn("W03",s,{attr:u,problem:`unknown "${u}" attribute`,didYouMean:A})}u==="attr:hidden"&&e.warn("W03",s,{attr:u,problem:"attr:hidden paints the wrong attribute",fix:'use show="expr"'});let E=le(s)||u==="attr:selected"&&s.tagName==="OPTION"&&!!s.closest("select[bind]");(u==="attr:value"||u==="attr:checked"||u==="attr:selected")&&E&&n("E30",s,{attr:u,problem:"attr: on a bound control collides with persist ownership",fix:"remove it; bind owns this attribute"}),u==="effect"&&le(s)&&/\b(value|checked)\s*=[^=]/.test(d.value)&&n("E30",s,{attr:u,expr:d.value,problem:"effect writes value/checked on a bound control (writes a stale value with no synthetic event)",fix:"write through onclick + Sap(this) instead"}),(u==="text"||u.startsWith("text:")||u==="show")&&vr(s)&&(u==="show"||n("E18",s,{attr:u,problem:"paint belongs on output elements, not form controls",fix:"move the paint to an <output> or <span>"}))}if(s.hasAttribute("state")){let d=W(s.getAttribute("state")),u=new Set;for(let E of d){E.name.includes("-")&&n("E08",s,{attr:"state",problem:`field "${E.name}" is not a valid identifier (the hyphen parses as subtraction)`,fix:`rename to ${E.name.replace(/-/g,"")}`}),u.has(E.name)&&n("E04",s,{attr:"state",problem:`field "${E.name}" is declared twice in one scope`}),u.add(E.name),Nt.has(E.attr)&&n("E05",s,{attr:"state",problem:`"${E.name}" is a reserved Sap word`}),gt.has(E.attr)&&n("E06",s,{attr:"state",problem:`"${E.name}" is a global HTML attribute name; pick another field name`}),E.name==="open"&&s.tagName==="DIALOG"&&n("E33",s,{attr:"state",problem:"dialog open is transient",fix:"use showModal() \u2014 declare state= only on <details> or popovers"});let A=ne(s,E.attr);A&&(E.attr==="checked"||E.attr==="selected")&&n("E35",s,{attr:"state",problem:`"${E.attr}" on a form control is the control's own state, not a declared field`,fix:'bind the control instead, e.g. <input type="checkbox" bind="done">'}),A&&E.type==="num"&&n("E35",s,{attr:"state",problem:`"${E.attr}" is an HTML boolean attribute; it cannot hold a number`,fix:`declare it bare: state="${E.attr}"`}),E.transient&&(A||E.type==="presence")&&n("E35",s,{attr:"state",problem:`"${E.name}" is carried by attribute presence, which transient would strip`,fix:"declare a separate name:bool:transient field and paint the attribute from it"})}}if(le(s)){if(s.hasAttribute("-"),s.tagName==="INPUT"){let d=(s.getAttribute("type")||"text").toLowerCase();d==="file"&&n("E32",s,{attr:"bind",problem:"files never serialize into an HTML file",fix:"use no-save + effect instead of bind"}),d==="password"&&!s.hasAttribute("transient")&&n("E31",s,{attr:"bind",problem:"a password must never serialize into a world-readable file",fix:"add transient to the password input"})}else if(s.tagName!=="SELECT"&&s.tagName!=="TEXTAREA"){let d=s.getAttribute("contenteditable");!(d!=null&&d!=="false")&&s.children.length>0&&n("E20",s,{attr:"bind",problem:"bind on a container element is not a control; a write would overwrite its children",fix:"bind a control (input/select/textarea), a contenteditable, or an empty text leaf"})}}if(s.hasAttribute("transient")&&s.hasAttribute("persist")&&n("E34",s,{problem:"transient and persist are opposite: persist forces the live value into the saved bytes, leaking exactly what transient drops",fix:"remove one \u2014 transient to keep it out of the file, or persist to save it"}),s.tagName==="DIALOG"&&s.hasAttribute("detail")&&!(s.parentElement&&s.parentElement.closest('[clay~="freeze"], [freeze], [save-freeze]'))&&e.warn("W31",s,{attr:"detail",problem:"a detail dialog writes open when it opens, and that attribute would be saved into the file",fix:'wrap the dialog in an element with clay="freeze" (not editor-ui, which removes it from the file), and make its key field transient'}),s.hasAttribute("item")&&!s.hasAttribute("template")&&s.parentNode&&s.parentNode.nodeType===1){let d=s.parentElement;(!d||!d.hasAttribute("items"))&&n("E10",s,{problem:"an [item] must be a direct child of an [items] list",fix:'wrap it in a container with items="name"'})}if(s.hasAttribute("items")&&m&&n("E17",s,{attr:"items",problem:"nested items inside a detail panel is a v1 mount error (nested collections ship in v1.1)"}),s.hasAttribute("items")){let d=t.querySelector(`[trigger-add="${s.getAttribute("items")}"]`);!Ft(s)&&!te(t,s.getAttribute("items"))&&G(s).length===0&&d&&n("E17",s,{attr:"items",problem:`trigger-add targets items="${s.getAttribute("items")}" but it has no [item template] to clone`})}}),r&&(e.halted=!0,e.haltReason=e.errors[0]?e.errors[0].code:"halt",V(t,e.haltReason)),!r}var mn="sap-styles",hn="[item][template]{display:none!important}[hidden]{display:none!important}[sap-error]{outline:2px solid #e5484d;outline-offset:1px}",pe=new WeakSet;function xr(t){if(pe.has(t))return;let e=t.defaultView,r=e&&e.CSSStyleSheet;if(r&&"adoptedStyleSheets"in t)try{let n=new r;n.replaceSync(hn),t.adoptedStyleSheets=[...t.adoptedStyleSheets,n],pe.add(t);return}catch{}if(!t.getElementById(mn)){let n=t.createElement("style");n.id=mn,n.textContent=hn,(t.head||t.documentElement).appendChild(n)}pe.add(t)}var Sr=0;function bn(){return typeof performance<"u"&&performance.now?performance.now():0}function me(t){let e=t.id||t.getAttribute("sap")||`app-${Sr++}`,r=new at(e),n={root:t,name:e,diag:r,_state:null,_stats:null,_lastPass:null,_passes:0,_broken:!1,_mountMs:0,_mountWrites:0};if(!Yt(t,r))return n.halted=!0,n;xr(t.ownerDocument);for(let s of t.querySelectorAll("textarea[data-value]"))qt(s);let i=bn();return bt(n,{trigger:"mount",full:!0}),n._mountMs=bn()-i,n._mountWrites=n._stats?n._stats.writes:0,n._mountWrites>0&&!Ke()&&!O("derived")&&r.warn("W30",t,{problem:`${n._mountWrites} paint(s) ran at mount; the saved file was out of sync with its declared state`,fix:"re-save once so the file mounts clean (a settled file writes nothing)"}),n}var gn=/^(set:|move:|sort:|trigger-add$|trigger-remove$|trigger-reset$)/;function Xt(t){return`${t.tagName.toLowerCase()}[sap]`}function kr(t){let e=0;for(let r of t.querySelectorAll("*"))for(let n of r.attributes)if(gn.test(n.name)){e++;break}for(let r of t.attributes)if(gn.test(r.name)){e++;break}return e}function wn(t){function e(b){let m=b._stats||{},d=b.root;return{root:Xt(d),fields:m.fields||0,calcs:m.calcs||0,paints:m.paints||0,actions:kr(d),lists:(d.hasAttribute("items")?1:0)+d.querySelectorAll("[items]").length,rows:d.querySelectorAll("[item]:not([template])").length,warnings:b.diag.warnings.length,errors:b.diag.errors.length,mountWrites:b._mountWrites||0,ms:Math.round((b._mountMs||0)*10)/10,passes:b._passes||0,lastPass:b._lastPass||null,ok:b.diag.errors.length===0&&!b.halted}}function r(){let b=t.apps().map(e);return{ok:b.every(m=>m.ok),apps:b}}function n(b){let m=e(b);return m.ok?`sap \u2713 ${m.root} \xB7 fields ${m.fields} \xB7 calcs ${m.calcs} \xB7 paints ${m.paints} \xB7 actions ${m.actions} \xB7 lists ${m.lists} \xB7 rows ${m.rows} \xB7 warnings ${m.warnings} \xB7 mount writes ${m.mountWrites} \xB7 ${m.ms}ms`:`sap \u2717 ${m.root} \xB7 errors ${m.errors} \xB7 warnings ${m.warnings} \xB7 ${m.ms}ms`}function o(){for(let b of t.apps()){let m=n(b);b.diag.errors.length||b.halted?console.error(m):console.log(m)}}function i(){let b=[],m=[];for(let d of t.apps())b.push(...d.diag.errors),m.push(...d.diag.warnings);return{ok:b.length===0,errors:b,warnings:m,counts:{errors:b.length,warnings:m.length}}}function s(b){let m=b===void 0?!0:!!b;for(let d of t.apps())d._debug=m;return console.log(`sap debug ${m?"on":"off"} \u2014 per-pass headers will ${m?"":"no longer "}log`),m}return{status:r,report:i,debug:s,greenLine:n,printGreenLines:o,REGISTRY:Zt}}var yn="0.7.1";function An({createAccessor:t,installInput:e,debugExtras:r}){let n=new Map,o=[],i=be(bt);function s(l){let g=l;for(;g;){if(g.nodeType===1&&g.hasAttribute&&g.hasAttribute("sap"))return n.get(g)||null;g=g.parentNode&&g.parentNode.host?g.parentNode.host:g.parentElement}return null}function b(){for(let l=o.length-1;l>=0;l--){let g=o[l];g.root.isConnected||(n.delete(g.root),o.splice(l,1))}}function m(l,g){if(l.moveBefore)try{l.moveBefore(g,null);return}catch{}l.appendChild(g)}function d(l,g){let v=g.parentElement;if(v){if(v.moveBefore)try{v.moveBefore(l,g);return}catch{}v.insertBefore(l,g)}}let u={apps:()=>o.slice(),appFor:s,isRegistered:l=>n.has(l),pruneDisconnected:b,schedule:(l,g)=>i.schedule(l,g),runNow:(l,g)=>i.runNow(l,g),moveInto:m,placeBefore:d,remountIfPresent:()=>x()},E=t(u),A=wn(u),N=r?r(u,A):{},R=!1,p=!1,y=null;function h(){R||(R=!0,e(u,E,document),y=tn(u))}function w(){let l=O("derived");l&&typeof l.mounted=="function"&&l.mounted()}function x(l=document){if(p)return[];h(),ue(u);let g=l.querySelectorAll("[sap]"),v=[];for(let T of g){if(n.has(T))continue;let f=me(T);n.set(T,f),o.push(f),v.push(f)}for(let T of v){let f=A.greenLine(T);T.diag.errors.length||T.halted?console.error(f):console.log(f)}return w(),v}function c(l){if(p)return null;if(h(),ue(u),!l)return x();let g=typeof l=="string"?document.querySelector(l):l;if(!g)return null;if(n.has(g))return n.get(g);let v=me(g);n.set(g,v),o.push(v);let T=A.greenLine(v);return v.diag.errors.length||v.halted?console.error(T):console.log(T),v}let a=E.Sap;return a.version=yn,a.refresh=function(){for(let g of o)g.root.isConnected&&i.runNow(g,"refresh")},a.batch=Ze,a.status=A.status,a.report=A.report,a.why=N.why,a.debug=A.debug,a.doctor=N.doctor,a.greenLine=A.greenLine,a.formats=dt,a.serializeControlToAttributes=mt,a.finalizeControlForSave=Xe,a.rehydrateControlFromAttributes=qt,a.mount=c,a.config=function(g={}){return g.formats&&Object.assign(dt,g.formats),a},a._registry=n,a._reset=function(){n.clear(),o.length=0,ce()},a.unmount=function(){p=!0,n.clear(),o.length=0,ce(),typeof y=="function"&&y()},{Sap:a,mountAll:x,mount:c,runtime:u}}function vn(t){if(typeof document>"u")return;let e=()=>Je(()=>t());document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e()}var $r=["for","form","list","headers","popovertarget","commandfor","anchor","aria-activedescendant","aria-controls","aria-describedby","aria-details","aria-errormessage","aria-flowto","aria-labelledby","aria-owns"];function _r(t,e){let r=null;return H(t,n=>{!r&&n.getAttribute("scope")===e&&(r=n)}),r}function En(t,e,r){let n=j(t)||e;for(;n;){for(let o of W(n.getAttribute("state")||""))if(o.name===r)return{el:n,decl:o};if(n.hasAttribute("sap"))break;n=j(n.parentElement)}return null}function Tr(t){return typeof t=="number"?"num":typeof t=="boolean"?"bool":"string"}function xn(t){function e(p){let y=t.appFor(p);if(!y)return null;let h=tt(p),w=h&&h._sapEachItem&&h._sapEachItem.$el;if(w&&w.isConnected)return{ctxEl:w,appRec:y,isRow:!0};let x=yt(p);if(x)return x._sapDetailRow?{ctxEl:x._sapDetailRow,appRec:y,isRow:!0}:{ctxEl:j(x.parentElement)||y.root,appRec:y,isRow:!1};let c=Ct(p);if(c&&c.hasAttribute("item"))return{ctxEl:c,appRec:y,isRow:!0};let a=j(p)||y.root;return{ctxEl:a,appRec:y,isRow:a.hasAttribute("item")}}function r(p){let y=typeof p=="string"?document.querySelector(p):p;if(!y||y.nodeType!==1)return null;let h=e(y);return h?R(h.ctxEl,h.appRec,h.isRow):null}function n(p,y){let h=tt(p);if(!h)return r(p);let w=t.appFor(p),x=h._sapEachItem&&h._sapEachItem.$el;if(x&&x.nodeType===1&&x.hasAttribute("item")&<(x,y))return x.isConnected?R(x,w,!0):null;let c=h.parentElement&&h.parentElement._sapDrawnEl;return!c||!c.isConnected?null:R(c,w,c.hasAttribute("item"))}function o(p,y,h){let w=et(p,h);if(w)return B(w).read();let x=ft(p,h);if(x)return G(x).map(g=>R(g,y,!0));let c=_r(p,h);if(c)return R(c,y,!1);let a=En(p,y.root,h);if(a)return a.decl.transient?Mt(a.el,a.decl):Ae(a.el,a.decl);let l=p._sapScope;return l?l[h]:void 0}function i(p,y,h,w,x){w.transient?Et(p,w,h):vt(p,w,h),t.schedule(x,"set:"+y)}function s(p,y){let h=new Set,w=j(p)||y;for(;w;){for(let x of W(w.getAttribute("state")||""))h.add(x.name);if(w.hasAttribute("sap"))break;w=j(w.parentElement)}return H(p,x=>{let c=x.getAttribute("bind");c&&h.add(c)}),h}function b(p,y,h,w){let x=et(p,h);if(x){if(!F(x))return;B(x).write(w);return}let c=p;for(;c;){for(let k of c.attributes)if(k.name==="calc:"+h){y.diag.error("E16",c,{attr:"calc:"+h,problem:`"${h}" is a computed field; computed fields are read-only`});return}if(c.hasAttribute("sap"))break;c=c.parentElement}let a=En(p,y.root,h);if(a){if(!F(a.el,{transient:a.decl.transient}))return;i(a.el,h,w,a.decl,y);return}let l=s(p,y.root);l.delete(h);let g=h.length>=4?wt(h,[...l]):null;if(g){y.diag.error("E12",p,{key:h,problem:`unknown state key "${h}"`,didYouMean:g});return}if(Nt.has(h)||gt.has(h)){y.diag.error("E15",p,{key:h,problem:`cannot write undeclared field "${h}" \u2014 it is a reserved/global name and cannot become state`,fix:"pick a different field name, or declare it explicitly in a state= attribute"});return}let v=y.root;if(!F(v))return;let T=Tr(w),f=v.getAttribute("state")||"",S=T==="string"?h:`${h}:${T}`;v.setAttribute("state",f?`${f} ${S}`:S),i(v,h,w,{name:h,attr:h,type:T,transient:!1},y)}function m(p){let y=p.ownerDocument,h=new Map,w=(x,c)=>{let a=we(y),l=x.getAttribute(c);l&&c==="id"&&h.set(l,a),x.setAttribute(c,a)};p.querySelectorAll("[id]").forEach(x=>w(x,"id")),p.querySelectorAll("[data-id]").forEach(x=>w(x,"data-id")),p.querySelectorAll("[sap-error]").forEach(x=>x.removeAttribute("sap-error")),p.removeAttribute("sap-error"),p.hasAttribute("data-id")?(p.removeAttribute("id"),w(p,"data-id")):w(p,"id");for(let x of[p,...p.querySelectorAll("*")])for(let c of $r){let a=x.getAttribute(c);if(a==null)continue;let l=a.split(/\s+/).map(g=>h.get(g)||g).join(" ");l!==a&&x.setAttribute(c,l)}}function d(p,y,h){let w=xt(y.root,p,h);if(!w)return y.diag.error("E17",p,{problem:`cannot resolve a list named "${h}" from here`}),null;if(!F(w))return null;let x=Ft(w);if(!x)return y.diag.error("E17",w,{problem:`items="${h}" has no [item template] to clone`}),null;let c=w.ownerDocument.importNode(x,!0);return c.removeAttribute("template"),m(c),w.appendChild(c),t.schedule(y,"trigger-add:"+h),R(c,y,!0)}function u(p,y){let h=W(p.getAttribute("state")||""),w=!0;H(p,x=>{x.hasAttribute("bind")&&!F(x)&&(w=!1)});for(let x of h)F(p,{transient:x.transient})||(w=!1);if(w){H(p,x=>{if(x.hasAttribute("bind")){let c=B(x),a=x.getAttribute("default");c.kind==="checkbox"||c.kind==="radio"?c.write(a!=null?a===""||a==="true"||x.value===a:x.hasAttribute("checked")):c.write(a??(x.getAttribute("value")||""))}});for(let x of h){let c=ve(p,x);x.transient?Et(p,x,c):vt(p,x,c)}t.schedule(y,"trigger-reset")}}function E(p,y){if(!p.isConnected)throw new Error("stale row handle: $remove() on a removed row");F(p)&&(p.remove(),t.schedule(y,"trigger-remove"))}function A(p,y,h){if(!p.isConnected)throw new Error("stale row handle: $move() on a removed row");let w=null;if(h&&h.nodeType===1?w=h:typeof h=="string"&&(w=xt(y.root,p,h)),!w){y.diag.error("E17",p,{problem:`$move() cannot resolve target "${h}"`});return}!F(p)||!F(w)||(t.moveInto(w,p),t.schedule(y,"trigger-move"))}function N(p){let y=p.parentElement;return y?G(y).indexOf(p):-1}function R(p,y,h){let w={get $el(){return p},get $key(){return Lt(p,h?"row":"scope")},get $index(){return N(p)},$add(c){return d(p,y,c)},$reset(){return u(p,y),x},$remove(){E(p,y)},$move(c){A(p,y,c)},get $appRec(){return y}},x=new Proxy(w,{get(c,a){return typeof a=="symbol"||a[0]==="$"?c[a]:o(p,y,a)},set(c,a,l){return typeof a=="string"&&a[0]==="$"?(c[a]=l,!0):(b(p,y,a,l),!0)},has(c,a){return typeof a=="string"&&a[0]==="$"?a in c:o(p,y,a)!==void 0}});return x}return{Sap:r,contextElFor:e,readField:o,writeField:b,makeProxy:R,writeTargetFor:n}}var Nr=["trigger-add","trigger-remove","trigger-reset"];function Rr(t){if(t.nodeType!==1)return!1;for(let e of t.attributes){let r=e.name;if(r.startsWith("set:")||r.startsWith("move:")||r.startsWith("sort:")||Nr.includes(r))return!0}return!1}function Lr(t,e){let r=t,n=e.parentElement;for(;r&&r!==n;){if(r.nodeType===1&&Rr(r)&&!(r.tagName==="FORM"&&r.hasAttribute("trigger-add")))return r;r=r.parentElement}return null}function Sn(t,e){let{Sap:r}=e;function n(c,a){let l=null,g=tt(c),v=yt(c);if(g)l=g._sapEachItem??null;else if(v&&v._sapDetailRow)l=v._sapDetailRow._sapScope||null;else{let S=Ct(c);S&&S.hasAttribute("item")&&(l=S._sapScope||null)}return{state:(j(c)||a.root)._sapScope||a._state||{},item:l,el:c,root:a._state||{}}}function o(c,a,l){if(!c.hasAttribute("confirm")){l();return}let g=c.getAttribute("confirm"),v=g,T=P(g);if(!T.error)try{let _=nt(T,n(c,a));(typeof _=="string"||typeof _=="number")&&(v=String(_))}catch{}let f=$t(),S=()=>{$t()===f&&l()},k=Qe();if(!k){window.confirm(v)&&S();return}if(c._sapGatePending)return;c._sapGatePending=!0;let $=()=>{c._sapGatePending=!1};k(v,()=>{$(),S()}).catch($)}function i(c,a){for(let l of c.attributes){if(!l.name.startsWith("set:"))continue;let g=l.name.slice(4),v=P(l.value);if(v.error){a.diag.error("E08",c,{attr:l.name,expr:l.value,problem:String(v.error.message)});continue}let T;try{T=nt(v,n(c,a))}catch(S){a.diag.error("E24",c,{attr:l.name,expr:l.value,problem:String(S.message)});continue}let f=e.writeTargetFor(c,g);f&&(f[g]=T)}}function s(c){let a=tt(c);if(!a)return c.closest("[item]");let l=a._sapEachItem&&a._sapEachItem.$el;return l&&l.nodeType===1&&l.hasAttribute("item")?l:null}function b(c,a){let l=s(c);if(!l||!F(l)||!F(l.parentElement))return;let g=G(l.parentElement),v=g.indexOf(l);a==="up"&&v>0?t.placeBefore(l,g[v-1]):a==="down"&&v<g.length-1&&t.placeBefore(g[v+1],l)}function m(c,a,l){if(a)return xt(l.root,c,a);let g=c;for(;g;){if(g.hasAttribute&&g.hasAttribute("items"))return g;g=g.parentElement}let v=j(c)||l.root,T=[];return H(v,f=>{f.hasAttribute("items")&&T.push(f)}),T[0]||null}function d(c,a){let l=c==null||c==="",g=a==null||a==="";if(l&&g)return 0;if(l)return 1;if(g)return-1;let v=Number(c),T=Number(a);return!Number.isNaN(v)&&!Number.isNaN(T)?v-T:String(c)<String(a)?-1:String(c)>String(a)?1:0}function u(c,a,l,g){let v=m(c,l,g);if(!v){g.diag.error("E17",c,{attr:"sort:"+a,problem:`no items list resolvable for sort:${a}`});return}if(!F(v))return;let T=G(v),f=_=>_._sapScope?_._sapScope[a]:void 0,S=[...T].sort((_,L)=>d(f(_),f(L))),$=S.every((_,L)=>_===T[L])?[...S].reverse():S;for(let _ of $)t.moveInto(v,_);t.schedule(g,"sort:"+a)}function E(c){if(!c||c.hidden)return;let a=c.querySelector("[bind]:not([type=hidden]), [contenteditable]");a&&typeof a.focus=="function"&&a.focus()}function A(c,a){o(c,a,()=>{let l=r(c);for(let g of[...c.attributes]){let v=g.name;if(v==="trigger-remove")l&&l.$remove();else if(v==="trigger-reset")l&&l.$reset();else if(v==="trigger-add"){let T=l&&l.$add(g.value);T&&E(T.$el)}else v==="move:up"?(b(c,"up"),t.schedule(a,"move:up")):v==="move:down"?(b(c,"down"),t.schedule(a,"move:down")):v.startsWith("move:to")?l&&l.$move(g.value):v.startsWith("sort:")&&u(c,v.slice(5),g.value,a)}[...c.attributes].some(g=>g.name.startsWith("set:"))&&i(c,a)})}function N(c){let a=c.target;if(!a||a.nodeType!==1)return;let l=t.appFor(a);if(!l)return;let g=Lr(a,l.root);g&&A(g,l)}function R(c){let a=B(c),l=c.getAttribute("default");a.kind==="checkbox"?a.write(l===""||l==="true"):a.write(l??"")}function p(c,a,l){let g=r(c);if(!g)return;let v=g.$add(l);if(!v)return;let T=[];H(c,f=>{f.hasAttribute("bind")&&T.push(f)});for(let f of T){if(f.type==="radio"&&!f.checked)continue;let S=f.getAttribute("bind"),k=et(v.$el,S);k?B(k).write(B(f).read()):lt(v.$el,S)&&(v[S]=B(f).read())}T.forEach(R),T.length?typeof T[0].focus=="function"&&T[0].focus():E(v.$el)}function y(c){let a=c.target;if(!a||!a.hasAttribute||!a.hasAttribute("trigger-add"))return;let l=t.appFor(a);l&&(c.preventDefault(),o(a,l,()=>p(a,l,a.getAttribute("trigger-add"))))}function h(c){let a=c.target;if(!a||a.tagName!=="DIALOG"||!a.hasAttribute("detail"))return;if(a._sapEngineClose){a._sapEngineClose=!1;return}if(a.open)return;let l=/^[\w.]+\s+by\s+state\.(\w+)\s*$/.exec(a.getAttribute("detail")||""),g=t.appFor(a);if(!l||!g)return;let v=W(a.getAttribute("state")||"").find(f=>f.name===l[1]);if(v){if(!F(a,{transient:v.transient}))return;v.transient?Et(a,v,""):vt(a,v,""),t.schedule(g,"close");return}let T=r(a.parentElement);T&&T[l[1]]!==""&&(T[l[1]]="")}function w(c,a){let l=c.hasAttribute("bind")&&Dt(c);if(!l&&c.hasAttribute("bind")&&tt(c)){let v=c.getAttribute("bind"),T=c._sapViewBind?e.writeTargetFor(c,v):null;return T&&(T[v]=B(c).read()),!0}let g=yt(c);if(g&&g._sapDetailRow&&c.hasAttribute("bind")&&!l){let v=g._sapDetailRow,T=c.getAttribute("bind"),f=et(v,T);if(f&&f!==c)return F(f)&&B(f).write(B(c).read()),!0;if(!f&&W(v.getAttribute("state")||"").some(S=>S.name===T))return e.writeField(v,a,T,B(c).read()),!0}return!1}function x(c=document){c.addEventListener("click",N),c.addEventListener("submit",y),c.addEventListener("close",h,!0)}return{install:x,routeInput:w}}function kn(t){let e=[];function r(m){let d=m.target;if(!d||d.nodeType!==1)return;let u=t.appFor(d);if(u){d.hasAttribute("persist")&&!zt(d)&&F(d)&&mt(d);for(let E of e)if(E(d,u))return;t.schedule(u,m.type+" "+(d.id||d.tagName.toLowerCase()))}}function n(m){let d=m.target,u=t.appFor(d);u&&[...d.querySelectorAll("[bind]")].every(E=>F(E))&&setTimeout(()=>{d.querySelectorAll("[bind]").forEach(E=>{E.dispatchEvent(new Event("input",{bubbles:!0})),E.dispatchEvent(new Event("change",{bubbles:!0}))}),t.schedule(u,"reset")},0)}function o(m){let d=t.appFor(m.target);d&&t.schedule(d,"toggle")}function i(m){let d=m.detail||{};for(let u of[d.from,d.to,m.target]){if(!u||u.nodeType!==1)continue;let E=t.appFor(u);E&&t.schedule(E,"sorted")}}function s(m){if(m.key!=="ArrowUp"&&m.key!=="ArrowDown")return;let d=m.target;if(!d||d.nodeType!==1||d.tagName!=="INPUT"||!d.hasAttribute("bind")||!d.hasAttribute("step"))return;let u=(d.getAttribute("type")||"text").toLowerCase();if(u!=="text"&&u!=="tel"&&u!=="search"||!t.appFor(d)||!F(d))return;m.preventDefault();let A=q(d.getAttribute("step"))||1,N=m.key==="ArrowUp"?1:-1,R=q(d.value)+A*(m.shiftKey?10:1)*N,p=d.getAttribute("min"),y=d.getAttribute("max");p!==null&&p!==""&&R<q(p)&&(R=q(p)),y!==null&&y!==""&&R>q(y)&&(R=q(y)),B(d).write(String(Number(R.toFixed(2))))}function b(m=document){m.addEventListener("reset",n),m.addEventListener("toggle",o,!0),m.addEventListener("input",r),m.addEventListener("change",r),m.addEventListener("clay:sorted",i),m.addEventListener("keydown",s)}return{install:b,addRouter:m=>e.push(m)}}function $n(t){let e=t.toLowerCase();return/^x-text$|^x-html$/.test(e)?'use text="state.x" (Sap paints text only)':/^x-show$|^v-show$|^v-if$/.test(e)?'use show="expr" (toggles native hidden)':/^x-model$|^v-model$/.test(e)?'use bind="field"':/^@|^x-on:|^v-on:|^on:/.test(e)?"use native onclick + Sap(this) (no event directive)":/^:|^x-bind:class$|^v-bind:class$/.test(e)?'use class:NAME="expr" or attr:NAME="expr"':/^x-for$|^v-for$/.test(e)?'use items="name" on the container and item template on the row':/^x-data$/.test(e)?"declare state with state= / bind / items (no JS state object)":/^x-init$/.test(e)?"use a <script> or onclick + Sap(this)":/^bind:/.test(e)?'use bind="field"; one-way paint is attr:NAME="expr"':/^x-/.test(e)||/^v-/.test(e)?"this is a foreign-dialect attribute; Sap has no x-/v- attributes":null}function _n(t){let e=[],r=n=>{for(let o of n.attributes){let i=o.name;(i.startsWith("calc:")||i==="text"||i.startsWith("text:")||i==="show"||i.startsWith("attr:")||i.startsWith("class:")||i.startsWith("css:")||i==="effect"||i==="invalid"||i.startsWith("set:")||i==="detail")&&e.push({el:n,attr:i,src:o.value})}};r(t);for(let n of t.querySelectorAll("*"))r(n);return e}function Tn(t){function e(o){return o?typeof o=="string"?document.querySelector(o):o.nodeType===1?o:null:null}function r(o,i){let s=e(o);if(!s)return console.warn("sap why: element not found"),null;let b=[`sap why <${s.tagName.toLowerCase()}> \u2014 ${Rt(s)}`],m=[...s.attributes].filter(u=>/^(bind|text|show|effect|invalid|detail|calc:|text:|attr:|class:|css:|set:|state|items|scope)/.test(u.name));for(let u of m)b.push(` ${u.name}="${u.value}"`);let d=s;for(;d&&!d._sapScope;)d=d.parentElement;if(d&&d._sapScope){let u=d._sapScope,E=i?[i]:Object.keys(u);b.push(" reads:");for(let A of E){let N=u[A];typeof N!="function"&&b.push(` ${A} = ${JSON.stringify(Array.isArray(N)?`[${N.length} rows]`:N)}`)}}return b.push(" serialization: textContent and value/checked attributes save with the file; reads live from properties"),console.log(b.join(`
|
|
10
10
|
`)),null}function n(){let o=[],i=0;for(let u of t.apps()){let E=u.root,A=Xt(E);i++;let N=new at(u.name);Yt(E,N);for(let w of N.errors)o.push({code:w.code,severity:"error",message:`${A}: ${w.code} ${w.slug} at ${w.el}`});for(let w of N.warnings)o.push({code:w.code,severity:"warn",message:`${A}: ${w.code} ${w.slug} at ${w.el}`});i++,bt(u,{trigger:"doctor-dryrun"});let R=u._stats?u._stats.writes:0;R>0&&o.push({code:"W30",severity:"warn",message:`${A}: dry recompute wrote ${R} cells on a quiet page; an element is stale or non-idempotent`}),i++;let p=_n(E).map(w=>w.src).join(" \0 "),y=[];for(let w of[E,...E.querySelectorAll("[state]")])for(let x of W(w.getAttribute("state")||""))y.push(x.name);for(let w of y)new RegExp(`(state|item)\\.${w}\\b`).test(p)||o.push({code:"I33",severity:"info",message:`${A}: field "${w}" is declared but read nowhere (dead state)`});i++;let h=new Map;for(let w of E.querySelectorAll("[id]"))h.set(w.id,(h.get(w.id)||0)+1);for(let[w,x]of h)x>1&&o.push({code:"W32",severity:"warn",message:`${A}: duplicate id "${w}" (${x} elements) \u2014 clone/edit collision`});i++;for(let w of _n(E))w.src.length>120&&o.push({code:"I33",severity:"info",message:`${A}: ${w.attr} expression is ${w.src.length} chars; consider a calc: field`});i++;for(let w of E.querySelectorAll("[text], [text\\:num]")){let x=w.textContent||"";/\.\d{5,}/.test(x)&&o.push({code:"I33",severity:"info",message:`${A}: ${Rt(w)} paints >4 decimals; consider text:FMT`})}}let s=o.filter(u=>u.severity==="error").length,b=o.filter(u=>u.severity==="warn").length,m=o.filter(u=>u.severity==="info").length;console.log(`sap doctor \xB7 ${t.apps().map(u=>Xt(u.root)).join(", ")} \xB7 errors ${s} \xB7 warnings ${b} \xB7 info ${m} \xB7 ${i} checks \xB7 0ms`);for(let u of o)(u.severity==="error"?console.error:u.severity==="warn"?console.warn:console.info)(` ${u.severity==="error"?"\u2717":u.severity==="warn"?"\u26A0":"\xB7"} ${u.message}`);return o}return{why:r,doctor:n}}function Cr(t,e){let r=String(t).split("."),n=i=>{for(let s of r){if(i==null)return;i=Array.isArray(i)?i.flatMap(b=>b&&b[s]!=null?b[s]:[]):i[s]}return i},o=n(e.state);return o===void 0?n(e.root):o}function Dr(t,e,r,n){e._sapScope=r;let o=e.getAttribute("detail")||"",i=/^([\w.]+)\s+by\s+(.+)$/.exec(o);if(!i){e.hidden=!0,e._sapDetailRow=null;return}let s=i[1],b=i[2].trim(),m=Cr(s,n),d;try{d=nt(P(b),{state:r,item:n.item,el:e,root:n.root})}catch{d=void 0}let u=Array.isArray(m)&&d!=null?m.find(A=>A&&typeof A=="object"&&A.$el&&String(A.$key)===String(d)):null;if(e._sapDetailRow=u?u.$el:null,u&&jt(u.$el),e.tagName==="DIALOG"){let A=u?String(u.$key):null;if(A!==e._sapDetailKey&&(e._sapDetailKey=A,e._sapDismissed=!1),!u){e._sapOpenedFor=null,e.open&&typeof e.close=="function"&&(e._sapEngineClose=!0,e.close());return}e.open?e._sapOpenedFor=A:(e._sapOpenedFor===A&&(e._sapDismissed=!0),e._sapOpenedFor=null,!e._sapDismissed&&e.isConnected&&typeof e.showModal=="function"&&(e.hidden&&(e.hidden=!1),e.showModal(),e._sapOpenedFor=A))}else{if(!u){e.hidden||(e.hidden=!0);return}e.hidden&&(e.hidden=!1)}Bt();let E={root:n.root,state:r,item:u,ownerEl:u.$el,projection:!0};t.collectEl(e,X(e),E),t.walkScope(e,u,E)}var Nn={name:"detail",begin(t){t.deferredDetails=[]},boundary:{detail(t,e,r,n,o){for(let i of W(e.getAttribute("state")||""))i.name in n||(n[i.name]=Y(e,i)?e.hasAttribute(i.attr):t.resolveDefault(e,i));t.deferredDetails.push({el:e,parentObj:n,ctx:o})}},afterIntake(t){for(let e=0;e<t.deferredDetails.length;e++){let{el:r,parentObj:n,ctx:o}=t.deferredDetails[e];Dr(t,r,n,o)}}};function Rn(t){let e=0,r=t;for(;r&&!(r.hasAttribute&&r.hasAttribute("sap"));)r=r.parentElement,e++;return e}var Ln={name:"calc",begin(t){t.calcs=[]},collect(t,e,r,n){if(!r.calcs)return!1;let o=n.item||n.state;for(let i of r.calcs)t.calcs.push({owner:o,ownerEl:n.ownerEl,name:i.name,entry:i.entry,def:i,el:e,ctx:n})},compute(t){let e=t.app,r=new Map;for(let o of t.calcs){let i=r.get(o.owner);i||(i={ownerEl:o.ownerEl,list:[]},r.set(o.owner,i)),i.list.push(o)}let n=[...r.values()].sort((o,i)=>Rn(i.ownerEl)-Rn(o.ownerEl));for(let o of n){let i;try{i=Le(o.list)}catch(s){e.diag.error("E07",o.list[0].el,{problem:s.message}),i=o.list}for(let s of i)try{s.owner[s.name]=z(s.entry,s.ctx.state,s.ctx.item,s.el,s.ctx.root),ct(s.el)}catch(b){s.owner[s.name]=void 0,e.diag.error("E24",s.el,{attr:"calc:"+s.name,expr:s.entry.src,problem:String(b.message)}),V(s.el,b.sapCode||"E24")}}t.stats.calcs=t.calcs.length,t.stats.lists=r.size}};function Fr(t,e,r){let n=r.nextSibling;if(e.isConnected&&t.moveBefore)try{t.moveBefore(e,n);return}catch{}t.insertBefore(e,n)}function Mr(t,e,r){for(let n=e.parentElement;n;n=n.parentElement)if(n._sapScope===r&&!n.hasAttribute("detail")||n.hasAttribute("sap"))return n;return t}function Or(t,e,r){let n=t.app;e._sapDrawnEl=Mr(t.root,e,r.state);let o=null;for(let p=e.firstElementChild;p;p=p.nextElementSibling)if(p.tagName==="TEMPLATE"){o=p;break}let i=o&&o.content.children.length===1?o.content.firstElementChild:null;if(!i)return n.diag.error("E42",e,{attr:"each",problem:"each needs one <template> child with exactly one element root"}),0;let s=e.getAttribute("each"),b;try{b=nt(P(s),{state:r.state,item:r.item,el:e,root:r.root})}catch(p){return n.diag.error("E24",e,{attr:"each",expr:s,problem:String(p.message)}),0}if(!Array.isArray(b))return n.diag.error("E40",e,{attr:"each",expr:s,problem:"each must evaluate to an array; the list keeps its last good rows"}),0;let m=P(e.getAttribute("key")||"item.$key"),d=[],u=new Set;for(let p of b){let y;try{y=z(m,r.state,p,e,r.root)}catch{y=void 0}let h=y==null?"":String(y);if(h===""||u.has(h))return n.diag.error("E41",e,{attr:"key",expr:m.src,problem:h===""?"an item has no key; the list keeps its last good rows":`duplicate key "${h}"; the list keeps its last good rows`}),0;u.add(h),d.push(h)}let E=e._sapEach||new Map,A=new Map,N=0,R=o;d.forEach((p,y)=>{let h=E.get(p);if(!h||h.parentElement!==e){h=e.ownerDocument.importNode(i,!0);let w=(h.getAttribute("clay")||"").split(/\s+/).filter(Boolean);w.includes("editor-ui")||h.setAttribute("clay",[...w,"editor-ui"].join(" ")),h._sapEachRow=!0,N++}h.getAttribute("data-key")!==p&&h.setAttribute("data-key",p),R.nextElementSibling!==h&&(Fr(e,h,R),N++),h._sapEachItem=b[y],A.set(p,h),R=h});for(let[p,y]of E)A.get(p)!==y&&y.parentElement===e&&(y.remove(),N++);return e._sapEach=A,Bt(),d.forEach((p,y)=>{let h=A.get(p),w={root:r.root,state:r.state,item:b[y],ownerEl:h,projection:!1,view:!0};t.collectEl(h,X(h),w),t.walkScope(h,{},w)}),N}var Cn={name:"each",begin(t){t.eachList=[]},boundary:{each(t,e,r,n,o){t.collectEl(e,r,o),t.eachList.push({el:e,ctx:o})}},reconcile(t){let e=0;for(let r=0;r<t.eachList.length;r++)e+=Or(t,t.eachList[r].el,t.eachList[r].ctx);return e}};function Pr(t,e){try{z(t.def.entry,t.ctx.state,t.ctx.item,t.el,t.ctx.root),ct(t.el)}catch(r){e.diag.error("E24",t.el,{attr:"effect",expr:t.def.entry&&t.def.entry.src,problem:String(r.message)}),V(t.el,"E24")}}var Dn={name:"effect",begin(t){t.effects=[]},collect(t,e,r,n){if(!r.effects)return!1;for(let o of r.effects)t.effects.push({def:o,el:e,ctx:n})},afterPaint(t){for(let e of t.effects)Pr(e,t.app)}};function Ir(t){let e="";try{let r=z(t.def.entry,t.ctx.state,t.ctx.item,t.el,t.ctx.root);e=typeof r=="string"?r:""}catch{e=""}typeof t.el.setCustomValidity=="function"&&t.el.setCustomValidity(e)}var Fn={name:"validation",begin(t){t.invalids=[]},collect(t,e,r,n){if(!r.invalids)return!1;for(let o of r.invalids)t.invalids.push({def:o,el:e,ctx:n})},afterPaint(t){for(let e of t.invalids)Ir(e)}};function Mn(t,e){if(t===t.ownerDocument.activeElement)return 0;if(t.type==="radio"){let i=e!=null&&String(t.value)===String(e);return t.checked===i?0:(t.checked=i,1)}let r=_t(t),n=Ht(t,r),o=e??"";return String(n)!==String(o)?(rn(t,r,o),1):0}var On={name:"projection",collect(t,e,r,n){if(!(r.bind!=null&&(n.view||n.projection)&&!Dt(e)))return!1;let o=r.bind,i=t.paints;n.view?lt(ye(n.item),o)?(e._sapViewBind="item",i.push({def:{kind:"projection",field:o,from:"item"},el:e,ctx:n})):o in n.state||o in n.root?(e._sapViewBind="drawn",i.push({def:{kind:"projection",field:o,from:"drawn"},el:e,ctx:n})):(e._sapViewBind=null,t.app.diag.error("E43",e,{attr:"bind",expr:o,problem:`bind="${o}" inside an each row matches no field of the row's record or of the scope the row is drawn in`,fix:"bind a field the record owns (bind, state= or items= on the [item]), or declare it with state= where the list is drawn"})):i.push({def:{kind:"projection",field:o,from:null},el:e,ctx:n})},paintKinds:{projection(t){let e=t.def;if(e.from==="drawn"){let r=e.field in t.ctx.state?t.ctx.state:t.ctx.root;return Mn(t.el,r[e.field])}return Mn(t.el,t.ctx.item?t.ctx.item[e.field]:"")}}};function Pn(){for(let t of[Nn,Ln,Cn,Dn,Fn,On])fn(t)}Pn();pn((t,e,r)=>{for(let n of t.attributes){let o=$n(n.name);o&&(e("E01",t,{attr:n.name,expr:n.value,problem:`"${n.name}" is a foreign-dialect attribute; Sap has no ${n.name.split(/[:=]/)[0]} directive`,fix:o+" \u2014 or wrap the subtree in sap-ignore if intentional"}),r(n.name))}});var{Sap:Kt,mountAll:In,mount:Wr,runtime:Br}=An({createAccessor:xn,debugExtras:Tn,installInput(t,e,r){let n=kn(t),o=Sn(t,e);n.addRouter(o.routeInput),n.install(r),o.install(r)}}),Tt=typeof window<"u"?window.Sap:null;Tt&&Tt!==Kt&&Tt.core&&typeof Tt.unmount=="function"&&Tt.unmount();vn(In);typeof window<"u"&&(window.Sap=Kt);var jr=Kt;return Vn(qr);})();
|
|
11
11
|
if (typeof window !== 'undefined' && Sap && Sap.default) window.Sap = Sap.default;
|
|
12
12
|
var sapDefault = Sap.default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@panphora/clayjs",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.21.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "clayjs: malleable documents. Save lifecycle for self-saving HTML.",
|
|
6
6
|
"license": "MIT-0",
|
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
"build:standalone": "node build.js --standalone",
|
|
73
73
|
"prepack": "node build.js --standalone",
|
|
74
74
|
"test:standalone": "node build.js --standalone && web-test-runner --config tests/browser/wtr.config.mjs",
|
|
75
|
+
"browser:install": "node scripts/chrome-for-testing/browser-runtime.cjs install",
|
|
75
76
|
"prepublishOnly": "testbox run",
|
|
76
77
|
"dev": "node tests/stub-server.mjs",
|
|
77
78
|
"build": "npm run build:bevel && npm run build:skins && node build.js",
|
|
@@ -111,7 +112,7 @@
|
|
|
111
112
|
"marked": "18.0.14",
|
|
112
113
|
"overtype": "2.6.1",
|
|
113
114
|
"parse5": "^7.3.0",
|
|
114
|
-
"playwright": "1.
|
|
115
|
+
"playwright": "1.64.1",
|
|
115
116
|
"postcss": "^8.5.28",
|
|
116
117
|
"prosemirror-commands": "1.7.2",
|
|
117
118
|
"prosemirror-dropcursor": "1.8.4",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { serializeRecoveryClone, captureRecoveryPage } from "./snapshot.js";
|
|
2
2
|
import { rowOf } from "./conflict-presentation.js";
|
|
3
3
|
import { documentName, downloadHtml } from "./download.js";
|
|
4
|
+
import { stripCopyContent } from "./copy-content.js";
|
|
4
5
|
|
|
5
6
|
export { documentName, downloadHtml };
|
|
6
7
|
|
|
@@ -31,12 +32,12 @@ export function buildRecovery(records, { refused = false } = {}) {
|
|
|
31
32
|
if (apply && !seen.has(apply.id)) { seen.add(apply.id); applies.push(apply); }
|
|
32
33
|
}
|
|
33
34
|
applies.sort((a, b) => (a.ticket || 0) - (b.ticket || 0));
|
|
34
|
-
const pageOf = (a) => serializeRecoveryClone(a.recoveryRoot ?? a.root, { prepared: a.domain === "save" });
|
|
35
|
+
const pageOf = (a) => stripCopyContent(serializeRecoveryClone(a.recoveryRoot ?? a.root, { prepared: a.domain === "save" }));
|
|
35
36
|
|
|
36
37
|
let html;
|
|
37
38
|
let older;
|
|
38
39
|
if (refused || !applies.length) {
|
|
39
|
-
html = captureRecoveryPage();
|
|
40
|
+
html = stripCopyContent(captureRecoveryPage());
|
|
40
41
|
older = applies;
|
|
41
42
|
} else {
|
|
42
43
|
html = pageOf(applies[applies.length - 1]);
|
|
@@ -66,9 +67,9 @@ export function buildRecovery(records, { refused = false } = {}) {
|
|
|
66
67
|
// The review panel's own copy: the page a reload kept, when there is one, with every
|
|
67
68
|
// stored row it drew listed beside it as JSON. The rows are already plain, so nothing
|
|
68
69
|
// here reads the ledger the tab no longer has.
|
|
69
|
-
export function downloadStored({ html = null, edits = [] } = {}) {
|
|
70
|
+
export async function downloadStored({ html = null, edits = [] } = {}) {
|
|
70
71
|
try {
|
|
71
|
-
const page = typeof html === "string" ? html : captureRecoveryPage();
|
|
72
|
+
const page = stripCopyContent(typeof html === "string" ? html : captureRecoveryPage());
|
|
72
73
|
const data = {
|
|
73
74
|
format: "clay-lost-edits",
|
|
74
75
|
version: 1,
|
|
@@ -78,17 +79,17 @@ export function downloadStored({ html = null, edits = [] } = {}) {
|
|
|
78
79
|
edits: Array.isArray(edits) ? edits : [],
|
|
79
80
|
earlierPages: [],
|
|
80
81
|
};
|
|
81
|
-
return downloadHtml({ html: embed(page, data), name: `${documentName()}-my-copy-${stamp()}.html` });
|
|
82
|
+
return await downloadHtml({ html: embed(page, data), name: `${documentName()}-my-copy-${stamp()}.html` });
|
|
82
83
|
} catch (err) {
|
|
83
84
|
console.error("clayjs: could not build the download", err);
|
|
84
85
|
return false;
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
|
|
88
|
-
export function downloadRecovery(records, { refused = false } = {}) {
|
|
89
|
+
export async function downloadRecovery(records, { refused = false } = {}) {
|
|
89
90
|
try {
|
|
90
91
|
const { html, name } = buildRecovery(records, { refused });
|
|
91
|
-
return downloadHtml({ html, name });
|
|
92
|
+
return await downloadHtml({ html, name });
|
|
92
93
|
} catch (err) {
|
|
93
94
|
console.error("clayjs: could not build the download", err);
|
|
94
95
|
return false;
|
|
@@ -707,12 +707,12 @@ async function onRevert() {
|
|
|
707
707
|
let downloadedTimer = null;
|
|
708
708
|
|
|
709
709
|
// Download my copy. Nothing here acknowledges or releases a record.
|
|
710
|
-
function onDownload() {
|
|
710
|
+
async function onDownload() {
|
|
711
711
|
const l = ledger();
|
|
712
712
|
// A refusal ends in a reload that takes every record with it, so its copy carries
|
|
713
713
|
// all of them; a replaced notice covers the rows it drew.
|
|
714
714
|
const records = refused ? (l?.list() ?? []) : renderedIds.map((id) => l?.get(id)).filter(Boolean);
|
|
715
|
-
const ok = downloadRecovery(records, { refused: !!refused });
|
|
715
|
+
const ok = await downloadRecovery(records, { refused: !!refused });
|
|
716
716
|
downloadFailed = !ok;
|
|
717
717
|
downloaded = ok;
|
|
718
718
|
clearTimeout(downloadedTimer);
|
|
@@ -801,14 +801,14 @@ async function onCopyStored(entry) {
|
|
|
801
801
|
|
|
802
802
|
// Download my copy, from the stored root: the page as this tab had it, with the
|
|
803
803
|
// losing text in it. Nothing here acknowledges or releases a record.
|
|
804
|
-
function onDownloadRecovered() {
|
|
804
|
+
async function onDownloadRecovered() {
|
|
805
805
|
const record = recovered.find((item) => item.root);
|
|
806
806
|
const edits = [];
|
|
807
807
|
for (const item of recovered) {
|
|
808
808
|
for (const entry of item.conflicts) edits.push({ id: entry.id, kind: entry.kind, name: storedName(entry), yours: entry.yours, now: entry.now, sentence: entry.sentence });
|
|
809
809
|
}
|
|
810
810
|
for (const entry of recoveredUndo) edits.push({ id: entry.id, kind: entry.kind, name: entry.name, yours: entry.yours, now: entry.now, sentence: entry.sentence });
|
|
811
|
-
const ok = downloadStored({ html: record?.root ?? null, edits });
|
|
811
|
+
const ok = await downloadStored({ html: record?.root ?? null, edits });
|
|
812
812
|
downloadFailed = !ok;
|
|
813
813
|
downloaded = ok;
|
|
814
814
|
clearTimeout(downloadedTimer);
|