domma-cms 0.6.14 → 0.6.16

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.
Files changed (46) hide show
  1. package/admin/js/app.js +4 -4
  2. package/admin/js/config/sidebar-config.js +1 -1
  3. package/admin/js/lib/markdown-toolbar.js +8 -6
  4. package/admin/js/templates/pages.html +5 -1
  5. package/admin/js/views/pages.js +2 -2
  6. package/config/plugins.json +11 -1
  7. package/package.json +1 -1
  8. package/plugins/analytics/stats.json +3 -3
  9. package/plugins/form-builder/data/forms/contacts.json +66 -0
  10. package/plugins/form-builder/data/forms/enquiries.json +103 -0
  11. package/plugins/form-builder/data/forms/feedback.json +131 -0
  12. package/plugins/form-builder/data/forms/notes.json +79 -0
  13. package/plugins/form-builder/data/forms/to-do.json +100 -0
  14. package/plugins/form-builder/data/submissions/contacts.json +1 -0
  15. package/plugins/form-builder/data/submissions/enquiries.json +1 -0
  16. package/plugins/form-builder/data/submissions/feedback.json +1 -0
  17. package/plugins/form-builder/data/submissions/notes.json +1 -0
  18. package/plugins/form-builder/data/submissions/to-do.json +1 -0
  19. package/plugins/job-board/admin/templates/application-detail.html +40 -0
  20. package/plugins/job-board/admin/templates/applications.html +10 -0
  21. package/plugins/job-board/admin/templates/companies.html +24 -0
  22. package/plugins/job-board/admin/templates/dashboard.html +36 -0
  23. package/plugins/job-board/admin/templates/job-editor.html +17 -0
  24. package/plugins/job-board/admin/templates/jobs.html +15 -0
  25. package/plugins/job-board/admin/templates/profile.html +17 -0
  26. package/plugins/job-board/admin/views/application-detail.js +62 -0
  27. package/plugins/job-board/admin/views/applications.js +47 -0
  28. package/plugins/job-board/admin/views/companies.js +104 -0
  29. package/plugins/job-board/admin/views/dashboard.js +88 -0
  30. package/plugins/job-board/admin/views/job-editor.js +86 -0
  31. package/plugins/job-board/admin/views/jobs.js +53 -0
  32. package/plugins/job-board/admin/views/profile.js +47 -0
  33. package/plugins/job-board/config.js +6 -0
  34. package/plugins/job-board/plugin.js +466 -0
  35. package/plugins/job-board/plugin.json +40 -0
  36. package/plugins/job-board/schemas/jb-agent-companies.json +17 -0
  37. package/plugins/job-board/schemas/jb-applications.json +20 -0
  38. package/plugins/job-board/schemas/jb-candidate-profiles.json +20 -0
  39. package/plugins/job-board/schemas/jb-companies.json +21 -0
  40. package/plugins/job-board/schemas/jb-jobs.json +23 -0
  41. package/public/css/site.css +1 -1
  42. package/server/routes/api/collections.js +4 -0
  43. package/server/routes/api/plugins.js +9 -1
  44. package/server/server.js +1 -0
  45. package/server/services/plugins.js +30 -0
  46. package/server/services/userTypes.js +227 -0
