@devwaren/vanilla-ts 1.0.14 → 1.0.15

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/dist/index.cjs CHANGED
@@ -16,9 +16,9 @@ export default function ${_.name}(DOM: HTMLElement) {
16
16
  \`);
17
17
  };
18
18
  `,"utf-8")}let R=p?`export const NotFound = async (DOM: HTMLElement) => {
19
- const mod = await import("../pages/${e.relative(s,p.file).replace(/\\/g,"/").replace(/\\.ts$/,"")}") as Module;
19
+ const mod = await import("../pages/${e.relative(s,p.file).replace(/\\/g,"/").replace(/\\.ts$/,"")}") as unknown as Module;
20
20
  return mod.default(DOM);
21
- };`:"export const NotFound = (DOM: HTMLElement) =>\n useTSElements(DOM, html`<h1>404 - Page Not Found</h1>`);",I=T.map(_=>{let Qe="../pages/"+e.relative(s,_.file).replace(/\\/g,"/").replace(/\.ts$/,"");return`{ path: "${_.route}", name: "${_.name}", component: () => import("${Qe}") as Promise<Module> }`}).join(`,
21
+ };`:"export const NotFound = (DOM: HTMLElement) =>\n useTSElements(DOM, html`<h1>404 - Page Not Found</h1>`);",I=T.map(_=>{let Qe="../pages/"+e.relative(s,_.file).replace(/\\/g,"/").replace(/\.ts$/,"");return`{ path: "${_.route}", name: "${_.name}", component: () => import("${Qe}") as unknown as Module }`}).join(`,
22
22
  `),Gt=`// AUTO-GENERATED ROUTER
23
23
  import { useTSElements, useTSParams, html } from "@devwaren/vanilla-ts";
24
24
 
@@ -102,9 +102,7 @@ export async function createRouter(DOM: HTMLElement) {
102
102
  useTSParams.getState().setFromPatternValues(Object.keys(params), Object.values(params));
103
103
 
104
104
  const query: Record<string, string> = {};
105
- url.searchParams.forEach((v, k) => {
106
- query[k] = v; // \u2705 no return
107
- });
105
+ url.searchParams.forEach((v, k) => { query[k] = v; });
108
106
  useTSParams.getState().setQuery(query);
109
107
 
110
108
  currentComponentUnmount?.();
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import Pe from"dompurify";var q=null;function xe(){return typeof window>"u"?null:(q||(q=Pe(window)),q)}var Ae=["div","span","p","a","button","ul","li","img","input","form","label","h1","h2","h3","h4","h5","h6","section","main","article","svg","path","circle","rect","line","polyline","polygon","g"],Ce=["class","id","href","src","alt","title","type","value","name","placeholder","target","rel","data-click","data-change","data-select","data-effect","data-hover","data-submit","data-key","data-event","data-component","data-stagger","data-input"];function He(n){return/^(https?:\/\/|\/|#)/i.test(n.trim())}function Oe(n){if(typeof window>"u")return n;let e=document.createElement("template");return e.innerHTML=n,e.content.querySelectorAll("*").forEach(t=>{[...t.attributes].forEach(r=>{let o=r.name.toLowerCase();if(o.startsWith("on")||o.startsWith("xlink")||o.startsWith("xml")){t.removeAttribute(r.name);return}(o==="href"||o==="src")&&!He(r.value)&&t.setAttribute(o,"#")}),t.tagName==="A"&&t.getAttribute("target")==="_blank"&&t.setAttribute("rel","noopener noreferrer")}),e.innerHTML}function K(n,...e){let t=xe(),r=n.reduce((s,i,a)=>{let l=a<e.length?String(e[a]??""):"";return s+i+l},"");if(!t)return r;let o=t.sanitize(r,{ALLOWED_TAGS:Ae,ALLOWED_ATTR:Ce,RETURN_DOM:!1});return Oe(o)}var De=(n,e)=>n.reduce((t,r,o)=>t+e(r,o),"");function Fe(n){return n}function $e(n){return new Proxy({},{get(e,t){return async r=>n(t,r)}})}import B from"dompurify";var V=(n,e)=>{let r={...{ADD_TAGS:["my-custom-tag"]},...e};return typeof n=="string"?B.sanitize(n,r):B.sanitize(n.innerHTML,r)};var G=(n,e,t)=>{if(!(typeof window>"u"||typeof document>"u"))if(typeof n=="string"){let r=document.getElementById(n);r?r.addEventListener(e,t):console.warn(`Element with id '${n}' not found.`)}else n instanceof HTMLElement?n.addEventListener(e,t):n===document?document.addEventListener(e,t):console.warn("Invalid target parameter provided.")};import{createStore as ke}from"zustand/vanilla";import qe from"dompurify";function C(n){return qe.sanitize(n??"")}function A(n,e){let t=Object.keys(n),r=Object.keys(e);if(t.length!==r.length)return!1;for(let o of t)if(n[o]!==e[o])return!1;return!0}function Ne(n,e){let t=[],r=n.replace(/:[^/]+/g,a=>(t.push(a.slice(1)),"([^/]+)")),o=new RegExp(`^${r}$`),s=e.match(o),i={};return s&&t.forEach((a,l)=>{i[a]=C(s[l+1]??"")}),i}function Ie(n){let e={},t=new URLSearchParams(n);for(let[r,o]of t.entries())e[r]=C(o);return e}var H=ke((n,e)=>({params:{},query:{},setFromPattern:t=>{let r=window.location.pathname,o=Ne(t,r),s=Ie(window.location.search),i=e();(!A(i.params,o)||!A(i.query,s))&&n({params:o,query:s})},setFromPatternValues:(t,r)=>{let o={};t.forEach((i,a)=>{o[i]=C(r[a]??"")});let s=e();A(s.params,o)||n({params:o})},setQuery:t=>{let r={};for(let s in t)r[s]=C(t[s]);let o=e();A(o.query,r)||n({query:r})},getParam:t=>e().params[t],getQuery:t=>e().query[t]}));function Y(n){let e=H.getState();e.setFromPattern(n);let t=e.params,r=e.query;return{...t,...r}}var X=(n,e,t)=>{let r=document.querySelectorAll(n);return r.forEach(o=>{o.addEventListener(e,t)}),()=>{r.forEach(o=>{o.removeEventListener(e,t)})}};import{animate as ze}from"motion";import _e from"dompurify";var N=typeof window<"u"&&typeof document<"u",J=["div","span","p","a","button","ul","li","img","input","form","label","h1","h2","h3","h4","h5","h6","section","main","article"],Z=["class","id","href","src","alt","title","type","value","name","placeholder","data-click","data-change","data-select","data-effect","data-hover","data-submit","data-key","data-event","data-component","data-stagger","data-input","data-children","data-slot","target","rel"],ee=N?_e(window):{sanitize:(n,e)=>n};function Ue(n){return/^(https?:\/\/|\/|#)/i.test(n.trim())}function je(n){N&&n.querySelectorAll("*").forEach(e=>{[...e.attributes].forEach(t=>{let r=t.name.toLowerCase();if(r.startsWith("on")){e.removeAttribute(t.name);return}(r==="href"||r==="src")&&!Ue(t.value)&&e.setAttribute(r,"#")}),e.tagName==="A"&&e.getAttribute("target")==="_blank"&&e.setAttribute("rel","noopener noreferrer")})}function te(n){let e={},t={},r=400,o=0,s="ease-in-out",i=0,a=!1,l,u;return n.split(/\s+/).forEach(c=>{c==="fade-in"&&(e.opacity=0,t.opacity=1),c==="fade-out"&&(e.opacity=1,t.opacity=0),c==="slide-up"&&(e.y=20,t.y=0),c==="slide-down"&&(e.y=-20,t.y=0),c==="slide-left"&&(e.x=20,t.x=0),c==="slide-right"&&(e.x=-20,t.x=0),c.startsWith("duration-")&&(r=+c.replace("duration-","")),c.startsWith("delay-")&&(o=+c.replace("delay-","")),(c==="linear"||c.startsWith("ease"))&&(s=c),c==="infinite"&&(i=1/0),c==="replay"&&(a=!0),c.startsWith("parallax-y-")&&(l=+c.replace("parallax-y-","")),c.startsWith("parallax-x-")&&(u=+c.replace("parallax-x-",""))}),{from:e,to:t,duration:r,easing:s,delay:o,repeat:i,replay:a,parallaxY:l,parallaxX:u}}function We(n,e){n.querySelectorAll("[data-component]").forEach(t=>{let r=t.dataset.component;e[r]?.(t)})}var ne=(n,e,t={},r)=>{if(!N||!n)return{html:ee.sanitize(e,{ALLOWED_TAGS:J,ALLOWED_ATTR:Z,...r})};let o=ee.sanitize(e,{ALLOWED_TAGS:J,ALLOWED_ATTR:Z,...r});n.innerHTML=o,je(n);let s=c=>{let d=c.target.closest("[data-click]");d&&t[d.dataset.click]?.(d)};n.addEventListener("click",s),n.querySelectorAll("[data-input]").forEach(c=>{let d=c.dataset.input;t[d]?.(c),c.addEventListener("input",()=>{t[d]?.(c)})}),We(n,t);let i=[];n.querySelectorAll("[data-effect]").forEach(c=>{let d=te(c.dataset.effect||"");(d.parallaxX||d.parallaxY)&&i.push({el:c,...d})});let a=!1,l=()=>{a||(a=!0,requestAnimationFrame(()=>{let c=window.scrollY;i.forEach(({el:d,parallaxX:h,parallaxY:p})=>{d.style.transform=`translate3d(${(h||0)*c}px, ${(p||0)*c}px, 0)`}),a=!1}))};window.addEventListener("scroll",l);let u=new IntersectionObserver(c=>{c.forEach(d=>{let h=d.target,p=te(h.dataset.effect||"");d.isIntersecting?(Object.assign(h.style,p.from),setTimeout(()=>{ze(h,p.to,{duration:p.duration/1e3,easing:p.easing,repeat:p.repeat})},p.delay),p.replay||u.unobserve(h)):p.replay&&Object.assign(h.style,p.from)})});return n.querySelectorAll("[data-effect]").forEach(c=>u.observe(c)),{cleanup(){u.disconnect(),window.removeEventListener("scroll",l),n.removeEventListener("click",s)}}};import re from"dompurify";var O=null,oe=(n,e)=>{if(typeof document>"u")return;let t=document.getElementById(n);if(!t)return;re.addHook("uponSanitizeAttribute",(i,a)=>{let l=(a.attrName||"").toLowerCase(),u=(a.attrValue??"").toString().trim();if(l.startsWith("on")){a.keepAttr=!1;return}if((l==="href"||l==="src")&&/^(javascript:|vbscript:|data:|file:|about:)/i.test(u)){a.keepAttr=!1;return}if(l==="class"){let d=u.split(/\s+/).filter(Boolean).filter(h=>{if(/^[a-zA-Z0-9\-\:\/_\[\]\(\)]+$/.test(h)){if(/^bg-\[url\(.*\)\]$/.test(h)){let p=h.replace(/^bg-\[url\(/,"").replace(/\)\]$/,"").replace(/^['"]|['"]$/g,"");return p===""||/^https?:\/\//i.test(p)||/^\/(?!\/)/.test(p)||/^\.{0,2}\//.test(p)}return!0}return!1});a.attrValue=d.join(" ");return}if(l==="style"){a.keepAttr=!1;return}});let r=t.cloneNode(!0),o=re.sanitize(r.innerHTML,{USE_PROFILES:{html:!0},ALLOWED_TAGS:["div","span","p","h1","h2","h3","h4","h5","h6","ul","ol","li","strong","em","a","img","br","form","button","input","label"],ALLOWED_ATTR:["href","src","alt","title","class","id","type","name","value","placeholder","data-click","data-change","data-submit","data-select","data-hover","data-classlist"],FORBID_TAGS:["script","iframe","object","embed","body","html","svg","math","link","meta"],ALLOW_DATA_ATTR:!0,KEEP_CONTENT:!1,RETURN_DOM_FRAGMENT:!0}),s=Array.from(o.childNodes).map(i=>i.outerHTML||i.textContent||"").join("");if(O!==null&&s!==O){let i=document.createElement("div");e(i);let l=new DOMParser().parseFromString(O,"text/html");for(;t.firstChild;)t.removeChild(t.firstChild);l.body.childNodes.forEach(u=>t.appendChild(u.cloneNode(!0)))}else{for(O=s;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(o),e(t)}};import se from"dompurify";typeof window<"u"&&!window.__anchorSinglePopstateHandlerAttached&&(window.addEventListener("popstate",n=>{let e=n.state;e?.scrollPosition!==void 0&&window.scrollTo(0,e.scrollPosition)}),window.__anchorSinglePopstateHandlerAttached=!0);var ie=(n,e,t,r="",o=null)=>{if(!n)return;let s=se.sanitize(e,{ALLOWED_URI_REGEXP:/^(https?:|\/)/}),i=se.sanitize(t,{USE_PROFILES:{html:!1}});n.setAttribute("href",s),n.setAttribute("aria-label",i),r&&(n.className=r.trim()),o&&n.replaceChildren(o),typeof window<"u"&&n.addEventListener("click",a=>{a.preventDefault();let u=a.currentTarget.getAttribute("href");if(u){let c=window.scrollY;window.scrollTo(0,0),window.history.pushState({scrollPosition:c},"",u),dispatchEvent(new PopStateEvent("popstate"))}})};import E from"dompurify";var ae=(n="'self' 'nonce-rAnd0m123' 'unsafe-inline' 'unsafe-eval'",e="'self' 'nonce-rAnd0m123'",t="'none'",r="'self' https://fonts.googleapis.com https://fonts.gstatic.com",o="'self' https://blogger.googleusercontent.com",s=["'self'","https://fonts.googleapis.com","https://fonts.gstatic.com","https://www.google.com/maps/"],i="'self' https://www.youtube.com",a="'self'",l="/csp-report",u=!1)=>{let c=()=>{try{let d=document.querySelector('meta[http-equiv="Content-Security-Policy"]');d||(d=document.createElement("meta"),d.setAttribute("http-equiv","Content-Security-Policy"),document.head.appendChild(d));let h=u?`report-uri ${l};`:"";d.setAttribute("content",`default-src 'self'; script-src ${n}; style-src ${e}; object-src ${t}; font-src ${r}; img-src ${o}; connect-src ${s.join(" ")}; frame-src ${i}; base-uri ${a}; ${h}`)}catch(d){console.error("Error adding CSP meta element:",d)}};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",c):c()};var ce=(n,e)=>{let t={name:E.sanitize(n.name||""),title:E.sanitize(n.title||""),description:E.sanitize(n.description||"Default description"),author:E.sanitize(n.author||""),favicon:n.favicon},r=m=>{t.name=E.sanitize(m),v("name",t.name)},o=m=>{t.title=E.sanitize(m),document.title=t.title},s=m=>{t.description=E.sanitize(m),v("description",t.description)},i=m=>{t.author=E.sanitize(m),v("author",t.author)},a=m=>{t.favicon=E.sanitize(m);let g=document.querySelector('link[rel="icon"]');g||(g=document.createElement("link"),g.rel="icon",document.head.appendChild(g)),g.href=t.favicon},l=()=>t.name,u=()=>t.title,c=()=>t.description,d=()=>t.author,h=()=>t.favicon,p=()=>t,P=(m,g)=>{let S=document.createElement("meta");S.setAttribute("name",m),S.setAttribute("content",g),document.head.appendChild(S)},v=(m,g)=>{let S=document.querySelector(`meta[name="${m}"]`);S?S.setAttribute("content",g):P(m,g)},y=()=>{t.title&&(document.title=t.title),t.name&&v("name",t.name),t.description&&v("description",t.description),t.author&&v("author",t.author),t.favicon&&a(t.favicon)};return e&&ae(e.scriptSrc,e.styleSrc,e.objectSrc,Array.isArray(e.connectSrc)?e.connectSrc.join(" "):e.connectSrc,e.reportOnly!==void 0?String(e.reportOnly):void 0),y(),{setName:r,setTitle:o,setDescription:s,setAuthor:i,setFavicon:a,getName:l,getTitle:u,getDescription:c,getAuthor:d,getFavicon:h,getAllMetaData:p,appendMetaTagsToHead:y}};import Qe from"dompurify";var D=(n,e,t,r,o)=>{let s=`#${n}`,i=e.querySelectorAll(s);if(i.length===0)throw new Error(`[useTSComponent] No element found with id '${n}' in the given parent.`);if(i.length>1)throw new Error(`[useTSComponent] Duplicate id '${n}' detected. Found ${i.length} elements.`);let a=i[0];a.innerHTML=Qe.sanitize(a.innerHTML,{USE_PROFILES:{html:!0}}),t(a,r,o)};var le=(n,e,t,r=[])=>{let o=new Set;n.forEach((s,i)=>{if(o.has(s)){console.warn(`[useTSCollection] Duplicate ID in collection array: "${s}" \u2014 skipping.`);return}o.add(s);let a=e.querySelectorAll(`#${s}`);if(a.length>1){console.warn(`[useTSCollection] Duplicate ID in DOM: "${s}" (${a.length} elements found) \u2014 skipping component mount.`);return}let l=t[i],u=Array.isArray(r)?r[i]:void 0;typeof l=="function"?D(s,e,l,u):console.warn(`[useTSCollection] No valid component function found for ID: "${s}"`)})};var M=(n,e)=>{let r=(e??document).querySelectorAll(n);if(r.length===0)return process.env.NODE_ENV!=="production"&&console.warn(`[useTSSelect] No element found for selector: '${n}'`),null;if(n.startsWith("#")&&r.length>1){if(process.env.NODE_ENV!=="production")throw new Error(`[useTSSelect] Duplicate ID detected: '${n}'. Found ${r.length} elements with this ID.`);return r[0]}return r.length>1&&process.env.NODE_ENV!=="production"&&console.warn(`[useTSSelect] Multiple elements found for selector: '${n}'. Returning the first one.`),r[0]};import{jwtDecode as Ke}from"jwt-decode";var ue=(n,e)=>{let t=localStorage.getItem("token");if(!t)return window.location.href=e,null;try{let r=Ke(t),o=Date.now()/1e3;return r.exp&&r.exp<o&&(console.error("Token has expired"),window.localStorage.removeItem("token"),window.location.href=e),null}catch(r){return console.error("Invalid token:",r),window.location.href=e,null}};var I=(n,e,t)=>{n.forEach(r=>{e.forEach(o=>{r.addEventListener(o,s=>{t(r,s)})})})};var de=()=>({back:()=>window.history.back(),forward:()=>window.history.forward()});var me=(n,e)=>{let t=document.querySelector(`#${n}`)||document.querySelector(`.${n}`);if(!t)return;let r=window.location.pathname.replace(/\/$/,"");for(let o of e){let s=o.path.replace(/\/$/,"");if(r===s||r.startsWith(`${s}/`)){o.component(t);break}}};function pe(n,e){let t=window.location.pathname.replace(/\/$/,"");e.routes.forEach(r=>{r.children?.length&&r.children.forEach(o=>{let s=o.path.replace(/\/$/,"");if(t===s||t.startsWith(`${s}/`)){let i=n.querySelector(`#${o.outlet}`)||n.querySelector(`.${o.outlet}`);i instanceof HTMLElement&&o.element&&o.element(i)}})})}var fe=async()=>{let n="https://cdn.jsdelivr.net/npm/brython@3/brython.min.js",e="https://cdn.jsdelivr.net/npm/brython@3/brython_stdlib.js",t=r=>new Promise((o,s)=>{let i=document.createElement("script");i.src=r,i.onload=()=>o(),i.onerror=()=>s(new Error(`Failed to load ${r}`)),document.head.appendChild(i)});await t(n),await t(e),typeof window.brython=="function"?window.brython():console.error("Brython did not load correctly.")},he=n=>new Promise((e,t)=>{let r=document.createElement("script");r.type="text/python",r.src=`/src/python/${n}`,r.onload=()=>e(),r.onerror=()=>t(new Error(`Failed to load ${n}`)),document.body.appendChild(r)});function ge(n){let e=null;return async(t,r)=>{try{if(!e){let o=await n();e=o.default||o}if(typeof e=="function")return e(t,r);if(e instanceof HTMLElement){let o=e.cloneNode(!0);return t?.appendChild(o),o}if(typeof e=="object"&&e!==null&&"render"in e&&typeof e.render=="function")return e.render(t,r);console.warn("useTSLazy: Unsupported module type",e)}catch(o){console.error("useTSLazy failed:",o)}}}var ye=n=>typeof window>"u"?{isDOM:null}:{isDOM:n||document.body};import{debounce as Be}from"lodash-es";var z=n=>n;typeof window<"u"&&typeof document<"u"&&(z=n=>{let e=document.createElement("div");return e.innerText=n,e.innerHTML});var Ve=n=>{(n?Array.isArray(n)?n:n instanceof HTMLAnchorElement?[n]:Array.from(n):Array.from(document.querySelectorAll("a"))).forEach(t=>{if(!t||t.dataset.anchorEnhanced==="true")return;t.dataset.anchorEnhanced="true";let r=t.getAttribute("class")||"";t.setAttribute("class",z(r));let o=t.getAttribute("aria-label");o&&t.setAttribute("aria-label",z(o));let s=t.querySelector(":scope > *");s&&(t.innerHTML="",t.appendChild(s));let i=t.getAttribute("href")||"";if(!i.startsWith("#")){try{if(new URL(i,window.location.href).origin!==window.location.origin)return}catch{return}t.addEventListener("click",a=>{a.preventDefault();let l=t.getAttribute("href")||"";try{let u=new URL(l,window.location.href);window.history.pushState({},"",u.pathname+u.search+u.hash),window.dispatchEvent(new PopStateEvent("popstate"))}catch(u){console.error("Invalid URL in anchor:",l,u)}})}})},Ge=Be(Ve,50),F=n=>{Ge(n)};var Te=n=>{if(!n)return;let e=M("a",n);F(e)};var Se=n=>{let e=n,t=[];return[()=>e,i=>{e=typeof i=="function"?i(e):i,t.forEach(a=>a(e))},i=>{t.push(i),i(e)}]};function Ee(n,e,t){let r=()=>{n.textContent=e().toString(),t?.(e())};r();let o=e.set;o&&(e.set=s=>{o(s),r()})}function ve(n){let[e,t,r]=Se(n),o=[],s=(()=>e());return s.set=i=>{t(i),o.forEach(a=>a(s()))},s.bind=i=>Ee(i,s),s.subscribe=i=>{o.push(i),i(s())},s}function we(n,e){let t={deps:e.map(o=>typeof o=="function"?o():o)},r=n();typeof r=="function"&&(t.cleanup=r),e.forEach((o,s)=>{typeof o=="function"&&"bind"in o&&o.subscribe?.(()=>{let a=o(),l=t.deps[s];if(a!==l){t.cleanup?.(),t.deps[s]=a;let u=n();typeof u=="function"&&(t.cleanup=u)}})})}var f={params:{},query:{}},_=new Set;function Ye(){return{params:{...f.params},query:{...f.query}}}function b(n,e){let t=Object.keys(n),r=Object.keys(e);if(t.length!==r.length)return!1;for(let o of t)if(n[o]!==e[o])return!1;return!0}function L(){let n=Ye();_.forEach(e=>e(n))}function Xe(n){let e={};if(!n)return e;let t=n.startsWith("?")?n.slice(1):n;for(let r of t.split("&")){if(!r)continue;let[o,s]=r.split("=");o&&(e[decodeURIComponent(o)]=decodeURIComponent(s||""))}return e}function Je(n){let e=new URLSearchParams;for(let r in n){let o=n[r];o!=null&&o!==""&&e.set(r,o)}let t=e.toString();return t?`?${t}`:""}function $(){if(typeof window>"u")return;let n=window.location.pathname,e=window.location.hash,t=Je(f.query);history.replaceState({},"",n+t+e)}var U={getState(){return{params:f.params,query:f.query,getParam:n=>f.params[n],getQuery:n=>f.query[n],setFromPattern(n){if(typeof window>"u")return;let e=n.match(/:([^/]+)/g)?.map(o=>o.slice(1))||[],t=window.location.pathname.split("/").filter(Boolean),r={};e.forEach((o,s)=>{r[o]=t[s]}),b(f.params,r)||(f.params=r,L())},setFromPatternValues(n,e){let t={};n.forEach((r,o)=>{t[r]=e[o]}),b(f.params,t)||(f.params=t,L())},setQuery(n){let e={...f.query,...n};b(f.query,e)||(f.query=e,$(),L())},replaceQuery(n){b(f.query,n)||(f.query={...n},$(),L())},removeQuery(n){if(!(n in f.query))return;let e={...f.query};delete e[n],f.query=e,$(),L()},clearQuery(){Object.keys(f.query).length!==0&&(f.query={},$(),L())},setQueryFromURL(n){let e=Xe(n);b(f.query,e)||(f.query=e,L())},subscribe(n){return _.add(n),()=>_.delete(n)}}}};typeof window<"u"&&window.addEventListener("popstate",()=>{U.getState().setQueryFromURL(window.location.search)});import Re from"dompurify";import{createStore as Ze}from"zustand/vanilla";import et from"dompurify";var w=Ze(n=>({params:{},query:{},setParams:e=>n(()=>({params:Le(e)})),setQuery:e=>n(()=>({query:Le(e)}))}));function Le(n){let e={};for(let t in n)e[t]=et.sanitize(n[t]);return e}var j=class{routes=[];expectedParams;apiFetcher;constructor(e,t,r){this.routes=e,this.expectedParams=new Set(t),this.apiFetcher=r,window.addEventListener("popstate",this.handlePopState.bind(this)),this.handlePopState()}handlePopState(){let e=window.location.pathname,t=window.location.search,r=this.parseQueryParams(t);if(e.startsWith("/api")&&this.apiFetcher){let i=e.replace("/api/","").split("/")[0],a=Object.fromEntries(new URLSearchParams(t));this.apiFetcher(i,a).then(l=>console.log("API response:",l)).catch(l=>console.error("API error:",l));return}let o=this.findMatchingRoute(e,this.routes);if(o){if(o.routeto){this.navigate(o.routeto);return}let s=this.filterAndSanitizeParams(o.params);w.getState().setParams(s),w.getState().setQuery(r);let i=document.createElement("div");if(o.element?.(i,s,r),o.children){let a=e.slice(o.path.length),l=i.querySelector("#child");l&&this.renderChildren(o.children,a,l,s,r)}}else{let s=this.findMatchingRoute("*",this.routes);if(s){let i=this.filterAndSanitizeParams(s.params);w.getState().setParams(i),w.getState().setQuery(r);let a=document.createElement("div");s.element?.(a,i,r)}}}renderChildren(e,t,r,o,s){if(!e||e.length===0){let a=r.querySelector("#child");a&&a.remove();return}let i=this.findMatchingRoute(t,e);if(i){let a=document.createElement("div");a.id="child";let l={...o,...i.params},u=this.filterAndSanitizeParams(l);if(w.getState().setParams(u),w.getState().setQuery(s),i.element?.(a,u,s),r.appendChild(a),i.children){let c=t.slice(i.path.length);this.renderChildren(i.children,c,a,u,s)}}}parseQueryParams(e){let t={},r=new URLSearchParams(e);for(let[o,s]of r.entries())this.expectedParams.has(o)&&(t[o]=Re.sanitize(s));return t}findMatchingRoute(e,t,r={}){for(let o of t){let s=o.path;if(s==="*")return o;{let a=[],l=s.replace(/:[^\s/]+/g,d=>(a.push(d.substring(1)),"([^\\s/]+)")),u=new RegExp(`^${l}(?:/|$)`),c=e.match(u);if(c){let d={...r};if(a.forEach((h,p)=>{d[h]=c[p+1]??""}),o.children){let h=e.slice(c[0].length),p=this.findMatchingRoute(h,o.children,d);if(p)return p}return{...o,params:d}}}}}filterAndSanitizeParams(e){if(!e)return{};let t={};for(let r in e)this.expectedParams.has(r)&&(t[r]=Re.sanitize(e[r]??""));return t}navigate(e){history.pushState(null,"",e),this.handlePopState()}addRoute(e){this.routes.push(e)}};var tt=()=>({name:"ts-filebased-router",async buildStart(){let n=await import("fs/promises"),e=await import("path"),t=await import("./esm-KRNKVVL7.js"),r=e.resolve("src/pages"),o=e.resolve("src/gen"),s=e.resolve("src/routes"),i=e.join(o,"tsrouter.gen.ts"),a=e.join(s,"__root.ts"),l=process.env.NODE_ENV!=="production",u=async y=>n.mkdir(y,{recursive:!0}).catch(()=>{}),c=y=>y.charAt(0).toUpperCase()+y.slice(1),d=y=>{let m="/"+e.relative(r,y).replace(/\\/g,"/");return m=m.replace(/\.ts$/,"").replace(/\/index$/,"")||"/",m.replace(/\[\.\.\.(.+?)\]/g,"*").replace(/\[(.+?)\]/g,":$1")},h=y=>y.replace(/^\//,"").split("/").map(m=>m.startsWith(":")?c(m.slice(1)):m.replace(/\b\w/g,g=>g.toUpperCase()).replace(/[-_]/g,"")).filter(Boolean).join("")||"Index",p=async y=>{let m=await n.readdir(y,{withFileTypes:!0}),g=[];for(let S of m){let R=e.join(y,S.name);S.isDirectory()?g.push(...await p(R)):S.isFile()&&S.name.endsWith(".ts")&&g.push({file:R,route:d(R),name:h(d(R))})}return g},P=async()=>{let y=await p(r),m=y.find(T=>T.route==="/notfound"),g=y.filter(T=>T.route!=="/notfound");for(let T of y)if(!(await n.readFile(T.file,"utf-8")).trim()){let x=T.route.includes(":"),Q=x?T.route.split("/").filter(k=>k.startsWith(":")).map(k=>k.slice(1)):[],be=x?`const { ${Q.join(", ")} } = useTSExtractParams("${T.route}");`:"";await n.writeFile(T.file,`import { html, useTSElements, useTSMetaData${x?", useTSExtractParams":""} } from "@devwaren/vanilla-ts";
1
+ import Pe from"dompurify";var q=null;function xe(){return typeof window>"u"?null:(q||(q=Pe(window)),q)}var Ae=["div","span","p","a","button","ul","li","img","input","form","label","h1","h2","h3","h4","h5","h6","section","main","article","svg","path","circle","rect","line","polyline","polygon","g"],Ce=["class","id","href","src","alt","title","type","value","name","placeholder","target","rel","data-click","data-change","data-select","data-effect","data-hover","data-submit","data-key","data-event","data-component","data-stagger","data-input"];function He(n){return/^(https?:\/\/|\/|#)/i.test(n.trim())}function Oe(n){if(typeof window>"u")return n;let e=document.createElement("template");return e.innerHTML=n,e.content.querySelectorAll("*").forEach(t=>{[...t.attributes].forEach(r=>{let o=r.name.toLowerCase();if(o.startsWith("on")||o.startsWith("xlink")||o.startsWith("xml")){t.removeAttribute(r.name);return}(o==="href"||o==="src")&&!He(r.value)&&t.setAttribute(o,"#")}),t.tagName==="A"&&t.getAttribute("target")==="_blank"&&t.setAttribute("rel","noopener noreferrer")}),e.innerHTML}function K(n,...e){let t=xe(),r=n.reduce((s,i,a)=>{let l=a<e.length?String(e[a]??""):"";return s+i+l},"");if(!t)return r;let o=t.sanitize(r,{ALLOWED_TAGS:Ae,ALLOWED_ATTR:Ce,RETURN_DOM:!1});return Oe(o)}var De=(n,e)=>n.reduce((t,r,o)=>t+e(r,o),"");function Fe(n){return n}function ke(n){return new Proxy({},{get(e,t){return async r=>n(t,r)}})}import B from"dompurify";var V=(n,e)=>{let r={...{ADD_TAGS:["my-custom-tag"]},...e};return typeof n=="string"?B.sanitize(n,r):B.sanitize(n.innerHTML,r)};var G=(n,e,t)=>{if(!(typeof window>"u"||typeof document>"u"))if(typeof n=="string"){let r=document.getElementById(n);r?r.addEventListener(e,t):console.warn(`Element with id '${n}' not found.`)}else n instanceof HTMLElement?n.addEventListener(e,t):n===document?document.addEventListener(e,t):console.warn("Invalid target parameter provided.")};import{createStore as $e}from"zustand/vanilla";import qe from"dompurify";function C(n){return qe.sanitize(n??"")}function A(n,e){let t=Object.keys(n),r=Object.keys(e);if(t.length!==r.length)return!1;for(let o of t)if(n[o]!==e[o])return!1;return!0}function Ne(n,e){let t=[],r=n.replace(/:[^/]+/g,a=>(t.push(a.slice(1)),"([^/]+)")),o=new RegExp(`^${r}$`),s=e.match(o),i={};return s&&t.forEach((a,l)=>{i[a]=C(s[l+1]??"")}),i}function Ie(n){let e={},t=new URLSearchParams(n);for(let[r,o]of t.entries())e[r]=C(o);return e}var H=$e((n,e)=>({params:{},query:{},setFromPattern:t=>{let r=window.location.pathname,o=Ne(t,r),s=Ie(window.location.search),i=e();(!A(i.params,o)||!A(i.query,s))&&n({params:o,query:s})},setFromPatternValues:(t,r)=>{let o={};t.forEach((i,a)=>{o[i]=C(r[a]??"")});let s=e();A(s.params,o)||n({params:o})},setQuery:t=>{let r={};for(let s in t)r[s]=C(t[s]);let o=e();A(o.query,r)||n({query:r})},getParam:t=>e().params[t],getQuery:t=>e().query[t]}));function Y(n){let e=H.getState();e.setFromPattern(n);let t=e.params,r=e.query;return{...t,...r}}var X=(n,e,t)=>{let r=document.querySelectorAll(n);return r.forEach(o=>{o.addEventListener(e,t)}),()=>{r.forEach(o=>{o.removeEventListener(e,t)})}};import{animate as ze}from"motion";import _e from"dompurify";var N=typeof window<"u"&&typeof document<"u",J=["div","span","p","a","button","ul","li","img","input","form","label","h1","h2","h3","h4","h5","h6","section","main","article"],Z=["class","id","href","src","alt","title","type","value","name","placeholder","data-click","data-change","data-select","data-effect","data-hover","data-submit","data-key","data-event","data-component","data-stagger","data-input","data-children","data-slot","target","rel"],ee=N?_e(window):{sanitize:(n,e)=>n};function Ue(n){return/^(https?:\/\/|\/|#)/i.test(n.trim())}function je(n){N&&n.querySelectorAll("*").forEach(e=>{[...e.attributes].forEach(t=>{let r=t.name.toLowerCase();if(r.startsWith("on")){e.removeAttribute(t.name);return}(r==="href"||r==="src")&&!Ue(t.value)&&e.setAttribute(r,"#")}),e.tagName==="A"&&e.getAttribute("target")==="_blank"&&e.setAttribute("rel","noopener noreferrer")})}function te(n){let e={},t={},r=400,o=0,s="ease-in-out",i=0,a=!1,l,u;return n.split(/\s+/).forEach(c=>{c==="fade-in"&&(e.opacity=0,t.opacity=1),c==="fade-out"&&(e.opacity=1,t.opacity=0),c==="slide-up"&&(e.y=20,t.y=0),c==="slide-down"&&(e.y=-20,t.y=0),c==="slide-left"&&(e.x=20,t.x=0),c==="slide-right"&&(e.x=-20,t.x=0),c.startsWith("duration-")&&(r=+c.replace("duration-","")),c.startsWith("delay-")&&(o=+c.replace("delay-","")),(c==="linear"||c.startsWith("ease"))&&(s=c),c==="infinite"&&(i=1/0),c==="replay"&&(a=!0),c.startsWith("parallax-y-")&&(l=+c.replace("parallax-y-","")),c.startsWith("parallax-x-")&&(u=+c.replace("parallax-x-",""))}),{from:e,to:t,duration:r,easing:s,delay:o,repeat:i,replay:a,parallaxY:l,parallaxX:u}}function We(n,e){n.querySelectorAll("[data-component]").forEach(t=>{let r=t.dataset.component;e[r]?.(t)})}var ne=(n,e,t={},r)=>{if(!N||!n)return{html:ee.sanitize(e,{ALLOWED_TAGS:J,ALLOWED_ATTR:Z,...r})};let o=ee.sanitize(e,{ALLOWED_TAGS:J,ALLOWED_ATTR:Z,...r});n.innerHTML=o,je(n);let s=c=>{let d=c.target.closest("[data-click]");d&&t[d.dataset.click]?.(d)};n.addEventListener("click",s),n.querySelectorAll("[data-input]").forEach(c=>{let d=c.dataset.input;t[d]?.(c),c.addEventListener("input",()=>{t[d]?.(c)})}),We(n,t);let i=[];n.querySelectorAll("[data-effect]").forEach(c=>{let d=te(c.dataset.effect||"");(d.parallaxX||d.parallaxY)&&i.push({el:c,...d})});let a=!1,l=()=>{a||(a=!0,requestAnimationFrame(()=>{let c=window.scrollY;i.forEach(({el:d,parallaxX:h,parallaxY:p})=>{d.style.transform=`translate3d(${(h||0)*c}px, ${(p||0)*c}px, 0)`}),a=!1}))};window.addEventListener("scroll",l);let u=new IntersectionObserver(c=>{c.forEach(d=>{let h=d.target,p=te(h.dataset.effect||"");d.isIntersecting?(Object.assign(h.style,p.from),setTimeout(()=>{ze(h,p.to,{duration:p.duration/1e3,easing:p.easing,repeat:p.repeat})},p.delay),p.replay||u.unobserve(h)):p.replay&&Object.assign(h.style,p.from)})});return n.querySelectorAll("[data-effect]").forEach(c=>u.observe(c)),{cleanup(){u.disconnect(),window.removeEventListener("scroll",l),n.removeEventListener("click",s)}}};import re from"dompurify";var O=null,oe=(n,e)=>{if(typeof document>"u")return;let t=document.getElementById(n);if(!t)return;re.addHook("uponSanitizeAttribute",(i,a)=>{let l=(a.attrName||"").toLowerCase(),u=(a.attrValue??"").toString().trim();if(l.startsWith("on")){a.keepAttr=!1;return}if((l==="href"||l==="src")&&/^(javascript:|vbscript:|data:|file:|about:)/i.test(u)){a.keepAttr=!1;return}if(l==="class"){let d=u.split(/\s+/).filter(Boolean).filter(h=>{if(/^[a-zA-Z0-9\-\:\/_\[\]\(\)]+$/.test(h)){if(/^bg-\[url\(.*\)\]$/.test(h)){let p=h.replace(/^bg-\[url\(/,"").replace(/\)\]$/,"").replace(/^['"]|['"]$/g,"");return p===""||/^https?:\/\//i.test(p)||/^\/(?!\/)/.test(p)||/^\.{0,2}\//.test(p)}return!0}return!1});a.attrValue=d.join(" ");return}if(l==="style"){a.keepAttr=!1;return}});let r=t.cloneNode(!0),o=re.sanitize(r.innerHTML,{USE_PROFILES:{html:!0},ALLOWED_TAGS:["div","span","p","h1","h2","h3","h4","h5","h6","ul","ol","li","strong","em","a","img","br","form","button","input","label"],ALLOWED_ATTR:["href","src","alt","title","class","id","type","name","value","placeholder","data-click","data-change","data-submit","data-select","data-hover","data-classlist"],FORBID_TAGS:["script","iframe","object","embed","body","html","svg","math","link","meta"],ALLOW_DATA_ATTR:!0,KEEP_CONTENT:!1,RETURN_DOM_FRAGMENT:!0}),s=Array.from(o.childNodes).map(i=>i.outerHTML||i.textContent||"").join("");if(O!==null&&s!==O){let i=document.createElement("div");e(i);let l=new DOMParser().parseFromString(O,"text/html");for(;t.firstChild;)t.removeChild(t.firstChild);l.body.childNodes.forEach(u=>t.appendChild(u.cloneNode(!0)))}else{for(O=s;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(o),e(t)}};import se from"dompurify";typeof window<"u"&&!window.__anchorSinglePopstateHandlerAttached&&(window.addEventListener("popstate",n=>{let e=n.state;e?.scrollPosition!==void 0&&window.scrollTo(0,e.scrollPosition)}),window.__anchorSinglePopstateHandlerAttached=!0);var ie=(n,e,t,r="",o=null)=>{if(!n)return;let s=se.sanitize(e,{ALLOWED_URI_REGEXP:/^(https?:|\/)/}),i=se.sanitize(t,{USE_PROFILES:{html:!1}});n.setAttribute("href",s),n.setAttribute("aria-label",i),r&&(n.className=r.trim()),o&&n.replaceChildren(o),typeof window<"u"&&n.addEventListener("click",a=>{a.preventDefault();let u=a.currentTarget.getAttribute("href");if(u){let c=window.scrollY;window.scrollTo(0,0),window.history.pushState({scrollPosition:c},"",u),dispatchEvent(new PopStateEvent("popstate"))}})};import E from"dompurify";var ae=(n="'self' 'nonce-rAnd0m123' 'unsafe-inline' 'unsafe-eval'",e="'self' 'nonce-rAnd0m123'",t="'none'",r="'self' https://fonts.googleapis.com https://fonts.gstatic.com",o="'self' https://blogger.googleusercontent.com",s=["'self'","https://fonts.googleapis.com","https://fonts.gstatic.com","https://www.google.com/maps/"],i="'self' https://www.youtube.com",a="'self'",l="/csp-report",u=!1)=>{let c=()=>{try{let d=document.querySelector('meta[http-equiv="Content-Security-Policy"]');d||(d=document.createElement("meta"),d.setAttribute("http-equiv","Content-Security-Policy"),document.head.appendChild(d));let h=u?`report-uri ${l};`:"";d.setAttribute("content",`default-src 'self'; script-src ${n}; style-src ${e}; object-src ${t}; font-src ${r}; img-src ${o}; connect-src ${s.join(" ")}; frame-src ${i}; base-uri ${a}; ${h}`)}catch(d){console.error("Error adding CSP meta element:",d)}};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",c):c()};var ce=(n,e)=>{let t={name:E.sanitize(n.name||""),title:E.sanitize(n.title||""),description:E.sanitize(n.description||"Default description"),author:E.sanitize(n.author||""),favicon:n.favicon},r=m=>{t.name=E.sanitize(m),v("name",t.name)},o=m=>{t.title=E.sanitize(m),document.title=t.title},s=m=>{t.description=E.sanitize(m),v("description",t.description)},i=m=>{t.author=E.sanitize(m),v("author",t.author)},a=m=>{t.favicon=E.sanitize(m);let g=document.querySelector('link[rel="icon"]');g||(g=document.createElement("link"),g.rel="icon",document.head.appendChild(g)),g.href=t.favicon},l=()=>t.name,u=()=>t.title,c=()=>t.description,d=()=>t.author,h=()=>t.favicon,p=()=>t,P=(m,g)=>{let S=document.createElement("meta");S.setAttribute("name",m),S.setAttribute("content",g),document.head.appendChild(S)},v=(m,g)=>{let S=document.querySelector(`meta[name="${m}"]`);S?S.setAttribute("content",g):P(m,g)},y=()=>{t.title&&(document.title=t.title),t.name&&v("name",t.name),t.description&&v("description",t.description),t.author&&v("author",t.author),t.favicon&&a(t.favicon)};return e&&ae(e.scriptSrc,e.styleSrc,e.objectSrc,Array.isArray(e.connectSrc)?e.connectSrc.join(" "):e.connectSrc,e.reportOnly!==void 0?String(e.reportOnly):void 0),y(),{setName:r,setTitle:o,setDescription:s,setAuthor:i,setFavicon:a,getName:l,getTitle:u,getDescription:c,getAuthor:d,getFavicon:h,getAllMetaData:p,appendMetaTagsToHead:y}};import Qe from"dompurify";var D=(n,e,t,r,o)=>{let s=`#${n}`,i=e.querySelectorAll(s);if(i.length===0)throw new Error(`[useTSComponent] No element found with id '${n}' in the given parent.`);if(i.length>1)throw new Error(`[useTSComponent] Duplicate id '${n}' detected. Found ${i.length} elements.`);let a=i[0];a.innerHTML=Qe.sanitize(a.innerHTML,{USE_PROFILES:{html:!0}}),t(a,r,o)};var le=(n,e,t,r=[])=>{let o=new Set;n.forEach((s,i)=>{if(o.has(s)){console.warn(`[useTSCollection] Duplicate ID in collection array: "${s}" \u2014 skipping.`);return}o.add(s);let a=e.querySelectorAll(`#${s}`);if(a.length>1){console.warn(`[useTSCollection] Duplicate ID in DOM: "${s}" (${a.length} elements found) \u2014 skipping component mount.`);return}let l=t[i],u=Array.isArray(r)?r[i]:void 0;typeof l=="function"?D(s,e,l,u):console.warn(`[useTSCollection] No valid component function found for ID: "${s}"`)})};var M=(n,e)=>{let r=(e??document).querySelectorAll(n);if(r.length===0)return process.env.NODE_ENV!=="production"&&console.warn(`[useTSSelect] No element found for selector: '${n}'`),null;if(n.startsWith("#")&&r.length>1){if(process.env.NODE_ENV!=="production")throw new Error(`[useTSSelect] Duplicate ID detected: '${n}'. Found ${r.length} elements with this ID.`);return r[0]}return r.length>1&&process.env.NODE_ENV!=="production"&&console.warn(`[useTSSelect] Multiple elements found for selector: '${n}'. Returning the first one.`),r[0]};import{jwtDecode as Ke}from"jwt-decode";var ue=(n,e)=>{let t=localStorage.getItem("token");if(!t)return window.location.href=e,null;try{let r=Ke(t),o=Date.now()/1e3;return r.exp&&r.exp<o&&(console.error("Token has expired"),window.localStorage.removeItem("token"),window.location.href=e),null}catch(r){return console.error("Invalid token:",r),window.location.href=e,null}};var I=(n,e,t)=>{n.forEach(r=>{e.forEach(o=>{r.addEventListener(o,s=>{t(r,s)})})})};var de=()=>({back:()=>window.history.back(),forward:()=>window.history.forward()});var me=(n,e)=>{let t=document.querySelector(`#${n}`)||document.querySelector(`.${n}`);if(!t)return;let r=window.location.pathname.replace(/\/$/,"");for(let o of e){let s=o.path.replace(/\/$/,"");if(r===s||r.startsWith(`${s}/`)){o.component(t);break}}};function pe(n,e){let t=window.location.pathname.replace(/\/$/,"");e.routes.forEach(r=>{r.children?.length&&r.children.forEach(o=>{let s=o.path.replace(/\/$/,"");if(t===s||t.startsWith(`${s}/`)){let i=n.querySelector(`#${o.outlet}`)||n.querySelector(`.${o.outlet}`);i instanceof HTMLElement&&o.element&&o.element(i)}})})}var fe=async()=>{let n="https://cdn.jsdelivr.net/npm/brython@3/brython.min.js",e="https://cdn.jsdelivr.net/npm/brython@3/brython_stdlib.js",t=r=>new Promise((o,s)=>{let i=document.createElement("script");i.src=r,i.onload=()=>o(),i.onerror=()=>s(new Error(`Failed to load ${r}`)),document.head.appendChild(i)});await t(n),await t(e),typeof window.brython=="function"?window.brython():console.error("Brython did not load correctly.")},he=n=>new Promise((e,t)=>{let r=document.createElement("script");r.type="text/python",r.src=`/src/python/${n}`,r.onload=()=>e(),r.onerror=()=>t(new Error(`Failed to load ${n}`)),document.body.appendChild(r)});function ge(n){let e=null;return async(t,r)=>{try{if(!e){let o=await n();e=o.default||o}if(typeof e=="function")return e(t,r);if(e instanceof HTMLElement){let o=e.cloneNode(!0);return t?.appendChild(o),o}if(typeof e=="object"&&e!==null&&"render"in e&&typeof e.render=="function")return e.render(t,r);console.warn("useTSLazy: Unsupported module type",e)}catch(o){console.error("useTSLazy failed:",o)}}}var ye=n=>typeof window>"u"?{isDOM:null}:{isDOM:n||document.body};import{debounce as Be}from"lodash-es";var z=n=>n;typeof window<"u"&&typeof document<"u"&&(z=n=>{let e=document.createElement("div");return e.innerText=n,e.innerHTML});var Ve=n=>{(n?Array.isArray(n)?n:n instanceof HTMLAnchorElement?[n]:Array.from(n):Array.from(document.querySelectorAll("a"))).forEach(t=>{if(!t||t.dataset.anchorEnhanced==="true")return;t.dataset.anchorEnhanced="true";let r=t.getAttribute("class")||"";t.setAttribute("class",z(r));let o=t.getAttribute("aria-label");o&&t.setAttribute("aria-label",z(o));let s=t.querySelector(":scope > *");s&&(t.innerHTML="",t.appendChild(s));let i=t.getAttribute("href")||"";if(!i.startsWith("#")){try{if(new URL(i,window.location.href).origin!==window.location.origin)return}catch{return}t.addEventListener("click",a=>{a.preventDefault();let l=t.getAttribute("href")||"";try{let u=new URL(l,window.location.href);window.history.pushState({},"",u.pathname+u.search+u.hash),window.dispatchEvent(new PopStateEvent("popstate"))}catch(u){console.error("Invalid URL in anchor:",l,u)}})}})},Ge=Be(Ve,50),F=n=>{Ge(n)};var Te=n=>{if(!n)return;let e=M("a",n);F(e)};var Se=n=>{let e=n,t=[];return[()=>e,i=>{e=typeof i=="function"?i(e):i,t.forEach(a=>a(e))},i=>{t.push(i),i(e)}]};function Ee(n,e,t){let r=()=>{n.textContent=e().toString(),t?.(e())};r();let o=e.set;o&&(e.set=s=>{o(s),r()})}function ve(n){let[e,t,r]=Se(n),o=[],s=(()=>e());return s.set=i=>{t(i),o.forEach(a=>a(s()))},s.bind=i=>Ee(i,s),s.subscribe=i=>{o.push(i),i(s())},s}function we(n,e){let t={deps:e.map(o=>typeof o=="function"?o():o)},r=n();typeof r=="function"&&(t.cleanup=r),e.forEach((o,s)=>{typeof o=="function"&&"bind"in o&&o.subscribe?.(()=>{let a=o(),l=t.deps[s];if(a!==l){t.cleanup?.(),t.deps[s]=a;let u=n();typeof u=="function"&&(t.cleanup=u)}})})}var f={params:{},query:{}},_=new Set;function Ye(){return{params:{...f.params},query:{...f.query}}}function b(n,e){let t=Object.keys(n),r=Object.keys(e);if(t.length!==r.length)return!1;for(let o of t)if(n[o]!==e[o])return!1;return!0}function L(){let n=Ye();_.forEach(e=>e(n))}function Xe(n){let e={};if(!n)return e;let t=n.startsWith("?")?n.slice(1):n;for(let r of t.split("&")){if(!r)continue;let[o,s]=r.split("=");o&&(e[decodeURIComponent(o)]=decodeURIComponent(s||""))}return e}function Je(n){let e=new URLSearchParams;for(let r in n){let o=n[r];o!=null&&o!==""&&e.set(r,o)}let t=e.toString();return t?`?${t}`:""}function k(){if(typeof window>"u")return;let n=window.location.pathname,e=window.location.hash,t=Je(f.query);history.replaceState({},"",n+t+e)}var U={getState(){return{params:f.params,query:f.query,getParam:n=>f.params[n],getQuery:n=>f.query[n],setFromPattern(n){if(typeof window>"u")return;let e=n.match(/:([^/]+)/g)?.map(o=>o.slice(1))||[],t=window.location.pathname.split("/").filter(Boolean),r={};e.forEach((o,s)=>{r[o]=t[s]}),b(f.params,r)||(f.params=r,L())},setFromPatternValues(n,e){let t={};n.forEach((r,o)=>{t[r]=e[o]}),b(f.params,t)||(f.params=t,L())},setQuery(n){let e={...f.query,...n};b(f.query,e)||(f.query=e,k(),L())},replaceQuery(n){b(f.query,n)||(f.query={...n},k(),L())},removeQuery(n){if(!(n in f.query))return;let e={...f.query};delete e[n],f.query=e,k(),L()},clearQuery(){Object.keys(f.query).length!==0&&(f.query={},k(),L())},setQueryFromURL(n){let e=Xe(n);b(f.query,e)||(f.query=e,L())},subscribe(n){return _.add(n),()=>_.delete(n)}}}};typeof window<"u"&&window.addEventListener("popstate",()=>{U.getState().setQueryFromURL(window.location.search)});import Re from"dompurify";import{createStore as Ze}from"zustand/vanilla";import et from"dompurify";var w=Ze(n=>({params:{},query:{},setParams:e=>n(()=>({params:Le(e)})),setQuery:e=>n(()=>({query:Le(e)}))}));function Le(n){let e={};for(let t in n)e[t]=et.sanitize(n[t]);return e}var j=class{routes=[];expectedParams;apiFetcher;constructor(e,t,r){this.routes=e,this.expectedParams=new Set(t),this.apiFetcher=r,window.addEventListener("popstate",this.handlePopState.bind(this)),this.handlePopState()}handlePopState(){let e=window.location.pathname,t=window.location.search,r=this.parseQueryParams(t);if(e.startsWith("/api")&&this.apiFetcher){let i=e.replace("/api/","").split("/")[0],a=Object.fromEntries(new URLSearchParams(t));this.apiFetcher(i,a).then(l=>console.log("API response:",l)).catch(l=>console.error("API error:",l));return}let o=this.findMatchingRoute(e,this.routes);if(o){if(o.routeto){this.navigate(o.routeto);return}let s=this.filterAndSanitizeParams(o.params);w.getState().setParams(s),w.getState().setQuery(r);let i=document.createElement("div");if(o.element?.(i,s,r),o.children){let a=e.slice(o.path.length),l=i.querySelector("#child");l&&this.renderChildren(o.children,a,l,s,r)}}else{let s=this.findMatchingRoute("*",this.routes);if(s){let i=this.filterAndSanitizeParams(s.params);w.getState().setParams(i),w.getState().setQuery(r);let a=document.createElement("div");s.element?.(a,i,r)}}}renderChildren(e,t,r,o,s){if(!e||e.length===0){let a=r.querySelector("#child");a&&a.remove();return}let i=this.findMatchingRoute(t,e);if(i){let a=document.createElement("div");a.id="child";let l={...o,...i.params},u=this.filterAndSanitizeParams(l);if(w.getState().setParams(u),w.getState().setQuery(s),i.element?.(a,u,s),r.appendChild(a),i.children){let c=t.slice(i.path.length);this.renderChildren(i.children,c,a,u,s)}}}parseQueryParams(e){let t={},r=new URLSearchParams(e);for(let[o,s]of r.entries())this.expectedParams.has(o)&&(t[o]=Re.sanitize(s));return t}findMatchingRoute(e,t,r={}){for(let o of t){let s=o.path;if(s==="*")return o;{let a=[],l=s.replace(/:[^\s/]+/g,d=>(a.push(d.substring(1)),"([^\\s/]+)")),u=new RegExp(`^${l}(?:/|$)`),c=e.match(u);if(c){let d={...r};if(a.forEach((h,p)=>{d[h]=c[p+1]??""}),o.children){let h=e.slice(c[0].length),p=this.findMatchingRoute(h,o.children,d);if(p)return p}return{...o,params:d}}}}}filterAndSanitizeParams(e){if(!e)return{};let t={};for(let r in e)this.expectedParams.has(r)&&(t[r]=Re.sanitize(e[r]??""));return t}navigate(e){history.pushState(null,"",e),this.handlePopState()}addRoute(e){this.routes.push(e)}};var tt=()=>({name:"ts-filebased-router",async buildStart(){let n=await import("fs/promises"),e=await import("path"),t=await import("./esm-KRNKVVL7.js"),r=e.resolve("src/pages"),o=e.resolve("src/gen"),s=e.resolve("src/routes"),i=e.join(o,"tsrouter.gen.ts"),a=e.join(s,"__root.ts"),l=process.env.NODE_ENV!=="production",u=async y=>n.mkdir(y,{recursive:!0}).catch(()=>{}),c=y=>y.charAt(0).toUpperCase()+y.slice(1),d=y=>{let m="/"+e.relative(r,y).replace(/\\/g,"/");return m=m.replace(/\.ts$/,"").replace(/\/index$/,"")||"/",m.replace(/\[\.\.\.(.+?)\]/g,"*").replace(/\[(.+?)\]/g,":$1")},h=y=>y.replace(/^\//,"").split("/").map(m=>m.startsWith(":")?c(m.slice(1)):m.replace(/\b\w/g,g=>g.toUpperCase()).replace(/[-_]/g,"")).filter(Boolean).join("")||"Index",p=async y=>{let m=await n.readdir(y,{withFileTypes:!0}),g=[];for(let S of m){let R=e.join(y,S.name);S.isDirectory()?g.push(...await p(R)):S.isFile()&&S.name.endsWith(".ts")&&g.push({file:R,route:d(R),name:h(d(R))})}return g},P=async()=>{let y=await p(r),m=y.find(T=>T.route==="/notfound"),g=y.filter(T=>T.route!=="/notfound");for(let T of y)if(!(await n.readFile(T.file,"utf-8")).trim()){let x=T.route.includes(":"),Q=x?T.route.split("/").filter($=>$.startsWith(":")).map($=>$.slice(1)):[],be=x?`const { ${Q.join(", ")} } = useTSExtractParams("${T.route}");`:"";await n.writeFile(T.file,`import { html, useTSElements, useTSMetaData${x?", useTSExtractParams":""} } from "@devwaren/vanilla-ts";
2
2
 
3
3
  export default function ${T.name}(DOM: HTMLElement) {
4
4
  useTSMetaData({
@@ -16,9 +16,9 @@ export default function ${T.name}(DOM: HTMLElement) {
16
16
  \`);
17
17
  };
18
18
  `,"utf-8")}let S=m?`export const NotFound = async (DOM: HTMLElement) => {
19
- const mod = await import("../pages/${e.relative(r,m.file).replace(/\\/g,"/").replace(/\\.ts$/,"")}") as Module;
19
+ const mod = await import("../pages/${e.relative(r,m.file).replace(/\\/g,"/").replace(/\\.ts$/,"")}") as unknown as Module;
20
20
  return mod.default(DOM);
21
- };`:"export const NotFound = (DOM: HTMLElement) =>\n useTSElements(DOM, html`<h1>404 - Page Not Found</h1>`);",R=g.map(T=>{let W="../pages/"+e.relative(r,T.file).replace(/\\/g,"/").replace(/\.ts$/,"");return`{ path: "${T.route}", name: "${T.name}", component: () => import("${W}") as Promise<Module> }`}).join(`,
21
+ };`:"export const NotFound = (DOM: HTMLElement) =>\n useTSElements(DOM, html`<h1>404 - Page Not Found</h1>`);",R=g.map(T=>{let W="../pages/"+e.relative(r,T.file).replace(/\\/g,"/").replace(/\.ts$/,"");return`{ path: "${T.route}", name: "${T.name}", component: () => import("${W}") as unknown as Module }`}).join(`,
22
22
  `),Me=`// AUTO-GENERATED ROUTER
23
23
  import { useTSElements, useTSParams, html } from "@devwaren/vanilla-ts";
24
24
 
@@ -102,9 +102,7 @@ export async function createRouter(DOM: HTMLElement) {
102
102
  useTSParams.getState().setFromPatternValues(Object.keys(params), Object.values(params));
103
103
 
104
104
  const query: Record<string, string> = {};
105
- url.searchParams.forEach((v, k) => {
106
- query[k] = v; // \u2705 no return
107
- });
105
+ url.searchParams.forEach((v, k) => { query[k] = v; });
108
106
  useTSParams.getState().setQuery(query);
109
107
 
110
108
  currentComponentUnmount?.();
@@ -125,4 +123,4 @@ export const Router = async (DOM: HTMLElement) => {
125
123
  await initializeRoute(router);
126
124
  return router;
127
125
  };
128
- `;await u(r),await P(),l&&t.watch(r,{ignoreInitial:!0}).on("all",async(m,g)=>{g.endsWith(".ts")&&(await P(),console.log("\u267B\uFE0F TS Router regenerated"))}),console.log("\u{1F7E2} TS Filebased Router initialized")}});var nt=async n=>{typeof window>"u"||typeof document>"u"||(await n.navigate(window.location.pathname+window.location.search,!1),window.addEventListener("popstate",()=>{n.navigate(window.location.pathname+window.location.search,!1)}),document.addEventListener("click",e=>{let t=e;if(t.defaultPrevented||t.button!==0||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey)return;let r=t.target.closest("a");if(!r)return;let o=new URL(r.href);o.origin===window.location.origin&&(t.preventDefault(),n.navigate(o.pathname+o.search))}))};export{tt as TSFilebasedRouter,j as TSRouter,$e as createClientFunc,ve as createSignal,Fe as createTSServerFunc,K as html,nt as initializeRoute,he as loadPyFiles,De as mapper,pe as renderChildRoutes,F as useAnchor,ie as useAnchorSingle,oe as useInitialDOM,ue as useTSAuth,le as useTSCollection,D as useTSComponent,I as useTSElementEach,ne as useTSElements,G as useTSEvent,X as useTSEventAll,Y as useTSExtractParams,ge as useTSLazy,ce as useTSMetaData,de as useTSNavigate,Te as useTSNoReload,me as useTSOutlet,H as useTSParams,V as useTSPurifier,U as useTSQuery,we as useTSReactor,ye as useTSSSRHydration,M as useTSSelect,fe as useTSloadBrython};
126
+ `;await u(r),await P(),l&&t.watch(r,{ignoreInitial:!0}).on("all",async(m,g)=>{g.endsWith(".ts")&&(await P(),console.log("\u267B\uFE0F TS Router regenerated"))}),console.log("\u{1F7E2} TS Filebased Router initialized")}});var nt=async n=>{typeof window>"u"||typeof document>"u"||(await n.navigate(window.location.pathname+window.location.search,!1),window.addEventListener("popstate",()=>{n.navigate(window.location.pathname+window.location.search,!1)}),document.addEventListener("click",e=>{let t=e;if(t.defaultPrevented||t.button!==0||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey)return;let r=t.target.closest("a");if(!r)return;let o=new URL(r.href);o.origin===window.location.origin&&(t.preventDefault(),n.navigate(o.pathname+o.search))}))};export{tt as TSFilebasedRouter,j as TSRouter,ke as createClientFunc,ve as createSignal,Fe as createTSServerFunc,K as html,nt as initializeRoute,he as loadPyFiles,De as mapper,pe as renderChildRoutes,F as useAnchor,ie as useAnchorSingle,oe as useInitialDOM,ue as useTSAuth,le as useTSCollection,D as useTSComponent,I as useTSElementEach,ne as useTSElements,G as useTSEvent,X as useTSEventAll,Y as useTSExtractParams,ge as useTSLazy,ce as useTSMetaData,de as useTSNavigate,Te as useTSNoReload,me as useTSOutlet,H as useTSParams,V as useTSPurifier,U as useTSQuery,we as useTSReactor,ye as useTSSSRHydration,M as useTSSelect,fe as useTSloadBrython};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devwaren/vanilla-ts",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "description": "Vanilla Framework-less TypeScript hooks for SPA development.",
5
5
  "author": "Waren Arapoc Gador",
6
6
  "license": "MIT",