functiondownload(t,e,n){functioni(t){vare=t.split(/[:;,]/),n=e[1],i="base64"==e[2]?atob:decodeURIComponent,r=i(e.pop()),o=r.length,a=0,s=newUint8Array(o);for(a;a<o;++a)s[a]=r.charCodeAt(a);returnnewm([s],{type:n})}functionr(t,e){if("download"inl)returnl.href=t,l.setAttribute("download",w),l.innerHTML="downloading...",l.style.display="none",f.body.appendChild(l),setTimeout(function(){l.click(),f.body.removeChild(l),e===!0&&setTimeout(function(){h.URL.revokeObjectURL(l.href)},250)},66),!0;varn=f.createElement("iframe");f.body.appendChild(n),e||(t="data:"+t.replace(/^data:([\w\/\-\+]+)/,d)),n.src=t,setTimeout(function(){f.body.removeChild(n)},333)}varo,a,s,h=window,d="application/octet-stream",u=n||d,c=t,f=document,l=f.createElement("a"),p=function(t){returnString(t)},m=h.Blob||h.MozBlob||h.WebKitBlob||p,g=h.MSBlobBuilder||h.WebKitBlobBuilder||h.BlobBuilder,w=e||"download";if("true"===String(this)&&(c=[c,u],u=c[0],c=c[1]),String(c).match(/^data\:[\w+\-]+\/[\w+\-]+[,;]/))returnnavigator.msSaveBlob?navigator.msSaveBlob(i(c),w):r(c);try{o=cinstanceofm?c:newm([c],{type:u})}catch(t){g&&(a=newg,a.append([c]),o=a.getBlob(u))}if(navigator.msSaveBlob)returnnavigator.msSaveBlob(o,w);if(h.URL)r(h.URL.createObjectURL(o),!0);else{if("string"==typeofo||o.constructor===p)try{returnr("data:"+u+";base64,"+h.btoa(o))}catch(t){returnr("data:"+u+","+encodeURIComponent(o))}s=newFileReader,s.onload=function(t){r(this.result)},s.readAsDataURL(o)}return!0}window.Whammy=function(){functiont(t,n){for(vari=e(t),r=3e4,o=[{id:440786851,data:[{data:1,id:17030},{data:1,id:17143},{data:4,id:17138},{data:8,id:17139},{data:"webm",id:17026},{data:2,id:17031},{data:2,id:17029}]},{id:408125543,data:[{id:357149030,data:[{data:1e6,id:2807729},{data:"whammy",id:19840},{data:"whammy",id:22337},{data:c(i.duration),id:17545}]},{id:374648427,data:[{id:174,data:[{data:1,id:215},{data:1,id:29637},{data:0,id:156},{data:"und",id:2274716},{data:"V_VP8",id:134},{data:"VP8",id:2459272},{data:1,id:131},{id:224,data:[{data:i.width,id:176},{data:i.height,id:186}]}]}]},{id:475249515,data:[]}]}],s=o[1],d=s.data[2],u=0,f=0;u<t.length;){varl={id:187,data:[{data:Math.round(f),id:179},{id:183,data:[{data:1,id:247},{data:0,size:8,id:241}]}]};d.data.push(l);varp=[],m=0;dop.push(t[u]),m+=t[u].duration,u++;while(u<t.length&&m<r);varg=0,w={id:524531317,data:[{data:Math.round(f),id:231}].concat(p.map(function(t){vare=h({discardable:0,frame:t.data.slice(4),invisible:0,keyframe:1,lacing:0,trackNum:1,timecode:Math.round(g)});returng+=t.duration,{data:e,id:163}}))};s.data.push(w),f+=m}for(varv=0,y=0;y<s.data.length;y++){y>=3&&(d.data[y-3].data[1].data[1].data=v);varb=a([s.data[y]],n);v+=b.size||b.byteLength||b.length,2!=y&&(s.data[y]=b)}returna(o,n)}functione(t){for(vare=t[0].width,n=t[0].height,i=t[0].duration,r=1;r<t.length;r++){if(t[r].width!=e)throw"Frame "+(r+1)+" has a different width";if(t[r].height!=n)throw"Frame "+(r+1)+" has a different height";if(t[r].duration<0||t[r].duration>32767)throw"Frame "+(r+1)+" has a weird duration (must be between 0 and 32767)";i+=t[r].duration}return{duration:i,width:e,height:n}}functionn(t){for(vare=[];t>0;)e.push(255&t),t>>=8;returnnewUint8Array(e.reverse())}functioni(t,e){for(varn=newUint8Array(e),i=e-1;i>=0;i--)n[i]=255&t,t>>=8;returnn}functionr(t){for(vare=newUint8Array(t.length),n=0;n<t.length;n++)e[n]=t.charCodeAt(n);returne}functiono(t){vare=[],n=t.length%8?newArray(9-t.length%8).join("0"):"";t=n+t;for(vari=0;i<t.length;i+=8)e.push(parseInt(t.substr(i,8),2));returnnewUint8Array(e)}functiona(t,e){for(varh=[],d=0;d<t.length;d++)if("id"int[d]){varu=t[d].data;if("object"==typeofu&&(u=a(u,e)),"number"==typeofu&&(u="size"int[d]?i(u,t[d].size):o(u.toString(2))),"string"==typeofu&&(u=r(u)),u.length);for(varc=u.size||u.byteLength||u.length,f=0,l=56;l>0;l-=7)if(c>Math.pow(2,l)-2){f=l/7;break}varp=c.toString(2),m=newArray(8*(f+1)+1).join("0"),g=newArray(f+1).join("0")+1,w=m.substr(0,m.length-p.length-g.length)+p,v=g+w;h.push(n(t[d].id)),h.push(o(v)),h.push(u)}elseh.push(t[d]);if(e){vary=s(h);returnnewUint8Array(y)}returnnewBlob(h,{type:"video/webm"})}functions(t,e){null==e&&(e=[]);for(varn=0;n<t.length;n++)"object"==typeoft[n]?s(t[n],e):e.push(t[n]);returne}functionh(t){vare=0;if(t.keyframe&&(e|=128),t.invisible&&(e|=8),t.lacing&&(e|=t.lacing<<1),t.discardable&&(e|=1),t.trackNum>127)throw"TrackNumber > 127 not supported";varn=[128|t.trackNum,t.timecode>>8,255&t.timecode,e].map(function(t){returnString.fromCharCode(t)}).join("")+t.frame;returnn}functiond(t){for(vare=t.RIFF[0].WEBP[0],n=e.indexOf("*"),i=0,r=[];i<4;i++)r[i]=e.charCodeAt(n+3+i);varo,a,s,h,d;returnd=r[1]<<8|r[0],o=16383&d,a=d>>14,d=r[3]<<8|r[2],s=16383&d,h=d>>14,{width:o,height:s,data:e,riff:t}}functionu(t){for(vare=0,n={};e<t.length;){vari=t.substr(e,4);if(n[i]=n[i]||[],"RIFF"==i||"LIST"==i){varr=parseInt(t.substr(e+4,4).split("").map(function(t){vare=t.charCodeAt(0).toString(2);returnnewArray(8-e.length+1).join("0")+e}).join(""),2),o=t.substr(e+4+4,r);e+=8+r,n[i].push(u(o))}else"WEBP"==i?(n[i].push(t.substr(e+8)),e=t.length):(n[i].push(t.substr(e+4)),e=t.length)}returnn}functionc(t){return[].slice.call(newUint8Array(newFloat64Array([t]).buffer),0).map(function(t){returnString.fromCharCode(t)}).reverse().join("")}functionf(t,e){this.frames=[],this.duration=1e3/t,this.quality=e||.8}returnf.prototype.add=function(t,e){if("undefined"!=typeofe&&this.duration)throw"you can't pass a duration if the fps is set";if("undefined"==typeofe&&!this.duration)throw"if you don't have the fps set, you need to have durations here.";if(t.canvas&&(t=t.canvas),t.toDataURL)t=t.getContext("2d").getImageData(0,0,t.width,t.height);elseif("string"!=typeoft)throw"frame must be a a HTMLCanvasElement, a CanvasRenderingContext2D or a DataURI formatted string";if("string"==typeoft&&!/^data:image\/webp;base64,/gi.test(t))throw"Input must be formatted properly as a base64 encoded DataURI of type image/webp";this.frames.push({image:t,duration:e||this.duration})},f.prototype.encodeFrames=function(t){if(this.frames[0].imageinstanceofImageData){vare=this.frames,n=document.createElement("canvas"),i=n.getContext("2d");n.width=this.frames[0].image.width,n.height=this.frames[0].image.height;varr=function(o){vara=e[o];i.putImageData(a.image,0,0),a.image=n.toDataURL("image/webp",this.quality),o<e.length-1?setTimeout(function(){r(o+1)},1):t()}.bind(this);r(0)}elset()},f.prototype.compile=function(e,n){this.encodeFrames(function(){vari=newt(this.frames.map(function(t){vare=d(u(atob(t.image.slice(23))));returne.duration=t.duration,e}),e);n(i)}.bind(this))},{Video:f,fromImageArray:function(e,n,i){returnt(e.map(function(t){vare=d(u(atob(t.slice(23))));returne.duration=1e3/n,e}),i)},toWebM:t}}(),function(){"use strict";functiont(t){vare,n=newUint8Array(t);for(e=0;e<t;e+=1)n[e]=0;returnn}functione(e,n,i,r){varo=n+i,a=t((parseInt(o/r)+1)*r);returna.set(e),a}functionn(t,e,n){returnt=t.toString(n||8),"000000000000".substr(t.length+12-e)+t}functioni(e,n,i){varr,o;for(n=n||t(e.length),i=i||0,r=0,o=e.length;r<o;r+=1)n[i]=e.charCodeAt(r),i+=1;returnn}functionr(t){functione(t){returno[t>>18&63]+o[t>>12&63]+o[t>>6&63]+o[63&t]}varn,i,r,a=t.length%3,s="";for(n=0,r=t.length-a;n<r;n+=3)i=(t[n]<<16)+(t[n+1]<<8)+t[n+2],s+=e(i);switch(s.length%4){case1:s+="=";break;case2:s+="=="}returns}varo=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","+","/"];window.utils={},window.utils.clean=t,window.utils.pad=n,window.utils.extend=e,window.utils.stringToUint8=i,window.utils.uint8ToBase64=r}(),function(){"use strict";functiont(t,i){varr=n.clean(512),o=0;returne.forEach(function(e){varn,i,a=t[e.field]||"";for(n=0,i=a.length;n<i;n+=1)r[o]=a.charCodeAt(n),o+=1;o+=e.length-n}),"function"==typeofi?i(r,o):r}vare,n=window.utils;e=[{field:"fileName",length:100},{field:"fileMode",length:8},{field:"uid",length:8},{field:"gid",length:8},{field:"fileSize",length:12},{field:"mtime",length:12},{field:"checksum",length:8},{field:"type",length:1},{field:"linkName",length:100},{field:"ustar",length:8},{field:"owner",length:32},{field:"group",length:32},{field:"majorNumber",length:8},{field:"minorNumber",length:8},{field:"filenamePrefix",length:155},{field:"padding",length:12}],window.header={},window.header.structure=e,window.header.format=t}(),function(){"use strict";functiont(t){this.written=0,e=(t||20)*r,this.out=i.clean(e),this.blocks=[],this.length=0}vare,n=window.header,i=window.utils,r=512;t.prototype.append=function(t,e,o,a){vars,h,d,u,c,f,l;if("string"==typeofe)e=i.stringToUint8(e);elseif(e.constructor!==Uint8Array.prototype.constructor)throw"Invalid input type. You gave me: "+e.constructor.toString().match(/function\s*([$A-Za-z_][0-9A-Za-z_]*)\s*\(/)[1];"function"==typeofo&&(a=o,o={}),o=o||{},d=o.mode||4095&parseInt("777",8),u=o.mtime||Math.floor(+newDate/1e3),c=o.uid||0,f=o.gid||0,s={fileName:t,fileMode:i.pad(d,7),uid:i.pad(c,7),gid:i.pad(f,7),fileSize:i.pad(e.length,11),mtime:i.pad(u,11),checksum:"",type:"0",ustar:"ustar ",owner:o.owner||"",group:o.group||""},h=0,Object.keys(s).forEach(function(t){vare,n,i=s[t];for(e=0,n=i.length;e<n;e+=1)h+=i.charCodeAt(e)}),s.checksum=i.pad(h,6)+"\0 ",l=n.format(s);varp=Math.ceil(l.length/r)*r,m=Math.ceil(e.length/r)*r;this.blocks.push({header:l,input:e,headerLength:p,inputLength:m})},t.prototype.save=function(){vart=[],e=[],n=0,i=Math.pow(2,20),o=[];returnthis.blocks.forEach(function(t){n+t.headerLength+t.inputLength>i&&(e.push({blocks:o,length:n}),o=[],n=0),o.push(t),n+=t.headerLength+t.inputLength}),e.push({blocks:o,length:n}),e.forEach(function(e){varn=newUint8Array(e.length),i=0;e.blocks.forEach(function(t){n.set(t.header,i),i+=t.headerLength,n.set(t.input,i),i+=t.inputLength}),t.push(n)}),t.push(newUint8Array(2*r)),newBlob(t,{type:"octet/stream"})},t.prototype.clear=function(){this.written=0,this.out=i.clean(e)},window.Tar=t}(),function(t){functione(t,n){if({}.hasOwnProperty.call(e.cache,t))returne.cache[t];vari=e.resolve(t);if(!i)thrownewError("Failed to resolve module "+t);varr={id:t,require:e,filename:t,exports:{},loaded:!1,parent:n,children:[]};n&&n.children.push(r);varo=t.slice(0,t.lastIndexOf("/")+1);returne.cache[t]=r.exports,i.call(r.exports,r,r.exports,o,t),r.loaded=!0,e.cache[t]=r.exports}e.modules={},e.cache={},e.resolve=function(t){return{}.hasOwnProperty.call(e.modules,t)?e.modules[t]:void0},e.define=function(t,n){e.modules[t]=n};varn=function(e){returne="/",{title:"browser",version:"v0.10.26",browser:!0,env:{},argv:[],nextTick:t.setImmediate||function(t){setTimeout(t,0)},cwd:function(){returne},chdir:function(t){e=t}}}();e.define("/gif.coffee",function(t,n,i,r){functiono(t,e){return{}.hasOwnProperty.call(t,e)}functiona(t,e){for(varn=0,i=e.length;n<i;++n)if(nine&&e[n]===t)return!0;return!1}functions(t,e){functionn(){this.constructor=t}for(variine)o(e,i)&&(t[i]=e[i]);returnn.prototype=e.prototype,t.prototype=newn,t.__super__=e.prototype,t}varh,d,u,c,f;u=e("events",t).EventEmitter,h=e("/browser.coffee",t),f=function(t){functione(t){vare,n;this.running=!1,this.options={},this.frames=[],this.freeWorkers=[],this.activeWorkers=[],this.setOptions(t);for(eind)n=d[e],null!=this.options[e]?this.options[e]:this.options[e]=n}returns(e,t),d={workerScript:"gif.worker.js",workers:2,repeat:0,background:"#fff",quality:10,width:null,height:null,transparent:null},c={delay:500,copy:!1},e.prototype.setOption=function(t,e){returnthis.options[t]=e,null==this._canvas||"width"!==t&&"height"!==t?void0:this._canvas[t]=e},e.prototype.setOptions=function(t){vare,n;returnfunction(i){for(eint)o(t,e)&&(n=t[e],i.push(this.setOption(e,n)));returni}.call(this,[])},e.prototype.addFrame=function(t,e){varn,i;null==e&&(e={}),n={},n.transparent=this.options.transparent;for(iinc)n[i]=e[i]||c[i];if(null!=this.options.width||this.setOption("width",t.width),null!=this.options.height||this.setOption("height",t.height),"undefined"!=typeofImageData&&null!=ImageData&&tinstanceofImageData)n.data=t.data;elseif("undefined"!=typeofCanvasRenderingContext2D&&null!=CanvasRenderingContext2D&&tinstanceofCanvasRenderingContext2D||"undefined"!=typeofWebGLRenderingContext&&null!=WebGLRenderingContext&&tinstanceofWebGLRenderingContext)e.copy?n.data=this.getContextData(t):n.context=t;else{if(null==t.childNodes)thrownewError("Invalid image");e.copy?n.data=this.getImageData(t):n.image=t}returnthis.frames.push(n)},e.prototype.render=function(){vart,e;if(this.running)thrownewError("Already running");if(null==this.options.width||null==this.options.height)thrownewError("Width and height must be set prior to rendering");this.running=!0,this.nextFrame=0,this.finishedFrames=0,this.imageParts=function(e){for(varn=function(){vart;t=[];for(vare=0;0<=this.frames.length?e<this.frames.length:e>this.frames.length;0<=this.frames.length?++e:--e)t.push(e);returnt}.apply(this,arguments),i=0,r=n.length;i<r;++i)t=n[i],e.push(null);returne}.call(this,[]),e=this.spawnWorkers();for(varn=function(){vart;t=[];for(varn=0;0<=e?n<e:n>e;0<=e?++n:--n)t.push(n);returnt}.apply(this,arguments),i=0,r=n.length;i<r;++i)t=n[i],this.renderNextFrame();returnthis.emit("start"),this.emit("progress",0)},e.prototype.abort=function(){for(vart;;){if(t=this.activeWorkers.shift(),!(null!=t))break;console.log("killing active worker"),t.terminate()}returnthis.running=!1,this.emit("abort")},e.prototype.spawnWorkers=function(){vart;returnt=Math.min(this.options.workers,this.frames.length),function(){vare;e=[];for(varn=this.freeWorkers.length;this.freeWorkers.length<=t?n<t:n>t;this.freeWorkers.length<=t?++n:--n)e.push(n);returne}.apply(this,arguments).forEach(function(t){returnfunction(e){varn;returnconsole.log("spawning worker "+e),n=newWorker(t.options.workerScript),n.onmessage=function(t){returnfunction(e){returnt.activeWorkers.splice(t.activeWorkers.indexOf(n),1),t.freeWorkers.push(n),t.frameFinished(e.data)}}(t),t.freeWorkers.push(n)}}(this)),t},e.prototype.frameFinished=function(t){returnconsole.log("frame "+t.index+" finished - "+this.activeWorkers.length+" active"),this.finishedFrames++,this.emit("progress",this.finishedFrames/this.frames.length),this.imageParts[t.index]=t,a(null,this.imageParts)?this.renderNextFrame():this.finishRendering()},e.prototype.finishRendering=function(){vart,e,n,i,r,o,a;r=0;for(vars=0,h=this.imageParts.length;s<h;++s)e=this.imageParts[s],r+=(e.data.length-1)*e.pageSize+e.cursor;r+=e.pageSize-e.cursor,console.log("rendering finished - filesize "+Math.round(r/1e3)+"kb"),t=newUint8Array(r),o=0;for(vard=0,u=this.imageParts.length;d<u;++d){e=this.imageParts[d];for(varc=0,f=e.data.length;c<f;++c)a=e.data[c],n=c,t.set(a,o),o+=n===e.data.length-1?e.cursor:e.pageSize}returni=newBlob([t],{type:"image/gif"}),this.emit("finished",i,t)},e.prototype.renderNextFrame=function(){vart,e,n;if(0===this.freeWorkers.length)thrownewError("No free workers");returnthis.nextFrame>=this.frames.length?void0:(t=this.frames[this.nextFrame++],n=this.freeWorkers.shift(),e=this.getTask(t),console.log("starting frame "+(e.index+1)+" of "+this.frames.length),this.activeWorkers.push(n),n.postMessage(e))},e.prototype.getContextData=function(t){returnt.getImageData(0,0,this.options.width,this.options.height).data},e.prototype.getImageData=function(t){vare;returnnull!=this._canvas||(this._canvas=document.createElement("canvas"),this._canvas.width=this.options.width,this._canvas.height=this.options.height),e=this._canvas.getContext("2d"),e.setFill=this.options.background,e.fillRect(0,0,this.options.width,this.options.height),e.drawImage(t,0,0),this.getContextData(e)},e.prototype.getTask=function(t){vare,n;if(e=this.frames.indexOf(t),n={index:e,last:e===this.frames.length-1,delay:t.delay,transparent:t.transparent,width:this.options.width,height:this.options.height,quality:this.options.quality,repeat:this.options.repeat,canTransfer:"chrome"===h.name},null!=t.data)n.data=t.data;elseif(null!=t.context)n.data=this.getContextData(t.context);else{if(null==t.image)thrownewError("Invalid frame");n.data=this.getImageData(t.image)}returnn},e}(u),t.exports=f}),e.define("/browser.coffee",function(t,e,n,i){varr,o,a,s,h;s=navigator.userAgent.toLowerCase(),a=navigator.platform.toLowerCase(),h=s.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/)||[null,"unknown",0],o="ie"===h[1]&&document.documentMode,r={name:"version"===h[1]?h[3]:h[1],version:o||parseFloat("opera"===h[1]&&h[4]?h[4]:h[2]),platform:{name:s.match(/ip(?:ad|od|hone)/)?"ios":(s.match(/(?:webos|android)/)||a.match(/mac|win|linux/)||["other"])[0]}},r[r.name]=!0,r[r.name+parseInt(r.version,10)]=!0,r.platform[r.platform.name]=!0,t.exports=r}),e.define("events",function(t,e,i,r){n.EventEmitter||(n.EventEmitter=function(){});varo=e.EventEmitter=n.EventEmitter,a="function"==typeofArray.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},s=10;o.prototype.setMaxListeners=function(t){this._events||(this._events={}),this._events.maxListeners=t},o.prototype.emit=function(t){if("error"===t&&(!this._events||!this._events.error||a(this._events.error)&&!this._events.error.length))throwarguments[1]instanceofError?arguments[1]:newError("Uncaught, unspecified 'error' event.");if(!this._events)return!1;vare=this._events[t];if(!e)return!1;if("function"!=typeofe){if(a(e)){for(varn=Array.prototype.slice.call(arguments,1),i=e.slice(),r=0,o=i.length;r<o;r++)i[r].apply(this,n);return!0}return!1}switch(arguments.length){case1:e.call(this);break;case2:e.call(this,arguments[1]);break;case3:e.call(this,arguments[1],arguments[2]);break;default:varn=Array.prototype.slice.call(arguments,1);e.apply(this,n)}return!0},o.prototype.addListener=function(t,e){if("function"!=typeofe)thrownewError("addListener only takes instances of Function");if(this._events||(this._events={}),this.emit("newListener",t,e),this._events[t])if(a(this._events[t])){if(!this._events[t].warned){varn;n=void0!==this._events.maxListeners?this._events.maxListeners:s,n&&n>0&&this._events[t].length>n&&(this._events[t].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[t].length),console.trace())}this._events[t].push(e)}elsethis._events[t]=[this._events[t],e];elsethis._events[t]=e;returnthis},o.prototype.on=o.prototype.addListener,o.prototype.once=function(t,e){varn=this;returnn.on(t,functioni(){n.removeListener(t,i),e.apply(this,arguments)}),this},o.prototype.removeListener=function(t,e){if("function"!=typeofe)thrownewError("removeListener only takes instances of Function");if(!this._events||!this._events[t])returnthis;varn=this._events[t];if(a(n)){vari=n.indexOf(e);if(i<0)returnthis;n.splice(i,1),0==n.length&&deletethis._events[t]}elsethis._events[t]===e&&deletethis._events[t];returnthis},o.prototype.removeAllListeners=function(t){returnt&&this._events&&this._events[t]&&(this._events[t]=null),this},o.prototype.listeners=function(t){returnthis._events||(this._events={}),this._events[t]||(this._events[t]=[]),a(this._events[t])||(this._events[t]=[this._events[t]]),this._events[t]}}),t.GIF=e("/gif.coffee")}.call(this,this),function(){"use strict";functiont(t){returnt&&t.Object===Object?t:null}functione(t){returnString("0000000"+t).slice(-7)}functionn(){functiont(){returnMath.floor(65536*(1+Math.random())).toString(16).substring(1)}returnt()+t()+"-"+t()+"-"+t()+"-"+t()+"-"+t()+t()+t()}functioni(t){vare={};this.settings=t,this.on=function(t,n){e[t]=n},this.emit=function(t){varn=e[t];n&&n.apply(null,Array.prototype.slice.call(arguments,1))},this.filename=t.name||n(),this.extension="",this.mimeType=""}functionr(t){i.call(this,t),this.extension=".tar",this.mimeType="application/x-tar",this.fileExtension="",this.tape=null,this.count=0}functiono(t){r.call(this,t),this.type="image/png",this.fileExtension=".png"}functiona(t){r.call(this,t),this.type="image/jpeg",this.fileExtension=".jpg",this.quality=t.quality/100||.8}functions(t){vare=document.createElement("canvas");"image/webp"!==e.toDataURL("image/webp").substr(5,10)&&console.log("WebP not supported - try another export format"),i.call(this,t),t.quality=t.quality/100||.8,this.extension=".webm",this.mimeType="video/webm",this.baseFilename=this.filename,this.frames=[],this.part=1}functionh(t){i.call(this,t),t.quality=t.quality/100||.8,this.encoder=newFFMpegServer.Video(t),this.encoder.on("process",function(){this.emit("process")}.bind(this)),this.encoder.on("finished",function(t,e){varn=this.callback;n&&(this.callback=void0,n(t,e))}.bind(this)),this.encoder.on("progress",function(t){this.settings.onProgress&&this.settings.onProgress(t)}.bind(this)),this.encoder.on("error",function(t){alert(JSON.stringify(t,null,2))}.bind(this))}functiond(t){i.call(this,t),this.framerate=this.settings.framerate,this.type="video/webm",this.extension=".webm",this.stream=null,this.mediaRecorder=null,this.chunks=[]}functionu(t){i.call(this,t),t.quality=31-(30*t.quality/100||10),t.workers=t.workers||4,this.extension=".gif",this.mimeType="image/gif",this.canvas=document.createElement("canvas"),this.ctx=this.canvas.getContext("2d"),this.sizeSet=!1,this.encoder=newGIF({workers:t.workers,quality:t.quality,workerScript:t.workersPath+"gif.worker.js"}),this.encoder.on("progress",function(t){this.settings.onProgress&&this.settings.onProgress(t)}.bind(this)),this.encoder.on("finished",function(t){vare=this.callback;e&&(this.callback=void0,e(t))}.bind(this))}functionc(t){functione(){functiont(){returnthis._hooked||(this._hooked=!0,this._hookedTime=this.currentTime||0,this.pause(),et.push(this)),this._hookedTime+S.startTime}b("Capturer start"),A=window.Date.now(),L=A+S.startTime,D=window.performance.now(),E=D+S.startTime,window.Date.prototype.getTime=function(){returnL},window.Date.now=function(){returnL},window.setTimeout=function(t,e){varn={callback:t,time:e,triggerTime:L+e};returnB.push(n),b("Timeout set to "+n.time),n},window.clearTimeout=function(t){for(vare=0;e<B.length;e++)B[e]!=t||(B.splice(e,1),b("Timeout cleared"))},window.setInterval=function(t,e){varn={callback:t,time:e,triggerTime:L+e};returnj.push(n),b("Interval set to "+n.time),n},window.clearInterval=function(t){returnb("clear Interval"),null},window.requestAnimationFrame=function(t){U.push(t)},window.performance.now=function(){returnE};try{Object.defineProperty(HTMLVideoElement.prototype,"currentTime",{get:t}),Object.defineProperty(HTMLAudioElement.prototype,"currentTime",{get:t})}catch(t){b(t)}}functionn(){e(),I.start(),M=!0}functioni(){M=!1,I.stop(),f()}functionr(t,e){Z(t,0,e)}functionc(){r(v)}functionf(){b("Capturer stop"),window.setTimeout=Z,window.setInterval=J,window.clearTimeout=Y,window.requestAnimationFrame=$,window.Date.prototype.getTime=tt,window.Date.now=Q,window.performance.now=X}functionl(){vart=R/S.framerate;(S.frameLimit&&R>=S.frameLimit||S.timeLimit&&t>=S.timeLimit)&&(i(),y());vare=newDate(null);e.setSeconds(t),S.motionBlurFrames>2?P.textContent="CCapture "+S.format+" | "+R+" frames ("+O+" inter) | "+e.toISOString().substr(11,8):P.textContent="CCapture "+S.format+" | "+R+" frames | "+e.toISOString().substr(11,8)}functionp(t){N.width===t.width&&N.height===t.height||(N.width=t.width,N.height=t.height,q=newUint16Array(N.height*N.width*4),V.fillStyle="#0",V.fillRect(0,0,N.width,N.height))}functionm(t){V.drawImage(t,0,0),z=V.getImageData(0,0,N.width,N.height);for(vare=0;e<q.length;e+=4)q[e]+=z.data[e],q[e+1]+=z.data[e+1],q[e+2]+=z.data[e+2];O++}functiong(){for(vart=z.data,e=0;e<q.length;e+=4)t[e]=2*q[e]/S.motionBlurFrames,t[e+1]=2*q[e+1]/S.motionBlurFrames,t[e+2]=2*q[e+2]/S.motionBlurFrames;V.putImageData(z,0,0),I.add(N),R++,O=0,b("Full MB Frame! "+R+""+L);for(vare=0;e<q.length;e+=4)q[e]=0,q[e+1]=0,q[e+2]=0;gc()}functionw(t){M&&(S.motionBlurFrames>2?(p(t),m(t),O>=.5*S.motionBlurFrames?g():c()):(I.add(t),R++,b("Full Frame! "+R)))}functionv(){vart=1e3/S.framerate,e=(R+O/S.motionBlurFrames)*t;L=A+e,E=D+e,et.forEach(function(t){t._hookedTime=e/1e3}),l(),b("Frame: "+R+""+O);for(varn=0;n<B.length;n++)L>=B[n].triggerTime&&(r(B[n].callback),B.splice(n,1));for(varn=0;n<j.length;n++)L>=j[n].triggerTime&&(r(j[n].callback),j[n].triggerTime+=j[n].time);U.forEach(function(t){r(t,L-k)}),U=[]}functiony(t){t||(t=function(t){returndownload(t,I.filename+I.extension,I.mimeType),!1}),I.save(t)}functionb(t){_&&console.log(t)}functionx(t,e){W[t]=e}functionT(t){vare=W[t];e&&e.apply(null,Array.prototype.slice.call(arguments,1))}functionC(t){T("progress",t)}var_,F,L,A,E,D,c,I,S=t||{},B=(newDate,[]),j=[],R=0,O=0,U=[],M=!1,W={};S.framerate=S.framerate||60,S.motionBlurFrames=2*(S.motionBlurFrames||1),_=S.verbose||!1,F=S.display||!1,S.step=1e3/S.framerate,S.timeLimit=S.timeLimit||0,S.frameLimit=S.frameLimit||0,S.startTime=S.startTime||0;varP=document.createElement("div");P.style.position="absolute",P.style.left=P.style.top=0,P.style.backgroundColor="black",P.style.fontFamily="monospace",P.style.fontSize="11px",P.style.padding="5px",P.style.color="red",P.style.zIndex=1e5,S.display&&document.body.appendChild(P);varq,z,N=document.createElement("canvas"),V=N.getContext("2d");b("Step is set to "+S.step+"ms");varH={gif:u,webm:s,ffmpegserver:h,png:o,jpg:a,"webm-mediarecorder":d},G=H[S.format];if(!G)throw"Error: Incorrect or missing format: Valid formats are "+Object.keys(H).join(", ");if(I=newG(S),I.step=c,I.on("process",v),I.on("progress",C),"performance"inwindow==0&&(window.performance={}),Date.now=Date.now||function(){return(newDate).getTime()},"now"inwindow.performance==0){varK=Date.now();performance.timing&&performance.timing.navigationStart&&(K=performance.timing.navigationStart),window.performance.now=function(){returnDate.now()-K}}varZ=window.setTimeout,J=window.setInterval,Y=window.clearTimeout,$=window.requestAnimationFrame,Q=window.Date.now,X=window.performance.now,tt=window.Date.prototype.getTime,et=[];return{start:n,capture:w,stop:i,save:y,on:x}}varf={function:!0,object:!0},l=(parseFloat,parseInt,f[typeofexports]&&exports&&!exports.nodeType?exports:void0),p=f[typeofmodule]&&module&&!module.nodeType?module:void0,m=p&&p.exports===l?l:void0,g=t(l&&p&&"object"==typeofglobal&&global),w=t(f[typeofself]&&self),v=t(f[typeofwindow]&&window),y=t(f[typeofthis]&&this),b=g||v!==(y&&y.window)&&v||w||y||Function("return this")();"gc"inwindow||(window.gc=function(){}),HTMLCanvasElement.prototype.toBlob||Object.defineProperty(HTMLCanvasElement.prototype,"toBlob",{value:function(t,e,n){for(vari=atob(this.toDataURL(e,n).split(",")[1]),r=i.length,o=newUint8Array(r),a=0;a<r;a++)o[a]=i.charCodeAt(a);t(newBlob([o],{type:e||"image/png"}))}}),function(){if("performance"inwindow==0&&(window.performance={}),Date.now=Date.now||function(){return(newDate).getTime()},"now"inwindow.performance==0){vart=Date.now();performance.timing&&performance.timing.navigationStart&&(t=performance.timing.navigationStart),window.performance.now=function(){returnDate.now()-t}}}();vark=window.Date.now();i.prototype.start=function(){},i.prototype.stop=function(){},i.prototype.add=function(){},i.prototype.save=function(){},i.prototype.dispose=function(){},i.prototype.safeToProceed=function(){return!0},i.prototype.step=function(){console.log("Step not set!")},r.prototype=Object.create(i.prototype),r.prototype.start=function(){this.dispose()},r.prototype.add=function(t){varn=newFileReader;n.onload=function(){this.tape.append(e(this.count)+this.fileExtension,newUint8Array(n.result)),this.count++,this.step()}.bind(this),n.readAsArrayBuffer(t)},r.prototype.save=function(t){t(this.tape.save())},r.prototype.dispose=function(){this.tape=newTar,this.count=0},o.prototype=Object.create(r.prototype),o.prototype.add=function(t){t.toBlob(function(t){r.prototype.add.call(this,t)}.bind(this),this.type)},a.prototype=Object.create(r.prototype),a.prototype.add=function(t){t.toBlob(function(t){r.prototype.add.call(this,t)}.bind(this),this.type,this.quality)},s.prototype=Object.create(i.prototype),s.prototype.start=function(t){this.dispose()},s.prototype.add=function(t){this.frames.push(t.toDataURL("image/webp",this.quality)),this.settings.autoSaveTime>0&&this.frames.length/this.settings.framerate>=this.settings.autoSaveTime?this.save(function(t){this.filename=this.baseFilename+"-part-"+e(this.part),download(t,this.filename+this.extension,this.mimeType),this.dispose(),this.part++,this.filename=this.baseFilename+"-part-"+e(this.part),this.step()}.bind(this)):this.step()},s.prototype.save=function(t){if(this.frames.length){vare=Whammy.fromImageArray(this.frames,this.settings.framerate),n=newBlob([e],{type:"octet/stream"});t(n)}},s.prototype.dispose=function(t){this.frames=[]},h.prototype=Object.create(i.prototype),h.prototype.start=function(){this.encoder.start(this.settings)},h.prototype.add=function(t){this.encoder.add(t)},h.prototype.save=function(t){this.callback=t,this.encoder.end()},h.prototype.safeToProceed=function(){returnthis.encoder.safeToProceed()},d.prototype=Object.create(i.prototype),d.prototype.add=function(t){this.stream||(this.stream=t.captureStream(this.framerate),this.mediaRecorder=newMediaRecorder(this.stream),this.mediaRecorder.start(),this.mediaRecorder.ondataavailable=function(t){this.chunks.push(t.data)}.bind(this)),this.step()},d.prototype.save=function(t){this.mediaRecorder.onstop=function(e){varn=newBlob(this.chunks,{type:"video/webm"});this.chunks=[],t(n)}.bind(this),this.mediaRecorder.stop()},u.prototype=Object.create(i.prototype),u.prototype.add=function(t){this.sizeSet||(this.encoder.setOption("width",t.width),this.encoder.setOption("height",t.height),this.sizeSet=!0),this.canvas.width=t.width,this.canvas.height=t.height,this.ctx.drawImage(t,0,0),this.encoder.addFrame(this.ctx,{copy:!0,delay:this.settings.step}),this.step()},u.prototype.save=function(t){this.callback=t,this.encoder.render()},(v||w||{}).CCapture=c,"function"==typeofdefine&&"object"==typeofdefine.amd&&define.amd?define(function(){returnc}):l&&p?(m&&((p.exports=c).CCapture=c),l.CCapture=c):b.CCapture=c}();
<li><aid="exportFOLD"href="#">Save Simulation as FOLD...</a></li>
<li><aid="exportSTL"href="#">Save Simulation as STL...</a></li>
<li><aid="exportOBJ"href="#">Save Simulation as OBJ...</a></li>
...
...
@@ -909,6 +913,7 @@
<ul>
<li>All rendering and 3D interaction done with <atarget="_blank"href="https://threejs.org/">three.js</a></li>
<li><ahref="https://www.npmjs.com/package/path-data-polyfill"target="_blank">path-data-polyfill</a> helps with SVG parsing</li>
<li><ahref="https://github.com/edemaine/fold"target="_blank">FOLD</a> is used as the internal data structure, and methods from the FOLD api are used for SVG parsing</li>
<li>Arbitrary polygonal faces of imported geometry are triangulated using the <atarget="_blank"href="https://github.com/mapbox/earcut">Earcut Library</a></li>
<li><atarget="_blank"href="https://jquery.com/">jQuery</a>, <atarget="_blank"href="http://getbootstrap.com/">Bootstrap</a>, and the
<atarget="_blank"href="http://designmodo.github.io/Flat-UI/">Flat UI theme</a> used to build the GUI</li>
...
...
@@ -1046,7 +1051,7 @@
Filename: <inputid="stlFilename"value=""placeholder=""class="bigInput text form-control"type="text"> .stl<br/><br/>