domma-cms 0.36.6 → 0.36.7

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.
@@ -1,8 +1,8 @@
1
- import{apiRequest as I}from"/admin/js/api.js";import{makeIconInput as fe}from"/admin/js/lib/shortcode-modal.js";const Z=[{value:"string",label:"Text (single line)"},{value:"email",label:"Email"},{value:"tel",label:"Phone"},{value:"number",label:"Number"},{value:"textarea",label:"Textarea (multi-line)"},{value:"select",label:"Dropdown (select)"},{value:"radio",label:"Radio buttons"},{value:"checkbox",label:"Single checkbox"},{value:"checkbox-group",label:"Checkbox group"},{value:"chooser",label:"Chooser (visual options)"},{value:"date",label:"Date"},{value:"time",label:"Time"},{value:"url",label:"URL"},{value:"password",label:"Password"},{value:"file",label:"File upload"},{value:"hidden",label:"Hidden field"}],W=new Set(["select","radio","checkbox-group","chooser"]);let g=[],q=null,P=null,M=null,G={};function w(e,t,s=14){e.textContent="";const n=document.createElement("span");return n.setAttribute("data-icon",t),n.setAttribute("data-icon-size",String(s)),n.style.cssText="display:inline-flex;align-items:center;vertical-align:middle;",e.appendChild(n),window.I?.scan?.(e),e}function D(e,t,s,n=14){return w(e,t,n),e.appendChild(document.createTextNode(" "+s)),e}function Q(e){const t=document.createElement("span");return t.setAttribute("data-icon","help-circle"),t.setAttribute("data-icon-size","12"),t.style.cssText="display:inline-flex;align-items:center;vertical-align:middle;margin-left:.3rem;opacity:.55;cursor:help;",window.I?.scan?.(t),typeof E<"u"&&E.tooltip&&E.tooltip(t,{content:e,position:"top"}),t}let _=null,ee=null;function Y(){clearTimeout(ee),ee=setTimeout(()=>{_&&_()},350)}function te(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_|_$/g,"")}function ne(e){return Z.find(t=>t.value===e)?.label||e}function le(e){return e?!!(e.visibility?.conditions?.length||e.requirement?.conditions?.length||e.validation?.length||e.cascade?.sourceField):!1}function he(e){const t={...g[e]};if(t.type==="spacer")return t;if(t.type==="page-break"){const h=document.getElementById(`fb-pb-label-${e}`),b=document.getElementById(`fb-pb-desc-${e}`);return h&&(t.label=h.value.trim()||t.label),b&&(t.description=b.value.trim()),t}const s=document.getElementById(`fb-label-${e}`),n=document.getElementById(`fb-name-${e}`),o=document.getElementById(`fb-type-${e}`),l=document.getElementById(`fb-required-${e}`),i=document.getElementById(`fb-placeholder-${e}`),p=document.getElementById(`fb-helper-${e}`),r=document.getElementById(`fb-tooltip-${e}`);if(s&&(t.label=s.value.trim()||t.label),n&&(t.name=n.value.trim()||t.name),o&&(t.type=o.value||t.type),l&&(t.required=l.checked),i&&(t.placeholder=i.value.trim()),p&&(t.helper=p.value.trim()),r&&(t.tooltip=r.value.trim()),t.type==="chooser"){const h=document.getElementById(`fb-chooser-variant-${e}`)?.value;h&&(t.variant=h);const b=document.getElementById(`fb-chooser-multiple-${e}`);b&&(t.multiple=b.checked);const v=document.getElementById(`fb-chooser-density-${e}`)?.value;v&&(t.density=v);const C=document.getElementById(`fb-chooser-columns-${e}`)?.value;C!==""&&C!==void 0&&(t.columns=parseInt(C,10)||3);const x=document.getElementById(`fb-chooser-accent-${e}`)?.value.trim();x?t.accent=x:delete t.accent;const T=document.getElementById(`fb-chooser-accent-style-${e}`)?.value;T?t.accentStyle=T:delete t.accentStyle;const z=document.getElementById(`fb-chooser-glow-${e}`);z&&(t.glow=z.checked);const B=document.getElementById(`fb-chooser-glow-colour-${e}`)?.value.trim();B?t.glowColour=B:delete t.glowColour;const N=document.getElementById(`fb-chooser-shadow-${e}`)?.value;N&&N!=="none"?t.shadow=N:delete t.shadow;const O=document.getElementById(`fb-chooser-shadow-colour-${e}`)?.value.trim();O?t.shadowColour=O:delete t.shadowColour,J(e),g[e]&&Array.isArray(g[e].options)&&(t.options=g[e].options)}else if(W.has(t.type)){const h=document.getElementById(`fb-options-${e}`);h&&(t.options=h.value.split(`
2
- `).filter(b=>b.trim()).map(b=>{const[v,...C]=b.split(":");return{value:v.trim(),label:C.join(":").trim()||v.trim()}}))}if(t.type==="textarea"){const h=parseInt(document.getElementById(`fb-rows-${e}`)?.value,10);h>0&&(t.formConfig={...t.formConfig||{},rows:h})}const a=document.getElementById(`fb-span-${e}`),d=document.getElementById(`fb-fullwidth-${e}`);if(a||d){const h={...t.formConfig||{}};if(d?.checked)h.span="full";else{const b=parseInt(a?.value,10);b>1?h.span=b:delete h.span}t.formConfig=Object.keys(h).length?h:void 0}const c=document.getElementById(`fb-minlength-${e}`)?.value;c&&(t.minLength=parseInt(c,10));const u=document.getElementById(`fb-maxlength-${e}`)?.value;u&&(t.maxLength=parseInt(u,10));const m=document.getElementById(`fb-min-${e}`)?.value;m!==""&&m!==void 0&&(t.min=parseFloat(m));const f=document.getElementById(`fb-max-${e}`)?.value;f!==""&&f!==void 0&&(t.max=parseFloat(f));const y=be(e);return y?t.logic=y:delete t.logic,t}function be(e){const t=document.querySelector(`.fb-field-card[data-index="${e}"]`);if(!t)return;const s=t.querySelector(".fb-field-logic");if(!s)return;const n={};let o=!1;const l=s.querySelector('[data-logic-section="visibility"]');if(l){const a=l.querySelector(".fb-logic-vis-default"),d=l.querySelector(".fb-logic-vis-transition"),c=Array.from(l.querySelectorAll(".fb-logic-cond-row")).map(f=>{const y=f.querySelector(".fb-logic-cond-field"),h=f.querySelector(".fb-logic-cond-op"),b=f.querySelector(".fb-logic-cond-val"),v=f.querySelector(".fb-logic-vis-then");return y?.value?{when:{all:[{field:y.value,operator:h.value,value:b.value}]},then:v.value}:null}).filter(Boolean),u=a?.value||"visible",m=d?.value||"none";(u!=="visible"||c.length>0||m!=="none")&&(n.visibility={default:u,conditions:c},m!=="none"&&(n.visibility.transition=m),o=!0)}const i=s.querySelector('[data-logic-section="requirement"]');if(i){const a=i.querySelector(".fb-logic-req-default"),d=Array.from(i.querySelectorAll(".fb-logic-cond-row")).map(c=>{const u=c.querySelector(".fb-logic-cond-field"),m=c.querySelector(".fb-logic-cond-op"),f=c.querySelector(".fb-logic-cond-val"),y=c.querySelector(".fb-logic-req-then");return u?.value?{when:{all:[{field:u.value,operator:m.value,value:f.value}]},then:y.value==="true"}:null}).filter(Boolean);d.length>0&&(n.requirement={default:a?.checked===!0,conditions:d},o=!0)}const p=s.querySelector('[data-logic-section="validation"]');if(p){const a=Array.from(p.querySelectorAll(".fb-logic-val-rule")).map(d=>{const c=d.querySelector(".fb-logic-val-type"),u=d.querySelector(".fb-logic-val-pattern"),m=d.querySelector(".fb-logic-val-flags"),f=d.querySelector(".fb-logic-val-message");if(!u?.value.trim())return null;const y=c?.value||"regex",h={type:y,message:f?.value.trim()||"Invalid value."};return y==="regex"?(h.pattern=u.value.trim(),m?.value.trim()&&(h.flags=m.value.trim())):h.field=u.value.trim(),h}).filter(Boolean);a.length>0&&(n.validation=a,o=!0)}const r=s.querySelector('[data-logic-section="cascade"]');if(r){const a=r.querySelector(".fb-logic-cascade-source"),d=r.querySelector(".fb-logic-cascade-mapping"),c=r.querySelector(".fb-logic-cascade-defaults"),u=a?.value?.trim();if(u){let m={};try{m=JSON.parse(d?.value||"{}")}catch{}const f=(c?.value||"").split(`
3
- `).filter(y=>y.trim()).map(y=>{const[h,...b]=y.split(":");return{value:h.trim(),label:b.join(":").trim()||h.trim()}});n.cascade={sourceField:u,mapping:m,defaultOptions:f},o=!0}}return o?n:void 0}function $(){g=g.map((e,t)=>he(t))}let A=null;function ge(e,t,s){const n=e.firstElementChild;if(!n)return;const o=document.createElement("span");o.setAttribute("data-icon","menu"),o.setAttribute("data-icon-size","13"),o.title="Drag to reorder",o.style.cssText="cursor:grab;opacity:.35;flex-shrink:0;display:inline-flex;align-items:center;",n.insertBefore(o,n.firstChild),window.I?.scan?.(n),n.draggable=!0,n.addEventListener("dragstart",l=>{A=t,l.dataTransfer.effectAllowed="move",e.style.opacity="0.4"}),n.addEventListener("dragend",()=>{e.style.opacity="",document.querySelectorAll("#fields-list .fb-field-card").forEach(l=>l.classList.remove("fb-drag-over"))}),e.addEventListener("dragover",l=>{A!=null&&(l.preventDefault(),l.dataTransfer.dropEffect="move",document.querySelectorAll("#fields-list .fb-field-card").forEach(i=>i.classList.remove("fb-drag-over")),e.classList.add("fb-drag-over"))}),e.addEventListener("dragleave",()=>e.classList.remove("fb-drag-over")),e.addEventListener("drop",l=>{if(l.preventDefault(),e.classList.remove("fb-drag-over"),A==null||A===t){A=null;return}$();const[i]=g.splice(A,1);g.splice(t,0,i),A=null,L(s)})}function L(e){const t=e.find("#fields-list").get(0),s=e.find("#fields-empty-msg").get(0);if(t){if(Array.from(t.querySelectorAll(".fb-field-card")).forEach(n=>n.remove()),g.length===0){s&&(s.style.display=""),Y();return}s&&(s.style.display="none"),g.forEach((n,o)=>{const l=n.type==="page-break"?ye(n,o,e):n.type==="spacer"?ve(n,o,e):xe(n,o,e);ge(l,o,e),t.appendChild(l)}),Y()}}function ye(e,t,s){const n=document.createElement("div");n.className="fb-field-card",n.dataset.index=t,n.style.cssText="border:2px dashed var(--dm-border,#444);border-radius:8px;overflow:hidden;margin-bottom:.75rem;background:var(--dm-card-bg,rgba(255,255,255,.02));";const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.6rem .8rem;cursor:pointer;user-select:none;";const l=document.createElement("span");l.textContent="\u2014 Page Break \u2014",l.style.cssText="font-size:.7rem;padding:.15rem .5rem;border-radius:999px;background:color-mix(in srgb, var(--dm-text-muted) 20%, transparent);color:var(--dm-text-muted,#888);white-space:nowrap;flex-shrink:0;font-style:italic;";const i=document.createElement("span");i.textContent=e.label||"Untitled Step",i.style.cssText="flex:1;font-weight:600;font-size:.9rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dm-text-muted,#888);";const p=document.createElement("div");p.style.cssText="display:flex;gap:.25rem;flex-shrink:0;margin-left:.5rem;";const r=document.createElement("button");r.className="btn btn-xs btn-ghost",r.title="Edit step",w(r,"more-horizontal"),r.addEventListener("click",m=>{m.stopPropagation(),d.style.display=d.style.display==="none"?"":"none"}),p.appendChild(r);const a=document.createElement("button");a.className="btn btn-xs btn-ghost",a.style.cssText="line-height:1;opacity:.6;",a.title="Remove page break",w(a,"x"),a.addEventListener("click",async m=>{m.stopPropagation(),await E.confirm("Remove this page break?")&&($(),g.splice(t,1),L(s))}),p.appendChild(a),o.appendChild(l),o.appendChild(i),o.appendChild(p),o.addEventListener("click",()=>{d.style.display=d.style.display==="none"?"":"none"});const d=document.createElement("div");d.className="fb-field-body",d.style.cssText="padding:.8rem;border-top:1px dashed var(--dm-border,#444);display:none;";const c=S([k("Step Title",`fb-pb-label-${t}`,"text",e.label||"","Shown as the wizard step heading"),k("Step Description",`fb-pb-desc-${t}`,"text",e.description||"","Optional sub-heading")]),u=c.querySelector(`#fb-pb-label-${t}`);return u&&u.addEventListener("input",()=>{i.textContent=u.value||"Untitled Step"}),d.appendChild(c),n.appendChild(o),n.appendChild(d),n}function ve(e,t,s){const n=document.createElement("div");n.className="fb-field-card",n.dataset.index=t,n.style.cssText="border:1px dashed var(--dm-border,#444);border-radius:6px;margin-bottom:.5rem;background:transparent;";const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.4rem .8rem;";const l=document.createElement("div");l.style.cssText="flex:1;height:1px;background:var(--dm-border,#444);";const i=document.createElement("span");i.textContent="Spacer",i.style.cssText="font-size:.7rem;color:var(--dm-text-muted,#888);white-space:nowrap;padding:0 .4rem;font-style:italic;";const p=document.createElement("div");p.style.cssText="flex:1;height:1px;background:var(--dm-border,#444);";const r=document.createElement("div");r.style.cssText="display:flex;gap:.25rem;flex-shrink:0;";const a=document.createElement("button");return a.className="btn btn-xs btn-ghost",a.style.cssText="line-height:1;opacity:.6;",a.title="Remove spacer",w(a,"x"),a.addEventListener("click",async d=>{d.stopPropagation(),$(),g.splice(t,1),L(s)}),r.appendChild(a),o.appendChild(l),o.appendChild(i),o.appendChild(p),o.appendChild(r),n.appendChild(o),n}function xe(e,t,s){const n=document.createElement("div");n.className="fb-field-card",n.dataset.index=t,n.style.cssText="border:1px solid var(--dm-border,#333);border-radius:8px;overflow:hidden;margin-bottom:.75rem;background:var(--dm-card-bg);box-shadow:var(--dm-shadow-sm);";const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.65rem .85rem;background:var(--dm-card-header-bg,rgba(255,255,255,.04));cursor:pointer;user-select:none;";const l=document.createElement("span");l.textContent=ne(e.type),l.style.cssText="font-size:.7rem;padding:.15rem .45rem;border-radius:999px;background:color-mix(in srgb, var(--dm-primary) 14%, transparent);color:var(--dm-primary,#6366f1);white-space:nowrap;flex-shrink:0;";const i=document.createElement("span");i.textContent=e.label||"(unlabelled)",i.style.cssText="flex:1;font-weight:600;font-size:.9rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;";const p=document.createElement("div");p.style.cssText="display:flex;gap:.25rem;flex-shrink:0;margin-left:.5rem;";const r=document.createElement("button");r.className="btn btn-xs btn-ghost",r.title="Edit field",w(r,"more-horizontal"),r.addEventListener("click",c=>{c.stopPropagation(),d.style.display=d.style.display==="none"?"":"none"}),p.appendChild(r);const a=document.createElement("button");if(a.className="btn btn-xs btn-ghost",a.style.cssText="line-height:1;opacity:.6;",a.title="Remove field",w(a,"x"),a.addEventListener("click",async c=>{c.stopPropagation(),await E.confirm("Remove this field?")&&($(),g.splice(t,1),L(s))}),p.appendChild(a),o.appendChild(l),o.appendChild(i),e.required){const c=document.createElement("span");c.textContent="required",c.style.cssText="font-size:.7rem;color:var(--dm-danger,#ef4444);flex-shrink:0;",o.appendChild(c)}if(le(e.logic)){const c=document.createElement("span");w(c,"zap"),c.title="Has conditional logic",c.style.cssText="font-size:.75rem;color:var(--dm-primary,#6366f1);flex-shrink:0;",o.appendChild(c)}o.appendChild(p),o.addEventListener("click",()=>{d.style.display=d.style.display==="none"?"":"none"});const d=Ce(e,t,i);return d.style.display="none",n.appendChild(o),n.appendChild(d),n}function Ce(e,t,s){const n=document.createElement("div");n.className="fb-field-body",n.style.cssText="padding:1rem .9rem;border-top:1px solid var(--dm-border,#333);";const o=S([k("Label",`fb-label-${t}`,"text",e.label||"","Shown above the field"),k("Field Name",`fb-name-${t}`,"text",e.name||"","Used as data key")]),l=S([Ie("Type",`fb-type-${t}`,Z,e.type||"string"),de("Required",`fb-required-${t}`,e.required||!1)]),i=S([k("Placeholder",`fb-placeholder-${t}`,"text",e.placeholder||"","Hint text inside the field")]),p=S([k("Helper Text",`fb-helper-${t}`,"text",e.helper||"","Shown below the field"),k("Tooltip",`fb-tooltip-${t}`,"text",e.tooltip||"","Shown on hover via a help icon next to the label")]),r=e.formConfig?.span,a=S([k("Column Span",`fb-span-${t}`,"number",r&&r!=="full"?String(r):"1","Columns to span (grid only)"),de("Full Width",`fb-fullwidth-${t}`,r==="full")]);a.classList.add("fb-grid-row"),a.style.display=document.getElementById("setting-layout")?.value==="grid"?"flex":"none",n.appendChild(o),n.appendChild(l),n.appendChild(i),n.appendChild(p),n.appendChild(a);const d=n.querySelector(`#fb-label-${t}`),c=n.querySelector(`#fb-name-${t}`);d&&d.addEventListener("input",()=>{s&&(s.textContent=d.value||"(unlabelled)"),c&&!c.dataset.manuallyEdited&&(c.value=te(d.value))}),c&&c.addEventListener("input",()=>{c.dataset.manuallyEdited="1"});const u=n.querySelector(`#fb-type-${t}`);u&&u.addEventListener("change",()=>{const f=n.closest(".fb-field-card");if(f){const b=f.querySelector("span");b&&(b.textContent=ne(u.value))}const y=n.querySelector(".fb-field-extras");y&&y.remove();const h=se(u.value,e,t);h&&n.appendChild(h)});const m=se(e.type,e,t);return m&&n.appendChild(m),n.appendChild(Ne(e,t)),n}const Ee=[{value:"equals",label:"equals"},{value:"not_equals",label:"does not equal"},{value:"contains",label:"contains"},{value:"not_contains",label:"does not contain"},{value:"starts_with",label:"starts with"},{value:"ends_with",label:"ends with"},{value:"greater_than",label:"is greater than"},{value:"less_than",label:"is less than"},{value:"is_empty",label:"is empty"},{value:"is_not_empty",label:"is not empty"},{value:"in",label:"is one of (comma sep)"},{value:"not_in",label:"is not one of (comma sep)"},{value:"matches_regex",label:"matches regex"}],oe=new Set(["is_empty","is_not_empty"]);function H(e){const t=document.createElement("p");return t.textContent=e,t.style.cssText="font-size:.72rem;font-weight:700;color:var(--dm-text-muted,#888);margin:1rem 0 .45rem;text-transform:uppercase;letter-spacing:.06em;",t}function V(e,t,s,n,o){const l=document.createElement("div");l.className="fb-logic-cond-row",l.style.cssText="display:flex;gap:.35rem;align-items:center;margin-bottom:.35rem;flex-wrap:wrap;";const i=document.createElement("span");i.textContent="When",i.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);flex-shrink:0;";const p=document.createElement("select");p.className="form-select fb-logic-cond-field",p.style.cssText="flex:1 1 140px;min-width:140px;",t.forEach(m=>{const f=document.createElement("option");f.value=m.value,f.textContent=m.label,e&&m.value===e.field&&(f.selected=!0),p.appendChild(f)});const r=document.createElement("select");r.className="form-select fb-logic-cond-op",r.style.cssText="flex:1 1 160px;min-width:140px;",Ee.forEach(m=>{const f=document.createElement("option");f.value=m.value,f.textContent=m.label,e&&m.value===e.operator&&(f.selected=!0),r.appendChild(f)});const a=document.createElement("input");a.type="text",a.className="form-input fb-logic-cond-val",a.placeholder="value",a.style.cssText="flex:1 1 120px;min-width:100px;",a.value=e?.value||"",e&&oe.has(e.operator)&&(a.style.display="none"),r.addEventListener("change",()=>{a.style.display=oe.has(r.value)?"none":""});const d=document.createElement("span");w(d,"arrow-right"),d.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);flex-shrink:0;";const c=document.createElement("select");c.className=`form-select ${n}`,c.style.cssText="flex:1 1 140px;min-width:120px;",s.forEach(m=>{const f=document.createElement("option");f.value=m.value,f.textContent=m.label,m.value===o&&(f.selected=!0),c.appendChild(f)});const u=document.createElement("button");return u.type="button",u.className="btn btn-xs btn-ghost",u.style.cssText="line-height:1;opacity:.6;",w(u,"x"),u.style.flexShrink="0",u.addEventListener("click",()=>l.remove()),l.appendChild(i),l.appendChild(p),l.appendChild(r),l.appendChild(a),l.appendChild(d),l.appendChild(c),l.appendChild(u),l}function we(e,t,s){const n=document.createElement("div");n.dataset.logicSection="visibility",n.appendChild(H("Visibility"));const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const l=document.createElement("span");l.textContent="Default:",l.style.cssText="font-size:.8rem;flex-shrink:0;";const i=document.createElement("select");i.className="form-select fb-logic-vis-default",i.style.cssText="max-width:240px;",[{value:"visible",label:"Visible"},{value:"hidden",label:"Hidden"}].forEach(m=>{const f=document.createElement("option");f.value=m.value,f.textContent=m.label,m.value===(e.default||"visible")&&(f.selected=!0),i.appendChild(f)}),o.appendChild(l),o.appendChild(i),n.appendChild(o);const p=document.createElement("div");p.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const r=document.createElement("span");r.textContent="Transition:",r.style.cssText="font-size:.8rem;flex-shrink:0;";const a=document.createElement("select");a.className="form-select fb-logic-vis-transition",a.style.cssText="max-width:240px;",[{value:"none",label:"None (instant)"},{value:"fade",label:"Fade"},{value:"slide",label:"Slide"},{value:"scale",label:"Scale"}].forEach(m=>{const f=document.createElement("option");f.value=m.value,f.textContent=m.label,m.value===(e.transition||"none")&&(f.selected=!0),a.appendChild(f)}),p.appendChild(r),p.appendChild(a),n.appendChild(p);const d=document.createElement("div");d.className="fb-logic-vis-rules";const c=s.map(m=>({value:m.name,label:m.label||m.name})),u=[{value:"visible",label:"Show"},{value:"hidden",label:"Hide"}];if((e.conditions||[]).forEach(m=>{const f=(m.when?.all||m.when?.any||[])[0],y=m.then==="hidden"?"hidden":"visible";c.length>0&&d.appendChild(V(f,c,u,"fb-logic-vis-then",y))}),n.appendChild(d),c.length>0){const m=document.createElement("button");m.type="button",m.className="btn btn-xs btn-ghost",m.style.cssText="font-size:.73rem;margin-top:.2rem;",D(m,"plus","Add visibility rule"),m.addEventListener("click",()=>d.appendChild(V(null,c,u,"fb-logic-vis-then","visible"))),n.appendChild(m)}return n}function Se(e,t,s){const n=document.createElement("div");n.dataset.logicSection="requirement",n.appendChild(H("Conditional Requirement"));const o=document.createElement("label");o.style.cssText="display:flex;align-items:center;gap:.4rem;font-size:.8rem;cursor:pointer;margin-bottom:.4rem;";const l=document.createElement("input");l.type="checkbox",l.className="fb-logic-req-default",l.checked=e.default===!0,o.appendChild(l),o.appendChild(document.createTextNode("Required by default")),n.appendChild(o);const i=document.createElement("div");i.className="fb-logic-req-rules";const p=s.map(a=>({value:a.name,label:a.label||a.name})),r=[{value:"true",label:"Make required"},{value:"false",label:"Make optional"}];if((e.conditions||[]).forEach(a=>{const d=(a.when?.all||a.when?.any||[])[0],c=a.then===!0?"true":"false";p.length>0&&i.appendChild(V(d,p,r,"fb-logic-req-then",c))}),n.appendChild(i),p.length>0){const a=document.createElement("button");a.type="button",a.className="btn btn-xs btn-ghost",a.style.cssText="font-size:.73rem;margin-top:.2rem;",D(a,"plus","Add requirement rule"),a.addEventListener("click",()=>i.appendChild(V(null,p,r,"fb-logic-req-then","true"))),n.appendChild(a)}return n}function ae(e){const t=document.createElement("div");t.className="fb-logic-val-rule",t.style.cssText="display:flex;gap:.35rem;align-items:center;margin-bottom:.35rem;flex-wrap:wrap;";const s=document.createElement("select");s.className="form-select fb-logic-val-type",s.style.cssText="flex:0 0 140px;",[{value:"regex",label:"Regex"},{value:"match",label:"Match field"}].forEach(p=>{const r=document.createElement("option");r.value=p.value,r.textContent=p.label,p.value===(e?.type||"regex")&&(r.selected=!0),s.appendChild(r)});const n=document.createElement("input");n.type="text",n.className="form-input fb-logic-val-pattern",n.placeholder=e?.type==="match"?"field name":"pattern",n.value=e?.pattern||e?.field||"",n.style.cssText="flex:3;";const o=document.createElement("input");o.type="text",o.className="form-input fb-logic-val-flags",o.placeholder="flags",o.value=e?.flags||"",o.style.cssText="flex:0 0 55px;",e?.type==="match"&&(o.style.display="none"),s.addEventListener("change",()=>{o.style.display=s.value==="match"?"none":"",n.placeholder=s.value==="match"?"field name":"pattern"});const l=document.createElement("input");l.type="text",l.className="form-input fb-logic-val-message",l.placeholder="Error message",l.value=e?.message||"",l.style.cssText="flex:4;";const i=document.createElement("button");return i.type="button",i.className="btn btn-xs btn-ghost",i.style.cssText="line-height:1;opacity:.6;",w(i,"x"),i.style.flexShrink="0",i.addEventListener("click",()=>t.remove()),t.appendChild(s),t.appendChild(n),t.appendChild(o),t.appendChild(l),t.appendChild(i),t}function ke(e,t,s){const n=document.createElement("div");n.dataset.logicSection="validation",n.appendChild(H("Custom Validation"));const o=document.createElement("div");o.className="fb-logic-val-rules",(e||[]).forEach(i=>o.appendChild(ae(i))),n.appendChild(o);const l=document.createElement("button");return l.type="button",l.className="btn btn-xs btn-ghost",l.style.cssText="font-size:.73rem;margin-top:.2rem;",D(l,"plus","Add validation rule"),l.addEventListener("click",()=>o.appendChild(ae(null))),n.appendChild(l),n}function Te(e,t,s){const n=document.createElement("div");n.dataset.logicSection="cascade",n.appendChild(H("Cascade Options")),n.lastChild.appendChild(Q("Make this field's options depend on another field. When the source field changes, the options here are replaced by the mapping entry for its value; if nothing matches, the default options below are shown."));const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem;";const l=document.createElement("span");l.textContent="Source field:",l.style.cssText="font-size:.8rem;flex-shrink:0;";const i=document.createElement("select");i.className="form-select fb-logic-cascade-source",i.style.cssText="flex:1;";const p=document.createElement("option");p.value="",p.textContent="\u2014 none \u2014",i.appendChild(p),s.forEach(u=>{const m=document.createElement("option");m.value=u.name,m.textContent=u.label||u.name,u.name===e.sourceField&&(m.selected=!0),i.appendChild(m)}),o.appendChild(l),o.appendChild(i),n.appendChild(o);const r=document.createElement("p");r.textContent='Mapping JSON \u2014 {"value":[{"value":"...","label":"..."}]}',r.appendChild(Q(`Each key is a value of the source field; its list becomes this field's options when that value is picked. Example: {"uk":[{"value":"london","label":"London"}]} shows London when the source is "uk".`)),r.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);margin:.3rem 0 .2rem;";const a=document.createElement("textarea");a.className="form-input fb-logic-cascade-mapping",a.rows=4,a.style.cssText="font-family:monospace;",a.placeholder='{"uk": [{"value": "london", "label": "London"}]}',a.value=e.mapping?JSON.stringify(e.mapping,null,2):"",n.appendChild(r),n.appendChild(a);const d=document.createElement("p");d.textContent="Default options (one per line: value:Label)",d.appendChild(Q("Shown before the source field has a value, or when its value has no mapping entry.")),d.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);margin:.3rem 0 .2rem;";const c=document.createElement("textarea");return c.className="form-input fb-logic-cascade-defaults",c.rows=3,c.style.cssText="font-family:monospace;",c.placeholder=`option1:Option 1
1
+ import{apiRequest as I}from"/admin/js/api.js";import{makeIconInput as fe}from"/admin/js/lib/shortcode-modal.js";const Z=[{value:"string",label:"Text (single line)"},{value:"email",label:"Email"},{value:"tel",label:"Phone"},{value:"number",label:"Number"},{value:"textarea",label:"Textarea (multi-line)"},{value:"select",label:"Dropdown (select)"},{value:"radio",label:"Radio buttons"},{value:"checkbox",label:"Single checkbox"},{value:"checkbox-group",label:"Checkbox group"},{value:"chooser",label:"Chooser (visual options)"},{value:"date",label:"Date"},{value:"time",label:"Time"},{value:"url",label:"URL"},{value:"password",label:"Password"},{value:"file",label:"File upload"},{value:"hidden",label:"Hidden field"}],W=new Set(["select","radio","checkbox-group","chooser"]);let g=[],q=null,P=null,M=null,G={};function w(e,n,s=14){e.textContent="";const t=document.createElement("span");return t.setAttribute("data-icon",n),t.setAttribute("data-icon-size",String(s)),t.style.cssText="display:inline-flex;align-items:center;vertical-align:middle;",e.appendChild(t),window.I?.scan?.(e),e}function D(e,n,s,t=14){return w(e,n,t),e.appendChild(document.createTextNode(" "+s)),e}function Q(e){const n=document.createElement("span");return n.setAttribute("data-icon","help-circle"),n.setAttribute("data-icon-size","12"),n.style.cssText="display:inline-flex;align-items:center;vertical-align:middle;margin-left:.3rem;opacity:.55;cursor:help;",window.I?.scan?.(n),typeof E<"u"&&E.tooltip&&E.tooltip(n,{content:e,position:"top"}),n}let _=null,ee=null;function Y(){clearTimeout(ee),ee=setTimeout(()=>{_&&_()},350)}function te(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_|_$/g,"")}function ne(e){return Z.find(n=>n.value===e)?.label||e}function le(e){return e?!!(e.visibility?.conditions?.length||e.requirement?.conditions?.length||e.validation?.length||e.cascade?.sourceField):!1}function he(e){const n={...g[e]};if(n.type==="spacer")return n;if(n.type==="page-break"){const h=document.getElementById(`fb-pb-label-${e}`),b=document.getElementById(`fb-pb-desc-${e}`);return h&&(n.label=h.value.trim()||n.label),b&&(n.description=b.value.trim()),n}const s=document.getElementById(`fb-label-${e}`),t=document.getElementById(`fb-name-${e}`),o=document.getElementById(`fb-type-${e}`),l=document.getElementById(`fb-required-${e}`),i=document.getElementById(`fb-placeholder-${e}`),d=document.getElementById(`fb-helper-${e}`),r=document.getElementById(`fb-tooltip-${e}`);if(s&&(n.label=s.value.trim()||n.label),t&&(n.name=t.value.trim()||n.name),o&&(n.type=o.value||n.type),l&&(n.required=l.checked),i&&(n.placeholder=i.value.trim()),d&&(n.helper=d.value.trim()),r&&(n.tooltip=r.value.trim()),n.type==="chooser"){const h=document.getElementById(`fb-chooser-variant-${e}`)?.value;h&&(n.variant=h);const b=document.getElementById(`fb-chooser-multiple-${e}`);b&&(n.multiple=b.checked);const v=document.getElementById(`fb-chooser-density-${e}`)?.value;v&&(n.density=v);const C=document.getElementById(`fb-chooser-columns-${e}`)?.value;C!==""&&C!==void 0&&(n.columns=parseInt(C,10)||3);const x=document.getElementById(`fb-chooser-accent-${e}`)?.value.trim();x?n.accent=x:delete n.accent;const T=document.getElementById(`fb-chooser-accent-style-${e}`)?.value;T?n.accentStyle=T:delete n.accentStyle;const z=document.getElementById(`fb-chooser-glow-${e}`);z&&(n.glow=z.checked);const B=document.getElementById(`fb-chooser-glow-colour-${e}`)?.value.trim();B?n.glowColour=B:delete n.glowColour;const N=document.getElementById(`fb-chooser-shadow-${e}`)?.value;N&&N!=="none"?n.shadow=N:delete n.shadow;const O=document.getElementById(`fb-chooser-shadow-colour-${e}`)?.value.trim();O?n.shadowColour=O:delete n.shadowColour,J(e),g[e]&&Array.isArray(g[e].options)&&(n.options=g[e].options)}else if(W.has(n.type)){const h=document.getElementById(`fb-options-${e}`);h&&(n.options=h.value.split(`
2
+ `).filter(b=>b.trim()).map(b=>{const[v,...C]=b.split(":");return{value:v.trim(),label:C.join(":").trim()||v.trim()}}))}if(n.type==="textarea"){const h=parseInt(document.getElementById(`fb-rows-${e}`)?.value,10);h>0&&(n.formConfig={...n.formConfig||{},rows:h})}const a=document.getElementById(`fb-span-${e}`),p=document.getElementById(`fb-fullwidth-${e}`);if(a||p){const h={...n.formConfig||{}};if(p?.checked)h.span="full";else{const b=parseInt(a?.value,10);b>1?h.span=b:delete h.span}n.formConfig=Object.keys(h).length?h:void 0}const c=document.getElementById(`fb-minlength-${e}`)?.value;c&&(n.minLength=parseInt(c,10));const u=document.getElementById(`fb-maxlength-${e}`)?.value;u&&(n.maxLength=parseInt(u,10));const m=document.getElementById(`fb-min-${e}`)?.value;m!==""&&m!==void 0&&(n.min=parseFloat(m));const f=document.getElementById(`fb-max-${e}`)?.value;f!==""&&f!==void 0&&(n.max=parseFloat(f));const y=be(e);return y?n.logic=y:delete n.logic,n}function be(e){const n=document.querySelector(`.fb-field-card[data-index="${e}"]`);if(!n)return;const s=n.querySelector(".fb-field-logic");if(!s)return;const t={};let o=!1;const l=s.querySelector('[data-logic-section="visibility"]');if(l){const a=l.querySelector(".fb-logic-vis-default"),p=l.querySelector(".fb-logic-vis-transition"),c=Array.from(l.querySelectorAll(".fb-logic-cond-row")).map(f=>{const y=f.querySelector(".fb-logic-cond-field"),h=f.querySelector(".fb-logic-cond-op"),b=f.querySelector(".fb-logic-cond-val"),v=f.querySelector(".fb-logic-vis-then");return y?.value?{when:{all:[{field:y.value,operator:h.value,value:b.value}]},then:v.value}:null}).filter(Boolean),u=a?.value||"visible",m=p?.value||"none";(u!=="visible"||c.length>0||m!=="none")&&(t.visibility={default:u,conditions:c},m!=="none"&&(t.visibility.transition=m),o=!0)}const i=s.querySelector('[data-logic-section="requirement"]');if(i){const a=i.querySelector(".fb-logic-req-default"),p=Array.from(i.querySelectorAll(".fb-logic-cond-row")).map(c=>{const u=c.querySelector(".fb-logic-cond-field"),m=c.querySelector(".fb-logic-cond-op"),f=c.querySelector(".fb-logic-cond-val"),y=c.querySelector(".fb-logic-req-then");return u?.value?{when:{all:[{field:u.value,operator:m.value,value:f.value}]},then:y.value==="true"}:null}).filter(Boolean);p.length>0&&(t.requirement={default:a?.checked===!0,conditions:p},o=!0)}const d=s.querySelector('[data-logic-section="validation"]');if(d){const a=Array.from(d.querySelectorAll(".fb-logic-val-rule")).map(p=>{const c=p.querySelector(".fb-logic-val-type"),u=p.querySelector(".fb-logic-val-pattern"),m=p.querySelector(".fb-logic-val-flags"),f=p.querySelector(".fb-logic-val-message");if(!u?.value.trim())return null;const y=c?.value||"regex",h={type:y,message:f?.value.trim()||"Invalid value."};return y==="regex"?(h.pattern=u.value.trim(),m?.value.trim()&&(h.flags=m.value.trim())):h.field=u.value.trim(),h}).filter(Boolean);a.length>0&&(t.validation=a,o=!0)}const r=s.querySelector('[data-logic-section="cascade"]');if(r){const a=r.querySelector(".fb-logic-cascade-source"),p=r.querySelector(".fb-logic-cascade-mapping"),c=r.querySelector(".fb-logic-cascade-defaults"),u=a?.value?.trim();if(u){let m={};try{m=JSON.parse(p?.value||"{}")}catch{}const f=(c?.value||"").split(`
3
+ `).filter(y=>y.trim()).map(y=>{const[h,...b]=y.split(":");return{value:h.trim(),label:b.join(":").trim()||h.trim()}});t.cascade={sourceField:u,mapping:m,defaultOptions:f},o=!0}}return o?t:void 0}function $(){g=g.map((e,n)=>he(n))}let A=null;function ge(e,n,s){const t=e.firstElementChild;if(!t)return;const o=document.createElement("span");o.setAttribute("data-icon","menu"),o.setAttribute("data-icon-size","13"),o.title="Drag to reorder",o.style.cssText="cursor:grab;opacity:.35;flex-shrink:0;display:inline-flex;align-items:center;",t.insertBefore(o,t.firstChild),window.I?.scan?.(t),t.draggable=!0,t.addEventListener("dragstart",l=>{A=n,l.dataTransfer.effectAllowed="move",e.style.opacity="0.4"}),t.addEventListener("dragend",()=>{e.style.opacity="",document.querySelectorAll("#fields-list .fb-field-card").forEach(l=>l.classList.remove("fb-drag-over"))}),e.addEventListener("dragover",l=>{A!=null&&(l.preventDefault(),l.dataTransfer.dropEffect="move",document.querySelectorAll("#fields-list .fb-field-card").forEach(i=>i.classList.remove("fb-drag-over")),e.classList.add("fb-drag-over"))}),e.addEventListener("dragleave",()=>e.classList.remove("fb-drag-over")),e.addEventListener("drop",l=>{if(l.preventDefault(),e.classList.remove("fb-drag-over"),A==null||A===n){A=null;return}$();const[i]=g.splice(A,1);g.splice(n,0,i),A=null,L(s)})}function L(e){const n=e.find("#fields-list").get(0),s=e.find("#fields-empty-msg").get(0);if(n){if(Array.from(n.querySelectorAll(".fb-field-card")).forEach(t=>t.remove()),g.length===0){s&&(s.style.display=""),Y();return}s&&(s.style.display="none"),g.forEach((t,o)=>{const l=t.type==="page-break"?ye(t,o,e):t.type==="spacer"?ve(t,o,e):xe(t,o,e);ge(l,o,e),n.appendChild(l)}),Y()}}function ye(e,n,s){const t=document.createElement("div");t.className="fb-field-card",t.dataset.index=n,t.style.cssText="border:2px dashed var(--dm-border,#444);border-radius:8px;overflow:hidden;margin-bottom:.75rem;background:var(--dm-card-bg,rgba(255,255,255,.02));";const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.6rem .8rem;cursor:pointer;user-select:none;";const l=document.createElement("span");l.textContent="\u2014 Page Break \u2014",l.style.cssText="font-size:.7rem;padding:.15rem .5rem;border-radius:999px;background:color-mix(in srgb, var(--dm-text-muted) 20%, transparent);color:var(--dm-text-muted,#888);white-space:nowrap;flex-shrink:0;font-style:italic;";const i=document.createElement("span");i.textContent=e.label||"Untitled Step",i.style.cssText="flex:1;font-weight:600;font-size:.9rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dm-text-muted,#888);";const d=document.createElement("div");d.style.cssText="display:flex;gap:.25rem;flex-shrink:0;margin-left:.5rem;";const r=document.createElement("button");r.className="btn btn-xs btn-ghost",r.title="Edit step",w(r,"more-horizontal"),r.addEventListener("click",m=>{m.stopPropagation(),p.style.display=p.style.display==="none"?"":"none"}),d.appendChild(r);const a=document.createElement("button");a.className="btn btn-xs btn-ghost",a.style.cssText="line-height:1;opacity:.6;",a.title="Remove page break",w(a,"x"),a.addEventListener("click",async m=>{m.stopPropagation(),await E.confirm("Remove this page break?")&&($(),g.splice(n,1),L(s))}),d.appendChild(a),o.appendChild(l),o.appendChild(i),o.appendChild(d),o.addEventListener("click",()=>{p.style.display=p.style.display==="none"?"":"none"});const p=document.createElement("div");p.className="fb-field-body",p.style.cssText="padding:.8rem;border-top:1px dashed var(--dm-border,#444);display:none;";const c=k([S("Step Title",`fb-pb-label-${n}`,"text",e.label||"","Shown as the wizard step heading"),S("Step Description",`fb-pb-desc-${n}`,"text",e.description||"","Optional sub-heading")]),u=c.querySelector(`#fb-pb-label-${n}`);return u&&u.addEventListener("input",()=>{i.textContent=u.value||"Untitled Step"}),p.appendChild(c),t.appendChild(o),t.appendChild(p),t}function ve(e,n,s){const t=document.createElement("div");t.className="fb-field-card",t.dataset.index=n,t.style.cssText="border:1px dashed var(--dm-border,#444);border-radius:6px;margin-bottom:.5rem;background:transparent;";const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.4rem .8rem;";const l=document.createElement("div");l.style.cssText="flex:1;height:1px;background:var(--dm-border,#444);";const i=document.createElement("span");i.textContent="Spacer",i.style.cssText="font-size:.7rem;color:var(--dm-text-muted,#888);white-space:nowrap;padding:0 .4rem;font-style:italic;";const d=document.createElement("div");d.style.cssText="flex:1;height:1px;background:var(--dm-border,#444);";const r=document.createElement("div");r.style.cssText="display:flex;gap:.25rem;flex-shrink:0;";const a=document.createElement("button");return a.className="btn btn-xs btn-ghost",a.style.cssText="line-height:1;opacity:.6;",a.title="Remove spacer",w(a,"x"),a.addEventListener("click",async p=>{p.stopPropagation(),$(),g.splice(n,1),L(s)}),r.appendChild(a),o.appendChild(l),o.appendChild(i),o.appendChild(d),o.appendChild(r),t.appendChild(o),t}function xe(e,n,s){const t=document.createElement("div");t.className="fb-field-card",t.dataset.index=n,t.style.cssText="border:1px solid var(--dm-border,#333);border-radius:8px;overflow:hidden;margin-bottom:.75rem;background:var(--dm-card-bg);box-shadow:var(--dm-shadow-sm);";const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.6rem;padding:.65rem .85rem;background:var(--dm-card-header-bg,rgba(255,255,255,.04));cursor:pointer;user-select:none;";const l=document.createElement("span");l.textContent=ne(e.type),l.style.cssText="font-size:.7rem;padding:.15rem .45rem;border-radius:999px;background:color-mix(in srgb, var(--dm-primary) 14%, transparent);color:var(--dm-primary,#6366f1);white-space:nowrap;flex-shrink:0;";const i=document.createElement("span");i.textContent=e.label||"(unlabelled)",i.style.cssText="flex:1;font-weight:600;font-size:.9rem;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;";const d=document.createElement("div");d.style.cssText="display:flex;gap:.25rem;flex-shrink:0;margin-left:.5rem;";const r=document.createElement("button");r.className="btn btn-xs btn-ghost",r.title="Edit field",w(r,"more-horizontal"),r.addEventListener("click",c=>{c.stopPropagation(),p.style.display=p.style.display==="none"?"":"none"}),d.appendChild(r);const a=document.createElement("button");if(a.className="btn btn-xs btn-ghost",a.style.cssText="line-height:1;opacity:.6;",a.title="Remove field",w(a,"x"),a.addEventListener("click",async c=>{c.stopPropagation(),await E.confirm("Remove this field?")&&($(),g.splice(n,1),L(s))}),d.appendChild(a),o.appendChild(l),o.appendChild(i),e.required){const c=document.createElement("span");c.textContent="required",c.style.cssText="font-size:.7rem;color:var(--dm-danger,#ef4444);flex-shrink:0;",o.appendChild(c)}if(le(e.logic)){const c=document.createElement("span");w(c,"zap"),c.title="Has conditional logic",c.style.cssText="font-size:.75rem;color:var(--dm-primary,#6366f1);flex-shrink:0;",o.appendChild(c)}o.appendChild(d),o.addEventListener("click",()=>{p.style.display=p.style.display==="none"?"":"none"});const p=Ce(e,n,i);return p.style.display="none",t.appendChild(o),t.appendChild(p),t}function Ce(e,n,s){const t=document.createElement("div");t.className="fb-field-body",t.style.cssText="padding:1rem .9rem;border-top:1px solid var(--dm-border,#333);";const o=k([S("Label",`fb-label-${n}`,"text",e.label||"","Shown above the field"),S("Field Name",`fb-name-${n}`,"text",e.name||"","Used as data key")]),l=k([Ie("Type",`fb-type-${n}`,Z,e.type||"string"),de("Required",`fb-required-${n}`,e.required||!1)]),i=k([S("Placeholder",`fb-placeholder-${n}`,"text",e.placeholder||"","Hint text inside the field")]),d=k([S("Helper Text",`fb-helper-${n}`,"text",e.helper||"","Shown below the field"),S("Tooltip",`fb-tooltip-${n}`,"text",e.tooltip||"","Shown on hover via a help icon next to the label")]),r=e.formConfig?.span,a=k([S("Column Span",`fb-span-${n}`,"number",r&&r!=="full"?String(r):"1","Columns to span (grid only)"),de("Full Width",`fb-fullwidth-${n}`,r==="full")]);a.classList.add("fb-grid-row"),a.style.display=document.getElementById("setting-layout")?.value==="grid"?"flex":"none",t.appendChild(o),t.appendChild(l),t.appendChild(i),t.appendChild(d),t.appendChild(a);const p=t.querySelector(`#fb-label-${n}`),c=t.querySelector(`#fb-name-${n}`);p&&p.addEventListener("input",()=>{s&&(s.textContent=p.value||"(unlabelled)"),c&&!c.dataset.manuallyEdited&&(c.value=te(p.value))}),c&&c.addEventListener("input",()=>{c.dataset.manuallyEdited="1"});const u=t.querySelector(`#fb-type-${n}`);u&&u.addEventListener("change",()=>{const f=t.closest(".fb-field-card");if(f){const b=f.querySelector("span");b&&(b.textContent=ne(u.value))}const y=t.querySelector(".fb-field-extras");y&&y.remove();const h=se(u.value,e,n);h&&t.appendChild(h)});const m=se(e.type,e,n);return m&&t.appendChild(m),t.appendChild(Ne(e,n)),t}const Ee=[{value:"equals",label:"equals"},{value:"not_equals",label:"does not equal"},{value:"contains",label:"contains"},{value:"not_contains",label:"does not contain"},{value:"starts_with",label:"starts with"},{value:"ends_with",label:"ends with"},{value:"greater_than",label:"is greater than"},{value:"less_than",label:"is less than"},{value:"is_empty",label:"is empty"},{value:"is_not_empty",label:"is not empty"},{value:"in",label:"is one of (comma sep)"},{value:"not_in",label:"is not one of (comma sep)"},{value:"matches_regex",label:"matches regex"}],oe=new Set(["is_empty","is_not_empty"]);function H(e){const n=document.createElement("p");return n.textContent=e,n.style.cssText="font-size:.72rem;font-weight:700;color:var(--dm-text-muted,#888);margin:1rem 0 .45rem;text-transform:uppercase;letter-spacing:.06em;",n}function V(e,n,s,t,o){const l=document.createElement("div");l.className="fb-logic-cond-row",l.style.cssText="display:flex;gap:.35rem;align-items:center;margin-bottom:.35rem;flex-wrap:wrap;";const i=document.createElement("span");i.textContent="When",i.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);flex-shrink:0;";const d=document.createElement("select");d.className="form-select fb-logic-cond-field",d.style.cssText="flex:1 1 140px;min-width:140px;",n.forEach(m=>{const f=document.createElement("option");f.value=m.value,f.textContent=m.label,e&&m.value===e.field&&(f.selected=!0),d.appendChild(f)});const r=document.createElement("select");r.className="form-select fb-logic-cond-op",r.style.cssText="flex:1 1 160px;min-width:140px;",Ee.forEach(m=>{const f=document.createElement("option");f.value=m.value,f.textContent=m.label,e&&m.value===e.operator&&(f.selected=!0),r.appendChild(f)});const a=document.createElement("input");a.type="text",a.className="form-input fb-logic-cond-val",a.placeholder="value",a.style.cssText="flex:1 1 120px;min-width:100px;",a.value=e?.value||"",e&&oe.has(e.operator)&&(a.style.display="none"),r.addEventListener("change",()=>{a.style.display=oe.has(r.value)?"none":""});const p=document.createElement("span");w(p,"arrow-right"),p.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);flex-shrink:0;";const c=document.createElement("select");c.className=`form-select ${t}`,c.style.cssText="flex:1 1 140px;min-width:120px;",s.forEach(m=>{const f=document.createElement("option");f.value=m.value,f.textContent=m.label,m.value===o&&(f.selected=!0),c.appendChild(f)});const u=document.createElement("button");return u.type="button",u.className="btn btn-xs btn-ghost",u.style.cssText="line-height:1;opacity:.6;",w(u,"x"),u.style.flexShrink="0",u.addEventListener("click",()=>l.remove()),l.appendChild(i),l.appendChild(d),l.appendChild(r),l.appendChild(a),l.appendChild(p),l.appendChild(c),l.appendChild(u),l}function we(e,n,s){const t=document.createElement("div");t.dataset.logicSection="visibility",t.appendChild(H("Visibility"));const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const l=document.createElement("span");l.textContent="Default:",l.style.cssText="font-size:.8rem;flex-shrink:0;";const i=document.createElement("select");i.className="form-select fb-logic-vis-default",i.style.cssText="max-width:240px;",[{value:"visible",label:"Visible"},{value:"hidden",label:"Hidden"}].forEach(m=>{const f=document.createElement("option");f.value=m.value,f.textContent=m.label,m.value===(e.default||"visible")&&(f.selected=!0),i.appendChild(f)}),o.appendChild(l),o.appendChild(i),t.appendChild(o);const d=document.createElement("div");d.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.4rem;";const r=document.createElement("span");r.textContent="Transition:",r.style.cssText="font-size:.8rem;flex-shrink:0;";const a=document.createElement("select");a.className="form-select fb-logic-vis-transition",a.style.cssText="max-width:240px;",[{value:"none",label:"None (instant)"},{value:"fade",label:"Fade"},{value:"slide",label:"Slide"},{value:"scale",label:"Scale"}].forEach(m=>{const f=document.createElement("option");f.value=m.value,f.textContent=m.label,m.value===(e.transition||"none")&&(f.selected=!0),a.appendChild(f)}),d.appendChild(r),d.appendChild(a),t.appendChild(d);const p=document.createElement("div");p.className="fb-logic-vis-rules";const c=s.map(m=>({value:m.name,label:m.label||m.name})),u=[{value:"visible",label:"Show"},{value:"hidden",label:"Hide"}];if((e.conditions||[]).forEach(m=>{const f=(m.when?.all||m.when?.any||[])[0],y=m.then==="hidden"?"hidden":"visible";c.length>0&&p.appendChild(V(f,c,u,"fb-logic-vis-then",y))}),t.appendChild(p),c.length>0){const m=document.createElement("button");m.type="button",m.className="btn btn-xs btn-ghost",m.style.cssText="font-size:.73rem;margin-top:.2rem;",D(m,"plus","Add visibility rule"),m.addEventListener("click",()=>p.appendChild(V(null,c,u,"fb-logic-vis-then","visible"))),t.appendChild(m)}return t}function ke(e,n,s){const t=document.createElement("div");t.dataset.logicSection="requirement",t.appendChild(H("Conditional Requirement"));const o=document.createElement("label");o.style.cssText="display:flex;align-items:center;gap:.4rem;font-size:.8rem;cursor:pointer;margin-bottom:.4rem;";const l=document.createElement("input");l.type="checkbox",l.className="fb-logic-req-default",l.checked=e.default===!0,o.appendChild(l),o.appendChild(document.createTextNode("Required by default")),t.appendChild(o);const i=document.createElement("div");i.className="fb-logic-req-rules";const d=s.map(a=>({value:a.name,label:a.label||a.name})),r=[{value:"true",label:"Make required"},{value:"false",label:"Make optional"}];if((e.conditions||[]).forEach(a=>{const p=(a.when?.all||a.when?.any||[])[0],c=a.then===!0?"true":"false";d.length>0&&i.appendChild(V(p,d,r,"fb-logic-req-then",c))}),t.appendChild(i),d.length>0){const a=document.createElement("button");a.type="button",a.className="btn btn-xs btn-ghost",a.style.cssText="font-size:.73rem;margin-top:.2rem;",D(a,"plus","Add requirement rule"),a.addEventListener("click",()=>i.appendChild(V(null,d,r,"fb-logic-req-then","true"))),t.appendChild(a)}return t}function ae(e){const n=document.createElement("div");n.className="fb-logic-val-rule",n.style.cssText="display:flex;gap:.35rem;align-items:center;margin-bottom:.35rem;flex-wrap:wrap;";const s=document.createElement("select");s.className="form-select fb-logic-val-type",s.style.cssText="flex:0 0 140px;",[{value:"regex",label:"Regex"},{value:"match",label:"Match field"}].forEach(d=>{const r=document.createElement("option");r.value=d.value,r.textContent=d.label,d.value===(e?.type||"regex")&&(r.selected=!0),s.appendChild(r)});const t=document.createElement("input");t.type="text",t.className="form-input fb-logic-val-pattern",t.placeholder=e?.type==="match"?"field name":"pattern",t.value=e?.pattern||e?.field||"",t.style.cssText="flex:3;";const o=document.createElement("input");o.type="text",o.className="form-input fb-logic-val-flags",o.placeholder="flags",o.value=e?.flags||"",o.style.cssText="flex:0 0 55px;",e?.type==="match"&&(o.style.display="none"),s.addEventListener("change",()=>{o.style.display=s.value==="match"?"none":"",t.placeholder=s.value==="match"?"field name":"pattern"});const l=document.createElement("input");l.type="text",l.className="form-input fb-logic-val-message",l.placeholder="Error message",l.value=e?.message||"",l.style.cssText="flex:4;";const i=document.createElement("button");return i.type="button",i.className="btn btn-xs btn-ghost",i.style.cssText="line-height:1;opacity:.6;",w(i,"x"),i.style.flexShrink="0",i.addEventListener("click",()=>n.remove()),n.appendChild(s),n.appendChild(t),n.appendChild(o),n.appendChild(l),n.appendChild(i),n}function Se(e,n,s){const t=document.createElement("div");t.dataset.logicSection="validation",t.appendChild(H("Custom Validation"));const o=document.createElement("div");o.className="fb-logic-val-rules",(e||[]).forEach(i=>o.appendChild(ae(i))),t.appendChild(o);const l=document.createElement("button");return l.type="button",l.className="btn btn-xs btn-ghost",l.style.cssText="font-size:.73rem;margin-top:.2rem;",D(l,"plus","Add validation rule"),l.addEventListener("click",()=>o.appendChild(ae(null))),t.appendChild(l),t}function Te(e,n,s){const t=document.createElement("div");t.dataset.logicSection="cascade",t.appendChild(H("Cascade Options")),t.lastChild.appendChild(Q("Make this field's options depend on another field. When the source field changes, the options here are replaced by the mapping entry for its value; if nothing matches, the default options below are shown."));const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem;";const l=document.createElement("span");l.textContent="Source field:",l.style.cssText="font-size:.8rem;flex-shrink:0;";const i=document.createElement("select");i.className="form-select fb-logic-cascade-source",i.style.cssText="flex:1;";const d=document.createElement("option");d.value="",d.textContent="\u2014 none \u2014",i.appendChild(d),s.forEach(u=>{const m=document.createElement("option");m.value=u.name,m.textContent=u.label||u.name,u.name===e.sourceField&&(m.selected=!0),i.appendChild(m)}),o.appendChild(l),o.appendChild(i),t.appendChild(o);const r=document.createElement("p");r.textContent='Mapping JSON \u2014 {"value":[{"value":"...","label":"..."}]}',r.appendChild(Q(`Each key is a value of the source field; its list becomes this field's options when that value is picked. Example: {"uk":[{"value":"london","label":"London"}]} shows London when the source is "uk".`)),r.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);margin:.3rem 0 .2rem;";const a=document.createElement("textarea");a.className="form-input fb-logic-cascade-mapping",a.rows=4,a.style.cssText="font-family:monospace;",a.placeholder='{"uk": [{"value": "london", "label": "London"}]}',a.value=e.mapping?JSON.stringify(e.mapping,null,2):"",t.appendChild(r),t.appendChild(a);const p=document.createElement("p");p.textContent="Default options (one per line: value:Label)",p.appendChild(Q("Shown before the source field has a value, or when its value has no mapping entry.")),p.style.cssText="font-size:.73rem;color:var(--dm-text-muted,#888);margin:.3rem 0 .2rem;";const c=document.createElement("textarea");return c.className="form-input fb-logic-cascade-defaults",c.rows=3,c.style.cssText="font-family:monospace;",c.placeholder=`option1:Option 1
4
4
  option2:Option 2`,c.value=(e.defaultOptions||[]).map(u=>{const m=typeof u=="string"?u:u.value??"",f=typeof u=="string"?u:u.label??m;return m===f?m:`${m}:${f}`}).join(`
5
- `),n.appendChild(d),n.appendChild(c),n}function Ne(e,t){const s=e.logic||{},n=g.filter((c,u)=>u!==t&&c.type!=="page-break"&&c.type!=="spacer"),o=document.createElement("div");o.className="fb-field-logic",o.style.cssText="margin-top:.75rem;border-top:1px solid var(--dm-border,#333);padding-top:.5rem;";const l=document.createElement("div");l.style.cssText="display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:.15rem 0;";const i=document.createElement("span");i.style.cssText="font-size:.8rem;font-weight:600;color:var(--dm-text-muted,#888);",i.textContent="\u26A1 Conditional Logic";const p=le(s),r=document.createElement("button");r.type="button",r.className="btn btn-xs btn-ghost",w(r,p?"chevron-down":"chevron-right",12);const a=document.createElement("div");a.className="fb-logic-body",a.style.cssText="padding:.25rem 0 .25rem;"+(p?"":"display:none;"),l.addEventListener("click",()=>{const c=a.style.display==="none";a.style.display=c?"":"none",w(r,c?"chevron-down":"chevron-right",12)}),l.appendChild(i),l.appendChild(r),o.appendChild(l),a.appendChild(we(s.visibility||{},t,n)),a.appendChild(Se(s.requirement||{},t,n)),a.appendChild(ke(s.validation||[],t,n));const d=document.getElementById(`fb-type-${t}`)?.value||e.type;return W.has(d)&&a.appendChild(Te(s.cascade||{},t,n)),o.appendChild(a),o}function se(e,t,s){const n=document.createElement("div");return n.className="fb-field-extras",e==="chooser"?(n.appendChild(qe(t,s)),n.appendChild(Le(t.options||[],s))):(W.has(e)&&n.appendChild(Fe(t.options||[],s)),e==="textarea"&&n.appendChild(S([k("Rows",`fb-rows-${s}`,"number",t.formConfig?.rows||4,"Height of textarea")])),(e==="string"||e==="textarea")&&n.appendChild(S([k("Min Length",`fb-minlength-${s}`,"number",t.minLength||"",""),k("Max Length",`fb-maxlength-${s}`,"number",t.maxLength||"","")])),e==="number"&&n.appendChild(S([k("Min",`fb-min-${s}`,"number",t.min??"",""),k("Max",`fb-max-${s}`,"number",t.max??"","")]))),n.children.length?n:null}function ie(e){const t=document.createElement("div");t.className="fb-chooser-section",t.style.cssText="border:1px solid var(--dm-border, #e5e7eb); border-radius:6px; margin-top:.5rem; overflow:hidden;";const s=document.createElement("div");s.style.cssText="padding:.4rem .6rem; background:color-mix(in srgb, var(--dm-background, #f9fafb) 60%, transparent); font-weight:600; font-size:.82rem; border-bottom:1px solid var(--dm-border, #e5e7eb);",s.textContent=e,t.appendChild(s);const n=document.createElement("div");return n.className="fb-chooser-section-body",n.style.cssText="padding:.55rem .6rem; display:flex; flex-direction:column; gap:.45rem;",t.appendChild(n),{wrap:t,body:n}}function U(e,t,s,n,o){const l=document.createElement("div");l.style.flex="1";const i=document.createElement("label");i.htmlFor=e,i.className="form-label",i.textContent=t,i.style.fontSize=".8rem";const p=document.createElement("select");if(p.id=e,p.className="form-input",n.forEach(([r,a])=>{const d=document.createElement("option");d.value=r,d.textContent=a,String(r)===String(s)&&(d.selected=!0),p.appendChild(d)}),l.appendChild(i),l.appendChild(p),o){const r=document.createElement("p");r.className="form-hint text-muted",r.textContent=o,r.style.cssText="font-size:.72rem;margin-top:.2rem;",l.appendChild(r)}return l}function ce(e,t,s,n){const o=document.createElement("div");o.style.flex="1";const l=document.createElement("label");l.style.cssText="display:inline-flex;align-items:center;gap:.4rem;font-size:.82rem;";const i=document.createElement("input");if(i.id=e,i.type="checkbox",i.checked=!!s,l.appendChild(i),l.appendChild(document.createTextNode(" "+t)),o.appendChild(l),n){const p=document.createElement("p");p.className="form-hint text-muted",p.textContent=n,p.style.cssText="font-size:.72rem;margin-top:.2rem;",o.appendChild(p)}return o}function K(e,t,s,n,o){const l=document.createElement("div");l.style.flex="1";const i=document.createElement("label");i.htmlFor=e,i.className="form-label",i.textContent=t,i.style.fontSize=".8rem",l.appendChild(i);const p=document.createElement("div");p.style.cssText="display:flex;gap:.4rem;align-items:stretch;";const r=document.createElement("input");r.id=e,r.type="text",r.className="form-input",r.value=s||"",n&&(r.placeholder=n),r.style.flex="1";const a=document.createElement("input");a.type="color",a.title="Pick a colour",a.style.cssText="width:36px;height:auto;padding:0;border:1px solid var(--dm-border,#e5e7eb);border-radius:4px;cursor:pointer;";const d=String(r.value).match(/^#[0-9a-fA-F]{3,8}$/);if(a.value=d?r.value:"#000000",a.addEventListener("input",()=>{r.value=a.value,r.dispatchEvent(new Event("input",{bubbles:!0}))}),p.appendChild(r),p.appendChild(a),l.appendChild(p),o){const c=document.createElement("p");c.className="form-hint text-muted",c.textContent=o,c.style.cssText="font-size:.72rem;margin-top:.2rem;",l.appendChild(c)}return l}function qe(e,t){const s=document.createElement("div");s.style.cssText="margin-top:.5rem; display:flex; flex-direction:column; gap:.4rem;";const n=ie("Layout");n.body.appendChild(S([U(`fb-chooser-variant-${t}`,"Variant",e.variant||"card",[["card","Card \u2014 rich tiles"],["chip","Chip \u2014 compact pills"]],"Card supports description and grid columns; chips wrap."),ce(`fb-chooser-multiple-${t}`,"Multi-select",!!e.multiple,"Off = single (radio); on = multi (checkbox).")])),n.body.appendChild(S([U(`fb-chooser-density-${t}`,"Density",e.density||"comfortable",[["comfortable","Comfortable"],["compact","Compact"]],"Compact strips description (card variant only)."),k("Columns",`fb-chooser-columns-${t}`,"number",e.columns||3,"Card grid (1\u20136). Ignored for chips.")])),s.appendChild(n.wrap);const o=ie("Visual");return o.body.appendChild(S([K(`fb-chooser-accent-${t}`,"Accent",e.accent||"","primary / success / #ec4899","Selected highlight colour \u2014 semantic name or any CSS colour."),U(`fb-chooser-accent-style-${t}`,"Accent style",e.accentStyle||"border",[["border","Border (default)"],["solid","Solid"],["glow","Glow"],["overlay","Overlay"],["underline","Underline"]],"Visual treatment of the selected state.")])),o.body.appendChild(S([ce(`fb-chooser-glow-${t}`,"Glow on selected",!!e.glow,"Soft outer glow."),K(`fb-chooser-glow-colour-${t}`,"Glow colour",e.glowColour||"","defaults to accent","Optional; semantic name or CSS colour.")])),o.body.appendChild(S([U(`fb-chooser-shadow-${t}`,"Shadow",e.shadow||"none",[["none","None"],["sm","Small"],["md","Medium"],["lg","Large"],["xl","Extra Large"]],"Drop shadow on every option."),K(`fb-chooser-shadow-colour-${t}`,"Shadow colour",e.shadowColour||"","rgba(0,0,0,0.1)","Optional shadow tint.")])),s.appendChild(o.wrap),s}function $e(e,t,s,n){const o=document.createElement("div");o.className="fb-chooser-option-row",o.dataset.optIdx=String(s),o.style.cssText="border:1px solid var(--dm-border,#e5e7eb); border-radius:4px; padding:.5rem; background:var(--dm-background-alt, color-mix(in srgb, var(--dm-card-bg, #fff) 92%, var(--dm-text, #111))); display:flex; flex-direction:column; gap:.35rem;";const l=document.createElement("div");l.style.cssText="display:flex; gap:.4rem; align-items:center;";const i=document.createElement("div");i.style.cssText="display:flex; flex-direction:column; gap:1px;";const p=document.createElement("button");p.type="button",p.className="btn btn-xs btn-ghost",p.title="Move up",w(p,"arrow-up"),p.addEventListener("click",N=>{N.preventDefault(),re(t,s,-1,n)});const r=document.createElement("button");r.type="button",r.className="btn btn-xs btn-ghost",r.title="Move down",w(r,"arrow-down"),r.addEventListener("click",N=>{N.preventDefault(),re(t,s,1,n)}),i.appendChild(p),i.appendChild(r),l.appendChild(i);const a=document.createElement("input");a.type="text",a.className="form-input fb-chooser-opt-value",a.placeholder="value",a.value=e.value||"",a.style.flex="1",l.appendChild(a);const d=document.createElement("input");d.type="text",d.className="form-input fb-chooser-opt-label",d.placeholder="label (visible to users)",d.value=e.label||"",d.style.flex="2",l.appendChild(d);const c=document.createElement("button");c.type="button",c.className="btn btn-xs btn-ghost",c.style.cssText="line-height:1;opacity:.6;",c.title="Remove option",w(c,"x"),c.addEventListener("click",N=>{N.preventDefault(),Ae(t,s,n)}),l.appendChild(c),o.appendChild(l);const u=document.createElement("div");u.style.cssText="display:flex; gap:.4rem;";const m=fe("icon name (optional)",e.icon||"");m.input.classList.add("fb-chooser-opt-icon"),m.el.style.flex="1",u.appendChild(m.el);const f=document.createElement("input");f.type="text",f.className="form-input fb-chooser-opt-description",f.placeholder="description (card + comfortable only)",f.value=e.description||"",f.style.flex="2",u.appendChild(f),o.appendChild(u);const y=document.createElement("div");y.style.cssText="display:flex; gap:.4rem;";const h=document.createElement("input");h.type="text",h.className="form-input fb-chooser-opt-tooltip",h.placeholder="tooltip (hover hint)",h.value=e.tooltip||"",h.style.flex="2",y.appendChild(h);const b=document.createElement("input");b.type="text",b.className="form-input fb-chooser-opt-badge-text",b.placeholder="badge text",b.value=e.badge?.text||"",b.style.flex="1",y.appendChild(b);const v=document.createElement("select");v.className="form-input fb-chooser-opt-badge-type",v.style.flex="1",[["","no badge"],["primary","primary"],["success","success"],["info","info"],["warning","warning"],["danger","danger"]].forEach(([N,O])=>{const j=document.createElement("option");j.value=N,j.textContent=O,(e.badge?.type||"")===N&&(j.selected=!0),v.appendChild(j)}),y.appendChild(v),o.appendChild(y);const C=document.createElement("div");C.style.cssText="display:flex; gap:1rem; font-size:.8rem;";const x=document.createElement("label");x.style.cssText="display:inline-flex;align-items:center;gap:.3rem;";const T=document.createElement("input");T.type="checkbox",T.className="fb-chooser-opt-recommended",T.checked=!!e.recommended,x.appendChild(T),x.appendChild(document.createTextNode(" Recommended")),C.appendChild(x);const z=document.createElement("label");z.style.cssText="display:inline-flex;align-items:center;gap:.3rem;";const B=document.createElement("input");return B.type="checkbox",B.className="fb-chooser-opt-disabled",B.checked=!!e.disabled,z.appendChild(B),z.appendChild(document.createTextNode(" Disabled")),C.appendChild(z),o.appendChild(C),o}function Le(e,t){const s=document.createElement("div");s.style.cssText="margin-top:.5rem;";const n=document.createElement("div");n.style.cssText="display:flex; align-items:center; justify-content:space-between; margin-bottom:.4rem;";const o=document.createElement("p");o.textContent="Options",o.style.cssText="font-size:.85rem;font-weight:600;margin:0;",n.appendChild(o);const l=document.createElement("button");l.type="button",l.className="btn btn-xs btn-ghost",D(l,"plus","Add option"),n.appendChild(l),s.appendChild(n);const i=document.createElement("div");i.className="fb-chooser-options-list",i.id=`fb-chooser-options-${t}`,i.style.cssText="display:flex; flex-direction:column; gap:.4rem;",s.appendChild(i);const p=()=>{i.replaceChildren();const r=ze(t);(r.length?r:e||[]).forEach((d,c)=>{i.appendChild($e(d,t,c,p))})};return l.addEventListener("click",r=>{r.preventDefault(),Be(t,p)}),p(),s}function ze(e){const t=g[e];return!t||!Array.isArray(t.options)?[]:t.options}function X(e){return g[e]?(Array.isArray(g[e].options)||(g[e].options=[]),g[e].options):[]}function Be(e,t){J(e),X(e).push({value:"new",label:"New option"}),t()}function Ae(e,t,s){J(e),X(e).splice(t,1),s()}function re(e,t,s,n){J(e);const o=X(e),l=t+s;if(l<0||l>=o.length)return;const[i]=o.splice(t,1);o.splice(l,0,i),n()}function J(e){const t=document.getElementById(`fb-chooser-options-${e}`);if(!t)return;const s=t.querySelectorAll(".fb-chooser-option-row"),n=[];s.forEach(o=>{const l={value:o.querySelector(".fb-chooser-opt-value")?.value.trim()||"",label:o.querySelector(".fb-chooser-opt-label")?.value.trim()||""},i=o.querySelector(".fb-chooser-opt-icon")?.value.trim();i&&(l.icon=i);const p=o.querySelector(".fb-chooser-opt-description")?.value.trim();p&&(l.description=p);const r=o.querySelector(".fb-chooser-opt-tooltip")?.value.trim();r&&(l.tooltip=r);const a=o.querySelector(".fb-chooser-opt-badge-text")?.value.trim(),d=o.querySelector(".fb-chooser-opt-badge-type")?.value;(a||d)&&(l.badge={},a&&(l.badge.text=a),d&&(l.badge.type=d)),o.querySelector(".fb-chooser-opt-recommended")?.checked&&(l.recommended=!0),o.querySelector(".fb-chooser-opt-disabled")?.checked&&(l.disabled=!0),n.push(l)}),g[e]&&(g[e].options=n)}function S(e){const t=document.createElement("div");return t.style.cssText="display:flex;gap:.85rem;margin-bottom:.75rem;",e.forEach(s=>{s&&t.appendChild(s)}),t}function k(e,t,s,n,o){const l=document.createElement("div");l.style.flex="1";const i=document.createElement("label");i.htmlFor=t,i.className="form-label",i.textContent=e,i.style.fontSize=".8rem";const p=document.createElement("input");if(p.id=t,p.type=s||"text",p.className="form-input",p.value=n??"",l.appendChild(i),l.appendChild(p),o){const r=document.createElement("p");r.className="form-hint text-muted",r.textContent=o,r.style.cssText="font-size:.73rem;margin-top:.2rem;",l.appendChild(r)}return l}function Ie(e,t,s,n){const o=document.createElement("div");o.style.flex="1";const l=document.createElement("label");l.htmlFor=t,l.className="form-label",l.textContent=e,l.style.fontSize=".8rem";const i=document.createElement("select");return i.id=t,i.className="form-select",s.forEach(p=>{const r=document.createElement("option");r.value=p.value,r.textContent=p.label,p.value===n&&(r.selected=!0),i.appendChild(r)}),o.appendChild(l),o.appendChild(i),o}function de(e,t,s){const n=document.createElement("div");n.style.cssText="flex:0;min-width:80px;display:flex;flex-direction:column;justify-content:flex-end;";const o=document.createElement("label");o.style.cssText="display:flex;align-items:center;gap:.4rem;cursor:pointer;font-size:.8rem;white-space:nowrap;";const l=document.createElement("input");return l.id=t,l.type="checkbox",l.checked=s,o.appendChild(l),o.appendChild(document.createTextNode(e)),n.appendChild(o),n}function Fe(e,t){const s=document.createElement("div");s.style.cssText="margin-top:.4rem;";const n=document.createElement("p");n.textContent="Options (one per line: value or value:Label)",n.style.cssText="font-size:.8rem;font-weight:600;margin-bottom:.3rem;";const o=document.createElement("textarea");return o.id=`fb-options-${t}`,o.className="form-input",o.rows=4,o.placeholder=`yes:Yes
5
+ `),t.appendChild(p),t.appendChild(c),t}function Ne(e,n){const s=e.logic||{},t=g.filter((c,u)=>u!==n&&c.type!=="page-break"&&c.type!=="spacer"),o=document.createElement("div");o.className="fb-field-logic",o.style.cssText="margin-top:.75rem;border-top:1px solid var(--dm-border,#333);padding-top:.5rem;";const l=document.createElement("div");l.style.cssText="display:flex;align-items:center;justify-content:space-between;cursor:pointer;padding:.15rem 0;";const i=document.createElement("span");i.style.cssText="font-size:.8rem;font-weight:600;color:var(--dm-text-muted,#888);",i.textContent="\u26A1 Conditional Logic";const d=le(s),r=document.createElement("button");r.type="button",r.className="btn btn-xs btn-ghost",w(r,d?"chevron-down":"chevron-right",12);const a=document.createElement("div");a.className="fb-logic-body",a.style.cssText="padding:.25rem 0 .25rem;"+(d?"":"display:none;"),l.addEventListener("click",()=>{const c=a.style.display==="none";a.style.display=c?"":"none",w(r,c?"chevron-down":"chevron-right",12)}),l.appendChild(i),l.appendChild(r),o.appendChild(l),a.appendChild(we(s.visibility||{},n,t)),a.appendChild(ke(s.requirement||{},n,t)),a.appendChild(Se(s.validation||[],n,t));const p=document.getElementById(`fb-type-${n}`)?.value||e.type;return W.has(p)&&a.appendChild(Te(s.cascade||{},n,t)),o.appendChild(a),o}function se(e,n,s){const t=document.createElement("div");return t.className="fb-field-extras",e==="chooser"?(t.appendChild(qe(n,s)),t.appendChild(Le(n.options||[],s))):(W.has(e)&&t.appendChild(Fe(n.options||[],s)),e==="textarea"&&t.appendChild(k([S("Rows",`fb-rows-${s}`,"number",n.formConfig?.rows||4,"Height of textarea")])),(e==="string"||e==="textarea")&&t.appendChild(k([S("Min Length",`fb-minlength-${s}`,"number",n.minLength||"",""),S("Max Length",`fb-maxlength-${s}`,"number",n.maxLength||"","")])),e==="number"&&t.appendChild(k([S("Min",`fb-min-${s}`,"number",n.min??"",""),S("Max",`fb-max-${s}`,"number",n.max??"","")]))),t.children.length?t:null}function ie(e){const n=document.createElement("div");n.className="fb-chooser-section",n.style.cssText="border:1px solid var(--dm-border, #e5e7eb); border-radius:6px; margin-top:.5rem; overflow:hidden;";const s=document.createElement("div");s.style.cssText="padding:.4rem .6rem; background:color-mix(in srgb, var(--dm-background, #f9fafb) 60%, transparent); font-weight:600; font-size:.82rem; border-bottom:1px solid var(--dm-border, #e5e7eb);",s.textContent=e,n.appendChild(s);const t=document.createElement("div");return t.className="fb-chooser-section-body",t.style.cssText="padding:.55rem .6rem; display:flex; flex-direction:column; gap:.45rem;",n.appendChild(t),{wrap:n,body:t}}function U(e,n,s,t,o){const l=document.createElement("div");l.style.flex="1";const i=document.createElement("label");i.htmlFor=e,i.className="form-label",i.textContent=n,i.style.fontSize=".8rem";const d=document.createElement("select");if(d.id=e,d.className="form-input",t.forEach(([r,a])=>{const p=document.createElement("option");p.value=r,p.textContent=a,String(r)===String(s)&&(p.selected=!0),d.appendChild(p)}),l.appendChild(i),l.appendChild(d),o){const r=document.createElement("p");r.className="form-hint text-muted",r.textContent=o,r.style.cssText="font-size:.72rem;margin-top:.2rem;",l.appendChild(r)}return l}function ce(e,n,s,t){const o=document.createElement("div");o.style.flex="1";const l=document.createElement("label");l.style.cssText="display:inline-flex;align-items:center;gap:.4rem;font-size:.82rem;";const i=document.createElement("input");if(i.id=e,i.type="checkbox",i.checked=!!s,l.appendChild(i),l.appendChild(document.createTextNode(" "+n)),o.appendChild(l),t){const d=document.createElement("p");d.className="form-hint text-muted",d.textContent=t,d.style.cssText="font-size:.72rem;margin-top:.2rem;",o.appendChild(d)}return o}function K(e,n,s,t,o){const l=document.createElement("div");l.style.flex="1";const i=document.createElement("label");i.htmlFor=e,i.className="form-label",i.textContent=n,i.style.fontSize=".8rem",l.appendChild(i);const d=document.createElement("div");d.style.cssText="display:flex;gap:.4rem;align-items:stretch;";const r=document.createElement("input");r.id=e,r.type="text",r.className="form-input",r.value=s||"",t&&(r.placeholder=t),r.style.flex="1";const a=document.createElement("input");a.type="color",a.title="Pick a colour",a.style.cssText="width:36px;height:auto;padding:0;border:1px solid var(--dm-border,#e5e7eb);border-radius:4px;cursor:pointer;";const p=String(r.value).match(/^#[0-9a-fA-F]{3,8}$/);if(a.value=p?r.value:"#000000",a.addEventListener("input",()=>{r.value=a.value,r.dispatchEvent(new Event("input",{bubbles:!0}))}),d.appendChild(r),d.appendChild(a),l.appendChild(d),o){const c=document.createElement("p");c.className="form-hint text-muted",c.textContent=o,c.style.cssText="font-size:.72rem;margin-top:.2rem;",l.appendChild(c)}return l}function qe(e,n){const s=document.createElement("div");s.style.cssText="margin-top:.5rem; display:flex; flex-direction:column; gap:.4rem;";const t=ie("Layout");t.body.appendChild(k([U(`fb-chooser-variant-${n}`,"Variant",e.variant||"card",[["card","Card \u2014 rich tiles"],["chip","Chip \u2014 compact pills"]],"Card supports description and grid columns; chips wrap."),ce(`fb-chooser-multiple-${n}`,"Multi-select",!!e.multiple,"Off = single (radio); on = multi (checkbox).")])),t.body.appendChild(k([U(`fb-chooser-density-${n}`,"Density",e.density||"comfortable",[["comfortable","Comfortable"],["compact","Compact"]],"Compact strips description (card variant only)."),S("Columns",`fb-chooser-columns-${n}`,"number",e.columns||3,"Card grid (1\u20136). Ignored for chips.")])),s.appendChild(t.wrap);const o=ie("Visual");return o.body.appendChild(k([K(`fb-chooser-accent-${n}`,"Accent",e.accent||"","primary / success / #ec4899","Selected highlight colour \u2014 semantic name or any CSS colour."),U(`fb-chooser-accent-style-${n}`,"Accent style",e.accentStyle||"border",[["border","Border (default)"],["solid","Solid"],["glow","Glow"],["overlay","Overlay"],["underline","Underline"]],"Visual treatment of the selected state.")])),o.body.appendChild(k([ce(`fb-chooser-glow-${n}`,"Glow on selected",!!e.glow,"Soft outer glow."),K(`fb-chooser-glow-colour-${n}`,"Glow colour",e.glowColour||"","defaults to accent","Optional; semantic name or CSS colour.")])),o.body.appendChild(k([U(`fb-chooser-shadow-${n}`,"Shadow",e.shadow||"none",[["none","None"],["sm","Small"],["md","Medium"],["lg","Large"],["xl","Extra Large"]],"Drop shadow on every option."),K(`fb-chooser-shadow-colour-${n}`,"Shadow colour",e.shadowColour||"","rgba(0,0,0,0.1)","Optional shadow tint.")])),s.appendChild(o.wrap),s}function $e(e,n,s,t){const o=document.createElement("div");o.className="fb-chooser-option-row",o.dataset.optIdx=String(s),o.style.cssText="border:1px solid var(--dm-border,#e5e7eb); border-radius:4px; padding:.5rem; background:var(--dm-background-alt, color-mix(in srgb, var(--dm-card-bg, #fff) 92%, var(--dm-text, #111))); display:flex; flex-direction:column; gap:.35rem;";const l=document.createElement("div");l.style.cssText="display:flex; gap:.4rem; align-items:center;";const i=document.createElement("div");i.style.cssText="display:flex; flex-direction:column; gap:1px;";const d=document.createElement("button");d.type="button",d.className="btn btn-xs btn-ghost",d.title="Move up",w(d,"arrow-up"),d.addEventListener("click",N=>{N.preventDefault(),re(n,s,-1,t)});const r=document.createElement("button");r.type="button",r.className="btn btn-xs btn-ghost",r.title="Move down",w(r,"arrow-down"),r.addEventListener("click",N=>{N.preventDefault(),re(n,s,1,t)}),i.appendChild(d),i.appendChild(r),l.appendChild(i);const a=document.createElement("input");a.type="text",a.className="form-input fb-chooser-opt-value",a.placeholder="value",a.value=e.value||"",a.style.flex="1",l.appendChild(a);const p=document.createElement("input");p.type="text",p.className="form-input fb-chooser-opt-label",p.placeholder="label (visible to users)",p.value=e.label||"",p.style.flex="2",l.appendChild(p);const c=document.createElement("button");c.type="button",c.className="btn btn-xs btn-ghost",c.style.cssText="line-height:1;opacity:.6;",c.title="Remove option",w(c,"x"),c.addEventListener("click",N=>{N.preventDefault(),Ae(n,s,t)}),l.appendChild(c),o.appendChild(l);const u=document.createElement("div");u.style.cssText="display:flex; gap:.4rem;";const m=fe("icon name (optional)",e.icon||"");m.input.classList.add("fb-chooser-opt-icon"),m.el.style.flex="1",u.appendChild(m.el);const f=document.createElement("input");f.type="text",f.className="form-input fb-chooser-opt-description",f.placeholder="description (card + comfortable only)",f.value=e.description||"",f.style.flex="2",u.appendChild(f),o.appendChild(u);const y=document.createElement("div");y.style.cssText="display:flex; gap:.4rem;";const h=document.createElement("input");h.type="text",h.className="form-input fb-chooser-opt-tooltip",h.placeholder="tooltip (hover hint)",h.value=e.tooltip||"",h.style.flex="2",y.appendChild(h);const b=document.createElement("input");b.type="text",b.className="form-input fb-chooser-opt-badge-text",b.placeholder="badge text",b.value=e.badge?.text||"",b.style.flex="1",y.appendChild(b);const v=document.createElement("select");v.className="form-input fb-chooser-opt-badge-type",v.style.flex="1",[["","no badge"],["primary","primary"],["success","success"],["info","info"],["warning","warning"],["danger","danger"]].forEach(([N,O])=>{const j=document.createElement("option");j.value=N,j.textContent=O,(e.badge?.type||"")===N&&(j.selected=!0),v.appendChild(j)}),y.appendChild(v),o.appendChild(y);const C=document.createElement("div");C.style.cssText="display:flex; gap:1rem; font-size:.8rem;";const x=document.createElement("label");x.style.cssText="display:inline-flex;align-items:center;gap:.3rem;";const T=document.createElement("input");T.type="checkbox",T.className="fb-chooser-opt-recommended",T.checked=!!e.recommended,x.appendChild(T),x.appendChild(document.createTextNode(" Recommended")),C.appendChild(x);const z=document.createElement("label");z.style.cssText="display:inline-flex;align-items:center;gap:.3rem;";const B=document.createElement("input");return B.type="checkbox",B.className="fb-chooser-opt-disabled",B.checked=!!e.disabled,z.appendChild(B),z.appendChild(document.createTextNode(" Disabled")),C.appendChild(z),o.appendChild(C),o}function Le(e,n){const s=document.createElement("div");s.style.cssText="margin-top:.5rem;";const t=document.createElement("div");t.style.cssText="display:flex; align-items:center; justify-content:space-between; margin-bottom:.4rem;";const o=document.createElement("p");o.textContent="Options",o.style.cssText="font-size:.85rem;font-weight:600;margin:0;",t.appendChild(o);const l=document.createElement("button");l.type="button",l.className="btn btn-xs btn-ghost",D(l,"plus","Add option"),t.appendChild(l),s.appendChild(t);const i=document.createElement("div");i.className="fb-chooser-options-list",i.id=`fb-chooser-options-${n}`,i.style.cssText="display:flex; flex-direction:column; gap:.4rem;",s.appendChild(i);const d=()=>{i.replaceChildren();const r=ze(n);(r.length?r:e||[]).forEach((p,c)=>{i.appendChild($e(p,n,c,d))})};return l.addEventListener("click",r=>{r.preventDefault(),Be(n,d)}),d(),s}function ze(e){const n=g[e];return!n||!Array.isArray(n.options)?[]:n.options}function X(e){return g[e]?(Array.isArray(g[e].options)||(g[e].options=[]),g[e].options):[]}function Be(e,n){J(e),X(e).push({value:"new",label:"New option"}),n()}function Ae(e,n,s){J(e),X(e).splice(n,1),s()}function re(e,n,s,t){J(e);const o=X(e),l=n+s;if(l<0||l>=o.length)return;const[i]=o.splice(n,1);o.splice(l,0,i),t()}function J(e){const n=document.getElementById(`fb-chooser-options-${e}`);if(!n)return;const s=n.querySelectorAll(".fb-chooser-option-row"),t=[];s.forEach(o=>{const l={value:o.querySelector(".fb-chooser-opt-value")?.value.trim()||"",label:o.querySelector(".fb-chooser-opt-label")?.value.trim()||""},i=o.querySelector(".fb-chooser-opt-icon")?.value.trim();i&&(l.icon=i);const d=o.querySelector(".fb-chooser-opt-description")?.value.trim();d&&(l.description=d);const r=o.querySelector(".fb-chooser-opt-tooltip")?.value.trim();r&&(l.tooltip=r);const a=o.querySelector(".fb-chooser-opt-badge-text")?.value.trim(),p=o.querySelector(".fb-chooser-opt-badge-type")?.value;(a||p)&&(l.badge={},a&&(l.badge.text=a),p&&(l.badge.type=p)),o.querySelector(".fb-chooser-opt-recommended")?.checked&&(l.recommended=!0),o.querySelector(".fb-chooser-opt-disabled")?.checked&&(l.disabled=!0),t.push(l)}),g[e]&&(g[e].options=t)}function k(e){const n=document.createElement("div");return n.style.cssText="display:flex;gap:.85rem;margin-bottom:.75rem;",e.forEach(s=>{s&&n.appendChild(s)}),n}function S(e,n,s,t,o){const l=document.createElement("div");l.style.flex="1";const i=document.createElement("label");i.htmlFor=n,i.className="form-label",i.textContent=e,i.style.fontSize=".8rem";const d=document.createElement("input");if(d.id=n,d.type=s||"text",d.className="form-input",d.value=t??"",l.appendChild(i),l.appendChild(d),o){const r=document.createElement("p");r.className="form-hint text-muted",r.textContent=o,r.style.cssText="font-size:.73rem;margin-top:.2rem;",l.appendChild(r)}return l}function Ie(e,n,s,t){const o=document.createElement("div");o.style.flex="1";const l=document.createElement("label");l.htmlFor=n,l.className="form-label",l.textContent=e,l.style.fontSize=".8rem";const i=document.createElement("select");return i.id=n,i.className="form-select",s.forEach(d=>{const r=document.createElement("option");r.value=d.value,r.textContent=d.label,d.value===t&&(r.selected=!0),i.appendChild(r)}),o.appendChild(l),o.appendChild(i),o}function de(e,n,s){const t=document.createElement("div");t.style.cssText="flex:0;min-width:80px;display:flex;flex-direction:column;justify-content:flex-end;";const o=document.createElement("label");o.style.cssText="display:flex;align-items:center;gap:.4rem;cursor:pointer;font-size:.8rem;white-space:nowrap;";const l=document.createElement("input");return l.id=n,l.type="checkbox",l.checked=s,o.appendChild(l),o.appendChild(document.createTextNode(e)),t.appendChild(o),t}function Fe(e,n){const s=document.createElement("div");s.style.cssText="margin-top:.4rem;";const t=document.createElement("p");t.textContent="Options (one per line: value or value:Label)",t.style.cssText="font-size:.8rem;font-weight:600;margin-bottom:.3rem;";const o=document.createElement("textarea");return o.id=`fb-options-${n}`,o.className="form-input",o.rows=4,o.placeholder=`yes:Yes
6
6
  no:No
7
- maybe:Maybe`,o.value=(e||[]).map(l=>{const i=typeof l=="string"?l:l.value??"",p=typeof l=="string"?l:l.label??i;return i===p?i:`${i}:${p}`}).join(`
8
- `),o.style.fontFamily="monospace",s.appendChild(n),s.appendChild(o),s}function pe(e){const t=e.find("#field-project").val()||"";return $(),{title:e.find("#field-title").val().trim(),slug:e.find("#field-slug").val().trim(),description:e.find("#field-description").val().trim(),...e.find("#field-bundled").is(":checked")?{bundled:!0}:{},meta:{...G||{},project:t||null},fields:g,settings:{submitText:e.find("#setting-submit-text").val().trim()||"Submit",successMessage:e.find("#setting-success-message").val().trim()||"Thank you.",layout:e.find("#setting-layout").val()||"stacked",columns:parseInt(e.find("#setting-columns").val(),10)||2,submitSpan:e.find("#setting-submit-span").val()||"",honeypot:e.find("#setting-honeypot").prop("checked"),rateLimitPerMinute:parseInt(e.find("#setting-rate-limit").val(),10)||3,successRedirect:e.find("#setting-success-redirect").val().trim()||null,actionSlug:e.find("#action-cms-slug").val()||null},actions:{email:{enabled:e.find("#action-email-enabled").prop("checked"),recipients:e.find("#action-email-recipients").val().trim(),subjectPrefix:e.find("#action-email-subject-prefix").val().trim()},webhook:{enabled:e.find("#action-webhook-enabled").prop("checked"),url:e.find("#action-webhook-url").val().trim(),method:e.find("#action-webhook-method").val()},...P!==null&&{collection:P}}}}function Oe(e){const t=[];let s=[],n="Step 1",o="";return e.forEach(l=>{l.type==="page-break"?(t.push({title:n,description:o,fields:s}),s=[],n=l.label||`Step ${t.length+1}`,o=l.description||""):l.type!=="spacer"&&s.push(l)}),(s.length||t.length===0)&&t.push({title:n,description:o,fields:s}),t}function me(e,t){const s={};return e.forEach(n=>{if(n.type==="page-break"||n.type==="spacer")return;const o={...n.formConfig||{}};o.span==="full"&&t&&(o.span=t);const i={type:n.type==="checkbox"?"boolean":n.type==="date"?"string":n.type,label:n.label,required:n.required,options:n.options,formConfig:{...n.placeholder&&{placeholder:n.placeholder},...n.helper&&{helperText:n.helper},...n.tooltip&&{tooltip:n.tooltip},...o}};n.type==="chooser"&&(n.variant&&(i.variant=n.variant),n.multiple&&(i.multiple=!0),n.density&&(i.density=n.density),n.columns&&(i.columns=n.columns),n.accent&&(i.accent=n.accent),n.accentStyle&&(i.accentStyle=n.accentStyle),n.glow&&(i.glow=!0),n.glowColour&&(i.glowColour=n.glowColour),n.shadow&&(i.shadow=n.shadow),n.shadowColour&&(i.shadowColour=n.shadowColour)),s[n.name]=i}),s}function ue(e,t){const s=typeof e=="string"?document.querySelector(e):e;s&&(t||[]).forEach(n=>{if(n.type!=="date"||!n.name)return;const o=s.querySelector(`[name="${n.name}"]`);o&&o.type!=="date"&&(o.type="date")})}export const formEditorView={templateUrl:"/admin/js/templates/form-editor.html",async onMount(e){g=[],q=null,P=null;const t=window.location.hash.match(/\/forms\/edit\/([^/?#]+)/);q=t?t[1]:null;let s=null;const n=E.loader(e.get(0),{type:"dots"});if(q)try{s=await I(`/forms/${q}`),g=s.fields||[],P=s.actions?.collection??null}catch{E.toast("Could not load form.",{type:"error"})}G={};try{const a=await I("/projects").catch(()=>[]),d=e.find("#field-project").get(0);d&&(Array.isArray(a)?a:[]).forEach(c=>{const u=document.createElement("option");u.value=c.slug,u.textContent=c.name||c.slug,d.appendChild(u)})}catch{}if(n.destroy(),s?e.find("#editor-title").get(0).textContent=`Edit: ${s.title}`:e.find("#editor-title").get(0).textContent="New Form",q||e.find("#field-title").get(0).addEventListener("input",function(){e.find("#field-slug").val(te(this.value))}),E.tabs(e.find("#editor-tabs").get(0)),s){e.find("#field-title").val(s.title),e.find("#field-slug").val(s.slug),e.find("#field-description").val(s.description||""),e.find("#field-bundled").prop("checked",!!s.bundled),G=s.meta||{},e.find("#field-project").val(s.meta?.project||"");const a=s.settings||{};e.find("#setting-submit-text").val(a.submitText||"Submit"),e.find("#setting-success-message").val(a.successMessage||""),e.find("#setting-layout").val(a.layout||"stacked"),e.find("#setting-columns").val(a.columns||2),e.find("#setting-submit-span").val(a.submitSpan||""),e.find("#columns-group").get(0).style.display=a.layout==="grid"?"":"none",e.find("#setting-honeypot").prop("checked",a.honeypot!==!1),e.find("#setting-rate-limit").val(a.rateLimitPerMinute||3),e.find("#setting-success-redirect").val(a.successRedirect||"");const d=s.actions?.email||{};e.find("#action-email-enabled").prop("checked",d.enabled||!1),e.find("#action-email-recipients").val(d.recipients||""),e.find("#action-email-subject-prefix").val(d.subjectPrefix||"");const c=s.actions?.webhook||{};e.find("#action-webhook-enabled").prop("checked",c.enabled||!1),e.find("#action-webhook-url").val(c.url||""),e.find("#action-webhook-method").val(c.method||"POST")}const o=s?.settings?.actionSlug||"";try{const a=await I("/actions").catch(()=>[]),d=e.find("#action-cms-slug").get(0);if((Array.isArray(a)?a:[]).forEach(c=>{const u=document.createElement("option");u.value=c.slug,u.textContent=c.title||c.slug,c.slug===o&&(u.selected=!0),d.appendChild(u)}),!a.length){const c=document.createElement("option");c.value="",c.textContent="No actions available",c.disabled=!0,d.appendChild(c)}}catch{}e.find("#setting-layout").get(0)?.addEventListener("change",function(){const a=this.value==="grid";e.find("#columns-group").get(0).style.display=a?"":"none",document.querySelectorAll(".fb-grid-row").forEach(d=>{d.style.display=a?"flex":"none"})}),L(e);const l=e.find("#add-element-menu").get(0);e.find("#add-element-btn").get(0).addEventListener("click",a=>{a.stopPropagation(),l.style.display=l.style.display==="none"?"":"none"}),M&&document.removeEventListener("click",M),M=()=>{l&&(l.style.display="none")},document.addEventListener("click",M),e.find("#add-field-btn").get(0).addEventListener("click",()=>{l&&(l.style.display="none"),$();const a=g.length;g.push({name:`field_${a+1}`,type:"string",label:"New Field",required:!1,placeholder:""}),L(e);const d=e.find("#fields-list").get(0)?.lastElementChild;if(d){const c=d.querySelector(".fb-field-body");c&&(c.style.display="")}}),e.find("#add-spacer-btn").get(0).addEventListener("click",()=>{l&&(l.style.display="none"),$(),g.push({type:"spacer"}),L(e)}),e.find("#add-page-break-btn").get(0).addEventListener("click",()=>{l&&(l.style.display="none"),$();const a=g.filter(d=>d.type==="page-break").length+2;g.push({type:"page-break",label:`Step ${a}`,description:""}),L(e)}),e.find("#save-form-btn").get(0).addEventListener("click",async()=>{const a=pe(e);if(!a.title){E.toast("Please enter a form title.",{type:"error"});return}try{q?(await I(`/forms/${q}`,{method:"PUT",body:JSON.stringify(a)}),E.toast("Form saved.",{type:"success"})):(q=(await I("/forms",{method:"POST",body:JSON.stringify(a)})).slug,R.navigate(`/forms/edit/${q}`),E.toast("Form created.",{type:"success"}))}catch(d){E.toast(d.message||"Failed to save form.",{type:"error"})}}),_=()=>{const a=pe(e),d=e.find("#preview-container").get(0);if(!d)return;const c=e.find("#preview-test-result").get(0),u=e.find("#preview-test-badge").get(0);c&&(c.style.display="none",c.textContent=""),u&&(u.style.display=q?"":"none"),e.find("#preview-card").get(0).style.display="",d.textContent="";const m=document.createElement("div");m.id="fb-preview-form",d.appendChild(m);const f=q?async h=>{c&&(c.style.display="none",c.textContent="");try{const b=await fetch(`/api/forms/submit/${q}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(h)}),v=await b.json();if(!b.ok)throw new Error(v.error||"Submission failed.");c&&(c.textContent=v.message||a.settings?.successMessage||"Submitted successfully.",c.style.cssText="display:block;margin-top:.75rem;padding:.6rem .9rem;border-radius:6px;font-size:.9rem;background:color-mix(in srgb, var(--dm-success) 12%, transparent);color:var(--dm-success,#22c55e);"),E.toast("Test submission stored.",{type:"success"})}catch(b){c&&(c.textContent=b.message,c.style.cssText="display:block;margin-top:.75rem;padding:.6rem .9rem;border-radius:6px;font-size:.9rem;background:color-mix(in srgb, var(--dm-danger) 12%, transparent);color:var(--dm-danger,#ef4444);"),E.toast(b.message,{type:"error"})}return!1}:()=>!1,y=a.fields.some(h=>h.type==="page-break");if(typeof F<"u"){const h=a.settings?.columns||2,b=a.settings?.layout||"stacked";if(y&&F.wizard){const v=Oe(a.fields).map(C=>({title:C.title,description:C.description,fields:me(C.fields,h)}));F.wizard("#fb-preview-form",{schema:{steps:v},onSubmit:f}),ue("#fb-preview-form",a.fields)}else if(F.render){const v=me(a.fields,h),C={};if(a.fields.forEach(x=>{if(!(!x.name||x.type==="page-break"||x.type==="spacer")&&(x.type==="select"||x.type==="multiselect")&&x.required){const T=(x.options||[])[0];T&&(C[x.name]=typeof T=="object"?T.value:T)}}),F.render("#fb-preview-form",v,C,{submitText:a.settings?.submitText||"Submit",layout:b,columns:h,onSubmit:f}),b==="grid"&&a.settings?.submitSpan==="full"){const x=document.querySelector("#fb-preview-form .form-buttons");x&&x.classList.add("col-span-full")}ue("#fb-preview-form",a.fields)}window.FormLogicEngine&&a.fields.some(v=>v.logic)&&requestAnimationFrame(()=>{new window.FormLogicEngine.FormLogicRuntime({fields:a.fields},m).init()})}else{const h=document.createElement("p");h.textContent=`${a.fields.filter(b=>b.type!=="page-break").length} field(s): ${a.fields.filter(b=>b.type!=="page-break").map(b=>b.label).join(", ")}`,h.style.cssText="color:var(--dm-text-muted);font-style:italic;",m.appendChild(h)}},_();const i=e.find("#editor-tabs").get(0),p=e.find("#preview-card").get(0),r=a=>{p&&p.contains(a.target)||Y()};i&&(i.addEventListener("input",r),i.addEventListener("change",r))}};
7
+ maybe:Maybe`,o.value=(e||[]).map(l=>{const i=typeof l=="string"?l:l.value??"",d=typeof l=="string"?l:l.label??i;return i===d?i:`${i}:${d}`}).join(`
8
+ `),o.style.fontFamily="monospace",s.appendChild(t),s.appendChild(o),s}function pe(e){const n=e.find("#field-project").val()||"";return $(),{title:e.find("#field-title").val().trim(),slug:e.find("#field-slug").val().trim(),description:e.find("#field-description").val().trim(),...e.find("#field-bundled").is(":checked")?{bundled:!0}:{},meta:{...G||{},project:n||null},fields:g,settings:{submitText:e.find("#setting-submit-text").val().trim()||"Submit",successMessage:e.find("#setting-success-message").val().trim()||"Thank you.",layout:e.find("#setting-layout").val()||"stacked",columns:parseInt(e.find("#setting-columns").val(),10)||2,submitSpan:e.find("#setting-submit-span").val()||"",honeypot:e.find("#setting-honeypot").prop("checked"),rateLimitPerMinute:parseInt(e.find("#setting-rate-limit").val(),10)||3,successRedirect:e.find("#setting-success-redirect").val().trim()||null,actionSlug:e.find("#action-cms-slug").val()||null},actions:{email:{enabled:e.find("#action-email-enabled").prop("checked"),recipients:e.find("#action-email-recipients").val().trim(),subjectPrefix:e.find("#action-email-subject-prefix").val().trim()},webhook:{enabled:e.find("#action-webhook-enabled").prop("checked"),url:e.find("#action-webhook-url").val().trim(),method:e.find("#action-webhook-method").val()},...P!==null&&{collection:P}}}}function Oe(e){const n=[];let s=[],t="Step 1",o="";return e.forEach(l=>{l.type==="page-break"?(n.push({title:t,description:o,fields:s}),s=[],t=l.label||`Step ${n.length+1}`,o=l.description||""):l.type!=="spacer"&&s.push(l)}),(s.length||n.length===0)&&n.push({title:t,description:o,fields:s}),n}function me(e,n){const s={};return e.forEach(t=>{if(t.type==="page-break"||t.type==="spacer")return;const o={...t.formConfig||{}};o.span==="full"&&n&&(o.span=n);const l=t.type==="chooser"||!!(t.variant&&["select","radio","checkbox-group"].includes(t.type)),d={type:t.type==="checkbox"?"boolean":t.type==="date"?"string":l?"chooser":t.type,label:t.label,required:t.required,options:t.options,formConfig:{...t.placeholder&&{placeholder:t.placeholder},...t.helper&&{helperText:t.helper},...t.tooltip&&{tooltip:t.tooltip},...o}};l&&(t.variant&&(d.variant=t.variant),(t.multiple||t.type==="checkbox-group")&&(d.multiple=!0),t.density&&(d.density=t.density),t.columns&&(d.columns=t.columns),t.accent&&(d.accent=t.accent),t.accentStyle&&(d.accentStyle=t.accentStyle),t.glow&&(d.glow=!0),t.glowColour&&(d.glowColour=t.glowColour),t.shadow&&(d.shadow=t.shadow),t.shadowColour&&(d.shadowColour=t.shadowColour)),s[t.name]=d}),s}function ue(e,n){const s=typeof e=="string"?document.querySelector(e):e;s&&(n||[]).forEach(t=>{if(t.type!=="date"||!t.name)return;const o=s.querySelector(`[name="${t.name}"]`);o&&o.type!=="date"&&(o.type="date")})}export const formEditorView={templateUrl:"/admin/js/templates/form-editor.html",async onMount(e){g=[],q=null,P=null;const n=window.location.hash.match(/\/forms\/edit\/([^/?#]+)/);q=n?n[1]:null;let s=null;const t=E.loader(e.get(0),{type:"dots"});if(q)try{s=await I(`/forms/${q}`),g=s.fields||[],P=s.actions?.collection??null}catch{E.toast("Could not load form.",{type:"error"})}G={};try{const a=await I("/projects").catch(()=>[]),p=e.find("#field-project").get(0);p&&(Array.isArray(a)?a:[]).forEach(c=>{const u=document.createElement("option");u.value=c.slug,u.textContent=c.name||c.slug,p.appendChild(u)})}catch{}if(t.destroy(),s?e.find("#editor-title").get(0).textContent=`Edit: ${s.title}`:e.find("#editor-title").get(0).textContent="New Form",q||e.find("#field-title").get(0).addEventListener("input",function(){e.find("#field-slug").val(te(this.value))}),E.tabs(e.find("#editor-tabs").get(0)),s){e.find("#field-title").val(s.title),e.find("#field-slug").val(s.slug),e.find("#field-description").val(s.description||""),e.find("#field-bundled").prop("checked",!!s.bundled),G=s.meta||{},e.find("#field-project").val(s.meta?.project||"");const a=s.settings||{};e.find("#setting-submit-text").val(a.submitText||"Submit"),e.find("#setting-success-message").val(a.successMessage||""),e.find("#setting-layout").val(a.layout||"stacked"),e.find("#setting-columns").val(a.columns||2),e.find("#setting-submit-span").val(a.submitSpan||""),e.find("#columns-group").get(0).style.display=a.layout==="grid"?"":"none",e.find("#setting-honeypot").prop("checked",a.honeypot!==!1),e.find("#setting-rate-limit").val(a.rateLimitPerMinute||3),e.find("#setting-success-redirect").val(a.successRedirect||"");const p=s.actions?.email||{};e.find("#action-email-enabled").prop("checked",p.enabled||!1),e.find("#action-email-recipients").val(p.recipients||""),e.find("#action-email-subject-prefix").val(p.subjectPrefix||"");const c=s.actions?.webhook||{};e.find("#action-webhook-enabled").prop("checked",c.enabled||!1),e.find("#action-webhook-url").val(c.url||""),e.find("#action-webhook-method").val(c.method||"POST")}const o=s?.settings?.actionSlug||"";try{const a=await I("/actions").catch(()=>[]),p=e.find("#action-cms-slug").get(0);if((Array.isArray(a)?a:[]).forEach(c=>{const u=document.createElement("option");u.value=c.slug,u.textContent=c.title||c.slug,c.slug===o&&(u.selected=!0),p.appendChild(u)}),!a.length){const c=document.createElement("option");c.value="",c.textContent="No actions available",c.disabled=!0,p.appendChild(c)}}catch{}e.find("#setting-layout").get(0)?.addEventListener("change",function(){const a=this.value==="grid";e.find("#columns-group").get(0).style.display=a?"":"none",document.querySelectorAll(".fb-grid-row").forEach(p=>{p.style.display=a?"flex":"none"})}),L(e);const l=e.find("#add-element-menu").get(0);e.find("#add-element-btn").get(0).addEventListener("click",a=>{a.stopPropagation(),l.style.display=l.style.display==="none"?"":"none"}),M&&document.removeEventListener("click",M),M=()=>{l&&(l.style.display="none")},document.addEventListener("click",M),e.find("#add-field-btn").get(0).addEventListener("click",()=>{l&&(l.style.display="none"),$();const a=g.length;g.push({name:`field_${a+1}`,type:"string",label:"New Field",required:!1,placeholder:""}),L(e);const p=e.find("#fields-list").get(0)?.lastElementChild;if(p){const c=p.querySelector(".fb-field-body");c&&(c.style.display="")}}),e.find("#add-spacer-btn").get(0).addEventListener("click",()=>{l&&(l.style.display="none"),$(),g.push({type:"spacer"}),L(e)}),e.find("#add-page-break-btn").get(0).addEventListener("click",()=>{l&&(l.style.display="none"),$();const a=g.filter(p=>p.type==="page-break").length+2;g.push({type:"page-break",label:`Step ${a}`,description:""}),L(e)}),e.find("#save-form-btn").get(0).addEventListener("click",async()=>{const a=pe(e);if(!a.title){E.toast("Please enter a form title.",{type:"error"});return}try{q?(await I(`/forms/${q}`,{method:"PUT",body:JSON.stringify(a)}),E.toast("Form saved.",{type:"success"})):(q=(await I("/forms",{method:"POST",body:JSON.stringify(a)})).slug,R.navigate(`/forms/edit/${q}`),E.toast("Form created.",{type:"success"}))}catch(p){E.toast(p.message||"Failed to save form.",{type:"error"})}}),_=()=>{const a=pe(e),p=e.find("#preview-container").get(0);if(!p)return;const c=e.find("#preview-test-result").get(0),u=e.find("#preview-test-badge").get(0);c&&(c.style.display="none",c.textContent=""),u&&(u.style.display=q?"":"none"),e.find("#preview-card").get(0).style.display="",p.textContent="";const m=document.createElement("div");m.id="fb-preview-form",p.appendChild(m);const f=q?async h=>{c&&(c.style.display="none",c.textContent="");try{const b=await fetch(`/api/forms/submit/${q}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(h)}),v=await b.json();if(!b.ok)throw new Error(v.error||"Submission failed.");c&&(c.textContent=v.message||a.settings?.successMessage||"Submitted successfully.",c.style.cssText="display:block;margin-top:.75rem;padding:.6rem .9rem;border-radius:6px;font-size:.9rem;background:color-mix(in srgb, var(--dm-success) 12%, transparent);color:var(--dm-success,#22c55e);"),E.toast("Test submission stored.",{type:"success"})}catch(b){c&&(c.textContent=b.message,c.style.cssText="display:block;margin-top:.75rem;padding:.6rem .9rem;border-radius:6px;font-size:.9rem;background:color-mix(in srgb, var(--dm-danger) 12%, transparent);color:var(--dm-danger,#ef4444);"),E.toast(b.message,{type:"error"})}return!1}:()=>!1,y=a.fields.some(h=>h.type==="page-break");if(typeof F<"u"){const h=a.settings?.columns||2,b=a.settings?.layout||"stacked";if(y&&F.wizard){const v=Oe(a.fields).map(C=>({title:C.title,description:C.description,fields:me(C.fields,h)}));F.wizard("#fb-preview-form",{schema:{steps:v},onSubmit:f}),ue("#fb-preview-form",a.fields)}else if(F.render){const v=me(a.fields,h),C={};if(a.fields.forEach(x=>{if(!(!x.name||x.type==="page-break"||x.type==="spacer")&&(x.type==="select"||x.type==="multiselect")&&x.required){const T=(x.options||[])[0];T&&(C[x.name]=typeof T=="object"?T.value:T)}}),F.render("#fb-preview-form",v,C,{submitText:a.settings?.submitText||"Submit",layout:b,columns:h,onSubmit:f}),b==="grid"&&a.settings?.submitSpan==="full"){const x=document.querySelector("#fb-preview-form .form-buttons");x&&x.classList.add("col-span-full")}ue("#fb-preview-form",a.fields)}window.FormLogicEngine&&a.fields.some(v=>v.logic)&&requestAnimationFrame(()=>{new window.FormLogicEngine.FormLogicRuntime({fields:a.fields},m).init()})}else{const h=document.createElement("p");h.textContent=`${a.fields.filter(b=>b.type!=="page-break").length} field(s): ${a.fields.filter(b=>b.type!=="page-break").map(b=>b.label).join(", ")}`,h.style.cssText="color:var(--dm-text-muted);font-style:italic;",m.appendChild(h)}},_();const i=e.find("#editor-tabs").get(0),d=e.find("#preview-card").get(0),r=a=>{d&&d.contains(a.target)||Y()};i&&(i.addEventListener("input",r),i.addEventListener("change",r))}};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "0.36.6",
3
+ "version": "0.36.7",
4
4
  "description": "File-based CMS powered by Domma and Fastify. Run npx domma-cms my-site to create a new project.",
