formique 1.0.12 → 1.2.0

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/formique.umd.js CHANGED
@@ -1 +1 @@
1
- !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e="undefined"!=typeof globalThis?globalThis:e||self).Formique=n()}(this,(function(){"use strict";class e{renderField(e,n,t,i,s,r){throw new Error("Method renderField must be implemented")}}return class extends e{constructor(e,n={},t={}){super(),this.formSchema=e,this.formParams=t,this.formSettings={requiredFieldIndicator:!0,placeholders:!0,asteriskHtml:'<span aria-hidden="true" style="color: red;">*</span>',...n},this.themeColor=n.themeColor||null,this.themeColorMap={primary:{"--formique-base-bg":"#ffffff","--formique-base-text":"#333333","--formique-base-shadow":"0 10px 30px rgba(0, 0, 0, 0.1)","--formique-base-label":"#555555","--formique-input-border":"#dddddd","--formique-focus-color":null,"--formique-btn-bg":null,"--formique-btn-text":"#ffffff","--formique-btn-shadow":null}},this.divClass="input-block",this.inputClass="form-input",this.radioGroupClass="radio-group",this.checkboxGroupClass="checkbox-group",this.selectGroupClass="form-select",this.submitButtonClass="form-submit-btn",this.formContainerId=n?.formContainerId||"formique",this.formId=this.formParams?.id||this.generateFormId(),this.formAction=t?.action||"https://httpbin.org/post",this.method="POST",this.formMarkUp="",this.dependencyGraph={},this.redirect=n?.redirect||"",this.redirectURL=n?.redirectURL||"",this.themes=["dark","light","pink","indigo","dark-blue","light-blue","dark-orange","bright-yellow","green","purple","midnight-blush","deep-blue","blue","brown","orange"],this.formiqueEndpoint="https://formiqueapi.onrender.com/api/send-email",document.addEventListener("DOMContentLoaded",(()=>{this.formMarkUp+=this.renderFormElement();const e=this.formSchema.filter((e=>"submit"!==e[0])).map((e=>{const[n,t,i,s,r={},l]=e;return this.renderField(n,t,i,s,r,l)})).join("");this.formMarkUp+=e;const n=this.formSchema.find((e=>"submit"===e[0]));if(n){const[e,t,i,s,r={}]=n,l=r.id||t;let a=this.submitButtonClass;"class"in r&&(a=r.class);let o="";for(const[e,n]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){o+=` ${e}="${n.endsWith("()")?n:`${n}()`}"`}else!0===n?o+=` ${e.replace(/_/g,"-")}`:!1!==n&&(o+=` ${e.replace(/_/g,"-")}="${n}"`);this.formMarkUp+=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n </div>\n <input type="submit" id="${l}" class="${a}" value="${i}"${o}>\n `}this.renderFormHTML();const t=document.getElementById(`${this.formId}`);if(t?t.addEventListener("submit",function(e){"email"===this.formSettings.submitMode&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleEmailSubmission(this.formId)),this.formSettings.submitOnPage&&(e.preventDefault(),document.getElementById("formiqueSpinner").style.display="block",this.handleOnPageFormSubmission(this.formId))}.bind(this)):console.error(`Form with ID ${this.formId} not found after rendering. Event listener could not be attached.`),this.initDependencyGraph(),this.registerObservers(),this.attachDynamicSelectListeners(),this.themeColor)this.applyCustomTheme(this.themeColor,this.formContainerId);else if(this.formSettings.theme&&this.themes.includes(this.formSettings.theme)){let e=this.formSettings.theme;this.applyTheme(e,this.formContainerId)}else this.applyTheme("dark",this.formContainerId)}))}generateFormId(){return`fmq-${Math.random().toString(36).substr(2,10)}`}initDependencyGraph(){this.dependencyGraph={},this.formSchema.forEach((e=>{const[n,t,i,s,r={}]=e,l=r.id||t;r.dependents&&(this.dependencyGraph[l]=r.dependents.map((e=>{const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]||{};return{dependent:t.id||e,condition:t.condition||null}}console.warn(`Dependent field "${e}" not found in schema.`)})),this.dependencyGraph[l].push({state:null}),this.attachInputChangeListener(l)),r.dependents&&r.dependents.forEach((e=>{const n=this.formSchema.find((([,n])=>n===e)),t=(n&&n[4]||{}).id||e,i=document.querySelector(`#${t}-block`);if(i){i.style.display="none";i.querySelectorAll("input, select, textarea").forEach((e=>{e.hasAttribute("required")&&!0===e.required?(e.setAttribute("data-original-required","true"),e.required=!1):e.setAttribute("data-original-required","false")}))}}))}))}attachInputChangeListener(e){const n=document.getElementById(e);n&&n.addEventListener("input",(n=>{const t=n.target.value;this.handleParentFieldChange(e,t)}))}handleParentFieldChange(e,n){const t=this.dependencyGraph[e];t&&(this.dependencyGraph[e].forEach((e=>{void 0!==e.state&&(e.state=n)})),t.forEach((e=>{if(e.dependent){const t=e.dependent+"-block",i=document.getElementById(t);if(i){const t="function"==typeof e.condition?e.condition(n):n===e.condition;i.style.display=t?"block":"none";i.querySelectorAll("input, select, textarea").forEach((e=>{t?e.required="true"===e.getAttribute("data-original-required"):(e.setAttribute("data-original-required",e.required),e.required=!1)}))}else console.warn(`Wrapper block with ID ${t} not found.`)}})))}registerObservers(){this.formSchema.forEach((e=>{const[n,t,i,s,r={}]=e,l=r.id||t;r.dependents&&r.dependents.forEach((e=>{if(this.dependencyGraph[l]){const n=this.formSchema.find((([,n])=>n===e));if(n){const t=n[4]?.id||e;this.dependencyGraph[l].forEach((n=>{n.dependent===e&&(n.observers||(n.observers=[]),n.observers.push(t))}))}}}))}))}attachDynamicSelectListeners(){this.formSchema.forEach((e=>{const[n,t,i,s,r={}]=e;if("dynamicSingleSelect"===n){const e=r.id||t,n=document.getElementById(e);if(n){if(n.addEventListener("change",(n=>{const t=n.target.value;document.querySelectorAll(`.${e}-subcategory-group`).forEach((e=>{const n=e.querySelector("select");n&&(n.setAttribute("data-original-required",n.required.toString()),n.required=!1),e.style.display="none"}));const i=t+"-options",s=document.getElementById(i);if(s){s.style.display="block";const e=s.querySelector("select");e&&(e.required="true"===e.getAttribute("data-original-required"))}})),n.value){const e=new Event("change");n.dispatchEvent(e)}}else console.warn(`Main dynamic select element with ID ${e} not found.`)}}))}applyTheme(e,n){const t=document.querySelector('link[href*="formique-css"]');t?fetch(t.href).then((e=>e.text())).then((t=>{const i=t.match(new RegExp(`\\.${e}-theme\\s*{([^}]*)}`,"i"));if(!i)return void console.error(`Theme rules for ${e} not found in the stylesheet.`);const s=i[1].trim(),r=document.getElementById(n);if(r){r.classList.add(`${e}-theme`,"formique");const t=document.createElement("style");t.textContent=`\n #${n} {\n ${s}\n }\n `,r.parentNode.insertBefore(t,r)}else console.error(`Form container with ID ${n} not found.`)})).catch((e=>{console.error("Error loading the stylesheet:",e)})):console.error("Stylesheet with 'formique-css' in the name not found!")}applyCustomTheme(e,n){const t=document.getElementById(n);if(!t)return void console.error(`Form container with ID "${n}" not found. Cannot apply custom theme.`);t.classList.add("formique");const i={"--formique-base-bg":"#ffffff","--formique-base-text":"#333333","--formique-base-shadow":"0 10px 30px rgba(0, 0, 0, 0.1)","--formique-base-label":"#555555","--formique-input-border":"#dddddd","--formique-focus-color":e,"--formique-btn-bg":e,"--formique-btn-text":"#ffffff","--formique-btn-shadow":`0 2px 10px ${((e,n)=>{const t=parseInt(e.slice(1),16),i=n,s=t>>16,r=t>>8&255,l=255&t;return"#"+(16777216+65536*(Math.round((255-s)*i)+s)+256*(Math.round((255-r)*i)+r)+(Math.round((255-l)*i)+l)).toString(16).slice(1)})(e,.2)||"rgba(0, 0, 0, 0.1)"}`};let s="";for(const[e,n]of Object.entries(i))s+=` ${e}: ${n};\n`;const r=document.createElement("style");r.textContent=`\n #${n}.formique {\n ${s}\n }\n `,t.parentNode.insertBefore(r,t),console.log(`Applied custom theme with color: ${e} to form container: ${n}`)}renderFormElement(){let e="<form";const n=this.formParams||{};if(n.id||(n.id=this.formId),Object.keys(n).forEach((t=>{const i=n[t];if(null!=i)if("boolean"==typeof i)i&&(e+=` ${t}`);else{const n="accept_charset"===t?"accept-charset":t.replace(/_/g,"-");e+=` ${n}="${i}"`}})),n.laravel){const n=document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");n&&(e+=`<input type="hidden" name="_token" value="${n}">`)}return e+=">\n",e}renderForm(){const e=this.formSchema.filter((e=>"submit"!==e[0])).map((e=>{const[n,t,i,s,r={},l]=e;return this.renderField(n,t,i,s,r,l)})).join("");this.formMarkUp+=e}renderSubmitButtonElement(){const e=this.formSchema.find((e=>"submit"===e[0]));if(e){const[n,t,i,s,r={}]=e,l=r.id||t;let a=this.submitButtonClass;"class"in r&&(a=r.class);let o="";for(const[e,n]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){o+=` ${e}="${n.endsWith("()")?n:`${n}()`}"`}else!0===n?o+=` ${e.replace(/_/g,"-")}`:!1!==n&&(o+=` ${e.replace(/_/g,"-")}="${n}"`);return`\n<div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n<input type="submit" id="${l}" class="${a}" value="${i}"${o}>\n `.trim()}return""}renderField(e,n,t,i,s,r){const l={text:this.renderTextField,email:this.renderEmailField,number:this.renderNumberField,password:this.renderPasswordField,textarea:this.renderTextAreaField,tel:this.renderTelField,date:this.renderDateField,time:this.renderTimeField,"datetime-local":this.renderDateTimeField,month:this.renderMonthField,week:this.renderWeekField,url:this.renderUrlField,search:this.renderSearchField,color:this.renderColorField,checkbox:this.renderCheckboxField,radio:this.renderRadioField,file:this.renderFileField,hidden:this.renderHiddenField,image:this.renderImageField,singleSelect:this.renderSingleSelectField,multipleSelect:this.renderMultipleSelectField,dynamicSingleSelect:this.renderDynamicSingleSelectField,range:this.renderRangeField,submit:this.renderSubmitButton}[e];return l?l.call(this,e,n,t,i,s,r):(console.warn(`Unsupported field type '${e}' encountered.`),"")}renderSubmitButton(e,n,t,i,s){const r=s.id||n;let l=this.submitButtonClass;"class"in s&&(l=s.class);let a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n:`${n}()`}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);return`<input type="${e}" id="${r}" class="${l}" value="${t}"${a}>`}showSuccessMessage(e){document.getElementById(this.formContainerId).innerHTML=`\n <div class="formique-success"> ${e}</div>\n ${this.formSettings.redirectURL?`<meta http-equiv="refresh" content="2;url=${this.formSettings.redirectURL}">`:""}\n `}showErrorMessage(e){const n=document.getElementById(this.formContainerId),t=document.createElement("div");t.className="formique-error",t.textContent=`${e}`,n.prepend(t)}hasFileInputs(e){return Boolean(e.querySelector('input[type="file"]'))}async handleEmailSubmission(e){console.log(`Starting email submission for form ID: ${e}`);const n=document.getElementById(e);if(!n)throw console.error(`Form with ID ${e} not found`),new Error(`Form with ID ${e} not found`);if(!Array.isArray(this.formSettings?.sendTo)||0===this.formSettings.sendTo.length)throw console.error("formSettings.sendTo must be an array with at least one recipient email"),new Error("formSettings.sendTo must be an array with at least one recipient email");const t={formData:{},metadata:{recipients:this.formSettings.sendTo,timestamp:(new Date).toISOString()}};let i="",s="",r="";console.log("Initial payload structure:",JSON.parse(JSON.stringify(t))),new FormData(n).forEach(((e,n)=>{console.log(`Processing form field - Key: ${n}, Value: ${e}`),t.formData[n]=e;const l=n.toLowerCase();("email"===l||l.includes("email"))&&(s=e),("name"===l||l.includes("name"))&&(i=e),("subject"===l||l.includes("subject"))&&(r=e)})),t.metadata.subject=r||this.formSettings.subject||"Message From Contact Form",console.log("Determined email subject:",t.metadata.subject),s&&(t.metadata.sender=s,t.metadata.replyTo=i?`${i} <${s}>`:s),console.log("Payload after form processing:",JSON.parse(JSON.stringify(t)));try{const e=this.formiqueEndpoint||this.formAction,n=this.method||"POST";console.log(`Preparing to send request to: ${e}`),console.log(`Request method: ${n}`),console.log("Final payload being sent:",t);const i=await fetch(e,{method:n,headers:{"Content-Type":"application/json","X-Formique-Version":"1.0"},body:JSON.stringify(t)});if(console.log(`Received response with status: ${i.status}`),!i.ok){const e=await i.json().catch((()=>({})));throw console.error("API Error Response:",e),new Error(e.error||`HTTP error! status: ${i.status}`)}const s=await i.json();console.log("API Success Response:",s);const r=this.formSettings.successMessage||s.message||"Your message has been sent successfully!";console.log(`Showing success message: ${r}`),this.showSuccessMessage(r)}catch(e){console.error("Email submission failed:",e);const n=this.formSettings.errorMessage||e.message||"Failed to send message. Please try again later.";console.log(`Showing error message: ${n}`),this.showErrorMessage(n),document.getElementById("formiqueSpinner").style.display="none"}}validateEmail(e){const n=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);return console.log(`Validating email ${e}: ${n?"valid":"invalid"}`),n}handleOnPageFormSubmission(e){const n=document.getElementById(e);if(n){const e=new FormData(n);fetch(this.formAction,{method:this.method,body:e}).then((e=>e.json())).then((e=>{console.log("Success:",e);const n=document.getElementById(this.formContainerId);if(this.redirect&&this.redirectURL&&(window.location.href=this.redirectURL),n){const e=document.createElement("div");e.classList.add("success-message","message-container"),e.innerHTML=this.formSettings.successMessage||"Your details have been successfully submitted!",n.innerHTML="",n.appendChild(e)}})).catch((e=>{console.error("Error:",e);const n=document.getElementById(this.formContainerId);if(n){let t=n.querySelector(".error-message");t&&t.remove();const i=document.createElement("div");i.classList.add("error-message","message-container");let s=this.formSettings.errorMessage||"An error occurred while submitting the form. Please try again.";s=`${s}<br/>Details: ${e.message}`,i.innerHTML=s,n.appendChild(i)}}))}}renderTextField(e,n,t,i,s){const r=["required","minlength","maxlength","pattern"];let l="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)l+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":l+=` ${e}="${t}"\n`;break;default:r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${l}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""} />\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=p}renderEmailField(e,n,t,i,s){const r=["required","pattern","minlength","maxlength","multiple"];let l="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)l+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":l+=` ${e}="${t}"\n`;break;default:r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'email'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${l}\n ${c.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderNumberField(e,n,t,i,s){const r=["required","min","max","step"];let l="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)l+=` ${e}\n`;else switch(e){case"min":case"max":case"step":l+=` ${e}="${t}"\n`;break;default:r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${l}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderPasswordField(e,n,t,i,s){const r=["required","minlength","maxlength","pattern"];let l="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)l+=` ${e}\n`;else switch(e){case"minlength":case"maxlength":case"pattern":l+=` ${e}="${t}"\n`;break;default:r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'password'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${l}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTextAreaField(e,n,t,i,s){const r=["required","minlength","maxlength","pattern"];let l="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)l+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":l+=` ${e}="${t}"\n`;break;default:r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'text'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n;const d=this.formSettings?.framework||!1;let c,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on"))if("semantq"===d){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else{$+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);c="class"in s?s.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${$}\n ${l}\n ${$.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=p}renderTelField(e,n,t,i,s){const r=["required","pattern","minlength","maxlength"];let l="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)l+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":l+=` ${e}="${t}"\n`;break;default:r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'tel'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${l}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return $=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),$}renderDateField(e,n,t,i,s){const r=["required","min","max","step","placeholder","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let l="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)l+=` ${e}\n`;else switch(e){case"min":case"max":case"step":l+=` ${e}="${t}"\n`;break;default:r.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'date'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${l}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderTimeField(e,n,t,i,s){const r=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let l="";i&&Object.entries(i).forEach((([t,i])=>{if(r.includes(t))if("boolean"==typeof i&&i)l+=` ${t}\n`;else switch(t){case"min":case"max":case"step":l+=` ${t}="${i}"\n`;break;default:r.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${l}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderDateTimeField(e,n,t,i,s){const r=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let l="";i&&Object.entries(i).forEach((([t,i])=>{if(r.includes(t))if("boolean"==typeof i&&i)l+=` ${t}\n`;else switch(t){case"min":case"max":case"step":l+=` ${t}="${i}"\n`;break;default:r.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${l}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderMonthField(e,n,t,i,s){const r=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let l="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)l+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":l+=` ${e}="${t}"\n`;break;default:r.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'month'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${l}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderWeekField(e,n,t,i,s){const r=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let l="";i&&Object.entries(i).forEach((([e,t])=>{if(r.includes(e))if("boolean"==typeof t&&t)l+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":l+=` ${e}="${t}"\n`;break;default:r.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'week'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${l}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderUrlField(e,n,t,i,s){const r=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let l="";i&&Object.entries(i).forEach((([t,i])=>{if(r.includes(t))if("boolean"==typeof i&&i)l+=` ${t}\n`;else if("pattern"===t)l+=` ${t}="${i}"\n`;else r.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${l}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderSearchField(e,n,t,i,s){const r=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let l="";i&&Object.entries(i).forEach((([t,i])=>{if(r.includes(t))if("boolean"==typeof i&&i)l+=` ${t}\n`;else if("pattern"===t)l+=` ${t}="${i}"\n`;else r.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${l}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderColorField(e,n,t,i,s){const r=["required","readonly","disabled","autocomplete","inputmode","title"];let l="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"boolean"==typeof i&&i?l+=` ${t}\n`:r.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);"class"in s&&(o=s.class),"color"===e&&(o+=" form-color-input");let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${l}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderFileField(e,n,t,i,s){const r=["required","accept","multiple","disabled","title"];let l="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?"boolean"==typeof i&&i?l+=` ${t}\n`:r.includes(t)||console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${l}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderHiddenField(e,n,t,i,s){const r=["type","name","value","id","class","style","required","readonly","disabled","tabindex"];let l="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)&&"boolean"==typeof i&&i?l+=` ${t}\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if("bind:value"===s?.binding&&n&&(a=`bind:value="${n}"\n`),s?.binding?.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s?.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o,d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);o="class"in s?s.class:this.inputClass;let $=`\n <div class="${this.divClass}" id="${d+"-block"}">\n \x3c!--<label for="${d}">${t} \n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label> --\x3e\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${d}"\n class="${o}"\n ${c}\n ${l}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),$=$.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$}renderImageField(e,n,t,i,s){const r=["accept","required","minwidth","maxwidth","minheight","maxheight","src","alt","width","height"];let l="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?l+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";const o=s?.binding;if("bind:value"===o&&n&&(a=`bind:value="${n}"\n`),"string"==typeof o&&o.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),o&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="image"===e&&"submit"===n?`\n <input \n type="image"\n name="${n}"\n ${a}\n id="${c}"\n class="${s.class||this.inputClass}"\n src="${s.src||"img_submit.gif"}"\n alt="${s.alt||"Submit"}"\n width="${s.width||"48"}"\n height="${s.height||"48"}"\n ${$}\n ${l}\n />`:`\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${c}"\n class="${s.class||this.inputClass}"\n ${$}\n ${l}\n />`;let p=`\n <div class="${this.divClass}" id="${c+"-block"}">\n ${"image"===e&&"submit"===n?"":`<label for="${c}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>`}\n ${d}\n </div>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));return p=p.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),p}renderTextAreaField(e,n,t,i,s){const r=["required","minlength","maxlength"];let l="";i&&Object.entries(i).forEach((([t,i])=>{r.includes(t)?l+="boolean"==typeof i&&i?` ${t}\n`:` ${t}="${i}"\n`:console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let a="";if(s.binding&&("bind:value"===s.binding&&n&&(a=`bind:value="${n}"\n`),s.binding.startsWith("::")&&n&&(a=`bind:value="${n}"\n`),s.binding&&!n))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){d+=` ${e}="${n.endsWith("()")?n:`${n}()`}"\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o+"-block"}">\n <label for="${o}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${l}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();$=$.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,n)=>`<textarea\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=$}renderRadioField(e,n,t,i,s,r){const l=["required"];let a="";i&&Object.entries(i).forEach((([e,t])=>{if(l.includes(e))if("boolean"==typeof t&&t)a+=` ${e}\n`;else if("required"===e)a+=` ${e}\n`;else l.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`);else console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'radio'.`)}));let o="";if(s.binding)if("bind:value"===s.binding&&n)o=` bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)o=` bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $=s.class||this.inputClass,p="";r&&r.length&&(p=r.map((t=>`\n <div>\n <input \n type="${e}" \n name="${n}" \n value="${t.value}"\n ${o} \n ${c}\n ${s.id,`id="${d}-${t.value}"`}\n class="${$}"\n ${a}\n />\n <label \n for="${s.id,`${d}-${t.value}`}">\n ${t.label}\n </label>\n </div>\n `)).join(""));let m=`\n <fieldset class="${this.radioGroupClass}" id="${d+"-block"}">\n <legend>\n ${t} \n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderCheckboxField(e,n,t,i,s,r){const l=["required"];let a="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"required"===t&&(a+=`${t}\n`):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&("bind:checked"===s.binding||s.binding.startsWith("::"))&&(o=` bind:checked="${n}"\n`);let d,c=s.id||n,$="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;$+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?$+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&($+=` ${e.replace(/_/g,"-")}="${n}"\n`);d="class"in s?s.class:this.inputClass;let p="";Array.isArray(r)&&(p=r.map((e=>{const t=`${c}-${e.value}`;return`\n <div>\n <input \n type="checkbox" \n name="${n}" \n value="${e.value}"${o} ${$}\n ${s.id,`id="${t}"`}\n class="${d}"\n />\n <label \n for="${t}">\n ${e.label}\n </label>\n </div>\n `})).join(""));let m=`\n <fieldset class="${this.checkboxGroupClass}" id="${c+"-block"}">\n <legend>\n ${t} ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${p}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<input\s+([^>]*)\/>/g,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderDynamicSingleSelectField(e,n,t,i,s,r){const l=r.flat().map((e=>{const n=e.options.some((e=>!0===e.selected));return{value:e.id,label:e.label,...n&&{selected:!0}}})),a=r;this.renderSingleSelectField(e,n,t,i,s,l,a,"dynamicSingleSelect")}renderSingleSelectField(e,n,t,i,s,r,l,a){console.log("Within renderSingleSelectField");const o=["required"];let d="",c=!1;i&&Object.entries(i).forEach((([t,i])=>{o.includes(t)?"required"===t&&(d+=`${t} `,c=!0):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let $="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&($=` bind:value="${n}" `);let p=s.id||n,m="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;m+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?m+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(m+=` ${e.replace(/_/g,"-")}="${n}"\n`);let u="";Array.isArray(r)&&(u+='\n <option value="">Choose an option</option>\n ',u+=r.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let f,h,g=s.class||this.inputClass;if("dynamicSingleSelect"===a&&l)if(t.includes("-")){const[e]=t.split("-");f=e,h=t}else f=t,h=t;else f=t;let b=`\n <fieldset class="${this.selectGroupClass}" id="${p+"-block"}">\n <legend>${f}\n ${d.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${p}"> Select ${f}\n <select name="${n}"\n ${$}\n \n id="${p}"\n class="${g}"\n ${m}\n ${d}\n data-original-required="${c}" >\n ${u}\n </select>\n </fieldset>\n`.replace(/^\s*\n/gm,"").trim().replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`));if(b=b.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=b,a&&"dynamicSingleSelect"===a&&l){const e=s.id||n;l.forEach((n=>{const{id:t,label:i,options:s}=n;const r=s.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join("");let l,a;console.log("Label (rawLabel for sub-category):",h),l=h.includes("-")?h.split("-")?.[1]+" Options":"options",a="options"!==l?h.split("-")?.[1]+" Option":l;let o=`\n <fieldset class="${this.selectGroupClass} ${e}-subcategory-group" id="${t}-options" style="display: none;"> <legend>${i} ${l} \n </legend>\n <label for="${t}"> Select ${i} ${a}\n </label>\n <select name="${t}"\n ${$}\n \n id="${t}"\n class="${g}"\n ${m}\n \n data-original-required="false" >\n <option value="">Choose an option</option>\n ${r}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();o=o.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),o=o.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=o}))}}renderMultipleSelectField(e,n,t,i,s,r){const l=["required","minlength","maxlength"];let a="";i&&Object.entries(i).forEach((([t,i])=>{l.includes(t)?"required"===t?a+=`${t} `:"minlength"===t?a+=`minlength="${i}" `:"maxlength"===t&&(a+=`maxlength="${i}" `):console.warn(`Unsupported validation attribute '${t}' for field '${n}' of type '${e}'.`)}));let o="";s.binding&&"string"==typeof s.binding&&s.binding.startsWith("::")&&(o=` bind:value="${n}" `);let d=s.id||n,c="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;c+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?c+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(c+=` ${e.replace(/_/g,"-")}="${n}"\n`);let $="";Array.isArray(r)&&($=r.map((e=>{const n=e.selected?" selected":"";return`\n <option value="${e.value}"${n}>${e.label}</option>\n `})).join(""));let p;p="class"in s?s.class:this.inputClass;let m=`\n <fieldset class="${this.selectGroupClass}" id="${d+"-block"}">\n <label for="${d}">${t}\n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <select name="${n}"\n ${o}\n \n id="${d}"\n class="${p}"\n ${c}\n ${a}\n multiple\n >\n ${$}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,n,t)=>`<select\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${t.trim()}\n</select>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderRangeField(e,n,t,i,s){const r=["required","min","max","step"];let l="";i&&Object.entries(i).forEach((([e,t])=>{r.includes(e)?l+="boolean"==typeof t&&t?` ${e}\n`:` ${e}="${t}"\n`:console.warn(`Unsupported validation attribute '${e}' for field '${n}' of type 'range'.`)}));let a="";if(s.binding)if("bind:value"===s.binding&&n)a=`bind:value="${n}"\n`;else if(s.binding.startsWith("::")&&n)a=`bind:value="${n}"\n`;else if(s.binding&&!n)return void console.log(`You cannot set binding value when there is no name attribute defined in ${n} ${e} field.`);let o=s.id||n,d="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&void 0!==n)if(e.startsWith("on")){const t=n.endsWith("()")?n.slice(0,-2):n;d+=` @${e.replace(/^on/,"")}={${t}}\n`}else!0===n?d+=` ${e.replace(/_/g,"-")}\n`:!1!==n&&(d+=` ${e.replace(/_/g,"-")}="${n}"\n`);let c=s.class||this.inputClass,$=`\n <div class="${this.divClass}" id="${o}-block">\n <label for="${o}">${t}\n ${l.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${n}"\n ${a}\n id="${o}"\n class="${c}"\n ${d}\n ${l}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${t}"`:""}\n />\n <span id="${o}-value">50</span> \x3c!-- Displays the range value dynamically --\x3e\n </div>\n `.replace(/^\s*\n/gm,"").trim();$=$.replace(/<input\s+([^>]*)\/>/,((e,n)=>`<input\n${n.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=$}renderSubmitButton(e,n,t,i,s){const r=s.id||n;let l,a="";for(const[e,n]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==n)if(e.startsWith("on")){a+=` ${e}="${n.endsWith("()")?n.slice(0,-2):n}"`}else!0===n?a+=` ${e.replace(/_/g,"-")}`:!1!==n&&(a+=` ${e.replace(/_/g,"-")}="${n}"`);l="class"in s?s.class:this.submitButtonClass;let o=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n\n <input type="${e}"\n id="${r+"-block"}"\n class="${l}"\n value="${t}"\n ${a}\n />\n `.replace(/^\s*\n/gm,"").trim();this.formMarkUp+=o}renderFormHTML(){this.formMarkUp+="</form>";const e=document.getElementById(this.formContainerId);e?e.innerHTML=this.formMarkUp:console.error(`Error: form container with ID ${this.formContainerId} not found. Please ensure an element with id ${this.formContainerId} exists in the HTML.`)}}}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Formique=t()}(this,(function(){"use strict";class e extends SyntaxError{constructor(e,t,n,i){super(e),this.expected=t,this.found=n,this.location=i,this.name="SyntaxError"}format(e){let t="Error: "+this.message;if(this.location){let n=null;const i=e.find((e=>e.source===this.location.source));i&&(n=i.text.split(/\r\n|\n|\r/g));const r=this.location.start,s=this.location.source&&"function"==typeof this.location.source.offset?this.location.source.offset(r):r,o=this.location.source+":"+s.line+":"+s.column;if(n){const e=this.location.end,i="".padEnd(s.line.toString().length," "),a=n[r.line-1],l=(r.line===e.line?e.column:a.length+1)-r.column||1;t+="\n --\x3e "+o+"\n"+i+" |\n"+s.line+" | "+a+"\n"+i+" | "+"".padEnd(r.column-1," ")+"".padEnd(l,"^")}else t+="\n at "+o}return t}static buildMessage(e,t){function n(e){return e.codePointAt(0).toString(16).toUpperCase()}const i=Object.prototype.hasOwnProperty.call(RegExp.prototype,"unicode")?new RegExp("[\\p{C}\\p{Mn}\\p{Mc}]","gu"):null;function r(e){return i?e.replace(i,(e=>"\\u{"+n(e)+"}")):e}function s(e){return r(e.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,(e=>"\\x0"+n(e))).replace(/[\x10-\x1F\x7F-\x9F]/g,(e=>"\\x"+n(e))))}function o(e){return r(e.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,(e=>"\\x0"+n(e))).replace(/[\x10-\x1F\x7F-\x9F]/g,(e=>"\\x"+n(e))))}const a={literal:e=>'"'+s(e.text)+'"',class(e){const t=e.parts.map((e=>Array.isArray(e)?o(e[0])+"-"+o(e[1]):o(e)));return"["+(e.inverted?"^":"")+t.join("")+"]"+(e.unicode?"u":"")},any:()=>"any character",end:()=>"end of input",other:e=>e.description};function l(e){return a[e.type](e)}return"Expected "+function(e){const t=e.map(l);if(t.sort(),t.length>0){let e=1;for(let n=1;n<t.length;n++)t[n-1]!==t[n]&&(t[e]=t[n],e++);t.length=e}switch(t.length){case 1:return t[0];case 2:return t[0]+" or "+t[1];default:return t.slice(0,-1).join(", ")+", or "+t[t.length-1]}}(e)+" but "+function(e){return e?'"'+s(e)+'"':"end of input"}(t)+" found."}}var t={StartRules:["start"],SyntaxError:e,parse:function(t,n){const i={},r=(n=void 0!==n?n:{}).grammarSource,s={start:ne};let o=ne;const a="@form:",l=":",d='"',c="true",u="false",p="-",f=",",m=/^[^,\r\n]/,b=/^[^"]/,h=/^[0-9]/,g=/^[a-zA-Z0-9_\-]/,$=/^[!*]/,y=/^[a-zA-Z]/,v=/^[a-zA-Z0-9_ \-]/,q=/^[ \t\n\r]/,x=/^[a-zA-Z_]/,S=/^[a-zA-Z0-9_.\/:\-?&=()@#%+![\] ]/,w={type:"other",description:"form directive must be in this format: @form: form-name"},k=J("@form:",!1),F=J(":",!1),A=X([",","\r","\n"],!0,!1,!1),C=J('"',!1),E=X(['"'],!0,!1,!1),O=J("true",!1),I=J("false",!1),j=X([["0","9"]],!1,!1,!1),M=J("-",!1),W=X([["a","z"],["A","Z"],["0","9"],"_","-"],!1,!1,!1),U=X(["!","*"],!1,!1,!1),T=J(",",!1),_=X([["a","z"],["A","Z"]],!1,!1,!1),P=X([["a","z"],["A","Z"],["0","9"],"_"," ","-"],!1,!1,!1),B=X([" ","\t","\n","\r"],!1,!1,!1),L=X([["a","z"],["A","Z"],"_"],!1,!1,!1),D=X([["a","z"],["A","Z"],["0","9"],"_",".","/",":","-","?","&","=","(",")","@","#","%","+","!","[","]"," "],!1,!1,!1);let R=0|n.peg$currPos,z=R;const H=[{line:1,column:1}];let Y,G=R,V=n.peg$maxFailExpected||[],N=0|n.peg$silentFails;if(n.startRule){if(!(n.startRule in s))throw new Error("Can't start parsing from rule \""+n.startRule+'".');o=s[n.startRule]}function K(){return t.substring(z,R)}function Z(){return ee(z,R)}function J(e,t){return{type:"literal",text:e,ignoreCase:t}}function X(e,t,n,i){return{type:"class",parts:e,inverted:t,ignoreCase:n,unicode:i}}function Q(e){let n,i=H[e];if(i)return i;if(e>=H.length)n=H.length-1;else for(n=e;!H[--n];);for(i=H[n],i={line:i.line,column:i.column};n<e;)10===t.charCodeAt(n)?(i.line++,i.column=1):i.column++,n++;return H[e]=i,i}function ee(e,t,n){const i=Q(e),s=Q(t);return{source:r,start:{offset:e,line:i.line,column:i.column},end:{offset:t,line:s.line,column:s.column}}}function te(e){R<G||(R>G&&(G=R,V=[]),V.push(e))}function ne(){let e,n;return e=R,pe(),n=function(){let e,n,r;e=R,n=function(){let e,n,r,s;N++,e=R,t.substr(R,6)===a?(n=a,R+=6):(n=i,0===N&&te(k));n!==i?(pe(),r=fe(),r!==i?(pe(),s=function(){let e,t,n,r,s;e=R,t=[],n=R,r=ie(),r!==i?(s=pe(),r=[r,s],n=r):(R=n,n=i);for(;n!==i;)t.push(n),n=R,r=ie(),r!==i?(s=pe(),r=[r,s],n=r):(R=n,n=i);return z=e,t=function(e){const t=[];for(const n of e)n[0]&&n[0].type&&t.push(n[0]);return me("FormProperties",Z().start,Z().end,{properties:t})}(t),e=t,e}(),z=e,o=r,l=s,e=me("FormDirective",Z().start,Z().end,{name:o,properties:l})):(R=e,e=i)):(R=e,e=i);var o,l;N--,e===i&&(n=i,0===N&&te(w));return e}(),n!==i?(pe(),r=function(){let e,t,n;if(e=R,pe(),t=[],n=oe(),n!==i)for(;n!==i;)t.push(n),n=oe();else t=i;t!==i?(z=e,r=t,e=me("FormFields",Z().start,Z().end,{fields:r})):(R=e,e=i);var r;return e}(),r===i&&(r=null),z=e,e=function(e,t){const n=[e];return t&&n.push(t),n}(n,r)):(R=e,e=i);return e}(),n!==i?(z=e,e=n):(R=e,e=i),e}function ie(){let e,n,r,s;var o,a;return e=R,n=fe(),n!==i?(58===t.charCodeAt(R)?(r=l,R++):(r=i,0===N&&te(F)),r!==i?(pe(),s=function(){let e;e=re(),e===i&&(e=se(),e===i&&(e=function(){let e,n;e=R,t.substr(R,4)===c?(n=c,R+=4):(n=i,0===N&&te(O));n===i&&(t.substr(R,5)===u?(n=u,R+=5):(n=i,0===N&&te(I)));n!==i&&(z=e,n=me("BooleanLiteral",Z().start,Z().end,{value:"true"===K()}));return e=n,e}(),e===i&&(e=function(){let e,n,r;e=R,n=[],r=t.charAt(R),h.test(r)?R++:(r=i,0===N&&te(j));if(r!==i)for(;r!==i;)n.push(r),r=t.charAt(R),h.test(r)?R++:(r=i,0===N&&te(j));else n=i;n!==i&&(z=e,n=me("NumberLiteral",Z().start,Z().end,{value:parseInt(K(),10)}));return e=n,e}(),e===i&&(e=fe()))));return e}(),s!==i?(z=e,o=n,a=s,e=me("FormProperty",Z().start,Z().end,{key:o,value:a})):(R=e,e=i)):(R=e,e=i)):(R=e,e=i),e}function re(){let e,n,r;if(e=R,n=[],r=t.charAt(R),m.test(r)?R++:(r=i,0===N&&te(A)),r!==i)for(;r!==i;)n.push(r),r=t.charAt(R),m.test(r)?R++:(r=i,0===N&&te(A));else n=i;return n!==i&&(z=e,n=me("StringLiteral",Z().start,Z().end,{value:K().trim()})),e=n,e}function se(){let e,n,r,s;if(e=R,34===t.charCodeAt(R)?(n=d,R++):(n=i,0===N&&te(C)),n!==i){for(r=[],s=t.charAt(R),b.test(s)?R++:(s=i,0===N&&te(E));s!==i;)r.push(s),s=t.charAt(R),b.test(s)?R++:(s=i,0===N&&te(E));34===t.charCodeAt(R)?(s=d,R++):(s=i,0===N&&te(C)),s!==i?(z=e,e=me("StringLiteral",Z().start,Z().end,{value:K().slice(1,-1)})):(R=e,e=i)}else R=e,e=i;return e}function oe(){let e,n,r,s;var o,a;return e=R,45===t.charCodeAt(R)?(n=p,R++):(n=i,0===N&&te(M)),n!==i?(pe(),r=function(){let e,n,r,s;e=R,pe(),n=ae(),n===i&&(n=null);pe(),r=function(){let e;e=function(){let e,n,r,s,o,a,d;e=R,n=ae(),n===i&&(n=null);r=[],s=t.charAt(R),g.test(s)?R++:(s=i,0===N&&te(W));if(s!==i)for(;s!==i;)r.push(s),s=t.charAt(R),g.test(s)?R++:(s=i,0===N&&te(W));else r=i;if(r!==i)if(s=ae(),s===i&&(s=null),58===t.charCodeAt(R)?(o=l,R++):(o=i,0===N&&te(F)),o!==i){if(a=[],d=t.charAt(R),g.test(d)?R++:(d=i,0===N&&te(W)),d!==i)for(;d!==i;)a.push(d),d=t.charAt(R),g.test(d)?R++:(d=i,0===N&&te(W));else a=i;a!==i?(z=e,c=a,e=(n||"")+r.join("")+":"+c.join("")):(R=e,e=i)}else R=e,e=i;else R=e,e=i;var c;return e}(),e===i&&(e=function(){let e,n,r;e=R,n=[],r=t.charAt(R),g.test(r)?R++:(r=i,0===N&&te(W));if(r!==i)for(;r!==i;)n.push(r),r=t.charAt(R),g.test(r)?R++:(r=i,0===N&&te(W));else n=i;n!==i&&(z=e,n=K());return e=n,e}());return e}(),r!==i?(pe(),s=ae(),s===i&&(s=null),pe(),z=e,e=(n||"")+r+(s||"")):(R=e,e=i);return e}(),r!==i?(s=function(){let e,t,n,r,s;e=R,t=[],n=R,r=pe(),s=le(),s!==i?(r=[r,s],n=r):(R=n,n=i);for(;n!==i;)t.push(n),n=R,r=pe(),s=le(),s!==i?(r=[r,s],n=r):(R=n,n=i);return z=e,t=function(e){return e.map((e=>e[1]))}(t),e=t,e}(),pe(),z=e,o=r,a=s,e=me("FormField",Z().start,Z().end,{name:o,attributes:a||[]})):(R=e,e=i)):(R=e,e=i),e}function ae(){let e,n,r;if(e=R,n=[],r=t.charAt(R),$.test(r)?R++:(r=i,0===N&&te(U)),r!==i)for(;r!==i;)n.push(r),r=t.charAt(R),$.test(r)?R++:(r=i,0===N&&te(U));else n=i;return n!==i&&(z=e,n=K()),e=n,e}function le(){let e;return e=function(){let e,n,r,s;e=R,n=ue(),n!==i?(58===t.charCodeAt(R)?(r=l,R++):(r=i,0===N&&te(F)),r!==i?(pe(),s=function(){let e,n,r,s,o,a,l,d;if(e=R,n=ce(),n!==i){if(r=[],s=R,o=pe(),44===t.charCodeAt(R)?(a=f,R++):(a=i,0===N&&te(T)),a!==i?(l=pe(),d=ce(),d!==i?(o=[o,a,l,d],s=o):(R=s,s=i)):(R=s,s=i),s!==i)for(;s!==i;)r.push(s),s=R,o=pe(),44===t.charCodeAt(R)?(a=f,R++):(a=i,0===N&&te(T)),a!==i?(l=pe(),d=ce(),d!==i?(o=[o,a,l,d],s=o):(R=s,s=i)):(R=s,s=i);else r=i;r!==i?(z=e,e=function(e,t){const n=[e];for(const e of t)n.push(e[3]);return n}(n,r)):(R=e,e=i)}else R=e,e=i;return e}(),s!==i?(z=e,o=n,a=s,e=me("OptionsAttribute",Z().start,Z().end,{key:o,values:a})):(R=e,e=i)):(R=e,e=i)):(R=e,e=i);var o,a;return e}(),e===i&&(e=function(){let e,n,r,s;e=R,n=ue(),n!==i?(58===t.charCodeAt(R)?(r=l,R++):(r=i,0===N&&te(F)),r!==i?(pe(),s=de(),s!==i?(pe(),z=e,o=n,a=s,e=me("FieldAttribute",Z().start,Z().end,{key:o,value:a})):(R=e,e=i)):(R=e,e=i)):(R=e,e=i);var o,a;e===i&&(e=R,n=function(){let e,n,r,s;e=R,n=t.charAt(R),y.test(n)?R++:(n=i,0===N&&te(_));if(n!==i){for(r=[],s=t.charAt(R),g.test(s)?R++:(s=i,0===N&&te(W));s!==i;)r.push(s),s=t.charAt(R),g.test(s)?R++:(s=i,0===N&&te(W));z=e,e=K()}else R=e,e=i;return e}(),n!==i?(r=pe(),z=e,d=n,e=me("FieldAttribute",Z().start,Z().end,{key:d,value:me("BooleanLiteral",Z().start,Z().end,{value:!0})})):(R=e,e=i));var d;return e}()),e}function de(){let e;return e=function(){let e,n,r,s;e=R,n=t.charAt(R),x.test(n)?R++:(n=i,0===N&&te(L));if(n!==i){for(r=[],s=t.charAt(R),S.test(s)?R++:(s=i,0===N&&te(D));s!==i;)r.push(s),s=t.charAt(R),S.test(s)?R++:(s=i,0===N&&te(D));z=e,e=me("StringLiteral",Z().start,Z().end,{value:K()})}else R=e,e=i;return e}(),e===i&&(e=se(),e===i&&(e=re())),e}function ce(){let e,t;var n;return e=R,t=de(),t!==i&&(z=e,n=t,t=me("Option",Z().start,Z().end,{value:n.value,quoted:"StringLiteral"===n.type})),e=t,e}function ue(){let e,n,r,s;if(e=R,n=t.charAt(R),y.test(n)?R++:(n=i,0===N&&te(_)),n!==i){for(r=[],s=t.charAt(R),v.test(s)?R++:(s=i,0===N&&te(P));s!==i;)r.push(s),s=t.charAt(R),v.test(s)?R++:(s=i,0===N&&te(P));z=e,e=K()}else R=e,e=i;return e}function pe(){let e,n;for(e=[],n=t.charAt(R),q.test(n)?R++:(n=i,0===N&&te(B));n!==i;)e.push(n),n=t.charAt(R),q.test(n)?R++:(n=i,0===N&&te(B));return e}function fe(){let e,n,r,s;if(e=R,n=t.charAt(R),x.test(n)?R++:(n=i,0===N&&te(L)),n!==i){for(r=[],s=t.charAt(R),g.test(s)?R++:(s=i,0===N&&te(W));s!==i;)r.push(s),s=t.charAt(R),g.test(s)?R++:(s=i,0===N&&te(W));z=e,e=me("Identifier",Z().start,Z().end,{value:K()})}else R=e,e=i;return e}function me(e,t,n,i){const r={type:e,start:t,end:n,...i};return i.expression&&(r.expression=me("Identifier",i.expression.start,i.expression.end,{name:i.expression.value,loc:{start:{line:1,column:i.expression.start+1},end:{line:1,column:i.expression.start+2}}})),r}Y=o();const be=Y!==i&&R===t.length;function he(){throw Y!==i&&R<t.length&&te({type:"end"}),function(t,n,i){return new e(e.buildMessage(t,n),t,n,i)}(V,G<t.length?function(e=R){const n=t.codePointAt(e);return void 0===n?"":String.fromCodePoint(n)}(G):null,G<t.length?ee(G,G+1):ee(G,G))}return n.peg$library?{peg$result:Y,peg$currPos:R,peg$FAILED:i,peg$maxFailExpected:V,peg$maxFailPos:G,peg$success:be,peg$throw:be?void 0:he}:be?Y:void he()}};class n{constructor(e){return this.ast=e,this.formSchema=[],this.formSettings={},this.formParams={},this.formAttributes=["action","method","enctype","name","target","autocomplete","novalidate","rel","accept-charset","id","class","style","title","lang","dir","hidden","tabindex","accesskey","draggable","contenteditable","spellcheck","onsubmit","onreset","onchange","oninput","onfocus","onblur","onkeydown","onkeyup","onclick","ondblclick","onmouseover","onmouseout","aria-label","aria-labelledby","aria-describedby","role"],this.inputAttributes=["id","class","type","value","name","placeholder","autofocus","size","accept","form","list"],this.validationAttributes=["required","disabled","readonly","minlength","maxlength","pattern","min","max","step","min","max","accept","multiple","filesize","checked","selected","placeholder","data-validate","data-required","data-min","data-max","data-minlength","data-maxlength","data-pattern","data-error","data-validate-on","data-equal-to","aria-required","aria-invalid","novalidate","formnovalidate"],this.ignoreAttributes=["oneof","oneOf","one","manyof","manyOf","many","radio","select","mutli-select","multiselect","multipleselect","multipleSelect","multiple-select","multiple","checkbox","selected","default"],this.inputTypeMaps={oneof:"radio",one:"radio",radio:"radio",select:"singleSelect",singleSelect:"singleSelect",manyof:"checkbox",many:"checkbox",checkbox:"checkbox","multi-select":"multipleSelect",multiselect:"multipleSelect",multipleselect:"multipleSelect","multiple-select":"multipleSelect",multiple:"multipleSelect",selectMany:"multipleSelect",selectOne:"singleSelect",manyselect:"multipleSelect",oneselect:"singleSelect",selectmany:"multipleSelect",selectone:"singleSelect"},this.regularInputTypes=["text","password","email","number","range","date","datetime-local","time","month","week","search","tel","url","color","select","checkbox","radio","file","hidden","submit","reset","button","image"],this.specialInputTypes=["singleSelect","dynamicSingleSelect","multipleSelect"],this.typeInferenceRules={email:{type:"email",priority:10},"e-mail":{type:"email",priority:9},mail:{type:"email",priority:8},name:{type:"text",subtype:"name",priority:10},"first-name":{type:"text",subtype:"given-name",priority:10},firstname:{type:"text",subtype:"given-name",priority:9},"given-name":{type:"text",subtype:"given-name",priority:10},"last-name":{type:"text",subtype:"family-name",priority:10},lastname:{type:"text",subtype:"family-name",priority:9},surname:{type:"text",subtype:"family-name",priority:10},"family-name":{type:"text",subtype:"family-name",priority:10},"full-name":{type:"text",subtype:"full-name",priority:10},"middle-name":{type:"text",subtype:"additional-name",priority:9},"middle-initial":{type:"text",subtype:"additional-name",priority:8},nickname:{type:"text",subtype:"nickname",priority:9},username:{type:"text",subtype:"username",priority:9},displayname:{type:"text",subtype:"display-name",priority:8},title:{type:"text",subtype:"title",priority:9},subject:{type:"text",subtype:"subject",priority:8},description:{type:"text",subtype:"description",priority:9},note:{type:"text",subtype:"note",priority:8},bio:{type:"text",subtype:"bio",priority:8},address:{type:"text",subtype:"address",priority:9},city:{type:"text",subtype:"city",priority:9},state:{type:"text",subtype:"state",priority:9},province:{type:"text",subtype:"province",priority:9},country:{type:"text",subtype:"country",priority:9},zipcode:{type:"text",subtype:"postal-code",priority:9},"postal-code":{type:"text",subtype:"postal-code",priority:9},company:{type:"text",subtype:"organization",priority:9},organization:{type:"text",subtype:"organization",priority:9},job:{type:"text",subtype:"job-title",priority:8},"job-title":{type:"text",subtype:"job-title",priority:9},occupation:{type:"text",subtype:"job-title",priority:8},message:{type:"textarea",subtype:"message",priority:9},comment:{type:"textarea",subtype:"comment",priority:8},tel:{type:"tel",priority:10},phone:{type:"tel",priority:10},mobile:{type:"tel",priority:10},telephone:{type:"tel",priority:10},cell:{type:"tel",priority:9},"cell-phone":{type:"tel",priority:9},count:{type:"number",priority:9},price:{type:"number",priority:9},total:{type:"number",priority:8},amount:{type:"number",priority:9},quantity:{type:"number",priority:9},qty:{type:"number",priority:8},age:{type:"number",priority:8},sum:{type:"number",priority:7},value:{type:"number",priority:7},percent:{type:"number",priority:8},percentage:{type:"number",priority:8},discount:{type:"number",priority:7},cost:{type:"number",priority:9},payment:{type:"number",priority:8},salary:{type:"number",priority:8},fee:{type:"number",priority:8},date:{type:"date",priority:10},dob:{type:"date",priority:9},"birth-date":{type:"date",priority:8},"start-date":{type:"date",priority:7},"end-date":{type:"date",priority:7},password:{type:"password",priority:10},pwd:{type:"password",priority:8},secret:{type:"password",priority:6},url:{type:"url",priority:10},website:{type:"url",priority:8},link:{type:"url",priority:7},color:{type:"color",priority:10},search:{type:"search",priority:10},range:{type:"range",priority:10},file:{type:"file",priority:10},upload:{type:"file",priority:9},document:{type:"file",priority:8},attachment:{type:"file",priority:8},resume:{type:"file",priority:7},cv:{type:"file",priority:7},portfolio:{type:"file",priority:7},image:{type:"file",accept:"image/*",priority:10},photo:{type:"file",accept:"image/*",priority:9},avatar:{type:"file",accept:"image/*",priority:9},picture:{type:"file",accept:"image/*",priority:8},logo:{type:"file",accept:"image/*",priority:8},banner:{type:"file",accept:"image/*",priority:7},thumbnail:{type:"file",accept:"image/*",priority:7},video:{type:"file",accept:"video/*",priority:9},audio:{type:"file",accept:"audio/*",priority:9},recording:{type:"file",accept:"audio/*",priority:7},pdf:{type:"file",accept:".pdf",priority:8},spreadsheet:{type:"file",accept:".csv,.xls,.xlsx",priority:7},excel:{type:"file",accept:".xls,.xlsx",priority:8},word:{type:"file",accept:".doc,.docx",priority:8},presentation:{type:"file",accept:".ppt,.pptx",priority:7},files:{type:"file",multiple:!0,priority:8},images:{type:"file",accept:"image/*",multiple:!0,priority:8},gallery:{type:"file",accept:"image/*",multiple:!0,priority:7},gender:{type:"radio",priority:10},sex:{type:"radio",priority:9},title:{type:"select",priority:8},pronoun:{type:"select",priority:8},salutation:{type:"select",priority:7},newsletter:{type:"radio",priority:7},agree:{type:"radio",priority:6},smoker:{type:"radio",priority:5},terms:{type:"radio",priority:6},maritalstatus:{type:"select",priority:7},employment:{type:"select",priority:7},education:{type:"select",priority:6},status:{type:"select",priority:5},country:{type:"select",priority:9},language:{type:"select",priority:6},region:{type:"select",priority:5},state:{type:"select",priority:5},rating:{type:"radio",priority:5},satisfaction:{type:"radio",priority:5},feedback:{type:"radio",priority:4},reset:{type:"reset",priority:10}},this.defaultType="text",this.traverse(),this.addSubmit(),{formSchema:this.formSchema,formSettings:this.formSettings,formParams:this.formParams}}inferInputType(e){if(!e)return this.defaultType;const t=e.toLowerCase().trim(),n=[];if(this.typeInferenceRules[t])return this.typeInferenceRules[t].type;for(const[e,i]of Object.entries(this.typeInferenceRules))t.includes(e)&&n.push({...i,key:e});return n.length>0?(n.sort(((e,t)=>t.priority-e.priority)),n[0].type):/.*password.*/i.test(e)?"password":/.*(mail|email).*/i.test(e)?"email":/.*(tel|phone|mobile).*/i.test(e)?"tel":/.*(date|dob|birth).*/i.test(e)?"date":this.defaultType}cleanFieldName(e){const[t="",n=""]=e.split(":");return{input_name:t.trim().replace(/[^\w-]/g,""),input_type:n.trim()}}cleanToInputType(e){if(this.specialInputTypes.includes(e))return e;const t=e.trim().toLowerCase();return t.includes("datetime-local")?t.replace(/[^a-z-]/g,""):t.replace(/[^a-z]/g,"")}toTitleCase(e){return e.toLowerCase().split(/[\s_-]+/).map((e=>e.charAt(0).toUpperCase()+e.slice(1))).join(" ")}isRequired(e){return e.replace(/\s+/g,"").includes("*")}traverse(){const e={FormDirective:this.buildDirective.bind(this),FormProperties:this.buildProperties.bind(this),FormProperty:this.buildProperty.bind(this),FormFields:this.buildFields.bind(this),FormField:this.buildField.bind(this),OptionsAttribute:this.buildOptionsAttribute.bind(this)},t=n=>{if(!n||"object"!=typeof n)return;const i=e[n.type];i&&i(n),n.properties&&n.properties.properties&&Array.isArray(n.properties.properties)&&n.properties.properties.forEach(t),n.fields&&Array.isArray(n.fields)&&n.fields.forEach(t),n.attributes&&Array.isArray(n.attributes)&&n.attributes.forEach(t),n.values&&Array.isArray(n.values)&&n.values.forEach(t)};Array.isArray(this.ast)&&this.ast.forEach(t)}extractAttributeKeys(e){if(!Array.isArray(e))throw new Error("Input must be an array of nodes");return e.filter((e=>"FieldAttribute"===e?.type)).map((e=>e?.key)).filter(Boolean).filter(((e,t,n)=>n.indexOf(e)===t))}extractOptionValues(e){if(!Array.isArray(e))throw new Error("Input must be an array of attributes");const t=e.filter((e=>"OptionsAttribute"===e?.type&&"options"===e.key)).flatMap((e=>e.values||[])).map((e=>e?.value)).filter(Boolean);return[...new Set(t)]}extractDependentValues(e){if(!Array.isArray(e))throw new Error("Input must be an array of attributes");return e.filter((e=>"OptionsAttribute"===e?.type&&"dependents"===e?.key)).flatMap((e=>e.values||[])).map((e=>e?.value)).filter(Boolean)}inputTypeResolver(e,t){if(e.includes("-"))return"dynamicSingleSelect";if(e.includes(":")){return e.split(":")[1]}const n=t.find((e=>e in this.inputTypeMaps));return n?this.inputTypeMaps[n]:this.inferInputType(e)}getOptionValuesByKey(e,t){if(!Array.isArray(e))throw new Error("Input must be an array of attributes");if(!t)throw new Error("Target key is required");const n=e.find((e=>"OptionsAttribute"===e?.type&&e?.key===t));return n?.values?n.values.map((e=>e?.value)).filter(Boolean).map((e=>e.toLowerCase())):[]}buildDynamicSingleSelect(e,t){const n=this.cleanFieldName(t).input_name;let i,r,s=[];s.push("dynamicSingleSelect",n,this.toTitleCase(n));let o,a=[];o=e.attributes.length>0?this.handleAttributes(e.attributes):{validations:{},attributes:{}},i=o.validations,r=o.attributes,this.isRequired(t)&&(i.required=!0),r.options&&(a=r.options,delete r.options),s.push(i),s.push(r);const l=this.extractOptionValues(e.attributes);let d=[];l.length>0&&l.forEach((t=>{let n={};t.toLowerCase(),n.id=t,n.label=t;const i=t,r=this.getOptionValuesByKey(e.attributes,i);let s=[];r.length>0&&(r.forEach((e=>{s.push({value:e.toLowerCase(),label:this.toTitleCase(e)})})),n.options=s,d.push(n))})),s.push(a),s.push(d),this.formSchema.push(s)}buildDirective(e){this.formParams.id=e.name.value}buildProperties(e){}buildProperty(e){const t=e.key.value;let n;if(n=e.value&&e.value.type?e.value.value:void 0===e.value||e.value,this.formAttributes.includes(t))this.formParams[t]=n;else if("sendTo"===t){let i;i=e.value&&Array.isArray(e.value.values)?e.value.values.map((e=>e.value)):n?[n]:[],this.formSettings[t]=i}else this.formSettings[t]=n}buildFields(e){}buildField(e){const t=e.name,n=this.cleanFieldName(t),i=n.input_name;let r;if(n.input_type)r=this.cleanToInputType(n.input_type);else{let t;e.attributes.length>0?(t=this.extractAttributeKeys(e.attributes),r=t.includes("manyof")?"checkbox":this.inputTypeResolver(i,t)):r=this.inferInputType(i)}if("dynamicSingleSelect"===r)return void this.buildDynamicSingleSelect(e,t);const s=[],o=this.toTitleCase(i);s.push(r,i,o);let a,l={},d={};if(a=e.attributes.length>0?this.handleAttributes(e.attributes,t):{validations:{},attributes:{}},l=a.validations,d=a.attributes,delete d.options,delete d.selected,delete d.default,delete d.manyof,this.isRequired(t)&&(l.required=!0),s.push(l),s.push(d),e.attributes.length>0&&("checkbox"===r||"radio"===r||"select"===r||"multipleSelect"===r||"singleSelect"===r)){const t="checkbox"===r||"multipleSelect"===r,n=(()=>{const t="checkbox"===r||"multipleSelect"===r,n=e.attributes.find((e=>"OptionsAttribute"===e?.type&&("selected"===e?.key||"default"===e?.key)));if(n&&n.values&&n.values.length>0){const e=n.values.map((e=>e.value.toLowerCase()));return t?e:e[0]}const i=e.attributes.find((e=>"FieldAttribute"===e?.type&&("selected"===e?.key||"default"===e?.key)));if(i){const e=i.value?.value||i.value,n="string"==typeof e?e.toLowerCase():e;return t?[n].filter(Boolean):n}return t?[]:null})(e.attributes),i=this.extractOptionValues(e.attributes);let o=[];i.length>0&&(i.forEach((e=>{const i=e;let r=!1;r=t?Array.isArray(n)&&n.includes(i):i===n,r?o.push({value:i,label:this.toTitleCase(e),selected:!0}):o.push({value:i,label:this.toTitleCase(e)})})),s.push(o))}this.formSchema.push(s)}handleAttributes(e,t){let n={},i={};const r=e=>{let t;return t=e&&"object"==typeof e&&void 0!==e.value?e.value:e,"string"==typeof t&&(t=t.trim(),t.length>=2&&t.startsWith("'")&&t.endsWith("'")&&(t=t.slice(1,-1))),t};e.forEach((e=>{const s=e.key;if("FieldAttribute"===e.type){let t=r(e.value);if(this.ignoreAttributes&&this.ignoreAttributes.includes(s))return;if(["selected","default","options"].includes(s))return;this.inputAttributes&&this.inputAttributes.includes(s)?i[s]=t:this.validationAttributes&&this.validationAttributes.includes(s)?n[s]=t:i[s]="dependents"===s?Array.isArray(t)?t:[t]:t}else if("OptionsAttribute"===e.type){if("dependents"===s){const t=e.values.map((e=>r(e))).filter(Boolean);t.length>0&&(i[s]=t)}if("accept"===s&&t.includes(":file")){const t=e.values.map((e=>r(e))).filter(Boolean);t.length>0&&(i[s]=t.join(","))}if("dependsOn"===s&&e.values&&e.values.length>=2){const t=r(e.values[0]),n=r(e.values[1]);t&&n&&(i.dependsOn=t,i.condition=n.toLowerCase())}}}));const s=e.find((e=>"OptionsAttribute"===e.type&&"options"===e.key));if(s?.values){const e=s.values.map((e=>({value:r(e),label:r(e)})));e.length>0&&(i.options=e)}const o=e.find((e=>"OptionsAttribute"===e.type&&"selected"===e.key));if(o&&o.values){const e=o.values.map((e=>r(e))).filter(Boolean);e.length>0&&(i.selected=e)}else{const t=e.find((e=>"FieldAttribute"===e.type&&"selected"===e.key));t&&(i.selected=r(t.value))}const a=e.find((e=>"FieldAttribute"===e.type&&"default"===e.key));return a&&(i.default=r(a.value)),{validations:n,attributes:i}}buildOptionsAttribute(e){}buildFieldAttribute(e){}buildOption(e){}buildIdentifier(e){}buildStringLiteral(e){}addSubmit(){this.formSchema.push(["submit","submit","Submit"])}}class i{renderField(e,t,n,i,r,s){throw new Error("Method renderField must be implemented")}}const r="\n@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600&display=swap');\n\n/* ==================== */\n/* BASE FORM VARIABLES */\n/* ==================== */\n\n:root {\n --formique-border-radius: 6px;\n --formique-padding: 2rem;\n}\n/*\n:root {\n --formique-base-bg: white;\n --formique-base-text: #333;\n --formique-base-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);\n --formique-base-label: #555;\n --formique-input-border: #ddd;\n --formique-focus-color: #6a4fbf;\n --formique-btn-bg: #6a4fbf;\n --formique-btn-text: white;\n --formique-btn-shadow: 0 2px 10px rgba(106, 79, 191, 0.3);\n --formique-border-radius: 6px;\n --formique-max-width: 100%;\n --formique-padding: 2rem;\n}\n*/\n/* ==================== */\n/* BASE FORM STYLES */\n/* ==================== */\n.formique {\n width: 100%;\n max-width: var(--formique-max-width);\n margin: 2rem auto;\n padding: var(--formique-padding);\n background-color: var(--formique-base-bg);\n border-radius: var(--formique-border-radius);\n box-shadow: var(--formique-base-shadow);\n font-family: 'Montserrat', sans-serif;\n color: var(--formique-base-text);\n transition: all 0.3s ease;\n box-sizing: border-box;\n}\n\n/* Input Block */\n.formique .input-block {\n margin-bottom: 1.5rem;\n position: relative;\n}\n\n.formique .input-block label {\n display: block;\n margin-bottom: 0.5rem;\n font-weight: 500;\n color: var(--formique-base-label);\n font-size: 0.9rem;\n}\n\n.formique .input-block .form-input,\n.formique .input-block .form-control {\n width: 100%;\n padding: 0.75rem 0;\n border: none;\n border-bottom: 1px solid var(--formique-input-border);\n background-color: transparent;\n color: var(--formique-base-text);\n box-sizing: border-box;\n font-size: 1rem;\n transition: all 0.3s ease;\n}\n\n.formique .input-block .form-input:focus,\n.formique .input-block .form-control:focus {\n outline: none;\n border-bottom-width: 2px;\n border-bottom-color: var(--formique-focus-color);\n}\n\n.formique .input-block .form-input:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n/* Fieldset General Styling */\n.formique fieldset {\n border: 1px solid var(--formique-input-border);\n border-radius: var(--formique-border-radius);\n padding: 1rem;\n margin-bottom: 1.5rem;\n background-color: var(--formique-base-bg);\n transition: all 0.3s ease;\n}\n\n.formique fieldset legend {\n font-weight: 600;\n color: var(--formique-base-label);\n font-size: 1rem;\n padding: 0 0.5rem;\n}\n\n/* Radio Group */\n.formique .radio-group {\n /* Styles are now handled by the general fieldset or input-block if used outside fieldset */\n}\n\n.formique .radio-group legend {\n display: block;\n margin-bottom: 0.75rem;\n font-weight: 500;\n color: var(--formique-base-label);\n font-size: 0.9rem;\n}\n\n.formique .radio-group div {\n margin-bottom: 0.5rem;\n display: flex;\n align-items: center;\n}\n\n.formique .radio-group .form-radio-input {\n margin-right: 0.75rem;\n width: 18px;\n height: 18px;\n accent-color: var(--formique-focus-color);\n cursor: pointer;\n}\n\n/* Checkbox Group */\n.formique .checkbox-group {\n /* Styles are now handled by the general fieldset or input-block if used outside fieldset */\n}\n\n.formique .checkbox-group legend {\n display: block;\n margin-bottom: 0.75rem;\n font-weight: 500;\n color: var(--formique-base-label);\n font-size: 0.9rem;\n}\n\n.formique .checkbox-group div {\n margin-bottom: 0.5rem;\n display: flex;\n align-items: center;\n}\n\n.formique .checkbox-group .form-checkbox-input {\n margin-right: 0.75rem;\n width: 18px;\n height: 18px;\n accent-color: var(--formique-focus-color);\n cursor: pointer;\n}\n\n/* Select (Dropdowns) */\n.formique .form-select {\n margin-bottom: 1.5rem;\n}\n\n.formique .form-select label {\n display: block;\n margin-bottom: 0.5rem;\n font-weight: 500;\n color: var(--formique-base-label);\n font-size: 0.9rem;\n}\n\n.formique .form-select .form-input { /* Changed from .form-select-input to .form-input */\n width: 100%;\n padding: 0.75rem;\n border: 1px solid var(--formique-input-border);\n border-radius: var(--formique-border-radius);\n background-color: var(--formique-base-bg);\n color: var(--formique-base-text);\n box-sizing: border-box;\n font-size: 1rem;\n transition: all 0.3s ease;\n /* Custom arrow for select element */\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20256%20256%22%3E%3Cpath%20fill%3D%22%23'+encodeURIComponent(var(--formique-base-text)).substring(1)+'%22%20d%3D%22M208.5%2084.5l-80%2080a12%2012%200%2001-17%200l-80-80a12%2012%200%200117-17L128%20139l71.5-71.5a12%2012%200%200117%2017z%22%2F%3E%3C%2Fsvg%3E');\n background-repeat: no-repeat;\n background-position: right 0.75rem center;\n background-size: 1rem;\n cursor: pointer;\n}\n\n.formique .form-select .form-input:focus { /* Changed from .form-select-input to .form-input */\n outline: none;\n border-color: var(--formique-focus-color);\n box-shadow: 0 0 0 2px rgba(106, 79, 191, 0.1);\n}\n\n/* Multiple Selects */\n.formique .form-select .form-input[multiple] {\n min-height: 100px; /* Adjust as needed */\n padding: 0.5rem;\n background-image: none; /* Remove custom arrow for multiselect */\n}\n\n/* Submit Button */\n.formique .form-submit-btn {\n display: block;\n width: 100%;\n padding: 0.875rem 1.75rem;\n border: none;\n border-radius: var(--formique-border-radius);\n background-color: var(--formique-btn-bg);\n color: var(--formique-btn-text);\n font-size: 1rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.3s ease;\n box-shadow: var(--formique-btn-shadow);\n box-sizing: border-box;\n}\n\n.formique .form-submit-btn:hover {\n transform: translateY(-1px);\n box-shadow: 0 4px 15px var(--formique-btn-shadow);\n}\n\n.formique .form-submit-btn:active {\n transform: translateY(0);\n}\n\n/* ==================== */\n/* THEME DEFINITIONS */\n/* ==================== */\n.dark-theme {\n --formique-base-bg: #1e1e1e;\n --formique-base-text: #e0e0e0;\n --formique-base-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);\n --formique-base-label: #b0b0b0;\n --formique-input-border: #444;\n --formique-focus-color: #b0b0b0;\n --formique-btn-bg: #b0b0b0;\n --formique-btn-text: #1e1e1e;\n --formique-btn-shadow: 0 2px 10px rgba(176, 176, 176, 0.3);\n}\n\n.light-theme {\n --formique-base-bg: #ffffff;\n --formique-base-text: #333333;\n --formique-base-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);\n --formique-base-label: #555555;\n --formique-input-border: #dddddd;\n --formique-focus-color: #555555;\n --formique-btn-bg: #777777;\n --formique-btn-text: #ffffff;\n --formique-btn-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);\n}\n\n.pink-theme {\n --formique-base-bg: #ffffff;\n --formique-base-text: #333333;\n --formique-base-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);\n --formique-base-label: #555555;\n --formique-input-border: #dddddd;\n --formique-focus-color: #ff4081;\n --formique-btn-bg: #ff4081;\n --formique-btn-text: #ffffff;\n --formique-btn-shadow: 0 2px 10px rgba(255, 64, 129, 0.3);\n}\n\n.indigo-theme {\n --formique-base-bg: #ffffff;\n --formique-base-text: #333333;\n --formique-base-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);\n --formique-base-label: #555555;\n --formique-input-border: #dddddd;\n --formique-focus-color: #3f51b5;\n --formique-btn-bg: #3f51b5;\n --formique-btn-text: #ffffff;\n --formique-btn-shadow: 0 2px 10px rgba(63, 81, 181, 0.3);\n}\n\n.dark-blue-theme {\n --formique-base-bg: #0a192f;\n --formique-base-text: #e6f1ff;\n --formique-base-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);\n --formique-base-label: #a8b2d1;\n --formique-input-border: #233554;\n --formique-focus-color: #64ffda;\n --formique-btn-bg: #64ffda;\n --formique-btn-text: #0a192f;\n --formique-btn-shadow: 0 2px 10px rgba(100, 255, 218, 0.3);\n}\n\n.light-blue-theme {\n --formique-base-bg: #f5f9ff;\n --formique-base-text: #2a4365;\n --formique-base-shadow: 0 10px 30px rgba(66, 153, 225, 0.1);\n --formique-base-label: #4299e1;\n --formique-input-border: #bee3f8;\n --formique-focus-color: #3182ce;\n --formique-btn-bg: #3182ce;\n --formique-btn-text: #ffffff;\n --formique-btn-shadow: 0 2px 10px rgba(49, 130, 206, 0.3);\n}\n\n.dark-orange-theme {\n --formique-base-bg: #2d3748;\n --formique-base-text: #f7fafc;\n --formique-base-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);\n --formique-base-label: #cbd5e0;\n --formique-input-border: #4a5568;\n --formique-focus-color: #ed8936;\n --formique-btn-bg: #ed8936;\n --formique-btn-text: #1a202c;\n --formique-btn-shadow: 0 2px 10px rgba(237, 137, 54, 0.3);\n}\n\n.bright-yellow-theme {\n --formique-base-bg: #ffffff;\n --formique-base-text: #1a202c;\n --formique-base-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);\n --formique-base-label: #4a5568;\n --formique-input-border: #e2e8f0;\n --formique-focus-color: #f6e05e;\n --formique-btn-bg: #f6e05e;\n --formique-btn-text: #1a202c;\n --formique-btn-shadow: 0 2px 10px rgba(246, 224, 94, 0.3);\n}\n\n.green-theme {\n --formique-base-bg: #ffffff;\n --formique-base-text: #1a202c;\n --formique-base-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);\n --formique-base-label: #4a5568;\n --formique-input-border: #e2e8f0;\n --formique-focus-color: #48bb78;\n --formique-btn-bg: #48bb78;\n --formique-btn-text: #ffffff;\n --formique-btn-shadow: 0 2px 10px rgba(72, 187, 120, 0.3);\n}\n\n.purple-theme {\n --formique-base-bg: #ffffff;\n --formique-base-text: #1a202c;\n --formique-base-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);\n --formique-base-label: #4a5568;\n --formique-input-border: #e2e8f0;\n --formique-focus-color: #9f7aea;\n --formique-btn-bg: #9f7aea;\n --formique-btn-text: #ffffff;\n --formique-btn-shadow: 0 2px 10px rgba(159, 122, 234, 0.3);\n}\n\n.midnight-blush-theme {\n --formique-base-bg: #1a1a2e;\n --formique-base-text: #e6e6e6;\n --formique-base-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);\n --formique-base-label: #b8b8b8;\n --formique-input-border: #4e4e6a;\n --formique-focus-color: #f67280;\n --formique-btn-bg: #f67280;\n --formique-btn-text: #1a1a2e;\n --formique-btn-shadow: 0 2px 10px rgba(246, 114, 128, 0.3);\n}\n\n.deep-blue-theme {\n --formique-base-bg: #0f172a;\n --formique-base-text: #e2e8f0;\n --formique-base-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);\n --formique-base-label: #94a3b8;\n --formique-input-border: #1e293b;\n --formique-focus-color: #60a5fa;\n --formique-btn-bg: #60a5fa;\n --formique-btn-text: #0f172a;\n --formique-btn-shadow: 0 2px 10px rgba(96, 165, 250, 0.3);\n}\n\n.blue-theme {\n --formique-base-bg: #ffffff;\n --formique-base-text: #1e3a8a;\n --formique-base-shadow: 0 10px 30px rgba(29, 78, 216, 0.1);\n --formique-base-label: #3b82f6;\n --formique-input-border: #bfdbfe;\n --formique-focus-color: #2563eb;\n --formique-btn-bg: #2563eb;\n --formique-btn-text: #ffffff;\n --formique-btn-shadow: 0 2px 10px rgba(37, 99, 235, 0.3);\n}\n\n.brown-theme {\n --formique-base-bg: #f5f5f5;\n --formique-base-text: #3e2723;\n --formique-base-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);\n --formique-base-label: #5d4037;\n --formique-input-border: #d7ccc8;\n --formique-focus-color: #8d6e63;\n --formique-btn-bg: #6d4c41;\n --formique-btn-text: #ffffff;\n --formique-btn-shadow: 0 2px 10px rgba(109, 76, 65, 0.3);\n}\n\n.orange-theme {\n --formique-base-bg: #ffffff;\n --formique-base-text: #7b341e;\n --formique-base-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);\n --formique-base-label: #dd6b20;\n --formique-input-border: #fed7aa;\n --formique-focus-color: #ed8936;\n --formique-btn-bg: #ed8936;\n --formique-btn-text: #ffffff;\n --formique-btn-shadow: 0 2px 10px rgba(237, 137, 54, 0.3);\n}\n/* ==================== */\n/* WIDTH CONTROL CLASSES */\n/* ==================== */\n.formique {\n padding: 1rem;\n}\n.formique.width-full {\n --formique-max-width: 100%;\n}\n\n.formique.width-half {\n --formique-max-width: 50%;\n}\n\n.formique.width-medium {\n --formique-max-width: 600px;\n}\n\n.formique.width-small {\n --formique-max-width: 400px;\n}\n\n.formique.width-custom {\n /* To be set inline or via JS */\n}\n\n/* Spinner Container */\n#formiqueSpinner {\n display: none;\n align-items: center;\n gap: 1rem;\n font-family: var(--formique-font-family, 'Montserrat, sans-serif');\n padding: 1rem;\n border-radius: var(--formique-border-radius, 6px);\n background-color: var(--formique-base-bg);\n color: var(--formique-base-text);\n margin-top: 1rem;\n}\n\n/* Spinner Circle */\n.formique-spinner {\n width: 1.5rem;\n height: 1.5rem;\n border: 3px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: var(--formique-btn-bg);\n animation: formique-spin 1s ease-in-out infinite;\n}\n\n/* Spinner Animation */\n@keyframes formique-spin {\n to { transform: rotate(360deg); }\n}\n\n/* Message */\n#formiqueSpinner .message {\n margin: 0;\n font-size: 0.9rem;\n color: var(--formique-focus-color);\n}\n\n\n.formique-success, .formique-error {\n /* Background with opacity to work with both themes */\n background-color: var(--formique-base-bg); /* Based on --formique-btn-bg */\n \n /* Text styling using theme variables */\n color: var(--formique-focus-color);\n font-family: inherit;\n font-size: 0.95rem;\n \n /* Border using focus color with opacity */\n border: 1px solid var(--formique-focus-color); /* Based on --formique-btn-bg */\n border-radius: 4px;\n padding: 12px 16px;\n margin: 16px 0;\n \n /* Layout */\n display: flex;\n align-items: center;\n gap: 8px;\n \n /* Animation */\n animation: fadeIn 0.3s ease-in-out;\n \n /* Shadow using theme variable */\n box-shadow: var(--formique-base-shadow);\n}\n\n.formique-success::before {\n content: \"✓\";\n color: var(--formique-btn-bg); /* Using button background color for checkmark */\n font-weight: bold;\n font-size: 1.2rem;\n}\n\n.formique-error::before {\n content: \"✗\";\n color: var(--formique-btn-bg); /* Using button background color for checkmark */\n font-weight: bold;\n font-size: 1.2rem;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(-10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n\n/* --- */\n/* Specific Styles for Color Input */\n.formique .input-block .form-color-input {\n /* Restore native appearance */\n -webkit-appearance: auto;\n -moz-appearance: auto;\n appearance: auto;\n \n /* Reset properties that typically interfere with native color inputs */\n padding: 2px; /* Small padding to allow native swatch to show */\n border: 1px solid var(--formique-input-border); /* Visible border */\n background-color: var(--formique-base-bg); /* Ensure it has a background */\n width: 50px; /* A typical width for the color swatch */\n height: 30px; /* A typical height for the color swatch */\n cursor: pointer; /* Indicates it's interactive */\n \n /* Ensure border-radius and vertical alignment blend with other inputs */\n border-radius: var(--formique-border-radius);\n vertical-align: middle; /* Aligns with text if label is inline */\n \n /* Override any focus border-bottom rules from general .form-input if needed */\n border-bottom: 1px solid var(--formique-input-border); /* Keep consistent border for focus */\n}\n\n.formique .input-block .form-color-input:focus {\n outline: none; /* Remove default browser outline */\n border-color: var(--formique-focus-color); /* Apply theme focus color */\n border-bottom-color: var(--formique-focus-color); /* Ensure bottom border matches on focus */\n box-shadow: 0 0 0 2px rgba(var(--formique-focus-color-rgb, 106, 79, 191), 0.1); /* Optional: subtle shadow */\n}\n\n";return class extends i{constructor(e,i={},r={}){let s;super();let o=i,a=r;if("string"==typeof e){const l=t.parse(e.trim()),d=new n(l);s=d.formSchema,o={...i,...d.formSettings},a={...r,...d.formParams}}else s=e;this.formSchema=s,this.formParams=a,this.formSettings={requiredFieldIndicator:!0,placeholders:!0,asteriskHtml:'<span aria-hidden="true" style="color: red;">*</span>',...o},!0!==this.formSettings.disableStyles&&this.injectInternalStyles(),this.themeColor=this.formSettings.themeColor||null,this.themeColorMap={primary:{"--formique-base-bg":"#ffffff","--formique-base-text":"#333333","--formique-base-shadow":"0 10px 30px rgba(0, 0, 0, 0.1)","--formique-base-label":"#555555","--formique-input-border":"#dddddd","--formique-focus-color":null,"--formique-btn-bg":null,"--formique-btn-text":"#ffffff","--formique-btn-shadow":null}},this.divClass="input-block",this.inputClass="form-input",this.radioGroupClass="radio-group",this.checkboxGroupClass="checkbox-group",this.selectGroupClass="form-select",this.submitButtonClass="form-submit-btn",this.formContainerId=i?.formContainerId||"formique",this.formId=this.formParams?.id||this.generateFormId(),this.formAction=r?.action||"https://httpbin.org/post",this.method="POST",this.formMarkUp="",this.dependencyGraph={},this.redirect=i?.redirect||"",this.redirectURL=i?.redirectURL||"",this.themes=["dark","light","pink","indigo","dark-blue","light-blue","dark-orange","bright-yellow","green","purple","midnight-blush","deep-blue","blue","brown","orange"],this.formiqueEndpoint="https://formiqueapi.onrender.com/api/send-email",document.addEventListener("DOMContentLoaded",(()=>{this.formMarkUp+=this.renderFormElement();const e=this.formSchema.filter((e=>"submit"!==e[0])).map((e=>{const[t,n,i,r,s={},o,a]=e;return this.renderField(t,n,i,r,s,o,a)})).join("");this.formMarkUp+=e;const t=this.formSchema.find((e=>"submit"===e[0]));if(t){const[e,n,i,r,s={}]=t,o=s.id||n;let a=this.submitButtonClass;"class"in s&&(a=s.class);let l="";for(const[e,t]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){l+=` ${e}="${t.endsWith("()")?t:`${t}()`}"`}else!0===t?l+=` ${e.replace(/_/g,"-")}`:!1!==t&&(l+=` ${e.replace(/_/g,"-")}="${t}"`);this.formMarkUp+=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n </div>\n <input type="submit" id="${o}" class="${a}" value="${i}"${l}>\n `}this.renderFormHTML();const n=document.getElementById(`${this.formId}`);n?n.addEventListener("submit",(e=>{e.preventDefault();if(this.formSchema.find((e=>"recaptcha"===e[0]))){if(!grecaptcha.getResponse())return document.getElementById("formiqueSpinner").style.display="none",void alert("Please verify that you are not a robot.")}document.getElementById("formiqueSpinner").style.display="block","email"!==this.formSettings.submitMode&&"rsvp"!==this.formSettings.submitMode||this.handleEmailSubmission(this.formId),this.formSettings.submitOnPage&&this.handleOnPageFormSubmission(this.formId)})):console.error(`Form with ID ${this.formId} not found after rendering. Event listener could not be attached.`),this.initDependencyGraph(),this.registerObservers(),this.attachDynamicSelectListeners();const i=this.formSchema.find((e=>"dynamicSingleSelect"===e[0]));if(i){(i[5]||[]).forEach((e=>{}))}if(!0!==this.formSettings.disableStyles){const e=document.getElementById(this.formContainerId);if(e){if(e.classList.add("formique"),this.themeColor)this.applyCustomTheme(this.themeColor,this.formContainerId);else{const e=this.formSettings.theme&&this.themes.includes(this.formSettings.theme)?this.formSettings.theme:"light";this.applyTheme(e,this.formContainerId)}this.formSettings.formContainerStyle&&(e.style.cssText+=this.formSettings.formContainerStyle)}}else console.log("Formique: Internal styles disabled by user settings.")}))}injectInternalStyles(){if(document.getElementById("formique-internal-css"))return;const e=document.createElement("style");e.id="formique-internal-css",e.textContent=r,document.head.appendChild(e)}applyCustomTheme(e,t){const n=document.getElementById(t);n&&(n.style.setProperty("--formique-focus-color",e),n.style.setProperty("--formique-btn-bg",e),n.style.setProperty("--formique-btn-shadow",`0 4px 14px ${e}66`))}generateFormId(){return`fmq-${Math.random().toString(36).substr(2,10)}`}initDependencyGraph(){this.dependencyGraph={},this.formSchema.forEach((e=>{const[t,n,i,r,s={}]=e,o=s.id||n;s.dependents&&(this.dependencyGraph[o]=s.dependents.map((e=>{const t=this.formSchema.find((([,t])=>t===e));if(t){const n=t[4]||{};return{dependent:n.id||e,condition:n.condition||null}}console.warn(`Dependent field "${e}" not found in schema.`)})),this.dependencyGraph[o].push({state:null}),this.attachInputChangeListener(o)),s.dependents&&s.dependents.forEach((e=>{const t=this.formSchema.find((([,t])=>t===e)),n=(t&&t[4]||{}).id||e,i=document.querySelector(`#${n}-block`);if(i){i.style.display="none";i.querySelectorAll("input, select, textarea").forEach((e=>{e.hasAttribute("required")&&!0===e.required?(e.setAttribute("data-original-required","true"),e.required=!1):e.setAttribute("data-original-required","false")}))}}))}))}attachInputChangeListener(e){const t=document.querySelectorAll(`[name="${e}"]`);if(0===t.length){const n=document.getElementById(e);if(!n)return void console.warn(`Parent field element(s) not found for field: ${e}`);t=[n]}t.forEach((t=>{const n="radio"===t.type||"checkbox"===t.type?"change":"input";t.addEventListener(n,(n=>{let i;("radio"!==t.type||n.target.checked)&&(i="checkbox"===t.type?n.target.checked?n.target.value:"":n.target.value,this.handleParentFieldChange(e,i.toLowerCase()))}))}))}handleParentFieldChange(e,t){const n=this.dependencyGraph[e];n&&(this.dependencyGraph[e].forEach((e=>{void 0!==e.state&&(e.state=t)})),n.forEach((e=>{if(e.dependent){const n=e.dependent+"-block",i=document.getElementById(n);if(i){const n="function"==typeof e.condition?e.condition(t):t===e.condition;i.style.display=n?"block":"none";i.querySelectorAll("input, select, textarea").forEach((e=>{n?e.required="true"===e.getAttribute("data-original-required"):(e.setAttribute("data-original-required",e.required),e.required=!1)}))}else console.warn(`Wrapper block with ID ${n} not found.`)}})))}registerObservers(){this.formSchema.forEach((e=>{const[t,n,i,r,s={}]=e,o=s.id||n;s.dependents&&s.dependents.forEach((e=>{if(this.dependencyGraph[o]){const t=this.formSchema.find((([,t])=>t===e));if(t){const n=t[4]?.id||e;this.dependencyGraph[o].forEach((t=>{t.dependent===e&&(t.observers||(t.observers=[]),t.observers.push(n))}))}}}))}))}attachDynamicSelectListeners(){this.formSchema.forEach((e=>{const[t,n,i,r,s={}]=e;if("dynamicSingleSelect"===t){const e=s.id||n,t=document.getElementById(e);if(t){if(t.addEventListener("change",(t=>{const n=t.target.value;document.querySelectorAll(`.${e}`).forEach((e=>{const t=e.querySelector("select");t&&(t.setAttribute("data-original-required",t.required.toString()),t.required=!1),e.style.display="none"}));const i=n,r=document.getElementById(i);if(r){r.style.display="block";const e=r.querySelector("select");e&&(e.required="true"===e.getAttribute("data-original-required"))}else console.warn("Selected fieldset not found with ID:",i)})),t.value){console.log("Triggering initial change event for:",e);const n=new Event("change");t.dispatchEvent(n)}}else console.warn(`Main dynamic select element with ID ${e} not found.`)}}))}applyTheme(e,t){if(!0===this.formSettings.disableStyles)return;const n=document.getElementById(t);n?(n.classList.add(`${e}-theme`,"formique"),n.setAttribute("data-theme",e)):console.error(`Form container with ID ${t} not found.`)}applyCustomTheme(e,t){const n=document.getElementById(t);if(!n)return void console.error(`Form container with ID "${t}" not found. Cannot apply custom theme.`);n.classList.add("formique");const i={"--formique-base-bg":"#ffffff","--formique-base-text":"#333333","--formique-base-shadow":"0 10px 30px rgba(0, 0, 0, 0.1)","--formique-base-label":"#555555","--formique-input-border":"#dddddd","--formique-focus-color":e,"--formique-btn-bg":e,"--formique-btn-text":"#ffffff","--formique-btn-shadow":`0 2px 10px ${((e,t)=>{const n=parseInt(e.slice(1),16),i=t,r=n>>16,s=n>>8&255,o=255&n;return"#"+(16777216+65536*(Math.round((255-r)*i)+r)+256*(Math.round((255-s)*i)+s)+(Math.round((255-o)*i)+o)).toString(16).slice(1)})(e,.2)||"rgba(0, 0, 0, 0.1)"}`};let r="";for(const[e,t]of Object.entries(i))r+=` ${e}: ${t};\n`;const s=document.createElement("style");s.textContent=`\n #${t}.formique {\n ${r}\n }\n `,n.parentNode.insertBefore(s,n)}renderFormElement(){let e="<form";const t=this.formParams||{};if(t.id||(t.id=this.formId),Object.keys(t).forEach((n=>{const i=t[n];if(null!=i)if("boolean"==typeof i)i&&(e+=` ${n}`);else{const t="accept_charset"===n?"accept-charset":n.replace(/_/g,"-");e+=` ${t}="${i}"`}})),t.laravel){const t=document.querySelector('meta[name="csrf-token"]')?.getAttribute("content");t&&(e+=`<input type="hidden" name="_token" value="${t}">`)}return e+=">\n",e}renderForm(){const e=this.formSchema.filter((e=>"submit"!==e[0])).map((e=>{const[t,n,i,r,s={},o]=e;return this.renderField(t,n,i,r,s,o)})).join("");this.formMarkUp+=e}renderSubmitButtonElement(){const e=this.formSchema.find((e=>"submit"===e[0]));if(e){const[t,n,i,r,s={}]=e,o=s.id||n;let a=this.submitButtonClass;"class"in s&&(a=s.class);let l="";for(const[e,t]of Object.entries(s))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){l+=` ${e}="${t.endsWith("()")?t:`${t}()`}"`}else!0===t?l+=` ${e.replace(/_/g,"-")}`:!1!==t&&(l+=` ${e.replace(/_/g,"-")}="${t}"`);return`\n<div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n<input type="submit" id="${o}" class="${a}" value="${i}"${l}>\n `.trim()}return""}renderField(e,t,n,i,r,s,o=void 0){const a={text:this.renderTextField,email:this.renderEmailField,number:this.renderNumberField,password:this.renderPasswordField,textarea:this.renderTextAreaField,tel:this.renderTelField,date:this.renderDateField,time:this.renderTimeField,"datetime-local":this.renderDateTimeField,month:this.renderMonthField,week:this.renderWeekField,url:this.renderUrlField,search:this.renderSearchField,color:this.renderColorField,checkbox:this.renderCheckboxField,radio:this.renderRadioField,file:this.renderFileField,hidden:this.renderHiddenField,image:this.renderImageField,singleSelect:this.renderSingleSelectField,multipleSelect:this.renderMultipleSelectField,dynamicSingleSelect:this.renderDynamicSingleSelectField,range:this.renderRangeField,recaptcha:this.renderRecaptchaField,submit:this.renderSubmitButton}[e];return a?a.call(this,e,t,n,i,r,s,o):(console.warn(`Unsupported field type '${e}' encountered.`),"")}renderSubmitButton(e,t,n,i,r){const s=r.id||t;let o=this.submitButtonClass;"class"in r&&(o=r.class);let a="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){a+=` ${e}="${t.endsWith("()")?t:`${t}()`}"`}else!0===t?a+=` ${e.replace(/_/g,"-")}`:!1!==t&&(a+=` ${e.replace(/_/g,"-")}="${t}"`);return`<input type="${e}" id="${s}" class="${o}" value="${n}"${a}>`}showSuccessMessage(e){document.getElementById(this.formContainerId).innerHTML=`\n <div class="formique-success"> ${e}</div>\n ${this.formSettings.redirectURL?`<meta http-equiv="refresh" content="2;url=${this.formSettings.redirectURL}">`:""}\n `}showErrorMessage(e){const t=document.getElementById(this.formContainerId),n=document.createElement("div");n.className="formique-error",n.textContent=`${e}`,t.prepend(n)}hasFileInputs(e){return Boolean(e.querySelector('input[type="file"]'))}async handleEmailSubmission(e){console.log(`Starting email submission for form ID: ${e}`);const t=document.getElementById(e);if(!t)throw console.error(`Form with ID ${e} not found`),new Error(`Form with ID ${e} not found`);if(!Array.isArray(this.formSettings?.sendTo)||0===this.formSettings.sendTo.length)throw console.error("formSettings.sendTo must be an array with at least one recipient email"),new Error("formSettings.sendTo must be an array with at least one recipient email");const n={formData:{},metadata:{recipients:this.formSettings.sendTo,timestamp:(new Date).toISOString()}};let i="",r="",s="",o="";console.log("Initial payload structure:",JSON.parse(JSON.stringify(n)));new FormData(t).forEach(((e,t)=>{console.log(`Processing form field - Key: ${t}, Value: ${e}`),n.formData[t]=e;const a=t.toLowerCase();a.includes("email")&&(r=e),a.includes("name")&&(i=e),a.includes("subject")&&(s=e),this.formSettings.emailField&&t===this.formSettings.emailField&&(o=e)})),n.metadata.subject=s||this.formSettings.subject||"Message From Contact Form",console.log("Determined email subject:",n.metadata.subject),r&&(n.metadata.sender=r,n.metadata.replyTo=i?`${i} <${r}>`:r),this.formSettings.recaptchaSecretKey&&(n.metadata.recaptchaSecretKey=this.formSettings.recaptchaSecretKey),console.log("Payload after form processing:",JSON.parse(JSON.stringify(n)));try{const e=this.formiqueEndpoint||this.formAction,t=this.method||"POST";console.log(`Preparing to send primary request to: ${e}`),console.log(`Request method: ${t}`),console.log("Final payload being sent to recipients:",n);const i=await fetch(e,{method:t,headers:{"Content-Type":"application/json","X-Formique-Version":"1.0"},body:JSON.stringify(n)});if(console.log(`Received response for primary email with status: ${i.status}`),!i.ok){const e=await i.json().catch((()=>({})));throw console.error("API Error Response:",e),new Error(e.error||`HTTP error! status: ${i.status}`)}const r=await i.json();if(console.log("Primary API Success Response:",r),"rsvp"===this.formSettings.submitMode&&o&&this.formSettings.registrantMessage){console.log("RSVP mode detected. Sending confirmation email to registrant.");const i={formData:n.formData,metadata:{recipients:[o],timestamp:(new Date).toISOString(),subject:this.formSettings.registrantSubject||"RSVP Confirmation",body:this.processDynamicMessage(this.formSettings.registrantMessage,n.formData),sender:this.formSettings.sendFrom||"noreply@yourdomain.com",replyTo:this.formSettings.sendFrom||"noreply@yourdomain.com"}};try{console.log("Preparing to send RSVP email. Final payload:",i);const n=await fetch(e,{method:t,headers:{"Content-Type":"application/json","X-Formique-Version":"1.0"},body:JSON.stringify(i)});if(n.ok)console.log("RSVP email sent successfully to registrant.");else{const e=await n.json().catch((()=>({})));console.error("RSVP API Error Response:",e),console.warn("Failed to send RSVP email to registrant, but primary submission was successful.")}}catch(e){console.error("RSVP email submission failed:",e),console.warn("Failed to send RSVP email to registrant, but primary submission was successful.")}}const s=this.formSettings.successMessage||r.message||"Your message has been sent successfully!";console.log(`Showing success message: ${s}`),this.showSuccessMessage(s)}catch(e){console.error("Email submission failed:",e);const t=this.formSettings.errorMessage||e.message||"Failed to send message. Please try again later.";console.log(`Showing error message: ${t}`),this.showErrorMessage(t)}finally{document.getElementById("formiqueSpinner").style.display="none"}}processDynamicMessage(e,t){let n=e;for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e)){const i=`{${e}}`;n=n.split(i).join(t[e])}return n}validateEmail(e){const t=/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);return console.log(`Validating email ${e}: ${t?"valid":"invalid"}`),t}attachSubmitListener(){this.formElement.addEventListener("submit",(e=>{if(this.formSchema.find((e=>"recaptcha"===e[0]))){if(!grecaptcha.getResponse())return e.preventDefault(),alert("Please verify that you are not a robot."),void(document.getElementById("formiqueSpinner").style.display="none")}this.handleOnPageFormSubmission(e)}))}handleOnPageFormSubmission(e){const t=document.getElementById(e);t&&t.addEventListener("submit",(e=>{if(this.formSchema.find((e=>"recaptcha"===e[0]))){if(!grecaptcha.getResponse())return e.preventDefault(),document.getElementById("formiqueSpinner").style.display="none",void alert("Please verify that you are not a robot.")}document.getElementById("formiqueSpinner").style.display="block";const n={};new FormData(t).forEach(((e,t)=>{n[t]=e})),console.log("Setting Object",this.formSettings);const i={formData:n,metadata:{...this.formSettings}};return fetch(this.formAction,{method:this.method,headers:{"Content-Type":"application/json"},body:JSON.stringify(i)}).then((e=>e.ok?e.json():e.json().then((t=>{throw new Error(t.error||`HTTP error! Status: ${e.status}`)})))).then((e=>{console.log("Success:",e),document.getElementById("formiqueSpinner").style.display="none";const t=document.getElementById(this.formContainerId);if(this.redirect&&this.redirectURL&&(window.location.href=this.redirectURL),t){const e=document.createElement("div");e.classList.add("success-message","message-container"),e.innerHTML=this.formSettings.successMessage||"Your details have been successfully submitted!",t.innerHTML="",t.appendChild(e)}})).catch((e=>{console.error("Error:",e),document.getElementById("formiqueSpinner").style.display="none";const t=document.getElementById(this.formContainerId);if(t){let n=t.querySelector(".error-message");n&&n.remove();const i=document.createElement("div");i.classList.add("error-message","message-container");let r=this.formSettings.errorMessage||"An error occurred while submitting the form. Please try again.";r=`${r}<br/>Details: ${e.message}`,i.innerHTML=r,t.appendChild(i)}})),!1}))}renderTextField(e,t,n,i,r){const s=["required","minlength","maxlength","pattern"];let o="";i&&Object.entries(i).forEach((([e,n])=>{if(s.includes(e))if("boolean"==typeof n&&n)o+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":o+=` ${e}="${n}"\n`;break;default:s.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'text'.`)}));let a="";if(r.binding&&("bind:value"===r.binding&&t&&(a=`bind:value="${t}"\n`),r.binding.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r.binding&&!t))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l=r.id||t;const d=this.formSettings?.framework||!1;let c,u="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on"))if("semantq"===d){const n=t.endsWith("()")?t.slice(0,-2):t;u+=` @${e.replace(/^on/,"")}={${n}}\n`}else{u+=` ${e}="${t.endsWith("()")?t:`${t}()`}"\n`}else!0===t?u+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(u+=` ${e.replace(/_/g,"-")}="${t}"\n`);c="class"in r?r.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${l+"-block"}">\n <label for="${l}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${l}"\n class="${c}"\n ${u}\n ${o}\n ${u.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${n}"`:""} />\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=p}renderEmailField(e,t,n,i,r){const s=["required","pattern","minlength","maxlength","multiple"];let o="";i&&Object.entries(i).forEach((([e,n])=>{if(s.includes(e))if("boolean"==typeof n&&n)o+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":o+=` ${e}="${n}"\n`;break;default:s.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'email'.`)}));let a="";if(r.binding&&("bind:value"===r.binding&&t&&(a=`bind:value="${t}"\n`),r.binding.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r.binding&&!t))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l,d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);l="class"in r?r.class:this.inputClass;let u=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${d}"\n class="${l}"\n ${c}\n ${o}\n ${c.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${n}"`:""}\n\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),u=u.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=u}renderNumberField(e,t,n,i,r){const s=["required","min","max","step"];let o="";i&&Object.entries(i).forEach((([e,n])=>{if(s.includes(e))if("boolean"==typeof n&&n)o+=` ${e}\n`;else switch(e){case"min":case"max":case"step":o+=` ${e}="${n}"\n`;break;default:s.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'number'.`)}));let a="";if(r.binding&&("bind:value"===r.binding&&t&&(a=`bind:value="${t}"\n`),r.binding.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r.binding&&!t))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l,d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);l="class"in r?r.class:this.inputClass;let u=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${d}"\n class="${l}"\n ${c}\n ${o}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),u=u.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=u}renderPasswordField(e,t,n,i,r){const s=["required","minlength","maxlength","pattern"];let o="";i&&Object.entries(i).forEach((([e,n])=>{if(s.includes(e))if("boolean"==typeof n&&n)o+=` ${e}\n`;else switch(e){case"minlength":case"maxlength":case"pattern":o+=` ${e}="${n}"\n`;break;default:s.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'password'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'password'.`)}));let a="";if(r.binding&&("bind:value"===r.binding&&t&&(a=`bind:value="${t}"\n`),r.binding.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r.binding&&!t))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l,d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);l="class"in r?r.class:this.inputClass;let u=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${d}"\n class="${l}"\n ${c}\n ${o}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),u=u.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=u}renderTextAreaField(e,t,n,i,r){const s=["required","minlength","maxlength","pattern"];let o="";i&&Object.entries(i).forEach((([e,n])=>{if(s.includes(e))if("boolean"==typeof n&&n)o+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":o+=` ${e}="${n}"\n`;break;default:s.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'number'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'text'.`)}));let a="";if(r.binding&&("bind:value"===r.binding&&t&&(a=`bind:value="${t}"\n`),r.binding.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r.binding&&!t))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l=r.id||t;const d=this.formSettings?.framework||!1;let c,u="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on"))if("semantq"===d){const n=t.endsWith("()")?t.slice(0,-2):t;u+=` @${e.replace(/^on/,"")}={${n}}\n`}else{u+=` ${e}="${t.endsWith("()")?t:`${t}()`}"\n`}else!0===t?u+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(u+=` ${e.replace(/_/g,"-")}="${t}"\n`);c="class"in r?r.class:this.inputClass;let p=`\n <div class="${this.divClass}" id="${l+"-block"}">\n <label for="${l}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${t}"\n ${a}\n id="${l}"\n class="${c}"\n ${u}\n ${o}\n ${u.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${n}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();p=p.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,t)=>`<textarea\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=p}renderTelField(e,t,n,i,r){const s=["required","pattern","minlength","maxlength"];let o="";i&&Object.entries(i).forEach((([e,n])=>{if(s.includes(e))if("boolean"==typeof n&&n)o+=` ${e}\n`;else switch(e){case"pattern":case"minlength":case"maxlength":o+=` ${e}="${n}"\n`;break;default:s.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'tel'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'tel'.`)}));let a="";if("bind:value"===r?.binding&&t&&(a=`bind:value="${t}"\n`),r?.binding?.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r?.binding&&!t)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l,d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);l="class"in r?r.class:this.inputClass;let u=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${d}"\n class="${l}"\n ${c}\n ${o}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();return u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),u=u.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),u}renderDateField(e,t,n,i,r){const s=["required","min","max","step","placeholder","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let o="";i&&Object.entries(i).forEach((([e,n])=>{if(s.includes(e))if("boolean"==typeof n&&n)o+=` ${e}\n`;else switch(e){case"min":case"max":case"step":o+=` ${e}="${n}"\n`;break;default:s.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'date'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'date'.`)}));let a="";if("bind:value"===r?.binding&&t&&(a=`bind:value="${t}"\n`),r?.binding?.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r?.binding&&!t)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l,d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);l="class"in r?r.class:this.inputClass;let u=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${d}"\n class="${l}"\n ${c}\n ${o}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),u=u.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=u}renderTimeField(e,t,n,i,r){const s=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let o="";i&&Object.entries(i).forEach((([n,i])=>{if(s.includes(n))if("boolean"==typeof i&&i)o+=` ${n}\n`;else switch(n){case"min":case"max":case"step":o+=` ${n}="${i}"\n`;break;default:s.includes(n)||console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`)}));let a="";if("bind:value"===r?.binding&&t&&(a=`bind:value="${t}"\n`),r?.binding?.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r?.binding&&!t)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l,d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);l="class"in r?r.class:this.inputClass;let u=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${d}"\n class="${l}"\n ${c}\n ${o}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),u=u.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=u}renderDateTimeField(e,t,n,i,r){const s=["required","min","max","step","readonly","disabled","autocomplete","spellcheck","inputmode","title"];let o="";i&&Object.entries(i).forEach((([n,i])=>{if(s.includes(n))if("boolean"==typeof i&&i)o+=` ${n}\n`;else switch(n){case"min":case"max":case"step":o+=` ${n}="${i}"\n`;break;default:s.includes(n)||console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`)}else console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`)}));let a="";if(r.binding&&("bind:value"===r.binding&&t&&(a=`bind:value="${t}"\n`),r.binding.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r.binding&&!t))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l,d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);l="class"in r?r.class:this.inputClass;let u=`\n <div class="${this.divClass}" id="${d+"-block"}"> \n <label for="${d}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${d}"\n class="${l}"\n ${c}\n ${o}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),u=u.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=u}renderMonthField(e,t,n,i,r){const s=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let o="";i&&Object.entries(i).forEach((([e,n])=>{if(s.includes(e))if("boolean"==typeof n&&n)o+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":o+=` ${e}="${n}"\n`;break;default:s.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'month'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'month'.`)}));let a="";if("bind:value"===r?.binding&&t&&(a=`bind:value="${t}"\n`),r?.binding?.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r?.binding&&!t)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l,d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);l="class"in r?r.class:this.inputClass;let u=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${d}"\n class="${l}"\n ${c}\n ${o}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),u=u.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=u}renderWeekField(e,t,n,i,r){const s=["required","min","max","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let o="";i&&Object.entries(i).forEach((([e,n])=>{if(s.includes(e))if("boolean"==typeof n&&n)o+=` ${e}\n`;else switch(e){case"min":case"max":case"pattern":o+=` ${e}="${n}"\n`;break;default:s.includes(e)&&console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'week'.`)}else console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'week'.`)}));let a="";if("bind:value"===r?.binding&&t&&(a=`bind:value="${t}"\n`),r?.binding?.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r?.binding&&!t)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l,d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);l="class"in r?r.class:this.inputClass;let u=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${d}"\n class="${l}"\n ${c}\n ${o}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),u=u.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=u}renderUrlField(e,t,n,i,r){const s=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let o="";i&&Object.entries(i).forEach((([n,i])=>{if(s.includes(n))if("boolean"==typeof i&&i)o+=` ${n}\n`;else if("pattern"===n)o+=` ${n}="${i}"\n`;else s.includes(n)||console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`)}));let a="";if("bind:value"===r?.binding&&t&&(a=`bind:value="${t}"\n`),r?.binding?.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r?.binding&&!t)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l,d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);l="class"in r?r.class:this.inputClass;let u=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${d}"\n class="${l}"\n ${c}\n ${o}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),u=u.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=u}renderSearchField(e,t,n,i,r){const s=["required","pattern","placeholder","readonly","disabled","size","autocomplete","spellcheck","inputmode","title"];let o="";i&&Object.entries(i).forEach((([n,i])=>{if(s.includes(n))if("boolean"==typeof i&&i)o+=` ${n}\n`;else if("pattern"===n)o+=` ${n}="${i}"\n`;else s.includes(n)||console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`);else console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`)}));let a="";if("bind:value"===r?.binding&&t&&(a=`bind:value="${t}"\n`),r?.binding?.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r?.binding&&!t)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l,d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);l="class"in r?r.class:this.inputClass;let u=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${d}"\n class="${l}"\n ${c}\n ${o}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),u=u.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=u}renderColorField(e,t,n,i,r){const s=["required","readonly","disabled","autocomplete","inputmode","title"];let o="";i&&Object.entries(i).forEach((([n,i])=>{s.includes(n)?"boolean"==typeof i&&i?o+=` ${n}\n`:s.includes(n)||console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`)}));let a="";if("bind:value"===r?.binding&&t&&(a=`bind:value="${t}"\n`),r?.binding?.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r?.binding&&!t)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l,d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);"class"in r&&(l=r.class),"color"===e&&(l+=" form-color-input");let u=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${d}"\n class="${l}"\n ${c}\n ${o}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),u=u.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=u}renderFileField(e,t,n,i,r){const s=["required","accept","multiple","disabled","title"];let o="";i&&Object.entries(i).forEach((([n,i])=>{s.includes(n)?"boolean"==typeof i&&i?o+=` ${n}\n`:s.includes(n)||console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`):console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`)}));let a="";if("bind:value"===r?.binding&&t&&(a=`bind:value="${t}"\n`),r?.binding?.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r?.binding&&!t)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l,d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);l="class"in r?r.class:this.inputClass;let u=`\n <div class="${this.divClass}" id="${d+"-block"}">\n <label for="${d}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${d}"\n class="${l}"\n ${c}\n ${o}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),u=u.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=u}renderHiddenField(e,t,n,i,r){const s=["type","name","value","id","class","style","required","readonly","disabled","tabindex"];let o="";i&&Object.entries(i).forEach((([n,i])=>{s.includes(n)&&"boolean"==typeof i&&i?o+=` ${n}\n`:console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`)}));let a="";if("bind:value"===r?.binding&&t&&(a=`bind:value="${t}"\n`),r?.binding?.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r?.binding&&!t)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l,d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);l="class"in r?r.class:this.inputClass;let u=`\n <div class="${this.divClass}" id="${d+"-block"}">\n \x3c!--<label for="${d}">${n} \n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label> --\x3e\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${d}"\n class="${l}"\n ${c}\n ${o}\n />\n </div>\n `.replace(/^\s*\n/gm,"").trim();u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),u=u.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=u}renderImageField(e,t,n,i,r){const s=["accept","required","minwidth","maxwidth","minheight","maxheight","src","alt","width","height"];let o="";i&&Object.entries(i).forEach((([n,i])=>{s.includes(n)?o+="boolean"==typeof i&&i?` ${n}\n`:` ${n}="${i}"\n`:console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`)}));let a="";const l=r?.binding;if("bind:value"===l&&t&&(a=`bind:value="${t}"\n`),"string"==typeof l&&l.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),l&&!t)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let d,c=r.id||t,u="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;u+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?u+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(u+=` ${e.replace(/_/g,"-")}="${t}"\n`);d="image"===e&&"submit"===t?`\n <input \n type="image"\n name="${t}"\n ${a}\n id="${c}"\n class="${r.class||this.inputClass}"\n src="${r.src||"img_submit.gif"}"\n alt="${r.alt||"Submit"}"\n width="${r.width||"48"}"\n height="${r.height||"48"}"\n ${u}\n ${o}\n />`:`\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${c}"\n class="${r.class||this.inputClass}"\n ${u}\n ${o}\n />`;let p=`\n <div class="${this.divClass}" id="${c+"-block"}">\n ${"image"===e&&"submit"===t?"":`<label for="${c}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>`}\n ${d}\n </div>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));return p=p.replace(/(<div\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),p}renderTextAreaField(e,t,n,i,r){const s=["required","minlength","maxlength"];let o="";i&&Object.entries(i).forEach((([n,i])=>{s.includes(n)?o+="boolean"==typeof i&&i?` ${n}\n`:` ${n}="${i}"\n`:console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`)}));let a="";if(r.binding&&("bind:value"===r.binding&&t&&(a=`bind:value="${t}"\n`),r.binding.startsWith("::")&&t&&(a=`bind:value="${t}"\n`),r.binding&&!t))return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l=r.id||t,d="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){d+=` ${e}="${t.endsWith("()")?t:`${t}()`}"\n`}else!0===t?d+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(d+=` ${e.replace(/_/g,"-")}="${t}"\n`);let c=r.class||this.inputClass,u=`\n <div class="${this.divClass}" id="${l+"-block"}">\n <label for="${l}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <textarea \n name="${t}"\n ${a}\n id="${l}"\n class="${c}"\n ${d}\n ${o}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${n}"`:""}>\n </textarea>\n </div>\n`.replace(/^\s*\n/gm,"").trim();u=u.replace(/<textarea\s+([^>]*)>\s*<\/textarea>/,((e,t)=>`<textarea\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n></textarea>`)),this.formMarkUp+=u}renderRadioField(e,t,n,i,r,s){const o=["required"];let a="";i&&Object.entries(i).forEach((([e,n])=>{if(o.includes(e))if("boolean"==typeof n&&n)a+=` ${e}\n`;else if("required"===e)a+=` ${e}\n`;else o.includes(e)||console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'radio'.`);else console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'radio'.`)}));let l="";if(r.binding)if("bind:value"===r.binding&&t)l=` bind:value="${t}"\n`;else if(r.binding.startsWith("::")&&t)l=` bind:value="${t}"\n`;else if(r.binding&&!t)return void console.log("%s",`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);let u=r.class||this.inputClass,p=null;if(s&&s.length){const e=s.find((e=>!0===e.selected));e&&(p=e.value)}let f="";s&&s.length&&(f=s.map((n=>{const i=n.value===p?" checked":"";return`\n <div>\n <input \n type="${e}" \n name="${t}" \n value="${n.value}"\n ${l} \n ${c}\n ${r.id,`id="${d}-${n.value}"`}\n class="${u}"\n ${a}\n ${i}\n />\n <label \n for="${r.id,`${d}-${n.value}`}">\n ${n.label}\n </label>\n </div>\n `})).join(""));let m=`\n <fieldset class="${this.radioGroupClass}" id="${d+"-block"}">\n <legend>\n ${n} \n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${f}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim().replace(/<input\s+([^>]*)\/>/g,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`));m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderCheckboxField(e,t,n,i,r,s){const o=["required"];let a="";i&&Object.entries(i).forEach((([n,i])=>{o.includes(n)?"required"===n&&(a+=`${n}\n`):console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`)}));let l="";r.binding&&("bind:checked"===r.binding||r.binding.startsWith("::"))&&(l=` bind:checked="${t}"\n`);let d,c=r.id||t,u="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;u+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?u+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(u+=` ${e.replace(/_/g,"-")}="${t}"\n`);d="class"in r?r.class:this.inputClass;const p=[];s&&s.length&&s.forEach((e=>{!0!==e.checked&&!0!==e.selected||p.push(e.value)}));let f="";Array.isArray(s)&&(f=s.map((e=>{const n=`${c}-${e.value}`,i=p.includes(e.value)?" checked":"";return`\n <div>\n <input \n type="checkbox" \n name="${t}" \n value="${e.value}"${l} ${u}\n ${r.id,`id="${n}"`}\n class="${d}"\n ${i}\n />\n <label \n for="${n}">\n ${e.label}\n </label>\n </div>\n `})).join(""));let m=`\n <fieldset class="${this.checkboxGroupClass}" id="${c+"-block"}">\n <legend>\n ${n} ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n ${f}\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();m=m.replace(/<input\s+([^>]*)\/>/g,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),m=m.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=m}renderDynamicSingleSelectField(e,t,n,i,r,s){const o=s.map((e=>({value:e.id,label:e.label}))),a=s.map((e=>({id:e.id,label:e.label+" Technologies",options:e.options})));this.renderSingleSelectField(e,t,n,i,r,o,a,"dynamicSingleSelect")}renderSingleSelectField(e,t,n,i,r,s,o,a){const l=["required"];let d="",c=!1;i&&Object.entries(i).forEach((([e,t])=>{l.includes(e)&&"required"===e&&(d+=`${e} `,c=!0)}));let u="";r.binding&&"string"==typeof r.binding&&r.binding.startsWith("::")&&(u=` bind:value="${t}" `);let p=r.id||t,f="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;f+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?f+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(f+=` ${e.replace(/_/g,"-")}="${t}"\n`);let m="";Array.isArray(s)&&(m+='\n <option value="">Choose an option</option>\n ',m+=s.map((e=>{const t=e.selected?" selected":"";return`\n <option value="${e.value}"${t}>${e.label}</option>\n `})).join(""));let b,h,g=r.class||this.inputClass;if("dynamicSingleSelect"===a&&o)if(n.includes("-")){const[e]=n.split("-");b=e,h=n}else b=n,h=n;else b=n;let $=`\n <fieldset class="${this.selectGroupClass}" id="${p+"-block"}">\n <legend>${b}\n ${d.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </legend>\n <label for="${p}"> Select ${b}\n <select name="${t}"\n ${u}\n \n id="${p}"\n class="${g}"\n ${f}\n ${d}\n data-original-required="${c}" >\n ${m}\n </select>\n </fieldset>\n`.replace(/^\s*\n/gm,"").trim().replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,t,n)=>`<select\n${(t.match(/(\w+(?:-\w+)*=("[^"]*"|'[^']*'|\w+)|[^=\s]+(?!\s*=))/g)||[]).map((e=>` ${e}`)).join("\n")}\n>\n${n.trim()}\n</select>`));if($=$.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=$,a&&"dynamicSingleSelect"===a&&o){const e=r.id||t;o.forEach((t=>{const{id:n,label:i,options:r}=t;const s=r.map((e=>{const t=e.selected?" selected":"";return`\n <option value="${e.value}"${t}>${e.label}</option>\n `})).join("");let o,a;o=h.includes("-")?h.split("-")?.[1]+" Options":"options",a="options"!==o?h.split("-")?.[1]+" Option":o;let l=`\n <fieldset class="${this.selectGroupClass} ${e}" id="${n}" style="display: none;"> <legend>${i} ${o} \n </legend>\n <label for="${n}"> Select ${i} ${a}\n </label>\n <select name="${n}"\n ${u}\n \n id="${n}"\n class="${g}"\n ${f}\n \n data-original-required="false" >\n <option value="">Choose an option</option>\n ${s}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();l=l.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,t,n)=>`<select\n${(t.match(/(\w+(?:-\w+)*=("[^"]*"|'[^']*'|\w+)|[^=\s]+(?!\s*=))/g)||[]).map((e=>` ${e}`)).join("\n")}\n>\n${n.trim()}\n</select>`)),l=l.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=l}))}}renderMultipleSelectField(e,t,n,i,r,s){const o=["required","minlength","maxlength"];let a="";i&&Object.entries(i).forEach((([n,i])=>{o.includes(n)?"required"===n?a+=`${n} `:"minlength"===n?a+=`minlength="${i}" `:"maxlength"===n&&(a+=`maxlength="${i}" `):console.warn(`Unsupported validation attribute '${n}' for field '${t}' of type '${e}'.`)}));let l="";r.binding&&"string"==typeof r.binding&&r.binding.startsWith("::")&&(l=` bind:value="${t}" `);let d=r.id||t,c="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;c+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?c+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(c+=` ${e.replace(/_/g,"-")}="${t}"\n`);let u="";Array.isArray(s)&&(u=s.map((e=>{const t=e.selected?" selected":"";return`\n <option value="${e.value}"${t}>${e.label}</option>\n `})).join(""));let p;p="class"in r?r.class:this.inputClass;let f=`\n <fieldset class="${this.selectGroupClass}" id="${d+"-block"}">\n <label for="${d}">${n}\n ${a.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n</label>\n <select name="${t}"\n ${l}\n \n id="${d}"\n class="${p}"\n ${c}\n ${a}\n multiple\n >\n ${u}\n </select>\n </fieldset>\n `.replace(/^\s*\n/gm,"").trim();f=f.replace(/<select\s+([^>]*)>([\s\S]*?)<\/select>/g,((e,t,n)=>`<select\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n>\n${n.trim()}\n</select>`)),f=f.replace(/(<fieldset\s+[^>]*>)/g,(e=>`\n${e}\n`)).replace(/\n\s*\n/g,"\n"),this.formMarkUp+=f}renderRangeField(e,t,n,i,r){const s=["required","min","max","step"];let o="";i&&Object.entries(i).forEach((([e,n])=>{s.includes(e)?o+="boolean"==typeof n&&n?` ${e}\n`:` ${e}="${n}"\n`:console.warn(`Unsupported validation attribute '${e}' for field '${t}' of type 'range'.`)}));let a="";if(r.binding)if("bind:value"===r.binding&&t)a=`bind:value="${t}"\n`;else if(r.binding.startsWith("::")&&t)a=`bind:value="${t}"\n`;else if(r.binding&&!t)return void console.log(`You cannot set binding value when there is no name attribute defined in ${t} ${e} field.`);let l=r.id||t,d="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&void 0!==t)if(e.startsWith("on")){const n=t.endsWith("()")?t.slice(0,-2):t;d+=` @${e.replace(/^on/,"")}={${n}}\n`}else!0===t?d+=` ${e.replace(/_/g,"-")}\n`:!1!==t&&(d+=` ${e.replace(/_/g,"-")}="${t}"\n`);let c=r.class||this.inputClass,u=`\n <div class="${this.divClass}" id="${l}-block">\n <label for="${l}">${n}\n ${o.includes("required")&&this.formSettings.requiredFieldIndicator?this.formSettings.asteriskHtml:""}\n </label>\n <input \n type="${e}"\n name="${t}"\n ${a}\n id="${l}"\n class="${c}"\n ${d}\n ${o}\n ${d.includes("placeholder")?"":this.formSettings.placeholders?`placeholder="${n}"`:""}\n />\n <span id="${l}-value">50</span> \x3c!-- Displays the range value dynamically --\x3e\n </div>\n `.replace(/^\s*\n/gm,"").trim();u=u.replace(/<input\s+([^>]*)\/>/,((e,t)=>`<input\n${t.trim().split(/\s+/).map((e=>` ${e}`)).join("\n")}\n/>`)),this.formMarkUp+=u}renderRecaptchaField(e,t,n,i,r={}){const s=r.id||t,o=r.siteKey;return o?`\n <div class="${this.divClass}" id="${s}-block">\n <label for="${s}">${n}</label>\n <div class="g-recaptcha" id="${s}" data-sitekey="${o}"></div>\n </div>\n `:(console.error("reCAPTCHA siteKey is missing from the field attributes."),"")}renderSubmitButton(e,t,n,i,r){const s=r.id||t;let o,a="";for(const[e,t]of Object.entries(r))if("id"!==e&&"class"!==e&&"dependsOn"!==e&&"dependents"!==e&&void 0!==t)if(e.startsWith("on")){a+=` ${e}="${t.endsWith("()")?t.slice(0,-2):t}"`}else!0===t?a+=` ${e.replace(/_/g,"-")}`:!1!==t&&(a+=` ${e.replace(/_/g,"-")}="${t}"`);o="class"in r?r.class:this.submitButtonClass;let l=`\n <div id="formiqueSpinner" style="display: flex; align-items: center; gap: 1rem; font-family: sans-serif; display:none;">\n <div class="formique-spinner"></div>\n <p class="message">Hang in tight, we are submitting your details…</p>\n</div>\n\n <input type="${e}"\n id="${s+"-block"}"\n class="${o}"\n value="${n}"\n ${a}\n />\n `.replace(/^\s*\n/gm,"").trim();this.formMarkUp+=l}renderFormHTML(){this.formMarkUp+="</form>";const e=document.getElementById(this.formContainerId);e?e.innerHTML=this.formMarkUp:console.error(`Error: form container with ID ${this.formContainerId} not found. Please ensure an element with id ${this.formContainerId} exists in the HTML.`)}}}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "formique",
3
- "version": "1.0.12",
3
+ "version": "1.2.0",
4
4
  "description": "Formique Declarative Form Syntax JavaScript Library",
5
5
  "main": "formique.umd.js",
6
6
  "module": "formique.mjs",