diff --git a/dist/assets/index-B240dcNf.css b/dist/assets/index-B240dcNf.css deleted file mode 100644 index 560bb9e..0000000 --- a/dist/assets/index-B240dcNf.css +++ /dev/null @@ -1 +0,0 @@ -layout.post-grid{margin-top:1rem}post-tile{display:block;transition:.3s all ease;position:relative;transition:all .3s ease;border-radius:10px;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none}@media (hover: hover){post-tile:hover{transform:scale(1.02);z-index:1;box-shadow:0 0 10px color-mix(in srgb,var(--background-color) 50%,transparent)}}post-tile.loading{transition:none}post-tile:active{transform:scale(.95)}post-tile div.video-detail,post-tile div.gif-detail{position:absolute;background-color:var(--background-color-lighter);color:var(--primary-color);bottom:.3rem;right:.3rem;padding:.2em .4em;height:1rem;border-radius:4px;font-size:12px;display:flex;align-items:center;gap:.2rem;z-index:2}post-tile div.video-detail ion-icon,post-tile div.gif-detail ion-icon{font-size:1.4rem}post-tile div.video-detail ion-icon[name=images-outline],post-tile div.gif-detail ion-icon[name=images-outline]{padding:.1rem;font-size:1rem}post-tile div.video-detail span.duration,post-tile div.gif-detail span.duration{text-transform:uppercase;z-index:2}post-tile img{height:100%;width:100%;vertical-align:top;background-color:var(--background-color)}post-tile video{height:100%;width:100%;object-fit:cover;position:absolute;z-index:1}searchbar{display:flex;align-items:center;flex-direction:column;width:100%;z-index:200;position:fixed;height:100%}searchbar div.input-container{margin-top:.4rem;background-color:color-mix(in srgb,var(--background-color-light) 100%,transparent);border-radius:.4rem;font-size:1rem;width:500px;padding:.4rem;max-width:calc(100% - 2rem);box-sizing:border-box;z-index:201;display:flex;align-items:center;border:1px solid var(--secondary-color-dark)}searchbar div.input-container:focus-within{outline:none}searchbar div.input-container tag-input{display:flex;gap:.4rem;width:100%;overflow:hidden;padding-inline:.4rem;box-sizing:border-box;cursor:text}searchbar div.input-container tag-input tag{display:inline-block;padding:.2rem .4rem;background-color:var(--secondary-color-dark);color:var(--secondary-color);border-radius:.4rem;cursor:pointer}searchbar div.input-container ion-icon{font-size:20px;color:var(--secondary-color-dark);cursor:pointer}searchbar div.input-container ion-icon:hover{color:var(--secondary-color)}searchbar div.selection-list-container{overflow:hidden;border-radius:.4rem;background-color:var(--background-color);z-index:201;max-width:calc(100% - 2rem);width:500px}searchbar div.selection-list-container selection-list{display:block;max-height:40vh;overflow-y:scroll;overflow-x:hidden;position:relative}searchbar div.selection-list-container selection-list::-webkit-scrollbar{width:4px}searchbar div.selection-list-container selection-list selection{display:flex;justify-content:space-between;align-items:center;padding:.4rem 1rem;cursor:pointer}searchbar div.selection-list-container selection-list selection:hover{background-color:color-mix(in srgb,var(--background-color-lighter) 50%,transparent)}searchbar div.selection-list-container selection-list selection.active{background-color:var(--background-color-lighter)}searchbar div.selection-list-container selection-list selection .tag-category{padding:.1rem .4rem;border-radius:.4rem;font-size:.9rem;background-color:var(--secondary-color-dark);color:var(--secondary-color)}searchbar div.filter{background-color:var(--background-color);opacity:.5;position:fixed;top:0;height:100%;width:100%;z-index:199}.input-wrapper{color:var(--primary-color);border:1px solid var(--secondary-color);border-radius:.4rem;position:relative;box-sizing:border-box;line-height:1em;font-size:14px;padding:4px 8px;display:inline-block;max-width:100%;text-overflow:ellipsis}.input-wrapper span.sizer{font-family:inherit;white-space:pre;height:1em;display:inline-block;font-size:inherit;line-height:inherit;box-sizing:border-box;position:relative;opacity:0;min-width:2px;-webkit-user-select:none;user-select:none;vertical-align:top}.input-wrapper input{height:100%;text-overflow:ellipsis;font-family:inherit;background:none;color:inherit;top:0;left:0;font-size:inherit;line-height:inherit;padding:inherit;position:absolute;box-sizing:border-box;width:100%;border:none;outline:none}button.icon{display:flex;justify-content:center;align-items:center;gap:.4rem;padding:.4rem;background-color:transparent}button.icon ion-icon{font-size:1.5rem}button.icon:hover{background-color:var(--background-color-light)}button.icon.vertical{flex-direction:column}#post{padding:0;padding-top:var(--nav-height)}#post section{background-color:#2f2f45;border-radius:20px;padding:20px}#post div.viewer{height:calc(100vh - 2rem - var(--nav-height));display:flex;justify-content:center;align-items:center;background-color:#000;border-radius:20px;overflow:hidden;width:calc(100vw - 300px - 4rem);margin:1rem}@media (max-width: 800px){#post div.viewer{width:100%;height:calc(100vh - var(--nav-height));border-radius:0;margin:0}}#post div.viewer img{max-width:100%;max-height:100%}#post div.viewer video{max-width:100%;max-height:100%;-webkit-user-drag:none;transition:all .3s ease}#post div.content{width:calc(100vw - 300px - 2rem);display:flex;flex-direction:column;padding:1rem;box-sizing:border-box}@media (max-width: 800px){#post div.content{width:100%}}#post div.content::-webkit-scrollbar{background-color:#000;width:4px}#post div.content::-webkit-scrollbar-thumb{background-color:#aeaeec;border-radius:2px}#post div.content>h3{padding-left:1rem;margin-block:1rem}#post div.content section.commentary *{text-wrap:wrap;word-break:break-word}#post div.sidebar{--padding: 1rem;position:fixed;top:calc(var(--nav-height) + var(--padding));right:var(--padding);display:flex;flex-direction:column;gap:.4rem;width:300px;overflow:scroll;overflow-x:hidden;height:calc(100vh - 2rem - var(--nav-height));border-radius:20px}@media (max-width: 800px){#post div.sidebar{position:static;width:100%;overflow:visible;height:100%;padding:1rem;box-sizing:border-box}}#post div.sidebar::-webkit-scrollbar{background-color:#000;width:0px}#post div.sidebar::-webkit-scrollbar-thumb{background-color:#aeaeec}#post div.sidebar h3{padding-left:1rem;margin-block:.6rem}#post div.sidebar .post-info{background-color:#2f2f45;border-radius:20px;padding:20px;display:flex;flex-direction:column;gap:.4rem}#post div.sidebar .post-info .buttons{display:grid;grid-template-columns:1fr 1fr 1fr;gap:1rem;margin-top:1rem}#post div.sidebar div.property{display:flex;gap:.6rem;align-items:center}#post div.sidebar div.property div.property-values{display:flex;gap:.4rem}#post div.sidebar div.property div.property-values span.property-value{background-color:var(--secondary-color-dark);color:var(--secondary-color);padding:2px 4px;border-radius:4px}#post div.sidebar div.inline{display:flex;gap:1rem}#post div.sidebar div.post-tags{display:flex;flex-direction:column;gap:.2rem}#post div.sidebar div.post-tags div.tag{align-items:center}#post div.sidebar div.post-tags div.tag a.tag-name{word-break:break-word;color:#d1d1ee;text-decoration:none}#post div.sidebar div.post-tags div.tag span.tag-post-count{background-color:var(--secondary-color-dark);color:var(--secondary-color);padding:0 4px;border-radius:4px;font-size:12px;margin-left:.4rem}page#root layout *{transition:all .3s ease}page#root .loader{text-align:center;padding-block:2rem}:root{--background-color: #1e1e2c;--background-color-lighter: #3b3b66;--background-color-light: #24243b;--primary-color: #d1d1ee;--primary-color-dark: #9696b3;--primary-color-darker: #72728d;--secondary-color: #aeaeec;--secondary-color-dark: #424268;--nav-height: 50px}html{overflow-x:hidden;font-size:14px}html ::-webkit-scrollbar{background-color:var(--background-color);width:8px}html ::-webkit-scrollbar-thumb{background-color:#aeaeec;border-radius:2px}body{overflow-x:hidden;background-color:var(--background-color);color:var(--primary-color);margin:0;font-family:Microsoft Yahei}nav{display:flex;width:100%;height:var(--nav-height);position:fixed;top:0;z-index:100;background-color:color-mix(in srgb,var(--background-color) 70%,transparent);justify-content:space-between;align-items:center;padding-inline:1rem;box-sizing:border-box;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}nav a.title{display:flex;align-items:center;gap:.4rem;text-decoration:none}nav a.title .booru-name{color:var(--secondary-color);margin:0}nav a.title .app{display:flex;align-items:center;border-radius:.4rem;margin:0;gap:.4rem}nav a.title .app .version{color:var(--background-color);background-color:var(--secondary-color);padding:.2em .4em;border-radius:.4rem;font-size:.8rem;font-weight:700}nav a.title .app .app-name{display:none;font-size:1rem;color:var(--secondary-color)}nav div.searchbar{padding:.4rem 10%;max-width:500px;background-color:color-mix(in srgb,var(--background-color-light) 30%,transparent);border:1px solid var(--primary-color-darker);border-radius:.4rem;color:var(--primary-color-dark);transition:.3s all ease;cursor:pointer}nav div.searchbar:hover{color:var(--primary-color)}nav div.buttons{display:flex;align-items:center;gap:1rem}nav div.buttons ion-icon{transition:all .3s ease;border-radius:1rem;padding:.4rem}nav div.buttons ion-icon:hover{background-color:color-mix(in srgb,var(--background-color-lighter) 50%,transparent)}nav div.buttons ion-icon.search{display:none}@media (max-width: 800px){nav div.searchbar{display:none}nav div.buttons ion-icon.search{display:inline-block}}router{display:block;position:relative}router route{display:block;position:relative;padding-inline:10px;padding-top:var(--nav-height)}button{background-color:var(--secondary-color-dark);color:var(--secondary-color);padding:.8rem 1.2rem;border-radius:1rem;border:none;cursor:pointer}ion-icon{font-size:24px;color:var(--primary-color);cursor:pointer}ion-icon:hover{color:var(--secondary-color)} diff --git a/dist/assets/index-C21fHnwq.js b/dist/assets/index-C21fHnwq.js deleted file mode 100644 index 260062e..0000000 --- a/dist/assets/index-C21fHnwq.js +++ /dev/null @@ -1 +0,0 @@ -var Lt=Object.defineProperty;var ft=r=>{throw TypeError(r)};var Pt=(r,t,e)=>t in r?Lt(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var u=(r,t,e)=>Pt(r,typeof t!="symbol"?t+"":t,e),pt=(r,t,e)=>t.has(r)||ft("Cannot "+e);var x=(r,t,e)=>(pt(r,t,"read from private field"),e?e.call(r):t.get(r)),B=(r,t,e)=>t.has(r)?ft("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(r):t.set(r,e),K=(r,t,e,s)=>(pt(r,t,"write to private field"),s?s.call(r,e):t.set(r,e),e);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))s(i);new MutationObserver(i=>{for(const n of i)if(n.type==="childList")for(const a of n.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&s(a)}).observe(document,{childList:!0,subtree:!0});function e(i){const n={};return i.integrity&&(n.integrity=i.integrity),i.referrerPolicy&&(n.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?n.credentials="include":i.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function s(i){if(i.ep)return;i.ep=!0;const n=e(i);fetch(i.href,n)}})();class U{constructor(){u(this,"__hidden",!1);u(this,"domEvents",{});u(this,"parent");u(this,"events",new et)}on(t,e,s){t=T.orArrayResolve(t);for(const i of t){this.domEvents[i]||(this.domEvents[i]=new Map);const n=a=>{e(a,this)};this.domEvents[i].set(e,n),this.events.on(i,e),this.dom.addEventListener(i,n,s)}return this}off(t,e,s){var n;const i=(n=this.domEvents[t])==null?void 0:n.get(e);return i&&this.dom.removeEventListener(t,i,s),this.events.off(t,e),this}once(t,e,s){const i=n=>{this.dom.removeEventListener(t,i,s),e(n,this)};return this.dom.addEventListener(t,i,s),this.events.once(t,e),this}hide(t,e=!0){return T.fluent(this,arguments,()=>this.__hidden,()=>{var s;if(t!==void 0)return t instanceof I?(this.__hidden=t.value,t.use(this,"hide")):this.__hidden=t,e&&((s=this.parent)==null||s.children.render()),this})}remove(){var t;return(t=this.parent)==null||t.children.remove(this).render(),this}replace(t){var e;return(e=this.parent)==null||e.children.replace(this,t).render(),this}contains(t){return t?t instanceof U?this.dom.contains(t.dom):t instanceof EventTarget?this.dom.contains(T(t).dom):this.dom.contains(t):!1}self(t){return t(this),this}inDOM(){return document.contains(this.dom)}isElement(){return this instanceof M}get element(){return this instanceof M?this:null}}class M extends U{constructor(e,s){super();u(this,"dom");u(this,"static_classes",new Set);this.dom=this.createDom(e,s),this.dom.$=this,this.setOptions(s)}createDom(e,s){return s!=null&&s.dom?s.dom:e==="svg"?document.createElementNS("http://www.w3.org/2000/svg","svg"):document.createElement((s==null?void 0:s.tagname)??e)}setOptions(e){return this.id(e==null?void 0:e.id),e&&e.class&&this.class(...e.class),this}id(e){return $.fluent(this,arguments,()=>this.dom.id,()=>$.set(this.dom,"id",e))}class(...e){return $.fluent(this,arguments,()=>this.dom.classList,()=>{this.dom.classList.forEach(s=>this.static_classes.has(s)??this.dom.classList.remove(s)),this.dom.classList.add(...e.detype())})}addClass(...e){return $.fluent(this,arguments,()=>this,()=>{this.dom.classList.add(...e.detype())})}removeClass(...e){return $.fluent(this,arguments,()=>this,()=>{this.dom.classList.remove(...e.detype())})}staticClass(...e){return $.fluent(this,arguments,()=>this.static_classes,()=>{this.removeClass(...this.static_classes),this.static_classes.clear(),this.addStaticClass(...e)})}addStaticClass(...e){return $.fluent(this,arguments,()=>this,()=>{e.detype().forEach(s=>this.static_classes.add(s)),this.addClass(...e)})}removeStaticClass(...e){return $.fluent(this,arguments,()=>this,()=>{e.detype().forEach(s=>this.static_classes.delete(s)),this.removeClass(...e)})}css(e){return $.fluent(this,arguments,()=>this.dom.style,()=>{Object.assign(this.dom.style,e)})}attribute(e,s){return arguments.length?arguments.length===1?e===void 0?null:this.dom.getAttribute(e):arguments.length===2?e?(s===null?this.dom.removeAttribute(e):s!==void 0&&this.dom.setAttribute(e,`${s}`),this):this:this:null}tabIndex(e){return $.fluent(this,arguments,()=>this.dom.tabIndex,()=>$.set(this.dom,"tabIndex",e))}focus(){return this.dom.focus(),this}blur(){return this.dom.blur(),this}animate(e,s,i){const n=this.dom.animate(e,s);return i&&(n.onfinish=()=>i(n)),n}getAnimations(e){return this.dom.getAnimations(e)}get dataset(){return this.dom.dataset}domRect(e){const s=this.dom.getBoundingClientRect();if(!e)return s;const i=e instanceof M?e.dom.getBoundingClientRect():e;return{...s,top:s.top-i.top,left:s.left-i.left,right:s.right-i.left,bottom:s.bottom-i.top,x:s.x-i.x,y:s.y-i.y}}}class J extends U{constructor(e){super();u(this,"dom");this.dom=e,this.dom.$=this}domRect(e){const s={bottom:innerHeight,height:innerHeight,left:0,right:innerWidth,top:0,width:innerWidth,x:0,y:0};if(!e)return s;const i=e instanceof M?e.dom.getBoundingClientRect():e;return{...s,top:s.top-i.top,left:s.left-i.left,right:s.right-i.left,bottom:s.bottom-i.top,x:s.x-i.x,y:s.y-i.y}}static from(e){return e.$ instanceof J?e.$:new J(e)}}const Mt="modulepreload",At=function(r){return"/"+r},gt={},Ct=function(t,e,s){let i=Promise.resolve();if(e&&e.length>0){document.getElementsByTagName("link");const a=document.querySelector("meta[property=csp-nonce]"),o=(a==null?void 0:a.nonce)||(a==null?void 0:a.getAttribute("nonce"));i=Promise.allSettled(e.map(c=>{if(c=At(c),c in gt)return;gt[c]=!0;const h=c.endsWith(".css"),d=h?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${c}"]${d}`))return;const m=document.createElement("link");if(m.rel=h?"stylesheet":Mt,h||(m.as="script"),m.crossOrigin="",m.href=c,o&&m.setAttribute("nonce",o),document.head.appendChild(m),h)return new Promise((w,l)=>{m.addEventListener("load",w),m.addEventListener("error",()=>l(new Error(`Unable to preload CSS for ${c}`)))})}))}function n(a){const o=new Event("vite:preloadError",{cancelable:!0});if(o.payload=a,window.dispatchEvent(o),!o.defaultPrevented)throw a}return i.then(a=>{for(const o of a||[])o.status==="rejected"&&n(o.reason);return t().catch(n)})};class Rt{constructor(t){u(this,"$container");u(this,"childList",new Set);this.$container=t}add(t,e=-1){if(e===-1||this.childList.size-1===e)this.childList.add(t);else{const s=[...this.childList];s.splice(e,0,t),this.childList.clear(),s.forEach(i=>this.childList.add(i))}t.parent=this.$container}remove(t){return this.childList.has(t)?(this.childList.delete(t),t.parent=void 0,this):this}removeAll(t=!0){this.childList.forEach(e=>this.remove(e)),t&&this.render()}replace(t,e){const s=this.array;return s.splice(s.indexOf(t),1,e),t.remove(),this.childList.clear(),s.forEach(i=>this.childList.add(i)),e.parent=this.$container,this}render(){const[t,e]=[this.array.map(i=>i.dom),Array.from(this.dom.childNodes)],s=[];for(;e.length||t.length;){const[i,n]=[e.at(0),t.at(0)];n?i?n!==i?(n.$.__hidden||(this.dom.insertBefore(n,i),s.push(n)),t.shift()):(n.$.__hidden&&this.dom.removeChild(n),t.shift(),e.shift()):(n.$.__hidden||this.dom.append(n),t.shift()):(i&&!s.includes(i)&&i.remove(),e.shift())}}indexOf(t){return this.array.indexOf(t)}get array(){return[...this.childList.values()]}get dom(){return this.$container.dom}}class I{constructor(t,e){u(this,"_value");u(this,"attributes",new Map);u(this,"linkStates",new Set);u(this,"options",{});this.set(t),e&&(this.options=e)}set(t){this._value=t,t instanceof I&&t.linkStates.add(this),this.update(),this.linkStates.forEach(e=>e.update())}update(){for(const[t,e]of this.attributes.entries())for(const s of e)t[s]instanceof Function?this.options.format?t[s](this.options.format(this.value)):t[s](this.value):s in t&&(t[s]=this.value)}toString(){return this.options.format?this.options.format(this.value):this.value instanceof Object?JSON.stringify(this.toJSON()):`${this.value}`}use(t,e){const s=this.attributes.get(t);s?s.add(e):this.attributes.set(t,new Set().add(e))}toJSON(){return this.value instanceof I?this.value.toJSON():this.value instanceof Object?I.toJSON(this.value):this.toString()}static toJSON(t){const e={};for(let[s,i]of Object.entries(t))i instanceof I?i=i.toJSON():i instanceof Object&&I.toJSON(i),Object.assign(e,{[s]:i});return e}get value(){return this._value instanceof I?this._value.value:this._value}}class q extends U{constructor(e){super();u(this,"dom");this.dom=new Text(e),this.dom.$=this}content(e){return $.fluent(this,arguments,()=>this.dom.textContent,()=>$.set(this.dom,"textContent",e))}}class Q extends M{constructor(t,e){super(t,e)}autocapitalize(t){return $.fluent(this,arguments,()=>this.dom.autocapitalize,()=>$.set(this.dom,"autocapitalize",t))}innerText(t){return $.fluent(this,arguments,()=>this.dom.innerText,()=>$.set(this.dom,"innerText",t))}title(t){return $.fluent(this,arguments,()=>this.dom.title,()=>$.set(this.dom,"title",t))}dir(t){return $.fluent(this,arguments,()=>this.dom.dir,()=>$.set(this.dom,"dir",t))}translate(t){return $.fluent(this,arguments,()=>this.dom.translate,()=>$.set(this.dom,"translate",t))}popover(t){return $.fluent(this,arguments,()=>this.dom.popover,()=>$.set(this.dom,"popover",t))}spellcheck(t){return $.fluent(this,arguments,()=>this.dom.spellcheck,()=>$.set(this.dom,"spellcheck",t))}inert(t){return $.fluent(this,arguments,()=>this.dom.inert,()=>$.set(this.dom,"inert",t))}lang(t){return $.fluent(this,arguments,()=>this.dom.lang,()=>$.set(this.dom,"lang",t))}draggable(t){return $.fluent(this,arguments,()=>this.dom.draggable,()=>$.set(this.dom,"draggable",t))}hidden(t){return $.fluent(this,arguments,()=>this.dom.hidden,()=>$.set(this.dom,"hidden",t))}click(){return this.dom.click(),this}attachInternals(){return this.dom.attachInternals()}hidePopover(){return this.dom.hidePopover(),this}showPopover(){return this.dom.showPopover(),this}togglePopover(){return this.dom.togglePopover(),this}get accessKeyLabel(){return this.dom.accessKeyLabel}get offsetHeight(){return this.dom.offsetHeight}get offsetLeft(){return this.dom.offsetLeft}get offsetParent(){return $(this.dom.offsetParent)}get offsetTop(){return this.dom.offsetTop}get offsetWidth(){return this.dom.offsetWidth}}class f extends Q{constructor(e,s){super(e,s);u(this,"children",new Rt(this));u(this,"__position_cursor",0)}content(e){return $.fluent(this,arguments,()=>this,()=>{this.children.removeAll(!1),this.insert(e)})}insert(e,s=-1){return $.fluent(this,arguments,()=>this,async()=>{if(e instanceof Function){let i=e(this);i instanceof Promise?e=await i:e=i}else e instanceof Promise&&(e=await e);e=$.orArrayResolve(e),this.__position_cursor=s<0?this.children.array.length+s:s;for(const i of e)if(i!=null){if(i instanceof Array)this.insert(i,this.__position_cursor);else if(typeof i=="string")this.children.add(new q(i),s);else if(i instanceof I){const n=new q(i.toString());i.use(n,"content"),this.children.add(n,s)}else if(i instanceof Promise){const n=(await Ct(async()=>{const{$Async:o}=await Promise.resolve().then(()=>Ut);return{$Async:o}},void 0)).$Async,a=new n().await(i);this.children.add(a,s)}else this.children.add(i,s);this.__position_cursor+=1}this.children.render()})}clear(){return this.children.removeAll(),this}$(e){return $(this.dom.querySelector(e))}$all(e){return Array.from(this.dom.querySelectorAll(e)).map(s=>$(s))}get scrollHeight(){return this.dom.scrollHeight}get scrollWidth(){return this.dom.scrollWidth}scrollTop(e){return $.fluent(this,arguments,()=>this.dom.scrollTop,()=>$.set(this.dom,"scrollTop",e))}scrollLeft(e){return $.fluent(this,arguments,()=>this.dom.scrollLeft,()=>$.set(this.dom,"scrollLeft",e))}}class kt extends f{constructor(t){super("a",t),this.dom.addEventListener("click",e=>{$.anchorHandler&&this.href()&&(e.preventDefault(),$.anchorHandler(this,e))})}href(t){return $.fluent(this,arguments,()=>this.dom.href,()=>{t&&(this.dom.href=t)})}target(t){return $.fluent(this,arguments,()=>this.dom.target??void 0,()=>{t&&(this.dom.target=t)})}}class Nt extends M{constructor(t,e){super(t,e)}}var _;(r=>{function t(o,c,h,d){return c.length?(d(),o):h()}r.fluent=t;function e(o){return o instanceof Array?o:[o]}r.orArrayResolve=e;function s(o,c){return e(c).forEach(h=>{Object.getOwnPropertyNames(h.prototype).forEach(d=>{d!=="constructor"&&Object.defineProperty(o.prototype,d,Object.getOwnPropertyDescriptor(h.prototype,d)||Object.create(null))})}),o}r.mixin=s;function i(o,c,h){h!==void 0&&(o[c]=h)}r.set=i;function n(o){return new I(o)}r.state=n;function a(o){if(o.$)return o.$;if(o.nodeName.toLowerCase()==="body")return new f("body",{dom:o});if(o.nodeName.toLowerCase()==="#document")return J.from(o);if(o instanceof HTMLElement){const c=$.TagNameElementMap[o.tagName.toLowerCase()],h=c===f?new c(o.tagName,{dom:o}):new c({dom:o});if(h instanceof f)for(const d of Array.from(h.dom.childNodes))h.children.add($(d));return h}else if(o instanceof Text){const c=new q(o.textContent??"");return c.dom=o,c}else if(o instanceof SVGElement&&o.tagName.toLowerCase()==="svg")return new Nt("svg",{dom:o});throw`$NODE.FROM: NOT SUPPORT TARGET ELEMENT TYPE (${o.nodeName})`}r.from=a})(_||(_={}));class L{static create(...t){const e=class{};return Object.getOwnPropertyNames(L.prototype).forEach(s=>{s!=="constructor"&&t.includes(s)&&Object.defineProperty(e.prototype,s,Object.getOwnPropertyDescriptor(L.prototype,s)||Object.create(null))}),e}disabled(t){return $.fluent(this,arguments,()=>this.dom.disabled,()=>$.set(this.dom,"disabled",t))}checkValidity(){return this.dom.checkValidity()}reportValidity(){return this.dom.reportValidity()}formAction(t){return $.fluent(this,arguments,()=>this.dom.formAction,()=>$.set(this.dom,"formAction",t))}formEnctype(t){return $.fluent(this,arguments,()=>this.dom.formEnctype,()=>$.set(this.dom,"formEnctype",t))}formMethod(t){return $.fluent(this,arguments,()=>this.dom.formMethod,()=>$.set(this.dom,"formMethod",t))}formNoValidate(t){return $.fluent(this,arguments,()=>this.dom.formNoValidate,()=>$.set(this.dom,"formNoValidate",t))}formTarget(t){return $.fluent(this,arguments,()=>this.dom.formTarget,()=>$.set(this.dom,"formTarget",t))}autocomplete(t){return $.fluent(this,arguments,()=>this.dom.autocomplete,()=>$.set(this.dom,"autocomplete",t))}name(t){return $.fluent(this,arguments,()=>this.dom.name,()=>$.set(this.dom,"name",t))}maxLength(t){return $.fluent(this,arguments,()=>this.dom.maxLength,()=>$.set(this.dom,"maxLength",t))}minLength(t){return $.fluent(this,arguments,()=>this.dom.minLength,()=>$.set(this.dom,"minLength",t))}required(t){return $.fluent(this,arguments,()=>this.dom.required,()=>$.set(this.dom,"required",t))}label(t){return $.fluent(this,arguments,()=>this.dom.label,()=>$.set(this.dom,"label",t))}get form(){return this.dom.form?$(this.dom.form):null}get validationMessage(){return this.dom.validationMessage}get validity(){return this.dom.validity}get willValidate(){return this.dom.willValidate}}class ht extends f{constructor(t){super("button",t)}type(t){return $.fluent(this,arguments,()=>this.dom.type,()=>$.set(this.dom,"type",t))}}_.mixin(ht,L.create("disabled","checkValidity","formAction","formEnctype","formMethod","formNoValidate","formTarget","reportValidity"));class yt extends f{constructor(t){super("form",t)}action(t){return $.fluent(this,arguments,()=>this.dom.formAction,()=>$.set(this.dom,"formAction",t))}enctype(t){return $.fluent(this,arguments,()=>this.dom.formEnctype,()=>$.set(this.dom,"formEnctype",t))}method(t){return $.fluent(this,arguments,()=>this.dom.formMethod,()=>$.set(this.dom,"formMethod",t))}noValidate(t){return $.fluent(this,arguments,()=>this.dom.formNoValidate,()=>$.set(this.dom,"formNoValidate",t))}acceptCharset(t){return $.fluent(this,arguments,()=>this.dom.acceptCharset,()=>$.set(this.dom,"acceptCharset",t))}target(t){return $.fluent(this,arguments,()=>this.dom.formTarget,()=>$.set(this.dom,"formTarget",t))}requestSubmit(){return this.dom.requestSubmit(),this}reset(){return this.dom.reset(),this}submit(){return this.dom.submit(),this}get length(){return this.dom.length}get elements(){return Array.from(this.dom.elements).map(t=>$(t))}}_.mixin(yt,L.create("checkValidity","reportValidity","autocomplete"));class C extends Q{constructor(t){super("input",t)}value(t){return $.fluent(this,arguments,()=>this.type()==="number"?Number(this.dom.value):this.dom.value,()=>$.set(this.dom,"value",t,e=>{this.on("input",()=>{e.attributes.has(this.dom)!==!1&&(typeof e.value=="string"&&e.set(`${this.value()}`),typeof e.value=="number"&&e.set(Number(this.value())))})}))}type(t){return $.fluent(this,arguments,()=>this.dom.type,()=>$.set(this.dom,"type",t))}capture(t){return $.fluent(this,arguments,()=>this.dom.capture,()=>$.set(this.dom,"capture",t))}alt(t){return $.fluent(this,arguments,()=>this.dom.alt,()=>$.set(this.dom,"alt",t))}height(t){return $.fluent(this,arguments,()=>this.dom.height,()=>$.set(this.dom,"height",t))}width(t){return $.fluent(this,arguments,()=>this.dom.width,()=>$.set(this.dom,"width",t))}defaultValue(t){return $.fluent(this,arguments,()=>this.dom.defaultValue,()=>$.set(this.dom,"defaultValue",t))}dirName(t){return $.fluent(this,arguments,()=>this.dom.dirName,()=>$.set(this.dom,"dirName",t))}pattern(t){return $.fluent(this,arguments,()=>this.dom.pattern,()=>$.set(this.dom,"pattern",t))}placeholder(t){return $.fluent(this,arguments,()=>this.dom.placeholder,()=>$.set(this.dom,"placeholder",t))}readOnly(t){return $.fluent(this,arguments,()=>this.dom.readOnly,()=>$.set(this.dom,"readOnly",t))}selectionDirection(t){return $.fluent(this,arguments,()=>this.dom.selectionDirection,()=>$.set(this.dom,"selectionDirection",t))}selectionEnd(t){return $.fluent(this,arguments,()=>this.dom.selectionEnd,()=>$.set(this.dom,"selectionEnd",t))}selectionStart(t){return $.fluent(this,arguments,()=>this.dom.selectionStart,()=>$.set(this.dom,"selectionStart",t))}size(t){return $.fluent(this,arguments,()=>this.dom.size,()=>$.set(this.dom,"size",t))}src(t){return $.fluent(this,arguments,()=>this.dom.src,()=>$.set(this.dom,"src",t))}inputMode(t){return $.fluent(this,arguments,()=>this.dom.inputMode,()=>$.set(this.dom,"inputMode",t))}valueAsDate(t){return $.fluent(this,arguments,()=>this.dom.valueAsDate,()=>$.set(this.dom,"valueAsDate",t))}valueAsNumber(t){return $.fluent(this,arguments,()=>this.dom.valueAsNumber,()=>$.set(this.dom,"valueAsNumber",t))}webkitdirectory(t){return $.fluent(this,arguments,()=>this.dom.webkitdirectory,()=>$.set(this.dom,"webkitdirectory",t))}select(){return this.dom.select(),this}setCustomValidity(t){return this.dom.setCustomValidity(t),this}setRangeText(t,e,s,i){return typeof e=="number"&&typeof s=="number"&&this.dom.setRangeText(t,e,s,i),this.dom.setRangeText(t),this}setSelectionRange(t,e,s){return this.dom.setSelectionRange(t,e,s),this}showPicker(){return this.dom.showPicker(),this}get files(){return this.dom.files}get webkitEntries(){return this.dom.webkitEntries}get labels(){return Array.from(this.dom.labels??[]).map(t=>$(t))}}_.mixin(C,L.create("checkValidity","reportValidity","autocomplete","name","form","required","validationMessage","validity","willValidate","formAction","formEnctype","formMethod","formNoValidate","formTarget"));class Dt extends C{constructor(t){super(t),this.type("number")}static from(t){return $.mixin(C,this)}stepDown(){return this.dom.stepDown(),this}stepUp(){return this.dom.stepUp(),this}max(t){return $.fluent(this,arguments,()=>this.dom.max===""?null:parseInt(this.dom.min),()=>$.set(this.dom,"max",t==null?void 0:t.toString()))}min(t){return $.fluent(this,arguments,()=>this.dom.min===""?null:parseInt(this.dom.min),()=>$.set(this.dom,"min",t==null?void 0:t.toString()))}step(t){return $.fluent(this,arguments,()=>Number(this.dom.step),()=>$.set(this.dom,"step",t==null?void 0:t.toString()))}}class Ht extends C{constructor(t){super(t),this.type("radio")}static from(t){return $.mixin(C,this)}checked(t){return $.fluent(this,arguments,()=>this.dom.checked,()=>$.set(this.dom,"checked",t))}defaultChecked(t){return $.fluent(this,arguments,()=>this.dom.defaultChecked,()=>$.set(this.dom,"defaultChecked",t))}}class Vt extends C{constructor(t){super(t),this.type("file")}static from(t){return $.mixin(C,this)}multiple(t){return $.fluent(this,arguments,()=>this.dom.multiple,()=>$.set(this.dom,"multiple",t))}accept(...t){return $.fluent(this,arguments,()=>this.dom.accept.split(","),()=>this.dom.accept=t.toString())}}_.mixin(C,[Dt,Ht,Vt]);class vt extends f{constructor(t){super("label",t)}for(t){return $.fluent(this,arguments,()=>this.dom.htmlFor,()=>{$.set(this.dom,"htmlFor",t)})}get control(){return this.dom.control}}_.mixin(vt,L.create("form"));class jt extends Q{constructor(t){super("img",t)}async load(t){return new Promise(e=>{const s=this.once("load",()=>{e(s)});typeof t=="string"?s.src(t):t.then(i=>s.src(i))})}static resize(t,e){return new Promise(s=>{const i=new Image;if(i.addEventListener("load",()=>{const n=document.createElement("canvas"),a=n.getContext("2d");if(!a)throw"$Image.resize: context undefined";const o=i.width/i.height,[c,h,d]=[o>1,o<1,o===1],m=e instanceof Array?e[0]:h?e:e*o,w=e instanceof Array?e[1]:c?e:e/o;n.height=w,n.width=m,a.drawImage(i,0,0,m,w),s(n.toDataURL())},{once:!0}),t instanceof File){const n=new FileReader;n.addEventListener("load",()=>i.src=n.result),n.readAsDataURL(t)}else i.src=t})}alt(t){return $.fluent(this,arguments,()=>this.dom.alt,()=>$.set(this.dom,"alt",t))}crossOrigin(t){return $.fluent(this,arguments,()=>this.dom.crossOrigin,()=>$.set(this.dom,"crossOrigin",t))}decoding(t){return $.fluent(this,arguments,()=>this.dom.decoding,()=>$.set(this.dom,"decoding",t))}height(t){return $.fluent(this,arguments,()=>this.dom.height,()=>$.set(this.dom,"height",t))}isMap(t){return $.fluent(this,arguments,()=>this.dom.isMap,()=>$.set(this.dom,"isMap",t))}loading(t){return $.fluent(this,arguments,()=>this.dom.loading,()=>$.set(this.dom,"loading",t))}referrerPolicy(t){return $.fluent(this,arguments,()=>this.dom.referrerPolicy,()=>$.set(this.dom,"referrerPolicy",t))}sizes(t){return $.fluent(this,arguments,()=>this.dom.sizes,()=>$.set(this.dom,"sizes",t))}src(t){return $.fluent(this,arguments,()=>this.dom.src,()=>$.set(this.dom,"src",t))}srcset(t){return $.fluent(this,arguments,()=>this.dom.srcset,()=>$.set(this.dom,"srcset",t))}useMap(t){return $.fluent(this,arguments,()=>this.dom.useMap,()=>$.set(this.dom,"useMap",t))}width(t){return $.fluent(this,arguments,()=>this.dom.width,()=>$.set(this.dom,"width",t))}decode(){return this.dom.decode()}get complete(){return this.dom.complete}get currentSrc(){return this.dom.currentSrc}get naturalHeight(){return this.dom.naturalHeight}get naturalWidth(){return this.dom.naturalWidth}get x(){return this.dom.x}get y(){return this.dom.y}}class Wt extends f{constructor(t){super("canvas",t)}height(t){return $.fluent(this,arguments,()=>this.dom.height,()=>{$.set(this.dom,"height",t)})}width(t){return $.fluent(this,arguments,()=>this.dom.width,()=>{$.set(this.dom,"width",t)})}captureStream(t){return this.dom.captureStream(t)}getContext(t,e){return this.dom.getContext(t)}toBlob(t,e,s){return this.dom.toBlob(t,e,s),this}toDataURL(t,e){return this.dom.toDataURL(t,e)}transferControlToOffscreen(){return this.dom.transferControlToOffscreen()}}class Ft extends f{constructor(t){super("dialog",t)}open(t){return $.fluent(this,arguments,()=>this.dom.open,()=>$.set(this.dom,"open",t))}returnValue(t){return $.fluent(this,arguments,()=>this.dom.returnValue,()=>$.set(this.dom,"returnValue",t))}close(){return this.dom.close(),this}show(){return this.dom.show(),this}showModal(){return this.dom.showModal(),this}}class wt extends f{constructor(t){super("select")}add(t){return this.insert(t),this}item(t){return $(this.dom.item(t))}namedItem(t){return $(this.dom.namedItem(t))}multiple(t){return $.fluent(this,arguments,()=>this.dom.multiple,()=>$.set(this.dom,"multiple",t))}get length(){return this.dom.length}get size(){return this.dom.size}get options(){return Array.from(this.dom.options).map(t=>$(t))}get selectedIndex(){return this.dom.selectedIndex}get selectedOptions(){return Array.from(this.dom.selectedOptions).map(t=>$(t))}value(t){return $.fluent(this,arguments,()=>this.dom.value,()=>$.set(this.dom,"value",t,e=>{this.on("input",()=>{e.attributes.has(this.dom)!==!1&&(typeof e.value=="string"&&e.set(`${this.value()}`),typeof e.value=="number"&&e.set(Number(this.value())))})}))}get labels(){return Array.from(this.dom.labels??[]).map(t=>$(t))}}_.mixin(wt,L.create("checkValidity","reportValidity","autocomplete","name","form","required","disabled","validationMessage","validity","willValidate"));class bt extends f{constructor(t){super("option",t)}defaultSelected(t){return $.fluent(this,arguments,()=>this.dom.defaultSelected,()=>$.set(this.dom,"defaultSelected",t))}selected(t){return $.fluent(this,arguments,()=>this.dom.selected,()=>$.set(this.dom,"selected",t))}text(t){return $.fluent(this,arguments,()=>this.dom.text,()=>$.set(this.dom,"text",t))}value(t){return $.fluent(this,arguments,()=>this.dom.value,()=>$.set(this.dom,"value",t))}get form(){return this.dom.form?$(this.dom.form):null}get index(){return this.dom.index}}_.mixin(bt,L.create("form","disabled","label"));class Tt extends f{constructor(t){super("optgroup",t)}disabled(t){return $.fluent(this,arguments,()=>this.dom.disabled,()=>$.set(this.dom,"disabled",t))}}_.mixin(Tt,L.create("disabled","label"));class St extends f{constructor(t){super("textarea",t)}cols(t){return $.fluent(this,arguments,()=>this.dom.cols,()=>$.set(this.dom,"cols",t))}wrap(t){return $.fluent(this,arguments,()=>this.dom.wrap,()=>$.set(this.dom,"wrap",t))}value(t){return $.fluent(this,arguments,()=>this.dom.value,()=>$.set(this.dom,"value",t))}defaultValue(t){return $.fluent(this,arguments,()=>this.dom.defaultValue,()=>$.set(this.dom,"defaultValue",t))}dirName(t){return $.fluent(this,arguments,()=>this.dom.dirName,()=>$.set(this.dom,"dirName",t))}placeholder(t){return $.fluent(this,arguments,()=>this.dom.placeholder,()=>$.set(this.dom,"placeholder",t))}readOnly(t){return $.fluent(this,arguments,()=>this.dom.readOnly,()=>$.set(this.dom,"readOnly",t))}selectionDirection(t){return $.fluent(this,arguments,()=>this.dom.selectionDirection,()=>$.set(this.dom,"selectionDirection",t))}selectionEnd(t){return $.fluent(this,arguments,()=>this.dom.selectionEnd,()=>$.set(this.dom,"selectionEnd",t))}selectionStart(t){return $.fluent(this,arguments,()=>this.dom.selectionStart,()=>$.set(this.dom,"selectionStart",t))}type(t){return $.fluent(this,arguments,()=>this.dom.type,()=>$.set(this.dom,"type",t))}inputMode(t){return $.fluent(this,arguments,()=>this.dom.inputMode,()=>$.set(this.dom,"inputMode",t))}select(){return this.dom.select(),this}setCustomValidity(t){return this.dom.setCustomValidity(t),this}setRangeText(t,e,s,i){return typeof e=="number"&&typeof s=="number"&&this.dom.setRangeText(t,e,s,i),this.dom.setRangeText(t),this}setSelectionRange(t,e,s){return this.dom.setSelectionRange(t,e,s),this}get labels(){return Array.from(this.dom.labels??[]).map(t=>$(t))}}_.mixin(St,L.create("checkValidity","reportValidity","autocomplete","name","form","required","disabled","minLength","maxLength","validationMessage","validity","willValidate"));var tt;class It extends f{constructor(e){super("async",e);B(this,tt,!1)}await(e){return e instanceof Function?e(this).then(s=>this._loaded(s)):e.then(s=>this._loaded(s)),this}_loaded(e){if(K(this,tt,!0),typeof e=="string")this.replace(new q(e));else if(e instanceof I){const s=new q(e.toString());e.use(s,"content"),this.replace(s)}else e==null?this.replace(new q(String(e))):this.replace(e);this.dom.dispatchEvent(new Event("load"))}get loaded(){return x(this,tt)}}tt=new WeakMap;const Ut=Object.freeze(Object.defineProperty({__proto__:null,$Async:It},Symbol.toStringTag,{value:"Module"}));class Gt extends M{constructor(t,e){super(t,e)}autoplay(t){return $.fluent(this,arguments,()=>this.dom.autoplay,()=>$.set(this.dom,"autoplay",t))}get buffered(){return this.dom.buffered}controls(t){return $.fluent(this,arguments,()=>this.dom.controls,()=>$.set(this.dom,"controls",t))}crossOrigin(t){return $.fluent(this,arguments,()=>this.dom.crossOrigin,()=>$.set(this.dom,"crossOrigin",t))}get currentSrc(){return this.dom.currentSrc}currentTime(t){return $.fluent(this,arguments,()=>this.dom.currentTime,()=>$.set(this.dom,"currentTime",t))}defaultMuted(t){return $.fluent(this,arguments,()=>this.dom.defaultMuted,()=>$.set(this.dom,"defaultMuted",t))}defaultPlaybackRate(t){return $.fluent(this,arguments,()=>this.dom.defaultPlaybackRate,()=>$.set(this.dom,"defaultPlaybackRate",t))}disableRemotePlayback(t){return $.fluent(this,arguments,()=>this.dom.disableRemotePlayback,()=>$.set(this.dom,"disableRemotePlayback",t))}get duration(){return this.dom.duration}get ended(){return this.dom.ended}get error(){return this.dom.error}loop(t){return $.fluent(this,arguments,()=>this.dom.loop,()=>$.set(this.dom,"loop",t))}mediaKeys(t){return $.fluent(this,arguments,()=>this.dom.mediaKeys,()=>$.set(this.dom,"setMediaKeys",[t]))}muted(t){return $.fluent(this,arguments,()=>this.dom.muted,()=>$.set(this.dom,"muted",t))}get networkState(){return this.dom.networkState}get paused(){return this.dom.paused}playbackRate(t){return $.fluent(this,arguments,()=>this.dom.playbackRate,()=>$.set(this.dom,"playbackRate",t))}get played(){return this.dom.played}preload(t){return $.fluent(this,arguments,()=>this.dom.preload,()=>$.set(this.dom,"preload",t))}preservesPitch(t){return $.fluent(this,arguments,()=>this.dom.preservesPitch,()=>$.set(this.dom,"preservesPitch",t))}get readyState(){return this.dom.readyState}get remote(){return this.dom.remote}get seekable(){return this.dom.seekable}get seeking(){return this.dom.seeking}sinkId(t){return $.fluent(this,arguments,()=>this.dom.sinkId,()=>$.set(this.dom,"setSinkId",[t]))}src(t){return $.fluent(this,arguments,()=>this.dom.src,()=>$.set(this.dom,"src",t))}srcObject(t){return $.fluent(this,arguments,()=>this.dom.srcObject,()=>$.set(this.dom,"srcObject",t))}get textTracks(){return this.dom.textTracks}volume(t){return $.fluent(this,arguments,()=>this.dom.volume,()=>$.set(this.dom,"volume",t))}addTextTrack(t,e,s){return this.dom.addTextTrack(t,e,s)}canPlayType(t){return this.dom.canPlayType(t)}fastSeek(t){return this.dom.fastSeek(t),this}load(){return this.dom.load(),this}pause(){return this.dom.pause(),this}async play(){return await this.dom.play(),this}get isPlaying(){return this.currentTime()>0&&!this.paused&&!this.ended&&this.readyState>2}}class zt extends Gt{constructor(t){super("video",t)}disablePictureInPicture(t){return $.fluent(this,arguments,()=>this.dom.disablePictureInPicture,()=>$.set(this.dom,"disablePictureInPicture",t))}height(t){return $.fluent(this,arguments,()=>this.dom.height,()=>$.set(this.dom,"height",t))}width(t){return $.fluent(this,arguments,()=>this.dom.width,()=>$.set(this.dom,"width",t))}playsInline(t){return $.fluent(this,arguments,()=>this.dom.playsInline,()=>$.set(this.dom,"playsInline",t))}poster(t){return $.fluent(this,arguments,()=>this.dom.poster,()=>$.set(this.dom,"poster",t))}get videoHeight(){return this.dom.videoHeight}get videoWidth(){return this.dom.videoWidth}cancelVideoFrameCallback(t){return this.dom.cancelVideoFrameCallback(t),this}getVideoPlaybackQuality(){return this.dom.getVideoPlaybackQuality()}requestPictureInPicture(){return this.dom.requestPictureInPicture()}requestVideoFrameCallback(t){return this.dom.requestVideoFrameCallback(t)}}function T(r){if(typeof r>"u"||r===null||r instanceof U)return r;if(typeof r=="string"){if(r.startsWith("::"))return Array.from(document.querySelectorAll(r.replace(/^::/,""))).map(t=>T(t));if(r.startsWith(":"))return T(document.querySelector(r.replace(/^:/,"")));if(r in T.TagNameElementMap){const t=T.TagNameElementMap[r];return t===Q?new Q(r):t===f?new f(r):new t}else return new f(r)}if(r instanceof Node)return r.$?r.$:_.from(r);throw`$: NOT SUPPORT TARGET ELEMENT TYPE ('${r}')`}(r=>{r.anchorHandler=null,r.TagNameElementMap={html:f,head:f,document:J,body:f,a:kt,p:f,pre:f,code:f,blockquote:f,strong:f,h1:f,h2:f,h3:f,h4:f,h5:f,h6:f,div:f,ol:f,ul:f,dl:f,li:f,input:C,label:vt,button:ht,form:yt,img:jt,dialog:Ft,canvas:Wt,select:wt,option:bt,optgroup:Tt,textarea:St,video:zt,async:It};function t(l,p,y,S){return p.length?(S(),l):y()}r.fluent=t;function e(l){return l instanceof Array?l:[l]}r.orArrayResolve=e;function s(l,p){return _.mixin(l,p)}r.mixin=s;function i(l,p,y,S){if(y!==void 0){if(y instanceof I){y.use(l,p),l[p]instanceof Function?l[p](...y.value):l[p]=y.value,S&&S(y);return}l[p]instanceof Function?l[p](...y):l[p]=y}}r.set=i;function n(l,p){return new I(l,p)}r.state=n;async function a(l,p){return new Promise(y=>{const S=new FileReader;S.onload=O=>{const b=r("img");if(b.once("load",A=>{const V=r("canvas"),j=V.getContext("2d"),R=b.height()/b.width(),[P,G]=[R>1?p/R:p,R>1?p:p*R];V.height(G).width(P),j==null||j.drawImage(b.dom,0,0,P,G),y(V.toDataURL(l.type))}),!O.target)throw"$.resize(): e.target is null";b.src(O.target.result)},S.readAsDataURL(l)})}r.resize=a;function o(l=1){return parseInt(getComputedStyle(document.documentElement).fontSize)*l}r.rem=o;function c(l){const p=new DOMParser().parseFromString(l,"text/html").body;return Array.from(p.children).map(y=>r(y))}r.html=c;function h(l,p,y){if(typeof p=="number")return Array(p).fill("").map(O=>{const b=S(l)?l[0](...l.slice(1)):r(l);return y&&y(b),b});{const O=[];for(const b of p){const A=l instanceof Function?l(...b):S(l)?l[0](...l.slice(1)):r(l);b instanceof Function?b(A):(b instanceof U||typeof b=="string")&&A.content(b),O.push(A)}return O}function S(O){return O instanceof Array&&O[0]instanceof Function}}r.builder=h;function d(l,p){return Object.assign(r.TagNameElementMap,{[l]:p}),r.TagNameElementMap}r.registerTagName=d;function m(...l){return new et}r.events=m;function w(l){return l()}r.call=w})(T||(T={}));globalThis.$=T;class et{constructor(){u(this,"eventMap",new Map)}fire(t,...e){var s;return(s=this.eventMap.get(t))==null||s.forEach(i=>i(...e)),this}on(t,e){const s=this.eventMap.get(t)??this.eventMap.set(t,new Set).get(t);return s==null||s.add(e),this}off(t,e){var s;return(s=this.eventMap.get(t))==null||s.delete(e),this}once(t,e){const s=(...n)=>{var a;(a=this.eventMap.get(t))==null||a.delete(s),e(...n)},i=this.eventMap.get(t)??this.eventMap.set(t,new Set).get(t);return i==null||i.add(s),this}}Array.prototype.detype=function(...r){return this.filter(t=>{if(r.length)for(const e of r)return typeof t!=typeof e;else return t!==void 0})};Object.defineProperties(Set.prototype,{array:{get:function(){return Array.from(this)}}});Set.prototype.sort=function(r){return this.array.sort(r)};class _t extends f{constructor(e){super("layout",e);u(this,"_property",{ROW_MAX_HEIGHT:200,GAP:0,IS_RENDERING:!1,RENDER_REQUEST:!1,COLUNM:1,TYPE:"justified",ROOT:null,ITEM_PROPERTIES:new Map});this.css({display:"block",position:"relative"}),new ResizeObserver(s=>{this.inDOM()&&(this.render(),this.dom.dispatchEvent(new Event("resize")))}).observe(this.dom),document.addEventListener("scroll",s=>{s.target===this.root().dom&&this.scrollCompute()}),new IntersectionObserver(s=>{this.inDOM()&&this.render()}).observe(this.dom)}type(e){return $.fluent(this,arguments,()=>this._property.TYPE,()=>$.set(this._property,"TYPE",e))}maxHeight(e){return $.fluent(this,arguments,()=>this._property.ROW_MAX_HEIGHT,()=>$.set(this._property,"ROW_MAX_HEIGHT",e))}column(e){return $.fluent(this,arguments,()=>this._property.COLUNM,()=>$.set(this._property,"COLUNM",e))}gap(e){return $.fluent(this,arguments,()=>this._property.GAP,()=>$.set(this._property,"GAP",e))}root(e){return $.fluent(this,arguments,()=>this._property.ROOT??$(document),()=>$.set(this._property,"ROOT",e))}get COL_WIDTH(){return(this.offsetWidth-this._property.GAP*(this._property.COLUNM-1))/this._property.COLUNM}justifiedCompute(){const e=[],s=this.offsetWidth;for(const i of this.children.array){const n=$(i);if(!(n instanceof M))continue;const a=n.attribute("layout-item-ratio"),o=a?parseFloat(a):n.dom.offsetWidth/n.dom.offsetHeight,c={$node:n,ratio:o};let h=e.at(-1);(!h||h.heightd+=l.ratio);const m=d+o,w=(s-this._property.GAP*h.items.length)/m;h.items.push(c),h.ratio=m,h.height=w}return e}waterfallCompute(){const e=[],s=this.COL_WIDTH,i=()=>{if(e.lengthn.height-a.height)[0]};for(const n of this.children.array){const a=$(n);if(!(a instanceof M))continue;const o=a.attribute("layout-item-ratio"),c=o?parseFloat(o):a.dom.offsetWidth/a.dom.offsetHeight,h={$node:a,ratio:c},d=i();let m=0;d.items.forEach(p=>m+=p.ratio);const w=s/(d.height+s/c),l=s/w;d.items.push(h),d.ratio=w,d.height=l}return e}render(){if(!this.inDOM())return this;if(this._property.ITEM_PROPERTIES.clear(),this._property.TYPE==="justified"){const e=this.justifiedCompute();let s=0;for(const i of e){let n=0;i.height>this._property.ROW_MAX_HEIGHT&&(i.height=this._property.ROW_MAX_HEIGHT);for(const a of i.items){const o=a.ratio*i.height;a.$node.css({position:"absolute",height:`${i.height}px`,width:`${o}px`,top:`${s}px`,left:`${n}px`}),a.$node.attribute("layout-item-ratio",a.ratio),this._property.ITEM_PROPERTIES.set(a.$node,{height:i.height,width:o,top:s,left:n,ratio:a.ratio,$node:a.$node}),n+=i.height*a.ratio+this._property.GAP}s+=i.height+this._property.GAP}this.css({height:`${s}px`})}else if(this._property.TYPE="waterfall"){const e=this.waterfallCompute(),s=this.COL_WIDTH;let i=0;for(const n of e){let a=0;for(const o of n.items){const c=s/o.ratio;o.$node.css({position:"absolute",height:`${c}px`,width:`${s}px`,top:`${a}px`,left:`${i}px`}),o.$node.attribute("layout-item-ratio",o.ratio),this._property.ITEM_PROPERTIES.set(o.$node,{height:c,width:s,top:a,left:i,ratio:o.ratio,$node:o.$node}),a+=c+this._property.GAP}i+=s+this._property.GAP}if(e.length){const n=e.sort((a,o)=>o.height-a.height)[0];this.css({height:`${n.height+n.items.length*this._property.GAP}px`})}else this.css({height:""})}return this.scrollCompute(),this}scrollCompute(){if(this.inDOM()===!1)return;const e=document.documentElement.scrollTop-this.dom.offsetTop;this._property.ITEM_PROPERTIES.forEach((s,i)=>{const n=s.top;s.top+s.height>e&&n{this.contentId=e,this.events.fire("rendered",{$view:this,previousContent:i,nextContent:s})},o=()=>{this.events.fire("afterSwitch",{$view:this,previousId:e})};return this.events.fire("beforeSwitch",{$view:this,preventDefault:()=>n=!0,targetId:e,previousContent:i,nextContent:s,switched:o,rendered:a}),n||(this.content(s),a(),o()),this}get currentContent(){if(this.contentId)return this.viewCache.get(this.contentId)}}$.registerTagName("view",Ot);var D;const g=class g extends Ot{constructor(e){super({tagname:"router",...e});B(this,D,"");u(this,"routes",new Map);g.routers.add(this)}base(e){return $.fluent(this,arguments,()=>x(this,D),()=>{K(this,D,e??x(this,D))})}map(e){e=$.orArrayResolve(e);for(const s of e)s instanceof Array?this.map(s):this.routes.set(s.path(),s);return this.resolve(),this}resolve(){return new Promise(e=>{if(!location.pathname.startsWith(x(this,D)))return e(2);const s=location.pathname.replace(x(this,D),"/").replace("//","/"),i=s.split("/").map(p=>`/${p}`),n=location.search,a=new Map(n.replace("?","").split("&").map(p=>p.split("="))),c=(()=>{const p=[];for(const[y,S]of this.routes){const O=$.orArrayResolve(y);for(const b of O){let A=0,V={},j={};const R=b.split("/").map(P=>`/${P}`);if(!(i.lengthObject.assign(j,{[mt]:a.get(mt)})),G.startsWith("/:")){A++,Object.assign(V,{[G.replace("/:","")]:i[P].replace("/","")});continue}else if(b.startsWith("#")&&b===location.hash){A++;continue}else if(G===i[P]){A++;continue}else break}p.push({deep:A,$route:S,params:V,query:j,pathId:Object.keys(j).length!==0?s+n:Object.keys(V).length!==0?s:O[0]})}}}return p.sort((y,S)=>S.deep-y.deep).at(0)})();if(!c)return e(1);const{$route:h,params:d,pathId:m,query:w}=c;if(m===this.contentId)return e(0);this.events.once("rendered",({nextContent:p,previousContent:y})=>{y==null||y.events.fire("afterShift",{$route:y}),p.events.fire("rendered",{$route:p}),e(0)});const l=this.viewCache.get(m)??h.build({params:d,query:w});this.viewCache.has(m)||this.setView(m,l),this.events.once("beforeSwitch",()=>{var p;l.events.fire("beforeShift",{$route:l}),(p=this.currentContent)==null||p.events.fire("beforeShift",{$route:this.currentContent})}),this.events.once("afterSwitch",()=>l.events.fire("afterShift",{$route:l})),this.switchView(m)})}static init(){if(!history.state||!("index"in history.state)){const e={index:g.historyIndex};history.replaceState(e,"")}else g.historyIndex=history.state.index;return g.navigationDirection=0,g.resolve(),window.addEventListener("popstate",()=>g.popstate()),window.addEventListener("scroll",()=>{this.setScrollHistory(this.historyIndex,location.href,document.documentElement.scrollTop)}),history.scrollRestoration="manual",this}static open(e,s){return e===void 0?this:(e=this.urlResolver(e),e.href===this.url.href?this:e.origin!==this.url.origin?(window.open(e,s),this):(g.clearForwardScrollHistory(),g.historyIndex++,history.pushState(g.historyState,"",e),g.stateChange(0),g.resolve(),this))}static back(){return this.historyIndex--,history.back(),this.stateChange(1),this}static replace(e){return e===void 0?this:(e=this.urlResolver(e),history.replaceState(g.historyState,"",e),this.stateChange(2),this.setScrollHistory(this.historyIndex,location.href,0),g.resolve(),this)}static urlResolver(e){return e instanceof URL?e:(e.startsWith("/")&&(e=`${location.origin}${e}`),e.startsWith("#")&&(e=`${location.origin}${location.pathname}${e}`),new URL(e))}static popstate(){const e=history.state.index>g.historyIndex?0:history.state.indexe.resolve())),this.scrollRestoration(),this.setScrollHistory(this.historyIndex,location.href,document.documentElement.scrollTop)}static get historyState(){return{index:g.historyIndex}}static stateChange(e){const s=this.url,i=new URL(location.href);this.url=i,g.events.fire("stateChange",{beforeURL:s,afterURL:i,direction:e}),g.navigationDirection=e}static setScrollHistory(e,s,i){const n=this.getScrollHistory();if(!n)return sessionStorage.setItem(this.scrollHistoryKey,JSON.stringify({[e]:{url:s,value:i}}));n[e]={url:s,value:i},sessionStorage.setItem(this.scrollHistoryKey,JSON.stringify(n))}static getScrollHistory(){const e=sessionStorage.getItem(this.scrollHistoryKey);if(e)return JSON.parse(e)}static clearForwardScrollHistory(){const e=this.getScrollHistory();if(e)for(const s in e)Number(s)>this.historyIndex&&delete e[s],sessionStorage.setItem(this.scrollHistoryKey,JSON.stringify(e))}static scrollRestoration(){const e=this.getScrollHistory();if(e&&e[this.historyIndex])document.documentElement.scrollTop=e[this.historyIndex].value??0;else if(location.hash.length){const s=$(document.body).$(location.hash);s&&(document.documentElement.scrollTop=s.dom.offsetTop)}else document.documentElement.scrollTop=0}};D=new WeakMap,u(g,"routers",new Set),u(g,"events",new et),u(g,"navigationDirection"),u(g,"historyIndex",0),u(g,"url",new URL(location.href)),u(g,"scrollHistoryKey","$ROUTER_SCROLL_HISTORY");let E=g;var W=(r=>(r[r.Forward=0]="Forward",r[r.Back=1]="Back",r[r.Replace=2]="Replace",r))(W||{});E.init();var X,H;const lt=class lt extends f{constructor(e){super("route",e);B(this,X,"");B(this,H);u(this,"rendered",!1)}path(e){return $.fluent(this,arguments,()=>x(this,X),()=>K(this,X,e??x(this,X)))}builder(e){return K(this,H,e),this}render(e){return x(this,H)&&this.content(x(this,H).call(this,{$route:this,params:e.params,query:e.query})),this.rendered=!0,this}build(e){return new lt({dom:this.dom.cloneNode()}).self(s=>{x(this,H)&&s.builder(x(this,H)).render({params:e.params,query:e.query})})}};X=new WeakMap,H=new WeakMap;let ot=lt;$.registerTagName("router",E);$.registerTagName("route",ot);Object.assign($,{open(r,t){return E.open(r,t)},replace(r){return E.replace(r)},back(){return E.back()}});const N=class N{constructor(t){u(this,"posts",new Map);u(this,"tags",new Map);Object.assign(this,t),this.origin.endsWith("/")&&(this.origin=this.origin.slice(0,-1)),N.manager.set(this.name,this)}static set(t){return this.used=t,this.name$.set(t.name),this.storageAPI=t.name,this.events.fire("set"),this}static get storageAPI(){return localStorage.getItem("booru_api")}static set storageAPI(t){t?localStorage.setItem("booru_api",t):localStorage.removeItem("booru_api")}};u(N,"used"),u(N,"events",new et),u(N,"name$",$.state(N.name)),u(N,"manager",new Map);let v=N;const qt=new Intl.NumberFormat("en",{notation:"compact"});class xt{constructor(t,e){u(this,"post_count$",$.state(0,{format:t=>`${qt.format(t)}`}));u(this,"name$",$.state(""));u(this,"booru");this.booru=t,Object.assign(this,e),this.$update()}static async fetch(t,e){var n;const s=await fetch(`${t.origin}/tags/${e}.json`).then(async a=>await a.json()),i=((n=t.tags.get(s.id))==null?void 0:n.update(s))??new this(t,s);return t.tags.set(i.id,i),i}static async fetchMultiple(t,e,s=1e3){let i="";if(e)for(const[c,h]of Object.entries(e))if(h instanceof Array)i+=`&search[${c}]=${h}`;else if(h instanceof Object)for(const[d,m]of Object.entries(h))i+=`&search[${c}${d}]=${m}`;else i+=`&search[${c}]=${h}`;return(await(await fetch(`${t.origin}/tags.json?limit=${s}${i}`)).json()).map(c=>{var d;const h=((d=t.tags.get(c.id))==null?void 0:d.update(c))??new this(t,c);return t.tags.set(h.id,h),h})}update(t){return Object.assign(this,t),this.$update(),this}$update(){this.post_count$.set(this.post_count),this.name$.set(this.name)}}var F=(r=>(r[r.General=0]="General",r[r.Artist=1]="Artist",r[r.Copyright=3]="Copyright",r[r.Character=4]="Character",r[r.Meta=5]="Meta",r))(F||{});class Y{constructor(t){u(this,"name$",$.state("loding..."));Object.assign(this,t),this.update$()}static async fetch(t,e){var n;const s=await fetch(`${t.origin}/users/${e}.json`).then(async a=>await a.json()),i=((n=this.manager.get(s.id))==null?void 0:n.update(s))??new this(s);return this.manager.set(i.id,i),i}static async fetchMultiple(t,e,s=200){let i="";if(e)for(const[c,h]of Object.entries(e))if(h instanceof Array)i+=`&search[${c}]=${h}`;else if(h instanceof Object)for(const[d,m]of Object.entries(h))i+=`&search[${c}${d}]=${m}`;else i+=`&search[${c}]=${h}`;return(await(await fetch(`${t.origin}/users.json?limit=${s}${i}`)).json()).map(c=>{const h=new this(c);return this.manager.set(h.id,h),h})}update(t){return Object.assign(this,t),this.update$(),this}update$(){this.name$.set(this.name)}}u(Y,"manager",new Map);const ct=1e3,it=ct*60,rt=it*60,nt=rt*24,Xt=nt*7,st=new Intl.RelativeTimeFormat("en",{style:"long"});function Bt(r){r=Math.floor(r);const t=r/ct,e=r/it,s=r/rt,i=r/nt,n=r%1e3,a=Math.floor(r%6e4/1e3),o=Math.floor(r%36e5/6e4),c=Math.floor(r%(36e5*24)/36e5),h=a.toString().padStart(2,"0"),d=o.toString().padStart(2,"0"),m=c.toString().padStart(2,"0");return{seconds:t,minutes:e,hours:s,days:i,mil:n,s:a,min:o,h:c,ss:h,mm:d,hh:m}}function Kt(r,t=Date.now()){const e=r-t,s=Math.abs(e);if(sawait s.json());return this.update(e),Y.fetchMultiple(this.booru,{id:[this.uploader_id,this.approver_id].detype(null)}).then(()=>this.update$()),this}static async fetchMultiple(e,s,i=20){let n="";if(s){if(typeof s=="string")n=s;else for(const[d,m]of Object.entries(s))if(m!==void 0){if(d==="tags"){n+=`${m}`;continue}n.at(-1)!=="="&&(n+=" "),n+=`${d}:${m}`}}const o=await(await fetch(`${e.origin}/posts.json?limit=${i}&tags=${n}&_method=get`)).json(),c=o.map(d=>{var w;const m=((w=e.posts.get(d.id))==null?void 0:w.update(d))??new this(e,d.id,d);return e.posts.set(m.id,m),m});if(!c.length)return c;const h=[...new Set(o.map(d=>[d.approver_id,d.uploader_id].detype(null)).flat())];return Y.fetchMultiple(e,{id:h}).then(()=>c.forEach(d=>d.update$())),c}update$(){var e,s,i,n;this.uploader$.set(((e=this.uploader)==null?void 0:e.name$)??((s=this.uploader_id)==null?void 0:s.toString())),this.approver$.set(((i=this.approver)==null?void 0:i.name$)??((n=this.approver_id)==null?void 0:n.toString())??"None"),this.created_date$.set(Kt(+new Date(this.created_at))),this.favorites$.set(this.fav_count),this.score$.set(this.score),this.file_size$.set(Yt(this.file_size)),this.file_ext$.set(this.file_ext),this.dimension$.set(`${this.image_width}x${this.image_height}`),this.createdDate=new Date(this.created_at),this.fire("update")}update(e){return Object.assign(this,e),this.update$(),this}async fetchTags(){return await this.ready,await xt.fetchMultiple(this.booru,{name:{_space:this.tag_string}})}get pathname(){return`/posts/${this.id}`}get uploader(){return Y.manager.get(this.uploader_id)}get approver(){return this.approver_id?Y.manager.get(this.approver_id):null}get isVideo(){return this.file_ext==="mp4"||this.file_ext==="webm"||this.file_ext==="zip"}get isGif(){return this.file_ext==="gif"}get isUgoria(){return this.file_ext==="zip"}get hasSound(){return this.tag_string_meta.includes("sound")}get tags(){const e=this.tag_string.split(" ");return[...this.booru.tags.values()].filter(s=>e.includes(s.name))}get previewURL(){var e;return((e=this.media_asset.variants.find(s=>s.file_ext==="webp"))==null?void 0:e.url)??this.large_file_url}}class Et{constructor(t){Object.assign(this,t)}static async fetch(t,e){const s=await fetch(`${t.origin}/artist_commentaries/${e}.json`);return new this(await s.json())}static async fetchMultiple(t,e,s=200){let i="";if(e)for(const[c,h]of Object.entries(e))if(h instanceof Array)i+=`&search[${c}]=${h}`;else if(h instanceof Object)for(const[d,m]of Object.entries(h))i+=`&search[${c}${d}]=${m}`;else i+=`&search[${c}]=${h}`;return(await(await fetch(`${t.origin}/artist_commentaries.json?limit=${s}${i}`)).json()).map(c=>{const h=new this(c);return this.manager.set(h.id,h),h})}}u(Et,"manager",new Map);const Jt=$("route").path("/posts/:id").id("post").builder(({$route:r,params:t})=>{if(!Number(t.id))return $("h1").content("404: POST NOT FOUND");const e=Z.get(v.used,+t.id);return[$("div").class("viewer").content(async()=>(await e.ready,e.isVideo?$("video").height(e.image_height).width(e.image_width).src(e.file_ext==="zip"?e.large_file_url:e.file_url).controls(!0).autoplay(!0).loop(!0).disablePictureInPicture(!0):$("img").src(e.large_file_url))),$("div").class("content").content([$("h3").content("Artist's Commentary"),$("section").class("commentary").content(async s=>{const i=(await Et.fetchMultiple(v.used,{post:{_id:e.id}})).at(0);return[i?[i.original_title?$("h3").content(i.original_title):null,$("pre").content(i.original_description)]:"No commentary"]})]),$("div").class("sidebar").self(s=>{let i=0;addEventListener("scroll",()=>{s.inDOM()&&(i=document.documentElement.scrollTop)}),r.on("beforeShift",()=>{innerWidth>800&&s.css({position:"absolute",top:`calc(${i}px + var(--nav-height) + var(--padding))`})}).on("afterShift",()=>s.css({position:"",top:""}))}).content([$("section").class("post-info").content([new k("id").name("Post").value(`#${t.id}`),new k("uploader").name("Uploader").value(e.uploader$),new k("approver").name("Approver").value(e.approver$),new k("date").name("Date").value(e.created_date$),new k("size").name("Size").value([e.file_size$,e.dimension$]),new k("file").name("File Type").value(e.file_ext$),$("div").class("inline").content([new k("favorites").name("Favorites").value(e.favorites$),new k("score").name("Score").value(e.score$)]),$("div").class("buttons").content([$("icon-button").class("vertical").icon("link-outline").content(v.name$).on("click",(s,i)=>{s.preventDefault(),navigator.clipboard.writeText(`${v.used.origin}${location.pathname}`),i.content("Copied!"),setTimeout(()=>{i.content(v.name$)},2e3)}),$("icon-button").class("vertical").icon("link-outline").content("File").on("click",(s,i)=>{s.preventDefault(),navigator.clipboard.writeText(e.file_url),i.content("Copied!"),setTimeout(()=>{i.content("File")},2e3)}),$("icon-button").class("vertical").icon("link-outline").content("Webm").on("click",(s,i)=>{s.preventDefault(),navigator.clipboard.writeText(e.previewURL),i.content("Copied!"),setTimeout(()=>{i.content("Webm")},2e3)}).hide(!0).self(async s=>{await e.ready,e.file_ext==="zip"&&s.hide(!1)})])]),$("div").class("post-tags").content(async s=>{const i=await e.fetchTags(),[n,a,o,c,h]=[i.filter(m=>m.category===F.Artist),i.filter(m=>m.category===F.Character),i.filter(m=>m.category===F.General),i.filter(m=>m.category===F.Meta),i.filter(m=>m.category===F.Copyright)];return[d("Artist",n),d("Character",a),d("Copyright",h),d("Meta",c),d("General",o)];function d(m,w){return w.length?[$("h3").content(m),$("section").content([w.map(l=>$("div").class("tag").content([$("a").class("tag-name").content(l.name).href(`/posts?tags=${l.name}`),$("span").class("tag-post-count").content(l.post_count$)]))])]:null}})])]});class k extends f{constructor(e){super("div");u(this,"$name",$("span").class("property-name"));u(this,"$values",$("div").class("property-values"));this.staticClass("property").attribute("property-id",e),this.content([this.$name,this.$values])}name(e){return this.$name.content(e),this}value(e){const s=$.orArrayResolve(e);return this.$values.content(s.map(i=>$("span").staticClass("property-value").content(i))),this}}class Qt extends f{constructor(e){super("post-tile");u(this,"post");u(this,"$video");u(this,"duration$",$.state(""));this.post=e,this.$video=this.post.isVideo?$("video").width(this.post.image_width).height(this.post.image_height).disablePictureInPicture(!0).loop(!0).muted(!0).hide(!0).on("mousedown",s=>s.preventDefault()):null,this.attribute("filetype",this.post.file_ext),this.durationUpdate(),this.build()}build(){var s,i;let e;(s=this.$video)==null||s.on("playing",(n,a)=>{e=setInterval(()=>{this.durationUpdate()},500)}),(i=this.$video)==null||i.on("pause",()=>{clearInterval(e),this.durationUpdate()}),this.class("loading").content([this.post.isVideo?$("div").class("video-detail").content([this.post.hasSound?$("ion-icon").name("volume-medium-outline"):null,this.post.isUgoria?$("ion-icon").name("images-outline"):null,$("span").class("duration").content(this.duration$)]):null,this.post.isGif?$("div").class("gif-detail").content([$("span").content("GIF")]):null,$("a").href(this.post.pathname).content(()=>[this.$video,$("img").draggable(!1).css({opacity:"0"}).width(this.post.image_width).height(this.post.image_height).src(this.post.previewURL).loading("lazy").on("mousedown",n=>n.preventDefault()).once("load",(n,a)=>{a.src(this.post.previewURL).on(["mouseenter","touchstart"],()=>{this.post.isGif&&a.src(this.post.large_file_url)}).on(["mouseleave","touchend","touchcancel"],()=>{this.post.isGif&&a.src(this.post.previewURL)}).animate({opacity:[0,1]},{duration:300,fill:"both"}),this.removeClass("loading")})]).on(["mouseenter","touchstart"],()=>{var n,a;(n=this.$video)!=null&&n.isPlaying||(a=this.$video)==null||a.src(this.post.large_file_url).hide(!1).play().catch(o=>{})}).on(["mouseleave","touchend","touchcancel"],()=>{var n;(n=this.$video)==null||n.pause().currentTime(0).hide(!0)})])}durationUpdate(){if(!this.$video)return;const e=Bt(this.post.media_asset.duration*1e3-this.$video.currentTime()*1e3);this.duration$.set(Number(e.hh)>0?`${e.hh}:${e.mm}:${e.ss}`:`${e.mm}:${e.ss}`)}}class $t extends _t{constructor(e){super();u(this,"posts",new Set);u(this,"$posts",new Set);u(this,"tags");this.tags=e==null?void 0:e.tags,this.addStaticClass("post-grid"),this.type("waterfall").gap(10),this.init()}async init(){setInterval(()=>{this.inDOM()&&document.documentElement.scrollTop===0&&this.updateNewest()},1e4),v.events.on("set",()=>{this.removeAll()}),this.on("resize",()=>this.resize()),this.loader()}async loader(){if(!this.inDOM())return setTimeout(()=>this.loader(),100);for(;this.inDOM()&&document.documentElement.scrollHeight<=innerHeight*2;)if(await this.getPosts(),!this.posts.size)return;document.documentElement.scrollTop+innerHeight>document.documentElement.scrollHeight-innerHeight*2&&await this.getPosts(),setTimeout(()=>this.loader(),100)}resize(){const e=Math.round(this.dom.clientWidth/300);this.column(e>=2?e:2)}addPost(e){e=$.orArrayResolve(e);for(const i of e){if(!i.file_url||this.posts.has(i))continue;const n=new Qt(i);this.$posts.add(n),this.posts.add(i)}const s=[...this.$posts.values()].sort((i,n)=>+n.post.createdDate-+i.post.createdDate);return this.content(s).render(),this}removeAll(){return this.posts.clear(),this.$posts.clear(),this.animate({opacity:[1,0]},{duration:300,easing:"ease"},()=>this.clear().render()),this}async updateNewest(){const e=this.sortedPosts.at(0),s=await Z.fetchMultiple(v.used,{tags:this.tags,id:e?`>${e.id}`:void 0},100);return this.addPost(s),this}async getPosts(){const e=this.sortedPosts.at(-1),s=await Z.fetchMultiple(v.used,{tags:this.tags,id:e?`<${e.id}`:void 0},100);return this.addPost(s),this}get sortedPosts(){return this.posts.array.sort((e,s)=>+s.createdDate-+e.createdDate)}}class Zt extends f{constructor(){super("searchbar");u(this,"$tagInput",new se(this));u(this,"$selectionList",new te);u(this,"typingTimer",null);u(this,"$filter",$("div").class("filter"));this.build(),window.addEventListener("keyup",e=>{!this.inDOM()&&e.key==="/"&&this.activate(),this.inDOM()&&e.key==="Escape"&&this.inactivate()})}build(){this.content([$("div").class("input-container").content([this.$tagInput.on("input",()=>this.inputHandler()).on("keydown",e=>this.keyHandler(e)),$("ion-icon").name("close-circle-outline").title("Clear Input").on("click",()=>this.$tagInput.clearAll())]).on("click",e=>{e.target===this.$tagInput.dom&&this.$tagInput.addTag().input()}),$("div").class("selection-list-container").content([this.$selectionList]),this.$filter.on("click",()=>{location.hash==="#search"&&$.back()})])}activate(){return this.hide(!1),this.$filter.animate({opacity:[0,.5]},{duration:300,easing:"ease"}),this.$tagInput.input(),this}inactivate(){return this.animate({opacity:[.5,0]},{duration:300,easing:"ease"},()=>this.hide(!0)),this}keyHandler(e){var n,a;const s=()=>{e.preventDefault(),this.$tagInput.addTag().input()},i=o=>{const c=this.$tagInput.children.indexOf(this.$tagInput.$inputor),h=this.$tagInput.children.array.at(c+1);this.$tagInput.addTag(o.value()),h?this.$tagInput.editTag(h):this.$tagInput.input()};switch(e.key){case"ArrowUp":{e.preventDefault(),this.$selectionList.focusPrevSelection(),this.$tagInput.value((n=this.$selectionList.focused)==null?void 0:n.value());break}case"ArrowDown":{e.preventDefault(),this.$selectionList.focusNextSelection(),this.$tagInput.value((a=this.$selectionList.focused)==null?void 0:a.value());break}case" ":s();break;case"Enter":{e.preventDefault(),this.$selectionList.focused?i(this.$selectionList.focused):(this.$tagInput.addTag(),this.search());break}case"Tab":{e.preventDefault();const o=this.$tagInput.children.indexOf(this.$tagInput.$inputor);if(e.shiftKey){this.$tagInput.editTag(this.$tagInput.children.array.at(o-1));break}if(this.$selectionList.focused)i(this.$selectionList.focused);else{const c=this.$tagInput.children.array.at(o+1);c?this.$tagInput.editTag(c):this.$tagInput.addTag().input()}break}case"Backspace":{const o=this.$tagInput.children.indexOf(this.$tagInput.$inputor);o!==0&&!this.$tagInput.$input.value().length&&(e.preventDefault(),this.$tagInput.editTag(this.$tagInput.children.array.at(o-1)));break}}}inputHandler(){this.typingTimer&&(clearTimeout(this.typingTimer),this.typingTimer=null),this.typingTimer=setTimeout(async()=>{this.typingTimer=null,this.getSearchSuggestions()},200)}async getSearchSuggestions(){const e=this.$tagInput.$input.value();if(!e.length)return this.$selectionList.clearSelections();const s=await xt.fetchMultiple(v.used,{fuzzy_name_matches:e,order:"similarity"});this.$selectionList.clearSelections().addSelections(s.map(i=>new ee().value(i.name).content([$("span").class("tag-name").content(i.name),$("span").class("tag-category").content(F[i.category])]).on("click",()=>{this.$tagInput.addTag(i.name).input()}))),this.$tagInput.$input.value().length||this.$selectionList.clearSelections()}search(){return $.replace(`/posts?tags=${this.$tagInput.query}`),this.$tagInput.clearAll(),this.inactivate(),this}checkURL(e,s){e.hash==="#search"&&this.inactivate(),s.hash==="#search"&&this.activate()}}class te extends f{constructor(){super("selection-list");u(this,"focused",null);u(this,"selections",new Set)}addSelections(e){e=$.orArrayResolve(e);for(const s of e)this.selections.add(s);return this.insert(e),this}clearSelections(){return this.focused=null,this.selections.clear(),this.clear(),this}focusSelection(e){return this.blurSelection(),this.focused=e,e.focus(),this}blurSelection(){var e;return(e=this.focused)==null||e.blur(),this.focused=null,this}focusNextSelection(){const e=this.selections.array,s=e.at(0);if(this.focused){const i=e.at(e.indexOf(this.focused)+1);i?this.focusSelection(i):s&&this.focusSelection(s)}else s&&this.focusSelection(s)}focusPrevSelection(){const e=this.selections.array;if(this.focused){const s=e.at(e.indexOf(this.focused)-1);s&&this.focusSelection(s)}else{const s=e.at(0);s&&this.focusSelection(s)}}}class ee extends f{constructor(){super("selection");u(this,"property",{value:""})}value(e){return $.fluent(this,arguments,()=>this.property.value,()=>$.set(this.property,"value",e))}focus(){return this.addClass("active"),this}blur(){return this.removeClass("active"),this}}class se extends f{constructor(e){super("tag-input");u(this,"$input",$("input").type("text"));u(this,"$sizer",$("span").class("sizer"));u(this,"$inputor",$("div").class("input-wrapper").content([this.$sizer,this.$input.on("input",()=>{this.$sizer.content(this.$input.value())})]));u(this,"tags",new Set);u(this,"$seachbar");this.$seachbar=e}input(){return this.insert(this.$inputor),this.$input.focus(),this.$input.value()?this.$seachbar.getSearchSuggestions():this.$seachbar.$selectionList.clearSelections(),this}addTag(e){if(e=e??this.$input.value(),!e.length)return this;const s=new ie(e);return s.on("click",()=>this.editTag(s)),this.tags.add(s),this.value(""),this.$inputor.replace(s),this}editTag(e){return this.addTag(),this.tags.delete(e),e.replace(this.$inputor),this.value(e.name),this.$input.focus(),this.$seachbar.getSearchSuggestions(),this}clearAll(){return this.value(""),this.tags.clear(),this.clear(),this}value(e){return e===void 0?this:(this.$input.value(e),this.$sizer.content(e),this)}get query(){return this.tags.array.map(e=>e.name).toString().replace(",","+")}}class ie extends f{constructor(e){super("tag");u(this,"name");this.name=e,this.build()}build(){this.content(this.name)}}class re extends f{constructor(){super("ion-icon")}name(t){return this.attribute("name",t),this}size(t){return this.attribute("size",t),this}}class ne extends ht{constructor(){super();u(this,"$icon",$("ion-icon"));u(this,"$label",$("span"));this.addStaticClass("icon"),this.build()}build(){super.content([this.$icon,this.$label])}content(e){return this.$label.content(e),this}icon(e){return this.$icon.name(e),this}}$.registerTagName("ion-icon",re);$.registerTagName("icon-button",ne);$.anchorHandler=r=>{$.open(r.href(),r.target())};const[at,oe]=[new v({origin:"https://danbooru.donmai.us",name:"Danbooru"}),new v({origin:"https://safebooru.donmai.us",name:"Safebooru"}),new v({origin:"https://testbooru.donmai.us",name:"Testbooru"})];v.set(v.manager.get(v.storageAPI??"")??at);const ut=new Zt().hide(!0);location.hash==="#search"&&ut.activate();$(document.body).content([$("nav").content([$("a").class("title").href("/").content([$("h1").class("booru-name").content(v.name$),$("h2").class("app").content([$("span").class("app-name").content("Viewer"),$("span").class("version").content("v0.3.3")])]),$("div").class("searchbar").content(["Search in ",v.name$]).self(r=>E.events.on("stateChange",({beforeURL:t,afterURL:e})=>{t.hash==="#search"&&r.hide(!1),e.hash==="#search"&&r.hide(!0)})).on("click",()=>$.open(location.href+"#search")),$("div").class("buttons").content([$("ion-icon").class("search").name("search-outline").title("Search").self(r=>E.events.on("stateChange",({beforeURL:t,afterURL:e})=>{t.hash==="#search"&&r.hide(!1),e.hash==="#search"&&r.hide(!0)})).on("click",()=>$.open(location.href+"#search")),$("ion-icon").class("switch").name("swap-horizontal").title("Switch Booru").on("click",()=>{v.used===at?v.set(oe):v.set(at)}),$("ion-icon").class("open").name("open-outline").title("Open in Original Site").on("click",()=>$.open(location.href.replace(location.origin,v.used.origin)))])]),ut,$("router").base("/").map([$("route").id("posts").path("/").builder(()=>new $t),$("route").id("posts").path("/posts?tags").builder(({query:r})=>new $t({tags:r.tags})),Jt]).on("beforeSwitch",r=>{r.preventDefault();function s(){var a;const n=$.call(()=>{switch(E.navigationDirection){case W.Forward:return["translateX(2%)","translateX(0%)"];case W.Back:return["translateX(-2%)","translateX(0%)"];case W.Replace:return}});r.$view.content(r.nextContent),r.rendered(),(a=r.nextContent.element)==null||a.class("animated").animate({opacity:[0,1],transform:n},{duration:300,easing:"ease"},()=>{var o;r.switched(),(o=r.nextContent.element)==null||o.removeClass("animated")})}function i(){var a,o;const n=$.call(()=>{switch(E.navigationDirection){case W.Forward:return["translateX(0%)","translateX(-2%)"];case W.Back:return["translateX(0%)","translateX(2%)"];case W.Replace:return}});(o=(a=r.previousContent)==null?void 0:a.element)==null||o.class("animated").animate({opacity:[1,0],transform:n},{duration:300,easing:"ease"},()=>{var c,h;(h=(c=r.previousContent)==null?void 0:c.element)==null||h.removeClass("animated"),s()})}r.previousContent?i():s()})]);E.events.on("stateChange",({beforeURL:r,afterURL:t})=>{ut.checkURL(r,t)}); diff --git a/dist/assets/index-DaDrA_5o.js b/dist/assets/index-DaDrA_5o.js new file mode 100644 index 0000000..b76c7d4 --- /dev/null +++ b/dist/assets/index-DaDrA_5o.js @@ -0,0 +1 @@ +var Et=Object.defineProperty;var ft=r=>{throw TypeError(r)};var Lt=(r,t,e)=>t in r?Et(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var h=(r,t,e)=>Lt(r,typeof t!="symbol"?t+"":t,e),pt=(r,t,e)=>t.has(r)||ft("Cannot "+e);var x=(r,t,e)=>(pt(r,t,"read from private field"),e?e.call(r):t.get(r)),B=(r,t,e)=>t.has(r)?ft("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(r):t.set(r,e),K=(r,t,e,s)=>(pt(r,t,"write to private field"),s?s.call(r,e):t.set(r,e),e);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))s(i);new MutationObserver(i=>{for(const n of i)if(n.type==="childList")for(const a of n.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&s(a)}).observe(document,{childList:!0,subtree:!0});function e(i){const n={};return i.integrity&&(n.integrity=i.integrity),i.referrerPolicy&&(n.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?n.credentials="include":i.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function s(i){if(i.ep)return;i.ep=!0;const n=e(i);fetch(i.href,n)}})();class G{constructor(){h(this,"__hidden",!1);h(this,"domEvents",{});h(this,"parent");h(this,"events",new et)}on(t,e,s){t=v.orArrayResolve(t);for(const i of t){this.domEvents[i]||(this.domEvents[i]=new Map);const n=a=>{e(a,this)};this.domEvents[i].set(e,n),this.events.on(i,e),this.dom.addEventListener(i,n,s)}return this}off(t,e,s){var n;const i=(n=this.domEvents[t])==null?void 0:n.get(e);return i&&this.dom.removeEventListener(t,i,s),this.events.off(t,e),this}once(t,e,s){const i=n=>{this.dom.removeEventListener(t,i,s),e(n,this)};return this.dom.addEventListener(t,i,s),this.events.once(t,e),this}hide(t,e=!0){return v.fluent(this,arguments,()=>this.__hidden,()=>{var s;if(t!==void 0)return t instanceof S?(this.__hidden=t.value,t.use(this,"hide")):this.__hidden=t,e&&((s=this.parent)==null||s.children.render()),this})}remove(){var t;return(t=this.parent)==null||t.children.remove(this).render(),this}replace(t){var e;return(e=this.parent)==null||e.children.replace(this,t).render(),this}contains(t){return t?t instanceof G?this.dom.contains(t.dom):t instanceof EventTarget?this.dom.contains(v(t).dom):this.dom.contains(t):!1}self(t){return t(this),this}inDOM(){return document.contains(this.dom)}isElement(){return this instanceof C}get element(){return this instanceof C?this:null}}class C extends G{constructor(e,s){super();h(this,"dom");h(this,"static_classes",new Set);this.dom=this.createDom(e,s),this.dom.$=this,this.setOptions(s)}createDom(e,s){return s!=null&&s.dom?s.dom:e==="svg"?document.createElementNS("http://www.w3.org/2000/svg","svg"):document.createElement((s==null?void 0:s.tagname)??e)}setOptions(e){return this.id(e==null?void 0:e.id),e&&e.class&&this.class(...e.class),this}id(e){return $.fluent(this,arguments,()=>this.dom.id,()=>$.set(this.dom,"id",e))}class(...e){return $.fluent(this,arguments,()=>this.dom.classList,()=>{this.dom.classList.forEach(s=>this.static_classes.has(s)??this.dom.classList.remove(s)),this.dom.classList.add(...e.detype())})}addClass(...e){return $.fluent(this,arguments,()=>this,()=>{this.dom.classList.add(...e.detype())})}removeClass(...e){return $.fluent(this,arguments,()=>this,()=>{this.dom.classList.remove(...e.detype())})}staticClass(...e){return $.fluent(this,arguments,()=>this.static_classes,()=>{this.removeClass(...this.static_classes),this.static_classes.clear(),this.addStaticClass(...e)})}addStaticClass(...e){return $.fluent(this,arguments,()=>this,()=>{e.detype().forEach(s=>this.static_classes.add(s)),this.addClass(...e)})}removeStaticClass(...e){return $.fluent(this,arguments,()=>this,()=>{e.detype().forEach(s=>this.static_classes.delete(s)),this.removeClass(...e)})}css(e){return $.fluent(this,arguments,()=>this.dom.style,()=>{Object.assign(this.dom.style,e)})}attribute(e,s){return arguments.length?arguments.length===1?e===void 0?null:this.dom.getAttribute(e):arguments.length===2?e?(s===null?this.dom.removeAttribute(e):s!==void 0&&this.dom.setAttribute(e,`${s}`),this):this:this:null}tabIndex(e){return $.fluent(this,arguments,()=>this.dom.tabIndex,()=>$.set(this.dom,"tabIndex",e))}focus(){return this.dom.focus(),this}blur(){return this.dom.blur(),this}animate(e,s,i){const n=this.dom.animate(e,s);return i&&(n.onfinish=()=>i(n)),n}getAnimations(e){return this.dom.getAnimations(e)}get dataset(){return this.dom.dataset}domRect(e){const s=this.dom.getBoundingClientRect();if(!e)return s;const i=e instanceof C?e.dom.getBoundingClientRect():e;return{...s,top:s.top-i.top,left:s.left-i.left,right:s.right-i.left,bottom:s.bottom-i.top,x:s.x-i.x,y:s.y-i.y}}}class J extends G{constructor(e){super();h(this,"dom");this.dom=e,this.dom.$=this}domRect(e){const s={bottom:innerHeight,height:innerHeight,left:0,right:innerWidth,top:0,width:innerWidth,x:0,y:0};if(!e)return s;const i=e instanceof C?e.dom.getBoundingClientRect():e;return{...s,top:s.top-i.top,left:s.left-i.left,right:s.right-i.left,bottom:s.bottom-i.top,x:s.x-i.x,y:s.y-i.y}}static from(e){return e.$ instanceof J?e.$:new J(e)}}const At="modulepreload",Pt=function(r){return"/"+r},gt={},Mt=function(t,e,s){let i=Promise.resolve();if(e&&e.length>0){document.getElementsByTagName("link");const a=document.querySelector("meta[property=csp-nonce]"),o=(a==null?void 0:a.nonce)||(a==null?void 0:a.getAttribute("nonce"));i=Promise.allSettled(e.map(u=>{if(u=Pt(u),u in gt)return;gt[u]=!0;const c=u.endsWith(".css"),d=c?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${u}"]${d}`))return;const m=document.createElement("link");if(m.rel=c?"stylesheet":At,c||(m.as="script"),m.crossOrigin="",m.href=u,o&&m.setAttribute("nonce",o),document.head.appendChild(m),c)return new Promise((b,l)=>{m.addEventListener("load",b),m.addEventListener("error",()=>l(new Error(`Unable to preload CSS for ${u}`)))})}))}function n(a){const o=new Event("vite:preloadError",{cancelable:!0});if(o.payload=a,window.dispatchEvent(o),!o.defaultPrevented)throw a}return i.then(a=>{for(const o of a||[])o.status==="rejected"&&n(o.reason);return t().catch(n)})};class Ct{constructor(t){h(this,"$container");h(this,"childList",new Set);this.$container=t}add(t,e=-1){if(e===-1||this.childList.size-1===e)this.childList.add(t);else{const s=[...this.childList];s.splice(e,0,t),this.childList.clear(),s.forEach(i=>this.childList.add(i))}t.parent=this.$container}remove(t){return this.childList.has(t)?(this.childList.delete(t),t.parent=void 0,this):this}removeAll(t=!0){this.childList.forEach(e=>this.remove(e)),t&&this.render()}replace(t,e){const s=this.array;return s.splice(s.indexOf(t),1,e),t.remove(),this.childList.clear(),s.forEach(i=>this.childList.add(i)),e.parent=this.$container,this}render(){const[t,e]=[this.array.map(i=>i.dom),Array.from(this.dom.childNodes)],s=[];for(;e.length||t.length;){const[i,n]=[e.at(0),t.at(0)];n?i?n!==i?(n.$.__hidden||(this.dom.insertBefore(n,i),s.push(n)),t.shift()):(n.$.__hidden&&this.dom.removeChild(n),t.shift(),e.shift()):(n.$.__hidden||this.dom.append(n),t.shift()):(i&&!s.includes(i)&&i.remove(),e.shift())}}indexOf(t){return this.array.indexOf(t)}get array(){return[...this.childList.values()]}get dom(){return this.$container.dom}}class S{constructor(t,e){h(this,"_value");h(this,"attributes",new Map);h(this,"linkStates",new Set);h(this,"options",{});this.set(t),e&&(this.options=e)}set(t){this._value=t,t instanceof S&&t.linkStates.add(this),this.update(),this.linkStates.forEach(e=>e.update())}static toJSON(t){const e={};for(let[s,i]of Object.entries(t))i instanceof S?i=i.toJSON():i instanceof Object&&S.toJSON(i),Object.assign(e,{[s]:i});return e}update(){for(const[t,e]of this.attributes.entries())for(const s of e)t[s]instanceof Function?this.options.format?t[s](this.options.format(this.value)):t[s](this.value):s in t&&(t[s]=this.value)}use(t,e){const s=this.attributes.get(t);s?s.add(e):this.attributes.set(t,new Set().add(e))}convert(t){return new S(this,{format:t})}get value(){return this._value instanceof S?this._value.value:this._value}toString(){return this.options.format?this.options.format(this.value):this.value instanceof Object?JSON.stringify(this.toJSON()):`${this.value}`}toJSON(){return this.value instanceof S?this.value.toJSON():this.value instanceof Object?S.toJSON(this.value):this.toString()}}class z extends G{constructor(e){super();h(this,"dom");this.dom=new Text(e),this.dom.$=this}content(e){return $.fluent(this,arguments,()=>this.dom.textContent,()=>$.set(this.dom,"textContent",e))}}class Q extends C{constructor(t,e){super(t,e)}autocapitalize(t){return $.fluent(this,arguments,()=>this.dom.autocapitalize,()=>$.set(this.dom,"autocapitalize",t))}innerText(t){return $.fluent(this,arguments,()=>this.dom.innerText,()=>$.set(this.dom,"innerText",t))}title(t){return $.fluent(this,arguments,()=>this.dom.title,()=>$.set(this.dom,"title",t))}dir(t){return $.fluent(this,arguments,()=>this.dom.dir,()=>$.set(this.dom,"dir",t))}translate(t){return $.fluent(this,arguments,()=>this.dom.translate,()=>$.set(this.dom,"translate",t))}popover(t){return $.fluent(this,arguments,()=>this.dom.popover,()=>$.set(this.dom,"popover",t))}spellcheck(t){return $.fluent(this,arguments,()=>this.dom.spellcheck,()=>$.set(this.dom,"spellcheck",t))}inert(t){return $.fluent(this,arguments,()=>this.dom.inert,()=>$.set(this.dom,"inert",t))}lang(t){return $.fluent(this,arguments,()=>this.dom.lang,()=>$.set(this.dom,"lang",t))}draggable(t){return $.fluent(this,arguments,()=>this.dom.draggable,()=>$.set(this.dom,"draggable",t))}hidden(t){return $.fluent(this,arguments,()=>this.dom.hidden,()=>$.set(this.dom,"hidden",t))}click(){return this.dom.click(),this}attachInternals(){return this.dom.attachInternals()}hidePopover(){return this.dom.hidePopover(),this}showPopover(){return this.dom.showPopover(),this}togglePopover(){return this.dom.togglePopover(),this}get accessKeyLabel(){return this.dom.accessKeyLabel}get offsetHeight(){return this.dom.offsetHeight}get offsetLeft(){return this.dom.offsetLeft}get offsetParent(){return $(this.dom.offsetParent)}get offsetTop(){return this.dom.offsetTop}get offsetWidth(){return this.dom.offsetWidth}}class f extends Q{constructor(e,s){super(e,s);h(this,"children",new Ct(this));h(this,"__position_cursor",0)}content(e){return $.fluent(this,arguments,()=>this,()=>{this.children.removeAll(!1),this.insert(e)})}insert(e,s=-1){return $.fluent(this,arguments,()=>this,async()=>{if(e instanceof Function){let i=e(this);i instanceof Promise?e=await i:e=i}else e instanceof Promise&&(e=await e);e=$.orArrayResolve(e),this.__position_cursor=s<0?this.children.array.length+s:s;for(const i of e)if(i!=null){if(i instanceof Array)this.insert(i,this.__position_cursor);else if(typeof i=="string")this.children.add(new z(i),s);else if(i instanceof S){const n=new z(i.toString());i.use(n,"content"),this.children.add(n,s)}else if(i instanceof Promise){const n=(await Mt(async()=>{const{$Async:o}=await Promise.resolve().then(()=>Ut);return{$Async:o}},void 0)).$Async,a=new n().await(i);this.children.add(a,s)}else this.children.add(i,s);this.__position_cursor+=1}this.children.render()})}clear(){return this.children.removeAll(),this}$(e){return $(this.dom.querySelector(e))}$all(e){return Array.from(this.dom.querySelectorAll(e)).map(s=>$(s))}get scrollHeight(){return this.dom.scrollHeight}get scrollWidth(){return this.dom.scrollWidth}scrollTop(e){return $.fluent(this,arguments,()=>this.dom.scrollTop,()=>$.set(this.dom,"scrollTop",e))}scrollLeft(e){return $.fluent(this,arguments,()=>this.dom.scrollLeft,()=>$.set(this.dom,"scrollLeft",e))}}class Rt extends f{constructor(t){super("a",t),this.dom.addEventListener("click",e=>{$.anchorHandler&&this.href()&&(e.preventDefault(),$.anchorHandler(this,e))})}href(t){return $.fluent(this,arguments,()=>this.dom.href,()=>$.set(this.dom,"href",t))}target(t){return $.fluent(this,arguments,()=>this.dom.target??void 0,()=>{t&&(this.dom.target=t)})}}class kt extends C{constructor(t,e){super(t,e)}}var I;(r=>{function t(o,u,c,d){return u.length?(d(),o):c()}r.fluent=t;function e(o){return o instanceof Array?o:[o]}r.orArrayResolve=e;function s(o,u){return e(u).forEach(c=>{Object.getOwnPropertyNames(c.prototype).forEach(d=>{d!=="constructor"&&Object.defineProperty(o.prototype,d,Object.getOwnPropertyDescriptor(c.prototype,d)||Object.create(null))})}),o}r.mixin=s;function i(o,u,c){c!==void 0&&(o[u]=c)}r.set=i;function n(o){return new S(o)}r.state=n;function a(o){if(o.$)return o.$;if(o.nodeName.toLowerCase()==="body")return new f("body",{dom:o});if(o.nodeName.toLowerCase()==="#document")return J.from(o);if(o instanceof HTMLElement){const u=$.TagNameElementMap[o.tagName.toLowerCase()],c=u===f?new u(o.tagName,{dom:o}):new u({dom:o});if(c instanceof f)for(const d of Array.from(c.dom.childNodes))c.children.add($(d));return c}else if(o instanceof Text){const u=new z(o.textContent??"");return u.dom=o,u}else if(o instanceof SVGElement&&o.tagName.toLowerCase()==="svg")return new kt("svg",{dom:o});throw`$NODE.FROM: NOT SUPPORT TARGET ELEMENT TYPE (${o.nodeName})`}r.from=a})(I||(I={}));class A{static create(...t){const e=class{};return Object.getOwnPropertyNames(A.prototype).forEach(s=>{s!=="constructor"&&t.includes(s)&&Object.defineProperty(e.prototype,s,Object.getOwnPropertyDescriptor(A.prototype,s)||Object.create(null))}),e}disabled(t){return $.fluent(this,arguments,()=>this.dom.disabled,()=>$.set(this.dom,"disabled",t))}checkValidity(){return this.dom.checkValidity()}reportValidity(){return this.dom.reportValidity()}formAction(t){return $.fluent(this,arguments,()=>this.dom.formAction,()=>$.set(this.dom,"formAction",t))}formEnctype(t){return $.fluent(this,arguments,()=>this.dom.formEnctype,()=>$.set(this.dom,"formEnctype",t))}formMethod(t){return $.fluent(this,arguments,()=>this.dom.formMethod,()=>$.set(this.dom,"formMethod",t))}formNoValidate(t){return $.fluent(this,arguments,()=>this.dom.formNoValidate,()=>$.set(this.dom,"formNoValidate",t))}formTarget(t){return $.fluent(this,arguments,()=>this.dom.formTarget,()=>$.set(this.dom,"formTarget",t))}autocomplete(t){return $.fluent(this,arguments,()=>this.dom.autocomplete,()=>$.set(this.dom,"autocomplete",t))}name(t){return $.fluent(this,arguments,()=>this.dom.name,()=>$.set(this.dom,"name",t))}maxLength(t){return $.fluent(this,arguments,()=>this.dom.maxLength,()=>$.set(this.dom,"maxLength",t))}minLength(t){return $.fluent(this,arguments,()=>this.dom.minLength,()=>$.set(this.dom,"minLength",t))}required(t){return $.fluent(this,arguments,()=>this.dom.required,()=>$.set(this.dom,"required",t))}label(t){return $.fluent(this,arguments,()=>this.dom.label,()=>$.set(this.dom,"label",t))}get form(){return this.dom.form?$(this.dom.form):null}get validationMessage(){return this.dom.validationMessage}get validity(){return this.dom.validity}get willValidate(){return this.dom.willValidate}}class ht extends f{constructor(t){super("button",t)}type(t){return $.fluent(this,arguments,()=>this.dom.type,()=>$.set(this.dom,"type",t))}}I.mixin(ht,A.create("disabled","checkValidity","formAction","formEnctype","formMethod","formNoValidate","formTarget","reportValidity"));class yt extends f{constructor(t){super("form",t)}action(t){return $.fluent(this,arguments,()=>this.dom.formAction,()=>$.set(this.dom,"formAction",t))}enctype(t){return $.fluent(this,arguments,()=>this.dom.formEnctype,()=>$.set(this.dom,"formEnctype",t))}method(t){return $.fluent(this,arguments,()=>this.dom.formMethod,()=>$.set(this.dom,"formMethod",t))}noValidate(t){return $.fluent(this,arguments,()=>this.dom.formNoValidate,()=>$.set(this.dom,"formNoValidate",t))}acceptCharset(t){return $.fluent(this,arguments,()=>this.dom.acceptCharset,()=>$.set(this.dom,"acceptCharset",t))}target(t){return $.fluent(this,arguments,()=>this.dom.formTarget,()=>$.set(this.dom,"formTarget",t))}requestSubmit(){return this.dom.requestSubmit(),this}reset(){return this.dom.reset(),this}submit(){return this.dom.submit(),this}get length(){return this.dom.length}get elements(){return Array.from(this.dom.elements).map(t=>$(t))}}I.mixin(yt,A.create("checkValidity","reportValidity","autocomplete"));class k extends Q{constructor(t){super("input",t)}value(t){return $.fluent(this,arguments,()=>this.type()==="number"?Number(this.dom.value):this.dom.value,()=>$.set(this.dom,"value",t,e=>{this.on("input",()=>{e.attributes.has(this.dom)!==!1&&(typeof e.value=="string"&&e.set(`${this.value()}`),typeof e.value=="number"&&e.set(Number(this.value())))})}))}type(t){return $.fluent(this,arguments,()=>this.dom.type,()=>$.set(this.dom,"type",t))}capture(t){return $.fluent(this,arguments,()=>this.dom.capture,()=>$.set(this.dom,"capture",t))}alt(t){return $.fluent(this,arguments,()=>this.dom.alt,()=>$.set(this.dom,"alt",t))}height(t){return $.fluent(this,arguments,()=>this.dom.height,()=>$.set(this.dom,"height",t))}width(t){return $.fluent(this,arguments,()=>this.dom.width,()=>$.set(this.dom,"width",t))}defaultValue(t){return $.fluent(this,arguments,()=>this.dom.defaultValue,()=>$.set(this.dom,"defaultValue",t))}dirName(t){return $.fluent(this,arguments,()=>this.dom.dirName,()=>$.set(this.dom,"dirName",t))}pattern(t){return $.fluent(this,arguments,()=>this.dom.pattern,()=>$.set(this.dom,"pattern",t))}placeholder(t){return $.fluent(this,arguments,()=>this.dom.placeholder,()=>$.set(this.dom,"placeholder",t))}readOnly(t){return $.fluent(this,arguments,()=>this.dom.readOnly,()=>$.set(this.dom,"readOnly",t))}selectionDirection(t){return $.fluent(this,arguments,()=>this.dom.selectionDirection,()=>$.set(this.dom,"selectionDirection",t))}selectionEnd(t){return $.fluent(this,arguments,()=>this.dom.selectionEnd,()=>$.set(this.dom,"selectionEnd",t))}selectionStart(t){return $.fluent(this,arguments,()=>this.dom.selectionStart,()=>$.set(this.dom,"selectionStart",t))}size(t){return $.fluent(this,arguments,()=>this.dom.size,()=>$.set(this.dom,"size",t))}src(t){return $.fluent(this,arguments,()=>this.dom.src,()=>$.set(this.dom,"src",t))}inputMode(t){return $.fluent(this,arguments,()=>this.dom.inputMode,()=>$.set(this.dom,"inputMode",t))}valueAsDate(t){return $.fluent(this,arguments,()=>this.dom.valueAsDate,()=>$.set(this.dom,"valueAsDate",t))}valueAsNumber(t){return $.fluent(this,arguments,()=>this.dom.valueAsNumber,()=>$.set(this.dom,"valueAsNumber",t))}webkitdirectory(t){return $.fluent(this,arguments,()=>this.dom.webkitdirectory,()=>$.set(this.dom,"webkitdirectory",t))}select(){return this.dom.select(),this}setCustomValidity(t){return this.dom.setCustomValidity(t),this}setRangeText(t,e,s,i){return typeof e=="number"&&typeof s=="number"&&this.dom.setRangeText(t,e,s,i),this.dom.setRangeText(t),this}setSelectionRange(t,e,s){return this.dom.setSelectionRange(t,e,s),this}showPicker(){return this.dom.showPicker(),this}get files(){return this.dom.files}get webkitEntries(){return this.dom.webkitEntries}get labels(){return Array.from(this.dom.labels??[]).map(t=>$(t))}}I.mixin(k,A.create("checkValidity","reportValidity","autocomplete","name","form","required","validationMessage","validity","willValidate","formAction","formEnctype","formMethod","formNoValidate","formTarget"));class Nt extends k{constructor(t){super(t),this.type("number")}static from(t){return $.mixin(k,this)}stepDown(){return this.dom.stepDown(),this}stepUp(){return this.dom.stepUp(),this}max(t){return $.fluent(this,arguments,()=>this.dom.max===""?null:parseInt(this.dom.min),()=>$.set(this.dom,"max",t==null?void 0:t.toString()))}min(t){return $.fluent(this,arguments,()=>this.dom.min===""?null:parseInt(this.dom.min),()=>$.set(this.dom,"min",t==null?void 0:t.toString()))}step(t){return $.fluent(this,arguments,()=>Number(this.dom.step),()=>$.set(this.dom,"step",t==null?void 0:t.toString()))}}class Ht extends k{constructor(t){super(t),this.type("radio")}static from(t){return $.mixin(k,this)}checked(t){return $.fluent(this,arguments,()=>this.dom.checked,()=>$.set(this.dom,"checked",t))}defaultChecked(t){return $.fluent(this,arguments,()=>this.dom.defaultChecked,()=>$.set(this.dom,"defaultChecked",t))}}class Dt extends k{constructor(t){super(t),this.type("file")}static from(t){return $.mixin(k,this)}multiple(t){return $.fluent(this,arguments,()=>this.dom.multiple,()=>$.set(this.dom,"multiple",t))}accept(...t){return $.fluent(this,arguments,()=>this.dom.accept.split(","),()=>this.dom.accept=t.toString())}}I.mixin(k,[Nt,Ht,Dt]);class vt extends f{constructor(t){super("label",t)}for(t){return $.fluent(this,arguments,()=>this.dom.htmlFor,()=>{$.set(this.dom,"htmlFor",t)})}get control(){return this.dom.control}}I.mixin(vt,A.create("form"));class Vt extends Q{constructor(t){super("img",t)}async load(t){return new Promise(e=>{const s=this.once("load",()=>{e(s)});typeof t=="string"?s.src(t):t.then(i=>s.src(i))})}static resize(t,e){return new Promise(s=>{const i=new Image;if(i.addEventListener("load",()=>{const n=document.createElement("canvas"),a=n.getContext("2d");if(!a)throw"$Image.resize: context undefined";const o=i.width/i.height,[u,c,d]=[o>1,o<1,o===1],m=e instanceof Array?e[0]:c?e:e*o,b=e instanceof Array?e[1]:u?e:e/o;n.height=b,n.width=m,a.drawImage(i,0,0,m,b),s(n.toDataURL())},{once:!0}),t instanceof File){const n=new FileReader;n.addEventListener("load",()=>i.src=n.result),n.readAsDataURL(t)}else i.src=t})}alt(t){return $.fluent(this,arguments,()=>this.dom.alt,()=>$.set(this.dom,"alt",t))}crossOrigin(t){return $.fluent(this,arguments,()=>this.dom.crossOrigin,()=>$.set(this.dom,"crossOrigin",t))}decoding(t){return $.fluent(this,arguments,()=>this.dom.decoding,()=>$.set(this.dom,"decoding",t))}height(t){return $.fluent(this,arguments,()=>this.dom.height,()=>$.set(this.dom,"height",t))}isMap(t){return $.fluent(this,arguments,()=>this.dom.isMap,()=>$.set(this.dom,"isMap",t))}loading(t){return $.fluent(this,arguments,()=>this.dom.loading,()=>$.set(this.dom,"loading",t))}referrerPolicy(t){return $.fluent(this,arguments,()=>this.dom.referrerPolicy,()=>$.set(this.dom,"referrerPolicy",t))}sizes(t){return $.fluent(this,arguments,()=>this.dom.sizes,()=>$.set(this.dom,"sizes",t))}src(t){return $.fluent(this,arguments,()=>this.dom.src,()=>$.set(this.dom,"src",t))}srcset(t){return $.fluent(this,arguments,()=>this.dom.srcset,()=>$.set(this.dom,"srcset",t))}useMap(t){return $.fluent(this,arguments,()=>this.dom.useMap,()=>$.set(this.dom,"useMap",t))}width(t){return $.fluent(this,arguments,()=>this.dom.width,()=>$.set(this.dom,"width",t))}decode(){return this.dom.decode()}get complete(){return this.dom.complete}get currentSrc(){return this.dom.currentSrc}get naturalHeight(){return this.dom.naturalHeight}get naturalWidth(){return this.dom.naturalWidth}get x(){return this.dom.x}get y(){return this.dom.y}}class jt extends f{constructor(t){super("canvas",t)}height(t){return $.fluent(this,arguments,()=>this.dom.height,()=>{$.set(this.dom,"height",t)})}width(t){return $.fluent(this,arguments,()=>this.dom.width,()=>{$.set(this.dom,"width",t)})}captureStream(t){return this.dom.captureStream(t)}getContext(t,e){return this.dom.getContext(t)}toBlob(t,e,s){return this.dom.toBlob(t,e,s),this}toDataURL(t,e){return this.dom.toDataURL(t,e)}transferControlToOffscreen(){return this.dom.transferControlToOffscreen()}}class Wt extends f{constructor(t){super("dialog",t)}open(t){return $.fluent(this,arguments,()=>this.dom.open,()=>$.set(this.dom,"open",t))}returnValue(t){return $.fluent(this,arguments,()=>this.dom.returnValue,()=>$.set(this.dom,"returnValue",t))}close(){return this.dom.close(),this}show(){return this.dom.show(),this}showModal(){return this.dom.showModal(),this}}class wt extends f{constructor(t){super("select")}add(t){return this.insert(t),this}item(t){return $(this.dom.item(t))}namedItem(t){return $(this.dom.namedItem(t))}multiple(t){return $.fluent(this,arguments,()=>this.dom.multiple,()=>$.set(this.dom,"multiple",t))}get length(){return this.dom.length}get size(){return this.dom.size}get options(){return Array.from(this.dom.options).map(t=>$(t))}get selectedIndex(){return this.dom.selectedIndex}get selectedOptions(){return Array.from(this.dom.selectedOptions).map(t=>$(t))}value(t){return $.fluent(this,arguments,()=>this.dom.value,()=>$.set(this.dom,"value",t,e=>{this.on("input",()=>{e.attributes.has(this.dom)!==!1&&(typeof e.value=="string"&&e.set(`${this.value()}`),typeof e.value=="number"&&e.set(Number(this.value())))})}))}get labels(){return Array.from(this.dom.labels??[]).map(t=>$(t))}}I.mixin(wt,A.create("checkValidity","reportValidity","autocomplete","name","form","required","disabled","validationMessage","validity","willValidate"));class bt extends f{constructor(t){super("option",t)}defaultSelected(t){return $.fluent(this,arguments,()=>this.dom.defaultSelected,()=>$.set(this.dom,"defaultSelected",t))}selected(t){return $.fluent(this,arguments,()=>this.dom.selected,()=>$.set(this.dom,"selected",t))}text(t){return $.fluent(this,arguments,()=>this.dom.text,()=>$.set(this.dom,"text",t))}value(t){return $.fluent(this,arguments,()=>this.dom.value,()=>$.set(this.dom,"value",t))}get form(){return this.dom.form?$(this.dom.form):null}get index(){return this.dom.index}}I.mixin(bt,A.create("form","disabled","label"));class Tt extends f{constructor(t){super("optgroup",t)}disabled(t){return $.fluent(this,arguments,()=>this.dom.disabled,()=>$.set(this.dom,"disabled",t))}}I.mixin(Tt,A.create("disabled","label"));class _t extends f{constructor(t){super("textarea",t)}cols(t){return $.fluent(this,arguments,()=>this.dom.cols,()=>$.set(this.dom,"cols",t))}wrap(t){return $.fluent(this,arguments,()=>this.dom.wrap,()=>$.set(this.dom,"wrap",t))}value(t){return $.fluent(this,arguments,()=>this.dom.value,()=>$.set(this.dom,"value",t))}defaultValue(t){return $.fluent(this,arguments,()=>this.dom.defaultValue,()=>$.set(this.dom,"defaultValue",t))}dirName(t){return $.fluent(this,arguments,()=>this.dom.dirName,()=>$.set(this.dom,"dirName",t))}placeholder(t){return $.fluent(this,arguments,()=>this.dom.placeholder,()=>$.set(this.dom,"placeholder",t))}readOnly(t){return $.fluent(this,arguments,()=>this.dom.readOnly,()=>$.set(this.dom,"readOnly",t))}selectionDirection(t){return $.fluent(this,arguments,()=>this.dom.selectionDirection,()=>$.set(this.dom,"selectionDirection",t))}selectionEnd(t){return $.fluent(this,arguments,()=>this.dom.selectionEnd,()=>$.set(this.dom,"selectionEnd",t))}selectionStart(t){return $.fluent(this,arguments,()=>this.dom.selectionStart,()=>$.set(this.dom,"selectionStart",t))}type(t){return $.fluent(this,arguments,()=>this.dom.type,()=>$.set(this.dom,"type",t))}inputMode(t){return $.fluent(this,arguments,()=>this.dom.inputMode,()=>$.set(this.dom,"inputMode",t))}select(){return this.dom.select(),this}setCustomValidity(t){return this.dom.setCustomValidity(t),this}setRangeText(t,e,s,i){return typeof e=="number"&&typeof s=="number"&&this.dom.setRangeText(t,e,s,i),this.dom.setRangeText(t),this}setSelectionRange(t,e,s){return this.dom.setSelectionRange(t,e,s),this}get labels(){return Array.from(this.dom.labels??[]).map(t=>$(t))}}I.mixin(_t,A.create("checkValidity","reportValidity","autocomplete","name","form","required","disabled","minLength","maxLength","validationMessage","validity","willValidate"));var tt;class St extends f{constructor(e){super("async",e);B(this,tt,!1)}await(e){return e instanceof Function?e(this).then(s=>this._loaded(s)):e.then(s=>this._loaded(s)),this}_loaded(e){if(K(this,tt,!0),typeof e=="string")this.replace(new z(e));else if(e instanceof S){const s=new z(e.toString());e.use(s,"content"),this.replace(s)}else e==null?this.replace(new z(String(e))):this.replace(e);this.dom.dispatchEvent(new Event("load"))}get loaded(){return x(this,tt)}}tt=new WeakMap;const Ut=Object.freeze(Object.defineProperty({__proto__:null,$Async:St},Symbol.toStringTag,{value:"Module"}));class Ft extends C{constructor(t,e){super(t,e)}autoplay(t){return $.fluent(this,arguments,()=>this.dom.autoplay,()=>$.set(this.dom,"autoplay",t))}get buffered(){return this.dom.buffered}controls(t){return $.fluent(this,arguments,()=>this.dom.controls,()=>$.set(this.dom,"controls",t))}crossOrigin(t){return $.fluent(this,arguments,()=>this.dom.crossOrigin,()=>$.set(this.dom,"crossOrigin",t))}get currentSrc(){return this.dom.currentSrc}currentTime(t){return $.fluent(this,arguments,()=>this.dom.currentTime,()=>$.set(this.dom,"currentTime",t))}defaultMuted(t){return $.fluent(this,arguments,()=>this.dom.defaultMuted,()=>$.set(this.dom,"defaultMuted",t))}defaultPlaybackRate(t){return $.fluent(this,arguments,()=>this.dom.defaultPlaybackRate,()=>$.set(this.dom,"defaultPlaybackRate",t))}disableRemotePlayback(t){return $.fluent(this,arguments,()=>this.dom.disableRemotePlayback,()=>$.set(this.dom,"disableRemotePlayback",t))}get duration(){return this.dom.duration}get ended(){return this.dom.ended}get error(){return this.dom.error}loop(t){return $.fluent(this,arguments,()=>this.dom.loop,()=>$.set(this.dom,"loop",t))}mediaKeys(t){return $.fluent(this,arguments,()=>this.dom.mediaKeys,()=>$.set(this.dom,"setMediaKeys",[t]))}muted(t){return $.fluent(this,arguments,()=>this.dom.muted,()=>$.set(this.dom,"muted",t))}get networkState(){return this.dom.networkState}get paused(){return this.dom.paused}playbackRate(t){return $.fluent(this,arguments,()=>this.dom.playbackRate,()=>$.set(this.dom,"playbackRate",t))}get played(){return this.dom.played}preload(t){return $.fluent(this,arguments,()=>this.dom.preload,()=>$.set(this.dom,"preload",t))}preservesPitch(t){return $.fluent(this,arguments,()=>this.dom.preservesPitch,()=>$.set(this.dom,"preservesPitch",t))}get readyState(){return this.dom.readyState}get remote(){return this.dom.remote}get seekable(){return this.dom.seekable}get seeking(){return this.dom.seeking}sinkId(t){return $.fluent(this,arguments,()=>this.dom.sinkId,()=>$.set(this.dom,"setSinkId",[t]))}src(t){return $.fluent(this,arguments,()=>this.dom.src,()=>$.set(this.dom,"src",t))}srcObject(t){return $.fluent(this,arguments,()=>this.dom.srcObject,()=>$.set(this.dom,"srcObject",t))}get textTracks(){return this.dom.textTracks}volume(t){return $.fluent(this,arguments,()=>this.dom.volume,()=>$.set(this.dom,"volume",t))}addTextTrack(t,e,s){return this.dom.addTextTrack(t,e,s)}canPlayType(t){return this.dom.canPlayType(t)}fastSeek(t){return this.dom.fastSeek(t),this}load(){return this.dom.load(),this}pause(){return this.dom.pause(),this}async play(){return await this.dom.play(),this}get isPlaying(){return this.currentTime()>0&&!this.paused&&!this.ended&&this.readyState>2}}class Gt extends Ft{constructor(t){super("video",t)}disablePictureInPicture(t){return $.fluent(this,arguments,()=>this.dom.disablePictureInPicture,()=>$.set(this.dom,"disablePictureInPicture",t))}height(t){return $.fluent(this,arguments,()=>this.dom.height,()=>$.set(this.dom,"height",t))}width(t){return $.fluent(this,arguments,()=>this.dom.width,()=>$.set(this.dom,"width",t))}playsInline(t){return $.fluent(this,arguments,()=>this.dom.playsInline,()=>$.set(this.dom,"playsInline",t))}poster(t){return $.fluent(this,arguments,()=>this.dom.poster,()=>$.set(this.dom,"poster",t))}get videoHeight(){return this.dom.videoHeight}get videoWidth(){return this.dom.videoWidth}cancelVideoFrameCallback(t){return this.dom.cancelVideoFrameCallback(t),this}getVideoPlaybackQuality(){return this.dom.getVideoPlaybackQuality()}requestPictureInPicture(){return this.dom.requestPictureInPicture()}requestVideoFrameCallback(t){return this.dom.requestVideoFrameCallback(t)}}function v(r){if(typeof r>"u"||r===null||r instanceof G)return r;if(typeof r=="string"){if(r.startsWith("::"))return Array.from(document.querySelectorAll(r.replace(/^::/,""))).map(t=>v(t));if(r.startsWith(":"))return v(document.querySelector(r.replace(/^:/,"")));if(r in v.TagNameElementMap){const t=v.TagNameElementMap[r];return t===Q?new Q(r):t===f?new f(r):new t}else return new f(r)}if(r instanceof Node)return r.$?r.$:I.from(r);throw`$: NOT SUPPORT TARGET ELEMENT TYPE ('${r}')`}(r=>{r.anchorHandler=null,r.TagNameElementMap={html:f,head:f,document:J,body:f,a:Rt,p:f,pre:f,code:f,blockquote:f,strong:f,h1:f,h2:f,h3:f,h4:f,h5:f,h6:f,div:f,ol:f,ul:f,dl:f,li:f,input:k,label:vt,button:ht,form:yt,img:Vt,dialog:Wt,canvas:jt,select:wt,option:bt,optgroup:Tt,textarea:_t,video:Gt,async:St};function t(l,p,y,_){return p.length?(_(),l):y()}r.fluent=t;function e(l){return l instanceof Array?l:[l]}r.orArrayResolve=e;function s(l,p){return I.mixin(l,p)}r.mixin=s;function i(l,p,y,_){if(y!==void 0){if(y instanceof S){y.use(l,p),l[p]instanceof Function?l[p](...y.value):l[p]=y.value,_&&_(y);return}l[p]instanceof Function?l[p](...y):l[p]=y}}r.set=i;function n(l,p){return new S(l,p)}r.state=n;async function a(l,p){return new Promise(y=>{const _=new FileReader;_.onload=O=>{const T=r("img");if(T.once("load",R=>{const j=r("canvas"),W=j.getContext("2d"),N=T.height()/T.width(),[P,q]=[N>1?p/N:p,N>1?p:p*N];j.height(q).width(P),W==null||W.drawImage(T.dom,0,0,P,q),y(j.toDataURL(l.type))}),!O.target)throw"$.resize(): e.target is null";T.src(O.target.result)},_.readAsDataURL(l)})}r.resize=a;function o(l=1){return parseInt(getComputedStyle(document.documentElement).fontSize)*l}r.rem=o;function u(l){const p=new DOMParser().parseFromString(l,"text/html").body;return Array.from(p.children).map(y=>r(y))}r.html=u;function c(l,p,y){if(typeof p=="number")return Array(p).fill("").map(O=>{const T=_(l)?l[0](...l.slice(1)):r(l);return y&&y(T),T});{const O=[];for(const T of p){const R=l instanceof Function?l(...T):_(l)?l[0](...l.slice(1)):r(l);T instanceof Function?T(R):(T instanceof G||typeof T=="string")&&R.content(T),O.push(R)}return O}function _(O){return O instanceof Array&&O[0]instanceof Function}}r.builder=c;function d(l,p){return Object.assign(r.TagNameElementMap,{[l]:p}),r.TagNameElementMap}r.registerTagName=d;function m(...l){return new et}r.events=m;function b(l){return l()}r.call=b})(v||(v={}));globalThis.$=v;class et{constructor(){h(this,"eventMap",new Map)}fire(t,...e){var s;return(s=this.eventMap.get(t))==null||s.forEach(i=>i(...e)),this}on(t,e){const s=this.eventMap.get(t)??this.eventMap.set(t,new Set).get(t);return s==null||s.add(e),this}off(t,e){var s;return(s=this.eventMap.get(t))==null||s.delete(e),this}once(t,e){const s=(...n)=>{var a;(a=this.eventMap.get(t))==null||a.delete(s),e(...n)},i=this.eventMap.get(t)??this.eventMap.set(t,new Set).get(t);return i==null||i.add(s),this}}Array.prototype.detype=function(...r){return this.filter(t=>{if(r.length)for(const e of r)return typeof t!=typeof e;else return t!==void 0})};Object.defineProperties(Set.prototype,{array:{get:function(){return Array.from(this)}}});Set.prototype.sort=function(r){return this.array.sort(r)};class It extends f{constructor(e){super("layout",e);h(this,"_property",{ROW_MAX_HEIGHT:200,GAP:0,IS_RENDERING:!1,RENDER_REQUEST:!1,COLUNM:1,TYPE:"justified",ROOT:null,ITEM_PROPERTIES:new Map});this.css({display:"block",position:"relative"}),new ResizeObserver(s=>{this.inDOM()&&(this.render(),this.dom.dispatchEvent(new Event("resize")))}).observe(this.dom),document.addEventListener("scroll",s=>{s.target===this.root().dom&&this.scrollCompute()},{passive:!0}),new IntersectionObserver(s=>{this.inDOM()&&this.render()}).observe(this.dom)}type(e){return $.fluent(this,arguments,()=>this._property.TYPE,()=>$.set(this._property,"TYPE",e))}maxHeight(e){return $.fluent(this,arguments,()=>this._property.ROW_MAX_HEIGHT,()=>$.set(this._property,"ROW_MAX_HEIGHT",e))}column(e){return $.fluent(this,arguments,()=>this._property.COLUNM,()=>$.set(this._property,"COLUNM",e))}gap(e){return $.fluent(this,arguments,()=>this._property.GAP,()=>$.set(this._property,"GAP",e))}root(e){return $.fluent(this,arguments,()=>this._property.ROOT??$(document),()=>$.set(this._property,"ROOT",e))}get COL_WIDTH(){return(this.offsetWidth-this._property.GAP*(this._property.COLUNM-1))/this._property.COLUNM}justifiedCompute(){const e=[],s=this.offsetWidth;for(const i of this.children.array){const n=$(i);if(!(n instanceof C))continue;const a=n.attribute("layout-item-ratio"),o=a?parseFloat(a):n.dom.offsetWidth/n.dom.offsetHeight,u={$node:n,ratio:o};let c=e.at(-1);(!c||c.heightd+=l.ratio);const m=d+o,b=(s-this._property.GAP*c.items.length)/m;c.items.push(u),c.ratio=m,c.height=b}return e}waterfallCompute(){const e=[],s=this.COL_WIDTH,i=()=>{if(e.lengthn.height-a.height)[0]};for(const n of this.children.array){const a=$(n);if(!(a instanceof C))continue;const o=a.attribute("layout-item-ratio"),u=o?parseFloat(o):a.dom.offsetWidth/a.dom.offsetHeight,c={$node:a,ratio:u},d=i();let m=0;d.items.forEach(p=>m+=p.ratio);const b=s/(d.height+s/u),l=s/b;d.items.push(c),d.ratio=b,d.height=l}return e}render(){if(!this.inDOM())return this;if(this._property.ITEM_PROPERTIES.clear(),this._property.TYPE==="justified"){const e=this.justifiedCompute();let s=0;for(const i of e){let n=0;i.height>this._property.ROW_MAX_HEIGHT&&(i.height=this._property.ROW_MAX_HEIGHT);for(const a of i.items){const o=a.ratio*i.height;a.$node.css({position:"absolute",height:`${i.height}px`,width:`${o}px`,top:`${s}px`,left:`${n}px`}),a.$node.attribute("layout-item-ratio",a.ratio),this._property.ITEM_PROPERTIES.set(a.$node,{height:i.height,width:o,top:s,left:n,ratio:a.ratio,$node:a.$node}),n+=i.height*a.ratio+this._property.GAP}s+=i.height+this._property.GAP}this.css({height:`${s}px`})}else if(this._property.TYPE="waterfall"){const e=this.waterfallCompute(),s=this.COL_WIDTH;let i=0;for(const n of e){let a=0;for(const o of n.items){const u=s/o.ratio;o.$node.css({position:"absolute",height:`${u}px`,width:`${s}px`,top:`${a}px`,left:`${i}px`}),o.$node.attribute("layout-item-ratio",o.ratio),this._property.ITEM_PROPERTIES.set(o.$node,{height:u,width:s,top:a,left:i,ratio:o.ratio,$node:o.$node}),a+=u+this._property.GAP}i+=s+this._property.GAP}if(e.length){const n=e.sort((a,o)=>o.height-a.height)[0];this.css({height:`${n.height+n.items.length*this._property.GAP}px`})}else this.css({height:""})}return this.scrollCompute(),this}scrollCompute(){if(this.inDOM()===!1)return;const e=document.documentElement.scrollTop-this.dom.offsetTop;this._property.ITEM_PROPERTIES.forEach((s,i)=>{const n=s.top;s.top+s.height>e&&n{this.contentId=e,this.events.fire("rendered",{$view:this,previousContent:i,nextContent:s})},o=()=>{this.events.fire("afterSwitch",{$view:this,previousId:e})};return this.events.fire("beforeSwitch",{$view:this,preventDefault:()=>n=!0,targetId:e,previousContent:i,nextContent:s,switched:o,rendered:a}),n||(this.content(s),a(),o()),this}get currentContent(){if(this.contentId)return this.viewCache.get(this.contentId)}}$.registerTagName("view",Ot);var D;const g=class g extends Ot{constructor(e){super({tagname:"router",...e});B(this,D,"");h(this,"routes",new Map);g.routers.add(this)}base(e){return $.fluent(this,arguments,()=>x(this,D),()=>{K(this,D,e??x(this,D))})}map(e){e=$.orArrayResolve(e);for(const s of e)s instanceof Array?this.map(s):this.routes.set(s.path(),s);return this.resolve(),this}resolve(){return new Promise(e=>{if(!location.pathname.startsWith(x(this,D)))return e(2);const s=location.pathname.replace(x(this,D),"/").replace("//","/"),i=s.split("/").map(p=>`/${p}`),n=location.search,a=new Map(n.replace("?","").split("&").map(p=>p.split("="))),u=(()=>{const p=[];for(const[y,_]of this.routes){const O=$.orArrayResolve(y);for(const T of O){let R=0,j={},W={};const N=T.split("/").map(P=>`/${P}`);if(!(i.lengthObject.assign(W,{[mt]:a.get(mt)})),q.startsWith("/:")){R++,Object.assign(j,{[q.replace("/:","")]:i[P].replace("/","")});continue}else if(T.startsWith("#")&&T===location.hash){R++;continue}else if(q===i[P]){R++;continue}else break}p.push({deep:R,$route:_,params:j,query:W,pathId:Object.keys(W).length!==0?s+n:Object.keys(j).length!==0?s:O[0]})}}}return p.sort((y,_)=>_.deep-y.deep).at(0)})();if(!u)return e(1);const{$route:c,params:d,pathId:m,query:b}=u;if(m===this.contentId)return e(0);this.events.once("rendered",({nextContent:p,previousContent:y})=>{y==null||y.events.fire("afterShift",{$route:y}),p.events.fire("rendered",{$route:p}),e(0)});const l=this.viewCache.get(m)??c.build({params:d,query:b});this.viewCache.has(m)||this.setView(m,l),this.events.once("beforeSwitch",()=>{var p;l.events.fire("beforeShift",{$route:l}),(p=this.currentContent)==null||p.events.fire("beforeShift",{$route:this.currentContent})}),this.events.once("afterSwitch",()=>l.events.fire("afterShift",{$route:l})),this.switchView(m)})}static init(){if(!history.state||!("index"in history.state)){const e={index:g.historyIndex};history.replaceState(e,"")}else g.historyIndex=history.state.index;return g.navigationDirection=0,g.resolve(),window.addEventListener("popstate",()=>g.popstate()),window.addEventListener("scroll",()=>{this.setScrollHistory(this.historyIndex,location.href,document.documentElement.scrollTop)},{passive:!0}),history.scrollRestoration="manual",this}static open(e,s){return e===void 0?this:(e=this.urlResolver(e),e.href===this.url.href?this:e.origin!==this.url.origin?(window.open(e,s),this):(g.clearForwardScrollHistory(),g.historyIndex++,history.pushState(g.historyState,"",e),g.stateChange(0),g.resolve(),this))}static back(){return this.historyIndex--,history.back(),this.stateChange(1),this}static replace(e){return e===void 0?this:(e=this.urlResolver(e),history.replaceState(g.historyState,"",e),this.stateChange(2),this.setScrollHistory(this.historyIndex,location.href,0),g.resolve(),this)}static urlResolver(e){return e instanceof URL?e:(e.startsWith("/")&&(e=`${location.origin}${e}`),e.startsWith("#")&&(e=`${location.origin}${location.pathname}${e}`),new URL(e))}static popstate(){const e=history.state.index>g.historyIndex?0:history.state.indexe.resolve())),this.scrollRestoration(),this.setScrollHistory(this.historyIndex,location.href,document.documentElement.scrollTop)}static get historyState(){return{index:g.historyIndex}}static stateChange(e){const s=this.url,i=new URL(location.href);this.url=i,g.events.fire("stateChange",{beforeURL:s,afterURL:i,direction:e}),g.navigationDirection=e}static setScrollHistory(e,s,i){const n=this.getScrollHistory();if(!n)return sessionStorage.setItem(this.scrollHistoryKey,JSON.stringify({[e]:{url:s,value:i}}));n[e]={url:s,value:i},sessionStorage.setItem(this.scrollHistoryKey,JSON.stringify(n))}static getScrollHistory(){const e=sessionStorage.getItem(this.scrollHistoryKey);if(e)return JSON.parse(e)}static clearForwardScrollHistory(){const e=this.getScrollHistory();if(e)for(const s in e)Number(s)>this.historyIndex&&delete e[s],sessionStorage.setItem(this.scrollHistoryKey,JSON.stringify(e))}static scrollRestoration(){const e=this.getScrollHistory();if(e&&e[this.historyIndex])document.documentElement.scrollTop=e[this.historyIndex].value??0;else if(location.hash.length){const s=$(document.body).$(location.hash);s&&(document.documentElement.scrollTop=s.dom.offsetTop)}else document.documentElement.scrollTop=0}};D=new WeakMap,h(g,"routers",new Set),h(g,"events",new et),h(g,"navigationDirection"),h(g,"historyIndex",0),h(g,"url",new URL(location.href)),h(g,"scrollHistoryKey","$ROUTER_SCROLL_HISTORY");let L=g;var U=(r=>(r[r.Forward=0]="Forward",r[r.Back=1]="Back",r[r.Replace=2]="Replace",r))(U||{});L.init();var X,V;const lt=class lt extends f{constructor(e){super("route",e);B(this,X,"");B(this,V);h(this,"rendered",!1)}path(e){return $.fluent(this,arguments,()=>x(this,X),()=>K(this,X,e??x(this,X)))}builder(e){return K(this,V,e),this}render(e){return x(this,V)&&this.content(x(this,V).call(this,{$route:this,params:e.params,query:e.query})),this.rendered=!0,this}build(e){return new lt({dom:this.dom.cloneNode()}).self(s=>{x(this,V)&&s.builder(x(this,V)).render({params:e.params,query:e.query})})}};X=new WeakMap,V=new WeakMap;let ot=lt;$.registerTagName("router",L);$.registerTagName("route",ot);Object.assign($,{open(r,t){return L.open(r,t)},replace(r){return L.replace(r)},back(){return L.back()}});const H=class H{constructor(t){h(this,"posts",new Map);h(this,"tags",new Map);Object.assign(this,t),this.origin.endsWith("/")&&(this.origin=this.origin.slice(0,-1)),H.manager.set(this.name,this)}static set(t){return this.used=t,this.name$.set(t.name),this.storageAPI=t.name,this.events.fire("set"),this}static get storageAPI(){return localStorage.getItem("booru_api")}static set storageAPI(t){t?localStorage.setItem("booru_api",t):localStorage.removeItem("booru_api")}};h(H,"used"),h(H,"events",new et),h(H,"name$",$.state(H.name)),h(H,"manager",new Map);let w=H;const qt=new Intl.NumberFormat("en",{notation:"compact"});class zt{constructor(t,e){h(this,"post_count$",$.state(0,{format:t=>`${qt.format(t)}`}));h(this,"name$",$.state(""));h(this,"booru");this.booru=t,Object.assign(this,e),this.$update()}static async fetch(t,e){var n;const s=await fetch(`${t.origin}/tags/${e}.json`).then(async a=>await a.json()),i=((n=t.tags.get(s.id))==null?void 0:n.update(s))??new this(t,s);return t.tags.set(i.id,i),i}static async fetchMultiple(t,e,s=1e3){let i="";if(e)for(const[u,c]of Object.entries(e))if(c instanceof Array)i+=`&search[${u}]=${c}`;else if(c instanceof Object)for(const[d,m]of Object.entries(c))i+=`&search[${u}${d}]=${m}`;else i+=`&search[${u}]=${c}`;return(await(await fetch(`${t.origin}/tags.json?limit=${s}${i}`)).json()).map(u=>{var d;const c=((d=t.tags.get(u.id))==null?void 0:d.update(u))??new this(t,u);return t.tags.set(c.id,c),c})}update(t){return Object.assign(this,t),this.$update(),this}$update(){this.post_count$.set(this.post_count),this.name$.set(this.name)}}var F=(r=>(r[r.General=0]="General",r[r.Artist=1]="Artist",r[r.Copyright=3]="Copyright",r[r.Character=4]="Character",r[r.Meta=5]="Meta",r))(F||{});class Y{constructor(t){h(this,"name$",$.state("loding..."));Object.assign(this,t),this.update$()}static async fetch(t,e){var n;const s=await fetch(`${t.origin}/users/${e}.json`).then(async a=>await a.json()),i=((n=this.manager.get(s.id))==null?void 0:n.update(s))??new this(s);return this.manager.set(i.id,i),i}static async fetchMultiple(t,e,s=200){let i="";if(e)for(const[u,c]of Object.entries(e))if(c instanceof Array)i+=`&search[${u}]=${c}`;else if(c instanceof Object)for(const[d,m]of Object.entries(c))i+=`&search[${u}${d}]=${m}`;else i+=`&search[${u}]=${c}`;return(await(await fetch(`${t.origin}/users.json?limit=${s}${i}`)).json()).map(u=>{const c=new this(u);return this.manager.set(c.id,c),c})}update(t){return Object.assign(this,t),this.update$(),this}update$(){this.name$.set(this.name)}}h(Y,"manager",new Map);const ct=1e3,it=ct*60,rt=it*60,nt=rt*24,Xt=nt*7,st=new Intl.RelativeTimeFormat("en",{style:"long"});function Bt(r){r=Math.floor(r);const t=r/ct,e=r/it,s=r/rt,i=r/nt,n=r%1e3,a=Math.floor(r%6e4/1e3),o=Math.floor(r%36e5/6e4),u=Math.floor(r%(36e5*24)/36e5),c=a.toString().padStart(2,"0"),d=o.toString().padStart(2,"0"),m=u.toString().padStart(2,"0");return{seconds:t,minutes:e,hours:s,days:i,mil:n,s:a,min:o,h:u,ss:c,mm:d,hh:m}}function Kt(r,t=Date.now()){const e=r-t,s=Math.abs(e);if(sawait s.json());return this.update(e),Y.fetchMultiple(this.booru,{id:[this.uploader_id,this.approver_id].detype(null)}).then(()=>this.update$()),this}static async fetchMultiple(e,s,i=20){let n="";if(s){if(typeof s=="string")n=s;else for(const[d,m]of Object.entries(s))if(m!==void 0){if(d==="tags"){n+=`${m}`;continue}n.at(-1)!=="="&&(n+=" "),n+=`${d}:${m}`}}const o=await(await fetch(`${e.origin}/posts.json?limit=${i}&tags=${n}&_method=get`)).json();if(!(o instanceof Array))return[];const u=o.map(d=>{var b;const m=((b=e.posts.get(d.id))==null?void 0:b.update(d))??new this(e,d.id,d);return e.posts.set(m.id,m),m});if(!u.length)return u;const c=[...new Set(o.map(d=>[d.approver_id,d.uploader_id].detype(null)).flat())];return Y.fetchMultiple(e,{id:c}).then(()=>u.forEach(d=>d.update$())),u}update$(){var e,s,i,n;this.uploader$.set(((e=this.uploader)==null?void 0:e.name$)??((s=this.uploader_id)==null?void 0:s.toString())),this.approver$.set(((i=this.approver)==null?void 0:i.name$)??((n=this.approver_id)==null?void 0:n.toString())??"None"),this.created_date$.set(Kt(+new Date(this.created_at))),this.favorites$.set(this.fav_count),this.score$.set(this.score),this.file_size$.set(Yt(this.file_size)),this.file_ext$.set(this.file_ext),this.file_url$.set(this.file_url),this.source$.set(this.source),this.dimension$.set(`${this.image_width}x${this.image_height}`),this.url$.set(`${this.url}`),this.isUgoria&&this.webm_url$.set(this.large_file_url),this.createdDate=new Date(this.created_at),this.fire("update")}update(e){return Object.assign(this,e),this.update$(),this}async fetchTags(){return await this.ready,await zt.fetchMultiple(this.booru,{name:{_space:this.tag_string}})}get pathname(){return`/posts/${this.id}`}get uploader(){return Y.manager.get(this.uploader_id)}get approver(){return this.approver_id?Y.manager.get(this.approver_id):null}get isVideo(){return this.file_ext==="mp4"||this.file_ext==="webm"||this.file_ext==="zip"}get isGif(){return this.file_ext==="gif"}get isUgoria(){return this.file_ext==="zip"}get hasSound(){return this.tag_string_meta.includes("sound")}get tags(){const e=this.tag_string.split(" ");return[...this.booru.tags.values()].filter(s=>e.includes(s.name))}get previewURL(){var e,s;return((s=(e=this.media_asset.variants)==null?void 0:e.find(i=>i.file_ext==="webp"))==null?void 0:s.url)??this.large_file_url}get url(){return`${this.booru.origin}/posts/${this.id}`}}class xt{constructor(t){Object.assign(this,t)}static async fetch(t,e){const s=await fetch(`${t.origin}/artist_commentaries/${e}.json`);return new this(await s.json())}static async fetchMultiple(t,e,s=200){let i="";if(e)for(const[u,c]of Object.entries(e))if(c instanceof Array)i+=`&search[${u}]=${c}`;else if(c instanceof Object)for(const[d,m]of Object.entries(c))i+=`&search[${u}${d}]=${m}`;else i+=`&search[${u}]=${c}`;return(await(await fetch(`${t.origin}/artist_commentaries.json?limit=${s}${i}`)).json()).map(u=>{const c=new this(u);return this.manager.set(c.id,c),c})}}h(xt,"manager",new Map);const Jt=$("route").path("/posts/:id").id("post").builder(({$route:r,params:t})=>{if(!Number(t.id))return $("h1").content("404: POST NOT FOUND");const e=Z.get(w.used,+t.id);return[$("div").class("viewer").content(async()=>(await e.ready,e.isVideo?$("video").height(e.image_height).width(e.image_width).src(e.file_ext==="zip"?e.large_file_url:e.file_url).controls(!0).autoplay(!0).loop(!0).disablePictureInPicture(!0):$("img").src(e.large_file_url))),$("div").class("content").content([$("h3").content("Artist's Commentary"),$("section").class("commentary").content(async s=>{const i=(await xt.fetchMultiple(w.used,{post:{_id:e.id}})).at(0);return[i?[i.original_title?$("h3").content(i.original_title):null,$("pre").content(i.original_description)]:"No commentary"]})]),$("div").class("sidebar").self(s=>{let i=0;addEventListener("scroll",()=>{s.inDOM()&&(i=document.documentElement.scrollTop)},{passive:!0}),r.on("beforeShift",()=>{innerWidth>800&&s.css({position:"absolute",top:`calc(${i}px + var(--nav-height) + var(--padding))`})}).on("afterShift",()=>s.css({position:"",top:""}))}).content([$("section").class("post-info").content([new E("id").name("Post").content(`#${t.id}`),new E("uploader").name("Uploader").content(e.uploader$),new E("approver").name("Approver").content(e.approver$),new E("date").name("Date").content(e.created_date$),new E("size").name("Size").content([e.file_size$,e.dimension$]),new E("file-type").name("File Type").content(e.file_ext$),$("div").class("inline").content([new E("favorites").name("Favorites").content(e.favorites$),new E("score").name("Score").content(e.score$)]),new E("file-url").name("File").content($("a").href(e.file_url$).content(e.file_url$.convert(s=>s.replace("https://",""))).target("_blank")),new E("source-url").name("Source").content($("a").href(e.source$).content(e.source$.convert(s=>s.replace("https://",""))).target("_blank")),new E("booru-url").name(w.name$).content($("a").href(e.url$).content(e.url$.convert(s=>s.replace("https://",""))).target("_blank")),new E("booru-url").name("Webm").hide(!0).self(async s=>{await e.ready,e.isUgoria&&s.content($("a").href(e.webm_url$).content(e.webm_url$.convert(i=>i.replace("https://",""))).target("_blank")).hide(!1)})]),$("div").class("post-tags").content(async s=>{const i=await e.fetchTags(),[n,a,o,u,c]=[i.filter(m=>m.category===F.Artist),i.filter(m=>m.category===F.Character),i.filter(m=>m.category===F.General),i.filter(m=>m.category===F.Meta),i.filter(m=>m.category===F.Copyright)];return[d("Artist",n),d("Character",a),d("Copyright",c),d("Meta",u),d("General",o)];function d(m,b){return b.length?[$("h3").content(m),$("section").content([b.map(l=>$("div").class("tag").content([$("a").class("tag-name").content(l.name).href(`/posts?tags=${l.name}`),$("span").class("tag-post-count").content(l.post_count$)]))])]:null}})])]});class E extends f{constructor(e){super("div");h(this,"$name",$("span").class("property-name"));h(this,"$values",$("div").class("property-values"));this.staticClass("property").attribute("property-id",e),super.content([this.$name,this.$values.hide(!0)])}name(e){return this.$name.content(e),this}content(e){this.$values.hide(!1);const s=$.orArrayResolve(e);return this.$values.content(s.map(i=>$("span").staticClass("property-value").content(i))),this}}class Qt extends f{constructor(e){super("post-tile");h(this,"post");h(this,"$video");h(this,"duration$",$.state(""));this.post=e,this.$video=this.post.isVideo?$("video").width(this.post.image_width).height(this.post.image_height).disablePictureInPicture(!0).loop(!0).muted(!0).hide(!0).on("mousedown",s=>s.preventDefault()):null,this.attribute("filetype",this.post.file_ext),this.durationUpdate(),this.build()}build(){var s,i;let e;(s=this.$video)==null||s.on("playing",(n,a)=>{e=setInterval(()=>{this.durationUpdate()},500)}),(i=this.$video)==null||i.on("pause",()=>{clearInterval(e),this.durationUpdate()}),this.class("loading").content([this.post.isVideo?$("div").class("video-detail").content([this.post.hasSound?$("ion-icon").name("volume-medium-outline"):null,this.post.isUgoria?$("ion-icon").name("images-outline"):null,$("span").class("duration").content(this.duration$)]):null,this.post.isGif?$("div").class("gif-detail").content([$("span").content("GIF")]):null,$("a").href(this.post.pathname).content(()=>[this.$video,$("img").draggable(!1).css({opacity:"0"}).width(this.post.image_width).height(this.post.image_height).src(this.post.previewURL).loading("lazy").on("mousedown",n=>n.preventDefault()).once("load",(n,a)=>{a.src(this.post.previewURL).on(["mouseenter","touchstart"],()=>{this.post.isGif&&a.src(this.post.large_file_url)},{passive:!0}).on(["mouseleave","touchend","touchcancel"],()=>{this.post.isGif&&a.src(this.post.previewURL)},{passive:!0}).animate({opacity:[0,1]},{duration:300,fill:"both"}),this.removeClass("loading")})]).on(["mouseenter","touchstart"],()=>{var n,a;(n=this.$video)!=null&&n.isPlaying||(a=this.$video)==null||a.src(this.post.large_file_url).hide(!1).play().catch(o=>{})},{passive:!0}).on(["mouseleave","touchend","touchcancel"],()=>{var n;(n=this.$video)==null||n.pause().currentTime(0).hide(!0)},{passive:!0})])}durationUpdate(){if(!this.$video)return;const e=Bt(this.post.media_asset.duration*1e3-this.$video.currentTime()*1e3);this.duration$.set(Number(e.hh)>0?`${e.hh}:${e.mm}:${e.ss}`:`${e.mm}:${e.ss}`)}}class $t extends It{constructor(e){super();h(this,"posts",new Set);h(this,"$posts",new Set);h(this,"tags");h(this,"finished",!1);this.tags=e==null?void 0:e.tags,this.addStaticClass("post-grid"),this.type("waterfall").gap(10),this.init()}async init(){setInterval(()=>{this.inDOM()&&document.documentElement.scrollTop===0&&this.updateNewest()},1e4),w.events.on("set",()=>{this.removeAll(),this.finished&&(this.finished=!1,this.loader())}),this.on("resize",()=>this.resize()),this.loader()}async loader(){if(!this.inDOM())return setTimeout(()=>this.loader(),100);for(;this.inDOM()&&document.documentElement.scrollHeight<=innerHeight*2;)if(!(await this.getPosts()).length)return this.finished=!0;if(document.documentElement.scrollTop+innerHeight>document.documentElement.scrollHeight-innerHeight*2&&!(await this.getPosts()).length)return this.finished=!0;setTimeout(()=>this.loader(),100)}resize(){const e=Math.round(this.dom.clientWidth/300);this.column(e>=2?e:2)}addPost(e){e=$.orArrayResolve(e);for(const i of e){if(!i.file_url||this.posts.has(i))continue;const n=new Qt(i);this.$posts.add(n),this.posts.add(i)}const s=[...this.$posts.values()].sort((i,n)=>+n.post.createdDate-+i.post.createdDate);return this.content(s).render(),this}removeAll(){return this.posts.clear(),this.$posts.clear(),this.animate({opacity:[1,0]},{duration:300,easing:"ease"},()=>this.clear().render()),this}async updateNewest(){const e=this.sortedPosts.at(0),s=await Z.fetchMultiple(w.used,{tags:this.tags,id:e?`>${e.id}`:void 0},100);return this.addPost(s),s}async getPosts(){const e=this.sortedPosts.at(-1),s=await Z.fetchMultiple(w.used,{tags:this.tags,id:e?`<${e.id}`:void 0},100);return this.addPost(s),s}get sortedPosts(){return this.posts.array.sort((e,s)=>+s.createdDate-+e.createdDate)}}class Zt{static async fetch(t,e,s=20){return(await fetch(`${t.origin}/autocomplete.json?search[query]=${e}&search[type]=tag_query&version=1&limit=${s}`).then(n=>n.json())).map(n=>new te(n))}}class te{constructor(t){Object.assign(this,t)}isTag(){return this.type==="tag"||this.type==="tag-autocorrect"||this.type==="tag-alias"||this.type==="tag-word"}isTagAutocorrect(){return this.type==="tag-autocorrect"}isTagAntecedent(){return!!this.antecedent}isTagWord(){return this.type==="tag-word"}isUser(){return this.type==="user"}}class ee extends f{constructor(){super("searchbar");h(this,"$tagInput",new re(this));h(this,"$selectionList",new se);h(this,"typingTimer",null);h(this,"$filter",$("div").class("filter"));this.build(),window.addEventListener("keyup",e=>{!this.inDOM()&&e.key==="/"&&this.activate(),this.inDOM()&&e.key==="Escape"&&this.inactivate()})}build(){this.content([$("div").class("input-container").content([this.$tagInput.on("input",()=>this.inputHandler()).on("keydown",e=>this.keyHandler(e)),$("ion-icon").name("close-circle-outline").title("Clear Input").on("click",()=>this.$tagInput.clearAll())]).on("click",e=>{e.target===this.$tagInput.dom&&this.$tagInput.addTag().input()}),$("div").class("selection-list-container").content([this.$selectionList]),this.$filter.on("click",()=>{location.hash==="#search"&&$.back()})])}activate(){return this.hide(!1),this.$filter.animate({opacity:[0,.5]},{duration:300,easing:"ease"}),this.$tagInput.input(),this}inactivate(){return this.animate({opacity:[.5,0]},{duration:300,easing:"ease"},()=>this.hide(!0)),this}keyHandler(e){var n,a;const s=()=>{e.preventDefault(),this.$tagInput.addTag().input()},i=o=>{const u=this.$tagInput.children.indexOf(this.$tagInput.$inputor),c=this.$tagInput.children.array.at(u+1);this.$tagInput.addTag(o.value()),c?this.$tagInput.editTag(c):this.$tagInput.input()};switch(e.key){case"ArrowUp":{e.preventDefault(),this.$selectionList.focusPrevSelection(),this.$tagInput.value((n=this.$selectionList.focused)==null?void 0:n.value());break}case"ArrowDown":{e.preventDefault(),this.$selectionList.focusNextSelection(),this.$tagInput.value((a=this.$selectionList.focused)==null?void 0:a.value());break}case" ":s();break;case"Enter":{e.preventDefault(),this.$selectionList.focused?i(this.$selectionList.focused):(this.$tagInput.addTag(),this.search());break}case"Tab":{e.preventDefault();const o=this.$tagInput.children.indexOf(this.$tagInput.$inputor);if(e.shiftKey){this.$tagInput.editTag(this.$tagInput.children.array.at(o-1));break}if(this.$selectionList.focused)i(this.$selectionList.focused);else{const u=this.$tagInput.children.array.at(o+1);u?this.$tagInput.editTag(u):this.$tagInput.addTag().input()}break}case"Backspace":{const o=this.$tagInput.children.indexOf(this.$tagInput.$inputor);o!==0&&!this.$tagInput.$input.value().length&&(e.preventDefault(),this.$tagInput.editTag(this.$tagInput.children.array.at(o-1)));break}}}inputHandler(){this.typingTimer&&(clearTimeout(this.typingTimer),this.typingTimer=null),this.typingTimer=setTimeout(async()=>{this.typingTimer=null,this.getSearchSuggestions()},200)}async getSearchSuggestions(){const e=this.$tagInput.$input.value();if(!e.length)return this.$selectionList.clearSelections();const s=await Zt.fetch(w.used,e,20);this.$selectionList.clearSelections().addSelections(s.map(i=>new ie().value(i.value).content([$("div").class("selection-label").content([i.isTagAntecedent()?$("span").class("tag-antecedent").self(n=>n.dom.innerHTML=i.antecedent.replaceAll(e,`${e}`)):null,$("div").class("label-container").content([i.isTagAntecedent()?$("ion-icon").name("arrow-forward-outline"):null,$("span").class("label").self(n=>n.dom.innerHTML=i.label.replaceAll(e,`${e}`))])]),i.isTag()?$("div").class("tag-detail").content([$("span").class("tag-post-count").content(new Intl.NumberFormat("en",{notation:"compact"}).format(i.post_count)),$("span").class("tag-category").content(F[i.category])]):null,i.isUser()?$("span").class("user-level").content(i.level):null]).on("click",()=>{this.$tagInput.addTag(i.label).input()}))),this.$tagInput.$input.value().length||this.$selectionList.clearSelections()}search(){return $.replace(`/posts?tags=${this.$tagInput.query.replace(":","%3A")}`),this.$tagInput.clearAll(),this.inactivate(),this}checkURL(e,s){e.hash==="#search"&&this.inactivate(),s.hash==="#search"&&this.activate()}}class se extends f{constructor(){super("selection-list");h(this,"focused",null);h(this,"selections",new Set)}addSelections(e){e=$.orArrayResolve(e);for(const s of e)this.selections.add(s);return this.insert(e),this}clearSelections(){return this.focused=null,this.selections.clear(),this.clear(),this}focusSelection(e){return this.blurSelection(),this.focused=e,e.focus(),e.offsetTopthis.scrollTop()+this.offsetHeight&&this.scrollTop(e.offsetTop+e.offsetHeight-this.offsetHeight),this}blurSelection(){var e;return(e=this.focused)==null||e.blur(),this.focused=null,this}focusNextSelection(){const e=this.selections.array,s=e.at(0);if(this.focused){const i=e.at(e.indexOf(this.focused)+1);i?this.focusSelection(i):s&&this.focusSelection(s)}else s&&this.focusSelection(s)}focusPrevSelection(){const e=this.selections.array;if(this.focused){const s=e.at(e.indexOf(this.focused)-1);s&&this.focusSelection(s)}else{const s=e.at(0);s&&this.focusSelection(s)}}}class ie extends f{constructor(){super("selection");h(this,"property",{value:""})}value(e){return $.fluent(this,arguments,()=>this.property.value,()=>$.set(this.property,"value",e))}focus(){return this.addClass("active"),this}blur(){return this.removeClass("active"),this}}class re extends f{constructor(e){super("tag-input");h(this,"$input",$("input").type("text"));h(this,"$sizer",$("span").class("sizer"));h(this,"$inputor",$("div").class("input-wrapper").content([this.$sizer,this.$input.on("input",()=>{this.$sizer.content(this.$input.value())})]));h(this,"tags",new Set);h(this,"$seachbar");this.$seachbar=e}input(){return this.insert(this.$inputor),this.$input.focus(),this.$input.value()?this.$seachbar.getSearchSuggestions():this.$seachbar.$selectionList.clearSelections(),this}addTag(e){if(e=e??this.$input.value(),!e.length)return this;const s=new ne(e);return s.on("click",()=>this.editTag(s)),this.tags.add(s),this.value(""),this.$inputor.replace(s),this}editTag(e){return this.addTag(),this.tags.delete(e),e.replace(this.$inputor),this.value(e.name),this.$input.focus(),this.$seachbar.getSearchSuggestions(),this}clearAll(){return this.value(""),this.tags.clear(),this.clear(),this}value(e){return e===void 0?this:(this.$input.value(e),this.$sizer.content(e),this)}get query(){return this.tags.array.map(e=>e.name).toString().replace(",","+")}}class ne extends f{constructor(e){super("tag");h(this,"name");this.name=e,this.build()}build(){this.content(this.name)}}class oe extends f{constructor(){super("ion-icon")}name(t){return this.attribute("name",t),this}size(t){return this.attribute("size",t),this}}class ae extends ht{constructor(){super();h(this,"$icon",$("ion-icon"));h(this,"$label",$("span"));this.addStaticClass("icon"),this.build()}build(){super.content([this.$icon,this.$label])}content(e){return this.$label.content(e),this}icon(e){return this.$icon.name(e),this}}$.registerTagName("ion-icon",oe);$.registerTagName("icon-button",ae);$.anchorHandler=r=>{$.open(r.href(),r.target())};const[at,he]=[new w({origin:"https://danbooru.donmai.us",name:"Danbooru"}),new w({origin:"https://safebooru.donmai.us",name:"Safebooru"}),new w({origin:"https://testbooru.donmai.us",name:"Testbooru"})];w.set(w.manager.get(w.storageAPI??"")??at);const ut=new ee().hide(!0);location.hash==="#search"&&ut.activate();$(document.body).content([$("nav").content([$("a").class("title").href("/").content([$("h1").class("booru-name").content(w.name$),$("h2").class("app").content([$("span").class("app-name").content("Viewer"),$("span").class("version").content("v0.3.4")])]),$("div").class("searchbar").content(["Search in ",w.name$]).self(r=>L.events.on("stateChange",({beforeURL:t,afterURL:e})=>{t.hash==="#search"&&r.hide(!1),e.hash==="#search"&&r.hide(!0)})).on("click",()=>$.open(location.href+"#search")),$("div").class("buttons").content([$("ion-icon").class("search").name("search-outline").title("Search").self(r=>L.events.on("stateChange",({beforeURL:t,afterURL:e})=>{t.hash==="#search"&&r.hide(!1),e.hash==="#search"&&r.hide(!0)})).on("click",()=>$.open(location.href+"#search")),$("ion-icon").class("switch").name("swap-horizontal").title("Switch Booru").on("click",()=>{w.used===at?w.set(he):w.set(at)}),$("ion-icon").class("open").name("open-outline").title("Open in Original Site").on("click",()=>$.open(location.href.replace(location.origin,w.used.origin)))])]),ut,$("router").base("/").map([$("route").id("posts").path("/").builder(()=>new $t),$("route").id("posts").path("/posts?tags").builder(({query:r})=>new $t({tags:r.tags})),Jt]).on("beforeSwitch",r=>{r.preventDefault();function s(){var a;const n=$.call(()=>{switch(L.navigationDirection){case U.Forward:return["translateX(2%)","translateX(0%)"];case U.Back:return["translateX(-2%)","translateX(0%)"];case U.Replace:return""}});r.$view.content(r.nextContent),r.rendered(),(a=r.nextContent.element)==null||a.class("animated").animate({opacity:[0,1],transform:n},{duration:300,easing:"ease"},()=>{var o;r.switched(),(o=r.nextContent.element)==null||o.removeClass("animated")})}function i(){var a,o;const n=$.call(()=>{switch(L.navigationDirection){case U.Forward:return["translateX(0%)","translateX(-2%)"];case U.Back:return["translateX(0%)","translateX(2%)"];case U.Replace:return""}});(o=(a=r.previousContent)==null?void 0:a.element)==null||o.class("animated").animate({opacity:[1,0],transform:n},{duration:300,easing:"ease"},()=>{var u,c;(c=(u=r.previousContent)==null?void 0:u.element)==null||c.removeClass("animated"),s()})}r.previousContent?i():s()})]);L.events.on("stateChange",({beforeURL:r,afterURL:t})=>{ut.checkURL(r,t)}); diff --git a/dist/assets/index-DeBFHjT4.css b/dist/assets/index-DeBFHjT4.css new file mode 100644 index 0000000..5c00c27 --- /dev/null +++ b/dist/assets/index-DeBFHjT4.css @@ -0,0 +1 @@ +layout.post-grid{margin-top:1rem}post-tile{display:block;transition:.3s all ease;position:relative;transition:all .3s ease;border-radius:10px;overflow:hidden;-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none}@media (hover: hover){post-tile:hover{transform:scale(1.02);z-index:1;box-shadow:0 0 10px color-mix(in srgb,var(--background-color) 50%,transparent)}}post-tile.loading{transition:none}post-tile:active{transform:scale(.95)}post-tile div.video-detail,post-tile div.gif-detail{position:absolute;background-color:var(--background-color-lighter);color:var(--primary-color);bottom:.3rem;right:.3rem;padding:.2em .4em;height:1rem;border-radius:4px;font-size:12px;display:flex;align-items:center;gap:.2rem;z-index:2}post-tile div.video-detail ion-icon,post-tile div.gif-detail ion-icon{font-size:1.4rem}post-tile div.video-detail ion-icon[name=images-outline],post-tile div.gif-detail ion-icon[name=images-outline]{padding:.1rem;font-size:1rem}post-tile div.video-detail span.duration,post-tile div.gif-detail span.duration{text-transform:uppercase;z-index:2}post-tile img{height:100%;width:100%;vertical-align:top;background-color:var(--background-color)}post-tile video{height:100%;width:100%;object-fit:cover;position:absolute;z-index:1}searchbar{display:flex;align-items:center;flex-direction:column;width:100%;z-index:200;position:fixed;height:100%}searchbar div.input-container{margin-top:.4rem;background-color:color-mix(in srgb,var(--background-color-light) 100%,transparent);border-radius:.4rem;font-size:1rem;width:500px;padding:.4rem;max-width:calc(100% - 2rem);box-sizing:border-box;z-index:201;display:flex;align-items:center;border:1px solid var(--secondary-color-dark)}searchbar div.input-container:focus-within{outline:none}searchbar div.input-container tag-input{display:flex;gap:.4rem;width:100%;overflow:hidden;padding-inline:.4rem;box-sizing:border-box;cursor:text}searchbar div.input-container tag-input tag{display:inline-block;padding:.2rem .4rem;background-color:var(--secondary-color-dark);color:var(--secondary-color);border-radius:.4rem;cursor:pointer}searchbar div.input-container ion-icon{font-size:20px;color:var(--secondary-color-dark);cursor:pointer}searchbar div.input-container ion-icon:hover{color:var(--secondary-color)}searchbar div.selection-list-container{overflow:hidden;border-radius:.4rem;background-color:var(--background-color);z-index:201;max-width:calc(100% - 2rem);width:500px}searchbar div.selection-list-container selection-list{display:block;max-height:40vh;overflow-y:scroll;overflow-x:hidden;position:relative}searchbar div.selection-list-container selection-list::-webkit-scrollbar{width:4px}searchbar div.selection-list-container selection-list selection{display:flex;justify-content:space-between;align-items:center;padding:.4rem 1rem;cursor:pointer;gap:1rem}searchbar div.selection-list-container selection-list selection:hover{background-color:color-mix(in srgb,var(--background-color-lighter) 50%,transparent)}searchbar div.selection-list-container selection-list selection.active{background-color:var(--background-color-lighter)}searchbar div.selection-list-container selection-list selection div.selection-label{display:flex;flex-wrap:wrap;gap:.5rem}searchbar div.selection-list-container selection-list selection div.selection-label .label-container{display:flex;gap:.5rem;align-items:center}searchbar div.selection-list-container selection-list selection div.selection-label .label-container ion-icon{font-size:1rem}searchbar div.selection-list-container selection-list selection div.tag-detail{display:flex;align-items:center;gap:.5rem}searchbar div.selection-list-container selection-list selection div.tag-detail .tag-post-count{font-size:.8rem}searchbar div.selection-list-container selection-list selection .tag-category,searchbar div.selection-list-container selection-list selection .user-level{padding:.1rem .4rem;border-radius:.4rem;font-size:.9rem;background-color:var(--secondary-color-dark);color:var(--secondary-color)}searchbar div.filter{background-color:var(--background-color);opacity:.5;position:fixed;top:0;height:100%;width:100%;z-index:199}.input-wrapper{color:var(--primary-color);border:1px solid var(--secondary-color);border-radius:.4rem;position:relative;box-sizing:border-box;line-height:1em;font-size:14px;padding:4px 8px;display:inline-block;max-width:100%;text-overflow:ellipsis}.input-wrapper span.sizer{font-family:inherit;white-space:pre;height:1em;display:inline-block;font-size:inherit;line-height:inherit;box-sizing:border-box;position:relative;opacity:0;min-width:2px;-webkit-user-select:none;user-select:none;vertical-align:top}.input-wrapper input{height:100%;text-overflow:ellipsis;font-family:inherit;background:none;color:inherit;top:0;left:0;font-size:inherit;line-height:inherit;padding:inherit;position:absolute;box-sizing:border-box;width:100%;border:none;outline:none}button.icon{display:flex;justify-content:center;align-items:center;gap:.4rem;padding:.4rem;background-color:transparent}button.icon ion-icon{font-size:1.5rem}button.icon:hover{background-color:var(--background-color-light)}button.icon.vertical{flex-direction:column}#post{padding:0;padding-top:var(--nav-height)}#post section{background-color:#2f2f45;border-radius:20px;padding:20px}#post div.viewer{height:calc(100vh - 2rem - var(--nav-height));display:flex;justify-content:center;align-items:center;background-color:#000;border-radius:20px;overflow:hidden;width:calc(100vw - 300px - 4rem);margin:1rem}@media (max-width: 800px){#post div.viewer{width:100%;height:calc(100vh - var(--nav-height));border-radius:0;margin:0}}#post div.viewer img{max-width:100%;max-height:100%}#post div.viewer video{max-width:100%;max-height:100%;-webkit-user-drag:none;transition:all .3s ease}#post div.content{width:calc(100vw - 300px - 2rem);display:flex;flex-direction:column;padding:1rem;box-sizing:border-box}@media (max-width: 800px){#post div.content{width:100%}}#post div.content::-webkit-scrollbar{background-color:#000;width:4px}#post div.content::-webkit-scrollbar-thumb{background-color:#aeaeec;border-radius:2px}#post div.content>h3{padding-left:1rem;margin-block:1rem}#post div.content section.commentary *{text-wrap:wrap;word-break:break-word}#post div.sidebar{--padding: 1rem;position:fixed;top:calc(var(--nav-height) + var(--padding));right:var(--padding);display:flex;flex-direction:column;gap:.4rem;width:300px;overflow:scroll;overflow-x:hidden;height:calc(100vh - 2rem - var(--nav-height));border-radius:20px}@media (max-width: 800px){#post div.sidebar{position:static;width:100%;overflow:visible;height:100%;padding:1rem;box-sizing:border-box}}#post div.sidebar::-webkit-scrollbar{background-color:#000;width:0px}#post div.sidebar::-webkit-scrollbar-thumb{background-color:#aeaeec}#post div.sidebar h3{padding-left:1rem;margin-block:.6rem}#post div.sidebar .post-info{background-color:#2f2f45;border-radius:20px;padding:20px;display:flex;flex-direction:column;gap:.4rem}#post div.sidebar .post-info .buttons{display:grid;grid-template-columns:1fr 1fr 1fr;gap:1rem;margin-top:1rem}#post div.sidebar div.property{display:flex;gap:.6rem;align-items:center;width:100%}#post div.sidebar div.property span.property-name{flex-shrink:0}#post div.sidebar div.property div.property-values{display:flex;gap:.4rem;overflow:hidden}#post div.sidebar div.property div.property-values span.property-value{background-color:var(--secondary-color-dark);color:var(--secondary-color);padding:2px 4px;border-radius:4px;text-overflow:ellipsis;overflow:hidden;text-wrap:nowrap}#post div.sidebar div.inline{display:flex;gap:1rem}#post div.sidebar div.post-tags{display:flex;flex-direction:column;gap:.2rem}#post div.sidebar div.post-tags div.tag{align-items:center}#post div.sidebar div.post-tags div.tag a.tag-name{word-break:break-word;color:#d1d1ee;text-decoration:none}#post div.sidebar div.post-tags div.tag span.tag-post-count{background-color:var(--secondary-color-dark);color:var(--secondary-color);padding:0 4px;border-radius:4px;font-size:12px;margin-left:.4rem}page#root layout *{transition:all .3s ease}page#root .loader{text-align:center;padding-block:2rem}:root{--background-color: #1e1e2c;--background-color-lighter: #3b3b66;--background-color-light: #24243b;--primary-color: #d1d1ee;--primary-color-dark: #9696b3;--primary-color-darker: #72728d;--secondary-color: #aeaeec;--secondary-color-dark: #424268;--nav-height: 50px}html{overflow-x:hidden;font-size:14px}html ::-webkit-scrollbar{background-color:var(--background-color);width:8px}html ::-webkit-scrollbar-thumb{background-color:#aeaeec;border-radius:2px}body{overflow-x:hidden;background-color:var(--background-color);color:var(--primary-color);margin:0;font-family:Microsoft Yahei}nav{display:flex;width:100%;height:var(--nav-height);position:fixed;top:0;z-index:100;background-color:color-mix(in srgb,var(--background-color) 70%,transparent);justify-content:space-between;align-items:center;padding-inline:1rem;box-sizing:border-box;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}nav a.title{display:flex;align-items:center;gap:.4rem;text-decoration:none}nav a.title .booru-name{color:var(--secondary-color);margin:0}nav a.title .app{display:flex;align-items:center;border-radius:.4rem;margin:0;gap:.4rem}nav a.title .app .version{color:var(--background-color);background-color:var(--secondary-color);padding:.2em .4em;border-radius:.4rem;font-size:.8rem;font-weight:700}nav a.title .app .app-name{display:none;font-size:1rem;color:var(--secondary-color)}nav div.searchbar{padding:.4rem 10%;max-width:500px;background-color:color-mix(in srgb,var(--background-color-light) 30%,transparent);border:1px solid var(--primary-color-darker);border-radius:.4rem;color:var(--primary-color-dark);transition:.3s all ease;cursor:pointer}nav div.searchbar:hover{color:var(--primary-color)}nav div.buttons{display:flex;align-items:center;gap:1rem}nav div.buttons ion-icon{transition:all .3s ease;border-radius:1rem;padding:.4rem}nav div.buttons ion-icon:hover{background-color:color-mix(in srgb,var(--background-color-lighter) 50%,transparent)}nav div.buttons ion-icon.search{display:none}@media (max-width: 800px){nav div.searchbar{display:none}nav div.buttons ion-icon.search{display:inline-block}}router{display:block;position:relative}router route{display:block;position:relative;padding-inline:10px;padding-top:var(--nav-height)}button{background-color:var(--secondary-color-dark);color:var(--secondary-color);padding:.8rem 1.2rem;border-radius:1rem;border:none;cursor:pointer}ion-icon{font-size:24px;color:var(--primary-color);cursor:pointer}ion-icon:hover{color:var(--secondary-color)}a{color:var(--secondary-color);text-decoration:none} diff --git a/dist/index.html b/dist/index.html index 9f76f2c..28ae191 100644 --- a/dist/index.html +++ b/dist/index.html @@ -7,8 +7,8 @@ Danbooru Viewer v0.2.5 - - + + diff --git a/index.scss b/index.scss index 6bea6ef..9d7a717 100644 --- a/index.scss +++ b/index.scss @@ -156,4 +156,9 @@ ion-icon { &:hover { color: var(--secondary-color); } +} + +a { + color: var(--secondary-color); + text-decoration: none; } \ No newline at end of file diff --git a/package.json b/package.json index aea1169..99494a3 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "danbooru-viewer", "module": "index.ts", "type": "module", - "version": "0.3.3", + "version": "0.3.4", "devDependencies": { "@types/bun": "latest", "vite": "^5.4.8" diff --git a/src/component/PostGrid/$PostGrid.ts b/src/component/PostGrid/$PostGrid.ts index 8c5a0c3..327fbd3 100644 --- a/src/component/PostGrid/$PostGrid.ts +++ b/src/component/PostGrid/$PostGrid.ts @@ -10,6 +10,7 @@ export class $PostGrid extends $Layout { posts = new Set(); $posts = new Set<$PostTile>(); tags?: string; + finished = false; constructor(options?: $PostGridOptions) { super(); this.tags = options?.tags; @@ -20,7 +21,13 @@ export class $PostGrid extends $Layout { protected async init() { setInterval(() => { if (this.inDOM() && document.documentElement.scrollTop === 0) this.updateNewest(); }, 10000); - Booru.events.on('set', () => { this.removeAll(); }) + Booru.events.on('set', () => { + this.removeAll(); + if (this.finished) { + this.finished = false; + this.loader(); + } + }) this.on('resize', () => this.resize()) this.loader(); } @@ -28,10 +35,13 @@ export class $PostGrid extends $Layout { protected async loader() { if (!this.inDOM()) return setTimeout(() => this.loader(), 100);; while (this.inDOM() && document.documentElement.scrollHeight <= innerHeight * 2) { - await this.getPosts(); - if (!this.posts.size) return; + const posts = await this.getPosts(); + if (!posts.length) return this.finished = true; + } + if (document.documentElement.scrollTop + innerHeight > document.documentElement.scrollHeight - innerHeight * 2) { + const posts = await this.getPosts(); + if (!posts.length) return this.finished = true; } - if (document.documentElement.scrollTop + innerHeight > document.documentElement.scrollHeight - innerHeight * 2) await this.getPosts(); setTimeout(() => this.loader(), 100); } @@ -65,14 +75,14 @@ export class $PostGrid extends $Layout { const latestPost = this.sortedPosts.at(0); const posts = await Post.fetchMultiple(Booru.used, {tags: this.tags, id: latestPost ? `>${latestPost.id}` : undefined}, 100); this.addPost(posts); - return this; + return posts; } async getPosts() { const oldestPost = this.sortedPosts.at(-1); const posts = await Post.fetchMultiple(Booru.used, {tags: this.tags, id: oldestPost ? `<${oldestPost.id}` : undefined}, 100); this.addPost(posts); - return this; + return posts; } get sortedPosts() { return this.posts.array.sort((a, b) => +b.createdDate - +a.createdDate); } diff --git a/src/component/PostTile/$PostTile.ts b/src/component/PostTile/$PostTile.ts index ff0b484..aafad55 100644 --- a/src/component/PostTile/$PostTile.ts +++ b/src/component/PostTile/$PostTile.ts @@ -46,14 +46,14 @@ export class $PostTile extends $Container { .once('load', (e, $img) => { $img .src(this.post.previewURL) - .on(['mouseenter', 'touchstart'], () => { if (this.post.isGif) { $img.src(this.post.large_file_url) } }) - .on(['mouseleave', 'touchend', 'touchcancel'], () => { if (this.post.isGif) { $img.src(this.post.previewURL) } }) + .on(['mouseenter', 'touchstart'], () => { if (this.post.isGif) { $img.src(this.post.large_file_url) } }, {passive: true}) + .on(['mouseleave', 'touchend', 'touchcancel'], () => { if (this.post.isGif) { $img.src(this.post.previewURL) } }, {passive: true}) .animate({opacity: [0, 1]}, {duration: 300, fill: 'both'}); this.removeClass('loading'); }) ]) - .on(['mouseenter', 'touchstart'], () => { if (!this.$video?.isPlaying) { this.$video?.src(this.post.large_file_url).hide(false).play().catch(err => undefined) } }) - .on(['mouseleave', 'touchend', 'touchcancel'], () => { this.$video?.pause().currentTime(0).hide(true); }) + .on(['mouseenter', 'touchstart'], () => { if (!this.$video?.isPlaying) { this.$video?.src(this.post.large_file_url).hide(false).play().catch(err => undefined) } }, {passive: true}) + .on(['mouseleave', 'touchend', 'touchcancel'], () => { this.$video?.pause().currentTime(0).hide(true); }, {passive: true}) ]) } diff --git a/src/component/Searchbar/$Searchbar.ts b/src/component/Searchbar/$Searchbar.ts index f15b366..b9e0148 100644 --- a/src/component/Searchbar/$Searchbar.ts +++ b/src/component/Searchbar/$Searchbar.ts @@ -1,6 +1,8 @@ import { $Container } from "elexis"; import { Tag, TagCategory } from "../../structure/Tag"; import { Booru } from "../../structure/Booru"; +import { User } from "../../structure/User"; +import { Autocomplete } from "../../structure/Autocomplete"; export class $Searchbar extends $Container { $tagInput = new $TagInput(this); @@ -128,21 +130,31 @@ export class $Searchbar extends $Container { async getSearchSuggestions() { const input = this.$tagInput.$input.value() if (!input.length) return this.$selectionList.clearSelections(); - const tags = await Tag.fetchMultiple(Booru.used, {fuzzy_name_matches: input, order: 'similarity'}); + const results = await Autocomplete.fetch(Booru.used, input, 20); this.$selectionList .clearSelections() - .addSelections(tags.map(tag => new $Selection().value(tag.name) + .addSelections(results.map(data => new $Selection().value(data.value) .content([ - $('span').class('tag-name').content(tag.name), - $('span').class('tag-category').content(TagCategory[tag.category]) + $('div').class('selection-label').content([ + data.isTagAntecedent() ? $('span').class('tag-antecedent').self($span => $span.dom.innerHTML = data.antecedent.replaceAll(input, `${input}`)) : null, + $('div').class('label-container').content([ + data.isTagAntecedent() ? $('ion-icon').name('arrow-forward-outline') : null, + $('span').class('label').self($span => $span.dom.innerHTML = data.label.replaceAll(input, `${input}`)) + ]) + ]), + data.isTag() ? $('div').class('tag-detail').content([ + $('span').class('tag-post-count').content(new Intl.NumberFormat('en', {notation: 'compact'}).format(data.post_count)), + $('span').class('tag-category').content(TagCategory[data.category]) + ]) : null, + data.isUser() ? $('span').class('user-level').content(data.level) : null ]) - .on('click', () => {this.$tagInput.addTag(tag.name).input()}) + .on('click', () => {this.$tagInput.addTag(data.label).input()}) )) if (!this.$tagInput.$input.value().length) this.$selectionList.clearSelections(); } search() { - $.replace(`/posts?tags=${this.$tagInput.query}`); + $.replace(`/posts?tags=${this.$tagInput.query.replace(':', '%3A')}`); this.$tagInput.clearAll(); this.inactivate(); return this; @@ -177,10 +189,12 @@ class $SelectionList extends $Container { return this; } - focusSelection(selection: $Selection) { + focusSelection($selection: $Selection) { this.blurSelection(); - this.focused = selection; - selection.focus(); + this.focused = $selection; + $selection.focus(); + if ($selection.offsetTop < this.scrollTop()) this.scrollTop($selection.offsetTop); + if ($selection.offsetTop + $selection.offsetHeight > this.scrollTop() + this.offsetHeight) this.scrollTop($selection.offsetTop + $selection.offsetHeight - this.offsetHeight); return this; } diff --git a/src/component/Searchbar/_$Searchbar.scss b/src/component/Searchbar/_$Searchbar.scss index 9163deb..4bd7dc8 100644 --- a/src/component/Searchbar/_$Searchbar.scss +++ b/src/component/Searchbar/_$Searchbar.scss @@ -81,6 +81,7 @@ searchbar { align-items: center; padding: 0.4rem 1rem; cursor: pointer; + gap: 1rem; &:hover { background-color: color-mix(in srgb, var(--background-color-lighter) 50%, transparent); @@ -88,9 +89,30 @@ searchbar { &.active { background-color: var(--background-color-lighter); } - .tag-name { + div.selection-label { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + .label-container { + display: flex; + gap: 0.5rem; + align-items: center; + + ion-icon { + font-size: 1rem; + } + } } - .tag-category { + + div.tag-detail { + display: flex; + align-items: center; + gap: 0.5rem; + .tag-post-count { + font-size: 0.8rem; + } + } + .tag-category, .user-level { padding: 0.1rem 0.4rem; border-radius: 0.4rem; font-size: 0.9rem; diff --git a/src/main.ts b/src/main.ts index 8ba76d9..245cc35 100644 --- a/src/main.ts +++ b/src/main.ts @@ -81,7 +81,7 @@ $(document.body).content([ switch ($Router.navigationDirection) { case $RouterNavigationDirection.Forward: return [`translateX(${TX}%)`, `translateX(0%)`]; case $RouterNavigationDirection.Back: return [`translateX(-${TX}%)`, `translateX(0%)`]; - case $RouterNavigationDirection.Replace: return undefined; + case $RouterNavigationDirection.Replace: return ''; } }) e.$view.content(e.nextContent); @@ -102,7 +102,7 @@ $(document.body).content([ switch ($Router.navigationDirection) { case $RouterNavigationDirection.Forward: return [`translateX(0%)`, `translateX(-${TX}%)`]; case $RouterNavigationDirection.Back: return [`translateX(0%)`, `translateX(${TX}%)`]; - case $RouterNavigationDirection.Replace: return undefined; + case $RouterNavigationDirection.Replace: return ''; } }) diff --git a/src/route/post/$post.ts b/src/route/post/$post.ts index 949aa78..a252b54 100644 --- a/src/route/post/$post.ts +++ b/src/route/post/$post.ts @@ -29,53 +29,60 @@ export const post_route = $('route').path('/posts/:id').id('post').builder(({$ro $('div').class('sidebar') .self($sidebar => { let scrollTop = 0; - addEventListener('scroll', () => { if ($sidebar.inDOM()) scrollTop = document.documentElement.scrollTop }) + addEventListener('scroll', () => { if ($sidebar.inDOM()) scrollTop = document.documentElement.scrollTop }, {passive: true}) $route .on('beforeShift', () => { if (innerWidth > 800) $sidebar.css({position: `absolute`, top: `calc(${scrollTop}px + var(--nav-height) + var(--padding))`}) }) .on('afterShift', () => $sidebar.css({position: '', top: ''})) }) .content([ $('section').class('post-info').content([ - new $Property('id').name('Post').value(`#${params.id}`), - new $Property('uploader').name('Uploader').value(post.uploader$), - new $Property('approver').name('Approver').value(post.approver$), - new $Property('date').name('Date').value(post.created_date$), - new $Property('size').name('Size').value([post.file_size$, post.dimension$]), - new $Property('file').name('File Type').value(post.file_ext$), + new $Property('id').name('Post').content(`#${params.id}`), + new $Property('uploader').name('Uploader').content(post.uploader$), + new $Property('approver').name('Approver').content(post.approver$), + new $Property('date').name('Date').content(post.created_date$), + new $Property('size').name('Size').content([post.file_size$, post.dimension$]), + new $Property('file-type').name('File Type').content(post.file_ext$), $('div').class('inline').content([ - new $Property('favorites').name('Favorites').value(post.favorites$), - new $Property('score').name('Score').value(post.score$) - ]), - $('div').class('buttons').content([ - $('icon-button').class('vertical').icon('link-outline').content(Booru.name$) - .on('click', (e, $button) => { - e.preventDefault(); - navigator.clipboard.writeText(`${Booru.used.origin}${location.pathname}`); - $button.content('Copied!'); - setTimeout(() => { - $button.content(Booru.name$) - }, 2000); - }), - $('icon-button').class('vertical').icon('link-outline').content(`File`) - .on('click', (e, $button) => { - e.preventDefault(); - navigator.clipboard.writeText(post.file_url); - $button.content('Copied!'); - setTimeout(() => { - $button.content('File') - }, 2000); - }), - $('icon-button').class('vertical').icon('link-outline').content(`Webm`) - .on('click', (e, $button) => { - e.preventDefault(); - navigator.clipboard.writeText(post.previewURL); - $button.content('Copied!'); - setTimeout(() => { - $button.content('Webm') - }, 2000); - }) - .hide(true).self(async ($button) => { await post.ready; if (post.file_ext === 'zip') $button.hide(false) }) + new $Property('favorites').name('Favorites').content(post.favorites$), + new $Property('score').name('Score').content(post.score$) ]), + new $Property('file-url').name('File').content($('a').href(post.file_url$).content(post.file_url$.convert((value) => value.replace('https://', ''))).target('_blank')), + new $Property('source-url').name('Source').content($('a').href(post.source$).content(post.source$.convert((value) => value.replace('https://', ''))).target('_blank')), + new $Property('booru-url').name(Booru.name$).content($('a').href(post.url$).content(post.url$.convert((value) => value.replace('https://', ''))).target('_blank')), + new $Property('booru-url').name('Webm').hide(true).self(async ($property) => { + await post.ready; + if (post.isUgoria) $property.content($('a').href(post.webm_url$).content(post.webm_url$.convert((value) => value.replace('https://', ''))).target('_blank')).hide(false); + }), + // $('div').class('buttons').content([ + // $('icon-button').class('vertical').icon('link-outline').content(Booru.name$) + // .on('click', (e, $button) => { + // e.preventDefault(); + // navigator.clipboard.writeText(`${Booru.used.origin}${location.pathname}`); + // $button.content('Copied!'); + // setTimeout(() => { + // $button.content(Booru.name$) + // }, 2000); + // }), + // $('icon-button').class('vertical').icon('link-outline').content(`File`) + // .on('click', (e, $button) => { + // e.preventDefault(); + // navigator.clipboard.writeText(post.file_url); + // $button.content('Copied!'); + // setTimeout(() => { + // $button.content('File') + // }, 2000); + // }), + // $('icon-button').class('vertical').icon('link-outline').content(`Webm`) + // .on('click', (e, $button) => { + // e.preventDefault(); + // navigator.clipboard.writeText(post.previewURL); + // $button.content('Copied!'); + // setTimeout(() => { + // $button.content('Webm') + // }, 2000); + // }) + // .hide(true).self(async ($button) => { await post.ready; if (post.file_ext === 'zip') $button.hide(false) }) + // ]), ]), $('div').class('post-tags').content(async $tags => { const tags = await post.fetchTags(); @@ -116,9 +123,9 @@ class $Property extends $Container { constructor(id: string) { super('div'); this.staticClass('property').attribute('property-id', id); - this.content([ + super.content([ this.$name, - this.$values + this.$values.hide(true) ]) } @@ -127,7 +134,8 @@ class $Property extends $Container { return this; } - value(content: OrMatrix<$ContainerContentType>) { + content(content: OrMatrix<$ContainerContentType>) { + this.$values.hide(false); const list = $.orArrayResolve(content); this.$values.content(list.map($item => $('span').staticClass('property-value').content($item))); return this; diff --git a/src/route/post/_$post.scss b/src/route/post/_$post.scss index 044828c..d4d5143 100644 --- a/src/route/post/_$post.scss +++ b/src/route/post/_$post.scss @@ -129,14 +129,22 @@ display: flex; gap: 0.6rem; align-items: center; + width: 100%; + span.property-name { + flex-shrink: 0; + } div.property-values { display: flex; gap: 0.4rem; + overflow: hidden; span.property-value { background-color: var(--secondary-color-dark); color: var(--secondary-color); padding: 2px 4px; border-radius: 4px; + text-overflow: ellipsis; + overflow: hidden; + text-wrap: nowrap; } } } diff --git a/src/structure/Autocomplete.ts b/src/structure/Autocomplete.ts new file mode 100644 index 0000000..a7b776a --- /dev/null +++ b/src/structure/Autocomplete.ts @@ -0,0 +1,75 @@ +import type { Booru } from "./Booru"; +import type { TagCategory } from "./Tag"; +import type { UserLevelString } from "./User"; + +export class Autocomplete { + static async fetch(booru: Booru, query: string, limit: number = 20) { + const res = await fetch(`${booru.origin}/autocomplete.json?search[query]=${query}&search[type]=tag_query&version=1&limit=${limit}`).then(res => res.json()) as AutocompleteData[]; + return res.map(data => new AutocompleteResult(data)); + } +} + +export interface AutocompleteResult extends AutocompleteBaseData {} +export class AutocompleteResult { + constructor(data: AutocompleteData) { + Object.assign(this, data); + } + + isTag(): this is AutocompleteResult & (AutocompleteTagData | AutocompleteTagAliasData | AutocompleteTagAutocorrectData) { + return this.type === 'tag' || this.type === 'tag-autocorrect' || this.type === 'tag-alias' || this.type === 'tag-word'; + } + + isTagAutocorrect(): this is AutocompleteResult & AutocompleteTagAutocorrectData { + return this.type === 'tag-autocorrect'; + } + + isTagAntecedent(): this is Autocomplete & AutocompleteTagAutocorrectData { + //@ts-expect-error + return !!this['antecedent' as any] + } + + isTagWord(): this is AutocompleteResult & AutocompleteTagWordData { + return this.type === 'tag-word' + } + + isUser(): this is AutocompleteResult & AutocompleteUserData { + return this.type === 'user'; + } +} + +type AutocompleteData = AutocompleteBaseData & (AutocompleteUserData | AutocompleteTagData | AutocompleteTagAutocorrectData | AutocompleteTagAliasData); + +interface AutocompleteBaseData { + type: 'user' | 'tag' | 'tag-autocorrect' | 'tag-alias' | 'tag-word'; + label: string; + value: string; +} + +interface AutocompleteUserData { + type: 'user'; + id: number; + level: Lowercase; +} +interface AutocompleteTagData { + type: 'tag'; + category: TagCategory; + post_count: number; +} +interface AutocompleteTagAutocorrectData { + type: 'tag-autocorrect'; + category: TagCategory; + post_count: number; + antecedent: string; +} +interface AutocompleteTagAliasData { + type: 'tag-alias'; + category: TagCategory; + post_count: number; + antecedent: string; +} +interface AutocompleteTagWordData{ + type: 'tag-word'; + category: TagCategory; + post_count: number; + antecedent: string; +} \ No newline at end of file diff --git a/src/structure/Post.ts b/src/structure/Post.ts index 5b3ce3f..cd2804e 100644 --- a/src/structure/Post.ts +++ b/src/structure/Post.ts @@ -16,9 +16,13 @@ export class Post extends $EventManager<{update: []}> { score$ = $.state(0); file_size$ = $.state(LOADING_STRING); file_ext$ = $.state(LOADING_STRING); + file_url$ = $.state(LOADING_STRING); + source$ = $.state(LOADING_STRING); dimension$ = $.state(LOADING_STRING); + url$ = $.state(LOADING_STRING); createdDate = new Date(this.created_at); ready?: Promise; + webm_url$ = $.state(LOADING_STRING); booru: Booru; constructor(booru: Booru, id: id, data?: PostData) { @@ -56,6 +60,7 @@ export class Post extends $EventManager<{update: []}> { } const req = await fetch(`${booru.origin}/posts.json?limit=${limit}&tags=${tagsQuery}&_method=get`); const dataArray: PostData[] = await req.json(); + if (dataArray instanceof Array === false) return []; const list = dataArray.map(data => { const instance = booru.posts.get(data.id)?.update(data) ?? new this(booru, data.id, data); booru.posts.set(instance.id, instance); @@ -75,7 +80,11 @@ export class Post extends $EventManager<{update: []}> { this.score$.set(this.score); this.file_size$.set(digitalUnit(this.file_size)); this.file_ext$.set(this.file_ext as any); + this.file_url$.set(this.file_url); + this.source$.set(this.source); this.dimension$.set(`${this.image_width}x${this.image_height}`); + this.url$.set(`${this.url}`); + if (this.isUgoria) this.webm_url$.set(this.large_file_url); this.createdDate = new Date(this.created_at); this.fire('update'); } @@ -102,7 +111,8 @@ export class Post extends $EventManager<{update: []}> { const tag_list = this.tag_string.split(' '); return [...this.booru.tags.values()].filter(tag => tag_list.includes(tag.name)) } - get previewURL() { return this.media_asset.variants.find(variant => variant.file_ext === 'webp')?.url ?? this.large_file_url } + get previewURL() { return this.media_asset.variants?.find(variant => variant.file_ext === 'webp')?.url ?? this.large_file_url } + get url() { return `${this.booru.origin}/posts/${this.id}` } } export interface PostData extends PostOptions { diff --git a/src/structure/User.ts b/src/structure/User.ts index efe8a24..e65f6b0 100644 --- a/src/structure/User.ts +++ b/src/structure/User.ts @@ -66,7 +66,7 @@ export interface UserData { } export type UserLevel = 10 | 20 | 30 | 31 | 32 | 40 | 50; -export type UserLevelString = "Member" | "Gold" | "Platinum" | "Admin"; +export type UserLevelString = "Member" | "Gold" | "Platinum" | "Admin" | "Contributor" | "Builder" | "Approver"; export interface UserProfileData extends UserData { "last_logged_in_at": ISOString,