From 9b54842ee715c5599982906ecbe8bf1bfc935a53 Mon Sep 17 00:00:00 2001 From: netanel-haber Date: Sun, 2 Jun 2024 09:13:15 +0000 Subject: [PATCH] deploy: 7092058609f2192fb25ff4bc92edb93e1a1f029e --- 200.html | 12 ++-- 404.html | 12 ++-- ...Doc.m4erpRCJ.js => ContentDoc.rfis-nOt.js} | 2 +- ...st.YfCz_pZv.js => ContentList.3CoUdjPc.js} | 2 +- ...xUQeo.js => ContentNavigation.f33EaOoS.js} | 4 +- ...y.7IlyA-wt.js => ContentQuery.8OtClJpg.js} | 2 +- ...Ci8vnAh.js => ContentRenderer.cy28u1UG.js} | 2 +- _nuxt/ContentRendererMarkdown.T55ooTnH.js | 1 + _nuxt/ContentRendererMarkdown.TQHLBOHw.js | 1 - ...> ContentRendererMarkdown.vue.RczDmK50.js} | 2 +- ...ot.yUuC7AiQ.js => ContentSlot.4Yv1O94w.js} | 2 +- ...pq4.js => DocumentDrivenEmpty.2yjd1SSH.js} | 2 +- ....js => DocumentDrivenNotFound.ifYdODZj.js} | 2 +- ...kdown.PGpQEzUu.js => Markdown.Ni6QM3--.js} | 2 +- ...{ProseA.mjBdkCoM.js => ProseA.Gnk6FU_h.js} | 2 +- ...zQiHAd5.js => ProseBlockquote.IIuhyPCv.js} | 2 +- _nuxt/ProseCode.4ZscnP7G.js | 1 - _nuxt/ProseCode.QIyOSdyq.js | 1 + ....L3vrDCRe.js => ProseCode.vue.rbas8gSm.js} | 2 +- ...2qvyBIJ.js => ProseCodeInline.o4JCub5L.js} | 2 +- ...roseEm.IVSr4QqS.js => ProseEm.4QCYOuXW.js} | 2 +- ...roseH1.98vvHrNf.js => ProseH1.eaEHGjQf.js} | 2 +- ...roseH2.3ZUTtu58.js => ProseH2.yJsNSjEm.js} | 2 +- ...roseH3.xS8JfK2d.js => ProseH3.tODisIiG.js} | 2 +- ...roseH4.W0zxJSWG.js => ProseH4.xj30r601.js} | 2 +- ...roseH5.D_jmzZ-I.js => ProseH5.q9bEm_2Z.js} | 2 +- ...roseH6.UGEbdmmN.js => ProseH6.7fYg4335.js} | 2 +- ...roseHr.VSPhZaq6.js => ProseHr.a_aaQ3qF.js} | 2 +- ...seImg._1ci9PF9.js => ProseImg.Uaqj6QZM.js} | 2 +- ...roseLi.pGb8hNnw.js => ProseLi.7JA3q9E2.js} | 2 +- ...roseOl._vZ89wqu.js => ProseOl.6gUkelNo.js} | 2 +- ...{ProseP.l0BQwt1b.js => ProseP.XuucEeBj.js} | 2 +- ...sePre.f92e3HR-.js => ProsePre.3GHfg6KT.js} | 2 +- ...pt.vwc6r6-w.js => ProseScript.WQQ7lrh9.js} | 2 +- ...ng.8IHfBQHv.js => ProseStrong.q8mG-bZC.js} | 2 +- ...ble.UwfW2q09.js => ProseTable.5kBeO5qI.js} | 2 +- ...ody.76lFHrfY.js => ProseTbody.FIDIkwnl.js} | 2 +- ...roseTd.Mqlmzd0p.js => ProseTd.KoI3F--9.js} | 2 +- ...roseTh.FnhkcspZ.js => ProseTh.m9_aWQqV.js} | 2 +- ...ead.0jV4MZhn.js => ProseThead.sBnyBi4S.js} | 2 +- ...roseTr.Hqs34-B0.js => ProseTr.YtSXwZb5.js} | 2 +- ...roseUl.2DgLM2oK.js => ProseUl.NGJ2KrmN.js} | 2 +- _nuxt/_...slug_.-1J-oLil.js | 1 + _nuxt/_...slug_.6mwjtp-q.js | 1 - _nuxt/builds/latest.json | 2 +- ...5c1e5955-a9a1-4785-b832-fac3e0fe121e.json} | 2 +- ...t-db.woz9fGTK.js => client-db.j5h9Mw_L.js} | 2 +- .../{entry.kyqmbcaI.js => entry.PS9LLiT2.js} | 8 +-- ...-404.RZ-3MmJ-.js => error-404.AT6CNjAs.js} | 2 +- ...-500.JOTan9fW.js => error-500.5nitSuEA.js} | 2 +- _nuxt/index.4QcPPhLg.css | 1 + _nuxt/index.4XUzm4qg.css | 1 - _nuxt/index.XaakE1gN.js | 1 + _nuxt/index.yVYxWBDr.js | 1 - ...review.WHtoAZxr.js => preview.99XykmGH.js} | 2 +- .../{query.veKqiZiu.js => query.9Ah2Ct9x.js} | 4 +- ...f.ZfSKW0Tx.js => vue.f36acd1f.jcQdGPHq.js} | 2 +- _payload.json | 2 +- ...19116628.json => cache.1717319582386.json} | 2 +- ...628.json => 1pxjniE9Qa.1717319582386.json} | 0 ...628.json => LZLxbnB5O3.1717319582386.json} | 0 ...628.json => gN4uEe4KzX.1717319582386.json} | 0 blog/_payload.json | 2 +- blog/index.html | 12 ++-- concurrency/_payload.json | 2 +- concurrency/index.html | 66 +++++++++---------- index.html | 18 ++--- ok-sometimes-async-await/_payload.json | 2 +- ok-sometimes-async-await/index.html | 56 ++++++++-------- .../_payload.json | 2 +- .../index.html | 44 ++++++------- 71 files changed, 171 insertions(+), 171 deletions(-) rename _nuxt/{ContentDoc.m4erpRCJ.js => ContentDoc.rfis-nOt.js} (84%) rename _nuxt/{ContentList.YfCz_pZv.js => ContentList.3CoUdjPc.js} (78%) rename _nuxt/{ContentNavigation.4-dxUQeo.js => ContentNavigation.f33EaOoS.js} (81%) rename _nuxt/{ContentQuery.7IlyA-wt.js => ContentQuery.8OtClJpg.js} (92%) rename _nuxt/{ContentRenderer.0Ci8vnAh.js => ContentRenderer.cy28u1UG.js} (84%) create mode 100644 _nuxt/ContentRendererMarkdown.T55ooTnH.js delete mode 100644 _nuxt/ContentRendererMarkdown.TQHLBOHw.js rename _nuxt/{ContentRendererMarkdown.vue.QtxrB05Z.js => ContentRendererMarkdown.vue.RczDmK50.js} (99%) rename _nuxt/{ContentSlot.yUuC7AiQ.js => ContentSlot.4Yv1O94w.js} (96%) rename _nuxt/{DocumentDrivenEmpty.FNlONpq4.js => DocumentDrivenEmpty.2yjd1SSH.js} (77%) rename _nuxt/{DocumentDrivenNotFound.PaEuZL54.js => DocumentDrivenNotFound.ifYdODZj.js} (59%) rename _nuxt/{Markdown.PGpQEzUu.js => Markdown.Ni6QM3--.js} (61%) rename _nuxt/{ProseA.mjBdkCoM.js => ProseA.Gnk6FU_h.js} (64%) rename _nuxt/{ProseBlockquote.0zQiHAd5.js => ProseBlockquote.IIuhyPCv.js} (66%) delete mode 100644 _nuxt/ProseCode.4ZscnP7G.js create mode 100644 _nuxt/ProseCode.QIyOSdyq.js rename _nuxt/{ProseCode.vue.L3vrDCRe.js => ProseCode.vue.rbas8gSm.js} (80%) rename _nuxt/{ProseCodeInline.D2qvyBIJ.js => ProseCodeInline.o4JCub5L.js} (66%) rename _nuxt/{ProseEm.IVSr4QqS.js => ProseEm.4QCYOuXW.js} (65%) rename _nuxt/{ProseH1.98vvHrNf.js => ProseH1.eaEHGjQf.js} (85%) rename _nuxt/{ProseH2.3ZUTtu58.js => ProseH2.yJsNSjEm.js} (85%) rename _nuxt/{ProseH3.xS8JfK2d.js => ProseH3.tODisIiG.js} (85%) rename _nuxt/{ProseH4.W0zxJSWG.js => ProseH4.xj30r601.js} (85%) rename _nuxt/{ProseH5.D_jmzZ-I.js => ProseH5.q9bEm_2Z.js} (85%) rename _nuxt/{ProseH6.UGEbdmmN.js => ProseH6.7fYg4335.js} (85%) rename _nuxt/{ProseHr.VSPhZaq6.js => ProseHr.a_aaQ3qF.js} (55%) rename _nuxt/{ProseImg._1ci9PF9.js => ProseImg.Uaqj6QZM.js} (89%) rename _nuxt/{ProseLi.pGb8hNnw.js => ProseLi.7JA3q9E2.js} (65%) rename _nuxt/{ProseOl._vZ89wqu.js => ProseOl.6gUkelNo.js} (65%) rename _nuxt/{ProseP.l0BQwt1b.js => ProseP.XuucEeBj.js} (65%) rename _nuxt/{ProsePre.f92e3HR-.js => ProsePre.3GHfg6KT.js} (74%) rename _nuxt/{ProseScript.vwc6r6-w.js => ProseScript.WQQ7lrh9.js} (86%) rename _nuxt/{ProseStrong.8IHfBQHv.js => ProseStrong.q8mG-bZC.js} (66%) rename _nuxt/{ProseTable.UwfW2q09.js => ProseTable.5kBeO5qI.js} (66%) rename _nuxt/{ProseTbody.76lFHrfY.js => ProseTbody.FIDIkwnl.js} (66%) rename _nuxt/{ProseTd.Mqlmzd0p.js => ProseTd.KoI3F--9.js} (65%) rename _nuxt/{ProseTh.FnhkcspZ.js => ProseTh.m9_aWQqV.js} (65%) rename _nuxt/{ProseThead.0jV4MZhn.js => ProseThead.sBnyBi4S.js} (66%) rename _nuxt/{ProseTr.Hqs34-B0.js => ProseTr.YtSXwZb5.js} (64%) rename _nuxt/{ProseUl.2DgLM2oK.js => ProseUl.NGJ2KrmN.js} (65%) create mode 100644 _nuxt/_...slug_.-1J-oLil.js delete mode 100644 _nuxt/_...slug_.6mwjtp-q.js rename _nuxt/builds/meta/{bb1ffd14-a21e-4a1d-9114-3af753bf049c.json => 5c1e5955-a9a1-4785-b832-fac3e0fe121e.json} (61%) rename _nuxt/{client-db.woz9fGTK.js => client-db.j5h9Mw_L.js} (99%) rename _nuxt/{entry.kyqmbcaI.js => entry.PS9LLiT2.js} (97%) rename _nuxt/{error-404.RZ-3MmJ-.js => error-404.AT6CNjAs.js} (94%) rename _nuxt/{error-500.JOTan9fW.js => error-500.5nitSuEA.js} (93%) create mode 100644 _nuxt/index.4QcPPhLg.css delete mode 100644 _nuxt/index.4XUzm4qg.css create mode 100644 _nuxt/index.XaakE1gN.js delete mode 100644 _nuxt/index.yVYxWBDr.js rename _nuxt/{preview.WHtoAZxr.js => preview.99XykmGH.js} (99%) rename _nuxt/{query.veKqiZiu.js => query.9Ah2Ct9x.js} (95%) rename _nuxt/{vue.f36acd1f.ZfSKW0Tx.js => vue.f36acd1f.jcQdGPHq.js} (83%) rename api/_content/{cache.1717319116628.json => cache.1717319582386.json} (99%) rename api/_content/query/{1pxjniE9Qa.1717319116628.json => 1pxjniE9Qa.1717319582386.json} (100%) rename api/_content/query/{LZLxbnB5O3.1717319116628.json => LZLxbnB5O3.1717319582386.json} (100%) rename api/_content/query/{gN4uEe4KzX.1717319116628.json => gN4uEe4KzX.1717319582386.json} (100%) diff --git a/200.html b/200.html index 004ac78..6252d04 100644 --- a/200.html +++ b/200.html @@ -3,10 +3,10 @@ - + - - - -
- \ No newline at end of file + + + +
+ \ No newline at end of file diff --git a/404.html b/404.html index 004ac78..6252d04 100644 --- a/404.html +++ b/404.html @@ -3,10 +3,10 @@ - + - - - -
- \ No newline at end of file + + + +
+ \ No newline at end of file diff --git a/_nuxt/ContentDoc.m4erpRCJ.js b/_nuxt/ContentDoc.rfis-nOt.js similarity index 84% rename from _nuxt/ContentDoc.m4erpRCJ.js rename to _nuxt/ContentDoc.rfis-nOt.js index 47bcd4d..ffc9bd7 100644 --- a/_nuxt/ContentDoc.m4erpRCJ.js +++ b/_nuxt/ContentDoc.rfis-nOt.js @@ -1 +1 @@ -import{u as d,i as _,q as y,s as w,v as g,g as D,x,y as H,z as u}from"./entry.kyqmbcaI.js";import{u as q}from"./vue.f36acd1f.ZfSKW0Tx.js";import S from"./ContentRenderer.0Ci8vnAh.js";import b from"./ContentQuery.7IlyA-wt.js";import"./ContentRendererMarkdown.vue.QtxrB05Z.js";import"./index.1dSrIji7.js";import"./preview.WHtoAZxr.js";import"./query.veKqiZiu.js";const a=(s,p=y())=>{const e=d(s),f=g();_(()=>d(s),(n=e)=>{if(!p.path||!n)return;const t=Object.assign({},(n==null?void 0:n.head)||{});t.meta=[...t.meta||[]],t.link=[...t.link||[]];const r=t.title||(n==null?void 0:n.title);r&&(t.title=r),f.public.content.host;const c=(t==null?void 0:t.description)||(n==null?void 0:n.description);c&&t.meta.filter(l=>l.name==="description").length===0&&t.meta.push({name:"description",content:c}),t!=null&&t.image||(n==null||n.image),w(()=>q(t))},{immediate:!0})},$=D({name:"ContentDoc",props:{tag:{type:String,required:!1,default:"div"},excerpt:{type:Boolean,default:!1},path:{type:String,required:!1,default:void 0},query:{type:Object,required:!1,default:void 0},head:{type:Boolean,required:!1,default:void 0}},render(s){const{contentHead:p}=g().public.content,e=x(),{tag:f,excerpt:m,path:n,query:t,head:r}=s,c=r===void 0?p:r,l={...t||{},path:n||(t==null?void 0:t.path)||H(y().path),find:"one"},v=(o,i)=>u("pre",null,JSON.stringify({message:"You should use slots with ",slot:o,data:i},null,2));return u(b,l,{default:e!=null&&e.default?({data:o,refresh:i,isPartial:C})=>{var h;return c&&a(o),(h=e.default)==null?void 0:h.call(e,{doc:o,refresh:i,isPartial:C,excerpt:m,...this.$attrs})}:({data:o})=>(c&&a(o),u(S,{value:o,excerpt:m,tag:f,...this.$attrs},{empty:i=>e!=null&&e.empty?e.empty(i):v("default",o)})),empty:o=>{var i;return((i=e==null?void 0:e.empty)==null?void 0:i.call(e,o))||u("p",null,"Document is empty, overwrite this content with #empty slot in .")},"not-found":o=>{var i;return((i=e==null?void 0:e["not-found"])==null?void 0:i.call(e,o))||u("p",null,"Document not found, overwrite this content with #not-found slot in .")}})}}),j=$,J=j;export{J as default}; +import{u as d,i as _,q as y,s as w,v as g,g as D,x,y as H,z as u}from"./entry.PS9LLiT2.js";import{u as q}from"./vue.f36acd1f.jcQdGPHq.js";import S from"./ContentRenderer.cy28u1UG.js";import b from"./ContentQuery.8OtClJpg.js";import"./ContentRendererMarkdown.vue.RczDmK50.js";import"./index.1dSrIji7.js";import"./preview.99XykmGH.js";import"./query.9Ah2Ct9x.js";const a=(s,p=y())=>{const e=d(s),f=g();_(()=>d(s),(n=e)=>{if(!p.path||!n)return;const t=Object.assign({},(n==null?void 0:n.head)||{});t.meta=[...t.meta||[]],t.link=[...t.link||[]];const r=t.title||(n==null?void 0:n.title);r&&(t.title=r),f.public.content.host;const c=(t==null?void 0:t.description)||(n==null?void 0:n.description);c&&t.meta.filter(l=>l.name==="description").length===0&&t.meta.push({name:"description",content:c}),t!=null&&t.image||(n==null||n.image),w(()=>q(t))},{immediate:!0})},$=D({name:"ContentDoc",props:{tag:{type:String,required:!1,default:"div"},excerpt:{type:Boolean,default:!1},path:{type:String,required:!1,default:void 0},query:{type:Object,required:!1,default:void 0},head:{type:Boolean,required:!1,default:void 0}},render(s){const{contentHead:p}=g().public.content,e=x(),{tag:f,excerpt:m,path:n,query:t,head:r}=s,c=r===void 0?p:r,l={...t||{},path:n||(t==null?void 0:t.path)||H(y().path),find:"one"},v=(o,i)=>u("pre",null,JSON.stringify({message:"You should use slots with ",slot:o,data:i},null,2));return u(b,l,{default:e!=null&&e.default?({data:o,refresh:i,isPartial:C})=>{var h;return c&&a(o),(h=e.default)==null?void 0:h.call(e,{doc:o,refresh:i,isPartial:C,excerpt:m,...this.$attrs})}:({data:o})=>(c&&a(o),u(S,{value:o,excerpt:m,tag:f,...this.$attrs},{empty:i=>e!=null&&e.empty?e.empty(i):v("default",o)})),empty:o=>{var i;return((i=e==null?void 0:e.empty)==null?void 0:i.call(e,o))||u("p",null,"Document is empty, overwrite this content with #empty slot in .")},"not-found":o=>{var i;return((i=e==null?void 0:e["not-found"])==null?void 0:i.call(e,o))||u("p",null,"Document not found, overwrite this content with #not-found slot in .")}})}}),j=$,J=j;export{J as default}; diff --git a/_nuxt/ContentList.YfCz_pZv.js b/_nuxt/ContentList.3CoUdjPc.js similarity index 78% rename from _nuxt/ContentList.YfCz_pZv.js rename to _nuxt/ContentList.3CoUdjPc.js index decad76..fba6dd0 100644 --- a/_nuxt/ContentList.YfCz_pZv.js +++ b/_nuxt/ContentList.3CoUdjPc.js @@ -1 +1 @@ -import d from"./ContentQuery.7IlyA-wt.js";import{g as c,x as l,z as f}from"./entry.kyqmbcaI.js";import"./query.veKqiZiu.js";import"./preview.WHtoAZxr.js";const u=(r,t)=>f("pre",null,JSON.stringify({message:"You should use slots with ",slot:r,data:t},null,2)),h=c({name:"ContentList",props:{path:{type:String,required:!1,default:void 0},query:{type:Object,required:!1,default:void 0}},render(r){const t=l(),{path:p,query:a}=r,m={...a||{},path:p||(a==null?void 0:a.path)||"/"};return f(d,m,{default:t!=null&&t.default?({data:e,refresh:o,isPartial:n})=>t.default({list:e,refresh:o,isPartial:n,...this.$attrs}):e=>u("default",e.data),empty:e=>t!=null&&t.empty?t.empty(e):u("default",e==null?void 0:e.data),"not-found":e=>{var o;return t!=null&&t["not-found"]?(o=t==null?void 0:t["not-found"])==null?void 0:o.call(t,e):u("not-found",e==null?void 0:e.data)}})}}),L=h;export{L as default}; +import d from"./ContentQuery.8OtClJpg.js";import{g as c,x as l,z as f}from"./entry.PS9LLiT2.js";import"./query.9Ah2Ct9x.js";import"./preview.99XykmGH.js";const u=(r,t)=>f("pre",null,JSON.stringify({message:"You should use slots with ",slot:r,data:t},null,2)),h=c({name:"ContentList",props:{path:{type:String,required:!1,default:void 0},query:{type:Object,required:!1,default:void 0}},render(r){const t=l(),{path:p,query:a}=r,m={...a||{},path:p||(a==null?void 0:a.path)||"/"};return f(d,m,{default:t!=null&&t.default?({data:e,refresh:o,isPartial:n})=>t.default({list:e,refresh:o,isPartial:n,...this.$attrs}):e=>u("default",e.data),empty:e=>t!=null&&t.empty?t.empty(e):u("default",e==null?void 0:e.data),"not-found":e=>{var o;return t!=null&&t["not-found"]?(o=t==null?void 0:t["not-found"])==null?void 0:o.call(t,e):u("not-found",e==null?void 0:e.data)}})}}),L=h;export{L as default}; diff --git a/_nuxt/ContentNavigation.4-dxUQeo.js b/_nuxt/ContentNavigation.f33EaOoS.js similarity index 81% rename from _nuxt/ContentNavigation.4-dxUQeo.js rename to _nuxt/ContentNavigation.f33EaOoS.js index 304c1e1..38497ff 100644 --- a/_nuxt/ContentNavigation.4-dxUQeo.js +++ b/_nuxt/ContentNavigation.f33EaOoS.js @@ -1,7 +1,7 @@ -import{q as v,w as f,e as m,s as l,j as d,u as g,a as h}from"./query.veKqiZiu.js";import{v as y,I as _,J as w,K as C,L as x,g as P,M as $,h as N,x as E,z as p,e as T}from"./entry.kyqmbcaI.js";import{h as c,u as j}from"./preview.WHtoAZxr.js";const S=async t=>{const{content:e}=y().public;typeof(t==null?void 0:t.params)!="function"&&(t=v(t));const n=t.params(),o=e.experimental.stripQueryParameters?f(`/navigation/${`${c(n)}.${e.integrity}`}/${m(n)}.json`):f(`/navigation/${c(n)}.${e.integrity}.json`);if(l())return(await _(()=>import("./client-db.woz9fGTK.js"),__vite__mapDeps([0,1,2,3,4,5]),import.meta.url).then(s=>s.generateNavigation))(n);const a=await $fetch(o,{method:"GET",responseType:"json",params:e.experimental.stripQueryParameters?void 0:{_params:d(n),previewToken:j().getPreviewToken()}});if(typeof a=="string"&&a.startsWith(""))throw new Error("Not found");return a},b="$s";function D(...t){const e=typeof t[t.length-1]=="string"?t.pop():void 0;typeof t[0]!="string"&&t.unshift(e);const[n,o]=t;if(!n||typeof n!="string")throw new TypeError("[nuxt] [useState] key must be a string: "+n);if(o!==void 0&&typeof o!="function")throw new Error("[nuxt] [useState] init must be a function: "+o);const a=b+n,r=x(),s=w(r.payload.state,a);if(s.value===void 0&&o){const i=o();if(C(i))return r.payload.state[a]=i,i;s.value=i}return s}const R=P({name:"ContentNavigation",props:{query:{type:Object,required:!1,default:void 0}},async setup(t){const{query:e}=$(t),n=N(()=>{var a;return typeof((a=e.value)==null?void 0:a.params)=="function"?e.value.params():e.value});if(!n.value&&D("dd-navigation").value){const{navigation:a}=g();return{navigation:a}}const{data:o}=await h(`content-navigation-${c(n.value)}`,()=>S(n.value));return{navigation:o}},render(t){const e=E(),{navigation:n}=t,o=s=>p(T,{to:s._path},()=>s.title),a=(s,i)=>p("ul",i?{"data-level":i}:null,s.map(u=>u.children?p("li",null,[o(u),a(u.children,i+1)]):p("li",null,o(u)))),r=s=>a(s,0);return e!=null&&e.default?e.default({navigation:n,...this.$attrs}):r(n)}}),K=R;export{K as default}; +import{q as v,w as f,e as m,s as l,j as d,u as g,a as h}from"./query.9Ah2Ct9x.js";import{v as y,I as _,J as w,K as C,L as x,g as P,M as $,h as N,x as E,z as p,e as T}from"./entry.PS9LLiT2.js";import{h as c,u as j}from"./preview.99XykmGH.js";const S=async t=>{const{content:e}=y().public;typeof(t==null?void 0:t.params)!="function"&&(t=v(t));const n=t.params(),o=e.experimental.stripQueryParameters?f(`/navigation/${`${c(n)}.${e.integrity}`}/${m(n)}.json`):f(`/navigation/${c(n)}.${e.integrity}.json`);if(l())return(await _(()=>import("./client-db.j5h9Mw_L.js"),__vite__mapDeps([0,1,2,3,4,5]),import.meta.url).then(s=>s.generateNavigation))(n);const a=await $fetch(o,{method:"GET",responseType:"json",params:e.experimental.stripQueryParameters?void 0:{_params:d(n),previewToken:j().getPreviewToken()}});if(typeof a=="string"&&a.startsWith(""))throw new Error("Not found");return a},b="$s";function D(...t){const e=typeof t[t.length-1]=="string"?t.pop():void 0;typeof t[0]!="string"&&t.unshift(e);const[n,o]=t;if(!n||typeof n!="string")throw new TypeError("[nuxt] [useState] key must be a string: "+n);if(o!==void 0&&typeof o!="function")throw new Error("[nuxt] [useState] init must be a function: "+o);const a=b+n,r=x(),s=w(r.payload.state,a);if(s.value===void 0&&o){const i=o();if(C(i))return r.payload.state[a]=i,i;s.value=i}return s}const R=P({name:"ContentNavigation",props:{query:{type:Object,required:!1,default:void 0}},async setup(t){const{query:e}=$(t),n=N(()=>{var a;return typeof((a=e.value)==null?void 0:a.params)=="function"?e.value.params():e.value});if(!n.value&&D("dd-navigation").value){const{navigation:a}=g();return{navigation:a}}const{data:o}=await h(`content-navigation-${c(n.value)}`,()=>S(n.value));return{navigation:o}},render(t){const e=E(),{navigation:n}=t,o=s=>p(T,{to:s._path},()=>s.title),a=(s,i)=>p("ul",i?{"data-level":i}:null,s.map(u=>u.children?p("li",null,[o(u),a(u.children,i+1)]):p("li",null,o(u)))),r=s=>a(s,0);return e!=null&&e.default?e.default({navigation:n,...this.$attrs}):r(n)}}),K=R;export{K as default}; function __vite__mapDeps(indexes) { if (!__vite__mapDeps.viteFileDeps) { - __vite__mapDeps.viteFileDeps = ["./client-db.woz9fGTK.js","./entry.kyqmbcaI.js","./entry.aFfi1m7m.css","./query.veKqiZiu.js","./preview.WHtoAZxr.js","./index.1dSrIji7.js"] + __vite__mapDeps.viteFileDeps = ["./client-db.j5h9Mw_L.js","./entry.PS9LLiT2.js","./entry.aFfi1m7m.css","./query.9Ah2Ct9x.js","./preview.99XykmGH.js","./index.1dSrIji7.js"] } return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) } diff --git a/_nuxt/ContentQuery.7IlyA-wt.js b/_nuxt/ContentQuery.8OtClJpg.js similarity index 92% rename from _nuxt/ContentQuery.7IlyA-wt.js rename to _nuxt/ContentQuery.8OtClJpg.js index 1d81b77..dddef20 100644 --- a/_nuxt/ContentQuery.7IlyA-wt.js +++ b/_nuxt/ContentQuery.8OtClJpg.js @@ -1 +1 @@ -import{a as g,q as m}from"./query.veKqiZiu.js";import{g as C,M as S,h as b,v as _,i as k,x as A,z as N}from"./entry.kyqmbcaI.js";import{h as O}from"./preview.WHtoAZxr.js";const Q=C({name:"ContentQuery",props:{path:{type:String,required:!1,default:void 0},only:{type:Array,required:!1,default:void 0},without:{type:Array,required:!1,default:void 0},where:{type:Object,required:!1,default:void 0},sort:{type:Object,required:!1,default:void 0},limit:{type:Number,required:!1,default:void 0},skip:{type:Number,required:!1,default:void 0},locale:{type:String,required:!1,default:void 0},find:{type:String,required:!1,default:void 0}},async setup(u){const{path:t,only:r,without:o,where:a,sort:f,limit:l,skip:d,locale:s,find:h}=S(u),y=b(()=>{var e;return(e=t.value)==null?void 0:e.includes("/_")}),p=!_().public.content.experimental.advanceQuery;k(()=>u,()=>n(),{deep:!0});const i=e=>p?e!=null&&e.surround?e.surround:e!=null&&e._id||Array.isArray(e)?e:e==null?void 0:e.result:e.result,{data:v,refresh:n}=await g(`content-query-${O(u)}`,()=>{let e;return t.value?e=m(t.value):e=m(),r.value&&(e=e.only(r.value)),o.value&&(e=e.without(o.value)),a.value&&(e=e.where(a.value)),f.value&&(e=e.sort(f.value)),l.value&&(e=e.limit(l.value)),d.value&&(e=e.skip(d.value)),s.value&&(e=e.where({_locale:s.value})),h.value==="one"?e.findOne().then(i):h.value==="surround"?t.value?p?e.findSurround(t.value):e.withSurround(t.value).findOne().then(i):(console.warn("[Content] Surround queries requires `path` prop to be set."),console.warn("[Content] Query without `path` will return regular `find()` results."),e.find().then(i)):e.find().then(i)});return{isPartial:y,data:v,refresh:n}},render(u){var c;const t=A(),{data:r,refresh:o,isPartial:a,path:f,only:l,without:d,where:s,sort:h,limit:y,skip:p,locale:i,find:v}=u,n={path:f,only:l,without:d,where:s,sort:h,limit:y,skip:p,locale:i,find:v};if(n.find==="one"){if(!r&&(t!=null&&t["not-found"]))return t["not-found"]({props:n,...this.$attrs});if(t!=null&&t.empty&&(r==null?void 0:r._type)==="markdown"&&!((c=r==null?void 0:r.body)!=null&&c.children.length))return t.empty({props:n,...this.$attrs})}else if((!r||!r.length)&&t!=null&&t["not-found"])return t["not-found"]({props:n,...this.$attrs});return t!=null&&t.default?t.default({data:r,refresh:o,isPartial:a,props:n,...this.$attrs}):((w,q)=>N("pre",null,JSON.stringify({message:"You should use slots with !",slot:w,data:q},null,2)))("default",{data:r,props:n,isPartial:a})}}),j=Q;export{j as default}; +import{a as g,q as m}from"./query.9Ah2Ct9x.js";import{g as C,M as S,h as b,v as _,i as k,x as A,z as N}from"./entry.PS9LLiT2.js";import{h as O}from"./preview.99XykmGH.js";const Q=C({name:"ContentQuery",props:{path:{type:String,required:!1,default:void 0},only:{type:Array,required:!1,default:void 0},without:{type:Array,required:!1,default:void 0},where:{type:Object,required:!1,default:void 0},sort:{type:Object,required:!1,default:void 0},limit:{type:Number,required:!1,default:void 0},skip:{type:Number,required:!1,default:void 0},locale:{type:String,required:!1,default:void 0},find:{type:String,required:!1,default:void 0}},async setup(u){const{path:t,only:r,without:o,where:a,sort:f,limit:l,skip:d,locale:s,find:h}=S(u),y=b(()=>{var e;return(e=t.value)==null?void 0:e.includes("/_")}),p=!_().public.content.experimental.advanceQuery;k(()=>u,()=>n(),{deep:!0});const i=e=>p?e!=null&&e.surround?e.surround:e!=null&&e._id||Array.isArray(e)?e:e==null?void 0:e.result:e.result,{data:v,refresh:n}=await g(`content-query-${O(u)}`,()=>{let e;return t.value?e=m(t.value):e=m(),r.value&&(e=e.only(r.value)),o.value&&(e=e.without(o.value)),a.value&&(e=e.where(a.value)),f.value&&(e=e.sort(f.value)),l.value&&(e=e.limit(l.value)),d.value&&(e=e.skip(d.value)),s.value&&(e=e.where({_locale:s.value})),h.value==="one"?e.findOne().then(i):h.value==="surround"?t.value?p?e.findSurround(t.value):e.withSurround(t.value).findOne().then(i):(console.warn("[Content] Surround queries requires `path` prop to be set."),console.warn("[Content] Query without `path` will return regular `find()` results."),e.find().then(i)):e.find().then(i)});return{isPartial:y,data:v,refresh:n}},render(u){var c;const t=A(),{data:r,refresh:o,isPartial:a,path:f,only:l,without:d,where:s,sort:h,limit:y,skip:p,locale:i,find:v}=u,n={path:f,only:l,without:d,where:s,sort:h,limit:y,skip:p,locale:i,find:v};if(n.find==="one"){if(!r&&(t!=null&&t["not-found"]))return t["not-found"]({props:n,...this.$attrs});if(t!=null&&t.empty&&(r==null?void 0:r._type)==="markdown"&&!((c=r==null?void 0:r.body)!=null&&c.children.length))return t.empty({props:n,...this.$attrs})}else if((!r||!r.length)&&t!=null&&t["not-found"])return t["not-found"]({props:n,...this.$attrs});return t!=null&&t.default?t.default({data:r,refresh:o,isPartial:a,props:n,...this.$attrs}):((w,q)=>N("pre",null,JSON.stringify({message:"You should use slots with !",slot:w,data:q},null,2)))("default",{data:r,props:n,isPartial:a})}}),j=Q;export{j as default}; diff --git a/_nuxt/ContentRenderer.0Ci8vnAh.js b/_nuxt/ContentRenderer.cy28u1UG.js similarity index 84% rename from _nuxt/ContentRenderer.0Ci8vnAh.js rename to _nuxt/ContentRenderer.cy28u1UG.js index 94f1129..37b9f52 100644 --- a/_nuxt/ContentRenderer.0Ci8vnAh.js +++ b/_nuxt/ContentRenderer.cy28u1UG.js @@ -1 +1 @@ -import{_ as o}from"./ContentRendererMarkdown.vue.QtxrB05Z.js";import{g as l,i as s,x as d,z as f}from"./entry.kyqmbcaI.js";import"./index.1dSrIji7.js";import"./preview.WHtoAZxr.js";const g=l({name:"ContentRenderer",props:{value:{type:Object,required:!1,default:()=>({})},excerpt:{type:Boolean,default:!1},tag:{type:String,default:"div"}},setup(t){s(()=>t.excerpt,n=>{var e,a,i;n&&!((e=t.value)!=null&&e.excerpt)&&(console.warn(`No excerpt found for document content/${(a=t==null?void 0:t.value)==null?void 0:a._path}.${(i=t==null?void 0:t.value)==null?void 0:i._extension}!`),console.warn("Make sure to use in your content if you want to use excerpt feature."))},{immediate:!0})},render(t){var u,c;const n=d(),{value:e,excerpt:a,tag:i}=t,r=a?e==null?void 0:e.excerpt:e==null?void 0:e.body;return!((u=r==null?void 0:r.children)!=null&&u.length)&&(n!=null&&n.empty)?n.empty({value:e,excerpt:a,tag:i,...this.$attrs}):n!=null&&n.default?n.default({value:e,excerpt:a,tag:i,...this.$attrs}):(r==null?void 0:r.type)==="root"&&((c=r==null?void 0:r.children)!=null&&c.length)?f(o,{value:e,excerpt:a,tag:i,...this.$attrs}):f("pre",null,JSON.stringify({message:"You should use slots with ",value:e,excerpt:a,tag:i},null,2))}});export{g as default}; +import{_ as o}from"./ContentRendererMarkdown.vue.RczDmK50.js";import{g as l,i as s,x as d,z as f}from"./entry.PS9LLiT2.js";import"./index.1dSrIji7.js";import"./preview.99XykmGH.js";const g=l({name:"ContentRenderer",props:{value:{type:Object,required:!1,default:()=>({})},excerpt:{type:Boolean,default:!1},tag:{type:String,default:"div"}},setup(t){s(()=>t.excerpt,n=>{var e,a,i;n&&!((e=t.value)!=null&&e.excerpt)&&(console.warn(`No excerpt found for document content/${(a=t==null?void 0:t.value)==null?void 0:a._path}.${(i=t==null?void 0:t.value)==null?void 0:i._extension}!`),console.warn("Make sure to use in your content if you want to use excerpt feature."))},{immediate:!0})},render(t){var u,c;const n=d(),{value:e,excerpt:a,tag:i}=t,r=a?e==null?void 0:e.excerpt:e==null?void 0:e.body;return!((u=r==null?void 0:r.children)!=null&&u.length)&&(n!=null&&n.empty)?n.empty({value:e,excerpt:a,tag:i,...this.$attrs}):n!=null&&n.default?n.default({value:e,excerpt:a,tag:i,...this.$attrs}):(r==null?void 0:r.type)==="root"&&((c=r==null?void 0:r.children)!=null&&c.length)?f(o,{value:e,excerpt:a,tag:i,...this.$attrs}):f("pre",null,JSON.stringify({message:"You should use slots with ",value:e,excerpt:a,tag:i},null,2))}});export{g as default}; diff --git a/_nuxt/ContentRendererMarkdown.T55ooTnH.js b/_nuxt/ContentRendererMarkdown.T55ooTnH.js new file mode 100644 index 0000000..0c1cd59 --- /dev/null +++ b/_nuxt/ContentRendererMarkdown.T55ooTnH.js @@ -0,0 +1 @@ +import{_ as o}from"./ContentRendererMarkdown.vue.RczDmK50.js";import"./entry.PS9LLiT2.js";import"./index.1dSrIji7.js";import"./preview.99XykmGH.js";export{o as default}; diff --git a/_nuxt/ContentRendererMarkdown.TQHLBOHw.js b/_nuxt/ContentRendererMarkdown.TQHLBOHw.js deleted file mode 100644 index adbfa34..0000000 --- a/_nuxt/ContentRendererMarkdown.TQHLBOHw.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as o}from"./ContentRendererMarkdown.vue.QtxrB05Z.js";import"./entry.kyqmbcaI.js";import"./index.1dSrIji7.js";import"./preview.WHtoAZxr.js";export{o as default}; diff --git a/_nuxt/ContentRendererMarkdown.vue.QtxrB05Z.js b/_nuxt/ContentRendererMarkdown.vue.RczDmK50.js similarity index 99% rename from _nuxt/ContentRendererMarkdown.vue.QtxrB05Z.js rename to _nuxt/ContentRendererMarkdown.vue.RczDmK50.js index cb8606f..d2de17d 100644 --- a/_nuxt/ContentRendererMarkdown.vue.QtxrB05Z.js +++ b/_nuxt/ContentRendererMarkdown.vue.RczDmK50.js @@ -1 +1 @@ -import{g as z,v as J,W as G,h as x,z as E,X as Q,Y as w,q as nn,Z as ln,o as en,$ as on,u as tn}from"./entry.kyqmbcaI.js";import{p as I,k as rn}from"./index.1dSrIji7.js";import{u as an}from"./preview.WHtoAZxr.js";class S{constructor(l,o,t){this.property=l,this.normal=o,t&&(this.space=t)}}S.prototype.property={};S.prototype.normal={};S.prototype.space=null;function j(n,l){const o={},t={};let r=-1;for(;++r4&&o.slice(0,4)==="data"&&dn.test(l)){if(l.charAt(4)==="-"){const a=l.slice(5).replace(U,fn);t="data"+a.charAt(0).toUpperCase()+a.slice(1)}else{const a=l.slice(4);if(!U.test(a)){let i=a.replace(gn,mn);i.charAt(0)!=="-"&&(i="-"+i),l="data"+i}}r=R}return new r(t,l)}function mn(n){return"-"+n.toLowerCase()}function fn(n){return n.charAt(1).toUpperCase()}const yn=j([H,F,N,W,cn],"html");j([H,F,N,W,pn],"svg");const T=["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","label","legend","li","link","main","map","mark","math","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rb","rp","rt","rtc","ruby","s","samp","script","section","select","slot","small","source","span","strong","style","sub","summary","sup","svg","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr"],M="default",K=/^@|^v-on:/,X=/^:|^v-bind:/,Y=/^v-model/,vn=["select","textarea","input"],bn=Object.fromEntries(["p","a","blockquote","code","pre","code","em","h1","h2","h3","h4","h5","h6","hr","img","ul","ol","li","strong","table","thead","tbody","td","th","tr","script"].map(n=>[n,`prose-${n}`])),kn=z({name:"MDCRenderer",props:{body:{type:Object,required:!0},data:{type:Object,default:()=>({})},tag:{type:[String,Boolean],default:void 0},prose:{type:Boolean,default:void 0},components:{type:Object,default:()=>({})}},async setup(n){var r,a;const{mdc:l}=J().public,o={...l.components.prose&&n.prose!==!1?bn:{},...l.components.map,...G(((a=(r=n.data)==null?void 0:r.mdc)==null?void 0:a.components)||{}),...n.components},t=x(()=>{var s;const i=(((s=n.body)==null?void 0:s.children)||[]).map(c=>c.tag||c.type).filter(c=>!T.includes(c));return Array.from(new Set(i)).sort().join(".")});return await Tn(n.body,{tags:o}),{tags:o,contentKey:t}},render(n){var h,y,d;const{tags:l,tag:o,body:t,data:r,contentKey:a}=n;if(!t)return null;const i={...r,tags:l},s=o!==!1?A(o||((h=i.component)==null?void 0:h.name)||i.component||"div"):void 0,c=$(t,E,i,i);return s?E(s,{...(y=i.component)==null?void 0:y.props,...this.$attrs,key:a},c):(d=c.default)==null?void 0:d.call(c)}});function Cn(n,l,o,t={}){if(n.type==="text")return l(w,n.value);const r=n.tag,a=Z(n,o.tags);if(n.tag==="binding")return Sn(n,l,o,t);const i=A(a);typeof i=="object"&&(i.tag=r);const s=xn(n,o);return l(i,s,$(n,l,o,{...t,...s}))}function Sn(n,l,o,t={}){var h,y;const r={...t,$route:()=>nn(),$document:o,$doc:o},a=/\.|\[(\d+)\]/,s=((h=n.props)==null?void 0:h.value.trim().split(a).filter(Boolean)).reduce((d,b)=>b in d?typeof d[b]=="function"?d[b]():d[b]:{},r),c=(y=n.props)==null?void 0:y.defaultValue;return l(w,s??c??"")}function $(n,l,o,t){const a=(n.children||[]).reduce((s,c)=>{if(!Mn(c))return s[M].push(c),s;const h=Ln(c);return s[h]=s[h]||[],c.type==="element"&&s[h].push(...c.children||[]),s},{[M]:[]});return Object.entries(a).reduce((s,[c,h])=>(h.length&&(s[c]=()=>{const y=h.map(d=>Cn(d,l,o,t));return Rn(y)}),s),{})}function xn(n,l){const{tag:o="",props:t={}}=n;return Object.keys(t).reduce(function(r,a){if(a==="__ignoreMap")return r;const i=t[a];if(Y.test(a)&&!vn.includes(o))return wn(a,i,r,l);if(a==="v-bind")return Pn(a,i,r,l);if(K.test(a))return On(a,i,r,l);if(X.test(a))return Dn(a,i,r,l);const{attribute:s}=hn(yn,a);return Array.isArray(i)&&i.every(c=>typeof c=="string")?(r[s]=i.join(" "),r):(r[s]=i,r)},{})}function wn(n,l,o,t){const r=d=>+d,a=d=>d.trim(),i=d=>d,s=n.replace(Y,"").split(".").filter(d=>d).reduce((d,b)=>(d[b]=!0,d),{}),c="value",h=s.lazy?"change":"input",y=s.number?r:s.trim?a:i;return o[c]=P(l,t),o.on=o.on||{},o.on[h]=d=>t[l]=y(d),o}function Pn(n,l,o,t){const r=P(l,t);return o=Object.assign(o,r),o}function On(n,l,o,t){return n=n.replace(K,""),o.on=o.on||{},o.on[n]=()=>P(l,t),o}function Dn(n,l,o,t){return n=n.replace(X,""),o[n]=P(l,t),o}const A=n=>{if(!T.includes(n)&&!(n!=null&&n.render)){const l=Q(I(n),!1);if(typeof l=="object")return l}return n};function P(n,l){const o=n.split(".").reduce((t,r)=>typeof t=="object"?t[r]:void 0,l);return typeof o>"u"?ln(n):o}function Ln(n){let l="";for(const o of Object.keys(n.props||{}))if(!(!o.startsWith("#")&&!o.startsWith("v-slot:"))){l=o.split(/[:#]/,2)[1];break}return l||M}function Mn(n){return n.tag==="template"}function Rn(n){const l=[];for(const o of n){const t=l[l.length-1];o.type===w&&(t==null?void 0:t.type)===w?t.children=t.children+o.children:l.push(o)}return l}async function Tn(n,l){if(!n)return;const o=Array.from(new Set(t(n,l)));await Promise.all(o.map(async r=>{if(r!=null&&r.render||r!=null&&r.ssrRender||r!=null&&r.__ssrInlineRender)return;const a=A(r);a!=null&&a.__asyncLoader&&!a.__asyncResolved&&await a.__asyncLoader()}));function t(r,a){const i=r.tag;if(r.type==="text"||i==="binding")return[];const s=Z(r,a.tags),c=[];r.type!=="root"&&!T.includes(s)&&c.push(s);for(const h of r.children||[])c.push(...t(h,a));return c}}function Z(n,l){var t;const o=n.tag;return!o||typeof((t=n.props)==null?void 0:t.__ignoreMap)<"u"?o:l[o]||l[I(o)]||l[rn(n.tag)]||o}const Un=z({__name:"ContentRendererMarkdown",props:{value:{type:Object,required:!0},excerpt:{type:Boolean,default:!1},tag:{type:String,default:"div"},components:{type:Object,default:()=>({})},data:{type:Object,default:()=>({})}},setup(n){const l=n,o=an().isEnabled(),t=x(()=>{let i=l.value.body||l.value;return l.excerpt&&l.value.excerpt&&(i=l.value.excerpt),i}),r=x(()=>{const{body:i,excerpt:s,...c}=l.value;return{...c,...l.data}}),a=x(()=>({...l.components,...r.value._components||{}}));return(i,s)=>{const c=kn;return en(),on(c,{body:t.value,data:r.value,tag:n.tag,components:a.value,"data-content-id":tn(o)?n.value._id:void 0},null,8,["body","data","tag","components","data-content-id"])}}});export{Un as _}; +import{g as z,v as J,W as G,h as x,z as E,X as Q,Y as w,q as nn,Z as ln,o as en,$ as on,u as tn}from"./entry.PS9LLiT2.js";import{p as I,k as rn}from"./index.1dSrIji7.js";import{u as an}from"./preview.99XykmGH.js";class S{constructor(l,o,t){this.property=l,this.normal=o,t&&(this.space=t)}}S.prototype.property={};S.prototype.normal={};S.prototype.space=null;function j(n,l){const o={},t={};let r=-1;for(;++r4&&o.slice(0,4)==="data"&&dn.test(l)){if(l.charAt(4)==="-"){const a=l.slice(5).replace(U,fn);t="data"+a.charAt(0).toUpperCase()+a.slice(1)}else{const a=l.slice(4);if(!U.test(a)){let i=a.replace(gn,mn);i.charAt(0)!=="-"&&(i="-"+i),l="data"+i}}r=R}return new r(t,l)}function mn(n){return"-"+n.toLowerCase()}function fn(n){return n.charAt(1).toUpperCase()}const yn=j([H,F,N,W,cn],"html");j([H,F,N,W,pn],"svg");const T=["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","label","legend","li","link","main","map","mark","math","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rb","rp","rt","rtc","ruby","s","samp","script","section","select","slot","small","source","span","strong","style","sub","summary","sup","svg","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr"],M="default",K=/^@|^v-on:/,X=/^:|^v-bind:/,Y=/^v-model/,vn=["select","textarea","input"],bn=Object.fromEntries(["p","a","blockquote","code","pre","code","em","h1","h2","h3","h4","h5","h6","hr","img","ul","ol","li","strong","table","thead","tbody","td","th","tr","script"].map(n=>[n,`prose-${n}`])),kn=z({name:"MDCRenderer",props:{body:{type:Object,required:!0},data:{type:Object,default:()=>({})},tag:{type:[String,Boolean],default:void 0},prose:{type:Boolean,default:void 0},components:{type:Object,default:()=>({})}},async setup(n){var r,a;const{mdc:l}=J().public,o={...l.components.prose&&n.prose!==!1?bn:{},...l.components.map,...G(((a=(r=n.data)==null?void 0:r.mdc)==null?void 0:a.components)||{}),...n.components},t=x(()=>{var s;const i=(((s=n.body)==null?void 0:s.children)||[]).map(c=>c.tag||c.type).filter(c=>!T.includes(c));return Array.from(new Set(i)).sort().join(".")});return await Tn(n.body,{tags:o}),{tags:o,contentKey:t}},render(n){var h,y,d;const{tags:l,tag:o,body:t,data:r,contentKey:a}=n;if(!t)return null;const i={...r,tags:l},s=o!==!1?A(o||((h=i.component)==null?void 0:h.name)||i.component||"div"):void 0,c=$(t,E,i,i);return s?E(s,{...(y=i.component)==null?void 0:y.props,...this.$attrs,key:a},c):(d=c.default)==null?void 0:d.call(c)}});function Cn(n,l,o,t={}){if(n.type==="text")return l(w,n.value);const r=n.tag,a=Z(n,o.tags);if(n.tag==="binding")return Sn(n,l,o,t);const i=A(a);typeof i=="object"&&(i.tag=r);const s=xn(n,o);return l(i,s,$(n,l,o,{...t,...s}))}function Sn(n,l,o,t={}){var h,y;const r={...t,$route:()=>nn(),$document:o,$doc:o},a=/\.|\[(\d+)\]/,s=((h=n.props)==null?void 0:h.value.trim().split(a).filter(Boolean)).reduce((d,b)=>b in d?typeof d[b]=="function"?d[b]():d[b]:{},r),c=(y=n.props)==null?void 0:y.defaultValue;return l(w,s??c??"")}function $(n,l,o,t){const a=(n.children||[]).reduce((s,c)=>{if(!Mn(c))return s[M].push(c),s;const h=Ln(c);return s[h]=s[h]||[],c.type==="element"&&s[h].push(...c.children||[]),s},{[M]:[]});return Object.entries(a).reduce((s,[c,h])=>(h.length&&(s[c]=()=>{const y=h.map(d=>Cn(d,l,o,t));return Rn(y)}),s),{})}function xn(n,l){const{tag:o="",props:t={}}=n;return Object.keys(t).reduce(function(r,a){if(a==="__ignoreMap")return r;const i=t[a];if(Y.test(a)&&!vn.includes(o))return wn(a,i,r,l);if(a==="v-bind")return Pn(a,i,r,l);if(K.test(a))return On(a,i,r,l);if(X.test(a))return Dn(a,i,r,l);const{attribute:s}=hn(yn,a);return Array.isArray(i)&&i.every(c=>typeof c=="string")?(r[s]=i.join(" "),r):(r[s]=i,r)},{})}function wn(n,l,o,t){const r=d=>+d,a=d=>d.trim(),i=d=>d,s=n.replace(Y,"").split(".").filter(d=>d).reduce((d,b)=>(d[b]=!0,d),{}),c="value",h=s.lazy?"change":"input",y=s.number?r:s.trim?a:i;return o[c]=P(l,t),o.on=o.on||{},o.on[h]=d=>t[l]=y(d),o}function Pn(n,l,o,t){const r=P(l,t);return o=Object.assign(o,r),o}function On(n,l,o,t){return n=n.replace(K,""),o.on=o.on||{},o.on[n]=()=>P(l,t),o}function Dn(n,l,o,t){return n=n.replace(X,""),o[n]=P(l,t),o}const A=n=>{if(!T.includes(n)&&!(n!=null&&n.render)){const l=Q(I(n),!1);if(typeof l=="object")return l}return n};function P(n,l){const o=n.split(".").reduce((t,r)=>typeof t=="object"?t[r]:void 0,l);return typeof o>"u"?ln(n):o}function Ln(n){let l="";for(const o of Object.keys(n.props||{}))if(!(!o.startsWith("#")&&!o.startsWith("v-slot:"))){l=o.split(/[:#]/,2)[1];break}return l||M}function Mn(n){return n.tag==="template"}function Rn(n){const l=[];for(const o of n){const t=l[l.length-1];o.type===w&&(t==null?void 0:t.type)===w?t.children=t.children+o.children:l.push(o)}return l}async function Tn(n,l){if(!n)return;const o=Array.from(new Set(t(n,l)));await Promise.all(o.map(async r=>{if(r!=null&&r.render||r!=null&&r.ssrRender||r!=null&&r.__ssrInlineRender)return;const a=A(r);a!=null&&a.__asyncLoader&&!a.__asyncResolved&&await a.__asyncLoader()}));function t(r,a){const i=r.tag;if(r.type==="text"||i==="binding")return[];const s=Z(r,a.tags),c=[];r.type!=="root"&&!T.includes(s)&&c.push(s);for(const h of r.children||[])c.push(...t(h,a));return c}}function Z(n,l){var t;const o=n.tag;return!o||typeof((t=n.props)==null?void 0:t.__ignoreMap)<"u"?o:l[o]||l[I(o)]||l[rn(n.tag)]||o}const Un=z({__name:"ContentRendererMarkdown",props:{value:{type:Object,required:!0},excerpt:{type:Boolean,default:!1},tag:{type:String,default:"div"},components:{type:Object,default:()=>({})},data:{type:Object,default:()=>({})}},setup(n){const l=n,o=an().isEnabled(),t=x(()=>{let i=l.value.body||l.value;return l.excerpt&&l.value.excerpt&&(i=l.value.excerpt),i}),r=x(()=>{const{body:i,excerpt:s,...c}=l.value;return{...c,...l.data}}),a=x(()=>({...l.components,...r.value._components||{}}));return(i,s)=>{const c=kn;return en(),on(c,{body:t.value,data:r.value,tag:n.tag,components:a.value,"data-content-id":tn(o)?n.value._id:void 0},null,8,["body","data","tag","components","data-content-id"])}}});export{Un as _}; diff --git a/_nuxt/ContentSlot.yUuC7AiQ.js b/_nuxt/ContentSlot.4Yv1O94w.js similarity index 96% rename from _nuxt/ContentSlot.yUuC7AiQ.js rename to _nuxt/ContentSlot.4Yv1O94w.js index d805480..738d00f 100644 --- a/_nuxt/ContentSlot.yUuC7AiQ.js +++ b/_nuxt/ContentSlot.4Yv1O94w.js @@ -1 +1 @@ -import{g as p,x as m,h as A,z as l,H as g}from"./entry.kyqmbcaI.js";const w=["p","h1","h2","h3","h4","h5","h6","li"];function f(r,t){return r.type===t||typeof r.type=="object"&&r.type.tag===t||r.tag===t}function s(r){return f(r,"text")||f(r,Symbol.for("v-txt"))}function y(r){var t;return Array.isArray(r.children)||typeof r.children=="string"?r.children:typeof((t=r.children)==null?void 0:t.default)=="function"?r.children.default():[]}function a(r){if(!r)return"";if(Array.isArray(r))return r.map(a).join("");if(s(r))return r.children||r.value||"";const t=y(r);return Array.isArray(t)?t.map(a).filter(Boolean).join(""):""}function c(r,t=[]){if(Array.isArray(r))return r.flatMap(n=>c(n,t));let e=r;return t.some(n=>n==="*"||f(r,n))&&(e=y(r)||r,!Array.isArray(e)&&w.some(n=>f(r,n))&&(e=[e])),e}function h(r,t=[]){return r=Array.isArray(r)?r:[r],t.length?r.flatMap(e=>h(c(e,[t[0]]),t.slice(1))).filter(e=>!(s(e)&&a(e).trim()==="")):r}function S(r,t=[]){return typeof t=="string"&&(t=t.split(",").map(e=>e.trim()).filter(Boolean)),t.length?h(r,t).reduce((e,n)=>(s(n)?typeof e[e.length-1]=="string"?e[e.length-1]+=n.children:e.push(n.children):e.push(n),e),[]):r}const x=p({name:"MDCSlot",functional:!0,props:{name:{type:String,default:"default"},unwrap:{type:[Boolean,String],default:!1},use:{type:Function,default:void 0}},setup(r){const{parent:t}=g(),{default:e}=m(),n=A(()=>typeof r.unwrap=="string"?r.unwrap.split(" "):["*"]);return{fallbackSlot:e,tags:n,parent:t}},render({use:r,unwrap:t,fallbackSlot:e,tags:n,parent:i}){var o;try{let u=r;return typeof r=="string"&&(u=(i==null?void 0:i.slots[r])||((o=i==null?void 0:i.parent)==null?void 0:o.slots[r]),console.warn(`Please set :use="$slots.${r}" in component to enable reactivity`)),u?t?S(u(),n):[u()]:e?e():l("div")}catch{return l("div")}}}),T=p({props:{use:{type:Function,default:void 0},unwrap:{type:[Boolean,String],default:!1}},render(r){return l(x,r)}});export{T as default}; +import{g as p,x as m,h as A,z as l,H as g}from"./entry.PS9LLiT2.js";const w=["p","h1","h2","h3","h4","h5","h6","li"];function f(r,t){return r.type===t||typeof r.type=="object"&&r.type.tag===t||r.tag===t}function s(r){return f(r,"text")||f(r,Symbol.for("v-txt"))}function y(r){var t;return Array.isArray(r.children)||typeof r.children=="string"?r.children:typeof((t=r.children)==null?void 0:t.default)=="function"?r.children.default():[]}function a(r){if(!r)return"";if(Array.isArray(r))return r.map(a).join("");if(s(r))return r.children||r.value||"";const t=y(r);return Array.isArray(t)?t.map(a).filter(Boolean).join(""):""}function c(r,t=[]){if(Array.isArray(r))return r.flatMap(n=>c(n,t));let e=r;return t.some(n=>n==="*"||f(r,n))&&(e=y(r)||r,!Array.isArray(e)&&w.some(n=>f(r,n))&&(e=[e])),e}function h(r,t=[]){return r=Array.isArray(r)?r:[r],t.length?r.flatMap(e=>h(c(e,[t[0]]),t.slice(1))).filter(e=>!(s(e)&&a(e).trim()==="")):r}function S(r,t=[]){return typeof t=="string"&&(t=t.split(",").map(e=>e.trim()).filter(Boolean)),t.length?h(r,t).reduce((e,n)=>(s(n)?typeof e[e.length-1]=="string"?e[e.length-1]+=n.children:e.push(n.children):e.push(n),e),[]):r}const x=p({name:"MDCSlot",functional:!0,props:{name:{type:String,default:"default"},unwrap:{type:[Boolean,String],default:!1},use:{type:Function,default:void 0}},setup(r){const{parent:t}=g(),{default:e}=m(),n=A(()=>typeof r.unwrap=="string"?r.unwrap.split(" "):["*"]);return{fallbackSlot:e,tags:n,parent:t}},render({use:r,unwrap:t,fallbackSlot:e,tags:n,parent:i}){var o;try{let u=r;return typeof r=="string"&&(u=(i==null?void 0:i.slots[r])||((o=i==null?void 0:i.parent)==null?void 0:o.slots[r]),console.warn(`Please set :use="$slots.${r}" in component to enable reactivity`)),u?t?S(u(),n):[u()]:e?e():l("div")}catch{return l("div")}}}),T=p({props:{use:{type:Function,default:void 0},unwrap:{type:[Boolean,String],default:!1}},render(r){return l(x,r)}});export{T as default}; diff --git a/_nuxt/DocumentDrivenEmpty.FNlONpq4.js b/_nuxt/DocumentDrivenEmpty.2yjd1SSH.js similarity index 77% rename from _nuxt/DocumentDrivenEmpty.FNlONpq4.js rename to _nuxt/DocumentDrivenEmpty.2yjd1SSH.js index 63e23ff..6e622ca 100644 --- a/_nuxt/DocumentDrivenEmpty.FNlONpq4.js +++ b/_nuxt/DocumentDrivenEmpty.2yjd1SSH.js @@ -1 +1 @@ -import{g as n,z as e}from"./entry.kyqmbcaI.js";const r=n({name:"DocumentDrivenEmpty",props:{value:{type:Object,required:!0}},render({value:t}){return e("div",void 0,[e("p","Document is empty"),e("p",`Add content to it by opening ${t._source}/${t._file} file.`)])}});export{r as default}; +import{g as n,z as e}from"./entry.PS9LLiT2.js";const r=n({name:"DocumentDrivenEmpty",props:{value:{type:Object,required:!0}},render({value:t}){return e("div",void 0,[e("p","Document is empty"),e("p",`Add content to it by opening ${t._source}/${t._file} file.`)])}});export{r as default}; diff --git a/_nuxt/DocumentDrivenNotFound.PaEuZL54.js b/_nuxt/DocumentDrivenNotFound.ifYdODZj.js similarity index 59% rename from _nuxt/DocumentDrivenNotFound.PaEuZL54.js rename to _nuxt/DocumentDrivenNotFound.ifYdODZj.js index d3bf4df..dd7cdc9 100644 --- a/_nuxt/DocumentDrivenNotFound.PaEuZL54.js +++ b/_nuxt/DocumentDrivenNotFound.ifYdODZj.js @@ -1 +1 @@ -import{g as n,z as e}from"./entry.kyqmbcaI.js";const t=n({name:"DocumentDrivenNotFound",render(){return e("div","Document not found")}});export{t as default}; +import{g as n,z as e}from"./entry.PS9LLiT2.js";const t=n({name:"DocumentDrivenNotFound",render(){return e("div","Document not found")}});export{t as default}; diff --git a/_nuxt/Markdown.PGpQEzUu.js b/_nuxt/Markdown.Ni6QM3--.js similarity index 61% rename from _nuxt/Markdown.PGpQEzUu.js rename to _nuxt/Markdown.Ni6QM3--.js index 4afcc98..5dc8da2 100644 --- a/_nuxt/Markdown.PGpQEzUu.js +++ b/_nuxt/Markdown.Ni6QM3--.js @@ -1 +1 @@ -import r from"./ContentSlot.yUuC7AiQ.js";import{g as o,x as u,h as f,H as c}from"./entry.kyqmbcaI.js";const i=o({name:"Markdown",extends:r,setup(t){const{parent:e}=c(),{between:n,default:a}=u(),s=f(()=>typeof t.unwrap=="string"?t.unwrap.split(" "):["*"]);return{fallbackSlot:a,tags:s,between:n,parent:e}}});export{i as default}; +import r from"./ContentSlot.4Yv1O94w.js";import{g as o,x as u,h as f,H as c}from"./entry.PS9LLiT2.js";const i=o({name:"Markdown",extends:r,setup(t){const{parent:e}=c(),{between:n,default:a}=u(),s=f(()=>typeof t.unwrap=="string"?t.unwrap.split(" "):["*"]);return{fallbackSlot:a,tags:s,between:n,parent:e}}});export{i as default}; diff --git a/_nuxt/ProseA.mjBdkCoM.js b/_nuxt/ProseA.Gnk6FU_h.js similarity index 64% rename from _nuxt/ProseA.mjBdkCoM.js rename to _nuxt/ProseA.Gnk6FU_h.js index abb0d79..dbe69bd 100644 --- a/_nuxt/ProseA.mjBdkCoM.js +++ b/_nuxt/ProseA.Gnk6FU_h.js @@ -1 +1 @@ -import{g as a,o as n,$ as o,w as s,a3 as f,e as u}from"./entry.kyqmbcaI.js";const _=a({__name:"ProseA",props:{href:{type:String,default:""},target:{type:String,default:void 0,required:!1}},setup(e){return(t,c)=>{const r=u;return n(),o(r,{href:e.href,target:e.target},{default:s(()=>[f(t.$slots,"default")]),_:3},8,["href","target"])}}});export{_ as default}; +import{g as a,o as n,$ as o,w as s,a3 as f,e as u}from"./entry.PS9LLiT2.js";const _=a({__name:"ProseA",props:{href:{type:String,default:""},target:{type:String,default:void 0,required:!1}},setup(e){return(t,c)=>{const r=u;return n(),o(r,{href:e.href,target:e.target},{default:s(()=>[f(t.$slots,"default")]),_:3},8,["href","target"])}}});export{_ as default}; diff --git a/_nuxt/ProseBlockquote.0zQiHAd5.js b/_nuxt/ProseBlockquote.IIuhyPCv.js similarity index 66% rename from _nuxt/ProseBlockquote.0zQiHAd5.js rename to _nuxt/ProseBlockquote.IIuhyPCv.js index ea035a4..718aacf 100644 --- a/_nuxt/ProseBlockquote.0zQiHAd5.js +++ b/_nuxt/ProseBlockquote.IIuhyPCv.js @@ -1 +1 @@ -import{_ as o,o as t,c,a3 as r}from"./entry.kyqmbcaI.js";const s={};function n(e,a){return t(),c("blockquote",null,[r(e.$slots,"default")])}const _=o(s,[["render",n]]);export{_ as default}; +import{_ as o,o as t,c,a3 as r}from"./entry.PS9LLiT2.js";const s={};function n(e,a){return t(),c("blockquote",null,[r(e.$slots,"default")])}const _=o(s,[["render",n]]);export{_ as default}; diff --git a/_nuxt/ProseCode.4ZscnP7G.js b/_nuxt/ProseCode.4ZscnP7G.js deleted file mode 100644 index 4d14e95..0000000 --- a/_nuxt/ProseCode.4ZscnP7G.js +++ /dev/null @@ -1 +0,0 @@ -import{_ as m}from"./ProseCode.vue.L3vrDCRe.js";import"./entry.kyqmbcaI.js";export{m as default}; diff --git a/_nuxt/ProseCode.QIyOSdyq.js b/_nuxt/ProseCode.QIyOSdyq.js new file mode 100644 index 0000000..c3fe784 --- /dev/null +++ b/_nuxt/ProseCode.QIyOSdyq.js @@ -0,0 +1 @@ +import{_ as m}from"./ProseCode.vue.rbas8gSm.js";import"./entry.PS9LLiT2.js";export{m as default}; diff --git a/_nuxt/ProseCode.vue.L3vrDCRe.js b/_nuxt/ProseCode.vue.rbas8gSm.js similarity index 80% rename from _nuxt/ProseCode.vue.L3vrDCRe.js rename to _nuxt/ProseCode.vue.rbas8gSm.js index 969598b..221d59f 100644 --- a/_nuxt/ProseCode.vue.L3vrDCRe.js +++ b/_nuxt/ProseCode.vue.rbas8gSm.js @@ -1 +1 @@ -import{g as t,a3 as a}from"./entry.kyqmbcaI.js";const o=t({__name:"ProseCode",props:{code:{type:String,default:""},language:{type:String,default:null},filename:{type:String,default:null},highlights:{type:Array,default:()=>[]},meta:{type:String,default:null}},setup(n){return(e,r)=>a(e.$slots,"default")}});export{o as _}; +import{g as t,a3 as a}from"./entry.PS9LLiT2.js";const o=t({__name:"ProseCode",props:{code:{type:String,default:""},language:{type:String,default:null},filename:{type:String,default:null},highlights:{type:Array,default:()=>[]},meta:{type:String,default:null}},setup(n){return(e,r)=>a(e.$slots,"default")}});export{o as _}; diff --git a/_nuxt/ProseCodeInline.D2qvyBIJ.js b/_nuxt/ProseCodeInline.o4JCub5L.js similarity index 66% rename from _nuxt/ProseCodeInline.D2qvyBIJ.js rename to _nuxt/ProseCodeInline.o4JCub5L.js index 3e8d7a5..b929586 100644 --- a/_nuxt/ProseCodeInline.D2qvyBIJ.js +++ b/_nuxt/ProseCodeInline.o4JCub5L.js @@ -1 +1 @@ -import{_ as o,o as n,c as r,a3 as c}from"./entry.kyqmbcaI.js";const s={};function t(e,a){return n(),r("code",null,[c(e.$slots,"default")])}const _=o(s,[["render",t]]);export{_ as default}; +import{_ as o,o as n,c as r,a3 as c}from"./entry.PS9LLiT2.js";const s={};function t(e,a){return n(),r("code",null,[c(e.$slots,"default")])}const _=o(s,[["render",t]]);export{_ as default}; diff --git a/_nuxt/ProseEm.IVSr4QqS.js b/_nuxt/ProseEm.4QCYOuXW.js similarity index 65% rename from _nuxt/ProseEm.IVSr4QqS.js rename to _nuxt/ProseEm.4QCYOuXW.js index 4793b9c..856035b 100644 --- a/_nuxt/ProseEm.IVSr4QqS.js +++ b/_nuxt/ProseEm.4QCYOuXW.js @@ -1 +1 @@ -import{_ as o,o as r,c as s,a3 as t}from"./entry.kyqmbcaI.js";const c={};function n(e,a){return r(),s("em",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; +import{_ as o,o as r,c as s,a3 as t}from"./entry.PS9LLiT2.js";const c={};function n(e,a){return r(),s("em",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/ProseH1.98vvHrNf.js b/_nuxt/ProseH1.eaEHGjQf.js similarity index 85% rename from _nuxt/ProseH1.98vvHrNf.js rename to _nuxt/ProseH1.eaEHGjQf.js index 8fde21b..8a27412 100644 --- a/_nuxt/ProseH1.98vvHrNf.js +++ b/_nuxt/ProseH1.eaEHGjQf.js @@ -1 +1 @@ -import{g as d,v as i,h as u,o as s,c as t,u as p,a3 as n}from"./entry.kyqmbcaI.js";const f=["id"],l=["href"],_=d({__name:"ProseH1",props:{id:{}},setup(a){const r=a,{headings:o}=i().public.mdc,c=u(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h1)});return(e,m)=>(s(),t("h1",{id:e.id},[p(c)?(s(),t("a",{key:0,href:`#${e.id}`},[n(e.$slots,"default")],8,l)):n(e.$slots,"default",{key:1})],8,f))}});export{_ as default}; +import{g as d,v as i,h as u,o as s,c as t,u as p,a3 as n}from"./entry.PS9LLiT2.js";const f=["id"],l=["href"],_=d({__name:"ProseH1",props:{id:{}},setup(a){const r=a,{headings:o}=i().public.mdc,c=u(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h1)});return(e,m)=>(s(),t("h1",{id:e.id},[p(c)?(s(),t("a",{key:0,href:`#${e.id}`},[n(e.$slots,"default")],8,l)):n(e.$slots,"default",{key:1})],8,f))}});export{_ as default}; diff --git a/_nuxt/ProseH2.3ZUTtu58.js b/_nuxt/ProseH2.yJsNSjEm.js similarity index 85% rename from _nuxt/ProseH2.3ZUTtu58.js rename to _nuxt/ProseH2.yJsNSjEm.js index ceba692..1deebb4 100644 --- a/_nuxt/ProseH2.3ZUTtu58.js +++ b/_nuxt/ProseH2.yJsNSjEm.js @@ -1 +1 @@ -import{g as i,v as c,h as u,o as s,c as n,u as p,a3 as t}from"./entry.kyqmbcaI.js";const f=["id"],l=["href"],k=i({__name:"ProseH2",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=u(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h2)});return(e,m)=>(s(),n("h2",{id:e.id},[e.id&&p(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; +import{g as i,v as c,h as u,o as s,c as n,u as p,a3 as t}from"./entry.PS9LLiT2.js";const f=["id"],l=["href"],k=i({__name:"ProseH2",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=u(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h2)});return(e,m)=>(s(),n("h2",{id:e.id},[e.id&&p(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; diff --git a/_nuxt/ProseH3.xS8JfK2d.js b/_nuxt/ProseH3.tODisIiG.js similarity index 85% rename from _nuxt/ProseH3.xS8JfK2d.js rename to _nuxt/ProseH3.tODisIiG.js index 76d3e3f..b2234d7 100644 --- a/_nuxt/ProseH3.xS8JfK2d.js +++ b/_nuxt/ProseH3.tODisIiG.js @@ -1 +1 @@ -import{g as i,v as c,h as u,o as s,c as n,u as p,a3 as t}from"./entry.kyqmbcaI.js";const f=["id"],l=["href"],k=i({__name:"ProseH3",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=u(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h3)});return(e,m)=>(s(),n("h3",{id:e.id},[e.id&&p(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; +import{g as i,v as c,h as u,o as s,c as n,u as p,a3 as t}from"./entry.PS9LLiT2.js";const f=["id"],l=["href"],k=i({__name:"ProseH3",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=u(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h3)});return(e,m)=>(s(),n("h3",{id:e.id},[e.id&&p(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; diff --git a/_nuxt/ProseH4.W0zxJSWG.js b/_nuxt/ProseH4.xj30r601.js similarity index 85% rename from _nuxt/ProseH4.W0zxJSWG.js rename to _nuxt/ProseH4.xj30r601.js index 0025980..53ceac7 100644 --- a/_nuxt/ProseH4.W0zxJSWG.js +++ b/_nuxt/ProseH4.xj30r601.js @@ -1 +1 @@ -import{g as i,v as c,h as u,o as s,c as n,u as p,a3 as t}from"./entry.kyqmbcaI.js";const f=["id"],l=["href"],k=i({__name:"ProseH4",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=u(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h4)});return(e,m)=>(s(),n("h4",{id:e.id},[e.id&&p(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; +import{g as i,v as c,h as u,o as s,c as n,u as p,a3 as t}from"./entry.PS9LLiT2.js";const f=["id"],l=["href"],k=i({__name:"ProseH4",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=u(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h4)});return(e,m)=>(s(),n("h4",{id:e.id},[e.id&&p(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; diff --git a/_nuxt/ProseH5.D_jmzZ-I.js b/_nuxt/ProseH5.q9bEm_2Z.js similarity index 85% rename from _nuxt/ProseH5.D_jmzZ-I.js rename to _nuxt/ProseH5.q9bEm_2Z.js index 77d3887..501377f 100644 --- a/_nuxt/ProseH5.D_jmzZ-I.js +++ b/_nuxt/ProseH5.q9bEm_2Z.js @@ -1 +1 @@ -import{g as i,v as c,h as u,o as s,c as n,u as p,a3 as t}from"./entry.kyqmbcaI.js";const f=["id"],l=["href"],k=i({__name:"ProseH5",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=u(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h5)});return(e,m)=>(s(),n("h5",{id:e.id},[e.id&&p(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; +import{g as i,v as c,h as u,o as s,c as n,u as p,a3 as t}from"./entry.PS9LLiT2.js";const f=["id"],l=["href"],k=i({__name:"ProseH5",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=u(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h5)});return(e,m)=>(s(),n("h5",{id:e.id},[e.id&&p(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; diff --git a/_nuxt/ProseH6.UGEbdmmN.js b/_nuxt/ProseH6.7fYg4335.js similarity index 85% rename from _nuxt/ProseH6.UGEbdmmN.js rename to _nuxt/ProseH6.7fYg4335.js index 31a0160..e2d7d68 100644 --- a/_nuxt/ProseH6.UGEbdmmN.js +++ b/_nuxt/ProseH6.7fYg4335.js @@ -1 +1 @@ -import{g as i,v as c,h as u,o as s,c as n,u as p,a3 as t}from"./entry.kyqmbcaI.js";const f=["id"],l=["href"],k=i({__name:"ProseH6",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=u(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h6)});return(e,m)=>(s(),n("h6",{id:e.id},[e.id&&p(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; +import{g as i,v as c,h as u,o as s,c as n,u as p,a3 as t}from"./entry.PS9LLiT2.js";const f=["id"],l=["href"],k=i({__name:"ProseH6",props:{id:{}},setup(a){const r=a,{headings:o}=c().public.mdc,d=u(()=>{var e;return r.id&&((e=o==null?void 0:o.anchorLinks)==null?void 0:e.h6)});return(e,m)=>(s(),n("h6",{id:e.id},[e.id&&p(d)?(s(),n("a",{key:0,href:`#${e.id}`},[t(e.$slots,"default")],8,l)):t(e.$slots,"default",{key:1})],8,f))}});export{k as default}; diff --git a/_nuxt/ProseHr.VSPhZaq6.js b/_nuxt/ProseHr.a_aaQ3qF.js similarity index 55% rename from _nuxt/ProseHr.VSPhZaq6.js rename to _nuxt/ProseHr.a_aaQ3qF.js index ed4df60..adf863d 100644 --- a/_nuxt/ProseHr.VSPhZaq6.js +++ b/_nuxt/ProseHr.a_aaQ3qF.js @@ -1 +1 @@ -import{_ as e,o as r,c}from"./entry.kyqmbcaI.js";const o={};function t(n,s){return r(),c("hr")}const a=e(o,[["render",t]]);export{a as default}; +import{_ as e,o as r,c}from"./entry.PS9LLiT2.js";const o={};function t(n,s){return r(),c("hr")}const a=e(o,[["render",t]]);export{a as default}; diff --git a/_nuxt/ProseImg._1ci9PF9.js b/_nuxt/ProseImg.Uaqj6QZM.js similarity index 89% rename from _nuxt/ProseImg._1ci9PF9.js rename to _nuxt/ProseImg.Uaqj6QZM.js index 471f5a7..557f3cb 100644 --- a/_nuxt/ProseImg._1ci9PF9.js +++ b/_nuxt/ProseImg.Uaqj6QZM.js @@ -1 +1 @@ -import{g as r,h as n,o as c,c as h,u as o,T as u,y as l,v as d,U as g}from"./entry.kyqmbcaI.js";const f=["src","alt","width","height"],p=r({__name:"ProseImg",props:{src:{type:String,default:""},alt:{type:String,default:""},width:{type:[String,Number],default:void 0},height:{type:[String,Number],default:void 0}},setup(e){const t=e,i=n(()=>{var a;if((a=t.src)!=null&&a.startsWith("/")&&!t.src.startsWith("//")){const s=u(l(d().app.baseURL));if(s!=="/"&&!t.src.startsWith(s))return g(s,t.src)}return t.src});return(a,s)=>(c(),h("img",{src:o(i),alt:e.alt,width:e.width,height:e.height},null,8,f))}});export{p as default}; +import{g as r,h as n,o as c,c as h,u as o,T as u,y as l,v as d,U as g}from"./entry.PS9LLiT2.js";const f=["src","alt","width","height"],p=r({__name:"ProseImg",props:{src:{type:String,default:""},alt:{type:String,default:""},width:{type:[String,Number],default:void 0},height:{type:[String,Number],default:void 0}},setup(e){const t=e,i=n(()=>{var a;if((a=t.src)!=null&&a.startsWith("/")&&!t.src.startsWith("//")){const s=u(l(d().app.baseURL));if(s!=="/"&&!t.src.startsWith(s))return g(s,t.src)}return t.src});return(a,s)=>(c(),h("img",{src:o(i),alt:e.alt,width:e.width,height:e.height},null,8,f))}});export{p as default}; diff --git a/_nuxt/ProseLi.pGb8hNnw.js b/_nuxt/ProseLi.7JA3q9E2.js similarity index 65% rename from _nuxt/ProseLi.pGb8hNnw.js rename to _nuxt/ProseLi.7JA3q9E2.js index 4eec846..3ec2f4c 100644 --- a/_nuxt/ProseLi.pGb8hNnw.js +++ b/_nuxt/ProseLi.7JA3q9E2.js @@ -1 +1 @@ -import{_ as o,o as r,c as s,a3 as t}from"./entry.kyqmbcaI.js";const c={};function n(e,a){return r(),s("li",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; +import{_ as o,o as r,c as s,a3 as t}from"./entry.PS9LLiT2.js";const c={};function n(e,a){return r(),s("li",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/ProseOl._vZ89wqu.js b/_nuxt/ProseOl.6gUkelNo.js similarity index 65% rename from _nuxt/ProseOl._vZ89wqu.js rename to _nuxt/ProseOl.6gUkelNo.js index 8d3c8bc..92c5b62 100644 --- a/_nuxt/ProseOl._vZ89wqu.js +++ b/_nuxt/ProseOl.6gUkelNo.js @@ -1 +1 @@ -import{_ as o,o as r,c as s,a3 as t}from"./entry.kyqmbcaI.js";const c={};function n(e,a){return r(),s("ol",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; +import{_ as o,o as r,c as s,a3 as t}from"./entry.PS9LLiT2.js";const c={};function n(e,a){return r(),s("ol",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/ProseP.l0BQwt1b.js b/_nuxt/ProseP.XuucEeBj.js similarity index 65% rename from _nuxt/ProseP.l0BQwt1b.js rename to _nuxt/ProseP.XuucEeBj.js index 0040abc..7f031ef 100644 --- a/_nuxt/ProseP.l0BQwt1b.js +++ b/_nuxt/ProseP.XuucEeBj.js @@ -1 +1 @@ -import{_ as o,o as r,c as s,a3 as t}from"./entry.kyqmbcaI.js";const c={};function n(e,a){return r(),s("p",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; +import{_ as o,o as r,c as s,a3 as t}from"./entry.PS9LLiT2.js";const c={};function n(e,a){return r(),s("p",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/ProsePre.f92e3HR-.js b/_nuxt/ProsePre.3GHfg6KT.js similarity index 74% rename from _nuxt/ProsePre.f92e3HR-.js rename to _nuxt/ProsePre.3GHfg6KT.js index b58b959..9e229b1 100644 --- a/_nuxt/ProsePre.f92e3HR-.js +++ b/_nuxt/ProsePre.3GHfg6KT.js @@ -1 +1 @@ -import{_ as l}from"./ProseCode.vue.L3vrDCRe.js";import{g as n,o as s,$ as i,w as o,n as r,l as g,a3 as u,a as f}from"./entry.kyqmbcaI.js";const h=n({__name:"ProsePre",props:{code:{type:String,default:""},language:{type:String,default:null},filename:{type:String,default:null},highlights:{type:Array,default:()=>[]},meta:{type:String,default:null},class:{type:String,default:null},style:{type:[String,Object],default:null}},setup(e){return(a,m)=>{const t=l;return s(),i(t,{code:e.code,language:e.language,filename:e.filename,highlights:e.highlights,meta:e.meta},{default:o(()=>[f("pre",{class:r(a.$props.class),style:g(e.style)},[u(a.$slots,"default")],6)]),_:3},8,["code","language","filename","highlights","meta"])}}});export{h as default}; +import{_ as l}from"./ProseCode.vue.rbas8gSm.js";import{g as n,o as s,$ as i,w as o,n as r,l as g,a3 as u,a as f}from"./entry.PS9LLiT2.js";const h=n({__name:"ProsePre",props:{code:{type:String,default:""},language:{type:String,default:null},filename:{type:String,default:null},highlights:{type:Array,default:()=>[]},meta:{type:String,default:null},class:{type:String,default:null},style:{type:[String,Object],default:null}},setup(e){return(a,m)=>{const t=l;return s(),i(t,{code:e.code,language:e.language,filename:e.filename,highlights:e.highlights,meta:e.meta},{default:o(()=>[f("pre",{class:r(a.$props.class),style:g(e.style)},[u(a.$slots,"default")],6)]),_:3},8,["code","language","filename","highlights","meta"])}}});export{h as default}; diff --git a/_nuxt/ProseScript.vwc6r6-w.js b/_nuxt/ProseScript.WQQ7lrh9.js similarity index 86% rename from _nuxt/ProseScript.vwc6r6-w.js rename to _nuxt/ProseScript.WQQ7lrh9.js index 2b3ae78..8eb935d 100644 --- a/_nuxt/ProseScript.vwc6r6-w.js +++ b/_nuxt/ProseScript.WQQ7lrh9.js @@ -1 +1 @@ -import{g as s,h as n,o as r,c as a,d as e,m as c,a as t}from"./entry.kyqmbcaI.js";const d={key:0},i=t("code",null,"script",-1),l=t("code",null,"ProseScript",-1),f=s({__name:"ProseScript",props:{src:{type:String,default:""}},setup(p){const o=n(()=>!1);return(m,_)=>o.value?(r(),a("div",d,[e(" Rendering the "),i,e(" element is dangerous and is disabled by default. Consider implementing your own "),l,e(" element to have control over script rendering. ")])):c("",!0)}});export{f as default}; +import{g as s,h as n,o as r,c as a,d as e,m as c,a as t}from"./entry.PS9LLiT2.js";const d={key:0},i=t("code",null,"script",-1),l=t("code",null,"ProseScript",-1),f=s({__name:"ProseScript",props:{src:{type:String,default:""}},setup(p){const o=n(()=>!1);return(m,_)=>o.value?(r(),a("div",d,[e(" Rendering the "),i,e(" element is dangerous and is disabled by default. Consider implementing your own "),l,e(" element to have control over script rendering. ")])):c("",!0)}});export{f as default}; diff --git a/_nuxt/ProseStrong.8IHfBQHv.js b/_nuxt/ProseStrong.q8mG-bZC.js similarity index 66% rename from _nuxt/ProseStrong.8IHfBQHv.js rename to _nuxt/ProseStrong.q8mG-bZC.js index 572fa90..2c3e95f 100644 --- a/_nuxt/ProseStrong.8IHfBQHv.js +++ b/_nuxt/ProseStrong.q8mG-bZC.js @@ -1 +1 @@ -import{_ as o,o as r,c as t,a3 as n}from"./entry.kyqmbcaI.js";const s={};function c(e,a){return r(),t("strong",null,[n(e.$slots,"default")])}const _=o(s,[["render",c]]);export{_ as default}; +import{_ as o,o as r,c as t,a3 as n}from"./entry.PS9LLiT2.js";const s={};function c(e,a){return r(),t("strong",null,[n(e.$slots,"default")])}const _=o(s,[["render",c]]);export{_ as default}; diff --git a/_nuxt/ProseTable.UwfW2q09.js b/_nuxt/ProseTable.5kBeO5qI.js similarity index 66% rename from _nuxt/ProseTable.UwfW2q09.js rename to _nuxt/ProseTable.5kBeO5qI.js index a93b3d7..2f65c89 100644 --- a/_nuxt/ProseTable.UwfW2q09.js +++ b/_nuxt/ProseTable.5kBeO5qI.js @@ -1 +1 @@ -import{_ as o,o as r,c as t,a3 as a}from"./entry.kyqmbcaI.js";const s={};function c(e,n){return r(),t("table",null,[a(e.$slots,"default")])}const _=o(s,[["render",c]]);export{_ as default}; +import{_ as o,o as r,c as t,a3 as a}from"./entry.PS9LLiT2.js";const s={};function c(e,n){return r(),t("table",null,[a(e.$slots,"default")])}const _=o(s,[["render",c]]);export{_ as default}; diff --git a/_nuxt/ProseTbody.76lFHrfY.js b/_nuxt/ProseTbody.FIDIkwnl.js similarity index 66% rename from _nuxt/ProseTbody.76lFHrfY.js rename to _nuxt/ProseTbody.FIDIkwnl.js index 6a98f3d..9e91454 100644 --- a/_nuxt/ProseTbody.76lFHrfY.js +++ b/_nuxt/ProseTbody.FIDIkwnl.js @@ -1 +1 @@ -import{_ as o,o as r,c as t,a3 as s}from"./entry.kyqmbcaI.js";const c={};function n(e,a){return r(),t("tbody",null,[s(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; +import{_ as o,o as r,c as t,a3 as s}from"./entry.PS9LLiT2.js";const c={};function n(e,a){return r(),t("tbody",null,[s(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/ProseTd.Mqlmzd0p.js b/_nuxt/ProseTd.KoI3F--9.js similarity index 65% rename from _nuxt/ProseTd.Mqlmzd0p.js rename to _nuxt/ProseTd.KoI3F--9.js index daf2d39..f19e33e 100644 --- a/_nuxt/ProseTd.Mqlmzd0p.js +++ b/_nuxt/ProseTd.KoI3F--9.js @@ -1 +1 @@ -import{_ as o,o as r,c as t,a3 as s}from"./entry.kyqmbcaI.js";const c={};function n(e,a){return r(),t("td",null,[s(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; +import{_ as o,o as r,c as t,a3 as s}from"./entry.PS9LLiT2.js";const c={};function n(e,a){return r(),t("td",null,[s(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/ProseTh.FnhkcspZ.js b/_nuxt/ProseTh.m9_aWQqV.js similarity index 65% rename from _nuxt/ProseTh.FnhkcspZ.js rename to _nuxt/ProseTh.m9_aWQqV.js index 0c8b526..05bb7c2 100644 --- a/_nuxt/ProseTh.FnhkcspZ.js +++ b/_nuxt/ProseTh.m9_aWQqV.js @@ -1 +1 @@ -import{_ as o,o as r,c as t,a3 as s}from"./entry.kyqmbcaI.js";const c={};function n(e,a){return r(),t("th",null,[s(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; +import{_ as o,o as r,c as t,a3 as s}from"./entry.PS9LLiT2.js";const c={};function n(e,a){return r(),t("th",null,[s(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/ProseThead.0jV4MZhn.js b/_nuxt/ProseThead.sBnyBi4S.js similarity index 66% rename from _nuxt/ProseThead.0jV4MZhn.js rename to _nuxt/ProseThead.sBnyBi4S.js index 05df0f8..cfb248c 100644 --- a/_nuxt/ProseThead.0jV4MZhn.js +++ b/_nuxt/ProseThead.sBnyBi4S.js @@ -1 +1 @@ -import{_ as o,o as r,c as t,a3 as a}from"./entry.kyqmbcaI.js";const s={};function c(e,n){return r(),t("thead",null,[a(e.$slots,"default")])}const _=o(s,[["render",c]]);export{_ as default}; +import{_ as o,o as r,c as t,a3 as a}from"./entry.PS9LLiT2.js";const s={};function c(e,n){return r(),t("thead",null,[a(e.$slots,"default")])}const _=o(s,[["render",c]]);export{_ as default}; diff --git a/_nuxt/ProseTr.Hqs34-B0.js b/_nuxt/ProseTr.YtSXwZb5.js similarity index 64% rename from _nuxt/ProseTr.Hqs34-B0.js rename to _nuxt/ProseTr.YtSXwZb5.js index 69d282b..7e36f8f 100644 --- a/_nuxt/ProseTr.Hqs34-B0.js +++ b/_nuxt/ProseTr.YtSXwZb5.js @@ -1 +1 @@ -import{_ as r,o,c as t,a3 as s}from"./entry.kyqmbcaI.js";const c={};function n(e,a){return o(),t("tr",null,[s(e.$slots,"default")])}const _=r(c,[["render",n]]);export{_ as default}; +import{_ as r,o,c as t,a3 as s}from"./entry.PS9LLiT2.js";const c={};function n(e,a){return o(),t("tr",null,[s(e.$slots,"default")])}const _=r(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/ProseUl.2DgLM2oK.js b/_nuxt/ProseUl.NGJ2KrmN.js similarity index 65% rename from _nuxt/ProseUl.2DgLM2oK.js rename to _nuxt/ProseUl.NGJ2KrmN.js index ed79740..7c28eb3 100644 --- a/_nuxt/ProseUl.2DgLM2oK.js +++ b/_nuxt/ProseUl.NGJ2KrmN.js @@ -1 +1 @@ -import{_ as o,o as r,c as s,a3 as t}from"./entry.kyqmbcaI.js";const c={};function n(e,a){return r(),s("ul",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; +import{_ as o,o as r,c as s,a3 as t}from"./entry.PS9LLiT2.js";const c={};function n(e,a){return r(),s("ul",null,[t(e.$slots,"default")])}const _=o(c,[["render",n]]);export{_ as default}; diff --git a/_nuxt/_...slug_.-1J-oLil.js b/_nuxt/_...slug_.-1J-oLil.js new file mode 100644 index 0000000..c3af2da --- /dev/null +++ b/_nuxt/_...slug_.-1J-oLil.js @@ -0,0 +1 @@ +import t from"./ContentDoc.rfis-nOt.js";import{_ as e,c as r,a as c,b as n,o as _}from"./entry.PS9LLiT2.js";import"./vue.f36acd1f.jcQdGPHq.js";import"./ContentRenderer.cy28u1UG.js";import"./ContentRendererMarkdown.vue.RczDmK50.js";import"./index.1dSrIji7.js";import"./preview.99XykmGH.js";import"./ContentQuery.8OtClJpg.js";import"./query.9Ah2Ct9x.js";const s={},a={class:"container mx-auto pt-6"};function m(p,i){const o=t;return _(),r("div",a,[c("article",null,[n(o,{class:"prose"})])])}const V=e(s,[["render",m]]);export{V as default}; diff --git a/_nuxt/_...slug_.6mwjtp-q.js b/_nuxt/_...slug_.6mwjtp-q.js deleted file mode 100644 index 14b44db..0000000 --- a/_nuxt/_...slug_.6mwjtp-q.js +++ /dev/null @@ -1 +0,0 @@ -import t from"./ContentDoc.m4erpRCJ.js";import{_ as e,c as r,a as c,b as n,o as _}from"./entry.kyqmbcaI.js";import"./vue.f36acd1f.ZfSKW0Tx.js";import"./ContentRenderer.0Ci8vnAh.js";import"./ContentRendererMarkdown.vue.QtxrB05Z.js";import"./index.1dSrIji7.js";import"./preview.WHtoAZxr.js";import"./ContentQuery.7IlyA-wt.js";import"./query.veKqiZiu.js";const s={},a={class:"container mx-auto pt-6"};function m(p,i){const o=t;return _(),r("div",a,[c("article",null,[n(o,{class:"prose"})])])}const V=e(s,[["render",m]]);export{V as default}; diff --git a/_nuxt/builds/latest.json b/_nuxt/builds/latest.json index 7452329..99b26fe 100644 --- a/_nuxt/builds/latest.json +++ b/_nuxt/builds/latest.json @@ -1 +1 @@ -{"id":"bb1ffd14-a21e-4a1d-9114-3af753bf049c","timestamp":1717319117239} \ No newline at end of file +{"id":"5c1e5955-a9a1-4785-b832-fac3e0fe121e","timestamp":1717319583000} \ No newline at end of file diff --git a/_nuxt/builds/meta/bb1ffd14-a21e-4a1d-9114-3af753bf049c.json b/_nuxt/builds/meta/5c1e5955-a9a1-4785-b832-fac3e0fe121e.json similarity index 61% rename from _nuxt/builds/meta/bb1ffd14-a21e-4a1d-9114-3af753bf049c.json rename to _nuxt/builds/meta/5c1e5955-a9a1-4785-b832-fac3e0fe121e.json index 38ba043..c52abe8 100644 --- a/_nuxt/builds/meta/bb1ffd14-a21e-4a1d-9114-3af753bf049c.json +++ b/_nuxt/builds/meta/5c1e5955-a9a1-4785-b832-fac3e0fe121e.json @@ -1 +1 @@ -{"id":"bb1ffd14-a21e-4a1d-9114-3af753bf049c","timestamp":1717319117239,"matcher":{"static":{"/":null,"/blog":{"redirect":"/"},"/blog/concurrency":{"redirect":"/concurrency"},"/blog/typescript-typesystems-and-javascript":{"redirect":"/typescript-typesystems-and-javascript"}},"wildcard":{},"dynamic":{}},"prerendered":["/blog","/","/typescript-typesystems-and-javascript","/ok-sometimes-async-await","/concurrency"]} \ No newline at end of file +{"id":"5c1e5955-a9a1-4785-b832-fac3e0fe121e","timestamp":1717319583000,"matcher":{"static":{"/":null,"/blog":{"redirect":"/"},"/blog/concurrency":{"redirect":"/concurrency"},"/blog/typescript-typesystems-and-javascript":{"redirect":"/typescript-typesystems-and-javascript"}},"wildcard":{},"dynamic":{}},"prerendered":["/blog","/","/typescript-typesystems-and-javascript","/ok-sometimes-async-await","/concurrency"]} \ No newline at end of file diff --git a/_nuxt/client-db.woz9fGTK.js b/_nuxt/client-db.j5h9Mw_L.js similarity index 99% rename from _nuxt/client-db.woz9fGTK.js rename to _nuxt/client-db.j5h9Mw_L.js index 319189c..22c468f 100644 --- a/_nuxt/client-db.woz9fGTK.js +++ b/_nuxt/client-db.j5h9Mw_L.js @@ -1 +1 @@ -import{U as z,v as N,S as b,L as W}from"./entry.kyqmbcaI.js";import{g as B,b as P,c as E,o as J,d as F,f as O,h as j,i as x,k}from"./query.veKqiZiu.js";import{p as H}from"./index.1dSrIji7.js";import{u as T}from"./preview.WHtoAZxr.js";const G="memory",Z=()=>{const e=new Map;return{name:G,options:{},hasItem(r){return e.has(r)},getItem(r){return e.get(r)??null},getItemRaw(r){return e.get(r)??null},setItem(r,n){e.set(r,n)},setItemRaw(r,n){e.set(r,n)},removeItem(r){e.delete(r)},getKeys(){return Array.from(e.keys())},clear(){e.clear()},dispose(){e.clear()}}},q=/"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,V=/"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,Q=/^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;function X(e,r){if(e==="__proto__"||e==="constructor"&&r&&typeof r=="object"&&"prototype"in r){ee(e);return}return r}function ee(e){console.warn(`[destr] Dropping "${e}" key to prevent prototype pollution.`)}function $(e,r={}){if(typeof e!="string")return e;const n=e.trim();if(e[0]==='"'&&e.at(-1)==='"'&&!e.includes("\\"))return n.slice(1,-1);if(n.length<=9){const i=n.toLowerCase();if(i==="true")return!0;if(i==="false")return!1;if(i==="undefined")return;if(i==="null")return null;if(i==="nan")return Number.NaN;if(i==="infinity")return Number.POSITIVE_INFINITY;if(i==="-infinity")return Number.NEGATIVE_INFINITY}if(!Q.test(e)){if(r.strict)throw new SyntaxError("[destr] Invalid JSON");return e}try{if(q.test(e)||V.test(e)){if(r.strict)throw new Error("[destr] Possible prototype pollution");return JSON.parse(e,X)}return JSON.parse(e)}catch(i){if(r.strict)throw i;return e}}function te(e){return!e||typeof e.then!="function"?Promise.resolve(e):e}function g(e,...r){try{return te(e(...r))}catch(n){return Promise.reject(n)}}function re(e){const r=typeof e;return e===null||r!=="object"&&r!=="function"}function ne(e){const r=Object.getPrototypeOf(e);return!r||r.isPrototypeOf(Object)}function K(e){if(re(e))return String(e);if(ne(e)||Array.isArray(e))return JSON.stringify(e);if(typeof e.toJSON=="function")return K(e.toJSON());throw new Error("[unstorage] Cannot stringify value!")}function U(){if(typeof Buffer===void 0)throw new TypeError("[unstorage] Buffer is not supported!")}const C="base64:";function ie(e){if(typeof e=="string")return e;U();const r=Buffer.from(e).toString("base64");return C+r}function se(e){return typeof e!="string"||!e.startsWith(C)?e:(U(),Buffer.from(e.slice(C.length),"base64"))}const ae=["hasItem","getItem","getItemRaw","setItem","setItemRaw","removeItem","getMeta","setMeta","removeMeta","getKeys","clear","mount","unmount"];function oe(e,r){if(r=A(r),!r)return e;const n={...e};for(const i of ae)n[i]=(f="",...c)=>e[i](r+f,...c);return n.getKeys=(i="",...f)=>e.getKeys(r+i,...f).then(c=>c.map(o=>o.slice(r.length))),n}function d(e){return e?e.split("?")[0].replace(/[/\\]/g,":").replace(/:+/g,":").replace(/^:|:$/g,""):""}function ue(...e){return d(e.join(":"))}function A(e){return e=d(e),e?e+":":""}const ce="memory",fe=()=>{const e=new Map;return{name:ce,options:{},hasItem(r){return e.has(r)},getItem(r){return e.get(r)??null},getItemRaw(r){return e.get(r)??null},setItem(r,n){e.set(r,n)},setItemRaw(r,n){e.set(r,n)},removeItem(r){e.delete(r)},getKeys(){return Array.from(e.keys())},clear(){e.clear()},dispose(){e.clear()}}};function le(e={}){const r={mounts:{"":e.driver||fe()},mountpoints:[""],watching:!1,watchListeners:[],unwatch:{}},n=t=>{for(const s of r.mountpoints)if(t.startsWith(s))return{base:s,relativeKey:t.slice(s.length),driver:r.mounts[s]};return{base:"",relativeKey:t,driver:r.mounts[""]}},i=(t,s)=>r.mountpoints.filter(a=>a.startsWith(t)||s&&t.startsWith(a)).map(a=>({relativeBase:t.length>a.length?t.slice(a.length):void 0,mountpoint:a,driver:r.mounts[a]})),f=(t,s)=>{if(r.watching){s=d(s);for(const a of r.watchListeners)a(t,s)}},c=async()=>{if(!r.watching){r.watching=!0;for(const t in r.mounts)r.unwatch[t]=await D(r.mounts[t],f,t)}},o=async()=>{if(r.watching){for(const t in r.unwatch)await r.unwatch[t]();r.unwatch={},r.watching=!1}},p=(t,s,a)=>{const u=new Map,l=m=>{let y=u.get(m.base);return y||(y={driver:m.driver,base:m.base,items:[]},u.set(m.base,y)),y};for(const m of t){const y=typeof m=="string",v=d(y?m:m.key),w=y?void 0:m.value,I=y||!m.options?s:{...s,...m.options},_=n(v);l(_).items.push({key:v,value:w,relativeKey:_.relativeKey,options:I})}return Promise.all([...u.values()].map(m=>a(m))).then(m=>m.flat())},h={hasItem(t,s={}){t=d(t);const{relativeKey:a,driver:u}=n(t);return g(u.hasItem,a,s)},getItem(t,s={}){t=d(t);const{relativeKey:a,driver:u}=n(t);return g(u.getItem,a,s).then(l=>$(l))},getItems(t,s){return p(t,s,a=>a.driver.getItems?g(a.driver.getItems,a.items.map(u=>({key:u.relativeKey,options:u.options})),s).then(u=>u.map(l=>({key:ue(a.base,l.key),value:$(l.value)}))):Promise.all(a.items.map(u=>g(a.driver.getItem,u.relativeKey,u.options).then(l=>({key:u.key,value:$(l)})))))},getItemRaw(t,s={}){t=d(t);const{relativeKey:a,driver:u}=n(t);return u.getItemRaw?g(u.getItemRaw,a,s):g(u.getItem,a,s).then(l=>se(l))},async setItem(t,s,a={}){if(s===void 0)return h.removeItem(t);t=d(t);const{relativeKey:u,driver:l}=n(t);l.setItem&&(await g(l.setItem,u,K(s),a),l.watch||f("update",t))},async setItems(t,s){await p(t,s,async a=>{a.driver.setItems&&await g(a.driver.setItems,a.items.map(u=>({key:u.relativeKey,value:K(u.value),options:u.options})),s),a.driver.setItem&&await Promise.all(a.items.map(u=>g(a.driver.setItem,u.relativeKey,K(u.value),u.options)))})},async setItemRaw(t,s,a={}){if(s===void 0)return h.removeItem(t,a);t=d(t);const{relativeKey:u,driver:l}=n(t);if(l.setItemRaw)await g(l.setItemRaw,u,s,a);else if(l.setItem)await g(l.setItem,u,ie(s),a);else return;l.watch||f("update",t)},async removeItem(t,s={}){typeof s=="boolean"&&(s={removeMeta:s}),t=d(t);const{relativeKey:a,driver:u}=n(t);u.removeItem&&(await g(u.removeItem,a,s),(s.removeMeta||s.removeMata)&&await g(u.removeItem,a+"$",s),u.watch||f("remove",t))},async getMeta(t,s={}){typeof s=="boolean"&&(s={nativeOnly:s}),t=d(t);const{relativeKey:a,driver:u}=n(t),l=Object.create(null);if(u.getMeta&&Object.assign(l,await g(u.getMeta,a,s)),!s.nativeOnly){const m=await g(u.getItem,a+"$",s).then(y=>$(y));m&&typeof m=="object"&&(typeof m.atime=="string"&&(m.atime=new Date(m.atime)),typeof m.mtime=="string"&&(m.mtime=new Date(m.mtime)),Object.assign(l,m))}return l},setMeta(t,s,a={}){return this.setItem(t+"$",s,a)},removeMeta(t,s={}){return this.removeItem(t+"$",s)},async getKeys(t,s={}){t=A(t);const a=i(t,!0);let u=[];const l=[];for(const m of a){const v=(await g(m.driver.getKeys,m.relativeBase,s)).map(w=>m.mountpoint+d(w)).filter(w=>!u.some(I=>w.startsWith(I)));l.push(...v),u=[m.mountpoint,...u.filter(w=>!w.startsWith(m.mountpoint))]}return t?l.filter(m=>m.startsWith(t)&&!m.endsWith("$")):l.filter(m=>!m.endsWith("$"))},async clear(t,s={}){t=A(t),await Promise.all(i(t,!1).map(async a=>{if(a.driver.clear)return g(a.driver.clear,a.relativeBase,s);if(a.driver.removeItem){const u=await a.driver.getKeys(a.relativeBase||"",s);return Promise.all(u.map(l=>a.driver.removeItem(l,s)))}}))},async dispose(){await Promise.all(Object.values(r.mounts).map(t=>L(t)))},async watch(t){return await c(),r.watchListeners.push(t),async()=>{r.watchListeners=r.watchListeners.filter(s=>s!==t),r.watchListeners.length===0&&await o()}},async unwatch(){r.watchListeners=[],await o()},mount(t,s){if(t=A(t),t&&r.mounts[t])throw new Error(`already mounted at ${t}`);return t&&(r.mountpoints.push(t),r.mountpoints.sort((a,u)=>u.length-a.length)),r.mounts[t]=s,r.watching&&Promise.resolve(D(s,f,t)).then(a=>{r.unwatch[t]=a}).catch(console.error),h},async unmount(t,s=!0){t=A(t),!(!t||!r.mounts[t])&&(r.watching&&t in r.unwatch&&(r.unwatch[t](),delete r.unwatch[t]),s&&await L(r.mounts[t]),r.mountpoints=r.mountpoints.filter(a=>a!==t),delete r.mounts[t])},getMount(t=""){t=d(t)+":";const s=n(t);return{driver:s.driver,base:s.base}},getMounts(t="",s={}){return t=d(t),i(t,s.parents).map(u=>({driver:u.driver,base:u.mountpoint}))}};return h}function D(e,r,n){return e.watch?e.watch((i,f)=>r(i,n+f)):()=>{}}async function L(e){typeof e.dispose=="function"&&await g(e.dispose)}function me(e={}){const r=pe(n,e.operators);function n(i,f){return typeof f!="object"||f instanceof RegExp?r.$eq(i,f):Object.keys(f||{}).every(c=>{const o=f[c];if(c.startsWith("$")&&r[c]){const p=r[c];return typeof p=="function"?p(i,o):!1}return n(B(i,c),o)})}return n}function pe(e,r={}){return{$match:(n,i)=>e(n,i),$eq:(n,i)=>i instanceof RegExp?i.test(n):n===i,$ne:(n,i)=>i instanceof RegExp?!i.test(n):n!==i,$not:(n,i)=>!e(n,i),$and:(n,i)=>(P(i,"$and requires an array as condition"),i.every(f=>e(n,f))),$or:(n,i)=>(P(i,"$or requires an array as condition"),i.some(f=>e(n,f))),$in:(n,i)=>E(i).some(f=>Array.isArray(n)?e(n,{$contains:f}):e(n,f)),$contains:(n,i)=>(n=Array.isArray(n)?n:String(n),E(i).every(f=>n.includes(f))),$icontains:(n,i)=>{if(typeof i!="string")throw new TypeError("$icontains requires a string, use $contains instead");return n=String(n).toLocaleLowerCase(),E(i).every(f=>n.includes(f.toLocaleLowerCase()))},$containsAny:(n,i)=>(P(i,"$containsAny requires an array as condition"),n=Array.isArray(n)?n:String(n),i.some(f=>n.includes(f))),$exists:(n,i)=>i?typeof n<"u":typeof n>"u",$type:(n,i)=>typeof n===String(i),$regex:(n,i)=>{if(!(i instanceof RegExp)){const f=String(i).match(/\/(.*)\/([dgimsuy]*)$/);i=f?new RegExp(f[1],f[2]||""):new RegExp(i)}return i.test(String(n||""))},$lt:(n,i)=>nn<=i,$gt:(n,i)=>n>i,$gte:(n,i)=>n>=i,...r||{}}}function he(e){const r=me(),n=(c,{query:o,before:p,after:h})=>{const t=typeof o=="string"?{_path:o}:o,s=c.findIndex(u=>r(u,t));p=p??1,h=h??1;const a=new Array(p+h).fill(null,0);return s===-1?a:a.map((u,l)=>c[s-p+l+ +(l>=p)]||null)},i=[(c,o)=>{const p=c.result.filter(h=>E(o.where).every(t=>r(h,t)));return{...c,result:p,total:p.length}},(c,o)=>E(o.sort).forEach(p=>F(c.result,p)),function(o,p,h){var t;if(p.surround){let s=n(((t=o.result)==null?void 0:t.length)===1?h:o.result,p.surround);s=O(j(p.without))(s),s=O(x(p.only))(s),o.surround=s}return o}],f=[(c,o)=>{if(o.skip)return{...c,result:c.result.slice(o.skip),skip:o.skip}},(c,o)=>{if(o.limit)return{...c,result:c.result.slice(0,o.limit),limit:o.limit}},function(o,p,h){var t,s,a;if(p.dirConfig){const u=((t=o.result[0])==null?void 0:t._path)||((a=(s=p.where)==null?void 0:s.find(l=>l._path))==null?void 0:a._path);if(typeof u=="string"){const l=h.find(m=>m._path===z(u,"_dir"));l&&(o.dirConfig={_path:l._path,...j(["_"])(l)})}}return o},(c,o)=>({...c,result:O(j(o.without))(c.result)}),(c,o)=>({...c,result:O(x(o.only))(c.result)})];return async c=>{const o=await e(),p=c.params(),h={result:o,limit:0,skip:0,total:o.length},t=i.reduce((a,u)=>u(a,p,o)||a,h);if(p.count)return{result:t.result.length};const s=f.reduce((a,u)=>u(a,p,o)||a,t);return p.first?{...J(["skip","limit","total"])(s),result:s.result[0]}:s}}function M(e){const r=he(e);return async n=>{var c;n.params().first&&n.withDirConfig();const i=n.params(),f=await r(n);return i.surround?f==null?void 0:f.surround:(f!=null&&f.dirConfig&&(f.result={_path:(c=f.dirConfig)==null?void 0:c._path,...f.result,_dir:f.dirConfig}),f==null?void 0:f.result)}}var ge=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},de={exports:{}};(function(e,r){(function(n,i,f){e.exports=f(),e.exports.default=f()})("slugify",ge,function(){var n=JSON.parse(`{"$":"dollar","%":"percent","&":"and","<":"less",">":"greater","|":"or","¢":"cent","£":"pound","¤":"currency","¥":"yen","©":"(c)","ª":"a","®":"(r)","º":"o","À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","Þ":"TH","ß":"ss","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","þ":"th","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"DJ","đ":"dj","Ē":"E","ē":"e","Ė":"E","ė":"e","Ę":"e","ę":"e","Ě":"E","ě":"e","Ğ":"G","ğ":"g","Ģ":"G","ģ":"g","Ĩ":"I","ĩ":"i","Ī":"i","ī":"i","Į":"I","į":"i","İ":"I","ı":"i","Ķ":"k","ķ":"k","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ł":"L","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","Ō":"O","ō":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ş":"S","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","Ť":"T","ť":"t","Ũ":"U","ũ":"u","Ū":"u","ū":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","Ə":"E","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Lj":"LJ","lj":"lj","Nj":"NJ","nj":"nj","Ș":"S","ș":"s","Ț":"T","ț":"t","ə":"e","˚":"o","Ά":"A","Έ":"E","Ή":"H","Ί":"I","Ό":"O","Ύ":"Y","Ώ":"W","ΐ":"i","Α":"A","Β":"B","Γ":"G","Δ":"D","Ε":"E","Ζ":"Z","Η":"H","Θ":"8","Ι":"I","Κ":"K","Λ":"L","Μ":"M","Ν":"N","Ξ":"3","Ο":"O","Π":"P","Ρ":"R","Σ":"S","Τ":"T","Υ":"Y","Φ":"F","Χ":"X","Ψ":"PS","Ω":"W","Ϊ":"I","Ϋ":"Y","ά":"a","έ":"e","ή":"h","ί":"i","ΰ":"y","α":"a","β":"b","γ":"g","δ":"d","ε":"e","ζ":"z","η":"h","θ":"8","ι":"i","κ":"k","λ":"l","μ":"m","ν":"n","ξ":"3","ο":"o","π":"p","ρ":"r","ς":"s","σ":"s","τ":"t","υ":"y","φ":"f","χ":"x","ψ":"ps","ω":"w","ϊ":"i","ϋ":"y","ό":"o","ύ":"y","ώ":"w","Ё":"Yo","Ђ":"DJ","Є":"Ye","І":"I","Ї":"Yi","Ј":"J","Љ":"LJ","Њ":"NJ","Ћ":"C","Џ":"DZ","А":"A","Б":"B","В":"V","Г":"G","Д":"D","Е":"E","Ж":"Zh","З":"Z","И":"I","Й":"J","К":"K","Л":"L","М":"M","Н":"N","О":"O","П":"P","Р":"R","С":"S","Т":"T","У":"U","Ф":"F","Х":"H","Ц":"C","Ч":"Ch","Ш":"Sh","Щ":"Sh","Ъ":"U","Ы":"Y","Ь":"","Э":"E","Ю":"Yu","Я":"Ya","а":"a","б":"b","в":"v","г":"g","д":"d","е":"e","ж":"zh","з":"z","и":"i","й":"j","к":"k","л":"l","м":"m","н":"n","о":"o","п":"p","р":"r","с":"s","т":"t","у":"u","ф":"f","х":"h","ц":"c","ч":"ch","ш":"sh","щ":"sh","ъ":"u","ы":"y","ь":"","э":"e","ю":"yu","я":"ya","ё":"yo","ђ":"dj","є":"ye","і":"i","ї":"yi","ј":"j","љ":"lj","њ":"nj","ћ":"c","ѝ":"u","џ":"dz","Ґ":"G","ґ":"g","Ғ":"GH","ғ":"gh","Қ":"KH","қ":"kh","Ң":"NG","ң":"ng","Ү":"UE","ү":"ue","Ұ":"U","ұ":"u","Һ":"H","һ":"h","Ә":"AE","ә":"ae","Ө":"OE","ө":"oe","Ա":"A","Բ":"B","Գ":"G","Դ":"D","Ե":"E","Զ":"Z","Է":"E'","Ը":"Y'","Թ":"T'","Ժ":"JH","Ի":"I","Լ":"L","Խ":"X","Ծ":"C'","Կ":"K","Հ":"H","Ձ":"D'","Ղ":"GH","Ճ":"TW","Մ":"M","Յ":"Y","Ն":"N","Շ":"SH","Չ":"CH","Պ":"P","Ջ":"J","Ռ":"R'","Ս":"S","Վ":"V","Տ":"T","Ր":"R","Ց":"C","Փ":"P'","Ք":"Q'","Օ":"O''","Ֆ":"F","և":"EV","ء":"a","آ":"aa","أ":"a","ؤ":"u","إ":"i","ئ":"e","ا":"a","ب":"b","ة":"h","ت":"t","ث":"th","ج":"j","ح":"h","خ":"kh","د":"d","ذ":"th","ر":"r","ز":"z","س":"s","ش":"sh","ص":"s","ض":"dh","ط":"t","ظ":"z","ع":"a","غ":"gh","ف":"f","ق":"q","ك":"k","ل":"l","م":"m","ن":"n","ه":"h","و":"w","ى":"a","ي":"y","ً":"an","ٌ":"on","ٍ":"en","َ":"a","ُ":"u","ِ":"e","ْ":"","٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","پ":"p","چ":"ch","ژ":"zh","ک":"k","گ":"g","ی":"y","۰":"0","۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","฿":"baht","ა":"a","ბ":"b","გ":"g","დ":"d","ე":"e","ვ":"v","ზ":"z","თ":"t","ი":"i","კ":"k","ლ":"l","მ":"m","ნ":"n","ო":"o","პ":"p","ჟ":"zh","რ":"r","ს":"s","ტ":"t","უ":"u","ფ":"f","ქ":"k","ღ":"gh","ყ":"q","შ":"sh","ჩ":"ch","ც":"ts","ძ":"dz","წ":"ts","ჭ":"ch","ხ":"kh","ჯ":"j","ჰ":"h","Ṣ":"S","ṣ":"s","Ẁ":"W","ẁ":"w","Ẃ":"W","ẃ":"w","Ẅ":"W","ẅ":"w","ẞ":"SS","Ạ":"A","ạ":"a","Ả":"A","ả":"a","Ấ":"A","ấ":"a","Ầ":"A","ầ":"a","Ẩ":"A","ẩ":"a","Ẫ":"A","ẫ":"a","Ậ":"A","ậ":"a","Ắ":"A","ắ":"a","Ằ":"A","ằ":"a","Ẳ":"A","ẳ":"a","Ẵ":"A","ẵ":"a","Ặ":"A","ặ":"a","Ẹ":"E","ẹ":"e","Ẻ":"E","ẻ":"e","Ẽ":"E","ẽ":"e","Ế":"E","ế":"e","Ề":"E","ề":"e","Ể":"E","ể":"e","Ễ":"E","ễ":"e","Ệ":"E","ệ":"e","Ỉ":"I","ỉ":"i","Ị":"I","ị":"i","Ọ":"O","ọ":"o","Ỏ":"O","ỏ":"o","Ố":"O","ố":"o","Ồ":"O","ồ":"o","Ổ":"O","ổ":"o","Ỗ":"O","ỗ":"o","Ộ":"O","ộ":"o","Ớ":"O","ớ":"o","Ờ":"O","ờ":"o","Ở":"O","ở":"o","Ỡ":"O","ỡ":"o","Ợ":"O","ợ":"o","Ụ":"U","ụ":"u","Ủ":"U","ủ":"u","Ứ":"U","ứ":"u","Ừ":"U","ừ":"u","Ử":"U","ử":"u","Ữ":"U","ữ":"u","Ự":"U","ự":"u","Ỳ":"Y","ỳ":"y","Ỵ":"Y","ỵ":"y","Ỷ":"Y","ỷ":"y","Ỹ":"Y","ỹ":"y","–":"-","‘":"'","’":"'","“":"\\"","”":"\\"","„":"\\"","†":"+","•":"*","…":"...","₠":"ecu","₢":"cruzeiro","₣":"french franc","₤":"lira","₥":"mill","₦":"naira","₧":"peseta","₨":"rupee","₩":"won","₪":"new shequel","₫":"dong","€":"euro","₭":"kip","₮":"tugrik","₯":"drachma","₰":"penny","₱":"peso","₲":"guarani","₳":"austral","₴":"hryvnia","₵":"cedi","₸":"kazakhstani tenge","₹":"indian rupee","₺":"turkish lira","₽":"russian ruble","₿":"bitcoin","℠":"sm","™":"tm","∂":"d","∆":"delta","∑":"sum","∞":"infinity","♥":"love","元":"yuan","円":"yen","﷼":"rial","ﻵ":"laa","ﻷ":"laa","ﻹ":"lai","ﻻ":"la"}`),i=JSON.parse('{"bg":{"Й":"Y","Ц":"Ts","Щ":"Sht","Ъ":"A","Ь":"Y","й":"y","ц":"ts","щ":"sht","ъ":"a","ь":"y"},"de":{"Ä":"AE","ä":"ae","Ö":"OE","ö":"oe","Ü":"UE","ü":"ue","ß":"ss","%":"prozent","&":"und","|":"oder","∑":"summe","∞":"unendlich","♥":"liebe"},"es":{"%":"por ciento","&":"y","<":"menor que",">":"mayor que","|":"o","¢":"centavos","£":"libras","¤":"moneda","₣":"francos","∑":"suma","∞":"infinito","♥":"amor"},"fr":{"%":"pourcent","&":"et","<":"plus petit",">":"plus grand","|":"ou","¢":"centime","£":"livre","¤":"devise","₣":"franc","∑":"somme","∞":"infini","♥":"amour"},"pt":{"%":"porcento","&":"e","<":"menor",">":"maior","|":"ou","¢":"centavo","∑":"soma","£":"libra","∞":"infinito","♥":"amor"},"uk":{"И":"Y","и":"y","Й":"Y","й":"y","Ц":"Ts","ц":"ts","Х":"Kh","х":"kh","Щ":"Shch","щ":"shch","Г":"H","г":"h"},"vi":{"Đ":"D","đ":"d"},"da":{"Ø":"OE","ø":"oe","Å":"AA","å":"aa","%":"procent","&":"og","|":"eller","$":"dollar","<":"mindre end",">":"større end"},"nb":{"&":"og","Å":"AA","Æ":"AE","Ø":"OE","å":"aa","æ":"ae","ø":"oe"},"it":{"&":"e"},"nl":{"&":"en"},"sv":{"&":"och","Å":"AA","Ä":"AE","Ö":"OE","å":"aa","ä":"ae","ö":"oe"}}');function f(c,o){if(typeof c!="string")throw new Error("slugify: string argument expected");o=typeof o=="string"?{replacement:o}:o||{};var p=i[o.locale]||{},h=o.replacement===void 0?"-":o.replacement,t=o.trim===void 0?!0:o.trim,s=c.normalize().split("").reduce(function(a,u){var l=p[u];return l===void 0&&(l=n[u]),l===void 0&&(l=u),l===h&&(l=" "),a+l.replace(o.remove||/[^\w\s$*_+~.()'"!\-:@]+/g,"")},"");return o.strict&&(s=s.replace(/[^A-Za-z0-9\s]/g,"")),t&&(s=s.trim()),s=s.replace(/\s+/g,h),o.lower&&(s=s.toLowerCase()),s}return f.extend=function(c){Object.assign(n,c)},f})})(de);const ye=e=>e.split(/[\s-]/g).map(H).join(" ");function we(e,r){const{navigation:n}=N().public.content;if(n===!1)return[];const i=c=>({...Ie(["title",...n.fields])(c),...Ae(c==null?void 0:c.navigation)?c.navigation:{}}),f=e.sort((c,o)=>c._path.localeCompare(o._path)).reduce((c,o)=>{const p=o._path.substring(1).split("/"),h=o._id.split(":").slice(1),t=!!h[h.length-1].match(/([1-9][0-9]*\.)?index.md/g),s=l=>({title:l.title,_path:l._path,_file:l._file,children:[],...i(l),...l._draft?{_draft:!0}:{}}),a=s(o);if(t){const l=r[a._path];if(typeof(l==null?void 0:l.navigation)<"u"&&!(l!=null&&l.navigation))return c;if(o._path!=="/"){const m=s(o);a.children.push(m)}Object.assign(a,i(l))}return p.length===1?(c.push(a),c):(p.slice(0,-1).reduce((l,m,y)=>{const v="/"+p.slice(0,y+1).join("/"),w=r[v];if(typeof(w==null?void 0:w.navigation)<"u"&&!w.navigation)return[];let I=l.find(_=>_._path===v);return I||(I={title:ye(m),_path:v,_file:o._file,children:[],...i(w)},l.push(I)),I.children},c).push(a),c)},[]);return Y(f)}const ve=new Intl.Collator(void 0,{numeric:!0,sensitivity:"base"});function Y(e){var n;e.forEach(i=>{i._file=i._file.split(".").slice(0,-1).join(".")});const r=e.sort((i,f)=>ve.compare(i._file,f._file));for(const i of r)(n=i.children)!=null&&n.length?Y(i.children):delete i.children,delete i._file;return e}function Ie(e){return r=>(r=r||{},e&&e.length?e.filter(n=>typeof r[n]<"u").reduce((n,i)=>Object.assign(n,{[i]:r[i]}),{}):r)}function Ae(e){return Object.prototype.toString.call(e)==="[object Object]"}const Ee=e=>b(e,N().public.content.api.baseURL),_e=oe(le({driver:Z()}),"@content");function Oe(e){async function r(){const n=new Set(await e.getKeys("cache:")),i=T().getPreviewToken();if(i){const c=await e.getItem(`${i}$`).then(h=>h||{});if(Array.isArray(c.ignoreSources)){const h=c.ignoreSources.map(t=>`cache:${t.trim()}:`);for(const t of n)h.some(s=>t.startsWith(s))&&n.delete(t)}const o=await e.getKeys(`${i}:`),p=await Promise.all(o.map(h=>e.getItem(h)));for(const h of p)n.delete(`cache:${h._id}`),h.__deleted||n.add(`${i}:${h._id}`)}return await Promise.all(Array.from(n).map(c=>e.getItem(c)))}return{storage:e,fetch:M(r),query:n=>k(M(r),{initialParams:n,legacy:!0})}}let R=null,S=null;async function $e(){return S?await S:R||(S=Se(),R=await S),R}async function Se(){const e=W(),{content:r}=N().public,n=Oe(_e),i=await n.storage.getItem("integrity");if(r.integrity!==+(i||0)){const{contents:f,navigation:c}=await $fetch(Ee(r.integrity?`cache.${r.integrity}.json`:"cache.json"));await Promise.all(f.map(o=>n.storage.setItem(`cache:${o._id}`,o))),await n.storage.setItem("navigation",c),await n.storage.setItem("integrity",r.integrity)}return await e.callHook("content:storage",n.storage),n}async function Ce(e){const r=await $e();if(!T().getPreviewToken()&&Object.keys(e||{}).length===0)return r.storage.getItem("navigation");const n=await r.query(e).where({_partial:!1,navigation:{$ne:!1}}).find(),f=(await r.query().where({_path:/\/_dir$/i,_partial:!0}).find()).reduce((c,o)=>{var h;((h=o.title)==null?void 0:h.toLowerCase())==="dir"&&(o.title=void 0);const p=o._path.split("/").slice(0,-1).join("/")||"/";return c[p]={...o,...o.body},c},{});return we(n,f)}export{_e as contentStorage,Oe as createDB,Ce as generateNavigation,$e as useContentDatabase}; +import{U as z,v as N,S as b,L as W}from"./entry.PS9LLiT2.js";import{g as B,b as P,c as E,o as J,d as F,f as O,h as j,i as x,k}from"./query.9Ah2Ct9x.js";import{p as H}from"./index.1dSrIji7.js";import{u as T}from"./preview.99XykmGH.js";const G="memory",Z=()=>{const e=new Map;return{name:G,options:{},hasItem(r){return e.has(r)},getItem(r){return e.get(r)??null},getItemRaw(r){return e.get(r)??null},setItem(r,n){e.set(r,n)},setItemRaw(r,n){e.set(r,n)},removeItem(r){e.delete(r)},getKeys(){return Array.from(e.keys())},clear(){e.clear()},dispose(){e.clear()}}},q=/"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,V=/"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,Q=/^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;function X(e,r){if(e==="__proto__"||e==="constructor"&&r&&typeof r=="object"&&"prototype"in r){ee(e);return}return r}function ee(e){console.warn(`[destr] Dropping "${e}" key to prevent prototype pollution.`)}function $(e,r={}){if(typeof e!="string")return e;const n=e.trim();if(e[0]==='"'&&e.at(-1)==='"'&&!e.includes("\\"))return n.slice(1,-1);if(n.length<=9){const i=n.toLowerCase();if(i==="true")return!0;if(i==="false")return!1;if(i==="undefined")return;if(i==="null")return null;if(i==="nan")return Number.NaN;if(i==="infinity")return Number.POSITIVE_INFINITY;if(i==="-infinity")return Number.NEGATIVE_INFINITY}if(!Q.test(e)){if(r.strict)throw new SyntaxError("[destr] Invalid JSON");return e}try{if(q.test(e)||V.test(e)){if(r.strict)throw new Error("[destr] Possible prototype pollution");return JSON.parse(e,X)}return JSON.parse(e)}catch(i){if(r.strict)throw i;return e}}function te(e){return!e||typeof e.then!="function"?Promise.resolve(e):e}function g(e,...r){try{return te(e(...r))}catch(n){return Promise.reject(n)}}function re(e){const r=typeof e;return e===null||r!=="object"&&r!=="function"}function ne(e){const r=Object.getPrototypeOf(e);return!r||r.isPrototypeOf(Object)}function K(e){if(re(e))return String(e);if(ne(e)||Array.isArray(e))return JSON.stringify(e);if(typeof e.toJSON=="function")return K(e.toJSON());throw new Error("[unstorage] Cannot stringify value!")}function U(){if(typeof Buffer===void 0)throw new TypeError("[unstorage] Buffer is not supported!")}const C="base64:";function ie(e){if(typeof e=="string")return e;U();const r=Buffer.from(e).toString("base64");return C+r}function se(e){return typeof e!="string"||!e.startsWith(C)?e:(U(),Buffer.from(e.slice(C.length),"base64"))}const ae=["hasItem","getItem","getItemRaw","setItem","setItemRaw","removeItem","getMeta","setMeta","removeMeta","getKeys","clear","mount","unmount"];function oe(e,r){if(r=A(r),!r)return e;const n={...e};for(const i of ae)n[i]=(f="",...c)=>e[i](r+f,...c);return n.getKeys=(i="",...f)=>e.getKeys(r+i,...f).then(c=>c.map(o=>o.slice(r.length))),n}function d(e){return e?e.split("?")[0].replace(/[/\\]/g,":").replace(/:+/g,":").replace(/^:|:$/g,""):""}function ue(...e){return d(e.join(":"))}function A(e){return e=d(e),e?e+":":""}const ce="memory",fe=()=>{const e=new Map;return{name:ce,options:{},hasItem(r){return e.has(r)},getItem(r){return e.get(r)??null},getItemRaw(r){return e.get(r)??null},setItem(r,n){e.set(r,n)},setItemRaw(r,n){e.set(r,n)},removeItem(r){e.delete(r)},getKeys(){return Array.from(e.keys())},clear(){e.clear()},dispose(){e.clear()}}};function le(e={}){const r={mounts:{"":e.driver||fe()},mountpoints:[""],watching:!1,watchListeners:[],unwatch:{}},n=t=>{for(const s of r.mountpoints)if(t.startsWith(s))return{base:s,relativeKey:t.slice(s.length),driver:r.mounts[s]};return{base:"",relativeKey:t,driver:r.mounts[""]}},i=(t,s)=>r.mountpoints.filter(a=>a.startsWith(t)||s&&t.startsWith(a)).map(a=>({relativeBase:t.length>a.length?t.slice(a.length):void 0,mountpoint:a,driver:r.mounts[a]})),f=(t,s)=>{if(r.watching){s=d(s);for(const a of r.watchListeners)a(t,s)}},c=async()=>{if(!r.watching){r.watching=!0;for(const t in r.mounts)r.unwatch[t]=await D(r.mounts[t],f,t)}},o=async()=>{if(r.watching){for(const t in r.unwatch)await r.unwatch[t]();r.unwatch={},r.watching=!1}},p=(t,s,a)=>{const u=new Map,l=m=>{let y=u.get(m.base);return y||(y={driver:m.driver,base:m.base,items:[]},u.set(m.base,y)),y};for(const m of t){const y=typeof m=="string",v=d(y?m:m.key),w=y?void 0:m.value,I=y||!m.options?s:{...s,...m.options},_=n(v);l(_).items.push({key:v,value:w,relativeKey:_.relativeKey,options:I})}return Promise.all([...u.values()].map(m=>a(m))).then(m=>m.flat())},h={hasItem(t,s={}){t=d(t);const{relativeKey:a,driver:u}=n(t);return g(u.hasItem,a,s)},getItem(t,s={}){t=d(t);const{relativeKey:a,driver:u}=n(t);return g(u.getItem,a,s).then(l=>$(l))},getItems(t,s){return p(t,s,a=>a.driver.getItems?g(a.driver.getItems,a.items.map(u=>({key:u.relativeKey,options:u.options})),s).then(u=>u.map(l=>({key:ue(a.base,l.key),value:$(l.value)}))):Promise.all(a.items.map(u=>g(a.driver.getItem,u.relativeKey,u.options).then(l=>({key:u.key,value:$(l)})))))},getItemRaw(t,s={}){t=d(t);const{relativeKey:a,driver:u}=n(t);return u.getItemRaw?g(u.getItemRaw,a,s):g(u.getItem,a,s).then(l=>se(l))},async setItem(t,s,a={}){if(s===void 0)return h.removeItem(t);t=d(t);const{relativeKey:u,driver:l}=n(t);l.setItem&&(await g(l.setItem,u,K(s),a),l.watch||f("update",t))},async setItems(t,s){await p(t,s,async a=>{a.driver.setItems&&await g(a.driver.setItems,a.items.map(u=>({key:u.relativeKey,value:K(u.value),options:u.options})),s),a.driver.setItem&&await Promise.all(a.items.map(u=>g(a.driver.setItem,u.relativeKey,K(u.value),u.options)))})},async setItemRaw(t,s,a={}){if(s===void 0)return h.removeItem(t,a);t=d(t);const{relativeKey:u,driver:l}=n(t);if(l.setItemRaw)await g(l.setItemRaw,u,s,a);else if(l.setItem)await g(l.setItem,u,ie(s),a);else return;l.watch||f("update",t)},async removeItem(t,s={}){typeof s=="boolean"&&(s={removeMeta:s}),t=d(t);const{relativeKey:a,driver:u}=n(t);u.removeItem&&(await g(u.removeItem,a,s),(s.removeMeta||s.removeMata)&&await g(u.removeItem,a+"$",s),u.watch||f("remove",t))},async getMeta(t,s={}){typeof s=="boolean"&&(s={nativeOnly:s}),t=d(t);const{relativeKey:a,driver:u}=n(t),l=Object.create(null);if(u.getMeta&&Object.assign(l,await g(u.getMeta,a,s)),!s.nativeOnly){const m=await g(u.getItem,a+"$",s).then(y=>$(y));m&&typeof m=="object"&&(typeof m.atime=="string"&&(m.atime=new Date(m.atime)),typeof m.mtime=="string"&&(m.mtime=new Date(m.mtime)),Object.assign(l,m))}return l},setMeta(t,s,a={}){return this.setItem(t+"$",s,a)},removeMeta(t,s={}){return this.removeItem(t+"$",s)},async getKeys(t,s={}){t=A(t);const a=i(t,!0);let u=[];const l=[];for(const m of a){const v=(await g(m.driver.getKeys,m.relativeBase,s)).map(w=>m.mountpoint+d(w)).filter(w=>!u.some(I=>w.startsWith(I)));l.push(...v),u=[m.mountpoint,...u.filter(w=>!w.startsWith(m.mountpoint))]}return t?l.filter(m=>m.startsWith(t)&&!m.endsWith("$")):l.filter(m=>!m.endsWith("$"))},async clear(t,s={}){t=A(t),await Promise.all(i(t,!1).map(async a=>{if(a.driver.clear)return g(a.driver.clear,a.relativeBase,s);if(a.driver.removeItem){const u=await a.driver.getKeys(a.relativeBase||"",s);return Promise.all(u.map(l=>a.driver.removeItem(l,s)))}}))},async dispose(){await Promise.all(Object.values(r.mounts).map(t=>L(t)))},async watch(t){return await c(),r.watchListeners.push(t),async()=>{r.watchListeners=r.watchListeners.filter(s=>s!==t),r.watchListeners.length===0&&await o()}},async unwatch(){r.watchListeners=[],await o()},mount(t,s){if(t=A(t),t&&r.mounts[t])throw new Error(`already mounted at ${t}`);return t&&(r.mountpoints.push(t),r.mountpoints.sort((a,u)=>u.length-a.length)),r.mounts[t]=s,r.watching&&Promise.resolve(D(s,f,t)).then(a=>{r.unwatch[t]=a}).catch(console.error),h},async unmount(t,s=!0){t=A(t),!(!t||!r.mounts[t])&&(r.watching&&t in r.unwatch&&(r.unwatch[t](),delete r.unwatch[t]),s&&await L(r.mounts[t]),r.mountpoints=r.mountpoints.filter(a=>a!==t),delete r.mounts[t])},getMount(t=""){t=d(t)+":";const s=n(t);return{driver:s.driver,base:s.base}},getMounts(t="",s={}){return t=d(t),i(t,s.parents).map(u=>({driver:u.driver,base:u.mountpoint}))}};return h}function D(e,r,n){return e.watch?e.watch((i,f)=>r(i,n+f)):()=>{}}async function L(e){typeof e.dispose=="function"&&await g(e.dispose)}function me(e={}){const r=pe(n,e.operators);function n(i,f){return typeof f!="object"||f instanceof RegExp?r.$eq(i,f):Object.keys(f||{}).every(c=>{const o=f[c];if(c.startsWith("$")&&r[c]){const p=r[c];return typeof p=="function"?p(i,o):!1}return n(B(i,c),o)})}return n}function pe(e,r={}){return{$match:(n,i)=>e(n,i),$eq:(n,i)=>i instanceof RegExp?i.test(n):n===i,$ne:(n,i)=>i instanceof RegExp?!i.test(n):n!==i,$not:(n,i)=>!e(n,i),$and:(n,i)=>(P(i,"$and requires an array as condition"),i.every(f=>e(n,f))),$or:(n,i)=>(P(i,"$or requires an array as condition"),i.some(f=>e(n,f))),$in:(n,i)=>E(i).some(f=>Array.isArray(n)?e(n,{$contains:f}):e(n,f)),$contains:(n,i)=>(n=Array.isArray(n)?n:String(n),E(i).every(f=>n.includes(f))),$icontains:(n,i)=>{if(typeof i!="string")throw new TypeError("$icontains requires a string, use $contains instead");return n=String(n).toLocaleLowerCase(),E(i).every(f=>n.includes(f.toLocaleLowerCase()))},$containsAny:(n,i)=>(P(i,"$containsAny requires an array as condition"),n=Array.isArray(n)?n:String(n),i.some(f=>n.includes(f))),$exists:(n,i)=>i?typeof n<"u":typeof n>"u",$type:(n,i)=>typeof n===String(i),$regex:(n,i)=>{if(!(i instanceof RegExp)){const f=String(i).match(/\/(.*)\/([dgimsuy]*)$/);i=f?new RegExp(f[1],f[2]||""):new RegExp(i)}return i.test(String(n||""))},$lt:(n,i)=>nn<=i,$gt:(n,i)=>n>i,$gte:(n,i)=>n>=i,...r||{}}}function he(e){const r=me(),n=(c,{query:o,before:p,after:h})=>{const t=typeof o=="string"?{_path:o}:o,s=c.findIndex(u=>r(u,t));p=p??1,h=h??1;const a=new Array(p+h).fill(null,0);return s===-1?a:a.map((u,l)=>c[s-p+l+ +(l>=p)]||null)},i=[(c,o)=>{const p=c.result.filter(h=>E(o.where).every(t=>r(h,t)));return{...c,result:p,total:p.length}},(c,o)=>E(o.sort).forEach(p=>F(c.result,p)),function(o,p,h){var t;if(p.surround){let s=n(((t=o.result)==null?void 0:t.length)===1?h:o.result,p.surround);s=O(j(p.without))(s),s=O(x(p.only))(s),o.surround=s}return o}],f=[(c,o)=>{if(o.skip)return{...c,result:c.result.slice(o.skip),skip:o.skip}},(c,o)=>{if(o.limit)return{...c,result:c.result.slice(0,o.limit),limit:o.limit}},function(o,p,h){var t,s,a;if(p.dirConfig){const u=((t=o.result[0])==null?void 0:t._path)||((a=(s=p.where)==null?void 0:s.find(l=>l._path))==null?void 0:a._path);if(typeof u=="string"){const l=h.find(m=>m._path===z(u,"_dir"));l&&(o.dirConfig={_path:l._path,...j(["_"])(l)})}}return o},(c,o)=>({...c,result:O(j(o.without))(c.result)}),(c,o)=>({...c,result:O(x(o.only))(c.result)})];return async c=>{const o=await e(),p=c.params(),h={result:o,limit:0,skip:0,total:o.length},t=i.reduce((a,u)=>u(a,p,o)||a,h);if(p.count)return{result:t.result.length};const s=f.reduce((a,u)=>u(a,p,o)||a,t);return p.first?{...J(["skip","limit","total"])(s),result:s.result[0]}:s}}function M(e){const r=he(e);return async n=>{var c;n.params().first&&n.withDirConfig();const i=n.params(),f=await r(n);return i.surround?f==null?void 0:f.surround:(f!=null&&f.dirConfig&&(f.result={_path:(c=f.dirConfig)==null?void 0:c._path,...f.result,_dir:f.dirConfig}),f==null?void 0:f.result)}}var ge=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},de={exports:{}};(function(e,r){(function(n,i,f){e.exports=f(),e.exports.default=f()})("slugify",ge,function(){var n=JSON.parse(`{"$":"dollar","%":"percent","&":"and","<":"less",">":"greater","|":"or","¢":"cent","£":"pound","¤":"currency","¥":"yen","©":"(c)","ª":"a","®":"(r)","º":"o","À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","Þ":"TH","ß":"ss","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","þ":"th","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"DJ","đ":"dj","Ē":"E","ē":"e","Ė":"E","ė":"e","Ę":"e","ę":"e","Ě":"E","ě":"e","Ğ":"G","ğ":"g","Ģ":"G","ģ":"g","Ĩ":"I","ĩ":"i","Ī":"i","ī":"i","Į":"I","į":"i","İ":"I","ı":"i","Ķ":"k","ķ":"k","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ł":"L","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","Ō":"O","ō":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ş":"S","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","Ť":"T","ť":"t","Ũ":"U","ũ":"u","Ū":"u","ū":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","Ə":"E","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Lj":"LJ","lj":"lj","Nj":"NJ","nj":"nj","Ș":"S","ș":"s","Ț":"T","ț":"t","ə":"e","˚":"o","Ά":"A","Έ":"E","Ή":"H","Ί":"I","Ό":"O","Ύ":"Y","Ώ":"W","ΐ":"i","Α":"A","Β":"B","Γ":"G","Δ":"D","Ε":"E","Ζ":"Z","Η":"H","Θ":"8","Ι":"I","Κ":"K","Λ":"L","Μ":"M","Ν":"N","Ξ":"3","Ο":"O","Π":"P","Ρ":"R","Σ":"S","Τ":"T","Υ":"Y","Φ":"F","Χ":"X","Ψ":"PS","Ω":"W","Ϊ":"I","Ϋ":"Y","ά":"a","έ":"e","ή":"h","ί":"i","ΰ":"y","α":"a","β":"b","γ":"g","δ":"d","ε":"e","ζ":"z","η":"h","θ":"8","ι":"i","κ":"k","λ":"l","μ":"m","ν":"n","ξ":"3","ο":"o","π":"p","ρ":"r","ς":"s","σ":"s","τ":"t","υ":"y","φ":"f","χ":"x","ψ":"ps","ω":"w","ϊ":"i","ϋ":"y","ό":"o","ύ":"y","ώ":"w","Ё":"Yo","Ђ":"DJ","Є":"Ye","І":"I","Ї":"Yi","Ј":"J","Љ":"LJ","Њ":"NJ","Ћ":"C","Џ":"DZ","А":"A","Б":"B","В":"V","Г":"G","Д":"D","Е":"E","Ж":"Zh","З":"Z","И":"I","Й":"J","К":"K","Л":"L","М":"M","Н":"N","О":"O","П":"P","Р":"R","С":"S","Т":"T","У":"U","Ф":"F","Х":"H","Ц":"C","Ч":"Ch","Ш":"Sh","Щ":"Sh","Ъ":"U","Ы":"Y","Ь":"","Э":"E","Ю":"Yu","Я":"Ya","а":"a","б":"b","в":"v","г":"g","д":"d","е":"e","ж":"zh","з":"z","и":"i","й":"j","к":"k","л":"l","м":"m","н":"n","о":"o","п":"p","р":"r","с":"s","т":"t","у":"u","ф":"f","х":"h","ц":"c","ч":"ch","ш":"sh","щ":"sh","ъ":"u","ы":"y","ь":"","э":"e","ю":"yu","я":"ya","ё":"yo","ђ":"dj","є":"ye","і":"i","ї":"yi","ј":"j","љ":"lj","њ":"nj","ћ":"c","ѝ":"u","џ":"dz","Ґ":"G","ґ":"g","Ғ":"GH","ғ":"gh","Қ":"KH","қ":"kh","Ң":"NG","ң":"ng","Ү":"UE","ү":"ue","Ұ":"U","ұ":"u","Һ":"H","һ":"h","Ә":"AE","ә":"ae","Ө":"OE","ө":"oe","Ա":"A","Բ":"B","Գ":"G","Դ":"D","Ե":"E","Զ":"Z","Է":"E'","Ը":"Y'","Թ":"T'","Ժ":"JH","Ի":"I","Լ":"L","Խ":"X","Ծ":"C'","Կ":"K","Հ":"H","Ձ":"D'","Ղ":"GH","Ճ":"TW","Մ":"M","Յ":"Y","Ն":"N","Շ":"SH","Չ":"CH","Պ":"P","Ջ":"J","Ռ":"R'","Ս":"S","Վ":"V","Տ":"T","Ր":"R","Ց":"C","Փ":"P'","Ք":"Q'","Օ":"O''","Ֆ":"F","և":"EV","ء":"a","آ":"aa","أ":"a","ؤ":"u","إ":"i","ئ":"e","ا":"a","ب":"b","ة":"h","ت":"t","ث":"th","ج":"j","ح":"h","خ":"kh","د":"d","ذ":"th","ر":"r","ز":"z","س":"s","ش":"sh","ص":"s","ض":"dh","ط":"t","ظ":"z","ع":"a","غ":"gh","ف":"f","ق":"q","ك":"k","ل":"l","م":"m","ن":"n","ه":"h","و":"w","ى":"a","ي":"y","ً":"an","ٌ":"on","ٍ":"en","َ":"a","ُ":"u","ِ":"e","ْ":"","٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","پ":"p","چ":"ch","ژ":"zh","ک":"k","گ":"g","ی":"y","۰":"0","۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","฿":"baht","ა":"a","ბ":"b","გ":"g","დ":"d","ე":"e","ვ":"v","ზ":"z","თ":"t","ი":"i","კ":"k","ლ":"l","მ":"m","ნ":"n","ო":"o","პ":"p","ჟ":"zh","რ":"r","ს":"s","ტ":"t","უ":"u","ფ":"f","ქ":"k","ღ":"gh","ყ":"q","შ":"sh","ჩ":"ch","ც":"ts","ძ":"dz","წ":"ts","ჭ":"ch","ხ":"kh","ჯ":"j","ჰ":"h","Ṣ":"S","ṣ":"s","Ẁ":"W","ẁ":"w","Ẃ":"W","ẃ":"w","Ẅ":"W","ẅ":"w","ẞ":"SS","Ạ":"A","ạ":"a","Ả":"A","ả":"a","Ấ":"A","ấ":"a","Ầ":"A","ầ":"a","Ẩ":"A","ẩ":"a","Ẫ":"A","ẫ":"a","Ậ":"A","ậ":"a","Ắ":"A","ắ":"a","Ằ":"A","ằ":"a","Ẳ":"A","ẳ":"a","Ẵ":"A","ẵ":"a","Ặ":"A","ặ":"a","Ẹ":"E","ẹ":"e","Ẻ":"E","ẻ":"e","Ẽ":"E","ẽ":"e","Ế":"E","ế":"e","Ề":"E","ề":"e","Ể":"E","ể":"e","Ễ":"E","ễ":"e","Ệ":"E","ệ":"e","Ỉ":"I","ỉ":"i","Ị":"I","ị":"i","Ọ":"O","ọ":"o","Ỏ":"O","ỏ":"o","Ố":"O","ố":"o","Ồ":"O","ồ":"o","Ổ":"O","ổ":"o","Ỗ":"O","ỗ":"o","Ộ":"O","ộ":"o","Ớ":"O","ớ":"o","Ờ":"O","ờ":"o","Ở":"O","ở":"o","Ỡ":"O","ỡ":"o","Ợ":"O","ợ":"o","Ụ":"U","ụ":"u","Ủ":"U","ủ":"u","Ứ":"U","ứ":"u","Ừ":"U","ừ":"u","Ử":"U","ử":"u","Ữ":"U","ữ":"u","Ự":"U","ự":"u","Ỳ":"Y","ỳ":"y","Ỵ":"Y","ỵ":"y","Ỷ":"Y","ỷ":"y","Ỹ":"Y","ỹ":"y","–":"-","‘":"'","’":"'","“":"\\"","”":"\\"","„":"\\"","†":"+","•":"*","…":"...","₠":"ecu","₢":"cruzeiro","₣":"french franc","₤":"lira","₥":"mill","₦":"naira","₧":"peseta","₨":"rupee","₩":"won","₪":"new shequel","₫":"dong","€":"euro","₭":"kip","₮":"tugrik","₯":"drachma","₰":"penny","₱":"peso","₲":"guarani","₳":"austral","₴":"hryvnia","₵":"cedi","₸":"kazakhstani tenge","₹":"indian rupee","₺":"turkish lira","₽":"russian ruble","₿":"bitcoin","℠":"sm","™":"tm","∂":"d","∆":"delta","∑":"sum","∞":"infinity","♥":"love","元":"yuan","円":"yen","﷼":"rial","ﻵ":"laa","ﻷ":"laa","ﻹ":"lai","ﻻ":"la"}`),i=JSON.parse('{"bg":{"Й":"Y","Ц":"Ts","Щ":"Sht","Ъ":"A","Ь":"Y","й":"y","ц":"ts","щ":"sht","ъ":"a","ь":"y"},"de":{"Ä":"AE","ä":"ae","Ö":"OE","ö":"oe","Ü":"UE","ü":"ue","ß":"ss","%":"prozent","&":"und","|":"oder","∑":"summe","∞":"unendlich","♥":"liebe"},"es":{"%":"por ciento","&":"y","<":"menor que",">":"mayor que","|":"o","¢":"centavos","£":"libras","¤":"moneda","₣":"francos","∑":"suma","∞":"infinito","♥":"amor"},"fr":{"%":"pourcent","&":"et","<":"plus petit",">":"plus grand","|":"ou","¢":"centime","£":"livre","¤":"devise","₣":"franc","∑":"somme","∞":"infini","♥":"amour"},"pt":{"%":"porcento","&":"e","<":"menor",">":"maior","|":"ou","¢":"centavo","∑":"soma","£":"libra","∞":"infinito","♥":"amor"},"uk":{"И":"Y","и":"y","Й":"Y","й":"y","Ц":"Ts","ц":"ts","Х":"Kh","х":"kh","Щ":"Shch","щ":"shch","Г":"H","г":"h"},"vi":{"Đ":"D","đ":"d"},"da":{"Ø":"OE","ø":"oe","Å":"AA","å":"aa","%":"procent","&":"og","|":"eller","$":"dollar","<":"mindre end",">":"større end"},"nb":{"&":"og","Å":"AA","Æ":"AE","Ø":"OE","å":"aa","æ":"ae","ø":"oe"},"it":{"&":"e"},"nl":{"&":"en"},"sv":{"&":"och","Å":"AA","Ä":"AE","Ö":"OE","å":"aa","ä":"ae","ö":"oe"}}');function f(c,o){if(typeof c!="string")throw new Error("slugify: string argument expected");o=typeof o=="string"?{replacement:o}:o||{};var p=i[o.locale]||{},h=o.replacement===void 0?"-":o.replacement,t=o.trim===void 0?!0:o.trim,s=c.normalize().split("").reduce(function(a,u){var l=p[u];return l===void 0&&(l=n[u]),l===void 0&&(l=u),l===h&&(l=" "),a+l.replace(o.remove||/[^\w\s$*_+~.()'"!\-:@]+/g,"")},"");return o.strict&&(s=s.replace(/[^A-Za-z0-9\s]/g,"")),t&&(s=s.trim()),s=s.replace(/\s+/g,h),o.lower&&(s=s.toLowerCase()),s}return f.extend=function(c){Object.assign(n,c)},f})})(de);const ye=e=>e.split(/[\s-]/g).map(H).join(" ");function we(e,r){const{navigation:n}=N().public.content;if(n===!1)return[];const i=c=>({...Ie(["title",...n.fields])(c),...Ae(c==null?void 0:c.navigation)?c.navigation:{}}),f=e.sort((c,o)=>c._path.localeCompare(o._path)).reduce((c,o)=>{const p=o._path.substring(1).split("/"),h=o._id.split(":").slice(1),t=!!h[h.length-1].match(/([1-9][0-9]*\.)?index.md/g),s=l=>({title:l.title,_path:l._path,_file:l._file,children:[],...i(l),...l._draft?{_draft:!0}:{}}),a=s(o);if(t){const l=r[a._path];if(typeof(l==null?void 0:l.navigation)<"u"&&!(l!=null&&l.navigation))return c;if(o._path!=="/"){const m=s(o);a.children.push(m)}Object.assign(a,i(l))}return p.length===1?(c.push(a),c):(p.slice(0,-1).reduce((l,m,y)=>{const v="/"+p.slice(0,y+1).join("/"),w=r[v];if(typeof(w==null?void 0:w.navigation)<"u"&&!w.navigation)return[];let I=l.find(_=>_._path===v);return I||(I={title:ye(m),_path:v,_file:o._file,children:[],...i(w)},l.push(I)),I.children},c).push(a),c)},[]);return Y(f)}const ve=new Intl.Collator(void 0,{numeric:!0,sensitivity:"base"});function Y(e){var n;e.forEach(i=>{i._file=i._file.split(".").slice(0,-1).join(".")});const r=e.sort((i,f)=>ve.compare(i._file,f._file));for(const i of r)(n=i.children)!=null&&n.length?Y(i.children):delete i.children,delete i._file;return e}function Ie(e){return r=>(r=r||{},e&&e.length?e.filter(n=>typeof r[n]<"u").reduce((n,i)=>Object.assign(n,{[i]:r[i]}),{}):r)}function Ae(e){return Object.prototype.toString.call(e)==="[object Object]"}const Ee=e=>b(e,N().public.content.api.baseURL),_e=oe(le({driver:Z()}),"@content");function Oe(e){async function r(){const n=new Set(await e.getKeys("cache:")),i=T().getPreviewToken();if(i){const c=await e.getItem(`${i}$`).then(h=>h||{});if(Array.isArray(c.ignoreSources)){const h=c.ignoreSources.map(t=>`cache:${t.trim()}:`);for(const t of n)h.some(s=>t.startsWith(s))&&n.delete(t)}const o=await e.getKeys(`${i}:`),p=await Promise.all(o.map(h=>e.getItem(h)));for(const h of p)n.delete(`cache:${h._id}`),h.__deleted||n.add(`${i}:${h._id}`)}return await Promise.all(Array.from(n).map(c=>e.getItem(c)))}return{storage:e,fetch:M(r),query:n=>k(M(r),{initialParams:n,legacy:!0})}}let R=null,S=null;async function $e(){return S?await S:R||(S=Se(),R=await S),R}async function Se(){const e=W(),{content:r}=N().public,n=Oe(_e),i=await n.storage.getItem("integrity");if(r.integrity!==+(i||0)){const{contents:f,navigation:c}=await $fetch(Ee(r.integrity?`cache.${r.integrity}.json`:"cache.json"));await Promise.all(f.map(o=>n.storage.setItem(`cache:${o._id}`,o))),await n.storage.setItem("navigation",c),await n.storage.setItem("integrity",r.integrity)}return await e.callHook("content:storage",n.storage),n}async function Ce(e){const r=await $e();if(!T().getPreviewToken()&&Object.keys(e||{}).length===0)return r.storage.getItem("navigation");const n=await r.query(e).where({_partial:!1,navigation:{$ne:!1}}).find(),f=(await r.query().where({_path:/\/_dir$/i,_partial:!0}).find()).reduce((c,o)=>{var h;((h=o.title)==null?void 0:h.toLowerCase())==="dir"&&(o.title=void 0);const p=o._path.split("/").slice(0,-1).join("/")||"/";return c[p]={...o,...o.body},c},{});return we(n,f)}export{_e as contentStorage,Oe as createDB,Ce as generateNavigation,$e as useContentDatabase}; diff --git a/_nuxt/entry.kyqmbcaI.js b/_nuxt/entry.PS9LLiT2.js similarity index 97% rename from _nuxt/entry.kyqmbcaI.js rename to _nuxt/entry.PS9LLiT2.js index 2709381..a34d4bb 100644 --- a/_nuxt/entry.kyqmbcaI.js +++ b/_nuxt/entry.PS9LLiT2.js @@ -1,13 +1,13 @@ -function Ns(e,t){const n=Object.create(null),r=e.split(",");for(let s=0;s!!n[s.toLowerCase()]:s=>!!n[s]}const fe={},Bt=[],Ge=()=>{},Ba=()=>!1,Hn=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Ms=e=>e.startsWith("onUpdate:"),_e=Object.assign,js=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Ua=Object.prototype.hasOwnProperty,ne=(e,t)=>Ua.call(e,t),z=Array.isArray,Ut=e=>$n(e)==="[object Map]",Ui=e=>$n(e)==="[object Set]",Ka=e=>$n(e)==="[object RegExp]",X=e=>typeof e=="function",pe=e=>typeof e=="string",mr=e=>typeof e=="symbol",ue=e=>e!==null&&typeof e=="object",Ki=e=>(ue(e)||X(e))&&X(e.then)&&X(e.catch),Vi=Object.prototype.toString,$n=e=>Vi.call(e),Va=e=>$n(e).slice(8,-1),Wi=e=>$n(e)==="[object Object]",Fs=e=>pe(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,gn=Ns(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),yr=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},Wa=/-(\w)/g,et=yr(e=>e.replace(Wa,(t,n)=>n?n.toUpperCase():"")),qa=/\B([A-Z])/g,nn=yr(e=>e.replace(qa,"-$1").toLowerCase()),_r=yr(e=>e.charAt(0).toUpperCase()+e.slice(1)),Mr=yr(e=>e?`on${_r(e)}`:""),St=(e,t)=>!Object.is(e,t),mn=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},za=e=>{const t=parseFloat(e);return isNaN(t)?e:t},qi=e=>{const t=pe(e)?Number(e):NaN;return isNaN(t)?e:t};let bo;const ns=()=>bo||(bo=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function vr(e){if(z(e)){const t={};for(let n=0;n{if(n){const r=n.split(Ja);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function br(e){let t="";if(pe(e))t=e;else if(z(e))for(let n=0;npe(e)?e:e==null?"":z(e)||ue(e)&&(e.toString===Vi||!X(e.toString))?JSON.stringify(e,Qi,2):String(e),Qi=(e,t)=>t&&t.__v_isRef?Qi(e,t.value):Ut(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[r,s])=>(n[`${r} =>`]=s,n),{})}:Ui(t)?{[`Set(${t.size})`]:[...t.values()]}:ue(t)&&!z(t)&&!Wi(t)?String(t):t;let Ie;class Ji{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Ie,!t&&Ie&&(this.index=(Ie.scopes||(Ie.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=Ie;try{return Ie=this,t()}finally{Ie=n}}}on(){Ie=this}off(){Ie=this.parent}stop(t){if(this._active){let n,r;for(n=0,r=this.effects.length;n{const t=new Set(e);return t.w=0,t.n=0,t},Xi=e=>(e.w&bt)>0,Yi=e=>(e.n&bt)>0,sc=({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let n=0;for(let r=0;r{(c==="length"||!mr(c)&&c>=a)&&l.push(u)})}else switch(n!==void 0&&l.push(i.get(n)),t){case"add":z(e)?Fs(n)&&l.push(i.get("length")):(l.push(i.get(xt)),Ut(e)&&l.push(i.get(ss)));break;case"delete":z(e)||(l.push(i.get(xt)),Ut(e)&&l.push(i.get(ss)));break;case"set":Ut(e)&&l.push(i.get(xt));break}if(l.length===1)l[0]&&os(l[0]);else{const a=[];for(const u of l)u&&a.push(...u);os(Ds(a))}}function os(e,t){const n=z(e)?e:[...e];for(const r of n)r.computed&&wo(r);for(const r of n)r.computed||wo(r)}function wo(e,t){(e!==Ue||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}function ic(e,t){var n;return(n=sr.get(e))==null?void 0:n.get(t)}const lc=Ns("__proto__,__v_isRef,__isVue"),el=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(mr)),Ro=ac();function ac(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const r=re(this);for(let o=0,i=this.length;o{e[t]=function(...n){rn();const r=re(this)[t].apply(this,n);return sn(),r}}),e}function cc(e){const t=re(this);return Oe(t,"has",e),t.hasOwnProperty(e)}class tl{constructor(t=!1,n=!1){this._isReadonly=t,this._shallow=n}get(t,n,r){const s=this._isReadonly,o=this._shallow;if(n==="__v_isReactive")return!s;if(n==="__v_isReadonly")return s;if(n==="__v_isShallow")return o;if(n==="__v_raw"&&r===(s?o?wc:ol:o?sl:rl).get(t))return t;const i=z(t);if(!s){if(i&&ne(Ro,n))return Reflect.get(Ro,n,r);if(n==="hasOwnProperty")return cc}const l=Reflect.get(t,n,r);return(mr(n)?el.has(n):lc(n))||(s||Oe(t,"get",n),o)?l:ve(l)?i&&Fs(n)?l:l.value:ue(l)?s?il(l):ot(l):l}}class nl extends tl{constructor(t=!1){super(!1,t)}set(t,n,r,s){let o=t[n];if(Lt(o)&&ve(o)&&!ve(r))return!1;if(!this._shallow&&(!or(r)&&!Lt(r)&&(o=re(o),r=re(r)),!z(t)&&ve(o)&&!ve(r)))return o.value=r,!0;const i=z(t)&&Fs(n)?Number(n)e,Er=e=>Reflect.getPrototypeOf(e);function Bn(e,t,n=!1,r=!1){e=e.__v_raw;const s=re(e),o=re(t);n||(St(t,o)&&Oe(s,"get",t),Oe(s,"get",o));const{has:i}=Er(s),l=r?Us:n?Ws:Cn;if(i.call(s,t))return l(e.get(t));if(i.call(s,o))return l(e.get(o));e!==s&&e.get(t)}function Un(e,t=!1){const n=this.__v_raw,r=re(n),s=re(e);return t||(St(e,s)&&Oe(r,"has",e),Oe(r,"has",s)),e===s?n.has(e):n.has(e)||n.has(s)}function Kn(e,t=!1){return e=e.__v_raw,!t&&Oe(re(e),"iterate",xt),Reflect.get(e,"size",e)}function Co(e){e=re(e);const t=re(this);return Er(t).has.call(t,e)||(t.add(e),st(t,"add",e,e)),this}function Po(e,t){t=re(t);const n=re(this),{has:r,get:s}=Er(n);let o=r.call(n,e);o||(e=re(e),o=r.call(n,e));const i=s.call(n,e);return n.set(e,t),o?St(t,i)&&st(n,"set",e,t):st(n,"add",e,t),this}function To(e){const t=re(this),{has:n,get:r}=Er(t);let s=n.call(t,e);s||(e=re(e),s=n.call(t,e)),r&&r.call(t,e);const o=t.delete(e);return s&&st(t,"delete",e,void 0),o}function Ao(){const e=re(this),t=e.size!==0,n=e.clear();return t&&st(e,"clear",void 0,void 0),n}function Vn(e,t){return function(r,s){const o=this,i=o.__v_raw,l=re(i),a=t?Us:e?Ws:Cn;return!e&&Oe(l,"iterate",xt),i.forEach((u,c)=>r.call(s,a(u),a(c),o))}}function Wn(e,t,n){return function(...r){const s=this.__v_raw,o=re(s),i=Ut(o),l=e==="entries"||e===Symbol.iterator&&i,a=e==="keys"&&i,u=s[e](...r),c=n?Us:t?Ws:Cn;return!t&&Oe(o,"iterate",a?ss:xt),{next(){const{value:f,done:d}=u.next();return d?{value:f,done:d}:{value:l?[c(f[0]),c(f[1])]:c(f),done:d}},[Symbol.iterator](){return this}}}}function ct(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function pc(){const e={get(o){return Bn(this,o)},get size(){return Kn(this)},has:Un,add:Co,set:Po,delete:To,clear:Ao,forEach:Vn(!1,!1)},t={get(o){return Bn(this,o,!1,!0)},get size(){return Kn(this)},has:Un,add:Co,set:Po,delete:To,clear:Ao,forEach:Vn(!1,!0)},n={get(o){return Bn(this,o,!0)},get size(){return Kn(this,!0)},has(o){return Un.call(this,o,!0)},add:ct("add"),set:ct("set"),delete:ct("delete"),clear:ct("clear"),forEach:Vn(!0,!1)},r={get(o){return Bn(this,o,!0,!0)},get size(){return Kn(this,!0)},has(o){return Un.call(this,o,!0)},add:ct("add"),set:ct("set"),delete:ct("delete"),clear:ct("clear"),forEach:Vn(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(o=>{e[o]=Wn(o,!1,!1),n[o]=Wn(o,!0,!1),t[o]=Wn(o,!1,!0),r[o]=Wn(o,!0,!0)}),[e,n,t,r]}const[gc,mc,yc,_c]=pc();function Ks(e,t){const n=t?e?_c:yc:e?mc:gc;return(r,s,o)=>s==="__v_isReactive"?!e:s==="__v_isReadonly"?e:s==="__v_raw"?r:Reflect.get(ne(n,s)&&s in r?n:r,s,o)}const vc={get:Ks(!1,!1)},bc={get:Ks(!1,!0)},Ec={get:Ks(!0,!1)},rl=new WeakMap,sl=new WeakMap,ol=new WeakMap,wc=new WeakMap;function Rc(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Cc(e){return e.__v_skip||!Object.isExtensible(e)?0:Rc(Va(e))}function ot(e){return Lt(e)?e:Vs(e,!1,fc,vc,rl)}function Nn(e){return Vs(e,!1,hc,bc,sl)}function il(e){return Vs(e,!0,dc,Ec,ol)}function Vs(e,t,n,r,s){if(!ue(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const o=s.get(e);if(o)return o;const i=Cc(e);if(i===0)return e;const l=new Proxy(e,i===2?r:n);return s.set(e,l),l}function Kt(e){return Lt(e)?Kt(e.__v_raw):!!(e&&e.__v_isReactive)}function Lt(e){return!!(e&&e.__v_isReadonly)}function or(e){return!!(e&&e.__v_isShallow)}function ll(e){return Kt(e)||Lt(e)}function re(e){const t=e&&e.__v_raw;return t?re(t):e}function al(e){return rr(e,"__v_skip",!0),e}const Cn=e=>ue(e)?ot(e):e,Ws=e=>ue(e)?il(e):e;function qs(e){_t&&Ue&&(e=re(e),Zi(e.dep||(e.dep=Ds())))}function zs(e,t){e=re(e);const n=e.dep;n&&os(n)}function ve(e){return!!(e&&e.__v_isRef===!0)}function Ze(e){return cl(e,!1)}function Pn(e){return cl(e,!0)}function cl(e,t){return ve(e)?e:new Pc(e,t)}class Pc{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:re(t),this._value=n?t:Cn(t)}get value(){return qs(this),this._value}set value(t){const n=this.__v_isShallow||or(t)||Lt(t);t=n?t:re(t),St(t,this._rawValue)&&(this._rawValue=t,this._value=n?t:Cn(t),zs(this))}}function he(e){return ve(e)?e.value:e}const Tc={get:(e,t,n)=>he(Reflect.get(e,t,n)),set:(e,t,n,r)=>{const s=e[t];return ve(s)&&!ve(n)?(s.value=n,!0):Reflect.set(e,t,n,r)}};function ul(e){return Kt(e)?e:new Proxy(e,Tc)}class Ac{constructor(t){this.dep=void 0,this.__v_isRef=!0;const{get:n,set:r}=t(()=>qs(this),()=>zs(this));this._get=n,this._set=r}get value(){return this._get()}set value(t){this._set(t)}}function ey(e){return new Ac(e)}function ty(e){const t=z(e)?new Array(e.length):{};for(const n in e)t[n]=fl(e,n);return t}class xc{constructor(t,n,r){this._object=t,this._key=n,this._defaultValue=r,this.__v_isRef=!0}get value(){const t=this._object[this._key];return t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return ic(re(this._object),this._key)}}class kc{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function Oc(e,t,n){return ve(e)?e:X(e)?new kc(e):ue(e)&&arguments.length>1?fl(e,t,n):Ze(e)}function fl(e,t,n){const r=e[t];return ve(r)?r:new xc(e,t,n)}class Sc{constructor(t,n,r,s){this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this._dirty=!0,this.effect=new Bs(t,()=>{this._dirty||(this._dirty=!0,zs(this))}),this.effect.computed=this,this.effect.active=this._cacheable=!s,this.__v_isReadonly=r}get value(){const t=re(this);return qs(t),(t._dirty||!t._cacheable)&&(t._dirty=!1,t._value=t.effect.run()),t._value}set value(t){this._setter(t)}}function Lc(e,t,n=!1){let r,s;const o=X(e);return o?(r=e,s=Ge):(r=e.get,s=e.set),new Sc(r,s,o||!s,n)}function vt(e,t,n,r){let s;try{s=r?e(...r):e()}catch(o){on(o,t,n)}return s}function je(e,t,n,r){if(X(e)){const o=vt(e,t,n,r);return o&&Ki(o)&&o.catch(i=>{on(i,t,n)}),o}const s=[];for(let o=0;o>>1,s=Re[r],o=An(s);oXe&&Re.splice(t,1)}function ls(e){z(e)?Vt.push(...e):(!rt||!rt.includes(e,e.allowRecurse?Tt+1:Tt))&&Vt.push(e),hl()}function xo(e,t=Tn?Xe+1:0){for(;tAn(n)-An(r)),Tt=0;Tte.id==null?1/0:e.id,Nc=(e,t)=>{const n=An(e)-An(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function pl(e){is=!1,Tn=!0,Re.sort(Nc);try{for(Xe=0;Xepe(m)?m.trim():m)),f&&(s=n.map(za))}let l,a=r[l=Mr(t)]||r[l=Mr(et(t))];!a&&o&&(a=r[l=Mr(nn(t))]),a&&je(a,e,6,s);const u=r[l+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,je(u,e,6,s)}}function gl(e,t,n=!1){const r=t.emitsCache,s=r.get(e);if(s!==void 0)return s;const o=e.emits;let i={},l=!1;if(!X(e)){const a=u=>{const c=gl(u,t,!0);c&&(l=!0,_e(i,c))};!n&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!o&&!l?(ue(e)&&r.set(e,null),null):(z(o)?o.forEach(a=>i[a]=null):_e(i,o),ue(e)&&r.set(e,i),i)}function Rr(e,t){return!e||!Hn(t)?!1:(t=t.slice(2).replace(/Once$/,""),ne(e,t[0].toLowerCase()+t.slice(1))||ne(e,nn(t))||ne(e,t))}let Ee=null,Cr=null;function lr(e){const t=Ee;return Ee=e,Cr=e&&e.type.__scopeId||null,t}function ny(e){Cr=e}function ry(){Cr=null}function Js(e,t=Ee,n){if(!t||e._n)return e;const r=(...s)=>{r._d&&Bo(-1);const o=lr(t);let i;try{i=e(...s)}finally{lr(o),r._d&&Bo(1)}return i};return r._n=!0,r._c=!0,r._d=!0,r}function jr(e){const{type:t,vnode:n,proxy:r,withProxy:s,props:o,propsOptions:[i],slots:l,attrs:a,emit:u,render:c,renderCache:f,data:d,setupState:m,ctx:v,inheritAttrs:R}=e;let k,w;const b=lr(e);try{if(n.shapeFlag&4){const g=s||r,C=g;k=Ne(c.call(C,g,f,o,m,d,v)),w=a}else{const g=t;k=Ne(g.length>1?g(o,{attrs:a,slots:l,emit:u}):g(o,null)),w=t.props?a:Fc(a)}}catch(g){vn.length=0,on(g,e,1),k=de(Te)}let y=k;if(w&&R!==!1){const g=Object.keys(w),{shapeFlag:C}=y;g.length&&C&7&&(i&&g.some(Ms)&&(w=Dc(w,i)),y=it(y,w))}return n.dirs&&(y=it(y),y.dirs=y.dirs?y.dirs.concat(n.dirs):n.dirs),n.transition&&(y.transition=n.transition),k=y,lr(b),k}function jc(e){let t;for(let n=0;n{let t;for(const n in e)(n==="class"||n==="style"||Hn(n))&&((t||(t={}))[n]=e[n]);return t},Dc=(e,t)=>{const n={};for(const r in e)(!Ms(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function Bc(e,t,n){const{props:r,children:s,component:o}=e,{props:i,children:l,patchFlag:a}=t,u=o.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&a>=0){if(a&1024)return!0;if(a&16)return r?ko(r,i,u):!!i;if(a&8){const c=t.dynamicProps;for(let f=0;fe.__isSuspense,Vc={name:"Suspense",__isSuspense:!0,process(e,t,n,r,s,o,i,l,a,u){e==null?Wc(t,n,r,s,o,i,l,a,u):qc(e,t,n,r,s,i,l,a,u)},hydrate:zc,create:Gs,normalize:Qc},vl=Vc;function xn(e,t){const n=e.props&&e.props[t];X(n)&&n()}function Wc(e,t,n,r,s,o,i,l,a){const{p:u,o:{createElement:c}}=a,f=c("div"),d=e.suspense=Gs(e,s,r,t,f,n,o,i,l,a);u(null,d.pendingBranch=e.ssContent,f,null,r,d,o,i),d.deps>0?(xn(e,"onPending"),xn(e,"onFallback"),u(null,e.ssFallback,t,n,r,null,o,i),Wt(d,e.ssFallback)):d.resolve(!1,!0)}function qc(e,t,n,r,s,o,i,l,{p:a,um:u,o:{createElement:c}}){const f=t.suspense=e.suspense;f.vnode=t,t.el=e.el;const d=t.ssContent,m=t.ssFallback,{activeBranch:v,pendingBranch:R,isInFallback:k,isHydrating:w}=f;if(R)f.pendingBranch=d,Ke(d,R)?(a(R,d,f.hiddenContainer,null,s,f,o,i,l),f.deps<=0?f.resolve():k&&(a(v,m,n,r,s,null,o,i,l),Wt(f,m))):(f.pendingId++,w?(f.isHydrating=!1,f.activeBranch=R):u(R,s,f),f.deps=0,f.effects.length=0,f.hiddenContainer=c("div"),k?(a(null,d,f.hiddenContainer,null,s,f,o,i,l),f.deps<=0?f.resolve():(a(v,m,n,r,s,null,o,i,l),Wt(f,m))):v&&Ke(d,v)?(a(v,d,n,r,s,f,o,i,l),f.resolve(!0)):(a(null,d,f.hiddenContainer,null,s,f,o,i,l),f.deps<=0&&f.resolve()));else if(v&&Ke(d,v))a(v,d,n,r,s,f,o,i,l),Wt(f,d);else if(xn(t,"onPending"),f.pendingBranch=d,f.pendingId++,a(null,d,f.hiddenContainer,null,s,f,o,i,l),f.deps<=0)f.resolve();else{const{timeout:b,pendingId:y}=f;b>0?setTimeout(()=>{f.pendingId===y&&f.fallback(m)},b):b===0&&f.fallback(m)}}function Gs(e,t,n,r,s,o,i,l,a,u,c=!1){const{p:f,m:d,um:m,n:v,o:{parentNode:R,remove:k}}=u;let w;const b=Jc(e);b&&t!=null&&t.pendingBranch&&(w=t.pendingId,t.deps++);const y=e.props?qi(e.props.timeout):void 0,g={vnode:e,parent:t,parentComponent:n,isSVG:i,container:r,hiddenContainer:s,anchor:o,deps:0,pendingId:0,timeout:typeof y=="number"?y:-1,activeBranch:null,pendingBranch:null,isInFallback:!0,isHydrating:c,isUnmounted:!1,effects:[],resolve(C=!1,I=!1){const{vnode:N,activeBranch:O,pendingBranch:D,pendingId:M,effects:Q,parentComponent:L,container:J}=g;let ae=!1;if(g.isHydrating)g.isHydrating=!1;else if(!C){ae=O&&D.transition&&D.transition.mode==="out-in",ae&&(O.transition.afterLeave=()=>{M===g.pendingId&&(d(D,J,v(O),0),ls(Q))});let{anchor:Z}=g;O&&(Z=v(O),m(O,L,g,!0)),ae||d(D,J,Z,0)}Wt(g,D),g.pendingBranch=null,g.isInFallback=!1;let le=g.parent,U=!1;for(;le;){if(le.pendingBranch){le.effects.push(...Q),U=!0;break}le=le.parent}!U&&!ae&&ls(Q),g.effects=[],b&&t&&t.pendingBranch&&w===t.pendingId&&(t.deps--,t.deps===0&&!I&&t.resolve()),xn(N,"onResolve")},fallback(C){if(!g.pendingBranch)return;const{vnode:I,activeBranch:N,parentComponent:O,container:D,isSVG:M}=g;xn(I,"onFallback");const Q=()=>{g.isInFallback&&(f(null,C,D,v(N),O,null,M,l,a),Wt(g,C))},L=C.transition&&C.transition.mode==="out-in";L&&(N.transition.afterLeave=Q),g.isInFallback=!0,m(N,O,null,!0),L||Q()},move(C,I,N){g.activeBranch&&d(g.activeBranch,C,I,N),g.container=C},next(){return g.activeBranch&&v(g.activeBranch)},registerDep(C,I){const N=!!g.pendingBranch;N&&g.deps++;const O=C.vnode.el;C.asyncDep.catch(D=>{on(D,C,0)}).then(D=>{if(C.isUnmounted||g.isUnmounted||g.pendingId!==C.suspenseId)return;C.asyncResolved=!0;const{vnode:M}=C;hs(C,D,!1),O&&(M.el=O);const Q=!O&&C.subTree.el;I(C,M,R(O||C.subTree.el),O?null:v(C.subTree),g,i,a),Q&&k(Q),Xs(C,M.el),N&&--g.deps===0&&g.resolve()})},unmount(C,I){g.isUnmounted=!0,g.activeBranch&&m(g.activeBranch,n,C,I),g.pendingBranch&&m(g.pendingBranch,n,C,I)}};return g}function zc(e,t,n,r,s,o,i,l,a){const u=t.suspense=Gs(t,r,n,e.parentNode,document.createElement("div"),null,s,o,i,l,!0),c=a(e,u.pendingBranch=t.ssContent,n,u,o,i);return u.deps===0&&u.resolve(!1,!0),c}function Qc(e){const{shapeFlag:t,children:n}=e,r=t&32;e.ssContent=So(r?n.default:n),e.ssFallback=r?So(n.fallback):de(Te)}function So(e){let t;if(X(e)){const n=Xt&&e._c;n&&(e._d=!1,Ye()),e=e(),n&&(e._d=!0,t=Me,Bl())}return z(e)&&(e=jc(e)),e=Ne(e),t&&!e.dynamicChildren&&(e.dynamicChildren=t.filter(n=>n!==e)),e}function bl(e,t){t&&t.pendingBranch?z(e)?t.effects.push(...e):t.effects.push(e):ls(e)}function Wt(e,t){e.activeBranch=t;const{vnode:n,parentComponent:r}=e,s=n.el=t.el;r&&r.subTree===n&&(r.vnode.el=s,Xs(r,s))}function Jc(e){var t;return((t=e.props)==null?void 0:t.suspensible)!=null&&e.props.suspensible!==!1}function sy(e,t){return Zs(e,null,t)}const qn={};function qt(e,t,n){return Zs(e,t,n)}function Zs(e,t,{immediate:n,deep:r,flush:s,onTrack:o,onTrigger:i}=fe){var l;const a=rc()===((l=ye)==null?void 0:l.scope)?ye:null;let u,c=!1,f=!1;if(ve(e)?(u=()=>e.value,c=or(e)):Kt(e)?(u=()=>e,r=!0):z(e)?(f=!0,c=e.some(g=>Kt(g)||or(g)),u=()=>e.map(g=>{if(ve(g))return g.value;if(Kt(g))return Ft(g);if(X(g))return vt(g,a,2)})):X(e)?t?u=()=>vt(e,a,2):u=()=>{if(!(a&&a.isUnmounted))return d&&d(),je(e,a,3,[m])}:u=Ge,t&&r){const g=u;u=()=>Ft(g())}let d,m=g=>{d=b.onStop=()=>{vt(g,a,4),d=b.onStop=void 0}},v;if(Zt)if(m=Ge,t?n&&je(t,a,3,[u(),f?[]:void 0,m]):u(),s==="sync"){const g=Bu();v=g.__watcherHandles||(g.__watcherHandles=[])}else return Ge;let R=f?new Array(e.length).fill(qn):qn;const k=()=>{if(b.active)if(t){const g=b.run();(r||c||(f?g.some((C,I)=>St(C,R[I])):St(g,R)))&&(d&&d(),je(t,a,3,[g,R===qn?void 0:f&&R[0]===qn?[]:R,m]),R=g)}else b.run()};k.allowRecurse=!!t;let w;s==="sync"?w=k:s==="post"?w=()=>be(k,a&&a.suspense):(k.pre=!0,a&&(k.id=a.uid),w=()=>wr(k));const b=new Bs(u,w);t?n?k():R=b.run():s==="post"?be(b.run.bind(b),a&&a.suspense):b.run();const y=()=>{b.stop(),a&&a.scope&&js(a.scope.effects,b)};return v&&v.push(y),y}function Xc(e,t,n){const r=this.proxy,s=pe(e)?e.includes(".")?El(r,e):()=>r[e]:e.bind(r,r);let o;X(t)?o=t:(o=t.handler,n=t);const i=ye;Gt(this);const l=Zs(s,o.bind(r),n);return i?Gt(i):Ot(),l}function El(e,t){const n=t.split(".");return()=>{let r=e;for(let s=0;s{Ft(n,t)});else if(Wi(e))for(const n in e)Ft(e[n],t);return e}function Je(e,t,n,r){const s=e.dirs,o=t&&t.dirs;for(let i=0;i{e.isMounted=!0}),Ar(()=>{e.isUnmounting=!0}),e}const $e=[Function,Array],wl={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:$e,onEnter:$e,onAfterEnter:$e,onEnterCancelled:$e,onBeforeLeave:$e,onLeave:$e,onAfterLeave:$e,onLeaveCancelled:$e,onBeforeAppear:$e,onAppear:$e,onAfterAppear:$e,onAppearCancelled:$e},Gc={name:"BaseTransition",props:wl,setup(e,{slots:t}){const n=kr(),r=Yc();let s;return()=>{const o=t.default&&Cl(t.default(),!0);if(!o||!o.length)return;let i=o[0];if(o.length>1){for(const R of o)if(R.type!==Te){i=R;break}}const l=re(e),{mode:a}=l;if(r.isLeaving)return Fr(i);const u=Lo(i);if(!u)return Fr(i);const c=as(u,l,r,n);ar(u,c);const f=n.subTree,d=f&&Lo(f);let m=!1;const{getTransitionKey:v}=u.type;if(v){const R=v();s===void 0?s=R:R!==s&&(s=R,m=!0)}if(d&&d.type!==Te&&(!Ke(u,d)||m)){const R=as(d,l,r,n);if(ar(d,R),a==="out-in")return r.isLeaving=!0,R.afterLeave=()=>{r.isLeaving=!1,n.update.active!==!1&&n.update()},Fr(i);a==="in-out"&&u.type!==Te&&(R.delayLeave=(k,w,b)=>{const y=Rl(r,d);y[String(d.key)]=d,k[pt]=()=>{w(),k[pt]=void 0,delete c.delayedLeave},c.delayedLeave=b})}return i}}},Zc=Gc;function Rl(e,t){const{leavingVNodes:n}=e;let r=n.get(t.type);return r||(r=Object.create(null),n.set(t.type,r)),r}function as(e,t,n,r){const{appear:s,mode:o,persisted:i=!1,onBeforeEnter:l,onEnter:a,onAfterEnter:u,onEnterCancelled:c,onBeforeLeave:f,onLeave:d,onAfterLeave:m,onLeaveCancelled:v,onBeforeAppear:R,onAppear:k,onAfterAppear:w,onAppearCancelled:b}=t,y=String(e.key),g=Rl(n,e),C=(O,D)=>{O&&je(O,r,9,D)},I=(O,D)=>{const M=D[1];C(O,D),z(O)?O.every(Q=>Q.length<=1)&&M():O.length<=1&&M()},N={mode:o,persisted:i,beforeEnter(O){let D=l;if(!n.isMounted)if(s)D=R||l;else return;O[pt]&&O[pt](!0);const M=g[y];M&&Ke(e,M)&&M.el[pt]&&M.el[pt](),C(D,[O])},enter(O){let D=a,M=u,Q=c;if(!n.isMounted)if(s)D=k||a,M=w||u,Q=b||c;else return;let L=!1;const J=O[zn]=ae=>{L||(L=!0,ae?C(Q,[O]):C(M,[O]),N.delayedLeave&&N.delayedLeave(),O[zn]=void 0)};D?I(D,[O,J]):J()},leave(O,D){const M=String(e.key);if(O[zn]&&O[zn](!0),n.isUnmounting)return D();C(f,[O]);let Q=!1;const L=O[pt]=J=>{Q||(Q=!0,D(),J?C(v,[O]):C(m,[O]),O[pt]=void 0,g[M]===e&&delete g[M])};g[M]=e,d?I(d,[O,L]):L()},clone(O){return as(O,t,n,r)}};return N}function Fr(e){if(jn(e))return e=it(e),e.children=null,e}function Lo(e){return jn(e)?e.children?e.children[0]:void 0:e}function ar(e,t){e.shapeFlag&6&&e.component?ar(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Cl(e,t=!1,n){let r=[],s=0;for(let o=0;o1)for(let o=0;o!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function ee(e){X(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:r,delay:s=200,timeout:o,suspensible:i=!0,onError:l}=e;let a=null,u,c=0;const f=()=>(c++,a=null,d()),d=()=>{let m;return a||(m=a=t().catch(v=>{if(v=v instanceof Error?v:new Error(String(v)),l)return new Promise((R,k)=>{l(v,()=>R(f()),()=>k(v),c+1)});throw v}).then(v=>m!==a&&a?a:(v&&(v.__esModule||v[Symbol.toStringTag]==="Module")&&(v=v.default),u=v,v)))};return ln({name:"AsyncComponentWrapper",__asyncLoader:d,get __asyncResolved(){return u},setup(){const m=ye;if(u)return()=>Dr(u,m);const v=b=>{a=null,on(b,m,13,!r)};if(i&&m.suspense||Zt)return d().then(b=>()=>Dr(b,m)).catch(b=>(v(b),()=>r?de(r,{error:b}):null));const R=Ze(!1),k=Ze(),w=Ze(!!s);return s&&setTimeout(()=>{w.value=!1},s),o!=null&&setTimeout(()=>{if(!R.value&&!k.value){const b=new Error(`Async component timed out after ${o}ms.`);v(b),k.value=b}},o),d().then(()=>{R.value=!0,m.parent&&jn(m.parent.vnode)&&wr(m.parent.update)}).catch(b=>{v(b),k.value=b}),()=>{if(R.value&&u)return Dr(u,m);if(k.value&&r)return de(r,{error:k.value});if(n&&!w.value)return de(n)}}})}function Dr(e,t){const{ref:n,props:r,children:s,ce:o}=t.vnode,i=de(e,r,s);return i.ref=n,i.ce=o,delete t.vnode.ce,i}const jn=e=>e.type.__isKeepAlive,eu={name:"KeepAlive",__isKeepAlive:!0,props:{include:[String,RegExp,Array],exclude:[String,RegExp,Array],max:[String,Number]},setup(e,{slots:t}){const n=kr(),r=n.ctx;if(!r.renderer)return()=>{const b=t.default&&t.default();return b&&b.length===1?b[0]:b};const s=new Map,o=new Set;let i=null;const l=n.suspense,{renderer:{p:a,m:u,um:c,o:{createElement:f}}}=r,d=f("div");r.activate=(b,y,g,C,I)=>{const N=b.component;u(b,y,g,0,l),a(N.vnode,b,y,g,N,l,C,b.slotScopeIds,I),be(()=>{N.isDeactivated=!1,N.a&&mn(N.a);const O=b.props&&b.props.onVnodeMounted;O&&xe(O,N.parent,b)},l)},r.deactivate=b=>{const y=b.component;u(b,d,null,1,l),be(()=>{y.da&&mn(y.da);const g=b.props&&b.props.onVnodeUnmounted;g&&xe(g,y.parent,b),y.isDeactivated=!0},l)};function m(b){Br(b),c(b,n,l,!0)}function v(b){s.forEach((y,g)=>{const C=ps(y.type);C&&(!b||!b(C))&&R(g)})}function R(b){const y=s.get(b);!i||!Ke(y,i)?m(y):i&&Br(i),s.delete(b),o.delete(b)}qt(()=>[e.include,e.exclude],([b,y])=>{b&&v(g=>hn(b,g)),y&&v(g=>!hn(y,g))},{flush:"post",deep:!0});let k=null;const w=()=>{k!=null&&s.set(k,Ur(n.subTree))};return Tr(w),Tl(w),Ar(()=>{s.forEach(b=>{const{subTree:y,suspense:g}=n,C=Ur(y);if(b.type===C.type&&b.key===C.key){Br(C);const I=C.component.da;I&&be(I,g);return}m(b)})}),()=>{if(k=null,!t.default)return null;const b=t.default(),y=b[0];if(b.length>1)return i=null,b;if(!Yt(y)||!(y.shapeFlag&4)&&!(y.shapeFlag&128))return i=null,y;let g=Ur(y);const C=g.type,I=ps(kt(g)?g.type.__asyncResolved||{}:C),{include:N,exclude:O,max:D}=e;if(N&&(!I||!hn(N,I))||O&&I&&hn(O,I))return i=g,y;const M=g.key==null?C:g.key,Q=s.get(M);return g.el&&(g=it(g),y.shapeFlag&128&&(y.ssContent=g)),k=M,Q?(g.el=Q.el,g.component=Q.component,g.transition&&ar(g,g.transition),g.shapeFlag|=512,o.delete(M),o.add(M)):(o.add(M),D&&o.size>parseInt(D,10)&&R(o.values().next().value)),g.shapeFlag|=256,i=g,_l(y.type)?y:g}}},tu=eu;function hn(e,t){return z(e)?e.some(n=>hn(n,t)):pe(e)?e.split(",").includes(t):Ka(e)?e.test(t):!1}function nu(e,t){Pl(e,"a",t)}function ru(e,t){Pl(e,"da",t)}function Pl(e,t,n=ye){const r=e.__wdc||(e.__wdc=()=>{let s=n;for(;s;){if(s.isDeactivated)return;s=s.parent}return e()});if(Pr(t,r,n),n){let s=n.parent;for(;s&&s.parent;)jn(s.parent.vnode)&&su(r,t,n,s),s=s.parent}}function su(e,t,n,r){const s=Pr(t,e,r,!0);Al(()=>{js(r[t],s)},n)}function Br(e){e.shapeFlag&=-257,e.shapeFlag&=-513}function Ur(e){return e.shapeFlag&128?e.ssContent:e}function Pr(e,t,n=ye,r=!1){if(n){const s=n[e]||(n[e]=[]),o=t.__weh||(t.__weh=(...i)=>{if(n.isUnmounted)return;rn(),Gt(n);const l=je(t,n,e,i);return Ot(),sn(),l});return r?s.unshift(o):s.push(o),o}}const lt=e=>(t,n=ye)=>(!Zt||e==="sp")&&Pr(e,(...r)=>t(...r),n),ou=lt("bm"),Tr=lt("m"),iu=lt("bu"),Tl=lt("u"),Ar=lt("bum"),Al=lt("um"),lu=lt("sp"),au=lt("rtg"),cu=lt("rtc");function xl(e,t=ye){Pr("ec",e,t)}function oy(e,t,n,r){let s;const o=n&&n[r];if(z(e)||pe(e)){s=new Array(e.length);for(let i=0,l=e.length;it(i,l,void 0,o&&o[l]));else{const i=Object.keys(e);s=new Array(i.length);for(let l=0,a=i.length;lYt(t)?!(t.type===Te||t.type===ke&&!kl(t.children)):!0)?e:null}const cs=e=>e?Wl(e)?oo(e)||e.proxy:cs(e.parent):null,yn=_e(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>cs(e.parent),$root:e=>cs(e.root),$emit:e=>e.emit,$options:e=>eo(e),$forceUpdate:e=>e.f||(e.f=()=>wr(e.update)),$nextTick:e=>e.n||(e.n=Mn.bind(e.proxy)),$watch:e=>Xc.bind(e)}),Kr=(e,t)=>e!==fe&&!e.__isScriptSetup&&ne(e,t),uu={get({_:e},t){const{ctx:n,setupState:r,data:s,props:o,accessCache:i,type:l,appContext:a}=e;let u;if(t[0]!=="$"){const m=i[t];if(m!==void 0)switch(m){case 1:return r[t];case 2:return s[t];case 4:return n[t];case 3:return o[t]}else{if(Kr(r,t))return i[t]=1,r[t];if(s!==fe&&ne(s,t))return i[t]=2,s[t];if((u=e.propsOptions[0])&&ne(u,t))return i[t]=3,o[t];if(n!==fe&&ne(n,t))return i[t]=4,n[t];us&&(i[t]=0)}}const c=yn[t];let f,d;if(c)return t==="$attrs"&&Oe(e,"get",t),c(e);if((f=l.__cssModules)&&(f=f[t]))return f;if(n!==fe&&ne(n,t))return i[t]=4,n[t];if(d=a.config.globalProperties,ne(d,t))return d[t]},set({_:e},t,n){const{data:r,setupState:s,ctx:o}=e;return Kr(s,t)?(s[t]=n,!0):r!==fe&&ne(r,t)?(r[t]=n,!0):ne(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:s,propsOptions:o}},i){let l;return!!n[i]||e!==fe&&ne(e,i)||Kr(t,i)||(l=o[0])&&ne(l,i)||ne(r,i)||ne(yn,i)||ne(s.config.globalProperties,i)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:ne(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function ly(){return fu().slots}function fu(){const e=kr();return e.setupContext||(e.setupContext=zl(e))}function Io(e){return z(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let us=!0;function du(e){const t=eo(e),n=e.proxy,r=e.ctx;us=!1,t.beforeCreate&&Ho(t.beforeCreate,e,"bc");const{data:s,computed:o,methods:i,watch:l,provide:a,inject:u,created:c,beforeMount:f,mounted:d,beforeUpdate:m,updated:v,activated:R,deactivated:k,beforeDestroy:w,beforeUnmount:b,destroyed:y,unmounted:g,render:C,renderTracked:I,renderTriggered:N,errorCaptured:O,serverPrefetch:D,expose:M,inheritAttrs:Q,components:L,directives:J,filters:ae}=t;if(u&&hu(u,r,null),i)for(const Z in i){const K=i[Z];X(K)&&(r[Z]=K.bind(n))}if(s){const Z=s.call(n,n);ue(Z)&&(e.data=ot(Z))}if(us=!0,o)for(const Z in o){const K=o[Z],Fe=X(K)?K.bind(n,n):X(K.get)?K.get.bind(n,n):Ge,at=!X(K)&&X(K.set)?K.set.bind(n):Ge,ze=Pe({get:Fe,set:at});Object.defineProperty(r,Z,{enumerable:!0,configurable:!0,get:()=>ze.value,set:Ae=>ze.value=Ae})}if(l)for(const Z in l)Ol(l[Z],r,n,Z);if(a){const Z=X(a)?a.call(n):a;Reflect.ownKeys(Z).forEach(K=>{zt(K,Z[K])})}c&&Ho(c,e,"c");function U(Z,K){z(K)?K.forEach(Fe=>Z(Fe.bind(n))):K&&Z(K.bind(n))}if(U(ou,f),U(Tr,d),U(iu,m),U(Tl,v),U(nu,R),U(ru,k),U(xl,O),U(cu,I),U(au,N),U(Ar,b),U(Al,g),U(lu,D),z(M))if(M.length){const Z=e.exposed||(e.exposed={});M.forEach(K=>{Object.defineProperty(Z,K,{get:()=>n[K],set:Fe=>n[K]=Fe})})}else e.exposed||(e.exposed={});C&&e.render===Ge&&(e.render=C),Q!=null&&(e.inheritAttrs=Q),L&&(e.components=L),J&&(e.directives=J)}function hu(e,t,n=Ge){z(e)&&(e=fs(e));for(const r in e){const s=e[r];let o;ue(s)?"default"in s?o=He(s.from||r,s.default,!0):o=He(s.from||r):o=He(s),ve(o)?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>o.value,set:i=>o.value=i}):t[r]=o}}function Ho(e,t,n){je(z(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,n)}function Ol(e,t,n,r){const s=r.includes(".")?El(n,r):()=>n[r];if(pe(e)){const o=t[e];X(o)&&qt(s,o)}else if(X(e))qt(s,e.bind(n));else if(ue(e))if(z(e))e.forEach(o=>Ol(o,t,n,r));else{const o=X(e.handler)?e.handler.bind(n):t[e.handler];X(o)&&qt(s,o,e)}}function eo(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:s,optionsCache:o,config:{optionMergeStrategies:i}}=e.appContext,l=o.get(t);let a;return l?a=l:!s.length&&!n&&!r?a=t:(a={},s.length&&s.forEach(u=>cr(a,u,i,!0)),cr(a,t,i)),ue(t)&&o.set(t,a),a}function cr(e,t,n,r=!1){const{mixins:s,extends:o}=t;o&&cr(e,o,n,!0),s&&s.forEach(i=>cr(e,i,n,!0));for(const i in t)if(!(r&&i==="expose")){const l=pu[i]||n&&n[i];e[i]=l?l(e[i],t[i]):t[i]}return e}const pu={data:$o,props:No,emits:No,methods:pn,computed:pn,beforeCreate:Ce,created:Ce,beforeMount:Ce,mounted:Ce,beforeUpdate:Ce,updated:Ce,beforeDestroy:Ce,beforeUnmount:Ce,destroyed:Ce,unmounted:Ce,activated:Ce,deactivated:Ce,errorCaptured:Ce,serverPrefetch:Ce,components:pn,directives:pn,watch:mu,provide:$o,inject:gu};function $o(e,t){return t?e?function(){return _e(X(e)?e.call(this,this):e,X(t)?t.call(this,this):t)}:t:e}function gu(e,t){return pn(fs(e),fs(t))}function fs(e){if(z(e)){const t={};for(let n=0;n1)return n&&X(t)?t.call(r&&r.proxy):t}}function Ll(){return!!(ye||Ee||kn)}function vu(e,t,n,r=!1){const s={},o={};rr(o,xr,1),e.propsDefaults=Object.create(null),Il(e,t,s,o);for(const i in e.propsOptions[0])i in s||(s[i]=void 0);n?e.props=r?s:Nn(s):e.type.props?e.props=s:e.props=o,e.attrs=o}function bu(e,t,n,r){const{props:s,attrs:o,vnode:{patchFlag:i}}=e,l=re(s),[a]=e.propsOptions;let u=!1;if((r||i>0)&&!(i&16)){if(i&8){const c=e.vnode.dynamicProps;for(let f=0;f{a=!0;const[d,m]=Hl(f,t,!0);_e(i,d),m&&l.push(...m)};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}if(!o&&!a)return ue(e)&&r.set(e,Bt),Bt;if(z(o))for(let c=0;c-1,m[1]=R<0||v-1||ne(m,"default"))&&l.push(f)}}}const u=[i,l];return ue(e)&&r.set(e,u),u}function Mo(e){return e[0]!=="$"}function jo(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function Fo(e,t){return jo(e)===jo(t)}function Do(e,t){return z(t)?t.findIndex(n=>Fo(n,e)):X(t)&&Fo(t,e)?0:-1}const $l=e=>e[0]==="_"||e==="$stable",to=e=>z(e)?e.map(Ne):[Ne(e)],Eu=(e,t,n)=>{if(t._n)return t;const r=Js((...s)=>to(t(...s)),n);return r._c=!1,r},Nl=(e,t,n)=>{const r=e._ctx;for(const s in e){if($l(s))continue;const o=e[s];if(X(o))t[s]=Eu(s,o,r);else if(o!=null){const i=to(o);t[s]=()=>i}}},Ml=(e,t)=>{const n=to(t);e.slots.default=()=>n},wu=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=re(t),rr(t,"_",n)):Nl(t,e.slots={})}else e.slots={},t&&Ml(e,t);rr(e.slots,xr,1)},Ru=(e,t,n)=>{const{vnode:r,slots:s}=e;let o=!0,i=fe;if(r.shapeFlag&32){const l=t._;l?n&&l===1?o=!1:(_e(s,t),!n&&l===1&&delete s._):(o=!t.$stable,Nl(t,s)),i=t}else t&&(Ml(e,t),i={default:1});if(o)for(const l in s)!$l(l)&&i[l]==null&&delete s[l]};function ur(e,t,n,r,s=!1){if(z(e)){e.forEach((d,m)=>ur(d,t&&(z(t)?t[m]:t),n,r,s));return}if(kt(r)&&!s)return;const o=r.shapeFlag&4?oo(r.component)||r.component.proxy:r.el,i=s?null:o,{i:l,r:a}=e,u=t&&t.r,c=l.refs===fe?l.refs={}:l.refs,f=l.setupState;if(u!=null&&u!==a&&(pe(u)?(c[u]=null,ne(f,u)&&(f[u]=null)):ve(u)&&(u.value=null)),X(a))vt(a,l,12,[i,c]);else{const d=pe(a),m=ve(a);if(d||m){const v=()=>{if(e.f){const R=d?ne(f,a)?f[a]:c[a]:a.value;s?z(R)&&js(R,o):z(R)?R.includes(o)||R.push(o):d?(c[a]=[o],ne(f,a)&&(f[a]=c[a])):(a.value=[o],e.k&&(c[e.k]=a.value))}else d?(c[a]=i,ne(f,a)&&(f[a]=i)):m&&(a.value=i,e.k&&(c[e.k]=i))};i?(v.id=-1,be(v,n)):v()}}}let ut=!1;const Qn=e=>/svg/.test(e.namespaceURI)&&e.tagName!=="foreignObject",Jn=e=>e.nodeType===8;function Cu(e){const{mt:t,p:n,o:{patchProp:r,createText:s,nextSibling:o,parentNode:i,remove:l,insert:a,createComment:u}}=e,c=(y,g)=>{if(!g.hasChildNodes()){n(null,y,g),ir(),g._vnode=y;return}ut=!1,f(g.firstChild,y,null,null,null),ir(),g._vnode=y,ut&&console.error("Hydration completed but contains mismatches.")},f=(y,g,C,I,N,O=!1)=>{const D=Jn(y)&&y.data==="[",M=()=>R(y,g,C,I,N,D),{type:Q,ref:L,shapeFlag:J,patchFlag:ae}=g;let le=y.nodeType;g.el=y,ae===-2&&(O=!1,g.dynamicChildren=null);let U=null;switch(Q){case Jt:le!==3?g.children===""?(a(g.el=s(""),i(y),y),U=y):U=M():(y.data!==g.children&&(ut=!0,y.data=g.children),U=o(y));break;case Te:b(y)?(U=o(y),w(g.el=y.content.firstChild,y,C)):le!==8||D?U=M():U=o(y);break;case _n:if(D&&(y=o(y),le=y.nodeType),le===1||le===3){U=y;const Z=!g.children.length;for(let K=0;K{O=O||!!g.dynamicChildren;const{type:D,props:M,patchFlag:Q,shapeFlag:L,dirs:J,transition:ae}=g,le=D==="input"||D==="option";if(le||Q!==-1){if(J&&Je(g,null,C,"created"),M)if(le||!O||Q&48)for(const K in M)(le&&(K.endsWith("value")||K==="indeterminate")||Hn(K)&&!gn(K)||K[0]===".")&&r(y,K,null,M[K],!1,void 0,C);else M.onClick&&r(y,"onClick",null,M.onClick,!1,void 0,C);let U;(U=M&&M.onVnodeBeforeMount)&&xe(U,C,g);let Z=!1;if(b(y)){Z=Fl(I,ae)&&C&&C.vnode.props&&C.vnode.props.appear;const K=y.content.firstChild;Z&&ae.beforeEnter(K),w(K,y,C),g.el=y=K}if(J&&Je(g,null,C,"beforeMount"),((U=M&&M.onVnodeMounted)||J||Z)&&bl(()=>{U&&xe(U,C,g),Z&&ae.enter(y),J&&Je(g,null,C,"mounted")},I),L&16&&!(M&&(M.innerHTML||M.textContent))){let K=m(y.firstChild,g,y,C,I,N,O);for(;K;){ut=!0;const Fe=K;K=K.nextSibling,l(Fe)}}else L&8&&y.textContent!==g.children&&(ut=!0,y.textContent=g.children)}return y.nextSibling},m=(y,g,C,I,N,O,D)=>{D=D||!!g.dynamicChildren;const M=g.children,Q=M.length;for(let L=0;L{const{slotScopeIds:D}=g;D&&(N=N?N.concat(D):D);const M=i(y),Q=m(o(y),g,M,C,I,N,O);return Q&&Jn(Q)&&Q.data==="]"?o(g.anchor=Q):(ut=!0,a(g.anchor=u("]"),M,Q),Q)},R=(y,g,C,I,N,O)=>{if(ut=!0,g.el=null,O){const Q=k(y);for(;;){const L=o(y);if(L&&L!==Q)l(L);else break}}const D=o(y),M=i(y);return l(y),n(null,g,M,D,C,I,Qn(M),N),D},k=(y,g="[",C="]")=>{let I=0;for(;y;)if(y=o(y),y&&Jn(y)&&(y.data===g&&I++,y.data===C)){if(I===0)return o(y);I--}return y},w=(y,g,C)=>{const I=g.parentNode;I&&I.replaceChild(y,g);let N=C;for(;N;)N.vnode.el===g&&(N.vnode.el=N.subTree.el=y),N=N.parent},b=y=>y.nodeType===1&&y.tagName.toLowerCase()==="template";return[c,f]}const be=bl;function Pu(e){return jl(e)}function Tu(e){return jl(e,Cu)}function jl(e,t){const n=ns();n.__VUE__=!0;const{insert:r,remove:s,patchProp:o,createElement:i,createText:l,createComment:a,setText:u,setElementText:c,parentNode:f,nextSibling:d,setScopeId:m=Ge,insertStaticContent:v}=e,R=(h,p,_,E=null,T=null,A=null,j=!1,S=null,H=!!p.dynamicChildren)=>{if(h===p)return;h&&!Ke(h,p)&&(E=P(h),Ae(h,T,A,!0),h=null),p.patchFlag===-2&&(H=!1,p.dynamicChildren=null);const{type:x,ref:W,shapeFlag:B}=p;switch(x){case Jt:k(h,p,_,E);break;case Te:w(h,p,_,E);break;case _n:h==null&&b(p,_,E,j);break;case ke:L(h,p,_,E,T,A,j,S,H);break;default:B&1?C(h,p,_,E,T,A,j,S,H):B&6?J(h,p,_,E,T,A,j,S,H):(B&64||B&128)&&x.process(h,p,_,E,T,A,j,S,H,$)}W!=null&&T&&ur(W,h&&h.ref,A,p||h,!p)},k=(h,p,_,E)=>{if(h==null)r(p.el=l(p.children),_,E);else{const T=p.el=h.el;p.children!==h.children&&u(T,p.children)}},w=(h,p,_,E)=>{h==null?r(p.el=a(p.children||""),_,E):p.el=h.el},b=(h,p,_,E)=>{[h.el,h.anchor]=v(h.children,p,_,E,h.el,h.anchor)},y=({el:h,anchor:p},_,E)=>{let T;for(;h&&h!==p;)T=d(h),r(h,_,E),h=T;r(p,_,E)},g=({el:h,anchor:p})=>{let _;for(;h&&h!==p;)_=d(h),s(h),h=_;s(p)},C=(h,p,_,E,T,A,j,S,H)=>{j=j||p.type==="svg",h==null?I(p,_,E,T,A,j,S,H):D(h,p,T,A,j,S,H)},I=(h,p,_,E,T,A,j,S)=>{let H,x;const{type:W,props:B,shapeFlag:q,transition:Y,dirs:te}=h;if(H=h.el=i(h.type,A,B&&B.is,B),q&8?c(H,h.children):q&16&&O(h.children,H,null,E,T,A&&W!=="foreignObject",j,S),te&&Je(h,null,E,"created"),N(H,h,h.scopeId,j,E),B){for(const ie in B)ie!=="value"&&!gn(ie)&&o(H,ie,null,B[ie],A,h.children,E,T,we);"value"in B&&o(H,"value",null,B.value),(x=B.onVnodeBeforeMount)&&xe(x,E,h)}te&&Je(h,null,E,"beforeMount");const ce=Fl(T,Y);ce&&Y.beforeEnter(H),r(H,p,_),((x=B&&B.onVnodeMounted)||ce||te)&&be(()=>{x&&xe(x,E,h),ce&&Y.enter(H),te&&Je(h,null,E,"mounted")},T)},N=(h,p,_,E,T)=>{if(_&&m(h,_),E)for(let A=0;A{for(let x=H;x{const S=p.el=h.el;let{patchFlag:H,dynamicChildren:x,dirs:W}=p;H|=h.patchFlag&16;const B=h.props||fe,q=p.props||fe;let Y;_&&wt(_,!1),(Y=q.onVnodeBeforeUpdate)&&xe(Y,_,p,h),W&&Je(p,h,_,"beforeUpdate"),_&&wt(_,!0);const te=T&&p.type!=="foreignObject";if(x?M(h.dynamicChildren,x,S,_,E,te,A):j||K(h,p,S,null,_,E,te,A,!1),H>0){if(H&16)Q(S,p,B,q,_,E,T);else if(H&2&&B.class!==q.class&&o(S,"class",null,q.class,T),H&4&&o(S,"style",B.style,q.style,T),H&8){const ce=p.dynamicProps;for(let ie=0;ie{Y&&xe(Y,_,p,h),W&&Je(p,h,_,"updated")},E)},M=(h,p,_,E,T,A,j)=>{for(let S=0;S{if(_!==E){if(_!==fe)for(const S in _)!gn(S)&&!(S in E)&&o(h,S,_[S],null,j,p.children,T,A,we);for(const S in E){if(gn(S))continue;const H=E[S],x=_[S];H!==x&&S!=="value"&&o(h,S,x,H,j,p.children,T,A,we)}"value"in E&&o(h,"value",_.value,E.value)}},L=(h,p,_,E,T,A,j,S,H)=>{const x=p.el=h?h.el:l(""),W=p.anchor=h?h.anchor:l("");let{patchFlag:B,dynamicChildren:q,slotScopeIds:Y}=p;Y&&(S=S?S.concat(Y):Y),h==null?(r(x,_,E),r(W,_,E),O(p.children,_,W,T,A,j,S,H)):B>0&&B&64&&q&&h.dynamicChildren?(M(h.dynamicChildren,q,_,T,A,j,S),(p.key!=null||T&&p===T.subTree)&&Dl(h,p,!0)):K(h,p,_,W,T,A,j,S,H)},J=(h,p,_,E,T,A,j,S,H)=>{p.slotScopeIds=S,h==null?p.shapeFlag&512?T.ctx.activate(p,_,E,j,H):ae(p,_,E,T,A,j,H):le(h,p,H)},ae=(h,p,_,E,T,A,j)=>{const S=h.component=$u(h,E,T);if(jn(h)&&(S.ctx.renderer=$),Nu(S),S.asyncDep){if(T&&T.registerDep(S,U),!h.el){const H=S.subTree=de(Te);w(null,H,p,_)}return}U(S,h,p,_,T,A,j)},le=(h,p,_)=>{const E=p.component=h.component;if(Bc(h,p,_))if(E.asyncDep&&!E.asyncResolved){Z(E,p,_);return}else E.next=p,$c(E.update),E.update();else p.el=h.el,E.vnode=p},U=(h,p,_,E,T,A,j)=>{const S=()=>{if(h.isMounted){let{next:W,bu:B,u:q,parent:Y,vnode:te}=h,ce=W,ie;wt(h,!1),W?(W.el=te.el,Z(h,W,j)):W=te,B&&mn(B),(ie=W.props&&W.props.onVnodeBeforeUpdate)&&xe(ie,Y,W,te),wt(h,!0);const me=jr(h),De=h.subTree;h.subTree=me,R(De,me,f(De.el),P(De),h,T,A),W.el=me.el,ce===null&&Xs(h,me.el),q&&be(q,T),(ie=W.props&&W.props.onVnodeUpdated)&&be(()=>xe(ie,Y,W,te),T)}else{let W;const{el:B,props:q}=p,{bm:Y,m:te,parent:ce}=h,ie=kt(p);if(wt(h,!1),Y&&mn(Y),!ie&&(W=q&&q.onVnodeBeforeMount)&&xe(W,ce,p),wt(h,!0),B&&se){const me=()=>{h.subTree=jr(h),se(B,h.subTree,h,T,null)};ie?p.type.__asyncLoader().then(()=>!h.isUnmounted&&me()):me()}else{const me=h.subTree=jr(h);R(null,me,_,E,h,T,A),p.el=me.el}if(te&&be(te,T),!ie&&(W=q&&q.onVnodeMounted)){const me=p;be(()=>xe(W,ce,me),T)}(p.shapeFlag&256||ce&&kt(ce.vnode)&&ce.vnode.shapeFlag&256)&&h.a&&be(h.a,T),h.isMounted=!0,p=_=E=null}},H=h.effect=new Bs(S,()=>wr(x),h.scope),x=h.update=()=>H.run();x.id=h.uid,wt(h,!0),x()},Z=(h,p,_)=>{p.component=h;const E=h.vnode.props;h.vnode=p,h.next=null,bu(h,p.props,E,_),Ru(h,p.children,_),rn(),xo(),sn()},K=(h,p,_,E,T,A,j,S,H=!1)=>{const x=h&&h.children,W=h?h.shapeFlag:0,B=p.children,{patchFlag:q,shapeFlag:Y}=p;if(q>0){if(q&128){at(x,B,_,E,T,A,j,S,H);return}else if(q&256){Fe(x,B,_,E,T,A,j,S,H);return}}Y&8?(W&16&&we(x,T,A),B!==x&&c(_,B)):W&16?Y&16?at(x,B,_,E,T,A,j,S,H):we(x,T,A,!0):(W&8&&c(_,""),Y&16&&O(B,_,E,T,A,j,S,H))},Fe=(h,p,_,E,T,A,j,S,H)=>{h=h||Bt,p=p||Bt;const x=h.length,W=p.length,B=Math.min(x,W);let q;for(q=0;qW?we(h,T,A,!0,!1,B):O(p,_,E,T,A,j,S,H,B)},at=(h,p,_,E,T,A,j,S,H)=>{let x=0;const W=p.length;let B=h.length-1,q=W-1;for(;x<=B&&x<=q;){const Y=h[x],te=p[x]=H?gt(p[x]):Ne(p[x]);if(Ke(Y,te))R(Y,te,_,null,T,A,j,S,H);else break;x++}for(;x<=B&&x<=q;){const Y=h[B],te=p[q]=H?gt(p[q]):Ne(p[q]);if(Ke(Y,te))R(Y,te,_,null,T,A,j,S,H);else break;B--,q--}if(x>B){if(x<=q){const Y=q+1,te=Yq)for(;x<=B;)Ae(h[x],T,A,!0),x++;else{const Y=x,te=x,ce=new Map;for(x=te;x<=q;x++){const Se=p[x]=H?gt(p[x]):Ne(p[x]);Se.key!=null&&ce.set(Se.key,x)}let ie,me=0;const De=q-te+1;let Nt=!1,yo=0;const cn=new Array(De);for(x=0;x=De){Ae(Se,T,A,!0);continue}let Qe;if(Se.key!=null)Qe=ce.get(Se.key);else for(ie=te;ie<=q;ie++)if(cn[ie-te]===0&&Ke(Se,p[ie])){Qe=ie;break}Qe===void 0?Ae(Se,T,A,!0):(cn[Qe-te]=x+1,Qe>=yo?yo=Qe:Nt=!0,R(Se,p[Qe],_,null,T,A,j,S,H),me++)}const _o=Nt?Au(cn):Bt;for(ie=_o.length-1,x=De-1;x>=0;x--){const Se=te+x,Qe=p[Se],vo=Se+1{const{el:A,type:j,transition:S,children:H,shapeFlag:x}=h;if(x&6){ze(h.component.subTree,p,_,E);return}if(x&128){h.suspense.move(p,_,E);return}if(x&64){j.move(h,p,_,$);return}if(j===ke){r(A,p,_);for(let B=0;BS.enter(A),T);else{const{leave:B,delayLeave:q,afterLeave:Y}=S,te=()=>r(A,p,_),ce=()=>{B(A,()=>{te(),Y&&Y()})};q?q(A,te,ce):ce()}else r(A,p,_)},Ae=(h,p,_,E=!1,T=!1)=>{const{type:A,props:j,ref:S,children:H,dynamicChildren:x,shapeFlag:W,patchFlag:B,dirs:q}=h;if(S!=null&&ur(S,null,_,h,!0),W&256){p.ctx.deactivate(h);return}const Y=W&1&&q,te=!kt(h);let ce;if(te&&(ce=j&&j.onVnodeBeforeUnmount)&&xe(ce,p,h),W&6)Dn(h.component,_,E);else{if(W&128){h.suspense.unmount(_,E);return}Y&&Je(h,null,p,"beforeUnmount"),W&64?h.type.remove(h,p,_,T,$,E):x&&(A!==ke||B>0&&B&64)?we(x,p,_,!1,!0):(A===ke&&B&384||!T&&W&16)&&we(H,p,_),E&&Ht(h)}(te&&(ce=j&&j.onVnodeUnmounted)||Y)&&be(()=>{ce&&xe(ce,p,h),Y&&Je(h,null,p,"unmounted")},_)},Ht=h=>{const{type:p,el:_,anchor:E,transition:T}=h;if(p===ke){$t(_,E);return}if(p===_n){g(h);return}const A=()=>{s(_),T&&!T.persisted&&T.afterLeave&&T.afterLeave()};if(h.shapeFlag&1&&T&&!T.persisted){const{leave:j,delayLeave:S}=T,H=()=>j(_,A);S?S(h.el,A,H):H()}else A()},$t=(h,p)=>{let _;for(;h!==p;)_=d(h),s(h),h=_;s(p)},Dn=(h,p,_)=>{const{bum:E,scope:T,update:A,subTree:j,um:S}=h;E&&mn(E),T.stop(),A&&(A.active=!1,Ae(j,h,p,_)),S&&be(S,p),be(()=>{h.isUnmounted=!0},p),p&&p.pendingBranch&&!p.isUnmounted&&h.asyncDep&&!h.asyncResolved&&h.suspenseId===p.pendingId&&(p.deps--,p.deps===0&&p.resolve())},we=(h,p,_,E=!1,T=!1,A=0)=>{for(let j=A;jh.shapeFlag&6?P(h.component.subTree):h.shapeFlag&128?h.suspense.next():d(h.anchor||h.el),F=(h,p,_)=>{h==null?p._vnode&&Ae(p._vnode,null,null,!0):R(p._vnode||null,h,p,null,null,null,_),xo(),ir(),p._vnode=h},$={p:R,um:Ae,m:ze,r:Ht,mt:ae,mc:O,pc:K,pbc:M,n:P,o:e};let V,se;return t&&([V,se]=t($)),{render:F,hydrate:V,createApp:_u(F,V)}}function wt({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function Fl(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Dl(e,t,n=!1){const r=e.children,s=t.children;if(z(r)&&z(s))for(let o=0;o>1,e[n[l]]0&&(t[r]=n[o-1]),n[o]=r)}}for(o=n.length,i=n[o-1];o-- >0;)n[o]=i,i=t[i];return n}const xu=e=>e.__isTeleport,ke=Symbol.for("v-fgt"),Jt=Symbol.for("v-txt"),Te=Symbol.for("v-cmt"),_n=Symbol.for("v-stc"),vn=[];let Me=null;function Ye(e=!1){vn.push(Me=e?null:[])}function Bl(){vn.pop(),Me=vn[vn.length-1]||null}let Xt=1;function Bo(e){Xt+=e}function Ul(e){return e.dynamicChildren=Xt>0?Me||Bt:null,Bl(),Xt>0&&Me&&Me.push(e),e}function ku(e,t,n,r,s,o){return Ul(Qt(e,t,n,r,s,o,!0))}function yt(e,t,n,r,s){return Ul(de(e,t,n,r,s,!0))}function Yt(e){return e?e.__v_isVNode===!0:!1}function Ke(e,t){return e.type===t.type&&e.key===t.key}const xr="__vInternal",Kl=({key:e})=>e??null,Zn=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?pe(e)||ve(e)||X(e)?{i:Ee,r:e,k:t,f:!!n}:e:null);function Qt(e,t=null,n=null,r=0,s=null,o=e===ke?0:1,i=!1,l=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Kl(t),ref:t&&Zn(t),scopeId:Cr,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:r,dynamicProps:s,dynamicChildren:null,appContext:null,ctx:Ee};return l?(ro(a,n),o&128&&e.normalize(a)):n&&(a.shapeFlag|=pe(n)?8:16),Xt>0&&!i&&Me&&(a.patchFlag>0||o&6)&&a.patchFlag!==32&&Me.push(a),a}const de=Ou;function Ou(e,t=null,n=null,r=0,s=null,o=!1){if((!e||e===ml)&&(e=Te),Yt(e)){const l=it(e,t,!0);return n&&ro(l,n),Xt>0&&!o&&Me&&(l.shapeFlag&6?Me[Me.indexOf(e)]=l:Me.push(l)),l.patchFlag|=-2,l}if(Fu(e)&&(e=e.__vccOpts),t){t=Vl(t);let{class:l,style:a}=t;l&&!pe(l)&&(t.class=br(l)),ue(a)&&(ll(a)&&!z(a)&&(a=_e({},a)),t.style=vr(a))}const i=pe(e)?1:_l(e)?128:xu(e)?64:ue(e)?4:X(e)?2:0;return Qt(e,t,n,r,s,i,o,!0)}function Vl(e){return e?ll(e)||xr in e?_e({},e):e:null}function it(e,t,n=!1){const{props:r,ref:s,patchFlag:o,children:i}=e,l=t?Lu(r||{},t):r;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&Kl(l),ref:t&&t.ref?n&&s?z(s)?s.concat(Zn(t)):[s,Zn(t)]:Zn(t):s,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:i,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ke?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&it(e.ssContent),ssFallback:e.ssFallback&&it(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function no(e=" ",t=0){return de(Jt,null,e,t)}function Su(e,t){const n=de(_n,null,e);return n.staticCount=t,n}function ay(e="",t=!1){return t?(Ye(),yt(Te,null,e)):de(Te,null,e)}function Ne(e){return e==null||typeof e=="boolean"?de(Te):z(e)?de(ke,null,e.slice()):typeof e=="object"?gt(e):de(Jt,null,String(e))}function gt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:it(e)}function ro(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(z(t))n=16;else if(typeof t=="object")if(r&65){const s=t.default;s&&(s._c&&(s._d=!1),ro(e,s()),s._c&&(s._d=!0));return}else{n=32;const s=t._;!s&&!(xr in t)?t._ctx=Ee:s===3&&Ee&&(Ee.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else X(t)?(t={default:t,_ctx:Ee},n=32):(t=String(t),r&64?(n=16,t=[no(t)]):n=8);e.children=t,e.shapeFlag|=n}function Lu(...e){const t={};for(let n=0;nye||Ee;let so,Mt,Uo="__VUE_INSTANCE_SETTERS__";(Mt=ns()[Uo])||(Mt=ns()[Uo]=[]),Mt.push(e=>ye=e),so=e=>{Mt.length>1?Mt.forEach(t=>t(e)):Mt[0](e)};const Gt=e=>{so(e),e.scope.on()},Ot=()=>{ye&&ye.scope.off(),so(null)};function Wl(e){return e.vnode.shapeFlag&4}let Zt=!1;function Nu(e,t=!1){Zt=t;const{props:n,children:r}=e.vnode,s=Wl(e);vu(e,n,s,t),wu(e,r);const o=s?Mu(e,t):void 0;return Zt=!1,o}function Mu(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=al(new Proxy(e.ctx,uu));const{setup:r}=n;if(r){const s=e.setupContext=r.length>1?zl(e):null;Gt(e),rn();const o=vt(r,e,0,[e.props,s]);if(sn(),Ot(),Ki(o)){if(o.then(Ot,Ot),t)return o.then(i=>{hs(e,i,t)}).catch(i=>{on(i,e,0)});e.asyncDep=o}else hs(e,o,t)}else ql(e,t)}function hs(e,t,n){X(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:ue(t)&&(e.setupState=ul(t)),ql(e,n)}let Ko;function ql(e,t,n){const r=e.type;if(!e.render){if(!t&&Ko&&!r.render){const s=r.template||eo(e).template;if(s){const{isCustomElement:o,compilerOptions:i}=e.appContext.config,{delimiters:l,compilerOptions:a}=r,u=_e(_e({isCustomElement:o,delimiters:l},i),a);r.render=Ko(s,u)}}e.render=r.render||Ge}{Gt(e),rn();try{du(e)}finally{sn(),Ot()}}}function ju(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return Oe(e,"get","$attrs"),t[n]}}))}function zl(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return ju(e)},slots:e.slots,emit:e.emit,expose:t}}function oo(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(ul(al(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in yn)return yn[n](e)},has(t,n){return n in t||n in yn}}))}function ps(e,t=!0){return X(e)?e.displayName||e.name:e.name||t&&e.__name}function Fu(e){return X(e)&&"__vccOpts"in e}const Pe=(e,t)=>Lc(e,t,Zt);function Ve(e,t,n){const r=arguments.length;return r===2?ue(t)&&!z(t)?Yt(t)?de(e,null,[t]):de(e,t):de(e,null,t):(r>3?n=Array.prototype.slice.call(arguments,2):r===3&&Yt(n)&&(n=[n]),de(e,t,n))}const Du=Symbol.for("v-scx"),Bu=()=>He(Du),Ql="3.3.10",Uu="http://www.w3.org/2000/svg",At=typeof document<"u"?document:null,Vo=At&&At.createElement("template"),Ku={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const s=t?At.createElementNS(Uu,e):At.createElement(e,n?{is:n}:void 0);return e==="select"&&r&&r.multiple!=null&&s.setAttribute("multiple",r.multiple),s},createText:e=>At.createTextNode(e),createComment:e=>At.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>At.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,s,o){const i=n?n.previousSibling:t.lastChild;if(s&&(s===o||s.nextSibling))for(;t.insertBefore(s.cloneNode(!0),n),!(s===o||!(s=s.nextSibling)););else{Vo.innerHTML=r?`${e}`:e;const l=Vo.content;if(r){const a=l.firstChild;for(;a.firstChild;)l.appendChild(a.firstChild);l.removeChild(a)}t.insertBefore(l,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},ft="transition",un="animation",On=Symbol("_vtc"),io=(e,{slots:t})=>Ve(Zc,Vu(e),t);io.displayName="Transition";const Jl={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};io.props=_e({},wl,Jl);const Rt=(e,t=[])=>{z(e)?e.forEach(n=>n(...t)):e&&e(...t)},Wo=e=>e?z(e)?e.some(t=>t.length>1):e.length>1:!1;function Vu(e){const t={};for(const L in e)L in Jl||(t[L]=e[L]);if(e.css===!1)return t;const{name:n="v",type:r,duration:s,enterFromClass:o=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:a=o,appearActiveClass:u=i,appearToClass:c=l,leaveFromClass:f=`${n}-leave-from`,leaveActiveClass:d=`${n}-leave-active`,leaveToClass:m=`${n}-leave-to`}=e,v=Wu(s),R=v&&v[0],k=v&&v[1],{onBeforeEnter:w,onEnter:b,onEnterCancelled:y,onLeave:g,onLeaveCancelled:C,onBeforeAppear:I=w,onAppear:N=b,onAppearCancelled:O=y}=t,D=(L,J,ae)=>{Ct(L,J?c:l),Ct(L,J?u:i),ae&&ae()},M=(L,J)=>{L._isLeaving=!1,Ct(L,f),Ct(L,m),Ct(L,d),J&&J()},Q=L=>(J,ae)=>{const le=L?N:b,U=()=>D(J,L,ae);Rt(le,[J,U]),qo(()=>{Ct(J,L?a:o),dt(J,L?c:l),Wo(le)||zo(J,r,R,U)})};return _e(t,{onBeforeEnter(L){Rt(w,[L]),dt(L,o),dt(L,i)},onBeforeAppear(L){Rt(I,[L]),dt(L,a),dt(L,u)},onEnter:Q(!1),onAppear:Q(!0),onLeave(L,J){L._isLeaving=!0;const ae=()=>M(L,J);dt(L,f),Qu(),dt(L,d),qo(()=>{L._isLeaving&&(Ct(L,f),dt(L,m),Wo(g)||zo(L,r,k,ae))}),Rt(g,[L,ae])},onEnterCancelled(L){D(L,!1),Rt(y,[L])},onAppearCancelled(L){D(L,!0),Rt(O,[L])},onLeaveCancelled(L){M(L),Rt(C,[L])}})}function Wu(e){if(e==null)return null;if(ue(e))return[Vr(e.enter),Vr(e.leave)];{const t=Vr(e);return[t,t]}}function Vr(e){return qi(e)}function dt(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[On]||(e[On]=new Set)).add(t)}function Ct(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const n=e[On];n&&(n.delete(t),n.size||(e[On]=void 0))}function qo(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let qu=0;function zo(e,t,n,r){const s=e._endId=++qu,o=()=>{s===e._endId&&r()};if(n)return setTimeout(o,n);const{type:i,timeout:l,propCount:a}=zu(e,t);if(!i)return r();const u=i+"end";let c=0;const f=()=>{e.removeEventListener(u,d),o()},d=m=>{m.target===e&&++c>=a&&f()};setTimeout(()=>{c(n[v]||"").split(", "),s=r(`${ft}Delay`),o=r(`${ft}Duration`),i=Qo(s,o),l=r(`${un}Delay`),a=r(`${un}Duration`),u=Qo(l,a);let c=null,f=0,d=0;t===ft?i>0&&(c=ft,f=i,d=o.length):t===un?u>0&&(c=un,f=u,d=a.length):(f=Math.max(i,u),c=f>0?i>u?ft:un:null,d=c?c===ft?o.length:a.length:0);const m=c===ft&&/\b(transform|all)(,|$)/.test(r(`${ft}Property`).toString());return{type:c,timeout:f,propCount:d,hasTransform:m}}function Qo(e,t){for(;e.lengthJo(n)+Jo(e[r])))}function Jo(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function Qu(){return document.body.offsetHeight}function Ju(e,t,n){const r=e[On];r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Xu=Symbol("_vod");function Yu(e,t,n){const r=e.style,s=pe(n);if(n&&!s){if(t&&!pe(t))for(const o in t)n[o]==null&&gs(r,o,"");for(const o in n)gs(r,o,n[o])}else{const o=r.display;s?t!==n&&(r.cssText=n):t&&e.removeAttribute("style"),Xu in e&&(r.display=o)}}const Xo=/\s*!important$/;function gs(e,t,n){if(z(n))n.forEach(r=>gs(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=Gu(e,t);Xo.test(n)?e.setProperty(nn(r),n.replace(Xo,""),"important"):e[r]=n}}const Yo=["Webkit","Moz","ms"],Wr={};function Gu(e,t){const n=Wr[t];if(n)return n;let r=et(t);if(r!=="filter"&&r in e)return Wr[t]=r;r=_r(r);for(let s=0;sqr||(of.then(()=>qr=0),qr=Date.now());function af(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;je(cf(r,n.value),t,5,[r])};return n.value=e,n.attached=lf(),n}function cf(e,t){if(z(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>s=>!s._stopped&&r&&r(s))}else return t}const ti=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,uf=(e,t,n,r,s=!1,o,i,l,a)=>{t==="class"?Ju(e,r,s):t==="style"?Yu(e,n,r):Hn(t)?Ms(t)||rf(e,t,n,r,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):ff(e,t,r,s))?ef(e,t,r,o,i,l,a):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Zu(e,t,r,s))};function ff(e,t,n,r){if(r)return!!(t==="innerHTML"||t==="textContent"||t in e&&ti(t)&&X(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const s=e.tagName;return!(s==="IMG"||s==="VIDEO"||s==="CANVAS"||s==="SOURCE")}return ti(t)&&pe(n)?!1:t in e}const Xl=_e({patchProp:uf},Ku);let bn,ni=!1;function df(){return bn||(bn=Pu(Xl))}function hf(){return bn=ni?bn:Tu(Xl),ni=!0,bn}const pf=(...e)=>{const t=df().createApp(...e),{mount:n}=t;return t.mount=r=>{const s=Yl(r);if(!s)return;const o=t._component;!X(o)&&!o.render&&!o.template&&(o.template=s.innerHTML),s.innerHTML="";const i=n(s,!1,s instanceof SVGElement);return s instanceof Element&&(s.removeAttribute("v-cloak"),s.setAttribute("data-v-app","")),i},t},gf=(...e)=>{const t=hf().createApp(...e),{mount:n}=t;return t.mount=r=>{const s=Yl(r);if(s)return n(s,!0,s instanceof SVGElement)},t};function Yl(e){return pe(e)?document.querySelector(e):e}const mf=/#/g,yf=/&/g,_f=/\//g,vf=/=/g,lo=/\+/g,bf=/%5e/gi,Ef=/%60/gi,wf=/%7c/gi,Rf=/%20/gi;function Cf(e){return encodeURI(""+e).replace(wf,"|")}function ms(e){return Cf(typeof e=="string"?e:JSON.stringify(e)).replace(lo,"%2B").replace(Rf,"+").replace(mf,"%23").replace(yf,"%26").replace(Ef,"`").replace(bf,"^").replace(_f,"%2F")}function zr(e){return ms(e).replace(vf,"%3D")}function fr(e=""){try{return decodeURIComponent(""+e)}catch{return""+e}}function Pf(e){return fr(e.replace(lo," "))}function Tf(e){return fr(e.replace(lo," "))}function Gl(e=""){const t={};e[0]==="?"&&(e=e.slice(1));for(const n of e.split("&")){const r=n.match(/([^=]+)=?(.*)/)||[];if(r.length<2)continue;const s=Pf(r[1]);if(s==="__proto__"||s==="constructor")continue;const o=Tf(r[2]||"");t[s]===void 0?t[s]=o:Array.isArray(t[s])?t[s].push(o):t[s]=[t[s],o]}return t}function Af(e,t){return(typeof t=="number"||typeof t=="boolean")&&(t=String(t)),t?Array.isArray(t)?t.map(n=>`${zr(e)}=${ms(n)}`).join("&"):`${zr(e)}=${ms(t)}`:zr(e)}function xf(e){return Object.keys(e).filter(t=>e[t]!==void 0).map(t=>Af(t,e[t])).filter(Boolean).join("&")}const kf=/^[\s\w\0+.-]{2,}:([/\\]{1,2})/,Of=/^[\s\w\0+.-]{2,}:([/\\]{2})?/,Sf=/^([/\\]\s*){2,}[^/\\]/,Lf=/^[\s\0]*(blob|data|javascript|vbscript):$/i,If=/\/$|\/\?|\/#/,Hf=/^\.?\//;function It(e,t={}){return typeof t=="boolean"&&(t={acceptRelative:t}),t.strict?kf.test(e):Of.test(e)||(t.acceptRelative?Sf.test(e):!1)}function $f(e){return!!e&&Lf.test(e)}function ys(e="",t){return t?If.test(e):e.endsWith("/")}function Or(e="",t){if(!t)return(ys(e)?e.slice(0,-1):e)||"/";if(!ys(e,!0))return e||"/";let n=e,r="";const s=e.indexOf("#");s>=0&&(n=e.slice(0,s),r=e.slice(s));const[o,...i]=n.split("?");return(o.slice(0,-1)||"/")+(i.length>0?`?${i.join("?")}`:"")+r}function dr(e="",t){if(!t)return e.endsWith("/")?e:e+"/";if(ys(e,!0))return e||"/";let n=e,r="";const s=e.indexOf("#");if(s>=0&&(n=e.slice(0,s),r=e.slice(s),!n))return r;const[o,...i]=n.split("?");return o+"/"+(i.length>0?`?${i.join("?")}`:"")+r}function Nf(e=""){return e.startsWith("/")}function ri(e=""){return Nf(e)?e:"/"+e}function cy(e,t){if(Zl(t)||It(e))return e;const n=Or(t);return e.startsWith(n)?e:an(n,e)}function si(e,t){if(Zl(t))return e;const n=Or(t);if(!e.startsWith(n))return e;const r=e.slice(n.length);return r[0]==="/"?r:"/"+r}function Mf(e,t){const n=Fn(e),r={...Gl(n.search),...t};return n.search=xf(r),Df(n)}function Zl(e){return!e||e==="/"}function jf(e){return e&&e!=="/"}function an(e,...t){let n=e||"";for(const r of t.filter(s=>jf(s)))if(n){const s=r.replace(Hf,"");n=dr(n)+s}else n=r;return n}function Ff(e,t,n={}){return n.trailingSlash||(e=dr(e),t=dr(t)),n.leadingSlash||(e=ri(e),t=ri(t)),n.encoding||(e=fr(e),t=fr(t)),e===t}const ea=Symbol.for("ufo:protocolRelative");function Fn(e="",t){const n=e.match(/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i);if(n){const[,f,d=""]=n;return{protocol:f.toLowerCase(),pathname:d,href:f+d,auth:"",host:"",search:"",hash:""}}if(!It(e,{acceptRelative:!0}))return t?Fn(t+e):oi(e);const[,r="",s,o=""]=e.replace(/\\/g,"/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/)||[],[,i="",l=""]=o.match(/([^#/?]*)(.*)?/)||[],{pathname:a,search:u,hash:c}=oi(l.replace(/\/(?=[A-Za-z]:)/,""));return{protocol:r.toLowerCase(),auth:s?s.slice(0,Math.max(0,s.length-1)):"",host:i,pathname:a,search:u,hash:c,[ea]:!r}}function oi(e=""){const[t="",n="",r=""]=(e.match(/([^#?]*)(\?[^#]*)?(#.*)?/)||[]).splice(1);return{pathname:t,search:n,hash:r}}function Df(e){const t=e.pathname||"",n=e.search?(e.search.startsWith("?")?"":"?")+e.search:"",r=e.hash||"",s=e.auth?e.auth+"@":"",o=e.host||"";return(e.protocol||e[ea]?(e.protocol||"")+"//":"")+s+o+t+n+r}const Bf=()=>{var e;return((e=window==null?void 0:window.__NUXT__)==null?void 0:e.config)||{}},hr=Bf().app,Uf=()=>hr.baseURL,Kf=()=>hr.buildAssetsDir,ao=(...e)=>an(ta(),Kf(),...e),ta=(...e)=>{const t=hr.cdnURL||hr.baseURL;return e.length?an(t,...e):t};globalThis.__buildAssetsURL=ao,globalThis.__publicAssetsURL=ta;const Vf=/"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,Wf=/"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,qf=/^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;function zf(e,t){if(e==="__proto__"||e==="constructor"&&t&&typeof t=="object"&&"prototype"in t){Qf(e);return}return t}function Qf(e){console.warn(`[destr] Dropping "${e}" key to prevent prototype pollution.`)}function Jf(e,t={}){if(typeof e!="string")return e;const n=e.trim();if(e[0]==='"'&&e.at(-1)==='"'&&!e.includes("\\"))return n.slice(1,-1);if(n.length<=9){const r=n.toLowerCase();if(r==="true")return!0;if(r==="false")return!1;if(r==="undefined")return;if(r==="null")return null;if(r==="nan")return Number.NaN;if(r==="infinity")return Number.POSITIVE_INFINITY;if(r==="-infinity")return Number.NEGATIVE_INFINITY}if(!qf.test(e)){if(t.strict)throw new SyntaxError("[destr] Invalid JSON");return e}try{if(Vf.test(e)||Wf.test(e)){if(t.strict)throw new Error("[destr] Possible prototype pollution");return JSON.parse(e,zf)}return JSON.parse(e)}catch(r){if(t.strict)throw r;return e}}const Xf=/#/g,Yf=/&/g,Gf=/=/g,co=/\+/g,Zf=/%5e/gi,ed=/%60/gi,td=/%7c/gi,nd=/%20/gi;function rd(e){return encodeURI(""+e).replace(td,"|")}function _s(e){return rd(typeof e=="string"?e:JSON.stringify(e)).replace(co,"%2B").replace(nd,"+").replace(Xf,"%23").replace(Yf,"%26").replace(ed,"`").replace(Zf,"^")}function Qr(e){return _s(e).replace(Gf,"%3D")}function na(e=""){try{return decodeURIComponent(""+e)}catch{return""+e}}function sd(e){return na(e.replace(co," "))}function od(e){return na(e.replace(co," "))}function id(e=""){const t={};e[0]==="?"&&(e=e.slice(1));for(const n of e.split("&")){const r=n.match(/([^=]+)=?(.*)/)||[];if(r.length<2)continue;const s=sd(r[1]);if(s==="__proto__"||s==="constructor")continue;const o=od(r[2]||"");t[s]===void 0?t[s]=o:Array.isArray(t[s])?t[s].push(o):t[s]=[t[s],o]}return t}function ld(e,t){return(typeof t=="number"||typeof t=="boolean")&&(t=String(t)),t?Array.isArray(t)?t.map(n=>`${Qr(e)}=${_s(n)}`).join("&"):`${Qr(e)}=${_s(t)}`:Qr(e)}function ad(e){return Object.keys(e).filter(t=>e[t]!==void 0).map(t=>ld(t,e[t])).filter(Boolean).join("&")}const cd=/^[\s\w\0+.-]{2,}:([/\\]{1,2})/,ud=/^[\s\w\0+.-]{2,}:([/\\]{2})?/,fd=/^([/\\]\s*){2,}[^/\\]/;function ra(e,t={}){return typeof t=="boolean"&&(t={acceptRelative:t}),t.strict?cd.test(e):ud.test(e)||(t.acceptRelative?fd.test(e):!1)}const dd=/\/$|\/\?|\/#/;function vs(e="",t){return t?dd.test(e):e.endsWith("/")}function hd(e="",t){if(!t)return(vs(e)?e.slice(0,-1):e)||"/";if(!vs(e,!0))return e||"/";let n=e,r="";const s=e.indexOf("#");s>=0&&(n=e.slice(0,s),r=e.slice(s));const[o,...i]=n.split("?");return(o.slice(0,-1)||"/")+(i.length>0?`?${i.join("?")}`:"")+r}function pd(e="",t){if(!t)return e.endsWith("/")?e:e+"/";if(vs(e,!0))return e||"/";let n=e,r="";const s=e.indexOf("#");if(s>=0&&(n=e.slice(0,s),r=e.slice(s),!n))return r;const[o,...i]=n.split("?");return o+"/"+(i.length>0?`?${i.join("?")}`:"")+r}function gd(e,t){if(yd(t)||ra(e))return e;const n=hd(t);return e.startsWith(n)?e:bd(n,e)}function md(e,t){const n=sa(e),r={...id(n.search),...t};return n.search=ad(r),Ed(n)}function yd(e){return!e||e==="/"}function _d(e){return e&&e!=="/"}const vd=/^\.?\//;function bd(e,...t){let n=e||"";for(const r of t.filter(s=>_d(s)))if(n){const s=r.replace(vd,"");n=pd(n)+s}else n=r;return n}function sa(e="",t){const n=e.match(/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i);if(n){const[,f,d=""]=n;return{protocol:f.toLowerCase(),pathname:d,href:f+d,auth:"",host:"",search:"",hash:""}}if(!ra(e,{acceptRelative:!0}))return t?sa(t+e):ii(e);const[,r="",s,o=""]=e.replace(/\\/g,"/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/)||[],[,i="",l=""]=o.match(/([^#/?]*)(.*)?/)||[],{pathname:a,search:u,hash:c}=ii(l.replace(/\/(?=[A-Za-z]:)/,""));return{protocol:r.toLowerCase(),auth:s?s.slice(0,Math.max(0,s.length-1)):"",host:i,pathname:a,search:u,hash:c}}function ii(e=""){const[t="",n="",r=""]=(e.match(/([^#?]*)(\?[^#]*)?(#.*)?/)||[]).splice(1);return{pathname:t,search:n,hash:r}}function Ed(e){const t=e.pathname||"",n=e.search?(e.search.startsWith("?")?"":"?")+e.search:"",r=e.hash||"",s=e.auth?e.auth+"@":"",o=e.host||"";return(e.protocol?e.protocol+"//":"")+s+o+t+n+r}class wd extends Error{constructor(t,n){super(t,n),this.name="FetchError",n!=null&&n.cause&&!this.cause&&(this.cause=n.cause)}}function Rd(e){var a,u,c,f,d;const t=((a=e.error)==null?void 0:a.message)||((u=e.error)==null?void 0:u.toString())||"",n=((c=e.request)==null?void 0:c.method)||((f=e.options)==null?void 0:f.method)||"GET",r=((d=e.request)==null?void 0:d.url)||String(e.request)||"/",s=`[${n}] ${JSON.stringify(r)}`,o=e.response?`${e.response.status} ${e.response.statusText}`:"",i=`${s}: ${o}${t?` ${t}`:""}`,l=new wd(i,e.error?{cause:e.error}:void 0);for(const m of["request","options","response"])Object.defineProperty(l,m,{get(){return e[m]}});for(const[m,v]of[["data","_data"],["status","status"],["statusCode","status"],["statusText","statusText"],["statusMessage","statusText"]])Object.defineProperty(l,m,{get(){return e.response&&e.response[v]}});return l}const Cd=new Set(Object.freeze(["PATCH","POST","PUT","DELETE"]));function li(e="GET"){return Cd.has(e.toUpperCase())}function Pd(e){if(e===void 0)return!1;const t=typeof e;return t==="string"||t==="number"||t==="boolean"||t===null?!0:t!=="object"?!1:Array.isArray(e)?!0:e.buffer?!1:e.constructor&&e.constructor.name==="Object"||typeof e.toJSON=="function"}const Td=new Set(["image/svg","application/xml","application/xhtml","application/html"]),Ad=/^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;function xd(e=""){if(!e)return"json";const t=e.split(";").shift()||"";return Ad.test(t)?"json":Td.has(t)||t.startsWith("text/")?"text":"blob"}function kd(e,t,n=globalThis.Headers){const r={...t,...e};if(t!=null&&t.params&&(e!=null&&e.params)&&(r.params={...t==null?void 0:t.params,...e==null?void 0:e.params}),t!=null&&t.query&&(e!=null&&e.query)&&(r.query={...t==null?void 0:t.query,...e==null?void 0:e.query}),t!=null&&t.headers&&(e!=null&&e.headers)){r.headers=new n((t==null?void 0:t.headers)||{});for(const[s,o]of new n((e==null?void 0:e.headers)||{}))r.headers.set(s,o)}return r}const Od=new Set([408,409,425,429,500,502,503,504]),Sd=new Set([101,204,205,304]);function oa(e={}){const{fetch:t=globalThis.fetch,Headers:n=globalThis.Headers,AbortController:r=globalThis.AbortController}=e;async function s(l){const a=l.error&&l.error.name==="AbortError"&&!l.options.timeout||!1;if(l.options.retry!==!1&&!a){let c;typeof l.options.retry=="number"?c=l.options.retry:c=li(l.options.method)?0:1;const f=l.response&&l.response.status||500;if(c>0&&(Array.isArray(l.options.retryStatusCodes)?l.options.retryStatusCodes.includes(f):Od.has(f))){const d=l.options.retryDelay||0;return d>0&&await new Promise(m=>setTimeout(m,d)),o(l.request,{...l.options,retry:c-1,timeout:l.options.timeout})}}const u=Rd(l);throw Error.captureStackTrace&&Error.captureStackTrace(u,o),u}const o=async function(a,u={}){var d;const c={request:a,options:kd(u,e.defaults,n),response:void 0,error:void 0};if(c.options.method=(d=c.options.method)==null?void 0:d.toUpperCase(),c.options.onRequest&&await c.options.onRequest(c),typeof c.request=="string"&&(c.options.baseURL&&(c.request=gd(c.request,c.options.baseURL)),(c.options.query||c.options.params)&&(c.request=md(c.request,{...c.options.params,...c.options.query}))),c.options.body&&li(c.options.method)&&(Pd(c.options.body)?(c.options.body=typeof c.options.body=="string"?c.options.body:JSON.stringify(c.options.body),c.options.headers=new n(c.options.headers||{}),c.options.headers.has("content-type")||c.options.headers.set("content-type","application/json"),c.options.headers.has("accept")||c.options.headers.set("accept","application/json")):("pipeTo"in c.options.body&&typeof c.options.body.pipeTo=="function"||typeof c.options.body.pipe=="function")&&("duplex"in c.options||(c.options.duplex="half"))),!c.options.signal&&c.options.timeout){const m=new r;setTimeout(()=>m.abort(),c.options.timeout),c.options.signal=m.signal}try{c.response=await t(c.request,c.options)}catch(m){return c.error=m,c.options.onRequestError&&await c.options.onRequestError(c),await s(c)}if(c.response.body&&!Sd.has(c.response.status)&&c.options.method!=="HEAD"){const m=(c.options.parseResponse?"json":c.options.responseType)||xd(c.response.headers.get("content-type")||"");switch(m){case"json":{const v=await c.response.text(),R=c.options.parseResponse||Jf;c.response._data=R(v);break}case"stream":{c.response._data=c.response.body;break}default:c.response._data=await c.response[m]()}}return c.options.onResponse&&await c.options.onResponse(c),!c.options.ignoreResponseError&&c.response.status>=400&&c.response.status<600?(c.options.onResponseError&&await c.options.onResponseError(c),await s(c)):c.response},i=async function(a,u){return(await o(a,u))._data};return i.raw=o,i.native=(...l)=>t(...l),i.create=(l={})=>oa({...e,defaults:{...e.defaults,...l}}),i}const uo=function(){if(typeof globalThis<"u")return globalThis;if(typeof self<"u")return self;if(typeof window<"u")return window;if(typeof global<"u")return global;throw new Error("unable to locate global object")}(),Ld=uo.fetch||(()=>Promise.reject(new Error("[ofetch] global.fetch is not supported!"))),Id=uo.Headers,Hd=uo.AbortController,$d=oa({fetch:Ld,Headers:Id,AbortController:Hd}),Nd=$d;globalThis.$fetch||(globalThis.$fetch=Nd.create({baseURL:Uf()}));function bs(e,t={},n){for(const r in e){const s=e[r],o=n?`${n}:${r}`:r;typeof s=="object"&&s!==null?bs(s,t,o):typeof s=="function"&&(t[o]=s)}return t}const Md={run:e=>e()},jd=()=>Md,ia=typeof console.createTask<"u"?console.createTask:jd;function Fd(e,t){const n=t.shift(),r=ia(n);return e.reduce((s,o)=>s.then(()=>r.run(()=>o(...t))),Promise.resolve())}function Dd(e,t){const n=t.shift(),r=ia(n);return Promise.all(e.map(s=>r.run(()=>s(...t))))}function Jr(e,t){for(const n of[...e])n(t)}class Bd{constructor(){this._hooks={},this._before=void 0,this._after=void 0,this._deprecatedMessages=void 0,this._deprecatedHooks={},this.hook=this.hook.bind(this),this.callHook=this.callHook.bind(this),this.callHookWith=this.callHookWith.bind(this)}hook(t,n,r={}){if(!t||typeof n!="function")return()=>{};const s=t;let o;for(;this._deprecatedHooks[t];)o=this._deprecatedHooks[t],t=o.to;if(o&&!r.allowDeprecated){let i=o.message;i||(i=`${s} hook has been deprecated`+(o.to?`, please use ${o.to}`:"")),this._deprecatedMessages||(this._deprecatedMessages=new Set),this._deprecatedMessages.has(i)||(console.warn(i),this._deprecatedMessages.add(i))}if(!n.name)try{Object.defineProperty(n,"name",{get:()=>"_"+t.replace(/\W+/g,"_")+"_hook_cb",configurable:!0})}catch{}return this._hooks[t]=this._hooks[t]||[],this._hooks[t].push(n),()=>{n&&(this.removeHook(t,n),n=void 0)}}hookOnce(t,n){let r,s=(...o)=>(typeof r=="function"&&r(),r=void 0,s=void 0,n(...o));return r=this.hook(t,s),r}removeHook(t,n){if(this._hooks[t]){const r=this._hooks[t].indexOf(n);r!==-1&&this._hooks[t].splice(r,1),this._hooks[t].length===0&&delete this._hooks[t]}}deprecateHook(t,n){this._deprecatedHooks[t]=typeof n=="string"?{to:n}:n;const r=this._hooks[t]||[];delete this._hooks[t];for(const s of r)this.hook(t,s)}deprecateHooks(t){Object.assign(this._deprecatedHooks,t);for(const n in t)this.deprecateHook(n,t[n])}addHooks(t){const n=bs(t),r=Object.keys(n).map(s=>this.hook(s,n[s]));return()=>{for(const s of r.splice(0,r.length))s()}}removeHooks(t){const n=bs(t);for(const r in n)this.removeHook(r,n[r])}removeAllHooks(){for(const t in this._hooks)delete this._hooks[t]}callHook(t,...n){return n.unshift(t),this.callHookWith(Fd,t,...n)}callHookParallel(t,...n){return n.unshift(t),this.callHookWith(Dd,t,...n)}callHookWith(t,n,...r){const s=this._before||this._after?{name:n,args:r,context:{}}:void 0;this._before&&Jr(this._before,s);const o=t(n in this._hooks?[...this._hooks[n]]:[],r);return o instanceof Promise?o.finally(()=>{this._after&&s&&Jr(this._after,s)}):(this._after&&s&&Jr(this._after,s),o)}beforeEach(t){return this._before=this._before||[],this._before.push(t),()=>{if(this._before!==void 0){const n=this._before.indexOf(t);n!==-1&&this._before.splice(n,1)}}}afterEach(t){return this._after=this._after||[],this._after.push(t),()=>{if(this._after!==void 0){const n=this._after.indexOf(t);n!==-1&&this._after.splice(n,1)}}}}function la(){return new Bd}function Ud(e={}){let t,n=!1;const r=i=>{if(t&&t!==i)throw new Error("Context conflict")};let s;if(e.asyncContext){const i=e.AsyncLocalStorage||globalThis.AsyncLocalStorage;i?s=new i:console.warn("[unctx] `AsyncLocalStorage` is not provided.")}const o=()=>{if(s&&t===void 0){const i=s.getStore();if(i!==void 0)return i}return t};return{use:()=>{const i=o();if(i===void 0)throw new Error("Context is not available");return i},tryUse:()=>o(),set:(i,l)=>{l||r(i),t=i,n=!0},unset:()=>{t=void 0,n=!1},call:(i,l)=>{r(i),t=i;try{return s?s.run(i,l):l()}finally{n||(t=void 0)}},async callAsync(i,l){t=i;const a=()=>{t=i},u=()=>t===i?a:void 0;Es.add(u);try{const c=s?s.run(i,l):l();return n||(t=void 0),await c}finally{Es.delete(u)}}}}function Kd(e={}){const t={};return{get(n,r={}){return t[n]||(t[n]=Ud({...e,...r})),t[n],t[n]}}}const pr=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof global<"u"?global:typeof window<"u"?window:{},ai="__unctx__",Vd=pr[ai]||(pr[ai]=Kd()),Wd=(e,t={})=>Vd.get(e,t),ci="__unctx_async_handlers__",Es=pr[ci]||(pr[ci]=new Set);function Sn(e){const t=[];for(const s of Es){const o=s();o&&t.push(o)}const n=()=>{for(const s of t)s()};let r=e();return r&&typeof r=="object"&&"catch"in r&&(r=r.catch(s=>{throw n(),s})),[r,n]}const aa=Wd("nuxt-app",{asyncContext:!1}),qd="__nuxt_plugin";function zd(e){let t=0;const n={_scope:tc(),provide:void 0,globalName:"nuxt",versions:{get nuxt(){return"3.10.3"},get vue(){return n.vueApp.version}},payload:ot({data:{},state:{},once:new Set,_errors:{},...window.__NUXT__??{}}),static:{data:{}},runWithContext:s=>n._scope.run(()=>Xd(n,s)),isHydrating:!0,deferHydration(){if(!n.isHydrating)return()=>{};t++;let s=!1;return()=>{if(!s&&(s=!0,t--,t===0))return n.isHydrating=!1,n.callHook("app:suspense:resolve")}},_asyncDataPromises:{},_asyncData:{},_payloadRevivers:{},...e};n.hooks=la(),n.hook=n.hooks.hook,n.callHook=n.hooks.callHook,n.provide=(s,o)=>{const i="$"+s;Xn(n,i,o),Xn(n.vueApp.config.globalProperties,i,o)},Xn(n.vueApp,"$nuxt",n),Xn(n.vueApp.config.globalProperties,"$nuxt",n);{window.addEventListener("nuxt.preloadError",o=>{n.callHook("app:chunkError",{error:o.payload})}),window.useNuxtApp=window.useNuxtApp||ge;const s=n.hook("app:error",(...o)=>{console.error("[nuxt] error caught during app initialization",...o)});n.hook("app:mounted",s)}const r=ot(n.payload.config);return n.provide("config",r),n}async function Qd(e,t){if(t.hooks&&e.hooks.addHooks(t.hooks),typeof t=="function"){const{provide:n}=await e.runWithContext(()=>t(e))||{};if(n&&typeof n=="object")for(const r in n)e.provide(r,n[r])}}async function Jd(e,t){const n=[],r=[],s=[],o=[];let i=0;async function l(a){var c;const u=((c=a.dependsOn)==null?void 0:c.filter(f=>t.some(d=>d._name===f)&&!n.includes(f)))??[];if(u.length>0)r.push([new Set(u),a]);else{const f=Qd(e,a).then(async()=>{a._name&&(n.push(a._name),await Promise.all(r.map(async([d,m])=>{d.has(a._name)&&(d.delete(a._name),d.size===0&&(i++,await l(m)))})))});a.parallel?s.push(f.catch(d=>o.push(d))):await f}}for(const a of t)await l(a);if(await Promise.all(s),i)for(let a=0;a{}),e,{[qd]:!0,_name:t})}function Xd(e,t,n){const r=()=>n?t(...n):t();return aa.set(e),e.vueApp.runWithContext(r)}function Yd(){var t;let e;return Ll()&&(e=(t=kr())==null?void 0:t.appContext.app.$nuxt),e=e||aa.tryUse(),e||null}function ge(){const e=Yd();if(!e)throw new Error("[nuxt] instance unavailable");return e}function Sr(e){return ge().$config}function Xn(e,t,n){Object.defineProperty(e,t,{get:()=>n})}function Gd(e){return{ctx:{table:e},matchAll:t=>ua(t,e)}}function ca(e){const t={};for(const n in e)t[n]=n==="dynamic"?new Map(Object.entries(e[n]).map(([r,s])=>[r,ca(s)])):new Map(Object.entries(e[n]));return t}function Zd(e){return Gd(ca(e))}function ua(e,t){const n=[];for(const[s,o]of ui(t.wildcard))e.startsWith(s)&&n.push(o);for(const[s,o]of ui(t.dynamic))if(e.startsWith(s+"/")){const i="/"+e.slice(s.length).split("/").splice(2).join("/");n.push(...ua(i,o))}const r=t.static.get(e);return r&&n.push(r),n.filter(Boolean)}function ui(e){return[...e.entries()].sort((t,n)=>t[0].length-n[0].length)}const eh=/"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,th=/"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,nh=/^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;function rh(e,t){if(e==="__proto__"||e==="constructor"&&t&&typeof t=="object"&&"prototype"in t){sh(e);return}return t}function sh(e){console.warn(`[destr] Dropping "${e}" key to prevent prototype pollution.`)}function ws(e,t={}){if(typeof e!="string")return e;const n=e.trim();if(e[0]==='"'&&e.endsWith('"')&&!e.includes("\\"))return n.slice(1,-1);if(n.length<=9){const r=n.toLowerCase();if(r==="true")return!0;if(r==="false")return!1;if(r==="undefined")return;if(r==="null")return null;if(r==="nan")return Number.NaN;if(r==="infinity")return Number.POSITIVE_INFINITY;if(r==="-infinity")return Number.NEGATIVE_INFINITY}if(!nh.test(e)){if(t.strict)throw new SyntaxError("[destr] Invalid JSON");return e}try{if(eh.test(e)||th.test(e)){if(t.strict)throw new Error("[destr] Possible prototype pollution");return JSON.parse(e,rh)}return JSON.parse(e)}catch(r){if(t.strict)throw r;return e}}function Xr(e){if(e===null||typeof e!="object")return!1;const t=Object.getPrototypeOf(e);return t!==null&&t!==Object.prototype&&Object.getPrototypeOf(t)!==null||Symbol.iterator in e?!1:Symbol.toStringTag in e?Object.prototype.toString.call(e)==="[object Module]":!0}function Rs(e,t,n=".",r){if(!Xr(t))return Rs(e,{},n,r);const s=Object.assign({},t);for(const o in e){if(o==="__proto__"||o==="constructor")continue;const i=e[o];i!=null&&(r&&r(s,o,i,n)||(Array.isArray(i)&&Array.isArray(s[o])?s[o]=[...i,...s[o]]:Xr(i)&&Xr(s[o])?s[o]=Rs(i,s[o],(n?`${n}.`:"")+o.toString(),r):s[o]=i))}return s}function fa(e){return(...t)=>t.reduce((n,r)=>Rs(n,r,"",e),{})}const da=fa(),oh=fa((e,t,n)=>{if(e[t]!==void 0&&typeof n=="function")return e[t]=n(e[t]),!0});function ih(e,t){try{return t in e}catch{return!1}}var lh=Object.defineProperty,ah=(e,t,n)=>t in e?lh(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Pt=(e,t,n)=>(ah(e,typeof t!="symbol"?t+"":t,n),n);class Cs extends Error{constructor(t,n={}){super(t,n),Pt(this,"statusCode",500),Pt(this,"fatal",!1),Pt(this,"unhandled",!1),Pt(this,"statusMessage"),Pt(this,"data"),Pt(this,"cause"),n.cause&&!this.cause&&(this.cause=n.cause)}toJSON(){const t={message:this.message,statusCode:Ts(this.statusCode,500)};return this.statusMessage&&(t.statusMessage=ha(this.statusMessage)),this.data!==void 0&&(t.data=this.data),t}}Pt(Cs,"__h3_error__",!0);function Ps(e){if(typeof e=="string")return new Cs(e);if(ch(e))return e;const t=new Cs(e.message??e.statusMessage??"",{cause:e.cause||e});if(ih(e,"stack"))try{Object.defineProperty(t,"stack",{get(){return e.stack}})}catch{try{t.stack=e.stack}catch{}}if(e.data&&(t.data=e.data),e.statusCode?t.statusCode=Ts(e.statusCode,t.statusCode):e.status&&(t.statusCode=Ts(e.status,t.statusCode)),e.statusMessage?t.statusMessage=e.statusMessage:e.statusText&&(t.statusMessage=e.statusText),t.statusMessage){const n=t.statusMessage;ha(t.statusMessage)!==n&&console.warn("[h3] Please prefer using `message` for longer error messages instead of `statusMessage`. In the future, `statusMessage` will be sanitized by default.")}return e.fatal!==void 0&&(t.fatal=e.fatal),e.unhandled!==void 0&&(t.unhandled=e.unhandled),t}function ch(e){var t;return((t=e==null?void 0:e.constructor)==null?void 0:t.__h3_error__)===!0}const uh=/[^\u0009\u0020-\u007E]/g;function ha(e=""){return e.replace(uh,"")}function Ts(e,t=200){return!e||(typeof e=="string"&&(e=Number.parseInt(e,10)),e<100||e>999)?t:e}const fh=Symbol("layout-meta"),Lr=Symbol("route"),qe=()=>{var e;return(e=ge())==null?void 0:e.$router},pa=()=>Ll()?He(Lr,ge()._route):ge()._route;const dh=()=>{try{if(ge()._processingMiddleware)return!0}catch{return!0}return!1},hh=(e,t)=>{e||(e="/");const n=typeof e=="string"?e:Mf(e.path||"/",e.query||{})+(e.hash||"");if(t!=null&&t.open){{const{target:l="_blank",windowFeatures:a={}}=t.open,u=Object.entries(a).filter(([c,f])=>f!==void 0).map(([c,f])=>`${c.toLowerCase()}=${f}`).join(", ");open(n,l,u)}return Promise.resolve()}const r=(t==null?void 0:t.external)||It(n,{acceptRelative:!0});if(r){if(!(t!=null&&t.external))throw new Error("Navigating to an external URL is not allowed by default. Use `navigateTo(url, { external: true })`.");const l=Fn(n).protocol;if(l&&$f(l))throw new Error(`Cannot navigate to a URL with '${l}' protocol.`)}const s=dh();if(!r&&s)return e;const o=qe(),i=ge();return r?(i._scope.stop(),t!=null&&t.replace?location.replace(n):location.href=n,s?i.isHydrating?new Promise(()=>{}):!1:Promise.resolve()):t!=null&&t.replace?o.replace(e):o.push(e)},ga="__nuxt_error",Ir=()=>Oc(ge().payload,"error"),Dt=e=>{const t=Hr(e);try{const n=ge(),r=Ir();n.hooks.callHook("app:error",t),r.value=r.value||t}catch{throw t}return t},ph=async(e={})=>{const t=ge(),n=Ir();t.callHook("app:error:cleared",e),e.redirect&&await qe().replace(e.redirect),n.value=null},gh=e=>!!e&&typeof e=="object"&&ga in e,Hr=e=>{const t=Ps(e);return Object.defineProperty(t,ga,{value:!0,configurable:!1,writable:!1}),t},mh="modulepreload",yh=function(e,t){return e[0]==="."?new URL(e,t).href:e},fi={},_h=function(t,n,r){let s=Promise.resolve();if(n&&n.length>0){const o=document.getElementsByTagName("link");s=Promise.all(n.map(i=>{if(i=yh(i,r),i in fi)return;fi[i]=!0;const l=i.endsWith(".css"),a=l?'[rel="stylesheet"]':"";if(!!r)for(let f=o.length-1;f>=0;f--){const d=o[f];if(d.href===i&&(!l||d.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${i}"]${a}`))return;const c=document.createElement("link");if(c.rel=l?"stylesheet":mh,l||(c.as="script",c.crossOrigin=""),c.href=i,document.head.appendChild(c),l)return new Promise((f,d)=>{c.addEventListener("load",f),c.addEventListener("error",()=>d(new Error(`Unable to preload CSS for ${i}`)))})}))}return s.then(()=>t()).catch(o=>{const i=new Event("vite:preloadError",{cancelable:!0});if(i.payload=o,window.dispatchEvent(i),!i.defaultPrevented)throw o})},G=(...e)=>_h(...e).catch(t=>{const n=new Event("nuxt.preloadError");throw n.payload=t,window.dispatchEvent(n),t}),vh=-1,bh=-2,Eh=-3,wh=-4,Rh=-5,Ch=-6;function Ph(e,t){return Th(JSON.parse(e),t)}function Th(e,t){if(typeof e=="number")return s(e,!0);if(!Array.isArray(e)||e.length===0)throw new Error("Invalid input");const n=e,r=Array(n.length);function s(o,i=!1){if(o===vh)return;if(o===Eh)return NaN;if(o===wh)return 1/0;if(o===Rh)return-1/0;if(o===Ch)return-0;if(i)throw new Error("Invalid input");if(o in r)return r[o];const l=n[o];if(!l||typeof l!="object")r[o]=l;else if(Array.isArray(l))if(typeof l[0]=="string"){const a=l[0],u=t==null?void 0:t[a];if(u)return r[o]=u(s(l[1]));switch(a){case"Date":r[o]=new Date(l[1]);break;case"Set":const c=new Set;r[o]=c;for(let m=1;m>>9)+65536).toString(16).substring(1,8).toLowerCase()}function di(e){return e._h||fo(e._d?e._d:`${e.tag}:${e.textContent||e.innerHTML||""}:${Object.entries(e.props).map(([t,n])=>`${t}:${String(n)}`).join(",")}`)}function ya(e,t){const{props:n,tag:r}=e;if(Oh.includes(r))return r;if(r==="link"&&n.rel==="canonical")return"canonical";if(n.charset)return"charset";const s=["id"];r==="meta"&&s.push("name","property","http-equiv");for(const o of s)if(typeof n[o]<"u"){const i=String(n[o]);return t&&!t(i)?!1:`${r}:${o}:${i}`}return!1}function hi(e,t){return e==null?t||null:typeof e=="function"?e(t):e}async function Lh(e,t,n){const r={tag:e,props:await _a(typeof t=="object"&&typeof t!="function"&&!(t instanceof Promise)?{...t}:{[["script","noscript","style"].includes(e)?"innerHTML":"textContent"]:t},["templateParams","titleTemplate"].includes(e))};return ma.forEach(s=>{const o=typeof r.props[s]<"u"?r.props[s]:n[s];typeof o<"u"&&((!["innerHTML","textContent","children"].includes(s)||xh.includes(r.tag))&&(r[s==="children"?"innerHTML":s]=o),delete r.props[s])}),r.props.body&&(r.tagPosition="bodyClose",delete r.props.body),r.tag==="script"&&typeof r.innerHTML=="object"&&(r.innerHTML=JSON.stringify(r.innerHTML),r.props.type=r.props.type||"application/json"),Array.isArray(r.props.content)?r.props.content.map(s=>({...r,props:{...r.props,content:s}})):r}function Ih(e){return typeof e=="object"&&!Array.isArray(e)&&(e=Object.keys(e).filter(t=>e[t])),(Array.isArray(e)?e.join(" "):e).split(" ").filter(t=>t.trim()).filter(Boolean).join(" ")}async function _a(e,t){for(const n of Object.keys(e)){if(n==="class"){e[n]=Ih(e[n]);continue}if(e[n]instanceof Promise&&(e[n]=await e[n]),!t&&!ma.includes(n)){const r=String(e[n]),s=n.startsWith("data-");r==="true"||r===""?e[n]=s?"true":!0:e[n]||(s&&r==="false"?e[n]="false":delete e[n])}}return e}const Hh=10;async function $h(e){const t=[];return Object.entries(e.resolvedInput).filter(([n,r])=>typeof r<"u"&&kh.includes(n)).forEach(([n,r])=>{const s=Ah(r);t.push(...s.map(o=>Lh(n,o,e)).flat())}),(await Promise.all(t)).flat().filter(Boolean).map((n,r)=>(n._e=e._i,e.mode&&(n._m=e.mode),n._p=(e._i<a&&a[u]||void 0,t):l=t[i],typeof l<"u"?(l||"").replace(/"/g,'\\"'):!1}let s=e;try{s=decodeURI(e)}catch{}return(s.match(/%(\w+\.+\w+)|%(\w+)/g)||[]).sort().reverse().forEach(i=>{const l=r(i.slice(1));typeof l=="string"&&(e=e.replace(new RegExp(`\\${i}(\\W|$)`,"g"),(a,u)=>`${l}${u}`).trim())}),e.includes(ht)&&(e.endsWith(ht)&&(e=e.slice(0,-ht.length).trim()),e.startsWith(ht)&&(e=e.slice(ht.length).trim()),e=e.replace(new RegExp(`\\${ht}\\s*\\${ht}`,"g"),ht),e=tr(e,{separator:n},n)),e}async function Mh(e){const t={tag:e.tagName.toLowerCase(),props:await _a(e.getAttributeNames().reduce((n,r)=>({...n,[r]:e.getAttribute(r)}),{})),innerHTML:e.innerHTML};return t._d=ya(t),t}async function ba(e,t={}){var c;const n=t.document||e.resolvedOptions.document;if(!n)return;const r={shouldRender:e.dirty,tags:[]};if(await e.hooks.callHook("dom:beforeRender",r),!r.shouldRender)return;const s=(await e.resolveTags()).map(f=>({tag:f,id:er.includes(f.tag)?di(f):f.tag,shouldRender:!0}));let o=e._dom;if(!o){o={elMap:{htmlAttrs:n.documentElement,bodyAttrs:n.body}};for(const f of["body","head"]){const d=(c=n==null?void 0:n[f])==null?void 0:c.children;for(const m of[...d].filter(v=>er.includes(v.tagName.toLowerCase())))o.elMap[m.getAttribute("data-hid")||di(await Mh(m))]=m}}o.pendingSideEffects={...o.sideEffects||{}},o.sideEffects={};function i(f,d,m){const v=`${f}:${d}`;o.sideEffects[v]=m,delete o.pendingSideEffects[v]}function l({id:f,$el:d,tag:m}){const v=m.tag.endsWith("Attrs");o.elMap[f]=d,v||(["textContent","innerHTML"].forEach(R=>{m[R]&&m[R]!==d[R]&&(d[R]=m[R])}),i(f,"el",()=>{o.elMap[f].remove(),delete o.elMap[f]})),Object.entries(m.props).forEach(([R,k])=>{const w=`attr:${R}`;if(R==="class")for(const b of(k||"").split(" ").filter(Boolean))v&&i(f,`${w}:${b}`,()=>d.classList.remove(b)),!d.classList.contains(b)&&d.classList.add(b);else d.getAttribute(R)!==k&&d.setAttribute(R,k===!0?"":String(k)),v&&i(f,w,()=>d.removeAttribute(R))})}const a=[],u={bodyClose:void 0,bodyOpen:void 0,head:void 0};for(const f of s){const{tag:d,shouldRender:m,id:v}=f;if(m){if(d.tag==="title"){n.title=d.textContent;continue}f.$el=f.$el||o.elMap[v],f.$el?l(f):er.includes(d.tag)&&a.push(f)}}for(const f of a){const d=f.tag.tagPosition||"head";f.$el=n.createElement(f.tag.tag),l(f),u[d]=u[d]||n.createDocumentFragment(),u[d].appendChild(f.$el)}for(const f of s)await e.hooks.callHook("dom:renderTag",f,n,i);u.head&&n.head.appendChild(u.head),u.bodyOpen&&n.body.insertBefore(u.bodyOpen,n.body.firstChild),u.bodyClose&&n.body.appendChild(u.bodyClose),Object.values(o.pendingSideEffects).forEach(f=>f()),e._dom=o,e.dirty=!1,await e.hooks.callHook("dom:rendered",{renders:s})}async function jh(e,t={}){const n=t.delayFn||(r=>setTimeout(r,10));return e._domUpdatePromise=e._domUpdatePromise||new Promise(r=>n(async()=>{await ba(e,t),delete e._domUpdatePromise,r()}))}function Fh(e){return t=>{var r,s;const n=((s=(r=t.resolvedOptions.document)==null?void 0:r.head.querySelector('script[id="unhead:payload"]'))==null?void 0:s.innerHTML)||!1;return n&&t.push(JSON.parse(n)),{mode:"client",hooks:{"entries:updated":function(o){jh(o,e)}}}}}const Dh=["templateParams","htmlAttrs","bodyAttrs"],Bh={hooks:{"tag:normalise":function({tag:e}){["hid","vmid","key"].forEach(r=>{e.props[r]&&(e.key=e.props[r],delete e.props[r])});const n=ya(e)||(e.key?`${e.tag}:${e.key}`:!1);n&&(e._d=n)},"tags:resolve":function(e){const t={};e.tags.forEach(r=>{const s=(r.key?`${r.tag}:${r.key}`:r._d)||r._p,o=t[s];if(o){let l=r==null?void 0:r.tagDuplicateStrategy;if(!l&&Dh.includes(r.tag)&&(l="merge"),l==="merge"){const a=o.props;["class","style"].forEach(u=>{a[u]&&(r.props[u]?(u==="style"&&!a[u].endsWith(";")&&(a[u]+=";"),r.props[u]=`${a[u]} ${r.props[u]}`):r.props[u]=a[u])}),t[s].props={...a,...r.props};return}else if(r._e===o._e){o._duped=o._duped||[],r._d=`${o._d}:${o._duped.length+1}`,o._duped.push(r);return}else if(gr(r)>gr(o))return}const i=Object.keys(r.props).length+(r.innerHTML?1:0)+(r.textContent?1:0);if(er.includes(r.tag)&&i===0){delete t[s];return}t[s]=r});const n=[];Object.values(t).forEach(r=>{const s=r._duped;delete r._duped,n.push(r),s&&n.push(...s)}),e.tags=n,e.tags=e.tags.filter(r=>!(r.tag==="meta"&&(r.props.name||r.props.property)&&!r.props.content))}}},Uh={mode:"server",hooks:{"tags:resolve":function(e){const t={};e.tags.filter(n=>["titleTemplate","templateParams","title"].includes(n.tag)&&n._m==="server").forEach(n=>{t[n.tag]=n.tag.startsWith("title")?n.textContent:n.props}),Object.keys(t).length&&e.tags.push({tag:"script",innerHTML:JSON.stringify(t),props:{id:"unhead:payload",type:"application/json"}})}}},Kh=["script","link","bodyAttrs"];function Vh(e){const t={},n={};return Object.entries(e.props).forEach(([r,s])=>{r.startsWith("on")&&typeof s=="function"?(va.includes(r)&&(t[r]=`this.dataset.${r} = true`),n[r]=s):t[r]=s}),{props:t,eventHandlers:n}}const Wh=e=>({hooks:{"tags:resolve":function(t){for(const n of t.tags)if(Kh.includes(n.tag)){const{props:r,eventHandlers:s}=Vh(n);n.props=r,Object.keys(s).length&&((n.props.src||n.props.href)&&(n.key=n.key||fo(n.props.src||n.props.href)),n._eventHandlers=s)}},"dom:renderTag":function(t,n,r){if(!t.tag._eventHandlers)return;const s=t.tag.tag==="bodyAttrs"?n.defaultView:t.$el;Object.entries(t.tag._eventHandlers).forEach(([o,i])=>{const l=`${t.tag._d||t.tag._p}:${o}`,a=o.slice(2).toLowerCase(),u=`data-h-${a}`;if(r(t.id,l,()=>{}),t.$el.hasAttribute(u))return;t.$el.setAttribute(u,"");let c;const f=d=>{i(d),c==null||c.disconnect()};o in t.$el.dataset?f(new Event(o.replace("on",""))):va.includes(o)&&typeof MutationObserver<"u"?(c=new MutationObserver(d=>{d.some(v=>v.attributeName===`data-${o}`)&&(f(new Event(o.replace("on",""))),c==null||c.disconnect())}),c.observe(t.$el,{attributes:!0})):s.addEventListener(a,f),r(t.id,l,()=>{c==null||c.disconnect(),s.removeEventListener(a,f),t.$el.removeAttribute(u)})})}}}),qh=["link","style","script","noscript"],zh={hooks:{"tag:normalise":({tag:e})=>{e.key&&qh.includes(e.tag)&&(e.props["data-hid"]=e._h=fo(e.key))}}},Qh={hooks:{"tags:resolve":e=>{const t=n=>{var r;return(r=e.tags.find(s=>s._d===n))==null?void 0:r._p};for(const{prefix:n,offset:r}of Nh)for(const s of e.tags.filter(o=>typeof o.tagPriority=="string"&&o.tagPriority.startsWith(n))){const o=t(s.tagPriority.replace(n,""));typeof o<"u"&&(s._p=o+r)}e.tags.sort((n,r)=>n._p-r._p).sort((n,r)=>gr(n)-gr(r))}}},Jh={meta:"content",link:"href",htmlAttrs:"lang"},Xh=e=>({hooks:{"tags:resolve":t=>{var l;const{tags:n}=t,r=(l=n.find(a=>a.tag==="title"))==null?void 0:l.textContent,s=n.findIndex(a=>a.tag==="templateParams"),o=s!==-1?n[s].props:{},i=o.separator||"|";delete o.separator,o.pageTitle=tr(o.pageTitle||r||"",o,i);for(const a of n.filter(u=>u.processTemplateParams!==!1)){const u=Jh[a.tag];u&&typeof a.props[u]=="string"?a.props[u]=tr(a.props[u],o,i):(a.processTemplateParams===!0||["titleTemplate","title"].includes(a.tag))&&["innerHTML","textContent"].forEach(c=>{typeof a[c]=="string"&&(a[c]=tr(a[c],o,i))})}e._templateParams=o,e._separator=i,t.tags=n.filter(a=>a.tag!=="templateParams")}}}),Yh={hooks:{"tags:resolve":e=>{const{tags:t}=e;let n=t.findIndex(s=>s.tag==="titleTemplate");const r=t.findIndex(s=>s.tag==="title");if(r!==-1&&n!==-1){const s=hi(t[n].textContent,t[r].textContent);s!==null?t[r].textContent=s||t[r].textContent:delete t[r]}else if(n!==-1){const s=hi(t[n].textContent);s!==null&&(t[n].textContent=s,t[n].tag="title",n=-1)}n!==-1&&delete t[n],e.tags=t.filter(Boolean)}}},Gh={hooks:{"tags:afterResolve":function(e){for(const t of e.tags)typeof t.innerHTML=="string"&&(t.innerHTML&&["application/ld+json","application/json"].includes(t.props.type)?t.innerHTML=t.innerHTML.replace(/{l.dirty=!0,t.callHook("entries:updated",l)};let s=0,o=[];const i=[],l={plugins:i,dirty:!1,resolvedOptions:e,hooks:t,headEntries(){return o},use(a){const u=typeof a=="function"?a(l):a;(!u.key||!i.some(c=>c.key===u.key))&&(i.push(u),mi(u.mode,n)&&t.addHooks(u.hooks||{}))},push(a,u){u==null||delete u.head;const c={_i:s++,input:a,...u};return mi(c.mode,n)&&(o.push(c),r()),{dispose(){o=o.filter(f=>f._i!==c._i),t.callHook("entries:updated",l),r()},patch(f){o=o.map(d=>(d._i===c._i&&(d.input=c.input=f),d)),r()}}},async resolveTags(){const a={tags:[],entries:[...o]};await t.callHook("entries:resolve",a);for(const u of a.entries){const c=u.resolvedInput||u.input;if(u.resolvedInput=await(u.transform?u.transform(c):c),u.resolvedInput)for(const f of await $h(u)){const d={tag:f,entry:u,resolvedOptions:l.resolvedOptions};await t.callHook("tag:normalise",d),a.tags.push(d.tag)}}return await t.callHook("tags:beforeResolve",a),await t.callHook("tags:resolve",a),await t.callHook("tags:afterResolve",a),a.tags},ssr:n};return[Bh,Uh,Wh,zh,Qh,Xh,Yh,Gh,...(e==null?void 0:e.plugins)||[]].forEach(a=>l.use(a)),l.hooks.callHook("init",l),l}function tp(){return Ea}const np=Ql.startsWith("3");function rp(e){return typeof e=="function"?e():he(e)}function As(e,t=""){if(e instanceof Promise)return e;const n=rp(e);return!e||!n?n:Array.isArray(n)?n.map(r=>As(r,t)):typeof n=="object"?Object.fromEntries(Object.entries(n).map(([r,s])=>r==="titleTemplate"||r.startsWith("on")?[r,he(s)]:[r,As(s,r)])):n}const sp={hooks:{"entries:resolve":function(e){for(const t of e.entries)t.resolvedInput=As(t.input)}}},wa="usehead";function op(e){return{install(n){np&&(n.config.globalProperties.$unhead=e,n.config.globalProperties.$head=e,n.provide(wa,e))}}.install}function ip(e={}){e.domDelayFn=e.domDelayFn||(n=>Mn(()=>setTimeout(()=>n(),0)));const t=Zh(e);return t.use(sp),t.install=op(t),t}const xs=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},ks="__unhead_injection_handler__";function lp(e){xs[ks]=e}function uy(){if(ks in xs)return xs[ks]();const e=He(wa);return e||tp()}const ap={nuxt:{buildId:"bb1ffd14-a21e-4a1d-9114-3af753bf049c"}},cp=oh(ap);function up(){const e=ge();return e._appConfig||(e._appConfig=ot(cp)),e._appConfig}const Os=!1,fp=!1,dp={componentName:"NuxtLink"},fy={deep:!0},hp="#__nuxt";let nr,Ra;function pp(){var t;const e=(t=up().nuxt)==null?void 0:t.buildId;return nr=$fetch(ao(`builds/meta/${e}.json`)),nr.then(n=>{Ra=Zd(n.matcher)}),nr}function $r(){return nr||pp()}async function Ca(e){return await $r(),da({},...Ra.matchAll(e).reverse())}function yi(e,t={}){const n=gp(e,t),r=ge(),s=r._payloadCache=r._payloadCache||{};return n in s||(s[n]=mp(e).then(o=>o?Pa(n).then(i=>i||(delete s[n],null)):(s[n]=null,null))),s[n]}const _i="json";function gp(e,t={}){const n=new URL(e,"http://localhost");if(n.host!=="localhost"||It(n.pathname,{acceptRelative:!0}))throw new Error("Payload URL must not include hostname: "+e);const r=t.hash||(t.fresh?Date.now():"");return an(Sr().app.baseURL,n.pathname,r?`_payload.${r}.${_i}`:`_payload.${_i}`)}async function Pa(e){const t=fetch(e).then(n=>n.text().then(Ta));try{return await t}catch(n){console.warn("[nuxt] Cannot load payload ",e,n)}return null}async function mp(e=pa().path){if(e=Or(e),(await $r()).prerendered.includes(e))return!0;const n=await Ca(e);return!!n.prerender&&!n.redirect}let Yn=null;async function yp(){if(Yn)return Yn;const e=document.getElementById("__NUXT_DATA__");if(!e)return{};const t=await Ta(e.textContent||""),n=e.dataset.src?await Pa(e.dataset.src):void 0;return Yn={...t,...n,...window.__NUXT__},Yn}async function Ta(e){return await Ph(e,ge()._payloadRevivers)}function _p(e,t){ge()._payloadRevivers[e]=t}const vi={NuxtError:e=>Hr(e),EmptyShallowRef:e=>Pn(e==="_"?void 0:e==="0n"?BigInt(0):ws(e)),EmptyRef:e=>Ze(e==="_"?void 0:e==="0n"?BigInt(0):ws(e)),ShallowRef:e=>Pn(e),ShallowReactive:e=>Nn(e),Ref:e=>Ze(e),Reactive:e=>ot(e)},vp=Et({name:"nuxt:revive-payload:client",order:-30,async setup(e){let t,n;for(const r in vi)_p(r,vi[r]);Object.assign(e.payload,([t,n]=Sn(()=>e.runWithContext(yp)),t=await t,n(),t)),window.__NUXT__=e.payload}}),bp=[],Ep=Et({name:"nuxt:head",enforce:"pre",setup(e){const t=ip({plugins:bp});lp(()=>ge().vueApp._context.provides.usehead),e.vueApp.use(t);{let n=!0;const r=async()=>{n=!1,await ba(t)};t.hooks.hook("dom:beforeRender",s=>{s.shouldRender=!n}),e.hooks.hook("page:start",()=>{n=!0}),e.hooks.hook("page:finish",()=>{e.isHydrating||r()}),e.hooks.hook("app:error",r),e.hooks.hook("app:suspense:resolve",r)}}});/*! +function Ns(e,t){const n=Object.create(null),r=e.split(",");for(let s=0;s!!n[s.toLowerCase()]:s=>!!n[s]}const fe={},Bt=[],Ge=()=>{},Ba=()=>!1,Hn=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Ms=e=>e.startsWith("onUpdate:"),_e=Object.assign,js=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Ua=Object.prototype.hasOwnProperty,ne=(e,t)=>Ua.call(e,t),z=Array.isArray,Ut=e=>$n(e)==="[object Map]",Ui=e=>$n(e)==="[object Set]",Ka=e=>$n(e)==="[object RegExp]",X=e=>typeof e=="function",pe=e=>typeof e=="string",mr=e=>typeof e=="symbol",ue=e=>e!==null&&typeof e=="object",Ki=e=>(ue(e)||X(e))&&X(e.then)&&X(e.catch),Vi=Object.prototype.toString,$n=e=>Vi.call(e),Va=e=>$n(e).slice(8,-1),Wi=e=>$n(e)==="[object Object]",Fs=e=>pe(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,gn=Ns(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),yr=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},Wa=/-(\w)/g,et=yr(e=>e.replace(Wa,(t,n)=>n?n.toUpperCase():"")),qa=/\B([A-Z])/g,nn=yr(e=>e.replace(qa,"-$1").toLowerCase()),_r=yr(e=>e.charAt(0).toUpperCase()+e.slice(1)),Mr=yr(e=>e?`on${_r(e)}`:""),St=(e,t)=>!Object.is(e,t),mn=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},za=e=>{const t=parseFloat(e);return isNaN(t)?e:t},qi=e=>{const t=pe(e)?Number(e):NaN;return isNaN(t)?e:t};let bo;const ns=()=>bo||(bo=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function vr(e){if(z(e)){const t={};for(let n=0;n{if(n){const r=n.split(Ja);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function br(e){let t="";if(pe(e))t=e;else if(z(e))for(let n=0;npe(e)?e:e==null?"":z(e)||ue(e)&&(e.toString===Vi||!X(e.toString))?JSON.stringify(e,Qi,2):String(e),Qi=(e,t)=>t&&t.__v_isRef?Qi(e,t.value):Ut(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[r,s])=>(n[`${r} =>`]=s,n),{})}:Ui(t)?{[`Set(${t.size})`]:[...t.values()]}:ue(t)&&!z(t)&&!Wi(t)?String(t):t;let Ie;class Ji{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Ie,!t&&Ie&&(this.index=(Ie.scopes||(Ie.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=Ie;try{return Ie=this,t()}finally{Ie=n}}}on(){Ie=this}off(){Ie=this.parent}stop(t){if(this._active){let n,r;for(n=0,r=this.effects.length;n{const t=new Set(e);return t.w=0,t.n=0,t},Xi=e=>(e.w&bt)>0,Yi=e=>(e.n&bt)>0,sc=({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let n=0;for(let r=0;r{(c==="length"||!mr(c)&&c>=a)&&l.push(u)})}else switch(n!==void 0&&l.push(i.get(n)),t){case"add":z(e)?Fs(n)&&l.push(i.get("length")):(l.push(i.get(xt)),Ut(e)&&l.push(i.get(ss)));break;case"delete":z(e)||(l.push(i.get(xt)),Ut(e)&&l.push(i.get(ss)));break;case"set":Ut(e)&&l.push(i.get(xt));break}if(l.length===1)l[0]&&os(l[0]);else{const a=[];for(const u of l)u&&a.push(...u);os(Ds(a))}}function os(e,t){const n=z(e)?e:[...e];for(const r of n)r.computed&&wo(r);for(const r of n)r.computed||wo(r)}function wo(e,t){(e!==Ue||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}function ic(e,t){var n;return(n=sr.get(e))==null?void 0:n.get(t)}const lc=Ns("__proto__,__v_isRef,__isVue"),el=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(mr)),Ro=ac();function ac(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const r=re(this);for(let o=0,i=this.length;o{e[t]=function(...n){rn();const r=re(this)[t].apply(this,n);return sn(),r}}),e}function cc(e){const t=re(this);return Oe(t,"has",e),t.hasOwnProperty(e)}class tl{constructor(t=!1,n=!1){this._isReadonly=t,this._shallow=n}get(t,n,r){const s=this._isReadonly,o=this._shallow;if(n==="__v_isReactive")return!s;if(n==="__v_isReadonly")return s;if(n==="__v_isShallow")return o;if(n==="__v_raw"&&r===(s?o?wc:ol:o?sl:rl).get(t))return t;const i=z(t);if(!s){if(i&&ne(Ro,n))return Reflect.get(Ro,n,r);if(n==="hasOwnProperty")return cc}const l=Reflect.get(t,n,r);return(mr(n)?el.has(n):lc(n))||(s||Oe(t,"get",n),o)?l:ve(l)?i&&Fs(n)?l:l.value:ue(l)?s?il(l):ot(l):l}}class nl extends tl{constructor(t=!1){super(!1,t)}set(t,n,r,s){let o=t[n];if(Lt(o)&&ve(o)&&!ve(r))return!1;if(!this._shallow&&(!or(r)&&!Lt(r)&&(o=re(o),r=re(r)),!z(t)&&ve(o)&&!ve(r)))return o.value=r,!0;const i=z(t)&&Fs(n)?Number(n)e,Er=e=>Reflect.getPrototypeOf(e);function Bn(e,t,n=!1,r=!1){e=e.__v_raw;const s=re(e),o=re(t);n||(St(t,o)&&Oe(s,"get",t),Oe(s,"get",o));const{has:i}=Er(s),l=r?Us:n?Ws:Cn;if(i.call(s,t))return l(e.get(t));if(i.call(s,o))return l(e.get(o));e!==s&&e.get(t)}function Un(e,t=!1){const n=this.__v_raw,r=re(n),s=re(e);return t||(St(e,s)&&Oe(r,"has",e),Oe(r,"has",s)),e===s?n.has(e):n.has(e)||n.has(s)}function Kn(e,t=!1){return e=e.__v_raw,!t&&Oe(re(e),"iterate",xt),Reflect.get(e,"size",e)}function Co(e){e=re(e);const t=re(this);return Er(t).has.call(t,e)||(t.add(e),st(t,"add",e,e)),this}function Po(e,t){t=re(t);const n=re(this),{has:r,get:s}=Er(n);let o=r.call(n,e);o||(e=re(e),o=r.call(n,e));const i=s.call(n,e);return n.set(e,t),o?St(t,i)&&st(n,"set",e,t):st(n,"add",e,t),this}function To(e){const t=re(this),{has:n,get:r}=Er(t);let s=n.call(t,e);s||(e=re(e),s=n.call(t,e)),r&&r.call(t,e);const o=t.delete(e);return s&&st(t,"delete",e,void 0),o}function Ao(){const e=re(this),t=e.size!==0,n=e.clear();return t&&st(e,"clear",void 0,void 0),n}function Vn(e,t){return function(r,s){const o=this,i=o.__v_raw,l=re(i),a=t?Us:e?Ws:Cn;return!e&&Oe(l,"iterate",xt),i.forEach((u,c)=>r.call(s,a(u),a(c),o))}}function Wn(e,t,n){return function(...r){const s=this.__v_raw,o=re(s),i=Ut(o),l=e==="entries"||e===Symbol.iterator&&i,a=e==="keys"&&i,u=s[e](...r),c=n?Us:t?Ws:Cn;return!t&&Oe(o,"iterate",a?ss:xt),{next(){const{value:f,done:d}=u.next();return d?{value:f,done:d}:{value:l?[c(f[0]),c(f[1])]:c(f),done:d}},[Symbol.iterator](){return this}}}}function ct(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function pc(){const e={get(o){return Bn(this,o)},get size(){return Kn(this)},has:Un,add:Co,set:Po,delete:To,clear:Ao,forEach:Vn(!1,!1)},t={get(o){return Bn(this,o,!1,!0)},get size(){return Kn(this)},has:Un,add:Co,set:Po,delete:To,clear:Ao,forEach:Vn(!1,!0)},n={get(o){return Bn(this,o,!0)},get size(){return Kn(this,!0)},has(o){return Un.call(this,o,!0)},add:ct("add"),set:ct("set"),delete:ct("delete"),clear:ct("clear"),forEach:Vn(!0,!1)},r={get(o){return Bn(this,o,!0,!0)},get size(){return Kn(this,!0)},has(o){return Un.call(this,o,!0)},add:ct("add"),set:ct("set"),delete:ct("delete"),clear:ct("clear"),forEach:Vn(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(o=>{e[o]=Wn(o,!1,!1),n[o]=Wn(o,!0,!1),t[o]=Wn(o,!1,!0),r[o]=Wn(o,!0,!0)}),[e,n,t,r]}const[gc,mc,yc,_c]=pc();function Ks(e,t){const n=t?e?_c:yc:e?mc:gc;return(r,s,o)=>s==="__v_isReactive"?!e:s==="__v_isReadonly"?e:s==="__v_raw"?r:Reflect.get(ne(n,s)&&s in r?n:r,s,o)}const vc={get:Ks(!1,!1)},bc={get:Ks(!1,!0)},Ec={get:Ks(!0,!1)},rl=new WeakMap,sl=new WeakMap,ol=new WeakMap,wc=new WeakMap;function Rc(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Cc(e){return e.__v_skip||!Object.isExtensible(e)?0:Rc(Va(e))}function ot(e){return Lt(e)?e:Vs(e,!1,fc,vc,rl)}function Nn(e){return Vs(e,!1,hc,bc,sl)}function il(e){return Vs(e,!0,dc,Ec,ol)}function Vs(e,t,n,r,s){if(!ue(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const o=s.get(e);if(o)return o;const i=Cc(e);if(i===0)return e;const l=new Proxy(e,i===2?r:n);return s.set(e,l),l}function Kt(e){return Lt(e)?Kt(e.__v_raw):!!(e&&e.__v_isReactive)}function Lt(e){return!!(e&&e.__v_isReadonly)}function or(e){return!!(e&&e.__v_isShallow)}function ll(e){return Kt(e)||Lt(e)}function re(e){const t=e&&e.__v_raw;return t?re(t):e}function al(e){return rr(e,"__v_skip",!0),e}const Cn=e=>ue(e)?ot(e):e,Ws=e=>ue(e)?il(e):e;function qs(e){_t&&Ue&&(e=re(e),Zi(e.dep||(e.dep=Ds())))}function zs(e,t){e=re(e);const n=e.dep;n&&os(n)}function ve(e){return!!(e&&e.__v_isRef===!0)}function Ze(e){return cl(e,!1)}function Pn(e){return cl(e,!0)}function cl(e,t){return ve(e)?e:new Pc(e,t)}class Pc{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:re(t),this._value=n?t:Cn(t)}get value(){return qs(this),this._value}set value(t){const n=this.__v_isShallow||or(t)||Lt(t);t=n?t:re(t),St(t,this._rawValue)&&(this._rawValue=t,this._value=n?t:Cn(t),zs(this))}}function he(e){return ve(e)?e.value:e}const Tc={get:(e,t,n)=>he(Reflect.get(e,t,n)),set:(e,t,n,r)=>{const s=e[t];return ve(s)&&!ve(n)?(s.value=n,!0):Reflect.set(e,t,n,r)}};function ul(e){return Kt(e)?e:new Proxy(e,Tc)}class Ac{constructor(t){this.dep=void 0,this.__v_isRef=!0;const{get:n,set:r}=t(()=>qs(this),()=>zs(this));this._get=n,this._set=r}get value(){return this._get()}set value(t){this._set(t)}}function ey(e){return new Ac(e)}function ty(e){const t=z(e)?new Array(e.length):{};for(const n in e)t[n]=fl(e,n);return t}class xc{constructor(t,n,r){this._object=t,this._key=n,this._defaultValue=r,this.__v_isRef=!0}get value(){const t=this._object[this._key];return t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return ic(re(this._object),this._key)}}class kc{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function Oc(e,t,n){return ve(e)?e:X(e)?new kc(e):ue(e)&&arguments.length>1?fl(e,t,n):Ze(e)}function fl(e,t,n){const r=e[t];return ve(r)?r:new xc(e,t,n)}class Sc{constructor(t,n,r,s){this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this._dirty=!0,this.effect=new Bs(t,()=>{this._dirty||(this._dirty=!0,zs(this))}),this.effect.computed=this,this.effect.active=this._cacheable=!s,this.__v_isReadonly=r}get value(){const t=re(this);return qs(t),(t._dirty||!t._cacheable)&&(t._dirty=!1,t._value=t.effect.run()),t._value}set value(t){this._setter(t)}}function Lc(e,t,n=!1){let r,s;const o=X(e);return o?(r=e,s=Ge):(r=e.get,s=e.set),new Sc(r,s,o||!s,n)}function vt(e,t,n,r){let s;try{s=r?e(...r):e()}catch(o){on(o,t,n)}return s}function je(e,t,n,r){if(X(e)){const o=vt(e,t,n,r);return o&&Ki(o)&&o.catch(i=>{on(i,t,n)}),o}const s=[];for(let o=0;o>>1,s=Re[r],o=An(s);oXe&&Re.splice(t,1)}function ls(e){z(e)?Vt.push(...e):(!rt||!rt.includes(e,e.allowRecurse?Tt+1:Tt))&&Vt.push(e),hl()}function xo(e,t=Tn?Xe+1:0){for(;tAn(n)-An(r)),Tt=0;Tte.id==null?1/0:e.id,Nc=(e,t)=>{const n=An(e)-An(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function pl(e){is=!1,Tn=!0,Re.sort(Nc);try{for(Xe=0;Xepe(m)?m.trim():m)),f&&(s=n.map(za))}let l,a=r[l=Mr(t)]||r[l=Mr(et(t))];!a&&o&&(a=r[l=Mr(nn(t))]),a&&je(a,e,6,s);const u=r[l+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,je(u,e,6,s)}}function gl(e,t,n=!1){const r=t.emitsCache,s=r.get(e);if(s!==void 0)return s;const o=e.emits;let i={},l=!1;if(!X(e)){const a=u=>{const c=gl(u,t,!0);c&&(l=!0,_e(i,c))};!n&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!o&&!l?(ue(e)&&r.set(e,null),null):(z(o)?o.forEach(a=>i[a]=null):_e(i,o),ue(e)&&r.set(e,i),i)}function Rr(e,t){return!e||!Hn(t)?!1:(t=t.slice(2).replace(/Once$/,""),ne(e,t[0].toLowerCase()+t.slice(1))||ne(e,nn(t))||ne(e,t))}let Ee=null,Cr=null;function lr(e){const t=Ee;return Ee=e,Cr=e&&e.type.__scopeId||null,t}function ny(e){Cr=e}function ry(){Cr=null}function Js(e,t=Ee,n){if(!t||e._n)return e;const r=(...s)=>{r._d&&Bo(-1);const o=lr(t);let i;try{i=e(...s)}finally{lr(o),r._d&&Bo(1)}return i};return r._n=!0,r._c=!0,r._d=!0,r}function jr(e){const{type:t,vnode:n,proxy:r,withProxy:s,props:o,propsOptions:[i],slots:l,attrs:a,emit:u,render:c,renderCache:f,data:d,setupState:m,ctx:v,inheritAttrs:R}=e;let k,w;const b=lr(e);try{if(n.shapeFlag&4){const g=s||r,C=g;k=Ne(c.call(C,g,f,o,m,d,v)),w=a}else{const g=t;k=Ne(g.length>1?g(o,{attrs:a,slots:l,emit:u}):g(o,null)),w=t.props?a:Fc(a)}}catch(g){vn.length=0,on(g,e,1),k=de(Te)}let y=k;if(w&&R!==!1){const g=Object.keys(w),{shapeFlag:C}=y;g.length&&C&7&&(i&&g.some(Ms)&&(w=Dc(w,i)),y=it(y,w))}return n.dirs&&(y=it(y),y.dirs=y.dirs?y.dirs.concat(n.dirs):n.dirs),n.transition&&(y.transition=n.transition),k=y,lr(b),k}function jc(e){let t;for(let n=0;n{let t;for(const n in e)(n==="class"||n==="style"||Hn(n))&&((t||(t={}))[n]=e[n]);return t},Dc=(e,t)=>{const n={};for(const r in e)(!Ms(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function Bc(e,t,n){const{props:r,children:s,component:o}=e,{props:i,children:l,patchFlag:a}=t,u=o.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&a>=0){if(a&1024)return!0;if(a&16)return r?ko(r,i,u):!!i;if(a&8){const c=t.dynamicProps;for(let f=0;fe.__isSuspense,Vc={name:"Suspense",__isSuspense:!0,process(e,t,n,r,s,o,i,l,a,u){e==null?Wc(t,n,r,s,o,i,l,a,u):qc(e,t,n,r,s,i,l,a,u)},hydrate:zc,create:Gs,normalize:Qc},vl=Vc;function xn(e,t){const n=e.props&&e.props[t];X(n)&&n()}function Wc(e,t,n,r,s,o,i,l,a){const{p:u,o:{createElement:c}}=a,f=c("div"),d=e.suspense=Gs(e,s,r,t,f,n,o,i,l,a);u(null,d.pendingBranch=e.ssContent,f,null,r,d,o,i),d.deps>0?(xn(e,"onPending"),xn(e,"onFallback"),u(null,e.ssFallback,t,n,r,null,o,i),Wt(d,e.ssFallback)):d.resolve(!1,!0)}function qc(e,t,n,r,s,o,i,l,{p:a,um:u,o:{createElement:c}}){const f=t.suspense=e.suspense;f.vnode=t,t.el=e.el;const d=t.ssContent,m=t.ssFallback,{activeBranch:v,pendingBranch:R,isInFallback:k,isHydrating:w}=f;if(R)f.pendingBranch=d,Ke(d,R)?(a(R,d,f.hiddenContainer,null,s,f,o,i,l),f.deps<=0?f.resolve():k&&(a(v,m,n,r,s,null,o,i,l),Wt(f,m))):(f.pendingId++,w?(f.isHydrating=!1,f.activeBranch=R):u(R,s,f),f.deps=0,f.effects.length=0,f.hiddenContainer=c("div"),k?(a(null,d,f.hiddenContainer,null,s,f,o,i,l),f.deps<=0?f.resolve():(a(v,m,n,r,s,null,o,i,l),Wt(f,m))):v&&Ke(d,v)?(a(v,d,n,r,s,f,o,i,l),f.resolve(!0)):(a(null,d,f.hiddenContainer,null,s,f,o,i,l),f.deps<=0&&f.resolve()));else if(v&&Ke(d,v))a(v,d,n,r,s,f,o,i,l),Wt(f,d);else if(xn(t,"onPending"),f.pendingBranch=d,f.pendingId++,a(null,d,f.hiddenContainer,null,s,f,o,i,l),f.deps<=0)f.resolve();else{const{timeout:b,pendingId:y}=f;b>0?setTimeout(()=>{f.pendingId===y&&f.fallback(m)},b):b===0&&f.fallback(m)}}function Gs(e,t,n,r,s,o,i,l,a,u,c=!1){const{p:f,m:d,um:m,n:v,o:{parentNode:R,remove:k}}=u;let w;const b=Jc(e);b&&t!=null&&t.pendingBranch&&(w=t.pendingId,t.deps++);const y=e.props?qi(e.props.timeout):void 0,g={vnode:e,parent:t,parentComponent:n,isSVG:i,container:r,hiddenContainer:s,anchor:o,deps:0,pendingId:0,timeout:typeof y=="number"?y:-1,activeBranch:null,pendingBranch:null,isInFallback:!0,isHydrating:c,isUnmounted:!1,effects:[],resolve(C=!1,I=!1){const{vnode:N,activeBranch:O,pendingBranch:D,pendingId:M,effects:Q,parentComponent:L,container:J}=g;let ae=!1;if(g.isHydrating)g.isHydrating=!1;else if(!C){ae=O&&D.transition&&D.transition.mode==="out-in",ae&&(O.transition.afterLeave=()=>{M===g.pendingId&&(d(D,J,v(O),0),ls(Q))});let{anchor:Z}=g;O&&(Z=v(O),m(O,L,g,!0)),ae||d(D,J,Z,0)}Wt(g,D),g.pendingBranch=null,g.isInFallback=!1;let le=g.parent,U=!1;for(;le;){if(le.pendingBranch){le.effects.push(...Q),U=!0;break}le=le.parent}!U&&!ae&&ls(Q),g.effects=[],b&&t&&t.pendingBranch&&w===t.pendingId&&(t.deps--,t.deps===0&&!I&&t.resolve()),xn(N,"onResolve")},fallback(C){if(!g.pendingBranch)return;const{vnode:I,activeBranch:N,parentComponent:O,container:D,isSVG:M}=g;xn(I,"onFallback");const Q=()=>{g.isInFallback&&(f(null,C,D,v(N),O,null,M,l,a),Wt(g,C))},L=C.transition&&C.transition.mode==="out-in";L&&(N.transition.afterLeave=Q),g.isInFallback=!0,m(N,O,null,!0),L||Q()},move(C,I,N){g.activeBranch&&d(g.activeBranch,C,I,N),g.container=C},next(){return g.activeBranch&&v(g.activeBranch)},registerDep(C,I){const N=!!g.pendingBranch;N&&g.deps++;const O=C.vnode.el;C.asyncDep.catch(D=>{on(D,C,0)}).then(D=>{if(C.isUnmounted||g.isUnmounted||g.pendingId!==C.suspenseId)return;C.asyncResolved=!0;const{vnode:M}=C;hs(C,D,!1),O&&(M.el=O);const Q=!O&&C.subTree.el;I(C,M,R(O||C.subTree.el),O?null:v(C.subTree),g,i,a),Q&&k(Q),Xs(C,M.el),N&&--g.deps===0&&g.resolve()})},unmount(C,I){g.isUnmounted=!0,g.activeBranch&&m(g.activeBranch,n,C,I),g.pendingBranch&&m(g.pendingBranch,n,C,I)}};return g}function zc(e,t,n,r,s,o,i,l,a){const u=t.suspense=Gs(t,r,n,e.parentNode,document.createElement("div"),null,s,o,i,l,!0),c=a(e,u.pendingBranch=t.ssContent,n,u,o,i);return u.deps===0&&u.resolve(!1,!0),c}function Qc(e){const{shapeFlag:t,children:n}=e,r=t&32;e.ssContent=So(r?n.default:n),e.ssFallback=r?So(n.fallback):de(Te)}function So(e){let t;if(X(e)){const n=Xt&&e._c;n&&(e._d=!1,Ye()),e=e(),n&&(e._d=!0,t=Me,Bl())}return z(e)&&(e=jc(e)),e=Ne(e),t&&!e.dynamicChildren&&(e.dynamicChildren=t.filter(n=>n!==e)),e}function bl(e,t){t&&t.pendingBranch?z(e)?t.effects.push(...e):t.effects.push(e):ls(e)}function Wt(e,t){e.activeBranch=t;const{vnode:n,parentComponent:r}=e,s=n.el=t.el;r&&r.subTree===n&&(r.vnode.el=s,Xs(r,s))}function Jc(e){var t;return((t=e.props)==null?void 0:t.suspensible)!=null&&e.props.suspensible!==!1}function sy(e,t){return Zs(e,null,t)}const qn={};function qt(e,t,n){return Zs(e,t,n)}function Zs(e,t,{immediate:n,deep:r,flush:s,onTrack:o,onTrigger:i}=fe){var l;const a=rc()===((l=ye)==null?void 0:l.scope)?ye:null;let u,c=!1,f=!1;if(ve(e)?(u=()=>e.value,c=or(e)):Kt(e)?(u=()=>e,r=!0):z(e)?(f=!0,c=e.some(g=>Kt(g)||or(g)),u=()=>e.map(g=>{if(ve(g))return g.value;if(Kt(g))return Ft(g);if(X(g))return vt(g,a,2)})):X(e)?t?u=()=>vt(e,a,2):u=()=>{if(!(a&&a.isUnmounted))return d&&d(),je(e,a,3,[m])}:u=Ge,t&&r){const g=u;u=()=>Ft(g())}let d,m=g=>{d=b.onStop=()=>{vt(g,a,4),d=b.onStop=void 0}},v;if(Zt)if(m=Ge,t?n&&je(t,a,3,[u(),f?[]:void 0,m]):u(),s==="sync"){const g=Bu();v=g.__watcherHandles||(g.__watcherHandles=[])}else return Ge;let R=f?new Array(e.length).fill(qn):qn;const k=()=>{if(b.active)if(t){const g=b.run();(r||c||(f?g.some((C,I)=>St(C,R[I])):St(g,R)))&&(d&&d(),je(t,a,3,[g,R===qn?void 0:f&&R[0]===qn?[]:R,m]),R=g)}else b.run()};k.allowRecurse=!!t;let w;s==="sync"?w=k:s==="post"?w=()=>be(k,a&&a.suspense):(k.pre=!0,a&&(k.id=a.uid),w=()=>wr(k));const b=new Bs(u,w);t?n?k():R=b.run():s==="post"?be(b.run.bind(b),a&&a.suspense):b.run();const y=()=>{b.stop(),a&&a.scope&&js(a.scope.effects,b)};return v&&v.push(y),y}function Xc(e,t,n){const r=this.proxy,s=pe(e)?e.includes(".")?El(r,e):()=>r[e]:e.bind(r,r);let o;X(t)?o=t:(o=t.handler,n=t);const i=ye;Gt(this);const l=Zs(s,o.bind(r),n);return i?Gt(i):Ot(),l}function El(e,t){const n=t.split(".");return()=>{let r=e;for(let s=0;s{Ft(n,t)});else if(Wi(e))for(const n in e)Ft(e[n],t);return e}function Je(e,t,n,r){const s=e.dirs,o=t&&t.dirs;for(let i=0;i{e.isMounted=!0}),Ar(()=>{e.isUnmounting=!0}),e}const $e=[Function,Array],wl={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:$e,onEnter:$e,onAfterEnter:$e,onEnterCancelled:$e,onBeforeLeave:$e,onLeave:$e,onAfterLeave:$e,onLeaveCancelled:$e,onBeforeAppear:$e,onAppear:$e,onAfterAppear:$e,onAppearCancelled:$e},Gc={name:"BaseTransition",props:wl,setup(e,{slots:t}){const n=kr(),r=Yc();let s;return()=>{const o=t.default&&Cl(t.default(),!0);if(!o||!o.length)return;let i=o[0];if(o.length>1){for(const R of o)if(R.type!==Te){i=R;break}}const l=re(e),{mode:a}=l;if(r.isLeaving)return Fr(i);const u=Lo(i);if(!u)return Fr(i);const c=as(u,l,r,n);ar(u,c);const f=n.subTree,d=f&&Lo(f);let m=!1;const{getTransitionKey:v}=u.type;if(v){const R=v();s===void 0?s=R:R!==s&&(s=R,m=!0)}if(d&&d.type!==Te&&(!Ke(u,d)||m)){const R=as(d,l,r,n);if(ar(d,R),a==="out-in")return r.isLeaving=!0,R.afterLeave=()=>{r.isLeaving=!1,n.update.active!==!1&&n.update()},Fr(i);a==="in-out"&&u.type!==Te&&(R.delayLeave=(k,w,b)=>{const y=Rl(r,d);y[String(d.key)]=d,k[pt]=()=>{w(),k[pt]=void 0,delete c.delayedLeave},c.delayedLeave=b})}return i}}},Zc=Gc;function Rl(e,t){const{leavingVNodes:n}=e;let r=n.get(t.type);return r||(r=Object.create(null),n.set(t.type,r)),r}function as(e,t,n,r){const{appear:s,mode:o,persisted:i=!1,onBeforeEnter:l,onEnter:a,onAfterEnter:u,onEnterCancelled:c,onBeforeLeave:f,onLeave:d,onAfterLeave:m,onLeaveCancelled:v,onBeforeAppear:R,onAppear:k,onAfterAppear:w,onAppearCancelled:b}=t,y=String(e.key),g=Rl(n,e),C=(O,D)=>{O&&je(O,r,9,D)},I=(O,D)=>{const M=D[1];C(O,D),z(O)?O.every(Q=>Q.length<=1)&&M():O.length<=1&&M()},N={mode:o,persisted:i,beforeEnter(O){let D=l;if(!n.isMounted)if(s)D=R||l;else return;O[pt]&&O[pt](!0);const M=g[y];M&&Ke(e,M)&&M.el[pt]&&M.el[pt](),C(D,[O])},enter(O){let D=a,M=u,Q=c;if(!n.isMounted)if(s)D=k||a,M=w||u,Q=b||c;else return;let L=!1;const J=O[zn]=ae=>{L||(L=!0,ae?C(Q,[O]):C(M,[O]),N.delayedLeave&&N.delayedLeave(),O[zn]=void 0)};D?I(D,[O,J]):J()},leave(O,D){const M=String(e.key);if(O[zn]&&O[zn](!0),n.isUnmounting)return D();C(f,[O]);let Q=!1;const L=O[pt]=J=>{Q||(Q=!0,D(),J?C(v,[O]):C(m,[O]),O[pt]=void 0,g[M]===e&&delete g[M])};g[M]=e,d?I(d,[O,L]):L()},clone(O){return as(O,t,n,r)}};return N}function Fr(e){if(jn(e))return e=it(e),e.children=null,e}function Lo(e){return jn(e)?e.children?e.children[0]:void 0:e}function ar(e,t){e.shapeFlag&6&&e.component?ar(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Cl(e,t=!1,n){let r=[],s=0;for(let o=0;o1)for(let o=0;o!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function ee(e){X(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:r,delay:s=200,timeout:o,suspensible:i=!0,onError:l}=e;let a=null,u,c=0;const f=()=>(c++,a=null,d()),d=()=>{let m;return a||(m=a=t().catch(v=>{if(v=v instanceof Error?v:new Error(String(v)),l)return new Promise((R,k)=>{l(v,()=>R(f()),()=>k(v),c+1)});throw v}).then(v=>m!==a&&a?a:(v&&(v.__esModule||v[Symbol.toStringTag]==="Module")&&(v=v.default),u=v,v)))};return ln({name:"AsyncComponentWrapper",__asyncLoader:d,get __asyncResolved(){return u},setup(){const m=ye;if(u)return()=>Dr(u,m);const v=b=>{a=null,on(b,m,13,!r)};if(i&&m.suspense||Zt)return d().then(b=>()=>Dr(b,m)).catch(b=>(v(b),()=>r?de(r,{error:b}):null));const R=Ze(!1),k=Ze(),w=Ze(!!s);return s&&setTimeout(()=>{w.value=!1},s),o!=null&&setTimeout(()=>{if(!R.value&&!k.value){const b=new Error(`Async component timed out after ${o}ms.`);v(b),k.value=b}},o),d().then(()=>{R.value=!0,m.parent&&jn(m.parent.vnode)&&wr(m.parent.update)}).catch(b=>{v(b),k.value=b}),()=>{if(R.value&&u)return Dr(u,m);if(k.value&&r)return de(r,{error:k.value});if(n&&!w.value)return de(n)}}})}function Dr(e,t){const{ref:n,props:r,children:s,ce:o}=t.vnode,i=de(e,r,s);return i.ref=n,i.ce=o,delete t.vnode.ce,i}const jn=e=>e.type.__isKeepAlive,eu={name:"KeepAlive",__isKeepAlive:!0,props:{include:[String,RegExp,Array],exclude:[String,RegExp,Array],max:[String,Number]},setup(e,{slots:t}){const n=kr(),r=n.ctx;if(!r.renderer)return()=>{const b=t.default&&t.default();return b&&b.length===1?b[0]:b};const s=new Map,o=new Set;let i=null;const l=n.suspense,{renderer:{p:a,m:u,um:c,o:{createElement:f}}}=r,d=f("div");r.activate=(b,y,g,C,I)=>{const N=b.component;u(b,y,g,0,l),a(N.vnode,b,y,g,N,l,C,b.slotScopeIds,I),be(()=>{N.isDeactivated=!1,N.a&&mn(N.a);const O=b.props&&b.props.onVnodeMounted;O&&xe(O,N.parent,b)},l)},r.deactivate=b=>{const y=b.component;u(b,d,null,1,l),be(()=>{y.da&&mn(y.da);const g=b.props&&b.props.onVnodeUnmounted;g&&xe(g,y.parent,b),y.isDeactivated=!0},l)};function m(b){Br(b),c(b,n,l,!0)}function v(b){s.forEach((y,g)=>{const C=ps(y.type);C&&(!b||!b(C))&&R(g)})}function R(b){const y=s.get(b);!i||!Ke(y,i)?m(y):i&&Br(i),s.delete(b),o.delete(b)}qt(()=>[e.include,e.exclude],([b,y])=>{b&&v(g=>hn(b,g)),y&&v(g=>!hn(y,g))},{flush:"post",deep:!0});let k=null;const w=()=>{k!=null&&s.set(k,Ur(n.subTree))};return Tr(w),Tl(w),Ar(()=>{s.forEach(b=>{const{subTree:y,suspense:g}=n,C=Ur(y);if(b.type===C.type&&b.key===C.key){Br(C);const I=C.component.da;I&&be(I,g);return}m(b)})}),()=>{if(k=null,!t.default)return null;const b=t.default(),y=b[0];if(b.length>1)return i=null,b;if(!Yt(y)||!(y.shapeFlag&4)&&!(y.shapeFlag&128))return i=null,y;let g=Ur(y);const C=g.type,I=ps(kt(g)?g.type.__asyncResolved||{}:C),{include:N,exclude:O,max:D}=e;if(N&&(!I||!hn(N,I))||O&&I&&hn(O,I))return i=g,y;const M=g.key==null?C:g.key,Q=s.get(M);return g.el&&(g=it(g),y.shapeFlag&128&&(y.ssContent=g)),k=M,Q?(g.el=Q.el,g.component=Q.component,g.transition&&ar(g,g.transition),g.shapeFlag|=512,o.delete(M),o.add(M)):(o.add(M),D&&o.size>parseInt(D,10)&&R(o.values().next().value)),g.shapeFlag|=256,i=g,_l(y.type)?y:g}}},tu=eu;function hn(e,t){return z(e)?e.some(n=>hn(n,t)):pe(e)?e.split(",").includes(t):Ka(e)?e.test(t):!1}function nu(e,t){Pl(e,"a",t)}function ru(e,t){Pl(e,"da",t)}function Pl(e,t,n=ye){const r=e.__wdc||(e.__wdc=()=>{let s=n;for(;s;){if(s.isDeactivated)return;s=s.parent}return e()});if(Pr(t,r,n),n){let s=n.parent;for(;s&&s.parent;)jn(s.parent.vnode)&&su(r,t,n,s),s=s.parent}}function su(e,t,n,r){const s=Pr(t,e,r,!0);Al(()=>{js(r[t],s)},n)}function Br(e){e.shapeFlag&=-257,e.shapeFlag&=-513}function Ur(e){return e.shapeFlag&128?e.ssContent:e}function Pr(e,t,n=ye,r=!1){if(n){const s=n[e]||(n[e]=[]),o=t.__weh||(t.__weh=(...i)=>{if(n.isUnmounted)return;rn(),Gt(n);const l=je(t,n,e,i);return Ot(),sn(),l});return r?s.unshift(o):s.push(o),o}}const lt=e=>(t,n=ye)=>(!Zt||e==="sp")&&Pr(e,(...r)=>t(...r),n),ou=lt("bm"),Tr=lt("m"),iu=lt("bu"),Tl=lt("u"),Ar=lt("bum"),Al=lt("um"),lu=lt("sp"),au=lt("rtg"),cu=lt("rtc");function xl(e,t=ye){Pr("ec",e,t)}function oy(e,t,n,r){let s;const o=n&&n[r];if(z(e)||pe(e)){s=new Array(e.length);for(let i=0,l=e.length;it(i,l,void 0,o&&o[l]));else{const i=Object.keys(e);s=new Array(i.length);for(let l=0,a=i.length;lYt(t)?!(t.type===Te||t.type===ke&&!kl(t.children)):!0)?e:null}const cs=e=>e?Wl(e)?oo(e)||e.proxy:cs(e.parent):null,yn=_e(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>cs(e.parent),$root:e=>cs(e.root),$emit:e=>e.emit,$options:e=>eo(e),$forceUpdate:e=>e.f||(e.f=()=>wr(e.update)),$nextTick:e=>e.n||(e.n=Mn.bind(e.proxy)),$watch:e=>Xc.bind(e)}),Kr=(e,t)=>e!==fe&&!e.__isScriptSetup&&ne(e,t),uu={get({_:e},t){const{ctx:n,setupState:r,data:s,props:o,accessCache:i,type:l,appContext:a}=e;let u;if(t[0]!=="$"){const m=i[t];if(m!==void 0)switch(m){case 1:return r[t];case 2:return s[t];case 4:return n[t];case 3:return o[t]}else{if(Kr(r,t))return i[t]=1,r[t];if(s!==fe&&ne(s,t))return i[t]=2,s[t];if((u=e.propsOptions[0])&&ne(u,t))return i[t]=3,o[t];if(n!==fe&&ne(n,t))return i[t]=4,n[t];us&&(i[t]=0)}}const c=yn[t];let f,d;if(c)return t==="$attrs"&&Oe(e,"get",t),c(e);if((f=l.__cssModules)&&(f=f[t]))return f;if(n!==fe&&ne(n,t))return i[t]=4,n[t];if(d=a.config.globalProperties,ne(d,t))return d[t]},set({_:e},t,n){const{data:r,setupState:s,ctx:o}=e;return Kr(s,t)?(s[t]=n,!0):r!==fe&&ne(r,t)?(r[t]=n,!0):ne(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:s,propsOptions:o}},i){let l;return!!n[i]||e!==fe&&ne(e,i)||Kr(t,i)||(l=o[0])&&ne(l,i)||ne(r,i)||ne(yn,i)||ne(s.config.globalProperties,i)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:ne(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function ly(){return fu().slots}function fu(){const e=kr();return e.setupContext||(e.setupContext=zl(e))}function Io(e){return z(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let us=!0;function du(e){const t=eo(e),n=e.proxy,r=e.ctx;us=!1,t.beforeCreate&&Ho(t.beforeCreate,e,"bc");const{data:s,computed:o,methods:i,watch:l,provide:a,inject:u,created:c,beforeMount:f,mounted:d,beforeUpdate:m,updated:v,activated:R,deactivated:k,beforeDestroy:w,beforeUnmount:b,destroyed:y,unmounted:g,render:C,renderTracked:I,renderTriggered:N,errorCaptured:O,serverPrefetch:D,expose:M,inheritAttrs:Q,components:L,directives:J,filters:ae}=t;if(u&&hu(u,r,null),i)for(const Z in i){const K=i[Z];X(K)&&(r[Z]=K.bind(n))}if(s){const Z=s.call(n,n);ue(Z)&&(e.data=ot(Z))}if(us=!0,o)for(const Z in o){const K=o[Z],Fe=X(K)?K.bind(n,n):X(K.get)?K.get.bind(n,n):Ge,at=!X(K)&&X(K.set)?K.set.bind(n):Ge,ze=Pe({get:Fe,set:at});Object.defineProperty(r,Z,{enumerable:!0,configurable:!0,get:()=>ze.value,set:Ae=>ze.value=Ae})}if(l)for(const Z in l)Ol(l[Z],r,n,Z);if(a){const Z=X(a)?a.call(n):a;Reflect.ownKeys(Z).forEach(K=>{zt(K,Z[K])})}c&&Ho(c,e,"c");function U(Z,K){z(K)?K.forEach(Fe=>Z(Fe.bind(n))):K&&Z(K.bind(n))}if(U(ou,f),U(Tr,d),U(iu,m),U(Tl,v),U(nu,R),U(ru,k),U(xl,O),U(cu,I),U(au,N),U(Ar,b),U(Al,g),U(lu,D),z(M))if(M.length){const Z=e.exposed||(e.exposed={});M.forEach(K=>{Object.defineProperty(Z,K,{get:()=>n[K],set:Fe=>n[K]=Fe})})}else e.exposed||(e.exposed={});C&&e.render===Ge&&(e.render=C),Q!=null&&(e.inheritAttrs=Q),L&&(e.components=L),J&&(e.directives=J)}function hu(e,t,n=Ge){z(e)&&(e=fs(e));for(const r in e){const s=e[r];let o;ue(s)?"default"in s?o=He(s.from||r,s.default,!0):o=He(s.from||r):o=He(s),ve(o)?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>o.value,set:i=>o.value=i}):t[r]=o}}function Ho(e,t,n){je(z(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,n)}function Ol(e,t,n,r){const s=r.includes(".")?El(n,r):()=>n[r];if(pe(e)){const o=t[e];X(o)&&qt(s,o)}else if(X(e))qt(s,e.bind(n));else if(ue(e))if(z(e))e.forEach(o=>Ol(o,t,n,r));else{const o=X(e.handler)?e.handler.bind(n):t[e.handler];X(o)&&qt(s,o,e)}}function eo(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:s,optionsCache:o,config:{optionMergeStrategies:i}}=e.appContext,l=o.get(t);let a;return l?a=l:!s.length&&!n&&!r?a=t:(a={},s.length&&s.forEach(u=>cr(a,u,i,!0)),cr(a,t,i)),ue(t)&&o.set(t,a),a}function cr(e,t,n,r=!1){const{mixins:s,extends:o}=t;o&&cr(e,o,n,!0),s&&s.forEach(i=>cr(e,i,n,!0));for(const i in t)if(!(r&&i==="expose")){const l=pu[i]||n&&n[i];e[i]=l?l(e[i],t[i]):t[i]}return e}const pu={data:$o,props:No,emits:No,methods:pn,computed:pn,beforeCreate:Ce,created:Ce,beforeMount:Ce,mounted:Ce,beforeUpdate:Ce,updated:Ce,beforeDestroy:Ce,beforeUnmount:Ce,destroyed:Ce,unmounted:Ce,activated:Ce,deactivated:Ce,errorCaptured:Ce,serverPrefetch:Ce,components:pn,directives:pn,watch:mu,provide:$o,inject:gu};function $o(e,t){return t?e?function(){return _e(X(e)?e.call(this,this):e,X(t)?t.call(this,this):t)}:t:e}function gu(e,t){return pn(fs(e),fs(t))}function fs(e){if(z(e)){const t={};for(let n=0;n1)return n&&X(t)?t.call(r&&r.proxy):t}}function Ll(){return!!(ye||Ee||kn)}function vu(e,t,n,r=!1){const s={},o={};rr(o,xr,1),e.propsDefaults=Object.create(null),Il(e,t,s,o);for(const i in e.propsOptions[0])i in s||(s[i]=void 0);n?e.props=r?s:Nn(s):e.type.props?e.props=s:e.props=o,e.attrs=o}function bu(e,t,n,r){const{props:s,attrs:o,vnode:{patchFlag:i}}=e,l=re(s),[a]=e.propsOptions;let u=!1;if((r||i>0)&&!(i&16)){if(i&8){const c=e.vnode.dynamicProps;for(let f=0;f{a=!0;const[d,m]=Hl(f,t,!0);_e(i,d),m&&l.push(...m)};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}if(!o&&!a)return ue(e)&&r.set(e,Bt),Bt;if(z(o))for(let c=0;c-1,m[1]=R<0||v-1||ne(m,"default"))&&l.push(f)}}}const u=[i,l];return ue(e)&&r.set(e,u),u}function Mo(e){return e[0]!=="$"}function jo(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function Fo(e,t){return jo(e)===jo(t)}function Do(e,t){return z(t)?t.findIndex(n=>Fo(n,e)):X(t)&&Fo(t,e)?0:-1}const $l=e=>e[0]==="_"||e==="$stable",to=e=>z(e)?e.map(Ne):[Ne(e)],Eu=(e,t,n)=>{if(t._n)return t;const r=Js((...s)=>to(t(...s)),n);return r._c=!1,r},Nl=(e,t,n)=>{const r=e._ctx;for(const s in e){if($l(s))continue;const o=e[s];if(X(o))t[s]=Eu(s,o,r);else if(o!=null){const i=to(o);t[s]=()=>i}}},Ml=(e,t)=>{const n=to(t);e.slots.default=()=>n},wu=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=re(t),rr(t,"_",n)):Nl(t,e.slots={})}else e.slots={},t&&Ml(e,t);rr(e.slots,xr,1)},Ru=(e,t,n)=>{const{vnode:r,slots:s}=e;let o=!0,i=fe;if(r.shapeFlag&32){const l=t._;l?n&&l===1?o=!1:(_e(s,t),!n&&l===1&&delete s._):(o=!t.$stable,Nl(t,s)),i=t}else t&&(Ml(e,t),i={default:1});if(o)for(const l in s)!$l(l)&&i[l]==null&&delete s[l]};function ur(e,t,n,r,s=!1){if(z(e)){e.forEach((d,m)=>ur(d,t&&(z(t)?t[m]:t),n,r,s));return}if(kt(r)&&!s)return;const o=r.shapeFlag&4?oo(r.component)||r.component.proxy:r.el,i=s?null:o,{i:l,r:a}=e,u=t&&t.r,c=l.refs===fe?l.refs={}:l.refs,f=l.setupState;if(u!=null&&u!==a&&(pe(u)?(c[u]=null,ne(f,u)&&(f[u]=null)):ve(u)&&(u.value=null)),X(a))vt(a,l,12,[i,c]);else{const d=pe(a),m=ve(a);if(d||m){const v=()=>{if(e.f){const R=d?ne(f,a)?f[a]:c[a]:a.value;s?z(R)&&js(R,o):z(R)?R.includes(o)||R.push(o):d?(c[a]=[o],ne(f,a)&&(f[a]=c[a])):(a.value=[o],e.k&&(c[e.k]=a.value))}else d?(c[a]=i,ne(f,a)&&(f[a]=i)):m&&(a.value=i,e.k&&(c[e.k]=i))};i?(v.id=-1,be(v,n)):v()}}}let ut=!1;const Qn=e=>/svg/.test(e.namespaceURI)&&e.tagName!=="foreignObject",Jn=e=>e.nodeType===8;function Cu(e){const{mt:t,p:n,o:{patchProp:r,createText:s,nextSibling:o,parentNode:i,remove:l,insert:a,createComment:u}}=e,c=(y,g)=>{if(!g.hasChildNodes()){n(null,y,g),ir(),g._vnode=y;return}ut=!1,f(g.firstChild,y,null,null,null),ir(),g._vnode=y,ut&&console.error("Hydration completed but contains mismatches.")},f=(y,g,C,I,N,O=!1)=>{const D=Jn(y)&&y.data==="[",M=()=>R(y,g,C,I,N,D),{type:Q,ref:L,shapeFlag:J,patchFlag:ae}=g;let le=y.nodeType;g.el=y,ae===-2&&(O=!1,g.dynamicChildren=null);let U=null;switch(Q){case Jt:le!==3?g.children===""?(a(g.el=s(""),i(y),y),U=y):U=M():(y.data!==g.children&&(ut=!0,y.data=g.children),U=o(y));break;case Te:b(y)?(U=o(y),w(g.el=y.content.firstChild,y,C)):le!==8||D?U=M():U=o(y);break;case _n:if(D&&(y=o(y),le=y.nodeType),le===1||le===3){U=y;const Z=!g.children.length;for(let K=0;K{O=O||!!g.dynamicChildren;const{type:D,props:M,patchFlag:Q,shapeFlag:L,dirs:J,transition:ae}=g,le=D==="input"||D==="option";if(le||Q!==-1){if(J&&Je(g,null,C,"created"),M)if(le||!O||Q&48)for(const K in M)(le&&(K.endsWith("value")||K==="indeterminate")||Hn(K)&&!gn(K)||K[0]===".")&&r(y,K,null,M[K],!1,void 0,C);else M.onClick&&r(y,"onClick",null,M.onClick,!1,void 0,C);let U;(U=M&&M.onVnodeBeforeMount)&&xe(U,C,g);let Z=!1;if(b(y)){Z=Fl(I,ae)&&C&&C.vnode.props&&C.vnode.props.appear;const K=y.content.firstChild;Z&&ae.beforeEnter(K),w(K,y,C),g.el=y=K}if(J&&Je(g,null,C,"beforeMount"),((U=M&&M.onVnodeMounted)||J||Z)&&bl(()=>{U&&xe(U,C,g),Z&&ae.enter(y),J&&Je(g,null,C,"mounted")},I),L&16&&!(M&&(M.innerHTML||M.textContent))){let K=m(y.firstChild,g,y,C,I,N,O);for(;K;){ut=!0;const Fe=K;K=K.nextSibling,l(Fe)}}else L&8&&y.textContent!==g.children&&(ut=!0,y.textContent=g.children)}return y.nextSibling},m=(y,g,C,I,N,O,D)=>{D=D||!!g.dynamicChildren;const M=g.children,Q=M.length;for(let L=0;L{const{slotScopeIds:D}=g;D&&(N=N?N.concat(D):D);const M=i(y),Q=m(o(y),g,M,C,I,N,O);return Q&&Jn(Q)&&Q.data==="]"?o(g.anchor=Q):(ut=!0,a(g.anchor=u("]"),M,Q),Q)},R=(y,g,C,I,N,O)=>{if(ut=!0,g.el=null,O){const Q=k(y);for(;;){const L=o(y);if(L&&L!==Q)l(L);else break}}const D=o(y),M=i(y);return l(y),n(null,g,M,D,C,I,Qn(M),N),D},k=(y,g="[",C="]")=>{let I=0;for(;y;)if(y=o(y),y&&Jn(y)&&(y.data===g&&I++,y.data===C)){if(I===0)return o(y);I--}return y},w=(y,g,C)=>{const I=g.parentNode;I&&I.replaceChild(y,g);let N=C;for(;N;)N.vnode.el===g&&(N.vnode.el=N.subTree.el=y),N=N.parent},b=y=>y.nodeType===1&&y.tagName.toLowerCase()==="template";return[c,f]}const be=bl;function Pu(e){return jl(e)}function Tu(e){return jl(e,Cu)}function jl(e,t){const n=ns();n.__VUE__=!0;const{insert:r,remove:s,patchProp:o,createElement:i,createText:l,createComment:a,setText:u,setElementText:c,parentNode:f,nextSibling:d,setScopeId:m=Ge,insertStaticContent:v}=e,R=(h,p,_,E=null,T=null,A=null,j=!1,S=null,H=!!p.dynamicChildren)=>{if(h===p)return;h&&!Ke(h,p)&&(E=P(h),Ae(h,T,A,!0),h=null),p.patchFlag===-2&&(H=!1,p.dynamicChildren=null);const{type:x,ref:W,shapeFlag:B}=p;switch(x){case Jt:k(h,p,_,E);break;case Te:w(h,p,_,E);break;case _n:h==null&&b(p,_,E,j);break;case ke:L(h,p,_,E,T,A,j,S,H);break;default:B&1?C(h,p,_,E,T,A,j,S,H):B&6?J(h,p,_,E,T,A,j,S,H):(B&64||B&128)&&x.process(h,p,_,E,T,A,j,S,H,$)}W!=null&&T&&ur(W,h&&h.ref,A,p||h,!p)},k=(h,p,_,E)=>{if(h==null)r(p.el=l(p.children),_,E);else{const T=p.el=h.el;p.children!==h.children&&u(T,p.children)}},w=(h,p,_,E)=>{h==null?r(p.el=a(p.children||""),_,E):p.el=h.el},b=(h,p,_,E)=>{[h.el,h.anchor]=v(h.children,p,_,E,h.el,h.anchor)},y=({el:h,anchor:p},_,E)=>{let T;for(;h&&h!==p;)T=d(h),r(h,_,E),h=T;r(p,_,E)},g=({el:h,anchor:p})=>{let _;for(;h&&h!==p;)_=d(h),s(h),h=_;s(p)},C=(h,p,_,E,T,A,j,S,H)=>{j=j||p.type==="svg",h==null?I(p,_,E,T,A,j,S,H):D(h,p,T,A,j,S,H)},I=(h,p,_,E,T,A,j,S)=>{let H,x;const{type:W,props:B,shapeFlag:q,transition:Y,dirs:te}=h;if(H=h.el=i(h.type,A,B&&B.is,B),q&8?c(H,h.children):q&16&&O(h.children,H,null,E,T,A&&W!=="foreignObject",j,S),te&&Je(h,null,E,"created"),N(H,h,h.scopeId,j,E),B){for(const ie in B)ie!=="value"&&!gn(ie)&&o(H,ie,null,B[ie],A,h.children,E,T,we);"value"in B&&o(H,"value",null,B.value),(x=B.onVnodeBeforeMount)&&xe(x,E,h)}te&&Je(h,null,E,"beforeMount");const ce=Fl(T,Y);ce&&Y.beforeEnter(H),r(H,p,_),((x=B&&B.onVnodeMounted)||ce||te)&&be(()=>{x&&xe(x,E,h),ce&&Y.enter(H),te&&Je(h,null,E,"mounted")},T)},N=(h,p,_,E,T)=>{if(_&&m(h,_),E)for(let A=0;A{for(let x=H;x{const S=p.el=h.el;let{patchFlag:H,dynamicChildren:x,dirs:W}=p;H|=h.patchFlag&16;const B=h.props||fe,q=p.props||fe;let Y;_&&wt(_,!1),(Y=q.onVnodeBeforeUpdate)&&xe(Y,_,p,h),W&&Je(p,h,_,"beforeUpdate"),_&&wt(_,!0);const te=T&&p.type!=="foreignObject";if(x?M(h.dynamicChildren,x,S,_,E,te,A):j||K(h,p,S,null,_,E,te,A,!1),H>0){if(H&16)Q(S,p,B,q,_,E,T);else if(H&2&&B.class!==q.class&&o(S,"class",null,q.class,T),H&4&&o(S,"style",B.style,q.style,T),H&8){const ce=p.dynamicProps;for(let ie=0;ie{Y&&xe(Y,_,p,h),W&&Je(p,h,_,"updated")},E)},M=(h,p,_,E,T,A,j)=>{for(let S=0;S{if(_!==E){if(_!==fe)for(const S in _)!gn(S)&&!(S in E)&&o(h,S,_[S],null,j,p.children,T,A,we);for(const S in E){if(gn(S))continue;const H=E[S],x=_[S];H!==x&&S!=="value"&&o(h,S,x,H,j,p.children,T,A,we)}"value"in E&&o(h,"value",_.value,E.value)}},L=(h,p,_,E,T,A,j,S,H)=>{const x=p.el=h?h.el:l(""),W=p.anchor=h?h.anchor:l("");let{patchFlag:B,dynamicChildren:q,slotScopeIds:Y}=p;Y&&(S=S?S.concat(Y):Y),h==null?(r(x,_,E),r(W,_,E),O(p.children,_,W,T,A,j,S,H)):B>0&&B&64&&q&&h.dynamicChildren?(M(h.dynamicChildren,q,_,T,A,j,S),(p.key!=null||T&&p===T.subTree)&&Dl(h,p,!0)):K(h,p,_,W,T,A,j,S,H)},J=(h,p,_,E,T,A,j,S,H)=>{p.slotScopeIds=S,h==null?p.shapeFlag&512?T.ctx.activate(p,_,E,j,H):ae(p,_,E,T,A,j,H):le(h,p,H)},ae=(h,p,_,E,T,A,j)=>{const S=h.component=$u(h,E,T);if(jn(h)&&(S.ctx.renderer=$),Nu(S),S.asyncDep){if(T&&T.registerDep(S,U),!h.el){const H=S.subTree=de(Te);w(null,H,p,_)}return}U(S,h,p,_,T,A,j)},le=(h,p,_)=>{const E=p.component=h.component;if(Bc(h,p,_))if(E.asyncDep&&!E.asyncResolved){Z(E,p,_);return}else E.next=p,$c(E.update),E.update();else p.el=h.el,E.vnode=p},U=(h,p,_,E,T,A,j)=>{const S=()=>{if(h.isMounted){let{next:W,bu:B,u:q,parent:Y,vnode:te}=h,ce=W,ie;wt(h,!1),W?(W.el=te.el,Z(h,W,j)):W=te,B&&mn(B),(ie=W.props&&W.props.onVnodeBeforeUpdate)&&xe(ie,Y,W,te),wt(h,!0);const me=jr(h),De=h.subTree;h.subTree=me,R(De,me,f(De.el),P(De),h,T,A),W.el=me.el,ce===null&&Xs(h,me.el),q&&be(q,T),(ie=W.props&&W.props.onVnodeUpdated)&&be(()=>xe(ie,Y,W,te),T)}else{let W;const{el:B,props:q}=p,{bm:Y,m:te,parent:ce}=h,ie=kt(p);if(wt(h,!1),Y&&mn(Y),!ie&&(W=q&&q.onVnodeBeforeMount)&&xe(W,ce,p),wt(h,!0),B&&se){const me=()=>{h.subTree=jr(h),se(B,h.subTree,h,T,null)};ie?p.type.__asyncLoader().then(()=>!h.isUnmounted&&me()):me()}else{const me=h.subTree=jr(h);R(null,me,_,E,h,T,A),p.el=me.el}if(te&&be(te,T),!ie&&(W=q&&q.onVnodeMounted)){const me=p;be(()=>xe(W,ce,me),T)}(p.shapeFlag&256||ce&&kt(ce.vnode)&&ce.vnode.shapeFlag&256)&&h.a&&be(h.a,T),h.isMounted=!0,p=_=E=null}},H=h.effect=new Bs(S,()=>wr(x),h.scope),x=h.update=()=>H.run();x.id=h.uid,wt(h,!0),x()},Z=(h,p,_)=>{p.component=h;const E=h.vnode.props;h.vnode=p,h.next=null,bu(h,p.props,E,_),Ru(h,p.children,_),rn(),xo(),sn()},K=(h,p,_,E,T,A,j,S,H=!1)=>{const x=h&&h.children,W=h?h.shapeFlag:0,B=p.children,{patchFlag:q,shapeFlag:Y}=p;if(q>0){if(q&128){at(x,B,_,E,T,A,j,S,H);return}else if(q&256){Fe(x,B,_,E,T,A,j,S,H);return}}Y&8?(W&16&&we(x,T,A),B!==x&&c(_,B)):W&16?Y&16?at(x,B,_,E,T,A,j,S,H):we(x,T,A,!0):(W&8&&c(_,""),Y&16&&O(B,_,E,T,A,j,S,H))},Fe=(h,p,_,E,T,A,j,S,H)=>{h=h||Bt,p=p||Bt;const x=h.length,W=p.length,B=Math.min(x,W);let q;for(q=0;qW?we(h,T,A,!0,!1,B):O(p,_,E,T,A,j,S,H,B)},at=(h,p,_,E,T,A,j,S,H)=>{let x=0;const W=p.length;let B=h.length-1,q=W-1;for(;x<=B&&x<=q;){const Y=h[x],te=p[x]=H?gt(p[x]):Ne(p[x]);if(Ke(Y,te))R(Y,te,_,null,T,A,j,S,H);else break;x++}for(;x<=B&&x<=q;){const Y=h[B],te=p[q]=H?gt(p[q]):Ne(p[q]);if(Ke(Y,te))R(Y,te,_,null,T,A,j,S,H);else break;B--,q--}if(x>B){if(x<=q){const Y=q+1,te=Yq)for(;x<=B;)Ae(h[x],T,A,!0),x++;else{const Y=x,te=x,ce=new Map;for(x=te;x<=q;x++){const Se=p[x]=H?gt(p[x]):Ne(p[x]);Se.key!=null&&ce.set(Se.key,x)}let ie,me=0;const De=q-te+1;let Nt=!1,yo=0;const cn=new Array(De);for(x=0;x=De){Ae(Se,T,A,!0);continue}let Qe;if(Se.key!=null)Qe=ce.get(Se.key);else for(ie=te;ie<=q;ie++)if(cn[ie-te]===0&&Ke(Se,p[ie])){Qe=ie;break}Qe===void 0?Ae(Se,T,A,!0):(cn[Qe-te]=x+1,Qe>=yo?yo=Qe:Nt=!0,R(Se,p[Qe],_,null,T,A,j,S,H),me++)}const _o=Nt?Au(cn):Bt;for(ie=_o.length-1,x=De-1;x>=0;x--){const Se=te+x,Qe=p[Se],vo=Se+1{const{el:A,type:j,transition:S,children:H,shapeFlag:x}=h;if(x&6){ze(h.component.subTree,p,_,E);return}if(x&128){h.suspense.move(p,_,E);return}if(x&64){j.move(h,p,_,$);return}if(j===ke){r(A,p,_);for(let B=0;BS.enter(A),T);else{const{leave:B,delayLeave:q,afterLeave:Y}=S,te=()=>r(A,p,_),ce=()=>{B(A,()=>{te(),Y&&Y()})};q?q(A,te,ce):ce()}else r(A,p,_)},Ae=(h,p,_,E=!1,T=!1)=>{const{type:A,props:j,ref:S,children:H,dynamicChildren:x,shapeFlag:W,patchFlag:B,dirs:q}=h;if(S!=null&&ur(S,null,_,h,!0),W&256){p.ctx.deactivate(h);return}const Y=W&1&&q,te=!kt(h);let ce;if(te&&(ce=j&&j.onVnodeBeforeUnmount)&&xe(ce,p,h),W&6)Dn(h.component,_,E);else{if(W&128){h.suspense.unmount(_,E);return}Y&&Je(h,null,p,"beforeUnmount"),W&64?h.type.remove(h,p,_,T,$,E):x&&(A!==ke||B>0&&B&64)?we(x,p,_,!1,!0):(A===ke&&B&384||!T&&W&16)&&we(H,p,_),E&&Ht(h)}(te&&(ce=j&&j.onVnodeUnmounted)||Y)&&be(()=>{ce&&xe(ce,p,h),Y&&Je(h,null,p,"unmounted")},_)},Ht=h=>{const{type:p,el:_,anchor:E,transition:T}=h;if(p===ke){$t(_,E);return}if(p===_n){g(h);return}const A=()=>{s(_),T&&!T.persisted&&T.afterLeave&&T.afterLeave()};if(h.shapeFlag&1&&T&&!T.persisted){const{leave:j,delayLeave:S}=T,H=()=>j(_,A);S?S(h.el,A,H):H()}else A()},$t=(h,p)=>{let _;for(;h!==p;)_=d(h),s(h),h=_;s(p)},Dn=(h,p,_)=>{const{bum:E,scope:T,update:A,subTree:j,um:S}=h;E&&mn(E),T.stop(),A&&(A.active=!1,Ae(j,h,p,_)),S&&be(S,p),be(()=>{h.isUnmounted=!0},p),p&&p.pendingBranch&&!p.isUnmounted&&h.asyncDep&&!h.asyncResolved&&h.suspenseId===p.pendingId&&(p.deps--,p.deps===0&&p.resolve())},we=(h,p,_,E=!1,T=!1,A=0)=>{for(let j=A;jh.shapeFlag&6?P(h.component.subTree):h.shapeFlag&128?h.suspense.next():d(h.anchor||h.el),F=(h,p,_)=>{h==null?p._vnode&&Ae(p._vnode,null,null,!0):R(p._vnode||null,h,p,null,null,null,_),xo(),ir(),p._vnode=h},$={p:R,um:Ae,m:ze,r:Ht,mt:ae,mc:O,pc:K,pbc:M,n:P,o:e};let V,se;return t&&([V,se]=t($)),{render:F,hydrate:V,createApp:_u(F,V)}}function wt({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function Fl(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Dl(e,t,n=!1){const r=e.children,s=t.children;if(z(r)&&z(s))for(let o=0;o>1,e[n[l]]0&&(t[r]=n[o-1]),n[o]=r)}}for(o=n.length,i=n[o-1];o-- >0;)n[o]=i,i=t[i];return n}const xu=e=>e.__isTeleport,ke=Symbol.for("v-fgt"),Jt=Symbol.for("v-txt"),Te=Symbol.for("v-cmt"),_n=Symbol.for("v-stc"),vn=[];let Me=null;function Ye(e=!1){vn.push(Me=e?null:[])}function Bl(){vn.pop(),Me=vn[vn.length-1]||null}let Xt=1;function Bo(e){Xt+=e}function Ul(e){return e.dynamicChildren=Xt>0?Me||Bt:null,Bl(),Xt>0&&Me&&Me.push(e),e}function ku(e,t,n,r,s,o){return Ul(Qt(e,t,n,r,s,o,!0))}function yt(e,t,n,r,s){return Ul(de(e,t,n,r,s,!0))}function Yt(e){return e?e.__v_isVNode===!0:!1}function Ke(e,t){return e.type===t.type&&e.key===t.key}const xr="__vInternal",Kl=({key:e})=>e??null,Zn=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?pe(e)||ve(e)||X(e)?{i:Ee,r:e,k:t,f:!!n}:e:null);function Qt(e,t=null,n=null,r=0,s=null,o=e===ke?0:1,i=!1,l=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Kl(t),ref:t&&Zn(t),scopeId:Cr,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:r,dynamicProps:s,dynamicChildren:null,appContext:null,ctx:Ee};return l?(ro(a,n),o&128&&e.normalize(a)):n&&(a.shapeFlag|=pe(n)?8:16),Xt>0&&!i&&Me&&(a.patchFlag>0||o&6)&&a.patchFlag!==32&&Me.push(a),a}const de=Ou;function Ou(e,t=null,n=null,r=0,s=null,o=!1){if((!e||e===ml)&&(e=Te),Yt(e)){const l=it(e,t,!0);return n&&ro(l,n),Xt>0&&!o&&Me&&(l.shapeFlag&6?Me[Me.indexOf(e)]=l:Me.push(l)),l.patchFlag|=-2,l}if(Fu(e)&&(e=e.__vccOpts),t){t=Vl(t);let{class:l,style:a}=t;l&&!pe(l)&&(t.class=br(l)),ue(a)&&(ll(a)&&!z(a)&&(a=_e({},a)),t.style=vr(a))}const i=pe(e)?1:_l(e)?128:xu(e)?64:ue(e)?4:X(e)?2:0;return Qt(e,t,n,r,s,i,o,!0)}function Vl(e){return e?ll(e)||xr in e?_e({},e):e:null}function it(e,t,n=!1){const{props:r,ref:s,patchFlag:o,children:i}=e,l=t?Lu(r||{},t):r;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&Kl(l),ref:t&&t.ref?n&&s?z(s)?s.concat(Zn(t)):[s,Zn(t)]:Zn(t):s,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:i,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ke?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&it(e.ssContent),ssFallback:e.ssFallback&&it(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function no(e=" ",t=0){return de(Jt,null,e,t)}function Su(e,t){const n=de(_n,null,e);return n.staticCount=t,n}function ay(e="",t=!1){return t?(Ye(),yt(Te,null,e)):de(Te,null,e)}function Ne(e){return e==null||typeof e=="boolean"?de(Te):z(e)?de(ke,null,e.slice()):typeof e=="object"?gt(e):de(Jt,null,String(e))}function gt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:it(e)}function ro(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(z(t))n=16;else if(typeof t=="object")if(r&65){const s=t.default;s&&(s._c&&(s._d=!1),ro(e,s()),s._c&&(s._d=!0));return}else{n=32;const s=t._;!s&&!(xr in t)?t._ctx=Ee:s===3&&Ee&&(Ee.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else X(t)?(t={default:t,_ctx:Ee},n=32):(t=String(t),r&64?(n=16,t=[no(t)]):n=8);e.children=t,e.shapeFlag|=n}function Lu(...e){const t={};for(let n=0;nye||Ee;let so,Mt,Uo="__VUE_INSTANCE_SETTERS__";(Mt=ns()[Uo])||(Mt=ns()[Uo]=[]),Mt.push(e=>ye=e),so=e=>{Mt.length>1?Mt.forEach(t=>t(e)):Mt[0](e)};const Gt=e=>{so(e),e.scope.on()},Ot=()=>{ye&&ye.scope.off(),so(null)};function Wl(e){return e.vnode.shapeFlag&4}let Zt=!1;function Nu(e,t=!1){Zt=t;const{props:n,children:r}=e.vnode,s=Wl(e);vu(e,n,s,t),wu(e,r);const o=s?Mu(e,t):void 0;return Zt=!1,o}function Mu(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=al(new Proxy(e.ctx,uu));const{setup:r}=n;if(r){const s=e.setupContext=r.length>1?zl(e):null;Gt(e),rn();const o=vt(r,e,0,[e.props,s]);if(sn(),Ot(),Ki(o)){if(o.then(Ot,Ot),t)return o.then(i=>{hs(e,i,t)}).catch(i=>{on(i,e,0)});e.asyncDep=o}else hs(e,o,t)}else ql(e,t)}function hs(e,t,n){X(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:ue(t)&&(e.setupState=ul(t)),ql(e,n)}let Ko;function ql(e,t,n){const r=e.type;if(!e.render){if(!t&&Ko&&!r.render){const s=r.template||eo(e).template;if(s){const{isCustomElement:o,compilerOptions:i}=e.appContext.config,{delimiters:l,compilerOptions:a}=r,u=_e(_e({isCustomElement:o,delimiters:l},i),a);r.render=Ko(s,u)}}e.render=r.render||Ge}{Gt(e),rn();try{du(e)}finally{sn(),Ot()}}}function ju(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return Oe(e,"get","$attrs"),t[n]}}))}function zl(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return ju(e)},slots:e.slots,emit:e.emit,expose:t}}function oo(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(ul(al(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in yn)return yn[n](e)},has(t,n){return n in t||n in yn}}))}function ps(e,t=!0){return X(e)?e.displayName||e.name:e.name||t&&e.__name}function Fu(e){return X(e)&&"__vccOpts"in e}const Pe=(e,t)=>Lc(e,t,Zt);function Ve(e,t,n){const r=arguments.length;return r===2?ue(t)&&!z(t)?Yt(t)?de(e,null,[t]):de(e,t):de(e,null,t):(r>3?n=Array.prototype.slice.call(arguments,2):r===3&&Yt(n)&&(n=[n]),de(e,t,n))}const Du=Symbol.for("v-scx"),Bu=()=>He(Du),Ql="3.3.10",Uu="http://www.w3.org/2000/svg",At=typeof document<"u"?document:null,Vo=At&&At.createElement("template"),Ku={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const s=t?At.createElementNS(Uu,e):At.createElement(e,n?{is:n}:void 0);return e==="select"&&r&&r.multiple!=null&&s.setAttribute("multiple",r.multiple),s},createText:e=>At.createTextNode(e),createComment:e=>At.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>At.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,s,o){const i=n?n.previousSibling:t.lastChild;if(s&&(s===o||s.nextSibling))for(;t.insertBefore(s.cloneNode(!0),n),!(s===o||!(s=s.nextSibling)););else{Vo.innerHTML=r?`${e}`:e;const l=Vo.content;if(r){const a=l.firstChild;for(;a.firstChild;)l.appendChild(a.firstChild);l.removeChild(a)}t.insertBefore(l,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},ft="transition",un="animation",On=Symbol("_vtc"),io=(e,{slots:t})=>Ve(Zc,Vu(e),t);io.displayName="Transition";const Jl={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};io.props=_e({},wl,Jl);const Rt=(e,t=[])=>{z(e)?e.forEach(n=>n(...t)):e&&e(...t)},Wo=e=>e?z(e)?e.some(t=>t.length>1):e.length>1:!1;function Vu(e){const t={};for(const L in e)L in Jl||(t[L]=e[L]);if(e.css===!1)return t;const{name:n="v",type:r,duration:s,enterFromClass:o=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:a=o,appearActiveClass:u=i,appearToClass:c=l,leaveFromClass:f=`${n}-leave-from`,leaveActiveClass:d=`${n}-leave-active`,leaveToClass:m=`${n}-leave-to`}=e,v=Wu(s),R=v&&v[0],k=v&&v[1],{onBeforeEnter:w,onEnter:b,onEnterCancelled:y,onLeave:g,onLeaveCancelled:C,onBeforeAppear:I=w,onAppear:N=b,onAppearCancelled:O=y}=t,D=(L,J,ae)=>{Ct(L,J?c:l),Ct(L,J?u:i),ae&&ae()},M=(L,J)=>{L._isLeaving=!1,Ct(L,f),Ct(L,m),Ct(L,d),J&&J()},Q=L=>(J,ae)=>{const le=L?N:b,U=()=>D(J,L,ae);Rt(le,[J,U]),qo(()=>{Ct(J,L?a:o),dt(J,L?c:l),Wo(le)||zo(J,r,R,U)})};return _e(t,{onBeforeEnter(L){Rt(w,[L]),dt(L,o),dt(L,i)},onBeforeAppear(L){Rt(I,[L]),dt(L,a),dt(L,u)},onEnter:Q(!1),onAppear:Q(!0),onLeave(L,J){L._isLeaving=!0;const ae=()=>M(L,J);dt(L,f),Qu(),dt(L,d),qo(()=>{L._isLeaving&&(Ct(L,f),dt(L,m),Wo(g)||zo(L,r,k,ae))}),Rt(g,[L,ae])},onEnterCancelled(L){D(L,!1),Rt(y,[L])},onAppearCancelled(L){D(L,!0),Rt(O,[L])},onLeaveCancelled(L){M(L),Rt(C,[L])}})}function Wu(e){if(e==null)return null;if(ue(e))return[Vr(e.enter),Vr(e.leave)];{const t=Vr(e);return[t,t]}}function Vr(e){return qi(e)}function dt(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[On]||(e[On]=new Set)).add(t)}function Ct(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const n=e[On];n&&(n.delete(t),n.size||(e[On]=void 0))}function qo(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let qu=0;function zo(e,t,n,r){const s=e._endId=++qu,o=()=>{s===e._endId&&r()};if(n)return setTimeout(o,n);const{type:i,timeout:l,propCount:a}=zu(e,t);if(!i)return r();const u=i+"end";let c=0;const f=()=>{e.removeEventListener(u,d),o()},d=m=>{m.target===e&&++c>=a&&f()};setTimeout(()=>{c(n[v]||"").split(", "),s=r(`${ft}Delay`),o=r(`${ft}Duration`),i=Qo(s,o),l=r(`${un}Delay`),a=r(`${un}Duration`),u=Qo(l,a);let c=null,f=0,d=0;t===ft?i>0&&(c=ft,f=i,d=o.length):t===un?u>0&&(c=un,f=u,d=a.length):(f=Math.max(i,u),c=f>0?i>u?ft:un:null,d=c?c===ft?o.length:a.length:0);const m=c===ft&&/\b(transform|all)(,|$)/.test(r(`${ft}Property`).toString());return{type:c,timeout:f,propCount:d,hasTransform:m}}function Qo(e,t){for(;e.lengthJo(n)+Jo(e[r])))}function Jo(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function Qu(){return document.body.offsetHeight}function Ju(e,t,n){const r=e[On];r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Xu=Symbol("_vod");function Yu(e,t,n){const r=e.style,s=pe(n);if(n&&!s){if(t&&!pe(t))for(const o in t)n[o]==null&&gs(r,o,"");for(const o in n)gs(r,o,n[o])}else{const o=r.display;s?t!==n&&(r.cssText=n):t&&e.removeAttribute("style"),Xu in e&&(r.display=o)}}const Xo=/\s*!important$/;function gs(e,t,n){if(z(n))n.forEach(r=>gs(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=Gu(e,t);Xo.test(n)?e.setProperty(nn(r),n.replace(Xo,""),"important"):e[r]=n}}const Yo=["Webkit","Moz","ms"],Wr={};function Gu(e,t){const n=Wr[t];if(n)return n;let r=et(t);if(r!=="filter"&&r in e)return Wr[t]=r;r=_r(r);for(let s=0;sqr||(of.then(()=>qr=0),qr=Date.now());function af(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;je(cf(r,n.value),t,5,[r])};return n.value=e,n.attached=lf(),n}function cf(e,t){if(z(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>s=>!s._stopped&&r&&r(s))}else return t}const ti=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,uf=(e,t,n,r,s=!1,o,i,l,a)=>{t==="class"?Ju(e,r,s):t==="style"?Yu(e,n,r):Hn(t)?Ms(t)||rf(e,t,n,r,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):ff(e,t,r,s))?ef(e,t,r,o,i,l,a):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Zu(e,t,r,s))};function ff(e,t,n,r){if(r)return!!(t==="innerHTML"||t==="textContent"||t in e&&ti(t)&&X(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const s=e.tagName;return!(s==="IMG"||s==="VIDEO"||s==="CANVAS"||s==="SOURCE")}return ti(t)&&pe(n)?!1:t in e}const Xl=_e({patchProp:uf},Ku);let bn,ni=!1;function df(){return bn||(bn=Pu(Xl))}function hf(){return bn=ni?bn:Tu(Xl),ni=!0,bn}const pf=(...e)=>{const t=df().createApp(...e),{mount:n}=t;return t.mount=r=>{const s=Yl(r);if(!s)return;const o=t._component;!X(o)&&!o.render&&!o.template&&(o.template=s.innerHTML),s.innerHTML="";const i=n(s,!1,s instanceof SVGElement);return s instanceof Element&&(s.removeAttribute("v-cloak"),s.setAttribute("data-v-app","")),i},t},gf=(...e)=>{const t=hf().createApp(...e),{mount:n}=t;return t.mount=r=>{const s=Yl(r);if(s)return n(s,!0,s instanceof SVGElement)},t};function Yl(e){return pe(e)?document.querySelector(e):e}const mf=/#/g,yf=/&/g,_f=/\//g,vf=/=/g,lo=/\+/g,bf=/%5e/gi,Ef=/%60/gi,wf=/%7c/gi,Rf=/%20/gi;function Cf(e){return encodeURI(""+e).replace(wf,"|")}function ms(e){return Cf(typeof e=="string"?e:JSON.stringify(e)).replace(lo,"%2B").replace(Rf,"+").replace(mf,"%23").replace(yf,"%26").replace(Ef,"`").replace(bf,"^").replace(_f,"%2F")}function zr(e){return ms(e).replace(vf,"%3D")}function fr(e=""){try{return decodeURIComponent(""+e)}catch{return""+e}}function Pf(e){return fr(e.replace(lo," "))}function Tf(e){return fr(e.replace(lo," "))}function Gl(e=""){const t={};e[0]==="?"&&(e=e.slice(1));for(const n of e.split("&")){const r=n.match(/([^=]+)=?(.*)/)||[];if(r.length<2)continue;const s=Pf(r[1]);if(s==="__proto__"||s==="constructor")continue;const o=Tf(r[2]||"");t[s]===void 0?t[s]=o:Array.isArray(t[s])?t[s].push(o):t[s]=[t[s],o]}return t}function Af(e,t){return(typeof t=="number"||typeof t=="boolean")&&(t=String(t)),t?Array.isArray(t)?t.map(n=>`${zr(e)}=${ms(n)}`).join("&"):`${zr(e)}=${ms(t)}`:zr(e)}function xf(e){return Object.keys(e).filter(t=>e[t]!==void 0).map(t=>Af(t,e[t])).filter(Boolean).join("&")}const kf=/^[\s\w\0+.-]{2,}:([/\\]{1,2})/,Of=/^[\s\w\0+.-]{2,}:([/\\]{2})?/,Sf=/^([/\\]\s*){2,}[^/\\]/,Lf=/^[\s\0]*(blob|data|javascript|vbscript):$/i,If=/\/$|\/\?|\/#/,Hf=/^\.?\//;function It(e,t={}){return typeof t=="boolean"&&(t={acceptRelative:t}),t.strict?kf.test(e):Of.test(e)||(t.acceptRelative?Sf.test(e):!1)}function $f(e){return!!e&&Lf.test(e)}function ys(e="",t){return t?If.test(e):e.endsWith("/")}function Or(e="",t){if(!t)return(ys(e)?e.slice(0,-1):e)||"/";if(!ys(e,!0))return e||"/";let n=e,r="";const s=e.indexOf("#");s>=0&&(n=e.slice(0,s),r=e.slice(s));const[o,...i]=n.split("?");return(o.slice(0,-1)||"/")+(i.length>0?`?${i.join("?")}`:"")+r}function dr(e="",t){if(!t)return e.endsWith("/")?e:e+"/";if(ys(e,!0))return e||"/";let n=e,r="";const s=e.indexOf("#");if(s>=0&&(n=e.slice(0,s),r=e.slice(s),!n))return r;const[o,...i]=n.split("?");return o+"/"+(i.length>0?`?${i.join("?")}`:"")+r}function Nf(e=""){return e.startsWith("/")}function ri(e=""){return Nf(e)?e:"/"+e}function cy(e,t){if(Zl(t)||It(e))return e;const n=Or(t);return e.startsWith(n)?e:an(n,e)}function si(e,t){if(Zl(t))return e;const n=Or(t);if(!e.startsWith(n))return e;const r=e.slice(n.length);return r[0]==="/"?r:"/"+r}function Mf(e,t){const n=Fn(e),r={...Gl(n.search),...t};return n.search=xf(r),Df(n)}function Zl(e){return!e||e==="/"}function jf(e){return e&&e!=="/"}function an(e,...t){let n=e||"";for(const r of t.filter(s=>jf(s)))if(n){const s=r.replace(Hf,"");n=dr(n)+s}else n=r;return n}function Ff(e,t,n={}){return n.trailingSlash||(e=dr(e),t=dr(t)),n.leadingSlash||(e=ri(e),t=ri(t)),n.encoding||(e=fr(e),t=fr(t)),e===t}const ea=Symbol.for("ufo:protocolRelative");function Fn(e="",t){const n=e.match(/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i);if(n){const[,f,d=""]=n;return{protocol:f.toLowerCase(),pathname:d,href:f+d,auth:"",host:"",search:"",hash:""}}if(!It(e,{acceptRelative:!0}))return t?Fn(t+e):oi(e);const[,r="",s,o=""]=e.replace(/\\/g,"/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/)||[],[,i="",l=""]=o.match(/([^#/?]*)(.*)?/)||[],{pathname:a,search:u,hash:c}=oi(l.replace(/\/(?=[A-Za-z]:)/,""));return{protocol:r.toLowerCase(),auth:s?s.slice(0,Math.max(0,s.length-1)):"",host:i,pathname:a,search:u,hash:c,[ea]:!r}}function oi(e=""){const[t="",n="",r=""]=(e.match(/([^#?]*)(\?[^#]*)?(#.*)?/)||[]).splice(1);return{pathname:t,search:n,hash:r}}function Df(e){const t=e.pathname||"",n=e.search?(e.search.startsWith("?")?"":"?")+e.search:"",r=e.hash||"",s=e.auth?e.auth+"@":"",o=e.host||"";return(e.protocol||e[ea]?(e.protocol||"")+"//":"")+s+o+t+n+r}const Bf=()=>{var e;return((e=window==null?void 0:window.__NUXT__)==null?void 0:e.config)||{}},hr=Bf().app,Uf=()=>hr.baseURL,Kf=()=>hr.buildAssetsDir,ao=(...e)=>an(ta(),Kf(),...e),ta=(...e)=>{const t=hr.cdnURL||hr.baseURL;return e.length?an(t,...e):t};globalThis.__buildAssetsURL=ao,globalThis.__publicAssetsURL=ta;const Vf=/"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,Wf=/"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,qf=/^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;function zf(e,t){if(e==="__proto__"||e==="constructor"&&t&&typeof t=="object"&&"prototype"in t){Qf(e);return}return t}function Qf(e){console.warn(`[destr] Dropping "${e}" key to prevent prototype pollution.`)}function Jf(e,t={}){if(typeof e!="string")return e;const n=e.trim();if(e[0]==='"'&&e.at(-1)==='"'&&!e.includes("\\"))return n.slice(1,-1);if(n.length<=9){const r=n.toLowerCase();if(r==="true")return!0;if(r==="false")return!1;if(r==="undefined")return;if(r==="null")return null;if(r==="nan")return Number.NaN;if(r==="infinity")return Number.POSITIVE_INFINITY;if(r==="-infinity")return Number.NEGATIVE_INFINITY}if(!qf.test(e)){if(t.strict)throw new SyntaxError("[destr] Invalid JSON");return e}try{if(Vf.test(e)||Wf.test(e)){if(t.strict)throw new Error("[destr] Possible prototype pollution");return JSON.parse(e,zf)}return JSON.parse(e)}catch(r){if(t.strict)throw r;return e}}const Xf=/#/g,Yf=/&/g,Gf=/=/g,co=/\+/g,Zf=/%5e/gi,ed=/%60/gi,td=/%7c/gi,nd=/%20/gi;function rd(e){return encodeURI(""+e).replace(td,"|")}function _s(e){return rd(typeof e=="string"?e:JSON.stringify(e)).replace(co,"%2B").replace(nd,"+").replace(Xf,"%23").replace(Yf,"%26").replace(ed,"`").replace(Zf,"^")}function Qr(e){return _s(e).replace(Gf,"%3D")}function na(e=""){try{return decodeURIComponent(""+e)}catch{return""+e}}function sd(e){return na(e.replace(co," "))}function od(e){return na(e.replace(co," "))}function id(e=""){const t={};e[0]==="?"&&(e=e.slice(1));for(const n of e.split("&")){const r=n.match(/([^=]+)=?(.*)/)||[];if(r.length<2)continue;const s=sd(r[1]);if(s==="__proto__"||s==="constructor")continue;const o=od(r[2]||"");t[s]===void 0?t[s]=o:Array.isArray(t[s])?t[s].push(o):t[s]=[t[s],o]}return t}function ld(e,t){return(typeof t=="number"||typeof t=="boolean")&&(t=String(t)),t?Array.isArray(t)?t.map(n=>`${Qr(e)}=${_s(n)}`).join("&"):`${Qr(e)}=${_s(t)}`:Qr(e)}function ad(e){return Object.keys(e).filter(t=>e[t]!==void 0).map(t=>ld(t,e[t])).filter(Boolean).join("&")}const cd=/^[\s\w\0+.-]{2,}:([/\\]{1,2})/,ud=/^[\s\w\0+.-]{2,}:([/\\]{2})?/,fd=/^([/\\]\s*){2,}[^/\\]/;function ra(e,t={}){return typeof t=="boolean"&&(t={acceptRelative:t}),t.strict?cd.test(e):ud.test(e)||(t.acceptRelative?fd.test(e):!1)}const dd=/\/$|\/\?|\/#/;function vs(e="",t){return t?dd.test(e):e.endsWith("/")}function hd(e="",t){if(!t)return(vs(e)?e.slice(0,-1):e)||"/";if(!vs(e,!0))return e||"/";let n=e,r="";const s=e.indexOf("#");s>=0&&(n=e.slice(0,s),r=e.slice(s));const[o,...i]=n.split("?");return(o.slice(0,-1)||"/")+(i.length>0?`?${i.join("?")}`:"")+r}function pd(e="",t){if(!t)return e.endsWith("/")?e:e+"/";if(vs(e,!0))return e||"/";let n=e,r="";const s=e.indexOf("#");if(s>=0&&(n=e.slice(0,s),r=e.slice(s),!n))return r;const[o,...i]=n.split("?");return o+"/"+(i.length>0?`?${i.join("?")}`:"")+r}function gd(e,t){if(yd(t)||ra(e))return e;const n=hd(t);return e.startsWith(n)?e:bd(n,e)}function md(e,t){const n=sa(e),r={...id(n.search),...t};return n.search=ad(r),Ed(n)}function yd(e){return!e||e==="/"}function _d(e){return e&&e!=="/"}const vd=/^\.?\//;function bd(e,...t){let n=e||"";for(const r of t.filter(s=>_d(s)))if(n){const s=r.replace(vd,"");n=pd(n)+s}else n=r;return n}function sa(e="",t){const n=e.match(/^[\s\0]*(blob:|data:|javascript:|vbscript:)(.*)/i);if(n){const[,f,d=""]=n;return{protocol:f.toLowerCase(),pathname:d,href:f+d,auth:"",host:"",search:"",hash:""}}if(!ra(e,{acceptRelative:!0}))return t?sa(t+e):ii(e);const[,r="",s,o=""]=e.replace(/\\/g,"/").match(/^[\s\0]*([\w+.-]{2,}:)?\/\/([^/@]+@)?(.*)/)||[],[,i="",l=""]=o.match(/([^#/?]*)(.*)?/)||[],{pathname:a,search:u,hash:c}=ii(l.replace(/\/(?=[A-Za-z]:)/,""));return{protocol:r.toLowerCase(),auth:s?s.slice(0,Math.max(0,s.length-1)):"",host:i,pathname:a,search:u,hash:c}}function ii(e=""){const[t="",n="",r=""]=(e.match(/([^#?]*)(\?[^#]*)?(#.*)?/)||[]).splice(1);return{pathname:t,search:n,hash:r}}function Ed(e){const t=e.pathname||"",n=e.search?(e.search.startsWith("?")?"":"?")+e.search:"",r=e.hash||"",s=e.auth?e.auth+"@":"",o=e.host||"";return(e.protocol?e.protocol+"//":"")+s+o+t+n+r}class wd extends Error{constructor(t,n){super(t,n),this.name="FetchError",n!=null&&n.cause&&!this.cause&&(this.cause=n.cause)}}function Rd(e){var a,u,c,f,d;const t=((a=e.error)==null?void 0:a.message)||((u=e.error)==null?void 0:u.toString())||"",n=((c=e.request)==null?void 0:c.method)||((f=e.options)==null?void 0:f.method)||"GET",r=((d=e.request)==null?void 0:d.url)||String(e.request)||"/",s=`[${n}] ${JSON.stringify(r)}`,o=e.response?`${e.response.status} ${e.response.statusText}`:"",i=`${s}: ${o}${t?` ${t}`:""}`,l=new wd(i,e.error?{cause:e.error}:void 0);for(const m of["request","options","response"])Object.defineProperty(l,m,{get(){return e[m]}});for(const[m,v]of[["data","_data"],["status","status"],["statusCode","status"],["statusText","statusText"],["statusMessage","statusText"]])Object.defineProperty(l,m,{get(){return e.response&&e.response[v]}});return l}const Cd=new Set(Object.freeze(["PATCH","POST","PUT","DELETE"]));function li(e="GET"){return Cd.has(e.toUpperCase())}function Pd(e){if(e===void 0)return!1;const t=typeof e;return t==="string"||t==="number"||t==="boolean"||t===null?!0:t!=="object"?!1:Array.isArray(e)?!0:e.buffer?!1:e.constructor&&e.constructor.name==="Object"||typeof e.toJSON=="function"}const Td=new Set(["image/svg","application/xml","application/xhtml","application/html"]),Ad=/^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;function xd(e=""){if(!e)return"json";const t=e.split(";").shift()||"";return Ad.test(t)?"json":Td.has(t)||t.startsWith("text/")?"text":"blob"}function kd(e,t,n=globalThis.Headers){const r={...t,...e};if(t!=null&&t.params&&(e!=null&&e.params)&&(r.params={...t==null?void 0:t.params,...e==null?void 0:e.params}),t!=null&&t.query&&(e!=null&&e.query)&&(r.query={...t==null?void 0:t.query,...e==null?void 0:e.query}),t!=null&&t.headers&&(e!=null&&e.headers)){r.headers=new n((t==null?void 0:t.headers)||{});for(const[s,o]of new n((e==null?void 0:e.headers)||{}))r.headers.set(s,o)}return r}const Od=new Set([408,409,425,429,500,502,503,504]),Sd=new Set([101,204,205,304]);function oa(e={}){const{fetch:t=globalThis.fetch,Headers:n=globalThis.Headers,AbortController:r=globalThis.AbortController}=e;async function s(l){const a=l.error&&l.error.name==="AbortError"&&!l.options.timeout||!1;if(l.options.retry!==!1&&!a){let c;typeof l.options.retry=="number"?c=l.options.retry:c=li(l.options.method)?0:1;const f=l.response&&l.response.status||500;if(c>0&&(Array.isArray(l.options.retryStatusCodes)?l.options.retryStatusCodes.includes(f):Od.has(f))){const d=l.options.retryDelay||0;return d>0&&await new Promise(m=>setTimeout(m,d)),o(l.request,{...l.options,retry:c-1,timeout:l.options.timeout})}}const u=Rd(l);throw Error.captureStackTrace&&Error.captureStackTrace(u,o),u}const o=async function(a,u={}){var d;const c={request:a,options:kd(u,e.defaults,n),response:void 0,error:void 0};if(c.options.method=(d=c.options.method)==null?void 0:d.toUpperCase(),c.options.onRequest&&await c.options.onRequest(c),typeof c.request=="string"&&(c.options.baseURL&&(c.request=gd(c.request,c.options.baseURL)),(c.options.query||c.options.params)&&(c.request=md(c.request,{...c.options.params,...c.options.query}))),c.options.body&&li(c.options.method)&&(Pd(c.options.body)?(c.options.body=typeof c.options.body=="string"?c.options.body:JSON.stringify(c.options.body),c.options.headers=new n(c.options.headers||{}),c.options.headers.has("content-type")||c.options.headers.set("content-type","application/json"),c.options.headers.has("accept")||c.options.headers.set("accept","application/json")):("pipeTo"in c.options.body&&typeof c.options.body.pipeTo=="function"||typeof c.options.body.pipe=="function")&&("duplex"in c.options||(c.options.duplex="half"))),!c.options.signal&&c.options.timeout){const m=new r;setTimeout(()=>m.abort(),c.options.timeout),c.options.signal=m.signal}try{c.response=await t(c.request,c.options)}catch(m){return c.error=m,c.options.onRequestError&&await c.options.onRequestError(c),await s(c)}if(c.response.body&&!Sd.has(c.response.status)&&c.options.method!=="HEAD"){const m=(c.options.parseResponse?"json":c.options.responseType)||xd(c.response.headers.get("content-type")||"");switch(m){case"json":{const v=await c.response.text(),R=c.options.parseResponse||Jf;c.response._data=R(v);break}case"stream":{c.response._data=c.response.body;break}default:c.response._data=await c.response[m]()}}return c.options.onResponse&&await c.options.onResponse(c),!c.options.ignoreResponseError&&c.response.status>=400&&c.response.status<600?(c.options.onResponseError&&await c.options.onResponseError(c),await s(c)):c.response},i=async function(a,u){return(await o(a,u))._data};return i.raw=o,i.native=(...l)=>t(...l),i.create=(l={})=>oa({...e,defaults:{...e.defaults,...l}}),i}const uo=function(){if(typeof globalThis<"u")return globalThis;if(typeof self<"u")return self;if(typeof window<"u")return window;if(typeof global<"u")return global;throw new Error("unable to locate global object")}(),Ld=uo.fetch||(()=>Promise.reject(new Error("[ofetch] global.fetch is not supported!"))),Id=uo.Headers,Hd=uo.AbortController,$d=oa({fetch:Ld,Headers:Id,AbortController:Hd}),Nd=$d;globalThis.$fetch||(globalThis.$fetch=Nd.create({baseURL:Uf()}));function bs(e,t={},n){for(const r in e){const s=e[r],o=n?`${n}:${r}`:r;typeof s=="object"&&s!==null?bs(s,t,o):typeof s=="function"&&(t[o]=s)}return t}const Md={run:e=>e()},jd=()=>Md,ia=typeof console.createTask<"u"?console.createTask:jd;function Fd(e,t){const n=t.shift(),r=ia(n);return e.reduce((s,o)=>s.then(()=>r.run(()=>o(...t))),Promise.resolve())}function Dd(e,t){const n=t.shift(),r=ia(n);return Promise.all(e.map(s=>r.run(()=>s(...t))))}function Jr(e,t){for(const n of[...e])n(t)}class Bd{constructor(){this._hooks={},this._before=void 0,this._after=void 0,this._deprecatedMessages=void 0,this._deprecatedHooks={},this.hook=this.hook.bind(this),this.callHook=this.callHook.bind(this),this.callHookWith=this.callHookWith.bind(this)}hook(t,n,r={}){if(!t||typeof n!="function")return()=>{};const s=t;let o;for(;this._deprecatedHooks[t];)o=this._deprecatedHooks[t],t=o.to;if(o&&!r.allowDeprecated){let i=o.message;i||(i=`${s} hook has been deprecated`+(o.to?`, please use ${o.to}`:"")),this._deprecatedMessages||(this._deprecatedMessages=new Set),this._deprecatedMessages.has(i)||(console.warn(i),this._deprecatedMessages.add(i))}if(!n.name)try{Object.defineProperty(n,"name",{get:()=>"_"+t.replace(/\W+/g,"_")+"_hook_cb",configurable:!0})}catch{}return this._hooks[t]=this._hooks[t]||[],this._hooks[t].push(n),()=>{n&&(this.removeHook(t,n),n=void 0)}}hookOnce(t,n){let r,s=(...o)=>(typeof r=="function"&&r(),r=void 0,s=void 0,n(...o));return r=this.hook(t,s),r}removeHook(t,n){if(this._hooks[t]){const r=this._hooks[t].indexOf(n);r!==-1&&this._hooks[t].splice(r,1),this._hooks[t].length===0&&delete this._hooks[t]}}deprecateHook(t,n){this._deprecatedHooks[t]=typeof n=="string"?{to:n}:n;const r=this._hooks[t]||[];delete this._hooks[t];for(const s of r)this.hook(t,s)}deprecateHooks(t){Object.assign(this._deprecatedHooks,t);for(const n in t)this.deprecateHook(n,t[n])}addHooks(t){const n=bs(t),r=Object.keys(n).map(s=>this.hook(s,n[s]));return()=>{for(const s of r.splice(0,r.length))s()}}removeHooks(t){const n=bs(t);for(const r in n)this.removeHook(r,n[r])}removeAllHooks(){for(const t in this._hooks)delete this._hooks[t]}callHook(t,...n){return n.unshift(t),this.callHookWith(Fd,t,...n)}callHookParallel(t,...n){return n.unshift(t),this.callHookWith(Dd,t,...n)}callHookWith(t,n,...r){const s=this._before||this._after?{name:n,args:r,context:{}}:void 0;this._before&&Jr(this._before,s);const o=t(n in this._hooks?[...this._hooks[n]]:[],r);return o instanceof Promise?o.finally(()=>{this._after&&s&&Jr(this._after,s)}):(this._after&&s&&Jr(this._after,s),o)}beforeEach(t){return this._before=this._before||[],this._before.push(t),()=>{if(this._before!==void 0){const n=this._before.indexOf(t);n!==-1&&this._before.splice(n,1)}}}afterEach(t){return this._after=this._after||[],this._after.push(t),()=>{if(this._after!==void 0){const n=this._after.indexOf(t);n!==-1&&this._after.splice(n,1)}}}}function la(){return new Bd}function Ud(e={}){let t,n=!1;const r=i=>{if(t&&t!==i)throw new Error("Context conflict")};let s;if(e.asyncContext){const i=e.AsyncLocalStorage||globalThis.AsyncLocalStorage;i?s=new i:console.warn("[unctx] `AsyncLocalStorage` is not provided.")}const o=()=>{if(s&&t===void 0){const i=s.getStore();if(i!==void 0)return i}return t};return{use:()=>{const i=o();if(i===void 0)throw new Error("Context is not available");return i},tryUse:()=>o(),set:(i,l)=>{l||r(i),t=i,n=!0},unset:()=>{t=void 0,n=!1},call:(i,l)=>{r(i),t=i;try{return s?s.run(i,l):l()}finally{n||(t=void 0)}},async callAsync(i,l){t=i;const a=()=>{t=i},u=()=>t===i?a:void 0;Es.add(u);try{const c=s?s.run(i,l):l();return n||(t=void 0),await c}finally{Es.delete(u)}}}}function Kd(e={}){const t={};return{get(n,r={}){return t[n]||(t[n]=Ud({...e,...r})),t[n],t[n]}}}const pr=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof global<"u"?global:typeof window<"u"?window:{},ai="__unctx__",Vd=pr[ai]||(pr[ai]=Kd()),Wd=(e,t={})=>Vd.get(e,t),ci="__unctx_async_handlers__",Es=pr[ci]||(pr[ci]=new Set);function Sn(e){const t=[];for(const s of Es){const o=s();o&&t.push(o)}const n=()=>{for(const s of t)s()};let r=e();return r&&typeof r=="object"&&"catch"in r&&(r=r.catch(s=>{throw n(),s})),[r,n]}const aa=Wd("nuxt-app",{asyncContext:!1}),qd="__nuxt_plugin";function zd(e){let t=0;const n={_scope:tc(),provide:void 0,globalName:"nuxt",versions:{get nuxt(){return"3.10.3"},get vue(){return n.vueApp.version}},payload:ot({data:{},state:{},once:new Set,_errors:{},...window.__NUXT__??{}}),static:{data:{}},runWithContext:s=>n._scope.run(()=>Xd(n,s)),isHydrating:!0,deferHydration(){if(!n.isHydrating)return()=>{};t++;let s=!1;return()=>{if(!s&&(s=!0,t--,t===0))return n.isHydrating=!1,n.callHook("app:suspense:resolve")}},_asyncDataPromises:{},_asyncData:{},_payloadRevivers:{},...e};n.hooks=la(),n.hook=n.hooks.hook,n.callHook=n.hooks.callHook,n.provide=(s,o)=>{const i="$"+s;Xn(n,i,o),Xn(n.vueApp.config.globalProperties,i,o)},Xn(n.vueApp,"$nuxt",n),Xn(n.vueApp.config.globalProperties,"$nuxt",n);{window.addEventListener("nuxt.preloadError",o=>{n.callHook("app:chunkError",{error:o.payload})}),window.useNuxtApp=window.useNuxtApp||ge;const s=n.hook("app:error",(...o)=>{console.error("[nuxt] error caught during app initialization",...o)});n.hook("app:mounted",s)}const r=ot(n.payload.config);return n.provide("config",r),n}async function Qd(e,t){if(t.hooks&&e.hooks.addHooks(t.hooks),typeof t=="function"){const{provide:n}=await e.runWithContext(()=>t(e))||{};if(n&&typeof n=="object")for(const r in n)e.provide(r,n[r])}}async function Jd(e,t){const n=[],r=[],s=[],o=[];let i=0;async function l(a){var c;const u=((c=a.dependsOn)==null?void 0:c.filter(f=>t.some(d=>d._name===f)&&!n.includes(f)))??[];if(u.length>0)r.push([new Set(u),a]);else{const f=Qd(e,a).then(async()=>{a._name&&(n.push(a._name),await Promise.all(r.map(async([d,m])=>{d.has(a._name)&&(d.delete(a._name),d.size===0&&(i++,await l(m)))})))});a.parallel?s.push(f.catch(d=>o.push(d))):await f}}for(const a of t)await l(a);if(await Promise.all(s),i)for(let a=0;a{}),e,{[qd]:!0,_name:t})}function Xd(e,t,n){const r=()=>n?t(...n):t();return aa.set(e),e.vueApp.runWithContext(r)}function Yd(){var t;let e;return Ll()&&(e=(t=kr())==null?void 0:t.appContext.app.$nuxt),e=e||aa.tryUse(),e||null}function ge(){const e=Yd();if(!e)throw new Error("[nuxt] instance unavailable");return e}function Sr(e){return ge().$config}function Xn(e,t,n){Object.defineProperty(e,t,{get:()=>n})}function Gd(e){return{ctx:{table:e},matchAll:t=>ua(t,e)}}function ca(e){const t={};for(const n in e)t[n]=n==="dynamic"?new Map(Object.entries(e[n]).map(([r,s])=>[r,ca(s)])):new Map(Object.entries(e[n]));return t}function Zd(e){return Gd(ca(e))}function ua(e,t){const n=[];for(const[s,o]of ui(t.wildcard))e.startsWith(s)&&n.push(o);for(const[s,o]of ui(t.dynamic))if(e.startsWith(s+"/")){const i="/"+e.slice(s.length).split("/").splice(2).join("/");n.push(...ua(i,o))}const r=t.static.get(e);return r&&n.push(r),n.filter(Boolean)}function ui(e){return[...e.entries()].sort((t,n)=>t[0].length-n[0].length)}const eh=/"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,th=/"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,nh=/^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;function rh(e,t){if(e==="__proto__"||e==="constructor"&&t&&typeof t=="object"&&"prototype"in t){sh(e);return}return t}function sh(e){console.warn(`[destr] Dropping "${e}" key to prevent prototype pollution.`)}function ws(e,t={}){if(typeof e!="string")return e;const n=e.trim();if(e[0]==='"'&&e.endsWith('"')&&!e.includes("\\"))return n.slice(1,-1);if(n.length<=9){const r=n.toLowerCase();if(r==="true")return!0;if(r==="false")return!1;if(r==="undefined")return;if(r==="null")return null;if(r==="nan")return Number.NaN;if(r==="infinity")return Number.POSITIVE_INFINITY;if(r==="-infinity")return Number.NEGATIVE_INFINITY}if(!nh.test(e)){if(t.strict)throw new SyntaxError("[destr] Invalid JSON");return e}try{if(eh.test(e)||th.test(e)){if(t.strict)throw new Error("[destr] Possible prototype pollution");return JSON.parse(e,rh)}return JSON.parse(e)}catch(r){if(t.strict)throw r;return e}}function Xr(e){if(e===null||typeof e!="object")return!1;const t=Object.getPrototypeOf(e);return t!==null&&t!==Object.prototype&&Object.getPrototypeOf(t)!==null||Symbol.iterator in e?!1:Symbol.toStringTag in e?Object.prototype.toString.call(e)==="[object Module]":!0}function Rs(e,t,n=".",r){if(!Xr(t))return Rs(e,{},n,r);const s=Object.assign({},t);for(const o in e){if(o==="__proto__"||o==="constructor")continue;const i=e[o];i!=null&&(r&&r(s,o,i,n)||(Array.isArray(i)&&Array.isArray(s[o])?s[o]=[...i,...s[o]]:Xr(i)&&Xr(s[o])?s[o]=Rs(i,s[o],(n?`${n}.`:"")+o.toString(),r):s[o]=i))}return s}function fa(e){return(...t)=>t.reduce((n,r)=>Rs(n,r,"",e),{})}const da=fa(),oh=fa((e,t,n)=>{if(e[t]!==void 0&&typeof n=="function")return e[t]=n(e[t]),!0});function ih(e,t){try{return t in e}catch{return!1}}var lh=Object.defineProperty,ah=(e,t,n)=>t in e?lh(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Pt=(e,t,n)=>(ah(e,typeof t!="symbol"?t+"":t,n),n);class Cs extends Error{constructor(t,n={}){super(t,n),Pt(this,"statusCode",500),Pt(this,"fatal",!1),Pt(this,"unhandled",!1),Pt(this,"statusMessage"),Pt(this,"data"),Pt(this,"cause"),n.cause&&!this.cause&&(this.cause=n.cause)}toJSON(){const t={message:this.message,statusCode:Ts(this.statusCode,500)};return this.statusMessage&&(t.statusMessage=ha(this.statusMessage)),this.data!==void 0&&(t.data=this.data),t}}Pt(Cs,"__h3_error__",!0);function Ps(e){if(typeof e=="string")return new Cs(e);if(ch(e))return e;const t=new Cs(e.message??e.statusMessage??"",{cause:e.cause||e});if(ih(e,"stack"))try{Object.defineProperty(t,"stack",{get(){return e.stack}})}catch{try{t.stack=e.stack}catch{}}if(e.data&&(t.data=e.data),e.statusCode?t.statusCode=Ts(e.statusCode,t.statusCode):e.status&&(t.statusCode=Ts(e.status,t.statusCode)),e.statusMessage?t.statusMessage=e.statusMessage:e.statusText&&(t.statusMessage=e.statusText),t.statusMessage){const n=t.statusMessage;ha(t.statusMessage)!==n&&console.warn("[h3] Please prefer using `message` for longer error messages instead of `statusMessage`. In the future, `statusMessage` will be sanitized by default.")}return e.fatal!==void 0&&(t.fatal=e.fatal),e.unhandled!==void 0&&(t.unhandled=e.unhandled),t}function ch(e){var t;return((t=e==null?void 0:e.constructor)==null?void 0:t.__h3_error__)===!0}const uh=/[^\u0009\u0020-\u007E]/g;function ha(e=""){return e.replace(uh,"")}function Ts(e,t=200){return!e||(typeof e=="string"&&(e=Number.parseInt(e,10)),e<100||e>999)?t:e}const fh=Symbol("layout-meta"),Lr=Symbol("route"),qe=()=>{var e;return(e=ge())==null?void 0:e.$router},pa=()=>Ll()?He(Lr,ge()._route):ge()._route;const dh=()=>{try{if(ge()._processingMiddleware)return!0}catch{return!0}return!1},hh=(e,t)=>{e||(e="/");const n=typeof e=="string"?e:Mf(e.path||"/",e.query||{})+(e.hash||"");if(t!=null&&t.open){{const{target:l="_blank",windowFeatures:a={}}=t.open,u=Object.entries(a).filter(([c,f])=>f!==void 0).map(([c,f])=>`${c.toLowerCase()}=${f}`).join(", ");open(n,l,u)}return Promise.resolve()}const r=(t==null?void 0:t.external)||It(n,{acceptRelative:!0});if(r){if(!(t!=null&&t.external))throw new Error("Navigating to an external URL is not allowed by default. Use `navigateTo(url, { external: true })`.");const l=Fn(n).protocol;if(l&&$f(l))throw new Error(`Cannot navigate to a URL with '${l}' protocol.`)}const s=dh();if(!r&&s)return e;const o=qe(),i=ge();return r?(i._scope.stop(),t!=null&&t.replace?location.replace(n):location.href=n,s?i.isHydrating?new Promise(()=>{}):!1:Promise.resolve()):t!=null&&t.replace?o.replace(e):o.push(e)},ga="__nuxt_error",Ir=()=>Oc(ge().payload,"error"),Dt=e=>{const t=Hr(e);try{const n=ge(),r=Ir();n.hooks.callHook("app:error",t),r.value=r.value||t}catch{throw t}return t},ph=async(e={})=>{const t=ge(),n=Ir();t.callHook("app:error:cleared",e),e.redirect&&await qe().replace(e.redirect),n.value=null},gh=e=>!!e&&typeof e=="object"&&ga in e,Hr=e=>{const t=Ps(e);return Object.defineProperty(t,ga,{value:!0,configurable:!1,writable:!1}),t},mh="modulepreload",yh=function(e,t){return e[0]==="."?new URL(e,t).href:e},fi={},_h=function(t,n,r){let s=Promise.resolve();if(n&&n.length>0){const o=document.getElementsByTagName("link");s=Promise.all(n.map(i=>{if(i=yh(i,r),i in fi)return;fi[i]=!0;const l=i.endsWith(".css"),a=l?'[rel="stylesheet"]':"";if(!!r)for(let f=o.length-1;f>=0;f--){const d=o[f];if(d.href===i&&(!l||d.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${i}"]${a}`))return;const c=document.createElement("link");if(c.rel=l?"stylesheet":mh,l||(c.as="script",c.crossOrigin=""),c.href=i,document.head.appendChild(c),l)return new Promise((f,d)=>{c.addEventListener("load",f),c.addEventListener("error",()=>d(new Error(`Unable to preload CSS for ${i}`)))})}))}return s.then(()=>t()).catch(o=>{const i=new Event("vite:preloadError",{cancelable:!0});if(i.payload=o,window.dispatchEvent(i),!i.defaultPrevented)throw o})},G=(...e)=>_h(...e).catch(t=>{const n=new Event("nuxt.preloadError");throw n.payload=t,window.dispatchEvent(n),t}),vh=-1,bh=-2,Eh=-3,wh=-4,Rh=-5,Ch=-6;function Ph(e,t){return Th(JSON.parse(e),t)}function Th(e,t){if(typeof e=="number")return s(e,!0);if(!Array.isArray(e)||e.length===0)throw new Error("Invalid input");const n=e,r=Array(n.length);function s(o,i=!1){if(o===vh)return;if(o===Eh)return NaN;if(o===wh)return 1/0;if(o===Rh)return-1/0;if(o===Ch)return-0;if(i)throw new Error("Invalid input");if(o in r)return r[o];const l=n[o];if(!l||typeof l!="object")r[o]=l;else if(Array.isArray(l))if(typeof l[0]=="string"){const a=l[0],u=t==null?void 0:t[a];if(u)return r[o]=u(s(l[1]));switch(a){case"Date":r[o]=new Date(l[1]);break;case"Set":const c=new Set;r[o]=c;for(let m=1;m>>9)+65536).toString(16).substring(1,8).toLowerCase()}function di(e){return e._h||fo(e._d?e._d:`${e.tag}:${e.textContent||e.innerHTML||""}:${Object.entries(e.props).map(([t,n])=>`${t}:${String(n)}`).join(",")}`)}function ya(e,t){const{props:n,tag:r}=e;if(Oh.includes(r))return r;if(r==="link"&&n.rel==="canonical")return"canonical";if(n.charset)return"charset";const s=["id"];r==="meta"&&s.push("name","property","http-equiv");for(const o of s)if(typeof n[o]<"u"){const i=String(n[o]);return t&&!t(i)?!1:`${r}:${o}:${i}`}return!1}function hi(e,t){return e==null?t||null:typeof e=="function"?e(t):e}async function Lh(e,t,n){const r={tag:e,props:await _a(typeof t=="object"&&typeof t!="function"&&!(t instanceof Promise)?{...t}:{[["script","noscript","style"].includes(e)?"innerHTML":"textContent"]:t},["templateParams","titleTemplate"].includes(e))};return ma.forEach(s=>{const o=typeof r.props[s]<"u"?r.props[s]:n[s];typeof o<"u"&&((!["innerHTML","textContent","children"].includes(s)||xh.includes(r.tag))&&(r[s==="children"?"innerHTML":s]=o),delete r.props[s])}),r.props.body&&(r.tagPosition="bodyClose",delete r.props.body),r.tag==="script"&&typeof r.innerHTML=="object"&&(r.innerHTML=JSON.stringify(r.innerHTML),r.props.type=r.props.type||"application/json"),Array.isArray(r.props.content)?r.props.content.map(s=>({...r,props:{...r.props,content:s}})):r}function Ih(e){return typeof e=="object"&&!Array.isArray(e)&&(e=Object.keys(e).filter(t=>e[t])),(Array.isArray(e)?e.join(" "):e).split(" ").filter(t=>t.trim()).filter(Boolean).join(" ")}async function _a(e,t){for(const n of Object.keys(e)){if(n==="class"){e[n]=Ih(e[n]);continue}if(e[n]instanceof Promise&&(e[n]=await e[n]),!t&&!ma.includes(n)){const r=String(e[n]),s=n.startsWith("data-");r==="true"||r===""?e[n]=s?"true":!0:e[n]||(s&&r==="false"?e[n]="false":delete e[n])}}return e}const Hh=10;async function $h(e){const t=[];return Object.entries(e.resolvedInput).filter(([n,r])=>typeof r<"u"&&kh.includes(n)).forEach(([n,r])=>{const s=Ah(r);t.push(...s.map(o=>Lh(n,o,e)).flat())}),(await Promise.all(t)).flat().filter(Boolean).map((n,r)=>(n._e=e._i,e.mode&&(n._m=e.mode),n._p=(e._i<a&&a[u]||void 0,t):l=t[i],typeof l<"u"?(l||"").replace(/"/g,'\\"'):!1}let s=e;try{s=decodeURI(e)}catch{}return(s.match(/%(\w+\.+\w+)|%(\w+)/g)||[]).sort().reverse().forEach(i=>{const l=r(i.slice(1));typeof l=="string"&&(e=e.replace(new RegExp(`\\${i}(\\W|$)`,"g"),(a,u)=>`${l}${u}`).trim())}),e.includes(ht)&&(e.endsWith(ht)&&(e=e.slice(0,-ht.length).trim()),e.startsWith(ht)&&(e=e.slice(ht.length).trim()),e=e.replace(new RegExp(`\\${ht}\\s*\\${ht}`,"g"),ht),e=tr(e,{separator:n},n)),e}async function Mh(e){const t={tag:e.tagName.toLowerCase(),props:await _a(e.getAttributeNames().reduce((n,r)=>({...n,[r]:e.getAttribute(r)}),{})),innerHTML:e.innerHTML};return t._d=ya(t),t}async function ba(e,t={}){var c;const n=t.document||e.resolvedOptions.document;if(!n)return;const r={shouldRender:e.dirty,tags:[]};if(await e.hooks.callHook("dom:beforeRender",r),!r.shouldRender)return;const s=(await e.resolveTags()).map(f=>({tag:f,id:er.includes(f.tag)?di(f):f.tag,shouldRender:!0}));let o=e._dom;if(!o){o={elMap:{htmlAttrs:n.documentElement,bodyAttrs:n.body}};for(const f of["body","head"]){const d=(c=n==null?void 0:n[f])==null?void 0:c.children;for(const m of[...d].filter(v=>er.includes(v.tagName.toLowerCase())))o.elMap[m.getAttribute("data-hid")||di(await Mh(m))]=m}}o.pendingSideEffects={...o.sideEffects||{}},o.sideEffects={};function i(f,d,m){const v=`${f}:${d}`;o.sideEffects[v]=m,delete o.pendingSideEffects[v]}function l({id:f,$el:d,tag:m}){const v=m.tag.endsWith("Attrs");o.elMap[f]=d,v||(["textContent","innerHTML"].forEach(R=>{m[R]&&m[R]!==d[R]&&(d[R]=m[R])}),i(f,"el",()=>{o.elMap[f].remove(),delete o.elMap[f]})),Object.entries(m.props).forEach(([R,k])=>{const w=`attr:${R}`;if(R==="class")for(const b of(k||"").split(" ").filter(Boolean))v&&i(f,`${w}:${b}`,()=>d.classList.remove(b)),!d.classList.contains(b)&&d.classList.add(b);else d.getAttribute(R)!==k&&d.setAttribute(R,k===!0?"":String(k)),v&&i(f,w,()=>d.removeAttribute(R))})}const a=[],u={bodyClose:void 0,bodyOpen:void 0,head:void 0};for(const f of s){const{tag:d,shouldRender:m,id:v}=f;if(m){if(d.tag==="title"){n.title=d.textContent;continue}f.$el=f.$el||o.elMap[v],f.$el?l(f):er.includes(d.tag)&&a.push(f)}}for(const f of a){const d=f.tag.tagPosition||"head";f.$el=n.createElement(f.tag.tag),l(f),u[d]=u[d]||n.createDocumentFragment(),u[d].appendChild(f.$el)}for(const f of s)await e.hooks.callHook("dom:renderTag",f,n,i);u.head&&n.head.appendChild(u.head),u.bodyOpen&&n.body.insertBefore(u.bodyOpen,n.body.firstChild),u.bodyClose&&n.body.appendChild(u.bodyClose),Object.values(o.pendingSideEffects).forEach(f=>f()),e._dom=o,e.dirty=!1,await e.hooks.callHook("dom:rendered",{renders:s})}async function jh(e,t={}){const n=t.delayFn||(r=>setTimeout(r,10));return e._domUpdatePromise=e._domUpdatePromise||new Promise(r=>n(async()=>{await ba(e,t),delete e._domUpdatePromise,r()}))}function Fh(e){return t=>{var r,s;const n=((s=(r=t.resolvedOptions.document)==null?void 0:r.head.querySelector('script[id="unhead:payload"]'))==null?void 0:s.innerHTML)||!1;return n&&t.push(JSON.parse(n)),{mode:"client",hooks:{"entries:updated":function(o){jh(o,e)}}}}}const Dh=["templateParams","htmlAttrs","bodyAttrs"],Bh={hooks:{"tag:normalise":function({tag:e}){["hid","vmid","key"].forEach(r=>{e.props[r]&&(e.key=e.props[r],delete e.props[r])});const n=ya(e)||(e.key?`${e.tag}:${e.key}`:!1);n&&(e._d=n)},"tags:resolve":function(e){const t={};e.tags.forEach(r=>{const s=(r.key?`${r.tag}:${r.key}`:r._d)||r._p,o=t[s];if(o){let l=r==null?void 0:r.tagDuplicateStrategy;if(!l&&Dh.includes(r.tag)&&(l="merge"),l==="merge"){const a=o.props;["class","style"].forEach(u=>{a[u]&&(r.props[u]?(u==="style"&&!a[u].endsWith(";")&&(a[u]+=";"),r.props[u]=`${a[u]} ${r.props[u]}`):r.props[u]=a[u])}),t[s].props={...a,...r.props};return}else if(r._e===o._e){o._duped=o._duped||[],r._d=`${o._d}:${o._duped.length+1}`,o._duped.push(r);return}else if(gr(r)>gr(o))return}const i=Object.keys(r.props).length+(r.innerHTML?1:0)+(r.textContent?1:0);if(er.includes(r.tag)&&i===0){delete t[s];return}t[s]=r});const n=[];Object.values(t).forEach(r=>{const s=r._duped;delete r._duped,n.push(r),s&&n.push(...s)}),e.tags=n,e.tags=e.tags.filter(r=>!(r.tag==="meta"&&(r.props.name||r.props.property)&&!r.props.content))}}},Uh={mode:"server",hooks:{"tags:resolve":function(e){const t={};e.tags.filter(n=>["titleTemplate","templateParams","title"].includes(n.tag)&&n._m==="server").forEach(n=>{t[n.tag]=n.tag.startsWith("title")?n.textContent:n.props}),Object.keys(t).length&&e.tags.push({tag:"script",innerHTML:JSON.stringify(t),props:{id:"unhead:payload",type:"application/json"}})}}},Kh=["script","link","bodyAttrs"];function Vh(e){const t={},n={};return Object.entries(e.props).forEach(([r,s])=>{r.startsWith("on")&&typeof s=="function"?(va.includes(r)&&(t[r]=`this.dataset.${r} = true`),n[r]=s):t[r]=s}),{props:t,eventHandlers:n}}const Wh=e=>({hooks:{"tags:resolve":function(t){for(const n of t.tags)if(Kh.includes(n.tag)){const{props:r,eventHandlers:s}=Vh(n);n.props=r,Object.keys(s).length&&((n.props.src||n.props.href)&&(n.key=n.key||fo(n.props.src||n.props.href)),n._eventHandlers=s)}},"dom:renderTag":function(t,n,r){if(!t.tag._eventHandlers)return;const s=t.tag.tag==="bodyAttrs"?n.defaultView:t.$el;Object.entries(t.tag._eventHandlers).forEach(([o,i])=>{const l=`${t.tag._d||t.tag._p}:${o}`,a=o.slice(2).toLowerCase(),u=`data-h-${a}`;if(r(t.id,l,()=>{}),t.$el.hasAttribute(u))return;t.$el.setAttribute(u,"");let c;const f=d=>{i(d),c==null||c.disconnect()};o in t.$el.dataset?f(new Event(o.replace("on",""))):va.includes(o)&&typeof MutationObserver<"u"?(c=new MutationObserver(d=>{d.some(v=>v.attributeName===`data-${o}`)&&(f(new Event(o.replace("on",""))),c==null||c.disconnect())}),c.observe(t.$el,{attributes:!0})):s.addEventListener(a,f),r(t.id,l,()=>{c==null||c.disconnect(),s.removeEventListener(a,f),t.$el.removeAttribute(u)})})}}}),qh=["link","style","script","noscript"],zh={hooks:{"tag:normalise":({tag:e})=>{e.key&&qh.includes(e.tag)&&(e.props["data-hid"]=e._h=fo(e.key))}}},Qh={hooks:{"tags:resolve":e=>{const t=n=>{var r;return(r=e.tags.find(s=>s._d===n))==null?void 0:r._p};for(const{prefix:n,offset:r}of Nh)for(const s of e.tags.filter(o=>typeof o.tagPriority=="string"&&o.tagPriority.startsWith(n))){const o=t(s.tagPriority.replace(n,""));typeof o<"u"&&(s._p=o+r)}e.tags.sort((n,r)=>n._p-r._p).sort((n,r)=>gr(n)-gr(r))}}},Jh={meta:"content",link:"href",htmlAttrs:"lang"},Xh=e=>({hooks:{"tags:resolve":t=>{var l;const{tags:n}=t,r=(l=n.find(a=>a.tag==="title"))==null?void 0:l.textContent,s=n.findIndex(a=>a.tag==="templateParams"),o=s!==-1?n[s].props:{},i=o.separator||"|";delete o.separator,o.pageTitle=tr(o.pageTitle||r||"",o,i);for(const a of n.filter(u=>u.processTemplateParams!==!1)){const u=Jh[a.tag];u&&typeof a.props[u]=="string"?a.props[u]=tr(a.props[u],o,i):(a.processTemplateParams===!0||["titleTemplate","title"].includes(a.tag))&&["innerHTML","textContent"].forEach(c=>{typeof a[c]=="string"&&(a[c]=tr(a[c],o,i))})}e._templateParams=o,e._separator=i,t.tags=n.filter(a=>a.tag!=="templateParams")}}}),Yh={hooks:{"tags:resolve":e=>{const{tags:t}=e;let n=t.findIndex(s=>s.tag==="titleTemplate");const r=t.findIndex(s=>s.tag==="title");if(r!==-1&&n!==-1){const s=hi(t[n].textContent,t[r].textContent);s!==null?t[r].textContent=s||t[r].textContent:delete t[r]}else if(n!==-1){const s=hi(t[n].textContent);s!==null&&(t[n].textContent=s,t[n].tag="title",n=-1)}n!==-1&&delete t[n],e.tags=t.filter(Boolean)}}},Gh={hooks:{"tags:afterResolve":function(e){for(const t of e.tags)typeof t.innerHTML=="string"&&(t.innerHTML&&["application/ld+json","application/json"].includes(t.props.type)?t.innerHTML=t.innerHTML.replace(/{l.dirty=!0,t.callHook("entries:updated",l)};let s=0,o=[];const i=[],l={plugins:i,dirty:!1,resolvedOptions:e,hooks:t,headEntries(){return o},use(a){const u=typeof a=="function"?a(l):a;(!u.key||!i.some(c=>c.key===u.key))&&(i.push(u),mi(u.mode,n)&&t.addHooks(u.hooks||{}))},push(a,u){u==null||delete u.head;const c={_i:s++,input:a,...u};return mi(c.mode,n)&&(o.push(c),r()),{dispose(){o=o.filter(f=>f._i!==c._i),t.callHook("entries:updated",l),r()},patch(f){o=o.map(d=>(d._i===c._i&&(d.input=c.input=f),d)),r()}}},async resolveTags(){const a={tags:[],entries:[...o]};await t.callHook("entries:resolve",a);for(const u of a.entries){const c=u.resolvedInput||u.input;if(u.resolvedInput=await(u.transform?u.transform(c):c),u.resolvedInput)for(const f of await $h(u)){const d={tag:f,entry:u,resolvedOptions:l.resolvedOptions};await t.callHook("tag:normalise",d),a.tags.push(d.tag)}}return await t.callHook("tags:beforeResolve",a),await t.callHook("tags:resolve",a),await t.callHook("tags:afterResolve",a),a.tags},ssr:n};return[Bh,Uh,Wh,zh,Qh,Xh,Yh,Gh,...(e==null?void 0:e.plugins)||[]].forEach(a=>l.use(a)),l.hooks.callHook("init",l),l}function tp(){return Ea}const np=Ql.startsWith("3");function rp(e){return typeof e=="function"?e():he(e)}function As(e,t=""){if(e instanceof Promise)return e;const n=rp(e);return!e||!n?n:Array.isArray(n)?n.map(r=>As(r,t)):typeof n=="object"?Object.fromEntries(Object.entries(n).map(([r,s])=>r==="titleTemplate"||r.startsWith("on")?[r,he(s)]:[r,As(s,r)])):n}const sp={hooks:{"entries:resolve":function(e){for(const t of e.entries)t.resolvedInput=As(t.input)}}},wa="usehead";function op(e){return{install(n){np&&(n.config.globalProperties.$unhead=e,n.config.globalProperties.$head=e,n.provide(wa,e))}}.install}function ip(e={}){e.domDelayFn=e.domDelayFn||(n=>Mn(()=>setTimeout(()=>n(),0)));const t=Zh(e);return t.use(sp),t.install=op(t),t}const xs=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},ks="__unhead_injection_handler__";function lp(e){xs[ks]=e}function uy(){if(ks in xs)return xs[ks]();const e=He(wa);return e||tp()}const ap={nuxt:{buildId:"5c1e5955-a9a1-4785-b832-fac3e0fe121e"}},cp=oh(ap);function up(){const e=ge();return e._appConfig||(e._appConfig=ot(cp)),e._appConfig}const Os=!1,fp=!1,dp={componentName:"NuxtLink"},fy={deep:!0},hp="#__nuxt";let nr,Ra;function pp(){var t;const e=(t=up().nuxt)==null?void 0:t.buildId;return nr=$fetch(ao(`builds/meta/${e}.json`)),nr.then(n=>{Ra=Zd(n.matcher)}),nr}function $r(){return nr||pp()}async function Ca(e){return await $r(),da({},...Ra.matchAll(e).reverse())}function yi(e,t={}){const n=gp(e,t),r=ge(),s=r._payloadCache=r._payloadCache||{};return n in s||(s[n]=mp(e).then(o=>o?Pa(n).then(i=>i||(delete s[n],null)):(s[n]=null,null))),s[n]}const _i="json";function gp(e,t={}){const n=new URL(e,"http://localhost");if(n.host!=="localhost"||It(n.pathname,{acceptRelative:!0}))throw new Error("Payload URL must not include hostname: "+e);const r=t.hash||(t.fresh?Date.now():"");return an(Sr().app.baseURL,n.pathname,r?`_payload.${r}.${_i}`:`_payload.${_i}`)}async function Pa(e){const t=fetch(e).then(n=>n.text().then(Ta));try{return await t}catch(n){console.warn("[nuxt] Cannot load payload ",e,n)}return null}async function mp(e=pa().path){if(e=Or(e),(await $r()).prerendered.includes(e))return!0;const n=await Ca(e);return!!n.prerender&&!n.redirect}let Yn=null;async function yp(){if(Yn)return Yn;const e=document.getElementById("__NUXT_DATA__");if(!e)return{};const t=await Ta(e.textContent||""),n=e.dataset.src?await Pa(e.dataset.src):void 0;return Yn={...t,...n,...window.__NUXT__},Yn}async function Ta(e){return await Ph(e,ge()._payloadRevivers)}function _p(e,t){ge()._payloadRevivers[e]=t}const vi={NuxtError:e=>Hr(e),EmptyShallowRef:e=>Pn(e==="_"?void 0:e==="0n"?BigInt(0):ws(e)),EmptyRef:e=>Ze(e==="_"?void 0:e==="0n"?BigInt(0):ws(e)),ShallowRef:e=>Pn(e),ShallowReactive:e=>Nn(e),Ref:e=>Ze(e),Reactive:e=>ot(e)},vp=Et({name:"nuxt:revive-payload:client",order:-30,async setup(e){let t,n;for(const r in vi)_p(r,vi[r]);Object.assign(e.payload,([t,n]=Sn(()=>e.runWithContext(yp)),t=await t,n(),t)),window.__NUXT__=e.payload}}),bp=[],Ep=Et({name:"nuxt:head",enforce:"pre",setup(e){const t=ip({plugins:bp});lp(()=>ge().vueApp._context.provides.usehead),e.vueApp.use(t);{let n=!0;const r=async()=>{n=!1,await ba(t)};t.hooks.hook("dom:beforeRender",s=>{s.shouldRender=!n}),e.hooks.hook("page:start",()=>{n=!0}),e.hooks.hook("page:finish",()=>{e.isHydrating||r()}),e.hooks.hook("app:error",r),e.hooks.hook("app:suspense:resolve",r)}}});/*! * vue-router v4.3.0 * (c) 2024 Eduardo San Martin Morote * @license MIT - */const jt=typeof document<"u";function wp(e){return e.__esModule||e[Symbol.toStringTag]==="Module"}const oe=Object.assign;function Yr(e,t){const n={};for(const r in t){const s=t[r];n[r]=We(s)?s.map(e):e(s)}return n}const En=()=>{},We=Array.isArray,Aa=/#/g,Rp=/&/g,Cp=/\//g,Pp=/=/g,Tp=/\?/g,xa=/\+/g,Ap=/%5B/g,xp=/%5D/g,ka=/%5E/g,kp=/%60/g,Oa=/%7B/g,Op=/%7C/g,Sa=/%7D/g,Sp=/%20/g;function ho(e){return encodeURI(""+e).replace(Op,"|").replace(Ap,"[").replace(xp,"]")}function Lp(e){return ho(e).replace(Oa,"{").replace(Sa,"}").replace(ka,"^")}function Ss(e){return ho(e).replace(xa,"%2B").replace(Sp,"+").replace(Aa,"%23").replace(Rp,"%26").replace(kp,"`").replace(Oa,"{").replace(Sa,"}").replace(ka,"^")}function Ip(e){return Ss(e).replace(Pp,"%3D")}function Hp(e){return ho(e).replace(Aa,"%23").replace(Tp,"%3F")}function $p(e){return e==null?"":Hp(e).replace(Cp,"%2F")}function Ln(e){try{return decodeURIComponent(""+e)}catch{}return""+e}const Np=/\/$/,Mp=e=>e.replace(Np,"");function Gr(e,t,n="/"){let r,s={},o="",i="";const l=t.indexOf("#");let a=t.indexOf("?");return l=0&&(a=-1),a>-1&&(r=t.slice(0,a),o=t.slice(a+1,l>-1?l:t.length),s=e(o)),l>-1&&(r=r||t.slice(0,l),i=t.slice(l,t.length)),r=Bp(r??t,n),{fullPath:r+(o&&"?")+o+i,path:r,query:s,hash:Ln(i)}}function jp(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function bi(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function Fp(e,t,n){const r=t.matched.length-1,s=n.matched.length-1;return r>-1&&r===s&&en(t.matched[r],n.matched[s])&&La(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function en(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function La(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!Dp(e[n],t[n]))return!1;return!0}function Dp(e,t){return We(e)?Ei(e,t):We(t)?Ei(t,e):e===t}function Ei(e,t){return We(t)?e.length===t.length&&e.every((n,r)=>n===t[r]):e.length===1&&e[0]===t}function Bp(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),r=e.split("/"),s=r[r.length-1];(s===".."||s===".")&&r.push("");let o=n.length-1,i,l;for(i=0;i1&&o--;else break;return n.slice(0,o).join("/")+"/"+r.slice(i).join("/")}var In;(function(e){e.pop="pop",e.push="push"})(In||(In={}));var wn;(function(e){e.back="back",e.forward="forward",e.unknown=""})(wn||(wn={}));function Up(e){if(!e)if(jt){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),Mp(e)}const Kp=/^[^#]+#/;function Vp(e,t){return e.replace(Kp,"#")+t}function Wp(e,t){const n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}const Nr=()=>({left:window.scrollX,top:window.scrollY});function qp(e){let t;if("el"in e){const n=e.el,r=typeof n=="string"&&n.startsWith("#"),s=typeof n=="string"?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!s)return;t=Wp(s,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.scrollX,t.top!=null?t.top:window.scrollY)}function wi(e,t){return(history.state?history.state.position-t:-1)+e}const Ls=new Map;function zp(e,t){Ls.set(e,t)}function Qp(e){const t=Ls.get(e);return Ls.delete(e),t}let Jp=()=>location.protocol+"//"+location.host;function Ia(e,t){const{pathname:n,search:r,hash:s}=t,o=e.indexOf("#");if(o>-1){let l=s.includes(e.slice(o))?e.slice(o).length:1,a=s.slice(l);return a[0]!=="/"&&(a="/"+a),bi(a,"")}return bi(n,e)+r+s}function Xp(e,t,n,r){let s=[],o=[],i=null;const l=({state:d})=>{const m=Ia(e,location),v=n.value,R=t.value;let k=0;if(d){if(n.value=m,t.value=d,i&&i===v){i=null;return}k=R?d.position-R.position:0}else r(m);s.forEach(w=>{w(n.value,v,{delta:k,type:In.pop,direction:k?k>0?wn.forward:wn.back:wn.unknown})})};function a(){i=n.value}function u(d){s.push(d);const m=()=>{const v=s.indexOf(d);v>-1&&s.splice(v,1)};return o.push(m),m}function c(){const{history:d}=window;d.state&&d.replaceState(oe({},d.state,{scroll:Nr()}),"")}function f(){for(const d of o)d();o=[],window.removeEventListener("popstate",l),window.removeEventListener("beforeunload",c)}return window.addEventListener("popstate",l),window.addEventListener("beforeunload",c,{passive:!0}),{pauseListeners:a,listen:u,destroy:f}}function Ri(e,t,n,r=!1,s=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:s?Nr():null}}function Yp(e){const{history:t,location:n}=window,r={value:Ia(e,n)},s={value:t.state};s.value||o(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function o(a,u,c){const f=e.indexOf("#"),d=f>-1?(n.host&&document.querySelector("base")?e:e.slice(f))+a:Jp()+e+a;try{t[c?"replaceState":"pushState"](u,"",d),s.value=u}catch(m){console.error(m),n[c?"replace":"assign"](d)}}function i(a,u){const c=oe({},t.state,Ri(s.value.back,a,s.value.forward,!0),u,{position:s.value.position});o(a,c,!0),r.value=a}function l(a,u){const c=oe({},s.value,t.state,{forward:a,scroll:Nr()});o(c.current,c,!0);const f=oe({},Ri(r.value,a,null),{position:c.position+1},u);o(a,f,!1),r.value=a}return{location:r,state:s,push:l,replace:i}}function Ha(e){e=Up(e);const t=Yp(e),n=Xp(e,t.state,t.location,t.replace);function r(o,i=!0){i||n.pauseListeners(),history.go(o)}const s=oe({location:"",base:e,go:r,createHref:Vp.bind(null,e)},t,n);return Object.defineProperty(s,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(s,"state",{enumerable:!0,get:()=>t.state.value}),s}function Gp(e){return e=location.host?e||location.pathname+location.search:"",e.includes("#")||(e+="#"),Ha(e)}function Zp(e){return typeof e=="string"||e&&typeof e=="object"}function $a(e){return typeof e=="string"||typeof e=="symbol"}const Be={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},Na=Symbol("");var Ci;(function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"})(Ci||(Ci={}));function tn(e,t){return oe(new Error,{type:e,[Na]:!0},t)}function tt(e,t){return e instanceof Error&&Na in e&&(t==null||!!(e.type&t))}const Pi="[^/]+?",eg={sensitive:!1,strict:!1,start:!0,end:!0},tg=/[.+*?^${}()[\]/\\]/g;function ng(e,t){const n=oe({},eg,t),r=[];let s=n.start?"^":"";const o=[];for(const u of e){const c=u.length?[]:[90];n.strict&&!u.length&&(s+="/");for(let f=0;ft.length?t.length===1&&t[0]===80?1:-1:0}function sg(e,t){let n=0;const r=e.score,s=t.score;for(;n0&&t[t.length-1]<0}const og={type:0,value:""},ig=/[a-zA-Z0-9_]/;function lg(e){if(!e)return[[]];if(e==="/")return[[og]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(m){throw new Error(`ERR (${n})/"${u}": ${m}`)}let n=0,r=n;const s=[];let o;function i(){o&&s.push(o),o=[]}let l=0,a,u="",c="";function f(){u&&(n===0?o.push({type:0,value:u}):n===1||n===2||n===3?(o.length>1&&(a==="*"||a==="+")&&t(`A repeatable param (${u}) must be alone in its segment. eg: '/:ids+.`),o.push({type:1,value:u,regexp:c,repeatable:a==="*"||a==="+",optional:a==="*"||a==="?"})):t("Invalid state to consume buffer"),u="")}function d(){u+=a}for(;l{i(b)}:En}function i(c){if($a(c)){const f=r.get(c);f&&(r.delete(c),n.splice(n.indexOf(f),1),f.children.forEach(i),f.alias.forEach(i))}else{const f=n.indexOf(c);f>-1&&(n.splice(f,1),c.record.name&&r.delete(c.record.name),c.children.forEach(i),c.alias.forEach(i))}}function l(){return n}function a(c){let f=0;for(;f=0&&(c.record.path!==n[f].record.path||!Ma(c,n[f]));)f++;n.splice(f,0,c),c.record.name&&!xi(c)&&r.set(c.record.name,c)}function u(c,f){let d,m={},v,R;if("name"in c&&c.name){if(d=r.get(c.name),!d)throw tn(1,{location:c});R=d.record.name,m=oe(Ai(f.params,d.keys.filter(b=>!b.optional).concat(d.parent?d.parent.keys.filter(b=>b.optional):[]).map(b=>b.name)),c.params&&Ai(c.params,d.keys.map(b=>b.name))),v=d.stringify(m)}else if(c.path!=null)v=c.path,d=n.find(b=>b.re.test(v)),d&&(m=d.parse(v),R=d.record.name);else{if(d=f.name?r.get(f.name):n.find(b=>b.re.test(f.path)),!d)throw tn(1,{location:c,currentLocation:f});R=d.record.name,m=oe({},f.params,c.params),v=d.stringify(m)}const k=[];let w=d;for(;w;)k.unshift(w.record),w=w.parent;return{name:R,path:v,params:m,matched:k,meta:dg(k)}}return e.forEach(c=>o(c)),{addRoute:o,resolve:u,removeRoute:i,getRoutes:l,getRecordMatcher:s}}function Ai(e,t){const n={};for(const r of t)r in e&&(n[r]=e[r]);return n}function ug(e){return{path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:void 0,beforeEnter:e.beforeEnter,props:fg(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}}}function fg(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const r in e.components)t[r]=typeof n=="object"?n[r]:n;return t}function xi(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function dg(e){return e.reduce((t,n)=>oe(t,n.meta),{})}function ki(e,t){const n={};for(const r in e)n[r]=r in t?t[r]:e[r];return n}function Ma(e,t){return t.children.some(n=>n===e||Ma(e,n))}function hg(e){const t={};if(e===""||e==="?")return t;const r=(e[0]==="?"?e.slice(1):e).split("&");for(let s=0;so&&Ss(o)):[r&&Ss(r)]).forEach(o=>{o!==void 0&&(t+=(t.length?"&":"")+n,o!=null&&(t+="="+o))})}return t}function pg(e){const t={};for(const n in e){const r=e[n];r!==void 0&&(t[n]=We(r)?r.map(s=>s==null?null:""+s):r==null?r:""+r)}return t}const gg=Symbol(""),Si=Symbol(""),po=Symbol(""),ja=Symbol(""),Is=Symbol("");function fn(){let e=[];function t(r){return e.push(r),()=>{const s=e.indexOf(r);s>-1&&e.splice(s,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function mt(e,t,n,r,s,o=i=>i()){const i=r&&(r.enterCallbacks[s]=r.enterCallbacks[s]||[]);return()=>new Promise((l,a)=>{const u=d=>{d===!1?a(tn(4,{from:n,to:t})):d instanceof Error?a(d):Zp(d)?a(tn(2,{from:t,to:d})):(i&&r.enterCallbacks[s]===i&&typeof d=="function"&&i.push(d),l())},c=o(()=>e.call(r&&r.instances[s],t,n,u));let f=Promise.resolve(c);e.length<3&&(f=f.then(u)),f.catch(d=>a(d))})}function Zr(e,t,n,r,s=o=>o()){const o=[];for(const i of e)for(const l in i.components){let a=i.components[l];if(!(t!=="beforeRouteEnter"&&!i.instances[l]))if(mg(a)){const c=(a.__vccOpts||a)[t];c&&o.push(mt(c,n,r,i,l,s))}else{let u=a();o.push(()=>u.then(c=>{if(!c)return Promise.reject(new Error(`Couldn't resolve component "${l}" at "${i.path}"`));const f=wp(c)?c.default:c;i.components[l]=f;const m=(f.__vccOpts||f)[t];return m&&mt(m,n,r,i,l,s)()}))}}return o}function mg(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function Li(e){const t=He(po),n=He(ja),r=Pe(()=>t.resolve(he(e.to))),s=Pe(()=>{const{matched:a}=r.value,{length:u}=a,c=a[u-1],f=n.matched;if(!c||!f.length)return-1;const d=f.findIndex(en.bind(null,c));if(d>-1)return d;const m=Ii(a[u-2]);return u>1&&Ii(c)===m&&f[f.length-1].path!==m?f.findIndex(en.bind(null,a[u-2])):d}),o=Pe(()=>s.value>-1&&bg(n.params,r.value.params)),i=Pe(()=>s.value>-1&&s.value===n.matched.length-1&&La(n.params,r.value.params));function l(a={}){return vg(a)?t[he(e.replace)?"replace":"push"](he(e.to)).catch(En):Promise.resolve()}return{route:r,href:Pe(()=>r.value.href),isActive:o,isExactActive:i,navigate:l}}const yg=ln({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:Li,setup(e,{slots:t}){const n=ot(Li(e)),{options:r}=He(po),s=Pe(()=>({[Hi(e.activeClass,r.linkActiveClass,"router-link-active")]:n.isActive,[Hi(e.exactActiveClass,r.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const o=t.default&&t.default(n);return e.custom?o:Ve("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:s.value},o)}}}),_g=yg;function vg(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function bg(e,t){for(const n in t){const r=t[n],s=e[n];if(typeof r=="string"){if(r!==s)return!1}else if(!We(s)||s.length!==r.length||r.some((o,i)=>o!==s[i]))return!1}return!0}function Ii(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Hi=(e,t,n)=>e??t??n,Eg=ln({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const r=He(Is),s=Pe(()=>e.route||r.value),o=He(Si,0),i=Pe(()=>{let u=he(o);const{matched:c}=s.value;let f;for(;(f=c[u])&&!f.components;)u++;return u}),l=Pe(()=>s.value.matched[i.value]);zt(Si,Pe(()=>i.value+1)),zt(gg,l),zt(Is,s);const a=Ze();return qt(()=>[a.value,l.value,e.name],([u,c,f],[d,m,v])=>{c&&(c.instances[f]=u,m&&m!==c&&u&&u===d&&(c.leaveGuards.size||(c.leaveGuards=m.leaveGuards),c.updateGuards.size||(c.updateGuards=m.updateGuards))),u&&c&&(!m||!en(c,m)||!d)&&(c.enterCallbacks[f]||[]).forEach(R=>R(u))},{flush:"post"}),()=>{const u=s.value,c=e.name,f=l.value,d=f&&f.components[c];if(!d)return $i(n.default,{Component:d,route:u});const m=f.props[c],v=m?m===!0?u.params:typeof m=="function"?m(u):m:null,k=Ve(d,oe({},v,t,{onVnodeUnmounted:w=>{w.component.isUnmounted&&(f.instances[c]=null)},ref:a}));return $i(n.default,{Component:k,route:u})||k}}});function $i(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const Fa=Eg;function wg(e){const t=cg(e.routes,e),n=e.parseQuery||hg,r=e.stringifyQuery||Oi,s=e.history,o=fn(),i=fn(),l=fn(),a=Pn(Be);let u=Be;jt&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const c=Yr.bind(null,P=>""+P),f=Yr.bind(null,$p),d=Yr.bind(null,Ln);function m(P,F){let $,V;return $a(P)?($=t.getRecordMatcher(P),V=F):V=P,t.addRoute(V,$)}function v(P){const F=t.getRecordMatcher(P);F&&t.removeRoute(F)}function R(){return t.getRoutes().map(P=>P.record)}function k(P){return!!t.getRecordMatcher(P)}function w(P,F){if(F=oe({},F||a.value),typeof P=="string"){const _=Gr(n,P,F.path),E=t.resolve({path:_.path},F),T=s.createHref(_.fullPath);return oe(_,E,{params:d(E.params),hash:Ln(_.hash),redirectedFrom:void 0,href:T})}let $;if(P.path!=null)$=oe({},P,{path:Gr(n,P.path,F.path).path});else{const _=oe({},P.params);for(const E in _)_[E]==null&&delete _[E];$=oe({},P,{params:f(_)}),F.params=f(F.params)}const V=t.resolve($,F),se=P.hash||"";V.params=c(d(V.params));const h=jp(r,oe({},P,{hash:Lp(se),path:V.path})),p=s.createHref(h);return oe({fullPath:h,hash:se,query:r===Oi?pg(P.query):P.query||{}},V,{redirectedFrom:void 0,href:p})}function b(P){return typeof P=="string"?Gr(n,P,a.value.path):oe({},P)}function y(P,F){if(u!==P)return tn(8,{from:F,to:P})}function g(P){return N(P)}function C(P){return g(oe(b(P),{replace:!0}))}function I(P){const F=P.matched[P.matched.length-1];if(F&&F.redirect){const{redirect:$}=F;let V=typeof $=="function"?$(P):$;return typeof V=="string"&&(V=V.includes("?")||V.includes("#")?V=b(V):{path:V},V.params={}),oe({query:P.query,hash:P.hash,params:V.path!=null?{}:P.params},V)}}function N(P,F){const $=u=w(P),V=a.value,se=P.state,h=P.force,p=P.replace===!0,_=I($);if(_)return N(oe(b(_),{state:typeof _=="object"?oe({},se,_.state):se,force:h,replace:p}),F||$);const E=$;E.redirectedFrom=F;let T;return!h&&Fp(r,V,$)&&(T=tn(16,{to:E,from:V}),ze(V,V,!0,!1)),(T?Promise.resolve(T):M(E,V)).catch(A=>tt(A)?tt(A,2)?A:at(A):K(A,E,V)).then(A=>{if(A){if(tt(A,2))return N(oe({replace:p},b(A.to),{state:typeof A.to=="object"?oe({},se,A.to.state):se,force:h}),F||E)}else A=L(E,V,!0,p,se);return Q(E,V,A),A})}function O(P,F){const $=y(P,F);return $?Promise.reject($):Promise.resolve()}function D(P){const F=$t.values().next().value;return F&&typeof F.runWithContext=="function"?F.runWithContext(P):P()}function M(P,F){let $;const[V,se,h]=Rg(P,F);$=Zr(V.reverse(),"beforeRouteLeave",P,F);for(const _ of V)_.leaveGuards.forEach(E=>{$.push(mt(E,P,F))});const p=O.bind(null,P,F);return $.push(p),we($).then(()=>{$=[];for(const _ of o.list())$.push(mt(_,P,F));return $.push(p),we($)}).then(()=>{$=Zr(se,"beforeRouteUpdate",P,F);for(const _ of se)_.updateGuards.forEach(E=>{$.push(mt(E,P,F))});return $.push(p),we($)}).then(()=>{$=[];for(const _ of h)if(_.beforeEnter)if(We(_.beforeEnter))for(const E of _.beforeEnter)$.push(mt(E,P,F));else $.push(mt(_.beforeEnter,P,F));return $.push(p),we($)}).then(()=>(P.matched.forEach(_=>_.enterCallbacks={}),$=Zr(h,"beforeRouteEnter",P,F,D),$.push(p),we($))).then(()=>{$=[];for(const _ of i.list())$.push(mt(_,P,F));return $.push(p),we($)}).catch(_=>tt(_,8)?_:Promise.reject(_))}function Q(P,F,$){l.list().forEach(V=>D(()=>V(P,F,$)))}function L(P,F,$,V,se){const h=y(P,F);if(h)return h;const p=F===Be,_=jt?history.state:{};$&&(V||p?s.replace(P.fullPath,oe({scroll:p&&_&&_.scroll},se)):s.push(P.fullPath,se)),a.value=P,ze(P,F,$,p),at()}let J;function ae(){J||(J=s.listen((P,F,$)=>{if(!Dn.listening)return;const V=w(P),se=I(V);if(se){N(oe(se,{replace:!0}),V).catch(En);return}u=V;const h=a.value;jt&&zp(wi(h.fullPath,$.delta),Nr()),M(V,h).catch(p=>tt(p,12)?p:tt(p,2)?(N(p.to,V).then(_=>{tt(_,20)&&!$.delta&&$.type===In.pop&&s.go(-1,!1)}).catch(En),Promise.reject()):($.delta&&s.go(-$.delta,!1),K(p,V,h))).then(p=>{p=p||L(V,h,!1),p&&($.delta&&!tt(p,8)?s.go(-$.delta,!1):$.type===In.pop&&tt(p,20)&&s.go(-1,!1)),Q(V,h,p)}).catch(En)}))}let le=fn(),U=fn(),Z;function K(P,F,$){at(P);const V=U.list();return V.length?V.forEach(se=>se(P,F,$)):console.error(P),Promise.reject(P)}function Fe(){return Z&&a.value!==Be?Promise.resolve():new Promise((P,F)=>{le.add([P,F])})}function at(P){return Z||(Z=!P,ae(),le.list().forEach(([F,$])=>P?$(P):F()),le.reset()),P}function ze(P,F,$,V){const{scrollBehavior:se}=e;if(!jt||!se)return Promise.resolve();const h=!$&&Qp(wi(P.fullPath,0))||(V||!$)&&history.state&&history.state.scroll||null;return Mn().then(()=>se(P,F,h)).then(p=>p&&qp(p)).catch(p=>K(p,P,F))}const Ae=P=>s.go(P);let Ht;const $t=new Set,Dn={currentRoute:a,listening:!0,addRoute:m,removeRoute:v,hasRoute:k,getRoutes:R,resolve:w,options:e,push:g,replace:C,go:Ae,back:()=>Ae(-1),forward:()=>Ae(1),beforeEach:o.add,beforeResolve:i.add,afterEach:l.add,onError:U.add,isReady:Fe,install(P){const F=this;P.component("RouterLink",_g),P.component("RouterView",Fa),P.config.globalProperties.$router=F,Object.defineProperty(P.config.globalProperties,"$route",{enumerable:!0,get:()=>he(a)}),jt&&!Ht&&a.value===Be&&(Ht=!0,g(s.location).catch(se=>{}));const $={};for(const se in Be)Object.defineProperty($,se,{get:()=>a.value[se],enumerable:!0});P.provide(po,F),P.provide(ja,Nn($)),P.provide(Is,a);const V=P.unmount;$t.add(P),P.unmount=function(){$t.delete(P),$t.size<1&&(u=Be,J&&J(),J=null,a.value=Be,Ht=!1,Z=!1),V()}}};function we(P){return P.reduce((F,$)=>F.then(()=>D($)),Promise.resolve())}return Dn}function Rg(e,t){const n=[],r=[],s=[],o=Math.max(t.matched.length,e.matched.length);for(let i=0;ien(u,l))?r.push(l):n.push(l));const a=e.matched[i];a&&(t.matched.find(u=>en(u,a))||s.push(a))}return[n,r,s]}const Cg=(e,t)=>t.path.replace(/(:\w+)\([^)]+\)/g,"$1").replace(/(:\w+)[?+*]/g,"$1").replace(/:\w+/g,n=>{var r;return((r=e.params[n.slice(1)])==null?void 0:r.toString())||""}),Hs=(e,t)=>{const n=e.route.matched.find(s=>{var o;return((o=s.components)==null?void 0:o.default)===e.Component.type}),r=t??(n==null?void 0:n.meta.key)??(n&&Cg(e.route,n));return typeof r=="function"?r(e.route):r},Pg=(e,t)=>({default:()=>e?Ve(tu,e===!0?{}:e,t):t});function go(e){return Array.isArray(e)?e:[e]}const es=null,ts=null,nt=null,Ni=[{name:"slug",path:"/:slug(.*)*",meta:{},alias:[],redirect:es==null?void 0:es.redirect,component:()=>G(()=>import("./_...slug_.6mwjtp-q.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8]),import.meta.url).then(e=>e.default||e)},{name:"index",path:"/",meta:{},alias:[],redirect:ts==null?void 0:ts.redirect,component:()=>G(()=>import("./index.yVYxWBDr.js"),__vite__mapDeps([9,10]),import.meta.url).then(e=>e.default||e)},{name:void 0,path:"/blog/",meta:{},alias:[],redirect:nt==null?void 0:nt.redirect,component:()=>G(()=>import("./component-stub.J7zsssVp.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default||e)},{name:void 0,path:"/blog/concurrency",meta:{},alias:[],redirect:nt==null?void 0:nt.redirect,component:()=>G(()=>import("./component-stub.J7zsssVp.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default||e)},{name:void 0,path:"/blog/typescript-typesystems-and-javascript",meta:{},alias:[],redirect:nt==null?void 0:nt.redirect,component:()=>G(()=>import("./component-stub.J7zsssVp.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default||e)}],Tg=(e,t,n)=>(t=t===!0?{}:t,{default:()=>{var r;return t?Ve(e,t,n):(r=n.default)==null?void 0:r.call(n)}});function Mi(e){const t=(e==null?void 0:e.meta.key)??e.path.replace(/(:\w+)\([^)]+\)/g,"$1").replace(/(:\w+)[?+*]/g,"$1").replace(/:\w+/g,n=>{var r;return((r=e.params[n.slice(1)])==null?void 0:r.toString())||""});return typeof t=="function"?t(e):t}function Ag(e,t){return e===t||t===Be?!1:Mi(e)!==Mi(t)?!0:!e.matched.every((r,s)=>{var o,i;return r.components&&r.components.default===((i=(o=t.matched[s])==null?void 0:o.components)==null?void 0:i.default)})}const xg={scrollBehavior(e,t,n){var u;const r=ge(),s=((u=qe().options)==null?void 0:u.scrollBehaviorType)??"auto";let o=n||void 0;const i=typeof e.meta.scrollToTop=="function"?e.meta.scrollToTop(e,t):e.meta.scrollToTop;if(!o&&t&&e&&i!==!1&&Ag(e,t)&&(o={left:0,top:0}),e.path===t.path)return t.hash&&!e.hash?{left:0,top:0}:e.hash?{el:e.hash,top:ji(e.hash),behavior:s}:!1;const l=c=>!!(c.meta.pageTransition??Os),a=l(t)&&l(e)?"page:transition:finish":"page:finish";return new Promise(c=>{r.hooks.hookOnce(a,async()=>{await new Promise(f=>setTimeout(f,0)),e.hash&&(o={el:e.hash,top:ji(e.hash),behavior:s}),c(o)})})}};function ji(e){try{const t=document.querySelector(e);if(t)return parseFloat(getComputedStyle(t).scrollMarginTop)}catch{}return 0}const kg={hashMode:!1,scrollBehaviorType:"auto"},Le={...kg,...xg},Og=async e=>{var a;let t,n;if(!((a=e.meta)!=null&&a.validate))return;const r=ge(),s=qe();if(([t,n]=Sn(()=>Promise.resolve(e.meta.validate(e))),t=await t,n(),t)===!0)return;const i=Hr({statusCode:404,statusMessage:`Page Not Found: ${e.fullPath}`,data:{path:e.fullPath}}),l=s.beforeResolve(u=>{if(l(),u===e){const c=s.afterEach(async()=>{c(),await r.runWithContext(()=>Dt(i)),window.history.pushState({},"",e.fullPath)});return!1}})},Sg=async e=>{let t,n;const r=([t,n]=Sn(()=>Ca(e.path)),t=await t,n(),t);if(r.redirect)return r.redirect},Lg=[Og,Sg],Rn={};function Ig(e,t,n){const{pathname:r,search:s,hash:o}=t,i=e.indexOf("#");if(i>-1){const u=o.includes(e.slice(i))?e.slice(i).length:1;let c=o.slice(u);return c[0]!=="/"&&(c="/"+c),si(c,"")}const l=si(r,e),a=!n||Ff(l,n,{trailingSlash:!0})?l:n;return a+(a.includes("?")?"":s)+o}const Hg=Et({name:"nuxt:router",enforce:"pre",async setup(e){var R,k;let t,n,r=Sr().app.baseURL;Le.hashMode&&!r.includes("#")&&(r+="#");const s=((R=Le.history)==null?void 0:R.call(Le,r))??(Le.hashMode?Gp(r):Ha(r)),o=((k=Le.routes)==null?void 0:k.call(Le,Ni))??Ni;let i;const l=Ig(r,window.location,e.payload.path),a=wg({...Le,scrollBehavior:(w,b,y)=>{if(b===Be){i=y;return}if(Le.scrollBehavior){if(a.options.scrollBehavior=Le.scrollBehavior,"scrollRestoration"in window.history){const g=a.beforeEach(()=>{g(),window.history.scrollRestoration="manual"})}return Le.scrollBehavior(w,Be,i||y)}},history:s,routes:o});"scrollRestoration"in window.history&&(window.history.scrollRestoration="auto"),e.vueApp.use(a);const u=Pn(a.currentRoute.value);a.afterEach((w,b)=>{u.value=b}),Object.defineProperty(e.vueApp.config.globalProperties,"previousRoute",{get:()=>u.value});const c=Pn(a.resolve(l)),f=()=>{c.value=a.currentRoute.value};e.hook("page:finish",f),a.afterEach((w,b)=>{var y,g,C,I;((g=(y=w.matched[0])==null?void 0:y.components)==null?void 0:g.default)===((I=(C=b.matched[0])==null?void 0:C.components)==null?void 0:I.default)&&f()});const d={};for(const w in c.value)Object.defineProperty(d,w,{get:()=>c.value[w]});e._route=Nn(d),e._middleware=e._middleware||{global:[],named:{}};const m=Ir();try{[t,n]=Sn(()=>a.isReady()),await t,n()}catch(w){[t,n]=Sn(()=>e.runWithContext(()=>Dt(w))),await t,n()}const v=e.payload.state._layout;return a.beforeEach(async(w,b)=>{var y;await e.callHook("page:loading:start"),w.meta=ot(w.meta),e.isHydrating&&v&&!Lt(w.meta.layout)&&(w.meta.layout=v),e._processingMiddleware=!0;{const g=new Set([...Lg,...e._middleware.global]);for(const C of w.matched){const I=C.meta.middleware;if(I)for(const N of go(I))g.add(N)}for(const C of g){const I=typeof C=="string"?e._middleware.named[C]||await((y=Rn[C])==null?void 0:y.call(Rn).then(O=>O.default||O)):C;if(!I)throw new Error(`Unknown route middleware: '${C}'.`);const N=await e.runWithContext(()=>I(w,b));if(!e.payload.serverRendered&&e.isHydrating&&(N===!1||N instanceof Error)){const O=N||Ps({statusCode:404,statusMessage:`Page Not Found: ${l}`});return await e.runWithContext(()=>Dt(O)),!1}if(N!==!0&&(N||N===!1))return N}}}),a.onError(async()=>{delete e._processingMiddleware,await e.callHook("page:loading:end")}),a.afterEach(async(w,b,y)=>{delete e._processingMiddleware,!e.isHydrating&&m.value&&await e.runWithContext(ph),y&&await e.callHook("page:loading:end"),w.matched.length===0&&await e.runWithContext(()=>Dt(Ps({statusCode:404,fatal:!1,statusMessage:`Page not found: ${w.fullPath}`,data:{path:w.fullPath}})))}),e.hooks.hookOnce("app:created",async()=>{try{const w=a.resolve(l);"name"in w&&(w.name=void 0),await a.replace({...w,force:!0}),a.options.scrollBehavior=Le.scrollBehavior}catch(w){await e.runWithContext(()=>Dt(w))}}),{provide:{router:a}}}}),$s=globalThis.requestIdleCallback||(e=>{const t=Date.now(),n={didTimeout:!1,timeRemaining:()=>Math.max(0,50-(Date.now()-t))};return setTimeout(()=>{e(n)},1)}),$g=globalThis.cancelIdleCallback||(e=>{clearTimeout(e)}),mo=e=>{const t=ge();t.isHydrating?t.hooks.hookOnce("app:suspense:resolve",()=>{$s(e)}):$s(e)},Ng=Et({name:"nuxt:payload",setup(e){qe().beforeResolve(async(t,n)=>{if(t.path===n.path)return;const r=await yi(t.path);r&&Object.assign(e.static.data,r.data)}),mo(()=>{var t;e.hooks.hook("link:prefetch",async n=>{Fn(n).protocol||await yi(n)}),((t=navigator.connection)==null?void 0:t.effectiveType)!=="slow-2g"&&setTimeout($r,1e3)})}}),Mg=Et(e=>{let t;async function n(){const r=await $r();t&&clearTimeout(t),t=setTimeout(n,1e3*60*60);const s=await $fetch(ao("builds/latest.json")+`?${Date.now()}`);s.id!==r.id&&e.hooks.callHook("app:manifest:update",s)}mo(()=>{t=setTimeout(n,1e3*60*60)})}),jg=ee(()=>G(()=>import("./ContentDoc.m4erpRCJ.js"),__vite__mapDeps([1,2,3,4,5,6,7,8]),import.meta.url).then(e=>e.default)),Fg=ee(()=>G(()=>import("./ContentList.YfCz_pZv.js"),__vite__mapDeps([11,7,8,6]),import.meta.url).then(e=>e.default)),Dg=ee(()=>G(()=>import("./ContentNavigation.4-dxUQeo.js"),__vite__mapDeps([12,8,6]),import.meta.url).then(e=>e.default)),Bg=ee(()=>G(()=>import("./ContentQuery.7IlyA-wt.js"),__vite__mapDeps([7,8,6]),import.meta.url).then(e=>e.default)),Ug=ee(()=>G(()=>import("./ContentRenderer.0Ci8vnAh.js"),__vite__mapDeps([3,4,5,6]),import.meta.url).then(e=>e.default)),Kg=ee(()=>G(()=>import("./ContentRendererMarkdown.TQHLBOHw.js"),__vite__mapDeps([13,4,5,6]),import.meta.url).then(e=>e.default)),Vg=ee(()=>G(()=>import("./ContentSlot.yUuC7AiQ.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),Wg=ee(()=>G(()=>import("./DocumentDrivenEmpty.FNlONpq4.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),qg=ee(()=>G(()=>import("./DocumentDrivenNotFound.PaEuZL54.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),zg=ee(()=>G(()=>import("./Markdown.PGpQEzUu.js"),__vite__mapDeps([14,15]),import.meta.url).then(e=>e.default)),Qg=ee(()=>G(()=>import("./ProseCode.4ZscnP7G.js"),__vite__mapDeps([16,17,18]),import.meta.url).then(e=>e.default)),Jg=ee(()=>G(()=>import("./ProseCodeInline.D2qvyBIJ.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),Xg=ee(()=>G(()=>import("./ProsePre.f92e3HR-.js"),__vite__mapDeps([19,17,18]),import.meta.url).then(e=>e.default)),Yg=ee(()=>G(()=>import("./ProseA.mjBdkCoM.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),Gg=ee(()=>G(()=>import("./ProseBlockquote.0zQiHAd5.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),Zg=ee(()=>G(()=>import("./ProseEm.IVSr4QqS.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),em=ee(()=>G(()=>import("./ProseH1.98vvHrNf.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),tm=ee(()=>G(()=>import("./ProseH2.3ZUTtu58.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),nm=ee(()=>G(()=>import("./ProseH3.xS8JfK2d.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),rm=ee(()=>G(()=>import("./ProseH4.W0zxJSWG.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),sm=ee(()=>G(()=>import("./ProseH5.D_jmzZ-I.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),om=ee(()=>G(()=>import("./ProseH6.UGEbdmmN.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),im=ee(()=>G(()=>import("./ProseHr.VSPhZaq6.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),lm=ee(()=>G(()=>import("./ProseImg._1ci9PF9.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),am=ee(()=>G(()=>import("./ProseLi.pGb8hNnw.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),cm=ee(()=>G(()=>import("./ProseOl._vZ89wqu.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),um=ee(()=>G(()=>import("./ProseP.l0BQwt1b.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),fm=ee(()=>G(()=>import("./ProseScript.vwc6r6-w.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),dm=ee(()=>G(()=>import("./ProseStrong.8IHfBQHv.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),hm=ee(()=>G(()=>import("./ProseTable.UwfW2q09.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),pm=ee(()=>G(()=>import("./ProseTbody.76lFHrfY.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),gm=ee(()=>G(()=>import("./ProseTd.Mqlmzd0p.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),mm=ee(()=>G(()=>import("./ProseTh.FnhkcspZ.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),ym=ee(()=>G(()=>import("./ProseThead.0jV4MZhn.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),_m=ee(()=>G(()=>import("./ProseTr.Hqs34-B0.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),vm=ee(()=>G(()=>import("./ProseUl.2DgLM2oK.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),bm=[["ContentDoc",jg],["ContentList",Fg],["ContentNavigation",Dg],["ContentQuery",Bg],["ContentRenderer",Ug],["ContentRendererMarkdown",Kg],["MDCSlot",Vg],["DocumentDrivenEmpty",Wg],["DocumentDrivenNotFound",qg],["Markdown",zg],["ProseCode",Qg],["ProseCodeInline",Jg],["ProsePre",Xg],["ProseA",Yg],["ProseBlockquote",Gg],["ProseEm",Zg],["ProseH1",em],["ProseH2",tm],["ProseH3",nm],["ProseH4",rm],["ProseH5",sm],["ProseH6",om],["ProseHr",im],["ProseImg",lm],["ProseLi",am],["ProseOl",cm],["ProseP",um],["ProseScript",fm],["ProseStrong",dm],["ProseTable",hm],["ProseTbody",pm],["ProseTd",gm],["ProseTh",mm],["ProseThead",ym],["ProseTr",_m],["ProseUl",vm]],Em=Et({name:"nuxt:global-components",setup(e){for(const[t,n]of bm)e.vueApp.component(t,n),e.vueApp.component("Lazy"+t,n)}}),Gn={},wm=Et({name:"nuxt:prefetch",setup(e){const t=qe();e.hooks.hook("app:mounted",()=>{t.beforeEach(async n=>{var s;const r=(s=n==null?void 0:n.meta)==null?void 0:s.layout;r&&typeof Gn[r]=="function"&&await Gn[r]()})}),e.hooks.hook("link:prefetch",n=>{if(It(n))return;const r=t.resolve(n);if(!r)return;const s=r.meta.layout;let o=go(r.meta.middleware);o=o.filter(i=>typeof i=="string");for(const i of o)typeof Rn[i]=="function"&&Rn[i]();s&&typeof Gn[s]=="function"&&Gn[s]()})}});function Rm(e={}){const t=e.path||window.location.pathname;let n={};try{n=ws(sessionStorage.getItem("nuxt:reload")||"{}")}catch{}if(e.force||(n==null?void 0:n.path)!==t||(n==null?void 0:n.expires){r.clear()}),e.hook("app:chunkError",({error:o})=>{r.add(o)});function s(o){const l="href"in o&&o.href[0]==="#"?n.app.baseURL+o.href:an(n.app.baseURL,o.fullPath);Rm({path:l,persistState:!0})}e.hook("app:manifest:update",()=>{t.beforeResolve(s)}),t.onError((o,i)=>{r.has(o)&&s(i)})}}),Pm=[vp,Ep,Hg,Ng,Mg,Em,wm,Cm];async function Da(e,t=qe()){const{path:n,matched:r}=t.resolve(e);if(!r.length||(t._routePreloaded||(t._routePreloaded=new Set),t._routePreloaded.has(n)))return;const s=t._preloadPromises=t._preloadPromises||[];if(s.length>4)return Promise.all(s).then(()=>Da(e,t));t._routePreloaded.add(n);const o=r.map(i=>{var l;return(l=i.components)==null?void 0:l.default}).filter(i=>typeof i=="function");for(const i of o){const l=Promise.resolve(i()).catch(()=>{}).finally(()=>s.splice(s.indexOf(l)));s.push(l)}await Promise.all(s)}const Tm=(...e)=>e.find(t=>t!==void 0);function Am(e){const t=e.componentName||"NuxtLink";function n(r,s){if(!r||e.trailingSlash!=="append"&&e.trailingSlash!=="remove")return r;if(typeof r=="string")return Fi(r,e.trailingSlash);const o="path"in r&&r.path!==void 0?r.path:s(r).path,i={...r,path:Fi(o,e.trailingSlash)};return"name"in i&&delete i.name,i}return ln({name:t,props:{to:{type:[String,Object],default:void 0,required:!1},href:{type:[String,Object],default:void 0,required:!1},target:{type:String,default:void 0,required:!1},rel:{type:String,default:void 0,required:!1},noRel:{type:Boolean,default:void 0,required:!1},prefetch:{type:Boolean,default:void 0,required:!1},noPrefetch:{type:Boolean,default:void 0,required:!1},activeClass:{type:String,default:void 0,required:!1},exactActiveClass:{type:String,default:void 0,required:!1},prefetchedClass:{type:String,default:void 0,required:!1},replace:{type:Boolean,default:void 0,required:!1},ariaCurrentValue:{type:String,default:void 0,required:!1},external:{type:Boolean,default:void 0,required:!1},custom:{type:Boolean,default:void 0,required:!1}},setup(r,{slots:s}){const o=qe(),i=Sr(),l=Pe(()=>{const v=r.to||r.href||"";return n(v,o.resolve)}),a=Pe(()=>typeof l.value=="string"&&It(l.value,{acceptRelative:!0})),u=Pe(()=>r.target&&r.target!=="_self"),c=Pe(()=>r.external||u.value?!0:typeof l.value=="object"?!1:l.value===""||a.value),f=Ze(!1),d=Ze(null),m=v=>{var R;d.value=r.custom?(R=v==null?void 0:v.$el)==null?void 0:R.nextElementSibling:v==null?void 0:v.$el};if(r.prefetch!==!1&&r.noPrefetch!==!0&&r.target!=="_blank"&&!Om()){const R=ge();let k,w=null;Tr(()=>{const b=km();mo(()=>{k=$s(()=>{var y;(y=d==null?void 0:d.value)!=null&&y.tagName&&(w=b.observe(d.value,async()=>{w==null||w(),w=null;const g=typeof l.value=="string"?l.value:o.resolve(l.value).fullPath;await Promise.all([R.hooks.callHook("link:prefetch",g).catch(()=>{}),!c.value&&Da(l.value,o).catch(()=>{})]),f.value=!0}))})})}),Ar(()=>{k&&$g(k),w==null||w(),w=null})}return()=>{var w,b;if(!c.value){const y={ref:m,to:l.value,activeClass:r.activeClass||e.activeClass,exactActiveClass:r.exactActiveClass||e.exactActiveClass,replace:r.replace,ariaCurrentValue:r.ariaCurrentValue,custom:r.custom};return r.custom||(f.value&&(y.class=r.prefetchedClass||e.prefetchedClass),y.rel=r.rel||void 0),Ve(Uc("RouterLink"),y,s.default)}const v=typeof l.value=="object"?((w=o.resolve(l.value))==null?void 0:w.href)??null:l.value&&!r.external&&!a.value?n(an(i.app.baseURL,l.value),o.resolve):l.value||null,R=r.target||null,k=Tm(r.noRel?"":r.rel,e.externalRelAttribute,a.value||u.value?"noopener noreferrer":"")||null;if(r.custom){if(!s.default)return null;const y=()=>hh(v,{replace:r.replace,external:r.external});return s.default({href:v,navigate:y,get route(){if(!v)return;const g=Fn(v);return{path:g.pathname,fullPath:g.pathname,get query(){return Gl(g.search)},hash:g.hash,params:{},name:void 0,matched:[],redirectedFrom:void 0,meta:{},href:v}},rel:k,target:R,isExternal:c.value,isActive:!1,isExactActive:!1})}return Ve("a",{ref:d,href:v,rel:k,target:R},(b=s.default)==null?void 0:b.call(s))}}})}const xm=Am(dp);function Fi(e,t){const n=t==="append"?dr:Or;return It(e)&&!e.startsWith("http")?e:n(e,!0)}function km(){const e=ge();if(e._observer)return e._observer;let t=null;const n=new Map,r=(o,i)=>(t||(t=new IntersectionObserver(l=>{for(const a of l){const u=n.get(a.target);(a.isIntersecting||a.intersectionRatio>0)&&u&&u()}})),n.set(o,i),t.observe(o),()=>{n.delete(o),t.unobserve(o),n.size===0&&(t.disconnect(),t=null)});return e._observer={observe:r}}function Om(){const e=navigator.connection;return!!(e&&(e.saveData||/2g/.test(e.effectiveType)))}const Sm=ln({props:{vnode:{type:Object,required:!0},route:{type:Object,required:!0},vnodeRef:Object,renderKey:String,trackRootNodes:Boolean},setup(e){const t=e.renderKey,n=e.route,r={};for(const s in e.route)Object.defineProperty(r,s,{get:()=>t===e.renderKey?e.route[s]:n[s]});return zt(Lr,Nn(r)),()=>Ve(e.vnode,{ref:e.vnodeRef})}}),Lm=ln({name:"NuxtPage",inheritAttrs:!1,props:{name:{type:String},transition:{type:[Boolean,Object],default:void 0},keepalive:{type:[Boolean,Object],default:void 0},route:{type:Object},pageKey:{type:[Function,String],default:null}},setup(e,{attrs:t,expose:n}){const r=ge(),s=Ze(),o=He(Lr,null);let i;n({pageRef:s});const l=He(fh,null);let a;const u=r.deferHydration();if(r.isHydrating){const c=r.hooks.hookOnce("app:error",u);qe().beforeEach(c)}return e.pageKey&&qt(()=>e.pageKey,(c,f)=>{c!==f&&r.callHook("page:loading:start")}),()=>Ve(Fa,{name:e.name,route:e.route,...t},{default:c=>{const f=Hm(o,c.route,c.Component),d=o&&o.matched.length===c.route.matched.length;if(!c.Component){if(a&&!d)return a;u();return}if(a&&l&&!l.isCurrent(c.route))return a;if(f&&o&&(!l||l!=null&&l.isCurrent(o)))return d?a:null;const m=Hs(c,e.pageKey);!r.isHydrating&&!$m(o,c.route,c.Component)&&i===m&&r.callHook("page:loading:end"),i=m;const v=!!(e.transition??c.route.meta.pageTransition??Os),R=v&&Im([e.transition,c.route.meta.pageTransition,Os,{onAfterLeave:()=>{r.callHook("page:transition:finish",c.Component)}}].filter(Boolean)),k=e.keepalive??c.route.meta.keepalive??fp;return a=Tg(io,v&&R,Pg(k,Ve(vl,{suspensible:!0,onPending:()=>r.callHook("page:start",c.Component),onResolve:()=>{Mn(()=>r.callHook("page:finish",c.Component).then(()=>r.callHook("page:loading:end")).finally(u))}},{default:()=>{const w=Ve(Sm,{key:m||void 0,vnode:c.Component,route:c.route,renderKey:m||void 0,trackRootNodes:v,vnodeRef:s});return k&&(w.type.name=c.Component.type.name||c.Component.type.__name||"RouteProvider"),w}}))).default(),a}})}});function Im(e){const t=e.map(n=>({...n,onAfterLeave:n.onAfterLeave?go(n.onAfterLeave):void 0}));return da(...t)}function Hm(e,t,n){if(!e)return!1;const r=t.matched.findIndex(s=>{var o;return((o=s.components)==null?void 0:o.default)===(n==null?void 0:n.type)});return!r||r===-1?!1:t.matched.slice(0,r).some((s,o)=>{var i,l,a;return((i=s.components)==null?void 0:i.default)!==((a=(l=e.matched[o])==null?void 0:l.components)==null?void 0:a.default)})||n&&Hs({route:t,Component:n})!==Hs({route:e,Component:n})}function $m(e,t,n){return e?t.matched.findIndex(s=>{var o;return((o=s.components)==null?void 0:o.default)===(n==null?void 0:n.type)}){const n=e.__vccOpts||e;for(const[r,s]of t)n[r]=s;return n},Dm={},Bm={class:"w-full min-h-screen flex flex-col"},Um={class:"topnav h-54px p-2 bg-white"},Km={class:"container mx-auto flex justify-between items-center max-w-2xl m-auto h-9"},Vm=Su('
',1),Wm=Qt("hr",null,null,-1),qm={class:"p-2 bg-white w-full max-w-2xl mx-auto flex-1"};function zm(e,t){const n=xm,r=Lm;return Ye(),ku("div",Bm,[Qt("header",Um,[Qt("div",Km,[de(n,{class:"text-l",to:"/"},{default:Js(()=>[no("Netanel Haber's 🏠 Thingy")]),_:1}),Vm]),Wm]),Qt("div",qm,[de(r)])])}const Qm=Fm(Dm,[["render",zm]]),Jm={__name:"nuxt-error-page",props:{error:Object},setup(e){const n=e.error;(n.stack||"").split(` + */const jt=typeof document<"u";function wp(e){return e.__esModule||e[Symbol.toStringTag]==="Module"}const oe=Object.assign;function Yr(e,t){const n={};for(const r in t){const s=t[r];n[r]=We(s)?s.map(e):e(s)}return n}const En=()=>{},We=Array.isArray,Aa=/#/g,Rp=/&/g,Cp=/\//g,Pp=/=/g,Tp=/\?/g,xa=/\+/g,Ap=/%5B/g,xp=/%5D/g,ka=/%5E/g,kp=/%60/g,Oa=/%7B/g,Op=/%7C/g,Sa=/%7D/g,Sp=/%20/g;function ho(e){return encodeURI(""+e).replace(Op,"|").replace(Ap,"[").replace(xp,"]")}function Lp(e){return ho(e).replace(Oa,"{").replace(Sa,"}").replace(ka,"^")}function Ss(e){return ho(e).replace(xa,"%2B").replace(Sp,"+").replace(Aa,"%23").replace(Rp,"%26").replace(kp,"`").replace(Oa,"{").replace(Sa,"}").replace(ka,"^")}function Ip(e){return Ss(e).replace(Pp,"%3D")}function Hp(e){return ho(e).replace(Aa,"%23").replace(Tp,"%3F")}function $p(e){return e==null?"":Hp(e).replace(Cp,"%2F")}function Ln(e){try{return decodeURIComponent(""+e)}catch{}return""+e}const Np=/\/$/,Mp=e=>e.replace(Np,"");function Gr(e,t,n="/"){let r,s={},o="",i="";const l=t.indexOf("#");let a=t.indexOf("?");return l=0&&(a=-1),a>-1&&(r=t.slice(0,a),o=t.slice(a+1,l>-1?l:t.length),s=e(o)),l>-1&&(r=r||t.slice(0,l),i=t.slice(l,t.length)),r=Bp(r??t,n),{fullPath:r+(o&&"?")+o+i,path:r,query:s,hash:Ln(i)}}function jp(e,t){const n=t.query?e(t.query):"";return t.path+(n&&"?")+n+(t.hash||"")}function bi(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||"/"}function Fp(e,t,n){const r=t.matched.length-1,s=n.matched.length-1;return r>-1&&r===s&&en(t.matched[r],n.matched[s])&&La(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function en(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function La(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e)if(!Dp(e[n],t[n]))return!1;return!0}function Dp(e,t){return We(e)?Ei(e,t):We(t)?Ei(t,e):e===t}function Ei(e,t){return We(t)?e.length===t.length&&e.every((n,r)=>n===t[r]):e.length===1&&e[0]===t}function Bp(e,t){if(e.startsWith("/"))return e;if(!e)return t;const n=t.split("/"),r=e.split("/"),s=r[r.length-1];(s===".."||s===".")&&r.push("");let o=n.length-1,i,l;for(i=0;i1&&o--;else break;return n.slice(0,o).join("/")+"/"+r.slice(i).join("/")}var In;(function(e){e.pop="pop",e.push="push"})(In||(In={}));var wn;(function(e){e.back="back",e.forward="forward",e.unknown=""})(wn||(wn={}));function Up(e){if(!e)if(jt){const t=document.querySelector("base");e=t&&t.getAttribute("href")||"/",e=e.replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return e[0]!=="/"&&e[0]!=="#"&&(e="/"+e),Mp(e)}const Kp=/^[^#]+#/;function Vp(e,t){return e.replace(Kp,"#")+t}function Wp(e,t){const n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}const Nr=()=>({left:window.scrollX,top:window.scrollY});function qp(e){let t;if("el"in e){const n=e.el,r=typeof n=="string"&&n.startsWith("#"),s=typeof n=="string"?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!s)return;t=Wp(s,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left!=null?t.left:window.scrollX,t.top!=null?t.top:window.scrollY)}function wi(e,t){return(history.state?history.state.position-t:-1)+e}const Ls=new Map;function zp(e,t){Ls.set(e,t)}function Qp(e){const t=Ls.get(e);return Ls.delete(e),t}let Jp=()=>location.protocol+"//"+location.host;function Ia(e,t){const{pathname:n,search:r,hash:s}=t,o=e.indexOf("#");if(o>-1){let l=s.includes(e.slice(o))?e.slice(o).length:1,a=s.slice(l);return a[0]!=="/"&&(a="/"+a),bi(a,"")}return bi(n,e)+r+s}function Xp(e,t,n,r){let s=[],o=[],i=null;const l=({state:d})=>{const m=Ia(e,location),v=n.value,R=t.value;let k=0;if(d){if(n.value=m,t.value=d,i&&i===v){i=null;return}k=R?d.position-R.position:0}else r(m);s.forEach(w=>{w(n.value,v,{delta:k,type:In.pop,direction:k?k>0?wn.forward:wn.back:wn.unknown})})};function a(){i=n.value}function u(d){s.push(d);const m=()=>{const v=s.indexOf(d);v>-1&&s.splice(v,1)};return o.push(m),m}function c(){const{history:d}=window;d.state&&d.replaceState(oe({},d.state,{scroll:Nr()}),"")}function f(){for(const d of o)d();o=[],window.removeEventListener("popstate",l),window.removeEventListener("beforeunload",c)}return window.addEventListener("popstate",l),window.addEventListener("beforeunload",c,{passive:!0}),{pauseListeners:a,listen:u,destroy:f}}function Ri(e,t,n,r=!1,s=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:s?Nr():null}}function Yp(e){const{history:t,location:n}=window,r={value:Ia(e,n)},s={value:t.state};s.value||o(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function o(a,u,c){const f=e.indexOf("#"),d=f>-1?(n.host&&document.querySelector("base")?e:e.slice(f))+a:Jp()+e+a;try{t[c?"replaceState":"pushState"](u,"",d),s.value=u}catch(m){console.error(m),n[c?"replace":"assign"](d)}}function i(a,u){const c=oe({},t.state,Ri(s.value.back,a,s.value.forward,!0),u,{position:s.value.position});o(a,c,!0),r.value=a}function l(a,u){const c=oe({},s.value,t.state,{forward:a,scroll:Nr()});o(c.current,c,!0);const f=oe({},Ri(r.value,a,null),{position:c.position+1},u);o(a,f,!1),r.value=a}return{location:r,state:s,push:l,replace:i}}function Ha(e){e=Up(e);const t=Yp(e),n=Xp(e,t.state,t.location,t.replace);function r(o,i=!0){i||n.pauseListeners(),history.go(o)}const s=oe({location:"",base:e,go:r,createHref:Vp.bind(null,e)},t,n);return Object.defineProperty(s,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(s,"state",{enumerable:!0,get:()=>t.state.value}),s}function Gp(e){return e=location.host?e||location.pathname+location.search:"",e.includes("#")||(e+="#"),Ha(e)}function Zp(e){return typeof e=="string"||e&&typeof e=="object"}function $a(e){return typeof e=="string"||typeof e=="symbol"}const Be={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},Na=Symbol("");var Ci;(function(e){e[e.aborted=4]="aborted",e[e.cancelled=8]="cancelled",e[e.duplicated=16]="duplicated"})(Ci||(Ci={}));function tn(e,t){return oe(new Error,{type:e,[Na]:!0},t)}function tt(e,t){return e instanceof Error&&Na in e&&(t==null||!!(e.type&t))}const Pi="[^/]+?",eg={sensitive:!1,strict:!1,start:!0,end:!0},tg=/[.+*?^${}()[\]/\\]/g;function ng(e,t){const n=oe({},eg,t),r=[];let s=n.start?"^":"";const o=[];for(const u of e){const c=u.length?[]:[90];n.strict&&!u.length&&(s+="/");for(let f=0;ft.length?t.length===1&&t[0]===80?1:-1:0}function sg(e,t){let n=0;const r=e.score,s=t.score;for(;n0&&t[t.length-1]<0}const og={type:0,value:""},ig=/[a-zA-Z0-9_]/;function lg(e){if(!e)return[[]];if(e==="/")return[[og]];if(!e.startsWith("/"))throw new Error(`Invalid path "${e}"`);function t(m){throw new Error(`ERR (${n})/"${u}": ${m}`)}let n=0,r=n;const s=[];let o;function i(){o&&s.push(o),o=[]}let l=0,a,u="",c="";function f(){u&&(n===0?o.push({type:0,value:u}):n===1||n===2||n===3?(o.length>1&&(a==="*"||a==="+")&&t(`A repeatable param (${u}) must be alone in its segment. eg: '/:ids+.`),o.push({type:1,value:u,regexp:c,repeatable:a==="*"||a==="+",optional:a==="*"||a==="?"})):t("Invalid state to consume buffer"),u="")}function d(){u+=a}for(;l{i(b)}:En}function i(c){if($a(c)){const f=r.get(c);f&&(r.delete(c),n.splice(n.indexOf(f),1),f.children.forEach(i),f.alias.forEach(i))}else{const f=n.indexOf(c);f>-1&&(n.splice(f,1),c.record.name&&r.delete(c.record.name),c.children.forEach(i),c.alias.forEach(i))}}function l(){return n}function a(c){let f=0;for(;f=0&&(c.record.path!==n[f].record.path||!Ma(c,n[f]));)f++;n.splice(f,0,c),c.record.name&&!xi(c)&&r.set(c.record.name,c)}function u(c,f){let d,m={},v,R;if("name"in c&&c.name){if(d=r.get(c.name),!d)throw tn(1,{location:c});R=d.record.name,m=oe(Ai(f.params,d.keys.filter(b=>!b.optional).concat(d.parent?d.parent.keys.filter(b=>b.optional):[]).map(b=>b.name)),c.params&&Ai(c.params,d.keys.map(b=>b.name))),v=d.stringify(m)}else if(c.path!=null)v=c.path,d=n.find(b=>b.re.test(v)),d&&(m=d.parse(v),R=d.record.name);else{if(d=f.name?r.get(f.name):n.find(b=>b.re.test(f.path)),!d)throw tn(1,{location:c,currentLocation:f});R=d.record.name,m=oe({},f.params,c.params),v=d.stringify(m)}const k=[];let w=d;for(;w;)k.unshift(w.record),w=w.parent;return{name:R,path:v,params:m,matched:k,meta:dg(k)}}return e.forEach(c=>o(c)),{addRoute:o,resolve:u,removeRoute:i,getRoutes:l,getRecordMatcher:s}}function Ai(e,t){const n={};for(const r of t)r in e&&(n[r]=e[r]);return n}function ug(e){return{path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:void 0,beforeEnter:e.beforeEnter,props:fg(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:"components"in e?e.components||null:e.component&&{default:e.component}}}function fg(e){const t={},n=e.props||!1;if("component"in e)t.default=n;else for(const r in e.components)t[r]=typeof n=="object"?n[r]:n;return t}function xi(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function dg(e){return e.reduce((t,n)=>oe(t,n.meta),{})}function ki(e,t){const n={};for(const r in e)n[r]=r in t?t[r]:e[r];return n}function Ma(e,t){return t.children.some(n=>n===e||Ma(e,n))}function hg(e){const t={};if(e===""||e==="?")return t;const r=(e[0]==="?"?e.slice(1):e).split("&");for(let s=0;so&&Ss(o)):[r&&Ss(r)]).forEach(o=>{o!==void 0&&(t+=(t.length?"&":"")+n,o!=null&&(t+="="+o))})}return t}function pg(e){const t={};for(const n in e){const r=e[n];r!==void 0&&(t[n]=We(r)?r.map(s=>s==null?null:""+s):r==null?r:""+r)}return t}const gg=Symbol(""),Si=Symbol(""),po=Symbol(""),ja=Symbol(""),Is=Symbol("");function fn(){let e=[];function t(r){return e.push(r),()=>{const s=e.indexOf(r);s>-1&&e.splice(s,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function mt(e,t,n,r,s,o=i=>i()){const i=r&&(r.enterCallbacks[s]=r.enterCallbacks[s]||[]);return()=>new Promise((l,a)=>{const u=d=>{d===!1?a(tn(4,{from:n,to:t})):d instanceof Error?a(d):Zp(d)?a(tn(2,{from:t,to:d})):(i&&r.enterCallbacks[s]===i&&typeof d=="function"&&i.push(d),l())},c=o(()=>e.call(r&&r.instances[s],t,n,u));let f=Promise.resolve(c);e.length<3&&(f=f.then(u)),f.catch(d=>a(d))})}function Zr(e,t,n,r,s=o=>o()){const o=[];for(const i of e)for(const l in i.components){let a=i.components[l];if(!(t!=="beforeRouteEnter"&&!i.instances[l]))if(mg(a)){const c=(a.__vccOpts||a)[t];c&&o.push(mt(c,n,r,i,l,s))}else{let u=a();o.push(()=>u.then(c=>{if(!c)return Promise.reject(new Error(`Couldn't resolve component "${l}" at "${i.path}"`));const f=wp(c)?c.default:c;i.components[l]=f;const m=(f.__vccOpts||f)[t];return m&&mt(m,n,r,i,l,s)()}))}}return o}function mg(e){return typeof e=="object"||"displayName"in e||"props"in e||"__vccOpts"in e}function Li(e){const t=He(po),n=He(ja),r=Pe(()=>t.resolve(he(e.to))),s=Pe(()=>{const{matched:a}=r.value,{length:u}=a,c=a[u-1],f=n.matched;if(!c||!f.length)return-1;const d=f.findIndex(en.bind(null,c));if(d>-1)return d;const m=Ii(a[u-2]);return u>1&&Ii(c)===m&&f[f.length-1].path!==m?f.findIndex(en.bind(null,a[u-2])):d}),o=Pe(()=>s.value>-1&&bg(n.params,r.value.params)),i=Pe(()=>s.value>-1&&s.value===n.matched.length-1&&La(n.params,r.value.params));function l(a={}){return vg(a)?t[he(e.replace)?"replace":"push"](he(e.to)).catch(En):Promise.resolve()}return{route:r,href:Pe(()=>r.value.href),isActive:o,isExactActive:i,navigate:l}}const yg=ln({name:"RouterLink",compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:Li,setup(e,{slots:t}){const n=ot(Li(e)),{options:r}=He(po),s=Pe(()=>({[Hi(e.activeClass,r.linkActiveClass,"router-link-active")]:n.isActive,[Hi(e.exactActiveClass,r.linkExactActiveClass,"router-link-exact-active")]:n.isExactActive}));return()=>{const o=t.default&&t.default(n);return e.custom?o:Ve("a",{"aria-current":n.isExactActive?e.ariaCurrentValue:null,href:n.href,onClick:n.navigate,class:s.value},o)}}}),_g=yg;function vg(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function bg(e,t){for(const n in t){const r=t[n],s=e[n];if(typeof r=="string"){if(r!==s)return!1}else if(!We(s)||s.length!==r.length||r.some((o,i)=>o!==s[i]))return!1}return!0}function Ii(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const Hi=(e,t,n)=>e??t??n,Eg=ln({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:n}){const r=He(Is),s=Pe(()=>e.route||r.value),o=He(Si,0),i=Pe(()=>{let u=he(o);const{matched:c}=s.value;let f;for(;(f=c[u])&&!f.components;)u++;return u}),l=Pe(()=>s.value.matched[i.value]);zt(Si,Pe(()=>i.value+1)),zt(gg,l),zt(Is,s);const a=Ze();return qt(()=>[a.value,l.value,e.name],([u,c,f],[d,m,v])=>{c&&(c.instances[f]=u,m&&m!==c&&u&&u===d&&(c.leaveGuards.size||(c.leaveGuards=m.leaveGuards),c.updateGuards.size||(c.updateGuards=m.updateGuards))),u&&c&&(!m||!en(c,m)||!d)&&(c.enterCallbacks[f]||[]).forEach(R=>R(u))},{flush:"post"}),()=>{const u=s.value,c=e.name,f=l.value,d=f&&f.components[c];if(!d)return $i(n.default,{Component:d,route:u});const m=f.props[c],v=m?m===!0?u.params:typeof m=="function"?m(u):m:null,k=Ve(d,oe({},v,t,{onVnodeUnmounted:w=>{w.component.isUnmounted&&(f.instances[c]=null)},ref:a}));return $i(n.default,{Component:k,route:u})||k}}});function $i(e,t){if(!e)return null;const n=e(t);return n.length===1?n[0]:n}const Fa=Eg;function wg(e){const t=cg(e.routes,e),n=e.parseQuery||hg,r=e.stringifyQuery||Oi,s=e.history,o=fn(),i=fn(),l=fn(),a=Pn(Be);let u=Be;jt&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const c=Yr.bind(null,P=>""+P),f=Yr.bind(null,$p),d=Yr.bind(null,Ln);function m(P,F){let $,V;return $a(P)?($=t.getRecordMatcher(P),V=F):V=P,t.addRoute(V,$)}function v(P){const F=t.getRecordMatcher(P);F&&t.removeRoute(F)}function R(){return t.getRoutes().map(P=>P.record)}function k(P){return!!t.getRecordMatcher(P)}function w(P,F){if(F=oe({},F||a.value),typeof P=="string"){const _=Gr(n,P,F.path),E=t.resolve({path:_.path},F),T=s.createHref(_.fullPath);return oe(_,E,{params:d(E.params),hash:Ln(_.hash),redirectedFrom:void 0,href:T})}let $;if(P.path!=null)$=oe({},P,{path:Gr(n,P.path,F.path).path});else{const _=oe({},P.params);for(const E in _)_[E]==null&&delete _[E];$=oe({},P,{params:f(_)}),F.params=f(F.params)}const V=t.resolve($,F),se=P.hash||"";V.params=c(d(V.params));const h=jp(r,oe({},P,{hash:Lp(se),path:V.path})),p=s.createHref(h);return oe({fullPath:h,hash:se,query:r===Oi?pg(P.query):P.query||{}},V,{redirectedFrom:void 0,href:p})}function b(P){return typeof P=="string"?Gr(n,P,a.value.path):oe({},P)}function y(P,F){if(u!==P)return tn(8,{from:F,to:P})}function g(P){return N(P)}function C(P){return g(oe(b(P),{replace:!0}))}function I(P){const F=P.matched[P.matched.length-1];if(F&&F.redirect){const{redirect:$}=F;let V=typeof $=="function"?$(P):$;return typeof V=="string"&&(V=V.includes("?")||V.includes("#")?V=b(V):{path:V},V.params={}),oe({query:P.query,hash:P.hash,params:V.path!=null?{}:P.params},V)}}function N(P,F){const $=u=w(P),V=a.value,se=P.state,h=P.force,p=P.replace===!0,_=I($);if(_)return N(oe(b(_),{state:typeof _=="object"?oe({},se,_.state):se,force:h,replace:p}),F||$);const E=$;E.redirectedFrom=F;let T;return!h&&Fp(r,V,$)&&(T=tn(16,{to:E,from:V}),ze(V,V,!0,!1)),(T?Promise.resolve(T):M(E,V)).catch(A=>tt(A)?tt(A,2)?A:at(A):K(A,E,V)).then(A=>{if(A){if(tt(A,2))return N(oe({replace:p},b(A.to),{state:typeof A.to=="object"?oe({},se,A.to.state):se,force:h}),F||E)}else A=L(E,V,!0,p,se);return Q(E,V,A),A})}function O(P,F){const $=y(P,F);return $?Promise.reject($):Promise.resolve()}function D(P){const F=$t.values().next().value;return F&&typeof F.runWithContext=="function"?F.runWithContext(P):P()}function M(P,F){let $;const[V,se,h]=Rg(P,F);$=Zr(V.reverse(),"beforeRouteLeave",P,F);for(const _ of V)_.leaveGuards.forEach(E=>{$.push(mt(E,P,F))});const p=O.bind(null,P,F);return $.push(p),we($).then(()=>{$=[];for(const _ of o.list())$.push(mt(_,P,F));return $.push(p),we($)}).then(()=>{$=Zr(se,"beforeRouteUpdate",P,F);for(const _ of se)_.updateGuards.forEach(E=>{$.push(mt(E,P,F))});return $.push(p),we($)}).then(()=>{$=[];for(const _ of h)if(_.beforeEnter)if(We(_.beforeEnter))for(const E of _.beforeEnter)$.push(mt(E,P,F));else $.push(mt(_.beforeEnter,P,F));return $.push(p),we($)}).then(()=>(P.matched.forEach(_=>_.enterCallbacks={}),$=Zr(h,"beforeRouteEnter",P,F,D),$.push(p),we($))).then(()=>{$=[];for(const _ of i.list())$.push(mt(_,P,F));return $.push(p),we($)}).catch(_=>tt(_,8)?_:Promise.reject(_))}function Q(P,F,$){l.list().forEach(V=>D(()=>V(P,F,$)))}function L(P,F,$,V,se){const h=y(P,F);if(h)return h;const p=F===Be,_=jt?history.state:{};$&&(V||p?s.replace(P.fullPath,oe({scroll:p&&_&&_.scroll},se)):s.push(P.fullPath,se)),a.value=P,ze(P,F,$,p),at()}let J;function ae(){J||(J=s.listen((P,F,$)=>{if(!Dn.listening)return;const V=w(P),se=I(V);if(se){N(oe(se,{replace:!0}),V).catch(En);return}u=V;const h=a.value;jt&&zp(wi(h.fullPath,$.delta),Nr()),M(V,h).catch(p=>tt(p,12)?p:tt(p,2)?(N(p.to,V).then(_=>{tt(_,20)&&!$.delta&&$.type===In.pop&&s.go(-1,!1)}).catch(En),Promise.reject()):($.delta&&s.go(-$.delta,!1),K(p,V,h))).then(p=>{p=p||L(V,h,!1),p&&($.delta&&!tt(p,8)?s.go(-$.delta,!1):$.type===In.pop&&tt(p,20)&&s.go(-1,!1)),Q(V,h,p)}).catch(En)}))}let le=fn(),U=fn(),Z;function K(P,F,$){at(P);const V=U.list();return V.length?V.forEach(se=>se(P,F,$)):console.error(P),Promise.reject(P)}function Fe(){return Z&&a.value!==Be?Promise.resolve():new Promise((P,F)=>{le.add([P,F])})}function at(P){return Z||(Z=!P,ae(),le.list().forEach(([F,$])=>P?$(P):F()),le.reset()),P}function ze(P,F,$,V){const{scrollBehavior:se}=e;if(!jt||!se)return Promise.resolve();const h=!$&&Qp(wi(P.fullPath,0))||(V||!$)&&history.state&&history.state.scroll||null;return Mn().then(()=>se(P,F,h)).then(p=>p&&qp(p)).catch(p=>K(p,P,F))}const Ae=P=>s.go(P);let Ht;const $t=new Set,Dn={currentRoute:a,listening:!0,addRoute:m,removeRoute:v,hasRoute:k,getRoutes:R,resolve:w,options:e,push:g,replace:C,go:Ae,back:()=>Ae(-1),forward:()=>Ae(1),beforeEach:o.add,beforeResolve:i.add,afterEach:l.add,onError:U.add,isReady:Fe,install(P){const F=this;P.component("RouterLink",_g),P.component("RouterView",Fa),P.config.globalProperties.$router=F,Object.defineProperty(P.config.globalProperties,"$route",{enumerable:!0,get:()=>he(a)}),jt&&!Ht&&a.value===Be&&(Ht=!0,g(s.location).catch(se=>{}));const $={};for(const se in Be)Object.defineProperty($,se,{get:()=>a.value[se],enumerable:!0});P.provide(po,F),P.provide(ja,Nn($)),P.provide(Is,a);const V=P.unmount;$t.add(P),P.unmount=function(){$t.delete(P),$t.size<1&&(u=Be,J&&J(),J=null,a.value=Be,Ht=!1,Z=!1),V()}}};function we(P){return P.reduce((F,$)=>F.then(()=>D($)),Promise.resolve())}return Dn}function Rg(e,t){const n=[],r=[],s=[],o=Math.max(t.matched.length,e.matched.length);for(let i=0;ien(u,l))?r.push(l):n.push(l));const a=e.matched[i];a&&(t.matched.find(u=>en(u,a))||s.push(a))}return[n,r,s]}const Cg=(e,t)=>t.path.replace(/(:\w+)\([^)]+\)/g,"$1").replace(/(:\w+)[?+*]/g,"$1").replace(/:\w+/g,n=>{var r;return((r=e.params[n.slice(1)])==null?void 0:r.toString())||""}),Hs=(e,t)=>{const n=e.route.matched.find(s=>{var o;return((o=s.components)==null?void 0:o.default)===e.Component.type}),r=t??(n==null?void 0:n.meta.key)??(n&&Cg(e.route,n));return typeof r=="function"?r(e.route):r},Pg=(e,t)=>({default:()=>e?Ve(tu,e===!0?{}:e,t):t});function go(e){return Array.isArray(e)?e:[e]}const es=null,ts=null,nt=null,Ni=[{name:"slug",path:"/:slug(.*)*",meta:{},alias:[],redirect:es==null?void 0:es.redirect,component:()=>G(()=>import("./_...slug_.-1J-oLil.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8]),import.meta.url).then(e=>e.default||e)},{name:"index",path:"/",meta:{},alias:[],redirect:ts==null?void 0:ts.redirect,component:()=>G(()=>import("./index.XaakE1gN.js"),__vite__mapDeps([9,10]),import.meta.url).then(e=>e.default||e)},{name:void 0,path:"/blog/",meta:{},alias:[],redirect:nt==null?void 0:nt.redirect,component:()=>G(()=>import("./component-stub.J7zsssVp.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default||e)},{name:void 0,path:"/blog/concurrency",meta:{},alias:[],redirect:nt==null?void 0:nt.redirect,component:()=>G(()=>import("./component-stub.J7zsssVp.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default||e)},{name:void 0,path:"/blog/typescript-typesystems-and-javascript",meta:{},alias:[],redirect:nt==null?void 0:nt.redirect,component:()=>G(()=>import("./component-stub.J7zsssVp.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default||e)}],Tg=(e,t,n)=>(t=t===!0?{}:t,{default:()=>{var r;return t?Ve(e,t,n):(r=n.default)==null?void 0:r.call(n)}});function Mi(e){const t=(e==null?void 0:e.meta.key)??e.path.replace(/(:\w+)\([^)]+\)/g,"$1").replace(/(:\w+)[?+*]/g,"$1").replace(/:\w+/g,n=>{var r;return((r=e.params[n.slice(1)])==null?void 0:r.toString())||""});return typeof t=="function"?t(e):t}function Ag(e,t){return e===t||t===Be?!1:Mi(e)!==Mi(t)?!0:!e.matched.every((r,s)=>{var o,i;return r.components&&r.components.default===((i=(o=t.matched[s])==null?void 0:o.components)==null?void 0:i.default)})}const xg={scrollBehavior(e,t,n){var u;const r=ge(),s=((u=qe().options)==null?void 0:u.scrollBehaviorType)??"auto";let o=n||void 0;const i=typeof e.meta.scrollToTop=="function"?e.meta.scrollToTop(e,t):e.meta.scrollToTop;if(!o&&t&&e&&i!==!1&&Ag(e,t)&&(o={left:0,top:0}),e.path===t.path)return t.hash&&!e.hash?{left:0,top:0}:e.hash?{el:e.hash,top:ji(e.hash),behavior:s}:!1;const l=c=>!!(c.meta.pageTransition??Os),a=l(t)&&l(e)?"page:transition:finish":"page:finish";return new Promise(c=>{r.hooks.hookOnce(a,async()=>{await new Promise(f=>setTimeout(f,0)),e.hash&&(o={el:e.hash,top:ji(e.hash),behavior:s}),c(o)})})}};function ji(e){try{const t=document.querySelector(e);if(t)return parseFloat(getComputedStyle(t).scrollMarginTop)}catch{}return 0}const kg={hashMode:!1,scrollBehaviorType:"auto"},Le={...kg,...xg},Og=async e=>{var a;let t,n;if(!((a=e.meta)!=null&&a.validate))return;const r=ge(),s=qe();if(([t,n]=Sn(()=>Promise.resolve(e.meta.validate(e))),t=await t,n(),t)===!0)return;const i=Hr({statusCode:404,statusMessage:`Page Not Found: ${e.fullPath}`,data:{path:e.fullPath}}),l=s.beforeResolve(u=>{if(l(),u===e){const c=s.afterEach(async()=>{c(),await r.runWithContext(()=>Dt(i)),window.history.pushState({},"",e.fullPath)});return!1}})},Sg=async e=>{let t,n;const r=([t,n]=Sn(()=>Ca(e.path)),t=await t,n(),t);if(r.redirect)return r.redirect},Lg=[Og,Sg],Rn={};function Ig(e,t,n){const{pathname:r,search:s,hash:o}=t,i=e.indexOf("#");if(i>-1){const u=o.includes(e.slice(i))?e.slice(i).length:1;let c=o.slice(u);return c[0]!=="/"&&(c="/"+c),si(c,"")}const l=si(r,e),a=!n||Ff(l,n,{trailingSlash:!0})?l:n;return a+(a.includes("?")?"":s)+o}const Hg=Et({name:"nuxt:router",enforce:"pre",async setup(e){var R,k;let t,n,r=Sr().app.baseURL;Le.hashMode&&!r.includes("#")&&(r+="#");const s=((R=Le.history)==null?void 0:R.call(Le,r))??(Le.hashMode?Gp(r):Ha(r)),o=((k=Le.routes)==null?void 0:k.call(Le,Ni))??Ni;let i;const l=Ig(r,window.location,e.payload.path),a=wg({...Le,scrollBehavior:(w,b,y)=>{if(b===Be){i=y;return}if(Le.scrollBehavior){if(a.options.scrollBehavior=Le.scrollBehavior,"scrollRestoration"in window.history){const g=a.beforeEach(()=>{g(),window.history.scrollRestoration="manual"})}return Le.scrollBehavior(w,Be,i||y)}},history:s,routes:o});"scrollRestoration"in window.history&&(window.history.scrollRestoration="auto"),e.vueApp.use(a);const u=Pn(a.currentRoute.value);a.afterEach((w,b)=>{u.value=b}),Object.defineProperty(e.vueApp.config.globalProperties,"previousRoute",{get:()=>u.value});const c=Pn(a.resolve(l)),f=()=>{c.value=a.currentRoute.value};e.hook("page:finish",f),a.afterEach((w,b)=>{var y,g,C,I;((g=(y=w.matched[0])==null?void 0:y.components)==null?void 0:g.default)===((I=(C=b.matched[0])==null?void 0:C.components)==null?void 0:I.default)&&f()});const d={};for(const w in c.value)Object.defineProperty(d,w,{get:()=>c.value[w]});e._route=Nn(d),e._middleware=e._middleware||{global:[],named:{}};const m=Ir();try{[t,n]=Sn(()=>a.isReady()),await t,n()}catch(w){[t,n]=Sn(()=>e.runWithContext(()=>Dt(w))),await t,n()}const v=e.payload.state._layout;return a.beforeEach(async(w,b)=>{var y;await e.callHook("page:loading:start"),w.meta=ot(w.meta),e.isHydrating&&v&&!Lt(w.meta.layout)&&(w.meta.layout=v),e._processingMiddleware=!0;{const g=new Set([...Lg,...e._middleware.global]);for(const C of w.matched){const I=C.meta.middleware;if(I)for(const N of go(I))g.add(N)}for(const C of g){const I=typeof C=="string"?e._middleware.named[C]||await((y=Rn[C])==null?void 0:y.call(Rn).then(O=>O.default||O)):C;if(!I)throw new Error(`Unknown route middleware: '${C}'.`);const N=await e.runWithContext(()=>I(w,b));if(!e.payload.serverRendered&&e.isHydrating&&(N===!1||N instanceof Error)){const O=N||Ps({statusCode:404,statusMessage:`Page Not Found: ${l}`});return await e.runWithContext(()=>Dt(O)),!1}if(N!==!0&&(N||N===!1))return N}}}),a.onError(async()=>{delete e._processingMiddleware,await e.callHook("page:loading:end")}),a.afterEach(async(w,b,y)=>{delete e._processingMiddleware,!e.isHydrating&&m.value&&await e.runWithContext(ph),y&&await e.callHook("page:loading:end"),w.matched.length===0&&await e.runWithContext(()=>Dt(Ps({statusCode:404,fatal:!1,statusMessage:`Page not found: ${w.fullPath}`,data:{path:w.fullPath}})))}),e.hooks.hookOnce("app:created",async()=>{try{const w=a.resolve(l);"name"in w&&(w.name=void 0),await a.replace({...w,force:!0}),a.options.scrollBehavior=Le.scrollBehavior}catch(w){await e.runWithContext(()=>Dt(w))}}),{provide:{router:a}}}}),$s=globalThis.requestIdleCallback||(e=>{const t=Date.now(),n={didTimeout:!1,timeRemaining:()=>Math.max(0,50-(Date.now()-t))};return setTimeout(()=>{e(n)},1)}),$g=globalThis.cancelIdleCallback||(e=>{clearTimeout(e)}),mo=e=>{const t=ge();t.isHydrating?t.hooks.hookOnce("app:suspense:resolve",()=>{$s(e)}):$s(e)},Ng=Et({name:"nuxt:payload",setup(e){qe().beforeResolve(async(t,n)=>{if(t.path===n.path)return;const r=await yi(t.path);r&&Object.assign(e.static.data,r.data)}),mo(()=>{var t;e.hooks.hook("link:prefetch",async n=>{Fn(n).protocol||await yi(n)}),((t=navigator.connection)==null?void 0:t.effectiveType)!=="slow-2g"&&setTimeout($r,1e3)})}}),Mg=Et(e=>{let t;async function n(){const r=await $r();t&&clearTimeout(t),t=setTimeout(n,1e3*60*60);const s=await $fetch(ao("builds/latest.json")+`?${Date.now()}`);s.id!==r.id&&e.hooks.callHook("app:manifest:update",s)}mo(()=>{t=setTimeout(n,1e3*60*60)})}),jg=ee(()=>G(()=>import("./ContentDoc.rfis-nOt.js"),__vite__mapDeps([1,2,3,4,5,6,7,8]),import.meta.url).then(e=>e.default)),Fg=ee(()=>G(()=>import("./ContentList.3CoUdjPc.js"),__vite__mapDeps([11,7,8,6]),import.meta.url).then(e=>e.default)),Dg=ee(()=>G(()=>import("./ContentNavigation.f33EaOoS.js"),__vite__mapDeps([12,8,6]),import.meta.url).then(e=>e.default)),Bg=ee(()=>G(()=>import("./ContentQuery.8OtClJpg.js"),__vite__mapDeps([7,8,6]),import.meta.url).then(e=>e.default)),Ug=ee(()=>G(()=>import("./ContentRenderer.cy28u1UG.js"),__vite__mapDeps([3,4,5,6]),import.meta.url).then(e=>e.default)),Kg=ee(()=>G(()=>import("./ContentRendererMarkdown.T55ooTnH.js"),__vite__mapDeps([13,4,5,6]),import.meta.url).then(e=>e.default)),Vg=ee(()=>G(()=>import("./ContentSlot.4Yv1O94w.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),Wg=ee(()=>G(()=>import("./DocumentDrivenEmpty.2yjd1SSH.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),qg=ee(()=>G(()=>import("./DocumentDrivenNotFound.ifYdODZj.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),zg=ee(()=>G(()=>import("./Markdown.Ni6QM3--.js"),__vite__mapDeps([14,15]),import.meta.url).then(e=>e.default)),Qg=ee(()=>G(()=>import("./ProseCode.QIyOSdyq.js"),__vite__mapDeps([16,17,18]),import.meta.url).then(e=>e.default)),Jg=ee(()=>G(()=>import("./ProseCodeInline.o4JCub5L.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),Xg=ee(()=>G(()=>import("./ProsePre.3GHfg6KT.js"),__vite__mapDeps([19,17,18]),import.meta.url).then(e=>e.default)),Yg=ee(()=>G(()=>import("./ProseA.Gnk6FU_h.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),Gg=ee(()=>G(()=>import("./ProseBlockquote.IIuhyPCv.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),Zg=ee(()=>G(()=>import("./ProseEm.4QCYOuXW.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),em=ee(()=>G(()=>import("./ProseH1.eaEHGjQf.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),tm=ee(()=>G(()=>import("./ProseH2.yJsNSjEm.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),nm=ee(()=>G(()=>import("./ProseH3.tODisIiG.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),rm=ee(()=>G(()=>import("./ProseH4.xj30r601.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),sm=ee(()=>G(()=>import("./ProseH5.q9bEm_2Z.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),om=ee(()=>G(()=>import("./ProseH6.7fYg4335.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),im=ee(()=>G(()=>import("./ProseHr.a_aaQ3qF.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),lm=ee(()=>G(()=>import("./ProseImg.Uaqj6QZM.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),am=ee(()=>G(()=>import("./ProseLi.7JA3q9E2.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),cm=ee(()=>G(()=>import("./ProseOl.6gUkelNo.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),um=ee(()=>G(()=>import("./ProseP.XuucEeBj.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),fm=ee(()=>G(()=>import("./ProseScript.WQQ7lrh9.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),dm=ee(()=>G(()=>import("./ProseStrong.q8mG-bZC.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),hm=ee(()=>G(()=>import("./ProseTable.5kBeO5qI.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),pm=ee(()=>G(()=>import("./ProseTbody.FIDIkwnl.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),gm=ee(()=>G(()=>import("./ProseTd.KoI3F--9.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),mm=ee(()=>G(()=>import("./ProseTh.m9_aWQqV.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),ym=ee(()=>G(()=>import("./ProseThead.sBnyBi4S.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),_m=ee(()=>G(()=>import("./ProseTr.YtSXwZb5.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),vm=ee(()=>G(()=>import("./ProseUl.NGJ2KrmN.js"),__vite__mapDeps([]),import.meta.url).then(e=>e.default)),bm=[["ContentDoc",jg],["ContentList",Fg],["ContentNavigation",Dg],["ContentQuery",Bg],["ContentRenderer",Ug],["ContentRendererMarkdown",Kg],["MDCSlot",Vg],["DocumentDrivenEmpty",Wg],["DocumentDrivenNotFound",qg],["Markdown",zg],["ProseCode",Qg],["ProseCodeInline",Jg],["ProsePre",Xg],["ProseA",Yg],["ProseBlockquote",Gg],["ProseEm",Zg],["ProseH1",em],["ProseH2",tm],["ProseH3",nm],["ProseH4",rm],["ProseH5",sm],["ProseH6",om],["ProseHr",im],["ProseImg",lm],["ProseLi",am],["ProseOl",cm],["ProseP",um],["ProseScript",fm],["ProseStrong",dm],["ProseTable",hm],["ProseTbody",pm],["ProseTd",gm],["ProseTh",mm],["ProseThead",ym],["ProseTr",_m],["ProseUl",vm]],Em=Et({name:"nuxt:global-components",setup(e){for(const[t,n]of bm)e.vueApp.component(t,n),e.vueApp.component("Lazy"+t,n)}}),Gn={},wm=Et({name:"nuxt:prefetch",setup(e){const t=qe();e.hooks.hook("app:mounted",()=>{t.beforeEach(async n=>{var s;const r=(s=n==null?void 0:n.meta)==null?void 0:s.layout;r&&typeof Gn[r]=="function"&&await Gn[r]()})}),e.hooks.hook("link:prefetch",n=>{if(It(n))return;const r=t.resolve(n);if(!r)return;const s=r.meta.layout;let o=go(r.meta.middleware);o=o.filter(i=>typeof i=="string");for(const i of o)typeof Rn[i]=="function"&&Rn[i]();s&&typeof Gn[s]=="function"&&Gn[s]()})}});function Rm(e={}){const t=e.path||window.location.pathname;let n={};try{n=ws(sessionStorage.getItem("nuxt:reload")||"{}")}catch{}if(e.force||(n==null?void 0:n.path)!==t||(n==null?void 0:n.expires){r.clear()}),e.hook("app:chunkError",({error:o})=>{r.add(o)});function s(o){const l="href"in o&&o.href[0]==="#"?n.app.baseURL+o.href:an(n.app.baseURL,o.fullPath);Rm({path:l,persistState:!0})}e.hook("app:manifest:update",()=>{t.beforeResolve(s)}),t.onError((o,i)=>{r.has(o)&&s(i)})}}),Pm=[vp,Ep,Hg,Ng,Mg,Em,wm,Cm];async function Da(e,t=qe()){const{path:n,matched:r}=t.resolve(e);if(!r.length||(t._routePreloaded||(t._routePreloaded=new Set),t._routePreloaded.has(n)))return;const s=t._preloadPromises=t._preloadPromises||[];if(s.length>4)return Promise.all(s).then(()=>Da(e,t));t._routePreloaded.add(n);const o=r.map(i=>{var l;return(l=i.components)==null?void 0:l.default}).filter(i=>typeof i=="function");for(const i of o){const l=Promise.resolve(i()).catch(()=>{}).finally(()=>s.splice(s.indexOf(l)));s.push(l)}await Promise.all(s)}const Tm=(...e)=>e.find(t=>t!==void 0);function Am(e){const t=e.componentName||"NuxtLink";function n(r,s){if(!r||e.trailingSlash!=="append"&&e.trailingSlash!=="remove")return r;if(typeof r=="string")return Fi(r,e.trailingSlash);const o="path"in r&&r.path!==void 0?r.path:s(r).path,i={...r,path:Fi(o,e.trailingSlash)};return"name"in i&&delete i.name,i}return ln({name:t,props:{to:{type:[String,Object],default:void 0,required:!1},href:{type:[String,Object],default:void 0,required:!1},target:{type:String,default:void 0,required:!1},rel:{type:String,default:void 0,required:!1},noRel:{type:Boolean,default:void 0,required:!1},prefetch:{type:Boolean,default:void 0,required:!1},noPrefetch:{type:Boolean,default:void 0,required:!1},activeClass:{type:String,default:void 0,required:!1},exactActiveClass:{type:String,default:void 0,required:!1},prefetchedClass:{type:String,default:void 0,required:!1},replace:{type:Boolean,default:void 0,required:!1},ariaCurrentValue:{type:String,default:void 0,required:!1},external:{type:Boolean,default:void 0,required:!1},custom:{type:Boolean,default:void 0,required:!1}},setup(r,{slots:s}){const o=qe(),i=Sr(),l=Pe(()=>{const v=r.to||r.href||"";return n(v,o.resolve)}),a=Pe(()=>typeof l.value=="string"&&It(l.value,{acceptRelative:!0})),u=Pe(()=>r.target&&r.target!=="_self"),c=Pe(()=>r.external||u.value?!0:typeof l.value=="object"?!1:l.value===""||a.value),f=Ze(!1),d=Ze(null),m=v=>{var R;d.value=r.custom?(R=v==null?void 0:v.$el)==null?void 0:R.nextElementSibling:v==null?void 0:v.$el};if(r.prefetch!==!1&&r.noPrefetch!==!0&&r.target!=="_blank"&&!Om()){const R=ge();let k,w=null;Tr(()=>{const b=km();mo(()=>{k=$s(()=>{var y;(y=d==null?void 0:d.value)!=null&&y.tagName&&(w=b.observe(d.value,async()=>{w==null||w(),w=null;const g=typeof l.value=="string"?l.value:o.resolve(l.value).fullPath;await Promise.all([R.hooks.callHook("link:prefetch",g).catch(()=>{}),!c.value&&Da(l.value,o).catch(()=>{})]),f.value=!0}))})})}),Ar(()=>{k&&$g(k),w==null||w(),w=null})}return()=>{var w,b;if(!c.value){const y={ref:m,to:l.value,activeClass:r.activeClass||e.activeClass,exactActiveClass:r.exactActiveClass||e.exactActiveClass,replace:r.replace,ariaCurrentValue:r.ariaCurrentValue,custom:r.custom};return r.custom||(f.value&&(y.class=r.prefetchedClass||e.prefetchedClass),y.rel=r.rel||void 0),Ve(Uc("RouterLink"),y,s.default)}const v=typeof l.value=="object"?((w=o.resolve(l.value))==null?void 0:w.href)??null:l.value&&!r.external&&!a.value?n(an(i.app.baseURL,l.value),o.resolve):l.value||null,R=r.target||null,k=Tm(r.noRel?"":r.rel,e.externalRelAttribute,a.value||u.value?"noopener noreferrer":"")||null;if(r.custom){if(!s.default)return null;const y=()=>hh(v,{replace:r.replace,external:r.external});return s.default({href:v,navigate:y,get route(){if(!v)return;const g=Fn(v);return{path:g.pathname,fullPath:g.pathname,get query(){return Gl(g.search)},hash:g.hash,params:{},name:void 0,matched:[],redirectedFrom:void 0,meta:{},href:v}},rel:k,target:R,isExternal:c.value,isActive:!1,isExactActive:!1})}return Ve("a",{ref:d,href:v,rel:k,target:R},(b=s.default)==null?void 0:b.call(s))}}})}const xm=Am(dp);function Fi(e,t){const n=t==="append"?dr:Or;return It(e)&&!e.startsWith("http")?e:n(e,!0)}function km(){const e=ge();if(e._observer)return e._observer;let t=null;const n=new Map,r=(o,i)=>(t||(t=new IntersectionObserver(l=>{for(const a of l){const u=n.get(a.target);(a.isIntersecting||a.intersectionRatio>0)&&u&&u()}})),n.set(o,i),t.observe(o),()=>{n.delete(o),t.unobserve(o),n.size===0&&(t.disconnect(),t=null)});return e._observer={observe:r}}function Om(){const e=navigator.connection;return!!(e&&(e.saveData||/2g/.test(e.effectiveType)))}const Sm=ln({props:{vnode:{type:Object,required:!0},route:{type:Object,required:!0},vnodeRef:Object,renderKey:String,trackRootNodes:Boolean},setup(e){const t=e.renderKey,n=e.route,r={};for(const s in e.route)Object.defineProperty(r,s,{get:()=>t===e.renderKey?e.route[s]:n[s]});return zt(Lr,Nn(r)),()=>Ve(e.vnode,{ref:e.vnodeRef})}}),Lm=ln({name:"NuxtPage",inheritAttrs:!1,props:{name:{type:String},transition:{type:[Boolean,Object],default:void 0},keepalive:{type:[Boolean,Object],default:void 0},route:{type:Object},pageKey:{type:[Function,String],default:null}},setup(e,{attrs:t,expose:n}){const r=ge(),s=Ze(),o=He(Lr,null);let i;n({pageRef:s});const l=He(fh,null);let a;const u=r.deferHydration();if(r.isHydrating){const c=r.hooks.hookOnce("app:error",u);qe().beforeEach(c)}return e.pageKey&&qt(()=>e.pageKey,(c,f)=>{c!==f&&r.callHook("page:loading:start")}),()=>Ve(Fa,{name:e.name,route:e.route,...t},{default:c=>{const f=Hm(o,c.route,c.Component),d=o&&o.matched.length===c.route.matched.length;if(!c.Component){if(a&&!d)return a;u();return}if(a&&l&&!l.isCurrent(c.route))return a;if(f&&o&&(!l||l!=null&&l.isCurrent(o)))return d?a:null;const m=Hs(c,e.pageKey);!r.isHydrating&&!$m(o,c.route,c.Component)&&i===m&&r.callHook("page:loading:end"),i=m;const v=!!(e.transition??c.route.meta.pageTransition??Os),R=v&&Im([e.transition,c.route.meta.pageTransition,Os,{onAfterLeave:()=>{r.callHook("page:transition:finish",c.Component)}}].filter(Boolean)),k=e.keepalive??c.route.meta.keepalive??fp;return a=Tg(io,v&&R,Pg(k,Ve(vl,{suspensible:!0,onPending:()=>r.callHook("page:start",c.Component),onResolve:()=>{Mn(()=>r.callHook("page:finish",c.Component).then(()=>r.callHook("page:loading:end")).finally(u))}},{default:()=>{const w=Ve(Sm,{key:m||void 0,vnode:c.Component,route:c.route,renderKey:m||void 0,trackRootNodes:v,vnodeRef:s});return k&&(w.type.name=c.Component.type.name||c.Component.type.__name||"RouteProvider"),w}}))).default(),a}})}});function Im(e){const t=e.map(n=>({...n,onAfterLeave:n.onAfterLeave?go(n.onAfterLeave):void 0}));return da(...t)}function Hm(e,t,n){if(!e)return!1;const r=t.matched.findIndex(s=>{var o;return((o=s.components)==null?void 0:o.default)===(n==null?void 0:n.type)});return!r||r===-1?!1:t.matched.slice(0,r).some((s,o)=>{var i,l,a;return((i=s.components)==null?void 0:i.default)!==((a=(l=e.matched[o])==null?void 0:l.components)==null?void 0:a.default)})||n&&Hs({route:t,Component:n})!==Hs({route:e,Component:n})}function $m(e,t,n){return e?t.matched.findIndex(s=>{var o;return((o=s.components)==null?void 0:o.default)===(n==null?void 0:n.type)}){const n=e.__vccOpts||e;for(const[r,s]of t)n[r]=s;return n},Dm={},Bm={class:"w-full min-h-screen flex flex-col"},Um={class:"topnav h-54px p-2 bg-white"},Km={class:"container mx-auto flex justify-between items-center max-w-2xl m-auto h-9"},Vm=Su('
',1),Wm=Qt("hr",null,null,-1),qm={class:"p-2 bg-white w-full max-w-2xl mx-auto flex-1"};function zm(e,t){const n=xm,r=Lm;return Ye(),ku("div",Bm,[Qt("header",Um,[Qt("div",Km,[de(n,{class:"text-l",to:"/"},{default:Js(()=>[no("Netanel Haber's 🏠 Thingy")]),_:1}),Vm]),Wm]),Qt("div",qm,[de(r)])])}const Qm=Fm(Dm,[["render",zm]]),Jm={__name:"nuxt-error-page",props:{error:Object},setup(e){const n=e.error;(n.stack||"").split(` `).splice(1).map(f=>({text:f.replace("webpack:/","").replace(".vue",".js").trim(),internal:f.includes("node_modules")&&!f.includes(".cache")||f.includes("internal")||f.includes("new Promise")})).map(f=>`${f.text}`).join(` -`);const r=Number(n.statusCode||500),s=r===404,o=n.statusMessage??(s?"Page Not Found":"Internal Server Error"),i=n.message||n.toString(),l=void 0,c=s?ee(()=>G(()=>import("./error-404.RZ-3MmJ-.js"),__vite__mapDeps([20,2,21]),import.meta.url).then(f=>f.default||f)):ee(()=>G(()=>import("./error-500.JOTan9fW.js"),__vite__mapDeps([22,2,23]),import.meta.url).then(f=>f.default||f));return(f,d)=>(Ye(),yt(he(c),Ga(Vl({statusCode:he(r),statusMessage:he(o),description:he(i),stack:he(l)})),null,16))}},Xm=Jm,Ym={__name:"nuxt-root",setup(e){const t=()=>null,n=ge(),r=n.deferHydration();if(n.isHydrating){const l=n.hooks.hookOnce("app:error",r);qe().beforeEach(l)}const s=!1;zt(Lr,pa()),n.hooks.callHookWith(l=>l.map(a=>a()),"vue:setup");const o=Ir();xl((l,a,u)=>{if(n.hooks.callHook("vue:error",l,a,u).catch(c=>console.error("[nuxt] Error in `vue:error` hook",c)),gh(l)&&(l.fatal||l.unhandled))return n.runWithContext(()=>Dt(l)),!1});const i=!1;return(l,a)=>(Ye(),yt(vl,{onResolve:he(r)},{default:Js(()=>[he(o)?(Ye(),yt(he(Xm),{key:0,error:he(o)},null,8,["error"])):he(i)?(Ye(),yt(he(t),{key:1,context:he(i)},null,8,["context"])):he(s)?(Ye(),yt(Kc(he(s)),{key:2})):(Ye(),yt(he(Qm),{key:3}))]),_:1},8,["onResolve"]))}},Di=Ym;let Bi;{let e;Bi=async function(){var i,l;if(e)return e;const r=!!((i=window.__NUXT__)!=null&&i.serverRendered||((l=document.getElementById("__NUXT_DATA__"))==null?void 0:l.dataset.ssr)==="true")?gf(Di):pf(Di),s=zd({vueApp:r});async function o(a){await s.callHook("app:error",a),s.payload.error=s.payload.error||Hr(a)}r.config.errorHandler=o;try{await Jd(s,Pm)}catch(a){o(a)}try{await s.hooks.callHook("app:created",r),await s.hooks.callHook("app:beforeMount",r),r.mount(hp),await s.hooks.callHook("app:mounted",r),await Mn()}catch(a){o(a)}return r.config.errorHandler===o&&(r.config.errorHandler=void 0),r},e=Bi().catch(t=>{throw console.error("Error while mounting app:",t),t})}export{yt as $,uy as A,sy as B,Ar as C,ru as D,nu as E,ke as F,As as G,kr as H,G as I,Oc as J,ve as K,ge as L,ty as M,fy as N,Pn as O,ou as P,Al as Q,Hr as R,cy as S,ri as T,an as U,Or as V,re as W,Uc as X,Jt as Y,ws as Z,Fm as _,Qt as a,rc as a0,Zm as a1,ey as a2,iy as a3,de as b,ku as c,no as d,xm as e,ry as f,ln as g,Pe as h,qt as i,Tr as j,oy as k,vr as l,ay as m,br as n,Ye as o,ny as p,pa as q,Ze as r,Mn as s,Gm as t,he as u,Sr as v,Js as w,ly as x,dr as y,Ve as z}; +`);const r=Number(n.statusCode||500),s=r===404,o=n.statusMessage??(s?"Page Not Found":"Internal Server Error"),i=n.message||n.toString(),l=void 0,c=s?ee(()=>G(()=>import("./error-404.AT6CNjAs.js"),__vite__mapDeps([20,2,21]),import.meta.url).then(f=>f.default||f)):ee(()=>G(()=>import("./error-500.5nitSuEA.js"),__vite__mapDeps([22,2,23]),import.meta.url).then(f=>f.default||f));return(f,d)=>(Ye(),yt(he(c),Ga(Vl({statusCode:he(r),statusMessage:he(o),description:he(i),stack:he(l)})),null,16))}},Xm=Jm,Ym={__name:"nuxt-root",setup(e){const t=()=>null,n=ge(),r=n.deferHydration();if(n.isHydrating){const l=n.hooks.hookOnce("app:error",r);qe().beforeEach(l)}const s=!1;zt(Lr,pa()),n.hooks.callHookWith(l=>l.map(a=>a()),"vue:setup");const o=Ir();xl((l,a,u)=>{if(n.hooks.callHook("vue:error",l,a,u).catch(c=>console.error("[nuxt] Error in `vue:error` hook",c)),gh(l)&&(l.fatal||l.unhandled))return n.runWithContext(()=>Dt(l)),!1});const i=!1;return(l,a)=>(Ye(),yt(vl,{onResolve:he(r)},{default:Js(()=>[he(o)?(Ye(),yt(he(Xm),{key:0,error:he(o)},null,8,["error"])):he(i)?(Ye(),yt(he(t),{key:1,context:he(i)},null,8,["context"])):he(s)?(Ye(),yt(Kc(he(s)),{key:2})):(Ye(),yt(he(Qm),{key:3}))]),_:1},8,["onResolve"]))}},Di=Ym;let Bi;{let e;Bi=async function(){var i,l;if(e)return e;const r=!!((i=window.__NUXT__)!=null&&i.serverRendered||((l=document.getElementById("__NUXT_DATA__"))==null?void 0:l.dataset.ssr)==="true")?gf(Di):pf(Di),s=zd({vueApp:r});async function o(a){await s.callHook("app:error",a),s.payload.error=s.payload.error||Hr(a)}r.config.errorHandler=o;try{await Jd(s,Pm)}catch(a){o(a)}try{await s.hooks.callHook("app:created",r),await s.hooks.callHook("app:beforeMount",r),r.mount(hp),await s.hooks.callHook("app:mounted",r),await Mn()}catch(a){o(a)}return r.config.errorHandler===o&&(r.config.errorHandler=void 0),r},e=Bi().catch(t=>{throw console.error("Error while mounting app:",t),t})}export{yt as $,uy as A,sy as B,Ar as C,ru as D,nu as E,ke as F,As as G,kr as H,G as I,Oc as J,ve as K,ge as L,ty as M,fy as N,Pn as O,ou as P,Al as Q,Hr as R,cy as S,ri as T,an as U,Or as V,re as W,Uc as X,Jt as Y,ws as Z,Fm as _,Qt as a,rc as a0,Zm as a1,ey as a2,iy as a3,de as b,ku as c,no as d,xm as e,ry as f,ln as g,Pe as h,qt as i,Tr as j,oy as k,vr as l,ay as m,br as n,Ye as o,ny as p,pa as q,Ze as r,Mn as s,Gm as t,he as u,Sr as v,Js as w,ly as x,dr as y,Ve as z}; function __vite__mapDeps(indexes) { if (!__vite__mapDeps.viteFileDeps) { - __vite__mapDeps.viteFileDeps = ["./_...slug_.6mwjtp-q.js","./ContentDoc.m4erpRCJ.js","./vue.f36acd1f.ZfSKW0Tx.js","./ContentRenderer.0Ci8vnAh.js","./ContentRendererMarkdown.vue.QtxrB05Z.js","./index.1dSrIji7.js","./preview.WHtoAZxr.js","./ContentQuery.7IlyA-wt.js","./query.veKqiZiu.js","./index.yVYxWBDr.js","./index.4XUzm4qg.css","./ContentList.YfCz_pZv.js","./ContentNavigation.4-dxUQeo.js","./ContentRendererMarkdown.TQHLBOHw.js","./Markdown.PGpQEzUu.js","./ContentSlot.yUuC7AiQ.js","./ProseCode.4ZscnP7G.js","./ProseCode.vue.L3vrDCRe.js","./ProsePre.nIRUQbb-.css","./ProsePre.f92e3HR-.js","./error-404.RZ-3MmJ-.js","./error-404.HTf4NPW_.css","./error-500.JOTan9fW.js","./error-500.s2VBNbvW.css"] + __vite__mapDeps.viteFileDeps = ["./_...slug_.-1J-oLil.js","./ContentDoc.rfis-nOt.js","./vue.f36acd1f.jcQdGPHq.js","./ContentRenderer.cy28u1UG.js","./ContentRendererMarkdown.vue.RczDmK50.js","./index.1dSrIji7.js","./preview.99XykmGH.js","./ContentQuery.8OtClJpg.js","./query.9Ah2Ct9x.js","./index.XaakE1gN.js","./index.4QcPPhLg.css","./ContentList.3CoUdjPc.js","./ContentNavigation.f33EaOoS.js","./ContentRendererMarkdown.T55ooTnH.js","./Markdown.Ni6QM3--.js","./ContentSlot.4Yv1O94w.js","./ProseCode.QIyOSdyq.js","./ProseCode.vue.rbas8gSm.js","./ProsePre.nIRUQbb-.css","./ProsePre.3GHfg6KT.js","./error-404.AT6CNjAs.js","./error-404.HTf4NPW_.css","./error-500.5nitSuEA.js","./error-500.s2VBNbvW.css"] } return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) } diff --git a/_nuxt/error-404.RZ-3MmJ-.js b/_nuxt/error-404.AT6CNjAs.js similarity index 94% rename from _nuxt/error-404.RZ-3MmJ-.js rename to _nuxt/error-404.AT6CNjAs.js index a3a68ea..88b0e6c 100644 --- a/_nuxt/error-404.RZ-3MmJ-.js +++ b/_nuxt/error-404.AT6CNjAs.js @@ -1 +1 @@ -import{_ as a,o as n,c as r,a as e,t as s,b as d,w as l,d as c,e as p,p as f,f as m}from"./entry.kyqmbcaI.js";import{u as h}from"./vue.f36acd1f.ZfSKW0Tx.js";const x=t=>(f("data-v-ccd3db62"),t=t(),m(),t),u={class:"font-sans antialiased bg-white dark:bg-black text-black dark:text-white grid min-h-screen place-content-center overflow-hidden"},g=x(()=>e("div",{class:"fixed left-0 right-0 spotlight z-10"},null,-1)),b={class:"max-w-520px text-center z-20"},_=["textContent"],w=["textContent"],y={class:"w-full flex items-center justify-center"},S={__name:"error-404",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:404},statusMessage:{type:String,default:"Not Found"},description:{type:String,default:"Sorry, the page you are looking for could not be found."},backHome:{type:String,default:"Go back home"}},setup(t){const o=t;return h({title:`${o.statusCode} - ${o.statusMessage} | ${o.appName}`,script:[],style:[{children:'*,:before,:after{-webkit-box-sizing:border-box;box-sizing:border-box;border-width:0;border-style:solid;border-color:#e0e0e0}*{--tw-ring-inset:var(--tw-empty, );--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(14, 165, 233, .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000}:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}a{color:inherit;text-decoration:inherit}body{margin:0;font-family:inherit;line-height:inherit}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}h1,p{margin:0}h1{font-size:inherit;font-weight:inherit}'}]}),(k,N)=>{const i=p;return n(),r("div",u,[g,e("div",b,[e("h1",{class:"text-8xl sm:text-10xl font-medium mb-8",textContent:s(t.statusCode)},null,8,_),e("p",{class:"text-xl px-8 sm:px-0 sm:text-4xl font-light mb-16 leading-tight",textContent:s(t.description)},null,8,w),e("div",y,[d(i,{to:"/",class:"gradient-border text-md sm:text-xl py-2 px-4 sm:py-3 sm:px-6 cursor-pointer"},{default:l(()=>[c(s(t.backHome),1)]),_:1})])])])}}},C=a(S,[["__scopeId","data-v-ccd3db62"]]);export{C as default}; +import{_ as a,o as n,c as r,a as e,t as s,b as d,w as l,d as c,e as p,p as f,f as m}from"./entry.PS9LLiT2.js";import{u as h}from"./vue.f36acd1f.jcQdGPHq.js";const x=t=>(f("data-v-ccd3db62"),t=t(),m(),t),u={class:"font-sans antialiased bg-white dark:bg-black text-black dark:text-white grid min-h-screen place-content-center overflow-hidden"},g=x(()=>e("div",{class:"fixed left-0 right-0 spotlight z-10"},null,-1)),b={class:"max-w-520px text-center z-20"},_=["textContent"],w=["textContent"],y={class:"w-full flex items-center justify-center"},S={__name:"error-404",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:404},statusMessage:{type:String,default:"Not Found"},description:{type:String,default:"Sorry, the page you are looking for could not be found."},backHome:{type:String,default:"Go back home"}},setup(t){const o=t;return h({title:`${o.statusCode} - ${o.statusMessage} | ${o.appName}`,script:[],style:[{children:'*,:before,:after{-webkit-box-sizing:border-box;box-sizing:border-box;border-width:0;border-style:solid;border-color:#e0e0e0}*{--tw-ring-inset:var(--tw-empty, );--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(14, 165, 233, .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000}:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}a{color:inherit;text-decoration:inherit}body{margin:0;font-family:inherit;line-height:inherit}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}h1,p{margin:0}h1{font-size:inherit;font-weight:inherit}'}]}),(k,N)=>{const i=p;return n(),r("div",u,[g,e("div",b,[e("h1",{class:"text-8xl sm:text-10xl font-medium mb-8",textContent:s(t.statusCode)},null,8,_),e("p",{class:"text-xl px-8 sm:px-0 sm:text-4xl font-light mb-16 leading-tight",textContent:s(t.description)},null,8,w),e("div",y,[d(i,{to:"/",class:"gradient-border text-md sm:text-xl py-2 px-4 sm:py-3 sm:px-6 cursor-pointer"},{default:l(()=>[c(s(t.backHome),1)]),_:1})])])])}}},C=a(S,[["__scopeId","data-v-ccd3db62"]]);export{C as default}; diff --git a/_nuxt/error-500.JOTan9fW.js b/_nuxt/error-500.5nitSuEA.js similarity index 93% rename from _nuxt/error-500.JOTan9fW.js rename to _nuxt/error-500.5nitSuEA.js index 0cd04ad..96a1c90 100644 --- a/_nuxt/error-500.JOTan9fW.js +++ b/_nuxt/error-500.5nitSuEA.js @@ -1 +1 @@ -import{u as i}from"./vue.f36acd1f.ZfSKW0Tx.js";import{_ as a,o as r,c as n,a as e,t as s,p as l,f as d}from"./entry.kyqmbcaI.js";const c=t=>(l("data-v-df79c84d"),t=t(),d(),t),p={class:"font-sans antialiased bg-white dark:bg-black text-black dark:text-white grid min-h-screen place-content-center overflow-hidden"},f=c(()=>e("div",{class:"fixed -bottom-1/2 left-0 right-0 h-1/2 spotlight"},null,-1)),h={class:"max-w-520px text-center"},m=["textContent"],g=["textContent"],x={__name:"error-500",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:500},statusMessage:{type:String,default:"Server error"},description:{type:String,default:"This page is temporarily unavailable."}},setup(t){const o=t;return i({title:`${o.statusCode} - ${o.statusMessage} | ${o.appName}`,script:[],style:[{children:'*,:before,:after{-webkit-box-sizing:border-box;box-sizing:border-box;border-width:0;border-style:solid;border-color:#e0e0e0}*{--tw-ring-inset:var(--tw-empty, );--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(14, 165, 233, .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000}:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{margin:0;font-family:inherit;line-height:inherit}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}h1,p{margin:0}h1{font-size:inherit;font-weight:inherit}'}]}),(b,u)=>(r(),n("div",p,[f,e("div",h,[e("h1",{class:"text-8xl sm:text-10xl font-medium mb-8",textContent:s(t.statusCode)},null,8,m),e("p",{class:"text-xl px-8 sm:px-0 sm:text-4xl font-light mb-16 leading-tight",textContent:s(t.description)},null,8,g)])]))}},y=a(x,[["__scopeId","data-v-df79c84d"]]);export{y as default}; +import{u as i}from"./vue.f36acd1f.jcQdGPHq.js";import{_ as a,o as r,c as n,a as e,t as s,p as l,f as d}from"./entry.PS9LLiT2.js";const c=t=>(l("data-v-df79c84d"),t=t(),d(),t),p={class:"font-sans antialiased bg-white dark:bg-black text-black dark:text-white grid min-h-screen place-content-center overflow-hidden"},f=c(()=>e("div",{class:"fixed -bottom-1/2 left-0 right-0 h-1/2 spotlight"},null,-1)),h={class:"max-w-520px text-center"},m=["textContent"],g=["textContent"],x={__name:"error-500",props:{appName:{type:String,default:"Nuxt"},version:{type:String,default:""},statusCode:{type:Number,default:500},statusMessage:{type:String,default:"Server error"},description:{type:String,default:"This page is temporarily unavailable."}},setup(t){const o=t;return i({title:`${o.statusCode} - ${o.statusMessage} | ${o.appName}`,script:[],style:[{children:'*,:before,:after{-webkit-box-sizing:border-box;box-sizing:border-box;border-width:0;border-style:solid;border-color:#e0e0e0}*{--tw-ring-inset:var(--tw-empty, );--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(14, 165, 233, .5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000}:root{-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{margin:0;font-family:inherit;line-height:inherit}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";line-height:1.5}h1,p{margin:0}h1{font-size:inherit;font-weight:inherit}'}]}),(b,u)=>(r(),n("div",p,[f,e("div",h,[e("h1",{class:"text-8xl sm:text-10xl font-medium mb-8",textContent:s(t.statusCode)},null,8,m),e("p",{class:"text-xl px-8 sm:px-0 sm:text-4xl font-light mb-16 leading-tight",textContent:s(t.description)},null,8,g)])]))}},y=a(x,[["__scopeId","data-v-df79c84d"]]);export{y as default}; diff --git a/_nuxt/index.4QcPPhLg.css b/_nuxt/index.4QcPPhLg.css new file mode 100644 index 0000000..74c8c3d --- /dev/null +++ b/_nuxt/index.4QcPPhLg.css @@ -0,0 +1 @@ +@keyframes nyan-cat-animation-a8e25a87{0%{background-position:0 50%}to{background-position:100% 50%}}.nyan[data-v-a8e25a87]{animation:nyan-cat-animation-a8e25a87 5s linear infinite;background-size:600% 600%} diff --git a/_nuxt/index.4XUzm4qg.css b/_nuxt/index.4XUzm4qg.css deleted file mode 100644 index 43dc9f8..0000000 --- a/_nuxt/index.4XUzm4qg.css +++ /dev/null @@ -1 +0,0 @@ -@keyframes nyan-cat-animation-07833b6c{0%{background-position:0 50%}to{background-position:100% 50%}}.nyan[data-v-07833b6c]{animation:nyan-cat-animation-07833b6c 5s linear infinite;background-size:600% 600%} diff --git a/_nuxt/index.XaakE1gN.js b/_nuxt/index.XaakE1gN.js new file mode 100644 index 0000000..7077e32 --- /dev/null +++ b/_nuxt/index.XaakE1gN.js @@ -0,0 +1 @@ +import{g as u,r as w,h as x,i as k,j as y,o as n,c as o,a as t,F as _,k as b,n as v,l as g,u as c,m as C,_ as S,b as p,w as A,d as B,t as m,e as F}from"./entry.PS9LLiT2.js";const I={class:"flex gap-2 p-1 flex-wrap justify-center"},E=["onClick","aria-label","aria-pressed"],T=["src"],V={key:0},$=["src"],N=u({__name:"Apps",setup(f){const l=Object.entries({checkers:{name:"Vanilla TS Checkers",href:"https://netanel-haber.github.io/checkers/",background:"linear-gradient(rgba(115, 104, 122, 0.709), rgb(93, 20, 133))",image:"/checkers.webp",height:"775px"},chatgpt:{name:"My ChatGPT Custom Instructions",href:"https://netanel-haber.github.io/chatgpt-custom-instructions/",background:"radial-gradient(circle, rgb(216, 200, 200) 0%, #00a67fae 100%)",image:"https://upload.wikimedia.org/wikipedia/commons/0/04/ChatGPT_logo.svg",height:"950px"},nyan:{name:"Tiny React Infinite Scroll",href:"https://codesandbox.io/embed/78wnx?view=preview&module=%2Fsrc%2Fuseinfinitescroll.js&hidenavigation=1",background:"linear-gradient(60deg, #ff0084, #ffce00, #29adff, #ff77a8, #ffccaa)",image:"/nyan.gif",height:"500px",class:"nyan"},resume:{name:"Resume",href:"https://www.netanel.dev/resume.pdf",background:"radial-gradient(circle, rgba(67,149,162,0.7570621468926554) 7%, rgba(249,212,72,0.8418079096045198) 45%, rgba(124,166,85,0.9491525423728814) 100%)",image:"/resume.webp",height:"850px"},password:{name:"Chrome Strong Password Generator",href:"https://netanel.dev/pwd",background:"radial-gradient(circle at 20% 4%, #4A90E2 0%, #4A90E2 25%, #DB4437 50%, #DB4437 75%, #F4B400 100%), radial-gradient(circle at 4% 4%, #4A90E2 0%, #4A90E2 25%, #0F9D58 50%, #F4B400 75%, #F4B400 100%)",image:"https://upload.wikimedia.org/wikipedia/commons/e/e1/Google_Chrome_icon_%28February_2022%29.svg",height:"300px"},wiki:{name:"Friend Reaches 500 Wiki Edits",href:"/talor-wiki.html",background:"radial-gradient(circle, #d6cab9 20%, #8da7b9 60%, #2d5f73 100%)",image:"/globe.webp",height:"850px"},"mac-apps":{name:"Suggested Mac Apps",href:"/mac-apps.html",background:"linear-gradient(90deg, rgb(240 238 234) 46%, rgb(141, 167, 185) 54%, rgb(55 144 179) 100%)",image:"/mac-logo.png",height:"450px"},"ubuntu-apps":{name:"Suggested Ubuntu Apps",href:"/ubuntu-apps.html",background:"linear-gradient(90deg, rgb(221, 72, 20) 0%, rgb(252, 99, 25) 50%, rgb(255, 148, 86) 100%)",image:"/ubuntu-logo.png",height:"450px"}}).map(([e,a])=>({...a,hash:e})),r=w(window==null?void 0:window.location.hash.slice(1)),i=x(()=>l.find(e=>e.hash===r.value)),d=e=>{var a;return((a=i.value)==null?void 0:a.hash)===e.hash},h=e=>{r.value=d(e)?"":e.hash};return k(r,e=>{window.location&&(window.location.hash=e)}),y(()=>{var e;(e=document.getElementById("app"))==null||e.scrollIntoView(),window.addEventListener("hashchange",()=>{var a;(a=document.getElementById("app"))==null||a.scrollIntoView({behavior:"smooth"}),r.value=window.location.hash.slice(1)})}),(e,a)=>(n(),o("div",null,[t("section",I,[(n(!0),o(_,null,b(c(l),s=>(n(),o("button",{key:s.hash,class:v([s.class,"w-[135px] h-[135px] rounded-md focus:shadow-[rgba(0,_0,_0,_0.75)_3px_3px_6px_-1px]"]),onClick:L=>h(s),"aria-label":s.name,style:g({backgroundImage:s.background}),"aria-pressed":d(s)},[t("img",{src:s.image,class:"w-full h-full p-1 rounded-md"},null,8,T)],14,E))),128))]),c(i)?(n(),o("section",V,[(n(),o("iframe",{id:"app",key:c(i).hash,class:"w-full my-4 border",allow:"clipboard-write",style:g({height:c(i).height}),src:c(i).href},null,12,$))])):C("",!0)]))}}),j=S(N,[["__scopeId","data-v-a8e25a87"]]),D={class:"mx-auto flex flex-col"},G={class:"mb-3 flex flex-col gap-3"},P={class:"p-1"},M={class:"mb-2"},R={class:"text-sm text-gray-600"},z=t("hr",null,null,-1),J=u({__name:"index",setup(f){const l=[{title:"Ok, Sometimes Async-Await",description:"I'll concede in 3 cases",to:"/ok-sometimes-async-await"},{title:"Concurrency",description:"Yes, Python has threads (*Sigh*)",to:"/concurrency"},{title:"TypeScript, TypeSystems and JavaScript",description:"Notepad -> Notepad++",to:"/typescript-typesystems-and-javascript"}];return(r,i)=>{const d=F,h=j;return n(),o("main",D,[t("section",G,[(n(),o(_,null,b(l,e=>t("article",null,[t("div",P,[t("div",M,[p(d,{class:"text-blue-600 text-lg",to:e.to},{default:A(()=>[B(m(e.title),1)]),_:2},1032,["to"])]),t("div",R,m(e.description),1)]),z])),64))]),p(h)])}}});export{J as default}; diff --git a/_nuxt/index.yVYxWBDr.js b/_nuxt/index.yVYxWBDr.js deleted file mode 100644 index de302e5..0000000 --- a/_nuxt/index.yVYxWBDr.js +++ /dev/null @@ -1 +0,0 @@ -import{g as u,r as w,h as x,i as k,j as y,o as n,c as i,a as t,F as _,k as f,n as v,l as m,u as r,m as C,_ as F,b as p,w as B,d as E,t as g,e as I}from"./entry.kyqmbcaI.js";const S={class:"flex gap-2 p-1 flex-wrap justify-center"},A=["onClick","aria-label","aria-pressed"],T=["src"],V={key:0},$=["src"],N=u({__name:"Apps",setup(b){const l=Object.entries({checkers:{name:"Vanilla TS Checkers",href:"https://netanel-haber.github.io/checkers/",background:"linear-gradient(rgba(115, 104, 122, 0.709), rgb(93, 20, 133))",image:"/checkers.webp",height:"775px"},chatgpt:{name:"My ChatGPT Custom Instructions",href:"https://netanel-haber.github.io/chatgpt-custom-instructions/",background:"radial-gradient(circle, rgb(216, 200, 200) 0%, #00a67fae 100%)",image:"https://upload.wikimedia.org/wikipedia/commons/0/04/ChatGPT_logo.svg",height:"950px"},nyan:{name:"Tiny React Infinite Scroll",href:"https://codesandbox.io/embed/78wnx?view=preview&module=%2Fsrc%2Fuseinfinitescroll.js&hidenavigation=1",background:"linear-gradient(60deg, #ff0084, #ffce00, #29adff, #ff77a8, #ffccaa)",image:"/nyan.gif",height:"500px",class:"nyan"},resume:{name:"Resume",href:"https://www.netanel.dev/resume.pdf",background:"radial-gradient(circle, rgba(67,149,162,0.7570621468926554) 7%, rgba(249,212,72,0.8418079096045198) 45%, rgba(124,166,85,0.9491525423728814) 100%)",image:"/resume.webp",height:"850px"},password:{name:"Chrome Strong Password Generator",href:"https://netanel.dev/pwd",background:"radial-gradient(circle at 20% 4%, #4A90E2 0%, #4A90E2 25%, #DB4437 50%, #DB4437 75%, #F4B400 100%), radial-gradient(circle at 4% 4%, #4A90E2 0%, #4A90E2 25%, #0F9D58 50%, #F4B400 75%, #F4B400 100%)",image:"https://upload.wikimedia.org/wikipedia/commons/e/e1/Google_Chrome_icon_%28February_2022%29.svg",height:"300px"},wiki:{name:"Friend Reaches 500 Wiki Edits",href:"/talor-wiki.html",background:"radial-gradient(circle, #d6cab9 20%, #8da7b9 60%, #2d5f73 100%)",image:"/globe.webp",height:"850px"},"mac-apps":{name:"Friend Reaches 500 Wiki Edits",href:"/mac-apps.html",background:"linear-gradient(90deg, rgb(240 238 234) 46%, rgb(141, 167, 185) 54%, rgb(55 144 179) 100%)",image:"/mac-logo.png",height:"375px"}}).map(([e,a])=>({...a,hash:e})),c=w(window==null?void 0:window.location.hash.slice(1)),o=x(()=>l.find(e=>e.hash===c.value)),d=e=>{var a;return((a=o.value)==null?void 0:a.hash)===e.hash},h=e=>{c.value=d(e)?"":e.hash};return k(c,e=>{window.location&&(window.location.hash=e)}),y(()=>{var e;(e=document.getElementById("app"))==null||e.scrollIntoView(),window.addEventListener("hashchange",()=>{var a;(a=document.getElementById("app"))==null||a.scrollIntoView({behavior:"smooth"}),c.value=window.location.hash.slice(1)})}),(e,a)=>(n(),i("div",null,[t("section",S,[(n(!0),i(_,null,f(r(l),s=>(n(),i("button",{key:s.hash,class:v([s.class,"w-[135px] h-[135px] rounded-md focus:shadow-[rgba(0,_0,_0,_0.75)_3px_3px_6px_-1px]"]),onClick:M=>h(s),"aria-label":s.name,style:m({backgroundImage:s.background}),"aria-pressed":d(s)},[t("img",{src:s.image,class:"w-full h-full p-1 rounded-md"},null,8,T)],14,A))),128))]),r(o)?(n(),i("section",V,[(n(),i("iframe",{id:"app",key:r(o).hash,class:"w-full my-4 border",allow:"clipboard-write",style:m({height:r(o).height}),src:r(o).href},null,12,$))])):C("",!0)]))}}),j=F(N,[["__scopeId","data-v-07833b6c"]]),D={class:"mx-auto flex flex-col"},G={class:"mb-3 flex flex-col gap-3"},P={class:"p-1"},R={class:"mb-2"},z={class:"text-sm text-gray-600"},L=t("hr",null,null,-1),W=u({__name:"index",setup(b){const l=[{title:"Ok, Sometimes Async-Await",description:"I'll concede in 3 cases",to:"/ok-sometimes-async-await"},{title:"Concurrency",description:"Yes, Python has threads (*Sigh*)",to:"/concurrency"},{title:"TypeScript, TypeSystems and JavaScript",description:"Notepad -> Notepad++",to:"/typescript-typesystems-and-javascript"}];return(c,o)=>{const d=I,h=j;return n(),i("main",D,[t("section",G,[(n(),i(_,null,f(l,e=>t("article",null,[t("div",P,[t("div",R,[p(d,{class:"text-blue-600 text-lg",to:e.to},{default:B(()=>[E(g(e.title),1)]),_:2},1032,["to"])]),t("div",z,g(e.description),1)]),L])),64))]),p(h)])}}});export{W as default}; diff --git a/_nuxt/preview.WHtoAZxr.js b/_nuxt/preview.99XykmGH.js similarity index 99% rename from _nuxt/preview.WHtoAZxr.js rename to _nuxt/preview.99XykmGH.js index c799131..7c90efe 100644 --- a/_nuxt/preview.WHtoAZxr.js +++ b/_nuxt/preview.99XykmGH.js @@ -1,3 +1,3 @@ -import{r as L,a0 as P,a1 as z,i as F,a2 as H,Z as K,s as q,q as x}from"./entry.kyqmbcaI.js";const S=/^[\u0009\u0020-\u007E\u0080-\u00FF]+$/;function V(t,i){if(typeof t!="string")throw new TypeError("argument str must be a string");const n={},r=(i||{}).decode||X;let o=0;for(;o{i+=r};return{toString(){return i},getContext(){return n},dispatch(r){return t.replacer&&(r=t.replacer(r)),this[r===null?"null":typeof r](r)},object(r){if(r&&typeof r.toJSON=="function")return this.object(r.toJSON());const o=Object.prototype.toString.call(r);let s="";const a=o.length;a<10?s="unknown:["+o+"]":s=o.slice(8,a-1),s=s.toLowerCase();let c=null;if((c=n.get(r))===void 0)n.set(r,n.size);else return this.dispatch("[CIRCULAR:"+c+"]");if(typeof Buffer<"u"&&Buffer.isBuffer&&Buffer.isBuffer(r))return e("buffer:"),e(r.toString("utf8"));if(s!=="object"&&s!=="function"&&s!=="asyncfunction")this[s]?this[s](r):t.ignoreUnknown||this.unkown(r,s);else{let u=Object.keys(r);t.unorderedObjects&&(u=u.sort());let f=[];t.respectType!==!1&&!A(r)&&(f=Z),t.excludeKeys&&(u=u.filter(l=>!t.excludeKeys(l)),f=f.filter(l=>!t.excludeKeys(l))),e("object:"+(u.length+f.length)+":");const h=l=>{this.dispatch(l),e(":"),t.excludeValues||this.dispatch(r[l]),e(",")};for(const l of u)h(l);for(const l of f)h(l)}},array(r,o){if(o=o===void 0?t.unorderedArrays!==!1:o,e("array:"+r.length+":"),!o||r.length<=1){for(const c of r)this.dispatch(c);return}const s=new Map,a=r.map(c=>{const u=R(t);u.dispatch(c);for(const[f,h]of u.getContext())s.set(f,h);return u.toString()});return n=s,a.sort(),this.array(a,!1)},date(r){return e("date:"+r.toJSON())},symbol(r){return e("symbol:"+r.toString())},unkown(r,o){if(e(o),!!r&&(e(":"),r&&typeof r.entries=="function"))return this.array(Array.from(r.entries()),!0)},error(r){return e("error:"+r.toString())},boolean(r){return e("bool:"+r)},string(r){e("string:"+r.length+":"),e(r)},function(r){e("fn:"),A(r)?this.dispatch("[native]"):this.dispatch(r.toString()),t.respectFunctionNames!==!1&&this.dispatch("function-name:"+String(r.name)),t.respectFunctionProperties&&this.object(r)},number(r){return e("number:"+r)},xml(r){return e("xml:"+r.toString())},null(){return e("Null")},undefined(){return e("Undefined")},regexp(r){return e("regex:"+r.toString())},uint8array(r){return e("uint8array:"),this.dispatch(Array.prototype.slice.call(r))},uint8clampedarray(r){return e("uint8clampedarray:"),this.dispatch(Array.prototype.slice.call(r))},int8array(r){return e("int8array:"),this.dispatch(Array.prototype.slice.call(r))},uint16array(r){return e("uint16array:"),this.dispatch(Array.prototype.slice.call(r))},int16array(r){return e("int16array:"),this.dispatch(Array.prototype.slice.call(r))},uint32array(r){return e("uint32array:"),this.dispatch(Array.prototype.slice.call(r))},int32array(r){return e("int32array:"),this.dispatch(Array.prototype.slice.call(r))},float32array(r){return e("float32array:"),this.dispatch(Array.prototype.slice.call(r))},float64array(r){return e("float64array:"),this.dispatch(Array.prototype.slice.call(r))},arraybuffer(r){return e("arraybuffer:"),this.dispatch(new Uint8Array(r))},url(r){return e("url:"+r.toString())},map(r){e("map:");const o=[...r];return this.array(o,t.unorderedSets!==!1)},set(r){e("set:");const o=[...r];return this.array(o,t.unorderedSets!==!1)},file(r){return e("file:"),this.dispatch([r.name,r.size,r.type,r.lastModfied])},blob(){if(t.ignoreUnknown)return e("[blob]");throw new Error(`Hashing Blob objects is currently not supported +import{r as L,a0 as P,a1 as z,i as F,a2 as H,Z as K,s as q,q as x}from"./entry.PS9LLiT2.js";const S=/^[\u0009\u0020-\u007E\u0080-\u00FF]+$/;function V(t,i){if(typeof t!="string")throw new TypeError("argument str must be a string");const n={},r=(i||{}).decode||X;let o=0;for(;o{i+=r};return{toString(){return i},getContext(){return n},dispatch(r){return t.replacer&&(r=t.replacer(r)),this[r===null?"null":typeof r](r)},object(r){if(r&&typeof r.toJSON=="function")return this.object(r.toJSON());const o=Object.prototype.toString.call(r);let s="";const a=o.length;a<10?s="unknown:["+o+"]":s=o.slice(8,a-1),s=s.toLowerCase();let c=null;if((c=n.get(r))===void 0)n.set(r,n.size);else return this.dispatch("[CIRCULAR:"+c+"]");if(typeof Buffer<"u"&&Buffer.isBuffer&&Buffer.isBuffer(r))return e("buffer:"),e(r.toString("utf8"));if(s!=="object"&&s!=="function"&&s!=="asyncfunction")this[s]?this[s](r):t.ignoreUnknown||this.unkown(r,s);else{let u=Object.keys(r);t.unorderedObjects&&(u=u.sort());let f=[];t.respectType!==!1&&!A(r)&&(f=Z),t.excludeKeys&&(u=u.filter(l=>!t.excludeKeys(l)),f=f.filter(l=>!t.excludeKeys(l))),e("object:"+(u.length+f.length)+":");const h=l=>{this.dispatch(l),e(":"),t.excludeValues||this.dispatch(r[l]),e(",")};for(const l of u)h(l);for(const l of f)h(l)}},array(r,o){if(o=o===void 0?t.unorderedArrays!==!1:o,e("array:"+r.length+":"),!o||r.length<=1){for(const c of r)this.dispatch(c);return}const s=new Map,a=r.map(c=>{const u=R(t);u.dispatch(c);for(const[f,h]of u.getContext())s.set(f,h);return u.toString()});return n=s,a.sort(),this.array(a,!1)},date(r){return e("date:"+r.toJSON())},symbol(r){return e("symbol:"+r.toString())},unkown(r,o){if(e(o),!!r&&(e(":"),r&&typeof r.entries=="function"))return this.array(Array.from(r.entries()),!0)},error(r){return e("error:"+r.toString())},boolean(r){return e("bool:"+r)},string(r){e("string:"+r.length+":"),e(r)},function(r){e("fn:"),A(r)?this.dispatch("[native]"):this.dispatch(r.toString()),t.respectFunctionNames!==!1&&this.dispatch("function-name:"+String(r.name)),t.respectFunctionProperties&&this.object(r)},number(r){return e("number:"+r)},xml(r){return e("xml:"+r.toString())},null(){return e("Null")},undefined(){return e("Undefined")},regexp(r){return e("regex:"+r.toString())},uint8array(r){return e("uint8array:"),this.dispatch(Array.prototype.slice.call(r))},uint8clampedarray(r){return e("uint8clampedarray:"),this.dispatch(Array.prototype.slice.call(r))},int8array(r){return e("int8array:"),this.dispatch(Array.prototype.slice.call(r))},uint16array(r){return e("uint16array:"),this.dispatch(Array.prototype.slice.call(r))},int16array(r){return e("int16array:"),this.dispatch(Array.prototype.slice.call(r))},uint32array(r){return e("uint32array:"),this.dispatch(Array.prototype.slice.call(r))},int32array(r){return e("int32array:"),this.dispatch(Array.prototype.slice.call(r))},float32array(r){return e("float32array:"),this.dispatch(Array.prototype.slice.call(r))},float64array(r){return e("float64array:"),this.dispatch(Array.prototype.slice.call(r))},arraybuffer(r){return e("arraybuffer:"),this.dispatch(new Uint8Array(r))},url(r){return e("url:"+r.toString())},map(r){e("map:");const o=[...r];return this.array(o,t.unorderedSets!==!1)},set(r){e("set:");const o=[...r];return this.array(o,t.unorderedSets!==!1)},file(r){return e("file:"),this.dispatch([r.name,r.size,r.type,r.lastModfied])},blob(){if(t.ignoreUnknown)return e("[blob]");throw new Error(`Hashing Blob objects is currently not supported Use "options.replacer" or "options.ignoreUnknown" `)},domwindow(){return e("domwindow")},bigint(r){return e("bigint:"+r.toString())},process(){return e("process")},timer(){return e("timer")},pipe(){return e("pipe")},tcp(){return e("tcp")},udp(){return e("udp")},tty(){return e("tty")},statwatcher(){return e("statwatcher")},securecontext(){return e("securecontext")},connection(){return e("connection")},zlib(){return e("zlib")},context(){return e("context")},nodescript(){return e("nodescript")},httpparser(){return e("httpparser")},dataview(){return e("dataview")},signal(){return e("signal")},fsevent(){return e("fsevent")},tlswrap(){return e("tlswrap")}}}const N="[native code] }",$=N.length;function A(t){return typeof t!="function"?!1:Function.prototype.toString.call(t).slice(-$)===N}class d{constructor(i,n){i=this.words=i||[],this.sigBytes=n===void 0?i.length*4:n}toString(i){return(i||G).stringify(this)}concat(i){if(this.clamp(),this.sigBytes%4)for(let n=0;n>>2]>>>24-n%4*8&255;this.words[this.sigBytes+n>>>2]|=e<<24-(this.sigBytes+n)%4*8}else for(let n=0;n>>2]=i.words[n>>>2];return this.sigBytes+=i.sigBytes,this}clamp(){this.words[this.sigBytes>>>2]&=4294967295<<32-this.sigBytes%4*8,this.words.length=Math.ceil(this.sigBytes/4)}clone(){return new d([...this.words])}}const G={stringify(t){const i=[];for(let n=0;n>>2]>>>24-n%4*8&255;i.push((e>>>4).toString(16),(e&15).toString(16))}return i.join("")}},Q={stringify(t){const i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",n=[];for(let e=0;e>>2]>>>24-e%4*8&255,o=t.words[e+1>>>2]>>>24-(e+1)%4*8&255,s=t.words[e+2>>>2]>>>24-(e+2)%4*8&255,a=r<<16|o<<8|s;for(let c=0;c<4&&e*8+c*6>>6*(3-c)&63))}return n.join("")}},ee={parse(t){const i=t.length,n=[];for(let e=0;e>>2]|=(t.charCodeAt(e)&255)<<24-e%4*8;return new d(n,i)}},te={parse(t){return ee.parse(unescape(encodeURIComponent(t)))}};class re{constructor(){this._data=new d,this._nDataBytes=0,this._minBufferSize=0,this.blockSize=512/32}reset(){this._data=new d,this._nDataBytes=0}_append(i){typeof i=="string"&&(i=te.parse(i)),this._data.concat(i),this._nDataBytes+=i.sigBytes}_doProcessBlock(i,n){}_process(i){let n,e=this._data.sigBytes/(this.blockSize*4);i?e=Math.ceil(e):e=Math.max((e|0)-this._minBufferSize,0);const r=e*this.blockSize,o=Math.min(r*4,this._data.sigBytes);if(r){for(let s=0;s>>7)^(w<<14|w>>>18)^w>>>3,m=y[l-2],U=(m<<15|m>>>17)^(m<<13|m>>>19)^m>>>10;y[l]=M+y[l-7]+U+y[l-16]}const g=c&u^~c&f,k=r&o^r&s^o&s,b=(r<<30|r>>>2)^(r<<19|r>>>13)^(r<<10|r>>>22),D=(c<<26|c>>>6)^(c<<21|c>>>11)^(c<<7|c>>>25),_=h+D+g+ie[l]+y[l],I=b+k;h=f,f=u,u=c,c=a+_|0,a=s,s=o,o=r,r=_+I|0}e[0]=e[0]+r|0,e[1]=e[1]+o|0,e[2]=e[2]+s|0,e[3]=e[3]+a|0,e[4]=e[4]+c|0,e[5]=e[5]+u|0,e[6]=e[6]+f|0,e[7]=e[7]+h|0}finalize(i){super.finalize(i);const n=this._nDataBytes*8,e=this._data.sigBytes*8;return this._data.words[e>>>5]|=128<<24-e%32,this._data.words[(e+64>>>9<<4)+14]=Math.floor(n/4294967296),this._data.words[(e+64>>>9<<4)+15]=n,this._data.sigBytes=this._data.words.length*4,this._process(),this._hash}}function oe(t){return new se().finalize(t).toString(Q)}function pe(t,i={}){const n=typeof t=="string"?t:B(t,i);return oe(n).slice(0,10)}function ae(t,i,n={}){return t===i||B(t,n)===B(i,n)}function p(t){if(typeof t!="object")return t;var i,n,e=Object.prototype.toString.call(t);if(e==="[object Object]"){if(t.constructor!==Object&&typeof t.constructor=="function"){n=new t.constructor;for(i in t)t.hasOwnProperty(i)&&n[i]!==t[i]&&(n[i]=p(t[i]))}else{n={};for(i in t)i==="__proto__"?Object.defineProperty(n,i,{value:p(t[i]),configurable:!0,enumerable:!0,writable:!0}):n[i]=p(t[i])}return n}if(e==="[object Array]"){for(i=t.length,n=Array(i);i--;)n[i]=p(t[i]);return n}return e==="[object Set]"?(n=new Set,t.forEach(function(r){n.add(p(r))}),n):e==="[object Map]"?(n=new Map,t.forEach(function(r,o){n.set(p(o),p(r))}),n):e==="[object Date]"?new Date(+t):e==="[object RegExp]"?(n=new RegExp(t.source,t.flags),n.lastIndex=t.lastIndex,n):e==="[object DataView]"?new t.constructor(p(t.buffer)):e==="[object ArrayBuffer]"?t.slice(0):e.slice(-6)==="Array]"?new t.constructor(t):t}const ce={path:"/",watch:!0,decode:t=>K(decodeURIComponent(t)),encode:t=>encodeURIComponent(typeof t=="string"?t:JSON.stringify(t))};function v(t,i){var c;const n={...ce,...i},e=O(n)||{};let r;n.maxAge!==void 0?r=n.maxAge*1e3:n.expires&&(r=n.expires.getTime()-Date.now());const o=r!==void 0&&r<=0,s=p(o?void 0:e[t]??((c=n.default)==null?void 0:c.call(n))),a=r&&!o?fe(s,r):L(s);{const u=typeof BroadcastChannel>"u"?null:new BroadcastChannel(`nuxt:cookies:${t}`),f=()=>{n.readonly||ae(a.value,e[t])||(le(t,a.value,n),e[t]=p(a.value),u==null||u.postMessage({value:n.encode(a.value)}))},h=g=>{var b;const k=g.refresh?(b=O(n))==null?void 0:b[t]:n.decode(g.value);l=!0,e[t]=a.value=k,q(()=>{l=!1})};let l=!1;P()&&z(()=>{l=!0,f(),u==null||u.close()}),u&&(u.onmessage=({data:g})=>h(g)),n.watch?F(a,()=>{l||f()},{deep:n.watch!=="shallow"}):f()}return a}function O(t={}){return V(document.cookie,t)}function ue(t,i,n={}){return i==null?T(t,i,{...n,maxAge:-1}):T(t,i,n)}function le(t,i,n={}){document.cookie=ue(t,i,n)}const j=2147483647;function fe(t,i){let n,e=0;return P()&&z(()=>{clearTimeout(n)}),H((r,o)=>{function s(){clearTimeout(n);const a=i-e,c=a{if(e+=c,e({isEnabled:()=>{const e=x().query;return Object.prototype.hasOwnProperty.call(e,"preview")&&!e.preview?!1:!!(e.preview||v("previewToken").value||sessionStorage.getItem("previewToken"))},getPreviewToken:()=>v("previewToken").value||sessionStorage.getItem("previewToken")||void 0,setPreviewToken:e=>{v("previewToken").value=e,x().query.preview=e||"",e?sessionStorage.setItem("previewToken",e):sessionStorage.removeItem("previewToken"),window.location.reload()}});export{pe as h,de as u}; diff --git a/_nuxt/query.veKqiZiu.js b/_nuxt/query.9Ah2Ct9x.js similarity index 95% rename from _nuxt/query.veKqiZiu.js rename to _nuxt/query.9Ah2Ct9x.js index 2fc2b9b..b12a8c5 100644 --- a/_nuxt/query.veKqiZiu.js +++ b/_nuxt/query.9Ah2Ct9x.js @@ -1,7 +1,7 @@ -import{N as R,r as w,O as k,J as B,P as T,Q as P,i as L,L as j,R as I,u as q,H as Q,S as F,v as g,T as H,U as M,V as U,I as N}from"./entry.kyqmbcaI.js";import{u as O,h as C}from"./preview.WHtoAZxr.js";const z=r=>r==="defer"||r===!1;function te(...r){var v;const n=typeof r[r.length-1]=="string"?r.pop():void 0;typeof r[0]!="string"&&r.unshift(n);let[e,i,a={}]=r;if(typeof e!="string")throw new TypeError("[nuxt] [asyncData] key must be a string.");if(typeof i!="function")throw new TypeError("[nuxt] [asyncData] handler must be a function.");const s=j(),t=i,c=()=>null,f=()=>s.isHydrating?s.payload.data[e]:s.static.data[e];a.server=a.server??!0,a.default=a.default??c,a.getCachedData=a.getCachedData??f,a.lazy=a.lazy??!1,a.immediate=a.immediate??!0,a.deep=a.deep??R.deep,a.dedupe=a.dedupe??"cancel";const p=()=>![null,void 0].includes(a.getCachedData(e));if(!s._asyncData[e]||!a.immediate){(v=s.payload._errors)[e]??(v[e]=null);const l=a.deep?w:k;s._asyncData[e]={data:l(a.getCachedData(e)??a.default()),pending:w(!p()),error:B(s.payload._errors,e),status:w("idle")}}const o={...s._asyncData[e]};o.refresh=o.execute=(l={})=>{if(s._asyncDataPromises[e]){if(z(l.dedupe??a.dedupe))return s._asyncDataPromises[e];s._asyncDataPromises[e].cancelled=!0}if((l._initial||s.isHydrating&&l._initial!==!1)&&p())return Promise.resolve(a.getCachedData(e));o.pending.value=!0,o.status.value="pending";const y=new Promise((u,d)=>{try{u(t(s))}catch(A){d(A)}}).then(u=>{if(y.cancelled)return s._asyncDataPromises[e];let d=u;a.transform&&(d=a.transform(u)),a.pick&&(d=K(d,a.pick)),s.payload.data[e]=d,o.data.value=d,o.error.value=null,o.status.value="success"}).catch(u=>{if(y.cancelled)return s._asyncDataPromises[e];o.error.value=I(u),o.data.value=q(a.default()),o.status.value="error"}).finally(()=>{y.cancelled||(o.pending.value=!1,delete s._asyncDataPromises[e])});return s._asyncDataPromises[e]=y,s._asyncDataPromises[e]};const m=()=>o.refresh({_initial:!0}),S=a.server!==!1&&s.payload.serverRendered;{const l=Q();if(l&&!l._nuxtOnBeforeMountCbs){l._nuxtOnBeforeMountCbs=[];const u=l._nuxtOnBeforeMountCbs;l&&(T(()=>{u.forEach(d=>{d()}),u.splice(0,u.length)}),P(()=>u.splice(0,u.length)))}S&&s.isHydrating&&(o.error.value||p())?(o.pending.value=!1,o.status.value=o.error.value?"error":"success"):l&&(s.payload.serverRendered&&s.isHydrating||a.lazy)&&a.immediate?l._nuxtOnBeforeMountCbs.push(m):a.immediate&&m(),a.watch&&L(a.watch,()=>o.refresh());const y=s.hook("app:data:refresh",async u=>{(!u||u.includes(e))&&await o.refresh()});l&&P(y)}const D=Promise.resolve(s._asyncDataPromises[e]).then(()=>o);return Object.assign(D,o),D}function K(r,n){const e={};for(const i of n)e[i]=r[i];return e}const b=(r,n)=>n.split(".").reduce((e,i)=>e&&e[i],r),_=(r,n)=>Object.keys(r).filter(n).reduce((e,i)=>Object.assign(e,{[i]:r[i]}),{}),re=r=>n=>r&&r.length?_(n,e=>!r.includes(e)):n,ne=r=>n=>Array.isArray(n)?n.map(e=>r(e)):r(n),$=r=>{const n=[],e=[];for(const i of r)["$","_"].includes(i)?n.push(i):e.push(i);return{prefixes:n,properties:e}},ae=(r=[])=>n=>{if(r.length===0||!n)return n;const{prefixes:e,properties:i}=$(r);return _(n,a=>!i.includes(a)&&!e.includes(a[0]))},se=(r=[])=>n=>{if(r.length===0||!n)return n;const{prefixes:e,properties:i}=$(r);return _(n,a=>i.includes(a)||e.includes(a[0]))},ie=(r,n)=>{const e=new Intl.Collator(n.$locale,{numeric:n.$numeric,caseFirst:n.$caseFirst,sensitivity:n.$sensitivity}),i=Object.keys(n).filter(a=>!a.startsWith("$"));for(const a of i)r=r.sort((s,t)=>{const c=[b(s,a),b(t,a)].map(f=>{if(f!==null)return f instanceof Date?f.toISOString():f});return n[a]===-1&&c.reverse(),e.compare(c[0],c[1])});return r},oe=(r,n="Expected an array")=>{if(!Array.isArray(r))throw new TypeError(n)},h=r=>Array.isArray(r)?r:[void 0,null].includes(r)?[]:[r],G=["sort","where","only","without"];function J(r,n={}){const e={};for(const t of Object.keys(n.initialParams||{}))e[t]=G.includes(t)?h(n.initialParams[t]):n.initialParams[t];const i=(t,c=f=>f)=>(...f)=>(e[t]=c(...f),s),a=t=>{var c;return n.legacy?t!=null&&t.surround?t.surround:t&&(t!=null&&t.dirConfig&&(t.result={_path:(c=t.dirConfig)==null?void 0:c._path,...t.result,_dir:t.dirConfig}),t!=null&&t._path||Array.isArray(t)||!Object.prototype.hasOwnProperty.call(t,"result")?t:t==null?void 0:t.result):t},s={params:()=>({...e,...e.where?{where:[...h(e.where)]}:{},...e.sort?{sort:[...h(e.sort)]}:{}}),only:i("only",h),without:i("without",h),where:i("where",t=>[...h(e.where),...h(t)]),sort:i("sort",t=>[...h(e.sort),...h(t)]),limit:i("limit",t=>parseInt(String(t),10)),skip:i("skip",t=>parseInt(String(t),10)),find:()=>r(s).then(a),findOne:()=>r(i("first")(!0)).then(a),count:()=>r(i("count")(!0)).then(a),locale:t=>s.where({_locale:t}),withSurround:i("surround",(t,c)=>({query:t,...c})),withDirConfig:()=>i("dirConfig")(!0)};return n.legacy&&(s.findSurround=(t,c)=>s.withSurround(t,c).find().then(a)),s}function E(r){return JSON.stringify(r,V)}function V(r,n){return n instanceof RegExp?`--REGEX ${n.toString()}`:n}const W=r=>{let n=E(r);return n=typeof Buffer<"u"?Buffer.from(n).toString("base64"):btoa(n),n=n.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,""),(n.match(/.{1,100}/g)||[]).join("/")},x=r=>F(r,g().public.content.api.baseURL),ce=()=>{throw console.warn("useContent is only accessible when you are using `documentDriven` mode."),console.warn("Learn more by visiting: https://content.nuxt.com/document-driven"),new Error("useContent is only accessible when you are using `documentDriven` mode.")},X=()=>{const{experimental:r}=g().public.content;return r.clientDB?!0:O().isEnabled()},Y=()=>async r=>{const{content:n}=g().public,e=r.params(),i=n.experimental.stripQueryParameters?x(`/query/${`${C(e)}.${n.integrity}`}/${W(e)}.json`):x(`/query/${C(e)}.${n.integrity}.json`);if(X())return(await N(()=>import("./client-db.woz9fGTK.js"),__vite__mapDeps([0,1,2,3,4]),import.meta.url).then(t=>t.useContentDatabase())).fetch(r);const a=await $fetch(i,{method:"GET",responseType:"json",params:n.experimental.stripQueryParameters?void 0:{_params:E(e),previewToken:O().getPreviewToken()}});if(typeof a=="string"&&a.startsWith(""))throw new Error("Not found");return a};function ue(r,...n){const{content:e}=g().public,i=J(Y(),{initialParams:typeof r!="string"?r:{},legacy:!0});let a;typeof r=="string"&&(a=H(M(r,...n)));const s=i.params;return i.params=()=>{var c,f,p;const t=s();return a&&(t.where=t.where||[],t.first&&(t.where||[]).length===0?t.where.push({_path:U(a)}):t.where.push({_path:new RegExp(`^${a.replace(/[-[\]{}()*+.,^$\s/]/g,"\\$&")}`)})),(c=t.sort)!=null&&c.length||(t.sort=[{_file:1,$numeric:!0}]),e.locales.length&&((p=(f=t.where)==null?void 0:f.find(m=>m._locale))!=null&&p._locale||(t.where=t.where||[],t.where.push({_locale:e.defaultLocale}))),t},i}export{te as a,oe as b,h as c,ie as d,W as e,ne as f,b as g,ae as h,se as i,E as j,J as k,re as o,ue as q,X as s,ce as u,x as w}; +import{N as R,r as w,O as k,J as B,P as T,Q as P,i as L,L as j,R as I,u as q,H as Q,S as F,v as g,T as H,U as M,V as U,I as N}from"./entry.PS9LLiT2.js";import{u as O,h as C}from"./preview.99XykmGH.js";const z=r=>r==="defer"||r===!1;function te(...r){var v;const n=typeof r[r.length-1]=="string"?r.pop():void 0;typeof r[0]!="string"&&r.unshift(n);let[e,i,a={}]=r;if(typeof e!="string")throw new TypeError("[nuxt] [asyncData] key must be a string.");if(typeof i!="function")throw new TypeError("[nuxt] [asyncData] handler must be a function.");const s=j(),t=i,c=()=>null,f=()=>s.isHydrating?s.payload.data[e]:s.static.data[e];a.server=a.server??!0,a.default=a.default??c,a.getCachedData=a.getCachedData??f,a.lazy=a.lazy??!1,a.immediate=a.immediate??!0,a.deep=a.deep??R.deep,a.dedupe=a.dedupe??"cancel";const p=()=>![null,void 0].includes(a.getCachedData(e));if(!s._asyncData[e]||!a.immediate){(v=s.payload._errors)[e]??(v[e]=null);const l=a.deep?w:k;s._asyncData[e]={data:l(a.getCachedData(e)??a.default()),pending:w(!p()),error:B(s.payload._errors,e),status:w("idle")}}const o={...s._asyncData[e]};o.refresh=o.execute=(l={})=>{if(s._asyncDataPromises[e]){if(z(l.dedupe??a.dedupe))return s._asyncDataPromises[e];s._asyncDataPromises[e].cancelled=!0}if((l._initial||s.isHydrating&&l._initial!==!1)&&p())return Promise.resolve(a.getCachedData(e));o.pending.value=!0,o.status.value="pending";const y=new Promise((u,d)=>{try{u(t(s))}catch(A){d(A)}}).then(u=>{if(y.cancelled)return s._asyncDataPromises[e];let d=u;a.transform&&(d=a.transform(u)),a.pick&&(d=K(d,a.pick)),s.payload.data[e]=d,o.data.value=d,o.error.value=null,o.status.value="success"}).catch(u=>{if(y.cancelled)return s._asyncDataPromises[e];o.error.value=I(u),o.data.value=q(a.default()),o.status.value="error"}).finally(()=>{y.cancelled||(o.pending.value=!1,delete s._asyncDataPromises[e])});return s._asyncDataPromises[e]=y,s._asyncDataPromises[e]};const m=()=>o.refresh({_initial:!0}),S=a.server!==!1&&s.payload.serverRendered;{const l=Q();if(l&&!l._nuxtOnBeforeMountCbs){l._nuxtOnBeforeMountCbs=[];const u=l._nuxtOnBeforeMountCbs;l&&(T(()=>{u.forEach(d=>{d()}),u.splice(0,u.length)}),P(()=>u.splice(0,u.length)))}S&&s.isHydrating&&(o.error.value||p())?(o.pending.value=!1,o.status.value=o.error.value?"error":"success"):l&&(s.payload.serverRendered&&s.isHydrating||a.lazy)&&a.immediate?l._nuxtOnBeforeMountCbs.push(m):a.immediate&&m(),a.watch&&L(a.watch,()=>o.refresh());const y=s.hook("app:data:refresh",async u=>{(!u||u.includes(e))&&await o.refresh()});l&&P(y)}const D=Promise.resolve(s._asyncDataPromises[e]).then(()=>o);return Object.assign(D,o),D}function K(r,n){const e={};for(const i of n)e[i]=r[i];return e}const b=(r,n)=>n.split(".").reduce((e,i)=>e&&e[i],r),_=(r,n)=>Object.keys(r).filter(n).reduce((e,i)=>Object.assign(e,{[i]:r[i]}),{}),re=r=>n=>r&&r.length?_(n,e=>!r.includes(e)):n,ne=r=>n=>Array.isArray(n)?n.map(e=>r(e)):r(n),$=r=>{const n=[],e=[];for(const i of r)["$","_"].includes(i)?n.push(i):e.push(i);return{prefixes:n,properties:e}},ae=(r=[])=>n=>{if(r.length===0||!n)return n;const{prefixes:e,properties:i}=$(r);return _(n,a=>!i.includes(a)&&!e.includes(a[0]))},se=(r=[])=>n=>{if(r.length===0||!n)return n;const{prefixes:e,properties:i}=$(r);return _(n,a=>i.includes(a)||e.includes(a[0]))},ie=(r,n)=>{const e=new Intl.Collator(n.$locale,{numeric:n.$numeric,caseFirst:n.$caseFirst,sensitivity:n.$sensitivity}),i=Object.keys(n).filter(a=>!a.startsWith("$"));for(const a of i)r=r.sort((s,t)=>{const c=[b(s,a),b(t,a)].map(f=>{if(f!==null)return f instanceof Date?f.toISOString():f});return n[a]===-1&&c.reverse(),e.compare(c[0],c[1])});return r},oe=(r,n="Expected an array")=>{if(!Array.isArray(r))throw new TypeError(n)},h=r=>Array.isArray(r)?r:[void 0,null].includes(r)?[]:[r],G=["sort","where","only","without"];function J(r,n={}){const e={};for(const t of Object.keys(n.initialParams||{}))e[t]=G.includes(t)?h(n.initialParams[t]):n.initialParams[t];const i=(t,c=f=>f)=>(...f)=>(e[t]=c(...f),s),a=t=>{var c;return n.legacy?t!=null&&t.surround?t.surround:t&&(t!=null&&t.dirConfig&&(t.result={_path:(c=t.dirConfig)==null?void 0:c._path,...t.result,_dir:t.dirConfig}),t!=null&&t._path||Array.isArray(t)||!Object.prototype.hasOwnProperty.call(t,"result")?t:t==null?void 0:t.result):t},s={params:()=>({...e,...e.where?{where:[...h(e.where)]}:{},...e.sort?{sort:[...h(e.sort)]}:{}}),only:i("only",h),without:i("without",h),where:i("where",t=>[...h(e.where),...h(t)]),sort:i("sort",t=>[...h(e.sort),...h(t)]),limit:i("limit",t=>parseInt(String(t),10)),skip:i("skip",t=>parseInt(String(t),10)),find:()=>r(s).then(a),findOne:()=>r(i("first")(!0)).then(a),count:()=>r(i("count")(!0)).then(a),locale:t=>s.where({_locale:t}),withSurround:i("surround",(t,c)=>({query:t,...c})),withDirConfig:()=>i("dirConfig")(!0)};return n.legacy&&(s.findSurround=(t,c)=>s.withSurround(t,c).find().then(a)),s}function E(r){return JSON.stringify(r,V)}function V(r,n){return n instanceof RegExp?`--REGEX ${n.toString()}`:n}const W=r=>{let n=E(r);return n=typeof Buffer<"u"?Buffer.from(n).toString("base64"):btoa(n),n=n.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,""),(n.match(/.{1,100}/g)||[]).join("/")},x=r=>F(r,g().public.content.api.baseURL),ce=()=>{throw console.warn("useContent is only accessible when you are using `documentDriven` mode."),console.warn("Learn more by visiting: https://content.nuxt.com/document-driven"),new Error("useContent is only accessible when you are using `documentDriven` mode.")},X=()=>{const{experimental:r}=g().public.content;return r.clientDB?!0:O().isEnabled()},Y=()=>async r=>{const{content:n}=g().public,e=r.params(),i=n.experimental.stripQueryParameters?x(`/query/${`${C(e)}.${n.integrity}`}/${W(e)}.json`):x(`/query/${C(e)}.${n.integrity}.json`);if(X())return(await N(()=>import("./client-db.j5h9Mw_L.js"),__vite__mapDeps([0,1,2,3,4]),import.meta.url).then(t=>t.useContentDatabase())).fetch(r);const a=await $fetch(i,{method:"GET",responseType:"json",params:n.experimental.stripQueryParameters?void 0:{_params:E(e),previewToken:O().getPreviewToken()}});if(typeof a=="string"&&a.startsWith(""))throw new Error("Not found");return a};function ue(r,...n){const{content:e}=g().public,i=J(Y(),{initialParams:typeof r!="string"?r:{},legacy:!0});let a;typeof r=="string"&&(a=H(M(r,...n)));const s=i.params;return i.params=()=>{var c,f,p;const t=s();return a&&(t.where=t.where||[],t.first&&(t.where||[]).length===0?t.where.push({_path:U(a)}):t.where.push({_path:new RegExp(`^${a.replace(/[-[\]{}()*+.,^$\s/]/g,"\\$&")}`)})),(c=t.sort)!=null&&c.length||(t.sort=[{_file:1,$numeric:!0}]),e.locales.length&&((p=(f=t.where)==null?void 0:f.find(m=>m._locale))!=null&&p._locale||(t.where=t.where||[],t.where.push({_locale:e.defaultLocale}))),t},i}export{te as a,oe as b,h as c,ie as d,W as e,ne as f,b as g,ae as h,se as i,E as j,J as k,re as o,ue as q,X as s,ce as u,x as w}; function __vite__mapDeps(indexes) { if (!__vite__mapDeps.viteFileDeps) { - __vite__mapDeps.viteFileDeps = ["./client-db.woz9fGTK.js","./entry.kyqmbcaI.js","./entry.aFfi1m7m.css","./index.1dSrIji7.js","./preview.WHtoAZxr.js"] + __vite__mapDeps.viteFileDeps = ["./client-db.j5h9Mw_L.js","./entry.PS9LLiT2.js","./entry.aFfi1m7m.css","./index.1dSrIji7.js","./preview.99XykmGH.js"] } return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) } diff --git a/_nuxt/vue.f36acd1f.ZfSKW0Tx.js b/_nuxt/vue.f36acd1f.jcQdGPHq.js similarity index 83% rename from _nuxt/vue.f36acd1f.ZfSKW0Tx.js rename to _nuxt/vue.f36acd1f.jcQdGPHq.js index 5381477..a5b5811 100644 --- a/_nuxt/vue.f36acd1f.ZfSKW0Tx.js +++ b/_nuxt/vue.f36acd1f.jcQdGPHq.js @@ -1 +1 @@ -import{A as o,r as u,B as f,i as d,C as v,D as i,E as l,G as h,H as m}from"./entry.kyqmbcaI.js";function U(t,a={}){const e=a.head||o();if(e)return e.ssr?e.push(t,a):p(e,t,a)}function p(t,a,e={}){const s=u(!1),n=u({});f(()=>{n.value=s.value?{}:h(a)});const r=t.push(n.value,e);return d(n,c=>{r.patch(c)}),m()&&(v(()=>{r.dispose()}),i(()=>{s.value=!0}),l(()=>{s.value=!1})),r}export{U as u}; +import{A as o,r as u,B as f,i as d,C as v,D as i,E as l,G as h,H as m}from"./entry.PS9LLiT2.js";function U(t,a={}){const e=a.head||o();if(e)return e.ssr?e.push(t,a):p(e,t,a)}function p(t,a,e={}){const s=u(!1),n=u({});f(()=>{n.value=s.value?{}:h(a)});const r=t.push(n.value,e);return d(n,c=>{r.patch(c)}),m()&&(v(()=>{r.dispose()}),i(()=>{s.value=!0}),l(()=>{s.value=!1})),r}export{U as u}; diff --git a/_payload.json b/_payload.json index 6ddb927..7f3bac5 100644 --- a/_payload.json +++ b/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1717319128705] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1717319594548] \ No newline at end of file diff --git a/api/_content/cache.1717319116628.json b/api/_content/cache.1717319582386.json similarity index 99% rename from api/_content/cache.1717319116628.json rename to api/_content/cache.1717319582386.json index 3d70661..4a26207 100644 --- a/api/_content/cache.1717319116628.json +++ b/api/_content/cache.1717319582386.json @@ -1 +1 @@ -{"generatedAt":1717319128636,"generateTime":820,"contents":[{"_path":"/concurrency","_dir":"","_draft":false,"_partial":false,"_locale":"","title":"Concurrency","description":"","body":{"type":"root","children":[{"type":"element","tag":"h2","props":{"id":"concurrency"},"children":[{"type":"text","value":"Concurrency"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This article aims to explain basic concepts related to concurrency, which is used to solve performance related problems. It starts and ends with Python (CPython, mostly), as a tie from and back into reality - but isn't really about Python at all. Actually, it isn't about any language, framework or library in particular. It aims to take a step back from questions of application and start from first principles."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's start by stating some facts about python concurrency. They may seem contradictory or confusing - the rest of the article aims to provide more clarity as to how they make sense together. It should be noted that some of these facts pertain to a standard use of Python - it is possible to bypass some limitations, either by using a less popular Python implementation, or by using non-standard "},{"type":"element","tag":"a","props":{"href":"https://numba.pydata.org/","rel":["nofollow"]},"children":[{"type":"text","value":"tools"}]},{"type":"text","value":" and libraries."}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Python has threads."}]},{"type":"text","value":"\nIf anyone says otherwise, they have important "},{"type":"element","tag":"a","props":{"href":"https://docs.python.org/3/library/threading.html","rel":["nofollow"]},"children":[{"type":"text","value":"standard"}]},{"type":"text","value":" Python "},{"type":"element","tag":"a","props":{"href":"https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor","rel":["nofollow"]},"children":[{"type":"text","value":"modules"}]},{"type":"text","value":" to explain away."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Python threads are useful"}]},{"type":"text","value":". "},{"type":"element","tag":"a","props":{"href":"https://replit.com/@NetanelHaber/pythonthreads?v=1","rel":["nofollow"]},"children":[{"type":"text","value":"Here are numbers for you to look at"}]},{"type":"text","value":"."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"No parallelization in python"}]},{"type":"text","value":": CPython threads cannot solve "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"every"}]},{"type":"text","value":" problem threads are put to use for in languages like C and C++."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Multi-processing can provide parallelization in Python"}]},{"type":"text","value":", although in practice the performance overhead will sometimes cancel out or severely reduce the wanted benefit"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-1","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-1"},"children":[{"type":"text","value":"1"}]}]},{"type":"text","value":"."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So what is the rule? When is multi-threading useful? Why is Python different than some other languages?"}]},{"type":"element","tag":"h3","props":{"id":"types-of-work"},"children":[{"type":"text","value":"Types of work"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Two basic concepts in this space are "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/CPU-bound","rel":["nofollow"]},"children":[{"type":"text","value":"CPU-bound"}]}]},{"type":"text","value":" and "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/I/O_bound","rel":["nofollow"]},"children":[{"type":"text","value":"I/O-bound"}]}]},{"type":"text","value":" (Input/Output) work. It helps to first state a basic fact: Computers have a fundamental bottleneck - they cannot execute more than one command at any time. Modern \"computers\" actually contain multiple computation units that can each execute one command at any given time. To compare the two types of work, we will first look at a single CPU core."}]},{"type":"element","tag":"h4","props":{"id":"multithreading-cpu-bound-work-on-a-single-core-the-same-work-with-extra-steps"},"children":[{"type":"text","value":"Multithreading CPU-bound work on a single core - the same work with extra steps"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If we task this computer with calculating "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"(2 ^ 19) / (3 ^ 33)"}]},{"type":"text","value":", it will boil the task down to a list of discreet commands to execute"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-2","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-2"},"children":[{"type":"text","value":"2"}]}]},{"type":"text","value":". This is very similar to human calculation. Say we've neared the end of a meal at a restaurant. We have two tasks ahead of us: Calculating the tip and calculating when to leave in order to catch a bus. The former calculation may penalize us "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"X"}]},{"type":"text","value":" of our time, while the latter may take "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Y"}]},{"type":"text","value":" of our time. In other words, altogether "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"X+Y"}]},{"type":"text","value":" work must be done. The \"brain-power\" (=time) will be spent, regardless of the way the work is divided, sliced or diced. "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"This is CPU-bound work."}]}]},{"type":"element","tag":"h4","props":{"id":"a-watched-pot-never-boils"},"children":[{"type":"text","value":"A watched pot never boils"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Now the computer is tasked with scraping Google search results. It receives a term as an argument and must retrieve the first 10 pages of results. So it:"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Asks for the first page "},{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"10ms"}]},{"type":"text","value":"."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Waits for the result to return from Google servers "},{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"80ms"}]},{"type":"text","value":"."}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Receives the result and saves it in a file "},{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"10ms"}]},{"type":"text","value":"."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It then repeats these steps for all 10 pages.\nThe execution times are just an example, but resemble real-world times for similar programs. So let's focus on 2 - it seems to be our performance bottleneck, at 80% of all execution time. The key word here is "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"waiting"}]},{"type":"text","value":". We have such a powerful tool at our disposal, and it mostly waits - i.e., does nothing, for most of our program. That's pretty unsavory. Next time you plan something with friends, try waiting for each friend to confirm before asking the next friend. "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"This is I/O-bound work"}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So a "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"CPU-bound"}]},{"type":"text","value":" task is one where the primary performance bottleneck is actual "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"work"}]},{"type":"text","value":" that cannot be avoided. An "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"I/O-bound"}]},{"type":"text","value":" task is one where the primary performance bottleneck is actually just "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"waiting"}]},{"type":"text","value":" for an external piece of data."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It is common sense that alleviating performance pain for problems with different bottlenecks will look different for each type of task. This is actually the key to our primary question. assessing the type of work before us - CPU, I/O or a mixture of both - can help us know in advance if certain solutions are applicable."}]},{"type":"element","tag":"h3","props":{"id":"enhancing-performance"},"children":[{"type":"text","value":"Enhancing Performance"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So for the first calculation task, we have a discreet list of commands we need to execute. Any unit can only execute one line at a time. We've already mentioned modern computers have many such units. So, for a slow program, the solution seems clear - divide and conquer. We divide our computation into smaller coherent parts (so we can assemble the solutions later for the final product), and give each available unit in the computer one part at a time to execute. For example, if we have a computation that can take 8X time, that can be divided into 8 smaller computations that each can take X time - and we have 8 cores - we can now accomplish this task in X time. This means that in order to enhance performance for CPU-bound tasks we need "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"parallelization"}]},{"type":"text","value":" - computing simultaneously on multiple units."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The second task, where we were mostly waiting, can complete faster by being able to do other work while waiting. In the wild, you might see the term "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"asynchronous"}]},{"type":"text","value":" used to describe such programs that allow for doing work while waiting, depending on the language or framework. We will use this term as well"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-3","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-3"},"children":[{"type":"text","value":"3"}]}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"On a side note, let's notice a subtle difference between the enhancements we may gain from optimizing both types of work. While both parallelization and asynchronous solutions can "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"save on overall execution time"}]},{"type":"text","value":", they cannot both "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"reduce CPU usage and resources"}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Consider 10 taps that produce 10L of water an hour. We need 100 liters altogether, so we're smart - we use 10 bottles and run all 10 taps at once. This should get us done in a minute, rather than 10 minutes. The trouble is the guy that arrived with us is also smart, and wants his 100L's worth of water too. This is the trouble with CPU work - the computer is capped at how much work it can accomplish simultaneously. To this end, \"optimizing\" your program by parallelizing its work doesn't really improve anything in terms of the amount of hard work that needs to be completed"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-4","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-4"},"children":[{"type":"text","value":"4"}]}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In contrast, optimizing I/O bound programs can actually "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"reduce CPU usage"}]},{"type":"text","value":" - one problem with I/O bound programs is that they needlessly waste CPU resources. In the best case scenario, we can get rid of almost all of the idle CPU time - which can be used to do more work"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-5","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-5"},"children":[{"type":"text","value":"5"}]}]},{"type":"text","value":" "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-6","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-6"},"children":[{"type":"text","value":"6"}]}]},{"type":"text","value":"."}]},{"type":"element","tag":"h3","props":{"id":"concurrency-1"},"children":[{"type":"text","value":"Concurrency"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So, CPU bound tasks could use parallel computing to achieve better performance, while for I/O bound tasks we would simply try to do more work while waiting. Generally, the blanket term for any solution for both of these bounds is "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"concurrency"}]},{"type":"text","value":". This denotes programs that cannot be thought about sequentially - in order to achieve either solution, the language will now expose syntax and interfaces that, while affording us the performance benefits of concurrent code, prevent us from being able to read our programs \"line after line\". It will now be possible for different bits of our programs to execute out of order."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's pause to list the terms we've encountered:"}]},{"type":"element","tag":"table","props":{},"children":[{"type":"text","value":"\n "},{"type":"element","tag":"thead","props":{},"children":[{"type":"text","value":"\n "},{"type":"element","tag":"tr","props":{},"children":[{"type":"text","value":"\n "},{"type":"element","tag":"th","props":{"colSpan":"2"},"children":[{"type":"text","value":"Concurrency\n "}]}]},{"type":"text","value":"\n "},{"type":"element","tag":"tr","props":{},"children":[{"type":"text","value":"\n "},{"type":"element","tag":"th","props":{},"children":[{"type":"text","value":"I/O-bound"}]},{"type":"text","value":"\n "},{"type":"element","tag":"th","props":{},"children":[{"type":"text","value":"CPU-bound"}]},{"type":"text","value":"\n "}]},{"type":"text","value":"\n "}]},{"type":"text","value":"\n "},{"type":"element","tag":"tbody","props":{},"children":[{"type":"text","value":"\n "},{"type":"element","tag":"tr","props":{},"children":[{"type":"text","value":"\n "},{"type":"element","tag":"td","props":{},"children":[{"type":"text","value":"Asynchronous Programming"}]},{"type":"text","value":"\n "},{"type":"element","tag":"td","props":{},"children":[{"type":"text","value":"Parallel Programming"}]},{"type":"text","value":"\n "}]},{"type":"text","value":"\n "}]}]},{"type":"element","tag":"h4","props":{"id":"challenges-on-the-way-to-real-world-solutions"},"children":[{"type":"text","value":"Challenges on the way to real-world solutions"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As mentioned, different frameworks expose different interfaces to programmers for writing concurrent code. Fundamentally, there are two challenges for language designers:"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Implementation"}]},{"type":"text","value":" - Developing the actual implementation(s) and mechanism(s) to allow for such code to run. This is not a trivial problem, especially if existing languages want to introduce new solutions."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Interface"}]},{"type":"text","value":" - Exposing the syntax and high-level tools with which users may interact with the implementations. This is also not a trivial problem - as mentioned, thinking about concurrent code isn't straightforward. Accordingly, a good language will look for interfaces that allow for expressing concurrent code in a readable, easy-to-reason-about way."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's give an example for a challenge on the implementation side. Cpython suffers from the "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"element","tag":"a","props":{"href":"https://www.youtube.com/watch?v=KVKufdTphKs","rel":["nofollow"]},"children":[{"type":"text","value":"GIL"}]}]},{"type":"text","value":" - the global interpreter lock. This means that the python interpreter cannot run more than one line of python bytecode at any given time. This means that Python effectively bans parallelization ("},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"within the same process"}]},{"type":"text","value":" - more on this soon), and therefore cannot improve the execution time of CPU-bound programs using concurrency"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-7","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-7"},"children":[{"type":"text","value":"7"}]}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's look at another example for a challenge, this time on the interface side. Javascript, an async language by default, used to only allow running code asynchronously using callbacks functions. These functions are passed to async calls (like api requests). These callbacks will eventually run with the result of async operations and execute side effects, such as displaying the result of the request on the page. Once we register a callback, we can continue working while the resource fetches."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This pattern suffered from a problem dubbed "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"element","tag":"a","props":{"href":"http://callbackhell.com/","rel":["nofollow"]},"children":[{"type":"text","value":"\"Callback Hell\""}]}]},{"type":"text","value":", where dependent chains of asynchronous calls, which by necessity meant nested callbacks, caused increasing right-indentation of code, until the final callback code started on the 100th column, say."}]},{"type":"text","value":"\n "},{"type":"element","tag":"pre","props":{},"children":[{"type":"text","value":" This\n isn't\n a\n pleasant\n read."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Addressing this, JavaScript introduced the "},{"type":"element","tag":"a","props":{"href":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise","rel":["nofollow"]},"children":[{"type":"text","value":"Promise API"}]},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-8","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-8"},"children":[{"type":"text","value":"8"}]}]},{"type":"text","value":"."}]},{"type":"element","tag":"h3","props":{"id":"a-taste-of-real-world-concurrency"},"children":[{"type":"text","value":"A Taste of Real-world Concurrency"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's take a cursory look at 3 basic archetypes of concurrency solutions, using a shoe factory as analogy."}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"Multiprocessing"}]},{"type":"text","value":" - multiprocessing can reduce the execution time of "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"both"}]},{"type":"text","value":" types of work. It involves using multiple OS processes within the same program, and coordinating between them. It is slow and very resource consuming in comparison with other concurrency solutions. If we use Python as an example, every process we spawn to run our code will, for example, contain its own running Python interpreter including the initial overhead of starting the process and the interpreter."},{"type":"element","tag":"br","props":{},"children":[]},{"type":"text","value":"Multiprocessing is analogous to building a brand new shoe factory for every order of shoes we receive, rather than using existing factories to produce multiple shoes. Every factory has an enormous initial construction overhead, it takes up a lot of real estate, and sharing resources and information between the factories is very slow.\nBack to Python: The GIL, which limits Python execution to one line at a time, only enforces its lock within the same process since every process is its own complete Python entity. This means that Python can allow real cpu parallelization using multiprocessing (refer to "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-1","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-1-2"},"children":[{"type":"text","value":"1"}]}]},{"type":"text","value":")"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"Multithreading"}]},{"type":"text","value":" - multithreading is a tricky, widely available solution for lean concurrency with shared resources within the same process. Threads are lighter execution units than processes. Let's refer back to the factory analogy. Here, we use just the one factory (=process) to run our code. We achieve concurrency by employing many workers to perform many tasks. The workers share the factory facilities and machines, so we save big on resources. If they can work at the same time (=in parallel), we can produce more in a given time ("},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"CPU-bound"}]},{"type":"text","value":" work)."},{"type":"element","tag":"br","props":{},"children":[]},{"type":"text","value":"It is important to state that multithreading can also provide performance benefits for ("},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"I/O-bound"}]},{"type":"text","value":" work). In languages with a GIL like Python, we effectively only allow one employee to work at any given time, and we switch between them. Why is this still useful? Workers, when not idle, can schedule deliveries, start long-running processes on machines, etc. - so if our factory mostly consists of kick-starting autonomous tasks ("},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"I/O-bound"}]},{"type":"text","value":" work), multiple employees can still accomplish much more than a single employee. With the meager time each employee is given, he can start some independent task, such as scheduling a delivery. We immediately yell \"freeze!\" and transfer the working rights to another worker. He too, registers some task. When we return to the first worker, our delivery has already arrived, and our worker can program a processing machine before we freeze him again."},{"type":"element","tag":"br","props":{},"children":[]},{"type":"text","value":"Back to reality. While multithreading is the ideal solution for CPU-bound work, it is less than ideal for I/O bound work. Even in a language that allows multi-threaded parallelism, our program still has idle CPU usage while any given thread waits for some I/O operation to complete. In addition, context switching between threads is time consuming, and as running permission is a zero-sum game, every millisecond of time given to one thread is a millisecond taken from another. So every thread is still resource consuming (though much leaner than a full process)."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"Asynchronous Tasks"}]},{"type":"text","value":"- This solution is relevant to I/O bound work, and can solve the wasted resource issues highlighted in the previous paragraph when using multithreading for I/O bound work. This is the final improvement to our factory, and it includes paying one of our employees more so he's willing to \"multi-task\"."},{"type":"element","tag":"br","props":{},"children":[]},{"type":"text","value":"Now, we hire a supervisor and buy a whiteboard. Our supervisor's job is to provide our employee with tasks to do when a task is completed. The worker schedules some delivery. Instead of waiting for the delivery, he first writes on the whiteboard: \"Supervisor, please let me know when the delivery has arrived for further processing\". Then he can immediately begin scheduling another delivery, or operating on deliveries from yesterday. The supervisor keeps an eye on the loading dock, and eventually the first delivery arrives. He erases the task from the whiteboard and tells the worker, who begins processing the delivery that just arrived. And so on."},{"type":"element","tag":"br","props":{},"children":[]},{"type":"text","value":"So this solution requires a couple of components, but it can saves immensely on resources when the work is mostly I/O bound - it needs a single thread for our actual code (the worker), and some constant number of other threads and data structures to inform our thread of new tasks and keep an eye out for completed async operations (the supervisor) and keep tabs on registered tasks (the whiteboard). Our code registers some async task, and requests to be notified when it returns with the results. It notifies the framework what it wants to do with the result, but the syntax of how it is notified and the underlying objects are very framework and languages specific."}]}]},{"type":"element","tag":"h3","props":{"id":"back-to-buzzwords"},"children":[{"type":"text","value":"Back to buzzwords"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The only way to get "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"parallelization"}]},{"type":"text","value":" in Python - in order to reduce execution time for "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"CPU-bound"}]},{"type":"text","value":" programs, is "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"multi-processing"}]},{"type":"text","value":", because of the "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"GIL"}]},{"type":"text","value":". This, by definition, doesn't come with shared resources like "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"multi-threading"}]},{"type":"text","value":" - so there's a large performance and resource penalty. This is not to say that threads have no use in Python - they may be used for reducing execution time for "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"I/O bound"}]},{"type":"text","value":" programs. Another Python-native alternative that can accomplish basically the same thing is the newish "},{"type":"element","tag":"a","props":{"href":"https://docs.python.org/3/library/asyncio.html","rel":["nofollow"]},"children":[{"type":"text","value":"asyncio"}]},{"type":"text","value":" library, that enables asynchronous code with a single thread."}]},{"type":"element","tag":"h3","props":{"id":"ack"},"children":[{"type":"text","value":"Ack"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Writing and resources about concurrency that I like:"}]}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Great "},{"type":"element","tag":"a","props":{"href":"https://www.youtube.com/watch?v=lJ3NC-R3gSI","rel":["nofollow"]},"children":[{"type":"text","value":"talk"}]},{"type":"text","value":" by Steve Klabnik."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Great "},{"type":"element","tag":"a","props":{"href":"https://eloquentjavascript.net/11_async.html","rel":["nofollow"]},"children":[{"type":"text","value":"chapter"}]},{"type":"text","value":" about async in eloquentJS, an outstanding book."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Friends that helped"}]}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Yoav Tzfati helped clean up my Python code"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Naomi Kriger and Yoav read my drafts"}]}]},{"type":"element","tag":"section","props":{"className":["footnotes"],"dataFootnotes":""},"children":[{"type":"element","tag":"h2","props":{"className":["sr-only"],"id":"footnote-label"},"children":[{"type":"text","value":"Footnotes"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{"id":"user-content-fn-1"},"children":[{"type":"text","value":"A Python developer friend of mine offered up the following heuristic: If you find yourself reaching for multi-processing in order to incorporate parallel code execution, it's time to choose a different language for this particular task. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-1","ariaLabel":"Back to reference 1","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-1-2","ariaLabel":"Back to reference 1-2","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"},{"type":"element","tag":"sup","props":{},"children":[{"type":"text","value":"2"}]}]}]},{"type":"element","tag":"li","props":{"id":"user-content-fn-2"},"children":[{"type":"text","value":"For brevity, we also implicitly disregard a further step where parallelism can come in handy - some calculations may perhaps allow for non-sequential execution of certain steps. This doesn't diminish the point, though. Say we've found the most reduced version of the algorithm, split among as many units as possible. We are still left with \"hard\" work needing to be completed. So we've tried our best to reach a solution in as little time as possible - but we still need to bite the bullet of real work needing to be done. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-2","ariaLabel":"Back to reference 2","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]},{"type":"element","tag":"li","props":{"id":"user-content-fn-3"},"children":[{"type":"text","value":"Although you would be hard pressed to justify the semantics, based on needle-thin differences between the dictionary definitions of some of the above terms. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-3","ariaLabel":"Back to reference 3","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]},{"type":"element","tag":"li","props":{"id":"user-content-fn-4"},"children":[{"type":"text","value":"I think that for a programmer like me, who's written only consumers - programs that just consume computing power - it may be harder to understand this perspective. Once you write a provider, such as an operating system, you suddenly understand this. You own "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"all"}]},{"type":"text","value":" of the resources - so when you parallelize management processes you'll notice you're stepping on your own toes - all of your programs are standing in line for water. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-4","ariaLabel":"Back to reference 4","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]},{"type":"element","tag":"li","props":{"id":"user-content-fn-5"},"children":[{"type":"text","value":"We can also quantify CPU usage as energy expenditure to further illustrate the point. There is no \"free\" energy - to this end, parallelizing CPU-bound programs cannot save energy. Async code also cannot save energy - but it "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"can"}]},{"type":"text","value":" minimize wasting energy. A more concise (but, in reality, wrong) framing of this idea is that the ideal program is only bound by CPU usage, as a program where we've solved all I/O issues is left with only CPU usage. This program doesn't exist, except in theory. I/O includes loading the next CPU instructions and reading registers as well, for example. In addition, These are not the only two bounds a program may have, for example another extremely important bound is "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/Memory-bound_function","rel":["nofollow"]},"children":[{"type":"text","value":"memory"}]}]},{"type":"text","value":", and a program is a tradeoff between all bounds. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-5","ariaLabel":"Back to reference 5","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]},{"type":"element","tag":"li","props":{"id":"user-content-fn-6"},"children":[{"type":"text","value":"A clock-cycle saved is a clock-cycle earned. This key insight, that a best case scenario asynchronous framework may reduce CPU usage, is what allows event-driven servers to serve many concurrent requests when the requests are mostly I/O bound. A new thread need not be created to serve every request - this can save an enormous amount of resources, in contrast with a thread-per-request framework which is capped by the realistic amount of threads that the server can maintain, thus severely limiting the vertical scaling of the server's possible concurrent requests. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-6","ariaLabel":"Back to reference 6","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]},{"type":"element","tag":"li","props":{"id":"user-content-fn-7"},"children":[{"type":"text","value":"Assuming only one line of Python bytecode is running allowed the writers of python interpreters to write simpler implementations. The trouble is, years later multi-threaded parallelization became important to many programming fields where performance is crucial. Now, existing Python implementations such as CPython are in trouble because the one-line assumption is fundamentally baked in to the underlying C and lifting the GIL as-is would break the interpreter. The "},{"type":"element","tag":"a","props":{"href":"https://www.youtube.com/watch?v=B_cQ0ykux_4","rel":["nofollow"]},"children":[{"type":"text","value":"\"Gilectomy\""}]},{"type":"text","value":", an attempt to remove the GIL from CPython, is a demonstration to that effect. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-7","ariaLabel":"Back to reference 7","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]},{"type":"element","tag":"li","props":{"id":"user-content-fn-8"},"children":[{"type":"text","value":"This allows us to transform nested callbacks into a list, eliminating callback nesting. Not much later, the language introduced a syntactical wrapper for the promise API that uses the "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"await"}]},{"type":"text","value":" keyword. This is an adoption of "},{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/Async/await","rel":["nofollow"]},"children":[{"type":"text","value":"syntax"}]},{"type":"text","value":" common to many languages, which enables giving asynchronous code a synchronous look, therefore arguably improving readability. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-8","ariaLabel":"Back to reference 8","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]}]}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"concurrency","depth":2,"text":"Concurrency","children":[{"id":"types-of-work","depth":3,"text":"Types of work"},{"id":"enhancing-performance","depth":3,"text":"Enhancing Performance"},{"id":"concurrency-1","depth":3,"text":"Concurrency"},{"id":"a-taste-of-real-world-concurrency","depth":3,"text":"A Taste of Real-world Concurrency"},{"id":"back-to-buzzwords","depth":3,"text":"Back to buzzwords"},{"id":"ack","depth":3,"text":"Ack"}]},{"id":"footnote-label","depth":2,"text":"Footnotes"}]}},"_type":"markdown","_id":"content:Concurrency.md","_source":"content","_file":"Concurrency.md","_extension":"md"},{"_path":"/ok-sometimes-async-await","_dir":"","_draft":false,"_partial":false,"_locale":"","title":"Ok, Sometimes Async Await","description":"","body":{"type":"root","children":[{"type":"element","tag":"h2","props":{"id":"ok-sometimes-async-await"},"children":[{"type":"text","value":"Ok, Sometimes Async-Await"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Normally, I continue believing that the classic (well, ES6) "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"promise.then().catch().finally()"}]},{"type":"text","value":" is nicer than using the newer ES17 "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"async-await"}]},{"type":"text","value":" syntax, because of function composability"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-1","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-1"},"children":[{"type":"text","value":"1"}]}]},{"type":"text","value":".\nThere are 2 cases where I think "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"async-await"}]},{"type":"text","value":" is neater, and one where it may perceivably come in handy:"}]},{"type":"element","tag":"h3","props":{"id":"_1-early-returnthrowing-errors"},"children":[{"type":"text","value":"1. Early Return/Throwing Errors"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes synthwave-84","code":"async function returnEarly(): Promise {\n if (someCondition) return;\n await networkRequest();\n if (someOtherCondition) return;\n return await someOtherNetworkRequest();\n}\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" returnEarly"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"()"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" Promise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":"SomeType"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" |"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" undefined"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"> {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"someCondition"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" networkRequest"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"someOtherCondition"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" someOtherNetworkRequest"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This way, your function can return early concisely, "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"but still always return a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Promise"}]}]},{"type":"text","value":".\nThis is because, all values returned from an "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"async function"}]},{"type":"text","value":" are automatically wrapped in a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Promise"}]},{"type":"text","value":" if they aren't already. The equivalent code is pretty ugly:"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes synthwave-84","code":"function returnEarly(): Promise {\n if (someCondition) return Promise.resolve();\n return networkRequest().then(() => {\n if (someOtherCondition) return Promise.resolve();\n return someOtherNetworkRequest();\n });\n}\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" returnEarly"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"()"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" Promise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":"SomeType"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" |"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" undefined"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"> {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"someCondition"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" Promise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"resolve"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" networkRequest"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"()."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"then"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"(() "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"someOtherCondition"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" Promise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"resolve"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" someOtherNetworkRequest"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"_2-promise-drilling"},"children":[{"type":"text","value":"2. Promise Drilling"}]},{"type":"element","tag":"pre","props":{"className":"language-js shiki shiki-themes synthwave-84","code":"async function hotPotato() {\n const a = await networkRequestA();\n const b = await networkRequestB(a);\n return await networkRequestC(a, b);\n}\n","language":"js","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" hotPotato"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"() {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FFFFFFEE"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" networkRequestA"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" b"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FFFFFFEE"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" networkRequestB"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":");\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" networkRequestC"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"b"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":");\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Sometimes, a computation requires a value several promises upstream. Using "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"async-await"}]},{"type":"text","value":", you see the entire function's scope trivially, so you don't need to drill down with the value."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The equivalent code is ugly:"}]},{"type":"element","tag":"pre","props":{"className":"language-js shiki shiki-themes synthwave-84","code":"function hotPotato() {\n return A()\n .then((a) => B(a).then((b) => [a, b]))\n .then(([a, b]) => C(a, b));\n}\n","language":"js","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" hotPotato"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"() {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" A"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" ."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"then"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"(("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" B"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":")."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"then"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"(("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"b"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" ["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"b"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"]))\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" ."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"then"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"((["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"b"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"]) "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" C"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"b"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"));\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"_3-object-asyncfunction"},"children":[{"type":"text","value":"3? [object AsyncFunction]"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This does not generally strike me as useful, but can theoretically come in handy."}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes synthwave-84","code":"Object.prototype.toString.call(async () => producePromise()); // '[object AsyncFunction]'\nObject.prototype.toString.call(() => producePromise()); // '[object Function]'\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":"Object"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"prototype"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"toString"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"call"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" () "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" producePromise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"()); "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#848BBD;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"// '[object AsyncFunction]'\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":"Object"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"prototype"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"toString"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"call"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"(() "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" producePromise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"()); "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#848BBD;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"// '[object Function]'\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So the language gives us a way to know if a function was declared with the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"async"}]},{"type":"text","value":" modifier.\nIn some contrived scenario, we can imagine that it may be very useful to be able to check during runtime if the function will be asynchronous "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"before invoking it"}]},{"type":"text","value":"."}]},{"type":"element","tag":"hr","props":{},"children":[]},{"type":"element","tag":"section","props":{"className":["footnotes"],"dataFootnotes":""},"children":[{"type":"element","tag":"h2","props":{"className":["sr-only"],"id":"footnote-label"},"children":[{"type":"text","value":"Footnotes"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{"id":"user-content-fn-1"},"children":[{"type":"text","value":"Composability: "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"fetchThing().then(doThing).catch(logError).finally(toFalse)"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-1","ariaLabel":"Back to reference 1","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"ok-sometimes-async-await","depth":2,"text":"Ok, Sometimes Async-Await","children":[{"id":"_1-early-returnthrowing-errors","depth":3,"text":"1. Early Return/Throwing Errors"},{"id":"_2-promise-drilling","depth":3,"text":"2. Promise Drilling"},{"id":"_3-object-asyncfunction","depth":3,"text":"3? [object AsyncFunction]"}]},{"id":"footnote-label","depth":2,"text":"Footnotes"}]}},"_type":"markdown","_id":"content:Ok, Sometimes Async-Await.md","_source":"content","_file":"Ok, Sometimes Async-Await.md","_extension":"md"},{"_path":"/typescript-typesystems-and-javascript","_dir":"","_draft":false,"_partial":false,"_locale":"","title":"TypeScript, TypeSystems And JavaScript","description":"","body":{"type":"root","children":[{"type":"element","tag":"h2","props":{"id":"typescript-typesystems-and-javascript"},"children":[{"type":"text","value":"TypeScript, TypeSystems and JavaScript"}]},{"type":"element","tag":"h3","props":{"id":"buzzwords"},"children":[{"type":"text","value":"Buzzwords"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"TypeScript (or “TS”) is a language built upon JavaScript (or “JS”), the primary (perhaps a vast, vast understatement) language used to program web applications. The term “built upon” is important here — TS is “strict superset” of JavaScript. This means that any valid JS program is also a valid TS program."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"TypeScript (or TS) first appeared 9 years ago, in 2012. It is written and maintained by Microsoft. It is now one of the "},{"type":"element","tag":"a","props":{"href":"https://venturebeat.com/2020/12/02/github-python-and-typescript-gain-popularity-among-programming-languages/","rel":["nofollow"]},"children":[{"type":"text","value":"most popular"}]},{"type":"text","value":" programming tools in the world. If TS were a startup company, early investors would be breaking out the champagne. Without exaggerating, I think most webdevs would agree with me in thinking that it won’t be long before “vanilla” JS will no longer be shipped in any new commercial product. For anything more than a personal/hobby project, JS will be constrained in TS shackles."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If the last two paragraphs irritated you, you’re not alone — they irritate me as well, although true. Buzzwords cut through all articles promoting some library or another, and they make it impossible to make actual value judgements. Moreover, they distract the reader from actual trends and move the focus from concepts to products. If C# were to switch out Java in its inception, do we envision a vastly different developmental landscape in the 90s? I’d argue against that. Rather, Java and its viable alternatives heralded the well-known trend (and one of more popular religions) of Object Oriented Programming, or OOP."}]},{"type":"element","tag":"h3","props":{"id":"an-example"},"children":[{"type":"text","value":"An Example"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So, the following case for TypeScript is actually a general case for using a type system in JavaScript programming. TypeScript is just the current best-in-class (by a wide chasm), and an objectively excellent candidate for accomplishing this goal. Let’s examine a very simple function in JS:"}]},{"type":"element","tag":"pre","props":{"className":"language-javascript shiki shiki-themes synthwave-84","code":"function multiply(x, y) {\n return x * y;\n}\n","language":"javascript","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" multiply"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"x"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"y"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" x"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" *"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" y"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let’s call this function:"}]},{"type":"element","tag":"pre","props":{"className":"language-javascript shiki shiki-themes synthwave-84","code":"multiply(2, 3); // = 6\n","language":"javascript","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"multiply"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#2EE2FA"},"children":[{"type":"text","value":"2"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#2EE2FA"},"children":[{"type":"text","value":"3"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"); "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#848BBD;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"// = 6\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So thats very nice. We have a function that multiplies two numbers. But let’s call it with a string:"}]},{"type":"element","tag":"pre","props":{"className":"language-javascript shiki shiki-themes synthwave-84","code":"multiply(2, \"hello\"); // = NaN\n","language":"javascript","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"multiply"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#2EE2FA"},"children":[{"type":"text","value":"2"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF8B39"},"children":[{"type":"text","value":"\"hello\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"); "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#848BBD;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"// = NaN\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This is obviously a nonsensical operation (although "},{"type":"element","tag":"a","props":{"href":"https://www.pythoncentral.io/use-python-multiply-strings/","rel":["nofollow"]},"children":[{"type":"text","value":"in Python"}]},{"type":"text","value":" multiplying 2 by “hello” would return “hellohello”. This is adorable) — and we receive NaN, which is a special value in JS which means “not a number” (complying with the "},{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/NaN","rel":["nofollow"]},"children":[{"type":"text","value":"IEEE 754 floating point standard"}]},{"type":"text","value":"). So it was a syntactically legal operation, but I doubt anyone writing that function wants their function to be called with a string value. Accordingly, this function could be written in TS like this:"}]},{"type":"element","tag":"pre","props":{"className":"language-typescript shiki shiki-themes synthwave-84","code":"function multiply(x: number, y: number) {\n return x * y;\n}\n","language":"typescript","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" multiply"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"x"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" number"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"y"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" number"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" x"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" *"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" y"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"We’ve simply told TS that we don’t allow non number inputs to be given to the function. Now the second function call with the string value is illegal — TypeScript will yell at you and your editor will highlight it with red, mean squiggly lined until you change it, optionally forbidding you to ship your code until you do. This may seem annoying at first — you must sprinkle type hints all around the place for TS to be happy, and it will yell at you if you dont obey your own rules. Migrating most of my company’s codebase was a lesson in patience in that regard. But the effort pays off in compound down the road, and let’s examine why."}]},{"type":"element","tag":"h3","props":{"id":"so-what"},"children":[{"type":"text","value":"So What"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"a","props":{"href":"https://www.python.org/dev/peps/pep-0020/","rel":["nofollow"]},"children":[{"type":"text","value":"Python zen"}]},{"type":"text","value":" teaches us “Explicit is better than implicit” — users familiar with type systems (who are gawking at my “discovery” of a feature existing in languages for over 45 years) might think I’m invoking this rule for readability reasons — as in, any person reading my multiply function with type hints will know immediately that the inputs are 2 numbers. This is true (although, TS has very powerful type inference, such that in many cases you may leave off type hints). Another valid point would be the functionality aspect — as I’ve mentioned, calling multiply with “hello” is now impossible, which is a great thing."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"For me, though, the most compelling case for type systems is more conceptual. TS forces you to explicitly fill your programs with assertions that mirror your assumptions about the program. Let’s rewrite our multiplication function:"}]},{"type":"element","tag":"pre","props":{"className":"language-typescript shiki shiki-themes synthwave-84","code":"function fruitPrice(basePrice: number, quantity: number) {\n return basePrice * quantity;\n}\n","language":"typescript","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" fruitPrice"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"basePrice"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" number"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"quantity"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" number"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" basePrice"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" *"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" quantity"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This function works great in dev with mock data, we receive the price of fruit from the server and the quantity from the client. Before pushing to production, the backend dev tells us that due to new architecture decisions, the price of certain fruit may be undetermined — now we may receive null, or an empty string when asking for the price of a fruit. Now when I call the price function with this new value, which may be undefined or a number, TypeScript yells because it know I am passing in a value which may not be a legal number."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Again, this is great — my function would fail without a rewrite. But the real lesson I can take from the squiggly lines is about my assumptions. TS punishes you for a lenient or thoughtlessly written piece of code — it forces you to reexamine what you think the program actually does. So fruitPrice will undoubtedly have to change, but now you know where you casually gave yourself a break by assuming a stricter subset of input than in reality. Now you know your program must take an undetermined price into account. TS will selflessly tell you where this assumption is relevant, but the real takeaway is forcing you to more strictly define your program."}]},{"type":"element","tag":"h3","props":{"id":"but-typescript-though"},"children":[{"type":"text","value":"But TypeScript, Though"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Something must be said about the tool in order to encourage its’ use, aside from touting the general benefits of a type system. So why TS, after all?"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"From a maintenance perspective, TS is, as mentioned, maintained by Microsoft. There are constant releases fixing bugs and meeting performance goals. New features are great, but really a dev needs to know that the project won’t "},{"type":"element","tag":"a","props":{"href":"https://www.theregister.com/2020/03/26/corejs_maintainer_jailed_code_release/","rel":["nofollow"]},"children":[{"type":"text","value":"collapse"}]},{"type":"text","value":" because of a dangerous dependency on a small team’s free time, and that the project won’t be "},{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/CoffeeScript","rel":["nofollow"]},"children":[{"type":"text","value":"forgotten"}]},{"type":"text","value":" after a swift period of adoption. There are no guarantees, obviously, and no project lasts forever. But, for now, it seems like the buzzword period is mostly over — and the aftermath is major "},{"type":"element","tag":"a","props":{"href":"https://angular.io/guide/typescript-configuration","rel":["nofollow"]},"children":[{"type":"text","value":"libraries"}]},{"type":"text","value":" and "},{"type":"element","tag":"a","props":{"href":"https://deno.land/","rel":["nofollow"]},"children":[{"type":"text","value":"technologies"}]},{"type":"text","value":" have adopted TS, or "},{"type":"element","tag":"a","props":{"href":"https://reactjs.org/docs/static-type-checking.html#typescript","rel":["nofollow"]},"children":[{"type":"text","value":"at least actively maintain type declaration files and tooling"}]},{"type":"text","value":" for consumers. Bet on TypeScript."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I think one of the reasons for TS’s steady success is its’ core product — type systems for JS. It has cultivated many features that were eventually swallowed into vanilla JS — "},{"type":"element","tag":"a","props":{"href":"https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining","rel":["nofollow"]},"children":[{"type":"text","value":"optional chaining"}]},{"type":"text","value":", what seems like "},{"type":"element","tag":"a","props":{"href":"https://www.typescriptlang.org/docs/handbook/classes.html","rel":["nofollow"]},"children":[{"type":"text","value":"direct inspiration for JS es2015 classes"}]},{"type":"text","value":", "},{"type":"element","tag":"a","props":{"href":"https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#nullish-coalescing","rel":["nofollow"]},"children":[{"type":"text","value":"nullish coalescing"}]},{"type":"text","value":" etc. But really, the main feature which browsers cannot adopt is the type system — JS is inherently dynamic, and a type system is a radical change browsers cannot simply add in. So by not competing with juggernaut browsers over its’ main feature, it can prevail safely without fearing a sudden hostile takeover."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"From a non maintenance perspective, TS has built its’ type system around widely used JS patterns. One example is that the TS type system is "},{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/Structural_type_system","rel":["nofollow"]},"children":[{"type":"text","value":"structural"}]},{"type":"text","value":" rather than nominal — basically, that one value is equivalent to another if it shares the structure of the other value. For example, a function that recieves { a: number; } as an argument, will also accept { a: number; b: number; } — the second type can be treated as the first type for all intents and purposes that the first type is used for in the function."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In many other type systems, types can act in for other types only if an explicit (=nominal) relationship was tied between them, such as inheritance. A structural type system fits the JS pattern of constant usage of anonynous objects and values (including functions), without explicitly calling constructors and so forth. Forcing nonimal typing on existing JS code would change the style and patterns devs are used to. This is not the only advantage to a structural type system, but it illustrates the thinking behind the language design. For more on the unique fit between TS and JS (I didn’t even touch on the functional aspect), I strongly recommend watching "},{"type":"element","tag":"a","props":{"href":"https://www.youtube.com/watch?v=jmPZztKIFf4","rel":["nofollow"]},"children":[{"type":"text","value":"this talk"}]},{"type":"text","value":" by "},{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/Anders_Hejlsberg","rel":["nofollow"]},"children":[{"type":"text","value":"Anders Hejlsberg"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h3","props":{"id":"giving-the-web-context"},"children":[{"type":"text","value":"Giving the Web Context"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In a final note, moving this text from notepad to an actual text editor with a spellchecker has shamefully revealed many squiggly lines, red, blue and green. In an imperfect analogy, JS editors have long had red lines for syntax errors (a.k.a. spelling mistakes). TS is more than a library, as it introduces a feature entirely impossible in current JS — green and blue squiggly lines, for contextual and grammatical errors. Suddenly my programs are more than blocks of black text, they speak to me and challenge my assumptions. So while we roll in the "},{"type":"element","tag":"a","props":{"href":"https://insights.stackoverflow.com/survey/2020#technology-what-languages-are-associated-with-the-highest-salaries-worldwide","rel":["nofollow"]},"children":[{"type":"text","value":"slim surplus of cash"}]},{"type":"text","value":" we supposedly make by writing TS over plain JS, let’s all collectively move our programs from notepad to a text editor."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://medium.com/@netanel.t.haber/typescript-typesystems-and-javascript-83153f249ce3?source=post_page-----83153f249ce3--------------------------------","rel":["nofollow"]},"children":[{"type":"text","value":"Originally published on February 27, 2021, on Medium"}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"typescript-typesystems-and-javascript","depth":2,"text":"TypeScript, TypeSystems and JavaScript","children":[{"id":"buzzwords","depth":3,"text":"Buzzwords"},{"id":"an-example","depth":3,"text":"An Example"},{"id":"so-what","depth":3,"text":"So What"},{"id":"but-typescript-though","depth":3,"text":"But TypeScript, Though"},{"id":"giving-the-web-context","depth":3,"text":"Giving the Web Context"}]}]}},"_type":"markdown","_id":"content:TypeScript, TypeSystems and JavaScript.md","_source":"content","_file":"TypeScript, TypeSystems and JavaScript.md","_extension":"md"}],"navigation":[{"title":"Concurrency","_path":"/concurrency"},{"title":"Ok, Sometimes Async Await","_path":"/ok-sometimes-async-await"},{"title":"TypeScript, TypeSystems And JavaScript","_path":"/typescript-typesystems-and-javascript"}]} \ No newline at end of file +{"generatedAt":1717319594372,"generateTime":696,"contents":[{"_path":"/concurrency","_dir":"","_draft":false,"_partial":false,"_locale":"","title":"Concurrency","description":"","body":{"type":"root","children":[{"type":"element","tag":"h2","props":{"id":"concurrency"},"children":[{"type":"text","value":"Concurrency"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This article aims to explain basic concepts related to concurrency, which is used to solve performance related problems. It starts and ends with Python (CPython, mostly), as a tie from and back into reality - but isn't really about Python at all. Actually, it isn't about any language, framework or library in particular. It aims to take a step back from questions of application and start from first principles."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's start by stating some facts about python concurrency. They may seem contradictory or confusing - the rest of the article aims to provide more clarity as to how they make sense together. It should be noted that some of these facts pertain to a standard use of Python - it is possible to bypass some limitations, either by using a less popular Python implementation, or by using non-standard "},{"type":"element","tag":"a","props":{"href":"https://numba.pydata.org/","rel":["nofollow"]},"children":[{"type":"text","value":"tools"}]},{"type":"text","value":" and libraries."}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Python has threads."}]},{"type":"text","value":"\nIf anyone says otherwise, they have important "},{"type":"element","tag":"a","props":{"href":"https://docs.python.org/3/library/threading.html","rel":["nofollow"]},"children":[{"type":"text","value":"standard"}]},{"type":"text","value":" Python "},{"type":"element","tag":"a","props":{"href":"https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor","rel":["nofollow"]},"children":[{"type":"text","value":"modules"}]},{"type":"text","value":" to explain away."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Python threads are useful"}]},{"type":"text","value":". "},{"type":"element","tag":"a","props":{"href":"https://replit.com/@NetanelHaber/pythonthreads?v=1","rel":["nofollow"]},"children":[{"type":"text","value":"Here are numbers for you to look at"}]},{"type":"text","value":"."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"No parallelization in python"}]},{"type":"text","value":": CPython threads cannot solve "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"every"}]},{"type":"text","value":" problem threads are put to use for in languages like C and C++."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Multi-processing can provide parallelization in Python"}]},{"type":"text","value":", although in practice the performance overhead will sometimes cancel out or severely reduce the wanted benefit"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-1","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-1"},"children":[{"type":"text","value":"1"}]}]},{"type":"text","value":"."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So what is the rule? When is multi-threading useful? Why is Python different than some other languages?"}]},{"type":"element","tag":"h3","props":{"id":"types-of-work"},"children":[{"type":"text","value":"Types of work"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Two basic concepts in this space are "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/CPU-bound","rel":["nofollow"]},"children":[{"type":"text","value":"CPU-bound"}]}]},{"type":"text","value":" and "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/I/O_bound","rel":["nofollow"]},"children":[{"type":"text","value":"I/O-bound"}]}]},{"type":"text","value":" (Input/Output) work. It helps to first state a basic fact: Computers have a fundamental bottleneck - they cannot execute more than one command at any time. Modern \"computers\" actually contain multiple computation units that can each execute one command at any given time. To compare the two types of work, we will first look at a single CPU core."}]},{"type":"element","tag":"h4","props":{"id":"multithreading-cpu-bound-work-on-a-single-core-the-same-work-with-extra-steps"},"children":[{"type":"text","value":"Multithreading CPU-bound work on a single core - the same work with extra steps"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If we task this computer with calculating "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"(2 ^ 19) / (3 ^ 33)"}]},{"type":"text","value":", it will boil the task down to a list of discreet commands to execute"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-2","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-2"},"children":[{"type":"text","value":"2"}]}]},{"type":"text","value":". This is very similar to human calculation. Say we've neared the end of a meal at a restaurant. We have two tasks ahead of us: Calculating the tip and calculating when to leave in order to catch a bus. The former calculation may penalize us "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"X"}]},{"type":"text","value":" of our time, while the latter may take "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Y"}]},{"type":"text","value":" of our time. In other words, altogether "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"X+Y"}]},{"type":"text","value":" work must be done. The \"brain-power\" (=time) will be spent, regardless of the way the work is divided, sliced or diced. "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"This is CPU-bound work."}]}]},{"type":"element","tag":"h4","props":{"id":"a-watched-pot-never-boils"},"children":[{"type":"text","value":"A watched pot never boils"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Now the computer is tasked with scraping Google search results. It receives a term as an argument and must retrieve the first 10 pages of results. So it:"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Asks for the first page "},{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"10ms"}]},{"type":"text","value":"."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Waits for the result to return from Google servers "},{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"80ms"}]},{"type":"text","value":"."}]}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Receives the result and saves it in a file "},{"type":"element","tag":"span","props":{},"children":[{"type":"text","value":"10ms"}]},{"type":"text","value":"."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It then repeats these steps for all 10 pages.\nThe execution times are just an example, but resemble real-world times for similar programs. So let's focus on 2 - it seems to be our performance bottleneck, at 80% of all execution time. The key word here is "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"waiting"}]},{"type":"text","value":". We have such a powerful tool at our disposal, and it mostly waits - i.e., does nothing, for most of our program. That's pretty unsavory. Next time you plan something with friends, try waiting for each friend to confirm before asking the next friend. "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"This is I/O-bound work"}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So a "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"CPU-bound"}]},{"type":"text","value":" task is one where the primary performance bottleneck is actual "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"work"}]},{"type":"text","value":" that cannot be avoided. An "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"I/O-bound"}]},{"type":"text","value":" task is one where the primary performance bottleneck is actually just "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"waiting"}]},{"type":"text","value":" for an external piece of data."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"It is common sense that alleviating performance pain for problems with different bottlenecks will look different for each type of task. This is actually the key to our primary question. assessing the type of work before us - CPU, I/O or a mixture of both - can help us know in advance if certain solutions are applicable."}]},{"type":"element","tag":"h3","props":{"id":"enhancing-performance"},"children":[{"type":"text","value":"Enhancing Performance"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So for the first calculation task, we have a discreet list of commands we need to execute. Any unit can only execute one line at a time. We've already mentioned modern computers have many such units. So, for a slow program, the solution seems clear - divide and conquer. We divide our computation into smaller coherent parts (so we can assemble the solutions later for the final product), and give each available unit in the computer one part at a time to execute. For example, if we have a computation that can take 8X time, that can be divided into 8 smaller computations that each can take X time - and we have 8 cores - we can now accomplish this task in X time. This means that in order to enhance performance for CPU-bound tasks we need "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"parallelization"}]},{"type":"text","value":" - computing simultaneously on multiple units."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The second task, where we were mostly waiting, can complete faster by being able to do other work while waiting. In the wild, you might see the term "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"asynchronous"}]},{"type":"text","value":" used to describe such programs that allow for doing work while waiting, depending on the language or framework. We will use this term as well"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-3","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-3"},"children":[{"type":"text","value":"3"}]}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"On a side note, let's notice a subtle difference between the enhancements we may gain from optimizing both types of work. While both parallelization and asynchronous solutions can "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"save on overall execution time"}]},{"type":"text","value":", they cannot both "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"reduce CPU usage and resources"}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Consider 10 taps that produce 10L of water an hour. We need 100 liters altogether, so we're smart - we use 10 bottles and run all 10 taps at once. This should get us done in a minute, rather than 10 minutes. The trouble is the guy that arrived with us is also smart, and wants his 100L's worth of water too. This is the trouble with CPU work - the computer is capped at how much work it can accomplish simultaneously. To this end, \"optimizing\" your program by parallelizing its work doesn't really improve anything in terms of the amount of hard work that needs to be completed"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-4","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-4"},"children":[{"type":"text","value":"4"}]}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In contrast, optimizing I/O bound programs can actually "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"reduce CPU usage"}]},{"type":"text","value":" - one problem with I/O bound programs is that they needlessly waste CPU resources. In the best case scenario, we can get rid of almost all of the idle CPU time - which can be used to do more work"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-5","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-5"},"children":[{"type":"text","value":"5"}]}]},{"type":"text","value":" "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-6","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-6"},"children":[{"type":"text","value":"6"}]}]},{"type":"text","value":"."}]},{"type":"element","tag":"h3","props":{"id":"concurrency-1"},"children":[{"type":"text","value":"Concurrency"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So, CPU bound tasks could use parallel computing to achieve better performance, while for I/O bound tasks we would simply try to do more work while waiting. Generally, the blanket term for any solution for both of these bounds is "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"concurrency"}]},{"type":"text","value":". This denotes programs that cannot be thought about sequentially - in order to achieve either solution, the language will now expose syntax and interfaces that, while affording us the performance benefits of concurrent code, prevent us from being able to read our programs \"line after line\". It will now be possible for different bits of our programs to execute out of order."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's pause to list the terms we've encountered:"}]},{"type":"element","tag":"table","props":{},"children":[{"type":"text","value":"\n "},{"type":"element","tag":"thead","props":{},"children":[{"type":"text","value":"\n "},{"type":"element","tag":"tr","props":{},"children":[{"type":"text","value":"\n "},{"type":"element","tag":"th","props":{"colSpan":"2"},"children":[{"type":"text","value":"Concurrency\n "}]}]},{"type":"text","value":"\n "},{"type":"element","tag":"tr","props":{},"children":[{"type":"text","value":"\n "},{"type":"element","tag":"th","props":{},"children":[{"type":"text","value":"I/O-bound"}]},{"type":"text","value":"\n "},{"type":"element","tag":"th","props":{},"children":[{"type":"text","value":"CPU-bound"}]},{"type":"text","value":"\n "}]},{"type":"text","value":"\n "}]},{"type":"text","value":"\n "},{"type":"element","tag":"tbody","props":{},"children":[{"type":"text","value":"\n "},{"type":"element","tag":"tr","props":{},"children":[{"type":"text","value":"\n "},{"type":"element","tag":"td","props":{},"children":[{"type":"text","value":"Asynchronous Programming"}]},{"type":"text","value":"\n "},{"type":"element","tag":"td","props":{},"children":[{"type":"text","value":"Parallel Programming"}]},{"type":"text","value":"\n "}]},{"type":"text","value":"\n "}]}]},{"type":"element","tag":"h4","props":{"id":"challenges-on-the-way-to-real-world-solutions"},"children":[{"type":"text","value":"Challenges on the way to real-world solutions"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"As mentioned, different frameworks expose different interfaces to programmers for writing concurrent code. Fundamentally, there are two challenges for language designers:"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Implementation"}]},{"type":"text","value":" - Developing the actual implementation(s) and mechanism(s) to allow for such code to run. This is not a trivial problem, especially if existing languages want to introduce new solutions."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Interface"}]},{"type":"text","value":" - Exposing the syntax and high-level tools with which users may interact with the implementations. This is also not a trivial problem - as mentioned, thinking about concurrent code isn't straightforward. Accordingly, a good language will look for interfaces that allow for expressing concurrent code in a readable, easy-to-reason-about way."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's give an example for a challenge on the implementation side. Cpython suffers from the "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"element","tag":"a","props":{"href":"https://www.youtube.com/watch?v=KVKufdTphKs","rel":["nofollow"]},"children":[{"type":"text","value":"GIL"}]}]},{"type":"text","value":" - the global interpreter lock. This means that the python interpreter cannot run more than one line of python bytecode at any given time. This means that Python effectively bans parallelization ("},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"within the same process"}]},{"type":"text","value":" - more on this soon), and therefore cannot improve the execution time of CPU-bound programs using concurrency"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-7","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-7"},"children":[{"type":"text","value":"7"}]}]},{"type":"text","value":"."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's look at another example for a challenge, this time on the interface side. Javascript, an async language by default, used to only allow running code asynchronously using callbacks functions. These functions are passed to async calls (like api requests). These callbacks will eventually run with the result of async operations and execute side effects, such as displaying the result of the request on the page. Once we register a callback, we can continue working while the resource fetches."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This pattern suffered from a problem dubbed "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"element","tag":"a","props":{"href":"http://callbackhell.com/","rel":["nofollow"]},"children":[{"type":"text","value":"\"Callback Hell\""}]}]},{"type":"text","value":", where dependent chains of asynchronous calls, which by necessity meant nested callbacks, caused increasing right-indentation of code, until the final callback code started on the 100th column, say."}]},{"type":"text","value":"\n "},{"type":"element","tag":"pre","props":{},"children":[{"type":"text","value":" This\n isn't\n a\n pleasant\n read."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Addressing this, JavaScript introduced the "},{"type":"element","tag":"a","props":{"href":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise","rel":["nofollow"]},"children":[{"type":"text","value":"Promise API"}]},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-8","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-8"},"children":[{"type":"text","value":"8"}]}]},{"type":"text","value":"."}]},{"type":"element","tag":"h3","props":{"id":"a-taste-of-real-world-concurrency"},"children":[{"type":"text","value":"A Taste of Real-world Concurrency"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let's take a cursory look at 3 basic archetypes of concurrency solutions, using a shoe factory as analogy."}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"Multiprocessing"}]},{"type":"text","value":" - multiprocessing can reduce the execution time of "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"both"}]},{"type":"text","value":" types of work. It involves using multiple OS processes within the same program, and coordinating between them. It is slow and very resource consuming in comparison with other concurrency solutions. If we use Python as an example, every process we spawn to run our code will, for example, contain its own running Python interpreter including the initial overhead of starting the process and the interpreter."},{"type":"element","tag":"br","props":{},"children":[]},{"type":"text","value":"Multiprocessing is analogous to building a brand new shoe factory for every order of shoes we receive, rather than using existing factories to produce multiple shoes. Every factory has an enormous initial construction overhead, it takes up a lot of real estate, and sharing resources and information between the factories is very slow.\nBack to Python: The GIL, which limits Python execution to one line at a time, only enforces its lock within the same process since every process is its own complete Python entity. This means that Python can allow real cpu parallelization using multiprocessing (refer to "},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-1","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-1-2"},"children":[{"type":"text","value":"1"}]}]},{"type":"text","value":")"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"Multithreading"}]},{"type":"text","value":" - multithreading is a tricky, widely available solution for lean concurrency with shared resources within the same process. Threads are lighter execution units than processes. Let's refer back to the factory analogy. Here, we use just the one factory (=process) to run our code. We achieve concurrency by employing many workers to perform many tasks. The workers share the factory facilities and machines, so we save big on resources. If they can work at the same time (=in parallel), we can produce more in a given time ("},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"CPU-bound"}]},{"type":"text","value":" work)."},{"type":"element","tag":"br","props":{},"children":[]},{"type":"text","value":"It is important to state that multithreading can also provide performance benefits for ("},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"I/O-bound"}]},{"type":"text","value":" work). In languages with a GIL like Python, we effectively only allow one employee to work at any given time, and we switch between them. Why is this still useful? Workers, when not idle, can schedule deliveries, start long-running processes on machines, etc. - so if our factory mostly consists of kick-starting autonomous tasks ("},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"I/O-bound"}]},{"type":"text","value":" work), multiple employees can still accomplish much more than a single employee. With the meager time each employee is given, he can start some independent task, such as scheduling a delivery. We immediately yell \"freeze!\" and transfer the working rights to another worker. He too, registers some task. When we return to the first worker, our delivery has already arrived, and our worker can program a processing machine before we freeze him again."},{"type":"element","tag":"br","props":{},"children":[]},{"type":"text","value":"Back to reality. While multithreading is the ideal solution for CPU-bound work, it is less than ideal for I/O bound work. Even in a language that allows multi-threaded parallelism, our program still has idle CPU usage while any given thread waits for some I/O operation to complete. In addition, context switching between threads is time consuming, and as running permission is a zero-sum game, every millisecond of time given to one thread is a millisecond taken from another. So every thread is still resource consuming (though much leaner than a full process)."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"Asynchronous Tasks"}]},{"type":"text","value":"- This solution is relevant to I/O bound work, and can solve the wasted resource issues highlighted in the previous paragraph when using multithreading for I/O bound work. This is the final improvement to our factory, and it includes paying one of our employees more so he's willing to \"multi-task\"."},{"type":"element","tag":"br","props":{},"children":[]},{"type":"text","value":"Now, we hire a supervisor and buy a whiteboard. Our supervisor's job is to provide our employee with tasks to do when a task is completed. The worker schedules some delivery. Instead of waiting for the delivery, he first writes on the whiteboard: \"Supervisor, please let me know when the delivery has arrived for further processing\". Then he can immediately begin scheduling another delivery, or operating on deliveries from yesterday. The supervisor keeps an eye on the loading dock, and eventually the first delivery arrives. He erases the task from the whiteboard and tells the worker, who begins processing the delivery that just arrived. And so on."},{"type":"element","tag":"br","props":{},"children":[]},{"type":"text","value":"So this solution requires a couple of components, but it can saves immensely on resources when the work is mostly I/O bound - it needs a single thread for our actual code (the worker), and some constant number of other threads and data structures to inform our thread of new tasks and keep an eye out for completed async operations (the supervisor) and keep tabs on registered tasks (the whiteboard). Our code registers some async task, and requests to be notified when it returns with the results. It notifies the framework what it wants to do with the result, but the syntax of how it is notified and the underlying objects are very framework and languages specific."}]}]},{"type":"element","tag":"h3","props":{"id":"back-to-buzzwords"},"children":[{"type":"text","value":"Back to buzzwords"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The only way to get "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"parallelization"}]},{"type":"text","value":" in Python - in order to reduce execution time for "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"CPU-bound"}]},{"type":"text","value":" programs, is "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"multi-processing"}]},{"type":"text","value":", because of the "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"GIL"}]},{"type":"text","value":". This, by definition, doesn't come with shared resources like "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"multi-threading"}]},{"type":"text","value":" - so there's a large performance and resource penalty. This is not to say that threads have no use in Python - they may be used for reducing execution time for "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"I/O bound"}]},{"type":"text","value":" programs. Another Python-native alternative that can accomplish basically the same thing is the newish "},{"type":"element","tag":"a","props":{"href":"https://docs.python.org/3/library/asyncio.html","rel":["nofollow"]},"children":[{"type":"text","value":"asyncio"}]},{"type":"text","value":" library, that enables asynchronous code with a single thread."}]},{"type":"element","tag":"h3","props":{"id":"ack"},"children":[{"type":"text","value":"Ack"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Writing and resources about concurrency that I like:"}]}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Great "},{"type":"element","tag":"a","props":{"href":"https://www.youtube.com/watch?v=lJ3NC-R3gSI","rel":["nofollow"]},"children":[{"type":"text","value":"talk"}]},{"type":"text","value":" by Steve Klabnik."}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Great "},{"type":"element","tag":"a","props":{"href":"https://eloquentjavascript.net/11_async.html","rel":["nofollow"]},"children":[{"type":"text","value":"chapter"}]},{"type":"text","value":" about async in eloquentJS, an outstanding book."}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"Friends that helped"}]}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Yoav Tzfati helped clean up my Python code"}]},{"type":"element","tag":"li","props":{},"children":[{"type":"text","value":"Naomi Kriger and Yoav read my drafts"}]}]},{"type":"element","tag":"section","props":{"className":["footnotes"],"dataFootnotes":""},"children":[{"type":"element","tag":"h2","props":{"className":["sr-only"],"id":"footnote-label"},"children":[{"type":"text","value":"Footnotes"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{"id":"user-content-fn-1"},"children":[{"type":"text","value":"A Python developer friend of mine offered up the following heuristic: If you find yourself reaching for multi-processing in order to incorporate parallel code execution, it's time to choose a different language for this particular task. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-1","ariaLabel":"Back to reference 1","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-1-2","ariaLabel":"Back to reference 1-2","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"},{"type":"element","tag":"sup","props":{},"children":[{"type":"text","value":"2"}]}]}]},{"type":"element","tag":"li","props":{"id":"user-content-fn-2"},"children":[{"type":"text","value":"For brevity, we also implicitly disregard a further step where parallelism can come in handy - some calculations may perhaps allow for non-sequential execution of certain steps. This doesn't diminish the point, though. Say we've found the most reduced version of the algorithm, split among as many units as possible. We are still left with \"hard\" work needing to be completed. So we've tried our best to reach a solution in as little time as possible - but we still need to bite the bullet of real work needing to be done. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-2","ariaLabel":"Back to reference 2","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]},{"type":"element","tag":"li","props":{"id":"user-content-fn-3"},"children":[{"type":"text","value":"Although you would be hard pressed to justify the semantics, based on needle-thin differences between the dictionary definitions of some of the above terms. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-3","ariaLabel":"Back to reference 3","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]},{"type":"element","tag":"li","props":{"id":"user-content-fn-4"},"children":[{"type":"text","value":"I think that for a programmer like me, who's written only consumers - programs that just consume computing power - it may be harder to understand this perspective. Once you write a provider, such as an operating system, you suddenly understand this. You own "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"all"}]},{"type":"text","value":" of the resources - so when you parallelize management processes you'll notice you're stepping on your own toes - all of your programs are standing in line for water. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-4","ariaLabel":"Back to reference 4","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]},{"type":"element","tag":"li","props":{"id":"user-content-fn-5"},"children":[{"type":"text","value":"We can also quantify CPU usage as energy expenditure to further illustrate the point. There is no \"free\" energy - to this end, parallelizing CPU-bound programs cannot save energy. Async code also cannot save energy - but it "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"can"}]},{"type":"text","value":" minimize wasting energy. A more concise (but, in reality, wrong) framing of this idea is that the ideal program is only bound by CPU usage, as a program where we've solved all I/O issues is left with only CPU usage. This program doesn't exist, except in theory. I/O includes loading the next CPU instructions and reading registers as well, for example. In addition, These are not the only two bounds a program may have, for example another extremely important bound is "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/Memory-bound_function","rel":["nofollow"]},"children":[{"type":"text","value":"memory"}]}]},{"type":"text","value":", and a program is a tradeoff between all bounds. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-5","ariaLabel":"Back to reference 5","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]},{"type":"element","tag":"li","props":{"id":"user-content-fn-6"},"children":[{"type":"text","value":"A clock-cycle saved is a clock-cycle earned. This key insight, that a best case scenario asynchronous framework may reduce CPU usage, is what allows event-driven servers to serve many concurrent requests when the requests are mostly I/O bound. A new thread need not be created to serve every request - this can save an enormous amount of resources, in contrast with a thread-per-request framework which is capped by the realistic amount of threads that the server can maintain, thus severely limiting the vertical scaling of the server's possible concurrent requests. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-6","ariaLabel":"Back to reference 6","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]},{"type":"element","tag":"li","props":{"id":"user-content-fn-7"},"children":[{"type":"text","value":"Assuming only one line of Python bytecode is running allowed the writers of python interpreters to write simpler implementations. The trouble is, years later multi-threaded parallelization became important to many programming fields where performance is crucial. Now, existing Python implementations such as CPython are in trouble because the one-line assumption is fundamentally baked in to the underlying C and lifting the GIL as-is would break the interpreter. The "},{"type":"element","tag":"a","props":{"href":"https://www.youtube.com/watch?v=B_cQ0ykux_4","rel":["nofollow"]},"children":[{"type":"text","value":"\"Gilectomy\""}]},{"type":"text","value":", an attempt to remove the GIL from CPython, is a demonstration to that effect. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-7","ariaLabel":"Back to reference 7","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]},{"type":"element","tag":"li","props":{"id":"user-content-fn-8"},"children":[{"type":"text","value":"This allows us to transform nested callbacks into a list, eliminating callback nesting. Not much later, the language introduced a syntactical wrapper for the promise API that uses the "},{"type":"element","tag":"span","props":{"className":["term","cursor-default","px-1","rounded"]},"children":[{"type":"text","value":"await"}]},{"type":"text","value":" keyword. This is an adoption of "},{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/Async/await","rel":["nofollow"]},"children":[{"type":"text","value":"syntax"}]},{"type":"text","value":" common to many languages, which enables giving asynchronous code a synchronous look, therefore arguably improving readability. "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-8","ariaLabel":"Back to reference 8","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]}]}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"concurrency","depth":2,"text":"Concurrency","children":[{"id":"types-of-work","depth":3,"text":"Types of work"},{"id":"enhancing-performance","depth":3,"text":"Enhancing Performance"},{"id":"concurrency-1","depth":3,"text":"Concurrency"},{"id":"a-taste-of-real-world-concurrency","depth":3,"text":"A Taste of Real-world Concurrency"},{"id":"back-to-buzzwords","depth":3,"text":"Back to buzzwords"},{"id":"ack","depth":3,"text":"Ack"}]},{"id":"footnote-label","depth":2,"text":"Footnotes"}]}},"_type":"markdown","_id":"content:Concurrency.md","_source":"content","_file":"Concurrency.md","_extension":"md"},{"_path":"/ok-sometimes-async-await","_dir":"","_draft":false,"_partial":false,"_locale":"","title":"Ok, Sometimes Async Await","description":"","body":{"type":"root","children":[{"type":"element","tag":"h2","props":{"id":"ok-sometimes-async-await"},"children":[{"type":"text","value":"Ok, Sometimes Async-Await"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Normally, I continue believing that the classic (well, ES6) "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"promise.then().catch().finally()"}]},{"type":"text","value":" is nicer than using the newer ES17 "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"async-await"}]},{"type":"text","value":" syntax, because of function composability"},{"type":"element","tag":"sup","props":{},"children":[{"type":"element","tag":"a","props":{"href":"#user-content-fn-1","ariaDescribedBy":["footnote-label"],"dataFootnoteRef":"","id":"user-content-fnref-1"},"children":[{"type":"text","value":"1"}]}]},{"type":"text","value":".\nThere are 2 cases where I think "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"async-await"}]},{"type":"text","value":" is neater, and one where it may perceivably come in handy:"}]},{"type":"element","tag":"h3","props":{"id":"_1-early-returnthrowing-errors"},"children":[{"type":"text","value":"1. Early Return/Throwing Errors"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes synthwave-84","code":"async function returnEarly(): Promise {\n if (someCondition) return;\n await networkRequest();\n if (someOtherCondition) return;\n return await someOtherNetworkRequest();\n}\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" returnEarly"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"()"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" Promise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":"SomeType"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" |"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" undefined"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"> {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"someCondition"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" networkRequest"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"someOtherCondition"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" someOtherNetworkRequest"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This way, your function can return early concisely, "},{"type":"element","tag":"strong","props":{},"children":[{"type":"text","value":"but still always return a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Promise"}]}]},{"type":"text","value":".\nThis is because, all values returned from an "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"async function"}]},{"type":"text","value":" are automatically wrapped in a "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"Promise"}]},{"type":"text","value":" if they aren't already. The equivalent code is pretty ugly:"}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes synthwave-84","code":"function returnEarly(): Promise {\n if (someCondition) return Promise.resolve();\n return networkRequest().then(() => {\n if (someOtherCondition) return Promise.resolve();\n return someOtherNetworkRequest();\n });\n}\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" returnEarly"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"()"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" Promise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"<"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":"SomeType"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" |"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" undefined"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"> {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"someCondition"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" Promise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"resolve"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" networkRequest"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"()."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"then"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"(() "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" if"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" ("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"someOtherCondition"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" Promise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"resolve"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" someOtherNetworkRequest"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":6},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" });\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":7},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"_2-promise-drilling"},"children":[{"type":"text","value":"2. Promise Drilling"}]},{"type":"element","tag":"pre","props":{"className":"language-js shiki shiki-themes synthwave-84","code":"async function hotPotato() {\n const a = await networkRequestA();\n const b = await networkRequestB(a);\n return await networkRequestC(a, b);\n}\n","language":"js","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" hotPotato"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"() {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FFFFFFEE"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" networkRequestA"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"();\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" const"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" b"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FFFFFFEE"},"children":[{"type":"text","value":" ="}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" networkRequestB"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":");\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" await"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" networkRequestC"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"b"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":");\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Sometimes, a computation requires a value several promises upstream. Using "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"async-await"}]},{"type":"text","value":", you see the entire function's scope trivially, so you don't need to drill down with the value."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The equivalent code is ugly:"}]},{"type":"element","tag":"pre","props":{"className":"language-js shiki shiki-themes synthwave-84","code":"function hotPotato() {\n return A()\n .then((a) => B(a).then((b) => [a, b]))\n .then(([a, b]) => C(a, b));\n}\n","language":"js","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" hotPotato"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"() {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" A"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"()\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" ."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"then"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"(("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" B"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":")."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"then"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"(("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"b"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" ["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"b"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"]))\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":4},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" ."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"then"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"((["}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"b"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"]) "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" C"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"a"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"b"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"));\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":5},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"h3","props":{"id":"_3-object-asyncfunction"},"children":[{"type":"text","value":"3? [object AsyncFunction]"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This does not generally strike me as useful, but can theoretically come in handy."}]},{"type":"element","tag":"pre","props":{"className":"language-ts shiki shiki-themes synthwave-84","code":"Object.prototype.toString.call(async () => producePromise()); // '[object AsyncFunction]'\nObject.prototype.toString.call(() => producePromise()); // '[object Function]'\n","language":"ts","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":"Object"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"prototype"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"toString"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"call"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"async"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":" () "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" producePromise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"()); "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#848BBD;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"// '[object AsyncFunction]'\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":"Object"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"prototype"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":"toString"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"."}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"call"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"(() "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"=>"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" producePromise"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"()); "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#848BBD;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"// '[object Function]'\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So the language gives us a way to know if a function was declared with the "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"async"}]},{"type":"text","value":" modifier.\nIn some contrived scenario, we can imagine that it may be very useful to be able to check during runtime if the function will be asynchronous "},{"type":"element","tag":"em","props":{},"children":[{"type":"text","value":"before invoking it"}]},{"type":"text","value":"."}]},{"type":"element","tag":"hr","props":{},"children":[]},{"type":"element","tag":"section","props":{"className":["footnotes"],"dataFootnotes":""},"children":[{"type":"element","tag":"h2","props":{"className":["sr-only"],"id":"footnote-label"},"children":[{"type":"text","value":"Footnotes"}]},{"type":"element","tag":"ol","props":{},"children":[{"type":"element","tag":"li","props":{"id":"user-content-fn-1"},"children":[{"type":"text","value":"Composability: "},{"type":"element","tag":"code","props":{"className":[]},"children":[{"type":"text","value":"fetchThing().then(doThing).catch(logError).finally(toFalse)"}]},{"type":"text","value":" "},{"type":"element","tag":"a","props":{"href":"#user-content-fnref-1","ariaLabel":"Back to reference 1","className":["data-footnote-backref"],"dataFootnoteBackref":""},"children":[{"type":"text","value":"↩"}]}]}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"ok-sometimes-async-await","depth":2,"text":"Ok, Sometimes Async-Await","children":[{"id":"_1-early-returnthrowing-errors","depth":3,"text":"1. Early Return/Throwing Errors"},{"id":"_2-promise-drilling","depth":3,"text":"2. Promise Drilling"},{"id":"_3-object-asyncfunction","depth":3,"text":"3? [object AsyncFunction]"}]},{"id":"footnote-label","depth":2,"text":"Footnotes"}]}},"_type":"markdown","_id":"content:Ok, Sometimes Async-Await.md","_source":"content","_file":"Ok, Sometimes Async-Await.md","_extension":"md"},{"_path":"/typescript-typesystems-and-javascript","_dir":"","_draft":false,"_partial":false,"_locale":"","title":"TypeScript, TypeSystems And JavaScript","description":"","body":{"type":"root","children":[{"type":"element","tag":"h2","props":{"id":"typescript-typesystems-and-javascript"},"children":[{"type":"text","value":"TypeScript, TypeSystems and JavaScript"}]},{"type":"element","tag":"h3","props":{"id":"buzzwords"},"children":[{"type":"text","value":"Buzzwords"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"TypeScript (or “TS”) is a language built upon JavaScript (or “JS”), the primary (perhaps a vast, vast understatement) language used to program web applications. The term “built upon” is important here — TS is “strict superset” of JavaScript. This means that any valid JS program is also a valid TS program."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"TypeScript (or TS) first appeared 9 years ago, in 2012. It is written and maintained by Microsoft. It is now one of the "},{"type":"element","tag":"a","props":{"href":"https://venturebeat.com/2020/12/02/github-python-and-typescript-gain-popularity-among-programming-languages/","rel":["nofollow"]},"children":[{"type":"text","value":"most popular"}]},{"type":"text","value":" programming tools in the world. If TS were a startup company, early investors would be breaking out the champagne. Without exaggerating, I think most webdevs would agree with me in thinking that it won’t be long before “vanilla” JS will no longer be shipped in any new commercial product. For anything more than a personal/hobby project, JS will be constrained in TS shackles."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"If the last two paragraphs irritated you, you’re not alone — they irritate me as well, although true. Buzzwords cut through all articles promoting some library or another, and they make it impossible to make actual value judgements. Moreover, they distract the reader from actual trends and move the focus from concepts to products. If C# were to switch out Java in its inception, do we envision a vastly different developmental landscape in the 90s? I’d argue against that. Rather, Java and its viable alternatives heralded the well-known trend (and one of more popular religions) of Object Oriented Programming, or OOP."}]},{"type":"element","tag":"h3","props":{"id":"an-example"},"children":[{"type":"text","value":"An Example"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So, the following case for TypeScript is actually a general case for using a type system in JavaScript programming. TypeScript is just the current best-in-class (by a wide chasm), and an objectively excellent candidate for accomplishing this goal. Let’s examine a very simple function in JS:"}]},{"type":"element","tag":"pre","props":{"className":"language-javascript shiki shiki-themes synthwave-84","code":"function multiply(x, y) {\n return x * y;\n}\n","language":"javascript","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" multiply"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"x"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"y"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" x"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" *"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" y"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Let’s call this function:"}]},{"type":"element","tag":"pre","props":{"className":"language-javascript shiki shiki-themes synthwave-84","code":"multiply(2, 3); // = 6\n","language":"javascript","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"multiply"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#2EE2FA"},"children":[{"type":"text","value":"2"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#2EE2FA"},"children":[{"type":"text","value":"3"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"); "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#848BBD;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"// = 6\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"So thats very nice. We have a function that multiplies two numbers. But let’s call it with a string:"}]},{"type":"element","tag":"pre","props":{"className":"language-javascript shiki shiki-themes synthwave-84","code":"multiply(2, \"hello\"); // = NaN\n","language":"javascript","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":"multiply"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#2EE2FA"},"children":[{"type":"text","value":"2"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF8B39"},"children":[{"type":"text","value":"\"hello\""}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"); "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#848BBD;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"// = NaN\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This is obviously a nonsensical operation (although "},{"type":"element","tag":"a","props":{"href":"https://www.pythoncentral.io/use-python-multiply-strings/","rel":["nofollow"]},"children":[{"type":"text","value":"in Python"}]},{"type":"text","value":" multiplying 2 by “hello” would return “hellohello”. This is adorable) — and we receive NaN, which is a special value in JS which means “not a number” (complying with the "},{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/NaN","rel":["nofollow"]},"children":[{"type":"text","value":"IEEE 754 floating point standard"}]},{"type":"text","value":"). So it was a syntactically legal operation, but I doubt anyone writing that function wants their function to be called with a string value. Accordingly, this function could be written in TS like this:"}]},{"type":"element","tag":"pre","props":{"className":"language-typescript shiki shiki-themes synthwave-84","code":"function multiply(x: number, y: number) {\n return x * y;\n}\n","language":"typescript","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" multiply"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"x"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" number"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"y"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" number"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" x"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" *"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" y"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"We’ve simply told TS that we don’t allow non number inputs to be given to the function. Now the second function call with the string value is illegal — TypeScript will yell at you and your editor will highlight it with red, mean squiggly lined until you change it, optionally forbidding you to ship your code until you do. This may seem annoying at first — you must sprinkle type hints all around the place for TS to be happy, and it will yell at you if you dont obey your own rules. Migrating most of my company’s codebase was a lesson in patience in that regard. But the effort pays off in compound down the road, and let’s examine why."}]},{"type":"element","tag":"h3","props":{"id":"so-what"},"children":[{"type":"text","value":"So What"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"The "},{"type":"element","tag":"a","props":{"href":"https://www.python.org/dev/peps/pep-0020/","rel":["nofollow"]},"children":[{"type":"text","value":"Python zen"}]},{"type":"text","value":" teaches us “Explicit is better than implicit” — users familiar with type systems (who are gawking at my “discovery” of a feature existing in languages for over 45 years) might think I’m invoking this rule for readability reasons — as in, any person reading my multiply function with type hints will know immediately that the inputs are 2 numbers. This is true (although, TS has very powerful type inference, such that in many cases you may leave off type hints). Another valid point would be the functionality aspect — as I’ve mentioned, calling multiply with “hello” is now impossible, which is a great thing."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"For me, though, the most compelling case for type systems is more conceptual. TS forces you to explicitly fill your programs with assertions that mirror your assumptions about the program. Let’s rewrite our multiplication function:"}]},{"type":"element","tag":"pre","props":{"className":"language-typescript shiki shiki-themes synthwave-84","code":"function fruitPrice(basePrice: number, quantity: number) {\n return basePrice * quantity;\n}\n","language":"typescript","meta":"","style":""},"children":[{"type":"element","tag":"code","props":{"__ignoreMap":""},"children":[{"type":"element","tag":"span","props":{"class":"line","line":1},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":"function"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#36F9F6"},"children":[{"type":"text","value":" fruitPrice"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"("}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"basePrice"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" number"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":", "}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB;--shiki-default-font-style:italic"},"children":[{"type":"text","value":"quantity"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":":"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FE4450"},"children":[{"type":"text","value":" number"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":") {\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":2},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" return"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" basePrice"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FEDE5D"},"children":[{"type":"text","value":" *"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#FF7EDB"},"children":[{"type":"text","value":" quantity"}]},{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":";\n"}]}]},{"type":"element","tag":"span","props":{"class":"line","line":3},"children":[{"type":"element","tag":"span","props":{"style":"--shiki-default:#BBBBBB"},"children":[{"type":"text","value":"}\n"}]}]}]}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"This function works great in dev with mock data, we receive the price of fruit from the server and the quantity from the client. Before pushing to production, the backend dev tells us that due to new architecture decisions, the price of certain fruit may be undetermined — now we may receive null, or an empty string when asking for the price of a fruit. Now when I call the price function with this new value, which may be undefined or a number, TypeScript yells because it know I am passing in a value which may not be a legal number."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Again, this is great — my function would fail without a rewrite. But the real lesson I can take from the squiggly lines is about my assumptions. TS punishes you for a lenient or thoughtlessly written piece of code — it forces you to reexamine what you think the program actually does. So fruitPrice will undoubtedly have to change, but now you know where you casually gave yourself a break by assuming a stricter subset of input than in reality. Now you know your program must take an undetermined price into account. TS will selflessly tell you where this assumption is relevant, but the real takeaway is forcing you to more strictly define your program."}]},{"type":"element","tag":"h3","props":{"id":"but-typescript-though"},"children":[{"type":"text","value":"But TypeScript, Though"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"Something must be said about the tool in order to encourage its’ use, aside from touting the general benefits of a type system. So why TS, after all?"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"From a maintenance perspective, TS is, as mentioned, maintained by Microsoft. There are constant releases fixing bugs and meeting performance goals. New features are great, but really a dev needs to know that the project won’t "},{"type":"element","tag":"a","props":{"href":"https://www.theregister.com/2020/03/26/corejs_maintainer_jailed_code_release/","rel":["nofollow"]},"children":[{"type":"text","value":"collapse"}]},{"type":"text","value":" because of a dangerous dependency on a small team’s free time, and that the project won’t be "},{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/CoffeeScript","rel":["nofollow"]},"children":[{"type":"text","value":"forgotten"}]},{"type":"text","value":" after a swift period of adoption. There are no guarantees, obviously, and no project lasts forever. But, for now, it seems like the buzzword period is mostly over — and the aftermath is major "},{"type":"element","tag":"a","props":{"href":"https://angular.io/guide/typescript-configuration","rel":["nofollow"]},"children":[{"type":"text","value":"libraries"}]},{"type":"text","value":" and "},{"type":"element","tag":"a","props":{"href":"https://deno.land/","rel":["nofollow"]},"children":[{"type":"text","value":"technologies"}]},{"type":"text","value":" have adopted TS, or "},{"type":"element","tag":"a","props":{"href":"https://reactjs.org/docs/static-type-checking.html#typescript","rel":["nofollow"]},"children":[{"type":"text","value":"at least actively maintain type declaration files and tooling"}]},{"type":"text","value":" for consumers. Bet on TypeScript."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"I think one of the reasons for TS’s steady success is its’ core product — type systems for JS. It has cultivated many features that were eventually swallowed into vanilla JS — "},{"type":"element","tag":"a","props":{"href":"https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining","rel":["nofollow"]},"children":[{"type":"text","value":"optional chaining"}]},{"type":"text","value":", what seems like "},{"type":"element","tag":"a","props":{"href":"https://www.typescriptlang.org/docs/handbook/classes.html","rel":["nofollow"]},"children":[{"type":"text","value":"direct inspiration for JS es2015 classes"}]},{"type":"text","value":", "},{"type":"element","tag":"a","props":{"href":"https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#nullish-coalescing","rel":["nofollow"]},"children":[{"type":"text","value":"nullish coalescing"}]},{"type":"text","value":" etc. But really, the main feature which browsers cannot adopt is the type system — JS is inherently dynamic, and a type system is a radical change browsers cannot simply add in. So by not competing with juggernaut browsers over its’ main feature, it can prevail safely without fearing a sudden hostile takeover."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"From a non maintenance perspective, TS has built its’ type system around widely used JS patterns. One example is that the TS type system is "},{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/Structural_type_system","rel":["nofollow"]},"children":[{"type":"text","value":"structural"}]},{"type":"text","value":" rather than nominal — basically, that one value is equivalent to another if it shares the structure of the other value. For example, a function that recieves { a: number; } as an argument, will also accept { a: number; b: number; } — the second type can be treated as the first type for all intents and purposes that the first type is used for in the function."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In many other type systems, types can act in for other types only if an explicit (=nominal) relationship was tied between them, such as inheritance. A structural type system fits the JS pattern of constant usage of anonynous objects and values (including functions), without explicitly calling constructors and so forth. Forcing nonimal typing on existing JS code would change the style and patterns devs are used to. This is not the only advantage to a structural type system, but it illustrates the thinking behind the language design. For more on the unique fit between TS and JS (I didn’t even touch on the functional aspect), I strongly recommend watching "},{"type":"element","tag":"a","props":{"href":"https://www.youtube.com/watch?v=jmPZztKIFf4","rel":["nofollow"]},"children":[{"type":"text","value":"this talk"}]},{"type":"text","value":" by "},{"type":"element","tag":"a","props":{"href":"https://en.wikipedia.org/wiki/Anders_Hejlsberg","rel":["nofollow"]},"children":[{"type":"text","value":"Anders Hejlsberg"}]},{"type":"text","value":"."}]},{"type":"element","tag":"h3","props":{"id":"giving-the-web-context"},"children":[{"type":"text","value":"Giving the Web Context"}]},{"type":"element","tag":"p","props":{},"children":[{"type":"text","value":"In a final note, moving this text from notepad to an actual text editor with a spellchecker has shamefully revealed many squiggly lines, red, blue and green. In an imperfect analogy, JS editors have long had red lines for syntax errors (a.k.a. spelling mistakes). TS is more than a library, as it introduces a feature entirely impossible in current JS — green and blue squiggly lines, for contextual and grammatical errors. Suddenly my programs are more than blocks of black text, they speak to me and challenge my assumptions. So while we roll in the "},{"type":"element","tag":"a","props":{"href":"https://insights.stackoverflow.com/survey/2020#technology-what-languages-are-associated-with-the-highest-salaries-worldwide","rel":["nofollow"]},"children":[{"type":"text","value":"slim surplus of cash"}]},{"type":"text","value":" we supposedly make by writing TS over plain JS, let’s all collectively move our programs from notepad to a text editor."}]},{"type":"element","tag":"p","props":{},"children":[{"type":"element","tag":"a","props":{"href":"https://medium.com/@netanel.t.haber/typescript-typesystems-and-javascript-83153f249ce3?source=post_page-----83153f249ce3--------------------------------","rel":["nofollow"]},"children":[{"type":"text","value":"Originally published on February 27, 2021, on Medium"}]}]},{"type":"element","tag":"style","props":{},"children":[{"type":"text","value":"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}"}]}],"toc":{"title":"","searchDepth":2,"depth":2,"links":[{"id":"typescript-typesystems-and-javascript","depth":2,"text":"TypeScript, TypeSystems and JavaScript","children":[{"id":"buzzwords","depth":3,"text":"Buzzwords"},{"id":"an-example","depth":3,"text":"An Example"},{"id":"so-what","depth":3,"text":"So What"},{"id":"but-typescript-though","depth":3,"text":"But TypeScript, Though"},{"id":"giving-the-web-context","depth":3,"text":"Giving the Web Context"}]}]}},"_type":"markdown","_id":"content:TypeScript, TypeSystems and JavaScript.md","_source":"content","_file":"TypeScript, TypeSystems and JavaScript.md","_extension":"md"}],"navigation":[{"title":"Concurrency","_path":"/concurrency"},{"title":"Ok, Sometimes Async Await","_path":"/ok-sometimes-async-await"},{"title":"TypeScript, TypeSystems And JavaScript","_path":"/typescript-typesystems-and-javascript"}]} \ No newline at end of file diff --git a/api/_content/query/1pxjniE9Qa.1717319116628.json b/api/_content/query/1pxjniE9Qa.1717319582386.json similarity index 100% rename from api/_content/query/1pxjniE9Qa.1717319116628.json rename to api/_content/query/1pxjniE9Qa.1717319582386.json diff --git a/api/_content/query/LZLxbnB5O3.1717319116628.json b/api/_content/query/LZLxbnB5O3.1717319582386.json similarity index 100% rename from api/_content/query/LZLxbnB5O3.1717319116628.json rename to api/_content/query/LZLxbnB5O3.1717319582386.json diff --git a/api/_content/query/gN4uEe4KzX.1717319116628.json b/api/_content/query/gN4uEe4KzX.1717319582386.json similarity index 100% rename from api/_content/query/gN4uEe4KzX.1717319116628.json rename to api/_content/query/gN4uEe4KzX.1717319582386.json diff --git a/blog/_payload.json b/blog/_payload.json index e7b394f..f3e4c0b 100644 --- a/blog/_payload.json +++ b/blog/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":3},["Reactive",2],{},1717319128706] \ No newline at end of file +[{"data":1,"prerenderedAt":3},["Reactive",2],{},1717319594549] \ No newline at end of file diff --git a/blog/index.html b/blog/index.html index 7bb82c3..5a91782 100644 --- a/blog/index.html +++ b/blog/index.html @@ -4,10 +4,10 @@ - + - - - - - \ No newline at end of file + + + + + \ No newline at end of file diff --git a/concurrency/_payload.json b/concurrency/_payload.json index f413b18..06c6e05 100644 --- a/concurrency/_payload.json +++ b/concurrency/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":1125},["Reactive",2],{"content-query-QonU1WAlCl":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":5,"title":7,"description":5,"body":8,"_type":1120,"_id":1121,"_source":1122,"_file":1123,"_extension":1124},"/concurrency","",false,"Concurrency",{"type":9,"children":10,"toc":1107},"root",[11,19,25,41,135,140,147,183,190,246,252,257,295,313,345,350,356,369,394,412,429,466,471,483,488,553,559,564,587,624,629,647,648,654,678,684,689,790,796,855,861,869,899,907,920],{"type":12,"tag":13,"props":14,"children":16},"element","h2",{"id":15},"concurrency",[17],{"type":18,"value":7},"text",{"type":12,"tag":20,"props":21,"children":22},"p",{},[23],{"type":18,"value":24},"This article aims to explain basic concepts related to concurrency, which is used to solve performance related problems. It starts and ends with Python (CPython, mostly), as a tie from and back into reality - but isn't really about Python at all. Actually, it isn't about any language, framework or library in particular. It aims to take a step back from questions of application and start from first principles.",{"type":12,"tag":20,"props":26,"children":27},{},[28,30,39],{"type":18,"value":29},"Let's start by stating some facts about python concurrency. They may seem contradictory or confusing - the rest of the article aims to provide more clarity as to how they make sense together. It should be noted that some of these facts pertain to a standard use of Python - it is possible to bypass some limitations, either by using a less popular Python implementation, or by using non-standard ",{"type":12,"tag":31,"props":32,"children":36},"a",{"href":33,"rel":34},"https://numba.pydata.org/",[35],"nofollow",[37],{"type":18,"value":38},"tools",{"type":18,"value":40}," and libraries.",{"type":12,"tag":42,"props":43,"children":44},"ol",{},[45,75,94,111],{"type":12,"tag":46,"props":47,"children":48},"li",{},[49,55,57,64,66,73],{"type":12,"tag":50,"props":51,"children":52},"strong",{},[53],{"type":18,"value":54},"Python has threads.",{"type":18,"value":56},"\nIf anyone says otherwise, they have important ",{"type":12,"tag":31,"props":58,"children":61},{"href":59,"rel":60},"https://docs.python.org/3/library/threading.html",[35],[62],{"type":18,"value":63},"standard",{"type":18,"value":65}," Python ",{"type":12,"tag":31,"props":67,"children":70},{"href":68,"rel":69},"https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor",[35],[71],{"type":18,"value":72},"modules",{"type":18,"value":74}," to explain away.",{"type":12,"tag":46,"props":76,"children":77},{},[78,83,85,92],{"type":12,"tag":50,"props":79,"children":80},{},[81],{"type":18,"value":82},"Python threads are useful",{"type":18,"value":84},". ",{"type":12,"tag":31,"props":86,"children":89},{"href":87,"rel":88},"https://replit.com/@NetanelHaber/pythonthreads?v=1",[35],[90],{"type":18,"value":91},"Here are numbers for you to look at",{"type":18,"value":93},".",{"type":12,"tag":46,"props":95,"children":96},{},[97,102,104,109],{"type":12,"tag":50,"props":98,"children":99},{},[100],{"type":18,"value":101},"No parallelization in python",{"type":18,"value":103},": CPython threads cannot solve ",{"type":12,"tag":50,"props":105,"children":106},{},[107],{"type":18,"value":108},"every",{"type":18,"value":110}," problem threads are put to use for in languages like C and C++.",{"type":12,"tag":46,"props":112,"children":113},{},[114,119,121,134],{"type":12,"tag":50,"props":115,"children":116},{},[117],{"type":18,"value":118},"Multi-processing can provide parallelization in Python",{"type":18,"value":120},", although in practice the performance overhead will sometimes cancel out or severely reduce the wanted benefit",{"type":12,"tag":122,"props":123,"children":124},"sup",{},[125],{"type":12,"tag":31,"props":126,"children":131},{"href":127,"ariaDescribedBy":128,"dataFootnoteRef":5,"id":130},"#user-content-fn-1",[129],"footnote-label","user-content-fnref-1",[132],{"type":18,"value":133},"1",{"type":18,"value":93},{"type":12,"tag":20,"props":136,"children":137},{},[138],{"type":18,"value":139},"So what is the rule? When is multi-threading useful? Why is Python different than some other languages?",{"type":12,"tag":141,"props":142,"children":144},"h3",{"id":143},"types-of-work",[145],{"type":18,"value":146},"Types of work",{"type":12,"tag":20,"props":148,"children":149},{},[150,152,168,170,181],{"type":18,"value":151},"Two basic concepts in this space are ",{"type":12,"tag":153,"props":154,"children":160},"span",{"className":155},[156,157,158,159],"term","cursor-default","px-1","rounded",[161],{"type":12,"tag":31,"props":162,"children":165},{"href":163,"rel":164},"https://en.wikipedia.org/wiki/CPU-bound",[35],[166],{"type":18,"value":167},"CPU-bound",{"type":18,"value":169}," and ",{"type":12,"tag":153,"props":171,"children":173},{"className":172},[156,157,158,159],[174],{"type":12,"tag":31,"props":175,"children":178},{"href":176,"rel":177},"https://en.wikipedia.org/wiki/I/O_bound",[35],[179],{"type":18,"value":180},"I/O-bound",{"type":18,"value":182}," (Input/Output) work. It helps to first state a basic fact: Computers have a fundamental bottleneck - they cannot execute more than one command at any time. Modern \"computers\" actually contain multiple computation units that can each execute one command at any given time. To compare the two types of work, we will first look at a single CPU core.",{"type":12,"tag":184,"props":185,"children":187},"h4",{"id":186},"multithreading-cpu-bound-work-on-a-single-core-the-same-work-with-extra-steps",[188],{"type":18,"value":189},"Multithreading CPU-bound work on a single core - the same work with extra steps",{"type":12,"tag":20,"props":191,"children":192},{},[193,195,202,204,215,217,223,225,231,233,239,241],{"type":18,"value":194},"If we task this computer with calculating ",{"type":12,"tag":196,"props":197,"children":199},"code",{"className":198},[],[200],{"type":18,"value":201},"(2 ^ 19) / (3 ^ 33)",{"type":18,"value":203},", it will boil the task down to a list of discreet commands to execute",{"type":12,"tag":122,"props":205,"children":206},{},[207],{"type":12,"tag":31,"props":208,"children":212},{"href":209,"ariaDescribedBy":210,"dataFootnoteRef":5,"id":211},"#user-content-fn-2",[129],"user-content-fnref-2",[213],{"type":18,"value":214},"2",{"type":18,"value":216},". This is very similar to human calculation. Say we've neared the end of a meal at a restaurant. We have two tasks ahead of us: Calculating the tip and calculating when to leave in order to catch a bus. The former calculation may penalize us ",{"type":12,"tag":196,"props":218,"children":220},{"className":219},[],[221],{"type":18,"value":222},"X",{"type":18,"value":224}," of our time, while the latter may take ",{"type":12,"tag":196,"props":226,"children":228},{"className":227},[],[229],{"type":18,"value":230},"Y",{"type":18,"value":232}," of our time. In other words, altogether ",{"type":12,"tag":196,"props":234,"children":236},{"className":235},[],[237],{"type":18,"value":238},"X+Y",{"type":18,"value":240}," work must be done. The \"brain-power\" (=time) will be spent, regardless of the way the work is divided, sliced or diced. ",{"type":12,"tag":50,"props":242,"children":243},{},[244],{"type":18,"value":245},"This is CPU-bound work.",{"type":12,"tag":184,"props":247,"children":249},{"id":248},"a-watched-pot-never-boils",[250],{"type":18,"value":251},"A watched pot never boils",{"type":12,"tag":20,"props":253,"children":254},{},[255],{"type":18,"value":256},"Now the computer is tasked with scraping Google search results. It receives a term as an argument and must retrieve the first 10 pages of results. So it:",{"type":12,"tag":42,"props":258,"children":259},{},[260,271,285],{"type":12,"tag":46,"props":261,"children":262},{},[263,265,270],{"type":18,"value":264},"Asks for the first page ",{"type":12,"tag":153,"props":266,"children":267},{},[268],{"type":18,"value":269},"10ms",{"type":18,"value":93},{"type":12,"tag":46,"props":272,"children":273},{},[274],{"type":12,"tag":50,"props":275,"children":276},{},[277,279,284],{"type":18,"value":278},"Waits for the result to return from Google servers ",{"type":12,"tag":153,"props":280,"children":281},{},[282],{"type":18,"value":283},"80ms",{"type":18,"value":93},{"type":12,"tag":46,"props":286,"children":287},{},[288,290,294],{"type":18,"value":289},"Receives the result and saves it in a file ",{"type":12,"tag":153,"props":291,"children":292},{},[293],{"type":18,"value":269},{"type":18,"value":93},{"type":12,"tag":20,"props":296,"children":297},{},[298,300,305,307,312],{"type":18,"value":299},"It then repeats these steps for all 10 pages.\nThe execution times are just an example, but resemble real-world times for similar programs. So let's focus on 2 - it seems to be our performance bottleneck, at 80% of all execution time. The key word here is ",{"type":12,"tag":50,"props":301,"children":302},{},[303],{"type":18,"value":304},"waiting",{"type":18,"value":306},". We have such a powerful tool at our disposal, and it mostly waits - i.e., does nothing, for most of our program. That's pretty unsavory. Next time you plan something with friends, try waiting for each friend to confirm before asking the next friend. ",{"type":12,"tag":50,"props":308,"children":309},{},[310],{"type":18,"value":311},"This is I/O-bound work",{"type":18,"value":93},{"type":12,"tag":20,"props":314,"children":315},{},[316,318,323,325,330,332,337,339,343],{"type":18,"value":317},"So a ",{"type":12,"tag":153,"props":319,"children":321},{"className":320},[156,157,158,159],[322],{"type":18,"value":167},{"type":18,"value":324}," task is one where the primary performance bottleneck is actual ",{"type":12,"tag":50,"props":326,"children":327},{},[328],{"type":18,"value":329},"work",{"type":18,"value":331}," that cannot be avoided. An ",{"type":12,"tag":153,"props":333,"children":335},{"className":334},[156,157,158,159],[336],{"type":18,"value":180},{"type":18,"value":338}," task is one where the primary performance bottleneck is actually just ",{"type":12,"tag":50,"props":340,"children":341},{},[342],{"type":18,"value":304},{"type":18,"value":344}," for an external piece of data.",{"type":12,"tag":20,"props":346,"children":347},{},[348],{"type":18,"value":349},"It is common sense that alleviating performance pain for problems with different bottlenecks will look different for each type of task. This is actually the key to our primary question. assessing the type of work before us - CPU, I/O or a mixture of both - can help us know in advance if certain solutions are applicable.",{"type":12,"tag":141,"props":351,"children":353},{"id":352},"enhancing-performance",[354],{"type":18,"value":355},"Enhancing Performance",{"type":12,"tag":20,"props":357,"children":358},{},[359,361,367],{"type":18,"value":360},"So for the first calculation task, we have a discreet list of commands we need to execute. Any unit can only execute one line at a time. We've already mentioned modern computers have many such units. So, for a slow program, the solution seems clear - divide and conquer. We divide our computation into smaller coherent parts (so we can assemble the solutions later for the final product), and give each available unit in the computer one part at a time to execute. For example, if we have a computation that can take 8X time, that can be divided into 8 smaller computations that each can take X time - and we have 8 cores - we can now accomplish this task in X time. This means that in order to enhance performance for CPU-bound tasks we need ",{"type":12,"tag":153,"props":362,"children":364},{"className":363},[156,157,158,159],[365],{"type":18,"value":366},"parallelization",{"type":18,"value":368}," - computing simultaneously on multiple units.",{"type":12,"tag":20,"props":370,"children":371},{},[372,374,380,382,393],{"type":18,"value":373},"The second task, where we were mostly waiting, can complete faster by being able to do other work while waiting. In the wild, you might see the term ",{"type":12,"tag":153,"props":375,"children":377},{"className":376},[156,157,158,159],[378],{"type":18,"value":379},"asynchronous",{"type":18,"value":381}," used to describe such programs that allow for doing work while waiting, depending on the language or framework. We will use this term as well",{"type":12,"tag":122,"props":383,"children":384},{},[385],{"type":12,"tag":31,"props":386,"children":390},{"href":387,"ariaDescribedBy":388,"dataFootnoteRef":5,"id":389},"#user-content-fn-3",[129],"user-content-fnref-3",[391],{"type":18,"value":392},"3",{"type":18,"value":93},{"type":12,"tag":20,"props":395,"children":396},{},[397,399,404,406,411],{"type":18,"value":398},"On a side note, let's notice a subtle difference between the enhancements we may gain from optimizing both types of work. While both parallelization and asynchronous solutions can ",{"type":12,"tag":50,"props":400,"children":401},{},[402],{"type":18,"value":403},"save on overall execution time",{"type":18,"value":405},", they cannot both ",{"type":12,"tag":50,"props":407,"children":408},{},[409],{"type":18,"value":410},"reduce CPU usage and resources",{"type":18,"value":93},{"type":12,"tag":20,"props":413,"children":414},{},[415,417,428],{"type":18,"value":416},"Consider 10 taps that produce 10L of water an hour. We need 100 liters altogether, so we're smart - we use 10 bottles and run all 10 taps at once. This should get us done in a minute, rather than 10 minutes. The trouble is the guy that arrived with us is also smart, and wants his 100L's worth of water too. This is the trouble with CPU work - the computer is capped at how much work it can accomplish simultaneously. To this end, \"optimizing\" your program by parallelizing its work doesn't really improve anything in terms of the amount of hard work that needs to be completed",{"type":12,"tag":122,"props":418,"children":419},{},[420],{"type":12,"tag":31,"props":421,"children":425},{"href":422,"ariaDescribedBy":423,"dataFootnoteRef":5,"id":424},"#user-content-fn-4",[129],"user-content-fnref-4",[426],{"type":18,"value":427},"4",{"type":18,"value":93},{"type":12,"tag":20,"props":430,"children":431},{},[432,434,439,441,452,454,465],{"type":18,"value":433},"In contrast, optimizing I/O bound programs can actually ",{"type":12,"tag":50,"props":435,"children":436},{},[437],{"type":18,"value":438},"reduce CPU usage",{"type":18,"value":440}," - one problem with I/O bound programs is that they needlessly waste CPU resources. In the best case scenario, we can get rid of almost all of the idle CPU time - which can be used to do more work",{"type":12,"tag":122,"props":442,"children":443},{},[444],{"type":12,"tag":31,"props":445,"children":449},{"href":446,"ariaDescribedBy":447,"dataFootnoteRef":5,"id":448},"#user-content-fn-5",[129],"user-content-fnref-5",[450],{"type":18,"value":451},"5",{"type":18,"value":453}," ",{"type":12,"tag":122,"props":455,"children":456},{},[457],{"type":12,"tag":31,"props":458,"children":462},{"href":459,"ariaDescribedBy":460,"dataFootnoteRef":5,"id":461},"#user-content-fn-6",[129],"user-content-fnref-6",[463],{"type":18,"value":464},"6",{"type":18,"value":93},{"type":12,"tag":141,"props":467,"children":469},{"id":468},"concurrency-1",[470],{"type":18,"value":7},{"type":12,"tag":20,"props":472,"children":473},{},[474,476,481],{"type":18,"value":475},"So, CPU bound tasks could use parallel computing to achieve better performance, while for I/O bound tasks we would simply try to do more work while waiting. Generally, the blanket term for any solution for both of these bounds is ",{"type":12,"tag":153,"props":477,"children":479},{"className":478},[156,157,158,159],[480],{"type":18,"value":15},{"type":18,"value":482},". This denotes programs that cannot be thought about sequentially - in order to achieve either solution, the language will now expose syntax and interfaces that, while affording us the performance benefits of concurrent code, prevent us from being able to read our programs \"line after line\". It will now be possible for different bits of our programs to execute out of order.",{"type":12,"tag":20,"props":484,"children":485},{},[486],{"type":18,"value":487},"Let's pause to list the terms we've encountered:",{"type":12,"tag":489,"props":490,"children":491},"table",{},[492,494,529,530],{"type":18,"value":493},"\n ",{"type":12,"tag":495,"props":496,"children":497},"thead",{},[498,500,512,514,528],{"type":18,"value":499},"\n ",{"type":12,"tag":501,"props":502,"children":503},"tr",{},[504,506],{"type":18,"value":505},"\n ",{"type":12,"tag":507,"props":508,"children":509},"th",{"colSpan":214},[510],{"type":18,"value":511},"Concurrency\n ",{"type":18,"value":513},"\n ",{"type":12,"tag":501,"props":515,"children":516},{},[517,518,522,523,527],{"type":18,"value":505},{"type":12,"tag":507,"props":519,"children":520},{},[521],{"type":18,"value":180},{"type":18,"value":505},{"type":12,"tag":507,"props":524,"children":525},{},[526],{"type":18,"value":167},{"type":18,"value":513},{"type":18,"value":493},{"type":18,"value":493},{"type":12,"tag":531,"props":532,"children":533},"tbody",{},[534,535,552],{"type":18,"value":513},{"type":12,"tag":501,"props":536,"children":537},{},[538,539,545,546,551],{"type":18,"value":505},{"type":12,"tag":540,"props":541,"children":542},"td",{},[543],{"type":18,"value":544},"Asynchronous Programming",{"type":18,"value":505},{"type":12,"tag":540,"props":547,"children":548},{},[549],{"type":18,"value":550},"Parallel Programming",{"type":18,"value":513},{"type":18,"value":493},{"type":12,"tag":184,"props":554,"children":556},{"id":555},"challenges-on-the-way-to-real-world-solutions",[557],{"type":18,"value":558},"Challenges on the way to real-world solutions",{"type":12,"tag":20,"props":560,"children":561},{},[562],{"type":18,"value":563},"As mentioned, different frameworks expose different interfaces to programmers for writing concurrent code. Fundamentally, there are two challenges for language designers:",{"type":12,"tag":42,"props":565,"children":566},{},[567,577],{"type":12,"tag":46,"props":568,"children":569},{},[570,575],{"type":12,"tag":50,"props":571,"children":572},{},[573],{"type":18,"value":574},"Implementation",{"type":18,"value":576}," - Developing the actual implementation(s) and mechanism(s) to allow for such code to run. This is not a trivial problem, especially if existing languages want to introduce new solutions.",{"type":12,"tag":46,"props":578,"children":579},{},[580,585],{"type":12,"tag":50,"props":581,"children":582},{},[583],{"type":18,"value":584},"Interface",{"type":18,"value":586}," - Exposing the syntax and high-level tools with which users may interact with the implementations. This is also not a trivial problem - as mentioned, thinking about concurrent code isn't straightforward. Accordingly, a good language will look for interfaces that allow for expressing concurrent code in a readable, easy-to-reason-about way.",{"type":12,"tag":20,"props":588,"children":589},{},[590,592,603,605,610,612,623],{"type":18,"value":591},"Let's give an example for a challenge on the implementation side. Cpython suffers from the ",{"type":12,"tag":153,"props":593,"children":595},{"className":594},[156,157,158,159],[596],{"type":12,"tag":31,"props":597,"children":600},{"href":598,"rel":599},"https://www.youtube.com/watch?v=KVKufdTphKs",[35],[601],{"type":18,"value":602},"GIL",{"type":18,"value":604}," - the global interpreter lock. This means that the python interpreter cannot run more than one line of python bytecode at any given time. This means that Python effectively bans parallelization (",{"type":12,"tag":50,"props":606,"children":607},{},[608],{"type":18,"value":609},"within the same process",{"type":18,"value":611}," - more on this soon), and therefore cannot improve the execution time of CPU-bound programs using concurrency",{"type":12,"tag":122,"props":613,"children":614},{},[615],{"type":12,"tag":31,"props":616,"children":620},{"href":617,"ariaDescribedBy":618,"dataFootnoteRef":5,"id":619},"#user-content-fn-7",[129],"user-content-fnref-7",[621],{"type":18,"value":622},"7",{"type":18,"value":93},{"type":12,"tag":20,"props":625,"children":626},{},[627],{"type":18,"value":628},"Let's look at another example for a challenge, this time on the interface side. Javascript, an async language by default, used to only allow running code asynchronously using callbacks functions. These functions are passed to async calls (like api requests). These callbacks will eventually run with the result of async operations and execute side effects, such as displaying the result of the request on the page. Once we register a callback, we can continue working while the resource fetches.",{"type":12,"tag":20,"props":630,"children":631},{},[632,634,645],{"type":18,"value":633},"This pattern suffered from a problem dubbed ",{"type":12,"tag":153,"props":635,"children":637},{"className":636},[156,157,158,159],[638],{"type":12,"tag":31,"props":639,"children":642},{"href":640,"rel":641},"http://callbackhell.com/",[35],[643],{"type":18,"value":644},"\"Callback Hell\"",{"type":18,"value":646},", where dependent chains of asynchronous calls, which by necessity meant nested callbacks, caused increasing right-indentation of code, until the final callback code started on the 100th column, say.",{"type":18,"value":493},{"type":12,"tag":649,"props":650,"children":651},"pre",{},[652],{"type":18,"value":653}," This\n isn't\n a\n pleasant\n read.",{"type":12,"tag":20,"props":655,"children":656},{},[657,659,666,677],{"type":18,"value":658},"Addressing this, JavaScript introduced the ",{"type":12,"tag":31,"props":660,"children":663},{"href":661,"rel":662},"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise",[35],[664],{"type":18,"value":665},"Promise API",{"type":12,"tag":122,"props":667,"children":668},{},[669],{"type":12,"tag":31,"props":670,"children":674},{"href":671,"ariaDescribedBy":672,"dataFootnoteRef":5,"id":673},"#user-content-fn-8",[129],"user-content-fnref-8",[675],{"type":18,"value":676},"8",{"type":18,"value":93},{"type":12,"tag":141,"props":679,"children":681},{"id":680},"a-taste-of-real-world-concurrency",[682],{"type":18,"value":683},"A Taste of Real-world Concurrency",{"type":12,"tag":20,"props":685,"children":686},{},[687],{"type":18,"value":688},"Let's take a cursory look at 3 basic archetypes of concurrency solutions, using a shoe factory as analogy.",{"type":12,"tag":42,"props":690,"children":691},{},[692,727,769],{"type":12,"tag":46,"props":693,"children":694},{},[695,701,703,708,710,714,716,725],{"type":12,"tag":153,"props":696,"children":698},{"className":697},[156,157,158,159],[699],{"type":18,"value":700},"Multiprocessing",{"type":18,"value":702}," - multiprocessing can reduce the execution time of ",{"type":12,"tag":50,"props":704,"children":705},{},[706],{"type":18,"value":707},"both",{"type":18,"value":709}," types of work. It involves using multiple OS processes within the same program, and coordinating between them. It is slow and very resource consuming in comparison with other concurrency solutions. If we use Python as an example, every process we spawn to run our code will, for example, contain its own running Python interpreter including the initial overhead of starting the process and the interpreter.",{"type":12,"tag":711,"props":712,"children":713},"br",{},[],{"type":18,"value":715},"Multiprocessing is analogous to building a brand new shoe factory for every order of shoes we receive, rather than using existing factories to produce multiple shoes. Every factory has an enormous initial construction overhead, it takes up a lot of real estate, and sharing resources and information between the factories is very slow.\nBack to Python: The GIL, which limits Python execution to one line at a time, only enforces its lock within the same process since every process is its own complete Python entity. This means that Python can allow real cpu parallelization using multiprocessing (refer to ",{"type":12,"tag":122,"props":717,"children":718},{},[719],{"type":12,"tag":31,"props":720,"children":723},{"href":127,"ariaDescribedBy":721,"dataFootnoteRef":5,"id":722},[129],"user-content-fnref-1-2",[724],{"type":18,"value":133},{"type":18,"value":726},")",{"type":12,"tag":46,"props":728,"children":729},{},[730,736,738,743,745,748,750,755,757,762,764,767],{"type":12,"tag":153,"props":731,"children":733},{"className":732},[156,157,158,159],[734],{"type":18,"value":735},"Multithreading",{"type":18,"value":737}," - multithreading is a tricky, widely available solution for lean concurrency with shared resources within the same process. Threads are lighter execution units than processes. Let's refer back to the factory analogy. Here, we use just the one factory (=process) to run our code. We achieve concurrency by employing many workers to perform many tasks. The workers share the factory facilities and machines, so we save big on resources. If they can work at the same time (=in parallel), we can produce more in a given time (",{"type":12,"tag":153,"props":739,"children":741},{"className":740},[156,157,158,159],[742],{"type":18,"value":167},{"type":18,"value":744}," work).",{"type":12,"tag":711,"props":746,"children":747},{},[],{"type":18,"value":749},"It is important to state that multithreading can also provide performance benefits for (",{"type":12,"tag":153,"props":751,"children":753},{"className":752},[156,157,158,159],[754],{"type":18,"value":180},{"type":18,"value":756}," work). In languages with a GIL like Python, we effectively only allow one employee to work at any given time, and we switch between them. Why is this still useful? Workers, when not idle, can schedule deliveries, start long-running processes on machines, etc. - so if our factory mostly consists of kick-starting autonomous tasks (",{"type":12,"tag":153,"props":758,"children":760},{"className":759},[156,157,158,159],[761],{"type":18,"value":180},{"type":18,"value":763}," work), multiple employees can still accomplish much more than a single employee. With the meager time each employee is given, he can start some independent task, such as scheduling a delivery. We immediately yell \"freeze!\" and transfer the working rights to another worker. He too, registers some task. When we return to the first worker, our delivery has already arrived, and our worker can program a processing machine before we freeze him again.",{"type":12,"tag":711,"props":765,"children":766},{},[],{"type":18,"value":768},"Back to reality. While multithreading is the ideal solution for CPU-bound work, it is less than ideal for I/O bound work. Even in a language that allows multi-threaded parallelism, our program still has idle CPU usage while any given thread waits for some I/O operation to complete. In addition, context switching between threads is time consuming, and as running permission is a zero-sum game, every millisecond of time given to one thread is a millisecond taken from another. So every thread is still resource consuming (though much leaner than a full process).",{"type":12,"tag":46,"props":770,"children":771},{},[772,778,780,783,785,788],{"type":12,"tag":153,"props":773,"children":775},{"className":774},[156,157,158,159],[776],{"type":18,"value":777},"Asynchronous Tasks",{"type":18,"value":779},"- This solution is relevant to I/O bound work, and can solve the wasted resource issues highlighted in the previous paragraph when using multithreading for I/O bound work. This is the final improvement to our factory, and it includes paying one of our employees more so he's willing to \"multi-task\".",{"type":12,"tag":711,"props":781,"children":782},{},[],{"type":18,"value":784},"Now, we hire a supervisor and buy a whiteboard. Our supervisor's job is to provide our employee with tasks to do when a task is completed. The worker schedules some delivery. Instead of waiting for the delivery, he first writes on the whiteboard: \"Supervisor, please let me know when the delivery has arrived for further processing\". Then he can immediately begin scheduling another delivery, or operating on deliveries from yesterday. The supervisor keeps an eye on the loading dock, and eventually the first delivery arrives. He erases the task from the whiteboard and tells the worker, who begins processing the delivery that just arrived. And so on.",{"type":12,"tag":711,"props":786,"children":787},{},[],{"type":18,"value":789},"So this solution requires a couple of components, but it can saves immensely on resources when the work is mostly I/O bound - it needs a single thread for our actual code (the worker), and some constant number of other threads and data structures to inform our thread of new tasks and keep an eye out for completed async operations (the supervisor) and keep tabs on registered tasks (the whiteboard). Our code registers some async task, and requests to be notified when it returns with the results. It notifies the framework what it wants to do with the result, but the syntax of how it is notified and the underlying objects are very framework and languages specific.",{"type":12,"tag":141,"props":791,"children":793},{"id":792},"back-to-buzzwords",[794],{"type":18,"value":795},"Back to buzzwords",{"type":12,"tag":20,"props":797,"children":798},{},[799,801,806,808,813,815,821,823,828,830,836,838,844,846,853],{"type":18,"value":800},"The only way to get ",{"type":12,"tag":153,"props":802,"children":804},{"className":803},[156,157,158,159],[805],{"type":18,"value":366},{"type":18,"value":807}," in Python - in order to reduce execution time for ",{"type":12,"tag":153,"props":809,"children":811},{"className":810},[156,157,158,159],[812],{"type":18,"value":167},{"type":18,"value":814}," programs, is ",{"type":12,"tag":153,"props":816,"children":818},{"className":817},[156,157,158,159],[819],{"type":18,"value":820},"multi-processing",{"type":18,"value":822},", because of the ",{"type":12,"tag":153,"props":824,"children":826},{"className":825},[156,157,158,159],[827],{"type":18,"value":602},{"type":18,"value":829},". This, by definition, doesn't come with shared resources like ",{"type":12,"tag":153,"props":831,"children":833},{"className":832},[156,157,158,159],[834],{"type":18,"value":835},"multi-threading",{"type":18,"value":837}," - so there's a large performance and resource penalty. This is not to say that threads have no use in Python - they may be used for reducing execution time for ",{"type":12,"tag":153,"props":839,"children":841},{"className":840},[156,157,158,159],[842],{"type":18,"value":843},"I/O bound",{"type":18,"value":845}," programs. Another Python-native alternative that can accomplish basically the same thing is the newish ",{"type":12,"tag":31,"props":847,"children":850},{"href":848,"rel":849},"https://docs.python.org/3/library/asyncio.html",[35],[851],{"type":18,"value":852},"asyncio",{"type":18,"value":854}," library, that enables asynchronous code with a single thread.",{"type":12,"tag":141,"props":856,"children":858},{"id":857},"ack",[859],{"type":18,"value":860},"Ack",{"type":12,"tag":20,"props":862,"children":863},{},[864],{"type":12,"tag":50,"props":865,"children":866},{},[867],{"type":18,"value":868},"Writing and resources about concurrency that I like:",{"type":12,"tag":42,"props":870,"children":871},{},[872,886],{"type":12,"tag":46,"props":873,"children":874},{},[875,877,884],{"type":18,"value":876},"Great ",{"type":12,"tag":31,"props":878,"children":881},{"href":879,"rel":880},"https://www.youtube.com/watch?v=lJ3NC-R3gSI",[35],[882],{"type":18,"value":883},"talk",{"type":18,"value":885}," by Steve Klabnik.",{"type":12,"tag":46,"props":887,"children":888},{},[889,890,897],{"type":18,"value":876},{"type":12,"tag":31,"props":891,"children":894},{"href":892,"rel":893},"https://eloquentjavascript.net/11_async.html",[35],[895],{"type":18,"value":896},"chapter",{"type":18,"value":898}," about async in eloquentJS, an outstanding book.",{"type":12,"tag":20,"props":900,"children":901},{},[902],{"type":12,"tag":50,"props":903,"children":904},{},[905],{"type":18,"value":906},"Friends that helped",{"type":12,"tag":42,"props":908,"children":909},{},[910,915],{"type":12,"tag":46,"props":911,"children":912},{},[913],{"type":18,"value":914},"Yoav Tzfati helped clean up my Python code",{"type":12,"tag":46,"props":916,"children":917},{},[918],{"type":18,"value":919},"Naomi Kriger and Yoav read my drafts",{"type":12,"tag":921,"props":922,"children":925},"section",{"className":923,"dataFootnotes":5},[924],"footnotes",[926,933],{"type":12,"tag":13,"props":927,"children":930},{"className":928,"id":129},[929],"sr-only",[931],{"type":18,"value":932},"Footnotes",{"type":12,"tag":42,"props":934,"children":935},{},[936,963,976,989,1009,1042,1055,1077],{"type":12,"tag":46,"props":937,"children":939},{"id":938},"user-content-fn-1",[940,942,951,952],{"type":18,"value":941},"A Python developer friend of mine offered up the following heuristic: If you find yourself reaching for multi-processing in order to incorporate parallel code execution, it's time to choose a different language for this particular task. ",{"type":12,"tag":31,"props":943,"children":948},{"href":944,"ariaLabel":945,"className":946,"dataFootnoteBackref":5},"#user-content-fnref-1","Back to reference 1",[947],"data-footnote-backref",[949],{"type":18,"value":950},"↩",{"type":18,"value":453},{"type":12,"tag":31,"props":953,"children":957},{"href":954,"ariaLabel":955,"className":956,"dataFootnoteBackref":5},"#user-content-fnref-1-2","Back to reference 1-2",[947],[958,959],{"type":18,"value":950},{"type":12,"tag":122,"props":960,"children":961},{},[962],{"type":18,"value":214},{"type":12,"tag":46,"props":964,"children":966},{"id":965},"user-content-fn-2",[967,969],{"type":18,"value":968},"For brevity, we also implicitly disregard a further step where parallelism can come in handy - some calculations may perhaps allow for non-sequential execution of certain steps. This doesn't diminish the point, though. Say we've found the most reduced version of the algorithm, split among as many units as possible. We are still left with \"hard\" work needing to be completed. So we've tried our best to reach a solution in as little time as possible - but we still need to bite the bullet of real work needing to be done. ",{"type":12,"tag":31,"props":970,"children":974},{"href":971,"ariaLabel":972,"className":973,"dataFootnoteBackref":5},"#user-content-fnref-2","Back to reference 2",[947],[975],{"type":18,"value":950},{"type":12,"tag":46,"props":977,"children":979},{"id":978},"user-content-fn-3",[980,982],{"type":18,"value":981},"Although you would be hard pressed to justify the semantics, based on needle-thin differences between the dictionary definitions of some of the above terms. ",{"type":12,"tag":31,"props":983,"children":987},{"href":984,"ariaLabel":985,"className":986,"dataFootnoteBackref":5},"#user-content-fnref-3","Back to reference 3",[947],[988],{"type":18,"value":950},{"type":12,"tag":46,"props":990,"children":992},{"id":991},"user-content-fn-4",[993,995,1000,1002],{"type":18,"value":994},"I think that for a programmer like me, who's written only consumers - programs that just consume computing power - it may be harder to understand this perspective. Once you write a provider, such as an operating system, you suddenly understand this. You own ",{"type":12,"tag":50,"props":996,"children":997},{},[998],{"type":18,"value":999},"all",{"type":18,"value":1001}," of the resources - so when you parallelize management processes you'll notice you're stepping on your own toes - all of your programs are standing in line for water. ",{"type":12,"tag":31,"props":1003,"children":1007},{"href":1004,"ariaLabel":1005,"className":1006,"dataFootnoteBackref":5},"#user-content-fnref-4","Back to reference 4",[947],[1008],{"type":18,"value":950},{"type":12,"tag":46,"props":1010,"children":1012},{"id":1011},"user-content-fn-5",[1013,1015,1020,1022,1033,1035],{"type":18,"value":1014},"We can also quantify CPU usage as energy expenditure to further illustrate the point. There is no \"free\" energy - to this end, parallelizing CPU-bound programs cannot save energy. Async code also cannot save energy - but it ",{"type":12,"tag":50,"props":1016,"children":1017},{},[1018],{"type":18,"value":1019},"can",{"type":18,"value":1021}," minimize wasting energy. A more concise (but, in reality, wrong) framing of this idea is that the ideal program is only bound by CPU usage, as a program where we've solved all I/O issues is left with only CPU usage. This program doesn't exist, except in theory. I/O includes loading the next CPU instructions and reading registers as well, for example. In addition, These are not the only two bounds a program may have, for example another extremely important bound is ",{"type":12,"tag":153,"props":1023,"children":1025},{"className":1024},[156,157,158,159],[1026],{"type":12,"tag":31,"props":1027,"children":1030},{"href":1028,"rel":1029},"https://en.wikipedia.org/wiki/Memory-bound_function",[35],[1031],{"type":18,"value":1032},"memory",{"type":18,"value":1034},", and a program is a tradeoff between all bounds. ",{"type":12,"tag":31,"props":1036,"children":1040},{"href":1037,"ariaLabel":1038,"className":1039,"dataFootnoteBackref":5},"#user-content-fnref-5","Back to reference 5",[947],[1041],{"type":18,"value":950},{"type":12,"tag":46,"props":1043,"children":1045},{"id":1044},"user-content-fn-6",[1046,1048],{"type":18,"value":1047},"A clock-cycle saved is a clock-cycle earned. This key insight, that a best case scenario asynchronous framework may reduce CPU usage, is what allows event-driven servers to serve many concurrent requests when the requests are mostly I/O bound. A new thread need not be created to serve every request - this can save an enormous amount of resources, in contrast with a thread-per-request framework which is capped by the realistic amount of threads that the server can maintain, thus severely limiting the vertical scaling of the server's possible concurrent requests. ",{"type":12,"tag":31,"props":1049,"children":1053},{"href":1050,"ariaLabel":1051,"className":1052,"dataFootnoteBackref":5},"#user-content-fnref-6","Back to reference 6",[947],[1054],{"type":18,"value":950},{"type":12,"tag":46,"props":1056,"children":1058},{"id":1057},"user-content-fn-7",[1059,1061,1068,1070],{"type":18,"value":1060},"Assuming only one line of Python bytecode is running allowed the writers of python interpreters to write simpler implementations. The trouble is, years later multi-threaded parallelization became important to many programming fields where performance is crucial. Now, existing Python implementations such as CPython are in trouble because the one-line assumption is fundamentally baked in to the underlying C and lifting the GIL as-is would break the interpreter. The ",{"type":12,"tag":31,"props":1062,"children":1065},{"href":1063,"rel":1064},"https://www.youtube.com/watch?v=B_cQ0ykux_4",[35],[1066],{"type":18,"value":1067},"\"Gilectomy\"",{"type":18,"value":1069},", an attempt to remove the GIL from CPython, is a demonstration to that effect. ",{"type":12,"tag":31,"props":1071,"children":1075},{"href":1072,"ariaLabel":1073,"className":1074,"dataFootnoteBackref":5},"#user-content-fnref-7","Back to reference 7",[947],[1076],{"type":18,"value":950},{"type":12,"tag":46,"props":1078,"children":1080},{"id":1079},"user-content-fn-8",[1081,1083,1089,1091,1098,1100],{"type":18,"value":1082},"This allows us to transform nested callbacks into a list, eliminating callback nesting. Not much later, the language introduced a syntactical wrapper for the promise API that uses the ",{"type":12,"tag":153,"props":1084,"children":1086},{"className":1085},[156,157,158,159],[1087],{"type":18,"value":1088},"await",{"type":18,"value":1090}," keyword. This is an adoption of ",{"type":12,"tag":31,"props":1092,"children":1095},{"href":1093,"rel":1094},"https://en.wikipedia.org/wiki/Async/await",[35],[1096],{"type":18,"value":1097},"syntax",{"type":18,"value":1099}," common to many languages, which enables giving asynchronous code a synchronous look, therefore arguably improving readability. ",{"type":12,"tag":31,"props":1101,"children":1105},{"href":1102,"ariaLabel":1103,"className":1104,"dataFootnoteBackref":5},"#user-content-fnref-8","Back to reference 8",[947],[1106],{"type":18,"value":950},{"title":5,"searchDepth":1108,"depth":1108,"links":1109},2,[1110,1119],{"id":15,"depth":1108,"text":7,"children":1111},[1112,1114,1115,1116,1117,1118],{"id":143,"depth":1113,"text":146},3,{"id":352,"depth":1113,"text":355},{"id":468,"depth":1113,"text":7},{"id":680,"depth":1113,"text":683},{"id":792,"depth":1113,"text":795},{"id":857,"depth":1113,"text":860},{"id":129,"depth":1108,"text":932},"markdown","content:Concurrency.md","content","Concurrency.md","md",1717319129437] \ No newline at end of file +[{"data":1,"prerenderedAt":1125},["Reactive",2],{"content-query-QonU1WAlCl":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":5,"title":7,"description":5,"body":8,"_type":1120,"_id":1121,"_source":1122,"_file":1123,"_extension":1124},"/concurrency","",false,"Concurrency",{"type":9,"children":10,"toc":1107},"root",[11,19,25,41,135,140,147,183,190,246,252,257,295,313,345,350,356,369,394,412,429,466,471,483,488,553,559,564,587,624,629,647,648,654,678,684,689,790,796,855,861,869,899,907,920],{"type":12,"tag":13,"props":14,"children":16},"element","h2",{"id":15},"concurrency",[17],{"type":18,"value":7},"text",{"type":12,"tag":20,"props":21,"children":22},"p",{},[23],{"type":18,"value":24},"This article aims to explain basic concepts related to concurrency, which is used to solve performance related problems. It starts and ends with Python (CPython, mostly), as a tie from and back into reality - but isn't really about Python at all. Actually, it isn't about any language, framework or library in particular. It aims to take a step back from questions of application and start from first principles.",{"type":12,"tag":20,"props":26,"children":27},{},[28,30,39],{"type":18,"value":29},"Let's start by stating some facts about python concurrency. They may seem contradictory or confusing - the rest of the article aims to provide more clarity as to how they make sense together. It should be noted that some of these facts pertain to a standard use of Python - it is possible to bypass some limitations, either by using a less popular Python implementation, or by using non-standard ",{"type":12,"tag":31,"props":32,"children":36},"a",{"href":33,"rel":34},"https://numba.pydata.org/",[35],"nofollow",[37],{"type":18,"value":38},"tools",{"type":18,"value":40}," and libraries.",{"type":12,"tag":42,"props":43,"children":44},"ol",{},[45,75,94,111],{"type":12,"tag":46,"props":47,"children":48},"li",{},[49,55,57,64,66,73],{"type":12,"tag":50,"props":51,"children":52},"strong",{},[53],{"type":18,"value":54},"Python has threads.",{"type":18,"value":56},"\nIf anyone says otherwise, they have important ",{"type":12,"tag":31,"props":58,"children":61},{"href":59,"rel":60},"https://docs.python.org/3/library/threading.html",[35],[62],{"type":18,"value":63},"standard",{"type":18,"value":65}," Python ",{"type":12,"tag":31,"props":67,"children":70},{"href":68,"rel":69},"https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor",[35],[71],{"type":18,"value":72},"modules",{"type":18,"value":74}," to explain away.",{"type":12,"tag":46,"props":76,"children":77},{},[78,83,85,92],{"type":12,"tag":50,"props":79,"children":80},{},[81],{"type":18,"value":82},"Python threads are useful",{"type":18,"value":84},". ",{"type":12,"tag":31,"props":86,"children":89},{"href":87,"rel":88},"https://replit.com/@NetanelHaber/pythonthreads?v=1",[35],[90],{"type":18,"value":91},"Here are numbers for you to look at",{"type":18,"value":93},".",{"type":12,"tag":46,"props":95,"children":96},{},[97,102,104,109],{"type":12,"tag":50,"props":98,"children":99},{},[100],{"type":18,"value":101},"No parallelization in python",{"type":18,"value":103},": CPython threads cannot solve ",{"type":12,"tag":50,"props":105,"children":106},{},[107],{"type":18,"value":108},"every",{"type":18,"value":110}," problem threads are put to use for in languages like C and C++.",{"type":12,"tag":46,"props":112,"children":113},{},[114,119,121,134],{"type":12,"tag":50,"props":115,"children":116},{},[117],{"type":18,"value":118},"Multi-processing can provide parallelization in Python",{"type":18,"value":120},", although in practice the performance overhead will sometimes cancel out or severely reduce the wanted benefit",{"type":12,"tag":122,"props":123,"children":124},"sup",{},[125],{"type":12,"tag":31,"props":126,"children":131},{"href":127,"ariaDescribedBy":128,"dataFootnoteRef":5,"id":130},"#user-content-fn-1",[129],"footnote-label","user-content-fnref-1",[132],{"type":18,"value":133},"1",{"type":18,"value":93},{"type":12,"tag":20,"props":136,"children":137},{},[138],{"type":18,"value":139},"So what is the rule? When is multi-threading useful? Why is Python different than some other languages?",{"type":12,"tag":141,"props":142,"children":144},"h3",{"id":143},"types-of-work",[145],{"type":18,"value":146},"Types of work",{"type":12,"tag":20,"props":148,"children":149},{},[150,152,168,170,181],{"type":18,"value":151},"Two basic concepts in this space are ",{"type":12,"tag":153,"props":154,"children":160},"span",{"className":155},[156,157,158,159],"term","cursor-default","px-1","rounded",[161],{"type":12,"tag":31,"props":162,"children":165},{"href":163,"rel":164},"https://en.wikipedia.org/wiki/CPU-bound",[35],[166],{"type":18,"value":167},"CPU-bound",{"type":18,"value":169}," and ",{"type":12,"tag":153,"props":171,"children":173},{"className":172},[156,157,158,159],[174],{"type":12,"tag":31,"props":175,"children":178},{"href":176,"rel":177},"https://en.wikipedia.org/wiki/I/O_bound",[35],[179],{"type":18,"value":180},"I/O-bound",{"type":18,"value":182}," (Input/Output) work. It helps to first state a basic fact: Computers have a fundamental bottleneck - they cannot execute more than one command at any time. Modern \"computers\" actually contain multiple computation units that can each execute one command at any given time. To compare the two types of work, we will first look at a single CPU core.",{"type":12,"tag":184,"props":185,"children":187},"h4",{"id":186},"multithreading-cpu-bound-work-on-a-single-core-the-same-work-with-extra-steps",[188],{"type":18,"value":189},"Multithreading CPU-bound work on a single core - the same work with extra steps",{"type":12,"tag":20,"props":191,"children":192},{},[193,195,202,204,215,217,223,225,231,233,239,241],{"type":18,"value":194},"If we task this computer with calculating ",{"type":12,"tag":196,"props":197,"children":199},"code",{"className":198},[],[200],{"type":18,"value":201},"(2 ^ 19) / (3 ^ 33)",{"type":18,"value":203},", it will boil the task down to a list of discreet commands to execute",{"type":12,"tag":122,"props":205,"children":206},{},[207],{"type":12,"tag":31,"props":208,"children":212},{"href":209,"ariaDescribedBy":210,"dataFootnoteRef":5,"id":211},"#user-content-fn-2",[129],"user-content-fnref-2",[213],{"type":18,"value":214},"2",{"type":18,"value":216},". This is very similar to human calculation. Say we've neared the end of a meal at a restaurant. We have two tasks ahead of us: Calculating the tip and calculating when to leave in order to catch a bus. The former calculation may penalize us ",{"type":12,"tag":196,"props":218,"children":220},{"className":219},[],[221],{"type":18,"value":222},"X",{"type":18,"value":224}," of our time, while the latter may take ",{"type":12,"tag":196,"props":226,"children":228},{"className":227},[],[229],{"type":18,"value":230},"Y",{"type":18,"value":232}," of our time. In other words, altogether ",{"type":12,"tag":196,"props":234,"children":236},{"className":235},[],[237],{"type":18,"value":238},"X+Y",{"type":18,"value":240}," work must be done. The \"brain-power\" (=time) will be spent, regardless of the way the work is divided, sliced or diced. ",{"type":12,"tag":50,"props":242,"children":243},{},[244],{"type":18,"value":245},"This is CPU-bound work.",{"type":12,"tag":184,"props":247,"children":249},{"id":248},"a-watched-pot-never-boils",[250],{"type":18,"value":251},"A watched pot never boils",{"type":12,"tag":20,"props":253,"children":254},{},[255],{"type":18,"value":256},"Now the computer is tasked with scraping Google search results. It receives a term as an argument and must retrieve the first 10 pages of results. So it:",{"type":12,"tag":42,"props":258,"children":259},{},[260,271,285],{"type":12,"tag":46,"props":261,"children":262},{},[263,265,270],{"type":18,"value":264},"Asks for the first page ",{"type":12,"tag":153,"props":266,"children":267},{},[268],{"type":18,"value":269},"10ms",{"type":18,"value":93},{"type":12,"tag":46,"props":272,"children":273},{},[274],{"type":12,"tag":50,"props":275,"children":276},{},[277,279,284],{"type":18,"value":278},"Waits for the result to return from Google servers ",{"type":12,"tag":153,"props":280,"children":281},{},[282],{"type":18,"value":283},"80ms",{"type":18,"value":93},{"type":12,"tag":46,"props":286,"children":287},{},[288,290,294],{"type":18,"value":289},"Receives the result and saves it in a file ",{"type":12,"tag":153,"props":291,"children":292},{},[293],{"type":18,"value":269},{"type":18,"value":93},{"type":12,"tag":20,"props":296,"children":297},{},[298,300,305,307,312],{"type":18,"value":299},"It then repeats these steps for all 10 pages.\nThe execution times are just an example, but resemble real-world times for similar programs. So let's focus on 2 - it seems to be our performance bottleneck, at 80% of all execution time. The key word here is ",{"type":12,"tag":50,"props":301,"children":302},{},[303],{"type":18,"value":304},"waiting",{"type":18,"value":306},". We have such a powerful tool at our disposal, and it mostly waits - i.e., does nothing, for most of our program. That's pretty unsavory. Next time you plan something with friends, try waiting for each friend to confirm before asking the next friend. ",{"type":12,"tag":50,"props":308,"children":309},{},[310],{"type":18,"value":311},"This is I/O-bound work",{"type":18,"value":93},{"type":12,"tag":20,"props":314,"children":315},{},[316,318,323,325,330,332,337,339,343],{"type":18,"value":317},"So a ",{"type":12,"tag":153,"props":319,"children":321},{"className":320},[156,157,158,159],[322],{"type":18,"value":167},{"type":18,"value":324}," task is one where the primary performance bottleneck is actual ",{"type":12,"tag":50,"props":326,"children":327},{},[328],{"type":18,"value":329},"work",{"type":18,"value":331}," that cannot be avoided. An ",{"type":12,"tag":153,"props":333,"children":335},{"className":334},[156,157,158,159],[336],{"type":18,"value":180},{"type":18,"value":338}," task is one where the primary performance bottleneck is actually just ",{"type":12,"tag":50,"props":340,"children":341},{},[342],{"type":18,"value":304},{"type":18,"value":344}," for an external piece of data.",{"type":12,"tag":20,"props":346,"children":347},{},[348],{"type":18,"value":349},"It is common sense that alleviating performance pain for problems with different bottlenecks will look different for each type of task. This is actually the key to our primary question. assessing the type of work before us - CPU, I/O or a mixture of both - can help us know in advance if certain solutions are applicable.",{"type":12,"tag":141,"props":351,"children":353},{"id":352},"enhancing-performance",[354],{"type":18,"value":355},"Enhancing Performance",{"type":12,"tag":20,"props":357,"children":358},{},[359,361,367],{"type":18,"value":360},"So for the first calculation task, we have a discreet list of commands we need to execute. Any unit can only execute one line at a time. We've already mentioned modern computers have many such units. So, for a slow program, the solution seems clear - divide and conquer. We divide our computation into smaller coherent parts (so we can assemble the solutions later for the final product), and give each available unit in the computer one part at a time to execute. For example, if we have a computation that can take 8X time, that can be divided into 8 smaller computations that each can take X time - and we have 8 cores - we can now accomplish this task in X time. This means that in order to enhance performance for CPU-bound tasks we need ",{"type":12,"tag":153,"props":362,"children":364},{"className":363},[156,157,158,159],[365],{"type":18,"value":366},"parallelization",{"type":18,"value":368}," - computing simultaneously on multiple units.",{"type":12,"tag":20,"props":370,"children":371},{},[372,374,380,382,393],{"type":18,"value":373},"The second task, where we were mostly waiting, can complete faster by being able to do other work while waiting. In the wild, you might see the term ",{"type":12,"tag":153,"props":375,"children":377},{"className":376},[156,157,158,159],[378],{"type":18,"value":379},"asynchronous",{"type":18,"value":381}," used to describe such programs that allow for doing work while waiting, depending on the language or framework. We will use this term as well",{"type":12,"tag":122,"props":383,"children":384},{},[385],{"type":12,"tag":31,"props":386,"children":390},{"href":387,"ariaDescribedBy":388,"dataFootnoteRef":5,"id":389},"#user-content-fn-3",[129],"user-content-fnref-3",[391],{"type":18,"value":392},"3",{"type":18,"value":93},{"type":12,"tag":20,"props":395,"children":396},{},[397,399,404,406,411],{"type":18,"value":398},"On a side note, let's notice a subtle difference between the enhancements we may gain from optimizing both types of work. While both parallelization and asynchronous solutions can ",{"type":12,"tag":50,"props":400,"children":401},{},[402],{"type":18,"value":403},"save on overall execution time",{"type":18,"value":405},", they cannot both ",{"type":12,"tag":50,"props":407,"children":408},{},[409],{"type":18,"value":410},"reduce CPU usage and resources",{"type":18,"value":93},{"type":12,"tag":20,"props":413,"children":414},{},[415,417,428],{"type":18,"value":416},"Consider 10 taps that produce 10L of water an hour. We need 100 liters altogether, so we're smart - we use 10 bottles and run all 10 taps at once. This should get us done in a minute, rather than 10 minutes. The trouble is the guy that arrived with us is also smart, and wants his 100L's worth of water too. This is the trouble with CPU work - the computer is capped at how much work it can accomplish simultaneously. To this end, \"optimizing\" your program by parallelizing its work doesn't really improve anything in terms of the amount of hard work that needs to be completed",{"type":12,"tag":122,"props":418,"children":419},{},[420],{"type":12,"tag":31,"props":421,"children":425},{"href":422,"ariaDescribedBy":423,"dataFootnoteRef":5,"id":424},"#user-content-fn-4",[129],"user-content-fnref-4",[426],{"type":18,"value":427},"4",{"type":18,"value":93},{"type":12,"tag":20,"props":430,"children":431},{},[432,434,439,441,452,454,465],{"type":18,"value":433},"In contrast, optimizing I/O bound programs can actually ",{"type":12,"tag":50,"props":435,"children":436},{},[437],{"type":18,"value":438},"reduce CPU usage",{"type":18,"value":440}," - one problem with I/O bound programs is that they needlessly waste CPU resources. In the best case scenario, we can get rid of almost all of the idle CPU time - which can be used to do more work",{"type":12,"tag":122,"props":442,"children":443},{},[444],{"type":12,"tag":31,"props":445,"children":449},{"href":446,"ariaDescribedBy":447,"dataFootnoteRef":5,"id":448},"#user-content-fn-5",[129],"user-content-fnref-5",[450],{"type":18,"value":451},"5",{"type":18,"value":453}," ",{"type":12,"tag":122,"props":455,"children":456},{},[457],{"type":12,"tag":31,"props":458,"children":462},{"href":459,"ariaDescribedBy":460,"dataFootnoteRef":5,"id":461},"#user-content-fn-6",[129],"user-content-fnref-6",[463],{"type":18,"value":464},"6",{"type":18,"value":93},{"type":12,"tag":141,"props":467,"children":469},{"id":468},"concurrency-1",[470],{"type":18,"value":7},{"type":12,"tag":20,"props":472,"children":473},{},[474,476,481],{"type":18,"value":475},"So, CPU bound tasks could use parallel computing to achieve better performance, while for I/O bound tasks we would simply try to do more work while waiting. Generally, the blanket term for any solution for both of these bounds is ",{"type":12,"tag":153,"props":477,"children":479},{"className":478},[156,157,158,159],[480],{"type":18,"value":15},{"type":18,"value":482},". This denotes programs that cannot be thought about sequentially - in order to achieve either solution, the language will now expose syntax and interfaces that, while affording us the performance benefits of concurrent code, prevent us from being able to read our programs \"line after line\". It will now be possible for different bits of our programs to execute out of order.",{"type":12,"tag":20,"props":484,"children":485},{},[486],{"type":18,"value":487},"Let's pause to list the terms we've encountered:",{"type":12,"tag":489,"props":490,"children":491},"table",{},[492,494,529,530],{"type":18,"value":493},"\n ",{"type":12,"tag":495,"props":496,"children":497},"thead",{},[498,500,512,514,528],{"type":18,"value":499},"\n ",{"type":12,"tag":501,"props":502,"children":503},"tr",{},[504,506],{"type":18,"value":505},"\n ",{"type":12,"tag":507,"props":508,"children":509},"th",{"colSpan":214},[510],{"type":18,"value":511},"Concurrency\n ",{"type":18,"value":513},"\n ",{"type":12,"tag":501,"props":515,"children":516},{},[517,518,522,523,527],{"type":18,"value":505},{"type":12,"tag":507,"props":519,"children":520},{},[521],{"type":18,"value":180},{"type":18,"value":505},{"type":12,"tag":507,"props":524,"children":525},{},[526],{"type":18,"value":167},{"type":18,"value":513},{"type":18,"value":493},{"type":18,"value":493},{"type":12,"tag":531,"props":532,"children":533},"tbody",{},[534,535,552],{"type":18,"value":513},{"type":12,"tag":501,"props":536,"children":537},{},[538,539,545,546,551],{"type":18,"value":505},{"type":12,"tag":540,"props":541,"children":542},"td",{},[543],{"type":18,"value":544},"Asynchronous Programming",{"type":18,"value":505},{"type":12,"tag":540,"props":547,"children":548},{},[549],{"type":18,"value":550},"Parallel Programming",{"type":18,"value":513},{"type":18,"value":493},{"type":12,"tag":184,"props":554,"children":556},{"id":555},"challenges-on-the-way-to-real-world-solutions",[557],{"type":18,"value":558},"Challenges on the way to real-world solutions",{"type":12,"tag":20,"props":560,"children":561},{},[562],{"type":18,"value":563},"As mentioned, different frameworks expose different interfaces to programmers for writing concurrent code. Fundamentally, there are two challenges for language designers:",{"type":12,"tag":42,"props":565,"children":566},{},[567,577],{"type":12,"tag":46,"props":568,"children":569},{},[570,575],{"type":12,"tag":50,"props":571,"children":572},{},[573],{"type":18,"value":574},"Implementation",{"type":18,"value":576}," - Developing the actual implementation(s) and mechanism(s) to allow for such code to run. This is not a trivial problem, especially if existing languages want to introduce new solutions.",{"type":12,"tag":46,"props":578,"children":579},{},[580,585],{"type":12,"tag":50,"props":581,"children":582},{},[583],{"type":18,"value":584},"Interface",{"type":18,"value":586}," - Exposing the syntax and high-level tools with which users may interact with the implementations. This is also not a trivial problem - as mentioned, thinking about concurrent code isn't straightforward. Accordingly, a good language will look for interfaces that allow for expressing concurrent code in a readable, easy-to-reason-about way.",{"type":12,"tag":20,"props":588,"children":589},{},[590,592,603,605,610,612,623],{"type":18,"value":591},"Let's give an example for a challenge on the implementation side. Cpython suffers from the ",{"type":12,"tag":153,"props":593,"children":595},{"className":594},[156,157,158,159],[596],{"type":12,"tag":31,"props":597,"children":600},{"href":598,"rel":599},"https://www.youtube.com/watch?v=KVKufdTphKs",[35],[601],{"type":18,"value":602},"GIL",{"type":18,"value":604}," - the global interpreter lock. This means that the python interpreter cannot run more than one line of python bytecode at any given time. This means that Python effectively bans parallelization (",{"type":12,"tag":50,"props":606,"children":607},{},[608],{"type":18,"value":609},"within the same process",{"type":18,"value":611}," - more on this soon), and therefore cannot improve the execution time of CPU-bound programs using concurrency",{"type":12,"tag":122,"props":613,"children":614},{},[615],{"type":12,"tag":31,"props":616,"children":620},{"href":617,"ariaDescribedBy":618,"dataFootnoteRef":5,"id":619},"#user-content-fn-7",[129],"user-content-fnref-7",[621],{"type":18,"value":622},"7",{"type":18,"value":93},{"type":12,"tag":20,"props":625,"children":626},{},[627],{"type":18,"value":628},"Let's look at another example for a challenge, this time on the interface side. Javascript, an async language by default, used to only allow running code asynchronously using callbacks functions. These functions are passed to async calls (like api requests). These callbacks will eventually run with the result of async operations and execute side effects, such as displaying the result of the request on the page. Once we register a callback, we can continue working while the resource fetches.",{"type":12,"tag":20,"props":630,"children":631},{},[632,634,645],{"type":18,"value":633},"This pattern suffered from a problem dubbed ",{"type":12,"tag":153,"props":635,"children":637},{"className":636},[156,157,158,159],[638],{"type":12,"tag":31,"props":639,"children":642},{"href":640,"rel":641},"http://callbackhell.com/",[35],[643],{"type":18,"value":644},"\"Callback Hell\"",{"type":18,"value":646},", where dependent chains of asynchronous calls, which by necessity meant nested callbacks, caused increasing right-indentation of code, until the final callback code started on the 100th column, say.",{"type":18,"value":493},{"type":12,"tag":649,"props":650,"children":651},"pre",{},[652],{"type":18,"value":653}," This\n isn't\n a\n pleasant\n read.",{"type":12,"tag":20,"props":655,"children":656},{},[657,659,666,677],{"type":18,"value":658},"Addressing this, JavaScript introduced the ",{"type":12,"tag":31,"props":660,"children":663},{"href":661,"rel":662},"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise",[35],[664],{"type":18,"value":665},"Promise API",{"type":12,"tag":122,"props":667,"children":668},{},[669],{"type":12,"tag":31,"props":670,"children":674},{"href":671,"ariaDescribedBy":672,"dataFootnoteRef":5,"id":673},"#user-content-fn-8",[129],"user-content-fnref-8",[675],{"type":18,"value":676},"8",{"type":18,"value":93},{"type":12,"tag":141,"props":679,"children":681},{"id":680},"a-taste-of-real-world-concurrency",[682],{"type":18,"value":683},"A Taste of Real-world Concurrency",{"type":12,"tag":20,"props":685,"children":686},{},[687],{"type":18,"value":688},"Let's take a cursory look at 3 basic archetypes of concurrency solutions, using a shoe factory as analogy.",{"type":12,"tag":42,"props":690,"children":691},{},[692,727,769],{"type":12,"tag":46,"props":693,"children":694},{},[695,701,703,708,710,714,716,725],{"type":12,"tag":153,"props":696,"children":698},{"className":697},[156,157,158,159],[699],{"type":18,"value":700},"Multiprocessing",{"type":18,"value":702}," - multiprocessing can reduce the execution time of ",{"type":12,"tag":50,"props":704,"children":705},{},[706],{"type":18,"value":707},"both",{"type":18,"value":709}," types of work. It involves using multiple OS processes within the same program, and coordinating between them. It is slow and very resource consuming in comparison with other concurrency solutions. If we use Python as an example, every process we spawn to run our code will, for example, contain its own running Python interpreter including the initial overhead of starting the process and the interpreter.",{"type":12,"tag":711,"props":712,"children":713},"br",{},[],{"type":18,"value":715},"Multiprocessing is analogous to building a brand new shoe factory for every order of shoes we receive, rather than using existing factories to produce multiple shoes. Every factory has an enormous initial construction overhead, it takes up a lot of real estate, and sharing resources and information between the factories is very slow.\nBack to Python: The GIL, which limits Python execution to one line at a time, only enforces its lock within the same process since every process is its own complete Python entity. This means that Python can allow real cpu parallelization using multiprocessing (refer to ",{"type":12,"tag":122,"props":717,"children":718},{},[719],{"type":12,"tag":31,"props":720,"children":723},{"href":127,"ariaDescribedBy":721,"dataFootnoteRef":5,"id":722},[129],"user-content-fnref-1-2",[724],{"type":18,"value":133},{"type":18,"value":726},")",{"type":12,"tag":46,"props":728,"children":729},{},[730,736,738,743,745,748,750,755,757,762,764,767],{"type":12,"tag":153,"props":731,"children":733},{"className":732},[156,157,158,159],[734],{"type":18,"value":735},"Multithreading",{"type":18,"value":737}," - multithreading is a tricky, widely available solution for lean concurrency with shared resources within the same process. Threads are lighter execution units than processes. Let's refer back to the factory analogy. Here, we use just the one factory (=process) to run our code. We achieve concurrency by employing many workers to perform many tasks. The workers share the factory facilities and machines, so we save big on resources. If they can work at the same time (=in parallel), we can produce more in a given time (",{"type":12,"tag":153,"props":739,"children":741},{"className":740},[156,157,158,159],[742],{"type":18,"value":167},{"type":18,"value":744}," work).",{"type":12,"tag":711,"props":746,"children":747},{},[],{"type":18,"value":749},"It is important to state that multithreading can also provide performance benefits for (",{"type":12,"tag":153,"props":751,"children":753},{"className":752},[156,157,158,159],[754],{"type":18,"value":180},{"type":18,"value":756}," work). In languages with a GIL like Python, we effectively only allow one employee to work at any given time, and we switch between them. Why is this still useful? Workers, when not idle, can schedule deliveries, start long-running processes on machines, etc. - so if our factory mostly consists of kick-starting autonomous tasks (",{"type":12,"tag":153,"props":758,"children":760},{"className":759},[156,157,158,159],[761],{"type":18,"value":180},{"type":18,"value":763}," work), multiple employees can still accomplish much more than a single employee. With the meager time each employee is given, he can start some independent task, such as scheduling a delivery. We immediately yell \"freeze!\" and transfer the working rights to another worker. He too, registers some task. When we return to the first worker, our delivery has already arrived, and our worker can program a processing machine before we freeze him again.",{"type":12,"tag":711,"props":765,"children":766},{},[],{"type":18,"value":768},"Back to reality. While multithreading is the ideal solution for CPU-bound work, it is less than ideal for I/O bound work. Even in a language that allows multi-threaded parallelism, our program still has idle CPU usage while any given thread waits for some I/O operation to complete. In addition, context switching between threads is time consuming, and as running permission is a zero-sum game, every millisecond of time given to one thread is a millisecond taken from another. So every thread is still resource consuming (though much leaner than a full process).",{"type":12,"tag":46,"props":770,"children":771},{},[772,778,780,783,785,788],{"type":12,"tag":153,"props":773,"children":775},{"className":774},[156,157,158,159],[776],{"type":18,"value":777},"Asynchronous Tasks",{"type":18,"value":779},"- This solution is relevant to I/O bound work, and can solve the wasted resource issues highlighted in the previous paragraph when using multithreading for I/O bound work. This is the final improvement to our factory, and it includes paying one of our employees more so he's willing to \"multi-task\".",{"type":12,"tag":711,"props":781,"children":782},{},[],{"type":18,"value":784},"Now, we hire a supervisor and buy a whiteboard. Our supervisor's job is to provide our employee with tasks to do when a task is completed. The worker schedules some delivery. Instead of waiting for the delivery, he first writes on the whiteboard: \"Supervisor, please let me know when the delivery has arrived for further processing\". Then he can immediately begin scheduling another delivery, or operating on deliveries from yesterday. The supervisor keeps an eye on the loading dock, and eventually the first delivery arrives. He erases the task from the whiteboard and tells the worker, who begins processing the delivery that just arrived. And so on.",{"type":12,"tag":711,"props":786,"children":787},{},[],{"type":18,"value":789},"So this solution requires a couple of components, but it can saves immensely on resources when the work is mostly I/O bound - it needs a single thread for our actual code (the worker), and some constant number of other threads and data structures to inform our thread of new tasks and keep an eye out for completed async operations (the supervisor) and keep tabs on registered tasks (the whiteboard). Our code registers some async task, and requests to be notified when it returns with the results. It notifies the framework what it wants to do with the result, but the syntax of how it is notified and the underlying objects are very framework and languages specific.",{"type":12,"tag":141,"props":791,"children":793},{"id":792},"back-to-buzzwords",[794],{"type":18,"value":795},"Back to buzzwords",{"type":12,"tag":20,"props":797,"children":798},{},[799,801,806,808,813,815,821,823,828,830,836,838,844,846,853],{"type":18,"value":800},"The only way to get ",{"type":12,"tag":153,"props":802,"children":804},{"className":803},[156,157,158,159],[805],{"type":18,"value":366},{"type":18,"value":807}," in Python - in order to reduce execution time for ",{"type":12,"tag":153,"props":809,"children":811},{"className":810},[156,157,158,159],[812],{"type":18,"value":167},{"type":18,"value":814}," programs, is ",{"type":12,"tag":153,"props":816,"children":818},{"className":817},[156,157,158,159],[819],{"type":18,"value":820},"multi-processing",{"type":18,"value":822},", because of the ",{"type":12,"tag":153,"props":824,"children":826},{"className":825},[156,157,158,159],[827],{"type":18,"value":602},{"type":18,"value":829},". This, by definition, doesn't come with shared resources like ",{"type":12,"tag":153,"props":831,"children":833},{"className":832},[156,157,158,159],[834],{"type":18,"value":835},"multi-threading",{"type":18,"value":837}," - so there's a large performance and resource penalty. This is not to say that threads have no use in Python - they may be used for reducing execution time for ",{"type":12,"tag":153,"props":839,"children":841},{"className":840},[156,157,158,159],[842],{"type":18,"value":843},"I/O bound",{"type":18,"value":845}," programs. Another Python-native alternative that can accomplish basically the same thing is the newish ",{"type":12,"tag":31,"props":847,"children":850},{"href":848,"rel":849},"https://docs.python.org/3/library/asyncio.html",[35],[851],{"type":18,"value":852},"asyncio",{"type":18,"value":854}," library, that enables asynchronous code with a single thread.",{"type":12,"tag":141,"props":856,"children":858},{"id":857},"ack",[859],{"type":18,"value":860},"Ack",{"type":12,"tag":20,"props":862,"children":863},{},[864],{"type":12,"tag":50,"props":865,"children":866},{},[867],{"type":18,"value":868},"Writing and resources about concurrency that I like:",{"type":12,"tag":42,"props":870,"children":871},{},[872,886],{"type":12,"tag":46,"props":873,"children":874},{},[875,877,884],{"type":18,"value":876},"Great ",{"type":12,"tag":31,"props":878,"children":881},{"href":879,"rel":880},"https://www.youtube.com/watch?v=lJ3NC-R3gSI",[35],[882],{"type":18,"value":883},"talk",{"type":18,"value":885}," by Steve Klabnik.",{"type":12,"tag":46,"props":887,"children":888},{},[889,890,897],{"type":18,"value":876},{"type":12,"tag":31,"props":891,"children":894},{"href":892,"rel":893},"https://eloquentjavascript.net/11_async.html",[35],[895],{"type":18,"value":896},"chapter",{"type":18,"value":898}," about async in eloquentJS, an outstanding book.",{"type":12,"tag":20,"props":900,"children":901},{},[902],{"type":12,"tag":50,"props":903,"children":904},{},[905],{"type":18,"value":906},"Friends that helped",{"type":12,"tag":42,"props":908,"children":909},{},[910,915],{"type":12,"tag":46,"props":911,"children":912},{},[913],{"type":18,"value":914},"Yoav Tzfati helped clean up my Python code",{"type":12,"tag":46,"props":916,"children":917},{},[918],{"type":18,"value":919},"Naomi Kriger and Yoav read my drafts",{"type":12,"tag":921,"props":922,"children":925},"section",{"className":923,"dataFootnotes":5},[924],"footnotes",[926,933],{"type":12,"tag":13,"props":927,"children":930},{"className":928,"id":129},[929],"sr-only",[931],{"type":18,"value":932},"Footnotes",{"type":12,"tag":42,"props":934,"children":935},{},[936,963,976,989,1009,1042,1055,1077],{"type":12,"tag":46,"props":937,"children":939},{"id":938},"user-content-fn-1",[940,942,951,952],{"type":18,"value":941},"A Python developer friend of mine offered up the following heuristic: If you find yourself reaching for multi-processing in order to incorporate parallel code execution, it's time to choose a different language for this particular task. ",{"type":12,"tag":31,"props":943,"children":948},{"href":944,"ariaLabel":945,"className":946,"dataFootnoteBackref":5},"#user-content-fnref-1","Back to reference 1",[947],"data-footnote-backref",[949],{"type":18,"value":950},"↩",{"type":18,"value":453},{"type":12,"tag":31,"props":953,"children":957},{"href":954,"ariaLabel":955,"className":956,"dataFootnoteBackref":5},"#user-content-fnref-1-2","Back to reference 1-2",[947],[958,959],{"type":18,"value":950},{"type":12,"tag":122,"props":960,"children":961},{},[962],{"type":18,"value":214},{"type":12,"tag":46,"props":964,"children":966},{"id":965},"user-content-fn-2",[967,969],{"type":18,"value":968},"For brevity, we also implicitly disregard a further step where parallelism can come in handy - some calculations may perhaps allow for non-sequential execution of certain steps. This doesn't diminish the point, though. Say we've found the most reduced version of the algorithm, split among as many units as possible. We are still left with \"hard\" work needing to be completed. So we've tried our best to reach a solution in as little time as possible - but we still need to bite the bullet of real work needing to be done. ",{"type":12,"tag":31,"props":970,"children":974},{"href":971,"ariaLabel":972,"className":973,"dataFootnoteBackref":5},"#user-content-fnref-2","Back to reference 2",[947],[975],{"type":18,"value":950},{"type":12,"tag":46,"props":977,"children":979},{"id":978},"user-content-fn-3",[980,982],{"type":18,"value":981},"Although you would be hard pressed to justify the semantics, based on needle-thin differences between the dictionary definitions of some of the above terms. ",{"type":12,"tag":31,"props":983,"children":987},{"href":984,"ariaLabel":985,"className":986,"dataFootnoteBackref":5},"#user-content-fnref-3","Back to reference 3",[947],[988],{"type":18,"value":950},{"type":12,"tag":46,"props":990,"children":992},{"id":991},"user-content-fn-4",[993,995,1000,1002],{"type":18,"value":994},"I think that for a programmer like me, who's written only consumers - programs that just consume computing power - it may be harder to understand this perspective. Once you write a provider, such as an operating system, you suddenly understand this. You own ",{"type":12,"tag":50,"props":996,"children":997},{},[998],{"type":18,"value":999},"all",{"type":18,"value":1001}," of the resources - so when you parallelize management processes you'll notice you're stepping on your own toes - all of your programs are standing in line for water. ",{"type":12,"tag":31,"props":1003,"children":1007},{"href":1004,"ariaLabel":1005,"className":1006,"dataFootnoteBackref":5},"#user-content-fnref-4","Back to reference 4",[947],[1008],{"type":18,"value":950},{"type":12,"tag":46,"props":1010,"children":1012},{"id":1011},"user-content-fn-5",[1013,1015,1020,1022,1033,1035],{"type":18,"value":1014},"We can also quantify CPU usage as energy expenditure to further illustrate the point. There is no \"free\" energy - to this end, parallelizing CPU-bound programs cannot save energy. Async code also cannot save energy - but it ",{"type":12,"tag":50,"props":1016,"children":1017},{},[1018],{"type":18,"value":1019},"can",{"type":18,"value":1021}," minimize wasting energy. A more concise (but, in reality, wrong) framing of this idea is that the ideal program is only bound by CPU usage, as a program where we've solved all I/O issues is left with only CPU usage. This program doesn't exist, except in theory. I/O includes loading the next CPU instructions and reading registers as well, for example. In addition, These are not the only two bounds a program may have, for example another extremely important bound is ",{"type":12,"tag":153,"props":1023,"children":1025},{"className":1024},[156,157,158,159],[1026],{"type":12,"tag":31,"props":1027,"children":1030},{"href":1028,"rel":1029},"https://en.wikipedia.org/wiki/Memory-bound_function",[35],[1031],{"type":18,"value":1032},"memory",{"type":18,"value":1034},", and a program is a tradeoff between all bounds. ",{"type":12,"tag":31,"props":1036,"children":1040},{"href":1037,"ariaLabel":1038,"className":1039,"dataFootnoteBackref":5},"#user-content-fnref-5","Back to reference 5",[947],[1041],{"type":18,"value":950},{"type":12,"tag":46,"props":1043,"children":1045},{"id":1044},"user-content-fn-6",[1046,1048],{"type":18,"value":1047},"A clock-cycle saved is a clock-cycle earned. This key insight, that a best case scenario asynchronous framework may reduce CPU usage, is what allows event-driven servers to serve many concurrent requests when the requests are mostly I/O bound. A new thread need not be created to serve every request - this can save an enormous amount of resources, in contrast with a thread-per-request framework which is capped by the realistic amount of threads that the server can maintain, thus severely limiting the vertical scaling of the server's possible concurrent requests. ",{"type":12,"tag":31,"props":1049,"children":1053},{"href":1050,"ariaLabel":1051,"className":1052,"dataFootnoteBackref":5},"#user-content-fnref-6","Back to reference 6",[947],[1054],{"type":18,"value":950},{"type":12,"tag":46,"props":1056,"children":1058},{"id":1057},"user-content-fn-7",[1059,1061,1068,1070],{"type":18,"value":1060},"Assuming only one line of Python bytecode is running allowed the writers of python interpreters to write simpler implementations. The trouble is, years later multi-threaded parallelization became important to many programming fields where performance is crucial. Now, existing Python implementations such as CPython are in trouble because the one-line assumption is fundamentally baked in to the underlying C and lifting the GIL as-is would break the interpreter. The ",{"type":12,"tag":31,"props":1062,"children":1065},{"href":1063,"rel":1064},"https://www.youtube.com/watch?v=B_cQ0ykux_4",[35],[1066],{"type":18,"value":1067},"\"Gilectomy\"",{"type":18,"value":1069},", an attempt to remove the GIL from CPython, is a demonstration to that effect. ",{"type":12,"tag":31,"props":1071,"children":1075},{"href":1072,"ariaLabel":1073,"className":1074,"dataFootnoteBackref":5},"#user-content-fnref-7","Back to reference 7",[947],[1076],{"type":18,"value":950},{"type":12,"tag":46,"props":1078,"children":1080},{"id":1079},"user-content-fn-8",[1081,1083,1089,1091,1098,1100],{"type":18,"value":1082},"This allows us to transform nested callbacks into a list, eliminating callback nesting. Not much later, the language introduced a syntactical wrapper for the promise API that uses the ",{"type":12,"tag":153,"props":1084,"children":1086},{"className":1085},[156,157,158,159],[1087],{"type":18,"value":1088},"await",{"type":18,"value":1090}," keyword. This is an adoption of ",{"type":12,"tag":31,"props":1092,"children":1095},{"href":1093,"rel":1094},"https://en.wikipedia.org/wiki/Async/await",[35],[1096],{"type":18,"value":1097},"syntax",{"type":18,"value":1099}," common to many languages, which enables giving asynchronous code a synchronous look, therefore arguably improving readability. ",{"type":12,"tag":31,"props":1101,"children":1105},{"href":1102,"ariaLabel":1103,"className":1104,"dataFootnoteBackref":5},"#user-content-fnref-8","Back to reference 8",[947],[1106],{"type":18,"value":950},{"title":5,"searchDepth":1108,"depth":1108,"links":1109},2,[1110,1119],{"id":15,"depth":1108,"text":7,"children":1111},[1112,1114,1115,1116,1117,1118],{"id":143,"depth":1113,"text":146},3,{"id":352,"depth":1113,"text":355},{"id":468,"depth":1113,"text":7},{"id":680,"depth":1113,"text":683},{"id":792,"depth":1113,"text":795},{"id":857,"depth":1113,"text":860},{"id":129,"depth":1108,"text":932},"markdown","content:Concurrency.md","content","Concurrency.md","md",1717319595049] \ No newline at end of file diff --git a/concurrency/index.html b/concurrency/index.html index bdb067a..a692639 100644 --- a/concurrency/index.html +++ b/concurrency/index.html @@ -8,39 +8,39 @@ - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - -

Concurrency

This article aims to explain basic concepts related to concurrency, which is used to solve performance related problems. It starts and ends with Python (CPython, mostly), as a tie from and back into reality - but isn't really about Python at all. Actually, it isn't about any language, framework or library in particular. It aims to take a step back from questions of application and start from first principles.

Let's start by stating some facts about python concurrency. They may seem contradictory or confusing - the rest of the article aims to provide more clarity as to how they make sense together. It should be noted that some of these facts pertain to a standard use of Python - it is possible to bypass some limitations, either by using a less popular Python implementation, or by using non-standard tools and libraries.

  1. Python has threads. + + +

    Concurrency

    This article aims to explain basic concepts related to concurrency, which is used to solve performance related problems. It starts and ends with Python (CPython, mostly), as a tie from and back into reality - but isn't really about Python at all. Actually, it isn't about any language, framework or library in particular. It aims to take a step back from questions of application and start from first principles.

    Let's start by stating some facts about python concurrency. They may seem contradictory or confusing - the rest of the article aims to provide more clarity as to how they make sense together. It should be noted that some of these facts pertain to a standard use of Python - it is possible to bypass some limitations, either by using a less popular Python implementation, or by using non-standard tools and libraries.

    1. Python has threads. If anyone says otherwise, they have important standard Python modules to explain away.
    2. Python threads are useful. Here are numbers for you to look at.
    3. No parallelization in python: CPython threads cannot solve every problem threads are put to use for in languages like C and C++.
    4. Multi-processing can provide parallelization in Python, although in practice the performance overhead will sometimes cancel out or severely reduce the wanted benefit1.

    So what is the rule? When is multi-threading useful? Why is Python different than some other languages?

    Types of work

    Two basic concepts in this space are CPU-bound and I/O-bound (Input/Output) work. It helps to first state a basic fact: Computers have a fundamental bottleneck - they cannot execute more than one command at any time. Modern "computers" actually contain multiple computation units that can each execute one command at any given time. To compare the two types of work, we will first look at a single CPU core.

    Multithreading CPU-bound work on a single core - the same work with extra steps

    If we task this computer with calculating (2 ^ 19) / (3 ^ 33), it will boil the task down to a list of discreet commands to execute2. This is very similar to human calculation. Say we've neared the end of a meal at a restaurant. We have two tasks ahead of us: Calculating the tip and calculating when to leave in order to catch a bus. The former calculation may penalize us X of our time, while the latter may take Y of our time. In other words, altogether X+Y work must be done. The "brain-power" (=time) will be spent, regardless of the way the work is divided, sliced or diced. This is CPU-bound work.

    A watched pot never boils

    Now the computer is tasked with scraping Google search results. It receives a term as an argument and must retrieve the first 10 pages of results. So it:

    1. Asks for the first page 10ms.
    2. Waits for the result to return from Google servers 80ms.
    3. Receives the result and saves it in a file 10ms.

    It then repeats these steps for all 10 pages. The execution times are just an example, but resemble real-world times for similar programs. So let's focus on 2 - it seems to be our performance bottleneck, at 80% of all execution time. The key word here is waiting. We have such a powerful tool at our disposal, and it mostly waits - i.e., does nothing, for most of our program. That's pretty unsavory. Next time you plan something with friends, try waiting for each friend to confirm before asking the next friend. This is I/O-bound work.

    So a CPU-bound task is one where the primary performance bottleneck is actual work that cannot be avoided. An I/O-bound task is one where the primary performance bottleneck is actually just waiting for an external piece of data.

    It is common sense that alleviating performance pain for problems with different bottlenecks will look different for each type of task. This is actually the key to our primary question. assessing the type of work before us - CPU, I/O or a mixture of both - can help us know in advance if certain solutions are applicable.

    Enhancing Performance

    So for the first calculation task, we have a discreet list of commands we need to execute. Any unit can only execute one line at a time. We've already mentioned modern computers have many such units. So, for a slow program, the solution seems clear - divide and conquer. We divide our computation into smaller coherent parts (so we can assemble the solutions later for the final product), and give each available unit in the computer one part at a time to execute. For example, if we have a computation that can take 8X time, that can be divided into 8 smaller computations that each can take X time - and we have 8 cores - we can now accomplish this task in X time. This means that in order to enhance performance for CPU-bound tasks we need parallelization - computing simultaneously on multiple units.

    The second task, where we were mostly waiting, can complete faster by being able to do other work while waiting. In the wild, you might see the term asynchronous used to describe such programs that allow for doing work while waiting, depending on the language or framework. We will use this term as well3.

    On a side note, let's notice a subtle difference between the enhancements we may gain from optimizing both types of work. While both parallelization and asynchronous solutions can save on overall execution time, they cannot both reduce CPU usage and resources.

    Consider 10 taps that produce 10L of water an hour. We need 100 liters altogether, so we're smart - we use 10 bottles and run all 10 taps at once. This should get us done in a minute, rather than 10 minutes. The trouble is the guy that arrived with us is also smart, and wants his 100L's worth of water too. This is the trouble with CPU work - the computer is capped at how much work it can accomplish simultaneously. To this end, "optimizing" your program by parallelizing its work doesn't really improve anything in terms of the amount of hard work that needs to be completed4.

    In contrast, optimizing I/O bound programs can actually reduce CPU usage - one problem with I/O bound programs is that they needlessly waste CPU resources. In the best case scenario, we can get rid of almost all of the idle CPU time - which can be used to do more work5 6.

    Concurrency

    So, CPU bound tasks could use parallel computing to achieve better performance, while for I/O bound tasks we would simply try to do more work while waiting. Generally, the blanket term for any solution for both of these bounds is concurrency. This denotes programs that cannot be thought about sequentially - in order to achieve either solution, the language will now expose syntax and interfaces that, while affording us the performance benefits of concurrent code, prevent us from being able to read our programs "line after line". It will now be possible for different bits of our programs to execute out of order.

    Let's pause to list the terms we've encountered:

    @@ -63,5 +63,5 @@ a pleasant read.

    Addressing this, JavaScript introduced the Promise API8.

    A Taste of Real-world Concurrency

    Let's take a cursory look at 3 basic archetypes of concurrency solutions, using a shoe factory as analogy.

    1. Multiprocessing - multiprocessing can reduce the execution time of both types of work. It involves using multiple OS processes within the same program, and coordinating between them. It is slow and very resource consuming in comparison with other concurrency solutions. If we use Python as an example, every process we spawn to run our code will, for example, contain its own running Python interpreter including the initial overhead of starting the process and the interpreter.
      Multiprocessing is analogous to building a brand new shoe factory for every order of shoes we receive, rather than using existing factories to produce multiple shoes. Every factory has an enormous initial construction overhead, it takes up a lot of real estate, and sharing resources and information between the factories is very slow. -Back to Python: The GIL, which limits Python execution to one line at a time, only enforces its lock within the same process since every process is its own complete Python entity. This means that Python can allow real cpu parallelization using multiprocessing (refer to 1)
    2. Multithreading - multithreading is a tricky, widely available solution for lean concurrency with shared resources within the same process. Threads are lighter execution units than processes. Let's refer back to the factory analogy. Here, we use just the one factory (=process) to run our code. We achieve concurrency by employing many workers to perform many tasks. The workers share the factory facilities and machines, so we save big on resources. If they can work at the same time (=in parallel), we can produce more in a given time (CPU-bound work).
      It is important to state that multithreading can also provide performance benefits for (I/O-bound work). In languages with a GIL like Python, we effectively only allow one employee to work at any given time, and we switch between them. Why is this still useful? Workers, when not idle, can schedule deliveries, start long-running processes on machines, etc. - so if our factory mostly consists of kick-starting autonomous tasks (I/O-bound work), multiple employees can still accomplish much more than a single employee. With the meager time each employee is given, he can start some independent task, such as scheduling a delivery. We immediately yell "freeze!" and transfer the working rights to another worker. He too, registers some task. When we return to the first worker, our delivery has already arrived, and our worker can program a processing machine before we freeze him again.
      Back to reality. While multithreading is the ideal solution for CPU-bound work, it is less than ideal for I/O bound work. Even in a language that allows multi-threaded parallelism, our program still has idle CPU usage while any given thread waits for some I/O operation to complete. In addition, context switching between threads is time consuming, and as running permission is a zero-sum game, every millisecond of time given to one thread is a millisecond taken from another. So every thread is still resource consuming (though much leaner than a full process).
    3. Asynchronous Tasks- This solution is relevant to I/O bound work, and can solve the wasted resource issues highlighted in the previous paragraph when using multithreading for I/O bound work. This is the final improvement to our factory, and it includes paying one of our employees more so he's willing to "multi-task".
      Now, we hire a supervisor and buy a whiteboard. Our supervisor's job is to provide our employee with tasks to do when a task is completed. The worker schedules some delivery. Instead of waiting for the delivery, he first writes on the whiteboard: "Supervisor, please let me know when the delivery has arrived for further processing". Then he can immediately begin scheduling another delivery, or operating on deliveries from yesterday. The supervisor keeps an eye on the loading dock, and eventually the first delivery arrives. He erases the task from the whiteboard and tells the worker, who begins processing the delivery that just arrived. And so on.
      So this solution requires a couple of components, but it can saves immensely on resources when the work is mostly I/O bound - it needs a single thread for our actual code (the worker), and some constant number of other threads and data structures to inform our thread of new tasks and keep an eye out for completed async operations (the supervisor) and keep tabs on registered tasks (the whiteboard). Our code registers some async task, and requests to be notified when it returns with the results. It notifies the framework what it wants to do with the result, but the syntax of how it is notified and the underlying objects are very framework and languages specific.

    Back to buzzwords

    The only way to get parallelization in Python - in order to reduce execution time for CPU-bound programs, is multi-processing, because of the GIL. This, by definition, doesn't come with shared resources like multi-threading - so there's a large performance and resource penalty. This is not to say that threads have no use in Python - they may be used for reducing execution time for I/O bound programs. Another Python-native alternative that can accomplish basically the same thing is the newish asyncio library, that enables asynchronous code with a single thread.

    Ack

    Writing and resources about concurrency that I like:

    1. Great talk by Steve Klabnik.
    2. Great chapter about async in eloquentJS, an outstanding book.

    Friends that helped

    1. Yoav Tzfati helped clean up my Python code
    2. Naomi Kriger and Yoav read my drafts

    Footnotes

    1. A Python developer friend of mine offered up the following heuristic: If you find yourself reaching for multi-processing in order to incorporate parallel code execution, it's time to choose a different language for this particular task. 2
    2. For brevity, we also implicitly disregard a further step where parallelism can come in handy - some calculations may perhaps allow for non-sequential execution of certain steps. This doesn't diminish the point, though. Say we've found the most reduced version of the algorithm, split among as many units as possible. We are still left with "hard" work needing to be completed. So we've tried our best to reach a solution in as little time as possible - but we still need to bite the bullet of real work needing to be done.
    3. Although you would be hard pressed to justify the semantics, based on needle-thin differences between the dictionary definitions of some of the above terms.
    4. I think that for a programmer like me, who's written only consumers - programs that just consume computing power - it may be harder to understand this perspective. Once you write a provider, such as an operating system, you suddenly understand this. You own all of the resources - so when you parallelize management processes you'll notice you're stepping on your own toes - all of your programs are standing in line for water.
    5. We can also quantify CPU usage as energy expenditure to further illustrate the point. There is no "free" energy - to this end, parallelizing CPU-bound programs cannot save energy. Async code also cannot save energy - but it can minimize wasting energy. A more concise (but, in reality, wrong) framing of this idea is that the ideal program is only bound by CPU usage, as a program where we've solved all I/O issues is left with only CPU usage. This program doesn't exist, except in theory. I/O includes loading the next CPU instructions and reading registers as well, for example. In addition, These are not the only two bounds a program may have, for example another extremely important bound is memory, and a program is a tradeoff between all bounds.
    6. A clock-cycle saved is a clock-cycle earned. This key insight, that a best case scenario asynchronous framework may reduce CPU usage, is what allows event-driven servers to serve many concurrent requests when the requests are mostly I/O bound. A new thread need not be created to serve every request - this can save an enormous amount of resources, in contrast with a thread-per-request framework which is capped by the realistic amount of threads that the server can maintain, thus severely limiting the vertical scaling of the server's possible concurrent requests.
    7. Assuming only one line of Python bytecode is running allowed the writers of python interpreters to write simpler implementations. The trouble is, years later multi-threaded parallelization became important to many programming fields where performance is crucial. Now, existing Python implementations such as CPython are in trouble because the one-line assumption is fundamentally baked in to the underlying C and lifting the GIL as-is would break the interpreter. The "Gilectomy", an attempt to remove the GIL from CPython, is a demonstration to that effect.
    8. This allows us to transform nested callbacks into a list, eliminating callback nesting. Not much later, the language introduced a syntactical wrapper for the promise API that uses the await keyword. This is an adoption of syntax common to many languages, which enables giving asynchronous code a synchronous look, therefore arguably improving readability.
    - \ No newline at end of file +Back to Python: The GIL, which limits Python execution to one line at a time, only enforces its lock within the same process since every process is its own complete Python entity. This means that Python can allow real cpu parallelization using multiprocessing (refer to 1)
  2. Multithreading - multithreading is a tricky, widely available solution for lean concurrency with shared resources within the same process. Threads are lighter execution units than processes. Let's refer back to the factory analogy. Here, we use just the one factory (=process) to run our code. We achieve concurrency by employing many workers to perform many tasks. The workers share the factory facilities and machines, so we save big on resources. If they can work at the same time (=in parallel), we can produce more in a given time (CPU-bound work).
    It is important to state that multithreading can also provide performance benefits for (I/O-bound work). In languages with a GIL like Python, we effectively only allow one employee to work at any given time, and we switch between them. Why is this still useful? Workers, when not idle, can schedule deliveries, start long-running processes on machines, etc. - so if our factory mostly consists of kick-starting autonomous tasks (I/O-bound work), multiple employees can still accomplish much more than a single employee. With the meager time each employee is given, he can start some independent task, such as scheduling a delivery. We immediately yell "freeze!" and transfer the working rights to another worker. He too, registers some task. When we return to the first worker, our delivery has already arrived, and our worker can program a processing machine before we freeze him again.
    Back to reality. While multithreading is the ideal solution for CPU-bound work, it is less than ideal for I/O bound work. Even in a language that allows multi-threaded parallelism, our program still has idle CPU usage while any given thread waits for some I/O operation to complete. In addition, context switching between threads is time consuming, and as running permission is a zero-sum game, every millisecond of time given to one thread is a millisecond taken from another. So every thread is still resource consuming (though much leaner than a full process).
  3. Asynchronous Tasks- This solution is relevant to I/O bound work, and can solve the wasted resource issues highlighted in the previous paragraph when using multithreading for I/O bound work. This is the final improvement to our factory, and it includes paying one of our employees more so he's willing to "multi-task".
    Now, we hire a supervisor and buy a whiteboard. Our supervisor's job is to provide our employee with tasks to do when a task is completed. The worker schedules some delivery. Instead of waiting for the delivery, he first writes on the whiteboard: "Supervisor, please let me know when the delivery has arrived for further processing". Then he can immediately begin scheduling another delivery, or operating on deliveries from yesterday. The supervisor keeps an eye on the loading dock, and eventually the first delivery arrives. He erases the task from the whiteboard and tells the worker, who begins processing the delivery that just arrived. And so on.
    So this solution requires a couple of components, but it can saves immensely on resources when the work is mostly I/O bound - it needs a single thread for our actual code (the worker), and some constant number of other threads and data structures to inform our thread of new tasks and keep an eye out for completed async operations (the supervisor) and keep tabs on registered tasks (the whiteboard). Our code registers some async task, and requests to be notified when it returns with the results. It notifies the framework what it wants to do with the result, but the syntax of how it is notified and the underlying objects are very framework and languages specific.
  4. Back to buzzwords

    The only way to get parallelization in Python - in order to reduce execution time for CPU-bound programs, is multi-processing, because of the GIL. This, by definition, doesn't come with shared resources like multi-threading - so there's a large performance and resource penalty. This is not to say that threads have no use in Python - they may be used for reducing execution time for I/O bound programs. Another Python-native alternative that can accomplish basically the same thing is the newish asyncio library, that enables asynchronous code with a single thread.

    Ack

    Writing and resources about concurrency that I like:

    1. Great talk by Steve Klabnik.
    2. Great chapter about async in eloquentJS, an outstanding book.

    Friends that helped

    1. Yoav Tzfati helped clean up my Python code
    2. Naomi Kriger and Yoav read my drafts

    Footnotes

    1. A Python developer friend of mine offered up the following heuristic: If you find yourself reaching for multi-processing in order to incorporate parallel code execution, it's time to choose a different language for this particular task. 2
    2. For brevity, we also implicitly disregard a further step where parallelism can come in handy - some calculations may perhaps allow for non-sequential execution of certain steps. This doesn't diminish the point, though. Say we've found the most reduced version of the algorithm, split among as many units as possible. We are still left with "hard" work needing to be completed. So we've tried our best to reach a solution in as little time as possible - but we still need to bite the bullet of real work needing to be done.
    3. Although you would be hard pressed to justify the semantics, based on needle-thin differences between the dictionary definitions of some of the above terms.
    4. I think that for a programmer like me, who's written only consumers - programs that just consume computing power - it may be harder to understand this perspective. Once you write a provider, such as an operating system, you suddenly understand this. You own all of the resources - so when you parallelize management processes you'll notice you're stepping on your own toes - all of your programs are standing in line for water.
    5. We can also quantify CPU usage as energy expenditure to further illustrate the point. There is no "free" energy - to this end, parallelizing CPU-bound programs cannot save energy. Async code also cannot save energy - but it can minimize wasting energy. A more concise (but, in reality, wrong) framing of this idea is that the ideal program is only bound by CPU usage, as a program where we've solved all I/O issues is left with only CPU usage. This program doesn't exist, except in theory. I/O includes loading the next CPU instructions and reading registers as well, for example. In addition, These are not the only two bounds a program may have, for example another extremely important bound is memory, and a program is a tradeoff between all bounds.
    6. A clock-cycle saved is a clock-cycle earned. This key insight, that a best case scenario asynchronous framework may reduce CPU usage, is what allows event-driven servers to serve many concurrent requests when the requests are mostly I/O bound. A new thread need not be created to serve every request - this can save an enormous amount of resources, in contrast with a thread-per-request framework which is capped by the realistic amount of threads that the server can maintain, thus severely limiting the vertical scaling of the server's possible concurrent requests.
    7. Assuming only one line of Python bytecode is running allowed the writers of python interpreters to write simpler implementations. The trouble is, years later multi-threaded parallelization became important to many programming fields where performance is crucial. Now, existing Python implementations such as CPython are in trouble because the one-line assumption is fundamentally baked in to the underlying C and lifting the GIL as-is would break the interpreter. The "Gilectomy", an attempt to remove the GIL from CPython, is a demonstration to that effect.
    8. This allows us to transform nested callbacks into a list, eliminating callback nesting. Not much later, the language introduced a syntactical wrapper for the promise API that uses the await keyword. This is an adoption of syntax common to many languages, which enables giving asynchronous code a synchronous look, therefore arguably improving readability.
    + \ No newline at end of file diff --git a/index.html b/index.html index fdad05b..7ca0948 100644 --- a/index.html +++ b/index.html @@ -3,14 +3,14 @@ - + - - - + + + - - - -

    - \ No newline at end of file + + + +

    + \ No newline at end of file diff --git a/ok-sometimes-async-await/_payload.json b/ok-sometimes-async-await/_payload.json index ba15836..5f531da 100644 --- a/ok-sometimes-async-await/_payload.json +++ b/ok-sometimes-async-await/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":1086},["Reactive",2],{"content-query-eFpg7TFCSy":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":5,"title":7,"description":5,"body":8,"_type":1081,"_id":1082,"_source":1083,"_file":1084,"_extension":1085},"/ok-sometimes-async-await","",false,"Ok, Sometimes Async Await",{"type":9,"children":10,"toc":1073},"root",[11,20,66,73,263,297,497,503,649,661,666,865,871,876,1003,1022,1026,1067],{"type":12,"tag":13,"props":14,"children":16},"element","h2",{"id":15},"ok-sometimes-async-await",[17],{"type":18,"value":19},"text","Ok, Sometimes Async-Await",{"type":12,"tag":21,"props":22,"children":23},"p",{},[24,26,33,35,41,43,57,59,64],{"type":18,"value":25},"Normally, I continue believing that the classic (well, ES6) ",{"type":12,"tag":27,"props":28,"children":30},"code",{"className":29},[],[31],{"type":18,"value":32},"promise.then().catch().finally()",{"type":18,"value":34}," is nicer than using the newer ES17 ",{"type":12,"tag":27,"props":36,"children":38},{"className":37},[],[39],{"type":18,"value":40},"async-await",{"type":18,"value":42}," syntax, because of function composability",{"type":12,"tag":44,"props":45,"children":46},"sup",{},[47],{"type":12,"tag":48,"props":49,"children":54},"a",{"href":50,"ariaDescribedBy":51,"dataFootnoteRef":5,"id":53},"#user-content-fn-1",[52],"footnote-label","user-content-fnref-1",[55],{"type":18,"value":56},"1",{"type":18,"value":58},".\nThere are 2 cases where I think ",{"type":12,"tag":27,"props":60,"children":62},{"className":61},[],[63],{"type":18,"value":40},{"type":18,"value":65}," is neater, and one where it may perceivably come in handy:",{"type":12,"tag":67,"props":68,"children":70},"h3",{"id":69},"_1-early-returnthrowing-errors",[71],{"type":18,"value":72},"1. Early Return/Throwing Errors",{"type":12,"tag":74,"props":75,"children":79},"pre",{"className":76,"code":77,"language":78,"meta":5,"style":5},"language-ts shiki shiki-themes synthwave-84","async function returnEarly(): Promise\u003CSomeType | undefined> {\n if (someCondition) return;\n await networkRequest();\n if (someOtherCondition) return;\n return await someOtherNetworkRequest();\n}\n","ts",[80],{"type":12,"tag":27,"props":81,"children":82},{"__ignoreMap":5},[83,148,183,202,231,254],{"type":12,"tag":84,"props":85,"children":88},"span",{"class":86,"line":87},"line",1,[89,95,100,106,112,117,123,128,133,138,143],{"type":12,"tag":84,"props":90,"children":92},{"style":91},"--shiki-default:#FEDE5D",[93],{"type":18,"value":94},"async",{"type":12,"tag":84,"props":96,"children":97},{"style":91},[98],{"type":18,"value":99}," function",{"type":12,"tag":84,"props":101,"children":103},{"style":102},"--shiki-default:#36F9F6",[104],{"type":18,"value":105}," returnEarly",{"type":12,"tag":84,"props":107,"children":109},{"style":108},"--shiki-default:#BBBBBB",[110],{"type":18,"value":111},"()",{"type":12,"tag":84,"props":113,"children":114},{"style":91},[115],{"type":18,"value":116},":",{"type":12,"tag":84,"props":118,"children":120},{"style":119},"--shiki-default:#FE4450",[121],{"type":18,"value":122}," Promise",{"type":12,"tag":84,"props":124,"children":125},{"style":108},[126],{"type":18,"value":127},"\u003C",{"type":12,"tag":84,"props":129,"children":130},{"style":119},[131],{"type":18,"value":132},"SomeType",{"type":12,"tag":84,"props":134,"children":135},{"style":91},[136],{"type":18,"value":137}," |",{"type":12,"tag":84,"props":139,"children":140},{"style":119},[141],{"type":18,"value":142}," undefined",{"type":12,"tag":84,"props":144,"children":145},{"style":108},[146],{"type":18,"value":147},"> {\n",{"type":12,"tag":84,"props":149,"children":151},{"class":86,"line":150},2,[152,157,162,168,173,178],{"type":12,"tag":84,"props":153,"children":154},{"style":91},[155],{"type":18,"value":156}," if",{"type":12,"tag":84,"props":158,"children":159},{"style":108},[160],{"type":18,"value":161}," (",{"type":12,"tag":84,"props":163,"children":165},{"style":164},"--shiki-default:#FF7EDB",[166],{"type":18,"value":167},"someCondition",{"type":12,"tag":84,"props":169,"children":170},{"style":108},[171],{"type":18,"value":172},") ",{"type":12,"tag":84,"props":174,"children":175},{"style":91},[176],{"type":18,"value":177},"return",{"type":12,"tag":84,"props":179,"children":180},{"style":108},[181],{"type":18,"value":182},";\n",{"type":12,"tag":84,"props":184,"children":186},{"class":86,"line":185},3,[187,192,197],{"type":12,"tag":84,"props":188,"children":189},{"style":91},[190],{"type":18,"value":191}," await",{"type":12,"tag":84,"props":193,"children":194},{"style":102},[195],{"type":18,"value":196}," networkRequest",{"type":12,"tag":84,"props":198,"children":199},{"style":108},[200],{"type":18,"value":201},"();\n",{"type":12,"tag":84,"props":203,"children":205},{"class":86,"line":204},4,[206,210,214,219,223,227],{"type":12,"tag":84,"props":207,"children":208},{"style":91},[209],{"type":18,"value":156},{"type":12,"tag":84,"props":211,"children":212},{"style":108},[213],{"type":18,"value":161},{"type":12,"tag":84,"props":215,"children":216},{"style":164},[217],{"type":18,"value":218},"someOtherCondition",{"type":12,"tag":84,"props":220,"children":221},{"style":108},[222],{"type":18,"value":172},{"type":12,"tag":84,"props":224,"children":225},{"style":91},[226],{"type":18,"value":177},{"type":12,"tag":84,"props":228,"children":229},{"style":108},[230],{"type":18,"value":182},{"type":12,"tag":84,"props":232,"children":234},{"class":86,"line":233},5,[235,240,245,250],{"type":12,"tag":84,"props":236,"children":237},{"style":91},[238],{"type":18,"value":239}," return",{"type":12,"tag":84,"props":241,"children":242},{"style":91},[243],{"type":18,"value":244}," await",{"type":12,"tag":84,"props":246,"children":247},{"style":102},[248],{"type":18,"value":249}," someOtherNetworkRequest",{"type":12,"tag":84,"props":251,"children":252},{"style":108},[253],{"type":18,"value":201},{"type":12,"tag":84,"props":255,"children":257},{"class":86,"line":256},6,[258],{"type":12,"tag":84,"props":259,"children":260},{"style":108},[261],{"type":18,"value":262},"}\n",{"type":12,"tag":21,"props":264,"children":265},{},[266,268,280,282,288,290,295],{"type":18,"value":267},"This way, your function can return early concisely, ",{"type":12,"tag":269,"props":270,"children":271},"strong",{},[272,274],{"type":18,"value":273},"but still always return a ",{"type":12,"tag":27,"props":275,"children":277},{"className":276},[],[278],{"type":18,"value":279},"Promise",{"type":18,"value":281},".\nThis is because, all values returned from an ",{"type":12,"tag":27,"props":283,"children":285},{"className":284},[],[286],{"type":18,"value":287},"async function",{"type":18,"value":289}," are automatically wrapped in a ",{"type":12,"tag":27,"props":291,"children":293},{"className":292},[],[294],{"type":18,"value":279},{"type":18,"value":296}," if they aren't already. The equivalent code is pretty ugly:",{"type":12,"tag":74,"props":298,"children":300},{"className":76,"code":299,"language":78,"meta":5,"style":5},"function returnEarly(): Promise\u003CSomeType | undefined> {\n if (someCondition) return Promise.resolve();\n return networkRequest().then(() => {\n if (someOtherCondition) return Promise.resolve();\n return someOtherNetworkRequest();\n });\n}\n",[301],{"type":12,"tag":27,"props":302,"children":303},{"__ignoreMap":5},[304,348,389,425,465,481,489],{"type":12,"tag":84,"props":305,"children":306},{"class":86,"line":87},[307,312,316,320,324,328,332,336,340,344],{"type":12,"tag":84,"props":308,"children":309},{"style":91},[310],{"type":18,"value":311},"function",{"type":12,"tag":84,"props":313,"children":314},{"style":102},[315],{"type":18,"value":105},{"type":12,"tag":84,"props":317,"children":318},{"style":108},[319],{"type":18,"value":111},{"type":12,"tag":84,"props":321,"children":322},{"style":91},[323],{"type":18,"value":116},{"type":12,"tag":84,"props":325,"children":326},{"style":119},[327],{"type":18,"value":122},{"type":12,"tag":84,"props":329,"children":330},{"style":108},[331],{"type":18,"value":127},{"type":12,"tag":84,"props":333,"children":334},{"style":119},[335],{"type":18,"value":132},{"type":12,"tag":84,"props":337,"children":338},{"style":91},[339],{"type":18,"value":137},{"type":12,"tag":84,"props":341,"children":342},{"style":119},[343],{"type":18,"value":142},{"type":12,"tag":84,"props":345,"children":346},{"style":108},[347],{"type":18,"value":147},{"type":12,"tag":84,"props":349,"children":350},{"class":86,"line":150},[351,355,359,363,367,371,375,380,385],{"type":12,"tag":84,"props":352,"children":353},{"style":91},[354],{"type":18,"value":156},{"type":12,"tag":84,"props":356,"children":357},{"style":108},[358],{"type":18,"value":161},{"type":12,"tag":84,"props":360,"children":361},{"style":164},[362],{"type":18,"value":167},{"type":12,"tag":84,"props":364,"children":365},{"style":108},[366],{"type":18,"value":172},{"type":12,"tag":84,"props":368,"children":369},{"style":91},[370],{"type":18,"value":177},{"type":12,"tag":84,"props":372,"children":373},{"style":119},[374],{"type":18,"value":122},{"type":12,"tag":84,"props":376,"children":377},{"style":108},[378],{"type":18,"value":379},".",{"type":12,"tag":84,"props":381,"children":382},{"style":102},[383],{"type":18,"value":384},"resolve",{"type":12,"tag":84,"props":386,"children":387},{"style":108},[388],{"type":18,"value":201},{"type":12,"tag":84,"props":390,"children":391},{"class":86,"line":185},[392,396,400,405,410,415,420],{"type":12,"tag":84,"props":393,"children":394},{"style":91},[395],{"type":18,"value":239},{"type":12,"tag":84,"props":397,"children":398},{"style":102},[399],{"type":18,"value":196},{"type":12,"tag":84,"props":401,"children":402},{"style":108},[403],{"type":18,"value":404},"().",{"type":12,"tag":84,"props":406,"children":407},{"style":102},[408],{"type":18,"value":409},"then",{"type":12,"tag":84,"props":411,"children":412},{"style":108},[413],{"type":18,"value":414},"(() ",{"type":12,"tag":84,"props":416,"children":417},{"style":91},[418],{"type":18,"value":419},"=>",{"type":12,"tag":84,"props":421,"children":422},{"style":108},[423],{"type":18,"value":424}," {\n",{"type":12,"tag":84,"props":426,"children":427},{"class":86,"line":204},[428,433,437,441,445,449,453,457,461],{"type":12,"tag":84,"props":429,"children":430},{"style":91},[431],{"type":18,"value":432}," if",{"type":12,"tag":84,"props":434,"children":435},{"style":108},[436],{"type":18,"value":161},{"type":12,"tag":84,"props":438,"children":439},{"style":164},[440],{"type":18,"value":218},{"type":12,"tag":84,"props":442,"children":443},{"style":108},[444],{"type":18,"value":172},{"type":12,"tag":84,"props":446,"children":447},{"style":91},[448],{"type":18,"value":177},{"type":12,"tag":84,"props":450,"children":451},{"style":119},[452],{"type":18,"value":122},{"type":12,"tag":84,"props":454,"children":455},{"style":108},[456],{"type":18,"value":379},{"type":12,"tag":84,"props":458,"children":459},{"style":102},[460],{"type":18,"value":384},{"type":12,"tag":84,"props":462,"children":463},{"style":108},[464],{"type":18,"value":201},{"type":12,"tag":84,"props":466,"children":467},{"class":86,"line":233},[468,473,477],{"type":12,"tag":84,"props":469,"children":470},{"style":91},[471],{"type":18,"value":472}," return",{"type":12,"tag":84,"props":474,"children":475},{"style":102},[476],{"type":18,"value":249},{"type":12,"tag":84,"props":478,"children":479},{"style":108},[480],{"type":18,"value":201},{"type":12,"tag":84,"props":482,"children":483},{"class":86,"line":256},[484],{"type":12,"tag":84,"props":485,"children":486},{"style":108},[487],{"type":18,"value":488}," });\n",{"type":12,"tag":84,"props":490,"children":492},{"class":86,"line":491},7,[493],{"type":12,"tag":84,"props":494,"children":495},{"style":108},[496],{"type":18,"value":262},{"type":12,"tag":67,"props":498,"children":500},{"id":499},"_2-promise-drilling",[501],{"type":18,"value":502},"2. Promise Drilling",{"type":12,"tag":74,"props":504,"children":508},{"className":505,"code":506,"language":507,"meta":5,"style":5},"language-js shiki shiki-themes synthwave-84","async function hotPotato() {\n const a = await networkRequestA();\n const b = await networkRequestB(a);\n return await networkRequestC(a, b);\n}\n","js",[509],{"type":12,"tag":27,"props":510,"children":511},{"__ignoreMap":5},[512,533,565,604,642],{"type":12,"tag":84,"props":513,"children":514},{"class":86,"line":87},[515,519,523,528],{"type":12,"tag":84,"props":516,"children":517},{"style":91},[518],{"type":18,"value":94},{"type":12,"tag":84,"props":520,"children":521},{"style":91},[522],{"type":18,"value":99},{"type":12,"tag":84,"props":524,"children":525},{"style":102},[526],{"type":18,"value":527}," hotPotato",{"type":12,"tag":84,"props":529,"children":530},{"style":108},[531],{"type":18,"value":532},"() {\n",{"type":12,"tag":84,"props":534,"children":535},{"class":86,"line":150},[536,541,546,552,556,561],{"type":12,"tag":84,"props":537,"children":538},{"style":91},[539],{"type":18,"value":540}," const",{"type":12,"tag":84,"props":542,"children":543},{"style":164},[544],{"type":18,"value":545}," a",{"type":12,"tag":84,"props":547,"children":549},{"style":548},"--shiki-default:#FFFFFFEE",[550],{"type":18,"value":551}," =",{"type":12,"tag":84,"props":553,"children":554},{"style":91},[555],{"type":18,"value":244},{"type":12,"tag":84,"props":557,"children":558},{"style":102},[559],{"type":18,"value":560}," networkRequestA",{"type":12,"tag":84,"props":562,"children":563},{"style":108},[564],{"type":18,"value":201},{"type":12,"tag":84,"props":566,"children":567},{"class":86,"line":185},[568,572,577,581,585,590,595,599],{"type":12,"tag":84,"props":569,"children":570},{"style":91},[571],{"type":18,"value":540},{"type":12,"tag":84,"props":573,"children":574},{"style":164},[575],{"type":18,"value":576}," b",{"type":12,"tag":84,"props":578,"children":579},{"style":548},[580],{"type":18,"value":551},{"type":12,"tag":84,"props":582,"children":583},{"style":91},[584],{"type":18,"value":244},{"type":12,"tag":84,"props":586,"children":587},{"style":102},[588],{"type":18,"value":589}," networkRequestB",{"type":12,"tag":84,"props":591,"children":592},{"style":108},[593],{"type":18,"value":594},"(",{"type":12,"tag":84,"props":596,"children":597},{"style":164},[598],{"type":18,"value":48},{"type":12,"tag":84,"props":600,"children":601},{"style":108},[602],{"type":18,"value":603},");\n",{"type":12,"tag":84,"props":605,"children":606},{"class":86,"line":204},[607,611,615,620,624,628,633,638],{"type":12,"tag":84,"props":608,"children":609},{"style":91},[610],{"type":18,"value":239},{"type":12,"tag":84,"props":612,"children":613},{"style":91},[614],{"type":18,"value":244},{"type":12,"tag":84,"props":616,"children":617},{"style":102},[618],{"type":18,"value":619}," networkRequestC",{"type":12,"tag":84,"props":621,"children":622},{"style":108},[623],{"type":18,"value":594},{"type":12,"tag":84,"props":625,"children":626},{"style":164},[627],{"type":18,"value":48},{"type":12,"tag":84,"props":629,"children":630},{"style":108},[631],{"type":18,"value":632},", ",{"type":12,"tag":84,"props":634,"children":635},{"style":164},[636],{"type":18,"value":637},"b",{"type":12,"tag":84,"props":639,"children":640},{"style":108},[641],{"type":18,"value":603},{"type":12,"tag":84,"props":643,"children":644},{"class":86,"line":233},[645],{"type":12,"tag":84,"props":646,"children":647},{"style":108},[648],{"type":18,"value":262},{"type":12,"tag":21,"props":650,"children":651},{},[652,654,659],{"type":18,"value":653},"Sometimes, a computation requires a value several promises upstream. Using ",{"type":12,"tag":27,"props":655,"children":657},{"className":656},[],[658],{"type":18,"value":40},{"type":18,"value":660},", you see the entire function's scope trivially, so you don't need to drill down with the value.",{"type":12,"tag":21,"props":662,"children":663},{},[664],{"type":18,"value":665},"The equivalent code is ugly:",{"type":12,"tag":74,"props":667,"children":669},{"className":505,"code":668,"language":507,"meta":5,"style":5},"function hotPotato() {\n return A()\n .then((a) => B(a).then((b) => [a, b]))\n .then(([a, b]) => C(a, b));\n}\n",[670],{"type":12,"tag":27,"props":671,"children":672},{"__ignoreMap":5},[673,688,705,795,858],{"type":12,"tag":84,"props":674,"children":675},{"class":86,"line":87},[676,680,684],{"type":12,"tag":84,"props":677,"children":678},{"style":91},[679],{"type":18,"value":311},{"type":12,"tag":84,"props":681,"children":682},{"style":102},[683],{"type":18,"value":527},{"type":12,"tag":84,"props":685,"children":686},{"style":108},[687],{"type":18,"value":532},{"type":12,"tag":84,"props":689,"children":690},{"class":86,"line":150},[691,695,700],{"type":12,"tag":84,"props":692,"children":693},{"style":91},[694],{"type":18,"value":239},{"type":12,"tag":84,"props":696,"children":697},{"style":102},[698],{"type":18,"value":699}," A",{"type":12,"tag":84,"props":701,"children":702},{"style":108},[703],{"type":18,"value":704},"()\n",{"type":12,"tag":84,"props":706,"children":707},{"class":86,"line":185},[708,713,717,722,727,731,735,740,744,748,753,757,761,765,769,773,778,782,786,790],{"type":12,"tag":84,"props":709,"children":710},{"style":108},[711],{"type":18,"value":712}," .",{"type":12,"tag":84,"props":714,"children":715},{"style":102},[716],{"type":18,"value":409},{"type":12,"tag":84,"props":718,"children":719},{"style":108},[720],{"type":18,"value":721},"((",{"type":12,"tag":84,"props":723,"children":725},{"style":724},"--shiki-default:#FF7EDB;--shiki-default-font-style:italic",[726],{"type":18,"value":48},{"type":12,"tag":84,"props":728,"children":729},{"style":108},[730],{"type":18,"value":172},{"type":12,"tag":84,"props":732,"children":733},{"style":91},[734],{"type":18,"value":419},{"type":12,"tag":84,"props":736,"children":737},{"style":102},[738],{"type":18,"value":739}," B",{"type":12,"tag":84,"props":741,"children":742},{"style":108},[743],{"type":18,"value":594},{"type":12,"tag":84,"props":745,"children":746},{"style":164},[747],{"type":18,"value":48},{"type":12,"tag":84,"props":749,"children":750},{"style":108},[751],{"type":18,"value":752},").",{"type":12,"tag":84,"props":754,"children":755},{"style":102},[756],{"type":18,"value":409},{"type":12,"tag":84,"props":758,"children":759},{"style":108},[760],{"type":18,"value":721},{"type":12,"tag":84,"props":762,"children":763},{"style":724},[764],{"type":18,"value":637},{"type":12,"tag":84,"props":766,"children":767},{"style":108},[768],{"type":18,"value":172},{"type":12,"tag":84,"props":770,"children":771},{"style":91},[772],{"type":18,"value":419},{"type":12,"tag":84,"props":774,"children":775},{"style":108},[776],{"type":18,"value":777}," [",{"type":12,"tag":84,"props":779,"children":780},{"style":164},[781],{"type":18,"value":48},{"type":12,"tag":84,"props":783,"children":784},{"style":108},[785],{"type":18,"value":632},{"type":12,"tag":84,"props":787,"children":788},{"style":164},[789],{"type":18,"value":637},{"type":12,"tag":84,"props":791,"children":792},{"style":108},[793],{"type":18,"value":794},"]))\n",{"type":12,"tag":84,"props":796,"children":797},{"class":86,"line":204},[798,802,806,811,815,819,823,828,832,837,841,845,849,853],{"type":12,"tag":84,"props":799,"children":800},{"style":108},[801],{"type":18,"value":712},{"type":12,"tag":84,"props":803,"children":804},{"style":102},[805],{"type":18,"value":409},{"type":12,"tag":84,"props":807,"children":808},{"style":108},[809],{"type":18,"value":810},"(([",{"type":12,"tag":84,"props":812,"children":813},{"style":724},[814],{"type":18,"value":48},{"type":12,"tag":84,"props":816,"children":817},{"style":108},[818],{"type":18,"value":632},{"type":12,"tag":84,"props":820,"children":821},{"style":724},[822],{"type":18,"value":637},{"type":12,"tag":84,"props":824,"children":825},{"style":108},[826],{"type":18,"value":827},"]) ",{"type":12,"tag":84,"props":829,"children":830},{"style":91},[831],{"type":18,"value":419},{"type":12,"tag":84,"props":833,"children":834},{"style":102},[835],{"type":18,"value":836}," C",{"type":12,"tag":84,"props":838,"children":839},{"style":108},[840],{"type":18,"value":594},{"type":12,"tag":84,"props":842,"children":843},{"style":164},[844],{"type":18,"value":48},{"type":12,"tag":84,"props":846,"children":847},{"style":108},[848],{"type":18,"value":632},{"type":12,"tag":84,"props":850,"children":851},{"style":164},[852],{"type":18,"value":637},{"type":12,"tag":84,"props":854,"children":855},{"style":108},[856],{"type":18,"value":857},"));\n",{"type":12,"tag":84,"props":859,"children":860},{"class":86,"line":233},[861],{"type":12,"tag":84,"props":862,"children":863},{"style":108},[864],{"type":18,"value":262},{"type":12,"tag":67,"props":866,"children":868},{"id":867},"_3-object-asyncfunction",[869],{"type":18,"value":870},"3? [object AsyncFunction]",{"type":12,"tag":21,"props":872,"children":873},{},[874],{"type":18,"value":875},"This does not generally strike me as useful, but can theoretically come in handy.",{"type":12,"tag":74,"props":877,"children":879},{"className":76,"code":878,"language":78,"meta":5,"style":5},"Object.prototype.toString.call(async () => producePromise()); // '[object AsyncFunction]'\nObject.prototype.toString.call(() => producePromise()); // '[object Function]'\n",[880],{"type":12,"tag":27,"props":881,"children":882},{"__ignoreMap":5},[883,951],{"type":12,"tag":84,"props":884,"children":885},{"class":86,"line":87},[886,891,895,900,904,909,913,918,922,926,931,935,940,945],{"type":12,"tag":84,"props":887,"children":888},{"style":119},[889],{"type":18,"value":890},"Object",{"type":12,"tag":84,"props":892,"children":893},{"style":108},[894],{"type":18,"value":379},{"type":12,"tag":84,"props":896,"children":897},{"style":164},[898],{"type":18,"value":899},"prototype",{"type":12,"tag":84,"props":901,"children":902},{"style":108},[903],{"type":18,"value":379},{"type":12,"tag":84,"props":905,"children":906},{"style":164},[907],{"type":18,"value":908},"toString",{"type":12,"tag":84,"props":910,"children":911},{"style":108},[912],{"type":18,"value":379},{"type":12,"tag":84,"props":914,"children":915},{"style":102},[916],{"type":18,"value":917},"call",{"type":12,"tag":84,"props":919,"children":920},{"style":108},[921],{"type":18,"value":594},{"type":12,"tag":84,"props":923,"children":924},{"style":91},[925],{"type":18,"value":94},{"type":12,"tag":84,"props":927,"children":928},{"style":108},[929],{"type":18,"value":930}," () ",{"type":12,"tag":84,"props":932,"children":933},{"style":91},[934],{"type":18,"value":419},{"type":12,"tag":84,"props":936,"children":937},{"style":102},[938],{"type":18,"value":939}," producePromise",{"type":12,"tag":84,"props":941,"children":942},{"style":108},[943],{"type":18,"value":944},"()); ",{"type":12,"tag":84,"props":946,"children":948},{"style":947},"--shiki-default:#848BBD;--shiki-default-font-style:italic",[949],{"type":18,"value":950},"// '[object AsyncFunction]'\n",{"type":12,"tag":84,"props":952,"children":953},{"class":86,"line":150},[954,958,962,966,970,974,978,982,986,990,994,998],{"type":12,"tag":84,"props":955,"children":956},{"style":119},[957],{"type":18,"value":890},{"type":12,"tag":84,"props":959,"children":960},{"style":108},[961],{"type":18,"value":379},{"type":12,"tag":84,"props":963,"children":964},{"style":164},[965],{"type":18,"value":899},{"type":12,"tag":84,"props":967,"children":968},{"style":108},[969],{"type":18,"value":379},{"type":12,"tag":84,"props":971,"children":972},{"style":164},[973],{"type":18,"value":908},{"type":12,"tag":84,"props":975,"children":976},{"style":108},[977],{"type":18,"value":379},{"type":12,"tag":84,"props":979,"children":980},{"style":102},[981],{"type":18,"value":917},{"type":12,"tag":84,"props":983,"children":984},{"style":108},[985],{"type":18,"value":414},{"type":12,"tag":84,"props":987,"children":988},{"style":91},[989],{"type":18,"value":419},{"type":12,"tag":84,"props":991,"children":992},{"style":102},[993],{"type":18,"value":939},{"type":12,"tag":84,"props":995,"children":996},{"style":108},[997],{"type":18,"value":944},{"type":12,"tag":84,"props":999,"children":1000},{"style":947},[1001],{"type":18,"value":1002},"// '[object Function]'\n",{"type":12,"tag":21,"props":1004,"children":1005},{},[1006,1008,1013,1015,1021],{"type":18,"value":1007},"So the language gives us a way to know if a function was declared with the ",{"type":12,"tag":27,"props":1009,"children":1011},{"className":1010},[],[1012],{"type":18,"value":94},{"type":18,"value":1014}," modifier.\nIn some contrived scenario, we can imagine that it may be very useful to be able to check during runtime if the function will be asynchronous ",{"type":12,"tag":1016,"props":1017,"children":1018},"em",{},[1019],{"type":18,"value":1020},"before invoking it",{"type":18,"value":379},{"type":12,"tag":1023,"props":1024,"children":1025},"hr",{},[],{"type":12,"tag":1027,"props":1028,"children":1031},"section",{"className":1029,"dataFootnotes":5},[1030],"footnotes",[1032,1039],{"type":12,"tag":13,"props":1033,"children":1036},{"className":1034,"id":52},[1035],"sr-only",[1037],{"type":18,"value":1038},"Footnotes",{"type":12,"tag":1040,"props":1041,"children":1042},"ol",{},[1043],{"type":12,"tag":1044,"props":1045,"children":1047},"li",{"id":1046},"user-content-fn-1",[1048,1050,1056,1058],{"type":18,"value":1049},"Composability: ",{"type":12,"tag":27,"props":1051,"children":1053},{"className":1052},[],[1054],{"type":18,"value":1055},"fetchThing().then(doThing).catch(logError).finally(toFalse)",{"type":18,"value":1057}," ",{"type":12,"tag":48,"props":1059,"children":1064},{"href":1060,"ariaLabel":1061,"className":1062,"dataFootnoteBackref":5},"#user-content-fnref-1","Back to reference 1",[1063],"data-footnote-backref",[1065],{"type":18,"value":1066},"↩",{"type":12,"tag":1068,"props":1069,"children":1070},"style",{},[1071],{"type":18,"value":1072},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":5,"searchDepth":150,"depth":150,"links":1074},[1075,1080],{"id":15,"depth":150,"text":19,"children":1076},[1077,1078,1079],{"id":69,"depth":185,"text":72},{"id":499,"depth":185,"text":502},{"id":867,"depth":185,"text":870},{"id":52,"depth":150,"text":1038},"markdown","content:Ok, Sometimes Async-Await.md","content","Ok, Sometimes Async-Await.md","md",1717319129434] \ No newline at end of file +[{"data":1,"prerenderedAt":1086},["Reactive",2],{"content-query-eFpg7TFCSy":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":5,"title":7,"description":5,"body":8,"_type":1081,"_id":1082,"_source":1083,"_file":1084,"_extension":1085},"/ok-sometimes-async-await","",false,"Ok, Sometimes Async Await",{"type":9,"children":10,"toc":1073},"root",[11,20,66,73,263,297,497,503,649,661,666,865,871,876,1003,1022,1026,1067],{"type":12,"tag":13,"props":14,"children":16},"element","h2",{"id":15},"ok-sometimes-async-await",[17],{"type":18,"value":19},"text","Ok, Sometimes Async-Await",{"type":12,"tag":21,"props":22,"children":23},"p",{},[24,26,33,35,41,43,57,59,64],{"type":18,"value":25},"Normally, I continue believing that the classic (well, ES6) ",{"type":12,"tag":27,"props":28,"children":30},"code",{"className":29},[],[31],{"type":18,"value":32},"promise.then().catch().finally()",{"type":18,"value":34}," is nicer than using the newer ES17 ",{"type":12,"tag":27,"props":36,"children":38},{"className":37},[],[39],{"type":18,"value":40},"async-await",{"type":18,"value":42}," syntax, because of function composability",{"type":12,"tag":44,"props":45,"children":46},"sup",{},[47],{"type":12,"tag":48,"props":49,"children":54},"a",{"href":50,"ariaDescribedBy":51,"dataFootnoteRef":5,"id":53},"#user-content-fn-1",[52],"footnote-label","user-content-fnref-1",[55],{"type":18,"value":56},"1",{"type":18,"value":58},".\nThere are 2 cases where I think ",{"type":12,"tag":27,"props":60,"children":62},{"className":61},[],[63],{"type":18,"value":40},{"type":18,"value":65}," is neater, and one where it may perceivably come in handy:",{"type":12,"tag":67,"props":68,"children":70},"h3",{"id":69},"_1-early-returnthrowing-errors",[71],{"type":18,"value":72},"1. Early Return/Throwing Errors",{"type":12,"tag":74,"props":75,"children":79},"pre",{"className":76,"code":77,"language":78,"meta":5,"style":5},"language-ts shiki shiki-themes synthwave-84","async function returnEarly(): Promise\u003CSomeType | undefined> {\n if (someCondition) return;\n await networkRequest();\n if (someOtherCondition) return;\n return await someOtherNetworkRequest();\n}\n","ts",[80],{"type":12,"tag":27,"props":81,"children":82},{"__ignoreMap":5},[83,148,183,202,231,254],{"type":12,"tag":84,"props":85,"children":88},"span",{"class":86,"line":87},"line",1,[89,95,100,106,112,117,123,128,133,138,143],{"type":12,"tag":84,"props":90,"children":92},{"style":91},"--shiki-default:#FEDE5D",[93],{"type":18,"value":94},"async",{"type":12,"tag":84,"props":96,"children":97},{"style":91},[98],{"type":18,"value":99}," function",{"type":12,"tag":84,"props":101,"children":103},{"style":102},"--shiki-default:#36F9F6",[104],{"type":18,"value":105}," returnEarly",{"type":12,"tag":84,"props":107,"children":109},{"style":108},"--shiki-default:#BBBBBB",[110],{"type":18,"value":111},"()",{"type":12,"tag":84,"props":113,"children":114},{"style":91},[115],{"type":18,"value":116},":",{"type":12,"tag":84,"props":118,"children":120},{"style":119},"--shiki-default:#FE4450",[121],{"type":18,"value":122}," Promise",{"type":12,"tag":84,"props":124,"children":125},{"style":108},[126],{"type":18,"value":127},"\u003C",{"type":12,"tag":84,"props":129,"children":130},{"style":119},[131],{"type":18,"value":132},"SomeType",{"type":12,"tag":84,"props":134,"children":135},{"style":91},[136],{"type":18,"value":137}," |",{"type":12,"tag":84,"props":139,"children":140},{"style":119},[141],{"type":18,"value":142}," undefined",{"type":12,"tag":84,"props":144,"children":145},{"style":108},[146],{"type":18,"value":147},"> {\n",{"type":12,"tag":84,"props":149,"children":151},{"class":86,"line":150},2,[152,157,162,168,173,178],{"type":12,"tag":84,"props":153,"children":154},{"style":91},[155],{"type":18,"value":156}," if",{"type":12,"tag":84,"props":158,"children":159},{"style":108},[160],{"type":18,"value":161}," (",{"type":12,"tag":84,"props":163,"children":165},{"style":164},"--shiki-default:#FF7EDB",[166],{"type":18,"value":167},"someCondition",{"type":12,"tag":84,"props":169,"children":170},{"style":108},[171],{"type":18,"value":172},") ",{"type":12,"tag":84,"props":174,"children":175},{"style":91},[176],{"type":18,"value":177},"return",{"type":12,"tag":84,"props":179,"children":180},{"style":108},[181],{"type":18,"value":182},";\n",{"type":12,"tag":84,"props":184,"children":186},{"class":86,"line":185},3,[187,192,197],{"type":12,"tag":84,"props":188,"children":189},{"style":91},[190],{"type":18,"value":191}," await",{"type":12,"tag":84,"props":193,"children":194},{"style":102},[195],{"type":18,"value":196}," networkRequest",{"type":12,"tag":84,"props":198,"children":199},{"style":108},[200],{"type":18,"value":201},"();\n",{"type":12,"tag":84,"props":203,"children":205},{"class":86,"line":204},4,[206,210,214,219,223,227],{"type":12,"tag":84,"props":207,"children":208},{"style":91},[209],{"type":18,"value":156},{"type":12,"tag":84,"props":211,"children":212},{"style":108},[213],{"type":18,"value":161},{"type":12,"tag":84,"props":215,"children":216},{"style":164},[217],{"type":18,"value":218},"someOtherCondition",{"type":12,"tag":84,"props":220,"children":221},{"style":108},[222],{"type":18,"value":172},{"type":12,"tag":84,"props":224,"children":225},{"style":91},[226],{"type":18,"value":177},{"type":12,"tag":84,"props":228,"children":229},{"style":108},[230],{"type":18,"value":182},{"type":12,"tag":84,"props":232,"children":234},{"class":86,"line":233},5,[235,240,245,250],{"type":12,"tag":84,"props":236,"children":237},{"style":91},[238],{"type":18,"value":239}," return",{"type":12,"tag":84,"props":241,"children":242},{"style":91},[243],{"type":18,"value":244}," await",{"type":12,"tag":84,"props":246,"children":247},{"style":102},[248],{"type":18,"value":249}," someOtherNetworkRequest",{"type":12,"tag":84,"props":251,"children":252},{"style":108},[253],{"type":18,"value":201},{"type":12,"tag":84,"props":255,"children":257},{"class":86,"line":256},6,[258],{"type":12,"tag":84,"props":259,"children":260},{"style":108},[261],{"type":18,"value":262},"}\n",{"type":12,"tag":21,"props":264,"children":265},{},[266,268,280,282,288,290,295],{"type":18,"value":267},"This way, your function can return early concisely, ",{"type":12,"tag":269,"props":270,"children":271},"strong",{},[272,274],{"type":18,"value":273},"but still always return a ",{"type":12,"tag":27,"props":275,"children":277},{"className":276},[],[278],{"type":18,"value":279},"Promise",{"type":18,"value":281},".\nThis is because, all values returned from an ",{"type":12,"tag":27,"props":283,"children":285},{"className":284},[],[286],{"type":18,"value":287},"async function",{"type":18,"value":289}," are automatically wrapped in a ",{"type":12,"tag":27,"props":291,"children":293},{"className":292},[],[294],{"type":18,"value":279},{"type":18,"value":296}," if they aren't already. The equivalent code is pretty ugly:",{"type":12,"tag":74,"props":298,"children":300},{"className":76,"code":299,"language":78,"meta":5,"style":5},"function returnEarly(): Promise\u003CSomeType | undefined> {\n if (someCondition) return Promise.resolve();\n return networkRequest().then(() => {\n if (someOtherCondition) return Promise.resolve();\n return someOtherNetworkRequest();\n });\n}\n",[301],{"type":12,"tag":27,"props":302,"children":303},{"__ignoreMap":5},[304,348,389,425,465,481,489],{"type":12,"tag":84,"props":305,"children":306},{"class":86,"line":87},[307,312,316,320,324,328,332,336,340,344],{"type":12,"tag":84,"props":308,"children":309},{"style":91},[310],{"type":18,"value":311},"function",{"type":12,"tag":84,"props":313,"children":314},{"style":102},[315],{"type":18,"value":105},{"type":12,"tag":84,"props":317,"children":318},{"style":108},[319],{"type":18,"value":111},{"type":12,"tag":84,"props":321,"children":322},{"style":91},[323],{"type":18,"value":116},{"type":12,"tag":84,"props":325,"children":326},{"style":119},[327],{"type":18,"value":122},{"type":12,"tag":84,"props":329,"children":330},{"style":108},[331],{"type":18,"value":127},{"type":12,"tag":84,"props":333,"children":334},{"style":119},[335],{"type":18,"value":132},{"type":12,"tag":84,"props":337,"children":338},{"style":91},[339],{"type":18,"value":137},{"type":12,"tag":84,"props":341,"children":342},{"style":119},[343],{"type":18,"value":142},{"type":12,"tag":84,"props":345,"children":346},{"style":108},[347],{"type":18,"value":147},{"type":12,"tag":84,"props":349,"children":350},{"class":86,"line":150},[351,355,359,363,367,371,375,380,385],{"type":12,"tag":84,"props":352,"children":353},{"style":91},[354],{"type":18,"value":156},{"type":12,"tag":84,"props":356,"children":357},{"style":108},[358],{"type":18,"value":161},{"type":12,"tag":84,"props":360,"children":361},{"style":164},[362],{"type":18,"value":167},{"type":12,"tag":84,"props":364,"children":365},{"style":108},[366],{"type":18,"value":172},{"type":12,"tag":84,"props":368,"children":369},{"style":91},[370],{"type":18,"value":177},{"type":12,"tag":84,"props":372,"children":373},{"style":119},[374],{"type":18,"value":122},{"type":12,"tag":84,"props":376,"children":377},{"style":108},[378],{"type":18,"value":379},".",{"type":12,"tag":84,"props":381,"children":382},{"style":102},[383],{"type":18,"value":384},"resolve",{"type":12,"tag":84,"props":386,"children":387},{"style":108},[388],{"type":18,"value":201},{"type":12,"tag":84,"props":390,"children":391},{"class":86,"line":185},[392,396,400,405,410,415,420],{"type":12,"tag":84,"props":393,"children":394},{"style":91},[395],{"type":18,"value":239},{"type":12,"tag":84,"props":397,"children":398},{"style":102},[399],{"type":18,"value":196},{"type":12,"tag":84,"props":401,"children":402},{"style":108},[403],{"type":18,"value":404},"().",{"type":12,"tag":84,"props":406,"children":407},{"style":102},[408],{"type":18,"value":409},"then",{"type":12,"tag":84,"props":411,"children":412},{"style":108},[413],{"type":18,"value":414},"(() ",{"type":12,"tag":84,"props":416,"children":417},{"style":91},[418],{"type":18,"value":419},"=>",{"type":12,"tag":84,"props":421,"children":422},{"style":108},[423],{"type":18,"value":424}," {\n",{"type":12,"tag":84,"props":426,"children":427},{"class":86,"line":204},[428,433,437,441,445,449,453,457,461],{"type":12,"tag":84,"props":429,"children":430},{"style":91},[431],{"type":18,"value":432}," if",{"type":12,"tag":84,"props":434,"children":435},{"style":108},[436],{"type":18,"value":161},{"type":12,"tag":84,"props":438,"children":439},{"style":164},[440],{"type":18,"value":218},{"type":12,"tag":84,"props":442,"children":443},{"style":108},[444],{"type":18,"value":172},{"type":12,"tag":84,"props":446,"children":447},{"style":91},[448],{"type":18,"value":177},{"type":12,"tag":84,"props":450,"children":451},{"style":119},[452],{"type":18,"value":122},{"type":12,"tag":84,"props":454,"children":455},{"style":108},[456],{"type":18,"value":379},{"type":12,"tag":84,"props":458,"children":459},{"style":102},[460],{"type":18,"value":384},{"type":12,"tag":84,"props":462,"children":463},{"style":108},[464],{"type":18,"value":201},{"type":12,"tag":84,"props":466,"children":467},{"class":86,"line":233},[468,473,477],{"type":12,"tag":84,"props":469,"children":470},{"style":91},[471],{"type":18,"value":472}," return",{"type":12,"tag":84,"props":474,"children":475},{"style":102},[476],{"type":18,"value":249},{"type":12,"tag":84,"props":478,"children":479},{"style":108},[480],{"type":18,"value":201},{"type":12,"tag":84,"props":482,"children":483},{"class":86,"line":256},[484],{"type":12,"tag":84,"props":485,"children":486},{"style":108},[487],{"type":18,"value":488}," });\n",{"type":12,"tag":84,"props":490,"children":492},{"class":86,"line":491},7,[493],{"type":12,"tag":84,"props":494,"children":495},{"style":108},[496],{"type":18,"value":262},{"type":12,"tag":67,"props":498,"children":500},{"id":499},"_2-promise-drilling",[501],{"type":18,"value":502},"2. Promise Drilling",{"type":12,"tag":74,"props":504,"children":508},{"className":505,"code":506,"language":507,"meta":5,"style":5},"language-js shiki shiki-themes synthwave-84","async function hotPotato() {\n const a = await networkRequestA();\n const b = await networkRequestB(a);\n return await networkRequestC(a, b);\n}\n","js",[509],{"type":12,"tag":27,"props":510,"children":511},{"__ignoreMap":5},[512,533,565,604,642],{"type":12,"tag":84,"props":513,"children":514},{"class":86,"line":87},[515,519,523,528],{"type":12,"tag":84,"props":516,"children":517},{"style":91},[518],{"type":18,"value":94},{"type":12,"tag":84,"props":520,"children":521},{"style":91},[522],{"type":18,"value":99},{"type":12,"tag":84,"props":524,"children":525},{"style":102},[526],{"type":18,"value":527}," hotPotato",{"type":12,"tag":84,"props":529,"children":530},{"style":108},[531],{"type":18,"value":532},"() {\n",{"type":12,"tag":84,"props":534,"children":535},{"class":86,"line":150},[536,541,546,552,556,561],{"type":12,"tag":84,"props":537,"children":538},{"style":91},[539],{"type":18,"value":540}," const",{"type":12,"tag":84,"props":542,"children":543},{"style":164},[544],{"type":18,"value":545}," a",{"type":12,"tag":84,"props":547,"children":549},{"style":548},"--shiki-default:#FFFFFFEE",[550],{"type":18,"value":551}," =",{"type":12,"tag":84,"props":553,"children":554},{"style":91},[555],{"type":18,"value":244},{"type":12,"tag":84,"props":557,"children":558},{"style":102},[559],{"type":18,"value":560}," networkRequestA",{"type":12,"tag":84,"props":562,"children":563},{"style":108},[564],{"type":18,"value":201},{"type":12,"tag":84,"props":566,"children":567},{"class":86,"line":185},[568,572,577,581,585,590,595,599],{"type":12,"tag":84,"props":569,"children":570},{"style":91},[571],{"type":18,"value":540},{"type":12,"tag":84,"props":573,"children":574},{"style":164},[575],{"type":18,"value":576}," b",{"type":12,"tag":84,"props":578,"children":579},{"style":548},[580],{"type":18,"value":551},{"type":12,"tag":84,"props":582,"children":583},{"style":91},[584],{"type":18,"value":244},{"type":12,"tag":84,"props":586,"children":587},{"style":102},[588],{"type":18,"value":589}," networkRequestB",{"type":12,"tag":84,"props":591,"children":592},{"style":108},[593],{"type":18,"value":594},"(",{"type":12,"tag":84,"props":596,"children":597},{"style":164},[598],{"type":18,"value":48},{"type":12,"tag":84,"props":600,"children":601},{"style":108},[602],{"type":18,"value":603},");\n",{"type":12,"tag":84,"props":605,"children":606},{"class":86,"line":204},[607,611,615,620,624,628,633,638],{"type":12,"tag":84,"props":608,"children":609},{"style":91},[610],{"type":18,"value":239},{"type":12,"tag":84,"props":612,"children":613},{"style":91},[614],{"type":18,"value":244},{"type":12,"tag":84,"props":616,"children":617},{"style":102},[618],{"type":18,"value":619}," networkRequestC",{"type":12,"tag":84,"props":621,"children":622},{"style":108},[623],{"type":18,"value":594},{"type":12,"tag":84,"props":625,"children":626},{"style":164},[627],{"type":18,"value":48},{"type":12,"tag":84,"props":629,"children":630},{"style":108},[631],{"type":18,"value":632},", ",{"type":12,"tag":84,"props":634,"children":635},{"style":164},[636],{"type":18,"value":637},"b",{"type":12,"tag":84,"props":639,"children":640},{"style":108},[641],{"type":18,"value":603},{"type":12,"tag":84,"props":643,"children":644},{"class":86,"line":233},[645],{"type":12,"tag":84,"props":646,"children":647},{"style":108},[648],{"type":18,"value":262},{"type":12,"tag":21,"props":650,"children":651},{},[652,654,659],{"type":18,"value":653},"Sometimes, a computation requires a value several promises upstream. Using ",{"type":12,"tag":27,"props":655,"children":657},{"className":656},[],[658],{"type":18,"value":40},{"type":18,"value":660},", you see the entire function's scope trivially, so you don't need to drill down with the value.",{"type":12,"tag":21,"props":662,"children":663},{},[664],{"type":18,"value":665},"The equivalent code is ugly:",{"type":12,"tag":74,"props":667,"children":669},{"className":505,"code":668,"language":507,"meta":5,"style":5},"function hotPotato() {\n return A()\n .then((a) => B(a).then((b) => [a, b]))\n .then(([a, b]) => C(a, b));\n}\n",[670],{"type":12,"tag":27,"props":671,"children":672},{"__ignoreMap":5},[673,688,705,795,858],{"type":12,"tag":84,"props":674,"children":675},{"class":86,"line":87},[676,680,684],{"type":12,"tag":84,"props":677,"children":678},{"style":91},[679],{"type":18,"value":311},{"type":12,"tag":84,"props":681,"children":682},{"style":102},[683],{"type":18,"value":527},{"type":12,"tag":84,"props":685,"children":686},{"style":108},[687],{"type":18,"value":532},{"type":12,"tag":84,"props":689,"children":690},{"class":86,"line":150},[691,695,700],{"type":12,"tag":84,"props":692,"children":693},{"style":91},[694],{"type":18,"value":239},{"type":12,"tag":84,"props":696,"children":697},{"style":102},[698],{"type":18,"value":699}," A",{"type":12,"tag":84,"props":701,"children":702},{"style":108},[703],{"type":18,"value":704},"()\n",{"type":12,"tag":84,"props":706,"children":707},{"class":86,"line":185},[708,713,717,722,727,731,735,740,744,748,753,757,761,765,769,773,778,782,786,790],{"type":12,"tag":84,"props":709,"children":710},{"style":108},[711],{"type":18,"value":712}," .",{"type":12,"tag":84,"props":714,"children":715},{"style":102},[716],{"type":18,"value":409},{"type":12,"tag":84,"props":718,"children":719},{"style":108},[720],{"type":18,"value":721},"((",{"type":12,"tag":84,"props":723,"children":725},{"style":724},"--shiki-default:#FF7EDB;--shiki-default-font-style:italic",[726],{"type":18,"value":48},{"type":12,"tag":84,"props":728,"children":729},{"style":108},[730],{"type":18,"value":172},{"type":12,"tag":84,"props":732,"children":733},{"style":91},[734],{"type":18,"value":419},{"type":12,"tag":84,"props":736,"children":737},{"style":102},[738],{"type":18,"value":739}," B",{"type":12,"tag":84,"props":741,"children":742},{"style":108},[743],{"type":18,"value":594},{"type":12,"tag":84,"props":745,"children":746},{"style":164},[747],{"type":18,"value":48},{"type":12,"tag":84,"props":749,"children":750},{"style":108},[751],{"type":18,"value":752},").",{"type":12,"tag":84,"props":754,"children":755},{"style":102},[756],{"type":18,"value":409},{"type":12,"tag":84,"props":758,"children":759},{"style":108},[760],{"type":18,"value":721},{"type":12,"tag":84,"props":762,"children":763},{"style":724},[764],{"type":18,"value":637},{"type":12,"tag":84,"props":766,"children":767},{"style":108},[768],{"type":18,"value":172},{"type":12,"tag":84,"props":770,"children":771},{"style":91},[772],{"type":18,"value":419},{"type":12,"tag":84,"props":774,"children":775},{"style":108},[776],{"type":18,"value":777}," [",{"type":12,"tag":84,"props":779,"children":780},{"style":164},[781],{"type":18,"value":48},{"type":12,"tag":84,"props":783,"children":784},{"style":108},[785],{"type":18,"value":632},{"type":12,"tag":84,"props":787,"children":788},{"style":164},[789],{"type":18,"value":637},{"type":12,"tag":84,"props":791,"children":792},{"style":108},[793],{"type":18,"value":794},"]))\n",{"type":12,"tag":84,"props":796,"children":797},{"class":86,"line":204},[798,802,806,811,815,819,823,828,832,837,841,845,849,853],{"type":12,"tag":84,"props":799,"children":800},{"style":108},[801],{"type":18,"value":712},{"type":12,"tag":84,"props":803,"children":804},{"style":102},[805],{"type":18,"value":409},{"type":12,"tag":84,"props":807,"children":808},{"style":108},[809],{"type":18,"value":810},"(([",{"type":12,"tag":84,"props":812,"children":813},{"style":724},[814],{"type":18,"value":48},{"type":12,"tag":84,"props":816,"children":817},{"style":108},[818],{"type":18,"value":632},{"type":12,"tag":84,"props":820,"children":821},{"style":724},[822],{"type":18,"value":637},{"type":12,"tag":84,"props":824,"children":825},{"style":108},[826],{"type":18,"value":827},"]) ",{"type":12,"tag":84,"props":829,"children":830},{"style":91},[831],{"type":18,"value":419},{"type":12,"tag":84,"props":833,"children":834},{"style":102},[835],{"type":18,"value":836}," C",{"type":12,"tag":84,"props":838,"children":839},{"style":108},[840],{"type":18,"value":594},{"type":12,"tag":84,"props":842,"children":843},{"style":164},[844],{"type":18,"value":48},{"type":12,"tag":84,"props":846,"children":847},{"style":108},[848],{"type":18,"value":632},{"type":12,"tag":84,"props":850,"children":851},{"style":164},[852],{"type":18,"value":637},{"type":12,"tag":84,"props":854,"children":855},{"style":108},[856],{"type":18,"value":857},"));\n",{"type":12,"tag":84,"props":859,"children":860},{"class":86,"line":233},[861],{"type":12,"tag":84,"props":862,"children":863},{"style":108},[864],{"type":18,"value":262},{"type":12,"tag":67,"props":866,"children":868},{"id":867},"_3-object-asyncfunction",[869],{"type":18,"value":870},"3? [object AsyncFunction]",{"type":12,"tag":21,"props":872,"children":873},{},[874],{"type":18,"value":875},"This does not generally strike me as useful, but can theoretically come in handy.",{"type":12,"tag":74,"props":877,"children":879},{"className":76,"code":878,"language":78,"meta":5,"style":5},"Object.prototype.toString.call(async () => producePromise()); // '[object AsyncFunction]'\nObject.prototype.toString.call(() => producePromise()); // '[object Function]'\n",[880],{"type":12,"tag":27,"props":881,"children":882},{"__ignoreMap":5},[883,951],{"type":12,"tag":84,"props":884,"children":885},{"class":86,"line":87},[886,891,895,900,904,909,913,918,922,926,931,935,940,945],{"type":12,"tag":84,"props":887,"children":888},{"style":119},[889],{"type":18,"value":890},"Object",{"type":12,"tag":84,"props":892,"children":893},{"style":108},[894],{"type":18,"value":379},{"type":12,"tag":84,"props":896,"children":897},{"style":164},[898],{"type":18,"value":899},"prototype",{"type":12,"tag":84,"props":901,"children":902},{"style":108},[903],{"type":18,"value":379},{"type":12,"tag":84,"props":905,"children":906},{"style":164},[907],{"type":18,"value":908},"toString",{"type":12,"tag":84,"props":910,"children":911},{"style":108},[912],{"type":18,"value":379},{"type":12,"tag":84,"props":914,"children":915},{"style":102},[916],{"type":18,"value":917},"call",{"type":12,"tag":84,"props":919,"children":920},{"style":108},[921],{"type":18,"value":594},{"type":12,"tag":84,"props":923,"children":924},{"style":91},[925],{"type":18,"value":94},{"type":12,"tag":84,"props":927,"children":928},{"style":108},[929],{"type":18,"value":930}," () ",{"type":12,"tag":84,"props":932,"children":933},{"style":91},[934],{"type":18,"value":419},{"type":12,"tag":84,"props":936,"children":937},{"style":102},[938],{"type":18,"value":939}," producePromise",{"type":12,"tag":84,"props":941,"children":942},{"style":108},[943],{"type":18,"value":944},"()); ",{"type":12,"tag":84,"props":946,"children":948},{"style":947},"--shiki-default:#848BBD;--shiki-default-font-style:italic",[949],{"type":18,"value":950},"// '[object AsyncFunction]'\n",{"type":12,"tag":84,"props":952,"children":953},{"class":86,"line":150},[954,958,962,966,970,974,978,982,986,990,994,998],{"type":12,"tag":84,"props":955,"children":956},{"style":119},[957],{"type":18,"value":890},{"type":12,"tag":84,"props":959,"children":960},{"style":108},[961],{"type":18,"value":379},{"type":12,"tag":84,"props":963,"children":964},{"style":164},[965],{"type":18,"value":899},{"type":12,"tag":84,"props":967,"children":968},{"style":108},[969],{"type":18,"value":379},{"type":12,"tag":84,"props":971,"children":972},{"style":164},[973],{"type":18,"value":908},{"type":12,"tag":84,"props":975,"children":976},{"style":108},[977],{"type":18,"value":379},{"type":12,"tag":84,"props":979,"children":980},{"style":102},[981],{"type":18,"value":917},{"type":12,"tag":84,"props":983,"children":984},{"style":108},[985],{"type":18,"value":414},{"type":12,"tag":84,"props":987,"children":988},{"style":91},[989],{"type":18,"value":419},{"type":12,"tag":84,"props":991,"children":992},{"style":102},[993],{"type":18,"value":939},{"type":12,"tag":84,"props":995,"children":996},{"style":108},[997],{"type":18,"value":944},{"type":12,"tag":84,"props":999,"children":1000},{"style":947},[1001],{"type":18,"value":1002},"// '[object Function]'\n",{"type":12,"tag":21,"props":1004,"children":1005},{},[1006,1008,1013,1015,1021],{"type":18,"value":1007},"So the language gives us a way to know if a function was declared with the ",{"type":12,"tag":27,"props":1009,"children":1011},{"className":1010},[],[1012],{"type":18,"value":94},{"type":18,"value":1014}," modifier.\nIn some contrived scenario, we can imagine that it may be very useful to be able to check during runtime if the function will be asynchronous ",{"type":12,"tag":1016,"props":1017,"children":1018},"em",{},[1019],{"type":18,"value":1020},"before invoking it",{"type":18,"value":379},{"type":12,"tag":1023,"props":1024,"children":1025},"hr",{},[],{"type":12,"tag":1027,"props":1028,"children":1031},"section",{"className":1029,"dataFootnotes":5},[1030],"footnotes",[1032,1039],{"type":12,"tag":13,"props":1033,"children":1036},{"className":1034,"id":52},[1035],"sr-only",[1037],{"type":18,"value":1038},"Footnotes",{"type":12,"tag":1040,"props":1041,"children":1042},"ol",{},[1043],{"type":12,"tag":1044,"props":1045,"children":1047},"li",{"id":1046},"user-content-fn-1",[1048,1050,1056,1058],{"type":18,"value":1049},"Composability: ",{"type":12,"tag":27,"props":1051,"children":1053},{"className":1052},[],[1054],{"type":18,"value":1055},"fetchThing().then(doThing).catch(logError).finally(toFalse)",{"type":18,"value":1057}," ",{"type":12,"tag":48,"props":1059,"children":1064},{"href":1060,"ariaLabel":1061,"className":1062,"dataFootnoteBackref":5},"#user-content-fnref-1","Back to reference 1",[1063],"data-footnote-backref",[1065],{"type":18,"value":1066},"↩",{"type":12,"tag":1068,"props":1069,"children":1070},"style",{},[1071],{"type":18,"value":1072},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":5,"searchDepth":150,"depth":150,"links":1074},[1075,1080],{"id":15,"depth":150,"text":19,"children":1076},[1077,1078,1079],{"id":69,"depth":185,"text":72},{"id":499,"depth":185,"text":502},{"id":867,"depth":185,"text":870},{"id":52,"depth":150,"text":1038},"markdown","content:Ok, Sometimes Async-Await.md","content","Ok, Sometimes Async-Await.md","md",1717319595048] \ No newline at end of file diff --git a/ok-sometimes-async-await/index.html b/ok-sometimes-async-await/index.html index 6872a9c..10e6638 100644 --- a/ok-sometimes-async-await/index.html +++ b/ok-sometimes-async-await/index.html @@ -8,34 +8,34 @@ - - - - - - + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - -

    Ok, Sometimes Async-Await

    Normally, I continue believing that the classic (well, ES6) promise.then().catch().finally() is nicer than using the newer ES17 async-await syntax, because of function composability1. + + +


    Ok, Sometimes Async-Await

    Normally, I continue believing that the classic (well, ES6) promise.then().catch().finally() is nicer than using the newer ES17 async-await syntax, because of function composability1. There are 2 cases where I think async-await is neater, and one where it may perceivably come in handy:

    1. Early Return/Throwing Errors

    async function returnEarly(): Promise<SomeType | undefined> {
       if (someCondition) return;
       await networkRequest();
    @@ -63,5 +63,5 @@
     

    3? [object AsyncFunction]

    This does not generally strike me as useful, but can theoretically come in handy.

    Object.prototype.toString.call(async () => producePromise()); // '[object AsyncFunction]'
     Object.prototype.toString.call(() => producePromise()); // '[object Function]'
     

    So the language gives us a way to know if a function was declared with the async modifier. -In some contrived scenario, we can imagine that it may be very useful to be able to check during runtime if the function will be asynchronous before invoking it.


    Footnotes

    1. Composability: fetchThing().then(doThing).catch(logError).finally(toFalse)
    - \ No newline at end of file +In some contrived scenario, we can imagine that it may be very useful to be able to check during runtime if the function will be asynchronous before invoking it.


    Footnotes

    1. Composability: fetchThing().then(doThing).catch(logError).finally(toFalse)
    + \ No newline at end of file diff --git a/typescript-typesystems-and-javascript/_payload.json b/typescript-typesystems-and-javascript/_payload.json index d209a53..1cf88fb 100644 --- a/typescript-typesystems-and-javascript/_payload.json +++ b/typescript-typesystems-and-javascript/_payload.json @@ -1 +1 @@ -[{"data":1,"prerenderedAt":676},["Reactive",2],{"content-query-wWUOLP34KS":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":5,"title":7,"description":5,"body":8,"_type":671,"_id":672,"_source":673,"_file":674,"_extension":675},"/typescript-typesystems-and-javascript","",false,"TypeScript, TypeSystems And JavaScript",{"type":9,"children":10,"toc":662},"root",[11,20,27,33,49,54,60,65,160,165,210,215,256,279,368,373,379,393,398,487,492,497,503,508,558,589,603,626,632,646,656],{"type":12,"tag":13,"props":14,"children":16},"element","h2",{"id":15},"typescript-typesystems-and-javascript",[17],{"type":18,"value":19},"text","TypeScript, TypeSystems and JavaScript",{"type":12,"tag":21,"props":22,"children":24},"h3",{"id":23},"buzzwords",[25],{"type":18,"value":26},"Buzzwords",{"type":12,"tag":28,"props":29,"children":30},"p",{},[31],{"type":18,"value":32},"TypeScript (or “TS”) is a language built upon JavaScript (or “JS”), the primary (perhaps a vast, vast understatement) language used to program web applications. The term “built upon” is important here — TS is “strict superset” of JavaScript. This means that any valid JS program is also a valid TS program.",{"type":12,"tag":28,"props":34,"children":35},{},[36,38,47],{"type":18,"value":37},"TypeScript (or TS) first appeared 9 years ago, in 2012. It is written and maintained by Microsoft. It is now one of the ",{"type":12,"tag":39,"props":40,"children":44},"a",{"href":41,"rel":42},"https://venturebeat.com/2020/12/02/github-python-and-typescript-gain-popularity-among-programming-languages/",[43],"nofollow",[45],{"type":18,"value":46},"most popular",{"type":18,"value":48}," programming tools in the world. If TS were a startup company, early investors would be breaking out the champagne. Without exaggerating, I think most webdevs would agree with me in thinking that it won’t be long before “vanilla” JS will no longer be shipped in any new commercial product. For anything more than a personal/hobby project, JS will be constrained in TS shackles.",{"type":12,"tag":28,"props":50,"children":51},{},[52],{"type":18,"value":53},"If the last two paragraphs irritated you, you’re not alone — they irritate me as well, although true. Buzzwords cut through all articles promoting some library or another, and they make it impossible to make actual value judgements. Moreover, they distract the reader from actual trends and move the focus from concepts to products. If C# were to switch out Java in its inception, do we envision a vastly different developmental landscape in the 90s? I’d argue against that. Rather, Java and its viable alternatives heralded the well-known trend (and one of more popular religions) of Object Oriented Programming, or OOP.",{"type":12,"tag":21,"props":55,"children":57},{"id":56},"an-example",[58],{"type":18,"value":59},"An Example",{"type":12,"tag":28,"props":61,"children":62},{},[63],{"type":18,"value":64},"So, the following case for TypeScript is actually a general case for using a type system in JavaScript programming. TypeScript is just the current best-in-class (by a wide chasm), and an objectively excellent candidate for accomplishing this goal. Let’s examine a very simple function in JS:",{"type":12,"tag":66,"props":67,"children":71},"pre",{"className":68,"code":69,"language":70,"meta":5,"style":5},"language-javascript shiki shiki-themes synthwave-84","function multiply(x, y) {\n return x * y;\n}\n","javascript",[72],{"type":12,"tag":73,"props":74,"children":75},"code",{"__ignoreMap":5},[76,121,151],{"type":12,"tag":77,"props":78,"children":81},"span",{"class":79,"line":80},"line",1,[82,88,94,100,106,111,116],{"type":12,"tag":77,"props":83,"children":85},{"style":84},"--shiki-default:#FEDE5D",[86],{"type":18,"value":87},"function",{"type":12,"tag":77,"props":89,"children":91},{"style":90},"--shiki-default:#36F9F6",[92],{"type":18,"value":93}," multiply",{"type":12,"tag":77,"props":95,"children":97},{"style":96},"--shiki-default:#BBBBBB",[98],{"type":18,"value":99},"(",{"type":12,"tag":77,"props":101,"children":103},{"style":102},"--shiki-default:#FF7EDB;--shiki-default-font-style:italic",[104],{"type":18,"value":105},"x",{"type":12,"tag":77,"props":107,"children":108},{"style":96},[109],{"type":18,"value":110},", ",{"type":12,"tag":77,"props":112,"children":113},{"style":102},[114],{"type":18,"value":115},"y",{"type":12,"tag":77,"props":117,"children":118},{"style":96},[119],{"type":18,"value":120},") {\n",{"type":12,"tag":77,"props":122,"children":124},{"class":79,"line":123},2,[125,130,136,141,146],{"type":12,"tag":77,"props":126,"children":127},{"style":84},[128],{"type":18,"value":129}," return",{"type":12,"tag":77,"props":131,"children":133},{"style":132},"--shiki-default:#FF7EDB",[134],{"type":18,"value":135}," x",{"type":12,"tag":77,"props":137,"children":138},{"style":84},[139],{"type":18,"value":140}," *",{"type":12,"tag":77,"props":142,"children":143},{"style":132},[144],{"type":18,"value":145}," y",{"type":12,"tag":77,"props":147,"children":148},{"style":96},[149],{"type":18,"value":150},";\n",{"type":12,"tag":77,"props":152,"children":154},{"class":79,"line":153},3,[155],{"type":12,"tag":77,"props":156,"children":157},{"style":96},[158],{"type":18,"value":159},"}\n",{"type":12,"tag":28,"props":161,"children":162},{},[163],{"type":18,"value":164},"Let’s call this function:",{"type":12,"tag":66,"props":166,"children":168},{"className":68,"code":167,"language":70,"meta":5,"style":5},"multiply(2, 3); // = 6\n",[169],{"type":12,"tag":73,"props":170,"children":171},{"__ignoreMap":5},[172],{"type":12,"tag":77,"props":173,"children":174},{"class":79,"line":80},[175,180,184,190,194,199,204],{"type":12,"tag":77,"props":176,"children":177},{"style":90},[178],{"type":18,"value":179},"multiply",{"type":12,"tag":77,"props":181,"children":182},{"style":96},[183],{"type":18,"value":99},{"type":12,"tag":77,"props":185,"children":187},{"style":186},"--shiki-default:#2EE2FA",[188],{"type":18,"value":189},"2",{"type":12,"tag":77,"props":191,"children":192},{"style":96},[193],{"type":18,"value":110},{"type":12,"tag":77,"props":195,"children":196},{"style":186},[197],{"type":18,"value":198},"3",{"type":12,"tag":77,"props":200,"children":201},{"style":96},[202],{"type":18,"value":203},"); ",{"type":12,"tag":77,"props":205,"children":207},{"style":206},"--shiki-default:#848BBD;--shiki-default-font-style:italic",[208],{"type":18,"value":209},"// = 6\n",{"type":12,"tag":28,"props":211,"children":212},{},[213],{"type":18,"value":214},"So thats very nice. We have a function that multiplies two numbers. But let’s call it with a string:",{"type":12,"tag":66,"props":216,"children":218},{"className":68,"code":217,"language":70,"meta":5,"style":5},"multiply(2, \"hello\"); // = NaN\n",[219],{"type":12,"tag":73,"props":220,"children":221},{"__ignoreMap":5},[222],{"type":12,"tag":77,"props":223,"children":224},{"class":79,"line":80},[225,229,233,237,241,247,251],{"type":12,"tag":77,"props":226,"children":227},{"style":90},[228],{"type":18,"value":179},{"type":12,"tag":77,"props":230,"children":231},{"style":96},[232],{"type":18,"value":99},{"type":12,"tag":77,"props":234,"children":235},{"style":186},[236],{"type":18,"value":189},{"type":12,"tag":77,"props":238,"children":239},{"style":96},[240],{"type":18,"value":110},{"type":12,"tag":77,"props":242,"children":244},{"style":243},"--shiki-default:#FF8B39",[245],{"type":18,"value":246},"\"hello\"",{"type":12,"tag":77,"props":248,"children":249},{"style":96},[250],{"type":18,"value":203},{"type":12,"tag":77,"props":252,"children":253},{"style":206},[254],{"type":18,"value":255},"// = NaN\n",{"type":12,"tag":28,"props":257,"children":258},{},[259,261,268,270,277],{"type":18,"value":260},"This is obviously a nonsensical operation (although ",{"type":12,"tag":39,"props":262,"children":265},{"href":263,"rel":264},"https://www.pythoncentral.io/use-python-multiply-strings/",[43],[266],{"type":18,"value":267},"in Python",{"type":18,"value":269}," multiplying 2 by “hello” would return “hellohello”. This is adorable) — and we receive NaN, which is a special value in JS which means “not a number” (complying with the ",{"type":12,"tag":39,"props":271,"children":274},{"href":272,"rel":273},"https://en.wikipedia.org/wiki/NaN",[43],[275],{"type":18,"value":276},"IEEE 754 floating point standard",{"type":18,"value":278},"). So it was a syntactically legal operation, but I doubt anyone writing that function wants their function to be called with a string value. Accordingly, this function could be written in TS like this:",{"type":12,"tag":66,"props":280,"children":284},{"className":281,"code":282,"language":283,"meta":5,"style":5},"language-typescript shiki shiki-themes synthwave-84","function multiply(x: number, y: number) {\n return x * y;\n}\n","typescript",[285],{"type":12,"tag":73,"props":286,"children":287},{"__ignoreMap":5},[288,338,361],{"type":12,"tag":77,"props":289,"children":290},{"class":79,"line":80},[291,295,299,303,307,312,318,322,326,330,334],{"type":12,"tag":77,"props":292,"children":293},{"style":84},[294],{"type":18,"value":87},{"type":12,"tag":77,"props":296,"children":297},{"style":90},[298],{"type":18,"value":93},{"type":12,"tag":77,"props":300,"children":301},{"style":96},[302],{"type":18,"value":99},{"type":12,"tag":77,"props":304,"children":305},{"style":102},[306],{"type":18,"value":105},{"type":12,"tag":77,"props":308,"children":309},{"style":84},[310],{"type":18,"value":311},":",{"type":12,"tag":77,"props":313,"children":315},{"style":314},"--shiki-default:#FE4450",[316],{"type":18,"value":317}," number",{"type":12,"tag":77,"props":319,"children":320},{"style":96},[321],{"type":18,"value":110},{"type":12,"tag":77,"props":323,"children":324},{"style":102},[325],{"type":18,"value":115},{"type":12,"tag":77,"props":327,"children":328},{"style":84},[329],{"type":18,"value":311},{"type":12,"tag":77,"props":331,"children":332},{"style":314},[333],{"type":18,"value":317},{"type":12,"tag":77,"props":335,"children":336},{"style":96},[337],{"type":18,"value":120},{"type":12,"tag":77,"props":339,"children":340},{"class":79,"line":123},[341,345,349,353,357],{"type":12,"tag":77,"props":342,"children":343},{"style":84},[344],{"type":18,"value":129},{"type":12,"tag":77,"props":346,"children":347},{"style":132},[348],{"type":18,"value":135},{"type":12,"tag":77,"props":350,"children":351},{"style":84},[352],{"type":18,"value":140},{"type":12,"tag":77,"props":354,"children":355},{"style":132},[356],{"type":18,"value":145},{"type":12,"tag":77,"props":358,"children":359},{"style":96},[360],{"type":18,"value":150},{"type":12,"tag":77,"props":362,"children":363},{"class":79,"line":153},[364],{"type":12,"tag":77,"props":365,"children":366},{"style":96},[367],{"type":18,"value":159},{"type":12,"tag":28,"props":369,"children":370},{},[371],{"type":18,"value":372},"We’ve simply told TS that we don’t allow non number inputs to be given to the function. Now the second function call with the string value is illegal — TypeScript will yell at you and your editor will highlight it with red, mean squiggly lined until you change it, optionally forbidding you to ship your code until you do. This may seem annoying at first — you must sprinkle type hints all around the place for TS to be happy, and it will yell at you if you dont obey your own rules. Migrating most of my company’s codebase was a lesson in patience in that regard. But the effort pays off in compound down the road, and let’s examine why.",{"type":12,"tag":21,"props":374,"children":376},{"id":375},"so-what",[377],{"type":18,"value":378},"So What",{"type":12,"tag":28,"props":380,"children":381},{},[382,384,391],{"type":18,"value":383},"The ",{"type":12,"tag":39,"props":385,"children":388},{"href":386,"rel":387},"https://www.python.org/dev/peps/pep-0020/",[43],[389],{"type":18,"value":390},"Python zen",{"type":18,"value":392}," teaches us “Explicit is better than implicit” — users familiar with type systems (who are gawking at my “discovery” of a feature existing in languages for over 45 years) might think I’m invoking this rule for readability reasons — as in, any person reading my multiply function with type hints will know immediately that the inputs are 2 numbers. This is true (although, TS has very powerful type inference, such that in many cases you may leave off type hints). Another valid point would be the functionality aspect — as I’ve mentioned, calling multiply with “hello” is now impossible, which is a great thing.",{"type":12,"tag":28,"props":394,"children":395},{},[396],{"type":18,"value":397},"For me, though, the most compelling case for type systems is more conceptual. TS forces you to explicitly fill your programs with assertions that mirror your assumptions about the program. Let’s rewrite our multiplication function:",{"type":12,"tag":66,"props":399,"children":401},{"className":281,"code":400,"language":283,"meta":5,"style":5},"function fruitPrice(basePrice: number, quantity: number) {\n return basePrice * quantity;\n}\n",[402],{"type":12,"tag":73,"props":403,"children":404},{"__ignoreMap":5},[405,455,480],{"type":12,"tag":77,"props":406,"children":407},{"class":79,"line":80},[408,412,417,421,426,430,434,438,443,447,451],{"type":12,"tag":77,"props":409,"children":410},{"style":84},[411],{"type":18,"value":87},{"type":12,"tag":77,"props":413,"children":414},{"style":90},[415],{"type":18,"value":416}," fruitPrice",{"type":12,"tag":77,"props":418,"children":419},{"style":96},[420],{"type":18,"value":99},{"type":12,"tag":77,"props":422,"children":423},{"style":102},[424],{"type":18,"value":425},"basePrice",{"type":12,"tag":77,"props":427,"children":428},{"style":84},[429],{"type":18,"value":311},{"type":12,"tag":77,"props":431,"children":432},{"style":314},[433],{"type":18,"value":317},{"type":12,"tag":77,"props":435,"children":436},{"style":96},[437],{"type":18,"value":110},{"type":12,"tag":77,"props":439,"children":440},{"style":102},[441],{"type":18,"value":442},"quantity",{"type":12,"tag":77,"props":444,"children":445},{"style":84},[446],{"type":18,"value":311},{"type":12,"tag":77,"props":448,"children":449},{"style":314},[450],{"type":18,"value":317},{"type":12,"tag":77,"props":452,"children":453},{"style":96},[454],{"type":18,"value":120},{"type":12,"tag":77,"props":456,"children":457},{"class":79,"line":123},[458,462,467,471,476],{"type":12,"tag":77,"props":459,"children":460},{"style":84},[461],{"type":18,"value":129},{"type":12,"tag":77,"props":463,"children":464},{"style":132},[465],{"type":18,"value":466}," basePrice",{"type":12,"tag":77,"props":468,"children":469},{"style":84},[470],{"type":18,"value":140},{"type":12,"tag":77,"props":472,"children":473},{"style":132},[474],{"type":18,"value":475}," quantity",{"type":12,"tag":77,"props":477,"children":478},{"style":96},[479],{"type":18,"value":150},{"type":12,"tag":77,"props":481,"children":482},{"class":79,"line":153},[483],{"type":12,"tag":77,"props":484,"children":485},{"style":96},[486],{"type":18,"value":159},{"type":12,"tag":28,"props":488,"children":489},{},[490],{"type":18,"value":491},"This function works great in dev with mock data, we receive the price of fruit from the server and the quantity from the client. Before pushing to production, the backend dev tells us that due to new architecture decisions, the price of certain fruit may be undetermined — now we may receive null, or an empty string when asking for the price of a fruit. Now when I call the price function with this new value, which may be undefined or a number, TypeScript yells because it know I am passing in a value which may not be a legal number.",{"type":12,"tag":28,"props":493,"children":494},{},[495],{"type":18,"value":496},"Again, this is great — my function would fail without a rewrite. But the real lesson I can take from the squiggly lines is about my assumptions. TS punishes you for a lenient or thoughtlessly written piece of code — it forces you to reexamine what you think the program actually does. So fruitPrice will undoubtedly have to change, but now you know where you casually gave yourself a break by assuming a stricter subset of input than in reality. Now you know your program must take an undetermined price into account. TS will selflessly tell you where this assumption is relevant, but the real takeaway is forcing you to more strictly define your program.",{"type":12,"tag":21,"props":498,"children":500},{"id":499},"but-typescript-though",[501],{"type":18,"value":502},"But TypeScript, Though",{"type":12,"tag":28,"props":504,"children":505},{},[506],{"type":18,"value":507},"Something must be said about the tool in order to encourage its’ use, aside from touting the general benefits of a type system. So why TS, after all?",{"type":12,"tag":28,"props":509,"children":510},{},[511,513,520,522,529,531,538,540,547,549,556],{"type":18,"value":512},"From a maintenance perspective, TS is, as mentioned, maintained by Microsoft. There are constant releases fixing bugs and meeting performance goals. New features are great, but really a dev needs to know that the project won’t ",{"type":12,"tag":39,"props":514,"children":517},{"href":515,"rel":516},"https://www.theregister.com/2020/03/26/corejs_maintainer_jailed_code_release/",[43],[518],{"type":18,"value":519},"collapse",{"type":18,"value":521}," because of a dangerous dependency on a small team’s free time, and that the project won’t be ",{"type":12,"tag":39,"props":523,"children":526},{"href":524,"rel":525},"https://en.wikipedia.org/wiki/CoffeeScript",[43],[527],{"type":18,"value":528},"forgotten",{"type":18,"value":530}," after a swift period of adoption. There are no guarantees, obviously, and no project lasts forever. But, for now, it seems like the buzzword period is mostly over — and the aftermath is major ",{"type":12,"tag":39,"props":532,"children":535},{"href":533,"rel":534},"https://angular.io/guide/typescript-configuration",[43],[536],{"type":18,"value":537},"libraries",{"type":18,"value":539}," and ",{"type":12,"tag":39,"props":541,"children":544},{"href":542,"rel":543},"https://deno.land/",[43],[545],{"type":18,"value":546},"technologies",{"type":18,"value":548}," have adopted TS, or ",{"type":12,"tag":39,"props":550,"children":553},{"href":551,"rel":552},"https://reactjs.org/docs/static-type-checking.html#typescript",[43],[554],{"type":18,"value":555},"at least actively maintain type declaration files and tooling",{"type":18,"value":557}," for consumers. Bet on TypeScript.",{"type":12,"tag":28,"props":559,"children":560},{},[561,563,570,572,579,580,587],{"type":18,"value":562},"I think one of the reasons for TS’s steady success is its’ core product — type systems for JS. It has cultivated many features that were eventually swallowed into vanilla JS — ",{"type":12,"tag":39,"props":564,"children":567},{"href":565,"rel":566},"https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining",[43],[568],{"type":18,"value":569},"optional chaining",{"type":18,"value":571},", what seems like ",{"type":12,"tag":39,"props":573,"children":576},{"href":574,"rel":575},"https://www.typescriptlang.org/docs/handbook/classes.html",[43],[577],{"type":18,"value":578},"direct inspiration for JS es2015 classes",{"type":18,"value":110},{"type":12,"tag":39,"props":581,"children":584},{"href":582,"rel":583},"https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#nullish-coalescing",[43],[585],{"type":18,"value":586},"nullish coalescing",{"type":18,"value":588}," etc. But really, the main feature which browsers cannot adopt is the type system — JS is inherently dynamic, and a type system is a radical change browsers cannot simply add in. So by not competing with juggernaut browsers over its’ main feature, it can prevail safely without fearing a sudden hostile takeover.",{"type":12,"tag":28,"props":590,"children":591},{},[592,594,601],{"type":18,"value":593},"From a non maintenance perspective, TS has built its’ type system around widely used JS patterns. One example is that the TS type system is ",{"type":12,"tag":39,"props":595,"children":598},{"href":596,"rel":597},"https://en.wikipedia.org/wiki/Structural_type_system",[43],[599],{"type":18,"value":600},"structural",{"type":18,"value":602}," rather than nominal — basically, that one value is equivalent to another if it shares the structure of the other value. For example, a function that recieves { a: number; } as an argument, will also accept { a: number; b: number; } — the second type can be treated as the first type for all intents and purposes that the first type is used for in the function.",{"type":12,"tag":28,"props":604,"children":605},{},[606,608,615,617,624],{"type":18,"value":607},"In many other type systems, types can act in for other types only if an explicit (=nominal) relationship was tied between them, such as inheritance. A structural type system fits the JS pattern of constant usage of anonynous objects and values (including functions), without explicitly calling constructors and so forth. Forcing nonimal typing on existing JS code would change the style and patterns devs are used to. This is not the only advantage to a structural type system, but it illustrates the thinking behind the language design. For more on the unique fit between TS and JS (I didn’t even touch on the functional aspect), I strongly recommend watching ",{"type":12,"tag":39,"props":609,"children":612},{"href":610,"rel":611},"https://www.youtube.com/watch?v=jmPZztKIFf4",[43],[613],{"type":18,"value":614},"this talk",{"type":18,"value":616}," by ",{"type":12,"tag":39,"props":618,"children":621},{"href":619,"rel":620},"https://en.wikipedia.org/wiki/Anders_Hejlsberg",[43],[622],{"type":18,"value":623},"Anders Hejlsberg",{"type":18,"value":625},".",{"type":12,"tag":21,"props":627,"children":629},{"id":628},"giving-the-web-context",[630],{"type":18,"value":631},"Giving the Web Context",{"type":12,"tag":28,"props":633,"children":634},{},[635,637,644],{"type":18,"value":636},"In a final note, moving this text from notepad to an actual text editor with a spellchecker has shamefully revealed many squiggly lines, red, blue and green. In an imperfect analogy, JS editors have long had red lines for syntax errors (a.k.a. spelling mistakes). TS is more than a library, as it introduces a feature entirely impossible in current JS — green and blue squiggly lines, for contextual and grammatical errors. Suddenly my programs are more than blocks of black text, they speak to me and challenge my assumptions. So while we roll in the ",{"type":12,"tag":39,"props":638,"children":641},{"href":639,"rel":640},"https://insights.stackoverflow.com/survey/2020#technology-what-languages-are-associated-with-the-highest-salaries-worldwide",[43],[642],{"type":18,"value":643},"slim surplus of cash",{"type":18,"value":645}," we supposedly make by writing TS over plain JS, let’s all collectively move our programs from notepad to a text editor.",{"type":12,"tag":28,"props":647,"children":648},{},[649],{"type":12,"tag":39,"props":650,"children":653},{"href":651,"rel":652},"https://medium.com/@netanel.t.haber/typescript-typesystems-and-javascript-83153f249ce3?source=post_page-----83153f249ce3--------------------------------",[43],[654],{"type":18,"value":655},"Originally published on February 27, 2021, on Medium",{"type":12,"tag":657,"props":658,"children":659},"style",{},[660],{"type":18,"value":661},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":5,"searchDepth":123,"depth":123,"links":663},[664],{"id":15,"depth":123,"text":19,"children":665},[666,667,668,669,670],{"id":23,"depth":153,"text":26},{"id":56,"depth":153,"text":59},{"id":375,"depth":153,"text":378},{"id":499,"depth":153,"text":502},{"id":628,"depth":153,"text":631},"markdown","content:TypeScript, TypeSystems and JavaScript.md","content","TypeScript, TypeSystems and JavaScript.md","md",1717319129438] \ No newline at end of file +[{"data":1,"prerenderedAt":676},["Reactive",2],{"content-query-wWUOLP34KS":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":5,"title":7,"description":5,"body":8,"_type":671,"_id":672,"_source":673,"_file":674,"_extension":675},"/typescript-typesystems-and-javascript","",false,"TypeScript, TypeSystems And JavaScript",{"type":9,"children":10,"toc":662},"root",[11,20,27,33,49,54,60,65,160,165,210,215,256,279,368,373,379,393,398,487,492,497,503,508,558,589,603,626,632,646,656],{"type":12,"tag":13,"props":14,"children":16},"element","h2",{"id":15},"typescript-typesystems-and-javascript",[17],{"type":18,"value":19},"text","TypeScript, TypeSystems and JavaScript",{"type":12,"tag":21,"props":22,"children":24},"h3",{"id":23},"buzzwords",[25],{"type":18,"value":26},"Buzzwords",{"type":12,"tag":28,"props":29,"children":30},"p",{},[31],{"type":18,"value":32},"TypeScript (or “TS”) is a language built upon JavaScript (or “JS”), the primary (perhaps a vast, vast understatement) language used to program web applications. The term “built upon” is important here — TS is “strict superset” of JavaScript. This means that any valid JS program is also a valid TS program.",{"type":12,"tag":28,"props":34,"children":35},{},[36,38,47],{"type":18,"value":37},"TypeScript (or TS) first appeared 9 years ago, in 2012. It is written and maintained by Microsoft. It is now one of the ",{"type":12,"tag":39,"props":40,"children":44},"a",{"href":41,"rel":42},"https://venturebeat.com/2020/12/02/github-python-and-typescript-gain-popularity-among-programming-languages/",[43],"nofollow",[45],{"type":18,"value":46},"most popular",{"type":18,"value":48}," programming tools in the world. If TS were a startup company, early investors would be breaking out the champagne. Without exaggerating, I think most webdevs would agree with me in thinking that it won’t be long before “vanilla” JS will no longer be shipped in any new commercial product. For anything more than a personal/hobby project, JS will be constrained in TS shackles.",{"type":12,"tag":28,"props":50,"children":51},{},[52],{"type":18,"value":53},"If the last two paragraphs irritated you, you’re not alone — they irritate me as well, although true. Buzzwords cut through all articles promoting some library or another, and they make it impossible to make actual value judgements. Moreover, they distract the reader from actual trends and move the focus from concepts to products. If C# were to switch out Java in its inception, do we envision a vastly different developmental landscape in the 90s? I’d argue against that. Rather, Java and its viable alternatives heralded the well-known trend (and one of more popular religions) of Object Oriented Programming, or OOP.",{"type":12,"tag":21,"props":55,"children":57},{"id":56},"an-example",[58],{"type":18,"value":59},"An Example",{"type":12,"tag":28,"props":61,"children":62},{},[63],{"type":18,"value":64},"So, the following case for TypeScript is actually a general case for using a type system in JavaScript programming. TypeScript is just the current best-in-class (by a wide chasm), and an objectively excellent candidate for accomplishing this goal. Let’s examine a very simple function in JS:",{"type":12,"tag":66,"props":67,"children":71},"pre",{"className":68,"code":69,"language":70,"meta":5,"style":5},"language-javascript shiki shiki-themes synthwave-84","function multiply(x, y) {\n return x * y;\n}\n","javascript",[72],{"type":12,"tag":73,"props":74,"children":75},"code",{"__ignoreMap":5},[76,121,151],{"type":12,"tag":77,"props":78,"children":81},"span",{"class":79,"line":80},"line",1,[82,88,94,100,106,111,116],{"type":12,"tag":77,"props":83,"children":85},{"style":84},"--shiki-default:#FEDE5D",[86],{"type":18,"value":87},"function",{"type":12,"tag":77,"props":89,"children":91},{"style":90},"--shiki-default:#36F9F6",[92],{"type":18,"value":93}," multiply",{"type":12,"tag":77,"props":95,"children":97},{"style":96},"--shiki-default:#BBBBBB",[98],{"type":18,"value":99},"(",{"type":12,"tag":77,"props":101,"children":103},{"style":102},"--shiki-default:#FF7EDB;--shiki-default-font-style:italic",[104],{"type":18,"value":105},"x",{"type":12,"tag":77,"props":107,"children":108},{"style":96},[109],{"type":18,"value":110},", ",{"type":12,"tag":77,"props":112,"children":113},{"style":102},[114],{"type":18,"value":115},"y",{"type":12,"tag":77,"props":117,"children":118},{"style":96},[119],{"type":18,"value":120},") {\n",{"type":12,"tag":77,"props":122,"children":124},{"class":79,"line":123},2,[125,130,136,141,146],{"type":12,"tag":77,"props":126,"children":127},{"style":84},[128],{"type":18,"value":129}," return",{"type":12,"tag":77,"props":131,"children":133},{"style":132},"--shiki-default:#FF7EDB",[134],{"type":18,"value":135}," x",{"type":12,"tag":77,"props":137,"children":138},{"style":84},[139],{"type":18,"value":140}," *",{"type":12,"tag":77,"props":142,"children":143},{"style":132},[144],{"type":18,"value":145}," y",{"type":12,"tag":77,"props":147,"children":148},{"style":96},[149],{"type":18,"value":150},";\n",{"type":12,"tag":77,"props":152,"children":154},{"class":79,"line":153},3,[155],{"type":12,"tag":77,"props":156,"children":157},{"style":96},[158],{"type":18,"value":159},"}\n",{"type":12,"tag":28,"props":161,"children":162},{},[163],{"type":18,"value":164},"Let’s call this function:",{"type":12,"tag":66,"props":166,"children":168},{"className":68,"code":167,"language":70,"meta":5,"style":5},"multiply(2, 3); // = 6\n",[169],{"type":12,"tag":73,"props":170,"children":171},{"__ignoreMap":5},[172],{"type":12,"tag":77,"props":173,"children":174},{"class":79,"line":80},[175,180,184,190,194,199,204],{"type":12,"tag":77,"props":176,"children":177},{"style":90},[178],{"type":18,"value":179},"multiply",{"type":12,"tag":77,"props":181,"children":182},{"style":96},[183],{"type":18,"value":99},{"type":12,"tag":77,"props":185,"children":187},{"style":186},"--shiki-default:#2EE2FA",[188],{"type":18,"value":189},"2",{"type":12,"tag":77,"props":191,"children":192},{"style":96},[193],{"type":18,"value":110},{"type":12,"tag":77,"props":195,"children":196},{"style":186},[197],{"type":18,"value":198},"3",{"type":12,"tag":77,"props":200,"children":201},{"style":96},[202],{"type":18,"value":203},"); ",{"type":12,"tag":77,"props":205,"children":207},{"style":206},"--shiki-default:#848BBD;--shiki-default-font-style:italic",[208],{"type":18,"value":209},"// = 6\n",{"type":12,"tag":28,"props":211,"children":212},{},[213],{"type":18,"value":214},"So thats very nice. We have a function that multiplies two numbers. But let’s call it with a string:",{"type":12,"tag":66,"props":216,"children":218},{"className":68,"code":217,"language":70,"meta":5,"style":5},"multiply(2, \"hello\"); // = NaN\n",[219],{"type":12,"tag":73,"props":220,"children":221},{"__ignoreMap":5},[222],{"type":12,"tag":77,"props":223,"children":224},{"class":79,"line":80},[225,229,233,237,241,247,251],{"type":12,"tag":77,"props":226,"children":227},{"style":90},[228],{"type":18,"value":179},{"type":12,"tag":77,"props":230,"children":231},{"style":96},[232],{"type":18,"value":99},{"type":12,"tag":77,"props":234,"children":235},{"style":186},[236],{"type":18,"value":189},{"type":12,"tag":77,"props":238,"children":239},{"style":96},[240],{"type":18,"value":110},{"type":12,"tag":77,"props":242,"children":244},{"style":243},"--shiki-default:#FF8B39",[245],{"type":18,"value":246},"\"hello\"",{"type":12,"tag":77,"props":248,"children":249},{"style":96},[250],{"type":18,"value":203},{"type":12,"tag":77,"props":252,"children":253},{"style":206},[254],{"type":18,"value":255},"// = NaN\n",{"type":12,"tag":28,"props":257,"children":258},{},[259,261,268,270,277],{"type":18,"value":260},"This is obviously a nonsensical operation (although ",{"type":12,"tag":39,"props":262,"children":265},{"href":263,"rel":264},"https://www.pythoncentral.io/use-python-multiply-strings/",[43],[266],{"type":18,"value":267},"in Python",{"type":18,"value":269}," multiplying 2 by “hello” would return “hellohello”. This is adorable) — and we receive NaN, which is a special value in JS which means “not a number” (complying with the ",{"type":12,"tag":39,"props":271,"children":274},{"href":272,"rel":273},"https://en.wikipedia.org/wiki/NaN",[43],[275],{"type":18,"value":276},"IEEE 754 floating point standard",{"type":18,"value":278},"). So it was a syntactically legal operation, but I doubt anyone writing that function wants their function to be called with a string value. Accordingly, this function could be written in TS like this:",{"type":12,"tag":66,"props":280,"children":284},{"className":281,"code":282,"language":283,"meta":5,"style":5},"language-typescript shiki shiki-themes synthwave-84","function multiply(x: number, y: number) {\n return x * y;\n}\n","typescript",[285],{"type":12,"tag":73,"props":286,"children":287},{"__ignoreMap":5},[288,338,361],{"type":12,"tag":77,"props":289,"children":290},{"class":79,"line":80},[291,295,299,303,307,312,318,322,326,330,334],{"type":12,"tag":77,"props":292,"children":293},{"style":84},[294],{"type":18,"value":87},{"type":12,"tag":77,"props":296,"children":297},{"style":90},[298],{"type":18,"value":93},{"type":12,"tag":77,"props":300,"children":301},{"style":96},[302],{"type":18,"value":99},{"type":12,"tag":77,"props":304,"children":305},{"style":102},[306],{"type":18,"value":105},{"type":12,"tag":77,"props":308,"children":309},{"style":84},[310],{"type":18,"value":311},":",{"type":12,"tag":77,"props":313,"children":315},{"style":314},"--shiki-default:#FE4450",[316],{"type":18,"value":317}," number",{"type":12,"tag":77,"props":319,"children":320},{"style":96},[321],{"type":18,"value":110},{"type":12,"tag":77,"props":323,"children":324},{"style":102},[325],{"type":18,"value":115},{"type":12,"tag":77,"props":327,"children":328},{"style":84},[329],{"type":18,"value":311},{"type":12,"tag":77,"props":331,"children":332},{"style":314},[333],{"type":18,"value":317},{"type":12,"tag":77,"props":335,"children":336},{"style":96},[337],{"type":18,"value":120},{"type":12,"tag":77,"props":339,"children":340},{"class":79,"line":123},[341,345,349,353,357],{"type":12,"tag":77,"props":342,"children":343},{"style":84},[344],{"type":18,"value":129},{"type":12,"tag":77,"props":346,"children":347},{"style":132},[348],{"type":18,"value":135},{"type":12,"tag":77,"props":350,"children":351},{"style":84},[352],{"type":18,"value":140},{"type":12,"tag":77,"props":354,"children":355},{"style":132},[356],{"type":18,"value":145},{"type":12,"tag":77,"props":358,"children":359},{"style":96},[360],{"type":18,"value":150},{"type":12,"tag":77,"props":362,"children":363},{"class":79,"line":153},[364],{"type":12,"tag":77,"props":365,"children":366},{"style":96},[367],{"type":18,"value":159},{"type":12,"tag":28,"props":369,"children":370},{},[371],{"type":18,"value":372},"We’ve simply told TS that we don’t allow non number inputs to be given to the function. Now the second function call with the string value is illegal — TypeScript will yell at you and your editor will highlight it with red, mean squiggly lined until you change it, optionally forbidding you to ship your code until you do. This may seem annoying at first — you must sprinkle type hints all around the place for TS to be happy, and it will yell at you if you dont obey your own rules. Migrating most of my company’s codebase was a lesson in patience in that regard. But the effort pays off in compound down the road, and let’s examine why.",{"type":12,"tag":21,"props":374,"children":376},{"id":375},"so-what",[377],{"type":18,"value":378},"So What",{"type":12,"tag":28,"props":380,"children":381},{},[382,384,391],{"type":18,"value":383},"The ",{"type":12,"tag":39,"props":385,"children":388},{"href":386,"rel":387},"https://www.python.org/dev/peps/pep-0020/",[43],[389],{"type":18,"value":390},"Python zen",{"type":18,"value":392}," teaches us “Explicit is better than implicit” — users familiar with type systems (who are gawking at my “discovery” of a feature existing in languages for over 45 years) might think I’m invoking this rule for readability reasons — as in, any person reading my multiply function with type hints will know immediately that the inputs are 2 numbers. This is true (although, TS has very powerful type inference, such that in many cases you may leave off type hints). Another valid point would be the functionality aspect — as I’ve mentioned, calling multiply with “hello” is now impossible, which is a great thing.",{"type":12,"tag":28,"props":394,"children":395},{},[396],{"type":18,"value":397},"For me, though, the most compelling case for type systems is more conceptual. TS forces you to explicitly fill your programs with assertions that mirror your assumptions about the program. Let’s rewrite our multiplication function:",{"type":12,"tag":66,"props":399,"children":401},{"className":281,"code":400,"language":283,"meta":5,"style":5},"function fruitPrice(basePrice: number, quantity: number) {\n return basePrice * quantity;\n}\n",[402],{"type":12,"tag":73,"props":403,"children":404},{"__ignoreMap":5},[405,455,480],{"type":12,"tag":77,"props":406,"children":407},{"class":79,"line":80},[408,412,417,421,426,430,434,438,443,447,451],{"type":12,"tag":77,"props":409,"children":410},{"style":84},[411],{"type":18,"value":87},{"type":12,"tag":77,"props":413,"children":414},{"style":90},[415],{"type":18,"value":416}," fruitPrice",{"type":12,"tag":77,"props":418,"children":419},{"style":96},[420],{"type":18,"value":99},{"type":12,"tag":77,"props":422,"children":423},{"style":102},[424],{"type":18,"value":425},"basePrice",{"type":12,"tag":77,"props":427,"children":428},{"style":84},[429],{"type":18,"value":311},{"type":12,"tag":77,"props":431,"children":432},{"style":314},[433],{"type":18,"value":317},{"type":12,"tag":77,"props":435,"children":436},{"style":96},[437],{"type":18,"value":110},{"type":12,"tag":77,"props":439,"children":440},{"style":102},[441],{"type":18,"value":442},"quantity",{"type":12,"tag":77,"props":444,"children":445},{"style":84},[446],{"type":18,"value":311},{"type":12,"tag":77,"props":448,"children":449},{"style":314},[450],{"type":18,"value":317},{"type":12,"tag":77,"props":452,"children":453},{"style":96},[454],{"type":18,"value":120},{"type":12,"tag":77,"props":456,"children":457},{"class":79,"line":123},[458,462,467,471,476],{"type":12,"tag":77,"props":459,"children":460},{"style":84},[461],{"type":18,"value":129},{"type":12,"tag":77,"props":463,"children":464},{"style":132},[465],{"type":18,"value":466}," basePrice",{"type":12,"tag":77,"props":468,"children":469},{"style":84},[470],{"type":18,"value":140},{"type":12,"tag":77,"props":472,"children":473},{"style":132},[474],{"type":18,"value":475}," quantity",{"type":12,"tag":77,"props":477,"children":478},{"style":96},[479],{"type":18,"value":150},{"type":12,"tag":77,"props":481,"children":482},{"class":79,"line":153},[483],{"type":12,"tag":77,"props":484,"children":485},{"style":96},[486],{"type":18,"value":159},{"type":12,"tag":28,"props":488,"children":489},{},[490],{"type":18,"value":491},"This function works great in dev with mock data, we receive the price of fruit from the server and the quantity from the client. Before pushing to production, the backend dev tells us that due to new architecture decisions, the price of certain fruit may be undetermined — now we may receive null, or an empty string when asking for the price of a fruit. Now when I call the price function with this new value, which may be undefined or a number, TypeScript yells because it know I am passing in a value which may not be a legal number.",{"type":12,"tag":28,"props":493,"children":494},{},[495],{"type":18,"value":496},"Again, this is great — my function would fail without a rewrite. But the real lesson I can take from the squiggly lines is about my assumptions. TS punishes you for a lenient or thoughtlessly written piece of code — it forces you to reexamine what you think the program actually does. So fruitPrice will undoubtedly have to change, but now you know where you casually gave yourself a break by assuming a stricter subset of input than in reality. Now you know your program must take an undetermined price into account. TS will selflessly tell you where this assumption is relevant, but the real takeaway is forcing you to more strictly define your program.",{"type":12,"tag":21,"props":498,"children":500},{"id":499},"but-typescript-though",[501],{"type":18,"value":502},"But TypeScript, Though",{"type":12,"tag":28,"props":504,"children":505},{},[506],{"type":18,"value":507},"Something must be said about the tool in order to encourage its’ use, aside from touting the general benefits of a type system. So why TS, after all?",{"type":12,"tag":28,"props":509,"children":510},{},[511,513,520,522,529,531,538,540,547,549,556],{"type":18,"value":512},"From a maintenance perspective, TS is, as mentioned, maintained by Microsoft. There are constant releases fixing bugs and meeting performance goals. New features are great, but really a dev needs to know that the project won’t ",{"type":12,"tag":39,"props":514,"children":517},{"href":515,"rel":516},"https://www.theregister.com/2020/03/26/corejs_maintainer_jailed_code_release/",[43],[518],{"type":18,"value":519},"collapse",{"type":18,"value":521}," because of a dangerous dependency on a small team’s free time, and that the project won’t be ",{"type":12,"tag":39,"props":523,"children":526},{"href":524,"rel":525},"https://en.wikipedia.org/wiki/CoffeeScript",[43],[527],{"type":18,"value":528},"forgotten",{"type":18,"value":530}," after a swift period of adoption. There are no guarantees, obviously, and no project lasts forever. But, for now, it seems like the buzzword period is mostly over — and the aftermath is major ",{"type":12,"tag":39,"props":532,"children":535},{"href":533,"rel":534},"https://angular.io/guide/typescript-configuration",[43],[536],{"type":18,"value":537},"libraries",{"type":18,"value":539}," and ",{"type":12,"tag":39,"props":541,"children":544},{"href":542,"rel":543},"https://deno.land/",[43],[545],{"type":18,"value":546},"technologies",{"type":18,"value":548}," have adopted TS, or ",{"type":12,"tag":39,"props":550,"children":553},{"href":551,"rel":552},"https://reactjs.org/docs/static-type-checking.html#typescript",[43],[554],{"type":18,"value":555},"at least actively maintain type declaration files and tooling",{"type":18,"value":557}," for consumers. Bet on TypeScript.",{"type":12,"tag":28,"props":559,"children":560},{},[561,563,570,572,579,580,587],{"type":18,"value":562},"I think one of the reasons for TS’s steady success is its’ core product — type systems for JS. It has cultivated many features that were eventually swallowed into vanilla JS — ",{"type":12,"tag":39,"props":564,"children":567},{"href":565,"rel":566},"https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining",[43],[568],{"type":18,"value":569},"optional chaining",{"type":18,"value":571},", what seems like ",{"type":12,"tag":39,"props":573,"children":576},{"href":574,"rel":575},"https://www.typescriptlang.org/docs/handbook/classes.html",[43],[577],{"type":18,"value":578},"direct inspiration for JS es2015 classes",{"type":18,"value":110},{"type":12,"tag":39,"props":581,"children":584},{"href":582,"rel":583},"https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#nullish-coalescing",[43],[585],{"type":18,"value":586},"nullish coalescing",{"type":18,"value":588}," etc. But really, the main feature which browsers cannot adopt is the type system — JS is inherently dynamic, and a type system is a radical change browsers cannot simply add in. So by not competing with juggernaut browsers over its’ main feature, it can prevail safely without fearing a sudden hostile takeover.",{"type":12,"tag":28,"props":590,"children":591},{},[592,594,601],{"type":18,"value":593},"From a non maintenance perspective, TS has built its’ type system around widely used JS patterns. One example is that the TS type system is ",{"type":12,"tag":39,"props":595,"children":598},{"href":596,"rel":597},"https://en.wikipedia.org/wiki/Structural_type_system",[43],[599],{"type":18,"value":600},"structural",{"type":18,"value":602}," rather than nominal — basically, that one value is equivalent to another if it shares the structure of the other value. For example, a function that recieves { a: number; } as an argument, will also accept { a: number; b: number; } — the second type can be treated as the first type for all intents and purposes that the first type is used for in the function.",{"type":12,"tag":28,"props":604,"children":605},{},[606,608,615,617,624],{"type":18,"value":607},"In many other type systems, types can act in for other types only if an explicit (=nominal) relationship was tied between them, such as inheritance. A structural type system fits the JS pattern of constant usage of anonynous objects and values (including functions), without explicitly calling constructors and so forth. Forcing nonimal typing on existing JS code would change the style and patterns devs are used to. This is not the only advantage to a structural type system, but it illustrates the thinking behind the language design. For more on the unique fit between TS and JS (I didn’t even touch on the functional aspect), I strongly recommend watching ",{"type":12,"tag":39,"props":609,"children":612},{"href":610,"rel":611},"https://www.youtube.com/watch?v=jmPZztKIFf4",[43],[613],{"type":18,"value":614},"this talk",{"type":18,"value":616}," by ",{"type":12,"tag":39,"props":618,"children":621},{"href":619,"rel":620},"https://en.wikipedia.org/wiki/Anders_Hejlsberg",[43],[622],{"type":18,"value":623},"Anders Hejlsberg",{"type":18,"value":625},".",{"type":12,"tag":21,"props":627,"children":629},{"id":628},"giving-the-web-context",[630],{"type":18,"value":631},"Giving the Web Context",{"type":12,"tag":28,"props":633,"children":634},{},[635,637,644],{"type":18,"value":636},"In a final note, moving this text from notepad to an actual text editor with a spellchecker has shamefully revealed many squiggly lines, red, blue and green. In an imperfect analogy, JS editors have long had red lines for syntax errors (a.k.a. spelling mistakes). TS is more than a library, as it introduces a feature entirely impossible in current JS — green and blue squiggly lines, for contextual and grammatical errors. Suddenly my programs are more than blocks of black text, they speak to me and challenge my assumptions. So while we roll in the ",{"type":12,"tag":39,"props":638,"children":641},{"href":639,"rel":640},"https://insights.stackoverflow.com/survey/2020#technology-what-languages-are-associated-with-the-highest-salaries-worldwide",[43],[642],{"type":18,"value":643},"slim surplus of cash",{"type":18,"value":645}," we supposedly make by writing TS over plain JS, let’s all collectively move our programs from notepad to a text editor.",{"type":12,"tag":28,"props":647,"children":648},{},[649],{"type":12,"tag":39,"props":650,"children":653},{"href":651,"rel":652},"https://medium.com/@netanel.t.haber/typescript-typesystems-and-javascript-83153f249ce3?source=post_page-----83153f249ce3--------------------------------",[43],[654],{"type":18,"value":655},"Originally published on February 27, 2021, on Medium",{"type":12,"tag":657,"props":658,"children":659},"style",{},[660],{"type":18,"value":661},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":5,"searchDepth":123,"depth":123,"links":663},[664],{"id":15,"depth":123,"text":19,"children":665},[666,667,668,669,670],{"id":23,"depth":153,"text":26},{"id":56,"depth":153,"text":59},{"id":375,"depth":153,"text":378},{"id":499,"depth":153,"text":502},{"id":628,"depth":153,"text":631},"markdown","content:TypeScript, TypeSystems and JavaScript.md","content","TypeScript, TypeSystems and JavaScript.md","md",1717319595051] \ No newline at end of file diff --git a/typescript-typesystems-and-javascript/index.html b/typescript-typesystems-and-javascript/index.html index 2e6eb6d..cd32857 100644 --- a/typescript-typesystems-and-javascript/index.html +++ b/typescript-typesystems-and-javascript/index.html @@ -8,28 +8,28 @@ - - - - - - + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - -

    TypeScript, TypeSystems and JavaScript

    Buzzwords

    TypeScript (or “TS”) is a language built upon JavaScript (or “JS”), the primary (perhaps a vast, vast understatement) language used to program web applications. The term “built upon” is important here — TS is “strict superset” of JavaScript. This means that any valid JS program is also a valid TS program.

    TypeScript (or TS) first appeared 9 years ago, in 2012. It is written and maintained by Microsoft. It is now one of the most popular programming tools in the world. If TS were a startup company, early investors would be breaking out the champagne. Without exaggerating, I think most webdevs would agree with me in thinking that it won’t be long before “vanilla” JS will no longer be shipped in any new commercial product. For anything more than a personal/hobby project, JS will be constrained in TS shackles.

    If the last two paragraphs irritated you, you’re not alone — they irritate me as well, although true. Buzzwords cut through all articles promoting some library or another, and they make it impossible to make actual value judgements. Moreover, they distract the reader from actual trends and move the focus from concepts to products. If C# were to switch out Java in its inception, do we envision a vastly different developmental landscape in the 90s? I’d argue against that. Rather, Java and its viable alternatives heralded the well-known trend (and one of more popular religions) of Object Oriented Programming, or OOP.

    An Example

    So, the following case for TypeScript is actually a general case for using a type system in JavaScript programming. TypeScript is just the current best-in-class (by a wide chasm), and an objectively excellent candidate for accomplishing this goal. Let’s examine a very simple function in JS:

    function multiply(x, y) {
    +
    +
    +

    TypeScript, TypeSystems and JavaScript

    Buzzwords

    TypeScript (or “TS”) is a language built upon JavaScript (or “JS”), the primary (perhaps a vast, vast understatement) language used to program web applications. The term “built upon” is important here — TS is “strict superset” of JavaScript. This means that any valid JS program is also a valid TS program.

    TypeScript (or TS) first appeared 9 years ago, in 2012. It is written and maintained by Microsoft. It is now one of the most popular programming tools in the world. If TS were a startup company, early investors would be breaking out the champagne. Without exaggerating, I think most webdevs would agree with me in thinking that it won’t be long before “vanilla” JS will no longer be shipped in any new commercial product. For anything more than a personal/hobby project, JS will be constrained in TS shackles.

    If the last two paragraphs irritated you, you’re not alone — they irritate me as well, although true. Buzzwords cut through all articles promoting some library or another, and they make it impossible to make actual value judgements. Moreover, they distract the reader from actual trends and move the focus from concepts to products. If C# were to switch out Java in its inception, do we envision a vastly different developmental landscape in the 90s? I’d argue against that. Rather, Java and its viable alternatives heralded the well-known trend (and one of more popular religions) of Object Oriented Programming, or OOP.

    An Example

    So, the following case for TypeScript is actually a general case for using a type system in JavaScript programming. TypeScript is just the current best-in-class (by a wide chasm), and an objectively excellent candidate for accomplishing this goal. Let’s examine a very simple function in JS:

    function multiply(x, y) {
       return x * y;
     }
     

    Let’s call this function:

    multiply(2, 3); // = 6
    @@ -40,5 +40,5 @@
     

    We’ve simply told TS that we don’t allow non number inputs to be given to the function. Now the second function call with the string value is illegal — TypeScript will yell at you and your editor will highlight it with red, mean squiggly lined until you change it, optionally forbidding you to ship your code until you do. This may seem annoying at first — you must sprinkle type hints all around the place for TS to be happy, and it will yell at you if you dont obey your own rules. Migrating most of my company’s codebase was a lesson in patience in that regard. But the effort pays off in compound down the road, and let’s examine why.

    So What

    The Python zen teaches us “Explicit is better than implicit” — users familiar with type systems (who are gawking at my “discovery” of a feature existing in languages for over 45 years) might think I’m invoking this rule for readability reasons — as in, any person reading my multiply function with type hints will know immediately that the inputs are 2 numbers. This is true (although, TS has very powerful type inference, such that in many cases you may leave off type hints). Another valid point would be the functionality aspect — as I’ve mentioned, calling multiply with “hello” is now impossible, which is a great thing.

    For me, though, the most compelling case for type systems is more conceptual. TS forces you to explicitly fill your programs with assertions that mirror your assumptions about the program. Let’s rewrite our multiplication function:

    function fruitPrice(basePrice: number, quantity: number) {
       return basePrice * quantity;
     }
    -

    This function works great in dev with mock data, we receive the price of fruit from the server and the quantity from the client. Before pushing to production, the backend dev tells us that due to new architecture decisions, the price of certain fruit may be undetermined — now we may receive null, or an empty string when asking for the price of a fruit. Now when I call the price function with this new value, which may be undefined or a number, TypeScript yells because it know I am passing in a value which may not be a legal number.

    Again, this is great — my function would fail without a rewrite. But the real lesson I can take from the squiggly lines is about my assumptions. TS punishes you for a lenient or thoughtlessly written piece of code — it forces you to reexamine what you think the program actually does. So fruitPrice will undoubtedly have to change, but now you know where you casually gave yourself a break by assuming a stricter subset of input than in reality. Now you know your program must take an undetermined price into account. TS will selflessly tell you where this assumption is relevant, but the real takeaway is forcing you to more strictly define your program.

    But TypeScript, Though

    Something must be said about the tool in order to encourage its’ use, aside from touting the general benefits of a type system. So why TS, after all?

    From a maintenance perspective, TS is, as mentioned, maintained by Microsoft. There are constant releases fixing bugs and meeting performance goals. New features are great, but really a dev needs to know that the project won’t collapse because of a dangerous dependency on a small team’s free time, and that the project won’t be forgotten after a swift period of adoption. There are no guarantees, obviously, and no project lasts forever. But, for now, it seems like the buzzword period is mostly over — and the aftermath is major libraries and technologies have adopted TS, or at least actively maintain type declaration files and tooling for consumers. Bet on TypeScript.

    I think one of the reasons for TS’s steady success is its’ core product — type systems for JS. It has cultivated many features that were eventually swallowed into vanilla JS — optional chaining, what seems like direct inspiration for JS es2015 classes, nullish coalescing etc. But really, the main feature which browsers cannot adopt is the type system — JS is inherently dynamic, and a type system is a radical change browsers cannot simply add in. So by not competing with juggernaut browsers over its’ main feature, it can prevail safely without fearing a sudden hostile takeover.

    From a non maintenance perspective, TS has built its’ type system around widely used JS patterns. One example is that the TS type system is structural rather than nominal — basically, that one value is equivalent to another if it shares the structure of the other value. For example, a function that recieves { a: number; } as an argument, will also accept { a: number; b: number; } — the second type can be treated as the first type for all intents and purposes that the first type is used for in the function.

    In many other type systems, types can act in for other types only if an explicit (=nominal) relationship was tied between them, such as inheritance. A structural type system fits the JS pattern of constant usage of anonynous objects and values (including functions), without explicitly calling constructors and so forth. Forcing nonimal typing on existing JS code would change the style and patterns devs are used to. This is not the only advantage to a structural type system, but it illustrates the thinking behind the language design. For more on the unique fit between TS and JS (I didn’t even touch on the functional aspect), I strongly recommend watching this talk by Anders Hejlsberg.

    Giving the Web Context

    In a final note, moving this text from notepad to an actual text editor with a spellchecker has shamefully revealed many squiggly lines, red, blue and green. In an imperfect analogy, JS editors have long had red lines for syntax errors (a.k.a. spelling mistakes). TS is more than a library, as it introduces a feature entirely impossible in current JS — green and blue squiggly lines, for contextual and grammatical errors. Suddenly my programs are more than blocks of black text, they speak to me and challenge my assumptions. So while we roll in the slim surplus of cash we supposedly make by writing TS over plain JS, let’s all collectively move our programs from notepad to a text editor.

    Originally published on February 27, 2021, on Medium

    - \ No newline at end of file +

    This function works great in dev with mock data, we receive the price of fruit from the server and the quantity from the client. Before pushing to production, the backend dev tells us that due to new architecture decisions, the price of certain fruit may be undetermined — now we may receive null, or an empty string when asking for the price of a fruit. Now when I call the price function with this new value, which may be undefined or a number, TypeScript yells because it know I am passing in a value which may not be a legal number.

    Again, this is great — my function would fail without a rewrite. But the real lesson I can take from the squiggly lines is about my assumptions. TS punishes you for a lenient or thoughtlessly written piece of code — it forces you to reexamine what you think the program actually does. So fruitPrice will undoubtedly have to change, but now you know where you casually gave yourself a break by assuming a stricter subset of input than in reality. Now you know your program must take an undetermined price into account. TS will selflessly tell you where this assumption is relevant, but the real takeaway is forcing you to more strictly define your program.

    But TypeScript, Though

    Something must be said about the tool in order to encourage its’ use, aside from touting the general benefits of a type system. So why TS, after all?

    From a maintenance perspective, TS is, as mentioned, maintained by Microsoft. There are constant releases fixing bugs and meeting performance goals. New features are great, but really a dev needs to know that the project won’t collapse because of a dangerous dependency on a small team’s free time, and that the project won’t be forgotten after a swift period of adoption. There are no guarantees, obviously, and no project lasts forever. But, for now, it seems like the buzzword period is mostly over — and the aftermath is major libraries and technologies have adopted TS, or at least actively maintain type declaration files and tooling for consumers. Bet on TypeScript.

    I think one of the reasons for TS’s steady success is its’ core product — type systems for JS. It has cultivated many features that were eventually swallowed into vanilla JS — optional chaining, what seems like direct inspiration for JS es2015 classes, nullish coalescing etc. But really, the main feature which browsers cannot adopt is the type system — JS is inherently dynamic, and a type system is a radical change browsers cannot simply add in. So by not competing with juggernaut browsers over its’ main feature, it can prevail safely without fearing a sudden hostile takeover.

    From a non maintenance perspective, TS has built its’ type system around widely used JS patterns. One example is that the TS type system is structural rather than nominal — basically, that one value is equivalent to another if it shares the structure of the other value. For example, a function that recieves { a: number; } as an argument, will also accept { a: number; b: number; } — the second type can be treated as the first type for all intents and purposes that the first type is used for in the function.

    In many other type systems, types can act in for other types only if an explicit (=nominal) relationship was tied between them, such as inheritance. A structural type system fits the JS pattern of constant usage of anonynous objects and values (including functions), without explicitly calling constructors and so forth. Forcing nonimal typing on existing JS code would change the style and patterns devs are used to. This is not the only advantage to a structural type system, but it illustrates the thinking behind the language design. For more on the unique fit between TS and JS (I didn’t even touch on the functional aspect), I strongly recommend watching this talk by Anders Hejlsberg.

    Giving the Web Context

    In a final note, moving this text from notepad to an actual text editor with a spellchecker has shamefully revealed many squiggly lines, red, blue and green. In an imperfect analogy, JS editors have long had red lines for syntax errors (a.k.a. spelling mistakes). TS is more than a library, as it introduces a feature entirely impossible in current JS — green and blue squiggly lines, for contextual and grammatical errors. Suddenly my programs are more than blocks of black text, they speak to me and challenge my assumptions. So while we roll in the slim surplus of cash we supposedly make by writing TS over plain JS, let’s all collectively move our programs from notepad to a text editor.

    Originally published on February 27, 2021, on Medium

    + \ No newline at end of file