diff --git a/public/build/assets/app-584e3628.js b/public/build/assets/app-584e3628.js deleted file mode 100644 index 307b28d1..00000000 --- a/public/build/assets/app-584e3628.js +++ /dev/null @@ -1 +0,0 @@ -import{a as f}from"./app-ef45e7b6.js";export{f as default}; diff --git a/public/build/assets/app-5cfcf402.js b/public/build/assets/app-5cfcf402.js new file mode 100644 index 00000000..c7da4cac --- /dev/null +++ b/public/build/assets/app-5cfcf402.js @@ -0,0 +1 @@ +import{a as f}from"./app-c6af0dee.js";export{f as default}; diff --git a/public/build/assets/app-ef45e7b6.js b/public/build/assets/app-c6af0dee.js similarity index 94% rename from public/build/assets/app-ef45e7b6.js rename to public/build/assets/app-c6af0dee.js index 5da4dedf..4f4e9756 100644 --- a/public/build/assets/app-ef45e7b6.js +++ b/public/build/assets/app-c6af0dee.js @@ -19,7 +19,7 @@ focus-trap/dist/focus-trap.esm.js: * focus-trap 6.9.4 * @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE *) -*/class Ng{constructor(){}set(e,t,r=null,i="/",s={}){const o=Object.assign({[e]:t,expires:r instanceof Date?r.toUTCString():r,path:i},{SameSite:"Lax",Secure:!0},s);document.cookie=Object.entries(o).reduce((l,a)=>l.concat(a.join("=")),[]).join("; ")}get(e,t=null){const r=document.cookie.match(new RegExp("(^| )"+e+"=([^;]+)"));return r&&r[2]?r[2]:t}isset(e){return document.cookie.match(new RegExp("(^| )"+e+"=([^;]+)"))!==null}remove(e){this.set(e,null,"Thu, 01 Jan 1970 00:00:01 GMT")}}document.addEventListener("alpine:init",()=>{window.Alpine.data("notifications",n=>({open:!1,processing:!1,notifications:[],nextPageUrl:n,unread:0,init(){this.fetch()},fetch(){this.processing=!0,window.$http.get(this.nextPageUrl).then(e=>{this.unread=e.data.total_unread,this.notifications.push(...e.data.data),this.nextPageUrl=e.data.next_page_url}).catch(e=>{}).finally(()=>{this.processing=!1})},markAsRead(e){e.is_read||(this.processing=!0,window.$http.patch(e.url).then(t=>{this.unread--,e.is_read=!0}).catch(t=>{}).finally(()=>{this.processing=!1}))}}))});document.addEventListener("alpine:init",()=>{window.Alpine.data("theme",()=>({systemMode:window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light",theme:window.$cookie.get("__root_theme","system"),init(){window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",e=>{this.theme==="system"&&document.documentElement.setAttribute("data-theme-mode",e.matches?"dark":"light")}),document.documentElement.setAttribute("data-theme-mode",this.theme==="system"?this.systemMode:this.theme),this.changeAssets(),new MutationObserver(()=>{this.changeAssets()}).observe(document.documentElement,{attributes:!0})},change(n){document.documentElement.classList.add("no-transition"),window.$cookie.set("__root_theme",n),this.theme=n,document.documentElement.setAttribute("data-theme-mode",n==="system"?this.systemMode:n),this.$root.querySelector(`.theme-switcher__${n}-mode`).focus(),document.documentElement.classList.remove("no-transition")},changeAssets(){const n=document.documentElement.getAttribute("data-theme-mode")==="system"?this.systemMode:document.documentElement.getAttribute("data-theme-mode");document.querySelectorAll("img[data-theme-mode]").forEach(e=>{e.src=e.getAttribute(`data-${n}-asset`)})}}))});Du.plugin(Ag);window.Alpine=Du;window.$http=ag.create({headers:{Accept:"application/json","Content-Type":"application/json","X-Requested-With":"XMLHttpRequest","X-Root-Request":"true"}});window.$cookie=new Ng;function ee(n){this.content=n}ee.prototype={constructor:ee,find:function(n){for(var e=0;e>1}};ee.from=function(n){if(n instanceof ee)return n;var e=[];if(n)for(var t in n)e.push(t,n[t]);return new ee(e)};function ld(n,e,t){for(let r=0;;r++){if(r==n.childCount||r==e.childCount)return n.childCount==e.childCount?null:t;let i=n.child(r),s=e.child(r);if(i==s){t+=i.nodeSize;continue}if(!i.sameMarkup(s))return t;if(i.isText&&i.text!=s.text){for(let o=0;i.text[o]==s.text[o];o++)t++;return t}if(i.content.size||s.content.size){let o=ld(i.content,s.content,t+1);if(o!=null)return o}t+=i.nodeSize}}function ad(n,e,t,r){for(let i=n.childCount,s=e.childCount;;){if(i==0||s==0)return i==s?null:{a:t,b:r};let o=n.child(--i),l=e.child(--s),a=o.nodeSize;if(o==l){t-=a,r-=a;continue}if(!o.sameMarkup(l))return{a:t,b:r};if(o.isText&&o.text!=l.text){let c=0,u=Math.min(o.text.length,l.text.length);for(;ce&&r(a,i+l,s||null,o)!==!1&&a.content.size){let u=l+1;a.nodesBetween(Math.max(0,e-u),Math.min(a.content.size,t-u),r,i+u)}l=c}}descendants(e){this.nodesBetween(0,this.size,e)}textBetween(e,t,r,i){let s="",o=!0;return this.nodesBetween(e,t,(l,a)=>{l.isText?(s+=l.text.slice(Math.max(e,a)-a,t-a),o=!r):l.isLeaf?(i?s+=typeof i=="function"?i(l):i:l.type.spec.leafText&&(s+=l.type.spec.leafText(l)),o=!r):!o&&l.isBlock&&(s+=r,o=!0)},0),s}append(e){if(!e.size)return this;if(!this.size)return e;let t=this.lastChild,r=e.firstChild,i=this.content.slice(),s=0;for(t.isText&&t.sameMarkup(r)&&(i[i.length-1]=t.withText(t.text+r.text),s=1);se)for(let s=0,o=0;oe&&((ot)&&(l.isText?l=l.cut(Math.max(0,e-o),Math.min(l.text.length,t-o)):l=l.cut(Math.max(0,e-o-1),Math.min(l.content.size,t-o-1))),r.push(l),i+=l.nodeSize),o=a}return new k(r,i)}cutByIndex(e,t){return e==t?k.empty:e==0&&t==this.content.length?this:new k(this.content.slice(e,t))}replaceChild(e,t){let r=this.content[e];if(r==t)return this;let i=this.content.slice(),s=this.size+t.nodeSize-r.nodeSize;return i[e]=t,new k(i,s)}addToStart(e){return new k([e].concat(this.content),this.size+e.nodeSize)}addToEnd(e){return new k(this.content.concat(e),this.size+e.nodeSize)}eq(e){if(this.content.length!=e.content.length)return!1;for(let t=0;tthis.size||e<0)throw new RangeError(`Position ${e} outside of fragment (${this})`);for(let r=0,i=0;;r++){let s=this.child(r),o=i+s.nodeSize;if(o>=e)return o==e||t>0?Er(r+1,o):Er(r,i);i=o}}toString(){return"<"+this.toStringInner()+">"}toStringInner(){return this.content.join(", ")}toJSON(){return this.content.length?this.content.map(e=>e.toJSON()):null}static fromJSON(e,t){if(!t)return k.empty;if(!Array.isArray(t))throw new RangeError("Invalid input for Fragment.fromJSON");return new k(t.map(e.nodeFromJSON))}static fromArray(e){if(!e.length)return k.empty;let t,r=0;for(let i=0;ithis.type.rank&&(t||(t=e.slice(0,i)),t.push(this),r=!0),t&&t.push(s)}}return t||(t=e.slice()),r||t.push(this),t}removeFromSet(e){for(let t=0;tr.type.rank-i.type.rank),t}};F.none=[];class Wr extends Error{}class v{constructor(e,t,r){this.content=e,this.openStart=t,this.openEnd=r}get size(){return this.content.size-this.openStart-this.openEnd}insertAt(e,t){let r=ud(this.content,e+this.openStart,t);return r&&new v(r,this.openStart,this.openEnd)}removeBetween(e,t){return new v(cd(this.content,e+this.openStart,t+this.openStart),this.openStart,this.openEnd)}eq(e){return this.content.eq(e.content)&&this.openStart==e.openStart&&this.openEnd==e.openEnd}toString(){return this.content+"("+this.openStart+","+this.openEnd+")"}toJSON(){if(!this.content.size)return null;let e={content:this.content.toJSON()};return this.openStart>0&&(e.openStart=this.openStart),this.openEnd>0&&(e.openEnd=this.openEnd),e}static fromJSON(e,t){if(!t)return v.empty;let r=t.openStart||0,i=t.openEnd||0;if(typeof r!="number"||typeof i!="number")throw new RangeError("Invalid input for Slice.fromJSON");return new v(k.fromJSON(e,t.content),r,i)}static maxOpen(e,t=!0){let r=0,i=0;for(let s=e.firstChild;s&&!s.isLeaf&&(t||!s.type.spec.isolating);s=s.firstChild)r++;for(let s=e.lastChild;s&&!s.isLeaf&&(t||!s.type.spec.isolating);s=s.lastChild)i++;return new v(e,r,i)}}v.empty=new v(k.empty,0,0);function cd(n,e,t){let{index:r,offset:i}=n.findIndex(e),s=n.maybeChild(r),{index:o,offset:l}=n.findIndex(t);if(i==e||s.isText){if(l!=t&&!n.child(o).isText)throw new RangeError("Removing non-flat range");return n.cut(0,e).append(n.cut(t))}if(r!=o)throw new RangeError("Removing non-flat range");return n.replaceChild(r,s.copy(cd(s.content,e-i-1,t-i-1)))}function ud(n,e,t,r){let{index:i,offset:s}=n.findIndex(e),o=n.maybeChild(i);if(s==e||o.isText)return r&&!r.canReplace(i,i,t)?null:n.cut(0,e).append(t).append(n.cut(e));let l=ud(o.content,e-s-1,t);return l&&n.replaceChild(i,o.copy(l))}function Rg(n,e,t){if(t.openStart>n.depth)throw new Wr("Inserted content deeper than insertion position");if(n.depth-t.openStart!=e.depth-t.openEnd)throw new Wr("Inconsistent open depths");return dd(n,e,t,0)}function dd(n,e,t,r){let i=n.index(r),s=n.node(r);if(i==e.index(r)&&r=0&&n.isText&&n.sameMarkup(e[t])?e[t]=n.withText(e[t].text+n.text):e.push(n)}function $n(n,e,t,r){let i=(e||n).node(t),s=0,o=e?e.index(t):i.childCount;n&&(s=n.index(t),n.depth>t?s++:n.textOffset&&(zt(n.nodeAfter,r),s++));for(let l=s;li&&ro(n,e,i+1),o=r.depth>i&&ro(t,r,i+1),l=[];return $n(null,n,i,l),s&&o&&e.index(i)==t.index(i)?(fd(s,o),zt($t(s,hd(n,e,t,r,i+1)),l)):(s&&zt($t(s,Jr(n,e,i+1)),l),$n(e,t,i,l),o&&zt($t(o,Jr(t,r,i+1)),l)),$n(r,null,i,l),new k(l)}function Jr(n,e,t){let r=[];if($n(null,n,t,r),n.depth>t){let i=ro(n,e,t+1);zt($t(i,Jr(n,e,t+1)),r)}return $n(e,null,t,r),new k(r)}function Dg(n,e){let t=e.depth-n.openStart,i=e.node(t).copy(n.content);for(let s=t-1;s>=0;s--)i=e.node(s).copy(k.from(i));return{start:i.resolveNoCache(n.openStart+t),end:i.resolveNoCache(i.content.size-n.openEnd-t)}}class Yn{constructor(e,t,r){this.pos=e,this.path=t,this.parentOffset=r,this.depth=t.length/3-1}resolveDepth(e){return e==null?this.depth:e<0?this.depth+e:e}get parent(){return this.node(this.depth)}get doc(){return this.node(0)}node(e){return this.path[this.resolveDepth(e)*3]}index(e){return this.path[this.resolveDepth(e)*3+1]}indexAfter(e){return e=this.resolveDepth(e),this.index(e)+(e==this.depth&&!this.textOffset?0:1)}start(e){return e=this.resolveDepth(e),e==0?0:this.path[e*3-1]+1}end(e){return e=this.resolveDepth(e),this.start(e)+this.node(e).content.size}before(e){if(e=this.resolveDepth(e),!e)throw new RangeError("There is no position before the top-level node");return e==this.depth+1?this.pos:this.path[e*3-1]}after(e){if(e=this.resolveDepth(e),!e)throw new RangeError("There is no position after the top-level node");return e==this.depth+1?this.pos:this.path[e*3-1]+this.path[e*3].nodeSize}get textOffset(){return this.pos-this.path[this.path.length-1]}get nodeAfter(){let e=this.parent,t=this.index(this.depth);if(t==e.childCount)return null;let r=this.pos-this.path[this.path.length-1],i=e.child(t);return r?e.child(t).cut(r):i}get nodeBefore(){let e=this.index(this.depth),t=this.pos-this.path[this.path.length-1];return t?this.parent.child(e).cut(0,t):e==0?null:this.parent.child(e-1)}posAtIndex(e,t){t=this.resolveDepth(t);let r=this.path[t*3],i=t==0?0:this.path[t*3-1]+1;for(let s=0;s0;t--)if(this.start(t)<=e&&this.end(t)>=e)return t;return 0}blockRange(e=this,t){if(e.pos=0;r--)if(e.pos<=this.end(r)&&(!t||t(this.node(r))))return new Gr(this,e,r);return null}sameParent(e){return this.pos-this.parentOffset==e.pos-e.parentOffset}max(e){return e.pos>this.pos?e:this}min(e){return e.pos=0&&t<=e.content.size))throw new RangeError("Position "+t+" out of range");let r=[],i=0,s=t;for(let o=e;;){let{index:l,offset:a}=o.content.findIndex(s),c=s-a;if(r.push(o,l,i+a),!c||(o=o.child(l),o.isText))break;s=c-1,i+=a+1}return new Yn(t,r,s)}static resolveCached(e,t){for(let i=0;ie&&this.nodesBetween(e,t,s=>(r.isInSet(s.marks)&&(i=!0),!i)),i}get isBlock(){return this.type.isBlock}get isTextblock(){return this.type.isTextblock}get inlineContent(){return this.type.inlineContent}get isInline(){return this.type.isInline}get isText(){return this.type.isText}get isLeaf(){return this.type.isLeaf}get isAtom(){return this.type.isAtom}toString(){if(this.type.spec.toDebugString)return this.type.spec.toDebugString(this);let e=this.type.name;return this.content.size&&(e+="("+this.content.toStringInner()+")"),pd(this.marks,e)}contentMatchAt(e){let t=this.type.contentMatch.matchFragment(this.content,0,e);if(!t)throw new Error("Called contentMatchAt on a node with invalid content");return t}canReplace(e,t,r=k.empty,i=0,s=r.childCount){let o=this.contentMatchAt(e).matchFragment(r,i,s),l=o&&o.matchFragment(this.content,t);if(!l||!l.validEnd)return!1;for(let a=i;at.type.name)}`);this.content.forEach(t=>t.check())}toJSON(){let e={type:this.type.name};for(let t in this.attrs){e.attrs=this.attrs;break}return this.content.size&&(e.content=this.content.toJSON()),this.marks.length&&(e.marks=this.marks.map(t=>t.toJSON())),e}static fromJSON(e,t){if(!t)throw new RangeError("Invalid input for Node.fromJSON");let r=null;if(t.marks){if(!Array.isArray(t.marks))throw new RangeError("Invalid mark data for Node.fromJSON");r=t.marks.map(e.markFromJSON)}if(t.type=="text"){if(typeof t.text!="string")throw new RangeError("Invalid text node in JSON");return e.text(t.text,r)}let i=k.fromJSON(e,t.content);return e.nodeType(t.type).create(t.attrs,i,r)}};Ht.prototype.text=void 0;class Yr extends Ht{constructor(e,t,r,i){if(super(e,t,null,i),!r)throw new RangeError("Empty text nodes are not allowed");this.text=r}toString(){return this.type.spec.toDebugString?this.type.spec.toDebugString(this):pd(this.marks,JSON.stringify(this.text))}get textContent(){return this.text}textBetween(e,t){return this.text.slice(e,t)}get nodeSize(){return this.text.length}mark(e){return e==this.marks?this:new Yr(this.type,this.attrs,this.text,e)}withText(e){return e==this.text?this:new Yr(this.type,this.attrs,e,this.marks)}cut(e=0,t=this.text.length){return e==0&&t==this.text.length?this:this.withText(this.text.slice(e,t))}eq(e){return this.sameMarkup(e)&&this.text==e.text}toJSON(){let e=super.toJSON();return e.text=this.text,e}}function pd(n,e){for(let t=n.length-1;t>=0;t--)e=n[t].type.name+"("+e+")";return e}class Kt{constructor(e){this.validEnd=e,this.next=[],this.wrapCache=[]}static parse(e,t){let r=new Pg(e,t);if(r.next==null)return Kt.empty;let i=md(r);r.next&&r.err("Unexpected trailing text");let s=jg(Hg(i));return Vg(s,r),s}matchType(e){for(let t=0;tc.createAndFill()));for(let c=0;c=this.next.length)throw new RangeError(`There's no ${e}th edge in this content match`);return this.next[e]}toString(){let e=[];function t(r){e.push(r);for(let i=0;i{let s=i+(r.validEnd?"*":" ")+" ";for(let o=0;o"+e.indexOf(r.next[o].next);return s}).join(` +*/class Ng{constructor(){}set(e,t,r=null,i="/",s={}){const o=Object.assign({[e]:t,expires:r instanceof Date?r.toUTCString():r,path:i},{SameSite:"Lax",Secure:!0},s);document.cookie=Object.entries(o).reduce((l,a)=>l.concat(a.join("=")),[]).join("; ")}get(e,t=null){const r=document.cookie.match(new RegExp("(^| )"+e+"=([^;]+)"));return r&&r[2]?r[2]:t}isset(e){return document.cookie.match(new RegExp("(^| )"+e+"=([^;]+)"))!==null}remove(e){this.set(e,null,"Thu, 01 Jan 1970 00:00:01 GMT")}}document.addEventListener("alpine:init",()=>{window.Alpine.data("notifications",n=>({open:!1,processing:!1,notifications:[],nextPageUrl:n,unread:0,init(){this.fetch()},fetch(){this.processing=!0,window.$http.get(this.nextPageUrl).then(e=>{this.unread=e.data.total_unread,this.notifications.push(...e.data.data),this.nextPageUrl=e.data.next_page_url}).catch(e=>{}).finally(()=>{this.processing=!1})},markAsRead(e){e.is_read||(this.processing=!0,window.$http.patch(e.url).then(t=>{this.unread--,e.is_read=!0}).catch(t=>{}).finally(()=>{this.processing=!1}))}}))});document.addEventListener("alpine:init",()=>{window.Alpine.data("theme",()=>({systemMode:window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light",theme:window.$cookie.get("theme","system"),init(){window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",e=>{this.theme==="system"&&document.documentElement.setAttribute("data-theme-mode",e.matches?"dark":"light")}),document.documentElement.setAttribute("data-theme-mode",this.theme==="system"?this.systemMode:this.theme),this.changeAssets(),new MutationObserver(()=>{this.changeAssets()}).observe(document.documentElement,{attributes:!0})},change(n){document.documentElement.classList.add("no-transition"),window.$cookie.set("theme",n),this.theme=n,document.documentElement.setAttribute("data-theme-mode",n==="system"?this.systemMode:n),this.$root.querySelector(`.theme-switcher__${n}-mode`).focus(),document.documentElement.classList.remove("no-transition")},changeAssets(){const n=document.documentElement.getAttribute("data-theme-mode")==="system"?this.systemMode:document.documentElement.getAttribute("data-theme-mode");document.querySelectorAll("img[data-theme-mode]").forEach(e=>{e.src=e.getAttribute(`data-${n}-asset`)})}}))});Du.plugin(Ag);window.Alpine=Du;window.$http=ag.create({headers:{Accept:"application/json","Content-Type":"application/json","X-Requested-With":"XMLHttpRequest","X-Root-Request":"true"}});window.$cookie=new Ng("__root_");function ee(n){this.content=n}ee.prototype={constructor:ee,find:function(n){for(var e=0;e>1}};ee.from=function(n){if(n instanceof ee)return n;var e=[];if(n)for(var t in n)e.push(t,n[t]);return new ee(e)};function ld(n,e,t){for(let r=0;;r++){if(r==n.childCount||r==e.childCount)return n.childCount==e.childCount?null:t;let i=n.child(r),s=e.child(r);if(i==s){t+=i.nodeSize;continue}if(!i.sameMarkup(s))return t;if(i.isText&&i.text!=s.text){for(let o=0;i.text[o]==s.text[o];o++)t++;return t}if(i.content.size||s.content.size){let o=ld(i.content,s.content,t+1);if(o!=null)return o}t+=i.nodeSize}}function ad(n,e,t,r){for(let i=n.childCount,s=e.childCount;;){if(i==0||s==0)return i==s?null:{a:t,b:r};let o=n.child(--i),l=e.child(--s),a=o.nodeSize;if(o==l){t-=a,r-=a;continue}if(!o.sameMarkup(l))return{a:t,b:r};if(o.isText&&o.text!=l.text){let c=0,u=Math.min(o.text.length,l.text.length);for(;ce&&r(a,i+l,s||null,o)!==!1&&a.content.size){let u=l+1;a.nodesBetween(Math.max(0,e-u),Math.min(a.content.size,t-u),r,i+u)}l=c}}descendants(e){this.nodesBetween(0,this.size,e)}textBetween(e,t,r,i){let s="",o=!0;return this.nodesBetween(e,t,(l,a)=>{l.isText?(s+=l.text.slice(Math.max(e,a)-a,t-a),o=!r):l.isLeaf?(i?s+=typeof i=="function"?i(l):i:l.type.spec.leafText&&(s+=l.type.spec.leafText(l)),o=!r):!o&&l.isBlock&&(s+=r,o=!0)},0),s}append(e){if(!e.size)return this;if(!this.size)return e;let t=this.lastChild,r=e.firstChild,i=this.content.slice(),s=0;for(t.isText&&t.sameMarkup(r)&&(i[i.length-1]=t.withText(t.text+r.text),s=1);se)for(let s=0,o=0;oe&&((ot)&&(l.isText?l=l.cut(Math.max(0,e-o),Math.min(l.text.length,t-o)):l=l.cut(Math.max(0,e-o-1),Math.min(l.content.size,t-o-1))),r.push(l),i+=l.nodeSize),o=a}return new k(r,i)}cutByIndex(e,t){return e==t?k.empty:e==0&&t==this.content.length?this:new k(this.content.slice(e,t))}replaceChild(e,t){let r=this.content[e];if(r==t)return this;let i=this.content.slice(),s=this.size+t.nodeSize-r.nodeSize;return i[e]=t,new k(i,s)}addToStart(e){return new k([e].concat(this.content),this.size+e.nodeSize)}addToEnd(e){return new k(this.content.concat(e),this.size+e.nodeSize)}eq(e){if(this.content.length!=e.content.length)return!1;for(let t=0;tthis.size||e<0)throw new RangeError(`Position ${e} outside of fragment (${this})`);for(let r=0,i=0;;r++){let s=this.child(r),o=i+s.nodeSize;if(o>=e)return o==e||t>0?Er(r+1,o):Er(r,i);i=o}}toString(){return"<"+this.toStringInner()+">"}toStringInner(){return this.content.join(", ")}toJSON(){return this.content.length?this.content.map(e=>e.toJSON()):null}static fromJSON(e,t){if(!t)return k.empty;if(!Array.isArray(t))throw new RangeError("Invalid input for Fragment.fromJSON");return new k(t.map(e.nodeFromJSON))}static fromArray(e){if(!e.length)return k.empty;let t,r=0;for(let i=0;ithis.type.rank&&(t||(t=e.slice(0,i)),t.push(this),r=!0),t&&t.push(s)}}return t||(t=e.slice()),r||t.push(this),t}removeFromSet(e){for(let t=0;tr.type.rank-i.type.rank),t}};F.none=[];class Wr extends Error{}class v{constructor(e,t,r){this.content=e,this.openStart=t,this.openEnd=r}get size(){return this.content.size-this.openStart-this.openEnd}insertAt(e,t){let r=ud(this.content,e+this.openStart,t);return r&&new v(r,this.openStart,this.openEnd)}removeBetween(e,t){return new v(cd(this.content,e+this.openStart,t+this.openStart),this.openStart,this.openEnd)}eq(e){return this.content.eq(e.content)&&this.openStart==e.openStart&&this.openEnd==e.openEnd}toString(){return this.content+"("+this.openStart+","+this.openEnd+")"}toJSON(){if(!this.content.size)return null;let e={content:this.content.toJSON()};return this.openStart>0&&(e.openStart=this.openStart),this.openEnd>0&&(e.openEnd=this.openEnd),e}static fromJSON(e,t){if(!t)return v.empty;let r=t.openStart||0,i=t.openEnd||0;if(typeof r!="number"||typeof i!="number")throw new RangeError("Invalid input for Slice.fromJSON");return new v(k.fromJSON(e,t.content),r,i)}static maxOpen(e,t=!0){let r=0,i=0;for(let s=e.firstChild;s&&!s.isLeaf&&(t||!s.type.spec.isolating);s=s.firstChild)r++;for(let s=e.lastChild;s&&!s.isLeaf&&(t||!s.type.spec.isolating);s=s.lastChild)i++;return new v(e,r,i)}}v.empty=new v(k.empty,0,0);function cd(n,e,t){let{index:r,offset:i}=n.findIndex(e),s=n.maybeChild(r),{index:o,offset:l}=n.findIndex(t);if(i==e||s.isText){if(l!=t&&!n.child(o).isText)throw new RangeError("Removing non-flat range");return n.cut(0,e).append(n.cut(t))}if(r!=o)throw new RangeError("Removing non-flat range");return n.replaceChild(r,s.copy(cd(s.content,e-i-1,t-i-1)))}function ud(n,e,t,r){let{index:i,offset:s}=n.findIndex(e),o=n.maybeChild(i);if(s==e||o.isText)return r&&!r.canReplace(i,i,t)?null:n.cut(0,e).append(t).append(n.cut(e));let l=ud(o.content,e-s-1,t);return l&&n.replaceChild(i,o.copy(l))}function Rg(n,e,t){if(t.openStart>n.depth)throw new Wr("Inserted content deeper than insertion position");if(n.depth-t.openStart!=e.depth-t.openEnd)throw new Wr("Inconsistent open depths");return dd(n,e,t,0)}function dd(n,e,t,r){let i=n.index(r),s=n.node(r);if(i==e.index(r)&&r=0&&n.isText&&n.sameMarkup(e[t])?e[t]=n.withText(e[t].text+n.text):e.push(n)}function $n(n,e,t,r){let i=(e||n).node(t),s=0,o=e?e.index(t):i.childCount;n&&(s=n.index(t),n.depth>t?s++:n.textOffset&&(zt(n.nodeAfter,r),s++));for(let l=s;li&&ro(n,e,i+1),o=r.depth>i&&ro(t,r,i+1),l=[];return $n(null,n,i,l),s&&o&&e.index(i)==t.index(i)?(fd(s,o),zt($t(s,hd(n,e,t,r,i+1)),l)):(s&&zt($t(s,Jr(n,e,i+1)),l),$n(e,t,i,l),o&&zt($t(o,Jr(t,r,i+1)),l)),$n(r,null,i,l),new k(l)}function Jr(n,e,t){let r=[];if($n(null,n,t,r),n.depth>t){let i=ro(n,e,t+1);zt($t(i,Jr(n,e,t+1)),r)}return $n(e,null,t,r),new k(r)}function Dg(n,e){let t=e.depth-n.openStart,i=e.node(t).copy(n.content);for(let s=t-1;s>=0;s--)i=e.node(s).copy(k.from(i));return{start:i.resolveNoCache(n.openStart+t),end:i.resolveNoCache(i.content.size-n.openEnd-t)}}class Yn{constructor(e,t,r){this.pos=e,this.path=t,this.parentOffset=r,this.depth=t.length/3-1}resolveDepth(e){return e==null?this.depth:e<0?this.depth+e:e}get parent(){return this.node(this.depth)}get doc(){return this.node(0)}node(e){return this.path[this.resolveDepth(e)*3]}index(e){return this.path[this.resolveDepth(e)*3+1]}indexAfter(e){return e=this.resolveDepth(e),this.index(e)+(e==this.depth&&!this.textOffset?0:1)}start(e){return e=this.resolveDepth(e),e==0?0:this.path[e*3-1]+1}end(e){return e=this.resolveDepth(e),this.start(e)+this.node(e).content.size}before(e){if(e=this.resolveDepth(e),!e)throw new RangeError("There is no position before the top-level node");return e==this.depth+1?this.pos:this.path[e*3-1]}after(e){if(e=this.resolveDepth(e),!e)throw new RangeError("There is no position after the top-level node");return e==this.depth+1?this.pos:this.path[e*3-1]+this.path[e*3].nodeSize}get textOffset(){return this.pos-this.path[this.path.length-1]}get nodeAfter(){let e=this.parent,t=this.index(this.depth);if(t==e.childCount)return null;let r=this.pos-this.path[this.path.length-1],i=e.child(t);return r?e.child(t).cut(r):i}get nodeBefore(){let e=this.index(this.depth),t=this.pos-this.path[this.path.length-1];return t?this.parent.child(e).cut(0,t):e==0?null:this.parent.child(e-1)}posAtIndex(e,t){t=this.resolveDepth(t);let r=this.path[t*3],i=t==0?0:this.path[t*3-1]+1;for(let s=0;s0;t--)if(this.start(t)<=e&&this.end(t)>=e)return t;return 0}blockRange(e=this,t){if(e.pos=0;r--)if(e.pos<=this.end(r)&&(!t||t(this.node(r))))return new Gr(this,e,r);return null}sameParent(e){return this.pos-this.parentOffset==e.pos-e.parentOffset}max(e){return e.pos>this.pos?e:this}min(e){return e.pos=0&&t<=e.content.size))throw new RangeError("Position "+t+" out of range");let r=[],i=0,s=t;for(let o=e;;){let{index:l,offset:a}=o.content.findIndex(s),c=s-a;if(r.push(o,l,i+a),!c||(o=o.child(l),o.isText))break;s=c-1,i+=a+1}return new Yn(t,r,s)}static resolveCached(e,t){for(let i=0;ie&&this.nodesBetween(e,t,s=>(r.isInSet(s.marks)&&(i=!0),!i)),i}get isBlock(){return this.type.isBlock}get isTextblock(){return this.type.isTextblock}get inlineContent(){return this.type.inlineContent}get isInline(){return this.type.isInline}get isText(){return this.type.isText}get isLeaf(){return this.type.isLeaf}get isAtom(){return this.type.isAtom}toString(){if(this.type.spec.toDebugString)return this.type.spec.toDebugString(this);let e=this.type.name;return this.content.size&&(e+="("+this.content.toStringInner()+")"),pd(this.marks,e)}contentMatchAt(e){let t=this.type.contentMatch.matchFragment(this.content,0,e);if(!t)throw new Error("Called contentMatchAt on a node with invalid content");return t}canReplace(e,t,r=k.empty,i=0,s=r.childCount){let o=this.contentMatchAt(e).matchFragment(r,i,s),l=o&&o.matchFragment(this.content,t);if(!l||!l.validEnd)return!1;for(let a=i;at.type.name)}`);this.content.forEach(t=>t.check())}toJSON(){let e={type:this.type.name};for(let t in this.attrs){e.attrs=this.attrs;break}return this.content.size&&(e.content=this.content.toJSON()),this.marks.length&&(e.marks=this.marks.map(t=>t.toJSON())),e}static fromJSON(e,t){if(!t)throw new RangeError("Invalid input for Node.fromJSON");let r=null;if(t.marks){if(!Array.isArray(t.marks))throw new RangeError("Invalid mark data for Node.fromJSON");r=t.marks.map(e.markFromJSON)}if(t.type=="text"){if(typeof t.text!="string")throw new RangeError("Invalid text node in JSON");return e.text(t.text,r)}let i=k.fromJSON(e,t.content);return e.nodeType(t.type).create(t.attrs,i,r)}};Ht.prototype.text=void 0;class Yr extends Ht{constructor(e,t,r,i){if(super(e,t,null,i),!r)throw new RangeError("Empty text nodes are not allowed");this.text=r}toString(){return this.type.spec.toDebugString?this.type.spec.toDebugString(this):pd(this.marks,JSON.stringify(this.text))}get textContent(){return this.text}textBetween(e,t){return this.text.slice(e,t)}get nodeSize(){return this.text.length}mark(e){return e==this.marks?this:new Yr(this.type,this.attrs,this.text,e)}withText(e){return e==this.text?this:new Yr(this.type,this.attrs,e,this.marks)}cut(e=0,t=this.text.length){return e==0&&t==this.text.length?this:this.withText(this.text.slice(e,t))}eq(e){return this.sameMarkup(e)&&this.text==e.text}toJSON(){let e=super.toJSON();return e.text=this.text,e}}function pd(n,e){for(let t=n.length-1;t>=0;t--)e=n[t].type.name+"("+e+")";return e}class Kt{constructor(e){this.validEnd=e,this.next=[],this.wrapCache=[]}static parse(e,t){let r=new Pg(e,t);if(r.next==null)return Kt.empty;let i=md(r);r.next&&r.err("Unexpected trailing text");let s=jg(Hg(i));return Vg(s,r),s}matchType(e){for(let t=0;tc.createAndFill()));for(let c=0;c=this.next.length)throw new RangeError(`There's no ${e}th edge in this content match`);return this.next[e]}toString(){let e=[];function t(r){e.push(r);for(let i=0;i{let s=i+(r.validEnd?"*":" ")+" ";for(let o=0;o"+e.indexOf(r.next[o].next);return s}).join(` `)}}Kt.empty=new Kt(!0);class Pg{constructor(e,t){this.string=e,this.nodeTypes=t,this.inline=null,this.pos=0,this.tokens=e.split(/\s*(?=\b|\W|$)/),this.tokens[this.tokens.length-1]==""&&this.tokens.pop(),this.tokens[0]==""&&this.tokens.shift()}get next(){return this.tokens[this.pos]}eat(e){return this.next==e&&(this.pos++||!0)}err(e){throw new SyntaxError(e+" (in content expression '"+this.string+"')")}}function md(n){let e=[];do e.push(Lg(n));while(n.eat("|"));return e.length==1?e[0]:{type:"choice",exprs:e}}function Lg(n){let e=[];do e.push(Bg(n));while(n.next&&n.next!=")"&&n.next!="|");return e.length==1?e[0]:{type:"seq",exprs:e}}function Bg(n){let e=$g(n);for(;;)if(n.eat("+"))e={type:"plus",expr:e};else if(n.eat("*"))e={type:"star",expr:e};else if(n.eat("?"))e={type:"opt",expr:e};else if(n.eat("{"))e=Fg(n,e);else break;return e}function la(n){/\D/.test(n.next)&&n.err("Expected number, got '"+n.next+"'");let e=Number(n.next);return n.pos++,e}function Fg(n,e){let t=la(n),r=t;return n.eat(",")&&(n.next!="}"?r=la(n):r=-1),n.eat("}")||n.err("Unclosed braced range"),{type:"range",min:t,max:r,expr:e}}function zg(n,e){let t=n.nodeTypes,r=t[e];if(r)return[r];let i=[];for(let s in t){let o=t[s];o.groups.indexOf(e)>-1&&i.push(o)}return i.length==0&&n.err("No node type or group '"+e+"' found"),i}function $g(n){if(n.eat("(")){let e=md(n);return n.eat(")")||n.err("Missing closing paren"),e}else if(/\W/.test(n.next))n.err("Unexpected token '"+n.next+"'");else{let e=zg(n,n.next).map(t=>(n.inline==null?n.inline=t.isInline:n.inline!=t.isInline&&n.err("Mixing inline and block content"),{type:"name",value:t}));return n.pos++,e.length==1?e[0]:{type:"choice",exprs:e}}}function Hg(n){let e=[[]];return i(s(n,0),t()),e;function t(){return e.push([])-1}function r(o,l,a){let c={term:a,to:l};return e[o].push(c),c}function i(o,l){o.forEach(a=>a.to=l)}function s(o,l){if(o.type=="choice")return o.exprs.reduce((a,c)=>a.concat(s(c,l)),[]);if(o.type=="seq")for(let a=0;;a++){let c=s(o.exprs[a],l);if(a==o.exprs.length-1)return c;i(c,l=t())}else if(o.type=="star"){let a=t();return r(l,a),i(s(o.expr,a),a),[r(a)]}else if(o.type=="plus"){let a=t();return i(s(o.expr,l),a),i(s(o.expr,a),a),[r(a)]}else{if(o.type=="opt")return[r(l)].concat(s(o.expr,l));if(o.type=="range"){let a=l;for(let c=0;c{n[o].forEach(({term:l,to:a})=>{if(!l)return;let c;for(let u=0;u{c||i.push([l,c=[]]),c.indexOf(u)==-1&&c.push(u)})})});let s=e[r.join(",")]=new Kt(r.indexOf(n.length-1)>-1);for(let o=0;o-1}allowsMarks(e){if(this.markSet==null)return!0;for(let t=0;tr[s]=new Sd(s,t,o));let i=t.spec.topNode||"doc";if(!r[i])throw new RangeError("Schema is missing its top node type ('"+i+"')");if(!r.text)throw new RangeError("Every schema needs a 'text' type");for(let s in r.text.attrs)throw new RangeError("The text node type should not have attributes");return r}};class Ug{constructor(e){this.hasDefault=Object.prototype.hasOwnProperty.call(e,"default"),this.default=e.default}get isRequired(){return!this.hasDefault}}class Pi{constructor(e,t,r,i){this.name=e,this.rank=t,this.schema=r,this.spec=i,this.attrs=xd(i.attrs),this.excluded=null;let s=yd(this.attrs);this.instance=s?new F(this,s):null}create(e=null){return!e&&this.instance?this.instance:new F(this,bd(this.attrs,e))}static compile(e,t){let r=Object.create(null),i=0;return e.forEach((s,o)=>r[s]=new Pi(s,i++,t,o)),r}removeFromSet(e){for(var t=0;t-1}}class Kg{constructor(e){this.cached=Object.create(null);let t=this.spec={};for(let i in e)t[i]=e[i];t.nodes=ee.from(e.nodes),t.marks=ee.from(e.marks||{}),this.nodes=ca.compile(this.spec.nodes,this),this.marks=Pi.compile(this.spec.marks,this);let r=Object.create(null);for(let i in this.nodes){if(i in this.marks)throw new RangeError(i+" can not be both a node and a mark");let s=this.nodes[i],o=s.spec.content||"",l=s.spec.marks;s.contentMatch=r[o]||(r[o]=Kt.parse(o,this.nodes)),s.inlineContent=s.contentMatch.inlineContent,s.markSet=l=="_"?null:l?ua(this,l.split(" ")):l==""||!s.inlineContent?[]:null}for(let i in this.marks){let s=this.marks[i],o=s.spec.excludes;s.excluded=o==null?[s]:o==""?[]:ua(this,o.split(" "))}this.nodeFromJSON=this.nodeFromJSON.bind(this),this.markFromJSON=this.markFromJSON.bind(this),this.topNodeType=this.nodes[this.spec.topNode||"doc"],this.cached.wrappings=Object.create(null)}node(e,t=null,r,i){if(typeof e=="string")e=this.nodeType(e);else if(e instanceof ca){if(e.schema!=this)throw new RangeError("Node type from different schema used ("+e.name+")")}else throw new RangeError("Invalid node type: "+e);return e.createChecked(t,r,i)}text(e,t){let r=this.nodes.text;return new Yr(r,r.defaultAttrs,e,F.setFrom(t))}mark(e,t){return typeof e=="string"&&(e=this.marks[e]),e.create(t)}nodeFromJSON(e){return Ht.fromJSON(this,e)}markFromJSON(e){return F.fromJSON(this,e)}nodeType(e){let t=this.nodes[e];if(!t)throw new RangeError("Unknown node type: "+e);return t}}function ua(n,e){let t=[];for(let r=0;r-1)&&t.push(o=a)}if(!o)throw new SyntaxError("Unknown mark type: '"+e[r]+"'")}return t}class mn{constructor(e,t){this.schema=e,this.rules=t,this.tags=[],this.styles=[],t.forEach(r=>{r.tag?this.tags.push(r):r.style&&this.styles.push(r)}),this.normalizeLists=!this.tags.some(r=>{if(!/^(ul|ol)\b/.test(r.tag)||!r.node)return!1;let i=e.nodes[r.node];return i.contentMatch.matchType(i)})}parse(e,t={}){let r=new fa(this,t,!1);return r.addAll(e,t.from,t.to),r.finish()}parseSlice(e,t={}){let r=new fa(this,t,!0);return r.addAll(e,t.from,t.to),v.maxOpen(r.finish())}matchTag(e,t,r){for(let i=r?this.tags.indexOf(r)+1:0;ie.length&&(l.charCodeAt(e.length)!=61||l.slice(e.length+1)!=t))){if(o.getAttrs){let a=o.getAttrs(t);if(a===!1)continue;o.attrs=a||void 0}return o}}}static schemaRules(e){let t=[];function r(i){let s=i.priority==null?50:i.priority,o=0;for(;o{r(o=ha(o)),o.mark||o.ignore||o.clearMark||(o.mark=i)})}for(let i in e.nodes){let s=e.nodes[i].spec.parseDOM;s&&s.forEach(o=>{r(o=ha(o)),o.node||o.ignore||o.mark||(o.node=i)})}return t}static fromSchema(e){return e.cached.domParser||(e.cached.domParser=new mn(e,mn.schemaRules(e)))}}const kd={address:!0,article:!0,aside:!0,blockquote:!0,canvas:!0,dd:!0,div:!0,dl:!0,fieldset:!0,figcaption:!0,figure:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,li:!0,noscript:!0,ol:!0,output:!0,p:!0,pre:!0,section:!0,table:!0,tfoot:!0,ul:!0},qg={head:!0,noscript:!0,object:!0,script:!0,style:!0,title:!0},wd={ol:!0,ul:!0},Xr=1,Qr=2,Hn=4;function da(n,e,t){return e!=null?(e?Xr:0)|(e==="full"?Qr:0):n&&n.whitespace=="pre"?Xr|Qr:t&~Hn}class vr{constructor(e,t,r,i,s,o,l){this.type=e,this.attrs=t,this.marks=r,this.pendingMarks=i,this.solid=s,this.options=l,this.content=[],this.activeMarks=F.none,this.stashMarks=[],this.match=o||(l&Hn?null:e.contentMatch)}findWrapping(e){if(!this.match){if(!this.type)return[];let t=this.type.contentMatch.fillBefore(k.from(e));if(t)this.match=this.type.contentMatch.matchFragment(t);else{let r=this.type.contentMatch,i;return(i=r.findWrapping(e.type))?(this.match=r,i):null}}return this.match.findWrapping(e.type)}finish(e){if(!(this.options&Xr)){let r=this.content[this.content.length-1],i;if(r&&r.isText&&(i=/[ \t\r\n\u000c]+$/.exec(r.text))){let s=r;r.text.length==i[0].length?this.content.pop():this.content[this.content.length-1]=s.withText(s.text.slice(0,s.text.length-i[0].length))}}let t=k.from(this.content);return!e&&this.match&&(t=t.append(this.match.fillBefore(k.empty,!0))),this.type?this.type.create(this.attrs,t,this.marks):t}popFromStashMark(e){for(let t=this.stashMarks.length-1;t>=0;t--)if(e.eq(this.stashMarks[t]))return this.stashMarks.splice(t,1)[0]}applyPending(e){for(let t=0,r=this.pendingMarks;tthis.addAll(e)),o&&this.sync(l),this.needsBlock=a}else this.withStyleRules(e,()=>{this.addElementByRule(e,s,s.consuming===!1?i:void 0)})}leafFallback(e){e.nodeName=="BR"&&this.top.type&&this.top.type.inlineContent&&this.addTextNode(e.ownerDocument.createTextNode(` `))}ignoreFallback(e){e.nodeName=="BR"&&(!this.top.type||!this.top.type.inlineContent)&&this.findPlace(this.parser.schema.text("-"))}readStyles(e){let t=F.none,r=F.none;for(let i=0;i{o.clearMark(l)&&(r=l.addToSet(r))}):t=this.parser.schema.marks[o.mark].create(o.attrs).addToSet(t),o.consuming===!1)s=o;else break}return[t,r]}addElementByRule(e,t,r){let i,s,o;t.node?(s=this.parser.schema.nodes[t.node],s.isLeaf?this.insertNode(s.create(t.attrs))||this.leafFallback(e):i=this.enter(s,t.attrs||null,t.preserveWhitespace)):(o=this.parser.schema.marks[t.mark].create(t.attrs),this.addPendingMark(o));let l=this.top;if(s&&s.isLeaf)this.findInside(e);else if(r)this.addElement(e,r);else if(t.getContent)this.findInside(e),t.getContent(e,this.parser.schema).forEach(a=>this.insertNode(a));else{let a=e;typeof t.contentElement=="string"?a=e.querySelector(t.contentElement):typeof t.contentElement=="function"?a=t.contentElement(e):t.contentElement&&(a=t.contentElement),this.findAround(e,a,!0),this.addAll(a)}i&&this.sync(l)&&this.open--,o&&this.removePendingMark(o,l)}addAll(e,t,r){let i=t||0;for(let s=t?e.childNodes[t]:e.firstChild,o=r==null?null:e.childNodes[r];s!=o;s=s.nextSibling,++i)this.findAtPoint(e,i),this.addDOM(s);this.findAtPoint(e,i)}findPlace(e){let t,r;for(let i=this.open;i>=0;i--){let s=this.nodes[i],o=s.findWrapping(e);if(o&&(!t||t.length>o.length)&&(t=o,r=s,!o.length)||s.solid)break}if(!t)return!1;this.sync(r);for(let i=0;ithis.open){for(;t>this.open;t--)this.nodes[t-1].content.push(this.nodes[t].finish(e));this.nodes.length=this.open+1}}finish(){return this.open=0,this.closeExtra(this.isOpen),this.nodes[0].finish(this.isOpen||this.options.topOpen)}sync(e){for(let t=this.open;t>=0;t--)if(this.nodes[t]==e)return this.open=t,!0;return!1}get currentPos(){this.closeExtra();let e=0;for(let t=this.open;t>=0;t--){let r=this.nodes[t].content;for(let i=r.length-1;i>=0;i--)e+=r[i].nodeSize;t&&e++}return e}findAtPoint(e,t){if(this.find)for(let r=0;r-1)return e.split(/\s*\|\s*/).some(this.matchesContext,this);let t=e.split("/"),r=this.options.context,i=!this.isOpen&&(!r||r.parent.type==this.nodes[0].type),s=-(r?r.depth+1:0)+(i?0:1),o=(l,a)=>{for(;l>=0;l--){let c=t[l];if(c==""){if(l==t.length-1||l==0)continue;for(;a>=s;a--)if(o(l-1,a))return!0;return!1}else{let u=a>0||a==0&&i?this.nodes[a].type:r&&a>=s?r.node(a-s).type:null;if(!u||u.name!=c&&u.groups.indexOf(c)==-1)return!1;a--}}return!0};return o(t.length-1,this.open)}textblockFromContext(){let e=this.options.context;if(e)for(let t=e.depth;t>=0;t--){let r=e.node(t).contentMatchAt(e.indexAfter(t)).defaultType;if(r&&r.isTextblock&&r.defaultAttrs)return r}for(let t in this.parser.schema.nodes){let r=this.parser.schema.nodes[t];if(r.isTextblock&&r.defaultAttrs)return r}}addPendingMark(e){let t=Xg(e,this.top.pendingMarks);t&&this.top.stashMarks.push(t),this.top.pendingMarks=e.addToSet(this.top.pendingMarks)}removePendingMark(e,t){for(let r=this.open;r>=0;r--){let i=this.nodes[r];if(i.pendingMarks.lastIndexOf(e)>-1)i.pendingMarks=e.removeFromSet(i.pendingMarks);else{i.activeMarks=e.removeFromSet(i.activeMarks);let o=i.popFromStashMark(e);o&&i.type&&i.type.allowsMarkType(o.type)&&(i.activeMarks=o.addToSet(i.activeMarks))}if(i==t)break}}}function Wg(n){for(let e=n.firstChild,t=null;e;e=e.nextSibling){let r=e.nodeType==1?e.nodeName.toLowerCase():null;r&&wd.hasOwnProperty(r)&&t?(t.appendChild(e),e=t):r=="li"?t=e:r&&(t=null)}}function Jg(n,e){return(n.matches||n.msMatchesSelector||n.webkitMatchesSelector||n.mozMatchesSelector).call(n,e)}function Gg(n){let e=/\s*([\w-]+)\s*:\s*([^;]+)/g,t,r=[];for(;t=e.exec(n);)r.push(t[1],t[2].trim());return r}function ha(n){let e={};for(let t in n)e[t]=n[t];return e}function Yg(n,e){let t=e.schema.nodes;for(let r in t){let i=t[r];if(!i.allowsMarkType(n))continue;let s=[],o=l=>{s.push(l);for(let a=0;a{if(s.length||o.marks.length){let l=0,a=0;for(;l=0;i--){let s=this.serializeMark(e.marks[i],e.isInline,t);s&&((s.contentDOM||s.dom).appendChild(r),r=s.dom)}return r}serializeMark(e,t,r={}){let i=this.marks[e.type.name];return i&&ze.renderSpec(ls(r),i(e,t))}static renderSpec(e,t,r=null){if(typeof t=="string")return{dom:e.createTextNode(t)};if(t.nodeType!=null)return{dom:t};if(t.dom&&t.dom.nodeType!=null)return t;let i=t[0],s=i.indexOf(" ");s>0&&(r=i.slice(0,s),i=i.slice(s+1));let o,l=r?e.createElementNS(r,i):e.createElement(i),a=t[1],c=1;if(a&&typeof a=="object"&&a.nodeType==null&&!Array.isArray(a)){c=2;for(let u in a)if(a[u]!=null){let d=u.indexOf(" ");d>0?l.setAttributeNS(u.slice(0,d),u.slice(d+1),a[u]):l.setAttribute(u,a[u])}}for(let u=c;uc)throw new RangeError("Content hole must be the only child of its parent node");return{dom:l,contentDOM:l}}else{let{dom:f,contentDOM:p}=ze.renderSpec(e,d,r);if(l.appendChild(f),p){if(o)throw new RangeError("Multiple content holes");o=p}}}return{dom:l,contentDOM:o}}static fromSchema(e){return e.cached.domSerializer||(e.cached.domSerializer=new ze(this.nodesFromSchema(e),this.marksFromSchema(e)))}static nodesFromSchema(e){let t=pa(e.nodes);return t.text||(t.text=r=>r.text),t}static marksFromSchema(e){return pa(e.marks)}}function pa(n){let e={};for(let t in n){let r=n[t].spec.toDOM;r&&(e[t]=r)}return e}function ls(n){return n.document||window.document}const Ed=65535,vd=Math.pow(2,16);function Qg(n,e){return n+e*vd}function ma(n){return n&Ed}function Zg(n){return(n-(n&Ed))/vd}const Md=1,Cd=2,Pr=4,Od=8;class so{constructor(e,t,r){this.pos=e,this.delInfo=t,this.recover=r}get deleted(){return(this.delInfo&Od)>0}get deletedBefore(){return(this.delInfo&(Md|Pr))>0}get deletedAfter(){return(this.delInfo&(Cd|Pr))>0}get deletedAcross(){return(this.delInfo&Pr)>0}}class ye{constructor(e,t=!1){if(this.ranges=e,this.inverted=t,!e.length&&ye.empty)return ye.empty}recover(e){let t=0,r=ma(e);if(!this.inverted)for(let i=0;ie)break;let c=this.ranges[l+s],u=this.ranges[l+o],d=a+c;if(e<=d){let f=c?e==a?-1:e==d?1:t:t,p=a+i+(f<0?0:u);if(r)return p;let h=e==(t<0?a:d)?null:Qg(l/3,e-a),g=e==a?Cd:e==d?Md:Pr;return(t<0?e!=a:e!=d)&&(g|=Od),new so(p,g,h)}i+=u-c}return r?e+i:new so(e+i,0,null)}touches(e,t){let r=0,i=ma(t),s=this.inverted?2:1,o=this.inverted?1:2;for(let l=0;le)break;let c=this.ranges[l+s],u=a+c;if(e<=u&&l==i*3)return!0;r+=this.ranges[l+o]-c}return!1}forEach(e){let t=this.inverted?2:1,r=this.inverted?1:2;for(let i=0,s=0;i=0;t--){let i=e.getMirror(t);this.appendMap(e.maps[t].invert(),i!=null&&i>t?r-i-1:void 0)}}invert(){let e=new an;return e.appendMappingInverted(this),e}map(e,t=1){if(this.mirror)return this._map(e,t,!0);for(let r=this.from;rs&&a!o.isAtom||!l.type.allowsMarkType(this.mark.type)?o:o.mark(this.mark.addToSet(o.marks)),i),t.openStart,t.openEnd);return U.fromReplace(e,this.from,this.to,s)}invert(){return new $e(this.from,this.to,this.mark)}map(e){let t=e.mapResult(this.from,1),r=e.mapResult(this.to,-1);return t.deleted&&r.deleted||t.pos>=r.pos?null:new at(t.pos,r.pos,this.mark)}merge(e){return e instanceof at&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new at(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"addMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number")throw new RangeError("Invalid input for AddMarkStep.fromJSON");return new at(t.from,t.to,e.markFromJSON(t.mark))}}oe.jsonID("addMark",at);class $e extends oe{constructor(e,t,r){super(),this.from=e,this.to=t,this.mark=r}apply(e){let t=e.slice(this.from,this.to),r=new v(nl(t.content,i=>i.mark(this.mark.removeFromSet(i.marks)),e),t.openStart,t.openEnd);return U.fromReplace(e,this.from,this.to,r)}invert(){return new at(this.from,this.to,this.mark)}map(e){let t=e.mapResult(this.from,1),r=e.mapResult(this.to,-1);return t.deleted&&r.deleted||t.pos>=r.pos?null:new $e(t.pos,r.pos,this.mark)}merge(e){return e instanceof $e&&e.mark.eq(this.mark)&&this.from<=e.to&&this.to>=e.from?new $e(Math.min(this.from,e.from),Math.max(this.to,e.to),this.mark):null}toJSON(){return{stepType:"removeMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number")throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");return new $e(t.from,t.to,e.markFromJSON(t.mark))}}oe.jsonID("removeMark",$e);class ct extends oe{constructor(e,t){super(),this.pos=e,this.mark=t}apply(e){let t=e.nodeAt(this.pos);if(!t)return U.fail("No node at mark step's position");let r=t.type.create(t.attrs,null,this.mark.addToSet(t.marks));return U.fromReplace(e,this.pos,this.pos+1,new v(k.from(r),0,t.isLeaf?0:1))}invert(e){let t=e.nodeAt(this.pos);if(t){let r=this.mark.addToSet(t.marks);if(r.length==t.marks.length){for(let i=0;ir.pos?null:new Y(t.pos,r.pos,i,s,this.slice,this.insert,this.structure)}toJSON(){let e={stepType:"replaceAround",from:this.from,to:this.to,gapFrom:this.gapFrom,gapTo:this.gapTo,insert:this.insert};return this.slice.size&&(e.slice=this.slice.toJSON()),this.structure&&(e.structure=!0),e}static fromJSON(e,t){if(typeof t.from!="number"||typeof t.to!="number"||typeof t.gapFrom!="number"||typeof t.gapTo!="number"||typeof t.insert!="number")throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");return new Y(t.from,t.to,t.gapFrom,t.gapTo,v.fromJSON(e,t.slice),t.insert,!!t.structure)}}oe.jsonID("replaceAround",Y);function oo(n,e,t){let r=n.resolve(e),i=t-e,s=r.depth;for(;i>0&&s>0&&r.indexAfter(s)==r.node(s).childCount;)s--,i--;if(i>0){let o=r.node(s).maybeChild(r.indexAfter(s));for(;i>0;){if(!o||o.isLeaf)return!0;o=o.firstChild,i--}}return!1}function ey(n,e,t,r){let i=[],s=[],o,l;n.doc.nodesBetween(e,t,(a,c,u)=>{if(!a.isInline)return;let d=a.marks;if(!r.isInSet(d)&&u.type.allowsMarkType(r.type)){let f=Math.max(c,e),p=Math.min(c+a.nodeSize,t),h=r.addToSet(d);for(let g=0;gn.step(a)),s.forEach(a=>n.step(a))}function ty(n,e,t,r){let i=[],s=0;n.doc.nodesBetween(e,t,(o,l)=>{if(!o.isInline)return;s++;let a=null;if(r instanceof Pi){let c=o.marks,u;for(;u=r.isInSet(c);)(a||(a=[])).push(u),c=u.removeFromSet(c)}else r?r.isInSet(o.marks)&&(a=[r]):a=o.marks;if(a&&a.length){let c=Math.min(l+o.nodeSize,t);for(let u=0;un.step(new $e(o.from,o.to,o.style)))}function ny(n,e,t,r=t.contentMatch){let i=n.doc.nodeAt(e),s=[],o=e+1;for(let l=0;l=0;l--)n.step(s[l])}function ry(n,e,t){return(e==0||n.canReplace(e,n.childCount))&&(t==n.childCount||n.canReplace(0,t))}function Cn(n){let t=n.parent.content.cutByIndex(n.startIndex,n.endIndex);for(let r=n.depth;;--r){let i=n.$from.node(r),s=n.$from.index(r),o=n.$to.indexAfter(r);if(rt;h--)g||r.index(h)>0?(g=!0,u=k.from(r.node(h).copy(u)),d++):a--;let f=k.empty,p=0;for(let h=s,g=!1;h>t;h--)g||i.after(h+1)=0;o--){if(r.size){let l=t[o].type.contentMatch.matchFragment(r);if(!l||!l.validEnd)throw new RangeError("Wrapper type given to Transform.wrap does not form valid content of its parent wrapper")}r=k.from(t[o].type.create(t[o].attrs,r))}let i=e.start,s=e.end;n.step(new Y(i,s,i,s,new v(r,0,0),t.length,!0))}function ay(n,e,t,r,i){if(!r.isTextblock)throw new RangeError("Type given to setBlockType should be a textblock");let s=n.steps.length;n.doc.nodesBetween(e,t,(o,l)=>{if(o.isTextblock&&!o.hasMarkup(r,i)&&cy(n.doc,n.mapping.slice(s).map(l),r)){n.clearIncompatible(n.mapping.slice(s).map(l,1),r);let a=n.mapping.slice(s),c=a.map(l,1),u=a.map(l+o.nodeSize,1);return n.step(new Y(c,u,c+1,u-1,new v(k.from(r.create(i,null,o.marks)),0,0),1,!0)),!1}})}function cy(n,e,t){let r=n.resolve(e),i=r.index();return r.parent.canReplaceWith(i,i+1,t)}function uy(n,e,t,r,i){let s=n.doc.nodeAt(e);if(!s)throw new RangeError("No node at given position");t||(t=s.type);let o=t.create(r,null,i||s.marks);if(s.isLeaf)return n.replaceWith(e,e+s.nodeSize,o);if(!t.validContent(s.content))throw new RangeError("Invalid content for node type "+t.name);n.step(new Y(e,e+s.nodeSize,e+1,e+s.nodeSize-1,new v(k.from(o),0,0),1,!0))}function cn(n,e,t=1,r){let i=n.resolve(e),s=i.depth-t,o=r&&r[r.length-1]||i.parent;if(s<0||i.parent.type.spec.isolating||!i.parent.canReplace(i.index(),i.parent.childCount)||!o.type.validContent(i.parent.content.cutByIndex(i.index(),i.parent.childCount)))return!1;for(let c=i.depth-1,u=t-2;c>s;c--,u--){let d=i.node(c),f=i.index(c);if(d.type.spec.isolating)return!1;let p=d.content.cutByIndex(f,d.childCount),h=r&&r[u+1];h&&(p=p.replaceChild(0,h.type.create(h.attrs)));let g=r&&r[u]||d;if(!d.canReplace(f+1,d.childCount)||!g.type.validContent(p))return!1}let l=i.indexAfter(s),a=r&&r[0];return i.node(s).canReplaceWith(l,l,a?a.type:i.node(s+1).type)}function dy(n,e,t=1,r){let i=n.doc.resolve(e),s=k.empty,o=k.empty;for(let l=i.depth,a=i.depth-t,c=t-1;l>a;l--,c--){s=k.from(i.node(l).copy(s));let u=r&&r[c];o=k.from(u?u.type.create(u.attrs,o):i.node(l).copy(o))}n.step(new te(e,e,new v(s.append(o),t,t),!0))}function St(n,e){let t=n.resolve(e),r=t.index();return Td(t.nodeBefore,t.nodeAfter)&&t.parent.canReplace(r,r+1)}function Td(n,e){return!!(n&&e&&!n.isLeaf&&n.canAppend(e))}function Li(n,e,t=-1){let r=n.resolve(e);for(let i=r.depth;;i--){let s,o,l=r.index(i);if(i==r.depth?(s=r.nodeBefore,o=r.nodeAfter):t>0?(s=r.node(i+1),l++,o=r.node(i).maybeChild(l)):(s=r.node(i).maybeChild(l-1),o=r.node(i+1)),s&&!s.isTextblock&&Td(s,o)&&r.node(i).canReplace(l,l+1))return e;if(i==0)break;e=t<0?r.before(i):r.after(i)}}function fy(n,e,t){let r=new te(e-t,e+t,v.empty,!0);n.step(r)}function hy(n,e,t){let r=n.resolve(e);if(r.parent.canReplaceWith(r.index(),r.index(),t))return e;if(r.parentOffset==0)for(let i=r.depth-1;i>=0;i--){let s=r.index(i);if(r.node(i).canReplaceWith(s,s,t))return r.before(i+1);if(s>0)return null}if(r.parentOffset==r.parent.content.size)for(let i=r.depth-1;i>=0;i--){let s=r.indexAfter(i);if(r.node(i).canReplaceWith(s,s,t))return r.after(i+1);if(s=0;o--){let l=o==r.depth?0:r.pos<=(r.start(o+1)+r.end(o+1))/2?-1:1,a=r.index(o)+(l>0?1:0),c=r.node(o),u=!1;if(s==1)u=c.canReplace(a,a,i);else{let d=c.contentMatchAt(a).findWrapping(i.firstChild.type);u=d&&c.canReplaceWith(a,a,d[0])}if(u)return l==0?r.pos:l<0?r.before(o+1):r.after(o+1)}return null}function il(n,e,t=e,r=v.empty){if(e==t&&!r.size)return null;let i=n.resolve(e),s=n.resolve(t);return Nd(i,s,r)?new te(e,t,r):new py(i,s,r).fit()}function Nd(n,e,t){return!t.openStart&&!t.openEnd&&n.start()==e.start()&&n.parent.canReplace(n.index(),e.index(),t.content)}class py{constructor(e,t,r){this.$from=e,this.$to=t,this.unplaced=r,this.frontier=[],this.placed=k.empty;for(let i=0;i<=e.depth;i++){let s=e.node(i);this.frontier.push({type:s.type,match:s.contentMatchAt(e.indexAfter(i))})}for(let i=e.depth;i>0;i--)this.placed=k.from(e.node(i).copy(this.placed))}get depth(){return this.frontier.length-1}fit(){for(;this.unplaced.size;){let c=this.findFittable();c?this.placeNodes(c):this.openMore()||this.dropNode()}let e=this.mustMoveInline(),t=this.placed.size-this.depth-this.$from.depth,r=this.$from,i=this.close(e<0?this.$to:r.doc.resolve(e));if(!i)return null;let s=this.placed,o=r.depth,l=i.depth;for(;o&&l&&s.childCount==1;)s=s.firstChild.content,o--,l--;let a=new v(s,o,l);return e>-1?new Y(r.pos,e,this.$to.pos,this.$to.end(),a,t):a.size||r.pos!=this.$to.pos?new te(r.pos,i.pos,a):null}findFittable(){let e=this.unplaced.openStart;for(let t=this.unplaced.content,r=0,i=this.unplaced.openEnd;r1&&(i=0),s.type.spec.isolating&&i<=r){e=r;break}t=s.content}for(let t=1;t<=2;t++)for(let r=t==1?e:this.unplaced.openStart;r>=0;r--){let i,s=null;r?(s=cs(this.unplaced.content,r-1).firstChild,i=s.content):i=this.unplaced.content;let o=i.firstChild;for(let l=this.depth;l>=0;l--){let{type:a,match:c}=this.frontier[l],u,d=null;if(t==1&&(o?c.matchType(o.type)||(d=c.fillBefore(k.from(o),!1)):s&&a.compatibleContent(s.type)))return{sliceDepth:r,frontierDepth:l,parent:s,inject:d};if(t==2&&o&&(u=c.findWrapping(o.type)))return{sliceDepth:r,frontierDepth:l,parent:s,wrap:u};if(s&&c.matchType(s.type))break}}}openMore(){let{content:e,openStart:t,openEnd:r}=this.unplaced,i=cs(e,t);return!i.childCount||i.firstChild.isLeaf?!1:(this.unplaced=new v(e,t+1,Math.max(r,i.size+t>=e.size-r?t+1:0)),!0)}dropNode(){let{content:e,openStart:t,openEnd:r}=this.unplaced,i=cs(e,t);if(i.childCount<=1&&t>0){let s=e.size-t<=t+i.size;this.unplaced=new v(_n(e,t-1,1),t-1,s?t-1:r)}else this.unplaced=new v(_n(e,t,1),t,r)}placeNodes({sliceDepth:e,frontierDepth:t,parent:r,inject:i,wrap:s}){for(;this.depth>t;)this.closeFrontierNode();if(s)for(let g=0;g1||a==0||g.content.size)&&(d=m,u.push(Rd(g.mark(f.allowedMarks(g.marks)),c==1?a:0,c==l.childCount?p:-1)))}let h=c==l.childCount;h||(p=-1),this.placed=Pn(this.placed,t,k.from(u)),this.frontier[t].match=d,h&&p<0&&r&&r.type==this.frontier[this.depth].type&&this.frontier.length>1&&this.closeFrontierNode();for(let g=0,m=l;g1&&i==this.$to.end(--r);)++i;return i}findCloseLevel(e){e:for(let t=Math.min(this.depth,e.depth);t>=0;t--){let{match:r,type:i}=this.frontier[t],s=t=0;l--){let{match:a,type:c}=this.frontier[l],u=us(e,l,c,a,!0);if(!u||u.childCount)continue e}return{depth:t,fit:o,move:s?e.doc.resolve(e.after(t+1)):e}}}}close(e){let t=this.findCloseLevel(e);if(!t)return null;for(;this.depth>t.depth;)this.closeFrontierNode();t.fit.childCount&&(this.placed=Pn(this.placed,t.depth,t.fit)),e=t.move;for(let r=t.depth+1;r<=e.depth;r++){let i=e.node(r),s=i.type.contentMatch.fillBefore(i.content,!0,e.index(r));this.openFrontierNode(i.type,i.attrs,s)}return e}openFrontierNode(e,t=null,r){let i=this.frontier[this.depth];i.match=i.match.matchType(e),this.placed=Pn(this.placed,this.depth,k.from(e.create(t,r))),this.frontier.push({type:e,match:e.contentMatch})}closeFrontierNode(){let t=this.frontier.pop().match.fillBefore(k.empty,!0);t.childCount&&(this.placed=Pn(this.placed,this.frontier.length,t))}}function _n(n,e,t){return e==0?n.cutByIndex(t,n.childCount):n.replaceChild(0,n.firstChild.copy(_n(n.firstChild.content,e-1,t)))}function Pn(n,e,t){return e==0?n.append(t):n.replaceChild(n.childCount-1,n.lastChild.copy(Pn(n.lastChild.content,e-1,t)))}function cs(n,e){for(let t=0;t1&&(r=r.replaceChild(0,Rd(r.firstChild,e-1,r.childCount==1?t-1:0))),e>0&&(r=n.type.contentMatch.fillBefore(r).append(r),t<=0&&(r=r.append(n.type.contentMatch.matchFragment(r).fillBefore(k.empty,!0)))),n.copy(r)}function us(n,e,t,r,i){let s=n.node(e),o=i?n.indexAfter(e):n.index(e);if(o==s.childCount&&!t.compatibleContent(s.type))return null;let l=r.fillBefore(s.content,!0,o);return l&&!my(t,s.content,o)?l:null}function my(n,e,t){for(let r=t;r0;f--,p--){let h=i.node(f).type.spec;if(h.defining||h.definingAsContext||h.isolating)break;o.indexOf(f)>-1?l=f:i.before(f)==p&&o.splice(1,0,-f)}let a=o.indexOf(l),c=[],u=r.openStart;for(let f=r.content,p=0;;p++){let h=f.firstChild;if(c.push(h),p==r.openStart)break;f=h.content}for(let f=u-1;f>=0;f--){let p=c[f],h=gy(p.type);if(h&&!p.sameMarkup(i.node(Math.abs(l)-1)))u=f;else if(h||!p.type.isTextblock)break}for(let f=r.openStart;f>=0;f--){let p=(f+u+1)%(r.openStart+1),h=c[p];if(h)for(let g=0;g=0&&(n.replace(e,t,r),!(n.steps.length>d));f--){let p=o[f];p<0||(e=i.before(p),t=s.after(p))}}function Dd(n,e,t,r,i){if(er){let s=i.contentMatchAt(0),o=s.fillBefore(n).append(n);n=o.append(s.matchFragment(o).fillBefore(k.empty,!0))}return n}function by(n,e,t,r){if(!r.isInline&&e==t&&n.doc.resolve(e).parent.content.size){let i=hy(n.doc,e,r.type);i!=null&&(e=t=i)}n.replaceRange(e,t,new v(k.from(r),0,0))}function xy(n,e,t){let r=n.doc.resolve(e),i=n.doc.resolve(t),s=Id(r,i);for(let o=0;o0&&(a||r.node(l-1).canReplace(r.index(l-1),i.indexAfter(l-1))))return n.delete(r.before(l),i.after(l))}for(let o=1;o<=r.depth&&o<=i.depth;o++)if(e-r.start(o)==r.depth-o&&t>r.end(o)&&i.end(o)-t!=i.depth-o)return n.delete(r.before(o),t);n.delete(e,t)}function Id(n,e){let t=[],r=Math.min(n.depth,e.depth);for(let i=r;i>=0;i--){let s=n.start(i);if(se.pos+(e.depth-i)||n.node(i).type.spec.isolating||e.node(i).type.spec.isolating)break;(s==e.start(i)||i==n.depth&&i==e.depth&&n.parent.inlineContent&&e.parent.inlineContent&&i&&e.start(i-1)==s-1)&&t.push(i)}return t}class un extends oe{constructor(e,t,r){super(),this.pos=e,this.attr=t,this.value=r}apply(e){let t=e.nodeAt(this.pos);if(!t)return U.fail("No node at attribute step's position");let r=Object.create(null);for(let s in t.attrs)r[s]=t.attrs[s];r[this.attr]=this.value;let i=t.type.create(r,null,t.marks);return U.fromReplace(e,this.pos,this.pos+1,new v(k.from(i),0,t.isLeaf?0:1))}getMap(){return ye.empty}invert(e){return new un(this.pos,this.attr,e.nodeAt(this.pos).attrs[this.attr])}map(e){let t=e.mapResult(this.pos,1);return t.deletedAfter?null:new un(t.pos,this.attr,this.value)}toJSON(){return{stepType:"attr",pos:this.pos,attr:this.attr,value:this.value}}static fromJSON(e,t){if(typeof t.pos!="number"||typeof t.attr!="string")throw new RangeError("Invalid input for AttrStep.fromJSON");return new un(t.pos,t.attr,t.value)}}oe.jsonID("attr",un);class Xn extends oe{constructor(e,t){super(),this.attr=e,this.value=t}apply(e){let t=Object.create(null);for(let i in e.attrs)t[i]=e.attrs[i];t[this.attr]=this.value;let r=e.type.create(t,e.content,e.marks);return U.ok(r)}getMap(){return ye.empty}invert(e){return new Xn(this.attr,e.attrs[this.attr])}map(e){return this}toJSON(){return{stepType:"docAttr",attr:this.attr,value:this.value}}static fromJSON(e,t){if(typeof t.attr!="string")throw new RangeError("Invalid input for DocAttrStep.fromJSON");return new Xn(t.attr,t.value)}}oe.jsonID("docAttr",Xn);let yn=class extends Error{};yn=function n(e){let t=Error.call(this,e);return t.__proto__=n.prototype,t};yn.prototype=Object.create(Error.prototype);yn.prototype.constructor=yn;yn.prototype.name="TransformError";class _d{constructor(e){this.doc=e,this.steps=[],this.docs=[],this.mapping=new an}get before(){return this.docs.length?this.docs[0]:this.doc}step(e){let t=this.maybeStep(e);if(t.failed)throw new yn(t.failed);return this}maybeStep(e){let t=e.apply(this.doc);return t.failed||this.addStep(e,t.doc),t}get docChanged(){return this.steps.length>0}addStep(e,t){this.docs.push(this.doc),this.steps.push(e),this.mapping.appendMap(e.getMap()),this.doc=t}replace(e,t=e,r=v.empty){let i=il(this.doc,e,t,r);return i&&this.step(i),this}replaceWith(e,t,r){return this.replace(e,t,new v(k.from(r),0,0))}delete(e,t){return this.replace(e,t,v.empty)}insert(e,t){return this.replaceWith(e,e,t)}replaceRange(e,t,r){return yy(this,e,t,r),this}replaceRangeWith(e,t,r){return by(this,e,t,r),this}deleteRange(e,t){return xy(this,e,t),this}lift(e,t){return iy(this,e,t),this}join(e,t=1){return fy(this,e,t),this}wrap(e,t){return ly(this,e,t),this}setBlockType(e,t=e,r,i=null){return ay(this,e,t,r,i),this}setNodeMarkup(e,t,r=null,i){return uy(this,e,t,r,i),this}setNodeAttribute(e,t,r){return this.step(new un(e,t,r)),this}setDocAttribute(e,t){return this.step(new Xn(e,t)),this}addNodeMark(e,t){return this.step(new ct(e,t)),this}removeNodeMark(e,t){if(!(t instanceof F)){let r=this.doc.nodeAt(e);if(!r)throw new RangeError("No node at position "+e);if(t=t.isInSet(r.marks),!t)return this}return this.step(new gn(e,t)),this}split(e,t=1,r){return dy(this,e,t,r),this}addMark(e,t,r){return ey(this,e,t,r),this}removeMark(e,t,r){return ty(this,e,t,r),this}clearIncompatible(e,t,r){return ny(this,e,t,r),this}}const ds=Object.create(null);class P{constructor(e,t,r){this.$anchor=e,this.$head=t,this.ranges=r||[new Sy(e.min(t),e.max(t))]}get anchor(){return this.$anchor.pos}get head(){return this.$head.pos}get from(){return this.$from.pos}get to(){return this.$to.pos}get $from(){return this.ranges[0].$from}get $to(){return this.ranges[0].$to}get empty(){let e=this.ranges;for(let t=0;t=0;s--){let o=t<0?Zt(e.node(0),e.node(s),e.before(s+1),e.index(s),t,r):Zt(e.node(0),e.node(s),e.after(s+1),e.index(s)+1,t,r);if(o)return o}return null}static near(e,t=1){return this.findFrom(e,t)||this.findFrom(e,-t)||new Te(e.node(0))}static atStart(e){return Zt(e,e,0,0,1)||new Te(e)}static atEnd(e){return Zt(e,e,e.content.size,e.childCount,-1)||new Te(e)}static fromJSON(e,t){if(!t||!t.type)throw new RangeError("Invalid input for Selection.fromJSON");let r=ds[t.type];if(!r)throw new RangeError(`No selection type ${t.type} defined`);return r.fromJSON(e,t)}static jsonID(e,t){if(e in ds)throw new RangeError("Duplicate use of selection JSON ID "+e);return ds[e]=t,t.prototype.jsonID=e,t}getBookmark(){return I.between(this.$anchor,this.$head).getBookmark()}}P.prototype.visible=!0;class Sy{constructor(e,t){this.$from=e,this.$to=t}}let ya=!1;function ba(n){!ya&&!n.parent.inlineContent&&(ya=!0,console.warn("TextSelection endpoint not pointing into a node with inline content ("+n.parent.type.name+")"))}class I extends P{constructor(e,t=e){ba(e),ba(t),super(e,t)}get $cursor(){return this.$anchor.pos==this.$head.pos?this.$head:null}map(e,t){let r=e.resolve(t.map(this.head));if(!r.parent.inlineContent)return P.near(r);let i=e.resolve(t.map(this.anchor));return new I(i.parent.inlineContent?i:r,r)}replace(e,t=v.empty){if(super.replace(e,t),t==v.empty){let r=this.$from.marksAcross(this.$to);r&&e.ensureMarks(r)}}eq(e){return e instanceof I&&e.anchor==this.anchor&&e.head==this.head}getBookmark(){return new Bi(this.anchor,this.head)}toJSON(){return{type:"text",anchor:this.anchor,head:this.head}}static fromJSON(e,t){if(typeof t.anchor!="number"||typeof t.head!="number")throw new RangeError("Invalid input for TextSelection.fromJSON");return new I(e.resolve(t.anchor),e.resolve(t.head))}static create(e,t,r=t){let i=e.resolve(t);return new this(i,r==t?i:e.resolve(r))}static between(e,t,r){let i=e.pos-t.pos;if((!r||i)&&(r=i>=0?1:-1),!t.parent.inlineContent){let s=P.findFrom(t,r,!0)||P.findFrom(t,-r,!0);if(s)t=s.$head;else return P.near(t,r)}return e.parent.inlineContent||(i==0?e=t:(e=(P.findFrom(e,-r,!0)||P.findFrom(e,r,!0)).$anchor,e.pos0?0:1);i>0?o=0;o+=i){let l=e.child(o);if(l.isAtom){if(!s&&N.isSelectable(l))return N.create(n,t-(i<0?l.nodeSize:0))}else{let a=Zt(n,l,t+i,i<0?l.childCount:0,i,s);if(a)return a}t+=l.nodeSize*i}return null}function xa(n,e,t){let r=n.steps.length-1;if(r{o==null&&(o=u)}),n.setSelection(P.near(n.doc.resolve(o),t))}const Sa=1,Mr=2,ka=4;class wy extends _d{constructor(e){super(e.doc),this.curSelectionFor=0,this.updated=0,this.meta=Object.create(null),this.time=Date.now(),this.curSelection=e.selection,this.storedMarks=e.storedMarks}get selection(){return this.curSelectionFor0}setStoredMarks(e){return this.storedMarks=e,this.updated|=Mr,this}ensureMarks(e){return F.sameSet(this.storedMarks||this.selection.$from.marks(),e)||this.setStoredMarks(e),this}addStoredMark(e){return this.ensureMarks(e.addToSet(this.storedMarks||this.selection.$head.marks()))}removeStoredMark(e){return this.ensureMarks(e.removeFromSet(this.storedMarks||this.selection.$head.marks()))}get storedMarksSet(){return(this.updated&Mr)>0}addStep(e,t){super.addStep(e,t),this.updated=this.updated&~Mr,this.storedMarks=null}setTime(e){return this.time=e,this}replaceSelection(e){return this.selection.replace(this,e),this}replaceSelectionWith(e,t=!0){let r=this.selection;return t&&(e=e.mark(this.storedMarks||(r.empty?r.$from.marks():r.$from.marksAcross(r.$to)||F.none))),r.replaceWith(this,e),this}deleteSelection(){return this.selection.replace(this),this}insertText(e,t,r){let i=this.doc.type.schema;if(t==null)return e?this.replaceSelectionWith(i.text(e),!0):this.deleteSelection();{if(r==null&&(r=t),r=r??t,!e)return this.deleteRange(t,r);let s=this.storedMarks;if(!s){let o=this.doc.resolve(t);s=r==t?o.marks():o.marksAcross(this.doc.resolve(r))}return this.replaceRangeWith(t,r,i.text(e,s)),this.selection.empty||this.setSelection(P.near(this.selection.$to)),this}}setMeta(e,t){return this.meta[typeof e=="string"?e:e.key]=t,this}getMeta(e){return this.meta[typeof e=="string"?e:e.key]}get isGeneric(){for(let e in this.meta)return!1;return!0}scrollIntoView(){return this.updated|=ka,this}get scrolledIntoView(){return(this.updated&ka)>0}}function wa(n,e){return!e||!n?n:n.bind(e)}class Ln{constructor(e,t,r){this.name=e,this.init=wa(t.init,r),this.apply=wa(t.apply,r)}}const Ey=[new Ln("doc",{init(n){return n.doc||n.schema.topNodeType.createAndFill()},apply(n){return n.doc}}),new Ln("selection",{init(n,e){return n.selection||P.atStart(e.doc)},apply(n){return n.selection}}),new Ln("storedMarks",{init(n){return n.storedMarks||null},apply(n,e,t,r){return r.selection.$cursor?n.storedMarks:null}}),new Ln("scrollToSelection",{init(){return 0},apply(n,e){return n.scrolledIntoView?e+1:e}})];class fs{constructor(e,t){this.schema=e,this.plugins=[],this.pluginsByKey=Object.create(null),this.fields=Ey.slice(),t&&t.forEach(r=>{if(this.pluginsByKey[r.key])throw new RangeError("Adding different instances of a keyed plugin ("+r.key+")");this.plugins.push(r),this.pluginsByKey[r.key]=r,r.spec.state&&this.fields.push(new Ln(r.key,r.spec.state,r))})}}class nn{constructor(e){this.config=e}get schema(){return this.config.schema}get plugins(){return this.config.plugins}apply(e){return this.applyTransaction(e).state}filterTransaction(e,t=-1){for(let r=0;rr.toJSON())),e&&typeof e=="object")for(let r in e){if(r=="doc"||r=="selection")throw new RangeError("The JSON fields `doc` and `selection` are reserved");let i=e[r],s=i.spec.state;s&&s.toJSON&&(t[r]=s.toJSON.call(i,this[i.key]))}return t}static fromJSON(e,t,r){if(!t)throw new RangeError("Invalid input for EditorState.fromJSON");if(!e.schema)throw new RangeError("Required config field 'schema' missing");let i=new fs(e.schema,e.plugins),s=new nn(i);return i.fields.forEach(o=>{if(o.name=="doc")s.doc=Ht.fromJSON(e.schema,t.doc);else if(o.name=="selection")s.selection=P.fromJSON(s.doc,t.selection);else if(o.name=="storedMarks")t.storedMarks&&(s.storedMarks=t.storedMarks.map(e.schema.markFromJSON));else{if(r)for(let l in r){let a=r[l],c=a.spec.state;if(a.key==o.name&&c&&c.fromJSON&&Object.prototype.hasOwnProperty.call(t,l)){s[o.name]=c.fromJSON.call(a,e,t[l],s);return}}s[o.name]=o.init(e,s)}}),s}}function Pd(n,e,t){for(let r in n){let i=n[r];i instanceof Function?i=i.bind(e):r=="handleDOMEvents"&&(i=Pd(i,e,{})),t[r]=i}return t}class me{constructor(e){this.spec=e,this.props={},e.props&&Pd(e.props,this,this.props),this.key=e.key?e.key.key:Ld("plugin")}getState(e){return e[this.key]}}const hs=Object.create(null);function Ld(n){return n in hs?n+"$"+ ++hs[n]:(hs[n]=0,n+"$")}class Ue{constructor(e="key"){this.key=Ld(e)}get(e){return e.config.pluginsByKey[this.key]}getState(e){return e[this.key]}}const le=function(n){for(var e=0;;e++)if(n=n.previousSibling,!n)return e},Qn=function(n){let e=n.assignedSlot||n.parentNode;return e&&e.nodeType==11?e.host:e};let Ea=null;const We=function(n,e,t){let r=Ea||(Ea=document.createRange());return r.setEnd(n,t??n.nodeValue.length),r.setStart(n,e||0),r},qt=function(n,e,t,r){return t&&(va(n,e,t,r,-1)||va(n,e,t,r,1))},vy=/^(img|br|input|textarea|hr)$/i;function va(n,e,t,r,i){for(;;){if(n==t&&e==r)return!0;if(e==(i<0?0:Be(n))){let s=n.parentNode;if(!s||s.nodeType!=1||ol(n)||vy.test(n.nodeName)||n.contentEditable=="false")return!1;e=le(n)+(i<0?0:1),n=s}else if(n.nodeType==1){if(n=n.childNodes[e+(i<0?-1:0)],n.contentEditable=="false")return!1;e=i<0?Be(n):0}else return!1}}function Be(n){return n.nodeType==3?n.nodeValue.length:n.childNodes.length}function My(n,e,t){for(let r=e==0,i=e==Be(n);r||i;){if(n==t)return!0;let s=le(n);if(n=n.parentNode,!n)return!1;r=r&&s==0,i=i&&s==Be(n)}}function ol(n){let e;for(let t=n;t&&!(e=t.pmViewDesc);t=t.parentNode);return e&&e.node&&e.node.isBlock&&(e.dom==n||e.contentDOM==n)}const Fi=function(n){return n.focusNode&&qt(n.focusNode,n.focusOffset,n.anchorNode,n.anchorOffset)};function Ct(n,e){let t=document.createEvent("Event");return t.initEvent("keydown",!0,!0),t.keyCode=n,t.key=t.code=e,t}function Cy(n){let e=n.activeElement;for(;e&&e.shadowRoot;)e=e.shadowRoot.activeElement;return e}function Oy(n,e,t){if(n.caretPositionFromPoint)try{let r=n.caretPositionFromPoint(e,t);if(r)return{node:r.offsetNode,offset:r.offset}}catch{}if(n.caretRangeFromPoint){let r=n.caretRangeFromPoint(e,t);if(r)return{node:r.startContainer,offset:r.startOffset}}}const He=typeof navigator<"u"?navigator:null,Ma=typeof document<"u"?document:null,kt=He&&He.userAgent||"",lo=/Edge\/(\d+)/.exec(kt),Bd=/MSIE \d/.exec(kt),ao=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(kt),he=!!(Bd||ao||lo),dt=Bd?document.documentMode:ao?+ao[1]:lo?+lo[1]:0,Ne=!he&&/gecko\/(\d+)/i.test(kt);Ne&&+(/Firefox\/(\d+)/.exec(kt)||[0,0])[1];const co=!he&&/Chrome\/(\d+)/.exec(kt),se=!!co,Ty=co?+co[1]:0,ce=!he&&!!He&&/Apple Computer/.test(He.vendor),bn=ce&&(/Mobile\/\w+/.test(kt)||!!He&&He.maxTouchPoints>2),xe=bn||(He?/Mac/.test(He.platform):!1),Ay=He?/Win/.test(He.platform):!1,Ce=/Android \d/.test(kt),dr=!!Ma&&"webkitFontSmoothing"in Ma.documentElement.style,Ny=dr?+(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent)||[0,0])[1]:0;function Ry(n){return{left:0,right:n.documentElement.clientWidth,top:0,bottom:n.documentElement.clientHeight}}function Ke(n,e){return typeof n=="number"?n:n[e]}function Dy(n){let e=n.getBoundingClientRect(),t=e.width/n.offsetWidth||1,r=e.height/n.offsetHeight||1;return{left:e.left,right:e.left+n.clientWidth*t,top:e.top,bottom:e.top+n.clientHeight*r}}function Ca(n,e,t){let r=n.someProp("scrollThreshold")||0,i=n.someProp("scrollMargin")||5,s=n.dom.ownerDocument;for(let o=t||n.dom;o;o=Qn(o)){if(o.nodeType!=1)continue;let l=o,a=l==s.body,c=a?Ry(s):Dy(l),u=0,d=0;if(e.topc.bottom-Ke(r,"bottom")&&(d=e.bottom-e.top>c.bottom-c.top?e.top+Ke(i,"top")-c.top:e.bottom-c.bottom+Ke(i,"bottom")),e.leftc.right-Ke(r,"right")&&(u=e.right-c.right+Ke(i,"right")),u||d)if(a)s.defaultView.scrollBy(u,d);else{let f=l.scrollLeft,p=l.scrollTop;d&&(l.scrollTop+=d),u&&(l.scrollLeft+=u);let h=l.scrollLeft-f,g=l.scrollTop-p;e={left:e.left-h,top:e.top-g,right:e.right-h,bottom:e.bottom-g}}if(a||/^(fixed|sticky)$/.test(getComputedStyle(o).position))break}}function Iy(n){let e=n.dom.getBoundingClientRect(),t=Math.max(0,e.top),r,i;for(let s=(e.left+e.right)/2,o=t+1;o=t-20){r=l,i=a.top;break}}return{refDOM:r,refTop:i,stack:Fd(n.dom)}}function Fd(n){let e=[],t=n.ownerDocument;for(let r=n;r&&(e.push({dom:r,top:r.scrollTop,left:r.scrollLeft}),n!=t);r=Qn(r));return e}function _y({refDOM:n,refTop:e,stack:t}){let r=n?n.getBoundingClientRect().top:0;zd(t,r==0?0:r-e)}function zd(n,e){for(let t=0;t=l){o=Math.max(h.bottom,o),l=Math.min(h.top,l);let g=h.left>e.left?h.left-e.left:h.right=(h.left+h.right)/2?1:0));continue}}else h.top>e.top&&!a&&h.left<=e.left&&h.right>=e.left&&(a=u,c={left:Math.max(h.left,Math.min(h.right,e.left)),top:h.top});!t&&(e.left>=h.right&&e.top>=h.top||e.left>=h.left&&e.top>=h.bottom)&&(s=d+1)}}return!t&&a&&(t=a,i=c,r=0),t&&t.nodeType==3?Ly(t,i):!t||r&&t.nodeType==1?{node:n,offset:s}:$d(t,i)}function Ly(n,e){let t=n.nodeValue.length,r=document.createRange();for(let i=0;i=(s.left+s.right)/2?1:0)}}return{node:n,offset:0}}function ll(n,e){return n.left>=e.left-1&&n.left<=e.right+1&&n.top>=e.top-1&&n.top<=e.bottom+1}function By(n,e){let t=n.parentNode;return t&&/^li$/i.test(t.nodeName)&&e.left(o.left+o.right)/2?1:-1}return n.docView.posFromDOM(r,i,s)}function zy(n,e,t,r){let i=-1;for(let s=e,o=!1;s!=n.dom;){let l=n.docView.nearestDesc(s,!0);if(!l)return null;if(l.dom.nodeType==1&&(l.node.isBlock&&l.parent&&!o||!l.contentDOM)){let a=l.dom.getBoundingClientRect();if(l.node.isBlock&&l.parent&&!o&&(o=!0,a.left>r.left||a.top>r.top?i=l.posBefore:(a.right-1?i:n.docView.posFromDOM(e,t,-1)}function Hd(n,e,t){let r=n.childNodes.length;if(r&&t.tope.top&&i++}let c;dr&&i&&r.nodeType==1&&(c=r.childNodes[i-1]).nodeType==1&&c.contentEditable=="false"&&c.getBoundingClientRect().top>=e.top&&i--,r==n.dom&&i==r.childNodes.length-1&&r.lastChild.nodeType==1&&e.top>r.lastChild.getBoundingClientRect().bottom?l=n.state.doc.content.size:(i==0||r.nodeType!=1||r.childNodes[i-1].nodeName!="BR")&&(l=zy(n,r,i,e))}l==null&&(l=Fy(n,o,e));let a=n.docView.nearestDesc(o,!0);return{pos:l,inside:a?a.posAtStart-a.border:-1}}function Oa(n){return n.top=0&&i==r.nodeValue.length?(a--,u=1):t<0?a--:c++,Dn(rt(We(r,a,c),u),u<0)}if(!n.state.doc.resolve(e-(s||0)).parent.inlineContent){if(s==null&&i&&(t<0||i==Be(r))){let a=r.childNodes[i-1];if(a.nodeType==1)return ps(a.getBoundingClientRect(),!1)}if(s==null&&i=0)}if(s==null&&i&&(t<0||i==Be(r))){let a=r.childNodes[i-1],c=a.nodeType==3?We(a,Be(a)-(o?0:1)):a.nodeType==1&&(a.nodeName!="BR"||!a.nextSibling)?a:null;if(c)return Dn(rt(c,1),!1)}if(s==null&&i=0)}function Dn(n,e){if(n.width==0)return n;let t=e?n.left:n.right;return{top:n.top,bottom:n.bottom,left:t,right:t}}function ps(n,e){if(n.height==0)return n;let t=e?n.top:n.bottom;return{top:t,bottom:t,left:n.left,right:n.right}}function Vd(n,e,t){let r=n.state,i=n.root.activeElement;r!=e&&n.updateState(e),i!=n.dom&&n.focus();try{return t()}finally{r!=e&&n.updateState(r),i!=n.dom&&i&&i.focus()}}function jy(n,e,t){let r=e.selection,i=t=="up"?r.$from:r.$to;return Vd(n,e,()=>{let{node:s}=n.docView.domFromPos(i.pos,t=="up"?-1:1);for(;;){let l=n.docView.nearestDesc(s,!0);if(!l)break;if(l.node.isBlock){s=l.contentDOM||l.dom;break}s=l.dom.parentNode}let o=jd(n,i.pos,1);for(let l=s.firstChild;l;l=l.nextSibling){let a;if(l.nodeType==1)a=l.getClientRects();else if(l.nodeType==3)a=We(l,0,l.nodeValue.length).getClientRects();else continue;for(let c=0;cu.top+1&&(t=="up"?o.top-u.top>(u.bottom-o.top)*2:u.bottom-o.bottom>(o.bottom-u.top)*2))return!1}}return!0})}const Vy=/[\u0590-\u08ac]/;function Uy(n,e,t){let{$head:r}=e.selection;if(!r.parent.isTextblock)return!1;let i=r.parentOffset,s=!i,o=i==r.parent.content.size,l=n.domSelection();return!Vy.test(r.parent.textContent)||!l.modify?t=="left"||t=="backward"?s:o:Vd(n,e,()=>{let{focusNode:a,focusOffset:c,anchorNode:u,anchorOffset:d}=n.domSelectionRange(),f=l.caretBidiLevel;l.modify("move",t,"character");let p=r.depth?n.docView.domAfterPos(r.before()):n.dom,{focusNode:h,focusOffset:g}=n.domSelectionRange(),m=h&&!p.contains(h.nodeType==1?h:h.parentNode)||a==h&&c==g;try{l.collapse(u,d),a&&(a!=u||c!=d)&&l.extend&&l.extend(a,c)}catch{}return f!=null&&(l.caretBidiLevel=f),m})}let Ta=null,Aa=null,Na=!1;function Ky(n,e,t){return Ta==e&&Aa==t?Na:(Ta=e,Aa=t,Na=t=="up"||t=="down"?jy(n,e,t):Uy(n,e,t))}const we=0,Ra=1,Rt=2,je=3;class fr{constructor(e,t,r,i){this.parent=e,this.children=t,this.dom=r,this.contentDOM=i,this.dirty=we,r.pmViewDesc=this}matchesWidget(e){return!1}matchesMark(e){return!1}matchesNode(e,t,r){return!1}matchesHack(e){return!1}parseRule(){return null}stopEvent(e){return!1}get size(){let e=0;for(let t=0;tle(this.contentDOM);else if(this.contentDOM&&this.contentDOM!=this.dom&&this.dom.contains(this.contentDOM))i=e.compareDocumentPosition(this.contentDOM)&2;else if(this.dom.firstChild){if(t==0)for(let s=e;;s=s.parentNode){if(s==this.dom){i=!1;break}if(s.previousSibling)break}if(i==null&&t==e.childNodes.length)for(let s=e;;s=s.parentNode){if(s==this.dom){i=!0;break}if(s.nextSibling)break}}return i??r>0?this.posAtEnd:this.posAtStart}nearestDesc(e,t=!1){for(let r=!0,i=e;i;i=i.parentNode){let s=this.getDesc(i),o;if(s&&(!t||s.node))if(r&&(o=s.nodeDOM)&&!(o.nodeType==1?o.contains(e.nodeType==1?e:e.parentNode):o==e))r=!1;else return s}}getDesc(e){let t=e.pmViewDesc;for(let r=t;r;r=r.parent)if(r==this)return t}posFromDOM(e,t,r){for(let i=e;i;i=i.parentNode){let s=this.getDesc(i);if(s)return s.localPosFromDOM(e,t,r)}return-1}descAt(e){for(let t=0,r=0;te||o instanceof Kd){i=e-s;break}s=l}if(i)return this.children[r].domFromPos(i-this.children[r].border,t);for(let s;r&&!(s=this.children[r-1]).size&&s instanceof Ud&&s.side>=0;r--);if(t<=0){let s,o=!0;for(;s=r?this.children[r-1]:null,!(!s||s.dom.parentNode==this.contentDOM);r--,o=!1);return s&&t&&o&&!s.border&&!s.domAtom?s.domFromPos(s.size,t):{node:this.contentDOM,offset:s?le(s.dom)+1:0}}else{let s,o=!0;for(;s=r=u&&t<=c-a.border&&a.node&&a.contentDOM&&this.contentDOM.contains(a.contentDOM))return a.parseRange(e,t,u);e=o;for(let d=l;d>0;d--){let f=this.children[d-1];if(f.size&&f.dom.parentNode==this.contentDOM&&!f.emptyChildAt(1)){i=le(f.dom)+1;break}e-=f.size}i==-1&&(i=0)}if(i>-1&&(c>t||l==this.children.length-1)){t=c;for(let u=l+1;up&&o { window.Alpine.data('theme', () => { return { systemMode: window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light', - theme: window.$cookie.get('__root_theme', 'system'), + theme: window.$cookie.get('theme', 'system'), init() { window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => { if (this.theme === 'system') { @@ -23,7 +23,7 @@ document.addEventListener('alpine:init', () => { change(theme) { document.documentElement.classList.add('no-transition'); - window.$cookie.set('__root_theme', theme); + window.$cookie.set('theme', theme); this.theme = theme; diff --git a/routes/api.php b/routes/api.php index 0861051b..b7495536 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,14 +1,7 @@ except(['store']); - -// Resource Fields -Route::any('/{resource}/fields/{field}', ResourceFieldController::class)->where('field', '.*'); - -// Actions -// Action Fields diff --git a/src/Actions/Action.php b/src/Actions/Action.php index e454c285..28265af8 100644 --- a/src/Actions/Action.php +++ b/src/Actions/Action.php @@ -3,16 +3,19 @@ namespace Cone\Root\Actions; use Cone\Root\Fields\Field; +use Cone\Root\Http\Controllers\ActionController; use Cone\Root\Interfaces\Form; use Cone\Root\Support\Alert; use Cone\Root\Traits\AsForm; use Cone\Root\Traits\Authorizable; use Cone\Root\Traits\Makeable; +use Cone\Root\Traits\RegistersRoutes; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Concerns\HasAttributes; use Illuminate\Http\Request; +use Illuminate\Routing\Router; use Illuminate\Support\Facades\Redirect; use Illuminate\Support\MessageBag; use Illuminate\Support\Str; @@ -25,6 +28,9 @@ abstract class Action implements Arrayable, Form, JsonSerializable use Authorizable; use HasAttributes; use Makeable; + use RegistersRoutes { + RegistersRoutes::registerRoutes as __registerRoutes; + } /** * The Blade template. @@ -46,11 +52,6 @@ abstract class Action implements Arrayable, Form, JsonSerializable */ protected ?Builder $query = null; - /** - * The API URI. - */ - protected ?string $apiUri = null; - /** * Handle the action. */ @@ -96,24 +97,6 @@ public function getTemplate(): string return $this->template; } - /** - * Set the API URI. - */ - public function setApiUri(string $apiUri): static - { - $this->apiUri = $apiUri; - - return $this; - } - - /** - * Get the API URI. - */ - public function getApiUri(): ?string - { - return $this->apiUri; - } - /** * Set the Eloquent query. */ @@ -129,7 +112,6 @@ public function setQuery(Builder $query): static */ protected function resolveField(Request $request, Field $field): void { - $field->setApiUri(sprintf('/%s/fields/%s', $this->getApiUri(), $field->getUriKey())); $field->setAttribute('form', $this->getKey()); $field->resolveErrorsUsing(function (Request $request): MessageBag { return $this->errors($request); @@ -190,6 +172,26 @@ public function perform(Request $request): Response ); } + /** + * Register the routes using the given router. + */ + public function registerRoutes(Request $request, Router $router): void + { + $this->__registerRoutes($request, $router); + + $router->prefix($this->getUriKey())->group(function (Router $router) use ($request): void { + $this->resolveFields($request)->registerRoutes($request, $router); + }); + } + + /** + * The routes that should be registered. + */ + public function routes(Router $router): void + { + $router->post('/', ActionController::class); + } + /** * Convert the element to a JSON serializable format. */ @@ -210,7 +212,7 @@ public function toArray(): array 'modalKey' => $this->getModalKey(), 'name' => $this->getName(), 'template' => $this->getTemplate(), - 'url' => $this->getApiUri(), + 'url' => $this->getUri(), ]; } diff --git a/src/Actions/Actions.php b/src/Actions/Actions.php index c7014b0a..98ef80f8 100644 --- a/src/Actions/Actions.php +++ b/src/Actions/Actions.php @@ -2,7 +2,9 @@ namespace Cone\Root\Actions; +use Cone\Root\Traits\RegistersRoutes; use Illuminate\Http\Request; +use Illuminate\Routing\Router; use Illuminate\Support\Arr; use Illuminate\Support\Collection; @@ -27,4 +29,18 @@ public function mapToTableComponents(Request $request): array { return $this->map->toTableComponent($request)->all(); } + + /** + * Register the action routes. + */ + public function registerRoutes(Request $request, Router $router): void + { + $router->prefix('actions')->group(function (Router $router) use ($request): void { + $this->each(static function (Action $action) use ($request, $router): void { + if (in_array(RegistersRoutes::class, class_uses_recursive($action))) { + $action->registerRoutes($request, $router); + } + }); + }); + } } diff --git a/src/Fields/BelongsToMany.php b/src/Fields/BelongsToMany.php index a3fbf2e2..a5e2b054 100644 --- a/src/Fields/BelongsToMany.php +++ b/src/Fields/BelongsToMany.php @@ -31,7 +31,6 @@ public function __construct(string $label, string $modelAttribute = null, Closur parent::__construct($label, $modelAttribute, $relation); $this->setAttribute('multiple', true); - $this->name($this->modelAttribute.'[]'); } /** @@ -49,10 +48,8 @@ public function getRelation(Model $model): EloquentRelation */ protected function resolveField(Request $request, Field $field): void { - if (! is_null($this->apiUri)) { - $field->setApiUri(sprintf('%s/%s', $this->apiUri, $field->getUriKey())); - } - + $field->setAttribute('form', $this->getAttribute('form')); + $field->resolveErrorsUsing($this->errorsResolver); $field->setModelAttribute( sprintf('%s.*.%s', $this->getModelAttribute(), $field->getModelAttribute()) ); @@ -105,6 +102,13 @@ public function toOption(Request $request, Model $model, Model $related): array $option = parent::toOption($request, $model, $related); + $option['attrs']['name'] = sprintf( + '%s[%s][%s]', + $this->getAttribute('name'), + $related->getKey(), + $this->getRelation($model)->getRelatedPivotKeyName() + ); + $option['fields'] = is_null($this->pivotFieldsResolver) ? new Fields() : call_user_func_array($this->pivotFieldsResolver, [$request, $model, $related]); diff --git a/src/Fields/Editor.php b/src/Fields/Editor.php index 8ffc5cc6..3b172904 100644 --- a/src/Fields/Editor.php +++ b/src/Fields/Editor.php @@ -4,14 +4,19 @@ use Closure; use Cone\Root\Models\Medium; +use Cone\Root\Traits\RegistersRoutes; use Cone\Root\Traits\ResolvesFields; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\MorphToMany; use Illuminate\Http\Request; +use Illuminate\Routing\Router; use Illuminate\Support\Facades\Config; class Editor extends Field { + use RegistersRoutes { + RegistersRoutes::registerRoutes as __registerRoutes; + } use ResolvesFields; /** @@ -41,17 +46,11 @@ public function __construct(string $label, string $modelAttribute = null) } /** - * {@inheritdoc} + * Get the URI key. */ - public function setApiUri(string $apiUri): static + public function getUriKey(): string { - if (! is_null($this->media)) { - $this->media->setApiUri( - sprintf('%s/%s', $apiUri, $this->media->getUriKey()) - ); - } - - return parent::setApiUri($apiUri); + return str_replace('.', '-', $this->getRequestKey()); } /** @@ -142,6 +141,20 @@ public function __construct(string $modelAttribute) }; } + /** + * Register the routes using the given router. + */ + public function registerRoutes(Request $request, Router $router): void + { + $this->__registerRoutes($request, $router); + + if (! is_null($this->media)) { + $router->prefix($this->getUriKey())->group(function (Router $router) use ($request): void { + $this->media->registerRoutes($request, $router); + }); + } + } + /** * {@inheritdoc} */ diff --git a/src/Fields/Field.php b/src/Fields/Field.php index 18ce8f0a..b6aeca16 100644 --- a/src/Fields/Field.php +++ b/src/Fields/Field.php @@ -9,7 +9,6 @@ use Illuminate\Contracts\Support\Arrayable; use Illuminate\Contracts\Support\MessageBag; use Illuminate\Database\Eloquent\Model; -use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Support\Arr; use Illuminate\Support\Str; @@ -83,11 +82,6 @@ abstract class Field implements Arrayable, JsonSerializable */ protected bool $withOldValue = true; - /** - * The API URI. - */ - protected ?string $apiUri = null; - /** * Indicates if the field has been hydrated. */ @@ -148,40 +142,6 @@ public function getValidationKey(): string return $this->getRequestKey(); } - /** - * Get the URI key. - */ - public function getUriKey(): string - { - return str_replace('.', '-', $this->getRequestKey()); - } - - /** - * Set the API URI. - */ - public function setApiUri(string $apiUri): static - { - $this->apiUri = $apiUri; - - return $this; - } - - /** - * Get the API URI. - */ - public function getApiUri(): ?string - { - return $this->apiUri; - } - - /** - * Handle the incoming API request. - */ - public function handleApiRequest(Request $request, Model $model): JsonResponse - { - return new JsonResponse($this->toArray()); - } - /** * Set the label attribute. */ @@ -352,7 +312,7 @@ public function hydrate(Closure $callback): static public function resolveHydrate(Request $request, Model $model, mixed $value): void { if (is_null($this->hydrateResolver)) { - $this->hydrateResolver = function () use ($model, $value): void { + $this->hydrateResolver = function (Request $request, Model $model, $value): void { $model->setAttribute($this->getModelAttribute(), $value); }; } diff --git a/src/Fields/Fields.php b/src/Fields/Fields.php index 17bf7312..f456d335 100644 --- a/src/Fields/Fields.php +++ b/src/Fields/Fields.php @@ -2,8 +2,10 @@ namespace Cone\Root\Fields; +use Cone\Root\Traits\RegistersRoutes; use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Request; +use Illuminate\Routing\Router; use Illuminate\Support\Arr; use Illuminate\Support\Collection; @@ -50,4 +52,18 @@ public function mapToFormComponents(Request $request, Model $model): array { return $this->map->toFormComponent($request, $model)->all(); } + + /** + * Register the field routes. + */ + public function registerRoutes(Request $request, Router $router): void + { + $router->prefix('fields')->group(function (Router $router) use ($request): void { + $this->each(static function (Field $field) use ($request, $router): void { + if (in_array(RegistersRoutes::class, class_uses_recursive($field))) { + $field->registerRoutes($request, $router); + } + }); + }); + } } diff --git a/src/Fields/Fieldset.php b/src/Fields/Fieldset.php index 141d9cf3..1a386a9b 100644 --- a/src/Fields/Fieldset.php +++ b/src/Fields/Fieldset.php @@ -2,13 +2,16 @@ namespace Cone\Root\Fields; +use Cone\Root\Traits\RegistersRoutes; use Cone\Root\Traits\ResolvesFields; use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Request; +use Illuminate\Routing\Router; use Illuminate\Support\Facades\App; class Fieldset extends Field { + use RegistersRoutes; use ResolvesFields; /** @@ -16,14 +19,31 @@ class Fieldset extends Field */ protected string $template = 'root::fields.fieldset'; + /** + * Get the URI key. + */ + public function getUriKey(): string + { + return str_replace('.', '-', $this->getRequestKey()); + } + /** * Handle the callback for the field resolution. */ protected function resolveField(Request $request, Field $field): void { - if (! is_null($this->apiUri)) { - $field->setApiUri(sprintf('%s/%s', $this->apiUri, $field->getUriKey())); - } + $field->setAttribute('form', $this->getAttribute('form')); + $field->resolveErrorsUsing($this->errorsResolver); + } + + /** + * Register the routes using the given router. + */ + public function registerRoutes(Request $request, Router $router): void + { + $router->prefix($this->getUriKey())->group(function (Router $router) use ($request): void { + $this->resolveFields($request)->registerRoutes($request, $router); + }); } /** diff --git a/src/Fields/File.php b/src/Fields/File.php index 187375b2..d52bc9fe 100644 --- a/src/Fields/File.php +++ b/src/Fields/File.php @@ -106,14 +106,6 @@ public function resolveOptions(Request $request, Model $model): array ->all(); } - /** - * {@inheritdoc} - */ - public function newOption(Model $related, string $label): Option - { - return new Option($related, $label); - } - /** * Set the storage resolver callback. */ diff --git a/src/Fields/Media.php b/src/Fields/Media.php index 7162fddb..29548442 100644 --- a/src/Fields/Media.php +++ b/src/Fields/Media.php @@ -2,12 +2,15 @@ namespace Cone\Root\Fields; +use Cone\Root\Http\Controllers\MediaController; use Cone\Root\Models\Medium; use Cone\Root\Traits\HasMedia; +use Cone\Root\Traits\RegistersRoutes; use Illuminate\Database\Eloquent\Model; -use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Http\UploadedFile; +use Illuminate\Routing\Router; +use Illuminate\Support\Arr; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\View; @@ -15,10 +18,9 @@ class Media extends File { - /** - * Indicates if the component is async. - */ - protected bool $async = true; + use RegistersRoutes { + RegistersRoutes::registerRoutes as __registerRoutes; + } /** * Indicates if the component is multiple. @@ -30,6 +32,22 @@ class Media extends File */ protected string $template = 'root::fields.media'; + /** + * Get the URI key. + */ + public function getUriKey(): string + { + return str_replace('.', '-', $this->getRequestKey()); + } + + /** + * Get the route parameter name. + */ + public function getRouteParameterName(): string + { + return 'field'; + } + /** * Get the modal key. */ @@ -68,13 +86,11 @@ public function paginate(Request $request, Model $model): array ->latest() ->paginate($request->input('per_page')) ->withQueryString() - ->setPath($this->apiUri) + ->setPath($this->getUri()) ->through(function (Medium $related) use ($request, $model): array { $option = $this->toOption($request, $model, $related); - $option['fields'] = array_map(static function (Field $field) use ($request, $model): array { - return $field->toFormComponent($request, $model); - }, $option['fields']); + $option['fields'] = $option['fields']->mapToFormComponents($request, $model); return array_merge($option, [ 'html' => View::make('root::fields.file-option', $option)->render(), @@ -137,6 +153,38 @@ public function store(Request $request, Model $model, UploadedFile $file): array return $this->stored($request, $model, $disk->path($file->getClientOriginalName())); } + /** + * Build the URI for the given request and model. + */ + public function buildUri(Request $request, Model $model): ?string + { + $uri = sprintf('%s?%s', $this->getUri(), Arr::query(array_filter([ + 'model' => $model->getKey(), + ]))); + + return rtrim($uri, '?'); + } + + /** + * Register the routes using the given router. + */ + public function registerRoutes(Request $request, Router $router): void + { + $this->__registerRoutes($request, $router); + + $router->prefix($this->getUriKey())->group(function (Router $router) use ($request): void { + $this->resolveFields($request)->registerRoutes($request, $router); + }); + } + + /** + * The routes that should be registered. + */ + public function routes(Router $router): void + { + $router->match(['GET', 'POST', 'DELETE'], '/', MediaController::class); + } + /** * {@inheritdoc} */ @@ -158,19 +206,7 @@ public function toFormComponent(Request $request, Model $model): array 'html' => View::make('root::fields.file-option', $option)->render(), ]); }, $data['options'] ?? []), + 'url' => $this->getUri() ? $this->buildUri($request, $model) : null, ]); } - - /** - * {@inheritdoc} - */ - public function handleApiRequest(Request $request, Model $model): JsonResponse - { - return match ($request->method()) { - 'GET' => new JsonResponse($this->paginate($request, $model)), - 'POST' => new JsonResponse($this->upload($request, $model), JsonResponse::HTTP_CREATED), - 'DELETE' => new JsonResponse(['deleted' => $this->prune($request, $model, $request->input('ids', []))]), - default => parent::handleApiRequest($request, $model), - }; - } } diff --git a/src/Fields/Relation.php b/src/Fields/Relation.php index fdd80a23..3f9c3fcf 100644 --- a/src/Fields/Relation.php +++ b/src/Fields/Relation.php @@ -25,11 +25,6 @@ abstract class Relation extends Field */ protected bool $nullable = false; - /** - * Indicates if the component is async. - */ - protected bool $async = false; - /** * The Blade template. */ @@ -151,26 +146,6 @@ public function resolveDisplay(Model $related): mixed return call_user_func_array($this->displayResolver, [$related]); } - /** - * Set the async attribute. - */ - public function async(bool $value = true): static - { - $this->async = $value; - - // $this->template = $value ? 'root::fields.dropdown' : 'root::fields.select'; - - return $this; - } - - /** - * Determine if the field is asnyc. - */ - public function isAsync(): bool - { - return $this->async; - } - /** * {@inheritdoc} */ @@ -256,20 +231,6 @@ public function newOption(Model $related, string $label): Option return new Option($related->getKey(), $label); } - /** - * Build the API URI. - */ - protected function buildApiUri(Model $model): ?string - { - if (is_null($this->apiUri)) { - return $this->apiUri; - } - - return sprintf('%s?%s', $this->apiUri, http_build_query([ - 'model' => $model->getKey(), - ])); - } - /** * Get the option representation of the model and the related model. */ @@ -289,10 +250,8 @@ public function toOption(Request $request, Model $model, Model $related): array public function toFormComponent(Request $request, Model $model): array { return array_merge(parent::toFormComponent($request, $model), [ - 'async' => $this->isAsync(), 'nullable' => $this->isNullable(), - 'options' => $this->isAsync() ? [] : $this->resolveOptions($request, $model), - 'url' => $this->isAsync() ? $this->buildApiUri($model) : null, + 'options' => $this->resolveOptions($request, $model), ]); } } diff --git a/src/Fields/Repeater.php b/src/Fields/Repeater.php index e0ea2fc5..e40119a3 100644 --- a/src/Fields/Repeater.php +++ b/src/Fields/Repeater.php @@ -3,15 +3,20 @@ namespace Cone\Root\Fields; use Closure; +use Cone\Root\Http\Controllers\RepeaterController; +use Cone\Root\Traits\RegistersRoutes; use Cone\Root\Traits\ResolvesFields; use Illuminate\Database\Eloquent\Model; -use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Illuminate\Routing\Router; use Illuminate\Support\Facades\View; use Illuminate\Support\Str; class Repeater extends Field { + use RegistersRoutes { + RegistersRoutes::registerRoutes as __registerRoutes; + } use ResolvesFields { ResolvesFields::withFields as __withFields; } @@ -31,6 +36,22 @@ class Repeater extends Field */ protected ?int $max = null; + /** + * Get the URI key. + */ + public function getUriKey(): string + { + return str_replace('.', '-', $this->getRequestKey()); + } + + /** + * Get the route parameter name. + */ + public function getRouteParameterName(): string + { + return 'field'; + } + /** * Set the maximum number of options. */ @@ -78,10 +99,6 @@ public function getOldValue(Request $request): mixed */ protected function resolveField(Request $request, Field $field): void { - if (! is_null($this->apiUri)) { - $field->setApiUri(sprintf('%s/%s', $this->apiUri, $field->getUriKey())); - } - $field->setModelAttribute( sprintf('%s.*.%s', $this->getModelAttribute(), $field->getModelAttribute()) ); @@ -163,6 +180,26 @@ public function buildOption(Request $request, Model $model): array return $option; } + /** + * Register the routes using the given router. + */ + public function registerRoutes(Request $request, Router $router): void + { + $this->__registerRoutes($request, $router); + + $router->prefix($this->getUriKey())->group(function (Router $router) use ($request): void { + $this->resolveFields($request)->registerRoutes($request, $router); + }); + } + + /** + * The routes that should be registered. + */ + public function routes(Router $router): void + { + $router->post('/', RepeaterController::class); + } + /** * Get the option representation of the model and the temporary model. */ @@ -193,7 +230,7 @@ public function toFormComponent(Request $request, Model $model): array 'html' => View::make('root::fields.repeater-option', $option)->render(), ]); }, $this->resolveOptions($request, $model)), - 'url' => $this->getApiUri(), + 'url' => $this->getUri(), ]); } @@ -207,15 +244,4 @@ public function toValidate(Request $request, Model $model): array $this->resolveFields($request)->mapToValidate($request, $model) ); } - - /** - * {@inheritdoc} - */ - public function handleApiRequest(Request $request, Model $model): JsonResponse - { - return match ($request->method()) { - 'POST' => new JsonResponse($this->buildOption($request, $model)), - default => parent::handleApiRequest($request, $model), - }; - } } diff --git a/src/Fields/Slug.php b/src/Fields/Slug.php index 44fb5076..c71084c8 100644 --- a/src/Fields/Slug.php +++ b/src/Fields/Slug.php @@ -32,6 +32,11 @@ class Slug extends Text */ protected bool $unique = false; + /** + * Indicates if the slug field is nullable. + */ + protected bool $nullable = false; + /** * The slug resolver. */ @@ -49,15 +54,23 @@ public function __construct(string $label, string $modelAttribute = null) $this->unique(); } + /** + * Set the "nullable" property. + */ + public function nullable(bool $value = true): static + { + $this->nullable = $value; + + return $this; + } + /** * {@inheritdoc} */ public function persist(Request $request, Model $model, mixed $value): void { - if ($model->exists || ! empty($value)) { - parent::persist($request, $model, $value); - } else { - $model->saved(function (Model $model) use ($request, $value): void { + if (! $model->exists) { + $model->saved(function (Model $model) use ($request): void { $value = $this->generate($request, $model); $this->resolveHydrate($request, $model, $value); @@ -67,6 +80,8 @@ public function persist(Request $request, Model $model, mixed $value): void }); }); } + + parent::persist($request, $model, $value); } /** @@ -74,7 +89,13 @@ public function persist(Request $request, Model $model, mixed $value): void */ public function getValueForHydrate(Request $request): mixed { - return Str::slug(parent::getValueForHydrate($request), $this->separator); + $value = parent::getValueForHydrate($request); + + if (! $this->nullable && empty($value)) { + $value = Str::random(); + } + + return Str::slug($value, $this->separator); } /** diff --git a/src/Http/Controllers/ActionController.php b/src/Http/Controllers/ActionController.php index 4f0421e1..d16e1a00 100644 --- a/src/Http/Controllers/ActionController.php +++ b/src/Http/Controllers/ActionController.php @@ -14,7 +14,7 @@ class ActionController extends Controller public function __invoke(Request $request): RedirectResponse { /** @var \Cone\Root\Actions\Action $action */ - $action = $request->route('rootAction'); + $action = $request->route('action'); Gate::allowIf($action->authorized($request)); diff --git a/src/Http/Controllers/MediaController.php b/src/Http/Controllers/MediaController.php new file mode 100644 index 00000000..332a54c1 --- /dev/null +++ b/src/Http/Controllers/MediaController.php @@ -0,0 +1,32 @@ +route('_resource'); + + $field = $request->route('field'); + + // Gate::allowIf($field->authorized($request, $model)); + + $model = $request->filled('model') + ? $resource->resolveRouteBinding($request, $request->input('model')) + : $resource->getModelInstance(); + + return match ($request->method()) { + 'GET' => new JsonResponse($field->paginate($request, $model)), + 'POST' => new JsonResponse($field->upload($request, $model), JsonResponse::HTTP_CREATED), + 'DELETE' => new JsonResponse(['deleted' => $field->prune($request, $model, $request->input('ids', []))]), + }; + } +} diff --git a/src/Http/Controllers/RepeaterController.php b/src/Http/Controllers/RepeaterController.php new file mode 100644 index 00000000..dec01867 --- /dev/null +++ b/src/Http/Controllers/RepeaterController.php @@ -0,0 +1,27 @@ +route('_resource'); + + $field = $request->route('field'); + + // Gate::allowIf($field->authorized($request, $model)); + + $model = $request->filled('model') + ? $resource->resolveRouteBinding($request, $request->input('model')) + : $resource->getModelInstance(); + + return new JsonResponse($field->buildOption($request, $model)); + } +} diff --git a/src/Http/Controllers/ResourceFieldController.php b/src/Http/Controllers/ResourceFieldController.php deleted file mode 100644 index 5901726a..00000000 --- a/src/Http/Controllers/ResourceFieldController.php +++ /dev/null @@ -1,31 +0,0 @@ -findField( - $request, $request->path() - ); - - if (is_null($field)) { - throw new NotFoundHttpException(); - } - - $model = $request->filled('model') - ? $resource->resolveRouteBinding($request, $request->input('model')) - : $resource->getModelInstance(); - - return $field->handleApiRequest($request, $model); - } -} diff --git a/src/Http/Middleware/HandleRootRequests.php b/src/Http/Middleware/HandleRootRequests.php index 51e0a2b2..0606da9d 100644 --- a/src/Http/Middleware/HandleRootRequests.php +++ b/src/Http/Middleware/HandleRootRequests.php @@ -3,7 +3,6 @@ namespace Cone\Root\Http\Middleware; use Closure; -use Cone\Root\Root; use Illuminate\Http\Request; use Symfony\Component\HttpFoundation\Response; @@ -16,8 +15,6 @@ class HandleRootRequests */ public function handle(Request $request, Closure $next): Response { - Root::instance()->boot(); - return $next($request); } } diff --git a/src/Resources/Resource.php b/src/Resources/Resource.php index 7ee1358f..416ee1d2 100644 --- a/src/Resources/Resource.php +++ b/src/Resources/Resource.php @@ -7,8 +7,10 @@ use Cone\Root\Filters\Filter; use Cone\Root\Interfaces\Form; use Cone\Root\Interfaces\Table; +use Cone\Root\Root; use Cone\Root\Traits\AsForm; use Cone\Root\Traits\Authorizable; +use Cone\Root\Traits\RegistersRoutes; use Cone\Root\Traits\ResolvesActions; use Cone\Root\Traits\ResolvesColumns; use Cone\Root\Traits\ResolvesFilters; @@ -20,15 +22,18 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Http\Request; +use Illuminate\Routing\Router; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Gate; -use Illuminate\Support\Facades\URL; use Illuminate\Support\Str; -class Resource implements Arrayable, Form, Table +abstract class Resource implements Arrayable, Form, Table { use AsForm; use Authorizable; + use RegistersRoutes { + RegistersRoutes::registerRoutes as __registerRoutes; + } use ResolvesActions; use ResolvesColumns; use ResolvesFilters; @@ -54,6 +59,16 @@ class Resource implements Arrayable, Form, Table */ protected string $icon = 'archive'; + /** + * Boot the resource. + */ + public function boot(Root $root): void + { + $root->routes(function (Router $router) use ($root): void { + $this->registerRoutes($root->app['request'], $router); + }); + } + /** * Get the model for the resource. */ @@ -78,6 +93,14 @@ public function getUriKey(): string return $this->getKey(); } + /** + * Get the route parameter name. + */ + public function getRouteParameterName(): string + { + return '_resource'; + } + /** * Get the name. */ @@ -201,20 +224,12 @@ public function isSoftDeletable(): bool return in_array(SoftDeletes::class, class_uses_recursive($this->getModel())); } - /** - * Get the resource URL. - */ - public function getUrl(): string - { - return URL::route('root.resource.index', $this->getUriKey()); - } - /** * Get the URL for the given model. */ public function modelUrl(Model $model): string { - return URL::route($model->exists ? 'root.resource.update' : 'root.resource.store', [$this->getUriKey(), $model]); + return sprintf('%s/%s', $this->getUri(), $model->exists ? $model->getRouteKey() : ''); } /** @@ -222,11 +237,8 @@ public function modelUrl(Model $model): string */ protected function resolveField(Request $request, Field $field): void { - $field->setApiUri(sprintf('/root/api/%s/fields/%s', $this->getKey(), $field->getUriKey())); $field->setAttribute('form', $this->getKey()); - $field->resolveErrorsUsing(function (Request $request): MessageBag { - return $this->errors($request); - }); + $field->resolveErrorsUsing(fn (Request $request): MessageBag => $this->errors($request)); } /** @@ -235,7 +247,6 @@ protected function resolveField(Request $request, Field $field): void protected function resolveAction(Request $request, Action $action): void { $action->setQuery($this->resolveFilteredQuery($request)); - $action->setApiUri(sprintf('/root/api/%s/actions/%s', $this->getKey(), $action->getUriKey())); } /** @@ -268,6 +279,19 @@ public function paginate(Request $request): LengthAwarePaginator }); } + /** + * Register the routes. + */ + public function registerRoutes(Request $request, Router $router): void + { + $this->__registerRoutes($request, $router); + + $router->prefix($this->getUriKey())->group(function (Router $router) use ($request): void { + $this->resolveActions($request)->registerRoutes($request, $router); + $this->resolveFields($request)->registerRoutes($request, $router); + }); + } + /** * Get the instance as an array. */ @@ -280,7 +304,7 @@ public function toArray(): array 'modelName' => $this->getModelName(), 'name' => $this->getName(), 'uriKey' => $this->getUriKey(), - 'url' => $this->getUrl(), + 'url' => $this->getUri(), ]; } @@ -314,7 +338,7 @@ public function toCreate(Request $request): array return array_merge($this->toArray(), [ 'title' => __('Create :model', ['model' => $this->getModelName()]), 'model' => $model = $this->getModelInstance(), - 'action' => $this->getUrl(), + 'action' => $this->getUri(), 'method' => 'POST', 'fields' => $this->resolveFields($request)->mapToFormComponents($request, $model), ]); diff --git a/src/Root.php b/src/Root.php index b974a0a9..437e5c8e 100644 --- a/src/Root.php +++ b/src/Root.php @@ -3,7 +3,6 @@ namespace Cone\Root; use Closure; -use Cone\Root\Resources\Resource; use Cone\Root\Resources\Resources; use Cone\Root\Widgets\Widgets; use Illuminate\Contracts\Foundation\Application; @@ -65,6 +64,8 @@ public static function instance(): static */ public function boot(): void { + $this->resources->each->boot($this); + foreach ($this->booting as $callback) { call_user_func_array($callback, [$this]); } @@ -120,12 +121,4 @@ public function getDomain(): string { return (string) Config::get('root.domain', null); } - - /** - * Get the current resource. - */ - public function getCurrentResource(): ?Resource - { - return $this->resources->current($this->app['request']); - } } diff --git a/src/RootServiceProvider.php b/src/RootServiceProvider.php index 41d3427d..dee0143c 100644 --- a/src/RootServiceProvider.php +++ b/src/RootServiceProvider.php @@ -53,6 +53,10 @@ public function register(): void $this->app->afterResolving(EncryptCookies::class, static function (EncryptCookies $middleware): void { $middleware->disableFor('__root_theme'); }); + + $this->app->booted(static function (Application $app): void { + $app->make(Root::class)->boot(); + }); } /** @@ -113,7 +117,7 @@ protected function registerRoutes(): void $root = $this->app->make(Root::class); - $this->app['router']->bind('resource', static function (string $key) use ($root): Resource { + $this->app['router']->bind('resource', function (string $key) use ($root): Resource { return $root->resources->resolve($key); }); @@ -187,7 +191,7 @@ protected function registerNavigation(): void $this->app->make(Root::class)->booting(static function (Root $root): void { $root->resources->each(static function (Resource $resource): void { Nav::location('sidebar')->new( - $resource->getUrl(), + $resource->getUri(), $resource->getName(), ['icon' => $resource->getIcon()] ); diff --git a/src/Traits/RegistersRoutes.php b/src/Traits/RegistersRoutes.php new file mode 100644 index 00000000..f06f9b50 --- /dev/null +++ b/src/Traits/RegistersRoutes.php @@ -0,0 +1,74 @@ +uri; + } + + /** + * Get the route parameter name. + */ + public function getRouteParameterName(): string + { + return Str::of(self::class)->classBasename()->lower()->value(); + } + + /** + * Register the routes using the given router. + */ + public function registerRoutes(Request $request, Router $router): void + { + $this->uri = Str::start(sprintf('%s/%s', $router->getLastGroupPrefix(), $this->getUriKey()), '/'); + + if (! App::routesAreCached()) { + $router->prefix($this->getUriKey())->group(function (Router $router): void { + $this->routes($router); + }); + } + + $router->matched(function (RouteMatched $event): void { + if (str_starts_with(Str::start($event->request->path(), '/'), $this->getUri())) { + $this->routeMatched($event); + } + }); + } + + /** + * Handle the route matched event. + */ + public function routeMatched(RouteMatched $event): void + { + $event->route->setParameter($this->getRouteParameterName(), $this); + } + + /** + * The routes that should be registered. + */ + public function routes(Router $router): void + { + // + } +} diff --git a/src/Traits/ResolvesFields.php b/src/Traits/ResolvesFields.php index 7a42d559..d1fb8fd8 100644 --- a/src/Traits/ResolvesFields.php +++ b/src/Traits/ResolvesFields.php @@ -67,23 +67,4 @@ protected function resolveField(Request $request, Field $field): void { // } - - /** - * Find the field with the given API URI. - */ - public function findField(Request $request, string $apiUri): ?Field - { - foreach ($this->resolveFields($request)->all() as $field) { - if (trim($field->getApiUri(), '/') === trim($apiUri, '/')) { - return $field; - } - - if (in_array(ResolvesFields::class, class_uses_recursive($field)) - && ! is_null($subfield = $field->findField($request, $apiUri))) { - return $subfield; - } - } - - return null; - } }