5
5
  "type": "module",
6
6
  "main": "server/server.js",
@@ -1 +1 @@
1
- const targets=document.querySelectorAll("[data-form]");targets.length&&targets.forEach(initFormTarget);function showMessage(a,s,t){const e=a.querySelector(".fb-form-success, .fb-form-error");e&&e.remove();const m=document.createElement("div");m.className=t==="success"?"fb-form-success":"fb-form-error",m.textContent=s,a.appendChild(m)}function attachRuntimeLifecycle(a,s){if(a._formLogicRuntime=s,!a.parentNode||typeof MutationObserver>"u")return;const t=new MutationObserver(function(e){for(const m of e)for(const n of m.removedNodes)if(n===a||n.nodeType===1&&n.contains&&n.contains(a)){s.destroy(),t.disconnect();return}});t.observe(a.parentNode,{childList:!0,subtree:!1})}function buildBlueprintFromFields(a,s){const t={};return a.forEach(function(e){if(e.type==="page-break"||e.type==="spacer"||!e.name)return;const m=e.type==="checkbox"?"boolean":e.type==="date"?"string":e.type,n={...e.formConfig||{}};n.span==="full"&&s&&(n.span=s);const r={type:m,label:e.label||e.name,required:e.required||!1,options:e.options,formConfig:{...e.placeholder&&{placeholder:e.placeholder},...e.helper&&{helperText:e.helper},...e.tooltip&&{tooltip:e.tooltip},...n}};e.minLength!==void 0&&(r.minLength=e.minLength),e.maxLength!==void 0&&(r.maxLength=e.maxLength),e.min!==void 0&&(r.min=e.min),e.max!==void 0&&(r.max=e.max),e.type==="chooser"&&(e.variant&&(r.variant=e.variant),e.multiple&&(r.multiple=!0),e.density&&(r.density=e.density),e.columns&&(r.columns=e.columns),e.accent&&(r.accent=e.accent),e.accentStyle&&(r.accentStyle=e.accentStyle),e.glow&&(r.glow=!0),e.glowColour&&(r.glowColour=e.glowColour),e.shadow&&(r.shadow=e.shadow),e.shadowColour&&(r.shadowColour=e.shadowColour)),t[e.name]=r}),t}function buildInitialData(a){const s={};return a.forEach(function(t){if(!(!t.name||t.type==="page-break"||t.type==="spacer")&&(t.type==="select"||t.type==="multiselect")&&t.required){const e=(t.options||[])[0];e&&(s[t.name]=typeof e=="object"?e.value:e)}}),s}function patchDateInputs(a,s){(s||[]).forEach(function(t){if(t.type!=="date"||!t.name)return;const e=a.querySelector('[name="'+t.name+'"]');e&&e.type!=="date"&&(e.type="date")})}function buildWizardSteps(a,s){const t=[];let e=[],m=s||"Step 1",n="";return a.forEach(function(r){r.type==="page-break"?(t.push({title:m,description:n,fieldGroup:e}),e=[],m=r.label||"Step "+(t.length+1),n=r.description||""):r.type!=="spacer"&&e.push(r)}),t.push({title:m,description:n,fieldGroup:e}),t}function injectHoneypot(a){const s=document.createElement("div");s.className="fb-form-honeypot",s.setAttribute("aria-hidden","true");const t=document.createElement("input");t.name="website",t.type="text",t.tabIndex=-1,t.autocomplete="url",t.placeholder="https://",s.appendChild(t);const e=document.createElement("input");e.name="_t",e.type="hidden",e.value=Date.now(),s.appendChild(e),a.appendChild(s)}function injectSpacers(a,s){const t=a.querySelector("form");if(!t)return;const e=Array.from(t.querySelectorAll(".form-group"));let m=0;s.forEach(function(n){if(n.type==="spacer"){const r=document.createElement("div");r.className="fb-spacer";const c=e[m];if(c)t.insertBefore(r,c);else{const l=t.querySelector('[type="submit"]');l?t.insertBefore(r,l):t.appendChild(r)}}else n.type!=="page-break"&&m++})}function submitForm(a,s,t,e,m){const n=m||e,r=n.querySelector('[name="website"]')?.value||"",c=n.querySelector('[name="_t"]')?.value||"",l=n?Array.from(n.querySelectorAll('input[type="file"]')):[],p=l.some(i=>i.files&&i.files.length>0);let u,o;if(p){const i=new FormData;for(const[h,f]of Object.entries(s||{}))f!=null&&(l.some(d=>d.name===h)||i.append(h,typeof f=="object"?JSON.stringify(f):String(f)));for(const h of l)for(const f of h.files)i.append(h.name,f,f.name);i.append("_hp",r),i.append("_t",c),u=i,o={}}else{const i=Object.assign({},s,{_hp:r,_t:c});u=JSON.stringify(i),o={"Content-Type":"application/json"}}return fetch("/api/forms/submit/"+a,{method:"POST",headers:o,body:u}).then(i=>i.json().then(h=>({ok:i.ok,body:h}))).then(i=>{i.ok&&i.body.ok?(e.textContent="",showMessage(e,i.body.message||t.successMessage||"Thank you.","success")):showMessage(e,i.body.error||"Something went wrong.","error")}).catch(()=>{showMessage(e,"Unable to submit. Please check your connection.","error")})}function renderManualForm(a,s,t,e,m){const n=document.createElement("form");n.noValidate=!0,s.forEach(function(c){const l=document.createElement("div");l.className="form-group",l.style.marginBottom="1.25rem";const p=document.createElement("label");if(p.className="form-label",p.textContent=c.label||c.name,c.required){const o=document.createElement("span");o.textContent=" *",o.style.color="#f87171",p.appendChild(o)}let u;c.type==="textarea"?(u=document.createElement("textarea"),u.rows=c.formConfig?.rows||4,u.className="form-input"):c.type==="select"?(u=document.createElement("select"),u.className="form-input",(c.options||[]).forEach(function(o){const i=document.createElement("option");i.value=typeof o=="string"?o:o.value??"",i.textContent=typeof o=="string"?o:o.label||i.value,u.appendChild(i)})):(u=document.createElement("input"),u.type=c.type||"text",u.className="form-input",c.placeholder&&(u.placeholder=c.placeholder),c.type==="file"&&(c.file?.accept&&(u.accept=c.file.accept),c.multiple&&(u.multiple=!0))),u.name=c.name,u.required=c.required||!1,l.appendChild(p),l.appendChild(u),n.appendChild(l)}),t.honeypot&&injectHoneypot(n);const r=document.createElement("button");r.type="submit",r.className="btn btn-primary",r.textContent=t.submitText||"Submit",n.appendChild(r),n.addEventListener("submit",function(c){c.preventDefault();const l={};if(s.forEach(function(p){const u=n.querySelector('[name="'+p.name+'"]');u&&(l[p.name]=u.value)}),window.FormLogicEngine&&m){const p=window.FormLogicEngine,u=[],o=[];if(s.forEach(function(i){if(p.evaluateFieldVisibility(i,l)==="hidden"){delete l[i.name];return}const f=p.evaluateFieldRequirement(i,l),d=l[i.name];f&&(!d||!String(d).trim())&&u.push(i.label||i.name);const y=p.validateField(i,d||"",l);y.length&&o.push(y[0].message)}),u.length||o.length){const i=[];u.length&&i.push("Required: "+u.join(", ")),o.length&&i.push(o.join("; ")),showMessage(a,i.join(". "),"error");return}}a.classList.add("fb-form-loading"),r.disabled=!0,submitForm(e,l,t,a,n).finally(function(){a.classList.remove("fb-form-loading"),r.disabled=!1})}),a.appendChild(n),window.FormLogicEngine&&m&&s.some(c=>c.logic)&&new window.FormLogicEngine.FormLogicRuntime(m,a).init()}function initFormTarget(a){const s=a.getAttribute("data-form");s&&fetch("/api/forms/"+s+"/public").then(t=>{if(!t.ok)throw new Error("Form not found: "+s);return t.json()}).then(t=>{const e=t.fields||[],m=t.settings||{},n=document.createElement("div");n.className="fb-form-wrapper",a.appendChild(n);const r=e.some(c=>c.type==="page-break");if(typeof Domma<"u"&&Domma.forms){const c=m.columns||1;if(r&&Domma.forms.wizard){const p=buildWizardSteps(e,t.title).map(function(o){return{title:o.title,description:o.description,fields:buildBlueprintFromFields(o.fieldGroup,c)}}),u=Domma.forms.wizard(n,{schema:{steps:p},onSubmit:function(o){return submitForm(s,o,m,n,null)}});Promise.resolve(u).then(function(){if(patchDateInputs(n,e),window.FormLogicEngine&&e.some(o=>o.logic)){const o=new window.FormLogicEngine.FormLogicRuntime(t,n);o.init(),attachRuntimeLifecycle(n,o)}if(m.honeypot){const o=n.querySelector("form");o&&injectHoneypot(o)}})}else if(Domma.forms.render){const l=buildBlueprintFromFields(e,c),p=buildInitialData(e),u=Domma.forms.render(n,l,p,{submitText:m.submitText||"Submit",layout:m.layout||"stacked",columns:c,onSubmit:function(o){return submitForm(s,o,m,n,null)}});Promise.resolve(u).then(function(){if(patchDateInputs(n,e),window.FormLogicEngine&&e.some(o=>o.logic)){const o=new window.FormLogicEngine.FormLogicRuntime(t,n);o.init(),attachRuntimeLifecycle(n,o)}if(e.some(o=>o.type==="spacer")&&injectSpacers(n,e),m.honeypot){const o=n.querySelector("form");o&&injectHoneypot(o)}})}}else renderManualForm(n,e.filter(c=>c.type!=="page-break"&&c.type!=="spacer"),m,s,t)}).catch(t=>{const e=document.createElement("p");e.textContent="Form unavailable.",e.style.cssText="color:#f87171;font-style:italic;",a.appendChild(e),console.warn("[forms]",t.message)})}
1
+ const targets=document.querySelectorAll("[data-form]");targets.length&&targets.forEach(initFormTarget);function showMessage(a,s,t){const e=a.querySelector(".fb-form-success, .fb-form-error");e&&e.remove();const u=document.createElement("div");u.className=t==="success"?"fb-form-success":"fb-form-error",u.textContent=s,a.appendChild(u)}function attachRuntimeLifecycle(a,s){if(a._formLogicRuntime=s,!a.parentNode||typeof MutationObserver>"u")return;const t=new MutationObserver(function(e){for(const u of e)for(const r of u.removedNodes)if(r===a||r.nodeType===1&&r.contains&&r.contains(a)){s.destroy(),t.disconnect();return}});t.observe(a.parentNode,{childList:!0,subtree:!1})}function buildBlueprintFromFields(a,s){const t={};return a.forEach(function(e){if(e.type==="page-break"||e.type==="spacer"||!e.name)return;const u=e.type==="chooser"||!!(e.variant&&["select","radio","checkbox-group"].includes(e.type)),r=e.type==="checkbox"?"boolean":e.type==="date"?"string":u?"chooser":e.type,m={...e.formConfig||{}};m.span==="full"&&s&&(m.span=s);const n={type:r,label:e.label||e.name,required:e.required||!1,options:e.options,formConfig:{...e.placeholder&&{placeholder:e.placeholder},...e.helper&&{helperText:e.helper},...e.tooltip&&{tooltip:e.tooltip},...m}};e.minLength!==void 0&&(n.minLength=e.minLength),e.maxLength!==void 0&&(n.maxLength=e.maxLength),e.min!==void 0&&(n.min=e.min),e.max!==void 0&&(n.max=e.max),u&&(e.variant&&(n.variant=e.variant),(e.multiple||e.type==="checkbox-group")&&(n.multiple=!0),e.density&&(n.density=e.density),e.columns&&(n.columns=e.columns),e.accent&&(n.accent=e.accent),e.accentStyle&&(n.accentStyle=e.accentStyle),e.glow&&(n.glow=!0),e.glowColour&&(n.glowColour=e.glowColour),e.shadow&&(n.shadow=e.shadow),e.shadowColour&&(n.shadowColour=e.shadowColour)),t[e.name]=n}),t}function buildInitialData(a){const s={};return a.forEach(function(t){if(!(!t.name||t.type==="page-break"||t.type==="spacer")&&(t.type==="select"||t.type==="multiselect")&&t.required){const e=(t.options||[])[0];e&&(s[t.name]=typeof e=="object"?e.value:e)}}),s}function patchDateInputs(a,s){(s||[]).forEach(function(t){if(t.type!=="date"||!t.name)return;const e=a.querySelector('[name="'+t.name+'"]');e&&e.type!=="date"&&(e.type="date")})}function buildWizardSteps(a,s){const t=[];let e=[],u=s||"Step 1",r="";return a.forEach(function(m){m.type==="page-break"?(t.push({title:u,description:r,fieldGroup:e}),e=[],u=m.label||"Step "+(t.length+1),r=m.description||""):m.type!=="spacer"&&e.push(m)}),t.push({title:u,description:r,fieldGroup:e}),t}function injectHoneypot(a){const s=document.createElement("div");s.className="fb-form-honeypot",s.setAttribute("aria-hidden","true");const t=document.createElement("input");t.name="website",t.type="text",t.tabIndex=-1,t.autocomplete="url",t.placeholder="https://",s.appendChild(t);const e=document.createElement("input");e.name="_t",e.type="hidden",e.value=Date.now(),s.appendChild(e),a.appendChild(s)}function injectSpacers(a,s){const t=a.querySelector("form");if(!t)return;const e=Array.from(t.querySelectorAll(".form-group"));let u=0;s.forEach(function(r){if(r.type==="spacer"){const m=document.createElement("div");m.className="fb-spacer";const n=e[u];if(n)t.insertBefore(m,n);else{const l=t.querySelector('[type="submit"]');l?t.insertBefore(m,l):t.appendChild(m)}}else r.type!=="page-break"&&u++})}function submitForm(a,s,t,e,u){const r=u||e,m=r.querySelector('[name="website"]')?.value||"",n=r.querySelector('[name="_t"]')?.value||"",l=r?Array.from(r.querySelectorAll('input[type="file"]')):[],p=l.some(c=>c.files&&c.files.length>0);let i,o;if(p){const c=new FormData;for(const[h,f]of Object.entries(s||{}))f!=null&&(l.some(d=>d.name===h)||c.append(h,typeof f=="object"?JSON.stringify(f):String(f)));for(const h of l)for(const f of h.files)c.append(h.name,f,f.name);c.append("_hp",m),c.append("_t",n),i=c,o={}}else{const c=Object.assign({},s,{_hp:m,_t:n});i=JSON.stringify(c),o={"Content-Type":"application/json"}}return fetch("/api/forms/submit/"+a,{method:"POST",headers:o,body:i}).then(c=>c.json().then(h=>({ok:c.ok,body:h}))).then(c=>{c.ok&&c.body.ok?(e.textContent="",showMessage(e,c.body.message||t.successMessage||"Thank you.","success")):showMessage(e,c.body.error||"Something went wrong.","error")}).catch(()=>{showMessage(e,"Unable to submit. Please check your connection.","error")})}function renderManualForm(a,s,t,e,u){const r=document.createElement("form");r.noValidate=!0,s.forEach(function(n){const l=document.createElement("div");l.className="form-group",l.style.marginBottom="1.25rem";const p=document.createElement("label");if(p.className="form-label",p.textContent=n.label||n.name,n.required){const o=document.createElement("span");o.textContent=" *",o.style.color="#f87171",p.appendChild(o)}let i;n.type==="textarea"?(i=document.createElement("textarea"),i.rows=n.formConfig?.rows||4,i.className="form-input"):n.type==="select"?(i=document.createElement("select"),i.className="form-input",(n.options||[]).forEach(function(o){const c=document.createElement("option");c.value=typeof o=="string"?o:o.value??"",c.textContent=typeof o=="string"?o:o.label||c.value,i.appendChild(c)})):(i=document.createElement("input"),i.type=n.type||"text",i.className="form-input",n.placeholder&&(i.placeholder=n.placeholder),n.type==="file"&&(n.file?.accept&&(i.accept=n.file.accept),n.multiple&&(i.multiple=!0))),i.name=n.name,i.required=n.required||!1,l.appendChild(p),l.appendChild(i),r.appendChild(l)}),t.honeypot&&injectHoneypot(r);const m=document.createElement("button");m.type="submit",m.className="btn btn-primary",m.textContent=t.submitText||"Submit",r.appendChild(m),r.addEventListener("submit",function(n){n.preventDefault();const l={};if(s.forEach(function(p){const i=r.querySelector('[name="'+p.name+'"]');i&&(l[p.name]=i.value)}),window.FormLogicEngine&&u){const p=window.FormLogicEngine,i=[],o=[];if(s.forEach(function(c){if(p.evaluateFieldVisibility(c,l)==="hidden"){delete l[c.name];return}const f=p.evaluateFieldRequirement(c,l),d=l[c.name];f&&(!d||!String(d).trim())&&i.push(c.label||c.name);const y=p.validateField(c,d||"",l);y.length&&o.push(y[0].message)}),i.length||o.length){const c=[];i.length&&c.push("Required: "+i.join(", ")),o.length&&c.push(o.join("; ")),showMessage(a,c.join(". "),"error");return}}a.classList.add("fb-form-loading"),m.disabled=!0,submitForm(e,l,t,a,r).finally(function(){a.classList.remove("fb-form-loading"),m.disabled=!1})}),a.appendChild(r),window.FormLogicEngine&&u&&s.some(n=>n.logic)&&new window.FormLogicEngine.FormLogicRuntime(u,a).init()}function initFormTarget(a){const s=a.getAttribute("data-form");s&&fetch("/api/forms/"+s+"/public").then(t=>{if(!t.ok)throw new Error("Form not found: "+s);return t.json()}).then(t=>{const e=t.fields||[],u=t.settings||{},r=document.createElement("div");r.className="fb-form-wrapper",a.appendChild(r);const m=e.some(n=>n.type==="page-break");if(typeof Domma<"u"&&Domma.forms){const n=u.columns||1;if(m&&Domma.forms.wizard){const p=buildWizardSteps(e,t.title).map(function(o){return{title:o.title,description:o.description,fields:buildBlueprintFromFields(o.fieldGroup,n)}}),i=Domma.forms.wizard(r,{schema:{steps:p},onSubmit:function(o){return submitForm(s,o,u,r,null)}});Promise.resolve(i).then(function(){if(patchDateInputs(r,e),window.FormLogicEngine&&e.some(o=>o.logic)){const o=new window.FormLogicEngine.FormLogicRuntime(t,r);o.init(),attachRuntimeLifecycle(r,o)}if(u.honeypot){const o=r.querySelector("form");o&&injectHoneypot(o)}})}else if(Domma.forms.render){const l=buildBlueprintFromFields(e,n),p=buildInitialData(e),i=Domma.forms.render(r,l,p,{submitText:u.submitText||"Submit",layout:u.layout||"stacked",columns:n,onSubmit:function(o){return submitForm(s,o,u,r,null)}});Promise.resolve(i).then(function(){if(patchDateInputs(r,e),window.FormLogicEngine&&e.some(o=>o.logic)){const o=new window.FormLogicEngine.FormLogicRuntime(t,r);o.init(),attachRuntimeLifecycle(r,o)}if(e.some(o=>o.type==="spacer")&&injectSpacers(r,e),u.honeypot){const o=r.querySelector("form");o&&injectHoneypot(o)}})}}else renderManualForm(r,e.filter(n=>n.type!=="page-break"&&n.type!=="spacer"),u,s,t)}).catch(t=>{const e=document.createElement("p");e.textContent="Form unavailable.",e.style.cssText="color:#f87171;font-style:italic;",a.appendChild(e),console.warn("[forms]",t.message)})}
package/public/js/site.js CHANGED
@@ -1 +1 @@
1
- import{makeBadgeEl as _,applyColour as A,applyPill as D}from"/public/js/menu-decor.mjs";$(()=>{const C=window.__CMS_NAV__||{},g=window.__CMS_SITE__||{};if(g.autoTheme?.enabled){let o=function(e){const f=(e||"07:00").split(":");return+f[0]*60+(+f[1]||0)},a=function(){const e=new Date,f=e.getHours()*60+e.getMinutes();return f>=o(t.dayStart)&&f<o(t.nightStart)?t.dayTheme:t.nightTheme};const t=g.autoTheme;Domma.theme.set(a()),setInterval(()=>Domma.theme.set(a()),6e4)}const b=$("#site-navbar");if(b.length&&C.brand){let a=function(i,n=0){return Array.isArray(i)?i.filter(c=>!(c&&c.type==="separator"&&n===0)).map(c=>c&&c.type==="separator"?{divider:!0}:Array.isArray(c?.items)?{...c,items:a(c.items,n+1)}:c):i},e=function(i){return Array.isArray(i)?i.filter(n=>!(n&&n.type==="separator")):[]};const t={...C.brand},o=t.size&&t.size!=="md"?` navbar-brand-${t.size}`:"";if(t.logo||t.icon||t.tagline){let i="";t.logo?i+=`<img src="${t.logo}" class="navbar-brand-logo" alt="${t.text||""}">`:t.icon&&(i+=`<span data-icon="${t.icon}" style="width:1.1em;height:1.1em;margin-right:.35em;vertical-align:middle;"></span>`),t.text&&(i+=`<span class="navbar-brand-text${o}">${t.text}</span>`),t.tagline&&(i+=`<small class="navbar-brand-tagline">${t.tagline}</small>`),t.html=i}else o&&t.text&&(t.html=`<span class="navbar-brand-text${o}">${t.text}</span>`);Domma.elements.navbar("#site-navbar",{brand:t,items:a(C.items||[]),variant:C.variant||"dark",position:C.position||"sticky",collapsible:!0}),Domma.icons.scan("#site-navbar");const f=b.get(0);if(C.appearOnHover){const i=window.matchMedia("(min-width: 993px)");f.querySelectorAll(".navbar-dropdown").forEach(n=>{n.addEventListener("mouseenter",()=>{i.matches&&n.classList.add("open")}),n.addEventListener("mouseleave",()=>{i.matches&&n.classList.remove("open")})})}const d=f.querySelector(".navbar-toggle"),l=f.querySelector(".navbar-collapse");if(d&&l){let i=null;const n=()=>{l.classList.contains("show")&&d.click()},c=()=>{i&&(i.remove(),i=null),document.body.classList.remove("dm-drawer-open")},s=()=>{i||(i=document.createElement("div"),i.className="dm-navbar-backdrop",i.addEventListener("click",n),document.body.appendChild(i),document.body.classList.add("dm-drawer-open"))};d.addEventListener("click",()=>{requestAnimationFrame(()=>{l.classList.contains("show")?s():c()})}),l.addEventListener("click",u=>{u.target.closest("a")&&requestAnimationFrame(c)}),document.addEventListener("keydown",u=>{u.key==="Escape"&&l.classList.contains("show")&&n()})}const y=e(C.items||[]);f.querySelectorAll(".navbar-link[data-index], .navbar-dropdown-item[data-index]").forEach(i=>{const n=y[parseInt(i.dataset.index,10)];if(!n)return;const c=i.dataset.subindex!=null,s=c&&Array.isArray(n.items)?n.items[parseInt(i.dataset.subindex,10)]:n;if(!s)return;s.colour&&A(i,s.colour),s.pill&&!c&&D(i,s.pill);const u=_(s.badge);u&&i.appendChild(u)})}const v=$("#site-footer");if(v.length){let f=function(r){return String(r??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")},d=function(r){return f(r).replace(/'/g,"&#39;")},l=function(r){if(r&&r.type==="separator")return'<li class="footer-sep"><hr></li>';const m=d(r.url||"#"),h=f(r.text||""),k=Array.isArray(r.items)&&r.items.length?`<ul>${r.items.map(l).join("")}</ul>`:"";return`<li><a href="${m}">${h}</a>${k}</li>`},y=function(r,m){return(r||[]).forEach(h=>{h&&h.type==="separator"||(m.push(h),Array.isArray(h.items)&&h.items.length&&y(h.items,m))}),m};const t=g.social||{},o={twitter:{label:"X / Twitter",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.742l7.73-8.835L1.254 2.25H8.08l4.259 5.629L18.244 2.25zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>'},facebook:{label:"Facebook",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>'},instagram:{label:"Instagram",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z"/></svg>'},linkedin:{label:"LinkedIn",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>'},github:{label:"GitHub",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>'},youtube:{label:"YouTube",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z"/></svg>'}};let a='<div class="footer-inner container">';const e=window.__CMS_FOOTER__||{primary:[],legal:[],copyright:""};if(e.copyright&&(a+=`<p>${f(e.copyright)}</p>`),e.primary.length&&(a+=`<nav class="footer-nav footer-nav--primary"><ul>${e.primary.map(l).join("")}</ul></nav>`),e.legal.length&&(a+=`<nav class="footer-nav footer-nav--legal"><ul>${e.legal.map(l).join("")}</ul></nav>`),g.footer){const r=Object.keys(o).filter(m=>t[m]);r.length&&(a+='<div class="footer-social">',r.forEach(m=>{const{label:h,svg:k}=o[m];a+=`<a href="${t[m]}" target="_blank" rel="noopener noreferrer" aria-label="${h}" class="footer-social-link">${k}</a>`}),a+="</div>")}a+="</div>",v.html(a);const i=[...y(e.primary,[]),...y(e.legal,[])];v.get(0).querySelectorAll(".footer-nav a").forEach((r,m)=>{const h=i[m];if(!h)return;h.colour&&A(r,h.colour);const k=_(h.badge);k&&r.appendChild(k)});const c=S.get("reduced_motion"),s=c!==null?!!c:!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches),u=v.get(0).querySelector(".footer-inner");if(u){const r=document.createElement("input");r.type="checkbox",r.className="form-switch-input",r.id="dm-motion-switch",r.checked=s,r.addEventListener("change",function(){S.set("reduced_motion",this.checked),window.location.reload()});const m=document.createElement("span");m.className="form-switch-label",m.textContent="Reduce motion";const h=document.createElement("label");h.className="form-switch footer-motion-switch",h.title="Reduce motion",h.appendChild(r),h.appendChild(m),u.appendChild(h)}}$("#site-sidebar").length&&Domma.elements.sidebar("#site-sidebar",{autoGenerate:!0,selector:"h2, h3",collapsible:!1,push:!0,contentSelector:".site-content"}),Domma.icons.scan(),Domma.syntax?.scan&&Domma.syntax.scan();const p=$(".page-body");if(p.length){p.find(".accordion").each(function(){Domma.elements.accordion(this,{allowMultiple:this.dataset.multi==="true"})}),p.find(".tabs").each(function(){Domma.elements.tabs(this)}),p.find(".carousel").each(function(){const t={autoplay:this.dataset.autoplay==="true",interval:parseInt(this.dataset.interval,10)||5e3,loop:this.dataset.loop!=="false",animation:this.dataset.animation||"slide"};if(this.dataset.animationDuration){const o=parseInt(this.dataset.animationDuration,10);Number.isFinite(o)&&(t.animationDuration=o)}this.dataset.animationEasing&&(t.animationEasing=this.dataset.animationEasing),Domma.elements.carousel(this,t)}),p.find(".dm-countdown").each(function(){const t={autoStart:!0};this.dataset.to&&(t.targetDate=new Date(this.dataset.to)),this.dataset.duration&&(t.duration=parseInt(this.dataset.duration,10)),this.dataset.format&&(t.format=this.dataset.format),Domma.elements.timer(this,t)}),p.find("[data-tooltip]").each(function(){Domma.elements.tooltip(this,{content:$(this).data("tooltip"),position:$(this).data("tooltip-position")||"top"})}),p.find(".dm-progression").each(function(){Domma.elements.progression(this,{layout:this.dataset.layout||"vertical",theme:this.dataset.theme||"minimal",mode:this.dataset.mode||"timeline",statusIcons:!0})});try{Domma.effects.reveal(".page-body .hero",{animation:"slide-up",duration:480,threshold:.06,stagger:60,once:!1})}catch{}document.querySelectorAll(".page-body .row[data-reveal]").forEach(t=>{const o=t.dataset.revealMode||"stagger",a=t.dataset.revealAnimation||"slide-up",e=parseInt(t.dataset.revealDuration,10)||400,f=parseInt(t.dataset.revealStagger,10)||60,d=parseInt(t.dataset.revealDelay,10)||0,l=t.dataset.revealDirection==="rtl",y=Array.from(t.children),i={"slide-up":"translateY(30px)","slide-down":"translateY(-30px)","slide-left":"translateX(30px)","slide-right":"translateX(-30px)",zoom:"scale(0.85)",flip:"perspective(600px) rotateX(15deg)"};y.forEach((n,c)=>{n.style.opacity="0",n.style.transform=i[a]||"",n.style.transition=`opacity ${e}ms ease, transform ${e}ms ease`;const s=l?y.length-1-c:c;n.style.transitionDelay=o==="stagger"?`${d+s*f}ms`:`${d}ms`}),requestAnimationFrame(()=>requestAnimationFrame(()=>{const n=new IntersectionObserver(c=>{c.forEach(s=>{s.isIntersecting&&(s.target.offsetWidth,s.target.style.opacity="1",s.target.style.transform="none",n.unobserve(s.target))})},{threshold:.1});y.forEach(c=>n.observe(c))}))}),p.find(".card[data-collapsible]").each(function(){const t=this.querySelector(".card-header");t&&t.addEventListener("click",()=>this.classList.toggle("is-collapsed"))}),p.find(".dm-so-trigger").each(function(){this.addEventListener("click",()=>{const t=this.dataset.soTarget,o=document.getElementById(t);if(!o)return;const a=E.slideover({title:o.dataset.soTitle||"",size:o.dataset.soSize||"md",position:o.dataset.soPosition||"right"});o.style.display="",a.setContent(o),a.open()})})}if(typeof $.setup=="function"){const t=Object.assign({},window.__CMS_DCONFIG__||{});if(document.querySelectorAll(".dm-page-config[data-config]").forEach(o=>{try{const a=atob(o.dataset.config),e=JSON.parse(a);Object.assign(t,e)}catch{}}),Object.keys(t).length>0){const o={};for(const[a,e]of Object.entries(t)){const f=e?.events?.click,{confirm:d,toast:l,alert:y,prompt:i,...n}=f||{};d||l||y||i?($(a).on("click",async function(s){if(s.preventDefault(),d&&!await E.confirm(d))return;let u=null;if(!(i&&(u=await E.prompt(i,{inputPlaceholder:n.promptPlaceholder||"",inputValue:n.promptDefault||""}),u===null))){if(n.target){const r=$(n.target);n.toggleClass&&r.toggleClass(n.toggleClass),n.addClass&&r.addClass(n.addClass),n.removeClass&&r.removeClass(n.removeClass),u!==null&&(n.setText&&r.text(u),n.setVal&&r.val(u),n.setAttr&&r.attr(n.setAttr,u))}n.href&&(window.location.href=n.href),l&&E.toast(l,{type:n.toastType||"success"}),y&&E.alert(y)}}),Object.keys(n).length&&(o[a]={...e,events:{...e.events,click:n}})):o[a]=e}$.setup(o)}}p.length&&x(p.get(0))});function x(C){C.querySelectorAll(".dm-cta-trigger").forEach(g=>{g.__ctaWired||(g.__ctaWired=!0,g.addEventListener("click",async()=>{const b=g.dataset.action,v=g.dataset.entry,w=g.dataset.confirm;let p=S.get("auth_token");if(!p){E.toast("Please log in to perform this action.",{type:"warning"});return}if(w&&!await E.confirm(w))return;const t=Array.from(g.childNodes).map(a=>a.cloneNode(!0));g.disabled=!0,g.textContent="Running\u2026";const o=a=>fetch(`/api/actions/${b}/public`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},body:JSON.stringify({entryId:v})});try{let a=await o(p);if(a.status===401){const f=S.get("auth_refresh_token");if(f){const d=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:f})});if(d.ok){const{token:l}=await d.json();S.set("auth_token",l),p=l,a=await o(p)}}}const e=await a.json().catch(()=>({}));if(!a.ok)throw new Error(e.error||e.message||`Error ${a.status}`);E.toast(e.message||"Action completed.",{type:"success"})}catch(a){E.toast(a.message||"Action failed.",{type:"error"})}finally{g.disabled=!1,g.textContent="",t.forEach(a=>g.appendChild(a)),Domma.icons.scan(g)}}))})}(function(){const g=document.querySelectorAll('.dm-collection-hydrate[data-collection-scope="mine"]');if(!g.length)return;const b=S.get("auth_token");function v(p,t){const o=document.createElement("div");o.className="dm-collection-display dm-collection-empty";const a=document.createElement("p");if(t){a.appendChild(document.createTextNode("Please "));const e=document.createElement("a");e.href="/login",e.textContent="sign in",a.appendChild(e),a.appendChild(document.createTextNode(" to view your entries."))}else a.textContent=p;return o.appendChild(a),o}function w(p,t){const o=document.createElement("template");o.innerHTML=t||"",p.replaceWith(o.content)}g.forEach(async p=>{const t=p.dataset.collectionAttrs;if(!t)return;if(!b){p.replaceChildren(v("",!0));return}const o=a=>fetch("/api/collections/render-scope",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},body:JSON.stringify({attrs:t})});try{let a=b,e=await o(a);if(e.status===401){const d=S.get("auth_refresh_token");if(d){const l=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:d})});if(l.ok){const{token:y}=await l.json();S.set("auth_token",y),a=y,e=await o(a)}}}if(!e.ok){const{error:d}=await e.json().catch(()=>({}));p.replaceChildren(v(d||"Unable to load entries.",!1));return}const{html:f}=await e.json();w(p,f)}catch{p.replaceChildren(v("Unable to load entries.",!1))}}),setTimeout(()=>{typeof Domma<"u"&&Domma.icons?.scan&&Domma.icons.scan(),typeof Domma<"u"&&Domma.syntax?.scan&&Domma.syntax.scan(),x(document.body)},100)})(),(function(){const g=document.querySelectorAll("[data-collection-table]");!g.length||typeof T>"u"||!T.create||g.forEach(b=>{let v;try{v=JSON.parse(atob(b.dataset.payload))}catch{return}const{columns:w,rows:p,search:t,sortable:o,exportable:a,pageSize:e,empty:f,ctaConfig:d}=v;if(!w?.length)return;if(d){const i=w.findIndex(n=>n.key==="_cta");i!==-1&&(w[i]={key:"_cta",title:"",render:(n,c)=>{const s=document.createElement("button");if(s.className=`btn btn-${d.style||"primary"} dm-cta-trigger`,s.dataset.action=d.action||"",s.dataset.entry=c._entryId||"",d.confirm&&(s.dataset.confirm=d.confirm),d.icon){const u=document.createElement("span");u.dataset.icon=d.icon,s.appendChild(u),s.appendChild(document.createTextNode(" "))}return s.appendChild(document.createTextNode(d.label||"Run")),s}})}const l="col-table-"+Math.random().toString(36).slice(2,7),y=document.createElement("div");y.id=l,b.replaceChildren(y),T.create("#"+l,{data:p,columns:w,search:t,sortable:o,exportable:a,pageSize:e,emptyMessage:f}),d&&x(y)})})(),(function(){const g=document.querySelectorAll("[data-form-inline]");if(!g.length||typeof F>"u")return;function b(t,o){const a={};return(t||[]).forEach(e=>{if(e.type==="page-break"||e.type==="spacer"||!e.name)return;const f=e.type==="checkbox"?"boolean":e.type==="date"?"string":e.type,d={...e.formConfig||{}};d.span==="full"&&o&&(d.span=o);const l={type:f,label:e.label,required:e.required,options:e.options,formConfig:{...e.placeholder&&{placeholder:e.placeholder},...e.helper&&{hint:e.helper},...d}};e.type==="chooser"&&(e.variant&&(l.variant=e.variant),e.multiple&&(l.multiple=!0),e.density&&(l.density=e.density),e.columns&&(l.columns=e.columns),e.accent&&(l.accent=e.accent),e.accentStyle&&(l.accentStyle=e.accentStyle),e.glow&&(l.glow=!0),e.glowColour&&(l.glowColour=e.glowColour),e.shadow&&(l.shadow=e.shadow),e.shadowColour&&(l.shadowColour=e.shadowColour)),a[e.name]=l}),a}function v(t){const o={};return(t||[]).forEach(a=>{if(!(!a.name||a.type==="page-break"||a.type==="spacer")&&(a.type==="select"||a.type==="multiselect")&&a.required){const e=(a.options||[])[0];e&&(o[a.name]=typeof e=="object"?e.value:e)}}),o}function w(t,o){(o||[]).forEach(a=>{if(a.type!=="date"||!a.name)return;const e=t.querySelector(`[name="${a.name}"]`);e&&e.type!=="date"&&(e.type="date")})}function p(t,o,a){let e=t.querySelector(".cms-form-message");e||(e=document.createElement("p"),e.className="cms-form-message",t.appendChild(e)),e.textContent=o,e.style.cssText=a?"color:var(--dm-danger,#f87171);margin-top:.75rem;":"color:var(--dm-success,#4ade80);margin-top:.75rem;"}g.forEach(t=>{let o;try{o=JSON.parse(atob(t.dataset.formInline))}catch{return}const a=o.fields||[],e=o.settings||{},f=e.columns||1,d=e.layout||"stacked",l=a.some(c=>c.type==="page-break"),y=async c=>{try{const s=t.querySelector('[name="website"]'),u=t.querySelector('[name="_t"]'),r=Object.assign({},c);s!==null&&(r._hp=s.value),u!==null&&(r._t=u.value);const m=await H.post(`/api/forms/submit/${o.slug}`,r);if(m&&m.error){p(t,m.error,!0);const h=new Error(m.error);throw h.formSubmitFailed=!0,h}if(m?.redirect){window.location.href=m.redirect;return}for(;t.firstChild;)t.removeChild(t.firstChild);p(t,m?.message||e.successMessage||"Thank you for your submission.",!1)}catch(s){throw s.formSubmitFailed||p(t,s.message||"Submission failed. Please try again.",!0),s}};function i(c){const s=c.querySelector("form");if(!s)return;const u=document.createElement("div");u.className="fb-form-honeypot",u.setAttribute("aria-hidden","true");const r=document.createElement("input");r.name="website",r.type="text",r.tabIndex=-1,r.autocomplete="url",r.placeholder="https://",u.appendChild(r);const m=document.createElement("input");m.name="_t",m.type="hidden",m.value=Date.now(),u.appendChild(m),s.appendChild(u)}function n(){if(!window.FormLogicEngine||!a.some(s=>s.logic))return;const c=new window.FormLogicEngine.FormLogicRuntime(o,t);if(c.init(),t._formLogicRuntime=c,t.parentNode&&typeof MutationObserver<"u"){const s=new MutationObserver(function(u){for(const r of u)for(const m of r.removedNodes)if(m===t||m.nodeType===1&&m.contains&&m.contains(t)){c.destroy(),s.disconnect();return}});s.observe(t.parentNode,{childList:!0,subtree:!1})}}if(l&&F.wizard){const c=[];let s=[],u=o.title||"Step 1",r="";a.forEach(h=>{h.type==="page-break"?(c.push({title:u,description:r,fields:b(s,f)}),s=[],u=h.label||`Step ${c.length+1}`,r=h.description||""):h.type!=="spacer"&&s.push(h)}),c.push({title:u,description:r,fields:b(s,f)});const m=F.wizard(t,{schema:{steps:c},onSubmit:y});Promise.resolve(m).then(function(){w(t,a),e.honeypot!==!1&&i(t),n()})}else if(F.render){const c=F.render(t,b(a,f),v(a),{submitText:e.submitText||"Submit",layout:d,columns:f,onSubmit:y});Promise.resolve(c).then(function(){if(d==="grid"&&e.submitSpan==="full"){const s=t.querySelector(".form-buttons");s&&s.classList.add("col-span-full")}w(t,a),e.honeypot!==!1&&i(t),n()})}}),$(document).on("click",".dm-banner__dismiss",function(){$(this).closest(".dm-banner").remove()})})();
1
+ import{makeBadgeEl as _,applyColour as A,applyPill as D}from"/public/js/menu-decor.mjs";$(()=>{const C=window.__CMS_NAV__||{},y=window.__CMS_SITE__||{};if(y.autoTheme?.enabled){let o=function(e){const p=(e||"07:00").split(":");return+p[0]*60+(+p[1]||0)},a=function(){const e=new Date,p=e.getHours()*60+e.getMinutes();return p>=o(t.dayStart)&&p<o(t.nightStart)?t.dayTheme:t.nightTheme};const t=y.autoTheme;Domma.theme.set(a()),setInterval(()=>Domma.theme.set(a()),6e4)}const b=$("#site-navbar");if(b.length&&C.brand){let a=function(i,n=0){return Array.isArray(i)?i.filter(c=>!(c&&c.type==="separator"&&n===0)).map(c=>c&&c.type==="separator"?{divider:!0}:Array.isArray(c?.items)?{...c,items:a(c.items,n+1)}:c):i},e=function(i){return Array.isArray(i)?i.filter(n=>!(n&&n.type==="separator")):[]};const t={...C.brand},o=t.size&&t.size!=="md"?` navbar-brand-${t.size}`:"";if(t.logo||t.icon||t.tagline){let i="";t.logo?i+=`<img src="${t.logo}" class="navbar-brand-logo" alt="${t.text||""}">`:t.icon&&(i+=`<span data-icon="${t.icon}" style="width:1.1em;height:1.1em;margin-right:.35em;vertical-align:middle;"></span>`),t.text&&(i+=`<span class="navbar-brand-text${o}">${t.text}</span>`),t.tagline&&(i+=`<small class="navbar-brand-tagline">${t.tagline}</small>`),t.html=i}else o&&t.text&&(t.html=`<span class="navbar-brand-text${o}">${t.text}</span>`);Domma.elements.navbar("#site-navbar",{brand:t,items:a(C.items||[]),variant:C.variant||"dark",position:C.position||"sticky",collapsible:!0}),Domma.icons.scan("#site-navbar");const p=b.get(0);if(C.appearOnHover){const i=window.matchMedia("(min-width: 993px)");p.querySelectorAll(".navbar-dropdown").forEach(n=>{n.addEventListener("mouseenter",()=>{i.matches&&n.classList.add("open")}),n.addEventListener("mouseleave",()=>{i.matches&&n.classList.remove("open")})})}const d=p.querySelector(".navbar-toggle"),h=p.querySelector(".navbar-collapse");if(d&&h){let i=null;const n=()=>{h.classList.contains("show")&&d.click()},c=()=>{i&&(i.remove(),i=null),document.body.classList.remove("dm-drawer-open")},s=()=>{i||(i=document.createElement("div"),i.className="dm-navbar-backdrop",i.addEventListener("click",n),document.body.appendChild(i),document.body.classList.add("dm-drawer-open"))};d.addEventListener("click",()=>{requestAnimationFrame(()=>{h.classList.contains("show")?s():c()})}),h.addEventListener("click",u=>{u.target.closest("a")&&requestAnimationFrame(c)}),document.addEventListener("keydown",u=>{u.key==="Escape"&&h.classList.contains("show")&&n()})}const m=e(C.items||[]);p.querySelectorAll(".navbar-link[data-index], .navbar-dropdown-item[data-index]").forEach(i=>{const n=m[parseInt(i.dataset.index,10)];if(!n)return;const c=i.dataset.subindex!=null,s=c&&Array.isArray(n.items)?n.items[parseInt(i.dataset.subindex,10)]:n;if(!s)return;s.colour&&A(i,s.colour),s.pill&&!c&&D(i,s.pill);const u=_(s.badge);u&&i.appendChild(u)})}const v=$("#site-footer");if(v.length){let p=function(r){return String(r??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")},d=function(r){return p(r).replace(/'/g,"&#39;")},h=function(r){if(r&&r.type==="separator")return'<li class="footer-sep"><hr></li>';const l=d(r.url||"#"),g=p(r.text||""),k=Array.isArray(r.items)&&r.items.length?`<ul>${r.items.map(h).join("")}</ul>`:"";return`<li><a href="${l}">${g}</a>${k}</li>`},m=function(r,l){return(r||[]).forEach(g=>{g&&g.type==="separator"||(l.push(g),Array.isArray(g.items)&&g.items.length&&m(g.items,l))}),l};const t=y.social||{},o={twitter:{label:"X / Twitter",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-4.714-6.231-5.401 6.231H2.742l7.73-8.835L1.254 2.25H8.08l4.259 5.629L18.244 2.25zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>'},facebook:{label:"Facebook",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>'},instagram:{label:"Instagram",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z"/></svg>'},linkedin:{label:"LinkedIn",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>'},github:{label:"GitHub",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>'},youtube:{label:"YouTube",svg:'<svg viewBox="0 0 24 24" fill="currentColor"><path d="M23.495 6.205a3.007 3.007 0 00-2.088-2.088c-1.87-.501-9.396-.501-9.396-.501s-7.507-.01-9.396.501A3.007 3.007 0 00.527 6.205a31.247 31.247 0 00-.522 5.805 31.247 31.247 0 00.522 5.783 3.007 3.007 0 002.088 2.088c1.868.502 9.396.502 9.396.502s7.506 0 9.396-.502a3.007 3.007 0 002.088-2.088 31.247 31.247 0 00.5-5.783 31.247 31.247 0 00-.5-5.805zM9.609 15.601V8.408l6.264 3.602z"/></svg>'}};let a='<div class="footer-inner container">';const e=window.__CMS_FOOTER__||{primary:[],legal:[],copyright:""};if(e.copyright&&(a+=`<p>${p(e.copyright)}</p>`),e.primary.length&&(a+=`<nav class="footer-nav footer-nav--primary"><ul>${e.primary.map(h).join("")}</ul></nav>`),e.legal.length&&(a+=`<nav class="footer-nav footer-nav--legal"><ul>${e.legal.map(h).join("")}</ul></nav>`),y.footer){const r=Object.keys(o).filter(l=>t[l]);r.length&&(a+='<div class="footer-social">',r.forEach(l=>{const{label:g,svg:k}=o[l];a+=`<a href="${t[l]}" target="_blank" rel="noopener noreferrer" aria-label="${g}" class="footer-social-link">${k}</a>`}),a+="</div>")}a+="</div>",v.html(a);const i=[...m(e.primary,[]),...m(e.legal,[])];v.get(0).querySelectorAll(".footer-nav a").forEach((r,l)=>{const g=i[l];if(!g)return;g.colour&&A(r,g.colour);const k=_(g.badge);k&&r.appendChild(k)});const c=S.get("reduced_motion"),s=c!==null?!!c:!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches),u=v.get(0).querySelector(".footer-inner");if(u){const r=document.createElement("input");r.type="checkbox",r.className="form-switch-input",r.id="dm-motion-switch",r.checked=s,r.addEventListener("change",function(){S.set("reduced_motion",this.checked),window.location.reload()});const l=document.createElement("span");l.className="form-switch-label",l.textContent="Reduce motion";const g=document.createElement("label");g.className="form-switch footer-motion-switch",g.title="Reduce motion",g.appendChild(r),g.appendChild(l),u.appendChild(g)}}$("#site-sidebar").length&&Domma.elements.sidebar("#site-sidebar",{autoGenerate:!0,selector:"h2, h3",collapsible:!1,push:!0,contentSelector:".site-content"}),Domma.icons.scan(),Domma.syntax?.scan&&Domma.syntax.scan();const f=$(".page-body");if(f.length){f.find(".accordion").each(function(){Domma.elements.accordion(this,{allowMultiple:this.dataset.multi==="true"})}),f.find(".tabs").each(function(){Domma.elements.tabs(this)}),f.find(".carousel").each(function(){const t={autoplay:this.dataset.autoplay==="true",interval:parseInt(this.dataset.interval,10)||5e3,loop:this.dataset.loop!=="false",animation:this.dataset.animation||"slide"};if(this.dataset.animationDuration){const o=parseInt(this.dataset.animationDuration,10);Number.isFinite(o)&&(t.animationDuration=o)}this.dataset.animationEasing&&(t.animationEasing=this.dataset.animationEasing),Domma.elements.carousel(this,t)}),f.find(".dm-countdown").each(function(){const t={autoStart:!0};this.dataset.to&&(t.targetDate=new Date(this.dataset.to)),this.dataset.duration&&(t.duration=parseInt(this.dataset.duration,10)),this.dataset.format&&(t.format=this.dataset.format),Domma.elements.timer(this,t)}),f.find("[data-tooltip]").each(function(){Domma.elements.tooltip(this,{content:$(this).data("tooltip"),position:$(this).data("tooltip-position")||"top"})}),f.find(".dm-progression").each(function(){Domma.elements.progression(this,{layout:this.dataset.layout||"vertical",theme:this.dataset.theme||"minimal",mode:this.dataset.mode||"timeline",statusIcons:!0})});try{Domma.effects.reveal(".page-body .hero",{animation:"slide-up",duration:480,threshold:.06,stagger:60,once:!1})}catch{}document.querySelectorAll(".page-body .row[data-reveal]").forEach(t=>{const o=t.dataset.revealMode||"stagger",a=t.dataset.revealAnimation||"slide-up",e=parseInt(t.dataset.revealDuration,10)||400,p=parseInt(t.dataset.revealStagger,10)||60,d=parseInt(t.dataset.revealDelay,10)||0,h=t.dataset.revealDirection==="rtl",m=Array.from(t.children),i={"slide-up":"translateY(30px)","slide-down":"translateY(-30px)","slide-left":"translateX(30px)","slide-right":"translateX(-30px)",zoom:"scale(0.85)",flip:"perspective(600px) rotateX(15deg)"};m.forEach((n,c)=>{n.style.opacity="0",n.style.transform=i[a]||"",n.style.transition=`opacity ${e}ms ease, transform ${e}ms ease`;const s=h?m.length-1-c:c;n.style.transitionDelay=o==="stagger"?`${d+s*p}ms`:`${d}ms`}),requestAnimationFrame(()=>requestAnimationFrame(()=>{const n=new IntersectionObserver(c=>{c.forEach(s=>{s.isIntersecting&&(s.target.offsetWidth,s.target.style.opacity="1",s.target.style.transform="none",n.unobserve(s.target))})},{threshold:.1});m.forEach(c=>n.observe(c))}))}),f.find(".card[data-collapsible]").each(function(){const t=this.querySelector(".card-header");t&&t.addEventListener("click",()=>this.classList.toggle("is-collapsed"))}),f.find(".dm-so-trigger").each(function(){this.addEventListener("click",()=>{const t=this.dataset.soTarget,o=document.getElementById(t);if(!o)return;const a=E.slideover({title:o.dataset.soTitle||"",size:o.dataset.soSize||"md",position:o.dataset.soPosition||"right"});o.style.display="",a.setContent(o),a.open()})})}if(typeof $.setup=="function"){const t=Object.assign({},window.__CMS_DCONFIG__||{});if(document.querySelectorAll(".dm-page-config[data-config]").forEach(o=>{try{const a=atob(o.dataset.config),e=JSON.parse(a);Object.assign(t,e)}catch{}}),Object.keys(t).length>0){const o={};for(const[a,e]of Object.entries(t)){const p=e?.events?.click,{confirm:d,toast:h,alert:m,prompt:i,...n}=p||{};d||h||m||i?($(a).on("click",async function(s){if(s.preventDefault(),d&&!await E.confirm(d))return;let u=null;if(!(i&&(u=await E.prompt(i,{inputPlaceholder:n.promptPlaceholder||"",inputValue:n.promptDefault||""}),u===null))){if(n.target){const r=$(n.target);n.toggleClass&&r.toggleClass(n.toggleClass),n.addClass&&r.addClass(n.addClass),n.removeClass&&r.removeClass(n.removeClass),u!==null&&(n.setText&&r.text(u),n.setVal&&r.val(u),n.setAttr&&r.attr(n.setAttr,u))}n.href&&(window.location.href=n.href),h&&E.toast(h,{type:n.toastType||"success"}),m&&E.alert(m)}}),Object.keys(n).length&&(o[a]={...e,events:{...e.events,click:n}})):o[a]=e}$.setup(o)}}f.length&&x(f.get(0))});function x(C){C.querySelectorAll(".dm-cta-trigger").forEach(y=>{y.__ctaWired||(y.__ctaWired=!0,y.addEventListener("click",async()=>{const b=y.dataset.action,v=y.dataset.entry,w=y.dataset.confirm;let f=S.get("auth_token");if(!f){E.toast("Please log in to perform this action.",{type:"warning"});return}if(w&&!await E.confirm(w))return;const t=Array.from(y.childNodes).map(a=>a.cloneNode(!0));y.disabled=!0,y.textContent="Running\u2026";const o=a=>fetch(`/api/actions/${b}/public`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},body:JSON.stringify({entryId:v})});try{let a=await o(f);if(a.status===401){const p=S.get("auth_refresh_token");if(p){const d=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:p})});if(d.ok){const{token:h}=await d.json();S.set("auth_token",h),f=h,a=await o(f)}}}const e=await a.json().catch(()=>({}));if(!a.ok)throw new Error(e.error||e.message||`Error ${a.status}`);E.toast(e.message||"Action completed.",{type:"success"})}catch(a){E.toast(a.message||"Action failed.",{type:"error"})}finally{y.disabled=!1,y.textContent="",t.forEach(a=>y.appendChild(a)),Domma.icons.scan(y)}}))})}(function(){const y=document.querySelectorAll('.dm-collection-hydrate[data-collection-scope="mine"]');if(!y.length)return;const b=S.get("auth_token");function v(f,t){const o=document.createElement("div");o.className="dm-collection-display dm-collection-empty";const a=document.createElement("p");if(t){a.appendChild(document.createTextNode("Please "));const e=document.createElement("a");e.href="/login",e.textContent="sign in",a.appendChild(e),a.appendChild(document.createTextNode(" to view your entries."))}else a.textContent=f;return o.appendChild(a),o}function w(f,t){const o=document.createElement("template");o.innerHTML=t||"",f.replaceWith(o.content)}y.forEach(async f=>{const t=f.dataset.collectionAttrs;if(!t)return;if(!b){f.replaceChildren(v("",!0));return}const o=a=>fetch("/api/collections/render-scope",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},body:JSON.stringify({attrs:t})});try{let a=b,e=await o(a);if(e.status===401){const d=S.get("auth_refresh_token");if(d){const h=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:d})});if(h.ok){const{token:m}=await h.json();S.set("auth_token",m),a=m,e=await o(a)}}}if(!e.ok){const{error:d}=await e.json().catch(()=>({}));f.replaceChildren(v(d||"Unable to load entries.",!1));return}const{html:p}=await e.json();w(f,p)}catch{f.replaceChildren(v("Unable to load entries.",!1))}}),setTimeout(()=>{typeof Domma<"u"&&Domma.icons?.scan&&Domma.icons.scan(),typeof Domma<"u"&&Domma.syntax?.scan&&Domma.syntax.scan(),x(document.body)},100)})(),(function(){const y=document.querySelectorAll("[data-collection-table]");!y.length||typeof T>"u"||!T.create||y.forEach(b=>{let v;try{v=JSON.parse(atob(b.dataset.payload))}catch{return}const{columns:w,rows:f,search:t,sortable:o,exportable:a,pageSize:e,empty:p,ctaConfig:d}=v;if(!w?.length)return;if(d){const i=w.findIndex(n=>n.key==="_cta");i!==-1&&(w[i]={key:"_cta",title:"",render:(n,c)=>{const s=document.createElement("button");if(s.className=`btn btn-${d.style||"primary"} dm-cta-trigger`,s.dataset.action=d.action||"",s.dataset.entry=c._entryId||"",d.confirm&&(s.dataset.confirm=d.confirm),d.icon){const u=document.createElement("span");u.dataset.icon=d.icon,s.appendChild(u),s.appendChild(document.createTextNode(" "))}return s.appendChild(document.createTextNode(d.label||"Run")),s}})}const h="col-table-"+Math.random().toString(36).slice(2,7),m=document.createElement("div");m.id=h,b.replaceChildren(m),T.create("#"+h,{data:f,columns:w,search:t,sortable:o,exportable:a,pageSize:e,emptyMessage:p}),d&&x(m)})})(),(function(){const y=document.querySelectorAll("[data-form-inline]");if(!y.length||typeof F>"u")return;function b(t,o){const a={};return(t||[]).forEach(e=>{if(e.type==="page-break"||e.type==="spacer"||!e.name)return;const p=e.type==="chooser"||!!(e.variant&&["select","radio","checkbox-group"].includes(e.type)),d=e.type==="checkbox"?"boolean":e.type==="date"?"string":p?"chooser":e.type,h={...e.formConfig||{}};h.span==="full"&&o&&(h.span=o);const m={type:d,label:e.label,required:e.required,options:e.options,formConfig:{...e.placeholder&&{placeholder:e.placeholder},...e.helper&&{hint:e.helper},...h}};p&&(e.variant&&(m.variant=e.variant),(e.multiple||e.type==="checkbox-group")&&(m.multiple=!0),e.density&&(m.density=e.density),e.columns&&(m.columns=e.columns),e.accent&&(m.accent=e.accent),e.accentStyle&&(m.accentStyle=e.accentStyle),e.glow&&(m.glow=!0),e.glowColour&&(m.glowColour=e.glowColour),e.shadow&&(m.shadow=e.shadow),e.shadowColour&&(m.shadowColour=e.shadowColour)),a[e.name]=m}),a}function v(t){const o={};return(t||[]).forEach(a=>{if(!(!a.name||a.type==="page-break"||a.type==="spacer")&&(a.type==="select"||a.type==="multiselect")&&a.required){const e=(a.options||[])[0];e&&(o[a.name]=typeof e=="object"?e.value:e)}}),o}function w(t,o){(o||[]).forEach(a=>{if(a.type!=="date"||!a.name)return;const e=t.querySelector(`[name="${a.name}"]`);e&&e.type!=="date"&&(e.type="date")})}function f(t,o,a){let e=t.querySelector(".cms-form-message");e||(e=document.createElement("p"),e.className="cms-form-message",t.appendChild(e)),e.textContent=o,e.style.cssText=a?"color:var(--dm-danger,#f87171);margin-top:.75rem;":"color:var(--dm-success,#4ade80);margin-top:.75rem;"}y.forEach(t=>{let o;try{o=JSON.parse(atob(t.dataset.formInline))}catch{return}const a=o.fields||[],e=o.settings||{},p=e.columns||1,d=e.layout||"stacked",h=a.some(c=>c.type==="page-break"),m=async c=>{try{const s=t.querySelector('[name="website"]'),u=t.querySelector('[name="_t"]'),r=Object.assign({},c);s!==null&&(r._hp=s.value),u!==null&&(r._t=u.value);const l=await H.post(`/api/forms/submit/${o.slug}`,r);if(l&&l.error){f(t,l.error,!0);const g=new Error(l.error);throw g.formSubmitFailed=!0,g}if(l?.redirect){window.location.href=l.redirect;return}for(;t.firstChild;)t.removeChild(t.firstChild);f(t,l?.message||e.successMessage||"Thank you for your submission.",!1)}catch(s){throw s.formSubmitFailed||f(t,s.message||"Submission failed. Please try again.",!0),s}};function i(c){const s=c.querySelector("form");if(!s)return;const u=document.createElement("div");u.className="fb-form-honeypot",u.setAttribute("aria-hidden","true");const r=document.createElement("input");r.name="website",r.type="text",r.tabIndex=-1,r.autocomplete="url",r.placeholder="https://",u.appendChild(r);const l=document.createElement("input");l.name="_t",l.type="hidden",l.value=Date.now(),u.appendChild(l),s.appendChild(u)}function n(){if(!window.FormLogicEngine||!a.some(s=>s.logic))return;const c=new window.FormLogicEngine.FormLogicRuntime(o,t);if(c.init(),t._formLogicRuntime=c,t.parentNode&&typeof MutationObserver<"u"){const s=new MutationObserver(function(u){for(const r of u)for(const l of r.removedNodes)if(l===t||l.nodeType===1&&l.contains&&l.contains(t)){c.destroy(),s.disconnect();return}});s.observe(t.parentNode,{childList:!0,subtree:!1})}}if(h&&F.wizard){const c=[];let s=[],u=o.title||"Step 1",r="";a.forEach(g=>{g.type==="page-break"?(c.push({title:u,description:r,fields:b(s,p)}),s=[],u=g.label||`Step ${c.length+1}`,r=g.description||""):g.type!=="spacer"&&s.push(g)}),c.push({title:u,description:r,fields:b(s,p)});const l=F.wizard(t,{schema:{steps:c},onSubmit:m});Promise.resolve(l).then(function(){w(t,a),e.honeypot!==!1&&i(t),n()})}else if(F.render){const c=F.render(t,b(a,p),v(a),{submitText:e.submitText||"Submit",layout:d,columns:p,onSubmit:m});Promise.resolve(c).then(function(){if(d==="grid"&&e.submitSpan==="full"){const s=t.querySelector(".form-buttons");s&&s.classList.add("col-span-full")}w(t,a),e.honeypot!==!1&&i(t),n()})}}),$(document).on("click",".dm-banner__dismiss",function(){$(this).closest(".dm-banner").remove()})})();