package/admin/js/app.js CHANGED
@@ -1,6 +1,6 @@
1
- import{getSidebarConfig as B}from"./config/sidebar-config.js";import{views as K}from"./views/index.js";import{api as s,getUser as S,isAuthenticated as n,logout as j}from"./api.js";$(()=>{(async()=>{try{const t=n()?await s.settings.get():null;Domma.theme.init({theme:t?.adminTheme||"charcoal-dark",persist:!0})}catch{Domma.theme.init({theme:"charcoal-dark",persist:!0})}})(),R.use(async(t,a,e)=>{if(t.path==="/login"||t.path==="/reset-password")return e();if(!n()){R.navigate("/login");return}e()});let l=null;async function D(){if(!n())return{};try{const[t,a,e,i,o,c,N,x,A,W,L,V,T]=await Promise.all([s.pages.list().catch(()=>[]),s.media.list().catch(()=>[]),s.users.list().catch(()=>[]),s.plugins.list().catch(()=>[]),s.collections.list().catch(()=>[]),s.forms.list().catch(()=>[]),s.themes.list().catch(()=>[]),s.views.list().catch(()=>[]),s.actions.list().catch(()=>[]),s.blocks.list().catch(()=>[]),s.navigation.get().catch(()=>({})),s.layouts.get().catch(()=>({})),s.get("/collections/roles/entries?limit=100").catch(()=>({entries:[]}))]),f=L.items||[],U=f.filter(m=>!m.hidden).length,v=f.length,I=i.filter(m=>m.enabled).length,C=i.length;return{pages:t.length,media:a.length,users:e.length,plugins:C>0?`${I}/${C}`:null,collections:o.length,forms:c.length,themes:N.length,views:x.length,actions:A.length,blocks:W.length,navigation:v>0?`${U}/${v}`:null,layouts:Object.keys(V).length,roles:(T.entries||[]).length}}catch{return{}}}async function d(){try{return(await s.get("/auth/permissions")).permissions||[]}catch{return[]}}async function p(t){l&&$("#admin-sidebar").empty();const a=await D(),e=u.map(i=>{if(!i.countKey)return i;const o=a[i.countKey];return{...i,badge:o!=null&&o>0?String(o):null}});l=Domma.elements.sidebar("#admin-sidebar",{header:{title:"CMS Admin",icon:"layout"},items:B(t,a,e),collapsible:!0,collapseAt:992,push:!0,contentSelector:".dashboard-main",top:"60px"}),y(),k()}function y(){$("#admin-sidebar .sidebar-link").each(function(){const t=$(this).find(".sidebar-text").text().trim();t&&$(this).attr("data-tooltip",t)}),E.tooltip("#admin-sidebar [data-tooltip]",{placement:"right"})}function k(){$("#admin-sidebar .sidebar-heading").each(function(){const t=$(this);t.addClass("sidebar-heading--collapsible"),t.append('<span class="sidebar-heading-toggle"><span data-icon="chevron-down"></span></span>'),t.on("click",function(){const a=!t.hasClass("is-collapsed");t.toggleClass("is-collapsed",a);let e=t.next();for(;e.length&&!e.hasClass("sidebar-heading")&&!e.hasClass("sidebar-divider");)e.toggle(!a),e=e.next()})}),Domma.icons.scan("#admin-sidebar")}M.subscribe("router:afterChange",({to:t})=>{l&&t.path!=="/login"&&t.path!=="/reset-password"&&l.setActive("#"+t.path)});const P=[{path:"/",view:"dashboard",title:"Dashboard - Domma CMS"},{path:"/pages",view:"pages",title:"Pages - Domma CMS"},{path:"/pages/new",view:"pageEditor",title:"New Page - Domma CMS"},{path:"/pages/edit/*",view:"pageEditor",title:"Edit Page - Domma CMS"},{path:"/media",view:"media",title:"Media - Domma CMS"},{path:"/navigation",view:"navigation",title:"Navigation - Domma CMS"},{path:"/layouts",view:"layouts",title:"Layouts - Domma CMS"},{path:"/settings",view:"settings",title:"Settings - Domma CMS"},{path:"/users",view:"users",title:"Users - Domma CMS"},{path:"/users/new",view:"userEditor",title:"New User - Domma CMS"},{path:"/users/edit/:id",view:"userEditor",title:"Edit User - Domma CMS"},{path:"/plugins",view:"plugins",title:"Plugins - Domma CMS"},{path:"/documentation",view:"documentation",title:"Usage - Domma CMS"},{path:"/tutorials",view:"tutorials",title:"Tutorials - Domma CMS"},{path:"/api-reference",view:"apiReference",title:"API Reference - Domma CMS"},{path:"/collections",view:"collections",title:"Collections - Domma CMS"},{path:"/collections/new",view:"collectionEditor",title:"New Collection - Domma CMS"},{path:"/collections/edit/:slug",view:"collectionEditor",title:"Edit Collection - Domma CMS"},{path:"/collections/:slug/entries",view:"collectionEntries",title:"Entries - Domma CMS"},{path:"/forms",view:"forms",title:"Forms - Domma CMS"},{path:"/forms/new",view:"formEditor",title:"New Form - Domma CMS"},{path:"/forms/edit/:slug",view:"formEditor",title:"Edit Form - Domma CMS"},{path:"/forms/:slug/submissions",view:"formSubmissions",title:"Submissions - Domma CMS"},{path:"/views",view:"viewsList",title:"Views - Domma CMS"},{path:"/views/new",view:"viewEditor",title:"New View - Domma CMS"},{path:"/views/edit/:slug",view:"viewEditor",title:"Edit View - Domma CMS"},{path:"/views/:slug/preview",view:"viewPreview",title:"View Preview - Domma CMS"},{path:"/actions",view:"actionsList",title:"Actions - Domma CMS"},{path:"/actions/new",view:"actionEditor",title:"New Action - Domma CMS"},{path:"/actions/edit/:slug",view:"actionEditor",title:"Edit Action - Domma CMS"},{path:"/pro/docs",view:"proDocs",title:"Pro Documentation - Domma CMS"},{path:"/blocks",view:"blocks",title:"Blocks - Domma CMS"},{path:"/blocks/new",view:"blockEditor",title:"New Block - Domma CMS"},{path:"/blocks/edit/:name",view:"blockEditor",title:"Edit Block - Domma CMS"},{path:"/my-profile",view:"myProfile",title:"My Profile - Domma CMS"},{path:"/roles",view:"roles",title:"Roles & Permissions - Domma CMS"},{path:"/roles/edit/:id",view:"roleEditor",title:"Edit Role - Domma CMS"},{path:"/login",view:"login",title:"Sign in - Domma CMS",onEnter:()=>{$("#admin-sidebar").hide(),$("#admin-topbar").hide()}},{path:"/reset-password",view:"login",title:"Reset Password - Domma CMS",onEnter:()=>{$("#admin-sidebar").hide(),$("#admin-topbar").hide()}}];M.subscribe("router:afterChange",async({to:t,from:a})=>{if(t.path!=="/login"&&t.path!=="/reset-password"){if($("#admin-sidebar").show(),$("#admin-topbar").show(),a?.path==="/login"||a?.path==="/reset-password"){await g();const e=await d();p(e)}w()}}),M.subscribe("router:afterChange",()=>{setTimeout(()=>{$(".btn-primary, .btn-danger").length&&Domma.effects.reveal(".btn-primary, .btn-danger",{animation:"fade",stagger:40,duration:300})},50)}),$("#view-container").on("click",".card-collapsible .card-header",function(t){$(t.target).closest("button, a").length||$(this).closest(".card").toggleClass("card-collapsed")}),document.addEventListener("keydown",t=>{if(!(t.ctrlKey||t.metaKey)||t.key!=="s"||window.location.hash==="#/login"||window.location.hash.startsWith("#/reset-password"))return;const a=document.querySelector("#view-container .view-header button.btn-primary");a&&(t.preventDefault(),a.click())});const h={...K},r=[...P];let u=[];async function g(){if(n())try{const t=await s.plugins.adminConfig();u=t.sidebar||[],t.routes?.length&&r.push(...t.routes);for(const[a,e]of Object.entries(t.views||{}))try{const i=await import(`/plugins/${e.entry}`);h[a]=i[e.exportName]}catch{}}catch{}}function w(){const t=S();if(!t||$("#topbar-user-name").length)return;const e={admin:"Admin",manager:"Manager",editor:"Editor",subscriber:"Subscriber"}[t.role]||t.role;$("#topbar-user").html(`
2
- <span id="topbar-user-name" class="topbar-user-name">${b(t.name)}</span>
3
- <span class="topbar-role-badge topbar-role-badge--${b(t.role)}">${e}</span>
1
+ import{getSidebarConfig as F}from"./config/sidebar-config.js";import{views as J}from"./views/index.js";import{api as o,getUser as r,isAuthenticated as l,logout as K}from"./api.js";$(()=>{(async()=>{try{const t=l()?await o.settings.get():null;Domma.theme.init({theme:t?.adminTheme||"charcoal-dark",persist:!0})}catch{Domma.theme.init({theme:"charcoal-dark",persist:!0})}})();const k=["jb-company","jb-agent","jb-candidate"],P=["/job-board","/my-profile"];function m(t){return t&&k.includes(t.role)}function d(t){return P.some(e=>t===e||t.startsWith(e+"/"))}R.use(async(t,e,i)=>{if(t.path==="/login"||t.path==="/reset-password")return i();if(!l()){R.navigate("/login");return}if(m(r())&&!d(t.path)){R.navigate("/job-board");return}i()});let c=null;async function j(){if(!l())return{};try{const[t,e,i,a,s,n,W,x,T,V,B,I,U]=await Promise.all([o.pages.list().catch(()=>[]),o.media.list().catch(()=>[]),o.users.list().catch(()=>[]),o.plugins.list().catch(()=>[]),o.collections.list().catch(()=>[]),o.forms.list().catch(()=>[]),o.themes.list().catch(()=>[]),o.views.list().catch(()=>[]),o.actions.list().catch(()=>[]),o.blocks.list().catch(()=>[]),o.navigation.get().catch(()=>({})),o.layouts.get().catch(()=>({})),o.get("/collections/roles/entries?limit=100").catch(()=>({entries:[]}))]),S=B.items||[],_=S.filter(h=>!h.hidden).length,D=S.length,O=a.filter(h=>h.enabled).length,y=a.length;return{pages:t.length,media:e.length,users:i.length,plugins:y>0?`${O}/${y}`:null,collections:s.length,forms:n.length,themes:W.length,views:x.length,actions:T.length,blocks:V.length,navigation:D>0?`${_}/${D}`:null,layouts:Object.keys(I).length,roles:(U.entries||[]).length}}catch{return{}}}async function u(){try{return(await o.get("/auth/permissions")).permissions||[]}catch{return[]}}async function g(t){c&&$("#admin-sidebar").empty();const e=await j(),i=b.map(a=>{if(!a.countKey)return a;const s=e[a.countKey];return{...a,badge:s!=null&&s>0?String(s):null}});c=Domma.elements.sidebar("#admin-sidebar",{header:{title:"CMS Admin",icon:"layout"},items:F(t,e,i),collapsible:!0,collapseAt:992,push:!0,contentSelector:".dashboard-main",top:"60px"}),A(),L()}function A(){$("#admin-sidebar .sidebar-link").each(function(){const t=$(this).find(".sidebar-text").text().trim();t&&$(this).attr("data-tooltip",t)}),E.tooltip("#admin-sidebar [data-tooltip]",{placement:"right"})}function L(){$("#admin-sidebar .sidebar-heading").each(function(){const t=$(this);t.addClass("sidebar-heading--collapsible"),t.append('<span class="sidebar-heading-toggle"><span data-icon="chevron-down"></span></span>'),t.on("click",function(){const e=!t.hasClass("is-collapsed");t.toggleClass("is-collapsed",e);let i=t.next();for(;i.length&&!i.hasClass("sidebar-heading")&&!i.hasClass("sidebar-divider");)i.toggle(!e),i=i.next()})}),Domma.icons.scan("#admin-sidebar")}M.subscribe("router:afterChange",({to:t})=>{c&&t.path!=="/login"&&t.path!=="/reset-password"&&c.setActive("#"+t.path)});const N=[{path:"/",view:"dashboard",title:"Dashboard - Domma CMS"},{path:"/pages",view:"pages",title:"Pages - Domma CMS"},{path:"/pages/new",view:"pageEditor",title:"New Page - Domma CMS"},{path:"/pages/edit/*",view:"pageEditor",title:"Edit Page - Domma CMS"},{path:"/media",view:"media",title:"Media - Domma CMS"},{path:"/navigation",view:"navigation",title:"Navigation - Domma CMS"},{path:"/layouts",view:"layouts",title:"Layouts - Domma CMS"},{path:"/settings",view:"settings",title:"Settings - Domma CMS"},{path:"/users",view:"users",title:"Users - Domma CMS"},{path:"/users/new",view:"userEditor",title:"New User - Domma CMS"},{path:"/users/edit/:id",view:"userEditor",title:"Edit User - Domma CMS"},{path:"/plugins",view:"plugins",title:"Plugins - Domma CMS"},{path:"/documentation",view:"documentation",title:"Usage - Domma CMS"},{path:"/tutorials",view:"tutorials",title:"Tutorials - Domma CMS"},{path:"/api-reference",view:"apiReference",title:"API Reference - Domma CMS"},{path:"/collections",view:"collections",title:"Collections - Domma CMS"},{path:"/collections/new",view:"collectionEditor",title:"New Collection - Domma CMS"},{path:"/collections/edit/:slug",view:"collectionEditor",title:"Edit Collection - Domma CMS"},{path:"/collections/:slug/entries",view:"collectionEntries",title:"Entries - Domma CMS"},{path:"/forms",view:"forms",title:"Forms - Domma CMS"},{path:"/forms/new",view:"formEditor",title:"New Form - Domma CMS"},{path:"/forms/edit/:slug",view:"formEditor",title:"Edit Form - Domma CMS"},{path:"/forms/:slug/submissions",view:"formSubmissions",title:"Submissions - Domma CMS"},{path:"/views",view:"viewsList",title:"Views - Domma CMS"},{path:"/views/new",view:"viewEditor",title:"New View - Domma CMS"},{path:"/views/edit/:slug",view:"viewEditor",title:"Edit View - Domma CMS"},{path:"/views/:slug/preview",view:"viewPreview",title:"View Preview - Domma CMS"},{path:"/actions",view:"actionsList",title:"Actions - Domma CMS"},{path:"/actions/new",view:"actionEditor",title:"New Action - Domma CMS"},{path:"/actions/edit/:slug",view:"actionEditor",title:"Edit Action - Domma CMS"},{path:"/pro/docs",view:"proDocs",title:"Pro Documentation - Domma CMS"},{path:"/blocks",view:"blocks",title:"Blocks - Domma CMS"},{path:"/blocks/new",view:"blockEditor",title:"New Block - Domma CMS"},{path:"/blocks/edit/:name",view:"blockEditor",title:"Edit Block - Domma CMS"},{path:"/my-profile",view:"myProfile",title:"My Profile - Domma CMS"},{path:"/roles",view:"roles",title:"Roles & Permissions - Domma CMS"},{path:"/roles/edit/:id",view:"roleEditor",title:"Edit Role - Domma CMS"},{path:"/login",view:"login",title:"Sign in - Domma CMS",onEnter:()=>{$("#admin-sidebar").hide(),$("#admin-topbar").hide()}},{path:"/reset-password",view:"login",title:"Reset Password - Domma CMS",onEnter:()=>{$("#admin-sidebar").hide(),$("#admin-topbar").hide()}}];M.subscribe("router:afterChange",async({to:t,from:e})=>{if(!(t.path==="/login"||t.path==="/reset-password")){if(m(r())&&!d(t.path)){R.navigate("/job-board");return}if($("#admin-sidebar").show(),$("#admin-topbar").show(),e?.path==="/login"||e?.path==="/reset-password"){$("#topbar-user-name").remove(),await f();const i=await u();g(i)}v()}}),M.subscribe("router:afterChange",()=>{setTimeout(()=>{$(".btn-primary, .btn-danger").length&&Domma.effects.reveal(".btn-primary, .btn-danger",{animation:"fade",stagger:40,duration:300})},50)}),$("#view-container").on("click",".card-collapsible .card-header",function(t){$(t.target).closest("button, a").length||$(this).closest(".card").toggleClass("card-collapsed")}),document.addEventListener("keydown",t=>{if(!(t.ctrlKey||t.metaKey)||t.key!=="s"||window.location.hash==="#/login"||window.location.hash.startsWith("#/reset-password"))return;const e=document.querySelector("#view-container .view-header button.btn-primary");e&&(t.preventDefault(),e.click())});const w={...J},p=[...N];let b=[];async function f(){if(l())try{const t=await o.plugins.adminConfig();b=t.sidebar||[],t.routes?.length&&p.push(...t.routes);for(const[e,i]of Object.entries(t.views||{}))try{const a=await import(`/plugins/${i.entry}`);w[e]=a[i.exportName]}catch{}}catch{}}function v(){const t=r();if(!t||$("#topbar-user-name").length)return;const i={admin:"Admin",manager:"Manager",editor:"Editor",subscriber:"Subscriber","jb-company":"Company","jb-agent":"Agent","jb-candidate":"Candidate"}[t.role]||t.role;$("#topbar-user").html(`
2
+ <span id="topbar-user-name" class="topbar-user-name">${C(t.name)}</span>
3
+ <span class="topbar-role-badge topbar-role-badge--${C(t.role)}">${i}</span>
4
4
  `),$("#topbar-actions").html(`
5
5
  <a href="#/my-profile" class="topbar-action-link" data-tooltip="My Profile" data-tooltip-placement="bottom">
6
6
  <span data-icon="user"></span>
@@ -14,4 +14,4 @@ import{getSidebarConfig as B}from"./config/sidebar-config.js";import{views as K}
14
14
  <span data-icon="log-out"></span>
15
15
  <span>Sign out</span>
16
16
  </a>
17
- `),$("#topbar-logout-btn").on("click",i=>{i.preventDefault(),j()}),Domma.icons.scan("#admin-topbar"),E.tooltip("#topbar-actions [data-tooltip]",{placement:"bottom"})}function b(t){return String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}(async()=>{if(!n()&&!window.location.hash.startsWith("#/reset-password"))window.location.hash="#/login";else if(await g(),S()){const o=await d();await p(o),w()}R.init({container:"#view-container",routes:r,views:h,default:"/",transitions:{enter:"fadeIn",leave:"fadeOut",duration:150}});const t=R._extractParams.bind(R);R._extractParams=function(i,o){if(i.endsWith("/*")){const c=i.slice(0,-2);return o.startsWith(c+"/")?{}:null}return t(i,o)};const a=(window.location.hash||"#/").slice(1)||"/";r.filter(i=>i.path.endsWith("/*")).some(i=>a.startsWith(i.path.slice(0,-2)+"/"))&&R._handleRouteChange()})()});
17
+ `),$("#topbar-logout-btn").on("click",a=>{a.preventDefault(),K()}),Domma.icons.scan("#admin-topbar"),E.tooltip("#topbar-actions [data-tooltip]",{placement:"bottom"})}function C(t){return String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}(async()=>{if(!l()&&!window.location.hash.startsWith("#/reset-password"))window.location.hash="#/login";else{const a=(window.location.hash||"#/").slice(1)||"/";if(m(r())&&!d(a)&&(window.location.hash="#/job-board"),await f(),r()){const n=await u();await g(n),v()}}R.init({container:"#view-container",routes:p,views:w,default:"/",transitions:{enter:"fadeIn",leave:"fadeOut",duration:150}});const t=R._extractParams.bind(R);R._extractParams=function(a,s){if(a.endsWith("/*")){const n=a.slice(0,-2);return s.startsWith(n+"/")?{}:null}return t(a,s)};const e=(window.location.hash||"#/").slice(1)||"/";p.filter(a=>a.path.endsWith("/*")).some(a=>e.startsWith(a.path.slice(0,-2)+"/"))&&R._handleRouteChange()})()});
@@ -1 +1 @@
1
- export function getSidebarConfig(n=[],t={},a=[]){const e=o=>n.includes(o)||["read","create","update","delete"].some(u=>n.includes(`${o}.${u}`)),s=o=>o==null?null:typeof o=="string"?o.length>0?o:null:o>0?String(o):null,i=[];return i.push({heading:"Overview"},{id:"dashboard",text:"Dashboard",icon:"home",url:"#/",section:"#/"},{divider:!0}),(e("navigation")||e("layouts"))&&i.push({heading:"Structure"},...e("navigation")?[{id:"navigation",text:"Navigation",icon:"menu",url:"#/navigation",section:"#/navigation",badge:s(t.navigation)}]:[],...e("layouts")?[{id:"layouts",text:"Layouts",icon:"layout",url:"#/layouts",section:"#/layouts",badge:s(t.layouts)}]:[],{divider:!0}),i.push({heading:"Content"}),e("pages")&&i.push({id:"pages",text:"Pages",icon:"file-text",url:"#/pages",section:"#/pages",badge:s(t.pages)}),e("media")&&i.push({id:"media",text:"Media",icon:"image",url:"#/media",section:"#/media",badge:s(t.media)}),(e("collections")||e("views")||e("actions"))&&(i.push({divider:!0},{heading:"Data"}),e("collections")&&(i.push({id:"collections",text:"Collections",icon:"database",url:"#/collections",section:"#/collections",badge:s(t.collections)}),i.push({id:"forms",text:"Forms",icon:"layout",url:"#/forms",section:"#/forms",badge:s(t.forms)})),e("views")&&i.push({id:"views",text:"Views",icon:"eye",url:"#/views",section:"#/views",badge:s(t.views)}),e("actions")&&i.push({id:"actions",text:"Actions",icon:"zap",url:"#/actions",section:"#/actions",badge:s(t.actions)}),e("pages")&&i.push({id:"blocks",text:"Blocks",icon:"box",url:"#/blocks",section:"#/blocks",badge:s(t.blocks)})),i.push({divider:!0},{heading:"Configuration"}),e("plugins")&&i.push({id:"roles",text:"Roles",icon:"shield",url:"#/roles",section:"#/roles",badge:s(t.roles)}),e("users")&&i.push({id:"users",text:"Users",icon:"users",url:"#/users",section:"#/users",badge:s(t.users)}),e("settings")&&i.push({id:"settings",text:"Site Settings",icon:"settings",url:"#/settings",section:"#/settings"}),i.push({divider:!0},{heading:"Plugins"}),e("plugins")&&(i.push({id:"plugins",text:"Plugins",icon:"package",url:"#/plugins",section:"#/plugins",badge:s(t.plugins)}),i.push(...a)),(e("navigation")||e("layouts")||e("settings"))&&i.push({divider:!0},{heading:"Pro"},{id:"pro-docs",text:"Documentation",icon:"zap",url:"#/pro/docs",section:"#/pro/docs"}),i.push({divider:!0},{heading:"Account"},{id:"my-profile",text:"My Profile",icon:"user",url:"#/my-profile",section:"#/my-profile"}),i.push({divider:!0},{heading:"View Site"},{id:"view-site",text:"View Site",icon:"external-link",url:"/",section:"/"}),i.push({divider:!0},{heading:"Documentation"},{id:"documentation",text:"Usage",icon:"book",url:"#/documentation",section:"#/documentation",badge:s(t.documents)},{id:"tutorials",text:"Tutorials",icon:"document",url:"#/tutorials",section:"#/documentation",badge:s(t.tutorials)},{id:"api-reference",text:"API Reference",icon:"code",url:"#/api-reference",section:"#/documentation"}),i}
1
+ export function getSidebarConfig(o=[],t={},l=[]){const e=n=>o.includes(n)||["read","create","update","delete"].some(r=>o.includes(`${n}.${r}`)),s=n=>n==null?null:typeof n=="string"?n.length>0?n:null:n>0?String(n):null,i=[],u=o.length>0&&o.every(n=>n.startsWith("jb-"));u||i.push({heading:"Overview"},{id:"dashboard",text:"Dashboard",icon:"home",url:"#/",section:"#/"},{divider:!0}),(e("navigation")||e("layouts"))&&i.push({heading:"Structure"},...e("navigation")?[{id:"navigation",text:"Navigation",icon:"menu",url:"#/navigation",section:"#/navigation",badge:s(t.navigation)}]:[],...e("layouts")?[{id:"layouts",text:"Layouts",icon:"layout",url:"#/layouts",section:"#/layouts",badge:s(t.layouts)}]:[],{divider:!0}),(e("pages")||e("media"))&&(i.push({heading:"Content"}),e("pages")&&i.push({id:"pages",text:"Pages",icon:"file-text",url:"#/pages",section:"#/pages",badge:s(t.pages)}),e("media")&&i.push({id:"media",text:"Media",icon:"image",url:"#/media",section:"#/media",badge:s(t.media)})),(e("collections")||e("views")||e("actions"))&&(i.push({divider:!0},{heading:"Data"}),e("collections")&&(i.push({id:"collections",text:"Collections",icon:"database",url:"#/collections",section:"#/collections",badge:s(t.collections)}),i.push({id:"forms",text:"Forms",icon:"layout",url:"#/forms",section:"#/forms",badge:s(t.forms)})),e("views")&&i.push({id:"views",text:"Views",icon:"eye",url:"#/views",section:"#/views",badge:s(t.views)}),e("actions")&&i.push({id:"actions",text:"Actions",icon:"zap",url:"#/actions",section:"#/actions",badge:s(t.actions)}),e("pages")&&i.push({id:"blocks",text:"Blocks",icon:"box",url:"#/blocks",section:"#/blocks",badge:s(t.blocks)})),(e("plugins")||e("users")||e("settings"))&&(i.push({divider:!0},{heading:"Configuration"}),e("plugins")&&i.push({id:"roles",text:"Roles",icon:"shield",url:"#/roles",section:"#/roles",badge:s(t.roles)}),e("users")&&i.push({id:"users",text:"Users",icon:"users",url:"#/users",section:"#/users",badge:s(t.users)}),e("settings")&&i.push({id:"settings",text:"Site Settings",icon:"settings",url:"#/settings",section:"#/settings"}));const a=l.filter(n=>n.permissions?.length?n.permissions.some(r=>o.includes(r)):!0);return e("plugins")?i.push({divider:!0},{heading:"Plugins"},{id:"plugins",text:"Plugins",icon:"package",url:"#/plugins",section:"#/plugins",badge:s(t.plugins)},...a):a.length&&i.push({divider:!0},...a),(e("navigation")||e("layouts")||e("settings"))&&i.push({divider:!0},{heading:"Pro"},{id:"pro-docs",text:"Documentation",icon:"zap",url:"#/pro/docs",section:"#/pro/docs"}),i.push({divider:!0},{heading:"Account"},{id:"my-profile",text:"My Profile",icon:"user",url:"#/my-profile",section:"#/my-profile"}),u||i.push({divider:!0},{heading:"View Site"},{id:"view-site",text:"View Site",icon:"external-link",url:"/",section:"/"}),(e("pages")||e("collections")||e("plugins")||e("settings"))&&i.push({divider:!0},{heading:"Documentation"},{id:"documentation",text:"Usage",icon:"book",url:"#/documentation",section:"#/documentation",badge:s(t.documents)},{id:"tutorials",text:"Tutorials",icon:"document",url:"#/tutorials",section:"#/documentation",badge:s(t.tutorials)},{id:"api-reference",text:"API Reference",icon:"code",url:"#/api-reference",section:"#/documentation"}),i}
@@ -1,4 +1,4 @@
1
- function z(){I.register("bold",{viewBox:"0 0 24 24",path:"M7 5H14a3 3 0 0 1 0 6H7V5zM7 11H15a3 3 0 0 1 0 6H7V11z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("italic",{viewBox:"0 0 24 24",path:"M11 5h4M9 19h4M13 5l-2 14",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("strikethrough",{viewBox:"0 0 24 24",path:"M16 4H9a3 3 0 0 0 0 6h6a3 3 0 0 1 0 6H6M3 12h18",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("quote",{viewBox:"0 0 24 24",path:"M3 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1zM15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("eye",{viewBox:"0 0 24 24",path:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("expand",{viewBox:"0 0 24 24",path:"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("columns",{viewBox:"0 0 24 24",path:"M3 4h18a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1zM12 4v16",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("card",{viewBox:"0 0 24 24",paths:["M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z","M3 9h18"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("help-circle",{viewBox:"0 0 24 24",path:"M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zM12 17h.01M12 13a2 2 0 0 0 2-2 2 2 0 0 0-2-2 2 2 0 0 0-2 2",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("spacer-insert",{viewBox:"0 0 24 24",paths:["M3 8h18","M3 16h18","M12 8v8"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("icon-pick",{viewBox:"0 0 24 24",paths:["M4 4h6v6H4z","M14 4h6v6h-6z","M4 14h6v6H4z","M14 14h6v6h-6z"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("btn-insert",{viewBox:"0 0 24 24",paths:["M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7z","M8 12h8M12 9v6"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("link-shortcode",{viewBox:"0 0 24 24",paths:["M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71","M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("layout-list",{viewBox:"0 0 24 24",paths:["M3 5h18M3 9h18","M3 14h4v6H3zM9 14h12M9 17h8"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("sparkles",{viewBox:"0 0 24 24",paths:["M12 3L13.5 8.5H19L14.5 11.5L16 17L12 14L8 17L9.5 11.5L5 8.5H10.5L12 3Z","M19 3L19.7 5.3H22L20.2 6.6L20.9 9L19 7.7L17.1 9L17.8 6.6L16 5.3H18.3L19 3Z","M5 13L5.5 14.7H7L5.8 15.5L6.3 17.2L5 16.3L3.7 17.2L4.2 15.5L3 14.7H4.5L5 13Z"],stroke:"currentColor",fill:"none",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("accordion-insert",{viewBox:"0 0 24 24",paths:["M3 4h18","M3 8h18","M8 11l4 4 4-4","M3 16h18","M3 20h18"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"})}export function wrapSelection(t,e,p){const i=t.selectionStart,s=t.selectionEnd,n=t.value,l=n.substring(i,s);l?(t.value=n.substring(0,i)+e+l+p+n.substring(s),t.selectionStart=i+e.length,t.selectionEnd=s+e.length):(t.value=n.substring(0,i)+e+p+n.substring(i),t.selectionStart=t.selectionEnd=i+e.length),t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}export function insertAtCursor(t,e){const p=t.selectionStart,i=t.value;t.value=i.substring(0,p)+e+i.substring(p),t.selectionStart=t.selectionEnd=p+e.length,t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}export function insertLine(t,e){const p=t.selectionStart,i=t.value,s=i.lastIndexOf(`
1
+ function z(){I.register("bold",{viewBox:"0 0 24 24",path:"M7 5H14a3 3 0 0 1 0 6H7V5zM7 11H15a3 3 0 0 1 0 6H7V11z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("italic",{viewBox:"0 0 24 24",path:"M11 5h4M9 19h4M13 5l-2 14",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("strikethrough",{viewBox:"0 0 24 24",path:"M16 4H9a3 3 0 0 0 0 6h6a3 3 0 0 1 0 6H6M3 12h18",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("quote",{viewBox:"0 0 24 24",path:"M3 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1zM15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("eye",{viewBox:"0 0 24 24",path:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8zM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6z",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("expand",{viewBox:"0 0 24 24",path:"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("columns",{viewBox:"0 0 24 24",path:"M3 4h18a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1zM12 4v16",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("card",{viewBox:"0 0 24 24",paths:["M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z","M3 9h18"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("help-circle",{viewBox:"0 0 24 24",path:"M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10zM12 17h.01M12 13a2 2 0 0 0 2-2 2 2 0 0 0-2-2 2 2 0 0 0-2 2",stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("spacer-insert",{viewBox:"0 0 24 24",paths:["M3 8h18","M3 16h18","M12 8v8"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("icon-pick",{viewBox:"0 0 24 24",paths:["M4 4h6v6H4z","M14 4h6v6h-6z","M4 14h6v6H4z","M14 14h6v6h-6z"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("btn-insert",{viewBox:"0 0 24 24",paths:["M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7z","M8 12h8M12 9v6"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("link-shortcode",{viewBox:"0 0 24 24",paths:["M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71","M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("layout-list",{viewBox:"0 0 24 24",paths:["M3 5h18M3 9h18","M3 14h4v6H3zM9 14h12M9 17h8"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("sparkles",{viewBox:"0 0 24 24",paths:["M12 3L13.5 8.5H19L14.5 11.5L16 17L12 14L8 17L9.5 11.5L5 8.5H10.5L12 3Z","M19 3L19.7 5.3H22L20.2 6.6L20.9 9L19 7.7L17.1 9L17.8 6.6L16 5.3H18.3L19 3Z","M5 13L5.5 14.7H7L5.8 15.5L6.3 17.2L5 16.3L3.7 17.2L4.2 15.5L3 14.7H4.5L5 13Z"],stroke:"currentColor",fill:"none",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("accordion-insert",{viewBox:"0 0 24 24",paths:["M3 4h18","M3 8h18","M8 11l4 4 4-4","M3 16h18","M3 20h18"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"}),I.register("hero",{viewBox:"0 0 24 24",paths:["M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5z","M7 8h10M7 11h6"],stroke:"currentColor",fill:"none",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round"})}export function wrapSelection(t,e,p){const i=t.selectionStart,s=t.selectionEnd,n=t.value,l=n.substring(i,s);l?(t.value=n.substring(0,i)+e+l+p+n.substring(s),t.selectionStart=i+e.length,t.selectionEnd=s+e.length):(t.value=n.substring(0,i)+e+p+n.substring(i),t.selectionStart=t.selectionEnd=i+e.length),t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}export function insertAtCursor(t,e){const p=t.selectionStart,i=t.value;t.value=i.substring(0,p)+e+i.substring(p),t.selectionStart=t.selectionEnd=p+e.length,t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}export function insertLine(t,e){const p=t.selectionStart,i=t.value,s=i.lastIndexOf(`
2
2
  `,p-1)+1,n=i.indexOf(`
3
3
  `,s),l=i.substring(s,n===-1?i.length:n);if(l.startsWith(e)){const r=n===-1?"":i.substring(n);t.value=i.substring(0,s)+l.substring(e.length)+r,t.selectionStart=t.selectionEnd=Math.max(s,p-e.length)}else t.value=i.substring(0,s)+e+i.substring(s),t.selectionStart=t.selectionEnd=p+e.length;t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}const B=[{category:"Entrance"},{label:"Reveal (fade)",snippet:t=>`[reveal animation="fade"]
4
4
  ${t||"Content"}
@@ -29,10 +29,12 @@ ${t||"Content"}
29
29
  [/firework]`},{label:"Fireworks show",snippet:()=>`[fireworks]
30
30
  [firework type="burst" colour="rainbow" /]
31
31
  [firework type="sparkle" colour="primary" /]
32
- [/fireworks]`,insert:!0},{label:"Celebrate",snippet:()=>'[celebrate theme="auto" intensity="medium" /]',insert:!0}];function N(t,e){const p=document.querySelector(".editor-effects-dropdown-menu");if(p){p.remove();return}const i=document.createElement("div");i.className="editor-effects-dropdown-menu",B.forEach(function(r){if(r.category){const d=document.createElement("div");d.className="editor-effects-category",d.textContent=r.category,i.appendChild(d)}else{const d=document.createElement("button");d.type="button",d.className="editor-effects-item",d.textContent=r.label,d.addEventListener("click",function(){if(i.remove(),r.insert)insertAtCursor(t,r.snippet(""));else{const c=t.selectionStart,m=t.selectionEnd,o=t.value.substring(c,m),a=r.snippet(o);t.value=t.value.substring(0,c)+a+t.value.substring(m),t.selectionStart=c,t.selectionEnd=c+a.length,t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}}),i.appendChild(d)}});const s=e.getBoundingClientRect(),n=e.closest(".editor-toolbar").getBoundingClientRect();i.style.top=s.bottom-n.top+4+"px",i.style.left=s.left-n.left+"px",e.closest(".editor-toolbar").appendChild(i);function l(r){!i.contains(r.target)&&r.target!==e&&(i.remove(),document.removeEventListener("click",l,!0))}setTimeout(function(){document.addEventListener("click",l,!0)},0)}const L=["activity","airpods","airport","alert-circle","alert-warning","ambulance","angry","annoyed","apartment","arch","archive","arrow-down","arrow-down-left","arrow-down-right","arrow-left","arrow-right","arrow-up","arrow-up-left","arrow-up-right","astonished","at-sign","attachment","award","badge","ban","bandage","bank","banknote","barbell","barcode","barn","baseball","basketball","battery","battery-charging","bauble","bell","bell-off","bells","bicycle","bitcoin","blood-drop","blush","bold","bone","book","book-closed","book-open","bookmark","bookmark-filled","bowling","box","boxing-glove","brain","bridge","briefcase","building","bus","cabin","cake","calculator","calendar","camera","camera-off","candy-cane","capsule","car","cart","cart-add","cash","cast","castle","chart-area","chart-bar","chart-bar-horizontal","chart-candlestick","chart-line","chart-pie","chat","chat-alt","check","check-circle","check-circle-filled","check-square","chevron-down","chevron-left","chevron-right","chevron-up","chevrons-down","chevrons-left","chevrons-right","chevrons-up","church","circle","circle-filled","clear-format","clipboard","clipboard-check","clipboard-list","clock","close","cloud","cloud-download","cloud-drizzle","cloud-lightning","cloud-off","cloud-rain","cloud-sun","cloud-upload","code","code-block","code-inline","cog","coins","columns","comment","compass","component","confused","cool","copy","corner-down-left","corner-down-right","corner-up-left","corner-up-right","court","cpu","credit-card","crown","crutch","cry","currency-dollar","currency-euro","currency-pound","cycling","database","dead","desktop","disappointed","dna","document","document-add","document-check","document-remove","document-text","dollar-sign","dome","dot","dots-horizontal","dots-vertical","download","droplet","droplets","dumbbell","edit","embed","emoji-happy","emoji-sad","euro-sign","exclamation","expand","expressionless","external-link","eye","eye-medical","eye-off","factory","fast-forward","feather","file-code","file-text","file-zip","fill","film","filter","fire","first-aid","fishing","flag","fog","folder","folder-add","folder-minus","folder-open","folder-plus","folder-remove","football","fortress","fuel","gamepad","garage","gauge","gift","git-branch","github","globe","golf","grid","grin","growth","hard-drive","hash","haze","heading-1","heading-2","heading-3","headphones","heart","heart-eyes","heart-filled","heart-pulse","heartbeat","help-circle","holly","home","hospital","hotel","house","image","image-add","images","inbox","indent","info","info-filled","investment","invoice","italic","joy","joystick","key","kettlebell","keyboard","laptop","laugh","layers","layout","library","lighthouse","lightning","link","link-2","link-add","linkedin","list","list-bullet","list-numbered","loader","loading","lock","log-in","log-out","lungs","mail","mail-open","map","map-pin","mask","maximize","medal","medical-cross","menu","menu-alt","message-circle","message-square","mic","mic-off","microscope","minimize","minus","minus-circle","minus-square","monitor","monument","moon","moon-star","more-horizontal","more-vertical","mosque","motorcycle","mountain","mouse","mouse-pointer","move","museum","music","nerd","neutral","notification","obelisk","office","outdent","package","palette","panel-bottom","panel-left","panel-right","panel-top","paperclip","parking","pause","pause-filled","percent","phone","phone-call","phone-incoming","phone-off","phone-outgoing","piggy-bank","pill","pill-bottle","pin","play","play-circle","play-filled","plug","plus","plus-circle","plus-square","podium","pound-sign","printer","pulse","pyramid","qrcode","question","quote","racket","radio","rage","rain","rainbow","receipt","redo","refresh","refresh-cw","reindeer","rewind","road","rotate-ccw","rotate-cw","router","rss","running","sad","safe","save","scale","scale-weight","school","search","send","server","settings","share","share-2","share-alt","shield","shield-alert","shield-check","shield-x","shipping","shocked","shopping-bag","shrink","sick","sidebar-left","sidebar-right","silly","skate","ski","skip-back","skip-forward","skyscraper","sleepy","sleigh","sliders","smartphone","smartwatch","smile","snow","snowflake","snowman","sob","soccer","sort","sparkles","speaker","spinner","square","stadium","star","star-decoration","star-eyes","star-filled","stethoscope","stop","stop-filled","stopwatch","store","strikethrough","sun","sunrise","sunset","surfboard","surprised","swimming","sync","syringe","tablet","tablet-smartphone","tag","tags","target","taxi","temple","tennis","tent","terminal","test-tube","text-center","text-left","text-right","thermometer","thermometer-medical","thermometer-sun","thinking","thumb-down","thumb-up","tongue","tool","tooth","tower","train-station","trash","tree","trending-down","trending-neutral","trending-up","trophy","truck","tv","tv-minimal","twitter","type","umbrella","underline","undo","university","unlink","unlock","upload","usb","user","user-add","user-check","user-group","user-plus","user-remove","users","vaccine","van","vault","video","video-off","volleyball","volume","volume-down","volume-mute","volume-off","volume-up","wallet","warehouse","warning","warning-filled","watch","webcam","wheelchair","whistle","wifi","wifi-off","wind","windmill","wink","wreath","x","x-circle","x-circle-filled","yoga","youtube","zany","zap"];function H(t,e,p){const i=document.querySelector(".editor-spacer-picker");if(i){i.remove();return}const s=document.createElement("div");s.className="editor-spacer-picker";const n=document.createElement("div");n.className="editor-spacer-picker-label",n.textContent="Spacer height",s.appendChild(n);const l=document.createElement("div");l.className="editor-spacer-picker-row";const r=document.createElement("input");r.type="range",r.className="editor-spacer-slider",r.min="4",r.max="200",r.step="4",r.value=p;const d=document.createElement("span");d.className="editor-spacer-slider-value",d.textContent=p+"px",r.addEventListener("input",function(){d.textContent=this.value+"px"}),l.appendChild(r),l.appendChild(d),s.appendChild(l);const c=document.createElement("button");c.type="button",c.className="btn btn-primary btn-sm editor-spacer-insert-btn",c.textContent="Insert",s.appendChild(c);function m(b){!s.contains(b.target)&&b.target!==e&&(s.remove(),document.removeEventListener("click",m,!0))}c.addEventListener("click",function(){s.remove(),document.removeEventListener("click",m,!0),insertAtCursor(t,`[spacer size="${r.value}" /]
33
- `)});const o=e.getBoundingClientRect(),a=e.closest(".editor-toolbar").getBoundingClientRect();s.style.top=o.bottom-a.top+4+"px";const u=o.left-a.left;s.style.left=Math.min(u,a.width-240-8)+"px",e.closest(".editor-toolbar").appendChild(s),setTimeout(function(){document.addEventListener("click",m,!0)},0)}function A(t,e){const p=document.querySelector(".editor-icon-picker");if(p){p.remove();return}const i=document.createElement("div");i.className="editor-icon-picker";const s=document.createElement("input");s.type="text",s.className="form-input editor-icon-picker-search",s.placeholder="Search icons\u2026",i.appendChild(s);const n=document.createElement("div");n.className="editor-icon-picker-size-row";const l=document.createElement("label");l.textContent="Size (px)";const r=document.createElement("input");r.type="number",r.className="form-input editor-icon-picker-size",r.placeholder="default",r.min="8",r.max="256",n.appendChild(l),n.appendChild(r),i.appendChild(n);const d=document.createElement("div");d.className="editor-icon-picker-grid",i.appendChild(d);function c(g){!i.contains(g.target)&&g.target!==e&&(i.remove(),document.removeEventListener("click",c,!0))}function m(g){d.textContent="";const k=g?L.filter(f=>f.includes(g.toLowerCase())):L;if(k.length===0){const f=document.createElement("div");f.className="editor-icon-picker-empty",f.textContent="No icons found",d.appendChild(f);return}k.forEach(function(f){const v=document.createElement("button");v.type="button",v.className="editor-icon-picker-item";const w=document.createElement("span");w.setAttribute("data-icon",f);const y=document.createElement("span");y.textContent=f,v.appendChild(w),v.appendChild(y),v.addEventListener("click",function(){i.remove(),document.removeEventListener("click",c,!0);const C=r.value.trim(),M=C?`[icon name="${f}" size="${C}" /]`:`[icon name="${f}" /]`;insertAtCursor(t,M)}),d.appendChild(v)}),Domma.icons.scan(d)}m(""),s.addEventListener("input",function(){m(this.value.trim())});const o=e.getBoundingClientRect(),a=e.closest(".editor-toolbar").getBoundingClientRect();i.style.top=o.bottom-a.top+4+"px";const u=o.left-a.left,b=320,h=a.width;i.style.left=Math.min(u,h-b-8)+"px",e.closest(".editor-toolbar").appendChild(i),requestAnimationFrame(function(){s.focus()}),setTimeout(function(){document.addEventListener("click",c,!0)},0)}function j(t,e,p,i){const s=document.querySelector(".editor-toolbar-dropdown");if(s){s.remove();return}const n=document.createElement("div");n.className="editor-toolbar-dropdown",p.forEach(function(m){const o=document.createElement("button");if(o.type="button",o.className="editor-toolbar-dropdown-item",m.icon){const u=document.createElement("span");u.setAttribute("data-icon",m.icon),o.appendChild(u)}const a=document.createElement("span");a.textContent=m.label,o.appendChild(a),o.addEventListener("click",function(){n.remove(),document.removeEventListener("click",c,!0),x(m.action,t,e,i)}),n.appendChild(o)});const l=e.getBoundingClientRect(),r=e.closest(".editor-toolbar").getBoundingClientRect();n.style.top=l.bottom-r.top+4+"px";const d=l.left-r.left;n.style.left=Math.min(d,r.width-180-8)+"px",e.closest(".editor-toolbar").appendChild(n),Domma.icons.scan(n);function c(m){!n.contains(m.target)&&m.target!==e&&(n.remove(),document.removeEventListener("click",c,!0))}setTimeout(function(){document.addEventListener("click",c,!0)},0)}function x(t,e,p,i){const{spacerDefault:s,handlers:n}=i;if(typeof t=="function")t(e);else if(t==="button")if(n.button)n.button(e);else{const l=e.selectionStart,r=e.selectionEnd,c=`[button href="" variant="primary"]${e.value.substring(l,r)||"Click me"}[/button]`;e.value=e.value.substring(0,l)+c+e.value.substring(r),e.selectionStart=e.selectionEnd=l+14,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="linksc")if(n.linksc)n.linksc(e);else{const l=e.selectionStart,r=e.selectionEnd,c=`[link href=""]${e.value.substring(l,r)||"Link text"}[/link]`;e.value=e.value.substring(0,l)+c+e.value.substring(r),e.selectionStart=e.selectionEnd=l+12,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="link")n.link&&n.link(e);else if(t==="image")n.image&&n.image(e);else if(t==="card")if(n.card)n.card(e);else{const l=e.selectionStart,r=e.selectionEnd,c=`[card title="Card Title"]
32
+ [/fireworks]`,insert:!0},{label:"Celebrate",snippet:()=>'[celebrate theme="auto" intensity="medium" /]',insert:!0}];function N(t,e){const p=document.querySelector(".editor-effects-dropdown-menu");if(p){p.remove();return}const i=document.createElement("div");i.className="editor-effects-dropdown-menu",B.forEach(function(r){if(r.category){const d=document.createElement("div");d.className="editor-effects-category",d.textContent=r.category,i.appendChild(d)}else{const d=document.createElement("button");d.type="button",d.className="editor-effects-item",d.textContent=r.label,d.addEventListener("click",function(){if(i.remove(),r.insert)insertAtCursor(t,r.snippet(""));else{const c=t.selectionStart,h=t.selectionEnd,o=t.value.substring(c,h),a=r.snippet(o);t.value=t.value.substring(0,c)+a+t.value.substring(h),t.selectionStart=c,t.selectionEnd=c+a.length,t.dispatchEvent(new Event("input",{bubbles:!0})),t.focus()}}),i.appendChild(d)}});const s=e.getBoundingClientRect(),n=e.closest(".editor-toolbar").getBoundingClientRect();i.style.top=s.bottom-n.top+4+"px",i.style.left=s.left-n.left+"px",e.closest(".editor-toolbar").appendChild(i);function l(r){!i.contains(r.target)&&r.target!==e&&(i.remove(),document.removeEventListener("click",l,!0))}setTimeout(function(){document.addEventListener("click",l,!0)},0)}const L=["activity","airpods","airport","alert-circle","alert-warning","ambulance","angry","annoyed","apartment","arch","archive","arrow-down","arrow-down-left","arrow-down-right","arrow-left","arrow-right","arrow-up","arrow-up-left","arrow-up-right","astonished","at-sign","attachment","award","badge","ban","bandage","bank","banknote","barbell","barcode","barn","baseball","basketball","battery","battery-charging","bauble","bell","bell-off","bells","bicycle","bitcoin","blood-drop","blush","bold","bone","book","book-closed","book-open","bookmark","bookmark-filled","bowling","box","boxing-glove","brain","bridge","briefcase","building","bus","cabin","cake","calculator","calendar","camera","camera-off","candy-cane","capsule","car","cart","cart-add","cash","cast","castle","chart-area","chart-bar","chart-bar-horizontal","chart-candlestick","chart-line","chart-pie","chat","chat-alt","check","check-circle","check-circle-filled","check-square","chevron-down","chevron-left","chevron-right","chevron-up","chevrons-down","chevrons-left","chevrons-right","chevrons-up","church","circle","circle-filled","clear-format","clipboard","clipboard-check","clipboard-list","clock","close","cloud","cloud-download","cloud-drizzle","cloud-lightning","cloud-off","cloud-rain","cloud-sun","cloud-upload","code","code-block","code-inline","cog","coins","columns","comment","compass","component","confused","cool","copy","corner-down-left","corner-down-right","corner-up-left","corner-up-right","court","cpu","credit-card","crown","crutch","cry","currency-dollar","currency-euro","currency-pound","cycling","database","dead","desktop","disappointed","dna","document","document-add","document-check","document-remove","document-text","dollar-sign","dome","dot","dots-horizontal","dots-vertical","download","droplet","droplets","dumbbell","edit","embed","emoji-happy","emoji-sad","euro-sign","exclamation","expand","expressionless","external-link","eye","eye-medical","eye-off","factory","fast-forward","feather","file-code","file-text","file-zip","fill","film","filter","fire","first-aid","fishing","flag","fog","folder","folder-add","folder-minus","folder-open","folder-plus","folder-remove","football","fortress","fuel","gamepad","garage","gauge","gift","git-branch","github","globe","golf","grid","grin","growth","hard-drive","hash","haze","heading-1","heading-2","heading-3","headphones","heart","heart-eyes","heart-filled","heart-pulse","heartbeat","help-circle","holly","home","hospital","hotel","house","image","image-add","images","inbox","indent","info","info-filled","investment","invoice","italic","joy","joystick","key","kettlebell","keyboard","laptop","laugh","layers","layout","library","lighthouse","lightning","link","link-2","link-add","linkedin","list","list-bullet","list-numbered","loader","loading","lock","log-in","log-out","lungs","mail","mail-open","map","map-pin","mask","maximize","medal","medical-cross","menu","menu-alt","message-circle","message-square","mic","mic-off","microscope","minimize","minus","minus-circle","minus-square","monitor","monument","moon","moon-star","more-horizontal","more-vertical","mosque","motorcycle","mountain","mouse","mouse-pointer","move","museum","music","nerd","neutral","notification","obelisk","office","outdent","package","palette","panel-bottom","panel-left","panel-right","panel-top","paperclip","parking","pause","pause-filled","percent","phone","phone-call","phone-incoming","phone-off","phone-outgoing","piggy-bank","pill","pill-bottle","pin","play","play-circle","play-filled","plug","plus","plus-circle","plus-square","podium","pound-sign","printer","pulse","pyramid","qrcode","question","quote","racket","radio","rage","rain","rainbow","receipt","redo","refresh","refresh-cw","reindeer","rewind","road","rotate-ccw","rotate-cw","router","rss","running","sad","safe","save","scale","scale-weight","school","search","send","server","settings","share","share-2","share-alt","shield","shield-alert","shield-check","shield-x","shipping","shocked","shopping-bag","shrink","sick","sidebar-left","sidebar-right","silly","skate","ski","skip-back","skip-forward","skyscraper","sleepy","sleigh","sliders","smartphone","smartwatch","smile","snow","snowflake","snowman","sob","soccer","sort","sparkles","speaker","spinner","square","stadium","star","star-decoration","star-eyes","star-filled","stethoscope","stop","stop-filled","stopwatch","store","strikethrough","sun","sunrise","sunset","surfboard","surprised","swimming","sync","syringe","tablet","tablet-smartphone","tag","tags","target","taxi","temple","tennis","tent","terminal","test-tube","text-center","text-left","text-right","thermometer","thermometer-medical","thermometer-sun","thinking","thumb-down","thumb-up","tongue","tool","tooth","tower","train-station","trash","tree","trending-down","trending-neutral","trending-up","trophy","truck","tv","tv-minimal","twitter","type","umbrella","underline","undo","university","unlink","unlock","upload","usb","user","user-add","user-check","user-group","user-plus","user-remove","users","vaccine","van","vault","video","video-off","volleyball","volume","volume-down","volume-mute","volume-off","volume-up","wallet","warehouse","warning","warning-filled","watch","webcam","wheelchair","whistle","wifi","wifi-off","wind","windmill","wink","wreath","x","x-circle","x-circle-filled","yoga","youtube","zany","zap"];function H(t,e,p){const i=document.querySelector(".editor-spacer-picker");if(i){i.remove();return}const s=document.createElement("div");s.className="editor-spacer-picker";const n=document.createElement("div");n.className="editor-spacer-picker-label",n.textContent="Spacer height",s.appendChild(n);const l=document.createElement("div");l.className="editor-spacer-picker-row";const r=document.createElement("input");r.type="range",r.className="editor-spacer-slider",r.min="4",r.max="200",r.step="4",r.value=p;const d=document.createElement("span");d.className="editor-spacer-slider-value",d.textContent=p+"px",r.addEventListener("input",function(){d.textContent=this.value+"px"}),l.appendChild(r),l.appendChild(d),s.appendChild(l);const c=document.createElement("button");c.type="button",c.className="btn btn-primary btn-sm editor-spacer-insert-btn",c.textContent="Insert",s.appendChild(c);function h(b){!s.contains(b.target)&&b.target!==e&&(s.remove(),document.removeEventListener("click",h,!0))}c.addEventListener("click",function(){s.remove(),document.removeEventListener("click",h,!0),insertAtCursor(t,`[spacer size="${r.value}" /]
33
+ `)});const o=e.getBoundingClientRect(),a=e.closest(".editor-toolbar").getBoundingClientRect();s.style.top=o.bottom-a.top+4+"px";const u=o.left-a.left;s.style.left=Math.min(u,a.width-240-8)+"px",e.closest(".editor-toolbar").appendChild(s),setTimeout(function(){document.addEventListener("click",h,!0)},0)}function A(t,e){const p=document.querySelector(".editor-icon-picker");if(p){p.remove();return}const i=document.createElement("div");i.className="editor-icon-picker";const s=document.createElement("input");s.type="text",s.className="form-input editor-icon-picker-search",s.placeholder="Search icons\u2026",i.appendChild(s);const n=document.createElement("div");n.className="editor-icon-picker-size-row";const l=document.createElement("label");l.textContent="Size (px)";const r=document.createElement("input");r.type="number",r.className="form-input editor-icon-picker-size",r.placeholder="default",r.min="8",r.max="256",n.appendChild(l),n.appendChild(r),i.appendChild(n);const d=document.createElement("div");d.className="editor-icon-picker-grid",i.appendChild(d);function c(g){!i.contains(g.target)&&g.target!==e&&(i.remove(),document.removeEventListener("click",c,!0))}function h(g){d.textContent="";const k=g?L.filter(f=>f.includes(g.toLowerCase())):L;if(k.length===0){const f=document.createElement("div");f.className="editor-icon-picker-empty",f.textContent="No icons found",d.appendChild(f);return}k.forEach(function(f){const v=document.createElement("button");v.type="button",v.className="editor-icon-picker-item";const w=document.createElement("span");w.setAttribute("data-icon",f);const y=document.createElement("span");y.textContent=f,v.appendChild(w),v.appendChild(y),v.addEventListener("click",function(){i.remove(),document.removeEventListener("click",c,!0);const C=r.value.trim(),M=C?`[icon name="${f}" size="${C}" /]`:`[icon name="${f}" /]`;insertAtCursor(t,M)}),d.appendChild(v)}),Domma.icons.scan(d)}h(""),s.addEventListener("input",function(){h(this.value.trim())});const o=e.getBoundingClientRect(),a=e.closest(".editor-toolbar").getBoundingClientRect();i.style.top=o.bottom-a.top+4+"px";const u=o.left-a.left,b=320,m=a.width;i.style.left=Math.min(u,m-b-8)+"px",e.closest(".editor-toolbar").appendChild(i),requestAnimationFrame(function(){s.focus()}),setTimeout(function(){document.addEventListener("click",c,!0)},0)}function j(t,e,p,i){const s=document.querySelector(".editor-toolbar-dropdown");if(s){s.remove();return}const n=document.createElement("div");n.className="editor-toolbar-dropdown",p.forEach(function(h){const o=document.createElement("button");if(o.type="button",o.className="editor-toolbar-dropdown-item",h.icon){const u=document.createElement("span");u.setAttribute("data-icon",h.icon),o.appendChild(u)}const a=document.createElement("span");a.textContent=h.label,o.appendChild(a),o.addEventListener("click",function(){n.remove(),document.removeEventListener("click",c,!0),x(h.action,t,e,i)}),n.appendChild(o)});const l=e.getBoundingClientRect(),r=e.closest(".editor-toolbar").getBoundingClientRect();n.style.top=l.bottom-r.top+4+"px";const d=l.left-r.left;n.style.left=Math.min(d,r.width-180-8)+"px",e.closest(".editor-toolbar").appendChild(n),Domma.icons.scan(n);function c(h){!n.contains(h.target)&&h.target!==e&&(n.remove(),document.removeEventListener("click",c,!0))}setTimeout(function(){document.addEventListener("click",c,!0)},0)}function x(t,e,p,i){const{spacerDefault:s,handlers:n}=i;if(typeof t=="function")t(e);else if(t==="button")if(n.button)n.button(e);else{const l=e.selectionStart,r=e.selectionEnd,c=`[button href="" variant="primary"]${e.value.substring(l,r)||"Click me"}[/button]`;e.value=e.value.substring(0,l)+c+e.value.substring(r),e.selectionStart=e.selectionEnd=l+14,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="linksc")if(n.linksc)n.linksc(e);else{const l=e.selectionStart,r=e.selectionEnd,c=`[link href=""]${e.value.substring(l,r)||"Link text"}[/link]`;e.value=e.value.substring(0,l)+c+e.value.substring(r),e.selectionStart=e.selectionEnd=l+12,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="link")n.link&&n.link(e);else if(t==="image")n.image&&n.image(e);else if(t==="card")if(n.card)n.card(e);else{const l=e.selectionStart,r=e.selectionEnd,c=`[card title="Card Title"]
34
34
  ${e.value.substring(l,r)||"Content here"}
35
- [/card]`;e.value=e.value.substring(0,l)+c+e.value.substring(r),e.selectionStart=l+13,e.selectionEnd=l+23,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="grid")if(n.grid)n.grid(e);else{const l=e.selectionStart,r=`[grid cols="2" gap="4"]
35
+ [/card]`;e.value=e.value.substring(0,l)+c+e.value.substring(r),e.selectionStart=l+13,e.selectionEnd=l+23,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="hero"){const l=e.selectionStart,r=e.selectionEnd,c=`[hero title="Hero Title" tagline="A short tagline" size="lg" variant="gradient-blue"]
36
+ ${e.value.substring(l,r)||"Optional body content here."}
37
+ [/hero]`;e.value=e.value.substring(0,l)+c+e.value.substring(r),e.selectionStart=e.selectionEnd=l+c.length,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else if(t==="grid")if(n.grid)n.grid(e);else{const l=e.selectionStart,r=`[grid cols="2" gap="4"]
36
38
  [col]
37
39
  Column 1
38
40
  [/col]
@@ -54,5 +56,5 @@ Describe this event.
54
56
  [/accordion]
55
57
  `;e.value=e.value.substring(0,l)+r+e.value.substring(l),e.selectionStart=e.selectionEnd=l+r.length,e.dispatchEvent(new Event("input",{bubbles:!0})),e.focus()}else t==="help"&&n.help&&n.help(e)}const S=[{icon:"bold",title:"Bold (Ctrl+B)",action:t=>wrapSelection(t,"**","**")},{icon:"italic",title:"Italic (Ctrl+I)",action:t=>wrapSelection(t,"_","_")},{icon:"strikethrough",title:"Strikethrough",action:t=>wrapSelection(t,"~~","~~")},"|",{type:"dropdown",icon:"heading-1",title:"Headings",items:[{label:"Heading 1",icon:"heading-1",action:t=>insertLine(t,"# ")},{label:"Heading 2",icon:"heading-2",action:t=>insertLine(t,"## ")},{label:"Heading 3",icon:"heading-3",action:t=>insertLine(t,"### ")}]},"|",{icon:"list-bullet",title:"Bullet list",action:t=>insertLine(t,"- ")},{icon:"list-numbered",title:"Numbered list",action:t=>insertLine(t,"1. ")},"|",{type:"dropdown",icon:"quote",title:"Paragraph",items:[{label:"Blockquote",icon:"quote",action:t=>insertLine(t,"> ")},{label:"Horizontal rule",icon:"minus-circle",action:t=>insertAtCursor(t,`
56
58
  ---
57
- `)}]},"|",{type:"dropdown",icon:"code-inline",title:"Code",items:[{label:"Inline code",icon:"code-inline",action:t=>wrapSelection(t,"`","`")},{label:"Code block",icon:"code-block",action:t=>wrapSelection(t,"\n```\n","\n```\n")}]},"|",{type:"dropdown",icon:"plus-circle",title:"Insert",items:[{label:"Image",icon:"image-add",action:"image"},{label:"Card",icon:"card",action:"card"},{label:"Grid",icon:"columns",action:"grid"},{label:"Badge",icon:"badge",action:"badge"},{label:"Timeline",icon:"activity",action:"timeline"},{label:"Spacer",icon:"spacer-insert",action:"spacerpick"},{label:"Icon",icon:"icon-pick",action:"iconpick"},{label:"Collection",icon:"database",action:"collection"},{label:"View",icon:"eye",action:"view"},{label:"Button",icon:"btn-insert",action:"button"},{label:"Link",icon:"link-shortcode",action:"linksc"},{label:"Tabs",icon:"layout-list",action:"tabs"},{label:"Accordion",icon:"accordion-insert",action:"accordion"},{label:"CTA Button",icon:"mouse-pointer",action:"cta"},{label:"Form",icon:"file-text",action:"form"}]},"|",{icon:"sparkles",title:"Effects",action:"effects"},{icon:"help-circle",title:"Editor help",action:"help"}];export function createToolbar(t,e,p={}){z();const i={link:null,image:null,card:null,grid:null,help:null,effects:null,collection:null,view:null,cta:null,form:null,button:null,linksc:null,tabs:null,accordion:null},s=p.spacerDefault??40,n=t.get(0),l=e.get(0);l.textContent="",S.forEach((o,a)=>{if(o==="|"){const u=document.createElement("span");u.className="editor-toolbar-sep",l.appendChild(u)}else{const u=document.createElement("button");u.className=o.type==="dropdown"?"editor-toolbar-btn editor-toolbar-dropdown-trigger":"editor-toolbar-btn",u.setAttribute("data-tooltip",o.title),u.setAttribute("data-idx",String(a)),u.type="button";const b=document.createElement("span");if(b.setAttribute("data-icon",o.icon),u.appendChild(b),o.type==="dropdown"){const h=document.createElement("span");h.className="editor-toolbar-caret",h.textContent="\u25BE",u.appendChild(h)}l.appendChild(u)}});const r=document.createElement("div");r.className="editor-toolbar-right",[{mode:"split",icon:"columns",label:"Split view",active:!0},{mode:"write",icon:"file-text",label:"Write only",active:!1},{mode:"preview",icon:"eye",label:"Preview only",active:!1}].forEach(o=>{const a=document.createElement("button");a.className="editor-view-btn"+(o.active?" active":""),a.setAttribute("data-mode",o.mode),a.setAttribute("data-tooltip",o.label),a.type="button";const u=document.createElement("span");u.setAttribute("data-icon",o.icon),a.appendChild(u),r.appendChild(a)});const d=document.createElement("span");d.className="editor-toolbar-sep",r.appendChild(d);const c=document.createElement("button");c.id="fullscreen-btn",c.className="editor-toolbar-btn",c.setAttribute("data-tooltip","Toggle fullscreen"),c.type="button";const m=document.createElement("span");return m.setAttribute("data-icon","expand"),c.appendChild(m),r.appendChild(c),l.appendChild(r),Domma.icons.scan(),l.querySelectorAll("[data-tooltip]").forEach(o=>{E.tooltip(o,{content:o.getAttribute("data-tooltip"),position:"top"})}),e.on("click",".editor-toolbar-btn[data-idx]",function(){const o=parseInt($(this).data("idx"),10),a=S[o];if(!a||a==="|")return;const u=e.get(0).querySelector(`[data-idx="${o}"]`),b={spacerDefault:s,handlers:i};a.type==="dropdown"?j(n,u,a.items,b):x(a.action,n,u,b)}),t.on("keydown",function(o){const a=o.key.toLowerCase();if(o.ctrlKey||o.metaKey)a==="b"?(o.preventDefault(),wrapSelection(n,"**","**")):a==="i"?(o.preventDefault(),wrapSelection(n,"_","_")):a==="k"&&(o.preventDefault(),i.link&&i.link(n));else if(o.key==="Tab")if(o.preventDefault(),o.shiftKey){const u=n.value.lastIndexOf(`
58
- `,n.selectionStart-1)+1,b=n.value.substring(u),h=b.match(/^ {1,4}/);if(h){const g=n.value.substring(0,u),k=n.value.substring(u+h[0].length);n.value=g+b.substring(h[0].length),n.selectionStart=n.selectionEnd=Math.max(u,n.selectionStart-h[0].length),n.dispatchEvent(new Event("input",{bubbles:!0}))}}else insertAtCursor(n," ")}),{$toolbar:e,onLink(o){i.link=o},onImage(o){i.image=o},onCard(o){i.card=o},onGrid(o){i.grid=o},onHelp(o){i.help=o},onEffects(o){i.effects=o},onCollection(o){i.collection=o},onView(o){i.view=o},onCta(o){i.cta=o},onForm(o){i.form=o},onButton(o){i.button=o},onLinkShortcode(o){i.linksc=o},onTabs(o){i.tabs=o},onAccordion(o){i.accordion=o}}}
59
+ `)}]},"|",{type:"dropdown",icon:"code-inline",title:"Code",items:[{label:"Inline code",icon:"code-inline",action:t=>wrapSelection(t,"`","`")},{label:"Code block",icon:"code-block",action:t=>wrapSelection(t,"\n```\n","\n```\n")}]},"|",{type:"dropdown",icon:"plus-circle",title:"Insert",items:[{label:"Accordion",icon:"accordion-insert",action:"accordion"},{label:"Badge",icon:"badge",action:"badge"},{label:"Button",icon:"btn-insert",action:"button"},{label:"Card",icon:"card",action:"card"},{label:"Collection",icon:"database",action:"collection"},{label:"CTA Button",icon:"mouse-pointer",action:"cta"},{label:"Form",icon:"file-text",action:"form"},{label:"Grid",icon:"columns",action:"grid"},{label:"Hero",icon:"hero",action:"hero"},{label:"Icon",icon:"icon-pick",action:"iconpick"},{label:"Image",icon:"image-add",action:"image"},{label:"Link",icon:"link-shortcode",action:"linksc"},{label:"Spacer",icon:"spacer-insert",action:"spacerpick"},{label:"Tabs",icon:"layout-list",action:"tabs"},{label:"Timeline",icon:"activity",action:"timeline"},{label:"View",icon:"eye",action:"view"}]},"|",{icon:"sparkles",title:"Effects",action:"effects"},{icon:"help-circle",title:"Editor help",action:"help"}];export function createToolbar(t,e,p={}){z();const i={link:null,image:null,card:null,grid:null,help:null,effects:null,collection:null,view:null,cta:null,form:null,button:null,linksc:null,tabs:null,accordion:null},s=p.spacerDefault??40,n=t.get(0),l=e.get(0);l.textContent="",S.forEach((o,a)=>{if(o==="|"){const u=document.createElement("span");u.className="editor-toolbar-sep",l.appendChild(u)}else{const u=document.createElement("button");u.className=o.type==="dropdown"?"editor-toolbar-btn editor-toolbar-dropdown-trigger":"editor-toolbar-btn",u.setAttribute("data-tooltip",o.title),u.setAttribute("data-idx",String(a)),u.type="button";const b=document.createElement("span");if(b.setAttribute("data-icon",o.icon),u.appendChild(b),o.type==="dropdown"){const m=document.createElement("span");m.className="editor-toolbar-caret",m.textContent="\u25BE",u.appendChild(m)}l.appendChild(u)}});const r=document.createElement("div");r.className="editor-toolbar-right",[{mode:"split",icon:"columns",label:"Split view",active:!0},{mode:"write",icon:"file-text",label:"Write only",active:!1},{mode:"preview",icon:"eye",label:"Preview only",active:!1}].forEach(o=>{const a=document.createElement("button");a.className="editor-view-btn"+(o.active?" active":""),a.setAttribute("data-mode",o.mode),a.setAttribute("data-tooltip",o.label),a.type="button";const u=document.createElement("span");u.setAttribute("data-icon",o.icon),a.appendChild(u),r.appendChild(a)});const d=document.createElement("span");d.className="editor-toolbar-sep",r.appendChild(d);const c=document.createElement("button");c.id="fullscreen-btn",c.className="editor-toolbar-btn",c.setAttribute("data-tooltip","Toggle fullscreen"),c.type="button";const h=document.createElement("span");return h.setAttribute("data-icon","expand"),c.appendChild(h),r.appendChild(c),l.appendChild(r),Domma.icons.scan(),l.querySelectorAll("[data-tooltip]").forEach(o=>{E.tooltip(o,{content:o.getAttribute("data-tooltip"),position:"top"})}),e.on("click",".editor-toolbar-btn[data-idx]",function(){const o=parseInt($(this).data("idx"),10),a=S[o];if(!a||a==="|")return;const u=e.get(0).querySelector(`[data-idx="${o}"]`),b={spacerDefault:s,handlers:i};a.type==="dropdown"?j(n,u,a.items,b):x(a.action,n,u,b)}),t.on("keydown",function(o){const a=o.key.toLowerCase();if(o.ctrlKey||o.metaKey)a==="b"?(o.preventDefault(),wrapSelection(n,"**","**")):a==="i"?(o.preventDefault(),wrapSelection(n,"_","_")):a==="k"&&(o.preventDefault(),i.link&&i.link(n));else if(o.key==="Tab")if(o.preventDefault(),o.shiftKey){const u=n.value.lastIndexOf(`
60
+ `,n.selectionStart-1)+1,b=n.value.substring(u),m=b.match(/^ {1,4}/);if(m){const g=n.value.substring(0,u),k=n.value.substring(u+m[0].length);n.value=g+b.substring(m[0].length),n.selectionStart=n.selectionEnd=Math.max(u,n.selectionStart-m[0].length),n.dispatchEvent(new Event("input",{bubbles:!0}))}}else insertAtCursor(n," ")}),{$toolbar:e,onLink(o){i.link=o},onImage(o){i.image=o},onCard(o){i.card=o},onGrid(o){i.grid=o},onHelp(o){i.help=o},onEffects(o){i.effects=o},onCollection(o){i.collection=o},onView(o){i.view=o},onCta(o){i.cta=o},onForm(o){i.form=o},onButton(o){i.button=o},onLinkShortcode(o){i.linksc=o},onTabs(o){i.tabs=o},onAccordion(o){i.accordion=o}}}
@@ -1,6 +1,10 @@
1
1
  <div class="view-header">
2
2
  <h1><span data-icon="file-text"></span> Pages</h1>
3
- <a href="#/pages/new" class="btn btn-primary"><span data-icon="plus"></span> New Page</a>
3
+ <div style="display:flex;gap:.5rem;align-items:center;margin-left:auto;">
4
+ <input id="pages-search" type="text" class="form-input form-input-sm" placeholder="Search pages…"
5
+ style="width:220px;">
6
+ <a href="#/pages/new" class="btn btn-primary"><span data-icon="plus"></span> New Page</a>
7
+ </div>
4
8
  </div>
5
9
 
6
10
  <div class="toolbar mb-3" style="display:flex;gap:.5rem;align-items:center;flex-wrap:wrap;">
@@ -1,5 +1,5 @@
1
- import{api as d}from"../api.js";export const pagesView={templateUrl:"/admin/js/templates/pages.html",async onMount(e){const c=E.loader(e.get(0),{type:"dots"});let n=await d.pages.list().catch(()=>[]);c.destroy();const l=s=>{T.create("#pages-table",{data:s,columns:[{key:"title",title:"Title",render:(t,a)=>`<a href="#/pages/edit${a.urlPath}">${t}</a>`},{key:"urlPath",title:"URL",render:t=>`<code>${t}</code>`},{key:"layout",title:"Layout"},{key:"status",title:"Status",render:t=>`<span class="badge badge-${t==="published"?"success":"warning"}">${t}</span>`},{key:"tags",title:"Tags",render:t=>Array.isArray(t)&&t.length?t.map(a=>`<span class="badge badge-info badge-pill badge-sm">${a}</span>`).join(" "):"\u2014"},{key:"updatedAt",title:"Updated",render:t=>t?D(t).format("DD MMM YYYY"):"\u2014"},{key:"actions",title:"Actions",render:(t,a)=>`
1
+ import{api as p}from"../api.js";export const pagesView={templateUrl:"/admin/js/templates/pages.html",async onMount(e){const c=E.loader(e.get(0),{type:"dots"});let i=await p.pages.list().catch(()=>[]);c.destroy();const l=s=>{T.create("#pages-table",{data:s,columns:[{key:"title",title:"Title",render:(t,a)=>`<a href="#/pages/edit${a.urlPath}">${t}</a>`},{key:"urlPath",title:"URL",render:t=>`<code>${t}</code>`},{key:"layout",title:"Layout"},{key:"status",title:"Status",render:t=>`<span class="badge badge-${t==="published"?"success":"warning"}">${t}</span>`},{key:"tags",title:"Tags",render:t=>Array.isArray(t)&&t.length?t.map(a=>`<span class="badge badge-info badge-pill badge-sm">${a}</span>`).join(" "):"\u2014"},{key:"updatedAt",title:"Updated",render:t=>t?D(t).format("DD MMM YYYY"):"\u2014"},{key:"actions",title:"Actions",render:(t,a)=>`
2
2
  <a href="#/pages/edit${a.urlPath}" class="btn btn-sm btn-primary">Edit</a>
3
3
  <a href="${a.urlPath}" target="_blank" class="btn btn-sm btn-ghost" data-tooltip="View"><span data-icon="external-link"></span></a>
4
4
  <button class="btn btn-sm btn-danger btn-delete" data-path="${a.urlPath}">Delete</button>
5
- `}],emptyMessage:'No pages found. <a href="#/pages/new">Create one</a>.'}),Domma.icons.scan(),document.querySelectorAll("#pages-table [data-tooltip]").forEach(t=>{E.tooltip(t,{content:t.getAttribute("data-tooltip"),position:"top"})}),Domma.effects.reveal(".card",{animation:"fade",duration:350})};l(n);const p=s=>{const t=e.find("#pages-tree").empty().get(0);if(!s.length){t.textContent="No pages found.";return}const a=s.map(i=>{const r=i.urlPath.split("/").filter(Boolean),o=r.length>1?"/"+r.slice(0,-1).join("/"):null,g=o&&s.some(b=>b.urlPath===o);return{id:i.urlPath,parent_id:g?o:null,name:i.title||i.urlPath,icon:i.status==="published"?"check-circle":"file-text"}});E.treeView(t,{data:a,idKey:"id",parentKey:"parent_id",labelKey:"name",iconKey:"icon",expandedByDefault:!0,onSelect:i=>{R.navigate(`/pages/edit${i}`)}}),Domma.icons.scan(t)};e.find("#view-table-btn").on("click",function(){e.find("#pages-table").show(),e.find("#pages-tree").hide(),$(this).addClass("btn-primary").removeClass("btn-ghost"),e.find("#view-tree-btn").addClass("btn-ghost").removeClass("btn-primary")}),e.find("#view-tree-btn").on("click",function(){e.find("#pages-table").hide(),e.find("#pages-tree").show(),$(this).addClass("btn-primary").removeClass("btn-ghost"),e.find("#view-table-btn").addClass("btn-ghost").removeClass("btn-primary"),p(n)}),e.find("#view-table-btn, #view-tree-btn").each(function(){E.tooltip(this,{content:this.getAttribute("data-tooltip"),position:"top"})}),e.find("#status-filter").off("change").on("change",function(){const s=$(this).val(),t=s?n.filter(a=>a.status===s):n;l(t)}),e.off("click",".btn-delete").on("click",".btn-delete",async function(){const s=$(this).data("path");if(await E.confirm(`Delete page at <strong>${s}</strong>? This cannot be undone.`))try{await d.pages.delete(s),E.toast("Page deleted.",{type:"success"}),n=n.filter(a=>a.urlPath!==s),l(n)}catch{E.toast("Failed to delete page.",{type:"error"})}})}};
5
+ `}],emptyMessage:'No pages found. <a href="#/pages/new">Create one</a>.'}),Domma.icons.scan(),document.querySelectorAll("#pages-table [data-tooltip]").forEach(t=>{E.tooltip(t,{content:t.getAttribute("data-tooltip"),position:"top"})}),Domma.effects.reveal(".card",{animation:"fade",duration:350})};l(i);const u=s=>{const t=e.find("#pages-tree").empty().get(0);if(!s.length){t.textContent="No pages found.";return}const a=s.map(n=>{const d=n.urlPath.split("/").filter(Boolean),r=d.length>1?"/"+d.slice(0,-1).join("/"):null,g=r&&s.some(f=>f.urlPath===r);return{id:n.urlPath,parent_id:g?r:null,name:n.title||n.urlPath,icon:n.status==="published"?"check-circle":"file-text"}});E.treeView(t,{data:a,idKey:"id",parentKey:"parent_id",labelKey:"name",iconKey:"icon",expandedByDefault:!0,onSelect:n=>{R.navigate(`/pages/edit${n}`)}}),Domma.icons.scan(t)};e.find("#view-table-btn").on("click",function(){e.find("#pages-table").show(),e.find("#pages-tree").hide(),$(this).addClass("btn-primary").removeClass("btn-ghost"),e.find("#view-tree-btn").addClass("btn-ghost").removeClass("btn-primary")}),e.find("#view-tree-btn").on("click",function(){e.find("#pages-table").hide(),e.find("#pages-tree").show(),$(this).addClass("btn-primary").removeClass("btn-ghost"),e.find("#view-table-btn").addClass("btn-ghost").removeClass("btn-primary"),u(i)}),e.find("#view-table-btn, #view-tree-btn").each(function(){E.tooltip(this,{content:this.getAttribute("data-tooltip"),position:"top"})});const o=()=>{const s=e.find("#status-filter").val(),t=e.find("#pages-search").val().toLowerCase().trim(),a=i.filter(n=>!(s&&n.status!==s||t&&!`${n.title} ${n.urlPath} ${(n.tags||[]).join(" ")}`.toLowerCase().includes(t)));l(a)};e.find("#status-filter").off("change").on("change",o),e.find("#pages-search").get(0).addEventListener("input",o),e.off("click",".btn-delete").on("click",".btn-delete",async function(){const s=$(this).data("path");if(await E.confirm(`Delete page at <strong>${s}</strong>? This cannot be undone.`))try{await p.pages.delete(s),E.toast("Page deleted.",{type:"success"}),i=i.filter(a=>a.urlPath!==s),l(i)}catch{E.toast("Failed to delete page.",{type:"error"})}})}};
@@ -9,7 +9,13 @@
9
9
  },
10
10
  "site-search": {
11
11
  "enabled": true,
12
- "settings": {}
12
+ "settings": {
13
+ "placeholder": "Search",
14
+ "keyboardShortcut": false,
15
+ "maxResults": 10,
16
+ "minQueryLength": 2,
17
+ "debounceMs": 300
18
+ }
13
19
  },
14
20
  "domma-effects": {
15
21
  "enabled": true,
@@ -19,5 +25,9 @@
19
25
  "defaultAnimation": "fade",
20
26
  "defaultThreshold": 0.1
21
27
  }
28
+ },
29
+ "job-board": {
30
+ "enabled": false,
31
+ "settings": {}
22
32
  }
23
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "0.6.14",
3
+ "version": "0.6.16",
4
4
  "description": "File-based CMS powered by Domma and Fastify. Run npx domma-cms my-site to create a new project.",
5
5
  "type": "module",
6
6
  "main": "server/server.js",
@@ -1,6 +1,6 @@
1
1
  {
2
- "/": 140,
3
- "/about": 71,
2
+ "/": 156,
3
+ "/about": 74,
4
4
  "/blog": 36,
5
5
  "/contact": 30,
6
6
  "/resources/typography": 4,
@@ -16,7 +16,7 @@
16
16
  "/resources/dependencies": 2,
17
17
  "/resources/components": 6,
18
18
  "/gdpr": 3,
19
- "/scratch": 69,
19
+ "/scratch": 70,
20
20
  "/getting-started": 3,
21
21
  "/resources/pro": 1,
22
22
  "/todo": 23,
@@ -0,0 +1,66 @@
1
+ {
2
+ "slug": "contacts",
3
+ "title": "Contacts",
4
+ "description": "Contact Information",
5
+ "fields": [
6
+ {
7
+ "name": "full_name",
8
+ "type": "string",
9
+ "label": "Full Name",
10
+ "required": false,
11
+ "placeholder": "Full Name",
12
+ "helper": "Full Name",
13
+ "minLength": 8,
14
+ "maxLength": 255
15
+ },
16
+ {
17
+ "type": "spacer"
18
+ },
19
+ {
20
+ "name": "phone_number",
21
+ "type": "tel",
22
+ "label": "Phone Number",
23
+ "required": false,
24
+ "placeholder": "Phone Number",
25
+ "helper": "Primary Phone Number"
26
+ },
27
+ {
28
+ "type": "spacer"
29
+ },
30
+ {
31
+ "name": "email_address",
32
+ "type": "string",
33
+ "label": "Email Address",
34
+ "required": false,
35
+ "placeholder": "Email Address",
36
+ "helper": "Email Address",
37
+ "minLength": 8,
38
+ "maxLength": 255
39
+ }
40
+ ],
41
+ "settings": {
42
+ "submitText": "Submit",
43
+ "successMessage": "Thank you for your submission.",
44
+ "layout": "stacked",
45
+ "honeypot": true,
46
+ "rateLimitPerMinute": 3
47
+ },
48
+ "actions": {
49
+ "email": {
50
+ "enabled": false,
51
+ "recipients": "",
52
+ "subjectPrefix": "[Contacts]"
53
+ },
54
+ "webhook": {
55
+ "enabled": false,
56
+ "url": "",
57
+ "method": "POST"
58
+ },
59
+ "collection": {
60
+ "enabled": true,
61
+ "slug": "contacts"
62
+ }
63
+ },
64
+ "createdAt": "2026-03-17T12:35:44.569Z",
65
+ "updatedAt": "2026-03-17T12:35:44.569Z"
66
+ }
@@ -0,0 +1,103 @@
1
+ {
2
+ "slug": "enquiries",
3
+ "title": "Enquiries",
4
+ "description": "Get in touch with us",
5
+ "fields": [
6
+ {
7
+ "name": "full_name",
8
+ "type": "string",
9
+ "label": "Full Name",
10
+ "required": true,
11
+ "placeholder": "Your full name",
12
+ "helper": "",
13
+ "validation": {
14
+ "min": 2,
15
+ "max": 100
16
+ }
17
+ },
18
+ {
19
+ "name": "email",
20
+ "type": "email",
21
+ "label": "Email Address",
22
+ "required": true,
23
+ "placeholder": "your@email.com",
24
+ "helper": ""
25
+ },
26
+ {
27
+ "name": "phone",
28
+ "type": "tel",
29
+ "label": "Phone Number",
30
+ "required": false,
31
+ "placeholder": "+44 7700 000000",
32
+ "helper": "Optional"
33
+ },
34
+ {
35
+ "name": "subject",
36
+ "type": "select",
37
+ "label": "Subject",
38
+ "required": true,
39
+ "placeholder": "Please select a subject",
40
+ "helper": "",
41
+ "options": [
42
+ {
43
+ "value": "general",
44
+ "label": "General Enquiry"
45
+ },
46
+ {
47
+ "value": "support",
48
+ "label": "Support"
49
+ },
50
+ {
51
+ "value": "sales",
52
+ "label": "Sales"
53
+ },
54
+ {
55
+ "value": "partnership",
56
+ "label": "Partnership"
57
+ },
58
+ {
59
+ "value": "other",
60
+ "label": "Other"
61
+ }
62
+ ]
63
+ },
64
+ {
65
+ "name": "message",
66
+ "type": "textarea",
67
+ "label": "Message",
68
+ "required": true,
69
+ "placeholder": "How can we help you?",
70
+ "helper": "",
71
+ "rows": 4,
72
+ "validation": {
73
+ "min": 10,
74
+ "max": 2000
75
+ }
76
+ }
77
+ ],
78
+ "settings": {
79
+ "submitText": "Send Message",
80
+ "successMessage": "Thanks for reaching out! We'll get back to you shortly.",
81
+ "layout": "stacked",
82
+ "honeypot": true,
83
+ "rateLimitPerMinute": 3
84
+ },
85
+ "actions": {
86
+ "email": {
87
+ "enabled": false,
88
+ "recipients": "",
89
+ "subjectPrefix": "[enquiries]"
90
+ },
91
+ "webhook": {
92
+ "enabled": false,
93
+ "url": "",
94
+ "method": "POST"
95
+ },
96
+ "collection": {
97
+ "enabled": true,
98
+ "slug": "enquiries"
99
+ }
100
+ },
101
+ "createdAt": "2026-03-17T12:35:44.569Z",
102
+ "updatedAt": "2026-03-17T12:35:44.569Z"
103
+ }