domma-cms 0.81.0 → 0.81.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/admin/index.html CHANGED
@@ -80,7 +80,7 @@
80
80
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
81
81
 
82
82
  <!-- Form Logic Engine - needed for conditional logic preview -->
83
- <script src="/public/js/form-logic-engine.js?v=20260926-end-no-finish"></script>
83
+ <script src="/public/js/form-logic-engine.js?v=20260926-limits"></script>
84
84
 
85
85
  <!-- Admin App (ES module entry) -->
86
86
  <script type="module" src="/admin/js/app.js"></script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "0.81.0",
3
+ "version": "0.81.1",
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
- (function(u,f){typeof module<"u"&&module.exports?module.exports=f():u.FormLogicEngine=f()})(typeof globalThis<"u"?globalThis:this,function(){"use strict";function u(e){return e===""||e===null||e===void 0?"":String(e)}function f(e){const i=parseFloat(e);return isNaN(i)?null:i}function p(e){return e==null?!0:typeof e=="string"?e.trim()==="":Array.isArray(e)?e.length===0:!1}const O={not_equals:"equals",not_contains:"contains",not_in:"in"};function w(e,i){const t=u(i),n=u(e.value);switch(e.operator){case"equals":return t===n;case"not_equals":return t!==n;case"contains":return t.toLowerCase().includes(n.toLowerCase());case"not_contains":return!t.toLowerCase().includes(n.toLowerCase());case"starts_with":return t.toLowerCase().startsWith(n.toLowerCase());case"ends_with":return t.toLowerCase().endsWith(n.toLowerCase());case"greater_than":{const r=f(i),s=f(e.value);return r!==null&&s!==null&&r>s}case"less_than":{const r=f(i),s=f(e.value);return r!==null&&s!==null&&r<s}case"is_empty":return p(i);case"is_not_empty":return!p(i);case"in":return(Array.isArray(e.value)?e.value.map(u):String(e.value).split(",").map(s=>s.trim())).includes(t);case"not_in":return!(Array.isArray(e.value)?e.value.map(u):String(e.value).split(",").map(s=>s.trim())).includes(t);case"matches_regex":try{const r=e.flags||"";return new RegExp(e.value,r).test(t)}catch(r){return typeof console<"u"&&console.warn&&console.warn('[FormLogicEngine] Invalid regex in condition for field "'+e.field+'": '+e.value,r&&r.message),!1}default:return!0}}function b(e,i){if(!e||!e.field||!e.operator)return!0;const t=i[e.field];if(!Array.isArray(t))return w(e,t);if(e.operator==="is_empty")return p(t);if(e.operator==="is_not_empty")return!p(t);const n=O[e.operator];if(n){const r=Object.assign({},e,{operator:n});return!t.some(s=>w(r,s))}return t.some(r=>w(e,r))}function h(e,i){return e?Array.isArray(e.all)?e.all.every(t=>t.all||t.any?h(t,i):b(t,i)):Array.isArray(e.any)?e.any.some(t=>t.all||t.any?h(t,i):b(t,i)):e.field&&e.operator?b(e,i):!0:!0}function q(e,i){const t=e.logic;if(!t||!t.visibility)return"visible";const n=t.visibility,r=n.conditions||[];for(const s of r)if(s.when&&h(s.when,i))return s.then==="hidden"?"hidden":"visible";return n.default==="hidden"?"hidden":"visible"}function _(e,i){const t=e.logic;if(!t||!t.requirement)return e.required||!1;const n=t.requirement,r=n.conditions||[];for(const s of r)if(s.when&&h(s.when,i))return s.then===!0;return n.default===!0}function A(e,i,t){const n=e.logic;if(!n||!Array.isArray(n.validation))return[];const r=[];for(const s of n.validation)switch(s.type){case"regex":{if(!p(i))try{new RegExp(s.pattern||"",s.flags||"").test(u(i))||r.push({message:s.message||"Invalid format."})}catch{}break}case"match":{const a=t[s.field];!p(i)&&u(i)!==u(a)&&r.push({message:s.message||"Fields do not match."});break}}return r}function S(e,i){const t=e.logic;if(!t||!t.cascade||!t.cascade.sourceField)return null;const n=t.cascade,r=n.mapping||{},s=i[n.sourceField];if(Array.isArray(s)){const o=new Set,l=[];return s.forEach(function(g){const d=u(g);Object.prototype.hasOwnProperty.call(r,d)&&(r[d]||[]).forEach(function(x){const B=u(x&&x.value);o.has(B)||(o.add(B),l.push(x))})}),l.length?l:n.defaultOptions||null}const a=u(s);return Object.prototype.hasOwnProperty.call(r,a)?r[a]||[]:n.defaultOptions||null}const V={fade:250,slide:300,scale:200};function C(e,i){const t=Number(i);return!isFinite(t)||t<0||t>5e3?V[e]||250:Math.round(t)}function W(e,i,t){const n=C(i,t);if(i==="fade")e.style.transition="opacity "+n+"ms ease",e.style.opacity="1",requestAnimationFrame(function(){e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.opacity=""},n+10)});else if(i==="slide"){const r=Math.round(n*.67);e.style.overflow="hidden",e.style.maxHeight=e.scrollHeight+"px",e.style.transition="max-height "+n+"ms ease, opacity "+r+"ms ease",requestAnimationFrame(function(){e.style.maxHeight="0",e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.maxHeight="",e.style.opacity="",e.style.overflow=""},n+20)})}else i==="scale"&&(e.style.transition="opacity "+n+"ms ease, transform "+n+"ms ease",e.style.transform="scale(1)",e.style.opacity="1",requestAnimationFrame(function(){e.style.transform="scale(0.95)",e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.transform="",e.style.opacity=""},n+20)}))}function D(e,i,t){const n=C(i,t);if(e.classList.remove("fb-field-hidden"),i==="fade")e.style.opacity="0",e.style.transition="opacity "+n+"ms ease",requestAnimationFrame(function(){e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.opacity=""},n+10)});else if(i==="slide"){const r=Math.round(n*.67);e.style.overflow="hidden",e.style.maxHeight="0",e.style.opacity="0",e.style.transition="max-height "+n+"ms ease, opacity "+r+"ms ease",requestAnimationFrame(function(){e.style.maxHeight=e.scrollHeight+"px",e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.maxHeight="",e.style.opacity="",e.style.overflow=""},n+20)})}else i==="scale"&&(e.style.transform="scale(0.95)",e.style.opacity="0",e.style.transition="opacity "+n+"ms ease, transform "+n+"ms ease",requestAnimationFrame(function(){e.style.transform="scale(1)",e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.transform="",e.style.opacity=""},n+20)}))}const T={banner:"state","disable-fields":"state","hide-fields":"state","require-fields":"state","block-submit":"state","end-form":"state",toast:"event",celebrate:"event","goto-step":"event",redirect:"event","run-action":"event",notify:"event"},H=["block-submit","hide-fields","disable-fields","require-fields","end-form","redirect","run-action","notify"];function k(e){return!!e&&!!e.name&&e.type!=="page-break"&&e.type!=="spacer"}function y(e,i,t){const n=(t||[]).filter(k),r=e.target||(e.fields&&e.fields.length?"listed":"rest");if(r==="listed"){const a=new Set(e.fields||[]);return n.filter(o=>a.has(o.name)&&o.name!==i.name).map(o=>o.name)}if(r==="all")return n.filter(a=>a.name!==i.name).map(a=>a.name);const s=n.findIndex(a=>a.name===i.name);return s===-1?[]:n.slice(s+1).map(a=>a.name)}function v(e,i){for(const t of i)e.includes(t)||e.push(t)}function P(e,i,t,n,r){if(!i||!i.type)return;const s=T[i.type];if(s){if(s==="event"){e.events.push({key:r,type:i.type,field:t.name,action:i});return}switch(i.type){case"banner":e.banners.push({key:r,field:t.name,message:i.message||"",level:i.level||"info",position:i.position||"field-below",dismissible:i.dismissible!==!1});break;case"hide-fields":v(e.hidden,y(i,t,n));break;case"disable-fields":v(e.disabled,y(i,t,n));break;case"require-fields":v(e.required,y(i,t,n));break;case"block-submit":e.blocks.push({key:r,message:i.message||"This form cannot be submitted yet."});break;case"end-form":v(e.masked,y({target:"rest"},t,n)),e.ends.push({key:r,field:t.name,message:i.message||"",finishLabel:i.finishLabel||"Finish",doneMessage:i.doneMessage||"",record:i.record!==!1,finish:i.finish!==!1}),i.finish===!1&&e.blocks.push({key:r,quiet:!0,message:i.message||"This form cannot be submitted."});break;default:break}}}function N(e,i){const t={active:[],banners:[],hidden:[],disabled:[],required:[],blocks:[],events:[],masked:[],ends:[]};return(e||[]).forEach(n=>{!k(n)||!Array.isArray(n.triggers)||n.triggers.forEach((r,s)=>{if(!r||r.enabled===!1)return;const a=r.id||`${n.name}::${s}`,o=h(r.when,i),l=`${a}:${o?"then":"else"}`,g=o?r.then:r.otherwise;!Array.isArray(g)||!g.length||(t.active.push(l),g.forEach(d=>P(t,d,n,e,l)))})}),t.required=t.required.filter(n=>!t.hidden.includes(n)&&!t.masked.includes(n)),t}function F(e){return(e||[]).some(i=>Array.isArray(i&&i.triggers)&&i.triggers.length>0)}function c(e,i,t){this._form=e,this._wrapper=i,this._fields=(e.fields||[]).filter(n=>n.type!=="page-break"),this._listeners=[],this._depMap=new Map,this._initialEval=!1,this._baseValues=t&&t.baseValues||null,this._hasTriggers=F(this._fields),this._triggerState=null,this._triggerPrev=new Set,this._triggerFired=new Set,this._triggerApplied={hidden:[],disabled:[],required:[],masked:[]},this._banners=new Map,this._dismissed=new Set,this._end=null}function m(e,i,t){const n=t||"",r=i||"";return n+'[name="'+e+'"]'+r+", "+n+'[name="'+e+'[]"]'+r}function $(e){return String(e||"").replace(/\[\]$/,"")}c.prototype._fieldInputs=function(e){return this._wrapper.querySelectorAll(m(e))},c.prototype._fieldInput=function(e){return this._wrapper.querySelector(m(e))},c.prototype._buildDepMap=function(){this._depMap.clear();const e=this;e._fields.forEach(function(i){const t=i.logic;if(!t)return;function n(r){if(!r)return;(r.all||r.any||[]).forEach(function(a){a.field?(e._depMap.has(a.field)||e._depMap.set(a.field,new Set),e._depMap.get(a.field).add(i.name)):n(a)})}if(t.visibility&&(t.visibility.conditions||[]).forEach(function(r){n(r.when)}),t.requirement&&(t.requirement.conditions||[]).forEach(function(r){n(r.when)}),t.cascade&&t.cascade.sourceField){const r=t.cascade.sourceField;e._depMap.has(r)||e._depMap.set(r,new Set),e._depMap.get(r).add(i.name)}})};function L(e,i){const t={};return(i||[]).forEach(function(n){if(!n||!n.name)return;const r=e.querySelectorAll(m(n.name));if(!r.length)return;const s=r[0];if(s.type==="radio"){const a=e.querySelector(m(n.name,":checked"));t[n.name]=a?a.value:""}else if(s.type==="checkbox")if(r.length>1||/\[\]$/.test(s.name||"")){const a=[];r.forEach(function(o){o.checked&&a.push(o.value)}),t[n.name]=a}else t[n.name]=s.checked?s.value||"true":"";else t[n.name]=s.value}),t}function I(e,i){const t=L(e,i),n=[],r=[];return(i||[]).forEach(function(s){if(!s||!s.name||q(s,t)==="hidden")return;const a=t[s.name],o=Array.isArray(a)?a.length===0:!String(a??"").trim();if(_(s,t)&&o){n.push({name:s.name,label:s.label||s.name});return}if(o)return;const l=A(s,a,t);l.length&&r.push(l[0].message)}),{valid:n.length===0&&r.length===0,missing:n,errors:r,values:t}}c.prototype._getValues=function(){const e=this._baseValues?Object.assign({},this._baseValues):{};return this._fields.forEach(function(i){const t=this._fieldInputs(i.name);if(!t.length)return;const n=t[0];if(n.type==="radio"){const r=this._wrapper.querySelector(m(i.name,":checked"));e[i.name]=r?r.value:""}else if(n.type==="checkbox")if(t.length>1||/\[\]$/.test(n.name||"")){const r=[];t.forEach(function(s){s.checked&&r.push(s.value)}),e[i.name]=r}else e[i.name]=n.checked?n.value||"true":"";else e[i.name]=n.value},this),e},c.prototype._applyVisibility=function(e,i){const n=q(e,i)==="hidden",r=this._findFieldWrapper(e.name);if(!r)return;r.setAttribute("aria-hidden",String(n));const s=this._initialEval?"none":e.logic?.visibility?.transition||"none";if(s==="none"){r.classList.toggle("fb-field-hidden",n);return}const a=e.logic?.visibility?.duration;r.style.transition="",n?W(r,s,a):D(r,s,a)},c.prototype._applyRequirement=function(e,i){const t=_(e,i),n=this._fieldInput(e.name);if(!n)return;if(/\[\]$/.test(n.name||"")||n.closest&&n.closest(".domma-chooser")){const s=this._findFieldWrapper(e.name);n.removeAttribute("required"),s&&(s.setAttribute("aria-required",String(t)),s.classList.toggle("fb-field-required",t));return}t?n.setAttribute("required",""):n.removeAttribute("required");const r=this._findFieldWrapper(e.name);r&&(r.setAttribute("aria-required",String(t)),r.classList.toggle("fb-field-required",t))},c.prototype._applyCascade=function(e,i){const t=S(e,i);if(t===null)return;const n=this._wrapper.querySelector(m(e.name,"","select"));if(!n)return;const r=n.value;n.textContent="",t.forEach(function(s){const a=document.createElement("option");a.value=s.value,a.textContent=s.label||s.value,s.value===r&&(a.selected=!0),n.appendChild(a)})},c.prototype._applyValidation=function(e,i){const t=this._fieldInput(e.name);if(!t)return;const n=A(e,i[e.name],i);let r=t.parentNode.querySelector(".fb-validation-error");n.length?(r||(r=document.createElement("div"),r.className="fb-validation-error",t.parentNode.appendChild(r)),r.textContent=n[0].message):r&&r.remove()},c.prototype._findFieldWrapper=function(e){const i=this._fieldInput(e);if(!i)return null;const t=i.closest("form")||this._wrapper;let n=i;for(;n.parentNode&&n.parentNode!==t;)n=n.parentNode;return n},c.prototype.evaluate=function(e){const i=this._getValues(),t=this;let n;if(e&&this._depMap.has(e)){const r=this._depMap.get(e);n=this._fields.filter(function(s){return r.has(s.name)})}else n=this._fields;n.forEach(function(r){r.logic&&(t._applyVisibility(r,i),t._applyRequirement(r,i),t._applyCascade(r,i))}),this._applyTriggers(i)},c.prototype.init=function(){this._buildDepMap();const e=this;if(this._wrapper.querySelectorAll("input, select, textarea").forEach(function(n){const r=$(n.getAttribute("name"));if(!r)return;const s=function(){e.evaluate(r)};n.addEventListener("input",s),n.addEventListener("change",s),e._listeners.push({el:n,event:"input",fn:s}),e._listeners.push({el:n,event:"change",fn:s});const a=e._fields.find(function(o){return o.name===r});if(a&&a.logic&&Array.isArray(a.logic.validation)&&a.logic.validation.length){const o=function(){const l=e._getValues();e._applyValidation(a,l)};n.addEventListener("blur",o),e._listeners.push({el:n,event:"blur",fn:o})}}),this._wrapper.querySelectorAll("[data-chooser-field]").forEach(function(n){const r=n.getAttribute("data-chooser-field");if(!r)return;const s=function(){setTimeout(function(){e.evaluate(r)},0)};n.addEventListener("click",s),e._listeners.push({el:n,event:"click",fn:s})}),this._hasTriggers){const n=function(r){if(e._end&&!(r.type==="click"&&!(r.target&&r.target.closest&&r.target.closest(z)))){if(!e._end.spec.finish){r.preventDefault(),r.stopImmediatePropagation();return}e._wrapper.dataset.triggerBlocked!=="true"&&(r.preventDefault(),r.stopImmediatePropagation(),e._finishEnded())}};this._wrapper.addEventListener("click",n,!0),this._wrapper.addEventListener("submit",n,!0),this._listeners.push({el:this._wrapper,event:"click",fn:n,capture:!0}),this._listeners.push({el:this._wrapper,event:"submit",fn:n,capture:!0})}this._initialEval=!0,this.evaluate(),this._initialEval=!1},c.prototype.destroy=function(){this._listeners.forEach(function(e){e.el.removeEventListener(e.event,e.fn,!!e.capture)}),this._listeners=[],this._banners.forEach(function(e){e&&e.parentNode&&e.parentNode.removeChild(e)}),this._banners.clear(),this._syncEnd([])},c.prototype._applyTriggers=function(e){if(!this._hasTriggers)return;const i=N(this._fields,e);this._triggerState=i;const t=this._triggerApplied||{hidden:[],disabled:[],required:[]};t.hidden.forEach(n=>{i.hidden.indexOf(n)===-1&&this._setTriggerHidden(n,!1)}),i.hidden.forEach(n=>this._setTriggerHidden(n,!0)),t.disabled.forEach(n=>{i.disabled.indexOf(n)===-1&&this._setTriggerDisabled(n,!1)}),i.disabled.forEach(n=>this._setTriggerDisabled(n,!0)),t.required.forEach(n=>{i.required.indexOf(n)===-1&&this._restoreRequired(n,e)}),i.required.forEach(n=>this._setTriggerRequired(n,!0)),(t.masked||[]).forEach(n=>{i.masked.indexOf(n)===-1&&this._setTriggerMasked(n,!1)}),i.masked.forEach(n=>this._setTriggerMasked(n,!0)),this._triggerApplied={hidden:i.hidden.slice(),disabled:i.disabled.slice(),required:i.required.slice(),masked:i.masked.slice()},this._syncBanners(i.banners),this._syncSubmitBlock(i.blocks),this._syncEnd(i.ends),this._fireTriggerEvents(i)},c.prototype._setTriggerHidden=function(e,i){const t=this._findFieldWrapper(e);t&&(t.classList.toggle("fb-field-trigger-hidden",i),t.setAttribute("aria-hidden",String(i||t.classList.contains("fb-field-hidden"))))},c.prototype._setTriggerMasked=function(e,i){const t=this._findFieldWrapper(e);t&&(t.classList.toggle("fb-field-trigger-masked",i),t.setAttribute("aria-hidden",String(i||t.classList.contains("fb-field-hidden")||t.classList.contains("fb-field-trigger-hidden"))))},c.prototype._setTriggerDisabled=function(e,i){const t=this._findFieldWrapper(e);t&&t.classList.toggle("fb-field-disabled",i),this._fieldInputs(e).forEach(function(r){r.disabled=i});const n=this._wrapper.querySelector('[data-chooser-field="'+e+'"]');n&&(n.classList.toggle("fb-field-disabled",i),n.querySelectorAll('button, [role="radio"], [role="checkbox"]').forEach(function(r){i?r.setAttribute("aria-disabled","true"):r.removeAttribute("aria-disabled")}))},c.prototype._setTriggerRequired=function(e,i){const t=this._fieldInput(e),n=this._findFieldWrapper(e);if(n&&(n.setAttribute("aria-required",String(i)),n.classList.toggle("fb-field-required",i)),!!t){if(/\[\]$/.test(t.name||"")||t.closest&&t.closest(".domma-chooser")){t.removeAttribute("required");return}i?t.setAttribute("required",""):t.removeAttribute("required")}},c.prototype._restoreRequired=function(e,i){const t=this._fields.find(function(n){return n.name===e});t&&this._setTriggerRequired(e,_(t,i))},c.prototype._syncBanners=function(e){const i=new Map;e.forEach(function(t){i.set(t.key,t)}),this._banners.forEach(function(t,n){i.has(n)||(t.parentNode&&t.parentNode.removeChild(t),this._banners.delete(n))},this),this._dismissed.forEach(function(t){i.has(t)||this._dismissed.delete(t)},this),i.forEach(function(t,n){if(this._banners.has(n)){const a=this._banners.get(n).querySelector(".fb-trigger-banner-text");a&&a.textContent!==t.message&&(a.textContent=t.message);return}if(this._dismissed.has(n))return;const r=this._buildBanner(t,n);r&&this._banners.set(n,r)},this)},c.prototype._buildBanner=function(e,i){if(typeof document>"u"||!e.message)return null;const t=document.createElement("div");t.className="fb-trigger-banner fb-trigger-banner--"+(e.level||"info"),t.setAttribute("role",e.level==="error"?"alert":"status"),t.dataset.triggerKey=i;const n=document.createElement("span");if(n.className="fb-trigger-banner-text",n.textContent=e.message,t.appendChild(n),e.dismissible){const a=document.createElement("button");a.type="button",a.className="fb-trigger-banner-close",a.setAttribute("aria-label","Dismiss"),a.textContent="\xD7";const o=this;a.addEventListener("click",function(){o._dismissed.add(i),t.parentNode&&t.parentNode.removeChild(t),o._banners.delete(i)}),t.appendChild(a)}const r=this._findFieldWrapper(e.field),s=this._wrapper.querySelector("form")||this._wrapper;return e.position==="form-top"?s.insertBefore(t,s.firstChild):r&&r.parentNode?e.position==="field-above"?r.parentNode.insertBefore(t,r):r.parentNode.insertBefore(t,r.nextSibling):s.appendChild(t),t},c.prototype._syncSubmitBlock=function(e){const i=this._wrapper.querySelector("form")||this._wrapper,t=i.querySelector('button[type="submit"], input[type="submit"], .fb-form-submit'),n=e.length>0;this._wrapper.dataset.triggerBlocked=n?"true":"false",t&&(t.disabled=n,t.setAttribute("aria-disabled",String(n)));let r=i.querySelector(".fb-trigger-block-note");const s=e.filter(function(a){return!a.quiet}).map(function(a){return a.message});if(!s.length){r&&r.parentNode&&r.parentNode.removeChild(r);return}r||(r=document.createElement("p"),r.className="fb-trigger-block-note",r.setAttribute("role","status"),(t&&t.parentNode?t.parentNode:i).appendChild(r)),r.textContent=s.join(" ")};const z='button[type="submit"], input[type="submit"], .fb-form-submit, .wizard-next, .wizard-submit';c.prototype._primaryButton=function(){return this._wrapper.querySelector(".wizard-next, .wizard-submit")||this._wrapper.querySelector('button[type="submit"], input[type="submit"], .fb-form-submit')};function M(e){return!!(e.matches&&e.matches(".wizard-next, .wizard-submit"))}function R(e,i){e.tagName==="INPUT"?e.value=i:e.textContent=i}return c.prototype._syncEnd=function(e){const i=e&&e.length?e[0]:null,t=this._end;if(t&&(!i||t.spec.key!==i.key)&&(t.panel&&t.panel.parentNode&&t.panel.parentNode.removeChild(t.panel),t.button&&t.button.isConnected&&(t.spec.finish?R(t.button,t.label):M(t.button)&&(t.button.disabled=!1)),this._end=null),this._wrapper.dataset.triggerEnded=i?"true":"false",!i||typeof document>"u")return;if(this._end){const a=this._end.panel&&this._end.panel.querySelector(".fb-trigger-end-text");a&&a.textContent!==i.message&&(a.textContent=i.message),this._end.spec=i;return}let n=null;if(i.message){n=document.createElement("div"),n.className="fb-trigger-end",n.setAttribute("role","status"),n.dataset.triggerKey=i.key;const a=document.createElement("div");a.className="fb-trigger-end-text",a.textContent=i.message,n.appendChild(a);const o=this._findFieldWrapper(i.field);o&&o.parentNode?o.parentNode.insertBefore(n,o.nextSibling):(this._wrapper.querySelector("form")||this._wrapper).appendChild(n)}const r=this._primaryButton();let s="";r&&i.finish?(s=r.tagName==="INPUT"?r.value:r.textContent,R(r,i.finishLabel)):r&&M(r)&&(r.disabled=!0),this._end={spec:i,panel:n,button:r,label:s}},c.prototype._finishEnded=function(){const e=this._triggerState||{},i=new Set([].concat(e.masked||[],e.hidden||[],e.disabled||[])),t=this,n=this._fields.filter(function(a){return k(a)&&!i.has(a.name)&&t._fieldInput(a.name)}),r=this._getValues();(e.masked||[]).forEach(function(a){delete r[a]});const s=I(this._wrapper,n);(e.required||[]).forEach(function(a){const o=n.find(function(d){return d.name===a});if(!o)return;const l=r[a];(Array.isArray(l)?l.length===0:!String(l??"").trim())&&!s.missing.some(function(d){return d.name===a})&&(s.missing.push({name:a,label:o.label||a}),s.valid=!1)}),this._wrapper.dispatchEvent(new CustomEvent("dm-form-end",{bubbles:!0,detail:{values:r,validation:s,end:this._end?this._end.spec:null}}))},c.prototype._fireTriggerEvents=function(e){const i=new Set(e.active),t=this;e.events.forEach(function(n){t._triggerPrev.has(n.key)||n.action.once&&t._triggerFired.has(n.key)||t._initialEval&&n.action.onLoad!==!0||(t._triggerFired.add(n.key),t._runTriggerEvent(n))}),this._triggerPrev=i},c.prototype._runTriggerEvent=function(e){const i=e.action;switch(i.type){case"toast":typeof E<"u"&&E&&typeof E.toast=="function"&&E.toast(i.message||"",{type:i.level||"info",duration:Number(i.duration)||4e3});break;case"celebrate":this._celebrate(i);break;default:break}typeof CustomEvent<"u"&&this._wrapper.dispatchEvent&&this._wrapper.dispatchEvent(new CustomEvent("dm-form-trigger",{bubbles:!0,detail:{type:i.type,field:e.field,action:i}}))},c.prototype._celebrate=function(e){typeof window>"u"||typeof document>"u"||window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches||import("/public/js/celebrations/index.js").then(function(i){const t=i.CelebrationsEffect;let n=e.theme||"auto";if(n==="auto"&&(n=t.getCurrentTheme(),!n))return;const r=new t({theme:n,intensity:e.intensity||"medium",enabled:!0,zIndex:999});r.init().then(function(){r.start()})}).catch(function(){})},c.prototype.submitBlock=function(){const e=this._triggerState&&this._triggerState.blocks||[];return{blocked:e.length>0,reasons:e.map(function(i){return i.message})}},{evaluateCondition:b,evaluateConditionGroup:h,evaluateFieldVisibility:q,evaluateFieldRequirement:_,validateField:A,collectValues:L,validateFields:I,getCascadeOptions:S,resolveTriggerState:N,resolveTriggerTargets:y,hasTriggers:F,TRIGGER_ACTION_KINDS:T,SERVER_TRIGGER_ACTIONS:H,FormLogicRuntime:c}});
1
+ (function(l,d){typeof module<"u"&&module.exports?module.exports=d():l.FormLogicEngine=d()})(typeof globalThis<"u"?globalThis:this,function(){"use strict";function l(e){return e===""||e===null||e===void 0?"":String(e)}function d(e){const r=parseFloat(e);return isNaN(r)?null:r}function p(e){return e==null?!0:typeof e=="string"?e.trim()==="":Array.isArray(e)?e.length===0:!1}const $={not_equals:"equals",not_contains:"contains",not_in:"in"};function q(e,r){const t=l(r),n=l(e.value);switch(e.operator){case"equals":return t===n;case"not_equals":return t!==n;case"contains":return t.toLowerCase().includes(n.toLowerCase());case"not_contains":return!t.toLowerCase().includes(n.toLowerCase());case"starts_with":return t.toLowerCase().startsWith(n.toLowerCase());case"ends_with":return t.toLowerCase().endsWith(n.toLowerCase());case"greater_than":{const i=d(r),s=d(e.value);return i!==null&&s!==null&&i>s}case"less_than":{const i=d(r),s=d(e.value);return i!==null&&s!==null&&i<s}case"is_empty":return p(r);case"is_not_empty":return!p(r);case"in":return(Array.isArray(e.value)?e.value.map(l):String(e.value).split(",").map(s=>s.trim())).includes(t);case"not_in":return!(Array.isArray(e.value)?e.value.map(l):String(e.value).split(",").map(s=>s.trim())).includes(t);case"matches_regex":try{const i=e.flags||"";return new RegExp(e.value,i).test(t)}catch(i){return typeof console<"u"&&console.warn&&console.warn('[FormLogicEngine] Invalid regex in condition for field "'+e.field+'": '+e.value,i&&i.message),!1}default:return!0}}function y(e,r){if(!e||!e.field||!e.operator)return!0;const t=r[e.field];if(!Array.isArray(t))return q(e,t);if(e.operator==="is_empty")return p(t);if(e.operator==="is_not_empty")return!p(t);const n=$[e.operator];if(n){const i=Object.assign({},e,{operator:n});return!t.some(s=>q(i,s))}return t.some(i=>q(e,i))}function h(e,r){return e?Array.isArray(e.all)?e.all.every(t=>t.all||t.any?h(t,r):y(t,r)):Array.isArray(e.any)?e.any.some(t=>t.all||t.any?h(t,r):y(t,r)):e.field&&e.operator?y(e,r):!0:!0}function A(e,r){const t=e.logic;if(!t||!t.visibility)return"visible";const n=t.visibility,i=n.conditions||[];for(const s of i)if(s.when&&h(s.when,r))return s.then==="hidden"?"hidden":"visible";return n.default==="hidden"?"hidden":"visible"}function _(e,r){const t=e.logic;if(!t||!t.requirement)return e.required||!1;const n=t.requirement,i=n.conditions||[];for(const s of i)if(s.when&&h(s.when,r))return s.then===!0;return n.default===!0}function v(e){if(e==null||e==="")return null;const r=Number(e);return Number.isFinite(r)?r:null}function V(e,r){if(p(r)||Array.isArray(r)||typeof r=="object")return[];const t=e.label||e.name;if(e.type==="number"){const a=Number(r);if(!Number.isFinite(a)||String(r).trim()==="")return[{message:`${t} must be a number.`}];const o=v(e.min),c=v(e.max);return o!==null&&a<o?[{message:`${t} must be at least ${o}.`}]:c!==null&&a>c?[{message:`${t} must be no more than ${c}.`}]:[]}const n=String(r).length,i=v(e.minLength),s=v(e.maxLength);return i!==null&&n<i?[{message:`${t} must be at least ${i} characters.`}]:s!==null&&n>s?[{message:`${t} must be no more than ${s} characters.`}]:[]}function x(e,r,t){const n=V(e,r),i=e.logic;if(!i||!Array.isArray(i.validation))return n;for(const s of i.validation)switch(s.type){case"regex":{if(!p(r))try{new RegExp(s.pattern||"",s.flags||"").test(l(r))||n.push({message:s.message||"Invalid format."})}catch{}break}case"match":{const a=t[s.field];!p(r)&&l(r)!==l(a)&&n.push({message:s.message||"Fields do not match."});break}}return n}function C(e,r){const t=e.logic;if(!t||!t.cascade||!t.cascade.sourceField)return null;const n=t.cascade,i=n.mapping||{},s=r[n.sourceField];if(Array.isArray(s)){const o=new Set,c=[];return s.forEach(function(g){const f=l(g);Object.prototype.hasOwnProperty.call(i,f)&&(i[f]||[]).forEach(function(S){const O=l(S&&S.value);o.has(O)||(o.add(O),c.push(S))})}),c.length?c:n.defaultOptions||null}const a=l(s);return Object.prototype.hasOwnProperty.call(i,a)?i[a]||[]:n.defaultOptions||null}const W={fade:250,slide:300,scale:200};function T(e,r){const t=Number(r);return!isFinite(t)||t<0||t>5e3?W[e]||250:Math.round(t)}function D(e,r,t){const n=T(r,t);if(r==="fade")e.style.transition="opacity "+n+"ms ease",e.style.opacity="1",requestAnimationFrame(function(){e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.opacity=""},n+10)});else if(r==="slide"){const i=Math.round(n*.67);e.style.overflow="hidden",e.style.maxHeight=e.scrollHeight+"px",e.style.transition="max-height "+n+"ms ease, opacity "+i+"ms ease",requestAnimationFrame(function(){e.style.maxHeight="0",e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.maxHeight="",e.style.opacity="",e.style.overflow=""},n+20)})}else r==="scale"&&(e.style.transition="opacity "+n+"ms ease, transform "+n+"ms ease",e.style.transform="scale(1)",e.style.opacity="1",requestAnimationFrame(function(){e.style.transform="scale(0.95)",e.style.opacity="0",setTimeout(function(){e.classList.add("fb-field-hidden"),e.style.transition="",e.style.transform="",e.style.opacity=""},n+20)}))}function H(e,r,t){const n=T(r,t);if(e.classList.remove("fb-field-hidden"),r==="fade")e.style.opacity="0",e.style.transition="opacity "+n+"ms ease",requestAnimationFrame(function(){e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.opacity=""},n+10)});else if(r==="slide"){const i=Math.round(n*.67);e.style.overflow="hidden",e.style.maxHeight="0",e.style.opacity="0",e.style.transition="max-height "+n+"ms ease, opacity "+i+"ms ease",requestAnimationFrame(function(){e.style.maxHeight=e.scrollHeight+"px",e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.maxHeight="",e.style.opacity="",e.style.overflow=""},n+20)})}else r==="scale"&&(e.style.transform="scale(0.95)",e.style.opacity="0",e.style.transition="opacity "+n+"ms ease, transform "+n+"ms ease",requestAnimationFrame(function(){e.style.transform="scale(1)",e.style.opacity="1",setTimeout(function(){e.style.transition="",e.style.transform="",e.style.opacity=""},n+20)}))}const N={banner:"state","disable-fields":"state","hide-fields":"state","require-fields":"state","block-submit":"state","end-form":"state",toast:"event",celebrate:"event","goto-step":"event",redirect:"event","run-action":"event",notify:"event"},P=["block-submit","hide-fields","disable-fields","require-fields","end-form","redirect","run-action","notify"];function k(e){return!!e&&!!e.name&&e.type!=="page-break"&&e.type!=="spacer"}function b(e,r,t){const n=(t||[]).filter(k),i=e.target||(e.fields&&e.fields.length?"listed":"rest");if(i==="listed"){const a=new Set(e.fields||[]);return n.filter(o=>a.has(o.name)&&o.name!==r.name).map(o=>o.name)}if(i==="all")return n.filter(a=>a.name!==r.name).map(a=>a.name);const s=n.findIndex(a=>a.name===r.name);return s===-1?[]:n.slice(s+1).map(a=>a.name)}function w(e,r){for(const t of r)e.includes(t)||e.push(t)}function z(e,r,t,n,i){if(!r||!r.type)return;const s=N[r.type];if(s){if(s==="event"){e.events.push({key:i,type:r.type,field:t.name,action:r});return}switch(r.type){case"banner":e.banners.push({key:i,field:t.name,message:r.message||"",level:r.level||"info",position:r.position||"field-below",dismissible:r.dismissible!==!1});break;case"hide-fields":w(e.hidden,b(r,t,n));break;case"disable-fields":w(e.disabled,b(r,t,n));break;case"require-fields":w(e.required,b(r,t,n));break;case"block-submit":e.blocks.push({key:i,message:r.message||"This form cannot be submitted yet."});break;case"end-form":w(e.masked,b({target:"rest"},t,n)),e.ends.push({key:i,field:t.name,message:r.message||"",finishLabel:r.finishLabel||"Finish",doneMessage:r.doneMessage||"",record:r.record!==!1,finish:r.finish!==!1}),r.finish===!1&&e.blocks.push({key:i,quiet:!0,message:r.message||"This form cannot be submitted."});break;default:break}}}function L(e,r){const t={active:[],banners:[],hidden:[],disabled:[],required:[],blocks:[],events:[],masked:[],ends:[]};return(e||[]).forEach(n=>{!k(n)||!Array.isArray(n.triggers)||n.triggers.forEach((i,s)=>{if(!i||i.enabled===!1)return;const a=i.id||`${n.name}::${s}`,o=h(i.when,r),c=`${a}:${o?"then":"else"}`,g=o?i.then:i.otherwise;!Array.isArray(g)||!g.length||(t.active.push(c),g.forEach(f=>z(t,f,n,e,c)))})}),t.required=t.required.filter(n=>!t.hidden.includes(n)&&!t.masked.includes(n)),t}function F(e){return(e||[]).some(r=>Array.isArray(r&&r.triggers)&&r.triggers.length>0)}function u(e,r,t){this._form=e,this._wrapper=r,this._fields=(e.fields||[]).filter(n=>n.type!=="page-break"),this._listeners=[],this._depMap=new Map,this._initialEval=!1,this._baseValues=t&&t.baseValues||null,this._hasTriggers=F(this._fields),this._triggerState=null,this._triggerPrev=new Set,this._triggerFired=new Set,this._triggerApplied={hidden:[],disabled:[],required:[],masked:[]},this._banners=new Map,this._dismissed=new Set,this._end=null}function m(e,r,t){const n=t||"",i=r||"";return n+'[name="'+e+'"]'+i+", "+n+'[name="'+e+'[]"]'+i}function G(e){return String(e||"").replace(/\[\]$/,"")}u.prototype._fieldInputs=function(e){return this._wrapper.querySelectorAll(m(e))},u.prototype._fieldInput=function(e){return this._wrapper.querySelector(m(e))},u.prototype._buildDepMap=function(){this._depMap.clear();const e=this;e._fields.forEach(function(r){const t=r.logic;if(!t)return;function n(i){if(!i)return;(i.all||i.any||[]).forEach(function(a){a.field?(e._depMap.has(a.field)||e._depMap.set(a.field,new Set),e._depMap.get(a.field).add(r.name)):n(a)})}if(t.visibility&&(t.visibility.conditions||[]).forEach(function(i){n(i.when)}),t.requirement&&(t.requirement.conditions||[]).forEach(function(i){n(i.when)}),t.cascade&&t.cascade.sourceField){const i=t.cascade.sourceField;e._depMap.has(i)||e._depMap.set(i,new Set),e._depMap.get(i).add(r.name)}})};function I(e,r){const t={};return(r||[]).forEach(function(n){if(!n||!n.name)return;const i=e.querySelectorAll(m(n.name));if(!i.length)return;const s=i[0];if(s.type==="radio"){const a=e.querySelector(m(n.name,":checked"));t[n.name]=a?a.value:""}else if(s.type==="checkbox")if(i.length>1||/\[\]$/.test(s.name||"")){const a=[];i.forEach(function(o){o.checked&&a.push(o.value)}),t[n.name]=a}else t[n.name]=s.checked?s.value||"true":"";else t[n.name]=s.value}),t}function M(e,r){const t=I(e,r),n=[],i=[];return(r||[]).forEach(function(s){if(!s||!s.name||A(s,t)==="hidden")return;const a=t[s.name],o=Array.isArray(a)?a.length===0:!String(a??"").trim();if(_(s,t)&&o){n.push({name:s.name,label:s.label||s.name});return}if(o)return;const c=x(s,a,t);c.length&&i.push(c[0].message)}),{valid:n.length===0&&i.length===0,missing:n,errors:i,values:t}}u.prototype._getValues=function(){const e=this._baseValues?Object.assign({},this._baseValues):{};return this._fields.forEach(function(r){const t=this._fieldInputs(r.name);if(!t.length)return;const n=t[0];if(n.type==="radio"){const i=this._wrapper.querySelector(m(r.name,":checked"));e[r.name]=i?i.value:""}else if(n.type==="checkbox")if(t.length>1||/\[\]$/.test(n.name||"")){const i=[];t.forEach(function(s){s.checked&&i.push(s.value)}),e[r.name]=i}else e[r.name]=n.checked?n.value||"true":"";else e[r.name]=n.value},this),e},u.prototype._applyVisibility=function(e,r){const n=A(e,r)==="hidden",i=this._findFieldWrapper(e.name);if(!i)return;i.setAttribute("aria-hidden",String(n));const s=this._initialEval?"none":e.logic?.visibility?.transition||"none";if(s==="none"){i.classList.toggle("fb-field-hidden",n);return}const a=e.logic?.visibility?.duration;i.style.transition="",n?D(i,s,a):H(i,s,a)},u.prototype._applyRequirement=function(e,r){const t=_(e,r),n=this._fieldInput(e.name);if(!n)return;if(/\[\]$/.test(n.name||"")||n.closest&&n.closest(".domma-chooser")){const s=this._findFieldWrapper(e.name);n.removeAttribute("required"),s&&(s.setAttribute("aria-required",String(t)),s.classList.toggle("fb-field-required",t));return}t?n.setAttribute("required",""):n.removeAttribute("required");const i=this._findFieldWrapper(e.name);i&&(i.setAttribute("aria-required",String(t)),i.classList.toggle("fb-field-required",t))},u.prototype._applyCascade=function(e,r){const t=C(e,r);if(t===null)return;const n=this._wrapper.querySelector(m(e.name,"","select"));if(!n)return;const i=n.value;n.textContent="",t.forEach(function(s){const a=document.createElement("option");a.value=s.value,a.textContent=s.label||s.value,s.value===i&&(a.selected=!0),n.appendChild(a)})},u.prototype._applyValidation=function(e,r){const t=this._fieldInput(e.name);if(!t)return;const n=x(e,r[e.name],r);let i=t.parentNode.querySelector(".fb-validation-error");n.length?(i||(i=document.createElement("div"),i.className="fb-validation-error",t.parentNode.appendChild(i)),i.textContent=n[0].message):i&&i.remove()},u.prototype._findFieldWrapper=function(e){const r=this._fieldInput(e);if(!r)return null;const t=r.closest("form")||this._wrapper;let n=r;for(;n.parentNode&&n.parentNode!==t;)n=n.parentNode;return n},u.prototype.evaluate=function(e){const r=this._getValues(),t=this;let n;if(e&&this._depMap.has(e)){const i=this._depMap.get(e);n=this._fields.filter(function(s){return i.has(s.name)})}else n=this._fields;n.forEach(function(i){i.logic&&(t._applyVisibility(i,r),t._applyRequirement(i,r),t._applyCascade(i,r))}),this._applyTriggers(r)},u.prototype.init=function(){this._buildDepMap();const e=this;if(this._wrapper.querySelectorAll("input, select, textarea").forEach(function(n){const i=G(n.getAttribute("name"));if(!i)return;const s=function(){e.evaluate(i)};n.addEventListener("input",s),n.addEventListener("change",s),e._listeners.push({el:n,event:"input",fn:s}),e._listeners.push({el:n,event:"change",fn:s});const a=e._fields.find(function(o){return o.name===i});if(a&&a.logic&&Array.isArray(a.logic.validation)&&a.logic.validation.length){const o=function(){const c=e._getValues();e._applyValidation(a,c)};n.addEventListener("blur",o),e._listeners.push({el:n,event:"blur",fn:o})}}),this._wrapper.querySelectorAll("[data-chooser-field]").forEach(function(n){const i=n.getAttribute("data-chooser-field");if(!i)return;const s=function(){setTimeout(function(){e.evaluate(i)},0)};n.addEventListener("click",s),e._listeners.push({el:n,event:"click",fn:s})}),this._hasTriggers){const n=function(i){if(e._end&&!(i.type==="click"&&!(i.target&&i.target.closest&&i.target.closest(j)))){if(!e._end.spec.finish){i.preventDefault(),i.stopImmediatePropagation();return}e._wrapper.dataset.triggerBlocked!=="true"&&(i.preventDefault(),i.stopImmediatePropagation(),e._finishEnded())}};this._wrapper.addEventListener("click",n,!0),this._wrapper.addEventListener("submit",n,!0),this._listeners.push({el:this._wrapper,event:"click",fn:n,capture:!0}),this._listeners.push({el:this._wrapper,event:"submit",fn:n,capture:!0})}this._initialEval=!0,this.evaluate(),this._initialEval=!1},u.prototype.destroy=function(){this._listeners.forEach(function(e){e.el.removeEventListener(e.event,e.fn,!!e.capture)}),this._listeners=[],this._banners.forEach(function(e){e&&e.parentNode&&e.parentNode.removeChild(e)}),this._banners.clear(),this._syncEnd([])},u.prototype._applyTriggers=function(e){if(!this._hasTriggers)return;const r=L(this._fields,e);this._triggerState=r;const t=this._triggerApplied||{hidden:[],disabled:[],required:[]};t.hidden.forEach(n=>{r.hidden.indexOf(n)===-1&&this._setTriggerHidden(n,!1)}),r.hidden.forEach(n=>this._setTriggerHidden(n,!0)),t.disabled.forEach(n=>{r.disabled.indexOf(n)===-1&&this._setTriggerDisabled(n,!1)}),r.disabled.forEach(n=>this._setTriggerDisabled(n,!0)),t.required.forEach(n=>{r.required.indexOf(n)===-1&&this._restoreRequired(n,e)}),r.required.forEach(n=>this._setTriggerRequired(n,!0)),(t.masked||[]).forEach(n=>{r.masked.indexOf(n)===-1&&this._setTriggerMasked(n,!1)}),r.masked.forEach(n=>this._setTriggerMasked(n,!0)),this._triggerApplied={hidden:r.hidden.slice(),disabled:r.disabled.slice(),required:r.required.slice(),masked:r.masked.slice()},this._syncBanners(r.banners),this._syncSubmitBlock(r.blocks),this._syncEnd(r.ends),this._fireTriggerEvents(r)},u.prototype._setTriggerHidden=function(e,r){const t=this._findFieldWrapper(e);t&&(t.classList.toggle("fb-field-trigger-hidden",r),t.setAttribute("aria-hidden",String(r||t.classList.contains("fb-field-hidden"))))},u.prototype._setTriggerMasked=function(e,r){const t=this._findFieldWrapper(e);t&&(t.classList.toggle("fb-field-trigger-masked",r),t.setAttribute("aria-hidden",String(r||t.classList.contains("fb-field-hidden")||t.classList.contains("fb-field-trigger-hidden"))))},u.prototype._setTriggerDisabled=function(e,r){const t=this._findFieldWrapper(e);t&&t.classList.toggle("fb-field-disabled",r),this._fieldInputs(e).forEach(function(i){i.disabled=r});const n=this._wrapper.querySelector('[data-chooser-field="'+e+'"]');n&&(n.classList.toggle("fb-field-disabled",r),n.querySelectorAll('button, [role="radio"], [role="checkbox"]').forEach(function(i){r?i.setAttribute("aria-disabled","true"):i.removeAttribute("aria-disabled")}))},u.prototype._setTriggerRequired=function(e,r){const t=this._fieldInput(e),n=this._findFieldWrapper(e);if(n&&(n.setAttribute("aria-required",String(r)),n.classList.toggle("fb-field-required",r)),!!t){if(/\[\]$/.test(t.name||"")||t.closest&&t.closest(".domma-chooser")){t.removeAttribute("required");return}r?t.setAttribute("required",""):t.removeAttribute("required")}},u.prototype._restoreRequired=function(e,r){const t=this._fields.find(function(n){return n.name===e});t&&this._setTriggerRequired(e,_(t,r))},u.prototype._syncBanners=function(e){const r=new Map;e.forEach(function(t){r.set(t.key,t)}),this._banners.forEach(function(t,n){r.has(n)||(t.parentNode&&t.parentNode.removeChild(t),this._banners.delete(n))},this),this._dismissed.forEach(function(t){r.has(t)||this._dismissed.delete(t)},this),r.forEach(function(t,n){if(this._banners.has(n)){const a=this._banners.get(n).querySelector(".fb-trigger-banner-text");a&&a.textContent!==t.message&&(a.textContent=t.message);return}if(this._dismissed.has(n))return;const i=this._buildBanner(t,n);i&&this._banners.set(n,i)},this)},u.prototype._buildBanner=function(e,r){if(typeof document>"u"||!e.message)return null;const t=document.createElement("div");t.className="fb-trigger-banner fb-trigger-banner--"+(e.level||"info"),t.setAttribute("role",e.level==="error"?"alert":"status"),t.dataset.triggerKey=r;const n=document.createElement("span");if(n.className="fb-trigger-banner-text",n.textContent=e.message,t.appendChild(n),e.dismissible){const a=document.createElement("button");a.type="button",a.className="fb-trigger-banner-close",a.setAttribute("aria-label","Dismiss"),a.textContent="\xD7";const o=this;a.addEventListener("click",function(){o._dismissed.add(r),t.parentNode&&t.parentNode.removeChild(t),o._banners.delete(r)}),t.appendChild(a)}const i=this._findFieldWrapper(e.field),s=this._wrapper.querySelector("form")||this._wrapper;return e.position==="form-top"?s.insertBefore(t,s.firstChild):i&&i.parentNode?e.position==="field-above"?i.parentNode.insertBefore(t,i):i.parentNode.insertBefore(t,i.nextSibling):s.appendChild(t),t},u.prototype._syncSubmitBlock=function(e){const r=this._wrapper.querySelector("form")||this._wrapper,t=r.querySelector('button[type="submit"], input[type="submit"], .fb-form-submit'),n=e.length>0;this._wrapper.dataset.triggerBlocked=n?"true":"false",t&&(t.disabled=n,t.setAttribute("aria-disabled",String(n)));let i=r.querySelector(".fb-trigger-block-note");const s=e.filter(function(a){return!a.quiet}).map(function(a){return a.message});if(!s.length){i&&i.parentNode&&i.parentNode.removeChild(i);return}i||(i=document.createElement("p"),i.className="fb-trigger-block-note",i.setAttribute("role","status"),(t&&t.parentNode?t.parentNode:r).appendChild(i)),i.textContent=s.join(" ")};const j='button[type="submit"], input[type="submit"], .fb-form-submit, .wizard-next, .wizard-submit';u.prototype._primaryButton=function(){return this._wrapper.querySelector(".wizard-next, .wizard-submit")||this._wrapper.querySelector('button[type="submit"], input[type="submit"], .fb-form-submit')};function R(e){return!!(e.matches&&e.matches(".wizard-next, .wizard-submit"))}function B(e,r){e.tagName==="INPUT"?e.value=r:e.textContent=r}return u.prototype._syncEnd=function(e){const r=e&&e.length?e[0]:null,t=this._end;if(t&&(!r||t.spec.key!==r.key)&&(t.panel&&t.panel.parentNode&&t.panel.parentNode.removeChild(t.panel),t.button&&t.button.isConnected&&(t.spec.finish?B(t.button,t.label):R(t.button)&&(t.button.disabled=!1)),this._end=null),this._wrapper.dataset.triggerEnded=r?"true":"false",!r||typeof document>"u")return;if(this._end){const a=this._end.panel&&this._end.panel.querySelector(".fb-trigger-end-text");a&&a.textContent!==r.message&&(a.textContent=r.message),this._end.spec=r;return}let n=null;if(r.message){n=document.createElement("div"),n.className="fb-trigger-end",n.setAttribute("role","status"),n.dataset.triggerKey=r.key;const a=document.createElement("div");a.className="fb-trigger-end-text",a.textContent=r.message,n.appendChild(a);const o=this._findFieldWrapper(r.field);o&&o.parentNode?o.parentNode.insertBefore(n,o.nextSibling):(this._wrapper.querySelector("form")||this._wrapper).appendChild(n)}const i=this._primaryButton();let s="";i&&r.finish?(s=i.tagName==="INPUT"?i.value:i.textContent,B(i,r.finishLabel)):i&&R(i)&&(i.disabled=!0),this._end={spec:r,panel:n,button:i,label:s}},u.prototype._finishEnded=function(){const e=this._triggerState||{},r=new Set([].concat(e.masked||[],e.hidden||[],e.disabled||[])),t=this,n=this._fields.filter(function(a){return k(a)&&!r.has(a.name)&&t._fieldInput(a.name)}),i=this._getValues();(e.masked||[]).forEach(function(a){delete i[a]});const s=M(this._wrapper,n);(e.required||[]).forEach(function(a){const o=n.find(function(f){return f.name===a});if(!o)return;const c=i[a];(Array.isArray(c)?c.length===0:!String(c??"").trim())&&!s.missing.some(function(f){return f.name===a})&&(s.missing.push({name:a,label:o.label||a}),s.valid=!1)}),this._wrapper.dispatchEvent(new CustomEvent("dm-form-end",{bubbles:!0,detail:{values:i,validation:s,end:this._end?this._end.spec:null}}))},u.prototype._fireTriggerEvents=function(e){const r=new Set(e.active),t=this;e.events.forEach(function(n){t._triggerPrev.has(n.key)||n.action.once&&t._triggerFired.has(n.key)||t._initialEval&&n.action.onLoad!==!0||(t._triggerFired.add(n.key),t._runTriggerEvent(n))}),this._triggerPrev=r},u.prototype._runTriggerEvent=function(e){const r=e.action;switch(r.type){case"toast":typeof E<"u"&&E&&typeof E.toast=="function"&&E.toast(r.message||"",{type:r.level||"info",duration:Number(r.duration)||4e3});break;case"celebrate":this._celebrate(r);break;default:break}typeof CustomEvent<"u"&&this._wrapper.dispatchEvent&&this._wrapper.dispatchEvent(new CustomEvent("dm-form-trigger",{bubbles:!0,detail:{type:r.type,field:e.field,action:r}}))},u.prototype._celebrate=function(e){typeof window>"u"||typeof document>"u"||window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches||import("/public/js/celebrations/index.js").then(function(r){const t=r.CelebrationsEffect;let n=e.theme||"auto";if(n==="auto"&&(n=t.getCurrentTheme(),!n))return;const i=new t({theme:n,intensity:e.intensity||"medium",enabled:!0,zIndex:999});i.init().then(function(){i.start()})}).catch(function(){})},u.prototype.submitBlock=function(){const e=this._triggerState&&this._triggerState.blocks||[];return{blocked:e.length>0,reasons:e.map(function(r){return r.message})}},{evaluateCondition:y,evaluateConditionGroup:h,evaluateFieldVisibility:A,evaluateFieldRequirement:_,validateField:x,collectValues:I,validateFields:M,getCascadeOptions:C,resolveTriggerState:L,resolveTriggerTargets:b,hasTriggers:F,TRIGGER_ACTION_KINDS:N,SERVER_TRIGGER_ACTIONS:P,FormLogicRuntime:u}});
package/public/js/site.js CHANGED
@@ -1 +1 @@
1
- import{makeBadgeEl as M,applyColour as O,applyPill as V,applyFloat as J,applyHighlight as N,applyItemHighlight as W,itemHighlightAttrs as G,isCurrentItem as j,menuAlign as X}from"/public/js/menu-decor.mjs?v=20260918-item-highlight";import{initFloatingMenus as Y}from"/public/js/menu-float.js?v=20260829-float-panel";import{enhancePickerFields as B,markInvalidFields as R,showValidationPopup as P}from"/public/js/forms.js?v=20260926-form-end";import{buildWizardSteps as U}from"/public/js/form-steps.mjs";$(()=>{const w=window.__CMS_NAV__||{},g=window.__CMS_SITE__||{};if(g.autoTheme?.enabled){let e=function(t){const c=(t||"07:00").split(":");return+c[0]*60+(+c[1]||0)},n=function(){const t=new Date,c=t.getHours()*60+t.getMinutes();return c>=e(o.dayStart)&&c<e(o.nightStart)?o.dayTheme:o.nightTheme},r=function(t){const c=o.apply&&o.apply[t]||{theme:t,custom:""};Domma.theme.set(c.theme);for(const u of[...document.body.classList])u.startsWith("dm-custom-")&&document.body.classList.remove(u);c.custom&&document.body.classList.add(c.custom)};const o=g.autoTheme;r(n()),setInterval(()=>r(n()),6e4)}const _=$("#site-navbar");if(_.length&&w.brand){let n=function(i,h=0){return Array.isArray(i)?i.filter(s=>!(s&&s.type==="spacer")).filter(s=>!(s&&s.type==="separator"&&h===0)).map(s=>s&&s.type==="separator"?{divider:!0}:Array.isArray(s?.items)?{...s,items:n(s.items,h+1)}:s):i},r=function(i){return Array.isArray(i)?i.filter(h=>!(h&&(h.type==="separator"||h.type==="spacer"))):[]};const o={...w.brand},e=o.size&&o.size!=="md"?` navbar-brand-${o.size}`:"";if(o.logo||o.icon||o.tagline){let i="";o.logo?i+=`<img src="${o.logo}" class="navbar-brand-logo" alt="${o.text||""}">`:o.icon&&(i+=`<span data-icon="${o.icon}" style="width:1.1em;height:1.1em;margin-right:.35em;vertical-align:middle;"></span>`),o.text&&(i+=`<span class="navbar-brand-text${e}">${o.text}</span>`),o.tagline&&(i+=`<small class="navbar-brand-tagline">${o.tagline}</small>`),o.html=i}else e&&o.text&&(o.html=`<span class="navbar-brand-text${e}">${o.text}</span>`);const t=w.position==="floating",c=w.orientation==="vertical";Domma.elements.navbar("#site-navbar",{brand:o,items:n(w.items||[]),variant:w.variant||"dark",position:t?"static":w.position||"sticky",collapsible:!0,appearOnHover:!!w.appearOnHover}),Domma.icons.scan("#site-navbar");const u=_.get(0);u.classList.add(`dm-nav-align-${X(w)||"centre"}`),c&&_.get(0).classList.add("dm-nav-vertical",w.side==="right"?"dm-nav-vertical-right":"dm-nav-vertical-left"),N(u,w),t&&(J(_.get(0),w),Y(_.get(0).parentNode||document));const y=u.querySelector(".navbar-toggle"),p=u.querySelector(".navbar-collapse");if(y&&p){let i=null;const h=()=>{p.classList.contains("show")&&y.click()},s=()=>{i&&(i.remove(),i=null),document.body.classList.remove("dm-drawer-open")},a=()=>{i||(i=document.createElement("div"),i.className="dm-navbar-backdrop",i.addEventListener("click",h),document.body.appendChild(i),document.body.classList.add("dm-drawer-open"))};y.addEventListener("click",()=>{requestAnimationFrame(()=>{p.classList.contains("show")?a():s()})}),p.addEventListener("click",l=>{l.target.closest("a")&&requestAnimationFrame(s)}),document.addEventListener("keydown",l=>{l.key==="Escape"&&p.classList.contains("show")&&h()})}const m=u.querySelector(".navbar-nav");if(m){const i=Array.from(m.children);let h=0;for(const s of w.items||[])if(!(s&&s.type==="separator")){if(s&&s.type==="spacer"){const a=document.createElement("li"),l=["xs","sm","md","lg","xl","flex"].includes(s.size)?s.size:"md";a.className=`dm-menu-spacer dm-menu-spacer--${l}`,a.setAttribute("aria-hidden","true"),m.insertBefore(a,i[h]||null);continue}h++}}const C=r(w.items||[]);u.querySelectorAll(".navbar-link[data-index], .navbar-dropdown-item[data-index]").forEach(i=>{const h=C[parseInt(i.dataset.index,10)];if(!h)return;const s=i.dataset.subindex!=null,a=s&&Array.isArray(h.items)?h.items[parseInt(i.dataset.subindex,10)]:h;if(!a)return;a.colour&&O(i,a.colour),a.pill&&!s&&V(i,a.pill),W(i,a);const l=M(a.badge);l&&i.appendChild(l),j(a.url,location.pathname)&&(i.classList.add("active"),i.setAttribute("aria-current","page"))})}const x=$("#site-footer");if(x.length){let t=function(a){return String(a??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")},c=function(a){return t(a).replace(/'/g,"&#39;")},u=function(a){if(a&&a.type==="separator")return'<li class="footer-sep"><hr></li>';if(a&&a.type==="spacer")return`<li class="dm-menu-spacer dm-menu-spacer--${["xs","sm","md","lg","xl","flex"].includes(a.size)?a.size:"md"}" aria-hidden="true"></li>`;const l=c(a.url||"#"),d=t(a.text||""),b=Array.isArray(a.items)&&a.items.length?`<ul>${a.items.map(u).join("")}</ul>`:"",v=G(a),I=[v.hover&&` data-menu-item-hover="${c(v.hover)}"`,v.active&&` data-menu-item-active="${c(v.active)}"`].filter(Boolean).join(""),D=v.accent?` style="--dm-menu-highlight:${c(v.accent)}"`:"";return`<li><a href="${l}"${I}${D}>${d}</a>${b}</li>`},y=function(a,l){return(a||[]).forEach(d=>{d&&(d.type==="separator"||d.type==="spacer")||(l.push(d),Array.isArray(d.items)&&d.items.length&&y(d.items,l))}),l};const o=g.social||{},e={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 n='<div class="footer-inner container">';const r=window.__CMS_FOOTER__||{primary:[],legal:[],copyright:""};if(r.copyright&&(n+=`<p>${t(r.copyright)}</p>`),r.primary.length&&(n+=`<nav class="footer-nav footer-nav--primary"><ul>${r.primary.map(u).join("")}</ul></nav>`),r.legal.length&&(n+=`<nav class="footer-nav footer-nav--legal"><ul>${r.legal.map(u).join("")}</ul></nav>`),g.footer){const a=Object.keys(e).filter(l=>o[l]);a.length&&(n+='<div class="footer-social">',a.forEach(l=>{const{label:d,svg:b}=e[l];n+=`<a href="${o[l]}" target="_blank" rel="noopener noreferrer" aria-label="${d}" class="footer-social-link">${b}</a>`}),n+="</div>")}n+="</div>",x.html(n);const p=[...y(r.primary,[]),...y(r.legal,[])];x.get(0).querySelectorAll(".footer-nav a").forEach((a,l)=>{const d=p[l];if(!d)return;d.colour&&O(a,d.colour);const b=M(d.badge);b&&a.appendChild(b),j(d.url,location.pathname)&&(a.classList.add("is-active"),a.setAttribute("aria-current","page"))}),N(x.get(0).querySelector(".footer-nav--primary"),{highlight:r.primaryHighlight}),N(x.get(0).querySelector(".footer-nav--legal"),{highlight:r.legalHighlight});const C=g.footer?.showMotionToggle!==!1,i=S.get("reduced_motion"),h=i!==null?!!i:!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches),s=x.get(0).querySelector(".footer-inner");if(C&&s){const a=document.createElement("input");a.type="checkbox",a.className="form-switch-input",a.id="dm-motion-switch",a.checked=h,a.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 d=document.createElement("label");d.className="form-switch footer-motion-switch",d.title="Reduce motion",d.appendChild(a),d.appendChild(l),s.appendChild(d)}}$("#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 o={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 e=parseInt(this.dataset.animationDuration,10);Number.isFinite(e)&&(o.animationDuration=e)}this.dataset.animationEasing&&(o.animationEasing=this.dataset.animationEasing),this.dataset.ctx&&(this._dmCtxSlides=Array.from(this.querySelectorAll(".carousel-slide")).map(e=>e.cloneNode(!0)),this._dmCarouselOpts=o),this._dmCarousel=Domma.elements.carousel(this,o)}),f.find(".dm-countdown").each(function(){const o={autoStart:!0};this.dataset.to&&(o.targetDate=new Date(this.dataset.to)),this.dataset.duration&&(o.duration=parseInt(this.dataset.duration,10)),this.dataset.format&&(o.format=this.dataset.format),Domma.elements.timer(this,o)}),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(){const o=Array.from(this.querySelectorAll(".dm-progression-item")).map(r=>{const t={title:r.querySelector(".dm-progression-item-title")?.textContent?.trim()||"",description:r.querySelector(".dm-progression-item-body")?.innerHTML?.trim()||""};return r.dataset.date&&(t.date=r.dataset.date),r.dataset.status&&(t.status=r.dataset.status),r.dataset.entryId&&(t._entryId=r.dataset.entryId),t}),e=this.dataset.layout==="centred"?"centered":this.dataset.layout||"vertical",n=Domma.elements.progression(this,{layout:e,theme:this.dataset.theme||"minimal",mode:this.dataset.mode||"timeline",statusIcons:!0,allowHtml:!0,...o.length?{items:o}:{}});o.length&&(this._dmCtx={instance:n,items:o})});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(o=>{const e=o.dataset.revealMode||"stagger",n=o.dataset.revealAnimation||"slide-up",r=parseInt(o.dataset.revealDuration,10)||400,t=parseInt(o.dataset.revealStagger,10)||60,c=parseInt(o.dataset.revealDelay,10)||0,u=o.dataset.revealDirection==="rtl",y=Array.from(o.children),p={"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((m,C)=>{m.style.opacity="0",m.style.transform=p[n]||"",m.style.transition=`opacity ${r}ms ease, transform ${r}ms ease`;const i=u?y.length-1-C:C;m.style.transitionDelay=e==="stagger"?`${c+i*t}ms`:`${c}ms`}),requestAnimationFrame(()=>requestAnimationFrame(()=>{const m=new IntersectionObserver(C=>{C.forEach(i=>{i.isIntersecting&&(i.target.offsetWidth,i.target.style.opacity="1",i.target.style.transform="none",m.unobserve(i.target))})},{threshold:.1});y.forEach(C=>m.observe(C))}))}),f.find(".card[data-collapsible]").each(function(){const o=this.querySelector(".card-header");o&&o.addEventListener("click",()=>this.classList.toggle("is-collapsed"))}),f.find(".dm-so-trigger").each(function(){this.addEventListener("click",()=>{const o=this.dataset.soTarget,e=document.getElementById(o);if(!e)return;const n=E.slideover({title:e.dataset.soTitle||"",size:e.dataset.soSize||"md",position:e.dataset.soPosition||"right"});e.style.display="",n.setContent(e),n.open()})})}if(typeof $.setup=="function"){const o=Object.assign({},window.__CMS_DCONFIG__||{});if(document.querySelectorAll(".dm-page-config[data-config]").forEach(e=>{try{const n=atob(e.dataset.config),r=JSON.parse(n);Object.assign(o,r)}catch{}}),Object.keys(o).length>0){const e={};for(const[n,r]of Object.entries(o)){const t=r?.events?.click,{confirm:c,toast:u,alert:y,prompt:p,...m}=t||{};c||u||y||p?($(n).on("click",async function(i){if(i.preventDefault(),c&&!await E.confirm(c))return;let h=null;if(!(p&&(h=await E.prompt(p,{inputPlaceholder:m.promptPlaceholder||"",inputValue:m.promptDefault||""}),h===null))){if(m.target){const s=$(m.target);m.toggleClass&&s.toggleClass(m.toggleClass),m.addClass&&s.addClass(m.addClass),m.removeClass&&s.removeClass(m.removeClass),h!==null&&(m.setText&&s.text(h),m.setVal&&s.val(h),m.setAttr&&s.attr(m.setAttr,h))}m.href&&(window.location.href=m.href),u&&E.toast(u,{type:m.toastType||"success"}),y&&E.alert(y)}}),Object.keys(m).length&&(e[n]={...r,events:{...r.events,click:m}})):e[n]=r}$.setup(e)}}f.length&&q(f.get(0))});function q(w){w.querySelectorAll(".dm-cta-trigger").forEach(g=>{g.__ctaWired||(g.__ctaWired=!0,g.addEventListener("click",async()=>{const _=g.dataset.action,x=g.dataset.entry,A=g.dataset.confirm;let f=S.get("auth_token");if(!f){E.toast("Please log in to perform this action.",{type:"warning"});return}if(A&&!await E.confirm(A))return;const o=Array.from(g.childNodes).map(n=>n.cloneNode(!0));g.disabled=!0,g.textContent="Running\u2026";const e=n=>fetch(`/api/actions/${_}/public`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`},body:JSON.stringify({entryId:x})});try{let n=await e(f);if(n.status===401){const t=S.get("auth_refresh_token");if(t){const c=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:t})});if(c.ok){const{token:u}=await c.json();S.set("auth_token",u),f=u,n=await e(f)}}}const r=await n.json().catch(()=>({}));if(!n.ok)throw new Error(r.error||r.message||`Error ${n.status}`);E.toast(r.message||"Action completed.",{type:"success"})}catch(n){E.toast(n.message||"Action failed.",{type:"error"})}finally{g.disabled=!1,g.textContent="",o.forEach(n=>g.appendChild(n)),Domma.icons.scan(g)}}))})}(function(){const g=document.querySelectorAll('.dm-collection-hydrate[data-collection-scope="mine"]');if(!g.length)return;const _=S.get("auth_token");function x(f,o){const e=document.createElement("div");e.className="dm-collection-display dm-collection-empty";const n=document.createElement("p");if(o){n.appendChild(document.createTextNode("Please "));const r=document.createElement("a");r.href="/login",r.textContent="sign in",n.appendChild(r),n.appendChild(document.createTextNode(" to view your entries."))}else n.textContent=f;return e.appendChild(n),e}function A(f,o){const e=document.createElement("template");e.innerHTML=o||"",f.replaceWith(e.content)}g.forEach(async f=>{const o=f.dataset.collectionAttrs;if(!o)return;if(!_){f.replaceChildren(x("",!0));return}const e=n=>fetch("/api/collections/render-scope",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n}`},body:JSON.stringify({attrs:o})});try{let n=_,r=await e(n);if(r.status===401){const c=S.get("auth_refresh_token");if(c){const u=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:c})});if(u.ok){const{token:y}=await u.json();S.set("auth_token",y),n=y,r=await e(n)}}}if(!r.ok){const{error:c}=await r.json().catch(()=>({}));f.replaceChildren(x(c||"Unable to load entries.",!1));return}const{html:t}=await r.json();A(f,t)}catch{f.replaceChildren(x("Unable to load entries.",!1))}}),setTimeout(()=>{typeof Domma<"u"&&Domma.icons?.scan&&Domma.icons.scan(),typeof Domma<"u"&&Domma.syntax?.scan&&Domma.syntax.scan(),q(document.body)},100)})(),(function(){const g=document.querySelectorAll("[data-collection-table]");!g.length||typeof T>"u"||!T.create||g.forEach(_=>{let x;try{x=JSON.parse(atob(_.dataset.payload))}catch{return}const{columns:A,rows:f,search:o,sortable:e,exportable:n,pageSize:r,empty:t,ctaConfig:c,slug:u,exportCfg:y}=x;if(!A?.length)return;if(c){const C=A.findIndex(i=>i.key==="_cta");C!==-1&&(A[C]={key:"_cta",title:"",render:(i,h)=>{const s=document.createElement("button");if(s.className=`btn btn-${c.style||"primary"} dm-cta-trigger`,s.dataset.action=c.action||"",s.dataset.entry=h._entryId||"",c.confirm&&(s.dataset.confirm=c.confirm),c.icon){const a=document.createElement("span");a.dataset.icon=c.icon,s.appendChild(a),s.appendChild(document.createTextNode(" "))}return s.appendChild(document.createTextNode(c.label||"Run")),s}})}const p="col-table-"+Math.random().toString(36).slice(2,7),m=document.createElement("div");m.id=p,_.replaceChildren(m),T.create("#"+p,{data:f,columns:A,search:o,sortable:e,exportable:n,pageSize:r,emptyMessage:t}),c&&q(m),_._dmTable={columns:A,rows:f,slug:u,exportCfg:y,render(C){T.create("#"+p,{data:C,columns:A,search:o,sortable:e,exportable:n,pageSize:r,emptyMessage:t}),c&&q(m)}}})})(),(function(){const g=document.querySelectorAll("[data-form-inline]");if(!g.length||typeof F>"u")return;function _(e){const n=e&&e.logic;return!!(n&&(n.visibility||n.requirement))}function x(e,n){const r={};return(e||[]).forEach(t=>{if(t.type==="page-break"||t.type==="spacer"||!t.name)return;const c=t.type==="chooser"||!!(t.variant&&["select","radio","checkbox-group"].includes(t.type)),u=t.type==="checkbox"?"boolean":t.type==="date"||t.type==="icon"||t.type==="image"?"string":c?"chooser":t.type,y={...t.formConfig||{}};y.span==="full"&&n&&(y.span=n);const p={type:u,required:_(t)?!1:t.required,label:t.label,options:t.options,formConfig:{...t.placeholder&&{placeholder:t.placeholder},...t.helper&&{hint:t.helper},...y}};c&&(t.variant&&(p.variant=t.variant),(t.multiple||t.type==="checkbox-group")&&(p.multiple=!0),t.density&&(p.density=t.density),t.columns&&(p.columns=t.columns),t.accent&&(p.accent=t.accent),t.accentStyle&&(p.accentStyle=t.accentStyle),t.glow&&(p.glow=!0),t.glowColour&&(p.glowColour=t.glowColour),t.shadow&&(p.shadow=t.shadow),t.shadowColour&&(p.shadowColour=t.shadowColour)),r[t.name]=p}),r}function A(e){const n={};return(e||[]).forEach(r=>{if(!(!r.name||r.type==="page-break"||r.type==="spacer")&&(r.type==="select"||r.type==="multiselect")&&r.required){const t=(r.options||[])[0];t&&(n[r.name]=typeof t=="object"?t.value:t)}}),n}function f(e,n){(n||[]).forEach(r=>{if(r.type!=="date"||!r.name)return;const t=e.querySelector(`[name="${r.name}"]`);t&&t.type!=="date"&&(t.type="date")})}function o(e,n,r){let t=e.querySelector(".cms-form-message");t||(t=document.createElement("p"),t.className="cms-form-message",e.appendChild(t)),t.textContent=n,t.style.cssText=r?"color:var(--dm-danger);margin-top:.75rem;":"color:var(--dm-success);margin-top:.75rem;"}g.forEach(e=>{let n;try{n=JSON.parse(atob(e.dataset.formInline))}catch{return}const r=n.fields||[],t=n.settings||{},c=Number(t.columns)===3?3:2,u=t.layout||"grid",y=r.some(s=>s.type==="page-break"),p=async s=>{if(e.dataset.triggerBlocked==="true"){const a=e._formLogicRuntime,l=a&&a.submitBlock?a.submitBlock().reasons:[];o(e,l.join(" ")||"This form cannot be submitted yet.",!0);const d=new Error("Blocked by a form trigger");throw d.formSubmitFailed=!0,d}try{const a=e.querySelector(".fb-form-honeypot"),l=a?.querySelector('input[type="text"]')||null,d=a?.querySelector('[name="_t"]')||null,b=Object.assign({},s);delete b._t,a?.dataset.hpName&&delete b[a.dataset.hpName],l!==null&&(b._hp=l.value),d!==null&&(b._t=d.value);const v=await H.post(`/api/forms/submit/${n.slug}`,b);if(v&&v.error){o(e,v.error,!0);const I=new Error(v.error);throw I.formSubmitFailed=!0,I}if(v?.redirect){window.location.href=v.redirect;return}for(;e.firstChild;)e.removeChild(e.firstChild);o(e,v?.message||t.successMessage||"Thank you for your submission.",!1)}catch(a){throw a.formSubmitFailed||o(e,a.message||"Submission failed. Please try again.",!0),a}},m=Date.now();function C(s){const a=s.querySelector("form");if(!a||a.querySelector(".fb-form-honeypot"))return;const l=document.createElement("div");l.className="fb-form-honeypot",l.setAttribute("aria-hidden","true");const d=document.createElement("input");d.name=a.querySelector('[name="website"]')?"_website":"website",l.dataset.hpName=d.name,d.type="text",d.tabIndex=-1,d.autocomplete="url",d.placeholder="https://",l.appendChild(d);const b=document.createElement("input");b.name="_t",b.type="hidden",b.value=m,l.appendChild(b),a.appendChild(l)}function i(s){if(!window.FormLogicEngine||!r.some(l=>l.logic||Array.isArray(l.triggers)&&l.triggers.length))return null;const a=new window.FormLogicEngine.FormLogicRuntime(n,e,s?{baseValues:s}:void 0);if(a.init(),e._formLogicRuntime=a,e._formLogicObserved)return a;if(e._formLogicObserved=!0,e.parentNode&&typeof MutationObserver<"u"){const l=new MutationObserver(function(d){for(const b of d)for(const v of b.removedNodes)if(v===e||v.nodeType===1&&v.contains&&v.contains(e)){e._formLogicRuntime&&e._formLogicRuntime.destroy(),l.disconnect();return}});l.observe(e.parentNode,{childList:!0,subtree:!1}),e._formLogicObserver=l}return a}let h=!1;if(e.addEventListener("dm-form-end",s=>{const a=s.detail?.validation;if(a&&!a.valid){R(e,a.missing),P(a);return}h||(h=!0,p(s.detail?.values||{}).catch(()=>{}).finally(()=>{h=!1}))}),y&&F.wizard){const s=U(r,n.title),a=s.map(k=>({title:k.title,description:k.description,fields:x(k.fields,c)})),l=s.map(k=>k.fields);let d=0,b=null,v=null;const I=k=>{const L=window.FormLogicEngine;if(!L||!L.validateFields)return;const z=L.validateFields(e,l[d]||[]);z.valid||(k.preventDefault(),k.stopImmediatePropagation(),R(e,z.missing),P(z))},D=()=>{const k=l[d]||r;f(e,k),B(e,k),t.honeypot!==!1&&C(e),b&&b.destroy(),b=i(v?.getStepData?v.getStepData():void 0),e.querySelectorAll(".wizard-next, .wizard-submit").forEach(L=>L.addEventListener("click",I,!0))};v=F.wizard(e,{schema:{steps:a},layout:u,columns:c,finishText:t.submitText||"Finish",onSubmit:p,onStepChange:k=>{d=k,setTimeout(D,0)}}),e.addEventListener("dm-form-trigger",k=>{if(k.detail?.type!=="goto-step"||!v?.goToStep)return;const L=Number(k.detail.action.step);!Number.isFinite(L)||L<0||L>=a.length||L!==d&&v.goToStep(L)}),Promise.resolve(v).then(D)}else if(F.render){const s=F.render(e,x(r,c),A(r),{submitText:t.submitText||"Submit",layout:u,columns:c,onSubmit:p});Promise.resolve(s).then(function(){if(u==="grid"&&t.submitSpan==="full"){const a=e.querySelector(".form-buttons");a&&a.classList.add("col-span-full")}f(e,r),B(e,r),t.honeypot!==!1&&C(e),i()})}}),$(document).on("click",".dm-banner__dismiss",function(){$(this).closest(".dm-banner").remove()})})();
1
+ import{makeBadgeEl as M,applyColour as O,applyPill as V,applyFloat as J,applyHighlight as N,applyItemHighlight as W,itemHighlightAttrs as G,isCurrentItem as j,menuAlign as X}from"/public/js/menu-decor.mjs?v=20260918-item-highlight";import{initFloatingMenus as Y}from"/public/js/menu-float.js?v=20260829-float-panel";import{enhancePickerFields as B,markInvalidFields as R,showValidationPopup as P}from"/public/js/forms.js?v=20260926-form-end";import{buildWizardSteps as U}from"/public/js/form-steps.mjs";$(()=>{const w=window.__CMS_NAV__||{},g=window.__CMS_SITE__||{};if(g.autoTheme?.enabled){let t=function(e){const c=(e||"07:00").split(":");return+c[0]*60+(+c[1]||0)},o=function(){const e=new Date,c=e.getHours()*60+e.getMinutes();return c>=t(n.dayStart)&&c<t(n.nightStart)?n.dayTheme:n.nightTheme},i=function(e){const c=n.apply&&n.apply[e]||{theme:e,custom:""};Domma.theme.set(c.theme);for(const p of[...document.body.classList])p.startsWith("dm-custom-")&&document.body.classList.remove(p);c.custom&&document.body.classList.add(c.custom)};const n=g.autoTheme;i(o()),setInterval(()=>i(o()),6e4)}const _=$("#site-navbar");if(_.length&&w.brand){let o=function(s,h=0){return Array.isArray(s)?s.filter(r=>!(r&&r.type==="spacer")).filter(r=>!(r&&r.type==="separator"&&h===0)).map(r=>r&&r.type==="separator"?{divider:!0}:Array.isArray(r?.items)?{...r,items:o(r.items,h+1)}:r):s},i=function(s){return Array.isArray(s)?s.filter(h=>!(h&&(h.type==="separator"||h.type==="spacer"))):[]};const n={...w.brand},t=n.size&&n.size!=="md"?` navbar-brand-${n.size}`:"";if(n.logo||n.icon||n.tagline){let s="";n.logo?s+=`<img src="${n.logo}" class="navbar-brand-logo" alt="${n.text||""}">`:n.icon&&(s+=`<span data-icon="${n.icon}" style="width:1.1em;height:1.1em;margin-right:.35em;vertical-align:middle;"></span>`),n.text&&(s+=`<span class="navbar-brand-text${t}">${n.text}</span>`),n.tagline&&(s+=`<small class="navbar-brand-tagline">${n.tagline}</small>`),n.html=s}else t&&n.text&&(n.html=`<span class="navbar-brand-text${t}">${n.text}</span>`);const e=w.position==="floating",c=w.orientation==="vertical";Domma.elements.navbar("#site-navbar",{brand:n,items:o(w.items||[]),variant:w.variant||"dark",position:e?"static":w.position||"sticky",collapsible:!0,appearOnHover:!!w.appearOnHover}),Domma.icons.scan("#site-navbar");const p=_.get(0);p.classList.add(`dm-nav-align-${X(w)||"centre"}`),c&&_.get(0).classList.add("dm-nav-vertical",w.side==="right"?"dm-nav-vertical-right":"dm-nav-vertical-left"),N(p,w),e&&(J(_.get(0),w),Y(_.get(0).parentNode||document));const y=p.querySelector(".navbar-toggle"),u=p.querySelector(".navbar-collapse");if(y&&u){let s=null;const h=()=>{u.classList.contains("show")&&y.click()},r=()=>{s&&(s.remove(),s=null),document.body.classList.remove("dm-drawer-open")},a=()=>{s||(s=document.createElement("div"),s.className="dm-navbar-backdrop",s.addEventListener("click",h),document.body.appendChild(s),document.body.classList.add("dm-drawer-open"))};y.addEventListener("click",()=>{requestAnimationFrame(()=>{u.classList.contains("show")?a():r()})}),u.addEventListener("click",l=>{l.target.closest("a")&&requestAnimationFrame(r)}),document.addEventListener("keydown",l=>{l.key==="Escape"&&u.classList.contains("show")&&h()})}const m=p.querySelector(".navbar-nav");if(m){const s=Array.from(m.children);let h=0;for(const r of w.items||[])if(!(r&&r.type==="separator")){if(r&&r.type==="spacer"){const a=document.createElement("li"),l=["xs","sm","md","lg","xl","flex"].includes(r.size)?r.size:"md";a.className=`dm-menu-spacer dm-menu-spacer--${l}`,a.setAttribute("aria-hidden","true"),m.insertBefore(a,s[h]||null);continue}h++}}const C=i(w.items||[]);p.querySelectorAll(".navbar-link[data-index], .navbar-dropdown-item[data-index]").forEach(s=>{const h=C[parseInt(s.dataset.index,10)];if(!h)return;const r=s.dataset.subindex!=null,a=r&&Array.isArray(h.items)?h.items[parseInt(s.dataset.subindex,10)]:h;if(!a)return;a.colour&&O(s,a.colour),a.pill&&!r&&V(s,a.pill),W(s,a);const l=M(a.badge);l&&s.appendChild(l),j(a.url,location.pathname)&&(s.classList.add("active"),s.setAttribute("aria-current","page"))})}const x=$("#site-footer");if(x.length){let e=function(a){return String(a??"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")},c=function(a){return e(a).replace(/'/g,"&#39;")},p=function(a){if(a&&a.type==="separator")return'<li class="footer-sep"><hr></li>';if(a&&a.type==="spacer")return`<li class="dm-menu-spacer dm-menu-spacer--${["xs","sm","md","lg","xl","flex"].includes(a.size)?a.size:"md"}" aria-hidden="true"></li>`;const l=c(a.url||"#"),d=e(a.text||""),b=Array.isArray(a.items)&&a.items.length?`<ul>${a.items.map(p).join("")}</ul>`:"",v=G(a),I=[v.hover&&` data-menu-item-hover="${c(v.hover)}"`,v.active&&` data-menu-item-active="${c(v.active)}"`].filter(Boolean).join(""),D=v.accent?` style="--dm-menu-highlight:${c(v.accent)}"`:"";return`<li><a href="${l}"${I}${D}>${d}</a>${b}</li>`},y=function(a,l){return(a||[]).forEach(d=>{d&&(d.type==="separator"||d.type==="spacer")||(l.push(d),Array.isArray(d.items)&&d.items.length&&y(d.items,l))}),l};const n=g.social||{},t={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 o='<div class="footer-inner container">';const i=window.__CMS_FOOTER__||{primary:[],legal:[],copyright:""};if(i.copyright&&(o+=`<p>${e(i.copyright)}</p>`),i.primary.length&&(o+=`<nav class="footer-nav footer-nav--primary"><ul>${i.primary.map(p).join("")}</ul></nav>`),i.legal.length&&(o+=`<nav class="footer-nav footer-nav--legal"><ul>${i.legal.map(p).join("")}</ul></nav>`),g.footer){const a=Object.keys(t).filter(l=>n[l]);a.length&&(o+='<div class="footer-social">',a.forEach(l=>{const{label:d,svg:b}=t[l];o+=`<a href="${n[l]}" target="_blank" rel="noopener noreferrer" aria-label="${d}" class="footer-social-link">${b}</a>`}),o+="</div>")}o+="</div>",x.html(o);const u=[...y(i.primary,[]),...y(i.legal,[])];x.get(0).querySelectorAll(".footer-nav a").forEach((a,l)=>{const d=u[l];if(!d)return;d.colour&&O(a,d.colour);const b=M(d.badge);b&&a.appendChild(b),j(d.url,location.pathname)&&(a.classList.add("is-active"),a.setAttribute("aria-current","page"))}),N(x.get(0).querySelector(".footer-nav--primary"),{highlight:i.primaryHighlight}),N(x.get(0).querySelector(".footer-nav--legal"),{highlight:i.legalHighlight});const C=g.footer?.showMotionToggle!==!1,s=S.get("reduced_motion"),h=s!==null?!!s:!!(window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches),r=x.get(0).querySelector(".footer-inner");if(C&&r){const a=document.createElement("input");a.type="checkbox",a.className="form-switch-input",a.id="dm-motion-switch",a.checked=h,a.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 d=document.createElement("label");d.className="form-switch footer-motion-switch",d.title="Reduce motion",d.appendChild(a),d.appendChild(l),r.appendChild(d)}}$("#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 n={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 t=parseInt(this.dataset.animationDuration,10);Number.isFinite(t)&&(n.animationDuration=t)}this.dataset.animationEasing&&(n.animationEasing=this.dataset.animationEasing),this.dataset.ctx&&(this._dmCtxSlides=Array.from(this.querySelectorAll(".carousel-slide")).map(t=>t.cloneNode(!0)),this._dmCarouselOpts=n),this._dmCarousel=Domma.elements.carousel(this,n)}),f.find(".dm-countdown").each(function(){const n={autoStart:!0};this.dataset.to&&(n.targetDate=new Date(this.dataset.to)),this.dataset.duration&&(n.duration=parseInt(this.dataset.duration,10)),this.dataset.format&&(n.format=this.dataset.format),Domma.elements.timer(this,n)}),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(){const n=Array.from(this.querySelectorAll(".dm-progression-item")).map(i=>{const e={title:i.querySelector(".dm-progression-item-title")?.textContent?.trim()||"",description:i.querySelector(".dm-progression-item-body")?.innerHTML?.trim()||""};return i.dataset.date&&(e.date=i.dataset.date),i.dataset.status&&(e.status=i.dataset.status),i.dataset.entryId&&(e._entryId=i.dataset.entryId),e}),t=this.dataset.layout==="centred"?"centered":this.dataset.layout||"vertical",o=Domma.elements.progression(this,{layout:t,theme:this.dataset.theme||"minimal",mode:this.dataset.mode||"timeline",statusIcons:!0,allowHtml:!0,...n.length?{items:n}:{}});n.length&&(this._dmCtx={instance:o,items:n})});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(n=>{const t=n.dataset.revealMode||"stagger",o=n.dataset.revealAnimation||"slide-up",i=parseInt(n.dataset.revealDuration,10)||400,e=parseInt(n.dataset.revealStagger,10)||60,c=parseInt(n.dataset.revealDelay,10)||0,p=n.dataset.revealDirection==="rtl",y=Array.from(n.children),u={"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((m,C)=>{m.style.opacity="0",m.style.transform=u[o]||"",m.style.transition=`opacity ${i}ms ease, transform ${i}ms ease`;const s=p?y.length-1-C:C;m.style.transitionDelay=t==="stagger"?`${c+s*e}ms`:`${c}ms`}),requestAnimationFrame(()=>requestAnimationFrame(()=>{const m=new IntersectionObserver(C=>{C.forEach(s=>{s.isIntersecting&&(s.target.offsetWidth,s.target.style.opacity="1",s.target.style.transform="none",m.unobserve(s.target))})},{threshold:.1});y.forEach(C=>m.observe(C))}))}),f.find(".card[data-collapsible]").each(function(){const n=this.querySelector(".card-header");n&&n.addEventListener("click",()=>this.classList.toggle("is-collapsed"))}),f.find(".dm-so-trigger").each(function(){this.addEventListener("click",()=>{const n=this.dataset.soTarget,t=document.getElementById(n);if(!t)return;const o=E.slideover({title:t.dataset.soTitle||"",size:t.dataset.soSize||"md",position:t.dataset.soPosition||"right"});t.style.display="",o.setContent(t),o.open()})})}if(typeof $.setup=="function"){const n=Object.assign({},window.__CMS_DCONFIG__||{});if(document.querySelectorAll(".dm-page-config[data-config]").forEach(t=>{try{const o=atob(t.dataset.config),i=JSON.parse(o);Object.assign(n,i)}catch{}}),Object.keys(n).length>0){const t={};for(const[o,i]of Object.entries(n)){const e=i?.events?.click,{confirm:c,toast:p,alert:y,prompt:u,...m}=e||{};c||p||y||u?($(o).on("click",async function(s){if(s.preventDefault(),c&&!await E.confirm(c))return;let h=null;if(!(u&&(h=await E.prompt(u,{inputPlaceholder:m.promptPlaceholder||"",inputValue:m.promptDefault||""}),h===null))){if(m.target){const r=$(m.target);m.toggleClass&&r.toggleClass(m.toggleClass),m.addClass&&r.addClass(m.addClass),m.removeClass&&r.removeClass(m.removeClass),h!==null&&(m.setText&&r.text(h),m.setVal&&r.val(h),m.setAttr&&r.attr(m.setAttr,h))}m.href&&(window.location.href=m.href),p&&E.toast(p,{type:m.toastType||"success"}),y&&E.alert(y)}}),Object.keys(m).length&&(t[o]={...i,events:{...i.events,click:m}})):t[o]=i}$.setup(t)}}f.length&&q(f.get(0))});function q(w){w.querySelectorAll(".dm-cta-trigger").forEach(g=>{g.__ctaWired||(g.__ctaWired=!0,g.addEventListener("click",async()=>{const _=g.dataset.action,x=g.dataset.entry,A=g.dataset.confirm;let f=S.get("auth_token");if(!f){E.toast("Please log in to perform this action.",{type:"warning"});return}if(A&&!await E.confirm(A))return;const n=Array.from(g.childNodes).map(o=>o.cloneNode(!0));g.disabled=!0,g.textContent="Running\u2026";const t=o=>fetch(`/api/actions/${_}/public`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},body:JSON.stringify({entryId:x})});try{let o=await t(f);if(o.status===401){const e=S.get("auth_refresh_token");if(e){const c=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:e})});if(c.ok){const{token:p}=await c.json();S.set("auth_token",p),f=p,o=await t(f)}}}const i=await o.json().catch(()=>({}));if(!o.ok)throw new Error(i.error||i.message||`Error ${o.status}`);E.toast(i.message||"Action completed.",{type:"success"})}catch(o){E.toast(o.message||"Action failed.",{type:"error"})}finally{g.disabled=!1,g.textContent="",n.forEach(o=>g.appendChild(o)),Domma.icons.scan(g)}}))})}(function(){const g=document.querySelectorAll('.dm-collection-hydrate[data-collection-scope="mine"]');if(!g.length)return;const _=S.get("auth_token");function x(f,n){const t=document.createElement("div");t.className="dm-collection-display dm-collection-empty";const o=document.createElement("p");if(n){o.appendChild(document.createTextNode("Please "));const i=document.createElement("a");i.href="/login",i.textContent="sign in",o.appendChild(i),o.appendChild(document.createTextNode(" to view your entries."))}else o.textContent=f;return t.appendChild(o),t}function A(f,n){const t=document.createElement("template");t.innerHTML=n||"",f.replaceWith(t.content)}g.forEach(async f=>{const n=f.dataset.collectionAttrs;if(!n)return;if(!_){f.replaceChildren(x("",!0));return}const t=o=>fetch("/api/collections/render-scope",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`},body:JSON.stringify({attrs:n})});try{let o=_,i=await t(o);if(i.status===401){const c=S.get("auth_refresh_token");if(c){const p=await fetch("/api/auth/refresh",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:c})});if(p.ok){const{token:y}=await p.json();S.set("auth_token",y),o=y,i=await t(o)}}}if(!i.ok){const{error:c}=await i.json().catch(()=>({}));f.replaceChildren(x(c||"Unable to load entries.",!1));return}const{html:e}=await i.json();A(f,e)}catch{f.replaceChildren(x("Unable to load entries.",!1))}}),setTimeout(()=>{typeof Domma<"u"&&Domma.icons?.scan&&Domma.icons.scan(),typeof Domma<"u"&&Domma.syntax?.scan&&Domma.syntax.scan(),q(document.body)},100)})(),(function(){const g=document.querySelectorAll("[data-collection-table]");!g.length||typeof T>"u"||!T.create||g.forEach(_=>{let x;try{x=JSON.parse(atob(_.dataset.payload))}catch{return}const{columns:A,rows:f,search:n,sortable:t,exportable:o,pageSize:i,empty:e,ctaConfig:c,slug:p,exportCfg:y}=x;if(!A?.length)return;if(c){const C=A.findIndex(s=>s.key==="_cta");C!==-1&&(A[C]={key:"_cta",title:"",render:(s,h)=>{const r=document.createElement("button");if(r.className=`btn btn-${c.style||"primary"} dm-cta-trigger`,r.dataset.action=c.action||"",r.dataset.entry=h._entryId||"",c.confirm&&(r.dataset.confirm=c.confirm),c.icon){const a=document.createElement("span");a.dataset.icon=c.icon,r.appendChild(a),r.appendChild(document.createTextNode(" "))}return r.appendChild(document.createTextNode(c.label||"Run")),r}})}const u="col-table-"+Math.random().toString(36).slice(2,7),m=document.createElement("div");m.id=u,_.replaceChildren(m),T.create("#"+u,{data:f,columns:A,search:n,sortable:t,exportable:o,pageSize:i,emptyMessage:e}),c&&q(m),_._dmTable={columns:A,rows:f,slug:p,exportCfg:y,render(C){T.create("#"+u,{data:C,columns:A,search:n,sortable:t,exportable:o,pageSize:i,emptyMessage:e}),c&&q(m)}}})})(),(function(){const g=document.querySelectorAll("[data-form-inline]");if(!g.length||typeof F>"u")return;function _(t){const o=t&&t.logic;return!!(o&&(o.visibility||o.requirement))}function x(t,o){const i={};return(t||[]).forEach(e=>{if(e.type==="page-break"||e.type==="spacer"||!e.name)return;const c=e.type==="chooser"||!!(e.variant&&["select","radio","checkbox-group"].includes(e.type)),p=e.type==="checkbox"?"boolean":e.type==="date"||e.type==="icon"||e.type==="image"?"string":c?"chooser":e.type,y={...e.formConfig||{}};y.span==="full"&&o&&(y.span=o);const u={type:p,required:_(e)?!1:e.required,label:e.label,options:e.options,formConfig:{...e.placeholder&&{placeholder:e.placeholder},...e.helper&&{hint:e.helper},...e.tooltip&&{tooltip:e.tooltip},...y}};e.minLength!==void 0&&(u.minLength=e.minLength),e.maxLength!==void 0&&(u.maxLength=e.maxLength),e.min!==void 0&&(u.min=e.min),e.max!==void 0&&(u.max=e.max),c&&(e.variant&&(u.variant=e.variant),(e.multiple||e.type==="checkbox-group")&&(u.multiple=!0),e.density&&(u.density=e.density),e.columns&&(u.columns=e.columns),e.accent&&(u.accent=e.accent),e.accentStyle&&(u.accentStyle=e.accentStyle),e.glow&&(u.glow=!0),e.glowColour&&(u.glowColour=e.glowColour),e.shadow&&(u.shadow=e.shadow),e.shadowColour&&(u.shadowColour=e.shadowColour)),i[e.name]=u}),i}function A(t){const o={};return(t||[]).forEach(i=>{if(!(!i.name||i.type==="page-break"||i.type==="spacer")&&(i.type==="select"||i.type==="multiselect")&&i.required){const e=(i.options||[])[0];e&&(o[i.name]=typeof e=="object"?e.value:e)}}),o}function f(t,o){(o||[]).forEach(i=>{if(i.type!=="date"||!i.name)return;const e=t.querySelector(`[name="${i.name}"]`);e&&e.type!=="date"&&(e.type="date")})}function n(t,o,i){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=i?"color:var(--dm-danger);margin-top:.75rem;":"color:var(--dm-success);margin-top:.75rem;"}g.forEach(t=>{let o;try{o=JSON.parse(atob(t.dataset.formInline))}catch{return}const i=o.fields||[],e=o.settings||{},c=Number(e.columns)===3?3:2,p=e.layout||"grid",y=i.some(r=>r.type==="page-break"),u=async r=>{if(t.dataset.triggerBlocked==="true"){const a=t._formLogicRuntime,l=a&&a.submitBlock?a.submitBlock().reasons:[];n(t,l.join(" ")||"This form cannot be submitted yet.",!0);const d=new Error("Blocked by a form trigger");throw d.formSubmitFailed=!0,d}try{const a=t.querySelector(".fb-form-honeypot"),l=a?.querySelector('input[type="text"]')||null,d=a?.querySelector('[name="_t"]')||null,b=Object.assign({},r);delete b._t,a?.dataset.hpName&&delete b[a.dataset.hpName],l!==null&&(b._hp=l.value),d!==null&&(b._t=d.value);const v=await H.post(`/api/forms/submit/${o.slug}`,b);if(v&&v.error){n(t,v.error,!0);const I=new Error(v.error);throw I.formSubmitFailed=!0,I}if(v?.redirect){window.location.href=v.redirect;return}for(;t.firstChild;)t.removeChild(t.firstChild);n(t,v?.message||e.successMessage||"Thank you for your submission.",!1)}catch(a){throw a.formSubmitFailed||n(t,a.message||"Submission failed. Please try again.",!0),a}},m=Date.now();function C(r){const a=r.querySelector("form");if(!a||a.querySelector(".fb-form-honeypot"))return;const l=document.createElement("div");l.className="fb-form-honeypot",l.setAttribute("aria-hidden","true");const d=document.createElement("input");d.name=a.querySelector('[name="website"]')?"_website":"website",l.dataset.hpName=d.name,d.type="text",d.tabIndex=-1,d.autocomplete="url",d.placeholder="https://",l.appendChild(d);const b=document.createElement("input");b.name="_t",b.type="hidden",b.value=m,l.appendChild(b),a.appendChild(l)}function s(r){if(!window.FormLogicEngine||!i.some(l=>l.logic||Array.isArray(l.triggers)&&l.triggers.length))return null;const a=new window.FormLogicEngine.FormLogicRuntime(o,t,r?{baseValues:r}:void 0);if(a.init(),t._formLogicRuntime=a,t._formLogicObserved)return a;if(t._formLogicObserved=!0,t.parentNode&&typeof MutationObserver<"u"){const l=new MutationObserver(function(d){for(const b of d)for(const v of b.removedNodes)if(v===t||v.nodeType===1&&v.contains&&v.contains(t)){t._formLogicRuntime&&t._formLogicRuntime.destroy(),l.disconnect();return}});l.observe(t.parentNode,{childList:!0,subtree:!1}),t._formLogicObserver=l}return a}let h=!1;if(t.addEventListener("dm-form-end",r=>{const a=r.detail?.validation;if(a&&!a.valid){R(t,a.missing),P(a);return}h||(h=!0,u(r.detail?.values||{}).catch(()=>{}).finally(()=>{h=!1}))}),y&&F.wizard){const r=U(i,o.title),a=r.map(k=>({title:k.title,description:k.description,fields:x(k.fields,c)})),l=r.map(k=>k.fields);let d=0,b=null,v=null;const I=k=>{const L=window.FormLogicEngine;if(!L||!L.validateFields)return;const z=L.validateFields(t,l[d]||[]);z.valid||(k.preventDefault(),k.stopImmediatePropagation(),R(t,z.missing),P(z))},D=()=>{const k=l[d]||i;f(t,k),B(t,k),e.honeypot!==!1&&C(t),b&&b.destroy(),b=s(v?.getStepData?v.getStepData():void 0),t.querySelectorAll(".wizard-next, .wizard-submit").forEach(L=>L.addEventListener("click",I,!0))};v=F.wizard(t,{schema:{steps:a},layout:p,columns:c,finishText:e.submitText||"Finish",onSubmit:u,onStepChange:k=>{d=k,setTimeout(D,0)}}),t.addEventListener("dm-form-trigger",k=>{if(k.detail?.type!=="goto-step"||!v?.goToStep)return;const L=Number(k.detail.action.step);!Number.isFinite(L)||L<0||L>=a.length||L!==d&&v.goToStep(L)}),Promise.resolve(v).then(D)}else if(F.render){const r=F.render(t,x(i,c),A(i),{submitText:e.submitText||"Submit",layout:p,columns:c,onSubmit:u});Promise.resolve(r).then(function(){if(p==="grid"&&e.submitSpan==="full"){const a=t.querySelector(".form-buttons");a&&a.classList.add("col-span-full")}f(t,i),B(t,i),e.honeypot!==!1&&C(t),s()})}}),$(document).on("click",".dm-banner__dismiss",function(){$(this).closest(".dm-banner").remove()})})();
@@ -136,7 +136,7 @@
136
136
  </script>
137
137
 
138
138
  <!-- Site initialisation -->
139
- <script src="/public/js/site.js?v=20260926-form-end-embed" type="module"></script>
139
+ <script src="/public/js/site.js?v=20260926-field-limits" type="module"></script>
140
140
  <script src="/public/js/collection-context.js?v=20260919-ctx-tokens" type="module"></script>
141
141
  {{ctxMenusModule}}
142
142
 
@@ -150,7 +150,7 @@
150
150
  <script src="/public/js/collection-browser.js?v=20260523-browser"></script>
151
151
 
152
152
  <!-- Core Forms (logic engine must load before renderer) -->
153
- <script src="/public/js/form-logic-engine.js?v=20260926-end-no-finish"></script>
153
+ <script src="/public/js/form-logic-engine.js?v=20260926-limits"></script>
154
154
  <script src="/public/js/forms.js?v=20260926-form-end" type="module"></script>
155
155
 
156
156
  <!-- Core effects runtime -->