create-shibumi 0.0.1 → 0.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/LICENSE +21 -0
- package/README.md +44 -2
- package/package.json +57 -5
- package/scripts/shibumi.lock.json +22 -0
- package/scripts/ship.lock.json +4 -0
- package/src/args.ts +162 -0
- package/src/cli.ts +232 -0
- package/src/create.ts +272 -0
- package/src/templates/blog/README.md +10 -0
- package/src/templates/blog/agents.md +36 -0
- package/src/templates/blog/astro.config.mjs +13 -0
- package/src/templates/blog/bun.lock +787 -0
- package/src/templates/blog/gitignore +4 -0
- package/src/templates/blog/package.json +29 -0
- package/src/templates/blog/public/og-default.png +0 -0
- package/src/templates/blog/public/style.css +147 -0
- package/src/templates/blog/src/components/BaseHead.astro +37 -0
- package/src/templates/blog/src/content/blog/one-vps-is-plenty.md +13 -0
- package/src/templates/blog/src/content/blog/own-your-source.md +13 -0
- package/src/templates/blog/src/content/blog/writing-for-agents.md +13 -0
- package/src/templates/blog/src/content.config.ts +17 -0
- package/src/templates/blog/src/layouts/Base.astro +26 -0
- package/src/templates/blog/src/pages/404.astro +11 -0
- package/src/templates/blog/src/pages/index.astro +30 -0
- package/src/templates/blog/src/pages/llms.txt.ts +29 -0
- package/src/templates/blog/src/pages/posts/[id].astro +31 -0
- package/src/templates/blog/src/pages/posts/[id].md.ts +18 -0
- package/src/templates/blog/src/pages/robots.txt.ts +6 -0
- package/src/templates/blog/src/pages/rss.xml.ts +21 -0
- package/src/templates/blog/src/site.ts +7 -0
- package/src/templates/blog/tsconfig.json +5 -0
- package/src/templates/full-stack/.dockerignore +14 -0
- package/src/templates/full-stack/Dockerfile +23 -0
- package/src/templates/full-stack/README.md +10 -0
- package/src/templates/full-stack/agents.md +60 -0
- package/src/templates/full-stack/bun.lock +225 -0
- package/src/templates/full-stack/compose.yaml +24 -0
- package/src/templates/full-stack/drizzle.config.ts +11 -0
- package/src/templates/full-stack/gitignore +6 -0
- package/src/templates/full-stack/package.json +39 -0
- package/src/templates/full-stack/public/app.js +11 -0
- package/src/templates/full-stack/public/style.css +60 -0
- package/src/templates/full-stack/public/vendor/alpine-csp-3.16.2.min.js +23 -0
- package/src/templates/full-stack/scripts/db.ts +39 -0
- package/src/templates/full-stack/src/app.ts +106 -0
- package/src/templates/full-stack/src/db/index.ts +11 -0
- package/src/templates/full-stack/src/db/lifecycle.ts +214 -0
- package/src/templates/full-stack/src/db/migrations/0001_notes.sql +9 -0
- package/src/templates/full-stack/src/db/schema.ts +13 -0
- package/src/templates/full-stack/src/env.ts +24 -0
- package/src/templates/full-stack/src/server.ts +30 -0
- package/src/templates/full-stack/test/app.test.ts +144 -0
- package/src/templates/full-stack/test/db.test.ts +169 -0
- package/src/templates/full-stack/tsconfig.json +19 -0
- package/src/templates/shibumi.ts +809 -0
- package/src/templates/ship.ts +2056 -0
- package/src/templates/static/README.md +10 -0
- package/src/templates/static/agents.md +31 -0
- package/src/templates/static/gitignore +2 -0
- package/src/templates/static/package.json +17 -0
- package/src/templates/static/public/404.html +15 -0
- package/src/templates/static/public/index.html +16 -0
- package/src/templates/static/public/style.css +50 -0
- package/src/templates/static/scripts/preview.ts +42 -0
- package/src/templates/web/.dockerignore +12 -0
- package/src/templates/web/Dockerfile +24 -0
- package/src/templates/web/README.md +10 -0
- package/src/templates/web/agents.md +54 -0
- package/src/templates/web/bun.lock +45 -0
- package/src/templates/web/compose.yaml +17 -0
- package/src/templates/web/gitignore +5 -0
- package/src/templates/web/package.json +33 -0
- package/src/templates/web/public/app.js +11 -0
- package/src/templates/web/public/style.css +60 -0
- package/src/templates/web/public/vendor/alpine-csp-3.16.2.min.js +23 -0
- package/src/templates/web/src/app.ts +96 -0
- package/src/templates/web/src/env.ts +21 -0
- package/src/templates/web/src/server.ts +23 -0
- package/src/templates/web/test/app.test.ts +137 -0
- package/src/templates/web/tsconfig.json +13 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
(()=>{var gt=!1,yt=!1,B=[],xt=-1,je=!1,Et=!1;function br(e){fn(e)}function vr(){Et=!0}function wr(){Et=!1,Or()}function fn(e){B.includes(e)||(B.push(e),e._x_schedulerPriority!==void 0&&(je=!0)),Or()}function Ar(e){let t=B.indexOf(e);t!==-1&&t>xt&&B.splice(t,1)}function Or(){if(!yt&&!gt){if(Et)return;gt=!0,queueMicrotask(pn)}}function pn(){gt=!1,yt=!0;for(let e=0;e<B.length;e++)je&&dn(e),B[e](),xt=e;B.length=0,xt=-1,je=!1,yt=!1}function dn(e){let t=new Map,r=B.slice(e).sort((i,n)=>hn(i,n,t));for(let i=0;i<r.length;i++)B[e+i]=r[i];je=!1}function hn(e,t,r){return _t(e)?_t(t)?Er(e._x_schedulerPriority.el,r)-Er(t._x_schedulerPriority.el,r)||e._x_schedulerPriority.order-t._x_schedulerPriority.order:-1:_t(t)?1:0}function _t(e){return e._x_schedulerPriority!==void 0}function Er(e,t){if(t.has(e))return t.get(e);let r=0,i=e;for(;e;)r++,e._x_teleportBack?e=e._x_teleportBack:typeof ShadowRoot=="function"&&e.parentNode instanceof ShadowRoot?e=e.parentNode.host:e=e.parentElement;return t.set(i,r),r}var D,j,K,vt,mn=0,bt=!0;function Sr(e){bt=!1,e(),bt=!0}function Tr(e){D=e.reactive,K=e.release,j=t=>e.effect(t,{scheduler:r=>{bt?br(r):r()}}),vt=e.raw}function wt(e){j=e}function Nr(e){let t=()=>{};return[(i,n)=>{let s=n?.priority==="structural"?mn++:void 0,o=j(i);return s!==void 0&&o!==void 0&&(o._x_schedulerPriority={el:e,order:s}),e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(a=>a())}),e._x_effects.add(o),t=()=>{o!==void 0&&(e._x_effects.delete(o),K(o))},o},()=>{t()}]}function $e(e,t){let r=!0,i,n,s=j(()=>{let o=e(),a=JSON.stringify(o);if(!r&&(typeof o=="object"||o!==i)){let c=typeof i=="object"?JSON.parse(n):i;queueMicrotask(()=>{t(o,c)})}i=o,n=a,r=!1});return()=>K(s)}async function Cr(e){vr();try{await e(),await Promise.resolve()}finally{wr()}}var Rr=[],kr=[],Dr=[];function Pr(e){Dr.push(e)}function fe(e,t){typeof t=="function"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,kr.push(t))}function Ve(e){Rr.push(e)}function He(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function At(e,t){e._x_attributeCleanups&&Object.entries(e._x_attributeCleanups).forEach(([r,i])=>{(t===void 0||t.includes(r))&&(i.forEach(n=>n()),delete e._x_attributeCleanups[r])})}function Mr(e){for(e._x_effects?.forEach(Ar);e._x_cleanups?.length;)e._x_cleanups.pop()()}var Ot=new MutationObserver(Ct),St=!1;function ve(){Ot.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),St=!0}function Tt(){_n(),Ot.disconnect(),St=!1}var be=[];function _n(){let e=Ot.takeRecords();be.push(()=>e.length>0&&Ct(e));let t=be.length;queueMicrotask(()=>{if(be.length===t)for(;be.length>0;)be.shift()()})}function _(e){if(!St)return e();Tt();let t=e();return ve(),t}var Nt=!1,Fe=[];function Ir(){Nt=!0}function Lr(){Nt=!1,Ct(Fe),Fe=[]}function Ct(e){if(Nt){Fe=Fe.concat(e);return}let t=[],r=new Set,i=new Map,n=new Map;for(let s=0;s<e.length;s++)if(!e[s].target._x_ignoreMutationObserver&&(e[s].type==="childList"&&(e[s].removedNodes.forEach(o=>{o.nodeType===1&&o._x_marker&&r.add(o)}),e[s].addedNodes.forEach(o=>{if(o.nodeType===1){if(r.has(o)){r.delete(o);return}o._x_marker||t.push(o)}})),e[s].type==="attributes")){let o=e[s].target,a=e[s].attributeName,c=e[s].oldValue,l=()=>{i.has(o)||i.set(o,[]),i.get(o).push({name:a,value:o.getAttribute(a)})},u=()=>{n.has(o)||n.set(o,[]),n.get(o).push(a)};o.hasAttribute(a)&&c===null?l():o.hasAttribute(a)?(u(),l()):u()}n.forEach((s,o)=>{At(o,s)}),i.forEach((s,o)=>{Rr.forEach(a=>a(o,s))});for(let s of r)t.some(o=>o.contains(s))||kr.forEach(o=>o(s));for(let s of t)s.isConnected&&Dr.forEach(o=>o(s));t=null,r=null,i=null,n=null}function Be(e){return P(z(e))}function $(e,t,r){return e._x_dataStack=[t,...z(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(i=>i!==t)}}function z(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?z(e.host):e.parentNode?z(e.parentNode):[]}function P(e){return new Proxy({objects:e},gn)}function Ur(e,t){return e===null||e===Object.prototype?null:Object.prototype.hasOwnProperty.call(e,t)?e:Ur(Object.getPrototypeOf(e),t)}var gn={ownKeys({objects:e}){return Array.from(new Set(e.flatMap(t=>Object.keys(t))))},has({objects:e},t){return t==Symbol.unscopables?!1:e.some(r=>Object.prototype.hasOwnProperty.call(r,t)||Reflect.has(r,t))},get({objects:e},t,r){return t=="toJSON"?yn:Reflect.get(e.find(i=>Reflect.has(i,t))||{},t,r)},set({objects:e},t,r,i){let n;for(let o of e)if(n=Ur(o,t),n)break;n||(n=e[e.length-1]);let s=Object.getOwnPropertyDescriptor(n,t);return s?.set&&s?.get?s.set.call(i,r)||!0:Reflect.set(n,t,r)}};function yn(){return Reflect.ownKeys(this).reduce((t,r)=>(t[r]=Reflect.get(this,r),t),{})}function pe(e,t=()=>{}){let r=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,i=(n,s="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:a,enumerable:c}])=>{if(c===!1||a===void 0||typeof a=="object"&&a!==null&&a.__v_skip)return;let l=s===""?o:`${s}.${o}`;typeof a=="object"&&a!==null&&a._x_interceptor?n[o]=a.initialize(e,l,o,t):r(a)&&a!==n&&!(a instanceof Element)&&i(a,l)})};return i(e)}function Ke(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(i,n,s,o){return e(this.initialValue,()=>xn(i,n),a=>Rt(i,n,a),n,s,o)}};return t(r),i=>{if(typeof i=="object"&&i!==null&&i._x_interceptor){let n=r.initialize.bind(r);r.initialize=(s,o,a,c)=>{let l=i.initialize(s,o,a,c);return r.initialValue=l,n(s,o,a,c)}}else r.initialValue=i;return r}}function xn(e,t){return t.split(".").reduce((r,i)=>r[i],e)}function Rt(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),Rt(e[t[0]],t.slice(1),r)}}var jr={};function v(e,t){jr[e]=t}function J(e,t){let r=En(t);return Object.entries(jr).forEach(([i,n])=>{Object.defineProperty(e,`$${i}`,{get(){return n(t,r)},enumerable:!1})}),e}function En(e){let[t,r]=kt(e),i={interceptor:Ke,...t};return fe(e,r),i}function Dt(e,t,r,...i){try{return r(...i)}catch(n){we(n,e,t)}}function we(...e){return $r(...e)}var $r=bn;function Fr(e){$r=e}function bn(e,t,r=void 0){e=Object.assign(e??{message:"No error message given."},{el:t,expression:r}),console.warn(`Alpine Expression Error: ${e.message}
|
|
2
|
+
|
|
3
|
+
${r?'Expression: "'+r+`"
|
|
4
|
+
|
|
5
|
+
`:""}`,t),setTimeout(()=>{throw e},0)}var X=!0;function ze(e){let t=X;X=!1;let r=e();return X=t,r}function M(e,t,r={}){let i;return b(e,t)(n=>i=n,r),i}function b(...e){return Vr(...e)}var Vr=()=>{};function Hr(e){Vr=e}var Br;function Kr(e){Br=e}function zr(e,t){return(r=()=>{},{scope:i={},params:n=[],context:s}={})=>{if(!X){Pt(r,t,P([i,...e]),n);return}let o=t.apply(P([i,...e]),n);Pt(r,o)}}function Pt(e,t,r,i,n){if(X&&typeof t=="function"){let s=t.apply(r,i);s instanceof Promise?s.then(o=>Pt(e,o,r,i)).catch(o=>we(o,n,t)):e(s)}else typeof t=="object"&&t instanceof Promise?t.then(s=>e(s)):e(t)}function Wr(...e){return Br(...e)}var Lt="x-";function R(e=""){return Lt+e}function qr(e){Lt=e}var We={};function h(e,t){return We[e]=t,{before(r){if(!We[r]){console.warn(String.raw`Cannot find directive \`${r}\`. \`${e}\` will use the default order of execution`);return}let i=te.indexOf(r);te.splice(i>=0?i:te.indexOf("DEFAULT"),0,e)}}}function Gr(e){return Object.keys(We).includes(e)}function Oe(e,t,r){if(t=Array.from(t),e._x_virtualDirectives){let s=Object.entries(e._x_virtualDirectives).map(([a,c])=>({name:a,value:c})),o=Ut(s);s=s.map(a=>o.find(c=>c.name===a.name)?{name:`x-bind:${a.name}`,value:`"${a.value}"`}:a),t=t.concat(s)}let i={};return t.map(Xr((s,o)=>i[s]=o)).filter(Qr).map(wn(i,r)).sort(An).map(s=>vn(e,s))}function Ut(e){return Array.from(e).map(Xr()).filter(t=>!Qr(t))}var Mt=!1,Ae=new Map,Yr=Symbol();function Jr(e){Mt=!0;let t=Symbol();Yr=t,Ae.set(t,[]);let r=()=>{for(;Ae.get(t).length;)Ae.get(t).shift()();Ae.delete(t)},i=()=>{Mt=!1,r()};e(r),i()}function kt(e){let t=[],r=a=>t.push(a),[i,n]=Nr(e);return t.push(n),[{Alpine:W,effect:i,cleanup:r,evaluateLater:b.bind(b,e),evaluate:M.bind(M,e)},()=>t.forEach(a=>a())]}function vn(e,t){let r=()=>{},i=We[t.type]||r,[n,s]=kt(e);He(e,t.original,s);let o=()=>{e._x_ignore||e._x_ignoreSelf||(i.inline&&i.inline(e,t,n),i=i.bind(i,e,t,n),Mt?Ae.get(Yr).push(i):i())};return o.runCleanups=s,o}var qe=(e,t)=>({name:r,value:i})=>(r.startsWith(e)&&(r=r.replace(e,t)),{name:r,value:i}),Ge=e=>e;function Xr(e=()=>{}){return({name:t,value:r})=>{let{name:i,value:n}=Zr.reduce((s,o)=>o(s),{name:t,value:r});return i!==t&&e(i,t),{name:i,value:n}}}var Zr=[];function de(e){Zr.push(e)}function Qr({name:e}){return ei().test(e)}var ei=()=>new RegExp(`^${Lt}([^:^.]+)\\b`);function wn(e,t){return({name:r,value:i})=>{r===i&&(i="");let n=r.match(ei()),s=r.match(/:([a-zA-Z0-9\-_:]+)/),o=r.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],a=t||e[r]||r;return{type:n?n[1]:null,value:s?s[1]:null,modifiers:o.map(c=>c.replace(".","")),expression:i,original:a}}}var It="DEFAULT",te=["ignore","ref","id","data","anchor","bind","init","for","model","modelable","transition","show","if",It,"teleport"];function An(e,t){let r=te.indexOf(e.type)===-1?It:e.type,i=te.indexOf(t.type)===-1?It:t.type;return te.indexOf(r)-te.indexOf(i)}function re(e,t,r={},i={}){return e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0,...i}))}function F(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(n=>F(n,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let i=e.firstElementChild;for(;i;)F(i,t,!1),i=i.nextElementSibling}function O(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}var ti=!1;function ri(){ti&&O("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),ti=!0,document.body||O("Unable to initialize. Trying to load Alpine before `<body>` is available. Did you forget to add `defer` in Alpine's `<script>` tag?"),re(document,"alpine:init"),re(document,"alpine:initializing"),ve(),Pr(t=>S(t,F)),fe(t=>k(t)),Ve((t,r)=>{Oe(t,r).forEach(i=>i())});let e=t=>!ie(t.parentElement,!0);Array.from(document.querySelectorAll(si().join(","))).filter(e).forEach(t=>{S(t)}),re(document,"alpine:initialized"),setTimeout(()=>{Sn()})}var jt=[],ii=[];function ni(){return jt.map(e=>e())}function si(){return jt.concat(ii).map(e=>e())}function Ye(e){jt.push(e)}function Je(e){ii.push(e)}function ie(e,t=!1){return C(e,r=>{if((t?si():ni()).some(n=>r.matches(n)))return!0})}function C(e,t){if(e){if(t(e))return e;if(e._x_teleportBack)return C(e._x_teleportBack,t);if(e.parentNode instanceof ShadowRoot)return C(e.parentNode.host,t);if(e.parentElement)return C(e.parentElement,t)}}function oi(e){return ni().some(t=>e.matches(t))}var ai=[];function ci(e){ai.push(e)}var On=1;function S(e,t=F,r=()=>{}){C(e,i=>i._x_ignore)||Jr(()=>{t(e,(i,n)=>{i._x_marker||(r(i,n),ai.forEach(s=>s(i,n)),Oe(i,i.attributes).forEach(s=>s()),i._x_ignore||(i._x_marker=On++),i._x_ignore&&n())})})}function k(e,t=F){t(e,r=>{Mr(r),At(r),delete r._x_marker})}function Sn(){[["ui","dialog",["[x-dialog], [x-popover]"]],["anchor","anchor",["[x-anchor]"]],["sort","sort",["[x-sort]"]]].forEach(([t,r,i])=>{Gr(r)||i.some(n=>{if(document.querySelector(n))return O(`found "${n}", but missing ${t} plugin`),!0})})}var $t=[],Ft=!1;function he(e=()=>{}){return queueMicrotask(()=>{Ft||setTimeout(()=>{Xe()})}),new Promise(t=>{$t.push(()=>{e(),t()})})}function Xe(){for(Ft=!1;$t.length;)$t.shift()()}function li(){Ft=!0}function Se(e,t){return Array.isArray(t)?ui(e,t.join(" ")):typeof t=="object"&&t!==null?Tn(e,t):typeof t=="function"?Se(e,t()):ui(e,t)}function Vt(e){return e.split(/\s/).filter(Boolean)}function ui(e,t){let r=n=>Vt(n).filter(s=>!e.classList.contains(s)).filter(Boolean),i=n=>(e.classList.add(...n),()=>{e.classList.remove(...n)});return t=t===!0?t="":t||"",i(r(t))}function Tn(e,t){let r=Object.entries(t).flatMap(([o,a])=>a?Vt(o):!1).filter(Boolean),i=Object.entries(t).flatMap(([o,a])=>a?!1:Vt(o)).filter(Boolean),n=[],s=[];return i.forEach(o=>{e.classList.contains(o)&&(e.classList.remove(o),s.push(o))}),r.forEach(o=>{e.classList.contains(o)||(e.classList.add(o),n.push(o))}),()=>{s.forEach(o=>e.classList.add(o)),n.forEach(o=>e.classList.remove(o))}}function ne(e,t){return typeof t=="object"&&t!==null?Nn(e,t):Cn(e,t)}function Nn(e,t){let r={};return Object.entries(t).forEach(([i,n])=>{r[i]=e.style[i],i.startsWith("--")||(i=Rn(i)),e.style.setProperty(i,n)}),setTimeout(()=>{e.style.length===0&&e.removeAttribute("style")}),()=>{ne(e,r)}}function Cn(e,t){let r=e.getAttribute("style",t);return e.setAttribute("style",t),()=>{e.setAttribute("style",r||"")}}function Rn(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()}function Te(e,t=()=>{}){let r=!1;return function(){r?t.apply(this,arguments):(r=!0,e.apply(this,arguments))}}h("transition",(e,{value:t,modifiers:r,expression:i},{evaluate:n})=>{typeof i=="function"&&(i=n(i)),i!==!1&&(!i||typeof i=="boolean"?Dn(e,r,t):kn(e,i,t))});function kn(e,t,r){fi(e,Se,""),{enter:n=>{e._x_transition.enter.during=n},"enter-start":n=>{e._x_transition.enter.start=n},"enter-end":n=>{e._x_transition.enter.end=n},leave:n=>{e._x_transition.leave.during=n},"leave-start":n=>{e._x_transition.leave.start=n},"leave-end":n=>{e._x_transition.leave.end=n}}[r](t)}function Dn(e,t,r){fi(e,ne);let i=!t.includes("in")&&!t.includes("out")&&!r,n=i||t.includes("in")||["enter"].includes(r),s=i||t.includes("out")||["leave"].includes(r);t.includes("in")&&!i&&(t=t.filter((p,y)=>y<t.indexOf("out"))),t.includes("out")&&!i&&(t=t.filter((p,y)=>y>t.indexOf("out")));let o=!t.includes("opacity")&&!t.includes("scale"),a=o||t.includes("opacity"),c=o||t.includes("scale"),l=a?0:1,u=c?Ne(t,"scale",95)/100:1,f=Ne(t,"delay",0)/1e3,g=Ne(t,"origin","center"),m="opacity, transform",L=Ne(t,"duration",150)/1e3,d=Ne(t,"duration",75)/1e3,w="cubic-bezier(0.4, 0.0, 0.2, 1)";n&&(e._x_transition.enter.during={transformOrigin:g,transitionDelay:`${f}s`,transitionProperty:m,transitionDuration:`${L}s`,transitionTimingFunction:w},e._x_transition.enter.start={opacity:l,transform:`scale(${u})`},e._x_transition.enter.end={opacity:1,transform:"scale(1)"}),s&&(e._x_transition.leave.during={transformOrigin:g,transitionDelay:`${f}s`,transitionProperty:m,transitionDuration:`${d}s`,transitionTimingFunction:w},e._x_transition.leave.start={opacity:1,transform:"scale(1)"},e._x_transition.leave.end={opacity:l,transform:`scale(${u})`})}function fi(e,t,r={}){e._x_transition||(e._x_transition={enter:{during:r,start:r,end:r},leave:{during:r,start:r,end:r},in(i=()=>{},n=()=>{}){Ze(e,t,{during:this.enter.during,start:this.enter.start,end:this.enter.end},i,n)},out(i=()=>{},n=()=>{}){Ze(e,t,{during:this.leave.during,start:this.leave.start,end:this.leave.end},i,n)}})}window.Element.prototype._x_toggleAndCascadeWithTransitions=function(e,t,r,i){let n=document.visibilityState==="visible"?requestAnimationFrame:setTimeout,s=()=>n(r);if(t){e._x_transition&&(e._x_transition.enter||e._x_transition.leave)?e._x_transition.enter&&(Object.entries(e._x_transition.enter.during).length||Object.entries(e._x_transition.enter.start).length||Object.entries(e._x_transition.enter.end).length)?e._x_transition.in(r):s():e._x_transition?e._x_transition.in(r):s();return}e._x_hidePromise=e._x_transition?new Promise((o,a)=>{e._x_transition.out(()=>{},()=>o(i)),e._x_transitioning&&e._x_transitioning.beforeCancel(()=>a({isFromCancelledTransition:!0}))}):Promise.resolve(i),queueMicrotask(()=>{let o=pi(e);o?(o._x_hideChildren||(o._x_hideChildren=[]),o._x_hideChildren.push(e)):n(()=>{let a=c=>{let l=Promise.all([c._x_hidePromise,...(c._x_hideChildren||[]).map(a)]).then(([u])=>u?.());return delete c._x_hidePromise,delete c._x_hideChildren,l};a(e).catch(c=>{if(!c.isFromCancelledTransition)throw c})})})};function pi(e){let t=e.parentNode;if(t)return t._x_hidePromise?t:pi(t)}function Ze(e,t,{during:r,start:i,end:n}={},s=()=>{},o=()=>{}){if(e._x_transitioning&&e._x_transitioning.cancel(),Object.keys(r).length===0&&Object.keys(i).length===0&&Object.keys(n).length===0){s(),o();return}let a,c,l;Pn(e,{start(){a=t(e,i)},during(){c=t(e,r)},before:s,end(){a(),l=t(e,n)},after:o,cleanup(){c(),l()}})}function Pn(e,t){let r,i,n,s=Te(()=>{_(()=>{r=!0,i||t.before(),n||(t.end(),Xe()),t.after(),e.isConnected&&t.cleanup(),delete e._x_transitioning})});e._x_transitioning={beforeCancels:[],beforeCancel(o){this.beforeCancels.push(o)},cancel:Te(function(){for(;this.beforeCancels.length;)this.beforeCancels.shift()();s()}),finish:s},_(()=>{t.start(),t.during()}),li(),requestAnimationFrame(()=>{if(r)return;let o=Number(getComputedStyle(e).transitionDuration.replace(/,.*/,"").replace("s",""))*1e3,a=Number(getComputedStyle(e).transitionDelay.replace(/,.*/,"").replace("s",""))*1e3;o===0&&(o=Number(getComputedStyle(e).animationDuration.replace("s",""))*1e3),_(()=>{t.before()}),i=!0,requestAnimationFrame(()=>{r||(_(()=>{t.end()}),Xe(),setTimeout(e._x_transitioning.finish,o+a),n=!0)})})}function Ne(e,t,r){if(e.indexOf(t)===-1)return r;let i=e[e.indexOf(t)+1];if(!i||t==="scale"&&isNaN(i))return r;if(t==="duration"||t==="delay"){let n=i.match(/([0-9]+)ms/);if(n)return n[1]}return t==="origin"&&["top","right","left","center","bottom"].includes(e[e.indexOf(t)+2])?[i,e[e.indexOf(t)+2]].join(" "):i}var V=!1;function T(e,t=()=>{}){return(...r)=>V?t(...r):e(...r)}function di(e){return(...t)=>V&&e(...t)}var hi=[];function Z(e){hi.push(e)}function mi(e,t){hi.forEach(r=>r(e,t)),V=!0,gi(()=>{S(t,(r,i)=>{i(r,()=>{})})}),V=!1}var Qe=!1;function _i(e,t){t._x_dataStack||(t._x_dataStack=e._x_dataStack),V=!0,Qe=!0,gi(()=>{Mn(t)}),V=!1,Qe=!1}function Mn(e){let t=!1;S(e,(i,n)=>{F(i,(s,o)=>{if(t&&oi(s))return o();t=!0,n(s,o)})})}function gi(e){let t=j;wt((r,i)=>{let n=t(r);return K(n),()=>{}}),e(),wt(t)}function Ce(e,t,r,i=[]){switch(e._x_bindings||(e._x_bindings=D({})),e._x_bindings[t]=r,t=i.includes("camel")?Hn(t):t,t){case"value":In(e,r);break;case"style":Un(e,r);break;case"class":Ln(e,r);break;case"selected":case"checked":jn(e,t,r);break;default:Ht(e,t,r);break}}function In(e,t){if(et(e))e.attributes.value===void 0&&(e.value=t);else if(ke(e))Number.isInteger(t)?e.value=t:!Array.isArray(t)&&typeof t!="boolean"&&![null,void 0].includes(t)?e.value=String(t):Array.isArray(t)?e.checked=t.some(r=>Bn(r,e.value)):e.checked=!!t;else if(e.tagName==="SELECT")Vn(e,t);else if(e.tagName==="OPTION")Ht(e,"value",t);else{if(e.value===t&&(typeof t!="object"||t===null))return;e.value=t===void 0?"":t}}function Ln(e,t){e._x_undoAddedClasses&&e._x_undoAddedClasses(),e._x_undoAddedClasses=Se(e,t)}function Un(e,t){e._x_undoAddedStyles&&e._x_undoAddedStyles(),e._x_undoAddedStyles=ne(e,t)}function jn(e,t,r){Ht(e,t,r),Fn(e,t,r)}function Ht(e,t,r){[null,void 0,!1].includes(r)&&zn(t)?e.removeAttribute(t):(yi(t)&&(r=t),Wn(r)&&(r=JSON.stringify(r)),$n(e,t,r))}function $n(e,t,r){e.getAttribute(t)!=r&&e.setAttribute(t,r)}function Fn(e,t,r){e[t]!==r&&(e[t]=r)}function Vn(e,t){let r=[].concat(t).map(i=>i+"");Array.from(e.options).forEach(i=>{i.selected=r.includes(i.value)})}function Hn(e){return e.toLowerCase().replace(/-(\w)/g,(t,r)=>r.toUpperCase())}function Bn(e,t){return e==t}function Re(e){return[1,"1","true","on","yes",!0].includes(e)?!0:[0,"0","false","off","no",!1].includes(e)?!1:e?Boolean(e):null}var Kn=new Set(["allowfullscreen","async","autofocus","autoplay","checked","controls","default","defer","disabled","formnovalidate","inert","ismap","itemscope","loop","multiple","muted","nomodule","novalidate","open","playsinline","readonly","required","reversed","selected","shadowrootclonable","shadowrootdelegatesfocus","shadowrootserializable"]);function yi(e){return Kn.has(e)}function zn(e){return!["aria-pressed","aria-checked","aria-expanded","aria-selected"].includes(e)}function Wn(e){return typeof e=="object"&&e!==null}function xi(e,t,r){return e._x_bindings&&e._x_bindings[t]!==void 0?e._x_bindings[t]:bi(e,t,r)}function Ei(e,t,r,i=!0){if(e._x_bindings&&e._x_bindings[t]!==void 0)return e._x_bindings[t];if(e._x_inlineBindings&&e._x_inlineBindings[t]!==void 0){let n=e._x_inlineBindings[t];return n.extract=i,ze(()=>M(e,n.expression))}return bi(e,t,r)}function bi(e,t,r){let i=e.getAttribute(t);return i===null?typeof r=="function"?r():r:i===""?!0:yi(t)?!![t,"true"].includes(i):i}function ke(e){return e.type==="checkbox"||e.localName==="ui-checkbox"||e.localName==="ui-switch"}function et(e){return e.type==="radio"||e.localName==="ui-radio"}function tt(e,t){let r;return function(){let i=this,n=arguments,s=function(){r=null,e.apply(i,n)};clearTimeout(r),r=setTimeout(s,t)}}function rt(e,t){let r;return function(){let i=this,n=arguments;r||(e.apply(i,n),r=!0,setTimeout(()=>r=!1,t))}}function it({get:e,set:t},{get:r,set:i}){let n=!0,s,o,a=j(()=>{let c=e(),l=r();if(n)i(Bt(c)),n=!1;else{let u=JSON.stringify(c),f=JSON.stringify(l);u!==s?i(Bt(c)):u!==f&&t(Bt(l))}s=JSON.stringify(e()),o=JSON.stringify(r())});return()=>{K(a)}}function Bt(e){return typeof e=="object"?JSON.parse(JSON.stringify(e)):e}function vi(e){(Array.isArray(e)?e:[e]).forEach(r=>r(W))}var q={},wi=!1;function Ai(e,t){if(wi||(q=D(q),wi=!0),t===void 0)return q[e];q[e]=t,typeof t=="object"&&t!==null&&t._x_interceptor?q[e]=t.initialize(q,e,e,()=>{}):pe(q[e]),typeof t=="object"&&t!==null&&t.hasOwnProperty("init")&&typeof t.init=="function"&&q[e].init()}function Oi(){return q}var Si={};function Ti(e,t){let r=typeof t!="function"?()=>t:t;return e instanceof Element?Kt(e,r()):(Si[e]=r,()=>{})}function Ni(e){return Object.entries(Si).forEach(([t,r])=>{Object.defineProperty(e,t,{get(){return(...i)=>r(...i)}})}),e}function Kt(e,t,r){let i=[];for(;i.length;)i.pop()();let n=Object.entries(t).map(([o,a])=>({name:o,value:a})),s=Ut(n);return n=n.map(o=>s.find(a=>a.name===o.name)?{name:`x-bind:${o.name}`,value:`"${o.value}"`}:o),Oe(e,n,r).map(o=>{i.push(o.runCleanups),o()}),()=>{for(;i.length;)i.pop()()}}var Ci={};function Ri(e,t){Ci[e]=t}function ki(e,t){return Object.entries(Ci).forEach(([r,i])=>{Object.defineProperty(e,r,{get(){return(...n)=>i.bind(t)(...n)},enumerable:!1})}),e}var qn={get reactive(){return D},get release(){return K},get effect(){return j},get raw(){return vt},get transaction(){return Cr},version:"3.16.2",flushAndStopDeferringMutations:Lr,dontAutoEvaluateFunctions:ze,disableEffectScheduling:Sr,startObservingMutations:ve,stopObservingMutations:Tt,setReactivityEngine:Tr,onAttributeRemoved:He,onAttributesAdded:Ve,closestDataStack:z,skipDuringClone:T,onlyDuringClone:di,addRootSelector:Ye,addInitSelector:Je,setErrorHandler:Fr,interceptClone:Z,addScopeToNode:$,deferMutations:Ir,mapAttributes:de,evaluateLater:b,interceptInit:ci,initInterceptors:pe,injectMagics:J,setEvaluator:Hr,setRawEvaluator:Kr,mergeProxies:P,extractProp:Ei,findClosest:C,onElRemoved:fe,closestRoot:ie,destroyTree:k,interceptor:Ke,transition:Ze,setStyles:ne,mutateDom:_,directive:h,entangle:it,throttle:rt,debounce:tt,evaluate:M,evaluateRaw:Wr,initTree:S,nextTick:he,prefixed:R,prefix:qr,plugin:vi,magic:v,store:Ai,start:ri,clone:_i,cloneNode:mi,bound:xi,$data:Be,watch:$e,walk:F,data:Ri,bind:Ti},W=qn;var Di=new WeakMap,Pi=new Set;Object.getOwnPropertyNames(globalThis).forEach(e=>{e==="styleMedia"||e==="sharedStorage"||Pi.add(globalThis[e])});var A=class{constructor(t,r,i,n){this.type=t,this.value=r,this.start=i,this.end=n}},zt=class{constructor(t){this.input=t,this.position=0,this.tokens=[]}tokenize(){for(;this.position<this.input.length&&(this.skipWhitespace(),!(this.position>=this.input.length));){let t=this.input[this.position];this.isDigit(t)?this.readNumber():this.isAlpha(t)||t==="_"||t==="$"?this.readIdentifierOrKeyword():t==='"'||t==="'"?this.readString():t==="/"&&this.peek()==="/"?this.skipLineComment():this.readOperatorOrPunctuation()}return this.tokens.push(new A("EOF",null,this.position,this.position)),this.tokens}skipWhitespace(){for(;this.position<this.input.length&&/\s/.test(this.input[this.position]);)this.position++}skipLineComment(){for(;this.position<this.input.length&&this.input[this.position]!==`
|
|
6
|
+
`;)this.position++}isDigit(t){return/[0-9]/.test(t)}isAlpha(t){return/[a-zA-Z]/.test(t)}isAlphaNumeric(t){return/[a-zA-Z0-9_$]/.test(t)}peek(t=1){return this.input[this.position+t]||""}readNumber(){let t=this.position,r=!1;for(;this.position<this.input.length;){let n=this.input[this.position];if(this.isDigit(n))this.position++;else if(n==="."&&!r)r=!0,this.position++;else break}let i=this.input.slice(t,this.position);this.tokens.push(new A("NUMBER",parseFloat(i),t,this.position))}readIdentifierOrKeyword(){let t=this.position;for(;this.position<this.input.length&&this.isAlphaNumeric(this.input[this.position]);)this.position++;let r=this.input.slice(t,this.position);["true","false","null","undefined","new","typeof","void","delete","in","instanceof"].includes(r)?r==="true"||r==="false"?this.tokens.push(new A("BOOLEAN",r==="true",t,this.position)):r==="null"?this.tokens.push(new A("NULL",null,t,this.position)):r==="undefined"?this.tokens.push(new A("UNDEFINED",void 0,t,this.position)):this.tokens.push(new A("KEYWORD",r,t,this.position)):this.tokens.push(new A("IDENTIFIER",r,t,this.position))}readString(){let t=this.position,r=this.input[this.position];this.position++;let i="",n=!1;for(;this.position<this.input.length;){let s=this.input[this.position];if(n){switch(s){case"n":i+=`
|
|
7
|
+
`;break;case"t":i+=" ";break;case"r":i+="\r";break;case"\\":i+="\\";break;case r:i+=r;break;default:i+=s}n=!1}else if(s==="\\")n=!0;else if(s===r){this.position++,this.tokens.push(new A("STRING",i,t,this.position));return}else i+=s;this.position++}throw new Error(`Unterminated string starting at position ${t}`)}readOperatorOrPunctuation(){let t=this.position,r=this.input[this.position],i=this.peek(),n=this.peek(2);if(r==="="&&i==="="&&n==="=")this.position+=3,this.tokens.push(new A("OPERATOR","===",t,this.position));else if(r==="!"&&i==="="&&n==="=")this.position+=3,this.tokens.push(new A("OPERATOR","!==",t,this.position));else if(r==="="&&i==="=")this.position+=2,this.tokens.push(new A("OPERATOR","==",t,this.position));else if(r==="!"&&i==="=")this.position+=2,this.tokens.push(new A("OPERATOR","!=",t,this.position));else if(r==="<"&&i==="=")this.position+=2,this.tokens.push(new A("OPERATOR","<=",t,this.position));else if(r===">"&&i==="=")this.position+=2,this.tokens.push(new A("OPERATOR",">=",t,this.position));else if(r==="&"&&i==="&")this.position+=2,this.tokens.push(new A("OPERATOR","&&",t,this.position));else if(r==="|"&&i==="|")this.position+=2,this.tokens.push(new A("OPERATOR","||",t,this.position));else if(r==="+"&&i==="+")this.position+=2,this.tokens.push(new A("OPERATOR","++",t,this.position));else if(r==="-"&&i==="-")this.position+=2,this.tokens.push(new A("OPERATOR","--",t,this.position));else{this.position++;let s="()[]{},.;:?".includes(r)?"PUNCTUATION":"OPERATOR";this.tokens.push(new A(s,r,t,this.position))}}},Wt=class{constructor(t){this.tokens=t,this.position=0}parse(){if(this.isAtEnd())throw new Error("Empty expression");let t=this.parseExpression();if(this.match("PUNCTUATION",";"),!this.isAtEnd())throw new Error(`Unexpected token: ${this.current().value}`);return t}parseExpression(){return this.parseAssignment()}parseAssignment(){let t=this.parseTernary();if(this.match("OPERATOR","=")){let r=this.parseAssignment();if(t.type==="Identifier"||t.type==="MemberExpression")return{type:"AssignmentExpression",left:t,operator:"=",right:r};throw new Error("Invalid assignment target")}return t}parseTernary(){let t=this.parseLogicalOr();if(this.match("PUNCTUATION","?")){let r=this.parseExpression();this.consume("PUNCTUATION",":");let i=this.parseExpression();return{type:"ConditionalExpression",test:t,consequent:r,alternate:i}}return t}parseLogicalOr(){let t=this.parseLogicalAnd();for(;this.match("OPERATOR","||");){let r=this.previous().value,i=this.parseLogicalAnd();t={type:"BinaryExpression",operator:r,left:t,right:i}}return t}parseLogicalAnd(){let t=this.parseEquality();for(;this.match("OPERATOR","&&");){let r=this.previous().value,i=this.parseEquality();t={type:"BinaryExpression",operator:r,left:t,right:i}}return t}parseEquality(){let t=this.parseRelational();for(;this.match("OPERATOR","==","!=","===","!==");){let r=this.previous().value,i=this.parseRelational();t={type:"BinaryExpression",operator:r,left:t,right:i}}return t}parseRelational(){let t=this.parseAdditive();for(;this.match("OPERATOR","<",">","<=",">=");){let r=this.previous().value,i=this.parseAdditive();t={type:"BinaryExpression",operator:r,left:t,right:i}}return t}parseAdditive(){let t=this.parseMultiplicative();for(;this.match("OPERATOR","+","-");){let r=this.previous().value,i=this.parseMultiplicative();t={type:"BinaryExpression",operator:r,left:t,right:i}}return t}parseMultiplicative(){let t=this.parseUnary();for(;this.match("OPERATOR","*","/","%");){let r=this.previous().value,i=this.parseUnary();t={type:"BinaryExpression",operator:r,left:t,right:i}}return t}parseUnary(){if(this.match("OPERATOR","++","--")){let t=this.previous().value,r=this.parseUnary();return{type:"UpdateExpression",operator:t,argument:r,prefix:!0}}if(this.match("OPERATOR","!","-","+")){let t=this.previous().value,r=this.parseUnary();return{type:"UnaryExpression",operator:t,argument:r,prefix:!0}}return this.parsePostfix()}parsePostfix(){let t=this.parseMember();return this.match("OPERATOR","++","--")?{type:"UpdateExpression",operator:this.previous().value,argument:t,prefix:!1}:t}parseMember(){let t=this.parsePrimary();for(;;)if(this.match("PUNCTUATION",".")){let r=this.consume("IDENTIFIER");t={type:"MemberExpression",object:t,property:{type:"Identifier",name:r.value},computed:!1}}else if(this.match("PUNCTUATION","[")){let r=this.parseExpression();this.consume("PUNCTUATION","]"),t={type:"MemberExpression",object:t,property:r,computed:!0}}else if(this.match("PUNCTUATION","(")){let r=this.parseArguments();t={type:"CallExpression",callee:t,arguments:r}}else break;return t}parseArguments(){let t=[];if(!this.check("PUNCTUATION",")"))do t.push(this.parseExpression());while(this.match("PUNCTUATION",","));return this.consume("PUNCTUATION",")"),t}parsePrimary(){if(this.match("NUMBER"))return{type:"Literal",value:this.previous().value};if(this.match("STRING"))return{type:"Literal",value:this.previous().value};if(this.match("BOOLEAN"))return{type:"Literal",value:this.previous().value};if(this.match("NULL"))return{type:"Literal",value:null};if(this.match("UNDEFINED"))return{type:"Literal",value:void 0};if(this.match("IDENTIFIER"))return{type:"Identifier",name:this.previous().value};if(this.match("PUNCTUATION","(")){let t=this.parseExpression();return this.consume("PUNCTUATION",")"),t}if(this.match("PUNCTUATION","["))return this.parseArrayLiteral();if(this.match("PUNCTUATION","{"))return this.parseObjectLiteral();throw new Error(`Unexpected token: ${this.current().type} "${this.current().value}"`)}parseArrayLiteral(){let t=[];for(;!this.check("PUNCTUATION","]")&&!this.isAtEnd()&&(t.push(this.parseExpression()),this.match("PUNCTUATION",","));)if(this.check("PUNCTUATION","]"))break;return this.consume("PUNCTUATION","]"),{type:"ArrayExpression",elements:t}}parseObjectLiteral(){let t=[];for(;!this.check("PUNCTUATION","}")&&!this.isAtEnd();){let r,i=!1;if(this.match("STRING"))r={type:"Literal",value:this.previous().value};else if(this.match("IDENTIFIER"))r={type:"Identifier",name:this.previous().value};else if(this.match("PUNCTUATION","["))r=this.parseExpression(),i=!0,this.consume("PUNCTUATION","]");else throw new Error("Expected property key");this.consume("PUNCTUATION",":");let n=this.parseExpression();if(t.push({type:"Property",key:r,value:n,computed:i,shorthand:!1}),this.match("PUNCTUATION",",")){if(this.check("PUNCTUATION","}"))break}else break}return this.consume("PUNCTUATION","}"),{type:"ObjectExpression",properties:t}}match(...t){for(let r=0;r<t.length;r++){let i=t[r];if(r===0&&t.length>1){let n=i;for(let s=1;s<t.length;s++)if(this.check(n,t[s]))return this.advance(),!0;return!1}else if(t.length===1)return this.checkType(i)?(this.advance(),!0):!1}return!1}check(t,r){return this.isAtEnd()?!1:r!==void 0?this.current().type===t&&this.current().value===r:this.current().type===t}checkType(t){return this.isAtEnd()?!1:this.current().type===t}advance(){return this.isAtEnd()||this.position++,this.previous()}isAtEnd(){return this.current().type==="EOF"}current(){return this.tokens[this.position]}previous(){return this.tokens[this.position-1]}consume(t,r){if(r!==void 0){if(this.check(t,r))return this.advance();throw new Error(`Expected ${t} "${r}" but got ${this.current().type} "${this.current().value}"`)}if(this.check(t))return this.advance();throw new Error(`Expected ${t} but got ${this.current().type} "${this.current().value}"`)}},qt=class{evaluate({node:t,scope:r={},context:i=null,forceBindingRootScopeToFunctions:n=!0}){switch(t.type){case"Literal":return t.value;case"Identifier":if(t.name in r){let p=r[t.name];return this.checkForDangerousValues(p),typeof p=="function"?p.bind(r):p}throw new Error(`Undefined variable: ${t.name}`);case"MemberExpression":let s=this.evaluate({node:t.object,scope:r,context:i,forceBindingRootScopeToFunctions:n});if(s==null)throw new Error("Cannot read property of null or undefined");let o;t.computed?o=this.evaluate({node:t.property,scope:r,context:i,forceBindingRootScopeToFunctions:n}):o=t.property.name,this.checkForDangerousKeywords(o);let a=s[o];return this.checkForDangerousValues(a),typeof a=="function"?n?a.bind(r):a.bind(s):a;case"CallExpression":let c=t.arguments.map(p=>this.evaluate({node:p,scope:r,context:i,forceBindingRootScopeToFunctions:n})),l;if(t.callee.type==="MemberExpression"){let p=this.evaluate({node:t.callee.object,scope:r,context:i,forceBindingRootScopeToFunctions:n}),y;t.callee.computed?y=this.evaluate({node:t.callee.property,scope:r,context:i,forceBindingRootScopeToFunctions:n}):y=t.callee.property.name,this.checkForDangerousKeywords(y);let U=p[y];if(typeof U!="function")throw new Error("Value is not a function");l=U.apply(p,c)}else if(t.callee.type==="Identifier"){let p=t.callee.name,y;if(p in r)y=r[p];else throw new Error(`Undefined variable: ${p}`);if(typeof y!="function")throw new Error("Value is not a function");let U=i!==null?i:r;l=y.apply(U,c)}else{let p=this.evaluate({node:t.callee,scope:r,context:i,forceBindingRootScopeToFunctions:n});if(typeof p!="function")throw new Error("Value is not a function");l=p.apply(i,c)}return this.checkForDangerousValues(l),l;case"UnaryExpression":let u=this.evaluate({node:t.argument,scope:r,context:i,forceBindingRootScopeToFunctions:n});switch(t.operator){case"!":return!u;case"-":return-u;case"+":return+u;default:throw new Error(`Unknown unary operator: ${t.operator}`)}case"UpdateExpression":if(t.argument.type==="Identifier"){let p=t.argument.name;if(!(p in r))throw new Error(`Undefined variable: ${p}`);let y=r[p];return t.operator==="++"?r[p]=y+1:t.operator==="--"&&(r[p]=y-1),t.prefix?r[p]:y}else if(t.argument.type==="MemberExpression"){let p=this.evaluate({node:t.argument.object,scope:r,context:i,forceBindingRootScopeToFunctions:n}),y=t.argument.computed?this.evaluate({node:t.argument.property,scope:r,context:i,forceBindingRootScopeToFunctions:n}):t.argument.property.name;if(this.isDOMObject(p))throw new Error("Property assignments on DOM objects are prohibited in the CSP build");this.checkForDangerousKeywords(y);let U=p[y];return t.operator==="++"?p[y]=U+1:t.operator==="--"&&(p[y]=U-1),t.prefix?p[y]:U}throw new Error("Invalid update expression target");case"BinaryExpression":let f=this.evaluate({node:t.left,scope:r,context:i,forceBindingRootScopeToFunctions:n}),g=()=>this.evaluate({node:t.right,scope:r,context:i,forceBindingRootScopeToFunctions:n});if(t.operator==="&&")return f&&g();if(t.operator==="||")return f||g();let m=g();switch(t.operator){case"+":return f+m;case"-":return f-m;case"*":return f*m;case"/":return f/m;case"%":return f%m;case"==":return f==m;case"!=":return f!=m;case"===":return f===m;case"!==":return f!==m;case"<":return f<m;case">":return f>m;case"<=":return f<=m;case">=":return f>=m;default:throw new Error(`Unknown binary operator: ${t.operator}`)}case"ConditionalExpression":return this.evaluate({node:t.test,scope:r,context:i,forceBindingRootScopeToFunctions:n})?this.evaluate({node:t.consequent,scope:r,context:i,forceBindingRootScopeToFunctions:n}):this.evaluate({node:t.alternate,scope:r,context:i,forceBindingRootScopeToFunctions:n});case"AssignmentExpression":let d=this.evaluate({node:t.right,scope:r,context:i,forceBindingRootScopeToFunctions:n});if(t.left.type==="Identifier")return r[t.left.name]=d,d;if(t.left.type==="MemberExpression"){let p=this.evaluate({node:t.left.object,scope:r,context:i,forceBindingRootScopeToFunctions:n}),y=t.left.computed?this.evaluate({node:t.left.property,scope:r,context:i,forceBindingRootScopeToFunctions:n}):t.left.property.name;if(this.isDOMObject(p))throw new Error("Property assignments on DOM objects are prohibited in the CSP build");return this.checkForDangerousKeywords(y),p[y]=d,d}throw new Error("Invalid assignment target");case"ArrayExpression":return t.elements.map(p=>this.evaluate({node:p,scope:r,context:i,forceBindingRootScopeToFunctions:n}));case"ObjectExpression":let w={};for(let p of t.properties){let y=p.computed?this.evaluate({node:p.key,scope:r,context:i,forceBindingRootScopeToFunctions:n}):p.key.type==="Identifier"?p.key.name:this.evaluate({node:p.key,scope:r,context:i,forceBindingRootScopeToFunctions:n}),U=this.evaluate({node:p.value,scope:r,context:i,forceBindingRootScopeToFunctions:n});w[y]=U}return w;default:throw new Error(`Unknown node type: ${t.type}`)}}isDOMObject(t){return t instanceof Node||typeof CSSStyleDeclaration<"u"&&t instanceof CSSStyleDeclaration||typeof DOMStringMap<"u"&&t instanceof DOMStringMap||typeof DOMTokenList<"u"&&t instanceof DOMTokenList||typeof NamedNodeMap<"u"&&t instanceof NamedNodeMap}checkForDangerousKeywords(t){if(["constructor","prototype","__proto__","__defineGetter__","__defineSetter__","insertAdjacentHTML","setAttribute","setAttributeNS","setAttributeNode","setAttributeNodeNS"].includes(t))throw new Error(`Accessing "${t}" is prohibited in the CSP build`)}checkForDangerousValues(t){if(t!==null&&!(typeof t!="object"&&typeof t!="function")&&!Di.has(t)){if(t instanceof HTMLIFrameElement||t instanceof HTMLScriptElement)throw new Error("Accessing iframes and scripts is prohibited in the CSP build");if(Pi.has(t))throw new Error("Accessing global variables is prohibited in the CSP build");return Di.set(t,!0),!0}}};function Gt(e){try{let r=new zt(e).tokenize(),n=new Wt(r).parse(),s=new qt;return function(o={}){let{scope:a={},context:c=null,forceBindingRootScopeToFunctions:l=!1}=o;return s.evaluate({node:n,scope:a,context:c,forceBindingRootScopeToFunctions:l})}}catch(t){throw new Error(`CSP Parser Error: ${t.message}`)}}function Mi(e,t,r={}){let i=Li(e),n=P([r.scope??{},...i]),s=r.params??[],a=Gt(t)({scope:n,forceBindingRootScopeToFunctions:!0});return typeof a=="function"&&X?a.apply(n,s):a}function Ii(e,t){let r=Li(e);if(typeof t=="function")return zr(r,t);let i=Gn(e,t,r);return Dt.bind(null,e,t,i)}function Li(e){let t={};return J(t,e),[t,...z(e)]}function Gn(e,t,r){if(e instanceof HTMLIFrameElement)throw new Error("Evaluating expressions on an iframe is prohibited in the CSP build");if(e instanceof HTMLScriptElement)throw new Error("Evaluating expressions on a script is prohibited in the CSP build");return(i=()=>{},{scope:n={},params:s=[]}={})=>{let o=P([n,...r]),c=Gt(t)({scope:o,forceBindingRootScopeToFunctions:!0});if(X&&typeof c=="function"){let l=c.apply(c,s);l instanceof Promise?l.then(u=>i(u)):i(l)}else typeof c=="object"&&c instanceof Promise?c.then(l=>i(l)):i(c)}}function Yt(e){let t=Object.create(null);for(let r of e.split(","))t[r]=1;return r=>r in t}var Yn=Object.freeze({}),Sa=Object.freeze([]);var me=Object.assign;var Jn=Object.prototype.hasOwnProperty,nt=(e,t)=>Jn.call(e,t),_e=Array.isArray,ge=e=>Ui(e)==="[object Map]";var Xn=e=>typeof e=="string",ye=e=>typeof e=="symbol",xe=e=>e!==null&&typeof e=="object";var Zn=Object.prototype.toString,Ui=e=>Zn.call(e),Jt=e=>Ui(e).slice(8,-1);var st=e=>Xn(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e;var ot=e=>{let t=Object.create(null);return r=>t[r]||(t[r]=e(r))},Qn=/-\w/g,Ta=ot(e=>e.replace(Qn,t=>t.slice(1).toUpperCase())),es=/\B([A-Z])/g,Na=ot(e=>e.replace(es,"-$1").toLowerCase()),Xt=ot(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ca=ot(e=>e?`on${Xt(e)}`:""),Q=(e,t)=>!Object.is(e,t);var ts="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly";var Ra=Yt(ts+",async,autofocus,autoplay,controls,default,defer,disabled,inert,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected");function oe(e,...t){console.warn(`[Vue warn] ${e}`,...t)}var Zt;var x;var Qt=new WeakSet,lt=class{constructor(t){this.fn=t,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,Zt&&(Zt.active?Zt.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,Qt.has(this)&&(Qt.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||rs(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,ji(this),Hi(this);let t=x,r=I;x=this,I=!0;try{return this.fn()}finally{x!==this&&oe("Active effect was not restored correctly - this is likely a Vue internal bug."),Bi(this),x=t,I=r,this.flags&=-3}}stop(){if(this.flags&1){for(let t=this.deps;t;t=t.nextDep)dr(t);this.deps=this.depsTail=void 0,ji(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?Qt.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){rr(this)&&this.run()}get dirty(){return rr(this)}},Vi=0,Pe,Me;function rs(e,t=!1){if(e.flags|=8,t){e.next=Me,Me=e;return}e.next=Pe,Pe=e}function fr(){Vi++}function pr(){if(--Vi>0)return;if(Me){let t=Me;for(Me=void 0;t;){let r=t.next;t.next=void 0,t.flags&=-9,t=r}}let e;for(;Pe;){let t=Pe;for(Pe=void 0;t;){let r=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(i){e||(e=i)}t=r}}if(e)throw e}function Hi(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function Bi(e){let t,r=e.depsTail,i=r;for(;i;){let n=i.prevDep;i.version===-1?(i===r&&(r=n),dr(i),ns(i)):t=i,i.dep.activeLink=i.prevActiveLink,i.prevActiveLink=void 0,i=n}e.deps=t,e.depsTail=r}function rr(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(is(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function is(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===ut)||(e.globalVersion=ut,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!rr(e))))return;e.flags|=2;let t=e.dep,r=x,i=I;x=e,I=!0;try{Hi(e);let n=e.fn(e._value);(t.version===0||Q(n,e._value))&&(e.flags|=128,e._value=n,t.version++)}catch(n){throw t.version++,n}finally{x=r,I=i,Bi(e),e.flags&=-3}}function dr(e,t=!1){let{dep:r,prevSub:i,nextSub:n}=e;if(i&&(i.nextSub=n,e.prevSub=void 0),n&&(n.prevSub=i,e.nextSub=void 0),r.subsHead===e&&(r.subsHead=n),r.subs===e&&(r.subs=i,!i&&r.computed)){r.computed.flags&=-5;for(let s=r.computed.deps;s;s=s.nextDep)dr(s,!0)}!t&&!--r.sc&&r.map&&r.map.delete(r.key)}function ns(e){let{prevDep:t,nextDep:r}=e;t&&(t.nextDep=r,e.prevDep=void 0),r&&(r.prevDep=t,e.nextDep=void 0)}function Ki(e,t){e.effect instanceof lt&&(e=e.effect.fn);let r=new lt(e);t&&me(r,t);try{r.run()}catch(n){throw r.stop(),n}let i=r.run.bind(r);return i.effect=r,i}function zi(e){e.effect.stop()}var I=!0,Wi=[];function ss(){Wi.push(I),I=!1}function os(){let e=Wi.pop();I=e===void 0?!0:e}function ji(e){let{cleanup:t}=e;if(e.cleanup=void 0,t){let r=x;x=void 0;try{t()}finally{x=r}}}var ut=0,ir=class{constructor(t,r){this.sub=t,this.dep=r,this.version=r.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}},nr=class{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0,this.subsHead=void 0}track(t){if(!x||!I||x===this.computed)return;let r=this.activeLink;if(r===void 0||r.sub!==x)r=this.activeLink=new ir(x,this),x.deps?(r.prevDep=x.depsTail,x.depsTail.nextDep=r,x.depsTail=r):x.deps=x.depsTail=r,qi(r);else if(r.version===-1&&(r.version=this.version,r.nextDep)){let i=r.nextDep;i.prevDep=r.prevDep,r.prevDep&&(r.prevDep.nextDep=i),r.prevDep=x.depsTail,r.nextDep=void 0,x.depsTail.nextDep=r,x.depsTail=r,x.deps===r&&(x.deps=i)}return x.onTrack&&x.onTrack(me({effect:x},t)),r}trigger(t){this.version++,ut++,this.notify(t)}notify(t){fr();try{for(let r=this.subsHead;r;r=r.nextSub)r.sub.onTrigger&&!(r.sub.flags&8)&&r.sub.onTrigger(me({effect:r.sub},t));for(let r=this.subs;r;r=r.prevSub)r.sub.notify()&&r.sub.dep.notify()}finally{pr()}}};function qi(e){if(e.dep.sc++,e.sub.flags&4){let t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let i=t.deps;i;i=i.nextDep)qi(i)}let r=e.dep.subs;r!==e&&(e.prevSub=r,r&&(r.nextSub=e)),e.dep.subsHead===void 0&&(e.dep.subsHead=e),e.dep.subs=e}}var sr=new WeakMap,se=Symbol("Object iterate"),or=Symbol("Map keys iterate"),Le=Symbol("Array iterate");function N(e,t,r){if(I&&x){let i=sr.get(e);i||sr.set(e,i=new Map);let n=i.get(r);n||(i.set(r,n=new nr),n.map=i,n.key=r),n.track({target:e,type:t,key:r})}}function ee(e,t,r,i,n,s){let o=sr.get(e);if(!o){ut++;return}let a=c=>{c&&c.trigger({target:e,type:t,key:r,newValue:i,oldValue:n,oldTarget:s})};if(fr(),t==="clear")o.forEach(a);else{let c=_e(e),l=c&&st(r);if(c&&r==="length"){let u=Number(i);o.forEach((f,g)=>{(g==="length"||g===Le||!ye(g)&&g>=u)&&a(f)})}else switch((r!==void 0||o.has(void 0))&&a(o.get(r)),l&&a(o.get(Le)),t){case"add":c?l&&a(o.get("length")):(a(o.get(se)),ge(e)&&a(o.get(or)));break;case"delete":c||(a(o.get(se)),ge(e)&&a(o.get(or)));break;case"set":ge(e)&&a(o.get(se));break}}pr()}function Ee(e){let t=E(e);return t===e?t:(N(t,"iterate",Le),ce(e)?t:t.map(le))}function hr(e){return N(e=E(e),"iterate",Le),e}function H(e,t){return ae(e)?Qi(e)?Ue(le(t)):Ue(t):le(t)}var as={__proto__:null,[Symbol.iterator](){return er(this,Symbol.iterator,e=>H(this,e))},concat(...e){return Ee(this).concat(...e.map(t=>_e(t)?Ee(t):t))},entries(){return er(this,"entries",e=>(e[1]=H(this,e[1]),e))},every(e,t){return G(this,"every",e,t,void 0,arguments)},filter(e,t){return G(this,"filter",e,t,r=>r.map(i=>H(this,i)),arguments)},find(e,t){return G(this,"find",e,t,r=>H(this,r),arguments)},findIndex(e,t){return G(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return G(this,"findLast",e,t,r=>H(this,r),arguments)},findLastIndex(e,t){return G(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return G(this,"forEach",e,t,void 0,arguments)},includes(...e){return tr(this,"includes",e)},indexOf(...e){return tr(this,"indexOf",e)},join(e){return Ee(this).join(e)},lastIndexOf(...e){return tr(this,"lastIndexOf",e)},map(e,t){return G(this,"map",e,t,void 0,arguments)},pop(){return De(this,"pop")},push(...e){return De(this,"push",e)},reduce(e,...t){return $i(this,"reduce",e,t)},reduceRight(e,...t){return $i(this,"reduceRight",e,t)},shift(){return De(this,"shift")},some(e,t){return G(this,"some",e,t,void 0,arguments)},splice(...e){return De(this,"splice",e)},toReversed(){return Ee(this).toReversed()},toSorted(e){return Ee(this).toSorted(e)},toSpliced(...e){return Ee(this).toSpliced(...e)},unshift(...e){return De(this,"unshift",e)},values(){return er(this,"values",e=>H(this,e))}};function er(e,t,r){let i=hr(e),n=i[t]();return i!==e&&!ce(e)&&(n._next=n.next,n.next=()=>{let s=n._next();return s.done||(s.value=r(s.value)),s}),n}var cs=Array.prototype;function G(e,t,r,i,n,s){let o=hr(e),a=o!==e&&!ce(e),c=o[t];if(c!==cs[t]){let f=c.apply(e,s);return a?le(f):f}let l=r;o!==e&&(a?l=function(f,g){return r.call(this,H(e,f),g,e)}:r.length>2&&(l=function(f,g){return r.call(this,f,g,e)}));let u=c.call(o,l,i);return a&&n?n(u):u}function $i(e,t,r,i){let n=hr(e),s=n!==e&&!ce(e),o=r,a=!1;n!==e&&(s?(a=i.length===0,o=function(l,u,f){return a&&(a=!1,l=H(e,l)),r.call(this,l,H(e,u),f,e)}):r.length>3&&(o=function(l,u,f){return r.call(this,l,u,f,e)}));let c=n[t](o,...i);return a?H(e,c):c}function tr(e,t,r){let i=E(e);N(i,"iterate",Le);let n=i[t](...r);return(n===-1||n===!1)&&Es(r[0])?(r[0]=E(r[0]),i[t](...r)):n}function De(e,t,r=[]){ss(),fr();let i=E(e)[t].apply(e,r);return pr(),os(),i}var ls=Yt("__proto__,__v_isRef,__isVue"),Gi=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(ye));function us(e){ye(e)||(e=String(e));let t=E(this);return N(t,"has",e),t.hasOwnProperty(e)}var ft=class{constructor(t=!1,r=!1){this._isReadonly=t,this._isShallow=r}get(t,r,i){if(r==="__v_skip")return t.__v_skip;let n=this._isReadonly,s=this._isShallow;if(r==="__v_isReactive")return!n;if(r==="__v_isReadonly")return n;if(r==="__v_isShallow")return s;if(r==="__v_raw")return i===(n?s?ys:Xi:s?gs:Ji).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(i)?t:void 0;let o=_e(t);if(!n){let c;if(o&&(c=as[r]))return c;if(r==="hasOwnProperty")return us}let a=Reflect.get(t,r,Ie(t)?t:i);if((ye(r)?Gi.has(r):ls(r))||(n||N(t,"get",r),s))return a;if(Ie(a)){let c=o&&st(r)?a:a.value;return n&&xe(c)?ur(c):c}return xe(a)?n?ur(a):pt(a):a}},ar=class extends ft{constructor(t=!1){super(!1,t)}set(t,r,i,n){let s=t[r],o=_e(t)&&st(r);if(!this._isShallow){let l=ae(s);if(!ce(i)&&!ae(i)&&(s=E(s),i=E(i)),!o&&Ie(s)&&!Ie(i))return l?(oe(`Set operation on key "${String(r)}" failed: target is readonly.`,t[r]),!0):(s.value=i,!0)}let a=o?Number(r)<t.length:nt(t,r),c=Reflect.set(t,r,i,Ie(t)?t:n);return t===E(n)&&c&&(a?Q(i,s)&&ee(t,"set",r,i,s):ee(t,"add",r,i)),c}deleteProperty(t,r){let i=nt(t,r),n=t[r],s=Reflect.deleteProperty(t,r);return s&&i&&ee(t,"delete",r,void 0,n),s}has(t,r){let i=Reflect.has(t,r);return(!ye(r)||!Gi.has(r))&&N(t,"has",r),i}ownKeys(t){return N(t,"iterate",_e(t)?"length":se),Reflect.ownKeys(t)}},cr=class extends ft{constructor(t=!1){super(!0,t)}set(t,r){return oe(`Set operation on key "${String(r)}" failed: target is readonly.`,t),!0}deleteProperty(t,r){return oe(`Delete operation on key "${String(r)}" failed: target is readonly.`,t),!0}},fs=new ar,ps=new cr;var lr=e=>e,at=e=>Reflect.getPrototypeOf(e);function ds(e,t,r){return function(...i){let n=this.__v_raw,s=E(n),o=ge(s),a=e==="entries"||e===Symbol.iterator&&o,c=e==="keys"&&o,l=n[e](...i),u=r?lr:t?Ue:le;return!t&&N(s,"iterate",c?or:se),me(Object.create(l),{next(){let{value:f,done:g}=l.next();return g?{value:f,done:g}:{value:a?[u(f[0]),u(f[1])]:u(f),done:g}}})}}function ct(e){return function(...t){{let r=t[0]?`on key "${t[0]}" `:"";oe(`${Xt(e)} operation ${r}failed: target is readonly.`,E(this))}return e==="delete"?!1:e==="clear"?void 0:this}}function hs(e,t){let r={get(n){let s=this.__v_raw,o=E(s),a=E(n);e||(Q(n,a)&&N(o,"get",n),N(o,"get",a));let{has:c}=at(o),l=t?lr:e?Ue:le;if(c.call(o,n))return l(s.get(n));if(c.call(o,a))return l(s.get(a));s!==o&&s.get(n)},get size(){let n=this.__v_raw;return!e&&N(E(n),"iterate",se),n.size},has(n){let s=this.__v_raw,o=E(s),a=E(n);return e||(Q(n,a)&&N(o,"has",n),N(o,"has",a)),n===a?s.has(n):s.has(n)||s.has(a)},forEach(n,s){let o=this,a=o.__v_raw,c=E(a),l=t?lr:e?Ue:le;return!e&&N(c,"iterate",se),a.forEach((u,f)=>n.call(s,l(u),l(f),o))}};return me(r,e?{add:ct("add"),set:ct("set"),delete:ct("delete"),clear:ct("clear")}:{add(n){let s=E(this),o=at(s),a=E(n),c=!t&&!ce(n)&&!ae(n)?a:n;return o.has.call(s,c)||Q(n,c)&&o.has.call(s,n)||Q(a,c)&&o.has.call(s,a)||(s.add(c),ee(s,"add",c,c)),this},set(n,s){!t&&!ce(s)&&!ae(s)&&(s=E(s));let o=E(this),{has:a,get:c}=at(o),l=a.call(o,n);l?Fi(o,a,n):(n=E(n),l=a.call(o,n));let u=c.call(o,n);return o.set(n,s),l?Q(s,u)&&ee(o,"set",n,s,u):ee(o,"add",n,s),this},delete(n){let s=E(this),{has:o,get:a}=at(s),c=o.call(s,n);c?Fi(s,o,n):(n=E(n),c=o.call(s,n));let l=a?a.call(s,n):void 0,u=s.delete(n);return c&&ee(s,"delete",n,void 0,l),u},clear(){let n=E(this),s=n.size!==0,o=ge(n)?new Map(n):new Set(n),a=n.clear();return s&&ee(n,"clear",void 0,void 0,o),a}}),["keys","values","entries",Symbol.iterator].forEach(n=>{r[n]=ds(n,e,t)}),r}function Yi(e,t){let r=hs(e,t);return(i,n,s)=>n==="__v_isReactive"?!e:n==="__v_isReadonly"?e:n==="__v_raw"?i:Reflect.get(nt(r,n)&&n in i?r:i,n,s)}var ms={get:Yi(!1,!1)};var _s={get:Yi(!0,!1)};function Fi(e,t,r){let i=E(r);if(i!==r&&t.call(e,i)){let n=Jt(e);oe(`Reactive ${n} contains both the raw and reactive versions of the same object${n==="Map"?" as keys":""}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.`)}}var Ji=new WeakMap,gs=new WeakMap,Xi=new WeakMap,ys=new WeakMap;function xs(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function pt(e){return ae(e)?e:Zi(e,!1,fs,ms,Ji)}function ur(e){return Zi(e,!0,ps,_s,Xi)}function Zi(e,t,r,i,n){if(!xe(e))return oe(`value cannot be made ${t?"readonly":"reactive"}: ${String(e)}`),e;if(e.__v_raw&&!(t&&e.__v_isReactive)||e.__v_skip||!Object.isExtensible(e))return e;let s=n.get(e);if(s)return s;let o=xs(Jt(e));if(o===0)return e;let a=new Proxy(e,o===2?i:r);return n.set(e,a),a}function Qi(e){return ae(e)?Qi(e.__v_raw):!!(e&&e.__v_isReactive)}function ae(e){return!!(e&&e.__v_isReadonly)}function ce(e){return!!(e&&e.__v_isShallow)}function Es(e){return e?!!e.__v_raw:!1}function E(e){let t=e&&e.__v_raw;return t?E(t):e}var le=e=>xe(e)?pt(e):e,Ue=e=>xe(e)?ur(e):e;function Ie(e){return e?e.__v_isRef===!0:!1}v("nextTick",()=>he);v("dispatch",e=>re.bind(re,e));v("watch",(e,{evaluateLater:t,cleanup:r})=>(i,n)=>{let s=t(i),a=$e(()=>{let c;return s(l=>c=l),c},n);r(a)});v("store",Oi);v("data",e=>Be(e));v("root",e=>ie(e));v("refs",e=>(e._x_refs_proxy||(e._x_refs_proxy=P(bs(e))),e._x_refs_proxy));function bs(e){let t=[];return C(e,r=>{r._x_refs&&t.push(r._x_refs)}),t}var mr={};function _r(e){return mr[e]||(mr[e]=0),++mr[e]}function en(e,t){return C(e,r=>{if(r._x_ids&&r._x_ids[t])return!0})}function tn(e,t){e._x_ids||(e._x_ids={}),e._x_ids[t]||(e._x_ids[t]=_r(t))}v("id",(e,{cleanup:t})=>(r,i=null)=>{let n=`${r}${i?`-${i}`:""}`;return vs(e,n,t,()=>{let s=en(e,r),o=s?s._x_ids[r]:_r(r);return i?`${r}-${o}-${i}`:`${r}-${o}`})});Z((e,t)=>{e._x_id&&(t._x_id=e._x_id)});function vs(e,t,r,i){if(e._x_id||(e._x_id={}),e._x_id[t])return e._x_id[t];let n=i();return e._x_id[t]=n,r(()=>{delete e._x_id[t]}),n}v("el",e=>e);rn("Focus","focus","focus");rn("Persist","persist","persist");function rn(e,t,r){v(t,i=>O(`You can't use [$${t}] without first installing the "${e}" plugin here: https://alpinejs.dev/plugins/${r}`,i))}h("modelable",(e,{expression:t},{effect:r,evaluateLater:i,cleanup:n})=>{let s=i(t),o=()=>{let u;return s(f=>u=f),u},a=i(`${t} = __placeholder`),c=u=>a(()=>{},{scope:{__placeholder:u}}),l=o();c(l),queueMicrotask(()=>{if(!e._x_model)return;e._x_removeModelListeners.default();let u=e._x_model.get,f=e._x_model.setWithModifiers,g=it({get(){return u()},set(m){f(m)}},{get(){return o()},set(m){c(m)}});n(g)})});h("teleport",(e,{modifiers:t,expression:r},{cleanup:i})=>{e.tagName.toLowerCase()!=="template"&&O("x-teleport can only be used on a <template> tag",e);let n=nn(r),s=e.content.cloneNode(!0).firstElementChild;e._x_teleport=s,s._x_teleportBack=e,e.setAttribute("data-teleport-template",!0),s.setAttribute("data-teleport-target",!0),e._x_forwardEvents&&e._x_forwardEvents.forEach(a=>{s.addEventListener(a,c=>{c.stopPropagation(),e.dispatchEvent(new c.constructor(c.type,c))})}),$(s,{},e);let o=(a,c,l)=>{l.includes("prepend")?c.parentNode.insertBefore(a,c):l.includes("append")?c.parentNode.insertBefore(a,c.nextSibling):c.appendChild(a)};_(()=>{T(()=>{o(s,n,t),S(s)})()}),e._x_teleportPutBack=()=>{let a=nn(r);_(()=>{o(e._x_teleport,a,t)})},i(()=>_(()=>{s.remove(),k(s)}))});var ws=document.createElement("div");function nn(e){let t=T(()=>document.querySelector(e),()=>ws)();return t||O(`Cannot find x-teleport element for selector: "${e}"`),t}var sn=()=>{};sn.inline=(e,{modifiers:t},{cleanup:r})=>{t.includes("self")?e._x_ignoreSelf=!0:e._x_ignore=!0,r(()=>{t.includes("self")?delete e._x_ignoreSelf:delete e._x_ignore})};h("ignore",sn);h("effect",T((e,{expression:t},{effect:r})=>{r(b(e,t))}));function Y(e,t,r,i){let n=e,s=c=>i(c),o={},a=(c,l)=>u=>l(c,u);return r.includes("dot")&&(t=As(t)),r.includes("camel")&&(t=Os(t)),r.includes("capture")&&(o.capture=!0),r.includes("window")&&(n=window),r.includes("document")&&(n=document),r.includes("passive")&&(o.passive=r[r.indexOf("passive")+1]!=="false"),s=gr(r,s),r.includes("prevent")&&(s=a(s,(c,l)=>{l.preventDefault(),c(l)})),r.includes("stop")&&(s=a(s,(c,l)=>{l.stopPropagation(),c(l)})),r.includes("once")&&(s=a(s,(c,l)=>{c(l),n.removeEventListener(t,s,o)})),(r.includes("away")||r.includes("outside"))&&(n=document,s=a(s,(c,l)=>{e.contains(l.target)||l.target.isConnected!==!1&&(e.offsetWidth<1&&e.offsetHeight<1||e._x_isShown!==!1&&c(l))})),r.includes("self")&&(s=a(s,(c,l)=>{l.target===e&&c(l)})),t==="submit"&&(s=a(s,(c,l)=>{l.target._x_pendingModelUpdates&&l.target._x_pendingModelUpdates.forEach(u=>u()),c(l)})),(Ts(t)||an(t))&&(s=a(s,(c,l)=>{Ns(l,r)||c(l)})),n.addEventListener(t,s,o),()=>{n.removeEventListener(t,s,o)}}function gr(e,t){if(e.includes("debounce")){let r=e[e.indexOf("debounce")+1]||"invalid-wait",i=dt(r.split("ms")[0])?Number(r.split("ms")[0]):250;t=tt(t,i)}if(e.includes("throttle")){let r=e[e.indexOf("throttle")+1]||"invalid-wait",i=dt(r.split("ms")[0])?Number(r.split("ms")[0]):250;t=rt(t,i)}return t}function As(e){return e.replace(/-/g,".")}function Os(e){return e.toLowerCase().replace(/-(\w)/g,(t,r)=>r.toUpperCase())}function dt(e){return!Array.isArray(e)&&!isNaN(e)}function Ss(e){return[" ","_"].includes(e)?e:e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[_\s]/,"-").toLowerCase()}function Ts(e){return["keydown","keyup"].includes(e)}function an(e){return["contextmenu","click","mouse"].some(t=>e.includes(t))}function Ns(e,t){let r=t.filter(s=>!["window","document","prevent","stop","once","capture","self","away","outside","passive","preserve-scroll","blur","change","lazy"].includes(s));if(r.includes("debounce")){let s=r.indexOf("debounce");r.splice(s,dt((r[s+1]||"invalid-wait").split("ms")[0])?2:1)}if(r.includes("throttle")){let s=r.indexOf("throttle");r.splice(s,dt((r[s+1]||"invalid-wait").split("ms")[0])?2:1)}if(r.length===0||r.length===1&&on(e.key).includes(r[0]))return!1;let n=["ctrl","shift","alt","meta","cmd","super"].filter(s=>r.includes(s));return r=r.filter(s=>!n.includes(s)),!(n.length>0&&n.filter(o=>((o==="cmd"||o==="super")&&(o="meta"),e[`${o}Key`])).length===n.length&&(an(e.type)||on(e.key).includes(r[0])))}function on(e){if(!e)return[];e=Ss(e);let t={ctrl:"control",slash:"/",space:" ",spacebar:" ",cmd:"meta",esc:"escape",up:"arrow-up",down:"arrow-down",left:"arrow-left",right:"arrow-right",period:".",comma:",",equal:"=",minus:"-",underscore:"_"};return t[e]=e,Object.keys(t).map(r=>{if(t[r]===e)return r}).filter(r=>r)}h("model",(e,{modifiers:t,expression:r},{effect:i,cleanup:n})=>{let s=e;t.includes("parent")&&(s=C(e,d=>d!==e));let o=b(s,r),a;typeof r=="string"?a=b(s,`${r} = __placeholder`):typeof r=="function"&&typeof r()=="string"?a=b(s,`${r()} = __placeholder`):a=()=>{};let c=()=>{let d;return o(w=>d=w),cn(d)?d.get():d},l=d=>{let w;o(p=>w=p),cn(w)?w.set(d):a(()=>{},{scope:{__placeholder:d}})};typeof r=="string"&&e.type==="radio"&&_(()=>{e.hasAttribute("name")||e.setAttribute("name",r)});let u=t.includes("change")||t.includes("lazy"),f=t.includes("blur"),g=t.includes("enter"),m=u||f||g,L;if(V)L=()=>{};else if(m){let d=[],w=p=>l(ht(e,t,p,c()));if(u&&d.push(Y(e,"change",t,w)),f&&(d.push(Y(e,"blur",t,w)),e.form)){let p=e.form,y=()=>w({target:e});p._x_pendingModelUpdates||(p._x_pendingModelUpdates=[]),p._x_pendingModelUpdates.push(y),n(()=>{p._x_pendingModelUpdates&&p._x_pendingModelUpdates.splice(p._x_pendingModelUpdates.indexOf(y),1)})}g&&d.push(Y(e,"keydown",t,p=>{p.key==="Enter"&&w(p)})),L=()=>d.forEach(p=>p())}else{let d=e.tagName.toLowerCase()==="select"||["checkbox","radio"].includes(e.type)?"change":"input";L=Y(e,d,t,w=>{l(ht(e,t,w,c()))})}if(t.includes("fill")&&([void 0,null,""].includes(c())||ke(e)&&Array.isArray(c())||e.tagName.toLowerCase()==="select"&&e.multiple)&&l(ht(e,t,{target:e},c())),e._x_removeModelListeners||(e._x_removeModelListeners={}),e._x_removeModelListeners.default=L,n(()=>e._x_removeModelListeners.default()),e.form){let d=Y(e.form,"reset",[],w=>{he(()=>e._x_model&&e._x_model.set(ht(e,t,{target:e},c())))});n(()=>d())}if(e._x_model={get(){return c()},set(d){l(d)},setWithModifiers:gr(t,l)},e._x_forceModelUpdate=d=>{d===void 0&&typeof r=="string"&&r.match(/\./)&&(d=""),_(()=>{ke(e)?Array.isArray(d)?e.checked=d.some(w=>w==e.value):e.checked=!!d:et(e)?typeof d=="boolean"?e.checked=Re(e.value)===d:e.checked=e.value==d:Ce(e,"value",d)})},e.tagName==="SELECT"){let d=new MutationObserver(()=>{e._x_forceModelUpdate(c())});d.observe(e,{childList:!0}),n(()=>d.disconnect())}i(()=>{let d=c();t.includes("unintrusive")&&document.activeElement.isSameNode(e)||e._x_forceModelUpdate(d)})});function ht(e,t,r,i){return _(()=>{if(r instanceof CustomEvent&&r.detail!==void 0)return r.detail!==null&&r.detail!==void 0?r.detail:r.target.value;if(ke(e))if(Array.isArray(i)){let n=null;return t.includes("number")?n=yr(r.target.value):t.includes("boolean")?n=Re(r.target.value):n=r.target.value,r.target.checked?i.includes(n)?i:i.concat([n]):i.filter(s=>!Cs(s,n))}else return r.target.checked;else{if(e.tagName.toLowerCase()==="select"&&e.multiple)return t.includes("number")?Array.from(r.target.selectedOptions).map(n=>{let s=n.value||n.text;return yr(s)}):t.includes("boolean")?Array.from(r.target.selectedOptions).map(n=>{let s=n.value||n.text;return Re(s)}):Array.from(r.target.selectedOptions).map(n=>n.value||n.text);{let n;return et(e)?r.target.checked?n=r.target.value:n=i:n=r.target.value,t.includes("number")?yr(n):t.includes("boolean")?Re(n):t.includes("trim")?n.trim():n}}})}function yr(e){let t=e?parseFloat(e):null;return Rs(t)?t:e}function Cs(e,t){return e==t}function Rs(e){return!Array.isArray(e)&&!isNaN(e)}function cn(e){return e!==null&&typeof e=="object"&&typeof e.get=="function"&&typeof e.set=="function"}h("cloak",e=>queueMicrotask(()=>_(()=>e.removeAttribute(R("cloak")))));Je(()=>`[${R("init")}]`);h("init",T((e,{expression:t},{evaluate:r})=>typeof t=="string"?!!t.trim()&&r(t,{},!1):r(t,{},!1)));h("text",(e,{expression:t},{effect:r,evaluateLater:i})=>{let n=i(t);r(()=>{n(s=>{_(()=>{e.textContent=s})})})});h("html",(e,{expression:t},{effect:r,evaluateLater:i})=>{let n=i(t);r(()=>{n(s=>{_(()=>{Array.from(e.children).forEach(o=>k(o)),e.innerHTML=s??"",e._x_ignoreSelf=!0,S(e),delete e._x_ignoreSelf})})},{priority:"structural"})});de(qe(":",Ge(R("bind:"))));var ln=(e,{value:t,modifiers:r,expression:i,original:n},{effect:s,cleanup:o})=>{if(!t){let c={};Ni(c),b(e,i)(u=>{Kt(e,u,n)},{scope:c});return}if(t==="key")return ks(e,i);if(e._x_inlineBindings&&e._x_inlineBindings[t]&&e._x_inlineBindings[t].extract)return;let a=b(e,i);s(()=>a(c=>{c===void 0&&typeof i=="string"&&i.match(/\./)&&(c=""),_(()=>Ce(e,t,c,r))})),o(()=>{e._x_undoAddedClasses&&e._x_undoAddedClasses(),e._x_undoAddedStyles&&e._x_undoAddedStyles()})};ln.inline=(e,{value:t,modifiers:r,expression:i})=>{t&&(e._x_inlineBindings||(e._x_inlineBindings={}),e._x_inlineBindings[t]={expression:i,extract:!1})};h("bind",ln);function ks(e,t){e._x_keyExpression=t}Ye(()=>`[${R("data")}]`);var ue=Symbol();h("data",(e,{expression:t},{cleanup:r})=>{if(Ps(e))return;let i=e[ue];if(i?.expression===t)return;t=t===""?"{}":t;let n={};J(n,e);let s={};ki(s,n);let o=M(e,t,{scope:s});(o===void 0||o===!0)&&(o={}),J(o,e);let a;if(i?.reactiveData){a=i.reactiveData,Ds(a,o);let l={expression:t};e[ue]=l,queueMicrotask(()=>{e[ue]===l&&delete e[ue]})}else a=D(o);pe(a,r);let c=$(e,a);a.init&&M(e,a.init),r(()=>{a.destroy&&M(e,a.destroy),c();let l={reactiveData:a};e[ue]=l,queueMicrotask(()=>{e[ue]===l&&delete e[ue]})})});function Ds(e,t){Object.keys(t).forEach(r=>{let i=Object.getOwnPropertyDescriptor(t,r),n=Object.getOwnPropertyDescriptor(e,r);i.get||i.set||n?.get||n?.set?(n&&delete e[r],n||(e[r]=void 0),i.get||i.set?Object.defineProperty(e,r,i):e[r]=t[r]):e[r]=t[r]}),Object.keys(e).filter(r=>!Object.prototype.hasOwnProperty.call(t,r)).forEach(r=>delete e[r])}Z((e,t)=>{e._x_dataStack&&(t._x_dataStack=e._x_dataStack,t.setAttribute("data-has-alpine-state",!0))});function Ps(e){return V?Qe?!0:e.hasAttribute("data-has-alpine-state"):!1}h("show",(e,{modifiers:t,expression:r},{effect:i})=>{let n=b(e,r);e._x_doHide||(e._x_doHide=()=>{_(()=>{e.style.setProperty("display","none",t.includes("important")?"important":void 0)})}),e._x_doShow||(e._x_doShow=()=>{_(()=>{e.style.length===1&&e.style.display==="none"?e.removeAttribute("style"):e.style.removeProperty("display")})});let s=()=>{e._x_doHide(),e._x_isShown=!1},o=()=>{e._x_doShow(),e._x_isShown=!0},a=()=>setTimeout(o),c=Te(f=>f?o():s(),f=>{typeof e._x_toggleAndCascadeWithTransitions=="function"?e._x_toggleAndCascadeWithTransitions(e,f,o,s):f?a():s()}),l,u=!0;i(()=>n(f=>{!u&&f===l||(t.includes("immediate")&&(f?a():s()),c(f),l=f,u=!1)}))});h("for",T((e,{expression:t},{effect:r,cleanup:i})=>{let n=Ls(t),s=b(e,n.items),o=b(e,e._x_keyExpression||"index");e._x_lookup=new Map,r(()=>Is(e,n,s,o),{priority:"structural"}),i(()=>{e._x_lookup.forEach(a=>_(()=>{k(a),a.remove()})),delete e._x_lookup,delete e._x_lastRenderedEl})}));function Ms(e){return t=>{Object.entries(t).forEach(([r,i])=>{e[r]=i})}}function Is(e,t,r,i){r(n=>{js(n)&&(n=Array.from({length:n},(l,u)=>u+1)),n==null&&(n=[]),n instanceof Set&&(n=Array.from(n)),n instanceof Map&&(n=Array.from(n));let s=e._x_lookup,o=new Map;e._x_lookup=o;let a=$s(n),c=Object.entries(n).map(([l,u])=>{a||(l=parseInt(l));let f=Us(t,u,l,n),g;return i(m=>{typeof m=="object"&&O("x-for key cannot be an object, it must be a string or an integer",e),s.has(m)&&(o.set(m,s.get(m)),s.delete(m)),g=m},{scope:{index:l,...f}}),[g,f]});_(()=>{s.forEach(f=>{k(f),f.remove()});let l=new Set,u=e;c.forEach(([f,g])=>{if(o.has(f)){let d=o.get(f);d._x_refreshXForScope(g),u.nextElementSibling!==d&&(u.nextElementSibling&&d.replaceWith(u.nextElementSibling),u.after(d)),u=d,d._x_currentIfEl&&(d.nextElementSibling!==d._x_currentIfEl&&u.after(d._x_currentIfEl),u=d._x_currentIfEl);return}e.content.children.length>1&&O("x-for templates require a single root element, additional elements will be ignored.",e);let m=document.importNode(e.content,!0).firstElementChild,L=D(g);$(m,L,e),m._x_refreshXForScope=Ms(L),o.set(f,m),l.add(m),u.after(m),u=m}),l.forEach(f=>S(f)),u!==e?e._x_lastRenderedEl=u:delete e._x_lastRenderedEl})})}function Ls(e){let t=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,r=/^\s*\(|\)\s*$/g,i=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,n=e.match(i);if(!n)return;let s={};s.items=n[2].trim();let o=n[1].replace(r,"").trim(),a=o.match(t);return a?(s.item=o.replace(t,"").trim(),s.index=a[1].trim(),a[2]&&(s.collection=a[2].trim())):s.item=o,s}function Us(e,t,r,i){let n={};return/^\[.*\]$/.test(e.item)&&Array.isArray(t)?e.item.replace("[","").replace("]","").split(",").map(o=>o.trim()).forEach((o,a)=>{n[o]=t[a]}):/^\{.*\}$/.test(e.item)&&!Array.isArray(t)&&typeof t=="object"?e.item.replace("{","").replace("}","").split(",").map(o=>o.trim()).forEach(o=>{n[o]=t[o]}):n[e.item]=t,e.index&&(n[e.index]=r),e.collection&&(n[e.collection]=i),n}function js(e){return typeof e!="object"&&!isNaN(e)}function $s(e){return typeof e=="object"&&!Array.isArray(e)}function un(){}un.inline=(e,{expression:t},{cleanup:r})=>{let i=ie(e);i&&(i._x_refs||(i._x_refs={}),i._x_refs[t]=e,r(()=>delete i._x_refs[t]))};h("ref",un);h("if",T((e,{expression:t},{effect:r,cleanup:i})=>{e.tagName.toLowerCase()!=="template"&&O("x-if can only be used on a <template> tag",e);let n=b(e,t),s=()=>{if(e._x_currentIfEl)return e._x_currentIfEl;let a=e.content.cloneNode(!0).firstElementChild;return $(a,{},e),_(()=>{e.after(a),S(a)}),e._x_currentIfEl=a,e._x_lastRenderedEl=a,e._x_undoIf=()=>{_(()=>{k(a),a.remove()}),delete e._x_currentIfEl,delete e._x_lastRenderedEl},a},o=()=>{e._x_undoIf&&(e._x_undoIf(),delete e._x_undoIf)};r(()=>n(a=>{a?s():o()}),{priority:"structural"}),i(()=>e._x_undoIf&&e._x_undoIf())}));h("id",(e,{expression:t},{evaluate:r})=>{r(t).forEach(n=>tn(e,n))});Z((e,t)=>{e._x_ids&&(t._x_ids=e._x_ids)});de(qe("@",Ge(R("on:"))));h("on",T((e,{value:t,modifiers:r,expression:i},{cleanup:n})=>{let s=i?b(e,i):()=>{};e.tagName.toLowerCase()==="template"&&(e._x_forwardEvents||(e._x_forwardEvents=[]),e._x_forwardEvents.includes(t)||e._x_forwardEvents.push(t));let o=Y(e,t,r,a=>{s(()=>{},{scope:{$event:a},params:[a]})});n(()=>o())}));mt("Collapse","collapse","collapse");mt("Intersect","intersect","intersect");mt("Focus","trap","focus");mt("Mask","mask","mask");function mt(e,t,r){h(t,i=>O(`You can't use [x-${t}] without first installing the "${e}" plugin here: https://alpinejs.dev/plugins/${r}`,i))}h("html",(e,{expression:t})=>{we(new Error("Using the x-html directive is prohibited in the CSP build"),e)});W.setEvaluator(Ii);W.setRawEvaluator(Mi);W.setReactivityEngine({reactive:pt,effect:(e,t={})=>{let r;return r=Ki(e,{scheduler:()=>{r&&(t.scheduler?t.scheduler(r):r())}}),r},release:zi,raw:E});var xr=W;window.Alpine=xr;queueMicrotask(()=>{xr.start()});})();
|
|
8
|
+
/*! Bundled license information:
|
|
9
|
+
|
|
10
|
+
@vue/shared/dist/shared.esm-bundler.js:
|
|
11
|
+
(**
|
|
12
|
+
* @vue/shared v3.5.41
|
|
13
|
+
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
|
14
|
+
* @license MIT
|
|
15
|
+
**)
|
|
16
|
+
|
|
17
|
+
@vue/reactivity/dist/reactivity.esm-bundler.js:
|
|
18
|
+
(**
|
|
19
|
+
* @vue/reactivity v3.5.41
|
|
20
|
+
* (c) 2018-present Yuxi (Evan) You and Vue contributors
|
|
21
|
+
* @license MIT
|
|
22
|
+
**)
|
|
23
|
+
*/
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// Owned database CLI: bun db:migrate | db:backup | db:restore <file> | db:status
|
|
3
|
+
// Restore must run with the app stopped; see agents.md for rollback semantics.
|
|
4
|
+
// Imports only ./lifecycle so restore never opens or creates the database
|
|
5
|
+
// before its checksum verifies.
|
|
6
|
+
import { appliedMigrations, applyMigrations, backupDatabase, hasUserTables, openDatabase, pendingMigrations, restoreDatabase } from "../src/db/lifecycle";
|
|
7
|
+
import { loadEnv } from "../src/env";
|
|
8
|
+
|
|
9
|
+
const env = loadEnv();
|
|
10
|
+
const [command, argument] = process.argv.slice(2);
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
if (command === "migrate") {
|
|
14
|
+
const database = openDatabase(env.DB_PATH);
|
|
15
|
+
if (pendingMigrations(database).length > 0 && hasUserTables(database)) {
|
|
16
|
+
console.log(`Pre-migration backup: ${await backupDatabase(database, env.DB_PATH)}`);
|
|
17
|
+
}
|
|
18
|
+
const applied = await applyMigrations(database);
|
|
19
|
+
console.log(applied.length > 0 ? `Applied: ${applied.join(", ")}` : "No pending migrations.");
|
|
20
|
+
} else if (command === "backup") {
|
|
21
|
+
const database = openDatabase(env.DB_PATH);
|
|
22
|
+
console.log(`Backup written: ${await backupDatabase(database, env.DB_PATH)}`);
|
|
23
|
+
} else if (command === "restore") {
|
|
24
|
+
if (!argument) throw new Error("usage: bun db:restore <backup-file>. Stop the app first.");
|
|
25
|
+
await restoreDatabase(argument, env.DB_PATH);
|
|
26
|
+
console.log(`Restored ${env.DB_PATH} from ${argument}. Start the app to re-apply newer migrations.`);
|
|
27
|
+
} else if (command === "status") {
|
|
28
|
+
const database = openDatabase(env.DB_PATH);
|
|
29
|
+
console.log(`Database: ${env.DB_PATH}`);
|
|
30
|
+
console.log(`Applied: ${appliedMigrations(database).join(", ") || "none"}`);
|
|
31
|
+
console.log(`Pending: ${pendingMigrations(database).map((m) => m.name).join(", ") || "none"}`);
|
|
32
|
+
} else {
|
|
33
|
+
console.error("usage: bun scripts/db.ts migrate|backup|restore <file>|status");
|
|
34
|
+
process.exit(2);
|
|
35
|
+
}
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { HTTPException } from "hono/http-exception";
|
|
3
|
+
import { serveStatic } from "hono/bun";
|
|
4
|
+
import { desc } from "drizzle-orm";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { db } from "./db";
|
|
7
|
+
import { notes } from "./db/schema";
|
|
8
|
+
|
|
9
|
+
// The exact response header set; test/app.test.ts asserts every entry on
|
|
10
|
+
// success, error, API, and static responses. Change both together.
|
|
11
|
+
export const SECURITY_HEADERS: Record<string, string> = {
|
|
12
|
+
"Content-Security-Policy":
|
|
13
|
+
"default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; connect-src 'self'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'",
|
|
14
|
+
"X-Content-Type-Options": "nosniff",
|
|
15
|
+
"X-Frame-Options": "DENY",
|
|
16
|
+
"Referrer-Policy": "strict-origin-when-cross-origin",
|
|
17
|
+
"Permissions-Policy": "camera=(), geolocation=(), microphone=()",
|
|
18
|
+
"Cross-Origin-Opener-Policy": "same-origin",
|
|
19
|
+
"Cross-Origin-Resource-Policy": "same-origin",
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function applyHeaders(res: Response): Response {
|
|
23
|
+
for (const [name, value] of Object.entries(SECURITY_HEADERS)) {
|
|
24
|
+
res.headers.set(name, value);
|
|
25
|
+
}
|
|
26
|
+
return res;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Factory so tests can build an instance and add probe routes before the
|
|
30
|
+
// router freezes on first dispatch.
|
|
31
|
+
export function createApp(): Hono {
|
|
32
|
+
const app = new Hono();
|
|
33
|
+
|
|
34
|
+
app.use("*", async (c, next) => {
|
|
35
|
+
await next();
|
|
36
|
+
applyHeaders(c.res);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Thrown errors bypass the middleware above (the exception unwinds past
|
|
40
|
+
// its post-next line), so the error handler applies the same set.
|
|
41
|
+
// Deliberate HTTP errors (framework middleware like CSRF throws
|
|
42
|
+
// HTTPException) keep their status; everything else is a logged 500.
|
|
43
|
+
app.onError((err, c) => {
|
|
44
|
+
if (err instanceof HTTPException) return applyHeaders(err.getResponse());
|
|
45
|
+
console.error(err);
|
|
46
|
+
return applyHeaders(c.text("Internal error", 500));
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
app.get("/healthz", (c) => c.json({ ok: true }));
|
|
50
|
+
|
|
51
|
+
const helloQuery = z.object({
|
|
52
|
+
name: z.string().min(1).max(100).optional(),
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
app.get("/api/hello", (c) => {
|
|
56
|
+
const parsed = helloQuery.safeParse(c.req.query());
|
|
57
|
+
if (!parsed.success) {
|
|
58
|
+
return c.json({ error: "Invalid query" }, 400);
|
|
59
|
+
}
|
|
60
|
+
return c.json({ hello: parsed.data.name ?? "world" });
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Representative read. Writes stay out of public routes: add authentication
|
|
64
|
+
// first (tests may insert directly through db).
|
|
65
|
+
app.get("/api/notes", async (c) => {
|
|
66
|
+
const rows = await db.select().from(notes).orderBy(desc(notes.createdAt)).limit(50);
|
|
67
|
+
return c.json({ notes: rows });
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const page = `<!doctype html>
|
|
71
|
+
<html lang="en">
|
|
72
|
+
<head>
|
|
73
|
+
<meta charset="utf-8" />
|
|
74
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
75
|
+
<title>Shibumi web app</title>
|
|
76
|
+
<link rel="stylesheet" href="/public/style.css" />
|
|
77
|
+
<!-- app.js must load before Alpine so the alpine:init listener exists
|
|
78
|
+
when Alpine starts; both defer, so document order is execution order. -->
|
|
79
|
+
<script src="/public/app.js" defer></script>
|
|
80
|
+
<script src="/public/vendor/alpine-csp-3.16.2.min.js" defer></script>
|
|
81
|
+
</head>
|
|
82
|
+
<body>
|
|
83
|
+
<main>
|
|
84
|
+
<h1>It persists.</h1>
|
|
85
|
+
<p>Hono routes, Zod validation, Alpine behavior, and SQLite with Drizzle under a persistent volume. To get started, open <code>src/app.ts</code>; this page lives there.</p>
|
|
86
|
+
<section x-data="counter">
|
|
87
|
+
<button x-on:click="inc" type="button">Count</button>
|
|
88
|
+
<output x-text="count"></output>
|
|
89
|
+
</section>
|
|
90
|
+
<p><a href="/api/hello?name=you">/api/hello</a> · <a href="/api/notes">/api/notes</a> · <a href="/healthz">/healthz</a></p>
|
|
91
|
+
</main>
|
|
92
|
+
</body>
|
|
93
|
+
</html>
|
|
94
|
+
`;
|
|
95
|
+
|
|
96
|
+
app.get("/", (c) => c.html(page));
|
|
97
|
+
|
|
98
|
+
// GET-only: static files must not answer mutation verbs.
|
|
99
|
+
app.get("/public/*", serveStatic({ root: "./" }));
|
|
100
|
+
|
|
101
|
+
app.notFound((c) => c.text("Not found", 404));
|
|
102
|
+
|
|
103
|
+
return app;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export const app = createApp();
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// App-side database singleton. Importing this module opens DB_PATH; tooling
|
|
2
|
+
// that must not touch the live database (db:restore) imports openDatabase
|
|
3
|
+
// from ./lifecycle instead, which is side-effect free.
|
|
4
|
+
import { drizzle } from "drizzle-orm/bun-sqlite";
|
|
5
|
+
import { loadEnv } from "../env";
|
|
6
|
+
import { openDatabase } from "./lifecycle";
|
|
7
|
+
import * as schema from "./schema";
|
|
8
|
+
|
|
9
|
+
const env = loadEnv();
|
|
10
|
+
export const sqlite = openDatabase(env.DB_PATH);
|
|
11
|
+
export const db = drizzle(sqlite, { schema });
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
// Owned database lifecycle: migrations, backups, restore.
|
|
2
|
+
//
|
|
3
|
+
// Boot ordering (src/server.ts): integrity check -> backup -> migrate -> serve.
|
|
4
|
+
// A failed step exits the process, the container never reports healthy, and
|
|
5
|
+
// shibumi-server keeps the previous deployment. Image rollback
|
|
6
|
+
// (bun ship --rollback) does NOT reverse schema or data changes; use
|
|
7
|
+
// `bun db:restore <backup>` for that, with the app stopped.
|
|
8
|
+
//
|
|
9
|
+
// Backup contract:
|
|
10
|
+
// - method: VACUUM INTO (consistent snapshot, safe under WAL)
|
|
11
|
+
// - trigger: automatically before applying pending migrations to a database
|
|
12
|
+
// that already has tables; manually via `bun db:backup`
|
|
13
|
+
// - location: <db-dir>/backups/<name>.<utc-timestamp>.sqlite + .sha256 sidecar
|
|
14
|
+
// - retention: newest 5 backups for this database kept; other files untouched
|
|
15
|
+
// - size guard: refuses when free disk space is under 2x the logical database
|
|
16
|
+
// size (page_count x page_size); skipped only when df output is unusable
|
|
17
|
+
// - locking: migrations run inside BEGIN IMMEDIATE transactions (single
|
|
18
|
+
// writer) and the journal is rechecked inside the lock, so concurrent
|
|
19
|
+
// runners cannot double-apply; a failure rolls back journal row and all
|
|
20
|
+
import { Database } from "bun:sqlite";
|
|
21
|
+
import { closeSync, existsSync, fsyncSync, mkdirSync, openSync, readdirSync, renameSync, rmSync } from "node:fs";
|
|
22
|
+
import { basename, dirname, join } from "node:path";
|
|
23
|
+
|
|
24
|
+
const BACKUP_RETENTION = 5;
|
|
25
|
+
const FREE_SPACE_FACTOR = 2;
|
|
26
|
+
|
|
27
|
+
export function openDatabase(path: string): Database {
|
|
28
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
29
|
+
const database = new Database(path, { create: true });
|
|
30
|
+
// Durability settings, applied on every open:
|
|
31
|
+
// WAL keeps readers unblocked during writes, foreign keys are enforced,
|
|
32
|
+
// and writers wait up to 5000 ms for a lock instead of failing instantly.
|
|
33
|
+
database.exec("PRAGMA journal_mode = WAL;");
|
|
34
|
+
database.exec("PRAGMA foreign_keys = ON;");
|
|
35
|
+
database.exec("PRAGMA busy_timeout = 5000;");
|
|
36
|
+
return database;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface MigrationFile {
|
|
40
|
+
name: string;
|
|
41
|
+
path: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function migrationsDir(): string {
|
|
45
|
+
// src/db/migrations in development; dist/migrations once bundled (the
|
|
46
|
+
// Dockerfile copies them next to dist/server.js).
|
|
47
|
+
const candidates = [join(import.meta.dir, "migrations"), join(import.meta.dir, "..", "src", "db", "migrations")];
|
|
48
|
+
for (const candidate of candidates) if (existsSync(candidate)) return candidate;
|
|
49
|
+
throw new Error(`migrations directory not found near ${import.meta.dir}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function listMigrations(dir = migrationsDir()): MigrationFile[] {
|
|
53
|
+
return readdirSync(dir)
|
|
54
|
+
.filter((name) => name.endsWith(".sql"))
|
|
55
|
+
.sort()
|
|
56
|
+
.map((name) => ({ name, path: join(dir, name) }));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function ensureJournal(database: Database): void {
|
|
60
|
+
database.exec("CREATE TABLE IF NOT EXISTS _migrations (name TEXT PRIMARY KEY, applied_at TEXT NOT NULL DEFAULT (datetime('now')));");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function appliedMigrations(database: Database): string[] {
|
|
64
|
+
ensureJournal(database);
|
|
65
|
+
return database.query<{ name: string }, []>("SELECT name FROM _migrations ORDER BY name").all().map((row) => row.name);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function pendingMigrations(database: Database, dir?: string): MigrationFile[] {
|
|
69
|
+
const applied = new Set(appliedMigrations(database));
|
|
70
|
+
const pending = listMigrations(dir).filter((migration) => !applied.has(migration.name));
|
|
71
|
+
// Migrations apply in filename order; a pending name sorting before an
|
|
72
|
+
// applied one means a backfilled or renamed history, which would replay
|
|
73
|
+
// out of order on the next fresh database. Refuse it.
|
|
74
|
+
const highWater = appliedMigrations(database).at(-1);
|
|
75
|
+
if (highWater) {
|
|
76
|
+
const backfilled = pending.filter((migration) => migration.name < highWater);
|
|
77
|
+
if (backfilled.length > 0) {
|
|
78
|
+
throw new Error(`migrations ${backfilled.map((m) => m.name).join(", ")} sort before already-applied ${highWater}. Rename them to sort last.`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return pending;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function hasUserTables(database: Database): boolean {
|
|
85
|
+
const row = database
|
|
86
|
+
.query<{ n: number }, []>("SELECT count(*) AS n FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' AND name != '_migrations'")
|
|
87
|
+
.get();
|
|
88
|
+
return (row?.n ?? 0) > 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function applyMigrations(database: Database, dir?: string): Promise<string[]> {
|
|
92
|
+
const applied: string[] = [];
|
|
93
|
+
for (const migration of pendingMigrations(database, dir)) {
|
|
94
|
+
const sql = await Bun.file(migration.path).text();
|
|
95
|
+
// Transaction control inside a migration would escape the runner's
|
|
96
|
+
// transaction and could commit partial changes without a journal row.
|
|
97
|
+
// Anchored at start-of-file or after a `;` so it also catches control
|
|
98
|
+
// that follows another statement on the same line.
|
|
99
|
+
if (/(^|;)\s*(BEGIN|COMMIT|ROLLBACK|END)\b/im.test(sql)) {
|
|
100
|
+
throw new Error(`migration ${migration.name} contains transaction control (BEGIN/COMMIT/ROLLBACK); the runner owns the transaction. Remove those statements.`);
|
|
101
|
+
}
|
|
102
|
+
database.exec("BEGIN IMMEDIATE;");
|
|
103
|
+
try {
|
|
104
|
+
// Recheck inside the write lock so concurrent runners cannot both
|
|
105
|
+
// apply the same migration.
|
|
106
|
+
const done = database.query("SELECT 1 FROM _migrations WHERE name = ?").get(migration.name);
|
|
107
|
+
if (done) {
|
|
108
|
+
database.exec("ROLLBACK;");
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
database.exec(sql);
|
|
112
|
+
database.query("INSERT INTO _migrations (name) VALUES (?)").run(migration.name);
|
|
113
|
+
database.exec("COMMIT;");
|
|
114
|
+
} catch (error) {
|
|
115
|
+
database.exec("ROLLBACK;");
|
|
116
|
+
throw new Error(`migration ${migration.name} failed and was rolled back: ${error instanceof Error ? error.message : String(error)}`);
|
|
117
|
+
}
|
|
118
|
+
applied.push(migration.name);
|
|
119
|
+
}
|
|
120
|
+
return applied;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function logicalDatabaseSize(database: Database): number {
|
|
124
|
+
const pageCount = database.query<{ page_count: number }, []>("PRAGMA page_count").get()?.page_count ?? 0;
|
|
125
|
+
const pageSize = database.query<{ page_size: number }, []>("PRAGMA page_size").get()?.page_size ?? 4096;
|
|
126
|
+
return pageCount * pageSize;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function freeDiskBytes(path: string): number | undefined {
|
|
130
|
+
const result = Bun.spawnSync(["df", "-k", path], { stdout: "pipe", stderr: "ignore" });
|
|
131
|
+
if (result.exitCode !== 0) return undefined;
|
|
132
|
+
const line = result.stdout.toString().trim().split("\n").at(-1);
|
|
133
|
+
const available = line?.trim().split(/\s+/)[3];
|
|
134
|
+
const kib = Number(available);
|
|
135
|
+
return Number.isFinite(kib) && kib > 0 ? kib * 1024 : undefined;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function sha256File(path: string): Promise<string> {
|
|
139
|
+
const hasher = new Bun.CryptoHasher("sha256");
|
|
140
|
+
const stream = Bun.file(path).stream();
|
|
141
|
+
for await (const chunk of stream) hasher.update(chunk);
|
|
142
|
+
return hasher.digest("hex");
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export async function backupDatabase(database: Database, dbPath: string): Promise<string> {
|
|
146
|
+
// Logical size covers WAL-resident pages that the file size misses.
|
|
147
|
+
const size = logicalDatabaseSize(database);
|
|
148
|
+
const backupsDir = join(dirname(dbPath), "backups");
|
|
149
|
+
mkdirSync(backupsDir, { recursive: true });
|
|
150
|
+
const free = freeDiskBytes(backupsDir);
|
|
151
|
+
if (free !== undefined && free < size * FREE_SPACE_FACTOR) {
|
|
152
|
+
throw new Error(`refusing backup: ${Math.round(free / 1024 ** 2)} MiB free, need ${Math.round((size * FREE_SPACE_FACTOR) / 1024 ** 2)} MiB (2x database size). Free disk space, then retry.`);
|
|
153
|
+
}
|
|
154
|
+
const stamp = new Date().toISOString().replaceAll(/[:.]/g, "-");
|
|
155
|
+
const prefix = `${basename(dbPath)}.`;
|
|
156
|
+
const target = join(backupsDir, `${prefix}${stamp}.sqlite`);
|
|
157
|
+
database.query("VACUUM INTO ?").run(target);
|
|
158
|
+
await Bun.write(`${target}.sha256`, `${await sha256File(target)} ${basename(target)}\n`);
|
|
159
|
+
|
|
160
|
+
// Retention touches only this database's own backups, never other files.
|
|
161
|
+
const backups = readdirSync(backupsDir)
|
|
162
|
+
.filter((name) => name.startsWith(prefix) && name.endsWith(".sqlite") && name !== basename(target))
|
|
163
|
+
.sort();
|
|
164
|
+
for (const stale of backups.slice(0, Math.max(0, backups.length - (BACKUP_RETENTION - 1)))) {
|
|
165
|
+
rmSync(join(backupsDir, stale), { force: true });
|
|
166
|
+
rmSync(join(backupsDir, `${stale}.sha256`), { force: true });
|
|
167
|
+
}
|
|
168
|
+
return target;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Restore is an offline operation: run it with the app stopped, then start
|
|
172
|
+
// the app so boot re-applies any migrations newer than the backup. Nothing
|
|
173
|
+
// is opened or created at the destination before the checksum verifies.
|
|
174
|
+
export async function restoreDatabase(backupPath: string, dbPath: string): Promise<void> {
|
|
175
|
+
if (!existsSync(backupPath)) throw new Error(`backup not found: ${backupPath}`);
|
|
176
|
+
const sidecar = `${backupPath}.sha256`;
|
|
177
|
+
if (!existsSync(sidecar)) throw new Error(`checksum sidecar not found: ${sidecar}`);
|
|
178
|
+
const expected = (await Bun.file(sidecar).text()).trim().split(/\s+/)[0];
|
|
179
|
+
const digest = await sha256File(backupPath);
|
|
180
|
+
if (digest !== expected) throw new Error(`backup checksum mismatch for ${backupPath}; the file is corrupt or was modified.`);
|
|
181
|
+
mkdirSync(dirname(dbPath), { recursive: true });
|
|
182
|
+
// Stage a fsynced copy, atomically swap it in, and only then drop WAL/SHM.
|
|
183
|
+
// A failed rename leaves the previous database family fully intact; a stale
|
|
184
|
+
// WAL against the swapped file is ignored by SQLite (salt mismatch).
|
|
185
|
+
const temp = `${dbPath}.restore-tmp`;
|
|
186
|
+
await Bun.write(temp, Bun.file(backupPath));
|
|
187
|
+
const handle = openSync(temp, "r");
|
|
188
|
+
try {
|
|
189
|
+
fsyncSync(handle);
|
|
190
|
+
} finally {
|
|
191
|
+
closeSync(handle);
|
|
192
|
+
}
|
|
193
|
+
renameSync(temp, dbPath);
|
|
194
|
+
rmSync(`${dbPath}-wal`, { force: true });
|
|
195
|
+
rmSync(`${dbPath}-shm`, { force: true });
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export async function bootDatabase(database: Database, dbPath: string): Promise<void> {
|
|
199
|
+
const check = database.query<{ quick_check: string }, []>("PRAGMA quick_check(1)").get();
|
|
200
|
+
if (check?.quick_check !== "ok") {
|
|
201
|
+
throw new Error(`database integrity check failed for ${dbPath}: ${check?.quick_check ?? "no result"}. Restore a backup with bun db:restore.`);
|
|
202
|
+
}
|
|
203
|
+
// Existing data is anything with user tables, journaled or not, so a
|
|
204
|
+
// database predating this tooling still gets a pre-migration backup.
|
|
205
|
+
const existingData = hasUserTables(database);
|
|
206
|
+
const pending = pendingMigrations(database);
|
|
207
|
+
if (pending.length === 0) return;
|
|
208
|
+
if (existingData) {
|
|
209
|
+
const backup = await backupDatabase(database, dbPath);
|
|
210
|
+
console.log(`Pre-migration backup: ${backup}`);
|
|
211
|
+
}
|
|
212
|
+
const applied = await applyMigrations(database);
|
|
213
|
+
console.log(`Applied migrations: ${applied.join(", ")}`);
|
|
214
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
CREATE TABLE notes (
|
|
2
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
3
|
+
title TEXT NOT NULL CHECK (length(title) BETWEEN 1 AND 500),
|
|
4
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
5
|
+
);
|
|
6
|
+
|
|
7
|
+
CREATE INDEX notes_created_at ON notes (created_at);
|
|
8
|
+
|
|
9
|
+
INSERT INTO notes (title) VALUES ('It persists.');
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
|
3
|
+
|
|
4
|
+
// Project-owned schema. Author changes here, then write a matching SQL
|
|
5
|
+
// migration in src/db/migrations/ (drizzle-kit generate drafts into
|
|
6
|
+
// src/db/drizzle/ for review; copy the reviewed SQL over).
|
|
7
|
+
export const notes = sqliteTable("notes", {
|
|
8
|
+
id: integer("id").primaryKey({ autoIncrement: true }),
|
|
9
|
+
title: text("title").notNull(),
|
|
10
|
+
createdAt: text("created_at")
|
|
11
|
+
.notNull()
|
|
12
|
+
.default(sql`(datetime('now'))`),
|
|
13
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
// Validate the environment at the boundary; the app never reads process.env
|
|
4
|
+
// directly. Add new variables here so misconfiguration fails at startup.
|
|
5
|
+
const schema = z.object({
|
|
6
|
+
PORT: z.coerce.number().int().min(1).max(65535).default(3000),
|
|
7
|
+
// Container deployments mount a persistent volume at /data and set
|
|
8
|
+
// DB_PATH=/data/app.db (see compose.yaml). Local development stays in ./data.
|
|
9
|
+
DB_PATH: z.string().min(1).default("data/app.db"),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export type Env = z.infer<typeof schema>;
|
|
13
|
+
|
|
14
|
+
export function loadEnv(source: Record<string, string | undefined> = process.env): Env {
|
|
15
|
+
const parsed = schema.safeParse(source);
|
|
16
|
+
if (!parsed.success) {
|
|
17
|
+
console.error("Invalid environment:");
|
|
18
|
+
for (const issue of parsed.error.issues) {
|
|
19
|
+
console.error(` ${issue.path.join(".")}: ${issue.message}`);
|
|
20
|
+
}
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
return parsed.data;
|
|
24
|
+
}
|