/**
 * Minified by jsDelivr using Terser v5.48.0.
 * Original file: /npm/etro@0.14.0/dist/etro-cjs.js
 *
 * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
 */
"use strict";function __awaiter(t,e,r,i){return new(r||(r=Promise))(function(s,n){function o(t){try{c(i.next(t))}catch(t){n(t)}}function a(t){try{c(i.throw(t))}catch(t){n(t)}}function c(t){var e;t.done?s(t.value):(e=t.value,e instanceof r?e:new r(function(t){t(e)})).then(o,a)}c((i=i.apply(t,e||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;class DeprecatedEvent{constructor(t,e=void 0){this.replacement=t,this.message=e}toString(){let t="";return this.replacement&&(t+=`Use ${this.replacement} instead.`),this.message&&(t+=` ${this.message}`),t}}const deprecatedEvents={};class TypeId{constructor(t){this._parts=t.split(".")}contains(t){if(t._parts.length>this._parts.length)return!1;for(let e=0;e<t._parts.length;e++)if(t._parts[e]!==this._parts[e])return!1;return!0}toString(){return this._parts.join(".")}}function deprecate(t,e,r=void 0){deprecatedEvents[t]=new DeprecatedEvent(e,r)}function subscribeOnce(t,e,r){const i=e=>{unsubscribe(t,i),r(e)};subscribe(t,e,i)}function subscribeMany(t,e,r){listeners.has(t)||listeners.set(t,[]),listeners.get(t).push({type:new TypeId(e),listener:r})}function subscribe(t,e,r,i={}){Object.keys(deprecatedEvents).includes(e)&&console.warn(`Event ${e} is deprecated. ${deprecatedEvents[e]}`),i.once?subscribeOnce(t,e,r):subscribeMany(t,e,r)}function unsubscribe(t,e){if(!listeners.has(t)||!listeners.get(t).map(t=>t.listener).includes(e))throw new Error("No matching event listener to remove");const r=listeners.get(t).filter(t=>t.listener!==e);listeners.set(t,r)}function _publish(t,e,r){r.target=t,r.type=e;const i=new TypeId(e);if(!listeners.has(t))return null;const s=[];for(let e=0;e<listeners.get(t).length;e++){const r=listeners.get(t)[e];i.contains(r.type)&&s.push(r.listener)}for(let t=0;t<s.length;t++){(0,s[t])(r)}return r}function publish(t,e,r){if(Object.keys(deprecatedEvents).includes(e)&&deprecatedEvents[e].replacement)throw new Error(`Event ${e} is deprecated. ${deprecatedEvents[e]}`);for(const i in deprecatedEvents){e===deprecatedEvents[i].replacement&&_publish(t,i,Object.assign({},r))}return _publish(t,e,r)}const listeners=new WeakMap;var event=Object.freeze({__proto__:null,deprecate:deprecate,publish:publish,subscribe:subscribe,unsubscribe:unsubscribe});function getPropertyDescriptor(t,e){do{const r=Object.getOwnPropertyDescriptor(t,e);if(r)return r;t=Object.getPrototypeOf(t)}while(t)}function applyOptions(t,e){const r=e.getDefaultOptions();for(const e in t)if(!r.hasOwnProperty(e))throw new Error("Invalid option: '"+e+"'");t=Object.assign(Object.assign({},r),t);for(const r in t){const i=getPropertyDescriptor(e,r);i&&!i.set||(e[r]=t[r])}}const valCache=new WeakMap;function cacheValue(t,e,r){valCache.has(t.movie)||valCache.set(t.movie,new WeakMap);const i=valCache.get(t.movie);i.has(t)||i.set(t,{});return i.get(t)[e]=r,r}function hasCachedValue(t,e){return valCache.has(t.movie)&&valCache.get(t.movie).has(t)&&e in valCache.get(t.movie).get(t)}function getCachedValue(t,e){return valCache.get(t.movie).get(t)[e]}function clearCachedValues(t){valCache.delete(t)}class KeyFrame{constructor(...t){this.value=t,this.interpolationKeys=[]}withKeys(t){return this.interpolationKeys=t,this}toJSON(){return{type:"KeyFrame",value:this.value.map(t=>{const e=[t[0],serializeProperty(t[1])];if(3===t.length){const r=t[2];r===linearInterp?e.push("linear"):r===cosineInterp&&e.push("cosine")}return e}),interpolationKeys:this.interpolationKeys}}evaluate(t){if(0===this.value.length)throw new Error("Empty keyframe");if(void 0===t)throw new Error("|time| is undefined or null");if(t<this.value[0][0])throw new Error("No keyframe point before |time|");for(let e=0;e<this.value.length;e++){const r=this.value[e][0],i=this.value[e][1],s=3===this.value[e].length?this.value[e][2]:linearInterp;if(!(e+1<this.value.length))return i;{const n=this.value[e+1][0],o=this.value[e+1][1];if(r<=t&&t<n){if("number"!=typeof i&&"object"!=typeof o)return i;if(typeof i!=typeof o)throw new Error("Type mismatch in keyframe values");return s(i,o,(t-r)/(n-r),this.interpolationKeys)}}}}}function val(t,e,r){if(hasCachedValue(t,e))return getCachedValue(t,e);const i=e.split(".");let s=t[i.shift()];for(;i.length>0;)s=s[i.shift()];const n=t.propertyFilters[e];let o;return o=s instanceof KeyFrame?s.evaluate(r):"function"==typeof s?s(t,r):s,cacheValue(t,e,n?n.call(t,o):o)}function linearInterp(t,e,r,i){if(typeof t!=typeof e)throw new Error("Type mismatch");if("number"!=typeof t&&"object"!=typeof t)return t;if("object"==typeof t){if(Object.getPrototypeOf(t)!==Object.getPrototypeOf(e))throw new Error("Prototype mismatch");const s=Object.create(Object.getPrototypeOf(t)),n=Object.keys(t)||i;for(let i=0;i<n.length;i++){const o=n[i];t.hasOwnProperty(o)&&e.hasOwnProperty(o)&&(s[o]=linearInterp(t[o],e[o],r))}return s}return(1-r)*t+r*e}function cosineInterp(t,e,r,i){if(typeof t!=typeof e)throw new Error("Type mismatch");if("number"!=typeof t&&"object"!=typeof t)return t;if("object"==typeof t&&"object"==typeof e){if(Object.getPrototypeOf(t)!==Object.getPrototypeOf(e))throw new Error("Prototype mismatch");const s=Object.create(Object.getPrototypeOf(t)),n=Object.keys(t)||i;for(let i=0;i<n.length;i++){const o=n[i];t.hasOwnProperty(o)&&e.hasOwnProperty(o)&&(s[o]=cosineInterp(t[o],e[o],r))}return s}const s=Math.cos(Math.PI/2*r);return s*t+(1-s)*e}class Color{constructor(t,e,r,i=1){this.r=t,this.g=e,this.b=r,this.a=i}toString(){return`rgba(${this.r}, ${this.g}, ${this.b}, ${this.a})`}toJSON(){return{type:"Color",r:this.r,g:this.g,b:this.b,a:this.a}}}const parseColorCanvas=document.createElement("canvas");parseColorCanvas.width=parseColorCanvas.height=1;const parseColorCtx=parseColorCanvas.getContext("2d");function parseColor(t){parseColorCtx.clearRect(0,0,1,1),parseColorCtx.fillStyle=t,parseColorCtx.fillRect(0,0,1,1);const e=parseColorCtx.getImageData(0,0,1,1).data;return new Color(e[0],e[1],e[2],e[3]/255)}class Font{constructor(t,e,r,i="normal",s="normal",n="normal",o="normal",a="normal"){this.size=t,this.sizeUnit=e,this.family=r,this.style=i,this.variant=s,this.weight=n,this.stretch=o,this.lineHeight=a}toString(){let t="";return"normal"!==this.style&&(t+=this.style+" "),"normal"!==this.variant&&(t+=this.variant+" "),"normal"!==this.weight&&(t+=this.weight+" "),"normal"!==this.stretch&&(t+=this.stretch+" "),t+=`${this.size}${this.sizeUnit} `,"normal"!==this.lineHeight&&(t+=this.lineHeight+" "),t+=this.family,t}toJSON(){return{type:"Font",size:this.size,sizeUnit:this.sizeUnit,family:this.family,style:this.style,variant:this.variant,weight:this.weight,stretch:this.stretch,lineHeight:this.lineHeight}}}const parseFontEl=document.createElement("div");function parseFont(t){parseFontEl.setAttribute("style",`font: ${t}`);const{fontSize:e,fontFamily:r,fontStyle:i,fontVariant:s,fontWeight:n,lineHeight:o}=parseFontEl.style;parseFontEl.removeAttribute("style");const a=parseFloat(e),c=e.substring(a.toString().length);return new Font(a,c,r,i,s,n,o)}function mapPixels(t,e,r,i,s,n,o,a=!0){i=i||0,s=s||0,n=n||e.width,o=o||e.height;const c=r.getImageData(i,s,n,o);for(let e=0,r=c.data.length;e<r;e+=4)t(c.data,e);a&&r.putImageData(c,i,s)}function serializeProperty(t){if(t&&"object"==typeof t){if("function"==typeof t.toJSON)return t.toJSON();if(Array.isArray(t))return t.map(serializeProperty);if(t instanceof HTMLImageElement||t instanceof HTMLVideoElement||t instanceof HTMLAudioElement)return t.getAttribute("src")||t.src;if(t.constructor===Object){const e={};for(const r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=serializeProperty(t[r]));return e}}return t}function deserializeProperty(t){if(t&&"object"==typeof t){if(Array.isArray(t))return t.map(deserializeProperty);if("Color"===t.type)return new Color(t.r,t.g,t.b,t.a);if("Font"===t.type)return new Font(t.size,t.sizeUnit,t.family,t.style,t.variant,t.weight,t.stretch,t.lineHeight);if("KeyFrame"===t.type){const e=new KeyFrame;return e.value=t.value.map(t=>{const e=[t[0],deserializeProperty(t[1])];return 3===t.length&&("linear"===t[2]?e.push(linearInterp):"cosine"===t[2]&&e.push(cosineInterp)),e}),e.interpolationKeys=t.interpolationKeys,e}if(t.constructor===Object){const e={};for(const r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=deserializeProperty(t[r]));return e}}return t}function AudioSourceMixin(t){return class extends t{constructor(t){var e;if(!t.source)throw new Error('Property "source" is required in options');const r=t.onload;delete t.onload,super(Object.assign(Object.assign({},t),{duration:null!==(e=t.duration)&&void 0!==e?e:0})),this._initialized=!1,this._sourceStartTime=t.sourceStartTime||0,applyOptions(t,this);const i=()=>{if(t.duration<0)throw new Error("Invalid options.duration. It must be a non-negative value.");if(this.sourceStartTime>this.source.duration)throw new Error("options.sourceStartTime cannot exceed options.source.duration");this._unstretchedDuration=t.duration||this.source.duration-this.sourceStartTime,this.duration=this._unstretchedDuration/this.playbackRate,r&&r.bind(this)(this.source,t)};this.source.readyState>=2?i():this.source.addEventListener("loadedmetadata",i),this.source.addEventListener("durationchange",()=>{this.duration=t.duration||this.source.duration-this.sourceStartTime})}whenReady(){const t=Object.create(null,{whenReady:{get:()=>super.whenReady}});return __awaiter(this,void 0,void 0,function*(){yield t.whenReady.call(this),this.source.readyState<4&&(yield new Promise(t=>{this.source.addEventListener("canplaythrough",t)}))})}attach(t){super.attach(t),subscribe(t,"audiodestinationupdate",t=>{this.audioNode.disconnect(this._lastAudioDestination),this.audioNode.connect(t.destination),this._lastAudioDestination=t.destination}),this._audioNode=this.audioNode||t.actx.createMediaElementSource(this.source),this.audioNode.connect(t.actx.destination),this._lastAudioDestination=t.actx.destination}detach(){const t=this.movie.actx.destination;super.detach(),this.audioNode.disconnect(t)}start(){this.source.currentTime=this.currentTime+this.sourceStartTime,this.source.play()}seek(t){super.seek(t),isNaN(this.currentTime)?this.source.currentTime=this.sourceStartTime:this.source.currentTime=this.currentTime+this.sourceStartTime}render(){super.render(),this.source.muted=val(this,"muted",this.currentTime),this.source.volume=val(this,"volume",this.currentTime),this.source.playbackRate=val(this,"playbackRate",this.currentTime)}stop(){super.stop(),this.source.pause()}get audioNode(){return this._audioNode}get playbackRate(){return this._playbackRate}set playbackRate(t){this._playbackRate=t,void 0!==this._unstretchedDuration&&(this.duration=this._unstretchedDuration/t)}get startTime(){return this.__startTime}set startTime(t){if(this.__startTime=t,this._initialized){const t=this.movie.currentTime-this.startTime;this.source.currentTime=this.sourceStartTime+t}}set sourceStartTime(t){if(this._sourceStartTime=t,this._initialized){const t=this.movie.currentTime-this.startTime;this.source.currentTime=t+this.sourceStartTime}}get sourceStartTime(){return this._sourceStartTime}get ready(){return Object.getOwnPropertyDescriptor(t.prototype,"ready").get.call(this)&&4===this.source.readyState}getDefaultOptions(){return Object.assign(Object.assign({},t.prototype.getDefaultOptions()),{source:void 0,sourceStartTime:0,duration:void 0,muted:!1,volume:1,playbackRate:1})}}}let Base$1=class{constructor(t){if(null===t.duration||void 0===t.duration)throw new Error('Property "duration" is required in BaseOptions');if(null===t.startTime||void 0===t.startTime)throw new Error('Property "startTime" is required in BaseOptions');this._startTime=t.startTime,this._duration=t.duration,applyOptions(t,this),this.active=!1,this.enabled=!0,this._occurrenceCount=0,this._movie=null}whenReady(){return __awaiter(this,void 0,void 0,function*(){})}tryAttach(t){0===this._occurrenceCount&&this.attach(t),this._occurrenceCount++}attach(t){this._movie=t}tryDetach(){if(null===this.movie)throw new Error("No movie to detach from");this._occurrenceCount--,0===this._occurrenceCount&&this.detach()}detach(){this._movie=null}start(){}seek(t){this._currentTime=t}progress(t){this._currentTime=t}render(){}stop(){this._currentTime=void 0}get parent(){return this._movie}get startTime(){return this._startTime}set startTime(t){this._startTime=t}get currentTime(){return this._currentTime}get duration(){return this._duration}set duration(t){this._duration=t}get ready(){return!0}get movie(){return this._movie}getDefaultOptions(){return{startTime:void 0,duration:void 0}}toJSON(){const t={type:`layer.${this.constructor.name}`},e=["type","publicExcludes","propertyFilters","movie","ready","parent","currentTime","effects",...this.publicExcludes];for(const r in this)r.startsWith("_")||-1!==e.indexOf(r)||"function"==typeof this[r]||(t[r]=serializeProperty(this[r]));return t.startTime=this.startTime,t.duration=this.duration,this.effects&&this.effects.length>0&&(t.effects=this.effects.map(t=>t.toJSON())),t}};Base$1.prototype.type="layer",Base$1.prototype.publicExcludes=["active"],Base$1.prototype.propertyFilters={};class Audio extends(AudioSourceMixin(Base$1)){constructor(t){if("string"==typeof t.source){const e=document.createElement("audio");e.src=t.source,t.source=e}super(t)}getDefaultOptions(){return Object.assign(Object.assign({},Object.getPrototypeOf(this).getDefaultOptions()),{sourceStartTime:0,duration:void 0})}}class CustomArrayListener{}class CustomArray extends Array{constructor(t,e){super();for(const r of t)e.onAdd(r);return new Proxy(t,{deleteProperty(t,r){const i=t[r];return delete t[r],e.onRemove(i),!0},set(t,r,i){const s=t[r];return t[r]=i,isNaN(Number(r))||(void 0!==s&&e.onRemove(s),e.onAdd(i)),!0}})}}class VisualEffectsListener extends CustomArrayListener{constructor(t){super(),this._layer=t}onAdd(t){t.tryAttach(this._layer)}onRemove(t){t.tryDetach()}}class VisualEffects extends CustomArray{constructor(t,e){super(t,new VisualEffectsListener(e))}}let Visual$1=class extends Base$1{constructor(t){super(t),applyOptions(t,this),this.canvas=document.createElement("canvas"),this.cctx=this.canvas.getContext("2d"),this.effects=new VisualEffects([],this)}whenReady(){const t=Object.create(null,{whenReady:{get:()=>super.whenReady}});return __awaiter(this,void 0,void 0,function*(){yield t.whenReady.call(this),yield Promise.all(this.effects.map(t=>t.whenReady()))})}render(){const t=val(this,"width",this.currentTime),e=val(this,"height",this.currentTime);0!==t&&0!==e&&(this.beginRender(),this.doRender(),this.endRender())}beginRender(){this.canvas.width=val(this,"width",this.currentTime),this.canvas.height=val(this,"height",this.currentTime),this.cctx.globalAlpha=val(this,"opacity",this.currentTime)}doRender(){this.background&&(this.cctx.fillStyle=val(this,"background",this.currentTime),this.cctx.fillRect(0,0,this.canvas.width,this.canvas.height));const t=val(this,"border",this.currentTime);t&&t.color&&(this.cctx.strokeStyle=t.color,this.cctx.lineWidth=t.thickness||1)}endRender(){(val(this,"width",this.currentTime)||val(this.movie,"width",this.movie.currentTime))*(val(this,"height",this.currentTime)||val(this.movie,"height",this.movie.currentTime))>0&&this._applyEffects()}_applyEffects(){for(let t=0;t<this.effects.length;t++){const e=this.effects[t];e&&e.enabled&&e.apply(this,this.movie.currentTime-this.startTime)}}addEffect(t){return this.effects.push(t),this}get ready(){return Object.getOwnPropertyDescriptor(Base$1.prototype,"ready").get.call(this)&&this.effects.every(t=>t.ready)}getDefaultOptions(){return Object.assign(Object.assign({},Base$1.prototype.getDefaultOptions()),{x:0,y:0,width:null,height:null,background:null,border:null,opacity:1})}};function VisualSourceMixin(t){class e extends t{constructor(t){if(!t.source)throw new Error('Property "source" is required in options');super(t),applyOptions(t,this)}whenReady(){const t=Object.create(null,{whenReady:{get:()=>super.whenReady}});return __awaiter(this,void 0,void 0,function*(){yield t.whenReady.call(this),yield new Promise(t=>{this.source instanceof HTMLImageElement?this.source.complete?t():this.source.addEventListener("load",()=>{t()}):4===this.source.readyState?t():this.source.addEventListener("canplaythrough",()=>{t()})})})}doRender(){super.doRender(),this.cctx.drawImage(this.source,val(this,"sourceX",this.currentTime),val(this,"sourceY",this.currentTime),val(this,"sourceWidth",this.currentTime),val(this,"sourceHeight",this.currentTime),val(this,"destX",this.currentTime),val(this,"destY",this.currentTime),val(this,"destWidth",this.currentTime),val(this,"destHeight",this.currentTime))}get ready(){const e=Object.getOwnPropertyDescriptor(t.prototype,"ready").get.call(this),r=this.source instanceof HTMLImageElement?this.source.complete:4===this.source.readyState;return e&&r}getDefaultOptions(){return Object.assign(Object.assign({},t.prototype.getDefaultOptions()),{source:void 0,sourceX:0,sourceY:0,sourceWidth:void 0,sourceHeight:void 0,destX:0,destY:0,destWidth:void 0,destHeight:void 0})}}return e.prototype.propertyFilters=Object.assign(Object.assign({},Visual$1.prototype.propertyFilters),{sourceWidth:function(t){const e=this.source instanceof HTMLImageElement?this.source.width:this.source.videoWidth;return null!=t?t:e},sourceHeight:function(t){const e=this.source instanceof HTMLImageElement?this.source.height:this.source.videoHeight;return null!=t?t:e},destWidth:function(t){return null!=t?t:val(this,"sourceWidth",this.currentTime)},destHeight:function(t){return null!=t?t:val(this,"sourceHeight",this.currentTime)},width:function(t){return null!=t?t:val(this,"destWidth",this.currentTime)},height:function(t){return null!=t?t:val(this,"destHeight",this.currentTime)}}),e}Visual$1.prototype.publicExcludes=Base$1.prototype.publicExcludes.concat(["canvas","cctx","effects"]),Visual$1.prototype.propertyFilters=Object.assign(Object.assign({},Base$1.prototype.propertyFilters),{width:function(t){return null!=t?t:this._movie.width},height:function(t){return null!=t?t:this._movie.height}});class Image extends(VisualSourceMixin(Visual$1)){constructor(t){if("string"==typeof t.source){const e=document.createElement("img");e.src=t.source,t.source=e}super(t)}}var TextStrokePosition;!function(t){t[t.Inside=0]="Inside",t[t.Center=1]="Center",t[t.Outside=2]="Outside"}(TextStrokePosition||(TextStrokePosition={}));class Text extends Visual$1{constructor(t){if(!t.text)throw new Error('Property "text" is required in TextOptions');super(Object.assign({background:null},t)),applyOptions(t,this)}doRender(){var t,e;super.doRender();const r=val(this,"text",this.currentTime),i=val(this,"font",this.currentTime),s=this.maxWidth?val(this,"maxWidth",this.currentTime):void 0;this.cctx.font=i,this.cctx.fillStyle=val(this,"color",this.currentTime),this.cctx.textAlign=val(this,"textAlign",this.currentTime),this.cctx.textBaseline=val(this,"textBaseline",this.currentTime),this.cctx.direction=val(this,"textDirection",this.currentTime),this.cctx.fillText(r,val(this,"textX",this.currentTime),val(this,"textY",this.currentTime),s);const n=val(this,"textStroke",this.currentTime);if(n){this.cctx.strokeStyle=n.color,this.cctx.lineWidth=null!==(t=n.thickness)&&void 0!==t?t:1;const i=null!==(e=n.position)&&void 0!==e?e:"outer",o=this.cctx.globalCompositeOperation;switch(i){case TextStrokePosition.Inside:this.cctx.globalCompositeOperation="source-atop",this.cctx.lineWidth*=2;break;case TextStrokePosition.Center:break;case TextStrokePosition.Outside:this.cctx.globalCompositeOperation="destination-over",this.cctx.lineWidth*=2}this.cctx.strokeText(r,val(this,"textX",this.currentTime),val(this,"textY",this.currentTime),s),this.cctx.globalCompositeOperation=o}this._prevText=r,this._prevFont=i,this._prevMaxWidth=s}getDefaultOptions(){return Object.assign(Object.assign({},Visual$1.prototype.getDefaultOptions()),{background:null,text:void 0,font:"10px sans-serif",color:parseColor("#fff"),textX:0,textY:0,maxWidth:null,textAlign:"start",textBaseline:"top",textDirection:"ltr",textStroke:null})}}class Video extends(AudioSourceMixin(VisualSourceMixin(Visual$1))){constructor(t){var e;if("string"==typeof t.source){const e=document.createElement("video");e.src=t.source,t.source=e}super(Object.assign(Object.assign({},t),{duration:null!==(e=t.duration)&&void 0!==e?e:0}))}}var Layers=Object.freeze({__proto__:null,Audio:Audio,AudioSourceMixin:AudioSourceMixin,Base:Base$1,Image:Image,Text:Text,get TextStrokePosition(){return TextStrokePosition},Video:Video,Visual:Visual$1,VisualSourceMixin:VisualSourceMixin});class Base{constructor(){this.enabled=!0,this._occurrenceCount=0,this._target=null}whenReady(){return __awaiter(this,void 0,void 0,function*(){})}tryAttach(t){0===this._occurrenceCount&&this.attach(t),this._occurrenceCount++}attach(t){this._target=t}tryDetach(){if(null===this._target)throw new Error("No movie to detach from");this._occurrenceCount--,0===this._occurrenceCount&&this.detach()}detach(){this._target=null}apply(t,e){}get currentTime(){return this._target?this._target.currentTime:void 0}get ready(){return!0}get parent(){return this._target}get movie(){return this._target?this._target.movie:void 0}getDefaultOptions(){return{}}toJSON(){const t={type:`effect.${this.constructor.name}`},e=["type","publicExcludes","propertyFilters","movie","ready","parent","currentTime",...this.publicExcludes];for(const r in this)r.startsWith("_")||-1!==e.indexOf(r)||"function"==typeof this[r]||(t[r]=serializeProperty(this[r]));return this.effects&&this.effects.length>0&&(t.effects=this.effects.map(t=>t.toJSON())),t}}Base.prototype.type="effect",Base.prototype.publicExcludes=[],Base.prototype.propertyFilters={};class Visual extends Base{apply(t,e){super.apply(t,e)}}class Shader extends Visual{constructor(t={}){super();const e=t.fragmentSource||Shader._IDENTITY_FRAGMENT_SOURCE,r=t.uniforms||{},i=t.textures||{},s=t.sourceTextureOptions||{},n=this._initGl();this._program=Shader._initShaderProgram(n,Shader._VERTEX_SOURCE,e),this._buffers=Shader._initRectBuffers(n),this._initTextures(r,i,s),this._initAttribs(),this._initUniforms(r)}_initGl(){this._canvas=document.createElement("canvas");const t=this._canvas.getContext("webgl");if(null===t)throw new Error("Unable to initialize WebGL. Your browser or machine may not support it.");return this._gl=t,t}_initTextures(t,e,r){const i=this._gl,s=i.getParameter(i.MAX_TEXTURE_IMAGE_UNITS);e.length>s&&console.warn("Too many textures!"),this._userTextures={};for(const r in e){const i=e[r],s=Object.assign(Object.assign({},Shader._DEFAULT_TEXTURE_OPTIONS),i);if(s.createUniform){if(t[r])throw new Error(`Texture - uniform naming conflict: ${r}!`);t[r]="1i"}this._userTextures[r]=s}this._sourceTextureOptions=Object.assign(Object.assign({},Shader._DEFAULT_TEXTURE_OPTIONS),r)}_initAttribs(){const t=this._gl;this._attribLocations={vertexPosition:t.getAttribLocation(this._program,"a_VertexPosition"),textureCoord:t.getAttribLocation(this._program,"a_TextureCoord")}}_initUniforms(t){const e=this._gl;this._uniformLocations={source:e.getUniformLocation(this._program,"u_Source"),size:e.getUniformLocation(this._program,"u_Size")},this._userUniforms={};for(const e in t){const r=t[e];this._userUniforms[e]="string"==typeof r?{type:r}:r}for(const r in t){const t="u_"+r.charAt(0).toUpperCase()+(r.length>1?r.slice(1):"");this._uniformLocations[r]=e.getUniformLocation(this._program,t)}}apply(t,e){this._checkDimensions(t),this._refreshGl(),this._enablePositionAttrib(),this._enableTexCoordAttrib(),this._prepareTextures(t,e),this._gl.useProgram(this._program),this._prepareUniforms(t,e),this._draw(t)}_checkDimensions(t){const e=this._gl;this._canvas.width===t.canvas.width&&this._canvas.height===t.canvas.height||(this._canvas.width=t.canvas.width,this._canvas.height=t.canvas.height,e.viewport(0,0,t.canvas.width,t.canvas.height))}_refreshGl(){const t=this._gl;t.clearColor(0,0,0,1),t.blendFuncSeparate(t.SRC_ALPHA,t.SRC_ALPHA,t.ONE,t.ZERO),t.enable(t.BLEND),t.disable(t.DEPTH_TEST),t.clear(t.COLOR_BUFFER_BIT|t.DEPTH_BUFFER_BIT)}_enablePositionAttrib(){const t=this._gl,e=t.FLOAT;t.bindBuffer(t.ARRAY_BUFFER,this._buffers.position),t.vertexAttribPointer(this._attribLocations.vertexPosition,2,e,!1,0,0),t.enableVertexAttribArray(this._attribLocations.vertexPosition)}_enableTexCoordAttrib(){const t=this._gl,e=t.FLOAT;t.bindBuffer(t.ARRAY_BUFFER,this._buffers.textureCoord),t.vertexAttribPointer(this._attribLocations.textureCoord,2,e,!1,0,0),t.enableVertexAttribArray(this._attribLocations.textureCoord)}_prepareTextures(t,e){const r=this._gl;r.activeTexture(r.TEXTURE0),this._inputTexture=Shader._loadTexture(r,t.canvas,this._sourceTextureOptions),r.bindTexture(r.TEXTURE_2D,this._inputTexture);let i=0;for(const t in this._userTextures){const s=this._userTextures[t];r.activeTexture(r.TEXTURE0+(Shader.INTERNAL_TEXTURE_UNITS+i));const n=Shader._loadTexture(r,val(this,t,e),s);r.bindTexture(r[s.target],n),i++}}_prepareUniforms(t,e){const r=this._gl;this._uniformLocations.source&&r.uniform1i(this._uniformLocations.source,0),this._uniformLocations.size&&r.uniform2iv(this._uniformLocations.size,[t.canvas.width,t.canvas.height]);for(const t in this._userUniforms){const i=this._userUniforms[t],s=val(this,t,e),n=this._prepareValue(s,i.type,e,i),o=this._uniformLocations[t];r["uniform"+i.type](o,n)}r.uniform1i(this._uniformLocations.test,0)}_draw(t){const e=this._gl;e.drawArrays(e.TRIANGLE_STRIP,0,4),t.cctx.clearRect(0,0,t.canvas.width,t.canvas.height),t.cctx.drawImage(this._canvas,0,0)}_prepareValue(t,e,r,i={}){const s=i.defaultFloatComponent||0;if("1i"===e){let e=0;for(const i in this._userTextures){t===val(this,i,r)&&(t=Shader.INTERNAL_TEXTURE_UNITS+e),e++}}if("3fv"===e){if(Array.isArray(t)&&(3===t.length||4===t.length))return t;if("object"==typeof t)return[void 0!==t.r?t.r:s,void 0!==t.g?t.g:s,void 0!==t.b?t.b:s];throw new Error(`Invalid type: ${e} or value: ${t}`)}if("4fv"===e){if(Array.isArray(t)&&4===t.length)return t;if("object"==typeof t)return[void 0!==t.r?t.r:s,void 0!==t.g?t.g:s,void 0!==t.b?t.b:s,void 0!==t.a?t.a:s];throw new Error(`Invalid type: ${e} or value: ${t}`)}return t}static _initRectBuffers(t){return{position:Shader._initBuffer(t,[-1,1,1,1,-1,-1,1,-1]),textureCoord:Shader._initBuffer(t,[0,0,1,0,0,1,1,1])}}static _initBuffer(t,e){const r=t.createBuffer();return t.bindBuffer(t.ARRAY_BUFFER,r),t.bufferData(t.ARRAY_BUFFER,new Float32Array(e),t.STATIC_DRAW),r}static _loadTexture(t,e,r={}){const i=t[(r=Object.assign(Object.assign({},Shader._DEFAULT_TEXTURE_OPTIONS),r)).target],s=r.level,n=t[r.internalFormat],o=t[r.srcFormat],a=t[r.srcType],c=t[r.wrapS],h=t[r.wrapT],u=t[r.minFilter],l=t[r.magFilter],d=t.createTexture();t.bindTexture(i,d),t.texImage2D(i,s,n,o,a,e);const p=i instanceof HTMLVideoElement?i.videoWidth:i.width,f=i instanceof HTMLVideoElement?i.videoHeight:i.height;return t.texParameteri(i,t.TEXTURE_MIN_FILTER,u),t.texParameteri(i,t.TEXTURE_MAG_FILTER,l),p&&isPowerOf2(p)&&f&&isPowerOf2(f)?(t.texParameteri(i,t.TEXTURE_WRAP_S,c),t.texParameteri(i,t.TEXTURE_WRAP_T,h),t.generateMipmap(i)):(c===t.CLAMP_TO_EDGE&&h===t.CLAMP_TO_EDGE||console.warn("Wrap mode is not CLAMP_TO_EDGE for a non-power-of-two texture. Defaulting to CLAMP_TO_EDGE"),t.texParameteri(i,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(i,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE)),d}static _initShaderProgram(t,e,r){const i=Shader._loadShader(t,t.VERTEX_SHADER,e),s=Shader._loadShader(t,t.FRAGMENT_SHADER,r),n=t.createProgram();return t.attachShader(n,i),t.attachShader(n,s),t.linkProgram(n),t.getProgramParameter(n,t.LINK_STATUS)?n:(console.warn("Unable to link shader program: "+t.getProgramInfoLog(n)),null)}static _loadShader(t,e,r){const i=t.createShader(e);return t.shaderSource(i,r),t.compileShader(i),t.getShaderParameter(i,t.COMPILE_STATUS)?i:(console.warn("An error occured compiling shader: "+t.getShaderInfoLog(i)),t.deleteShader(i),null)}}Shader.INTERNAL_TEXTURE_UNITS=1,Shader._DEFAULT_TEXTURE_OPTIONS={createUniform:!0,target:"TEXTURE_2D",level:0,internalFormat:"RGBA",srcFormat:"RGBA",srcType:"UNSIGNED_BYTE",minFilter:"LINEAR",magFilter:"LINEAR",wrapS:"CLAMP_TO_EDGE",wrapT:"CLAMP_TO_EDGE"},Shader._VERTEX_SOURCE="\n    attribute vec4 a_VertexPosition;\n    attribute vec2 a_TextureCoord;\n\n    varying highp vec2 v_TextureCoord;\n\n    void main() {\n        // no need for projection or model-view matrices, since we're just rendering a rectangle\n        // that fills the screen (see position values)\n        gl_Position = a_VertexPosition;\n        v_TextureCoord = a_TextureCoord;\n    }\n  ",Shader._IDENTITY_FRAGMENT_SOURCE="\n    precision mediump float;\n\n    uniform sampler2D u_Source;\n\n    varying highp vec2 v_TextureCoord;\n\n    void main() {\n        gl_FragColor = texture2D(u_Source, v_TextureCoord);\n    }\n  ";const isPowerOf2=t=>0===(t&&t-1);class Brightness extends Shader{constructor(t={}){super({fragmentSource:"\n        precision mediump float;\n\n        uniform sampler2D u_Source;\n        uniform float u_Brightness;\n\n        varying highp vec2 v_TextureCoord;\n\n        void main() {\n          vec4 color = texture2D(u_Source, v_TextureCoord);\n          vec3 rgb = clamp(color.rgb + u_Brightness / 255.0, 0.0, 1.0);\n          gl_FragColor = vec4(rgb, color.a);\n        }\n      ",uniforms:{brightness:"1f"}}),this.brightness=t.brightness||0}}class Channels extends Shader{constructor(t={}){super({fragmentSource:"\n        precision mediump float;\n\n        uniform sampler2D u_Source;\n        uniform vec4 u_Factors;\n\n        varying highp vec2 v_TextureCoord;\n\n        void main() {\n          vec4 color = texture2D(u_Source, v_TextureCoord);\n          gl_FragColor = clamp(u_Factors * color, 0.0, 1.0);\n        }\n      ",uniforms:{factors:{type:"4fv",defaultFloatComponent:1}}}),this.factors=t.factors||{}}}class ChromaKey extends Shader{constructor(t={}){super({fragmentSource:"\n        precision mediump float;\n\n        uniform sampler2D u_Source;\n        uniform vec3 u_Target;\n        uniform float u_Threshold;\n        uniform bool u_Interpolate;\n\n        varying highp vec2 v_TextureCoord;\n\n        void main() {\n          vec4 color = texture2D(u_Source, v_TextureCoord);\n          float alpha = color.a;\n          vec3 dist = abs(color.rgb - u_Target / 255.0);\n          if (!u_Interpolate) {\n            // Standard way that most video editors probably use (all-or-nothing method)\n            float thresh = u_Threshold / 255.0;\n            bool transparent = dist.r <= thresh && dist.g <= thresh && dist.b <= thresh;\n            if (transparent)\n              alpha = 0.0;\n          } else {\n            /*\n             better way IMHO:\n             Take the average of the absolute differences between the pixel and the target for each channel\n             */\n            float transparency = (dist.r + dist.g + dist.b) / 3.0;\n            // TODO: custom or variety of interpolation methods\n            alpha = transparency;\n          }\n          gl_FragColor = vec4(color.rgb, alpha);\n        }\n      ",uniforms:{target:"3fv",threshold:"1f",interpolate:"1i"}}),this.target=t.target||new Color(0,0,0),this.threshold=t.threshold||0,this.interpolate=t.interpolate||!1}}class Contrast extends Shader{constructor(t={}){super({fragmentSource:"\n        precision mediump float;\n\n        uniform sampler2D u_Source;\n        uniform float u_Contrast;\n\n        varying highp vec2 v_TextureCoord;\n\n        void main() {\n          vec4 color = texture2D(u_Source, v_TextureCoord);\n          vec3 rgb = clamp(u_Contrast * (color.rgb - 0.5) + 0.5, 0.0, 1.0);\n          gl_FragColor = vec4(rgb, color.a);\n        }\n      ",uniforms:{contrast:"1f"}}),this.contrast=t.contrast||1}}class EllipticalMaskOptions{}class EllipticalMask extends Visual{constructor(t){super(),this.x=t.x,this.y=t.y,this.radiusX=t.radiusX,this.radiusY=t.radiusY,this.rotation=t.rotation||0,this.startAngle=t.startAngle||0,this.endAngle=void 0!==t.endAngle?t.endAngle:2*Math.PI,this.anticlockwise=t.anticlockwise||!1,this._tmpCanvas=document.createElement("canvas"),this._tmpCtx=this._tmpCanvas.getContext("2d")}apply(t,e){const r=t.cctx,i=t.canvas,s=val(this,"x",e),n=val(this,"y",e),o=val(this,"radiusX",e),a=val(this,"radiusY",e),c=val(this,"rotation",e),h=val(this,"startAngle",e),u=val(this,"endAngle",e),l=val(this,"anticlockwise",e);this._tmpCanvas.width=t.canvas.width,this._tmpCanvas.height=t.canvas.height,this._tmpCtx.drawImage(i,0,0),r.clearRect(0,0,i.width,i.height),r.save(),r.beginPath(),r.ellipse(s,n,o,a,c,h,u,l),r.closePath(),r.clip(),r.drawImage(this._tmpCanvas,0,0),r.restore()}}class StackEffectsListener extends CustomArrayListener{constructor(t){super(),this._stack=t}onAdd(t){this._stack.parent&&t.tryAttach(this._stack.parent)}onRemove(t){this._stack.parent&&t.tryDetach()}}class StackEffects extends CustomArray{constructor(t,e){super(t,new StackEffectsListener(e))}}class Stack extends Visual{constructor(t){super(),this.effects=new StackEffects(t.effects,this),t.effects.forEach(t=>this.effects.push(t))}attach(t){super.attach(t),this.effects.filter(t=>!!t).forEach(e=>{e.tryAttach(t)})}detach(){super.detach(),this.effects.filter(t=>!!t).forEach(t=>{t.tryDetach()})}apply(t,e){for(let r=0;r<this.effects.length;r++){const i=this.effects[r];i&&i.apply(t,e)}}addEffect(t){return this.effects.push(t),this}}class GaussianBlur extends Stack{constructor(t){super({effects:[new GaussianBlurHorizontal(t),new GaussianBlurVertical(t)]})}}class GaussianBlurComponent extends Shader{constructor(t){super({fragmentSource:t.fragmentSource,uniforms:{radius:"1i"},textures:{shape:{minFilter:"NEAREST",magFilter:"NEAREST"}}}),this.radius=t.radius,this._radiusCache=void 0}apply(t,e){const r=val(this,"radius",e);r!==this._radiusCache&&(this.shape=GaussianBlurComponent._render1DKernel(GaussianBlurComponent._gen1DKernel(r))),this._radiusCache=r,super.apply(t,e)}static _render1DKernel(t){const e=document.createElement("canvas");e.width=t.length,e.height=1;const r=e.getContext("2d"),i=r.createImageData(e.width,e.height);for(let e=0;e<t.length;e++)i.data[4*e+0]=255*t[e],i.data[4*e+1]=0,i.data[4*e+2]=0,i.data[4*e+3]=255;return r.putImageData(i,0,0),e}static _gen1DKernel(t){const e=GaussianBlurComponent._genPascalRow(2*t+1);let r=0;for(let t=0;t<e.length;t++)r+=e[t];for(let t=0;t<e.length;t++)e[t]/=r;return e}static _genPascalRow(t){if(t<0)throw new Error(`Invalid index ${t}`);let e=[1];for(let r=1;r<t;r++){const t=[];t.length=e.length+1,t[0]=t[t.length-1]=1;for(let r=1;r<t.length-1;r++)t[r]=e[r-1]+e[r];e=t}return e}}GaussianBlurComponent.prototype.publicExcludes=Shader.prototype.publicExcludes.concat(["shape"]);class GaussianBlurHorizontal extends GaussianBlurComponent{constructor(t){super({fragmentSource:"\n        #define MAX_RADIUS 250\n\n        precision mediump float;\n\n        uniform sampler2D u_Source;\n        uniform ivec2 u_Size;   // pixel dimensions of input and output\n        uniform sampler2D u_Shape;  // pseudo one-dimension of blur distribution (would be 1D but webgl doesn't support it)\n        uniform int u_Radius;   // TODO: support floating-point radii\n\n        varying highp vec2 v_TextureCoord;\n\n        void main() {\n          /*\n           * Ideally, totalWeight should end up being 1, but due to rounding errors, it sometimes ends up less than 1\n           * (I believe JS canvas stores values as integers, which rounds down for the majority of the Gaussian curve)\n           * So, normalize by accumulating all the weights and dividing by that.\n           */\n          float totalWeight = 0.0;\n          vec4 avg = vec4(0.0);\n          // GLSL can only use constants in for-loop declaration, so start at zero, and stop before 2 * u_Radius + 1,\n          // opposed to starting at -u_Radius and stopping _at_ +u_Radius.\n          for (int i = 0; i < 2 * MAX_RADIUS + 1; i++) {\n            if (i >= 2 * u_Radius + 1)\n              break;  // GLSL can only use constants in for-loop declaration, so we break here.\n            // (2 * u_Radius + 1) is the width of u_Shape, by definition\n            float weight = texture2D(u_Shape, vec2(float(i) / float(2 * u_Radius + 1), 0.5)).r;   // TODO: use single-channel format\n            totalWeight += weight;\n            vec4 sample = texture2D(u_Source, v_TextureCoord + vec2(i - u_Radius, 0.0) / vec2(u_Size));\n            avg += weight * sample;\n          }\n          gl_FragColor = avg / totalWeight;\n        }\n      ",radius:t.radius})}}class GaussianBlurVertical extends GaussianBlurComponent{constructor(t){super({fragmentSource:"\n        #define MAX_RADIUS 250\n\n        precision mediump float;\n\n        uniform sampler2D u_Source;\n        uniform ivec2 u_Size;   // pixel dimensions of input and output\n        uniform sampler2D u_Shape;  // pseudo one-dimension of blur distribution (would be 1D but webgl doesn't support it)\n        uniform int u_Radius;   // TODO: support floating-point radii\n\n        varying highp vec2 v_TextureCoord;\n\n        void main() {\n          /*\n           * Ideally, totalWeight should end up being 1, but due to rounding errors, it sometimes ends up less than 1\n           * (I believe JS canvas stores values as integers, which rounds down for the majority of the Gaussian curve)\n           * So, normalize by accumulating all the weights and dividing by that.\n           */\n          float totalWeight = 0.0;\n          vec4 avg = vec4(0.0);\n          // GLSL can only use constants in for-loop declaration, so start at zero, and stop before 2 * u_Radius + 1,\n          // opposed to starting at -u_Radius and stopping _at_ +u_Radius.\n          for (int i = 0; i < 2 * MAX_RADIUS + 1; i++) {\n            if (i >= 2 * u_Radius + 1)\n              break;  // GLSL can only use constants in for-loop declaration, so we break here.\n            // (2 * u_Radius + 1) is the width of u_Shape, by definition\n            float weight = texture2D(u_Shape, vec2(float(i) / float(2 * u_Radius + 1), 0.5)).r;   // TODO: use single-channel format\n            totalWeight += weight;\n            vec4 sample = texture2D(u_Source, v_TextureCoord + vec2(0.0, i - u_Radius) / vec2(u_Size));\n            avg += weight * sample;\n          }\n          gl_FragColor = avg / totalWeight;\n        }\n      ",radius:t.radius})}}class Grayscale extends Shader{constructor(){super({fragmentSource:"\n        precision mediump float;\n\n        uniform sampler2D u_Source;\n        uniform vec4 u_Factors;\n\n        varying highp vec2 v_TextureCoord;\n\n        float max3(float x, float y, float z) {\n          return max(x, max(y, z));\n        }\n\n        float min3(float x, float y, float z) {\n          return min(x, min(y, z));\n        }\n\n        void main() {\n          vec4 color = texture2D(u_Source, v_TextureCoord);\n          // Desaturate\n          float value = (max3(color.r, color.g, color.b) + min3(color.r, color.g, color.b)) / 2.0;\n          gl_FragColor = vec4(value, value, value, color.a);\n        }\n      "})}}class Pixelate extends Shader{constructor(t={}){super({fragmentSource:"\n        precision mediump float;\n\n        uniform sampler2D u_Source;\n        uniform ivec2 u_Size;\n        uniform int u_PixelSize;\n\n        varying highp vec2 v_TextureCoord;\n\n        void main() {\n          int ps = u_PixelSize;\n\n          // Snap to nearest block's center\n          vec2 loc = vec2(u_Size) * v_TextureCoord; // pixel-space\n          vec2 snappedLoc = float(ps) * floor(loc / float(ps));\n          vec2 centeredLoc = snappedLoc + vec2(float(u_PixelSize) / 2.0 + 0.5);\n          vec2 clampedLoc = clamp(centeredLoc, vec2(0.0), vec2(u_Size));\n          gl_FragColor = texture2D(u_Source, clampedLoc / vec2(u_Size));\n        }\n      ",uniforms:{pixelSize:"1i"}}),this.pixelSize=t.pixelSize||1}apply(t,e){const r=val(this,"pixelSize",e);if(r%1!=0||r<0)throw new Error("Pixel size must be a nonnegative integer");super.apply(t,e)}}class Transform extends Visual{constructor(t){super(),this.matrix=t.matrix,this._tmpMatrix=new Transform.Matrix,this._tmpCanvas=document.createElement("canvas"),this._tmpCtx=this._tmpCanvas.getContext("2d")}apply(t,e){t.canvas.width!==this._tmpCanvas.width&&(this._tmpCanvas.width=t.canvas.width),t.canvas.height!==this._tmpCanvas.height&&(this._tmpCanvas.height=t.canvas.height),this._tmpMatrix.data=val(this,"matrix",e).data,this._tmpCtx.setTransform(this._tmpMatrix.a,this._tmpMatrix.b,this._tmpMatrix.c,this._tmpMatrix.d,this._tmpMatrix.e,this._tmpMatrix.f),this._tmpCtx.drawImage(t.canvas,0,0),this._tmpCtx.setTransform(1,0,0,0,1,0),t.cctx.clearRect(0,0,t.canvas.width,t.canvas.height),t.cctx.drawImage(this._tmpCanvas,0,0)}}!function(t){class e{constructor(t){this.data=t||[1,0,0,0,1,0,0,0,1]}identity(){for(let t=0;t<this.data.length;t++)this.data[t]=e.IDENTITY.data[t];return this}cell(t,e,r){return void 0!==r&&(this.data[3*e+t]=r),this.data[3*e+t]}get a(){return this.data[0]}get b(){return this.data[3]}get c(){return this.data[1]}get d(){return this.data[4]}get e(){return this.data[2]}get f(){return this.data[5]}multiply(t){for(let r=0;r<3;r++)for(let i=0;i<3;i++){let s=0;for(let e=0;e<3;e++)s+=this.cell(r,e)*t.cell(e,i);e._TMP_MATRIX.cell(r,i,s)}for(let t=0;t<e._TMP_MATRIX.data.length;t++)this.data[t]=e._TMP_MATRIX.data[t];return this}translate(t,r){return this.multiply(new e([1,0,t,0,1,r,0,0,1])),this}scale(t,r){return this.multiply(new e([t,0,0,0,r,0,0,0,1])),this}rotate(t){const r=Math.cos(t),i=Math.sin(t);return this.multiply(new e([r,i,0,-i,r,0,0,0,1])),this}}e.IDENTITY=new e,e._TMP_MATRIX=new e,t.Matrix=e}(Transform||(Transform={}));var Effects=Object.freeze({__proto__:null,Base:Base,Brightness:Brightness,Channels:Channels,ChromaKey:ChromaKey,Contrast:Contrast,EllipticalMask:EllipticalMask,EllipticalMaskOptions:EllipticalMaskOptions,GaussianBlur:GaussianBlur,GaussianBlurHorizontal:GaussianBlurHorizontal,GaussianBlurVertical:GaussianBlurVertical,Grayscale:Grayscale,Pixelate:Pixelate,Shader:Shader,Stack:Stack,get Transform(){return Transform},Visual:Visual});class MovieEffectsListener extends CustomArrayListener{constructor(t){super(),this._movie=t}onAdd(t){t.tryAttach(this._movie)}onRemove(t){t.tryDetach()}}class MovieEffects extends CustomArray{constructor(t,e){super(t,new MovieEffectsListener(e))}}class MovieLayersListener extends CustomArrayListener{constructor(t){super(),this._movie=t}onAdd(t){t.tryAttach(this._movie)}onRemove(t){t.tryDetach()}}class MovieLayers extends CustomArray{constructor(t,e){super(t,new MovieLayersListener(e))}}class MovieOptions{}class Movie{constructor(t){if(this._recording=!1,this.actx=t.actx||t.audioContext||new AudioContext||new window.webkitAudioContext,delete t.actx,!t.canvas)throw new Error('Required option "canvas" not provided to Movie');this._canvas=this._visibleCanvas=t.canvas,delete t.canvas,this._cctx=this.canvas.getContext("2d"),applyOptions(t,this),this.effects=new MovieEffects([],this),this.layers=new MovieLayers([],this),this._paused=!0,this._ended=!1,this._renderingFrame=!1,this.currentTime=0}_whenReady(){return __awaiter(this,void 0,void 0,function*(){yield Promise.all([Promise.all(this.layers.map(t=>t.whenReady())),Promise.all(this.effects.map(t=>t.whenReady()))])})}play(t={}){var e;return __awaiter(this,void 0,void 0,function*(){if(yield this._whenReady(),!this.paused)throw new Error("Already playing");this._paused=this._ended=!1,this._lastRealTime=performance.now(),this._endTime=t.duration?this.currentTime+t.duration:this.duration,null===(e=t.onStart)||void 0===e||e.call(t),publish(this,"movie.play",{}),yield new Promise(e=>{this.renderingFrame||this._render(void 0,e,t.onDraw),this._renderingFrame=!1}),this._lastRealTime=void 0})}_show(){this._canvas=this._visibleCanvas,this._cctx=this.canvas.getContext("2d"),publish(this,"audiodestinationupdate",{movie:this,destination:this.actx.destination})}stream(t){return __awaiter(this,void 0,void 0,function*(){if(!t||!t.frameRate)throw new Error('Required option "frameRate" not provided to Movie.stream');if(!1===t.video&&!1===t.audio)throw new Error("Both video and audio cannot be disabled");if(!this.paused)throw new Error("Cannot stream movie while it's already playing");yield this._whenReady(),this._canvas=document.createElement("canvas"),this.canvas.width=this._visibleCanvas.width,this.canvas.height=this._visibleCanvas.height,this._cctx=this.canvas.getContext("2d");let e=[];if(!1!==t.video){const r=this.canvas.captureStream(t.frameRate);e=e.concat(r.getTracks())}if(this.layers.some(t=>t instanceof Audio||t instanceof Video)&&!1!==t.audio){const t=this.actx.createMediaStreamDestination(),r=t.stream;e=e.concat(r.getTracks()),publish(this,"audiodestinationupdate",{movie:this,destination:t})}this._currentStream=new MediaStream(e),yield this.play({onStart:()=>{t.onStart(this._currentStream)},duration:t.duration}),this._currentStream.getTracks().forEach(t=>{t.stop()}),this._currentStream=null,this._show()})}record(t){var e;return __awaiter(this,void 0,void 0,function*(){if(!1===t.video&&!1===t.audio)throw new Error("Both video and audio cannot be disabled");if(!this.paused)throw new Error("Cannot record movie while it's already playing");const r=t.type||"video/webm";if(MediaRecorder&&MediaRecorder.isTypeSupported&&!MediaRecorder.isTypeSupported(r))throw new Error("Please pass a valid MIME type for the exported video");const i=yield new Promise(e=>{this.stream({frameRate:t.frameRate,duration:t.duration,video:t.video,audio:t.audio,onStart:e}).then(()=>{this._recorder.requestData(),this._recorder.stop()})}),s=[],n=Object.assign(Object.assign({},t.mediaRecorderOptions||{}),{mimeType:r});return this._recorder=new MediaRecorder(i,n),this._recorder.ondataavailable=t=>{t.data.size>0&&s.push(t.data)},this._recorder.start(),this._recording=!0,null===(e=t.onStart)||void 0===e||e.call(t,this._recorder),publish(this,"movie.record",{options:t}),yield new Promise((t,e)=>{this._recorder.onstop=()=>{t()},this._recorder.onerror=e}),this._paused=!0,this._ended=!0,this._recording=!1,new Blob(s,{type:r})})}pause(){this._paused=!0;for(let t=0;t<this.layers.length;t++)if(Object.prototype.hasOwnProperty.call(this.layers,t)){const e=this.layers[t];e.active&&(e.stop(),e.active=!1)}return publish(this,"movie.pause",{}),this}stop(){return this.pause(),this.currentTime=0,this}_render(t=performance.now(),e=void 0,r=void 0){if(clearCachedValues(this),this.rendering){if(this.ready){publish(this,"movie.loadeddata",{movie:this}),this._recording&&"paused"===this._recorder.state&&this._recorder.resume();const i=this._currentStream?this._endTime:this.duration;if(this._updateCurrentTime(t,i),this.currentTime===i&&(this.recording&&publish(this,"movie.recordended",{movie:this}),this.currentTime===this.duration&&publish(this,"movie.ended",{movie:this,repeat:this.repeat}),this._currentTime=0,publish(this,"movie.timeupdate",{movie:this}),this._renderingFrame=!1,this.recording||!this.repeat)){this._paused=!0,this._ended=!0;for(let t=0;t<this.layers.length;t++)if(Object.prototype.hasOwnProperty.call(this.layers,t)){const e=this.layers[t];if(!e||!e.active)continue;e.stop(),e.active=!1}return publish(this,"movie.pause",{}),void(e&&e())}this._renderBackground(t),this._renderLayers(),this._applyEffects(),null==r||r()}else this.recording&&"recording"===this._recorder.state&&this._recorder.pause();if(this._renderingFrame&&this.ready)return this._renderingFrame=!1,void(e&&e());window.requestAnimationFrame(()=>{this._render(void 0,e)})}else e&&e()}_updateCurrentTime(t,e){if(!this._renderingFrame){const r=t/1e3,i=r-this._lastRealTime;this._lastRealTime=r,i>0&&(this._currentTime+=i,publish(this,"movie.timeupdate",{movie:this})),this.currentTime>e&&(this._currentTime=e)}}_renderBackground(t){this.cctx.clearRect(0,0,this.canvas.width,this.canvas.height);const e=val(this,"background",t);e&&(this.cctx.fillStyle=e,this.cctx.fillRect(0,0,this.canvas.width,this.canvas.height))}_renderLayers(){for(let t=0;t<this.layers.length;t++){if(!Object.prototype.hasOwnProperty.call(this.layers,t))continue;const e=this.layers[t];if(!e)continue;const r=this.currentTime-e.startTime;if(!val(e,"enabled",r)||this.currentTime<e.startTime||this.currentTime>e.startTime+e.duration)e.active&&!this._renderingFrame&&(e.stop(),e.active=!1);else if(this._renderingFrame||e.progress(r),e.active||!val(e,"enabled",r)||this._renderingFrame||(e.start(),e.active=!0),e.render(),e instanceof Visual$1){const t=e.canvas;t.width*t.height>0&&this.cctx.drawImage(t,val(e,"x",r),val(e,"y",r),t.width,t.height)}}}_applyEffects(){for(let t=0;t<this.effects.length;t++){const e=this.effects[t];e&&e.apply(this,this.currentTime)}}refresh(){if(!this.paused)throw new Error("Already playing");return new Promise(t=>{this._renderingFrame=!0,this._render(void 0,t)})}_publishToLayers(t,e){for(let r=0;r<this.layers.length;r++)Object.prototype.hasOwnProperty.call(this.layers,r)&&publish(this.layers[r],t,e)}get rendering(){return!this.paused||this._renderingFrame}get renderingFrame(){return this._renderingFrame}get recording(){return this._recording}get duration(){return this.layers.reduce((t,e)=>Math.max(e.startTime+e.duration,t),0)}addLayer(t){return this.layers.push(t),this}addEffect(t){return this.effects.push(t),this}get paused(){return this._paused}get ended(){return this._ended}seek(t){this._currentTime=t;for(let e=0;e<this.layers.length;e++){const r=this.layers[e];if(r){const e=t-r.startTime;e>=0&&e<=r.duration?r.seek(e):r.seek(void 0)}}publish(this,"movie.seek",{})}get currentTime(){return this._currentTime}set currentTime(t){this.seek(t)}setCurrentTime(t,e=!0){return new Promise((r,i)=>{this.seek(t),e?this.refresh().then(r).catch(i):r()})}get ready(){const t=this.layers.every(t=>t.ready),e=this.effects.every(t=>t.ready);return t&&e}get canvas(){return this._canvas}get cctx(){return this._cctx}get width(){return this.canvas.width}set width(t){this.canvas.width=t}get height(){return this.canvas.height}set height(t){this.canvas.height=t}get movie(){return this}getDefaultOptions(){return{canvas:void 0,background:parseColor("#000"),repeat:!1}}toJSON(){return{type:"movie",canvas:this.canvas?{width:this.canvas.width,height:this.canvas.height}:void 0,background:serializeProperty(this.background),repeat:this.repeat,layers:this.layers.map(t=>t.toJSON()),effects:this.effects.map(t=>t.toJSON())}}static fromJSON(t,e,r){e||(e=document.createElement("canvas"),t.canvas&&(e.width=t.canvas.width,e.height=t.canvas.height));const i={canvas:e,actx:r,background:deserializeProperty(t.background),repeat:t.repeat},s=new Movie(i),n=t=>{const e=t.type.replace("effect.",""),r=Effects[e];if(!r)throw new Error(`Unknown effect type: ${e}`);const i={},s=r.prototype.getDefaultOptions?r.prototype.getDefaultOptions():{};for(const e in t)"type"!==e&&"effects"!==e&&e in s&&(i[e]=deserializeProperty(t[e]));t.effects&&(i.effects=t.effects.map(t=>n(t)));const o=new r(i);for(const e in t)"type"===e||"effects"===e||e in s||(o[e]=deserializeProperty(t[e]));return o},o=t=>{const e=t.type.replace("layer.",""),r=Layers[e];if(!r)throw new Error(`Unknown layer type: ${e}`);const i={},s=r.prototype.getDefaultOptions?r.prototype.getDefaultOptions():{};"startTime"in s||(s.startTime=void 0),"duration"in s||(s.duration=void 0);for(const e in t)"type"!==e&&"effects"!==e&&e in s&&(i[e]=deserializeProperty(t[e]));const o=new r(i);for(const e in t)"type"===e||"effects"===e||e in s||(o[e]=deserializeProperty(t[e]));if(t.effects)for(const e of t.effects)o.addEffect(n(e));return o};if(t.layers)for(const e of t.layers)s.addLayer(o(e));if(t.effects)for(const e of t.effects)s.addEffect(n(e));return s}}Movie.prototype.type="movie",Movie.prototype.propertyFilters={},deprecate("movie.audiodestinationupdate","audiodestinationupdate"),deprecate("movie.ended",void 0),deprecate("movie.loadeddata",void 0),deprecate("movie.pause",void 0,"Wait for `play()`, `stream()`, or `record()` to resolve instead."),deprecate("movie.play",void 0,"Provide an `onStart` callback to `play()`, `stream()`, or `record()` instead."),deprecate("movie.record",void 0,"Provide an `onStart` callback to `record()` instead."),deprecate("movie.recordended",void 0,"Wait for `record()` to resolve instead."),deprecate("movie.seek",void 0,"Override the `seek` method on layers instead."),deprecate("movie.timeupdate",void 0,"Override the `progress` method on layers instead.");var etro=Object.freeze({__proto__:null,Color:Color,Font:Font,KeyFrame:KeyFrame,Movie:Movie,MovieOptions:MovieOptions,applyOptions:applyOptions,clearCachedValues:clearCachedValues,cosineInterp:cosineInterp,deserializeProperty:deserializeProperty,effect:Effects,event:event,layer:Layers,linearInterp:linearInterp,mapPixels:mapPixels,parseColor:parseColor,parseFont:parseFont,serializeProperty:serializeProperty,val:val});module.exports=etro;
//# sourceMappingURL=/sm/bc6b9bae71836d656991a1bb657714eb9e815a59dc7c8cf18f4bd3b6345881f1.map