@panphora/clayjs 0.2.1 → 0.4.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/README.md +103 -7
- package/clay-data.js +1 -1
- package/clay-internals.js +19 -0
- package/clay.js +19 -3
- package/package.json +5 -2
- package/sap.js +5 -5
- package/src/attrs/onaftersave.js +12 -1
- package/src/attrs/refetch-on-save.js +4 -4
- package/src/attrs/save-freeze.js +47 -19
- package/src/core/admin-contenteditable.js +2 -2
- package/src/core/admin-inputs.js +2 -2
- package/src/core/admin-onclick.js +2 -2
- package/src/core/admin-resources.js +23 -14
- package/src/core/autosave.js +11 -1
- package/src/core/edit-mode.js +2 -2
- package/src/core/host-attrs.js +46 -0
- package/src/core/is-edit-mode.js +14 -6
- package/src/core/persist.js +12 -2
- package/src/core/save-core.js +199 -290
- package/src/core/save.js +121 -82
- package/src/core/snapshot.js +89 -36
- package/src/core/unsaved-warning.js +8 -2
- package/src/dom/all.js +4 -29
- package/src/dom/form-data.js +1 -1
- package/src/dom/nearest.js +11 -9
- package/src/internals/index.js +69 -0
- package/src/lib/cache-bust.js +10 -0
- package/src/lib/cookie.js +50 -15
- package/src/lib/extension-noise.js +5 -1
- package/src/lib/mutation.js +65 -18
- package/src/lib/region-policy.js +17 -2
- package/src/lib/root-attrs.js +45 -0
- package/src/lib/throttle.js +25 -13
- package/src/loader.js +18 -24
- package/src/options/options.js +1 -3
- package/src/plugins/demo.js +7 -1
- package/src/plugins/undo.js +3 -3
- package/src/sync/live-sync.js +77 -76
- package/src/ui/dialogs.js +10 -1
- package/src/ui/index.js +0 -10
- package/src/utils/debounce.js +24 -7
- package/src/vendor/control-serialize.vendor.js +2 -1
- package/src/vendor/hyper-undo.vendor.js +1 -1
- package/src/vendor/hypercms.vendor.js +29 -16
- package/src/vendor/richclay.vendor.js +29 -22
package/sap.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// GENERATED — do not edit. Vendored from sapjs/dist/sap.min.js via sapjs
|
|
2
2
|
// `npm run copy-to-clayjs`. Edit the sapjs source and re-run.
|
|
3
3
|
(function () {
|
|
4
|
-
var Sap=(()=>{var
|
|
5
|
-
${t}`:`"use strict"; return (${t});`;r={fn:new Function(...
|
|
6
|
-
`+(e[0]==="W"?"sap \u26A0 ":"sap \u2717 ")+e+" "+s];return
|
|
7
|
-
`)),f}error(e,n,r={}){let s=this.block(e,n,r);return this.errors.push(s),s}warn(e,n,r={}){let s=this.block(e,n,r);return this.warnings.push(s),s}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 Y(t,e){t&&t.getAttribute("sap-error")!==e&&t.setAttribute("sap-error",e)}function St(t){t&&t.hasAttribute("sap-error")&&t.removeAttribute("sap-error")}function ft(t,e){let n=null,r=3;for(let s of e){let f=je(t,s);f<r&&(r=f,n=s)}return n}function je(t,e){let n=t.length,r=e.length,s=Array.from({length:n+1},(f,u)=>[u,...new Array(r).fill(0)]);for(let f=0;f<=r;f++)s[0][f]=f;for(let f=1;f<=n;f++)for(let u=1;u<=r;u++)s[f][u]=Math.min(s[f-1][u]+1,s[f][u-1]+1,s[f-1][u-1]+(t[f-1]===e[u-1]?0:1));return s[n][r]}var j=null,$t=!1,X=null;function Zt(t){let e=null;return{kind:"hub",subscribe(n){let r=t.onAnyChange({debounce:0,require:"observed"},n);typeof r=="function"&&(e=r)},suppress(n){t.pause();try{return n()}finally{t.resume()}},teardown(){if(e){try{e()}catch{}e=null}}}}function Ve(){let t=null;return{kind:"native",subscribe(e){t=new MutationObserver(r=>e(Ue(r)));let n=typeof document<"u"&&document.body||typeof document<"u"&&document.documentElement;n&&t.observe(n,{childList:!0,subtree:!0,attributes:!0,characterData:!0})},suppress(e){let n=typeof window<"u"&&window.hyperclay&&window.hyperclay.undo;n&&n.pause&&n.pause();try{return e()}finally{t&&t.takeRecords(),n&&n.resume&&n.resume()}},teardown(){t&&(t.disconnect(),t=null)}}}function Ue(t){let e=[];for(let n of t)if(n.type==="attributes"){let r=n.target;r&&r.nodeType===1&&!xt(r)&&e.push({type:"attribute",element:r})}else if(n.type==="characterData"){let r=n.target&&n.target.parentElement;r&&!xt(r)&&e.push({type:"characterData",element:r})}else if(n.type==="childList"){for(let r of n.addedNodes)if(!(r.nodeType!==1||xt(r))&&(e.push({type:"add",element:r}),r.querySelectorAll))for(let s of r.querySelectorAll("*"))xt(s)||e.push({type:"add",element:s});for(let r of n.removedNodes)r.nodeType===1&&e.push({type:"remove",element:r,parent:n.target})}return e}function xt(t){return!!(t.closest&&t.closest("[sap-ignore],[template]"))}function Ge(t,e){t.pruneDisconnected();let n=new Set,r=!1;for(let s of e){let f=s.type==="remove"?s.parent:s.element,u=f&&t.appFor(f);u&&n.add(u),s.type==="add"&&s.element&&s.element.nodeType===1&&s.element.hasAttribute&&s.element.hasAttribute("sap")&&!(t.isRegistered&&t.isRegistered(s.element))&&(r=!0)}r&&t.remountIfPresent();for(let s of n)s.root.isConnected&&t.schedule(s,"mutation")}function te(t){if(j)return j.suppress(t);let e=typeof window<"u"&&window.hyperclay&&window.hyperclay.undo;if(e&&e.pause&&e.resume){e.pause();try{return t()}finally{e.resume()}}return t()}function Lt(t,e){$t=!0,j=t,t.subscribe(n=>Ge(e,n))}function Ct(t){if($t||typeof window>"u"||typeof document>"u")return;let e=window,n=e.hyperclay&&e.hyperclay.Mutation;if(n&&typeof n.onAnyChange=="function"){Lt(Zt(n),t);return}typeof MutationObserver=="function"&&(Lt(Ve(),t),X=function(){let s=e.hyperclay&&e.hyperclay.Mutation;s&&(document.removeEventListener("hyperclay:mutation-ready",X),X=null,j&&j.teardown(),$t=!1,Lt(Zt(s),t))},document.addEventListener("hyperclay:mutation-ready",X))}function ee(){if(j)try{j.teardown()}catch{}X&&typeof document<"u"&&document.removeEventListener("hyperclay:mutation-ready",X),j=null,$t=!1,X=null}var oe=new Set(At);function rt(t,e={}){if(e.breaker){t.diag.error("E26",t.root,{problem:"recompute loop halted after 50 passes; recent triggers: "+(t._breakerRing||[]).join(", ")}),Y(t.root,"loop");return}te(()=>Ye(t,e))}function Ye(t,e){let n=t.root,r={},s=[],f=[],u=[],T=[],E=[],y=new Set;t.diag.errors=[];let l={root:r,state:r,item:null,ownerEl:n,projection:!1};function w(o,i){let h=o.getAttribute(i.name);return h==null&&(h=i.default!=null?i.default:i.type==="num"?"0":i.type==="bool"?"false":"",E.push({el:o,name:i.name,value:mt(G(h,i.type),i.type)})),G(h,i.type)}function k(o,i){let h=F(o.getAttribute("state")||"");o._sapStateDecls=h;for(let p of h){if(p.type==="string"&&oe.has(p.name)&&typeof o[p.name]=="boolean"){i[p.name]=o.hasAttribute(p.name);continue}if(p.transient){i[p.name]=ht(o,p);continue}i[p.name]=w(o,p)}}function L(o,i){if(!o.hasAttribute("bind"))return;let h=o.getAttribute("bind"),p=i.item||i.state,v=R(o);v.kind==="radio"?(h in p||(p[h]=""),o.checked&&(p[h]=o.value)):p[h]=v.read(),o.hasAttribute("transient")&&(o.removeAttribute("value"),o.removeAttribute("checked"))}function b(o,i){for(let h of o.attributes){let p=h.name,v=h.value;if(p.startsWith("calc:"))s.push({owner:i.item||i.state,ownerEl:i.ownerEl,name:p.slice(5),entry:D(v),el:o,ctx:i});else if(p==="text"||p.startsWith("text:"))f.push({el:o,kind:"text",fmt:p.includes(":")?p.slice(5):null,entry:D(v),ctx:i});else if(p==="show")f.push({el:o,kind:"show",entry:D(v),ctx:i});else if(p.startsWith("attr:"))f.push({el:o,kind:"attr",arg:p.slice(5),entry:D(v),ctx:i});else if(p.startsWith("class:"))f.push({el:o,kind:"class",arg:p.slice(6),entry:D(v),ctx:i});else if(p.startsWith("css:"))f.push({el:o,kind:"css",arg:p.slice(4),entry:D(v),ctx:i});else if(p==="effect")u.push({el:o,entry:D(v,!0),ctx:i});else if(p==="invalid")T.push({el:o,entry:D(v),ctx:i});else if(p.startsWith("show-when:")||p.startsWith("option:")){let N=p.slice(p.indexOf(":")+1);y.add(N),f.push({el:o,kind:"when",match:"show",field:N,values:v.split("|"),ctx:i})}else if(p.startsWith("hide-when:")){let N=p.slice(p.indexOf(":")+1);y.add(N),f.push({el:o,kind:"when",match:"hide",field:N,values:v.split("|"),ctx:i})}else if(p.startsWith("option-not:")){let N=p.slice(p.indexOf(":")+1);y.add(N),f.push({el:o,kind:"when",match:"show-not",field:N,values:v.split("|"),ctx:i})}}i.projection&&o.hasAttribute("bind")&&f.push({el:o,kind:"projection",field:o.getAttribute("bind"),ctx:i})}function g(o,i,h){Z(i,"row"),Object.defineProperty(o,"$key",{value:i.id,enumerable:!1}),Object.defineProperty(o,"$index",{value:h,enumerable:!1}),Object.defineProperty(o,"$el",{value:i,enumerable:!1})}function a(o,i,h){k(o,i),o._sapScope=i,!h.projection&&o.hasAttribute("bind")&&L(o,h),b(o,h),o.hasAttribute("items")?x(o,i,h):A(o,i,h)}function A(o,i,h){W(o,(p,v)=>{v?p.hasAttribute("scope")?S(p,i,h):p.hasAttribute("items")?(b(p,h),x(p,i,h)):p.hasAttribute("detail")&&M(p,i,h):(h.projection||L(p,h),b(p,h))})}function S(o,i,h){let p=o.getAttribute("scope"),v={};i[p]=v;let N={root:h.root,state:v,item:null,ownerEl:o,projection:h.projection};a(o,v,N)}function x(o,i,h){let p=o.getAttribute("items"),v=[];i[p]=v,o._sapList=v,O(o).forEach((N,ot)=>{let C={};g(C,N,ot);let q={root:h.root,state:h.state,item:C,ownerEl:N,projection:h.projection};a(N,C,q),v.push(C)})}function $(o,i){let h=String(o).split("."),p=i.state;for(let v of h)p=p?.[v];if(p===void 0){p=i.root;for(let v of h)p=p?.[v]}return p}function M(o,i,h){for(let Q of F(o.getAttribute("state")||""))Q.name in i||(i[Q.name]=w(o,Q));o._sapScope=i;let p=o.getAttribute("detail")||"",v=/^([\w.]+)\s+by\s+(.+)$/.exec(p);if(!v){o.hidden=!0,o._sapDetailRow=null;return}let N=v[1],ot=v[2].trim(),C=$(N,h),q;try{q=H(D(ot),{state:i,item:h.item,el:o,root:h.root})}catch{q=void 0}let J=Array.isArray(C)?C.find(Q=>Q&&String(Q.$key)===String(q)):null;if(o._sapDetailRow=J?J.$el:null,!J){o.hidden||(o.hidden=!0);return}o.hidden&&(o.hidden=!1);let Ot={root:h.root,state:i,item:J,ownerEl:J.$el,projection:!0};b(o,Ot),A(o,J,Ot)}if(a(n,r,l),E.length&&y.size)for(let o of E)y.has(o.name)&&o.el.getAttribute(o.name)==null&&o.el.setAttribute(o.name,o.value);let m=new Map;for(let o of s){let i=m.get(o.owner);i||(i={ownerEl:o.ownerEl,list:[]},m.set(o.owner,i)),i.list.push(o)}let d=[...m.values()].sort((o,i)=>re(i.ownerEl)-re(o.ownerEl));for(let o of d){let i;try{i=Vt(o.list)}catch(h){t.diag.error("E07",o.list[0].el,{problem:h.message}),i=o.list}for(let h of i)try{h.owner[h.name]=H(h.entry,{state:h.ctx.state,item:h.ctx.item,el:h.el,root:h.ctx.root}),St(h.el)}catch(p){h.owner[h.name]=void 0,t.diag.error("E24",h.el,{attr:"calc:"+h.name,expr:h.entry.src,problem:String(p.message)}),Y(h.el,p.sapCode||"E24")}}let c=0;for(let o of f)c+=Je(o,t);for(let o of u)Qe(o,t);for(let o of T)Ze(o);t._state=r,t._stats={fields:Object.keys(r).filter(o=>typeof r[o]!="function").length,calcs:s.length,paints:f.length,lists:m.size,writes:c},t._lastPass={trigger:e.trigger||"refresh",writes:c},t._debug&&console.log(`sap pass \xB7 trigger: ${t._lastPass.trigger} \xB7 writes ${c}/${f.length}`)}function Xe(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 Mt(t,e,n,r){let s=t;for(;s&&s.nodeType===1;){if(s.hasAttribute&&s.hasAttribute(e)){let f=n.includes(s.getAttribute(e));if(r?!f:f)return!0}s=s.parentElement}return!1}function Ke(t,e){if(t===t.ownerDocument.activeElement)return 0;let n=R(t),r=n.read(),s=e??"";return String(r)!==String(s)?(n.write(s,{silent:!0}),1):0}function Je(t,e){if(t.kind==="projection")return Ke(t.el,t.ctx.item?t.ctx.item[t.field]:"");if(t.kind==="when")return ne(t,null);let n={state:t.ctx.state,item:t.ctx.item,el:t.el,root:t.ctx.root};try{let r=H(t.entry,n),s=ne(t,r);return St(t.el),s}catch(r){return e.diag.error(r.sapCode==="E22"?"E22":"E24",t.el,{attr:Xe(t),expr:t.entry&&t.entry.src,problem:String(r.message)}),Y(t.el,r.sapCode||"E24"),0}}function ne(t,e){let n=t.el;switch(t.kind){case"text":{let r=t.fmt!=null?qt(t.fmt,e):e==null?"":String(e);return n.textContent!==r?(n.textContent=r,1):0}case"show":{let r=!e;return n.hidden!==r?(n.hidden=r,1):0}case"when":{let r=typeof window<"u"&&window.hyperclay&&window.hyperclay.optionVisibility;if(r&&r._started)return n._sapWhen&&n.hidden?(n.hidden=!1,n._sapWhen=!1,1):0;let s;t.match==="hide"?s=!Mt(n,t.field,t.values,!1):t.match==="show-not"?s=Mt(n,t.field,t.values,!0):s=Mt(n,t.field,t.values,!1),n._sapWhen=!0;let f=!s;return n.hidden!==f?(n.hidden=f,1):0}case"attr":{let r=t.arg;if(oe.has(r)){let f=n.hasAttribute(r);return e&&!f?(n.setAttribute(r,""),1):!e&&f?(n.removeAttribute(r),1):0}let s=typeof e=="boolean"?String(e):e==null?"":String(e);return n.getAttribute(r)!==s?(n.setAttribute(r,s),1):0}case"class":{let r=!!e;return n.classList.contains(t.arg)!==r?(n.classList.toggle(t.arg,r),1):0}case"css":{let r=e==null?"":String(e);return n.style.getPropertyValue("--"+t.arg)!==r?(n.style.setProperty("--"+t.arg,r),1):0}default:return 0}}function Qe(t,e){try{H(t.entry,{state:t.ctx.state,item:t.ctx.item,el:t.el,root:t.ctx.root}),St(t.el)}catch(n){e.diag.error("E24",t.el,{attr:"effect",expr:t.entry&&t.entry.src,problem:String(n.message)}),Y(t.el,"E24")}}function Ze(t){let e="";try{let n=H(t.entry,{state:t.ctx.state,item:t.ctx.item,el:t.el,root:t.ctx.root});e=typeof n=="string"?n:""}catch{e=""}typeof t.el.setCustomValidity=="function"&&t.el.setCustomValidity(e)}function re(t){let e=0,n=t;for(;n&&!(n.hasAttribute&&n.hasAttribute("sap"));)n=n.parentElement,e++;return e}var tn=new Set(At),se=new Set(["calc","text","attr","class","css","set","move","sort","option","option-not","show-when","hide-when","editmode"]),en=new Set(["show-when","hide-when","option","option-not"]),nn=/\b(?:state|item|root)\.|===|!==|&&|\|\||[()]|^\s*!/,ie=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"]);function rn(t){return t.tagName==="INPUT"||t.tagName==="SELECT"||t.tagName==="TEXTAREA"}function Rt(t){return t.hasAttribute("bind")}function on(t,e){e(t);for(let r of t.children)n(r);function n(r){if(r.nodeType===1&&!((r.hasAttribute("sap-ignore")||r.hasAttribute("template"))&&r.hasAttribute("sap-ignore"))){e(r);for(let s of r.children)n(s)}}}function kt(t,e){let n=!1,r=(u,T,E)=>{e.error(u,T,E),n=!0},s=t.ownerDocument.createTreeWalker(t,4),f;for(;f=s.nextNode();)if(/\{\{.*\}\}/.test(f.nodeValue||"")){r("E02",f.parentElement||t,{problem:"moustaches in text content are not a Sap feature",fix:'move the expression onto the element: text="state.x"'});break}return on(t,u=>{let T=u.closest&&u.closest("[detail]");for(let E of[...u.attributes]){let y=E.name,l=Qt(y);if(l){r("E01",u,{attr:y,expr:E.value,problem:`"${y}" is a foreign-dialect attribute; Sap has no ${y.split(/[:=]/)[0]} directive`,fix:l+" \u2014 or wrap the subtree in sap-ignore if intentional"});continue}if(y.includes(":")){let w=y.slice(0,y.indexOf(":"));if(se.has(w)){if(en.has(w)&&nn.test(E.value)){let k=y.slice(y.indexOf(":")+1);e.warn("W04",u,{attr:y,expr:E.value,problem:`${w}: compares the "${k}" attribute against a literal value, not a JS expression`,fix:`use show="${E.value}" for an expression, or a literal like ${w}:${k}="overview"`})}}else{let k=ft(w,[...se]);e.warn("W03",u,{attr:y,problem:`unknown "${w}:" attribute`,didYouMean:k?`${k}:`:null})}}else if(!ie.has(y)&&!ct.has(y)&&!tn.has(y)&&!/^(data-|aria-|on)/.test(y)&&!(y in u)){let w=ft(y,[...ie]);w&&e.warn("W03",u,{attr:y,problem:`unknown "${y}" attribute`,didYouMean:w})}y==="attr:hidden"&&e.warn("W03",u,{attr:y,problem:"attr:hidden paints the wrong attribute",fix:'use show="expr"'}),(y==="attr:value"||y==="attr:checked"||y==="attr:selected")&&Rt(u)&&r("E30",u,{attr:y,problem:"attr: on a bound control collides with persist ownership",fix:"remove it; bind owns this attribute"}),y==="effect"&&Rt(u)&&/\b(value|checked)\s*=[^=]/.test(E.value)&&r("E30",u,{attr:y,expr:E.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"}),(y==="text"||y.startsWith("text:")||y==="show")&&rn(u)&&(y==="show"||r("E18",u,{attr:y,problem:"paint belongs on output elements, not form controls",fix:"move the paint to an <output> or <span>"}))}if(u.hasAttribute("state")){let E=F(u.getAttribute("state")),y=new Set;for(let l of E)l.name.includes("-")&&r("E08",u,{attr:"state",problem:`field "${l.name}" is not a valid identifier (the hyphen parses as subtraction)`,fix:`rename to ${l.name.replace(/-/g,"")}`}),y.has(l.name)&&r("E04",u,{attr:"state",problem:`field "${l.name}" is declared twice in one scope`}),y.add(l.name),vt.has(l.name)&&r("E05",u,{attr:"state",problem:`"${l.name}" is a reserved Sap word`}),ct.has(l.name)&&r("E06",u,{attr:"state",problem:`"${l.name}" is a global HTML attribute name; pick another field name`}),l.name==="open"&&u.tagName==="DIALOG"&&r("E33",u,{attr:"state",problem:"dialog open is transient",fix:"use showModal() \u2014 declare state= only on <details> or popovers"})}if(Rt(u)){if(u.hasAttribute("-"),u.tagName==="INPUT"){let E=(u.getAttribute("type")||"text").toLowerCase();E==="file"&&r("E32",u,{attr:"bind",problem:"files never serialize into an HTML file",fix:"use no-save + effect instead of bind"}),E==="password"&&!u.hasAttribute("transient")&&r("E31",u,{attr:"bind",problem:"a password must never serialize into a world-readable file",fix:"add transient to the password input"})}else if(u.tagName!=="SELECT"&&u.tagName!=="TEXTAREA"){let E=u.getAttribute("contenteditable");!(E!=null&&E!=="false")&&u.children.length>0&&r("E20",u,{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(u.hasAttribute("transient")&&u.hasAttribute("persist")&&r("E34",u,{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"}),u.hasAttribute("item")&&!u.hasAttribute("template")){let E=u.parentElement;(!E||!E.hasAttribute("items"))&&r("E10",u,{problem:"an [item] must be a direct child of an [items] list",fix:'wrap it in a container with items="name"'})}if(u.hasAttribute("items")&&T&&r("E17",u,{attr:"items",problem:"nested items inside a detail panel is a v1 mount error (nested collections ship in v1.1)"}),u.hasAttribute("items")){let E=t.querySelector(`[trigger-add="${u.getAttribute("items")}"]`);!pt(u)&&O(u).length===0&&E&&r("E17",u,{attr:"items",problem:`trigger-add targets items="${u.getAttribute("items")}" but it has no [item template] to clone`})}}),n&&(e.halted=!0,e.haltReason=e.errors[0]?e.errors[0].code:"halt",Y(t,e.haltReason)),!n}var ae="sap-styles",ue="[item][template]{display:none!important}[hidden]{display:none!important}[sap-error]{outline:2px solid #e5484d;outline-offset:1px}",Dt=new WeakSet;function sn(t){if(Dt.has(t))return;let e=t.defaultView,n=e&&e.CSSStyleSheet;if(n&&"adoptedStyleSheets"in t)try{let r=new n;r.replaceSync(ue),t.adoptedStyleSheets=[...t.adoptedStyleSheets,r],Dt.add(t);return}catch{}if(!t.getElementById(ae)){let r=t.createElement("style");r.id=ae,r.textContent=ue,(t.head||t.documentElement).appendChild(r)}Dt.add(t)}var an=0;function ce(){return typeof performance<"u"&&performance.now?performance.now():0}function It(t){let e=t.id||t.getAttribute("sap")||`app-${an++}`,n=new nt(e),r={root:t,name:e,diag:n,_state:null,_stats:null,_lastPass:null,_passes:0,_broken:!1,_mountMs:0,_mountWrites:0};if(!kt(t,n))return r.halted=!0,r;sn(t.ownerDocument);for(let u of t.querySelectorAll("textarea[data-value]"))wt(u);let f=ce();return rt(r,{trigger:"mount"}),r._mountMs=ce()-f,r._mountWrites=r._stats?r._stats.writes:0,r._mountWrites>0&&n.warn("W30",t,{problem:`${r._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)"}),r}function un(t,e){let n=null;return W(t,r=>{!n&&r.getAttribute("scope")===e&&(n=r)}),n}function fe(t,e,n){let r=I(t)||e;for(;r;){for(let s of F(r.getAttribute("state")||""))if(s.name===n)return{el:r,decl:s};if(r.hasAttribute("sap"))break;r=I(r.parentElement)}return null}function cn(t){return typeof t=="number"?"num":typeof t=="boolean"?"bool":"string"}function le(t){function e(b){let g=t.appFor(b);if(!g)return null;let a=it(b);if(a)return a._sapDetailRow?{ctxEl:a._sapDetailRow,appRec:g,isRow:!0}:{ctxEl:I(a.parentElement)||g.root,appRec:g,isRow:!1};let A=dt(b);if(A&&A.hasAttribute("item"))return{ctxEl:A,appRec:g,isRow:!0};let S=I(b)||g.root;return{ctxEl:S,appRec:g,isRow:S.hasAttribute("item")}}function n(b){let g=typeof b=="string"?document.querySelector(b):b;if(!g||g.nodeType!==1)return null;let a=e(g);return a?L(a.ctxEl,a.appRec,a.isRow):null}function r(b,g,a){let A=tt(b,a);if(A)return R(A).read();let S=st(b,a);if(S)return O(S).map(m=>L(m,g,!0));let x=un(b,a);if(x)return L(x,g,!1);let $=fe(b,g.root,a);if($)return $.decl.transient?ht($.el,$.decl):G($.el.getAttribute(a),$.decl.type);let M=b._sapScope;return M?M[a]:void 0}function s(b,g,a,A,S){A.transient?Tt(b,A,a):b.setAttribute(g,mt(a,A.type)),t.schedule(S,"set:"+g)}function f(b,g){let a=new Set,A=I(b)||g;for(;A;){for(let S of F(A.getAttribute("state")||""))a.add(S.name);if(A.hasAttribute("sap"))break;A=I(A.parentElement)}return W(b,S=>{let x=S.getAttribute("bind");x&&a.add(x)}),a}function u(b,g,a,A){let S=tt(b,a);if(S){R(S).write(A);return}let x=b;for(;x;){for(let h of x.attributes)if(h.name==="calc:"+a){g.diag.error("E16",x,{attr:"calc:"+a,problem:`"${a}" is a computed field; computed fields are read-only`});return}if(x.hasAttribute("sap"))break;x=x.parentElement}let $=fe(b,g.root,a);if($){s($.el,a,A,$.decl,g);return}let M=f(b,g.root);M.delete(a);let m=a.length>=4?ft(a,[...M]):null;if(m){g.diag.error("E12",b,{key:a,problem:`unknown state key "${a}"`,didYouMean:m});return}if(vt.has(a)||ct.has(a)){g.diag.error("E15",b,{key:a,problem:`cannot write undeclared field "${a}" \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 d=g.root,c=cn(A),o=d.getAttribute("state")||"",i=c==="string"?a:`${a}:${c}`;d.setAttribute("state",o?`${o} ${i}`:i),s(d,a,A,{name:a,type:c,transient:!1},g)}function T(b){let g=a=>{a.id&&(a.id="",Z(a,"row")),a.hasAttribute("sap-error")&&a.removeAttribute("sap-error")};b.id="",Z(b,"row"),b.querySelectorAll("[id]").forEach(g)}function E(b,g,a){let A=at(g.root,b,a);if(!A)return g.diag.error("E17",b,{problem:`cannot resolve a list named "${a}" from here`}),null;let S=pt(A);if(!S)return g.diag.error("E17",A,{problem:`items="${a}" has no [item template] to clone`}),null;let x=S.cloneNode(!0);return x.removeAttribute("template"),T(x),A.appendChild(x),t.schedule(g,"trigger-add:"+a),L(x,g,!0)}function y(b,g){W(b,a=>{if(a.hasAttribute("bind")){let A=R(a),S=a.getAttribute("default");A.kind==="checkbox"||A.kind==="radio"?A.write(S!=null?S===""||S==="true"||a.value===S:a.hasAttribute("checked")):A.write(S??(a.getAttribute("value")||""))}});for(let a of F(b.getAttribute("state")||"")){let A=a.default!=null?a.default:a.type==="num"?"0":a.type==="bool"?"false":"";a.transient?Tt(b,a,G(A,a.type)):b.setAttribute(a.name,A)}t.schedule(g,"trigger-reset")}function l(b,g){if(!b.isConnected)throw new Error("stale row handle: $remove() on a removed row");b.remove(),t.schedule(g,"trigger-remove")}function w(b,g,a){if(!b.isConnected)throw new Error("stale row handle: $move() on a removed row");let A=null;if(a&&a.nodeType===1?A=a:typeof a=="string"&&(A=at(g.root,b,a)),!A){g.diag.error("E17",b,{problem:`$move() cannot resolve target "${a}"`});return}t.moveInto(A,b),t.schedule(g,"trigger-move")}function k(b){let g=b.parentElement;return g?O(g).indexOf(b):-1}function L(b,g,a){let A={get $el(){return b},get $key(){return Z(b,a?"row":"scope")},get $index(){return k(b)},$add(x){return E(b,g,x)},$reset(){return y(b,g),S},$remove(){l(b,g)},$move(x){w(b,g,x)},get $appRec(){return g}},S=new Proxy(A,{get(x,$){return typeof $=="symbol"||$[0]==="$"?x[$]:r(b,g,$)},set(x,$,M){return typeof $=="string"&&$[0]==="$"?(x[$]=M,!0):(u(b,g,$,M),!0)},has(x,$){return typeof $=="string"&&$[0]==="$"?$ in x:r(b,g,$)!==void 0}});return S}return{Sap:n,contextElFor:e,readField:r,writeField:u,makeProxy:L}}var fn=["trigger-add","trigger-remove","trigger-reset"];function ln(t){if(t.nodeType!==1)return!1;for(let e of t.attributes){let n=e.name;if(n.startsWith("set:")||n.startsWith("move:")||n.startsWith("sort:")||fn.includes(n))return!0}return!1}function dn(t,e){let n=t,r=e.parentElement;for(;n&&n!==r;){if(n.nodeType===1&&ln(n)&&!(n.tagName==="FORM"&&n.hasAttribute("trigger-add")))return n;n=n.parentElement}return null}function de(t,e){let{Sap:n}=e;function r(m,d){let c=null,o=it(m);if(o&&o._sapDetailRow)c=o._sapDetailRow._sapScope||null;else{let p=dt(m);p&&p.hasAttribute("item")&&(c=p._sapScope||null)}return{state:(I(m)||d.root)._sapScope||d._state||{},item:c,el:m,root:d._state||{}}}function s(m,d,c){if(!m.hasAttribute("confirm")){c();return}let o=m.getAttribute("confirm"),i=o,h=D(o);if(!h.error)try{let N=H(h,r(m,d));(typeof N=="string"||typeof N=="number")&&(i=String(N))}catch{}let p=Yt();if(!p){window.confirm(i)&&c();return}if(m._sapGatePending)return;m._sapGatePending=!0;let v=()=>{m._sapGatePending=!1};p(i,()=>{v(),c()}).catch(v)}function f(m,d){for(let c of m.attributes){if(!c.name.startsWith("set:"))continue;let o=c.name.slice(4),i=D(c.value);if(i.error){d.diag.error("E08",m,{attr:c.name,expr:c.value,problem:String(i.error.message)});continue}let h;try{h=H(i,r(m,d))}catch(v){d.diag.error("E24",m,{attr:c.name,expr:c.value,problem:String(v.message)});continue}let p=n(m);p&&(p[o]=h)}}function u(m,d){let c=m.closest("[item]");if(!c)return;let o=O(c.parentElement),i=o.indexOf(c);d==="up"&&i>0?t.placeBefore(c,o[i-1]):d==="down"&&i<o.length-1&&t.placeBefore(o[i+1],c)}function T(m,d,c){if(d)return at(c.root,m,d);let o=m;for(;o;){if(o.hasAttribute&&o.hasAttribute("items"))return o;o=o.parentElement}let i=I(m)||c.root,h=[];return W(i,p=>{p.hasAttribute("items")&&h.push(p)}),h[0]||null}function E(m,d){let c=m==null||m==="",o=d==null||d==="";if(c&&o)return 0;if(c)return 1;if(o)return-1;let i=Number(m),h=Number(d);return!Number.isNaN(i)&&!Number.isNaN(h)?i-h:String(m)<String(d)?-1:String(m)>String(d)?1:0}function y(m,d,c,o){let i=T(m,c,o);if(!i){o.diag.error("E17",m,{attr:"sort:"+d,problem:`no items list resolvable for sort:${d}`});return}let h=O(i),p=C=>C._sapScope?C._sapScope[d]:void 0,v=[...h].sort((C,q)=>E(p(C),p(q))),ot=v.every((C,q)=>C===h[q])?[...v].reverse():v;for(let C of ot)t.moveInto(i,C);t.schedule(o,"sort:"+d)}function l(m){if(!m||m.hidden)return;let d=m.querySelector("[bind]:not([type=hidden]), [contenteditable]");d&&typeof d.focus=="function"&&d.focus()}function w(m,d){s(m,d,()=>{let c=n(m);for(let o of[...m.attributes]){let i=o.name;if(i==="trigger-remove")c&&c.$remove();else if(i==="trigger-reset")c&&c.$reset();else if(i==="trigger-add"){let h=c&&c.$add(o.value);h&&l(h.$el)}else i==="move:up"?(u(m,"up"),t.schedule(d,"move:up")):i==="move:down"?(u(m,"down"),t.schedule(d,"move:down")):i.startsWith("move:to")?c&&c.$move(o.value):i.startsWith("sort:")&&y(m,i.slice(5),o.value,d)}[...m.attributes].some(o=>o.name.startsWith("set:"))&&f(m,d)})}function k(m){let d=m.target;if(!d||d.nodeType!==1)return;let c=t.appFor(d);if(!c)return;let o=dn(d,c.root);o&&w(o,c)}function L(m){let d=R(m),c=m.getAttribute("default");d.kind==="checkbox"?d.write(c===""||c==="true"):d.write(c??"")}function b(m,d,c){let o=n(m);if(!o)return;let i=o.$add(c);if(!i)return;let h=[];W(m,p=>{p.hasAttribute("bind")&&h.push(p)});for(let p of h){let v=tt(i.$el,p.getAttribute("bind"));v&&R(v).write(R(p).read())}h.forEach(L),h.length?typeof h[0].focus=="function"&&h[0].focus():l(i.$el)}function g(m){let d=m.target;if(!d||!d.hasAttribute||!d.hasAttribute("trigger-add"))return;let c=t.appFor(d);c&&(m.preventDefault(),s(d,c,()=>b(d,c,d.getAttribute("trigger-add"))))}function a(m){let d=m.target,c=t.appFor(d);c&&setTimeout(()=>{d.querySelectorAll("[bind]").forEach(o=>{o.dispatchEvent(new Event("input",{bubbles:!0})),o.dispatchEvent(new Event("change",{bubbles:!0}))}),t.schedule(c,"reset")},0)}function A(m){let d=t.appFor(m.target);d&&t.schedule(d,"toggle")}function S(m){let d=m.target;if(!d||d.nodeType!==1)return;let c=t.appFor(d);if(!c)return;d.hasAttribute("persist")&&!yt(d)&&et(d);let o=it(d);if(o&&o._sapDetailRow&&d.hasAttribute("bind")){let i=tt(o._sapDetailRow,d.getAttribute("bind"));if(i&&i!==d){R(i).write(R(d).read());return}}t.schedule(c,m.type+" "+(d.id||d.tagName.toLowerCase()))}function x(m){let d=m.detail||{};for(let c of[d.from,d.to,m.target]){if(!c||c.nodeType!==1)continue;let o=t.appFor(c);o&&t.schedule(o,"sorted")}}function $(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 c=(d.getAttribute("type")||"text").toLowerCase();if(c!=="text"&&c!=="tel"&&c!=="search"||!t.appFor(d))return;m.preventDefault();let i=P(d.getAttribute("step"))||1,h=m.key==="ArrowUp"?1:-1,p=P(d.value)+i*(m.shiftKey?10:1)*h,v=d.getAttribute("min"),N=d.getAttribute("max");v!==null&&v!==""&&p<P(v)&&(p=P(v)),N!==null&&N!==""&&p>P(N)&&(p=P(N)),R(d).write(String(Number(p.toFixed(2))))}function M(m=document){m.addEventListener("click",k),m.addEventListener("submit",g),m.addEventListener("reset",a),m.addEventListener("toggle",A,!0),m.addEventListener("input",S),m.addEventListener("change",S),m.addEventListener("clay:sorted",x),m.addEventListener("keydown",$)}return{install:M}}var pe=/^(set:|move:|sort:|trigger-add$|trigger-remove$|trigger-reset$)/;function Wt(t){return`${t.tagName.toLowerCase()}[sap]`}function pn(t){let e=0;for(let n of t.querySelectorAll("*"))for(let r of n.attributes)if(pe.test(r.name)){e++;break}for(let n of t.attributes)if(pe.test(n.name)){e++;break}return e}function me(t){let e=[],n=r=>{for(let s of r.attributes){let f=s.name;(f.startsWith("calc:")||f==="text"||f.startsWith("text:")||f==="show"||f.startsWith("attr:")||f.startsWith("class:")||f.startsWith("css:")||f==="effect"||f==="invalid"||f.startsWith("set:")||f==="detail")&&e.push({el:r,attr:f,src:s.value})}};n(t);for(let r of t.querySelectorAll("*"))n(r);return e}function he(t){function e(l){let w=l._stats||{},k=l.root;return{root:Wt(k),fields:w.fields||0,calcs:w.calcs||0,paints:w.paints||0,actions:pn(k),lists:(k.hasAttribute("items")?1:0)+k.querySelectorAll("[items]").length,rows:k.querySelectorAll("[item]:not([template])").length,warnings:l.diag.warnings.length,errors:l.diag.errors.length,mountWrites:l._mountWrites||0,ms:Math.round((l._mountMs||0)*10)/10,passes:l._passes||0,lastPass:l._lastPass||null,ok:l.diag.errors.length===0&&!l.halted}}function n(){let l=t.apps().map(e);return{ok:l.every(w=>w.ok),apps:l}}function r(l){let w=e(l);return w.ok?`sap \u2713 ${w.root} \xB7 fields ${w.fields} \xB7 calcs ${w.calcs} \xB7 paints ${w.paints} \xB7 actions ${w.actions} \xB7 lists ${w.lists} \xB7 rows ${w.rows} \xB7 warnings ${w.warnings} \xB7 mount writes ${w.mountWrites} \xB7 ${w.ms}ms`:`sap \u2717 ${w.root} \xB7 errors ${w.errors} \xB7 warnings ${w.warnings} \xB7 ${w.ms}ms`}function s(){for(let l of t.apps()){let w=r(l);l.diag.errors.length||l.halted?console.error(w):console.log(w)}}function f(){let l=[],w=[];for(let k of t.apps())l.push(...k.diag.errors),w.push(...k.diag.warnings);return{ok:l.length===0,errors:l,warnings:w,counts:{errors:l.length,warnings:w.length}}}function u(l){return l?typeof l=="string"?document.querySelector(l):l.nodeType===1?l:null:null}function T(l,w){let k=u(l);if(!k)return console.warn("sap why: element not found"),null;let L=[`sap why <${k.tagName.toLowerCase()}> \u2014 ${Et(k)}`],b=[...k.attributes].filter(a=>/^(bind|text|show|effect|invalid|detail|calc:|text:|attr:|class:|css:|set:|state|items|scope)/.test(a.name));for(let a of b)L.push(` ${a.name}="${a.value}"`);let g=k;for(;g&&!g._sapScope;)g=g.parentElement;if(g&&g._sapScope){let a=g._sapScope,A=w?[w]:Object.keys(a);L.push(" reads:");for(let S of A){let x=a[S];typeof x!="function"&&L.push(` ${S} = ${JSON.stringify(Array.isArray(x)?`[${x.length} rows]`:x)}`)}}return L.push(" serialization: textContent and value/checked attributes save with the file; reads live from properties"),console.log(L.join(`
|
|
8
|
-
`)),null}function E(l){let
|
|
4
|
+
var Sap=(()=>{var _t=Object.defineProperty;var Se=Object.getOwnPropertyDescriptor;var xe=Object.getOwnPropertyNames;var $e=Object.prototype.hasOwnProperty;var ke=(t,e)=>{for(var n in e)_t(t,n,{get:e[n],enumerable:!0})},Ne=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of xe(e))!$e.call(t,s)&&s!==n&&_t(t,s,{get:()=>e[s],enumerable:!(r=Se(e,s))||r.enumerable});return t};var Te=t=>Ne(_t({},"__esModule",{value:!0}),t);var Nn={};ke(Nn,{Sap:()=>_,default:()=>kn,mount:()=>Ee,mountAll:()=>pt,runtime:()=>K});function zt(t){let e=!1,n=new Set,r=[];function s(l){l&&(r.push(l),r.length>8&&r.shift())}function i(l,y){s(y),!l._broken&&(n.add(l),!e&&(e=!0,queueMicrotask(a)))}function a(){e=!1;let l=[...n];n.clear();for(let y of l)k(y)}function k(l){if(!l._broken){if(l._passes=(l._passes||0)+1,l._passes>50){l._broken=!0,l._breakerRing=r.slice(),t(l,{breaker:!0});return}l._resetArmed||(l._resetArmed=!0,setTimeout(()=>{l._passes=0,l._resetArmed=!1},0)),t(l)}}function E(l,y){s(y),k(l)}function w(l){l._broken=!1,l._passes=0}return{schedule:i,runNow:E,rearm:w,ring:r}}var _e=0;function Z(t,e="sap"){return t.id||(t.id=`${e}-${(_e++).toString(36)}`),t.id}function Le(t){return t.hasAttribute("scope")||t.hasAttribute("items")||t.hasAttribute("detail")}function Ce(t){return t.hasAttribute("sap-ignore")||t.hasAttribute("template")}function F(t,e){for(let r of t.children)n(r);function n(r){if(r.nodeType!==1||Ce(r))return;let s=Le(r);if(e(r,s),!s)for(let i of r.children)n(i)}}function I(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 mt(t){let e=t;for(;e;){if(e.hasAttribute("detail")||e.hasAttribute("item"))return e;e=e.parentElement}return null}function at(t){let e=t;for(;e;){if(e.hasAttribute("detail"))return e;e=e.parentElement}return null}function tt(t,e){let n=null;return F(t,r=>{!n&&r.getAttribute("bind")===e&&(n=r)}),n}function it(t,e){let n=null;return F(t,r=>{!n&&r.getAttribute("items")===e&&(n=r)}),n}function O(t){return[...t.children].filter(e=>e.hasAttribute("item")&&!e.hasAttribute("template"))}function ht(t){return[...t.children].find(e=>e.hasAttribute("item")&&e.hasAttribute("template"))||null}function P(t){let e=[];if(!t)return e;for(let n of t.trim().split(/\s+/)){if(!n)continue;let r=n,s,i=r.indexOf("=");i>=0&&(s=r.slice(i+1),r=r.slice(0,i));let a=r.split(":"),k=a[0],E="string",w=!1;for(let l of a.slice(1))l==="num"?E="num":l==="bool"?E="bool":l==="transient"&&(w=!0);e.push({name:k,type:E,default:s,transient:w})}return e}function G(t,e){if(e==="num"){if(t==null||t==="")return 0;let n=Number(t);return Number.isNaN(n)?0:n}return e==="bool"?t==="true"||t===""||t==="1":t??""}function bt(t,e){return e==="bool"?t?"true":"false":t==null?"":String(t)}function gt(t,e){let n=t._sapTransient||(t._sapTransient={});if(!(e.name in n)){let r=t.getAttribute(e.name);r==null&&(r=e.default!=null?e.default:e.type==="num"?"0":e.type==="bool"?"false":""),n[e.name]=G(r,e.type)}return t.hasAttribute(e.name)&&t.removeAttribute(e.name),n[e.name]}function Lt(t,e,n){(t._sapTransient||(t._sapTransient={}))[e.name]=n,t.hasAttribute(e.name)&&t.removeAttribute(e.name)}function ut(t,e,n){let r=String(n).split("."),s=r[r.length-1];if(r.length===1){let k=Re(e,s);return k||(t.getAttribute("items")===s?t:t.querySelector(`[items="${s}"]`))}let i=r[r.length-2],a=[...t.querySelectorAll(`[scope="${i}"]`)].find(k=>it(k,s));return a?it(a,s):null}function Re(t,e){let n=I(t);for(;n;){if(n.getAttribute("items")===e)return n;let r=it(n,e);if(r)return r;n=I(n.parentElement)}return null}function B(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 yt(t,e){return Array.isArray(t)?e==null?t:t.map(n=>typeof e=="function"?e(n):n?.[e]):[]}function Ht(t,e){return yt(t,e).reduce((n,r)=>n+B(r),0)}function Me(t,e){return Array.isArray(t)?e==null?t.length:t.reduce((n,r)=>n+(e(r)?1:0),0):0}function De(t,e){let n=yt(t,e);return n.length?Ht(t,e)/n.length:0}function Ie(t,e){let n=yt(t,e).filter(r=>r!=null&&r!=="");return n.length?n.every(r=>typeof r=="number"||!Number.isNaN(Number(r)))?Math.min(...n.map(Number)):n.reduce((r,s)=>String(r)<=String(s)?r:s):0}function We(t,e){let n=yt(t,e).filter(r=>r!=null&&r!=="");return n.length?n.every(r=>typeof r=="number"||!Number.isNaN(Number(r)))?Math.max(...n.map(Number)):n.reduce((r,s)=>String(r)>=String(s)?r:s):0}function Fe(t,e,n){let r=B(t)===1?e:n??e+"s";return`${t} ${r}`}function Pe(t,e){let n=new Date(t),r=new Date(e);return Number.isNaN(+n)||Number.isNaN(+r)?0:Math.round((r-n)/864e5)}function H(t){return typeof t=="number"?t:Number(t)}var ct={usd:t=>"$"+H(t).toLocaleString("en-US",{maximumFractionDigits:0}),usd2:t=>"$"+H(t).toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}),pct:t=>Math.round(H(t))+"%",pct1:t=>H(t).toFixed(1)+"%",int:t=>Math.round(H(t)).toLocaleString("en-US"),num:t=>H(t).toLocaleString("en-US"),num2:t=>H(t).toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2}),compact:t=>H(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=H(t),n=Math.floor(e/100),r=n%10,s=Math.floor(n/10)%60;return`${Math.floor(n/600)}:${String(s).padStart(2,"0")}.${r}`}},Oe=new Set(["usd","usd2","pct","pct1","int","num","num2","compact","clock"]);function Ut(t,e){if(!t)return e==null?"":String(e);let n=ct[t];if(typeof n!="function"){let r=new Error(`unknown format "${t}"`);throw r.sapCode="E22",r}if(Oe.has(t)){let r=typeof e=="number"?e:Number(e);if(!Number.isFinite(r)){let s=new Error(`format "${t}" received ${typeof e=="string"?`"${e}"`:e}`);throw s.sapCode="E22",s}}return n(e)}function jt(){return[ct,B,Ht,Me,De,Ie,We,Fe,Pe]}var Be=["state","item","el","root","fmt","num","sum","count","avg","min","max","plural","days"],wt=new Map,Vt=/\bstate\.([a-z][a-z0-9_]*)/g,Yt=/\bitem\.([a-z][a-z0-9_]*)/g;function qe(t){let e=new Set,n=new Set,r;for(Vt.lastIndex=0;r=Vt.exec(t);)e.add(r[1]);for(Yt.lastIndex=0;r=Yt.exec(t);)n.add(r[1]);return{state:e,item:n}}function D(t,e=!1){let n=(e?"!":"")+t,r=wt.get(n);if(r)return r;wt.size>512&&wt.clear();try{let s=e?`"use strict";
|
|
5
|
+
${t}`:`"use strict"; return (${t});`;r={fn:new Function(...Be,s),src:t,statement:e,deps:qe(t),error:null}}catch(s){r={fn:null,src:t,statement:e,deps:{state:new Set,item:new Set},error:s}}return wt.set(n,r),r}function U(t,e){if(t.error)throw t.error;return t.fn(e.state,e.item,e.el??null,e.root,...jt())}function Gt(t){let e=new Map;for(let a of t)e.set(a.name,a);let n=[],r=new Map,s=[];function i(a){let k=r.get(a.name);if(k!==1){if(k===0){let E=[...s.slice(s.indexOf(a.name)),a.name].join(" -> "),w=new Error(`calc: cycle: ${E}`);throw w.sapCode="E07",w.cycle=E,w}r.set(a.name,0),s.push(a.name);for(let E of a.entry.deps.state){let w=e.get(E);w&&w!==a&&i(w)}for(let E of a.entry.deps.item){let w=e.get(E);w&&w!==a&&i(w)}s.pop(),r.set(a.name,1),n.push(a)}}for(let a of t)i(a);return n}function Xt(t){return(t.getAttribute("type")||"text").toLowerCase()}function et(t){let e=t.tagName;if(e==="INPUT"){let n=Xt(t);n==="checkbox"||n==="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 n=t.options;for(let r=0;r<n.length;r++)n[r].selected?n[r].setAttribute("selected",""):n[r].removeAttribute("selected")}}function Kt(t,e=t){let n=t.tagName;if(n==="INPUT"){let r=Xt(t);r==="checkbox"||r==="radio"?e.checked?t.setAttribute("checked",""):t.removeAttribute("checked"):t.setAttribute("value",e.value);return}if(n==="TEXTAREA"){t.textContent=e.value,t.removeAttribute("data-value");return}if(n==="SELECT"){let r=t.options,s=e.options;for(let i=0;i<r.length;i++)s[i]&&s[i].selected?r[i].setAttribute("selected",""):r[i].removeAttribute("selected")}}function At(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,n=window.hyperclay;return t==="consent"?e?.confirm||n?.consent||null:e?.[t]||n?.[t]||null}var Ct=["clay:mutation-ready","hyperclay:mutation-ready"],ze=["clay:sync-applied","hyperclay:livesync-applied"],He=["clay:ready","hyperclay:ready"];function ft(t,e,n){let r=null,s=i=>{r!==null&&r!==i.type||(r=i.type,queueMicrotask(()=>{r=null}),n(i))};for(let i of e)t.addEventListener(i,s);return()=>{for(let i of e)t.removeEventListener(i,s)}}function vt(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 Jt(){let t=W("consent");return typeof t=="function"?t:null}function Qt(t,e){if(typeof e!="function")throw new Error("Sap.batch(label, fn): fn must be a function");let n=W("undo");n&&n.flush&&n.flush();let r=e();if(r&&typeof r.then=="function")throw new Error("Sap.batch fn must be synchronous (it returned a promise)");return n&&n.commitCaptured&&n.commitCaptured(t),r}function Zt(t){if(typeof window>"u"||typeof document>"u")return;let e=()=>{let i=!1;for(let a of t.apps())a.root.isConnected?t.runNow(a,"platform"):i=!0;i&&(t.pruneDisconnected(),t.remountIfPresent())};ft(document,ze,e);let n=!1,r=()=>{},s=()=>{if(n)return!0;let i=W("undo");if(!i||typeof i.on!="function")return!1;let a=i.on("undo",e);return typeof a!="function"?!1:typeof i.on("redo",e)!="function"?(a(),!1):(n=!0,r(),!0)};if(!s()){let i=ft(document,Ct,s),a=ft(document,He,s);r=()=>{i(),a()};let k=W("ready");k&&typeof k.then=="function"&&k.then(s,()=>{})}}function Ue(t){let e=t.tagName;if(e==="INPUT"){let n=(t.getAttribute("type")||"text").toLowerCase();return n==="checkbox"?"checkbox":n==="radio"?"radio":n==="number"||n==="range"?"number":n==="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 Ve(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(n=>n.value);case"hidden":case"text":return t.value;case"leaf":return t.textContent;default:return t.value}}function Ye(t,e,n){switch(e){case"checkbox":t.checked=!!n;break;case"radio":t.checked=String(t.value)===String(n);break;case"number":case"text":case"hidden":t.value=n==null?"":String(n);break;case"select-one":t.value=n==null?"":String(n);break;case"select-multiple":{let r=new Set((Array.isArray(n)?n:[n]).map(String));for(let s of t.options)s.selected=r.has(s.value);break}case"leaf":t.textContent=n==null?"":String(n);break;default:t.value=n==null?"":String(n)}}function te(t){if(t.hasAttribute("transient")){t.removeAttribute("value"),t.removeAttribute("checked"),t.removeAttribute("data-value");return}vt(t)||et(t)}function Ge(t){t.dispatchEvent(new Event("input",{bubbles:!0})),t.dispatchEvent(new Event("change",{bubbles:!0}))}function M(t){let e=Ue(t);return{el:t,kind:e,read(){return Ve(t,e)},write(n,r={}){Ye(t,e,n),r.noMirror||te(t),r.silent||Ge(t)},mirror(){te(t)}}}var Rt={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"},W03:{slug:"unknown-colon-attribute",behavior:"WARN"},W04:{slug:"expression-in-when",behavior:"WARN"},W30:{slug:"nonzero-mount-writes",behavior:"WARN"}},Et=["disabled","readonly","required","checked","selected","multiple","open","inert","autofocus","novalidate","hidden"],lt=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"]),St=new Set(["sap","scope","items","item","template","bind","calc","text","show","attr","set","trigger","move","sort","detail","effect","invalid","confirm","transient","default","persist","sortable","editmode"]);function xt(t){if(!t||t.nodeType!==1)return"?";if(t.id)return`${t.tagName.toLowerCase()}#${t.id}`;let e=[],n=t,r=0;for(;n&&n.nodeType===1&&r<4;){let s=n.tagName.toLowerCase();if(n.hasAttribute("sap"))s+="[sap]";else if(n.parentElement){let i=[...n.parentElement.children].filter(a=>a.tagName===n.tagName);i.length>1&&(s+=`:nth-of-type(${i.indexOf(n)+1})`)}if(e.unshift(s),n.hasAttribute("sap"))break;n=n.parentElement,r++}return e.join(" > ")}function ee(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}var nt=class{constructor(e){this.appName=e,this.errors=[],this.warnings=[],this.halted=!1,this.haltReason=null}block(e,n,r={}){let s=(Rt[e]||{}).slug||"error",i={code:e,slug:s,el:xt(n),attr:r.attr||null,expr:r.expr||null,key:r.key||null,problem:r.problem||"",didYouMean:r.didYouMean||null,fix:r.fix||null,phase:r.phase||"runtime"},a=[`
|
|
6
|
+
`+(e[0]==="W"?"sap \u26A0 ":"sap \u2717 ")+e+" "+s];return a.push(` at ${i.el}${i.attr?` \u2014 ${i.attr}="${i.expr??""}"`:""}`),i.problem&&a.push(` problem: ${i.problem}`),i.didYouMean&&a.push(` did you mean: ${i.didYouMean}`),i.fix&&a.push(` fix: ${i.fix}`),console.error(a.join(`
|
|
7
|
+
`)),i}error(e,n,r={}){let s=this.block(e,n,r);return this.errors.push(s),s}warn(e,n,r={}){let s=this.block(e,n,r);return this.warnings.push(s),s}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 X(t,e){t&&t.getAttribute("sap-error")!==e&&t.setAttribute("sap-error",e)}function $t(t){t&&t.hasAttribute("sap-error")&&t.removeAttribute("sap-error")}function dt(t,e){let n=null,r=3;for(let s of e){let i=Xe(t,s);i<r&&(r=i,n=s)}return n}function Xe(t,e){let n=t.length,r=e.length,s=Array.from({length:n+1},(i,a)=>[a,...new Array(r).fill(0)]);for(let i=0;i<=r;i++)s[0][i]=i;for(let i=1;i<=n;i++)for(let a=1;a<=r;a++)s[i][a]=Math.min(s[i-1][a]+1,s[i][a-1]+1,s[i-1][a-1]+(t[i-1]===e[a-1]?0:1));return s[n][r]}var j=null,Nt=!1,rt=null;function ne(t){let e=null;return{kind:"hub",subscribe(n){let r=t.onAnyChange({debounce:0,require:"observed"},n);typeof r=="function"&&(e=r)},suppress(n){t.pause();try{return n()}finally{t.resume()}},teardown(){if(e){try{e()}catch{}e=null}}}}function Ke(){let t=null;return{kind:"native",subscribe(e){t=new MutationObserver(r=>e(Je(r)));let n=typeof document<"u"&&document.body||typeof document<"u"&&document.documentElement;n&&t.observe(n,{childList:!0,subtree:!0,attributes:!0,characterData:!0})},suppress(e){let n=W("undo");n&&n.pause&&n.pause();try{return e()}finally{t&&t.takeRecords(),n&&n.resume&&n.resume()}},teardown(){t&&(t.disconnect(),t=null)}}}function Je(t){let e=[];for(let n of t)if(n.type==="attributes"){let r=n.target;r&&r.nodeType===1&&!kt(r)&&e.push({type:"attribute",element:r})}else if(n.type==="characterData"){let r=n.target&&n.target.parentElement;r&&!kt(r)&&e.push({type:"characterData",element:r})}else if(n.type==="childList"){for(let r of n.addedNodes)if(!(r.nodeType!==1||kt(r))&&(e.push({type:"add",element:r}),r.querySelectorAll))for(let s of r.querySelectorAll("*"))kt(s)||e.push({type:"add",element:s});for(let r of n.removedNodes)r.nodeType===1&&e.push({type:"remove",element:r,parent:n.target})}return e}function kt(t){return!!(t.closest&&t.closest("[sap-ignore],[template]"))}function Qe(t,e){t.pruneDisconnected();let n=new Set,r=!1;for(let s of e){let i=s.type==="remove"?s.parent:s.element,a=i&&t.appFor(i);a&&n.add(a),s.type==="add"&&s.element&&s.element.nodeType===1&&s.element.hasAttribute&&s.element.hasAttribute("sap")&&!(t.isRegistered&&t.isRegistered(s.element))&&(r=!0)}r&&t.remountIfPresent();for(let s of n)s.root.isConnected&&t.schedule(s,"mutation")}function re(t){if(j)return j.suppress(t);let e=W("undo");if(e&&e.pause&&e.resume){e.pause();try{return t()}finally{e.resume()}}return t()}function Mt(t,e){Nt=!0,j=t,t.subscribe(n=>Qe(e,n))}function Dt(t){if(Nt||typeof window>"u"||typeof document>"u")return;let e=W("Mutation");if(e&&typeof e.onAnyChange=="function"){Mt(ne(e),t);return}typeof MutationObserver=="function"&&(Mt(Ke(),t),rt=ft(document,Ct,function(){let r=W("Mutation");r&&(rt(),rt=null,j&&j.teardown(),Nt=!1,Mt(ne(r),t))}))}function oe(){if(j)try{j.teardown()}catch{}rt&&typeof document<"u"&&rt(),j=null,Nt=!1,rt=null}var ae=new Set(Et);function ot(t,e={}){if(e.breaker){t.diag.error("E26",t.root,{problem:"recompute loop halted after 50 passes; recent triggers: "+(t._breakerRing||[]).join(", ")}),X(t.root,"loop");return}re(()=>Ze(t,e))}function Ze(t,e){let n=t.root,r={},s=[],i=[],a=[],k=[],E=[],w=new Set;t.diag.errors=[];let l={root:r,state:r,item:null,ownerEl:n,projection:!1};function y(o,u){let h=o.getAttribute(u.name);return h==null&&(h=u.default!=null?u.default:u.type==="num"?"0":u.type==="bool"?"false":"",E.push({el:o,name:u.name,value:bt(G(h,u.type),u.type)})),G(h,u.type)}function N(o,u){let h=P(o.getAttribute("state")||"");o._sapStateDecls=h;for(let p of h){if(p.type==="string"&&ae.has(p.name)&&typeof o[p.name]=="boolean"){u[p.name]=o.hasAttribute(p.name);continue}if(p.transient){u[p.name]=gt(o,p);continue}u[p.name]=y(o,p)}}function L(o,u){if(!o.hasAttribute("bind"))return;let h=o.getAttribute("bind"),p=u.item||u.state,v=M(o);v.kind==="radio"?(h in p||(p[h]=""),o.checked&&(p[h]=o.value)):p[h]=v.read(),o.hasAttribute("transient")&&(o.removeAttribute("value"),o.removeAttribute("checked"))}function b(o,u){for(let h of o.attributes){let p=h.name,v=h.value;if(p.startsWith("calc:"))s.push({owner:u.item||u.state,ownerEl:u.ownerEl,name:p.slice(5),entry:D(v),el:o,ctx:u});else if(p==="text"||p.startsWith("text:"))i.push({el:o,kind:"text",fmt:p.includes(":")?p.slice(5):null,entry:D(v),ctx:u});else if(p==="show")i.push({el:o,kind:"show",entry:D(v),ctx:u});else if(p.startsWith("attr:"))i.push({el:o,kind:"attr",arg:p.slice(5),entry:D(v),ctx:u});else if(p.startsWith("class:"))i.push({el:o,kind:"class",arg:p.slice(6),entry:D(v),ctx:u});else if(p.startsWith("css:"))i.push({el:o,kind:"css",arg:p.slice(4),entry:D(v),ctx:u});else if(p==="effect")a.push({el:o,entry:D(v,!0),ctx:u});else if(p==="invalid")k.push({el:o,entry:D(v),ctx:u});else if(p.startsWith("show-when:")||p.startsWith("option:")){let T=p.slice(p.indexOf(":")+1);w.add(T),i.push({el:o,kind:"when",match:"show",field:T,values:v.split("|"),ctx:u})}else if(p.startsWith("hide-when:")){let T=p.slice(p.indexOf(":")+1);w.add(T),i.push({el:o,kind:"when",match:"hide",field:T,values:v.split("|"),ctx:u})}else if(p.startsWith("option-not:")){let T=p.slice(p.indexOf(":")+1);w.add(T),i.push({el:o,kind:"when",match:"show-not",field:T,values:v.split("|"),ctx:u})}}u.projection&&o.hasAttribute("bind")&&i.push({el:o,kind:"projection",field:o.getAttribute("bind"),ctx:u})}function g(o,u,h){Z(u,"row"),Object.defineProperty(o,"$key",{value:u.id,enumerable:!1}),Object.defineProperty(o,"$index",{value:h,enumerable:!1}),Object.defineProperty(o,"$el",{value:u,enumerable:!1})}function c(o,u,h){N(o,u),o._sapScope=u,!h.projection&&o.hasAttribute("bind")&&L(o,h),b(o,h),o.hasAttribute("items")?x(o,u,h):A(o,u,h)}function A(o,u,h){F(o,(p,v)=>{v?p.hasAttribute("scope")?S(p,u,h):p.hasAttribute("items")?(b(p,h),x(p,u,h)):p.hasAttribute("detail")&&R(p,u,h):(h.projection||L(p,h),b(p,h))})}function S(o,u,h){let p=o.getAttribute("scope"),v={};u[p]=v;let T={root:h.root,state:v,item:null,ownerEl:o,projection:h.projection};c(o,v,T)}function x(o,u,h){let p=o.getAttribute("items"),v=[];u[p]=v,o._sapList=v,O(o).forEach((T,st)=>{let C={};g(C,T,st);let z={root:h.root,state:h.state,item:C,ownerEl:T,projection:h.projection};c(T,C,z),v.push(C)})}function $(o,u){let h=String(o).split("."),p=u.state;for(let v of h)p=p?.[v];if(p===void 0){p=u.root;for(let v of h)p=p?.[v]}return p}function R(o,u,h){for(let Q of P(o.getAttribute("state")||""))Q.name in u||(u[Q.name]=y(o,Q));o._sapScope=u;let p=o.getAttribute("detail")||"",v=/^([\w.]+)\s+by\s+(.+)$/.exec(p);if(!v){o.hidden=!0,o._sapDetailRow=null;return}let T=v[1],st=v[2].trim(),C=$(T,h),z;try{z=U(D(st),{state:u,item:h.item,el:o,root:h.root})}catch{z=void 0}let J=Array.isArray(C)?C.find(Q=>Q&&String(Q.$key)===String(z)):null;if(o._sapDetailRow=J?J.$el:null,!J){o.hidden||(o.hidden=!0);return}o.hidden&&(o.hidden=!1);let qt={root:h.root,state:u,item:J,ownerEl:J.$el,projection:!0};b(o,qt),A(o,J,qt)}if(c(n,r,l),E.length&&w.size)for(let o of E)w.has(o.name)&&o.el.getAttribute(o.name)==null&&o.el.setAttribute(o.name,o.value);let m=new Map;for(let o of s){let u=m.get(o.owner);u||(u={ownerEl:o.ownerEl,list:[]},m.set(o.owner,u)),u.list.push(o)}let d=[...m.values()].sort((o,u)=>ie(u.ownerEl)-ie(o.ownerEl));for(let o of d){let u;try{u=Gt(o.list)}catch(h){t.diag.error("E07",o.list[0].el,{problem:h.message}),u=o.list}for(let h of u)try{h.owner[h.name]=U(h.entry,{state:h.ctx.state,item:h.ctx.item,el:h.el,root:h.ctx.root}),$t(h.el)}catch(p){h.owner[h.name]=void 0,t.diag.error("E24",h.el,{attr:"calc:"+h.name,expr:h.entry.src,problem:String(p.message)}),X(h.el,p.sapCode||"E24")}}let f=0;for(let o of i)f+=nn(o,t);for(let o of a)rn(o,t);for(let o of k)on(o);t._state=r,t._stats={fields:Object.keys(r).filter(o=>typeof r[o]!="function").length,calcs:s.length,paints:i.length,lists:m.size,writes:f},t._lastPass={trigger:e.trigger||"refresh",writes:f},t._debug&&console.log(`sap pass \xB7 trigger: ${t._lastPass.trigger} \xB7 writes ${f}/${i.length}`)}function tn(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 It(t,e,n,r){let s=t;for(;s&&s.nodeType===1;){if(s.hasAttribute&&s.hasAttribute(e)){let i=n.includes(s.getAttribute(e));if(r?!i:i)return!0}s=s.parentElement}return!1}function en(t,e){if(t===t.ownerDocument.activeElement)return 0;let n=M(t),r=n.read(),s=e??"";return String(r)!==String(s)?(n.write(s,{silent:!0}),1):0}function nn(t,e){if(t.kind==="projection")return en(t.el,t.ctx.item?t.ctx.item[t.field]:"");if(t.kind==="when")return se(t,null);let n={state:t.ctx.state,item:t.ctx.item,el:t.el,root:t.ctx.root};try{let r=U(t.entry,n),s=se(t,r);return $t(t.el),s}catch(r){return e.diag.error(r.sapCode==="E22"?"E22":"E24",t.el,{attr:tn(t),expr:t.entry&&t.entry.src,problem:String(r.message)}),X(t.el,r.sapCode||"E24"),0}}function se(t,e){let n=t.el;switch(t.kind){case"text":{let r=t.fmt!=null?Ut(t.fmt,e):e==null?"":String(e);return n.textContent!==r?(n.textContent=r,1):0}case"show":{let r=!e;return n.hidden!==r?(n.hidden=r,1):0}case"when":{let r=W("optionVisibility");if(r&&r._started)return n._sapWhen&&n.hidden?(n.hidden=!1,n._sapWhen=!1,1):0;let s;t.match==="hide"?s=!It(n,t.field,t.values,!1):t.match==="show-not"?s=It(n,t.field,t.values,!0):s=It(n,t.field,t.values,!1),n._sapWhen=!0;let i=!s;return n.hidden!==i?(n.hidden=i,1):0}case"attr":{let r=t.arg;if(ae.has(r)){let i=n.hasAttribute(r);return e&&!i?(n.setAttribute(r,""),1):!e&&i?(n.removeAttribute(r),1):0}let s=typeof e=="boolean"?String(e):e==null?"":String(e);return n.getAttribute(r)!==s?(n.setAttribute(r,s),1):0}case"class":{let r=!!e;return n.classList.contains(t.arg)!==r?(n.classList.toggle(t.arg,r),1):0}case"css":{let r=e==null?"":String(e);return n.style.getPropertyValue("--"+t.arg)!==r?(n.style.setProperty("--"+t.arg,r),1):0}default:return 0}}function rn(t,e){try{U(t.entry,{state:t.ctx.state,item:t.ctx.item,el:t.el,root:t.ctx.root}),$t(t.el)}catch(n){e.diag.error("E24",t.el,{attr:"effect",expr:t.entry&&t.entry.src,problem:String(n.message)}),X(t.el,"E24")}}function on(t){let e="";try{let n=U(t.entry,{state:t.ctx.state,item:t.ctx.item,el:t.el,root:t.ctx.root});e=typeof n=="string"?n:""}catch{e=""}typeof t.el.setCustomValidity=="function"&&t.el.setCustomValidity(e)}function ie(t){let e=0,n=t;for(;n&&!(n.hasAttribute&&n.hasAttribute("sap"));)n=n.parentElement,e++;return e}var sn=new Set(Et),ue=new Set(["calc","text","attr","class","css","set","move","sort","option","option-not","show-when","hide-when","editmode"]),an=new Set(["show-when","hide-when","option","option-not"]),un=/\b(?:state|item|root)\.|===|!==|&&|\|\||[()]|^\s*!/,ce=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"]);function cn(t){return t.tagName==="INPUT"||t.tagName==="SELECT"||t.tagName==="TEXTAREA"}function Wt(t){return t.hasAttribute("bind")}function fn(t,e){e(t);for(let r of t.children)n(r);function n(r){if(r.nodeType===1&&!((r.hasAttribute("sap-ignore")||r.hasAttribute("template"))&&r.hasAttribute("sap-ignore"))){e(r);for(let s of r.children)n(s)}}}function Tt(t,e){let n=!1,r=(a,k,E)=>{e.error(a,k,E),n=!0},s=t.ownerDocument.createTreeWalker(t,4),i;for(;i=s.nextNode();)if(/\{\{.*\}\}/.test(i.nodeValue||"")){r("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 fn(t,a=>{let k=a.closest&&a.closest("[detail]");for(let E of[...a.attributes]){let w=E.name,l=ee(w);if(l){r("E01",a,{attr:w,expr:E.value,problem:`"${w}" is a foreign-dialect attribute; Sap has no ${w.split(/[:=]/)[0]} directive`,fix:l+" \u2014 or wrap the subtree in sap-ignore if intentional"});continue}if(w.includes(":")){let y=w.slice(0,w.indexOf(":"));if(ue.has(y)){if(an.has(y)&&un.test(E.value)){let N=w.slice(w.indexOf(":")+1);e.warn("W04",a,{attr:w,expr:E.value,problem:`${y}: compares the "${N}" attribute against a literal value, not a JS expression`,fix:`use show="${E.value}" for an expression, or a literal like ${y}:${N}="overview"`})}}else{let N=dt(y,[...ue]);e.warn("W03",a,{attr:w,problem:`unknown "${y}:" attribute`,didYouMean:N?`${N}:`:null})}}else if(!ce.has(w)&&!lt.has(w)&&!sn.has(w)&&!/^(data-|aria-|on)/.test(w)&&!(w in a)){let y=dt(w,[...ce]);y&&e.warn("W03",a,{attr:w,problem:`unknown "${w}" attribute`,didYouMean:y})}w==="attr:hidden"&&e.warn("W03",a,{attr:w,problem:"attr:hidden paints the wrong attribute",fix:'use show="expr"'}),(w==="attr:value"||w==="attr:checked"||w==="attr:selected")&&Wt(a)&&r("E30",a,{attr:w,problem:"attr: on a bound control collides with persist ownership",fix:"remove it; bind owns this attribute"}),w==="effect"&&Wt(a)&&/\b(value|checked)\s*=[^=]/.test(E.value)&&r("E30",a,{attr:w,expr:E.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"}),(w==="text"||w.startsWith("text:")||w==="show")&&cn(a)&&(w==="show"||r("E18",a,{attr:w,problem:"paint belongs on output elements, not form controls",fix:"move the paint to an <output> or <span>"}))}if(a.hasAttribute("state")){let E=P(a.getAttribute("state")),w=new Set;for(let l of E)l.name.includes("-")&&r("E08",a,{attr:"state",problem:`field "${l.name}" is not a valid identifier (the hyphen parses as subtraction)`,fix:`rename to ${l.name.replace(/-/g,"")}`}),w.has(l.name)&&r("E04",a,{attr:"state",problem:`field "${l.name}" is declared twice in one scope`}),w.add(l.name),St.has(l.name)&&r("E05",a,{attr:"state",problem:`"${l.name}" is a reserved Sap word`}),lt.has(l.name)&&r("E06",a,{attr:"state",problem:`"${l.name}" is a global HTML attribute name; pick another field name`}),l.name==="open"&&a.tagName==="DIALOG"&&r("E33",a,{attr:"state",problem:"dialog open is transient",fix:"use showModal() \u2014 declare state= only on <details> or popovers"})}if(Wt(a)){if(a.hasAttribute("-"),a.tagName==="INPUT"){let E=(a.getAttribute("type")||"text").toLowerCase();E==="file"&&r("E32",a,{attr:"bind",problem:"files never serialize into an HTML file",fix:"use no-save + effect instead of bind"}),E==="password"&&!a.hasAttribute("transient")&&r("E31",a,{attr:"bind",problem:"a password must never serialize into a world-readable file",fix:"add transient to the password input"})}else if(a.tagName!=="SELECT"&&a.tagName!=="TEXTAREA"){let E=a.getAttribute("contenteditable");!(E!=null&&E!=="false")&&a.children.length>0&&r("E20",a,{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(a.hasAttribute("transient")&&a.hasAttribute("persist")&&r("E34",a,{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"}),a.hasAttribute("item")&&!a.hasAttribute("template")){let E=a.parentElement;(!E||!E.hasAttribute("items"))&&r("E10",a,{problem:"an [item] must be a direct child of an [items] list",fix:'wrap it in a container with items="name"'})}if(a.hasAttribute("items")&&k&&r("E17",a,{attr:"items",problem:"nested items inside a detail panel is a v1 mount error (nested collections ship in v1.1)"}),a.hasAttribute("items")){let E=t.querySelector(`[trigger-add="${a.getAttribute("items")}"]`);!ht(a)&&O(a).length===0&&E&&r("E17",a,{attr:"items",problem:`trigger-add targets items="${a.getAttribute("items")}" but it has no [item template] to clone`})}}),n&&(e.halted=!0,e.haltReason=e.errors[0]?e.errors[0].code:"halt",X(t,e.haltReason)),!n}var fe="sap-styles",le="[item][template]{display:none!important}[hidden]{display:none!important}[sap-error]{outline:2px solid #e5484d;outline-offset:1px}",Ft=new WeakSet;function ln(t){if(Ft.has(t))return;let e=t.defaultView,n=e&&e.CSSStyleSheet;if(n&&"adoptedStyleSheets"in t)try{let r=new n;r.replaceSync(le),t.adoptedStyleSheets=[...t.adoptedStyleSheets,r],Ft.add(t);return}catch{}if(!t.getElementById(fe)){let r=t.createElement("style");r.id=fe,r.textContent=le,(t.head||t.documentElement).appendChild(r)}Ft.add(t)}var dn=0;function de(){return typeof performance<"u"&&performance.now?performance.now():0}function Pt(t){let e=t.id||t.getAttribute("sap")||`app-${dn++}`,n=new nt(e),r={root:t,name:e,diag:n,_state:null,_stats:null,_lastPass:null,_passes:0,_broken:!1,_mountMs:0,_mountWrites:0};if(!Tt(t,n))return r.halted=!0,r;ln(t.ownerDocument);for(let a of t.querySelectorAll("textarea[data-value]"))At(a);let i=de();return ot(r,{trigger:"mount"}),r._mountMs=de()-i,r._mountWrites=r._stats?r._stats.writes:0,r._mountWrites>0&&n.warn("W30",t,{problem:`${r._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)"}),r}function pn(t,e){let n=null;return F(t,r=>{!n&&r.getAttribute("scope")===e&&(n=r)}),n}function pe(t,e,n){let r=I(t)||e;for(;r;){for(let s of P(r.getAttribute("state")||""))if(s.name===n)return{el:r,decl:s};if(r.hasAttribute("sap"))break;r=I(r.parentElement)}return null}function mn(t){return typeof t=="number"?"num":typeof t=="boolean"?"bool":"string"}function me(t){function e(b){let g=t.appFor(b);if(!g)return null;let c=at(b);if(c)return c._sapDetailRow?{ctxEl:c._sapDetailRow,appRec:g,isRow:!0}:{ctxEl:I(c.parentElement)||g.root,appRec:g,isRow:!1};let A=mt(b);if(A&&A.hasAttribute("item"))return{ctxEl:A,appRec:g,isRow:!0};let S=I(b)||g.root;return{ctxEl:S,appRec:g,isRow:S.hasAttribute("item")}}function n(b){let g=typeof b=="string"?document.querySelector(b):b;if(!g||g.nodeType!==1)return null;let c=e(g);return c?L(c.ctxEl,c.appRec,c.isRow):null}function r(b,g,c){let A=tt(b,c);if(A)return M(A).read();let S=it(b,c);if(S)return O(S).map(m=>L(m,g,!0));let x=pn(b,c);if(x)return L(x,g,!1);let $=pe(b,g.root,c);if($)return $.decl.transient?gt($.el,$.decl):G($.el.getAttribute(c),$.decl.type);let R=b._sapScope;return R?R[c]:void 0}function s(b,g,c,A,S){A.transient?Lt(b,A,c):b.setAttribute(g,bt(c,A.type)),t.schedule(S,"set:"+g)}function i(b,g){let c=new Set,A=I(b)||g;for(;A;){for(let S of P(A.getAttribute("state")||""))c.add(S.name);if(A.hasAttribute("sap"))break;A=I(A.parentElement)}return F(b,S=>{let x=S.getAttribute("bind");x&&c.add(x)}),c}function a(b,g,c,A){let S=tt(b,c);if(S){M(S).write(A);return}let x=b;for(;x;){for(let h of x.attributes)if(h.name==="calc:"+c){g.diag.error("E16",x,{attr:"calc:"+c,problem:`"${c}" is a computed field; computed fields are read-only`});return}if(x.hasAttribute("sap"))break;x=x.parentElement}let $=pe(b,g.root,c);if($){s($.el,c,A,$.decl,g);return}let R=i(b,g.root);R.delete(c);let m=c.length>=4?dt(c,[...R]):null;if(m){g.diag.error("E12",b,{key:c,problem:`unknown state key "${c}"`,didYouMean:m});return}if(St.has(c)||lt.has(c)){g.diag.error("E15",b,{key:c,problem:`cannot write undeclared field "${c}" \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 d=g.root,f=mn(A),o=d.getAttribute("state")||"",u=f==="string"?c:`${c}:${f}`;d.setAttribute("state",o?`${o} ${u}`:u),s(d,c,A,{name:c,type:f,transient:!1},g)}function k(b){let g=c=>{c.id&&(c.id="",Z(c,"row")),c.hasAttribute("sap-error")&&c.removeAttribute("sap-error")};b.id="",Z(b,"row"),b.querySelectorAll("[id]").forEach(g)}function E(b,g,c){let A=ut(g.root,b,c);if(!A)return g.diag.error("E17",b,{problem:`cannot resolve a list named "${c}" from here`}),null;let S=ht(A);if(!S)return g.diag.error("E17",A,{problem:`items="${c}" has no [item template] to clone`}),null;let x=S.cloneNode(!0);return x.removeAttribute("template"),k(x),A.appendChild(x),t.schedule(g,"trigger-add:"+c),L(x,g,!0)}function w(b,g){F(b,c=>{if(c.hasAttribute("bind")){let A=M(c),S=c.getAttribute("default");A.kind==="checkbox"||A.kind==="radio"?A.write(S!=null?S===""||S==="true"||c.value===S:c.hasAttribute("checked")):A.write(S??(c.getAttribute("value")||""))}});for(let c of P(b.getAttribute("state")||"")){let A=c.default!=null?c.default:c.type==="num"?"0":c.type==="bool"?"false":"";c.transient?Lt(b,c,G(A,c.type)):b.setAttribute(c.name,A)}t.schedule(g,"trigger-reset")}function l(b,g){if(!b.isConnected)throw new Error("stale row handle: $remove() on a removed row");b.remove(),t.schedule(g,"trigger-remove")}function y(b,g,c){if(!b.isConnected)throw new Error("stale row handle: $move() on a removed row");let A=null;if(c&&c.nodeType===1?A=c:typeof c=="string"&&(A=ut(g.root,b,c)),!A){g.diag.error("E17",b,{problem:`$move() cannot resolve target "${c}"`});return}t.moveInto(A,b),t.schedule(g,"trigger-move")}function N(b){let g=b.parentElement;return g?O(g).indexOf(b):-1}function L(b,g,c){let A={get $el(){return b},get $key(){return Z(b,c?"row":"scope")},get $index(){return N(b)},$add(x){return E(b,g,x)},$reset(){return w(b,g),S},$remove(){l(b,g)},$move(x){y(b,g,x)},get $appRec(){return g}},S=new Proxy(A,{get(x,$){return typeof $=="symbol"||$[0]==="$"?x[$]:r(b,g,$)},set(x,$,R){return typeof $=="string"&&$[0]==="$"?(x[$]=R,!0):(a(b,g,$,R),!0)},has(x,$){return typeof $=="string"&&$[0]==="$"?$ in x:r(b,g,$)!==void 0}});return S}return{Sap:n,contextElFor:e,readField:r,writeField:a,makeProxy:L}}var hn=["trigger-add","trigger-remove","trigger-reset"];function bn(t){if(t.nodeType!==1)return!1;for(let e of t.attributes){let n=e.name;if(n.startsWith("set:")||n.startsWith("move:")||n.startsWith("sort:")||hn.includes(n))return!0}return!1}function gn(t,e){let n=t,r=e.parentElement;for(;n&&n!==r;){if(n.nodeType===1&&bn(n)&&!(n.tagName==="FORM"&&n.hasAttribute("trigger-add")))return n;n=n.parentElement}return null}function he(t,e){let{Sap:n}=e;function r(m,d){let f=null,o=at(m);if(o&&o._sapDetailRow)f=o._sapDetailRow._sapScope||null;else{let p=mt(m);p&&p.hasAttribute("item")&&(f=p._sapScope||null)}return{state:(I(m)||d.root)._sapScope||d._state||{},item:f,el:m,root:d._state||{}}}function s(m,d,f){if(!m.hasAttribute("confirm")){f();return}let o=m.getAttribute("confirm"),u=o,h=D(o);if(!h.error)try{let T=U(h,r(m,d));(typeof T=="string"||typeof T=="number")&&(u=String(T))}catch{}let p=Jt();if(!p){window.confirm(u)&&f();return}if(m._sapGatePending)return;m._sapGatePending=!0;let v=()=>{m._sapGatePending=!1};p(u,()=>{v(),f()}).catch(v)}function i(m,d){for(let f of m.attributes){if(!f.name.startsWith("set:"))continue;let o=f.name.slice(4),u=D(f.value);if(u.error){d.diag.error("E08",m,{attr:f.name,expr:f.value,problem:String(u.error.message)});continue}let h;try{h=U(u,r(m,d))}catch(v){d.diag.error("E24",m,{attr:f.name,expr:f.value,problem:String(v.message)});continue}let p=n(m);p&&(p[o]=h)}}function a(m,d){let f=m.closest("[item]");if(!f)return;let o=O(f.parentElement),u=o.indexOf(f);d==="up"&&u>0?t.placeBefore(f,o[u-1]):d==="down"&&u<o.length-1&&t.placeBefore(o[u+1],f)}function k(m,d,f){if(d)return ut(f.root,m,d);let o=m;for(;o;){if(o.hasAttribute&&o.hasAttribute("items"))return o;o=o.parentElement}let u=I(m)||f.root,h=[];return F(u,p=>{p.hasAttribute("items")&&h.push(p)}),h[0]||null}function E(m,d){let f=m==null||m==="",o=d==null||d==="";if(f&&o)return 0;if(f)return 1;if(o)return-1;let u=Number(m),h=Number(d);return!Number.isNaN(u)&&!Number.isNaN(h)?u-h:String(m)<String(d)?-1:String(m)>String(d)?1:0}function w(m,d,f,o){let u=k(m,f,o);if(!u){o.diag.error("E17",m,{attr:"sort:"+d,problem:`no items list resolvable for sort:${d}`});return}let h=O(u),p=C=>C._sapScope?C._sapScope[d]:void 0,v=[...h].sort((C,z)=>E(p(C),p(z))),st=v.every((C,z)=>C===h[z])?[...v].reverse():v;for(let C of st)t.moveInto(u,C);t.schedule(o,"sort:"+d)}function l(m){if(!m||m.hidden)return;let d=m.querySelector("[bind]:not([type=hidden]), [contenteditable]");d&&typeof d.focus=="function"&&d.focus()}function y(m,d){s(m,d,()=>{let f=n(m);for(let o of[...m.attributes]){let u=o.name;if(u==="trigger-remove")f&&f.$remove();else if(u==="trigger-reset")f&&f.$reset();else if(u==="trigger-add"){let h=f&&f.$add(o.value);h&&l(h.$el)}else u==="move:up"?(a(m,"up"),t.schedule(d,"move:up")):u==="move:down"?(a(m,"down"),t.schedule(d,"move:down")):u.startsWith("move:to")?f&&f.$move(o.value):u.startsWith("sort:")&&w(m,u.slice(5),o.value,d)}[...m.attributes].some(o=>o.name.startsWith("set:"))&&i(m,d)})}function N(m){let d=m.target;if(!d||d.nodeType!==1)return;let f=t.appFor(d);if(!f)return;let o=gn(d,f.root);o&&y(o,f)}function L(m){let d=M(m),f=m.getAttribute("default");d.kind==="checkbox"?d.write(f===""||f==="true"):d.write(f??"")}function b(m,d,f){let o=n(m);if(!o)return;let u=o.$add(f);if(!u)return;let h=[];F(m,p=>{p.hasAttribute("bind")&&h.push(p)});for(let p of h){let v=tt(u.$el,p.getAttribute("bind"));v&&M(v).write(M(p).read())}h.forEach(L),h.length?typeof h[0].focus=="function"&&h[0].focus():l(u.$el)}function g(m){let d=m.target;if(!d||!d.hasAttribute||!d.hasAttribute("trigger-add"))return;let f=t.appFor(d);f&&(m.preventDefault(),s(d,f,()=>b(d,f,d.getAttribute("trigger-add"))))}function c(m){let d=m.target,f=t.appFor(d);f&&setTimeout(()=>{d.querySelectorAll("[bind]").forEach(o=>{o.dispatchEvent(new Event("input",{bubbles:!0})),o.dispatchEvent(new Event("change",{bubbles:!0}))}),t.schedule(f,"reset")},0)}function A(m){let d=t.appFor(m.target);d&&t.schedule(d,"toggle")}function S(m){let d=m.target;if(!d||d.nodeType!==1)return;let f=t.appFor(d);if(!f)return;d.hasAttribute("persist")&&!vt(d)&&et(d);let o=at(d);if(o&&o._sapDetailRow&&d.hasAttribute("bind")){let u=tt(o._sapDetailRow,d.getAttribute("bind"));if(u&&u!==d){M(u).write(M(d).read());return}}t.schedule(f,m.type+" "+(d.id||d.tagName.toLowerCase()))}function x(m){let d=m.detail||{};for(let f of[d.from,d.to,m.target]){if(!f||f.nodeType!==1)continue;let o=t.appFor(f);o&&t.schedule(o,"sorted")}}function $(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 f=(d.getAttribute("type")||"text").toLowerCase();if(f!=="text"&&f!=="tel"&&f!=="search"||!t.appFor(d))return;m.preventDefault();let u=B(d.getAttribute("step"))||1,h=m.key==="ArrowUp"?1:-1,p=B(d.value)+u*(m.shiftKey?10:1)*h,v=d.getAttribute("min"),T=d.getAttribute("max");v!==null&&v!==""&&p<B(v)&&(p=B(v)),T!==null&&T!==""&&p>B(T)&&(p=B(T)),M(d).write(String(Number(p.toFixed(2))))}function R(m=document){m.addEventListener("click",N),m.addEventListener("submit",g),m.addEventListener("reset",c),m.addEventListener("toggle",A,!0),m.addEventListener("input",S),m.addEventListener("change",S),m.addEventListener("clay:sorted",x),m.addEventListener("keydown",$)}return{install:R}}var be=/^(set:|move:|sort:|trigger-add$|trigger-remove$|trigger-reset$)/;function Ot(t){return`${t.tagName.toLowerCase()}[sap]`}function yn(t){let e=0;for(let n of t.querySelectorAll("*"))for(let r of n.attributes)if(be.test(r.name)){e++;break}for(let n of t.attributes)if(be.test(n.name)){e++;break}return e}function ge(t){let e=[],n=r=>{for(let s of r.attributes){let i=s.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:r,attr:i,src:s.value})}};n(t);for(let r of t.querySelectorAll("*"))n(r);return e}function ye(t){function e(l){let y=l._stats||{},N=l.root;return{root:Ot(N),fields:y.fields||0,calcs:y.calcs||0,paints:y.paints||0,actions:yn(N),lists:(N.hasAttribute("items")?1:0)+N.querySelectorAll("[items]").length,rows:N.querySelectorAll("[item]:not([template])").length,warnings:l.diag.warnings.length,errors:l.diag.errors.length,mountWrites:l._mountWrites||0,ms:Math.round((l._mountMs||0)*10)/10,passes:l._passes||0,lastPass:l._lastPass||null,ok:l.diag.errors.length===0&&!l.halted}}function n(){let l=t.apps().map(e);return{ok:l.every(y=>y.ok),apps:l}}function r(l){let y=e(l);return y.ok?`sap \u2713 ${y.root} \xB7 fields ${y.fields} \xB7 calcs ${y.calcs} \xB7 paints ${y.paints} \xB7 actions ${y.actions} \xB7 lists ${y.lists} \xB7 rows ${y.rows} \xB7 warnings ${y.warnings} \xB7 mount writes ${y.mountWrites} \xB7 ${y.ms}ms`:`sap \u2717 ${y.root} \xB7 errors ${y.errors} \xB7 warnings ${y.warnings} \xB7 ${y.ms}ms`}function s(){for(let l of t.apps()){let y=r(l);l.diag.errors.length||l.halted?console.error(y):console.log(y)}}function i(){let l=[],y=[];for(let N of t.apps())l.push(...N.diag.errors),y.push(...N.diag.warnings);return{ok:l.length===0,errors:l,warnings:y,counts:{errors:l.length,warnings:y.length}}}function a(l){return l?typeof l=="string"?document.querySelector(l):l.nodeType===1?l:null:null}function k(l,y){let N=a(l);if(!N)return console.warn("sap why: element not found"),null;let L=[`sap why <${N.tagName.toLowerCase()}> \u2014 ${xt(N)}`],b=[...N.attributes].filter(c=>/^(bind|text|show|effect|invalid|detail|calc:|text:|attr:|class:|css:|set:|state|items|scope)/.test(c.name));for(let c of b)L.push(` ${c.name}="${c.value}"`);let g=N;for(;g&&!g._sapScope;)g=g.parentElement;if(g&&g._sapScope){let c=g._sapScope,A=y?[y]:Object.keys(c);L.push(" reads:");for(let S of A){let x=c[S];typeof x!="function"&&L.push(` ${S} = ${JSON.stringify(Array.isArray(x)?`[${x.length} rows]`:x)}`)}}return L.push(" serialization: textContent and value/checked attributes save with the file; reads live from properties"),console.log(L.join(`
|
|
8
|
+
`)),null}function E(l){let y=l===void 0?!0:!!l;for(let N of t.apps())N._debug=y;return console.log(`sap debug ${y?"on":"off"} \u2014 per-pass headers will ${y?"":"no longer "}log`),y}function w(){let l=[],y=0;for(let c of t.apps()){let A=c.root,S=Ot(A);y++;let x=new nt(c.name);Tt(A,x);for(let f of x.errors)l.push({code:f.code,severity:"error",message:`${S}: ${f.code} ${f.slug} at ${f.el}`});for(let f of x.warnings)l.push({code:f.code,severity:"warn",message:`${S}: ${f.code} ${f.slug} at ${f.el}`});y++,ot(c,{trigger:"doctor-dryrun"});let $=c._stats?c._stats.writes:0;$>0&&l.push({code:"W30",severity:"warn",message:`${S}: dry recompute wrote ${$} cells on a quiet page; an element is stale or non-idempotent`}),y++;let R=ge(A).map(f=>f.src).join(" \0 "),m=[];for(let f of[A,...A.querySelectorAll("[state]")])for(let o of P(f.getAttribute("state")||""))m.push(o.name);for(let f of m)new RegExp(`(state|item)\\.${f}\\b`).test(R)||l.push({code:"I33",severity:"info",message:`${S}: field "${f}" is declared but read nowhere (dead state)`});y++;let d=new Map;for(let f of A.querySelectorAll("[id]"))d.set(f.id,(d.get(f.id)||0)+1);for(let[f,o]of d)o>1&&l.push({code:"W32",severity:"warn",message:`${S}: duplicate id "${f}" (${o} elements) \u2014 clone/edit collision`});y++;for(let f of ge(A))f.src.length>120&&l.push({code:"I33",severity:"info",message:`${S}: ${f.attr} expression is ${f.src.length} chars; consider a calc: field`});y++;for(let f of A.querySelectorAll("[text], [text\\:num]")){let o=f.textContent||"";/\.\d{5,}/.test(o)&&l.push({code:"I33",severity:"info",message:`${S}: ${xt(f)} paints >4 decimals; consider text:FMT`})}}let N=l.filter(c=>c.severity==="error").length,L=l.filter(c=>c.severity==="warn").length,b=l.filter(c=>c.severity==="info").length;console.log(`sap doctor \xB7 ${t.apps().map(c=>Ot(c.root)).join(", ")} \xB7 errors ${N} \xB7 warnings ${L} \xB7 info ${b} \xB7 ${y} checks \xB7 0ms`);for(let c of l)(c.severity==="error"?console.error:c.severity==="warn"?console.warn:console.info)(` ${c.severity==="error"?"\u2717":c.severity==="warn"?"\u26A0":"\xB7"} ${c.message}`);return l}return{status:n,report:i,why:k,debug:E,doctor:w,greenLine:r,printGreenLines:s,REGISTRY:Rt}}var wn="0.2.0",q=new Map,V=[],Bt=zt(ot);function An(t){let e=t;for(;e;){if(e.nodeType===1&&e.hasAttribute&&e.hasAttribute("sap"))return q.get(e)||null;e=e.parentNode&&e.parentNode.host?e.parentNode.host:e.parentElement}return null}function vn(){for(let t=V.length-1;t>=0;t--){let e=V[t];e.root.isConnected||(q.delete(e.root),V.splice(t,1))}}function En(t,e){if(t.moveBefore)try{t.moveBefore(e,null);return}catch{}t.appendChild(e)}function Sn(t,e){let n=e.parentElement;if(n){if(n.moveBefore)try{n.moveBefore(t,e);return}catch{}n.insertBefore(t,e)}}var K={apps:()=>V.slice(),appFor:An,isRegistered:t=>q.has(t),pruneDisconnected:vn,schedule:(t,e)=>Bt.schedule(t,e),runNow:(t,e)=>Bt.runNow(t,e),moveInto:En,placeBefore:Sn,remountIfPresent:()=>pt()},Ae=me(K),xn=he(K,Ae),Y=ye(K),we=!1;function ve(){we||(we=!0,xn.install(document),Zt(K))}function pt(t=document){ve(),Dt(K);let e=t.querySelectorAll("[sap]"),n=[];for(let r of e){if(q.has(r))continue;let s=Pt(r);q.set(r,s),V.push(s),n.push(s)}for(let r of n){let s=Y.greenLine(r);r.diag.errors.length||r.halted?console.error(s):console.log(s)}return n}function Ee(t){if(ve(),Dt(K),!t)return pt();let e=typeof t=="string"?document.querySelector(t):t;if(!e)return null;if(q.has(e))return q.get(e);let n=Pt(e);q.set(e,n),V.push(n);let r=Y.greenLine(n);return n.diag.errors.length||n.halted?console.error(r):console.log(r),n}var _=Ae.Sap;_.version=wn;_.refresh=function(){for(let e of V)e.root.isConnected&&Bt.runNow(e,"refresh")};_.batch=Qt;_.status=Y.status;_.report=Y.report;_.why=Y.why;_.debug=Y.debug;_.doctor=Y.doctor;_.greenLine=Y.greenLine;_.formats=ct;_.serializeControlToAttributes=et;_.finalizeControlForSave=Kt;_.rehydrateControlFromAttributes=At;_.mount=Ee;_.config=function(e={}){return e.formats&&Object.assign(ct,e.formats),_};_._registry=q;_._reset=function(){q.clear(),V.length=0,oe()};function $n(){typeof document>"u"||(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>pt()):pt())}$n();typeof window<"u"&&(window.Sap=_);var kn=_;return Te(Nn);})();
|
|
9
9
|
if (typeof window !== 'undefined' && Sap && Sap.default) window.Sap = Sap.default;
|
|
10
10
|
var sapDefault = Sap.default;
|
|
11
11
|
window.clay = window.clay || {};
|
package/src/attrs/onaftersave.js
CHANGED
|
@@ -5,9 +5,20 @@
|
|
|
5
5
|
* Only fires on 'clay:save-saved' events (not on error/offline).
|
|
6
6
|
*
|
|
7
7
|
* Usage:
|
|
8
|
-
* <span onaftersave="this.innerText = event.detail.msg"></span>
|
|
8
|
+
* <span clay="no-trigger-autosave" onaftersave="this.innerText = event.detail.msg"></span>
|
|
9
9
|
* <link href="styles.css" onaftersave="cacheBust(this)">
|
|
10
10
|
*
|
|
11
|
+
* MARK WHAT YOU MUTATE `no-trigger-autosave`.
|
|
12
|
+
* These handlers run after the save baseline has been taken, so anything they write
|
|
13
|
+
* to the live DOM reads as a change the user made and leaves the page permanently
|
|
14
|
+
* dirty: autosave loops, and the close-tab warning never clears. The token strips
|
|
15
|
+
* the element from every comparison capture, which is what stops that.
|
|
16
|
+
* `cacheBust()` marks its own target, so the second example needs nothing. A handler
|
|
17
|
+
* that mutates some OTHER element has to mark that element itself.
|
|
18
|
+
*
|
|
19
|
+
* (The alternative — re-reading the whole live DOM after handlers run — is what
|
|
20
|
+
* clayjs used to do, and it silently discarded anything typed during a save.)
|
|
21
|
+
*
|
|
11
22
|
* The event.detail object contains:
|
|
12
23
|
* - status: 'saved'
|
|
13
24
|
* - msg: string (e.g., 'Saved')
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { addRegionToken } from '../lib/region-policy.js';
|
|
2
|
+
|
|
1
3
|
function swapElement(el) {
|
|
2
4
|
const attr = el.hasAttribute('href') ? 'href' : el.hasAttribute('src') ? 'src' : null;
|
|
3
5
|
if (!attr) return;
|
|
@@ -12,10 +14,8 @@ function swapElement(el) {
|
|
|
12
14
|
newEl.setAttribute(name, value);
|
|
13
15
|
}
|
|
14
16
|
newEl.setAttribute(attr, isSameOrigin ? url.pathname + url.search : url.href);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
tokens.add("no-undo");
|
|
18
|
-
newEl.setAttribute("clay", Array.from(tokens).join(" "));
|
|
17
|
+
addRegionToken(newEl, "no-trigger-autosave");
|
|
18
|
+
addRegionToken(newEl, "no-undo");
|
|
19
19
|
|
|
20
20
|
el.insertAdjacentElement('afterend', newEl);
|
|
21
21
|
|
package/src/attrs/save-freeze.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* Changes inside freeze elements do not trigger autosave dirty checks.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { onSnapshot,
|
|
19
|
+
import { onSnapshot, addDocumentTransform } from "../core/snapshot.js";
|
|
20
20
|
import { isEditMode } from "../core/is-edit-mode.js";
|
|
21
21
|
import { FREEZE_SELECTOR } from "../lib/region-policy.js";
|
|
22
22
|
import Mutation from "../lib/mutation.js";
|
|
@@ -44,22 +44,51 @@ function captureAll() {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
// Which cloned element holds which authored innerHTML, for the current snapshot.
|
|
48
|
+
// Keyed by the cloned element itself: the prepare phase runs on the same clone
|
|
49
|
+
// object the snapshot phase saw, so identity is the pairing. An attribute marker
|
|
50
|
+
// would work too, right up until clay:snapshot-ready — which fires BETWEEN the two
|
|
51
|
+
// phases — hands the still-marked clone to live-sync and demo mode, both of which
|
|
52
|
+
// serialize it on the spot.
|
|
53
|
+
let pending = new WeakMap();
|
|
54
|
+
|
|
55
|
+
// Phase 2. The clone is a verbatim cloneNode of the live root and nothing has been
|
|
56
|
+
// stripped from it yet, so pairing by position is sound HERE and nowhere else.
|
|
57
|
+
function freezeSnapshot(clone) {
|
|
58
|
+
pending = new WeakMap();
|
|
59
|
+
|
|
48
60
|
const liveElements = document.querySelectorAll(FREEZE_SELECTOR);
|
|
49
61
|
const cloneElements = clone.querySelectorAll(FREEZE_SELECTOR);
|
|
50
62
|
|
|
51
63
|
log('freezing clone — live:', liveElements.length, 'clone:', cloneElements.length);
|
|
52
64
|
|
|
65
|
+
// Counts can only differ if an earlier onSnapshot hook added or removed
|
|
66
|
+
// elements, which means alignment is already gone. Restoring nothing beats
|
|
67
|
+
// restoring one element's authored content into a different element.
|
|
68
|
+
if (liveElements.length !== cloneElements.length) {
|
|
69
|
+
console.warn('[save-freeze] live/clone freeze counts differ, skipping freeze restore');
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
53
73
|
for (let i = 0; i < cloneElements.length; i++) {
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
74
|
+
if (!originals.has(liveElements[i])) continue;
|
|
75
|
+
const original = originals.get(liveElements[i]);
|
|
76
|
+
pending.set(cloneElements[i], original);
|
|
77
|
+
if (cloneElements[i].innerHTML !== original) {
|
|
78
|
+
log('element', i, '— restoring original');
|
|
79
|
+
cloneElements[i].innerHTML = original;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Phase 3a. Re-freeze anything an [onbeforesave] handler changed between the two
|
|
85
|
+
// phases. Nothing to clean up: the pairing never entered the document.
|
|
86
|
+
function freezePrepare(clone) {
|
|
87
|
+
for (const el of clone.querySelectorAll(FREEZE_SELECTOR)) {
|
|
88
|
+
const original = pending.get(el);
|
|
89
|
+
if (original !== undefined && el.innerHTML !== original) {
|
|
90
|
+
log('re-restoring original after prepare-phase change');
|
|
91
|
+
el.innerHTML = original;
|
|
63
92
|
}
|
|
64
93
|
}
|
|
65
94
|
}
|
|
@@ -75,10 +104,8 @@ function init() {
|
|
|
75
104
|
// debounce:0 so we snapshot the authored content before any runtime edit
|
|
76
105
|
// mutates it; the callback is a pure read into a WeakMap (no DOM writes).
|
|
77
106
|
// require:'observed' (skip only no-watch); pausable:false so a morphed-in
|
|
78
|
-
// freeze region is still captured.
|
|
79
|
-
//
|
|
80
|
-
// directly to <head> at runtime is no longer captured (authored <head> freeze
|
|
81
|
-
// regions are still handled by captureAll() on load) — an accepted edge.
|
|
107
|
+
// freeze region is still captured. Mutation observes document.documentElement,
|
|
108
|
+
// so a [freeze] added directly to <head> at runtime is captured like any other.
|
|
82
109
|
Mutation.onAddElement({
|
|
83
110
|
selectorFilter: FREEZE_SELECTOR,
|
|
84
111
|
require: 'observed',
|
|
@@ -90,11 +117,12 @@ function init() {
|
|
|
90
117
|
|
|
91
118
|
// Phase 2: Freeze in snapshot — before snapshot-ready fires.
|
|
92
119
|
// This prevents live-sync from writing unfrozen content to disk.
|
|
93
|
-
onSnapshot(
|
|
120
|
+
onSnapshot(freezeSnapshot);
|
|
94
121
|
|
|
95
|
-
// Phase 3a: Freeze again in prepare
|
|
96
|
-
//
|
|
97
|
-
|
|
122
|
+
// Phase 3a: Freeze again in prepare, for anything changed between the phases
|
|
123
|
+
// (e.g. onbeforesave handlers). Pairs by the WeakMap phase 2 filled, because by
|
|
124
|
+
// now the clone has lost its [no-snapshot] subtrees and position means nothing.
|
|
125
|
+
addDocumentTransform(freezePrepare);
|
|
98
126
|
}
|
|
99
127
|
|
|
100
128
|
init();
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { isEditMode, isOwner } from "./is-edit-mode.js";
|
|
2
2
|
import onDomReady from "../lib/dom-ready.js";
|
|
3
|
-
import {
|
|
3
|
+
import { addDocumentTransform } from "./snapshot.js";
|
|
4
4
|
|
|
5
5
|
export const SELECTOR = '[editmode\\:contenteditable]';
|
|
6
6
|
|
|
7
7
|
export function disableContentEditableBeforeSave () {
|
|
8
|
-
|
|
8
|
+
addDocumentTransform(docElem => {
|
|
9
9
|
docElem.querySelectorAll(SELECTOR).forEach(resource => {
|
|
10
10
|
const originalValue = resource.getAttribute("contenteditable");
|
|
11
11
|
resource.setAttribute("inert-contenteditable", originalValue);
|
package/src/core/admin-inputs.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { isEditMode, isOwner } from "./is-edit-mode.js";
|
|
2
2
|
import onDomReady from "../lib/dom-ready.js";
|
|
3
|
-
import {
|
|
3
|
+
import { addDocumentTransform } from "./snapshot.js";
|
|
4
4
|
|
|
5
5
|
export const SELECTOR_DISABLED = '[viewmode\\:disabled]';
|
|
6
6
|
export const SELECTOR_READONLY = '[viewmode\\:readonly]';
|
|
7
7
|
|
|
8
8
|
export function disableAdminInputsBeforeSave() {
|
|
9
|
-
|
|
9
|
+
addDocumentTransform(docElem => {
|
|
10
10
|
docElem.querySelectorAll(SELECTOR_DISABLED).forEach(input => {
|
|
11
11
|
input.setAttribute('disabled', '');
|
|
12
12
|
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { isEditMode, isOwner } from "./is-edit-mode.js";
|
|
2
2
|
import onDomReady from "../lib/dom-ready.js";
|
|
3
|
-
import {
|
|
3
|
+
import { addDocumentTransform } from "./snapshot.js";
|
|
4
4
|
|
|
5
5
|
export const SELECTOR = '[editmode\\:onclick]';
|
|
6
6
|
|
|
7
7
|
export function disableOnClickBeforeSave () {
|
|
8
|
-
|
|
8
|
+
addDocumentTransform(docElem => {
|
|
9
9
|
docElem.querySelectorAll(SELECTOR).forEach(resource => {
|
|
10
10
|
const originalValue = resource.getAttribute("onclick");
|
|
11
11
|
resource.setAttribute("inert-onclick", originalValue);
|
|
@@ -1,18 +1,31 @@
|
|
|
1
1
|
import { isEditMode, isOwner } from "./is-edit-mode.js";
|
|
2
2
|
import onDomReady from "../lib/dom-ready.js";
|
|
3
|
-
import {
|
|
3
|
+
import { addDocumentTransform } from "./snapshot.js";
|
|
4
4
|
|
|
5
5
|
export const SELECTOR = '[editmode\\:resource]:is(style, link, script)';
|
|
6
6
|
export const SELECTOR_INERT = '[editmode\\:resource]:is(style, link, script)[type^="inert/"]';
|
|
7
7
|
|
|
8
|
+
const INERT_PREFIX = 'inert/';
|
|
9
|
+
|
|
10
|
+
// An absent type is recorded as an empty remainder, so enabling restores absence
|
|
11
|
+
// rather than inventing text/javascript. A <style> or a stylesheet <link> handed a
|
|
12
|
+
// JavaScript MIME on the way back never applies again.
|
|
13
|
+
function makeInert(resource) {
|
|
14
|
+
const current = resource.getAttribute('type');
|
|
15
|
+
if (current && current.startsWith(INERT_PREFIX)) return false;
|
|
16
|
+
resource.setAttribute('type', INERT_PREFIX + (current || ''));
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function makeActive(resource) {
|
|
21
|
+
const original = resource.getAttribute('type').slice(INERT_PREFIX.length);
|
|
22
|
+
if (original) resource.setAttribute('type', original);
|
|
23
|
+
else resource.removeAttribute('type');
|
|
24
|
+
}
|
|
25
|
+
|
|
8
26
|
export function disableAdminResourcesBeforeSave () {
|
|
9
|
-
|
|
10
|
-
docElem.querySelectorAll(SELECTOR).forEach(
|
|
11
|
-
const currentType = resource.getAttribute('type') || 'text/javascript';
|
|
12
|
-
if (!currentType.startsWith('inert/')) {
|
|
13
|
-
resource.setAttribute('type', `inert/${currentType}`);
|
|
14
|
-
}
|
|
15
|
-
});
|
|
27
|
+
addDocumentTransform(docElem => {
|
|
28
|
+
docElem.querySelectorAll(SELECTOR).forEach(makeInert);
|
|
16
29
|
});
|
|
17
30
|
}
|
|
18
31
|
|
|
@@ -27,18 +40,14 @@ export function enableAdminResourcesOnPageLoad () {
|
|
|
27
40
|
// Runtime toggle functions
|
|
28
41
|
export function enableAdminResources() {
|
|
29
42
|
document.querySelectorAll(SELECTOR_INERT).forEach(resource => {
|
|
30
|
-
resource
|
|
43
|
+
makeActive(resource);
|
|
31
44
|
resource.replaceWith(resource.cloneNode(true));
|
|
32
45
|
});
|
|
33
46
|
}
|
|
34
47
|
|
|
35
48
|
export function disableAdminResources() {
|
|
36
49
|
document.querySelectorAll(SELECTOR).forEach(resource => {
|
|
37
|
-
|
|
38
|
-
if (!currentType.startsWith('inert/')) {
|
|
39
|
-
resource.setAttribute('type', `inert/${currentType}`);
|
|
40
|
-
resource.replaceWith(resource.cloneNode(true));
|
|
41
|
-
}
|
|
50
|
+
if (makeInert(resource)) resource.replaceWith(resource.cloneNode(true));
|
|
42
51
|
});
|
|
43
52
|
}
|
|
44
53
|
|
package/src/core/autosave.js
CHANGED
|
@@ -19,9 +19,19 @@ import { initUserGesture, markUserDriven } from "../lib/user-gesture.js";
|
|
|
19
19
|
* Initialize auto-save on DOM changes
|
|
20
20
|
* Uses debounced mutation observer
|
|
21
21
|
*/
|
|
22
|
+
// A bare debounce resets on every change, so a page with anything that mutates
|
|
23
|
+
// faster than the delay — a clock, a countdown, a polling counter — pushes autosave
|
|
24
|
+
// into the future forever and it never fires, with nothing in the UI saying so.
|
|
25
|
+
// maxWait bounds that: however long the churn lasts, a save happens within
|
|
26
|
+
// AUTOSAVE_MAX_WAIT_MS of the first change it was waiting on. (The settled baseline
|
|
27
|
+
// capture in save.js already solved this for itself with MAX_SETTLE_MS.)
|
|
28
|
+
const AUTOSAVE_DEBOUNCE_MS = 1500;
|
|
29
|
+
const AUTOSAVE_MAX_WAIT_MS = 10000;
|
|
30
|
+
|
|
22
31
|
function initSavePageOnChange() {
|
|
23
32
|
Mutation.onAnyChange({
|
|
24
|
-
debounce:
|
|
33
|
+
debounce: AUTOSAVE_DEBOUNCE_MS,
|
|
34
|
+
maxWait: AUTOSAVE_MAX_WAIT_MS,
|
|
25
35
|
omitChangeDetails: true,
|
|
26
36
|
require: 'autosave'
|
|
27
37
|
}, () => {
|
package/src/core/edit-mode.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// (it's the way IN), and setPageTypeOnPageLoad marks <html> in either mode.
|
|
4
4
|
import { isEditMode, isOwner } from "./is-edit-mode.js";
|
|
5
5
|
import onDomReady from "../lib/dom-ready.js";
|
|
6
|
-
import {
|
|
6
|
+
import { addDocumentTransform } from "./snapshot.js";
|
|
7
7
|
|
|
8
8
|
export function toggleEditMode() {
|
|
9
9
|
const url = new URL(window.location.href);
|
|
@@ -13,7 +13,7 @@ export function toggleEditMode() {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export function setViewerPageTypeBeforeSave () {
|
|
16
|
-
|
|
16
|
+
addDocumentTransform(docElem => {
|
|
17
17
|
docElem.setAttribute("editmode", "false");
|
|
18
18
|
docElem.setAttribute("pageowner", "false");
|
|
19
19
|
});
|