let t=null;class e{static createItem(t){return{prev:null,next:null,data:t}}constructor(){this.head=null,this.tail=null,this.cursor=null}createItem(t){return e.createItem(t)}allocateCursor(e,r){let s;return null!==t?(s=t,t=t.cursor,s.prev=e,s.next=r,s.cursor=this.cursor):s={prev:e,next:r,cursor:this.cursor},this.cursor=s,s}releaseCursor(){const{cursor:e}=this;this.cursor=e.cursor,e.prev=null,e.next=null,e.cursor=t,t=e}updateCursors(t,e,r,s){let{cursor:l}=this;for(;null!==l;)l.prev===t&&(l.prev=e),l.next===r&&(l.next=s),l=l.cursor}*[Symbol.iterator](){for(let t=this.head;null!==t;t=t.next)yield t.data}get size(){let t=0;for(let e=this.head;null!==e;e=e.next)t++;return t}get isEmpty(){return null===this.head}get first(){return this.head&&this.head.data}get last(){return this.tail&&this.tail.data}fromArray(t){let r=null;this.head=null;for(let s of t){const t=e.createItem(s);null!==r?r.next=t:this.head=t,t.prev=r,r=t}return this.tail=r,this}toArray(){return[...this]}toJSON(){return[...this]}forEach(t,e=this){const r=this.allocateCursor(null,this.head);for(;null!==r.next;){const s=r.next;r.next=s.next,t.call(e,s.data,s,this)}this.releaseCursor()}forEachRight(t,e=this){const r=this.allocateCursor(this.tail,null);for(;null!==r.prev;){const s=r.prev;r.prev=s.prev,t.call(e,s.data,s,this)}this.releaseCursor()}reduce(t,e,r=this){let s,l=this.allocateCursor(null,this.head),i=e;for(;null!==l.next;)s=l.next,l.next=s.next,i=t.call(r,i,s.data,s,this);return this.releaseCursor(),i}reduceRight(t,e,r=this){let s,l=this.allocateCursor(this.tail,null),i=e;for(;null!==l.prev;)s=l.prev,l.prev=s.prev,i=t.call(r,i,s.data,s,this);return this.releaseCursor(),i}some(t,e=this){for(let r=this.head;null!==r;r=r.next)if(t.call(e,r.data,r,this))return!0;return!1}map(t,r=this){const s=new e;for(let e=this.head;null!==e;e=e.next)s.appendData(t.call(r,e.data,e,this));return s}filter(t,r=this){const s=new e;for(let e=this.head;null!==e;e=e.next)t.call(r,e.data,e,this)&&s.appendData(e.data);return s}nextUntil(t,e,r=this){if(null===t)return;const s=this.allocateCursor(null,t);for(;null!==s.next;){const t=s.next;if(s.next=t.next,e.call(r,t.data,t,this))break}this.releaseCursor()}prevUntil(t,e,r=this){if(null===t)return;const s=this.allocateCursor(t,null);for(;null!==s.prev;){const t=s.prev;if(s.prev=t.prev,e.call(r,t.data,t,this))break}this.releaseCursor()}clear(){this.head=null,this.tail=null}copy(){const t=new e;for(let e of this)t.appendData(e);return t}prepend(t){return this.updateCursors(null,t,this.head,t),null!==this.head?(this.head.prev=t,t.next=this.head):this.tail=t,this.head=t,this}prependData(t){return this.prepend(e.createItem(t))}append(t){return this.insert(t)}appendData(t){return this.insert(e.createItem(t))}insert(t,e=null){if(null!==e)if(this.updateCursors(e.prev,t,e,t),null===e.prev){if(this.head!==e)throw new Error("before doesn't belong to list");this.head=t,e.prev=t,t.next=e,this.updateCursors(null,t)}else e.prev.next=t,t.prev=e.prev,e.prev=t,t.next=e;else this.updateCursors(this.tail,t,null,t),null!==this.tail?(this.tail.next=t,t.prev=this.tail):this.head=t,this.tail=t;return this}insertData(t,r){return this.insert(e.createItem(t),r)}remove(t){if(this.updateCursors(t,t.prev,t,t.next),null!==t.prev)t.prev.next=t.next;else{if(this.head!==t)throw new Error("item doesn't belong to list");this.head=t.next}if(null!==t.next)t.next.prev=t.prev;else{if(this.tail!==t)throw new Error("item doesn't belong to list");this.tail=t.prev}return t.prev=null,t.next=null,t}push(t){this.insert(e.createItem(t))}pop(){return null!==this.tail?this.remove(this.tail):null}unshift(t){this.prepend(e.createItem(t))}shift(){return null!==this.head?this.remove(this.head):null}prependList(t){return this.insertList(t,this.head)}appendList(t){return this.insertList(t)}insertList(t,e){return null===t.head||(null!=e?(this.updateCursors(e.prev,t.tail,e,t.head),null!==e.prev?(e.prev.next=t.head,t.head.prev=e.prev):this.head=t.head,e.prev=t.tail,t.tail.next=e):(this.updateCursors(this.tail,t.tail,null,t.head),null!==this.tail?(this.tail.next=t.head,t.head.prev=this.tail):this.head=t.head,this.tail=t.tail),t.head=null,t.tail=null),this}replace(t,e){"head"in e?this.insertList(e,t):this.insert(e,t),this.remove(t)}}export{e as List};