@panphora/clayjs 1.14.0 → 1.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clay.standalone.js +1605 -1170
- package/dist/server/checkpoint.cjs +1 -70690
- package/dist/server/core.cjs +72210 -0
- package/dist/server/rooms.cjs +1 -72039
- package/docs/guide.md +36 -9
- package/entries/sap.js +5 -5
- package/package.json +1 -1
- package/packed-contract.json +1 -0
- package/src/core/boot-phase.js +6 -0
- package/src/core/conflict-download.js +1 -1
- package/src/core/save.js +94 -6
- package/src/core/snapshot.js +12 -0
- package/src/lib/derived.js +116 -0
- package/src/lib/mutation.js +3 -1
- package/src/lib/style.js +10 -7
- package/src/loader-logic.js +12 -4
- package/src/loader.js +31 -1
- package/src/page/blocks.js +61 -12
- package/src/page/editor.js +3 -1
- package/src/plugins/derive.js +12 -0
- package/src/plugins/undo.js +2 -1
- package/src/plugins/visitor-drafts/prompt-style.js +2 -1
- package/src/plugins/visitor-drafts/prompt.js +1 -1
- package/src/sync/conflict-revert.js +2 -0
- package/src/sync/conflicts.js +2 -2
- package/src/sync/live-sync.js +23 -6
- package/src/vendor/sap-core.vendor.js +9 -0
- package/src/vendor/sap-ownership.vendor.js +111 -0
package/src/plugins/undo.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { undo } from '../vendor/hyper-undo.vendor.js'
|
|
7
7
|
import { isEditMode } from '../core/is-edit-mode.js'
|
|
8
8
|
import { isTabLocalAttr } from '../lib/root-attrs.js'
|
|
9
|
+
import { isDerivedAttr } from '../lib/derived.js'
|
|
9
10
|
import { PERSIST } from '../lib/attr-aliases.js'
|
|
10
11
|
|
|
11
12
|
// Tab-local attributes (ephemeral state, route-active, root library state) are
|
|
@@ -15,7 +16,7 @@ const withTabLocal = (opts = {}) => {
|
|
|
15
16
|
const own = opts.ignoreAttribute
|
|
16
17
|
return {
|
|
17
18
|
...opts,
|
|
18
|
-
ignoreAttribute: (name, target) => isTabLocalAttr(name, target) || (own ? own(name, target) : false),
|
|
19
|
+
ignoreAttribute: (name, target) => isTabLocalAttr(name, target) || isDerivedAttr(target, name) || (own ? own(name, target) : false),
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -103,9 +103,10 @@ export const PROMPT_CSS = `.hcp {
|
|
|
103
103
|
}
|
|
104
104
|
.hcp .hcp-dock .hcp-x:hover { color: var(--hcp-ink); background: var(--hcp-face); }
|
|
105
105
|
.hcp-tab__label { display: inline; }
|
|
106
|
+
.hcp-tab__mini { display: none; }
|
|
107
|
+
.hcp[data-hcp-state="mini"] .hcp-tab__mini { display: inline; }
|
|
106
108
|
.hcp[data-hcp-state="mini"] .hcp-tab__label,
|
|
107
109
|
.hcp[data-hcp-state="mini"] .hcp-dock .hcp-x { display: none; }
|
|
108
|
-
.hcp[data-hcp-state="mini"] .hcp-tab { width: 34px; padding: 0; }
|
|
109
110
|
.hcp[data-hcp-state="card"] .hcp-dock { display: none; }
|
|
110
111
|
|
|
111
112
|
.hcp-card {
|
|
@@ -19,7 +19,7 @@ const ASIDE = `<aside class="hcp" id="hcp" hidden aria-label="Download this app"
|
|
|
19
19
|
<div class="hcp-foot"><button type="button" class="hcp-quiet" data-hcp="dismiss">Don’t show again</button></div>
|
|
20
20
|
</section>
|
|
21
21
|
<div class="hcp-dock">
|
|
22
|
-
<button type="button" class="hcp-btn hcp-tab" data-hcp="open" aria-controls="hcp-card" aria-expanded="false" aria-label="This app is free to keep"><span><svg width="16" height="16" viewBox="0 0 256 256" fill="currentColor" aria-hidden="true"><path d="M224,144v64a8,8,0,0,1-8,8H40a8,8,0,0,1-8-8V144a8,8,0,0,1,16,0v56H208V144a8,8,0,0,1,16,0Zm-101.66,5.66a8,8,0,0,0,11.32,0l40-40a8,8,0,0,0-11.32-11.32L136,124.69V32a8,8,0,0,0-16,0v92.69L93.66,98.34a8,8,0,0,0-11.32,11.32Z"/></svg><span class="hcp-tab__label">This app is free to keep</span></span></button>
|
|
22
|
+
<button type="button" class="hcp-btn hcp-tab" data-hcp="open" aria-controls="hcp-card" aria-expanded="false" aria-label="This app is free to keep"><span><svg width="16" height="16" viewBox="0 0 256 256" fill="currentColor" aria-hidden="true"><path d="M224,144v64a8,8,0,0,1-8,8H40a8,8,0,0,1-8-8V144a8,8,0,0,1,16,0v56H208V144a8,8,0,0,1,16,0Zm-101.66,5.66a8,8,0,0,0,11.32,0l40-40a8,8,0,0,0-11.32-11.32L136,124.69V32a8,8,0,0,0-16,0v92.69L93.66,98.34a8,8,0,0,0-11.32,11.32Z"/></svg><span class="hcp-tab__label">This app is free to keep</span><span class="hcp-tab__mini">Keep</span></span></button>
|
|
23
23
|
<button type="button" class="hcp-x" data-hcp="minimize" aria-label="Minimize download notice"><svg width="12" height="12" viewBox="0 0 12 12" fill="currentColor" aria-hidden="true"><path d="M1.4 0 6 4.6 10.6 0 12 1.4 7.4 6 12 10.6 10.6 12 6 7.4 1.4 12 0 10.6 4.6 6 0 1.4z"/></svg></button>
|
|
24
24
|
</div>
|
|
25
25
|
</aside>`;
|
|
@@ -4,6 +4,7 @@ import { protectionOf, protectionGeneration, captureFootprintWitnesses, footprin
|
|
|
4
4
|
import { SYNC_IGNORE_SELECTOR, REMOTE_WINS_SELECTOR } from "./live-sync.js";
|
|
5
5
|
import { savePage } from "../core/save.js";
|
|
6
6
|
import { gateMarkDirty } from "../lib/dirty-gate.js";
|
|
7
|
+
import { repaintDerived } from "../lib/derived.js";
|
|
7
8
|
import Mutation from "../lib/mutation.js";
|
|
8
9
|
import { markExplicitSave } from "../lib/user-gesture.js";
|
|
9
10
|
import { enableContentEditable } from "../core/admin-contenteditable.js";
|
|
@@ -1136,6 +1137,7 @@ export async function revertConflicts(ids) {
|
|
|
1136
1137
|
await Promise.resolve();
|
|
1137
1138
|
const plan = prepareRevert(ids);
|
|
1138
1139
|
const revertedIds = applyRevert(plan);
|
|
1140
|
+
repaintDerived();
|
|
1139
1141
|
let saveResult = null;
|
|
1140
1142
|
if (revertedIds.length) {
|
|
1141
1143
|
gateMarkDirty();
|
package/src/sync/conflicts.js
CHANGED
|
@@ -56,9 +56,9 @@ function install(apply, raw) {
|
|
|
56
56
|
return id;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
export function beginApply({ source, seq = null, etag = null, domain, root }) {
|
|
59
|
+
export function beginApply({ source, seq = null, etag = null, domain, root, recoveryRoot = null }) {
|
|
60
60
|
const id = nextId('a');
|
|
61
|
-
applies.set(id, { id, source, seq, etag, ticket: 0, domain, root, ids: new Set() });
|
|
61
|
+
applies.set(id, { id, source, seq, etag, ticket: 0, domain, root, recoveryRoot, ids: new Set() });
|
|
62
62
|
pending.add(id);
|
|
63
63
|
register().changed();
|
|
64
64
|
return id;
|
package/src/sync/live-sync.js
CHANGED
|
@@ -62,6 +62,7 @@ import { SyncStream } from './stream.js';
|
|
|
62
62
|
import { streamOpened, streamClosed, streamEvent, LIVE_EVENTS } from '../live/stream-bridge.js';
|
|
63
63
|
import { conflicts, beginApply, completeApply, failApply } from './conflicts.js';
|
|
64
64
|
import { beginLineageCapture } from './conflict-footprints.js';
|
|
65
|
+
import { isDerivedAttr, ownsDerivedText, stripDerived, repaintDerived, paintSignatureOfHtml, derivedActive } from '../lib/derived.js';
|
|
65
66
|
|
|
66
67
|
// What a live-sync merge never reads or touches on any side: editor chrome,
|
|
67
68
|
// content kept out of the save or the snapshot, the contents of frozen regions,
|
|
@@ -78,11 +79,13 @@ const SYNC_IGNORE_SELECTOR = [
|
|
|
78
79
|
// A frozen element is a scratchpad: the element is part of the document and
|
|
79
80
|
// merges like any other, but its contents belong to this tab. Every merge input
|
|
80
81
|
// has its frozen elements emptied, and hyper-morph's opaque option leaves the
|
|
81
|
-
// live contents alone.
|
|
82
|
+
// live contents alone. Painted output (lib/derived.js) is left out of every
|
|
83
|
+
// input the same way, and the engine repaints it once the merge has applied.
|
|
82
84
|
const FREEZE_SELECTOR = '[clay~="freeze"], [freeze], [save-freeze]';
|
|
83
85
|
|
|
84
86
|
function emptyScratchpads(root) {
|
|
85
87
|
for (const el of root.querySelectorAll(FREEZE_SELECTOR)) el.replaceChildren();
|
|
88
|
+
if (derivedActive()) stripDerived(root);
|
|
86
89
|
return root;
|
|
87
90
|
}
|
|
88
91
|
|
|
@@ -187,7 +190,7 @@ function pairedBaseline() {
|
|
|
187
190
|
const { forComparison, forDirty } = captureForComparisonAndDirty({ flushUndo: false });
|
|
188
191
|
return [forComparison, forDirty];
|
|
189
192
|
}
|
|
190
|
-
import { savePageThrottled, setLastSavedBaselines, setUnsavedChanges, getLastSavedBytes, conflictResolvedBySync, isSaveConflicted, baselineSettled } from '../core/save.js';
|
|
193
|
+
import { savePageThrottled, setLastSavedBaselines, setUnsavedChanges, getLastSavedBytes, conflictResolvedBySync, isSaveConflicted, baselineSettled, schedulePaintHeal } from '../core/save.js';
|
|
191
194
|
|
|
192
195
|
/**
|
|
193
196
|
* The two live-sync wires, and the rule for choosing between them.
|
|
@@ -1702,9 +1705,9 @@ class LiveSync {
|
|
|
1702
1705
|
live: document,
|
|
1703
1706
|
remote,
|
|
1704
1707
|
ignore: (el) => el.matches(SYNC_IGNORE_SELECTOR),
|
|
1705
|
-
opaque: (el) => el.matches(FREEZE_SELECTOR),
|
|
1708
|
+
opaque: (el) => el.matches(FREEZE_SELECTOR) || (derivedActive() && ownsDerivedText(el)),
|
|
1706
1709
|
remoteWins: (el) => el.matches(REMOTE_WINS_SELECTOR),
|
|
1707
|
-
ignoreAttribute: isRootLocalAttr,
|
|
1710
|
+
ignoreAttribute: (el, name, merged) => isRootLocalAttr(el, name, merged) || (derivedActive() && isDerivedAttr(merged || el, name)),
|
|
1708
1711
|
protectFocusedValue: true,
|
|
1709
1712
|
keepLiveOnly: source === 'peer',
|
|
1710
1713
|
scripts: { mergeTags: mergeTagRecognizers },
|
|
@@ -1754,9 +1757,13 @@ class LiveSync {
|
|
|
1754
1757
|
},
|
|
1755
1758
|
});
|
|
1756
1759
|
} else {
|
|
1757
|
-
|
|
1760
|
+
const captured = captureLocal();
|
|
1761
|
+
// Download my copy serializes the page as it was, painted values included;
|
|
1762
|
+
// the merge itself needs them stripped.
|
|
1763
|
+
const recoveryRoot = captured.cloneNode(true);
|
|
1764
|
+
localRoot = emptyScratchpads(captured);
|
|
1758
1765
|
applyId = beginApply({
|
|
1759
|
-
source, seq, etag, root: localRoot,
|
|
1766
|
+
source, seq, etag, root: localRoot, recoveryRoot,
|
|
1760
1767
|
domain: source === 'disk' ? 'save' : 'sync',
|
|
1761
1768
|
});
|
|
1762
1769
|
try {
|
|
@@ -1912,6 +1919,7 @@ class LiveSync {
|
|
|
1912
1919
|
});
|
|
1913
1920
|
diverged = report.localDiverged;
|
|
1914
1921
|
typedDuringWait = typed;
|
|
1922
|
+
repaintDerived();
|
|
1915
1923
|
|
|
1916
1924
|
// Restore viewport. Done after morph so layout has settled.
|
|
1917
1925
|
window.scrollTo(scrollX, scrollY);
|
|
@@ -2038,6 +2046,7 @@ class LiveSync {
|
|
|
2038
2046
|
* local edits.
|
|
2039
2047
|
*/
|
|
2040
2048
|
async _doApplyExternal(html, seq, etag = null, by = null, fetchOptions = null) {
|
|
2049
|
+
const priorDisk = this._diskBase;
|
|
2041
2050
|
this._log(`applyExternal - external disk change (seq=${seq})`);
|
|
2042
2051
|
this.isPaused = true;
|
|
2043
2052
|
|
|
@@ -2114,6 +2123,7 @@ class LiveSync {
|
|
|
2114
2123
|
});
|
|
2115
2124
|
diverged = report.localDiverged;
|
|
2116
2125
|
typedDuringWait = typed;
|
|
2126
|
+
repaintDerived();
|
|
2117
2127
|
// The file holds these bytes and this tab has applied them. Dated at the
|
|
2118
2128
|
// apply, so a save that captured during the await keeps its newer base.
|
|
2119
2129
|
this._setDiskBase(html, ticket);
|
|
@@ -2191,6 +2201,13 @@ class LiveSync {
|
|
|
2191
2201
|
// autosave is on, as in the peer lane.
|
|
2192
2202
|
if (stamped) conflictResolvedBySync(etag);
|
|
2193
2203
|
this._saveAfterMerge(diverged, typedDuringWait);
|
|
2204
|
+
// A disk frame from a writer that does not paint (an agent, the data API)
|
|
2205
|
+
// changes records and leaves the painted values as they were. If the page's
|
|
2206
|
+
// repainted values differ from them once the timer fires, one tab saves so
|
|
2207
|
+
// the bytes on disk heal. A writer that paints is left alone.
|
|
2208
|
+
if (priorDisk != null && paintSignatureOfHtml(priorDisk) === paintSignatureOfHtml(html)) {
|
|
2209
|
+
schedulePaintHeal(() => (this._diskBase == null ? null : paintSignatureOfHtml(this._diskBase)));
|
|
2210
|
+
}
|
|
2194
2211
|
}
|
|
2195
2212
|
|
|
2196
2213
|
/**
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// GENERATED — do not edit. Vendored from sapjs/dist/sap-core.min.js via sapjs
|
|
2
|
+
// `npm run copy-to-clayjs`. Edit the sapjs source and re-run.
|
|
3
|
+
var SapCoreBundle=(()=>{var st=Object.defineProperty;var Ce=Object.getOwnPropertyDescriptor;var $e=Object.getOwnPropertyNames;var Pe=Object.prototype.hasOwnProperty;var Me=(t,e)=>{for(var r in e)st(t,r,{get:e[r],enumerable:!0})},Oe=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of $e(e))!Pe.call(t,o)&&o!==r&&st(t,o,{get:()=>e[o],enumerable:!(n=Ce(e,o))||n.enumerable});return t};var Ie=t=>Oe(st({},"__esModule",{value:!0}),t);var Sn={};Me(Sn,{FULL_SAPJS:()=>U,Sap:()=>q,default:()=>vn,mount:()=>An,mountAll:()=>_e,needsFullSapjs:()=>St,runtime:()=>En});function Nt(t){let e=!1,r=new Set,n=[];function o(a){a&&(n.push(a),n.length>8&&n.shift())}function u(a,m){o(m),!a._broken&&(r.add(a),!e&&(e=!0,queueMicrotask(i)))}function i(){e=!1;let a=[...r];r.clear();for(let m of a)d(m)}function d(a,m=!1){if(!(a._broken||a.halted)){if(a._passes=(a._passes||0)+1,a._passes>50){a._broken=!0,a._breakerRing=n.slice(),t(a,{breaker:!0});return}a._resetArmed||(a._resetArmed=!0,setTimeout(()=>{a._passes=0,a._resetArmed=!1},0)),t(a,m?{full:!0}:{})}}function l(a,m){o(m),d(a,!0)}function c(a){a._broken=!1,a._passes=0}return{schedule:u,runNow:l,rearm:c,ring:n}}var at={E01:{slug:"foreign-dialect",behavior:"HALT"},E02:{slug:"moustaches-in-text",behavior:"HALT"},E04:{slug:"duplicate-declaration",behavior:"HALT"},E05:{slug:"reserved-name",behavior:"HALT"},E06:{slug:"global-html-name",behavior:"HALT"},E07:{slug:"calc-cycle",behavior:"ERR"},E08:{slug:"expression-syntax",behavior:"HALT"},E10:{slug:"orphan-item",behavior:"HALT"},E12:{slug:"unknown-state-key",behavior:"ERR"},E15:{slug:"write-to-undeclared-key",behavior:"ERR"},E16:{slug:"write-to-computed-field",behavior:"ERR"},E17:{slug:"unresolvable-action-target",behavior:"HALT"},E18:{slug:"paint-on-form-control",behavior:"HALT"},E20:{slug:"bind-on-non-control",behavior:"HALT"},E22:{slug:"format-type",behavior:"ERR"},E24:{slug:"runtime-expression-throw",behavior:"ERR"},E26:{slug:"circuit-breaker",behavior:"HALT"},E30:{slug:"attr-on-bound-control",behavior:"HALT"},E31:{slug:"password-without-transient",behavior:"HALT"},E32:{slug:"file-bind",behavior:"HALT"},E33:{slug:"dialog-state-open",behavior:"HALT"},E34:{slug:"transient-persist-collision",behavior:"HALT"},E35:{slug:"presence-state-misuse",behavior:"HALT"},E40:{slug:"each-not-array",behavior:"ERR"},E41:{slug:"each-bad-key",behavior:"ERR"},E42:{slug:"each-template",behavior:"ERR"},E43:{slug:"bind-in-each-row",behavior:"ERR"},E50:{slug:"needs-full-sapjs",behavior:"HALT"},W03:{slug:"unknown-colon-attribute",behavior:"WARN"},W04:{slug:"expression-in-when",behavior:"WARN"},W30:{slug:"nonzero-mount-writes",behavior:"WARN"},W31:{slug:"detail-dialog-saved-open",behavior:"WARN"}},O=["disabled","readonly","required","checked","selected","multiple","open","inert","autofocus","novalidate","hidden"],ut=new Set(["title","style","hidden","lang","dir","translate","class","id","nonce","autofocus","tabindex","contenteditable","spellcheck","draggable","role","slot","part","name","value","type","itemscope","itemtype","itemid","itemprop","itemref"]),Tt=new Set(["sap","scope","items","item","template","bind","calc","text","show","attr","set","trigger","move","sort","detail","each","effect","invalid","confirm","transient","default","persist","sortable","editmode"]);function De(t){if(!t||t.nodeType!==1)return"?";if(t.id)return`${t.tagName.toLowerCase()}#${t.id}`;let e=[],r=t,n=0;for(;r&&r.nodeType===1&&n<4;){let o=r.tagName.toLowerCase();if(r.hasAttribute("sap"))o+="[sap]";else if(r.parentElement){let u=0,i=0;for(let d=r.parentElement.firstElementChild;d;d=d.nextElementSibling)d.tagName===r.tagName&&(u++,d===r&&(i=u));u>1&&(o+=`:nth-of-type(${i})`)}if(e.unshift(o),r.hasAttribute("sap"))break;r=r.parentElement,n++}return e.join(" > ")}var Y=class{constructor(e){this.appName=e,this.errors=[],this.warnings=[],this.halted=!1,this.haltReason=null}block(e,r,n={}){let o=(at[e]||{}).slug||"error",u={code:e,slug:o,el:De(r),attr:n.attr||null,expr:n.expr||null,key:n.key||null,problem:n.problem||"",didYouMean:n.didYouMean||null,fix:n.fix||null,phase:n.phase||"runtime"},i=[`
|
|
4
|
+
`+(e[0]==="W"?"sap \u26A0 ":"sap \u2717 ")+e+" "+o];return i.push(` at ${u.el}${u.attr?` \u2014 ${u.attr}="${u.expr??""}"`:""}`),u.problem&&i.push(` problem: ${u.problem}`),u.didYouMean&&i.push(` did you mean: ${u.didYouMean}`),u.fix&&i.push(` fix: ${u.fix}`),(e[0]==="W"?console.warn:console.error)(i.join(`
|
|
5
|
+
`)),u}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 P(t,e){t&&t.getAttribute("sap-error")!==e&&t.setAttribute("sap-error",e)}function Lt(t){t&&t.hasAttribute("sap-error")&&t.removeAttribute("sap-error")}function ct(t,e){let r=null,n=3;for(let o of e){let u=Be(t,o);u<n&&(n=u,r=o)}return r}function Be(t,e){let r=t.length,n=e.length,o=Array.from({length:r+1},(u,i)=>[i,...new Array(n).fill(0)]);for(let u=0;u<=n;u++)o[0][u]=u;for(let u=1;u<=r;u++)for(let i=1;i<=n;i++)o[u][i]=Math.min(o[u-1][i]+1,o[u][i-1]+1,o[u-1][i-1]+(t[u-1]===e[i-1]?0:1));return o[r][n]}var Fe=new Set(O),We={readonly:"readOnly",novalidate:"noValidate"},ze=0,_t=new WeakMap;function Rt(t,e="sap"){let r=t.getAttribute("data-id");if(r)return r;if(t.id)return t.id;let n=_t.get(t);return n||(n=`${e}-${(ze++).toString(36)}`,_t.set(t,n)),n}function Ct(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 lt(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 $t(t){for(let e=t.firstElementChild;e;e=e.nextElementSibling)if(e.hasAttribute("item")&&e.hasAttribute("template"))return e;return lt(t.closest("[sap]"),t.getAttribute("items"))}function G(t){let e=[];if(!t)return e;for(let r of t.trim().split(/\s+/)){if(!r)continue;let n=r,o,u=n.indexOf("=");u>=0&&(o=n.slice(u+1),n=n.slice(0,u));let i=n.split(":"),d=i[0],l="string",c=!1;for(let g of i.slice(1))g==="num"?l="num":g==="bool"?l="bool":g==="presence"?l="presence":g==="transient"&&(c=!0);let a=d,m=a.startsWith("data-")&&a.length>5?a.slice(5).replace(/-([a-z])/g,(g,A)=>A.toUpperCase()):a;e.push({name:m,attr:a,type:l,default:o,transient:c})}return e}function X(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 Pt(t,e){return e==="bool"?t?"true":"false":t==null?"":String(t)}function ft(t,e){return Fe.has(e)&&typeof t[We[e]||e]=="boolean"}function Mt(t,e){return e.type==="presence"||e.type!=="num"&&ft(t,e.attr||e.name)}function dt(t){return t.default!=null?t.default:t.type==="num"?"0":t.type==="bool"?"false":""}function Ot(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=dt(e)),n[e.name]=X(o,e.type)}return t.hasAttribute(r)&&t.removeAttribute(r),n[e.name]}function S(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 K(t,e){return Array.isArray(t)?e==null?t:t.map(r=>typeof e=="function"?e(r):r?.[e]):[]}function pt(t,e){return K(t,e).reduce((r,n)=>r+S(n),0)}function It(t,e){return Array.isArray(t)?e==null?t.length:t.reduce((r,n)=>r+(e(n)?1:0),0):0}function Dt(t,e){let r=K(t,e);return r.length?pt(t,e)/r.length:0}function Bt(t,e){let r=K(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 Ft(t,e){let r=K(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 Wt(t,e,r){let n=S(t)===1?e:r??e+"s";return`${t} ${n}`}function zt(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 T(t){return typeof t=="number"?t:Number(t)}var I={usd:t=>"$"+T(t).toLocaleString("en-US",{maximumFractionDigits:0}),usd2:t=>"$"+T(t).toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}),pct:t=>Math.round(T(t))+"%",pct1:t=>T(t).toFixed(1)+"%",int:t=>Math.round(T(t)).toLocaleString("en-US"),num:t=>T(t).toLocaleString("en-US"),num2:t=>T(t).toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}),compact:t=>T(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=T(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}`}},He=new Set(["usd","usd2","pct","pct1","int","num","num2","compact","clock"]);function Ht(t,e){if(!t)return e==null?"":String(e);let r=I[t];if(typeof r!="function"){let n=new Error(`unknown format "${t}"`);throw n.sapCode="E22",n}if(He.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 je=["state","item","el","root","fmt","num","sum","count","avg","min","max","plural","days"],J=new Map,jt=/\bstate\.([a-z][a-z0-9_]*)/g,Ut=/\bitem\.([a-z][a-z0-9_]*)/g;function Ue(t){let e=new Set,r=new Set,n;for(jt.lastIndex=0;n=jt.exec(t);)e.add(n[1]);for(Ut.lastIndex=0;n=Ut.exec(t);)r.add(n[1]);return{state:e,item:r}}function N(t,e=!1){let r=(e?"!":"")+t,n=J.get(r);if(n)return n;J.size>512&&J.clear();try{let o=e?`"use strict";
|
|
6
|
+
${t}`:`"use strict"; return (${t});`;n={fn:new Function(...je,o),src:t,statement:e,deps:Ue(t),error:null}}catch(o){n={fn:null,src:t,statement:e,deps:{state:new Set,item:new Set},error:o}}return J.set(r,n),n}function qt(t,e,r,n,o){if(t.error)throw t.error;return t.fn(e,r,n,o,I,S,pt,It,Dt,Bt,Ft,Wt,zt)}var j={},H=null,Yt=!0,Z=!1;function Gt(){j={}}function Xt(t){let e=Z;return H?Jt(H.takeRecords()):Yt&&qe(),Z=!!H&&t.getRootNode()===document,e}function Kt(t){Z=t}function qe(){if(typeof document>"u"||typeof MutationObserver!="function"){Yt=!1;return}H=new MutationObserver(Jt),H.observe(document,{attributes:!0,childList:!0,subtree:!0})}function Jt(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&&Qt(r)}function Qt(t){t._sapPlan&&(t._sapPlan=null);for(let e=t.firstElementChild;e;e=e.nextElementSibling)Qt(e)}function tt(t){if(!Z)return Vt(t);let e=t._sapPlan;return e&&e.gen===j?e:t._sapPlan=Vt(t)}function Vt(t){let e={gen:j,inert:t.tagName==="TEMPLATE",template:!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,u=n.indexOf(":");if(u<0){switch(n){case"sap-ignore":e.inert=!0;break;case"cms-template":e.inert=!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=G(o);break;case"text":(e.paints||(e.paints=[])).push({kind:"text",fmt:null,entry:N(o)});break;case"show":(e.paints||(e.paints=[])).push({kind:"show",entry:N(o)});break;case"effect":(e.effects||(e.effects=[])).push({entry:N(o,!0)});break;case"invalid":(e.invalids||(e.invalids=[])).push({entry:N(o)});break}continue}let i=n.slice(0,u),d=n.slice(u+1);switch(i){case"calc":(e.calcs||(e.calcs=[])).push({name:d,entry:N(o)});break;case"text":(e.paints||(e.paints=[])).push({kind:"text",fmt:d,entry:N(o)});break;case"attr":(e.paints||(e.paints=[])).push({kind:"attr",arg:d,entry:N(o)});break;case"class":(e.paints||(e.paints=[])).push({kind:"class",arg:d,entry:N(o)});break;case"css":(e.paints||(e.paints=[])).push({kind:"css",arg:d,entry:N(o)});break;case"show-when":case"option":(e.paints||(e.paints=[])).push({kind:"when",match:"show",field:d,values:o.split("|")});break;case"hide-when":(e.paints||(e.paints=[])).push({kind:"when",match:"hide",field:d,values:o.split("|")});break;case"option-not":(e.paints||(e.paints=[])).push({kind:"when",match:"show-not",field:d,values:o.split("|")});break}}return e.boundary=e.scope?"scope":e.items?"items":e.detail?"detail":e.each?"each":null,Ye(e)?Ve():e}var Q=null;function Ve(){return(!Q||Q.gen!==j)&&(Q=Object.freeze({gen:j,inert:!1,template:!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})),Q}function Ye(t){return!t.inert&&!t.item&&t.boundary===null&&t.bind===null&&!t.transient&&!t.decls&&!t.calcs&&!t.paints&&!t.effects&&!t.invalids}function Zt(t){return(t.getAttribute("type")||"text").toLowerCase()}function D(t){let e=t.tagName;if(e==="INPUT"){let r=Zt(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 te(t,e=t){let r=t.tagName;if(r==="INPUT"){let n=Zt(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(`
|
|
7
|
+
`)?`
|
|
8
|
+
`+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 u=0;u<n.length;u++)o[u]&&o[u].selected?n[u].hasAttribute("selected")||n[u].setAttribute("selected",""):n[u].removeAttribute("selected")}}function et(t){t.tagName!=="TEXTAREA"||!t.hasAttribute("data-value")||t!==t.ownerDocument.activeElement&&(t.textContent=t.getAttribute("data-value"),t.removeAttribute("data-value"))}function w(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 ee(){let t=w("visitorDrafts");return!!(t&&typeof t.restored=="function"&&t.restored()?.restored)}var mt=["clay:mutation-ready","hyperclay:mutation-ready"],Ge=["clay:sync-applied","hyperclay:livesync-applied"],Xe=["clay:ready","hyperclay:ready"],Ke=["clay:route"];function B(t,e,r){let n=null,o=u=>{n!==null&&n!==u.type||(n=u.type,queueMicrotask(()=>{n=null}),r(u))};for(let u of e)t.addEventListener(u,o);return()=>{for(let u of e)t.removeEventListener(u,o)}}function ne(t){let e=typeof window<"u"&&window.clay&&window.clay.ready;e&&typeof e.then=="function"?e.then(()=>t(),()=>t()):t()}function nt(t){let e=w("region");return!e||typeof e.resolveRegionPolicy!="function"||typeof e.skipForPolicy!="function"?!1:e.skipForPolicy(e.resolveRegionPolicy(t),void 0,["no-save","freeze"])}function re(t,e){if(typeof e!="function")throw new Error("Sap.batch(label, fn): fn must be a function");let r=w("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 oe(t){if(typeof window>"u"||typeof document>"u")return;let e=()=>{let c=!1;for(let a of t.apps())a.root.isConnected?t.runNow(a,"platform"):c=!0;c&&t.pruneDisconnected(),t.remountIfPresent()},r=w("derived"),n=r&&typeof r.register=="function"?r.register(e):null,o=typeof n=="function"?null:B(document,Ge,e),u=B(document,Ke,e),i=!1,d=()=>{},l=()=>{if(i)return!0;let c=w("undo");if(!c||typeof c.on!="function")return!1;let a=c.on("undo",e);return typeof a!="function"?!1:typeof c.on("redo",e)!="function"?(a(),!1):(i=!0,d(),!0)};if(!l()){let c=B(document,mt,l),a=B(document,Xe,l);d=()=>{c(),a()};let m=w("ready");m&&typeof m.then=="function"&&m.then(l,()=>{})}return()=>{typeof n=="function"&&n(),o&&o(),u(),d()}}function ht(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 Je(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 se(t,e){switch(e){case"checkbox":return t.checked;case"radio":return t.checked?t.value:void 0;case"number":return Je(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 Qe(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 ie(t){if(t.hasAttribute("transient")){t.removeAttribute("value"),t.removeAttribute("checked"),t.removeAttribute("data-value");return}nt(t)||D(t)}function Ze(t){t.dispatchEvent(new Event("input",{bubbles:!0})),t.dispatchEvent(new Event("change",{bubbles:!0}))}function ae(t,e){return se(t,e)}function ue(t){let e=ht(t);return{el:t,kind:e,read(){return se(t,e)},write(r,n={}){Qe(t,e,r),n.noMirror||ie(t),n.silent||Ze(t)},mirror(){ie(t)}}}var _=null,ot=!1,F=null;function ce(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 tn(){let t=null;return{kind:"native",subscribe(e){t=new MutationObserver(n=>e(en(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=w("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 en(t){let e=[];for(let r of t)if(r.type==="attributes"){let n=r.target;n&&n.nodeType===1&&!rt(n)&&e.push({type:"attribute",element:n})}else if(r.type==="characterData"){let n=r.target&&r.target.parentElement;n&&!rt(n)&&e.push({type:"characterData",element:n})}else if(r.type==="childList"){for(let n of r.addedNodes)if(!(n.nodeType!==1||rt(n))&&(e.push({type:"add",element:n}),n.querySelectorAll))for(let o of n.querySelectorAll("*"))rt(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 rt(t){return!!(t.closest&&t.closest("[sap-ignore],[template],[cms-template]"))}function nn(t,e){t.pruneDisconnected();let r=new Set,n=!1;for(let o of e){let u=o.type==="remove"?o.parent:o.element,i=u&&t.appFor(u);i&&r.add(i),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 le(t){if(_)return _.suppress(t);let e=w("undo");if(e&&e.pause&&e.resume){e.pause();try{return t()}finally{e.resume()}}return t()}function bt(t,e){ot=!0,_=t,t.subscribe(r=>nn(e,r))}function gt(t){if(ot||typeof window>"u"||typeof document>"u")return;let e=w("Mutation");if(e&&typeof e.onAnyChange=="function"){bt(ce(e),t);return}typeof MutationObserver=="function"&&(bt(tn(),t),F=B(document,mt,function(){let n=w("Mutation");n&&(F(),F=null,_&&_.teardown(),ot=!1,bt(ce(n),t))}))}function yt(){if(_)try{_.teardown()}catch{}F&&typeof document<"u"&&F(),_=null,ot=!1,F=null}var rn=new Set(O),R=[],de={},pe={};function me(t){R.includes(t)||(R.push(t),t.boundary&&Object.assign(de,t.boundary),t.paintKinds&&Object.assign(pe,t.paintKinds))}function it(t,e={}){if(e.breaker){t.diag.error("E26",t.root,{problem:"recompute loop halted after 50 passes; recent triggers: "+(t._breakerRing||[]).join(", ")}),P(t.root,"loop");return}e.full&&Gt();let r=Xt(t.root);try{le(()=>on(t,e))}finally{Kt(r)}t._viewsChanged&&(t._viewsChanged=!1,t.root.dispatchEvent(new CustomEvent("sap:views-updated",{bubbles:!0})))}function on(t,e){let r=t.root,n={},o=[],u=[],i=new Set;t.diag.errors=[];let d={root:n,state:n,item:null,ownerEl:r,projection:!1};function l(s,f){let h=f.attr||f.name,p=s.getAttribute(h);return p==null&&(p=dt(f),u.push({el:s,name:f.name,attr:h,value:Pt(X(p,f.type),f.type)})),X(p,f.type)}function c(s,f,h){let p=f.decls;if(p)for(let b of p){if(b.transient){h[b.name]=Ot(s,b);continue}if(Mt(s,b)){h[b.name]=s.hasAttribute(b.attr);continue}h[b.name]=l(s,b)}}function a(s,f,h){let p=f.bind,b=h.item||h.state,$=ht(s);$==="radio"?(p in b||(b[p]=""),s.checked&&(b[p]=s.value)):b[p]=ae(s,$),f.transient&&(s.removeAttribute("value"),s.removeAttribute("checked"))}function m(s,f,h){if(f.paints)for(let p of f.paints)p.kind==="when"&&i.add(p.field),o.push({def:p,el:s,ctx:h});for(let p of R)p.collect&&p.collect(v,s,f,h)}function g(s,f,h){Object.defineProperty(s,"$key",{value:Rt(f,"row"),enumerable:!1}),Object.defineProperty(s,"$index",{value:h,enumerable:!1}),Object.defineProperty(s,"$el",{value:f,enumerable:!1})}function A(s,f,h){let p=tt(s);c(s,p,f),s._sapScope=f,!h.projection&&p.bind!=null&&a(s,p,h),m(s,p,h),p.items?z(s,f,h):E(s,f,h)}function E(s,f,h){for(let p=s.firstElementChild;p;p=p.nextElementSibling)x(p,f,h)}function x(s,f,h){let p=tt(s);if(!p.inert){if(p.boundary){p.boundary==="scope"?k(s,f,h):p.boundary==="items"?(m(s,p,h),z(s,f,h)):de[p.boundary](v,s,p,f,h);return}!h.projection&&!h.view&&p.bind!=null&&a(s,p,h),m(s,p,h);for(let b=s.firstElementChild;b;b=b.nextElementSibling)x(b,f,h)}}function k(s,f,h){let p=s.getAttribute("scope"),b={};f[p]=b;let $={root:h.root,state:b,item:null,ownerEl:s,projection:h.projection};A(s,b,$)}function z(s,f,h){let p=s.getAttribute("items"),b=[];f[p]=b,s._sapList=b;let $=0;for(let L=s.firstElementChild;L;L=L.nextElementSibling){let kt=tt(L);if(!kt.item||kt.template||L.hasAttribute("cms-template"))continue;let V={};g(V,L,$);let Re={root:h.root,state:h.state,item:V,ownerEl:L,projection:h.projection};A(L,V,Re),b.push(V),$++}}let v={app:t,root:r,rootObj:n,paints:o,stats:{calcs:0,lists:0},resolveDefault:l,collectEl:m,walkScope:E};for(let s of R)s.begin&&s.begin(v);if(A(r,n,d),t.halted)return;for(let s of R)s.afterIntake&&s.afterIntake(v);if(u.length&&i.size)for(let s of u)i.has(s.attr)&&s.el.getAttribute(s.attr)==null&&s.el.setAttribute(s.attr,s.value);for(let s of R)s.compute&&s.compute(v);let M=0;for(let s of R)s.reconcile&&(M+=s.reconcile(v));let C=0,y=M;for(let s of o){let f=an(s,t);s.ctx.view?y+=f:C+=f}for(let s of R)s.afterPaint&&s.afterPaint(v);t._state=n,t._stats={fields:Object.keys(n).filter(s=>typeof n[s]!="function").length,calcs:v.stats.calcs,paints:o.length,lists:v.stats.lists,writes:C,viewWrites:y},t._viewsChanged=y>0,t._lastPass={trigger:e.trigger||"refresh",writes:C},t._debug&&console.log(`sap pass \xB7 trigger: ${t._lastPass.trigger} \xB7 writes ${C}/${o.length}`)}function sn(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 wt(t,e,r,n){let o=t;for(;o&&o.nodeType===1;){if(o.hasAttribute&&o.hasAttribute(e)){let u=r.includes(o.getAttribute(e));if(n?!u:u)return!0}o=o.parentElement}return!1}function an(t,e){let r=t.def,n=t.el,o=pe[r.kind];if(o)return o(t,e);if(r.kind==="when")return fe(r,n,null);try{let u=qt(r.entry,t.ctx.state,t.ctx.item,n,t.ctx.root),i=fe(r,n,u);return Lt(n),i}catch(u){return e.diag.error(u.sapCode==="E22"?"E22":"E24",n,{attr:sn(r),expr:r.entry&&r.entry.src,problem:String(u.message)}),P(n,u.sapCode||"E24"),0}}function fe(t,e,r){switch(t.kind){case"text":{let n=t.fmt!=null?Ht(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=w("optionVisibility");if(n&&n._started)return e._sapWhen&&e.hidden?(e.hidden=!1,e._sapWhen=!1,1):0;let o;t.match==="hide"?o=!wt(e,t.field,t.values,!1):t.match==="show-not"?o=wt(e,t.field,t.values,!0):o=wt(e,t.field,t.values,!1),e._sapWhen=!0;let u=!o;return e.hidden!==u?(e.hidden=u,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 u=0;return e[n]!==!!r&&(e[n]=!!r,u=1),!!r!==e.hasAttribute(n)&&(r?e.setAttribute(n,""):e.removeAttribute(n),u=1),u}if(rn.has(n)){let u=e.hasAttribute(n);return r&&!u?(e.setAttribute(n,""),1):!r&&u?(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 un=new Set(O),he=new Set(["calc","text","attr","class","css","set","move","sort","option","option-not","show-when","hide-when","editmode"]),cn=new Set(["show-when","hide-when","option","option-not"]),ln=/\b(?:state|item|root)\.|===|!==|&&|\|\||[()]|^\s*!/,be=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"]),Et=[];function ge(t){Et.includes(t)||Et.push(t)}function fn(t){return t.tagName==="INPUT"||t.tagName==="SELECT"||t.tagName==="TEXTAREA"}function At(t){return t.hasAttribute("bind")}function dn(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 ye(t,e){let r=!1,n=(i,d,l)=>{e.error(i,d,l),r=!0},o=t.ownerDocument.createTreeWalker(t,4),u;for(;u=o.nextNode();)if(/\{\{.*\}\}/.test(u.nodeValue||"")){n("E02",u.parentElement||t,{problem:"moustaches in text content are not a Sap feature",fix:'move the expression onto the element: text="state.x"'});break}return dn(t,i=>{let d=new Set;for(let c of Et)c(i,n,a=>d.add(a));let l=i.closest&&i.closest("[detail]");for(let c of[...i.attributes]){let a=c.name;if(d.has(a))continue;if(a.includes(":")){let g=a.slice(0,a.indexOf(":"));if(he.has(g)){if(cn.has(g)&&ln.test(c.value)){let A=a.slice(a.indexOf(":")+1);e.warn("W04",i,{attr:a,expr:c.value,problem:`${g}: compares the "${A}" attribute against a literal value, not a JS expression`,fix:`use show="${c.value}" for an expression, or a literal like ${g}:${A}="overview"`})}}else{let A=ct(g,[...he]);e.warn("W03",i,{attr:a,problem:`unknown "${g}:" attribute`,didYouMean:A?`${A}:`:null})}}else if(!be.has(a)&&!ut.has(a)&&!un.has(a)&&!/^(data-|aria-|on)/.test(a)&&!(a in i)){let g=ct(a,[...be]);g&&e.warn("W03",i,{attr:a,problem:`unknown "${a}" attribute`,didYouMean:g})}a==="attr:hidden"&&e.warn("W03",i,{attr:a,problem:"attr:hidden paints the wrong attribute",fix:'use show="expr"'});let m=At(i)||a==="attr:selected"&&i.tagName==="OPTION"&&!!i.closest("select[bind]");(a==="attr:value"||a==="attr:checked"||a==="attr:selected")&&m&&n("E30",i,{attr:a,problem:"attr: on a bound control collides with persist ownership",fix:"remove it; bind owns this attribute"}),a==="effect"&&At(i)&&/\b(value|checked)\s*=[^=]/.test(c.value)&&n("E30",i,{attr:a,expr:c.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"}),(a==="text"||a.startsWith("text:")||a==="show")&&fn(i)&&(a==="show"||n("E18",i,{attr:a,problem:"paint belongs on output elements, not form controls",fix:"move the paint to an <output> or <span>"}))}if(i.hasAttribute("state")){let c=G(i.getAttribute("state")),a=new Set;for(let m of c){m.name.includes("-")&&n("E08",i,{attr:"state",problem:`field "${m.name}" is not a valid identifier (the hyphen parses as subtraction)`,fix:`rename to ${m.name.replace(/-/g,"")}`}),a.has(m.name)&&n("E04",i,{attr:"state",problem:`field "${m.name}" is declared twice in one scope`}),a.add(m.name),Tt.has(m.attr)&&n("E05",i,{attr:"state",problem:`"${m.name}" is a reserved Sap word`}),ut.has(m.attr)&&n("E06",i,{attr:"state",problem:`"${m.name}" is a global HTML attribute name; pick another field name`}),m.name==="open"&&i.tagName==="DIALOG"&&n("E33",i,{attr:"state",problem:"dialog open is transient",fix:"use showModal() \u2014 declare state= only on <details> or popovers"});let g=ft(i,m.attr);g&&(m.attr==="checked"||m.attr==="selected")&&n("E35",i,{attr:"state",problem:`"${m.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">'}),g&&m.type==="num"&&n("E35",i,{attr:"state",problem:`"${m.attr}" is an HTML boolean attribute; it cannot hold a number`,fix:`declare it bare: state="${m.attr}"`}),m.transient&&(g||m.type==="presence")&&n("E35",i,{attr:"state",problem:`"${m.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(At(i)){if(i.hasAttribute("-"),i.tagName==="INPUT"){let c=(i.getAttribute("type")||"text").toLowerCase();c==="file"&&n("E32",i,{attr:"bind",problem:"files never serialize into an HTML file",fix:"use no-save + effect instead of bind"}),c==="password"&&!i.hasAttribute("transient")&&n("E31",i,{attr:"bind",problem:"a password must never serialize into a world-readable file",fix:"add transient to the password input"})}else if(i.tagName!=="SELECT"&&i.tagName!=="TEXTAREA"){let c=i.getAttribute("contenteditable");!(c!=null&&c!=="false")&&i.children.length>0&&n("E20",i,{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(i.hasAttribute("transient")&&i.hasAttribute("persist")&&n("E34",i,{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"}),i.tagName==="DIALOG"&&i.hasAttribute("detail")&&!(i.parentElement&&i.parentElement.closest('[clay~="freeze"], [freeze], [save-freeze]'))&&e.warn("W31",i,{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'}),i.hasAttribute("item")&&!i.hasAttribute("template")&&i.parentNode&&i.parentNode.nodeType===1){let c=i.parentElement;(!c||!c.hasAttribute("items"))&&n("E10",i,{problem:"an [item] must be a direct child of an [items] list",fix:'wrap it in a container with items="name"'})}if(i.hasAttribute("items")&&l&&n("E17",i,{attr:"items",problem:"nested items inside a detail panel is a v1 mount error (nested collections ship in v1.1)"}),i.hasAttribute("items")){let c=t.querySelector(`[trigger-add="${i.getAttribute("items")}"]`);!$t(i)&&!lt(t,i.getAttribute("items"))&&Ct(i).length===0&&c&&n("E17",i,{attr:"items",problem:`trigger-add targets items="${i.getAttribute("items")}" but it has no [item template] to clone`})}}),r&&(e.halted=!0,e.haltReason=e.errors[0]?e.errors[0].code:"halt",P(t,e.haltReason)),!r}var we="sap-styles",Ae="[item][template]{display:none!important}[hidden]{display:none!important}[sap-error]{outline:2px solid #e5484d;outline-offset:1px}",xt=new WeakSet;function pn(t){if(xt.has(t))return;let e=t.defaultView,r=e&&e.CSSStyleSheet;if(r&&"adoptedStyleSheets"in t)try{let n=new r;n.replaceSync(Ae),t.adoptedStyleSheets=[...t.adoptedStyleSheets,n],xt.add(t);return}catch{}if(!t.getElementById(we)){let n=t.createElement("style");n.id=we,n.textContent=Ae,(t.head||t.documentElement).appendChild(n)}xt.add(t)}var mn=0;function Ee(){return typeof performance<"u"&&performance.now?performance.now():0}function vt(t){let e=t.id||t.getAttribute("sap")||`app-${mn++}`,r=new Y(e),n={root:t,name:e,diag:r,_state:null,_stats:null,_lastPass:null,_passes:0,_broken:!1,_mountMs:0,_mountWrites:0};if(!ye(t,r))return n.halted=!0,n;pn(t.ownerDocument);for(let i of t.querySelectorAll("textarea[data-value]"))et(i);let u=Ee();return it(n,{trigger:"mount",full:!0}),n._mountMs=Ee()-u,n._mountWrites=n._stats?n._stats.writes:0,n._mountWrites>0&&!ee()&&!w("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 xe=/^(set:|move:|sort:|trigger-add$|trigger-remove$|trigger-reset$)/;function hn(t){return`${t.tagName.toLowerCase()}[sap]`}function bn(t){let e=0;for(let r of t.querySelectorAll("*"))for(let n of r.attributes)if(xe.test(n.name)){e++;break}for(let r of t.attributes)if(xe.test(r.name)){e++;break}return e}function ve(t){function e(d){let l=d._stats||{},c=d.root;return{root:hn(c),fields:l.fields||0,calcs:l.calcs||0,paints:l.paints||0,actions:bn(c),lists:(c.hasAttribute("items")?1:0)+c.querySelectorAll("[items]").length,rows:c.querySelectorAll("[item]:not([template])").length,warnings:d.diag.warnings.length,errors:d.diag.errors.length,mountWrites:d._mountWrites||0,ms:Math.round((d._mountMs||0)*10)/10,passes:d._passes||0,lastPass:d._lastPass||null,ok:d.diag.errors.length===0&&!d.halted}}function r(){let d=t.apps().map(e);return{ok:d.every(l=>l.ok),apps:d}}function n(d){let l=e(d);return l.ok?`sap \u2713 ${l.root} \xB7 fields ${l.fields} \xB7 calcs ${l.calcs} \xB7 paints ${l.paints} \xB7 actions ${l.actions} \xB7 lists ${l.lists} \xB7 rows ${l.rows} \xB7 warnings ${l.warnings} \xB7 mount writes ${l.mountWrites} \xB7 ${l.ms}ms`:`sap \u2717 ${l.root} \xB7 errors ${l.errors} \xB7 warnings ${l.warnings} \xB7 ${l.ms}ms`}function o(){for(let d of t.apps()){let l=n(d);d.diag.errors.length||d.halted?console.error(l):console.log(l)}}function u(){let d=[],l=[];for(let c of t.apps())d.push(...c.diag.errors),l.push(...c.diag.warnings);return{ok:d.length===0,errors:d,warnings:l,counts:{errors:d.length,warnings:l.length}}}function i(d){let l=d===void 0?!0:!!d;for(let c of t.apps())c._debug=l;return console.log(`sap debug ${l?"on":"off"} \u2014 per-pass headers will ${l?"":"no longer "}log`),l}return{status:r,report:u,debug:i,greenLine:n,printGreenLines:o,REGISTRY:at}}var Se="0.6.0";function ke({createAccessor:t,installInput:e,debugExtras:r}){let n=new Map,o=[],u=Nt(it);function i(s){let f=s;for(;f;){if(f.nodeType===1&&f.hasAttribute&&f.hasAttribute("sap"))return n.get(f)||null;f=f.parentNode&&f.parentNode.host?f.parentNode.host:f.parentElement}return null}function d(){for(let s=o.length-1;s>=0;s--){let f=o[s];f.root.isConnected||(n.delete(f.root),o.splice(s,1))}}function l(s,f){if(s.moveBefore)try{s.moveBefore(f,null);return}catch{}s.appendChild(f)}function c(s,f){let h=f.parentElement;if(h){if(h.moveBefore)try{h.moveBefore(s,f);return}catch{}h.insertBefore(s,f)}}let a={apps:()=>o.slice(),appFor:i,isRegistered:s=>n.has(s),pruneDisconnected:d,schedule:(s,f)=>u.schedule(s,f),runNow:(s,f)=>u.runNow(s,f),moveInto:l,placeBefore:c,remountIfPresent:()=>M()},m=t(a),g=ve(a),A=r?r(a,g):{},E=!1,x=!1,k=null;function z(){E||(E=!0,e(a,m,document),k=oe(a))}function v(){let s=w("derived");s&&typeof s.mounted=="function"&&s.mounted()}function M(s=document){if(x)return[];z(),gt(a);let f=s.querySelectorAll("[sap]"),h=[];for(let p of f){if(n.has(p))continue;let b=vt(p);n.set(p,b),o.push(b),h.push(b)}for(let p of h){let b=g.greenLine(p);p.diag.errors.length||p.halted?console.error(b):console.log(b)}return v(),h}function C(s){if(x)return null;if(z(),gt(a),!s)return M();let f=typeof s=="string"?document.querySelector(s):s;if(!f)return null;if(n.has(f))return n.get(f);let h=vt(f);n.set(f,h),o.push(h);let p=g.greenLine(h);return h.diag.errors.length||h.halted?console.error(p):console.log(p),h}let y=m.Sap;return y.version=Se,y.refresh=function(){for(let f of o)f.root.isConnected&&u.runNow(f,"refresh")},y.batch=re,y.status=g.status,y.report=g.report,y.why=A.why,y.debug=g.debug,y.doctor=A.doctor,y.greenLine=g.greenLine,y.formats=I,y.serializeControlToAttributes=D,y.finalizeControlForSave=te,y.rehydrateControlFromAttributes=et,y.mount=C,y.config=function(f={}){return f.formats&&Object.assign(I,f.formats),y},y._registry=n,y._reset=function(){n.clear(),o.length=0,yt()},y.unmount=function(){x=!0,n.clear(),o.length=0,yt(),typeof k=="function"&&k()},{Sap:y,mountAll:M,mount:C,runtime:a}}function Ne(t){if(typeof document>"u")return;let e=()=>ne(()=>t());document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e()}function Te(t){let e=[];function r(l){let c=l.target;if(!c||c.nodeType!==1)return;let a=t.appFor(c);if(a){c.hasAttribute("persist")&&!nt(c)&&D(c);for(let m of e)if(m(c,a))return;t.schedule(a,l.type+" "+(c.id||c.tagName.toLowerCase()))}}function n(l){let c=l.target,a=t.appFor(c);a&&setTimeout(()=>{c.querySelectorAll("[bind]").forEach(m=>{m.dispatchEvent(new Event("input",{bubbles:!0})),m.dispatchEvent(new Event("change",{bubbles:!0}))}),t.schedule(a,"reset")},0)}function o(l){let c=t.appFor(l.target);c&&t.schedule(c,"toggle")}function u(l){let c=l.detail||{};for(let a of[c.from,c.to,l.target]){if(!a||a.nodeType!==1)continue;let m=t.appFor(a);m&&t.schedule(m,"sorted")}}function i(l){if(l.key!=="ArrowUp"&&l.key!=="ArrowDown")return;let c=l.target;if(!c||c.nodeType!==1||c.tagName!=="INPUT"||!c.hasAttribute("bind")||!c.hasAttribute("step"))return;let a=(c.getAttribute("type")||"text").toLowerCase();if(a!=="text"&&a!=="tel"&&a!=="search"||!t.appFor(c))return;l.preventDefault();let g=S(c.getAttribute("step"))||1,A=l.key==="ArrowUp"?1:-1,E=S(c.value)+g*(l.shiftKey?10:1)*A,x=c.getAttribute("min"),k=c.getAttribute("max");x!==null&&x!==""&&E<S(x)&&(E=S(x)),k!==null&&k!==""&&E>S(k)&&(E=S(k)),ue(c).write(String(Number(E.toFixed(2))))}function d(l=document){l.addEventListener("reset",n),l.addEventListener("toggle",o,!0),l.addEventListener("input",r),l.addEventListener("change",r),l.addEventListener("clay:sorted",u),l.addEventListener("keydown",i)}return{install:d,addRouter:l=>e.push(l)}}var U="https://clayjs.com/v1/sap.js",gn=/^(calc|set|move|sort):/,yn=new Set(["each","detail","effect","invalid","confirm","trigger-add","trigger-remove","trigger-reset"]);function St(t){return gn.test(t)||yn.has(t)}ge((t,e)=>{for(let r of t.attributes)St(r.name)&&e("E50",t,{attr:r.name,expr:r.value,problem:`${r.name} is full sapjs; the sapjs core only paints declared state`,fix:`load ${U}; the markup stays as it is`})});function W(t,e,r){t.app.diag.error("E50",e,{attr:r,problem:`${r} is full sapjs; the sapjs core only paints declared state`,fix:`load ${U}; the markup stays as it is`}),P(e,"E50"),t.app.halted=!0}me({name:"core-only",collect(t,e,r){r.calcs&&W(t,e,"calc:"+r.calcs[0].name),r.effects&&W(t,e,"effect"),r.invalids&&W(t,e,"invalid");for(let n of e.attributes)St(n.name)&&(n.name.startsWith("calc:")&&r.calcs||n.name==="effect"&&r.effects||n.name==="invalid"&&r.invalids||W(t,e,n.name))},boundary:{each(t,e){W(t,e,"each")},detail(t,e){W(t,e,"detail")}}});function wn(){return{Sap:function(){throw new Error(`Sap(el) is full sapjs; load ${U}`)}}}var Le=t=>()=>(console.warn(`Sap.${t} is full sapjs; load ${U}`),null),{Sap:q,mountAll:_e,mount:An,runtime:En}=ke({createAccessor:wn,debugExtras:()=>({why:Le("why"),doctor:Le("doctor")}),installInput(t,e,r){Te(t).install(r)}});q.core=!0;var xn=typeof window<"u"&&window.Sap&&!window.Sap.core;xn?q.unmount():Ne(_e);typeof window<"u"&&!window.Sap&&(window.Sap=q);var vn=q;return Ie(Sn);})();
|
|
9
|
+
export default SapCoreBundle.default;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// GENERATED — do not edit. Vendored from sapjs/src/ownership.js
|
|
2
|
+
// via sapjs `npm run propagate`, which writes every client's copy from one
|
|
3
|
+
// table. Edit the sapjs source and re-run.
|
|
4
|
+
|
|
5
|
+
// What sapjs paints on an element, read from that element's own attributes. No
|
|
6
|
+
// expression runs and no engine state is read, so a host can ask it of any tree:
|
|
7
|
+
// the live page, a snapshot clone, or a parsed frame. Self-contained on purpose:
|
|
8
|
+
// ClayJS vendors this file verbatim.
|
|
9
|
+
|
|
10
|
+
export const BEACON = "sap-error";
|
|
11
|
+
|
|
12
|
+
const WHEN = /^(show-when|hide-when|option|option-not):/;
|
|
13
|
+
// Identity and the attributes that declare the record itself are never paint
|
|
14
|
+
// output. Form state is, unless a bind or persist owns it.
|
|
15
|
+
const NEVER = new Set([
|
|
16
|
+
"id", "data-id", "class", "style",
|
|
17
|
+
"sap", "scope", "items", "item", "bind", "state", "template", "cms-template", "sap-ignore",
|
|
18
|
+
]);
|
|
19
|
+
const FORM_STATE = new Set(["value", "checked", "selected"]);
|
|
20
|
+
|
|
21
|
+
function recordOwnsFormState(el) {
|
|
22
|
+
return el.hasAttribute("bind") || el.hasAttribute("persist") || !!el.closest("select[bind]");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function inert(el) {
|
|
26
|
+
return el.localName === "template" || el.hasAttribute("template") || el.hasAttribute("cms-template") || el.hasAttribute("sap-ignore");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// The [sap] root an element is painted under, or null when it sits outside every
|
|
30
|
+
// app or inside a subtree the engine never reads.
|
|
31
|
+
export function appOf(el) {
|
|
32
|
+
for (let cur = el; cur && cur.nodeType === 1; cur = cur.parentElement) {
|
|
33
|
+
if (inert(cur)) return null;
|
|
34
|
+
if (cur.hasAttribute("sap")) return cur;
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function declares(el, name) {
|
|
40
|
+
const decl = el.getAttribute("state");
|
|
41
|
+
if (!decl) return false;
|
|
42
|
+
for (const token of decl.trim().split(/\s+/)) {
|
|
43
|
+
if (token.split("=")[0].split(":")[0] === name) return true;
|
|
44
|
+
}
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function paintsHidden(el) {
|
|
49
|
+
if (el.hasAttribute("show")) return true;
|
|
50
|
+
for (const a of el.attributes) if (WHEN.test(a.name)) return true;
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// True when a sapjs paint writes attribute `name` on `el`.
|
|
55
|
+
export function ownsAttr(el, name) {
|
|
56
|
+
if (!el || el.nodeType !== 1 || !name) return false;
|
|
57
|
+
if (name === BEACON) return !!appOf(el);
|
|
58
|
+
if (NEVER.has(name)) return false;
|
|
59
|
+
if (FORM_STATE.has(name) && recordOwnsFormState(el)) return false;
|
|
60
|
+
if (name === "hidden") return paintsHidden(el) && !!appOf(el);
|
|
61
|
+
return el.hasAttribute("attr:" + name) && !declares(el, name) && !!appOf(el);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Everything a paint writes on `el`: whole attributes, class tokens, --custom
|
|
65
|
+
// properties in style, and whether text owns its children. Null when nothing.
|
|
66
|
+
export function paintsOf(el) {
|
|
67
|
+
if (!el || el.nodeType !== 1 || !appOf(el)) return null;
|
|
68
|
+
let out = null;
|
|
69
|
+
const add = (key, v) => ((out || (out = { attrs: [], classes: [], vars: [], text: false }))[key].push(v));
|
|
70
|
+
for (const a of el.attributes) {
|
|
71
|
+
const n = a.name;
|
|
72
|
+
if (n === "text" || n.startsWith("text:")) {
|
|
73
|
+
if (!el.hasAttribute("bind")) (out || (out = { attrs: [], classes: [], vars: [], text: false })).text = true;
|
|
74
|
+
}
|
|
75
|
+
else if (n.startsWith("attr:")) {
|
|
76
|
+
const target = n.slice(5);
|
|
77
|
+
if (target && !NEVER.has(target) && !(FORM_STATE.has(target) && recordOwnsFormState(el)) && !declares(el, target)) add("attrs", target);
|
|
78
|
+
} else if (n.startsWith("class:")) add("classes", n.slice(6));
|
|
79
|
+
else if (n.startsWith("css:")) add("vars", "--" + n.slice(4));
|
|
80
|
+
}
|
|
81
|
+
if (paintsHidden(el)) add("attrs", "hidden");
|
|
82
|
+
if (el.hasAttribute(BEACON)) add("attrs", BEACON);
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Calls visit(el, paints) for every painted element under root, in document order.
|
|
87
|
+
export function eachPainted(root, visit) {
|
|
88
|
+
if (!root || root.nodeType !== 1 && root.nodeType !== 9) return;
|
|
89
|
+
const apps = root.nodeType === 1 && root.hasAttribute("sap")
|
|
90
|
+
? [root]
|
|
91
|
+
: [...root.querySelectorAll("[sap]")].filter((app) => !app.parentElement || !app.parentElement.closest("[sap]"));
|
|
92
|
+
for (const app of apps) {
|
|
93
|
+
for (const el of [app, ...app.querySelectorAll("*")]) {
|
|
94
|
+
const p = paintsOf(el);
|
|
95
|
+
if (p) visit(el, p);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Removes every painted value from a detached tree, in place: owned attributes,
|
|
101
|
+
// owned class tokens and --properties, and the children of text paints.
|
|
102
|
+
export function stripPaints(root) {
|
|
103
|
+
eachPainted(root, (el, p) => {
|
|
104
|
+
for (const name of p.attrs) if (el.hasAttribute(name)) el.removeAttribute(name);
|
|
105
|
+
for (const token of p.classes) if (el.classList.contains(token)) el.classList.remove(token);
|
|
106
|
+
if (!el.getAttribute("class") && el.hasAttribute("class") && p.classes.length) el.removeAttribute("class");
|
|
107
|
+
for (const v of p.vars) if (el.style.getPropertyValue(v) !== "") el.style.removeProperty(v);
|
|
108
|
+
if (p.vars.length && el.hasAttribute("style") && !el.getAttribute("style").trim()) el.removeAttribute("style");
|
|
109
|
+
if (p.text && el.firstChild) el.replaceChildren();
|
|
110
|
+
});
|
|
111
|
+
}
|