@baack-software/baack-ts-editor 0.1.4 → 0.1.6
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 +1 -1
- package/dist/chunks/chunk-5RFN34CS.js +2 -0
- package/dist/chunks/chunk-5RFN34CS.js.map +7 -0
- package/dist/chunks/{chunk-V4BSLQ2M.js → chunk-MSWF55NC.js} +53 -24
- package/dist/chunks/chunk-MSWF55NC.js.map +7 -0
- package/dist/chunks/chunk-VNUXOULZ.js +3 -0
- package/dist/chunks/chunk-VNUXOULZ.js.map +7 -0
- package/dist/chunks/dist-CF3GEGCB.js +2 -0
- package/dist/chunks/dist-CF3GEGCB.js.map +7 -0
- package/dist/editor.js +11 -10
- package/dist/editor.js.map +4 -4
- package/dist/loader.js +1 -1
- package/dist/loader.js.map +3 -3
- package/package.json +4 -3
- package/dist/chunks/chunk-V4BSLQ2M.js.map +0 -7
package/dist/editor.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import{b as w,c as R,e as L,f as Mt,h as Z,i as T,j as W,k as ve,l as c,m as Ct}from"./chunks/chunk-V4BSLQ2M.js";function E(r,e={},...t){return{tag:r,attrs:e,children:t}}function It(r,e=document){if(typeof r=="string")return e.createTextNode(r);let t=e.createElement(r.tag);for(let[n,i]of Object.entries(r.attrs))i!==void 0&&t.setAttribute(n,i);return r.html!==void 0?t.innerHTML=r.html:t.append(...r.children.map(n=>It(n,e))),t}function Pt(r,e,t,n){for(let i of t)e.attrs[i]===void 0&&r.removeAttribute(i);for(let[i,s]of Object.entries(e.attrs))s===void 0?r.removeAttribute(i):r.getAttribute(i)!==s&&r.setAttribute(i,s);n&&(e.html!==void 0?r.innerHTML=e.html:r.replaceChildren(...e.children.map(i=>It(i,r.ownerDocument))))}function ye(r,e,t){if(!r.carried||!e)return t;let n={...t};for(let i of r.carried){let s=e[i];!(i in n)&&s!==void 0&&(n[i]=s)}return n}function M(r,e){let t={};for(let n of r.valueKeys){let i=e[n];i!==void 0&&(t[n]=i)}return t}function ge(r,e,t){return JSON.stringify(M(r,e))===JSON.stringify(M(r,t))}function dt(r,e,t){let n={...e,...t};for(let i of r.derived??[])delete n[i];return n}function $t(r,e,t,n){let i=r.component?.(e);if(!i)return;let s=i.propsFrom(e);Pt(e,i.render({name:t.name,sortOrder:t.sortOrder,item:n},s),i.volatile,i.ownsChildren)}function Y(r,e,t,n){let i={...M(r,t),name:e.name,sortOrder:e.sortOrder,entity:{urn:n}};return e.urn!==void 0&&(i.urn=e.urn),i}function de(r){return`data-${r.attribute}-name`}function X(r){return`data-${r.attribute}-sort-order`}function P(r){return`data-${r.attribute}-urn`}var U="data-entity-urn",be=class{entries;listener;selector;byElement=new Map;unscopedByElement=new Map;observer;warned=new WeakSet;constructor(e,t){this.entries=e,this.listener=t,this.selector=e.map(n=>`[${de(n)}]`).join(","),this.observer=new MutationObserver(n=>this.onMutations(n))}start(e=document.documentElement){this.scan(e),this.observer.observe(e,{subtree:!0,childList:!0,attributes:!0,attributeFilter:[U,...this.entries.flatMap(t=>[de(t),X(t)])]})}stop(){this.observer.disconnect()}all(){return[...this.byElement.values()].flat()}unscoped(){for(let e of this.unscopedByElement.keys())e.isConnected||this.unscopedByElement.delete(e);return[...this.unscopedByElement.values()].flat()}of(e){return this.byElement.get(e)??[]}closest(e){if(!(e instanceof Element))return;let t=e.closest(this.selector);return t instanceof HTMLElement&&this.byElement.has(t)?t:void 0}flush(){let e=this.observer.takeRecords();e.length>0&&this.onMutations(e)}onMutations(e){let t=new Set,n=!1;for(let i of e){i.type==="attributes"&&i.target instanceof Element&&t.add(i.target);for(let s of i.addedNodes)s instanceof Element&&t.add(s);i.removedNodes.length>0&&(n=!0)}n&&this.sweep();for(let i of t)i.isConnected&&this.scan(i)}scan(e){let t=[...e.querySelectorAll(this.selector)];e instanceof HTMLElement&&e.matches(this.selector)&&t.unshift(e);let n=[],i=[];for(let s of t){let o=this.bind(s),a=this.unscopedSlots(s);a.length>0?this.unscopedByElement.set(s,a):this.unscopedByElement.delete(s);let d=this.byElement.get(s)??[];ci(d,o)||(i.push(...d),n.push(...o),o.length>0?this.byElement.set(s,o):this.byElement.delete(s))}e instanceof HTMLElement&&!e.matches(this.selector)&&this.byElement.has(e)&&(i.push(...this.byElement.get(e)),this.byElement.delete(e)),i.length>0&&this.listener.removed(i),n.length>0&&this.listener.added(n)}sweep(){let e=[];for(let[t,n]of this.byElement)t.isConnected||(e.push(...n),this.byElement.delete(t));e.length>0&&this.listener.removed(e)}bind(e){let t=e.closest(`[${U}]`)?.getAttribute(U),n=[];for(let i of this.entries){let s=e.getAttribute(de(i));if(!s||!t)continue;let o=this.sortOrder(e,i);o!==void 0&&n.push({element:e,entry:i,scope:t,name:s,sortOrder:o})}return n}unscopedSlots(e){if(e.closest(`[${U}]`))return[];let t=[];for(let n of this.entries){let i=e.getAttribute(de(n)),s=i?this.sortOrder(e,n):void 0;i&&s!==void 0&&t.push({element:e,entry:n,name:i,sortOrder:s})}return t}sortOrder(e,t){let n=e.getAttribute(X(t)),i=n===null||n.trim()===""?0:Number(n);if(Number.isInteger(i))return i;this.warn(e,`has ${X(t)}="${n}", which is not an integer`)}warn(e,t){this.warned.has(e)||(this.warned.add(e),console.warn(`Baack editor: element ${t}; it will not be editable.`,e))}};function ci(r,e){return r.length===e.length&&r.every((t,n)=>t.entry===e[n].entry&&t.scope===e[n].scope&&t.name===e[n].name&&t.sortOrder===e[n].sortOrder)}function $(r){return`${r.entityUrn}|${r.type}|${r.name}|${r.sortOrder}`}function z(r){return r.kind==="move"?`move|${r.planId}|${r.urn}`:r.kind==="edit"?r.urn:$(r)}var we=class{items=new Map;onChange;constructor(e){this.onChange=e}getEdit(e){let t=this.items.get(e);return t?.kind==="edit"?t:void 0}getCreate(e){let t=this.items.get(e);return t?.kind==="create"?t:void 0}set(e){this.items.set(z(e),e),this.onChange()}clear(e){this.items.delete(e)&&this.onChange()}clearAll(e){let t=this.all().filter(n=>e===void 0||n.entityUrn===e);for(let n of t)this.items.delete(z(n));return t.length>0&&this.onChange(),t}load(e){this.items.clear();for(let t of e)this.items.set(z(t),t);this.onChange()}all(){return[...this.items.values()]}plan(e){return this.all().filter(t=>t.kind==="move"&&t.planId===e)}count(){return this.items.size}byEntity(){let e=new Map;for(let t of this.items.values())e.set(t.entityUrn,[...e.get(t.entityUrn)??[],t]);return e}};var Ht="baack-editor:stash:";var Ee=class{key;constructor(e){this.key=Ht+e}load(e=Date.now()){ui(e);try{let t=window.localStorage.getItem(this.key);if(!t)return[];let n=JSON.parse(t);return n.version!==1||!Array.isArray(n.items)?[]:n.items}catch(t){return console.warn("Baack editor: could not read unsaved changes from this browser.",t),[]}}save(e,t=Date.now()){try{if(e.length===0)window.localStorage.removeItem(this.key);else{let n={version:1,savedAt:t,items:e};window.localStorage.setItem(this.key,JSON.stringify(n))}}catch(n){console.warn("Baack editor: could not keep unsaved changes in this browser.",n)}}};function ui(r){try{for(let e=window.localStorage.length-1;e>=0;e-=1){let t=window.localStorage.key(e);if(!t?.startsWith(Ht))continue;let n=JSON.parse(window.localStorage.getItem(t)??"{}").savedAt;(typeof n!="number"||r-n>6048e5)&&window.localStorage.removeItem(t)}}catch{}}var ke=class r{entity;constructor(e){this.entity=e}get urn(){return this.entity.urn}get name(){return this.entity.name}get status(){return this.entity.status}get language(){return this.entity.language}get variant(){return this.entity.variant}get publishedAt(){return this.entity.publishTimestamp?new Date(this.entity.publishTimestamp):void 0}get updatedAt(){return this.entity.updatedTimestamp?new Date(this.entity.updatedTimestamp):void 0}get raw(){return this.entity}allByName(e,t){return e?e.filter(n=>n.name===t).sort((n,i)=>n.sortOrder-i.sortOrder):[]}byNameAndSortOrder(e,t,n=0){return e?.find(i=>i.name===t&&i.sortOrder===n)}has(e){let{texts:t,markdowns:n,templates:i,booleans:s,doubles:o,longs:a,money:d,dateTimes:l,images:u,latLongs:h,jsons:f,links:p,references:v}=this.entity;return[t,n,i,s,o,a,d,l,u,h,f,p,v].some(m=>m?.some(g=>g.name===e))}hasByNameAndSortOrder(e,t,n=0){return this.byNameAndSortOrder(e,t,n)!==void 0}hasText(e,t=0){return this.hasByNameAndSortOrder(this.entity.texts,e,t)}hasMarkdown(e,t=0){return this.hasByNameAndSortOrder(this.entity.markdowns,e,t)}hasTemplate(e,t=0){return this.hasByNameAndSortOrder(this.entity.templates,e,t)}hasBoolean(e,t=0){return this.hasByNameAndSortOrder(this.entity.booleans,e,t)}hasDouble(e,t=0){return this.hasByNameAndSortOrder(this.entity.doubles,e,t)}hasLong(e,t=0){return this.hasByNameAndSortOrder(this.entity.longs,e,t)}hasNumber(e,t=0){return this.hasDouble(e,t)||this.hasLong(e,t)}hasMoney(e,t=0){return this.hasByNameAndSortOrder(this.entity.money,e,t)}hasDate(e,t=0){return this.hasByNameAndSortOrder(this.entity.dateTimes,e,t)}hasImage(e,t=0){return this.hasByNameAndSortOrder(this.entity.images,e,t)}hasLatLong(e,t=0){return this.hasByNameAndSortOrder(this.entity.latLongs,e,t)}hasJson(e,t=0){return this.hasByNameAndSortOrder(this.entity.jsons,e,t)}hasLink(e,t=0){return this.hasByNameAndSortOrder(this.entity.links,e,t)}hasReference(e,t=0){return this.hasByNameAndSortOrder(this.entity.references,e,t)}text(e,t=0){return this.byNameAndSortOrder(this.entity.texts,e,t)}texts(e){return this.allByName(this.entity.texts,e)}requireText(e,t=0){let n=this.text(e,t);if(n===void 0)throw new Error(`EntityView: missing required text item "${e}" on entity ${this.entity.urn}`);return n}markdown(e,t=0){return this.byNameAndSortOrder(this.entity.markdowns,e,t)}markdowns(e){return this.allByName(this.entity.markdowns,e)}template(e,t=0){return this.byNameAndSortOrder(this.entity.templates,e,t)}templates(e){return this.allByName(this.entity.templates,e)}boolean(e,t=0){return this.byNameAndSortOrder(this.entity.booleans,e,t)}booleans(e){return this.allByName(this.entity.booleans,e)}double(e,t=0){return this.byNameAndSortOrder(this.entity.doubles,e,t)}doubles(e){return this.allByName(this.entity.doubles,e)}long(e,t=0){return this.byNameAndSortOrder(this.entity.longs,e,t)}longs(e){return this.allByName(this.entity.longs,e)}number(e,t=0){return this.double(e,t)??this.long(e,t)}money(e,t=0){return this.byNameAndSortOrder(this.entity.money,e,t)}moneys(e){return this.allByName(this.entity.money,e)}date(e,t=0){return this.byNameAndSortOrder(this.entity.dateTimes,e,t)}dates(e){return this.allByName(this.entity.dateTimes,e)}image(e,t=0){return this.byNameAndSortOrder(this.entity.images,e,t)}images(e){return this.allByName(this.entity.images,e)}latLong(e,t=0){return this.byNameAndSortOrder(this.entity.latLongs,e,t)}latLongs(e){return this.allByName(this.entity.latLongs,e)}json(e,t=0){return this.byNameAndSortOrder(this.entity.jsons,e,t)}jsons(e){return this.allByName(this.entity.jsons,e)}link(e,t=0){return this.byNameAndSortOrder(this.entity.links,e,t)}links(e){return this.allByName(this.entity.links,e)}reference(e,t=0){return this.byNameAndSortOrder(this.entity.references,e,t)}references(e){return this.allByName(this.entity.references,e)}static async fetch(e,t,n,i){let s=await e.read(w.ENTITY_VIEW,t,n,i);return new r(s)}static from(e){return new r(e)}};var xe=class{scopes=new Map;views=new Map;items=new Map;hasScope(e){return this.scopes.has(e)}loadEntity(e,t){this.scopes.set(e,t.urn),this.views.set(t.urn,ke.from(t))}entityFor(e){return this.scopes.get(e)}view(e){return this.views.get(e)}entities(){return[...this.views.keys()]}scopesFor(e){return[...this.scopes].filter(([,t])=>t===e).map(([t])=>t)}itemFor(e){let t=this.scopes.get(e.scope);return t===void 0?void 0:this.itemAt(t,e.entry,e.name,e.sortOrder)}itemAt(e,t,n,i){let s=this.views.get(e),o=s?t.find(s,n,i):void 0;if(!o?.urn)return;let a={entry:t,item:o,entityUrn:e};return this.items.set(o.urn,a),a}remember(e,t,n){let i={entry:t,item:n,entityUrn:e};return n.urn&&this.items.set(n.urn,i),i}get(e){return this.items.get(e)}replace(e,t){let n=this.items.get(e);if(!n||!t.urn)throw new Error(`Cannot replace unknown item ${e}`);let i={entry:n.entry,item:t,entityUrn:n.entityUrn};if(this.items.delete(e),this.items.set(t.urn,i),n.entry.renderedByView)return i;let s=this.views.get(n.entityUrn)?.raw[n.entry.entityArray],o=s?.findIndex(a=>a.urn===e)??-1;return s&&o>=0&&(s[o]=t),i}clearEntities(){this.scopes.clear(),this.views.clear(),this.items.clear()}};var le=class extends Error{expectedUrn;received;constructor(e,t){super(`The entity view returned ${t.urn} (${t.language}) for ${e}`),this.name="EntityMismatchError",this.expectedUrn=e,this.received=t}},Q=class extends Error{entityUrn;constructor(e){super(`${e} has no live view: it is not published`),this.name="NotLiveError",this.entityUrn=e}};function S(r){return r==="PUBLISHED"||r==="PUBLISHED_WITH_DRAFTS"}var Le=class{transport;locators=new Map;constructor(e){this.transport=e}async read(e,t={}){let n=await this.locator(e),i;try{i=await this.transport.entityView(e,{...t,...n})}catch(s){throw t.version===void 0&&R(s)&&s.isNotFound?new Q(e):s}if(i.urn!==e)throw new le(e,i);return i}async readAsLive(e){let t=await this.transport.readEntity(e);if(this.locators.set(e,Promise.resolve({language:t.language,variant:t.variant??""})),S(t.status))return{entity:await this.read(e),live:!0};if(t.status==="PUBLISH"||t.status==="PUBLISH_PENDING")try{return{entity:await this.read(e),live:!0}}catch(n){if(!(n instanceof Q))throw n}return{entity:await this.read(e,{version:"LATEST"}),live:!1}}locator(e){let t=this.locators.get(e);return t||(t=this.transport.readEntity(e).then(n=>({language:n.language,variant:n.variant??""})),t.catch(()=>this.locators.delete(e)),this.locators.set(e,t)),t}};function Te(r,e){return{label:r.canPublish?"Review and publish\u2026":"Request approval\u2026",run:()=>r.hooks.publishEntity(e)}}function ee(r){let e=document.documentElement.getAttribute(U);return e?r.entityFor(e):void 0}function te(r,e){let t=ee(r);return[...e].sort((n,i)=>n===t?-1:i===t?1:0)}function ce(r){switch(r){case"DRAFT_UNPUBLISHED":return"Draft, not published yet";case"PUBLISH":return"Publishing\u2026";case"PUBLISH_PENDING":return"Scheduled to publish";case"PUBLISHED":return"Published";case"PUBLISHED_WITH_DRAFTS":return"Published, with unpublished changes";default:return""}}var Se="data-baack-state",hi={editable:["1px dashed","primary",70],editing:["2px solid","primary",100],changed:["2px solid","warning",100],unresolved:["1px dotted","muted",80],previewing:["2px dashed","preview",100],published:["2px solid","success",100]};function pi(r,e){let[t,n,i]=hi[e],[s,o]=Mt[n],a=d=>i===100?d:`color-mix(in srgb, ${d} ${i}%, transparent)`;r.style.outline=`${t} ${a(s)}`,r.style.outline=`${t} ${a(`light-dark(${s}, ${o})`)}`}var ue=new WeakMap;function N(r,e){if(!ue.has(r)){let{outline:t,outlineOffset:n,display:i,minWidth:s,minHeight:o}=r.style;ue.set(r,{outline:t,outlineOffset:n,display:i,minWidth:s,minHeight:o})}pi(r,e),r.style.outlineOffset="2px",r.setAttribute(Se,e),Ae(r)}function Ae(r){let e=ue.get(r);e&&(r.style.display=e.display,r.style.minWidth=e.minWidth,r.style.minHeight=e.minHeight,!(r.textContent!==""||r.querySelector("img, picture, svg, video, iframe"))&&(getComputedStyle(r).display==="inline"&&(r.style.display="inline-block"),r.style.minWidth="1ch",r.style.minHeight="1lh"))}function Bt(r){let e=ue.get(r);e&&(r.style.outline=e.outline,r.style.outlineOffset=e.outlineOffset,r.style.display=e.display,r.style.minWidth=e.minWidth,r.style.minHeight=e.minHeight,r.getAttribute("style")||r.removeAttribute("style"),ue.delete(r)),r.removeAttribute(Se)}function Oe(r){return r.split(/\n\s*\n/).map(e=>e.split(`
|
|
2
|
-
`).map(t=>t.replace(/\s+/g," ").trim()).filter(Boolean)).filter(e=>e.length>0)}function
|
|
1
|
+
import{c as L,d as Zt,f as z,g as x,h as Z,i as ee,j as l,k as Xt,l as Qt,m as en}from"./chunks/chunk-MSWF55NC.js";import{C as Kt,P as jt,i as Ut,ia as qt,l as Vt,la as gt,m as _t,n as Gt,o as vt,oa as Wt,p as zt,qa as Yt,r as ye,va as Jt}from"./chunks/chunk-VNUXOULZ.js";import{a as w,c as D}from"./chunks/chunk-5RFN34CS.js";function E(r,e={},...t){return{tag:r,attrs:e,children:t}}function tn(r,e=document){if(typeof r=="string")return e.createTextNode(r);let t=e.createElement(r.tag);for(let[n,i]of Object.entries(r.attrs))i!==void 0&&t.setAttribute(n,i);return r.html!==void 0?t.innerHTML=r.html:t.append(...r.children.map(n=>tn(n,e))),t}function nn(r,e,t,n){for(let i of t)e.attrs[i]===void 0&&r.removeAttribute(i);for(let[i,s]of Object.entries(e.attrs))s===void 0?r.removeAttribute(i):r.getAttribute(i)!==s&&r.setAttribute(i,s);n&&(e.html!==void 0?r.innerHTML=e.html:r.replaceChildren(...e.children.map(i=>tn(i,r.ownerDocument))))}function be(r,e,t){if(!r.carried||!e)return t;let n={...t};for(let i of r.carried){let s=e[i];!(i in n)&&s!==void 0&&(n[i]=s)}return n}function O(r,e){let t={};for(let n of r.valueKeys){let i=e[n];i!==void 0&&(t[n]=i)}return t}function we(r,e,t){return JSON.stringify(O(r,e))===JSON.stringify(O(r,t))}function yt(r,e,t){let n={...e,...t};for(let i of r.derived??[])delete n[i];return n}function rn(r,e,t,n){let i=r.component?.(e);if(!i)return;let s=i.propsFrom(e);nn(e,i.render({name:t.name,sortOrder:t.sortOrder,item:n},s),i.volatile,i.ownsChildren)}function X(r,e,t,n){let i={...O(r,t),name:e.name,sortOrder:e.sortOrder,entity:{urn:n}};return e.urn!==void 0&&(i.urn=e.urn),i}function ce(r){return`data-${r.attribute}-name`}function te(r){return`data-${r.attribute}-sort-order`}function B(r){return`data-${r.attribute}-urn`}var _="data-entity-urn",Ee=class{entries;listener;selector;byElement=new Map;unscopedByElement=new Map;observer;warned=new WeakSet;constructor(e,t){this.entries=e,this.listener=t,this.selector=e.map(n=>`[${ce(n)}]`).join(","),this.observer=new MutationObserver(n=>this.onMutations(n))}start(e=document.documentElement){this.scan(e),this.observer.observe(e,{subtree:!0,childList:!0,attributes:!0,attributeFilter:[_,...this.entries.flatMap(t=>[ce(t),te(t)])]})}stop(){this.observer.disconnect()}all(){return[...this.byElement.values()].flat()}unscoped(){for(let e of this.unscopedByElement.keys())e.isConnected||this.unscopedByElement.delete(e);return[...this.unscopedByElement.values()].flat()}of(e){return this.byElement.get(e)??[]}closest(e){if(!(e instanceof Element))return;let t=e.closest(this.selector);return t instanceof HTMLElement&&this.byElement.has(t)?t:void 0}flush(){let e=this.observer.takeRecords();e.length>0&&this.onMutations(e)}onMutations(e){let t=new Set,n=!1;for(let i of e){i.type==="attributes"&&i.target instanceof Element&&t.add(i.target);for(let s of i.addedNodes)s instanceof Element&&t.add(s);i.removedNodes.length>0&&(n=!0)}n&&this.sweep();for(let i of t)i.isConnected&&this.scan(i)}scan(e){let t=[...e.querySelectorAll(this.selector)];e instanceof HTMLElement&&e.matches(this.selector)&&t.unshift(e);let n=[],i=[];for(let s of t){let o=this.bind(s),a=this.unscopedSlots(s);a.length>0?this.unscopedByElement.set(s,a):this.unscopedByElement.delete(s);let d=this.byElement.get(s)??[];Ni(d,o)||(i.push(...d),n.push(...o),o.length>0?this.byElement.set(s,o):this.byElement.delete(s))}e instanceof HTMLElement&&!e.matches(this.selector)&&this.byElement.has(e)&&(i.push(...this.byElement.get(e)),this.byElement.delete(e)),i.length>0&&this.listener.removed(i),n.length>0&&this.listener.added(n)}sweep(){let e=[];for(let[t,n]of this.byElement)t.isConnected||(e.push(...n),this.byElement.delete(t));e.length>0&&this.listener.removed(e)}bind(e){let t=e.closest(`[${_}]`)?.getAttribute(_),n=[];for(let i of this.entries){let s=e.getAttribute(ce(i));if(!s||!t)continue;let o=this.sortOrder(e,i);o!==void 0&&n.push({element:e,entry:i,scope:t,name:s,sortOrder:o})}return n}unscopedSlots(e){if(e.closest(`[${_}]`))return[];let t=[];for(let n of this.entries){let i=e.getAttribute(ce(n)),s=i?this.sortOrder(e,n):void 0;i&&s!==void 0&&t.push({element:e,entry:n,name:i,sortOrder:s})}return t}sortOrder(e,t){let n=e.getAttribute(te(t)),i=n===null||n.trim()===""?0:Number(n);if(Number.isInteger(i))return i;this.warn(e,`has ${te(t)}="${n}", which is not an integer`)}warn(e,t){this.warned.has(e)||(this.warned.add(e),console.warn(`Baack editor: element ${t}; it will not be editable.`,e))}};function Ni(r,e){return r.length===e.length&&r.every((t,n)=>t.entry===e[n].entry&&t.scope===e[n].scope&&t.name===e[n].name&&t.sortOrder===e[n].sortOrder)}function H(r){return`${r.entityUrn}|${r.type}|${r.name}|${r.sortOrder}`}function K(r){return r.kind==="move"?`move|${r.planId}|${r.urn}`:r.kind==="edit"?r.urn:H(r)}var ke=class{items=new Map;onChange;constructor(e){this.onChange=e}getEdit(e){let t=this.items.get(e);return t?.kind==="edit"?t:void 0}getCreate(e){let t=this.items.get(e);return t?.kind==="create"?t:void 0}set(e){this.items.set(K(e),e),this.onChange()}clear(e){this.items.delete(e)&&this.onChange()}clearAll(e){let t=this.all().filter(n=>e===void 0||n.entityUrn===e);for(let n of t)this.items.delete(K(n));return t.length>0&&this.onChange(),t}load(e){this.items.clear();for(let t of e)this.items.set(K(t),t);this.onChange()}all(){return[...this.items.values()]}plan(e){return this.all().filter(t=>t.kind==="move"&&t.planId===e)}count(){return this.items.size}byEntity(){let e=new Map;for(let t of this.items.values())e.set(t.entityUrn,[...e.get(t.entityUrn)??[],t]);return e}};var sn="baack-editor:stash:";var xe=class{key;constructor(e){this.key=sn+e}load(e=Date.now()){Ri(e);try{let t=window.localStorage.getItem(this.key);if(!t)return[];let n=JSON.parse(t);return n.version!==1||!Array.isArray(n.items)?[]:n.items}catch(t){return console.warn("Baack editor: could not read unsaved changes from this browser.",t),[]}}save(e,t=Date.now()){try{if(e.length===0)window.localStorage.removeItem(this.key);else{let n={version:1,savedAt:t,items:e};window.localStorage.setItem(this.key,JSON.stringify(n))}}catch(n){console.warn("Baack editor: could not keep unsaved changes in this browser.",n)}}};function Ri(r){try{for(let e=window.localStorage.length-1;e>=0;e-=1){let t=window.localStorage.key(e);if(!t?.startsWith(sn))continue;let n=JSON.parse(window.localStorage.getItem(t)??"{}").savedAt;(typeof n!="number"||r-n>6048e5)&&window.localStorage.removeItem(t)}}catch{}}var Te=class r{entity;constructor(e){this.entity=e}get urn(){return this.entity.urn}get name(){return this.entity.name}get status(){return this.entity.status}get language(){return this.entity.language}get variant(){return this.entity.variant}get publishedAt(){return this.entity.publishTimestamp?new Date(this.entity.publishTimestamp):void 0}get updatedAt(){return this.entity.updatedTimestamp?new Date(this.entity.updatedTimestamp):void 0}get raw(){return this.entity}allByName(e,t){return e?e.filter(n=>n.name===t).sort((n,i)=>n.sortOrder-i.sortOrder):[]}byNameAndSortOrder(e,t,n=0){return e?.find(i=>i.name===t&&i.sortOrder===n)}has(e){let{texts:t,markdowns:n,templates:i,booleans:s,doubles:o,longs:a,money:d,dateTimes:c,images:u,latLongs:h,jsons:v,links:p,references:f}=this.entity;return[t,n,i,s,o,a,d,c,u,h,v,p,f].some(m=>m?.some(g=>g.name===e))}hasByNameAndSortOrder(e,t,n=0){return this.byNameAndSortOrder(e,t,n)!==void 0}hasText(e,t=0){return this.hasByNameAndSortOrder(this.entity.texts,e,t)}hasMarkdown(e,t=0){return this.hasByNameAndSortOrder(this.entity.markdowns,e,t)}hasTemplate(e,t=0){return this.hasByNameAndSortOrder(this.entity.templates,e,t)}hasBoolean(e,t=0){return this.hasByNameAndSortOrder(this.entity.booleans,e,t)}hasDouble(e,t=0){return this.hasByNameAndSortOrder(this.entity.doubles,e,t)}hasLong(e,t=0){return this.hasByNameAndSortOrder(this.entity.longs,e,t)}hasNumber(e,t=0){return this.hasDouble(e,t)||this.hasLong(e,t)}hasMoney(e,t=0){return this.hasByNameAndSortOrder(this.entity.money,e,t)}hasDate(e,t=0){return this.hasByNameAndSortOrder(this.entity.dateTimes,e,t)}hasImage(e,t=0){return this.hasByNameAndSortOrder(this.entity.images,e,t)}hasLatLong(e,t=0){return this.hasByNameAndSortOrder(this.entity.latLongs,e,t)}hasJson(e,t=0){return this.hasByNameAndSortOrder(this.entity.jsons,e,t)}hasLink(e,t=0){return this.hasByNameAndSortOrder(this.entity.links,e,t)}hasReference(e,t=0){return this.hasByNameAndSortOrder(this.entity.references,e,t)}text(e,t=0){return this.byNameAndSortOrder(this.entity.texts,e,t)}texts(e){return this.allByName(this.entity.texts,e)}requireText(e,t=0){let n=this.text(e,t);if(n===void 0)throw new Error(`EntityView: missing required text item "${e}" on entity ${this.entity.urn}`);return n}markdown(e,t=0){return this.byNameAndSortOrder(this.entity.markdowns,e,t)}markdowns(e){return this.allByName(this.entity.markdowns,e)}template(e,t=0){return this.byNameAndSortOrder(this.entity.templates,e,t)}templates(e){return this.allByName(this.entity.templates,e)}boolean(e,t=0){return this.byNameAndSortOrder(this.entity.booleans,e,t)}booleans(e){return this.allByName(this.entity.booleans,e)}double(e,t=0){return this.byNameAndSortOrder(this.entity.doubles,e,t)}doubles(e){return this.allByName(this.entity.doubles,e)}long(e,t=0){return this.byNameAndSortOrder(this.entity.longs,e,t)}longs(e){return this.allByName(this.entity.longs,e)}number(e,t=0){return this.double(e,t)??this.long(e,t)}money(e,t=0){return this.byNameAndSortOrder(this.entity.money,e,t)}moneys(e){return this.allByName(this.entity.money,e)}date(e,t=0){return this.byNameAndSortOrder(this.entity.dateTimes,e,t)}dates(e){return this.allByName(this.entity.dateTimes,e)}image(e,t=0){return this.byNameAndSortOrder(this.entity.images,e,t)}images(e){return this.allByName(this.entity.images,e)}latLong(e,t=0){return this.byNameAndSortOrder(this.entity.latLongs,e,t)}latLongs(e){return this.allByName(this.entity.latLongs,e)}json(e,t=0){return this.byNameAndSortOrder(this.entity.jsons,e,t)}jsons(e){return this.allByName(this.entity.jsons,e)}link(e,t=0){return this.byNameAndSortOrder(this.entity.links,e,t)}links(e){return this.allByName(this.entity.links,e)}reference(e,t=0){return this.byNameAndSortOrder(this.entity.references,e,t)}references(e){return this.allByName(this.entity.references,e)}static async fetch(e,t,n,i){let s=await e.read(w.ENTITY_VIEW,t,n,i);return new r(s)}static from(e){return new r(e)}};var Le=class{scopes=new Map;views=new Map;items=new Map;hasScope(e){return this.scopes.has(e)}loadEntity(e,t){this.scopes.set(e,t.urn),this.views.set(t.urn,Te.from(t))}entityFor(e){return this.scopes.get(e)}view(e){return this.views.get(e)}entities(){return[...this.views.keys()]}scopesFor(e){return[...this.scopes].filter(([,t])=>t===e).map(([t])=>t)}itemFor(e){let t=this.scopes.get(e.scope);return t===void 0?void 0:this.itemAt(t,e.entry,e.name,e.sortOrder)}itemAt(e,t,n,i){let s=this.views.get(e),o=s?t.find(s,n,i):void 0;if(!o?.urn)return;let a={entry:t,item:o,entityUrn:e};return this.items.set(o.urn,a),a}remember(e,t,n){let i={entry:t,item:n,entityUrn:e};return n.urn&&this.items.set(n.urn,i),i}get(e){return this.items.get(e)}replace(e,t){let n=this.items.get(e);if(!n||!t.urn)throw new Error(`Cannot replace unknown item ${e}`);let i={entry:n.entry,item:t,entityUrn:n.entityUrn};if(this.items.delete(e),this.items.set(t.urn,i),n.entry.renderedByView)return i;let s=this.views.get(n.entityUrn)?.raw[n.entry.entityArray],o=s?.findIndex(a=>a.urn===e)??-1;return s&&o>=0&&(s[o]=t),i}clearEntities(){this.scopes.clear(),this.views.clear(),this.items.clear()}};var ue=class extends Error{expectedUrn;received;constructor(e,t){super(`The entity view returned ${t.urn} (${t.language}) for ${e}`),this.name="EntityMismatchError",this.expectedUrn=e,this.received=t}},ne=class extends Error{entityUrn;constructor(e){super(`${e} has no live view: it is not published`),this.name="NotLiveError",this.entityUrn=e}};function S(r){return r==="PUBLISHED"||r==="PUBLISHED_WITH_DRAFTS"}var Se=class{transport;locators=new Map;constructor(e){this.transport=e}async read(e,t={}){let n=await this.locator(e),i;try{i=await this.transport.entityView(e,{...t,...n})}catch(s){throw t.version===void 0&&D(s)&&s.isNotFound?new ne(e):s}if(i.urn!==e)throw new ue(e,i);return i}async readAsLive(e){let t=await this.transport.readEntity(e);if(this.locators.set(e,Promise.resolve({language:t.language,variant:t.variant??""})),S(t.status))return{entity:await this.read(e),live:!0};if(t.status==="PUBLISH"||t.status==="PUBLISH_PENDING")try{return{entity:await this.read(e),live:!0}}catch(n){if(!(n instanceof ne))throw n}return{entity:await this.read(e,{version:"LATEST"}),live:!1}}locator(e){let t=this.locators.get(e);return t||(t=this.transport.readEntity(e).then(n=>({language:n.language,variant:n.variant??""})),t.catch(()=>this.locators.delete(e)),this.locators.set(e,t)),t}};function Ae(r,e){return{label:r.canPublish?"Review and publish\u2026":"Request approval\u2026",run:()=>r.hooks.publishEntity(e)}}function ie(r){let e=document.documentElement.getAttribute(_);return e?r.entityFor(e):void 0}function re(r,e){let t=ie(r);return[...e].sort((n,i)=>n===t?-1:i===t?1:0)}function he(r){switch(r){case"DRAFT_UNPUBLISHED":return"Draft, not published yet";case"PUBLISH":return"Publishing\u2026";case"PUBLISH_PENDING":return"Scheduled to publish";case"PUBLISHED":return"Published";case"PUBLISHED_WITH_DRAFTS":return"Published, with unpublished changes";default:return""}}var Ce="data-baack-state",Di={editable:["1px dashed","primary",70],editing:["2px solid","primary",100],changed:["2px solid","warning",100],unresolved:["1px dotted","muted",80],previewing:["2px dashed","preview",100],published:["2px solid","success",100]};function Fi(r,e){let[t,n,i]=Di[e],[s,o]=Zt[n],a=d=>i===100?d:`color-mix(in srgb, ${d} ${i}%, transparent)`;r.style.outline=`${t} ${a(s)}`,r.style.outline=`${t} ${a(`light-dark(${s}, ${o})`)}`}var pe=new WeakMap;function F(r,e){if(!pe.has(r)){let{outline:t,outlineOffset:n,display:i,minWidth:s,minHeight:o}=r.style;pe.set(r,{outline:t,outlineOffset:n,display:i,minWidth:s,minHeight:o})}Fi(r,e),r.style.outlineOffset="2px",r.setAttribute(Ce,e),Oe(r)}function Oe(r){let e=pe.get(r);e&&(r.style.display=e.display,r.style.minWidth=e.minWidth,r.style.minHeight=e.minHeight,!(r.textContent!==""||r.querySelector("img, picture, svg, video, iframe"))&&(getComputedStyle(r).display==="inline"&&(r.style.display="inline-block"),r.style.minWidth="1ch",r.style.minHeight="1lh"))}function on(r){let e=pe.get(r);e&&(r.style.outline=e.outline,r.style.outlineOffset=e.outlineOffset,r.style.display=e.display,r.style.minWidth=e.minWidth,r.style.minHeight=e.minHeight,r.getAttribute("style")||r.removeAttribute("style"),pe.delete(r)),r.removeAttribute(Ce)}function Me(r){return r.split(/\n\s*\n/).map(e=>e.split(`
|
|
2
|
+
`).map(t=>t.replace(/\s+/g," ").trim()).filter(Boolean)).filter(e=>e.length>0)}function se(r){return Me(r).flat()}var Ui=/(https?:\/\/[^\s)]+[^\s).,;:!?]|[\w.+-]+@[\w-]+(?:\.[\w-]+)+)/g;function an(r){return r.split(Ui).map((e,t)=>{if(e!=="")return t%2===0?{text:e}:{text:e,href:e.includes("@")&&!e.startsWith("http")?`mailto:${e}`:e}}).filter(e=>e!==void 0)}function me(r){try{return new Intl.NumberFormat("en-GB",{style:"currency",currency:r}).resolvedOptions().maximumFractionDigits??2}catch{return 2}}function dn(r){return r.formattedValue?r.formattedValue:Pe(r.unitValue,me(r.currencyCode))}function ln(r){if(r.currencySymbol)return r.currencySymbol;try{return new Intl.NumberFormat("en-GB",{style:"currency",currency:r.currencyCode}).formatToParts(0).find(t=>t.type==="currency")?.value??r.currencyCode}catch{return r.currencyCode}}function Pe(r,e){let t=r<0,n=String(Math.abs(Math.trunc(r)));if(e===0)return(t?"-":"")+n;let i=n.padStart(e+1,"0");return`${t?"-":""}${i.slice(0,-e)}.${i.slice(-e)}`}function bt(r,e){let t=/^\s*(-)?(\d+)(?:\.(\d*))?\s*$/.exec(r);if(!t)return;let[,n,i="0",s=""]=t;if(s.length>e)return;let o=Number(i+s.padEnd(e,"0"));if(Number.isSafeInteger(o))return n?-o:o}function M(r){return Date.parse(/[zZ]|[+-]\d\d:?\d\d$/.test(r)?r:`${r}Z`)}function cn(r,e){let t=M(r);if(Number.isNaN(t))return r;let n={timeZone:e.timeZone??"UTC"};return e.dateStyle&&(n.dateStyle=e.dateStyle),e.timeStyle&&(n.timeStyle=e.timeStyle),!e.dateStyle&&!e.timeStyle&&(n.dateStyle="medium"),new Intl.DateTimeFormat(e.locale??"en-GB",n).format(t)}function un(r,e){return new Intl.NumberFormat(e??"en-GB",{maximumFractionDigits:20}).format(r)}var Vi=new Set(["id","role","title","lang","dir","tabindex","itemscope","itemtype","itemid","itemref"]),_i=/^data-(placeholder|section|content-rows?|[a-z]+-(name|sort-order|urn|list)|attr-[a-z0-9-]+-(name|sort-order|urn|placeholder))$/;function Gi(r){return _i.test(r)?!1:Vi.has(r)||/^(data|aria)-[a-z0-9-]+$/.test(r)}function I(r){let e={};for(let[t,n]of Object.entries(r??{}))Gi(t)&&(e[t]=n);return e}function $(r,e,t){return{[`data-${r}-name`]:e.name,[`data-${r}-sort-order`]:String(e.sortOrder),[`data-${r}-urn`]:t?void 0:e.item?.urn,"data-placeholder":t?"":void 0}}function N(r,...e){return[`data-${r}-urn`,"data-placeholder",...e]}function W(r){return{className:r.getAttribute("class")??void 0,itemProp:r.getAttribute("itemprop")??void 0}}function pn(r,e,t){return t?r.flatMap((n,i)=>i>0?[E("br"),...e(n)]:e(n)):[r.join(" ")]}function mn(r,e){return e?an(r).map(t=>"href"in t?E("a",{href:t.href},t.text):t.text):[r]}var wt={type:"text",volatile:N("text"),ownsChildren:!0,render(r,e){let t=r.item?se(r.item.value):[],n=t.length===0,i=e.as??"span",s=n?se(e.placeholder):t,o=E(i,{...I(e.attributes),class:e.className,itemprop:e.itemProp,...$("text",r,n),"data-text-linkify":e.linkify?"":void 0,"data-text-unsafe-literal":e.unsafeLiteral?"":void 0},...pn(s,a=>mn(a,e.linkify===!0),i!=="title"&&i!=="option"));return e.unsafeLiteral&&!n&&(o.html=r.item.value),o},propsFrom:r=>({...W(r),placeholder:"",as:r.localName,linkify:r.hasAttribute("data-text-linkify"),unsafeLiteral:r.hasAttribute("data-text-unsafe-literal")})},fn={type:"text",volatile:N("text"),ownsChildren:!0,render(r,e){let t=r.item?Me(r.item.value):[],n=t.length===0,i=n?Me(e.placeholder):t,s=E(e.as??"div",{...I(e.attributes),class:e.className,itemprop:e.itemProp,...$("text",r,n),"data-text-layout":"paragraphs","data-text-linkify":e.linkify?"":void 0,"data-text-unsafe-literal":e.unsafeLiteral?"":void 0},...i.map(o=>E("p",{class:e.paragraphClassName},...pn(o,a=>mn(a,e.linkify===!0),!0))));return e.unsafeLiteral&&!n&&(s.html=r.item.value),s},propsFrom:r=>({...wt.propsFrom(r),paragraphClassName:r.querySelector(":scope > p")?.getAttribute("class")??void 0})},vn={type:"text",volatile:N("text","content"),ownsChildren:!1,render(r,e){let t=r.item?se(r.item.value).join(" "):"",n=t==="";return E("meta",{...I(e.attributes),name:e.name,property:e.property,content:n?e.placeholder:t,...$("text",r,n)})},propsFrom:r=>({name:r.getAttribute("name")??void 0,property:r.getAttribute("property")??void 0,placeholder:""})};function gn(r){return{type:r,volatile:N(r),ownsChildren:!0,render(e,t){let n=e.item?.value,i=!n?.trim(),s=E(t.as??"div",{...I(t.attributes),class:t.className,itemprop:t.itemProp,...$(r,e,i)});return i?s.children=[E("p",{},t.placeholder)]:s.html=n,s},propsFrom:e=>({...W(e),placeholder:"",as:e.localName})}}var yn=gn("markdown"),bn=gn("template"),wn={type:"money",volatile:N("money","itemprop","content","data-money-currency","data-money-unit-value"),ownsChildren:!0,render(r,e){let t=r.item,n={"data-money-offer":e.offer?"":void 0,"data-money-item-prop":e.offer?void 0:e.itemProp};if(!t)return E("span",{...I(e.attributes),class:e.className,...$("money",r,!0),...n},e.placeholder);let i=dn(t);return E("span",{...I(e.attributes),class:e.className,itemprop:e.offer?"price":e.itemProp,content:e.offer?i:void 0,...$("money",r,!1),"data-money-currency":t.currencyCode,"data-money-unit-value":String(t.unitValue),...n},E("span",{itemprop:e.offer?"priceCurrency":void 0,content:e.offer?t.currencyCode:void 0},ln(t)),i)},propsFrom:r=>({className:r.getAttribute("class")??void 0,itemProp:r.getAttribute("data-money-item-prop")??void 0,offer:r.hasAttribute("data-money-offer"),placeholder:""})};function En(r){return{type:r,volatile:N(r,"value"),ownsChildren:!0,render(e,t){let n=e.item;return E("data",{...I(t.attributes),class:t.className,itemprop:t.itemProp,value:n?String(n.value):void 0,...$(r,e,!n),"data-locale":t.locale},n?un(n.value,t.locale):t.placeholder)},propsFrom:e=>({...W(e),placeholder:"",locale:e.getAttribute("data-locale")??void 0})}}var kn=En("long"),xn=En("double"),Tn={type:"datetime",volatile:N("datetime","datetime"),ownsChildren:!0,render(r,e){let t=r.item,n=t?M(t.value):NaN;return E("time",{...I(e.attributes),class:e.className,itemprop:e.itemProp,datetime:Number.isNaN(n)?void 0:new Date(n).toISOString(),...$("datetime",r,!t),"data-locale":e.locale,"data-date-style":e.dateStyle,"data-time-style":e.timeStyle,"data-time-zone":e.timeZone},t?cn(t.value,e):e.placeholder)},propsFrom:r=>({...W(r),placeholder:"",locale:r.getAttribute("data-locale")??void 0,dateStyle:r.getAttribute("data-date-style")??void 0,timeStyle:r.getAttribute("data-time-style")??void 0,timeZone:r.getAttribute("data-time-zone")??void 0})},Ln={type:"boolean",volatile:N("boolean","hidden"),ownsChildren:!1,render(r,e){let t=r.item?r.item.value:e.fallback===!0,n=e.invert?!t:t;return E(e.as??"div",{...I(e.attributes),class:e.className,hidden:n?void 0:"",...$("boolean",r,!r.item),"data-boolean-value":String(t),"data-boolean-invert":e.invert?"":void 0})},propsFrom:r=>({className:r.getAttribute("class")??void 0,invert:r.hasAttribute("data-boolean-invert"),as:r.localName})},Sn={type:"latlong",volatile:N("latlong"),ownsChildren:!0,render(r,e){let t=r.item,n={...I(e.attributes),class:e.className,itemprop:e.itemProp,itemscope:"",itemtype:"https://schema.org/GeoCoordinates",...$("latlong",r,!t)};return t?E("span",n,E("meta",{itemprop:"latitude",content:String(t.latitude)}),E("meta",{itemprop:"longitude",content:String(t.longitude)}),`${t.latitude}, ${t.longitude}`):E("span",n,e.placeholder)},propsFrom:r=>({...W(r),placeholder:""})};function zi(r,e,t){let n=e.item?se(e.item.value).join(" "):"",i=n==="";return{[r]:i?t:n,[`data-attr-${r}-name`]:e.name,[`data-attr-${r}-sort-order`]:String(e.sortOrder),[`data-attr-${r}-urn`]:i?void 0:e.item?.urn,[`data-attr-${r}-placeholder`]:i?"":void 0}}function Ki(r){return[`data-attr-${r}-urn`,`data-attr-${r}-placeholder`]}function ji(r,e){let t=r.getAttribute(`data-attr-${e}-name`)??"",n=Number(r.getAttribute(`data-attr-${e}-sort-order`)??0),i=r.getAttribute(`data-attr-${e}-urn`),s=r.getAttribute(e)??"";return i===null?{ref:{name:t,sortOrder:n},placeholder:s}:{ref:{name:t,sortOrder:n,item:{urn:i,value:s}},placeholder:""}}var is={type:"text",volatile:[...N("text"),...Ki("value")],ownsChildren:!0,render(r,e){let t=r.item?se(r.item.value).join(" "):"",n=t==="";return E("option",{...I(e.attributes),class:e.className,...Yi(r.sortOrder),...$("text",r,n),...zi("value",e.value,e.valuePlaceholder)},n?e.placeholder:t)},propsFrom:r=>{let e=ji(r,"value");return{...W(r),placeholder:"",value:e.ref,valuePlaceholder:e.placeholder}}};function hn(r){return r.replace(/\r\n?/g,`
|
|
3
|
+
`)}var An={type:"text",volatile:N("text"),ownsChildren:!0,render(r,e){let t=r.item&&r.item.value.trim()!==""?hn(r.item.value):"",n=t==="";return E(e.as??"code",{...I(e.attributes),class:e.className,itemprop:e.itemProp,...$("text",r,n),"data-text-layout":"code"},n?hn(e.placeholder):t)},propsFrom:r=>({...W(r),placeholder:"",as:r.localName})},Ie={type:"link",volatile:N("link","rel","hreflang"),ownsChildren:!0,render(r,e){let t=r.item,n=t?t.text||t.href:e.placeholder;return E("a",{...I(e.attributes),class:e.className,itemprop:e.itemProp,href:t?t.href:e.placeholderHref??"#",rel:t?.rel||void 0,hreflang:t?.lang||void 0,...$("link",r,!t)},e.textItemProp?E("span",{itemprop:e.textItemProp},n):n)},propsFrom:r=>({...W(r),placeholder:"",textItemProp:r.querySelector(":scope > span[itemprop]")?.getAttribute("itemprop")??void 0})},Cn={type:"link",volatile:Ie.volatile,ownsChildren:!1,render(r,e){let t=Ie.render(r,{...e,placeholder:""});return t.attrs["data-link-wraps"]="",t.children=[],t},propsFrom:r=>W(r)},qi="768px",Wi="1024px",On={type:"image",volatile:N("image"),ownsChildren:!0,render(r,e){let t=r.item,n={...I(e.attributes),class:e.className,...$("image",r,!t?.src),"data-image-priority":e.priority?"":void 0,"data-image-alt":e.placeholderAlt,"data-image-item-prop":e.itemProp,"data-image-img-class":e.imgClassName};return t?.src?E("picture",n,...t.largeSrc?[E("source",{media:`(min-width: ${Wi})`,srcset:t.largeSrc})]:[],...t.mediumSrc?[E("source",{media:`(min-width: ${qi})`,srcset:t.mediumSrc})]:[],E("img",{src:t.src,alt:t.altText??e.placeholderAlt??"",loading:e.priority?"eager":"lazy",decoding:"async",fetchpriority:e.priority?"high":void 0,itemprop:e.itemProp,class:e.imgClassName})):E("picture",n)},propsFrom:r=>({className:r.getAttribute("class")??void 0,priority:r.hasAttribute("data-image-priority"),itemProp:r.getAttribute("data-image-item-prop")??void 0,imgClassName:r.getAttribute("data-image-img-class")??void 0,placeholderAlt:r.getAttribute("data-image-alt")??void 0})};function Yi(r){return{"data-content-row":String(r)}}var Mn={type:"text",volatile:N("text","data-section"),ownsChildren:!1,render(r,e){let t=r.item?.value.trim();return E(e.as??"section",{...I(e.attributes),class:e.className,...$("text",r,!t),"data-section":t||e.placeholder})},propsFrom:r=>({className:r.getAttribute("class")??void 0,placeholder:r.getAttribute("data-section")??"",as:r.localName})};var Ji=/<\/?[a-z!][^>]*>/i,In={type:"text",label:"Text",attribute:"text",entityArray:"texts",endpoint:w.TEXT,historyEndpoint:w.TEXT_HISTORY,surface:"inline",valueKeys:["value"],component:r=>r.localName==="meta"?vn:r.hasAttribute("data-section")?Mn:r.getAttribute("data-text-layout")==="code"?An:Zi(r.getAttribute("data-text-layout")==="paragraphs"?fn:wt),find:(r,e,t)=>r.text(e,t),defaults:()=>({value:""}),read:r=>({value:oe(r)}),form:{fields:[{key:"value",label:"Text",kind:"textarea"}],toForm:r=>({value:r.value}),fromForm:r=>({value:typeof r.value=="string"?r.value:""})},fromPlaceholder:r=>r.localName==="meta"?{value:r.getAttribute("content")??""}:r.hasAttribute("data-section")?{value:r.getAttribute("data-section")??""}:r.getAttribute("data-text-layout")==="paragraphs"?{value:[...r.querySelectorAll(":scope > p")].map(e=>oe(e)).join(`
|
|
3
4
|
|
|
4
|
-
`)}:{value:
|
|
5
|
-
`:e+=ie(t);return e}var O=r=>typeof r=="string"?r:"";function ln(r,e,t,n,i,s){return{type:r,label:e,attribute:r,entityArray:r==="markdown"?"markdowns":"templates",endpoint:t,historyEndpoint:n,surface:r==="markdown"?"inline":"panel",valueKeys:["value"],renderedByView:!0,component:()=>i,...r==="markdown"?{read:o=>({value:ie(o)})}:{},fromPlaceholder:o=>({value:(o.textContent??"").trim()}),find:s,defaults:()=>({value:""}),form:{fields:[{key:"value",label:r==="markdown"?"Markdown source":"Velocity template source",kind:"code"}],toForm:o=>({value:o.value}),fromForm:o=>({value:O(o.value)}),describe:()=>r==="markdown"?"The page shows the rendered result after you send.":"Templates can show other items. The page shows the result after you send."},validate:()=>[]}}var cn=ln("markdown","Markdown",w.MARKDOWN,w.MARKDOWN_HISTORY,jt,(r,e,t)=>r.markdown(e,t)),un=ln("template","Template",w.TEMPLATE,w.TEMPLATE_HISTORY,qt,(r,e,t)=>r.template(e,t)),hn={type:"json",label:"JSON",attribute:"json",entityArray:"jsons",endpoint:w.JSON,historyEndpoint:w.JSON_HISTORY,surface:"panel",valueKeys:["value"],find:(r,e,t)=>r.json(e,t),defaults:()=>({value:{}}),form:{fields:[{key:"value",label:"JSON object",kind:"code"}],toForm:r=>({value:JSON.stringify(r.value??{},null,2)}),fromForm:r=>{try{let e=JSON.parse(O(r.value));return typeof e!="object"||e===null||Array.isArray(e)?'The value must be a JSON object, like {"key": "value"}.':{value:e}}catch(e){return`This is not valid JSON: ${e instanceof Error?e.message:String(e)}`}}},validate:()=>[]},pn={type:"boolean",label:"Switch",attribute:"boolean",entityArray:"booleans",endpoint:w.BOOLEAN,historyEndpoint:w.BOOLEAN_HISTORY,surface:"popover",valueKeys:["value"],component:()=>Qt,fromPlaceholder:r=>({value:r.getAttribute("data-boolean-value")==="true"}),find:(r,e,t)=>r.boolean(e,t),defaults:()=>({value:!1}),form:{fields:[{key:"value",label:"On",kind:"checkbox"}],toForm:r=>({value:r.value}),fromForm:r=>({value:r.value===!0})},validate:()=>[]};function ki(r){if(!/^\s*-?\d+\s*$/.test(r))return;let e=Number(r);return Number.isSafeInteger(e)?e:void 0}var mn={type:"long",label:"Whole number",attribute:"long",entityArray:"longs",endpoint:w.LONG,historyEndpoint:w.LONG_HISTORY,surface:"popover",valueKeys:["value"],component:()=>Jt,find:(r,e,t)=>r.long(e,t),defaults:()=>({value:0}),form:{fields:[{key:"value",label:"Value",kind:"integer"}],toForm:r=>({value:String(r.value)}),fromForm:r=>{let e=ki(O(r.value));return e===void 0?"Enter a whole number.":{value:e}}},validate:()=>[]};function ut(r){if(!/^\s*-?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?\s*$/i.test(r))return;let e=Number(r);return Number.isFinite(e)?e:void 0}var fn={type:"double",label:"Number",attribute:"double",entityArray:"doubles",endpoint:w.DOUBLE,historyEndpoint:w.DOUBLE_HISTORY,surface:"popover",valueKeys:["value"],component:()=>Zt,find:(r,e,t)=>r.double(e,t),defaults:()=>({value:0}),form:{fields:[{key:"value",label:"Value",kind:"decimal"}],toForm:r=>({value:String(r.value)}),fromForm:r=>{let e=ut(O(r.value));return e===void 0?"Enter a number.":{value:e}}},validate:()=>[]};function xi(r){let e=C(r);return Number.isNaN(e)?"":new Date(e-new Date(e).getTimezoneOffset()*6e4).toISOString().slice(0,16)}function an(r){if(!/^\d{4}-\d\d-\d\dT\d\d:\d\d(:\d\d)?$/.test(r))return;let e=new Date(r).getTime();return Number.isNaN(e)?void 0:new Date(e).toISOString().replace("Z","")}var vn={type:"dateTime",label:"Date and time",attribute:"datetime",entityArray:"dateTimes",endpoint:w.DATE_TIME,historyEndpoint:w.DATE_TIME_HISTORY,surface:"popover",valueKeys:["value"],component:()=>Xt,find:(r,e,t)=>r.date(e,t),defaults:()=>({value:new Date().toISOString().replace("Z","")}),form:{fields:[{key:"value",label:"Date and time (your local time)",kind:"datetime"}],toForm:r=>({value:xi(r.value)}),fromForm:r=>{let e=an(O(r.value));return e===void 0?"Enter a date and time.":{value:e}},describe:r=>{let e=an(O(r.value));return e?`Stored as ${e.slice(0,16).replace("T"," ")} UTC.`:""}},validate:()=>[]},yn={type:"latLong",label:"Location",attribute:"latlong",entityArray:"latLongs",endpoint:w.LAT_LONG,historyEndpoint:w.LAT_LONG_HISTORY,surface:"popover",valueKeys:["latitude","longitude"],component:()=>en,find:(r,e,t)=>r.latLong(e,t),defaults:()=>({latitude:0,longitude:0}),form:{fields:[{key:"latitude",label:"Latitude",kind:"decimal"},{key:"longitude",label:"Longitude",kind:"decimal"}],toForm:r=>({latitude:String(r.latitude),longitude:String(r.longitude)}),fromForm:r=>{let e=ut(O(r.latitude)),t=ut(O(r.longitude));return e===void 0||Math.abs(e)>90?"Latitude must be a number from -90 to 90.":t===void 0||Math.abs(t)>180?"Longitude must be a number from -180 to 180.":{latitude:e,longitude:t}}},validate:()=>[]};function dn(r){if(!/^[A-Z]{3}$/.test(r))return!1;try{return new Intl.NumberFormat("en",{style:"currency",currency:r}),!0}catch{return!1}}var gn={type:"money",label:"Money",attribute:"money",entityArray:"money",endpoint:w.MONEY,historyEndpoint:w.MONEY_HISTORY,surface:"popover",valueKeys:["currencyCode","unitValue"],derived:["formattedValue","currencySymbol"],component:()=>Wt,find:(r,e,t)=>r.money(e,t),defaults:()=>({currencyCode:"GBP",unitValue:0}),form:{fields:[{key:"currencyCode",label:"Currency",kind:"currency"},{key:"amount",label:"Amount",kind:"text"}],toForm:r=>({currencyCode:r.currencyCode,amount:Ce(r.unitValue,he(r.currencyCode))}),fromForm:r=>{let e=O(r.currencyCode).trim().toUpperCase();if(!dn(e))return"Enter a three-letter currency code, like GBP or JPY.";let t=he(e),n=lt(O(r.amount),t);return n===void 0?t===0?`${e} has no minor units. Enter a whole amount.`:`Enter an amount with at most ${t} decimal places, like ${Ce(1250,t)}.`:{currencyCode:e,unitValue:n}},describe:r=>{let e=O(r.currencyCode).trim().toUpperCase();if(!dn(e))return"";let t=lt(O(r.amount),he(e));return t===void 0?"":`Stored as ${t} in the smallest unit of ${e}.`}},validate:()=>[]},V=[{size:"DEFAULT",field:"src",label:"Default file"},{size:"MEDIUM",field:"mediumSrc",label:"Medium file (from 768px wide)"},{size:"LARGE",field:"largeSrc",label:"Large file (from 1024px wide)"}],bn={type:"image",label:"Image",attribute:"image",entityArray:"images",endpoint:w.IMAGE,historyEndpoint:w.IMAGE_HISTORY,surface:"popover",valueKeys:["altText","src","mediumSrc","largeSrc"],carried:["src","mediumSrc","largeSrc"],component:()=>nn,fromPlaceholder:r=>({altText:r.querySelector("img")?.alt??""}),find:(r,e,t)=>r.image(e,t),defaults:()=>({altText:""}),form:{fields:[{key:"altText",label:"Alt text",kind:"text"},...V.map(r=>({key:r.size,label:r.label,kind:"file"}))],toForm:r=>({altText:r.altText??"",...Object.fromEntries(V.flatMap(e=>[[e.size,""],[`${e.size}:current`,String(r[e.field]??"")]]))}),fromForm:r=>({altText:O(r.altText)}),describe:r=>{let e=V.filter(i=>O(r[i.size])!=="");if(e.length===0)return"Saving keeps the current files.";let t=V.filter(i=>!e.includes(i)&&O(r[`${i.size}:current`])!==""),n=`Saving creates a new version, then uploads ${e.map(i=>i.label.toLowerCase().split(" (")[0]).join(", ")}.`;return e.some(i=>i.size==="DEFAULT")&&t.length>0?`${n} The ${t.map(i=>i.size.toLowerCase()).join(" and ")} file still shows the previous picture; choose new ones too if it changed.`:n}},validate:({altText:r})=>r?[]:[{level:"warning",message:"Images need alt text unless they are decorative."}]},wn={type:"link",label:"Link",attribute:"link",entityArray:"links",endpoint:w.LINK,historyEndpoint:w.LINK_HISTORY,surface:"popover",valueKeys:["href","text","rel","lang"],component:()=>tn,fromPlaceholder:r=>{let e=r.getAttribute("href"),t=(r.textContent??"").trim();return{href:e&&e!=="#"?e:"",...t?{text:t}:{}}},find:(r,e,t)=>r.link(e,t),defaults:()=>({href:"",text:""}),form:{fields:[{key:"text",label:"Text",kind:"text"},{key:"href",label:"Address",kind:"url"},{key:"rel",label:"Relationship (rel), e.g. nofollow",kind:"text"},{key:"lang",label:"Language of the target, e.g. en",kind:"text"}],toForm:r=>({text:r.text??"",href:r.href,rel:r.rel??"",lang:r.lang??""}),fromForm:r=>{let e=O(r.href).trim();if(!e)return"Enter the address the link goes to.";if(e.length>2048)return"The address can be at most 2048 characters.";let t={href:e};for(let n of["text","rel","lang"]){let i=O(r[n]).trim();i&&(t[n]=i)}return t}},validate:({href:r})=>/^\s*javascript:/i.test(r)?[{level:"error",message:"Links cannot run scripts."}]:[]},En={type:"reference",label:"Reference",attribute:"reference",entityArray:"references",endpoint:w.REFERENCE,historyEndpoint:w.REFERENCE_HISTORY,surface:"popover",valueKeys:["entityReference"],find:(r,e,t)=>r.reference(e,t),defaults:()=>({entityReference:{urn:""}}),form:{fields:[{key:"urn",label:"Entity referred to",kind:"entity"}],toForm:r=>({urn:r.entityReference?.urn??""}),fromForm:r=>{let e=O(r.urn).trim();return/^[0-9a-f-]{36}$/i.test(e)?{entityReference:{urn:e}}:"Choose the entity this refers to."}},validate:()=>[]};var kn=[250,500,1e3,2e3,4e3],Li=3e4,Ie=class{ctx;view;saving;editing;constructor(e,t,n,i){this.ctx=e,this.view=t,this.saving=n,this.editing=i}async save(e,t){let n=pt(t).find(g=>g.level==="error");if(n)return this.ctx.popover.setError(n.message);let i=await Ti(t,window.baackEditorConfig?.imageWidths),{pending:s,popover:o,store:a,feedback:d}=this.ctx,l=e.entry,u=l.form.fromForm(o.values());if(typeof u=="string")return o.setError(u);let h=e.urn?a.get(e.urn)?.item:void 0,f=ye(l,h,u);for(let g of i.keys())delete f[V.find(y=>y.size===g).field];e.urn?s.set({kind:"edit",type:l.type,urn:e.urn,entityUrn:e.entityUrn,name:e.name,sortOrder:e.sortOrder,value:f}):s.set({kind:"create",type:l.type,entityUrn:e.entityUrn,name:e.name,sortOrder:e.sortOrder,value:f});let p=e.urn?s.getEdit(e.urn):s.getCreate($({...e,type:l.type}));o.setSending(!0),o.setError("");let v;try{v=await this.saving().commit(p)}catch(g){o.setSending(!1);let y=await d.describe(g,"save this image");o.setError(y.message,y.debug);return}o.setSending(!1);let m=new Map([...i].map(([g,y])=>[g,URL.createObjectURL(y)]));this.preview(e.entityUrn,v,m),await this.upload(e,v,i,m)}async upload(e,t,n,i){let{transport:s,feedback:o,toolbar:a}=this.ctx;this.editing().close();let d=c("div","simple-form");d.setAttribute("aria-label","Image upload");let l=new Map;d.append(c("div","title",`Uploading to a new version of ${e.name}`));for(let[b,k]of n){let A=c("p","hint",`${xn(b)}: ${k.name}: uploading\u2026`);l.set(b,A),d.append(A)}let u=this.ctx.panels.show(d,{entityUrn:e.entityUrn,focus:!1}),h=(b,k,A=!1)=>{let K=l.get(b);K.textContent=`${xn(b)}: ${n.get(b).name}: ${k}`,K.className=A?"error":"hint"},f=await Promise.allSettled([...n].map(([b,k])=>s.uploadImageFile(t.urn,b,k))),p=f.flatMap(b=>b.status==="fulfilled"?[b.value]:[]),v=new Map;for(let[b,k]of f.entries()){let[A,K]=[...n][b];k.status==="rejected"?(v.set(A,K),h(A,(await o.describe(k.reason,"upload this file")).message,!0)):h(A,"uploaded; waiting for the CDN\u2026")}let m=[...n.keys()].filter(b=>!v.has(b)),g=b=>V.find(k=>k.size===b).field,x=m.every(b=>p.some(k=>k[g(b)]))||await this.waitForAddresses(e.entry,t.urn,m);for(let b of m)h(b,x?"done":"still processing; it appears when the CDN has placed it.");if(await this.view.refresh(e.entityUrn),v.size>0){this.preview(e.entityUrn,t,new Map([...i].filter(([A])=>v.has(A))));let b=c("button","primary","Retry failed uploads");b.type="button",b.addEventListener("click",()=>{this.retry(e,t,v,i)});let k=c("div","actions");k.append(b),d.append(c("p","message","Some files were not uploaded. The new version keeps the others."),k);return}for(let b of i.values())URL.revokeObjectURL(b);u.close(),a.showMessage(`Uploaded ${n.size} ${n.size===1?"file":"files"} to a new version of ${e.name}.`,!0)}async retry(e,t,n,i){let s=await this.ctx.transport.read(e.entry,t.urn),o=new Map([...n].filter(([a])=>!s[V.find(d=>d.size===a).field]));await this.upload(e,t,o,i)}async waitForAddresses(e,t,n){if(n.length===0)return!0;let i=Date.now();for(let s=0;Date.now()-i<Li;s+=1){let o=await this.ctx.transport.read(e,t);if(n.every(a=>o[V.find(d=>d.size===a).field]))return this.ctx.store.remember(this.ctx.store.get(t)?.entityUrn??"",e,o),!0;await new Promise(a=>setTimeout(a,kn[Math.min(s,kn.length-1)]))}return!1}preview(e,t,n){let i={...this.ctx.store.get(t.urn)?.item??t};for(let[o,a]of n)i[V.find(d=>d.size===o).field]=a;let s=this.ctx.entry("image");for(let o of this.ctx.discovery.all())o.entry!==s||this.ctx.store.entityFor(o.scope)!==e||o.element.getAttribute(P(s))!==t.urn&&!(o.name===t.name&&o.sortOrder===t.sortOrder)||(this.ctx.live.render(o,i),N(o.element,"changed"))}};function xn(r){return V.find(e=>e.size===r).label.split(" (")[0]}async function Ti(r,e){let t=r.get("DEFAULT");if(!e||!t||r.size>1)return r;let n=new Map(r);for(let i of["MEDIUM","LARGE"]){let s=e[i];s&&n.set(i,await Si(t,s,i))}return n}async function Si(r,e,t){try{let n=await createImageBitmap(r);if(n.width<=e)return r;let i=Math.round(n.height*e/n.width),s=document.createElement("canvas");s.width=e,s.height=i,s.getContext("2d").drawImage(n,0,0,e,i);let o=r.type==="image/png"||r.type==="image/webp"?r.type:"image/jpeg",a=await new Promise((l,u)=>s.toBlob(h=>h?l(h):u(new Error("Could not scale the image")),o,.9)),d=r.name.replace(/(\.[^.]+)?$/,`-${t.toLowerCase()}$1`);return new File([a],d,{type:o})}catch{return r}}var Ai=["image/apng","image/avif","image/gif","image/jpeg","image/png","image/svg+xml","image/webp"],ht=1024*1024;function pt(r){let e=window.baackEditorConfig?.maxImageBytes??10*ht,t=window.baackEditorConfig?.warnImageBytes??2*ht,n=s=>`${(s/ht).toFixed(1)} MB`,i=[];for(let s of r.values())Ai.includes(s.type)?s.size>e?i.push({level:"error",message:`${s.name} is ${n(s.size)}; the limit is ${n(e)}. Use a smaller file.`}):s.size>t&&i.push({level:"warning",message:`${s.name} is ${n(s.size)}, large for the web. Compressing it will make the page faster.`}):i.push({level:"error",message:`${s.name} is not an image type Baack accepts: JPEG, PNG, APNG, GIF, WebP, AVIF or SVG.`});return i}var Ln="data-content-live",Tn="baack:item-shown",Sn="baack:live-request";function G(r){return r.closest(`[${Ln}]`)!==null}var $e=class{store;shown=new Map;previews=new Set;constructor(e){this.store=e,document.addEventListener(Sn,this.onRequest)}render(e,t){if(!G(e.element)){$t(e.entry,e.element,e,t);return}let n={...this.slot(e),item:t};this.previews.has(J(n))||(this.shown.set(J(n),n),Pe(n),t.urn&&e.element.setAttribute(P(e.entry),t.urn))}restore(e){if(!G(e.element))return!1;let t={...this.slot(e),restore:!0};return this.previews.has(J(t))||(this.shown.delete(J(t)),Pe(t)),!0}showAt(e,t,n){let i=n?{...this.slot(e),sortOrder:t,item:n}:{...this.slot(e),sortOrder:t,restore:!0};n?(this.shown.set(J(i),i),this.previews.add(J(i))):(this.shown.delete(J(i)),this.previews.delete(J(i))),Pe(i)}endPreviews(){this.previews.clear()}slot(e){return{entityUrn:this.store.entityFor(e.scope)??e.scope,type:e.entry.type,name:e.name,sortOrder:e.sortOrder}}onRequest=e=>{for(let t of this.shown.values())t.entityUrn===e.detail.entityUrn&&Pe(t)}};function J(r){return`${r.entityUrn}\0${r.type}\0${r.name}\0${r.sortOrder}`}function Pe(r){document.dispatchEvent(new CustomEvent(Tn,{detail:r}))}var Oi=/Mac|iPhone|iPad/.test(navigator.userAgent),He=class{element;sendsOnEnter;host;callbacks;savedEditable;savedWhiteSpace;savedChildren;constructor(e,t,n,i){this.element=e,this.host=n,this.callbacks=i,this.sendsOnEnter=getComputedStyle(e).display.startsWith("inline")&&e.getAttribute("data-text-layout")!=="paragraphs",this.savedEditable=e.getAttribute("contenteditable"),this.savedWhiteSpace=e.style.whiteSpace,this.savedChildren=G(e)?[...e.childNodes]:void 0,e.textContent=t,Ae(e),e.setAttribute("contenteditable","plaintext-only"),e.style.whiteSpace="pre-wrap",e.addEventListener("input",this.onInput),e.addEventListener("keydown",this.onKeyDown),e.addEventListener("blur",this.onBlur),e.focus(),Mi(e)}get hint(){let e=Oi?"\u2318":"Ctrl";return this.sendsOnEnter?"Enter to save \xB7 Esc to revert":`${e}+Enter to save \xB7 Esc to revert`}close(){this.element.removeEventListener("input",this.onInput),this.element.removeEventListener("keydown",this.onKeyDown),this.element.removeEventListener("blur",this.onBlur),this.savedEditable===null?this.element.removeAttribute("contenteditable"):this.element.setAttribute("contenteditable",this.savedEditable),this.element.style.whiteSpace=this.savedWhiteSpace,this.element.getAttribute("style")||this.element.removeAttribute("style"),this.savedChildren&&this.element.replaceChildren(...this.savedChildren)}onInput=()=>{Ae(this.element),this.callbacks.input()};onKeyDown=e=>{e.key==="Escape"?(e.preventDefault(),this.callbacks.revert()):e.key==="Enter"&&(e.metaKey||e.ctrlKey||this.sendsOnEnter&&!e.shiftKey)&&(e.preventDefault(),this.callbacks.send())};onBlur=e=>{e.relatedTarget!==this.host.element&&this.callbacks.blurred()}};function Mi(r){let e=window.getSelection();if(!e||e.rangeCount>0&&r.contains(e.getRangeAt(0).commonAncestorContainer))return;let t=document.createRange();t.selectNodeContents(r),t.collapse(!1),e.removeAllRanges(),e.addRange(t)}var Be=class{ctx;view;save;active;constructor(e,t,n){this.ctx=e,this.view=t,this.save=n}get current(){return this.active}attach(){document.addEventListener("dblclick",this.onDoubleClick,!0),document.addEventListener("click",this.onClick,!0)}detach(){document.removeEventListener("dblclick",this.onDoubleClick,!0),document.removeEventListener("click",this.onClick,!0)}onDoubleClick=e=>{let{discovery:t,toolbar:n}=this.ctx,i=t.closest(e.target);if(!i||this.active?.target.binding?.element===i)return;let s=t.of(i)[0];if(!s)return;e.preventDefault();let o=this.targetFor(s);if(!o){n.showMessage(`The content for "${s.name}" has not loaded.`);return}this.open(o)};onClick=e=>{this.ctx.discovery.closest(e.target)&&e.preventDefault()};onPointerDown=e=>{let t=e.composedPath(),n=this.active?.target.binding?.element??this.active?.target.anchor;!this.active||t.includes(this.ctx.host.element)||n&&t.includes(n)||this.close()};targetFor(e){let{store:t}=this.ctx,n=t.entityFor(e.scope);if(!n)return;let i=e.element.getAttribute(P(e.entry))??void 0;return{entityUrn:n,entry:e.entry,name:e.name,sortOrder:e.sortOrder,urn:i&&t.get(i)?i:void 0,anchor:e.element,binding:e}}open(e){this.view.stopPreview(e);let t=e.binding&&e.binding.element.getClientRects().length>0,n=e.binding?e.entry.component?.(e.binding.element).ownsChildren!==!1:!1;if(e.urn&&e.entry.surface==="inline"&&e.binding&&t&&n)this.openInline(e);else{let i=!e.urn&&e.binding?e.entry.fromPlaceholder?.(e.binding.element):void 0;this.openForm(t?e:{...e,binding:void 0,anchor:e.anchor},i)}}async openInline(e){this.close();let{store:t,pending:n,host:i,popover:s}=this.ctx,{entry:o}=e,a=e.binding.element,d=t.get(e.urn),l=o.renderedByView?await this.baseValue(e):M(o,d.item);if(!l||this.active||!this.view.isEditing||!a.isConnected)return;let u=n.getEdit(e.urn)?.value??l,h=new He(a,String(u.value??""),i,{input:()=>this.setPending(e,o.read(a)),send:()=>{this.save(e)},revert:()=>this.revert(e),blurred:()=>this.close()});this.active={target:e,session:h},N(a,"editing"),s.show(a,o.label,`${e.name} #${e.sortOrder}`,h.hint,{send:()=>{this.save(e)},revert:()=>this.revert(e)}),s.setIssues(o.validate(o.read(a))),this.offerHistory(e)}offerHistory(e){let{hooks:t}=this.ctx;this.ctx.popover.setNameAction(()=>t.showItem(e));let n=e.urn;if(!n||e.fromVersion){this.ctx.popover.setExtras([]);return}let i=e.binding,s=[{label:"History",icon:"history",run:()=>{this.close(),t.openHistory({entityUrn:e.entityUrn,entry:e.entry,name:e.name,sortOrder:e.sortOrder,urn:n})}}];i&&t.canReorder(i)&&s.push({label:"Move up",icon:"arrow-up",menu:!0,run:()=>t.moveBy(i,-1)},{label:"Move down",icon:"arrow-down",menu:!0,run:()=>t.moveBy(i,1)},{label:"Reorder\u2026",icon:"list-ordered",menu:!0,run:()=>t.reorder(i)}),s.push({label:"Move or rename\u2026",icon:"pencil-line",menu:!0,run:()=>t.relocate(e)}),this.ctx.popover.setExtras(s)}async openForm(e,t){this.close();let{store:n,pending:i,popover:s,toolbar:o}=this.ctx,{entry:a}=e,d=a.form;if(!d)return;let l;if(e.urn){let h=await this.baseValue(e);if(!h)return;l=(e.fromVersion?void 0:i.getEdit(e.urn)?.value)??h}else{if(n.itemAt(e.entityUrn,a,e.name,e.sortOrder)){o.showMessage(`An item already exists at ${e.name} #${e.sortOrder}.`);return}l=i.getCreate($({...e,type:a.type}))?.value??t??(e.binding?a.fromPlaceholder?.(e.binding.element):void 0)??a.defaults()}this.active={target:e,session:void 0},e.binding&&N(e.binding.element,"editing");let u=d.toForm(l);s.showForm(e.anchor,e.fromVersion?`${a.label}, from an older version`:e.urn?a.label:`New ${a.label.toLowerCase()}`,`${e.name} #${e.sortOrder}`,d.fields,u,{input:h=>this.onFormInput(e,h),send:()=>{this.save(e)},revert:()=>this.revert(e)},a.surface==="panel"),s.setDescription(this.describeForm(e,u)),s.setIssues(a.validate(l)),this.offerHistory(e),e.fromVersion&&this.setPending(e,l),document.addEventListener("pointerdown",this.onPointerDown,!0)}describeForm(e,t){let n=[e.entry.form?.describe?.(t)??""];return!e.urn&&S(this.ctx.store.view(e.entityUrn)?.status)&&n.push("This content is published, so a new item is live as soon as it is saved."),n.filter(Boolean).join(" ")}async baseValue(e){let{store:t,sources:n,transport:i,feedback:s}=this.ctx,o=e.urn,a=t.get(o)??t.itemAt(e.entityUrn,e.entry,e.name,e.sortOrder);if(!(!a||a.item.urn!==o)){if(!e.entry.renderedByView)return M(e.entry,a.item);try{let d=n.get(o)??M(e.entry,await i.read(e.entry,o));return n.set(o,d),d}catch(d){s.report(d,"load the source",()=>{this.openForm(e)});return}}}close(){let e=this.active;if(!e)return;this.active=void 0,document.removeEventListener("pointerdown",this.onPointerDown,!0),e.session?.close(),this.ctx.popover.hide();let t=e.target.binding;this.view.isEditing&&t?.element.isConnected&&this.view.show(t)}onFormInput(e,t){let{popover:n}=this.ctx,i=e.entry.form;if(!i)return;n.setDescription(this.describeForm(e,t));let s=i.fromForm(t);if(typeof s=="string"){n.setError(s),n.setIssues([]);return}n.setError("");let o=e.entry.type==="image"?pt(n.files()):[];n.setIssues([...e.entry.validate(s),...o]),this.setPending(e,s)}setPending(e,t){let{store:n,sources:i,pending:s,popover:o}=this.ctx,{entry:a}=e,d=t;if(e.urn){let l=n.get(e.urn)??n.itemAt(e.entityUrn,a,e.name,e.sortOrder);d=ye(a,l?.item,t);let u=e.fromVersion?n.itemAt(e.entityUrn,a,e.name,e.sortOrder):l,h=a.renderedByView?i.get(u?.item.urn??e.urn):u?.item;h&&ge(a,d,h)?s.clear(e.urn):s.set({kind:"edit",type:a.type,urn:e.urn,entityUrn:e.entityUrn,name:e.name,sortOrder:e.sortOrder,value:d,...e.fromVersion?{fromVersion:!0}:{}})}else s.set({kind:"create",type:a.type,entityUrn:e.entityUrn,name:e.name,sortOrder:e.sortOrder,value:d});this.view.reshow(e),e.entry.surface==="inline"&&this.active?.session&&o.setIssues(a.validate(d))}revert(e){this.ctx.pending.clear(e.urn??$({...e,type:e.entry.type})),this.close(),this.view.reshow(e)}};function re(r,e,t){if(R(r)){let n=Ii(r);return n===void 0?An(r,e,t):{...An(r,e,t),debug:n}}return Ci(r,e)}function An(r,e,t){if(r.isUnauthorized||r.isNotFound&&t===!1)return{kind:"unauthorized",message:`Your session has ended. Log in again to ${e}. Your changes are kept.`};if(r.isForbidden)return{kind:"forbidden",message:`You don't have permission to ${e}.`};if(r.isNotFound)return{kind:"not-found",message:`This item no longer exists, or you don't have permission to ${e}.`};if(r.isConflict)return{kind:"conflict",message:"Someone else changed this since you opened it. Reload to see their version."};let{detail:n}=r;return{kind:"failed",message:`Couldn't ${e} (HTTP ${r.status})${n?`: ${n.replace(/\.$/,"")}`:""}. Try again.`}}function Ci(r,e){if(r instanceof Q)return{kind:"not-live",message:"This content is not published yet, so it has no live version to show. Show the latest drafts to edit it."};if(r instanceof le){let{language:t}=r.received;return{kind:"mismatch",message:`Couldn't ${e}: Baack returned a different language version (${t}) instead of the content on this page, so it can't be edited here. Reload the page and try again.`}}return r instanceof TypeError?{kind:"network",message:`Couldn't reach Baack to ${e}. Check your connection and try again.`}:{kind:"failed",message:`Couldn't ${e}: ${r instanceof Error?r.message:String(r)}`}}function Ii(r){let e=r.json();if(e===void 0)return;let t=s=>{try{return JSON.stringify(JSON.parse(s),null,2)}catch{return s}},n=(()=>{try{return new URL(r.url).pathname}catch{return r.url}})();return`${`Request: ${r.method} ${n}${r.requestBody?`
|
|
5
|
+
`)}:{value:oe(r)},validate:({value:r})=>Ji.test(r)?[{level:"warning",message:"This looks like HTML. Text items are plain text, so the page shows the tags as typed, and apps on other platforms will too."}]:[]};function Zi(r){return{...r,render(e,t){let n=r.render(e,{...t,unsafeLiteral:!1});return t.unsafeLiteral&&(n.attrs["data-text-unsafe-literal"]=""),n}}}function oe(r){let e="";for(let t of r.childNodes)t.nodeType===Node.TEXT_NODE?e+=t.nodeValue??"":t.nodeName==="BR"?e+=`
|
|
6
|
+
`:e+=oe(t);return e}var C=r=>typeof r=="string"?r:"";function Hn(r,e,t,n,i,s){return{type:r,label:e,attribute:r,entityArray:r==="markdown"?"markdowns":"templates",endpoint:t,historyEndpoint:n,surface:r==="markdown"?"inline":"panel",valueKeys:["value"],renderedByView:!0,component:()=>i,...r==="markdown"?{read:o=>({value:oe(o)})}:{},fromPlaceholder:o=>o.hasAttribute(`data-${r}-wraps`)?void 0:{value:(o.textContent??"").trim()},showsPageRendering:o=>o.hasAttribute(`data-${r}-wraps`),find:s,defaults:()=>({value:""}),form:{fields:[{key:"value",label:r==="markdown"?"Markdown source":"Velocity template source",kind:"code"}],toForm:o=>({value:o.value}),fromForm:o=>({value:C(o.value)}),describe:()=>r==="markdown"?"The page shows the rendered result after you send.":"Templates can show other items. The page shows the result after you send."},validate:()=>[]}}var Nn=Hn("markdown","Markdown",w.MARKDOWN,w.MARKDOWN_HISTORY,yn,(r,e,t)=>r.markdown(e,t)),Rn=Hn("template","Template",w.TEMPLATE,w.TEMPLATE_HISTORY,bn,(r,e,t)=>r.template(e,t)),Dn={type:"json",label:"JSON",attribute:"json",entityArray:"jsons",endpoint:w.JSON,historyEndpoint:w.JSON_HISTORY,surface:"panel",valueKeys:["value"],find:(r,e,t)=>r.json(e,t),defaults:()=>({value:{}}),form:{fields:[{key:"value",label:"JSON object",kind:"code"}],toForm:r=>({value:JSON.stringify(r.value??{},null,2)}),fromForm:r=>{try{let e=JSON.parse(C(r.value));return typeof e!="object"||e===null||Array.isArray(e)?'The value must be a JSON object, like {"key": "value"}.':{value:e}}catch(e){return`This is not valid JSON: ${e instanceof Error?e.message:String(e)}`}}},validate:()=>[]},Fn={type:"boolean",label:"Switch",attribute:"boolean",entityArray:"booleans",endpoint:w.BOOLEAN,historyEndpoint:w.BOOLEAN_HISTORY,surface:"popover",valueKeys:["value"],component:()=>Ln,fromPlaceholder:r=>({value:r.getAttribute("data-boolean-value")==="true"}),find:(r,e,t)=>r.boolean(e,t),defaults:()=>({value:!1}),form:{fields:[{key:"value",label:"On",kind:"checkbox"}],toForm:r=>({value:r.value}),fromForm:r=>({value:r.value===!0})},validate:()=>[]};function Xi(r){if(!/^\s*-?\d+\s*$/.test(r))return;let e=Number(r);return Number.isSafeInteger(e)?e:void 0}var Un={type:"long",label:"Whole number",attribute:"long",entityArray:"longs",endpoint:w.LONG,historyEndpoint:w.LONG_HISTORY,surface:"popover",valueKeys:["value"],component:()=>kn,find:(r,e,t)=>r.long(e,t),defaults:()=>({value:0}),form:{fields:[{key:"value",label:"Value",kind:"integer"}],toForm:r=>({value:String(r.value)}),fromForm:r=>{let e=Xi(C(r.value));return e===void 0?"Enter a whole number.":{value:e}}},validate:()=>[]};function Et(r){if(!/^\s*-?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?\s*$/i.test(r))return;let e=Number(r);return Number.isFinite(e)?e:void 0}var Vn={type:"double",label:"Number",attribute:"double",entityArray:"doubles",endpoint:w.DOUBLE,historyEndpoint:w.DOUBLE_HISTORY,surface:"popover",valueKeys:["value"],component:()=>xn,find:(r,e,t)=>r.double(e,t),defaults:()=>({value:0}),form:{fields:[{key:"value",label:"Value",kind:"decimal"}],toForm:r=>({value:String(r.value)}),fromForm:r=>{let e=Et(C(r.value));return e===void 0?"Enter a number.":{value:e}}},validate:()=>[]};function Qi(r){let e=M(r);return Number.isNaN(e)?"":new Date(e-new Date(e).getTimezoneOffset()*6e4).toISOString().slice(0,16)}function $n(r){if(!/^\d{4}-\d\d-\d\dT\d\d:\d\d(:\d\d)?$/.test(r))return;let e=new Date(r).getTime();return Number.isNaN(e)?void 0:new Date(e).toISOString().replace("Z","")}var _n={type:"dateTime",label:"Date and time",attribute:"datetime",entityArray:"dateTimes",endpoint:w.DATE_TIME,historyEndpoint:w.DATE_TIME_HISTORY,surface:"popover",valueKeys:["value"],component:()=>Tn,find:(r,e,t)=>r.date(e,t),defaults:()=>({value:new Date().toISOString().replace("Z","")}),form:{fields:[{key:"value",label:"Date and time (your local time)",kind:"datetime"}],toForm:r=>({value:Qi(r.value)}),fromForm:r=>{let e=$n(C(r.value));return e===void 0?"Enter a date and time.":{value:e}},describe:r=>{let e=$n(C(r.value));return e?`Stored as ${e.slice(0,16).replace("T"," ")} UTC.`:""}},validate:()=>[]},Gn={type:"latLong",label:"Location",attribute:"latlong",entityArray:"latLongs",endpoint:w.LAT_LONG,historyEndpoint:w.LAT_LONG_HISTORY,surface:"popover",valueKeys:["latitude","longitude"],component:()=>Sn,find:(r,e,t)=>r.latLong(e,t),defaults:()=>({latitude:0,longitude:0}),form:{fields:[{key:"latitude",label:"Latitude",kind:"decimal"},{key:"longitude",label:"Longitude",kind:"decimal"}],toForm:r=>({latitude:String(r.latitude),longitude:String(r.longitude)}),fromForm:r=>{let e=Et(C(r.latitude)),t=Et(C(r.longitude));return e===void 0||Math.abs(e)>90?"Latitude must be a number from -90 to 90.":t===void 0||Math.abs(t)>180?"Longitude must be a number from -180 to 180.":{latitude:e,longitude:t}}},validate:()=>[]};function Bn(r){if(!/^[A-Z]{3}$/.test(r))return!1;try{return new Intl.NumberFormat("en",{style:"currency",currency:r}),!0}catch{return!1}}var zn={type:"money",label:"Money",attribute:"money",entityArray:"money",endpoint:w.MONEY,historyEndpoint:w.MONEY_HISTORY,surface:"popover",valueKeys:["currencyCode","unitValue"],derived:["formattedValue","currencySymbol"],component:()=>wn,find:(r,e,t)=>r.money(e,t),defaults:()=>({currencyCode:"GBP",unitValue:0}),form:{fields:[{key:"currencyCode",label:"Currency",kind:"currency"},{key:"amount",label:"Amount",kind:"text"}],toForm:r=>({currencyCode:r.currencyCode,amount:Pe(r.unitValue,me(r.currencyCode))}),fromForm:r=>{let e=C(r.currencyCode).trim().toUpperCase();if(!Bn(e))return"Enter a three-letter currency code, like GBP or JPY.";let t=me(e),n=bt(C(r.amount),t);return n===void 0?t===0?`${e} has no minor units. Enter a whole amount.`:`Enter an amount with at most ${t} decimal places, like ${Pe(1250,t)}.`:{currencyCode:e,unitValue:n}},describe:r=>{let e=C(r.currencyCode).trim().toUpperCase();if(!Bn(e))return"";let t=bt(C(r.amount),me(e));return t===void 0?"":`Stored as ${t} in the smallest unit of ${e}.`}},validate:()=>[]},G=[{size:"DEFAULT",field:"src",label:"Default file"},{size:"MEDIUM",field:"mediumSrc",label:"Medium file (from 768px wide)"},{size:"LARGE",field:"largeSrc",label:"Large file (from 1024px wide)"}],Kn={type:"image",label:"Image",attribute:"image",entityArray:"images",endpoint:w.IMAGE,historyEndpoint:w.IMAGE_HISTORY,surface:"popover",valueKeys:["altText","src","mediumSrc","largeSrc"],carried:["src","mediumSrc","largeSrc"],component:()=>On,fromPlaceholder:r=>({altText:r.querySelector("img")?.alt??""}),find:(r,e,t)=>r.image(e,t),defaults:()=>({altText:""}),form:{fields:[{key:"altText",label:"Alt text",kind:"text"},...G.map(r=>({key:r.size,label:r.label,kind:"file"}))],toForm:r=>({altText:r.altText??"",...Object.fromEntries(G.flatMap(e=>[[e.size,""],[`${e.size}:current`,String(r[e.field]??"")]]))}),fromForm:r=>({altText:C(r.altText)}),describe:r=>{let e=G.filter(i=>C(r[i.size])!=="");if(e.length===0)return"Saving keeps the current files.";let t=G.filter(i=>!e.includes(i)&&C(r[`${i.size}:current`])!==""),n=`Saving creates a new version, then uploads ${e.map(i=>i.label.toLowerCase().split(" (")[0]).join(", ")}.`;return e.some(i=>i.size==="DEFAULT")&&t.length>0?`${n} The ${t.map(i=>i.size.toLowerCase()).join(" and ")} file still shows the previous picture; choose new ones too if it changed.`:n}},validate:({altText:r})=>r?[]:[{level:"warning",message:"Images need alt text unless they are decorative."}]},jn={type:"link",label:"Link",attribute:"link",entityArray:"links",endpoint:w.LINK,historyEndpoint:w.LINK_HISTORY,surface:"popover",valueKeys:["href","text","rel","lang"],component:r=>r.hasAttribute("data-link-wraps")?Cn:Ie,fromPlaceholder:r=>{let e=r.getAttribute("href"),t=r.hasAttribute("data-link-wraps")?"":(r.textContent??"").trim();return{href:e&&e!=="#"?e:"",...t?{text:t}:{}}},find:(r,e,t)=>r.link(e,t),defaults:()=>({href:"",text:""}),form:{fields:[{key:"text",label:"Text",kind:"text"},{key:"href",label:"Address",kind:"url"},{key:"rel",label:"Relationship (rel), e.g. nofollow",kind:"text"},{key:"lang",label:"Language of the target, e.g. en",kind:"text"}],toForm:r=>({text:r.text??"",href:r.href,rel:r.rel??"",lang:r.lang??""}),fromForm:r=>{let e=C(r.href).trim();if(!e)return"Enter the address the link goes to.";if(e.length>2048)return"The address can be at most 2048 characters.";let t={href:e};for(let n of["text","rel","lang"]){let i=C(r[n]).trim();i&&(t[n]=i)}return t}},validate:({href:r})=>/^\s*javascript:/i.test(r)?[{level:"error",message:"Links cannot run scripts."}]:[]},qn={type:"reference",label:"Reference",attribute:"reference",entityArray:"references",endpoint:w.REFERENCE,historyEndpoint:w.REFERENCE_HISTORY,surface:"popover",valueKeys:["entityReference"],find:(r,e,t)=>r.reference(e,t),defaults:()=>({entityReference:{urn:""}}),form:{fields:[{key:"urn",label:"Entity referred to",kind:"entity"}],toForm:r=>({urn:r.entityReference?.urn??""}),fromForm:r=>{let e=C(r.urn).trim();return/^[0-9a-f-]{36}$/i.test(e)?{entityReference:{urn:e}}:"Choose the entity this refers to."}},validate:()=>[]};var Wn=[250,500,1e3,2e3,4e3],er=3e4,$e=class{ctx;view;saving;editing;constructor(e,t,n,i){this.ctx=e,this.view=t,this.saving=n,this.editing=i}async save(e,t){let n=xt(t).find(g=>g.level==="error");if(n)return this.ctx.popover.setError(n.message);let i=await tr(t,window.baackEditorConfig?.imageWidths),{pending:s,popover:o,store:a,feedback:d}=this.ctx,c=e.entry,u=c.form.fromForm(o.values());if(typeof u=="string")return o.setError(u);let h=e.urn?a.get(e.urn)?.item:void 0,v=be(c,h,u);for(let g of i.keys())delete v[G.find(y=>y.size===g).field];e.urn?s.set({kind:"edit",type:c.type,urn:e.urn,entityUrn:e.entityUrn,name:e.name,sortOrder:e.sortOrder,value:v}):s.set({kind:"create",type:c.type,entityUrn:e.entityUrn,name:e.name,sortOrder:e.sortOrder,value:v});let p=e.urn?s.getEdit(e.urn):s.getCreate(H({...e,type:c.type}));o.setSending(!0),o.setError("");let f;try{f=await this.saving().commit(p)}catch(g){o.setSending(!1);let y=await d.describe(g,"save this image");o.setError(y.message,y.debug);return}o.setSending(!1);let m=new Map([...i].map(([g,y])=>[g,URL.createObjectURL(y)]));this.preview(e.entityUrn,f,m),await this.upload(e,f,i,m)}async upload(e,t,n,i){let{transport:s,feedback:o,toolbar:a}=this.ctx;this.editing().close();let d=l("div","simple-form");d.setAttribute("aria-label","Image upload");let c=new Map;d.append(l("div","title",`Uploading to a new version of ${e.name}`));for(let[b,k]of n){let A=l("p","hint",`${Yn(b)}: ${k.name}: uploading\u2026`);c.set(b,A),d.append(A)}let u=this.ctx.panels.show(d,{entityUrn:e.entityUrn,focus:!1}),h=(b,k,A=!1)=>{let q=c.get(b);q.textContent=`${Yn(b)}: ${n.get(b).name}: ${k}`,q.className=A?"error":"hint"},v=await Promise.allSettled([...n].map(([b,k])=>s.uploadImageFile(t.urn,b,k))),p=v.flatMap(b=>b.status==="fulfilled"?[b.value]:[]),f=new Map;for(let[b,k]of v.entries()){let[A,q]=[...n][b];k.status==="rejected"?(f.set(A,q),h(A,(await o.describe(k.reason,"upload this file")).message,!0)):h(A,"uploaded; waiting for the CDN\u2026")}let m=[...n.keys()].filter(b=>!f.has(b)),g=b=>G.find(k=>k.size===b).field,T=m.every(b=>p.some(k=>k[g(b)]))||await this.waitForAddresses(e.entry,t.urn,m);for(let b of m)h(b,T?"done":"still processing; it appears when the CDN has placed it.");if(await this.view.refresh(e.entityUrn),f.size>0){this.preview(e.entityUrn,t,new Map([...i].filter(([A])=>f.has(A))));let b=l("button","primary","Retry failed uploads");b.type="button",b.addEventListener("click",()=>{this.retry(e,t,f,i)});let k=l("div","actions");k.append(b),d.append(l("p","message","Some files were not uploaded. The new version keeps the others."),k);return}for(let b of i.values())URL.revokeObjectURL(b);u.close(),a.showMessage(`Uploaded ${n.size} ${n.size===1?"file":"files"} to a new version of ${e.name}.`,!0)}async retry(e,t,n,i){let s=await this.ctx.transport.read(e.entry,t.urn),o=new Map([...n].filter(([a])=>!s[G.find(d=>d.size===a).field]));await this.upload(e,t,o,i)}async waitForAddresses(e,t,n){if(n.length===0)return!0;let i=Date.now();for(let s=0;Date.now()-i<er;s+=1){let o=await this.ctx.transport.read(e,t);if(n.every(a=>o[G.find(d=>d.size===a).field]))return this.ctx.store.remember(this.ctx.store.get(t)?.entityUrn??"",e,o),!0;await new Promise(a=>setTimeout(a,Wn[Math.min(s,Wn.length-1)]))}return!1}preview(e,t,n){let i={...this.ctx.store.get(t.urn)?.item??t};for(let[o,a]of n)i[G.find(d=>d.size===o).field]=a;let s=this.ctx.entry("image");for(let o of this.ctx.discovery.all())o.entry!==s||this.ctx.store.entityFor(o.scope)!==e||o.element.getAttribute(B(s))!==t.urn&&!(o.name===t.name&&o.sortOrder===t.sortOrder)||(this.ctx.live.render(o,i),F(o.element,"changed"))}};function Yn(r){return G.find(e=>e.size===r).label.split(" (")[0]}async function tr(r,e){let t=r.get("DEFAULT");if(!e||!t||r.size>1)return r;let n=new Map(r);for(let i of["MEDIUM","LARGE"]){let s=e[i];s&&n.set(i,await nr(t,s,i))}return n}async function nr(r,e,t){try{let n=await createImageBitmap(r);if(n.width<=e)return r;let i=Math.round(n.height*e/n.width),s=document.createElement("canvas");s.width=e,s.height=i,s.getContext("2d").drawImage(n,0,0,e,i);let o=r.type==="image/png"||r.type==="image/webp"?r.type:"image/jpeg",a=await new Promise((c,u)=>s.toBlob(h=>h?c(h):u(new Error("Could not scale the image")),o,.9)),d=r.name.replace(/(\.[^.]+)?$/,`-${t.toLowerCase()}$1`);return new File([a],d,{type:o})}catch{return r}}var ir=["image/apng","image/avif","image/gif","image/jpeg","image/png","image/svg+xml","image/webp"],kt=1024*1024;function xt(r){let e=window.baackEditorConfig?.maxImageBytes??10*kt,t=window.baackEditorConfig?.warnImageBytes??2*kt,n=s=>`${(s/kt).toFixed(1)} MB`,i=[];for(let s of r.values())ir.includes(s.type)?s.size>e?i.push({level:"error",message:`${s.name} is ${n(s.size)}; the limit is ${n(e)}. Use a smaller file.`}):s.size>t&&i.push({level:"warning",message:`${s.name} is ${n(s.size)}, large for the web. Compressing it will make the page faster.`}):i.push({level:"error",message:`${s.name} is not an image type Baack accepts: JPEG, PNG, APNG, GIF, WebP, AVIF or SVG.`});return i}var Jn="data-content-live",Zn="baack:item-shown",Xn="baack:live-request";function j(r){return r.closest(`[${Jn}]`)!==null}var He=class{store;shown=new Map;previews=new Set;constructor(e){this.store=e,document.addEventListener(Xn,this.onRequest)}render(e,t){if(!j(e.element)){rn(e.entry,e.element,e,t);return}let n={...this.slot(e),item:t};this.previews.has(Q(n))||(this.shown.set(Q(n),n),Be(n),t.urn&&e.element.setAttribute(B(e.entry),t.urn))}restore(e){if(!j(e.element))return!1;let t={...this.slot(e),restore:!0};return this.previews.has(Q(t))||(this.shown.delete(Q(t)),Be(t)),!0}showAt(e,t,n){let i=n?{...this.slot(e),sortOrder:t,item:n}:{...this.slot(e),sortOrder:t,restore:!0};n?(this.shown.set(Q(i),i),this.previews.add(Q(i))):(this.shown.delete(Q(i)),this.previews.delete(Q(i))),Be(i)}endPreviews(){this.previews.clear()}slot(e){return{entityUrn:this.store.entityFor(e.scope)??e.scope,type:e.entry.type,name:e.name,sortOrder:e.sortOrder}}onRequest=e=>{for(let t of this.shown.values())t.entityUrn===e.detail.entityUrn&&Be(t)}};function Q(r){return`${r.entityUrn}\0${r.type}\0${r.name}\0${r.sortOrder}`}function Be(r){document.dispatchEvent(new CustomEvent(Zn,{detail:r}))}var rr=/Mac|iPhone|iPad/.test(navigator.userAgent),Ne=class{element;sendsOnEnter;host;callbacks;savedEditable;savedWhiteSpace;savedChildren;constructor(e,t,n,i){this.element=e,this.host=n,this.callbacks=i,this.sendsOnEnter=getComputedStyle(e).display.startsWith("inline")&&e.getAttribute("data-text-layout")!=="paragraphs",this.savedEditable=e.getAttribute("contenteditable"),this.savedWhiteSpace=e.style.whiteSpace,this.savedChildren=j(e)?[...e.childNodes]:void 0,e.textContent=t,Oe(e),e.setAttribute("contenteditable","plaintext-only"),e.style.whiteSpace="pre-wrap",e.addEventListener("input",this.onInput),e.addEventListener("keydown",this.onKeyDown),e.addEventListener("blur",this.onBlur),e.focus(),sr(e)}get hint(){let e=rr?"\u2318":"Ctrl";return this.sendsOnEnter?"Enter to save \xB7 Esc to revert":`${e}+Enter to save \xB7 Esc to revert`}close(){this.element.removeEventListener("input",this.onInput),this.element.removeEventListener("keydown",this.onKeyDown),this.element.removeEventListener("blur",this.onBlur),this.savedEditable===null?this.element.removeAttribute("contenteditable"):this.element.setAttribute("contenteditable",this.savedEditable),this.element.style.whiteSpace=this.savedWhiteSpace,this.element.getAttribute("style")||this.element.removeAttribute("style"),this.savedChildren&&this.element.replaceChildren(...this.savedChildren)}onInput=()=>{Oe(this.element),this.callbacks.input()};onKeyDown=e=>{e.key==="Escape"?(e.preventDefault(),this.callbacks.revert()):e.key==="Enter"&&(e.metaKey||e.ctrlKey||this.sendsOnEnter&&!e.shiftKey)&&(e.preventDefault(),this.callbacks.send())};onBlur=e=>{e.relatedTarget!==this.host.element&&this.callbacks.blurred()}};function sr(r){let e=window.getSelection();if(!e||e.rangeCount>0&&r.contains(e.getRangeAt(0).commonAncestorContainer))return;let t=document.createRange();t.selectNodeContents(r),t.collapse(!1),e.removeAllRanges(),e.addRange(t)}var Re=class{ctx;view;save;active;constructor(e,t,n){this.ctx=e,this.view=t,this.save=n}get current(){return this.active}attach(){document.addEventListener("dblclick",this.onDoubleClick,!0),document.addEventListener("click",this.onClick,!0)}detach(){document.removeEventListener("dblclick",this.onDoubleClick,!0),document.removeEventListener("click",this.onClick,!0)}onDoubleClick=e=>{let{discovery:t,toolbar:n}=this.ctx,i=t.closest(e.target);if(!i||this.active?.target.binding?.element===i)return;let s=t.of(i)[0];if(!s)return;e.preventDefault();let o=this.targetFor(s);if(!o){n.showMessage(`The content for "${s.name}" has not loaded.`);return}this.open(o)};onClick=e=>{this.ctx.discovery.closest(e.target)&&e.preventDefault()};onPointerDown=e=>{let t=e.composedPath(),n=this.active?.target.binding?.element??this.active?.target.anchor;!this.active||t.includes(this.ctx.host.element)||n&&t.includes(n)||this.close()};targetFor(e){let{store:t}=this.ctx,n=t.entityFor(e.scope);if(!n)return;let i=e.element.getAttribute(B(e.entry))??void 0;return{entityUrn:n,entry:e.entry,name:e.name,sortOrder:e.sortOrder,urn:i&&t.get(i)?i:void 0,anchor:e.element,binding:e}}open(e){this.view.stopPreview(e);let t=e.binding&&e.binding.element.getClientRects().length>0,n=e.binding?e.entry.component?.(e.binding.element).ownsChildren!==!1:!1;if(e.urn&&e.entry.surface==="inline"&&e.binding&&t&&n)this.openInline(e);else{let i=!e.urn&&e.binding?e.entry.fromPlaceholder?.(e.binding.element):void 0;this.openForm(t?e:{...e,binding:void 0,anchor:e.anchor},i)}}async openInline(e){this.close();let{store:t,pending:n,host:i,popover:s}=this.ctx,{entry:o}=e,a=e.binding.element,d=t.get(e.urn),c=o.renderedByView?await this.baseValue(e):O(o,d.item);if(!c||this.active||!this.view.isEditing||!a.isConnected)return;let u=n.getEdit(e.urn)?.value??c,h=new Ne(a,String(u.value??""),i,{input:()=>this.setPending(e,o.read(a)),send:()=>{this.save(e)},revert:()=>this.revert(e),blurred:()=>this.close()});this.active={target:e,session:h},F(a,"editing"),s.show(a,o.label,`${e.name} #${e.sortOrder}`,h.hint,{send:()=>{this.save(e)},revert:()=>this.revert(e)}),s.setIssues(o.validate(o.read(a))),this.offerHistory(e)}offerHistory(e){let{hooks:t}=this.ctx;this.ctx.popover.setNameAction(()=>t.showItem(e));let n=e.urn;if(!n||e.fromVersion){this.ctx.popover.setExtras([]);return}let i=e.binding,s=[{label:"History",icon:"history",run:()=>{this.close(),t.openHistory({entityUrn:e.entityUrn,entry:e.entry,name:e.name,sortOrder:e.sortOrder,urn:n})}}];i&&t.canReorder(i)&&s.push({label:"Move up",icon:"arrow-up",menu:!0,run:()=>t.moveBy(i,-1)},{label:"Move down",icon:"arrow-down",menu:!0,run:()=>t.moveBy(i,1)},{label:"Reorder\u2026",icon:"list-ordered",menu:!0,run:()=>t.reorder(i)}),s.push({label:"Move or rename\u2026",icon:"pencil-line",menu:!0,run:()=>t.relocate(e)}),this.ctx.popover.setExtras(s)}async openForm(e,t){this.close();let{store:n,pending:i,popover:s,toolbar:o}=this.ctx,{entry:a}=e,d=a.form;if(!d)return;let c;if(e.urn){let h=await this.baseValue(e);if(!h)return;c=(e.fromVersion?void 0:i.getEdit(e.urn)?.value)??h}else{if(n.itemAt(e.entityUrn,a,e.name,e.sortOrder)){o.showMessage(`An item already exists at ${e.name} #${e.sortOrder}.`);return}c=i.getCreate(H({...e,type:a.type}))?.value??t??(e.binding?a.fromPlaceholder?.(e.binding.element):void 0)??a.defaults()}this.active={target:e,session:void 0},e.binding&&F(e.binding.element,"editing");let u=d.toForm(c);s.showForm(e.anchor,e.fromVersion?`${a.label}, from an older version`:e.urn?a.label:`New ${a.label.toLowerCase()}`,`${e.name} #${e.sortOrder}`,d.fields,u,{input:h=>this.onFormInput(e,h),send:()=>{this.save(e)},revert:()=>this.revert(e)},a.surface==="panel"),s.setDescription(this.describeForm(e,u)),s.setIssues(a.validate(c)),this.offerHistory(e),e.fromVersion&&this.setPending(e,c),document.addEventListener("pointerdown",this.onPointerDown,!0)}describeForm(e,t){let n=[e.entry.form?.describe?.(t)??""];return!e.urn&&S(this.ctx.store.view(e.entityUrn)?.status)&&n.push("This content is published, so a new item is live as soon as it is saved."),n.filter(Boolean).join(" ")}async baseValue(e){let{store:t,sources:n,transport:i,feedback:s}=this.ctx,o=e.urn,a=t.get(o)??t.itemAt(e.entityUrn,e.entry,e.name,e.sortOrder);if(!(!a||a.item.urn!==o)){if(!e.entry.renderedByView)return O(e.entry,a.item);try{let d=n.get(o)??O(e.entry,await i.read(e.entry,o));return n.set(o,d),d}catch(d){s.report(d,"load the source",()=>{this.openForm(e)});return}}}close(){let e=this.active;if(!e)return;this.active=void 0,document.removeEventListener("pointerdown",this.onPointerDown,!0),e.session?.close(),this.ctx.popover.hide();let t=e.target.binding;this.view.isEditing&&t?.element.isConnected&&this.view.show(t)}onFormInput(e,t){let{popover:n}=this.ctx,i=e.entry.form;if(!i)return;n.setDescription(this.describeForm(e,t));let s=i.fromForm(t);if(typeof s=="string"){n.setError(s),n.setIssues([]);return}n.setError("");let o=e.entry.type==="image"?xt(n.files()):[];n.setIssues([...e.entry.validate(s),...o]),this.setPending(e,s)}setPending(e,t){let{store:n,sources:i,pending:s,popover:o}=this.ctx,{entry:a}=e,d=t;if(e.urn){let c=n.get(e.urn)??n.itemAt(e.entityUrn,a,e.name,e.sortOrder);d=be(a,c?.item,t);let u=e.fromVersion?n.itemAt(e.entityUrn,a,e.name,e.sortOrder):c,h=a.renderedByView?i.get(u?.item.urn??e.urn):u?.item;h&&we(a,d,h)?s.clear(e.urn):s.set({kind:"edit",type:a.type,urn:e.urn,entityUrn:e.entityUrn,name:e.name,sortOrder:e.sortOrder,value:d,...e.fromVersion?{fromVersion:!0}:{}})}else s.set({kind:"create",type:a.type,entityUrn:e.entityUrn,name:e.name,sortOrder:e.sortOrder,value:d});this.view.reshow(e),e.entry.surface==="inline"&&this.active?.session&&o.setIssues(a.validate(d))}revert(e){this.ctx.pending.clear(e.urn??H({...e,type:e.entry.type})),this.close(),this.view.reshow(e)}};function U(r,e,t){if(D(r)){let n=ar(r);return n===void 0?Qn(r,e,t):{...Qn(r,e,t),debug:n}}return or(r,e)}function Qn(r,e,t){if(r.isUnauthorized||r.isNotFound&&t===!1)return{kind:"unauthorized",message:`Your session has ended. Log in again to ${e}. Your changes are kept.`};if(r.isForbidden)return{kind:"forbidden",message:`You don't have permission to ${e}.`};if(r.isNotFound)return{kind:"not-found",message:`This item no longer exists, or you don't have permission to ${e}.`};if(r.isConflict)return{kind:"conflict",message:"Someone else changed this since you opened it. Reload to see their version."};let{detail:n}=r;return{kind:"failed",message:`Couldn't ${e} (HTTP ${r.status})${n?`: ${n.replace(/\.$/,"")}`:""}. Try again.`}}function or(r,e){if(r instanceof ne)return{kind:"not-live",message:"This content is not published yet, so it has no live version to show. Show the latest drafts to edit it."};if(r instanceof ue){let{language:t}=r.received;return{kind:"mismatch",message:`Couldn't ${e}: Baack returned a different language version (${t}) instead of the content on this page, so it can't be edited here. Reload the page and try again.`}}return r instanceof TypeError?{kind:"network",message:`Couldn't reach Baack to ${e}. Check your connection and try again.`}:{kind:"failed",message:`Couldn't ${e}: ${r instanceof Error?r.message:String(r)}`}}function ar(r){let e=r.json();if(e===void 0)return;let t=s=>{try{return JSON.stringify(JSON.parse(s),null,2)}catch{return s}},n=(()=>{try{return new URL(r.url).pathname}catch{return r.url}})();return`${`Request: ${r.method} ${n}${r.requestBody?`
|
|
6
7
|
${t(r.requestBody)}`:""}`}
|
|
7
8
|
|
|
8
9
|
Response: ${r.status}
|
|
9
|
-
${JSON.stringify(e,null,2)}`}var
|
|
10
|
-
${p.debug}`)}for(let h of d)await this.view.refresh(h);let[u]=d;i.showMessage(o.length>0?`Saved ${
|
|
10
|
+
${JSON.stringify(e,null,2)}`}var dr=2e3,De=class{transport;toolbar;retry;stopWatching;constructor(e,t){this.transport=e,this.toolbar=t}retryAfterLogin(){this.stopWatching?.(),this.retry?.()}async report(e,t,n){let i=await this.describe(e,t);this.toolbar().showMessage(i.message,!1,i.debug),i.kind==="unauthorized"&&this.promptLogin(i.message,n)}async describe(e,t){let n;if(D(e)&&e.isNotFound)try{n=(await this.transport.clientContext()).hasSession===!0}catch(i){console.warn("Baack editor: could not read the client context to explain a 404",i)}return U(e,t,n)}async promptLogin(e,t){this.retry=t;let n;try{n=(await this.transport.clientContext()).loginIframeSrc}catch(d){console.warn("Baack editor: could not read the client context for the login prompt",d)}this.toolbar().showLogin(e,n),this.stopWatching?.();let i=!1,s=()=>{i||(i=!0,this.transport.clientContext().then(d=>{if(!this.toolbar().loginShown)return this.stopWatching?.();d.hasSession===!0&&(this.toolbar().hideLogin(),this.retryAfterLogin())}).catch(()=>{}).finally(()=>i=!1))},o=setInterval(s,dr),a=en(s);this.stopWatching=()=>{clearInterval(o),a(),this.stopWatching=void 0}}};function ti(r,e){return r===e?0:r===0?e>0?100:-100:(e-r)/Math.abs(r)*100}function ni(r){let e=new Intl.NumberFormat("en-GB",{maximumFractionDigits:1}).format(Math.abs(r));return`${r>0?"+":r<0?"\u2212":""}${e}%`}var ei=2e3;function Fe(r,e){if(r===e)return[{kind:"same",text:e}];let t=r.split(/(\s+)/).filter(Boolean),n=e.split(/(\s+)/).filter(Boolean);if(t.length*n.length>ei*ei)return[{kind:"removed",text:r},{kind:"added",text:e}];let i=Array.from({length:t.length+1},()=>new Array(n.length+1).fill(0));for(let c=t.length-1;c>=0;c-=1)for(let u=n.length-1;u>=0;u-=1)i[c][u]=t[c]===n[u]?i[c+1][u+1]+1:Math.max(i[c+1][u],i[c][u+1]);let s=[],o=(c,u)=>{let h=s.at(-1);h?.kind===c?h.text+=u:s.push({kind:c,text:u})},a=0,d=0;for(;a<t.length&&d<n.length;)t[a]===n[d]?(o("same",t[a]),a+=1,d+=1):i[a+1][d]>=i[a][d+1]?(o("removed",t[a]),a+=1):(o("added",n[d]),d+=1);for(;a<t.length;)o("removed",t[a++]);for(;d<n.length;)o("added",n[d++]);return s}function ae(r){document.dispatchEvent(new CustomEvent("baack:item-updated",{detail:r}))}function Tt(r){document.dispatchEvent(new CustomEvent("baack:item-published",{detail:r}))}function ii(r){document.dispatchEvent(new CustomEvent("baack:entity-state",{detail:r}))}function ri(r){document.dispatchEvent(new CustomEvent("baack:entity-published",{detail:{entityUrn:r}}))}var R=class{element;inputs=new Map;submit;error;submitLabel;onCancel;constructor(e,t,n,i,s){this.submitLabel=n,this.onCancel=s,this.element=l("form","simple-form"),this.element.append(l("div","title",e));for(let d of t){let c=l("label","field"),u;if(d.options){u=l("select");for(let h of d.options)u.append(Object.assign(l("option","",h.label),{value:h.value}))}else d.kind==="multiline"?(u=l("textarea"),u.rows=4):(u=l("input"),u.type=d.kind==="date"?"date":"text");u.name=d.key,u.value=d.value,d.required&&u.setAttribute("aria-required","true"),c.append(l("span","caption",d.label),u instanceof HTMLSelectElement?ee(u):u),this.inputs.set(d.key,u),this.element.append(c)}this.error=l("p","error"),this.error.setAttribute("role","alert"),this.submit=l("button","primary",n),this.submit.type="submit";let o=l("button","","Cancel");o.type="button",o.addEventListener("click",()=>this.cancel());let a=l("div","actions");a.append(o,this.submit),this.element.append(this.error,a),this.element.addEventListener("submit",d=>{d.preventDefault(),this.submit.disabled||i(this.values())})}cancel(){this.element.dispatchEvent(new Event("cancel")),this.element.remove(),this.onCancel?.()}values(){return Object.fromEntries([...this.inputs].map(([e,t])=>[e,t.value.trim()]))}setBusy(e,t="Working\u2026"){this.submit.disabled=e,this.submit.textContent=e?t:this.submitLabel}setError(e){this.error.textContent=e}};var de=class extends Error{change;newest;constructor(e,t){super("a newer draft of this item has been saved"),this.change=e,this.newest=t}};function V(r,e){return r.form?Object.values(r.form.toForm(e)).map(t=>typeof t=="boolean"?t?"on":"off":t).filter(t=>t!=="").join(" \xB7 "):JSON.stringify(e)}function Ve(r,e,t){let n=[{kind:"same",text:V(r,e)},{kind:"arrow",text:"\u2192"},{kind:"same",text:V(r,t)}],i=lr(e,t);return i?[...n,{kind:"same",text:" "},i]:n}function lr(r,e){let t=r,n=e;if(typeof t.unitValue!="number"||typeof n.unitValue!="number"||t.currencyCode!==n.currencyCode)return;let i=ti(t.unitValue,n.unitValue);if(i!==0)return{kind:i>0?"increase":"decrease",text:ni(i)}}var Ue=class{ctx;view;editing;inFlight=new Set;constructor(e,t,n){this.ctx=e,this.view=t,this.editing=n}async save(e){let{pending:t,popover:n,feedback:i}=this.ctx,s=this.editing(),o=e.urn??H({...e,type:e.entry.type});if(this.inFlight.has(o))return;let a=()=>s.current?.target===e;if(a()&&e.entry.type==="image"){let c=n.files();if(c.size>0){this.inFlight.add(o);try{await this.ctx.hooks.saveImage(e,c)}finally{this.inFlight.delete(o)}return}}if(a()&&!s.current.session&&e.entry.form){let c=e.entry.form.fromForm(n.values());if(typeof c=="string"){n.setError(c);return}(!e.urn||!t.getEdit(e.urn))&&s.setPending(e,c)}let d=e.urn?t.getEdit(e.urn):t.getCreate(o);if(!d){a()&&s.close();return}if(!e.entry.validate(d.value).some(c=>c.level==="error")){this.inFlight.add(o),n.setSending(!0),n.setError("");try{await this.commit(d),a()&&s.close(),await this.view.refresh(e.entityUrn)}catch(c){if(c instanceof de){this.showConflict(c,a()?e.anchor:this.ctx.toolbar.modeButton);return}if(c instanceof fe){a()&&s.close(),this.ctx.toolbar.showMessage(c.message),await this.view.refresh(e.entityUrn);return}let u=()=>{this.save(e)};if(a()){let h=await i.describe(c,e.urn?"save this change":"create this item");n.setError(h.message,h.debug),h.kind==="unauthorized"&&i.promptLogin(h.message,u)}else i.report(c,"save this change",u)}finally{this.inFlight.delete(o),n.setSending(!1)}}}async commit(e){let{store:t,transport:n,pending:i}=this.ctx,s=this.ctx.entry(e.type);if(e.kind==="edit"){if(!e.fromVersion){let u=(await n.history(s,e.urn)).history[0];if(u?.urn&&u.urn!==e.urn)throw new de(e,u)}let d=t.get(e.urn)??t.itemAt(e.entityUrn,s,e.name,e.sortOrder);if(!d||d.item.urn!==e.urn)throw new Error("the item has changed since this edit was made");let c=await n.update(s,e.urn,X(s,d.item,e.value,e.entityUrn));if(!c?.urn)throw new Error("the API returned no URN for the new version");return this.applySaved(s,e.urn,c),ae({entityUrn:e.entityUrn,oldUrn:e.urn,newUrn:c.urn,type:s.type,value:c}),si(c,d.item),c}if(t.itemAt(e.entityUrn,s,e.name,e.sortOrder))throw i.clear(K(e)),new Error(`an item already exists at ${e.name} #${e.sortOrder}`);let o={name:e.name,sortOrder:e.sortOrder},a=await n.create(s,X(s,o,e.value,e.entityUrn));if(!a?.urn)throw new Error("the API returned no URN for the new item");return i.clear(K(e)),ae({entityUrn:e.entityUrn,newUrn:a.urn,type:s.type,value:a}),si(a,o),a}applySaved(e,t,n){let{discovery:i,store:s,pending:o,sources:a,toolbar:d}=this.ctx,c=this.editing(),u=i.all().filter(v=>v.entry===e&&v.element.getAttribute(B(e))===t);s.replace(t,n),o.clear(t),a.delete(t);let h=c.current?.target.binding;h&&u.includes(h)&&c.close();for(let v of u)e.renderedByView?v.element.setAttribute(B(e),n.urn):this.ctx.live.render(v,n),F(v.element,"editable");d.showMessage("")}async saveAll(e){let{pending:t,feedback:n,toolbar:i}=this.ctx,s=t.all().filter(h=>(e===void 0||h.entityUrn===e)&&!(h.kind==="edit"&&h.stale));for(let h of new Set(s.flatMap(v=>v.kind==="move"?[v.planId]:[])))await this.ctx.hooks.runPlan(h);await Promise.all([...new Set(s.map(h=>h.entityUrn))].map(h=>this.view.loadScope(h)));let o=[],a=[],d=new Set,c=0;for(let h of s)if(h.kind!=="move")try{await this.commit(h),c+=1,d.add(h.entityUrn)}catch(v){if(v instanceof fe){c+=1,d.add(h.entityUrn),o.push(`${h.name} #${h.sortOrder}: ${v.message}`);continue}if(v instanceof de){this.ctx.pending.set({...v.change,stale:!0}),o.push(`${h.name} #${h.sortOrder}: a newer draft was saved; use Resolve.`);continue}let p=await n.describe(v,"save this change");if(p.kind==="unauthorized"){n.promptLogin(p.message,()=>{this.saveAll(e)});break}o.push(`${h.name} #${h.sortOrder}: ${p.message}`),p.debug&&a.push(`${h.name} #${h.sortOrder}:
|
|
11
|
+
${p.debug}`)}for(let h of d)await this.view.refresh(h);let[u]=d;i.showMessage(o.length>0?`Saved ${c}. Not saved: ${o.join(" ")}`:`Saved ${c} ${c===1?"change":"changes"}.`,o.length===0,a.join(`
|
|
11
12
|
|
|
12
|
-
`)||void 0,o.length===0&&
|
|
13
|
-
${
|
|
13
|
+
`)||void 0,o.length===0&&c>0&&d.size===1&&u?Ae(this.ctx,u):void 0)}async resolve(e,t){let n=this.ctx.entry(e.type);try{let i=(await this.ctx.transport.history(n,e.urn)).history[0];i?.urn&&i.urn!==e.urn?this.showConflict(new de(e,i),t):this.ctx.pending.set({...e,stale:!1})}catch(i){this.ctx.feedback.report(i,"check this item",()=>{this.resolve(e,t)})}}showConflict(e,t){let{popover:n}=this.ctx,{change:i,newest:s}=e,o=this.ctx.entry(i.type),a=s.createdTimestamp?new Date(M(s.createdTimestamp)).toLocaleString():"recently",d=()=>{n.hide(),this.editing().close()};n.showChoices(t,"A newer draft was saved",`${i.name} #${i.sortOrder}`,[{label:"Yours (not saved)",text:V(o,i.value)},{label:`The newer draft, saved ${a}`,text:V(o,s)}],"Nothing has been saved. Choose which value to keep.",[{label:"Cancel",run:d},{label:"Keep theirs",run:()=>{this.ctx.pending.clear(i.urn),d(),this.view.refresh(i.entityUrn)}},{label:"Save yours on top",primary:!0,run:()=>{this.saveOnTop(e,d)}}])}async saveOnTop(e,t){let{transport:n,pending:i,sources:s,feedback:o}=this.ctx,{change:a,newest:d}=e,c=this.ctx.entry(a.type);try{let u=await n.update(c,d.urn,X(c,d,a.value,a.entityUrn));i.clear(a.urn),s.delete(a.urn),ae({entityUrn:a.entityUrn,oldUrn:d.urn,newUrn:u.urn,type:c.type,value:u}),t(),await this.view.refresh(a.entityUrn)}catch(u){o.report(u,"save this change",()=>{this.saveOnTop(e,t)})}}discardAll(e){this.editing().close();let t=this.ctx.pending.clearAll(e);for(let n of t)this.view.reshow({entityUrn:n.entityUrn,entry:this.ctx.entry(n.type),name:n.name,sortOrder:n.sortOrder,urn:n.kind==="edit"?n.urn:void 0});this.ctx.toolbar.showMessage(`Discarded ${t.length} unsaved ${t.length===1?"change":"changes"}.`,!0)}confirmCreateAll(e,t){let{store:n}=this.ctx;if(!S(n.view(e)?.status)){this.createAll(e);return}let i=new R(`${this.ctx.entityTitle(e)} is published`,[],`Create ${t} ${t===1?"item":"items"} on the live site`,()=>{s.close(),this.createAll(e)});i.element.insertBefore(Object.assign(document.createElement("p"),{className:"hint",textContent:"New items on a published entity are live as soon as they are created. Check the placeholders first."}),i.element.querySelector(".error"));let s=this.ctx.panels.show(i.element,{entityUrn:e})}async createAll(e){let{store:t,pending:n,feedback:i,toolbar:s}=this.ctx;await this.view.refresh(e);let o=0,a=[],d=[],c=[];for(let u of this.view.missingBindings(e)){let{entry:h}=u;if(t.itemAt(e,h,u.name,u.sortOrder))continue;if(h.showsPageRendering?.(u.element)){a.push(u.name);continue}let v=H({entityUrn:e,type:h.type,name:u.name,sortOrder:u.sortOrder}),p=n.getCreate(v)?.value??h.fromPlaceholder?.(u.element)??h.defaults();if(h.form&&typeof h.form.fromForm(h.form.toForm(p))=="string"){d.push(`${u.name}: its placeholder is not a valid ${h.label.toLowerCase()}`);continue}try{await this.commit({kind:"create",type:h.type,entityUrn:e,name:u.name,sortOrder:u.sortOrder,value:p}),o+=1,await this.view.refresh(e)}catch(f){let m=await i.describe(f,"create this item");if(m.kind==="unauthorized"){i.promptLogin(m.message,()=>{this.createAll(e)});break}d.push(`${u.name}: ${m.message}`),m.debug&&c.push(`${u.name}:
|
|
14
|
+
${m.debug}`)}}s.showMessage(`Created ${o} ${o===1?"item":"items"}.${a.length>0?` Left to be created from the site's source: ${a.join(", ")}.`:""}${d.length>0?` Not created: ${d.join(" ")}`:""}`,d.length===0,c.join(`
|
|
14
15
|
|
|
15
|
-
`)||void 0)}};function $n(r,e){if(!(r.name===e.name&&r.sortOrder===e.sortOrder))throw new pe(`Saved, but the API stored it as "${r.name??""}" #${r.sortOrder??"?"} instead of ${e.name} #${e.sortOrder}. Do not save it again; this needs fixing in the API.`)}var pe=class extends Error{};var $i={added:["ins",""],removed:["del",""],increase:["span","delta up"],decrease:["span","delta down"],arrow:["span","arrow"]};function me(r){let e=c("div","change");if(typeof r=="string")return e.textContent=r,e;for(let t of r){if(t.kind==="same"){e.append(t.text);continue}let[n,i]=$i[t.kind],s=c(n,i,t.text);t.kind==="arrow"&&s.setAttribute("aria-label","to"),(t.kind==="increase"||t.kind==="decrease")&&(s.title=`${t.text.replace(/^[+−]/,"")} ${t.kind}`),e.append(s)}return e}var Ue=class{element;status;list;more;compare;constructor(e,t){this.element=c("div","level-item");let n=c("label","field");this.compare=c("select"),this.compare.append(Object.assign(c("option","","Compare with the live version"),{value:"live"}),Object.assign(c("option","","Compare with the previous version"),{value:"previous"})),this.compare.addEventListener("change",()=>t(this.compare.value)),n.append(c("span","caption","Show changes"),ve(this.compare)),this.status=c("p","hint"),this.status.setAttribute("role","status"),this.list=c("ol","rows history-rows"),this.list.setAttribute("aria-label","Versions, newest first"),this.more=c("button","","Load older versions"),this.more.type="button",this.more.hidden=!0,this.more.addEventListener("click",e),this.element.append(n,this.status,this.list,this.more)}setStatus(e){this.status.textContent=e}render(e,t){let n=new Set([...this.list.querySelectorAll('li.history-row:has(> button[aria-expanded="true"])')].map(i=>i.dataset.when));this.list.replaceChildren(...e.map(i=>this.row(i,n))),this.more.hidden=!t}row(e,t){let n=c("li","row history-row");n.dataset.when=e.whenUtc;let i=c("button","row-main");i.type="button",i.dataset.row="";let s=c("span","row-name",e.when);s.title=`${e.whenUtc} UTC`,i.append(s),e.live&&i.append(c("span","status status-up-to-date","live"));for(let d of e.notes)i.append(c("span","status note",d));let o=c("span","stack-chevron");o.append(L("chevron-right")),o.setAttribute("aria-hidden","true"),i.append(o),i.addEventListener("click",()=>e.open());let a=c("div","actions");if(a.append(Hn(e.preview)),n.append(i,me(e.change),a),e.collapsed.length>0){let d=T(`${e.collapsed.length} earlier ${e.collapsed.length===1?"draft":"drafts"}`,"ghost","xs"),l=t.has(e.whenUtc);d.setAttribute("aria-expanded",String(l));let u=c("ol","rows");u.hidden=!l,u.append(...e.collapsed.map(h=>this.row(h,t))),d.addEventListener("click",()=>{u.hidden=!u.hidden,d.setAttribute("aria-expanded",String(!u.hidden))}),n.append(d,u)}return n}};function ft(r,e){if(!e){r.replaceChildren(c("p","message","This version is no longer in the history. Go back to see the versions there are."));return}let t=c("p","version-head");t.title=`Saved ${e.whenUtc} UTC`;for(let s of e.marks)t.append(c("span",`status ${s==="live"?"status-up-to-date":"note"}`,s));for(let s of e.notes)t.append(c("span","status note",s));let n=e.changes.map(({label:s,change:o})=>{let a=c("div","field version-change");return a.append(c("span","caption",s),me(o)),a}),i=c("div","actions");i.append(...e.actions.map(Hn)),r.replaceChildren(...t.childElementCount>0?[t]:[],...n,i)}function Hn(r){let e=T(r.label,W(r),"sm");return r.pressed!==void 0&&e.setAttribute("aria-pressed",String(r.pressed)),r.disabled&&(e.disabled=!0,e.title=r.disabled),e.addEventListener("click",()=>r.run(e)),e}var Hi=400,Bi=0,fe,vt=0;function I(r,e){if(r.removeAttribute("title"),e!==void 0){let n=c("span","visually-hidden",e);n.id=`baack-tooltip-${++Bi}`;let i=()=>r.parentElement&&!n.isConnected&&r.after(n);i(),queueMicrotask(i),r.setAttribute("aria-describedby",n.id)}let t=()=>e??r.getAttribute("aria-label")??"";r.addEventListener("pointerenter",n=>{n.pointerType!=="touch"&&(clearTimeout(vt),vt=window.setTimeout(()=>Bn(r,t()),fe?0:Hi))}),r.addEventListener("focus",()=>{r.matches(":focus-visible")&&Bn(r,t())});for(let n of["pointerleave","blur","pointerdown"])r.addEventListener(n,yt);r.addEventListener("keydown",n=>{n.key==="Escape"&&fe?.trigger===r&&yt()})}function Bn(r,e){if(yt(),!r.isConnected||r.getClientRects().length===0)return;let t=c("div","tooltip",e);t.setAttribute("aria-hidden","true"),r.getRootNode().append(t);let n=r.getBoundingClientRect(),{width:i,height:s}=t.getBoundingClientRect(),o=n.top-s-6;t.style.top=`${o>=8?o:n.bottom+6}px`,t.style.left=`${Math.min(Math.max(8,n.left+n.width/2-i/2),window.innerWidth-i-8)}px`,fe={tip:t,trigger:r}}function yt(){clearTimeout(vt),fe?.tip.remove(),fe=void 0}var Nn="baack-editor:side",Ri=150,Rn=3,Ni=0,Di="(max-width: 640px)",Ve=class{element;back;heading;crumbs;body;announcer;dock;entries=[];id=`baack-stack-${Ni+=1}`;closeListeners=[];toolbar;constructor(e){this.element=c("aside","panel side stack"),this.element.setAttribute("aria-label","Editor"),this.element.hidden=!0;let t=c("div","stack-bar");this.back=T("","ghost","sm","stack-back"),this.back.addEventListener("click",()=>this.pop()),this.dock=T("","ghost","icon-sm","side-dock"),this.dock.addEventListener("click",()=>this.setSide(this.side==="right"?"left":"right"));let n=T("","ghost","icon-sm","stack-close");n.setAttribute("aria-label","Close"),n.append(L("x")),n.addEventListener("click",()=>this.close()),t.append(this.back,c("span","stack-spacer"),this.dock,n),I(this.dock),I(n);let i=c("nav","stack-crumbs");i.setAttribute("aria-label","Where you are"),this.crumbs=c("ol"),i.append(this.crumbs),this.heading=c("h2","stack-title"),this.heading.id=`${this.id}-title`,this.heading.tabIndex=-1,this.body=c("div","stack-body"),this.announcer=c("p","visually-hidden"),this.announcer.setAttribute("aria-live","polite"),this.element.append(t,i,this.heading,this.body,this.announcer),this.element.addEventListener("keydown",this.onKeyDown),this.setSide(Fi()),e.root.append(this.element)}avoid(e){this.toolbar=e,new ResizeObserver(()=>this.fit()).observe(e),window.addEventListener("resize",()=>this.fit()),this.fit()}onClose(e){this.closeListeners.push(e)}fit(){let e=this.toolbar?.getBoundingClientRect().top,t=(this.side==="right"||matchMedia(Di).matches)&&e!==void 0;this.element.style.bottom=t?`${Math.max(16,window.innerHeight-e+8)}px`:""}get current(){return this.entries.at(-1)?.level}get path(){return this.entries.map(e=>e.level.id)}get isOpen(){return!this.element.hidden}push(e,{focus:t=!0}={}){let n=this.entries.at(-1);n&&(n.scrollTop=this.body.scrollTop,n.origin=this.focusedIn(n.section));let i=this.enter(e);this.entries.push(i),this.show(i,n,"in",t)}pop(){if(this.entries.length<=1){this.close();return}this.popTo(this.entries.at(-2).level.id)}popTo(e){let t=this.entries.findIndex(i=>i.level.id===e);if(t<0||t===this.entries.length-1)return;let n=this.entries.at(-1);for(let i of this.entries.splice(t+1))this.leave(i,i===n);this.show(this.entries[t],n,"out")}replace(e,{focus:t=!0}={}){let n=this.entries.pop();n&&this.leave(n,!1);let i=this.enter(e);this.entries.push(i),this.show(i,void 0,"none",t)}reset(e,{focus:t=!0}={}){for(let i of this.entries.splice(0))this.leave(i,!1);for(let i of e)this.entries.push(this.enter(i));let n=this.entries.at(-1);n&&this.show(n,void 0,"none",t)}open(){this.element.hidden=!1}close(){if(!this.element.hidden){this.element.hidden=!0;for(let e of this.closeListeners)e()}}get side(){return this.element.dataset.side==="left"?"left":"right"}setSide(e){this.element.dataset.side=e,this.dock.setAttribute("aria-label",e==="right"?"Move to left":"Move to right"),this.dock.replaceChildren(L(e==="right"?"panel-left":"panel-right")),this.fit();try{localStorage.setItem(Nn,e)}catch{}}enter(e){let t=c("section","stack-level");return t.dataset.level=e.id,t.setAttribute("aria-labelledby",this.heading.id),t.hidden=!0,t.append(e.render()),this.body.append(t),{level:e,section:t,scrollTop:0,origin:void 0}}leave(e,t){e.level.dispose?.(),(!t||!this.animates())&&e.section.remove()}show(e,t,n,i=!0){this.element.hidden=!1;for(let o of this.entries)o.section.hidden=o!==e;e.section.hidden=!1,this.renderHeader(),this.body.scrollTop=n==="out"?e.scrollTop:0,t&&n!=="none"&&this.slide(e.section,t.section,n),e.level.onShow?.(),this.announcer.textContent=e.level.title;let s=n==="out"&&e.origin?.isConnected?e.origin:void 0;i&&(s??this.heading).focus({preventScroll:n==="out"})}renderHeader(){let e=this.entries.at(-1).level,t=this.entries.at(-2)?.level;this.heading.textContent=e.title,this.back.hidden=!t,this.back.replaceChildren(...t?[L("chevron-left"),c("span","stack-back-text",t.title)]:[]),this.back.setAttribute("aria-label",t?`Back to ${t.title}`:"Back");let n=this.entries.map((s,o)=>({entry:s,index:o})),i=n.length>Rn+1?[n[0],void 0,...n.slice(n.length-(Rn-1))]:n;this.crumbs.replaceChildren(...i.flatMap((s,o)=>{let a=c("li","stack-crumb-separator");a.setAttribute("role","presentation"),a.setAttribute("aria-hidden","true"),a.append(L("chevron-right"));let d=c("li"),l=h=>(d.append(h),o===0?[d]:[a,d]);if(!s)return l(c("span","meta","\u2026"));if(s.index===this.entries.length-1){let h=c("span","",s.entry.level.title);return h.setAttribute("aria-current","page"),l(h)}let u=c("button","stack-crumb",s.entry.level.title);return u.type="button",u.addEventListener("click",()=>this.popTo(s.entry.level.id)),l(u)})),this.crumbs.parentElement.hidden=this.entries.length<2}animates(){return typeof Element.prototype.animate=="function"&&!matchMedia("(prefers-reduced-motion: reduce)").matches}slide(e,t,n){if(!this.animates())return;let i=this.side==="right"?"100%":"-100%",s={duration:Ri,easing:"ease-out"};if(n==="in"){e.animate([{transform:`translateX(${i})`},{transform:"none"}],s);return}t.hidden=!1,t.inert=!0,t.setAttribute("aria-hidden","true"),t.classList.add("leaving"),t.style.top=`${this.body.scrollTop}px`,t.animate([{transform:"none"},{transform:`translateX(${i})`}],s).finished.then(()=>t.remove(),()=>t.remove())}focusedIn(e){let t=this.element.getRootNode().activeElement;return t instanceof HTMLElement&&e.contains(t)?t:void 0}onKeyDown=e=>{if(e.key==="Escape"&&!e.defaultPrevented){e.preventDefault(),e.stopPropagation(),this.pop();return}if(e.key!=="ArrowDown"&&e.key!=="ArrowUp")return;let t=this.entries.at(-1)?.section,n=t&&this.focusedIn(t);if(!t||!n?.matches("[data-row]"))return;let i=[...t.querySelectorAll("[data-row]")].filter(o=>!o.closest("[hidden]")),s=i[i.indexOf(n)+(e.key==="ArrowDown"?1:-1)];s&&(e.preventDefault(),s.focus())}};function Fi(){try{return localStorage.getItem(Nn)==="left"?"left":"right"}catch{return"right"}}function Dn(r,e,t){let n=c("button","stack-row");n.type="button",n.dataset.row="";let i=c("span","stack-row-text");i.append(c("span","stack-row-label",r)),e&&i.append(c("span","meta",e));let s=c("span","stack-chevron");return s.append(L("chevron-right")),n.append(i,s),n.addEventListener("click",t),n}function _e(r){let e=c("div","level-confirm");e.append(c("p","meta",r.meta));for(let n of r.blocks){let i=c("div","field");i.append(c("span","caption",n.label),c("pre","snippet",n.text)),e.append(i)}e.append(c("p","description",r.description));let t=c("div","actions");for(let n of r.choices){let i=T(n.label,W(n));i.addEventListener("click",()=>n.run(i)),t.append(i)}return e.append(t),{id:r.id,title:r.title,render:()=>e}}var Ui=600*1e3,ze=class{stack;ctx;editing;view;hooks;state;constructor(e,t,n,i,s){this.ctx=e,this.editing=t,this.view=n,this.stack=i,this.hooks=s,n.onPreviewChange(()=>this.render())}async open(e){this.state&&!_i(this.state,e)&&this.stopPreview();let t=new Ue(()=>{this.loadMore()},s=>{this.state===i&&(i.against=s,this.render())}),n={id:Vi(e),title:`${e.name} #${e.sortOrder}`,render:()=>t.element,dispose:()=>{this.state===i&&(this.stopPreview(),this.state=void 0)}},i={...e,versions:[],live:void 0,after:void 0,against:"live",linked:!1,level:n,view:t,version:void 0};this.state=i,this.hooks.show(n,e.entityUrn),t.setStatus("Loading\u2026"),i.linked=await this.isLinked(e),this.state===i&&await this.loadMore()}close(){this.stopPreview(),this.state=void 0}stopPreview(){this.state&&this.view.previewedUrn&&(this.view.stopPreview(this.state),this.ctx.toolbar.showMessage(""))}togglePreview(e,t){if(this.view.previewedUrn===t.urn){this.stopPreview();return}this.editing.close(),this.view.previewVersion(e,t);let n=window.getSelection(),i=this.view.bindingsAt(e).map(o=>o.element);n?.anchorNode&&i.some(o=>o.contains(n.anchorNode))&&n.removeAllRanges(),this.view.bindingsAt(e)[0]?.element.scrollIntoView({block:"nearest",behavior:"smooth"});let s=new Date(C(t.createdTimestamp??"")).toLocaleString();this.ctx.toolbar.showMessage(`Previewing the version of ${e.name} saved ${s}. Nothing is saved; stop the preview to see the latest again.`,!0)}changed(e){let t=this.state;if(!t||e&&e!==t.entityUrn)return;let n=this.ctx.store.itemAt(t.entityUrn,t.entry,t.name,t.sortOrder);n?.item.urn&&(t.urn=n.item.urn),this.reload(t)}async reload(e){try{let t=await this.ctx.transport.history(e.entry,e.urn);if(this.state!==e)return;e.live=t.item??void 0,e.versions=[...t.history],e.after=t.pagination?.isMorePages?t.pagination.after??void 0:void 0,this.render()}catch(t){this.ctx.feedback.report(t,"load the history",()=>{this.reload(e)})}}async loadMore(){let e=this.state;if(e)try{let t=await this.ctx.transport.history(e.entry,e.urn,e.after);if(this.state!==e)return;e.live??=t.item??void 0,e.versions.push(...t.history),e.after=t.pagination?.isMorePages?t.pagination.after??void 0:void 0,e.view.setStatus(""),this.render()}catch(t){e.view.setStatus(""),this.ctx.feedback.report(t,"load the history",()=>{this.loadMore()})}}render(){let e=this.state;if(!e)return;let t=e.versions.map((s,o)=>this.row(e,s,e.versions[o+1])),n=[],i;e.versions.forEach((s,o)=>{let a=C(s.createdTimestamp??""),d=n.at(-1),l=s.isPublished===!0;d&&!l&&!d.live&&i!==void 0&&i-a<=Ui?d.collapsed.push(t[o]):n.push(t[o]),i=a}),e.view.render(n,e.after!==void 0),e.version&&this.stack.path.includes(Fn(e.version.urn))&&ft(e.version.body,this.versionModel(e,e.version.urn))}row(e,t,n){let i=e.against==="live"?e.live:n;return{when:bt(t),whenUtc:t.createdTimestamp??"",live:t.isPublished===!0,change:gt(e.entry,t,i,e.against),notes:this.notes(t,n),open:()=>this.openVersion(e,t),preview:this.previewAction(e,t),collapsed:[]}}notes(e,t){let n=[];t&&t.name!==e.name&&n.push(`renamed from ${t.name}`),t&&t.sortOrder!==e.sortOrder&&n.push(`moved from #${t.sortOrder} to #${e.sortOrder}`);let i=e.urn?this.ctx.groups?.of(e.urn):void 0;return i&&n.push(`part of: ${i.label}`),n}openVersion(e,t){let n=t.urn,i=c("div","level-version");e.version={urn:n,body:i},ft(i,this.versionModel(e,n)),this.stack.push({id:Fn(n),title:`Version saved ${bt(t)}`,render:()=>i,dispose:()=>{e.version?.urn===n&&(e.version=void 0)}})}versionModel(e,t){let n=e.versions.findIndex(l=>l.urn===t),i=e.versions[n];if(!i)return;let s=e.versions[n+1],o=[...i.isPublished===!0?["live"]:[],...n===0?["latest"]:[]],a=s!==void 0&&s.urn===e.live?.urn,d=[{label:a?"Against the one before, which is live":"Against the one before",change:gt(e.entry,i,s,"previous")||"The same value as the one before."}];return i.isPublished!==!0&&!a&&d.push({label:"Against live",change:gt(e.entry,i,e.live,"live")}),{when:bt(i),whenUtc:i.createdTimestamp??"",marks:o,notes:this.notes(i,s),changes:d,actions:this.actions(e,i)}}actions(e,t){let{ctx:n}=this,i=[],s=n.store.view(e.entityUrn)?.status;if(n.canPublish&&t.isPublished!==!0&&(S(s)||s==="PUBLISH")){let a=s==="PUBLISH"?"Publishing is in progress for this page.":void 0,d=n.groups?.of(t.urn)!==void 0;i.push(e.linked||d?{label:"Publish with the page\u2026",disabled:a,run:()=>this.hooks.publishEntity(e.entityUrn)}:{label:"Publish this version",primary:!0,disabled:a,run:()=>{this.publish(e,t)}})}i.push(this.previewAction(e,t)),t!==e.versions[0]&&i.push({label:"Edit from this version",run:a=>this.editFrom(e,t,a)});let o=e.versions.length===1&&e.after===void 0;return i.push({label:o?"Delete this item\u2026":"Delete this version\u2026",destructive:!0,run:()=>this.confirmDelete(e,t,o)}),i}previewAction(e,t){let n=this.view.previewedUrn===t.urn,i=this.ctx.store.itemAt(e.entityUrn,e.entry,e.name,e.sortOrder)?.item.urn,s=e.entry.renderedByView?"The page shows the server's rendering of this type, which history does not include.":this.view.mode!=="LATEST"?"Previews are shown on the latest drafts.":this.view.bindingsAt(e).length===0?"This item is not shown on this page.":t.urn===i&&!this.ctx.pending.getEdit(t.urn)?"The page already shows this version.":void 0;return{label:n?"Stop preview":"Preview on the page",pressed:n,disabled:n?void 0:s,run:()=>this.togglePreview(e,t)}}confirmDelete(e,t,n){let i=new Date(C(t.createdTimestamp??"")).toLocaleString(),s=t.isPublished===!0?"from this page and from the live site":"from this page",o=[{label:`The version saved ${i}`,text:F(e.entry,t)}],a=n?`This is its only version, so deleting it deletes the item: it disappears ${s}, and cannot be restored.`:"It is removed from the history for good and cannot be restored. Every version uses storage, which is billed.",d=!n&&t.isPublished===!0?Un(e,t):void 0;if(d){let l=new Date(C(d.version?.createdTimestamp??"")).toLocaleString();d.version&&o.push({label:`Goes live in its place: the version saved ${l}`,text:F(e.entry,d.version)}),a=d.newer?`This is the live version. The API puts the next newer version live in its place: a draft saved ${l}, which may never have been published. Publish the version you want first if that is not it. It cannot be restored.`:d.version?`This is the live version. The API puts the version before it live in its place (saved ${l}). It cannot be restored.`:"This is the live version. The API puts the version before it live in its place. It cannot be restored."}this.stack.push(_e({id:"confirm-delete",title:n?"Delete this item permanently?":d?"Delete the live version permanently?":"Delete this version permanently?",meta:`${e.name} #${e.sortOrder}`,blocks:o,description:a,choices:[{label:"Cancel",run:()=>this.stack.pop()},{label:"Delete permanently",destructive:!0,run:l=>{l.disabled=!0,l.textContent="Deleting\u2026",this.deleteVersion(e,t).finally(()=>{l.disabled=!1,l.textContent="Delete permanently"})}}]}))}async deleteVersion(e,t){let{transport:n,pending:i,toolbar:s,feedback:o}=this.ctx,a=t.isPublished===!0?Un(e,t).version:void 0;try{await n.remove(e.entry,t.urn),a?.urn&&mt({entityUrn:e.entityUrn,urn:a.urn,type:e.entry.type});let d=e.versions.find(u=>u.urn!==t.urn),l=i.getEdit(t.urn);if(!d?.urn){l&&i.clear(t.urn),this.close(),this.stack.popTo(`entity:${e.entityUrn}`),s.showMessage(`Deleted ${e.name} #${e.sortOrder}.`,!0),await this.hooks.published(e.entityUrn);return}l&&i.set({...l,stale:!0}),s.showMessage(`Deleted the version of ${e.name} saved ${new Date(C(t.createdTimestamp??"")).toLocaleString()}.`,!0),this.state===e&&this.stack.popTo(e.level.id),e.urn=d.urn,await this.hooks.published(e.entityUrn),this.state===e&&await this.reload(e)}catch(d){o.report(d,"delete this version",()=>{this.deleteVersion(e,t)})}}async publish(e,t){try{await this.ctx.transport.publishVersion(e.entry,t),mt({entityUrn:e.entityUrn,urn:t.urn,type:e.entry.type}),this.ctx.announcePublished(e.entityUrn,`Published the version of ${e.name} saved ${new Date(C(t.createdTimestamp??"")).toLocaleString()}.`,{itemUrn:t.urn}),await this.hooks.published(e.entityUrn)}catch(n){this.ctx.feedback.report(n,"publish this version",()=>{this.publish(e,t)})}}editFrom(e,t,n){this.ctx.store.remember(e.entityUrn,e.entry,t),this.editing.open({entityUrn:e.entityUrn,entry:e.entry,name:t.name,sortOrder:t.sortOrder,urn:t.urn,anchor:n,binding:void 0,fromVersion:!0})}async isLinked(e){if(e.entry.type==="template")return!0;let{store:t,sources:n,transport:i}=this.ctx,s=t.view(e.entityUrn)?.raw.templates??[],o=this.ctx.entry("template"),a=new RegExp(`\\$\\{?${e.name.replace(/[^\w-]/g,"")}\\b`);for(let d of s)if(d.urn)try{let l=n.get(d.urn)??{value:(await i.read(o,d.urn)).value};if(n.set(d.urn,l),a.test(String(l.value??"")))return!0}catch{}return!1}};function gt(r,e,t,n){if(!t)return n==="live"?"Nothing is live yet.":"The first version.";if(t.urn===e.urn)return n==="live"?"This is the live version.":"";let i=t.value,s=e.value;if(typeof i=="string"&&typeof s=="string")return Ne(i,s);let o=F(r,t),a=F(r,e);return o===a?"No change to the value.":Fe(r,t,e)}function bt(r){let e=C(r.createdTimestamp??"");return Number.isNaN(e)?"Unknown time":new Date(e).toLocaleString()}function Vi(r){return`item:${r.entityUrn}:${r.entry.type}:${r.name}:${r.sortOrder}`}function Fn(r){return`version:${r}`}function _i(r,e){return r.entityUrn===e.entityUrn&&r.entry===e.entry&&r.name===e.name&&r.sortOrder===e.sortOrder}function Un(r,e){let t=r.versions.indexOf(e);return t>0?{version:r.versions[t-1],newer:!0}:{version:r.versions[t+1],newer:!1}}function _n(r,e){let t=r.map(s=>s.sortOrder).sort((s,o)=>s-o),n=new Map(r.map(s=>[s.key,s]));if(e.length!==r.length||e.some(s=>!n.has(s)))throw new Error("The new order must contain exactly the items of the list");let i=[];return e.forEach((s,o)=>{let a=n.get(s),d=t[o];a.sortOrder!==d&&i.push({key:s,from:a.sortOrder,to:d})}),i}function zn(r,e){let t=[...r].sort((d,l)=>d.sortOrder-l.sortOrder);if(t.length===0)return{sortOrder:0,shifts:[]};if(e.position==="head")return{sortOrder:t[0].sortOrder-1,shifts:[]};if(e.position==="tail")return{sortOrder:t.at(-1).sortOrder+1,shifts:[]};let n=t.findIndex(d=>d.key===e.key);if(n<0)throw new Error("The item to insert after is not in the list");let i=t[n],s=t[n+1];if(!s)return{sortOrder:i.sortOrder+1,shifts:[]};if(s.sortOrder-i.sortOrder>1)return{sortOrder:Math.floor((i.sortOrder+s.sortOrder)/2),shifts:[]};let o=t.slice(0,n+1),a=t.slice(n+1);return a.length<=o.length?{sortOrder:s.sortOrder,shifts:[...Vn(a,1)].reverse()}:{sortOrder:i.sortOrder,shifts:Vn([...o].reverse(),-1).reverse()}}function Vn(r,e){let t=[];for(let[n,i]of r.entries()){if(n>0&&i.sortOrder!==t.at(-1).to)break;t.push({key:i.key,from:i.sortOrder,to:i.sortOrder+e})}return t}function Gn(r,e){return[{key:r.key,from:r.sortOrder,to:e.sortOrder},{key:e.key,from:e.sortOrder,to:r.sortOrder}]}async function Kn(r,e,t){let{store:n,sources:i,transport:s}=r,o=r.entry("template"),a=new RegExp(`\\$\\{?${t.replace(/[^\w-]/g,"")}\\b`),d=[];for(let l of n.view(e)?.raw.templates??[])if(l.urn)try{let u=i.get(l.urn)??{value:(await s.read(o,l.urn)).value};i.set(l.urn,u),a.test(String(u.value??""))&&d.push(`${l.name} #${l.sortOrder}`)}catch{}return d}var Ge=class{element;entries=[];actions;list;status;saveButton;addButtons;dragging;panels;handle;constructor(e){this.panels=e,this.element=c("div","reorder"),this.status=c("p","hint"),this.status.setAttribute("role","status"),this.list=c("ol","rows reorder-rows"),this.list.setAttribute("aria-label","Entries, in order"),this.addButtons=c("div","actions");let t=c("div","actions"),n=c("button","","Cancel");n.type="button",n.addEventListener("click",()=>this.actions?.cancel()),this.saveButton=c("button","primary","Save order"),this.saveButton.type="button",this.saveButton.addEventListener("click",()=>this.actions?.save(this.keys())),t.append(n,this.saveButton),this.element.append(this.status,this.list,this.addButtons,t)}get isOpen(){return this.handle?.isOpen??!1}open(e,t,n,i){if(this.entries=[...n],this.actions=i,this.setStatus(""),this.setBusy(!1),this.addButtons.replaceChildren(),i.add){let s=c("button","","Add at the start");s.type="button",s.addEventListener("click",()=>i.add({position:"head"},s));let o=c("button","","Add at the end");o.type="button",o.addEventListener("click",()=>i.add({position:"tail"},o)),this.addButtons.append(s,o)}this.render(),this.handle=this.panels.show(this.element,{title:e,entityUrn:t,onLeave:()=>{let s=this.actions;this.actions=void 0,s?.cancel()}})}close(){this.actions=void 0,this.handle?.close()}setStatus(e){this.status.textContent=e}setBusy(e,t="Saving\u2026"){this.saveButton.disabled=e,this.saveButton.textContent=e?t:"Save order"}keys(){return this.entries.map(e=>e.key)}move(e,t,n){if(t<0||t>=this.entries.length||e===t)return;let[i]=this.entries.splice(e,1);if(this.entries.splice(t,0,i),this.render(),n){let o=[...[...this.list.children].find(a=>a.dataset.key===i.key)?.querySelectorAll("button[data-move]")??[]];(o.find(a=>a.dataset.move===n&&!a.disabled)??o.find(a=>!a.disabled))?.focus()}this.actions?.changed(this.keys())}render(){this.list.replaceChildren(...this.entries.map((e,t)=>{let n=c("li","row reorder-row");n.draggable=!0,n.dataset.key=e.key;let i=c("span","handle");i.setAttribute("aria-hidden","true"),i.append(L("grip-vertical"));let s=c("div","row-main");s.append(c("span","row-name",e.label)),e.detail&&s.append(c("span","meta",e.detail));let o=c("button","","Move up");o.type="button",o.disabled=t===0,o.setAttribute("aria-label",`Move ${e.label} up`),o.dataset.move="up",o.addEventListener("click",()=>this.move(t,t-1,"up"));let a=c("button","","Move down");if(a.type="button",a.disabled=t===this.entries.length-1,a.setAttribute("aria-label",`Move ${e.label} down`),a.dataset.move="down",a.addEventListener("click",()=>this.move(t,t+1,"down")),n.append(i,s,o,a),this.actions?.add){let d=T("","ghost","icon-sm");d.setAttribute("aria-label",`Add after ${e.label}`),d.append(L("plus")),I(d),d.addEventListener("click",()=>this.actions?.add({position:"after",key:e.key},d)),n.append(d)}return n.addEventListener("dragstart",d=>{this.dragging=e.key,d.dataTransfer?.setData("text/plain",e.key),n.classList.add("dragging")}),n.addEventListener("dragend",()=>{this.dragging=void 0,n.classList.remove("dragging")}),n.addEventListener("dragover",d=>d.preventDefault()),n.addEventListener("drop",d=>{d.preventDefault();let l=this.entries.findIndex(u=>u.key===this.dragging);l>=0&&this.move(l,t)}),n}))}};var Ke=class{panel;ctx;view;editing;groups;done=new Map;failures=new Map;create;constructor(e,t,n,i,s){this.ctx=e,this.create=s,this.view=t,this.editing=n,this.groups=i,this.panel=new Ge(e.panels)}groupOf(e){let t=this.ctx.store.entityFor(e.scope);if(!t)return;let n=e.element.closest("[data-content-rows]"),i=e.element.closest(`[data-${e.entry.attribute}-list="${CSS.escape(e.name)}"]`);if(i&&(!n||n.contains(i)))return this.listGroup(i,e,t);if(n)return this.rowsGroup(n,e,t)}listGroup(e,t,n){let i=[];for(let s of e.children){let o=this.ctx.discovery.all().find(u=>u.entry===t.entry&&u.name===t.name&&s.contains(u.element)&&this.ctx.store.entityFor(u.scope)===n);if(!o)continue;let a=this.ctx.store.itemFor(o),d=o.element.getAttribute("data-section");if(!a?.item.urn&&d===null)continue;let l=a?.item.urn?String(a.item.value??a.item.name):d;i.push({key:a?.item.urn??`slot:${o.sortOrder}`,element:s,bindings:[o],sortOrder:o.sortOrder,label:d===null?l:zi(s,l),...d!==null?{detail:` \xB7 ${(s.textContent??"").trim().replace(/\s+/g," ").slice(0,70)}\u2026`}:{},...a?.item.urn?{}:{missing:d}})}return{kind:"list",container:e,entityUrn:n,entry:t.entry,name:t.name,units:i}}rowsGroup(e,t,n){let i=[];for(let s of e.children){let o=Number(s.getAttribute("data-content-row"));if(!Number.isInteger(o))continue;let a=this.ctx.discovery.all().filter(l=>s.contains(l.element)&&this.ctx.store.entityFor(l.scope)===n),d=a.map(l=>(l.element.textContent??"").trim()).filter(Boolean);i.push({key:`row:${o}`,element:s,bindings:a,sortOrder:o,label:d[0]??`Row ${o}`,detail:d.length>1?` \xB7 ${d.slice(1).join(" \xB7 ")}`:""})}return{kind:"rows",container:e,entityUrn:n,entry:t.entry,name:t.name,units:i}}openReorder(e){let t=this.groupOf(e);if(!t||t.units.length===0)return;this.editing().close(),this.view.rememberOrder(t.container);let n=t.units.map(s=>s.key),i=t.kind==="rows"?"rows":t.name==="sections"?"sections":`"${t.name}"`;this.panel.open(`Reorder ${i}`,t.entityUrn,t.units.map(s=>({key:s.key,label:s.label,sortOrder:s.sortOrder,...s.detail?{detail:s.detail}:{}})),{changed:s=>this.preview(t,s),cancel:()=>{this.preview(t,n),this.panel.close()},save:s=>{this.saveOrder(t,s,()=>this.panel.close())},...t.kind==="list"?{add:(s,o)=>{this.insert(t,s,o)}}:{}})}moveBy(e,t){let n=this.groupOf(e);if(!n)return;let i=n.units.map(a=>a.key),s=n.units.findIndex(a=>a.bindings.includes(e)),o=s+t;s<0||o<0||o>=i.length||([i[s],i[o]]=[i[o],i[s]],this.editing().close(),this.view.rememberOrder(n.container),this.preview(n,i),this.saveOrder(n,i,()=>{}))}preview(e,t){let n=new Map(e.units.map(a=>[a.key,a]));if(G(e.container)){this.previewLive(e,t);return}let i=new Set(e.units.map(a=>a.element)),o=[...e.container.children].filter(a=>i.has(a)).map(a=>{let d=document.createComment("");return a.replaceWith(d),d});t.forEach((a,d)=>o[d]?.replaceWith(n.get(a).element))}previewLive(e,t){let n=new Map(e.units.map(a=>[a.key,a])),i=e.units.map(a=>a.sortOrder).sort((a,d)=>a-d),s=e.units.map(a=>a.key),o=t.every((a,d)=>a===s[d]);t.forEach((a,d)=>{let l=n.get(a),u=l.bindings[0],f=this.ctx.store.itemFor(u)?.item??{name:e.name,value:l.missing};this.ctx.live.showAt(u,i[d],o?void 0:{...f,sortOrder:i[d]})})}async saveOrder(e,t,n){let i=_n(e.units.map(u=>({key:u.key,sortOrder:u.sortOrder})),t),s=new Map(e.units.map(u=>[u.key,u])),o=e.units.filter(u=>u.missing!==void 0);if(i.length===0&&o.length===0){n();return}let a=[];for(let u of i){let h=s.get(u.key);if(h.missing===void 0)for(let f of h.bindings){let p=this.ctx.store.itemFor(f);p?.item.urn&&a.push(this.step(f.entry,p.item,e.entityUrn,{name:f.name,sortOrder:u.to}))}}let d=e.kind==="rows"?"Reorder rows":`Reorder ${e.name}`;this.panel.setBusy(!0);let l=await this.runSteps(a,d)&&await this.createMissing(e,o,i);if(this.panel.setBusy(!1),!l){this.preview(e,e.units.map(u=>u.key)),await this.view.refresh(e.entityUrn);return}if(G(e.container))this.ctx.live.endPreviews();else for(let u of i)for(let h of s.get(u.key).bindings)this.view.retag(h,u.to);n(),await this.view.refresh(e.entityUrn)}async createMissing(e,t,n){if(t.length===0)return!0;let{feedback:i,toolbar:s}=this.ctx;await this.view.refresh(e.entityUrn);let o=new Map(n.map(a=>[a.key,a.to]));for(let a of t){let d=o.get(a.key)??a.sortOrder;try{await this.create({kind:"create",type:e.entry.type,entityUrn:e.entityUrn,name:e.name,sortOrder:d,value:{value:a.missing}})}catch(l){let u=await i.describe(l,`add ${a.missing} to ${e.name}`);return s.showMessage(`Reorder ${e.name}: ${u.message}`,!1,u.debug),!1}}return!0}keyedMembers(){let e=new Set,t=[];for(let n of this.ctx.discovery.all()){if(!n.element.hasAttribute("data-section"))continue;let i=this.groupOf(n);!i||i.kind!=="list"||e.has(i.container)||(e.add(i.container),i.units.forEach((s,o)=>t.push({binding:s.bindings[0],name:i.name,index:o,count:i.units.length})))}return t}openOrderMenu(e){let t=this.groupOf(e);if(!t||t.units.length<2)return;let{popover:n}=this.ctx;this.editing().close(),this.view.rememberOrder(t.container);let i=t.units.map(u=>u.key),s=t.units.find(u=>u.bindings.includes(e)),o=[...i],a=new Map(t.units.map(u=>[u.key,u.label])),d=()=>{this.preview(t,i),this.changedOrder()},l=()=>{let u=o.indexOf(s.key),h=o.some((m,g)=>m!==i[g]),f=m=>{let g=[...o];[g[u],g[u+m]]=[g[u+m],g[u]],o=g,this.preview(t,o),this.changedOrder(),l()},p=o[u-1],v=o[u+1];n.whenEnded(void 0),n.showChoices(s.element,`Order of ${t.name}`,`${u+1} of ${o.length}`,[],[`${s.label} is ${u+1} of ${o.length}.`,p?`Before it: ${a.get(p)}.`:"",v?`After it: ${a.get(v)}.`:"",h?"Not saved yet.":"",h&&t.units.some(m=>m.missing!==void 0)&&S(this.ctx.store.view(t.entityUrn)?.status)?"This content is published, and this order is new, so it is live as soon as it is saved.":""].filter(Boolean).join(" "),[...p?[{label:"Move previous",run:()=>f(-1)}]:[],...v?[{label:"Move next",run:()=>f(1)}]:[],{label:"Reorder all\u2026",run:()=>{n.whenEnded(void 0),n.hide(),d(),this.openReorder(e)}},...h?[{label:"Save",primary:!0,run:()=>{n.whenEnded(void 0),n.hide(),this.saveOrder(t,o,()=>{}).then(()=>this.changedOrder())}}]:[],{label:h?"Revert":"Close",run:()=>n.hide()}]),n.whenEnded(d)};l()}orderListeners=new Set;onOrderChange(e){this.orderListeners.add(e)}changedOrder(){for(let e of this.orderListeners)e()}async insert(e,t,n){let i=e.units.map(h=>({key:h.key,sortOrder:h.sortOrder}));await this.view.refresh(e.entityUrn);let s=zn(i,t),o=new Map(e.units.map(h=>[h.key,h]));if(s.shifts.length>0){let h=s.shifts.flatMap(f=>o.get(f.key).bindings.flatMap(p=>{let v=this.ctx.store.itemFor(p);return v?.item.urn?[this.step(p.entry,v.item,e.entityUrn,{name:p.name,sortOrder:f.to})]:[]}));if(!await this.runSteps(h,`Make room in ${e.name}`))return;for(let f of s.shifts)for(let p of o.get(f.key).bindings)this.view.retag(p,f.to);await this.view.refresh(e.entityUrn)}if(this.ctx.store.itemAt(e.entityUrn,e.entry,e.name,s.sortOrder)){this.ctx.toolbar.showMessage(`${e.name} #${s.sortOrder} is taken. Reopen the list and try again.`);return}let a=e.units.at(t.position==="head"?0:-1),d=t.position==="after"?o.get(t.key).element:a.element,l=a.element.cloneNode(!0);for(let h of[l,...l.querySelectorAll("*")])h.removeAttribute("style"),h.removeAttribute("data-baack-state"),h.removeAttribute(`data-${e.entry.attribute}-urn`),h.hasAttribute(`data-${e.entry.attribute}-name`)&&(h.setAttribute(`data-${e.entry.attribute}-sort-order`,String(s.sortOrder)),h.setAttribute("data-placeholder",""));t.position==="head"?e.container.insertBefore(l,d):d.after(l),this.view.track(l),this.panel.close();let u=l.matches(`[data-${e.entry.attribute}-name]`)?l:l.querySelector(`[data-${e.entry.attribute}-name]`);this.editing().open({entityUrn:e.entityUrn,entry:e.entry,name:e.name,sortOrder:s.sortOrder,anchor:u??l,binding:void 0})}async relocate(e,t,n,i){let{store:s}=this.ctx;this.editing().close();let o=this.ctx.discovery.all().filter(f=>f.entry===n&&f.name===i.name&&f.sortOrder===i.sortOrder).length,a=await Kn(this.ctx,t,i.name),d=c("div","simple-form");d.append(c("p","hint",`${i.name} #${i.sortOrder} is shown in ${o} ${o===1?"place":"places"} on this page. Those places will show the new item there, or a placeholder.`));let l=new _(`Move or rename ${i.name} #${i.sortOrder}`,[{key:"name",label:"Name",value:i.name},{key:"sortOrder",label:"Sort order",value:String(i.sortOrder)}],"Move",f=>{let p=f.name??"",v=Number(f.sortOrder);if(!/^[A-Za-z0-9_-]+$/.test(p))return l.setError("Use letters, numbers, - and _ in the name.");if(!Number.isInteger(v))return l.setError("The sort order must be a whole number.");if(p===i.name&&v===i.sortOrder)return l.setError("That is where it is now.");l.setBusy(!0,"Checking\u2026"),this.view.refresh(t).then(async()=>{if(l.setBusy(!1),s.itemAt(t,n,p,v)&&!u){u=!0,l.setError(`${p} #${v} is taken. Press Move again to swap the two.`);return}h.close(),await this.moveTo(t,n,i,{name:p,sortOrder:v})})}),u=!1;l.element.insertBefore(d,l.element.querySelector(".error")),a.length>0&&l.element.insertBefore(c("p","issues",`Templates use "${i.name}" and would stop showing it if it is renamed: ${a.join(", ")}.`),l.element.querySelector(".error")),l.element.insertBefore(c("p","issues","Renaming changes the name every client looks this item up by, including apps this editor cannot see. They break when it is published."),l.element.querySelector(".error"));let h=this.ctx.panels.show(l.element,{entityUrn:t})}async moveTo(e,t,n,i){await this.view.refresh(e);let s=this.ctx.store.itemAt(e,t,i.name,i.sortOrder);if(s?.item.urn===n.urn)return!0;let o=s?Gn({key:n.urn,sortOrder:n.sortOrder},{key:s.item.urn,sortOrder:i.sortOrder}).map(d=>this.step(t,d.key===n.urn?n:s.item,e,{name:d.key===n.urn?i.name:n.name,sortOrder:d.to})):[this.step(t,n,e,i)],a=s?`Swap ${n.name} #${n.sortOrder} and ${i.name} #${i.sortOrder}`:i.name===n.name?`Move ${n.name} #${n.sortOrder} to #${i.sortOrder}`:`Rename ${n.name} to ${i.name}`;return await this.runSteps(o,a)?(await this.view.refresh(e),!0):!1}step(e,t,n,i){return{kind:"move",type:e.type,urn:t.urn,entityUrn:n,name:t.name,sortOrder:t.sortOrder,to:i}}async runSteps(e,t){if(e.length===0)return!0;let n=`plan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,7)}`;for(let i of e)this.ctx.pending.set({...i,planId:n,label:t});return this.run(n)}async run(e){let{pending:t,transport:n,toolbar:i,feedback:s}=this.ctx,o=t.plan(e);if(o.length===0)return!0;let a=o[0].label,d=o[0].entityUrn,l=this.done.get(e)??[];this.done.set(e,l),i.showMessage(`${a}: moving\u2026`,!0);for(let u of o){let h=this.ctx.entry(u.type);try{let f=(await n.history(h,u.urn)).history[0];if(!f?.urn)throw new Error(`${u.name} #${u.sortOrder} no longer exists`);if(f.name===u.to.name&&f.sortOrder===u.to.sortOrder){t.clear(z(u)),l.push({step:u,urn:f.urn});continue}if(f.urn!==u.urn)throw new Error(`${u.name} #${u.sortOrder} was changed by someone else after this move was planned`);let p={...f,name:u.to.name,sortOrder:u.to.sortOrder},v=await n.update(h,f.urn,Y(h,p,M(h,f),u.entityUrn));if(!v?.urn)throw new Error("the API returned no URN for the new version");t.clear(z(u)),l.push({step:u,urn:v.urn}),se({entityUrn:u.entityUrn,oldUrn:u.urn,newUrn:v.urn,type:h.type,value:v})}catch(f){let p=await s.describe(f,"move this item");return this.showFailure(e,a,l.length,l.length+t.plan(e).length,p.message,p.debug,d),p.kind==="unauthorized"&&s.promptLogin(p.message,()=>{this.run(e)}),!1}}return this.groups()?.add({id:e,label:a,entityUrn:d,versions:l.map(u=>u.urn),at:Date.now()}),this.done.delete(e),this.closeFailure(e),i.showMessage(`${a}: done. Saved as drafts.`,!0,void 0,Te(this.ctx,d)),!0}showFailure(e,t,n,i,s,o,a){let d=c("div","simple-form");d.append(c("div","title",`${t} stopped part-way`),c("p","message",`Moved ${n} of ${i}. ${s}`),...Z(o),c("p","hint","The rest is kept with your unsaved changes, in this browser, until you retry or put things back."));let l=c("button","primary","Retry");l.type="button",l.addEventListener("click",()=>{this.run(e).then(async f=>{f&&await this.refreshAfter(e)})});let u=c("button","",n>0?"Put back":"Discard this move");u.type="button",u.addEventListener("click",()=>{this.putBack(e)});let h=c("div","actions");h.append(u,l),d.append(h),this.closeFailure(e),this.failures.set(e,this.ctx.panels.show(d,{entityUrn:a}))}closeFailure(e){this.failures.get(e)?.close(),this.failures.delete(e)}async refreshAfter(e){for(let t of this.ctx.store.entities())await this.view.refresh(t)}async putBack(e){let{pending:t}=this.ctx,n=this.done.get(e)??[],i=t.plan(e);for(let d of i)t.clear(z(d));let s=i[0]?.label??n[0]?.step.label??"Move",o=i[0]?.entityUrn??n[0]?.step.entityUrn;if(this.done.delete(e),n.length===0){this.closeFailure(e),this.ctx.toolbar.showMessage(`${s}: nothing had moved, so nothing changed. The move is discarded.`,!0);return}let a=n.map(({step:d,urn:l})=>({kind:"move",type:d.type,urn:l,entityUrn:d.entityUrn,name:d.to.name,sortOrder:d.to.sortOrder,to:{name:d.name,sortOrder:d.sortOrder}}));await this.runSteps(a,`Put back: ${s}`)&&(this.ctx.toolbar.showMessage(`Put back: ${s}.`,!0),o&&await this.view.refresh(o))}};function zi(r,e){return(r.querySelector("h1, h2, h3, h4, h5, h6")?.textContent??"").trim().replace(/\s+/g," ")||e}var je=class{layer;onOpen;tags=[];frame=0;resizes=new ResizeObserver(()=>this.schedule());constructor(e,t){this.layer=c("div","order-tags"),e.root.append(this.layer),this.onOpen=t}show(e){if(e.length===this.tags.length&&e.every((i,s)=>this.tags[s].binding===i.binding&&this.tags[s].button.textContent===jn(i))){this.place();return}let n=this.tags.findIndex(i=>i.button.matches(":focus"));this.clear();for(let i of e){let s=c("button","order-tag",jn(i));s.type="button",s.setAttribute("aria-label",`Order of ${i.name}: ${i.index+1} of ${i.count}`),s.addEventListener("click",()=>this.onOpen(i.binding)),this.layer.append(s),this.tags.push({binding:i.binding,element:i.binding.element,button:s}),this.resizes.observe(i.binding.element)}this.tags.length>0&&(window.addEventListener("scroll",this.schedule,!0),window.addEventListener("resize",this.schedule)),this.place(),this.tags[n]?.button.focus()}clear(){cancelAnimationFrame(this.frame),this.resizes.disconnect(),window.removeEventListener("scroll",this.schedule,!0),window.removeEventListener("resize",this.schedule),this.layer.replaceChildren(),this.tags=[]}schedule=()=>{cancelAnimationFrame(this.frame),this.frame=requestAnimationFrame(()=>this.place())};place(){for(let{element:e,button:t}of this.tags){let n=e.getBoundingClientRect();t.hidden=e.getClientRects().length===0,t.style.top=`${n.top+4}px`,t.style.right=`${window.innerWidth-n.right+4}px`}}};function jn(r){return`${r.name} \xB7 ${r.index+1} of ${r.count} \u22EF`}var Gi="baack-editor:groups:";var qe=class{key;constructor(e){this.key=Gi+e}all(){try{let e=JSON.parse(window.localStorage.getItem(this.key)??"[]");return Array.isArray(e)?e:[]}catch{return[]}}of(e){return this.all().find(t=>t.versions.includes(e))}add(e){try{let t=[...this.all(),e].slice(-200);window.localStorage.setItem(this.key,JSON.stringify(t))}catch(t){console.warn("Baack editor: could not record which versions belong together.",t)}}};var Ki="baack-editor:entities",qn=1440*60*1e3,ji=4,qi=[500,2e3];function j(r){return r.replace(/^\/[^/]+\/content(?=\/|$)/,"")||"/"}var We=class{transport;owners;cache=new Map;key;search;constructor(e,t,n){this.transport=e,this.owners=t,this.key=`${Ki}:${n??"anonymous"}`;try{let i=JSON.parse(localStorage.getItem(this.key)??"[]");for(let s of i)Date.now()-s.at<qn&&this.cache.set(s.urn,s)}catch{}}get(e){return this.cache.get(e)}async describe(e){return this.cache.get(e)??this.remember(await this.transport.readEntity(e))}remember(e){let t={urn:e.urn,name:e.name,path:j(e.name),language:e.language,variant:e.variant??"",at:Date.now()};return this.cache.set(t.urn,t),this.search=this.search?.then(n=>({...n,urns:n.urns.includes(t.urn)?n.urns:[...n.urns,t.urn]})),this.save(),t}async list(e){this.search??=this.searchAll().catch(u=>{throw this.search=void 0,u});let{urns:t,complete:n}=await this.search,i=()=>({entities:t.flatMap(u=>this.cache.get(u)??[]).sort(Wi),complete:n}),s=t.filter(u=>!this.fresh(u));s.length>0&&e?.(i());let o,a=[...s],d=async()=>{for(let u=a.shift();u;u=a.shift())try{this.remember(await this.readWithRetry(u)),e?.(i())}catch(h){R(h)&&h.isNotFound||(o??=h)}};if(await Promise.all(Array.from({length:Math.min(ji,s.length)},d)),o)throw o;let l=i();return e?.(l),l}async readWithRetry(e){for(let t of qi)try{return await this.transport.readEntity(e)}catch(n){if(!(R(n)&&n.status===429))throw n;await new Promise(i=>setTimeout(i,t))}return this.transport.readEntity(e)}async searchAll(){let e=await Promise.all((await this.owners()).map(t=>this.transport.searchEntities(t)));return{urns:[...new Set(e.flatMap(t=>t.urns))],complete:e.every(t=>t.complete)}}fresh(e){let t=this.cache.get(e);return t!==void 0&&Date.now()-t.at<qn}save(){try{localStorage.setItem(this.key,JSON.stringify([...this.cache.values()]))}catch{}}};function Wi(r,e){return r.path.localeCompare(e.path)||r.language.localeCompare(e.language)||r.variant.localeCompare(e.variant)}var Wn="/home";function Ye(r){let e=r.replace(/\/index\.html?$/,"/").replace(/\/+$/,"");return e===""?Wn:e}function Yn(r){return r===Wn?"/":r}function wt(r){return r.endsWith("/")}var Je=class{deps;constructor(e){this.deps=e}async offerEntityForPage(){let{transport:e,panels:t}=this.deps,n=(this.deps.entityNameForPage??Ye)(location.pathname),i=document.documentElement.lang||"en-GB";try{let s=await e.entityView(n,{version:"LATEST",language:i}),o=c("div","simple-form");o.append(c("div","title","Content for this page exists"),c("p","hint","Add this to the page's root element so the editor and the site can find it:"),Jn(s.urn));let a=c("button","primary","Use it for this visit");a.type="button",a.addEventListener("click",()=>{document.documentElement.setAttribute(U,s.urn),d.close()}),o.append(ae(a));let d=t.show(o)}catch(s){R(s)&&s.isNotFound?await this.showCreateEntity(n,i):this.deps.report(s,"look up this page",()=>{this.offerEntityForPage()})}}async showCreateEntity(e,t){let{panels:n}=this.deps,i=await this.newEntityForm({title:"This page has no content in Baack yet",submitLabel:"Create content for this page",path:e,pathLabel:"Name of this page's content",hint:`No content named ${e} (${t}) was found for ${location.pathname}.`,language:t,onCreated:s=>{let o=c("div","simple-form");o.append(c("div","title","Content created (in draft)"),c("p","hint","Add this to the page's root element. Until then, the editor uses it for this visit:"),Jn(s.urn),c("p","hint",'Next: create the items this page shows, with "Create all" on its content.'));let a=c("button","primary","Show its items");a.type="button",a.addEventListener("click",()=>this.deps.openEntity(s.urn)),o.append(ae(a)),n.show(o),document.documentElement.setAttribute(U,s.urn)}});n.show(i.element)}async offerNewEntity(e){let{panels:t}=this.deps,n=await this.newEntityForm({title:"New entity",submitLabel:"Create entity",path:"",language:e,onCreated:i=>{let s=c("div","simple-form"),o=c("pre","snippet",i.urn),a=c("button","","Copy URN");a.type="button",a.addEventListener("click",()=>{navigator.clipboard?.writeText(i.urn).then(()=>a.textContent="Copied",()=>a.textContent="Select and copy it")});let d=c("button","","Done");d.type="button",d.addEventListener("click",()=>l.close()),s.append(c("div","title",`Created ${j(i.name)} (${i.language}) in draft`),c("p","hint","Choose it in a reference item, or use its URN in the site:"),o,ae(a,d));let l=t.show(s)}});t.show(n.element)}async newEntityForm(e){let{transport:t}=this.deps,n=await this.owners(),i=new _(e.title,[{key:"name",label:e.pathLabel??"Path, such as /menu",value:e.path},{key:"language",label:"Language",value:e.language},{key:"variant",label:"Variant (optional)",value:e.variant??""},...n.length>1?[{key:"owner",label:"Owner",value:n[0].urn,options:n.map(s=>({value:s.urn,label:s.name??s.urn}))}]:[]],e.submitLabel,s=>{let o=s.owner??n[0]?.urn,a=s.name??"",d=s.language??"",l=s.variant??"";if(!o)return i.setError("No company was found to own the content.");if(!a.startsWith("/"))return i.setError("The path must start with /, like /menu.");if(wt(a))return i.setError(`Content has no index: give it a name of its own, without a trailing /, such as ${Ye(a)}.`);if(!d)return i.setError("Enter a language, such as en-GB.");i.setError(""),i.setBusy(!0,"Creating\u2026"),this.existing(a,d,l).then(u=>{if(u){i.setBusy(!1),i.setError(`${a} (${d}${l?` \xB7 ${l}`:""}) already exists.`);return}return t.createEntity({owner:{urn:o},status:"DRAFT_UNPUBLISHED",name:a,language:d,variant:l}).then(h=>{this.deps.created(h),e.onCreated(h)})}).catch(u=>{i.setBusy(!1),i.setError(re(u,"create the entity").message)})},e.onCancel);return e.hint&&i.element.insertBefore(c("p","hint",e.hint),i.element.querySelector("label")),i}async existing(e,t,n){try{let i=await this.deps.transport.entityView(e,{version:"LATEST",language:t,variant:n});return j(i.name)===e&&i.language.toLowerCase()===t.toLowerCase()&&(i.variant??"")===n?i:void 0}catch(i){if(R(i)&&i.isNotFound)return;throw i}}offerNewPageLike(e){let{transport:t,panels:n,store:i,context:s}=this.deps,o=i.view(e);if(!o)return;let a=new _("New page like this",[{key:"name",label:"Path of the new page",value:j(o.raw.name)},{key:"language",label:"Language, such as fr-FR",value:o.language,required:!0},{key:"variant",label:"Variant (optional, empty for the default)",value:o.variant??""}],"Create page",d=>{let l=d.name??"",u=d.language??"",h=d.variant??"",f=o.raw.owner?.urn??s.company?.urn;if(!l.startsWith("/"))return a.setError("The path must start with /, like /blog/new-post.");if(wt(l))return a.setError(`Content has no index: give it a name of its own, without a trailing /, such as ${Ye(l)}.`);if(!u)return a.setError("Enter a language, such as fr-FR.");if(!f)return a.setError("No company was found to own the content.");a.setError(""),a.setBusy(!0,"Creating\u2026"),this.existing(l,u,h).then(p=>{if(p){a.setBusy(!1),a.setError(`${l} (${u}${h?` \xB7 ${h}`:""}) already exists. Change the path, language or variant.`);return}return t.createEntity({owner:{urn:f},status:"DRAFT_UNPUBLISHED",name:l,language:u,variant:h}).then(v=>(this.deps.created(v),this.copyItems(e,v.urn,l,0,{language:u,variant:h})))}).catch(p=>{a.setBusy(!1),a.setError(re(p,"create the page").message)})});n.show(a.element,{entityUrn:e})}async copyItems(e,t,n,i,s){let{transport:o,panels:a,store:d,registry:l}=this.deps,u=d.view(e),f=s&&(s.language.toLowerCase()!==u.language.toLowerCase()||s.variant!==(u.variant??""))?`${n} (${s.language}${s.variant?` \xB7 ${s.variant}`:""})`:n,p=l.flatMap(y=>(u.raw[y.entityArray]??[]).map(x=>[y,x])),v=c("p","hint");v.setAttribute("role","status");let m=c("div","simple-form");m.append(c("div","title",`Creating ${f}`),v),a.show(m,{entityUrn:e});for(let y=i;y<p.length;y+=1){let[x,b]=p[y];v.textContent=`Copying item ${y+1} of ${p.length}\u2026`;try{let k=x.renderedByView?M(x,await o.read(x,b.urn)):M(x,b),A={name:b.name,sortOrder:b.sortOrder};await o.create(x,Y(x,A,k,t))}catch(k){v.textContent=`Copied ${y} of ${p.length}. ${re(k,`copy ${b.name}`).message}`;let A=c("button","primary","Copy the rest");A.type="button",A.addEventListener("click",()=>{this.copyItems(e,t,n,y,s)}),m.append(ae(A));return}}let g=c("a","",`Open ${n}`);g.href=n,v.textContent=`Created ${f} in draft with ${p.length} items. Images need their files uploaded again. A site built ahead of time shows the page after its next build.`,m.append(ae(g))}async owners(){let e=this.deps.context.company?[this.deps.context.company]:[];try{let t=await this.deps.transport.companies(),n=this.deps.context.company?.urn;return t.length>0?[...t].sort((i,s)=>i.urn===n?-1:s.urn===n?1:0):e}catch{return e}}};function Jn(r){let e=c("div","simple-form"),t=c("pre","snippet",`<html data-entity-urn="${r}">`),n=c("button","","Copy");return n.type="button",n.addEventListener("click",()=>{navigator.clipboard?.writeText(`data-entity-urn="${r}"`).then(()=>n.textContent="Copied",()=>n.textContent="Select and copy it")}),e.append(t,ae(n)),e}function ae(...r){let e=c("div","actions");return e.append(...r),e}function Zn(r,e,t){let n=c("p","hint",e.note??"");n.setAttribute("role","status");let i=[n];for(let d of e.blockers)i.push(c("p","error",d));for(let d of e.warnings)i.push(c("p","issues",d));let s=c("ul","rows");s.setAttribute("aria-label","Changes that will go live");for(let d of e.changes){let l=c("li","row history-row"),u=c("div","row-main"),h=d.select?c("button","row-name link",d.name):c("span","row-name",d.name);h instanceof HTMLButtonElement&&(h.type="button",I(h,"Show its history"),h.addEventListener("click",()=>d.select?.())),u.append(h,c("span","meta",` #${d.sortOrder} \xB7 ${d.type}`),c("span",`status status-${d.kind==="changed"?"unpublished-changes":"note"}`,d.kind),...(d.notes??[]).map(f=>c("span","status note move",f))),l.append(u,me(d.change)),s.append(l)}e.changes.length===0&&i.push(c("p","hint","Nothing has changed since the last publish.")),i.push(s);let o=c("div","actions");if(t.schedule){let d=t.schedule,l=c("button","","Schedule\u2026");l.type="button",I(l,"Publish at a later time"),l.disabled=e.blockers.length>0,l.addEventListener("click",()=>d()),o.append(l)}let a=c("button","primary",e.confirmLabel);a.type="button",a.disabled=e.blockers.length>0,a.addEventListener("click",()=>t.confirm(a)),o.append(a),i.push(o),r.replaceChildren(...i)}function Xn(r,e,t,n){let i=c("p","hint","The content goes live by itself at this time. Until then it stays a draft, and you can cancel the schedule."),s=c("label","field"),o=c("input");o.type="datetime-local",s.append(c("span","caption","Publish at (your local time)"),o);let a=c("div","actions"),d=c("button","","Cancel");d.type="button",d.addEventListener("click",n);let l=c("button","primary",e);l.type="button",l.disabled=!0,o.addEventListener("input",()=>l.disabled=!o.value),l.addEventListener("click",()=>t(o.value,l)),a.append(d,l),r.replaceChildren(i,s,a)}var Qn=[1,2,4,8,15],Ze=class{ctx;stack;hooks;reviewing;view;tracked=new Map;stuckAfterMs;active=!1;constructor(e,t,n,i,s){this.ctx=e,this.view=t,this.stuckAfterMs=n,this.stack=i,this.hooks=s,window.addEventListener("focus",()=>{this.refreshAll()}),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&this.refreshAll()})}start(){this.active=!0,this.render()}stop(){this.active=!1;for(let e of this.tracked.values())clearTimeout(e.timer);this.tracked.clear(),this.reviewing=void 0,this.ctx.toolbar.setLifecycle([])}changed(){if(this.active){for(let e of this.ctx.store.entities()){let t=this.ctx.store.view(e)?.status;t&&this.observe(e,t)}this.render()}}async refreshAll(){this.active&&await Promise.all(this.ctx.store.entities().map(e=>this.refreshStatus(e)))}async refreshStatus(e){try{let t=await this.ctx.transport.readEntity(e);this.observe(e,t.status,t.publishTimestamp??void 0),this.render()}catch(t){this.ctx.feedback.report(t,"check the publishing status",()=>{this.refreshStatus(e)})}}observe(e,t,n){let i=this.ctx.store.view(e);if(i){let d=i.raw;d.status=t,n!==void 0&&(d.publishTimestamp=n)}let s=this.tracked.get(e),o=s?.status,a=s??{status:t,attempt:0};a.status=t,t==="PUBLISH"?(a.publishingSince??=Date.now(),this.poll(e,a)):(clearTimeout(a.timer),delete a.timer,delete a.publishingSince,a.attempt=0),this.tracked.set(e,a),o!==void 0&&o!==t&&(In({entityUrn:e,status:t,previous:o}),o==="PUBLISH"&&S(t)&&this.published(e))}published(e){Pn(e),this.ctx.announcePublished(e,`${this.ctx.entityTitle(e)} is published.`,{quiet:!0}),this.view.refresh(e)}poll(e,t){if(t.timer)return;let n=Qn[Math.min(t.attempt,Qn.length-1)];t.attempt+=1,t.timer=setTimeout(()=>{delete t.timer,this.active&&this.refreshStatus(e)},n*1e3)}render(){if(!this.active)return;let e=te(this.ctx.store,this.ctx.store.entities()).map(t=>this.row(t));this.ctx.toolbar.setLifecycle(e)}row(e){let{canPublish:t}=this.ctx,n=this.ctx.store.view(e),i=this.tracked.get(e)?.status??n?.status,s=this.ctx.entityTitle(e),o=t?"Publish\u2026":"Request approval\u2026",a=t?"Review and publish\u2026":"Request approval\u2026",d={entityUrn:e,title:s,label:ce(i),verbs:[]};switch(i){case"DRAFT_UNPUBLISHED":d.verbs.push({label:o,primary:!0,run:()=>{this.openReview(e)}});break;case"PUBLISH_PENDING":{let l=n?.raw.publishTimestamp;l&&(d.label=`Scheduled for ${new Date(C(l)).toLocaleString()}`),t&&d.verbs.push({label:"Cancel schedule",run:()=>this.confirmDraft(e,"Cancel the schedule?")});break}case"PUBLISH":{let l=this.tracked.get(e)?.publishingSince??Date.now();Date.now()-l>this.stuckAfterMs&&(d.note="Publishing is taking longer than expected. Publishing again is safe; if that does not help, contact support.",t&&d.verbs.push({label:"Publish again",run:()=>{this.setStatus(e,"PUBLISH",void 0)}}));break}case"PUBLISHED_WITH_DRAFTS":d.verbs.push({label:a,primary:!0,run:()=>{this.openReview(e)}}),t&&d.verbs.push({label:"Unpublish",run:()=>this.confirmDraft(e,"Unpublish this content?")});break;case"PUBLISHED":t&&d.verbs.push({label:"Unpublish",run:()=>this.confirmDraft(e,"Unpublish this content?")});break;default:break}return d}confirmDraft(e,t){this.hooks.show(_e({id:`draft:${e}`,title:t,meta:this.ctx.entityTitle(e),blocks:[],description:"The content stays in Baack but is no longer public. You can publish it again, now or at a later time.",choices:[{label:"Cancel",run:()=>this.stack.pop()},{label:"Back to draft",primary:!0,run:n=>{n.disabled=!0,this.setStatus(e,"DRAFT_UNPUBLISHED",void 0).then(i=>{i?this.stack.popTo(`entity:${e}`):n.disabled=!1})}}]}),e)}async openReview(e,t){let{store:n,views:i,canPublish:s}=this.ctx,o=n.view(e)?.status;if(o==="PUBLISH")return;let a;try{a=await i.read(e)}catch{a=void 0}let d=n.view(e).raw,l=ei(d,this.ctx.registry),u=await this.changes(e,d,a),{blockers:h,warnings:f}=await this.checks(d),p=`review:${e}`,v=`${u.length} ${u.length===1?"change":"changes"}`,m=this.reviewing?.id===p&&this.stack.path.includes(p)?this.reviewing:void 0,g=m?.body??c("div","level-review");if(Zn(g,{changes:u,blockers:h,warnings:f,confirmLabel:s?`Publish ${v}`:"Request approval",...t?{note:t}:{}},{confirm:x=>{this.confirm(e,l,u,void 0,x)},...s&&o==="DRAFT_UNPUBLISHED"?{schedule:()=>this.stack.push(this.scheduleLevel(e,l,u,`Schedule ${v}`))}:{}}),m){this.stack.popTo(p);return}this.reviewing={entityUrn:e,id:p,body:g};let y=this.ctx.entityTitle(e).replace(/^Content for /,"");this.hooks.show({id:p,title:`${s?"Review and publish":"Request approval for"} ${y}`,render:()=>g,dispose:()=>{this.reviewing?.body===g&&(this.reviewing=void 0)}},e)}scheduleLevel(e,t,n,i){let s=c("div","level-schedule");return Xn(s,i,(o,a)=>{this.confirm(e,t,n,o,a)},()=>this.stack.pop()),{id:`schedule:${e}`,title:"Schedule the publish",render:()=>s}}async confirm(e,t,n,i,s){let{views:o,feedback:a,canPublish:d}=this.ctx;s.disabled=!0;try{let l=await o.read(e,{version:"LATEST"}),u=ei(l,this.ctx.registry);if(u.size!==t.size||[...u].some(h=>!t.has(h))){await this.view.refresh(e),await this.openReview(e,"The content changed while you were reviewing. Check the list again before publishing.");return}if(d){let h=i?new Date(i).toISOString().replace("Z",""):void 0;if(!await this.setStatus(e,"PUBLISH",h)){s.disabled=!1;return}}else await this.requestApproval(e,n);this.stack.popTo(`entity:${e}`)}catch(l){s.disabled=!1,a.report(l,d?"publish":"request approval",()=>{this.confirm(e,t,n,i,s)})}}async setStatus(e,t,n){let{transport:i,feedback:s}=this.ctx;try{let o=await i.readEntity(e),a=await i.updateEntity(e,{owner:{urn:o.owner.urn},name:o.name,language:o.language,variant:o.variant??"",status:t,...n?{publishTimestamp:n}:{}}),d=this.tracked.get(e)?.status;return this.observe(e,a.status,a.publishTimestamp??void 0),t==="PUBLISH"&&d!=="PUBLISH"&&S(a.status)&&(a.status==="PUBLISHED"?this.published(e):(this.ctx.announcePublished(e,`${this.ctx.entityTitle(e)} was published, but some changes are still not live.`,{info:!1}),this.view.refresh(e))),this.render(),t==="DRAFT_UNPUBLISHED"&&await this.view.refresh(e),!0}catch(o){return s.report(o,t==="PUBLISH"?"publish":"move the content back to draft",()=>{this.setStatus(e,t,n)}),!1}}async requestApproval(e,t){let{transport:n,store:i,toolbar:s}=this.ctx,a=i.view(e).raw.owner?.urn,d=this.ctx.entityTitle(e).replace(/^Content for /,""),l=t.map(h=>`- ${h.name} #${h.sortOrder} (${h.type}): ${h.kind}`),u=await n.createTask({...a?{owner:{urn:a}}:{},title:`Review and publish ${d}`,description:[`Page: ${location.href}`,`Entity: ${e}`,"","Changes:",...l].join(`
|
|
16
|
-
`),status:"PENDING",priority:"MEDIUM",associatedEntities:[{urn:e}]});s.showMessage(`Approval requested (task ${u.urn?.slice(0,8)??""}).`,!0)}async changes(e,t,n){let i=(o,a)=>()=>a.urn?this.ctx.hooks.openHistory({entityUrn:e,entry:o,name:a.name,sortOrder:a.sortOrder,urn:a.urn}):void 0,s=[];for(let o of this.ctx.registry){let a=t[o.entityArray]??[],d=n?.[o.entityArray]??[],l=new Map(d.map(m=>[m.urn,m])),u=m=>`${m.name}#${m.sortOrder}`,h=new Map(d.map(m=>[u(m),m])),f=a.filter(m=>!l.has(m.urn)),p=await Promise.all(f.map(m=>this.liveVersionOf(o,m,l,h.get(u(m))))),v=new Set(a.filter(m=>l.has(m.urn)).map(m=>m.urn));f.forEach((m,g)=>{let y=p[g];y&&v.add(y.urn);let x=y?Ji(y,m):[],b=!y||!ge(o,M(o,y),M(o,m));s.push({name:m.name,sortOrder:m.sortOrder,type:o.label,kind:y?"changed":"new",change:b?ti(o,y,m):Yi(x.join("; ")),...b&&x.length>0?{notes:x}:{},select:i(o,m)})});for(let m of d)!v.has(m.urn)&&!a.some(g=>u(g)===u(m))&&s.push({name:m.name,sortOrder:m.sortOrder,type:o.label,kind:"removed",change:ti(o,m,void 0)})}return s}async liveVersionOf(e,t,n,i){try{let{history:s,pagination:o}=await this.ctx.transport.history(e,t.urn),a=s.find(d=>n.has(d.urn));return a?n.get(a.urn):o?.isMorePages?i:void 0}catch{return i}}async checks(e){let t=(e.images??[]).flatMap(i=>Et(i,this.ctx.requiredImageSlots).map(s=>`${i.name} #${i.sortOrder} has no ${s==="DEFAULT"?"image":s.toLowerCase()} file. Upload one before publishing.`)),n=[];for(let i of e.references??[]){let s=i.entityReference?.urn;if(s)try{let o=await this.ctx.transport.readEntity(s);(o.status==="DRAFT_UNPUBLISHED"||o.status==="PUBLISHED_WITH_DRAFTS")&&n.push(`${i.name} refers to content that ${o.status==="DRAFT_UNPUBLISHED"?"is not published":"has unpublished changes"} (${o.name}).`)}catch{n.push(`${i.name} refers to content that could not be checked.`)}}return{blockers:t,warnings:n}}};function Et(r,e){let t={DEFAULT:"src",MEDIUM:"mediumSrc",LARGE:"largeSrc"};return e.filter(n=>!r[t[n]])}function ei(r,e){let t=new Set;for(let n of e)for(let i of r[n.entityArray]??[])i.urn&&t.add(i.urn);return t}function ti(r,e,t){let n=o=>{let a=o?.value;if(typeof a=="string")return r.renderedByView?new DOMParser().parseFromString(a,"text/html").body.textContent??"":a},i=n(e),s=n(t);return i!==void 0||s!==void 0?Ne(i??"",s??""):e?t?Fe(r,e,t):`Removed: ${F(r,e)}`:F(r,t)}var Yi=r=>r.charAt(0).toUpperCase()+r.slice(1);function Ji(r,e){let t=[];r.name!==e.name&&t.push(`renamed from ${r.name}`);let n=e.sortOrder-r.sortOrder;return n!==0&&t.push(`moved #${r.sortOrder} \u2192 #${e.sortOrder} (${n>0?"+":"\u2212"}${Math.abs(n)})`),t}var Xe=class{stack;onOpen;constructor(e,t,n=()=>{}){this.onOpen=t,this.stack=new Ve(e),this.stack.element.classList.add("outline"),this.stack.onClose(n)}get element(){return this.stack.element}get isOpen(){return this.stack.isOpen}open(){this.stack.open(),this.onOpen()}close(){this.stack.close()}focusFilter(){this.element.querySelector('.stack-level:not([hidden]) input[type="search"]')?.focus()}renderSection(e,t){let n=e.querySelector('input[type="search"]')?.value??"",i=[];if(t.subtitle||t.verbs?.length){let o=c("div","level-lifecycle");if(o.setAttribute("role","group"),o.setAttribute("aria-label","Lifecycle"),t.subtitle&&o.append(c("p","section-status lifecycle-status",t.subtitle)),t.note&&o.append(c("p","message",t.note)),t.verbs?.length){let a=c("div","actions");a.append(...t.verbs.map(d=>this.button(d))),o.append(a)}i.push(o)}let s=c("input");s.type="search",s.placeholder="Filter by name or type",s.setAttribute("aria-label","Filter items"),s.value=n,s.addEventListener("input",()=>ni(e,s.value)),i.push(s);for(let o of t.groups){if(o.rows.length===0)continue;let a=c("div","outline-group"),d=c("div","group-heading");d.append(c("span","group-label",`${o.label} (${o.rows.length})`)),o.action&&d.append(this.button(o.action)),a.append(d),o.hint&&a.append(c("p","group-hint",o.hint));let l=c("ul","rows");l.setAttribute("aria-label",o.label),l.append(...o.rows.map(u=>this.row(u))),a.append(l),i.push(a)}if(t.actions.length>0){let o=c("div","actions");o.append(...t.actions.map(a=>this.button(a))),i.push(o)}e.replaceChildren(...i),ni(e,n),e.querySelector("li.row.current")?.scrollIntoView({block:"nearest"})}row(e){let t=c("li",e.current?"row current":"row");e.current&&t.setAttribute("aria-current","true"),t.dataset.filter=`${e.name} ${e.type}`.toLowerCase();let n=c(e.select?"button":"div","row-main");n instanceof HTMLButtonElement&&(n.type="button",n.dataset.row="",n.addEventListener("click",()=>e.select?.(t))),n.append(c("span","row-name",e.name),c("span","meta",` #${e.sortOrder} \xB7 ${e.type}`),...e.status?[c("span",`status status-${e.status.replace(/\s+/g,"-")}`,e.status)]:[],...(e.notes??[]).map(i=>c("span","status note",i))),t.append(n);for(let i of e.flags)t.append(c("span","flag",i));e.action&&t.append(this.button(e.action));for(let i of e.actions??[])t.append(this.button(i));return t}button(e){let t=T(e.label,W(e),"sm");return e.disabled&&(t.disabled=!0,t.title=e.disabled),t.addEventListener("click",()=>e.run(t)),t}};function ni(r,e){let t=e.trim().toLowerCase();for(let n of r.querySelectorAll("li.row"))n.hidden=t!==""&&!n.dataset.filter.includes(t)}var Zi=/<\/?[a-z!][^>]*>/i,Qe=class{outline;ctx;view;editing;saving;onboarding;live=new Map;focus;selected;levels=new Map;closed;panels=0;newEntity;constructor(e,t,n,i,s){this.ctx=e,this.view=t,this.editing=n,this.saving=i,this.onboarding=s,this.outline=new Xe(e.host,()=>{this.outline.stack.path.length===0?this.openAt(ee(e.store),{focus:!1}):this.render()},()=>{this.focus=void 0,this.selected=void 0,this.closed?.()})}onClose(e){this.closed=e}changed(e){e&&this.live.delete(e),this.outline.isOpen&&this.render()}clear(){this.outline.close(),this.outline.stack.reset([]),this.levels.clear(),this.live.clear(),this.focus=void 0}setNewEntity(e){this.newEntity=e,this.outline.isOpen&&this.render()}toggle(){this.outline.isOpen?this.outline.close():this.outline.open()}openEntity(e){this.selected=void 0,this.focus=void 0,this.openAt(e)}selectItem(e){this.focus=void 0,this.selected={entityUrn:e.entityUrn,entry:e.entry,name:e.name,sortOrder:e.sortOrder},this.openAt(e.entityUrn)}focusSlot(e){this.focus={entityUrn:e.entityUrn,entry:e.entry,name:e.name,sortOrder:e.sortOrder},this.openAt(e.entityUrn,{slots:!0})}showAbove(e,t){let{stack:n}=this.outline,i=[`entity:${e}`,`review:${e}`];if(this.outline.isOpen&&i.includes(n.current?.id??"")){n.push(t);return}this.focus=void 0,this.selected=void 0,this.openAt(e,{above:t})}showPanel(e,t={}){let{stack:n}=this.outline,i=e.querySelector(":scope > .title"),s=t.title??i?.textContent??"Editor";t.title||i?.remove(),this.panels+=1;let o=`panel:${this.panels}`,a=!0,d={id:o,title:s,render:()=>e,dispose:()=>{a=!1,t.onLeave?.()}},l={get isOpen(){return a},close:()=>{let f=n.path,p=f.indexOf(o);p>0&&n.popTo(f[p-1])}};e.addEventListener("cancel",()=>l.close());let u=t.focus??!0,h=this.outline.isOpen&&n.path.length>0;return h&&n.current?.id.startsWith("panel:")?n.replace(d,{focus:u}):h&&(!t.entityUrn||n.path.includes(`entity:${t.entityUrn}`))?n.push(d,{focus:u}):(this.focus=void 0,this.selected=void 0,this.openAt(t.entityUrn,{above:d,focus:u})),l}openAt(e,{slots:t=!1,focus:n=!0,above:i=void 0}={}){let s=[this.pageLevel()];e&&this.ctx.store.view(e)&&s.push(this.entityLevel(e)),t&&this.focus&&s.push(this.slotsLevel(this.focus)),i&&s.push(i),this.outline.stack.reset(s,{focus:n}),this.outline.open(),this.render()}async render(){this.outline.isOpen&&await Promise.all(this.outline.stack.path.map(e=>this.levels.get(e)?.refresh()))}remember(e,t,n){return this.levels.set(e.id,{level:e,body:t,refresh:n}),e}pageLevel(){let e=c("div","level-page"),t={id:"page",title:"This page",render:()=>e};return this.remember(t,e,()=>{let{store:n,toolbar:i}=this.ctx,s=te(n,n.entities()),o=s.map(a=>Dn(this.ctx.entityTitle(a),i.lifecycleOf(a)?.label??ce(n.view(a)?.status),()=>this.outline.stack.push(this.entityLevel(a))));if(s.length===0&&o.push(c("p","hint","No content has loaded for this page.")),this.newEntity){let a=this.newEntity,d=c("button","","New entity\u2026");d.type="button",I(d,"Create an entity, such as a menu shared by many pages"),d.addEventListener("click",()=>a());let l=c("div","actions");l.append(d),o.push(l)}e.replaceChildren(...o)})}entityLevel(e){let t=`entity:${e}`,n=this.levels.get(t);if(n)return n.level;let i=c("div","level-entity"),s={id:t,title:this.ctx.entityTitle(e),render:()=>i,onShow:()=>{this.render()}};return this.remember(s,i,async()=>{if(!this.ctx.store.view(e))return;let o=await this.section(e,e===ee(this.ctx.store));this.outline.stack.path.includes(t)&&this.outline.renderSection(i,o)})}togglePending(){if(this.outline.isOpen&&this.outline.stack.current?.id==="unsaved"){this.outline.close();return}this.focus=void 0,this.selected=void 0,this.outline.stack.reset([this.pageLevel(),this.pendingLevel()]),this.outline.open()}pendingLevel(){let e=c("div","level-unsaved"),t={id:"unsaved",title:"Unsaved changes",render:()=>e};return this.remember(t,e,()=>e.replaceChildren(...this.ctx.toolbar.pendingSections()))}slotsLevel(e){let t=c("div","level-slots"),n={id:"slots",title:`Slots for ${e.name}`,render:()=>t};return this.remember(n,t,()=>{!this.focus||!this.ctx.store.view(this.focus.entityUrn)||this.outline.renderSection(t,this.slotsSection(this.focus))})}slotsSection(e){let{store:t,hooks:n}=this.ctx,{entityUrn:i,entry:s,name:o}=e,a=(t.view(i).raw[s.entityArray]??[]).filter(h=>h.name===o&&h.urn).sort((h,f)=>h.sortOrder-f.sortOrder),d=a.find(h=>h.sortOrder===e.sortOrder),l=async h=>{d&&await n.moveSlot(e,d,h)&&(this.focus={...e,sortOrder:h},this.render())},u=a.map(h=>h===d?{name:o,sortOrder:h.sortOrder,type:s.label,status:"moving",flags:[],current:!0,actions:[{label:"Rename\u2026",run:()=>n.rename(e,h)}]}:{name:o,sortOrder:h.sortOrder,type:s.label,status:"",flags:[],...d?{actions:[{label:`Swap with #${d.sortOrder}`,run:()=>{l(h.sortOrder)}}]}:{}});if(d){let h=new Set(a.map(m=>m.sortOrder)),f=a[0]?.sortOrder??0,p=a.at(-1)?.sortOrder??0,v=Array.from({length:Math.max(0,p-f)},(m,g)=>f+g).filter(m=>!h.has(m));for(let m of[...v.length<=5?v:[],p+1])u.push({name:o,sortOrder:m,type:s.label,status:"empty",flags:[],actions:[{label:"Move here",run:()=>{l(m)}}]});u.sort((m,g)=>m.sortOrder-g.sortOrder)}return{subtitle:d?`Moving ${o} #${d.sortOrder}. Swap it with another, move it to a free sort order, or rename it.`:`${o} #${e.sortOrder} is no longer here.`,groups:[{label:`Slots for ${o}`,rows:u}],actions:[{label:"Show all items",run:()=>{this.focus=void 0,this.outline.stack.popTo(`entity:${i}`)}}]}}async section(e,t){let{store:n,pending:i,registry:s}=this.ctx,o=n.view(e),{urns:a,found:d}=await this.counterpartUrns(e),l=this.view.mode==="live"?!this.view.draftsOnLivePage.has(e):S(o.status)||d,u=[],h=[],f=[];for(let m of s){let g=o.raw[m.entityArray]??[];for(let y of g){if(!y.urn)continue;let x={entityUrn:e,entry:m,name:y.name,sortOrder:y.sortOrder},b=this.view.bindingsAt(x),k=b.filter(q=>!q.element.closest("head")),A=g.filter(q=>q.name===y.name&&q.sortOrder===y.sortOrder).length,K=y.urn,at={name:y.name,sortOrder:y.sortOrder,type:m.label,status:i.getEdit(K)?"unsaved":l?a.has(K)?"up to date":"unpublished changes":"",flags:[...Xi(m,y,A,this.ctx.requiredImageSlots),...b.some(q=>q.element.hasAttribute("data-text-unsafe-literal"))?["the site renders this as HTML"]:[]],action:{label:"History",run:()=>this.ctx.hooks.openHistory({...x,urn:K})},...this.referenceAction(y),current:ii(this.selected,x),select:q=>{let Ot={...x,urn:K,anchor:q,binding:k[0]};k[0]&&k[0].element.scrollIntoView({block:"center"}),this.editing.open(k[0]&&k[0].element.getClientRects().length>0?Ot:{...Ot,binding:void 0})}};k.length>0?u.push(at):b.length>0||!m.component?h.push(at):f.push({...at,notes:["not used"]})}}let p=this.view.missingBindings(e).map(m=>{let g=$({entityUrn:e,type:m.entry.type,name:m.name,sortOrder:m.sortOrder});return{name:m.name,sortOrder:m.sortOrder,type:m.entry.label,status:i.getCreate(g)?"unsaved":"not in content",flags:[],current:ii(this.selected,{entityUrn:e,entry:m.entry,name:m.name,sortOrder:m.sortOrder}),action:{label:"Create",run:y=>{m.element.getClientRects().length>0&&m.element.scrollIntoView({block:"center"}),this.editing.open({entityUrn:e,entry:m.entry,name:m.name,sortOrder:m.sortOrder,anchor:y,binding:m})}}}}),v=this.ctx.toolbar.lifecycleOf(e);return{subtitle:v?.label??ce(o.status),...v?.note?{note:v.note}:{},verbs:(v?.verbs??[]).map(m=>({label:m.label,run:()=>m.run(),...m.primary?{primary:!0}:{},...m.disabled?{disabled:m.disabled}:{}})),groups:[{label:"On this page",rows:u},{label:"Page settings",rows:h},{label:"Not used on this page",rows:f,hint:"In the content, but nothing on this page shows them."},{label:"In the page, not in the content",rows:p,hint:"Content items on the page that are not saved in the content yet. Each shows its placeholder until it is created.",action:{label:"Create all",run:()=>this.saving.confirmCreateAll(e,p.length)}}],actions:[{label:"Add item",run:m=>this.showAddItem(e,m)},...t?[{label:"New page like this",run:()=>this.onboarding.offerNewPageLike(e)}]:[]]}}referenceAction(e){let t=e.entityReference?.urn;return!t||!this.ctx.store.view(t)?{}:{actions:[{label:`${this.ctx.entityTitle(t)} \u203A`,run:()=>this.outline.stack.push(this.entityLevel(t))}]}}counterpartUrns(e){let t=this.live.get(e);return t||(t=this.ctx.views.read(e,this.view.mode==="live"?{version:"LATEST"}:{}).then(n=>{let i=new Set;for(let s of this.ctx.registry)for(let o of n[s.entityArray]??[])o.urn&&i.add(o.urn);return i}).then(n=>({urns:n,found:!0})).catch(()=>({urns:new Set,found:!1})),this.live.set(e,t)),t}showAddItem(e,t){let{store:n,registry:i}=this.ctx,s=new _(`Add an item to ${this.ctx.entityTitle(e)}`,[{key:"type",label:"Type",value:"text",options:i.map(a=>({value:a.type,label:a.label}))},{key:"name",label:"Name",value:""},{key:"sortOrder",label:"Sort order",value:"0"}],"Next",a=>{let d=this.ctx.entry(a.type),l=a.name??"",u=Number(a.sortOrder);if(!/^[A-Za-z0-9_-]+$/.test(l))return s.setError("Use letters, numbers, - and _ in the name.");if(!Number.isInteger(u))return s.setError("The sort order must be a whole number.");s.setBusy(!0,"Checking\u2026"),this.view.refresh(e).then(()=>{if(s.setBusy(!1),n.itemAt(e,d,l,u)){s.setError(`An item already exists at ${l} #${u}. Choose a free sort order.`);return}o.close(),this.editing.open({entityUrn:e,entry:d,name:l,sortOrder:u,anchor:t,binding:void 0})})}),o=this.ctx.panels.show(s.element,{entityUrn:e})}};function Xi(r,e,t,n){let i=[];t>1&&i.push(`${t} items share this sort order`);let s=e;if(r.type==="text"&&Zi.test(String(s.value??""))&&i.push("contains markup"),r.type==="image"){s.altText||i.push("no alt text");for(let o of Et(e,n))i.push(o==="DEFAULT"?"no image file":`no ${o.toLowerCase()} file`)}return i}function ii(r,e){return r!==void 0&&r.entityUrn===e.entityUrn&&r.entry===e.entry&&r.name===e.name&&r.sortOrder===e.sortOrder}var kt="A site that is built ahead of time shows it to visitors after its next build.";function xt(r){return typeof r=="string"?r:void 0}async function ri(r,e,t,n,{info:i=!0,quiet:s=!1}={}){let o=(a,d)=>s?r.announce(n,a,d):r.showMessage(a?`${n} ${a}`:n,d);if(o("",i),e!==void 0)try{let a=typeof e=="string"?e:await e(t);a&&o(a,i)}catch(a){console.error("Baack editor: the site's afterPublish callback failed",a);let d=a instanceof Error?a.message:String(a);o(`The site's after-publish step failed: ${d}`,!1)}}var Lt=50,Qi=0;function Tt(r){return`${r.path} (${r.language}${r.variant?` \xB7 ${r.variant}`:""})`}var et=class{element;input;value;source;onChange;listbox;status;note;createArea;id=`baack-entity-picker-${Qi+=1}`;listing;created=[];loading;options=[];active=-1;chosenLabel="";constructor(e,t,n,i){this.source=e,this.onChange=i,this.element=c("div","entity-picker"),this.input=c("input"),this.input.type="text",this.input.autocomplete="off",this.input.spellcheck=!1,this.input.placeholder="Type a path, such as /menu",this.input.setAttribute("role","combobox"),this.input.setAttribute("aria-autocomplete","list"),this.input.setAttribute("aria-expanded","false"),this.input.setAttribute("aria-controls",`${this.id}-list`),this.value=c("input"),this.value.type="hidden",this.value.name=t,this.value.value=n,this.listbox=c("ul","entity-options"),this.listbox.id=`${this.id}-list`,this.listbox.setAttribute("role","listbox"),this.listbox.setAttribute("aria-label","Entities"),this.listbox.hidden=!0,this.status=c("p","hint"),this.status.setAttribute("role","status"),this.note=c("p","hint"),this.createArea=c("div","entity-create");let s=c("div","combobox-field");s.append(L("search"),this.input,L("chevron-down")),this.element.append(s,this.listbox,this.status,this.note,this.createArea,this.value),this.input.addEventListener("focus",()=>this.open()),this.input.addEventListener("input",()=>this.open()),this.input.addEventListener("keydown",this.onKeyDown),this.input.addEventListener("blur",()=>{this.close(),this.input.value!==this.chosenLabel&&(this.input.value=this.chosenLabel)}),n&&this.showChosen(n)}async showChosen(e){this.chosenLabel=e,this.input.value=e;try{let t=await this.source.describe(e);if(this.value.value!==e)return;this.chosenLabel=Tt(t),this.input.value===e&&(this.input.value=this.chosenLabel)}catch(t){this.source.report(t,"show the entity referred to",()=>{this.showChosen(e)})}this.showNote(e)}async showNote(e){try{let t=await this.source.note(e);this.value.value===e&&(this.note.textContent=t)}catch(t){this.source.report(t,"check the entity referred to",()=>{this.showNote(e)})}}open(){this.listbox.hidden=!1,this.input.setAttribute("aria-expanded","true"),this.loading??=this.source.list(e=>{this.listing=e,this.render()}).then(e=>{this.listing=e,this.render()}).catch(e=>{this.loading=void 0,this.status.textContent="The list of entities could not be loaded.",this.source.report(e,"list the entities",()=>this.open())}),this.render()}close(){this.listbox.hidden=!0,this.input.setAttribute("aria-expanded","false"),this.input.removeAttribute("aria-activedescendant"),this.active=-1}render(){if(this.listbox.hidden)return;let e=this.input.value===this.chosenLabel?"":this.input.value.trim().toLowerCase(),t=this.listing?.entities??[],n=[...t,...this.created.filter(d=>!t.some(l=>l.urn===d.urn))].filter(d=>!e||Tt(d).toLowerCase().includes(e)).sort((d,l)=>d.path===l.path?+(l.language===this.source.language)-+(d.language===this.source.language):0);this.options=n.slice(0,Lt).map(d=>{let l=c("li","entity-option");l.append(c("span","",d.path),c("span","meta",` ${d.language}${d.variant?` \xB7 ${d.variant}`:""}`));let u=d.urn===this.value.value;return l.setAttribute("aria-selected",String(u)),u&&l.append(L("check")),{element:l,choose:()=>this.choose(d)}});let i=this.input.value.trim(),s=e&&i.startsWith("/")?i:e?`/${i}`:"",o=c("li","entity-option create",s?`Create a new entity "${s}"\u2026`:"Create a new entity\u2026");o.prepend(L("plus")),this.options.push({element:o,choose:()=>{this.create(s)}}),this.options.forEach((d,l)=>{d.element.id=`${this.id}-option-${l}`,d.element.setAttribute("role","option"),d.element.addEventListener("mousedown",u=>u.preventDefault()),d.element.addEventListener("click",()=>d.choose())}),this.listbox.replaceChildren(...this.options.map(d=>d.element)),this.setActive(Math.min(this.active,this.options.length-1));let a=t.length+this.created.length;this.status.textContent=this.listing?[n.length>Lt?`Showing ${Lt} of ${n.length}; type to narrow.`:"",this.listing.complete?"":"The search was still running, so some entities may be missing.",a===0?"No entities found.":""].filter(Boolean).join(" "):"Loading entities\u2026"}setActive(e){this.active=e,this.options.forEach((n,i)=>n.element.classList.toggle("active",i===e));let t=this.options[e];t?(this.input.setAttribute("aria-activedescendant",t.element.id),t.element.scrollIntoView({block:"nearest"})):this.input.removeAttribute("aria-activedescendant")}choose(e){this.value.value=e.urn,this.chosenLabel=Tt(e),this.input.value=this.chosenLabel,this.note.textContent="",this.close(),this.onChange(),this.showNote(e.urn)}async create(e){this.close(),this.input.disabled=!0;try{let t=await this.source.create(this.createArea,e);t&&(this.created.push(t),this.choose(t))}finally{this.createArea.replaceChildren(),this.input.disabled=!1,this.input.focus()}}onKeyDown=e=>{let t=!this.listbox.hidden;if(e.key==="ArrowDown"||e.key==="ArrowUp"){e.preventDefault(),t||this.open();let n=e.key==="ArrowDown"?1:-1;this.setActive((this.active+n+this.options.length)%this.options.length)}else e.key==="Enter"&&t&&this.active>=0&&!(e.metaKey||e.ctrlKey)?(e.preventDefault(),e.stopPropagation(),this.options[this.active]?.choose()):e.key==="Escape"&&t&&(e.preventDefault(),e.stopPropagation(),this.close())}};var er=0,tt=class{trigger;items;menu;constructor(e,t){this.trigger=e,this.items=t,e.id||=`baack-menu-trigger-${++er}`,e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded","false"),e.addEventListener("mousedown",n=>n.preventDefault()),e.addEventListener("click",n=>this.menu?this.close(!0):this.open(n.detail===0?"first":void 0)),e.addEventListener("keydown",n=>{(n.key==="ArrowDown"||n.key==="ArrowUp")&&(n.preventDefault(),this.open(n.key==="ArrowDown"?"first":"last"))})}get isOpen(){return this.menu!==void 0}open(e){this.close(!1);let t=c("div","menu");t.setAttribute("role","menu"),t.setAttribute("aria-labelledby",this.trigger.id);for(let n of this.items()){let i=c("button",n.destructive?"menu-item destructive":"menu-item");i.type="button",i.setAttribute("role","menuitem"),i.tabIndex=-1,n.icon&&i.append(L(n.icon)),i.append(n.label),i.addEventListener("mousedown",s=>s.preventDefault()),i.addEventListener("click",()=>{this.close(i.matches(":focus")),n.run()}),t.append(i)}t.addEventListener("keydown",this.onKey),(this.trigger.closest(".panel")??this.trigger.parentElement).append(t),this.menu=t,this.trigger.setAttribute("aria-expanded","true"),this.trigger.setAttribute("aria-controls",t.id=`${this.trigger.id}-list`),this.place(),window.addEventListener("pointerdown",this.onOutside,!0),window.addEventListener("scroll",this.onScroll,!0),window.addEventListener("resize",this.onScroll),e&&this.focusAt(e==="first"?0:-1)}close(e){this.menu&&(this.menu.remove(),this.menu=void 0,this.trigger.setAttribute("aria-expanded","false"),this.trigger.removeAttribute("aria-controls"),window.removeEventListener("pointerdown",this.onOutside,!0),window.removeEventListener("scroll",this.onScroll,!0),window.removeEventListener("resize",this.onScroll),e&&this.trigger.focus())}entries(){return[...this.menu?.querySelectorAll('[role="menuitem"]')??[]]}focusAt(e){let t=this.entries(),n=t.at(e%t.length);for(let i of t)i.tabIndex=i===n?0:-1;n?.focus()}onKey=e=>{let t=this.entries(),n=t.indexOf(e.target);if(e.key==="Escape")e.preventDefault(),e.stopPropagation(),this.close(!0);else if(e.key==="Tab")e.preventDefault(),this.close(!0);else if(e.key==="ArrowDown"||e.key==="ArrowUp")e.preventDefault(),this.focusAt((n+(e.key==="ArrowDown"?1:-1)+t.length)%t.length);else if(e.key==="Home"||e.key==="End")e.preventDefault(),this.focusAt(e.key==="Home"?0:-1);else if(e.key.length===1&&/\S/.test(e.key)){let i=e.key.toLowerCase();for(let s=1;s<=t.length;s++){let o=(n+s)%t.length;if(t[o].textContent.trim().toLowerCase().startsWith(i)){this.focusAt(o);break}}}};onOutside=e=>{let t=e.composedPath();!t.includes(this.menu)&&!t.includes(this.trigger)&&this.close(!1)};onScroll=e=>{e.type==="scroll"&&this.menu&&e.composedPath().includes(this.menu)||this.close(!1)};place(){let e=this.menu,t=this.trigger.getBoundingClientRect();e.style.minWidth=`${Math.max(t.width,128)}px`;let{width:n,height:i}=e.getBoundingClientRect(),s=t.bottom+4,o=s+i<=window.innerHeight-8||t.top-i-4<8?s:t.top-i-4;e.style.top=`${Math.max(8,o)}px`,e.style.left=`${Math.min(Math.max(8,t.right-n),window.innerWidth-n-8)}px`}};var tr=["GBP","EUR","USD","JPY","CHF","CAD","AUD","NZD","SEK","NOK","DKK","PLN","INR","CNY","BRL"],nr=/Mac|iPhone|iPad/.test(navigator.userAgent),nt=class{element;title;form;description;issues;error;errorDebug;sendButton;extras;menu;buttons;choices;hint;anchor;actions;inputs=new Map;slotStatus=new Map;reposition=()=>this.place();side;onEnd;anchorObserver=new ResizeObserver(this.reposition);entities;currentValues={};constructor(e){this.element=c("div","panel popover"),this.element.setAttribute("role","dialog"),this.element.hidden=!0,this.title=c("div","title"),this.form=c("div","form"),this.description=c("p","hint"),this.issues=c("ul","issues"),this.error=c("p","error"),this.error.setAttribute("role","alert"),this.errorDebug=c("div","error-debug");let t=c("button","","Revert");t.type="button",this.sendButton=c("button","primary","Save"),this.sendButton.type="button";for(let n of[t,this.sendButton])n.addEventListener("mousedown",i=>i.preventDefault());t.addEventListener("click",()=>this.actions?.revert()),this.sendButton.addEventListener("click",()=>this.actions?.send()),this.element.addEventListener("keydown",n=>{n.key==="Escape"?(n.preventDefault(),this.actions?.revert()):n.key==="Enter"&&(n.metaKey||n.ctrlKey)&&(n.preventDefault(),this.actions?.send())}),this.extras=c("div","extras"),this.buttons=c("div","actions"),this.buttons.append(t,this.sendButton),this.choices=c("div","actions"),this.choices.hidden=!0,this.hint=c("p","hint"),this.element.append(this.title,this.form,this.description,this.issues,this.error,this.errorDebug,this.extras,this.buttons,this.choices,this.hint),e.root.append(this.element),new ResizeObserver(()=>{this.element.hidden||(this.side=void 0,this.place())}).observe(this.element)}setEntitySource(e){this.entities=e}get isOpen(){return!this.element.hidden}show(e,t,n,i,s){this.open(e,t,n,i,s,!1),this.form.replaceChildren(),this.inputs.clear(),this.place()}showForm(e,t,n,i,s,o,a){this.open(e,t,n,`${nr?"\u2318":"Ctrl"}+Enter to save \xB7 Esc to revert`,o,a),this.inputs.clear(),this.slotStatus.clear(),this.currentValues=s,this.form.replaceChildren(...i.map(d=>this.field(d,s[d.key],()=>o.input(this.values())))),this.place(),this.form.querySelector('input:not([type="hidden"]), textarea, select')?.focus()}showChoices(e,t,n,i,s,o){this.open(e,t,n,"",{send:()=>{},revert:()=>o.at(-1)?.run()},!0),this.inputs.clear(),this.form.replaceChildren(...i.map(a=>{let d=c("div","field");return d.append(c("span","caption",a.label),c("pre","snippet",a.text)),d})),this.setDescription(s),this.buttons.hidden=!0,this.choices.hidden=!1,this.choices.replaceChildren(...o.map(a=>{let d=T(a.label,W(a));return d.addEventListener("click",()=>a.run()),d})),this.place()}whenEnded(e){this.onEnd=e}ended(){let e=this.onEnd;this.onEnd=void 0,e?.()}hide(){this.ended(),this.menu?.close(!1),this.element.hidden=!0,this.anchor=void 0,this.side=void 0,this.anchorObserver.disconnect(),this.actions=void 0,window.removeEventListener("scroll",this.reposition,!0),window.removeEventListener("resize",this.reposition),window.removeEventListener("keydown",this.onWindowKey)}onWindowKey=e=>{e.key!=="Escape"||e.defaultPrevented||this.element.hidden||(e.preventDefault(),this.actions?.revert())};values(){let e={...this.currentValues};for(let[t,n]of this.inputs)n instanceof HTMLInputElement&&n.type==="file"?e[t]=n.files?.[0]?.name??"":e[t]=n instanceof HTMLInputElement&&n.type==="checkbox"?n.checked:n.value;return e}files(){let e=new Map;for(let[t,n]of this.inputs){let i=n instanceof HTMLInputElement&&n.type==="file"?n.files?.[0]:void 0;i&&e.set(t,i)}return e}setSlotStatus(e,t,n=!1){let i=this.slotStatus.get(e);i&&(i.textContent=t,i.classList.toggle("error",n))}setValues(e){for(let[t,n]of this.inputs){let i=e[t];n instanceof HTMLInputElement&&n.type==="checkbox"?n.checked=i===!0:n.type!=="file"&&(n.value=typeof i=="string"?i:"")}}setNameAction(e){let t=this.title.querySelector(".meta");if(!t||!e)return;let n=c("button","meta link",t.textContent??"");n.type="button",I(n,"Show in Items"),n.addEventListener("mousedown",i=>i.preventDefault()),n.addEventListener("click",e),t.replaceWith(n)}setExtras(e){this.menu?.close(!1),this.menu=void 0;let t=e.filter(i=>!i.menu),n=e.filter(i=>i.menu);if(this.extras.replaceChildren(...t.map(i=>{let s=T(i.label,"ghost","sm");return i.icon&&s.prepend(L(i.icon)),s.addEventListener("mousedown",o=>o.preventDefault()),s.addEventListener("click",()=>i.run()),s})),n.length>0){let i=T("","ghost","icon-sm");i.setAttribute("aria-label","More actions"),i.append(L("ellipsis")),this.extras.append(i),I(i),this.menu=new tt(i,()=>n)}}setDescription(e){this.description.textContent=e}setIssues(e){this.issues.replaceChildren(...e.map(t=>c("li",t.level,t.message)))}setError(e,t){this.error.textContent=e,this.errorDebug.replaceChildren(...Z(t))}setSending(e){this.sendButton.disabled=e,this.sendButton.textContent=e?"Saving\u2026":"Save"}open(e,t,n,i,s,o){this.ended(),e!==this.anchor&&(this.side=void 0),this.anchor=e,this.anchorObserver.disconnect(),this.anchorObserver.observe(e),this.actions=s,this.title.textContent=`${t} `,this.title.append(c("span","meta",n)),this.element.setAttribute("aria-label",`Edit ${t.toLowerCase()} ${n}`),this.element.classList.toggle("wide",o),this.buttons.hidden=!1,this.choices.hidden=!0,this.setExtras([]),this.hint.textContent=i,this.setDescription(""),this.setIssues([]),this.setError(""),this.setSending(!1),this.element.hidden=!1,window.addEventListener("scroll",this.reposition,!0),window.addEventListener("resize",this.reposition),window.addEventListener("keydown",this.onWindowKey)}field(e,t,n){let i=c("label",`field ${e.kind}`),s=c("span","caption",e.label),o;if(e.kind==="file"){o=c("input"),o.type="file",o.accept="image/apng,image/avif,image/gif,image/jpeg,image/png,image/svg+xml,image/webp",o.name=e.key;let a=typeof this.currentValues[`${e.key}:current`]=="string"?this.currentValues[`${e.key}:current`]:"",d=c("div","slot-preview");if(a){let u=c("img");u.src=a,u.alt="",d.append(u,c("span","meta",a))}else d.append(c("span","meta","No file"));let l=c("span","hint");return l.setAttribute("role","status"),this.slotStatus.set(e.key,l),o.addEventListener("change",n),this.inputs.set(e.key,o),i.append(s,d,o,l),i}if(e.kind==="entity"&&this.entities){let a=c("div","field entity");s.id=`baack-field-${e.key}`;let d=new et(this.entities,e.key,typeof t=="string"?t:"",n);return d.input.setAttribute("aria-labelledby",s.id),this.inputs.set(e.key,d.value),a.append(s,d.element),a}if(e.kind==="textarea"||e.kind==="code")o=c("textarea"),o.rows=e.kind==="code"?12:4,o.spellcheck=e.kind!=="code";else{if(o=c("input"),o.type=e.kind==="checkbox"?"checkbox":e.kind==="datetime"?"datetime-local":e.kind==="url"?"url":"text",e.kind==="integer"&&(o.inputMode="numeric"),e.kind==="decimal"&&(o.inputMode="decimal"),e.kind==="currency"){o.maxLength=3,o.autocapitalize="characters";let a=c("datalist");a.id=`baack-currencies-${e.key}`,a.append(...tr.map(d=>Object.assign(c("option"),{value:d}))),o.setAttribute("list",a.id),i.append(a)}e.kind==="url"&&this.entities&&i.append(this.pathSuggestions(o,e.key))}return o instanceof HTMLInputElement&&o.type==="checkbox"?(o.setAttribute("role","switch"),o.className="switch",o.checked=t===!0,i.append(o,s)):(o.value=typeof t=="string"?t:"",i.append(s,o)),o.name=e.key,o.addEventListener("input",n),o.addEventListener("change",n),this.inputs.set(e.key,o),i}pathSuggestions(e,t){let n=c("datalist");n.id=`baack-paths-${t}`,e.setAttribute("list",n.id);let i=({entities:s})=>n.replaceChildren(...[...new Set(s.map(o=>this.entities.pagePath(o.path)))].map(o=>Object.assign(c("option"),{value:o})));return e.addEventListener("focus",()=>{this.entities?.list(i).then(i,()=>{})},{once:!0}),n}place(){if(!this.anchor)return;let e=this.anchor.getBoundingClientRect();if(!this.anchor.getClientRects().length&&this.side)return;let t=this.element.offsetHeight,n=this.element.offsetWidth,i=this.anchor.closest(".panel");if(i&&i!==this.element){let a=i.getBoundingClientRect();this.element.style.left=`${Math.max(8,a.left-n-8)}px`,this.element.style.top=`${Math.max(8,Math.min(e.top,window.innerHeight-t-8))}px`;return}this.side??=e.bottom+8+t<=window.innerHeight?"below":e.top-t-8>=8?"above":"within";let s=this.side==="below"?Math.max(8,e.bottom+8):this.side==="above"?Math.min(e.top-t-8,window.innerHeight-t-8):Math.max(8,Math.min(e.bottom+8,window.innerHeight-t-8)),o=Math.max(8,Math.min(e.left,window.innerWidth-n-8));this.element.style.top=`${s}px`,this.element.style.left=`${o}px`}};var it=class{modeButton;itemsButton;readButton;pendingButton;message;messageAction;runMessageAction;messageDebug;entities;lifecycleRows=[];pendingGroups=[];openPending;pendingListeners=[];openEntity;lifecycleListeners=[];login;loginFrame;loginText;pendingActions;constructor(e,t,n){this.pendingActions=n,this.modeButton=Ct(e);let i=this.modeButton.closest(".toolbar"),s=this.modeButton.parentElement;this.itemsButton=c("button","","Items"),this.itemsButton.type="button",I(this.itemsButton,"Every item on this page (Alt+Shift+I)"),this.itemsButton.hidden=!0,this.pendingButton=c("button","pending"),this.pendingButton.type="button",this.pendingButton.hidden=!0,I(this.pendingButton,"Show them in the sidebar, with Save all and Discard all"),this.pendingButton.addEventListener("click",()=>this.openPending?.()),this.readButton=c("button","","Show live page"),this.readButton.type="button",this.readButton.hidden=!0,s.append(this.itemsButton,this.readButton,this.pendingButton),this.message=c("p","message"),this.message.setAttribute("role","status"),this.messageAction=T("","primary","sm","message-action"),this.messageAction.hidden=!0,this.messageAction.addEventListener("click",()=>{let a=this.runMessageAction;this.showMessage(""),a?.()}),this.messageDebug=c("div","message-debug"),this.entities=c("div","entities"),this.login=c("div","login"),this.login.hidden=!0,this.loginText=c("p","message"),this.loginText.setAttribute("role","alert"),this.loginFrame=c("iframe"),this.loginFrame.title="Log in to Baack";let o=c("button","primary","I have logged in, try again");o.type="button",o.addEventListener("click",()=>{this.hideLogin(),t()}),this.login.append(this.loginText,this.loginFrame,o),i.append(this.entities,this.message,this.messageAction,this.messageDebug,this.login)}setEditMode(e){this.modeButton.disabled=!1,this.modeButton.setAttribute("aria-pressed",String(e)),this.itemsButton.hidden=!e,this.readButton.hidden=!e}setReadMode(e){this.readButton.textContent=e?"Show live page":"Show latest drafts"}setPending(e){this.pendingGroups=e;let t=e.reduce((n,i)=>n+i.rows.length,0);this.pendingButton.hidden=t===0,this.pendingButton.textContent=t===1?"1 unsaved change":`${t} unsaved changes`,this.renderEntities();for(let n of this.pendingListeners)n()}setOpenPending(e){this.openPending=e}onPending(e){this.pendingListeners.push(e)}pendingSections(){return this.pendingGroups.length===0?[c("p","hint","Nothing is unsaved.")]:[...this.pendingGroups.map(e=>this.pendingSection(e)),...this.pendingGroups.length>1?[this.actions(void 0,"everywhere")]:[]]}setOpenEntity(e){this.openEntity=e}setLifecycle(e){this.lifecycleRows=e,this.renderEntities();for(let t of this.lifecycleListeners)t()}lifecycleOf(e){return this.lifecycleRows.find(t=>t.entityUrn===e)}showsEntity(e){return this.lifecycleRows[0]?.entityUrn===e}onLifecycle(e){this.lifecycleListeners.push(e)}renderEntities(){let e=this.lifecycleRows[0];this.entities.replaceChildren(...e?[this.entityLabel(e)]:[])}entityLabel(e){let t=this.pendingGroups.find(i=>i.entityUrn===e.entityUrn)?.rows.length??0,n=c("button","entity-label");if(n.type="button",I(n,"Open in the sidebar"),n.append(c("span","title",e.title),c("span","meta",` \xB7 ${e.label}`)),t>0&&n.append(c("span","meta unsent",` \xB7 ${t} unsaved`)),n.addEventListener("click",()=>this.openEntity?.(e.entityUrn)),e.note){let i=c("div","entity");return i.append(n,c("p","message",e.note)),i}return n}pendingSection(e){let t=e.title,n=c("section","entity");n.setAttribute("aria-label",`Unsaved in ${t}`),n.append(c("div","meta",`${t}: ${e.rows.length} unsaved`));let i=c("ul","rows");for(let s of e.rows){let o=c("li",s.problem?"row problem":"row",s.label);if(o.append(c("span","meta",` \xB7 ${s.detail}`)),s.action){let a=c("button","",s.action.label);a.type="button";let d=s.action.run;a.addEventListener("click",()=>d(a)),o.append(" ",a)}i.append(o)}return n.append(i,this.actions(e.entityUrn,`in ${t}`)),n}showMessage(e,t=!1,n,i){this.message.textContent=e,this.message.classList.remove("visually-hidden"),this.message.classList.toggle("info",t),this.messageDebug.replaceChildren(...Z(n)),this.runMessageAction=i?.run,this.messageAction.textContent=i?.label??"",this.messageAction.hidden=!i}announce(e,t="",n=!0){this.showMessage(t,n),this.message.prepend(c("span","visually-hidden",t?`${e} `:e)),this.message.classList.toggle("visually-hidden",!t)}showLogin(e,t){this.loginText.textContent=e,t?(this.loginFrame.src=t,this.loginFrame.hidden=!1):(this.loginFrame.removeAttribute("src"),this.loginFrame.hidden=!0),this.login.hidden=!1}hideLogin(){this.login.hidden=!0}actions(e,t){let n=c("div","actions"),i=c("button","primary",e?"Save all":"Save everything");i.type="button",i.setAttribute("aria-label",`Save all unsaved changes ${t}`),i.addEventListener("click",()=>this.pendingActions.sendAll(e));let s=T(e?"Discard all":"Discard everything","destructive");return s.setAttribute("aria-label",`Discard all unsaved changes ${t}`),s.addEventListener("click",()=>this.pendingActions.discardAll(e)),n.append(s,i),n}};function rt(r){let e=window.matchMedia?.("(prefers-reduced-motion: reduce)").matches??!1;if(typeof document.startViewTransition!="function"||e||document.visibilityState!=="visible")return r(),Promise.resolve();let t=document.startViewTransition(r);return t.ready.catch(()=>{}),t.finished.catch(()=>{}),t.updateCallbackDone}var st=class{ctx;hooks;snapshots=new Map;carried=new Map;orders=new Map;added=new Set;loading=new Map;editMode=!1;readMode="LATEST";session=0;previewing;previewListeners=new Set;changedThisVisit=new Set;built=new WeakMap;constructor(e,t){this.ctx=e,this.hooks=t}get isEditing(){return this.editMode}get mode(){return this.readMode}begin(e="LATEST"){this.editMode=!0,this.readMode=e,this.session+=1}readOptions(e){return e==="live"?{}:{version:e==="LATEST"?"LATEST":String(e)}}readLiveChanges(){let{store:e}=this.ctx,t=[...this.changedThisVisit].filter(n=>S(e.view(n)?.status)).flatMap(n=>e.scopesFor(n));return this.readLive(t)}async readLive(e){try{return await Promise.all(e.map(async t=>[t,await this.ctx.views.read(t)]))}catch(t){return this.ctx.feedback.report(t,"show the published content",()=>{this.readLive(e).then(n=>{this.editMode||this.showLive(n)})}),[]}}showLive(e){let{store:t,discovery:n}=this.ctx;for(let[o,a]of e)t.loadEntity(o,a);let i=new Set(e.map(([o])=>o)),s=!1;n.flush();for(let o of n.all()){if(!i.has(o.scope))continue;let a=t.itemFor(o);!a?.item.urn||o.element.getAttribute(P(o.entry))===a.item.urn||(this.recordBuilt(o),this.ctx.live.render(o,a.item),s=!0)}return t.clearEntities(),s}async leave(e){let t=!1;return await rt(()=>{this.end(),t=this.showLive(e)}),t}async prefetch(e,t){let n=await Promise.all(t.map(async i=>[i,await this.readIn(i,e)]));return new Map(n)}async switchTo(e,t){let{store:n,discovery:i}=this.ctx;await rt(()=>{this.end(),this.begin(e);for(let[s,o]of t)n.loadEntity(s,o.entity),o.draft&&this.draftsOnLivePage.add(o.entity.urn);i.flush();for(let s of i.all())this.show(s)}),this.hooks.changed()}get previewedUrn(){return this.previewing?.version.urn}onPreviewChange(e){this.previewListeners.add(e)}previewVersion(e,t){let n=this.previewing?.slot;this.previewing={slot:e,version:t},n&&!St(n,e)&&this.reshow(n),this.reshow(e),this.notifyPreview()}stopPreview(e){let t=this.previewing;!t||e&&!St(t.slot,e)||(this.previewing=void 0,this.reshow(t.slot),this.notifyPreview())}notifyPreview(){for(let e of this.previewListeners)e()}end(){this.previewing&&(this.previewing=void 0,this.notifyPreview()),this.editMode=!1,this.session+=1,this.ctx.live.endPreviews();for(let e of this.added)e.remove();this.added.clear(),this.restoreOrders();for(let e of[...this.snapshots.keys()])this.restore(e);for(let[e,t]of this.carried)for(let n of t.values())e.isConnected&&!G(e)&&oi(e,n);this.carried.clear(),this.ctx.store.clearEntities(),this.loading.clear(),this.draftsOnLivePage.clear(),this.ctx.sources.clear()}async hydrate(e){let t=this.session,n=new Set(e.map(i=>i.scope));await Promise.all([...n].map(i=>this.loadScope(i))),t===this.session&&(await rt(()=>{if(t===this.session)for(let i of e)this.ctx.discovery.of(i.element).includes(i)&&this.show(i)}),t===this.session&&this.hooks.changed())}draftsOnLivePage=new Set;async readScope(e){let{entity:t,draft:n}=await this.readIn(e,this.readMode);return n?this.draftsOnLivePage.add(t.urn):this.draftsOnLivePage.delete(t.urn),t}async readIn(e,t){let{views:n}=this.ctx;if(t!=="live")return{entity:await n.read(e,this.readOptions(t)),draft:!1};let{entity:i,live:s}=await n.readAsLive(e);return{entity:i,draft:!s}}loadScope(e){let{store:t,feedback:n,discovery:i}=this.ctx;if(t.hasScope(e))return Promise.resolve();let s=this.loading.get(e);if(!s){let o=this.session;s=this.readScope(e).then(a=>{o===this.session&&t.loadEntity(e,a)}).catch(a=>{this.loading.delete(e);let d=this.readMode==="live"?"load the live content":"load the latest content";n.report(a,d,()=>{this.hydrate(i.all())})}),this.loading.set(e,s)}return s}show(e){let{store:t,pending:n}=this.ctx,{element:i,entry:s}=e;this.snapshots.has(e)||this.snapshots.set(e,this.carriedSnapshot(i,s)??si(i,s)),this.recordBuilt(e);let o=t.itemFor(e),a=this.previewing;if(o?.item.urn&&a&&St(a.slot,{...e,entityUrn:t.entityFor(e.scope)})){this.ctx.live.render(e,dt(s,o.item,M(s,a.version))),N(i,"previewing");return}if(o?.item.urn){let u=n.getEdit(o.item.urn),h=u&&!u.stale,f=h&&!s.renderedByView?dt(s,o.item,u.value):o.item;this.ctx.live.render(e,f),N(i,h?"changed":this.publishedSinceBuilt(e,o.item.urn)?"published":"editable");return}let d=t.entityFor(e.scope),l=d?n.getCreate($({entityUrn:d,type:s.type,name:e.name,sortOrder:e.sortOrder})):void 0;l&&!s.renderedByView?(this.ctx.live.render(e,{name:e.name,sortOrder:e.sortOrder,...l.value}),N(i,"changed")):N(i,l?"changed":"unresolved")}recordBuilt({element:e,entry:t}){let n=this.built.get(e)??new Map;n.has(t)||n.set(t,e.getAttribute(P(t))??void 0),this.built.set(e,n)}publishedSinceBuilt(e,t){if(this.readMode!=="live")return!1;let n=this.ctx.store.entityFor(e.scope);return!n||this.draftsOnLivePage.has(n)?!1:this.built.get(e.element)?.get(e.entry)!==t}countPublishedSinceBuilt(){return new Set(this.ctx.discovery.all().filter(e=>e.element.getAttribute(Se)==="published").map(e=>e.element)).size}showAll(){for(let e of this.ctx.discovery.all())this.show(e)}reshow(e){let{discovery:t,store:n}=this.ctx;for(let i of t.all()){if(i.entry!==e.entry||n.entityFor(i.scope)!==e.entityUrn)continue;let s=e.urn&&i.element.getAttribute(P(i.entry))===e.urn,o=i.name===e.name&&i.sortOrder===e.sortOrder;!s&&!o||this.hooks.editingElement()!==i.element&&this.show(i)}}forget(e){for(let t of e){if(this.hooks.editingBinding()===t&&this.hooks.closeEditor(),this.carried.get(t.element)?.has(t.entry)){this.snapshots.delete(t);continue}this.restore(t)}}retag(e,t,n=e.name){let{element:i,entry:s}=e,o=this.snapshots.get(e)??si(i,s),a=this.carried.get(i)??new Map;a.set(s,o),this.carried.set(i,a),i.setAttribute(X(s),String(t)),i.setAttribute(`data-${s.attribute}-name`,n)}carriedSnapshot(e,t){let n=this.carried.get(e),i=n?.get(t);return i&&n.delete(t),n&&n.size===0&&this.carried.delete(e),i}rememberOrder(e){G(e)||this.orders.has(e)||this.orders.set(e,[...e.childNodes])}restoreOrder(e){let t=this.orders.get(e);t&&(e.append(...t.filter(n=>n.parentNode===e||!n.parentNode)),this.orders.delete(e))}restoreOrders(){for(let e of[...this.orders.keys()])this.restoreOrder(e)}track(e){this.added.add(e)}async refresh(e){let{store:t,feedback:n,discovery:i}=this.ctx,s=this.session,o=t.scopesFor(e);this.readMode==="LATEST"&&this.changedThisVisit.add(e);try{for(let a of o){let d=await this.readScope(a);if(s!==this.session)return;t.loadEntity(a,d)}}catch(a){n.report(a,"show the latest content",()=>{this.refresh(e)});return}for(let a of i.all())o.includes(a.scope)&&this.hooks.editingBinding()!==a&&this.show(a);this.hooks.changed(e)}bindingsAt(e){return this.ctx.discovery.all().filter(t=>t.entry===e.entry&&t.name===e.name&&t.sortOrder===e.sortOrder&&this.ctx.store.entityFor(t.scope)===e.entityUrn)}missingBindings(e){let{store:t,discovery:n}=this.ctx,i=new Set;return n.all().filter(s=>{if(t.entityFor(s.scope)!==e||t.itemAt(e,s.entry,s.name,s.sortOrder))return!1;let o=$({entityUrn:e,type:s.entry.type,name:s.name,sortOrder:s.sortOrder});return i.has(o)?!1:(i.add(o),!0)})}restore(e){let t=this.snapshots.get(e);if(this.snapshots.delete(e),Bt(e.element),this.ctx.live.restore(e)){let n=P(e.entry),i=t?.attributes.find(([s])=>s===n)?.[1];i?e.element.setAttribute(n,i):e.element.removeAttribute(n);return}t&&e.element.isConnected&&oi(e.element,t)}};function si(r,e){let t=e.component?.(r).ownsChildren??!0;return{attributes:[...r.attributes].map(n=>[n.name,n.value]),children:t?[...r.childNodes].map(n=>n.cloneNode(!0)):void 0}}function oi(r,e){let t=new Set(e.attributes.map(([n])=>n));for(let n of[...r.attributes])t.has(n.name)||r.removeAttribute(n.name);for(let[n,i]of e.attributes)r.setAttribute(n,i);e.children&&r.replaceChildren(...e.children)}function St(r,e){return r.entityUrn===e.entityUrn&&r.entry===e.entry&&r.name===e.name&&r.sortOrder===e.sortOrder}var ot=class{ctx;view;editing;saving;outline;onboarding;history;publishing;moves;tags;images;stash;restored=!1;constructor(e,t,n,i,s){let o=new xe,a,d=new Re(e,()=>a);a=new it(t,()=>d.retryAfterLogin(),{sendAll:p=>{this.saving.saveAll(p)},discardAll:p=>this.saving.discardAll(p)});let l=new be(n,{added:p=>{this.view.isEditing&&this.view.hydrate(p)},removed:p=>this.view.forget(p)}),u=new We(e,async()=>{let v=(await e.companies().catch(()=>[])).map(m=>m.urn);return v.length>0?v:s.company?.urn?[s.company.urn]:[]},s.user?.urn);this.ctx={transport:e,host:t,registry:i,store:o,pending:new we(()=>this.pendingChanged()),toolbar:a,popover:new nt(t),panels:{show:(p,v)=>this.outline.showPanel(p,v)},feedback:d,views:new Le(e),sources:new Map,discovery:l,canPublish:["PUBLISHER","ADMIN","SUPER"].includes(s.user?.role??""),requiredImageSlots:window.baackEditorConfig?.requiredImageSlots??["DEFAULT"],live:new $e(o),hooks:{openHistory:p=>{this.history.open(p)},publishEntity:p=>{this.publishing.openReview(p)},canReorder:p=>(this.moves.groupOf(p)?.units.length??0)>1,reorder:p=>this.moves.openReorder(p),moveBy:(p,v)=>this.moves.moveBy(p,v),relocate:p=>{this.editing.close(),this.outline.focusSlot(p)},showItem:p=>this.outline.selectItem(p),rename:(p,v)=>{this.moves.relocate(void 0,p.entityUrn,p.entry,v)},moveSlot:(p,v,m)=>this.moves.moveTo(p.entityUrn,p.entry,v,{name:p.name,sortOrder:m}),runPlan:p=>this.moves.run(p),saveImage:(p,v)=>this.images.save(p,v)},groups:s.user?.urn?new qe(s.user.urn):void 0,entry:p=>i.find(v=>v.type===p),entityTitle:p=>{let v=o.view(p)?.name;return v?`Content for ${j(v)}`:`Entity ${p.slice(0,8)}`},announcePublished:(p,v,m={})=>{let g=o.view(p),y=g?.name??"",x={entityUrn:p,name:y,path:y&&di(j(y)),language:g?.language??"",variant:g?.variant??""};m.itemUrn&&(x.itemUrn=m.itemUrn);let b=m.quiet===!0&&a.showsEntity(p);ri(a,window.baackEditorConfig?.afterPublish,x,v,{...m.info!==void 0?{info:m.info}:{},quiet:b})}},this.stash=s.user?.urn?new Ee(s.user.urn):void 0,this.view=new st(this.ctx,{editingElement:()=>this.editing.current?.session?this.editing.current.target.binding?.element:void 0,editingBinding:()=>this.editing.current?.target.binding,closeEditor:()=>this.editing.close(),changed:p=>{this.refreshTags(),this.outline.changed(p),this.history?.changed(p),this.publishing?.changed()}}),this.saving=new De(this.ctx,this.view,()=>this.editing),this.editing=new Be(this.ctx,this.view,p=>this.saving.save(p)),this.onboarding=new Je({transport:e,toolbar:a,context:s,registry:i,store:o,panels:this.ctx.panels,openEntity:p=>this.outline.openEntity(p),entityNameForPage:window.baackEditorConfig?.entityNameForPage,report:(p,v,m)=>d.report(p,v,m),created:p=>u.remember(p)}),this.ctx.popover.setEntitySource(this.entitySource(u)),this.outline=new Qe(this.ctx,this.view,this.editing,this.saving,this.onboarding);let h=this.outline.outline.stack;h.avoid(a.modeButton.closest(".toolbar"));let f=this.ctx.popover.element;new MutationObserver(()=>h.element.classList.toggle("item-editing",!f.hidden)).observe(f,{attributes:!0,attributeFilter:["hidden"]}),this.moves=new Ke(this.ctx,this.view,()=>this.editing,()=>this.ctx.groups,p=>this.saving.commit(p)),this.tags=new je(this.ctx.host,p=>this.moves.openOrderMenu(p)),this.moves.onOrderChange(()=>this.refreshTags()),this.images=new Ie(this.ctx,this.view,()=>this.saving,()=>this.editing),this.publishing=new Ze(this.ctx,this.view,window.baackEditorConfig?.publishTimeoutMs??300*1e3,this.outline.outline.stack,{show:(p,v)=>this.outline.showAbove(v,p)}),this.history=new ze(this.ctx,this.editing,this.view,this.outline.outline.stack,{show:(p,v)=>this.outline.showAbove(v,p),publishEntity:p=>this.ctx.hooks.publishEntity(p),published:async p=>{await this.view.refresh(p),await this.publishing.refreshStatus(p)}}),a.modeButton.addEventListener("click",()=>{this.setEditMode(!this.view.isEditing)}),a.itemsButton.addEventListener("click",()=>this.outline.toggle()),a.setOpenEntity(p=>this.outline.openEntity(p)),a.onLifecycle(()=>this.outline.changed()),a.setOpenPending(()=>this.outline.togglePending()),a.onPending(()=>this.outline.changed()),this.outline.onClose(()=>this.history.stopPreview()),a.readButton.addEventListener("click",()=>{this.setReadMode(this.view.mode==="LATEST"?"live":"LATEST")}),document.addEventListener("keydown",p=>{this.view.isEditing&&p.altKey&&p.shiftKey&&p.code==="KeyI"&&(p.preventDefault(),this.outline.toggle(),this.outline.outline.isOpen&&this.outline.outline.focusFilter())}),l.start()}leaving;get isEditing(){return this.view.isEditing}async setEditMode(e,t="LATEST",n=!0){if(await this.leaving,e===this.view.isEditing)return;let{toolbar:i,discovery:s}=this.ctx;if(i.setEditMode(e),e)this.view.begin(t),this.startMode(t),await this.view.hydrate(s.all()),await this.afterRead(t);else{this.stopMode();let o=n&&this.view.mode==="LATEST"?this.view.readLiveChanges():Promise.resolve([]);this.leaving=o.then(()=>{});let a=await o;this.leaving=void 0,await this.view.leave(a)&&i.showMessage(`Showing the published content. ${xt(window.baackEditorConfig?.afterPublish)??kt}`,!0)}}startMode(e){this.showReadMode(e),e==="LATEST"&&(this.editing.attach(),this.publishing.start(),this.outline.setNewEntity(()=>{this.onboarding.offerNewEntity(this.pageLanguage())}))}pageLanguage(){let{store:e}=this.ctx,t=ee(e);return t&&e.view(t)?.language||document.documentElement.lang||"en-GB"}entitySource(e){let{transport:t,feedback:n}=this.ctx,i=()=>this.onboarding,s=()=>this.pageLanguage();return{list:o=>e.list(o),describe:o=>e.describe(o),get language(){return s()},create(o,a){return new Promise(d=>{i().newEntityForm({title:"New entity",submitLabel:"Create and choose it",path:a,language:this.language,onCreated:l=>d(e.remember(l)),onCancel:()=>d(void 0)}).then(l=>{l.element.addEventListener("keydown",u=>{u.key==="Escape"&&(u.preventDefault(),u.stopPropagation(),l.cancel())}),o.replaceChildren(l.element),l.element.querySelector("input")?.focus()})})},note:async o=>{let a=await t.readEntity(o);return e.remember(a),S(a.status)||a.status==="PUBLISH"?"":`${j(a.name)} is not published yet, so pages show it only once it is.`},pagePath:di,report:(o,a,d)=>{n.report(o,a,d)}}}refreshTags(){this.tags&&(this.view.isEditing&&this.view.mode==="LATEST"?this.tags.show(this.moves.keyedMembers()):this.tags.clear())}stopMode(){let{toolbar:e}=this.ctx;this.tags.clear(),this.editing.detach(),this.editing.close(),this.outline.clear(),this.history.close(),this.publishing.stop(),this.moves.panel.close(),this.outline.setNewEntity(void 0),e.showMessage(""),e.hideLogin()}async afterRead(e){let{toolbar:t,discovery:n}=this.ctx;if(e==="live"){let i=this.view.countPublishedSinceBuilt(),s=[i>0?`Showing the live content. ${i===1?"1 item was":`${i} items were`} published since this page was built, outlined in green. ${xt(window.baackEditorConfig?.afterPublish)??kt}`:"Showing the live page, as visitors see it."];if(this.view.draftsOnLivePage.size>0){let o=[...this.view.draftsOnLivePage].map(a=>this.ctx.entityTitle(a)).join(", ");s.push(`Not published yet, so shown as the latest drafts: ${o}.`)}t.showMessage(`${s.join(" ")} Editing is off.`,!0)}e==="LATEST"&&(await this.restoreStash(),n.unscoped().length>0&&!document.documentElement.hasAttribute(U)&&this.onboarding.offerEntityForPage())}async setReadMode(e){if(!this.view.isEditing){await this.setEditMode(!0,e);return}if(e===this.view.mode)return;let t=[...new Set(this.ctx.discovery.all().map(i=>i.scope))],n;try{n=await this.view.prefetch(e,t)}catch(i){let s=e==="live"?"load the live content":"load the latest content";this.ctx.feedback.report(i,s,()=>{this.setReadMode(e)});return}!this.view.isEditing||e===this.view.mode||(this.stopMode(),this.startMode(e),await this.view.switchTo(e,n),await this.afterRead(e))}showReadMode(e){let{toolbar:t}=this.ctx;t.setReadMode(e==="LATEST"),e==="live"&&t.showMessage("Showing the live page, as visitors see it. Editing is off.",!0),typeof e=="number"&&t.showMessage(`Showing the latest drafts as of ${new Date(e).toLocaleString()}. Read-only.`,!0)}pendingChanged(){let{pending:e,toolbar:t}=this.ctx,n=e.all();this.stash?.save(n);let i=e.byEntity(),s=te(this.ctx.store,[...i.keys()]).map(o=>({entityUrn:o,title:this.ctx.entityTitle(o),rows:i.get(o).map(a=>({label:`${a.name} #${a.sortOrder}`,detail:a.kind==="create"?"new item":a.kind==="move"?`${a.label}: to ${a.to.name===a.name?"":a.to.name}#${a.to.sortOrder}`:a.stale?"based on an older version":"edit",problem:a.kind==="edit"&&a.stale===!0,...a.kind==="edit"&&a.stale?{action:{label:"Resolve",run:d=>{this.saving.resolve(a,d)}}}:{}}))}));t.setPending(s),n.length>0?window.addEventListener("beforeunload",ai):window.removeEventListener("beforeunload",ai),this.outline?.changed()}async restoreStash(){if(this.restored||!this.stash)return;this.restored=!0;let e=this.stash.load();if(e.length===0)return;await Promise.all([...new Set(e.map(n=>n.entityUrn))].map(n=>this.view.loadScope(n)));let t=e.map(n=>n.kind!=="edit"?n:this.ctx.store.itemAt(n.entityUrn,this.ctx.entry(n.type),n.name,n.sortOrder)?.item.urn===n.urn?{...n,stale:!1}:{...n,stale:!0});this.ctx.pending.load(t),this.view.showAll(),this.ctx.toolbar.showMessage(`Restored ${t.length} unsaved ${t.length===1?"change":"changes"} from this browser.`,!0)}};function ai(r){r.preventDefault()}function di(r){return(window.baackEditorConfig?.pagePathForEntity??Yn)(r)}var At=[on,cn,un,hn,pn,mn,fn,vn,yn,gn,bn,wn,En],li=At.filter(r=>r.component!==void 0);function Ga(r){let e=new ot(r.transport,r.host,li,At,r.context);return e.setReadMode(r.mode??"LATEST"),e}export{Ga as start};
|
|
16
|
+
`)||void 0)}};function si(r,e){if(!(r.name===e.name&&r.sortOrder===e.sortOrder))throw new fe(`Saved, but the API stored it as "${r.name??""}" #${r.sortOrder??"?"} instead of ${e.name} #${e.sortOrder}. Do not save it again; this needs fixing in the API.`)}var fe=class extends Error{};var cr={added:["ins",""],removed:["del",""],increase:["span","delta up"],decrease:["span","delta down"],arrow:["span","arrow"]};function ve(r){let e=l("div","change");if(typeof r=="string")return e.textContent=r,e;for(let t of r){if(t.kind==="same"){e.append(t.text);continue}let[n,i]=cr[t.kind],s=l(n,i,t.text);t.kind==="arrow"&&s.setAttribute("aria-label","to"),(t.kind==="increase"||t.kind==="decrease")&&(s.title=`${t.text.replace(/^[+−]/,"")} ${t.kind}`),e.append(s)}return e}var _e=class{element;status;list;more;compare;constructor(e,t){this.element=l("div","level-item");let n=l("label","field");this.compare=l("select"),this.compare.append(Object.assign(l("option","","Compare with the live version"),{value:"live"}),Object.assign(l("option","","Compare with the previous version"),{value:"previous"})),this.compare.addEventListener("change",()=>t(this.compare.value)),n.append(l("span","caption","Show changes"),ee(this.compare)),this.status=l("p","hint"),this.status.setAttribute("role","status"),this.list=l("ol","rows history-rows"),this.list.setAttribute("aria-label","Versions, newest first"),this.more=l("button","","Load older versions"),this.more.type="button",this.more.hidden=!0,this.more.addEventListener("click",e),this.element.append(n,this.status,this.list,this.more)}setStatus(e){this.status.textContent=e}render(e,t){let n=new Set([...this.list.querySelectorAll('li.history-row:has(> button[aria-expanded="true"])')].map(i=>i.dataset.when));this.list.replaceChildren(...e.map(i=>this.row(i,n))),this.more.hidden=!t}row(e,t){let n=l("li","row history-row");n.dataset.when=e.whenUtc;let i=l("button","row-main");i.type="button",i.dataset.row="";let s=l("span","row-name",e.when);s.title=`${e.whenUtc} UTC`,i.append(s),e.live&&i.append(l("span","status status-up-to-date","live"));for(let d of e.notes)i.append(l("span","status note",d));let o=l("span","stack-chevron");o.append(L("chevron-right")),o.setAttribute("aria-hidden","true"),i.append(o),i.addEventListener("click",()=>e.open());let a=l("div","actions");if(a.append(oi(e.preview)),n.append(i,ve(e.change),a),e.collapsed.length>0){let d=x(`${e.collapsed.length} earlier ${e.collapsed.length===1?"draft":"drafts"}`,"ghost","xs"),c=t.has(e.whenUtc);d.setAttribute("aria-expanded",String(c));let u=l("ol","rows");u.hidden=!c,u.append(...e.collapsed.map(h=>this.row(h,t))),d.addEventListener("click",()=>{u.hidden=!u.hidden,d.setAttribute("aria-expanded",String(!u.hidden))}),n.append(d,u)}return n}};function Lt(r,e){if(!e){r.replaceChildren(l("p","message","This version is no longer in the history. Go back to see the versions there are."));return}let t=l("p","version-head");t.title=`Saved ${e.whenUtc} UTC`;for(let s of e.marks)t.append(l("span",`status ${s==="live"?"status-up-to-date":"note"}`,s));for(let s of e.notes)t.append(l("span","status note",s));let n=e.changes.map(({label:s,change:o})=>{let a=l("div","field version-change");return a.append(l("span","caption",s),ve(o)),a}),i=l("div","actions");i.append(...e.actions.map(oi)),r.replaceChildren(...t.childElementCount>0?[t]:[],...n,i)}function oi(r){let e=x(r.label,Z(r),"sm");return r.pressed!==void 0&&e.setAttribute("aria-pressed",String(r.pressed)),r.disabled&&(e.disabled=!0,e.title=r.disabled),e.addEventListener("click",()=>r.run(e)),e}var ur=400,hr=0,ge,St=0;function P(r,e){if(r.removeAttribute("title"),e!==void 0){let n=l("span","visually-hidden",e);n.id=`baack-tooltip-${++hr}`;let i=()=>r.parentElement&&!n.isConnected&&r.after(n);i(),queueMicrotask(i),r.setAttribute("aria-describedby",n.id)}let t=()=>e??r.getAttribute("aria-label")??"";r.addEventListener("pointerenter",n=>{n.pointerType!=="touch"&&(clearTimeout(St),St=window.setTimeout(()=>ai(r,t()),ge?0:ur))}),r.addEventListener("focus",()=>{r.matches(":focus-visible")&&ai(r,t())});for(let n of["pointerleave","blur","pointerdown"])r.addEventListener(n,At);r.addEventListener("keydown",n=>{n.key==="Escape"&&ge?.trigger===r&&At()})}function ai(r,e){if(At(),!r.isConnected||r.getClientRects().length===0)return;let t=l("div","tooltip",e);t.setAttribute("aria-hidden","true"),r.getRootNode().append(t);let n=r.getBoundingClientRect(),{width:i,height:s}=t.getBoundingClientRect(),o=n.top-s-6;t.style.top=`${o>=8?o:n.bottom+6}px`,t.style.left=`${Math.min(Math.max(8,n.left+n.width/2-i/2),window.innerWidth-i-8)}px`,ge={tip:t,trigger:r}}function At(){clearTimeout(St),ge?.tip.remove(),ge=void 0}var li="baack-editor:side",pr=150,di=3,mr=0,fr="(max-width: 640px)",Ge=class{element;back;heading;crumbs;body;announcer;dock;entries=[];id=`baack-stack-${mr+=1}`;closeListeners=[];toolbar;constructor(e){this.element=l("aside","panel side stack"),this.element.setAttribute("aria-label","Editor"),this.element.hidden=!0;let t=l("div","stack-bar");this.back=x("","ghost","sm","stack-back"),this.back.addEventListener("click",()=>this.pop()),this.dock=x("","ghost","icon-sm","side-dock"),this.dock.addEventListener("click",()=>this.setSide(this.side==="right"?"left":"right"));let n=x("","ghost","icon-sm","stack-close");n.setAttribute("aria-label","Close"),n.append(L("x")),n.addEventListener("click",()=>this.close()),t.append(this.back,l("span","stack-spacer"),this.dock,n),P(this.dock),P(n);let i=l("nav","stack-crumbs");i.setAttribute("aria-label","Where you are"),this.crumbs=l("ol"),i.append(this.crumbs),this.heading=l("h2","stack-title"),this.heading.id=`${this.id}-title`,this.heading.tabIndex=-1,this.body=l("div","stack-body"),this.announcer=l("p","visually-hidden"),this.announcer.setAttribute("aria-live","polite"),this.element.append(t,i,this.heading,this.body,this.announcer),this.element.addEventListener("keydown",this.onKeyDown),this.setSide(vr()),e.root.append(this.element)}avoid(e){this.toolbar=e,new ResizeObserver(()=>this.fit()).observe(e),window.addEventListener("resize",()=>this.fit()),this.fit()}onClose(e){this.closeListeners.push(e)}fit(){let e=this.toolbar?.getBoundingClientRect().top,t=(this.side==="right"||matchMedia(fr).matches)&&e!==void 0;this.element.style.bottom=t?`${Math.max(16,window.innerHeight-e+8)}px`:""}get current(){return this.entries.at(-1)?.level}get path(){return this.entries.map(e=>e.level.id)}get isOpen(){return!this.element.hidden}push(e,{focus:t=!0}={}){let n=this.entries.at(-1);n&&(n.scrollTop=this.body.scrollTop,n.origin=this.focusedIn(n.section));let i=this.enter(e);this.entries.push(i),this.show(i,n,"in",t)}pop(){if(this.entries.length<=1){this.close();return}this.popTo(this.entries.at(-2).level.id)}popTo(e){let t=this.entries.findIndex(i=>i.level.id===e);if(t<0||t===this.entries.length-1)return;let n=this.entries.at(-1);for(let i of this.entries.splice(t+1))this.leave(i,i===n);this.show(this.entries[t],n,"out")}replace(e,{focus:t=!0}={}){let n=this.entries.pop();n&&this.leave(n,!1);let i=this.enter(e);this.entries.push(i),this.show(i,void 0,"none",t)}reset(e,{focus:t=!0}={}){for(let i of this.entries.splice(0))this.leave(i,!1);for(let i of e)this.entries.push(this.enter(i));let n=this.entries.at(-1);n&&this.show(n,void 0,"none",t)}open(){this.element.hidden=!1}close(){if(!this.element.hidden){this.element.hidden=!0;for(let e of this.closeListeners)e()}}get side(){return this.element.dataset.side==="left"?"left":"right"}setSide(e){this.element.dataset.side=e,this.dock.setAttribute("aria-label",e==="right"?"Move to left":"Move to right"),this.dock.replaceChildren(L(e==="right"?"panel-left":"panel-right")),this.fit();try{localStorage.setItem(li,e)}catch{}}enter(e){let t=l("section","stack-level");return t.dataset.level=e.id,t.setAttribute("aria-labelledby",this.heading.id),t.hidden=!0,t.append(e.render()),this.body.append(t),{level:e,section:t,scrollTop:0,origin:void 0}}leave(e,t){e.level.dispose?.(),(!t||!this.animates())&&e.section.remove()}show(e,t,n,i=!0){this.element.hidden=!1;for(let o of this.entries)o.section.hidden=o!==e;e.section.hidden=!1,this.renderHeader(),this.body.scrollTop=n==="out"?e.scrollTop:0,t&&n!=="none"&&this.slide(e.section,t.section,n),e.level.onShow?.(),this.announcer.textContent=e.level.title;let s=n==="out"&&e.origin?.isConnected?e.origin:void 0;i&&(s??this.heading).focus({preventScroll:n==="out"})}renderHeader(){let e=this.entries.at(-1).level,t=this.entries.at(-2)?.level;this.heading.textContent=e.title,this.back.hidden=!t,this.back.replaceChildren(...t?[L("chevron-left"),l("span","stack-back-text",t.title)]:[]),this.back.setAttribute("aria-label",t?`Back to ${t.title}`:"Back");let n=this.entries.map((s,o)=>({entry:s,index:o})),i=n.length>di+1?[n[0],void 0,...n.slice(n.length-(di-1))]:n;this.crumbs.replaceChildren(...i.flatMap((s,o)=>{let a=l("li","stack-crumb-separator");a.setAttribute("role","presentation"),a.setAttribute("aria-hidden","true"),a.append(L("chevron-right"));let d=l("li"),c=h=>(d.append(h),o===0?[d]:[a,d]);if(!s)return c(l("span","meta","\u2026"));if(s.index===this.entries.length-1){let h=l("span","",s.entry.level.title);return h.setAttribute("aria-current","page"),c(h)}let u=l("button","stack-crumb",s.entry.level.title);return u.type="button",u.addEventListener("click",()=>this.popTo(s.entry.level.id)),c(u)})),this.crumbs.parentElement.hidden=this.entries.length<2}animates(){return typeof Element.prototype.animate=="function"&&!matchMedia("(prefers-reduced-motion: reduce)").matches}slide(e,t,n){if(!this.animates())return;let i=this.side==="right"?"100%":"-100%",s={duration:pr,easing:"ease-out"};if(n==="in"){e.animate([{transform:`translateX(${i})`},{transform:"none"}],s);return}t.hidden=!1,t.inert=!0,t.setAttribute("aria-hidden","true"),t.classList.add("leaving"),t.style.top=`${this.body.scrollTop}px`,t.animate([{transform:"none"},{transform:`translateX(${i})`}],s).finished.then(()=>t.remove(),()=>t.remove())}focusedIn(e){let t=this.element.getRootNode().activeElement;return t instanceof HTMLElement&&e.contains(t)?t:void 0}onKeyDown=e=>{if(e.key==="Escape"&&!e.defaultPrevented){e.preventDefault(),e.stopPropagation(),this.pop();return}if(e.key!=="ArrowDown"&&e.key!=="ArrowUp")return;let t=this.entries.at(-1)?.section,n=t&&this.focusedIn(t);if(!t||!n?.matches("[data-row]"))return;let i=[...t.querySelectorAll("[data-row]")].filter(o=>!o.closest("[hidden]")),s=i[i.indexOf(n)+(e.key==="ArrowDown"?1:-1)];s&&(e.preventDefault(),s.focus())}};function vr(){try{return localStorage.getItem(li)==="left"?"left":"right"}catch{return"right"}}function ze(r,e,t){let n=l("button","stack-row");n.type="button",n.dataset.row="";let i=l("span","stack-row-text");i.append(l("span","stack-row-label",r)),e&&i.append(l("span","meta",e));let s=l("span","stack-chevron");return s.append(L("chevron-right")),n.append(i,s),n.addEventListener("click",t),n}function Ke(r){let e=l("div","level-confirm");e.append(l("p","meta",r.meta));for(let n of r.blocks){let i=l("div","field");i.append(l("span","caption",n.label),l("pre","snippet",n.text)),e.append(i)}e.append(l("p","description",r.description));let t=l("div","actions");for(let n of r.choices){let i=x(n.label,Z(n));i.addEventListener("click",()=>n.run(i)),t.append(i)}return e.append(t),{id:r.id,title:r.title,render:()=>e}}var gr=600*1e3,je=class{stack;ctx;editing;view;hooks;state;constructor(e,t,n,i,s){this.ctx=e,this.editing=t,this.view=n,this.stack=i,this.hooks=s,n.onPreviewChange(()=>this.render())}async open(e){this.state&&!br(this.state,e)&&this.stopPreview();let t=new _e(()=>{this.loadMore()},s=>{this.state===i&&(i.against=s,this.render())}),n={id:yr(e),title:`${e.name} #${e.sortOrder}`,render:()=>t.element,dispose:()=>{this.state===i&&(this.stopPreview(),this.state=void 0)}},i={...e,versions:[],live:void 0,after:void 0,against:"live",linked:!1,level:n,view:t,version:void 0};this.state=i,this.hooks.show(n,e.entityUrn),t.setStatus("Loading\u2026"),i.linked=await this.isLinked(e),this.state===i&&await this.loadMore()}close(){this.stopPreview(),this.state=void 0}stopPreview(){this.state&&this.view.previewedUrn&&(this.view.stopPreview(this.state),this.ctx.toolbar.showMessage(""))}togglePreview(e,t){if(this.view.previewedUrn===t.urn){this.stopPreview();return}this.editing.close(),this.view.previewVersion(e,t);let n=window.getSelection(),i=this.view.bindingsAt(e).map(o=>o.element);n?.anchorNode&&i.some(o=>o.contains(n.anchorNode))&&n.removeAllRanges(),this.view.bindingsAt(e)[0]?.element.scrollIntoView({block:"nearest",behavior:"smooth"});let s=new Date(M(t.createdTimestamp??"")).toLocaleString();this.ctx.toolbar.showMessage(`Previewing the version of ${e.name} saved ${s}. Nothing is saved; stop the preview to see the latest again.`,!0)}changed(e){let t=this.state;if(!t||e&&e!==t.entityUrn)return;let n=this.ctx.store.itemAt(t.entityUrn,t.entry,t.name,t.sortOrder);n?.item.urn&&(t.urn=n.item.urn),this.reload(t)}async reload(e){try{let t=await this.ctx.transport.history(e.entry,e.urn);if(this.state!==e)return;e.live=t.item??void 0,e.versions=[...t.history],e.after=t.pagination?.isMorePages?t.pagination.after??void 0:void 0,this.render()}catch(t){this.ctx.feedback.report(t,"load the history",()=>{this.reload(e)})}}async loadMore(){let e=this.state;if(e)try{let t=await this.ctx.transport.history(e.entry,e.urn,e.after);if(this.state!==e)return;e.live??=t.item??void 0,e.versions.push(...t.history),e.after=t.pagination?.isMorePages?t.pagination.after??void 0:void 0,e.view.setStatus(""),this.render()}catch(t){e.view.setStatus(""),this.ctx.feedback.report(t,"load the history",()=>{this.loadMore()})}}render(){let e=this.state;if(!e)return;let t=e.versions.map((s,o)=>this.row(e,s,e.versions[o+1])),n=[],i;e.versions.forEach((s,o)=>{let a=M(s.createdTimestamp??""),d=n.at(-1),c=s.isPublished===!0;d&&!c&&!d.live&&i!==void 0&&i-a<=gr?d.collapsed.push(t[o]):n.push(t[o]),i=a}),e.view.render(n,e.after!==void 0),e.version&&this.stack.path.includes(ci(e.version.urn))&&Lt(e.version.body,this.versionModel(e,e.version.urn))}row(e,t,n){let i=e.against==="live"?e.live:n;return{when:Ot(t),whenUtc:t.createdTimestamp??"",live:t.isPublished===!0,change:Ct(e.entry,t,i,e.against),notes:this.notes(t,n),open:()=>this.openVersion(e,t),preview:this.previewAction(e,t),collapsed:[]}}notes(e,t){let n=[];t&&t.name!==e.name&&n.push(`renamed from ${t.name}`),t&&t.sortOrder!==e.sortOrder&&n.push(`moved from #${t.sortOrder} to #${e.sortOrder}`);let i=e.urn?this.ctx.groups?.of(e.urn):void 0;return i&&n.push(`part of: ${i.label}`),n}openVersion(e,t){let n=t.urn,i=l("div","level-version");e.version={urn:n,body:i},Lt(i,this.versionModel(e,n)),this.stack.push({id:ci(n),title:`Version saved ${Ot(t)}`,render:()=>i,dispose:()=>{e.version?.urn===n&&(e.version=void 0)}})}versionModel(e,t){let n=e.versions.findIndex(c=>c.urn===t),i=e.versions[n];if(!i)return;let s=e.versions[n+1],o=[...i.isPublished===!0?["live"]:[],...n===0?["latest"]:[]],a=s!==void 0&&s.urn===e.live?.urn,d=[{label:a?"Against the one before, which is live":"Against the one before",change:Ct(e.entry,i,s,"previous")||"The same value as the one before."}];return i.isPublished!==!0&&!a&&d.push({label:"Against live",change:Ct(e.entry,i,e.live,"live")}),{when:Ot(i),whenUtc:i.createdTimestamp??"",marks:o,notes:this.notes(i,s),changes:d,actions:this.actions(e,i)}}actions(e,t){let{ctx:n}=this,i=[],s=n.store.view(e.entityUrn)?.status;if(n.canPublish&&t.isPublished!==!0&&(S(s)||s==="PUBLISH")){let a=s==="PUBLISH"?"Publishing is in progress for this page.":void 0,d=n.groups?.of(t.urn)!==void 0;i.push(e.linked||d?{label:"Publish with the page\u2026",disabled:a,run:()=>this.hooks.publishEntity(e.entityUrn)}:{label:"Publish this version",primary:!0,disabled:a,run:()=>{this.publish(e,t)}})}i.push(this.previewAction(e,t)),t!==e.versions[0]&&i.push({label:"Edit from this version",run:a=>this.editFrom(e,t,a)});let o=e.versions.length===1&&e.after===void 0;return i.push({label:o?"Delete this item\u2026":"Delete this version\u2026",destructive:!0,run:()=>this.confirmDelete(e,t,o)}),i}previewAction(e,t){let n=this.view.previewedUrn===t.urn,i=this.ctx.store.itemAt(e.entityUrn,e.entry,e.name,e.sortOrder)?.item.urn,s=e.entry.renderedByView?"The page shows the server's rendering of this type, which history does not include.":this.view.mode!=="LATEST"?"Previews are shown on the latest drafts.":this.view.bindingsAt(e).length===0?"This item is not shown on this page.":t.urn===i&&!this.ctx.pending.getEdit(t.urn)?"The page already shows this version.":void 0;return{label:n?"Stop preview":"Preview on the page",pressed:n,disabled:n?void 0:s,run:()=>this.togglePreview(e,t)}}confirmDelete(e,t,n){let i=new Date(M(t.createdTimestamp??"")).toLocaleString(),s=t.isPublished===!0?"from this page and from the live site":"from this page",o=[{label:`The version saved ${i}`,text:V(e.entry,t)}],a=n?`This is its only version, so deleting it deletes the item: it disappears ${s}, and cannot be restored.`:"It is removed from the history for good and cannot be restored. Every version uses storage, which is billed.",d=!n&&t.isPublished===!0?ui(e,t):void 0;if(d){let c=new Date(M(d.version?.createdTimestamp??"")).toLocaleString();d.version&&o.push({label:`Goes live in its place: the version saved ${c}`,text:V(e.entry,d.version)}),a=d.newer?`This is the live version. The API puts the next newer version live in its place: a draft saved ${c}, which may never have been published. Publish the version you want first if that is not it. It cannot be restored.`:d.version?`This is the live version. The API puts the version before it live in its place (saved ${c}). It cannot be restored.`:"This is the live version. The API puts the version before it live in its place. It cannot be restored."}this.stack.push(Ke({id:"confirm-delete",title:n?"Delete this item permanently?":d?"Delete the live version permanently?":"Delete this version permanently?",meta:`${e.name} #${e.sortOrder}`,blocks:o,description:a,choices:[{label:"Cancel",run:()=>this.stack.pop()},{label:"Delete permanently",destructive:!0,run:c=>{c.disabled=!0,c.textContent="Deleting\u2026",this.deleteVersion(e,t).finally(()=>{c.disabled=!1,c.textContent="Delete permanently"})}}]}))}async deleteVersion(e,t){let{transport:n,pending:i,toolbar:s,feedback:o}=this.ctx,a=t.isPublished===!0?ui(e,t).version:void 0;try{await n.remove(e.entry,t.urn),a?.urn&&Tt({entityUrn:e.entityUrn,urn:a.urn,type:e.entry.type});let d=e.versions.find(u=>u.urn!==t.urn),c=i.getEdit(t.urn);if(!d?.urn){c&&i.clear(t.urn),this.close(),this.stack.popTo(`entity:${e.entityUrn}`),s.showMessage(`Deleted ${e.name} #${e.sortOrder}.`,!0),await this.hooks.published(e.entityUrn);return}c&&i.set({...c,stale:!0}),s.showMessage(`Deleted the version of ${e.name} saved ${new Date(M(t.createdTimestamp??"")).toLocaleString()}.`,!0),this.state===e&&this.stack.popTo(e.level.id),e.urn=d.urn,await this.hooks.published(e.entityUrn),this.state===e&&await this.reload(e)}catch(d){o.report(d,"delete this version",()=>{this.deleteVersion(e,t)})}}async publish(e,t){try{await this.ctx.transport.publishVersion(e.entry,t),Tt({entityUrn:e.entityUrn,urn:t.urn,type:e.entry.type}),this.ctx.announcePublished(e.entityUrn,`Published the version of ${e.name} saved ${new Date(M(t.createdTimestamp??"")).toLocaleString()}.`,{itemUrn:t.urn}),await this.hooks.published(e.entityUrn)}catch(n){this.ctx.feedback.report(n,"publish this version",()=>{this.publish(e,t)})}}editFrom(e,t,n){this.ctx.store.remember(e.entityUrn,e.entry,t),this.editing.open({entityUrn:e.entityUrn,entry:e.entry,name:t.name,sortOrder:t.sortOrder,urn:t.urn,anchor:n,binding:void 0,fromVersion:!0})}async isLinked(e){if(e.entry.type==="template")return!0;let{store:t,sources:n,transport:i}=this.ctx,s=t.view(e.entityUrn)?.raw.templates??[],o=this.ctx.entry("template"),a=new RegExp(`\\$\\{?${e.name.replace(/[^\w-]/g,"")}\\b`);for(let d of s)if(d.urn)try{let c=n.get(d.urn)??{value:(await i.read(o,d.urn)).value};if(n.set(d.urn,c),a.test(String(c.value??"")))return!0}catch{}return!1}};function Ct(r,e,t,n){if(!t)return n==="live"?"Nothing is live yet.":"The first version.";if(t.urn===e.urn)return n==="live"?"This is the live version.":"";let i=t.value,s=e.value;if(typeof i=="string"&&typeof s=="string")return Fe(i,s);let o=V(r,t),a=V(r,e);return o===a?"No change to the value.":Ve(r,t,e)}function Ot(r){let e=M(r.createdTimestamp??"");return Number.isNaN(e)?"Unknown time":new Date(e).toLocaleString()}function yr(r){return`item:${r.entityUrn}:${r.entry.type}:${r.name}:${r.sortOrder}`}function ci(r){return`version:${r}`}function br(r,e){return r.entityUrn===e.entityUrn&&r.entry===e.entry&&r.name===e.name&&r.sortOrder===e.sortOrder}function ui(r,e){let t=r.versions.indexOf(e);return t>0?{version:r.versions[t-1],newer:!0}:{version:r.versions[t+1],newer:!1}}function pi(r,e){let t=r.map(s=>s.sortOrder).sort((s,o)=>s-o),n=new Map(r.map(s=>[s.key,s]));if(e.length!==r.length||e.some(s=>!n.has(s)))throw new Error("The new order must contain exactly the items of the list");let i=[];return e.forEach((s,o)=>{let a=n.get(s),d=t[o];a.sortOrder!==d&&i.push({key:s,from:a.sortOrder,to:d})}),i}function mi(r,e){let t=[...r].sort((d,c)=>d.sortOrder-c.sortOrder);if(t.length===0)return{sortOrder:0,shifts:[]};if(e.position==="head")return{sortOrder:t[0].sortOrder-1,shifts:[]};if(e.position==="tail")return{sortOrder:t.at(-1).sortOrder+1,shifts:[]};let n=t.findIndex(d=>d.key===e.key);if(n<0)throw new Error("The item to insert after is not in the list");let i=t[n],s=t[n+1];if(!s)return{sortOrder:i.sortOrder+1,shifts:[]};if(s.sortOrder-i.sortOrder>1)return{sortOrder:Math.floor((i.sortOrder+s.sortOrder)/2),shifts:[]};let o=t.slice(0,n+1),a=t.slice(n+1);return a.length<=o.length?{sortOrder:s.sortOrder,shifts:[...hi(a,1)].reverse()}:{sortOrder:i.sortOrder,shifts:hi([...o].reverse(),-1).reverse()}}function hi(r,e){let t=[];for(let[n,i]of r.entries()){if(n>0&&i.sortOrder!==t.at(-1).to)break;t.push({key:i.key,from:i.sortOrder,to:i.sortOrder+e})}return t}function fi(r,e){return[{key:r.key,from:r.sortOrder,to:e.sortOrder},{key:e.key,from:e.sortOrder,to:r.sortOrder}]}async function vi(r,e,t){let{store:n,sources:i,transport:s}=r,o=r.entry("template"),a=new RegExp(`\\$\\{?${t.replace(/[^\w-]/g,"")}\\b`),d=[];for(let c of n.view(e)?.raw.templates??[])if(c.urn)try{let u=i.get(c.urn)??{value:(await s.read(o,c.urn)).value};i.set(c.urn,u),a.test(String(u.value??""))&&d.push(`${c.name} #${c.sortOrder}`)}catch{}return d}var qe=class{element;entries=[];actions;list;status;saveButton;addButtons;dragging;panels;handle;constructor(e){this.panels=e,this.element=l("div","reorder"),this.status=l("p","hint"),this.status.setAttribute("role","status"),this.list=l("ol","rows reorder-rows"),this.list.setAttribute("aria-label","Entries, in order"),this.addButtons=l("div","actions");let t=l("div","actions"),n=l("button","","Cancel");n.type="button",n.addEventListener("click",()=>this.actions?.cancel()),this.saveButton=l("button","primary","Save order"),this.saveButton.type="button",this.saveButton.addEventListener("click",()=>this.actions?.save(this.keys())),t.append(n,this.saveButton),this.element.append(this.status,this.list,this.addButtons,t)}get isOpen(){return this.handle?.isOpen??!1}open(e,t,n,i){if(this.entries=[...n],this.actions=i,this.setStatus(""),this.setBusy(!1),this.addButtons.replaceChildren(),i.add){let s=l("button","","Add at the start");s.type="button",s.addEventListener("click",()=>i.add({position:"head"},s));let o=l("button","","Add at the end");o.type="button",o.addEventListener("click",()=>i.add({position:"tail"},o)),this.addButtons.append(s,o)}this.render(),this.handle=this.panels.show(this.element,{title:e,entityUrn:t,onLeave:()=>{let s=this.actions;this.actions=void 0,s?.cancel()}})}close(){this.actions=void 0,this.handle?.close()}setStatus(e){this.status.textContent=e}setBusy(e,t="Saving\u2026"){this.saveButton.disabled=e,this.saveButton.textContent=e?t:"Save order"}keys(){return this.entries.map(e=>e.key)}move(e,t,n){if(t<0||t>=this.entries.length||e===t)return;let[i]=this.entries.splice(e,1);if(this.entries.splice(t,0,i),this.render(),n){let o=[...[...this.list.children].find(a=>a.dataset.key===i.key)?.querySelectorAll("button[data-move]")??[]];(o.find(a=>a.dataset.move===n&&!a.disabled)??o.find(a=>!a.disabled))?.focus()}this.actions?.changed(this.keys())}render(){this.list.replaceChildren(...this.entries.map((e,t)=>{let n=l("li","row reorder-row");n.draggable=!0,n.dataset.key=e.key;let i=l("span","handle");i.setAttribute("aria-hidden","true"),i.append(L("grip-vertical"));let s=l("div","row-main");s.append(l("span","row-name",e.label)),e.detail&&s.append(l("span","meta",e.detail));let o=l("button","","Move up");o.type="button",o.disabled=t===0,o.setAttribute("aria-label",`Move ${e.label} up`),o.dataset.move="up",o.addEventListener("click",()=>this.move(t,t-1,"up"));let a=l("button","","Move down");if(a.type="button",a.disabled=t===this.entries.length-1,a.setAttribute("aria-label",`Move ${e.label} down`),a.dataset.move="down",a.addEventListener("click",()=>this.move(t,t+1,"down")),n.append(i,s,o,a),this.actions?.add){let d=x("","ghost","icon-sm");d.setAttribute("aria-label",`Add after ${e.label}`),d.append(L("plus")),P(d),d.addEventListener("click",()=>this.actions?.add({position:"after",key:e.key},d)),n.append(d)}return n.addEventListener("dragstart",d=>{this.dragging=e.key,d.dataTransfer?.setData("text/plain",e.key),n.classList.add("dragging")}),n.addEventListener("dragend",()=>{this.dragging=void 0,n.classList.remove("dragging")}),n.addEventListener("dragover",d=>d.preventDefault()),n.addEventListener("drop",d=>{d.preventDefault();let c=this.entries.findIndex(u=>u.key===this.dragging);c>=0&&this.move(c,t)}),n}))}};var We=class{panel;ctx;view;editing;groups;done=new Map;failures=new Map;create;constructor(e,t,n,i,s){this.ctx=e,this.create=s,this.view=t,this.editing=n,this.groups=i,this.panel=new qe(e.panels)}groupOf(e){let t=this.ctx.store.entityFor(e.scope);if(!t)return;let n=e.element.closest("[data-content-rows]"),i=e.element.closest(`[data-${e.entry.attribute}-list="${CSS.escape(e.name)}"]`);if(i&&(!n||n.contains(i)))return this.listGroup(i,e,t);if(n)return this.rowsGroup(n,e,t)}listGroup(e,t,n){let i=[];for(let s of e.children){let o=this.ctx.discovery.all().find(u=>u.entry===t.entry&&u.name===t.name&&s.contains(u.element)&&this.ctx.store.entityFor(u.scope)===n);if(!o)continue;let a=this.ctx.store.itemFor(o),d=o.element.getAttribute("data-section");if(!a?.item.urn&&d===null)continue;let c=a?.item.urn?String(a.item.value??a.item.name):d;i.push({key:a?.item.urn??`slot:${o.sortOrder}`,element:s,bindings:[o],sortOrder:o.sortOrder,label:d===null?c:wr(s,c),...d!==null?{detail:` \xB7 ${(s.textContent??"").trim().replace(/\s+/g," ").slice(0,70)}\u2026`}:{},...a?.item.urn?{}:{missing:d}})}return{kind:"list",container:e,entityUrn:n,entry:t.entry,name:t.name,units:i}}rowsGroup(e,t,n){let i=[];for(let s of e.children){let o=Number(s.getAttribute("data-content-row"));if(!Number.isInteger(o))continue;let a=this.ctx.discovery.all().filter(c=>s.contains(c.element)&&this.ctx.store.entityFor(c.scope)===n),d=a.map(c=>(c.element.textContent??"").trim()).filter(Boolean);i.push({key:`row:${o}`,element:s,bindings:a,sortOrder:o,label:d[0]??`Row ${o}`,detail:d.length>1?` \xB7 ${d.slice(1).join(" \xB7 ")}`:""})}return{kind:"rows",container:e,entityUrn:n,entry:t.entry,name:t.name,units:i}}openReorder(e){let t=this.groupOf(e);if(!t||t.units.length===0)return;this.editing().close(),this.view.rememberOrder(t.container);let n=t.units.map(s=>s.key),i=t.kind==="rows"?"rows":t.name==="sections"?"sections":`"${t.name}"`;this.panel.open(`Reorder ${i}`,t.entityUrn,t.units.map(s=>({key:s.key,label:s.label,sortOrder:s.sortOrder,...s.detail?{detail:s.detail}:{}})),{changed:s=>this.preview(t,s),cancel:()=>{this.preview(t,n),this.panel.close()},save:s=>{this.saveOrder(t,s,()=>this.panel.close())},...t.kind==="list"?{add:(s,o)=>{this.insert(t,s,o)}}:{}})}moveBy(e,t){let n=this.groupOf(e);if(!n)return;let i=n.units.map(a=>a.key),s=n.units.findIndex(a=>a.bindings.includes(e)),o=s+t;s<0||o<0||o>=i.length||([i[s],i[o]]=[i[o],i[s]],this.editing().close(),this.view.rememberOrder(n.container),this.preview(n,i),this.saveOrder(n,i,()=>{}))}preview(e,t){let n=new Map(e.units.map(a=>[a.key,a]));if(j(e.container)){this.previewLive(e,t);return}let i=new Set(e.units.map(a=>a.element)),o=[...e.container.children].filter(a=>i.has(a)).map(a=>{let d=document.createComment("");return a.replaceWith(d),d});t.forEach((a,d)=>o[d]?.replaceWith(n.get(a).element))}previewLive(e,t){let n=new Map(e.units.map(a=>[a.key,a])),i=e.units.map(a=>a.sortOrder).sort((a,d)=>a-d),s=e.units.map(a=>a.key),o=t.every((a,d)=>a===s[d]);t.forEach((a,d)=>{let c=n.get(a),u=c.bindings[0],v=this.ctx.store.itemFor(u)?.item??{name:e.name,value:c.missing};this.ctx.live.showAt(u,i[d],o?void 0:{...v,sortOrder:i[d]})})}async saveOrder(e,t,n){let i=pi(e.units.map(u=>({key:u.key,sortOrder:u.sortOrder})),t),s=new Map(e.units.map(u=>[u.key,u])),o=e.units.filter(u=>u.missing!==void 0);if(i.length===0&&o.length===0){n();return}let a=[];for(let u of i){let h=s.get(u.key);if(h.missing===void 0)for(let v of h.bindings){let p=this.ctx.store.itemFor(v);p?.item.urn&&a.push(this.step(v.entry,p.item,e.entityUrn,{name:v.name,sortOrder:u.to}))}}let d=e.kind==="rows"?"Reorder rows":`Reorder ${e.name}`;this.panel.setBusy(!0);let c=await this.runSteps(a,d)&&await this.createMissing(e,o,i);if(this.panel.setBusy(!1),!c){this.preview(e,e.units.map(u=>u.key)),await this.view.refresh(e.entityUrn);return}if(j(e.container))this.ctx.live.endPreviews();else for(let u of i)for(let h of s.get(u.key).bindings)this.view.retag(h,u.to);n(),await this.view.refresh(e.entityUrn)}async createMissing(e,t,n){if(t.length===0)return!0;let{feedback:i,toolbar:s}=this.ctx;await this.view.refresh(e.entityUrn);let o=new Map(n.map(a=>[a.key,a.to]));for(let a of t){let d=o.get(a.key)??a.sortOrder;try{await this.create({kind:"create",type:e.entry.type,entityUrn:e.entityUrn,name:e.name,sortOrder:d,value:{value:a.missing}})}catch(c){let u=await i.describe(c,`add ${a.missing} to ${e.name}`);return s.showMessage(`Reorder ${e.name}: ${u.message}`,!1,u.debug),!1}}return!0}keyedMembers(){let e=new Set,t=[];for(let n of this.ctx.discovery.all()){if(!n.element.hasAttribute("data-section"))continue;let i=this.groupOf(n);!i||i.kind!=="list"||e.has(i.container)||(e.add(i.container),i.units.forEach((s,o)=>t.push({binding:s.bindings[0],name:i.name,index:o,count:i.units.length})))}return t}openOrderMenu(e){let t=this.groupOf(e);if(!t||t.units.length<2)return;let{popover:n}=this.ctx;this.editing().close(),this.view.rememberOrder(t.container);let i=t.units.map(u=>u.key),s=t.units.find(u=>u.bindings.includes(e)),o=[...i],a=new Map(t.units.map(u=>[u.key,u.label])),d=()=>{this.preview(t,i),this.changedOrder()},c=()=>{let u=o.indexOf(s.key),h=o.some((m,g)=>m!==i[g]),v=m=>{let g=[...o];[g[u],g[u+m]]=[g[u+m],g[u]],o=g,this.preview(t,o),this.changedOrder(),c()},p=o[u-1],f=o[u+1];n.whenEnded(void 0),n.showChoices(s.element,`Order of ${t.name}`,`${u+1} of ${o.length}`,[],[`${s.label} is ${u+1} of ${o.length}.`,p?`Before it: ${a.get(p)}.`:"",f?`After it: ${a.get(f)}.`:"",h?"Not saved yet.":"",h&&t.units.some(m=>m.missing!==void 0)&&S(this.ctx.store.view(t.entityUrn)?.status)?"This content is published, and this order is new, so it is live as soon as it is saved.":""].filter(Boolean).join(" "),[...p?[{label:"Move previous",run:()=>v(-1)}]:[],...f?[{label:"Move next",run:()=>v(1)}]:[],{label:"Reorder all\u2026",run:()=>{n.whenEnded(void 0),n.hide(),d(),this.openReorder(e)}},...h?[{label:"Save",primary:!0,run:()=>{n.whenEnded(void 0),n.hide(),this.saveOrder(t,o,()=>{}).then(()=>this.changedOrder())}}]:[],{label:h?"Revert":"Close",run:()=>n.hide()}]),n.whenEnded(d)};c()}orderListeners=new Set;onOrderChange(e){this.orderListeners.add(e)}changedOrder(){for(let e of this.orderListeners)e()}async insert(e,t,n){let i=e.units.map(h=>({key:h.key,sortOrder:h.sortOrder}));await this.view.refresh(e.entityUrn);let s=mi(i,t),o=new Map(e.units.map(h=>[h.key,h]));if(s.shifts.length>0){let h=s.shifts.flatMap(v=>o.get(v.key).bindings.flatMap(p=>{let f=this.ctx.store.itemFor(p);return f?.item.urn?[this.step(p.entry,f.item,e.entityUrn,{name:p.name,sortOrder:v.to})]:[]}));if(!await this.runSteps(h,`Make room in ${e.name}`))return;for(let v of s.shifts)for(let p of o.get(v.key).bindings)this.view.retag(p,v.to);await this.view.refresh(e.entityUrn)}if(this.ctx.store.itemAt(e.entityUrn,e.entry,e.name,s.sortOrder)){this.ctx.toolbar.showMessage(`${e.name} #${s.sortOrder} is taken. Reopen the list and try again.`);return}let a=e.units.at(t.position==="head"?0:-1),d=t.position==="after"?o.get(t.key).element:a.element,c=a.element.cloneNode(!0);for(let h of[c,...c.querySelectorAll("*")])h.removeAttribute("style"),h.removeAttribute("data-baack-state"),h.removeAttribute(`data-${e.entry.attribute}-urn`),h.hasAttribute(`data-${e.entry.attribute}-name`)&&(h.setAttribute(`data-${e.entry.attribute}-sort-order`,String(s.sortOrder)),h.setAttribute("data-placeholder",""));t.position==="head"?e.container.insertBefore(c,d):d.after(c),this.view.track(c),this.panel.close();let u=c.matches(`[data-${e.entry.attribute}-name]`)?c:c.querySelector(`[data-${e.entry.attribute}-name]`);this.editing().open({entityUrn:e.entityUrn,entry:e.entry,name:e.name,sortOrder:s.sortOrder,anchor:u??c,binding:void 0})}async relocate(e,t,n,i){let{store:s}=this.ctx;this.editing().close();let o=this.ctx.discovery.all().filter(v=>v.entry===n&&v.name===i.name&&v.sortOrder===i.sortOrder).length,a=await vi(this.ctx,t,i.name),d=l("div","simple-form");d.append(l("p","hint",`${i.name} #${i.sortOrder} is shown in ${o} ${o===1?"place":"places"} on this page. Those places will show the new item there, or a placeholder.`));let c=new R(`Move or rename ${i.name} #${i.sortOrder}`,[{key:"name",label:"Name",value:i.name},{key:"sortOrder",label:"Sort order",value:String(i.sortOrder)}],"Move",v=>{let p=v.name??"",f=Number(v.sortOrder);if(!/^[A-Za-z0-9_-]+$/.test(p))return c.setError("Use letters, numbers, - and _ in the name.");if(!Number.isInteger(f))return c.setError("The sort order must be a whole number.");if(p===i.name&&f===i.sortOrder)return c.setError("That is where it is now.");c.setBusy(!0,"Checking\u2026"),this.view.refresh(t).then(async()=>{if(c.setBusy(!1),s.itemAt(t,n,p,f)&&!u){u=!0,c.setError(`${p} #${f} is taken. Press Move again to swap the two.`);return}h.close(),await this.moveTo(t,n,i,{name:p,sortOrder:f})})}),u=!1;c.element.insertBefore(d,c.element.querySelector(".error")),a.length>0&&c.element.insertBefore(l("p","issues",`Templates use "${i.name}" and would stop showing it if it is renamed: ${a.join(", ")}.`),c.element.querySelector(".error")),c.element.insertBefore(l("p","issues","Renaming changes the name every client looks this item up by, including apps this editor cannot see. They break when it is published."),c.element.querySelector(".error"));let h=this.ctx.panels.show(c.element,{entityUrn:t})}async moveTo(e,t,n,i){await this.view.refresh(e);let s=this.ctx.store.itemAt(e,t,i.name,i.sortOrder);if(s?.item.urn===n.urn)return!0;let o=s?fi({key:n.urn,sortOrder:n.sortOrder},{key:s.item.urn,sortOrder:i.sortOrder}).map(d=>this.step(t,d.key===n.urn?n:s.item,e,{name:d.key===n.urn?i.name:n.name,sortOrder:d.to})):[this.step(t,n,e,i)],a=s?`Swap ${n.name} #${n.sortOrder} and ${i.name} #${i.sortOrder}`:i.name===n.name?`Move ${n.name} #${n.sortOrder} to #${i.sortOrder}`:`Rename ${n.name} to ${i.name}`;return await this.runSteps(o,a)?(await this.view.refresh(e),!0):!1}step(e,t,n,i){return{kind:"move",type:e.type,urn:t.urn,entityUrn:n,name:t.name,sortOrder:t.sortOrder,to:i}}async runSteps(e,t){if(e.length===0)return!0;let n=`plan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,7)}`;for(let i of e)this.ctx.pending.set({...i,planId:n,label:t});return this.run(n)}async run(e){let{pending:t,transport:n,toolbar:i,feedback:s}=this.ctx,o=t.plan(e);if(o.length===0)return!0;let a=o[0].label,d=o[0].entityUrn,c=this.done.get(e)??[];this.done.set(e,c),i.showMessage(`${a}: moving\u2026`,!0);for(let u of o){let h=this.ctx.entry(u.type);try{let v=(await n.history(h,u.urn)).history[0];if(!v?.urn)throw new Error(`${u.name} #${u.sortOrder} no longer exists`);if(v.name===u.to.name&&v.sortOrder===u.to.sortOrder){t.clear(K(u)),c.push({step:u,urn:v.urn});continue}if(v.urn!==u.urn)throw new Error(`${u.name} #${u.sortOrder} was changed by someone else after this move was planned`);let p={...v,name:u.to.name,sortOrder:u.to.sortOrder},f=await n.update(h,v.urn,X(h,p,O(h,v),u.entityUrn));if(!f?.urn)throw new Error("the API returned no URN for the new version");t.clear(K(u)),c.push({step:u,urn:f.urn}),ae({entityUrn:u.entityUrn,oldUrn:u.urn,newUrn:f.urn,type:h.type,value:f})}catch(v){let p=await s.describe(v,"move this item");return this.showFailure(e,a,c.length,c.length+t.plan(e).length,p.message,p.debug,d),p.kind==="unauthorized"&&s.promptLogin(p.message,()=>{this.run(e)}),!1}}return this.groups()?.add({id:e,label:a,entityUrn:d,versions:c.map(u=>u.urn),at:Date.now()}),this.done.delete(e),this.closeFailure(e),i.showMessage(`${a}: done. Saved as drafts.`,!0,void 0,Ae(this.ctx,d)),!0}showFailure(e,t,n,i,s,o,a){let d=l("div","simple-form");d.append(l("div","title",`${t} stopped part-way`),l("p","message",`Moved ${n} of ${i}. ${s}`),...z(o),l("p","hint","The rest is kept with your unsaved changes, in this browser, until you retry or put things back."));let c=l("button","primary","Retry");c.type="button",c.addEventListener("click",()=>{this.run(e).then(async v=>{v&&await this.refreshAfter(e)})});let u=l("button","",n>0?"Put back":"Discard this move");u.type="button",u.addEventListener("click",()=>{this.putBack(e)});let h=l("div","actions");h.append(u,c),d.append(h),this.closeFailure(e),this.failures.set(e,this.ctx.panels.show(d,{entityUrn:a}))}closeFailure(e){this.failures.get(e)?.close(),this.failures.delete(e)}async refreshAfter(e){for(let t of this.ctx.store.entities())await this.view.refresh(t)}async putBack(e){let{pending:t}=this.ctx,n=this.done.get(e)??[],i=t.plan(e);for(let d of i)t.clear(K(d));let s=i[0]?.label??n[0]?.step.label??"Move",o=i[0]?.entityUrn??n[0]?.step.entityUrn;if(this.done.delete(e),n.length===0){this.closeFailure(e),this.ctx.toolbar.showMessage(`${s}: nothing had moved, so nothing changed. The move is discarded.`,!0);return}let a=n.map(({step:d,urn:c})=>({kind:"move",type:d.type,urn:c,entityUrn:d.entityUrn,name:d.to.name,sortOrder:d.to.sortOrder,to:{name:d.name,sortOrder:d.sortOrder}}));await this.runSteps(a,`Put back: ${s}`)&&(this.ctx.toolbar.showMessage(`Put back: ${s}.`,!0),o&&await this.view.refresh(o))}};function wr(r,e){return(r.querySelector("h1, h2, h3, h4, h5, h6")?.textContent??"").trim().replace(/\s+/g," ")||e}var Ye=class{layer;onOpen;tags=[];frame=0;resizes=new ResizeObserver(()=>this.schedule());constructor(e,t){this.layer=l("div","order-tags"),e.root.append(this.layer),this.onOpen=t}show(e){if(e.length===this.tags.length&&e.every((i,s)=>this.tags[s].binding===i.binding&&this.tags[s].button.textContent===gi(i))){this.place();return}let n=this.tags.findIndex(i=>i.button.matches(":focus"));this.clear();for(let i of e){let s=l("button","order-tag",gi(i));s.type="button",s.setAttribute("aria-label",`Order of ${i.name}: ${i.index+1} of ${i.count}`),s.addEventListener("click",()=>this.onOpen(i.binding)),this.layer.append(s),this.tags.push({binding:i.binding,element:i.binding.element,button:s}),this.resizes.observe(i.binding.element)}this.tags.length>0&&(window.addEventListener("scroll",this.schedule,!0),window.addEventListener("resize",this.schedule)),this.place(),this.tags[n]?.button.focus()}clear(){cancelAnimationFrame(this.frame),this.resizes.disconnect(),window.removeEventListener("scroll",this.schedule,!0),window.removeEventListener("resize",this.schedule),this.layer.replaceChildren(),this.tags=[]}schedule=()=>{cancelAnimationFrame(this.frame),this.frame=requestAnimationFrame(()=>this.place())};place(){for(let{element:e,button:t}of this.tags){let n=e.getBoundingClientRect();t.hidden=e.getClientRects().length===0,t.style.top=`${n.top+4}px`,t.style.right=`${window.innerWidth-n.right+4}px`}}};function gi(r){return`${r.name} \xB7 ${r.index+1} of ${r.count} \u22EF`}var Er="baack-editor:groups:";var Je=class{key;constructor(e){this.key=Er+e}all(){try{let e=JSON.parse(window.localStorage.getItem(this.key)??"[]");return Array.isArray(e)?e:[]}catch{return[]}}of(e){return this.all().find(t=>t.versions.includes(e))}add(e){try{let t=[...this.all(),e].slice(-200);window.localStorage.setItem(this.key,JSON.stringify(t))}catch(t){console.warn("Baack editor: could not record which versions belong together.",t)}}};var kr="baack-editor:entities",yi=1440*60*1e3,xr=4,Tr=[500,2e3];function Y(r){return r.replace(/^\/[^/]+\/content(?=\/|$)/,"")||"/"}var Ze=class{transport;owners;cache=new Map;key;search;constructor(e,t,n){this.transport=e,this.owners=t,this.key=`${kr}:${n??"anonymous"}`;try{let i=JSON.parse(localStorage.getItem(this.key)??"[]");for(let s of i)Date.now()-s.at<yi&&this.cache.set(s.urn,s)}catch{}}get(e){return this.cache.get(e)}async describe(e){return this.cache.get(e)??this.remember(await this.transport.readEntity(e))}remember(e){let t={urn:e.urn,name:e.name,path:Y(e.name),language:e.language,variant:e.variant??"",at:Date.now()};return this.cache.set(t.urn,t),this.search=this.search?.then(n=>({...n,urns:n.urns.includes(t.urn)?n.urns:[...n.urns,t.urn]})),this.save(),t}async list(e){this.search??=this.searchAll().catch(u=>{throw this.search=void 0,u});let{urns:t,complete:n}=await this.search,i=()=>({entities:t.flatMap(u=>this.cache.get(u)??[]).sort(Lr),complete:n}),s=t.filter(u=>!this.fresh(u));s.length>0&&e?.(i());let o,a=[...s],d=async()=>{for(let u=a.shift();u;u=a.shift())try{this.remember(await this.readWithRetry(u)),e?.(i())}catch(h){D(h)&&h.isNotFound||(o??=h)}};if(await Promise.all(Array.from({length:Math.min(xr,s.length)},d)),o)throw o;let c=i();return e?.(c),c}async readWithRetry(e){for(let t of Tr)try{return await this.transport.readEntity(e)}catch(n){if(!(D(n)&&n.status===429))throw n;await new Promise(i=>setTimeout(i,t))}return this.transport.readEntity(e)}async searchAll(){let e=await Promise.all((await this.owners()).map(t=>this.transport.searchEntities(t)));return{urns:[...new Set(e.flatMap(t=>t.urns))],complete:e.every(t=>t.complete)}}fresh(e){let t=this.cache.get(e);return t!==void 0&&Date.now()-t.at<yi}save(){try{localStorage.setItem(this.key,JSON.stringify([...this.cache.values()]))}catch{}}};function Lr(r,e){return r.path.localeCompare(e.path)||r.language.localeCompare(e.language)||r.variant.localeCompare(e.variant)}var bi="/home";function Xe(r){let e=r.replace(/\/index\.html?$/,"/").replace(/\/+$/,"");return e===""?bi:e}function wi(r){return r===bi?"/":r}function Mt(r){return r.endsWith("/")}var Qe=class{deps;constructor(e){this.deps=e}async offerEntityForPage(){let{transport:e,panels:t}=this.deps,n=(this.deps.entityNameForPage??Xe)(location.pathname),i=document.documentElement.lang||"en-GB";try{let s=await e.entityView(n,{version:"LATEST",language:i}),o=l("div","simple-form");o.append(l("div","title","Content for this page exists"),l("p","hint","Add this to the page's root element so the editor and the site can find it:"),Ei(s.urn));let a=l("button","primary","Use it for this visit");a.type="button",a.addEventListener("click",()=>{document.documentElement.setAttribute(_,s.urn),d.close()}),o.append(le(a));let d=t.show(o)}catch(s){D(s)&&s.isNotFound?await this.showCreateEntity(n,i):this.deps.report(s,"look up this page",()=>{this.offerEntityForPage()})}}async showCreateEntity(e,t){let{panels:n}=this.deps,i=await this.newEntityForm({title:"This page has no content in Baack yet",submitLabel:"Create content for this page",path:e,pathLabel:"Name of this page's content",hint:`No content named ${e} (${t}) was found for ${location.pathname}.`,language:t,onCreated:s=>{let o=l("div","simple-form");o.append(l("div","title","Content created (in draft)"),l("p","hint","Add this to the page's root element. Until then, the editor uses it for this visit:"),Ei(s.urn),l("p","hint",'Next: create the items this page shows, with "Create all" on its content.'));let a=l("button","primary","Show its items");a.type="button",a.addEventListener("click",()=>this.deps.openEntity(s.urn)),o.append(le(a)),n.show(o),document.documentElement.setAttribute(_,s.urn)}});n.show(i.element)}async offerNewEntity(e){let{panels:t}=this.deps,n=await this.newEntityForm({title:"New entity",submitLabel:"Create entity",path:"",language:e,onCreated:i=>{let s=l("div","simple-form"),o=l("pre","snippet",i.urn),a=l("button","","Copy URN");a.type="button",a.addEventListener("click",()=>{navigator.clipboard?.writeText(i.urn).then(()=>a.textContent="Copied",()=>a.textContent="Select and copy it")});let d=l("button","","Done");d.type="button",d.addEventListener("click",()=>c.close()),s.append(l("div","title",`Created ${Y(i.name)} (${i.language}) in draft`),l("p","hint","Choose it in a reference item, or use its URN in the site:"),o,le(a,d));let c=t.show(s)}});t.show(n.element)}async newEntityForm(e){let{transport:t}=this.deps,n=await this.owners(),i=new R(e.title,[{key:"name",label:e.pathLabel??"Path, such as /menu",value:e.path},{key:"language",label:"Language",value:e.language},{key:"variant",label:"Variant (optional)",value:e.variant??""},...n.length>1?[{key:"owner",label:"Owner",value:n[0].urn,options:n.map(s=>({value:s.urn,label:s.name??s.urn}))}]:[]],e.submitLabel,s=>{let o=s.owner??n[0]?.urn,a=s.name??"",d=s.language??"",c=s.variant??"";if(!o)return i.setError("No company was found to own the content.");if(!a.startsWith("/"))return i.setError("The path must start with /, like /menu.");if(Mt(a))return i.setError(`Content has no index: give it a name of its own, without a trailing /, such as ${Xe(a)}.`);if(!d)return i.setError("Enter a language, such as en-GB.");i.setError(""),i.setBusy(!0,"Creating\u2026"),this.existing(a,d,c).then(u=>{if(u){i.setBusy(!1),i.setError(`${a} (${d}${c?` \xB7 ${c}`:""}) already exists.`);return}return t.createEntity({owner:{urn:o},status:"DRAFT_UNPUBLISHED",name:a,language:d,variant:c}).then(h=>{this.deps.created(h),e.onCreated(h)})}).catch(u=>{i.setBusy(!1),i.setError(U(u,"create the entity").message)})},e.onCancel);return e.hint&&i.element.insertBefore(l("p","hint",e.hint),i.element.querySelector("label")),i}async existing(e,t,n){try{let i=await this.deps.transport.entityView(e,{version:"LATEST",language:t,variant:n});return Y(i.name)===e&&i.language.toLowerCase()===t.toLowerCase()&&(i.variant??"")===n?i:void 0}catch(i){if(D(i)&&i.isNotFound)return;throw i}}offerNewPageLike(e){let{transport:t,panels:n,store:i,context:s}=this.deps,o=i.view(e);if(!o)return;let a=new R("New page like this",[{key:"name",label:"Path of the new page",value:Y(o.raw.name)},{key:"language",label:"Language, such as fr-FR",value:o.language,required:!0},{key:"variant",label:"Variant (optional, empty for the default)",value:o.variant??""}],"Create page",d=>{let c=d.name??"",u=d.language??"",h=d.variant??"",v=o.raw.owner?.urn??s.company?.urn;if(!c.startsWith("/"))return a.setError("The path must start with /, like /blog/new-post.");if(Mt(c))return a.setError(`Content has no index: give it a name of its own, without a trailing /, such as ${Xe(c)}.`);if(!u)return a.setError("Enter a language, such as fr-FR.");if(!v)return a.setError("No company was found to own the content.");a.setError(""),a.setBusy(!0,"Creating\u2026"),this.existing(c,u,h).then(p=>{if(p){a.setBusy(!1),a.setError(`${c} (${u}${h?` \xB7 ${h}`:""}) already exists. Change the path, language or variant.`);return}return t.createEntity({owner:{urn:v},status:"DRAFT_UNPUBLISHED",name:c,language:u,variant:h}).then(f=>(this.deps.created(f),this.copyItems(e,f.urn,c,0,{language:u,variant:h})))}).catch(p=>{a.setBusy(!1),a.setError(U(p,"create the page").message)})});n.show(a.element,{entityUrn:e})}async copyItems(e,t,n,i,s){let{transport:o,panels:a,store:d,registry:c}=this.deps,u=d.view(e),v=s&&(s.language.toLowerCase()!==u.language.toLowerCase()||s.variant!==(u.variant??""))?`${n} (${s.language}${s.variant?` \xB7 ${s.variant}`:""})`:n,p=c.flatMap(y=>(u.raw[y.entityArray]??[]).map(T=>[y,T])),f=l("p","hint");f.setAttribute("role","status");let m=l("div","simple-form");m.append(l("div","title",`Creating ${v}`),f),a.show(m,{entityUrn:e});for(let y=i;y<p.length;y+=1){let[T,b]=p[y];f.textContent=`Copying item ${y+1} of ${p.length}\u2026`;try{let k=T.renderedByView?O(T,await o.read(T,b.urn)):O(T,b),A={name:b.name,sortOrder:b.sortOrder};await o.create(T,X(T,A,k,t))}catch(k){f.textContent=`Copied ${y} of ${p.length}. ${U(k,`copy ${b.name}`).message}`;let A=l("button","primary","Copy the rest");A.type="button",A.addEventListener("click",()=>{this.copyItems(e,t,n,y,s)}),m.append(le(A));return}}let g=l("a","",`Open ${n}`);g.href=n,f.textContent=`Created ${v} in draft with ${p.length} items. Images need their files uploaded again. A site built ahead of time shows the page after its next build.`,m.append(le(g))}async owners(){let e=this.deps.context.company?[this.deps.context.company]:[];try{let t=await this.deps.transport.companies(),n=this.deps.context.company?.urn;return t.length>0?[...t].sort((i,s)=>i.urn===n?-1:s.urn===n?1:0):e}catch{return e}}};function Ei(r){let e=l("div","simple-form"),t=l("pre","snippet",`<html data-entity-urn="${r}">`),n=l("button","","Copy");return n.type="button",n.addEventListener("click",()=>{navigator.clipboard?.writeText(`data-entity-urn="${r}"`).then(()=>n.textContent="Copied",()=>n.textContent="Select and copy it")}),e.append(t,le(n)),e}function le(...r){let e=l("div","actions");return e.append(...r),e}function ki(r,e,t){let n=l("p","hint",e.note??"");n.setAttribute("role","status");let i=[n];for(let d of e.blockers)i.push(l("p","error",d));for(let d of e.warnings)i.push(l("p","issues",d));let s=l("ul","rows");s.setAttribute("aria-label","Changes that will go live");for(let d of e.changes){let c=l("li","row history-row"),u=l("div","row-main"),h=d.select?l("button","row-name link",d.name):l("span","row-name",d.name);h instanceof HTMLButtonElement&&(h.type="button",P(h,"Show its history"),h.addEventListener("click",()=>d.select?.())),u.append(h,l("span","meta",` #${d.sortOrder} \xB7 ${d.type}`),l("span",`status status-${d.kind==="changed"?"unpublished-changes":"note"}`,d.kind),...(d.notes??[]).map(v=>l("span","status note move",v))),c.append(u,ve(d.change)),s.append(c)}e.changes.length===0&&i.push(l("p","hint","Nothing has changed since the last publish.")),i.push(s);let o=l("div","actions");if(t.schedule){let d=t.schedule,c=l("button","","Schedule\u2026");c.type="button",P(c,"Publish at a later time"),c.disabled=e.blockers.length>0,c.addEventListener("click",()=>d()),o.append(c)}let a=l("button","primary",e.confirmLabel);a.type="button",a.disabled=e.blockers.length>0,a.addEventListener("click",()=>t.confirm(a)),o.append(a),i.push(o),r.replaceChildren(...i)}function xi(r,e,t,n){let i=l("p","hint","The content goes live by itself at this time. Until then it stays a draft, and you can cancel the schedule."),s=l("label","field"),o=l("input");o.type="datetime-local",s.append(l("span","caption","Publish at (your local time)"),o);let a=l("div","actions"),d=l("button","","Cancel");d.type="button",d.addEventListener("click",n);let c=l("button","primary",e);c.type="button",c.disabled=!0,o.addEventListener("input",()=>c.disabled=!o.value),c.addEventListener("click",()=>t(o.value,c)),a.append(d,c),r.replaceChildren(i,s,a)}var Ti=[1,2,4,8,15],et=class{ctx;stack;hooks;reviewing;view;tracked=new Map;stuckAfterMs;active=!1;constructor(e,t,n,i,s){this.ctx=e,this.view=t,this.stuckAfterMs=n,this.stack=i,this.hooks=s,window.addEventListener("focus",()=>{this.refreshAll()}),document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&this.refreshAll()})}start(){this.active=!0,this.render()}stop(){this.active=!1;for(let e of this.tracked.values())clearTimeout(e.timer);this.tracked.clear(),this.reviewing=void 0,this.ctx.toolbar.setLifecycle([])}changed(){if(this.active){for(let e of this.ctx.store.entities()){let t=this.ctx.store.view(e)?.status;t&&this.observe(e,t)}this.render()}}async refreshAll(){this.active&&await Promise.all(this.ctx.store.entities().map(e=>this.refreshStatus(e)))}async refreshStatus(e){try{let t=await this.ctx.transport.readEntity(e);this.observe(e,t.status,t.publishTimestamp??void 0),this.render()}catch(t){this.ctx.feedback.report(t,"check the publishing status",()=>{this.refreshStatus(e)})}}observe(e,t,n){let i=this.ctx.store.view(e);if(i){let d=i.raw;d.status=t,n!==void 0&&(d.publishTimestamp=n)}let s=this.tracked.get(e),o=s?.status,a=s??{status:t,attempt:0};a.status=t,t==="PUBLISH"?(a.publishingSince??=Date.now(),this.poll(e,a)):(clearTimeout(a.timer),delete a.timer,delete a.publishingSince,a.attempt=0),this.tracked.set(e,a),o!==void 0&&o!==t&&(ii({entityUrn:e,status:t,previous:o}),o==="PUBLISH"&&S(t)&&this.published(e))}published(e){ri(e),this.ctx.announcePublished(e,`${this.ctx.entityTitle(e)} is published.`,{quiet:!0}),this.view.refresh(e)}poll(e,t){if(t.timer)return;let n=Ti[Math.min(t.attempt,Ti.length-1)];t.attempt+=1,t.timer=setTimeout(()=>{delete t.timer,this.active&&this.refreshStatus(e)},n*1e3)}render(){if(!this.active)return;let e=re(this.ctx.store,this.ctx.store.entities()).map(t=>this.row(t));this.ctx.toolbar.setLifecycle(e)}row(e){let{canPublish:t}=this.ctx,n=this.ctx.store.view(e),i=this.tracked.get(e)?.status??n?.status,s=this.ctx.entityTitle(e),o=t?"Publish\u2026":"Request approval\u2026",a=t?"Review and publish\u2026":"Request approval\u2026",d={entityUrn:e,title:s,label:he(i),verbs:[]};switch(i){case"DRAFT_UNPUBLISHED":d.verbs.push({label:o,primary:!0,run:()=>{this.openReview(e)}});break;case"PUBLISH_PENDING":{let c=n?.raw.publishTimestamp;c&&(d.label=`Scheduled for ${new Date(M(c)).toLocaleString()}`),t&&d.verbs.push({label:"Cancel schedule",run:()=>this.confirmDraft(e,"Cancel the schedule?")});break}case"PUBLISH":{let c=this.tracked.get(e)?.publishingSince??Date.now();Date.now()-c>this.stuckAfterMs&&(d.note="Publishing is taking longer than expected. Publishing again is safe; if that does not help, contact support.",t&&d.verbs.push({label:"Publish again",run:()=>{this.setStatus(e,"PUBLISH",void 0)}}));break}case"PUBLISHED_WITH_DRAFTS":d.verbs.push({label:a,primary:!0,run:()=>{this.openReview(e)}}),t&&d.verbs.push({label:"Unpublish",run:()=>this.confirmDraft(e,"Unpublish this content?")});break;case"PUBLISHED":t&&d.verbs.push({label:"Unpublish",run:()=>this.confirmDraft(e,"Unpublish this content?")});break;default:break}return d}confirmDraft(e,t){this.hooks.show(Ke({id:`draft:${e}`,title:t,meta:this.ctx.entityTitle(e),blocks:[],description:"The content stays in Baack but is no longer public. You can publish it again, now or at a later time.",choices:[{label:"Cancel",run:()=>this.stack.pop()},{label:"Back to draft",primary:!0,run:n=>{n.disabled=!0,this.setStatus(e,"DRAFT_UNPUBLISHED",void 0).then(i=>{i?this.stack.popTo(`entity:${e}`):n.disabled=!1})}}]}),e)}async openReview(e,t){let{store:n,views:i,canPublish:s}=this.ctx,o=n.view(e)?.status;if(o==="PUBLISH")return;let a;try{a=await i.read(e)}catch{a=void 0}let d=n.view(e).raw,c=Li(d,this.ctx.registry),u=await this.changes(e,d,a),{blockers:h,warnings:v}=await this.checks(d),p=`review:${e}`,f=`${u.length} ${u.length===1?"change":"changes"}`,m=this.reviewing?.id===p&&this.stack.path.includes(p)?this.reviewing:void 0,g=m?.body??l("div","level-review");if(ki(g,{changes:u,blockers:h,warnings:v,confirmLabel:s?`Publish ${f}`:"Request approval",...t?{note:t}:{}},{confirm:T=>{this.confirm(e,c,u,void 0,T)},...s&&o==="DRAFT_UNPUBLISHED"?{schedule:()=>this.stack.push(this.scheduleLevel(e,c,u,`Schedule ${f}`))}:{}}),m){this.stack.popTo(p);return}this.reviewing={entityUrn:e,id:p,body:g};let y=this.ctx.entityTitle(e).replace(/^Content for /,"");this.hooks.show({id:p,title:`${s?"Review and publish":"Request approval for"} ${y}`,render:()=>g,dispose:()=>{this.reviewing?.body===g&&(this.reviewing=void 0)}},e)}scheduleLevel(e,t,n,i){let s=l("div","level-schedule");return xi(s,i,(o,a)=>{this.confirm(e,t,n,o,a)},()=>this.stack.pop()),{id:`schedule:${e}`,title:"Schedule the publish",render:()=>s}}async confirm(e,t,n,i,s){let{views:o,feedback:a,canPublish:d}=this.ctx;s.disabled=!0;try{let c=await o.read(e,{version:"LATEST"}),u=Li(c,this.ctx.registry);if(u.size!==t.size||[...u].some(h=>!t.has(h))){await this.view.refresh(e),await this.openReview(e,"The content changed while you were reviewing. Check the list again before publishing.");return}if(d){let h=i?new Date(i).toISOString().replace("Z",""):void 0;if(!await this.setStatus(e,"PUBLISH",h)){s.disabled=!1;return}}else await this.requestApproval(e,n);this.stack.popTo(`entity:${e}`)}catch(c){s.disabled=!1,a.report(c,d?"publish":"request approval",()=>{this.confirm(e,t,n,i,s)})}}async setStatus(e,t,n){let{transport:i,feedback:s}=this.ctx;try{let o=await i.readEntity(e),a=await i.updateEntity(e,{owner:{urn:o.owner.urn},name:o.name,language:o.language,variant:o.variant??"",status:t,...n?{publishTimestamp:n}:{}}),d=this.tracked.get(e)?.status;return this.observe(e,a.status,a.publishTimestamp??void 0),t==="PUBLISH"&&d!=="PUBLISH"&&S(a.status)&&(a.status==="PUBLISHED"?this.published(e):(this.ctx.announcePublished(e,`${this.ctx.entityTitle(e)} was published, but some changes are still not live.`,{info:!1}),this.view.refresh(e))),this.render(),t==="DRAFT_UNPUBLISHED"&&await this.view.refresh(e),!0}catch(o){return s.report(o,t==="PUBLISH"?"publish":"move the content back to draft",()=>{this.setStatus(e,t,n)}),!1}}async requestApproval(e,t){let{transport:n,store:i,toolbar:s}=this.ctx,a=i.view(e).raw.owner?.urn,d=this.ctx.entityTitle(e).replace(/^Content for /,""),c=t.map(h=>`- ${h.name} #${h.sortOrder} (${h.type}): ${h.kind}`),u=await n.createTask({...a?{owner:{urn:a}}:{},title:`Review and publish ${d}`,description:[`Page: ${location.href}`,`Entity: ${e}`,"","Changes:",...c].join(`
|
|
17
|
+
`),status:"PENDING",priority:"MEDIUM",associatedEntities:[{urn:e}]});s.showMessage(`Approval requested (task ${u.urn?.slice(0,8)??""}).`,!0)}async changes(e,t,n){let i=(o,a)=>()=>a.urn?this.ctx.hooks.openHistory({entityUrn:e,entry:o,name:a.name,sortOrder:a.sortOrder,urn:a.urn}):void 0,s=[];for(let o of this.ctx.registry){let a=t[o.entityArray]??[],d=n?.[o.entityArray]??[],c=new Map(d.map(m=>[m.urn,m])),u=m=>`${m.name}#${m.sortOrder}`,h=new Map(d.map(m=>[u(m),m])),v=a.filter(m=>!c.has(m.urn)),p=await Promise.all(v.map(m=>this.liveVersionOf(o,m,c,h.get(u(m))))),f=new Set(a.filter(m=>c.has(m.urn)).map(m=>m.urn));v.forEach((m,g)=>{let y=p[g];y&&f.add(y.urn);let T=y?Ar(y,m):[],b=!y||!we(o,O(o,y),O(o,m));s.push({name:m.name,sortOrder:m.sortOrder,type:o.label,kind:y?"changed":"new",change:b?Si(o,y,m):Sr(T.join("; ")),...b&&T.length>0?{notes:T}:{},select:i(o,m)})});for(let m of d)!f.has(m.urn)&&!a.some(g=>u(g)===u(m))&&s.push({name:m.name,sortOrder:m.sortOrder,type:o.label,kind:"removed",change:Si(o,m,void 0)})}return s}async liveVersionOf(e,t,n,i){try{let{history:s,pagination:o}=await this.ctx.transport.history(e,t.urn),a=s.find(d=>n.has(d.urn));return a?n.get(a.urn):o?.isMorePages?i:void 0}catch{return i}}async checks(e){let t=(e.images??[]).flatMap(i=>Pt(i,this.ctx.requiredImageSlots).map(s=>`${i.name} #${i.sortOrder} has no ${s==="DEFAULT"?"image":s.toLowerCase()} file. Upload one before publishing.`)),n=[];for(let i of e.references??[]){let s=i.entityReference?.urn;if(s)try{let o=await this.ctx.transport.readEntity(s);(o.status==="DRAFT_UNPUBLISHED"||o.status==="PUBLISHED_WITH_DRAFTS")&&n.push(`${i.name} refers to content that ${o.status==="DRAFT_UNPUBLISHED"?"is not published":"has unpublished changes"} (${o.name}).`)}catch{n.push(`${i.name} refers to content that could not be checked.`)}}return{blockers:t,warnings:n}}};function Pt(r,e){let t={DEFAULT:"src",MEDIUM:"mediumSrc",LARGE:"largeSrc"};return e.filter(n=>!r[t[n]])}function Li(r,e){let t=new Set;for(let n of e)for(let i of r[n.entityArray]??[])i.urn&&t.add(i.urn);return t}function Si(r,e,t){let n=o=>{let a=o?.value;if(typeof a=="string")return r.renderedByView?new DOMParser().parseFromString(a,"text/html").body.textContent??"":a},i=n(e),s=n(t);return i!==void 0||s!==void 0?Fe(i??"",s??""):e?t?Ve(r,e,t):`Removed: ${V(r,e)}`:V(r,t)}var Sr=r=>r.charAt(0).toUpperCase()+r.slice(1);function Ar(r,e){let t=[];r.name!==e.name&&t.push(`renamed from ${r.name}`);let n=e.sortOrder-r.sortOrder;return n!==0&&t.push(`moved #${r.sortOrder} \u2192 #${e.sortOrder} (${n>0?"+":"\u2212"}${Math.abs(n)})`),t}var tt=class{stack;onOpen;constructor(e,t,n=()=>{}){this.onOpen=t,this.stack=new Ge(e),this.stack.element.classList.add("outline"),this.stack.onClose(n)}get element(){return this.stack.element}get isOpen(){return this.stack.isOpen}open(){this.stack.open(),this.onOpen()}close(){this.stack.close()}focusFilter(){this.element.querySelector('.stack-level:not([hidden]) input[type="search"]')?.focus()}renderSection(e,t){let n=e.querySelector('input[type="search"]')?.value??"",i=[];if(t.subtitle||t.verbs?.length){let o=l("div","level-lifecycle");if(o.setAttribute("role","group"),o.setAttribute("aria-label","Lifecycle"),t.subtitle&&o.append(l("p","section-status lifecycle-status",t.subtitle)),t.note&&o.append(l("p","message",t.note)),t.verbs?.length){let a=l("div","actions");a.append(...t.verbs.map(d=>this.button(d))),o.append(a)}i.push(o)}for(let o of t.drills??[])i.push(ze(o.label,o.detail,()=>o.open()));let s=l("input");s.type="search",s.placeholder="Filter by name or type",s.setAttribute("aria-label","Filter items"),s.value=n,s.addEventListener("input",()=>Ai(e,s.value)),i.push(s);for(let o of t.groups){if(o.rows.length===0)continue;let a=l("div","outline-group"),d=l("div","group-heading");d.append(l("span","group-label",`${o.label} (${o.rows.length})`)),o.action&&d.append(this.button(o.action)),a.append(d),o.hint&&a.append(l("p","group-hint",o.hint));let c=l("ul","rows");c.setAttribute("aria-label",o.label),c.append(...o.rows.map(u=>this.row(u))),a.append(c),i.push(a)}if(t.actions.length>0){let o=l("div","actions");o.append(...t.actions.map(a=>this.button(a))),i.push(o)}e.replaceChildren(...i),Ai(e,n),e.querySelector("li.row.current")?.scrollIntoView({block:"nearest"})}row(e){let t=l("li",e.current?"row current":"row");e.current&&t.setAttribute("aria-current","true"),t.dataset.filter=`${e.name} ${e.type}`.toLowerCase();let n=l(e.select?"button":"div","row-main");n instanceof HTMLButtonElement&&(n.type="button",n.dataset.row="",n.addEventListener("click",()=>e.select?.(t))),n.append(l("span","row-name",e.name),l("span","meta",` #${e.sortOrder} \xB7 ${e.type}`),...e.status?[l("span",`status status-${e.status.replace(/\s+/g,"-")}`,e.status)]:[],...(e.notes??[]).map(i=>l("span","status note",i))),t.append(n);for(let i of e.flags)t.append(l("span","flag",i));e.action&&t.append(this.button(e.action));for(let i of e.actions??[])t.append(this.button(i));return t}button(e){let t=x(e.label,Z(e),"sm");return e.disabled&&(t.disabled=!0,t.title=e.disabled),t.addEventListener("click",()=>e.run(t)),t}};function Ai(r,e){let t=e.trim().toLowerCase();for(let n of r.querySelectorAll("li.row"))n.hidden=t!==""&&!n.dataset.filter.includes(t)}var Cr=/<\/?[a-z!][^>]*>/i,nt=class{outline;ctx;view;editing;saving;onboarding;live=new Map;focus;selected;levels=new Map;closed;panels=0;newEntity;tasks;constructor(e,t,n,i,s){this.ctx=e,this.view=t,this.editing=n,this.saving=i,this.onboarding=s,this.outline=new tt(e.host,()=>{this.outline.stack.path.length===0?this.openAt(ie(e.store),{focus:!1}):this.render()},()=>{this.focus=void 0,this.selected=void 0,this.closed?.()})}onClose(e){this.closed=e}changed(e){e&&this.live.delete(e),this.outline.isOpen&&this.render()}setTasks(e){this.tasks=e}clear(){this.tasks?.clear(),this.outline.close(),this.outline.stack.reset([]),this.levels.clear(),this.live.clear(),this.focus=void 0}setNewEntity(e){this.newEntity=e,this.outline.isOpen&&this.render()}toggle(){this.outline.isOpen?this.outline.close():this.outline.open()}openEntity(e){this.selected=void 0,this.focus=void 0,this.openAt(e)}selectItem(e){this.focus=void 0,this.selected={entityUrn:e.entityUrn,entry:e.entry,name:e.name,sortOrder:e.sortOrder},this.openAt(e.entityUrn)}focusSlot(e){this.focus={entityUrn:e.entityUrn,entry:e.entry,name:e.name,sortOrder:e.sortOrder},this.openAt(e.entityUrn,{slots:!0})}showAbove(e,t){let{stack:n}=this.outline,i=[`entity:${e}`,`review:${e}`];if(this.outline.isOpen&&i.includes(n.current?.id??"")){n.push(t);return}this.focus=void 0,this.selected=void 0,this.openAt(e,{above:t})}showPanel(e,t={}){let{stack:n}=this.outline,i=e.querySelector(":scope > .title"),s=t.title??i?.textContent??"Editor";t.title||i?.remove(),this.panels+=1;let o=`panel:${this.panels}`,a=!0,d={id:o,title:s,render:()=>e,dispose:()=>{a=!1,t.onLeave?.()}},c={get isOpen(){return a},close:()=>{let v=n.path,p=v.indexOf(o);p>0&&n.popTo(v[p-1])}};e.addEventListener("cancel",()=>c.close());let u=t.focus??!0,h=this.outline.isOpen&&n.path.length>0;return h&&n.current?.id.startsWith("panel:")?n.replace(d,{focus:u}):h&&(!t.entityUrn||n.path.includes(`entity:${t.entityUrn}`))?n.push(d,{focus:u}):(this.focus=void 0,this.selected=void 0,this.openAt(t.entityUrn,{above:d,focus:u})),c}openAt(e,{slots:t=!1,focus:n=!0,above:i=void 0}={}){let s=[this.pageLevel()];e&&this.ctx.store.view(e)&&s.push(this.entityLevel(e)),t&&this.focus&&s.push(this.slotsLevel(this.focus)),i&&s.push(i),this.outline.stack.reset(s,{focus:n}),this.outline.open(),this.render()}async render(){this.outline.isOpen&&await Promise.all(this.outline.stack.path.map(e=>this.levels.get(e)?.refresh()))}remember(e,t,n){return this.levels.set(e.id,{level:e,body:t,refresh:n}),e}pageLevel(){let e=l("div","level-page"),t={id:"page",title:"This page",render:()=>e};return this.remember(t,e,()=>{let{store:n,toolbar:i}=this.ctx,s=re(n,n.entities()),o=s.map(a=>ze(this.ctx.entityTitle(a),i.lifecycleOf(a)?.label??he(n.view(a)?.status),()=>this.outline.stack.push(this.entityLevel(a))));if(s.length===0&&o.push(l("p","hint","No content has loaded for this page.")),this.newEntity){let a=this.newEntity,d=l("button","","New entity\u2026");d.type="button",P(d,"Create an entity, such as a menu shared by many pages"),d.addEventListener("click",()=>a());let c=l("div","actions");c.append(d),o.push(c)}e.replaceChildren(...o)})}entityLevel(e){let t=`entity:${e}`,n=this.levels.get(t);if(n)return n.level;let i=l("div","level-entity"),s={id:t,title:this.ctx.entityTitle(e),render:()=>i,onShow:()=>{this.render()}};return this.remember(s,i,async()=>{if(!this.ctx.store.view(e))return;let o=await this.section(e,e===ie(this.ctx.store));this.outline.stack.path.includes(t)&&this.outline.renderSection(i,o)})}togglePending(){if(this.outline.isOpen&&this.outline.stack.current?.id==="unsaved"){this.outline.close();return}this.focus=void 0,this.selected=void 0,this.outline.stack.reset([this.pageLevel(),this.pendingLevel()]),this.outline.open()}pendingLevel(){let e=l("div","level-unsaved"),t={id:"unsaved",title:"Unsaved changes",render:()=>e};return this.remember(t,e,()=>e.replaceChildren(...this.ctx.toolbar.pendingSections()))}slotsLevel(e){let t=l("div","level-slots"),n={id:"slots",title:`Slots for ${e.name}`,render:()=>t};return this.remember(n,t,()=>{!this.focus||!this.ctx.store.view(this.focus.entityUrn)||this.outline.renderSection(t,this.slotsSection(this.focus))})}slotsSection(e){let{store:t,hooks:n}=this.ctx,{entityUrn:i,entry:s,name:o}=e,a=(t.view(i).raw[s.entityArray]??[]).filter(h=>h.name===o&&h.urn).sort((h,v)=>h.sortOrder-v.sortOrder),d=a.find(h=>h.sortOrder===e.sortOrder),c=async h=>{d&&await n.moveSlot(e,d,h)&&(this.focus={...e,sortOrder:h},this.render())},u=a.map(h=>h===d?{name:o,sortOrder:h.sortOrder,type:s.label,status:"moving",flags:[],current:!0,actions:[{label:"Rename\u2026",run:()=>n.rename(e,h)}]}:{name:o,sortOrder:h.sortOrder,type:s.label,status:"",flags:[],...d?{actions:[{label:`Swap with #${d.sortOrder}`,run:()=>{c(h.sortOrder)}}]}:{}});if(d){let h=new Set(a.map(m=>m.sortOrder)),v=a[0]?.sortOrder??0,p=a.at(-1)?.sortOrder??0,f=Array.from({length:Math.max(0,p-v)},(m,g)=>v+g).filter(m=>!h.has(m));for(let m of[...f.length<=5?f:[],p+1])u.push({name:o,sortOrder:m,type:s.label,status:"empty",flags:[],actions:[{label:"Move here",run:()=>{c(m)}}]});u.sort((m,g)=>m.sortOrder-g.sortOrder)}return{subtitle:d?`Moving ${o} #${d.sortOrder}. Swap it with another, move it to a free sort order, or rename it.`:`${o} #${e.sortOrder} is no longer here.`,groups:[{label:`Slots for ${o}`,rows:u}],actions:[{label:"Show all items",run:()=>{this.focus=void 0,this.outline.stack.popTo(`entity:${i}`)}}]}}async section(e,t){let{store:n,pending:i,registry:s}=this.ctx,o=n.view(e),{urns:a,found:d}=await this.counterpartUrns(e),c=this.view.mode==="live"?!this.view.draftsOnLivePage.has(e):S(o.status)||d,u=[],h=[],v=[];for(let m of s){let g=o.raw[m.entityArray]??[];for(let y of g){if(!y.urn)continue;let T={entityUrn:e,entry:m,name:y.name,sortOrder:y.sortOrder},b=this.view.bindingsAt(T),k=b.filter(J=>!J.element.closest("head")),A=g.filter(J=>J.name===y.name&&J.sortOrder===y.sortOrder).length,q=y.urn,ft={name:y.name,sortOrder:y.sortOrder,type:m.label,status:i.getEdit(q)?"unsaved":c?a.has(q)?"up to date":"unpublished changes":"",flags:[...Or(m,y,A,this.ctx.requiredImageSlots),...b.some(J=>J.element.hasAttribute("data-text-unsafe-literal"))?["the site renders this as HTML"]:[]],action:{label:"History",run:()=>this.ctx.hooks.openHistory({...T,urn:q})},...this.referenceAction(y),current:Ci(this.selected,T),select:J=>{let Ft={...T,urn:q,anchor:J,binding:k[0]};k[0]&&k[0].element.scrollIntoView({block:"center"}),this.editing.open(k[0]&&k[0].element.getClientRects().length>0?Ft:{...Ft,binding:void 0})}};k.length>0?u.push(ft):b.length>0||!m.component?h.push(ft):v.push({...ft,notes:["not used"]})}}let p=this.view.missingBindings(e).map(m=>{let g=H({entityUrn:e,type:m.entry.type,name:m.name,sortOrder:m.sortOrder});return{name:m.name,sortOrder:m.sortOrder,type:m.entry.label,status:i.getCreate(g)?"unsaved":"not in content",flags:[],current:Ci(this.selected,{entityUrn:e,entry:m.entry,name:m.name,sortOrder:m.sortOrder}),action:{label:"Create",run:y=>{m.element.getClientRects().length>0&&m.element.scrollIntoView({block:"center"}),this.editing.open({entityUrn:e,entry:m.entry,name:m.name,sortOrder:m.sortOrder,anchor:y,binding:m})}}}}),f=this.ctx.toolbar.lifecycleOf(e);return{subtitle:f?.label??he(o.status),...f?.note?{note:f.note}:{},verbs:(f?.verbs??[]).map(m=>({label:m.label,run:()=>m.run(),...m.primary?{primary:!0}:{},...m.disabled?{disabled:m.disabled}:{}})),...this.tasks?{drills:[this.tasksDrill(this.tasks,e)]}:{},groups:[{label:"On this page",rows:u},{label:"Page settings",rows:h},{label:"Not used on this page",rows:v,hint:"In the content, but nothing on this page shows them."},{label:"In the page, not in the content",rows:p,hint:"Content items on the page that are not saved in the content yet. Each shows its placeholder until it is created.",action:{label:"Create all",run:()=>this.saving.confirmCreateAll(e,this.view.missingBindings(e).filter(m=>!m.entry.showsPageRendering?.(m.element)).length)}}],actions:[{label:"Add item",run:m=>this.showAddItem(e,m)},...t?[{label:"New page like this",run:()=>this.onboarding.offerNewPageLike(e)}]:[]]}}tasksDrill(e,t){return{label:"Tasks",detail:e.summary(t),open:()=>this.outline.stack.push(e.listLevel(t))}}referenceAction(e){let t=e.entityReference?.urn;return!t||!this.ctx.store.view(t)?{}:{actions:[{label:`${this.ctx.entityTitle(t)} \u203A`,run:()=>this.outline.stack.push(this.entityLevel(t))}]}}counterpartUrns(e){let t=this.live.get(e);return t||(t=this.ctx.views.read(e,this.view.mode==="live"?{version:"LATEST"}:{}).then(n=>{let i=new Set;for(let s of this.ctx.registry)for(let o of n[s.entityArray]??[])o.urn&&i.add(o.urn);return i}).then(n=>({urns:n,found:!0})).catch(()=>({urns:new Set,found:!1})),this.live.set(e,t)),t}showAddItem(e,t){let{store:n,registry:i}=this.ctx,s=new R(`Add an item to ${this.ctx.entityTitle(e)}`,[{key:"type",label:"Type",value:"text",options:i.map(a=>({value:a.type,label:a.label}))},{key:"name",label:"Name",value:""},{key:"sortOrder",label:"Sort order",value:"0"}],"Next",a=>{let d=this.ctx.entry(a.type),c=a.name??"",u=Number(a.sortOrder);if(!/^[A-Za-z0-9_-]+$/.test(c))return s.setError("Use letters, numbers, - and _ in the name.");if(!Number.isInteger(u))return s.setError("The sort order must be a whole number.");s.setBusy(!0,"Checking\u2026"),this.view.refresh(e).then(()=>{if(s.setBusy(!1),n.itemAt(e,d,c,u)){s.setError(`An item already exists at ${c} #${u}. Choose a free sort order.`);return}o.close(),this.editing.open({entityUrn:e,entry:d,name:c,sortOrder:u,anchor:t,binding:void 0})})}),o=this.ctx.panels.show(s.element,{entityUrn:e})}};function Or(r,e,t,n){let i=[];t>1&&i.push(`${t} items share this sort order`);let s=e;if(r.type==="text"&&Cr.test(String(s.value??""))&&i.push("contains markup"),r.type==="image"){s.altText||i.push("no alt text");for(let o of Pt(e,n))i.push(o==="DEFAULT"?"no image file":`no ${o.toLowerCase()} file`)}return i}function Ci(r,e){return r!==void 0&&r.entityUrn===e.entityUrn&&r.entry===e.entry&&r.name===e.name&&r.sortOrder===e.sortOrder}function st(r,e){if(e.state==="loading"){r.replaceChildren(it("Reading tasks\u2026"));return}if(e.state==="failed"){let o=x("Try again","outline","sm");o.addEventListener("click",()=>e.retry());let a=l("div","actions");a.append(o),r.replaceChildren(It(e.failure.message),...z(e.failure.debug),a);return}let t=[];if(e.cards.length===0)t.push(it("No open tasks."));else{let o=l("ul","task-list");o.setAttribute("aria-label","Open tasks, most urgent first");for(let a of e.cards){let d=l("li"),c=l("button","task-card");c.type="button",c.dataset.row="",c.append(Oi(a));let u=l("span","stack-chevron");u.setAttribute("aria-hidden","true"),u.append(L("chevron-right")),c.append(u),c.addEventListener("click",()=>e.open(a.urn)),d.append(c),o.append(d)}t.push(it(`${e.cards.length} open ${e.cards.length===1?"task":"tasks"}`),o)}let n=x("Refresh","ghost","sm");n.addEventListener("click",()=>e.refresh());let i=x("New task\u2026","outline","sm");i.addEventListener("click",()=>e.newTask());let s=l("div","actions");s.append(n,i),t.push(s),r.replaceChildren(...t)}function Oi(r,{title:e=!0}={}){let t=l("span","task-card-text");e&&t.append(l("span","task-title",r.title));let n=l("span","task-facts");if(n.append(l("span",`status task-status tone-${r.status.tone}`,r.status.label)),r.priority.value!=="NONE"&&n.append(l("span","meta",`${r.priority.label} priority`)),r.due&&(n.append(l("span","meta",`Due ${Mr(r.due.date)}`)),r.due.overdue&&n.append(l("span","flag","overdue"))),r.assignee){let i=l("span","task-assignee"),s=l("span",`avatar avatar-${r.assignee.colour}`,r.assignee.initials);s.setAttribute("aria-hidden","true"),i.append(s,l("span","meta",r.assignee.name)),r.assignee.email&&i.append(l("span","meta task-email",r.assignee.email)),n.append(i)}else n.append(l("span","meta","Unassigned"));return t.append(n),r.blockedBy.length>0&&t.append(l("span","flag task-blocked",`Blocked by ${r.blockedBy.map(i=>i.name).join(", ")}`)),t}var rt=class{element;facts;description;statusSelect;statusButton;statusError;commentBox;commentButton;commentError;activityStatus;activity;moreButton;current="";constructor(e,t){this.element=l("div","level-task"),this.facts=l("div","task-head"),this.description=l("p","task-description");let n=l("label","field");this.statusSelect=l("select"),this.statusSelect.name="status";for(let h of e)this.statusSelect.append(Object.assign(l("option","",h.label),{value:h.value}));this.statusSelect.addEventListener("change",()=>this.syncStatusButton()),n.append(l("span","caption","Status"),ee(this.statusSelect)),this.statusButton=x("Change status","outline","sm"),this.statusButton.addEventListener("click",()=>t.setStatus(this.statusSelect.value)),this.statusError=It("");let i=l("div","actions");i.append(this.statusButton);let s=l("div","task-section");s.append(n,this.statusError,i);let o=l("label","field");this.commentBox=l("textarea"),this.commentBox.name="comment",this.commentBox.rows=3,this.commentBox.addEventListener("input",()=>{this.commentButton.disabled=this.commentBox.value.trim()===""}),o.append(l("span","caption","Comment"),this.commentBox),this.commentButton=x("Comment","primary","sm"),this.commentButton.disabled=!0,this.commentButton.addEventListener("click",()=>t.comment(this.commentBox.value.trim())),this.commentError=It("");let a=l("div","actions");a.append(this.commentButton);let d=l("div","task-section");d.append(o,this.commentError,a);let c=l("div","group-heading");c.append(l("span","group-label","Activity")),this.activityStatus=it(""),this.activity=l("ol","task-activity"),this.activity.setAttribute("aria-label","Activity, newest first"),this.moreButton=x("Load more","ghost","sm"),this.moreButton.hidden=!0,this.moreButton.addEventListener("click",()=>t.more());let u=l("div","task-section");u.append(c,this.activityStatus,this.activity,this.moreButton),this.element.append(this.facts,this.description,s,d,u)}setTask(e,t){this.facts.replaceChildren(Oi(e,{title:!1})),this.description.textContent=t||"No description.",this.description.classList.toggle("meta",!t),this.current=e.status.value,this.statusSelect.value=e.status.value,this.syncStatusButton()}setStatusBusy(e){this.statusSelect.disabled=e,this.statusButton.disabled=e||this.statusSelect.value===this.current,this.statusButton.textContent=e?"Changing\u2026":"Change status",e&&(this.statusError.textContent="")}setStatusError(e){this.statusError.replaceChildren(e.message,...z(e.debug))}setCommentBusy(e){this.commentBox.disabled=e,this.commentButton.disabled=e||this.commentBox.value.trim()==="",this.commentButton.textContent=e?"Sending\u2026":"Comment",e&&(this.commentError.textContent="")}clearComment(){this.commentBox.value="",this.commentButton.disabled=!0}setCommentError(e){this.commentError.replaceChildren(e.message,...z(e.debug))}setActivityStatus(e){this.activityStatus.textContent=e}setActivity(e,t){this.activity.replaceChildren(...e.map(n=>{let i=l("li","task-entry"),s=l("div","task-entry-head"),o=l("span","meta",n.when);return o.title=`${n.whenUtc} UTC`,s.append(l("span","row-name",n.who),l("span","meta",n.what.toLowerCase()),o),i.append(s),n.comment!==void 0&&i.append(l("p","task-comment",n.comment)),i})),this.moreButton.hidden=!t}setMoreBusy(e){this.moreButton.disabled=e,this.moreButton.textContent=e?"Loading\u2026":"Load more"}syncStatusButton(){this.statusButton.disabled=this.statusSelect.value===this.current}};function Mr(r){return r.toLocaleDateString(void 0,{day:"numeric",month:"short",year:"numeric"})}function it(r){let e=l("p","hint");return e.setAttribute("role","status"),e.textContent=r,e}function It(r){let e=l("p","error");return e.setAttribute("role","alert"),e.textContent=r,e}var at=class{ctx;stack;options;entities=new Map;shown=new Map;constructor(e,t,n){this.ctx=e,this.stack=t,this.options=n}summary(e){let t=this.entities.get(e)??this.load(e);if(t.state==="loading")return"Reading tasks\u2026";if(t.state==="failed")return"Couldn't read the tasks";let n=t.tasks.filter(ye).length;return n===0?"No open tasks":`${n} open`}clear(){this.entities.clear()}listLevel(e){let t=ot(e),n=l("div","level-tasks"),i=()=>{let s=this.entities.get(e)??this.load(e);if(s.state==="loading")return st(n,{state:"loading"});if(s.state==="failed")return st(n,{state:"failed",failure:s.failure,retry:()=>this.reload(e)});st(n,{state:"ready",cards:s.tasks.filter(ye).sort(Kt).map(o=>this.card(s,o)),open:o=>this.stack.push(this.taskLevel(e,o)),refresh:()=>this.reload(e),newTask:()=>this.stack.push(this.newTaskLevel(e))})};return this.track({id:t,title:"Tasks",render:()=>n,onShow:i},e,i)}reload(e){this.load(e),this.update(e)}load(e){let t=this.entities.get(e),n={state:"loading",tasks:t?.tasks??[],people:t?.people??[]};this.entities.set(e,n);let i=this.options.ownerOf(e);return(i?this.ctx.transport.tasksAbout(e,i):Promise.reject(new Error("the content has no owner"))).then(o=>{n.state="ready",n.tasks=o.tasks,n.people=o.identities.map(Wt)},o=>{n.state="failed",n.failure=U(o,"read the tasks")}).then(()=>{this.entities.get(e)===n&&this.update(e)}),n}update(e){for(let t of this.shown.values())t.entityUrn===e&&t.redraw();this.options.changed(e)}track(e,t,n){return this.shown.set(e.id,{entityUrn:t,redraw:n}),{...e,dispose:()=>{this.shown.delete(e.id),e.dispose?.()}}}directory(e){return{...gt,people:e.people,tasks:e.tasks}}card(e,t){return Jt(t,{directory:this.directory(e)})}actor(e){let t=this.options.ownerOf(e);return t?this.options.actorIn(t):void 0}replace(e,t){let n=this.entities.get(e);if(!n)return;let i=n.tasks.findIndex(s=>s.urn===t.urn);i<0?n.tasks.push(t):n.tasks[i]=t}taskLevel(e,t){let n=this.entities.get(e),i=()=>this.entities.get(e)?.tasks.find(f=>f.urn===t),s=_t.filter(f=>f!=="UNDEFINED").map(f=>({value:f,label:vt[f]})),o=[],a,d=!1,c=new rt(s,{setStatus:f=>{this.setStatus(e,t,f,c,()=>h(!0))},comment:f=>{this.comment(e,t,f,c,()=>h(!0))},more:()=>{h(!1)}}),u=()=>{let f=this.entities.get(e),m=f?this.directory(f):gt;c.setActivity(o.map(g=>Pr(g,m)),a!==void 0)},h=async f=>{f?c.setActivityStatus(o.length===0?"Reading the activity\u2026":""):c.setMoreBusy(!0);try{let m=await this.ctx.transport.taskLogs(t,f?void 0:a);o=f?m.logs:[...o,...m.logs],a=m.pagination?.isMorePages?m.pagination.after??void 0:void 0,c.setActivityStatus(o.length===0?"No activity yet.":""),u()}catch(m){c.setActivityStatus(U(m,"read the activity").message)}finally{c.setMoreBusy(!1)}},v=()=>{let f=i();if(!f){c.element.replaceChildren(l("p","message","This task is no longer here. Go back to see the open tasks."));return}c.setTask(this.card(this.entities.get(e),f),f.description),u(),d||(d=!0,h(!0))},p=(n?.tasks.find(f=>f.urn===t)?.title??"Task")||"Task";return this.track({id:`task:${t}`,title:p,render:()=>c.element,onShow:v},e,v)}async setStatus(e,t,n,i,s){i.setStatusBusy(!0);let o;try{o=await this.ctx.transport.setTaskStatus(t,n,this.actor(e))}catch(a){i.setStatusBusy(!1),i.setStatusError(U(a,"change this task's status"));return}i.setStatusBusy(!1),this.replace(e,o),ye(o)?s():(this.ctx.toolbar.showMessage(`${vt[o.status]}: \u201C${o.title}\u201D. It is no longer in the open tasks.`,!0),this.stack.popTo(ot(e))),this.update(e)}async comment(e,t,n,i,s){if(n){i.setCommentBusy(!0);try{await this.ctx.transport.commentOnTask(t,n,this.actor(e))}catch(o){i.setCommentBusy(!1),i.setCommentError(U(o,"add this comment"));return}i.setCommentBusy(!1),i.clearComment(),await s()}}newTaskLevel(e){let n=[...this.entities.get(e)?.people??[]].sort((s,o)=>s.name.localeCompare(o.name)),i=new R("New task",[{key:"title",label:"Title",value:"",required:!0},{key:"description",label:"Description",value:"",kind:"multiline"},{key:"due",label:"Due date",value:"",kind:"date"},{key:"priority",label:"Priority",value:"NONE",options:Gt.map(s=>({value:s,label:zt[s]}))},{key:"assignee",label:"Assignee",value:"",options:[{value:"",label:"Unassigned"},...n.map(s=>({value:s.urn,label:s.email?`${s.name||s.urn} (${s.email})`:s.name||s.urn}))]}],"Create task",s=>{this.create(e,s,i)});return i.element.querySelector(":scope > .title")?.remove(),i.element.addEventListener("cancel",()=>this.stack.popTo(ot(e))),{id:`new-task:${e}`,title:"New task",render:()=>i.element}}async create(e,t,n){let i=t.title??"";if(!i)return n.setError("Give the task a title.");let s=this.options.ownerOf(e);if(!s)return n.setError("Couldn't create the task: the content has no owner.");let o=t.due?Vt(`${t.due}T23:59`):void 0,a=this.actor(e),d=jt({owner:{urn:s},title:i,description:t.description??"",priority:t.priority||"NONE",...o?{dueTimestamp:o}:{},...t.assignee?{assignee:{urn:t.assignee}}:{},associatedEntities:[{urn:e}],...a?{identityForLogs:{urn:a}}:{}});n.setError(""),n.setBusy(!0,"Creating\u2026");let c;try{c=await this.ctx.transport.createTask(d)}catch(u){n.setBusy(!1),n.setError(U(u,"create the task").message);return}this.replace(e,c),this.ctx.toolbar.showMessage(`Created the task \u201C${c.title}\u201D.`,!0),this.stack.popTo(ot(e)),this.update(e)}};function ot(r){return`tasks:${r}`}function Pr(r,e){let t=Ut(r.createdTimestamp);return{who:r.identity?Yt(e,r.identity):"Someone",when:t?t.toLocaleString():"Unknown time",whenUtc:r.createdTimestamp??"",what:qt(r.activity),...r.comment!=null?{comment:r.comment}:{}}}var $t="A site that is built ahead of time shows it to visitors after its next build.";function Bt(r){return typeof r=="string"?r:void 0}async function Mi(r,e,t,n,{info:i=!0,quiet:s=!1}={}){let o=(a,d)=>s?r.announce(n,a,d):r.showMessage(a?`${n} ${a}`:n,d);if(o("",i),e!==void 0)try{let a=typeof e=="string"?e:await e(t);a&&o(a,i)}catch(a){console.error("Baack editor: the site's afterPublish callback failed",a);let d=a instanceof Error?a.message:String(a);o(`The site's after-publish step failed: ${d}`,!1)}}var Ht=50,Ir=0;function Nt(r){return`${r.path} (${r.language}${r.variant?` \xB7 ${r.variant}`:""})`}var dt=class{element;input;value;source;onChange;listbox;status;note;createArea;id=`baack-entity-picker-${Ir+=1}`;listing;created=[];loading;options=[];active=-1;chosenLabel="";constructor(e,t,n,i){this.source=e,this.onChange=i,this.element=l("div","entity-picker"),this.input=l("input"),this.input.type="text",this.input.autocomplete="off",this.input.spellcheck=!1,this.input.placeholder="Type a path, such as /menu",this.input.setAttribute("role","combobox"),this.input.setAttribute("aria-autocomplete","list"),this.input.setAttribute("aria-expanded","false"),this.input.setAttribute("aria-controls",`${this.id}-list`),this.value=l("input"),this.value.type="hidden",this.value.name=t,this.value.value=n,this.listbox=l("ul","entity-options"),this.listbox.id=`${this.id}-list`,this.listbox.setAttribute("role","listbox"),this.listbox.setAttribute("aria-label","Entities"),this.listbox.hidden=!0,this.status=l("p","hint"),this.status.setAttribute("role","status"),this.note=l("p","hint"),this.createArea=l("div","entity-create");let s=l("div","combobox-field");s.append(L("search"),this.input,L("chevron-down")),this.element.append(s,this.listbox,this.status,this.note,this.createArea,this.value),this.input.addEventListener("focus",()=>this.open()),this.input.addEventListener("input",()=>this.open()),this.input.addEventListener("keydown",this.onKeyDown),this.input.addEventListener("blur",()=>{this.close(),this.input.value!==this.chosenLabel&&(this.input.value=this.chosenLabel)}),n&&this.showChosen(n)}async showChosen(e){this.chosenLabel=e,this.input.value=e;try{let t=await this.source.describe(e);if(this.value.value!==e)return;this.chosenLabel=Nt(t),this.input.value===e&&(this.input.value=this.chosenLabel)}catch(t){this.source.report(t,"show the entity referred to",()=>{this.showChosen(e)})}this.showNote(e)}async showNote(e){try{let t=await this.source.note(e);this.value.value===e&&(this.note.textContent=t)}catch(t){this.source.report(t,"check the entity referred to",()=>{this.showNote(e)})}}open(){this.listbox.hidden=!1,this.input.setAttribute("aria-expanded","true"),this.loading??=this.source.list(e=>{this.listing=e,this.render()}).then(e=>{this.listing=e,this.render()}).catch(e=>{this.loading=void 0,this.status.textContent="The list of entities could not be loaded.",this.source.report(e,"list the entities",()=>this.open())}),this.render()}close(){this.listbox.hidden=!0,this.input.setAttribute("aria-expanded","false"),this.input.removeAttribute("aria-activedescendant"),this.active=-1}render(){if(this.listbox.hidden)return;let e=this.input.value===this.chosenLabel?"":this.input.value.trim().toLowerCase(),t=this.listing?.entities??[],n=[...t,...this.created.filter(d=>!t.some(c=>c.urn===d.urn))].filter(d=>!e||Nt(d).toLowerCase().includes(e)).sort((d,c)=>d.path===c.path?+(c.language===this.source.language)-+(d.language===this.source.language):0);this.options=n.slice(0,Ht).map(d=>{let c=l("li","entity-option");c.append(l("span","",d.path),l("span","meta",` ${d.language}${d.variant?` \xB7 ${d.variant}`:""}`));let u=d.urn===this.value.value;return c.setAttribute("aria-selected",String(u)),u&&c.append(L("check")),{element:c,choose:()=>this.choose(d)}});let i=this.input.value.trim(),s=e&&i.startsWith("/")?i:e?`/${i}`:"",o=l("li","entity-option create",s?`Create a new entity "${s}"\u2026`:"Create a new entity\u2026");o.prepend(L("plus")),this.options.push({element:o,choose:()=>{this.create(s)}}),this.options.forEach((d,c)=>{d.element.id=`${this.id}-option-${c}`,d.element.setAttribute("role","option"),d.element.addEventListener("mousedown",u=>u.preventDefault()),d.element.addEventListener("click",()=>d.choose())}),this.listbox.replaceChildren(...this.options.map(d=>d.element)),this.setActive(Math.min(this.active,this.options.length-1));let a=t.length+this.created.length;this.status.textContent=this.listing?[n.length>Ht?`Showing ${Ht} of ${n.length}; type to narrow.`:"",this.listing.complete?"":"The search was still running, so some entities may be missing.",a===0?"No entities found.":""].filter(Boolean).join(" "):"Loading entities\u2026"}setActive(e){this.active=e,this.options.forEach((n,i)=>n.element.classList.toggle("active",i===e));let t=this.options[e];t?(this.input.setAttribute("aria-activedescendant",t.element.id),t.element.scrollIntoView({block:"nearest"})):this.input.removeAttribute("aria-activedescendant")}choose(e){this.value.value=e.urn,this.chosenLabel=Nt(e),this.input.value=this.chosenLabel,this.note.textContent="",this.close(),this.onChange(),this.showNote(e.urn)}async create(e){this.close(),this.input.disabled=!0;try{let t=await this.source.create(this.createArea,e);t&&(this.created.push(t),this.choose(t))}finally{this.createArea.replaceChildren(),this.input.disabled=!1,this.input.focus()}}onKeyDown=e=>{let t=!this.listbox.hidden;if(e.key==="ArrowDown"||e.key==="ArrowUp"){e.preventDefault(),t||this.open();let n=e.key==="ArrowDown"?1:-1;this.setActive((this.active+n+this.options.length)%this.options.length)}else e.key==="Enter"&&t&&this.active>=0&&!(e.metaKey||e.ctrlKey)?(e.preventDefault(),e.stopPropagation(),this.options[this.active]?.choose()):e.key==="Escape"&&t&&(e.preventDefault(),e.stopPropagation(),this.close())}};var $r=0,lt=class{trigger;items;menu;constructor(e,t){this.trigger=e,this.items=t,e.id||=`baack-menu-trigger-${++$r}`,e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded","false"),e.addEventListener("mousedown",n=>n.preventDefault()),e.addEventListener("click",n=>this.menu?this.close(!0):this.open(n.detail===0?"first":void 0)),e.addEventListener("keydown",n=>{(n.key==="ArrowDown"||n.key==="ArrowUp")&&(n.preventDefault(),this.open(n.key==="ArrowDown"?"first":"last"))})}get isOpen(){return this.menu!==void 0}open(e){this.close(!1);let t=l("div","menu");t.setAttribute("role","menu"),t.setAttribute("aria-labelledby",this.trigger.id);for(let n of this.items()){let i=l("button",n.destructive?"menu-item destructive":"menu-item");i.type="button",i.setAttribute("role","menuitem"),i.tabIndex=-1,n.icon&&i.append(L(n.icon)),i.append(n.label),i.addEventListener("mousedown",s=>s.preventDefault()),i.addEventListener("click",()=>{this.close(i.matches(":focus")),n.run()}),t.append(i)}t.addEventListener("keydown",this.onKey),(this.trigger.closest(".panel")??this.trigger.parentElement).append(t),this.menu=t,this.trigger.setAttribute("aria-expanded","true"),this.trigger.setAttribute("aria-controls",t.id=`${this.trigger.id}-list`),this.place(),window.addEventListener("pointerdown",this.onOutside,!0),window.addEventListener("scroll",this.onScroll,!0),window.addEventListener("resize",this.onScroll),e&&this.focusAt(e==="first"?0:-1)}close(e){this.menu&&(this.menu.remove(),this.menu=void 0,this.trigger.setAttribute("aria-expanded","false"),this.trigger.removeAttribute("aria-controls"),window.removeEventListener("pointerdown",this.onOutside,!0),window.removeEventListener("scroll",this.onScroll,!0),window.removeEventListener("resize",this.onScroll),e&&this.trigger.focus())}entries(){return[...this.menu?.querySelectorAll('[role="menuitem"]')??[]]}focusAt(e){let t=this.entries(),n=t.at(e%t.length);for(let i of t)i.tabIndex=i===n?0:-1;n?.focus()}onKey=e=>{let t=this.entries(),n=t.indexOf(e.target);if(e.key==="Escape")e.preventDefault(),e.stopPropagation(),this.close(!0);else if(e.key==="Tab")e.preventDefault(),this.close(!0);else if(e.key==="ArrowDown"||e.key==="ArrowUp")e.preventDefault(),this.focusAt((n+(e.key==="ArrowDown"?1:-1)+t.length)%t.length);else if(e.key==="Home"||e.key==="End")e.preventDefault(),this.focusAt(e.key==="Home"?0:-1);else if(e.key.length===1&&/\S/.test(e.key)){let i=e.key.toLowerCase();for(let s=1;s<=t.length;s++){let o=(n+s)%t.length;if(t[o].textContent.trim().toLowerCase().startsWith(i)){this.focusAt(o);break}}}};onOutside=e=>{let t=e.composedPath();!t.includes(this.menu)&&!t.includes(this.trigger)&&this.close(!1)};onScroll=e=>{e.type==="scroll"&&this.menu&&e.composedPath().includes(this.menu)||this.close(!1)};place(){let e=this.menu,t=this.trigger.getBoundingClientRect();e.style.minWidth=`${Math.max(t.width,128)}px`;let{width:n,height:i}=e.getBoundingClientRect(),s=t.bottom+4,o=s+i<=window.innerHeight-8||t.top-i-4<8?s:t.top-i-4;e.style.top=`${Math.max(8,o)}px`,e.style.left=`${Math.min(Math.max(8,t.right-n),window.innerWidth-n-8)}px`}};var Br=["GBP","EUR","USD","JPY","CHF","CAD","AUD","NZD","SEK","NOK","DKK","PLN","INR","CNY","BRL"],Hr=/Mac|iPhone|iPad/.test(navigator.userAgent),ct=class{element;title;form;description;issues;error;errorDebug;sendButton;extras;menu;buttons;choices;hint;anchor;actions;inputs=new Map;slotStatus=new Map;reposition=()=>this.place();side;onEnd;anchorObserver=new ResizeObserver(this.reposition);entities;currentValues={};constructor(e){this.element=l("div","panel popover"),this.element.setAttribute("role","dialog"),this.element.hidden=!0,this.title=l("div","title"),this.form=l("div","form"),this.description=l("p","hint"),this.issues=l("ul","issues"),this.error=l("p","error"),this.error.setAttribute("role","alert"),this.errorDebug=l("div","error-debug");let t=l("button","","Revert");t.type="button",this.sendButton=l("button","primary","Save"),this.sendButton.type="button";for(let n of[t,this.sendButton])n.addEventListener("mousedown",i=>i.preventDefault());t.addEventListener("click",()=>this.actions?.revert()),this.sendButton.addEventListener("click",()=>this.actions?.send()),this.element.addEventListener("keydown",n=>{n.key==="Escape"?(n.preventDefault(),this.actions?.revert()):n.key==="Enter"&&(n.metaKey||n.ctrlKey)&&(n.preventDefault(),this.actions?.send())}),this.extras=l("div","extras"),this.buttons=l("div","actions"),this.buttons.append(t,this.sendButton),this.choices=l("div","actions"),this.choices.hidden=!0,this.hint=l("p","hint"),this.element.append(this.title,this.form,this.description,this.issues,this.error,this.errorDebug,this.extras,this.buttons,this.choices,this.hint),e.root.append(this.element),new ResizeObserver(()=>{this.element.hidden||(this.side=void 0,this.place())}).observe(this.element)}setEntitySource(e){this.entities=e}get isOpen(){return!this.element.hidden}show(e,t,n,i,s){this.open(e,t,n,i,s,!1),this.form.replaceChildren(),this.inputs.clear(),this.place()}showForm(e,t,n,i,s,o,a){this.open(e,t,n,`${Hr?"\u2318":"Ctrl"}+Enter to save \xB7 Esc to revert`,o,a),this.inputs.clear(),this.slotStatus.clear(),this.currentValues=s,this.form.replaceChildren(...i.map(d=>this.field(d,s[d.key],()=>o.input(this.values())))),this.place(),this.form.querySelector('input:not([type="hidden"]), textarea, select')?.focus()}showChoices(e,t,n,i,s,o){this.open(e,t,n,"",{send:()=>{},revert:()=>o.at(-1)?.run()},!0),this.inputs.clear(),this.form.replaceChildren(...i.map(a=>{let d=l("div","field");return d.append(l("span","caption",a.label),l("pre","snippet",a.text)),d})),this.setDescription(s),this.buttons.hidden=!0,this.choices.hidden=!1,this.choices.replaceChildren(...o.map(a=>{let d=x(a.label,Z(a));return d.addEventListener("click",()=>a.run()),d})),this.place()}whenEnded(e){this.onEnd=e}ended(){let e=this.onEnd;this.onEnd=void 0,e?.()}hide(){this.ended(),this.menu?.close(!1),this.element.hidden=!0,this.anchor=void 0,this.side=void 0,this.anchorObserver.disconnect(),this.actions=void 0,window.removeEventListener("scroll",this.reposition,!0),window.removeEventListener("resize",this.reposition),window.removeEventListener("keydown",this.onWindowKey)}onWindowKey=e=>{e.key!=="Escape"||e.defaultPrevented||this.element.hidden||(e.preventDefault(),this.actions?.revert())};values(){let e={...this.currentValues};for(let[t,n]of this.inputs)n instanceof HTMLInputElement&&n.type==="file"?e[t]=n.files?.[0]?.name??"":e[t]=n instanceof HTMLInputElement&&n.type==="checkbox"?n.checked:n.value;return e}files(){let e=new Map;for(let[t,n]of this.inputs){let i=n instanceof HTMLInputElement&&n.type==="file"?n.files?.[0]:void 0;i&&e.set(t,i)}return e}setSlotStatus(e,t,n=!1){let i=this.slotStatus.get(e);i&&(i.textContent=t,i.classList.toggle("error",n))}setValues(e){for(let[t,n]of this.inputs){let i=e[t];n instanceof HTMLInputElement&&n.type==="checkbox"?n.checked=i===!0:n.type!=="file"&&(n.value=typeof i=="string"?i:"")}}setNameAction(e){let t=this.title.querySelector(".meta");if(!t||!e)return;let n=l("button","meta link",t.textContent??"");n.type="button",P(n,"Show in Items"),n.addEventListener("mousedown",i=>i.preventDefault()),n.addEventListener("click",e),t.replaceWith(n)}setExtras(e){this.menu?.close(!1),this.menu=void 0;let t=e.filter(i=>!i.menu),n=e.filter(i=>i.menu);if(this.extras.replaceChildren(...t.map(i=>{let s=x(i.label,"ghost","sm");return i.icon&&s.prepend(L(i.icon)),s.addEventListener("mousedown",o=>o.preventDefault()),s.addEventListener("click",()=>i.run()),s})),n.length>0){let i=x("","ghost","icon-sm");i.setAttribute("aria-label","More actions"),i.append(L("ellipsis")),this.extras.append(i),P(i),this.menu=new lt(i,()=>n)}}setDescription(e){this.description.textContent=e}setIssues(e){this.issues.replaceChildren(...e.map(t=>l("li",t.level,t.message)))}setError(e,t){this.error.textContent=e,this.errorDebug.replaceChildren(...z(t))}setSending(e){this.sendButton.disabled=e,this.sendButton.textContent=e?"Saving\u2026":"Save"}open(e,t,n,i,s,o){this.ended(),e!==this.anchor&&(this.side=void 0),this.anchor=e,this.anchorObserver.disconnect(),this.anchorObserver.observe(e),this.actions=s,this.title.textContent=`${t} `,this.title.append(l("span","meta",n)),this.element.setAttribute("aria-label",`Edit ${t.toLowerCase()} ${n}`),this.element.classList.toggle("wide",o),this.buttons.hidden=!1,this.choices.hidden=!0,this.setExtras([]),this.hint.textContent=i,this.setDescription(""),this.setIssues([]),this.setError(""),this.setSending(!1),this.element.hidden=!1,window.addEventListener("scroll",this.reposition,!0),window.addEventListener("resize",this.reposition),window.addEventListener("keydown",this.onWindowKey)}field(e,t,n){let i=l("label",`field ${e.kind}`),s=l("span","caption",e.label),o;if(e.kind==="file"){o=l("input"),o.type="file",o.accept="image/apng,image/avif,image/gif,image/jpeg,image/png,image/svg+xml,image/webp",o.name=e.key;let a=typeof this.currentValues[`${e.key}:current`]=="string"?this.currentValues[`${e.key}:current`]:"",d=l("div","slot-preview");if(a){let u=l("img");u.src=a,u.alt="",d.append(u,l("span","meta",a))}else d.append(l("span","meta","No file"));let c=l("span","hint");return c.setAttribute("role","status"),this.slotStatus.set(e.key,c),o.addEventListener("change",n),this.inputs.set(e.key,o),i.append(s,d,o,c),i}if(e.kind==="entity"&&this.entities){let a=l("div","field entity");s.id=`baack-field-${e.key}`;let d=new dt(this.entities,e.key,typeof t=="string"?t:"",n);return d.input.setAttribute("aria-labelledby",s.id),this.inputs.set(e.key,d.value),a.append(s,d.element),a}if(e.kind==="textarea"||e.kind==="code")o=l("textarea"),o.rows=e.kind==="code"?12:4,o.spellcheck=e.kind!=="code";else{if(o=l("input"),o.type=e.kind==="checkbox"?"checkbox":e.kind==="datetime"?"datetime-local":e.kind==="url"?"url":"text",e.kind==="integer"&&(o.inputMode="numeric"),e.kind==="decimal"&&(o.inputMode="decimal"),e.kind==="currency"){o.maxLength=3,o.autocapitalize="characters";let a=l("datalist");a.id=`baack-currencies-${e.key}`,a.append(...Br.map(d=>Object.assign(l("option"),{value:d}))),o.setAttribute("list",a.id),i.append(a)}e.kind==="url"&&this.entities&&i.append(this.pathSuggestions(o,e.key))}return o instanceof HTMLInputElement&&o.type==="checkbox"?(o.setAttribute("role","switch"),o.className="switch",o.checked=t===!0,i.append(o,s)):(o.value=typeof t=="string"?t:"",i.append(s,o)),o.name=e.key,o.addEventListener("input",n),o.addEventListener("change",n),this.inputs.set(e.key,o),i}pathSuggestions(e,t){let n=l("datalist");n.id=`baack-paths-${t}`,e.setAttribute("list",n.id);let i=({entities:s})=>n.replaceChildren(...[...new Set(s.map(o=>this.entities.pagePath(o.path)))].map(o=>Object.assign(l("option"),{value:o})));return e.addEventListener("focus",()=>{this.entities?.list(i).then(i,()=>{})},{once:!0}),n}place(){if(!this.anchor)return;let e=this.anchor.getBoundingClientRect();if(!this.anchor.getClientRects().length&&this.side)return;let t=this.element.offsetHeight,n=this.element.offsetWidth,i=this.anchor.closest(".panel");if(i&&i!==this.element){let a=i.getBoundingClientRect();this.element.style.left=`${Math.max(8,a.left-n-8)}px`,this.element.style.top=`${Math.max(8,Math.min(e.top,window.innerHeight-t-8))}px`;return}this.side??=e.bottom+8+t<=window.innerHeight?"below":e.top-t-8>=8?"above":"within";let s=this.side==="below"?Math.max(8,e.bottom+8):this.side==="above"?Math.min(e.top-t-8,window.innerHeight-t-8):Math.max(8,Math.min(e.bottom+8,window.innerHeight-t-8)),o=Math.max(8,Math.min(e.left,window.innerWidth-n-8));this.element.style.top=`${s}px`,this.element.style.left=`${o}px`}};var ut=class{modeButton;itemsButton;readButton;pendingButton;message;messageAction;runMessageAction;messageDebug;entities;lifecycleRows=[];pendingGroups=[];openPending;pendingListeners=[];openEntity;lifecycleListeners=[];login;loginActions;loginLink;loginText;pendingActions;constructor(e,t,n){this.pendingActions=n,this.modeButton=Xt(e);let i=this.modeButton.closest(".toolbar"),s=this.modeButton.parentElement;this.itemsButton=l("button","","Items"),this.itemsButton.type="button",P(this.itemsButton,"Every item on this page (Alt+Shift+I)"),this.itemsButton.hidden=!0,this.pendingButton=l("button","pending"),this.pendingButton.type="button",this.pendingButton.hidden=!0,P(this.pendingButton,"Show them in the sidebar, with Save all and Discard all"),this.pendingButton.addEventListener("click",()=>this.openPending?.()),this.readButton=l("button","","Show live page"),this.readButton.type="button",this.readButton.hidden=!0,s.append(this.itemsButton,this.readButton,this.pendingButton),this.message=l("p","message"),this.message.setAttribute("role","status"),this.messageAction=x("","primary","sm","message-action"),this.messageAction.hidden=!0,this.messageAction.addEventListener("click",()=>{let a=this.runMessageAction;this.showMessage(""),a?.()}),this.messageDebug=l("div","message-debug"),this.entities=l("div","entities"),this.login=l("div","login"),this.login.hidden=!0,this.loginText=l("p","message"),this.loginText.setAttribute("role","alert"),this.loginActions=l("span","login-actions");let o=l("button","","I have logged in, try again");o.type="button",o.addEventListener("click",()=>{this.hideLogin(),t()}),this.login.append(this.loginText,this.loginActions,o),i.append(this.entities,this.message,this.messageAction,this.messageDebug,this.login)}setEditMode(e){this.modeButton.disabled=!1,this.modeButton.setAttribute("aria-pressed",String(e)),window.baackEditorConfig?.launcher==="page"&&(this.modeButton.closest(".toolbar").hidden=!e);for(let t of document.querySelectorAll("[data-baack-editor-launch]"))t.setAttribute("aria-pressed",String(e));this.itemsButton.hidden=!e,this.readButton.hidden=!e}setReadMode(e){this.readButton.textContent=e?"Show live page":"Show latest drafts"}setPending(e){this.pendingGroups=e;let t=e.reduce((n,i)=>n+i.rows.length,0);this.pendingButton.hidden=t===0,this.pendingButton.textContent=t===1?"1 unsaved change":`${t} unsaved changes`,this.renderEntities();for(let n of this.pendingListeners)n()}setOpenPending(e){this.openPending=e}onPending(e){this.pendingListeners.push(e)}pendingSections(){return this.pendingGroups.length===0?[l("p","hint","Nothing is unsaved.")]:[...this.pendingGroups.map(e=>this.pendingSection(e)),...this.pendingGroups.length>1?[this.actions(void 0,"everywhere")]:[]]}setOpenEntity(e){this.openEntity=e}setLifecycle(e){this.lifecycleRows=e,this.renderEntities();for(let t of this.lifecycleListeners)t()}lifecycleOf(e){return this.lifecycleRows.find(t=>t.entityUrn===e)}showsEntity(e){return this.lifecycleRows[0]?.entityUrn===e}onLifecycle(e){this.lifecycleListeners.push(e)}renderEntities(){let e=this.lifecycleRows[0];this.entities.replaceChildren(...e?[this.entityLabel(e)]:[])}entityLabel(e){let t=this.pendingGroups.find(i=>i.entityUrn===e.entityUrn)?.rows.length??0,n=l("button","entity-label");if(n.type="button",P(n,"Open in the sidebar"),n.append(l("span","title",e.title),l("span","meta",` \xB7 ${e.label}`)),t>0&&n.append(l("span","meta unsent",` \xB7 ${t} unsaved`)),n.addEventListener("click",()=>this.openEntity?.(e.entityUrn)),e.note){let i=l("div","entity");return i.append(n,l("p","message",e.note)),i}return n}pendingSection(e){let t=e.title,n=l("section","entity");n.setAttribute("aria-label",`Unsaved in ${t}`),n.append(l("div","meta",`${t}: ${e.rows.length} unsaved`));let i=l("ul","rows");for(let s of e.rows){let o=l("li",s.problem?"row problem":"row",s.label);if(o.append(l("span","meta",` \xB7 ${s.detail}`)),s.action){let a=l("button","",s.action.label);a.type="button";let d=s.action.run;a.addEventListener("click",()=>d(a)),o.append(" ",a)}i.append(o)}return n.append(i,this.actions(e.entityUrn,`in ${t}`)),n}showMessage(e,t=!1,n,i){this.message.textContent=e,this.message.classList.remove("visually-hidden"),this.message.classList.toggle("info",t),this.messageDebug.replaceChildren(...z(n)),this.runMessageAction=i?.run,this.messageAction.textContent=i?.label??"",this.messageAction.hidden=!i}announce(e,t="",n=!0){this.showMessage(t,n),this.message.prepend(l("span","visually-hidden",t?`${e} `:e)),this.message.classList.toggle("visually-hidden",!t)}showLogin(e,t){this.loginText.textContent=e,this.loginLink?.close(),this.loginLink=t?Qt(t):void 0,this.loginActions.replaceChildren(...this.loginLink?[this.loginLink.element]:[]),this.login.hidden=!1}hideLogin(){this.login.hidden=!0,this.loginLink?.close(),this.loginLink=void 0}get loginShown(){return!this.login.hidden}actions(e,t){let n=l("div","actions"),i=l("button","primary",e?"Save all":"Save everything");i.type="button",i.setAttribute("aria-label",`Save all unsaved changes ${t}`),i.addEventListener("click",()=>this.pendingActions.sendAll(e));let s=x(e?"Discard all":"Discard everything","destructive");return s.setAttribute("aria-label",`Discard all unsaved changes ${t}`),s.addEventListener("click",()=>this.pendingActions.discardAll(e)),n.append(s,i),n}};function ht(r){let e=window.matchMedia?.("(prefers-reduced-motion: reduce)").matches??!1;if(typeof document.startViewTransition!="function"||e||document.visibilityState!=="visible")return r(),Promise.resolve();let t=document.startViewTransition(r);return t.ready.catch(()=>{}),t.finished.catch(()=>{}),t.updateCallbackDone}var pt=class{ctx;hooks;snapshots=new Map;carried=new Map;orders=new Map;added=new Set;loading=new Map;editMode=!1;readMode="LATEST";session=0;previewing;previewListeners=new Set;changedThisVisit=new Set;built=new WeakMap;constructor(e,t){this.ctx=e,this.hooks=t}get isEditing(){return this.editMode}get mode(){return this.readMode}begin(e="LATEST"){this.editMode=!0,this.readMode=e,this.session+=1}readOptions(e){return e==="live"?{}:{version:e==="LATEST"?"LATEST":String(e)}}readLiveChanges(){let{store:e}=this.ctx,t=[...this.changedThisVisit].filter(n=>S(e.view(n)?.status)).flatMap(n=>e.scopesFor(n));return this.readLive(t)}async readLive(e){try{return await Promise.all(e.map(async t=>[t,await this.ctx.views.read(t)]))}catch(t){return this.ctx.feedback.report(t,"show the published content",()=>{this.readLive(e).then(n=>{this.editMode||this.showLive(n)})}),[]}}showLive(e){let{store:t,discovery:n}=this.ctx;for(let[o,a]of e)t.loadEntity(o,a);let i=new Set(e.map(([o])=>o)),s=!1;n.flush();for(let o of n.all()){if(!i.has(o.scope))continue;let a=t.itemFor(o);!a?.item.urn||o.element.getAttribute(B(o.entry))===a.item.urn||(this.recordBuilt(o),this.ctx.live.render(o,a.item),s=!0)}return t.clearEntities(),s}async leave(e){let t=!1;return await ht(()=>{this.end(),t=this.showLive(e)}),t}async prefetch(e,t){let n=await Promise.all(t.map(async i=>[i,await this.readIn(i,e)]));return new Map(n)}async switchTo(e,t){let{store:n,discovery:i}=this.ctx;await ht(()=>{this.end(),this.begin(e);for(let[s,o]of t)n.loadEntity(s,o.entity),o.draft&&this.draftsOnLivePage.add(o.entity.urn);i.flush();for(let s of i.all())this.show(s)}),this.hooks.changed()}get previewedUrn(){return this.previewing?.version.urn}onPreviewChange(e){this.previewListeners.add(e)}previewVersion(e,t){let n=this.previewing?.slot;this.previewing={slot:e,version:t},n&&!Rt(n,e)&&this.reshow(n),this.reshow(e),this.notifyPreview()}stopPreview(e){let t=this.previewing;!t||e&&!Rt(t.slot,e)||(this.previewing=void 0,this.reshow(t.slot),this.notifyPreview())}notifyPreview(){for(let e of this.previewListeners)e()}end(){this.previewing&&(this.previewing=void 0,this.notifyPreview()),this.editMode=!1,this.session+=1,this.ctx.live.endPreviews();for(let e of this.added)e.remove();this.added.clear(),this.restoreOrders();for(let e of[...this.snapshots.keys()])this.restore(e);for(let[e,t]of this.carried)for(let n of t.values())e.isConnected&&!j(e)&&Ii(e,n);this.carried.clear(),this.ctx.store.clearEntities(),this.loading.clear(),this.draftsOnLivePage.clear(),this.ctx.sources.clear()}async hydrate(e){let t=this.session,n=new Set(e.map(i=>i.scope));await Promise.all([...n].map(i=>this.loadScope(i))),t===this.session&&(await ht(()=>{if(t===this.session)for(let i of e)this.ctx.discovery.of(i.element).includes(i)&&this.show(i)}),t===this.session&&this.hooks.changed())}draftsOnLivePage=new Set;async readScope(e){let{entity:t,draft:n}=await this.readIn(e,this.readMode);return n?this.draftsOnLivePage.add(t.urn):this.draftsOnLivePage.delete(t.urn),t}async readIn(e,t){let{views:n}=this.ctx;if(t!=="live")return{entity:await n.read(e,this.readOptions(t)),draft:!1};let{entity:i,live:s}=await n.readAsLive(e);return{entity:i,draft:!s}}loadScope(e){let{store:t,feedback:n,discovery:i}=this.ctx;if(t.hasScope(e))return Promise.resolve();let s=this.loading.get(e);if(!s){let o=this.session;s=this.readScope(e).then(a=>{o===this.session&&t.loadEntity(e,a)}).catch(a=>{this.loading.delete(e);let d=this.readMode==="live"?"load the live content":"load the latest content";n.report(a,d,()=>{this.hydrate(i.all())})}),this.loading.set(e,s)}return s}show(e){let{store:t,pending:n}=this.ctx,{element:i,entry:s}=e;this.snapshots.has(e)||this.snapshots.set(e,this.carriedSnapshot(i,s)??Pi(i,s)),this.recordBuilt(e);let o=t.itemFor(e),a=this.previewing;if(o?.item.urn&&a&&Rt(a.slot,{...e,entityUrn:t.entityFor(e.scope)})){this.ctx.live.render(e,yt(s,o.item,O(s,a.version))),F(i,"previewing");return}if(o?.item.urn){let u=n.getEdit(o.item.urn),h=u&&!u.stale,v=h&&!s.renderedByView?yt(s,o.item,u.value):o.item;this.ctx.live.render(e,v),F(i,h?"changed":this.publishedSinceBuilt(e,o.item.urn)?"published":"editable");return}let d=t.entityFor(e.scope),c=d?n.getCreate(H({entityUrn:d,type:s.type,name:e.name,sortOrder:e.sortOrder})):void 0;c&&!s.renderedByView?(this.ctx.live.render(e,{name:e.name,sortOrder:e.sortOrder,...c.value}),F(i,"changed")):F(i,c?"changed":"unresolved")}recordBuilt({element:e,entry:t}){let n=this.built.get(e)??new Map;n.has(t)||n.set(t,e.getAttribute(B(t))??void 0),this.built.set(e,n)}publishedSinceBuilt(e,t){if(this.readMode!=="live")return!1;let n=this.ctx.store.entityFor(e.scope);return!n||this.draftsOnLivePage.has(n)?!1:this.built.get(e.element)?.get(e.entry)!==t}countPublishedSinceBuilt(){return new Set(this.ctx.discovery.all().filter(e=>e.element.getAttribute(Ce)==="published").map(e=>e.element)).size}showAll(){for(let e of this.ctx.discovery.all())this.show(e)}reshow(e){let{discovery:t,store:n}=this.ctx;for(let i of t.all()){if(i.entry!==e.entry||n.entityFor(i.scope)!==e.entityUrn)continue;let s=e.urn&&i.element.getAttribute(B(i.entry))===e.urn,o=i.name===e.name&&i.sortOrder===e.sortOrder;!s&&!o||this.hooks.editingElement()!==i.element&&this.show(i)}}forget(e){for(let t of e){if(this.hooks.editingBinding()===t&&this.hooks.closeEditor(),this.carried.get(t.element)?.has(t.entry)){this.snapshots.delete(t);continue}this.restore(t)}}retag(e,t,n=e.name){let{element:i,entry:s}=e,o=this.snapshots.get(e)??Pi(i,s),a=this.carried.get(i)??new Map;a.set(s,o),this.carried.set(i,a),i.setAttribute(te(s),String(t)),i.setAttribute(`data-${s.attribute}-name`,n)}carriedSnapshot(e,t){let n=this.carried.get(e),i=n?.get(t);return i&&n.delete(t),n&&n.size===0&&this.carried.delete(e),i}rememberOrder(e){j(e)||this.orders.has(e)||this.orders.set(e,[...e.childNodes])}restoreOrder(e){let t=this.orders.get(e);t&&(e.append(...t.filter(n=>n.parentNode===e||!n.parentNode)),this.orders.delete(e))}restoreOrders(){for(let e of[...this.orders.keys()])this.restoreOrder(e)}track(e){this.added.add(e)}async refresh(e){let{store:t,feedback:n,discovery:i}=this.ctx,s=this.session,o=t.scopesFor(e);this.readMode==="LATEST"&&this.changedThisVisit.add(e);try{for(let a of o){let d=await this.readScope(a);if(s!==this.session)return;t.loadEntity(a,d)}}catch(a){n.report(a,"show the latest content",()=>{this.refresh(e)});return}for(let a of i.all())o.includes(a.scope)&&this.hooks.editingBinding()!==a&&this.show(a);this.hooks.changed(e)}bindingsAt(e){return this.ctx.discovery.all().filter(t=>t.entry===e.entry&&t.name===e.name&&t.sortOrder===e.sortOrder&&this.ctx.store.entityFor(t.scope)===e.entityUrn)}missingBindings(e){let{store:t,discovery:n}=this.ctx,i=new Set;return n.all().filter(s=>{if(t.entityFor(s.scope)!==e||t.itemAt(e,s.entry,s.name,s.sortOrder))return!1;let o=H({entityUrn:e,type:s.entry.type,name:s.name,sortOrder:s.sortOrder});return i.has(o)?!1:(i.add(o),!0)})}restore(e){let t=this.snapshots.get(e);if(this.snapshots.delete(e),on(e.element),this.ctx.live.restore(e)){let n=B(e.entry),i=t?.attributes.find(([s])=>s===n)?.[1];i?e.element.setAttribute(n,i):e.element.removeAttribute(n);return}t&&e.element.isConnected&&Ii(e.element,t)}};function Pi(r,e){let t=e.component?.(r).ownsChildren??!0;return{attributes:[...r.attributes].map(n=>[n.name,n.value]),children:t?[...r.childNodes].map(n=>n.cloneNode(!0)):void 0}}function Ii(r,e){let t=new Set(e.attributes.map(([n])=>n));for(let n of[...r.attributes])t.has(n.name)||r.removeAttribute(n.name);for(let[n,i]of e.attributes)r.setAttribute(n,i);e.children&&r.replaceChildren(...e.children)}function Rt(r,e){return r.entityUrn===e.entityUrn&&r.entry===e.entry&&r.name===e.name&&r.sortOrder===e.sortOrder}var mt=class{ctx;view;editing;saving;outline;onboarding;history;publishing;moves;tags;images;stash;restored=!1;constructor(e,t,n,i,s){let o=new Le,a,d=new De(e,()=>a);a=new ut(t,()=>d.retryAfterLogin(),{sendAll:p=>{this.saving.saveAll(p)},discardAll:p=>this.saving.discardAll(p)});let c=new Ee(n,{added:p=>{this.view.isEditing&&this.view.hydrate(p)},removed:p=>this.view.forget(p)}),u=new Ze(e,async()=>{let f=(await e.companies().catch(()=>[])).map(m=>m.urn);return f.length>0?f:s.company?.urn?[s.company.urn]:[]},s.user?.urn);this.ctx={transport:e,host:t,registry:i,store:o,pending:new ke(()=>this.pendingChanged()),toolbar:a,popover:new ct(t),panels:{show:(p,f)=>this.outline.showPanel(p,f)},feedback:d,views:new Se(e),sources:new Map,discovery:c,canPublish:["PUBLISHER","ADMIN","SUPER"].includes(s.user?.role??""),requiredImageSlots:window.baackEditorConfig?.requiredImageSlots??["DEFAULT"],live:new He(o),hooks:{openHistory:p=>{this.history.open(p)},publishEntity:p=>{this.publishing.openReview(p)},canReorder:p=>(this.moves.groupOf(p)?.units.length??0)>1,reorder:p=>this.moves.openReorder(p),moveBy:(p,f)=>this.moves.moveBy(p,f),relocate:p=>{this.editing.close(),this.outline.focusSlot(p)},showItem:p=>this.outline.selectItem(p),rename:(p,f)=>{this.moves.relocate(void 0,p.entityUrn,p.entry,f)},moveSlot:(p,f,m)=>this.moves.moveTo(p.entityUrn,p.entry,f,{name:p.name,sortOrder:m}),runPlan:p=>this.moves.run(p),saveImage:(p,f)=>this.images.save(p,f)},groups:s.user?.urn?new Je(s.user.urn):void 0,entry:p=>i.find(f=>f.type===p),entityTitle:p=>{let f=o.view(p)?.name;return f?`Content for ${Y(f)}`:`Entity ${p.slice(0,8)}`},announcePublished:(p,f,m={})=>{let g=o.view(p),y=g?.name??"",T={entityUrn:p,name:y,path:y&&Bi(Y(y)),language:g?.language??"",variant:g?.variant??""};m.itemUrn&&(T.itemUrn=m.itemUrn);let b=m.quiet===!0&&a.showsEntity(p);Mi(a,window.baackEditorConfig?.afterPublish,T,f,{...m.info!==void 0?{info:m.info}:{},quiet:b})}},this.stash=s.user?.urn?new xe(s.user.urn):void 0,this.view=new pt(this.ctx,{editingElement:()=>this.editing.current?.session?this.editing.current.target.binding?.element:void 0,editingBinding:()=>this.editing.current?.target.binding,closeEditor:()=>this.editing.close(),changed:p=>{this.refreshTags(),this.outline.changed(p),this.history?.changed(p),this.publishing?.changed()}}),this.saving=new Ue(this.ctx,this.view,()=>this.editing),this.editing=new Re(this.ctx,this.view,p=>this.saving.save(p)),this.onboarding=new Qe({transport:e,toolbar:a,context:s,registry:i,store:o,panels:this.ctx.panels,openEntity:p=>this.outline.openEntity(p),entityNameForPage:window.baackEditorConfig?.entityNameForPage,report:(p,f,m)=>d.report(p,f,m),created:p=>u.remember(p)}),this.ctx.popover.setEntitySource(this.entitySource(u)),this.outline=new nt(this.ctx,this.view,this.editing,this.saving,this.onboarding),this.outline.setTasks(new at(this.ctx,this.outline.outline.stack,{ownerOf:p=>o.view(p)?.raw.owner?.urn??s.company?.urn,actorIn:p=>s.userIdentities?.find(f=>f.company?.urn===p)?.identity?.urn,changed:()=>{this.outline.render()}}));let h=this.outline.outline.stack;h.avoid(a.modeButton.closest(".toolbar"));let v=this.ctx.popover.element;new MutationObserver(()=>h.element.classList.toggle("item-editing",!v.hidden)).observe(v,{attributes:!0,attributeFilter:["hidden"]}),this.moves=new We(this.ctx,this.view,()=>this.editing,()=>this.ctx.groups,p=>this.saving.commit(p)),this.tags=new Ye(this.ctx.host,p=>this.moves.openOrderMenu(p)),this.moves.onOrderChange(()=>this.refreshTags()),this.images=new $e(this.ctx,this.view,()=>this.saving,()=>this.editing),this.publishing=new et(this.ctx,this.view,window.baackEditorConfig?.publishTimeoutMs??300*1e3,this.outline.outline.stack,{show:(p,f)=>this.outline.showAbove(f,p)}),this.history=new je(this.ctx,this.editing,this.view,this.outline.outline.stack,{show:(p,f)=>this.outline.showAbove(f,p),publishEntity:p=>this.ctx.hooks.publishEntity(p),published:async p=>{await this.view.refresh(p),await this.publishing.refreshStatus(p)}}),a.modeButton.addEventListener("click",()=>{this.setEditMode(!this.view.isEditing)}),a.itemsButton.addEventListener("click",()=>this.outline.toggle()),a.setOpenEntity(p=>this.outline.openEntity(p)),a.onLifecycle(()=>this.outline.changed()),a.setOpenPending(()=>this.outline.togglePending()),a.onPending(()=>this.outline.changed()),this.outline.onClose(()=>this.history.stopPreview()),a.readButton.addEventListener("click",()=>{this.setReadMode(this.view.mode==="LATEST"?"live":"LATEST")}),document.addEventListener("keydown",p=>{this.view.isEditing&&p.altKey&&p.shiftKey&&p.code==="KeyI"&&(p.preventDefault(),this.outline.toggle(),this.outline.outline.isOpen&&this.outline.outline.focusFilter())}),c.start()}leaving;get isEditing(){return this.view.isEditing}async setEditMode(e,t="LATEST",n=!0){if(await this.leaving,e===this.view.isEditing)return;let{toolbar:i,discovery:s}=this.ctx;if(i.setEditMode(e),e)this.view.begin(t),this.startMode(t),await this.view.hydrate(s.all()),await this.afterRead(t);else{this.stopMode();let o=n&&this.view.mode==="LATEST"?this.view.readLiveChanges():Promise.resolve([]);this.leaving=o.then(()=>{});let a=await o;this.leaving=void 0,await this.view.leave(a)&&i.showMessage(`Showing the published content. ${Bt(window.baackEditorConfig?.afterPublish)??$t}`,!0)}}startMode(e){this.showReadMode(e),e==="LATEST"&&(this.editing.attach(),this.publishing.start(),this.outline.setNewEntity(()=>{this.onboarding.offerNewEntity(this.pageLanguage())}))}pageLanguage(){let{store:e}=this.ctx,t=ie(e);return t&&e.view(t)?.language||document.documentElement.lang||"en-GB"}entitySource(e){let{transport:t,feedback:n}=this.ctx,i=()=>this.onboarding,s=()=>this.pageLanguage();return{list:o=>e.list(o),describe:o=>e.describe(o),get language(){return s()},create(o,a){return new Promise(d=>{i().newEntityForm({title:"New entity",submitLabel:"Create and choose it",path:a,language:this.language,onCreated:c=>d(e.remember(c)),onCancel:()=>d(void 0)}).then(c=>{c.element.addEventListener("keydown",u=>{u.key==="Escape"&&(u.preventDefault(),u.stopPropagation(),c.cancel())}),o.replaceChildren(c.element),c.element.querySelector("input")?.focus()})})},note:async o=>{let a=await t.readEntity(o);return e.remember(a),S(a.status)||a.status==="PUBLISH"?"":`${Y(a.name)} is not published yet, so pages show it only once it is.`},pagePath:Bi,report:(o,a,d)=>{n.report(o,a,d)}}}refreshTags(){this.tags&&(this.view.isEditing&&this.view.mode==="LATEST"?this.tags.show(this.moves.keyedMembers()):this.tags.clear())}stopMode(){let{toolbar:e}=this.ctx;this.tags.clear(),this.editing.detach(),this.editing.close(),this.outline.clear(),this.history.close(),this.publishing.stop(),this.moves.panel.close(),this.outline.setNewEntity(void 0),e.showMessage(""),e.hideLogin()}async afterRead(e){let{toolbar:t,discovery:n}=this.ctx;if(e==="live"){let i=this.view.countPublishedSinceBuilt(),s=[i>0?`Showing the live content. ${i===1?"1 item was":`${i} items were`} published since this page was built, outlined in green. ${Bt(window.baackEditorConfig?.afterPublish)??$t}`:"Showing the live page, as visitors see it."];if(this.view.draftsOnLivePage.size>0){let o=[...this.view.draftsOnLivePage].map(a=>this.ctx.entityTitle(a)).join(", ");s.push(`Not published yet, so shown as the latest drafts: ${o}.`)}t.showMessage(`${s.join(" ")} Editing is off.`,!0)}e==="LATEST"&&(await this.restoreStash(),n.unscoped().length>0&&!document.documentElement.hasAttribute(_)&&this.onboarding.offerEntityForPage())}async setReadMode(e){if(!this.view.isEditing){await this.setEditMode(!0,e);return}if(e===this.view.mode)return;let t=[...new Set(this.ctx.discovery.all().map(i=>i.scope))],n;try{n=await this.view.prefetch(e,t)}catch(i){let s=e==="live"?"load the live content":"load the latest content";this.ctx.feedback.report(i,s,()=>{this.setReadMode(e)});return}!this.view.isEditing||e===this.view.mode||(this.stopMode(),this.startMode(e),await this.view.switchTo(e,n),await this.afterRead(e))}showReadMode(e){let{toolbar:t}=this.ctx;t.setReadMode(e==="LATEST"),e==="live"&&t.showMessage("Showing the live page, as visitors see it. Editing is off.",!0),typeof e=="number"&&t.showMessage(`Showing the latest drafts as of ${new Date(e).toLocaleString()}. Read-only.`,!0)}pendingChanged(){let{pending:e,toolbar:t}=this.ctx,n=e.all();this.stash?.save(n);let i=e.byEntity(),s=re(this.ctx.store,[...i.keys()]).map(o=>({entityUrn:o,title:this.ctx.entityTitle(o),rows:i.get(o).map(a=>({label:`${a.name} #${a.sortOrder}`,detail:a.kind==="create"?"new item":a.kind==="move"?`${a.label}: to ${a.to.name===a.name?"":a.to.name}#${a.to.sortOrder}`:a.stale?"based on an older version":"edit",problem:a.kind==="edit"&&a.stale===!0,...a.kind==="edit"&&a.stale?{action:{label:"Resolve",run:d=>{this.saving.resolve(a,d)}}}:{}}))}));t.setPending(s),n.length>0?window.addEventListener("beforeunload",$i):window.removeEventListener("beforeunload",$i),this.outline?.changed()}async restoreStash(){if(this.restored||!this.stash)return;this.restored=!0;let e=this.stash.load();if(e.length===0)return;await Promise.all([...new Set(e.map(n=>n.entityUrn))].map(n=>this.view.loadScope(n)));let t=e.map(n=>n.kind!=="edit"?n:this.ctx.store.itemAt(n.entityUrn,this.ctx.entry(n.type),n.name,n.sortOrder)?.item.urn===n.urn?{...n,stale:!1}:{...n,stale:!0});this.ctx.pending.load(t),this.view.showAll(),this.ctx.toolbar.showMessage(`Restored ${t.length} unsaved ${t.length===1?"change":"changes"} from this browser.`,!0)}};function $i(r){r.preventDefault()}function Bi(r){return(window.baackEditorConfig?.pagePathForEntity??wi)(r)}var Dt=[In,Nn,Rn,Dn,Fn,Un,Vn,_n,Gn,zn,Kn,jn,qn],Hi=Dt.filter(r=>r.component!==void 0);function Nd(r){let e=new mt(r.transport,r.host,Hi,Dt,r.context);return e.setReadMode(r.mode??"LATEST"),e}export{Nd as start};
|
|
17
18
|
//# sourceMappingURL=editor.js.map
|