diff --git a/amd/build/jspdf.min.js b/amd/build/jspdf.min.js
index c4477db707e27330979bd696881726939f36cb26..85706da1f9c4551beb8e4fe8fc6da72365561ebd 100644
--- a/amd/build/jspdf.min.js
+++ b/amd/build/jspdf.min.js
@@ -1,90 +1,395 @@
-function _typeof2(obj){return _typeof2="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(obj){return typeof obj}:function(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj},_typeof2(obj)}define("mod_pdfannotator/jspdf",(function(){var API,getCharWidthsArray,getArraySum,getStringUnitWidth,splitLongWord,splitParagraphIntoLines,_typeof="function"==typeof Symbol&&"symbol"===_typeof2(Symbol.iterator)?function(obj){return _typeof2(obj)}:function(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":_typeof2(obj)},jsPDF=function(global){var pageFormats={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]};function PubSub(context){var topics={};this.subscribe=function(topic,callback,once){if("function"!=typeof callback)return!1;topics.hasOwnProperty(topic)||(topics[topic]={});var id=Math.random().toString(35);return topics[topic][id]=[callback,!!once],id},this.unsubscribe=function(token){for(var topic in topics)if(topics[topic][token])return delete topics[topic][token],!0;return!1},this.publish=function(topic){if(topics.hasOwnProperty(topic)){var args=Array.prototype.slice.call(arguments,1),idr=[];for(var id in topics[topic]){var sub=topics[topic][id];try{sub[0].apply(context,args)}catch(ex){global.console&&console.error("jsPDF PubSub Error",ex.message,ex)}sub[1]&&idr.push(id)}idr.length&&idr.forEach(this.unsubscribe)}}}function jsPDF(orientation,unit,format,compressPdf){var options={};"object"===(void 0===orientation?"undefined":_typeof(orientation))&&(orientation=(options=orientation).orientation,unit=options.unit||unit,format=options.format||format,compressPdf=options.compress||options.compressPdf||compressPdf),unit=unit||"mm",format=format||"a4",orientation=(""+(orientation||"P")).toLowerCase();(""+format).toLowerCase();var activeFontKey,k,tmp,currentPage,pageWidth,pageHeight,pageMode,zoomMode,layoutMode,creationDate,fn,compress=!!compressPdf&&"function"==typeof Uint8Array,textColor=options.textColor||"0 g",drawColor=options.drawColor||"0 G",activeFontSize=options.fontSize||16,activeCharSpace=options.charSpace||0,R2L=options.R2L||!1,lineHeightProportion=options.lineHeight||1.15,lineWidth=options.lineWidth||.200025,fileId="00000000000000000000000000000000",objectNumber=2,outToPages=!1,offsets=[],fonts={},fontmap={},page=0,pages=[],pagesContext=[],pagedim=[],content=[],additionalObjects=[],lineCapID=0,lineJoinID=0,content_length=0,documentProperties={title:"",subject:"",author:"",keywords:"",creator:""},API={},events=new PubSub(API),hotfixes=options.hotfixes||[],generateColorString=function(options){var color,ch1=options.ch1,ch2=options.ch2,ch3=options.ch3,ch4=options.ch4,letterArray=(options.precision,"draw"===options.pdfColorType?["G","RG","K"]:["g","rg","k"]);if("string"==typeof ch1&&"#"!==ch1.charAt(0)){var rgbColor=new RGBColor(ch1);rgbColor.ok&&(ch1=rgbColor.toHex())}if("string"==typeof ch1&&/^#[0-9A-Fa-f]{3}$/.test(ch1)&&(ch1="#"+ch1[1]+ch1[1]+ch1[2]+ch1[2]+ch1[3]+ch1[3]),"string"==typeof ch1&&/^#[0-9A-Fa-f]{6}$/.test(ch1)){var hex=parseInt(ch1.substr(1),16);ch1=hex>>16&255,ch2=hex>>8&255,ch3=255&hex}if(void 0===ch2||void 0===ch4&&ch1===ch2&&ch2===ch3)if("string"==typeof ch1)color=ch1+" "+letterArray[0];else if(2===options.precision)color=f2(ch1/255)+" "+letterArray[0];else color=f3(ch1/255)+" "+letterArray[0];else if(void 0===ch4||"object"===(void 0===ch4?"undefined":_typeof(ch4))){if("string"==typeof ch1)color=[ch1,ch2,ch3,letterArray[1]].join(" ");else if(2===options.precision)color=[f2(ch1/255),f2(ch2/255),f2(ch3/255),letterArray[1]].join(" ");else color=[f3(ch1/255),f3(ch2/255),f3(ch3/255),letterArray[1]].join(" ");ch4&&0===ch4.a&&(color=["255","255","255",letterArray[1]].join(" "))}else if("string"==typeof ch1)color=[ch1,ch2,ch3,ch4,letterArray[2]].join(" ");else if(2===options.precision)color=[f2(ch1),f2(ch2),f2(ch3),f2(ch4),letterArray[2]].join(" ");else color=[f3(ch1),f3(ch2),f3(ch3),f3(ch4),letterArray[2]].join(" ");return color},convertDateToPDFDate=function(parmDate){var padd2=function(number){return("0"+parseInt(number)).slice(-2)},tzoffset=parmDate.getTimezoneOffset(),tzsign=tzoffset<0?"+":"-",tzhour=Math.floor(Math.abs(tzoffset/60)),tzmin=Math.abs(tzoffset%60),timeZoneString=[tzsign,padd2(tzhour),"'",padd2(tzmin),"'"].join("");return["D:",parmDate.getFullYear(),padd2(parmDate.getMonth()+1),padd2(parmDate.getDate()),padd2(parmDate.getHours()),padd2(parmDate.getMinutes()),padd2(parmDate.getSeconds()),timeZoneString].join("")},setCreationDate=function(date){var tmpCreationDateString;return void 0===(void 0===date?"undefined":_typeof(date))&&(date=new Date),tmpCreationDateString="object"===(void 0===date?"undefined":_typeof(date))&&"[object Date]"===Object.prototype.toString.call(date)?convertDateToPDFDate(date):/^D:(20[0-2][0-9]|203[0-7]|19[7-9][0-9])(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])(0[0-9]|1[0-9]|2[0-3])(0[0-9]|[1-5][0-9])(0[0-9]|[1-5][0-9])(\+0[0-9]|\+1[0-4]|\-0[0-9]|\-1[0-1])\'(0[0-9]|[1-5][0-9])\'?$/.test(date)?date:convertDateToPDFDate(new Date),creationDate=tmpCreationDateString},getCreationDate=function(type){var parmPDFDate,year,month,date,hour,minutes,seconds,result=creationDate;return"jsDate"===type&&(parmPDFDate=creationDate,year=parseInt(parmPDFDate.substr(2,4),10),month=parseInt(parmPDFDate.substr(6,2),10)-1,date=parseInt(parmPDFDate.substr(8,2),10),hour=parseInt(parmPDFDate.substr(10,2),10),minutes=parseInt(parmPDFDate.substr(12,2),10),seconds=parseInt(parmPDFDate.substr(14,2),10),parseInt(parmPDFDate.substr(16,2),10),parseInt(parmPDFDate.substr(20,2),10),result=new Date(year,month,date,hour,minutes,seconds,0)),result},setFileId=function(value){return value=value||"12345678901234567890123456789012".split("").map((function(){return"ABCDEF0123456789".charAt(Math.floor(16*Math.random()))})).join(""),fileId=value},f2=function(number){return number.toFixed(2)},f3=function(number){return number.toFixed(3)},out=function(string){string="string"==typeof string?string:string.toString(),outToPages?pages[currentPage].push(string):(content_length+=string.length+1,content.push(string))},newObject=function(){return objectNumber++,offsets[objectNumber]=content_length,out(objectNumber+" 0 obj"),objectNumber},putStream=function(str){out("stream"),out(str),out("endstream")},putResourceDictionary=function(){for(var fontKey in out("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]"),out("/Font <<"),fonts)fonts.hasOwnProperty(fontKey)&&out("/"+fontKey+" "+fonts[fontKey].objectNumber+" 0 R");out(">>"),out("/XObject <<"),events.publish("putXobjectDict"),out(">>")},putResources=function(){!function(){for(var fontKey in fonts)fonts.hasOwnProperty(fontKey)&&(font=fonts[fontKey],events.publish("putFont",{font:font,out:out,newObject:newObject}),!0!==font.isAlreadyPutted&&(font.objectNumber=newObject(),out("<<"),out("/Type /Font"),out("/BaseFont /"+font.postScriptName),out("/Subtype /Type1"),"string"==typeof font.encoding&&out("/Encoding /"+font.encoding),out("/FirstChar 32"),out("/LastChar 255"),out(">>"),out("endobj")));var font}(),events.publish("putResources"),offsets[2]=content_length,out("2 0 obj"),out("<<"),putResourceDictionary(),out(">>"),out("endobj"),events.publish("postPutResources")},addToFontDictionary=function(fontKey,fontName,fontStyle){fontmap.hasOwnProperty(fontName)||(fontmap[fontName]={}),fontmap[fontName][fontStyle]=fontKey},addFont=function(postScriptName,fontName,fontStyle,encoding){var fontKey="F"+(Object.keys(fonts).length+1).toString(10),font=fonts[fontKey]={id:fontKey,postScriptName:postScriptName,fontName:fontName,fontStyle:fontStyle,encoding:encoding,metadata:{}};return addToFontDictionary(fontKey,fontName,fontStyle),events.publish("addFont",font),fontKey},pdfEscape=function(text,flags){return function(text,flags){var i,l,sourceEncoding,encodingBlock,outputEncoding,newtext,isUnicode,ch,bch;if(sourceEncoding=(flags=flags||{}).sourceEncoding||"Unicode",outputEncoding=flags.outputEncoding,(flags.autoencode||outputEncoding)&&fonts[activeFontKey].metadata&&fonts[activeFontKey].metadata[sourceEncoding]&&fonts[activeFontKey].metadata[sourceEncoding].encoding&&(encodingBlock=fonts[activeFontKey].metadata[sourceEncoding].encoding,!outputEncoding&&fonts[activeFontKey].encoding&&(outputEncoding=fonts[activeFontKey].encoding),!outputEncoding&&encodingBlock.codePages&&(outputEncoding=encodingBlock.codePages[0]),"string"==typeof outputEncoding&&(outputEncoding=encodingBlock[outputEncoding]),outputEncoding)){for(isUnicode=!1,newtext=[],i=0,l=text.length;i<l;i++)(ch=outputEncoding[text.charCodeAt(i)])?newtext.push(String.fromCharCode(ch)):newtext.push(text[i]),newtext[i].charCodeAt(0)>>8&&(isUnicode=!0);text=newtext.join("")}for(i=text.length;void 0===isUnicode&&0!==i;)text.charCodeAt(i-1)>>8&&(isUnicode=!0),i--;if(!isUnicode)return text;for(newtext=flags.noBOM?[]:[254,255],i=0,l=text.length;i<l;i++){if((bch=(ch=text.charCodeAt(i))>>8)>>8)throw new Error("Character at position "+i+" of string '"+text+"' exceeds 16bits. Cannot be encoded into UCS-2 BE");newtext.push(bch),newtext.push(ch-(bch<<8))}return String.fromCharCode.apply(void 0,newtext)}(text,flags).replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")},beginPage=function(width,height){var orientation="string"==typeof height&&height.toLowerCase();if("string"==typeof width){var format=width.toLowerCase();pageFormats.hasOwnProperty(format)&&(width=pageFormats[format][0]/k,height=pageFormats[format][1]/k)}if(Array.isArray(width)&&(height=width[1],width=width[0]),orientation){switch(orientation.substr(0,1)){case"l":height>width&&(orientation="s");break;case"p":width>height&&(orientation="s")}"s"===orientation&&(tmp=width,width=height,height=tmp)}outToPages=!0,pages[++page]=[],pagedim[page]={width:Number(width)||pageWidth,height:Number(height)||pageHeight},pagesContext[page]={},_setPage(page)},_addPage=function(){beginPage.apply(this,arguments),out(f2(lineWidth*k)+" w"),out(drawColor),0!==lineCapID&&out(lineCapID+" J"),0!==lineJoinID&&out(lineJoinID+" j"),events.publish("addPage",{pageNumber:page})},_deletePage=function(n){n>0&&n<=page&&(pages.splice(n,1),pagedim.splice(n,1),page--,currentPage>page&&(currentPage=page),this.setPage(currentPage))},_setPage=function(n){n>0&&n<=page&&(currentPage=n,pageWidth=pagedim[n].width,pageHeight=pagedim[n].height)},_getFont=function(fontName,fontStyle,options){var fontNameLowerCase,key=void 0;return options=options||{},fontName=void 0!==fontName?fontName:fonts[activeFontKey].fontName,fontStyle=void 0!==fontStyle?fontStyle:fonts[activeFontKey].fontStyle,fontNameLowerCase=fontName.toLowerCase(),void 0!==fontmap[fontNameLowerCase]&&void 0!==fontmap[fontNameLowerCase][fontStyle]?key=fontmap[fontNameLowerCase][fontStyle]:void 0!==fontmap[fontName]&&void 0!==fontmap[fontName][fontStyle]?key=fontmap[fontName][fontStyle]:!1===options.disableWarning&&console.warn("Unable to look up font label for font '"+fontName+"', '"+fontStyle+"'. Refer to getFontList() for available fonts."),key||options.noFallback||null==(key=fontmap.times[fontStyle])&&(key=fontmap.times.normal),key},buildDocument=function(){outToPages=!1,objectNumber=2,content_length=0,content=[],offsets=[],additionalObjects=[],events.publish("buildDocument"),out("%PDF-1.3"),out("%ºß¬à"),function(){var n,p,arr,i,deflater,adler32,adler32cs,wPt,hPt,pageObjectNumbers=[];for(adler32cs=global.adler32cs||jsPDF.API.adler32cs,compress&&void 0===adler32cs&&(compress=!1),n=1;n<=page;n++){if(pageObjectNumbers.push(newObject()),wPt=(pageWidth=pagedim[n].width)*k,hPt=(pageHeight=pagedim[n].height)*k,out("<</Type /Page"),out("/Parent 1 0 R"),out("/Resources 2 0 R"),out("/MediaBox [0 0 "+f2(wPt)+" "+f2(hPt)+"]"),events.publish("putPage",{pageNumber:n,page:pages[n]}),out("/Contents "+(objectNumber+1)+" 0 R"),out(">>"),out("endobj"),p=pages[n].join("\n"),newObject(),compress){for(arr=[],i=p.length;i--;)arr[i]=p.charCodeAt(i);adler32=adler32cs.from(p),(deflater=new Deflater(6)).append(new Uint8Array(arr)),p=deflater.flush(),(arr=new Uint8Array(p.length+6)).set(new Uint8Array([120,156])),arr.set(p,2),arr.set(new Uint8Array([255&adler32,adler32>>8&255,adler32>>16&255,adler32>>24&255]),p.length+2),p=String.fromCharCode.apply(null,arr),out("<</Length "+p.length+" /Filter [/FlateDecode]>>")}else out("<</Length "+p.length+">>");putStream(p),out("endobj")}offsets[1]=content_length,out("1 0 obj"),out("<</Type /Pages");var kids="/Kids [";for(i=0;i<page;i++)kids+=pageObjectNumbers[i]+" 0 R ";out(kids+"]"),out("/Count "+page),out(">>"),out("endobj"),events.publish("postPutPages")}(),function(){events.publish("putAdditionalObjects");for(var i=0;i<additionalObjects.length;i++){var obj=additionalObjects[i];offsets[obj.objId]=content_length,out(obj.objId+" 0 obj"),out(obj.content),out("endobj")}objectNumber+=additionalObjects.length,events.publish("postPutAdditionalObjects")}(),putResources(),newObject(),out("<<"),function(){for(var key in out("/Producer (jsPDF "+jsPDF.version+")"),documentProperties)documentProperties.hasOwnProperty(key)&&documentProperties[key]&&out("/"+key.substr(0,1).toUpperCase()+key.substr(1)+" ("+pdfEscape(documentProperties[key])+")");out("/CreationDate ("+creationDate+")")}(),out(">>"),out("endobj"),newObject(),out("<<"),function(){switch(out("/Type /Catalog"),out("/Pages 1 0 R"),zoomMode||(zoomMode="fullwidth"),zoomMode){case"fullwidth":out("/OpenAction [3 0 R /FitH null]");break;case"fullheight":out("/OpenAction [3 0 R /FitV null]");break;case"fullpage":out("/OpenAction [3 0 R /Fit]");break;case"original":out("/OpenAction [3 0 R /XYZ null null 1]");break;default:var pcn=""+zoomMode;"%"===pcn.substr(pcn.length-1)&&(zoomMode=parseInt(zoomMode)/100),"number"==typeof zoomMode&&out("/OpenAction [3 0 R /XYZ null null "+f2(zoomMode)+"]")}switch(layoutMode||(layoutMode="continuous"),layoutMode){case"continuous":out("/PageLayout /OneColumn");break;case"single":out("/PageLayout /SinglePage");break;case"two":case"twoleft":out("/PageLayout /TwoColumnLeft");break;case"tworight":out("/PageLayout /TwoColumnRight")}pageMode&&out("/PageMode /"+pageMode),events.publish("putCatalog")}(),out(">>"),out("endobj");var i,o=content_length,p="0000000000";for(out("xref"),out("0 "+(objectNumber+1)),out(p+" 65535 f "),i=1;i<=objectNumber;i++){var offset=offsets[i];out("function"==typeof offset?(p+offsets[i]()).slice(-10)+" 00000 n ":(p+offsets[i]).slice(-10)+" 00000 n ")}return out("trailer"),out("<<"),out("/Size "+(objectNumber+1)),out("/Root "+objectNumber+" 0 R"),out("/Info "+(objectNumber-1)+" 0 R"),out("/ID [ <"+fileId+"> <"+fileId+"> ]"),out(">>"),out("startxref"),out(""+o),out("%%EOF"),outToPages=!0,content.join("\n")},getStyle=function(style){var op="S";return"F"===style?op="f":"FD"===style||"DF"===style?op="B":"f"!==style&&"f*"!==style&&"B"!==style&&"B*"!==style||(op=style),op},getArrayBuffer=function(){for(var data=buildDocument(),len=data.length,ab=new ArrayBuffer(len),u8=new Uint8Array(ab);len--;)u8[len]=data.charCodeAt(len);return ab},getBlob=function(){return new Blob([getArrayBuffer()],{type:"application/pdf"})},_output=(fn=function(type,options){var datauri="dataur"===(""+type).substr(0,6)?"data:application/pdf;base64,"+btoa(buildDocument()):0;switch(type){case void 0:return buildDocument();case"save":if("object"===("undefined"==typeof navigator?"undefined":_typeof(navigator))&&navigator.getUserMedia&&(void 0===global.URL||void 0===global.URL.createObjectURL))return API.output("dataurlnewwindow");saveAs(getBlob(),options),"function"==typeof saveAs.unload&&global.setTimeout&&setTimeout(saveAs.unload,911);break;case"arraybuffer":return getArrayBuffer();case"blob":return getBlob();case"bloburi":case"bloburl":return global.URL&&global.URL.createObjectURL(getBlob())||void 0;case"datauristring":case"dataurlstring":return datauri;case"dataurlnewwindow":var nW=global.open(datauri);if(nW||"undefined"==typeof safari)return nW;case"datauri":case"dataurl":return global.document.location.href=datauri;default:throw new Error('Output type "'+type+'" is not supported.')}},fn.foo=function(){try{return fn.apply(this,arguments)}catch(e){var stack=e.stack||"";~stack.indexOf(" at ")&&(stack=stack.split(" at ")[1]);var m="Error in function "+stack.split("\n")[0].split("<")[0]+": "+e.message;if(!global.console)throw new Error(m);global.console.error(m,e),global.alert&&alert(m)}},fn.foo.bar=fn,fn.foo),hasHotfix=function(hotfixName){return!0===Array.isArray(hotfixes)&&hotfixes.indexOf(hotfixName)>-1};switch(unit){case"pt":k=1;break;case"mm":k=72/25.4;break;case"cm":k=72/2.54;break;case"in":k=72;break;case"px":k=1==hasHotfix("px_scaling")?.75:96/72;break;case"pc":case"em":k=12;break;case"ex":k=6;break;default:throw"Invalid unit: "+unit}for(var plugin in setCreationDate(),setFileId(),API.internal={pdfEscape:pdfEscape,getStyle:getStyle,getFont:function(){return fonts[_getFont.apply(API,arguments)]},getFontSize:function(){return activeFontSize},getCharSpace:function(){return activeCharSpace},getTextColor:function(){var colorEncoded=textColor.split(" ");if(2===colorEncoded.length&&"g"===colorEncoded[1]){var floatVal=parseFloat(colorEncoded[0]);colorEncoded=[floatVal,floatVal,floatVal,"r"]}for(var colorAsHex="#",i=0;i<3;i++)colorAsHex+=("0"+Math.floor(255*parseFloat(colorEncoded[i])).toString(16)).slice(-2);return colorAsHex},getLineHeight:function(){return activeFontSize*lineHeightProportion},write:function(string1){out(1===arguments.length?string1:Array.prototype.join.call(arguments," "))},getCoordinateString:function(value){return f2(value*k)},getVerticalCoordinateString:function(value){return f2((pageHeight-value)*k)},collections:{},newObject:newObject,newAdditionalObject:function(){var objId=2*pages.length+1,obj={objId:objId+=additionalObjects.length,content:""};return additionalObjects.push(obj),obj},newObjectDeferred:function(){return objectNumber++,offsets[objectNumber]=function(){return content_length},objectNumber},newObjectDeferredBegin:function(oid){offsets[oid]=content_length},putStream:putStream,events:events,scaleFactor:k,pageSize:{getWidth:function(){return pageWidth},getHeight:function(){return pageHeight}},output:function(type,options){return _output(type,options)},getNumberOfPages:function(){return pages.length-1},pages:pages,out:out,f2:f2,getPageInfo:function(pageNumberOneBased){return{objId:2*(pageNumberOneBased-1)+3,pageNumber:pageNumberOneBased,pageContext:pagesContext[pageNumberOneBased]}},getCurrentPageInfo:function(){return{objId:2*(currentPage-1)+3,pageNumber:currentPage,pageContext:pagesContext[currentPage]}},getPDFVersion:function(){return"1.3"},hasHotfix:hasHotfix},API.addPage=function(){return _addPage.apply(this,arguments),this},API.setPage=function(){return _setPage.apply(this,arguments),this},API.insertPage=function(beforePage){return this.addPage(),this.movePage(currentPage,beforePage),this},API.movePage=function(targetPage,beforePage){if(targetPage>beforePage){for(var tmpPages=pages[targetPage],tmpPagedim=pagedim[targetPage],tmpPagesContext=pagesContext[targetPage],i=targetPage;i>beforePage;i--)pages[i]=pages[i-1],pagedim[i]=pagedim[i-1],pagesContext[i]=pagesContext[i-1];pages[beforePage]=tmpPages,pagedim[beforePage]=tmpPagedim,pagesContext[beforePage]=tmpPagesContext,this.setPage(beforePage)}else if(targetPage<beforePage){for(tmpPages=pages[targetPage],tmpPagedim=pagedim[targetPage],tmpPagesContext=pagesContext[targetPage],i=targetPage;i<beforePage;i++)pages[i]=pages[i+1],pagedim[i]=pagedim[i+1],pagesContext[i]=pagesContext[i+1];pages[beforePage]=tmpPages,pagedim[beforePage]=tmpPagedim,pagesContext[beforePage]=tmpPagesContext,this.setPage(beforePage)}return this},API.deletePage=function(){return _deletePage.apply(this,arguments),this},API.setCreationDate=function(date){return setCreationDate(date),this},API.getCreationDate=function(type){return getCreationDate(type)},API.setFileId=function(value){return setFileId(value),this},API.getFileId=function(){return fileId},API.setDisplayMode=function(zoom,layout,pmode){if(zoomMode=zoom,layoutMode=layout,pageMode=pmode,-1==[void 0,null,"UseNone","UseOutlines","UseThumbs","FullScreen"].indexOf(pmode))throw new Error('Page mode must be one of UseNone, UseOutlines, UseThumbs, or FullScreen. "'+pmode+'" is not recognized.');return this},API.text=function(text,x,y,options){var tmp,xtra="",isHex=!1,lineHeight=lineHeightProportion,scope=this;function ESC(s){return s=s.split("\t").join(Array(options.TabLen||9).join(" ")),pdfEscape(s,flags)}function transformTextToSpecialArray(text){for(var curDa,sa=text.concat(),da=[],len=sa.length;len--;)"string"==typeof(curDa=sa.shift())?da.push(curDa):"[object Array]"===Object.prototype.toString.call(text)&&1===curDa.length?da.push(curDa[0]):da.push([curDa[0],curDa[1],curDa[2]]);return da}function processTextByFunction(text,processingFunction){var result;if("string"==typeof text)result=processingFunction(text)[0];else if("[object Array]"===Object.prototype.toString.call(text)){for(var curDa,tmpResult,sa=text.concat(),da=[],len=sa.length;len--;)"string"==typeof(curDa=sa.shift())?da.push(processingFunction(curDa)[0]):"[object Array]"===Object.prototype.toString.call(curDa)&&"string"===curDa[0]&&(tmpResult=processingFunction(curDa[0],curDa[1],curDa[2]),da.push([tmpResult[0],tmpResult[1],tmpResult[2]]));result=da}return result}"number"==typeof text&&(tmp=y,y=x,x=text,text=tmp);var angle=arguments[4],align=arguments[5];"object"===(void 0===(flags=arguments[3])?"undefined":_typeof(flags))&&null!==flags||("string"==typeof angle&&(align=angle,angle=null),"string"==typeof flags&&(align=flags,flags=null),"number"==typeof flags&&(angle=flags,flags=null),options={flags:flags,angle:angle,align:align});var textIsOfTypeString=!1,tmpTextIsOfTypeString=!0;if("string"==typeof text)textIsOfTypeString=!0;else if("[object Array]"===Object.prototype.toString.call(text)){for(var curDa,sa=text.concat(),da=[],len=sa.length;len--;)("string"!=typeof(curDa=sa.shift())||"[object Array]"===Object.prototype.toString.call(curDa)&&"string"!=typeof curDa[0])&&(tmpTextIsOfTypeString=!1);textIsOfTypeString=tmpTextIsOfTypeString}if(!1===textIsOfTypeString)throw new Error('Type of text must be string or Array. "'+text+'" is not recognized.');var activeFontEncoding=fonts[activeFontKey].encoding;"WinAnsiEncoding"!==activeFontEncoding&&"StandardEncoding"!==activeFontEncoding||(text=processTextByFunction(text,(function(text,posX,posY){return[ESC(text),posX,posY]}))),"string"==typeof text&&(text=text.match(/[\r?\n]/)?text.split(/\r\n|\r|\n/g):[text]),(maxWidth=options.maxWidth||0)>0&&("string"==typeof text?text=scope.splitTextToSize(text,maxWidth):"[object Array]"===Object.prototype.toString.call(text)&&(text=scope.splitTextToSize(text.join(" "),maxWidth)));var payload={text:text,x:x,y:y,options:options,mutex:{pdfEscape:pdfEscape,activeFontKey:activeFontKey,fonts:fonts,activeFontSize:activeFontSize}};events.publish("preProcessText",payload),text=payload.text;angle=(options=payload.options).angle;var k=scope.internal.scaleFactor,transformationMatrix=(scope.internal.pageSize.getHeight(),[]);if(angle){angle*=Math.PI/180;var c=Math.cos(angle),s=Math.sin(angle),f2=function(number){return number.toFixed(2)};transformationMatrix=[f2(c),f2(s),f2(-1*s),f2(c)]}void 0!==(charSpace=options.charSpace)&&(xtra+=charSpace+" Tc\n");options.lang;var tmpRenderingMode=-1,parmRenderingMode=options.renderingMode||options.stroke,pageContext=scope.internal.getCurrentPageInfo().pageContext;switch(parmRenderingMode){case 0:case!1:case"fill":tmpRenderingMode=0;break;case 1:case!0:case"stroke":tmpRenderingMode=1;break;case 2:case"fillThenStroke":tmpRenderingMode=2;break;case 3:case"invisible":tmpRenderingMode=3;break;case 4:case"fillAndAddForClipping":tmpRenderingMode=4;break;case 5:case"strokeAndAddPathForClipping":tmpRenderingMode=5;break;case 6:case"fillThenStrokeAndAddToPathForClipping":tmpRenderingMode=6;break;case 7:case"addToPathForClipping":tmpRenderingMode=7}var usedRenderingMode=pageContext.usedRenderingMode||-1;-1!==tmpRenderingMode?xtra+=tmpRenderingMode+" Tr\n":-1!==usedRenderingMode&&(xtra+="0 Tr\n"),-1!==tmpRenderingMode&&(pageContext.usedRenderingMode=tmpRenderingMode);align=options.align||"left";var leading=activeFontSize*lineHeight,pageHeight=scope.internal.pageSize.getHeight(),pageWidth=scope.internal.pageSize.getWidth(),activeFont=(k=scope.internal.scaleFactor,fonts[activeFontKey]),charSpace=options.charSpace||activeCharSpace,maxWidth=options.maxWidth||0,flags={},wordSpacingPerLine=[];if("[object Array]"===Object.prototype.toString.call(text)){var newY,lineWidths;da=transformTextToSpecialArray(text);"left"!==align&&(lineWidths=da.map((function(v){return scope.getStringUnitWidth(v,{font:activeFont,charSpace:charSpace,fontSize:activeFontSize})*activeFontSize/k})));var newX,maxLineLength=Math.max.apply(Math,lineWidths),prevWidth=0;if("right"===align){x-=lineWidths[0],text=[];var i=0;for(len=da.length;i<len;i++)maxLineLength-lineWidths[i],0===i?(newX=x*k,newY=(pageHeight-y)*k):(newX=(prevWidth-lineWidths[i])*k,newY=-leading),text.push([da[i],newX,newY]),prevWidth=lineWidths[i]}else if("center"===align){x-=lineWidths[0]/2,text=[];for(i=0,len=da.length;i<len;i++)(maxLineLength-lineWidths[i])/2,0===i?(newX=x*k,newY=(pageHeight-y)*k):(newX=(prevWidth-lineWidths[i])/2*k,newY=-leading),text.push([da[i],newX,newY]),prevWidth=lineWidths[i]}else if("left"===align){text=[];for(i=0,len=da.length;i<len;i++)newY=0===i?(pageHeight-y)*k:-leading,newX=0===i?x*k:0,text.push(da[i])}else{if("justify"!==align)throw new Error('Unrecognized alignment option, use "left", "center", "right" or "justify".');text=[];for(maxWidth=0!==maxWidth?maxWidth:pageWidth,i=0,len=da.length;i<len;i++)newY=0===i?(pageHeight-y)*k:-leading,newX=0===i?x*k:0,i<len-1&&wordSpacingPerLine.push(((maxWidth-lineWidths[i])/(da[i].split(" ").length-1)*k).toFixed(2)),text.push([da[i],newX,newY])}}var doReversing="boolean"==typeof options.R2L?options.R2L:R2L;!0===doReversing&&(text=processTextByFunction(text,(function(text,posX,posY){return[text.split("").reverse().join(""),posX,posY]})));payload={text:text,x:x,y:y,options:options,mutex:{pdfEscape:pdfEscape,activeFontKey:activeFontKey,fonts:fonts,activeFontSize:activeFontSize}};events.publish("postProcessText",payload),text=payload.text,isHex=payload.mutex.isHex;da=transformTextToSpecialArray(text);text=[];var posX,posY,content,variant=0,wordSpacing=(len=da.length,"");for(i=0;i<len;i++)wordSpacing="","[object Array]"!==Object.prototype.toString.call(da[i])?(posX=parseFloat(x*k).toFixed(2),posY=parseFloat((pageHeight-y)*k).toFixed(2),content=(isHex?"<":"(")+da[i]+(isHex?">":")")):"[object Array]"===Object.prototype.toString.call(da[i])&&(posX=parseFloat(da[i][1]).toFixed(2),posY=parseFloat(da[i][2]).toFixed(2),content=(isHex?"<":"(")+da[i][0]+(isHex?">":")"),variant=1),void 0!==wordSpacingPerLine&&void 0!==wordSpacingPerLine[i]&&(wordSpacing=wordSpacingPerLine[i]+" Tw\n"),0!==transformationMatrix.length&&0===i?text.push(wordSpacing+transformationMatrix.join(" ")+" "+posX+" "+posY+" Tm\n"+content):1===variant||0===variant&&0===i?text.push(wordSpacing+posX+" "+posY+" Td\n"+content):text.push(wordSpacing+content);text=0===variant?text.join(" Tj\nT* "):text.join(" Tj\n"),text+=" Tj\n";var result="BT\n/"+activeFontKey+" "+activeFontSize+" Tf\n"+(activeFontSize*lineHeight).toFixed(2)+" TL\n"+textColor+"\n";return result+=xtra,result+=text,out(result+="ET"),scope},API.lstext=function(text,x,y,spacing){console.warn("jsPDF.lstext is deprecated");for(var i=0,len=text.length;i<len;i++,x+=spacing)this.text(text[i],x,y);return this},API.line=function(x1,y1,x2,y2){return this.lines([[x2-x1,y2-y1]],x1,y1)},API.clip=function(){out("W"),out("S")},API.clip_fixed=function(fillRule){out("evenodd"===fillRule?"W*":"W"),out("n")},API.lines=function(lines,x,y,scale,style,closed){var scalex,scaley,i,l,leg,x2,y2,x3,y3,x4,y4;for("number"==typeof lines&&(tmp=y,y=x,x=lines,lines=tmp),scale=scale||[1,1],out(f3(x*k)+" "+f3((pageHeight-y)*k)+" m "),scalex=scale[0],scaley=scale[1],l=lines.length,x4=x,y4=y,i=0;i<l;i++)2===(leg=lines[i]).length?(x4=leg[0]*scalex+x4,y4=leg[1]*scaley+y4,out(f3(x4*k)+" "+f3((pageHeight-y4)*k)+" l")):(x2=leg[0]*scalex+x4,y2=leg[1]*scaley+y4,x3=leg[2]*scalex+x4,y3=leg[3]*scaley+y4,x4=leg[4]*scalex+x4,y4=leg[5]*scaley+y4,out(f3(x2*k)+" "+f3((pageHeight-y2)*k)+" "+f3(x3*k)+" "+f3((pageHeight-y3)*k)+" "+f3(x4*k)+" "+f3((pageHeight-y4)*k)+" c"));return closed&&out(" h"),null!==style&&out(getStyle(style)),this},API.rect=function(x,y,w,h,style){getStyle(style);return out([f2(x*k),f2((pageHeight-y)*k),f2(w*k),f2(-h*k),"re"].join(" ")),null!==style&&out(getStyle(style)),this},API.triangle=function(x1,y1,x2,y2,x3,y3,style){return this.lines([[x2-x1,y2-y1],[x3-x2,y3-y2],[x1-x3,y1-y3]],x1,y1,[1,1],style,!0),this},API.roundedRect=function(x,y,w,h,rx,ry,style){var MyArc=4/3*(Math.SQRT2-1);return this.lines([[w-2*rx,0],[rx*MyArc,0,rx,ry-ry*MyArc,rx,ry],[0,h-2*ry],[0,ry*MyArc,-rx*MyArc,ry,-rx,ry],[2*rx-w,0],[-rx*MyArc,0,-rx,-ry*MyArc,-rx,-ry],[0,2*ry-h],[0,-ry*MyArc,rx*MyArc,-ry,rx,-ry]],x+rx,y,[1,1],style),this},API.ellipse=function(x,y,rx,ry,style){var lx=4/3*(Math.SQRT2-1)*rx,ly=4/3*(Math.SQRT2-1)*ry;return out([f2((x+rx)*k),f2((pageHeight-y)*k),"m",f2((x+rx)*k),f2((pageHeight-(y-ly))*k),f2((x+lx)*k),f2((pageHeight-(y-ry))*k),f2(x*k),f2((pageHeight-(y-ry))*k),"c"].join(" ")),out([f2((x-lx)*k),f2((pageHeight-(y-ry))*k),f2((x-rx)*k),f2((pageHeight-(y-ly))*k),f2((x-rx)*k),f2((pageHeight-y)*k),"c"].join(" ")),out([f2((x-rx)*k),f2((pageHeight-(y+ly))*k),f2((x-lx)*k),f2((pageHeight-(y+ry))*k),f2(x*k),f2((pageHeight-(y+ry))*k),"c"].join(" ")),out([f2((x+lx)*k),f2((pageHeight-(y+ry))*k),f2((x+rx)*k),f2((pageHeight-(y+ly))*k),f2((x+rx)*k),f2((pageHeight-y)*k),"c"].join(" ")),null!==style&&out(getStyle(style)),this},API.circle=function(x,y,r,style){return this.ellipse(x,y,r,r,style)},API.setProperties=function(properties){for(var property in documentProperties)documentProperties.hasOwnProperty(property)&&properties[property]&&(documentProperties[property]=properties[property]);return this},API.setFontSize=function(size){return activeFontSize=size,this},API.setFont=function(fontName,fontStyle){return activeFontKey=_getFont(fontName,fontStyle),this},API.setFontStyle=API.setFontType=function(style){return activeFontKey=_getFont(void 0,style),this},API.getFontList=function(){var fontName,fontStyle,tmp,list={};for(fontName in fontmap)if(fontmap.hasOwnProperty(fontName))for(fontStyle in list[fontName]=tmp=[],fontmap[fontName])fontmap[fontName].hasOwnProperty(fontStyle)&&tmp.push(fontStyle);return list},API.addFont=function(postScriptName,fontName,fontStyle,encoding){addFont(postScriptName,fontName,fontStyle,encoding=encoding||"Identity-H")},API.setLineWidth=function(width){return out((width*k).toFixed(2)+" w"),this},API.setDrawColor=function(ch1,ch2,ch3,ch4){return out(generateColorString({ch1:ch1,ch2:ch2,ch3:ch3,ch4:ch4,pdfColorType:"draw",precision:2})),this},API.setFillColor=function(ch1,ch2,ch3,ch4){return out(generateColorString({ch1:ch1,ch2:ch2,ch3:ch3,ch4:ch4,pdfColorType:"fill",precision:2})),this},API.setTextColor=function(ch1,ch2,ch3,ch4){return textColor=generateColorString({ch1:ch1,ch2:ch2,ch3:ch3,ch4:ch4,pdfColorType:"text",precision:3}),this},API.setCharSpace=function(charSpace){return activeCharSpace=charSpace,this},API.setR2L=function(boolean){return R2L=boolean,this},API.CapJoinStyles={0:0,butt:0,but:0,miter:0,1:1,round:1,rounded:1,circle:1,2:2,projecting:2,project:2,square:2,bevel:2},API.setLineCap=function(style){var id=this.CapJoinStyles[style];if(void 0===id)throw new Error("Line cap style of '"+style+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return lineCapID=id,out(id+" J"),this},API.setLineJoin=function(style){var id=this.CapJoinStyles[style];if(void 0===id)throw new Error("Line join style of '"+style+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return lineJoinID=id,out(id+" j"),this},API.output=_output,API.save=function(filename){API.output("save",filename)},jsPDF.API)jsPDF.API.hasOwnProperty(plugin)&&("events"===plugin&&jsPDF.API.events.length?function(events,newEvents){var eventname,handler_and_args,i;for(i=newEvents.length-1;-1!==i;i--)eventname=newEvents[i][0],handler_and_args=newEvents[i][1],events.subscribe.apply(events,[eventname].concat("function"==typeof handler_and_args?[handler_and_args]:handler_and_args))}(events,jsPDF.API.events):API[plugin]=jsPDF.API[plugin]);return function(){for(var standardFonts=[["Helvetica","helvetica","normal","WinAnsiEncoding"],["Helvetica-Bold","helvetica","bold","WinAnsiEncoding"],["Helvetica-Oblique","helvetica","italic","WinAnsiEncoding"],["Helvetica-BoldOblique","helvetica","bolditalic","WinAnsiEncoding"],["Courier","courier","normal","WinAnsiEncoding"],["Courier-Bold","courier","bold","WinAnsiEncoding"],["Courier-Oblique","courier","italic","WinAnsiEncoding"],["Courier-BoldOblique","courier","bolditalic","WinAnsiEncoding"],["Times-Roman","times","normal","WinAnsiEncoding"],["Times-Bold","times","bold","WinAnsiEncoding"],["Times-Italic","times","italic","WinAnsiEncoding"],["Times-BoldItalic","times","bolditalic","WinAnsiEncoding"],["ZapfDingbats","zapfdingbats","normal",null],["Symbol","symbol","normal",null]],i=0,l=standardFonts.length;i<l;i++){var fontKey=addFont(standardFonts[i][0],standardFonts[i][1],standardFonts[i][2],standardFonts[i][3]),parts=standardFonts[i][0].split("-");addToFontDictionary(fontKey,parts[0],parts[1]||"")}events.publish("addFonts",{fonts:fonts,dictionary:fontmap})}(),activeFontKey="F1",_addPage(format,orientation),events.publish("initialized"),API}return jsPDF.API={events:[]},jsPDF.version="0.0.0","function"==typeof define&&define.amd?define("jsPDF",(function(){return jsPDF})):"undefined"!=typeof module&&module.exports?(module.exports=jsPDF,module.exports.jsPDF=jsPDF):global.jsPDF=jsPDF,jsPDF}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||"undefined"!=typeof global&&global||Function('return typeof this === "object" && this.content')()||Function("return this")());
-/** @preserve
-   * jsPDF - PDF Document creation from JavaScript
-   * Version 1.4.1 Built on 2018-06-06T07:49:28.721Z
-   *                           CommitID 3233f44044
-   *
-   * Copyright (c) 2010-2016 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF
-   *               2010 Aaron Spike, https://github.com/acspike
-   *               2012 Willow Systems Corporation, willow-systems.com
-   *               2012 Pablo Hess, https://github.com/pablohess
-   *               2012 Florian Jenett, https://github.com/fjenett
-   *               2013 Warren Weckesser, https://github.com/warrenweckesser
-   *               2013 Youssef Beddad, https://github.com/lifof
-   *               2013 Lee Driscoll, https://github.com/lsdriscoll
-   *               2013 Stefan Slonevskiy, https://github.com/stefslon
-   *               2013 Jeremy Morel, https://github.com/jmorel
-   *               2013 Christoph Hartmann, https://github.com/chris-rock
-   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
-   *               2014 James Makes, https://github.com/dollaruw
-   *               2014 Diego Casorran, https://github.com/diegocr
-   *               2014 Steven Spungin, https://github.com/Flamenco
-   *               2014 Kenneth Glassey, https://github.com/Gavvers
-   *
-   * Licensed under the MIT License
-   *
-   * Contributor(s):
-   *    siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango,
-   *    kim3er, mfo, alnorth, Flamenco
-   */!function(jsPDFAPI,globalObj){var scope,pageHeight,scaleFactor=1,inherit=function(child,parent){child.prototype=Object.create(parent.prototype),child.prototype.constructor=child},scale=function(x){return x*(scaleFactor/1)},createFormXObject=function(formObject){var xobj=new AcroFormXObject,height=AcroFormAppearance.internal.getHeight(formObject)||0,width=AcroFormAppearance.internal.getWidth(formObject)||0;return xobj.BBox=[0,0,width.toFixed(2),height.toFixed(2)],xobj},setBitPosition=function(variable,position,value){variable=variable||0;var bitMask=1;if(bitMask<<=position-1,1==(value=value||1))variable=variable|bitMask;else variable=variable&~bitMask;return variable},calculateFlagsOnOptions=function(flags,opts,PDFVersion){PDFVersion=PDFVersion||1.3,flags=flags||0;return 1==opts.readOnly&&(flags=setBitPosition(flags,1)),1==opts.required&&(flags=setBitPosition(flags,2)),1==opts.noExport&&(flags=setBitPosition(flags,3)),1==opts.multiline&&(flags=setBitPosition(flags,13)),opts.password&&(flags=setBitPosition(flags,14)),opts.noToggleToOff&&(flags=setBitPosition(flags,15)),opts.radio&&(flags=setBitPosition(flags,16)),opts.pushbutton&&(flags=setBitPosition(flags,17)),opts.combo&&(flags=setBitPosition(flags,18)),opts.edit&&(flags=setBitPosition(flags,19)),opts.sort&&(flags=setBitPosition(flags,20)),opts.fileSelect&&PDFVersion>=1.4&&(flags=setBitPosition(flags,21)),opts.multiSelect&&PDFVersion>=1.4&&(flags=setBitPosition(flags,22)),opts.doNotSpellCheck&&PDFVersion>=1.4&&(flags=setBitPosition(flags,23)),1==opts.doNotScroll&&PDFVersion>=1.4&&(flags=setBitPosition(flags,24)),opts.richText&&PDFVersion>=1.4&&(flags=setBitPosition(flags,25)),flags},calculateCoordinates=function(args){var x=args[0],y=args[1],w=args[2],h=args[3],coordinates={};return Array.isArray(x)?(x[0]=scale(x[0]),x[1]=scale(x[1]),x[2]=scale(x[2]),x[3]=scale(x[3])):(x=scale(x),y=scale(y),w=scale(w),h=scale(h)),coordinates.lowerLeft_X=x||0,coordinates.lowerLeft_Y=scale(pageHeight)-y-h||0,coordinates.upperRight_X=x+w||0,coordinates.upperRight_Y=scale(pageHeight)-y||0,[coordinates.lowerLeft_X.toFixed(2),coordinates.lowerLeft_Y.toFixed(2),coordinates.upperRight_X.toFixed(2),coordinates.upperRight_Y.toFixed(2)]},calculateAppearanceStream=function(formObject){if(formObject.appearanceStreamContent)return formObject.appearanceStreamContent;if(formObject.V||formObject.DV){var stream=[],text=formObject.V||formObject.DV,calcRes=calculateX(formObject,text);stream.push("/Tx BMC"),stream.push("q"),stream.push("/F1 "+calcRes.fontSize.toFixed(2)+" Tf"),stream.push("1 0 0 1 0 0 Tm"),stream.push("BT"),stream.push(calcRes.text),stream.push("ET"),stream.push("Q"),stream.push("EMC");var appearanceStreamContent=new createFormXObject(formObject);return appearanceStreamContent.stream=stream.join("\n"),appearanceStreamContent}},calculateX=function(formObject,text,font,maxFontSize){maxFontSize=maxFontSize||12,font=font||"helvetica";var returnValue={text:"",fontSize:""},textSplit=(text=")"==(text="("==text.substr(0,1)?text.substr(1):text).substr(text.length-1)?text.substr(0,text.length-1):text).split(" "),fontSize=maxFontSize,height=AcroFormAppearance.internal.getHeight(formObject)||0;height=height<0?-height:height;var width=AcroFormAppearance.internal.getWidth(formObject)||0;width=width<0?-width:width;var isSmallerThanWidth=function(i,lastLine,fontSize){if(i+1<textSplit.length){var tmp=lastLine+" "+textSplit[i+1];return calculateFontSpace(tmp,fontSize+"px",font).width<=width-4}return!1};fontSize++;FontSize:for(;;){text="";fontSize--;var textHeight=calculateFontSpace("3",fontSize+"px",font).height,startY=formObject.multiline?height-fontSize:(height-textHeight)/2,startX=-2,lastY=startY+=2,firstWordInLine=0,lastWordInLine=0,lastLength=0;if(fontSize<=0){fontSize=12,text="(...) Tj\n",text+="% Width of Text: "+calculateFontSpace(text,"1px").width+", FieldWidth:"+width+"\n";break}lastLength=calculateFontSpace(textSplit[0]+" ",fontSize+"px",font).width;var lastLine="",lineCount=0;for(var i in textSplit){lastLine=" "==(lastLine+=textSplit[i]+" ").substr(lastLine.length-1)?lastLine.substr(0,lastLine.length-1):lastLine;var key=parseInt(i);lastLength=calculateFontSpace(lastLine+" ",fontSize+"px",font).width;var nextLineIsSmaller=isSmallerThanWidth(key,lastLine,fontSize),isLastWord=i>=textSplit.length-1;if(!nextLineIsSmaller||isLastWord){if(nextLineIsSmaller||isLastWord){if(isLastWord)lastWordInLine=key;else if(formObject.multiline&&(textHeight+2)*(lineCount+2)+2>height)continue FontSize}else{if(!formObject.multiline)continue FontSize;if((textHeight+2)*(lineCount+2)+2>height)continue FontSize;lastWordInLine=key}for(var line="",x=firstWordInLine;x<=lastWordInLine;x++)line+=textSplit[x]+" ";switch(line=" "==line.substr(line.length-1)?line.substr(0,line.length-1):line,lastLength=calculateFontSpace(line,fontSize+"px",font).width,formObject.Q){case 2:startX=width-lastLength-2;break;case 1:startX=(width-lastLength)/2;break;default:startX=2}text+=startX.toFixed(2)+" "+lastY.toFixed(2)+" Td\n",text+="("+line+") Tj\n",text+=-startX.toFixed(2)+" 0 Td\n",lastY=-(fontSize+2),lastLength=0,firstWordInLine=lastWordInLine+1,lineCount++,lastLine=""}else lastLine+=" "}break}return returnValue.text=text,returnValue.fontSize=fontSize,returnValue},calculateFontSpace=function(text,fontSize,fontType){fontType=fontType||"helvetica";var font=scope.internal.getFont(fontType),width=scope.getStringUnitWidth(text,{font:font,fontSize:parseFloat(fontSize),charSpace:0})*parseFloat(fontSize);return{height:scope.getStringUnitWidth("3",{font:font,fontSize:parseFloat(fontSize),charSpace:0})*parseFloat(fontSize)*1.5,width:width}},acroformPluginTemplate={fields:[],xForms:[],acroFormDictionaryRoot:null,printedOut:!1,internal:null,isInitialized:!1},annotReferenceCallback=function(){for(var i in scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields){var formObject=scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields[i];formObject.hasAnnotation&&createAnnotationReference.call(scope,formObject)}},putForm=function(formObject){scope.internal.acroformPlugin.printedOut&&(scope.internal.acroformPlugin.printedOut=!1,scope.internal.acroformPlugin.acroFormDictionaryRoot=null),scope.internal.acroformPlugin.acroFormDictionaryRoot||initializeAcroForm.call(scope),scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields.push(formObject)},createAnnotationReference=function(object){var options={type:"reference",object:object};scope.annotationPlugin.annotations[scope.internal.getPageInfo(object.page).pageNumber].push(options)},putCatalogCallback=function(){void 0!==scope.internal.acroformPlugin.acroFormDictionaryRoot?scope.internal.write("/AcroForm "+scope.internal.acroformPlugin.acroFormDictionaryRoot.objId+" 0 R"):console.log("Root missing...")},AcroFormDictionaryCallback=function(){scope.internal.events.unsubscribe(scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID),delete scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID,scope.internal.acroformPlugin.printedOut=!0},createFieldCallback=function(fieldArray){var standardFields=!fieldArray;fieldArray||(scope.internal.newObjectDeferredBegin(scope.internal.acroformPlugin.acroFormDictionaryRoot.objId),scope.internal.out(scope.internal.acroformPlugin.acroFormDictionaryRoot.getString()));fieldArray=fieldArray||scope.internal.acroformPlugin.acroFormDictionaryRoot.Kids;for(var i in fieldArray){var form=fieldArray[i],oldRect=form.Rect;form.Rect&&(form.Rect=calculateCoordinates.call(this,form.Rect)),scope.internal.newObjectDeferredBegin(form.objId);var content=form.objId+" 0 obj\n<<\n";if("object"===(void 0===form?"undefined":_typeof(form))&&"function"==typeof form.getContent&&(content+=form.getContent()),form.Rect=oldRect,form.hasAppearanceStream&&!form.appearanceStreamContent){var appearance=calculateAppearanceStream.call(this,form);content+="/AP << /N "+appearance+" >>\n",scope.internal.acroformPlugin.xForms.push(appearance)}if(form.appearanceStreamContent){for(var k in content+="/AP << ",form.appearanceStreamContent){var value=form.appearanceStreamContent[k];if(content+="/"+k+" ",content+="<< ",Object.keys(value).length>=1||Array.isArray(value))for(var i in value){var obj;"function"==typeof(obj=value[i])&&(obj=obj.call(this,form)),content+="/"+i+" "+obj+" ",scope.internal.acroformPlugin.xForms.indexOf(obj)>=0||scope.internal.acroformPlugin.xForms.push(obj)}else"function"==typeof(obj=value)&&(obj=obj.call(this,form)),content+="/"+i+" "+obj+" \n",scope.internal.acroformPlugin.xForms.indexOf(obj)>=0||scope.internal.acroformPlugin.xForms.push(obj);content+=" >>\n"}content+=">>\n"}content+=">>\nendobj\n",scope.internal.out(content)}standardFields&&createXFormObjectCallback.call(this,scope.internal.acroformPlugin.xForms)},createXFormObjectCallback=function(fieldArray){for(var i in fieldArray){var key=i,form=fieldArray[i];scope.internal.newObjectDeferredBegin(form&&form.objId);var content="";"object"===(void 0===form?"undefined":_typeof(form))&&"function"==typeof form.getString&&(content=form.getString()),scope.internal.out(content),delete fieldArray[key]}},initializeAcroForm=function(){if(void 0!==this.internal&&(void 0===this.internal.acroformPlugin||!1===this.internal.acroformPlugin.isInitialized)){if(scope=this,AcroFormField.FieldNum=0,this.internal.acroformPlugin=JSON.parse(JSON.stringify(acroformPluginTemplate)),this.internal.acroformPlugin.acroFormDictionaryRoot)throw new Error("Exception while creating AcroformDictionary");scaleFactor=scope.internal.scaleFactor,pageHeight=scope.internal.pageSize.getHeight(),scope.internal.acroformPlugin.acroFormDictionaryRoot=new AcroFormDictionary,scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID=scope.internal.events.subscribe("postPutResources",AcroFormDictionaryCallback),scope.internal.events.subscribe("buildDocument",annotReferenceCallback),scope.internal.events.subscribe("putCatalog",putCatalogCallback),scope.internal.events.subscribe("postPutPages",createFieldCallback),scope.internal.acroformPlugin.isInitialized=!0}},arrayToPdfArray=function(array){if(Array.isArray(array)){var content=" [";for(var i in array){content+=array[i].toString(),content+=i<array.length-1?" ":""}return content+="]"}},toPdfString=function(string){return 0!==(string=string||"").indexOf("(")&&(string="("+string),")"!=string.substring(string.length-1)&&(string+=")"),string},AcroFormPDFObject=function(){var _objId;Object.defineProperty(this,"objId",{get:function(){return _objId||(_objId=scope.internal.newObjectDeferred()),_objId||console.log("Couldn't create Object ID"),_objId},configurable:!1})};AcroFormPDFObject.prototype.toString=function(){return this.objId+" 0 R"},AcroFormPDFObject.prototype.getString=function(){var res=this.objId+" 0 obj\n<<";return res+=this.getContent()+">>\n",this.stream&&(res+="stream\n",res+=this.stream,res+="\nendstream\n"),res+="endobj\n"},AcroFormPDFObject.prototype.getContent=function(){var object="";return object+=function(fieldObject){var content="",keys=Object.keys(fieldObject).filter((function(key){return"content"!=key&&"appearanceStreamContent"!=key&&"_"!=key.substring(0,1)}));for(var i in keys){var key=keys[i],value=fieldObject[key];value&&(Array.isArray(value)?content+="/"+key+" "+arrayToPdfArray(value)+"\n":content+=value instanceof AcroFormPDFObject?"/"+key+" "+value.objId+" 0 R\n":"/"+key+" "+value+"\n")}return content}(this)};var AcroFormXObject=function(){var _stream;AcroFormPDFObject.call(this),this.Type="/XObject",this.Subtype="/Form",this.FormType=1,this.BBox,this.Matrix,this.Resources="2 0 R",this.PieceInfo,Object.defineProperty(this,"Length",{enumerable:!0,get:function(){return void 0!==_stream?_stream.length:0}}),Object.defineProperty(this,"stream",{enumerable:!1,set:function(val){_stream=val.trim()},get:function(){return _stream||null}})};inherit(AcroFormXObject,AcroFormPDFObject);var AcroFormDictionary=function(){AcroFormPDFObject.call(this);var _Kids=[];Object.defineProperty(this,"Kids",{enumerable:!1,configurable:!0,get:function(){return _Kids.length>0?_Kids:void 0}}),Object.defineProperty(this,"Fields",{enumerable:!0,configurable:!0,get:function(){return _Kids}}),this.DA};inherit(AcroFormDictionary,AcroFormPDFObject);var AcroFormField=function AcroFormField(){var _Rect;AcroFormPDFObject.call(this),Object.defineProperty(this,"Rect",{enumerable:!0,configurable:!1,get:function(){if(_Rect)return _Rect},set:function(val){_Rect=val}});var _T,_DA,_DV,_V,_FT="";Object.defineProperty(this,"FT",{enumerable:!0,set:function(val){_FT=val},get:function(){return _FT}}),Object.defineProperty(this,"T",{enumerable:!0,configurable:!1,set:function(val){_T=val},get:function(){if(!_T||_T.length<1){if(this instanceof AcroFormChildClass)return;return"(FieldObject"+AcroFormField.FieldNum+++")"}return"("==_T.substring(0,1)&&_T.substring(_T.length-1)?_T:"("+_T+")"}}),Object.defineProperty(this,"DA",{enumerable:!0,get:function(){if(_DA)return"("+_DA+")"},set:function(val){_DA=val}}),Object.defineProperty(this,"DV",{enumerable:!0,configurable:!0,get:function(){if(_DV)return _DV},set:function(val){_DV=val}}),Object.defineProperty(this,"V",{enumerable:!0,configurable:!0,get:function(){if(_V)return _V},set:function(val){_V=val}}),Object.defineProperty(this,"Type",{enumerable:!0,get:function(){return this.hasAnnotation?"/Annot":null}}),Object.defineProperty(this,"Subtype",{enumerable:!0,get:function(){return this.hasAnnotation?"/Widget":null}}),this.BG,Object.defineProperty(this,"hasAnnotation",{enumerable:!1,get:function(){return!!(this.Rect||this.BC||this.BG)}}),Object.defineProperty(this,"hasAppearanceStream",{enumerable:!1,configurable:!0,writable:!0}),Object.defineProperty(this,"page",{enumerable:!1,configurable:!0,writable:!0})};inherit(AcroFormField,AcroFormPDFObject);var AcroFormChoiceField=function(){AcroFormField.call(this),this.FT="/Ch",this.Opt=[],this.V="()",this.TI=0;var _combo=!1;Object.defineProperty(this,"combo",{enumerable:!1,get:function(){return _combo},set:function(val){_combo=val}}),Object.defineProperty(this,"edit",{enumerable:!0,set:function(val){1==val?(this._edit=!0,this.combo=!0):this._edit=!1},get:function(){return!!this._edit&&this._edit},configurable:!1}),this.hasAppearanceStream=!0};inherit(AcroFormChoiceField,AcroFormField);var AcroFormListBox=function(){AcroFormChoiceField.call(this),this.combo=!1};inherit(AcroFormListBox,AcroFormChoiceField);var AcroFormComboBox=function(){AcroFormListBox.call(this),this.combo=!0};inherit(AcroFormComboBox,AcroFormListBox);var AcroFormEditBox=function(){AcroFormComboBox.call(this),this.edit=!0};inherit(AcroFormEditBox,AcroFormComboBox);var AcroFormButton=function(){AcroFormField.call(this),this.FT="/Btn"};inherit(AcroFormButton,AcroFormField);var AcroFormPushButton=function(){AcroFormButton.call(this);var _pushbutton=!0;Object.defineProperty(this,"pushbutton",{enumerable:!1,get:function(){return _pushbutton},set:function(val){_pushbutton=val}})};inherit(AcroFormPushButton,AcroFormButton);var AcroFormRadioButton=function(){AcroFormButton.call(this);var _radio=!0;Object.defineProperty(this,"radio",{enumerable:!1,get:function(){return _radio},set:function(val){_radio=val}});var _noToggleToOff,_Kids=[];Object.defineProperty(this,"Kids",{enumerable:!0,get:function(){if(_Kids.length>0)return _Kids}}),Object.defineProperty(this,"__Kids",{get:function(){return _Kids}}),Object.defineProperty(this,"noToggleToOff",{enumerable:!1,get:function(){return _noToggleToOff},set:function(val){_noToggleToOff=val}})};inherit(AcroFormRadioButton,AcroFormButton);var AcroFormChildClass=function(parent,name){AcroFormField.call(this),this.Parent=parent,this._AppearanceType=AcroFormAppearance.RadioButton.Circle,this.appearanceStreamContent=this._AppearanceType.createAppearanceStream(name),this.F=setBitPosition(this.F,3,1),this.MK=this._AppearanceType.createMK(),this.AS="/Off",this._Name=name};inherit(AcroFormChildClass,AcroFormField),AcroFormRadioButton.prototype.setAppearance=function(appearance){if("createAppearanceStream"in appearance&&"createMK"in appearance)for(var i in this.__Kids){var child=this.__Kids[i];child.appearanceStreamContent=appearance.createAppearanceStream(child._Name),child.MK=appearance.createMK()}else console.log("Couldn't assign Appearance to RadioButton. Appearance was Invalid!")},AcroFormRadioButton.prototype.createOption=function(name){this.__Kids.length;var child=new AcroFormChildClass(this,name);return this.__Kids.push(child),jsPDFAPI.addField(child),child};var AcroFormCheckBox=function(){AcroFormButton.call(this),this.appearanceStreamContent=AcroFormAppearance.CheckBox.createAppearanceStream(),this.MK=AcroFormAppearance.CheckBox.createMK(),this.AS="/On",this.V="/On"};inherit(AcroFormCheckBox,AcroFormButton);var AcroFormTextField=function(){var _V,_DV;AcroFormField.call(this),this.DA=AcroFormAppearance.createDefaultAppearanceStream(),this.F=4,Object.defineProperty(this,"V",{get:function(){return _V?toPdfString(_V):_V},enumerable:!0,set:function(val){_V=val}}),Object.defineProperty(this,"DV",{get:function(){return _DV?toPdfString(_DV):_DV},enumerable:!0,set:function(val){_DV=val}});var _multiline=!1;Object.defineProperty(this,"multiline",{enumerable:!1,get:function(){return _multiline},set:function(val){_multiline=val}});var _fileSelect=!1;Object.defineProperty(this,"fileSelect",{enumerable:!1,get:function(){return _fileSelect},set:function(val){_fileSelect=val}});var _doNotSpellCheck=!1;Object.defineProperty(this,"doNotSpellCheck",{enumerable:!1,get:function(){return _doNotSpellCheck},set:function(val){_doNotSpellCheck=val}});var _doNotScroll=!1;Object.defineProperty(this,"doNotScroll",{enumerable:!1,get:function(){return _doNotScroll},set:function(val){_doNotScroll=val}});var _MaxLen=!1;Object.defineProperty(this,"MaxLen",{enumerable:!0,get:function(){return _MaxLen},set:function(val){_MaxLen=val}}),Object.defineProperty(this,"hasAppearanceStream",{enumerable:!1,get:function(){return this.V||this.DV}})};inherit(AcroFormTextField,AcroFormField);var AcroFormPasswordField=function(){AcroFormTextField.call(this);var _password=!0;Object.defineProperty(this,"password",{enumerable:!1,get:function(){return _password},set:function(val){_password=val}})};inherit(AcroFormPasswordField,AcroFormTextField);var AcroFormAppearance={CheckBox:{createAppearanceStream:function(){return{N:{On:AcroFormAppearance.CheckBox.YesNormal},D:{On:AcroFormAppearance.CheckBox.YesPushDown,Off:AcroFormAppearance.CheckBox.OffPushDown}}},createMK:function(){return"<< /CA (3)>>"},YesPushDown:function(formObject){var xobj=createFormXObject(formObject),stream=[],zapfDingbatsId=scope.internal.getFont("zapfdingbats","normal").id;formObject.Q=1;var calcRes=calculateX(formObject,"3","ZapfDingbats",50);return stream.push("0.749023 g"),stream.push("0 0 "+AcroFormAppearance.internal.getWidth(formObject).toFixed(2)+" "+AcroFormAppearance.internal.getHeight(formObject).toFixed(2)+" re"),stream.push("f"),stream.push("BMC"),stream.push("q"),stream.push("0 0 1 rg"),stream.push("/"+zapfDingbatsId+" "+calcRes.fontSize.toFixed(2)+" Tf 0 g"),stream.push("BT"),stream.push(calcRes.text),stream.push("ET"),stream.push("Q"),stream.push("EMC"),xobj.stream=stream.join("\n"),xobj},YesNormal:function(formObject){var xobj=createFormXObject(formObject),zapfDingbatsId=scope.internal.getFont("zapfdingbats","normal").id,stream=[];formObject.Q=1;var height=AcroFormAppearance.internal.getHeight(formObject),width=AcroFormAppearance.internal.getWidth(formObject),calcRes=calculateX(formObject,"3","ZapfDingbats",.9*height);return stream.push("1 g"),stream.push("0 0 "+width.toFixed(2)+" "+height.toFixed(2)+" re"),stream.push("f"),stream.push("q"),stream.push("0 0 1 rg"),stream.push("0 0 "+(width-1).toFixed(2)+" "+(height-1).toFixed(2)+" re"),stream.push("W"),stream.push("n"),stream.push("0 g"),stream.push("BT"),stream.push("/"+zapfDingbatsId+" "+calcRes.fontSize.toFixed(2)+" Tf 0 g"),stream.push(calcRes.text),stream.push("ET"),stream.push("Q"),xobj.stream=stream.join("\n"),xobj},OffPushDown:function(formObject){var xobj=createFormXObject(formObject),stream=[];return stream.push("0.749023 g"),stream.push("0 0 "+AcroFormAppearance.internal.getWidth(formObject).toFixed(2)+" "+AcroFormAppearance.internal.getHeight(formObject).toFixed(2)+" re"),stream.push("f"),xobj.stream=stream.join("\n"),xobj}},RadioButton:{Circle:{createAppearanceStream:function(name){var appearanceStreamContent={D:{Off:AcroFormAppearance.RadioButton.Circle.OffPushDown},N:{}};return appearanceStreamContent.N[name]=AcroFormAppearance.RadioButton.Circle.YesNormal,appearanceStreamContent.D[name]=AcroFormAppearance.RadioButton.Circle.YesPushDown,appearanceStreamContent},createMK:function(){return"<< /CA (l)>>"},YesNormal:function(formObject){var xobj=createFormXObject(formObject),stream=[],DotRadius=AcroFormAppearance.internal.getWidth(formObject)<=AcroFormAppearance.internal.getHeight(formObject)?AcroFormAppearance.internal.getWidth(formObject)/4:AcroFormAppearance.internal.getHeight(formObject)/4;DotRadius*=.9;var c=AcroFormAppearance.internal.Bezier_C;return stream.push("q"),stream.push("1 0 0 1 "+AcroFormAppearance.internal.getWidth(formObject)/2+" "+AcroFormAppearance.internal.getHeight(formObject)/2+" cm"),stream.push(DotRadius+" 0 m"),stream.push(DotRadius+" "+DotRadius*c+" "+DotRadius*c+" "+DotRadius+" 0 "+DotRadius+" c"),stream.push("-"+DotRadius*c+" "+DotRadius+" -"+DotRadius+" "+DotRadius*c+" -"+DotRadius+" 0 c"),stream.push("-"+DotRadius+" -"+DotRadius*c+" -"+DotRadius*c+" -"+DotRadius+" 0 -"+DotRadius+" c"),stream.push(DotRadius*c+" -"+DotRadius+" "+DotRadius+" -"+DotRadius*c+" "+DotRadius+" 0 c"),stream.push("f"),stream.push("Q"),xobj.stream=stream.join("\n"),xobj},YesPushDown:function(formObject){var xobj=createFormXObject(formObject),stream=[],DotRadius=AcroFormAppearance.internal.getWidth(formObject)<=AcroFormAppearance.internal.getHeight(formObject)?AcroFormAppearance.internal.getWidth(formObject)/4:AcroFormAppearance.internal.getHeight(formObject)/4,k=2*(DotRadius*=.9),kc=k*AcroFormAppearance.internal.Bezier_C,dc=DotRadius*AcroFormAppearance.internal.Bezier_C;return stream.push("0.749023 g"),stream.push("q"),stream.push("1 0 0 1 "+(AcroFormAppearance.internal.getWidth(formObject)/2).toFixed(2)+" "+(AcroFormAppearance.internal.getHeight(formObject)/2).toFixed(2)+" cm"),stream.push(k+" 0 m"),stream.push(k+" "+kc+" "+kc+" "+k+" 0 "+k+" c"),stream.push("-"+kc+" "+k+" -"+k+" "+kc+" -"+k+" 0 c"),stream.push("-"+k+" -"+kc+" -"+kc+" -"+k+" 0 -"+k+" c"),stream.push(kc+" -"+k+" "+k+" -"+kc+" "+k+" 0 c"),stream.push("f"),stream.push("Q"),stream.push("0 g"),stream.push("q"),stream.push("1 0 0 1 "+(AcroFormAppearance.internal.getWidth(formObject)/2).toFixed(2)+" "+(AcroFormAppearance.internal.getHeight(formObject)/2).toFixed(2)+" cm"),stream.push(DotRadius+" 0 m"),stream.push(DotRadius+" "+dc+" "+dc+" "+DotRadius+" 0 "+DotRadius+" c"),stream.push("-"+dc+" "+DotRadius+" -"+DotRadius+" "+dc+" -"+DotRadius+" 0 c"),stream.push("-"+DotRadius+" -"+dc+" -"+dc+" -"+DotRadius+" 0 -"+DotRadius+" c"),stream.push(dc+" -"+DotRadius+" "+DotRadius+" -"+dc+" "+DotRadius+" 0 c"),stream.push("f"),stream.push("Q"),xobj.stream=stream.join("\n"),xobj},OffPushDown:function(formObject){var xobj=createFormXObject(formObject),stream=[],DotRadius=AcroFormAppearance.internal.getWidth(formObject)<=AcroFormAppearance.internal.getHeight(formObject)?AcroFormAppearance.internal.getWidth(formObject)/4:AcroFormAppearance.internal.getHeight(formObject)/4,k=2*(DotRadius*=.9),kc=k*AcroFormAppearance.internal.Bezier_C;return stream.push("0.749023 g"),stream.push("q"),stream.push("1 0 0 1 "+(AcroFormAppearance.internal.getWidth(formObject)/2).toFixed(2)+" "+(AcroFormAppearance.internal.getHeight(formObject)/2).toFixed(2)+" cm"),stream.push(k+" 0 m"),stream.push(k+" "+kc+" "+kc+" "+k+" 0 "+k+" c"),stream.push("-"+kc+" "+k+" -"+k+" "+kc+" -"+k+" 0 c"),stream.push("-"+k+" -"+kc+" -"+kc+" -"+k+" 0 -"+k+" c"),stream.push(kc+" -"+k+" "+k+" -"+kc+" "+k+" 0 c"),stream.push("f"),stream.push("Q"),xobj.stream=stream.join("\n"),xobj}},Cross:{createAppearanceStream:function(name){var appearanceStreamContent={D:{Off:AcroFormAppearance.RadioButton.Cross.OffPushDown},N:{}};return appearanceStreamContent.N[name]=AcroFormAppearance.RadioButton.Cross.YesNormal,appearanceStreamContent.D[name]=AcroFormAppearance.RadioButton.Cross.YesPushDown,appearanceStreamContent},createMK:function(){return"<< /CA (8)>>"},YesNormal:function(formObject){var xobj=createFormXObject(formObject),stream=[],cross=AcroFormAppearance.internal.calculateCross(formObject);return stream.push("q"),stream.push("1 1 "+(AcroFormAppearance.internal.getWidth(formObject)-2).toFixed(2)+" "+(AcroFormAppearance.internal.getHeight(formObject)-2).toFixed(2)+" re"),stream.push("W"),stream.push("n"),stream.push(cross.x1.x.toFixed(2)+" "+cross.x1.y.toFixed(2)+" m"),stream.push(cross.x2.x.toFixed(2)+" "+cross.x2.y.toFixed(2)+" l"),stream.push(cross.x4.x.toFixed(2)+" "+cross.x4.y.toFixed(2)+" m"),stream.push(cross.x3.x.toFixed(2)+" "+cross.x3.y.toFixed(2)+" l"),stream.push("s"),stream.push("Q"),xobj.stream=stream.join("\n"),xobj},YesPushDown:function(formObject){var xobj=createFormXObject(formObject),cross=AcroFormAppearance.internal.calculateCross(formObject),stream=[];return stream.push("0.749023 g"),stream.push("0 0 "+AcroFormAppearance.internal.getWidth(formObject).toFixed(2)+" "+AcroFormAppearance.internal.getHeight(formObject).toFixed(2)+" re"),stream.push("f"),stream.push("q"),stream.push("1 1 "+(AcroFormAppearance.internal.getWidth(formObject)-2).toFixed(2)+" "+(AcroFormAppearance.internal.getHeight(formObject)-2).toFixed(2)+" re"),stream.push("W"),stream.push("n"),stream.push(cross.x1.x.toFixed(2)+" "+cross.x1.y.toFixed(2)+" m"),stream.push(cross.x2.x.toFixed(2)+" "+cross.x2.y.toFixed(2)+" l"),stream.push(cross.x4.x.toFixed(2)+" "+cross.x4.y.toFixed(2)+" m"),stream.push(cross.x3.x.toFixed(2)+" "+cross.x3.y.toFixed(2)+" l"),stream.push("s"),stream.push("Q"),xobj.stream=stream.join("\n"),xobj},OffPushDown:function(formObject){var xobj=createFormXObject(formObject),stream=[];return stream.push("0.749023 g"),stream.push("0 0 "+AcroFormAppearance.internal.getWidth(formObject).toFixed(2)+" "+AcroFormAppearance.internal.getHeight(formObject).toFixed(2)+" re"),stream.push("f"),xobj.stream=stream.join("\n"),xobj}}},createDefaultAppearanceStream:function(formObject){return"/F1 0 Tf 0 g"}};AcroFormAppearance.internal={Bezier_C:.551915024494,calculateCross:function(formObject){var x,y,width=AcroFormAppearance.internal.getWidth(formObject),height=AcroFormAppearance.internal.getHeight(formObject),a=(x=width)>(y=height)?y:x;return{x1:{x:(width-a)/2,y:(height-a)/2+a},x2:{x:(width-a)/2+a,y:(height-a)/2},x3:{x:(width-a)/2,y:(height-a)/2},x4:{x:(width-a)/2+a,y:(height-a)/2+a}}}},AcroFormAppearance.internal.getWidth=function(formObject){var result=0;return"object"===(void 0===formObject?"undefined":_typeof(formObject))&&(result=scale(formObject.Rect[2])),result},AcroFormAppearance.internal.getHeight=function(formObject){var result=0;return"object"===(void 0===formObject?"undefined":_typeof(formObject))&&(result=scale(formObject.Rect[3])),result},jsPDFAPI.addField=function(fieldObject){return initializeAcroForm.call(this),fieldObject instanceof AcroFormTextField?this.addTextField.call(this,fieldObject):fieldObject instanceof AcroFormChoiceField?this.addChoiceField.call(this,fieldObject):fieldObject instanceof AcroFormButton?this.addButton.call(this,fieldObject):(fieldObject instanceof AcroFormChildClass||fieldObject)&&putForm.call(this,fieldObject),fieldObject.page=scope.internal.getCurrentPageInfo().pageNumber,this},jsPDFAPI.addButton=function(opts){initializeAcroForm.call(this);var options=opts||new AcroFormField;options.FT="/Btn",options.Ff=calculateFlagsOnOptions(options.Ff,opts,scope.internal.getPDFVersion()),putForm.call(this,options)},jsPDFAPI.addTextField=function(opts){initializeAcroForm.call(this);var options=opts||new AcroFormField;options.FT="/Tx",options.Ff=calculateFlagsOnOptions(options.Ff,opts,scope.internal.getPDFVersion()),putForm.call(this,options)},jsPDFAPI.addChoiceField=function(opts){initializeAcroForm.call(this);var options=opts||new AcroFormField;options.FT="/Ch",options.Ff=calculateFlagsOnOptions(options.Ff,opts,scope.internal.getPDFVersion()),putForm.call(this,options)},"object"==(void 0===globalObj?"undefined":_typeof(globalObj))&&(globalObj.ChoiceField=AcroFormChoiceField,globalObj.ListBox=AcroFormListBox,globalObj.ComboBox=AcroFormComboBox,globalObj.EditBox=AcroFormEditBox,globalObj.Button=AcroFormButton,globalObj.PushButton=AcroFormPushButton,globalObj.RadioButton=AcroFormRadioButton,globalObj.CheckBox=AcroFormCheckBox,globalObj.TextField=AcroFormTextField,globalObj.PasswordField=AcroFormPasswordField,globalObj.AcroForm={Appearance:AcroFormAppearance}),jsPDFAPI.AcroFormChoiceField=AcroFormChoiceField,jsPDFAPI.AcroFormListBox=AcroFormListBox,jsPDFAPI.AcroFormComboBox=AcroFormComboBox,jsPDFAPI.AcroFormEditBox=AcroFormEditBox,jsPDFAPI.AcroFormButton=AcroFormButton,jsPDFAPI.AcroFormPushButton=AcroFormPushButton,jsPDFAPI.AcroFormRadioButton=AcroFormRadioButton,jsPDFAPI.AcroFormCheckBox=AcroFormCheckBox,jsPDFAPI.AcroFormTextField=AcroFormTextField,jsPDFAPI.AcroFormPasswordField=AcroFormPasswordField,jsPDFAPI.AcroForm={ChoiceField:AcroFormChoiceField,ListBox:AcroFormListBox,ComboBox:AcroFormComboBox,EditBox:AcroFormEditBox,Button:AcroFormButton,PushButton:AcroFormPushButton,RadioButton:AcroFormRadioButton,CheckBox:AcroFormCheckBox,TextField:AcroFormTextField,PasswordField:AcroFormPasswordField}}(jsPDF.API,"undefined"!=typeof window&&window||"undefined"!=typeof global&&global),jsPDF.API.addHTML=function(element,x,y,options,callback){if("undefined"==typeof html2canvas&&"undefined"==typeof rasterizeHTML)throw new Error("You need either https://github.com/niklasvh/html2canvas or https://github.com/cburgmer/rasterizeHTML.js");"number"!=typeof x&&(options=x,callback=y),"function"==typeof options&&(callback=options,options=null),"function"!=typeof callback&&(callback=function(){});var I=this.internal,K=I.scaleFactor,W=I.pageSize.getWidth(),H=I.pageSize.getHeight();if((options=options||{}).onrendered=function(obj){x=parseInt(x)||0,y=parseInt(y)||0;var dim=options.dim||{},margin=Object.assign({top:0,right:0,bottom:0,left:0,useFor:"content"},options.margin),h=dim.h||Math.min(H,obj.height/K),w=dim.w||Math.min(W,obj.width/K)-x,format=options.format||"JPEG",imageCompression=options.imageCompression||"SLOW";if(obj.height>H-margin.top-margin.bottom&&options.pagesplit){var cropArea=function(parmObj,parmX,parmY,parmWidth,parmHeight){var canvas=document.createElement("canvas");canvas.height=parmHeight,canvas.width=parmWidth;var ctx=canvas.getContext("2d");return ctx.mozImageSmoothingEnabled=!1,ctx.webkitImageSmoothingEnabled=!1,ctx.msImageSmoothingEnabled=!1,ctx.imageSmoothingEnabled=!1,ctx.fillStyle=options.backgroundColor||"#ffffff",ctx.fillRect(0,0,parmWidth,parmHeight),ctx.drawImage(parmObj,parmX,parmY,parmWidth,parmHeight,0,0,parmWidth,parmHeight),canvas},crop=function(){for(var width,height,cy=0,cx=0,position={},isOverWide=!1;;){var canvas;if(cx=0,position.top=0!==cy?margin.top:y,position.left=0!==cy?margin.left:x,isOverWide=(W-margin.left-margin.right)*K<obj.width,"content"===margin.useFor?0===cy?(width=Math.min((W-margin.left)*K,obj.width),height=Math.min((H-margin.top)*K,obj.height-cy)):(width=Math.min(W*K,obj.width),height=Math.min(H*K,obj.height-cy),position.top=0):(width=Math.min((W-margin.left-margin.right)*K,obj.width),height=Math.min((H-margin.bottom-margin.top)*K,obj.height-cy)),isOverWide)for(;;){"content"===margin.useFor&&(0===cx?width=Math.min((W-margin.left)*K,obj.width):(width=Math.min(W*K,obj.width-cx),position.left=0));var args=[canvas=cropArea(obj,cx,cy,width,height),position.left,position.top,canvas.width/K,canvas.height/K,format,null,imageCompression];if(this.addImage.apply(this,args),(cx+=width)>=obj.width)break;this.addPage()}else args=[canvas=cropArea(obj,0,cy,width,height),position.left,position.top,canvas.width/K,canvas.height/K,format,null,imageCompression],this.addImage.apply(this,args);if((cy+=height)>=obj.height)break;this.addPage()}callback(w,cy,null,args)}.bind(this);if("CANVAS"===obj.nodeName){var img=new Image;img.onload=crop,img.src=obj.toDataURL("image/png"),obj=img}else crop()}else{var alias=Math.random().toString(35),args=[obj,x,y,w,h,format,alias,imageCompression];this.addImage.apply(this,args),callback(w,h,alias,args)}}.bind(this),"undefined"!=typeof html2canvas&&!options.rstz)return html2canvas(element,options);if("undefined"!=typeof rasterizeHTML){var meth="drawDocument";return"string"==typeof element&&(meth=/^http/.test(element)?"drawURL":"drawHTML"),options.width=options.width||W*K,rasterizeHTML[meth](element,void 0,options).then((function(r){options.onrendered(r.image)}),(function(e){callback(null,e)}))}return null},
-/** @preserve
-   * jsPDF addImage plugin
-   * Copyright (c) 2012 Jason Siefken, https://github.com/siefkenj/
-   *               2013 Chris Dowling, https://github.com/gingerchris
-   *               2013 Trinh Ho, https://github.com/ineedfat
-   *               2013 Edwin Alejandro Perez, https://github.com/eaparango
-   *               2013 Norah Smith, https://github.com/burnburnrocket
-   *               2014 Diego Casorran, https://github.com/diegocr
-   *               2014 James Robb, https://github.com/jamesbrobb
-   *
-   * 
-   */
-function(jsPDFAPI){var imageFileTypeHeaders={PNG:[[137,80,78,71]],TIFF:[[77,77,0,42],[73,73,42,0]],JPEG:[[255,216,255,224,void 0,void 0,74,70,73,70,0],[255,216,255,225,void 0,void 0,69,120,105,102,0,0]],JPEG2000:[[0,0,0,12,106,80,32,32]],GIF87a:[[71,73,70,56,55,97]],GIF89a:[[71,73,70,56,57,97]],BMP:[[66,77],[66,65],[67,73],[67,80],[73,67],[80,84]]};jsPDFAPI.getImageFileTypeByImageData=function(imageData,fallbackFormat){var i,j;fallbackFormat=fallbackFormat||"UNKNOWN";var headerSchemata,compareResult,fileType,result="UNKNOWN";for(fileType in imageFileTypeHeaders)for(headerSchemata=imageFileTypeHeaders[fileType],i=0;i<headerSchemata.length;i+=1){for(compareResult=!0,j=0;j<headerSchemata[i].length;j+=1)if(void 0!==headerSchemata[i][j]&&headerSchemata[i][j]!==imageData.charCodeAt(j)){compareResult=!1;break}if(!0===compareResult){result=fileType;break}}return"UNKNOWN"===result&&"UNKNOWN"!==fallbackFormat&&(console.warn('FileType of Image not recognized. Processing image as "'+fallbackFormat+'".'),result=fallbackFormat),result};var putImage=function putImage(img){var objectNumber=this.internal.newObject(),out=this.internal.write,putStream=this.internal.putStream;if(img.n=objectNumber,out("<</Type /XObject"),out("/Subtype /Image"),out("/Width "+img.w),out("/Height "+img.h),img.cs===this.color_spaces.INDEXED?out("/ColorSpace [/Indexed /DeviceRGB "+(img.pal.length/3-1)+" "+("smask"in img?objectNumber+2:objectNumber+1)+" 0 R]"):(out("/ColorSpace /"+img.cs),img.cs===this.color_spaces.DEVICE_CMYK&&out("/Decode [1 0 1 0 1 0 1 0]")),out("/BitsPerComponent "+img.bpc),"f"in img&&out("/Filter /"+img.f),"dp"in img&&out("/DecodeParms <<"+img.dp+">>"),"trns"in img&&img.trns.constructor==Array){for(var trns="",i=0,len=img.trns.length;i<len;i++)trns+=img.trns[i]+" "+img.trns[i]+" ";out("/Mask ["+trns+"]")}if("smask"in img&&out("/SMask "+(objectNumber+1)+" 0 R"),out("/Length "+img.data.length+">>"),putStream(img.data),out("endobj"),"smask"in img){var dp="/Predictor "+img.p+" /Colors 1 /BitsPerComponent "+img.bpc+" /Columns "+img.w,smask={w:img.w,h:img.h,cs:"DeviceGray",bpc:img.bpc,dp:dp,data:img.smask};"f"in img&&(smask.f=img.f),putImage.call(this,smask)}img.cs===this.color_spaces.INDEXED&&(this.internal.newObject(),out("<< /Length "+img.pal.length+">>"),putStream(this.arrayBufferToBinaryString(new Uint8Array(img.pal))),out("endobj"))},putResourcesCallback=function(){var images=this.internal.collections.addImage_images;for(var i in images)putImage.call(this,images[i])},putXObjectsDictCallback=function(){var image,images=this.internal.collections.addImage_images,out=this.internal.write;for(var i in images)out("/I"+(image=images[i]).i,image.n,"0","R")},checkCompressValue=function(value){return value&&"string"==typeof value&&(value=value.toUpperCase()),value in jsPDFAPI.image_compression?value:jsPDFAPI.image_compression.NONE},getImages=function(){var images=this.internal.collections.addImage_images;return images||(this.internal.collections.addImage_images=images={},this.internal.events.subscribe("putResources",putResourcesCallback),this.internal.events.subscribe("putXobjectDict",putXObjectsDictCallback)),images},getImageIndex=function(images){var imageIndex=0;return images&&(imageIndex=Object.keys?Object.keys(images).length:function(o){var i=0;for(var e in o)o.hasOwnProperty(e)&&i++;return i}(images)),imageIndex},notDefined=function(value){return null==value||0===value.length},generateAliasFromData=function(data){return"string"==typeof data&&jsPDFAPI.sHashCode(data)},isImageTypeSupported=function(type){return"function"==typeof jsPDFAPI["process"+type.toUpperCase()]},isDOMElement=function(object){return"object"===(void 0===object?"undefined":_typeof(object))&&1===object.nodeType},createDataURIFromElement=function(element,format){if("IMG"===element.nodeName&&element.hasAttribute("src")){var src=""+element.getAttribute("src");if(0===src.indexOf("data:image/"))return src;!format&&/\.png(?:[?#].*)?$/i.test(src)&&(format="png")}if("CANVAS"===element.nodeName)var canvas=element;else{(canvas=document.createElement("canvas")).width=element.clientWidth||element.width,canvas.height=element.clientHeight||element.height;var ctx=canvas.getContext("2d");if(!ctx)throw"addImage requires canvas to be supported by browser.";ctx.drawImage(element,0,0,canvas.width,canvas.height)}return canvas.toDataURL("png"==(""+format).toLowerCase()?"image/png":"image/jpeg")},checkImagesForAlias=function(alias,images){var cached_info;if(images)for(var e in images)if(alias===images[e].alias){cached_info=images[e];break}return cached_info},determineWidthAndHeight=function(w,h,info){return w||h||(w=-96,h=-96),w<0&&(w=-1*info.w*72/w/this.internal.scaleFactor),h<0&&(h=-1*info.h*72/h/this.internal.scaleFactor),0===w&&(w=h*info.w/info.h),0===h&&(h=w*info.h/info.w),[w,h]},writeImageToPDF=function(x,y,w,h,info,index,images,rotation){var dims=determineWidthAndHeight.call(this,w,h,info),coord=this.internal.getCoordinateString,vcoord=this.internal.getVerticalCoordinateString;if(w=dims[0],h=dims[1],images[index]=info,rotation){rotation*=Math.PI/180;var c=Math.cos(rotation),s=Math.sin(rotation),f4=function(number){return number.toFixed(4)},rotationTransformationMatrix=[f4(c),f4(s),f4(-1*s),f4(c),0,0,"cm"]}this.internal.write("q"),rotation?(this.internal.write([1,"0","0",1,coord(x),vcoord(y+h),"cm"].join(" ")),this.internal.write(rotationTransformationMatrix.join(" ")),this.internal.write([coord(w),"0","0",coord(h),"0","0","cm"].join(" "))):this.internal.write([coord(w),"0","0",coord(h),coord(x),vcoord(y+h),"cm"].join(" ")),this.internal.write("/I"+info.i+" Do"),this.internal.write("Q")};jsPDFAPI.color_spaces={DEVICE_RGB:"DeviceRGB",DEVICE_GRAY:"DeviceGray",DEVICE_CMYK:"DeviceCMYK",CAL_GREY:"CalGray",CAL_RGB:"CalRGB",LAB:"Lab",ICC_BASED:"ICCBased",INDEXED:"Indexed",PATTERN:"Pattern",SEPARATION:"Separation",DEVICE_N:"DeviceN"},jsPDFAPI.decode={DCT_DECODE:"DCTDecode",FLATE_DECODE:"FlateDecode",LZW_DECODE:"LZWDecode",JPX_DECODE:"JPXDecode",JBIG2_DECODE:"JBIG2Decode",ASCII85_DECODE:"ASCII85Decode",ASCII_HEX_DECODE:"ASCIIHexDecode",RUN_LENGTH_DECODE:"RunLengthDecode",CCITT_FAX_DECODE:"CCITTFaxDecode"},jsPDFAPI.image_compression={NONE:"NONE",FAST:"FAST",MEDIUM:"MEDIUM",SLOW:"SLOW"},jsPDFAPI.sHashCode=function(str){return str=str||"",Array.prototype.reduce&&str.split("").reduce((function(a,b){return(a=(a<<5)-a+b.charCodeAt(0))&a}),0)},jsPDFAPI.isString=function(object){return"string"==typeof object},jsPDFAPI.validateStringAsBase64=function(possibleBase64String){var result=!0;return(possibleBase64String=possibleBase64String||"").length%4!=0&&(result=!1),!1===/[A-Za-z0-9\/]+/.test(possibleBase64String.substr(0,possibleBase64String.length-2))&&(result=!1),!1===/[A-Za-z0-9\/][A-Za-z0-9+\/]|[A-Za-z0-9+\/]=|==/.test(possibleBase64String.substr(-2))&&(result=!1),result},jsPDFAPI.extractInfoFromBase64DataURI=function(dataURI){return/^data:([\w]+?\/([\w]+?));base64,(.+)$/g.exec(dataURI)},jsPDFAPI.supportsArrayBuffer=function(){return"undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array},jsPDFAPI.isArrayBuffer=function(object){return!!this.supportsArrayBuffer()&&object instanceof ArrayBuffer},jsPDFAPI.isArrayBufferView=function(object){return!!this.supportsArrayBuffer()&&("undefined"!=typeof Uint32Array&&(object instanceof Int8Array||object instanceof Uint8Array||"undefined"!=typeof Uint8ClampedArray&&object instanceof Uint8ClampedArray||object instanceof Int16Array||object instanceof Uint16Array||object instanceof Int32Array||object instanceof Uint32Array||object instanceof Float32Array||object instanceof Float64Array))},jsPDFAPI.binaryStringToUint8Array=function(binary_string){for(var len=binary_string.length,bytes=new Uint8Array(len),i=0;i<len;i++)bytes[i]=binary_string.charCodeAt(i);return bytes},jsPDFAPI.arrayBufferToBinaryString=function(buffer){if("function"==typeof atob)return atob(this.arrayBufferToBase64(buffer));if("function"==typeof TextDecoder){var decoder=new TextDecoder("ascii");if("ascii"===decoder.encoding)return decoder.decode(buffer)}for(var data=this.isArrayBuffer(buffer)?buffer:new Uint8Array(buffer),binary_string="",slicesCount=Math.ceil(data.byteLength/20480),i=0;i<slicesCount;i++)binary_string+=String.fromCharCode.apply(null,data.slice(20480*i,20480*i+20480));return binary_string},jsPDFAPI.arrayBufferToBase64=function(arrayBuffer){for(var chunk,base64="",encodings="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",bytes=new Uint8Array(arrayBuffer),byteLength=bytes.byteLength,byteRemainder=byteLength%3,mainLength=byteLength-byteRemainder,i=0;i<mainLength;i+=3)base64+=encodings[(16515072&(chunk=bytes[i]<<16|bytes[i+1]<<8|bytes[i+2]))>>18]+encodings[(258048&chunk)>>12]+encodings[(4032&chunk)>>6]+encodings[63&chunk];return 1==byteRemainder?base64+=encodings[(252&(chunk=bytes[mainLength]))>>2]+encodings[(3&chunk)<<4]+"==":2==byteRemainder&&(base64+=encodings[(64512&(chunk=bytes[mainLength]<<8|bytes[mainLength+1]))>>10]+encodings[(1008&chunk)>>4]+encodings[(15&chunk)<<2]+"="),base64},jsPDFAPI.createImageInfo=function(data,wd,ht,cs,bpc,f,imageIndex,alias,dp,trns,pal,smask,p){var info={alias:alias,w:wd,h:ht,cs:cs,bpc:bpc,i:imageIndex,data:data};return f&&(info.f=f),dp&&(info.dp=dp),trns&&(info.trns=trns),pal&&(info.pal=pal),smask&&(info.smask=smask),p&&(info.p=p),info},jsPDFAPI.addImage=function(imageData,format,x,y,w,h,alias,compression,rotation){var tmpImageData="";if("string"!=typeof format){var tmp=h;h=w,w=y,y=x,x=format,format=tmp}if("object"===(void 0===imageData?"undefined":_typeof(imageData))&&!isDOMElement(imageData)&&"imageData"in imageData){var options=imageData;imageData=options.imageData,format=options.format||format,x=options.x||x||0,y=options.y||y||0,w=options.w||w,h=options.h||h,alias=options.alias||alias,compression=options.compression||compression,rotation=options.rotation||options.angle||rotation}if(isNaN(x)||isNaN(y))throw console.error("jsPDF.addImage: Invalid coordinates",arguments),new Error("Invalid coordinates passed to jsPDF.addImage");var info,dataAsBinaryString,images=getImages.call(this);if(!(info=checkImagesForAlias(imageData,images))&&(isDOMElement(imageData)&&(imageData=createDataURIFromElement(imageData,format)),notDefined(alias)&&(alias=generateAliasFromData(imageData)),!(info=checkImagesForAlias(alias,images)))){if(this.isString(imageData)&&(""!==(tmpImageData=this.convertStringToImageData(imageData))||void 0!==(tmpImageData=this.loadImageFile(imageData)))&&(imageData=tmpImageData),format=this.getImageFileTypeByImageData(imageData,format),!isImageTypeSupported(format))throw new Error("addImage does not support files of type '"+format+"', please ensure that a plugin for '"+format+"' support is added.");if(this.supportsArrayBuffer()&&(imageData instanceof Uint8Array||(dataAsBinaryString=imageData,imageData=this.binaryStringToUint8Array(imageData))),!(info=this["process"+format.toUpperCase()](imageData,getImageIndex(images),alias,checkCompressValue(compression),dataAsBinaryString)))throw new Error("An unkwown error occurred whilst processing the image")}return writeImageToPDF.call(this,x,y,w,h,info,info.i,images,rotation),this},jsPDFAPI.convertStringToImageData=function(stringData){var base64Info,imageData="";this.isString(stringData)&&(null!==(base64Info=this.extractInfoFromBase64DataURI(stringData))?jsPDFAPI.validateStringAsBase64(base64Info[3])&&(imageData=atob(base64Info[3])):jsPDFAPI.validateStringAsBase64(stringData)&&(imageData=atob(stringData)));return imageData};var readBytes=function(data,offset){return data.subarray(offset,offset+5)};jsPDFAPI.processJPEG=function(data,index,alias,compression,dataAsBinaryString,colorSpace){var dims,filter=this.decode.DCT_DECODE;if(!this.isString(data)&&!this.isArrayBuffer(data)&&!this.isArrayBufferView(data))return null;if(this.isString(data)&&(dims=function(imgData){var height;if(255===!imgData.charCodeAt(0)||216===!imgData.charCodeAt(1)||255===!imgData.charCodeAt(2)||224===!imgData.charCodeAt(3)||!imgData.charCodeAt(6)==="J".charCodeAt(0)||!imgData.charCodeAt(7)==="F".charCodeAt(0)||!imgData.charCodeAt(8)==="I".charCodeAt(0)||!imgData.charCodeAt(9)==="F".charCodeAt(0)||0===!imgData.charCodeAt(10))throw new Error("getJpegSize requires a binary string jpeg file");for(var blockLength=256*imgData.charCodeAt(4)+imgData.charCodeAt(5),i=4,len=imgData.length;i<len;){if(i+=blockLength,255!==imgData.charCodeAt(i))throw new Error("getJpegSize could not find the size of the image");if(192===imgData.charCodeAt(i+1)||193===imgData.charCodeAt(i+1)||194===imgData.charCodeAt(i+1)||195===imgData.charCodeAt(i+1)||196===imgData.charCodeAt(i+1)||197===imgData.charCodeAt(i+1)||198===imgData.charCodeAt(i+1)||199===imgData.charCodeAt(i+1))return height=256*imgData.charCodeAt(i+5)+imgData.charCodeAt(i+6),[256*imgData.charCodeAt(i+7)+imgData.charCodeAt(i+8),height,imgData.charCodeAt(i+9)];i+=2,blockLength=256*imgData.charCodeAt(i)+imgData.charCodeAt(i+1)}}(data)),this.isArrayBuffer(data)&&(data=new Uint8Array(data)),this.isArrayBufferView(data)&&(dims=function(data){if(65496!=(data[0]<<8|data[1]))throw new Error("Supplied data is not a JPEG");for(var bytes,len=data.length,block=(data[4]<<8)+data[5],pos=4;pos<len;){if(block=((bytes=readBytes(data,pos+=block))[2]<<8)+bytes[3],(192===bytes[1]||194===bytes[1])&&255===bytes[0]&&block>7)return{width:((bytes=readBytes(data,pos+5))[2]<<8)+bytes[3],height:(bytes[0]<<8)+bytes[1],numcomponents:bytes[4]};pos+=2}throw new Error("getJpegSizeFromBytes could not find the size of the image")}(data),data=dataAsBinaryString||this.arrayBufferToBinaryString(data)),void 0===colorSpace)switch(dims.numcomponents){case 1:colorSpace=this.color_spaces.DEVICE_GRAY;break;case 4:colorSpace=this.color_spaces.DEVICE_CMYK;break;default:colorSpace=this.color_spaces.DEVICE_RGB}return this.createImageInfo(data,dims.width,dims.height,colorSpace,8,filter,index,alias)},jsPDFAPI.processJPG=function(){return this.processJPEG.apply(this,arguments)},jsPDFAPI.loadImageFile=function(path,sync,callback){sync=sync||!0,callback=callback||function(){};Object.prototype.toString.call("undefined"!=typeof process?process:0);if(void 0!==("undefined"==typeof window?"undefined":_typeof(window))&&"object"===("undefined"==typeof location?"undefined":_typeof(location))&&"http"===location.protocol.substr(0,4))return function(url,sync,callback){var req=new XMLHttpRequest,byteArray=[],i=0,sanitizeUnicode=function(data){var dataLength=data.length,StringFromCharCode=String.fromCharCode;for(i=0;i<dataLength;i+=1)byteArray.push(StringFromCharCode(255&data.charCodeAt(i)));return byteArray.join("")};if(req.open("GET",url,!sync),req.overrideMimeType("text/plain; charset=x-user-defined"),!1===sync&&(req.onload=function(){return sanitizeUnicode(this.responseText)}),req.send(null),200===req.status)return sync?sanitizeUnicode(req.responseText):void 0;console.warn('Unable to load file "'+url+'"')}(path,sync)},jsPDFAPI.getImageProperties=function(imageData){var info,format,tmpImageData="";if(isDOMElement(imageData)&&(imageData=createDataURIFromElement(imageData)),this.isString(imageData)&&(""!==(tmpImageData=this.convertStringToImageData(imageData))||void 0!==(tmpImageData=this.loadImageFile(imageData)))&&(imageData=tmpImageData),format=this.getImageFileTypeByImageData(imageData),!isImageTypeSupported(format))throw new Error("addImage does not support files of type '"+format+"', please ensure that a plugin for '"+format+"' support is added.");if(this.supportsArrayBuffer()&&(imageData instanceof Uint8Array||(imageData=this.binaryStringToUint8Array(imageData))),!(info=this["process"+format.toUpperCase()](imageData)))throw new Error("An unkwown error occurred whilst processing the image");return{fileType:format,width:info.w,height:info.h,colorSpace:info.cs,compressionMode:info.f,bitsPerComponent:info.bpc}}}(jsPDF.API),function(jsPDFAPI){var annotationPlugin={annotations:[],f2:function(number){return number.toFixed(2)},notEmpty:function(obj){if(void 0!==obj&&""!=obj)return!0}};jsPDF.API.annotationPlugin=annotationPlugin,jsPDF.API.events.push(["addPage",function(info){this.annotationPlugin.annotations[info.pageNumber]=[]}]),jsPDFAPI.events.push(["putPage",function(info){for(var pageAnnos=this.annotationPlugin.annotations[info.pageNumber],found=!1,a=0;a<pageAnnos.length&&!found;a++){switch((anno=pageAnnos[a]).type){case"link":if(annotationPlugin.notEmpty(anno.options.url)||annotationPlugin.notEmpty(anno.options.pageNumber)){found=!0;break}case"reference":case"text":case"freetext":found=!0}}if(0!=found){this.internal.write("/Annots [");var f2=this.annotationPlugin.f2,k=this.internal.scaleFactor,pageHeight=this.internal.pageSize.getHeight(),pageInfo=this.internal.getPageInfo(info.pageNumber);for(a=0;a<pageAnnos.length;a++){var anno;switch((anno=pageAnnos[a]).type){case"reference":this.internal.write(" "+anno.object.objId+" 0 R ");break;case"text":var objText=this.internal.newAdditionalObject(),objPopup=this.internal.newAdditionalObject(),title=anno.title||"Note";line="<</Type /Annot /Subtype /Text "+(rect="/Rect ["+f2(anno.bounds.x*k)+" "+f2(pageHeight-(anno.bounds.y+anno.bounds.h)*k)+" "+f2((anno.bounds.x+anno.bounds.w)*k)+" "+f2((pageHeight-anno.bounds.y)*k)+"] ")+"/Contents ("+anno.contents+")",line+=" /Popup "+objPopup.objId+" 0 R",line+=" /P "+pageInfo.objId+" 0 R",line+=" /T ("+title+") >>",objText.content=line;var parent=objText.objId+" 0 R";line="<</Type /Annot /Subtype /Popup "+(rect="/Rect ["+f2((anno.bounds.x+30)*k)+" "+f2(pageHeight-(anno.bounds.y+anno.bounds.h)*k)+" "+f2((anno.bounds.x+anno.bounds.w+30)*k)+" "+f2((pageHeight-anno.bounds.y)*k)+"] ")+" /Parent "+parent,anno.open&&(line+=" /Open true"),line+=" >>",objPopup.content=line,this.internal.write(objText.objId,"0 R",objPopup.objId,"0 R");break;case"freetext":var rect="/Rect ["+f2(anno.bounds.x*k)+" "+f2((pageHeight-anno.bounds.y)*k)+" "+f2(anno.bounds.x+anno.bounds.w*k)+" "+f2(pageHeight-(anno.bounds.y+anno.bounds.h)*k)+"] ",color=anno.color||"#000000";line="<</Type /Annot /Subtype /FreeText "+rect+"/Contents ("+anno.contents+")",line+=" /DS(font: Helvetica,sans-serif 12.0pt; text-align:left; color:#"+color+")",line+=" /Border [0 0 0]",line+=" >>",this.internal.write(line);break;case"link":if(anno.options.name){var loc=this.annotations._nameMap[anno.options.name];anno.options.pageNumber=loc.page,anno.options.top=loc.y}else anno.options.top||(anno.options.top=0);rect="/Rect ["+f2(anno.x*k)+" "+f2((pageHeight-anno.y)*k)+" "+f2((anno.x+anno.w)*k)+" "+f2((pageHeight-(anno.y+anno.h))*k)+"] ";var line="";if(anno.options.url)line="<</Type /Annot /Subtype /Link "+rect+"/Border [0 0 0] /A <</S /URI /URI ("+anno.options.url+") >>";else if(anno.options.pageNumber){switch(line="<</Type /Annot /Subtype /Link "+rect+"/Border [0 0 0] /Dest ["+(info=this.internal.getPageInfo(anno.options.pageNumber)).objId+" 0 R",anno.options.magFactor=anno.options.magFactor||"XYZ",anno.options.magFactor){case"Fit":line+=" /Fit]";break;case"FitH":line+=" /FitH "+anno.options.top+"]";break;case"FitV":anno.options.left=anno.options.left||0,line+=" /FitV "+anno.options.left+"]";break;default:var top=f2((pageHeight-anno.options.top)*k);anno.options.left=anno.options.left||0,void 0===anno.options.zoom&&(anno.options.zoom=0),line+=" /XYZ "+anno.options.left+" "+top+" "+anno.options.zoom+"]"}}""!=line&&(line+=" >>",this.internal.write(line))}}this.internal.write("]")}}]),jsPDFAPI.createAnnotation=function(options){switch(options.type){case"link":this.link(options.bounds.x,options.bounds.y,options.bounds.w,options.bounds.h,options);break;case"text":case"freetext":this.annotationPlugin.annotations[this.internal.getCurrentPageInfo().pageNumber].push(options)}},jsPDFAPI.link=function(x,y,w,h,options){this.annotationPlugin.annotations[this.internal.getCurrentPageInfo().pageNumber].push({x:x,y:y,w:w,h:h,options:options,type:"link"})},jsPDFAPI.textWithLink=function(text,x,y,options){var width=this.getTextWidth(text),height=this.internal.getLineHeight()/this.internal.scaleFactor;return this.text(text,x,y),y+=.2*height,this.link(x,y-height,width,height,options),width},jsPDFAPI.getTextWidth=function(text){var fontSize=this.internal.getFontSize();return this.getStringUnitWidth(text)*fontSize/this.internal.scaleFactor},jsPDFAPI.getLineHeight=function(){return this.internal.getLineHeight()}}(jsPDF.API),function(jsPDFAPI){var arLangCodesKeys=Object.keys({ar:"Arabic (Standard)","ar-DZ":"Arabic (Algeria)","ar-BH":"Arabic (Bahrain)","ar-EG":"Arabic (Egypt)","ar-IQ":"Arabic (Iraq)","ar-JO":"Arabic (Jordan)","ar-KW":"Arabic (Kuwait)","ar-LB":"Arabic (Lebanon)","ar-LY":"Arabic (Libya)","ar-MA":"Arabic (Morocco)","ar-OM":"Arabic (Oman)","ar-QA":"Arabic (Qatar)","ar-SA":"Arabic (Saudi Arabia)","ar-SY":"Arabic (Syria)","ar-TN":"Arabic (Tunisia)","ar-AE":"Arabic (U.A.E.)","ar-YE":"Arabic (Yemen)",fa:"Persian","fa-IR":"Persian/Iran",ur:"Urdu"}),arabicSubst={1569:[65152],1570:[65153,65154,65153,65154],1571:[65155,65156,65155,65156],1572:[65157,65158],1573:[65159,65160,65159,65160],1574:[65161,65162,65163,65164],1575:[65165,65166,65165,65166],1576:[65167,65168,65169,65170],1577:[65171,65172],1578:[65173,65174,65175,65176],1579:[65177,65178,65179,65180],1580:[65181,65182,65183,65184],1581:[65185,65186,65187,65188],1582:[65189,65190,65191,65192],1583:[65193,65194,65193],1584:[65195,65196,65195],1585:[65197,65198,65197],1586:[65199,65200,65199],1587:[65201,65202,65203,65204],1588:[65205,65206,65207,65208],1589:[65209,65210,65211,65212],1590:[65213,65214,65215,65216],1591:[65217,65218,65219,65220],1592:[65221,65222,65223,65224],1593:[65225,65226,65227,65228],1594:[65229,65230,65231,65232],1601:[65233,65234,65235,65236],1602:[65237,65238,65239,65240],1603:[65241,65242,65243,65244],1604:[65245,65246,65247,65248],1605:[65249,65250,65251,65252],1606:[65253,65254,65255,65256],1607:[65257,65258,65259,65260],1608:[65261,65262,65261],1609:[65263,65264,64488,64489],1610:[65265,65266,65267,65268],1649:[64336,64337],1655:[64477],1657:[64358,64359,64360,64361],1658:[64350,64351,64352,64353],1659:[64338,64339,64340,64341],1662:[64342,64343,64344,64345],1663:[64354,64355,64356,64357],1664:[64346,64347,64348,64349],1667:[64374,64375,64376,64377],1668:[64370,64371,64372,64373],1670:[64378,64379,64380,64381],1671:[64382,64383,64384,64385],1672:[64392,64393],1676:[64388,64389],1677:[64386,64387],1678:[64390,64391],1681:[64396,64397],1688:[64394,64395,64394],1700:[64362,64363,64364,64365],1702:[64366,64367,64368,64369],1705:[64398,64399,64400,64401],1709:[64467,64468,64469,64470],1711:[64402,64403,64404,64405],1713:[64410,64411,64412,64413],1715:[64406,64407,64408,64409],1722:[64414,64415],1723:[64416,64417,64418,64419],1726:[64426,64427,64428,64429],1728:[64420,64421],1729:[64422,64423,64424,64425],1733:[64480,64481],1734:[64473,64474],1735:[64471,64472],1736:[64475,64476],1737:[64482,64483],1739:[64478,64479],1740:[64508,64509,64510,64511],1744:[64484,64485,64486,64487],1746:[64430,64431],1747:[64432,64433]},arabiclaasubst={1570:[65269,65270,65269,65270],1571:[65271,65272,65271,65272],1573:[65273,65274,65273,65274],1575:[65275,65276,65275,65276]},arabicorigsubst={1570:[65153,65154,65153,65154],1571:[65155,65156,65155,65156],1573:[65159,65160,65159,65160],1575:[65165,65166,65165,65166]},arabic_diacritics={1612:64606,1613:64607,1614:64608,1615:64609,1616:64610},alfletter=[1570,1571,1573,1575],endedletter=[1569,1570,1571,1572,1573,1575,1577,1583,1584,1585,1586,1608,1688];function isArabicLetter(letter){return void 0!==letter&&void 0!==arabicSubst[letter.charCodeAt(0)]}function isArabicEndLetter(letter){return void 0!==letter&&endedletter.indexOf(letter.charCodeAt(0))>=0}function isArabicAlfLetter(letter){return void 0!==letter&&alfletter.indexOf(letter.charCodeAt(0))>=0}function arabicLetterHasFinalForm(letter){return isArabicLetter(letter)&&arabicSubst[letter.charCodeAt(0)].length>=2}function getCorrectForm(currentChar,beforeChar,nextChar,arabicSubstition){return isArabicLetter(currentChar)?(arabicSubstition=arabicSubstition||{},arabicSubst=Object.assign(arabicSubst,arabicSubstition),!arabicLetterHasFinalForm(currentChar)||!isArabicLetter(beforeChar)&&!isArabicLetter(nextChar)||!isArabicLetter(nextChar)&&isArabicEndLetter(beforeChar)||isArabicEndLetter(currentChar)&&!isArabicLetter(beforeChar)||isArabicEndLetter(currentChar)&&isArabicAlfLetter(beforeChar)||isArabicEndLetter(currentChar)&&isArabicEndLetter(beforeChar)?(arabicSubst=Object.assign(arabicSubst,arabicorigsubst),0):isArabicLetter(letter=currentChar)&&4==arabicSubst[letter.charCodeAt(0)].length&&isArabicLetter(beforeChar)&&!isArabicEndLetter(beforeChar)&&isArabicLetter(nextChar)&&arabicLetterHasFinalForm(nextChar)?(arabicSubst=Object.assign(arabicSubst,arabicorigsubst),3):isArabicEndLetter(currentChar)||!isArabicLetter(nextChar)?(arabicSubst=Object.assign(arabicSubst,arabicorigsubst),1):(arabicSubst=Object.assign(arabicSubst,arabicorigsubst),2)):-1;var letter}var processArabic=jsPDFAPI.processArabic=function(text,reverse){text=text||"",reverse=reverse||!1;var resultingLetter,letter,character,result="",i=0,position=0,currentLetter="",prevLetter="",nextLetter="";for(i=0;i<text.length;i+=1)currentLetter=text[i],prevLetter=text[i-1],nextLetter=text[i+1],isArabicLetter(currentLetter)?void 0!==prevLetter&&1604===prevLetter.charCodeAt(0)&&isArabicAlfLetter(currentLetter)?(position=getCorrectForm(currentLetter,text[i-2],text[i+1],arabiclaasubst),resultingLetter=String.fromCharCode(arabiclaasubst[currentLetter.charCodeAt(0)][position]),result=result.substr(0,result.length-1)+resultingLetter):void 0!==prevLetter&&1617===prevLetter.charCodeAt(0)&&(void 0!==(letter=currentLetter)&&void 0!==arabic_diacritics[letter.charCodeAt(0)])?(position=getCorrectForm(currentLetter,text[i-2],text[i+1],arabicorigsubst),resultingLetter=String.fromCharCode(arabic_diacritics[currentLetter.charCodeAt(0)][position]),result=result.substr(0,result.length-1)+resultingLetter):(position=getCorrectForm(currentLetter,prevLetter,nextLetter,arabicorigsubst),result+=String.fromCharCode(arabicSubst[currentLetter.charCodeAt(0)][position])):result+=reverse?{"(":")",")":"("}[character=currentLetter]||character:currentLetter;return reverse?result.split("").reverse().join(""):result};jsPDFAPI.events.push(["preProcessText",function(args){var text=args.text,options=(args.x,args.y,args.options||{}),lang=(args.mutex,options.lang),tmpText=[];if(arLangCodesKeys.indexOf(lang)>=0){if("[object Array]"===Object.prototype.toString.call(text)){var i=0;for(tmpText=[],i=0;i<text.length;i+=1)"[object Array]"===Object.prototype.toString.call(text[i])?tmpText.push([processArabic(text[i][0],!0),text[i][1],text[i][2]]):tmpText.push([processArabic(text[i],!0)]);args.text=tmpText}else args.text=processArabic(text,!0);void 0===options.charSpace&&(args.options.charSpace=0),!0===options.R2L&&(args.options.R2L=!1)}}])}(jsPDF.API),function(jsPDFAPI){jsPDFAPI.autoPrint=function(options){var refAutoPrintTag;if((options=options||{}).variant=options.variant||"non-conform","javascript"===options.variant)this.addJS("print({});");else this.internal.events.subscribe("postPutResources",(function(){refAutoPrintTag=this.internal.newObject(),this.internal.out("<<"),this.internal.out("/S /Named"),this.internal.out("/Type /Action"),this.internal.out("/N /Print"),this.internal.out(">>"),this.internal.out("endobj")})),this.internal.events.subscribe("putCatalog",(function(){this.internal.out("/OpenAction "+refAutoPrintTag+" 0 R")}));return this}}(jsPDF.API),function(jsPDFAPI){jsPDFAPI.events.push(["initialized",function(){this.canvas.pdf=this}]),jsPDFAPI.canvas={getContext:function(name){return this.pdf.context2d._canvas=this,this.pdf.context2d},childNodes:[]},Object.defineProperty(jsPDFAPI.canvas,"width",{get:function(){return this._width},set:function(value){this._width=value,this.getContext("2d").pageWrapX=value+1}}),Object.defineProperty(jsPDFAPI.canvas,"height",{get:function(){return this._height},set:function(value){this._height=value,this.getContext("2d").pageWrapY=value+1}})}(jsPDF.API),function(jsPDFAPI){var fontName,fontSize,fontStyle,headerFunction,lastCellPos={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},pages=1,setLastCellPosition=function(x,y,w,h,ln){lastCellPos={x:x,y:y,w:w,h:h,ln:ln}},getLastCellPosition=function(){return lastCellPos},NO_MARGINS={left:0,top:0,bottom:0};jsPDFAPI.setHeaderFunction=function(func){headerFunction=func},jsPDFAPI.getTextDimensions=function(txt){fontName=this.internal.getFont().fontName,fontSize=this.table_font_size||this.internal.getFontSize(),fontStyle=this.internal.getFont().fontStyle;var dimensions,text,px2pt=19.049976/25.4;(text=document.createElement("font")).id="jsPDFCell";try{text.style.fontStyle=fontStyle}catch(e){text.style.fontWeight=fontStyle}text.style.fontSize=fontSize+"pt",text.style.fontFamily=fontName;try{text.textContent=txt}catch(e){text.innerText=txt}return document.body.appendChild(text),dimensions={w:(text.offsetWidth+1)*px2pt,h:(text.offsetHeight+1)*px2pt},document.body.removeChild(text),dimensions},jsPDFAPI.cellAddPage=function(){var margins=this.margins||NO_MARGINS;this.addPage(),setLastCellPosition(margins.left,margins.top,void 0,void 0),pages+=1},jsPDFAPI.cellInitialize=function(){lastCellPos={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},pages=1},jsPDFAPI.cell=function(x,y,w,h,txt,ln,align){var curCell=getLastCellPosition(),pgAdded=!1;if(void 0!==curCell.ln)if(curCell.ln===ln)x=curCell.x+curCell.w,y=curCell.y;else{var margins=this.margins||NO_MARGINS;curCell.y+curCell.h+h+13>=this.internal.pageSize.getHeight()-margins.bottom&&(this.cellAddPage(),pgAdded=!0,this.printHeaders&&this.tableHeaderRow&&this.printHeaderRow(ln,!0)),y=getLastCellPosition().y+getLastCellPosition().h,pgAdded&&(y=23)}if(void 0!==txt[0])if(this.printingHeaderRow?this.rect(x,y,w,h,"FD"):this.rect(x,y,w,h),"right"===align){txt instanceof Array||(txt=[txt]);for(var i=0;i<txt.length;i++){var currentLine=txt[i],textSize=this.getStringUnitWidth(currentLine)*this.internal.getFontSize();this.text(currentLine,x+w-textSize-3,y+this.internal.getLineHeight()*(i+1))}}else this.text(txt,x+3,y+this.internal.getLineHeight());return setLastCellPosition(x,y,w,h,ln),this},jsPDFAPI.arrayMax=function(array,comparisonFn){var i,ln,item,max=array[0];for(i=0,ln=array.length;i<ln;i+=1)item=array[i],comparisonFn?-1===comparisonFn(max,item)&&(max=item):item>max&&(max=item);return max},jsPDFAPI.table=function(x,y,data,headers,config){if(!data)throw"No data for PDF table";var header,i,ln,cln,columnData,column,j,model,jln,func,headerNames=[],headerPrompts=[],columnMatrix={},columnWidths={},columnMinWidths=[],tableHeaderConfigs=[],autoSize=!1,printHeaders=!0,fontSize=12,margins=NO_MARGINS;if(margins.width=this.internal.pageSize.getWidth(),config&&(!0===config.autoSize&&(autoSize=!0),!1===config.printHeaders&&(printHeaders=!1),config.fontSize&&(fontSize=config.fontSize),config.css&&void 0!==config.css["font-size"]&&(fontSize=16*config.css["font-size"]),config.margins&&(margins=config.margins)),this.lnMod=0,lastCellPos={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},pages=1,this.printHeaders=printHeaders,this.margins=margins,this.setFontSize(fontSize),this.table_font_size=fontSize,null==headers)headerNames=Object.keys(data[0]);else if(headers[0]&&"string"!=typeof headers[0]){for(i=0,ln=headers.length;i<ln;i+=1)header=headers[i],headerNames.push(header.name),headerPrompts.push(header.prompt),columnWidths[header.name]=.7499990551181103*header.width}else headerNames=headers;if(autoSize)for(func=function(rec){return rec[header]},i=0,ln=headerNames.length;i<ln;i+=1){for(columnMatrix[header=headerNames[i]]=data.map(func),columnMinWidths.push(this.getTextDimensions(headerPrompts[i]||header).w),j=0,cln=(column=columnMatrix[header]).length;j<cln;j+=1)columnData=column[j],columnMinWidths.push(this.getTextDimensions(columnData).w);columnWidths[header]=jsPDFAPI.arrayMax(columnMinWidths),columnMinWidths=[]}if(printHeaders){var lineHeight=this.calculateLineHeight(headerNames,columnWidths,headerPrompts.length?headerPrompts:headerNames);for(i=0,ln=headerNames.length;i<ln;i+=1)header=headerNames[i],tableHeaderConfigs.push([x,y,columnWidths[header],lineHeight,String(headerPrompts.length?headerPrompts[i]:header)]);this.setTableHeaderRow(tableHeaderConfigs),this.printHeaderRow(1,!1)}for(i=0,ln=data.length;i<ln;i+=1){for(model=data[i],lineHeight=this.calculateLineHeight(headerNames,columnWidths,model),j=0,jln=headerNames.length;j<jln;j+=1)header=headerNames[j],this.cell(x,y,columnWidths[header],lineHeight,model[header],i+2,header.align)}return this.lastCellPos=lastCellPos,this.table_x=x,this.table_y=y,this},jsPDFAPI.calculateLineHeight=function(headerNames,columnWidths,model){for(var header,lineHeight=0,j=0;j<headerNames.length;j++){model[header=headerNames[j]]=this.splitTextToSize(String(model[header]),columnWidths[header]-3);var h=this.internal.getLineHeight()*model[header].length+3;h>lineHeight&&(lineHeight=h)}return lineHeight},jsPDFAPI.setTableHeaderRow=function(config){this.tableHeaderRow=config},jsPDFAPI.printHeaderRow=function(lineNumber,new_page){if(!this.tableHeaderRow)throw"Property tableHeaderRow does not exist.";var tableHeaderCell,tmpArray,i,ln;if(this.printingHeaderRow=!0,void 0!==headerFunction){var position=headerFunction(this,pages);setLastCellPosition(position[0],position[1],position[2],position[3],-1)}this.setFontStyle("bold");var tempHeaderConf=[];for(i=0,ln=this.tableHeaderRow.length;i<ln;i+=1)this.setFillColor(200,200,200),tableHeaderCell=this.tableHeaderRow[i],new_page&&(this.margins.top=13,tableHeaderCell[1]=this.margins&&this.margins.top||0,tempHeaderConf.push(tableHeaderCell)),tmpArray=[].concat(tableHeaderCell),this.cell.apply(this,tmpArray.concat(lineNumber));tempHeaderConf.length>0&&this.setTableHeaderRow(tempHeaderConf),this.setFontStyle("normal"),this.printingHeaderRow=!1}}(jsPDF.API),function(jsPDFAPI){jsPDFAPI.events.push(["initialized",function(){this.context2d.pdf=this,this.context2d.internal.pdf=this,this.context2d.ctx=new context,this.context2d.ctxStack=[],this.context2d.path=[]}]),jsPDFAPI.context2d={pageWrapXEnabled:!1,pageWrapYEnabled:!1,pageWrapX:9999999,pageWrapY:9999999,ctx:new context,f2:function(number){return number.toFixed(2)},fillRect:function(x,y,w,h){if(!this._isFillTransparent()){x=this._wrapX(x),y=this._wrapY(y);var xRect=this._matrix_map_rect(this.ctx._transform,{x:x,y:y,w:w,h:h});this.pdf.rect(xRect.x,xRect.y,xRect.w,xRect.h,"f")}},strokeRect:function(x,y,w,h){if(!this._isStrokeTransparent()){x=this._wrapX(x),y=this._wrapY(y);var xRect=this._matrix_map_rect(this.ctx._transform,{x:x,y:y,w:w,h:h});this.pdf.rect(xRect.x,xRect.y,xRect.w,xRect.h,"s")}},clearRect:function(x,y,w,h){if(!this.ctx.ignoreClearRect){x=this._wrapX(x),y=this._wrapY(y);var xRect=this._matrix_map_rect(this.ctx._transform,{x:x,y:y,w:w,h:h});this.save(),this.setFillStyle("#ffffff"),this.pdf.rect(xRect.x,xRect.y,xRect.w,xRect.h,"f"),this.restore()}},save:function(){this.ctx._fontSize=this.pdf.internal.getFontSize();var ctx=new context;ctx.copy(this.ctx),this.ctxStack.push(this.ctx),this.ctx=ctx},restore:function(){this.ctx=this.ctxStack.pop(),this.setFillStyle(this.ctx.fillStyle),this.setStrokeStyle(this.ctx.strokeStyle),this.setFont(this.ctx.font),this.pdf.setFontSize(this.ctx._fontSize),this.setLineCap(this.ctx.lineCap),this.setLineWidth(this.ctx.lineWidth),this.setLineJoin(this.ctx.lineJoin)},rect:function(x,y,w,h){this.moveTo(x,y),this.lineTo(x+w,y),this.lineTo(x+w,y+h),this.lineTo(x,y+h),this.lineTo(x,y),this.closePath()},beginPath:function(){this.path=[]},closePath:function(){this.path.push({type:"close"})},_getRGBA:function(style){var r,g,b,a,rgbColor=new RGBColor(style);if(!style)return{r:0,g:0,b:0,a:0,style:style};if(this.internal.rxTransparent.test(style))r=0,g=0,b=0,a=0;else{var m=this.internal.rxRgb.exec(style);null!=m?(r=parseInt(m[1]),g=parseInt(m[2]),b=parseInt(m[3]),a=1):null!=(m=this.internal.rxRgba.exec(style))?(r=parseInt(m[1]),g=parseInt(m[2]),b=parseInt(m[3]),a=parseFloat(m[4])):(a=1,"#"!=style.charAt(0)&&(style=rgbColor.ok?rgbColor.toHex():"#000000"),4===style.length?(r=style.substring(1,2),r+=r,g=style.substring(2,3),g+=g,b=style.substring(3,4),b+=b):(r=style.substring(1,3),g=style.substring(3,5),b=style.substring(5,7)),r=parseInt(r,16),g=parseInt(g,16),b=parseInt(b,16))}return{r:r,g:g,b:b,a:a,style:style}},setFillStyle:function(style){var rgba=this._getRGBA(style);this.ctx.fillStyle=style,this.ctx._isFillTransparent=0===rgba.a,this.ctx._fillOpacity=rgba.a,this.pdf.setFillColor(rgba.r,rgba.g,rgba.b,{a:rgba.a}),this.pdf.setTextColor(rgba.r,rgba.g,rgba.b,{a:rgba.a})},setStrokeStyle:function(style){var rgba=this._getRGBA(style);this.ctx.strokeStyle=rgba.style,this.ctx._isStrokeTransparent=0===rgba.a,this.ctx._strokeOpacity=rgba.a,0===rgba.a?this.pdf.setDrawColor(255,255,255):(rgba.a,this.pdf.setDrawColor(rgba.r,rgba.g,rgba.b))},fillText:function(text,x,y,maxWidth){if(!this._isFillTransparent()){x=this._wrapX(x),y=this._wrapY(y);var xpt=this._matrix_map_point(this.ctx._transform,[x,y]);x=xpt[0],y=xpt[1];var degs=57.2958*this._matrix_rotation(this.ctx._transform);if(this.ctx._clip_path.length>0){var lines;(lines=window.outIntercept?"group"===window.outIntercept.type?window.outIntercept.stream:window.outIntercept:this.internal.getCurrentPage()).push("q");var origPath=this.path;this.path=this.ctx._clip_path,this.ctx._clip_path=[],this._fill(null,!0),this.ctx._clip_path=this.path,this.path=origPath}var scale=1;try{scale=this._matrix_decompose(this._getTransform()).scale[0]}catch(e){console.warn(e)}if(scale<.01)this.pdf.text(text,x,this._getBaseline(y),null,degs);else{var oldSize=this.pdf.internal.getFontSize();this.pdf.setFontSize(oldSize*scale),this.pdf.text(text,x,this._getBaseline(y),null,degs),this.pdf.setFontSize(oldSize)}this.ctx._clip_path.length>0&&lines.push("Q")}},strokeText:function(text,x,y,maxWidth){if(!this._isStrokeTransparent()){x=this._wrapX(x),y=this._wrapY(y);var xpt=this._matrix_map_point(this.ctx._transform,[x,y]);x=xpt[0],y=xpt[1];var degs=57.2958*this._matrix_rotation(this.ctx._transform);if(this.ctx._clip_path.length>0){var lines;(lines=window.outIntercept?"group"===window.outIntercept.type?window.outIntercept.stream:window.outIntercept:this.internal.getCurrentPage()).push("q");var origPath=this.path;this.path=this.ctx._clip_path,this.ctx._clip_path=[],this._fill(null,!0),this.ctx._clip_path=this.path,this.path=origPath}var scale=1;try{scale=this._matrix_decompose(this._getTransform()).scale[0]}catch(e){console.warn(e)}if(1===scale)this.pdf.text(text,x,this._getBaseline(y),{stroke:!0},degs);else{var oldSize=this.pdf.internal.getFontSize();this.pdf.setFontSize(oldSize*scale),this.pdf.text(text,x,this._getBaseline(y),{stroke:!0},degs),this.pdf.setFontSize(oldSize)}this.ctx._clip_path.length>0&&lines.push("Q")}},setFont:function(font){if(this.ctx.font=font,null!=(m=/\s*(\w+)\s+(\w+)\s+(\w+)\s+([\d\.]+)(px|pt|em)\s+(.*)?/.exec(font))){var fontStyle=m[1],fontWeight=(m[2],m[3]),fontSize=m[4],fontSizeUnit=m[5],fontFamily=m[6];fontSize="px"===fontSizeUnit?Math.floor(parseFloat(fontSize)):"em"===fontSizeUnit?Math.floor(parseFloat(fontSize)*this.pdf.getFontSize()):Math.floor(parseFloat(fontSize)),this.pdf.setFontSize(fontSize),"bold"===fontWeight||"700"===fontWeight?this.pdf.setFontStyle("bold"):"italic"===fontStyle?this.pdf.setFontStyle("italic"):this.pdf.setFontStyle("normal"),style="bold"===fontWeight||"700"===fontWeight?"italic"===fontStyle?"bolditalic":"bold":"italic"===fontStyle?"italic":"normal";for(var parts=fontFamily.toLowerCase().split(/\s*,\s*/),jsPdfFontName="Times",i=0;i<parts.length;i++){if(void 0!==this.pdf.internal.getFont(parts[i],style,{noFallback:!0,disableWarning:!0})){jsPdfFontName=parts[i];break}if("bolditalic"===style&&void 0!==this.pdf.internal.getFont(parts[i],"bold",{noFallback:!0,disableWarning:!0}))jsPdfFontName=parts[i],style="bold";else if(void 0!==this.pdf.internal.getFont(parts[i],"normal",{noFallback:!0,disableWarning:!0})){jsPdfFontName=parts[i],style="normal";break}}this.pdf.setFont(jsPdfFontName,style)}else{var m=/\s*(\d+)(pt|px|em)\s+([\w "]+)\s*([\w "]+)?/.exec(font);if(null!=m){var style,size=m[1],name=(m[2],m[3]);(style=m[4])||(style="normal"),size="em"===fontSizeUnit?Math.floor(parseFloat(fontSize)*this.pdf.getFontSize()):Math.floor(parseFloat(size)),this.pdf.setFontSize(size),this.pdf.setFont(name,style)}}},setTextBaseline:function(baseline){this.ctx.textBaseline=baseline},getTextBaseline:function(){return this.ctx.textBaseline},setTextAlign:function(align){this.ctx.textAlign=align},getTextAlign:function(){return this.ctx.textAlign},setLineWidth:function(width){this.ctx.lineWidth=width,this.pdf.setLineWidth(width)},setLineCap:function(style){this.ctx.lineCap=style,this.pdf.setLineCap(style)},setLineJoin:function(style){this.ctx.lineJoin=style,this.pdf.setLineJoin(style)},moveTo:function(x,y){x=this._wrapX(x),y=this._wrapY(y);var xpt=this._matrix_map_point(this.ctx._transform,[x,y]),obj={type:"mt",x:x=xpt[0],y:y=xpt[1]};this.path.push(obj)},_wrapX:function(x){return this.pageWrapXEnabled?x%this.pageWrapX:x},_wrapY:function(y){return this.pageWrapYEnabled?(this._gotoPage(this._page(y)),(y-this.lastBreak)%this.pageWrapY):y},transform:function(a,b,c,d,e,f){this.ctx._transform=this._matrix_multiply(this.ctx._transform,[a,b,c,d,e,f])},setTransform:function(a,b,c,d,e,f){this.ctx._transform=[a,b,c,d,e,f]},_getTransform:function(){return this.ctx._transform},lastBreak:0,pageBreaks:[],_page:function(y){if(this.pageWrapYEnabled){this.lastBreak=0;for(var manualBreaks=0,autoBreaks=0,i=0;i<this.pageBreaks.length;i++)if(y>=this.pageBreaks[i]){manualBreaks++,0===this.lastBreak&&autoBreaks++;var spaceBetweenLastBreak=this.pageBreaks[i]-this.lastBreak;this.lastBreak=this.pageBreaks[i],autoBreaks+=Math.floor(spaceBetweenLastBreak/this.pageWrapY)}if(0===this.lastBreak)autoBreaks+=Math.floor(y/this.pageWrapY)+1;return autoBreaks+manualBreaks}return this.pdf.internal.getCurrentPageInfo().pageNumber},_gotoPage:function(pageOneBased){},lineTo:function(x,y){x=this._wrapX(x),y=this._wrapY(y);var xpt=this._matrix_map_point(this.ctx._transform,[x,y]),obj={type:"lt",x:x=xpt[0],y:y=xpt[1]};this.path.push(obj)},bezierCurveTo:function(x1,y1,x2,y2,x,y){var xpt;x1=this._wrapX(x1),y1=this._wrapY(y1),x2=this._wrapX(x2),y2=this._wrapY(y2),x=this._wrapX(x),y=this._wrapY(y),x=(xpt=this._matrix_map_point(this.ctx._transform,[x,y]))[0],y=xpt[1];var obj={type:"bct",x1:x1=(xpt=this._matrix_map_point(this.ctx._transform,[x1,y1]))[0],y1:y1=xpt[1],x2:x2=(xpt=this._matrix_map_point(this.ctx._transform,[x2,y2]))[0],y2:y2=xpt[1],x:x,y:y};this.path.push(obj)},quadraticCurveTo:function(x1,y1,x,y){var xpt;x1=this._wrapX(x1),y1=this._wrapY(y1),x=this._wrapX(x),y=this._wrapY(y),x=(xpt=this._matrix_map_point(this.ctx._transform,[x,y]))[0],y=xpt[1];var obj={type:"qct",x1:x1=(xpt=this._matrix_map_point(this.ctx._transform,[x1,y1]))[0],y1:y1=xpt[1],x:x,y:y};this.path.push(obj)},arc:function(x,y,radius,startAngle,endAngle,anticlockwise){if(x=this._wrapX(x),y=this._wrapY(y),!this._matrix_is_identity(this.ctx._transform)){var xpt=this._matrix_map_point(this.ctx._transform,[x,y]);x=xpt[0],y=xpt[1];var x_radPt0=this._matrix_map_point(this.ctx._transform,[0,0]),x_radPt=this._matrix_map_point(this.ctx._transform,[0,radius]);radius=Math.sqrt(Math.pow(x_radPt[0]-x_radPt0[0],2)+Math.pow(x_radPt[1]-x_radPt0[1],2))}var obj={type:"arc",x:x,y:y,radius:radius,startAngle:startAngle,endAngle:endAngle,anticlockwise:anticlockwise};this.path.push(obj)},drawImage:function(img,x,y,w,h,x2,y2,w2,h2){void 0!==x2&&(x=x2,y=y2,w=w2,h=h2),x=this._wrapX(x),y=this._wrapY(y);var format,xRect=this._matrix_map_rect(this.ctx._transform,{x:x,y:y,w:w,h:h}),m=(this._matrix_map_rect(this.ctx._transform,{x:x2,y:y2,w:w2,h:h2}),/data:image\/(\w+).*/i.exec(img));format=null!=m?m[1]:"png",this.pdf.addImage(img,format,xRect.x,xRect.y,xRect.w,xRect.h)},_matrix_multiply:function(m2,m1){var sx=m1[0],shy=m1[1],shx=m1[2],sy=m1[3],tx=m1[4],ty=m1[5],t0=sx*m2[0]+shy*m2[2],t2=shx*m2[0]+sy*m2[2],t4=tx*m2[0]+ty*m2[2]+m2[4];return shy=sx*m2[1]+shy*m2[3],sy=shx*m2[1]+sy*m2[3],ty=tx*m2[1]+ty*m2[3]+m2[5],[sx=t0,shy,shx=t2,sy,tx=t4,ty]},_matrix_rotation:function(m){return Math.atan2(m[2],m[0])},_matrix_decompose:function(matrix){var a=matrix[0],b=matrix[1],c=matrix[2],d=matrix[3],scaleX=Math.sqrt(a*a+b*b),shear=(a/=scaleX)*c+(b/=scaleX)*d;c-=a*shear,d-=b*shear;var scaleY=Math.sqrt(c*c+d*d);return shear/=scaleY,a*(d/=scaleY)<b*(c/=scaleY)&&(a=-a,b=-b,shear=-shear,scaleX=-scaleX),{scale:[scaleX,0,0,scaleY,0,0],translate:[1,0,0,1,matrix[4],matrix[5]],rotate:[a,b,-b,a,0,0],skew:[1,0,shear,1,0,0]}},_matrix_map_point:function(m1,pt){var sx=m1[0],shy=m1[1],shx=m1[2],sy=m1[3],tx=m1[4],ty=m1[5],px=pt[0],py=pt[1];return[px*sx+py*shx+tx,px*shy+py*sy+ty]},_matrix_map_point_obj:function(m1,pt){var xpt=this._matrix_map_point(m1,[pt.x,pt.y]);return{x:xpt[0],y:xpt[1]}},_matrix_map_rect:function(m1,rect){var p1=this._matrix_map_point(m1,[rect.x,rect.y]),p2=this._matrix_map_point(m1,[rect.x+rect.w,rect.y+rect.h]);return{x:p1[0],y:p1[1],w:p2[0]-p1[0],h:p2[1]-p1[1]}},_matrix_is_identity:function(m1){return 1==m1[0]&&(0==m1[1]&&(0==m1[2]&&(1==m1[3]&&(0==m1[4]&&0==m1[5]))))},rotate:function(angle){var matrix=[Math.cos(angle),Math.sin(angle),-Math.sin(angle),Math.cos(angle),0,0];this.ctx._transform=this._matrix_multiply(this.ctx._transform,matrix)},scale:function(sx,sy){var matrix=[sx,0,0,sy,0,0];this.ctx._transform=this._matrix_multiply(this.ctx._transform,matrix)},translate:function(x,y){var matrix=[1,0,0,1,x,y];this.ctx._transform=this._matrix_multiply(this.ctx._transform,matrix)},stroke:function(){if(this.ctx._clip_path.length>0){var lines;(lines=window.outIntercept?"group"===window.outIntercept.type?window.outIntercept.stream:window.outIntercept:this.internal.getCurrentPage()).push("q");var origPath=this.path;this.path=this.ctx._clip_path,this.ctx._clip_path=[],this._stroke(!0),this.ctx._clip_path=this.path,this.path=origPath,this._stroke(!1),lines.push("Q")}else this._stroke(!1)},_stroke:function(isClip){if(isClip||!this._isStrokeTransparent()){for(var moves=[],xPath=this.path,i=0;i<xPath.length;i++){var pt=xPath[i];switch(pt.type){case"mt":moves.push({start:pt,deltas:[],abs:[]});break;case"lt":var delta=[pt.x-xPath[i-1].x,pt.y-xPath[i-1].y];moves[moves.length-1].deltas.push(delta),moves[moves.length-1].abs.push(pt);break;case"bct":delta=[pt.x1-xPath[i-1].x,pt.y1-xPath[i-1].y,pt.x2-xPath[i-1].x,pt.y2-xPath[i-1].y,pt.x-xPath[i-1].x,pt.y-xPath[i-1].y];moves[moves.length-1].deltas.push(delta);break;case"qct":var x1=xPath[i-1].x+2/3*(pt.x1-xPath[i-1].x),y1=xPath[i-1].y+2/3*(pt.y1-xPath[i-1].y),x2=pt.x+2/3*(pt.x1-pt.x),y2=pt.y+2/3*(pt.y1-pt.y),x3=pt.x,y3=pt.y;delta=[x1-xPath[i-1].x,y1-xPath[i-1].y,x2-xPath[i-1].x,y2-xPath[i-1].y,x3-xPath[i-1].x,y3-xPath[i-1].y];moves[moves.length-1].deltas.push(delta);break;case"arc":0==moves.length&&moves.push({start:{x:0,y:0},deltas:[],abs:[]}),moves[moves.length-1].arc=!0,Array.isArray(moves[moves.length-1].abs)&&moves[moves.length-1].abs.push(pt)}}for(i=0;i<moves.length;i++){var style;if(style=i==moves.length-1?"s":null,moves[i].arc)for(var arcs=moves[i].abs,ii=0;ii<arcs.length;ii++){var arc=arcs[ii],start=360*arc.startAngle/(2*Math.PI),end=360*arc.endAngle/(2*Math.PI),x=arc.x,y=arc.y;this.internal.arc2(this,x,y,arc.radius,start,end,arc.anticlockwise,style,isClip)}else{x=moves[i].start.x,y=moves[i].start.y;isClip?(this.pdf.lines(moves[i].deltas,x,y,null,null),this.pdf.clip_fixed()):this.pdf.lines(moves[i].deltas,x,y,null,style)}}}},_isFillTransparent:function(){return this.ctx._isFillTransparent||0==this.globalAlpha},_isStrokeTransparent:function(){return this.ctx._isStrokeTransparent||0==this.globalAlpha},fill:function(fillRule){if(this.ctx._clip_path.length>0){var lines;(lines=window.outIntercept?"group"===window.outIntercept.type?window.outIntercept.stream:window.outIntercept:this.internal.getCurrentPage()).push("q");var origPath=this.path;this.path=this.ctx._clip_path,this.ctx._clip_path=[],this._fill(fillRule,!0),this.ctx._clip_path=this.path,this.path=origPath,this._fill(fillRule,!1),lines.push("Q")}else this._fill(fillRule,!1)},_fill:function(fillRule,isClip){if(!this._isFillTransparent()){var lines,v2Support="function"==typeof this.pdf.internal.newObject2;lines=window.outIntercept?"group"===window.outIntercept.type?window.outIntercept.stream:window.outIntercept:this.internal.getCurrentPage();var moves=[],outInterceptOld=window.outIntercept;if(v2Support)switch(this.ctx.globalCompositeOperation){case"normal":case"source-over":break;case"destination-in":case"destination-out":var obj=this.pdf.internal.newStreamObject(),obj2=this.pdf.internal.newObject2();obj2.push("<</Type /ExtGState"),obj2.push("/SMask <</S /Alpha /G "+obj.objId+" 0 R>>"),obj2.push(">>");var gsName="MASK"+obj2.objId;this.pdf.internal.addGraphicsState(gsName,obj2.objId);var instruction="/"+gsName+" gs";lines.splice(0,0,"q"),lines.splice(1,0,instruction),lines.push("Q"),window.outIntercept=obj;break;default:var dictionaryEntry="/"+this.pdf.internal.blendModeMap[this.ctx.globalCompositeOperation.toUpperCase()];dictionaryEntry&&this.pdf.internal.out(dictionaryEntry+" gs")}var alpha=this.ctx.globalAlpha;if(this.ctx._fillOpacity<1&&(alpha=this.ctx._fillOpacity),v2Support){var objOpac=this.pdf.internal.newObject2();objOpac.push("<</Type /ExtGState"),objOpac.push("/CA "+alpha),objOpac.push("/ca "+alpha),objOpac.push(">>");gsName="GS_O_"+objOpac.objId;this.pdf.internal.addGraphicsState(gsName,objOpac.objId),this.pdf.internal.out("/"+gsName+" gs")}for(var xPath=this.path,i=0;i<xPath.length;i++){var pt=xPath[i];switch(pt.type){case"mt":moves.push({start:pt,deltas:[],abs:[]});break;case"lt":var delta=[pt.x-xPath[i-1].x,pt.y-xPath[i-1].y];moves[moves.length-1].deltas.push(delta),moves[moves.length-1].abs.push(pt);break;case"bct":delta=[pt.x1-xPath[i-1].x,pt.y1-xPath[i-1].y,pt.x2-xPath[i-1].x,pt.y2-xPath[i-1].y,pt.x-xPath[i-1].x,pt.y-xPath[i-1].y];moves[moves.length-1].deltas.push(delta);break;case"qct":var x1=xPath[i-1].x+2/3*(pt.x1-xPath[i-1].x),y1=xPath[i-1].y+2/3*(pt.y1-xPath[i-1].y),x2=pt.x+2/3*(pt.x1-pt.x),y2=pt.y+2/3*(pt.y1-pt.y),x3=pt.x,y3=pt.y;delta=[x1-xPath[i-1].x,y1-xPath[i-1].y,x2-xPath[i-1].x,y2-xPath[i-1].y,x3-xPath[i-1].x,y3-xPath[i-1].y];moves[moves.length-1].deltas.push(delta);break;case"arc":0===moves.length&&moves.push({deltas:[],abs:[]}),moves[moves.length-1].arc=!0,Array.isArray(moves[moves.length-1].abs)&&moves[moves.length-1].abs.push(pt);break;case"close":moves.push({close:!0})}}for(i=0;i<moves.length;i++){var style;if(i==moves.length-1?(style="f","evenodd"===fillRule&&(style+="*")):style=null,moves[i].close)this.pdf.internal.out("h"),style&&this.pdf.internal.out(style);else if(moves[i].arc){moves[i].start&&this.internal.move2(this,moves[i].start.x,moves[i].start.y);for(var arcs=moves[i].abs,ii=0;ii<arcs.length;ii++){var arc=arcs[ii];if(void 0!==arc.startAngle){var start=360*arc.startAngle/(2*Math.PI),end=360*arc.endAngle/(2*Math.PI),x=arc.x,y=arc.y;if(0===ii&&this.internal.move2(this,x,y),this.internal.arc2(this,x,y,arc.radius,start,end,arc.anticlockwise,null,isClip),ii===arcs.length-1&&moves[i].start){x=moves[i].start.x,y=moves[i].start.y;this.internal.line2(c2d,x,y)}}else this.internal.line2(c2d,arc.x,arc.y)}}else{x=moves[i].start.x,y=moves[i].start.y;isClip?(this.pdf.lines(moves[i].deltas,x,y,null,null),this.pdf.clip_fixed()):this.pdf.lines(moves[i].deltas,x,y,null,style)}}window.outIntercept=outInterceptOld}},pushMask:function(){if("function"==typeof this.pdf.internal.newObject2){var obj=this.pdf.internal.newStreamObject(),obj2=this.pdf.internal.newObject2();obj2.push("<</Type /ExtGState"),obj2.push("/SMask <</S /Alpha /G "+obj.objId+" 0 R>>"),obj2.push(">>");var gsName="MASK"+obj2.objId;this.pdf.internal.addGraphicsState(gsName,obj2.objId);var instruction="/"+gsName+" gs";this.pdf.internal.out(instruction)}else console.log("jsPDF v2 not enabled")},clip:function(){if(this.ctx._clip_path.length>0)for(var i=0;i<this.path.length;i++)this.ctx._clip_path.push(this.path[i]);else this.ctx._clip_path=this.path;this.path=[]},measureText:function(text){var pdf=this.pdf;return{getWidth:function(){var fontSize=pdf.internal.getFontSize(),txtWidth=pdf.getStringUnitWidth(text)*fontSize/pdf.internal.scaleFactor;return txtWidth*=1.3333},get width(){return this.getWidth(text)}}},_getBaseline:function(y){var height=parseInt(this.pdf.internal.getFontSize()),descent=.25*height;switch(this.ctx.textBaseline){case"bottom":return y-descent;case"top":return y+height;case"hanging":return y+height-descent;case"middle":return y+height/2-descent;default:return y}}};var c2d=jsPDFAPI.context2d;function context(){this._isStrokeTransparent=!1,this._strokeOpacity=1,this.strokeStyle="#000000",this.fillStyle="#000000",this._isFillTransparent=!1,this._fillOpacity=1,this.font="12pt times",this.textBaseline="alphabetic",this.textAlign="start",this.lineWidth=1,this.lineJoin="miter",this.lineCap="butt",this._transform=[1,0,0,1,0,0],this.globalCompositeOperation="normal",this.globalAlpha=1,this._clip_path=[],this.ignoreClearRect=!1,this.copy=function(ctx){this._isStrokeTransparent=ctx._isStrokeTransparent,this._strokeOpacity=ctx._strokeOpacity,this.strokeStyle=ctx.strokeStyle,this._isFillTransparent=ctx._isFillTransparent,this._fillOpacity=ctx._fillOpacity,this.fillStyle=ctx.fillStyle,this.font=ctx.font,this.lineWidth=ctx.lineWidth,this.lineJoin=ctx.lineJoin,this.lineCap=ctx.lineCap,this.textBaseline=ctx.textBaseline,this.textAlign=ctx.textAlign,this._fontSize=ctx._fontSize,this._transform=ctx._transform.slice(0),this.globalCompositeOperation=ctx.globalCompositeOperation,this.globalAlpha=ctx.globalAlpha,this._clip_path=ctx._clip_path.slice(0),this.ignoreClearRect=ctx.ignoreClearRect}}Object.defineProperty(c2d,"fillStyle",{set:function(value){this.setFillStyle(value)},get:function(){return this.ctx.fillStyle}}),Object.defineProperty(c2d,"strokeStyle",{set:function(value){this.setStrokeStyle(value)},get:function(){return this.ctx.strokeStyle}}),Object.defineProperty(c2d,"lineWidth",{set:function(value){this.setLineWidth(value)},get:function(){return this.ctx.lineWidth}}),Object.defineProperty(c2d,"lineCap",{set:function(val){this.setLineCap(val)},get:function(){return this.ctx.lineCap}}),Object.defineProperty(c2d,"lineJoin",{set:function(val){this.setLineJoin(val)},get:function(){return this.ctx.lineJoin}}),Object.defineProperty(c2d,"miterLimit",{set:function(val){this.ctx.miterLimit=val},get:function(){return this.ctx.miterLimit}}),Object.defineProperty(c2d,"textBaseline",{set:function(value){this.setTextBaseline(value)},get:function(){return this.getTextBaseline()}}),Object.defineProperty(c2d,"textAlign",{set:function(value){this.setTextAlign(value)},get:function(){return this.getTextAlign()}}),Object.defineProperty(c2d,"font",{set:function(value){this.setFont(value)},get:function(){return this.ctx.font}}),Object.defineProperty(c2d,"globalCompositeOperation",{set:function(value){this.ctx.globalCompositeOperation=value},get:function(){return this.ctx.globalCompositeOperation}}),Object.defineProperty(c2d,"globalAlpha",{set:function(value){this.ctx.globalAlpha=value},get:function(){return this.ctx.globalAlpha}}),Object.defineProperty(c2d,"canvas",{get:function(){return{parentNode:!1,style:!1}}}),Object.defineProperty(c2d,"ignoreClearRect",{set:function(value){this.ctx.ignoreClearRect=value},get:function(){return this.ctx.ignoreClearRect}}),c2d.internal={},c2d.internal.rxRgb=/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/,c2d.internal.rxRgba=/rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/,c2d.internal.rxTransparent=/transparent|rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*0+\s*\)/,c2d.internal.arc=function(c2d,xc,yc,r,a1,a2,anticlockwise,style){for(var k=this.pdf.internal.scaleFactor,pageHeight=this.pdf.internal.pageSize.getHeight(),f2=this.pdf.internal.f2,a1r=a1*(Math.PI/180),a2r=a2*(Math.PI/180),curves=this.createArc(r,a1r,a2r,anticlockwise),i=0;i<curves.length;i++){var curve=curves[i];0===i?this.pdf.internal.out([f2((curve.x1+xc)*k),f2((pageHeight-(curve.y1+yc))*k),"m",f2((curve.x2+xc)*k),f2((pageHeight-(curve.y2+yc))*k),f2((curve.x3+xc)*k),f2((pageHeight-(curve.y3+yc))*k),f2((curve.x4+xc)*k),f2((pageHeight-(curve.y4+yc))*k),"c"].join(" ")):this.pdf.internal.out([f2((curve.x2+xc)*k),f2((pageHeight-(curve.y2+yc))*k),f2((curve.x3+xc)*k),f2((pageHeight-(curve.y3+yc))*k),f2((curve.x4+xc)*k),f2((pageHeight-(curve.y4+yc))*k),"c"].join(" ")),c2d._lastPoint={x:xc,y:yc}}null!==style&&this.pdf.internal.out(this.pdf.internal.getStyle(style))},c2d.internal.arc2=function(c2d,x,y,r,a1,a2,anticlockwise,style,isClip){var centerX=x,centerY=y;isClip?(this.arc(c2d,centerX,centerY,r,a1,a2,anticlockwise,null),this.pdf.clip_fixed()):this.arc(c2d,centerX,centerY,r,a1,a2,anticlockwise,style)},c2d.internal.move2=function(c2d,x,y){var k=this.pdf.internal.scaleFactor,pageHeight=this.pdf.internal.pageSize.getHeight(),f2=this.pdf.internal.f2;this.pdf.internal.out([f2(x*k),f2((pageHeight-y)*k),"m"].join(" ")),c2d._lastPoint={x:x,y:y}},c2d.internal.line2=function(c2d,dx,dy){var k=this.pdf.internal.scaleFactor,pageHeight=this.pdf.internal.pageSize.getHeight(),f2=this.pdf.internal.f2,pt={x:dx,y:dy};this.pdf.internal.out([f2(pt.x*k),f2((pageHeight-pt.y)*k),"l"].join(" ")),c2d._lastPoint=pt},c2d.internal.createArc=function(radius,startAngle,endAngle,anticlockwise){var twoPI=2*Math.PI,piOverTwo=Math.PI/2,startAngleN=startAngle;for((startAngleN<twoPI||startAngleN>twoPI)&&(startAngleN%=twoPI),startAngleN<0&&(startAngleN=twoPI+startAngleN);startAngle>endAngle;)startAngle-=twoPI;var totalAngle=Math.abs(endAngle-startAngle);totalAngle<twoPI&&anticlockwise&&(totalAngle=twoPI-totalAngle);for(var curves=[],sgn=anticlockwise?-1:1,a1=startAngleN;totalAngle>1e-5;){var a2=a1+sgn*Math.min(totalAngle,piOverTwo);curves.push(this.createSmallArc(radius,a1,a2)),totalAngle-=Math.abs(a2-a1),a1=a2}return curves},c2d.internal.getCurrentPage=function(){return this.pdf.internal.pages[this.pdf.internal.getCurrentPageInfo().pageNumber]},c2d.internal.createSmallArc=function(r,a1,a2){var a=(a2-a1)/2,x4=r*Math.cos(a),y4=r*Math.sin(a),x1=x4,y1=-y4,q1=x1*x1+y1*y1,q2=q1+x1*x4+y1*y4,k2=4/3*(Math.sqrt(2*q1*q2)-q2)/(x1*y4-y1*x4),x2=x1-k2*y1,y2=y1+k2*x1,x3=x2,y3=-y2,ar=a+a1,cos_ar=Math.cos(ar),sin_ar=Math.sin(ar);return{x1:r*Math.cos(a1),y1:r*Math.sin(a1),x2:x2*cos_ar-y2*sin_ar,y2:x2*sin_ar+y2*cos_ar,x3:x3*cos_ar-y3*sin_ar,y3:x3*sin_ar+y3*cos_ar,x4:r*Math.cos(a2),y4:r*Math.sin(a2)}}}(jsPDF.API,"undefined"!=typeof self&&self||"undefined"!=typeof window&&window||"undefined"!=typeof global&&global||Function('return typeof this === "object" && this.content')()||Function("return this")()),
-/** @preserve
-   * jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser
-   * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
-   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
-   *               2014 Diego Casorran, https://github.com/diegocr
-   *               2014 Daniel Husar, https://github.com/danielhusar
-   *               2014 Wolfgang Gassler, https://github.com/woolfg
-   *               2014 Steven Spungin, https://github.com/flamenco
-   *
-   * 
+function _typeof2(obj){return _typeof2="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(obj){return typeof obj}:function(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj},_typeof2(obj)
+/** @license
+ *
+ * jsPDF - PDF Document creation from JavaScript
+ * Version 2.5.1 Built on 2022-01-28T15:37:57.789Z
+ *                      CommitID 00000000
+ *
+ * Copyright (c) 2010-2021 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF
+ *               2015-2021 yWorks GmbH, http://www.yworks.com
+ *               2015-2021 Lukas Holländer <lukas.hollaender@yworks.com>, https://github.com/HackbrettXXX
+ *               2016-2018 Aras Abbasi <aras.abbasi@gmail.com>
+ *               2010 Aaron Spike, https://github.com/acspike
+ *               2012 Willow Systems Corporation, https://github.com/willowsystems
+ *               2012 Pablo Hess, https://github.com/pablohess
+ *               2012 Florian Jenett, https://github.com/fjenett
+ *               2013 Warren Weckesser, https://github.com/warrenweckesser
+ *               2013 Youssef Beddad, https://github.com/lifof
+ *               2013 Lee Driscoll, https://github.com/lsdriscoll
+ *               2013 Stefan Slonevskiy, https://github.com/stefslon
+ *               2013 Jeremy Morel, https://github.com/jmorel
+ *               2013 Christoph Hartmann, https://github.com/chris-rock
+ *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
+ *               2014 James Makes, https://github.com/dollaruw
+ *               2014 Diego Casorran, https://github.com/diegocr
+ *               2014 Steven Spungin, https://github.com/Flamenco
+ *               2014 Kenneth Glassey, https://github.com/Gavvers
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributor(s):
+ *    siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango,
+ *    kim3er, mfo, alnorth, Flamenco
+ */}!function(global,factory){"object"===("undefined"==typeof exports?"undefined":_typeof2(exports))&&"undefined"!=typeof module?factory(exports):"function"==typeof define&&define.amd?define("mod_pdfannotator/jspdf",["exports"],factory):factory((global=global||self).jspdf={})}(window,(function(exports){function _typeof(obj){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(obj){return typeof obj}:function(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj},_typeof(obj)}var globalObject=function(){return"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this}();function consoleLog(){globalObject.console&&"function"==typeof globalObject.console.log&&globalObject.console.log.apply(globalObject.console,arguments)}var console={log:consoleLog,warn:function(str){globalObject.console&&("function"==typeof globalObject.console.warn?globalObject.console.warn.apply(globalObject.console,arguments):consoleLog.call(null,arguments))},error:function(str){globalObject.console&&("function"==typeof globalObject.console.error?globalObject.console.error.apply(globalObject.console,arguments):consoleLog(str))}};function download(url,name,opts){var xhr=new XMLHttpRequest;xhr.open("GET",url),xhr.responseType="blob",xhr.onload=function(){saveAs(xhr.response,name,opts)},xhr.onerror=function(){console.error("could not download file")},xhr.send()}function corsEnabled(url){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,!1);try{xhr.send()}catch(e){}return xhr.status>=200&&xhr.status<=299}function click(node){try{node.dispatchEvent(new MouseEvent("click"))}catch(e){var evt=document.createEvent("MouseEvents");evt.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),node.dispatchEvent(evt)}}var atob,btoa,saveAs=globalObject.saveAs||("object"!==("undefined"==typeof window?"undefined":_typeof(window))||window!==globalObject?function(){}:"undefined"!=typeof HTMLAnchorElement&&"download"in HTMLAnchorElement.prototype?function(blob,name,opts){var URL=globalObject.URL||globalObject.webkitURL,a=document.createElement("a");name=name||blob.name||"download",a.download=name,a.rel="noopener","string"==typeof blob?(a.href=blob,a.origin!==location.origin?corsEnabled(a.href)?download(blob,name,opts):click(a,a.target="_blank"):click(a)):(a.href=URL.createObjectURL(blob),setTimeout((function(){URL.revokeObjectURL(a.href)}),4e4),setTimeout((function(){click(a)}),0))}:"msSaveOrOpenBlob"in navigator?function(blob,name,opts){if(name=name||blob.name||"download","string"==typeof blob)if(corsEnabled(blob))download(blob,name,opts);else{var a=document.createElement("a");a.href=blob,a.target="_blank",setTimeout((function(){click(a)}))}else navigator.msSaveOrOpenBlob(function(blob,opts){return void 0===opts?opts={autoBom:!1}:"object"!==_typeof(opts)&&(console.warn("Deprecated: Expected third argument to be a object"),opts={autoBom:!opts}),opts.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)?new Blob([String.fromCharCode(65279),blob],{type:blob.type}):blob}(blob,opts),name)}:function(blob,name,opts,popup){if((popup=popup||open("","_blank"))&&(popup.document.title=popup.document.body.innerText="downloading..."),"string"==typeof blob)return download(blob,name,opts);var force="application/octet-stream"===blob.type,isSafari=/constructor/i.test(globalObject.HTMLElement)||globalObject.safari,isChromeIOS=/CriOS\/[\d]+/.test(navigator.userAgent);if((isChromeIOS||force&&isSafari)&&"object"===("undefined"==typeof FileReader?"undefined":_typeof(FileReader))){var reader=new FileReader;reader.onloadend=function(){var url=reader.result;url=isChromeIOS?url:url.replace(/^data:[^;]*;/,"data:attachment/file;"),popup?popup.location.href=url:location=url,popup=null},reader.readAsDataURL(blob)}else{var URL=globalObject.URL||globalObject.webkitURL,url=URL.createObjectURL(blob);popup?popup.location=url:location.href=url,popup=null,setTimeout((function(){URL.revokeObjectURL(url)}),4e4)}});
+/**
+   * A class to parse color values
+   * @author Stoyan Stefanov <sstoo@gmail.com>
+   * {@link   http://www.phpied.com/rgb-color-parser-in-javascript/}
+   * @license Use it if you like it
+   */function RGBColor(color_string){var channels;color_string=color_string||"",this.ok=!1,"#"==color_string.charAt(0)&&(color_string=color_string.substr(1,6));color_string={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"00ffff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000000",blanchedalmond:"ffebcd",blue:"0000ff",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"00ffff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dodgerblue:"1e90ff",feldspar:"d19275",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"ff00ff",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgrey:"d3d3d3",lightgreen:"90ee90",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslateblue:"8470ff",lightslategray:"778899",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"00ff00",limegreen:"32cd32",linen:"faf0e6",magenta:"ff00ff",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370d8",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"d87093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",red:"ff0000",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",violetred:"d02090",wheat:"f5deb3",white:"ffffff",whitesmoke:"f5f5f5",yellow:"ffff00",yellowgreen:"9acd32"}[color_string=(color_string=color_string.replace(/ /g,"")).toLowerCase()]||color_string;for(var color_defs=[{re:/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,example:["rgb(123, 234, 45)","rgb(255,234,245)"],process:function(bits){return[parseInt(bits[1]),parseInt(bits[2]),parseInt(bits[3])]}},{re:/^(\w{2})(\w{2})(\w{2})$/,example:["#00ff00","336699"],process:function(bits){return[parseInt(bits[1],16),parseInt(bits[2],16),parseInt(bits[3],16)]}},{re:/^(\w{1})(\w{1})(\w{1})$/,example:["#fb0","f0f"],process:function(bits){return[parseInt(bits[1]+bits[1],16),parseInt(bits[2]+bits[2],16),parseInt(bits[3]+bits[3],16)]}}],i=0;i<color_defs.length;i++){var re=color_defs[i].re,processor=color_defs[i].process,bits=re.exec(color_string);bits&&(channels=processor(bits),this.r=channels[0],this.g=channels[1],this.b=channels[2],this.ok=!0)}this.r=this.r<0||isNaN(this.r)?0:this.r>255?255:this.r,this.g=this.g<0||isNaN(this.g)?0:this.g>255?255:this.g,this.b=this.b<0||isNaN(this.b)?0:this.b>255?255:this.b,this.toRGB=function(){return"rgb("+this.r+", "+this.g+", "+this.b+")"},this.toHex=function(){var r=this.r.toString(16),g=this.g.toString(16),b=this.b.toString(16);return 1==r.length&&(r="0"+r),1==g.length&&(g="0"+g),1==b.length&&(b="0"+b),"#"+r+g+b}}
+/**
+   * @license
+   * Joseph Myers does not specify a particular license for his work.
+   *
+   * Author: Joseph Myers
+   * Accessed from: http://www.myersdaily.org/joseph/javascript/md5.js
+   *
+   * Modified by: Owen Leong
+   */
+function md5cycle(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a=ff(a,b,c,d,k[0],7,-680876936),d=ff(d,a,b,c,k[1],12,-389564586),c=ff(c,d,a,b,k[2],17,606105819),b=ff(b,c,d,a,k[3],22,-1044525330),a=ff(a,b,c,d,k[4],7,-176418897),d=ff(d,a,b,c,k[5],12,1200080426),c=ff(c,d,a,b,k[6],17,-1473231341),b=ff(b,c,d,a,k[7],22,-45705983),a=ff(a,b,c,d,k[8],7,1770035416),d=ff(d,a,b,c,k[9],12,-1958414417),c=ff(c,d,a,b,k[10],17,-42063),b=ff(b,c,d,a,k[11],22,-1990404162),a=ff(a,b,c,d,k[12],7,1804603682),d=ff(d,a,b,c,k[13],12,-40341101),c=ff(c,d,a,b,k[14],17,-1502002290),a=gg(a,b=ff(b,c,d,a,k[15],22,1236535329),c,d,k[1],5,-165796510),d=gg(d,a,b,c,k[6],9,-1069501632),c=gg(c,d,a,b,k[11],14,643717713),b=gg(b,c,d,a,k[0],20,-373897302),a=gg(a,b,c,d,k[5],5,-701558691),d=gg(d,a,b,c,k[10],9,38016083),c=gg(c,d,a,b,k[15],14,-660478335),b=gg(b,c,d,a,k[4],20,-405537848),a=gg(a,b,c,d,k[9],5,568446438),d=gg(d,a,b,c,k[14],9,-1019803690),c=gg(c,d,a,b,k[3],14,-187363961),b=gg(b,c,d,a,k[8],20,1163531501),a=gg(a,b,c,d,k[13],5,-1444681467),d=gg(d,a,b,c,k[2],9,-51403784),c=gg(c,d,a,b,k[7],14,1735328473),a=hh(a,b=gg(b,c,d,a,k[12],20,-1926607734),c,d,k[5],4,-378558),d=hh(d,a,b,c,k[8],11,-2022574463),c=hh(c,d,a,b,k[11],16,1839030562),b=hh(b,c,d,a,k[14],23,-35309556),a=hh(a,b,c,d,k[1],4,-1530992060),d=hh(d,a,b,c,k[4],11,1272893353),c=hh(c,d,a,b,k[7],16,-155497632),b=hh(b,c,d,a,k[10],23,-1094730640),a=hh(a,b,c,d,k[13],4,681279174),d=hh(d,a,b,c,k[0],11,-358537222),c=hh(c,d,a,b,k[3],16,-722521979),b=hh(b,c,d,a,k[6],23,76029189),a=hh(a,b,c,d,k[9],4,-640364487),d=hh(d,a,b,c,k[12],11,-421815835),c=hh(c,d,a,b,k[15],16,530742520),a=ii(a,b=hh(b,c,d,a,k[2],23,-995338651),c,d,k[0],6,-198630844),d=ii(d,a,b,c,k[7],10,1126891415),c=ii(c,d,a,b,k[14],15,-1416354905),b=ii(b,c,d,a,k[5],21,-57434055),a=ii(a,b,c,d,k[12],6,1700485571),d=ii(d,a,b,c,k[3],10,-1894986606),c=ii(c,d,a,b,k[10],15,-1051523),b=ii(b,c,d,a,k[1],21,-2054922799),a=ii(a,b,c,d,k[8],6,1873313359),d=ii(d,a,b,c,k[15],10,-30611744),c=ii(c,d,a,b,k[6],15,-1560198380),b=ii(b,c,d,a,k[13],21,1309151649),a=ii(a,b,c,d,k[4],6,-145523070),d=ii(d,a,b,c,k[11],10,-1120210379),c=ii(c,d,a,b,k[2],15,718787259),b=ii(b,c,d,a,k[9],21,-343485551),x[0]=add32(a,x[0]),x[1]=add32(b,x[1]),x[2]=add32(c,x[2]),x[3]=add32(d,x[3])}function cmn(q,a,b,x,s,t){return a=add32(add32(a,q),add32(x,t)),add32(a<<s|a>>>32-s,b)}function ff(a,b,c,d,x,s,t){return cmn(b&c|~b&d,a,b,x,s,t)}function gg(a,b,c,d,x,s,t){return cmn(b&d|c&~d,a,b,x,s,t)}function hh(a,b,c,d,x,s,t){return cmn(b^c^d,a,b,x,s,t)}function ii(a,b,c,d,x,s,t){return cmn(c^(b|~d),a,b,x,s,t)}function md51(s){var i,n=s.length,state=[1732584193,-271733879,-1732584194,271733878];for(i=64;i<=s.length;i+=64)md5cycle(state,md5blk(s.substring(i-64,i)));s=s.substring(i-64);var tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i<s.length;i++)tail[i>>2]|=s.charCodeAt(i)<<(i%4<<3);if(tail[i>>2]|=128<<(i%4<<3),i>55)for(md5cycle(state,tail),i=0;i<16;i++)tail[i]=0;return tail[14]=8*n,md5cycle(state,tail),state}function md5blk(s){var i,md5blks=[];for(i=0;i<64;i+=4)md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24);return md5blks}atob=globalObject.atob.bind(globalObject),btoa=globalObject.btoa.bind(globalObject);var hex_chr="0123456789abcdef".split("");function rhex(n){for(var s="",j=0;j<4;j++)s+=hex_chr[n>>8*j+4&15]+hex_chr[n>>8*j&15];return s}function singleToByteString(n){return String.fromCharCode((255&n)>>0,(65280&n)>>8,(16711680&n)>>16,(4278190080&n)>>24)}function md5Bin(s){return function(x){return x.map(singleToByteString).join("")}(md51(s))}var md5Check="5d41402abc4b2a76b9719d911017c592"!=function(x){for(var i=0;i<x.length;i++)x[i]=rhex(x[i]);return x.join("")}(md51("hello"));function add32(a,b){if(md5Check){var lsw=(65535&a)+(65535&b);return(a>>16)+(b>>16)+(lsw>>16)<<16|65535&lsw}return a+b&4294967295}
+/**
+   * @license
+   * FPDF is released under a permissive license: there is no usage restriction.
+   * You may embed it freely in your application (commercial or not), with or
+   * without modifications.
+   *
+   * Reference: http://www.fpdf.org/en/script/script37.php
+   */function rc4(key,data){var lastKey,lastState,str,num;if(key!==lastKey){for(var k=(str=key,num=1+(256/key.length>>0),new Array(num+1).join(str)),state=[],i=0;i<256;i++)state[i]=i;var j=0;for(i=0;i<256;i++){var t=state[i];j=(j+t+k.charCodeAt(i))%256,state[i]=state[j],state[j]=t}lastKey=key,lastState=state}else state=lastState;var length=data.length,a=0,b=0,out="";for(i=0;i<length;i++)b=(b+(t=state[a=(a+1)%256]))%256,state[a]=state[b],state[b]=t,k=state[(state[a]+state[b])%256],out+=String.fromCharCode(data.charCodeAt(i)^k);return out}
+/**
+   * @license
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   * Author: Owen Leong (@owenl131)
+   * Date: 15 Oct 2020
+   * References:
+   * https://www.cs.cmu.edu/~dst/Adobe/Gallery/anon21jul01-pdf-encryption.txt
+   * https://github.com/foliojs/pdfkit/blob/master/lib/security.js
+   * http://www.fpdf.org/en/script/script37.php
+   */var permissionOptions={print:4,modify:8,copy:16,"annot-forms":32};function PDFSecurity(permissions,userPassword,ownerPassword,fileId){this.v=1,this.r=2;var protection=192;permissions.forEach((function(perm){if(void 0!==permissionOptions.perm)throw new Error("Invalid permission: "+perm);protection+=permissionOptions[perm]})),this.padding="(¿N^NuŠAd\0NVÿú\b..\0¶Ðh>€/\f©þdSiz";var paddedUserPassword=(userPassword+this.padding).substr(0,32),paddedOwnerPassword=(ownerPassword+this.padding).substr(0,32);this.O=this.processOwnerPassword(paddedUserPassword,paddedOwnerPassword),this.P=-(1+(255^protection)),this.encryptionKey=md5Bin(paddedUserPassword+this.O+this.lsbFirstWord(this.P)+this.hexToBytes(fileId)).substr(0,5),this.U=rc4(this.encryptionKey,this.padding)}function toPDFName(str){if(/[^\u0000-\u00ff]/.test(str))throw new Error("Invalid PDF Name Object: "+str+", Only accept ASCII characters.");for(var result="",strLength=str.length,i=0;i<strLength;i++){var charCode=str.charCodeAt(i);if(charCode<33||35===charCode||37===charCode||40===charCode||41===charCode||47===charCode||60===charCode||62===charCode||91===charCode||93===charCode||123===charCode||125===charCode||charCode>126)result+="#"+("0"+charCode.toString(16)).slice(-2);else result+=str[i]}return result}function PubSub(context){if("object"!==_typeof(context))throw new Error("Invalid Context passed to initialize PubSub (jsPDF-module)");var topics={};this.subscribe=function(topic,callback,once){if(once=once||!1,"string"!=typeof topic||"function"!=typeof callback||"boolean"!=typeof once)throw new Error("Invalid arguments passed to PubSub.subscribe (jsPDF-module)");topics.hasOwnProperty(topic)||(topics[topic]={});var token=Math.random().toString(35);return topics[topic][token]=[callback,!!once],token},this.unsubscribe=function(token){for(var topic in topics)if(topics[topic][token])return delete topics[topic][token],0===Object.keys(topics[topic]).length&&delete topics[topic],!0;return!1},this.publish=function(topic){if(topics.hasOwnProperty(topic)){var args=Array.prototype.slice.call(arguments,1),tokens=[];for(var token in topics[topic]){var sub=topics[topic][token];try{sub[0].apply(context,args)}catch(ex){globalObject.console&&console.error("jsPDF PubSub Error",ex.message,ex)}sub[1]&&tokens.push(token)}tokens.length&&tokens.forEach(this.unsubscribe)}},this.getTopics=function(){return topics}}function GState(parameters){if(!(this instanceof GState))return new GState(parameters);var supported="opacity,stroke-opacity".split(",");for(var p in parameters)parameters.hasOwnProperty(p)&&supported.indexOf(p)>=0&&(this[p]=parameters[p]);this.id="",this.objectNumber=-1}function Pattern(gState,matrix){this.gState=gState,this.matrix=matrix,this.id="",this.objectNumber=-1}function ShadingPattern(type,coords,colors,gState,matrix){if(!(this instanceof ShadingPattern))return new ShadingPattern(type,coords,colors,gState,matrix);this.type="axial"===type?2:3,this.coords=coords,this.colors=colors,Pattern.call(this,gState,matrix)}function TilingPattern(boundingBox,xStep,yStep,gState,matrix){if(!(this instanceof TilingPattern))return new TilingPattern(boundingBox,xStep,yStep,gState,matrix);this.boundingBox=boundingBox,this.xStep=xStep,this.yStep=yStep,this.stream="",this.cloneIndex=0,Pattern.call(this,gState,matrix)}function jsPDF(options){var precision,orientation="string"==typeof arguments[0]?arguments[0]:"p",unit=arguments[1],format=arguments[2],compressPdf=arguments[3],filters=[],userUnit=1,floatPrecision=16,defaultPathOperation="S",encryptionOptions=null;"object"===_typeof(options=options||{})&&(orientation=options.orientation,unit=options.unit||unit,format=options.format||format,compressPdf=options.compress||options.compressPdf||compressPdf,null!==(encryptionOptions=options.encryption||null)&&(encryptionOptions.userPassword=encryptionOptions.userPassword||"",encryptionOptions.ownerPassword=encryptionOptions.ownerPassword||"",encryptionOptions.userPermissions=encryptionOptions.userPermissions||[]),userUnit="number"==typeof options.userUnit?Math.abs(options.userUnit):1,void 0!==options.precision&&(precision=options.precision),void 0!==options.floatPrecision&&(floatPrecision=options.floatPrecision),defaultPathOperation=options.defaultPathOperation||"S"),filters=options.filters||(!0===compressPdf?["FlateEncode"]:filters),unit=unit||"mm",orientation=(""+(orientation||"P")).toLowerCase();var putOnlyUsedFonts=options.putOnlyUsedFonts||!1,usedFonts={},API={internal:{},__private__:{}};API.__private__.PubSub=PubSub;var pdfVersion="1.3",getPdfVersion=API.__private__.getPdfVersion=function(){return pdfVersion};API.__private__.setPdfVersion=function(value){pdfVersion=value};var pageFormats={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]};API.__private__.getPageFormats=function(){return pageFormats};var getPageFormat=API.__private__.getPageFormat=function(value){return pageFormats[value]};format=format||"a4";var ApiMode={COMPAT:"compat",ADVANCED:"advanced"},apiMode=ApiMode.COMPAT;function advancedAPI(){this.saveGraphicsState(),out(new Matrix(scaleFactor,0,0,-scaleFactor,0,getPageHeight()*scaleFactor).toString()+" cm"),this.setFontSize(this.getFontSize()/scaleFactor),defaultPathOperation="n",apiMode=ApiMode.ADVANCED}function compatAPI(){this.restoreGraphicsState(),defaultPathOperation="S",apiMode=ApiMode.COMPAT}var combineFontStyleAndFontWeight=API.__private__.combineFontStyleAndFontWeight=function(fontStyle,fontWeight){if("bold"==fontStyle&&"normal"==fontWeight||"bold"==fontStyle&&400==fontWeight||"normal"==fontStyle&&"italic"==fontWeight||"bold"==fontStyle&&"italic"==fontWeight)throw new Error("Invalid Combination of fontweight and fontstyle");return fontWeight&&(fontStyle=400==fontWeight||"normal"===fontWeight?"italic"===fontStyle?"italic":"normal":700!=fontWeight&&"bold"!==fontWeight||"normal"!==fontStyle?(700==fontWeight?"bold":fontWeight)+""+fontStyle:"bold"),fontStyle};API.advancedAPI=function(body){var doSwitch=apiMode===ApiMode.COMPAT;return doSwitch&&advancedAPI.call(this),"function"!=typeof body||(body(this),doSwitch&&compatAPI.call(this)),this},API.compatAPI=function(body){var doSwitch=apiMode===ApiMode.ADVANCED;return doSwitch&&compatAPI.call(this),"function"!=typeof body||(body(this),doSwitch&&advancedAPI.call(this)),this},API.isAdvancedAPI=function(){return apiMode===ApiMode.ADVANCED};var hpf,advancedApiModeTrap=function(methodName){if(apiMode!==ApiMode.ADVANCED)throw new Error(methodName+" is only available in 'advanced' API mode. You need to call advancedAPI() first.")},roundToPrecision=API.roundToPrecision=API.__private__.roundToPrecision=function(number,parmPrecision){var tmpPrecision=precision||parmPrecision;if(isNaN(number)||isNaN(tmpPrecision))throw new Error("Invalid argument passed to jsPDF.roundToPrecision");return number.toFixed(tmpPrecision).replace(/0+$/,"")};hpf=API.hpf=API.__private__.hpf="number"==typeof floatPrecision?function(number){if(isNaN(number))throw new Error("Invalid argument passed to jsPDF.hpf");return roundToPrecision(number,floatPrecision)}:"smart"===floatPrecision?function(number){if(isNaN(number))throw new Error("Invalid argument passed to jsPDF.hpf");return roundToPrecision(number,number>-1&&number<1?16:5)}:function(number){if(isNaN(number))throw new Error("Invalid argument passed to jsPDF.hpf");return roundToPrecision(number,16)};var f2=API.f2=API.__private__.f2=function(number){if(isNaN(number))throw new Error("Invalid argument passed to jsPDF.f2");return roundToPrecision(number,2)},f3=API.__private__.f3=function(number){if(isNaN(number))throw new Error("Invalid argument passed to jsPDF.f3");return roundToPrecision(number,3)},scale=API.scale=API.__private__.scale=function(number){if(isNaN(number))throw new Error("Invalid argument passed to jsPDF.scale");return apiMode===ApiMode.COMPAT?number*scaleFactor:apiMode===ApiMode.ADVANCED?number:void 0},transformY=function(y){return apiMode===ApiMode.COMPAT?getPageHeight()-y:apiMode===ApiMode.ADVANCED?y:void 0},transformScaleY=function(y){return scale(transformY(y))};API.__private__.setPrecision=API.setPrecision=function(value){"number"==typeof parseInt(value,10)&&(precision=parseInt(value,10))};var creationDate,fileId="00000000000000000000000000000000",getFileId=API.__private__.getFileId=function(){return fileId},setFileId=API.__private__.setFileId=function(value){return fileId=void 0!==value&&/^[a-fA-F0-9]{32}$/.test(value)?value.toUpperCase():fileId.split("").map((function(){return"ABCDEF0123456789".charAt(Math.floor(16*Math.random()))})).join(""),null!==encryptionOptions&&(encryption=new PDFSecurity(encryptionOptions.userPermissions,encryptionOptions.userPassword,encryptionOptions.ownerPassword,fileId)),fileId};API.setFileId=function(value){return setFileId(value),this},API.getFileId=function(){return getFileId()};var convertDateToPDFDate=API.__private__.convertDateToPDFDate=function(parmDate){var tzoffset=parmDate.getTimezoneOffset(),tzsign=tzoffset<0?"+":"-",tzhour=Math.floor(Math.abs(tzoffset/60)),tzmin=Math.abs(tzoffset%60),timeZoneString=[tzsign,padd2(tzhour),"'",padd2(tzmin),"'"].join("");return["D:",parmDate.getFullYear(),padd2(parmDate.getMonth()+1),padd2(parmDate.getDate()),padd2(parmDate.getHours()),padd2(parmDate.getMinutes()),padd2(parmDate.getSeconds()),timeZoneString].join("")},convertPDFDateToDate=API.__private__.convertPDFDateToDate=function(parmPDFDate){var year=parseInt(parmPDFDate.substr(2,4),10),month=parseInt(parmPDFDate.substr(6,2),10)-1,date=parseInt(parmPDFDate.substr(8,2),10),hour=parseInt(parmPDFDate.substr(10,2),10),minutes=parseInt(parmPDFDate.substr(12,2),10),seconds=parseInt(parmPDFDate.substr(14,2),10);return new Date(year,month,date,hour,minutes,seconds,0)},setCreationDate=API.__private__.setCreationDate=function(date){var tmpCreationDateString;if(void 0===date&&(date=new Date),date instanceof Date)tmpCreationDateString=convertDateToPDFDate(date);else{if(!/^D:(20[0-2][0-9]|203[0-7]|19[7-9][0-9])(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])(0[0-9]|1[0-9]|2[0-3])(0[0-9]|[1-5][0-9])(0[0-9]|[1-5][0-9])(\+0[0-9]|\+1[0-4]|-0[0-9]|-1[0-1])'(0[0-9]|[1-5][0-9])'?$/.test(date))throw new Error("Invalid argument passed to jsPDF.setCreationDate");tmpCreationDateString=date}return creationDate=tmpCreationDateString},getCreationDate=API.__private__.getCreationDate=function(type){var result=creationDate;return"jsDate"===type&&(result=convertPDFDateToDate(creationDate)),result};API.setCreationDate=function(date){return setCreationDate(date),this},API.getCreationDate=function(type){return getCreationDate(type)};var currentPage,padd2=API.__private__.padd2=function(number){return("0"+parseInt(number)).slice(-2)},padd2Hex=API.__private__.padd2Hex=function(hexString){return("00"+(hexString=hexString.toString())).substr(hexString.length)},objectNumber=0,offsets=[],content=[],contentLength=0,additionalObjects=[],pages=[],hasCustomDestination=!1,outputDestination=content,resetDocument=function(){objectNumber=0,contentLength=0,content=[],offsets=[],additionalObjects=[],rootDictionaryObjId=newObjectDeferred(),resourceDictionaryObjId=newObjectDeferred()};API.__private__.setCustomOutputDestination=function(destination){hasCustomDestination=!0,outputDestination=destination};var setOutputDestination=function(destination){hasCustomDestination||(outputDestination=destination)};API.__private__.resetCustomOutputDestination=function(){hasCustomDestination=!1,outputDestination=content};var out=API.__private__.out=function(string){return string=string.toString(),contentLength+=string.length+1,outputDestination.push(string),outputDestination},write=API.__private__.write=function(value){return out(1===arguments.length?value.toString():Array.prototype.join.call(arguments," "))},getArrayBuffer=API.__private__.getArrayBuffer=function(data){for(var len=data.length,ab=new ArrayBuffer(len),u8=new Uint8Array(ab);len--;)u8[len]=data.charCodeAt(len);return ab},standardFonts=[["Helvetica","helvetica","normal","WinAnsiEncoding"],["Helvetica-Bold","helvetica","bold","WinAnsiEncoding"],["Helvetica-Oblique","helvetica","italic","WinAnsiEncoding"],["Helvetica-BoldOblique","helvetica","bolditalic","WinAnsiEncoding"],["Courier","courier","normal","WinAnsiEncoding"],["Courier-Bold","courier","bold","WinAnsiEncoding"],["Courier-Oblique","courier","italic","WinAnsiEncoding"],["Courier-BoldOblique","courier","bolditalic","WinAnsiEncoding"],["Times-Roman","times","normal","WinAnsiEncoding"],["Times-Bold","times","bold","WinAnsiEncoding"],["Times-Italic","times","italic","WinAnsiEncoding"],["Times-BoldItalic","times","bolditalic","WinAnsiEncoding"],["ZapfDingbats","zapfdingbats","normal",null],["Symbol","symbol","normal",null]];API.__private__.getStandardFonts=function(){return standardFonts};var activeFontSize=options.fontSize||16;API.__private__.setFontSize=API.setFontSize=function(size){return activeFontSize=apiMode===ApiMode.ADVANCED?size/scaleFactor:size,this};var zoomMode,getFontSize=API.__private__.getFontSize=API.getFontSize=function(){return apiMode===ApiMode.COMPAT?activeFontSize:activeFontSize*scaleFactor},R2L=options.R2L||!1;API.__private__.setR2L=API.setR2L=function(value){return R2L=value,this},API.__private__.getR2L=API.getR2L=function(){return R2L};var pageMode,setZoomMode=API.__private__.setZoomMode=function(zoom){var validZoomModes=[void 0,null,"fullwidth","fullheight","fullpage","original"];if(/^(?:\d+\.\d*|\d*\.\d+|\d+)%$/.test(zoom))zoomMode=zoom;else if(isNaN(zoom)){if(-1===validZoomModes.indexOf(zoom))throw new Error('zoom must be Integer (e.g. 2), a percentage Value (e.g. 300%) or fullwidth, fullheight, fullpage, original. "'+zoom+'" is not recognized.');zoomMode=zoom}else zoomMode=parseInt(zoom,10)};API.__private__.getZoomMode=function(){return zoomMode};var layoutMode,setPageMode=API.__private__.setPageMode=function(pmode){if(-1==[void 0,null,"UseNone","UseOutlines","UseThumbs","FullScreen"].indexOf(pmode))throw new Error('Page mode must be one of UseNone, UseOutlines, UseThumbs, or FullScreen. "'+pmode+'" is not recognized.');pageMode=pmode};API.__private__.getPageMode=function(){return pageMode};var setLayoutMode=API.__private__.setLayoutMode=function(layout){if(-1==[void 0,null,"continuous","single","twoleft","tworight","two"].indexOf(layout))throw new Error('Layout mode must be one of continuous, single, twoleft, tworight. "'+layout+'" is not recognized.');layoutMode=layout};API.__private__.getLayoutMode=function(){return layoutMode},API.__private__.setDisplayMode=API.setDisplayMode=function(zoom,layout,pmode){return setZoomMode(zoom),setLayoutMode(layout),setPageMode(pmode),this};var documentProperties={title:"",subject:"",author:"",keywords:"",creator:""};API.__private__.getDocumentProperty=function(key){if(-1===Object.keys(documentProperties).indexOf(key))throw new Error("Invalid argument passed to jsPDF.getDocumentProperty");return documentProperties[key]},API.__private__.getDocumentProperties=function(){return documentProperties},API.__private__.setDocumentProperties=API.setProperties=API.setDocumentProperties=function(properties){for(var property in documentProperties)documentProperties.hasOwnProperty(property)&&properties[property]&&(documentProperties[property]=properties[property]);return this},API.__private__.setDocumentProperty=function(key,value){if(-1===Object.keys(documentProperties).indexOf(key))throw new Error("Invalid arguments passed to jsPDF.setDocumentProperty");return documentProperties[key]=value};var activeFontKey,scaleFactor,pageX,pageY,pageMatrix,fonts={},fontmap={},fontStateStack=[],patterns={},patternMap={},gStates={},gStatesMap={},activeGState=null,page=0,pagesContext=[],events=new PubSub(API),hotfixes=options.hotfixes||[],renderTargets={},renderTargetMap={},renderTargetStack=[],Matrix=function Matrix(sx,shy,shx,sy,tx,ty){if(!(this instanceof Matrix))return new Matrix(sx,shy,shx,sy,tx,ty);isNaN(sx)&&(sx=1),isNaN(shy)&&(shy=0),isNaN(shx)&&(shx=0),isNaN(sy)&&(sy=1),isNaN(tx)&&(tx=0),isNaN(ty)&&(ty=0),this._matrix=[sx,shy,shx,sy,tx,ty]};Object.defineProperty(Matrix.prototype,"sx",{get:function(){return this._matrix[0]},set:function(value){this._matrix[0]=value}}),Object.defineProperty(Matrix.prototype,"shy",{get:function(){return this._matrix[1]},set:function(value){this._matrix[1]=value}}),Object.defineProperty(Matrix.prototype,"shx",{get:function(){return this._matrix[2]},set:function(value){this._matrix[2]=value}}),Object.defineProperty(Matrix.prototype,"sy",{get:function(){return this._matrix[3]},set:function(value){this._matrix[3]=value}}),Object.defineProperty(Matrix.prototype,"tx",{get:function(){return this._matrix[4]},set:function(value){this._matrix[4]=value}}),Object.defineProperty(Matrix.prototype,"ty",{get:function(){return this._matrix[5]},set:function(value){this._matrix[5]=value}}),Object.defineProperty(Matrix.prototype,"a",{get:function(){return this._matrix[0]},set:function(value){this._matrix[0]=value}}),Object.defineProperty(Matrix.prototype,"b",{get:function(){return this._matrix[1]},set:function(value){this._matrix[1]=value}}),Object.defineProperty(Matrix.prototype,"c",{get:function(){return this._matrix[2]},set:function(value){this._matrix[2]=value}}),Object.defineProperty(Matrix.prototype,"d",{get:function(){return this._matrix[3]},set:function(value){this._matrix[3]=value}}),Object.defineProperty(Matrix.prototype,"e",{get:function(){return this._matrix[4]},set:function(value){this._matrix[4]=value}}),Object.defineProperty(Matrix.prototype,"f",{get:function(){return this._matrix[5]},set:function(value){this._matrix[5]=value}}),Object.defineProperty(Matrix.prototype,"rotation",{get:function(){return Math.atan2(this.shx,this.sx)}}),Object.defineProperty(Matrix.prototype,"scaleX",{get:function(){return this.decompose().scale.sx}}),Object.defineProperty(Matrix.prototype,"scaleY",{get:function(){return this.decompose().scale.sy}}),Object.defineProperty(Matrix.prototype,"isIdentity",{get:function(){return 1===this.sx&&(0===this.shy&&(0===this.shx&&(1===this.sy&&(0===this.tx&&0===this.ty))))}}),Matrix.prototype.join=function(separator){return[this.sx,this.shy,this.shx,this.sy,this.tx,this.ty].map(hpf).join(separator)},Matrix.prototype.multiply=function(matrix){var sx=matrix.sx*this.sx+matrix.shy*this.shx,shy=matrix.sx*this.shy+matrix.shy*this.sy,shx=matrix.shx*this.sx+matrix.sy*this.shx,sy=matrix.shx*this.shy+matrix.sy*this.sy,tx=matrix.tx*this.sx+matrix.ty*this.shx+this.tx,ty=matrix.tx*this.shy+matrix.ty*this.sy+this.ty;return new Matrix(sx,shy,shx,sy,tx,ty)},Matrix.prototype.decompose=function(){var a=this.sx,b=this.shy,c=this.shx,d=this.sy,e=this.tx,f=this.ty,scaleX=Math.sqrt(a*a+b*b),shear=(a/=scaleX)*c+(b/=scaleX)*d;c-=a*shear,d-=b*shear;var scaleY=Math.sqrt(c*c+d*d);return shear/=scaleY,a*(d/=scaleY)<b*(c/=scaleY)&&(a=-a,b=-b,shear=-shear,scaleX=-scaleX),{scale:new Matrix(scaleX,0,0,scaleY,0,0),translate:new Matrix(1,0,0,1,e,f),rotate:new Matrix(a,b,-b,a,0,0),skew:new Matrix(1,0,shear,1,0,0)}},Matrix.prototype.toString=function(parmPrecision){return this.join(" ")},Matrix.prototype.inversed=function(){var a=this.sx,b=this.shy,c=this.shx,d=this.sy,e=this.tx,f=this.ty,quot=1/(a*d-b*c),aInv=d*quot,bInv=-b*quot,cInv=-c*quot,dInv=a*quot;return new Matrix(aInv,bInv,cInv,dInv,-aInv*e-cInv*f,-bInv*e-dInv*f)},Matrix.prototype.applyToPoint=function(pt){var x=pt.x*this.sx+pt.y*this.shx+this.tx,y=pt.x*this.shy+pt.y*this.sy+this.ty;return new Point(x,y)},Matrix.prototype.applyToRectangle=function(rect){var pt1=this.applyToPoint(rect),pt2=this.applyToPoint(new Point(rect.x+rect.w,rect.y+rect.h));return new Rectangle(pt1.x,pt1.y,pt2.x-pt1.x,pt2.y-pt1.y)},Matrix.prototype.clone=function(){var sx=this.sx,shy=this.shy,shx=this.shx,sy=this.sy,tx=this.tx,ty=this.ty;return new Matrix(sx,shy,shx,sy,tx,ty)},API.Matrix=Matrix;var matrixMult=API.matrixMult=function(m1,m2){return m2.multiply(m1)},identityMatrix=new Matrix(1,0,0,1,0,0);API.unitMatrix=API.identityMatrix=identityMatrix;var addPattern=function(key,pattern){if(!patternMap[key]){var patternKey=(pattern instanceof ShadingPattern?"Sh":"P")+(Object.keys(patterns).length+1).toString(10);pattern.id=patternKey,patternMap[key]=patternKey,patterns[patternKey]=pattern,events.publish("addPattern",pattern)}};API.ShadingPattern=ShadingPattern,API.TilingPattern=TilingPattern,API.addShadingPattern=function(key,pattern){return advancedApiModeTrap("addShadingPattern()"),addPattern(key,pattern),this},API.beginTilingPattern=function(pattern){advancedApiModeTrap("beginTilingPattern()"),beginNewRenderTarget(pattern.boundingBox[0],pattern.boundingBox[1],pattern.boundingBox[2]-pattern.boundingBox[0],pattern.boundingBox[3]-pattern.boundingBox[1],pattern.matrix)},API.endTilingPattern=function(key,pattern){advancedApiModeTrap("endTilingPattern()"),pattern.stream=pages[currentPage].join("\n"),addPattern(key,pattern),events.publish("endTilingPattern",pattern),renderTargetStack.pop().restore()};var newObject=API.__private__.newObject=function(){var oid=newObjectDeferred();return newObjectDeferredBegin(oid,!0),oid},newObjectDeferred=API.__private__.newObjectDeferred=function(){return objectNumber++,offsets[objectNumber]=function(){return contentLength},objectNumber},newObjectDeferredBegin=function(oid,doOutput){return doOutput="boolean"==typeof doOutput&&doOutput,offsets[oid]=contentLength,doOutput&&out(oid+" 0 obj"),oid},newAdditionalObject=API.__private__.newAdditionalObject=function(){var obj={objId:newObjectDeferred(),content:""};return additionalObjects.push(obj),obj},rootDictionaryObjId=newObjectDeferred(),resourceDictionaryObjId=newObjectDeferred(),decodeColorString=API.__private__.decodeColorString=function(color){var colorEncoded=color.split(" ");if(2!==colorEncoded.length||"g"!==colorEncoded[1]&&"G"!==colorEncoded[1]){if(5===colorEncoded.length&&("k"===colorEncoded[4]||"K"===colorEncoded[4])){colorEncoded=[(1-colorEncoded[0])*(1-colorEncoded[3]),(1-colorEncoded[1])*(1-colorEncoded[3]),(1-colorEncoded[2])*(1-colorEncoded[3]),"r"]}}else{var floatVal=parseFloat(colorEncoded[0]);colorEncoded=[floatVal,floatVal,floatVal,"r"]}for(var colorAsRGB="#",i=0;i<3;i++)colorAsRGB+=("0"+Math.floor(255*parseFloat(colorEncoded[i])).toString(16)).slice(-2);return colorAsRGB},encodeColorString=API.__private__.encodeColorString=function(options){var color;"string"==typeof options&&(options={ch1:options});var ch1=options.ch1,ch2=options.ch2,ch3=options.ch3,ch4=options.ch4,letterArray="draw"===options.pdfColorType?["G","RG","K"]:["g","rg","k"];if("string"==typeof ch1&&"#"!==ch1.charAt(0)){var rgbColor=new RGBColor(ch1);if(rgbColor.ok)ch1=rgbColor.toHex();else if(!/^\d*\.?\d*$/.test(ch1))throw new Error('Invalid color "'+ch1+'" passed to jsPDF.encodeColorString.')}if("string"==typeof ch1&&/^#[0-9A-Fa-f]{3}$/.test(ch1)&&(ch1="#"+ch1[1]+ch1[1]+ch1[2]+ch1[2]+ch1[3]+ch1[3]),"string"==typeof ch1&&/^#[0-9A-Fa-f]{6}$/.test(ch1)){var hex=parseInt(ch1.substr(1),16);ch1=hex>>16&255,ch2=hex>>8&255,ch3=255&hex}if(void 0===ch2||void 0===ch4&&ch1===ch2&&ch2===ch3)if("string"==typeof ch1)color=ch1+" "+letterArray[0];else if(2===options.precision)color=f2(ch1/255)+" "+letterArray[0];else color=f3(ch1/255)+" "+letterArray[0];else if(void 0===ch4||"object"===_typeof(ch4)){if(ch4&&!isNaN(ch4.a)&&0===ch4.a)return color=["1.","1.","1.",letterArray[1]].join(" ");if("string"==typeof ch1)color=[ch1,ch2,ch3,letterArray[1]].join(" ");else if(2===options.precision)color=[f2(ch1/255),f2(ch2/255),f2(ch3/255),letterArray[1]].join(" ");else color=[f3(ch1/255),f3(ch2/255),f3(ch3/255),letterArray[1]].join(" ")}else if("string"==typeof ch1)color=[ch1,ch2,ch3,ch4,letterArray[2]].join(" ");else if(2===options.precision)color=[f2(ch1),f2(ch2),f2(ch3),f2(ch4),letterArray[2]].join(" ");else color=[f3(ch1),f3(ch2),f3(ch3),f3(ch4),letterArray[2]].join(" ");return color},getFilters=API.__private__.getFilters=function(){return filters},putStream=API.__private__.putStream=function(options){var data=(options=options||{}).data||"",filters=options.filters||getFilters(),alreadyAppliedFilters=options.alreadyAppliedFilters||[],addLength1=options.addLength1||!1,valueOfLength1=data.length,objectId=options.objectId,encryptor=function(data){return data};if(null!==encryptionOptions&&void 0===objectId)throw new Error("ObjectId must be passed to putStream for file encryption");null!==encryptionOptions&&(encryptor=encryption.encryptor(objectId,0));var processedData={};!0===filters&&(filters=["FlateEncode"]);var keyValues=options.additionalKeyValues||[],filterAsString=(processedData=void 0!==jsPDF.API.processDataByFilters?jsPDF.API.processDataByFilters(data,filters):{data:data,reverseChain:[]}).reverseChain+(Array.isArray(alreadyAppliedFilters)?alreadyAppliedFilters.join(" "):alreadyAppliedFilters.toString());if(0!==processedData.data.length&&(keyValues.push({key:"Length",value:processedData.data.length}),!0===addLength1&&keyValues.push({key:"Length1",value:valueOfLength1})),0!=filterAsString.length)if(filterAsString.split("/").length-1==1)keyValues.push({key:"Filter",value:filterAsString});else{keyValues.push({key:"Filter",value:"["+filterAsString+"]"});for(var j=0;j<keyValues.length;j+=1)if("DecodeParms"===keyValues[j].key){for(var decodeParmsArray=[],i=0;i<processedData.reverseChain.split("/").length-1;i+=1)decodeParmsArray.push("null");decodeParmsArray.push(keyValues[j].value),keyValues[j].value="["+decodeParmsArray.join(" ")+"]"}}out("<<");for(var k=0;k<keyValues.length;k++)out("/"+keyValues[k].key+" "+keyValues[k].value);out(">>"),0!==processedData.data.length&&(out("stream"),out(encryptor(processedData.data)),out("endstream"))},putPage=API.__private__.putPage=function(page){var pageNumber=page.number,data=page.data,pageObjectNumber=page.objId,pageContentsObjId=page.contentsObjId;newObjectDeferredBegin(pageObjectNumber,!0),out("<</Type /Page"),out("/Parent "+page.rootDictionaryObjId+" 0 R"),out("/Resources "+page.resourceDictionaryObjId+" 0 R"),out("/MediaBox ["+parseFloat(hpf(page.mediaBox.bottomLeftX))+" "+parseFloat(hpf(page.mediaBox.bottomLeftY))+" "+hpf(page.mediaBox.topRightX)+" "+hpf(page.mediaBox.topRightY)+"]"),null!==page.cropBox&&out("/CropBox ["+hpf(page.cropBox.bottomLeftX)+" "+hpf(page.cropBox.bottomLeftY)+" "+hpf(page.cropBox.topRightX)+" "+hpf(page.cropBox.topRightY)+"]"),null!==page.bleedBox&&out("/BleedBox ["+hpf(page.bleedBox.bottomLeftX)+" "+hpf(page.bleedBox.bottomLeftY)+" "+hpf(page.bleedBox.topRightX)+" "+hpf(page.bleedBox.topRightY)+"]"),null!==page.trimBox&&out("/TrimBox ["+hpf(page.trimBox.bottomLeftX)+" "+hpf(page.trimBox.bottomLeftY)+" "+hpf(page.trimBox.topRightX)+" "+hpf(page.trimBox.topRightY)+"]"),null!==page.artBox&&out("/ArtBox ["+hpf(page.artBox.bottomLeftX)+" "+hpf(page.artBox.bottomLeftY)+" "+hpf(page.artBox.topRightX)+" "+hpf(page.artBox.topRightY)+"]"),"number"==typeof page.userUnit&&1!==page.userUnit&&out("/UserUnit "+page.userUnit),events.publish("putPage",{objId:pageObjectNumber,pageContext:pagesContext[pageNumber],pageNumber:pageNumber,page:data}),out("/Contents "+pageContentsObjId+" 0 R"),out(">>"),out("endobj");var pageContent=data.join("\n");return apiMode===ApiMode.ADVANCED&&(pageContent+="\nQ"),newObjectDeferredBegin(pageContentsObjId,!0),putStream({data:pageContent,filters:getFilters(),objectId:pageContentsObjId}),out("endobj"),pageObjectNumber},putPages=API.__private__.putPages=function(){var n,i,pageObjectNumbers=[];for(n=1;n<=page;n++)pagesContext[n].objId=newObjectDeferred(),pagesContext[n].contentsObjId=newObjectDeferred();for(n=1;n<=page;n++)pageObjectNumbers.push(putPage({number:n,data:pages[n],objId:pagesContext[n].objId,contentsObjId:pagesContext[n].contentsObjId,mediaBox:pagesContext[n].mediaBox,cropBox:pagesContext[n].cropBox,bleedBox:pagesContext[n].bleedBox,trimBox:pagesContext[n].trimBox,artBox:pagesContext[n].artBox,userUnit:pagesContext[n].userUnit,rootDictionaryObjId:rootDictionaryObjId,resourceDictionaryObjId:resourceDictionaryObjId}));newObjectDeferredBegin(rootDictionaryObjId,!0),out("<</Type /Pages");var kids="/Kids [";for(i=0;i<page;i++)kids+=pageObjectNumbers[i]+" 0 R ";out(kids+"]"),out("/Count "+page),out(">>"),out("endobj"),events.publish("postPutPages")},putFont=function(font){events.publish("putFont",{font:font,out:out,newObject:newObject,putStream:putStream}),!0!==font.isAlreadyPutted&&(font.objectNumber=newObject(),out("<<"),out("/Type /Font"),out("/BaseFont /"+toPDFName(font.postScriptName)),out("/Subtype /Type1"),"string"==typeof font.encoding&&out("/Encoding /"+font.encoding),out("/FirstChar 32"),out("/LastChar 255"),out(">>"),out("endobj"))},putFonts=function(){for(var fontKey in fonts)fonts.hasOwnProperty(fontKey)&&(!1===putOnlyUsedFonts||!0===putOnlyUsedFonts&&usedFonts.hasOwnProperty(fontKey))&&putFont(fonts[fontKey])},putXObject=function(xObject){xObject.objectNumber=newObject();var options=[];options.push({key:"Type",value:"/XObject"}),options.push({key:"Subtype",value:"/Form"}),options.push({key:"BBox",value:"["+[hpf(xObject.x),hpf(xObject.y),hpf(xObject.x+xObject.width),hpf(xObject.y+xObject.height)].join(" ")+"]"}),options.push({key:"Matrix",value:"["+xObject.matrix.toString()+"]"});var stream=xObject.pages[1].join("\n");putStream({data:stream,additionalKeyValues:options,objectId:xObject.objectNumber}),out("endobj")},putXObjects=function(){for(var xObjectKey in renderTargets)renderTargets.hasOwnProperty(xObjectKey)&&putXObject(renderTargets[xObjectKey])},interpolateAndEncodeRGBStream=function(colors,numberSamples){var t,tValues=[],dT=1/(numberSamples-1);for(t=0;t<1;t+=dT)tValues.push(t);if(tValues.push(1),0!=colors[0].offset){var c0={offset:0,color:colors[0].color};colors.unshift(c0)}if(1!=colors[colors.length-1].offset){var c1={offset:1,color:colors[colors.length-1].color};colors.push(c1)}for(var out="",index=0,i=0;i<tValues.length;i++){for(t=tValues[i];t>colors[index+1].offset;)index++;var a=colors[index].offset,d=(t-a)/(colors[index+1].offset-a),aColor=colors[index].color,bColor=colors[index+1].color;out+=padd2Hex(Math.round((1-d)*aColor[0]+d*bColor[0]).toString(16))+padd2Hex(Math.round((1-d)*aColor[1]+d*bColor[1]).toString(16))+padd2Hex(Math.round((1-d)*aColor[2]+d*bColor[2]).toString(16))}return out.trim()},putShadingPattern=function(pattern,numberSamples){numberSamples||(numberSamples=21);var funcObjectNumber=newObject(),stream=interpolateAndEncodeRGBStream(pattern.colors,numberSamples),options=[];options.push({key:"FunctionType",value:"0"}),options.push({key:"Domain",value:"[0.0 1.0]"}),options.push({key:"Size",value:"["+numberSamples+"]"}),options.push({key:"BitsPerSample",value:"8"}),options.push({key:"Range",value:"[0.0 1.0 0.0 1.0 0.0 1.0]"}),options.push({key:"Decode",value:"[0.0 1.0 0.0 1.0 0.0 1.0]"}),putStream({data:stream,additionalKeyValues:options,alreadyAppliedFilters:["/ASCIIHexDecode"],objectId:funcObjectNumber}),out("endobj"),pattern.objectNumber=newObject(),out("<< /ShadingType "+pattern.type),out("/ColorSpace /DeviceRGB");var coords="/Coords ["+hpf(parseFloat(pattern.coords[0]))+" "+hpf(parseFloat(pattern.coords[1]))+" ";2===pattern.type?coords+=hpf(parseFloat(pattern.coords[2]))+" "+hpf(parseFloat(pattern.coords[3])):coords+=hpf(parseFloat(pattern.coords[2]))+" "+hpf(parseFloat(pattern.coords[3]))+" "+hpf(parseFloat(pattern.coords[4]))+" "+hpf(parseFloat(pattern.coords[5])),out(coords+="]"),pattern.matrix&&out("/Matrix ["+pattern.matrix.toString()+"]"),out("/Function "+funcObjectNumber+" 0 R"),out("/Extend [true true]"),out(">>"),out("endobj")},putTilingPattern=function(pattern,deferredResourceDictionaryIds){var resourcesObjectId=newObjectDeferred(),patternObjectId=newObject();deferredResourceDictionaryIds.push({resourcesOid:resourcesObjectId,objectOid:patternObjectId}),pattern.objectNumber=patternObjectId;var options=[];options.push({key:"Type",value:"/Pattern"}),options.push({key:"PatternType",value:"1"}),options.push({key:"PaintType",value:"1"}),options.push({key:"TilingType",value:"1"}),options.push({key:"BBox",value:"["+pattern.boundingBox.map(hpf).join(" ")+"]"}),options.push({key:"XStep",value:hpf(pattern.xStep)}),options.push({key:"YStep",value:hpf(pattern.yStep)}),options.push({key:"Resources",value:resourcesObjectId+" 0 R"}),pattern.matrix&&options.push({key:"Matrix",value:"["+pattern.matrix.toString()+"]"}),putStream({data:pattern.stream,additionalKeyValues:options,objectId:pattern.objectNumber}),out("endobj")},putPatterns=function(deferredResourceDictionaryIds){var patternKey;for(patternKey in patterns)patterns.hasOwnProperty(patternKey)&&(patterns[patternKey]instanceof ShadingPattern?putShadingPattern(patterns[patternKey]):patterns[patternKey]instanceof TilingPattern&&putTilingPattern(patterns[patternKey],deferredResourceDictionaryIds))},putGState=function(gState){for(var p in gState.objectNumber=newObject(),out("<<"),gState)switch(p){case"opacity":out("/ca "+f2(gState[p]));break;case"stroke-opacity":out("/CA "+f2(gState[p]))}out(">>"),out("endobj")},putGStates=function(){var gStateKey;for(gStateKey in gStates)gStates.hasOwnProperty(gStateKey)&&putGState(gStates[gStateKey])},putXobjectDict=function(){for(var xObjectKey in out("/XObject <<"),renderTargets)renderTargets.hasOwnProperty(xObjectKey)&&renderTargets[xObjectKey].objectNumber>=0&&out("/"+xObjectKey+" "+renderTargets[xObjectKey].objectNumber+" 0 R");events.publish("putXobjectDict"),out(">>")},putEncryptionDict=function(){encryption.oid=newObject(),out("<<"),out("/Filter /Standard"),out("/V "+encryption.v),out("/R "+encryption.r),out("/U <"+encryption.toHexString(encryption.U)+">"),out("/O <"+encryption.toHexString(encryption.O)+">"),out("/P "+encryption.P),out(">>"),out("endobj")},putFontDict=function(){for(var fontKey in out("/Font <<"),fonts)fonts.hasOwnProperty(fontKey)&&(!1===putOnlyUsedFonts||!0===putOnlyUsedFonts&&usedFonts.hasOwnProperty(fontKey))&&out("/"+fontKey+" "+fonts[fontKey].objectNumber+" 0 R");out(">>")},putShadingPatternDict=function(){if(Object.keys(patterns).length>0){for(var patternKey in out("/Shading <<"),patterns)patterns.hasOwnProperty(patternKey)&&patterns[patternKey]instanceof ShadingPattern&&patterns[patternKey].objectNumber>=0&&out("/"+patternKey+" "+patterns[patternKey].objectNumber+" 0 R");events.publish("putShadingPatternDict"),out(">>")}},putTilingPatternDict=function(objectOid){if(Object.keys(patterns).length>0){for(var patternKey in out("/Pattern <<"),patterns)patterns.hasOwnProperty(patternKey)&&patterns[patternKey]instanceof API.TilingPattern&&patterns[patternKey].objectNumber>=0&&patterns[patternKey].objectNumber<objectOid&&out("/"+patternKey+" "+patterns[patternKey].objectNumber+" 0 R");events.publish("putTilingPatternDict"),out(">>")}},putGStatesDict=function(){if(Object.keys(gStates).length>0){var gStateKey;for(gStateKey in out("/ExtGState <<"),gStates)gStates.hasOwnProperty(gStateKey)&&gStates[gStateKey].objectNumber>=0&&out("/"+gStateKey+" "+gStates[gStateKey].objectNumber+" 0 R");events.publish("putGStateDict"),out(">>")}},putResourceDictionary=function(objectIds){newObjectDeferredBegin(objectIds.resourcesOid,!0),out("<<"),out("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]"),putFontDict(),putShadingPatternDict(),putTilingPatternDict(objectIds.objectOid),putGStatesDict(),putXobjectDict(),out(">>"),out("endobj")},putResources=function(){var deferredResourceDictionaryIds=[];putFonts(),putGStates(),putXObjects(),putPatterns(deferredResourceDictionaryIds),events.publish("putResources"),deferredResourceDictionaryIds.forEach(putResourceDictionary),putResourceDictionary({resourcesOid:resourceDictionaryObjId,objectOid:Number.MAX_SAFE_INTEGER}),events.publish("postPutResources")},putAdditionalObjects=function(){events.publish("putAdditionalObjects");for(var i=0;i<additionalObjects.length;i++){var obj=additionalObjects[i];newObjectDeferredBegin(obj.objId,!0),out(obj.content),out("endobj")}events.publish("postPutAdditionalObjects")},addFontToFontDictionary=function(font){fontmap[font.fontName]=fontmap[font.fontName]||{},fontmap[font.fontName][font.fontStyle]=font.id},addFont=function(postScriptName,fontName,fontStyle,encoding,isStandardFont){var font={id:"F"+(Object.keys(fonts).length+1).toString(10),postScriptName:postScriptName,fontName:fontName,fontStyle:fontStyle,encoding:encoding,isStandardFont:isStandardFont||!1,metadata:{}};return events.publish("addFont",{font:font,instance:this}),fonts[font.id]=font,addFontToFontDictionary(font),font.id},addFonts=function(arrayOfFonts){for(var i=0,l=standardFonts.length;i<l;i++){var fontKey=addFont.call(this,arrayOfFonts[i][0],arrayOfFonts[i][1],arrayOfFonts[i][2],standardFonts[i][3],!0);!1===putOnlyUsedFonts&&(usedFonts[fontKey]=!0);var parts=arrayOfFonts[i][0].split("-");addFontToFontDictionary({id:fontKey,fontName:parts[0],fontStyle:parts[1]||""})}events.publish("addFonts",{fonts:fonts,dictionary:fontmap})},SAFE=function(fn){return fn.foo=function(){try{return fn.apply(this,arguments)}catch(e){var stack=e.stack||"";~stack.indexOf(" at ")&&(stack=stack.split(" at ")[1]);var m="Error in function "+stack.split("\n")[0].split("<")[0]+": "+e.message;if(!globalObject.console)throw new Error(m);globalObject.console.error(m,e),globalObject.alert&&alert(m)}},fn.foo.bar=fn,fn.foo},to8bitStream=function(text,flags){var i,l,sourceEncoding,encodingBlock,outputEncoding,newtext,isUnicode,ch,bch;if(sourceEncoding=(flags=flags||{}).sourceEncoding||"Unicode",outputEncoding=flags.outputEncoding,(flags.autoencode||outputEncoding)&&fonts[activeFontKey].metadata&&fonts[activeFontKey].metadata[sourceEncoding]&&fonts[activeFontKey].metadata[sourceEncoding].encoding&&(encodingBlock=fonts[activeFontKey].metadata[sourceEncoding].encoding,!outputEncoding&&fonts[activeFontKey].encoding&&(outputEncoding=fonts[activeFontKey].encoding),!outputEncoding&&encodingBlock.codePages&&(outputEncoding=encodingBlock.codePages[0]),"string"==typeof outputEncoding&&(outputEncoding=encodingBlock[outputEncoding]),outputEncoding)){for(isUnicode=!1,newtext=[],i=0,l=text.length;i<l;i++)(ch=outputEncoding[text.charCodeAt(i)])?newtext.push(String.fromCharCode(ch)):newtext.push(text[i]),newtext[i].charCodeAt(0)>>8&&(isUnicode=!0);text=newtext.join("")}for(i=text.length;void 0===isUnicode&&0!==i;)text.charCodeAt(i-1)>>8&&(isUnicode=!0),i--;if(!isUnicode)return text;for(newtext=flags.noBOM?[]:[254,255],i=0,l=text.length;i<l;i++){if((bch=(ch=text.charCodeAt(i))>>8)>>8)throw new Error("Character at position "+i+" of string '"+text+"' exceeds 16bits. Cannot be encoded into UCS-2 BE");newtext.push(bch),newtext.push(ch-(bch<<8))}return String.fromCharCode.apply(void 0,newtext)},pdfEscape=API.__private__.pdfEscape=API.pdfEscape=function(text,flags){return to8bitStream(text,flags).replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")},beginPage=API.__private__.beginPage=function(format){pages[++page]=[],pagesContext[page]={objId:0,contentsObjId:0,userUnit:Number(userUnit),artBox:null,bleedBox:null,cropBox:null,trimBox:null,mediaBox:{bottomLeftX:0,bottomLeftY:0,topRightX:Number(format[0]),topRightY:Number(format[1])}},_setPage(page),setOutputDestination(pages[currentPage])},_addPage=function(parmFormat,parmOrientation){var dimensions,width,height;switch(orientation=parmOrientation||orientation,"string"==typeof parmFormat&&(dimensions=getPageFormat(parmFormat.toLowerCase()),Array.isArray(dimensions)&&(width=dimensions[0],height=dimensions[1])),Array.isArray(parmFormat)&&(width=parmFormat[0]*scaleFactor,height=parmFormat[1]*scaleFactor),isNaN(width)&&(width=format[0],height=format[1]),(width>14400||height>14400)&&(console.warn("A page in a PDF can not be wider or taller than 14400 userUnit. jsPDF limits the width/height to 14400"),width=Math.min(14400,width),height=Math.min(14400,height)),format=[width,height],orientation.substr(0,1)){case"l":height>width&&(format=[height,width]);break;case"p":width>height&&(format=[height,width])}beginPage(format),setLineWidth(lineWidth),out(strokeColor),0!==lineCapID&&out(lineCapID+" J"),0!==lineJoinID&&out(lineJoinID+" j"),events.publish("addPage",{pageNumber:page})},_deletePage=function(n){n>0&&n<=page&&(pages.splice(n,1),pagesContext.splice(n,1),page--,currentPage>page&&(currentPage=page),this.setPage(currentPage))},_setPage=function(n){n>0&&n<=page&&(currentPage=n)},getNumberOfPages=API.__private__.getNumberOfPages=API.getNumberOfPages=function(){return pages.length-1},getFont=function(fontName,fontStyle,options){var fontNameLowerCase,key=void 0;return options=options||{},fontName=void 0!==fontName?fontName:fonts[activeFontKey].fontName,fontStyle=void 0!==fontStyle?fontStyle:fonts[activeFontKey].fontStyle,fontNameLowerCase=fontName.toLowerCase(),void 0!==fontmap[fontNameLowerCase]&&void 0!==fontmap[fontNameLowerCase][fontStyle]?key=fontmap[fontNameLowerCase][fontStyle]:void 0!==fontmap[fontName]&&void 0!==fontmap[fontName][fontStyle]?key=fontmap[fontName][fontStyle]:!1===options.disableWarning&&console.warn("Unable to look up font label for font '"+fontName+"', '"+fontStyle+"'. Refer to getFontList() for available fonts."),key||options.noFallback||null==(key=fontmap.times[fontStyle])&&(key=fontmap.times.normal),key},putInfo=API.__private__.putInfo=function(){var objectId=newObject(),encryptor=function(data){return data};for(var key in null!==encryptionOptions&&(encryptor=encryption.encryptor(objectId,0)),out("<<"),out("/Producer ("+pdfEscape(encryptor("jsPDF "+jsPDF.version))+")"),documentProperties)documentProperties.hasOwnProperty(key)&&documentProperties[key]&&out("/"+key.substr(0,1).toUpperCase()+key.substr(1)+" ("+pdfEscape(encryptor(documentProperties[key]))+")");out("/CreationDate ("+pdfEscape(encryptor(creationDate))+")"),out(">>"),out("endobj")},putCatalog=API.__private__.putCatalog=function(options){var tmpRootDictionaryObjId=(options=options||{}).rootDictionaryObjId||rootDictionaryObjId;switch(newObject(),out("<<"),out("/Type /Catalog"),out("/Pages "+tmpRootDictionaryObjId+" 0 R"),zoomMode||(zoomMode="fullwidth"),zoomMode){case"fullwidth":out("/OpenAction [3 0 R /FitH null]");break;case"fullheight":out("/OpenAction [3 0 R /FitV null]");break;case"fullpage":out("/OpenAction [3 0 R /Fit]");break;case"original":out("/OpenAction [3 0 R /XYZ null null 1]");break;default:var pcn=""+zoomMode;"%"===pcn.substr(pcn.length-1)&&(zoomMode=parseInt(zoomMode)/100),"number"==typeof zoomMode&&out("/OpenAction [3 0 R /XYZ null null "+f2(zoomMode)+"]")}switch(layoutMode||(layoutMode="continuous"),layoutMode){case"continuous":out("/PageLayout /OneColumn");break;case"single":out("/PageLayout /SinglePage");break;case"two":case"twoleft":out("/PageLayout /TwoColumnLeft");break;case"tworight":out("/PageLayout /TwoColumnRight")}pageMode&&out("/PageMode /"+pageMode),events.publish("putCatalog"),out(">>"),out("endobj")},putTrailer=API.__private__.putTrailer=function(){out("trailer"),out("<<"),out("/Size "+(objectNumber+1)),out("/Root "+objectNumber+" 0 R"),out("/Info "+(objectNumber-1)+" 0 R"),null!==encryptionOptions&&out("/Encrypt "+encryption.oid+" 0 R"),out("/ID [ <"+fileId+"> <"+fileId+"> ]"),out(">>")},putHeader=API.__private__.putHeader=function(){out("%PDF-"+pdfVersion),out("%ºß¬à")},putXRef=API.__private__.putXRef=function(){var p="0000000000";out("xref"),out("0 "+(objectNumber+1)),out("0000000000 65535 f ");for(var i=1;i<=objectNumber;i++){"function"==typeof offsets[i]?out((p+offsets[i]()).slice(-10)+" 00000 n "):void 0!==offsets[i]?out((p+offsets[i]).slice(-10)+" 00000 n "):out("0000000000 00000 n ")}},buildDocument=API.__private__.buildDocument=function(){resetDocument(),setOutputDestination(content),events.publish("buildDocument"),putHeader(),putPages(),putAdditionalObjects(),putResources(),null!==encryptionOptions&&putEncryptionDict(),putInfo(),putCatalog();var offsetOfXRef=contentLength;return putXRef(),putTrailer(),out("startxref"),out(""+offsetOfXRef),out("%%EOF"),setOutputDestination(pages[currentPage]),content.join("\n")},getBlob=API.__private__.getBlob=function(data){return new Blob([getArrayBuffer(data)],{type:"application/pdf"})},output=API.output=API.__private__.output=SAFE((function(type,options){switch("string"==typeof(options=options||{})?options={filename:options}:options.filename=options.filename||"generated.pdf",type){case void 0:return buildDocument();case"save":API.save(options.filename);break;case"arraybuffer":return getArrayBuffer(buildDocument());case"blob":return getBlob(buildDocument());case"bloburi":case"bloburl":if(void 0!==globalObject.URL&&"function"==typeof globalObject.URL.createObjectURL)return globalObject.URL&&globalObject.URL.createObjectURL(getBlob(buildDocument()))||void 0;console.warn("bloburl is not supported by your system, because URL.createObjectURL is not supported by your browser.");break;case"datauristring":case"dataurlstring":var dataURI="",pdfDocument=buildDocument();try{dataURI=btoa(pdfDocument)}catch(e){dataURI=btoa(unescape(encodeURIComponent(pdfDocument)))}return"data:application/pdf;filename="+options.filename+";base64,"+dataURI;case"pdfobjectnewwindow":if("[object Window]"===Object.prototype.toString.call(globalObject)){var pdfObjectUrl="https://cdnjs.cloudflare.com/ajax/libs/pdfobject/2.1.1/pdfobject.min.js",integrity=' integrity="sha512-4ze/a9/4jqu+tX9dfOqJYSvyYd5M6qum/3HpCLr+/Jqf0whc37VUbkpNGHR7/8pSnCFw47T1fmIpwBV7UySh3g==" crossorigin="anonymous"';options.pdfObjectUrl&&(pdfObjectUrl=options.pdfObjectUrl,integrity="");var htmlForNewWindow='<html><style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;}  </style><body><script src="'+pdfObjectUrl+'"'+integrity+'><\/script><script >PDFObject.embed("'+this.output("dataurlstring")+'", '+JSON.stringify(options)+");<\/script></body></html>",nW=globalObject.open();return null!==nW&&nW.document.write(htmlForNewWindow),nW}throw new Error("The option pdfobjectnewwindow just works in a browser-environment.");case"pdfjsnewwindow":if("[object Window]"===Object.prototype.toString.call(globalObject)){var htmlForPDFjsNewWindow='<html><style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;}  </style><body><iframe id="pdfViewer" src="'+(options.pdfJsUrl||"examples/PDF.js/web/viewer.html")+"?file=&downloadName="+options.filename+'" width="500px" height="400px" /></body></html>',PDFjsNewWindow=globalObject.open();if(null!==PDFjsNewWindow){PDFjsNewWindow.document.write(htmlForPDFjsNewWindow);var scope=this;PDFjsNewWindow.document.documentElement.querySelector("#pdfViewer").onload=function(){PDFjsNewWindow.document.title=options.filename,PDFjsNewWindow.document.documentElement.querySelector("#pdfViewer").contentWindow.PDFViewerApplication.open(scope.output("bloburl"))}}return PDFjsNewWindow}throw new Error("The option pdfjsnewwindow just works in a browser-environment.");case"dataurlnewwindow":if("[object Window]"!==Object.prototype.toString.call(globalObject))throw new Error("The option dataurlnewwindow just works in a browser-environment.");var htmlForDataURLNewWindow='<html><style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;}  </style><body><iframe src="'+this.output("datauristring",options)+'"></iframe></body></html>',dataURLNewWindow=globalObject.open();if(null!==dataURLNewWindow&&(dataURLNewWindow.document.write(htmlForDataURLNewWindow),dataURLNewWindow.document.title=options.filename),dataURLNewWindow||"undefined"==typeof safari)return dataURLNewWindow;break;case"datauri":case"dataurl":return globalObject.document.location.href=this.output("datauristring",options);default:return null}})),hasHotfix=function(hotfixName){return!0===Array.isArray(hotfixes)&&hotfixes.indexOf(hotfixName)>-1};switch(unit){case"pt":scaleFactor=1;break;case"mm":scaleFactor=72/25.4;break;case"cm":scaleFactor=72/2.54;break;case"in":scaleFactor=72;break;case"px":scaleFactor=1==hasHotfix("px_scaling")?.75:96/72;break;case"pc":case"em":scaleFactor=12;break;case"ex":scaleFactor=6;break;default:if("number"!=typeof unit)throw new Error("Invalid unit: "+unit);scaleFactor=unit}var encryption=null;setCreationDate(),setFileId();var getEncryptor=function(objectId){return null!==encryptionOptions?encryption.encryptor(objectId,0):function(data){return data}},getPageInfo=API.__private__.getPageInfo=API.getPageInfo=function(pageNumberOneBased){if(isNaN(pageNumberOneBased)||pageNumberOneBased%1!=0)throw new Error("Invalid argument passed to jsPDF.getPageInfo");return{objId:pagesContext[pageNumberOneBased].objId,pageNumber:pageNumberOneBased,pageContext:pagesContext[pageNumberOneBased]}},getPageInfoByObjId=API.__private__.getPageInfoByObjId=function(objId){if(isNaN(objId)||objId%1!=0)throw new Error("Invalid argument passed to jsPDF.getPageInfoByObjId");for(var pageNumber in pagesContext)if(pagesContext[pageNumber].objId===objId)break;return getPageInfo(pageNumber)},getCurrentPageInfo=API.__private__.getCurrentPageInfo=API.getCurrentPageInfo=function(){return{objId:pagesContext[currentPage].objId,pageNumber:currentPage,pageContext:pagesContext[currentPage]}};API.addPage=function(){return _addPage.apply(this,arguments),this},API.setPage=function(){return _setPage.apply(this,arguments),setOutputDestination.call(this,pages[currentPage]),this},API.insertPage=function(beforePage){return this.addPage(),this.movePage(currentPage,beforePage),this},API.movePage=function(targetPage,beforePage){var tmpPages,tmpPagesContext;if(targetPage>beforePage){tmpPages=pages[targetPage],tmpPagesContext=pagesContext[targetPage];for(var i=targetPage;i>beforePage;i--)pages[i]=pages[i-1],pagesContext[i]=pagesContext[i-1];pages[beforePage]=tmpPages,pagesContext[beforePage]=tmpPagesContext,this.setPage(beforePage)}else if(targetPage<beforePage){tmpPages=pages[targetPage],tmpPagesContext=pagesContext[targetPage];for(var j=targetPage;j<beforePage;j++)pages[j]=pages[j+1],pagesContext[j]=pagesContext[j+1];pages[beforePage]=tmpPages,pagesContext[beforePage]=tmpPagesContext,this.setPage(beforePage)}return this},API.deletePage=function(){return _deletePage.apply(this,arguments),this},API.__private__.text=API.text=function(text,x,y,options,transform){var payload,da,angle,align,charSpace,maxWidth,flags,horizontalScale,transformationMatrix,scope=(options=options||{}).scope||this;if("number"==typeof text&&"number"==typeof x&&("string"==typeof y||Array.isArray(y))){var tmp=y;y=x,x=text,text=tmp}if(arguments[3]instanceof Matrix==!1?(angle=arguments[4],align=arguments[5],"object"===_typeof(flags=arguments[3])&&null!==flags||("string"==typeof angle&&(align=angle,angle=null),"string"==typeof flags&&(align=flags,flags=null),"number"==typeof flags&&(angle=flags,flags=null),options={flags:flags,angle:angle,align:align})):(advancedApiModeTrap("The transform parameter of text() with a Matrix value"),transformationMatrix=transform),isNaN(x)||isNaN(y)||null==text)throw new Error("Invalid arguments passed to jsPDF.text");if(0===text.length)return scope;var xtra="",isHex=!1,lineHeight="number"==typeof options.lineHeightFactor?options.lineHeightFactor:lineHeightFactor,scaleFactor=scope.internal.scaleFactor;function ESC(s){return s=s.split("\t").join(Array(options.TabLen||9).join(" ")),pdfEscape(s,flags)}function transformTextToSpecialArray(text){for(var curDa,sa=text.concat(),da=[],len=sa.length;len--;)"string"==typeof(curDa=sa.shift())?da.push(curDa):Array.isArray(text)&&(1===curDa.length||void 0===curDa[1]&&void 0===curDa[2])?da.push(curDa[0]):da.push([curDa[0],curDa[1],curDa[2]]);return da}function processTextByFunction(text,processingFunction){var result;if("string"==typeof text)result=processingFunction(text)[0];else if(Array.isArray(text)){for(var curDa,tmpResult,sa=text.concat(),da=[],len=sa.length;len--;)"string"==typeof(curDa=sa.shift())?da.push(processingFunction(curDa)[0]):Array.isArray(curDa)&&"string"==typeof curDa[0]&&(tmpResult=processingFunction(curDa[0],curDa[1],curDa[2]),da.push([tmpResult[0],tmpResult[1],tmpResult[2]]));result=da}return result}var textIsOfTypeString=!1,tmpTextIsOfTypeString=!0;if("string"==typeof text)textIsOfTypeString=!0;else if(Array.isArray(text)){var sa=text.concat();da=[];for(var curDa,len=sa.length;len--;)("string"!=typeof(curDa=sa.shift())||Array.isArray(curDa)&&"string"!=typeof curDa[0])&&(tmpTextIsOfTypeString=!1);textIsOfTypeString=tmpTextIsOfTypeString}if(!1===textIsOfTypeString)throw new Error('Type of text must be string or Array. "'+text+'" is not recognized.');"string"==typeof text&&(text=text.match(/[\r?\n]/)?text.split(/\r\n|\r|\n/g):[text]);var height=activeFontSize/scope.internal.scaleFactor,descent=height*(lineHeight-1);switch(options.baseline){case"bottom":y-=descent;break;case"top":y+=height-descent;break;case"hanging":y+=height-2*descent;break;case"middle":y+=height/2-descent}if((maxWidth=options.maxWidth||0)>0&&("string"==typeof text?text=scope.splitTextToSize(text,maxWidth):"[object Array]"===Object.prototype.toString.call(text)&&(text=text.reduce((function(acc,textLine){return acc.concat(scope.splitTextToSize(textLine,maxWidth))}),[]))),payload={text:text,x:x,y:y,options:options,mutex:{pdfEscape:pdfEscape,activeFontKey:activeFontKey,fonts:fonts,activeFontSize:activeFontSize}},events.publish("preProcessText",payload),text=payload.text,angle=(options=payload.options).angle,transformationMatrix instanceof Matrix==!1&&angle&&"number"==typeof angle){angle*=Math.PI/180,0===options.rotationDirection&&(angle=-angle),apiMode===ApiMode.ADVANCED&&(angle=-angle);var c=Math.cos(angle),s=Math.sin(angle);transformationMatrix=new Matrix(c,s,-s,c,0,0)}else angle&&angle instanceof Matrix&&(transformationMatrix=angle);apiMode!==ApiMode.ADVANCED||transformationMatrix||(transformationMatrix=identityMatrix),void 0!==(charSpace=options.charSpace||activeCharSpace)&&(xtra+=hpf(scale(charSpace))+" Tc\n",this.setCharSpace(this.getCharSpace()||0)),void 0!==(horizontalScale=options.horizontalScale)&&(xtra+=hpf(100*horizontalScale)+" Tz\n");options.lang;var renderingMode=-1,parmRenderingMode=void 0!==options.renderingMode?options.renderingMode:options.stroke,pageContext=scope.internal.getCurrentPageInfo().pageContext;switch(parmRenderingMode){case 0:case!1:case"fill":renderingMode=0;break;case 1:case!0:case"stroke":renderingMode=1;break;case 2:case"fillThenStroke":renderingMode=2;break;case 3:case"invisible":renderingMode=3;break;case 4:case"fillAndAddForClipping":renderingMode=4;break;case 5:case"strokeAndAddPathForClipping":renderingMode=5;break;case 6:case"fillThenStrokeAndAddToPathForClipping":renderingMode=6;break;case 7:case"addToPathForClipping":renderingMode=7}var usedRenderingMode=void 0!==pageContext.usedRenderingMode?pageContext.usedRenderingMode:-1;-1!==renderingMode?xtra+=renderingMode+" Tr\n":-1!==usedRenderingMode&&(xtra+="0 Tr\n"),-1!==renderingMode&&(pageContext.usedRenderingMode=renderingMode),align=options.align||"left";var lineWidths,leading=activeFontSize*lineHeight,pageWidth=scope.internal.pageSize.getWidth(),activeFont=fonts[activeFontKey];charSpace=options.charSpace||activeCharSpace,maxWidth=options.maxWidth||0,flags=Object.assign({autoencode:!0,noBOM:!0},options.flags);var wordSpacingPerLine=[];if("[object Array]"===Object.prototype.toString.call(text)){var newY;da=transformTextToSpecialArray(text),"left"!==align&&(lineWidths=da.map((function(v){return scope.getStringUnitWidth(v,{font:activeFont,charSpace:charSpace,fontSize:activeFontSize,doKerning:!1})*activeFontSize/scaleFactor})));var newX,prevWidth=0;if("right"===align){x-=lineWidths[0],text=[],len=da.length;for(var i=0;i<len;i++)0===i?(newX=getHorizontalCoordinate(x),newY=getVerticalCoordinate(y)):(newX=scale(prevWidth-lineWidths[i]),newY=-leading),text.push([da[i],newX,newY]),prevWidth=lineWidths[i]}else if("center"===align){x-=lineWidths[0]/2,text=[],len=da.length;for(var j=0;j<len;j++)0===j?(newX=getHorizontalCoordinate(x),newY=getVerticalCoordinate(y)):(newX=scale((prevWidth-lineWidths[j])/2),newY=-leading),text.push([da[j],newX,newY]),prevWidth=lineWidths[j]}else if("left"===align){text=[],len=da.length;for(var h=0;h<len;h++)text.push(da[h])}else{if("justify"!==align)throw new Error('Unrecognized alignment option, use "left", "center", "right" or "justify".');text=[],len=da.length,maxWidth=0!==maxWidth?maxWidth:pageWidth;for(var l=0;l<len;l++)newY=0===l?getVerticalCoordinate(y):-leading,newX=0===l?getHorizontalCoordinate(x):0,l<len-1?wordSpacingPerLine.push(hpf(scale((maxWidth-lineWidths[l])/(da[l].split(" ").length-1)))):wordSpacingPerLine.push(0),text.push([da[l],newX,newY])}}var doReversing="boolean"==typeof options.R2L?options.R2L:R2L;!0===doReversing&&(text=processTextByFunction(text,(function(text,posX,posY){return[text.split("").reverse().join(""),posX,posY]}))),payload={text:text,x:x,y:y,options:options,mutex:{pdfEscape:pdfEscape,activeFontKey:activeFontKey,fonts:fonts,activeFontSize:activeFontSize}},events.publish("postProcessText",payload),text=payload.text,isHex=payload.mutex.isHex||!1;var activeFontEncoding=fonts[activeFontKey].encoding;"WinAnsiEncoding"!==activeFontEncoding&&"StandardEncoding"!==activeFontEncoding||(text=processTextByFunction(text,(function(text,posX,posY){return[ESC(text),posX,posY]}))),da=transformTextToSpecialArray(text),text=[];for(var posX,posY,content,STRING=0,ARRAY=1,variant=Array.isArray(da[0])?ARRAY:STRING,wordSpacing="",generatePosition=function(parmPosX,parmPosY,parmTransformationMatrix){var position="";return parmTransformationMatrix instanceof Matrix?(parmTransformationMatrix="number"==typeof options.angle?matrixMult(parmTransformationMatrix,new Matrix(1,0,0,1,parmPosX,parmPosY)):matrixMult(new Matrix(1,0,0,1,parmPosX,parmPosY),parmTransformationMatrix),apiMode===ApiMode.ADVANCED&&(parmTransformationMatrix=matrixMult(new Matrix(1,0,0,-1,0,0),parmTransformationMatrix)),position=parmTransformationMatrix.join(" ")+" Tm\n"):position=hpf(parmPosX)+" "+hpf(parmPosY)+" Td\n",position},lineIndex=0;lineIndex<da.length;lineIndex++){switch(wordSpacing="",variant){case ARRAY:content=(isHex?"<":"(")+da[lineIndex][0]+(isHex?">":")"),posX=parseFloat(da[lineIndex][1]),posY=parseFloat(da[lineIndex][2]);break;case STRING:content=(isHex?"<":"(")+da[lineIndex]+(isHex?">":")"),posX=getHorizontalCoordinate(x),posY=getVerticalCoordinate(y)}void 0!==wordSpacingPerLine&&void 0!==wordSpacingPerLine[lineIndex]&&(wordSpacing=wordSpacingPerLine[lineIndex]+" Tw\n"),0===lineIndex?text.push(wordSpacing+generatePosition(posX,posY,transformationMatrix)+content):variant===STRING?text.push(wordSpacing+content):variant===ARRAY&&text.push(wordSpacing+generatePosition(posX,posY,transformationMatrix)+content)}text=variant===STRING?text.join(" Tj\nT* "):text.join(" Tj\n"),text+=" Tj\n";var result="BT\n/";return result+=activeFontKey+" "+activeFontSize+" Tf\n",result+=hpf(activeFontSize*lineHeight)+" TL\n",result+=textColor+"\n",result+=xtra,result+=text,out(result+="ET"),usedFonts[activeFontKey]=!0,scope};var clip=API.__private__.clip=API.clip=function(rule){return out("evenodd"===rule?"W*":"W"),this};API.clipEvenOdd=function(){return clip("evenodd")},API.__private__.discardPath=API.discardPath=function(){return out("n"),this};var isValidStyle=API.__private__.isValidStyle=function(style){var result=!1;return-1!==[void 0,null,"S","D","F","DF","FD","f","f*","B","B*","n"].indexOf(style)&&(result=!0),result};API.__private__.setDefaultPathOperation=API.setDefaultPathOperation=function(operator){return isValidStyle(operator)&&(defaultPathOperation=operator),this};var getStyle=API.__private__.getStyle=API.getStyle=function(style){var op=defaultPathOperation;switch(style){case"D":case"S":op="S";break;case"F":op="f";break;case"FD":case"DF":op="B";break;case"f":case"f*":case"B":case"B*":op=style}return op},close=API.close=function(){return out("h"),this};API.stroke=function(){return out("S"),this},API.fill=function(pattern){return fillWithOptionalPattern("f",pattern),this},API.fillEvenOdd=function(pattern){return fillWithOptionalPattern("f*",pattern),this},API.fillStroke=function(pattern){return fillWithOptionalPattern("B",pattern),this},API.fillStrokeEvenOdd=function(pattern){return fillWithOptionalPattern("B*",pattern),this};var fillWithOptionalPattern=function(style,pattern){"object"===_typeof(pattern)?fillWithPattern(pattern,style):out(style)},putStyle=function(style){null===style||apiMode===ApiMode.ADVANCED&&void 0===style||(style=getStyle(style),out(style))};function cloneTilingPattern(patternKey,boundingBox,xStep,yStep,matrix){var clone=new TilingPattern(boundingBox||this.boundingBox,xStep||this.xStep,yStep||this.yStep,this.gState,matrix||this.matrix);clone.stream=this.stream;var key=patternKey+"$$"+this.cloneIndex+++"$$";return addPattern(key,clone),clone}var fillWithPattern=function(patternData,style){var patternId=patternMap[patternData.key],pattern=patterns[patternId];if(pattern instanceof ShadingPattern)out("q"),out(clipRuleFromStyle(style)),pattern.gState&&API.setGState(pattern.gState),out(patternData.matrix.toString()+" cm"),out("/"+patternId+" sh"),out("Q");else if(pattern instanceof TilingPattern){var matrix=new Matrix(1,0,0,-1,0,getPageHeight());patternData.matrix&&(matrix=matrix.multiply(patternData.matrix||identityMatrix),patternId=cloneTilingPattern.call(pattern,patternData.key,patternData.boundingBox,patternData.xStep,patternData.yStep,matrix).id),out("q"),out("/Pattern cs"),out("/"+patternId+" scn"),pattern.gState&&API.setGState(pattern.gState),out(style),out("Q")}},clipRuleFromStyle=function(style){switch(style){case"f":case"F":case"n":return"W n";case"f*":return"W* n";case"B":case"S":return"W S";case"B*":return"W* S"}},moveTo=API.moveTo=function(x,y){return out(hpf(scale(x))+" "+hpf(transformScaleY(y))+" m"),this},lineTo=API.lineTo=function(x,y){return out(hpf(scale(x))+" "+hpf(transformScaleY(y))+" l"),this},curveTo=API.curveTo=function(x1,y1,x2,y2,x3,y3){return out([hpf(scale(x1)),hpf(transformScaleY(y1)),hpf(scale(x2)),hpf(transformScaleY(y2)),hpf(scale(x3)),hpf(transformScaleY(y3)),"c"].join(" ")),this};API.__private__.line=API.line=function(x1,y1,x2,y2,style){if(isNaN(x1)||isNaN(y1)||isNaN(x2)||isNaN(y2)||!isValidStyle(style))throw new Error("Invalid arguments passed to jsPDF.line");return apiMode===ApiMode.COMPAT?this.lines([[x2-x1,y2-y1]],x1,y1,[1,1],style||"S"):this.lines([[x2-x1,y2-y1]],x1,y1,[1,1]).stroke()},API.__private__.lines=API.lines=function(lines,x,y,scale,style,closed){var scalex,scaley,i,l,leg,x2,y2,x3,y3,x4,y4,tmp;if("number"==typeof lines&&(tmp=y,y=x,x=lines,lines=tmp),scale=scale||[1,1],closed=closed||!1,isNaN(x)||isNaN(y)||!Array.isArray(lines)||!Array.isArray(scale)||!isValidStyle(style)||"boolean"!=typeof closed)throw new Error("Invalid arguments passed to jsPDF.lines");for(moveTo(x,y),scalex=scale[0],scaley=scale[1],l=lines.length,x4=x,y4=y,i=0;i<l;i++)2===(leg=lines[i]).length?(x4=leg[0]*scalex+x4,y4=leg[1]*scaley+y4,lineTo(x4,y4)):(x2=leg[0]*scalex+x4,y2=leg[1]*scaley+y4,x3=leg[2]*scalex+x4,y3=leg[3]*scaley+y4,x4=leg[4]*scalex+x4,y4=leg[5]*scaley+y4,curveTo(x2,y2,x3,y3,x4,y4));return closed&&close(),putStyle(style),this},API.path=function(lines){for(var i=0;i<lines.length;i++){var leg=lines[i],coords=leg.c;switch(leg.op){case"m":moveTo(coords[0],coords[1]);break;case"l":lineTo(coords[0],coords[1]);break;case"c":curveTo.apply(this,coords);break;case"h":close()}}return this},API.__private__.rect=API.rect=function(x,y,w,h,style){if(isNaN(x)||isNaN(y)||isNaN(w)||isNaN(h)||!isValidStyle(style))throw new Error("Invalid arguments passed to jsPDF.rect");return apiMode===ApiMode.COMPAT&&(h=-h),out([hpf(scale(x)),hpf(transformScaleY(y)),hpf(scale(w)),hpf(scale(h)),"re"].join(" ")),putStyle(style),this},API.__private__.triangle=API.triangle=function(x1,y1,x2,y2,x3,y3,style){if(isNaN(x1)||isNaN(y1)||isNaN(x2)||isNaN(y2)||isNaN(x3)||isNaN(y3)||!isValidStyle(style))throw new Error("Invalid arguments passed to jsPDF.triangle");return this.lines([[x2-x1,y2-y1],[x3-x2,y3-y2],[x1-x3,y1-y3]],x1,y1,[1,1],style,!0),this},API.__private__.roundedRect=API.roundedRect=function(x,y,w,h,rx,ry,style){if(isNaN(x)||isNaN(y)||isNaN(w)||isNaN(h)||isNaN(rx)||isNaN(ry)||!isValidStyle(style))throw new Error("Invalid arguments passed to jsPDF.roundedRect");var MyArc=4/3*(Math.SQRT2-1);return rx=Math.min(rx,.5*w),ry=Math.min(ry,.5*h),this.lines([[w-2*rx,0],[rx*MyArc,0,rx,ry-ry*MyArc,rx,ry],[0,h-2*ry],[0,ry*MyArc,-rx*MyArc,ry,-rx,ry],[2*rx-w,0],[-rx*MyArc,0,-rx,-ry*MyArc,-rx,-ry],[0,2*ry-h],[0,-ry*MyArc,rx*MyArc,-ry,rx,-ry]],x+rx,y,[1,1],style,!0),this},API.__private__.ellipse=API.ellipse=function(x,y,rx,ry,style){if(isNaN(x)||isNaN(y)||isNaN(rx)||isNaN(ry)||!isValidStyle(style))throw new Error("Invalid arguments passed to jsPDF.ellipse");var lx=4/3*(Math.SQRT2-1)*rx,ly=4/3*(Math.SQRT2-1)*ry;return moveTo(x+rx,y),curveTo(x+rx,y-ly,x+lx,y-ry,x,y-ry),curveTo(x-lx,y-ry,x-rx,y-ly,x-rx,y),curveTo(x-rx,y+ly,x-lx,y+ry,x,y+ry),curveTo(x+lx,y+ry,x+rx,y+ly,x+rx,y),putStyle(style),this},API.__private__.circle=API.circle=function(x,y,r,style){if(isNaN(x)||isNaN(y)||isNaN(r)||!isValidStyle(style))throw new Error("Invalid arguments passed to jsPDF.circle");return this.ellipse(x,y,r,r,style)},API.setFont=function(fontName,fontStyle,fontWeight){return fontWeight&&(fontStyle=combineFontStyleAndFontWeight(fontStyle,fontWeight)),activeFontKey=getFont(fontName,fontStyle,{disableWarning:!1}),this};var getFontEntry=API.__private__.getFont=API.getFont=function(){return fonts[getFont.apply(API,arguments)]};API.__private__.getFontList=API.getFontList=function(){var fontName,fontStyle,list={};for(fontName in fontmap)if(fontmap.hasOwnProperty(fontName))for(fontStyle in list[fontName]=[],fontmap[fontName])fontmap[fontName].hasOwnProperty(fontStyle)&&list[fontName].push(fontStyle);return list},API.addFont=function(postScriptName,fontName,fontStyle,fontWeight,encoding){var encodingOptions=["StandardEncoding","MacRomanEncoding","Identity-H","WinAnsiEncoding"];return arguments[3]&&-1!==encodingOptions.indexOf(arguments[3])?encoding=arguments[3]:arguments[3]&&-1==encodingOptions.indexOf(arguments[3])&&(fontStyle=combineFontStyleAndFontWeight(fontStyle,fontWeight)),encoding=encoding||"Identity-H",addFont.call(this,postScriptName,fontName,fontStyle,encoding)};var lineHeightFactor,lineWidth=options.lineWidth||.200025,getLineWidth=API.__private__.getLineWidth=API.getLineWidth=function(){return lineWidth},setLineWidth=API.__private__.setLineWidth=API.setLineWidth=function(width){return lineWidth=width,out(hpf(scale(width))+" w"),this};API.__private__.setLineDash=jsPDF.API.setLineDash=jsPDF.API.setLineDashPattern=function(dashArray,dashPhase){if(dashArray=dashArray||[],dashPhase=dashPhase||0,isNaN(dashPhase)||!Array.isArray(dashArray))throw new Error("Invalid arguments passed to jsPDF.setLineDash");return dashArray=dashArray.map((function(x){return hpf(scale(x))})).join(" "),dashPhase=hpf(scale(dashPhase)),out("["+dashArray+"] "+dashPhase+" d"),this};var getLineHeight=API.__private__.getLineHeight=API.getLineHeight=function(){return activeFontSize*lineHeightFactor};API.__private__.getLineHeight=API.getLineHeight=function(){return activeFontSize*lineHeightFactor};var setLineHeightFactor=API.__private__.setLineHeightFactor=API.setLineHeightFactor=function(value){return"number"==typeof(value=value||1.15)&&(lineHeightFactor=value),this},getLineHeightFactor=API.__private__.getLineHeightFactor=API.getLineHeightFactor=function(){return lineHeightFactor};setLineHeightFactor(options.lineHeight);var getHorizontalCoordinate=API.__private__.getHorizontalCoordinate=function(value){return scale(value)},getVerticalCoordinate=API.__private__.getVerticalCoordinate=function(value){return apiMode===ApiMode.ADVANCED?value:pagesContext[currentPage].mediaBox.topRightY-pagesContext[currentPage].mediaBox.bottomLeftY-scale(value)},getHorizontalCoordinateString=API.__private__.getHorizontalCoordinateString=API.getHorizontalCoordinateString=function(value){return hpf(getHorizontalCoordinate(value))},getVerticalCoordinateString=API.__private__.getVerticalCoordinateString=API.getVerticalCoordinateString=function(value){return hpf(getVerticalCoordinate(value))},strokeColor=options.strokeColor||"0 G";API.__private__.getStrokeColor=API.getDrawColor=function(){return decodeColorString(strokeColor)},API.__private__.setStrokeColor=API.setDrawColor=function(ch1,ch2,ch3,ch4){return strokeColor=encodeColorString({ch1:ch1,ch2:ch2,ch3:ch3,ch4:ch4,pdfColorType:"draw",precision:2}),out(strokeColor),this};var fillColor=options.fillColor||"0 g";API.__private__.getFillColor=API.getFillColor=function(){return decodeColorString(fillColor)},API.__private__.setFillColor=API.setFillColor=function(ch1,ch2,ch3,ch4){return fillColor=encodeColorString({ch1:ch1,ch2:ch2,ch3:ch3,ch4:ch4,pdfColorType:"fill",precision:2}),out(fillColor),this};var textColor=options.textColor||"0 g",getTextColor=API.__private__.getTextColor=API.getTextColor=function(){return decodeColorString(textColor)};API.__private__.setTextColor=API.setTextColor=function(ch1,ch2,ch3,ch4){return textColor=encodeColorString({ch1:ch1,ch2:ch2,ch3:ch3,ch4:ch4,pdfColorType:"text",precision:3}),this};var activeCharSpace=options.charSpace,getCharSpace=API.__private__.getCharSpace=API.getCharSpace=function(){return parseFloat(activeCharSpace||0)};API.__private__.setCharSpace=API.setCharSpace=function(charSpace){if(isNaN(charSpace))throw new Error("Invalid argument passed to jsPDF.setCharSpace");return activeCharSpace=charSpace,this};var lineCapID=0;API.CapJoinStyles={0:0,butt:0,but:0,miter:0,1:1,round:1,rounded:1,circle:1,2:2,projecting:2,project:2,square:2,bevel:2},API.__private__.setLineCap=API.setLineCap=function(style){var id=API.CapJoinStyles[style];if(void 0===id)throw new Error("Line cap style of '"+style+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return lineCapID=id,out(id+" J"),this};var lineJoinID=0;API.__private__.setLineJoin=API.setLineJoin=function(style){var id=API.CapJoinStyles[style];if(void 0===id)throw new Error("Line join style of '"+style+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return lineJoinID=id,out(id+" j"),this},API.__private__.setLineMiterLimit=API.__private__.setMiterLimit=API.setLineMiterLimit=API.setMiterLimit=function(length){if(length=length||0,isNaN(length))throw new Error("Invalid argument passed to jsPDF.setLineMiterLimit");return out(hpf(scale(length))+" M"),this},API.GState=GState,API.setGState=function(gState){(gState="string"==typeof gState?gStates[gStatesMap[gState]]:addGState(null,gState)).equals(activeGState)||(out("/"+gState.id+" gs"),activeGState=gState)};var addGState=function(key,gState){if(!key||!gStatesMap[key]){var duplicate=!1;for(var s in gStates)if(gStates.hasOwnProperty(s)&&gStates[s].equals(gState)){duplicate=!0;break}if(duplicate)gState=gStates[s];else{var gStateKey="GS"+(Object.keys(gStates).length+1).toString(10);gStates[gStateKey]=gState,gState.id=gStateKey}return key&&(gStatesMap[key]=gState.id),events.publish("addGState",gState),gState}};API.addGState=function(key,gState){return addGState(key,gState),this},API.saveGraphicsState=function(){return out("q"),fontStateStack.push({key:activeFontKey,size:activeFontSize,color:textColor}),this},API.restoreGraphicsState=function(){out("Q");var fontState=fontStateStack.pop();return activeFontKey=fontState.key,activeFontSize=fontState.size,textColor=fontState.color,activeGState=null,this},API.setCurrentTransformationMatrix=function(matrix){return out(matrix.toString()+" cm"),this},API.comment=function(text){return out("#"+text),this};var Point=function(x,y){var _x=x||0;Object.defineProperty(this,"x",{enumerable:!0,get:function(){return _x},set:function(value){isNaN(value)||(_x=parseFloat(value))}});var _y=y||0;Object.defineProperty(this,"y",{enumerable:!0,get:function(){return _y},set:function(value){isNaN(value)||(_y=parseFloat(value))}});var _type="pt";return Object.defineProperty(this,"type",{enumerable:!0,get:function(){return _type},set:function(value){_type=value.toString()}}),this},Rectangle=function(x,y,w,h){Point.call(this,x,y),this.type="rect";var _w=w||0;Object.defineProperty(this,"w",{enumerable:!0,get:function(){return _w},set:function(value){isNaN(value)||(_w=parseFloat(value))}});var _h=h||0;return Object.defineProperty(this,"h",{enumerable:!0,get:function(){return _h},set:function(value){isNaN(value)||(_h=parseFloat(value))}}),this},RenderTarget=function(){this.page=page,this.currentPage=currentPage,this.pages=pages.slice(0),this.pagesContext=pagesContext.slice(0),this.x=pageX,this.y=pageY,this.matrix=pageMatrix,this.width=getPageWidth(currentPage),this.height=getPageHeight(currentPage),this.outputDestination=outputDestination,this.id="",this.objectNumber=-1};RenderTarget.prototype.restore=function(){page=this.page,currentPage=this.currentPage,pagesContext=this.pagesContext,pages=this.pages,pageX=this.x,pageY=this.y,pageMatrix=this.matrix,setPageWidth(currentPage,this.width),setPageHeight(currentPage,this.height),outputDestination=this.outputDestination};var beginNewRenderTarget=function(x,y,width,height,matrix){renderTargetStack.push(new RenderTarget),page=currentPage=0,pages=[],pageX=x,pageY=y,pageMatrix=matrix,beginPage([width,height])},endFormObject=function(key){if(renderTargetMap[key])renderTargetStack.pop().restore();else{var newXObject=new RenderTarget,xObjectId="Xo"+(Object.keys(renderTargets).length+1).toString(10);newXObject.id=xObjectId,renderTargetMap[key]=xObjectId,renderTargets[xObjectId]=newXObject,events.publish("addFormObject",newXObject),renderTargetStack.pop().restore()}};for(var plugin in API.beginFormObject=function(x,y,width,height,matrix){return beginNewRenderTarget(x,y,width,height,matrix),this},API.endFormObject=function(key){return endFormObject(key),this},API.doFormObject=function(key,matrix){var xObject=renderTargets[renderTargetMap[key]];return out("q"),out(matrix.toString()+" cm"),out("/"+xObject.id+" Do"),out("Q"),this},API.getFormObject=function(key){var xObject=renderTargets[renderTargetMap[key]];return{x:xObject.x,y:xObject.y,width:xObject.width,height:xObject.height,matrix:xObject.matrix}},API.save=function(filename,options){return filename=filename||"generated.pdf",(options=options||{}).returnPromise=options.returnPromise||!1,!1===options.returnPromise?(saveAs(getBlob(buildDocument()),filename),"function"==typeof saveAs.unload&&globalObject.setTimeout&&setTimeout(saveAs.unload,911),this):new Promise((function(resolve,reject){try{var result=saveAs(getBlob(buildDocument()),filename);"function"==typeof saveAs.unload&&globalObject.setTimeout&&setTimeout(saveAs.unload,911),resolve(result)}catch(e){reject(e.message)}}))},jsPDF.API)jsPDF.API.hasOwnProperty(plugin)&&("events"===plugin&&jsPDF.API.events.length?function(events,newEvents){var eventname,handler_and_args,i;for(i=newEvents.length-1;-1!==i;i--)eventname=newEvents[i][0],handler_and_args=newEvents[i][1],events.subscribe.apply(events,[eventname].concat("function"==typeof handler_and_args?[handler_and_args]:handler_and_args))}(events,jsPDF.API.events):API[plugin]=jsPDF.API[plugin]);var getPageWidth=API.getPageWidth=function(pageNumber){return(pagesContext[pageNumber=pageNumber||currentPage].mediaBox.topRightX-pagesContext[pageNumber].mediaBox.bottomLeftX)/scaleFactor},setPageWidth=API.setPageWidth=function(pageNumber,value){pagesContext[pageNumber].mediaBox.topRightX=value*scaleFactor+pagesContext[pageNumber].mediaBox.bottomLeftX},getPageHeight=API.getPageHeight=function(pageNumber){return(pagesContext[pageNumber=pageNumber||currentPage].mediaBox.topRightY-pagesContext[pageNumber].mediaBox.bottomLeftY)/scaleFactor},setPageHeight=API.setPageHeight=function(pageNumber,value){pagesContext[pageNumber].mediaBox.topRightY=value*scaleFactor+pagesContext[pageNumber].mediaBox.bottomLeftY};return API.internal={pdfEscape:pdfEscape,getStyle:getStyle,getFont:getFontEntry,getFontSize:getFontSize,getCharSpace:getCharSpace,getTextColor:getTextColor,getLineHeight:getLineHeight,getLineHeightFactor:getLineHeightFactor,getLineWidth:getLineWidth,write:write,getHorizontalCoordinate:getHorizontalCoordinate,getVerticalCoordinate:getVerticalCoordinate,getCoordinateString:getHorizontalCoordinateString,getVerticalCoordinateString:getVerticalCoordinateString,collections:{},newObject:newObject,newAdditionalObject:newAdditionalObject,newObjectDeferred:newObjectDeferred,newObjectDeferredBegin:newObjectDeferredBegin,getFilters:getFilters,putStream:putStream,events:events,scaleFactor:scaleFactor,pageSize:{getWidth:function(){return getPageWidth(currentPage)},setWidth:function(value){setPageWidth(currentPage,value)},getHeight:function(){return getPageHeight(currentPage)},setHeight:function(value){setPageHeight(currentPage,value)}},encryptionOptions:encryptionOptions,encryption:encryption,getEncryptor:getEncryptor,output:output,getNumberOfPages:getNumberOfPages,pages:pages,out:out,f2:f2,f3:f3,getPageInfo:getPageInfo,getPageInfoByObjId:getPageInfoByObjId,getCurrentPageInfo:getCurrentPageInfo,getPDFVersion:getPdfVersion,Point:Point,Rectangle:Rectangle,Matrix:Matrix,hasHotfix:hasHotfix},Object.defineProperty(API.internal.pageSize,"width",{get:function(){return getPageWidth(currentPage)},set:function(value){setPageWidth(currentPage,value)},enumerable:!0,configurable:!0}),Object.defineProperty(API.internal.pageSize,"height",{get:function(){return getPageHeight(currentPage)},set:function(value){setPageHeight(currentPage,value)},enumerable:!0,configurable:!0}),addFonts.call(API,standardFonts),activeFontKey="F1",_addPage(format,orientation),events.publish("initialized"),API}PDFSecurity.prototype.lsbFirstWord=function(data){return String.fromCharCode(data>>0&255,data>>8&255,data>>16&255,data>>24&255)},PDFSecurity.prototype.toHexString=function(byteString){return byteString.split("").map((function(byte){return("0"+(255&byte.charCodeAt(0)).toString(16)).slice(-2)})).join("")},PDFSecurity.prototype.hexToBytes=function(hex){for(var bytes=[],c=0;c<hex.length;c+=2)bytes.push(String.fromCharCode(parseInt(hex.substr(c,2),16)));return bytes.join("")},PDFSecurity.prototype.processOwnerPassword=function(paddedUserPassword,paddedOwnerPassword){return rc4(md5Bin(paddedOwnerPassword).substr(0,5),paddedUserPassword)},PDFSecurity.prototype.encryptor=function(objectId,generation){var key=md5Bin(this.encryptionKey+String.fromCharCode(255&objectId,objectId>>8&255,objectId>>16&255,255&generation,generation>>8&255)).substr(0,10);return function(data){return rc4(key,data)}},GState.prototype.equals=function(other){var p,ignore="id,objectNumber,equals";if(!other||_typeof(other)!==_typeof(this))return!1;var count=0;for(p in this)if(!(ignore.indexOf(p)>=0)){if(this.hasOwnProperty(p)&&!other.hasOwnProperty(p))return!1;if(this[p]!==other[p])return!1;count++}for(p in other)other.hasOwnProperty(p)&&ignore.indexOf(p)<0&&count--;return 0===count},jsPDF.API={events:[]},jsPDF.version="2.5.1";var jsPDFAPI=jsPDF.API,scaleFactor=1,pdfEscape=function(value){return value.replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")},pdfUnescape=function(value){return value.replace(/\\\\/g,"\\").replace(/\\\(/g,"(").replace(/\\\)/g,")")},f2=function(number){return number.toFixed(2)},f5=function(number){return number.toFixed(5)};jsPDFAPI.__acroform__={};var inherit=function(child,parent){child.prototype=Object.create(parent.prototype),child.prototype.constructor=child},scale=function(x){return x*scaleFactor},createFormXObject=function(formObject){var xobj=new AcroFormXObject,height=AcroFormAppearance.internal.getHeight(formObject)||0,width=AcroFormAppearance.internal.getWidth(formObject)||0;return xobj.BBox=[0,0,Number(f2(width)),Number(f2(height))],xobj},setBit=jsPDFAPI.__acroform__.setBit=function(number,bitPosition){if(number=number||0,bitPosition=bitPosition||0,isNaN(number)||isNaN(bitPosition))throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.setBit");return number|=1<<bitPosition},clearBit=jsPDFAPI.__acroform__.clearBit=function(number,bitPosition){if(number=number||0,bitPosition=bitPosition||0,isNaN(number)||isNaN(bitPosition))throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.clearBit");return number&=~(1<<bitPosition)},getBit=jsPDFAPI.__acroform__.getBit=function(number,bitPosition){if(isNaN(number)||isNaN(bitPosition))throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.getBit");return 0==(number&1<<bitPosition)?0:1},getBitForPdf=jsPDFAPI.__acroform__.getBitForPdf=function(number,bitPosition){if(isNaN(number)||isNaN(bitPosition))throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.getBitForPdf");return getBit(number,bitPosition-1)},setBitForPdf=jsPDFAPI.__acroform__.setBitForPdf=function(number,bitPosition){if(isNaN(number)||isNaN(bitPosition))throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.setBitForPdf");return setBit(number,bitPosition-1)},clearBitForPdf=jsPDFAPI.__acroform__.clearBitForPdf=function(number,bitPosition){if(isNaN(number)||isNaN(bitPosition))throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.clearBitForPdf");return clearBit(number,bitPosition-1)},calculateCoordinates=jsPDFAPI.__acroform__.calculateCoordinates=function(args,scope){var getHorizontalCoordinate=scope.internal.getHorizontalCoordinate,getVerticalCoordinate=scope.internal.getVerticalCoordinate,x=args[0],y=args[1],w=args[2],h=args[3],coordinates={};return coordinates.lowerLeft_X=getHorizontalCoordinate(x)||0,coordinates.lowerLeft_Y=getVerticalCoordinate(y+h)||0,coordinates.upperRight_X=getHorizontalCoordinate(x+w)||0,coordinates.upperRight_Y=getVerticalCoordinate(y)||0,[Number(f2(coordinates.lowerLeft_X)),Number(f2(coordinates.lowerLeft_Y)),Number(f2(coordinates.upperRight_X)),Number(f2(coordinates.upperRight_Y))]},calculateAppearanceStream=function(formObject){if(formObject.appearanceStreamContent)return formObject.appearanceStreamContent;if(formObject.V||formObject.DV){var stream=[],text=formObject._V||formObject.DV,calcRes=calculateX(formObject,text),fontKey=formObject.scope.internal.getFont(formObject.fontName,formObject.fontStyle).id;stream.push("/Tx BMC"),stream.push("q"),stream.push("BT"),stream.push(formObject.scope.__private__.encodeColorString(formObject.color)),stream.push("/"+fontKey+" "+f2(calcRes.fontSize)+" Tf"),stream.push("1 0 0 1 0 0 Tm"),stream.push(calcRes.text),stream.push("ET"),stream.push("Q"),stream.push("EMC");var appearanceStreamContent=createFormXObject(formObject);return appearanceStreamContent.scope=formObject.scope,appearanceStreamContent.stream=stream.join("\n"),appearanceStreamContent}},calculateX=function(formObject,text){var maxFontSize=0===formObject.fontSize?formObject.maxFontSize:formObject.fontSize,returnValue={text:"",fontSize:""},textSplit=(text=")"==(text="("==text.substr(0,1)?text.substr(1):text).substr(text.length-1)?text.substr(0,text.length-1):text).split(" ");textSplit=formObject.multiline?textSplit.map((function(word){return word.split("\n")})):textSplit.map((function(word){return[word]}));var fontSize=maxFontSize,height=AcroFormAppearance.internal.getHeight(formObject)||0;height=height<0?-height:height;var width=AcroFormAppearance.internal.getWidth(formObject)||0;width=width<0?-width:width;var isSmallerThanWidth=function(i,lastLine,fontSize){if(i+1<textSplit.length){var tmp=lastLine+" "+textSplit[i+1][0];return calculateFontSpace(tmp,formObject,fontSize).width<=width-4}return!1};fontSize++;FontSize:for(;fontSize>0;){text="",fontSize--;var startX,lastLength,textHeight=calculateFontSpace("3",formObject,fontSize).height,startY=formObject.multiline?height-fontSize:(height-textHeight)/2,lastY=startY+=2,firstWordInLine=0,lastWordInLine=0,currWord=0;if(fontSize<=0){text="(...) Tj\n",text+="% Width of Text: "+calculateFontSpace(text,formObject,fontSize=12).width+", FieldWidth:"+width+"\n";break}for(var lastLine="",lineCount=0,i=0;i<textSplit.length;i++)if(textSplit.hasOwnProperty(i)){var isWithNewLine=!1;if(1!==textSplit[i].length&&currWord!==textSplit[i].length-1){if((textHeight+2)*(lineCount+2)+2>height)continue FontSize;lastLine+=textSplit[i][currWord],isWithNewLine=!0,lastWordInLine=i,i--}else{lastLine=" "==(lastLine+=textSplit[i][currWord]+" ").substr(lastLine.length-1)?lastLine.substr(0,lastLine.length-1):lastLine;var key=parseInt(i),nextLineIsSmaller=isSmallerThanWidth(key,lastLine,fontSize),isLastWord=i>=textSplit.length-1;if(nextLineIsSmaller&&!isLastWord){lastLine+=" ",currWord=0;continue}if(nextLineIsSmaller||isLastWord){if(isLastWord)lastWordInLine=key;else if(formObject.multiline&&(textHeight+2)*(lineCount+2)+2>height)continue FontSize}else{if(!formObject.multiline)continue FontSize;if((textHeight+2)*(lineCount+2)+2>height)continue FontSize;lastWordInLine=key}}for(var line="",x=firstWordInLine;x<=lastWordInLine;x++){var currLine=textSplit[x];if(formObject.multiline){if(x===lastWordInLine){line+=currLine[currWord]+" ",currWord=(currWord+1)%currLine.length;continue}if(x===firstWordInLine){line+=currLine[currLine.length-1]+" ";continue}}line+=currLine[0]+" "}switch(line=" "==line.substr(line.length-1)?line.substr(0,line.length-1):line,lastLength=calculateFontSpace(line,formObject,fontSize).width,formObject.textAlign){case"right":startX=width-lastLength-2;break;case"center":startX=(width-lastLength)/2;break;default:startX=2}text+=f2(startX)+" "+f2(lastY)+" Td\n",text+="("+pdfEscape(line)+") Tj\n",text+=-f2(startX)+" 0 Td\n",lastY=-(fontSize+2),lastLength=0,firstWordInLine=isWithNewLine?lastWordInLine:lastWordInLine+1,lineCount++,lastLine=""}else;break}return returnValue.text=text,returnValue.fontSize=fontSize,returnValue},calculateFontSpace=function(text,formObject,fontSize){var font=formObject.scope.internal.getFont(formObject.fontName,formObject.fontStyle),width=formObject.scope.getStringUnitWidth(text,{font:font,fontSize:parseFloat(fontSize),charSpace:0})*parseFloat(fontSize);return{height:formObject.scope.getStringUnitWidth("3",{font:font,fontSize:parseFloat(fontSize),charSpace:0})*parseFloat(fontSize)*1.5,width:width}},acroformPluginTemplate={fields:[],xForms:[],acroFormDictionaryRoot:null,printedOut:!1,internal:null,isInitialized:!1},createAnnotationReference=function(object,scope){var options={type:"reference",object:object};void 0===scope.internal.getPageInfo(object.page).pageContext.annotations.find((function(entry){return entry.type===options.type&&entry.object===options.object}))&&scope.internal.getPageInfo(object.page).pageContext.annotations.push(options)},createXFormObjectCallback=function(fieldArray,scope){for(var i in fieldArray)if(fieldArray.hasOwnProperty(i)){var key=i,fieldObject=fieldArray[i];scope.internal.newObjectDeferredBegin(fieldObject.objId,!0),"object"===_typeof(fieldObject)&&"function"==typeof fieldObject.putStream&&fieldObject.putStream(),delete fieldArray[key]}},initializeAcroForm=function(scope,formObject){if(formObject.scope=scope,void 0!==scope.internal&&(void 0===scope.internal.acroformPlugin||!1===scope.internal.acroformPlugin.isInitialized)){if(AcroFormField.FieldNum=0,scope.internal.acroformPlugin=JSON.parse(JSON.stringify(acroformPluginTemplate)),scope.internal.acroformPlugin.acroFormDictionaryRoot)throw new Error("Exception while creating AcroformDictionary");scaleFactor=scope.internal.scaleFactor,scope.internal.acroformPlugin.acroFormDictionaryRoot=new AcroFormDictionary,scope.internal.acroformPlugin.acroFormDictionaryRoot.scope=scope,scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID=scope.internal.events.subscribe("postPutResources",(function(){!function(scope){scope.internal.events.unsubscribe(scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID),delete scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID,scope.internal.acroformPlugin.printedOut=!0}(scope)})),scope.internal.events.subscribe("buildDocument",(function(){!function(scope){scope.internal.acroformPlugin.acroFormDictionaryRoot.objId=void 0;var fields=scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields;for(var i in fields)if(fields.hasOwnProperty(i)){var formObject=fields[i];formObject.objId=void 0,formObject.hasAnnotation&&createAnnotationReference(formObject,scope)}}(scope)})),scope.internal.events.subscribe("putCatalog",(function(){!function(scope){if(void 0===scope.internal.acroformPlugin.acroFormDictionaryRoot)throw new Error("putCatalogCallback: Root missing.");scope.internal.write("/AcroForm "+scope.internal.acroformPlugin.acroFormDictionaryRoot.objId+" 0 R")}(scope)})),scope.internal.events.subscribe("postPutPages",(function(fieldArray){!function(fieldArray,scope){var standardFields=!fieldArray;for(var i in fieldArray||(scope.internal.newObjectDeferredBegin(scope.internal.acroformPlugin.acroFormDictionaryRoot.objId,!0),scope.internal.acroformPlugin.acroFormDictionaryRoot.putStream()),fieldArray=fieldArray||scope.internal.acroformPlugin.acroFormDictionaryRoot.Kids)if(fieldArray.hasOwnProperty(i)){var fieldObject=fieldArray[i],keyValueList=[],oldRect=fieldObject.Rect;if(fieldObject.Rect&&(fieldObject.Rect=calculateCoordinates(fieldObject.Rect,scope)),scope.internal.newObjectDeferredBegin(fieldObject.objId,!0),fieldObject.DA=AcroFormAppearance.createDefaultAppearanceStream(fieldObject),"object"===_typeof(fieldObject)&&"function"==typeof fieldObject.getKeyValueListForStream&&(keyValueList=fieldObject.getKeyValueListForStream()),fieldObject.Rect=oldRect,fieldObject.hasAppearanceStream&&!fieldObject.appearanceStreamContent){var appearance=calculateAppearanceStream(fieldObject);keyValueList.push({key:"AP",value:"<</N "+appearance+">>"}),scope.internal.acroformPlugin.xForms.push(appearance)}if(fieldObject.appearanceStreamContent){var appearanceStreamString="";for(var k in fieldObject.appearanceStreamContent)if(fieldObject.appearanceStreamContent.hasOwnProperty(k)){var value=fieldObject.appearanceStreamContent[k];if(appearanceStreamString+="/"+k+" ",appearanceStreamString+="<<",Object.keys(value).length>=1||Array.isArray(value)){for(var i in value)if(value.hasOwnProperty(i)){var obj=value[i];"function"==typeof obj&&(obj=obj.call(scope,fieldObject)),appearanceStreamString+="/"+i+" "+obj+" ",scope.internal.acroformPlugin.xForms.indexOf(obj)>=0||scope.internal.acroformPlugin.xForms.push(obj)}}else"function"==typeof(obj=value)&&(obj=obj.call(scope,fieldObject)),appearanceStreamString+="/"+i+" "+obj,scope.internal.acroformPlugin.xForms.indexOf(obj)>=0||scope.internal.acroformPlugin.xForms.push(obj);appearanceStreamString+=">>"}keyValueList.push({key:"AP",value:"<<\n"+appearanceStreamString+">>"})}scope.internal.putStream({additionalKeyValues:keyValueList,objectId:fieldObject.objId}),scope.internal.out("endobj")}standardFields&&createXFormObjectCallback(scope.internal.acroformPlugin.xForms,scope)}(fieldArray,scope)})),scope.internal.acroformPlugin.isInitialized=!0}},arrayToPdfArray=jsPDFAPI.__acroform__.arrayToPdfArray=function(array,objId,scope){var encryptor=function(data){return data};if(Array.isArray(array)){for(var content="[",i=0;i<array.length;i++)switch(0!==i&&(content+=" "),_typeof(array[i])){case"boolean":case"number":case"object":content+=array[i].toString();break;case"string":"/"!==array[i].substr(0,1)?(void 0!==objId&&scope&&(encryptor=scope.internal.getEncryptor(objId)),content+="("+pdfEscape(encryptor(array[i].toString()))+")"):content+=array[i].toString()}return content+="]"}throw new Error("Invalid argument passed to jsPDF.__acroform__.arrayToPdfArray")};var toPdfString=function(string,objId,scope){var encryptor=function(data){return data};return void 0!==objId&&scope&&(encryptor=scope.internal.getEncryptor(objId)),(string=string||"").toString(),string="("+pdfEscape(encryptor(string))+")"},AcroFormPDFObject=function(){this._objId=void 0,this._scope=void 0,Object.defineProperty(this,"objId",{get:function(){if(void 0===this._objId){if(void 0===this.scope)return;this._objId=this.scope.internal.newObjectDeferred()}return this._objId},set:function(value){this._objId=value}}),Object.defineProperty(this,"scope",{value:this._scope,writable:!0})};AcroFormPDFObject.prototype.toString=function(){return this.objId+" 0 R"},AcroFormPDFObject.prototype.putStream=function(){var keyValueList=this.getKeyValueListForStream();this.scope.internal.putStream({data:this.stream,additionalKeyValues:keyValueList,objectId:this.objId}),this.scope.internal.out("endobj")},AcroFormPDFObject.prototype.getKeyValueListForStream=function(){var keyValueList=[],keys=Object.getOwnPropertyNames(this).filter((function(key){return"content"!=key&&"appearanceStreamContent"!=key&&"scope"!=key&&"objId"!=key&&"_"!=key.substring(0,1)}));for(var i in keys)if(!1===Object.getOwnPropertyDescriptor(this,keys[i]).configurable){var key=keys[i],value=this[key];value&&(Array.isArray(value)?keyValueList.push({key:key,value:arrayToPdfArray(value,this.objId,this.scope)}):value instanceof AcroFormPDFObject?(value.scope=this.scope,keyValueList.push({key:key,value:value.objId+" 0 R"})):"function"!=typeof value&&keyValueList.push({key:key,value:value}))}return keyValueList};var AcroFormXObject=function(){AcroFormPDFObject.call(this),Object.defineProperty(this,"Type",{value:"/XObject",configurable:!1,writable:!0}),Object.defineProperty(this,"Subtype",{value:"/Form",configurable:!1,writable:!0}),Object.defineProperty(this,"FormType",{value:1,configurable:!1,writable:!0});var _stream,_BBox=[];Object.defineProperty(this,"BBox",{configurable:!1,get:function(){return _BBox},set:function(value){_BBox=value}}),Object.defineProperty(this,"Resources",{value:"2 0 R",configurable:!1,writable:!0}),Object.defineProperty(this,"stream",{enumerable:!1,configurable:!0,set:function(value){_stream=value.trim()},get:function(){return _stream||null}})};inherit(AcroFormXObject,AcroFormPDFObject);var AcroFormDictionary=function(){AcroFormPDFObject.call(this);var _DA,_Kids=[];Object.defineProperty(this,"Kids",{enumerable:!1,configurable:!0,get:function(){return _Kids.length>0?_Kids:void 0}}),Object.defineProperty(this,"Fields",{enumerable:!1,configurable:!1,get:function(){return _Kids}}),Object.defineProperty(this,"DA",{enumerable:!1,configurable:!1,get:function(){if(_DA){var encryptor=function(data){return data};return this.scope&&(encryptor=this.scope.internal.getEncryptor(this.objId)),"("+pdfEscape(encryptor(_DA))+")"}},set:function(value){_DA=value}})};inherit(AcroFormDictionary,AcroFormPDFObject);var AcroFormField=function AcroFormField(){AcroFormPDFObject.call(this);var _F=4;Object.defineProperty(this,"F",{enumerable:!1,configurable:!1,get:function(){return _F},set:function(value){if(isNaN(value))throw new Error('Invalid value "'+value+'" for attribute F supplied.');_F=value}}),Object.defineProperty(this,"showWhenPrinted",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(_F,3))},set:function(value){!0===Boolean(value)?this.F=setBitForPdf(_F,3):this.F=clearBitForPdf(_F,3)}});var _Ff=0;Object.defineProperty(this,"Ff",{enumerable:!1,configurable:!1,get:function(){return _Ff},set:function(value){if(isNaN(value))throw new Error('Invalid value "'+value+'" for attribute Ff supplied.');_Ff=value}});var _Rect=[];Object.defineProperty(this,"Rect",{enumerable:!1,configurable:!1,get:function(){if(0!==_Rect.length)return _Rect},set:function(value){_Rect=void 0!==value?value:[]}}),Object.defineProperty(this,"x",{enumerable:!0,configurable:!0,get:function(){return!_Rect||isNaN(_Rect[0])?0:_Rect[0]},set:function(value){_Rect[0]=value}}),Object.defineProperty(this,"y",{enumerable:!0,configurable:!0,get:function(){return!_Rect||isNaN(_Rect[1])?0:_Rect[1]},set:function(value){_Rect[1]=value}}),Object.defineProperty(this,"width",{enumerable:!0,configurable:!0,get:function(){return!_Rect||isNaN(_Rect[2])?0:_Rect[2]},set:function(value){_Rect[2]=value}}),Object.defineProperty(this,"height",{enumerable:!0,configurable:!0,get:function(){return!_Rect||isNaN(_Rect[3])?0:_Rect[3]},set:function(value){_Rect[3]=value}});var _FT="";Object.defineProperty(this,"FT",{enumerable:!0,configurable:!1,get:function(){return _FT},set:function(value){switch(value){case"/Btn":case"/Tx":case"/Ch":case"/Sig":_FT=value;break;default:throw new Error('Invalid value "'+value+'" for attribute FT supplied.')}}});var _T=null;Object.defineProperty(this,"T",{enumerable:!0,configurable:!1,get:function(){if(!_T||_T.length<1){if(this instanceof AcroFormChildClass)return;_T="FieldObject"+AcroFormField.FieldNum++}var encryptor=function(data){return data};return this.scope&&(encryptor=this.scope.internal.getEncryptor(this.objId)),"("+pdfEscape(encryptor(_T))+")"},set:function(value){_T=value.toString()}}),Object.defineProperty(this,"fieldName",{configurable:!0,enumerable:!0,get:function(){return _T},set:function(value){_T=value}});var _fontName="helvetica";Object.defineProperty(this,"fontName",{enumerable:!0,configurable:!0,get:function(){return _fontName},set:function(value){_fontName=value}});var _fontStyle="normal";Object.defineProperty(this,"fontStyle",{enumerable:!0,configurable:!0,get:function(){return _fontStyle},set:function(value){_fontStyle=value}});var _fontSize=0;Object.defineProperty(this,"fontSize",{enumerable:!0,configurable:!0,get:function(){return _fontSize},set:function(value){_fontSize=value}});var _maxFontSize=void 0;Object.defineProperty(this,"maxFontSize",{enumerable:!0,configurable:!0,get:function(){return void 0===_maxFontSize?50/scaleFactor:_maxFontSize},set:function(value){_maxFontSize=value}});var _color="black";Object.defineProperty(this,"color",{enumerable:!0,configurable:!0,get:function(){return _color},set:function(value){_color=value}});var _DA="/F1 0 Tf 0 g";Object.defineProperty(this,"DA",{enumerable:!0,configurable:!1,get:function(){if(!(!_DA||this instanceof AcroFormChildClass||this instanceof AcroFormTextField))return toPdfString(_DA,this.objId,this.scope)},set:function(value){value=value.toString(),_DA=value}});var _DV=null;Object.defineProperty(this,"DV",{enumerable:!1,configurable:!1,get:function(){if(_DV)return this instanceof AcroFormButton==!1?toPdfString(_DV,this.objId,this.scope):_DV},set:function(value){value=value.toString(),_DV=this instanceof AcroFormButton==!1?"("===value.substr(0,1)?pdfUnescape(value.substr(1,value.length-2)):pdfUnescape(value):value}}),Object.defineProperty(this,"defaultValue",{enumerable:!0,configurable:!0,get:function(){return this instanceof AcroFormButton==!0?pdfUnescape(_DV.substr(1,_DV.length-1)):_DV},set:function(value){value=value.toString(),_DV=this instanceof AcroFormButton==!0?"/"+value:value}});var _V=null;Object.defineProperty(this,"_V",{enumerable:!1,configurable:!1,get:function(){if(_V)return _V},set:function(value){this.V=value}}),Object.defineProperty(this,"V",{enumerable:!1,configurable:!1,get:function(){if(_V)return this instanceof AcroFormButton==!1?toPdfString(_V,this.objId,this.scope):_V},set:function(value){value=value.toString(),_V=this instanceof AcroFormButton==!1?"("===value.substr(0,1)?pdfUnescape(value.substr(1,value.length-2)):pdfUnescape(value):value}}),Object.defineProperty(this,"value",{enumerable:!0,configurable:!0,get:function(){return this instanceof AcroFormButton==!0?pdfUnescape(_V.substr(1,_V.length-1)):_V},set:function(value){value=value.toString(),_V=this instanceof AcroFormButton==!0?"/"+value:value}}),Object.defineProperty(this,"hasAnnotation",{enumerable:!0,configurable:!0,get:function(){return this.Rect}}),Object.defineProperty(this,"Type",{enumerable:!0,configurable:!1,get:function(){return this.hasAnnotation?"/Annot":null}}),Object.defineProperty(this,"Subtype",{enumerable:!0,configurable:!1,get:function(){return this.hasAnnotation?"/Widget":null}});var _page,_hasAppearanceStream=!1;Object.defineProperty(this,"hasAppearanceStream",{enumerable:!0,configurable:!0,get:function(){return _hasAppearanceStream},set:function(value){value=Boolean(value),_hasAppearanceStream=value}}),Object.defineProperty(this,"page",{enumerable:!0,configurable:!0,get:function(){if(_page)return _page},set:function(value){_page=value}}),Object.defineProperty(this,"readOnly",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,1))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,1):this.Ff=clearBitForPdf(this.Ff,1)}}),Object.defineProperty(this,"required",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,2))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,2):this.Ff=clearBitForPdf(this.Ff,2)}}),Object.defineProperty(this,"noExport",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,3))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,3):this.Ff=clearBitForPdf(this.Ff,3)}});var _Q=null;Object.defineProperty(this,"Q",{enumerable:!0,configurable:!1,get:function(){if(null!==_Q)return _Q},set:function(value){if(-1===[0,1,2].indexOf(value))throw new Error('Invalid value "'+value+'" for attribute Q supplied.');_Q=value}}),Object.defineProperty(this,"textAlign",{get:function(){var result;switch(_Q){case 0:default:result="left";break;case 1:result="center";break;case 2:result="right"}return result},configurable:!0,enumerable:!0,set:function(value){switch(value){case"right":case 2:_Q=2;break;case"center":case 1:_Q=1;break;default:_Q=0}}})};inherit(AcroFormField,AcroFormPDFObject);var AcroFormChoiceField=function(){AcroFormField.call(this),this.FT="/Ch",this.V="()",this.fontName="zapfdingbats";var _TI=0;Object.defineProperty(this,"TI",{enumerable:!0,configurable:!1,get:function(){return _TI},set:function(value){_TI=value}}),Object.defineProperty(this,"topIndex",{enumerable:!0,configurable:!0,get:function(){return _TI},set:function(value){_TI=value}});var _Opt=[];Object.defineProperty(this,"Opt",{enumerable:!0,configurable:!1,get:function(){return arrayToPdfArray(_Opt,this.objId,this.scope)},set:function(value){var array,result;result=[],"string"==typeof(array=value)&&(result=function(string,regex,index){index||(index=1);for(var match,matches=[];match=regex.exec(string);)matches.push(match[index]);return matches}(array,/\((.*?)\)/g)),_Opt=result}}),this.getOptions=function(){return _Opt},this.setOptions=function(value){_Opt=value,this.sort&&_Opt.sort()},this.addOption=function(value){value=(value=value||"").toString(),_Opt.push(value),this.sort&&_Opt.sort()},this.removeOption=function(value,allEntries){for(allEntries=allEntries||!1,value=(value=value||"").toString();-1!==_Opt.indexOf(value)&&(_Opt.splice(_Opt.indexOf(value),1),!1!==allEntries););},Object.defineProperty(this,"combo",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,18))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,18):this.Ff=clearBitForPdf(this.Ff,18)}}),Object.defineProperty(this,"edit",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,19))},set:function(value){!0===this.combo&&(!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,19):this.Ff=clearBitForPdf(this.Ff,19))}}),Object.defineProperty(this,"sort",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,20))},set:function(value){!0===Boolean(value)?(this.Ff=setBitForPdf(this.Ff,20),_Opt.sort()):this.Ff=clearBitForPdf(this.Ff,20)}}),Object.defineProperty(this,"multiSelect",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,22))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,22):this.Ff=clearBitForPdf(this.Ff,22)}}),Object.defineProperty(this,"doNotSpellCheck",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,23))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,23):this.Ff=clearBitForPdf(this.Ff,23)}}),Object.defineProperty(this,"commitOnSelChange",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,27))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,27):this.Ff=clearBitForPdf(this.Ff,27)}}),this.hasAppearanceStream=!1};inherit(AcroFormChoiceField,AcroFormField);var AcroFormListBox=function(){AcroFormChoiceField.call(this),this.fontName="helvetica",this.combo=!1};inherit(AcroFormListBox,AcroFormChoiceField);var AcroFormComboBox=function(){AcroFormListBox.call(this),this.combo=!0};inherit(AcroFormComboBox,AcroFormListBox);var AcroFormEditBox=function(){AcroFormComboBox.call(this),this.edit=!0};inherit(AcroFormEditBox,AcroFormComboBox);var AcroFormButton=function(){AcroFormField.call(this),this.FT="/Btn",Object.defineProperty(this,"noToggleToOff",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,15))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,15):this.Ff=clearBitForPdf(this.Ff,15)}}),Object.defineProperty(this,"radio",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,16))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,16):this.Ff=clearBitForPdf(this.Ff,16)}}),Object.defineProperty(this,"pushButton",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,17))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,17):this.Ff=clearBitForPdf(this.Ff,17)}}),Object.defineProperty(this,"radioIsUnison",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,26))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,26):this.Ff=clearBitForPdf(this.Ff,26)}});var _AS,_MK={};Object.defineProperty(this,"MK",{enumerable:!1,configurable:!1,get:function(){var encryptor=function(data){return data};if(this.scope&&(encryptor=this.scope.internal.getEncryptor(this.objId)),0!==Object.keys(_MK).length){var key,result=[];for(key in result.push("<<"),_MK)result.push("/"+key+" ("+pdfEscape(encryptor(_MK[key]))+")");return result.push(">>"),result.join("\n")}},set:function(value){"object"===_typeof(value)&&(_MK=value)}}),Object.defineProperty(this,"caption",{enumerable:!0,configurable:!0,get:function(){return _MK.CA||""},set:function(value){"string"==typeof value&&(_MK.CA=value)}}),Object.defineProperty(this,"AS",{enumerable:!1,configurable:!1,get:function(){return _AS},set:function(value){_AS=value}}),Object.defineProperty(this,"appearanceState",{enumerable:!0,configurable:!0,get:function(){return _AS.substr(1,_AS.length-1)},set:function(value){_AS="/"+value}})};inherit(AcroFormButton,AcroFormField);var AcroFormPushButton=function(){AcroFormButton.call(this),this.pushButton=!0};inherit(AcroFormPushButton,AcroFormButton);var AcroFormRadioButton=function(){AcroFormButton.call(this),this.radio=!0,this.pushButton=!1;var _Kids=[];Object.defineProperty(this,"Kids",{enumerable:!0,configurable:!1,get:function(){return _Kids},set:function(value){_Kids=void 0!==value?value:[]}})};inherit(AcroFormRadioButton,AcroFormButton);var AcroFormChildClass=function(){var _parent,_optionName;AcroFormField.call(this),Object.defineProperty(this,"Parent",{enumerable:!1,configurable:!1,get:function(){return _parent},set:function(value){_parent=value}}),Object.defineProperty(this,"optionName",{enumerable:!1,configurable:!0,get:function(){return _optionName},set:function(value){_optionName=value}});var _AS,_MK={};Object.defineProperty(this,"MK",{enumerable:!1,configurable:!1,get:function(){var encryptor=function(data){return data};this.scope&&(encryptor=this.scope.internal.getEncryptor(this.objId));var key,result=[];for(key in result.push("<<"),_MK)result.push("/"+key+" ("+pdfEscape(encryptor(_MK[key]))+")");return result.push(">>"),result.join("\n")},set:function(value){"object"===_typeof(value)&&(_MK=value)}}),Object.defineProperty(this,"caption",{enumerable:!0,configurable:!0,get:function(){return _MK.CA||""},set:function(value){"string"==typeof value&&(_MK.CA=value)}}),Object.defineProperty(this,"AS",{enumerable:!1,configurable:!1,get:function(){return _AS},set:function(value){_AS=value}}),Object.defineProperty(this,"appearanceState",{enumerable:!0,configurable:!0,get:function(){return _AS.substr(1,_AS.length-1)},set:function(value){_AS="/"+value}}),this.caption="l",this.appearanceState="Off",this._AppearanceType=AcroFormAppearance.RadioButton.Circle,this.appearanceStreamContent=this._AppearanceType.createAppearanceStream(this.optionName)};inherit(AcroFormChildClass,AcroFormField),AcroFormRadioButton.prototype.setAppearance=function(appearance){if(!("createAppearanceStream"in appearance)||!("getCA"in appearance))throw new Error("Couldn't assign Appearance to RadioButton. Appearance was Invalid!");for(var objId in this.Kids)if(this.Kids.hasOwnProperty(objId)){var child=this.Kids[objId];child.appearanceStreamContent=appearance.createAppearanceStream(child.optionName),child.caption=appearance.getCA()}},AcroFormRadioButton.prototype.createOption=function(name){var child=new AcroFormChildClass;return child.Parent=this,child.optionName=name,this.Kids.push(child),addField.call(this.scope,child),child};var AcroFormCheckBox=function(){AcroFormButton.call(this),this.fontName="zapfdingbats",this.caption="3",this.appearanceState="On",this.value="On",this.textAlign="center",this.appearanceStreamContent=AcroFormAppearance.CheckBox.createAppearanceStream()};inherit(AcroFormCheckBox,AcroFormButton);var AcroFormTextField=function(){AcroFormField.call(this),this.FT="/Tx",Object.defineProperty(this,"multiline",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,13))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,13):this.Ff=clearBitForPdf(this.Ff,13)}}),Object.defineProperty(this,"fileSelect",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,21))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,21):this.Ff=clearBitForPdf(this.Ff,21)}}),Object.defineProperty(this,"doNotSpellCheck",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,23))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,23):this.Ff=clearBitForPdf(this.Ff,23)}}),Object.defineProperty(this,"doNotScroll",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,24))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,24):this.Ff=clearBitForPdf(this.Ff,24)}}),Object.defineProperty(this,"comb",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,25))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,25):this.Ff=clearBitForPdf(this.Ff,25)}}),Object.defineProperty(this,"richText",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,26))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,26):this.Ff=clearBitForPdf(this.Ff,26)}});var _MaxLen=null;Object.defineProperty(this,"MaxLen",{enumerable:!0,configurable:!1,get:function(){return _MaxLen},set:function(value){_MaxLen=value}}),Object.defineProperty(this,"maxLength",{enumerable:!0,configurable:!0,get:function(){return _MaxLen},set:function(value){Number.isInteger(value)&&(_MaxLen=value)}}),Object.defineProperty(this,"hasAppearanceStream",{enumerable:!0,configurable:!0,get:function(){return this.V||this.DV}})};inherit(AcroFormTextField,AcroFormField);var AcroFormPasswordField=function(){AcroFormTextField.call(this),Object.defineProperty(this,"password",{enumerable:!0,configurable:!0,get:function(){return Boolean(getBitForPdf(this.Ff,14))},set:function(value){!0===Boolean(value)?this.Ff=setBitForPdf(this.Ff,14):this.Ff=clearBitForPdf(this.Ff,14)}}),this.password=!0};inherit(AcroFormPasswordField,AcroFormTextField);var AcroFormAppearance={CheckBox:{createAppearanceStream:function(){return{N:{On:AcroFormAppearance.CheckBox.YesNormal},D:{On:AcroFormAppearance.CheckBox.YesPushDown,Off:AcroFormAppearance.CheckBox.OffPushDown}}},YesPushDown:function(formObject){var xobj=createFormXObject(formObject);xobj.scope=formObject.scope;var stream=[],fontKey=formObject.scope.internal.getFont(formObject.fontName,formObject.fontStyle).id,encodedColor=formObject.scope.__private__.encodeColorString(formObject.color),calcRes=calculateX(formObject,formObject.caption);return stream.push("0.749023 g"),stream.push("0 0 "+f2(AcroFormAppearance.internal.getWidth(formObject))+" "+f2(AcroFormAppearance.internal.getHeight(formObject))+" re"),stream.push("f"),stream.push("BMC"),stream.push("q"),stream.push("0 0 1 rg"),stream.push("/"+fontKey+" "+f2(calcRes.fontSize)+" Tf "+encodedColor),stream.push("BT"),stream.push(calcRes.text),stream.push("ET"),stream.push("Q"),stream.push("EMC"),xobj.stream=stream.join("\n"),xobj},YesNormal:function(formObject){var xobj=createFormXObject(formObject);xobj.scope=formObject.scope;var fontKey=formObject.scope.internal.getFont(formObject.fontName,formObject.fontStyle).id,encodedColor=formObject.scope.__private__.encodeColorString(formObject.color),stream=[],height=AcroFormAppearance.internal.getHeight(formObject),width=AcroFormAppearance.internal.getWidth(formObject),calcRes=calculateX(formObject,formObject.caption);return stream.push("1 g"),stream.push("0 0 "+f2(width)+" "+f2(height)+" re"),stream.push("f"),stream.push("q"),stream.push("0 0 1 rg"),stream.push("0 0 "+f2(width-1)+" "+f2(height-1)+" re"),stream.push("W"),stream.push("n"),stream.push("0 g"),stream.push("BT"),stream.push("/"+fontKey+" "+f2(calcRes.fontSize)+" Tf "+encodedColor),stream.push(calcRes.text),stream.push("ET"),stream.push("Q"),xobj.stream=stream.join("\n"),xobj},OffPushDown:function(formObject){var xobj=createFormXObject(formObject);xobj.scope=formObject.scope;var stream=[];return stream.push("0.749023 g"),stream.push("0 0 "+f2(AcroFormAppearance.internal.getWidth(formObject))+" "+f2(AcroFormAppearance.internal.getHeight(formObject))+" re"),stream.push("f"),xobj.stream=stream.join("\n"),xobj}},RadioButton:{Circle:{createAppearanceStream:function(name){var appearanceStreamContent={D:{Off:AcroFormAppearance.RadioButton.Circle.OffPushDown},N:{}};return appearanceStreamContent.N[name]=AcroFormAppearance.RadioButton.Circle.YesNormal,appearanceStreamContent.D[name]=AcroFormAppearance.RadioButton.Circle.YesPushDown,appearanceStreamContent},getCA:function(){return"l"},YesNormal:function(formObject){var xobj=createFormXObject(formObject);xobj.scope=formObject.scope;var stream=[],DotRadius=AcroFormAppearance.internal.getWidth(formObject)<=AcroFormAppearance.internal.getHeight(formObject)?AcroFormAppearance.internal.getWidth(formObject)/4:AcroFormAppearance.internal.getHeight(formObject)/4;DotRadius=Number((.9*DotRadius).toFixed(5));var c=AcroFormAppearance.internal.Bezier_C,DotRadiusBezier=Number((DotRadius*c).toFixed(5));return stream.push("q"),stream.push("1 0 0 1 "+f5(AcroFormAppearance.internal.getWidth(formObject)/2)+" "+f5(AcroFormAppearance.internal.getHeight(formObject)/2)+" cm"),stream.push(DotRadius+" 0 m"),stream.push(DotRadius+" "+DotRadiusBezier+" "+DotRadiusBezier+" "+DotRadius+" 0 "+DotRadius+" c"),stream.push("-"+DotRadiusBezier+" "+DotRadius+" -"+DotRadius+" "+DotRadiusBezier+" -"+DotRadius+" 0 c"),stream.push("-"+DotRadius+" -"+DotRadiusBezier+" -"+DotRadiusBezier+" -"+DotRadius+" 0 -"+DotRadius+" c"),stream.push(DotRadiusBezier+" -"+DotRadius+" "+DotRadius+" -"+DotRadiusBezier+" "+DotRadius+" 0 c"),stream.push("f"),stream.push("Q"),xobj.stream=stream.join("\n"),xobj},YesPushDown:function(formObject){var xobj=createFormXObject(formObject);xobj.scope=formObject.scope;var stream=[],DotRadius=AcroFormAppearance.internal.getWidth(formObject)<=AcroFormAppearance.internal.getHeight(formObject)?AcroFormAppearance.internal.getWidth(formObject)/4:AcroFormAppearance.internal.getHeight(formObject)/4;DotRadius=Number((.9*DotRadius).toFixed(5));var k=Number((2*DotRadius).toFixed(5)),kc=Number((k*AcroFormAppearance.internal.Bezier_C).toFixed(5)),dc=Number((DotRadius*AcroFormAppearance.internal.Bezier_C).toFixed(5));return stream.push("0.749023 g"),stream.push("q"),stream.push("1 0 0 1 "+f5(AcroFormAppearance.internal.getWidth(formObject)/2)+" "+f5(AcroFormAppearance.internal.getHeight(formObject)/2)+" cm"),stream.push(k+" 0 m"),stream.push(k+" "+kc+" "+kc+" "+k+" 0 "+k+" c"),stream.push("-"+kc+" "+k+" -"+k+" "+kc+" -"+k+" 0 c"),stream.push("-"+k+" -"+kc+" -"+kc+" -"+k+" 0 -"+k+" c"),stream.push(kc+" -"+k+" "+k+" -"+kc+" "+k+" 0 c"),stream.push("f"),stream.push("Q"),stream.push("0 g"),stream.push("q"),stream.push("1 0 0 1 "+f5(AcroFormAppearance.internal.getWidth(formObject)/2)+" "+f5(AcroFormAppearance.internal.getHeight(formObject)/2)+" cm"),stream.push(DotRadius+" 0 m"),stream.push(DotRadius+" "+dc+" "+dc+" "+DotRadius+" 0 "+DotRadius+" c"),stream.push("-"+dc+" "+DotRadius+" -"+DotRadius+" "+dc+" -"+DotRadius+" 0 c"),stream.push("-"+DotRadius+" -"+dc+" -"+dc+" -"+DotRadius+" 0 -"+DotRadius+" c"),stream.push(dc+" -"+DotRadius+" "+DotRadius+" -"+dc+" "+DotRadius+" 0 c"),stream.push("f"),stream.push("Q"),xobj.stream=stream.join("\n"),xobj},OffPushDown:function(formObject){var xobj=createFormXObject(formObject);xobj.scope=formObject.scope;var stream=[],DotRadius=AcroFormAppearance.internal.getWidth(formObject)<=AcroFormAppearance.internal.getHeight(formObject)?AcroFormAppearance.internal.getWidth(formObject)/4:AcroFormAppearance.internal.getHeight(formObject)/4;DotRadius=Number((.9*DotRadius).toFixed(5));var k=Number((2*DotRadius).toFixed(5)),kc=Number((k*AcroFormAppearance.internal.Bezier_C).toFixed(5));return stream.push("0.749023 g"),stream.push("q"),stream.push("1 0 0 1 "+f5(AcroFormAppearance.internal.getWidth(formObject)/2)+" "+f5(AcroFormAppearance.internal.getHeight(formObject)/2)+" cm"),stream.push(k+" 0 m"),stream.push(k+" "+kc+" "+kc+" "+k+" 0 "+k+" c"),stream.push("-"+kc+" "+k+" -"+k+" "+kc+" -"+k+" 0 c"),stream.push("-"+k+" -"+kc+" -"+kc+" -"+k+" 0 -"+k+" c"),stream.push(kc+" -"+k+" "+k+" -"+kc+" "+k+" 0 c"),stream.push("f"),stream.push("Q"),xobj.stream=stream.join("\n"),xobj}},Cross:{createAppearanceStream:function(name){var appearanceStreamContent={D:{Off:AcroFormAppearance.RadioButton.Cross.OffPushDown},N:{}};return appearanceStreamContent.N[name]=AcroFormAppearance.RadioButton.Cross.YesNormal,appearanceStreamContent.D[name]=AcroFormAppearance.RadioButton.Cross.YesPushDown,appearanceStreamContent},getCA:function(){return"8"},YesNormal:function(formObject){var xobj=createFormXObject(formObject);xobj.scope=formObject.scope;var stream=[],cross=AcroFormAppearance.internal.calculateCross(formObject);return stream.push("q"),stream.push("1 1 "+f2(AcroFormAppearance.internal.getWidth(formObject)-2)+" "+f2(AcroFormAppearance.internal.getHeight(formObject)-2)+" re"),stream.push("W"),stream.push("n"),stream.push(f2(cross.x1.x)+" "+f2(cross.x1.y)+" m"),stream.push(f2(cross.x2.x)+" "+f2(cross.x2.y)+" l"),stream.push(f2(cross.x4.x)+" "+f2(cross.x4.y)+" m"),stream.push(f2(cross.x3.x)+" "+f2(cross.x3.y)+" l"),stream.push("s"),stream.push("Q"),xobj.stream=stream.join("\n"),xobj},YesPushDown:function(formObject){var xobj=createFormXObject(formObject);xobj.scope=formObject.scope;var cross=AcroFormAppearance.internal.calculateCross(formObject),stream=[];return stream.push("0.749023 g"),stream.push("0 0 "+f2(AcroFormAppearance.internal.getWidth(formObject))+" "+f2(AcroFormAppearance.internal.getHeight(formObject))+" re"),stream.push("f"),stream.push("q"),stream.push("1 1 "+f2(AcroFormAppearance.internal.getWidth(formObject)-2)+" "+f2(AcroFormAppearance.internal.getHeight(formObject)-2)+" re"),stream.push("W"),stream.push("n"),stream.push(f2(cross.x1.x)+" "+f2(cross.x1.y)+" m"),stream.push(f2(cross.x2.x)+" "+f2(cross.x2.y)+" l"),stream.push(f2(cross.x4.x)+" "+f2(cross.x4.y)+" m"),stream.push(f2(cross.x3.x)+" "+f2(cross.x3.y)+" l"),stream.push("s"),stream.push("Q"),xobj.stream=stream.join("\n"),xobj},OffPushDown:function(formObject){var xobj=createFormXObject(formObject);xobj.scope=formObject.scope;var stream=[];return stream.push("0.749023 g"),stream.push("0 0 "+f2(AcroFormAppearance.internal.getWidth(formObject))+" "+f2(AcroFormAppearance.internal.getHeight(formObject))+" re"),stream.push("f"),xobj.stream=stream.join("\n"),xobj}}},createDefaultAppearanceStream:function(formObject){var fontKey=formObject.scope.internal.getFont(formObject.fontName,formObject.fontStyle).id,encodedColor=formObject.scope.__private__.encodeColorString(formObject.color);return"/"+fontKey+" "+formObject.fontSize+" Tf "+encodedColor}};AcroFormAppearance.internal={Bezier_C:.551915024494,calculateCross:function(formObject){var width=AcroFormAppearance.internal.getWidth(formObject),height=AcroFormAppearance.internal.getHeight(formObject),a=Math.min(width,height);return{x1:{x:(width-a)/2,y:(height-a)/2+a},x2:{x:(width-a)/2+a,y:(height-a)/2},x3:{x:(width-a)/2,y:(height-a)/2},x4:{x:(width-a)/2+a,y:(height-a)/2+a}}}},AcroFormAppearance.internal.getWidth=function(formObject){var result=0;return"object"===_typeof(formObject)&&(result=scale(formObject.Rect[2])),result},AcroFormAppearance.internal.getHeight=function(formObject){var result=0;return"object"===_typeof(formObject)&&(result=scale(formObject.Rect[3])),result};var addField=jsPDFAPI.addField=function(fieldObject){if(initializeAcroForm(this,fieldObject),!(fieldObject instanceof AcroFormField))throw new Error("Invalid argument passed to jsPDF.addField.");var formObject;return(formObject=fieldObject).scope.internal.acroformPlugin.printedOut&&(formObject.scope.internal.acroformPlugin.printedOut=!1,formObject.scope.internal.acroformPlugin.acroFormDictionaryRoot=null),formObject.scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields.push(formObject),fieldObject.page=fieldObject.scope.internal.getCurrentPageInfo().pageNumber,this};jsPDFAPI.AcroFormChoiceField=AcroFormChoiceField,jsPDFAPI.AcroFormListBox=AcroFormListBox,jsPDFAPI.AcroFormComboBox=AcroFormComboBox,jsPDFAPI.AcroFormEditBox=AcroFormEditBox,jsPDFAPI.AcroFormButton=AcroFormButton,jsPDFAPI.AcroFormPushButton=AcroFormPushButton,jsPDFAPI.AcroFormRadioButton=AcroFormRadioButton,jsPDFAPI.AcroFormCheckBox=AcroFormCheckBox,jsPDFAPI.AcroFormTextField=AcroFormTextField,jsPDFAPI.AcroFormPasswordField=AcroFormPasswordField,jsPDFAPI.AcroFormAppearance=AcroFormAppearance,jsPDFAPI.AcroForm={ChoiceField:AcroFormChoiceField,ListBox:AcroFormListBox,ComboBox:AcroFormComboBox,EditBox:AcroFormEditBox,Button:AcroFormButton,PushButton:AcroFormPushButton,RadioButton:AcroFormRadioButton,CheckBox:AcroFormCheckBox,TextField:AcroFormTextField,PasswordField:AcroFormPasswordField,Appearance:AcroFormAppearance},jsPDF.AcroForm={ChoiceField:AcroFormChoiceField,ListBox:AcroFormListBox,ComboBox:AcroFormComboBox,EditBox:AcroFormEditBox,Button:AcroFormButton,PushButton:AcroFormPushButton,RadioButton:AcroFormRadioButton,CheckBox:AcroFormCheckBox,TextField:AcroFormTextField,PasswordField:AcroFormPasswordField,Appearance:AcroFormAppearance};var AcroForm=jsPDF.AcroForm;function toLookup(arr){return arr.reduce((function(lookup,name,index){return lookup[name]=index,lookup}),{})}!function(jsPDFAPI){jsPDFAPI.__addimage__={};var UNKNOWN="UNKNOWN",imageFileTypeHeaders={PNG:[[137,80,78,71]],TIFF:[[77,77,0,42],[73,73,42,0]],JPEG:[[255,216,255,224,void 0,void 0,74,70,73,70,0],[255,216,255,225,void 0,void 0,69,120,105,102,0,0],[255,216,255,219],[255,216,255,238]],JPEG2000:[[0,0,0,12,106,80,32,32]],GIF87a:[[71,73,70,56,55,97]],GIF89a:[[71,73,70,56,57,97]],WEBP:[[82,73,70,70,void 0,void 0,void 0,void 0,87,69,66,80]],BMP:[[66,77],[66,65],[67,73],[67,80],[73,67],[80,84]]},getImageFileTypeByImageData=jsPDFAPI.__addimage__.getImageFileTypeByImageData=function(imageData,fallbackFormat){var i,j,headerSchemata,compareResult,fileType,result=UNKNOWN;if("RGBA"===(fallbackFormat=fallbackFormat||UNKNOWN)||void 0!==imageData.data&&imageData.data instanceof Uint8ClampedArray&&"height"in imageData&&"width"in imageData)return"RGBA";if(isArrayBufferView(imageData))for(fileType in imageFileTypeHeaders)for(headerSchemata=imageFileTypeHeaders[fileType],i=0;i<headerSchemata.length;i+=1){for(compareResult=!0,j=0;j<headerSchemata[i].length;j+=1)if(void 0!==headerSchemata[i][j]&&headerSchemata[i][j]!==imageData[j]){compareResult=!1;break}if(!0===compareResult){result=fileType;break}}else for(fileType in imageFileTypeHeaders)for(headerSchemata=imageFileTypeHeaders[fileType],i=0;i<headerSchemata.length;i+=1){for(compareResult=!0,j=0;j<headerSchemata[i].length;j+=1)if(void 0!==headerSchemata[i][j]&&headerSchemata[i][j]!==imageData.charCodeAt(j)){compareResult=!1;break}if(!0===compareResult){result=fileType;break}}return result===UNKNOWN&&fallbackFormat!==UNKNOWN&&(result=fallbackFormat),result},putImage=function putImage(image){for(var out=this.internal.write,putStream=this.internal.putStream,filter=(0,this.internal.getFilters)();-1!==filter.indexOf("FlateEncode");)filter.splice(filter.indexOf("FlateEncode"),1);image.objectId=this.internal.newObject();var additionalKeyValues=[];if(additionalKeyValues.push({key:"Type",value:"/XObject"}),additionalKeyValues.push({key:"Subtype",value:"/Image"}),additionalKeyValues.push({key:"Width",value:image.width}),additionalKeyValues.push({key:"Height",value:image.height}),image.colorSpace===color_spaces.INDEXED?additionalKeyValues.push({key:"ColorSpace",value:"[/Indexed /DeviceRGB "+(image.palette.length/3-1)+" "+("sMask"in image&&void 0!==image.sMask?image.objectId+2:image.objectId+1)+" 0 R]"}):(additionalKeyValues.push({key:"ColorSpace",value:"/"+image.colorSpace}),image.colorSpace===color_spaces.DEVICE_CMYK&&additionalKeyValues.push({key:"Decode",value:"[1 0 1 0 1 0 1 0]"})),additionalKeyValues.push({key:"BitsPerComponent",value:image.bitsPerComponent}),"decodeParameters"in image&&void 0!==image.decodeParameters&&additionalKeyValues.push({key:"DecodeParms",value:"<<"+image.decodeParameters+">>"}),"transparency"in image&&Array.isArray(image.transparency)){for(var transparency="",i=0,len=image.transparency.length;i<len;i++)transparency+=image.transparency[i]+" "+image.transparency[i]+" ";additionalKeyValues.push({key:"Mask",value:"["+transparency+"]"})}void 0!==image.sMask&&additionalKeyValues.push({key:"SMask",value:image.objectId+1+" 0 R"});var alreadyAppliedFilters=void 0!==image.filter?["/"+image.filter]:void 0;if(putStream({data:image.data,additionalKeyValues:additionalKeyValues,alreadyAppliedFilters:alreadyAppliedFilters,objectId:image.objectId}),out("endobj"),"sMask"in image&&void 0!==image.sMask){var decodeParameters="/Predictor "+image.predictor+" /Colors 1 /BitsPerComponent "+image.bitsPerComponent+" /Columns "+image.width,sMask={width:image.width,height:image.height,colorSpace:"DeviceGray",bitsPerComponent:image.bitsPerComponent,decodeParameters:decodeParameters,data:image.sMask};"filter"in image&&(sMask.filter=image.filter),putImage.call(this,sMask)}if(image.colorSpace===color_spaces.INDEXED){var objId=this.internal.newObject();putStream({data:arrayBufferToBinaryString(new Uint8Array(image.palette)),objectId:objId}),out("endobj")}},putResourcesCallback=function(){var images=this.internal.collections.addImage_images;for(var i in images)putImage.call(this,images[i])},putXObjectsDictCallback=function(){var image,images=this.internal.collections.addImage_images,out=this.internal.write;for(var i in images)out("/I"+(image=images[i]).index,image.objectId,"0","R")},initialize=function(){this.internal.collections.addImage_images||(this.internal.collections.addImage_images={},this.internal.events.subscribe("putResources",putResourcesCallback),this.internal.events.subscribe("putXobjectDict",putXObjectsDictCallback))},getImages=function(){var images=this.internal.collections.addImage_images;return initialize.call(this),images},getImageIndex=function(){return Object.keys(this.internal.collections.addImage_images).length},isImageTypeSupported=function(type){return"function"==typeof jsPDFAPI["process"+type.toUpperCase()]},isDOMElement=function(object){return"object"===_typeof(object)&&1===object.nodeType},getImageDataFromElement=function(element,format){if("IMG"===element.nodeName&&element.hasAttribute("src")){var src=""+element.getAttribute("src");if(0===src.indexOf("data:image/"))return atob(unescape(src).split("base64,").pop());var tmpImageData=jsPDFAPI.loadFile(src,!0);if(void 0!==tmpImageData)return tmpImageData}if("CANVAS"===element.nodeName){if(0===element.width||0===element.height)throw new Error("Given canvas must have data. Canvas width: "+element.width+", height: "+element.height);var mimeType;switch(format){case"PNG":mimeType="image/png";break;case"WEBP":mimeType="image/webp";break;default:mimeType="image/jpeg"}return atob(element.toDataURL(mimeType,1).split("base64,").pop())}},checkImagesForAlias=function(alias){var images=this.internal.collections.addImage_images;if(images)for(var e in images)if(alias===images[e].alias)return images[e]},determineWidthAndHeight=function(width,height,image){return width||height||(width=-96,height=-96),width<0&&(width=-1*image.width*72/width/this.internal.scaleFactor),height<0&&(height=-1*image.height*72/height/this.internal.scaleFactor),0===width&&(width=height*image.width/image.height),0===height&&(height=width*image.height/image.width),[width,height]},writeImageToPDF=function(x,y,width,height,image,rotation){var dims=determineWidthAndHeight.call(this,width,height,image),coord=this.internal.getCoordinateString,vcoord=this.internal.getVerticalCoordinateString,images=getImages.call(this);if(width=dims[0],height=dims[1],images[image.index]=image,rotation){rotation*=Math.PI/180;var c=Math.cos(rotation),s=Math.sin(rotation),f4=function(number){return number.toFixed(4)},rotationTransformationMatrix=[f4(c),f4(s),f4(-1*s),f4(c),0,0,"cm"]}this.internal.write("q"),rotation?(this.internal.write([1,"0","0",1,coord(x),vcoord(y+height),"cm"].join(" ")),this.internal.write(rotationTransformationMatrix.join(" ")),this.internal.write([coord(width),"0","0",coord(height),"0","0","cm"].join(" "))):this.internal.write([coord(width),"0","0",coord(height),coord(x),vcoord(y+height),"cm"].join(" ")),this.isAdvancedAPI()&&this.internal.write([1,0,0,-1,0,0,"cm"].join(" ")),this.internal.write("/I"+image.index+" Do"),this.internal.write("Q")},color_spaces=jsPDFAPI.color_spaces={DEVICE_RGB:"DeviceRGB",DEVICE_GRAY:"DeviceGray",DEVICE_CMYK:"DeviceCMYK",CAL_GREY:"CalGray",CAL_RGB:"CalRGB",LAB:"Lab",ICC_BASED:"ICCBased",INDEXED:"Indexed",PATTERN:"Pattern",SEPARATION:"Separation",DEVICE_N:"DeviceN"};jsPDFAPI.decode={DCT_DECODE:"DCTDecode",FLATE_DECODE:"FlateDecode",LZW_DECODE:"LZWDecode",JPX_DECODE:"JPXDecode",JBIG2_DECODE:"JBIG2Decode",ASCII85_DECODE:"ASCII85Decode",ASCII_HEX_DECODE:"ASCIIHexDecode",RUN_LENGTH_DECODE:"RunLengthDecode",CCITT_FAX_DECODE:"CCITTFaxDecode"};var image_compression=jsPDFAPI.image_compression={NONE:"NONE",FAST:"FAST",MEDIUM:"MEDIUM",SLOW:"SLOW"},sHashCode=jsPDFAPI.__addimage__.sHashCode=function(data){var i,len,hash=0;if("string"==typeof data)for(len=data.length,i=0;i<len;i++)hash=(hash<<5)-hash+data.charCodeAt(i),hash|=0;else if(isArrayBufferView(data))for(len=data.byteLength/2,i=0;i<len;i++)hash=(hash<<5)-hash+data[i],hash|=0;return hash},validateStringAsBase64=jsPDFAPI.__addimage__.validateStringAsBase64=function(possibleBase64String){(possibleBase64String=possibleBase64String||"").toString().trim();var result=!0;return 0===possibleBase64String.length&&(result=!1),possibleBase64String.length%4!=0&&(result=!1),!1===/^[A-Za-z0-9+/]+$/.test(possibleBase64String.substr(0,possibleBase64String.length-2))&&(result=!1),!1===/^[A-Za-z0-9/][A-Za-z0-9+/]|[A-Za-z0-9+/]=|==$/.test(possibleBase64String.substr(-2))&&(result=!1),result},extractImageFromDataUrl=jsPDFAPI.__addimage__.extractImageFromDataUrl=function(dataUrl){var dataUrlParts=(dataUrl=dataUrl||"").split("base64,"),result=null;if(2===dataUrlParts.length){var extractedInfo=/^data:(\w*\/\w*);*(charset=(?!charset=)[\w=-]*)*;*$/.exec(dataUrlParts[0]);Array.isArray(extractedInfo)&&(result={mimeType:extractedInfo[1],charset:extractedInfo[2],data:dataUrlParts[1]})}return result},supportsArrayBuffer=jsPDFAPI.__addimage__.supportsArrayBuffer=function(){return"undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array};jsPDFAPI.__addimage__.isArrayBuffer=function(object){return supportsArrayBuffer()&&object instanceof ArrayBuffer};var isArrayBufferView=jsPDFAPI.__addimage__.isArrayBufferView=function(object){return supportsArrayBuffer()&&"undefined"!=typeof Uint32Array&&(object instanceof Int8Array||object instanceof Uint8Array||"undefined"!=typeof Uint8ClampedArray&&object instanceof Uint8ClampedArray||object instanceof Int16Array||object instanceof Uint16Array||object instanceof Int32Array||object instanceof Uint32Array||object instanceof Float32Array||object instanceof Float64Array)},binaryStringToUint8Array=jsPDFAPI.__addimage__.binaryStringToUint8Array=function(binary_string){for(var len=binary_string.length,bytes=new Uint8Array(len),i=0;i<len;i++)bytes[i]=binary_string.charCodeAt(i);return bytes},arrayBufferToBinaryString=jsPDFAPI.__addimage__.arrayBufferToBinaryString=function(buffer){for(var out="",buf=isArrayBufferView(buffer)?buffer:new Uint8Array(buffer),i=0;i<buf.length;i+=8192)out+=String.fromCharCode.apply(null,buf.subarray(i,i+8192));return out};jsPDFAPI.addImage=function(){var imageData,format,x,y,w,h,alias,compression,rotation;if("number"==typeof arguments[1]?(format=UNKNOWN,x=arguments[1],y=arguments[2],w=arguments[3],h=arguments[4],alias=arguments[5],compression=arguments[6],rotation=arguments[7]):(format=arguments[1],x=arguments[2],y=arguments[3],w=arguments[4],h=arguments[5],alias=arguments[6],compression=arguments[7],rotation=arguments[8]),"object"===_typeof(imageData=arguments[0])&&!isDOMElement(imageData)&&"imageData"in imageData){var options=imageData;imageData=options.imageData,format=options.format||format||UNKNOWN,x=options.x||x||0,y=options.y||y||0,w=options.w||options.width||w,h=options.h||options.height||h,alias=options.alias||alias,compression=options.compression||compression,rotation=options.rotation||options.angle||rotation}var filter=this.internal.getFilters();if(void 0===compression&&-1!==filter.indexOf("FlateEncode")&&(compression="SLOW"),isNaN(x)||isNaN(y))throw new Error("Invalid coordinates passed to jsPDF.addImage");initialize.call(this);var image=processImageData.call(this,imageData,format,alias,compression);return writeImageToPDF.call(this,x,y,w,h,image,rotation),this};var processImageData=function(imageData,format,alias,compression){var result,dataAsBinaryString,value;if("string"==typeof imageData&&getImageFileTypeByImageData(imageData)===UNKNOWN){imageData=unescape(imageData);var tmpImageData=convertBase64ToBinaryString(imageData,!1);(""!==tmpImageData||void 0!==(tmpImageData=jsPDFAPI.loadFile(imageData,!0)))&&(imageData=tmpImageData)}if(isDOMElement(imageData)&&(imageData=getImageDataFromElement(imageData,format)),format=getImageFileTypeByImageData(imageData,format),!isImageTypeSupported(format))throw new Error("addImage does not support files of type '"+format+"', please ensure that a plugin for '"+format+"' support is added.");if((null==(value=alias)||0===value.length)&&(alias=function(imageData){return"string"==typeof imageData||isArrayBufferView(imageData)?sHashCode(imageData):isArrayBufferView(imageData.data)?sHashCode(imageData.data):null}(imageData)),(result=checkImagesForAlias.call(this,alias))||(supportsArrayBuffer()&&(imageData instanceof Uint8Array||"RGBA"===format||(dataAsBinaryString=imageData,imageData=binaryStringToUint8Array(imageData))),result=this["process"+format.toUpperCase()](imageData,getImageIndex.call(this),alias,function(value){return value&&"string"==typeof value&&(value=value.toUpperCase()),value in jsPDFAPI.image_compression?value:image_compression.NONE}(compression),dataAsBinaryString)),!result)throw new Error("An unknown error occurred whilst processing the image.");return result},convertBase64ToBinaryString=jsPDFAPI.__addimage__.convertBase64ToBinaryString=function(stringData,throwError){var base64Info;throwError="boolean"!=typeof throwError||throwError;var rawData,imageData="";if("string"==typeof stringData){rawData=null!==(base64Info=extractImageFromDataUrl(stringData))?base64Info.data:stringData;try{imageData=atob(rawData)}catch(e){if(throwError)throw validateStringAsBase64(rawData)?new Error("atob-Error in jsPDF.convertBase64ToBinaryString "+e.message):new Error("Supplied Data is not a valid base64-String jsPDF.convertBase64ToBinaryString ")}}return imageData};jsPDFAPI.getImageProperties=function(imageData){var image,format,tmpImageData="";if(isDOMElement(imageData)&&(imageData=getImageDataFromElement(imageData)),"string"==typeof imageData&&getImageFileTypeByImageData(imageData)===UNKNOWN&&(""===(tmpImageData=convertBase64ToBinaryString(imageData,!1))&&(tmpImageData=jsPDFAPI.loadFile(imageData)||""),imageData=tmpImageData),format=getImageFileTypeByImageData(imageData),!isImageTypeSupported(format))throw new Error("addImage does not support files of type '"+format+"', please ensure that a plugin for '"+format+"' support is added.");if(!supportsArrayBuffer()||imageData instanceof Uint8Array||(imageData=binaryStringToUint8Array(imageData)),!(image=this["process"+format.toUpperCase()](imageData)))throw new Error("An unknown error occurred whilst processing the image");return image.fileType=format,image}}(jsPDF.API),
+/**
+   * @license
+   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+function(jsPDFAPI){var notEmpty=function(obj){if(void 0!==obj&&""!=obj)return!0};jsPDF.API.events.push(["addPage",function(addPageData){this.internal.getPageInfo(addPageData.pageNumber).pageContext.annotations=[]}]),jsPDFAPI.events.push(["putPage",function(putPageData){for(var anno,rect,line,getHorizontalCoordinateString=this.internal.getCoordinateString,getVerticalCoordinateString=this.internal.getVerticalCoordinateString,pageInfo=this.internal.getPageInfoByObjId(putPageData.objId),pageAnnos=putPageData.pageContext.annotations,found=!1,a=0;a<pageAnnos.length&&!found;a++)switch((anno=pageAnnos[a]).type){case"link":(notEmpty(anno.options.url)||notEmpty(anno.options.pageNumber))&&(found=!0);break;case"reference":case"text":case"freetext":found=!0}if(0!=found){this.internal.write("/Annots [");for(var i=0;i<pageAnnos.length;i++){anno=pageAnnos[i];var escape=this.internal.pdfEscape,encryptor=this.internal.getEncryptor(putPageData.objId);switch(anno.type){case"reference":this.internal.write(" "+anno.object.objId+" 0 R ");break;case"text":var objText=this.internal.newAdditionalObject(),objPopup=this.internal.newAdditionalObject(),encryptorText=this.internal.getEncryptor(objText.objId),title=anno.title||"Note";line="<</Type /Annot /Subtype /Text "+(rect="/Rect ["+getHorizontalCoordinateString(anno.bounds.x)+" "+getVerticalCoordinateString(anno.bounds.y+anno.bounds.h)+" "+getHorizontalCoordinateString(anno.bounds.x+anno.bounds.w)+" "+getVerticalCoordinateString(anno.bounds.y)+"] ")+"/Contents ("+escape(encryptorText(anno.contents))+")",line+=" /Popup "+objPopup.objId+" 0 R",line+=" /P "+pageInfo.objId+" 0 R",line+=" /T ("+escape(encryptorText(title))+") >>",objText.content=line;var parent=objText.objId+" 0 R";line="<</Type /Annot /Subtype /Popup "+(rect="/Rect ["+getHorizontalCoordinateString(anno.bounds.x+30)+" "+getVerticalCoordinateString(anno.bounds.y+anno.bounds.h)+" "+getHorizontalCoordinateString(anno.bounds.x+anno.bounds.w+30)+" "+getVerticalCoordinateString(anno.bounds.y)+"] ")+" /Parent "+parent,anno.open&&(line+=" /Open true"),line+=" >>",objPopup.content=line,this.internal.write(objText.objId,"0 R",objPopup.objId,"0 R");break;case"freetext":rect="/Rect ["+getHorizontalCoordinateString(anno.bounds.x)+" "+getVerticalCoordinateString(anno.bounds.y)+" "+getHorizontalCoordinateString(anno.bounds.x+anno.bounds.w)+" "+getVerticalCoordinateString(anno.bounds.y+anno.bounds.h)+"] ";var color=anno.color||"#000000";line="<</Type /Annot /Subtype /FreeText "+rect+"/Contents ("+escape(encryptor(anno.contents))+")",line+=" /DS(font: Helvetica,sans-serif 12.0pt; text-align:left; color:#"+color+")",line+=" /Border [0 0 0]",line+=" >>",this.internal.write(line);break;case"link":if(anno.options.name){var loc=this.annotations._nameMap[anno.options.name];anno.options.pageNumber=loc.page,anno.options.top=loc.y}else anno.options.top||(anno.options.top=0);if(rect="/Rect ["+anno.finalBounds.x+" "+anno.finalBounds.y+" "+anno.finalBounds.w+" "+anno.finalBounds.h+"] ",line="",anno.options.url)line="<</Type /Annot /Subtype /Link "+rect+"/Border [0 0 0] /A <</S /URI /URI ("+escape(encryptor(anno.options.url))+") >>";else if(anno.options.pageNumber){switch(line="<</Type /Annot /Subtype /Link "+rect+"/Border [0 0 0] /Dest ["+this.internal.getPageInfo(anno.options.pageNumber).objId+" 0 R",anno.options.magFactor=anno.options.magFactor||"XYZ",anno.options.magFactor){case"Fit":line+=" /Fit]";break;case"FitH":line+=" /FitH "+anno.options.top+"]";break;case"FitV":anno.options.left=anno.options.left||0,line+=" /FitV "+anno.options.left+"]";break;default:var top=getVerticalCoordinateString(anno.options.top);anno.options.left=anno.options.left||0,void 0===anno.options.zoom&&(anno.options.zoom=0),line+=" /XYZ "+anno.options.left+" "+top+" "+anno.options.zoom+"]"}}""!=line&&(line+=" >>",this.internal.write(line))}}this.internal.write("]")}}]),jsPDFAPI.createAnnotation=function(options){var pageInfo=this.internal.getCurrentPageInfo();switch(options.type){case"link":this.link(options.bounds.x,options.bounds.y,options.bounds.w,options.bounds.h,options);break;case"text":case"freetext":pageInfo.pageContext.annotations.push(options)}},jsPDFAPI.link=function(x,y,w,h,options){var pageInfo=this.internal.getCurrentPageInfo(),getHorizontalCoordinateString=this.internal.getCoordinateString,getVerticalCoordinateString=this.internal.getVerticalCoordinateString;pageInfo.pageContext.annotations.push({finalBounds:{x:getHorizontalCoordinateString(x),y:getVerticalCoordinateString(y),w:getHorizontalCoordinateString(x+w),h:getVerticalCoordinateString(y+h)},options:options,type:"link"})},jsPDFAPI.textWithLink=function(text,x,y,options){var linkHeight,linkWidth,totalLineWidth=this.getTextWidth(text),lineHeight=this.internal.getLineHeight()/this.internal.scaleFactor;if(void 0!==options.maxWidth){linkWidth=options.maxWidth;var numOfLines=this.splitTextToSize(text,linkWidth).length;linkHeight=Math.ceil(lineHeight*numOfLines)}else linkWidth=totalLineWidth,linkHeight=lineHeight;return this.text(text,x,y,options),y+=.2*lineHeight,"center"===options.align&&(x-=totalLineWidth/2),"right"===options.align&&(x-=totalLineWidth),this.link(x,y-lineHeight,linkWidth,linkHeight,options),totalLineWidth},jsPDFAPI.getTextWidth=function(text){var fontSize=this.internal.getFontSize();return this.getStringUnitWidth(text)*fontSize/this.internal.scaleFactor}}(jsPDF.API),
+/**
+   * @license
+   * Copyright (c) 2017 Aras Abbasi
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+function(jsPDFAPI){var arabicSubstitionA={1569:[65152],1570:[65153,65154],1571:[65155,65156],1572:[65157,65158],1573:[65159,65160],1574:[65161,65162,65163,65164],1575:[65165,65166],1576:[65167,65168,65169,65170],1577:[65171,65172],1578:[65173,65174,65175,65176],1579:[65177,65178,65179,65180],1580:[65181,65182,65183,65184],1581:[65185,65186,65187,65188],1582:[65189,65190,65191,65192],1583:[65193,65194],1584:[65195,65196],1585:[65197,65198],1586:[65199,65200],1587:[65201,65202,65203,65204],1588:[65205,65206,65207,65208],1589:[65209,65210,65211,65212],1590:[65213,65214,65215,65216],1591:[65217,65218,65219,65220],1592:[65221,65222,65223,65224],1593:[65225,65226,65227,65228],1594:[65229,65230,65231,65232],1601:[65233,65234,65235,65236],1602:[65237,65238,65239,65240],1603:[65241,65242,65243,65244],1604:[65245,65246,65247,65248],1605:[65249,65250,65251,65252],1606:[65253,65254,65255,65256],1607:[65257,65258,65259,65260],1608:[65261,65262],1609:[65263,65264,64488,64489],1610:[65265,65266,65267,65268],1649:[64336,64337],1655:[64477],1657:[64358,64359,64360,64361],1658:[64350,64351,64352,64353],1659:[64338,64339,64340,64341],1662:[64342,64343,64344,64345],1663:[64354,64355,64356,64357],1664:[64346,64347,64348,64349],1667:[64374,64375,64376,64377],1668:[64370,64371,64372,64373],1670:[64378,64379,64380,64381],1671:[64382,64383,64384,64385],1672:[64392,64393],1676:[64388,64389],1677:[64386,64387],1678:[64390,64391],1681:[64396,64397],1688:[64394,64395],1700:[64362,64363,64364,64365],1702:[64366,64367,64368,64369],1705:[64398,64399,64400,64401],1709:[64467,64468,64469,64470],1711:[64402,64403,64404,64405],1713:[64410,64411,64412,64413],1715:[64406,64407,64408,64409],1722:[64414,64415],1723:[64416,64417,64418,64419],1726:[64426,64427,64428,64429],1728:[64420,64421],1729:[64422,64423,64424,64425],1733:[64480,64481],1734:[64473,64474],1735:[64471,64472],1736:[64475,64476],1737:[64482,64483],1739:[64478,64479],1740:[64508,64509,64510,64511],1744:[64484,64485,64486,64487],1746:[64430,64431],1747:[64432,64433]},ligatures={65247:{65154:65269,65156:65271,65160:65273,65166:65275},65248:{65154:65270,65156:65272,65160:65274,65166:65276},65165:{65247:{65248:{65258:65010}}},1617:{1612:64606,1613:64607,1614:64608,1615:64609,1616:64610}},arabic_diacritics={1612:64606,1613:64607,1614:64608,1615:64609,1616:64610},alfletter=[1570,1571,1573,1575];jsPDFAPI.__arabicParser__={};var isInArabicSubstitutionA=jsPDFAPI.__arabicParser__.isInArabicSubstitutionA=function(letter){return void 0!==arabicSubstitionA[letter.charCodeAt(0)]},isArabicLetter=jsPDFAPI.__arabicParser__.isArabicLetter=function(letter){return"string"==typeof letter&&/^[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]+$/.test(letter)},isArabicEndLetter=jsPDFAPI.__arabicParser__.isArabicEndLetter=function(letter){return isArabicLetter(letter)&&isInArabicSubstitutionA(letter)&&arabicSubstitionA[letter.charCodeAt(0)].length<=2},isArabicAlfLetter=jsPDFAPI.__arabicParser__.isArabicAlfLetter=function(letter){return isArabicLetter(letter)&&alfletter.indexOf(letter.charCodeAt(0))>=0};jsPDFAPI.__arabicParser__.arabicLetterHasIsolatedForm=function(letter){return isArabicLetter(letter)&&isInArabicSubstitutionA(letter)&&arabicSubstitionA[letter.charCodeAt(0)].length>=1};var arabicLetterHasFinalForm=jsPDFAPI.__arabicParser__.arabicLetterHasFinalForm=function(letter){return isArabicLetter(letter)&&isInArabicSubstitutionA(letter)&&arabicSubstitionA[letter.charCodeAt(0)].length>=2};jsPDFAPI.__arabicParser__.arabicLetterHasInitialForm=function(letter){return isArabicLetter(letter)&&isInArabicSubstitutionA(letter)&&arabicSubstitionA[letter.charCodeAt(0)].length>=3};var arabicLetterHasMedialForm=jsPDFAPI.__arabicParser__.arabicLetterHasMedialForm=function(letter){return isArabicLetter(letter)&&isInArabicSubstitutionA(letter)&&4==arabicSubstitionA[letter.charCodeAt(0)].length},resolveLigatures=jsPDFAPI.__arabicParser__.resolveLigatures=function(letters){var i=0,tmpLigatures=ligatures,result="",effectedLetters=0;for(i=0;i<letters.length;i+=1)void 0!==tmpLigatures[letters.charCodeAt(i)]?(effectedLetters++,"number"==typeof(tmpLigatures=tmpLigatures[letters.charCodeAt(i)])&&(result+=String.fromCharCode(tmpLigatures),tmpLigatures=ligatures,effectedLetters=0),i===letters.length-1&&(tmpLigatures=ligatures,result+=letters.charAt(i-(effectedLetters-1)),i-=effectedLetters-1,effectedLetters=0)):(tmpLigatures=ligatures,result+=letters.charAt(i-effectedLetters),i-=effectedLetters,effectedLetters=0);return result};jsPDFAPI.__arabicParser__.isArabicDiacritic=function(letter){return void 0!==letter&&void 0!==arabic_diacritics[letter.charCodeAt(0)]};var getCorrectForm=jsPDFAPI.__arabicParser__.getCorrectForm=function(currentChar,beforeChar,nextChar){return isArabicLetter(currentChar)?!1===isInArabicSubstitutionA(currentChar)?-1:!arabicLetterHasFinalForm(currentChar)||!isArabicLetter(beforeChar)&&!isArabicLetter(nextChar)||!isArabicLetter(nextChar)&&isArabicEndLetter(beforeChar)||isArabicEndLetter(currentChar)&&!isArabicLetter(beforeChar)||isArabicEndLetter(currentChar)&&isArabicAlfLetter(beforeChar)||isArabicEndLetter(currentChar)&&isArabicEndLetter(beforeChar)?0:arabicLetterHasMedialForm(currentChar)&&isArabicLetter(beforeChar)&&!isArabicEndLetter(beforeChar)&&isArabicLetter(nextChar)&&arabicLetterHasFinalForm(nextChar)?3:isArabicEndLetter(currentChar)||!isArabicLetter(nextChar)?1:2:-1},parseArabic=function(text){var i=0,j=0,position=0,currentLetter="",prevLetter="",nextLetter="",words=(text=text||"").split("\\s+"),newWords=[];for(i=0;i<words.length;i+=1){for(newWords.push(""),j=0;j<words[i].length;j+=1)currentLetter=words[i][j],prevLetter=words[i][j-1],nextLetter=words[i][j+1],isArabicLetter(currentLetter)?(position=getCorrectForm(currentLetter,prevLetter,nextLetter),newWords[i]+=-1!==position?String.fromCharCode(arabicSubstitionA[currentLetter.charCodeAt(0)][position]):currentLetter):newWords[i]+=currentLetter;newWords[i]=resolveLigatures(newWords[i])}return newWords.join(" ")},processArabic=jsPDFAPI.__arabicParser__.processArabic=jsPDFAPI.processArabic=function(){var result,text="string"==typeof arguments[0]?arguments[0]:arguments[0].text,tmpText=[];if(Array.isArray(text)){var i=0;for(tmpText=[],i=0;i<text.length;i+=1)Array.isArray(text[i])?tmpText.push([parseArabic(text[i][0]),text[i][1],text[i][2]]):tmpText.push([parseArabic(text[i])]);result=tmpText}else result=parseArabic(text);return"string"==typeof arguments[0]?result:(arguments[0].text=result,arguments[0])};jsPDFAPI.events.push(["preProcessText",processArabic])}(jsPDF.API),
+/** @license
+   * jsPDF Autoprint Plugin
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+function(jsPDFAPI){jsPDFAPI.autoPrint=function(options){var refAutoPrintTag;if((options=options||{}).variant=options.variant||"non-conform","javascript"===options.variant)this.addJS("print({});");else this.internal.events.subscribe("postPutResources",(function(){refAutoPrintTag=this.internal.newObject(),this.internal.out("<<"),this.internal.out("/S /Named"),this.internal.out("/Type /Action"),this.internal.out("/N /Print"),this.internal.out(">>"),this.internal.out("endobj")})),this.internal.events.subscribe("putCatalog",(function(){this.internal.out("/OpenAction "+refAutoPrintTag+" 0 R")}));return this}}(jsPDF.API),
+/**
+   * @license
+   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+function(jsPDFAPI){var Canvas=function(){var jsPdfInstance=void 0;Object.defineProperty(this,"pdf",{get:function(){return jsPdfInstance},set:function(value){jsPdfInstance=value}});var _width=150;Object.defineProperty(this,"width",{get:function(){return _width},set:function(value){_width=isNaN(value)||!1===Number.isInteger(value)||value<0?150:value,this.getContext("2d").pageWrapXEnabled&&(this.getContext("2d").pageWrapX=_width+1)}});var _height=300;Object.defineProperty(this,"height",{get:function(){return _height},set:function(value){_height=isNaN(value)||!1===Number.isInteger(value)||value<0?300:value,this.getContext("2d").pageWrapYEnabled&&(this.getContext("2d").pageWrapY=_height+1)}});var _childNodes=[];Object.defineProperty(this,"childNodes",{get:function(){return _childNodes},set:function(value){_childNodes=value}});var _style={};Object.defineProperty(this,"style",{get:function(){return _style},set:function(value){_style=value}}),Object.defineProperty(this,"parentNode",{})};Canvas.prototype.getContext=function(contextType,contextAttributes){var key;if("2d"!==(contextType=contextType||"2d"))return null;for(key in contextAttributes)this.pdf.context2d.hasOwnProperty(key)&&(this.pdf.context2d[key]=contextAttributes[key]);return this.pdf.context2d._canvas=this,this.pdf.context2d},Canvas.prototype.toDataURL=function(){throw new Error("toDataURL is not implemented.")},jsPDFAPI.events.push(["initialized",function(){this.canvas=new Canvas,this.canvas.pdf=this}])}(jsPDF.API),function(jsPDFAPI){var NO_MARGINS={left:0,top:0,bottom:0,right:0},printingHeaderRow=!1,_initialize=function(){void 0===this.internal.__cell__&&(this.internal.__cell__={},this.internal.__cell__.padding=3,this.internal.__cell__.headerFunction=void 0,this.internal.__cell__.margins=Object.assign({},NO_MARGINS),this.internal.__cell__.margins.width=this.getPageWidth(),_reset.call(this))},_reset=function(){this.internal.__cell__.lastCell=new Cell,this.internal.__cell__.pages=1},Cell=function(){var _x=arguments[0];Object.defineProperty(this,"x",{enumerable:!0,get:function(){return _x},set:function(value){_x=value}});var _y=arguments[1];Object.defineProperty(this,"y",{enumerable:!0,get:function(){return _y},set:function(value){_y=value}});var _width=arguments[2];Object.defineProperty(this,"width",{enumerable:!0,get:function(){return _width},set:function(value){_width=value}});var _height=arguments[3];Object.defineProperty(this,"height",{enumerable:!0,get:function(){return _height},set:function(value){_height=value}});var _text=arguments[4];Object.defineProperty(this,"text",{enumerable:!0,get:function(){return _text},set:function(value){_text=value}});var _lineNumber=arguments[5];Object.defineProperty(this,"lineNumber",{enumerable:!0,get:function(){return _lineNumber},set:function(value){_lineNumber=value}});var _align=arguments[6];return Object.defineProperty(this,"align",{enumerable:!0,get:function(){return _align},set:function(value){_align=value}}),this};Cell.prototype.clone=function(){return new Cell(this.x,this.y,this.width,this.height,this.text,this.lineNumber,this.align)},Cell.prototype.toArray=function(){return[this.x,this.y,this.width,this.height,this.text,this.lineNumber,this.align]},jsPDFAPI.setHeaderFunction=function(func){return _initialize.call(this),this.internal.__cell__.headerFunction="function"==typeof func?func:void 0,this},jsPDFAPI.getTextDimensions=function(text,options){_initialize.call(this);var fontSize=(options=options||{}).fontSize||this.getFontSize(),font=options.font||this.getFont(),scaleFactor=options.scaleFactor||this.internal.scaleFactor,width=0,amountOfLines=0,tempWidth=0,scope=this;if(!Array.isArray(text)&&"string"!=typeof text){if("number"!=typeof text)throw new Error("getTextDimensions expects text-parameter to be of type String or type Number or an Array of Strings.");text=String(text)}var maxWidth=options.maxWidth;maxWidth>0?"string"==typeof text?text=this.splitTextToSize(text,maxWidth):"[object Array]"===Object.prototype.toString.call(text)&&(text=text.reduce((function(acc,textLine){return acc.concat(scope.splitTextToSize(textLine,maxWidth))}),[])):text=Array.isArray(text)?text:[text];for(var i=0;i<text.length;i++)width<(tempWidth=this.getStringUnitWidth(text[i],{font:font})*fontSize)&&(width=tempWidth);return 0!==width&&(amountOfLines=text.length),{w:width/=scaleFactor,h:Math.max((amountOfLines*fontSize*this.getLineHeightFactor()-fontSize*(this.getLineHeightFactor()-1))/scaleFactor,0)}},jsPDFAPI.cellAddPage=function(){_initialize.call(this),this.addPage();var margins=this.internal.__cell__.margins||NO_MARGINS;return this.internal.__cell__.lastCell=new Cell(margins.left,margins.top,void 0,void 0),this.internal.__cell__.pages+=1,this};var cell=jsPDFAPI.cell=function(){var currentCell;currentCell=arguments[0]instanceof Cell?arguments[0]:new Cell(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]),_initialize.call(this);var lastCell=this.internal.__cell__.lastCell,padding=this.internal.__cell__.padding,margins=this.internal.__cell__.margins||NO_MARGINS,tableHeaderRow=this.internal.__cell__.tableHeaderRow,printHeaders=this.internal.__cell__.printHeaders;return void 0!==lastCell.lineNumber&&(lastCell.lineNumber===currentCell.lineNumber?(currentCell.x=(lastCell.x||0)+(lastCell.width||0),currentCell.y=lastCell.y||0):lastCell.y+lastCell.height+currentCell.height+margins.bottom>this.getPageHeight()?(this.cellAddPage(),currentCell.y=margins.top,printHeaders&&tableHeaderRow&&(this.printHeaderRow(currentCell.lineNumber,!0),currentCell.y+=tableHeaderRow[0].height)):currentCell.y=lastCell.y+lastCell.height||currentCell.y),void 0!==currentCell.text[0]&&(this.rect(currentCell.x,currentCell.y,currentCell.width,currentCell.height,!0===printingHeaderRow?"FD":void 0),"right"===currentCell.align?this.text(currentCell.text,currentCell.x+currentCell.width-padding,currentCell.y+padding,{align:"right",baseline:"top"}):"center"===currentCell.align?this.text(currentCell.text,currentCell.x+currentCell.width/2,currentCell.y+padding,{align:"center",baseline:"top",maxWidth:currentCell.width-padding-padding}):this.text(currentCell.text,currentCell.x+padding,currentCell.y+padding,{align:"left",baseline:"top",maxWidth:currentCell.width-padding-padding})),this.internal.__cell__.lastCell=currentCell,this};jsPDFAPI.table=function(x,y,data,headers,config){if(_initialize.call(this),!data)throw new Error("No data for PDF table.");var i,column,j,headerName,headerNames=[],headerLabels=[],headerAligns=[],columnMatrix={},columnWidths={},columnMinWidths=[],tableHeaderConfigs=[],autoSize=(config=config||{}).autoSize||!1,printHeaders=!1!==config.printHeaders,fontSize=config.css&&void 0!==config.css["font-size"]?16*config.css["font-size"]:config.fontSize||12,margins=config.margins||Object.assign({width:this.getPageWidth()},NO_MARGINS),padding="number"==typeof config.padding?config.padding:3,headerBackgroundColor=config.headerBackgroundColor||"#c8c8c8",headerTextColor=config.headerTextColor||"#000";if(_reset.call(this),this.internal.__cell__.printHeaders=printHeaders,this.internal.__cell__.margins=margins,this.internal.__cell__.table_font_size=fontSize,this.internal.__cell__.padding=padding,this.internal.__cell__.headerBackgroundColor=headerBackgroundColor,this.internal.__cell__.headerTextColor=headerTextColor,this.setFontSize(fontSize),null==headers)headerLabels=headerNames=Object.keys(data[0]),headerAligns=headerNames.map((function(){return"left"}));else if(Array.isArray(headers)&&"object"===_typeof(headers[0]))for(headerNames=headers.map((function(header){return header.name})),headerLabels=headers.map((function(header){return header.prompt||header.name||""})),headerAligns=headers.map((function(header){return header.align||"left"})),i=0;i<headers.length;i+=1)columnWidths[headers[i].name]=.7499990551181103*headers[i].width;else Array.isArray(headers)&&"string"==typeof headers[0]&&(headerLabels=headerNames=headers,headerAligns=headerNames.map((function(){return"left"})));if(autoSize||Array.isArray(headers)&&"string"==typeof headers[0])for(i=0;i<headerNames.length;i+=1){for(columnMatrix[headerName=headerNames[i]]=data.map((function(rec){return rec[headerName]})),this.setFont(void 0,"bold"),columnMinWidths.push(this.getTextDimensions(headerLabels[i],{fontSize:this.internal.__cell__.table_font_size,scaleFactor:this.internal.scaleFactor}).w),column=columnMatrix[headerName],this.setFont(void 0,"normal"),j=0;j<column.length;j+=1)columnMinWidths.push(this.getTextDimensions(column[j],{fontSize:this.internal.__cell__.table_font_size,scaleFactor:this.internal.scaleFactor}).w);columnWidths[headerName]=Math.max.apply(null,columnMinWidths)+padding+padding,columnMinWidths=[]}if(printHeaders){var row={};for(i=0;i<headerNames.length;i+=1)row[headerNames[i]]={},row[headerNames[i]].text=headerLabels[i],row[headerNames[i]].align=headerAligns[i];var rowHeight=calculateLineHeight.call(this,row,columnWidths);tableHeaderConfigs=headerNames.map((function(value){return new Cell(x,y,columnWidths[value],rowHeight,row[value].text,void 0,row[value].align)})),this.setTableHeaderRow(tableHeaderConfigs),this.printHeaderRow(1,!1)}var align=headers.reduce((function(pv,cv){return pv[cv.name]=cv.align,pv}),{});for(i=0;i<data.length;i+=1){"rowStart"in config&&config.rowStart instanceof Function&&config.rowStart({row:i,data:data[i]},this);var lineHeight=calculateLineHeight.call(this,data[i],columnWidths);for(j=0;j<headerNames.length;j+=1){var cellData=data[i][headerNames[j]];"cellStart"in config&&config.cellStart instanceof Function&&config.cellStart({row:i,col:j,data:cellData},this),cell.call(this,new Cell(x,y,columnWidths[headerNames[j]],lineHeight,cellData,i+2,align[headerNames[j]]))}}return this.internal.__cell__.table_x=x,this.internal.__cell__.table_y=y,this};var calculateLineHeight=function(model,columnWidths){var padding=this.internal.__cell__.padding,fontSize=this.internal.__cell__.table_font_size,scaleFactor=this.internal.scaleFactor;return Object.keys(model).map((function(key){var value=model[key];return this.splitTextToSize(value.hasOwnProperty("text")?value.text:value,columnWidths[key]-padding-padding)}),this).map((function(value){return this.getLineHeightFactor()*value.length*fontSize/scaleFactor+padding+padding}),this).reduce((function(pv,cv){return Math.max(pv,cv)}),0)};jsPDFAPI.setTableHeaderRow=function(config){_initialize.call(this),this.internal.__cell__.tableHeaderRow=config},jsPDFAPI.printHeaderRow=function(lineNumber,new_page){if(_initialize.call(this),!this.internal.__cell__.tableHeaderRow)throw new Error("Property tableHeaderRow does not exist.");var tableHeaderCell;if(printingHeaderRow=!0,"function"==typeof this.internal.__cell__.headerFunction){var position=this.internal.__cell__.headerFunction(this,this.internal.__cell__.pages);this.internal.__cell__.lastCell=new Cell(position[0],position[1],position[2],position[3],void 0,-1)}this.setFont(void 0,"bold");for(var tempHeaderConf=[],i=0;i<this.internal.__cell__.tableHeaderRow.length;i+=1){tableHeaderCell=this.internal.__cell__.tableHeaderRow[i].clone(),new_page&&(tableHeaderCell.y=this.internal.__cell__.margins.top||0,tempHeaderConf.push(tableHeaderCell)),tableHeaderCell.lineNumber=lineNumber;var currentTextColor=this.getTextColor();this.setTextColor(this.internal.__cell__.headerTextColor),this.setFillColor(this.internal.__cell__.headerBackgroundColor),cell.call(this,tableHeaderCell),this.setTextColor(currentTextColor)}tempHeaderConf.length>0&&this.setTableHeaderRow(tempHeaderConf),this.setFont(void 0,"normal"),printingHeaderRow=!1}}(jsPDF.API);var fontStyleOrder={italic:["italic","oblique","normal"],oblique:["oblique","italic","normal"],normal:["normal","oblique","italic"]},fontStretchOrder=["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded"],fontStretchLookup=toLookup(fontStretchOrder),fontWeights=[100,200,300,400,500,600,700,800,900],fontWeightsLookup=toLookup(fontWeights);function normalizeFontFace(fontFace){var family=fontFace.family.replace(/"|'/g,"").toLowerCase(),style=function(style){return fontStyleOrder[style=style||"normal"]?style:"normal"}(fontFace.style),weight=function(weight){return weight?"number"==typeof weight?weight>=100&&weight<=900&&weight%100==0?weight:400:/^\d00$/.test(weight)?parseInt(weight):"bold"===weight?700:400:400}(fontFace.weight),stretch=function(stretch){return"number"==typeof fontStretchLookup[stretch=stretch||"normal"]?stretch:"normal"}(fontFace.stretch);return{family:family,style:style,weight:weight,stretch:stretch,src:fontFace.src||[],ref:fontFace.ref||{name:family,style:[stretch,style,weight].join(" ")}}}function searchFromPivot(matchingSet,order,pivot,dir){var i;for(i=pivot;i>=0&&i<order.length;i+=dir)if(matchingSet[order[i]])return matchingSet[order[i]];for(i=pivot;i>=0&&i<order.length;i-=dir)if(matchingSet[order[i]])return matchingSet[order[i]]}var defaultGenericFontFamilies={"sans-serif":"helvetica",fixed:"courier",monospace:"courier",terminal:"courier",cursive:"times",fantasy:"times",serif:"times"},systemFonts={caption:"times",icon:"times",menu:"times","message-box":"times","small-caption":"times","status-bar":"times"};function ruleToString(rule){return[rule.stretch,rule.style,rule.weight,rule.family].join(" ")}function resolveFontFace(fontFaceMap,rules,opts){for(var defaultFontFamily=(opts=opts||{}).defaultFontFamily||"times",genericFontFamilies=Object.assign({},defaultGenericFontFamilies,opts.genericFontFamilies||{}),rule=null,matches=null,i=0;i<rules.length;++i)if(genericFontFamilies[(rule=normalizeFontFace(rules[i])).family]&&(rule.family=genericFontFamilies[rule.family]),fontFaceMap.hasOwnProperty(rule.family)){matches=fontFaceMap[rule.family];break}if(!(matches=matches||fontFaceMap[defaultFontFamily]))throw new Error("Could not find a font-family for the rule '"+ruleToString(rule)+"' and default family '"+defaultFontFamily+"'.");if(matches=function(stretch,matchingSet){if(matchingSet[stretch])return matchingSet[stretch];var pivot=fontStretchLookup[stretch],dir=pivot<=fontStretchLookup.normal?-1:1,match=searchFromPivot(matchingSet,fontStretchOrder,pivot,dir);if(!match)throw new Error("Could not find a matching font-stretch value for "+stretch);return match}(rule.stretch,matches),matches=function(fontStyle,matchingSet){if(matchingSet[fontStyle])return matchingSet[fontStyle];for(var ordering=fontStyleOrder[fontStyle],i=0;i<ordering.length;++i)if(matchingSet[ordering[i]])return matchingSet[ordering[i]];throw new Error("Could not find a matching font-style for "+fontStyle)}(rule.style,matches),!(matches=function(weight,matchingSet){if(matchingSet[weight])return matchingSet[weight];if(400===weight&&matchingSet[500])return matchingSet[500];if(500===weight&&matchingSet[400])return matchingSet[400];var pivot=fontWeightsLookup[weight],match=searchFromPivot(matchingSet,fontWeights,pivot,weight<400?-1:1);if(!match)throw new Error("Could not find a matching font-weight for value "+weight);return match}(rule.weight,matches)))throw new Error("Failed to resolve a font for the rule '"+ruleToString(rule)+"'.");return matches}function eatWhiteSpace(input){return input.trimLeft()}function parseQuotedFontFamily(input,quote){for(var index=0;index<input.length;){if(input.charAt(index)===quote)return[input.substring(0,index),input.substring(index+1)];index+=1}return null}function parseNonQuotedFontFamily(input){var match=input.match(/^(-[a-z_]|[a-z_])[a-z0-9_-]*/i);return null===match?null:[match[0],input.substring(match[0].length)]}var defaultFont=["times"];!function(jsPDFAPI){var f2,getHorizontalCoordinateString,getVerticalCoordinateString,getHorizontalCoordinate,getVerticalCoordinate,Point,Rectangle,Matrix,_ctx,ContextLayer=function(ctx){return ctx=ctx||{},this.isStrokeTransparent=ctx.isStrokeTransparent||!1,this.strokeOpacity=ctx.strokeOpacity||1,this.strokeStyle=ctx.strokeStyle||"#000000",this.fillStyle=ctx.fillStyle||"#000000",this.isFillTransparent=ctx.isFillTransparent||!1,this.fillOpacity=ctx.fillOpacity||1,this.font=ctx.font||"10px sans-serif",this.textBaseline=ctx.textBaseline||"alphabetic",this.textAlign=ctx.textAlign||"left",this.lineWidth=ctx.lineWidth||1,this.lineJoin=ctx.lineJoin||"miter",this.lineCap=ctx.lineCap||"butt",this.path=ctx.path||[],this.transform=void 0!==ctx.transform?ctx.transform.clone():new Matrix,this.globalCompositeOperation=ctx.globalCompositeOperation||"normal",this.globalAlpha=ctx.globalAlpha||1,this.clip_path=ctx.clip_path||[],this.currentPoint=ctx.currentPoint||new Point,this.miterLimit=ctx.miterLimit||10,this.lastPoint=ctx.lastPoint||new Point,this.lineDashOffset=ctx.lineDashOffset||0,this.lineDash=ctx.lineDash||[],this.margin=ctx.margin||[0,0,0,0],this.prevPageLastElemOffset=ctx.prevPageLastElemOffset||0,this.ignoreClearRect="boolean"!=typeof ctx.ignoreClearRect||ctx.ignoreClearRect,this};jsPDFAPI.events.push(["initialized",function(){this.context2d=new Context2D(this),f2=this.internal.f2,getHorizontalCoordinateString=this.internal.getCoordinateString,getVerticalCoordinateString=this.internal.getVerticalCoordinateString,getHorizontalCoordinate=this.internal.getHorizontalCoordinate,getVerticalCoordinate=this.internal.getVerticalCoordinate,Point=this.internal.Point,Rectangle=this.internal.Rectangle,Matrix=this.internal.Matrix,_ctx=new ContextLayer}]);var Context2D=function(pdf){Object.defineProperty(this,"canvas",{get:function(){return{parentNode:!1,style:!1}}});var _pdf=pdf;Object.defineProperty(this,"pdf",{get:function(){return _pdf}});var _pageWrapXEnabled=!1;Object.defineProperty(this,"pageWrapXEnabled",{get:function(){return _pageWrapXEnabled},set:function(value){_pageWrapXEnabled=Boolean(value)}});var _pageWrapYEnabled=!1;Object.defineProperty(this,"pageWrapYEnabled",{get:function(){return _pageWrapYEnabled},set:function(value){_pageWrapYEnabled=Boolean(value)}});var _posX=0;Object.defineProperty(this,"posX",{get:function(){return _posX},set:function(value){isNaN(value)||(_posX=value)}});var _posY=0;Object.defineProperty(this,"posY",{get:function(){return _posY},set:function(value){isNaN(value)||(_posY=value)}}),Object.defineProperty(this,"margin",{get:function(){return _ctx.margin},set:function(value){var margin;"number"==typeof value?margin=[value,value,value,value]:((margin=new Array(4))[0]=value[0],margin[1]=value.length>=2?value[1]:margin[0],margin[2]=value.length>=3?value[2]:margin[0],margin[3]=value.length>=4?value[3]:margin[1]),_ctx.margin=margin}});var _autoPaging=!1;Object.defineProperty(this,"autoPaging",{get:function(){return _autoPaging},set:function(value){_autoPaging=value}});var lastBreak=0;Object.defineProperty(this,"lastBreak",{get:function(){return lastBreak},set:function(value){lastBreak=value}});var pageBreaks=[];Object.defineProperty(this,"pageBreaks",{get:function(){return pageBreaks},set:function(value){pageBreaks=value}}),Object.defineProperty(this,"ctx",{get:function(){return _ctx},set:function(value){value instanceof ContextLayer&&(_ctx=value)}}),Object.defineProperty(this,"path",{get:function(){return _ctx.path},set:function(value){_ctx.path=value}});var _ctxStack=[];Object.defineProperty(this,"ctxStack",{get:function(){return _ctxStack},set:function(value){_ctxStack=value}}),Object.defineProperty(this,"fillStyle",{get:function(){return this.ctx.fillStyle},set:function(value){var rgba;rgba=getRGBA(value),this.ctx.fillStyle=rgba.style,this.ctx.isFillTransparent=0===rgba.a,this.ctx.fillOpacity=rgba.a,this.pdf.setFillColor(rgba.r,rgba.g,rgba.b,{a:rgba.a}),this.pdf.setTextColor(rgba.r,rgba.g,rgba.b,{a:rgba.a})}}),Object.defineProperty(this,"strokeStyle",{get:function(){return this.ctx.strokeStyle},set:function(value){var rgba=getRGBA(value);this.ctx.strokeStyle=rgba.style,this.ctx.isStrokeTransparent=0===rgba.a,this.ctx.strokeOpacity=rgba.a,0===rgba.a?this.pdf.setDrawColor(255,255,255):(rgba.a,this.pdf.setDrawColor(rgba.r,rgba.g,rgba.b))}}),Object.defineProperty(this,"lineCap",{get:function(){return this.ctx.lineCap},set:function(value){-1!==["butt","round","square"].indexOf(value)&&(this.ctx.lineCap=value,this.pdf.setLineCap(value))}}),Object.defineProperty(this,"lineWidth",{get:function(){return this.ctx.lineWidth},set:function(value){isNaN(value)||(this.ctx.lineWidth=value,this.pdf.setLineWidth(value))}}),Object.defineProperty(this,"lineJoin",{get:function(){return this.ctx.lineJoin},set:function(value){-1!==["bevel","round","miter"].indexOf(value)&&(this.ctx.lineJoin=value,this.pdf.setLineJoin(value))}}),Object.defineProperty(this,"miterLimit",{get:function(){return this.ctx.miterLimit},set:function(value){isNaN(value)||(this.ctx.miterLimit=value,this.pdf.setMiterLimit(value))}}),Object.defineProperty(this,"textBaseline",{get:function(){return this.ctx.textBaseline},set:function(value){this.ctx.textBaseline=value}}),Object.defineProperty(this,"textAlign",{get:function(){return this.ctx.textAlign},set:function(value){-1!==["right","end","center","left","start"].indexOf(value)&&(this.ctx.textAlign=value)}});var _fontFaceMap=null;function getFontFaceMap(pdf,fontFaces){if(null===_fontFaceMap){var convertedFontFaces=function(fontMap){var fontFaces=[];return Object.keys(fontMap).forEach((function(family){fontMap[family].forEach((function(style){var fontFace=null;switch(style){case"bold":fontFace={family:family,weight:"bold"};break;case"italic":fontFace={family:family,style:"italic"};break;case"bolditalic":fontFace={family:family,weight:"bold",style:"italic"};break;case"":case"normal":fontFace={family:family}}null!==fontFace&&(fontFace.ref={name:family,style:style},fontFaces.push(fontFace))}))})),fontFaces}(pdf.getFontList());_fontFaceMap=function(fontFaces){for(var map={},i=0;i<fontFaces.length;++i){var normalized=normalizeFontFace(fontFaces[i]),name=normalized.family,stretch=normalized.stretch,style=normalized.style,weight=normalized.weight;map[name]=map[name]||{},map[name][stretch]=map[name][stretch]||{},map[name][stretch][style]=map[name][stretch][style]||{},map[name][stretch][style][weight]=normalized}return map}(convertedFontFaces.concat(fontFaces))}return _fontFaceMap}var _fontFaces=null;Object.defineProperty(this,"fontFaces",{get:function(){return _fontFaces},set:function(value){_fontFaceMap=null,_fontFaces=value}}),Object.defineProperty(this,"font",{get:function(){return this.ctx.font},set:function(value){var matches;if(this.ctx.font=value,null!==(matches=/^\s*(?=(?:(?:[-a-z]+\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\1|\2|\3)\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\d]+(?:\%|in|[cem]m|ex|p[ctx]))(?:\s*\/\s*(normal|[.\d]+(?:\%|in|[cem]m|ex|p[ctx])))?\s*([-_,\"\'\sa-z]+?)\s*$/i.exec(value))){var fontStyle=matches[1],fontWeight=(matches[2],matches[3]),fontSize=matches[4],fontFamily=(matches[5],matches[6]),fontSizeUnit=/^([.\d]+)((?:%|in|[cem]m|ex|p[ctx]))$/i.exec(fontSize)[2];fontSize="px"===fontSizeUnit?Math.floor(parseFloat(fontSize)*this.pdf.internal.scaleFactor):"em"===fontSizeUnit?Math.floor(parseFloat(fontSize)*this.pdf.getFontSize()):Math.floor(parseFloat(fontSize)*this.pdf.internal.scaleFactor),this.pdf.setFontSize(fontSize);var parts=function(input){var ch,parsed,result=[],remaining=input.trim();if(""===remaining)return defaultFont;if(remaining in systemFonts)return[systemFonts[remaining]];for(;""!==remaining;){switch(parsed=null,ch=(remaining=eatWhiteSpace(remaining)).charAt(0)){case'"':case"'":parsed=parseQuotedFontFamily(remaining.substring(1),ch);break;default:parsed=parseNonQuotedFontFamily(remaining)}if(null===parsed)return defaultFont;if(result.push(parsed[0]),""!==(remaining=eatWhiteSpace(parsed[1]))&&","!==remaining.charAt(0))return defaultFont;remaining=remaining.replace(/^,/,"")}return result}(fontFamily);if(this.fontFaces){var fontFaceMap=getFontFaceMap(this.pdf,this.fontFaces),rules=parts.map((function(ff){return{family:ff,stretch:"normal",weight:fontWeight,style:fontStyle}})),font=resolveFontFace(fontFaceMap,rules);this.pdf.setFont(font.ref.name,font.ref.style)}else{var style="";("bold"===fontWeight||parseInt(fontWeight,10)>=700||"bold"===fontStyle)&&(style="bold"),"italic"===fontStyle&&(style+="italic"),0===style.length&&(style="normal");for(var jsPdfFontName="",fallbackFonts={arial:"Helvetica",Arial:"Helvetica",verdana:"Helvetica",Verdana:"Helvetica",helvetica:"Helvetica",Helvetica:"Helvetica","sans-serif":"Helvetica",fixed:"Courier",monospace:"Courier",terminal:"Courier",cursive:"Times",fantasy:"Times",serif:"Times"},i=0;i<parts.length;i++){if(void 0!==this.pdf.internal.getFont(parts[i],style,{noFallback:!0,disableWarning:!0})){jsPdfFontName=parts[i];break}if("bolditalic"===style&&void 0!==this.pdf.internal.getFont(parts[i],"bold",{noFallback:!0,disableWarning:!0}))jsPdfFontName=parts[i],style="bold";else if(void 0!==this.pdf.internal.getFont(parts[i],"normal",{noFallback:!0,disableWarning:!0})){jsPdfFontName=parts[i],style="normal";break}}if(""===jsPdfFontName)for(var j=0;j<parts.length;j++)if(fallbackFonts[parts[j]]){jsPdfFontName=fallbackFonts[parts[j]];break}jsPdfFontName=""===jsPdfFontName?"Times":jsPdfFontName,this.pdf.setFont(jsPdfFontName,style)}}}}),Object.defineProperty(this,"globalCompositeOperation",{get:function(){return this.ctx.globalCompositeOperation},set:function(value){this.ctx.globalCompositeOperation=value}}),Object.defineProperty(this,"globalAlpha",{get:function(){return this.ctx.globalAlpha},set:function(value){this.ctx.globalAlpha=value}}),Object.defineProperty(this,"lineDashOffset",{get:function(){return this.ctx.lineDashOffset},set:function(value){this.ctx.lineDashOffset=value,setLineDash.call(this)}}),Object.defineProperty(this,"lineDash",{get:function(){return this.ctx.lineDash},set:function(value){this.ctx.lineDash=value,setLineDash.call(this)}}),Object.defineProperty(this,"ignoreClearRect",{get:function(){return this.ctx.ignoreClearRect},set:function(value){this.ctx.ignoreClearRect=Boolean(value)}})};Context2D.prototype.setLineDash=function(dashArray){this.lineDash=dashArray},Context2D.prototype.getLineDash=function(){return this.lineDash.length%2?this.lineDash.concat(this.lineDash):this.lineDash.slice()},Context2D.prototype.fill=function(){pathPreProcess.call(this,"fill",!1)},Context2D.prototype.stroke=function(){pathPreProcess.call(this,"stroke",!1)},Context2D.prototype.beginPath=function(){this.path=[{type:"begin"}]},Context2D.prototype.moveTo=function(x,y){if(isNaN(x)||isNaN(y))throw console.error("jsPDF.context2d.moveTo: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.moveTo");var pt=this.ctx.transform.applyToPoint(new Point(x,y));this.path.push({type:"mt",x:pt.x,y:pt.y}),this.ctx.lastPoint=new Point(x,y)},Context2D.prototype.closePath=function(){var pathBegin=new Point(0,0),i=0;for(i=this.path.length-1;-1!==i;i--)if("begin"===this.path[i].type&&"object"===_typeof(this.path[i+1])&&"number"==typeof this.path[i+1].x){pathBegin=new Point(this.path[i+1].x,this.path[i+1].y);break}this.path.push({type:"close"}),this.ctx.lastPoint=new Point(pathBegin.x,pathBegin.y)},Context2D.prototype.lineTo=function(x,y){if(isNaN(x)||isNaN(y))throw console.error("jsPDF.context2d.lineTo: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.lineTo");var pt=this.ctx.transform.applyToPoint(new Point(x,y));this.path.push({type:"lt",x:pt.x,y:pt.y}),this.ctx.lastPoint=new Point(pt.x,pt.y)},Context2D.prototype.clip=function(){this.ctx.clip_path=JSON.parse(JSON.stringify(this.path)),pathPreProcess.call(this,null,!0)},Context2D.prototype.quadraticCurveTo=function(cpx,cpy,x,y){if(isNaN(x)||isNaN(y)||isNaN(cpx)||isNaN(cpy))throw console.error("jsPDF.context2d.quadraticCurveTo: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.quadraticCurveTo");var pt0=this.ctx.transform.applyToPoint(new Point(x,y)),pt1=this.ctx.transform.applyToPoint(new Point(cpx,cpy));this.path.push({type:"qct",x1:pt1.x,y1:pt1.y,x:pt0.x,y:pt0.y}),this.ctx.lastPoint=new Point(pt0.x,pt0.y)},Context2D.prototype.bezierCurveTo=function(cp1x,cp1y,cp2x,cp2y,x,y){if(isNaN(x)||isNaN(y)||isNaN(cp1x)||isNaN(cp1y)||isNaN(cp2x)||isNaN(cp2y))throw console.error("jsPDF.context2d.bezierCurveTo: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.bezierCurveTo");var pt0=this.ctx.transform.applyToPoint(new Point(x,y)),pt1=this.ctx.transform.applyToPoint(new Point(cp1x,cp1y)),pt2=this.ctx.transform.applyToPoint(new Point(cp2x,cp2y));this.path.push({type:"bct",x1:pt1.x,y1:pt1.y,x2:pt2.x,y2:pt2.y,x:pt0.x,y:pt0.y}),this.ctx.lastPoint=new Point(pt0.x,pt0.y)},Context2D.prototype.arc=function(x,y,radius,startAngle,endAngle,counterclockwise){if(isNaN(x)||isNaN(y)||isNaN(radius)||isNaN(startAngle)||isNaN(endAngle))throw console.error("jsPDF.context2d.arc: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.arc");if(counterclockwise=Boolean(counterclockwise),!this.ctx.transform.isIdentity){var xpt=this.ctx.transform.applyToPoint(new Point(x,y));x=xpt.x,y=xpt.y;var x_radPt=this.ctx.transform.applyToPoint(new Point(0,radius)),x_radPt0=this.ctx.transform.applyToPoint(new Point(0,0));radius=Math.sqrt(Math.pow(x_radPt.x-x_radPt0.x,2)+Math.pow(x_radPt.y-x_radPt0.y,2))}Math.abs(endAngle-startAngle)>=2*Math.PI&&(startAngle=0,endAngle=2*Math.PI),this.path.push({type:"arc",x:x,y:y,radius:radius,startAngle:startAngle,endAngle:endAngle,counterclockwise:counterclockwise})},Context2D.prototype.arcTo=function(x1,y1,x2,y2,radius){throw new Error("arcTo not implemented.")},Context2D.prototype.rect=function(x,y,w,h){if(isNaN(x)||isNaN(y)||isNaN(w)||isNaN(h))throw console.error("jsPDF.context2d.rect: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.rect");this.moveTo(x,y),this.lineTo(x+w,y),this.lineTo(x+w,y+h),this.lineTo(x,y+h),this.lineTo(x,y),this.lineTo(x+w,y),this.lineTo(x,y)},Context2D.prototype.fillRect=function(x,y,w,h){if(isNaN(x)||isNaN(y)||isNaN(w)||isNaN(h))throw console.error("jsPDF.context2d.fillRect: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.fillRect");if(!isFillTransparent.call(this)){var tmp={};"butt"!==this.lineCap&&(tmp.lineCap=this.lineCap,this.lineCap="butt"),"miter"!==this.lineJoin&&(tmp.lineJoin=this.lineJoin,this.lineJoin="miter"),this.beginPath(),this.rect(x,y,w,h),this.fill(),tmp.hasOwnProperty("lineCap")&&(this.lineCap=tmp.lineCap),tmp.hasOwnProperty("lineJoin")&&(this.lineJoin=tmp.lineJoin)}},Context2D.prototype.strokeRect=function(x,y,w,h){if(isNaN(x)||isNaN(y)||isNaN(w)||isNaN(h))throw console.error("jsPDF.context2d.strokeRect: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.strokeRect");isStrokeTransparent.call(this)||(this.beginPath(),this.rect(x,y,w,h),this.stroke())},Context2D.prototype.clearRect=function(x,y,w,h){if(isNaN(x)||isNaN(y)||isNaN(w)||isNaN(h))throw console.error("jsPDF.context2d.clearRect: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.clearRect");this.ignoreClearRect||(this.fillStyle="#ffffff",this.fillRect(x,y,w,h))},Context2D.prototype.save=function(doStackPush){doStackPush="boolean"!=typeof doStackPush||doStackPush;for(var tmpPageNumber=this.pdf.internal.getCurrentPageInfo().pageNumber,i=0;i<this.pdf.internal.getNumberOfPages();i++)this.pdf.setPage(i+1),this.pdf.internal.out("q");if(this.pdf.setPage(tmpPageNumber),doStackPush){this.ctx.fontSize=this.pdf.internal.getFontSize();var ctx=new ContextLayer(this.ctx);this.ctxStack.push(this.ctx),this.ctx=ctx}},Context2D.prototype.restore=function(doStackPop){doStackPop="boolean"!=typeof doStackPop||doStackPop;for(var tmpPageNumber=this.pdf.internal.getCurrentPageInfo().pageNumber,i=0;i<this.pdf.internal.getNumberOfPages();i++)this.pdf.setPage(i+1),this.pdf.internal.out("Q");this.pdf.setPage(tmpPageNumber),doStackPop&&0!==this.ctxStack.length&&(this.ctx=this.ctxStack.pop(),this.fillStyle=this.ctx.fillStyle,this.strokeStyle=this.ctx.strokeStyle,this.font=this.ctx.font,this.lineCap=this.ctx.lineCap,this.lineWidth=this.ctx.lineWidth,this.lineJoin=this.ctx.lineJoin,this.lineDash=this.ctx.lineDash,this.lineDashOffset=this.ctx.lineDashOffset)},Context2D.prototype.toDataURL=function(){throw new Error("toDataUrl not implemented.")};var getRGBA=function(style){var r,g,b,a;if(!0===style.isCanvasGradient&&(style=style.getColor()),!style)return{r:0,g:0,b:0,a:0,style:style};if(/transparent|rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*0+\s*\)/.test(style))r=0,g=0,b=0,a=0;else{var matches=/rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/.exec(style);if(null!==matches)r=parseInt(matches[1]),g=parseInt(matches[2]),b=parseInt(matches[3]),a=1;else if(null!==(matches=/rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/.exec(style)))r=parseInt(matches[1]),g=parseInt(matches[2]),b=parseInt(matches[3]),a=parseFloat(matches[4]);else{if(a=1,"string"==typeof style&&"#"!==style.charAt(0)){var rgbColor=new RGBColor(style);style=rgbColor.ok?rgbColor.toHex():"#000000"}4===style.length?(r=style.substring(1,2),r+=r,g=style.substring(2,3),g+=g,b=style.substring(3,4),b+=b):(r=style.substring(1,3),g=style.substring(3,5),b=style.substring(5,7)),r=parseInt(r,16),g=parseInt(g,16),b=parseInt(b,16)}}return{r:r,g:g,b:b,a:a,style:style}},isFillTransparent=function(){return this.ctx.isFillTransparent||0==this.globalAlpha},isStrokeTransparent=function(){return Boolean(this.ctx.isStrokeTransparent||0==this.globalAlpha)};Context2D.prototype.fillText=function(text,x,y,maxWidth){if(isNaN(x)||isNaN(y)||"string"!=typeof text)throw console.error("jsPDF.context2d.fillText: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.fillText");if(maxWidth=isNaN(maxWidth)?void 0:maxWidth,!isFillTransparent.call(this)){var degs=rad2deg(this.ctx.transform.rotation),scale=this.ctx.transform.scaleX;putText.call(this,{text:text,x:x,y:y,scale:scale,angle:degs,align:this.textAlign,maxWidth:maxWidth})}},Context2D.prototype.strokeText=function(text,x,y,maxWidth){if(isNaN(x)||isNaN(y)||"string"!=typeof text)throw console.error("jsPDF.context2d.strokeText: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.strokeText");if(!isStrokeTransparent.call(this)){maxWidth=isNaN(maxWidth)?void 0:maxWidth;var degs=rad2deg(this.ctx.transform.rotation),scale=this.ctx.transform.scaleX;putText.call(this,{text:text,x:x,y:y,scale:scale,renderingMode:"stroke",angle:degs,align:this.textAlign,maxWidth:maxWidth})}},Context2D.prototype.measureText=function(text){if("string"!=typeof text)throw console.error("jsPDF.context2d.measureText: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.measureText");var pdf=this.pdf,k=this.pdf.internal.scaleFactor,fontSize=pdf.internal.getFontSize(),txtWidth=pdf.getStringUnitWidth(text)*fontSize/pdf.internal.scaleFactor,TextMetrics=function(options){var _width=(options=options||{}).width||0;return Object.defineProperty(this,"width",{get:function(){return _width}}),this};return new TextMetrics({width:txtWidth*=Math.round(96*k/72*1e4)/1e4})},Context2D.prototype.scale=function(scalewidth,scaleheight){if(isNaN(scalewidth)||isNaN(scaleheight))throw console.error("jsPDF.context2d.scale: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.scale");var matrix=new Matrix(scalewidth,0,0,scaleheight,0,0);this.ctx.transform=this.ctx.transform.multiply(matrix)},Context2D.prototype.rotate=function(angle){if(isNaN(angle))throw console.error("jsPDF.context2d.rotate: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.rotate");var matrix=new Matrix(Math.cos(angle),Math.sin(angle),-Math.sin(angle),Math.cos(angle),0,0);this.ctx.transform=this.ctx.transform.multiply(matrix)},Context2D.prototype.translate=function(x,y){if(isNaN(x)||isNaN(y))throw console.error("jsPDF.context2d.translate: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.translate");var matrix=new Matrix(1,0,0,1,x,y);this.ctx.transform=this.ctx.transform.multiply(matrix)},Context2D.prototype.transform=function(a,b,c,d,e,f){if(isNaN(a)||isNaN(b)||isNaN(c)||isNaN(d)||isNaN(e)||isNaN(f))throw console.error("jsPDF.context2d.transform: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.transform");var matrix=new Matrix(a,b,c,d,e,f);this.ctx.transform=this.ctx.transform.multiply(matrix)},Context2D.prototype.setTransform=function(a,b,c,d,e,f){a=isNaN(a)?1:a,b=isNaN(b)?0:b,c=isNaN(c)?0:c,d=isNaN(d)?1:d,e=isNaN(e)?0:e,f=isNaN(f)?0:f,this.ctx.transform=new Matrix(a,b,c,d,e,f)};var hasMargins=function(){return this.margin[0]>0||this.margin[1]>0||this.margin[2]>0||this.margin[3]>0};Context2D.prototype.drawImage=function(img,sx,sy,swidth,sheight,x,y,width,height){var imageProperties=this.pdf.getImageProperties(img),factorX=1,factorY=1,clipFactorX=1,clipFactorY=1;void 0!==swidth&&void 0!==width&&(clipFactorX=width/swidth,clipFactorY=height/sheight,factorX=imageProperties.width/swidth*width/swidth,factorY=imageProperties.height/sheight*height/sheight),void 0===x&&(x=sx,y=sy,sx=0,sy=0),void 0!==swidth&&void 0===width&&(width=swidth,height=sheight),void 0===swidth&&void 0===width&&(width=imageProperties.width,height=imageProperties.height);for(var clipPath,decomposedTransformationMatrix=this.ctx.transform.decompose(),angle=rad2deg(decomposedTransformationMatrix.rotate.shx),matrix=new Matrix,xRect=(matrix=(matrix=(matrix=matrix.multiply(decomposedTransformationMatrix.translate)).multiply(decomposedTransformationMatrix.skew)).multiply(decomposedTransformationMatrix.scale)).applyToRectangle(new Rectangle(x-sx*clipFactorX,y-sy*clipFactorY,swidth*factorX,sheight*factorY)),pageArray=getPagesByPath.call(this,xRect),pages=[],ii=0;ii<pageArray.length;ii+=1)-1===pages.indexOf(pageArray[ii])&&pages.push(pageArray[ii]);if(sortPages(pages),this.autoPaging)for(var min=pages[0],max=pages[pages.length-1],i=min;i<max+1;i++){this.pdf.setPage(i);var pageWidthMinusMargins=this.pdf.internal.pageSize.width-this.margin[3]-this.margin[1],topMargin=1===i?this.posY+this.margin[0]:this.margin[0],firstPageHeight=this.pdf.internal.pageSize.height-this.posY-this.margin[0]-this.margin[2],pageHeightMinusMargins=this.pdf.internal.pageSize.height-this.margin[0]-this.margin[2],previousPageHeightSum=1===i?0:firstPageHeight+(i-2)*pageHeightMinusMargins;if(0!==this.ctx.clip_path.length){var tmpPaths=this.path;clipPath=JSON.parse(JSON.stringify(this.ctx.clip_path)),this.path=pathPositionRedo(clipPath,this.posX+this.margin[3],-previousPageHeightSum+topMargin+this.ctx.prevPageLastElemOffset),drawPaths.call(this,"fill",!0),this.path=tmpPaths}var tmpRect=JSON.parse(JSON.stringify(xRect));tmpRect=pathPositionRedo([tmpRect],this.posX+this.margin[3],-previousPageHeightSum+topMargin+this.ctx.prevPageLastElemOffset)[0];var needsClipping=(i>min||i<max)&&hasMargins.call(this);needsClipping&&(this.pdf.saveGraphicsState(),this.pdf.rect(this.margin[3],this.margin[0],pageWidthMinusMargins,pageHeightMinusMargins,null).clip().discardPath()),this.pdf.addImage(img,"JPEG",tmpRect.x,tmpRect.y,tmpRect.w,tmpRect.h,null,null,angle),needsClipping&&this.pdf.restoreGraphicsState()}else this.pdf.addImage(img,"JPEG",xRect.x,xRect.y,xRect.w,xRect.h,null,null,angle)};var getPagesByPath=function(path,pageWrapX,pageWrapY){var result=[];pageWrapX=pageWrapX||this.pdf.internal.pageSize.width,pageWrapY=pageWrapY||this.pdf.internal.pageSize.height-this.margin[0]-this.margin[2];var yOffset=this.posY+this.ctx.prevPageLastElemOffset;switch(path.type){default:case"mt":case"lt":result.push(Math.floor((path.y+yOffset)/pageWrapY)+1);break;case"arc":result.push(Math.floor((path.y+yOffset-path.radius)/pageWrapY)+1),result.push(Math.floor((path.y+yOffset+path.radius)/pageWrapY)+1);break;case"qct":var rectOfQuadraticCurve=getQuadraticCurveBoundary(this.ctx.lastPoint.x,this.ctx.lastPoint.y,path.x1,path.y1,path.x,path.y);result.push(Math.floor((rectOfQuadraticCurve.y+yOffset)/pageWrapY)+1),result.push(Math.floor((rectOfQuadraticCurve.y+rectOfQuadraticCurve.h+yOffset)/pageWrapY)+1);break;case"bct":var rectOfBezierCurve=getBezierCurveBoundary(this.ctx.lastPoint.x,this.ctx.lastPoint.y,path.x1,path.y1,path.x2,path.y2,path.x,path.y);result.push(Math.floor((rectOfBezierCurve.y+yOffset)/pageWrapY)+1),result.push(Math.floor((rectOfBezierCurve.y+rectOfBezierCurve.h+yOffset)/pageWrapY)+1);break;case"rect":result.push(Math.floor((path.y+yOffset)/pageWrapY)+1),result.push(Math.floor((path.y+path.h+yOffset)/pageWrapY)+1)}for(var i=0;i<result.length;i+=1)for(;this.pdf.internal.getNumberOfPages()<result[i];)addPage.call(this);return result},addPage=function(){var fillStyle=this.fillStyle,strokeStyle=this.strokeStyle,font=this.font,lineCap=this.lineCap,lineWidth=this.lineWidth,lineJoin=this.lineJoin;this.pdf.addPage(),this.fillStyle=fillStyle,this.strokeStyle=strokeStyle,this.font=font,this.lineCap=lineCap,this.lineWidth=lineWidth,this.lineJoin=lineJoin},pathPositionRedo=function(paths,x,y){for(var i=0;i<paths.length;i++)switch(paths[i].type){case"bct":paths[i].x2+=x,paths[i].y2+=y;case"qct":paths[i].x1+=x,paths[i].y1+=y;default:paths[i].x+=x,paths[i].y+=y}return paths},sortPages=function(pages){return pages.sort((function(a,b){return a-b}))},pathPreProcess=function(rule,isClip){for(var clipPath,tmpPath,fillStyle=this.fillStyle,strokeStyle=this.strokeStyle,lineCap=this.lineCap,oldLineWidth=this.lineWidth,lineWidth=Math.abs(oldLineWidth*this.ctx.transform.scaleX),lineJoin=this.lineJoin,origPath=JSON.parse(JSON.stringify(this.path)),xPath=JSON.parse(JSON.stringify(this.path)),pages=[],i=0;i<xPath.length;i++)if(void 0!==xPath[i].x)for(var page=getPagesByPath.call(this,xPath[i]),ii=0;ii<page.length;ii+=1)-1===pages.indexOf(page[ii])&&pages.push(page[ii]);for(var j=0;j<pages.length;j++)for(;this.pdf.internal.getNumberOfPages()<pages[j];)addPage.call(this);if(sortPages(pages),this.autoPaging)for(var min=pages[0],max=pages[pages.length-1],k=min;k<max+1;k++){this.pdf.setPage(k),this.fillStyle=fillStyle,this.strokeStyle=strokeStyle,this.lineCap=lineCap,this.lineWidth=lineWidth,this.lineJoin=lineJoin;var pageWidthMinusMargins=this.pdf.internal.pageSize.width-this.margin[3]-this.margin[1],topMargin=1===k?this.posY+this.margin[0]:this.margin[0],firstPageHeight=this.pdf.internal.pageSize.height-this.posY-this.margin[0]-this.margin[2],pageHeightMinusMargins=this.pdf.internal.pageSize.height-this.margin[0]-this.margin[2],previousPageHeightSum=1===k?0:firstPageHeight+(k-2)*pageHeightMinusMargins;if(0!==this.ctx.clip_path.length){var tmpPaths=this.path;clipPath=JSON.parse(JSON.stringify(this.ctx.clip_path)),this.path=pathPositionRedo(clipPath,this.posX+this.margin[3],-previousPageHeightSum+topMargin+this.ctx.prevPageLastElemOffset),drawPaths.call(this,rule,!0),this.path=tmpPaths}if(tmpPath=JSON.parse(JSON.stringify(origPath)),this.path=pathPositionRedo(tmpPath,this.posX+this.margin[3],-previousPageHeightSum+topMargin+this.ctx.prevPageLastElemOffset),!1===isClip||0===k){var needsClipping=(k>min||k<max)&&hasMargins.call(this);needsClipping&&(this.pdf.saveGraphicsState(),this.pdf.rect(this.margin[3],this.margin[0],pageWidthMinusMargins,pageHeightMinusMargins,null).clip().discardPath()),drawPaths.call(this,rule,isClip),needsClipping&&this.pdf.restoreGraphicsState()}this.lineWidth=oldLineWidth}else this.lineWidth=lineWidth,drawPaths.call(this,rule,isClip),this.lineWidth=oldLineWidth;this.path=origPath},drawPaths=function(rule,isClip){if(("stroke"!==rule||isClip||!isStrokeTransparent.call(this))&&("stroke"===rule||isClip||!isFillTransparent.call(this))){for(var delta,style,moves=[],xPath=this.path,i=0;i<xPath.length;i++){var pt=xPath[i];switch(pt.type){case"begin":moves.push({begin:!0});break;case"close":moves.push({close:!0});break;case"mt":moves.push({start:pt,deltas:[],abs:[]});break;case"lt":var iii=moves.length;if(xPath[i-1]&&!isNaN(xPath[i-1].x)&&(delta=[pt.x-xPath[i-1].x,pt.y-xPath[i-1].y],iii>0))for(;iii>=0;iii--)if(!0!==moves[iii-1].close&&!0!==moves[iii-1].begin){moves[iii-1].deltas.push(delta),moves[iii-1].abs.push(pt);break}break;case"bct":delta=[pt.x1-xPath[i-1].x,pt.y1-xPath[i-1].y,pt.x2-xPath[i-1].x,pt.y2-xPath[i-1].y,pt.x-xPath[i-1].x,pt.y-xPath[i-1].y],moves[moves.length-1].deltas.push(delta);break;case"qct":var x1=xPath[i-1].x+2/3*(pt.x1-xPath[i-1].x),y1=xPath[i-1].y+2/3*(pt.y1-xPath[i-1].y),x2=pt.x+2/3*(pt.x1-pt.x),y2=pt.y+2/3*(pt.y1-pt.y),x3=pt.x,y3=pt.y;delta=[x1-xPath[i-1].x,y1-xPath[i-1].y,x2-xPath[i-1].x,y2-xPath[i-1].y,x3-xPath[i-1].x,y3-xPath[i-1].y],moves[moves.length-1].deltas.push(delta);break;case"arc":moves.push({deltas:[],abs:[],arc:!0}),Array.isArray(moves[moves.length-1].abs)&&moves[moves.length-1].abs.push(pt)}}style=isClip?null:"stroke"===rule?"stroke":"fill";for(var began=!1,k=0;k<moves.length;k++)if(moves[k].arc)for(var arcs=moves[k].abs,ii=0;ii<arcs.length;ii++){var arc=arcs[ii];"arc"===arc.type?drawArc.call(this,arc.x,arc.y,arc.radius,arc.startAngle,arc.endAngle,arc.counterclockwise,void 0,isClip,!began):drawLine.call(this,arc.x,arc.y),began=!0}else if(!0===moves[k].close)this.pdf.internal.out("h"),began=!1;else if(!0!==moves[k].begin){var x=moves[k].start.x,y=moves[k].start.y;drawLines.call(this,moves[k].deltas,x,y),began=!0}style&&putStyle.call(this,style),isClip&&doClip.call(this)}},getBaseline=function(y){var height=this.pdf.internal.getFontSize()/this.pdf.internal.scaleFactor,descent=height*(this.pdf.internal.getLineHeightFactor()-1);switch(this.ctx.textBaseline){case"bottom":return y-descent;case"top":return y+height-descent;case"hanging":return y+height-2*descent;case"middle":return y+height/2-descent;default:return y}},getTextBottom=function(yBaseLine){return yBaseLine+this.pdf.internal.getFontSize()/this.pdf.internal.scaleFactor*(this.pdf.internal.getLineHeightFactor()-1)};Context2D.prototype.createLinearGradient=function(){var canvasGradient=function(){};return canvasGradient.colorStops=[],canvasGradient.addColorStop=function(offset,color){this.colorStops.push([offset,color])},canvasGradient.getColor=function(){return 0===this.colorStops.length?"#000000":this.colorStops[0][1]},canvasGradient.isCanvasGradient=!0,canvasGradient},Context2D.prototype.createPattern=function(){return this.createLinearGradient()},Context2D.prototype.createRadialGradient=function(){return this.createLinearGradient()};var drawArc=function(x,y,r,a1,a2,counterclockwise,style,isClip,includeMove){for(var curves=createArc.call(this,r,a1,a2,counterclockwise),i=0;i<curves.length;i++){var curve=curves[i];0===i&&(includeMove?doMove.call(this,curve.x1+x,curve.y1+y):drawLine.call(this,curve.x1+x,curve.y1+y)),drawCurve.call(this,x,y,curve.x2,curve.y2,curve.x3,curve.y3,curve.x4,curve.y4)}isClip?doClip.call(this):putStyle.call(this,style)},putStyle=function(style){switch(style){case"stroke":this.pdf.internal.out("S");break;case"fill":this.pdf.internal.out("f")}},doClip=function(){this.pdf.clip(),this.pdf.discardPath()},doMove=function(x,y){this.pdf.internal.out(getHorizontalCoordinateString(x)+" "+getVerticalCoordinateString(y)+" m")},putText=function(options){var textAlign;switch(options.align){case"right":case"end":textAlign="right";break;case"center":textAlign="center";break;default:textAlign="left"}var textDimensions=this.pdf.getTextDimensions(options.text),yBaseLine=getBaseline.call(this,options.y),yTop=getTextBottom.call(this,yBaseLine)-textDimensions.h,pt=this.ctx.transform.applyToPoint(new Point(options.x,yBaseLine)),decomposedTransformationMatrix=this.ctx.transform.decompose(),matrix=new Matrix;matrix=(matrix=(matrix=matrix.multiply(decomposedTransformationMatrix.translate)).multiply(decomposedTransformationMatrix.skew)).multiply(decomposedTransformationMatrix.scale);for(var clipPath,oldSize,oldLineWidth,baselineRect=this.ctx.transform.applyToRectangle(new Rectangle(options.x,yBaseLine,textDimensions.w,textDimensions.h)),textBounds=matrix.applyToRectangle(new Rectangle(options.x,yTop,textDimensions.w,textDimensions.h)),pageArray=getPagesByPath.call(this,textBounds),pages=[],ii=0;ii<pageArray.length;ii+=1)-1===pages.indexOf(pageArray[ii])&&pages.push(pageArray[ii]);if(sortPages(pages),this.autoPaging)for(var min=pages[0],max=pages[pages.length-1],i=min;i<max+1;i++){this.pdf.setPage(i);var topMargin=1===i?this.posY+this.margin[0]:this.margin[0],firstPageHeight=this.pdf.internal.pageSize.height-this.posY-this.margin[0]-this.margin[2],pageHeightMinusBottomMargin=this.pdf.internal.pageSize.height-this.margin[2],pageHeightMinusMargins=pageHeightMinusBottomMargin-this.margin[0],pageWidthMinusRightMargin=this.pdf.internal.pageSize.width-this.margin[1],pageWidthMinusMargins=pageWidthMinusRightMargin-this.margin[3],previousPageHeightSum=1===i?0:firstPageHeight+(i-2)*pageHeightMinusMargins;if(0!==this.ctx.clip_path.length){var tmpPaths=this.path;clipPath=JSON.parse(JSON.stringify(this.ctx.clip_path)),this.path=pathPositionRedo(clipPath,this.posX+this.margin[3],-1*previousPageHeightSum+topMargin),drawPaths.call(this,"fill",!0),this.path=tmpPaths}var textBoundsOnPage=pathPositionRedo([JSON.parse(JSON.stringify(textBounds))],this.posX+this.margin[3],-previousPageHeightSum+topMargin+this.ctx.prevPageLastElemOffset)[0];options.scale>=.01&&(oldSize=this.pdf.internal.getFontSize(),this.pdf.setFontSize(oldSize*options.scale),oldLineWidth=this.lineWidth,this.lineWidth=oldLineWidth*options.scale);var doSlice="text"!==this.autoPaging;if(doSlice||textBoundsOnPage.y+textBoundsOnPage.h<=pageHeightMinusBottomMargin){if(doSlice||textBoundsOnPage.y>=topMargin&&textBoundsOnPage.x<=pageWidthMinusRightMargin){var croppedText=doSlice?options.text:this.pdf.splitTextToSize(options.text,options.maxWidth||pageWidthMinusRightMargin-textBoundsOnPage.x)[0],baseLineRectOnPage=pathPositionRedo([JSON.parse(JSON.stringify(baselineRect))],this.posX+this.margin[3],-previousPageHeightSum+topMargin+this.ctx.prevPageLastElemOffset)[0],needsClipping=doSlice&&(i>min||i<max)&&hasMargins.call(this);needsClipping&&(this.pdf.saveGraphicsState(),this.pdf.rect(this.margin[3],this.margin[0],pageWidthMinusMargins,pageHeightMinusMargins,null).clip().discardPath()),this.pdf.text(croppedText,baseLineRectOnPage.x,baseLineRectOnPage.y,{angle:options.angle,align:textAlign,renderingMode:options.renderingMode}),needsClipping&&this.pdf.restoreGraphicsState()}}else textBoundsOnPage.y<pageHeightMinusBottomMargin&&(this.ctx.prevPageLastElemOffset+=pageHeightMinusBottomMargin-textBoundsOnPage.y);options.scale>=.01&&(this.pdf.setFontSize(oldSize),this.lineWidth=oldLineWidth)}else options.scale>=.01&&(oldSize=this.pdf.internal.getFontSize(),this.pdf.setFontSize(oldSize*options.scale),oldLineWidth=this.lineWidth,this.lineWidth=oldLineWidth*options.scale),this.pdf.text(options.text,pt.x+this.posX,pt.y+this.posY,{angle:options.angle,align:textAlign,renderingMode:options.renderingMode,maxWidth:options.maxWidth}),options.scale>=.01&&(this.pdf.setFontSize(oldSize),this.lineWidth=oldLineWidth)},drawLine=function(x,y,prevX,prevY){prevX=prevX||0,prevY=prevY||0,this.pdf.internal.out(getHorizontalCoordinateString(x+prevX)+" "+getVerticalCoordinateString(y+prevY)+" l")},drawLines=function(lines,x,y){return this.pdf.lines(lines,x,y,null,null)},drawCurve=function(x,y,x1,y1,x2,y2,x3,y3){this.pdf.internal.out([f2(getHorizontalCoordinate(x1+x)),f2(getVerticalCoordinate(y1+y)),f2(getHorizontalCoordinate(x2+x)),f2(getVerticalCoordinate(y2+y)),f2(getHorizontalCoordinate(x3+x)),f2(getVerticalCoordinate(y3+y)),"c"].join(" "))},createArc=function(radius,startAngle,endAngle,anticlockwise){for(var twoPi=2*Math.PI,halfPi=Math.PI/2;startAngle>endAngle;)startAngle-=twoPi;var totalAngle=Math.abs(endAngle-startAngle);totalAngle<twoPi&&anticlockwise&&(totalAngle=twoPi-totalAngle);for(var curves=[],sgn=anticlockwise?-1:1,a1=startAngle;totalAngle>1e-5;){var a2=a1+sgn*Math.min(totalAngle,halfPi);curves.push(createSmallArc.call(this,radius,a1,a2)),totalAngle-=Math.abs(a2-a1),a1=a2}return curves},createSmallArc=function(r,a1,a2){var a=(a2-a1)/2,x4=r*Math.cos(a),y4=r*Math.sin(a),x1=x4,y1=-y4,q1=x1*x1+y1*y1,q2=q1+x1*x4+y1*y4,k2=4/3*(Math.sqrt(2*q1*q2)-q2)/(x1*y4-y1*x4),x2=x1-k2*y1,y2=y1+k2*x1,x3=x2,y3=-y2,ar=a+a1,cos_ar=Math.cos(ar),sin_ar=Math.sin(ar);return{x1:r*Math.cos(a1),y1:r*Math.sin(a1),x2:x2*cos_ar-y2*sin_ar,y2:x2*sin_ar+y2*cos_ar,x3:x3*cos_ar-y3*sin_ar,y3:x3*sin_ar+y3*cos_ar,x4:r*Math.cos(a2),y4:r*Math.sin(a2)}},rad2deg=function(value){return 180*value/Math.PI},getQuadraticCurveBoundary=function(sx,sy,cpx,cpy,ex,ey){var midX1=sx+.5*(cpx-sx),midY1=sy+.5*(cpy-sy),midX2=ex+.5*(cpx-ex),midY2=ey+.5*(cpy-ey),resultX1=Math.min(sx,ex,midX1,midX2),resultX2=Math.max(sx,ex,midX1,midX2),resultY1=Math.min(sy,ey,midY1,midY2),resultY2=Math.max(sy,ey,midY1,midY2);return new Rectangle(resultX1,resultY1,resultX2-resultX1,resultY2-resultY1)},getBezierCurveBoundary=function(ax,ay,bx,by,cx,cy,dx,dy){var d,i,px,py,qx,qy,sx,sy,x,y,minx,miny,maxx,maxy,tobx=bx-ax,toby=by-ay,tocx=cx-bx,tocy=cy-by,todx=dx-cx,tody=dy-cy;for(i=0;i<41;i++)x=(sx=(px=ax+(d=i/40)*tobx)+d*((qx=bx+d*tocx)-px))+d*(qx+d*(cx+d*todx-qx)-sx),y=(sy=(py=ay+d*toby)+d*((qy=by+d*tocy)-py))+d*(qy+d*(cy+d*tody-qy)-sy),0==i?(minx=x,miny=y,maxx=x,maxy=y):(minx=Math.min(minx,x),miny=Math.min(miny,y),maxx=Math.max(maxx,x),maxy=Math.max(maxy,y));return new Rectangle(Math.round(minx),Math.round(miny),Math.round(maxx-minx),Math.round(maxy-miny))},setLineDash=function(){if(this.prevLineDash||this.ctx.lineDash.length||this.ctx.lineDashOffset){var lineDash,lineDashOffset,nextLineDash=(lineDash=this.ctx.lineDash,lineDashOffset=this.ctx.lineDashOffset,JSON.stringify({lineDash:lineDash,lineDashOffset:lineDashOffset}));this.prevLineDash!==nextLineDash&&(this.pdf.setLineDash(this.ctx.lineDash,this.ctx.lineDashOffset),this.prevLineDash=nextLineDash)}}}(jsPDF.API);try{require("worker_threads").Worker}catch(e){}var u8=Uint8Array,u16=Uint16Array,u32=Uint32Array,fleb=new u8([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),fdeb=new u8([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),clim=new u8([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),freb=function(eb,start){for(var b=new u16(31),i=0;i<31;++i)b[i]=start+=1<<eb[i-1];var r=new u32(b[30]);for(i=1;i<30;++i)for(var j=b[i];j<b[i+1];++j)r[j]=j-b[i]<<5|i;return[b,r]},_a=freb(fleb,2),fl=_a[0],revfl=_a[1];fl[28]=258,revfl[258]=28;for(var _b=freb(fdeb,0),fd=_b[0],revfd=_b[1],rev=new u16(32768),i=0;i<32768;++i){var x=(43690&i)>>>1|(21845&i)<<1;x=(61680&(x=(52428&x)>>>2|(13107&x)<<2))>>>4|(3855&x)<<4,rev[i]=((65280&x)>>>8|(255&x)<<8)>>>1}var hMap=function(cd,mb,r){for(var s=cd.length,i=0,l=new u16(mb);i<s;++i)++l[cd[i]-1];var co,le=new u16(mb);for(i=0;i<mb;++i)le[i]=le[i-1]+l[i-1]<<1;if(r){co=new u16(1<<mb);var rvb=15-mb;for(i=0;i<s;++i)if(cd[i])for(var sv=i<<4|cd[i],r_1=mb-cd[i],v=le[cd[i]-1]++<<r_1,m=v|(1<<r_1)-1;v<=m;++v)co[rev[v]>>>rvb]=sv}else for(co=new u16(s),i=0;i<s;++i)co[i]=rev[le[cd[i]-1]++]>>>15-cd[i];return co},flt=new u8(288);for(i=0;i<144;++i)flt[i]=8;for(i=144;i<256;++i)flt[i]=9;for(i=256;i<280;++i)flt[i]=7;for(i=280;i<288;++i)flt[i]=8;var fdt=new u8(32);for(i=0;i<32;++i)fdt[i]=5;var flm=hMap(flt,9,0),flrm=hMap(flt,9,1),fdm=hMap(fdt,5,0),fdrm=hMap(fdt,5,1),max=function(a){for(var m=a[0],i=1;i<a.length;++i)a[i]>m&&(m=a[i]);return m},bits=function(d,p,m){var o=p/8>>0;return(d[o]|d[o+1]<<8)>>>(7&p)&m},bits16=function(d,p){var o=p/8>>0;return(d[o]|d[o+1]<<8|d[o+2]<<16)>>>(7&p)},shft=function(p){return(p/8>>0)+(7&p&&1)},slc=function(v,s,e){(null==s||s<0)&&(s=0),(null==e||e>v.length)&&(e=v.length);var n=new(v instanceof u16?u16:v instanceof u32?u32:u8)(e-s);return n.set(v.subarray(s,e)),n},wbits=function(d,p,v){v<<=7&p;var o=p/8>>0;d[o]|=v,d[o+1]|=v>>>8},wbits16=function(d,p,v){v<<=7&p;var o=p/8>>0;d[o]|=v,d[o+1]|=v>>>8,d[o+2]|=v>>>16},hTree=function(d,mb){for(var t=[],i=0;i<d.length;++i)d[i]&&t.push({s:i,f:d[i]});var s=t.length,t2=t.slice();if(!s)return[new u8(0),0];if(1==s){var v=new u8(t[0].s+1);return v[t[0].s]=1,[v,1]}t.sort((function(a,b){return a.f-b.f})),t.push({s:-1,f:25001});var l=t[0],r=t[1],i0=0,i1=1,i2=2;for(t[0]={s:-1,f:l.f+r.f,l:l,r:r};i1!=s-1;)l=t[t[i0].f<t[i2].f?i0++:i2++],r=t[i0!=i1&&t[i0].f<t[i2].f?i0++:i2++],t[i1++]={s:-1,f:l.f+r.f,l:l,r:r};var maxSym=t2[0].s;for(i=1;i<s;++i)t2[i].s>maxSym&&(maxSym=t2[i].s);var tr=new u16(maxSym+1),mbt=ln(t[i1-1],tr,0);if(mbt>mb){i=0;var dt=0,lft=mbt-mb,cst=1<<lft;for(t2.sort((function(a,b){return tr[b.s]-tr[a.s]||a.f-b.f}));i<s;++i){var i2_1=t2[i].s;if(!(tr[i2_1]>mb))break;dt+=cst-(1<<mbt-tr[i2_1]),tr[i2_1]=mb}for(dt>>>=lft;dt>0;){var i2_2=t2[i].s;tr[i2_2]<mb?dt-=1<<mb-tr[i2_2]++-1:++i}for(;i>=0&&dt;--i){var i2_3=t2[i].s;tr[i2_3]==mb&&(--tr[i2_3],++dt)}mbt=mb}return[new u8(tr),mbt]},ln=function ln(n,l,d){return-1==n.s?Math.max(ln(n.l,l,d+1),ln(n.r,l,d+1)):l[n.s]=d},lc=function(c){for(var s=c.length;s&&!c[--s];);for(var cl=new u16(++s),cli=0,cln=c[0],cls=1,w=function(v){cl[cli++]=v},i=1;i<=s;++i)if(c[i]==cln&&i!=s)++cls;else{if(!cln&&cls>2){for(;cls>138;cls-=138)w(32754);cls>2&&(w(cls>10?cls-11<<5|28690:cls-3<<5|12305),cls=0)}else if(cls>3){for(w(cln),--cls;cls>6;cls-=6)w(8304);cls>2&&(w(cls-3<<5|8208),cls=0)}for(;cls--;)w(cln);cls=1,cln=c[i]}return[cl.subarray(0,cli),s]},clen=function(cf,cl){for(var l=0,i=0;i<cl.length;++i)l+=cf[i]*cl[i];return l},wfblk=function(out,pos,dat){var s=dat.length,o=shft(pos+2);out[o]=255&s,out[o+1]=s>>>8,out[o+2]=255^out[o],out[o+3]=255^out[o+1];for(var i=0;i<s;++i)out[o+i+4]=dat[i];return 8*(o+4+s)},wblk=function(dat,out,final,syms,lf,df,eb,li,bs,bl,p){wbits(out,p++,final),++lf[256];for(var _a=hTree(lf,15),dlt=_a[0],mlb=_a[1],_b=hTree(df,15),ddt=_b[0],mdb=_b[1],_c=lc(dlt),lclt=_c[0],nlc=_c[1],_d=lc(ddt),lcdt=_d[0],ndc=_d[1],lcfreq=new u16(19),i=0;i<lclt.length;++i)lcfreq[31&lclt[i]]++;for(i=0;i<lcdt.length;++i)lcfreq[31&lcdt[i]]++;for(var _e=hTree(lcfreq,7),lct=_e[0],mlcb=_e[1],nlcc=19;nlcc>4&&!lct[clim[nlcc-1]];--nlcc);var lm,ll,dm,dl,flen=bl+5<<3,ftlen=clen(lf,flt)+clen(df,fdt)+eb,dtlen=clen(lf,dlt)+clen(df,ddt)+eb+14+3*nlcc+clen(lcfreq,lct)+(2*lcfreq[16]+3*lcfreq[17]+7*lcfreq[18]);if(flen<=ftlen&&flen<=dtlen)return wfblk(out,p,dat.subarray(bs,bs+bl));if(wbits(out,p,1+(dtlen<ftlen)),p+=2,dtlen<ftlen){lm=hMap(dlt,mlb,0),ll=dlt,dm=hMap(ddt,mdb,0),dl=ddt;var llm=hMap(lct,mlcb,0);wbits(out,p,nlc-257),wbits(out,p+5,ndc-1),wbits(out,p+10,nlcc-4),p+=14;for(i=0;i<nlcc;++i)wbits(out,p+3*i,lct[clim[i]]);p+=3*nlcc;for(var lcts=[lclt,lcdt],it=0;it<2;++it){var clct=lcts[it];for(i=0;i<clct.length;++i){var len=31&clct[i];wbits(out,p,llm[len]),p+=lct[len],len>15&&(wbits(out,p,clct[i]>>>5&127),p+=clct[i]>>>12)}}}else lm=flm,ll=flt,dm=fdm,dl=fdt;for(i=0;i<li;++i)if(syms[i]>255){len=syms[i]>>>18&31;wbits16(out,p,lm[len+257]),p+=ll[len+257],len>7&&(wbits(out,p,syms[i]>>>23&31),p+=fleb[len]);var dst=31&syms[i];wbits16(out,p,dm[dst]),p+=dl[dst],dst>3&&(wbits16(out,p,syms[i]>>>5&8191),p+=fdeb[dst])}else wbits16(out,p,lm[syms[i]]),p+=ll[syms[i]];return wbits16(out,p,lm[256]),p+ll[256]},deo=new u32([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),et=new u8(0),dopt=function(dat,opt,pre,post,st){return function(dat,lvl,plvl,pre,post,lst){var s=dat.length,o=new u8(pre+s+5*(1+Math.floor(s/7e3))+post),w=o.subarray(pre,o.length-post),pos=0;if(!lvl||s<8)for(var i=0;i<=s;i+=65535){var e=i+65535;e<s?pos=wfblk(w,pos,dat.subarray(i,e)):(w[i]=lst,pos=wfblk(w,pos,dat.subarray(i,s)))}else{for(var opt=deo[lvl-1],n=opt>>>13,c=8191&opt,msk_1=(1<<plvl)-1,prev=new u16(32768),head=new u16(msk_1+1),bs1_1=Math.ceil(plvl/3),bs2_1=2*bs1_1,hsh=function(i){return(dat[i]^dat[i+1]<<bs1_1^dat[i+2]<<bs2_1)&msk_1},syms=new u32(25e3),lf=new u16(288),df=new u16(32),lc_1=0,eb=0,li=(i=0,0),wi=0,bs=0;i<s;++i){var hv=hsh(i),imod=32767&i,pimod=head[hv];if(prev[imod]=pimod,head[hv]=imod,wi<=i){var rem=s-i;if((lc_1>7e3||li>24576)&&rem>423){pos=wblk(dat,w,0,syms,lf,df,eb,li,bs,i-bs,pos),li=lc_1=eb=0,bs=i;for(var j=0;j<286;++j)lf[j]=0;for(j=0;j<30;++j)df[j]=0}var l=2,d=0,ch_1=c,dif=imod-pimod&32767;if(rem>2&&hv==hsh(i-dif))for(var maxn=Math.min(n,rem)-1,maxd=Math.min(32767,i),ml=Math.min(258,rem);dif<=maxd&&--ch_1&&imod!=pimod;){if(dat[i+l]==dat[i+l-dif]){for(var nl=0;nl<ml&&dat[i+nl]==dat[i+nl-dif];++nl);if(nl>l){if(l=nl,d=dif,nl>maxn)break;var mmd=Math.min(dif,nl-2),md=0;for(j=0;j<mmd;++j){var ti=i-dif+j+32768&32767,cd=ti-prev[ti]+32768&32767;cd>md&&(md=cd,pimod=ti)}}}dif+=(imod=pimod)-(pimod=prev[imod])+32768&32767}if(d){syms[li++]=268435456|revfl[l]<<18|revfd[d];var lin=31&revfl[l],din=31&revfd[d];eb+=fleb[lin]+fdeb[din],++lf[257+lin],++df[din],wi=i+l,++lc_1}else syms[li++]=dat[i],++lf[dat[i]]}}pos=wblk(dat,w,lst,syms,lf,df,eb,li,bs,i-bs,pos),lst||(pos=wfblk(w,pos,et))}return slc(o,0,pre+shft(pos)+post)}(dat,null==opt.level?6:opt.level,null==opt.mem?Math.ceil(1.5*Math.max(8,Math.min(13,Math.log(dat.length)))):12+opt.mem,pre,post,!st)};function zlibSync(data,opts){void 0===opts&&(opts={});var a=function(){var a=1,b=0;return{p:function(d){for(var n=a,m=b,l=d.length,i=0;i!=l;){for(var e=Math.min(i+5552,l);i<e;++i)m+=n+=d[i];n%=65521,m%=65521}a=n,b=m},d:function(){return(a>>>8<<16|(255&b)<<8|b>>>8)+2*((255&a)<<23)}}}();a.p(data);var d=dopt(data,opts,2,4);return function(c,o){var lv=o.level,fl=0==lv?0:lv<6?1:9==lv?3:2;c[0]=120,c[1]=fl<<6|(fl?32-2*fl:1)}(d,opts),function(d,b,v){for(;v;++b)d[b]=v,v>>>=8}(d,d.length-4,a.d()),d}function unzlibSync(data,out){return function(dat,buf,st){var sl=dat.length,noBuf=!buf||st,noSt=!st||st.i;st||(st={}),buf||(buf=new u8(3*sl));var cbuf=function(l){var bl=buf.length;if(l>bl){var nbuf=new u8(Math.max(2*bl,l));nbuf.set(buf),buf=nbuf}},final=st.f||0,pos=st.p||0,bt=st.b||0,lm=st.l,dm=st.d,lbt=st.m,dbt=st.n,tbts=8*sl;do{if(!lm){st.f=final=bits(dat,pos,1);var type=bits(dat,pos+1,3);if(pos+=3,!type){var l=dat[(s=shft(pos)+4)-4]|dat[s-3]<<8,t=s+l;if(t>sl){if(noSt)throw"unexpected EOF";break}noBuf&&cbuf(bt+l),buf.set(dat.subarray(s,t),bt),st.b=bt+=l,st.p=pos=8*t;continue}if(1==type)lm=flrm,dm=fdrm,lbt=9,dbt=5;else{if(2!=type)throw"invalid block type";var hLit=bits(dat,pos,31)+257,hcLen=bits(dat,pos+10,15)+4,tl=hLit+bits(dat,pos+5,31)+1;pos+=14;for(var ldt=new u8(tl),clt=new u8(19),i=0;i<hcLen;++i)clt[clim[i]]=bits(dat,pos+3*i,7);pos+=3*hcLen;var clb=max(clt),clbmsk=(1<<clb)-1;if(!noSt&&pos+tl*(clb+7)>tbts)break;var clm=hMap(clt,clb,1);for(i=0;i<tl;){var s,r=clm[bits(dat,pos,clbmsk)];if(pos+=15&r,(s=r>>>4)<16)ldt[i++]=s;else{var c=0,n=0;for(16==s?(n=3+bits(dat,pos,3),pos+=2,c=ldt[i-1]):17==s?(n=3+bits(dat,pos,7),pos+=3):18==s&&(n=11+bits(dat,pos,127),pos+=7);n--;)ldt[i++]=c}}var lt=ldt.subarray(0,hLit),dt=ldt.subarray(hLit);lbt=max(lt),dbt=max(dt),lm=hMap(lt,lbt,1),dm=hMap(dt,dbt,1)}if(pos>tbts)throw"unexpected EOF"}noBuf&&cbuf(bt+131072);for(var lms=(1<<lbt)-1,dms=(1<<dbt)-1,mxa=lbt+dbt+18;noSt||pos+mxa<tbts;){var sym=(c=lm[bits16(dat,pos)&lms])>>>4;if((pos+=15&c)>tbts)throw"unexpected EOF";if(!c)throw"invalid length/literal";if(sym<256)buf[bt++]=sym;else{if(256==sym){lm=null;break}var add=sym-254;if(sym>264){var b=fleb[i=sym-257];add=bits(dat,pos,(1<<b)-1)+fl[i],pos+=b}var d=dm[bits16(dat,pos)&dms],dsym=d>>>4;if(!d)throw"invalid distance";if(pos+=15&d,dt=fd[dsym],dsym>3&&(b=fdeb[dsym],dt+=bits16(dat,pos)&(1<<b)-1,pos+=b),pos>tbts)throw"unexpected EOF";noBuf&&cbuf(bt+131072);for(var end=bt+add;bt<end;bt+=4)buf[bt]=buf[bt-dt],buf[bt+1]=buf[bt+1-dt],buf[bt+2]=buf[bt+2-dt],buf[bt+3]=buf[bt+3-dt];bt=end}}st.l=lm,st.p=pos,st.b=bt,lm&&(final=1,st.m=lbt,st.d=dm,st.n=dbt)}while(!final);return bt==buf.length?buf:slc(buf,0,bt)}((function(d){if(8!=(15&d[0])||d[0]>>>4>7||(d[0]<<8|d[1])%31)throw"invalid zlib data";if(32&d[1])throw"invalid zlib data: preset dictionaries not supported"}(data),data.subarray(2,-4)),out)}
+/**
+   * @license
+   * jsPDF filters PlugIn
+   * Copyright (c) 2014 Aras Abbasi
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */!function(jsPDFAPI){var ASCII85Encode=function(a){var b,c,d,e,f,g,h,i,j,k;for(/[^\x00-\xFF]/.test(a),c=[],d=0,e=(a+=b="\0\0\0\0".slice(a.length%4||4)).length;e>d;d+=4)0!==(f=(a.charCodeAt(d)<<24)+(a.charCodeAt(d+1)<<16)+(a.charCodeAt(d+2)<<8)+a.charCodeAt(d+3))?(g=(f=((f=((f=((f=(f-(k=f%85))/85)-(j=f%85))/85)-(i=f%85))/85)-(h=f%85))/85)%85,c.push(g+33,h+33,i+33,j+33,k+33)):c.push(122);return function(a,b){for(var c=b;c>0;c--)a.pop()}(c,b.length),String.fromCharCode.apply(String,c)+"~>"},ASCII85Decode=function(a){var c,d,e,f,g,h=String,l="length",w=255,x="charCodeAt",y="slice",z="replace";for(a[y](-2),a=a[y](0,-2)[z](/\s/g,"")[z]("z","!!!!!"),e=[],f=0,g=(a+=c="uuuuu"[y](a[l]%5||5))[l];g>f;f+=5)d=52200625*(a[x](f)-33)+614125*(a[x](f+1)-33)+7225*(a[x](f+2)-33)+85*(a[x](f+3)-33)+(a[x](f+4)-33),e.push(w&d>>24,w&d>>16,w&d>>8,w&d);return function(a,b){for(var c=b;c>0;c--)a.pop()}(e,c[l]),h.fromCharCode.apply(h,e)},ASCIIHexDecode=function(value){var regexCheckIfHex=new RegExp(/^([0-9A-Fa-f]{2})+$/);if(-1!==(value=value.replace(/\s/g,"")).indexOf(">")&&(value=value.substr(0,value.indexOf(">"))),value.length%2&&(value+="0"),!1===regexCheckIfHex.test(value))return"";for(var result="",i=0;i<value.length;i+=2)result+=String.fromCharCode("0x"+(value[i]+value[i+1]));return result},FlateEncode=function(data){for(var arr=new Uint8Array(data.length),i=data.length;i--;)arr[i]=data.charCodeAt(i);return data=(arr=zlibSync(arr)).reduce((function(data,byte){return data+String.fromCharCode(byte)}),"")};jsPDFAPI.processDataByFilters=function(origData,filterChain){var i=0,data=origData||"",reverseChain=[];for("string"==typeof(filterChain=filterChain||[])&&(filterChain=[filterChain]),i=0;i<filterChain.length;i+=1)switch(filterChain[i]){case"ASCII85Decode":case"/ASCII85Decode":data=ASCII85Decode(data),reverseChain.push("/ASCII85Encode");break;case"ASCII85Encode":case"/ASCII85Encode":data=ASCII85Encode(data),reverseChain.push("/ASCII85Decode");break;case"ASCIIHexDecode":case"/ASCIIHexDecode":data=ASCIIHexDecode(data),reverseChain.push("/ASCIIHexEncode");break;case"ASCIIHexEncode":case"/ASCIIHexEncode":data=data.split("").map((function(value){return("0"+value.charCodeAt().toString(16)).slice(-2)})).join("")+">",reverseChain.push("/ASCIIHexDecode");break;case"FlateEncode":case"/FlateEncode":data=FlateEncode(data),reverseChain.push("/FlateDecode");break;default:throw new Error('The filter: "'+filterChain[i]+'" is not implemented')}return{data:data,reverseChain:reverseChain.reverse().join(" ")}}}(jsPDF.API),
+/**
+   * @license
+   * jsPDF fileloading PlugIn
+   * Copyright (c) 2018 Aras Abbasi (aras.abbasi@gmail.com)
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+function(jsPDFAPI){jsPDFAPI.loadFile=function(url,sync,callback){return function(url,sync,callback){sync=!1!==sync,callback="function"==typeof callback?callback:function(){};var result=void 0,xhr=function(url,sync,callback){var request=new XMLHttpRequest,i=0,sanitizeUnicode=function(data){var dataLength=data.length,charArray=[],StringFromCharCode=String.fromCharCode;for(i=0;i<dataLength;i+=1)charArray.push(StringFromCharCode(255&data.charCodeAt(i)));return charArray.join("")};if(request.open("GET",url,!sync),request.overrideMimeType("text/plain; charset=x-user-defined"),!1===sync&&(request.onload=function(){200===request.status?callback(sanitizeUnicode(this.responseText)):callback(void 0)}),request.send(null),sync&&200===request.status)return sanitizeUnicode(request.responseText)};try{result=xhr(url,sync,callback)}catch(e){}return result}(url,sync,callback)},jsPDFAPI.loadImageFile=jsPDFAPI.loadFile}(jsPDF.API),function(jsPDFAPI){function loadHtml2Canvas(){return(globalObject.html2canvas?Promise.resolve(globalObject.html2canvas):"object"===(void 0===exports?"undefined":_typeof(exports))&&"undefined"!=typeof module?new Promise((function(resolve,reject){try{resolve(require("html2canvas"))}catch(e){reject(e)}})):"function"==typeof define&&define.amd?new Promise((function(resolve,reject){try{require(["html2canvas"],resolve)}catch(e){reject(e)}})):Promise.reject(new Error("Could not load html2canvas"))).catch((function(e){return Promise.reject(new Error("Could not load html2canvas: "+e))})).then((function(html2canvas){return html2canvas.default?html2canvas.default:html2canvas}))}function loadDomPurify(){return(globalObject.DOMPurify?Promise.resolve(globalObject.DOMPurify):"object"===(void 0===exports?"undefined":_typeof(exports))&&"undefined"!=typeof module?new Promise((function(resolve,reject){try{resolve(require("dompurify"))}catch(e){reject(e)}})):"function"==typeof define&&define.amd?new Promise((function(resolve,reject){try{require(["dompurify"],resolve)}catch(e){reject(e)}})):Promise.reject(new Error("Could not load dompurify"))).catch((function(e){return Promise.reject(new Error("Could not load dompurify: "+e))})).then((function(dompurify){return dompurify.default?dompurify.default:dompurify}))}var objType=function(obj){var type=_typeof(obj);return"undefined"===type?"undefined":"string"===type||obj instanceof String?"string":"number"===type||obj instanceof Number?"number":"function"===type||obj instanceof Function?"function":obj&&obj.constructor===Array?"array":obj&&1===obj.nodeType?"element":"object"===type?"object":"unknown"},createElement=function(tagName,opt){var el=document.createElement(tagName);for(var key in opt.className&&(el.className=opt.className),opt.innerHTML&&opt.dompurify&&(el.innerHTML=opt.dompurify.sanitize(opt.innerHTML)),opt.style)el.style[key]=opt.style[key];return el},cloneNode=function cloneNode(node,javascriptEnabled){for(var clone=3===node.nodeType?document.createTextNode(node.nodeValue):node.cloneNode(!1),child=node.firstChild;child;child=child.nextSibling)!0!==javascriptEnabled&&1===child.nodeType&&"SCRIPT"===child.nodeName||clone.appendChild(cloneNode(child,javascriptEnabled));return 1===node.nodeType&&("CANVAS"===node.nodeName?(clone.width=node.width,clone.height=node.height,clone.getContext("2d").drawImage(node,0,0)):"TEXTAREA"!==node.nodeName&&"SELECT"!==node.nodeName||(clone.value=node.value),clone.addEventListener("load",(function(){clone.scrollTop=node.scrollTop,clone.scrollLeft=node.scrollLeft}),!0)),clone},Worker=function Worker(opt){var root=Object.assign(Worker.convert(Promise.resolve()),JSON.parse(JSON.stringify(Worker.template))),self=Worker.convert(Promise.resolve(),root);return self=(self=self.setProgress(1,Worker,1,[Worker])).set(opt)};(Worker.prototype=Object.create(Promise.prototype)).constructor=Worker,Worker.convert=function(promise,inherit){return promise.__proto__=inherit||Worker.prototype,promise},Worker.template={prop:{src:null,container:null,overlay:null,canvas:null,img:null,pdf:null,pageSize:null,callback:function(){}},progress:{val:0,state:null,n:0,stack:[]},opt:{filename:"file.pdf",margin:[0,0,0,0],enableLinks:!0,x:0,y:0,html2canvas:{},jsPDF:{},backgroundColor:"transparent"}},Worker.prototype.from=function(src,type){return this.then((function(){switch(type=type||function(src){switch(objType(src)){case"string":return"string";case"element":return"canvas"===src.nodeName.toLowerCase()?"canvas":"element";default:return"unknown"}}(src),type){case"string":return this.then(loadDomPurify).then((function(dompurify){return this.set({src:createElement("div",{innerHTML:src,dompurify:dompurify})})}));case"element":return this.set({src:src});case"canvas":return this.set({canvas:src});case"img":return this.set({img:src});default:return this.error("Unknown source type.")}}))},Worker.prototype.to=function(target){switch(target){case"container":return this.toContainer();case"canvas":return this.toCanvas();case"img":return this.toImg();case"pdf":return this.toPdf();default:return this.error("Invalid target.")}},Worker.prototype.toContainer=function(){return this.thenList([function(){return this.prop.src||this.error("Cannot duplicate - no source HTML.")},function(){return this.prop.pageSize||this.setPageSize()}]).then((function(){var containerCSS={position:"relative",display:"inline-block",width:("number"!=typeof this.opt.width||isNaN(this.opt.width)||"number"!=typeof this.opt.windowWidth||isNaN(this.opt.windowWidth)?Math.max(this.prop.src.clientWidth,this.prop.src.scrollWidth,this.prop.src.offsetWidth):this.opt.windowWidth)+"px",left:0,right:0,top:0,margin:"auto",backgroundColor:this.opt.backgroundColor},source=cloneNode(this.prop.src,this.opt.html2canvas.javascriptEnabled);"BODY"===source.tagName&&(containerCSS.height=Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight)+"px"),this.prop.overlay=createElement("div",{className:"html2pdf__overlay",style:{position:"fixed",overflow:"hidden",zIndex:1e3,left:"-100000px",right:0,bottom:0,top:0}}),this.prop.container=createElement("div",{className:"html2pdf__container",style:containerCSS}),this.prop.container.appendChild(source),this.prop.container.firstChild.appendChild(createElement("div",{style:{clear:"both",border:"0 none transparent",margin:0,padding:0,height:0}})),this.prop.container.style.float="none",this.prop.overlay.appendChild(this.prop.container),document.body.appendChild(this.prop.overlay),this.prop.container.firstChild.style.position="relative",this.prop.container.height=Math.max(this.prop.container.firstChild.clientHeight,this.prop.container.firstChild.scrollHeight,this.prop.container.firstChild.offsetHeight)+"px"}))},Worker.prototype.toCanvas=function(){var prereqs=[function(){return document.body.contains(this.prop.container)||this.toContainer()}];return this.thenList(prereqs).then(loadHtml2Canvas).then((function(html2canvas){var options=Object.assign({},this.opt.html2canvas);return delete options.onrendered,html2canvas(this.prop.container,options)})).then((function(canvas){(this.opt.html2canvas.onrendered||function(){})(canvas),this.prop.canvas=canvas,document.body.removeChild(this.prop.overlay)}))},Worker.prototype.toContext2d=function(){var prereqs=[function(){return document.body.contains(this.prop.container)||this.toContainer()}];return this.thenList(prereqs).then(loadHtml2Canvas).then((function(html2canvas){var pdf=this.opt.jsPDF,fontFaces=this.opt.fontFaces,scale="number"!=typeof this.opt.width||isNaN(this.opt.width)||"number"!=typeof this.opt.windowWidth||isNaN(this.opt.windowWidth)?1:this.opt.width/this.opt.windowWidth,options=Object.assign({async:!0,allowTaint:!0,scale:scale,scrollX:this.opt.scrollX||0,scrollY:this.opt.scrollY||0,backgroundColor:"#ffffff",imageTimeout:15e3,logging:!0,proxy:null,removeContainer:!0,foreignObjectRendering:!1,useCORS:!1},this.opt.html2canvas);if(delete options.onrendered,pdf.context2d.autoPaging=void 0===this.opt.autoPaging||this.opt.autoPaging,pdf.context2d.posX=this.opt.x,pdf.context2d.posY=this.opt.y,pdf.context2d.margin=this.opt.margin,pdf.context2d.fontFaces=fontFaces,fontFaces)for(var i=0;i<fontFaces.length;++i){var font=fontFaces[i],src=font.src.find((function(src){return"truetype"===src.format}));src&&pdf.addFont(src.url,font.ref.name,font.ref.style)}return options.windowHeight=options.windowHeight||0,options.windowHeight=0==options.windowHeight?Math.max(this.prop.container.clientHeight,this.prop.container.scrollHeight,this.prop.container.offsetHeight):options.windowHeight,pdf.context2d.save(!0),html2canvas(this.prop.container,options)})).then((function(canvas){this.opt.jsPDF.context2d.restore(!0),(this.opt.html2canvas.onrendered||function(){})(canvas),this.prop.canvas=canvas,document.body.removeChild(this.prop.overlay)}))},Worker.prototype.toImg=function(){return this.thenList([function(){return this.prop.canvas||this.toCanvas()}]).then((function(){var imgData=this.prop.canvas.toDataURL("image/"+this.opt.image.type,this.opt.image.quality);this.prop.img=document.createElement("img"),this.prop.img.src=imgData}))},Worker.prototype.toPdf=function(){return this.thenList([function(){return this.toContext2d()}]).then((function(){this.prop.pdf=this.prop.pdf||this.opt.jsPDF}))},Worker.prototype.output=function(type,options,src){return"img"===(src=src||"pdf").toLowerCase()||"image"===src.toLowerCase()?this.outputImg(type,options):this.outputPdf(type,options)},Worker.prototype.outputPdf=function(type,options){return this.thenList([function(){return this.prop.pdf||this.toPdf()}]).then((function(){return this.prop.pdf.output(type,options)}))},Worker.prototype.outputImg=function(type){return this.thenList([function(){return this.prop.img||this.toImg()}]).then((function(){switch(type){case void 0:case"img":return this.prop.img;case"datauristring":case"dataurlstring":return this.prop.img.src;case"datauri":case"dataurl":return document.location.href=this.prop.img.src;default:throw'Image output type "'+type+'" is not supported.'}}))},Worker.prototype.save=function(filename){return this.thenList([function(){return this.prop.pdf||this.toPdf()}]).set(filename?{filename:filename}:null).then((function(){this.prop.pdf.save(this.opt.filename)}))},Worker.prototype.doCallback=function(){return this.thenList([function(){return this.prop.pdf||this.toPdf()}]).then((function(){this.prop.callback(this.prop.pdf)}))},Worker.prototype.set=function(opt){if("object"!==objType(opt))return this;var fns=Object.keys(opt||{}).map((function(key){if(key in Worker.template.prop)return function(){this.prop[key]=opt[key]};switch(key){case"margin":return this.setMargin.bind(this,opt.margin);case"jsPDF":return function(){return this.opt.jsPDF=opt.jsPDF,this.setPageSize()};case"pageSize":return this.setPageSize.bind(this,opt.pageSize);default:return function(){this.opt[key]=opt[key]}}}),this);return this.then((function(){return this.thenList(fns)}))},Worker.prototype.get=function(key,cbk){return this.then((function(){var val=key in Worker.template.prop?this.prop[key]:this.opt[key];return cbk?cbk(val):val}))},Worker.prototype.setMargin=function(margin){return this.then((function(){switch(objType(margin)){case"number":margin=[margin,margin,margin,margin];case"array":if(2===margin.length&&(margin=[margin[0],margin[1],margin[0],margin[1]]),4===margin.length)break;default:return this.error("Invalid margin array.")}this.opt.margin=margin})).then(this.setPageSize)},Worker.prototype.setPageSize=function(pageSize){function toPx(val,k){return Math.floor(val*k/72*96)}return this.then((function(){(pageSize=pageSize||jsPDF.getPageSize(this.opt.jsPDF)).hasOwnProperty("inner")||(pageSize.inner={width:pageSize.width-this.opt.margin[1]-this.opt.margin[3],height:pageSize.height-this.opt.margin[0]-this.opt.margin[2]},pageSize.inner.px={width:toPx(pageSize.inner.width,pageSize.k),height:toPx(pageSize.inner.height,pageSize.k)},pageSize.inner.ratio=pageSize.inner.height/pageSize.inner.width),this.prop.pageSize=pageSize}))},Worker.prototype.setProgress=function(val,state,n,stack){return null!=val&&(this.progress.val=val),null!=state&&(this.progress.state=state),null!=n&&(this.progress.n=n),null!=stack&&(this.progress.stack=stack),this.progress.ratio=this.progress.val/this.progress.state,this},Worker.prototype.updateProgress=function(val,state,n,stack){return this.setProgress(val?this.progress.val+val:null,state||null,n?this.progress.n+n:null,stack?this.progress.stack.concat(stack):null)},Worker.prototype.then=function(onFulfilled,onRejected){var self=this;return this.thenCore(onFulfilled,onRejected,(function(onFulfilled,onRejected){return self.updateProgress(null,null,1,[onFulfilled]),Promise.prototype.then.call(this,(function(val){return self.updateProgress(null,onFulfilled),val})).then(onFulfilled,onRejected).then((function(val){return self.updateProgress(1),val}))}))},Worker.prototype.thenCore=function(onFulfilled,onRejected,thenBase){thenBase=thenBase||Promise.prototype.then;onFulfilled&&(onFulfilled=onFulfilled.bind(this)),onRejected&&(onRejected=onRejected.bind(this));var selfPromise=-1!==Promise.toString().indexOf("[native code]")&&"Promise"===Promise.name?this:Worker.convert(Object.assign({},this),Promise.prototype),returnVal=thenBase.call(selfPromise,onFulfilled,onRejected);return Worker.convert(returnVal,this.__proto__)},Worker.prototype.thenExternal=function(onFulfilled,onRejected){return Promise.prototype.then.call(this,onFulfilled,onRejected)},Worker.prototype.thenList=function(fns){var self=this;return fns.forEach((function(fn){self=self.thenCore(fn)})),self},Worker.prototype.catch=function(onRejected){onRejected&&(onRejected=onRejected.bind(this));var returnVal=Promise.prototype.catch.call(this,onRejected);return Worker.convert(returnVal,this)},Worker.prototype.catchExternal=function(onRejected){return Promise.prototype.catch.call(this,onRejected)},Worker.prototype.error=function(msg){return this.then((function(){throw new Error(msg)}))},Worker.prototype.using=Worker.prototype.set,Worker.prototype.saveAs=Worker.prototype.save,Worker.prototype.export=Worker.prototype.output,Worker.prototype.run=Worker.prototype.then,jsPDF.getPageSize=function(orientation,unit,format){if("object"===_typeof(orientation)){var options=orientation;orientation=options.orientation,unit=options.unit||unit,format=options.format||format}unit=unit||"mm",format=format||"a4",orientation=(""+(orientation||"P")).toLowerCase();var k,format_as_string=(""+format).toLowerCase(),pageFormats={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]};switch(unit){case"pt":k=1;break;case"mm":k=72/25.4;break;case"cm":k=72/2.54;break;case"in":k=72;break;case"px":k=.75;break;case"pc":case"em":k=12;break;case"ex":k=6;break;default:throw"Invalid unit: "+unit}var tmp,pageHeight=0,pageWidth=0;if(pageFormats.hasOwnProperty(format_as_string))pageHeight=pageFormats[format_as_string][1]/k,pageWidth=pageFormats[format_as_string][0]/k;else try{pageHeight=format[1],pageWidth=format[0]}catch(err){throw new Error("Invalid format: "+format)}if("p"===orientation||"portrait"===orientation)orientation="p",pageWidth>pageHeight&&(tmp=pageWidth,pageWidth=pageHeight,pageHeight=tmp);else{if("l"!==orientation&&"landscape"!==orientation)throw"Invalid orientation: "+orientation;orientation="l",pageHeight>pageWidth&&(tmp=pageWidth,pageWidth=pageHeight,pageHeight=tmp)}return{width:pageWidth,height:pageHeight,unit:unit,k:k,orientation:orientation}},jsPDFAPI.html=function(src,options){(options=options||{}).callback=options.callback||function(){},options.html2canvas=options.html2canvas||{},options.html2canvas.canvas=options.html2canvas.canvas||this.canvas,options.jsPDF=options.jsPDF||this,options.fontFaces=options.fontFaces?options.fontFaces.map(normalizeFontFace):null;var worker=new Worker(options);return options.worker?worker:worker.from(src).doCallback()}}(jsPDF.API),
+/**
+   * @license
    * ====================================================================
+   * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
+   *
+   * Permission is hereby granted, free of charge, to any person obtaining
+   * a copy of this software and associated documentation files (the
+   * "Software"), to deal in the Software without restriction, including
+   * without limitation the rights to use, copy, modify, merge, publish,
+   * distribute, sublicense, and/or sell copies of the Software, and to
+   * permit persons to whom the Software is furnished to do so, subject to
+   * the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be
+   * included in all copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+   * ====================================================================
+   */
+function(jsPDFAPI){var jsNamesObj,jsJsObj,text;jsPDFAPI.addJS=function(javascript){return text=javascript,this.internal.events.subscribe("postPutResources",(function(){jsNamesObj=this.internal.newObject(),this.internal.out("<<"),this.internal.out("/Names [(EmbeddedJS) "+(jsNamesObj+1)+" 0 R]"),this.internal.out(">>"),this.internal.out("endobj"),jsJsObj=this.internal.newObject(),this.internal.out("<<"),this.internal.out("/S /JavaScript"),this.internal.out("/JS ("+text+")"),this.internal.out(">>"),this.internal.out("endobj")})),this.internal.events.subscribe("putCatalog",(function(){void 0!==jsNamesObj&&void 0!==jsJsObj&&this.internal.out("/Names <</JavaScript "+jsNamesObj+" 0 R>>")})),this}}(jsPDF.API),
+/**
+   * @license
+   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+function(jsPDFAPI){var namesOid;jsPDFAPI.events.push(["postPutResources",function(){var pdf=this,rx=/^(\d+) 0 obj$/;if(this.outline.root.children.length>0)for(var lines=pdf.outline.render().split(/\r\n/),i=0;i<lines.length;i++){var line=lines[i],m=rx.exec(line);if(null!=m){var oid=m[1];pdf.internal.newObjectDeferredBegin(oid,!1)}pdf.internal.write(line)}if(this.outline.createNamedDestinations){var totalPages=this.internal.pages.length,dests=[];for(i=0;i<totalPages;i++){var id=pdf.internal.newObject();dests.push(id);var info=pdf.internal.getPageInfo(i+1);pdf.internal.write("<< /D["+info.objId+" 0 R /XYZ null null null]>> endobj")}var names2Oid=pdf.internal.newObject();pdf.internal.write("<< /Names [ ");for(i=0;i<dests.length;i++)pdf.internal.write("(page_"+(i+1)+")"+dests[i]+" 0 R");pdf.internal.write(" ] >>","endobj"),namesOid=pdf.internal.newObject(),pdf.internal.write("<< /Dests "+names2Oid+" 0 R"),pdf.internal.write(">>","endobj")}}]),jsPDFAPI.events.push(["putCatalog",function(){this.outline.root.children.length>0&&(this.internal.write("/Outlines",this.outline.makeRef(this.outline.root)),this.outline.createNamedDestinations&&this.internal.write("/Names "+namesOid+" 0 R"))}]),jsPDFAPI.events.push(["initialized",function(){var pdf=this;pdf.outline={createNamedDestinations:!1,root:{children:[]}},pdf.outline.add=function(parent,title,options){var item={title:title,options:options,children:[]};return null==parent&&(parent=this.root),parent.children.push(item),item},pdf.outline.render=function(){return this.ctx={},this.ctx.val="",this.ctx.pdf=pdf,this.genIds_r(this.root),this.renderRoot(this.root),this.renderItems(this.root),this.ctx.val},pdf.outline.genIds_r=function(node){node.id=pdf.internal.newObjectDeferred();for(var i=0;i<node.children.length;i++)this.genIds_r(node.children[i])},pdf.outline.renderRoot=function(node){this.objStart(node),this.line("/Type /Outlines"),node.children.length>0&&(this.line("/First "+this.makeRef(node.children[0])),this.line("/Last "+this.makeRef(node.children[node.children.length-1]))),this.line("/Count "+this.count_r({count:0},node)),this.objEnd()},pdf.outline.renderItems=function(node){for(var getVerticalCoordinateString=this.ctx.pdf.internal.getVerticalCoordinateString,i=0;i<node.children.length;i++){var item=node.children[i];this.objStart(item),this.line("/Title "+this.makeString(item.title)),this.line("/Parent "+this.makeRef(node)),i>0&&this.line("/Prev "+this.makeRef(node.children[i-1])),i<node.children.length-1&&this.line("/Next "+this.makeRef(node.children[i+1])),item.children.length>0&&(this.line("/First "+this.makeRef(item.children[0])),this.line("/Last "+this.makeRef(item.children[item.children.length-1])));var count=this.count=this.count_r({count:0},item);if(count>0&&this.line("/Count "+count),item.options&&item.options.pageNumber){var info=pdf.internal.getPageInfo(item.options.pageNumber);this.line("/Dest ["+info.objId+" 0 R /XYZ 0 "+getVerticalCoordinateString(0)+" 0]")}this.objEnd()}for(var z=0;z<node.children.length;z++)this.renderItems(node.children[z])},pdf.outline.line=function(text){this.ctx.val+=text+"\r\n"},pdf.outline.makeRef=function(node){return node.id+" 0 R"},pdf.outline.makeString=function(val){return"("+pdf.internal.pdfEscape(val)+")"},pdf.outline.objStart=function(node){this.ctx.val+="\r\n"+node.id+" 0 obj\r\n<<\r\n"},pdf.outline.objEnd=function(){this.ctx.val+=">> \r\nendobj\r\n"},pdf.outline.count_r=function(ctx,node){for(var i=0;i<node.children.length;i++)ctx.count++,this.count_r(ctx,node.children[i]);return ctx.count}}])}(jsPDF.API),
+/**
+   * @license
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
    */
-function(jsPDFAPI){var clone,_DrillForContent,FontNameDB,FontStyleMap,TextAlignMap,FontWeightMap,FloatMap,ClearMap,GetCSS,PurgeWhiteSpace,Renderer,ResolveFont,ResolveUnitedNumber,UnitedNumberMap,elementHandledElsewhere,images,loadImgs,checkForFooter,process,tableToJson;clone=function(){return function(obj){return Clone.prototype=obj,new Clone};function Clone(){}}(),PurgeWhiteSpace=function(array){var fragment,i,l,lTrimmed,r,rTrimmed,trailingSpace;for(i=0,l=array.length,fragment=void 0,lTrimmed=!1,rTrimmed=!1;!lTrimmed&&i!==l;)(fragment=array[i]=array[i].trimLeft())&&(lTrimmed=!0),i++;for(i=l-1;l&&!rTrimmed&&-1!==i;)(fragment=array[i]=array[i].trimRight())&&(rTrimmed=!0),i--;for(r=/\s+$/g,trailingSpace=!0,i=0;i!==l;)"\u2028"!=array[i]&&(fragment=array[i].replace(/\s+/g," "),trailingSpace&&(fragment=fragment.trimLeft()),fragment&&(trailingSpace=r.test(fragment)),array[i]=fragment),i++;return array},ResolveFont=function(css_font_family_string){var name,part,parts;for(name=void 0,part=(parts=css_font_family_string.split(",")).shift();!name&&part;)name=FontNameDB[part.trim().toLowerCase()],part=parts.shift();return name},ResolveUnitedNumber=function(css_line_height_string){var value;return(css_line_height_string="auto"===css_line_height_string?"0px":css_line_height_string).indexOf("em")>-1&&!isNaN(Number(css_line_height_string.replace("em","")))&&(css_line_height_string=18.719*Number(css_line_height_string.replace("em",""))+"px"),css_line_height_string.indexOf("pt")>-1&&!isNaN(Number(css_line_height_string.replace("pt","")))&&(css_line_height_string=1.333*Number(css_line_height_string.replace("pt",""))+"px"),void 0,16,(value=UnitedNumberMap[css_line_height_string])?value:undefined!==(value={"xx-small":9,"x-small":11,small:13,medium:16,large:19,"x-large":23,"xx-large":28,auto:0}[css_line_height_string])||(value=parseFloat(css_line_height_string))?UnitedNumberMap[css_line_height_string]=value/16:(value=css_line_height_string.match(/([\d\.]+)(px)/),Array.isArray(value)&&3===value.length?UnitedNumberMap[css_line_height_string]=parseFloat(value[1])/16:UnitedNumberMap[css_line_height_string]=1)},GetCSS=function(element){var css,tmp,computedCSSElement,compCSS;return compCSS=function(el){return document.defaultView&&document.defaultView.getComputedStyle?document.defaultView.getComputedStyle(el,null):el.currentStyle?el.currentStyle:el.style}(element),tmp=void 0,(css={})["font-family"]=ResolveFont((computedCSSElement=function(prop){return prop=prop.replace(/-\D/g,(function(match){return match.charAt(1).toUpperCase()})),compCSS[prop]})("font-family"))||"times",css["font-style"]=FontStyleMap[computedCSSElement("font-style")]||"normal",css["text-align"]=TextAlignMap[computedCSSElement("text-align")]||"left","bold"===(tmp=FontWeightMap[computedCSSElement("font-weight")]||"normal")&&("normal"===css["font-style"]?css["font-style"]=tmp:css["font-style"]=tmp+css["font-style"]),css["font-size"]=ResolveUnitedNumber(computedCSSElement("font-size"))||1,css["line-height"]=ResolveUnitedNumber(computedCSSElement("line-height"))||1,css.display="inline"===computedCSSElement("display")?"inline":"block",tmp="block"===css.display,css["margin-top"]=tmp&&ResolveUnitedNumber(computedCSSElement("margin-top"))||0,css["margin-bottom"]=tmp&&ResolveUnitedNumber(computedCSSElement("margin-bottom"))||0,css["padding-top"]=tmp&&ResolveUnitedNumber(computedCSSElement("padding-top"))||0,css["padding-bottom"]=tmp&&ResolveUnitedNumber(computedCSSElement("padding-bottom"))||0,css["margin-left"]=tmp&&ResolveUnitedNumber(computedCSSElement("margin-left"))||0,css["margin-right"]=tmp&&ResolveUnitedNumber(computedCSSElement("margin-right"))||0,css["padding-left"]=tmp&&ResolveUnitedNumber(computedCSSElement("padding-left"))||0,css["padding-right"]=tmp&&ResolveUnitedNumber(computedCSSElement("padding-right"))||0,css["page-break-before"]=computedCSSElement("page-break-before")||"auto",css.float=FloatMap[computedCSSElement("cssFloat")]||"none",css.clear=ClearMap[computedCSSElement("clear")]||"none",css.color=computedCSSElement("color"),css},elementHandledElsewhere=function(element,renderer,elementHandlers){var handlers,i,isHandledElsewhere,l,classNames;if(isHandledElsewhere=!1,i=void 0,l=void 0,handlers=elementHandlers["#"+element.id])if("function"==typeof handlers)isHandledElsewhere=handlers(element,renderer);else for(i=0,l=handlers.length;!isHandledElsewhere&&i!==l;)isHandledElsewhere=handlers[i](element,renderer),i++;if(handlers=elementHandlers[element.nodeName],!isHandledElsewhere&&handlers)if("function"==typeof handlers)isHandledElsewhere=handlers(element,renderer);else for(i=0,l=handlers.length;!isHandledElsewhere&&i!==l;)isHandledElsewhere=handlers[i](element,renderer),i++;for(classNames="string"==typeof element.className?element.className.split(" "):[],i=0;i<classNames.length;i++)if(handlers=elementHandlers["."+classNames[i]],!isHandledElsewhere&&handlers)if("function"==typeof handlers)isHandledElsewhere=handlers(element,renderer);else for(i=0,l=handlers.length;!isHandledElsewhere&&i!==l;)isHandledElsewhere=handlers[i](element,renderer),i++;return isHandledElsewhere},tableToJson=function(table,renderer){var data,headers,i,j,rowData,tableRow,table_with,cell,l;for(data=[],headers=[],i=0,l=table.rows[0].cells.length,table_with=table.clientWidth;i<l;)cell=table.rows[0].cells[i],headers[i]={name:cell.textContent.toLowerCase().replace(/\s+/g,""),prompt:cell.textContent.replace(/\r?\n/g,""),width:cell.clientWidth/table_with*renderer.pdf.internal.pageSize.getWidth()},i++;for(i=1;i<table.rows.length;){for(tableRow=table.rows[i],rowData={},j=0;j<tableRow.cells.length;)rowData[headers[j].name]=tableRow.cells[j].textContent.replace(/\r?\n/g,""),j++;data.push(rowData),i++}return{rows:data,headers:headers}};var SkipNode={SCRIPT:1,STYLE:1,NOSCRIPT:1,OBJECT:1,EMBED:1,SELECT:1},listCount=1;_DrillForContent=function(element,renderer,elementHandlers){var cn,cns,fragmentCSS,i,isBlock,l,table2json,cb;for(cns=element.childNodes,cn=void 0,(isBlock="block"===(fragmentCSS=GetCSS(element)).display)&&(renderer.setBlockBoundary(),renderer.setBlockStyle(fragmentCSS)),i=0,l=cns.length;i<l;){if("object"===(void 0===(cn=cns[i])?"undefined":_typeof(cn))){if(renderer.executeWatchFunctions(cn),1===cn.nodeType&&"HEADER"===cn.nodeName){var header=cn,oldMarginTop=renderer.pdf.margins_doc.top;renderer.pdf.internal.events.subscribe("addPage",(function(pageInfo){renderer.y=oldMarginTop,_DrillForContent(header,renderer,elementHandlers),renderer.pdf.margins_doc.top=renderer.y+10,renderer.y+=10}),!1)}if(8===cn.nodeType&&"#comment"===cn.nodeName)~cn.textContent.indexOf("ADD_PAGE")&&(renderer.pdf.addPage(),renderer.y=renderer.pdf.margins_doc.top);else if(1!==cn.nodeType||SkipNode[cn.nodeName])if(3===cn.nodeType){var value=cn.nodeValue;if(cn.nodeValue&&"LI"===cn.parentNode.nodeName)if("OL"===cn.parentNode.parentNode.nodeName)value=listCount+++". "+value;else{var fontSize=fragmentCSS["font-size"],offsetX=(3-.75*fontSize)*renderer.pdf.internal.scaleFactor,offsetY=.75*fontSize*renderer.pdf.internal.scaleFactor,radius=1.74*fontSize/renderer.pdf.internal.scaleFactor;cb=function(x,y){this.pdf.circle(x+offsetX,y+offsetY,radius,"FD")}}16&cn.ownerDocument.body.compareDocumentPosition(cn)&&renderer.addText(value,fragmentCSS)}else"string"==typeof cn&&renderer.addText(cn,fragmentCSS);else{var cached_image;if("IMG"===cn.nodeName){var url=cn.getAttribute("src");cached_image=images[renderer.pdf.sHashCode(url)||url]}if(cached_image){renderer.pdf.internal.pageSize.getHeight()-renderer.pdf.margins_doc.bottom<renderer.y+cn.height&&renderer.y>renderer.pdf.margins_doc.top&&(renderer.pdf.addPage(),renderer.y=renderer.pdf.margins_doc.top,renderer.executeWatchFunctions(cn));var imagesCSS=GetCSS(cn),imageX=renderer.x,fontToUnitRatio=12/renderer.pdf.internal.scaleFactor,additionalSpaceLeft=(imagesCSS["margin-left"]+imagesCSS["padding-left"])*fontToUnitRatio,additionalSpaceRight=(imagesCSS["margin-right"]+imagesCSS["padding-right"])*fontToUnitRatio,additionalSpaceTop=(imagesCSS["margin-top"]+imagesCSS["padding-top"])*fontToUnitRatio,additionalSpaceBottom=(imagesCSS["margin-bottom"]+imagesCSS["padding-bottom"])*fontToUnitRatio;void 0!==imagesCSS.float&&"right"===imagesCSS.float?imageX+=renderer.settings.width-cn.width-additionalSpaceRight:imageX+=additionalSpaceLeft,renderer.pdf.addImage(cached_image,imageX,renderer.y+additionalSpaceTop,cn.width,cn.height),cached_image=void 0,"right"===imagesCSS.float||"left"===imagesCSS.float?(renderer.watchFunctions.push(function(diffX,thresholdY,diffWidth,el){return renderer.y>=thresholdY?(renderer.x+=diffX,renderer.settings.width+=diffWidth,!0):!!(el&&1===el.nodeType&&!SkipNode[el.nodeName]&&renderer.x+el.width>renderer.pdf.margins_doc.left+renderer.pdf.margins_doc.width)&&(renderer.x+=diffX,renderer.y=thresholdY,renderer.settings.width+=diffWidth,!0)}.bind(this,"left"===imagesCSS.float?-cn.width-additionalSpaceLeft-additionalSpaceRight:0,renderer.y+cn.height+additionalSpaceTop+additionalSpaceBottom,cn.width)),renderer.watchFunctions.push(function(yPositionAfterFloating,pages,el){return!(renderer.y<yPositionAfterFloating&&pages===renderer.pdf.internal.getNumberOfPages())||1===el.nodeType&&"both"===GetCSS(el).clear&&(renderer.y=yPositionAfterFloating,!0)}.bind(this,renderer.y+cn.height,renderer.pdf.internal.getNumberOfPages())),renderer.settings.width-=cn.width+additionalSpaceLeft+additionalSpaceRight,"left"===imagesCSS.float&&(renderer.x+=cn.width+additionalSpaceLeft+additionalSpaceRight)):renderer.y+=cn.height+additionalSpaceTop+additionalSpaceBottom}else if("TABLE"===cn.nodeName)table2json=tableToJson(cn,renderer),renderer.y+=10,renderer.pdf.table(renderer.x,renderer.y,table2json.rows,table2json.headers,{autoSize:!1,printHeaders:elementHandlers.printHeaders,margins:renderer.pdf.margins_doc,css:GetCSS(cn)}),renderer.y=renderer.pdf.lastCellPos.y+renderer.pdf.lastCellPos.h+20;else if("OL"===cn.nodeName||"UL"===cn.nodeName)listCount=1,elementHandledElsewhere(cn,renderer,elementHandlers)||_DrillForContent(cn,renderer,elementHandlers),renderer.y+=10;else if("LI"===cn.nodeName){var temp=renderer.x;renderer.x+=20/renderer.pdf.internal.scaleFactor,renderer.y+=3,elementHandledElsewhere(cn,renderer,elementHandlers)||_DrillForContent(cn,renderer,elementHandlers),renderer.x=temp}else"BR"===cn.nodeName?(renderer.y+=fragmentCSS["font-size"]*renderer.pdf.internal.scaleFactor,renderer.addText("\u2028",clone(fragmentCSS))):elementHandledElsewhere(cn,renderer,elementHandlers)||_DrillForContent(cn,renderer,elementHandlers)}}i++}if(elementHandlers.outY=renderer.y,isBlock)return renderer.setBlockBoundary(cb)},images={},loadImgs=function(element,renderer,elementHandlers,cb){var found_images,imgs=element.getElementsByTagName("img"),l=imgs.length,x=0;function done(){renderer.pdf.internal.events.publish("imagesLoaded"),cb(found_images)}function loadImage(url,width,height){if(url){var img=new Image;found_images=++x,img.crossOrigin="",img.onerror=img.onload=function(){if(img.complete&&(0===img.src.indexOf("data:image/")&&(img.width=width||img.width||0,img.height=height||img.height||0),img.width+img.height)){var hash=renderer.pdf.sHashCode(url)||url;images[hash]=images[hash]||img}--x||done()},img.src=url}}for(;l--;)loadImage(imgs[l].getAttribute("src"),imgs[l].width,imgs[l].height);return x||done()},checkForFooter=function(elem,renderer,elementHandlers){var footer=elem.getElementsByTagName("footer");if(footer.length>0){footer=footer[0];var oldOut=renderer.pdf.internal.write,oldY=renderer.y;renderer.pdf.internal.write=function(){},_DrillForContent(footer,renderer,elementHandlers);var footerHeight=Math.ceil(renderer.y-oldY)+5;renderer.y=oldY,renderer.pdf.internal.write=oldOut,renderer.pdf.margins_doc.bottom+=footerHeight;for(var renderFooter=function(pageInfo){var pageNumber=void 0!==pageInfo?pageInfo.pageNumber:1,oldPosition=renderer.y;renderer.y=renderer.pdf.internal.pageSize.getHeight()-renderer.pdf.margins_doc.bottom,renderer.pdf.margins_doc.bottom-=footerHeight;for(var spans=footer.getElementsByTagName("span"),i=0;i<spans.length;++i)(" "+spans[i].className+" ").replace(/[\n\t]/g," ").indexOf(" pageCounter ")>-1&&(spans[i].innerHTML=pageNumber),(" "+spans[i].className+" ").replace(/[\n\t]/g," ").indexOf(" totalPages ")>-1&&(spans[i].innerHTML="###jsPDFVarTotalPages###");_DrillForContent(footer,renderer,elementHandlers),renderer.pdf.margins_doc.bottom+=footerHeight,renderer.y=oldPosition},spans=footer.getElementsByTagName("span"),i=0;i<spans.length;++i)(" "+spans[i].className+" ").replace(/[\n\t]/g," ").indexOf(" totalPages ")>-1&&renderer.pdf.internal.events.subscribe("htmlRenderingFinished",renderer.pdf.putTotalPages.bind(renderer.pdf,"###jsPDFVarTotalPages###"),!0);renderer.pdf.internal.events.subscribe("addPage",renderFooter,!1),renderFooter(),SkipNode.FOOTER=1}},process=function(pdf,element,x,y,settings,callback){if(!element)return!1;"string"==typeof element||element.parentNode||(element=""+element.innerHTML),"string"==typeof element&&(element=function(element){var $frame,$hiddendiv,framename;return framename="jsPDFhtmlText"+Date.now().toString()+(1e3*Math.random()).toFixed(0),"position: absolute !important;clip: rect(1px 1px 1px 1px); /* IE6, IE7 */clip: rect(1px, 1px, 1px, 1px);padding:0 !important;border:0 !important;height: 1px !important;width: 1px !important; top:auto;left:-100px;overflow: hidden;",($hiddendiv=document.createElement("div")).style.cssText="position: absolute !important;clip: rect(1px 1px 1px 1px); /* IE6, IE7 */clip: rect(1px, 1px, 1px, 1px);padding:0 !important;border:0 !important;height: 1px !important;width: 1px !important; top:auto;left:-100px;overflow: hidden;",$hiddendiv.innerHTML='<iframe style="height:1px;width:1px" name="'+framename+'" />',document.body.appendChild($hiddendiv),($frame=window.frames[framename]).document.open(),$frame.document.writeln(element),$frame.document.close(),$frame.document.body}(element.replace(/<\/?script[^>]*?>/gi,"")));var out,r=new Renderer(pdf,x,y,settings);return loadImgs.call(this,element,r,settings.elementHandlers,(function(found_images){checkForFooter(element,r,settings.elementHandlers),_DrillForContent(element,r,settings.elementHandlers),r.pdf.internal.events.publish("htmlRenderingFinished"),out=r.dispose(),"function"==typeof callback?callback(out):found_images&&console.error("jsPDF Warning: rendering issues? provide a callback to fromHTML!")})),out||{x:r.x,y:r.y}},(Renderer=function(pdf,x,y,settings){return this.pdf=pdf,this.x=x,this.y=y,this.settings=settings,this.watchFunctions=[],this.init(),this}).prototype.init=function(){return this.paragraph={text:[],style:[]},this.pdf.internal.write("q")},Renderer.prototype.dispose=function(){return this.pdf.internal.write("Q"),{x:this.x,y:this.y,ready:!0}},Renderer.prototype.executeWatchFunctions=function(el){var ret=!1,narray=[];if(this.watchFunctions.length>0){for(var i=0;i<this.watchFunctions.length;++i)!0===this.watchFunctions[i](el)?ret=!0:narray.push(this.watchFunctions[i]);this.watchFunctions=narray}return ret},Renderer.prototype.splitFragmentsIntoLines=function(fragments,styles){var currentLineLength,ff,fontMetrics,fontMetricsCache,fragment,fragmentChopped,fragmentLength,fragmentSpecificMetrics,fs,k,line,lines,maxLineLength,style;for(12,k=this.pdf.internal.scaleFactor,fontMetricsCache={},ff=void 0,fs=void 0,fontMetrics=void 0,fragment=void 0,style=void 0,fragmentSpecificMetrics=void 0,fragmentLength=void 0,fragmentChopped=void 0,lines=[line=[]],currentLineLength=0,maxLineLength=this.settings.width;fragments.length;)if(fragment=fragments.shift(),style=styles.shift(),fragment)if((fontMetrics=fontMetricsCache[(ff=style["font-family"])+(fs=style["font-style"])])||(fontMetrics=this.pdf.internal.getFont(ff,fs).metadata.Unicode,fontMetricsCache[ff+fs]=fontMetrics),fragmentSpecificMetrics={widths:fontMetrics.widths,kerning:fontMetrics.kerning,fontSize:12*style["font-size"],textIndent:currentLineLength},fragmentLength=this.pdf.getStringUnitWidth(fragment,fragmentSpecificMetrics)*fragmentSpecificMetrics.fontSize/k,"\u2028"==fragment)line=[],lines.push(line);else if(currentLineLength+fragmentLength>maxLineLength){for(fragmentChopped=this.pdf.splitTextToSize(fragment,maxLineLength,fragmentSpecificMetrics),line.push([fragmentChopped.shift(),style]);fragmentChopped.length;)line=[[fragmentChopped.shift(),style]],lines.push(line);currentLineLength=this.pdf.getStringUnitWidth(line[0][0],fragmentSpecificMetrics)*fragmentSpecificMetrics.fontSize/k}else line.push([fragment,style]),currentLineLength+=fragmentLength;if(void 0!==style["text-align"]&&("center"===style["text-align"]||"right"===style["text-align"]||"justify"===style["text-align"]))for(var i=0;i<lines.length;++i){var length=this.pdf.getStringUnitWidth(lines[i][0][0],fragmentSpecificMetrics)*fragmentSpecificMetrics.fontSize/k;i>0&&(lines[i][0][1]=clone(lines[i][0][1]));var space=maxLineLength-length;if("right"===style["text-align"])lines[i][0][1]["margin-left"]=space;else if("center"===style["text-align"])lines[i][0][1]["margin-left"]=space/2;else if("justify"===style["text-align"]){var countSpaces=lines[i][0][0].split(" ").length-1;lines[i][0][1]["word-spacing"]=space/countSpaces,i===lines.length-1&&(lines[i][0][1]["word-spacing"]=0)}}return lines},Renderer.prototype.RenderTextFragment=function(text,style){var font,maxLineHeight;maxLineHeight=0,this.pdf.internal.pageSize.getHeight()-this.pdf.margins_doc.bottom<this.y+this.pdf.internal.getFontSize()&&(this.pdf.internal.write("ET","Q"),this.pdf.addPage(),this.y=this.pdf.margins_doc.top,this.pdf.internal.write("q","BT",this.getPdfColor(style.color),this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td"),maxLineHeight=Math.max(maxLineHeight,style["line-height"],style["font-size"]),this.pdf.internal.write(0,(-12*maxLineHeight).toFixed(2),"Td")),font=this.pdf.internal.getFont(style["font-family"],style["font-style"]);var pdfTextColor=this.getPdfColor(style.color);pdfTextColor!==this.lastTextColor&&(this.pdf.internal.write(pdfTextColor),this.lastTextColor=pdfTextColor),void 0!==style["word-spacing"]&&style["word-spacing"]>0&&this.pdf.internal.write(style["word-spacing"].toFixed(2),"Tw"),this.pdf.internal.write("/"+font.id,(12*style["font-size"]).toFixed(2),"Tf","("+this.pdf.internal.pdfEscape(text)+") Tj"),void 0!==style["word-spacing"]&&this.pdf.internal.write(0,"Tw")},Renderer.prototype.getPdfColor=function(style){var r,g,b,rgbColor=new RGBColor(style),m=/rgb\s*\(\s*(\d+),\s*(\d+),\s*(\d+\s*)\)/.exec(style);if(null!=m?(r=parseInt(m[1]),g=parseInt(m[2]),b=parseInt(m[3])):("#"!=style.charAt(0)&&(style=rgbColor.ok?rgbColor.toHex():"#000000"),r=style.substring(1,3),r=parseInt(r,16),g=style.substring(3,5),g=parseInt(g,16),b=style.substring(5,7),b=parseInt(b,16)),"string"==typeof r&&/^#[0-9A-Fa-f]{6}$/.test(r)){var hex=parseInt(r.substr(1),16);r=hex>>16&255,g=hex>>8&255,b=255&hex}var f3=this.f3;return 0===r&&0===g&&0===b||void 0===g?f3(r/255)+" g":[f3(r/255),f3(g/255),f3(b/255),"rg"].join(" ")},Renderer.prototype.f3=function(number){return number.toFixed(3)},Renderer.prototype.renderParagraph=function(cb){var blockstyle,fontToUnitRatio,fragments,i,l,line,lines,maxLineHeight,out,paragraphspacing_after,paragraphspacing_before,styles,fontSize;if(fragments=PurgeWhiteSpace(this.paragraph.text),styles=this.paragraph.style,blockstyle=this.paragraph.blockstyle,this.paragraph.priorblockstyle||{},this.paragraph={text:[],style:[],blockstyle:{},priorblockstyle:blockstyle},fragments.join("").trim()){lines=this.splitFragmentsIntoLines(fragments,styles),line=void 0,maxLineHeight=void 0,12,fontToUnitRatio=12/this.pdf.internal.scaleFactor,this.priorMarginBottom=this.priorMarginBottom||0,paragraphspacing_before=(Math.max((blockstyle["margin-top"]||0)-this.priorMarginBottom,0)+(blockstyle["padding-top"]||0))*fontToUnitRatio,paragraphspacing_after=((blockstyle["margin-bottom"]||0)+(blockstyle["padding-bottom"]||0))*fontToUnitRatio,this.priorMarginBottom=blockstyle["margin-bottom"]||0,"always"===blockstyle["page-break-before"]&&(this.pdf.addPage(),this.y=0,paragraphspacing_before=((blockstyle["margin-top"]||0)+(blockstyle["padding-top"]||0))*fontToUnitRatio),out=this.pdf.internal.write,i=void 0,l=void 0,this.y+=paragraphspacing_before,out("q","BT 0 g",this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td");for(var currentIndent=0;lines.length;){for(maxLineHeight=0,i=0,l=(line=lines.shift()).length;i!==l;)line[i][0].trim()&&(maxLineHeight=Math.max(maxLineHeight,line[i][1]["line-height"],line[i][1]["font-size"]),fontSize=7*line[i][1]["font-size"]),i++;var indentMove=0,wantedIndent=0;for(void 0!==line[0][1]["margin-left"]&&line[0][1]["margin-left"]>0&&(indentMove=(wantedIndent=this.pdf.internal.getCoordinateString(line[0][1]["margin-left"]))-currentIndent,currentIndent=wantedIndent),out(indentMove+Math.max(blockstyle["margin-left"]||0,0)*fontToUnitRatio,(-12*maxLineHeight).toFixed(2),"Td"),i=0,l=line.length;i!==l;)line[i][0]&&this.RenderTextFragment(line[i][0],line[i][1]),i++;if(this.y+=maxLineHeight*fontToUnitRatio,this.executeWatchFunctions(line[0][1])&&lines.length>0){var localFragments=[],localStyles=[];lines.forEach((function(localLine){for(var i=0,l=localLine.length;i!==l;)localLine[i][0]&&(localFragments.push(localLine[i][0]+" "),localStyles.push(localLine[i][1])),++i})),lines=this.splitFragmentsIntoLines(PurgeWhiteSpace(localFragments),localStyles),out("ET","Q"),out("q","BT 0 g",this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td")}}return cb&&"function"==typeof cb&&cb.call(this,this.x-9,this.y-fontSize/2),out("ET","Q"),this.y+=paragraphspacing_after}},Renderer.prototype.setBlockBoundary=function(cb){return this.renderParagraph(cb)},Renderer.prototype.setBlockStyle=function(css){return this.paragraph.blockstyle=css},Renderer.prototype.addText=function(text,css){return this.paragraph.text.push(text),this.paragraph.style.push(css)},FontNameDB={helvetica:"helvetica","sans-serif":"helvetica","times new roman":"times",serif:"times",times:"times",monospace:"courier",courier:"courier"},FontWeightMap={100:"normal",200:"normal",300:"normal",400:"normal",500:"bold",600:"bold",700:"bold",800:"bold",900:"bold",normal:"normal",bold:"bold",bolder:"bold",lighter:"normal"},FontStyleMap={normal:"normal",italic:"italic",oblique:"italic"},TextAlignMap={left:"left",right:"right",center:"center",justify:"justify"},FloatMap={none:"none",right:"right",left:"left"},ClearMap={none:"none",both:"both"},UnitedNumberMap={normal:1},jsPDFAPI.fromHTML=function(HTML,x,y,settings,callback,margins){return this.margins_doc=margins||{top:0,bottom:0},settings||(settings={}),settings.elementHandlers||(settings.elementHandlers={}),process(this,HTML,isNaN(x)?4:x,isNaN(y)?4:y,settings,callback)}}(jsPDF.API),function(jsPDFAPI){var jsNamesObj,jsJsObj,text;jsPDFAPI.addJS=function(txt){return text=txt,this.internal.events.subscribe("postPutResources",(function(txt){jsNamesObj=this.internal.newObject(),this.internal.out("<<"),this.internal.out("/Names [(EmbeddedJS) "+(jsNamesObj+1)+" 0 R]"),this.internal.out(">>"),this.internal.out("endobj"),jsJsObj=this.internal.newObject(),this.internal.out("<<"),this.internal.out("/S /JavaScript"),this.internal.out("/JS ("+text+")"),this.internal.out(">>"),this.internal.out("endobj")})),this.internal.events.subscribe("putCatalog",(function(){void 0!==jsNamesObj&&void 0!==jsJsObj&&this.internal.out("/Names <</JavaScript "+jsNamesObj+" 0 R>>")})),this}}(jsPDF.API),function(jsPDFAPI){jsPDFAPI.events.push(["postPutResources",function(){var pdf=this,rx=/^(\d+) 0 obj$/;if(this.outline.root.children.length>0)for(var lines=pdf.outline.render().split(/\r\n/),i=0;i<lines.length;i++){var line=lines[i],m=rx.exec(line);if(null!=m){var oid=m[1];pdf.internal.newObjectDeferredBegin(oid)}pdf.internal.write(line)}if(this.outline.createNamedDestinations){var totalPages=this.internal.pages.length,dests=[];for(i=0;i<totalPages;i++){var id=pdf.internal.newObject();dests.push(id);var info=pdf.internal.getPageInfo(i+1);pdf.internal.write("<< /D["+info.objId+" 0 R /XYZ null null null]>> endobj")}var names2Oid=pdf.internal.newObject();pdf.internal.write("<< /Names [ ");for(i=0;i<dests.length;i++)pdf.internal.write("(page_"+(i+1)+")"+dests[i]+" 0 R");pdf.internal.write(" ] >>","endobj");pdf.internal.newObject();pdf.internal.write("<< /Dests "+names2Oid+" 0 R"),pdf.internal.write(">>","endobj")}}]),jsPDFAPI.events.push(["putCatalog",function(){this.outline.root.children.length>0&&(this.internal.write("/Outlines",this.outline.makeRef(this.outline.root)),this.outline.createNamedDestinations&&this.internal.write("/Names "+namesOid+" 0 R"))}]),jsPDFAPI.events.push(["initialized",function(){var pdf=this;pdf.outline={createNamedDestinations:!1,root:{children:[]}},pdf.outline.add=function(parent,title,options){var item={title:title,options:options,children:[]};return null==parent&&(parent=this.root),parent.children.push(item),item},pdf.outline.render=function(){return this.ctx={},this.ctx.val="",this.ctx.pdf=pdf,this.genIds_r(this.root),this.renderRoot(this.root),this.renderItems(this.root),this.ctx.val},pdf.outline.genIds_r=function(node){node.id=pdf.internal.newObjectDeferred();for(var i=0;i<node.children.length;i++)this.genIds_r(node.children[i])},pdf.outline.renderRoot=function(node){this.objStart(node),this.line("/Type /Outlines"),node.children.length>0&&(this.line("/First "+this.makeRef(node.children[0])),this.line("/Last "+this.makeRef(node.children[node.children.length-1]))),this.line("/Count "+this.count_r({count:0},node)),this.objEnd()},pdf.outline.renderItems=function(node){for(var i=0;i<node.children.length;i++){var item=node.children[i];this.objStart(item),this.line("/Title "+this.makeString(item.title)),this.line("/Parent "+this.makeRef(node)),i>0&&this.line("/Prev "+this.makeRef(node.children[i-1])),i<node.children.length-1&&this.line("/Next "+this.makeRef(node.children[i+1])),item.children.length>0&&(this.line("/First "+this.makeRef(item.children[0])),this.line("/Last "+this.makeRef(item.children[item.children.length-1])));var count=this.count=this.count_r({count:0},item);if(count>0&&this.line("/Count "+count),item.options&&item.options.pageNumber){var info=pdf.internal.getPageInfo(item.options.pageNumber);this.line("/Dest ["+info.objId+" 0 R /XYZ 0 "+this.ctx.pdf.internal.pageSize.getHeight()*this.ctx.pdf.internal.scaleFactor+" 0]")}this.objEnd()}for(i=0;i<node.children.length;i++){item=node.children[i];this.renderItems(item)}},pdf.outline.line=function(text){this.ctx.val+=text+"\r\n"},pdf.outline.makeRef=function(node){return node.id+" 0 R"},pdf.outline.makeString=function(val){return"("+pdf.internal.pdfEscape(val)+")"},pdf.outline.objStart=function(node){this.ctx.val+="\r\n"+node.id+" 0 obj\r\n<<\r\n"},pdf.outline.objEnd=function(node){this.ctx.val+=">> \r\nendobj\r\n"},pdf.outline.count_r=function(ctx,node){for(var i=0;i<node.children.length;i++)ctx.count++,this.count_r(ctx,node.children[i]);return ctx.count}}])}(jsPDF.API),
-/**@preserve
-   *  ====================================================================
-   * jsPDF PNG PlugIn
+function(jsPDFAPI){var markers=[192,193,194,195,196,197,198,199];jsPDFAPI.processJPEG=function(data,index,alias,compression,dataAsBinaryString,colorSpace){var dims,filter=this.decode.DCT_DECODE,result=null;if("string"==typeof data||this.__addimage__.isArrayBuffer(data)||this.__addimage__.isArrayBufferView(data)){switch(data=dataAsBinaryString||data,data=this.__addimage__.isArrayBuffer(data)?new Uint8Array(data):data,dims=function(imgData){for(var height,blockLength=256*imgData.charCodeAt(4)+imgData.charCodeAt(5),len=imgData.length,result={width:0,height:0,numcomponents:1},i=4;i<len;i+=2){if(i+=blockLength,-1!==markers.indexOf(imgData.charCodeAt(i+1))){height=256*imgData.charCodeAt(i+5)+imgData.charCodeAt(i+6),result={width:256*imgData.charCodeAt(i+7)+imgData.charCodeAt(i+8),height:height,numcomponents:imgData.charCodeAt(i+9)};break}blockLength=256*imgData.charCodeAt(i+2)+imgData.charCodeAt(i+3)}return result}(data=this.__addimage__.isArrayBufferView(data)?this.__addimage__.arrayBufferToBinaryString(data):data),dims.numcomponents){case 1:colorSpace=this.color_spaces.DEVICE_GRAY;break;case 4:colorSpace=this.color_spaces.DEVICE_CMYK;break;case 3:colorSpace=this.color_spaces.DEVICE_RGB}result={data:data,width:dims.width,height:dims.height,colorSpace:colorSpace,bitsPerComponent:8,filter:filter,index:index,alias:alias}}return result}}(jsPDF.API);var API,getCharWidthsArray,getStringUnitWidth,splitLongWord,splitParagraphIntoLines,PNG=function(){var makeImage,scratchCanvas,scratchCtx;function PNG(data){var chunkSize,colors,palLen,delayDen,delayNum,frame,index,key,section,palShort,text,_i,_j,_ref;for(this.data=data,this.pos=8,this.palette=[],this.imgData=[],this.transparency={},this.animation=null,this.text={},frame=null;;){switch(chunkSize=this.readUInt32(),section=function(){var _i,_results;for(_results=[],_i=0;_i<4;++_i)_results.push(String.fromCharCode(this.data[this.pos++]));return _results}.call(this).join(""),section){case"IHDR":this.width=this.readUInt32(),this.height=this.readUInt32(),this.bits=this.data[this.pos++],this.colorType=this.data[this.pos++],this.compressionMethod=this.data[this.pos++],this.filterMethod=this.data[this.pos++],this.interlaceMethod=this.data[this.pos++];break;case"acTL":this.animation={numFrames:this.readUInt32(),numPlays:this.readUInt32()||1/0,frames:[]};break;case"PLTE":this.palette=this.read(chunkSize);break;case"fcTL":frame&&this.animation.frames.push(frame),this.pos+=4,frame={width:this.readUInt32(),height:this.readUInt32(),xOffset:this.readUInt32(),yOffset:this.readUInt32()},delayNum=this.readUInt16(),delayDen=this.readUInt16()||100,frame.delay=1e3*delayNum/delayDen,frame.disposeOp=this.data[this.pos++],frame.blendOp=this.data[this.pos++],frame.data=[];break;case"IDAT":case"fdAT":for("fdAT"===section&&(this.pos+=4,chunkSize-=4),data=(null!=frame?frame.data:void 0)||this.imgData,_i=0;0<=chunkSize?_i<chunkSize:_i>chunkSize;0<=chunkSize?++_i:--_i)data.push(this.data[this.pos++]);break;case"tRNS":switch(this.transparency={},this.colorType){case 3:if(palLen=this.palette.length/3,this.transparency.indexed=this.read(chunkSize),this.transparency.indexed.length>palLen)throw new Error("More transparent colors than palette size");if((palShort=palLen-this.transparency.indexed.length)>0)for(_j=0;0<=palShort?_j<palShort:_j>palShort;0<=palShort?++_j:--_j)this.transparency.indexed.push(255);break;case 0:this.transparency.grayscale=this.read(chunkSize)[0];break;case 2:this.transparency.rgb=this.read(chunkSize)}break;case"tEXt":index=(text=this.read(chunkSize)).indexOf(0),key=String.fromCharCode.apply(String,text.slice(0,index)),this.text[key]=String.fromCharCode.apply(String,text.slice(index+1));break;case"IEND":return frame&&this.animation.frames.push(frame),this.colors=function(){switch(this.colorType){case 0:case 3:case 4:return 1;case 2:case 6:return 3}}.call(this),this.hasAlphaChannel=4===(_ref=this.colorType)||6===_ref,colors=this.colors+(this.hasAlphaChannel?1:0),this.pixelBitlength=this.bits*colors,this.colorSpace=function(){switch(this.colors){case 1:return"DeviceGray";case 3:return"DeviceRGB"}}.call(this),void(this.imgData=new Uint8Array(this.imgData));default:this.pos+=chunkSize}if(this.pos+=4,this.pos>this.data.length)throw new Error("Incomplete or corrupt PNG file")}}PNG.prototype.read=function(bytes){var _i,_results;for(_results=[],_i=0;0<=bytes?_i<bytes:_i>bytes;0<=bytes?++_i:--_i)_results.push(this.data[this.pos++]);return _results},PNG.prototype.readUInt32=function(){return this.data[this.pos++]<<24|this.data[this.pos++]<<16|this.data[this.pos++]<<8|this.data[this.pos++]},PNG.prototype.readUInt16=function(){return this.data[this.pos++]<<8|this.data[this.pos++]},PNG.prototype.decodePixels=function(data){var pixelBytes=this.pixelBitlength/8,fullPixels=new Uint8Array(this.width*this.height*pixelBytes),pos=0,_this=this;if(null==data&&(data=this.imgData),0===data.length)return new Uint8Array(0);function pass(x0,y0,dx,dy){var abyte,c,col,i,left,length,p,pa,paeth,pb,pc,pixels,row,scanlineLength,upper,upperLeft,_i,_j,_k,_l,_m,w=Math.ceil((_this.width-x0)/dx),h=Math.ceil((_this.height-y0)/dy),isFull=_this.width==w&&_this.height==h;for(scanlineLength=pixelBytes*w,pixels=isFull?fullPixels:new Uint8Array(scanlineLength*h),length=data.length,row=0,c=0;row<h&&pos<length;){switch(data[pos++]){case 0:for(i=_i=0;_i<scanlineLength;i=_i+=1)pixels[c++]=data[pos++];break;case 1:for(i=_j=0;_j<scanlineLength;i=_j+=1)abyte=data[pos++],left=i<pixelBytes?0:pixels[c-pixelBytes],pixels[c++]=(abyte+left)%256;break;case 2:for(i=_k=0;_k<scanlineLength;i=_k+=1)abyte=data[pos++],col=(i-i%pixelBytes)/pixelBytes,upper=row&&pixels[(row-1)*scanlineLength+col*pixelBytes+i%pixelBytes],pixels[c++]=(upper+abyte)%256;break;case 3:for(i=_l=0;_l<scanlineLength;i=_l+=1)abyte=data[pos++],col=(i-i%pixelBytes)/pixelBytes,left=i<pixelBytes?0:pixels[c-pixelBytes],upper=row&&pixels[(row-1)*scanlineLength+col*pixelBytes+i%pixelBytes],pixels[c++]=(abyte+Math.floor((left+upper)/2))%256;break;case 4:for(i=_m=0;_m<scanlineLength;i=_m+=1)abyte=data[pos++],col=(i-i%pixelBytes)/pixelBytes,left=i<pixelBytes?0:pixels[c-pixelBytes],0===row?upper=upperLeft=0:(upper=pixels[(row-1)*scanlineLength+col*pixelBytes+i%pixelBytes],upperLeft=col&&pixels[(row-1)*scanlineLength+(col-1)*pixelBytes+i%pixelBytes]),p=left+upper-upperLeft,pa=Math.abs(p-left),pb=Math.abs(p-upper),pc=Math.abs(p-upperLeft),paeth=pa<=pb&&pa<=pc?left:pb<=pc?upper:upperLeft,pixels[c++]=(abyte+paeth)%256;break;default:throw new Error("Invalid filter algorithm: "+data[pos-1])}if(!isFull){var fullPos=((y0+row*dy)*_this.width+x0)*pixelBytes,partPos=row*scanlineLength;for(i=0;i<w;i+=1){for(var j=0;j<pixelBytes;j+=1)fullPixels[fullPos++]=pixels[partPos++];fullPos+=(dx-1)*pixelBytes}}row++}}return data=unzlibSync(data),1==_this.interlaceMethod?(pass(0,0,8,8),pass(4,0,8,8),pass(0,4,4,8),pass(2,0,4,4),pass(0,2,2,4),pass(1,0,2,2),pass(0,1,1,2)):pass(0,0,1,1),fullPixels},PNG.prototype.decodePalette=function(){var c,i,palette,pos,ret,transparency,_i,_ref,_ref1;for(palette=this.palette,transparency=this.transparency.indexed||[],ret=new Uint8Array((transparency.length||0)+palette.length),pos=0,c=0,i=_i=0,_ref=palette.length;_i<_ref;i=_i+=3)ret[pos++]=palette[i],ret[pos++]=palette[i+1],ret[pos++]=palette[i+2],ret[pos++]=null!=(_ref1=transparency[c++])?_ref1:255;return ret},PNG.prototype.copyToImageData=function(imageData,pixels){var alpha,colors,data,i,input,j,k,length,palette,v,_ref;if(colors=this.colors,palette=null,alpha=this.hasAlphaChannel,this.palette.length&&(palette=null!=(_ref=this._decodedPalette)?_ref:this._decodedPalette=this.decodePalette(),colors=4,alpha=!0),length=(data=imageData.data||imageData).length,input=palette||pixels,i=j=0,1===colors)for(;i<length;)k=palette?4*pixels[i/4]:j,v=input[k++],data[i++]=v,data[i++]=v,data[i++]=v,data[i++]=alpha?input[k++]:255,j=k;else for(;i<length;)k=palette?4*pixels[i/4]:j,data[i++]=input[k++],data[i++]=input[k++],data[i++]=input[k++],data[i++]=alpha?input[k++]:255,j=k},PNG.prototype.decode=function(){var ret;return ret=new Uint8Array(this.width*this.height*4),this.copyToImageData(ret,this.decodePixels()),ret};var hasBrowserCanvas=function(){if("[object Window]"===Object.prototype.toString.call(globalObject)){try{scratchCanvas=globalObject.document.createElement("canvas"),scratchCtx=scratchCanvas.getContext("2d")}catch(e){return!1}return!0}return!1};return hasBrowserCanvas(),makeImage=function(imageData){var img;if(!0===hasBrowserCanvas())return scratchCtx.width=imageData.width,scratchCtx.height=imageData.height,scratchCtx.clearRect(0,0,imageData.width,imageData.height),scratchCtx.putImageData(imageData,0,0),(img=new Image).src=scratchCanvas.toDataURL(),img;throw new Error("This method requires a Browser with Canvas-capability.")},PNG.prototype.decodeFrames=function(ctx){var frame,i,imageData,pixels,_i,_len,_ref,_results;if(this.animation){for(_results=[],i=_i=0,_len=(_ref=this.animation.frames).length;_i<_len;i=++_i)frame=_ref[i],imageData=ctx.createImageData(frame.width,frame.height),pixels=this.decodePixels(new Uint8Array(frame.data)),this.copyToImageData(imageData,pixels),frame.imageData=imageData,_results.push(frame.image=makeImage(imageData));return _results}},PNG.prototype.renderFrame=function(ctx,number){var frame,frames,prev;return frame=(frames=this.animation.frames)[number],prev=frames[number-1],0===number&&ctx.clearRect(0,0,this.width,this.height),1===(null!=prev?prev.disposeOp:void 0)?ctx.clearRect(prev.xOffset,prev.yOffset,prev.width,prev.height):2===(null!=prev?prev.disposeOp:void 0)&&ctx.putImageData(prev.imageData,prev.xOffset,prev.yOffset),0===frame.blendOp&&ctx.clearRect(frame.xOffset,frame.yOffset,frame.width,frame.height),ctx.drawImage(frame.image,frame.xOffset,frame.yOffset)},PNG.prototype.animate=function(ctx){var _doFrame,frameNumber,frames,numFrames,numPlays,_ref,_this=this;return frameNumber=0,_ref=this.animation,numFrames=_ref.numFrames,frames=_ref.frames,numPlays=_ref.numPlays,(_doFrame=function(){var f,frame;if(f=frameNumber++%numFrames,frame=frames[f],_this.renderFrame(ctx,f),numFrames>1&&frameNumber/numFrames<numPlays)return _this.animation._timeout=setTimeout(_doFrame,frame.delay)})()},PNG.prototype.stopAnimation=function(){var _ref;return clearTimeout(null!=(_ref=this.animation)?_ref._timeout:void 0)},PNG.prototype.render=function(canvas){var ctx,data;return canvas._png&&canvas._png.stopAnimation(),canvas._png=this,canvas.width=this.width,canvas.height=this.height,ctx=canvas.getContext("2d"),this.animation?(this.decodeFrames(ctx),this.animate(ctx)):(data=ctx.createImageData(this.width,this.height),this.copyToImageData(data,this.decodePixels()),ctx.putImageData(data,0,0))},PNG}();
+/**
+   * @license
+   *
    * Copyright (c) 2014 James Robb, https://github.com/jamesbrobb
    *
-   * 
+   * Permission is hereby granted, free of charge, to any person obtaining
+   * a copy of this software and associated documentation files (the
+   * "Software"), to deal in the Software without restriction, including
+   * without limitation the rights to use, copy, modify, merge, publish,
+   * distribute, sublicense, and/or sell copies of the Software, and to
+   * permit persons to whom the Software is furnished to do so, subject to
+   * the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be
+   * included in all copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    * ====================================================================
    */
-function(jsPDFAPI){var hasCompressionJS=function(){var inst="function"==typeof Deflater;if(!inst)throw new Error("requires deflate.js for compression");return inst},compressBytes=function(bytes,lineLength,colorsPerPixel,compression){var level=5,filter_method=filterUp;switch(compression){case jsPDFAPI.image_compression.FAST:level=3,filter_method=filterSub;break;case jsPDFAPI.image_compression.MEDIUM:level=6,filter_method=filterAverage;break;case jsPDFAPI.image_compression.SLOW:level=9,filter_method=filterPaeth}bytes=applyPngFilterMethod(bytes,lineLength,colorsPerPixel,filter_method);var header=new Uint8Array(createZlibHeader(level)),checksum=adler32(bytes),deflate=new Deflater(level),a=deflate.append(bytes),cBytes=deflate.flush(),len=header.length+a.length+cBytes.length,cmpd=new Uint8Array(len+4);return cmpd.set(header),cmpd.set(a,header.length),cmpd.set(cBytes,header.length+a.length),cmpd[len++]=checksum>>>24&255,cmpd[len++]=checksum>>>16&255,cmpd[len++]=checksum>>>8&255,cmpd[len++]=255&checksum,jsPDFAPI.arrayBufferToBinaryString(cmpd)},createZlibHeader=function(bytes,level){var cmf=Math.LOG2E*Math.log(32768)-8<<4|8,hdr=cmf<<8;return hdr|=Math.min(3,(level-1&255)>>1)<<6,hdr|=0,[cmf,255&(hdr+=31-hdr%31)]},adler32=function(array,param){for(var tlen,s1=1,s2=0,len=array.length,i=0;len>0;){len-=tlen=len>param?param:len;do{s2+=s1+=array[i++]}while(--tlen);s1%=65521,s2%=65521}return(s2<<16|s1)>>>0},applyPngFilterMethod=function(bytes,lineLength,colorsPerPixel,filter_method){for(var line,prevLine,offset,lines=bytes.length/lineLength,result=new Uint8Array(bytes.length+lines),filter_methods=getFilterMethods(),i=0;i<lines;i++){if(offset=i*lineLength,line=bytes.subarray(offset,offset+lineLength),filter_method)result.set(filter_method(line,colorsPerPixel,prevLine),offset+i);else{for(var j=0,len=filter_methods.length,results=[];j<len;j++)results[j]=filter_methods[j](line,colorsPerPixel,prevLine);var ind=getIndexOfSmallestSum(results.concat());result.set(results[ind],offset+i)}prevLine=line}return result},filterNone=function(line,colorsPerPixel,prevLine){var result=Array.apply([],line);return result.unshift(0),result},filterSub=function(line,colorsPerPixel,prevLine){var left,result=[],i=0,len=line.length;for(result[0]=1;i<len;i++)left=line[i-colorsPerPixel]||0,result[i+1]=line[i]-left+256&255;return result},filterUp=function(line,colorsPerPixel,prevLine){var up,result=[],i=0,len=line.length;for(result[0]=2;i<len;i++)up=prevLine&&prevLine[i]||0,result[i+1]=line[i]-up+256&255;return result},filterAverage=function(line,colorsPerPixel,prevLine){var left,up,result=[],i=0,len=line.length;for(result[0]=3;i<len;i++)left=line[i-colorsPerPixel]||0,up=prevLine&&prevLine[i]||0,result[i+1]=line[i]+256-(left+up>>>1)&255;return result},filterPaeth=function(line,colorsPerPixel,prevLine){var left,up,upLeft,paeth,result=[],i=0,len=line.length;for(result[0]=4;i<len;i++)left=line[i-colorsPerPixel]||0,up=prevLine&&prevLine[i]||0,upLeft=prevLine&&prevLine[i-colorsPerPixel]||0,paeth=paethPredictor(left,up,upLeft),result[i+1]=line[i]-paeth+256&255;return result},paethPredictor=function(left,up,upLeft){var p=left+up-upLeft,pLeft=Math.abs(p-left),pUp=Math.abs(p-up),pUpLeft=Math.abs(p-upLeft);return pLeft<=pUp&&pLeft<=pUpLeft?left:pUp<=pUpLeft?up:upLeft},getFilterMethods=function(){return[filterNone,filterSub,filterUp,filterAverage,filterPaeth]},getIndexOfSmallestSum=function(arrays){for(var sum,min,ind,i=0,len=arrays.length;i<len;)((sum=absSum(arrays[i].slice(1)))<min||!min)&&(min=sum,ind=i),i++;return ind},absSum=function(array){for(var i=0,len=array.length,sum=0;i<len;)sum+=Math.abs(array[i++]);return sum};jsPDFAPI.processPNG=function(imageData,imageIndex,alias,compression,dataAsBinaryString){var img,dp,trns,colors,pal,smask,colorSpace=this.color_spaces.DEVICE_RGB,decode=this.decode.FLATE_DECODE,bpc=8;if(this.isArrayBuffer(imageData)&&(imageData=new Uint8Array(imageData)),this.isArrayBufferView(imageData)){if("function"!=typeof PNG||"function"!=typeof FlateStream)throw new Error("PNG support requires png.js and zlib.js");if(imageData=(img=new PNG(imageData)).imgData,bpc=img.bits,colorSpace=img.colorSpace,colors=img.colors,-1!==[4,6].indexOf(img.colorType)){if(8===img.bits)for(var pbl,len=(pixels=32==img.pixelBitlength?new Uint32Array(img.decodePixels().buffer):16==img.pixelBitlength?new Uint16Array(img.decodePixels().buffer):new Uint8Array(img.decodePixels().buffer)).length,imgData=new Uint8Array(len*img.colors),alphaData=new Uint8Array(len),pDiff=img.pixelBitlength-img.bits,i=0,n=0;i<len;i++){for(pixel=pixels[i],pbl=0;pbl<pDiff;)imgData[n++]=pixel>>>pbl&255,pbl+=img.bits;alphaData[i]=pixel>>>pbl&255}if(16===img.bits){len=(pixels=new Uint32Array(img.decodePixels().buffer)).length,imgData=new Uint8Array(len*(32/img.pixelBitlength)*img.colors),alphaData=new Uint8Array(len*(32/img.pixelBitlength));for(var pixel,hasColors=img.colors>1,a=(i=0,n=0,0);i<len;)pixel=pixels[i++],imgData[n++]=pixel>>>0&255,hasColors&&(imgData[n++]=pixel>>>16&255,pixel=pixels[i++],imgData[n++]=pixel>>>0&255),alphaData[a++]=pixel>>>16&255;bpc=8}compression!==jsPDFAPI.image_compression.NONE&&hasCompressionJS()?(imageData=compressBytes(imgData,img.width*img.colors,img.colors,compression),smask=compressBytes(alphaData,img.width,1,compression)):(imageData=imgData,smask=alphaData,decode=null)}if(3===img.colorType&&(colorSpace=this.color_spaces.INDEXED,pal=img.palette,img.transparency.indexed)){var trans=img.transparency.indexed,total=0;for(i=0,len=trans.length;i<len;++i)total+=trans[i];if((total/=255)===len-1&&-1!==trans.indexOf(0))trns=[trans.indexOf(0)];else if(total!==len){var pixels=img.decodePixels();for(alphaData=new Uint8Array(pixels.length),i=0,len=pixels.length;i<len;i++)alphaData[i]=trans[pixels[i]];smask=compressBytes(alphaData,img.width,1)}}var predictor=function(compression){var predictor;switch(compression){case jsPDFAPI.image_compression.FAST:predictor=11;break;case jsPDFAPI.image_compression.MEDIUM:predictor=13;break;case jsPDFAPI.image_compression.SLOW:predictor=14;break;default:predictor=12}return predictor}(compression);return dp=decode===this.decode.FLATE_DECODE?"/Predictor "+predictor+" /Colors "+colors+" /BitsPerComponent "+bpc+" /Columns "+img.width:"/Colors "+colors+" /BitsPerComponent "+bpc+" /Columns "+img.width,(this.isArrayBuffer(imageData)||this.isArrayBufferView(imageData))&&(imageData=this.arrayBufferToBinaryString(imageData)),(smask&&this.isArrayBuffer(smask)||this.isArrayBufferView(smask))&&(smask=this.arrayBufferToBinaryString(smask)),this.createImageInfo(imageData,img.width,img.height,colorSpace,bpc,decode,imageIndex,alias,dp,trns,pal,smask,predictor)}throw new Error("Unsupported PNG image data, try using JPEG instead.")}}(jsPDF.API),function(jsPDFAPI){jsPDFAPI.processGIF89A=function(imageData,imageIndex,alias,compression,dataAsBinaryString){var reader=new GifReader(imageData),width=reader.width,height=reader.height,pixels=[];reader.decodeAndBlitFrameRGBA(0,pixels);var rawImageData={data:pixels,width:width,height:height},data=new JPEGEncoder(100).encode(rawImageData,100);return jsPDFAPI.processJPEG.call(this,data,imageIndex,alias,compression)},jsPDFAPI.processGIF87A=jsPDFAPI.processGIF89A}(jsPDF.API),function(jsPDFAPI){jsPDFAPI.processBMP=function(imageData,imageIndex,alias,compression,dataAsBinaryString){var reader=new BmpDecoder(imageData,!1),width=reader.width,height=reader.height,rawImageData={data:reader.getData(),width:width,height:height},data=new JPEGEncoder(100).encode(rawImageData,100);return jsPDFAPI.processJPEG.call(this,data,imageIndex,alias,compression)}}(jsPDF.API),function(jsPDFAPI){jsPDFAPI.setLanguage=function(langCode){return void 0===this.internal.languageSettings&&(this.internal.languageSettings={},this.internal.languageSettings.isSubscribed=!1),void 0!=={af:"Afrikaans",sq:"Albanian",ar:"Arabic (Standard)","ar-DZ":"Arabic (Algeria)","ar-BH":"Arabic (Bahrain)","ar-EG":"Arabic (Egypt)","ar-IQ":"Arabic (Iraq)","ar-JO":"Arabic (Jordan)","ar-KW":"Arabic (Kuwait)","ar-LB":"Arabic (Lebanon)","ar-LY":"Arabic (Libya)","ar-MA":"Arabic (Morocco)","ar-OM":"Arabic (Oman)","ar-QA":"Arabic (Qatar)","ar-SA":"Arabic (Saudi Arabia)","ar-SY":"Arabic (Syria)","ar-TN":"Arabic (Tunisia)","ar-AE":"Arabic (U.A.E.)","ar-YE":"Arabic (Yemen)",an:"Aragonese",hy:"Armenian",as:"Assamese",ast:"Asturian",az:"Azerbaijani",eu:"Basque",be:"Belarusian",bn:"Bengali",bs:"Bosnian",br:"Breton",bg:"Bulgarian",my:"Burmese",ca:"Catalan",ch:"Chamorro",ce:"Chechen",zh:"Chinese","zh-HK":"Chinese (Hong Kong)","zh-CN":"Chinese (PRC)","zh-SG":"Chinese (Singapore)","zh-TW":"Chinese (Taiwan)",cv:"Chuvash",co:"Corsican",cr:"Cree",hr:"Croatian",cs:"Czech",da:"Danish",nl:"Dutch (Standard)","nl-BE":"Dutch (Belgian)",en:"English","en-AU":"English (Australia)","en-BZ":"English (Belize)","en-CA":"English (Canada)","en-IE":"English (Ireland)","en-JM":"English (Jamaica)","en-NZ":"English (New Zealand)","en-PH":"English (Philippines)","en-ZA":"English (South Africa)","en-TT":"English (Trinidad & Tobago)","en-GB":"English (United Kingdom)","en-US":"English (United States)","en-ZW":"English (Zimbabwe)",eo:"Esperanto",et:"Estonian",fo:"Faeroese",fj:"Fijian",fi:"Finnish",fr:"French (Standard)","fr-BE":"French (Belgium)","fr-CA":"French (Canada)","fr-FR":"French (France)","fr-LU":"French (Luxembourg)","fr-MC":"French (Monaco)","fr-CH":"French (Switzerland)",fy:"Frisian",fur:"Friulian",gd:"Gaelic (Scots)","gd-IE":"Gaelic (Irish)",gl:"Galacian",ka:"Georgian",de:"German (Standard)","de-AT":"German (Austria)","de-DE":"German (Germany)","de-LI":"German (Liechtenstein)","de-LU":"German (Luxembourg)","de-CH":"German (Switzerland)",el:"Greek",gu:"Gujurati",ht:"Haitian",he:"Hebrew",hi:"Hindi",hu:"Hungarian",is:"Icelandic",id:"Indonesian",iu:"Inuktitut",ga:"Irish",it:"Italian (Standard)","it-CH":"Italian (Switzerland)",ja:"Japanese",kn:"Kannada",ks:"Kashmiri",kk:"Kazakh",km:"Khmer",ky:"Kirghiz",tlh:"Klingon",ko:"Korean","ko-KP":"Korean (North Korea)","ko-KR":"Korean (South Korea)",la:"Latin",lv:"Latvian",lt:"Lithuanian",lb:"Luxembourgish",mk:"FYRO Macedonian",ms:"Malay",ml:"Malayalam",mt:"Maltese",mi:"Maori",mr:"Marathi",mo:"Moldavian",nv:"Navajo",ng:"Ndonga",ne:"Nepali",no:"Norwegian",nb:"Norwegian (Bokmal)",nn:"Norwegian (Nynorsk)",oc:"Occitan",or:"Oriya",om:"Oromo",fa:"Persian","fa-IR":"Persian/Iran",pl:"Polish",pt:"Portuguese","pt-BR":"Portuguese (Brazil)",pa:"Punjabi","pa-IN":"Punjabi (India)","pa-PK":"Punjabi (Pakistan)",qu:"Quechua",rm:"Rhaeto-Romanic",ro:"Romanian","ro-MO":"Romanian (Moldavia)",ru:"Russian","ru-MO":"Russian (Moldavia)",sz:"Sami (Lappish)",sg:"Sango",sa:"Sanskrit",sc:"Sardinian",sd:"Sindhi",si:"Singhalese",sr:"Serbian",sk:"Slovak",sl:"Slovenian",so:"Somani",sb:"Sorbian",es:"Spanish","es-AR":"Spanish (Argentina)","es-BO":"Spanish (Bolivia)","es-CL":"Spanish (Chile)","es-CO":"Spanish (Colombia)","es-CR":"Spanish (Costa Rica)","es-DO":"Spanish (Dominican Republic)","es-EC":"Spanish (Ecuador)","es-SV":"Spanish (El Salvador)","es-GT":"Spanish (Guatemala)","es-HN":"Spanish (Honduras)","es-MX":"Spanish (Mexico)","es-NI":"Spanish (Nicaragua)","es-PA":"Spanish (Panama)","es-PY":"Spanish (Paraguay)","es-PE":"Spanish (Peru)","es-PR":"Spanish (Puerto Rico)","es-ES":"Spanish (Spain)","es-UY":"Spanish (Uruguay)","es-VE":"Spanish (Venezuela)",sx:"Sutu",sw:"Swahili",sv:"Swedish","sv-FI":"Swedish (Finland)","sv-SV":"Swedish (Sweden)",ta:"Tamil",tt:"Tatar",te:"Teluga",th:"Thai",tig:"Tigre",ts:"Tsonga",tn:"Tswana",tr:"Turkish",tk:"Turkmen",uk:"Ukrainian",hsb:"Upper Sorbian",ur:"Urdu",ve:"Venda",vi:"Vietnamese",vo:"Volapuk",wa:"Walloon",cy:"Welsh",xh:"Xhosa",ji:"Yiddish",zu:"Zulu"}[langCode]&&(this.internal.languageSettings.languageCode=langCode,!1===this.internal.languageSettings.isSubscribed&&(this.internal.events.subscribe("putCatalog",(function(){this.internal.write("/Lang ("+this.internal.languageSettings.languageCode+")")})),this.internal.languageSettings.isSubscribed=!0)),this}}(jsPDF.API),
-/** @preserve
-   * jsPDF split_text_to_size plugin - MIT license.
-   * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
-   *               2014 Diego Casorran, https://github.com/diegocr
-   */
-API=jsPDF.API,getCharWidthsArray=API.getCharWidthsArray=function(text,options){var i,l,char_code,activeFont=(options=options||{}).font||this.internal.getFont(),fontSize=options.fontSize||this.internal.getFontSize(),charSpace=options.charSpace||this.internal.getCharSpace(),widths=options.widths?options.widths:activeFont.metadata.Unicode.widths,widthsFractionOf=widths.fof?widths.fof:1,kerning=options.kerning?options.kerning:activeFont.metadata.Unicode.kerning,kerningFractionOf=kerning.fof?kerning.fof:1,prior_char_code=0,default_char_width=widths[0]||widthsFractionOf,output=[];for(i=0,l=text.length;i<l;i++)char_code=text.charCodeAt(i),"function"==typeof activeFont.metadata.widthOfString?output.push((activeFont.metadata.widthOfGlyph(activeFont.metadata.characterToGlyph(char_code))+charSpace*(1e3/fontSize)||0)/1e3):output.push((widths[char_code]||default_char_width)/widthsFractionOf+(kerning[char_code]&&kerning[char_code][prior_char_code]||0)/kerningFractionOf),prior_char_code=char_code;return output},getArraySum=API.getArraySum=function(array){for(var i=array.length,output=0;i;)output+=array[--i];return output},getStringUnitWidth=API.getStringUnitWidth=function(text,options){var fontSize=(options=options||{}).fontSize||this.internal.getFontSize(),font=options.font||this.internal.getFont(),charSpace=options.charSpace||this.internal.getCharSpace();return"function"==typeof font.metadata.widthOfString?font.metadata.widthOfString(text,fontSize,charSpace)/fontSize:getArraySum(getCharWidthsArray.apply(this,arguments))},splitLongWord=function(word,widths_array,firstLineMaxLen,maxLen){for(var answer=[],i=0,l=word.length,workingLen=0;i!==l&&workingLen+widths_array[i]<firstLineMaxLen;)workingLen+=widths_array[i],i++;answer.push(word.slice(0,i));var startOfLine=i;for(workingLen=0;i!==l;)workingLen+widths_array[i]>maxLen&&(answer.push(word.slice(startOfLine,i)),workingLen=0,startOfLine=i),workingLen+=widths_array[i],i++;return startOfLine!==i&&answer.push(word.slice(startOfLine,i)),answer},splitParagraphIntoLines=function(text,maxlen,options){options||(options={});var word,widths_array,i,l,tmp,lineIndent,line=[],lines=[line],line_length=options.textIndent||0,separator_length=0,current_word_length=0,words=text.split(" "),spaceCharWidth=getCharWidthsArray.apply(this,[" ",options])[0];if(lineIndent=-1===options.lineIndent?words[0].length+2:options.lineIndent||0){var pad=Array(lineIndent).join(" "),wrds=[];words.map((function(wrd){(wrd=wrd.split(/\s*\n/)).length>1?wrds=wrds.concat(wrd.map((function(wrd,idx){return(idx&&wrd.length?"\n":"")+wrd}))):wrds.push(wrd[0])})),words=wrds,lineIndent=getStringUnitWidth.apply(this,[pad,options])}for(i=0,l=words.length;i<l;i++){var force=0;if(word=words[i],lineIndent&&"\n"==word[0]&&(word=word.substr(1),force=1),widths_array=getCharWidthsArray.apply(this,[word,options]),line_length+separator_length+(current_word_length=getArraySum(widths_array))>maxlen||force){if(current_word_length>maxlen){for(tmp=splitLongWord.apply(this,[word,widths_array,maxlen-(line_length+separator_length),maxlen]),line.push(tmp.shift()),line=[tmp.pop()];tmp.length;)lines.push([tmp.shift()]);current_word_length=getArraySum(widths_array.slice(word.length-(line[0]?line[0].length:0)))}else line=[word];lines.push(line),line_length=current_word_length+lineIndent,separator_length=spaceCharWidth}else line.push(word),line_length+=separator_length+current_word_length,separator_length=spaceCharWidth}if(lineIndent)var postProcess=function(ln,idx){return(idx?pad:"")+ln.join(" ")};else postProcess=function(ln){return ln.join(" ")};return lines.map(postProcess)},API.splitTextToSize=function(text,maxlen,options){var paragraphs,fsize=(options=options||{}).fontSize||this.internal.getFontSize(),newOptions=function(options){var widths={0:1},kerning={};if(options.widths&&options.kerning)return{widths:options.widths,kerning:options.kerning};var f=this.internal.getFont(options.fontName,options.fontStyle);return f.metadata.Unicode?{widths:f.metadata.Unicode.widths||widths,kerning:f.metadata.Unicode.kerning||kerning}:{font:f.metadata,fontSize:this.internal.getFontSize(),charSpace:this.internal.getCharSpace()}}.call(this,options);paragraphs=Array.isArray(text)?text:text.split(/\r?\n/);var fontUnit_maxLen=1*this.internal.scaleFactor*maxlen/fsize;newOptions.textIndent=options.textIndent?1*options.textIndent*this.internal.scaleFactor/fsize:0,newOptions.lineIndent=options.lineIndent;var i,l,output=[];for(i=0,l=paragraphs.length;i<l;i++)output=output.concat(splitParagraphIntoLines.apply(this,[paragraphs[i],fontUnit_maxLen,newOptions]));return output},
-/** @preserve 
-  jsPDF standard_fonts_metrics plugin
-  Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
-  MIT license.
-  */
-function(API){var uncompress=function(data){for(var mapping={},i=0;i<"klmnopqrstuvwxyz".length;i++)mapping["klmnopqrstuvwxyz"[i]]="0123456789abcdef"[i];var stringparts,parent_key_pair,key,ch,output={},sign=1,activeobject=output,parentchain=[],keyparts="",valueparts="",datalen=data.length-1;for(i=1;i!=datalen;)ch=data[i],i+=1,"'"==ch?stringparts?(key=stringparts.join(""),stringparts=undefined):stringparts=[]:stringparts?stringparts.push(ch):"{"==ch?(parentchain.push([activeobject,key]),activeobject={},key=undefined):"}"==ch?((parent_key_pair=parentchain.pop())[0][parent_key_pair[1]]=activeobject,key=undefined,activeobject=parent_key_pair[0]):"-"==ch?sign=-1:undefined===key?mapping.hasOwnProperty(ch)?(keyparts+=mapping[ch],key=parseInt(keyparts,16)*sign,sign=1,keyparts=""):keyparts+=ch:mapping.hasOwnProperty(ch)?(valueparts+=mapping[ch],activeobject[key]=parseInt(valueparts,16)*sign,sign=1,key=undefined,valueparts=""):valueparts+=ch;return output},encodingBlock={codePages:["WinAnsiEncoding"],WinAnsiEncoding:uncompress("{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}")},encodings={Unicode:{Courier:encodingBlock,"Courier-Bold":encodingBlock,"Courier-BoldOblique":encodingBlock,"Courier-Oblique":encodingBlock,Helvetica:encodingBlock,"Helvetica-Bold":encodingBlock,"Helvetica-BoldOblique":encodingBlock,"Helvetica-Oblique":encodingBlock,"Times-Roman":encodingBlock,"Times-Bold":encodingBlock,"Times-BoldItalic":encodingBlock,"Times-Italic":encodingBlock}},fontMetrics={Unicode:{"Courier-Oblique":uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-BoldItalic":uncompress("{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'kerning'{cl{4qu5kt5qt5rs17ss5ts}201s{201ss}201t{cks4lscmscnscoscpscls2wu2yu201ts}201x{2wu2yu}2k{201ts}2w{4qx5kx5ou5qx5rs17su5tu}2x{17su5tu5ou}2y{4qx5kx5ou5qx5rs17ss5ts}'fof'-6ofn{17sw5tw5ou5qw5rs}7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qs}3v{17su5tu5os5qs}7p{17su5tu}ck{4qu5kt5qt5rs17ss5ts}4l{4qu5kt5qt5rs17ss5ts}cm{4qu5kt5qt5rs17ss5ts}cn{4qu5kt5qt5rs17ss5ts}co{4qu5kt5qt5rs17ss5ts}cp{4qu5kt5qt5rs17ss5ts}6l{4qu5ou5qw5rt17su5tu}5q{ckuclucmucnucoucpu4lu}5r{ckuclucmucnucoucpu4lu}7q{cksclscmscnscoscps4ls}6p{4qu5ou5qw5rt17sw5tw}ek{4qu5ou5qw5rt17su5tu}el{4qu5ou5qw5rt17su5tu}em{4qu5ou5qw5rt17su5tu}en{4qu5ou5qw5rt17su5tu}eo{4qu5ou5qw5rt17su5tu}ep{4qu5ou5qw5rt17su5tu}es{17ss5ts5qs4qu}et{4qu5ou5qw5rt17sw5tw}eu{4qu5ou5qw5rt17ss5ts}ev{17ss5ts5qs4qu}6z{17sw5tw5ou5qw5rs}fm{17sw5tw5ou5qw5rs}7n{201ts}fo{17sw5tw5ou5qw5rs}fp{17sw5tw5ou5qw5rs}fq{17sw5tw5ou5qw5rs}7r{cksclscmscnscoscps4ls}fs{17sw5tw5ou5qw5rs}ft{17su5tu}fu{17su5tu}fv{17su5tu}fw{17su5tu}fz{cksclscmscnscoscps4ls}}}"),"Helvetica-Bold":uncompress("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),Courier:uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Courier-BoldOblique":uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Bold":uncompress("{'widths'{k3q2q5ncx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2l202m2n2n3m2o3m2p6o202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5x4l4s4m4m4n4s4o4s4p4m4q3x4r4y4s4y4t2r4u3m4v4y4w4m4x5y4y4s4z4y5k3x5l4y5m4s5n3r5o4m5p4s5q4s5r6o5s4s5t4s5u4m5v2l5w1w5x2l5y3u5z3m6k2l6l3m6m3r6n2w6o3r6p2w6q2l6r3m6s3r6t1w6u2l6v3r6w1w6x5n6y3r6z3m7k3r7l3r7m2w7n2r7o2l7p3r7q3m7r4s7s3m7t3m7u2w7v2r7w1q7x2r7y3o202l3mcl4sal2lam3man3mao3map3mar3mas2lat4uau1yav3maw3tay4uaz2lbk2sbl3t'fof'6obo2lbp3rbr1tbs2lbu2lbv3mbz3mck4s202k3mcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3rek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3m3u2l17s4s19m3m}'kerning'{cl{4qt5ks5ot5qy5rw17sv5tv}201t{cks4lscmscnscoscpscls4wv}2k{201ts}2w{4qu5ku7mu5os5qx5ru17su5tu}2x{17su5tu5ou5qs}2y{4qv5kv7mu5ot5qz5ru17su5tu}'fof'-6o7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qu}3v{17su5tu5os5qu}fu{17su5tu5ou5qu}7p{17su5tu5ou5qu}ck{4qt5ks5ot5qy5rw17sv5tv}4l{4qt5ks5ot5qy5rw17sv5tv}cm{4qt5ks5ot5qy5rw17sv5tv}cn{4qt5ks5ot5qy5rw17sv5tv}co{4qt5ks5ot5qy5rw17sv5tv}cp{4qt5ks5ot5qy5rw17sv5tv}6l{17st5tt5ou5qu}17s{ckuclucmucnucoucpu4lu4wu}5o{ckuclucmucnucoucpu4lu4wu}5q{ckzclzcmzcnzcozcpz4lz4wu}5r{ckxclxcmxcnxcoxcpx4lx4wu}5t{ckuclucmucnucoucpu4lu4wu}7q{ckuclucmucnucoucpu4lu}6p{17sw5tw5ou5qu}ek{17st5tt5qu}el{17st5tt5ou5qu}em{17st5tt5qu}en{17st5tt5qu}eo{17st5tt5qu}ep{17st5tt5ou5qu}es{17ss5ts5qu}et{17sw5tw5ou5qu}eu{17sw5tw5ou5qu}ev{17ss5ts5qu}6z{17sw5tw5ou5qu5rs}fm{17sw5tw5ou5qu5rs}fn{17sw5tw5ou5qu5rs}fo{17sw5tw5ou5qu5rs}fp{17sw5tw5ou5qu5rs}fq{17sw5tw5ou5qu5rs}7r{cktcltcmtcntcotcpt4lt5os}fs{17sw5tw5ou5qu5rs}ft{17su5tu5ou5qu}7m{5os}fv{17su5tu5ou5qu}fw{17su5tu5ou5qu}fz{cksclscmscnscoscps4ls}}}"),Symbol:uncompress("{'widths'{k3uaw4r19m3m2k1t2l2l202m2y2n3m2p5n202q6o3k3m2s2l2t2l2v3r2w1t3m3m2y1t2z1wbk2sbl3r'fof'6o3n3m3o3m3p3m3q3m3r3m3s3m3t3m3u1w3v1w3w3r3x3r3y3r3z2wbp3t3l3m5v2l5x2l5z3m2q4yfr3r7v3k7w1o7x3k}'kerning'{'fof'-6o}}"),Helvetica:uncompress("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}"),"Helvetica-BoldOblique":uncompress("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),ZapfDingbats:uncompress("{'widths'{k4u2k1w'fof'6o}'kerning'{'fof'-6o}}"),"Courier-Bold":uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Italic":uncompress("{'widths'{k3n2q4ycx2l201n3m201o5t201s2l201t2l201u2l201w3r201x3r201y3r2k1t2l2l202m2n2n3m2o3m2p5n202q5t2r1p2s2l2t2l2u3m2v4n2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w4n3x4n3y4n3z3m4k5w4l3x4m3x4n4m4o4s4p3x4q3x4r4s4s4s4t2l4u2w4v4m4w3r4x5n4y4m4z4s5k3x5l4s5m3x5n3m5o3r5p4s5q3x5r5n5s3x5t3r5u3r5v2r5w1w5x2r5y2u5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q1w6r3m6s3m6t1w6u1w6v2w6w1w6x4s6y3m6z3m7k3m7l3m7m2r7n2r7o1w7p3m7q2w7r4m7s2w7t2w7u2r7v2s7w1v7x2s7y3q202l3mcl3xal2ram3man3mao3map3mar3mas2lat4wau1vav3maw4nay4waz2lbk2sbl4n'fof'6obo2lbp3mbq3obr1tbs2lbu1zbv3mbz3mck3x202k3mcm3xcn3xco3xcp3xcq5tcr4mcs3xct3xcu3xcv3xcw2l2m2ucy2lcz2ldl4mdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr4nfs3mft3mfu3mfv3mfw3mfz2w203k6o212m6m2dw2l2cq2l3t3m3u2l17s3r19m3m}'kerning'{cl{5kt4qw}201s{201sw}201t{201tw2wy2yy6q-t}201x{2wy2yy}2k{201tw}2w{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}2x{17ss5ts5os}2y{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}'fof'-6o6t{17ss5ts5qs}7t{5os}3v{5qs}7p{17su5tu5qs}ck{5kt4qw}4l{5kt4qw}cm{5kt4qw}cn{5kt4qw}co{5kt4qw}cp{5kt4qw}6l{4qs5ks5ou5qw5ru17su5tu}17s{2ks}5q{ckvclvcmvcnvcovcpv4lv}5r{ckuclucmucnucoucpu4lu}5t{2ks}6p{4qs5ks5ou5qw5ru17su5tu}ek{4qs5ks5ou5qw5ru17su5tu}el{4qs5ks5ou5qw5ru17su5tu}em{4qs5ks5ou5qw5ru17su5tu}en{4qs5ks5ou5qw5ru17su5tu}eo{4qs5ks5ou5qw5ru17su5tu}ep{4qs5ks5ou5qw5ru17su5tu}es{5ks5qs4qs}et{4qs5ks5ou5qw5ru17su5tu}eu{4qs5ks5qw5ru17su5tu}ev{5ks5qs4qs}ex{17ss5ts5qs}6z{4qv5ks5ou5qw5ru17su5tu}fm{4qv5ks5ou5qw5ru17su5tu}fn{4qv5ks5ou5qw5ru17su5tu}fo{4qv5ks5ou5qw5ru17su5tu}fp{4qv5ks5ou5qw5ru17su5tu}fq{4qv5ks5ou5qw5ru17su5tu}7r{5os}fs{4qv5ks5ou5qw5ru17su5tu}ft{17su5tu5qs}fu{17su5tu5qs}fv{17su5tu5qs}fw{17su5tu5qs}}}"),"Times-Roman":uncompress("{'widths'{k3n2q4ycx2l201n3m201o6o201s2l201t2l201u2l201w2w201x2w201y2w2k1t2l2l202m2n2n3m2o3m2p5n202q6o2r1m2s2l2t2l2u3m2v3s2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v1w3w3s3x3s3y3s3z2w4k5w4l4s4m4m4n4m4o4s4p3x4q3r4r4s4s4s4t2l4u2r4v4s4w3x4x5t4y4s4z4s5k3r5l4s5m4m5n3r5o3x5p4s5q4s5r5y5s4s5t4s5u3x5v2l5w1w5x2l5y2z5z3m6k2l6l2w6m3m6n2w6o3m6p2w6q2l6r3m6s3m6t1w6u1w6v3m6w1w6x4y6y3m6z3m7k3m7l3m7m2l7n2r7o1w7p3m7q3m7r4s7s3m7t3m7u2w7v3k7w1o7x3k7y3q202l3mcl4sal2lam3man3mao3map3mar3mas2lat4wau1vav3maw3say4waz2lbk2sbl3s'fof'6obo2lbp3mbq2xbr1tbs2lbu1zbv3mbz2wck4s202k3mcm4scn4sco4scp4scq5tcr4mcs3xct3xcu3xcv3xcw2l2m2tcy2lcz2ldl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek2wel2wem2wen2weo2wep2weq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr3sfs3mft3mfu3mfv3mfw3mfz3m203k6o212m6m2dw2l2cq2l3t3m3u1w17s4s19m3m}'kerning'{cl{4qs5ku17sw5ou5qy5rw201ss5tw201ws}201s{201ss}201t{ckw4lwcmwcnwcowcpwclw4wu201ts}2k{201ts}2w{4qs5kw5os5qx5ru17sx5tx}2x{17sw5tw5ou5qu}2y{4qs5kw5os5qx5ru17sx5tx}'fof'-6o7t{ckuclucmucnucoucpu4lu5os5rs}3u{17su5tu5qs}3v{17su5tu5qs}7p{17sw5tw5qs}ck{4qs5ku17sw5ou5qy5rw201ss5tw201ws}4l{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cm{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cn{4qs5ku17sw5ou5qy5rw201ss5tw201ws}co{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cp{4qs5ku17sw5ou5qy5rw201ss5tw201ws}6l{17su5tu5os5qw5rs}17s{2ktclvcmvcnvcovcpv4lv4wuckv}5o{ckwclwcmwcnwcowcpw4lw4wu}5q{ckyclycmycnycoycpy4ly4wu5ms}5r{cktcltcmtcntcotcpt4lt4ws}5t{2ktclvcmvcnvcovcpv4lv4wuckv}7q{cksclscmscnscoscps4ls}6p{17su5tu5qw5rs}ek{5qs5rs}el{17su5tu5os5qw5rs}em{17su5tu5os5qs5rs}en{17su5qs5rs}eo{5qs5rs}ep{17su5tu5os5qw5rs}es{5qs}et{17su5tu5qw5rs}eu{17su5tu5qs5rs}ev{5qs}6z{17sv5tv5os5qx5rs}fm{5os5qt5rs}fn{17sv5tv5os5qx5rs}fo{17sv5tv5os5qx5rs}fp{5os5qt5rs}fq{5os5qt5rs}7r{ckuclucmucnucoucpu4lu5os}fs{17sv5tv5os5qx5rs}ft{17ss5ts5qs}fu{17sw5tw5qs}fv{17sw5tw5qs}fw{17ss5ts5qs}fz{ckuclucmucnucoucpu4lu5os5rs}}}"),"Helvetica-Oblique":uncompress("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}")}};API.events.push(["addFont",function(font){var metrics,unicode_section,encodingBlock;(metrics=fontMetrics.Unicode[font.postScriptName])&&((unicode_section=font.metadata.Unicode?font.metadata.Unicode:font.metadata.Unicode={}).widths=metrics.widths,unicode_section.kerning=metrics.kerning),(encodingBlock=encodings.Unicode[font.postScriptName])&&((unicode_section=font.metadata.Unicode?font.metadata.Unicode:font.metadata.Unicode={}).encoding=encodingBlock,encodingBlock.codePages&&encodingBlock.codePages.length&&(font.encoding=encodingBlock.codePages[0]))}])}(jsPDF.API),function(jsPDF,global){jsPDF.API.events.push(["addFont",function(font){jsPDF.API.existsFileInVFS(font.postScriptName)?(font.metadata=jsPDF.API.TTFFont.open(font.postScriptName,font.fontName,jsPDF.API.getFileFromVFS(font.postScriptName),font.encoding),font.metadata.Unicode=font.metadata.Unicode||{encoding:{},kerning:{},widths:[]}):font.id.slice(1)>14&&console.error("Font does not exist in FileInVFS, import fonts or remove declaration doc.addFont('"+font.postScriptName+"').")}])}(jsPDF,"undefined"!=typeof self&&self||"undefined"!=typeof global&&global||"undefined"!=typeof window&&window||Function("return this")()),
-/** @preserve
-  jsPDF SVG plugin
-  Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
-  */
-function(jsPDFAPI){jsPDFAPI.addSvg=function(svgtext,x,y,w,h){if(undefined===x||undefined===y)throw new Error("addSVG needs values for 'x' and 'y'");function convertPathToPDFLinesArgs(path){for(var x=parseFloat(path[1]),y=parseFloat(path[2]),vectors=[],position=3,len=path.length;position<len;)"c"===path[position]?(vectors.push([parseFloat(path[position+1]),parseFloat(path[position+2]),parseFloat(path[position+3]),parseFloat(path[position+4]),parseFloat(path[position+5]),parseFloat(path[position+6])]),position+=7):"l"===path[position]?(vectors.push([parseFloat(path[position+1]),parseFloat(path[position+2])]),position+=3):position+=1;return[x,y,vectors]}var svgnode=function(svgtext,frame){var framedoc=(frame.contentWindow||frame.contentDocument).document;return framedoc.write(svgtext),framedoc.close(),framedoc.getElementsByTagName("svg")[0]}(svgtext,function(document){var frame=document.createElement("iframe");return function(cssbody,document){var styletag=document.createElement("style");styletag.type="text/css",styletag.styleSheet?styletag.styleSheet.cssText=cssbody:styletag.appendChild(document.createTextNode(cssbody)),document.getElementsByTagName("head")[0].appendChild(styletag)}(".jsPDF_sillysvg_iframe {display:none;position:absolute;}",document),frame.name="childframe",frame.setAttribute("width",0),frame.setAttribute("height",0),frame.setAttribute("frameborder","0"),frame.setAttribute("scrolling","no"),frame.setAttribute("seamless","seamless"),frame.setAttribute("class","jsPDF_sillysvg_iframe"),document.body.appendChild(frame),frame}(document)),scale=[1,1],svgw=parseFloat(svgnode.getAttribute("width")),svgh=parseFloat(svgnode.getAttribute("height"));svgw&&svgh&&(w&&h?scale=[w/svgw,h/svgh]:w?scale=[w/svgw,w/svgw]:h&&(scale=[h/svgh,h/svgh]));var i,l,tmp,linesargs,items=svgnode.childNodes;for(i=0,l=items.length;i<l;i++)(tmp=items[i]).tagName&&"PATH"===tmp.tagName.toUpperCase()&&((linesargs=convertPathToPDFLinesArgs(tmp.getAttribute("d").split(" ")))[0]=linesargs[0]*scale[0]+x,linesargs[1]=linesargs[1]*scale[1]+y,this.lines.call(this,linesargs[2],linesargs[0],linesargs[1],scale));return this},jsPDFAPI.addSVG=jsPDFAPI.addSvg,jsPDFAPI.addSvgAsImage=function(svg,x,y,w,h,alias,compression,rotation){if(isNaN(x)||isNaN(y))throw console.error("jsPDF.addSvgAsImage: Invalid coordinates",arguments),new Error("Invalid coordinates passed to jsPDF.addSvgAsImage");if(isNaN(w)||isNaN(h))throw console.error("jsPDF.addSvgAsImage: Invalid measurements",arguments),new Error("Invalid measurements (width and/or height) passed to jsPDF.addSvgAsImage");var canvas=document.createElement("canvas");canvas.width=w,canvas.height=h;var ctx=canvas.getContext("2d");return ctx.fillStyle="#fff",ctx.fillRect(0,0,canvas.width,canvas.height),canvg(canvas,svg,{ignoreMouse:!0,ignoreAnimation:!0,ignoreDimensions:!0,ignoreClear:!0}),this.addImage(canvas.toDataURL("image/jpeg",1),x,y,w,h,compression,rotation),this}}(jsPDF.API),function(jsPDFAPI){jsPDFAPI.putTotalPages=function(pageExpression){for(var replaceExpression=new RegExp(pageExpression,"g"),n=1;n<=this.internal.getNumberOfPages();n++)for(var i=0;i<this.internal.pages[n].length;i++)this.internal.pages[n][i]=this.internal.pages[n][i].replace(replaceExpression,this.internal.getNumberOfPages());return this}}(jsPDF.API),function(jsPDFAPI){jsPDFAPI.viewerPreferences=function(options,doReset){var configuration;options=options||{},doReset=doReset||!1;var method,value,configurationTemplate={HideToolbar:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},HideMenubar:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},HideWindowUI:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},FitWindow:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},CenterWindow:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},DisplayDocTitle:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.4},NonFullScreenPageMode:{defaultValue:"UseNone",value:"UseNone",type:"name",explicitSet:!1,valueSet:["UseNone","UseOutlines","UseThumbs","UseOC"],pdfVersion:1.3},Direction:{defaultValue:"L2R",value:"L2R",type:"name",explicitSet:!1,valueSet:["L2R","R2L"],pdfVersion:1.3},ViewArea:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},ViewClip:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintArea:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintClip:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintScaling:{defaultValue:"AppDefault",value:"AppDefault",type:"name",explicitSet:!1,valueSet:["AppDefault","None"],pdfVersion:1.6},Duplex:{defaultValue:"",value:"none",type:"name",explicitSet:!1,valueSet:["Simplex","DuplexFlipShortEdge","DuplexFlipLongEdge","none"],pdfVersion:1.7},PickTrayByPDFSize:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.7},PrintPageRange:{defaultValue:"",value:"",type:"array",explicitSet:!1,valueSet:null,pdfVersion:1.7},NumCopies:{defaultValue:1,value:1,type:"integer",explicitSet:!1,valueSet:null,pdfVersion:1.7}},configurationKeys=Object.keys(configurationTemplate),rangeArray=[],i=0,j=0,k=0,isValid=!0;function arrayContainsElement(array,element){var iterator,result=!1;for(iterator=0;iterator<array.length;iterator+=1)array[iterator]===element&&(result=!0);return result}if(void 0===this.internal.viewerpreferences&&(this.internal.viewerpreferences={},this.internal.viewerpreferences.configuration=JSON.parse(JSON.stringify(configurationTemplate)),this.internal.viewerpreferences.isSubscribed=!1),configuration=this.internal.viewerpreferences.configuration,"reset"===options||!0===doReset){var len=configurationKeys.length;for(k=0;k<len;k+=1)configuration[configurationKeys[k]].value=configuration[configurationKeys[k]].defaultValue,configuration[configurationKeys[k]].explicitSet=!1}if("object"===(void 0===options?"undefined":_typeof(options)))for(method in options)if(value=options[method],arrayContainsElement(configurationKeys,method)&&void 0!==value){if("boolean"===configuration[method].type&&"boolean"==typeof value)configuration[method].value=value;else if("name"===configuration[method].type&&arrayContainsElement(configuration[method].valueSet,value))configuration[method].value=value;else if("integer"===configuration[method].type&&Number.isInteger(value))configuration[method].value=value;else if("array"===configuration[method].type){for(i=0;i<value.length;i+=1)if(isValid=!0,1===value[i].length&&"number"==typeof value[i][0])rangeArray.push(String(value[i]));else if(value[i].length>1){for(j=0;j<value[i].length;j+=1)"number"!=typeof value[i][j]&&(isValid=!1);!0===isValid&&rangeArray.push(String(value[i].join("-")))}configuration[method].value=String(rangeArray)}else configuration[method].value=configuration[method].defaultValue;configuration[method].explicitSet=!0}return!1===this.internal.viewerpreferences.isSubscribed&&(this.internal.events.subscribe("putCatalog",(function(){var vPref,pdfDict=[];for(vPref in configuration)!0===configuration[vPref].explicitSet&&("name"===configuration[vPref].type?pdfDict.push("/"+vPref+" /"+configuration[vPref].value):pdfDict.push("/"+vPref+" "+configuration[vPref].value));0!==pdfDict.length&&this.internal.write("/ViewerPreferences\n<<\n"+pdfDict.join("\n")+"\n>>")})),this.internal.viewerpreferences.isSubscribed=!0),this.internal.viewerpreferences.configuration=configuration,this}}(jsPDF.API),function(jsPDFAPI){var xmpmetadata="",xmpnamespaceuri="",metadata_object_number="";jsPDFAPI.addMetadata=function(metadata,namespaceuri){return xmpnamespaceuri=namespaceuri||"http://jspdf.default.namespaceuri/",xmpmetadata=metadata,this.internal.events.subscribe("postPutResources",(function(){if(xmpmetadata){var rdf_beginning='<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:jspdf="'+xmpnamespaceuri+'"><jspdf:metadata>',utf8_xmpmeta_beginning=unescape(encodeURIComponent('<x:xmpmeta xmlns:x="adobe:ns:meta/">')),utf8_rdf_beginning=unescape(encodeURIComponent(rdf_beginning)),utf8_metadata=unescape(encodeURIComponent(xmpmetadata)),utf8_rdf_ending=unescape(encodeURIComponent("</jspdf:metadata></rdf:Description></rdf:RDF>")),utf8_xmpmeta_ending=unescape(encodeURIComponent("</x:xmpmeta>")),total_len=utf8_rdf_beginning.length+utf8_metadata.length+utf8_rdf_ending.length+utf8_xmpmeta_beginning.length+utf8_xmpmeta_ending.length;metadata_object_number=this.internal.newObject(),this.internal.write("<< /Type /Metadata /Subtype /XML /Length "+total_len+" >>"),this.internal.write("stream"),this.internal.write(utf8_xmpmeta_beginning+utf8_rdf_beginning+utf8_metadata+utf8_rdf_ending+utf8_xmpmeta_ending),this.internal.write("endstream"),this.internal.write("endobj")}else metadata_object_number=""})),this.internal.events.subscribe("putCatalog",(function(){metadata_object_number&&this.internal.write("/Metadata "+metadata_object_number+" 0 R")})),this}}(jsPDF.API),function(jsPDF,global){var jsPDFAPI=jsPDF.API,glyID=[0];jsPDFAPI.events.push(["putFont",function(args){!function(font,out,newObject){if(font.metadata instanceof jsPDF.API.TTFFont&&"Identity-H"===font.encoding){for(var widths=font.metadata.Unicode.widths,pdfOutput=font.metadata.subset.encode(glyID),pdfOutput2="",i=0;i<pdfOutput.length;i++)pdfOutput2+=String.fromCharCode(pdfOutput[i]);var fontTable=newObject();out("<<"),out("/Length "+pdfOutput2.length),out("/Length1 "+pdfOutput2.length),out(">>"),out("stream"),out(pdfOutput2),out("endstream"),out("endobj");var fontDescriptor=newObject();out("<<"),out("/Type /FontDescriptor"),out("/FontName /"+font.fontName),out("/FontFile2 "+fontTable+" 0 R"),out("/FontBBox "+jsPDF.API.PDFObject.convert(font.metadata.bbox)),out("/Flags "+font.metadata.flags),out("/StemV "+font.metadata.stemV),out("/ItalicAngle "+font.metadata.italicAngle),out("/Ascent "+font.metadata.ascender),out("/Descent "+font.metadata.decender),out("/CapHeight "+font.metadata.capHeight),out(">>"),out("endobj");var DescendantFont=newObject();out("<<"),out("/Type /Font"),out("/BaseFont /"+font.fontName),out("/FontDescriptor "+fontDescriptor+" 0 R"),out("/W "+jsPDF.API.PDFObject.convert(widths)),out("/CIDToGIDMap /Identity"),out("/DW 1000"),out("/Subtype /CIDFontType2"),out("/CIDSystemInfo"),out("<<"),out("/Supplement 0"),out("/Registry (Adobe)"),out("/Ordering ("+font.encoding+")"),out(">>"),out(">>"),out("endobj"),font.objectNumber=newObject(),out("<<"),out("/Type /Font"),out("/Subtype /Type0"),out("/BaseFont /"+font.fontName),out("/Encoding /"+font.encoding),out("/DescendantFonts ["+DescendantFont+" 0 R]"),out(">>"),out("endobj"),font.isAlreadyPutted=!0}}(args.font,args.out,args.newObject)}]);jsPDFAPI.events.push(["putFont",function(args){!function(font,out,newObject){if(font.metadata instanceof jsPDF.API.TTFFont&&"WinAnsiEncoding"===font.encoding){font.metadata.Unicode.widths;for(var pdfOutput=font.metadata.rawData,pdfOutput2="",i=0;i<pdfOutput.length;i++)pdfOutput2+=String.fromCharCode(pdfOutput[i]);var fontTable=newObject();out("<<"),out("/Length "+pdfOutput2.length),out("/Length1 "+pdfOutput2.length),out(">>"),out("stream"),out(pdfOutput2),out("endstream"),out("endobj");var fontDescriptor=newObject();for(out("<<"),out("/Descent "+font.metadata.decender),out("/CapHeight "+font.metadata.capHeight),out("/StemV "+font.metadata.stemV),out("/Type /FontDescriptor"),out("/FontFile2 "+fontTable+" 0 R"),out("/Flags 96"),out("/FontBBox "+jsPDF.API.PDFObject.convert(font.metadata.bbox)),out("/FontName /"+font.fontName),out("/ItalicAngle "+font.metadata.italicAngle),out("/Ascent "+font.metadata.ascender),out(">>"),out("endobj"),font.objectNumber=newObject(),i=0;i<font.metadata.hmtx.widths.length;i++)font.metadata.hmtx.widths[i]=parseInt(font.metadata.hmtx.widths[i]*(1e3/font.metadata.head.unitsPerEm));out("<</Subtype/TrueType/Type/Font/BaseFont/"+font.fontName+"/FontDescriptor "+fontDescriptor+" 0 R/Encoding/"+font.encoding+" /FirstChar 29 /LastChar 255 /Widths "+jsPDF.API.PDFObject.convert(font.metadata.hmtx.widths)+">>"),out("endobj"),font.isAlreadyPutted=!0}}(args.font,args.out,args.newObject)}]);var utf8TextFunction=function(args){var cmapConfirm,key,text=args.text||"",x=args.x,y=args.y,options=args.options||{},mutex=args.mutex||{},pdfEscape=mutex.pdfEscape,activeFontKey=mutex.activeFontKey,fonts=mutex.fonts,str=(mutex.activeFontSize,""),s=0,strText="",encoding=fonts[key=activeFontKey].encoding;if("Identity-H"!==fonts[key].encoding)return{text:text,x:x,y:y,options:options,mutex:mutex};for(strText=text,key=activeFontKey,"[object Array]"===Object.prototype.toString.call(text)&&(strText=text[0]),s=0;s<strText.length;s+=1)fonts[key].metadata.hasOwnProperty("cmap")&&(cmapConfirm=fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)]),cmapConfirm||strText[s].charCodeAt(0)<256&&fonts[key].metadata.hasOwnProperty("Unicode")?str+=strText[s]:str+="";var result="";return parseInt(key.slice(1))<14||"WinAnsiEncoding"===encoding?result=function(str){for(var hex="",i=0;i<str.length;i++)hex+=""+str.charCodeAt(i).toString(16);return hex}(pdfEscape(str,key)):"Identity-H"===encoding&&(result=function(text,font){for(var t,widths=font.metadata.Unicode.widths,padz=["","0","00","000","0000"],ar=[""],i=0,l=text.length;i<l;++i){if(t=font.metadata.characterToGlyph(text.charCodeAt(i)),glyID.push(t),-1==widths.indexOf(t)&&(widths.push(t),widths.push([parseInt(font.metadata.widthOfGlyph(t),10)])),"0"==t)return ar.join("");t=t.toString(16),ar.push(padz[4-t.length],t)}return ar.join("")}(str,fonts[key])),mutex.isHex=!0,{text:result,x:x,y:y,options:options,mutex:mutex}};jsPDFAPI.events.push(["postProcessText",function(parms){var text=parms.text||"",x=parms.x,y=parms.y,options=parms.options,mutex=parms.mutex,tmpText=(options.lang,[]),args={text:text,x:x,y:y,options:options,mutex:mutex};if("[object Array]"===Object.prototype.toString.call(text)){var i=0;for(i=0;i<text.length;i+=1)"[object Array]"===Object.prototype.toString.call(text[i])&&3===text[i].length?tmpText.push([utf8TextFunction(Object.assign({},args,{text:text[i][0]})).text,text[i][1],text[i][2]]):tmpText.push(utf8TextFunction(Object.assign({},args,{text:text[i]})).text);parms.text=tmpText}else parms.text=utf8TextFunction(Object.assign({},args,{text:text})).text}])}(jsPDF,"undefined"!=typeof self&&self||"undefined"!=typeof global&&global||"undefined"!=typeof window&&window||Function("return this")()),function(jsPDFAPI){var vFS={};jsPDFAPI.existsFileInVFS=function(filename){return vFS.hasOwnProperty(filename)},jsPDFAPI.addFileToVFS=function(filename,filecontent){return vFS[filename]=filecontent,this},jsPDFAPI.getFileFromVFS=function(filename){return vFS.hasOwnProperty(filename)?vFS[filename]:null}}(jsPDF.API),function(view){if(view.URL=view.URL||view.webkitURL,view.Blob&&view.URL)try{return void new Blob}catch(e){}var BlobBuilder=view.BlobBuilder||view.WebKitBlobBuilder||view.MozBlobBuilder||function(view){var get_class=function(object){return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]},FakeBlobBuilder=function(){this.data=[]},FakeBlob=function(data,type,encoding){this.data=data,this.size=data.length,this.type=type,this.encoding=encoding},FBB_proto=FakeBlobBuilder.prototype,FB_proto=FakeBlob.prototype,FileReaderSync=view.FileReaderSync,FileException=function(type){this.code=this[this.name=type]},file_ex_codes="NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR".split(" "),file_ex_code=file_ex_codes.length,real_URL=view.URL||view.webkitURL||view,real_create_object_URL=real_URL.createObjectURL,real_revoke_object_URL=real_URL.revokeObjectURL,URL=real_URL,btoa=view.btoa,atob=view.atob,ArrayBuffer=view.ArrayBuffer,Uint8Array=view.Uint8Array,origin=/^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/;for(FakeBlob.fake=FB_proto.fake=!0;file_ex_code--;)FileException.prototype[file_ex_codes[file_ex_code]]=file_ex_code+1;return real_URL.createObjectURL||(URL=view.URL=function(uri){var uri_origin,uri_info=document.createElementNS("http://www.w3.org/1999/xhtml","a");return uri_info.href=uri,"origin"in uri_info||("data:"===uri_info.protocol.toLowerCase()?uri_info.origin=null:(uri_origin=uri.match(origin),uri_info.origin=uri_origin&&uri_origin[1])),uri_info}),URL.createObjectURL=function(blob){var data_URI_header,type=blob.type;return null===type&&(type="application/octet-stream"),blob instanceof FakeBlob?(data_URI_header="data:"+type,"base64"===blob.encoding?data_URI_header+";base64,"+blob.data:"URI"===blob.encoding?data_URI_header+","+decodeURIComponent(blob.data):btoa?data_URI_header+";base64,"+btoa(blob.data):data_URI_header+","+encodeURIComponent(blob.data)):real_create_object_URL?real_create_object_URL.call(real_URL,blob):void 0},URL.revokeObjectURL=function(object_URL){"data:"!==object_URL.substring(0,5)&&real_revoke_object_URL&&real_revoke_object_URL.call(real_URL,object_URL)},FBB_proto.append=function(data){var bb=this.data;if(Uint8Array&&(data instanceof ArrayBuffer||data instanceof Uint8Array)){for(var str="",buf=new Uint8Array(data),i=0,buf_len=buf.length;i<buf_len;i++)str+=String.fromCharCode(buf[i]);bb.push(str)}else if("Blob"===get_class(data)||"File"===get_class(data)){if(!FileReaderSync)throw new FileException("NOT_READABLE_ERR");var fr=new FileReaderSync;bb.push(fr.readAsBinaryString(data))}else data instanceof FakeBlob?"base64"===data.encoding&&atob?bb.push(atob(data.data)):"URI"===data.encoding?bb.push(decodeURIComponent(data.data)):"raw"===data.encoding&&bb.push(data.data):("string"!=typeof data&&(data+=""),bb.push(unescape(encodeURIComponent(data))))},FBB_proto.getBlob=function(type){return arguments.length||(type=null),new FakeBlob(this.data.join(""),type,"raw")},FBB_proto.toString=function(){return"[object BlobBuilder]"},FB_proto.slice=function(start,end,type){var args=arguments.length;return args<3&&(type=null),new FakeBlob(this.data.slice(start,args>1?end:this.data.length),type,this.encoding)},FB_proto.toString=function(){return"[object Blob]"},FB_proto.close=function(){this.size=0,delete this.data},FakeBlobBuilder}(view);view.Blob=function(blobParts,options){var type=options&&options.type||"",builder=new BlobBuilder;if(blobParts)for(var i=0,len=blobParts.length;i<len;i++)Uint8Array&&blobParts[i]instanceof Uint8Array?builder.append(blobParts[i].buffer):builder.append(blobParts[i]);var blob=builder.getBlob(type);return!blob.slice&&blob.webkitSlice&&(blob.slice=blob.webkitSlice),blob};var getPrototypeOf=Object.getPrototypeOf||function(object){return object.__proto__};view.Blob.prototype=getPrototypeOf(new view.Blob)}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||window.content||window);var saveAs=saveAs||function(view){if(!(void 0===view||"undefined"!=typeof navigator&&/MSIE [1-9]\./.test(navigator.userAgent))){var doc=view.document,get_URL=function(){return view.URL||view.webkitURL||view},save_link=doc.createElementNS("http://www.w3.org/1999/xhtml","a"),can_use_save_link="download"in save_link,is_safari=/constructor/i.test(view.HTMLElement)||view.safari,is_chrome_ios=/CriOS\/[\d]+/.test(navigator.userAgent),throw_outside=function(ex){(view.setImmediate||view.setTimeout)((function(){throw ex}),0)},revoke=function(file){setTimeout((function(){"string"==typeof file?get_URL().revokeObjectURL(file):file.remove()}),4e4)},auto_bom=function(blob){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)?new Blob([String.fromCharCode(65279),blob],{type:blob.type}):blob},FileSaver=function(blob,name,no_auto_bom){no_auto_bom||(blob=auto_bom(blob));var object_url,filesaver=this,force="application/octet-stream"===blob.type,dispatch_all=function(){!function(filesaver,event_types,event){for(var i=(event_types=[].concat(event_types)).length;i--;){var listener=filesaver["on"+event_types[i]];if("function"==typeof listener)try{listener.call(filesaver,event||filesaver)}catch(ex){throw_outside(ex)}}}(filesaver,"writestart progress write writeend".split(" "))};if(filesaver.readyState=filesaver.INIT,can_use_save_link)return object_url=get_URL().createObjectURL(blob),void setTimeout((function(){var node,event;save_link.href=object_url,save_link.download=name,node=save_link,event=new MouseEvent("click"),node.dispatchEvent(event),dispatch_all(),revoke(object_url),filesaver.readyState=filesaver.DONE}));!function(){if((is_chrome_ios||force&&is_safari)&&view.FileReader){var reader=new FileReader;return reader.onloadend=function(){var url=is_chrome_ios?reader.result:reader.result.replace(/^data:[^;]*;/,"data:attachment/file;");view.open(url,"_blank")||(view.location.href=url),url=void 0,filesaver.readyState=filesaver.DONE,dispatch_all()},reader.readAsDataURL(blob),void(filesaver.readyState=filesaver.INIT)}(object_url||(object_url=get_URL().createObjectURL(blob)),force)?view.location.href=object_url:view.open(object_url,"_blank")||(view.location.href=object_url);filesaver.readyState=filesaver.DONE,dispatch_all(),revoke(object_url)}()},FS_proto=FileSaver.prototype;return"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob?function(blob,name,no_auto_bom){return name=name||blob.name||"download",no_auto_bom||(blob=auto_bom(blob)),navigator.msSaveOrOpenBlob(blob,name)}:(FS_proto.abort=function(){},FS_proto.readyState=FS_proto.INIT=0,FS_proto.WRITING=1,FS_proto.DONE=2,FS_proto.error=FS_proto.onwritestart=FS_proto.onprogress=FS_proto.onwrite=FS_proto.onabort=FS_proto.onerror=FS_proto.onwriteend=null,function(blob,name,no_auto_bom){return new FileSaver(blob,name||blob.name||"download",no_auto_bom)})}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||window.content);function GifReader(buf){var p=0;if(71!==buf[p++]||73!==buf[p++]||70!==buf[p++]||56!==buf[p++]||56!=(buf[p++]+1&253)||97!==buf[p++])throw"Invalid GIF 87a/89a header.";var width=buf[p++]|buf[p++]<<8,height=buf[p++]|buf[p++]<<8,pf0=buf[p++],global_palette_flag=pf0>>7,num_global_colors=1<<(7&pf0)+1;buf[p++];buf[p++];var global_palette_offset=null;global_palette_flag&&(global_palette_offset=p,p+=3*num_global_colors);var no_eof=!0,frames=[],delay=0,transparent_index=null,disposal=0,loop_count=null;for(this.width=width,this.height=height;no_eof&&p<buf.length;)switch(buf[p++]){case 33:switch(buf[p++]){case 255:if(11!==buf[p]||78==buf[p+1]&&69==buf[p+2]&&84==buf[p+3]&&83==buf[p+4]&&67==buf[p+5]&&65==buf[p+6]&&80==buf[p+7]&&69==buf[p+8]&&50==buf[p+9]&&46==buf[p+10]&&48==buf[p+11]&&3==buf[p+12]&&1==buf[p+13]&&0==buf[p+16])p+=14,loop_count=buf[p++]|buf[p++]<<8,p++;else for(p+=12;;){if(0===(block_size=buf[p++]))break;p+=block_size}break;case 249:if(4!==buf[p++]||0!==buf[p+4])throw"Invalid graphics extension block.";var pf1=buf[p++];delay=buf[p++]|buf[p++]<<8,transparent_index=buf[p++],0==(1&pf1)&&(transparent_index=null),disposal=pf1>>2&7,p++;break;case 254:for(;;){if(0===(block_size=buf[p++]))break;p+=block_size}break;default:throw"Unknown graphic control label: 0x"+buf[p-1].toString(16)}break;case 44:var x=buf[p++]|buf[p++]<<8,y=buf[p++]|buf[p++]<<8,w=buf[p++]|buf[p++]<<8,h=buf[p++]|buf[p++]<<8,pf2=buf[p++],interlace_flag=pf2>>6&1,palette_offset=global_palette_offset,has_local_palette=!1;if(pf2>>7){has_local_palette=!0;palette_offset=p,p+=3*(1<<(7&pf2)+1)}var data_offset=p;for(p++;;){var block_size;if(0===(block_size=buf[p++]))break;p+=block_size}frames.push({x:x,y:y,width:w,height:h,has_local_palette:has_local_palette,palette_offset:palette_offset,data_offset:data_offset,data_length:p-data_offset,transparent_index:transparent_index,interlaced:!!interlace_flag,delay:delay,disposal:disposal});break;case 59:no_eof=!1;break;default:throw"Unknown gif block: 0x"+buf[p-1].toString(16)}this.numFrames=function(){return frames.length},this.loopCount=function(){return loop_count},this.frameInfo=function(frame_num){if(frame_num<0||frame_num>=frames.length)throw"Frame index out of range.";return frames[frame_num]},this.decodeAndBlitFrameBGRA=function(frame_num,pixels){var frame=this.frameInfo(frame_num),num_pixels=frame.width*frame.height,index_stream=new Uint8Array(num_pixels);GifReaderLZWOutputIndexStream(buf,frame.data_offset,index_stream,num_pixels);var palette_offset=frame.palette_offset,trans=frame.transparent_index;null===trans&&(trans=256);var framewidth=frame.width,framestride=width-framewidth,xleft=framewidth,opbeg=4*(frame.y*width+frame.x),opend=4*((frame.y+frame.height)*width+frame.x),op=opbeg,scanstride=4*framestride;!0===frame.interlaced&&(scanstride+=4*(framewidth+framestride)*7);for(var interlaceskip=8,i=0,il=index_stream.length;i<il;++i){var index=index_stream[i];if(0===xleft&&(xleft=framewidth,(op+=scanstride)>=opend&&(scanstride=framestride+4*(framewidth+framestride)*(interlaceskip-1),op=opbeg+(framewidth+framestride)*(interlaceskip<<1),interlaceskip>>=1)),index===trans)op+=4;else{var r=buf[palette_offset+3*index],g=buf[palette_offset+3*index+1],b=buf[palette_offset+3*index+2];pixels[op++]=b,pixels[op++]=g,pixels[op++]=r,pixels[op++]=255}--xleft}},this.decodeAndBlitFrameRGBA=function(frame_num,pixels){var frame=this.frameInfo(frame_num),num_pixels=frame.width*frame.height,index_stream=new Uint8Array(num_pixels);GifReaderLZWOutputIndexStream(buf,frame.data_offset,index_stream,num_pixels);var palette_offset=frame.palette_offset,trans=frame.transparent_index;null===trans&&(trans=256);var framewidth=frame.width,framestride=width-framewidth,xleft=framewidth,opbeg=4*(frame.y*width+frame.x),opend=4*((frame.y+frame.height)*width+frame.x),op=opbeg,scanstride=4*framestride;!0===frame.interlaced&&(scanstride+=4*(framewidth+framestride)*7);for(var interlaceskip=8,i=0,il=index_stream.length;i<il;++i){var index=index_stream[i];if(0===xleft&&(xleft=framewidth,(op+=scanstride)>=opend&&(scanstride=framestride+4*(framewidth+framestride)*(interlaceskip-1),op=opbeg+(framewidth+framestride)*(interlaceskip<<1),interlaceskip>>=1)),index===trans)op+=4;else{var r=buf[palette_offset+3*index],g=buf[palette_offset+3*index+1],b=buf[palette_offset+3*index+2];pixels[op++]=r,pixels[op++]=g,pixels[op++]=b,pixels[op++]=255}--xleft}}}function GifReaderLZWOutputIndexStream(code_stream,p,output,output_length){for(var min_code_size=code_stream[p++],clear_code=1<<min_code_size,eoi_code=clear_code+1,next_code=eoi_code+1,cur_code_size=min_code_size+1,code_mask=(1<<cur_code_size)-1,cur_shift=0,cur=0,op=0,subblock_size=code_stream[p++],code_table=new Int32Array(4096),prev_code=null;;){for(;cur_shift<16&&0!==subblock_size;)cur|=code_stream[p++]<<cur_shift,cur_shift+=8,1===subblock_size?subblock_size=code_stream[p++]:--subblock_size;if(cur_shift<cur_code_size)break;var code=cur&code_mask;if(cur>>=cur_code_size,cur_shift-=cur_code_size,code!==clear_code){if(code===eoi_code)break;for(var chase_code=code<next_code?code:prev_code,chase_length=0,chase=chase_code;chase>clear_code;)chase=code_table[chase]>>8,++chase_length;var k=chase;if(op+chase_length+(chase_code!==code?1:0)>output_length)return void console.log("Warning, gif stream longer than expected.");output[op++]=k;var b=op+=chase_length;for(chase_code!==code&&(output[op++]=k),chase=chase_code;chase_length--;)chase=code_table[chase],output[--b]=255&chase,chase>>=8;null!==prev_code&&next_code<4096&&(code_table[next_code++]=prev_code<<8|k,next_code>=code_mask+1&&cur_code_size<12&&(++cur_code_size,code_mask=code_mask<<1|1)),prev_code=code}else next_code=eoi_code+1,code_mask=(1<<(cur_code_size=min_code_size+1))-1,prev_code=null}return op!==output_length&&console.log("Warning, gif stream shorter than expected."),output}"undefined"!=typeof module&&module.exports?module.exports.saveAs=saveAs:"undefined"!=typeof define&&null!==define&&null!==define.amd&&define("FileSaver.js",(function(){return saveAs})),function(jsPDF,callback){jsPDF.API.adler32cs=function(){var _hasArrayBuffer="function"==typeof ArrayBuffer&&"function"==typeof Uint8Array,_Buffer=null,_isBuffer=function(){if(!_hasArrayBuffer)return function(){return!1};try{var buffer={};"function"==typeof buffer.Buffer&&(_Buffer=buffer.Buffer)}catch(error){}return function(value){return value instanceof ArrayBuffer||null!==_Buffer&&value instanceof _Buffer}}(),_utf8ToBinary=null!==_Buffer?function(utf8String){return new _Buffer(utf8String,"utf8").toString("binary")}:function(utf8String){return unescape(encodeURIComponent(utf8String))},MOD=65521,_update=function(checksum,binaryString){for(var a=65535&checksum,b=checksum>>>16,i=0,length=binaryString.length;i<length;i++)b=(b+(a=(a+(255&binaryString.charCodeAt(i)))%MOD))%MOD;return(b<<16|a)>>>0},_updateUint8Array=function(checksum,uint8Array){for(var a=65535&checksum,b=checksum>>>16,i=0,length=uint8Array.length;i<length;i++)b=(b+(a=(a+uint8Array[i])%MOD))%MOD;return(b<<16|a)>>>0},exports={},Adler32=exports.Adler32=(ctor=function(checksum){if(!(this instanceof ctor))throw new TypeError("Constructor cannot called be as a function.");if(!isFinite(checksum=null==checksum?1:+checksum))throw new Error("First arguments needs to be a finite number.");this.checksum=checksum>>>0},proto=ctor.prototype={},proto.constructor=ctor,ctor.from=((from=function(binaryString){if(!(this instanceof ctor))throw new TypeError("Constructor cannot called be as a function.");if(null==binaryString)throw new Error("First argument needs to be a string.");this.checksum=_update(1,binaryString.toString())}).prototype=proto,from),ctor.fromUtf8=((fromUtf8=function(utf8String){if(!(this instanceof ctor))throw new TypeError("Constructor cannot called be as a function.");if(null==utf8String)throw new Error("First argument needs to be a string.");var binaryString=_utf8ToBinary(utf8String.toString());this.checksum=_update(1,binaryString)}).prototype=proto,fromUtf8),_hasArrayBuffer&&(ctor.fromBuffer=((fromBuffer=function(buffer){if(!(this instanceof ctor))throw new TypeError("Constructor cannot called be as a function.");if(!_isBuffer(buffer))throw new Error("First argument needs to be ArrayBuffer.");var array=new Uint8Array(buffer);return this.checksum=_updateUint8Array(1,array)}).prototype=proto,fromBuffer)),proto.update=function(binaryString){if(null==binaryString)throw new Error("First argument needs to be a string.");return binaryString=binaryString.toString(),this.checksum=_update(this.checksum,binaryString)},proto.updateUtf8=function(utf8String){if(null==utf8String)throw new Error("First argument needs to be a string.");var binaryString=_utf8ToBinary(utf8String.toString());return this.checksum=_update(this.checksum,binaryString)},_hasArrayBuffer&&(proto.updateBuffer=function(buffer){if(!_isBuffer(buffer))throw new Error("First argument needs to be ArrayBuffer.");var array=new Uint8Array(buffer);return this.checksum=_updateUint8Array(this.checksum,array)}),proto.clone=function(){return new Adler32(this.checksum)},ctor);var from,fromUtf8,fromBuffer,ctor,proto;exports.from=function(binaryString){if(null==binaryString)throw new Error("First argument needs to be a string.");return _update(1,binaryString.toString())},exports.fromUtf8=function(utf8String){if(null==utf8String)throw new Error("First argument needs to be a string.");var binaryString=_utf8ToBinary(utf8String.toString());return _update(1,binaryString)},_hasArrayBuffer&&(exports.fromBuffer=function(buffer){if(!_isBuffer(buffer))throw new Error("First argument need to be ArrayBuffer.");var array=new Uint8Array(buffer);return _updateUint8Array(1,array)});return exports}()}(jsPDF);try{exports.GifWriter=function(buf,width,height,gopts){var p=0,loop_count=void 0===(gopts=void 0===gopts?{}:gopts).loop?null:gopts.loop,global_palette=void 0===gopts.palette?null:gopts.palette;if(width<=0||height<=0||width>65535||height>65535)throw"Width/Height invalid.";function check_palette_and_num_colors(palette){var num_colors=palette.length;if(num_colors<2||num_colors>256||num_colors&num_colors-1)throw"Invalid code/color length, must be power of 2 and 2 .. 256.";return num_colors}buf[p++]=71,buf[p++]=73,buf[p++]=70,buf[p++]=56,buf[p++]=57,buf[p++]=97;var gp_num_colors_pow2=0,background=0;if(null!==global_palette){for(var gp_num_colors=check_palette_and_num_colors(global_palette);gp_num_colors>>=1;)++gp_num_colors_pow2;if(gp_num_colors=1<<gp_num_colors_pow2,--gp_num_colors_pow2,void 0!==gopts.background){if((background=gopts.background)>=gp_num_colors)throw"Background index out of range.";if(0===background)throw"Background index explicitly passed as 0."}}if(buf[p++]=255&width,buf[p++]=width>>8&255,buf[p++]=255&height,buf[p++]=height>>8&255,buf[p++]=(null!==global_palette?128:0)|gp_num_colors_pow2,buf[p++]=background,buf[p++]=0,null!==global_palette)for(var i=0,il=global_palette.length;i<il;++i){var rgb=global_palette[i];buf[p++]=rgb>>16&255,buf[p++]=rgb>>8&255,buf[p++]=255&rgb}if(null!==loop_count){if(loop_count<0||loop_count>65535)throw"Loop count invalid.";buf[p++]=33,buf[p++]=255,buf[p++]=11,buf[p++]=78,buf[p++]=69,buf[p++]=84,buf[p++]=83,buf[p++]=67,buf[p++]=65,buf[p++]=80,buf[p++]=69,buf[p++]=50,buf[p++]=46,buf[p++]=48,buf[p++]=3,buf[p++]=1,buf[p++]=255&loop_count,buf[p++]=loop_count>>8&255,buf[p++]=0}var ended=!1;this.addFrame=function(x,y,w,h,indexed_pixels,opts){if(!0===ended&&(--p,ended=!1),opts=void 0===opts?{}:opts,x<0||y<0||x>65535||y>65535)throw"x/y invalid.";if(w<=0||h<=0||w>65535||h>65535)throw"Width/Height invalid.";if(indexed_pixels.length<w*h)throw"Not enough pixels for the frame size.";var using_local_palette=!0,palette=opts.palette;if(null==palette&&(using_local_palette=!1,palette=global_palette),null==palette)throw"Must supply either a local or global palette.";for(var num_colors=check_palette_and_num_colors(palette),min_code_size=0;num_colors>>=1;)++min_code_size;num_colors=1<<min_code_size;var delay=void 0===opts.delay?0:opts.delay,disposal=void 0===opts.disposal?0:opts.disposal;if(disposal<0||disposal>3)throw"Disposal out of range.";var use_transparency=!1,transparent_index=0;if(void 0!==opts.transparent&&null!==opts.transparent&&(use_transparency=!0,(transparent_index=opts.transparent)<0||transparent_index>=num_colors))throw"Transparent color index.";if((0!==disposal||use_transparency||0!==delay)&&(buf[p++]=33,buf[p++]=249,buf[p++]=4,buf[p++]=disposal<<2|(!0===use_transparency?1:0),buf[p++]=255&delay,buf[p++]=delay>>8&255,buf[p++]=transparent_index,buf[p++]=0),buf[p++]=44,buf[p++]=255&x,buf[p++]=x>>8&255,buf[p++]=255&y,buf[p++]=y>>8&255,buf[p++]=255&w,buf[p++]=w>>8&255,buf[p++]=255&h,buf[p++]=h>>8&255,buf[p++]=!0===using_local_palette?128|min_code_size-1:0,!0===using_local_palette)for(var i=0,il=palette.length;i<il;++i){var rgb=palette[i];buf[p++]=rgb>>16&255,buf[p++]=rgb>>8&255,buf[p++]=255&rgb}p=function(buf,p,min_code_size,index_stream){buf[p++]=min_code_size;var cur_subblock=p++,clear_code=1<<min_code_size,code_mask=clear_code-1,eoi_code=clear_code+1,next_code=eoi_code+1,cur_code_size=min_code_size+1,cur_shift=0,cur=0;function emit_bytes_to_buffer(bit_block_size){for(;cur_shift>=bit_block_size;)buf[p++]=255&cur,cur>>=8,cur_shift-=8,p===cur_subblock+256&&(buf[cur_subblock]=255,cur_subblock=p++)}function emit_code(c){cur|=c<<cur_shift,cur_shift+=cur_code_size,emit_bytes_to_buffer(8)}var ib_code=index_stream[0]&code_mask,code_table={};emit_code(clear_code);for(var i=1,il=index_stream.length;i<il;++i){var k=index_stream[i]&code_mask,cur_key=ib_code<<8|k,cur_code=code_table[cur_key];if(void 0===cur_code){for(cur|=ib_code<<cur_shift,cur_shift+=cur_code_size;cur_shift>=8;)buf[p++]=255&cur,cur>>=8,cur_shift-=8,p===cur_subblock+256&&(buf[cur_subblock]=255,cur_subblock=p++);4096===next_code?(emit_code(clear_code),next_code=eoi_code+1,cur_code_size=min_code_size+1,code_table={}):(next_code>=1<<cur_code_size&&++cur_code_size,code_table[cur_key]=next_code++),ib_code=k}else ib_code=cur_code}return emit_code(ib_code),emit_code(eoi_code),emit_bytes_to_buffer(1),cur_subblock+1===p?buf[cur_subblock]=0:(buf[cur_subblock]=p-cur_subblock-1,buf[p++]=0),p}(buf,p,min_code_size<2?2:min_code_size,indexed_pixels)},this.end=function(){return!1===ended&&(buf[p++]=59,ended=!0),p}},exports.GifReader=GifReader}catch(e){}function JPEGEncoder(quality){var YDC_HT,UVDC_HT,YAC_HT,UVAC_HT,currentQuality,ffloor=Math.floor,YTable=new Array(64),UVTable=new Array(64),fdtbl_Y=new Array(64),fdtbl_UV=new Array(64),bitcode=new Array(65535),category=new Array(65535),outputfDCTQuant=new Array(64),DU=new Array(64),byteout=[],bytenew=0,bytepos=7,YDU=new Array(64),UDU=new Array(64),VDU=new Array(64),clt=new Array(256),RGB_YUV_TABLE=new Array(2048),ZigZag=[0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18,24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63],std_dc_luminance_nrcodes=[0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0],std_dc_luminance_values=[0,1,2,3,4,5,6,7,8,9,10,11],std_ac_luminance_nrcodes=[0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,125],std_ac_luminance_values=[1,2,3,0,4,17,5,18,33,49,65,6,19,81,97,7,34,113,20,50,129,145,161,8,35,66,177,193,21,82,209,240,36,51,98,114,130,9,10,22,23,24,25,26,37,38,39,40,41,42,52,53,54,55,56,57,58,67,68,69,70,71,72,73,74,83,84,85,86,87,88,89,90,99,100,101,102,103,104,105,106,115,116,117,118,119,120,121,122,131,132,133,134,135,136,137,138,146,147,148,149,150,151,152,153,154,162,163,164,165,166,167,168,169,170,178,179,180,181,182,183,184,185,186,194,195,196,197,198,199,200,201,202,210,211,212,213,214,215,216,217,218,225,226,227,228,229,230,231,232,233,234,241,242,243,244,245,246,247,248,249,250],std_dc_chrominance_nrcodes=[0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0],std_dc_chrominance_values=[0,1,2,3,4,5,6,7,8,9,10,11],std_ac_chrominance_nrcodes=[0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,119],std_ac_chrominance_values=[0,1,2,3,17,4,5,33,49,6,18,65,81,7,97,113,19,34,50,129,8,20,66,145,161,177,193,9,35,51,82,240,21,98,114,209,10,22,36,52,225,37,241,23,24,25,26,38,39,40,41,42,53,54,55,56,57,58,67,68,69,70,71,72,73,74,83,84,85,86,87,88,89,90,99,100,101,102,103,104,105,106,115,116,117,118,119,120,121,122,130,131,132,133,134,135,136,137,138,146,147,148,149,150,151,152,153,154,162,163,164,165,166,167,168,169,170,178,179,180,181,182,183,184,185,186,194,195,196,197,198,199,200,201,202,210,211,212,213,214,215,216,217,218,226,227,228,229,230,231,232,233,234,242,243,244,245,246,247,248,249,250];function computeHuffmanTbl(nrcodes,std_table){for(var codevalue=0,pos_in_table=0,HT=new Array,k=1;k<=16;k++){for(var j=1;j<=nrcodes[k];j++)HT[std_table[pos_in_table]]=[],HT[std_table[pos_in_table]][0]=codevalue,HT[std_table[pos_in_table]][1]=k,pos_in_table++,codevalue++;codevalue*=2}return HT}function writeBits(bs){for(var value=bs[0],posval=bs[1]-1;posval>=0;)value&1<<posval&&(bytenew|=1<<bytepos),posval--,--bytepos<0&&(255==bytenew?(writeByte(255),writeByte(0)):writeByte(bytenew),bytepos=7,bytenew=0)}function writeByte(value){byteout.push(value)}function writeWord(value){writeByte(value>>8&255),writeByte(255&value)}function processDU(CDU,fdtbl,DC,HTDC,HTAC){for(var pos,EOB=HTAC[0],M16zeroes=HTAC[240],DU_DCT=function(data,fdtbl){var d0,d1,d2,d3,d4,d5,d6,d7,i,fDCTQuant,dataOff=0;for(i=0;i<8;++i){d0=data[dataOff],d1=data[dataOff+1],d2=data[dataOff+2],d3=data[dataOff+3],d4=data[dataOff+4],d5=data[dataOff+5],d6=data[dataOff+6];var tmp0=d0+(d7=data[dataOff+7]),tmp7=d0-d7,tmp1=d1+d6,tmp6=d1-d6,tmp2=d2+d5,tmp5=d2-d5,tmp3=d3+d4,tmp4=d3-d4,tmp10=tmp0+tmp3,tmp13=tmp0-tmp3,tmp11=tmp1+tmp2,tmp12=tmp1-tmp2;data[dataOff]=tmp10+tmp11,data[dataOff+4]=tmp10-tmp11;var z1=.707106781*(tmp12+tmp13);data[dataOff+2]=tmp13+z1,data[dataOff+6]=tmp13-z1;var z5=.382683433*((tmp10=tmp4+tmp5)-(tmp12=tmp6+tmp7)),z2=.5411961*tmp10+z5,z4=1.306562965*tmp12+z5,z3=.707106781*(tmp11=tmp5+tmp6),z11=tmp7+z3,z13=tmp7-z3;data[dataOff+5]=z13+z2,data[dataOff+3]=z13-z2,data[dataOff+1]=z11+z4,data[dataOff+7]=z11-z4,dataOff+=8}for(dataOff=0,i=0;i<8;++i){d0=data[dataOff],d1=data[dataOff+8],d2=data[dataOff+16],d3=data[dataOff+24],d4=data[dataOff+32],d5=data[dataOff+40],d6=data[dataOff+48];var tmp0p2=d0+(d7=data[dataOff+56]),tmp7p2=d0-d7,tmp1p2=d1+d6,tmp6p2=d1-d6,tmp2p2=d2+d5,tmp5p2=d2-d5,tmp3p2=d3+d4,tmp4p2=d3-d4,tmp10p2=tmp0p2+tmp3p2,tmp13p2=tmp0p2-tmp3p2,tmp11p2=tmp1p2+tmp2p2,tmp12p2=tmp1p2-tmp2p2;data[dataOff]=tmp10p2+tmp11p2,data[dataOff+32]=tmp10p2-tmp11p2;var z1p2=.707106781*(tmp12p2+tmp13p2);data[dataOff+16]=tmp13p2+z1p2,data[dataOff+48]=tmp13p2-z1p2;var z5p2=.382683433*((tmp10p2=tmp4p2+tmp5p2)-(tmp12p2=tmp6p2+tmp7p2)),z2p2=.5411961*tmp10p2+z5p2,z4p2=1.306562965*tmp12p2+z5p2,z3p2=.707106781*(tmp11p2=tmp5p2+tmp6p2),z11p2=tmp7p2+z3p2,z13p2=tmp7p2-z3p2;data[dataOff+40]=z13p2+z2p2,data[dataOff+24]=z13p2-z2p2,data[dataOff+8]=z11p2+z4p2,data[dataOff+56]=z11p2-z4p2,dataOff++}for(i=0;i<64;++i)fDCTQuant=data[i]*fdtbl[i],outputfDCTQuant[i]=fDCTQuant>0?fDCTQuant+.5|0:fDCTQuant-.5|0;return outputfDCTQuant}(CDU,fdtbl),j=0;j<64;++j)DU[ZigZag[j]]=DU_DCT[j];var Diff=DU[0]-DC;DC=DU[0],0==Diff?writeBits(HTDC[0]):(writeBits(HTDC[category[pos=32767+Diff]]),writeBits(bitcode[pos]));for(var end0pos=63;end0pos>0&&0==DU[end0pos];end0pos--);if(0==end0pos)return writeBits(EOB),DC;for(var lng,i=1;i<=end0pos;){for(var startpos=i;0==DU[i]&&i<=end0pos;++i);var nrzeroes=i-startpos;if(nrzeroes>=16){lng=nrzeroes>>4;for(var nrmarker=1;nrmarker<=lng;++nrmarker)writeBits(M16zeroes);nrzeroes&=15}pos=32767+DU[i],writeBits(HTAC[(nrzeroes<<4)+category[pos]]),writeBits(bitcode[pos]),i++}return 63!=end0pos&&writeBits(EOB),DC}function setQuality(quality){if(quality<=0&&(quality=1),quality>100&&(quality=100),currentQuality!=quality){(function(sf){for(var YQT=[16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22,37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99],i=0;i<64;i++){var t=ffloor((YQT[i]*sf+50)/100);t<1?t=1:t>255&&(t=255),YTable[ZigZag[i]]=t}for(var UVQT=[17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99],j=0;j<64;j++){var u=ffloor((UVQT[j]*sf+50)/100);u<1?u=1:u>255&&(u=255),UVTable[ZigZag[j]]=u}for(var aasf=[1,1.387039845,1.306562965,1.175875602,1,.785694958,.5411961,.275899379],k=0,row=0;row<8;row++)for(var col=0;col<8;col++)fdtbl_Y[k]=1/(YTable[ZigZag[k]]*aasf[row]*aasf[col]*8),fdtbl_UV[k]=1/(UVTable[ZigZag[k]]*aasf[row]*aasf[col]*8),k++})(quality<50?Math.floor(5e3/quality):Math.floor(200-2*quality)),currentQuality=quality}}this.encode=function(image,quality){(new Date).getTime();quality&&setQuality(quality),byteout=new Array,bytenew=0,bytepos=7,writeWord(65496),writeWord(65504),writeWord(16),writeByte(74),writeByte(70),writeByte(73),writeByte(70),writeByte(0),writeByte(1),writeByte(1),writeByte(0),writeWord(1),writeWord(1),writeByte(0),writeByte(0),function(){writeWord(65499),writeWord(132),writeByte(0);for(var i=0;i<64;i++)writeByte(YTable[i]);writeByte(1);for(var j=0;j<64;j++)writeByte(UVTable[j])}(),function(width,height){writeWord(65472),writeWord(17),writeByte(8),writeWord(height),writeWord(width),writeByte(3),writeByte(1),writeByte(17),writeByte(0),writeByte(2),writeByte(17),writeByte(1),writeByte(3),writeByte(17),writeByte(1)}(image.width,image.height),function(){writeWord(65476),writeWord(418),writeByte(0);for(var i=0;i<16;i++)writeByte(std_dc_luminance_nrcodes[i+1]);for(var j=0;j<=11;j++)writeByte(std_dc_luminance_values[j]);writeByte(16);for(var k=0;k<16;k++)writeByte(std_ac_luminance_nrcodes[k+1]);for(var l=0;l<=161;l++)writeByte(std_ac_luminance_values[l]);writeByte(1);for(var m=0;m<16;m++)writeByte(std_dc_chrominance_nrcodes[m+1]);for(var n=0;n<=11;n++)writeByte(std_dc_chrominance_values[n]);writeByte(17);for(var o=0;o<16;o++)writeByte(std_ac_chrominance_nrcodes[o+1]);for(var p=0;p<=161;p++)writeByte(std_ac_chrominance_values[p])}(),writeWord(65498),writeWord(12),writeByte(3),writeByte(1),writeByte(0),writeByte(2),writeByte(17),writeByte(3),writeByte(17),writeByte(0),writeByte(63),writeByte(0);var DCY=0,DCU=0,DCV=0;bytenew=0,bytepos=7,this.encode.displayName="_encode_";for(var x,r,g,b,start,p,col,row,pos,imageData=image.data,width=image.width,height=image.height,quadWidth=4*width,y=0;y<height;){for(x=0;x<quadWidth;){for(p=start=quadWidth*y+x,col=-1,row=0,pos=0;pos<64;pos++)p=start+(row=pos>>3)*quadWidth+(col=4*(7&pos)),y+row>=height&&(p-=quadWidth*(y+1+row-height)),x+col>=quadWidth&&(p-=x+col-quadWidth+4),r=imageData[p++],g=imageData[p++],b=imageData[p++],YDU[pos]=(RGB_YUV_TABLE[r]+RGB_YUV_TABLE[g+256>>0]+RGB_YUV_TABLE[b+512>>0]>>16)-128,UDU[pos]=(RGB_YUV_TABLE[r+768>>0]+RGB_YUV_TABLE[g+1024>>0]+RGB_YUV_TABLE[b+1280>>0]>>16)-128,VDU[pos]=(RGB_YUV_TABLE[r+1280>>0]+RGB_YUV_TABLE[g+1536>>0]+RGB_YUV_TABLE[b+1792>>0]>>16)-128;DCY=processDU(YDU,fdtbl_Y,DCY,YDC_HT,YAC_HT),DCU=processDU(UDU,fdtbl_UV,DCU,UVDC_HT,UVAC_HT),DCV=processDU(VDU,fdtbl_UV,DCV,UVDC_HT,UVAC_HT),x+=32}y+=8}if(bytepos>=0){var fillbits=[];fillbits[1]=bytepos+1,fillbits[0]=(1<<bytepos+1)-1,writeBits(fillbits)}return writeWord(65497),new Uint8Array(byteout)},function(){(new Date).getTime();quality||(quality=50),function(){for(var sfcc=String.fromCharCode,i=0;i<256;i++)clt[i]=sfcc(i)}(),YDC_HT=computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values),UVDC_HT=computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values),YAC_HT=computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values),UVAC_HT=computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values),function(){for(var nrlower=1,nrupper=2,cat=1;cat<=15;cat++){for(var nr=nrlower;nr<nrupper;nr++)category[32767+nr]=cat,bitcode[32767+nr]=[],bitcode[32767+nr][1]=cat,bitcode[32767+nr][0]=nr;for(var nrneg=-(nrupper-1);nrneg<=-nrlower;nrneg++)category[32767+nrneg]=cat,bitcode[32767+nrneg]=[],bitcode[32767+nrneg][1]=cat,bitcode[32767+nrneg][0]=nrupper-1+nrneg;nrlower<<=1,nrupper<<=1}}(),function(){for(var i=0;i<256;i++)RGB_YUV_TABLE[i]=19595*i,RGB_YUV_TABLE[i+256>>0]=38470*i,RGB_YUV_TABLE[i+512>>0]=7471*i+32768,RGB_YUV_TABLE[i+768>>0]=-11059*i,RGB_YUV_TABLE[i+1024>>0]=-21709*i,RGB_YUV_TABLE[i+1280>>0]=32768*i+8421375,RGB_YUV_TABLE[i+1536>>0]=-27439*i,RGB_YUV_TABLE[i+1792>>0]=-5329*i}(),setQuality(quality),(new Date).getTime()}()}try{module.exports=JPEGEncoder}catch(e){}function BmpDecoder(buffer,is_with_alpha){if(this.pos=0,this.buffer=buffer,this.datav=new DataView(buffer.buffer),this.is_with_alpha=!!is_with_alpha,this.bottom_up=!0,this.flag=String.fromCharCode(this.buffer[0])+String.fromCharCode(this.buffer[1]),this.pos+=2,-1===["BM","BA","CI","CP","IC","PT"].indexOf(this.flag))throw new Error("Invalid BMP File");this.parseHeader(),this.parseBGR()}BmpDecoder.prototype.parseHeader=function(){if(this.fileSize=this.datav.getUint32(this.pos,!0),this.pos+=4,this.reserved=this.datav.getUint32(this.pos,!0),this.pos+=4,this.offset=this.datav.getUint32(this.pos,!0),this.pos+=4,this.headerSize=this.datav.getUint32(this.pos,!0),this.pos+=4,this.width=this.datav.getUint32(this.pos,!0),this.pos+=4,this.height=this.datav.getInt32(this.pos,!0),this.pos+=4,this.planes=this.datav.getUint16(this.pos,!0),this.pos+=2,this.bitPP=this.datav.getUint16(this.pos,!0),this.pos+=2,this.compress=this.datav.getUint32(this.pos,!0),this.pos+=4,this.rawSize=this.datav.getUint32(this.pos,!0),this.pos+=4,this.hr=this.datav.getUint32(this.pos,!0),this.pos+=4,this.vr=this.datav.getUint32(this.pos,!0),this.pos+=4,this.colors=this.datav.getUint32(this.pos,!0),this.pos+=4,this.importantColors=this.datav.getUint32(this.pos,!0),this.pos+=4,16===this.bitPP&&this.is_with_alpha&&(this.bitPP=15),this.bitPP<15){var len=0===this.colors?1<<this.bitPP:this.colors;this.palette=new Array(len);for(var i=0;i<len;i++){var blue=this.datav.getUint8(this.pos++,!0),green=this.datav.getUint8(this.pos++,!0),red=this.datav.getUint8(this.pos++,!0),quad=this.datav.getUint8(this.pos++,!0);this.palette[i]={red:red,green:green,blue:blue,quad:quad}}}this.height<0&&(this.height*=-1,this.bottom_up=!1)},BmpDecoder.prototype.parseBGR=function(){this.pos=this.offset;try{var bitn="bit"+this.bitPP,len=this.width*this.height*4;this.data=new Uint8Array(len),this[bitn]()}catch(e){console.log("bit decode error:"+e)}},BmpDecoder.prototype.bit1=function(){var xlen=Math.ceil(this.width/8),mode=xlen%4,y=this.height>=0?this.height-1:-this.height;for(y=this.height-1;y>=0;y--){for(var line=this.bottom_up?y:this.height-1-y,x=0;x<xlen;x++)for(var b=this.datav.getUint8(this.pos++,!0),location=line*this.width*4+8*x*4,i=0;i<8&&8*x+i<this.width;i++){var rgb=this.palette[b>>7-i&1];this.data[location+4*i]=rgb.blue,this.data[location+4*i+1]=rgb.green,this.data[location+4*i+2]=rgb.red,this.data[location+4*i+3]=255}0!=mode&&(this.pos+=4-mode)}},BmpDecoder.prototype.bit4=function(){for(var xlen=Math.ceil(this.width/2),mode=xlen%4,y=this.height-1;y>=0;y--){for(var line=this.bottom_up?y:this.height-1-y,x=0;x<xlen;x++){var b=this.datav.getUint8(this.pos++,!0),location=line*this.width*4+2*x*4,before=b>>4,after=15&b,rgb=this.palette[before];if(this.data[location]=rgb.blue,this.data[location+1]=rgb.green,this.data[location+2]=rgb.red,this.data[location+3]=255,2*x+1>=this.width)break;rgb=this.palette[after],this.data[location+4]=rgb.blue,this.data[location+4+1]=rgb.green,this.data[location+4+2]=rgb.red,this.data[location+4+3]=255}0!=mode&&(this.pos+=4-mode)}},BmpDecoder.prototype.bit8=function(){for(var mode=this.width%4,y=this.height-1;y>=0;y--){for(var line=this.bottom_up?y:this.height-1-y,x=0;x<this.width;x++){var b=this.datav.getUint8(this.pos++,!0),location=line*this.width*4+4*x;if(b<this.palette.length){var rgb=this.palette[b];this.data[location]=rgb.red,this.data[location+1]=rgb.green,this.data[location+2]=rgb.blue,this.data[location+3]=255}else this.data[location]=255,this.data[location+1]=255,this.data[location+2]=255,this.data[location+3]=255}0!=mode&&(this.pos+=4-mode)}},BmpDecoder.prototype.bit15=function(){for(var dif_w=this.width%3,_1_5=parseInt("11111",2),y=this.height-1;y>=0;y--){for(var line=this.bottom_up?y:this.height-1-y,x=0;x<this.width;x++){var B=this.datav.getUint16(this.pos,!0);this.pos+=2;var blue=(B&_1_5)/_1_5*255|0,green=(B>>5&_1_5)/_1_5*255|0,red=(B>>10&_1_5)/_1_5*255|0,alpha=B>>15?255:0,location=line*this.width*4+4*x;this.data[location]=red,this.data[location+1]=green,this.data[location+2]=blue,this.data[location+3]=alpha}this.pos+=dif_w}},BmpDecoder.prototype.bit16=function(){for(var dif_w=this.width%3,_1_5=parseInt("11111",2),_1_6=parseInt("111111",2),y=this.height-1;y>=0;y--){for(var line=this.bottom_up?y:this.height-1-y,x=0;x<this.width;x++){var B=this.datav.getUint16(this.pos,!0);this.pos+=2;var blue=(B&_1_5)/_1_5*255|0,green=(B>>5&_1_6)/_1_6*255|0,red=(B>>11)/_1_5*255|0,location=line*this.width*4+4*x;this.data[location]=red,this.data[location+1]=green,this.data[location+2]=blue,this.data[location+3]=255}this.pos+=dif_w}},BmpDecoder.prototype.bit24=function(){for(var y=this.height-1;y>=0;y--){for(var line=this.bottom_up?y:this.height-1-y,x=0;x<this.width;x++){var blue=this.datav.getUint8(this.pos++,!0),green=this.datav.getUint8(this.pos++,!0),red=this.datav.getUint8(this.pos++,!0),location=line*this.width*4+4*x;this.data[location]=red,this.data[location+1]=green,this.data[location+2]=blue,this.data[location+3]=255}this.pos+=this.width%4}},BmpDecoder.prototype.bit32=function(){for(var y=this.height-1;y>=0;y--)for(var line=this.bottom_up?y:this.height-1-y,x=0;x<this.width;x++){var blue=this.datav.getUint8(this.pos++,!0),green=this.datav.getUint8(this.pos++,!0),red=this.datav.getUint8(this.pos++,!0),alpha=this.datav.getUint8(this.pos++,!0),location=line*this.width*4+4*x;this.data[location]=red,this.data[location+1]=green,this.data[location+2]=blue,this.data[location+3]=alpha}},BmpDecoder.prototype.getData=function(){return this.data};try{module.exports=function(bmpData){var decoder=new BmpDecoder(bmpData);return{data:decoder.getData(),width:decoder.width,height:decoder.height}}}catch(e){}!function(global){var _dist_code=[0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,0,0,16,17,18,18,19,19,20,20,20,20,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29];function Tree(){var that=this;function bi_reverse(code,len){var res=0;do{res|=1&code,code>>>=1,res<<=1}while(--len>0);return res>>>1}that.build_tree=function(s){var n,m,node,tree=that.dyn_tree,stree=that.stat_desc.static_tree,elems=that.stat_desc.elems,max_code=-1;for(s.heap_len=0,s.heap_max=573,n=0;n<elems;n++)0!==tree[2*n]?(s.heap[++s.heap_len]=max_code=n,s.depth[n]=0):tree[2*n+1]=0;for(;s.heap_len<2;)tree[2*(node=s.heap[++s.heap_len]=max_code<2?++max_code:0)]=1,s.depth[node]=0,s.opt_len--,stree&&(s.static_len-=stree[2*node+1]);for(that.max_code=max_code,n=Math.floor(s.heap_len/2);n>=1;n--)s.pqdownheap(tree,n);node=elems;do{n=s.heap[1],s.heap[1]=s.heap[s.heap_len--],s.pqdownheap(tree,1),m=s.heap[1],s.heap[--s.heap_max]=n,s.heap[--s.heap_max]=m,tree[2*node]=tree[2*n]+tree[2*m],s.depth[node]=Math.max(s.depth[n],s.depth[m])+1,tree[2*n+1]=tree[2*m+1]=node,s.heap[1]=node++,s.pqdownheap(tree,1)}while(s.heap_len>=2);s.heap[--s.heap_max]=s.heap[1],function(s){var h,n,m,bits,xbits,f,tree=that.dyn_tree,stree=that.stat_desc.static_tree,extra=that.stat_desc.extra_bits,base=that.stat_desc.extra_base,max_length=that.stat_desc.max_length,overflow=0;for(bits=0;bits<=15;bits++)s.bl_count[bits]=0;for(tree[2*s.heap[s.heap_max]+1]=0,h=s.heap_max+1;h<573;h++)(bits=tree[2*tree[2*(n=s.heap[h])+1]+1]+1)>max_length&&(bits=max_length,overflow++),tree[2*n+1]=bits,n>that.max_code||(s.bl_count[bits]++,xbits=0,n>=base&&(xbits=extra[n-base]),f=tree[2*n],s.opt_len+=f*(bits+xbits),stree&&(s.static_len+=f*(stree[2*n+1]+xbits)));if(0!==overflow){do{for(bits=max_length-1;0===s.bl_count[bits];)bits--;s.bl_count[bits]--,s.bl_count[bits+1]+=2,s.bl_count[max_length]--,overflow-=2}while(overflow>0);for(bits=max_length;0!==bits;bits--)for(n=s.bl_count[bits];0!==n;)(m=s.heap[--h])>that.max_code||(tree[2*m+1]!=bits&&(s.opt_len+=(bits-tree[2*m+1])*tree[2*m],tree[2*m+1]=bits),n--)}}(s),function(tree,max_code,bl_count){var bits,n,len,next_code=[],code=0;for(bits=1;bits<=15;bits++)next_code[bits]=code=code+bl_count[bits-1]<<1;for(n=0;n<=max_code;n++)0!==(len=tree[2*n+1])&&(tree[2*n]=bi_reverse(next_code[len]++,len))}(tree,that.max_code,s.bl_count)}}function StaticTree(static_tree,extra_bits,extra_base,elems,max_length){this.static_tree=static_tree,this.extra_bits=extra_bits,this.extra_base=extra_base,this.elems=elems,this.max_length=max_length}Tree._length_code=[0,1,2,3,4,5,6,7,8,8,9,9,10,10,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28],Tree.base_length=[0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224,0],Tree.base_dist=[0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576],Tree.d_code=function(dist){return dist<256?_dist_code[dist]:_dist_code[256+(dist>>>7)]},Tree.extra_lbits=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],Tree.extra_dbits=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],Tree.extra_blbits=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],Tree.bl_order=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],StaticTree.static_ltree=[12,8,140,8,76,8,204,8,44,8,172,8,108,8,236,8,28,8,156,8,92,8,220,8,60,8,188,8,124,8,252,8,2,8,130,8,66,8,194,8,34,8,162,8,98,8,226,8,18,8,146,8,82,8,210,8,50,8,178,8,114,8,242,8,10,8,138,8,74,8,202,8,42,8,170,8,106,8,234,8,26,8,154,8,90,8,218,8,58,8,186,8,122,8,250,8,6,8,134,8,70,8,198,8,38,8,166,8,102,8,230,8,22,8,150,8,86,8,214,8,54,8,182,8,118,8,246,8,14,8,142,8,78,8,206,8,46,8,174,8,110,8,238,8,30,8,158,8,94,8,222,8,62,8,190,8,126,8,254,8,1,8,129,8,65,8,193,8,33,8,161,8,97,8,225,8,17,8,145,8,81,8,209,8,49,8,177,8,113,8,241,8,9,8,137,8,73,8,201,8,41,8,169,8,105,8,233,8,25,8,153,8,89,8,217,8,57,8,185,8,121,8,249,8,5,8,133,8,69,8,197,8,37,8,165,8,101,8,229,8,21,8,149,8,85,8,213,8,53,8,181,8,117,8,245,8,13,8,141,8,77,8,205,8,45,8,173,8,109,8,237,8,29,8,157,8,93,8,221,8,61,8,189,8,125,8,253,8,19,9,275,9,147,9,403,9,83,9,339,9,211,9,467,9,51,9,307,9,179,9,435,9,115,9,371,9,243,9,499,9,11,9,267,9,139,9,395,9,75,9,331,9,203,9,459,9,43,9,299,9,171,9,427,9,107,9,363,9,235,9,491,9,27,9,283,9,155,9,411,9,91,9,347,9,219,9,475,9,59,9,315,9,187,9,443,9,123,9,379,9,251,9,507,9,7,9,263,9,135,9,391,9,71,9,327,9,199,9,455,9,39,9,295,9,167,9,423,9,103,9,359,9,231,9,487,9,23,9,279,9,151,9,407,9,87,9,343,9,215,9,471,9,55,9,311,9,183,9,439,9,119,9,375,9,247,9,503,9,15,9,271,9,143,9,399,9,79,9,335,9,207,9,463,9,47,9,303,9,175,9,431,9,111,9,367,9,239,9,495,9,31,9,287,9,159,9,415,9,95,9,351,9,223,9,479,9,63,9,319,9,191,9,447,9,127,9,383,9,255,9,511,9,0,7,64,7,32,7,96,7,16,7,80,7,48,7,112,7,8,7,72,7,40,7,104,7,24,7,88,7,56,7,120,7,4,7,68,7,36,7,100,7,20,7,84,7,52,7,116,7,3,8,131,8,67,8,195,8,35,8,163,8,99,8,227,8],StaticTree.static_dtree=[0,5,16,5,8,5,24,5,4,5,20,5,12,5,28,5,2,5,18,5,10,5,26,5,6,5,22,5,14,5,30,5,1,5,17,5,9,5,25,5,5,5,21,5,13,5,29,5,3,5,19,5,11,5,27,5,7,5,23,5],StaticTree.static_l_desc=new StaticTree(StaticTree.static_ltree,Tree.extra_lbits,257,286,15),StaticTree.static_d_desc=new StaticTree(StaticTree.static_dtree,Tree.extra_dbits,0,30,15),StaticTree.static_bl_desc=new StaticTree(null,Tree.extra_blbits,0,19,7);function Config(good_length,max_lazy,nice_length,max_chain,func){this.good_length=good_length,this.max_lazy=max_lazy,this.nice_length=nice_length,this.max_chain=max_chain,this.func=func}var config_table=[new Config(0,0,0,0,0),new Config(4,4,8,4,1),new Config(4,5,16,8,1),new Config(4,6,32,32,1),new Config(4,4,16,16,2),new Config(8,16,32,32,2),new Config(8,16,128,128,2),new Config(8,32,128,256,2),new Config(32,128,258,1024,2),new Config(32,258,258,4096,2)],z_errmsg=["need dictionary","stream end","","","stream error","data error","","buffer error","",""];function smaller(tree,n,m,depth){var tn2=tree[2*n],tm2=tree[2*m];return tn2<tm2||tn2==tm2&&depth[n]<=depth[m]}function Deflate(){var strm,status,pending_buf_size,last_flush,w_size,w_bits,w_mask,window,window_size,prev,head,ins_h,hash_size,hash_bits,hash_mask,hash_shift,block_start,match_length,prev_match,match_available,strstart,match_start,lookahead,prev_length,max_chain_length,max_lazy_match,level,strategy,good_match,nice_match,dyn_ltree,dyn_dtree,bl_tree,l_buf,lit_bufsize,last_lit,d_buf,matches,last_eob_len,bi_buf,bi_valid,that=this,l_desc=new Tree,d_desc=new Tree,bl_desc=new Tree;function init_block(){var i;for(i=0;i<286;i++)dyn_ltree[2*i]=0;for(i=0;i<30;i++)dyn_dtree[2*i]=0;for(i=0;i<19;i++)bl_tree[2*i]=0;dyn_ltree[512]=1,that.opt_len=that.static_len=0,last_lit=matches=0}function scan_tree(tree,max_code){var n,curlen,prevlen=-1,nextlen=tree[1],count=0,max_count=7,min_count=4;for(0===nextlen&&(max_count=138,min_count=3),tree[2*(max_code+1)+1]=65535,n=0;n<=max_code;n++)curlen=nextlen,nextlen=tree[2*(n+1)+1],++count<max_count&&curlen==nextlen||(count<min_count?bl_tree[2*curlen]+=count:0!==curlen?(curlen!=prevlen&&bl_tree[2*curlen]++,bl_tree[32]++):count<=10?bl_tree[34]++:bl_tree[36]++,count=0,prevlen=curlen,0===nextlen?(max_count=138,min_count=3):curlen==nextlen?(max_count=6,min_count=3):(max_count=7,min_count=4))}function put_byte(p){that.pending_buf[that.pending++]=p}function put_short(w){put_byte(255&w),put_byte(w>>>8&255)}function send_bits(value,length){var val,len=length;bi_valid>16-len?(put_short(bi_buf|=(val=value)<<bi_valid&65535),bi_buf=val>>>16-bi_valid,bi_valid+=len-16):(bi_buf|=value<<bi_valid&65535,bi_valid+=len)}function send_code(c,tree){var c2=2*c;send_bits(65535&tree[c2],65535&tree[c2+1])}function send_tree(tree,max_code){var n,curlen,prevlen=-1,nextlen=tree[1],count=0,max_count=7,min_count=4;for(0===nextlen&&(max_count=138,min_count=3),n=0;n<=max_code;n++)if(curlen=nextlen,nextlen=tree[2*(n+1)+1],!(++count<max_count&&curlen==nextlen)){if(count<min_count)do{send_code(curlen,bl_tree)}while(0!=--count);else 0!==curlen?(curlen!=prevlen&&(send_code(curlen,bl_tree),count--),send_code(16,bl_tree),send_bits(count-3,2)):count<=10?(send_code(17,bl_tree),send_bits(count-3,3)):(send_code(18,bl_tree),send_bits(count-11,7));count=0,prevlen=curlen,0===nextlen?(max_count=138,min_count=3):curlen==nextlen?(max_count=6,min_count=3):(max_count=7,min_count=4)}}function bi_flush(){16==bi_valid?(put_short(bi_buf),bi_buf=0,bi_valid=0):bi_valid>=8&&(put_byte(255&bi_buf),bi_buf>>>=8,bi_valid-=8)}function _tr_tally(dist,lc){var out_length,in_length,dcode;if(that.pending_buf[d_buf+2*last_lit]=dist>>>8&255,that.pending_buf[d_buf+2*last_lit+1]=255&dist,that.pending_buf[l_buf+last_lit]=255&lc,last_lit++,0===dist?dyn_ltree[2*lc]++:(matches++,dist--,dyn_ltree[2*(Tree._length_code[lc]+256+1)]++,dyn_dtree[2*Tree.d_code(dist)]++),0==(8191&last_lit)&&level>2){for(out_length=8*last_lit,in_length=strstart-block_start,dcode=0;dcode<30;dcode++)out_length+=dyn_dtree[2*dcode]*(5+Tree.extra_dbits[dcode]);if(out_length>>>=3,matches<Math.floor(last_lit/2)&&out_length<Math.floor(in_length/2))return!0}return last_lit==lit_bufsize-1}function compress_block(ltree,dtree){var dist,lc,code,extra,lx=0;if(0!==last_lit)do{dist=that.pending_buf[d_buf+2*lx]<<8&65280|255&that.pending_buf[d_buf+2*lx+1],lc=255&that.pending_buf[l_buf+lx],lx++,0===dist?send_code(lc,ltree):(send_code((code=Tree._length_code[lc])+256+1,ltree),0!==(extra=Tree.extra_lbits[code])&&send_bits(lc-=Tree.base_length[code],extra),dist--,send_code(code=Tree.d_code(dist),dtree),0!==(extra=Tree.extra_dbits[code])&&send_bits(dist-=Tree.base_dist[code],extra))}while(lx<last_lit);send_code(256,ltree),last_eob_len=ltree[513]}function bi_windup(){bi_valid>8?put_short(bi_buf):bi_valid>0&&put_byte(255&bi_buf),bi_buf=0,bi_valid=0}function _tr_stored_block(buf,stored_len,eof){send_bits(0+(eof?1:0),3),function(buf,len,header){bi_windup(),last_eob_len=8,header&&(put_short(len),put_short(~len)),that.pending_buf.set(window.subarray(buf,buf+len),that.pending),that.pending+=len}(buf,stored_len,!0)}function _tr_flush_block(buf,stored_len,eof){var opt_lenb,static_lenb,max_blindex=0;level>0?(l_desc.build_tree(that),d_desc.build_tree(that),max_blindex=function(){var max_blindex;for(scan_tree(dyn_ltree,l_desc.max_code),scan_tree(dyn_dtree,d_desc.max_code),bl_desc.build_tree(that),max_blindex=18;max_blindex>=3&&0===bl_tree[2*Tree.bl_order[max_blindex]+1];max_blindex--);return that.opt_len+=3*(max_blindex+1)+5+5+4,max_blindex}(),opt_lenb=that.opt_len+3+7>>>3,(static_lenb=that.static_len+3+7>>>3)<=opt_lenb&&(opt_lenb=static_lenb)):opt_lenb=static_lenb=stored_len+5,stored_len+4<=opt_lenb&&-1!=buf?_tr_stored_block(buf,stored_len,eof):static_lenb==opt_lenb?(send_bits(2+(eof?1:0),3),compress_block(StaticTree.static_ltree,StaticTree.static_dtree)):(send_bits(4+(eof?1:0),3),function(lcodes,dcodes,blcodes){var rank;for(send_bits(lcodes-257,5),send_bits(dcodes-1,5),send_bits(blcodes-4,4),rank=0;rank<blcodes;rank++)send_bits(bl_tree[2*Tree.bl_order[rank]+1],3);send_tree(dyn_ltree,lcodes-1),send_tree(dyn_dtree,dcodes-1)}(l_desc.max_code+1,d_desc.max_code+1,max_blindex+1),compress_block(dyn_ltree,dyn_dtree)),init_block(),eof&&bi_windup()}function flush_block_only(eof){_tr_flush_block(block_start>=0?block_start:-1,strstart-block_start,eof),block_start=strstart,strm.flush_pending()}function fill_window(){var n,m,p,more;do{if(0===(more=window_size-lookahead-strstart)&&0===strstart&&0===lookahead)more=w_size;else if(-1==more)more--;else if(strstart>=w_size+w_size-262){window.set(window.subarray(w_size,w_size+w_size),0),match_start-=w_size,strstart-=w_size,block_start-=w_size,p=n=hash_size;do{m=65535&head[--p],head[p]=m>=w_size?m-w_size:0}while(0!=--n);p=n=w_size;do{m=65535&prev[--p],prev[p]=m>=w_size?m-w_size:0}while(0!=--n);more+=w_size}if(0===strm.avail_in)return;n=strm.read_buf(window,strstart+lookahead,more),(lookahead+=n)>=3&&(ins_h=((ins_h=255&window[strstart])<<hash_shift^255&window[strstart+1])&hash_mask)}while(lookahead<262&&0!==strm.avail_in)}function longest_match(cur_match){var match,len,chain_length=max_chain_length,scan=strstart,best_len=prev_length,limit=strstart>w_size-262?strstart-(w_size-262):0,_nice_match=nice_match,wmask=w_mask,strend=strstart+258,scan_end1=window[scan+best_len-1],scan_end=window[scan+best_len];prev_length>=good_match&&(chain_length>>=2),_nice_match>lookahead&&(_nice_match=lookahead);do{if(window[(match=cur_match)+best_len]==scan_end&&window[match+best_len-1]==scan_end1&&window[match]==window[scan]&&window[++match]==window[scan+1]){scan+=2,match++;do{}while(window[++scan]==window[++match]&&window[++scan]==window[++match]&&window[++scan]==window[++match]&&window[++scan]==window[++match]&&window[++scan]==window[++match]&&window[++scan]==window[++match]&&window[++scan]==window[++match]&&window[++scan]==window[++match]&&scan<strend);if(len=258-(strend-scan),scan=strend-258,len>best_len){if(match_start=cur_match,best_len=len,len>=_nice_match)break;scan_end1=window[scan+best_len-1],scan_end=window[scan+best_len]}}}while((cur_match=65535&prev[cur_match&wmask])>limit&&0!=--chain_length);return best_len<=lookahead?best_len:lookahead}function deflateReset(strm){return strm.total_in=strm.total_out=0,strm.msg=null,that.pending=0,that.pending_out=0,status=113,last_flush=0,l_desc.dyn_tree=dyn_ltree,l_desc.stat_desc=StaticTree.static_l_desc,d_desc.dyn_tree=dyn_dtree,d_desc.stat_desc=StaticTree.static_d_desc,bl_desc.dyn_tree=bl_tree,bl_desc.stat_desc=StaticTree.static_bl_desc,bi_buf=0,bi_valid=0,last_eob_len=8,init_block(),function(){var i;for(window_size=2*w_size,head[hash_size-1]=0,i=0;i<hash_size-1;i++)head[i]=0;max_lazy_match=config_table[level].max_lazy,good_match=config_table[level].good_length,nice_match=config_table[level].nice_length,max_chain_length=config_table[level].max_chain,strstart=0,block_start=0,lookahead=0,match_length=prev_length=2,match_available=0,ins_h=0}(),0}that.depth=[],that.bl_count=[],that.heap=[],dyn_ltree=[],dyn_dtree=[],bl_tree=[],that.pqdownheap=function(tree,k){for(var heap=that.heap,v=heap[k],j=k<<1;j<=that.heap_len&&(j<that.heap_len&&smaller(tree,heap[j+1],heap[j],that.depth)&&j++,!smaller(tree,v,heap[j],that.depth));)heap[k]=heap[j],k=j,j<<=1;heap[k]=v},that.deflateInit=function(strm,_level,bits,_method,memLevel,_strategy){return _method||(_method=8),memLevel||(memLevel=8),_strategy||(_strategy=0),strm.msg=null,-1==_level&&(_level=6),memLevel<1||memLevel>9||8!=_method||bits<9||bits>15||_level<0||_level>9||_strategy<0||_strategy>2?-2:(strm.dstate=that,w_mask=(w_size=1<<(w_bits=bits))-1,hash_mask=(hash_size=1<<(hash_bits=memLevel+7))-1,hash_shift=Math.floor((hash_bits+3-1)/3),window=new Uint8Array(2*w_size),prev=[],head=[],lit_bufsize=1<<memLevel+6,that.pending_buf=new Uint8Array(4*lit_bufsize),pending_buf_size=4*lit_bufsize,d_buf=Math.floor(lit_bufsize/2),l_buf=3*lit_bufsize,level=_level,strategy=_strategy,deflateReset(strm))},that.deflateEnd=function(){return 42!=status&&113!=status&&666!=status?-2:(that.pending_buf=null,head=null,prev=null,window=null,that.dstate=null,113==status?-3:0)},that.deflateParams=function(strm,_level,_strategy){var err=0;return-1==_level&&(_level=6),_level<0||_level>9||_strategy<0||_strategy>2?-2:(config_table[level].func!=config_table[_level].func&&0!==strm.total_in&&(err=strm.deflate(1)),level!=_level&&(max_lazy_match=config_table[level=_level].max_lazy,good_match=config_table[level].good_length,nice_match=config_table[level].nice_length,max_chain_length=config_table[level].max_chain),strategy=_strategy,err)},that.deflateSetDictionary=function(strm,dictionary,dictLength){var n,length=dictLength,index=0;if(!dictionary||42!=status)return-2;if(length<3)return 0;for(length>w_size-262&&(index=dictLength-(length=w_size-262)),window.set(dictionary.subarray(index,index+length),0),strstart=length,block_start=length,ins_h=((ins_h=255&window[0])<<hash_shift^255&window[1])&hash_mask,n=0;n<=length-3;n++)ins_h=(ins_h<<hash_shift^255&window[n+2])&hash_mask,prev[n&w_mask]=head[ins_h],head[ins_h]=n;return 0},that.deflate=function(_strm,flush){var i,header,level_flags,old_flush,bstate,b;if(flush>4||flush<0)return-2;if(!_strm.next_out||!_strm.next_in&&0!==_strm.avail_in||666==status&&4!=flush)return _strm.msg=z_errmsg[4],-2;if(0===_strm.avail_out)return _strm.msg=z_errmsg[7],-5;if(strm=_strm,old_flush=last_flush,last_flush=flush,42==status&&(header=8+(w_bits-8<<4)<<8,(level_flags=(level-1&255)>>1)>3&&(level_flags=3),header|=level_flags<<6,0!==strstart&&(header|=32),status=113,put_byte((b=header+=31-header%31)>>8&255),put_byte(255&b)),0!==that.pending){if(strm.flush_pending(),0===strm.avail_out)return last_flush=-1,0}else if(0===strm.avail_in&&flush<=old_flush&&4!=flush)return strm.msg=z_errmsg[7],-5;if(666==status&&0!==strm.avail_in)return _strm.msg=z_errmsg[7],-5;if(0!==strm.avail_in||0!==lookahead||0!=flush&&666!=status){switch(bstate=-1,config_table[level].func){case 0:bstate=function(flush){var max_start,max_block_size=65535;for(max_block_size>pending_buf_size-5&&(max_block_size=pending_buf_size-5);;){if(lookahead<=1){if(fill_window(),0===lookahead&&0==flush)return 0;if(0===lookahead)break}if(strstart+=lookahead,lookahead=0,max_start=block_start+max_block_size,(0===strstart||strstart>=max_start)&&(lookahead=strstart-max_start,strstart=max_start,flush_block_only(!1),0===strm.avail_out))return 0;if(strstart-block_start>=w_size-262&&(flush_block_only(!1),0===strm.avail_out))return 0}return flush_block_only(4==flush),0===strm.avail_out?4==flush?2:0:4==flush?3:1}(flush);break;case 1:bstate=function(flush){for(var bflush,hash_head=0;;){if(lookahead<262){if(fill_window(),lookahead<262&&0==flush)return 0;if(0===lookahead)break}if(lookahead>=3&&(ins_h=(ins_h<<hash_shift^255&window[strstart+2])&hash_mask,hash_head=65535&head[ins_h],prev[strstart&w_mask]=head[ins_h],head[ins_h]=strstart),0!==hash_head&&(strstart-hash_head&65535)<=w_size-262&&2!=strategy&&(match_length=longest_match(hash_head)),match_length>=3)if(bflush=_tr_tally(strstart-match_start,match_length-3),lookahead-=match_length,match_length<=max_lazy_match&&lookahead>=3){match_length--;do{strstart++,ins_h=(ins_h<<hash_shift^255&window[strstart+2])&hash_mask,hash_head=65535&head[ins_h],prev[strstart&w_mask]=head[ins_h],head[ins_h]=strstart}while(0!=--match_length);strstart++}else strstart+=match_length,match_length=0,ins_h=((ins_h=255&window[strstart])<<hash_shift^255&window[strstart+1])&hash_mask;else bflush=_tr_tally(0,255&window[strstart]),lookahead--,strstart++;if(bflush&&(flush_block_only(!1),0===strm.avail_out))return 0}return flush_block_only(4==flush),0===strm.avail_out?4==flush?2:0:4==flush?3:1}(flush);break;case 2:bstate=function(flush){for(var bflush,max_insert,hash_head=0;;){if(lookahead<262){if(fill_window(),lookahead<262&&0==flush)return 0;if(0===lookahead)break}if(lookahead>=3&&(ins_h=(ins_h<<hash_shift^255&window[strstart+2])&hash_mask,hash_head=65535&head[ins_h],prev[strstart&w_mask]=head[ins_h],head[ins_h]=strstart),prev_length=match_length,prev_match=match_start,match_length=2,0!==hash_head&&prev_length<max_lazy_match&&(strstart-hash_head&65535)<=w_size-262&&(2!=strategy&&(match_length=longest_match(hash_head)),match_length<=5&&(1==strategy||3==match_length&&strstart-match_start>4096)&&(match_length=2)),prev_length>=3&&match_length<=prev_length){max_insert=strstart+lookahead-3,bflush=_tr_tally(strstart-1-prev_match,prev_length-3),lookahead-=prev_length-1,prev_length-=2;do{++strstart<=max_insert&&(ins_h=(ins_h<<hash_shift^255&window[strstart+2])&hash_mask,hash_head=65535&head[ins_h],prev[strstart&w_mask]=head[ins_h],head[ins_h]=strstart)}while(0!=--prev_length);if(match_available=0,match_length=2,strstart++,bflush&&(flush_block_only(!1),0===strm.avail_out))return 0}else if(0!==match_available){if((bflush=_tr_tally(0,255&window[strstart-1]))&&flush_block_only(!1),strstart++,lookahead--,0===strm.avail_out)return 0}else match_available=1,strstart++,lookahead--}return 0!==match_available&&(bflush=_tr_tally(0,255&window[strstart-1]),match_available=0),flush_block_only(4==flush),0===strm.avail_out?4==flush?2:0:4==flush?3:1}(flush)}if(2!=bstate&&3!=bstate||(status=666),0==bstate||2==bstate)return 0===strm.avail_out&&(last_flush=-1),0;if(1==bstate){if(1==flush)send_bits(2,3),send_code(256,StaticTree.static_ltree),bi_flush(),1+last_eob_len+10-bi_valid<9&&(send_bits(2,3),send_code(256,StaticTree.static_ltree),bi_flush()),last_eob_len=7;else if(_tr_stored_block(0,0,!1),3==flush)for(i=0;i<hash_size;i++)head[i]=0;if(strm.flush_pending(),0===strm.avail_out)return last_flush=-1,0}}return 4!=flush?0:1}}function ZStream(){this.next_in_index=0,this.next_out_index=0,this.avail_in=0,this.total_in=0,this.avail_out=0,this.total_out=0}ZStream.prototype={deflateInit:function(level,bits){return this.dstate=new Deflate,bits||(bits=15),this.dstate.deflateInit(this,level,bits)},deflate:function(flush){return this.dstate?this.dstate.deflate(this,flush):-2},deflateEnd:function(){if(!this.dstate)return-2;var ret=this.dstate.deflateEnd();return this.dstate=null,ret},deflateParams:function(level,strategy){return this.dstate?this.dstate.deflateParams(this,level,strategy):-2},deflateSetDictionary:function(dictionary,dictLength){return this.dstate?this.dstate.deflateSetDictionary(this,dictionary,dictLength):-2},read_buf:function(buf,start,size){var len=this.avail_in;return len>size&&(len=size),0===len?0:(this.avail_in-=len,buf.set(this.next_in.subarray(this.next_in_index,this.next_in_index+len),start),this.next_in_index+=len,this.total_in+=len,len)},flush_pending:function(){var len=this.dstate.pending;len>this.avail_out&&(len=this.avail_out),0!==len&&(this.next_out.set(this.dstate.pending_buf.subarray(this.dstate.pending_out,this.dstate.pending_out+len),this.next_out_index),this.next_out_index+=len,this.dstate.pending_out+=len,this.total_out+=len,this.avail_out-=len,this.dstate.pending-=len,0===this.dstate.pending&&(this.dstate.pending_out=0))}};var env=global.zip||global;env.Deflater=env._jzlib_Deflater=function(options){var z=new ZStream,buf=new Uint8Array(512),level=options?options.level:-1;void 0===level&&(level=-1),z.deflateInit(level),z.next_out=buf,this.append=function(data,onprogress){var array,buffers=[],lastIndex=0,bufferIndex=0,bufferSize=0;if(data.length){z.next_in_index=0,z.next_in=data,z.avail_in=data.length;do{if(z.next_out_index=0,z.avail_out=512,0!=z.deflate(0))throw new Error("deflating: "+z.msg);z.next_out_index&&(512==z.next_out_index?buffers.push(new Uint8Array(buf)):buffers.push(new Uint8Array(buf.subarray(0,z.next_out_index)))),bufferSize+=z.next_out_index,onprogress&&z.next_in_index>0&&z.next_in_index!=lastIndex&&(onprogress(z.next_in_index),lastIndex=z.next_in_index)}while(z.avail_in>0||0===z.avail_out);return array=new Uint8Array(bufferSize),buffers.forEach((function(chunk){array.set(chunk,bufferIndex),bufferIndex+=chunk.length})),array}},this.flush=function(){var err,array,buffers=[],bufferIndex=0,bufferSize=0;do{if(z.next_out_index=0,z.avail_out=512,1!=(err=z.deflate(4))&&0!=err)throw new Error("deflating: "+z.msg);512-z.avail_out>0&&buffers.push(new Uint8Array(buf.subarray(0,z.next_out_index))),bufferSize+=z.next_out_index}while(z.avail_in>0||0===z.avail_out);return z.deflateEnd(),array=new Uint8Array(bufferSize),buffers.forEach((function(chunk){array.set(chunk,bufferIndex),bufferIndex+=chunk.length})),array}}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||"undefined"!=typeof global&&global||Function('return typeof this === "object" && this.content')()||Function("return this")()),
 /**
-   * A class to parse color values
-   * @author Stoyan Stefanov <sstoo@gmail.com>
-   * @link   http://www.phpied.com/rgb-color-parser-in-javascript/
-   * @license Use it if you like it
+   * @license
+   * (c) Dean McNamee <dean@gmail.com>, 2013.
+   *
+   * https://github.com/deanm/omggif
+   *
+   * Permission is hereby granted, free of charge, to any person obtaining a copy
+   * of this software and associated documentation files (the "Software"), to
+   * deal in the Software without restriction, including without limitation the
+   * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+   * sell copies of the Software, and to permit persons to whom the Software is
+   * furnished to do so, subject to the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be included in
+   * all copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+   * IN THE SOFTWARE.
+   *
+   * omggif is a JavaScript implementation of a GIF 89a encoder and decoder,
+   * including animation and compression.  It does not rely on any specific
+   * underlying system, so should run in the browser, Node, or Plask.
+   */
+function GifReader(buf){var p=0;if(71!==buf[p++]||73!==buf[p++]||70!==buf[p++]||56!==buf[p++]||56!=(buf[p++]+1&253)||97!==buf[p++])throw new Error("Invalid GIF 87a/89a header.");var width=buf[p++]|buf[p++]<<8,height=buf[p++]|buf[p++]<<8,pf0=buf[p++],global_palette_flag=pf0>>7,num_global_colors=1<<(7&pf0)+1;buf[p++];buf[p++];var global_palette_offset=null,global_palette_size=null;global_palette_flag&&(global_palette_offset=p,global_palette_size=num_global_colors,p+=3*num_global_colors);var no_eof=!0,frames=[],delay=0,transparent_index=null,disposal=0,loop_count=null;for(this.width=width,this.height=height;no_eof&&p<buf.length;)switch(buf[p++]){case 33:switch(buf[p++]){case 255:if(11!==buf[p]||78==buf[p+1]&&69==buf[p+2]&&84==buf[p+3]&&83==buf[p+4]&&67==buf[p+5]&&65==buf[p+6]&&80==buf[p+7]&&69==buf[p+8]&&50==buf[p+9]&&46==buf[p+10]&&48==buf[p+11]&&3==buf[p+12]&&1==buf[p+13]&&0==buf[p+16])p+=14,loop_count=buf[p++]|buf[p++]<<8,p++;else for(p+=12;;){if(!((block_size=buf[p++])>=0))throw Error("Invalid block size");if(0===block_size)break;p+=block_size}break;case 249:if(4!==buf[p++]||0!==buf[p+4])throw new Error("Invalid graphics extension block.");var pf1=buf[p++];delay=buf[p++]|buf[p++]<<8,transparent_index=buf[p++],0==(1&pf1)&&(transparent_index=null),disposal=pf1>>2&7,p++;break;case 254:for(;;){if(!((block_size=buf[p++])>=0))throw Error("Invalid block size");if(0===block_size)break;p+=block_size}break;default:throw new Error("Unknown graphic control label: 0x"+buf[p-1].toString(16))}break;case 44:var x=buf[p++]|buf[p++]<<8,y=buf[p++]|buf[p++]<<8,w=buf[p++]|buf[p++]<<8,h=buf[p++]|buf[p++]<<8,pf2=buf[p++],interlace_flag=pf2>>6&1,num_local_colors=1<<(7&pf2)+1,palette_offset=global_palette_offset,palette_size=global_palette_size,has_local_palette=!1;if(pf2>>7){has_local_palette=!0;palette_offset=p,palette_size=num_local_colors,p+=3*num_local_colors}var data_offset=p;for(p++;;){var block_size;if(!((block_size=buf[p++])>=0))throw Error("Invalid block size");if(0===block_size)break;p+=block_size}frames.push({x:x,y:y,width:w,height:h,has_local_palette:has_local_palette,palette_offset:palette_offset,palette_size:palette_size,data_offset:data_offset,data_length:p-data_offset,transparent_index:transparent_index,interlaced:!!interlace_flag,delay:delay,disposal:disposal});break;case 59:no_eof=!1;break;default:throw new Error("Unknown gif block: 0x"+buf[p-1].toString(16))}this.numFrames=function(){return frames.length},this.loopCount=function(){return loop_count},this.frameInfo=function(frame_num){if(frame_num<0||frame_num>=frames.length)throw new Error("Frame index out of range.");return frames[frame_num]},this.decodeAndBlitFrameBGRA=function(frame_num,pixels){var frame=this.frameInfo(frame_num),num_pixels=frame.width*frame.height,index_stream=new Uint8Array(num_pixels);GifReaderLZWOutputIndexStream(buf,frame.data_offset,index_stream,num_pixels);var palette_offset=frame.palette_offset,trans=frame.transparent_index;null===trans&&(trans=256);var framewidth=frame.width,framestride=width-framewidth,xleft=framewidth,opbeg=4*(frame.y*width+frame.x),opend=4*((frame.y+frame.height)*width+frame.x),op=opbeg,scanstride=4*framestride;!0===frame.interlaced&&(scanstride+=4*width*7);for(var interlaceskip=8,i=0,il=index_stream.length;i<il;++i){var index=index_stream[i];if(0===xleft&&(xleft=framewidth,(op+=scanstride)>=opend&&(scanstride=4*framestride+4*width*(interlaceskip-1),op=opbeg+(framewidth+framestride)*(interlaceskip<<1),interlaceskip>>=1)),index===trans)op+=4;else{var r=buf[palette_offset+3*index],g=buf[palette_offset+3*index+1],b=buf[palette_offset+3*index+2];pixels[op++]=b,pixels[op++]=g,pixels[op++]=r,pixels[op++]=255}--xleft}},this.decodeAndBlitFrameRGBA=function(frame_num,pixels){var frame=this.frameInfo(frame_num),num_pixels=frame.width*frame.height,index_stream=new Uint8Array(num_pixels);GifReaderLZWOutputIndexStream(buf,frame.data_offset,index_stream,num_pixels);var palette_offset=frame.palette_offset,trans=frame.transparent_index;null===trans&&(trans=256);var framewidth=frame.width,framestride=width-framewidth,xleft=framewidth,opbeg=4*(frame.y*width+frame.x),opend=4*((frame.y+frame.height)*width+frame.x),op=opbeg,scanstride=4*framestride;!0===frame.interlaced&&(scanstride+=4*width*7);for(var interlaceskip=8,i=0,il=index_stream.length;i<il;++i){var index=index_stream[i];if(0===xleft&&(xleft=framewidth,(op+=scanstride)>=opend&&(scanstride=4*framestride+4*width*(interlaceskip-1),op=opbeg+(framewidth+framestride)*(interlaceskip<<1),interlaceskip>>=1)),index===trans)op+=4;else{var r=buf[palette_offset+3*index],g=buf[palette_offset+3*index+1],b=buf[palette_offset+3*index+2];pixels[op++]=r,pixels[op++]=g,pixels[op++]=b,pixels[op++]=255}--xleft}}}function GifReaderLZWOutputIndexStream(code_stream,p,output,output_length){for(var min_code_size=code_stream[p++],clear_code=1<<min_code_size,eoi_code=clear_code+1,next_code=eoi_code+1,cur_code_size=min_code_size+1,code_mask=(1<<cur_code_size)-1,cur_shift=0,cur=0,op=0,subblock_size=code_stream[p++],code_table=new Int32Array(4096),prev_code=null;;){for(;cur_shift<16&&0!==subblock_size;)cur|=code_stream[p++]<<cur_shift,cur_shift+=8,1===subblock_size?subblock_size=code_stream[p++]:--subblock_size;if(cur_shift<cur_code_size)break;var code=cur&code_mask;if(cur>>=cur_code_size,cur_shift-=cur_code_size,code!==clear_code){if(code===eoi_code)break;for(var chase_code=code<next_code?code:prev_code,chase_length=0,chase=chase_code;chase>clear_code;)chase=code_table[chase]>>8,++chase_length;var k=chase;if(op+chase_length+(chase_code!==code?1:0)>output_length)return void console.log("Warning, gif stream longer than expected.");output[op++]=k;var b=op+=chase_length;for(chase_code!==code&&(output[op++]=k),chase=chase_code;chase_length--;)chase=code_table[chase],output[--b]=255&chase,chase>>=8;null!==prev_code&&next_code<4096&&(code_table[next_code++]=prev_code<<8|k,next_code>=code_mask+1&&cur_code_size<12&&(++cur_code_size,code_mask=code_mask<<1|1)),prev_code=code}else next_code=eoi_code+1,code_mask=(1<<(cur_code_size=min_code_size+1))-1,prev_code=null}return op!==output_length&&console.log("Warning, gif stream shorter than expected."),output}
+/**
+   * @license
+    Copyright (c) 2008, Adobe Systems Incorporated
+    All rights reserved.
+     Redistribution and use in source and binary forms, with or without 
+    modification, are permitted provided that the following conditions are
+    met:
+     * Redistributions of source code must retain the above copyright notice, 
+      this list of conditions and the following disclaimer.
+    
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the 
+      documentation and/or other materials provided with the distribution.
+    
+    * Neither the name of Adobe Systems Incorporated nor the names of its 
+      contributors may be used to endorse or promote products derived from 
+      this software without specific prior written permission.
+     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
+    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  */function JPEGEncoder(quality){var YDC_HT,UVDC_HT,YAC_HT,UVAC_HT,currentQuality,ffloor=Math.floor,YTable=new Array(64),UVTable=new Array(64),fdtbl_Y=new Array(64),fdtbl_UV=new Array(64),bitcode=new Array(65535),category=new Array(65535),outputfDCTQuant=new Array(64),DU=new Array(64),byteout=[],bytenew=0,bytepos=7,YDU=new Array(64),UDU=new Array(64),VDU=new Array(64),clt=new Array(256),RGB_YUV_TABLE=new Array(2048),ZigZag=[0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18,24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63],std_dc_luminance_nrcodes=[0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0],std_dc_luminance_values=[0,1,2,3,4,5,6,7,8,9,10,11],std_ac_luminance_nrcodes=[0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,125],std_ac_luminance_values=[1,2,3,0,4,17,5,18,33,49,65,6,19,81,97,7,34,113,20,50,129,145,161,8,35,66,177,193,21,82,209,240,36,51,98,114,130,9,10,22,23,24,25,26,37,38,39,40,41,42,52,53,54,55,56,57,58,67,68,69,70,71,72,73,74,83,84,85,86,87,88,89,90,99,100,101,102,103,104,105,106,115,116,117,118,119,120,121,122,131,132,133,134,135,136,137,138,146,147,148,149,150,151,152,153,154,162,163,164,165,166,167,168,169,170,178,179,180,181,182,183,184,185,186,194,195,196,197,198,199,200,201,202,210,211,212,213,214,215,216,217,218,225,226,227,228,229,230,231,232,233,234,241,242,243,244,245,246,247,248,249,250],std_dc_chrominance_nrcodes=[0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0],std_dc_chrominance_values=[0,1,2,3,4,5,6,7,8,9,10,11],std_ac_chrominance_nrcodes=[0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,119],std_ac_chrominance_values=[0,1,2,3,17,4,5,33,49,6,18,65,81,7,97,113,19,34,50,129,8,20,66,145,161,177,193,9,35,51,82,240,21,98,114,209,10,22,36,52,225,37,241,23,24,25,26,38,39,40,41,42,53,54,55,56,57,58,67,68,69,70,71,72,73,74,83,84,85,86,87,88,89,90,99,100,101,102,103,104,105,106,115,116,117,118,119,120,121,122,130,131,132,133,134,135,136,137,138,146,147,148,149,150,151,152,153,154,162,163,164,165,166,167,168,169,170,178,179,180,181,182,183,184,185,186,194,195,196,197,198,199,200,201,202,210,211,212,213,214,215,216,217,218,226,227,228,229,230,231,232,233,234,242,243,244,245,246,247,248,249,250];function computeHuffmanTbl(nrcodes,std_table){for(var codevalue=0,pos_in_table=0,HT=new Array,k=1;k<=16;k++){for(var j=1;j<=nrcodes[k];j++)HT[std_table[pos_in_table]]=[],HT[std_table[pos_in_table]][0]=codevalue,HT[std_table[pos_in_table]][1]=k,pos_in_table++,codevalue++;codevalue*=2}return HT}function writeBits(bs){for(var value=bs[0],posval=bs[1]-1;posval>=0;)value&1<<posval&&(bytenew|=1<<bytepos),posval--,--bytepos<0&&(255==bytenew?(writeByte(255),writeByte(0)):writeByte(bytenew),bytepos=7,bytenew=0)}function writeByte(value){byteout.push(value)}function writeWord(value){writeByte(value>>8&255),writeByte(255&value)}function processDU(CDU,fdtbl,DC,HTDC,HTAC){for(var pos,EOB=HTAC[0],M16zeroes=HTAC[240],DU_DCT=function(data,fdtbl){var d0,d1,d2,d3,d4,d5,d6,d7,i,fDCTQuant,dataOff=0;for(i=0;i<8;++i){d0=data[dataOff],d1=data[dataOff+1],d2=data[dataOff+2],d3=data[dataOff+3],d4=data[dataOff+4],d5=data[dataOff+5],d6=data[dataOff+6];var tmp0=d0+(d7=data[dataOff+7]),tmp7=d0-d7,tmp1=d1+d6,tmp6=d1-d6,tmp2=d2+d5,tmp5=d2-d5,tmp3=d3+d4,tmp4=d3-d4,tmp10=tmp0+tmp3,tmp13=tmp0-tmp3,tmp11=tmp1+tmp2,tmp12=tmp1-tmp2;data[dataOff]=tmp10+tmp11,data[dataOff+4]=tmp10-tmp11;var z1=.707106781*(tmp12+tmp13);data[dataOff+2]=tmp13+z1,data[dataOff+6]=tmp13-z1;var z5=.382683433*((tmp10=tmp4+tmp5)-(tmp12=tmp6+tmp7)),z2=.5411961*tmp10+z5,z4=1.306562965*tmp12+z5,z3=.707106781*(tmp11=tmp5+tmp6),z11=tmp7+z3,z13=tmp7-z3;data[dataOff+5]=z13+z2,data[dataOff+3]=z13-z2,data[dataOff+1]=z11+z4,data[dataOff+7]=z11-z4,dataOff+=8}for(dataOff=0,i=0;i<8;++i){d0=data[dataOff],d1=data[dataOff+8],d2=data[dataOff+16],d3=data[dataOff+24],d4=data[dataOff+32],d5=data[dataOff+40],d6=data[dataOff+48];var tmp0p2=d0+(d7=data[dataOff+56]),tmp7p2=d0-d7,tmp1p2=d1+d6,tmp6p2=d1-d6,tmp2p2=d2+d5,tmp5p2=d2-d5,tmp3p2=d3+d4,tmp4p2=d3-d4,tmp10p2=tmp0p2+tmp3p2,tmp13p2=tmp0p2-tmp3p2,tmp11p2=tmp1p2+tmp2p2,tmp12p2=tmp1p2-tmp2p2;data[dataOff]=tmp10p2+tmp11p2,data[dataOff+32]=tmp10p2-tmp11p2;var z1p2=.707106781*(tmp12p2+tmp13p2);data[dataOff+16]=tmp13p2+z1p2,data[dataOff+48]=tmp13p2-z1p2;var z5p2=.382683433*((tmp10p2=tmp4p2+tmp5p2)-(tmp12p2=tmp6p2+tmp7p2)),z2p2=.5411961*tmp10p2+z5p2,z4p2=1.306562965*tmp12p2+z5p2,z3p2=.707106781*(tmp11p2=tmp5p2+tmp6p2),z11p2=tmp7p2+z3p2,z13p2=tmp7p2-z3p2;data[dataOff+40]=z13p2+z2p2,data[dataOff+24]=z13p2-z2p2,data[dataOff+8]=z11p2+z4p2,data[dataOff+56]=z11p2-z4p2,dataOff++}for(i=0;i<64;++i)fDCTQuant=data[i]*fdtbl[i],outputfDCTQuant[i]=fDCTQuant>0?fDCTQuant+.5|0:fDCTQuant-.5|0;return outputfDCTQuant}(CDU,fdtbl),j=0;j<64;++j)DU[ZigZag[j]]=DU_DCT[j];var Diff=DU[0]-DC;DC=DU[0],0==Diff?writeBits(HTDC[0]):(writeBits(HTDC[category[pos=32767+Diff]]),writeBits(bitcode[pos]));for(var end0pos=63;end0pos>0&&0==DU[end0pos];)end0pos--;if(0==end0pos)return writeBits(EOB),DC;for(var lng,i=1;i<=end0pos;){for(var startpos=i;0==DU[i]&&i<=end0pos;)++i;var nrzeroes=i-startpos;if(nrzeroes>=16){lng=nrzeroes>>4;for(var nrmarker=1;nrmarker<=lng;++nrmarker)writeBits(M16zeroes);nrzeroes&=15}pos=32767+DU[i],writeBits(HTAC[(nrzeroes<<4)+category[pos]]),writeBits(bitcode[pos]),i++}return 63!=end0pos&&writeBits(EOB),DC}function setQuality(quality){(quality=Math.min(Math.max(quality,1),100),currentQuality!=quality)&&(!function(sf){for(var YQT=[16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22,37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99],i=0;i<64;i++){var t=ffloor((YQT[i]*sf+50)/100);t=Math.min(Math.max(t,1),255),YTable[ZigZag[i]]=t}for(var UVQT=[17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99],j=0;j<64;j++){var u=ffloor((UVQT[j]*sf+50)/100);u=Math.min(Math.max(u,1),255),UVTable[ZigZag[j]]=u}for(var aasf=[1,1.387039845,1.306562965,1.175875602,1,.785694958,.5411961,.275899379],k=0,row=0;row<8;row++)for(var col=0;col<8;col++)fdtbl_Y[k]=1/(YTable[ZigZag[k]]*aasf[row]*aasf[col]*8),fdtbl_UV[k]=1/(UVTable[ZigZag[k]]*aasf[row]*aasf[col]*8),k++}(quality<50?Math.floor(5e3/quality):Math.floor(200-2*quality)),currentQuality=quality)}this.encode=function(image,quality){quality&&setQuality(quality),byteout=new Array,bytenew=0,bytepos=7,writeWord(65496),writeWord(65504),writeWord(16),writeByte(74),writeByte(70),writeByte(73),writeByte(70),writeByte(0),writeByte(1),writeByte(1),writeByte(0),writeWord(1),writeWord(1),writeByte(0),writeByte(0),function(){writeWord(65499),writeWord(132),writeByte(0);for(var i=0;i<64;i++)writeByte(YTable[i]);writeByte(1);for(var j=0;j<64;j++)writeByte(UVTable[j])}(),function(width,height){writeWord(65472),writeWord(17),writeByte(8),writeWord(height),writeWord(width),writeByte(3),writeByte(1),writeByte(17),writeByte(0),writeByte(2),writeByte(17),writeByte(1),writeByte(3),writeByte(17),writeByte(1)}(image.width,image.height),function(){writeWord(65476),writeWord(418),writeByte(0);for(var i=0;i<16;i++)writeByte(std_dc_luminance_nrcodes[i+1]);for(var j=0;j<=11;j++)writeByte(std_dc_luminance_values[j]);writeByte(16);for(var k=0;k<16;k++)writeByte(std_ac_luminance_nrcodes[k+1]);for(var l=0;l<=161;l++)writeByte(std_ac_luminance_values[l]);writeByte(1);for(var m=0;m<16;m++)writeByte(std_dc_chrominance_nrcodes[m+1]);for(var n=0;n<=11;n++)writeByte(std_dc_chrominance_values[n]);writeByte(17);for(var o=0;o<16;o++)writeByte(std_ac_chrominance_nrcodes[o+1]);for(var p=0;p<=161;p++)writeByte(std_ac_chrominance_values[p])}(),writeWord(65498),writeWord(12),writeByte(3),writeByte(1),writeByte(0),writeByte(2),writeByte(17),writeByte(3),writeByte(17),writeByte(0),writeByte(63),writeByte(0);var DCY=0,DCU=0,DCV=0;bytenew=0,bytepos=7,this.encode.displayName="_encode_";for(var x,r,g,b,start,p,col,row,pos,imageData=image.data,width=image.width,height=image.height,quadWidth=4*width,y=0;y<height;){for(x=0;x<quadWidth;){for(start=quadWidth*y+x,col=-1,row=0,pos=0;pos<64;pos++)p=start+(row=pos>>3)*quadWidth+(col=4*(7&pos)),y+row>=height&&(p-=quadWidth*(y+1+row-height)),x+col>=quadWidth&&(p-=x+col-quadWidth+4),r=imageData[p++],g=imageData[p++],b=imageData[p++],YDU[pos]=(RGB_YUV_TABLE[r]+RGB_YUV_TABLE[g+256>>0]+RGB_YUV_TABLE[b+512>>0]>>16)-128,UDU[pos]=(RGB_YUV_TABLE[r+768>>0]+RGB_YUV_TABLE[g+1024>>0]+RGB_YUV_TABLE[b+1280>>0]>>16)-128,VDU[pos]=(RGB_YUV_TABLE[r+1280>>0]+RGB_YUV_TABLE[g+1536>>0]+RGB_YUV_TABLE[b+1792>>0]>>16)-128;DCY=processDU(YDU,fdtbl_Y,DCY,YDC_HT,YAC_HT),DCU=processDU(UDU,fdtbl_UV,DCU,UVDC_HT,UVAC_HT),DCV=processDU(VDU,fdtbl_UV,DCV,UVDC_HT,UVAC_HT),x+=32}y+=8}if(bytepos>=0){var fillbits=[];fillbits[1]=bytepos+1,fillbits[0]=(1<<bytepos+1)-1,writeBits(fillbits)}return writeWord(65497),new Uint8Array(byteout)},quality=quality||50,function(){for(var sfcc=String.fromCharCode,i=0;i<256;i++)clt[i]=sfcc(i)}(),YDC_HT=computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values),UVDC_HT=computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values),YAC_HT=computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values),UVAC_HT=computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values),function(){for(var nrlower=1,nrupper=2,cat=1;cat<=15;cat++){for(var nr=nrlower;nr<nrupper;nr++)category[32767+nr]=cat,bitcode[32767+nr]=[],bitcode[32767+nr][1]=cat,bitcode[32767+nr][0]=nr;for(var nrneg=-(nrupper-1);nrneg<=-nrlower;nrneg++)category[32767+nrneg]=cat,bitcode[32767+nrneg]=[],bitcode[32767+nrneg][1]=cat,bitcode[32767+nrneg][0]=nrupper-1+nrneg;nrlower<<=1,nrupper<<=1}}(),function(){for(var i=0;i<256;i++)RGB_YUV_TABLE[i]=19595*i,RGB_YUV_TABLE[i+256>>0]=38470*i,RGB_YUV_TABLE[i+512>>0]=7471*i+32768,RGB_YUV_TABLE[i+768>>0]=-11059*i,RGB_YUV_TABLE[i+1024>>0]=-21709*i,RGB_YUV_TABLE[i+1280>>0]=32768*i+8421375,RGB_YUV_TABLE[i+1536>>0]=-27439*i,RGB_YUV_TABLE[i+1792>>0]=-5329*i}(),setQuality(quality)}
+/**
+   * @license
+   * Copyright (c) 2017 Aras Abbasi
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */function BmpDecoder(buffer,is_with_alpha){if(this.pos=0,this.buffer=buffer,this.datav=new DataView(buffer.buffer),this.is_with_alpha=!!is_with_alpha,this.bottom_up=!0,this.flag=String.fromCharCode(this.buffer[0])+String.fromCharCode(this.buffer[1]),this.pos+=2,-1===["BM","BA","CI","CP","IC","PT"].indexOf(this.flag))throw new Error("Invalid BMP File");this.parseHeader(),this.parseBGR()}function WebPDecoder(imageData){function x(F){if(!F)throw Error("assert :P")}function fa(F,L,J){for(var H=0;4>H;H++)if(F[L+H]!=J.charCodeAt(H))return!0;return!1}function I(F,L,J,H,Z){for(var O=0;O<Z;O++)F[L+O]=J[H+O]}function M(F,L,J,H){for(var Z=0;Z<H;Z++)F[L+Z]=J}function V(F){return new Int32Array(F)}function wa(F,L){for(var J=[],H=0;H<F;H++)J.push(new L);return J}function Ed(F,L){var H=[];return function J(H,O,F){for(var Z=F[O],ma=0;ma<Z&&(H.push(F.length>O+1?[]:new L),!(F.length<O+1));ma++)J(H[ma],O+1,F)}(H,0,F),H}var _WebPDecoder=function(){var self=this;function L(a,b){for(var c=1<<b-1>>>0;a&c;)c>>>=1;return c?(a&c-1)+c:a}function J(a,b,c,d,e){x(!(d%c));do{a[b+(d-=c)]=e}while(0<d)}function Z(a,b,c,d,e){if(x(2328>=e),512>=e)var f=V(512);else if(null==(f=V(e)))return 0;return function(a,b,c,d,e,f){var k,l,g=b,h=1<<c,m=V(16),n=V(16);for(x(0!=e),x(null!=d),x(null!=a),x(0<c),l=0;l<e;++l){if(15<d[l])return 0;++m[d[l]]}if(m[0]==e)return 0;for(n[1]=0,k=1;15>k;++k){if(m[k]>1<<k)return 0;n[k+1]=n[k]+m[k]}for(l=0;l<e;++l)k=d[l],0<d[l]&&(f[n[k]++]=l);if(1==n[15])return(d=new O).g=0,d.value=f[0],J(a,g,1,h,d),h;var u,r=-1,q=h-1,t=0,v=1,p=1,w=1<<c;for(l=0,k=1,e=2;k<=c;++k,e<<=1){if(v+=p<<=1,0>(p-=m[k]))return 0;for(;0<m[k];--m[k])(d=new O).g=k,d.value=f[l++],J(a,g+t,e,w,d),t=L(t,k)}for(k=c+1,e=2;15>=k;++k,e<<=1){if(v+=p<<=1,0>(p-=m[k]))return 0;for(;0<m[k];--m[k]){if(d=new O,(t&q)!=r){for(g+=w,u=1<<(r=k)-c;15>r&&!(0>=(u-=m[r]));)++r,u<<=1;h+=w=1<<(u=r-c),a[b+(r=t&q)].g=u+c,a[b+r].value=g-b-r}d.g=k-c,d.value=f[l++],J(a,g+(t>>c),e,w,d),t=L(t,k)}}return v!=2*n[15]-1?0:h}(a,b,c,d,e,f)}function O(){this.value=this.g=0}function Fd(){this.value=this.g=0}function Ub(){this.G=wa(5,O),this.H=V(5),this.jc=this.Qb=this.qb=this.nd=0,this.pd=wa(xb,Fd)}function ma(a,b,c,d){x(null!=a),x(null!=b),x(2147483648>d),a.Ca=254,a.I=0,a.b=-8,a.Ka=0,a.oa=b,a.pa=c,a.Jd=b,a.Yc=c+d,a.Zc=4<=d?c+d-4+1:c,Qa(a)}function na(a,b){for(var c=0;0<b--;)c|=K(a,128)<<b;return c}function ca(a,b){var c=na(a,b);return G(a)?-c:c}function cb(a,b,c,d){var e,f=0;for(x(null!=a),x(null!=b),x(4294967288>d),a.Sb=d,a.Ra=0,a.u=0,a.h=0,4<d&&(d=4),e=0;e<d;++e)f+=b[c+e]<<8*e;a.Ra=f,a.bb=d,a.oa=b,a.pa=c}function Vb(a){for(;8<=a.u&&a.bb<a.Sb;)a.Ra>>>=8,a.Ra+=a.oa[a.pa+a.bb]<<ob-8>>>0,++a.bb,a.u-=8;db(a)&&(a.h=1,a.u=0)}function D(a,b){if(x(0<=b),!a.h&&b<=Gd){var c=pb(a)&Hd[b];return a.u+=b,Vb(a),c}return a.h=1,a.u=0}function Wb(){this.b=this.Ca=this.I=0,this.oa=[],this.pa=0,this.Jd=[],this.Yc=0,this.Zc=[],this.Ka=0}function Ra(){this.Ra=0,this.oa=[],this.h=this.u=this.bb=this.Sb=this.pa=0}function pb(a){return a.Ra>>>(a.u&ob-1)>>>0}function db(a){return x(a.bb<=a.Sb),a.h||a.bb==a.Sb&&a.u>ob}function qb(a,b){a.u=b,a.h=db(a)}function Sa(a){a.u>=Xb&&(x(a.u>=Xb),Vb(a))}function Qa(a){x(null!=a&&null!=a.oa),a.pa<a.Zc?(a.I=(a.oa[a.pa++]|a.I<<8)>>>0,a.b+=8):(x(null!=a&&null!=a.oa),a.pa<a.Yc?(a.b+=8,a.I=a.oa[a.pa++]|a.I<<8):a.Ka?a.b=0:(a.I<<=8,a.b+=8,a.Ka=1))}function G(a){return na(a,1)}function K(a,b){var c=a.Ca;0>a.b&&Qa(a);var d=a.b,e=c*b>>>8,f=(a.I>>>d>e)+0;for(f?(c-=e,a.I-=e+1<<d>>>0):c=e+1,d=c,e=0;256<=d;)e+=8,d>>=8;return d=7^e+Id[d],a.b-=d,a.Ca=(c<<d)-1,f}function ra(a,b,c){a[b+0]=c>>24&255,a[b+1]=c>>16&255,a[b+2]=c>>8&255,a[b+3]=c>>0&255}function Ta(a,b){return a[b+0]<<0|a[b+1]<<8}function Yb(a,b){return Ta(a,b)|a[b+2]<<16}function Ha(a,b){return Ta(a,b)|Ta(a,b+2)<<16}function Zb(a,b){var c=1<<b;return x(null!=a),x(0<b),a.X=V(c),null==a.X?0:(a.Mb=32-b,a.Xa=b,1)}function $b(a,b){x(null!=a),x(null!=b),x(a.Xa==b.Xa),I(b.X,0,a.X,0,1<<b.Xa)}function ac(){this.X=[],this.Xa=this.Mb=0}function bc(a,b,c,d){x(null!=c),x(null!=d);var e=c[0],f=d[0];return 0==e&&(e=(a*f+b/2)/b),0==f&&(f=(b*e+a/2)/a),0>=e||0>=f?0:(c[0]=e,d[0]=f,1)}function xa(a,b){return a+(1<<b)-1>>>b}function yb(a,b){return((4278255360&a)+(4278255360&b)>>>0&4278255360)+((16711935&a)+(16711935&b)>>>0&16711935)>>>0}function X(a,b){self[b]=function(b,d,e,f,g,h,k){var c;for(c=0;c<g;++c){var m=self[a](h[k+c-1],e,f+c);h[k+c]=yb(b[d+c],m)}}}function Jd(){this.ud=this.hd=this.jd=0}function aa(a,b){return((4278124286&(a^b))>>>1)+(a&b)>>>0}function sa(a){return 0<=a&&256>a?a:0>a?0:255<a?255:void 0}function eb(a,b){return sa(a+(a-b+.5>>1))}function Ia(a,b,c){return Math.abs(b-c)-Math.abs(a-c)}function cc(a,b,c,d,e,f,g){for(d=f[g-1],c=0;c<e;++c)f[g+c]=d=yb(a[b+c],d)}function Kd(a,b,c,d,e){var f;for(f=0;f<c;++f){var g=a[b+f],h=g>>8&255,k=16711935&(k=(k=16711935&g)+((h<<16)+h));d[e+f]=(4278255360&g)+k>>>0}}function dc(a,b){b.jd=a>>0&255,b.hd=a>>8&255,b.ud=a>>16&255}function Ld(a,b,c,d,e,f){var g;for(g=0;g<d;++g){var h=b[c+g],k=h>>>8,m=h,l=255&(l=(l=h>>>16)+((a.jd<<24>>24)*(k<<24>>24)>>>5));m=255&(m=(m=m+((a.hd<<24>>24)*(k<<24>>24)>>>5))+((a.ud<<24>>24)*(l<<24>>24)>>>5));e[f+g]=(4278255360&h)+(l<<16)+m}}function ec(a,b,c,d,e){self[b]=function(a,b,c,k,l,m,n,r,q){for(k=n;k<r;++k)for(n=0;n<q;++n)l[m++]=e(c[d(a[b++])])},self[a]=function(a,b,h,k,l,m,n){var f=8>>a.b,g=a.Ea,t=a.K[0],v=a.w;if(8>f)for(a=(1<<a.b)-1,v=(1<<f)-1;b<h;++b){var u,p=0;for(u=0;u<g;++u)u&a||(p=d(k[l++])),m[n++]=e(t[p&v]),p>>=f}else self["VP8LMapColor"+c](k,l,t,v,m,n,b,h,g)}}function Md(a,b,c,d,e){for(c=b+c;b<c;){var f=a[b++];d[e++]=f>>16&255,d[e++]=f>>8&255,d[e++]=f>>0&255}}function Nd(a,b,c,d,e){for(c=b+c;b<c;){var f=a[b++];d[e++]=f>>16&255,d[e++]=f>>8&255,d[e++]=f>>0&255,d[e++]=f>>24&255}}function Od(a,b,c,d,e){for(c=b+c;b<c;){var g=(f=a[b++])>>16&240|f>>12&15,f=f>>0&240|f>>28&15;d[e++]=g,d[e++]=f}}function Pd(a,b,c,d,e){for(c=b+c;b<c;){var g=(f=a[b++])>>16&248|f>>13&7,f=f>>5&224|f>>3&31;d[e++]=g,d[e++]=f}}function Qd(a,b,c,d,e){for(c=b+c;b<c;){var f=a[b++];d[e++]=f>>0&255,d[e++]=f>>8&255,d[e++]=f>>16&255}}function fb(a,b,c,d,e,f){if(0==f)for(c=b+c;b<c;)ra(d,((f=a[b++])[0]>>24|f[1]>>8&65280|f[2]<<8&16711680|f[3]<<24)>>>0),e+=32;else I(d,e,a,b,c)}function gb(a,b){self[b][0]=self[a+"0"],self[b][1]=self[a+"1"],self[b][2]=self[a+"2"],self[b][3]=self[a+"3"],self[b][4]=self[a+"4"],self[b][5]=self[a+"5"],self[b][6]=self[a+"6"],self[b][7]=self[a+"7"],self[b][8]=self[a+"8"],self[b][9]=self[a+"9"],self[b][10]=self[a+"10"],self[b][11]=self[a+"11"],self[b][12]=self[a+"12"],self[b][13]=self[a+"13"],self[b][14]=self[a+"0"],self[b][15]=self[a+"0"]}function hb(a){return a==zb||a==Ab||a==Ja||a==Bb}function Rd(){this.eb=[],this.size=this.A=this.fb=0}function Sd(){this.y=[],this.f=[],this.ea=[],this.F=[],this.Tc=this.Ed=this.Cd=this.Fd=this.lb=this.Db=this.Ab=this.fa=this.J=this.W=this.N=this.O=0}function Cb(){this.Rd=this.height=this.width=this.S=0,this.f={},this.f.RGBA=new Rd,this.f.kb=new Sd,this.sd=null}function Td(){this.width=[0],this.height=[0],this.Pd=[0],this.Qd=[0],this.format=[0]}function Ud(){this.Id=this.fd=this.Md=this.hb=this.ib=this.da=this.bd=this.cd=this.j=this.v=this.Da=this.Sd=this.ob=0}function Vd(a){return alert("todo:WebPSamplerProcessPlane"),a.T}function Wd(a,b){var c=a.T,d=b.ba.f.RGBA,e=d.eb,f=d.fb+a.ka*d.A,g=P[b.ba.S],h=a.y,k=a.O,l=a.f,m=a.N,n=a.ea,r=a.W,q=b.cc,t=b.dc,v=b.Mc,p=b.Nc,u=a.ka,w=a.ka+a.T,y=a.U,A=y+1>>1;for(0==u?g(h,k,null,null,l,m,n,r,l,m,n,r,e,f,null,null,y):(g(b.ec,b.fc,h,k,q,t,v,p,l,m,n,r,e,f-d.A,e,f,y),++c);u+2<w;u+=2)q=l,t=m,v=n,p=r,m+=a.Rc,r+=a.Rc,f+=2*d.A,g(h,(k+=2*a.fa)-a.fa,h,k,q,t,v,p,l,m,n,r,e,f-d.A,e,f,y);return k+=a.fa,a.j+w<a.o?(I(b.ec,b.fc,h,k,y),I(b.cc,b.dc,l,m,A),I(b.Mc,b.Nc,n,r,A),c--):1&w||g(h,k,null,null,l,m,n,r,l,m,n,r,e,f+d.A,null,null,y),c}function Xd(a,b,c){var d=a.F,e=[a.J];if(null!=d){var f=a.U,g=b.ba.S,h=g==ya||g==Ja;b=b.ba.f.RGBA;var k=[0],l=a.ka;k[0]=a.T,a.Kb&&(0==l?--k[0]:(--l,e[0]-=a.width),a.j+a.ka+a.T==a.o&&(k[0]=a.o-a.j-l));var m=b.eb;l=b.fb+l*b.A;a=fc(d,e[0],a.width,f,k,m,l+(h?0:3),b.A),x(c==k),a&&hb(g)&&za(m,l,h,f,k,b.A)}return 0}function gc(a){var b=a.ma,c=b.ba.S,d=11>c,e=c==Ua||c==Va||c==ya||c==Db||12==c||hb(c);if(b.memory=null,b.Ib=null,b.Jb=null,b.Nd=null,!hc(b.Oa,a,e?11:12))return 0;if(e&&hb(c)&&ic(),a.da)alert("todo:use_scaling");else{if(d){if(b.Ib=Vd,a.Kb){if(c=a.U+1>>1,b.memory=V(a.U+2*c),null==b.memory)return 0;b.ec=b.memory,b.fc=0,b.cc=b.ec,b.dc=b.fc+a.U,b.Mc=b.cc,b.Nc=b.dc+c,b.Ib=Wd,ic()}}else alert("todo:EmitYUV");e&&(b.Jb=Xd,d&&Aa())}if(d&&!jc){for(a=0;256>a;++a)Yd[a]=89858*(a-128)+Ba>>Wa,Zd[a]=-22014*(a-128)+Ba,$d[a]=-45773*(a-128),ae[a]=113618*(a-128)+Ba>>Wa;for(a=ta;a<Eb;++a)b=76283*(a-16)+Ba>>Wa,be[a-ta]=ga(b,255),ce[a-ta]=ga(b+8>>4,15);jc=1}return 1}function kc(a){var b=a.ma,c=a.U,d=a.T;return x(!(1&a.ka)),0>=c||0>=d?0:(c=b.Ib(a,b),null!=b.Jb&&b.Jb(a,b,c),b.Dc+=c,1)}function lc(a){a.ma.memory=null}function mc(a,b,c,d){return 47!=D(a,8)?0:(b[0]=D(a,14)+1,c[0]=D(a,14)+1,d[0]=D(a,1),0!=D(a,3)?0:!a.h)}function ib(a,b){if(4>a)return a+1;var c=a-2>>1;return(2+(1&a)<<c)+D(b,c)+1}function nc(a,b){return 120<b?b-120:1<=(c=((c=de[b-1])>>4)*a+(8-(15&c)))?c:1;var c}function ua(a,b,c){var d=pb(c),e=a[b+=255&d].g-8;return 0<e&&(qb(c,c.u+8),d=pb(c),b+=a[b].value,b+=d&(1<<e)-1),qb(c,c.u+a[b].g),a[b].value}function ub(a,b,c){return c.g+=a.g,c.value+=a.value<<b>>>0,x(8>=c.g),a.g}function ha(a,b,c){var d=a.xc;return x((b=0==d?0:a.vc[a.md*(c>>d)+(b>>d)])<a.Wb),a.Ya[b]}function oc(a,b,c,d){var e=a.ab,f=a.c*b,g=a.C;b=g+b;var h=c,k=d;for(d=a.Ta,c=a.Ua;0<e--;){var l=a.gc[e],m=g,n=b,r=h,q=k,t=(k=d,h=c,l.Ea);switch(x(m<n),x(n<=l.nc),l.hc){case 2:pc(r,q,(n-m)*t,k,h);break;case 0:var p=m,u=n,w=k,y=h,A=(v=l).Ea;0==p&&(ee(r,q,null,null,1,w,y),cc(r,q+1,0,0,A-1,w,y+1),q+=A,y+=A,++p);for(var E=1<<v.b,B=E-1,C=xa(A,v.b),N=v.K,v=v.w+(p>>v.b)*C;p<u;){var z=N,Q=v,S=1;for(fe(r,q,w,y-A,1,w,y);S<A;){var D=(S&~B)+E;D>A&&(D=A),(0,qc[z[Q++]>>8&15])(r,q+ +S,w,y+S-A,D-S,w,y+S),S=D}q+=A,y+=A,++p&B||(v+=C)}n!=l.nc&&I(k,h-t,k,h+(n-m-1)*t,t);break;case 1:for(t=r,u=q,A=(r=l.Ea)-(y=r&~(w=(q=1<<l.b)-1)),p=xa(r,l.b),E=l.K,l=l.w+(m>>l.b)*p;m<n;){for(B=E,C=l,N=new Jd,v=u+y,z=u+r;u<v;)dc(B[C++],N),Fb(N,t,u,q,k,h),u+=q,h+=q;u<z&&(dc(B[C++],N),Fb(N,t,u,A,k,h),u+=A,h+=A),++m&w||(l+=p)}break;case 3:if(r==k&&q==h&&0<l.b){for(u=k,r=t=h+(n-m)*t-(y=(n-m)*xa(l.Ea,l.b)),q=k,w=h,p=[],y=(A=y)-1;0<=y;--y)p[y]=q[w+y];for(y=A-1;0<=y;--y)u[r+y]=p[y];rc(l,m,n,k,t,k,h)}else rc(l,m,n,r,q,k,h)}h=d,k=c}k!=c&&I(d,c,h,k,f)}function ge(a,b){var c=a.V,d=a.Ba+a.c*a.C,e=b-a.C;if(x(b<=a.l.o),x(16>=e),0<e){var f=a.l,g=a.Ta,h=a.Ua,k=f.width;if(oc(a,e,c,d),e=h=[h],x((c=a.C)<(d=b)),x(f.v<f.va),d>f.o&&(d=f.o),c<f.j){var l=f.j-c;c=f.j;e[0]+=l*k}if(c>=d?c=0:(e[0]+=4*f.v,f.ka=c-f.j,f.U=f.va-f.v,f.T=d-c,c=1),c){if(h=h[0],11>(c=a.ca).S){var m=c.f.RGBA,n=(d=c.S,e=f.U,f=f.T,l=m.eb,m.A),r=f;for(m=m.fb+a.Ma*m.A;0<r--;){var q=g,t=h,v=e,p=l,u=m;switch(d){case Ca:sc(q,t,v,p,u);break;case Ua:Gb(q,t,v,p,u);break;case zb:Gb(q,t,v,p,u),za(p,u,0,v,1,0);break;case tc:uc(q,t,v,p,u);break;case Va:fb(q,t,v,p,u,1);break;case Ab:fb(q,t,v,p,u,1),za(p,u,0,v,1,0);break;case ya:fb(q,t,v,p,u,0);break;case Ja:fb(q,t,v,p,u,0),za(p,u,1,v,1,0);break;case Db:Hb(q,t,v,p,u);break;case Bb:Hb(q,t,v,p,u),vc(p,u,v,1,0);break;case wc:xc(q,t,v,p,u);break;default:x(0)}h+=k,m+=n}a.Ma+=f}else alert("todo:EmitRescaledRowsYUVA");x(a.Ma<=c.height)}}a.C=b,x(a.C<=a.i)}function yc(a){var b;if(0<a.ua)return 0;for(b=0;b<a.Wb;++b){var c=a.Ya[b].G,d=a.Ya[b].H;if(0<c[1][d[1]+0].g||0<c[2][d[2]+0].g||0<c[3][d[3]+0].g)return 0}return 1}function zc(a,b,c,d,e,f){if(0!=a.Z){var g=a.qd,h=a.rd;for(x(null!=ia[a.Z]);b<c;++b)ia[a.Z](g,h,d,e,d,e,f),g=d,h=e,e+=f;a.qd=g,a.rd=h}}function Ib(a,b){var c=a.l.ma,d=0==c.Z||1==c.Z?a.l.j:a.C;d=a.C<d?d:a.C;if(x(b<=a.l.o),b>d){var e=a.l.width,f=c.ca,g=c.tb+e*d,h=a.V,k=a.Ba+a.c*d,l=a.gc;x(1==a.ab),x(3==l[0].hc),he(l[0],d,b,h,k,f,g),zc(c,d,b,f,g,e)}a.C=a.Ma=b}function Jb(a,b,c,d,e,f,g){var h=a.$/d,k=a.$%d,l=a.m,m=a.s,n=c+a.$,r=n;e=c+d*e;var q=c+d*f,t=280+m.ua,v=a.Pb?h:16777216,p=0<m.ua?m.Wa:null,u=m.wc,w=n<q?ha(m,k,h):null;x(a.C<f),x(q<=e);var y=!1;a:for(;;){for(;y||n<q;){var A=0;if(h>=v){var E=n-c;x((v=a).Pb),v.wd=v.m,v.xd=E,0<v.s.ua&&$b(v.s.Wa,v.s.vb),v=h+ie}if(k&u||(w=ha(m,k,h)),x(null!=w),w.Qb&&(b[n]=w.qb,y=!0),!y)if(Sa(l),w.jc){A=l,E=b;var B=n,C=w.pd[pb(A)&xb-1];x(w.jc),256>C.g?(qb(A,A.u+C.g),E[B]=C.value,A=0):(qb(A,A.u+C.g-256),x(256<=C.value),A=C.value),0==A&&(y=!0)}else A=ua(w.G[0],w.H[0],l);if(l.h)break;if(y||256>A){if(!y)if(w.nd)b[n]=(w.qb|A<<8)>>>0;else{if(Sa(l),y=ua(w.G[1],w.H[1],l),Sa(l),E=ua(w.G[2],w.H[2],l),B=ua(w.G[3],w.H[3],l),l.h)break;b[n]=(B<<24|y<<16|A<<8|E)>>>0}if(y=!1,++n,++k>=d&&(k=0,++h,null!=g&&h<=f&&!(h%16)&&g(a,h),null!=p))for(;r<n;)A=b[r++],p.X[(506832829*A&4294967295)>>>p.Mb]=A}else if(280>A){if(A=ib(A-256,l),E=ua(w.G[4],w.H[4],l),Sa(l),E=nc(d,E=ib(E,l)),l.h)break;if(n-c<E||e-n<A)break a;for(B=0;B<A;++B)b[n+B]=b[n+B-E];for(n+=A,k+=A;k>=d;)k-=d,++h,null!=g&&h<=f&&!(h%16)&&g(a,h);if(x(n<=e),k&u&&(w=ha(m,k,h)),null!=p)for(;r<n;)A=b[r++],p.X[(506832829*A&4294967295)>>>p.Mb]=A}else{if(!(A<t))break a;for(y=A-280,x(null!=p);r<n;)A=b[r++],p.X[(506832829*A&4294967295)>>>p.Mb]=A;A=n,x(!(y>>>(E=p).Xa)),b[A]=E.X[y],y=!0}y||x(l.h==db(l))}if(a.Pb&&l.h&&n<e)x(a.m.h),a.a=5,a.m=a.wd,a.$=a.xd,0<a.s.ua&&$b(a.s.vb,a.s.Wa);else{if(l.h)break a;null!=g&&g(a,h>f?f:h),a.a=0,a.$=n-c}return 1}return a.a=3,0}function Ac(a){x(null!=a),a.vc=null,a.yc=null,a.Ya=null;var b=a.Wa;null!=b&&(b.X=null),a.vb=null,x(null!=a)}function Bc(){var a=new je;return null==a?null:(a.a=0,a.xb=Cc,gb("Predictor","VP8LPredictors"),gb("Predictor","VP8LPredictors_C"),gb("PredictorAdd","VP8LPredictorsAdd"),gb("PredictorAdd","VP8LPredictorsAdd_C"),pc=Kd,Fb=Ld,sc=Md,Gb=Nd,Hb=Od,xc=Pd,uc=Qd,self.VP8LMapColor32b=ke,self.VP8LMapColor8b=le,a)}function rb(a,b,c,d,e){var f=1,g=[a],h=[b],k=d.m,l=d.s,m=null,n=0;a:for(;;){if(c)for(;f&&D(k,1);){var r=g,q=h,t=d,v=1,p=t.m,u=t.gc[t.ab],w=D(p,2);if(t.Oc&1<<w)f=0;else{switch(t.Oc|=1<<w,u.hc=w,u.Ea=r[0],u.nc=q[0],u.K=[null],++t.ab,x(4>=t.ab),w){case 0:case 1:u.b=D(p,3)+2,v=rb(xa(u.Ea,u.b),xa(u.nc,u.b),0,t,u.K),u.K=u.K[0];break;case 3:var E,y=D(p,8)+1,A=16<y?0:4<y?1:2<y?2:3;if(r[0]=xa(u.Ea,A),u.b=A,E=v=rb(y,1,0,t,u.K)){var B,C=y,N=u,z=1<<(8>>N.b),Q=V(z);if(null==Q)E=0;else{var S=N.K[0],K=N.w;for(Q[0]=N.K[0][0],B=1;B<1*C;++B)Q[B]=yb(S[K+B],Q[B-1]);for(;B<4*z;++B)Q[B]=0;N.K[0]=null,N.K[0]=Q,E=1}}v=E;break;case 2:break;default:x(0)}f=v}}if(g=g[0],h=h[0],f&&D(k,1)&&!(f=1<=(n=D(k,4))&&11>=n)){d.a=3;break a}var H;if(H=f)b:{var Da,ba,U,F=d,G=g,L=h,J=n,T=c,X=F.m,R=F.s,P=[null],W=1,aa=0,na=me[J];c:for(;;){if(T&&D(X,1)){var ca=D(X,3)+2,ga=xa(G,ca),ka=xa(L,ca),qa=ga*ka;if(!rb(ga,ka,0,F,P))break c;for(P=P[0],R.xc=ca,Da=0;Da<qa;++Da){var ia=P[Da]>>8&65535;P[Da]=ia,ia>=W&&(W=ia+1)}}if(X.h)break c;for(ba=0;5>ba;++ba){var Y=Dc[ba];!ba&&0<J&&(Y+=1<<J),aa<Y&&(aa=Y)}var ma=wa(W*na,O),ua=W,va=wa(ua,Ub);if(null==va)var la=null;else x(65536>=ua),la=va;var ha=V(aa);if(null==la||null==ha||null==ma){F.a=1;break c}var pa=ma;for(Da=U=0;Da<W;++Da){var ja=la[Da],da=ja.G,ea=ja.H,Fa=0,ra=1,Ha=0;for(ba=0;5>ba;++ba){Y=Dc[ba],da[ba]=pa,ea[ba]=U,!ba&&0<J&&(Y+=1<<J);d:{var sa,za=Y,ta=F,oa=ha,db=pa,eb=U,Ia=0,Ka=ta.m,fb=D(Ka,1);if(M(oa,0,0,za),fb){var gb=D(Ka,1)+1,hb=D(Ka,1),Ja=D(Ka,0==hb?1:8);oa[Ja]=1,2==gb&&(oa[Ja=D(Ka,8)]=1);var ya=1}else{var Ua=V(19),Va=D(Ka,4)+4;if(19<Va){ta.a=3;var Aa=0;break d}for(sa=0;sa<Va;++sa)Ua[ne[sa]]=D(Ka,3);var Ba=void 0,sb=void 0,Wa=ta,ib=Ua,Ca=za,Xa=oa,Oa=0,La=Wa.m,Ya=8,Za=wa(128,O);e:for(;Z(Za,0,7,ib,19);){if(D(La,1)){var kb=2+2*D(La,3);if((Ba=2+D(La,kb))>Ca)break e}else Ba=Ca;for(sb=0;sb<Ca&&Ba--;){Sa(La);var $a=Za[0+(127&pb(La))];qb(La,La.u+$a.g);var jb=$a.value;if(16>jb)Xa[sb++]=jb,0!=jb&&(Ya=jb);else{var lb=16==jb,ab=jb-16,mb=oe[ab],bb=D(La,pe[ab])+mb;if(sb+bb>Ca)break e;for(var nb=lb?Ya:0;0<bb--;)Xa[sb++]=nb}}Oa=1;break e}Oa||(Wa.a=3),ya=Oa}(ya=ya&&!Ka.h)&&(Ia=Z(db,eb,8,oa,za)),ya&&0!=Ia?Aa=Ia:(ta.a=3,Aa=0)}if(0==Aa)break c;if(ra&&1==qe[ba]&&(ra=0==pa[U].g),Fa+=pa[U].g,U+=Aa,3>=ba){var tb,Pa=ha[0];for(tb=1;tb<Y;++tb)ha[tb]>Pa&&(Pa=ha[tb]);Ha+=Pa}}if(ja.nd=ra,ja.Qb=0,ra&&(ja.qb=(da[3][ea[3]+0].value<<24|da[1][ea[1]+0].value<<16|da[2][ea[2]+0].value)>>>0,0==Fa&&256>da[0][ea[0]+0].value&&(ja.Qb=1,ja.qb+=da[0][ea[0]+0].value<<8)),ja.jc=!ja.Qb&&6>Ha,ja.jc){var Ga,Ea=ja;for(Ga=0;Ga<xb;++Ga){var Ma=Ga,Na=Ea.pd[Ma],vb=Ea.G[0][Ea.H[0]+Ma];256<=vb.value?(Na.g=vb.g+256,Na.value=vb.value):(Na.g=0,Na.value=0,Ma>>=ub(vb,8,Na),Ma>>=ub(Ea.G[1][Ea.H[1]+Ma],16,Na),Ma>>=ub(Ea.G[2][Ea.H[2]+Ma],0,Na),ub(Ea.G[3][Ea.H[3]+Ma],24,Na))}}}R.vc=P,R.Wb=W,R.Ya=la,R.yc=ma,H=1;break b}H=0}if(!(f=H)){d.a=3;break a}if(0<n){if(l.ua=1<<n,!Zb(l.Wa,n)){d.a=1,f=0;break a}}else l.ua=0;var Qa=d,cb=g,ob=h,Ra=Qa.s,Ta=Ra.xc;if(Qa.c=cb,Qa.i=ob,Ra.md=xa(cb,Ta),Ra.wc=0==Ta?-1:(1<<Ta)-1,c){d.xb=re;break a}if(null==(m=V(g*h))){d.a=1,f=0;break a}f=(f=Jb(d,m,0,g,h,h,null))&&!k.h;break a}return f?(null!=e?e[0]=m:(x(null==m),x(c)),d.$=0,c||Ac(l)):Ac(l),f}function Ec(a,b){var c=a.c*a.i,d=c+b+16*b;return x(a.c<=b),a.V=V(d),null==a.V?(a.Ta=null,a.Ua=0,a.a=1,0):(a.Ta=a.V,a.Ua=a.Ba+c+b,1)}function se(a,b){var c=a.C,d=b-c,e=a.V,f=a.Ba+a.c*c;for(x(b<=a.l.o);0<d;){var g=16<d?16:d,h=a.l.ma,k=a.l.width,l=k*g,m=h.ca,n=h.tb+k*c,r=a.Ta,q=a.Ua;oc(a,g,e,f),Fc(r,q,m,n,l),zc(h,c,c+g,m,n,k),d-=g,e+=g*a.c,c+=g}x(c==b),a.C=a.Ma=b}function ue(){this.ub=this.yd=this.td=this.Rb=0}function ve(){this.Kd=this.Ld=this.Ud=this.Td=this.i=this.c=0}function we(){this.Fb=this.Bb=this.Cb=0,this.Zb=V(4),this.Lb=V(4)}function Gc(){this.Yb=function(){var L=[];return function F(J,H,Z){for(var O=Z[H],L=0;L<O&&(J.push(Z.length>H+1?[]:0),!(Z.length<H+1));L++)F(J[L],H+1,Z)}(L,0,[3,11]),L}()}function xe(){this.jb=V(3),this.Wc=Ed([4,8],Gc),this.Xc=Ed([4,17],Gc)}function ye(){this.Pc=this.wb=this.Tb=this.zd=0,this.vd=new V(4),this.od=new V(4)}function Xa(){this.ld=this.La=this.dd=this.tc=0}function Hc(){this.Na=this.la=0}function ze(){this.Sc=[0,0],this.Eb=[0,0],this.Qc=[0,0],this.ia=this.lc=0}function Kb(){this.ad=V(384),this.Za=0,this.Ob=V(16),this.$b=this.Ad=this.ia=this.Gc=this.Hc=this.Dd=0}function Ae(){this.uc=this.M=this.Nb=0,this.wa=Array(new Xa),this.Y=0,this.ya=Array(new Kb),this.aa=0,this.l=new Oa}function Ic(){this.y=V(16),this.f=V(8),this.ea=V(8)}function Be(){this.cb=this.a=0,this.sc="",this.m=new Wb,this.Od=new ue,this.Kc=new ve,this.ed=new ye,this.Qa=new we,this.Ic=this.$c=this.Aa=0,this.D=new Ae,this.Xb=this.Va=this.Hb=this.zb=this.yb=this.Ub=this.za=0,this.Jc=wa(8,Wb),this.ia=0,this.pb=wa(4,ze),this.Pa=new xe,this.Bd=this.kc=0,this.Ac=[],this.Bc=0,this.zc=[0,0,0,0],this.Gd=Array(new Ic),this.Hd=0,this.rb=Array(new Hc),this.sb=0,this.wa=Array(new Xa),this.Y=0,this.oc=[],this.pc=0,this.sa=[],this.ta=0,this.qa=[],this.ra=0,this.Ha=[],this.B=this.R=this.Ia=0,this.Ec=[],this.M=this.ja=this.Vb=this.Fc=0,this.ya=Array(new Kb),this.L=this.aa=0,this.gd=Ed([4,2],Xa),this.ga=null,this.Fa=[],this.Cc=this.qc=this.P=0,this.Gb=[],this.Uc=0,this.mb=[],this.nb=0,this.rc=[],this.Ga=this.Vc=0}function ga(a,b){return 0>a?0:a>b?b:a}function Oa(){this.T=this.U=this.ka=this.height=this.width=0,this.y=[],this.f=[],this.ea=[],this.Rc=this.fa=this.W=this.N=this.O=0,this.ma="void",this.put="VP8IoPutHook",this.ac="VP8IoSetupHook",this.bc="VP8IoTeardownHook",this.ha=this.Kb=0,this.data=[],this.hb=this.ib=this.da=this.o=this.j=this.va=this.v=this.Da=this.ob=this.w=0,this.F=[],this.J=0}function Ce(){var a=new Be;return null!=a&&(a.a=0,a.sc="OK",a.cb=0,a.Xb=0,oa||(oa=De)),a}function T(a,b,c){return 0==a.a&&(a.a=b,a.sc=c,a.cb=0),0}function Jc(a,b,c){return 3<=c&&157==a[b+0]&&1==a[b+1]&&42==a[b+2]}function Kc(a,b){if(null==a)return 0;if(a.a=0,a.sc="OK",null==b)return T(a,2,"null VP8Io passed to VP8GetHeaders()");var c=b.data,d=b.w,e=b.ha;if(4>e)return T(a,7,"Truncated header.");var f=c[d+0]|c[d+1]<<8|c[d+2]<<16,g=a.Od;if(g.Rb=!(1&f),g.td=f>>1&7,g.yd=f>>4&1,g.ub=f>>5,3<g.td)return T(a,3,"Incorrect keyframe parameters.");if(!g.yd)return T(a,4,"Frame not displayable.");d+=3,e-=3;var h=a.Kc;if(g.Rb){if(7>e)return T(a,7,"cannot parse picture header");if(!Jc(c,d,e))return T(a,3,"Bad code word");h.c=16383&(c[d+4]<<8|c[d+3]),h.Td=c[d+4]>>6,h.i=16383&(c[d+6]<<8|c[d+5]),h.Ud=c[d+6]>>6,d+=7,e-=7,a.za=h.c+15>>4,a.Ub=h.i+15>>4,b.width=h.c,b.height=h.i,b.Da=0,b.j=0,b.v=0,b.va=b.width,b.o=b.height,b.da=0,b.ib=b.width,b.hb=b.height,b.U=b.width,b.T=b.height,M((f=a.Pa).jb,0,255,f.jb.length),x(null!=(f=a.Qa)),f.Cb=0,f.Bb=0,f.Fb=1,M(f.Zb,0,0,f.Zb.length),M(f.Lb,0,0,f.Lb)}if(g.ub>e)return T(a,7,"bad partition length");ma(f=a.m,c,d,g.ub),d+=g.ub,e-=g.ub,g.Rb&&(h.Ld=G(f),h.Kd=G(f)),h=a.Qa;var l,k=a.Pa;if(x(null!=f),x(null!=h),h.Cb=G(f),h.Cb){if(h.Bb=G(f),G(f)){for(h.Fb=G(f),l=0;4>l;++l)h.Zb[l]=G(f)?ca(f,7):0;for(l=0;4>l;++l)h.Lb[l]=G(f)?ca(f,6):0}if(h.Bb)for(l=0;3>l;++l)k.jb[l]=G(f)?na(f,8):255}else h.Bb=0;if(f.Ka)return T(a,3,"cannot parse segment header");if((h=a.ed).zd=G(f),h.Tb=na(f,6),h.wb=na(f,3),h.Pc=G(f),h.Pc&&G(f)){for(k=0;4>k;++k)G(f)&&(h.vd[k]=ca(f,6));for(k=0;4>k;++k)G(f)&&(h.od[k]=ca(f,6))}if(a.L=0==h.Tb?0:h.zd?1:2,f.Ka)return T(a,3,"cannot parse filter header");var m=e;if(e=l=d,d=l+m,h=m,a.Xb=(1<<na(a.m,2))-1,m<3*(k=a.Xb))c=7;else{for(l+=3*k,h-=3*k,m=0;m<k;++m){var n=c[e+0]|c[e+1]<<8|c[e+2]<<16;n>h&&(n=h),ma(a.Jc[+m],c,l,n),l+=n,h-=n,e+=3}ma(a.Jc[+k],c,l,h),c=l<d?0:5}if(0!=c)return T(a,c,"cannot parse partitions");for(c=na(l=a.m,7),e=G(l)?ca(l,4):0,d=G(l)?ca(l,4):0,h=G(l)?ca(l,4):0,k=G(l)?ca(l,4):0,l=G(l)?ca(l,4):0,m=a.Qa,n=0;4>n;++n){if(m.Cb){var r=m.Zb[n];m.Fb||(r+=c)}else{if(0<n){a.pb[n]=a.pb[0];continue}r=c}var q=a.pb[n];q.Sc[0]=Lb[ga(r+e,127)],q.Sc[1]=Mb[ga(r+0,127)],q.Eb[0]=2*Lb[ga(r+d,127)],q.Eb[1]=101581*Mb[ga(r+h,127)]>>16,8>q.Eb[1]&&(q.Eb[1]=8),q.Qc[0]=Lb[ga(r+k,117)],q.Qc[1]=Mb[ga(r+l,127)],q.lc=r+l}if(!g.Rb)return T(a,4,"Not a key frame.");for(G(f),g=a.Pa,c=0;4>c;++c){for(e=0;8>e;++e)for(d=0;3>d;++d)for(h=0;11>h;++h)k=K(f,Ee[c][e][d][h])?na(f,8):Fe[c][e][d][h],g.Wc[c][e].Yb[d][h]=k;for(e=0;17>e;++e)g.Xc[c][e]=g.Wc[c][Ge[e]]}return a.kc=G(f),a.kc&&(a.Bd=na(f,8)),a.cb=1}function De(a,b,c,d,e,f,g){var h=b[e].Yb[c];for(c=0;16>e;++e){if(!K(a,h[c+0]))return e;for(;!K(a,h[c+1]);)if(h=b[++e].Yb[0],c=0,16==e)return 16;var k=b[e+1].Yb;if(K(a,h[c+2])){var l=a,r=0;if(K(l,(m=h)[(n=c)+3]))if(K(l,m[n+6])){for(h=0,n=2*(r=K(l,m[n+8]))+(m=K(l,m[n+9+r])),r=0,m=He[n];m[h];++h)r+=r+K(l,m[h]);r+=3+(8<<n)}else K(l,m[n+7])?(r=7+2*K(l,165),r+=K(l,145)):r=5+K(l,159);else r=K(l,m[n+4])?3+K(l,m[n+5]):2;h=k[2]}else r=1,h=k[1];k=g+Ie[e],0>(l=a).b&&Qa(l);var n,m=l.b,q=(n=l.Ca>>1)-(l.I>>m)>>31;--l.b,l.Ca+=q,l.Ca|=1,l.I-=(n+1&q)<<m,f[k]=((r^q)-q)*d[(0<e)+0]}return 16}function Lc(a){var b=a.rb[a.sb-1];b.la=0,b.Na=0,M(a.zc,0,0,a.zc.length),a.ja=0}function Me(a,b){if(null==a)return 0;if(null==b)return T(a,2,"NULL VP8Io parameter in VP8Decode().");if(!a.cb&&!Kc(a,b))return 0;if(x(a.cb),null==b.ac||b.ac(b)){b.ob&&(a.L=0);var c=Ya[a.L];if(2==a.L?(a.yb=0,a.zb=0):(a.yb=b.v-c>>4,a.zb=b.j-c>>4,0>a.yb&&(a.yb=0),0>a.zb&&(a.zb=0)),a.Va=b.o+15+c>>4,a.Hb=b.va+15+c>>4,a.Hb>a.za&&(a.Hb=a.za),a.Va>a.Ub&&(a.Va=a.Ub),0<a.L){var d=a.ed;for(c=0;4>c;++c){var e;if(a.Qa.Cb){var f=a.Qa.Lb[c];a.Qa.Fb||(f+=d.Tb)}else f=d.Tb;for(e=0;1>=e;++e){var g=a.gd[c][e],h=f;if(d.Pc&&(h+=d.vd[0],e&&(h+=d.od[0])),0<(h=0>h?0:63<h?63:h)){var k=h;0<d.wb&&((k=4<d.wb?k>>2:k>>1)>9-d.wb&&(k=9-d.wb)),1>k&&(k=1),g.dd=k,g.tc=2*h+k,g.ld=40<=h?2:15<=h?1:0}else g.tc=0;g.La=e}}}c=0}else T(a,6,"Frame setup failed"),c=a.a;if(c=0==c){if(c){a.$c=0,0<a.Aa||(a.Ic=Ne);b:{c=a.Ic;d=4*(k=a.za);var l=32*k,m=k+1,n=0<a.L?k*(0<a.Aa?2:1):0,r=(2==a.Aa?2:1)*k;if((g=d+832+(e=3*(16*c+Ya[a.L])/2*l)+(f=null!=a.Fa&&0<a.Fa.length?a.Kc.c*a.Kc.i:0))!=g)c=0;else{if(g>a.Vb){if(a.Vb=0,a.Ec=V(g),a.Fc=0,null==a.Ec){c=T(a,1,"no memory during frame initialization.");break b}a.Vb=g}g=a.Ec,h=a.Fc,a.Ac=g,a.Bc=h,h+=d,a.Gd=wa(l,Ic),a.Hd=0,a.rb=wa(m+1,Hc),a.sb=1,a.wa=n?wa(n,Xa):null,a.Y=0,a.D.Nb=0,a.D.wa=a.wa,a.D.Y=a.Y,0<a.Aa&&(a.D.Y+=k),x(!0),a.oc=g,a.pc=h,h+=832,a.ya=wa(r,Kb),a.aa=0,a.D.ya=a.ya,a.D.aa=a.aa,2==a.Aa&&(a.D.aa+=k),a.R=16*k,a.B=8*k,k=(l=Ya[a.L])*a.R,l=l/2*a.B,a.sa=g,a.ta=h+k,a.qa=a.sa,a.ra=a.ta+16*c*a.R+l,a.Ha=a.qa,a.Ia=a.ra+8*c*a.B+l,a.$c=0,h+=e,a.mb=f?g:null,a.nb=f?h:null,x(h+f<=a.Fc+a.Vb),Lc(a),M(a.Ac,a.Bc,0,d),c=1}}if(c){if(b.ka=0,b.y=a.sa,b.O=a.ta,b.f=a.qa,b.N=a.ra,b.ea=a.Ha,b.Vd=a.Ia,b.fa=a.R,b.Rc=a.B,b.F=null,b.J=0,!ad){for(c=-255;255>=c;++c)bd[255+c]=0>c?-c:c;for(c=-1020;1020>=c;++c)cd[1020+c]=-128>c?-128:127<c?127:c;for(c=-112;112>=c;++c)dd[112+c]=-16>c?-16:15<c?15:c;for(c=-255;510>=c;++c)ed[255+c]=0>c?0:255<c?255:c;ad=1}Nc=Oe,Za=Pe,Nb=Qe,pa=Re,Ob=Se,fd=Te,Xc=Ue,Tc=Ve,Yc=We,Uc=Xe,Zc=Ye,Vc=Ze,$c=$e,Wc=af,Rc=gd,Pc=hd,Sc=bf,Qc=cf,W[0]=df,W[1]=ef,W[2]=ff,W[3]=gf,W[4]=hf,W[5]=jf,W[6]=kf,W[7]=lf,W[8]=mf,W[9]=nf,Y[0]=of,Y[1]=pf,Y[2]=qf,Y[3]=rf,Y[4]=sf,Y[5]=tf,Y[6]=uf,ka[0]=vf,ka[1]=wf,ka[2]=xf,ka[3]=yf,ka[4]=zf,ka[5]=Af,ka[6]=Bf,c=1}else c=0}c&&(c=function(a,b){for(a.M=0;a.M<a.Va;++a.M){var f,c=a.Jc[a.M&a.Xb],d=a.m,e=a;for(f=0;f<e.za;++f){var g=d,h=e,k=h.Ac,l=h.Bc+4*f,m=h.zc,n=h.ya[h.aa+f];if(h.Qa.Bb?n.$b=K(g,h.Pa.jb[0])?2+K(g,h.Pa.jb[2]):K(g,h.Pa.jb[1]):n.$b=0,h.kc&&(n.Ad=K(g,h.Bd)),n.Za=!K(g,145)+0,n.Za){var r=n.Ob,q=0;for(h=0;4>h;++h){var v,t=m[0+h];for(v=0;4>v;++v){t=Ke[k[l+v]][t];for(var p=Mc[K(g,t[0])];0<p;)p=Mc[2*p+K(g,t[p])];t=-p,k[l+v]=t}I(r,q,k,l,4),q+=4,m[0+h]=t}}else t=K(g,156)?K(g,128)?1:3:K(g,163)?2:0,n.Ob[0]=t,M(k,l,t,4),M(m,0,t,4);n.Dd=K(g,142)?K(g,114)?K(g,183)?1:3:2:0}if(e.m.Ka)return T(a,7,"Premature end-of-partition0 encountered.");for(;a.ja<a.za;++a.ja){if(e=c,g=(d=a).rb[d.sb-1],k=d.rb[d.sb+d.ja],f=d.ya[d.aa+d.ja],l=d.kc?f.Ad:0)g.la=k.la=0,f.Za||(g.Na=k.Na=0),f.Hc=0,f.Gc=0,f.ia=0;else{var u,w;if(g=k,k=e,l=d.Pa.Xc,m=d.ya[d.aa+d.ja],n=d.pb[m.$b],h=m.ad,r=0,q=d.rb[d.sb-1],t=v=0,M(h,r,0,384),m.Za)var y=0,A=l[3];else{p=V(16);var E=g.Na+q.Na;if(E=oa(k,l[1],E,n.Eb,0,p,0),g.Na=q.Na=(0<E)+0,1<E)Nc(p,0,h,r);else{var B=p[0]+3>>3;for(p=0;256>p;p+=16)h[r+p]=B}y=1,A=l[0]}var C=15&g.la,N=15&q.la;for(p=0;4>p;++p){var z=1&N;for(B=w=0;4>B;++B)C=C>>1|(z=(E=oa(k,A,E=z+(1&C),n.Sc,y,h,r))>y)<<7,w=w<<2|(3<E?3:1<E?2:0!=h[r+0]),r+=16;C>>=4,N=N>>1|z<<7,v=(v<<8|w)>>>0}for(A=C,y=N>>4,u=0;4>u;u+=2){for(w=0,C=g.la>>4+u,N=q.la>>4+u,p=0;2>p;++p){for(z=1&N,B=0;2>B;++B)E=z+(1&C),C=C>>1|(z=0<(E=oa(k,l[2],E,n.Qc,0,h,r)))<<3,w=w<<2|(3<E?3:1<E?2:0!=h[r+0]),r+=16;C>>=2,N=N>>1|z<<5}t|=w<<4*u,A|=C<<4<<u,y|=(240&N)<<u}g.la=A,q.la=y,m.Hc=v,m.Gc=t,m.ia=43690&t?0:n.ia,l=!(v|t)}if(0<d.L&&(d.wa[d.Y+d.ja]=d.gd[f.$b][f.Za],d.wa[d.Y+d.ja].La|=!l),e.Ka)return T(a,7,"Premature end-of-file encountered.")}if(Lc(a),d=b,e=1,f=(c=a).D,g=0<c.L&&c.M>=c.zb&&c.M<=c.Va,0==c.Aa)a:{if(f.M=c.M,f.uc=g,Oc(c,f),e=1,f=(w=c.D).Nb,g=(t=Ya[c.L])*c.R,k=t/2*c.B,p=16*f*c.R,B=8*f*c.B,l=c.sa,m=c.ta-g+p,n=c.qa,h=c.ra-k+B,r=c.Ha,q=c.Ia-k+B,N=0==(C=w.M),v=C>=c.Va-1,2==c.Aa&&Oc(c,w),w.uc)for(z=(E=c).D.M,x(E.D.uc),w=E.yb;w<E.Hb;++w){y=w,A=z;var D=(S=(Q=E).D).Nb;u=Q.R;var S=S.wa[S.Y+y],F=Q.sa,H=Q.ta+16*D*u+16*y,J=S.dd,G=S.tc;if(0!=G)if(x(3<=G),1==Q.L)0<y&&Pc(F,H,u,G+4),S.La&&Qc(F,H,u,G),0<A&&Rc(F,H,u,G+4),S.La&&Sc(F,H,u,G);else{var L=Q.B,O=Q.qa,P=Q.ra+8*D*L+8*y,R=Q.Ha,Q=Q.Ia+8*D*L+8*y;D=S.ld,0<y&&(Tc(F,H,u,G+4,J,D),Uc(O,P,R,Q,L,G+4,J,D)),S.La&&(Vc(F,H,u,G,J,D),Wc(O,P,R,Q,L,G,J,D)),0<A&&(Xc(F,H,u,G+4,J,D),Yc(O,P,R,Q,L,G+4,J,D)),S.La&&(Zc(F,H,u,G,J,D),$c(O,P,R,Q,L,G,J,D))}}if(c.ia&&alert("todo:DitherRow"),null!=d.put){if(w=16*C,C=16*(C+1),N?(d.y=c.sa,d.O=c.ta+p,d.f=c.qa,d.N=c.ra+B,d.ea=c.Ha,d.W=c.Ia+B):(w-=t,d.y=l,d.O=m,d.f=n,d.N=h,d.ea=r,d.W=q),v||(C-=t),C>d.o&&(C=d.o),d.F=null,d.J=null,null!=c.Fa&&0<c.Fa.length&&w<C&&(d.J=Le(c,d,w,C-w),d.F=c.mb,null==d.F&&0==d.F.length)){e=T(c,3,"Could not decode alpha data.");break a}w<d.j&&(t=d.j-w,w=d.j,x(!(1&t)),d.O+=c.R*t,d.N+=c.B*(t>>1),d.W+=c.B*(t>>1),null!=d.F&&(d.J+=d.width*t)),w<C&&(d.O+=d.v,d.N+=d.v>>1,d.W+=d.v>>1,null!=d.F&&(d.J+=d.v),d.ka=w-d.j,d.U=d.va-d.v,d.T=C-w,e=d.put(d))}f+1!=c.Ic||v||(I(c.sa,c.ta-g,l,m+16*c.R,g),I(c.qa,c.ra-k,n,h+8*c.B,k),I(c.Ha,c.Ia-k,r,q+8*c.B,k))}if(!e)return T(a,6,"Output aborted.")}return 1}(a,b)),null!=b.bc&&b.bc(b),c&=1}return c?(a.cb=0,c):0}function qa(a,b,c,d,e){e=a[b+c+32*d]+(e>>3),a[b+c+32*d]=-256&e?0>e?0:255:e}function kb(a,b,c,d,e,f){qa(a,b,0,c,d+e),qa(a,b,1,c,d+f),qa(a,b,2,c,d-f),qa(a,b,3,c,d-e)}function da(a){return(20091*a>>16)+a}function id(a,b,c,d){var f,e=0,g=V(16);for(f=0;4>f;++f){var h=a[b+0]+a[b+8],k=a[b+0]-a[b+8],l=(35468*a[b+4]>>16)-da(a[b+12]),m=da(a[b+4])+(35468*a[b+12]>>16);g[e+0]=h+m,g[e+1]=k+l,g[e+2]=k-l,g[e+3]=h-m,e+=4,b++}for(f=e=0;4>f;++f)h=(a=g[e+0]+4)+g[e+8],k=a-g[e+8],l=(35468*g[e+4]>>16)-da(g[e+12]),qa(c,d,0,0,h+(m=da(g[e+4])+(35468*g[e+12]>>16))),qa(c,d,1,0,k+l),qa(c,d,2,0,k-l),qa(c,d,3,0,h-m),e++,d+=32}function Te(a,b,c,d){var e=a[b+0]+4,f=35468*a[b+4]>>16,g=da(a[b+4]),h=35468*a[b+1]>>16;kb(c,d,0,e+g,a=da(a[b+1]),h),kb(c,d,1,e+f,a,h),kb(c,d,2,e-f,a,h),kb(c,d,3,e-g,a,h)}function Pe(a,b,c,d,e){id(a,b,c,d),e&&id(a,b+16,c,d+4)}function Qe(a,b,c,d){Za(a,b+0,c,d,1),Za(a,b+32,c,d+128,1)}function Re(a,b,c,d){var e;for(a=a[b+0]+4,e=0;4>e;++e)for(b=0;4>b;++b)qa(c,d,b,e,a)}function Se(a,b,c,d){a[b+0]&&pa(a,b+0,c,d),a[b+16]&&pa(a,b+16,c,d+4),a[b+32]&&pa(a,b+32,c,d+128),a[b+48]&&pa(a,b+48,c,d+128+4)}function Oe(a,b,c,d){var f,e=V(16);for(f=0;4>f;++f){var g=a[b+0+f]+a[b+12+f],h=a[b+4+f]+a[b+8+f],k=a[b+4+f]-a[b+8+f],l=a[b+0+f]-a[b+12+f];e[0+f]=g+h,e[8+f]=g-h,e[4+f]=l+k,e[12+f]=l-k}for(f=0;4>f;++f)g=(a=e[0+4*f]+3)+e[3+4*f],h=e[1+4*f]+e[2+4*f],k=e[1+4*f]-e[2+4*f],l=a-e[3+4*f],c[d+0]=g+h>>3,c[d+16]=l+k>>3,c[d+32]=g-h>>3,c[d+48]=l-k>>3,d+=64}function Pb(a,b,c){var g,d=b-32,e=R,f=255-a[d-1];for(g=0;g<c;++g){var l,h=e,k=f+a[b-1];for(l=0;l<c;++l)a[b+l]=h[k+a[d+l]];b+=32}}function ef(a,b){Pb(a,b,4)}function wf(a,b){Pb(a,b,8)}function pf(a,b){Pb(a,b,16)}function qf(a,b){var c;for(c=0;16>c;++c)I(a,b+32*c,a,b-32,16)}function rf(a,b){var c;for(c=16;0<c;--c)M(a,b,a[b-1],16),b+=32}function $a(a,b,c){var d;for(d=0;16>d;++d)M(b,c+32*d,a,16)}function of(a,b){var d,c=16;for(d=0;16>d;++d)c+=a[b-1+32*d]+a[b+d-32];$a(c>>5,a,b)}function sf(a,b){var d,c=8;for(d=0;16>d;++d)c+=a[b-1+32*d];$a(c>>4,a,b)}function tf(a,b){var d,c=8;for(d=0;16>d;++d)c+=a[b+d-32];$a(c>>4,a,b)}function uf(a,b){$a(128,a,b)}function z(a,b,c){return a+2*b+c+2>>2}function ff(a,b){var d,c=b-32;c=new Uint8Array([z(a[c-1],a[c+0],a[c+1]),z(a[c+0],a[c+1],a[c+2]),z(a[c+1],a[c+2],a[c+3]),z(a[c+2],a[c+3],a[c+4])]);for(d=0;4>d;++d)I(a,b+32*d,c,0,c.length)}function gf(a,b){var c=a[b-1],d=a[b-1+32],e=a[b-1+64],f=a[b-1+96];ra(a,b+0,16843009*z(a[b-1-32],c,d)),ra(a,b+32,16843009*z(c,d,e)),ra(a,b+64,16843009*z(d,e,f)),ra(a,b+96,16843009*z(e,f,f))}function df(a,b){var d,c=4;for(d=0;4>d;++d)c+=a[b+d-32]+a[b-1+32*d];for(c>>=3,d=0;4>d;++d)M(a,b+32*d,c,4)}function hf(a,b){var c=a[b-1+0],d=a[b-1+32],e=a[b-1+64],f=a[b-1-32],g=a[b+0-32],h=a[b+1-32],k=a[b+2-32],l=a[b+3-32];a[b+0+96]=z(d,e,a[b-1+96]),a[b+1+96]=a[b+0+64]=z(c,d,e),a[b+2+96]=a[b+1+64]=a[b+0+32]=z(f,c,d),a[b+3+96]=a[b+2+64]=a[b+1+32]=a[b+0+0]=z(g,f,c),a[b+3+64]=a[b+2+32]=a[b+1+0]=z(h,g,f),a[b+3+32]=a[b+2+0]=z(k,h,g),a[b+3+0]=z(l,k,h)}function kf(a,b){var c=a[b+1-32],d=a[b+2-32],e=a[b+3-32],f=a[b+4-32],g=a[b+5-32],h=a[b+6-32],k=a[b+7-32];a[b+0+0]=z(a[b+0-32],c,d),a[b+1+0]=a[b+0+32]=z(c,d,e),a[b+2+0]=a[b+1+32]=a[b+0+64]=z(d,e,f),a[b+3+0]=a[b+2+32]=a[b+1+64]=a[b+0+96]=z(e,f,g),a[b+3+32]=a[b+2+64]=a[b+1+96]=z(f,g,h),a[b+3+64]=a[b+2+96]=z(g,h,k),a[b+3+96]=z(h,k,k)}function jf(a,b){var c=a[b-1+0],d=a[b-1+32],e=a[b-1+64],f=a[b-1-32],g=a[b+0-32],h=a[b+1-32],k=a[b+2-32],l=a[b+3-32];a[b+0+0]=a[b+1+64]=f+g+1>>1,a[b+1+0]=a[b+2+64]=g+h+1>>1,a[b+2+0]=a[b+3+64]=h+k+1>>1,a[b+3+0]=k+l+1>>1,a[b+0+96]=z(e,d,c),a[b+0+64]=z(d,c,f),a[b+0+32]=a[b+1+96]=z(c,f,g),a[b+1+32]=a[b+2+96]=z(f,g,h),a[b+2+32]=a[b+3+96]=z(g,h,k),a[b+3+32]=z(h,k,l)}function lf(a,b){var c=a[b+0-32],d=a[b+1-32],e=a[b+2-32],f=a[b+3-32],g=a[b+4-32],h=a[b+5-32],k=a[b+6-32],l=a[b+7-32];a[b+0+0]=c+d+1>>1,a[b+1+0]=a[b+0+64]=d+e+1>>1,a[b+2+0]=a[b+1+64]=e+f+1>>1,a[b+3+0]=a[b+2+64]=f+g+1>>1,a[b+0+32]=z(c,d,e),a[b+1+32]=a[b+0+96]=z(d,e,f),a[b+2+32]=a[b+1+96]=z(e,f,g),a[b+3+32]=a[b+2+96]=z(f,g,h),a[b+3+64]=z(g,h,k),a[b+3+96]=z(h,k,l)}function nf(a,b){var c=a[b-1+0],d=a[b-1+32],e=a[b-1+64],f=a[b-1+96];a[b+0+0]=c+d+1>>1,a[b+2+0]=a[b+0+32]=d+e+1>>1,a[b+2+32]=a[b+0+64]=e+f+1>>1,a[b+1+0]=z(c,d,e),a[b+3+0]=a[b+1+32]=z(d,e,f),a[b+3+32]=a[b+1+64]=z(e,f,f),a[b+3+64]=a[b+2+64]=a[b+0+96]=a[b+1+96]=a[b+2+96]=a[b+3+96]=f}function mf(a,b){var c=a[b-1+0],d=a[b-1+32],e=a[b-1+64],f=a[b-1+96],g=a[b-1-32],h=a[b+0-32],k=a[b+1-32],l=a[b+2-32];a[b+0+0]=a[b+2+32]=c+g+1>>1,a[b+0+32]=a[b+2+64]=d+c+1>>1,a[b+0+64]=a[b+2+96]=e+d+1>>1,a[b+0+96]=f+e+1>>1,a[b+3+0]=z(h,k,l),a[b+2+0]=z(g,h,k),a[b+1+0]=a[b+3+32]=z(c,g,h),a[b+1+32]=a[b+3+64]=z(d,c,g),a[b+1+64]=a[b+3+96]=z(e,d,c),a[b+1+96]=z(f,e,d)}function xf(a,b){var c;for(c=0;8>c;++c)I(a,b+32*c,a,b-32,8)}function yf(a,b){var c;for(c=0;8>c;++c)M(a,b,a[b-1],8),b+=32}function lb(a,b,c){var d;for(d=0;8>d;++d)M(b,c+32*d,a,8)}function vf(a,b){var d,c=8;for(d=0;8>d;++d)c+=a[b+d-32]+a[b-1+32*d];lb(c>>4,a,b)}function Af(a,b){var d,c=4;for(d=0;8>d;++d)c+=a[b+d-32];lb(c>>3,a,b)}function zf(a,b){var d,c=4;for(d=0;8>d;++d)c+=a[b-1+32*d];lb(c>>3,a,b)}function Bf(a,b){lb(128,a,b)}function ab(a,b,c){var d=a[b-c],e=a[b+0],f=3*(e-d)+Qb[1020+a[b-2*c]-a[b+c]],g=mb[112+(f+4>>3)];a[b-c]=R[255+d+mb[112+(f+3>>3)]],a[b+0]=R[255+e-g]}function jd(a,b,c,d){var e=a[b+0],f=a[b+c];return U[255+a[b-2*c]-a[b-c]]>d||U[255+f-e]>d}function kd(a,b,c,d){return 4*U[255+a[b-c]-a[b+0]]+U[255+a[b-2*c]-a[b+c]]<=d}function ld(a,b,c,d,e){var f=a[b-3*c],g=a[b-2*c],h=a[b-c],k=a[b+0],l=a[b+c],m=a[b+2*c],n=a[b+3*c];return 4*U[255+h-k]+U[255+g-l]>d?0:U[255+a[b-4*c]-f]<=e&&U[255+f-g]<=e&&U[255+g-h]<=e&&U[255+n-m]<=e&&U[255+m-l]<=e&&U[255+l-k]<=e}function gd(a,b,c,d){var e=2*d+1;for(d=0;16>d;++d)kd(a,b+d,c,e)&&ab(a,b+d,c)}function hd(a,b,c,d){var e=2*d+1;for(d=0;16>d;++d)kd(a,b+d*c,1,e)&&ab(a,b+d*c,1)}function bf(a,b,c,d){var e;for(e=3;0<e;--e)gd(a,b+=4*c,c,d)}function cf(a,b,c,d){var e;for(e=3;0<e;--e)hd(a,b+=4,c,d)}function ea(a,b,c,d,e,f,g,h){for(f=2*f+1;0<e--;){if(ld(a,b,c,f,g))if(jd(a,b,c,h))ab(a,b,c);else{var k=a,l=b,m=c,n=k[l-2*m],r=k[l-m],q=k[l+0],t=k[l+m],v=k[l+2*m],u=27*(p=Qb[1020+3*(q-r)+Qb[1020+n-t]])+63>>7,w=18*p+63>>7,p=9*p+63>>7;k[l-3*m]=R[255+k[l-3*m]+p],k[l-2*m]=R[255+n+w],k[l-m]=R[255+r+u],k[l+0]=R[255+q-u],k[l+m]=R[255+t-w],k[l+2*m]=R[255+v-p]}b+=d}}function Fa(a,b,c,d,e,f,g,h){for(f=2*f+1;0<e--;){if(ld(a,b,c,f,g))if(jd(a,b,c,h))ab(a,b,c);else{var k=a,l=b,m=c,n=k[l-m],r=k[l+0],q=k[l+m],v=mb[112+((t=3*(r-n))+4>>3)],t=mb[112+(t+3>>3)],p=v+1>>1;k[l-2*m]=R[255+k[l-2*m]+p],k[l-m]=R[255+n+t],k[l+0]=R[255+r-v],k[l+m]=R[255+q-p]}b+=d}}function Ue(a,b,c,d,e,f){ea(a,b,c,1,16,d,e,f)}function Ve(a,b,c,d,e,f){ea(a,b,1,c,16,d,e,f)}function Ye(a,b,c,d,e,f){var g;for(g=3;0<g;--g)Fa(a,b+=4*c,c,1,16,d,e,f)}function Ze(a,b,c,d,e,f){var g;for(g=3;0<g;--g)Fa(a,b+=4,1,c,16,d,e,f)}function We(a,b,c,d,e,f,g,h){ea(a,b,e,1,8,f,g,h),ea(c,d,e,1,8,f,g,h)}function Xe(a,b,c,d,e,f,g,h){ea(a,b,1,e,8,f,g,h),ea(c,d,1,e,8,f,g,h)}function $e(a,b,c,d,e,f,g,h){Fa(a,b+4*e,e,1,8,f,g,h),Fa(c,d+4*e,e,1,8,f,g,h)}function af(a,b,c,d,e,f,g,h){Fa(a,b+4,1,e,8,f,g,h),Fa(c,d+4,1,e,8,f,g,h)}function Cf(){this.ba=new Cb,this.ec=[],this.cc=[],this.Mc=[],this.Dc=this.Nc=this.dc=this.fc=0,this.Oa=new Ud,this.memory=0,this.Ib="OutputFunc",this.Jb="OutputAlphaFunc",this.Nd="OutputRowFunc"}function md(){this.data=[],this.offset=this.kd=this.ha=this.w=0,this.na=[],this.xa=this.gb=this.Ja=this.Sa=this.P=0}function Df(){this.nc=this.Ea=this.b=this.hc=0,this.K=[],this.w=0}function Ef(){this.ua=0,this.Wa=new ac,this.vb=new ac,this.md=this.xc=this.wc=0,this.vc=[],this.Wb=0,this.Ya=new Ub,this.yc=new O}function je(){this.xb=this.a=0,this.l=new Oa,this.ca=new Cb,this.V=[],this.Ba=0,this.Ta=[],this.Ua=0,this.m=new Ra,this.Pb=0,this.wd=new Ra,this.Ma=this.$=this.C=this.i=this.c=this.xd=0,this.s=new Ef,this.ab=0,this.gc=wa(4,Df),this.Oc=0}function Ff(){this.Lc=this.Z=this.$a=this.i=this.c=0,this.l=new Oa,this.ic=0,this.ca=[],this.tb=0,this.qd=null,this.rd=0}function Rb(a,b,c,d,e,f,g){for(a=null==a?0:a[b+0],b=0;b<g;++b)e[f+b]=a+c[d+b]&255,a=e[f+b]}function Gf(a,b,c,d,e,f,g){var h;if(null==a)Rb(null,null,c,d,e,f,g);else for(h=0;h<g;++h)e[f+h]=a[b+h]+c[d+h]&255}function Hf(a,b,c,d,e,f,g){if(null==a)Rb(null,null,c,d,e,f,g);else{var m,h=a[b+0],k=h,l=h;for(m=0;m<g;++m)k=l+(h=a[b+m])-k,l=c[d+m]+(-256&k?0>k?0:255:k)&255,k=h,e[f+m]=l}}function Le(a,b,c,d){var e=b.width,f=b.o;if(x(null!=a&&null!=b),0>c||0>=d||c+d>f)return null;if(!a.Cc){if(null==a.ga){var g;if(a.ga=new Ff,(g=null==a.ga)||(g=b.width*b.o,x(0==a.Gb.length),a.Gb=V(g),a.Uc=0,null==a.Gb?g=0:(a.mb=a.Gb,a.nb=a.Uc,a.rc=null,g=1),g=!g),!g){g=a.ga;var h=a.Fa,k=a.P,l=a.qc,m=a.mb,n=a.nb,r=k+1,q=l-1,t=g.l;if(x(null!=h&&null!=m&&null!=b),ia[0]=null,ia[1]=Rb,ia[2]=Gf,ia[3]=Hf,g.ca=m,g.tb=n,g.c=b.width,g.i=b.height,x(0<g.c&&0<g.i),1>=l)b=0;else if(g.$a=h[k+0]>>0&3,g.Z=h[k+0]>>2&3,g.Lc=h[k+0]>>4&3,k=h[k+0]>>6&3,0>g.$a||1<g.$a||4<=g.Z||1<g.Lc||k)b=0;else if(t.put=kc,t.ac=gc,t.bc=lc,t.ma=g,t.width=b.width,t.height=b.height,t.Da=b.Da,t.v=b.v,t.va=b.va,t.j=b.j,t.o=b.o,g.$a)b:{x(1==g.$a),b=Bc();c:for(;;){if(null==b){b=0;break b}if(x(null!=g),g.mc=b,b.c=g.c,b.i=g.i,b.l=g.l,b.l.ma=g,b.l.width=g.c,b.l.height=g.i,b.a=0,cb(b.m,h,r,q),!rb(g.c,g.i,1,b,null))break c;if(1==b.ab&&3==b.gc[0].hc&&yc(b.s)?(g.ic=1,h=b.c*b.i,b.Ta=null,b.Ua=0,b.V=V(h),b.Ba=0,null==b.V?(b.a=1,b=0):b=1):(g.ic=0,b=Ec(b,g.c)),!b)break c;b=1;break b}g.mc=null,b=0}else b=q>=g.c*g.i;g=!b}if(g)return null;1!=a.ga.Lc?a.Ga=0:d=f-c}x(null!=a.ga),x(c+d<=f);a:{if(b=(h=a.ga).c,f=h.l.o,0==h.$a){if(r=a.rc,q=a.Vc,t=a.Fa,k=a.P+1+c*b,l=a.mb,m=a.nb+c*b,x(k<=a.P+a.qc),0!=h.Z)for(x(null!=ia[h.Z]),g=0;g<d;++g)ia[h.Z](r,q,t,k,l,m,b),r=l,q=m,m+=b,k+=b;else for(g=0;g<d;++g)I(l,m,t,k,b),r=l,q=m,m+=b,k+=b;a.rc=r,a.Vc=q}else{if(x(null!=h.mc),b=c+d,x(null!=(g=h.mc)),x(b<=g.i),g.C>=b)b=1;else if(h.ic||Aa(),h.ic){h=g.V,r=g.Ba,q=g.c;var v=g.i,p=(t=1,k=g.$/q,l=g.$%q,m=g.m,n=g.s,g.$),u=q*v,w=q*b,y=n.wc,A=p<w?ha(n,l,k):null;x(p<=u),x(b<=v),x(yc(n));c:for(;;){for(;!m.h&&p<w;){if(l&y||(A=ha(n,l,k)),x(null!=A),Sa(m),256>(v=ua(A.G[0],A.H[0],m)))h[r+p]=v,++p,++l>=q&&(l=0,++k<=b&&!(k%16)&&Ib(g,k));else{if(!(280>v)){t=0;break c}v=ib(v-256,m);var B,E=ua(A.G[4],A.H[4],m);if(Sa(m),!(p>=(E=nc(q,E=ib(E,m)))&&u-p>=v)){t=0;break c}for(B=0;B<v;++B)h[r+p+B]=h[r+p+B-E];for(p+=v,l+=v;l>=q;)l-=q,++k<=b&&!(k%16)&&Ib(g,k);p<w&&l&y&&(A=ha(n,l,k))}x(m.h==db(m))}Ib(g,k>b?b:k);break c}!t||m.h&&p<u?(t=0,g.a=m.h?5:3):g.$=p,b=t}else b=Jb(g,g.V,g.Ba,g.c,g.i,b,se);if(!b){d=0;break a}}c+d>=f&&(a.Cc=1),d=1}if(!d)return null;if(a.Cc&&(null!=(d=a.ga)&&(d.mc=null),a.ga=null,0<a.Ga))return alert("todo:WebPDequantizeLevels"),null}return a.nb+c*e}function If(a,b,c,d,e,f){for(;0<e--;){var m,g=a,h=b+(c?1:0),k=a,l=b+(c?0:3);for(m=0;m<d;++m){var n=k[l+4*m];255!=n&&(n*=32897,g[h+4*m+0]=g[h+4*m+0]*n>>23,g[h+4*m+1]=g[h+4*m+1]*n>>23,g[h+4*m+2]=g[h+4*m+2]*n>>23)}b+=f}}function Jf(a,b,c,d,e){for(;0<d--;){var f;for(f=0;f<c;++f){var g=a[b+2*f+0],k=15&(h=a[b+2*f+1]),l=4369*k,h=(240&h|h>>4)*l>>16;a[b+2*f+0]=(240&g|g>>4)*l>>16&240|(15&g|g<<4)*l>>16>>4&15,a[b+2*f+1]=240&h|k}b+=e}}function Kf(a,b,c,d,e,f,g,h){var l,m,k=255;for(m=0;m<e;++m){for(l=0;l<d;++l){var n=a[b+l];f[g+4*l]=n,k&=n}b+=c,g+=h}return 255!=k}function Lf(a,b,c,d,e){var f;for(f=0;f<e;++f)c[d+f]=a[b+f]>>8}function Aa(){za=If,vc=Jf,fc=Kf,Fc=Lf}function va(a,b,c){self[a]=function(a,e,f,g,h,k,l,m,n,r,q,t,v,p,u,w,y){var d,E=y-1>>1,B=h[k+0]|l[m+0]<<16,C=n[r+0]|q[t+0]<<16;x(null!=a);var z=3*B+C+131074>>2;for(b(a[e+0],255&z,z>>16,v,p),null!=f&&(z=3*C+B+131074>>2,b(f[g+0],255&z,z>>16,u,w)),d=1;d<=E;++d){var D=h[k+d]|l[m+d]<<16,G=n[r+d]|q[t+d]<<16,F=B+D+C+G+524296,H=F+2*(D+C)>>3;z=H+B>>1,B=(F=F+2*(B+G)>>3)+D>>1,b(a[e+2*d-1],255&z,z>>16,v,p+(2*d-1)*c),b(a[e+2*d-0],255&B,B>>16,v,p+(2*d-0)*c),null!=f&&(z=F+C>>1,B=H+G>>1,b(f[g+2*d-1],255&z,z>>16,u,w+(2*d-1)*c),b(f[g+2*d+0],255&B,B>>16,u,w+(2*d+0)*c)),B=D,C=G}1&y||(z=3*B+C+131074>>2,b(a[e+y-1],255&z,z>>16,v,p+(y-1)*c),null!=f&&(z=3*C+B+131074>>2,b(f[g+y-1],255&z,z>>16,u,w+(y-1)*c)))}}function ic(){P[Ca]=Mf,P[Ua]=nd,P[tc]=Nf,P[Va]=od,P[ya]=pd,P[Db]=qd,P[wc]=Of,P[zb]=nd,P[Ab]=od,P[Ja]=pd,P[Bb]=qd}function Sb(a){return a&~Pf?0>a?0:255:a>>rd}function bb(a,b){return Sb((19077*a>>8)+(26149*b>>8)-14234)}function nb(a,b,c){return Sb((19077*a>>8)-(6419*b>>8)-(13320*c>>8)+8708)}function Pa(a,b){return Sb((19077*a>>8)+(33050*b>>8)-17685)}function Ga(a,b,c,d,e){d[e+0]=bb(a,c),d[e+1]=nb(a,b,c),d[e+2]=Pa(a,b)}function Tb(a,b,c,d,e){d[e+0]=Pa(a,b),d[e+1]=nb(a,b,c),d[e+2]=bb(a,c)}function sd(a,b,c,d,e){var f=nb(a,b,c);b=f<<3&224|Pa(a,b)>>3,d[e+0]=248&bb(a,c)|f>>5,d[e+1]=b}function td(a,b,c,d,e){var f=240&Pa(a,b)|15;d[e+0]=240&bb(a,c)|nb(a,b,c)>>4,d[e+1]=f}function ud(a,b,c,d,e){d[e+0]=255,Ga(a,b,c,d,e+1)}function vd(a,b,c,d,e){Tb(a,b,c,d,e),d[e+3]=255}function wd(a,b,c,d,e){Ga(a,b,c,d,e),d[e+3]=255}function ga(a,b){return 0>a?0:a>b?b:a}function la(a,b,c){self[a]=function(a,e,f,g,h,k,l,m,n){for(var d=m+(-2&n)*c;m!=d;)b(a[e+0],f[g+0],h[k+0],l,m),b(a[e+1],f[g+0],h[k+0],l,m+c),e+=2,++g,++k,m+=2*c;1&n&&b(a[e+0],f[g+0],h[k+0],l,m)}}function xd(a,b,c){return 0==c?0==a?0==b?6:5:0==b?4:0:c}function yd(a,b,c,d,e){switch(a>>>30){case 3:Za(b,c,d,e,0);break;case 2:fd(b,c,d,e);break;case 1:pa(b,c,d,e)}}function Oc(a,b){var c,d,e=b.M,f=b.Nb,g=a.oc,h=a.pc+40,k=a.oc,l=a.pc+584,m=a.oc,n=a.pc+600;for(c=0;16>c;++c)g[h+32*c-1]=129;for(c=0;8>c;++c)k[l+32*c-1]=129,m[n+32*c-1]=129;for(0<e?g[h-1-32]=k[l-1-32]=m[n-1-32]=129:(M(g,h-32-1,127,21),M(k,l-32-1,127,9),M(m,n-32-1,127,9)),d=0;d<a.za;++d){var r=b.ya[b.aa+d];if(0<d){for(c=-1;16>c;++c)I(g,h+32*c-4,g,h+32*c+12,4);for(c=-1;8>c;++c)I(k,l+32*c-4,k,l+32*c+4,4),I(m,n+32*c-4,m,n+32*c+4,4)}var q=a.Gd,t=a.Hd+d,v=r.ad,p=r.Hc;if(0<e&&(I(g,h-32,q[t].y,0,16),I(k,l-32,q[t].f,0,8),I(m,n-32,q[t].ea,0,8)),r.Za){var u=g,w=h-32+16;for(0<e&&(d>=a.za-1?M(u,w,q[t].y[15],4):I(u,w,q[t+1].y,0,4)),c=0;4>c;c++)u[w+128+c]=u[w+256+c]=u[w+384+c]=u[w+0+c];for(c=0;16>c;++c,p<<=2)u=g,w=h+zd[c],W[r.Ob[c]](u,w),yd(p,v,16*+c,u,w)}else if(u=xd(d,e,r.Ob[0]),Y[u](g,h),0!=p)for(c=0;16>c;++c,p<<=2)yd(p,v,16*+c,g,h+zd[c]);for(c=r.Gc,u=xd(d,e,r.Dd),ka[u](k,l),ka[u](m,n),p=v,u=k,w=l,255&(r=c>>0)&&(170&r?Nb(p,256,u,w):Ob(p,256,u,w)),r=m,p=n,255&(c>>=8)&&(170&c?Nb(v,320,r,p):Ob(v,320,r,p)),e<a.Ub-1&&(I(q[t].y,0,g,h+480,16),I(q[t].f,0,k,l+224,8),I(q[t].ea,0,m,n+224,8)),c=8*f*a.B,q=a.sa,t=a.ta+16*d+16*f*a.R,v=a.qa,r=a.ra+8*d+c,p=a.Ha,u=a.Ia+8*d+c,c=0;16>c;++c)I(q,t+c*a.R,g,h+32*c,16);for(c=0;8>c;++c)I(v,r+c*a.B,k,l+32*c,8),I(p,u+c*a.B,m,n+32*c,8)}}function Ad(a,b,c,d,e,f,g,h,k){var l=[0],m=[0],n=0,r=null!=k?k.kd:0,q=null!=k?k:new md;if(null==a||12>c)return 7;q.data=a,q.w=b,q.ha=c,b=[b],c=[c],q.gb=[q.gb];a:{var t=b,v=c,p=q.gb;if(x(null!=a),x(null!=v),x(null!=p),p[0]=0,12<=v[0]&&!fa(a,t[0],"RIFF")){if(fa(a,t[0]+8,"WEBP")){p=3;break a}var u=Ha(a,t[0]+4);if(12>u||4294967286<u){p=3;break a}if(r&&u>v[0]-8){p=7;break a}p[0]=u,t[0]+=12,v[0]-=12}p=0}if(0!=p)return p;for(u=0<q.gb[0],c=c[0];;){a:{var w=a;v=b,p=c;var A=l,z=m,B=t=[0];if((y=n=[n])[0]=0,8>p[0])p=7;else{if(!fa(w,v[0],"VP8X")){if(10!=Ha(w,v[0]+4)){p=3;break a}if(18>p[0]){p=7;break a}var C=Ha(w,v[0]+8),D=1+Yb(w,v[0]+12);if(2147483648<=D*(w=1+Yb(w,v[0]+15))){p=3;break a}null!=B&&(B[0]=C),null!=A&&(A[0]=D),null!=z&&(z[0]=w),v[0]+=18,p[0]-=18,y[0]=1}p=0}}if(n=n[0],t=t[0],0!=p)return p;if(v=!!(2&t),!u&&n)return 3;if(null!=f&&(f[0]=!!(16&t)),null!=g&&(g[0]=v),null!=h&&(h[0]=0),g=l[0],t=m[0],n&&v&&null==k){p=0;break}if(4>c){p=7;break}if(u&&n||!u&&!n&&!fa(a,b[0],"ALPH")){c=[c],q.na=[q.na],q.P=[q.P],q.Sa=[q.Sa];a:{C=a,p=b,u=c;var y=q.gb;A=q.na,z=q.P,B=q.Sa;D=22,x(null!=C),x(null!=u),w=p[0];var F=u[0];for(x(null!=A),x(null!=B),A[0]=null,z[0]=null,B[0]=0;;){if(p[0]=w,u[0]=F,8>F){p=7;break a}var G=Ha(C,w+4);if(4294967286<G){p=3;break a}var H=8+G+1&-2;if(D+=H,0<y&&D>y){p=3;break a}if(!fa(C,w,"VP8 ")||!fa(C,w,"VP8L")){p=0;break a}if(F[0]<H){p=7;break a}fa(C,w,"ALPH")||(A[0]=C,z[0]=w+8,B[0]=G),w+=H,F-=H}}if(c=c[0],q.na=q.na[0],q.P=q.P[0],q.Sa=q.Sa[0],0!=p)break}c=[c],q.Ja=[q.Ja],q.xa=[q.xa];a:if(y=a,p=b,u=c,A=q.gb[0],z=q.Ja,B=q.xa,C=p[0],w=!fa(y,C,"VP8 "),D=!fa(y,C,"VP8L"),x(null!=y),x(null!=u),x(null!=z),x(null!=B),8>u[0])p=7;else{if(w||D){if(y=Ha(y,C+4),12<=A&&y>A-12){p=3;break a}if(r&&y>u[0]-8){p=7;break a}z[0]=y,p[0]+=8,u[0]-=8,B[0]=D}else B[0]=5<=u[0]&&47==y[C+0]&&!(y[C+4]>>5),z[0]=u[0];p=0}if(c=c[0],q.Ja=q.Ja[0],q.xa=q.xa[0],b=b[0],0!=p)break;if(4294967286<q.Ja)return 3;if(null==h||v||(h[0]=q.xa?2:1),g=[g],t=[t],q.xa){if(5>c){p=7;break}h=g,r=t,v=f,null==a||5>c?a=0:5<=c&&47==a[b+0]&&!(a[b+4]>>5)?(u=[0],y=[0],A=[0],cb(z=new Ra,a,b,c),mc(z,u,y,A)?(null!=h&&(h[0]=u[0]),null!=r&&(r[0]=y[0]),null!=v&&(v[0]=A[0]),a=1):a=0):a=0}else{if(10>c){p=7;break}h=t,null==a||10>c||!Jc(a,b+3,c-3)?a=0:(r=a[b+0]|a[b+1]<<8|a[b+2]<<16,v=16383&(a[b+7]<<8|a[b+6]),a=16383&(a[b+9]<<8|a[b+8]),1&r||3<(r>>1&7)||!(r>>4&1)||r>>5>=q.Ja||!v||!a?a=0:(g&&(g[0]=v),h&&(h[0]=a),a=1))}if(!a)return 3;if(g=g[0],t=t[0],n&&(l[0]!=g||m[0]!=t))return 3;null!=k&&(k[0]=q,k.offset=b-k.w,x(4294967286>b-k.w),x(k.offset==k.ha-c));break}return 0==p||7==p&&n&&null==k?(null!=f&&(f[0]|=null!=q.na&&0<q.na.length),null!=d&&(d[0]=g),null!=e&&(e[0]=t),0):p}function hc(a,b,c){var d=b.width,e=b.height,f=0,g=0,h=d,k=e;if(b.Da=null!=a&&0<a.Da,b.Da&&(h=a.cd,k=a.bd,f=a.v,g=a.j,11>c||(f&=-2,g&=-2),0>f||0>g||0>=h||0>=k||f+h>d||g+k>e))return 0;if(b.v=f,b.j=g,b.va=f+h,b.o=g+k,b.U=h,b.T=k,b.da=null!=a&&0<a.da,b.da){if(!bc(h,k,c=[a.ib],f=[a.hb]))return 0;b.ib=c[0],b.hb=f[0]}return b.ob=null!=a&&a.ob,b.Kb=null==a||!a.Sd,b.da&&(b.ob=b.ib<3*d/4&&b.hb<3*e/4,b.Kb=0),1}function Bd(a){if(null==a)return 2;if(11>a.S){var b=a.f.RGBA;b.fb+=(a.height-1)*b.A,b.A=-b.A}else b=a.f.kb,a=a.height,b.O+=(a-1)*b.fa,b.fa=-b.fa,b.N+=(a-1>>1)*b.Ab,b.Ab=-b.Ab,b.W+=(a-1>>1)*b.Db,b.Db=-b.Db,null!=b.F&&(b.J+=(a-1)*b.lb,b.lb=-b.lb);return 0}function Cd(a,b,c,d){if(null==d||0>=a||0>=b)return 2;if(null!=c){if(c.Da){var e=c.cd,f=c.bd,g=-2&c.v,h=-2&c.j;if(0>g||0>h||0>=e||0>=f||g+e>a||h+f>b)return 2;a=e,b=f}if(c.da){if(!bc(a,b,e=[c.ib],f=[c.hb]))return 2;a=e[0],b=f[0]}}d.width=a,d.height=b;a:{var k=d.width,l=d.height;if(a=d.S,0>=k||0>=l||!(a>=Ca&&13>a))a=2;else{if(0>=d.Rd&&null==d.sd){g=f=e=b=0;var m=(h=k*Dd[a])*l;if(11>a||(f=(l+1)/2*(b=(k+1)/2),12==a&&(g=(e=k)*l)),null==(l=V(m+2*f+g))){a=1;break a}d.sd=l,11>a?((k=d.f.RGBA).eb=l,k.fb=0,k.A=h,k.size=m):((k=d.f.kb).y=l,k.O=0,k.fa=h,k.Fd=m,k.f=l,k.N=0+m,k.Ab=b,k.Cd=f,k.ea=l,k.W=0+m+f,k.Db=b,k.Ed=f,12==a&&(k.F=l,k.J=0+m+2*f),k.Tc=g,k.lb=e)}if(b=1,e=d.S,f=d.width,g=d.height,e>=Ca&&13>e)if(11>e)a=d.f.RGBA,b&=(h=Math.abs(a.A))*(g-1)+f<=a.size,b&=h>=f*Dd[e],b&=null!=a.eb;else{a=d.f.kb,h=(f+1)/2,m=(g+1)/2,k=Math.abs(a.fa);l=Math.abs(a.Ab);var n=Math.abs(a.Db),r=Math.abs(a.lb),q=r*(g-1)+f;b&=k*(g-1)+f<=a.Fd,b&=l*(m-1)+h<=a.Cd,b=(b&=n*(m-1)+h<=a.Ed)&k>=f&l>=h&n>=h,b&=null!=a.y,b&=null!=a.f,b&=null!=a.ea,12==e&&(b&=r>=f,b&=q<=a.Tc,b&=null!=a.F)}else b=0;a=b?0:2}}return 0!=a||null!=c&&c.fd&&(a=Bd(d)),a}var xb=64,Hd=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535,131071,262143,524287,1048575,2097151,4194303,8388607,16777215],Gd=24,ob=32,Xb=8,Id=[0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7];X("Predictor0","PredictorAdd0"),self.Predictor0=function(){return 4278190080},self.Predictor1=function(a){return a},self.Predictor2=function(a,b,c){return b[c+0]},self.Predictor3=function(a,b,c){return b[c+1]},self.Predictor4=function(a,b,c){return b[c-1]},self.Predictor5=function(a,b,c){return aa(aa(a,b[c+1]),b[c+0])},self.Predictor6=function(a,b,c){return aa(a,b[c-1])},self.Predictor7=function(a,b,c){return aa(a,b[c+0])},self.Predictor8=function(a,b,c){return aa(b[c-1],b[c+0])},self.Predictor9=function(a,b,c){return aa(b[c+0],b[c+1])},self.Predictor10=function(a,b,c){return aa(aa(a,b[c-1]),aa(b[c+0],b[c+1]))},self.Predictor11=function(a,b,c){var d=b[c+0];return 0>=Ia(d>>24&255,a>>24&255,(b=b[c-1])>>24&255)+Ia(d>>16&255,a>>16&255,b>>16&255)+Ia(d>>8&255,a>>8&255,b>>8&255)+Ia(255&d,255&a,255&b)?d:a},self.Predictor12=function(a,b,c){var d=b[c+0];return(sa((a>>24&255)+(d>>24&255)-((b=b[c-1])>>24&255))<<24|sa((a>>16&255)+(d>>16&255)-(b>>16&255))<<16|sa((a>>8&255)+(d>>8&255)-(b>>8&255))<<8|sa((255&a)+(255&d)-(255&b)))>>>0},self.Predictor13=function(a,b,c){var d=b[c-1];return(eb((a=aa(a,b[c+0]))>>24&255,d>>24&255)<<24|eb(a>>16&255,d>>16&255)<<16|eb(a>>8&255,d>>8&255)<<8|eb(a>>0&255,d>>0&255))>>>0};var ee=self.PredictorAdd0;self.PredictorAdd1=cc,X("Predictor2","PredictorAdd2"),X("Predictor3","PredictorAdd3"),X("Predictor4","PredictorAdd4"),X("Predictor5","PredictorAdd5"),X("Predictor6","PredictorAdd6"),X("Predictor7","PredictorAdd7"),X("Predictor8","PredictorAdd8"),X("Predictor9","PredictorAdd9"),X("Predictor10","PredictorAdd10"),X("Predictor11","PredictorAdd11"),X("Predictor12","PredictorAdd12"),X("Predictor13","PredictorAdd13");var fe=self.PredictorAdd2;ec("ColorIndexInverseTransform","MapARGB","32b",(function(a){return a>>8&255}),(function(a){return a})),ec("VP8LColorIndexInverseTransformAlpha","MapAlpha","8b",(function(a){return a}),(function(a){return a>>8&255}));var pc,rc=self.ColorIndexInverseTransform,ke=self.MapARGB,he=self.VP8LColorIndexInverseTransformAlpha,le=self.MapAlpha,qc=self.VP8LPredictorsAdd=[];qc.length=16,(self.VP8LPredictors=[]).length=16,(self.VP8LPredictorsAdd_C=[]).length=16,(self.VP8LPredictors_C=[]).length=16;var Fb,sc,Gb,Hb,xc,uc,Nc,Za,fd,Nb,pa,Ob,Xc,Tc,Yc,Uc,Zc,Vc,$c,Wc,Rc,Pc,Sc,Qc,za,vc,fc,Fc,bd=V(511),cd=V(2041),dd=V(225),ed=V(767),ad=0,Qb=cd,mb=dd,R=ed,U=bd,Ca=0,Ua=1,tc=2,Va=3,ya=4,Db=5,wc=6,zb=7,Ab=8,Ja=9,Bb=10,pe=[2,3,7],oe=[3,3,11],Dc=[280,256,256,256,40],qe=[0,1,1,1,0],ne=[17,18,0,1,2,3,4,5,16,6,7,8,9,10,11,12,13,14,15],de=[24,7,23,25,40,6,39,41,22,26,38,42,56,5,55,57,21,27,54,58,37,43,72,4,71,73,20,28,53,59,70,74,36,44,88,69,75,52,60,3,87,89,19,29,86,90,35,45,68,76,85,91,51,61,104,2,103,105,18,30,102,106,34,46,84,92,67,77,101,107,50,62,120,1,119,121,83,93,17,31,100,108,66,78,118,122,33,47,117,123,49,63,99,109,82,94,0,116,124,65,79,16,32,98,110,48,115,125,81,95,64,114,126,97,111,80,113,127,96,112],me=[2954,2956,2958,2962,2970,2986,3018,3082,3212,3468,3980,5004],ie=8,Lb=[4,5,6,7,8,9,10,10,11,12,13,14,15,16,17,17,18,19,20,20,21,21,22,22,23,23,24,25,25,26,27,28,29,30,31,32,33,34,35,36,37,37,38,39,40,41,42,43,44,45,46,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,76,77,78,79,80,81,82,83,84,85,86,87,88,89,91,93,95,96,98,100,101,102,104,106,108,110,112,114,116,118,122,124,126,128,130,132,134,136,138,140,143,145,148,151,154,157],Mb=[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102,104,106,108,110,112,114,116,119,122,125,128,131,134,137,140,143,146,149,152,155,158,161,164,167,170,173,177,181,185,189,193,197,201,205,209,213,217,221,225,229,234,239,245,249,254,259,264,269,274,279,284],oa=null,He=[[173,148,140,0],[176,155,140,135,0],[180,157,141,134,130,0],[254,254,243,230,196,177,153,140,133,130,129,0]],Ie=[0,1,4,8,5,2,3,6,9,12,13,10,7,11,14,15],Mc=[-0,1,-1,2,-2,3,4,6,-3,5,-4,-5,-6,7,-7,8,-8,-9],Fe=[[[[128,128,128,128,128,128,128,128,128,128,128],[128,128,128,128,128,128,128,128,128,128,128],[128,128,128,128,128,128,128,128,128,128,128]],[[253,136,254,255,228,219,128,128,128,128,128],[189,129,242,255,227,213,255,219,128,128,128],[106,126,227,252,214,209,255,255,128,128,128]],[[1,98,248,255,236,226,255,255,128,128,128],[181,133,238,254,221,234,255,154,128,128,128],[78,134,202,247,198,180,255,219,128,128,128]],[[1,185,249,255,243,255,128,128,128,128,128],[184,150,247,255,236,224,128,128,128,128,128],[77,110,216,255,236,230,128,128,128,128,128]],[[1,101,251,255,241,255,128,128,128,128,128],[170,139,241,252,236,209,255,255,128,128,128],[37,116,196,243,228,255,255,255,128,128,128]],[[1,204,254,255,245,255,128,128,128,128,128],[207,160,250,255,238,128,128,128,128,128,128],[102,103,231,255,211,171,128,128,128,128,128]],[[1,152,252,255,240,255,128,128,128,128,128],[177,135,243,255,234,225,128,128,128,128,128],[80,129,211,255,194,224,128,128,128,128,128]],[[1,1,255,128,128,128,128,128,128,128,128],[246,1,255,128,128,128,128,128,128,128,128],[255,128,128,128,128,128,128,128,128,128,128]]],[[[198,35,237,223,193,187,162,160,145,155,62],[131,45,198,221,172,176,220,157,252,221,1],[68,47,146,208,149,167,221,162,255,223,128]],[[1,149,241,255,221,224,255,255,128,128,128],[184,141,234,253,222,220,255,199,128,128,128],[81,99,181,242,176,190,249,202,255,255,128]],[[1,129,232,253,214,197,242,196,255,255,128],[99,121,210,250,201,198,255,202,128,128,128],[23,91,163,242,170,187,247,210,255,255,128]],[[1,200,246,255,234,255,128,128,128,128,128],[109,178,241,255,231,245,255,255,128,128,128],[44,130,201,253,205,192,255,255,128,128,128]],[[1,132,239,251,219,209,255,165,128,128,128],[94,136,225,251,218,190,255,255,128,128,128],[22,100,174,245,186,161,255,199,128,128,128]],[[1,182,249,255,232,235,128,128,128,128,128],[124,143,241,255,227,234,128,128,128,128,128],[35,77,181,251,193,211,255,205,128,128,128]],[[1,157,247,255,236,231,255,255,128,128,128],[121,141,235,255,225,227,255,255,128,128,128],[45,99,188,251,195,217,255,224,128,128,128]],[[1,1,251,255,213,255,128,128,128,128,128],[203,1,248,255,255,128,128,128,128,128,128],[137,1,177,255,224,255,128,128,128,128,128]]],[[[253,9,248,251,207,208,255,192,128,128,128],[175,13,224,243,193,185,249,198,255,255,128],[73,17,171,221,161,179,236,167,255,234,128]],[[1,95,247,253,212,183,255,255,128,128,128],[239,90,244,250,211,209,255,255,128,128,128],[155,77,195,248,188,195,255,255,128,128,128]],[[1,24,239,251,218,219,255,205,128,128,128],[201,51,219,255,196,186,128,128,128,128,128],[69,46,190,239,201,218,255,228,128,128,128]],[[1,191,251,255,255,128,128,128,128,128,128],[223,165,249,255,213,255,128,128,128,128,128],[141,124,248,255,255,128,128,128,128,128,128]],[[1,16,248,255,255,128,128,128,128,128,128],[190,36,230,255,236,255,128,128,128,128,128],[149,1,255,128,128,128,128,128,128,128,128]],[[1,226,255,128,128,128,128,128,128,128,128],[247,192,255,128,128,128,128,128,128,128,128],[240,128,255,128,128,128,128,128,128,128,128]],[[1,134,252,255,255,128,128,128,128,128,128],[213,62,250,255,255,128,128,128,128,128,128],[55,93,255,128,128,128,128,128,128,128,128]],[[128,128,128,128,128,128,128,128,128,128,128],[128,128,128,128,128,128,128,128,128,128,128],[128,128,128,128,128,128,128,128,128,128,128]]],[[[202,24,213,235,186,191,220,160,240,175,255],[126,38,182,232,169,184,228,174,255,187,128],[61,46,138,219,151,178,240,170,255,216,128]],[[1,112,230,250,199,191,247,159,255,255,128],[166,109,228,252,211,215,255,174,128,128,128],[39,77,162,232,172,180,245,178,255,255,128]],[[1,52,220,246,198,199,249,220,255,255,128],[124,74,191,243,183,193,250,221,255,255,128],[24,71,130,219,154,170,243,182,255,255,128]],[[1,182,225,249,219,240,255,224,128,128,128],[149,150,226,252,216,205,255,171,128,128,128],[28,108,170,242,183,194,254,223,255,255,128]],[[1,81,230,252,204,203,255,192,128,128,128],[123,102,209,247,188,196,255,233,128,128,128],[20,95,153,243,164,173,255,203,128,128,128]],[[1,222,248,255,216,213,128,128,128,128,128],[168,175,246,252,235,205,255,255,128,128,128],[47,116,215,255,211,212,255,255,128,128,128]],[[1,121,236,253,212,214,255,255,128,128,128],[141,84,213,252,201,202,255,219,128,128,128],[42,80,160,240,162,185,255,205,128,128,128]],[[1,1,255,128,128,128,128,128,128,128,128],[244,1,255,128,128,128,128,128,128,128,128],[238,1,255,128,128,128,128,128,128,128,128]]]],Ke=[[[231,120,48,89,115,113,120,152,112],[152,179,64,126,170,118,46,70,95],[175,69,143,80,85,82,72,155,103],[56,58,10,171,218,189,17,13,152],[114,26,17,163,44,195,21,10,173],[121,24,80,195,26,62,44,64,85],[144,71,10,38,171,213,144,34,26],[170,46,55,19,136,160,33,206,71],[63,20,8,114,114,208,12,9,226],[81,40,11,96,182,84,29,16,36]],[[134,183,89,137,98,101,106,165,148],[72,187,100,130,157,111,32,75,80],[66,102,167,99,74,62,40,234,128],[41,53,9,178,241,141,26,8,107],[74,43,26,146,73,166,49,23,157],[65,38,105,160,51,52,31,115,128],[104,79,12,27,217,255,87,17,7],[87,68,71,44,114,51,15,186,23],[47,41,14,110,182,183,21,17,194],[66,45,25,102,197,189,23,18,22]],[[88,88,147,150,42,46,45,196,205],[43,97,183,117,85,38,35,179,61],[39,53,200,87,26,21,43,232,171],[56,34,51,104,114,102,29,93,77],[39,28,85,171,58,165,90,98,64],[34,22,116,206,23,34,43,166,73],[107,54,32,26,51,1,81,43,31],[68,25,106,22,64,171,36,225,114],[34,19,21,102,132,188,16,76,124],[62,18,78,95,85,57,50,48,51]],[[193,101,35,159,215,111,89,46,111],[60,148,31,172,219,228,21,18,111],[112,113,77,85,179,255,38,120,114],[40,42,1,196,245,209,10,25,109],[88,43,29,140,166,213,37,43,154],[61,63,30,155,67,45,68,1,209],[100,80,8,43,154,1,51,26,71],[142,78,78,16,255,128,34,197,171],[41,40,5,102,211,183,4,1,221],[51,50,17,168,209,192,23,25,82]],[[138,31,36,171,27,166,38,44,229],[67,87,58,169,82,115,26,59,179],[63,59,90,180,59,166,93,73,154],[40,40,21,116,143,209,34,39,175],[47,15,16,183,34,223,49,45,183],[46,17,33,183,6,98,15,32,183],[57,46,22,24,128,1,54,17,37],[65,32,73,115,28,128,23,128,205],[40,3,9,115,51,192,18,6,223],[87,37,9,115,59,77,64,21,47]],[[104,55,44,218,9,54,53,130,226],[64,90,70,205,40,41,23,26,57],[54,57,112,184,5,41,38,166,213],[30,34,26,133,152,116,10,32,134],[39,19,53,221,26,114,32,73,255],[31,9,65,234,2,15,1,118,73],[75,32,12,51,192,255,160,43,51],[88,31,35,67,102,85,55,186,85],[56,21,23,111,59,205,45,37,192],[55,38,70,124,73,102,1,34,98]],[[125,98,42,88,104,85,117,175,82],[95,84,53,89,128,100,113,101,45],[75,79,123,47,51,128,81,171,1],[57,17,5,71,102,57,53,41,49],[38,33,13,121,57,73,26,1,85],[41,10,67,138,77,110,90,47,114],[115,21,2,10,102,255,166,23,6],[101,29,16,10,85,128,101,196,26],[57,18,10,102,102,213,34,20,43],[117,20,15,36,163,128,68,1,26]],[[102,61,71,37,34,53,31,243,192],[69,60,71,38,73,119,28,222,37],[68,45,128,34,1,47,11,245,171],[62,17,19,70,146,85,55,62,70],[37,43,37,154,100,163,85,160,1],[63,9,92,136,28,64,32,201,85],[75,15,9,9,64,255,184,119,16],[86,6,28,5,64,255,25,248,1],[56,8,17,132,137,255,55,116,128],[58,15,20,82,135,57,26,121,40]],[[164,50,31,137,154,133,25,35,218],[51,103,44,131,131,123,31,6,158],[86,40,64,135,148,224,45,183,128],[22,26,17,131,240,154,14,1,209],[45,16,21,91,64,222,7,1,197],[56,21,39,155,60,138,23,102,213],[83,12,13,54,192,255,68,47,28],[85,26,85,85,128,128,32,146,171],[18,11,7,63,144,171,4,4,246],[35,27,10,146,174,171,12,26,128]],[[190,80,35,99,180,80,126,54,45],[85,126,47,87,176,51,41,20,32],[101,75,128,139,118,146,116,128,85],[56,41,15,176,236,85,37,9,62],[71,30,17,119,118,255,17,18,138],[101,38,60,138,55,70,43,26,142],[146,36,19,30,171,255,97,27,20],[138,45,61,62,219,1,81,188,64],[32,41,20,117,151,142,20,21,163],[112,19,12,61,195,128,48,4,24]]],Ee=[[[[255,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]],[[176,246,255,255,255,255,255,255,255,255,255],[223,241,252,255,255,255,255,255,255,255,255],[249,253,253,255,255,255,255,255,255,255,255]],[[255,244,252,255,255,255,255,255,255,255,255],[234,254,254,255,255,255,255,255,255,255,255],[253,255,255,255,255,255,255,255,255,255,255]],[[255,246,254,255,255,255,255,255,255,255,255],[239,253,254,255,255,255,255,255,255,255,255],[254,255,254,255,255,255,255,255,255,255,255]],[[255,248,254,255,255,255,255,255,255,255,255],[251,255,254,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]],[[255,253,254,255,255,255,255,255,255,255,255],[251,254,254,255,255,255,255,255,255,255,255],[254,255,254,255,255,255,255,255,255,255,255]],[[255,254,253,255,254,255,255,255,255,255,255],[250,255,254,255,254,255,255,255,255,255,255],[254,255,255,255,255,255,255,255,255,255,255]],[[255,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]]],[[[217,255,255,255,255,255,255,255,255,255,255],[225,252,241,253,255,255,254,255,255,255,255],[234,250,241,250,253,255,253,254,255,255,255]],[[255,254,255,255,255,255,255,255,255,255,255],[223,254,254,255,255,255,255,255,255,255,255],[238,253,254,254,255,255,255,255,255,255,255]],[[255,248,254,255,255,255,255,255,255,255,255],[249,254,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]],[[255,253,255,255,255,255,255,255,255,255,255],[247,254,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]],[[255,253,254,255,255,255,255,255,255,255,255],[252,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]],[[255,254,254,255,255,255,255,255,255,255,255],[253,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]],[[255,254,253,255,255,255,255,255,255,255,255],[250,255,255,255,255,255,255,255,255,255,255],[254,255,255,255,255,255,255,255,255,255,255]],[[255,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]]],[[[186,251,250,255,255,255,255,255,255,255,255],[234,251,244,254,255,255,255,255,255,255,255],[251,251,243,253,254,255,254,255,255,255,255]],[[255,253,254,255,255,255,255,255,255,255,255],[236,253,254,255,255,255,255,255,255,255,255],[251,253,253,254,254,255,255,255,255,255,255]],[[255,254,254,255,255,255,255,255,255,255,255],[254,254,254,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]],[[255,254,255,255,255,255,255,255,255,255,255],[254,254,255,255,255,255,255,255,255,255,255],[254,255,255,255,255,255,255,255,255,255,255]],[[255,255,255,255,255,255,255,255,255,255,255],[254,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]],[[255,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]],[[255,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]],[[255,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]]],[[[248,255,255,255,255,255,255,255,255,255,255],[250,254,252,254,255,255,255,255,255,255,255],[248,254,249,253,255,255,255,255,255,255,255]],[[255,253,253,255,255,255,255,255,255,255,255],[246,253,253,255,255,255,255,255,255,255,255],[252,254,251,254,254,255,255,255,255,255,255]],[[255,254,252,255,255,255,255,255,255,255,255],[248,254,253,255,255,255,255,255,255,255,255],[253,255,254,254,255,255,255,255,255,255,255]],[[255,251,254,255,255,255,255,255,255,255,255],[245,251,254,255,255,255,255,255,255,255,255],[253,253,254,255,255,255,255,255,255,255,255]],[[255,251,253,255,255,255,255,255,255,255,255],[252,253,254,255,255,255,255,255,255,255,255],[255,254,255,255,255,255,255,255,255,255,255]],[[255,252,255,255,255,255,255,255,255,255,255],[249,255,254,255,255,255,255,255,255,255,255],[255,255,254,255,255,255,255,255,255,255,255]],[[255,255,253,255,255,255,255,255,255,255,255],[250,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]],[[255,255,255,255,255,255,255,255,255,255,255],[254,255,255,255,255,255,255,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255]]]],Ge=[0,1,2,3,6,4,5,6,6,6,6,6,6,6,6,7,0],Y=[],W=[],ka=[],re=1,Cc=2,ia=[],P=[];va("UpsampleRgbLinePair",Ga,3),va("UpsampleBgrLinePair",Tb,3),va("UpsampleRgbaLinePair",wd,4),va("UpsampleBgraLinePair",vd,4),va("UpsampleArgbLinePair",ud,4),va("UpsampleRgba4444LinePair",td,2),va("UpsampleRgb565LinePair",sd,2);var Mf=self.UpsampleRgbLinePair,Nf=self.UpsampleBgrLinePair,nd=self.UpsampleRgbaLinePair,od=self.UpsampleBgraLinePair,pd=self.UpsampleArgbLinePair,qd=self.UpsampleRgba4444LinePair,Of=self.UpsampleRgb565LinePair,Wa=16,Ba=1<<Wa-1,ta=-227,Eb=482,rd=6,Pf=(256<<rd)-1,jc=0,Yd=V(256),ae=V(256),$d=V(256),Zd=V(256),be=V(Eb-ta),ce=V(Eb-ta);la("YuvToRgbRow",Ga,3),la("YuvToBgrRow",Tb,3),la("YuvToRgbaRow",wd,4),la("YuvToBgraRow",vd,4),la("YuvToArgbRow",ud,4),la("YuvToRgba4444Row",td,2),la("YuvToRgb565Row",sd,2);var zd=[0,4,8,12,128,132,136,140,256,260,264,268,384,388,392,396],Ya=[0,2,8],Qf=[8,7,6,4,4,2,2,2,1,1,1,1],Ne=1;this.WebPDecodeRGBA=function(a,b,c,d,e){var f=Ua,g=new Cf,h=new Cb;g.ba=h,h.S=f,h.width=[h.width],h.height=[h.height];var k=h.width,l=h.height,m=new Td;if(null==m||null==a)var n=2;else x(null!=m),n=Ad(a,b,c,m.width,m.height,m.Pd,m.Qd,m.format,null);if(0!=n?k=0:(null!=k&&(k[0]=m.width[0]),null!=l&&(l[0]=m.height[0]),k=1),k){h.width=h.width[0],h.height=h.height[0],null!=d&&(d[0]=h.width),null!=e&&(e[0]=h.height);b:{if(d=new Oa,(e=new md).data=a,e.w=b,e.ha=c,e.kd=1,b=[0],x(null!=e),(0==(a=Ad(e.data,e.w,e.ha,null,null,null,b,null,e))||7==a)&&b[0]&&(a=4),0==(b=a)){if(x(null!=g),d.data=e.data,d.w=e.w+e.offset,d.ha=e.ha-e.offset,d.put=kc,d.ac=gc,d.bc=lc,d.ma=g,e.xa){if(null==(a=Bc())){g=1;break b}if(function(a,b){var c=[0],d=[0],e=[0];a:for(;;){if(null==a)return 0;if(null==b)return a.a=2,0;if(a.l=b,a.a=0,cb(a.m,b.data,b.w,b.ha),!mc(a.m,c,d,e)){a.a=3;break a}if(a.xb=Cc,b.width=c[0],b.height=d[0],!rb(c[0],d[0],1,a,null))break a;return 1}return x(0!=a.a),0}(a,d)){if(d=0==(b=Cd(d.width,d.height,g.Oa,g.ba))){c:{d=a;d:for(;;){if(null==d){d=0;break c}if(x(null!=d.s.yc),x(null!=d.s.Ya),x(0<d.s.Wb),x(null!=(c=d.l)),x(null!=(e=c.ma)),0!=d.xb){if(d.ca=e.ba,d.tb=e.tb,x(null!=d.ca),!hc(e.Oa,c,Va)){d.a=2;break d}if(!Ec(d,c.width))break d;if(c.da)break d;if((c.da||hb(d.ca.S))&&Aa(),11>d.ca.S||(alert("todo:WebPInitConvertARGBToYUV"),null!=d.ca.f.kb.F&&Aa()),d.Pb&&0<d.s.ua&&null==d.s.vb.X&&!Zb(d.s.vb,d.s.Wa.Xa)){d.a=1;break d}d.xb=0}if(!Jb(d,d.V,d.Ba,d.c,d.i,c.o,ge))break d;e.Dc=d.Ma,d=1;break c}x(0!=d.a),d=0}d=!d}d&&(b=a.a)}else b=a.a}else{if(null==(a=new Ce)){g=1;break b}if(a.Fa=e.na,a.P=e.P,a.qc=e.Sa,Kc(a,d)){if(0==(b=Cd(d.width,d.height,g.Oa,g.ba))){if(a.Aa=0,c=g.Oa,x(null!=(e=a)),null!=c){if(0<(k=0>(k=c.Md)?0:100<k?255:255*k/100)){for(l=m=0;4>l;++l)12>(n=e.pb[l]).lc&&(n.ia=k*Qf[0>n.lc?0:n.lc]>>3),m|=n.ia;m&&(alert("todo:VP8InitRandom"),e.ia=1)}e.Ga=c.Id,100<e.Ga?e.Ga=100:0>e.Ga&&(e.Ga=0)}Me(a,d)||(b=a.a)}}else b=a.a}0==b&&null!=g.Oa&&g.Oa.fd&&(b=Bd(g.ba))}g=b}f=0!=g?null:11>f?h.f.RGBA.eb:h.f.kb.y}else f=null;return f};var Dd=[3,4,3,4,4,2,2,4,4,4,2,1,1]};function GetTag(data,data_off){for(var str="",i=0;i<4;i++)str+=String.fromCharCode(data[data_off++]);return str}function GetLE24(data,data_off){return(data[data_off+0]<<0|data[data_off+1]<<8|data[data_off+2]<<16)>>>0}function GetLE32(data,data_off){return(data[data_off+0]<<0|data[data_off+1]<<8|data[data_off+2]<<16|data[data_off+3]<<24)>>>0}new _WebPDecoder;var height=[0],width=[0],pixels=[],webpdecoder=new _WebPDecoder,response=imageData,imagearray=function(src,src_off){var imagearray={},i=0,alpha_chunk=!1,alpha_size=0,alpha_offset=0;if(imagearray.frames=[],!
+/** @license
+     * Copyright (c) 2017 Dominik Homberger
+    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+    https://webpjs.appspot.com
+    WebPRiffParser dominikhlbg@gmail.com
+    */
+function(data,data_off,str,size){for(var i=0;i<size;i++)if(data[data_off+i]!=str.charCodeAt(i))return!0;return!1}(src,src_off,"RIFF",4)){var data,data_off;GetLE32(src,src_off+=4);for(src_off+=8;src_off<src.length;){var fourcc=GetTag(src,src_off),payload_size=GetLE32(src,src_off+=4);src_off+=4;var payload_size_padded=payload_size+(1&payload_size);switch(fourcc){case"VP8 ":case"VP8L":void 0===imagearray.frames[i]&&(imagearray.frames[i]={});(obj=imagearray.frames[i]).src_off=alpha_chunk?alpha_offset:src_off-8,obj.src_size=alpha_size+payload_size+8,i++,alpha_chunk&&(alpha_chunk=!1,alpha_size=0,alpha_offset=0);break;case"VP8X":(obj=imagearray.header={}).feature_flags=src[src_off];var src_off_=src_off+4;obj.canvas_width=1+GetLE24(src,src_off_);src_off_+=3;obj.canvas_height=1+GetLE24(src,src_off_);src_off_+=3;break;case"ALPH":alpha_chunk=!0,alpha_size=payload_size_padded+8,alpha_offset=src_off-8;break;case"ANIM":(obj=imagearray.header).bgcolor=GetLE32(src,src_off);src_off_=src_off+4;obj.loop_count=(data=src)[(data_off=src_off_)+0]<<0|data[data_off+1]<<8;src_off_+=2;break;case"ANMF":var temp,obj;(obj=imagearray.frames[i]={}).offset_x=2*GetLE24(src,src_off),src_off+=3,obj.offset_y=2*GetLE24(src,src_off),src_off+=3,obj.width=1+GetLE24(src,src_off),src_off+=3,obj.height=1+GetLE24(src,src_off),src_off+=3,obj.duration=GetLE24(src,src_off),src_off+=3,temp=src[src_off++],obj.dispose=1&temp,obj.blend=temp>>1&1}"ANMF"!=fourcc&&(src_off+=payload_size_padded)}return imagearray}}(response,0);imagearray.response=response,imagearray.rgbaoutput=!0,imagearray.dataurl=!1;var header=imagearray.header?imagearray.header:null,frames=imagearray.frames?imagearray.frames:null;if(header){header.loop_counter=header.loop_count,height=[header.canvas_height],width=[header.canvas_width];for(var f=0;f<frames.length&&0!=frames[f].blend;f++);}var frame=frames[0],rgba=webpdecoder.WebPDecodeRGBA(response,frame.src_off,frame.src_size,width,height);frame.rgba=rgba,frame.imgwidth=width[0],frame.imgheight=height[0];for(var i=0;i<width[0]*height[0]*4;i++)pixels[i]=rgba[i];return this.width=width,this.height=height,this.data=pixels,this}!function(jsPDFAPI){var hasCompressionJS=function(){return!0},compressBytes=function(bytes,lineLength,colorsPerPixel,compression){var level=4,filter_method=filterUp;switch(compression){case jsPDFAPI.image_compression.FAST:level=1,filter_method=filterSub;break;case jsPDFAPI.image_compression.MEDIUM:level=6,filter_method=filterAverage;break;case jsPDFAPI.image_compression.SLOW:level=9,filter_method=filterPaeth}var dat=zlibSync(bytes=applyPngFilterMethod(bytes,lineLength,colorsPerPixel,filter_method),{level:level});return jsPDFAPI.__addimage__.arrayBufferToBinaryString(dat)},applyPngFilterMethod=function(bytes,lineLength,colorsPerPixel,filter_method){for(var line,prevLine,offset,lines=bytes.length/lineLength,result=new Uint8Array(bytes.length+lines),filter_methods=getFilterMethods(),i=0;i<lines;i+=1){if(offset=i*lineLength,line=bytes.subarray(offset,offset+lineLength),filter_method)result.set(filter_method(line,colorsPerPixel,prevLine),offset+i);else{for(var j,len=filter_methods.length,results=[];j<len;j+=1)results[j]=filter_methods[j](line,colorsPerPixel,prevLine);var ind=getIndexOfSmallestSum(results.concat());result.set(results[ind],offset+i)}prevLine=line}return result},filterNone=function(line){var result=Array.apply([],line);return result.unshift(0),result},filterSub=function(line,colorsPerPixel){var left,result=[],len=line.length;result[0]=1;for(var i=0;i<len;i+=1)left=line[i-colorsPerPixel]||0,result[i+1]=line[i]-left+256&255;return result},filterUp=function(line,colorsPerPixel,prevLine){var up,result=[],len=line.length;result[0]=2;for(var i=0;i<len;i+=1)up=prevLine&&prevLine[i]||0,result[i+1]=line[i]-up+256&255;return result},filterAverage=function(line,colorsPerPixel,prevLine){var left,up,result=[],len=line.length;result[0]=3;for(var i=0;i<len;i+=1)left=line[i-colorsPerPixel]||0,up=prevLine&&prevLine[i]||0,result[i+1]=line[i]+256-(left+up>>>1)&255;return result},filterPaeth=function(line,colorsPerPixel,prevLine){var left,up,upLeft,paeth,result=[],len=line.length;result[0]=4;for(var i=0;i<len;i+=1)left=line[i-colorsPerPixel]||0,up=prevLine&&prevLine[i]||0,upLeft=prevLine&&prevLine[i-colorsPerPixel]||0,paeth=paethPredictor(left,up,upLeft),result[i+1]=line[i]-paeth+256&255;return result},paethPredictor=function(left,up,upLeft){if(left===up&&up===upLeft)return left;var pLeft=Math.abs(up-upLeft),pUp=Math.abs(left-upLeft),pUpLeft=Math.abs(left+up-upLeft-upLeft);return pLeft<=pUp&&pLeft<=pUpLeft?left:pUp<=pUpLeft?up:upLeft},getFilterMethods=function(){return[filterNone,filterSub,filterUp,filterAverage,filterPaeth]},getIndexOfSmallestSum=function(arrays){var sum=arrays.map((function(value){return value.reduce((function(pv,cv){return pv+Math.abs(cv)}),0)}));return sum.indexOf(Math.min.apply(null,sum))};jsPDFAPI.processPNG=function(imageData,index,alias,compression){var colorSpace,bitsPerComponent,image,trns,colors,pal,smask,pixels,len,alphaData,imgData,hasColors,pixel,i,n,filter=this.decode.FLATE_DECODE,decodeParameters="";if(this.__addimage__.isArrayBuffer(imageData)&&(imageData=new Uint8Array(imageData)),this.__addimage__.isArrayBufferView(imageData)){if(imageData=(image=new PNG(imageData)).imgData,bitsPerComponent=image.bits,colorSpace=image.colorSpace,colors=image.colors,-1!==[4,6].indexOf(image.colorType)){if(8===image.bits){len=(pixels=32==image.pixelBitlength?new Uint32Array(image.decodePixels().buffer):16==image.pixelBitlength?new Uint16Array(image.decodePixels().buffer):new Uint8Array(image.decodePixels().buffer)).length,imgData=new Uint8Array(len*image.colors),alphaData=new Uint8Array(len);var pbl,pDiff=image.pixelBitlength-image.bits;for(i=0,n=0;i<len;i++){for(pixel=pixels[i],pbl=0;pbl<pDiff;)imgData[n++]=pixel>>>pbl&255,pbl+=image.bits;alphaData[i]=pixel>>>pbl&255}}if(16===image.bits){len=(pixels=new Uint32Array(image.decodePixels().buffer)).length,imgData=new Uint8Array(len*(32/image.pixelBitlength)*image.colors),alphaData=new Uint8Array(len*(32/image.pixelBitlength)),hasColors=image.colors>1,i=0,n=0;for(var a=0;i<len;)pixel=pixels[i++],imgData[n++]=pixel>>>0&255,hasColors&&(imgData[n++]=pixel>>>16&255,pixel=pixels[i++],imgData[n++]=pixel>>>0&255),alphaData[a++]=pixel>>>16&255;bitsPerComponent=8}compression!==jsPDFAPI.image_compression.NONE&&hasCompressionJS()?(imageData=compressBytes(imgData,image.width*image.colors,image.colors,compression),smask=compressBytes(alphaData,image.width,1,compression)):(imageData=imgData,smask=alphaData,filter=void 0)}if(3===image.colorType&&(colorSpace=this.color_spaces.INDEXED,pal=image.palette,image.transparency.indexed)){var trans=image.transparency.indexed,total=0;for(i=0,len=trans.length;i<len;++i)total+=trans[i];if((total/=255)===len-1&&-1!==trans.indexOf(0))trns=[trans.indexOf(0)];else if(total!==len){for(pixels=image.decodePixels(),alphaData=new Uint8Array(pixels.length),i=0,len=pixels.length;i<len;i++)alphaData[i]=trans[pixels[i]];smask=compressBytes(alphaData,image.width,1)}}var predictor=function(compression){var predictor;switch(compression){case jsPDFAPI.image_compression.FAST:predictor=11;break;case jsPDFAPI.image_compression.MEDIUM:predictor=13;break;case jsPDFAPI.image_compression.SLOW:predictor=14;break;default:predictor=12}return predictor}(compression);return filter===this.decode.FLATE_DECODE&&(decodeParameters="/Predictor "+predictor+" "),decodeParameters+="/Colors "+colors+" /BitsPerComponent "+bitsPerComponent+" /Columns "+image.width,(this.__addimage__.isArrayBuffer(imageData)||this.__addimage__.isArrayBufferView(imageData))&&(imageData=this.__addimage__.arrayBufferToBinaryString(imageData)),(smask&&this.__addimage__.isArrayBuffer(smask)||this.__addimage__.isArrayBufferView(smask))&&(smask=this.__addimage__.arrayBufferToBinaryString(smask)),{alias:alias,data:imageData,index:index,filter:filter,decodeParameters:decodeParameters,transparency:trns,palette:pal,sMask:smask,predictor:predictor,width:image.width,height:image.height,bitsPerComponent:bitsPerComponent,colorSpace:colorSpace}}}}(jsPDF.API),function(jsPDFAPI){jsPDFAPI.processGIF89A=function(imageData,index,alias,compression){var reader=new GifReader(imageData),width=reader.width,height=reader.height,pixels=[];reader.decodeAndBlitFrameRGBA(0,pixels);var rawImageData={data:pixels,width:width,height:height},data=new JPEGEncoder(100).encode(rawImageData,100);return jsPDFAPI.processJPEG.call(this,data,index,alias,compression)},jsPDFAPI.processGIF87A=jsPDFAPI.processGIF89A}(jsPDF.API),BmpDecoder.prototype.parseHeader=function(){if(this.fileSize=this.datav.getUint32(this.pos,!0),this.pos+=4,this.reserved=this.datav.getUint32(this.pos,!0),this.pos+=4,this.offset=this.datav.getUint32(this.pos,!0),this.pos+=4,this.headerSize=this.datav.getUint32(this.pos,!0),this.pos+=4,this.width=this.datav.getUint32(this.pos,!0),this.pos+=4,this.height=this.datav.getInt32(this.pos,!0),this.pos+=4,this.planes=this.datav.getUint16(this.pos,!0),this.pos+=2,this.bitPP=this.datav.getUint16(this.pos,!0),this.pos+=2,this.compress=this.datav.getUint32(this.pos,!0),this.pos+=4,this.rawSize=this.datav.getUint32(this.pos,!0),this.pos+=4,this.hr=this.datav.getUint32(this.pos,!0),this.pos+=4,this.vr=this.datav.getUint32(this.pos,!0),this.pos+=4,this.colors=this.datav.getUint32(this.pos,!0),this.pos+=4,this.importantColors=this.datav.getUint32(this.pos,!0),this.pos+=4,16===this.bitPP&&this.is_with_alpha&&(this.bitPP=15),this.bitPP<15){var len=0===this.colors?1<<this.bitPP:this.colors;this.palette=new Array(len);for(var i=0;i<len;i++){var blue=this.datav.getUint8(this.pos++,!0),green=this.datav.getUint8(this.pos++,!0),red=this.datav.getUint8(this.pos++,!0),quad=this.datav.getUint8(this.pos++,!0);this.palette[i]={red:red,green:green,blue:blue,quad:quad}}}this.height<0&&(this.height*=-1,this.bottom_up=!1)},BmpDecoder.prototype.parseBGR=function(){this.pos=this.offset;try{var bitn="bit"+this.bitPP,len=this.width*this.height*4;this.data=new Uint8Array(len),this[bitn]()}catch(e){console.log("bit decode error:"+e)}},BmpDecoder.prototype.bit1=function(){var y,xlen=Math.ceil(this.width/8),mode=xlen%4;for(y=this.height-1;y>=0;y--){for(var line=this.bottom_up?y:this.height-1-y,x=0;x<xlen;x++)for(var b=this.datav.getUint8(this.pos++,!0),location=line*this.width*4+8*x*4,i=0;i<8&&8*x+i<this.width;i++){var rgb=this.palette[b>>7-i&1];this.data[location+4*i]=rgb.blue,this.data[location+4*i+1]=rgb.green,this.data[location+4*i+2]=rgb.red,this.data[location+4*i+3]=255}0!==mode&&(this.pos+=4-mode)}},BmpDecoder.prototype.bit4=function(){for(var xlen=Math.ceil(this.width/2),mode=xlen%4,y=this.height-1;y>=0;y--){for(var line=this.bottom_up?y:this.height-1-y,x=0;x<xlen;x++){var b=this.datav.getUint8(this.pos++,!0),location=line*this.width*4+2*x*4,before=b>>4,after=15&b,rgb=this.palette[before];if(this.data[location]=rgb.blue,this.data[location+1]=rgb.green,this.data[location+2]=rgb.red,this.data[location+3]=255,2*x+1>=this.width)break;rgb=this.palette[after],this.data[location+4]=rgb.blue,this.data[location+4+1]=rgb.green,this.data[location+4+2]=rgb.red,this.data[location+4+3]=255}0!==mode&&(this.pos+=4-mode)}},BmpDecoder.prototype.bit8=function(){for(var mode=this.width%4,y=this.height-1;y>=0;y--){for(var line=this.bottom_up?y:this.height-1-y,x=0;x<this.width;x++){var b=this.datav.getUint8(this.pos++,!0),location=line*this.width*4+4*x;if(b<this.palette.length){var rgb=this.palette[b];this.data[location]=rgb.red,this.data[location+1]=rgb.green,this.data[location+2]=rgb.blue,this.data[location+3]=255}else this.data[location]=255,this.data[location+1]=255,this.data[location+2]=255,this.data[location+3]=255}0!==mode&&(this.pos+=4-mode)}},BmpDecoder.prototype.bit15=function(){for(var dif_w=this.width%3,_1_5=parseInt("11111",2),y=this.height-1;y>=0;y--){for(var line=this.bottom_up?y:this.height-1-y,x=0;x<this.width;x++){var B=this.datav.getUint16(this.pos,!0);this.pos+=2;var blue=(B&_1_5)/_1_5*255|0,green=(B>>5&_1_5)/_1_5*255|0,red=(B>>10&_1_5)/_1_5*255|0,alpha=B>>15?255:0,location=line*this.width*4+4*x;this.data[location]=red,this.data[location+1]=green,this.data[location+2]=blue,this.data[location+3]=alpha}this.pos+=dif_w}},BmpDecoder.prototype.bit16=function(){for(var dif_w=this.width%3,_1_5=parseInt("11111",2),_1_6=parseInt("111111",2),y=this.height-1;y>=0;y--){for(var line=this.bottom_up?y:this.height-1-y,x=0;x<this.width;x++){var B=this.datav.getUint16(this.pos,!0);this.pos+=2;var blue=(B&_1_5)/_1_5*255|0,green=(B>>5&_1_6)/_1_6*255|0,red=(B>>11)/_1_5*255|0,location=line*this.width*4+4*x;this.data[location]=red,this.data[location+1]=green,this.data[location+2]=blue,this.data[location+3]=255}this.pos+=dif_w}},BmpDecoder.prototype.bit24=function(){for(var y=this.height-1;y>=0;y--){for(var line=this.bottom_up?y:this.height-1-y,x=0;x<this.width;x++){var blue=this.datav.getUint8(this.pos++,!0),green=this.datav.getUint8(this.pos++,!0),red=this.datav.getUint8(this.pos++,!0),location=line*this.width*4+4*x;this.data[location]=red,this.data[location+1]=green,this.data[location+2]=blue,this.data[location+3]=255}this.pos+=this.width%4}},BmpDecoder.prototype.bit32=function(){for(var y=this.height-1;y>=0;y--)for(var line=this.bottom_up?y:this.height-1-y,x=0;x<this.width;x++){var blue=this.datav.getUint8(this.pos++,!0),green=this.datav.getUint8(this.pos++,!0),red=this.datav.getUint8(this.pos++,!0),alpha=this.datav.getUint8(this.pos++,!0),location=line*this.width*4+4*x;this.data[location]=red,this.data[location+1]=green,this.data[location+2]=blue,this.data[location+3]=alpha}},BmpDecoder.prototype.getData=function(){return this.data},
+/**
+   * @license
+   * Copyright (c) 2018 Aras Abbasi
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+function(jsPDFAPI){jsPDFAPI.processBMP=function(imageData,index,alias,compression){var reader=new BmpDecoder(imageData,!1),width=reader.width,height=reader.height,rawImageData={data:reader.getData(),width:width,height:height},data=new JPEGEncoder(100).encode(rawImageData,100);return jsPDFAPI.processJPEG.call(this,data,index,alias,compression)}}(jsPDF.API),WebPDecoder.prototype.getData=function(){return this.data},
+/**
+   * @license
+   * Copyright (c) 2019 Aras Abbasi
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+function(jsPDFAPI){jsPDFAPI.processWEBP=function(imageData,index,alias,compression){var reader=new WebPDecoder(imageData,!1),width=reader.width,height=reader.height,rawImageData={data:reader.getData(),width:width,height:height},data=new JPEGEncoder(100).encode(rawImageData,100);return jsPDFAPI.processJPEG.call(this,data,index,alias,compression)}}(jsPDF.API),
+/**
+   * @license
+   *
+   * Copyright (c) 2021 Antti Palola, https://github.com/Pantura
+   *
+   * Permission is hereby granted, free of charge, to any person obtaining
+   * a copy of this software and associated documentation files (the
+   * "Software"), to deal in the Software without restriction, including
+   * without limitation the rights to use, copy, modify, merge, publish,
+   * distribute, sublicense, and/or sell copies of the Software, and to
+   * permit persons to whom the Software is furnished to do so, subject to
+   * the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be
+   * included in all copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+   * ====================================================================
+   */
+function(jsPDFAPI){jsPDFAPI.processRGBA=function(imageData,index,alias){for(var imagePixels=imageData.data,length=imagePixels.length,rgbOut=new Uint8Array(length/4*3),alphaOut=new Uint8Array(length/4),outIndex=0,alphaIndex=0,i=0;i<length;i+=4){var r=imagePixels[i],g=imagePixels[i+1],b=imagePixels[i+2],alpha=imagePixels[i+3];rgbOut[outIndex++]=r,rgbOut[outIndex++]=g,rgbOut[outIndex++]=b,alphaOut[alphaIndex++]=alpha}var rgbData=this.__addimage__.arrayBufferToBinaryString(rgbOut);return{alpha:this.__addimage__.arrayBufferToBinaryString(alphaOut),data:rgbData,index:index,alias:alias,colorSpace:"DeviceRGB",bitsPerComponent:8,width:imageData.width,height:imageData.height}}}(jsPDF.API),
+/**
+   * @license
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+function(jsPDFAPI){jsPDFAPI.setLanguage=function(langCode){return void 0===this.internal.languageSettings&&(this.internal.languageSettings={},this.internal.languageSettings.isSubscribed=!1),void 0!=={af:"Afrikaans",sq:"Albanian",ar:"Arabic (Standard)","ar-DZ":"Arabic (Algeria)","ar-BH":"Arabic (Bahrain)","ar-EG":"Arabic (Egypt)","ar-IQ":"Arabic (Iraq)","ar-JO":"Arabic (Jordan)","ar-KW":"Arabic (Kuwait)","ar-LB":"Arabic (Lebanon)","ar-LY":"Arabic (Libya)","ar-MA":"Arabic (Morocco)","ar-OM":"Arabic (Oman)","ar-QA":"Arabic (Qatar)","ar-SA":"Arabic (Saudi Arabia)","ar-SY":"Arabic (Syria)","ar-TN":"Arabic (Tunisia)","ar-AE":"Arabic (U.A.E.)","ar-YE":"Arabic (Yemen)",an:"Aragonese",hy:"Armenian",as:"Assamese",ast:"Asturian",az:"Azerbaijani",eu:"Basque",be:"Belarusian",bn:"Bengali",bs:"Bosnian",br:"Breton",bg:"Bulgarian",my:"Burmese",ca:"Catalan",ch:"Chamorro",ce:"Chechen",zh:"Chinese","zh-HK":"Chinese (Hong Kong)","zh-CN":"Chinese (PRC)","zh-SG":"Chinese (Singapore)","zh-TW":"Chinese (Taiwan)",cv:"Chuvash",co:"Corsican",cr:"Cree",hr:"Croatian",cs:"Czech",da:"Danish",nl:"Dutch (Standard)","nl-BE":"Dutch (Belgian)",en:"English","en-AU":"English (Australia)","en-BZ":"English (Belize)","en-CA":"English (Canada)","en-IE":"English (Ireland)","en-JM":"English (Jamaica)","en-NZ":"English (New Zealand)","en-PH":"English (Philippines)","en-ZA":"English (South Africa)","en-TT":"English (Trinidad & Tobago)","en-GB":"English (United Kingdom)","en-US":"English (United States)","en-ZW":"English (Zimbabwe)",eo:"Esperanto",et:"Estonian",fo:"Faeroese",fj:"Fijian",fi:"Finnish",fr:"French (Standard)","fr-BE":"French (Belgium)","fr-CA":"French (Canada)","fr-FR":"French (France)","fr-LU":"French (Luxembourg)","fr-MC":"French (Monaco)","fr-CH":"French (Switzerland)",fy:"Frisian",fur:"Friulian",gd:"Gaelic (Scots)","gd-IE":"Gaelic (Irish)",gl:"Galacian",ka:"Georgian",de:"German (Standard)","de-AT":"German (Austria)","de-DE":"German (Germany)","de-LI":"German (Liechtenstein)","de-LU":"German (Luxembourg)","de-CH":"German (Switzerland)",el:"Greek",gu:"Gujurati",ht:"Haitian",he:"Hebrew",hi:"Hindi",hu:"Hungarian",is:"Icelandic",id:"Indonesian",iu:"Inuktitut",ga:"Irish",it:"Italian (Standard)","it-CH":"Italian (Switzerland)",ja:"Japanese",kn:"Kannada",ks:"Kashmiri",kk:"Kazakh",km:"Khmer",ky:"Kirghiz",tlh:"Klingon",ko:"Korean","ko-KP":"Korean (North Korea)","ko-KR":"Korean (South Korea)",la:"Latin",lv:"Latvian",lt:"Lithuanian",lb:"Luxembourgish",mk:"North Macedonia",ms:"Malay",ml:"Malayalam",mt:"Maltese",mi:"Maori",mr:"Marathi",mo:"Moldavian",nv:"Navajo",ng:"Ndonga",ne:"Nepali",no:"Norwegian",nb:"Norwegian (Bokmal)",nn:"Norwegian (Nynorsk)",oc:"Occitan",or:"Oriya",om:"Oromo",fa:"Persian","fa-IR":"Persian/Iran",pl:"Polish",pt:"Portuguese","pt-BR":"Portuguese (Brazil)",pa:"Punjabi","pa-IN":"Punjabi (India)","pa-PK":"Punjabi (Pakistan)",qu:"Quechua",rm:"Rhaeto-Romanic",ro:"Romanian","ro-MO":"Romanian (Moldavia)",ru:"Russian","ru-MO":"Russian (Moldavia)",sz:"Sami (Lappish)",sg:"Sango",sa:"Sanskrit",sc:"Sardinian",sd:"Sindhi",si:"Singhalese",sr:"Serbian",sk:"Slovak",sl:"Slovenian",so:"Somani",sb:"Sorbian",es:"Spanish","es-AR":"Spanish (Argentina)","es-BO":"Spanish (Bolivia)","es-CL":"Spanish (Chile)","es-CO":"Spanish (Colombia)","es-CR":"Spanish (Costa Rica)","es-DO":"Spanish (Dominican Republic)","es-EC":"Spanish (Ecuador)","es-SV":"Spanish (El Salvador)","es-GT":"Spanish (Guatemala)","es-HN":"Spanish (Honduras)","es-MX":"Spanish (Mexico)","es-NI":"Spanish (Nicaragua)","es-PA":"Spanish (Panama)","es-PY":"Spanish (Paraguay)","es-PE":"Spanish (Peru)","es-PR":"Spanish (Puerto Rico)","es-ES":"Spanish (Spain)","es-UY":"Spanish (Uruguay)","es-VE":"Spanish (Venezuela)",sx:"Sutu",sw:"Swahili",sv:"Swedish","sv-FI":"Swedish (Finland)","sv-SV":"Swedish (Sweden)",ta:"Tamil",tt:"Tatar",te:"Teluga",th:"Thai",tig:"Tigre",ts:"Tsonga",tn:"Tswana",tr:"Turkish",tk:"Turkmen",uk:"Ukrainian",hsb:"Upper Sorbian",ur:"Urdu",ve:"Venda",vi:"Vietnamese",vo:"Volapuk",wa:"Walloon",cy:"Welsh",xh:"Xhosa",ji:"Yiddish",zu:"Zulu"}[langCode]&&(this.internal.languageSettings.languageCode=langCode,!1===this.internal.languageSettings.isSubscribed&&(this.internal.events.subscribe("putCatalog",(function(){this.internal.write("/Lang ("+this.internal.languageSettings.languageCode+")")})),this.internal.languageSettings.isSubscribed=!0)),this}}(jsPDF.API),API=jsPDF.API,getCharWidthsArray=API.getCharWidthsArray=function(text,options){var i,char_code,activeFont=(options=options||{}).font||this.internal.getFont(),fontSize=options.fontSize||this.internal.getFontSize(),charSpace=options.charSpace||this.internal.getCharSpace(),widths=options.widths?options.widths:activeFont.metadata.Unicode.widths,widthsFractionOf=widths.fof?widths.fof:1,kerning=options.kerning?options.kerning:activeFont.metadata.Unicode.kerning,kerningFractionOf=kerning.fof?kerning.fof:1,doKerning=!1!==options.doKerning,kerningValue=0,length=text.length,prior_char_code=0,default_char_width=widths[0]||widthsFractionOf,output=[];for(i=0;i<length;i++)char_code=text.charCodeAt(i),"function"==typeof activeFont.metadata.widthOfString?output.push((activeFont.metadata.widthOfGlyph(activeFont.metadata.characterToGlyph(char_code))+charSpace*(1e3/fontSize)||0)/1e3):(kerningValue=doKerning&&"object"===_typeof(kerning[char_code])&&!isNaN(parseInt(kerning[char_code][prior_char_code],10))?kerning[char_code][prior_char_code]/kerningFractionOf:0,output.push((widths[char_code]||default_char_width)/widthsFractionOf+kerningValue)),prior_char_code=char_code;return output},getStringUnitWidth=API.getStringUnitWidth=function(text,options){var fontSize=(options=options||{}).fontSize||this.internal.getFontSize(),font=options.font||this.internal.getFont(),charSpace=options.charSpace||this.internal.getCharSpace();return API.processArabic&&(text=API.processArabic(text)),"function"==typeof font.metadata.widthOfString?font.metadata.widthOfString(text,fontSize,charSpace)/fontSize:getCharWidthsArray.apply(this,arguments).reduce((function(pv,cv){return pv+cv}),0)},splitLongWord=function(word,widths_array,firstLineMaxLen,maxLen){for(var answer=[],i=0,l=word.length,workingLen=0;i!==l&&workingLen+widths_array[i]<firstLineMaxLen;)workingLen+=widths_array[i],i++;answer.push(word.slice(0,i));var startOfLine=i;for(workingLen=0;i!==l;)workingLen+widths_array[i]>maxLen&&(answer.push(word.slice(startOfLine,i)),workingLen=0,startOfLine=i),workingLen+=widths_array[i],i++;return startOfLine!==i&&answer.push(word.slice(startOfLine,i)),answer},splitParagraphIntoLines=function(text,maxlen,options){options||(options={});var word,widths_array,i,l,tmp,lineIndent,postProcess,line=[],lines=[line],line_length=options.textIndent||0,separator_length=0,current_word_length=0,words=text.split(" "),spaceCharWidth=getCharWidthsArray.apply(this,[" ",options])[0];if(lineIndent=-1===options.lineIndent?words[0].length+2:options.lineIndent||0){var pad=Array(lineIndent).join(" "),wrds=[];words.map((function(wrd){(wrd=wrd.split(/\s*\n/)).length>1?wrds=wrds.concat(wrd.map((function(wrd,idx){return(idx&&wrd.length?"\n":"")+wrd}))):wrds.push(wrd[0])})),words=wrds,lineIndent=getStringUnitWidth.apply(this,[pad,options])}for(i=0,l=words.length;i<l;i++){var force=0;if(word=words[i],lineIndent&&"\n"==word[0]&&(word=word.substr(1),force=1),line_length+separator_length+(current_word_length=(widths_array=getCharWidthsArray.apply(this,[word,options])).reduce((function(pv,cv){return pv+cv}),0))>maxlen||force){if(current_word_length>maxlen){for(tmp=splitLongWord.apply(this,[word,widths_array,maxlen-(line_length+separator_length),maxlen]),line.push(tmp.shift()),line=[tmp.pop()];tmp.length;)lines.push([tmp.shift()]);current_word_length=widths_array.slice(word.length-(line[0]?line[0].length:0)).reduce((function(pv,cv){return pv+cv}),0)}else line=[word];lines.push(line),line_length=current_word_length+lineIndent,separator_length=spaceCharWidth}else line.push(word),line_length+=separator_length+current_word_length,separator_length=spaceCharWidth}return postProcess=lineIndent?function(ln,idx){return(idx?pad:"")+ln.join(" ")}:function(ln){return ln.join(" ")},lines.map(postProcess)},API.splitTextToSize=function(text,maxlen,options){var paragraphs,fsize=(options=options||{}).fontSize||this.internal.getFontSize(),newOptions=function(options){if(options.widths&&options.kerning)return{widths:options.widths,kerning:options.kerning};var f=this.internal.getFont(options.fontName,options.fontStyle);return f.metadata.Unicode?{widths:f.metadata.Unicode.widths||{0:1},kerning:f.metadata.Unicode.kerning||{}}:{font:f.metadata,fontSize:this.internal.getFontSize(),charSpace:this.internal.getCharSpace()}}.call(this,options);paragraphs=Array.isArray(text)?text:String(text).split(/\r?\n/);var fontUnit_maxLen=1*this.internal.scaleFactor*maxlen/fsize;newOptions.textIndent=options.textIndent?1*options.textIndent*this.internal.scaleFactor/fsize:0,newOptions.lineIndent=options.lineIndent;var i,l,output=[];for(i=0,l=paragraphs.length;i<l;i++)output=output.concat(splitParagraphIntoLines.apply(this,[paragraphs[i],fontUnit_maxLen,newOptions]));return output},function(API){API.__fontmetrics__=API.__fontmetrics__||{};for(var encoded="klmnopqrstuvwxyz",mappingUncompress={},mappingCompress={},i=0;i<encoded.length;i++)mappingUncompress[encoded[i]]="0123456789abcdef"[i],mappingCompress["0123456789abcdef"[i]]=encoded[i];var hex=function(value){return"0x"+parseInt(value,10).toString(16)},compress=API.__fontmetrics__.compress=function(data){var value,keystring,valuestring,numberprefix,vals=["{"];for(var key in data){if(value=data[key],isNaN(parseInt(key,10))?keystring="'"+key+"'":(key=parseInt(key,10),keystring=(keystring=hex(key).slice(2)).slice(0,-1)+mappingCompress[keystring.slice(-1)]),"number"==typeof value)value<0?(valuestring=hex(value).slice(3),numberprefix="-"):(valuestring=hex(value).slice(2),numberprefix=""),valuestring=numberprefix+valuestring.slice(0,-1)+mappingCompress[valuestring.slice(-1)];else{if("object"!==_typeof(value))throw new Error("Don't know what to do with value type "+_typeof(value)+".");valuestring=compress(value)}vals.push(keystring+valuestring)}return vals.push("}"),vals.join("")},uncompress=API.__fontmetrics__.uncompress=function(data){if("string"!=typeof data)throw new Error("Invalid argument passed to uncompress.");for(var stringparts,parent_key_pair,key,ch,output={},sign=1,activeobject=output,parentchain=[],keyparts="",valueparts="",datalen=data.length-1,i=1;i<datalen;i+=1)"'"==(ch=data[i])?stringparts?(key=stringparts.join(""),stringparts=void 0):stringparts=[]:stringparts?stringparts.push(ch):"{"==ch?(parentchain.push([activeobject,key]),activeobject={},key=void 0):"}"==ch?((parent_key_pair=parentchain.pop())[0][parent_key_pair[1]]=activeobject,key=void 0,activeobject=parent_key_pair[0]):"-"==ch?sign=-1:void 0===key?mappingUncompress.hasOwnProperty(ch)?(keyparts+=mappingUncompress[ch],key=parseInt(keyparts,16)*sign,sign=1,keyparts=""):keyparts+=ch:mappingUncompress.hasOwnProperty(ch)?(valueparts+=mappingUncompress[ch],activeobject[key]=parseInt(valueparts,16)*sign,sign=1,key=void 0,valueparts=""):valueparts+=ch;return output},encodingBlock={codePages:["WinAnsiEncoding"],WinAnsiEncoding:uncompress("{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}")},encodings={Unicode:{Courier:encodingBlock,"Courier-Bold":encodingBlock,"Courier-BoldOblique":encodingBlock,"Courier-Oblique":encodingBlock,Helvetica:encodingBlock,"Helvetica-Bold":encodingBlock,"Helvetica-BoldOblique":encodingBlock,"Helvetica-Oblique":encodingBlock,"Times-Roman":encodingBlock,"Times-Bold":encodingBlock,"Times-BoldItalic":encodingBlock,"Times-Italic":encodingBlock}},fontMetrics={Unicode:{"Courier-Oblique":uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-BoldItalic":uncompress("{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'kerning'{cl{4qu5kt5qt5rs17ss5ts}201s{201ss}201t{cks4lscmscnscoscpscls2wu2yu201ts}201x{2wu2yu}2k{201ts}2w{4qx5kx5ou5qx5rs17su5tu}2x{17su5tu5ou}2y{4qx5kx5ou5qx5rs17ss5ts}'fof'-6ofn{17sw5tw5ou5qw5rs}7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qs}3v{17su5tu5os5qs}7p{17su5tu}ck{4qu5kt5qt5rs17ss5ts}4l{4qu5kt5qt5rs17ss5ts}cm{4qu5kt5qt5rs17ss5ts}cn{4qu5kt5qt5rs17ss5ts}co{4qu5kt5qt5rs17ss5ts}cp{4qu5kt5qt5rs17ss5ts}6l{4qu5ou5qw5rt17su5tu}5q{ckuclucmucnucoucpu4lu}5r{ckuclucmucnucoucpu4lu}7q{cksclscmscnscoscps4ls}6p{4qu5ou5qw5rt17sw5tw}ek{4qu5ou5qw5rt17su5tu}el{4qu5ou5qw5rt17su5tu}em{4qu5ou5qw5rt17su5tu}en{4qu5ou5qw5rt17su5tu}eo{4qu5ou5qw5rt17su5tu}ep{4qu5ou5qw5rt17su5tu}es{17ss5ts5qs4qu}et{4qu5ou5qw5rt17sw5tw}eu{4qu5ou5qw5rt17ss5ts}ev{17ss5ts5qs4qu}6z{17sw5tw5ou5qw5rs}fm{17sw5tw5ou5qw5rs}7n{201ts}fo{17sw5tw5ou5qw5rs}fp{17sw5tw5ou5qw5rs}fq{17sw5tw5ou5qw5rs}7r{cksclscmscnscoscps4ls}fs{17sw5tw5ou5qw5rs}ft{17su5tu}fu{17su5tu}fv{17su5tu}fw{17su5tu}fz{cksclscmscnscoscps4ls}}}"),"Helvetica-Bold":uncompress("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),Courier:uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Courier-BoldOblique":uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Bold":uncompress("{'widths'{k3q2q5ncx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2l202m2n2n3m2o3m2p6o202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5x4l4s4m4m4n4s4o4s4p4m4q3x4r4y4s4y4t2r4u3m4v4y4w4m4x5y4y4s4z4y5k3x5l4y5m4s5n3r5o4m5p4s5q4s5r6o5s4s5t4s5u4m5v2l5w1w5x2l5y3u5z3m6k2l6l3m6m3r6n2w6o3r6p2w6q2l6r3m6s3r6t1w6u2l6v3r6w1w6x5n6y3r6z3m7k3r7l3r7m2w7n2r7o2l7p3r7q3m7r4s7s3m7t3m7u2w7v2r7w1q7x2r7y3o202l3mcl4sal2lam3man3mao3map3mar3mas2lat4uau1yav3maw3tay4uaz2lbk2sbl3t'fof'6obo2lbp3rbr1tbs2lbu2lbv3mbz3mck4s202k3mcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3rek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3m3u2l17s4s19m3m}'kerning'{cl{4qt5ks5ot5qy5rw17sv5tv}201t{cks4lscmscnscoscpscls4wv}2k{201ts}2w{4qu5ku7mu5os5qx5ru17su5tu}2x{17su5tu5ou5qs}2y{4qv5kv7mu5ot5qz5ru17su5tu}'fof'-6o7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qu}3v{17su5tu5os5qu}fu{17su5tu5ou5qu}7p{17su5tu5ou5qu}ck{4qt5ks5ot5qy5rw17sv5tv}4l{4qt5ks5ot5qy5rw17sv5tv}cm{4qt5ks5ot5qy5rw17sv5tv}cn{4qt5ks5ot5qy5rw17sv5tv}co{4qt5ks5ot5qy5rw17sv5tv}cp{4qt5ks5ot5qy5rw17sv5tv}6l{17st5tt5ou5qu}17s{ckuclucmucnucoucpu4lu4wu}5o{ckuclucmucnucoucpu4lu4wu}5q{ckzclzcmzcnzcozcpz4lz4wu}5r{ckxclxcmxcnxcoxcpx4lx4wu}5t{ckuclucmucnucoucpu4lu4wu}7q{ckuclucmucnucoucpu4lu}6p{17sw5tw5ou5qu}ek{17st5tt5qu}el{17st5tt5ou5qu}em{17st5tt5qu}en{17st5tt5qu}eo{17st5tt5qu}ep{17st5tt5ou5qu}es{17ss5ts5qu}et{17sw5tw5ou5qu}eu{17sw5tw5ou5qu}ev{17ss5ts5qu}6z{17sw5tw5ou5qu5rs}fm{17sw5tw5ou5qu5rs}fn{17sw5tw5ou5qu5rs}fo{17sw5tw5ou5qu5rs}fp{17sw5tw5ou5qu5rs}fq{17sw5tw5ou5qu5rs}7r{cktcltcmtcntcotcpt4lt5os}fs{17sw5tw5ou5qu5rs}ft{17su5tu5ou5qu}7m{5os}fv{17su5tu5ou5qu}fw{17su5tu5ou5qu}fz{cksclscmscnscoscps4ls}}}"),Symbol:uncompress("{'widths'{k3uaw4r19m3m2k1t2l2l202m2y2n3m2p5n202q6o3k3m2s2l2t2l2v3r2w1t3m3m2y1t2z1wbk2sbl3r'fof'6o3n3m3o3m3p3m3q3m3r3m3s3m3t3m3u1w3v1w3w3r3x3r3y3r3z2wbp3t3l3m5v2l5x2l5z3m2q4yfr3r7v3k7w1o7x3k}'kerning'{'fof'-6o}}"),Helvetica:uncompress("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}"),"Helvetica-BoldOblique":uncompress("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),ZapfDingbats:uncompress("{'widths'{k4u2k1w'fof'6o}'kerning'{'fof'-6o}}"),"Courier-Bold":uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Italic":uncompress("{'widths'{k3n2q4ycx2l201n3m201o5t201s2l201t2l201u2l201w3r201x3r201y3r2k1t2l2l202m2n2n3m2o3m2p5n202q5t2r1p2s2l2t2l2u3m2v4n2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w4n3x4n3y4n3z3m4k5w4l3x4m3x4n4m4o4s4p3x4q3x4r4s4s4s4t2l4u2w4v4m4w3r4x5n4y4m4z4s5k3x5l4s5m3x5n3m5o3r5p4s5q3x5r5n5s3x5t3r5u3r5v2r5w1w5x2r5y2u5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q1w6r3m6s3m6t1w6u1w6v2w6w1w6x4s6y3m6z3m7k3m7l3m7m2r7n2r7o1w7p3m7q2w7r4m7s2w7t2w7u2r7v2s7w1v7x2s7y3q202l3mcl3xal2ram3man3mao3map3mar3mas2lat4wau1vav3maw4nay4waz2lbk2sbl4n'fof'6obo2lbp3mbq3obr1tbs2lbu1zbv3mbz3mck3x202k3mcm3xcn3xco3xcp3xcq5tcr4mcs3xct3xcu3xcv3xcw2l2m2ucy2lcz2ldl4mdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr4nfs3mft3mfu3mfv3mfw3mfz2w203k6o212m6m2dw2l2cq2l3t3m3u2l17s3r19m3m}'kerning'{cl{5kt4qw}201s{201sw}201t{201tw2wy2yy6q-t}201x{2wy2yy}2k{201tw}2w{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}2x{17ss5ts5os}2y{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}'fof'-6o6t{17ss5ts5qs}7t{5os}3v{5qs}7p{17su5tu5qs}ck{5kt4qw}4l{5kt4qw}cm{5kt4qw}cn{5kt4qw}co{5kt4qw}cp{5kt4qw}6l{4qs5ks5ou5qw5ru17su5tu}17s{2ks}5q{ckvclvcmvcnvcovcpv4lv}5r{ckuclucmucnucoucpu4lu}5t{2ks}6p{4qs5ks5ou5qw5ru17su5tu}ek{4qs5ks5ou5qw5ru17su5tu}el{4qs5ks5ou5qw5ru17su5tu}em{4qs5ks5ou5qw5ru17su5tu}en{4qs5ks5ou5qw5ru17su5tu}eo{4qs5ks5ou5qw5ru17su5tu}ep{4qs5ks5ou5qw5ru17su5tu}es{5ks5qs4qs}et{4qs5ks5ou5qw5ru17su5tu}eu{4qs5ks5qw5ru17su5tu}ev{5ks5qs4qs}ex{17ss5ts5qs}6z{4qv5ks5ou5qw5ru17su5tu}fm{4qv5ks5ou5qw5ru17su5tu}fn{4qv5ks5ou5qw5ru17su5tu}fo{4qv5ks5ou5qw5ru17su5tu}fp{4qv5ks5ou5qw5ru17su5tu}fq{4qv5ks5ou5qw5ru17su5tu}7r{5os}fs{4qv5ks5ou5qw5ru17su5tu}ft{17su5tu5qs}fu{17su5tu5qs}fv{17su5tu5qs}fw{17su5tu5qs}}}"),"Times-Roman":uncompress("{'widths'{k3n2q4ycx2l201n3m201o6o201s2l201t2l201u2l201w2w201x2w201y2w2k1t2l2l202m2n2n3m2o3m2p5n202q6o2r1m2s2l2t2l2u3m2v3s2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v1w3w3s3x3s3y3s3z2w4k5w4l4s4m4m4n4m4o4s4p3x4q3r4r4s4s4s4t2l4u2r4v4s4w3x4x5t4y4s4z4s5k3r5l4s5m4m5n3r5o3x5p4s5q4s5r5y5s4s5t4s5u3x5v2l5w1w5x2l5y2z5z3m6k2l6l2w6m3m6n2w6o3m6p2w6q2l6r3m6s3m6t1w6u1w6v3m6w1w6x4y6y3m6z3m7k3m7l3m7m2l7n2r7o1w7p3m7q3m7r4s7s3m7t3m7u2w7v3k7w1o7x3k7y3q202l3mcl4sal2lam3man3mao3map3mar3mas2lat4wau1vav3maw3say4waz2lbk2sbl3s'fof'6obo2lbp3mbq2xbr1tbs2lbu1zbv3mbz2wck4s202k3mcm4scn4sco4scp4scq5tcr4mcs3xct3xcu3xcv3xcw2l2m2tcy2lcz2ldl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek2wel2wem2wen2weo2wep2weq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr3sfs3mft3mfu3mfv3mfw3mfz3m203k6o212m6m2dw2l2cq2l3t3m3u1w17s4s19m3m}'kerning'{cl{4qs5ku17sw5ou5qy5rw201ss5tw201ws}201s{201ss}201t{ckw4lwcmwcnwcowcpwclw4wu201ts}2k{201ts}2w{4qs5kw5os5qx5ru17sx5tx}2x{17sw5tw5ou5qu}2y{4qs5kw5os5qx5ru17sx5tx}'fof'-6o7t{ckuclucmucnucoucpu4lu5os5rs}3u{17su5tu5qs}3v{17su5tu5qs}7p{17sw5tw5qs}ck{4qs5ku17sw5ou5qy5rw201ss5tw201ws}4l{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cm{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cn{4qs5ku17sw5ou5qy5rw201ss5tw201ws}co{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cp{4qs5ku17sw5ou5qy5rw201ss5tw201ws}6l{17su5tu5os5qw5rs}17s{2ktclvcmvcnvcovcpv4lv4wuckv}5o{ckwclwcmwcnwcowcpw4lw4wu}5q{ckyclycmycnycoycpy4ly4wu5ms}5r{cktcltcmtcntcotcpt4lt4ws}5t{2ktclvcmvcnvcovcpv4lv4wuckv}7q{cksclscmscnscoscps4ls}6p{17su5tu5qw5rs}ek{5qs5rs}el{17su5tu5os5qw5rs}em{17su5tu5os5qs5rs}en{17su5qs5rs}eo{5qs5rs}ep{17su5tu5os5qw5rs}es{5qs}et{17su5tu5qw5rs}eu{17su5tu5qs5rs}ev{5qs}6z{17sv5tv5os5qx5rs}fm{5os5qt5rs}fn{17sv5tv5os5qx5rs}fo{17sv5tv5os5qx5rs}fp{5os5qt5rs}fq{5os5qt5rs}7r{ckuclucmucnucoucpu4lu5os}fs{17sv5tv5os5qx5rs}ft{17ss5ts5qs}fu{17sw5tw5qs}fv{17sw5tw5qs}fw{17ss5ts5qs}fz{ckuclucmucnucoucpu4lu5os5rs}}}"),"Helvetica-Oblique":uncompress("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}")}};API.events.push(["addFont",function(data){var font=data.font,metrics=fontMetrics.Unicode[font.postScriptName];metrics&&(font.metadata.Unicode={},font.metadata.Unicode.widths=metrics.widths,font.metadata.Unicode.kerning=metrics.kerning);var encodingBlock=encodings.Unicode[font.postScriptName];encodingBlock&&(font.metadata.Unicode.encoding=encodingBlock,font.encoding=encodingBlock.codePages[0])}])}(jsPDF.API),
+/**
+   * @license
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+function(jsPDF){var binaryStringToUint8Array=function(binary_string){for(var len=binary_string.length,bytes=new Uint8Array(len),i=0;i<len;i++)bytes[i]=binary_string.charCodeAt(i);return bytes};jsPDF.API.events.push(["addFont",function(data){var file=void 0,font=data.font,instance=data.instance;if(!font.isStandardFont){if(void 0===instance)throw new Error("Font does not exist in vFS, import fonts or remove declaration doc.addFont('"+font.postScriptName+"').");if("string"!=typeof(file=!1===instance.existsFileInVFS(font.postScriptName)?instance.loadFile(font.postScriptName):instance.getFileFromVFS(font.postScriptName)))throw new Error("Font is not stored as string-data in vFS, import fonts or remove declaration doc.addFont('"+font.postScriptName+"').");!function(font,file){file=/^\x00\x01\x00\x00/.test(file)?binaryStringToUint8Array(file):binaryStringToUint8Array(atob(file)),font.metadata=jsPDF.API.TTFFont.open(file),font.metadata.Unicode=font.metadata.Unicode||{encoding:{},kerning:{},widths:[]},font.metadata.glyIdsUsed=[0]}(font,file)}}])}(jsPDF),function(jsPDFAPI){function loadCanvg(){return(globalObject.canvg?Promise.resolve(globalObject.canvg):"object"===(void 0===exports?"undefined":_typeof(exports))&&"undefined"!=typeof module?new Promise((function(resolve,reject){try{resolve(require("canvg"))}catch(e){reject(e)}})):"function"==typeof define&&define.amd?new Promise((function(resolve,reject){try{require(["canvg"],resolve)}catch(e){reject(e)}})):Promise.reject(new Error("Could not load canvg"))).catch((function(e){return Promise.reject(new Error("Could not load canvg: "+e))})).then((function(canvg){return canvg.default?canvg.default:canvg}))}jsPDFAPI.addSvgAsImage=function(svg,x,y,w,h,alias,compression,rotation){if(isNaN(x)||isNaN(y))throw console.error("jsPDF.addSvgAsImage: Invalid coordinates",arguments),new Error("Invalid coordinates passed to jsPDF.addSvgAsImage");if(isNaN(w)||isNaN(h))throw console.error("jsPDF.addSvgAsImage: Invalid measurements",arguments),new Error("Invalid measurements (width and/or height) passed to jsPDF.addSvgAsImage");var canvas=document.createElement("canvas");canvas.width=w,canvas.height=h;var ctx=canvas.getContext("2d");ctx.fillStyle="#fff",ctx.fillRect(0,0,canvas.width,canvas.height);var options={ignoreMouse:!0,ignoreAnimation:!0,ignoreDimensions:!0},doc=this;return loadCanvg().then((function(canvg){return canvg.fromString(ctx,svg,options)}),(function(){return Promise.reject(new Error("Could not load canvg."))})).then((function(instance){return instance.render(options)})).then((function(){doc.addImage(canvas.toDataURL("image/jpeg",1),x,y,w,h,compression,rotation)}))}}(jsPDF.API),
+/**
+   * @license
+   * ====================================================================
+   * Copyright (c) 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
+   *
+   * Permission is hereby granted, free of charge, to any person obtaining
+   * a copy of this software and associated documentation files (the
+   * "Software"), to deal in the Software without restriction, including
+   * without limitation the rights to use, copy, modify, merge, publish,
+   * distribute, sublicense, and/or sell copies of the Software, and to
+   * permit persons to whom the Software is furnished to do so, subject to
+   * the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be
+   * included in all copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+   * ====================================================================
+   */
+function(jsPDFAPI){jsPDFAPI.putTotalPages=function(pageExpression){var replaceExpression,totalNumberOfPages=0;parseInt(this.internal.getFont().id.substr(1),10)<15?(replaceExpression=new RegExp(pageExpression,"g"),totalNumberOfPages=this.internal.getNumberOfPages()):(replaceExpression=new RegExp(this.pdfEscape16(pageExpression,this.internal.getFont()),"g"),totalNumberOfPages=this.pdfEscape16(this.internal.getNumberOfPages()+"",this.internal.getFont()));for(var n=1;n<=this.internal.getNumberOfPages();n++)for(var i=0;i<this.internal.pages[n].length;i++)this.internal.pages[n][i]=this.internal.pages[n][i].replace(replaceExpression,totalNumberOfPages);return this}}(jsPDF.API),function(jsPDFAPI){jsPDFAPI.viewerPreferences=function(options,doReset){var configuration;options=options||{},doReset=doReset||!1;var isValid,method,value,configurationTemplate={HideToolbar:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},HideMenubar:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},HideWindowUI:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},FitWindow:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},CenterWindow:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.3},DisplayDocTitle:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.4},NonFullScreenPageMode:{defaultValue:"UseNone",value:"UseNone",type:"name",explicitSet:!1,valueSet:["UseNone","UseOutlines","UseThumbs","UseOC"],pdfVersion:1.3},Direction:{defaultValue:"L2R",value:"L2R",type:"name",explicitSet:!1,valueSet:["L2R","R2L"],pdfVersion:1.3},ViewArea:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},ViewClip:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintArea:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintClip:{defaultValue:"CropBox",value:"CropBox",type:"name",explicitSet:!1,valueSet:["MediaBox","CropBox","TrimBox","BleedBox","ArtBox"],pdfVersion:1.4},PrintScaling:{defaultValue:"AppDefault",value:"AppDefault",type:"name",explicitSet:!1,valueSet:["AppDefault","None"],pdfVersion:1.6},Duplex:{defaultValue:"",value:"none",type:"name",explicitSet:!1,valueSet:["Simplex","DuplexFlipShortEdge","DuplexFlipLongEdge","none"],pdfVersion:1.7},PickTrayByPDFSize:{defaultValue:!1,value:!1,type:"boolean",explicitSet:!1,valueSet:[!0,!1],pdfVersion:1.7},PrintPageRange:{defaultValue:"",value:"",type:"array",explicitSet:!1,valueSet:null,pdfVersion:1.7},NumCopies:{defaultValue:1,value:1,type:"integer",explicitSet:!1,valueSet:null,pdfVersion:1.7}},configurationKeys=Object.keys(configurationTemplate),rangeArray=[],i=0,j=0,k=0;function arrayContainsElement(array,element){var iterator,result=!1;for(iterator=0;iterator<array.length;iterator+=1)array[iterator]===element&&(result=!0);return result}if(void 0===this.internal.viewerpreferences&&(this.internal.viewerpreferences={},this.internal.viewerpreferences.configuration=JSON.parse(JSON.stringify(configurationTemplate)),this.internal.viewerpreferences.isSubscribed=!1),configuration=this.internal.viewerpreferences.configuration,"reset"===options||!0===doReset){var len=configurationKeys.length;for(k=0;k<len;k+=1)configuration[configurationKeys[k]].value=configuration[configurationKeys[k]].defaultValue,configuration[configurationKeys[k]].explicitSet=!1}if("object"===_typeof(options))for(method in options)if(value=options[method],arrayContainsElement(configurationKeys,method)&&void 0!==value){if("boolean"===configuration[method].type&&"boolean"==typeof value)configuration[method].value=value;else if("name"===configuration[method].type&&arrayContainsElement(configuration[method].valueSet,value))configuration[method].value=value;else if("integer"===configuration[method].type&&Number.isInteger(value))configuration[method].value=value;else if("array"===configuration[method].type){for(i=0;i<value.length;i+=1)if(isValid=!0,1===value[i].length&&"number"==typeof value[i][0])rangeArray.push(String(value[i]-1));else if(value[i].length>1){for(j=0;j<value[i].length;j+=1)"number"!=typeof value[i][j]&&(isValid=!1);!0===isValid&&rangeArray.push([value[i][0]-1,value[i][1]-1].join(" "))}configuration[method].value="["+rangeArray.join(" ")+"]"}else configuration[method].value=configuration[method].defaultValue;configuration[method].explicitSet=!0}return!1===this.internal.viewerpreferences.isSubscribed&&(this.internal.events.subscribe("putCatalog",(function(){var vPref,pdfDict=[];for(vPref in configuration)!0===configuration[vPref].explicitSet&&("name"===configuration[vPref].type?pdfDict.push("/"+vPref+" /"+configuration[vPref].value):pdfDict.push("/"+vPref+" "+configuration[vPref].value));0!==pdfDict.length&&this.internal.write("/ViewerPreferences\n<<\n"+pdfDict.join("\n")+"\n>>")})),this.internal.viewerpreferences.isSubscribed=!0),this.internal.viewerpreferences.configuration=configuration,this}}(jsPDF.API),
+/** ====================================================================
+   * @license
+   * jsPDF XMP metadata plugin
+   * Copyright (c) 2016 Jussi Utunen, u-jussi@suomi24.fi
+   *
+   * Permission is hereby granted, free of charge, to any person obtaining
+   * a copy of this software and associated documentation files (the
+   * "Software"), to deal in the Software without restriction, including
+   * without limitation the rights to use, copy, modify, merge, publish,
+   * distribute, sublicense, and/or sell copies of the Software, and to
+   * permit persons to whom the Software is furnished to do so, subject to
+   * the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be
+   * included in all copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+   * ====================================================================
+   */
+function(jsPDFAPI){var postPutResources=function(){var rdf_beginning='<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:jspdf="'+this.internal.__metadata__.namespaceuri+'"><jspdf:metadata>',utf8_xmpmeta_beginning=unescape(encodeURIComponent('<x:xmpmeta xmlns:x="adobe:ns:meta/">')),utf8_rdf_beginning=unescape(encodeURIComponent(rdf_beginning)),utf8_metadata=unescape(encodeURIComponent(this.internal.__metadata__.metadata)),utf8_rdf_ending=unescape(encodeURIComponent("</jspdf:metadata></rdf:Description></rdf:RDF>")),utf8_xmpmeta_ending=unescape(encodeURIComponent("</x:xmpmeta>")),total_len=utf8_rdf_beginning.length+utf8_metadata.length+utf8_rdf_ending.length+utf8_xmpmeta_beginning.length+utf8_xmpmeta_ending.length;this.internal.__metadata__.metadata_object_number=this.internal.newObject(),this.internal.write("<< /Type /Metadata /Subtype /XML /Length "+total_len+" >>"),this.internal.write("stream"),this.internal.write(utf8_xmpmeta_beginning+utf8_rdf_beginning+utf8_metadata+utf8_rdf_ending+utf8_xmpmeta_ending),this.internal.write("endstream"),this.internal.write("endobj")},putCatalog=function(){this.internal.__metadata__.metadata_object_number&&this.internal.write("/Metadata "+this.internal.__metadata__.metadata_object_number+" 0 R")};jsPDFAPI.addMetadata=function(metadata,namespaceuri){return void 0===this.internal.__metadata__&&(this.internal.__metadata__={metadata:metadata,namespaceuri:namespaceuri||"http://jspdf.default.namespaceuri/"},this.internal.events.subscribe("putCatalog",putCatalog),this.internal.events.subscribe("postPutResources",postPutResources)),this}}(jsPDF.API),function(jsPDF){var jsPDFAPI=jsPDF.API,pdfEscape16=jsPDFAPI.pdfEscape16=function(text,font){for(var t,widths=font.metadata.Unicode.widths,padz=["","0","00","000","0000"],ar=[""],i=0,l=text.length;i<l;++i){if(t=font.metadata.characterToGlyph(text.charCodeAt(i)),font.metadata.glyIdsUsed.push(t),font.metadata.toUnicode[t]=text.charCodeAt(i),-1==widths.indexOf(t)&&(widths.push(t),widths.push([parseInt(font.metadata.widthOfGlyph(t),10)])),"0"==t)return ar.join("");t=t.toString(16),ar.push(padz[4-t.length],t)}return ar.join("")},toUnicodeCmap=function(map){var code,codes,range,unicode,unicodeMap,_i,_len;for(unicodeMap="/CIDInit /ProcSet findresource begin\n12 dict begin\nbegincmap\n/CIDSystemInfo <<\n  /Registry (Adobe)\n  /Ordering (UCS)\n  /Supplement 0\n>> def\n/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n1 begincodespacerange\n<0000><ffff>\nendcodespacerange",range=[],_i=0,_len=(codes=Object.keys(map).sort((function(a,b){return a-b}))).length;_i<_len;_i++)code=codes[_i],range.length>=100&&(unicodeMap+="\n"+range.length+" beginbfchar\n"+range.join("\n")+"\nendbfchar",range=[]),void 0!==map[code]&&null!==map[code]&&"function"==typeof map[code].toString&&(unicode=("0000"+map[code].toString(16)).slice(-4),code=("0000"+(+code).toString(16)).slice(-4),range.push("<"+code+"><"+unicode+">"));return range.length&&(unicodeMap+="\n"+range.length+" beginbfchar\n"+range.join("\n")+"\nendbfchar\n"),unicodeMap+="endcmap\nCMapName currentdict /CMap defineresource pop\nend\nend"};jsPDFAPI.events.push(["putFont",function(args){!function(options){var font=options.font,out=options.out,newObject=options.newObject,putStream=options.putStream;if(font.metadata instanceof jsPDF.API.TTFFont&&"Identity-H"===font.encoding){for(var widths=font.metadata.Unicode.widths,pdfOutput=font.metadata.subset.encode(font.metadata.glyIdsUsed,1),pdfOutput2="",i=0;i<pdfOutput.length;i++)pdfOutput2+=String.fromCharCode(pdfOutput[i]);var fontTable=newObject();putStream({data:pdfOutput2,addLength1:!0,objectId:fontTable}),out("endobj");var cmap=newObject();putStream({data:toUnicodeCmap(font.metadata.toUnicode),addLength1:!0,objectId:cmap}),out("endobj");var fontDescriptor=newObject();out("<<"),out("/Type /FontDescriptor"),out("/FontName /"+toPDFName(font.fontName)),out("/FontFile2 "+fontTable+" 0 R"),out("/FontBBox "+jsPDF.API.PDFObject.convert(font.metadata.bbox)),out("/Flags "+font.metadata.flags),out("/StemV "+font.metadata.stemV),out("/ItalicAngle "+font.metadata.italicAngle),out("/Ascent "+font.metadata.ascender),out("/Descent "+font.metadata.decender),out("/CapHeight "+font.metadata.capHeight),out(">>"),out("endobj");var DescendantFont=newObject();out("<<"),out("/Type /Font"),out("/BaseFont /"+toPDFName(font.fontName)),out("/FontDescriptor "+fontDescriptor+" 0 R"),out("/W "+jsPDF.API.PDFObject.convert(widths)),out("/CIDToGIDMap /Identity"),out("/DW 1000"),out("/Subtype /CIDFontType2"),out("/CIDSystemInfo"),out("<<"),out("/Supplement 0"),out("/Registry (Adobe)"),out("/Ordering ("+font.encoding+")"),out(">>"),out(">>"),out("endobj"),font.objectNumber=newObject(),out("<<"),out("/Type /Font"),out("/Subtype /Type0"),out("/ToUnicode "+cmap+" 0 R"),out("/BaseFont /"+toPDFName(font.fontName)),out("/Encoding /"+font.encoding),out("/DescendantFonts ["+DescendantFont+" 0 R]"),out(">>"),out("endobj"),font.isAlreadyPutted=!0}}(args)}]);jsPDFAPI.events.push(["putFont",function(args){!function(options){var font=options.font,out=options.out,newObject=options.newObject,putStream=options.putStream;if(font.metadata instanceof jsPDF.API.TTFFont&&"WinAnsiEncoding"===font.encoding){for(var pdfOutput=font.metadata.rawData,pdfOutput2="",i=0;i<pdfOutput.length;i++)pdfOutput2+=String.fromCharCode(pdfOutput[i]);var fontTable=newObject();putStream({data:pdfOutput2,addLength1:!0,objectId:fontTable}),out("endobj");var cmap=newObject();putStream({data:toUnicodeCmap(font.metadata.toUnicode),addLength1:!0,objectId:cmap}),out("endobj");var fontDescriptor=newObject();out("<<"),out("/Descent "+font.metadata.decender),out("/CapHeight "+font.metadata.capHeight),out("/StemV "+font.metadata.stemV),out("/Type /FontDescriptor"),out("/FontFile2 "+fontTable+" 0 R"),out("/Flags 96"),out("/FontBBox "+jsPDF.API.PDFObject.convert(font.metadata.bbox)),out("/FontName /"+toPDFName(font.fontName)),out("/ItalicAngle "+font.metadata.italicAngle),out("/Ascent "+font.metadata.ascender),out(">>"),out("endobj"),font.objectNumber=newObject();for(var j=0;j<font.metadata.hmtx.widths.length;j++)font.metadata.hmtx.widths[j]=parseInt(font.metadata.hmtx.widths[j]*(1e3/font.metadata.head.unitsPerEm));out("<</Subtype/TrueType/Type/Font/ToUnicode "+cmap+" 0 R/BaseFont/"+toPDFName(font.fontName)+"/FontDescriptor "+fontDescriptor+" 0 R/Encoding/"+font.encoding+" /FirstChar 29 /LastChar 255 /Widths "+jsPDF.API.PDFObject.convert(font.metadata.hmtx.widths)+">>"),out("endobj"),font.isAlreadyPutted=!0}}(args)}]);var utf8TextFunction=function(args){var cmapConfirm,text=args.text||"",x=args.x,y=args.y,options=args.options||{},mutex=args.mutex||{},pdfEscape=mutex.pdfEscape,activeFontKey=mutex.activeFontKey,fonts=mutex.fonts,key=activeFontKey,str="",s=0,strText="",encoding=fonts[key].encoding;if("Identity-H"!==fonts[key].encoding)return{text:text,x:x,y:y,options:options,mutex:mutex};for(strText=text,key=activeFontKey,Array.isArray(text)&&(strText=text[0]),s=0;s<strText.length;s+=1)fonts[key].metadata.hasOwnProperty("cmap")&&(cmapConfirm=fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)]),cmapConfirm||strText[s].charCodeAt(0)<256&&fonts[key].metadata.hasOwnProperty("Unicode")?str+=strText[s]:str+="";var result="";return parseInt(key.slice(1))<14||"WinAnsiEncoding"===encoding?result=pdfEscape(str,key).split("").map((function(cv){return cv.charCodeAt(0).toString(16)})).join(""):"Identity-H"===encoding&&(result=pdfEscape16(str,fonts[key])),mutex.isHex=!0,{text:result,x:x,y:y,options:options,mutex:mutex}};jsPDFAPI.events.push(["postProcessText",function(parms){var text=parms.text||"",tmpText=[],args={text:text,x:parms.x,y:parms.y,options:parms.options,mutex:parms.mutex};if(Array.isArray(text)){var i=0;for(i=0;i<text.length;i+=1)Array.isArray(text[i])&&3===text[i].length?tmpText.push([utf8TextFunction(Object.assign({},args,{text:text[i][0]})).text,text[i][1],text[i][2]]):tmpText.push(utf8TextFunction(Object.assign({},args,{text:text[i]})).text);parms.text=tmpText}else parms.text=utf8TextFunction(Object.assign({},args,{text:text})).text}])}(jsPDF),
+/**
+   * @license
+   * jsPDF virtual FileSystem functionality
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+function(jsPDFAPI){var _initializeVFS=function(){return void 0===this.internal.vFS&&(this.internal.vFS={}),!0};jsPDFAPI.existsFileInVFS=function(filename){return _initializeVFS.call(this),void 0!==this.internal.vFS[filename]},jsPDFAPI.addFileToVFS=function(filename,filecontent){return _initializeVFS.call(this),this.internal.vFS[filename]=filecontent,this},jsPDFAPI.getFileFromVFS=function(filename){return _initializeVFS.call(this),void 0!==this.internal.vFS[filename]?this.internal.vFS[filename]:null}}(jsPDF.API),
+/**
+   * @license
+   * Unicode Bidi Engine based on the work of Alex Shensis (@asthensis)
+   * MIT License
    */
-function(global){function RGBColor(color_string){var channels;this.ok=!1,"#"==color_string.charAt(0)&&(color_string=color_string.substr(1,6)),color_string=(color_string=color_string.replace(/ /g,"")).toLowerCase();var simple_colors={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"00ffff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000000",blanchedalmond:"ffebcd",blue:"0000ff",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"00ffff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dodgerblue:"1e90ff",feldspar:"d19275",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"ff00ff",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgrey:"d3d3d3",lightgreen:"90ee90",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslateblue:"8470ff",lightslategray:"778899",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"00ff00",limegreen:"32cd32",linen:"faf0e6",magenta:"ff00ff",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370d8",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"d87093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",red:"ff0000",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",violetred:"d02090",wheat:"f5deb3",white:"ffffff",whitesmoke:"f5f5f5",yellow:"ffff00",yellowgreen:"9acd32"};for(var key in simple_colors)color_string==key&&(color_string=simple_colors[key]);for(var color_defs=[{re:/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,example:["rgb(123, 234, 45)","rgb(255,234,245)"],process:function(bits){return[parseInt(bits[1]),parseInt(bits[2]),parseInt(bits[3])]}},{re:/^(\w{2})(\w{2})(\w{2})$/,example:["#00ff00","336699"],process:function(bits){return[parseInt(bits[1],16),parseInt(bits[2],16),parseInt(bits[3],16)]}},{re:/^(\w{1})(\w{1})(\w{1})$/,example:["#fb0","f0f"],process:function(bits){return[parseInt(bits[1]+bits[1],16),parseInt(bits[2]+bits[2],16),parseInt(bits[3]+bits[3],16)]}}],i=0;i<color_defs.length;i++){var re=color_defs[i].re,processor=color_defs[i].process,bits=re.exec(color_string);bits&&(channels=processor(bits),this.r=channels[0],this.g=channels[1],this.b=channels[2],this.ok=!0)}this.r=this.r<0||isNaN(this.r)?0:this.r>255?255:this.r,this.g=this.g<0||isNaN(this.g)?0:this.g>255?255:this.g,this.b=this.b<0||isNaN(this.b)?0:this.b>255?255:this.b,this.toRGB=function(){return"rgb("+this.r+", "+this.g+", "+this.b+")"},this.toHex=function(){var r=this.r.toString(16),g=this.g.toString(16),b=this.b.toString(16);return 1==r.length&&(r="0"+r),1==g.length&&(g="0"+g),1==b.length&&(b="0"+b),"#"+r+g+b},this.getHelpXML=function(){for(var examples=new Array,i=0;i<color_defs.length;i++)for(var example=color_defs[i].example,j=0;j<example.length;j++)examples[examples.length]=example[j];for(var sc in simple_colors)examples[examples.length]=sc;var xml=document.createElement("ul");xml.setAttribute("id","rgbcolor-examples");for(i=0;i<examples.length;i++)try{var list_item=document.createElement("li"),list_color=new RGBColor(examples[i]),example_div=document.createElement("div");example_div.style.cssText="margin: 3px; border: 1px solid black; background:"+list_color.toHex()+"; color:"+list_color.toHex(),example_div.appendChild(document.createTextNode("test"));var list_item_value=document.createTextNode(" "+examples[i]+" -> "+list_color.toRGB()+" -> "+list_color.toHex());list_item.appendChild(example_div),list_item.appendChild(list_item_value),xml.appendChild(list_item)}catch(e){}return xml}}"undefined"!=typeof define&&define.amd?define("RGBColor",(function(){return RGBColor})):"undefined"!=typeof module&&module.exports&&(module.exports=RGBColor),global.RGBColor=RGBColor}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||"undefined"!=typeof global&&global||Function('return typeof this === "object" && this.content')()||Function("return this")()),function(e){if("object"==("undefined"==typeof exports?"undefined":_typeof2(exports))&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define("html2canvas",[],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.html2canvas=e()}}((function(){return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a="function"==typeof require&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,(function(e){var n=t[o][1][e];return s(n||e)}),l,l.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o<r.length;o++)s(r[o]);return s}({1:[function(_dereq_,module,exports){(function(global){!function(root){var freeExports="object"==_typeof2(exports)&&exports,freeModule="object"==_typeof2(module)&&module&&module.exports==freeExports&&module,freeGlobal="object"==_typeof2(global)&&global;freeGlobal.global!==freeGlobal&&freeGlobal.window!==freeGlobal||(root=freeGlobal);var punycode,key,maxInt=2147483647,regexPunycode=/^xn--/,regexNonASCII=/[^ -~]/,regexSeparators=/\x2E|\u3002|\uFF0E|\uFF61/g,errors={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},floor=Math.floor,stringFromCharCode=String.fromCharCode;function error(type){throw RangeError(errors[type])}function map(array,fn){for(var length=array.length;length--;)array[length]=fn(array[length]);return array}function mapDomain(string,fn){return map(string.split(regexSeparators),fn).join(".")}function ucs2decode(string){for(var value,extra,output=[],counter=0,length=string.length;counter<length;)(value=string.charCodeAt(counter++))>=55296&&value<=56319&&counter<length?56320==(64512&(extra=string.charCodeAt(counter++)))?output.push(((1023&value)<<10)+(1023&extra)+65536):(output.push(value),counter--):output.push(value);return output}function ucs2encode(array){return map(array,(function(value){var output="";return value>65535&&(output+=stringFromCharCode((value-=65536)>>>10&1023|55296),value=56320|1023&value),output+=stringFromCharCode(value)})).join("")}function digitToBasic(digit,flag){return digit+22+75*(digit<26)-((0!=flag)<<5)}function adapt(delta,numPoints,firstTime){var k=0;for(delta=firstTime?floor(delta/700):delta>>1,delta+=floor(delta/numPoints);delta>455;k+=36)delta=floor(delta/35);return floor(k+36*delta/(delta+38))}function decode(input){var out,basic,j,index,oldi,w,k,digit,t,baseMinusT,codePoint,output=[],inputLength=input.length,i=0,n=128,bias=72;for((basic=input.lastIndexOf("-"))<0&&(basic=0),j=0;j<basic;++j)input.charCodeAt(j)>=128&&error("not-basic"),output.push(input.charCodeAt(j));for(index=basic>0?basic+1:0;index<inputLength;){for(oldi=i,w=1,k=36;index>=inputLength&&error("invalid-input"),((digit=(codePoint=input.charCodeAt(index++))-48<10?codePoint-22:codePoint-65<26?codePoint-65:codePoint-97<26?codePoint-97:36)>=36||digit>floor((maxInt-i)/w))&&error("overflow"),i+=digit*w,!(digit<(t=k<=bias?1:k>=bias+26?26:k-bias));k+=36)w>floor(maxInt/(baseMinusT=36-t))&&error("overflow"),w*=baseMinusT;bias=adapt(i-oldi,out=output.length+1,0==oldi),floor(i/out)>maxInt-n&&error("overflow"),n+=floor(i/out),i%=out,output.splice(i++,0,n)}return ucs2encode(output)}function encode(input){var n,delta,handledCPCount,basicLength,bias,j,m,q,k,t,currentValue,inputLength,handledCPCountPlusOne,baseMinusT,qMinusT,output=[];for(inputLength=(input=ucs2decode(input)).length,n=128,delta=0,bias=72,j=0;j<inputLength;++j)(currentValue=input[j])<128&&output.push(stringFromCharCode(currentValue));for(handledCPCount=basicLength=output.length,basicLength&&output.push("-");handledCPCount<inputLength;){for(m=maxInt,j=0;j<inputLength;++j)(currentValue=input[j])>=n&&currentValue<m&&(m=currentValue);for(m-n>floor((maxInt-delta)/(handledCPCountPlusOne=handledCPCount+1))&&error("overflow"),delta+=(m-n)*handledCPCountPlusOne,n=m,j=0;j<inputLength;++j)if((currentValue=input[j])<n&&++delta>maxInt&&error("overflow"),currentValue==n){for(q=delta,k=36;!(q<(t=k<=bias?1:k>=bias+26?26:k-bias));k+=36)qMinusT=q-t,baseMinusT=36-t,output.push(stringFromCharCode(digitToBasic(t+qMinusT%baseMinusT,0))),q=floor(qMinusT/baseMinusT);output.push(stringFromCharCode(digitToBasic(q,0))),bias=adapt(delta,handledCPCountPlusOne,handledCPCount==basicLength),delta=0,++handledCPCount}++delta,++n}return output.join("")}if(punycode={version:"1.2.4",ucs2:{decode:ucs2decode,encode:ucs2encode},decode:decode,encode:encode,toASCII:function(domain){return mapDomain(domain,(function(string){return regexNonASCII.test(string)?"xn--"+encode(string):string}))},toUnicode:function(domain){return mapDomain(domain,(function(string){return regexPunycode.test(string)?decode(string.slice(4).toLowerCase()):string}))}},freeExports&&!freeExports.nodeType)if(freeModule)freeModule.exports=punycode;else for(key in punycode)punycode.hasOwnProperty(key)&&(freeExports[key]=punycode[key]);else root.punycode=punycode}(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],2:[function(_dereq_,module,exports){var log=_dereq_("./log");function cloneNode(node,javascriptEnabled){for(var clone=3===node.nodeType?document.createTextNode(node.nodeValue):node.cloneNode(!1),child=node.firstChild;child;)!0!==javascriptEnabled&&1===child.nodeType&&"SCRIPT"===child.nodeName||clone.appendChild(cloneNode(child,javascriptEnabled)),child=child.nextSibling;return 1===node.nodeType&&(clone._scrollTop=node.scrollTop,clone._scrollLeft=node.scrollLeft,"CANVAS"===node.nodeName?function(canvas,clonedCanvas){try{clonedCanvas&&(clonedCanvas.width=canvas.width,clonedCanvas.height=canvas.height,clonedCanvas.getContext("2d").putImageData(canvas.getContext("2d").getImageData(0,0,canvas.width,canvas.height),0,0))}catch(e){log("Unable to copy canvas content from",canvas,e)}}(node,clone):"TEXTAREA"!==node.nodeName&&"SELECT"!==node.nodeName||(clone.value=node.value)),clone}function initNode(node){if(1===node.nodeType){node.scrollTop=node._scrollTop,node.scrollLeft=node._scrollLeft;for(var child=node.firstChild;child;)initNode(child),child=child.nextSibling}}module.exports=function(ownerDocument,containerDocument,width,height,options,x,y){var documentElement=cloneNode(ownerDocument.documentElement,options.javascriptEnabled),container=containerDocument.createElement("iframe");return container.className="html2canvas-container",container.style.visibility="hidden",container.style.position="fixed",container.style.left="-10000px",container.style.top="0px",container.style.border="0",container.width=width,container.height=height,container.scrolling="no",containerDocument.body.appendChild(container),new Promise((function(resolve){var documentClone=container.contentWindow.document;container.contentWindow.onload=container.onload=function(){var interval=setInterval((function(){documentClone.body.childNodes.length>0&&(initNode(documentClone.documentElement),clearInterval(interval),"view"===options.type&&(container.contentWindow.scrollTo(x,y),!/(iPad|iPhone|iPod)/g.test(navigator.userAgent)||container.contentWindow.scrollY===y&&container.contentWindow.scrollX===x||(documentClone.documentElement.style.top=-y+"px",documentClone.documentElement.style.left=-x+"px",documentClone.documentElement.style.position="absolute")),resolve(container))}),50)},documentClone.open(),documentClone.write("<!DOCTYPE html><html></html>"),function(ownerDocument,x,y){!ownerDocument.defaultView||x===ownerDocument.defaultView.pageXOffset&&y===ownerDocument.defaultView.pageYOffset||ownerDocument.defaultView.scrollTo(x,y)}(ownerDocument,x,y),documentClone.replaceChild(documentClone.adoptNode(documentElement),documentClone.documentElement),documentClone.close()}))}},{"./log":13}],3:[function(_dereq_,module,exports){function Color(value){this.r=0,this.g=0,this.b=0,this.a=null;this.fromArray(value)||this.namedColor(value)||this.rgb(value)||this.rgba(value)||this.hex6(value)||this.hex3(value)}Color.prototype.darken=function(amount){var a=1-amount;return new Color([Math.round(this.r*a),Math.round(this.g*a),Math.round(this.b*a),this.a])},Color.prototype.isTransparent=function(){return 0===this.a},Color.prototype.isBlack=function(){return 0===this.r&&0===this.g&&0===this.b},Color.prototype.fromArray=function(array){return Array.isArray(array)&&(this.r=Math.min(array[0],255),this.g=Math.min(array[1],255),this.b=Math.min(array[2],255),array.length>3&&(this.a=array[3])),Array.isArray(array)};var _hex3=/^#([a-f0-9]{3})$/i;Color.prototype.hex3=function(value){var match;return null!==(match=value.match(_hex3))&&(this.r=parseInt(match[1][0]+match[1][0],16),this.g=parseInt(match[1][1]+match[1][1],16),this.b=parseInt(match[1][2]+match[1][2],16)),null!==match};var _hex6=/^#([a-f0-9]{6})$/i;Color.prototype.hex6=function(value){var match=null;return null!==(match=value.match(_hex6))&&(this.r=parseInt(match[1].substring(0,2),16),this.g=parseInt(match[1].substring(2,4),16),this.b=parseInt(match[1].substring(4,6),16)),null!==match};var _rgb=/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/;Color.prototype.rgb=function(value){var match;return null!==(match=value.match(_rgb))&&(this.r=Number(match[1]),this.g=Number(match[2]),this.b=Number(match[3])),null!==match};var _rgba=/^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d?\.?\d+)\s*\)$/;Color.prototype.rgba=function(value){var match;return null!==(match=value.match(_rgba))&&(this.r=Number(match[1]),this.g=Number(match[2]),this.b=Number(match[3]),this.a=Number(match[4])),null!==match},Color.prototype.toString=function(){return null!==this.a&&1!==this.a?"rgba("+[this.r,this.g,this.b,this.a].join(",")+")":"rgb("+[this.r,this.g,this.b].join(",")+")"},Color.prototype.namedColor=function(value){value=value.toLowerCase();var color=colors[value];if(color)this.r=color[0],this.g=color[1],this.b=color[2];else if("transparent"===value)return this.r=this.g=this.b=this.a=0,!0;return!!color},Color.prototype.isColor=!0;var colors={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]};module.exports=Color},{}],4:[function(_dereq_,module,exports){var Support=_dereq_("./support"),CanvasRenderer=_dereq_("./renderers/canvas"),ImageLoader=_dereq_("./imageloader"),NodeParser=_dereq_("./nodeparser"),NodeContainer=_dereq_("./nodecontainer"),log=_dereq_("./log"),utils=_dereq_("./utils"),createWindowClone=_dereq_("./clone"),loadUrlDocument=_dereq_("./proxy").loadUrlDocument,getBounds=utils.getBounds,html2canvasCloneIndex=0;function html2canvas(nodeList,options){var url,link,index=html2canvasCloneIndex++;if((options=options||{}).logging&&(log.options.logging=!0,log.options.start=Date.now()),options.async=void 0===options.async||options.async,options.allowTaint=void 0!==options.allowTaint&&options.allowTaint,options.removeContainer=void 0===options.removeContainer||options.removeContainer,options.javascriptEnabled=void 0!==options.javascriptEnabled&&options.javascriptEnabled,options.imageTimeout=void 0===options.imageTimeout?1e4:options.imageTimeout,options.renderer="function"==typeof options.renderer?options.renderer:CanvasRenderer,options.strict=!!options.strict,"string"==typeof nodeList){if("string"!=typeof options.proxy)return Promise.reject("Proxy must be used when rendering url");var width=null!=options.width?options.width:window.innerWidth,height=null!=options.height?options.height:window.innerHeight;return loadUrlDocument((url=nodeList,link=document.createElement("a"),link.href=url,link.href=link.href,link),options.proxy,document,width,height,options).then((function(container){return renderWindow(container.contentWindow.document.documentElement,container,options,width,height)}))}var node=(void 0===nodeList?[document.documentElement]:nodeList.length?nodeList:[nodeList])[0];return node.setAttribute("data-html2canvas-node"+index,index),function(document,options,windowWidth,windowHeight,html2canvasIndex){return createWindowClone(document,document,windowWidth,windowHeight,options,document.defaultView.pageXOffset,document.defaultView.pageYOffset).then((function(container){log("Document cloned");var attributeName="data-html2canvas-node"+html2canvasIndex,selector="["+attributeName+"='"+html2canvasIndex+"']";document.querySelector(selector).removeAttribute(attributeName);var clonedWindow=container.contentWindow,node=clonedWindow.document.querySelector(selector);return("function"==typeof options.onclone?Promise.resolve(options.onclone(clonedWindow.document)):Promise.resolve(!0)).then((function(){return renderWindow(node,container,options,windowWidth,windowHeight)}))}))}(node.ownerDocument,options,node.ownerDocument.defaultView.innerWidth,node.ownerDocument.defaultView.innerHeight,index).then((function(canvas){return"function"==typeof options.onrendered&&(log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas"),options.onrendered(canvas)),canvas}))}html2canvas.CanvasRenderer=CanvasRenderer,html2canvas.NodeContainer=NodeContainer,html2canvas.log=log,html2canvas.utils=utils;var html2canvasExport="undefined"==typeof document||"function"!=typeof Object.create||"function"!=typeof document.createElement("canvas").getContext?function(){return Promise.reject("No canvas support")}:html2canvas;function renderWindow(node,container,options,windowWidth,windowHeight){var doc,clonedWindow=container.contentWindow,support=new Support(clonedWindow.document),imageLoader=new ImageLoader(options,support),bounds=getBounds(node),width="view"===options.type?windowWidth:(doc=clonedWindow.document,Math.max(Math.max(doc.body.scrollWidth,doc.documentElement.scrollWidth),Math.max(doc.body.offsetWidth,doc.documentElement.offsetWidth),Math.max(doc.body.clientWidth,doc.documentElement.clientWidth))),height="view"===options.type?windowHeight:function(doc){return Math.max(Math.max(doc.body.scrollHeight,doc.documentElement.scrollHeight),Math.max(doc.body.offsetHeight,doc.documentElement.offsetHeight),Math.max(doc.body.clientHeight,doc.documentElement.clientHeight))}(clonedWindow.document),renderer=new options.renderer(width,height,imageLoader,options,document);return new NodeParser(node,renderer,support,imageLoader,options).ready.then((function(){var canvas;return log("Finished rendering"),canvas="view"===options.type?crop(renderer.canvas,{width:renderer.canvas.width,height:renderer.canvas.height,top:0,left:0,x:0,y:0}):node===clonedWindow.document.body||node===clonedWindow.document.documentElement||null!=options.canvas?renderer.canvas:crop(renderer.canvas,{width:null!=options.width?options.width:bounds.width,height:null!=options.height?options.height:bounds.height,top:bounds.top,left:bounds.left,x:0,y:0}),function(container,options){options.removeContainer&&(container.parentNode.removeChild(container),log("Cleaned up container"))}(container,options),canvas}))}function crop(canvas,bounds){var croppedCanvas=document.createElement("canvas"),x1=Math.min(canvas.width-1,Math.max(0,bounds.left)),x2=Math.min(canvas.width,Math.max(1,bounds.left+bounds.width)),y1=Math.min(canvas.height-1,Math.max(0,bounds.top)),y2=Math.min(canvas.height,Math.max(1,bounds.top+bounds.height));croppedCanvas.width=bounds.width,croppedCanvas.height=bounds.height;var width=x2-x1,height=y2-y1;return log("Cropping canvas at:","left:",bounds.left,"top:",bounds.top,"width:",width,"height:",height),log("Resulting crop with width",bounds.width,"and height",bounds.height,"with x",x1,"and y",y1),croppedCanvas.getContext("2d").drawImage(canvas,x1,y1,width,height,bounds.x,bounds.y,width,height),croppedCanvas}module.exports=html2canvasExport},{"./clone":2,"./imageloader":11,"./log":13,"./nodecontainer":14,"./nodeparser":15,"./proxy":16,"./renderers/canvas":20,"./support":22,"./utils":26}],5:[function(_dereq_,module,exports){var log=_dereq_("./log"),smallImage=_dereq_("./utils").smallImage;module.exports=function DummyImageContainer(src){if(this.src=src,log("DummyImageContainer for",src),!this.promise||!this.image){log("Initiating DummyImageContainer"),DummyImageContainer.prototype.image=new Image;var image=this.image;DummyImageContainer.prototype.promise=new Promise((function(resolve,reject){image.onload=resolve,image.onerror=reject,image.src=smallImage(),!0===image.complete&&resolve(image)}))}}},{"./log":13,"./utils":26}],6:[function(_dereq_,module,exports){var smallImage=_dereq_("./utils").smallImage;module.exports=function(family,size){var baseline,middle,container=document.createElement("div"),img=document.createElement("img"),span=document.createElement("span");container.style.visibility="hidden",container.style.fontFamily=family,container.style.fontSize=size,container.style.margin=0,container.style.padding=0,document.body.appendChild(container),img.src=smallImage(),img.width=1,img.height=1,img.style.margin=0,img.style.padding=0,img.style.verticalAlign="baseline",span.style.fontFamily=family,span.style.fontSize=size,span.style.margin=0,span.style.padding=0,span.appendChild(document.createTextNode("Hidden Text")),container.appendChild(span),container.appendChild(img),baseline=img.offsetTop-span.offsetTop+1,container.removeChild(span),container.appendChild(document.createTextNode("Hidden Text")),container.style.lineHeight="normal",img.style.verticalAlign="super",middle=img.offsetTop-container.offsetTop+1,document.body.removeChild(container),this.baseline=baseline,this.lineWidth=1,this.middle=middle}},{"./utils":26}],7:[function(_dereq_,module,exports){var Font=_dereq_("./font");function FontMetrics(){this.data={}}FontMetrics.prototype.getMetrics=function(family,size){return void 0===this.data[family+"-"+size]&&(this.data[family+"-"+size]=new Font(family,size)),this.data[family+"-"+size]},module.exports=FontMetrics},{"./font":6}],8:[function(_dereq_,module,exports){var getBounds=_dereq_("./utils").getBounds,loadUrlDocument=_dereq_("./proxy").loadUrlDocument;function FrameContainer(container,sameOrigin,options){this.image=null,this.src=container;var self=this,bounds=getBounds(container);this.promise=(sameOrigin?new Promise((function(resolve){"about:blank"===container.contentWindow.document.URL||null==container.contentWindow.document.documentElement?container.contentWindow.onload=container.onload=function(){resolve(container)}:resolve(container)})):this.proxyLoad(options.proxy,bounds,options)).then((function(container){return _dereq_("./core")(container.contentWindow.document.documentElement,{type:"view",width:container.width,height:container.height,proxy:options.proxy,javascriptEnabled:options.javascriptEnabled,removeContainer:options.removeContainer,allowTaint:options.allowTaint,imageTimeout:options.imageTimeout/2})})).then((function(canvas){return self.image=canvas}))}FrameContainer.prototype.proxyLoad=function(proxy,bounds,options){var container=this.src;return loadUrlDocument(container.src,proxy,container.ownerDocument,bounds.width,bounds.height,options)},module.exports=FrameContainer},{"./core":4,"./proxy":16,"./utils":26}],9:[function(_dereq_,module,exports){function GradientContainer(imageData){this.src=imageData.value,this.colorStops=[],this.type=null,this.x0=.5,this.y0=.5,this.x1=.5,this.y1=.5,this.promise=Promise.resolve(!0)}GradientContainer.TYPES={LINEAR:1,RADIAL:2},GradientContainer.REGEXP_COLORSTOP=/^\s*(rgba?\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3}(?:,\s*[0-9\.]+)?\s*\)|[a-z]{3,20}|#[a-f0-9]{3,6})(?:\s+(\d{1,3}(?:\.\d+)?)(%|px)?)?(?:\s|$)/i,module.exports=GradientContainer},{}],10:[function(_dereq_,module,exports){module.exports=function(src,cors){this.src=src,this.image=new Image;var self=this;this.tainted=null,this.promise=new Promise((function(resolve,reject){self.image.onload=resolve,self.image.onerror=reject,cors&&(self.image.crossOrigin="anonymous"),self.image.src=src,!0===self.image.complete&&resolve(self.image)}))}},{}],11:[function(_dereq_,module,exports){var log=_dereq_("./log"),ImageContainer=_dereq_("./imagecontainer"),DummyImageContainer=_dereq_("./dummyimagecontainer"),ProxyImageContainer=_dereq_("./proxyimagecontainer"),FrameContainer=_dereq_("./framecontainer"),SVGContainer=_dereq_("./svgcontainer"),SVGNodeContainer=_dereq_("./svgnodecontainer"),LinearGradientContainer=_dereq_("./lineargradientcontainer"),WebkitGradientContainer=_dereq_("./webkitgradientcontainer"),bind=_dereq_("./utils").bind;function ImageLoader(options,support){this.link=null,this.options=options,this.support=support,this.origin=this.getOrigin(window.location.href)}ImageLoader.prototype.findImages=function(nodes){var images=[];return nodes.reduce((function(imageNodes,container){switch(container.node.nodeName){case"IMG":return imageNodes.concat([{args:[container.node.src],method:"url"}]);case"svg":case"IFRAME":return imageNodes.concat([{args:[container.node],method:container.node.nodeName}])}return imageNodes}),[]).forEach(this.addImage(images,this.loadImage),this),images},ImageLoader.prototype.findBackgroundImage=function(images,container){return container.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(images,this.loadImage),this),images},ImageLoader.prototype.addImage=function(images,callback){return function(newImage){newImage.args.forEach((function(image){this.imageExists(images,image)||(images.splice(0,0,callback.call(this,newImage)),log("Added image #"+images.length,"string"==typeof image?image.substring(0,100):image))}),this)}},ImageLoader.prototype.hasImageBackground=function(imageData){return"none"!==imageData.method},ImageLoader.prototype.loadImage=function(imageData){if("url"===imageData.method){var src=imageData.args[0];return!this.isSVG(src)||this.support.svg||this.options.allowTaint?src.match(/data:image\/.*;base64,/i)?new ImageContainer(src.replace(/url\(['"]{0,}|['"]{0,}\)$/gi,""),!1):this.isSameOrigin(src)||!0===this.options.allowTaint||this.isSVG(src)?new ImageContainer(src,!1):this.support.cors&&!this.options.allowTaint&&this.options.useCORS?new ImageContainer(src,!0):this.options.proxy?new ProxyImageContainer(src,this.options.proxy):new DummyImageContainer(src):new SVGContainer(src)}return"linear-gradient"===imageData.method?new LinearGradientContainer(imageData):"gradient"===imageData.method?new WebkitGradientContainer(imageData):"svg"===imageData.method?new SVGNodeContainer(imageData.args[0],this.support.svg):"IFRAME"===imageData.method?new FrameContainer(imageData.args[0],this.isSameOrigin(imageData.args[0].src),this.options):new DummyImageContainer(imageData)},ImageLoader.prototype.isSVG=function(src){return"svg"===src.substring(src.length-3).toLowerCase()||SVGContainer.prototype.isInline(src)},ImageLoader.prototype.imageExists=function(images,src){return images.some((function(image){return image.src===src}))},ImageLoader.prototype.isSameOrigin=function(url){return this.getOrigin(url)===this.origin},ImageLoader.prototype.getOrigin=function(url){var link=this.link||(this.link=document.createElement("a"));return link.href=url,link.href=link.href,link.protocol+link.hostname+link.port},ImageLoader.prototype.getPromise=function(container){return this.timeout(container,this.options.imageTimeout).catch((function(){return new DummyImageContainer(container.src).promise.then((function(image){container.image=image}))}))},ImageLoader.prototype.get=function(src){var found=null;return this.images.some((function(img){return(found=img).src===src}))?found:null},ImageLoader.prototype.fetch=function(nodes){return this.images=nodes.reduce(bind(this.findBackgroundImage,this),this.findImages(nodes)),this.images.forEach((function(image,index){image.promise.then((function(){log("Succesfully loaded image #"+(index+1),image)}),(function(e){log("Failed loading image #"+(index+1),image,e)}))})),this.ready=Promise.all(this.images.map(this.getPromise,this)),log("Finished searching images"),this},ImageLoader.prototype.timeout=function(container,timeout){var timer,promise=Promise.race([container.promise,new Promise((function(res,reject){timer=setTimeout((function(){log("Timed out loading image",container),reject(container)}),timeout)}))]).then((function(container){return clearTimeout(timer),container}));return promise.catch((function(){clearTimeout(timer)})),promise},module.exports=ImageLoader},{"./dummyimagecontainer":5,"./framecontainer":8,"./imagecontainer":10,"./lineargradientcontainer":12,"./log":13,"./proxyimagecontainer":17,"./svgcontainer":23,"./svgnodecontainer":24,"./utils":26,"./webkitgradientcontainer":27}],12:[function(_dereq_,module,exports){var GradientContainer=_dereq_("./gradientcontainer"),Color=_dereq_("./color");function LinearGradientContainer(imageData){GradientContainer.apply(this,arguments),this.type=GradientContainer.TYPES.LINEAR;var hasDirection=LinearGradientContainer.REGEXP_DIRECTION.test(imageData.args[0])||!GradientContainer.REGEXP_COLORSTOP.test(imageData.args[0]);hasDirection?imageData.args[0].split(/\s+/).reverse().forEach((function(position,index){switch(position){case"left":this.x0=0,this.x1=1;break;case"top":this.y0=0,this.y1=1;break;case"right":this.x0=1,this.x1=0;break;case"bottom":this.y0=1,this.y1=0;break;case"to":var y0=this.y0,x0=this.x0;this.y0=this.y1,this.x0=this.x1,this.x1=x0,this.y1=y0;break;case"center":break;default:var ratio=.01*parseFloat(position,10);if(isNaN(ratio))break;0===index?(this.y0=ratio,this.y1=1-this.y0):(this.x0=ratio,this.x1=1-this.x0)}}),this):(this.y0=0,this.y1=1),this.colorStops=imageData.args.slice(hasDirection?1:0).map((function(colorStop){var colorStopMatch=colorStop.match(GradientContainer.REGEXP_COLORSTOP),value=+colorStopMatch[2],unit=0===value?"%":colorStopMatch[3];return{color:new Color(colorStopMatch[1]),stop:"%"===unit?value/100:null}})),null===this.colorStops[0].stop&&(this.colorStops[0].stop=0),null===this.colorStops[this.colorStops.length-1].stop&&(this.colorStops[this.colorStops.length-1].stop=1),this.colorStops.forEach((function(colorStop,index){null===colorStop.stop&&this.colorStops.slice(index).some((function(find,count){return null!==find.stop&&(colorStop.stop=(find.stop-this.colorStops[index-1].stop)/(count+1)+this.colorStops[index-1].stop,!0)}),this)}),this)}LinearGradientContainer.prototype=Object.create(GradientContainer.prototype),LinearGradientContainer.REGEXP_DIRECTION=/^\s*(?:to|left|right|top|bottom|center|\d{1,3}(?:\.\d+)?%?)(?:\s|$)/i,module.exports=LinearGradientContainer},{"./color":3,"./gradientcontainer":9}],13:[function(_dereq_,module,exports){var logger=function logger(){logger.options.logging&&window.console&&window.console.log&&Function.prototype.bind.call(window.console.log,window.console).apply(window.console,[Date.now()-logger.options.start+"ms","html2canvas:"].concat([].slice.call(arguments,0)))};logger.options={logging:!1},module.exports=logger},{}],14:[function(_dereq_,module,exports){var Color=_dereq_("./color"),utils=_dereq_("./utils"),getBounds=utils.getBounds,parseBackgrounds=utils.parseBackgrounds,offsetBounds=utils.offsetBounds;function NodeContainer(node,parent){this.node=node,this.parent=parent,this.stack=null,this.bounds=null,this.borders=null,this.clip=[],this.backgroundClip=[],this.offsetBounds=null,this.visible=null,this.computedStyles=null,this.colors={},this.styles={},this.backgroundImages=null,this.transformData=null,this.transformMatrix=null,this.isPseudoElement=!1,this.opacity=null}function isPercentage(value){return-1!==value.toString().indexOf("%")}function removePx(str){return str.replace("px","")}function asFloat(str){return parseFloat(str)}NodeContainer.prototype.cloneTo=function(stack){stack.visible=this.visible,stack.borders=this.borders,stack.bounds=this.bounds,stack.clip=this.clip,stack.backgroundClip=this.backgroundClip,stack.computedStyles=this.computedStyles,stack.styles=this.styles,stack.backgroundImages=this.backgroundImages,stack.opacity=this.opacity},NodeContainer.prototype.getOpacity=function(){return null===this.opacity?this.opacity=this.cssFloat("opacity"):this.opacity},NodeContainer.prototype.assignStack=function(stack){this.stack=stack,stack.children.push(this)},NodeContainer.prototype.isElementVisible=function(){return this.node.nodeType===Node.TEXT_NODE?this.parent.visible:"none"!==this.css("display")&&"hidden"!==this.css("visibility")&&!this.node.hasAttribute("data-html2canvas-ignore")&&("INPUT"!==this.node.nodeName||"hidden"!==this.node.getAttribute("type"))},NodeContainer.prototype.css=function(attribute){return this.computedStyles||(this.computedStyles=this.isPseudoElement?this.parent.computedStyle(this.before?":before":":after"):this.computedStyle(null)),this.styles[attribute]||(this.styles[attribute]=this.computedStyles[attribute])},NodeContainer.prototype.prefixedCss=function(attribute){var value=this.css(attribute);return void 0===value&&["webkit","moz","ms","o"].some((function(prefix){return void 0!==(value=this.css(prefix+attribute.substr(0,1).toUpperCase()+attribute.substr(1)))}),this),void 0===value?null:value},NodeContainer.prototype.computedStyle=function(type){return this.node.ownerDocument.defaultView.getComputedStyle(this.node,type)},NodeContainer.prototype.cssInt=function(attribute){var value=parseInt(this.css(attribute),10);return isNaN(value)?0:value},NodeContainer.prototype.color=function(attribute){return this.colors[attribute]||(this.colors[attribute]=new Color(this.css(attribute)))},NodeContainer.prototype.cssFloat=function(attribute){var value=parseFloat(this.css(attribute));return isNaN(value)?0:value},NodeContainer.prototype.fontWeight=function(){var weight=this.css("fontWeight");switch(parseInt(weight,10)){case 401:weight="bold";break;case 400:weight="normal"}return weight},NodeContainer.prototype.parseClip=function(){var matches=this.css("clip").match(this.CLIP);return matches?{top:parseInt(matches[1],10),right:parseInt(matches[2],10),bottom:parseInt(matches[3],10),left:parseInt(matches[4],10)}:null},NodeContainer.prototype.parseBackgroundImages=function(){return this.backgroundImages||(this.backgroundImages=parseBackgrounds(this.css("backgroundImage")))},NodeContainer.prototype.cssList=function(property,index){var value=(this.css(property)||"").split(",");return 1===(value=(value=value[index||0]||value[0]||"auto").trim().split(" ")).length&&(value=[value[0],isPercentage(value[0])?"auto":value[0]]),value},NodeContainer.prototype.parseBackgroundSize=function(bounds,image,index){var width,height,size=this.cssList("backgroundSize",index);if(isPercentage(size[0]))width=bounds.width*parseFloat(size[0])/100;else{if(/contain|cover/.test(size[0])){var targetRatio=bounds.width/bounds.height,currentRatio=image.width/image.height;return targetRatio<currentRatio^"contain"===size[0]?{width:bounds.height*currentRatio,height:bounds.height}:{width:bounds.width,height:bounds.width/currentRatio}}width=parseInt(size[0],10)}return height="auto"===size[0]&&"auto"===size[1]?image.height:"auto"===size[1]?width/image.width*image.height:isPercentage(size[1])?bounds.height*parseFloat(size[1])/100:parseInt(size[1],10),"auto"===size[0]&&(width=height/image.height*image.width),{width:width,height:height}},NodeContainer.prototype.parseBackgroundPosition=function(bounds,image,index,backgroundSize){var left,top,position=this.cssList("backgroundPosition",index);return left=isPercentage(position[0])?(bounds.width-(backgroundSize||image).width)*(parseFloat(position[0])/100):parseInt(position[0],10),top="auto"===position[1]?left/image.width*image.height:isPercentage(position[1])?(bounds.height-(backgroundSize||image).height)*parseFloat(position[1])/100:parseInt(position[1],10),"auto"===position[0]&&(left=top/image.height*image.width),{left:left,top:top}},NodeContainer.prototype.parseBackgroundRepeat=function(index){return this.cssList("backgroundRepeat",index)[0]},NodeContainer.prototype.parseTextShadows=function(){var textShadow=this.css("textShadow"),results=[];if(textShadow&&"none"!==textShadow)for(var shadows=textShadow.match(this.TEXT_SHADOW_PROPERTY),i=0;shadows&&i<shadows.length;i++){var s=shadows[i].match(this.TEXT_SHADOW_VALUES);results.push({color:new Color(s[0]),offsetX:s[1]?parseFloat(s[1].replace("px","")):0,offsetY:s[2]?parseFloat(s[2].replace("px","")):0,blur:s[3]?s[3].replace("px",""):0})}return results},NodeContainer.prototype.parseTransform=function(){if(!this.transformData)if(this.hasTransform()){var offset=this.parseBounds(),origin=this.prefixedCss("transformOrigin").split(" ").map(removePx).map(asFloat);origin[0]+=offset.left,origin[1]+=offset.top,this.transformData={origin:origin,matrix:this.parseTransformMatrix()}}else this.transformData={origin:[0,0],matrix:[1,0,0,1,0,0]};return this.transformData},NodeContainer.prototype.parseTransformMatrix=function(){if(!this.transformMatrix){var transform=this.prefixedCss("transform"),matrix=transform?function(match){if(match&&"matrix"===match[1])return match[2].split(",").map((function(s){return parseFloat(s.trim())}));if(match&&"matrix3d"===match[1]){var matrix3d=match[2].split(",").map((function(s){return parseFloat(s.trim())}));return[matrix3d[0],matrix3d[1],matrix3d[4],matrix3d[5],matrix3d[12],matrix3d[13]]}}(transform.match(this.MATRIX_PROPERTY)):null;this.transformMatrix=matrix||[1,0,0,1,0,0]}return this.transformMatrix},NodeContainer.prototype.parseBounds=function(){return this.bounds||(this.bounds=this.hasTransform()?offsetBounds(this.node):getBounds(this.node))},NodeContainer.prototype.hasTransform=function(){return"1,0,0,1,0,0"!==this.parseTransformMatrix().join(",")||this.parent&&this.parent.hasTransform()},NodeContainer.prototype.getValue=function(){var node,option,value=this.node.value||"";return"SELECT"===this.node.tagName?(node=this.node,value=(option=node.options[node.selectedIndex||0])&&option.text||""):"password"===this.node.type&&(value=Array(value.length+1).join("•")),0===value.length?this.node.placeholder||"":value},NodeContainer.prototype.MATRIX_PROPERTY=/(matrix|matrix3d)\((.+)\)/,NodeContainer.prototype.TEXT_SHADOW_PROPERTY=/((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g,NodeContainer.prototype.TEXT_SHADOW_VALUES=/(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g,NodeContainer.prototype.CLIP=/^rect\((\d+)px,? (\d+)px,? (\d+)px,? (\d+)px\)$/,module.exports=NodeContainer},{"./color":3,"./utils":26}],15:[function(_dereq_,module,exports){var log=_dereq_("./log"),punycode=_dereq_("punycode"),NodeContainer=_dereq_("./nodecontainer"),TextContainer=_dereq_("./textcontainer"),PseudoElementContainer=_dereq_("./pseudoelementcontainer"),FontMetrics=_dereq_("./fontmetrics"),Color=_dereq_("./color"),StackingContext=_dereq_("./stackingcontext"),utils=_dereq_("./utils"),bind=utils.bind,getBounds=utils.getBounds,parseBackgrounds=utils.parseBackgrounds,offsetBounds=utils.offsetBounds;function NodeParser(element,renderer,support,imageLoader,options){log("Starting NodeParser"),this.renderer=renderer,this.options=options,this.range=null,this.support=support,this.renderQueue=[],this.stack=new StackingContext(!0,1,element.ownerDocument,null);var parent=new NodeContainer(element,null);if(options.background&&renderer.rectangle(0,0,renderer.width,renderer.height,new Color(options.background)),element===element.ownerDocument.documentElement){var canvasBackground=new NodeContainer(parent.color("backgroundColor").isTransparent()?element.ownerDocument.body:element.ownerDocument.documentElement,null);renderer.rectangle(0,0,renderer.width,renderer.height,canvasBackground.color("backgroundColor"))}parent.visibile=parent.isElementVisible(),this.createPseudoHideStyles(element.ownerDocument),this.disableAnimations(element.ownerDocument),this.nodes=flatten([parent].concat(this.getChildren(parent)).filter((function(container){return container.visible=container.isElementVisible()})).map(this.getPseudoElements,this)),this.fontMetrics=new FontMetrics,log("Fetched nodes, total:",this.nodes.length),log("Calculate overflow clips"),this.calculateOverflowClips(),log("Start fetching images"),this.images=imageLoader.fetch(this.nodes.filter(isElement)),this.ready=this.images.ready.then(bind((function(){return log("Images loaded, starting parsing"),log("Creating stacking contexts"),this.createStackingContexts(),log("Sorting stacking contexts"),this.sortStackingContexts(this.stack),this.parse(this.stack),log("Render queue created with "+this.renderQueue.length+" items"),new Promise(bind((function(resolve){options.async?"function"==typeof options.async?options.async.call(this,this.renderQueue,resolve):this.renderQueue.length>0?(this.renderIndex=0,this.asyncRenderer(this.renderQueue,resolve)):resolve():(this.renderQueue.forEach(this.paint,this),resolve())}),this))}),this))}function hasParentClip(container){return container.parent&&container.parent.clip.length}function ClearTransform(){}NodeParser.prototype.calculateOverflowClips=function(){this.nodes.forEach((function(container){if(isElement(container)){isPseudoElement(container)&&container.appendToDOM(),container.borders=this.parseBorders(container);var clip="hidden"===container.css("overflow")?[container.borders.clip]:[],cssClip=container.parseClip();cssClip&&-1!==["absolute","fixed"].indexOf(container.css("position"))&&clip.push([["rect",container.bounds.left+cssClip.left,container.bounds.top+cssClip.top,cssClip.right-cssClip.left,cssClip.bottom-cssClip.top]]),container.clip=hasParentClip(container)?container.parent.clip.concat(clip):clip,container.backgroundClip="hidden"!==container.css("overflow")?container.clip.concat([container.borders.clip]):container.clip,isPseudoElement(container)&&container.cleanDOM()}else isTextNode(container)&&(container.clip=hasParentClip(container)?container.parent.clip:[]);isPseudoElement(container)||(container.bounds=null)}),this)},NodeParser.prototype.asyncRenderer=function(queue,resolve,asyncTimer){asyncTimer=asyncTimer||Date.now(),this.paint(queue[this.renderIndex++]),queue.length===this.renderIndex?resolve():asyncTimer+20>Date.now()?this.asyncRenderer(queue,resolve,asyncTimer):setTimeout(bind((function(){this.asyncRenderer(queue,resolve)}),this),0)},NodeParser.prototype.createPseudoHideStyles=function(document){this.createStyles(document,"."+PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE+':before { content: "" !important; display: none !important; }.'+PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER+':after { content: "" !important; display: none !important; }')},NodeParser.prototype.disableAnimations=function(document){this.createStyles(document,"* { -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; animation: none !important; -webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important;}")},NodeParser.prototype.createStyles=function(document,styles){var hidePseudoElements=document.createElement("style");hidePseudoElements.innerHTML=styles,document.body.appendChild(hidePseudoElements)},NodeParser.prototype.getPseudoElements=function(container){var nodes=[[container]];if(container.node.nodeType===Node.ELEMENT_NODE){var before=this.getPseudoElement(container,":before"),after=this.getPseudoElement(container,":after");before&&nodes.push(before),after&&nodes.push(after)}return flatten(nodes)},NodeParser.prototype.getPseudoElement=function(container,type){var style=container.computedStyle(type);if(!style||!style.content||"none"===style.content||"-moz-alt-content"===style.content||"none"===style.display)return null;for(var content=function(content){var first=content.substr(0,1);return first===content.substr(content.length-1)&&first.match(/'|"/)?content.substr(1,content.length-2):content}(style.content),isImage="url"===content.substr(0,3),pseudoNode=document.createElement(isImage?"img":"html2canvaspseudoelement"),pseudoContainer=new PseudoElementContainer(pseudoNode,container,type),i=style.length-1;i>=0;i--){var property=style.item(i).replace(/(\-[a-z])/g,(function(match){return match.toUpperCase().replace("-","")}));pseudoNode.style[property]=style[property]}if(pseudoNode.className=PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE+" "+PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER,isImage)return pseudoNode.src=parseBackgrounds(content)[0].args[0],[pseudoContainer];var text=document.createTextNode(content);return pseudoNode.appendChild(text),[pseudoContainer,new TextContainer(text,pseudoContainer)]},NodeParser.prototype.getChildren=function(parentContainer){return flatten([].filter.call(parentContainer.node.childNodes,renderableNode).map((function(node){var container=[node.nodeType===Node.TEXT_NODE?new TextContainer(node,parentContainer):new NodeContainer(node,parentContainer)].filter(nonIgnoredElement);return node.nodeType===Node.ELEMENT_NODE&&container.length&&"TEXTAREA"!==node.tagName?container[0].isElementVisible()?container.concat(this.getChildren(container[0])):[]:container}),this))},NodeParser.prototype.newStackingContext=function(container,hasOwnStacking){var stack=new StackingContext(hasOwnStacking,container.getOpacity(),container.node,container.parent);container.cloneTo(stack),(hasOwnStacking?stack.getParentStack(this):stack.parent.stack).contexts.push(stack),container.stack=stack},NodeParser.prototype.createStackingContexts=function(){this.nodes.forEach((function(container){isElement(container)&&(this.isRootElement(container)||function(container){return container.getOpacity()<1}(container)||function(container){var position=container.css("position");return"auto"!==(-1!==["absolute","relative","fixed"].indexOf(position)?container.css("zIndex"):"auto")}(container)||this.isBodyWithTransparentRoot(container)||container.hasTransform())?this.newStackingContext(container,!0):isElement(container)&&(isPositioned(container)&&zIndex0(container)||function(container){return-1!==["inline-block","inline-table"].indexOf(container.css("display"))}(container)||isFloating(container))?this.newStackingContext(container,!1):container.assignStack(container.parent.stack)}),this)},NodeParser.prototype.isBodyWithTransparentRoot=function(container){return"BODY"===container.node.nodeName&&container.parent.color("backgroundColor").isTransparent()},NodeParser.prototype.isRootElement=function(container){return null===container.parent},NodeParser.prototype.sortStackingContexts=function(stack){var contexts;stack.contexts.sort((contexts=stack.contexts.slice(0),function(a,b){return a.cssInt("zIndex")+contexts.indexOf(a)/contexts.length-(b.cssInt("zIndex")+contexts.indexOf(b)/contexts.length)})),stack.contexts.forEach(this.sortStackingContexts,this)},NodeParser.prototype.parseTextBounds=function(container){return function(text,index,textList){if("none"!==container.parent.css("textDecoration").substr(0,4)||0!==text.trim().length){if(this.support.rangeBounds&&!container.parent.hasTransform()){var offset=textList.slice(0,index).join("").length;return this.getRangeBounds(container.node,offset,text.length)}if(container.node&&"string"==typeof container.node.data){var replacementNode=container.node.splitText(text.length),bounds=this.getWrapperBounds(container.node,container.parent.hasTransform());return container.node=replacementNode,bounds}}else this.support.rangeBounds&&!container.parent.hasTransform()||(container.node=container.node.splitText(text.length));return{}}},NodeParser.prototype.getWrapperBounds=function(node,transform){var wrapper=node.ownerDocument.createElement("html2canvaswrapper"),parent=node.parentNode,backupText=node.cloneNode(!0);wrapper.appendChild(node.cloneNode(!0)),parent.replaceChild(wrapper,node);var bounds=transform?offsetBounds(wrapper):getBounds(wrapper);return parent.replaceChild(backupText,wrapper),bounds},NodeParser.prototype.getRangeBounds=function(node,offset,length){var range=this.range||(this.range=node.ownerDocument.createRange());return range.setStart(node,offset),range.setEnd(node,offset+length),range.getBoundingClientRect()},NodeParser.prototype.parse=function(stack){var negativeZindex=stack.contexts.filter(negativeZIndex),descendantElements=stack.children.filter(isElement),descendantNonFloats=descendantElements.filter(not(isFloating)),nonInlineNonPositionedDescendants=descendantNonFloats.filter(not(isPositioned)).filter(not(inlineLevel)),nonPositionedFloats=descendantElements.filter(not(isPositioned)).filter(isFloating),inFlow=descendantNonFloats.filter(not(isPositioned)).filter(inlineLevel),stackLevel0=stack.contexts.concat(descendantNonFloats.filter(isPositioned)).filter(zIndex0),text=stack.children.filter(isTextNode).filter(hasText),positiveZindex=stack.contexts.filter(positiveZIndex);negativeZindex.concat(nonInlineNonPositionedDescendants).concat(nonPositionedFloats).concat(inFlow).concat(stackLevel0).concat(text).concat(positiveZindex).forEach((function(container){this.renderQueue.push(container),isStackingContext(container)&&(this.parse(container),this.renderQueue.push(new ClearTransform))}),this)},NodeParser.prototype.paint=function(container){try{container instanceof ClearTransform?this.renderer.ctx.restore():isTextNode(container)?(isPseudoElement(container.parent)&&container.parent.appendToDOM(),this.paintText(container),isPseudoElement(container.parent)&&container.parent.cleanDOM()):this.paintNode(container)}catch(e){if(log(e),this.options.strict)throw e}},NodeParser.prototype.paintNode=function(container){isStackingContext(container)&&(this.renderer.setOpacity(container.opacity),this.renderer.ctx.save(),container.hasTransform()&&this.renderer.setTransform(container.parseTransform())),"INPUT"===container.node.nodeName&&"checkbox"===container.node.type?this.paintCheckbox(container):"INPUT"===container.node.nodeName&&"radio"===container.node.type?this.paintRadio(container):this.paintElement(container)},NodeParser.prototype.paintElement=function(container){var bounds=container.parseBounds();this.renderer.clip(container.backgroundClip,(function(){this.renderer.renderBackground(container,bounds,container.borders.borders.map(getWidth))}),this),this.renderer.clip(container.clip,(function(){this.renderer.renderBorders(container.borders.borders)}),this),this.renderer.clip(container.backgroundClip,(function(){switch(container.node.nodeName){case"svg":case"IFRAME":var imgContainer=this.images.get(container.node);imgContainer?this.renderer.renderImage(container,bounds,container.borders,imgContainer):log("Error loading <"+container.node.nodeName+">",container.node);break;case"IMG":var imageContainer=this.images.get(container.node.src);imageContainer?this.renderer.renderImage(container,bounds,container.borders,imageContainer):log("Error loading <img>",container.node.src);break;case"CANVAS":this.renderer.renderImage(container,bounds,container.borders,{image:container.node});break;case"SELECT":case"INPUT":case"TEXTAREA":this.paintFormValue(container)}}),this)},NodeParser.prototype.paintCheckbox=function(container){var b=container.parseBounds(),size=Math.min(b.width,b.height),bounds={width:size-1,height:size-1,top:b.top,left:b.left},r=[3,3],radius=[r,r,r,r],borders=[1,1,1,1].map((function(w){return{color:new Color("#A5A5A5"),width:w}})),borderPoints=calculateCurvePoints(bounds,radius,borders);this.renderer.clip(container.backgroundClip,(function(){this.renderer.rectangle(bounds.left+1,bounds.top+1,bounds.width-2,bounds.height-2,new Color("#DEDEDE")),this.renderer.renderBorders(calculateBorders(borders,bounds,borderPoints,radius)),container.node.checked&&(this.renderer.font(new Color("#424242"),"normal","normal","bold",size-3+"px","arial"),this.renderer.text("✔",bounds.left+size/6,bounds.top+size-1))}),this)},NodeParser.prototype.paintRadio=function(container){var bounds=container.parseBounds(),size=Math.min(bounds.width,bounds.height)-2;this.renderer.clip(container.backgroundClip,(function(){this.renderer.circleStroke(bounds.left+1,bounds.top+1,size,new Color("#DEDEDE"),1,new Color("#A5A5A5")),container.node.checked&&this.renderer.circle(Math.ceil(bounds.left+size/4)+1,Math.ceil(bounds.top+size/4)+1,Math.floor(size/2),new Color("#424242"))}),this)},NodeParser.prototype.paintFormValue=function(container){var value=container.getValue();if(value.length>0){var document=container.node.ownerDocument,wrapper=document.createElement("html2canvaswrapper");["lineHeight","textAlign","fontFamily","fontWeight","fontSize","color","paddingLeft","paddingTop","paddingRight","paddingBottom","width","height","borderLeftStyle","borderTopStyle","borderLeftWidth","borderTopWidth","boxSizing","whiteSpace","wordWrap"].forEach((function(property){try{wrapper.style[property]=container.css(property)}catch(e){log("html2canvas: Parse: Exception caught in renderFormValue: "+e.message)}}));var bounds=container.parseBounds();wrapper.style.position="fixed",wrapper.style.left=bounds.left+"px",wrapper.style.top=bounds.top+"px",wrapper.textContent=value,document.body.appendChild(wrapper),this.paintText(new TextContainer(wrapper.firstChild,container)),document.body.removeChild(wrapper)}},NodeParser.prototype.paintText=function(container){container.applyTextTransform();var string,characters=punycode.ucs2.decode(container.node.data),textList=this.options.letterRendering&&!function(container){return/^(normal|none|0px)$/.test(container.parent.css("letterSpacing"))}(container)||(string=container.node.data,/[^\u0000-\u00ff]/.test(string))?characters.map((function(character){return punycode.ucs2.encode([character])})):function(characters){var word,words=[],i=0,onWordBoundary=!1;for(;characters.length;)isWordBoundary(characters[i])===onWordBoundary?((word=characters.splice(0,i)).length&&words.push(punycode.ucs2.encode(word)),onWordBoundary=!onWordBoundary,i=0):i++,i>=characters.length&&(word=characters.splice(0,i)).length&&words.push(punycode.ucs2.encode(word));return words}(characters),weight=container.parent.fontWeight(),size=container.parent.css("fontSize"),family=container.parent.css("fontFamily"),shadows=container.parent.parseTextShadows();this.renderer.font(container.parent.color("color"),container.parent.css("fontStyle"),container.parent.css("fontVariant"),weight,size,family),shadows.length?this.renderer.fontShadow(shadows[0].color,shadows[0].offsetX,shadows[0].offsetY,shadows[0].blur):this.renderer.clearShadow(),this.renderer.clip(container.parent.clip,(function(){textList.map(this.parseTextBounds(container),this).forEach((function(bounds,index){bounds&&!1===/^\s*$/.test(textList[index])&&(this.renderer.text(textList[index],bounds.left,bounds.bottom),this.renderTextDecoration(container.parent,bounds,this.fontMetrics.getMetrics(family,size)))}),this)}),this)},NodeParser.prototype.renderTextDecoration=function(container,bounds,metrics){switch(container.css("textDecoration").split(" ")[0]){case"underline":this.renderer.rectangle(bounds.left,Math.round(bounds.top+metrics.baseline+metrics.lineWidth),bounds.width,1,container.color("color"));break;case"overline":this.renderer.rectangle(bounds.left,Math.round(bounds.top),bounds.width,1,container.color("color"));break;case"line-through":this.renderer.rectangle(bounds.left,Math.ceil(bounds.top+metrics.middle+metrics.lineWidth),bounds.width,1,container.color("color"))}};var borderColorTransforms={inset:[["darken",.6],["darken",.1],["darken",.1],["darken",.6]]};function calculateBorders(borders,nodeBounds,borderPoints,radius){return borders.map((function(border,borderSide){if(border.width>0){var bx=nodeBounds.left,by=nodeBounds.top,bw=nodeBounds.width,bh=nodeBounds.height-borders[2].width;switch(borderSide){case 0:bh=borders[0].width,border.args=drawSide({c1:[bx,by],c2:[bx+bw,by],c3:[bx+bw-borders[1].width,by+bh],c4:[bx+borders[3].width,by+bh]},radius[0],radius[1],borderPoints.topLeftOuter,borderPoints.topLeftInner,borderPoints.topRightOuter,borderPoints.topRightInner);break;case 1:bx=nodeBounds.left+nodeBounds.width-borders[1].width,bw=borders[1].width,border.args=drawSide({c1:[bx+bw,by],c2:[bx+bw,by+bh+borders[2].width],c3:[bx,by+bh],c4:[bx,by+borders[0].width]},radius[1],radius[2],borderPoints.topRightOuter,borderPoints.topRightInner,borderPoints.bottomRightOuter,borderPoints.bottomRightInner);break;case 2:by=by+nodeBounds.height-borders[2].width,bh=borders[2].width,border.args=drawSide({c1:[bx+bw,by+bh],c2:[bx,by+bh],c3:[bx+borders[3].width,by],c4:[bx+bw-borders[3].width,by]},radius[2],radius[3],borderPoints.bottomRightOuter,borderPoints.bottomRightInner,borderPoints.bottomLeftOuter,borderPoints.bottomLeftInner);break;case 3:bw=borders[3].width,border.args=drawSide({c1:[bx,by+bh+borders[2].width],c2:[bx,by],c3:[bx+bw,by+borders[0].width],c4:[bx+bw,by+bh]},radius[3],radius[0],borderPoints.bottomLeftOuter,borderPoints.bottomLeftInner,borderPoints.topLeftOuter,borderPoints.topLeftInner)}}return border}))}function getCurvePoints(x,y,r1,r2){var kappa=(Math.sqrt(2)-1)/3*4,ox=r1*kappa,oy=r2*kappa,xm=x+r1,ym=y+r2;return{topLeft:bezierCurve({x:x,y:ym},{x:x,y:ym-oy},{x:xm-ox,y:y},{x:xm,y:y}),topRight:bezierCurve({x:x,y:y},{x:x+ox,y:y},{x:xm,y:ym-oy},{x:xm,y:ym}),bottomRight:bezierCurve({x:xm,y:y},{x:xm,y:y+oy},{x:x+ox,y:ym},{x:x,y:ym}),bottomLeft:bezierCurve({x:xm,y:ym},{x:xm-ox,y:ym},{x:x,y:y+oy},{x:x,y:y})}}function calculateCurvePoints(bounds,borderRadius,borders){var x=bounds.left,y=bounds.top,width=bounds.width,height=bounds.height,tlh=borderRadius[0][0]<width/2?borderRadius[0][0]:width/2,tlv=borderRadius[0][1]<height/2?borderRadius[0][1]:height/2,trh=borderRadius[1][0]<width/2?borderRadius[1][0]:width/2,trv=borderRadius[1][1]<height/2?borderRadius[1][1]:height/2,brh=borderRadius[2][0]<width/2?borderRadius[2][0]:width/2,brv=borderRadius[2][1]<height/2?borderRadius[2][1]:height/2,blh=borderRadius[3][0]<width/2?borderRadius[3][0]:width/2,blv=borderRadius[3][1]<height/2?borderRadius[3][1]:height/2,topWidth=width-trh,rightHeight=height-brv,bottomWidth=width-brh,leftHeight=height-blv;return{topLeftOuter:getCurvePoints(x,y,tlh,tlv).topLeft.subdivide(.5),topLeftInner:getCurvePoints(x+borders[3].width,y+borders[0].width,Math.max(0,tlh-borders[3].width),Math.max(0,tlv-borders[0].width)).topLeft.subdivide(.5),topRightOuter:getCurvePoints(x+topWidth,y,trh,trv).topRight.subdivide(.5),topRightInner:getCurvePoints(x+Math.min(topWidth,width+borders[3].width),y+borders[0].width,topWidth>width+borders[3].width?0:trh-borders[3].width,trv-borders[0].width).topRight.subdivide(.5),bottomRightOuter:getCurvePoints(x+bottomWidth,y+rightHeight,brh,brv).bottomRight.subdivide(.5),bottomRightInner:getCurvePoints(x+Math.min(bottomWidth,width-borders[3].width),y+Math.min(rightHeight,height+borders[0].width),Math.max(0,brh-borders[1].width),brv-borders[2].width).bottomRight.subdivide(.5),bottomLeftOuter:getCurvePoints(x,y+leftHeight,blh,blv).bottomLeft.subdivide(.5),bottomLeftInner:getCurvePoints(x+borders[3].width,y+leftHeight,Math.max(0,blh-borders[3].width),blv-borders[2].width).bottomLeft.subdivide(.5)}}function bezierCurve(start,startControl,endControl,end){var lerp=function(a,b,t){return{x:a.x+(b.x-a.x)*t,y:a.y+(b.y-a.y)*t}};return{start:start,startControl:startControl,endControl:endControl,end:end,subdivide:function(t){var ab=lerp(start,startControl,t),bc=lerp(startControl,endControl,t),cd=lerp(endControl,end,t),abbc=lerp(ab,bc,t),bccd=lerp(bc,cd,t),dest=lerp(abbc,bccd,t);return[bezierCurve(start,ab,abbc,dest),bezierCurve(dest,bccd,cd,end)]},curveTo:function(borderArgs){borderArgs.push(["bezierCurve",startControl.x,startControl.y,endControl.x,endControl.y,end.x,end.y])},curveToReversed:function(borderArgs){borderArgs.push(["bezierCurve",endControl.x,endControl.y,startControl.x,startControl.y,start.x,start.y])}}}function drawSide(borderData,radius1,radius2,outer1,inner1,outer2,inner2){var borderArgs=[];return radius1[0]>0||radius1[1]>0?(borderArgs.push(["line",outer1[1].start.x,outer1[1].start.y]),outer1[1].curveTo(borderArgs)):borderArgs.push(["line",borderData.c1[0],borderData.c1[1]]),radius2[0]>0||radius2[1]>0?(borderArgs.push(["line",outer2[0].start.x,outer2[0].start.y]),outer2[0].curveTo(borderArgs),borderArgs.push(["line",inner2[0].end.x,inner2[0].end.y]),inner2[0].curveToReversed(borderArgs)):(borderArgs.push(["line",borderData.c2[0],borderData.c2[1]]),borderArgs.push(["line",borderData.c3[0],borderData.c3[1]])),radius1[0]>0||radius1[1]>0?(borderArgs.push(["line",inner1[1].end.x,inner1[1].end.y]),inner1[1].curveToReversed(borderArgs)):borderArgs.push(["line",borderData.c4[0],borderData.c4[1]]),borderArgs}function parseCorner(borderArgs,radius1,radius2,corner1,corner2,x,y){radius1[0]>0||radius1[1]>0?(borderArgs.push(["line",corner1[0].start.x,corner1[0].start.y]),corner1[0].curveTo(borderArgs),corner1[1].curveTo(borderArgs)):borderArgs.push(["line",x,y]),(radius2[0]>0||radius2[1]>0)&&borderArgs.push(["line",corner2[0].start.x,corner2[0].start.y])}function negativeZIndex(container){return container.cssInt("zIndex")<0}function positiveZIndex(container){return container.cssInt("zIndex")>0}function zIndex0(container){return 0===container.cssInt("zIndex")}function inlineLevel(container){return-1!==["inline","inline-block","inline-table"].indexOf(container.css("display"))}function isStackingContext(container){return container instanceof StackingContext}function hasText(container){return container.node.data.trim().length>0}function renderableNode(node){return node.nodeType===Node.TEXT_NODE||node.nodeType===Node.ELEMENT_NODE}function isPositioned(container){return"static"!==container.css("position")}function isFloating(container){return"none"!==container.css("float")}function not(callback){var context=this;return function(){return!callback.apply(context,arguments)}}function isElement(container){return container.node.nodeType===Node.ELEMENT_NODE}function isPseudoElement(container){return!0===container.isPseudoElement}function isTextNode(container){return container.node.nodeType===Node.TEXT_NODE}function asInt(value){return parseInt(value,10)}function getWidth(border){return border.width}function nonIgnoredElement(nodeContainer){return nodeContainer.node.nodeType!==Node.ELEMENT_NODE||-1===["SCRIPT","HEAD","TITLE","OBJECT","BR","OPTION"].indexOf(nodeContainer.node.nodeName)}function flatten(arrays){return[].concat.apply([],arrays)}function isWordBoundary(characterCode){return-1!==[32,13,10,9,45].indexOf(characterCode)}NodeParser.prototype.parseBorders=function(container){var nodeBounds=container.parseBounds(),radius=function(container){return["TopLeft","TopRight","BottomRight","BottomLeft"].map((function(side){var arr=container.css("border"+side+"Radius").split(" ");return arr.length<=1&&(arr[1]=arr[0]),arr.map(asInt)}))}(container),borders=["Top","Right","Bottom","Left"].map((function(side,index){var style=container.css("border"+side+"Style"),color=container.color("border"+side+"Color");"inset"===style&&color.isBlack()&&(color=new Color([255,255,255,color.a]));var colorTransform=borderColorTransforms[style]?borderColorTransforms[style][index]:null;return{width:container.cssInt("border"+side+"Width"),color:colorTransform?color[colorTransform[0]](colorTransform[1]):color,args:null}})),borderPoints=calculateCurvePoints(nodeBounds,radius,borders);return{clip:this.parseBackgroundClip(container,borderPoints,borders,radius,nodeBounds),borders:calculateBorders(borders,nodeBounds,borderPoints,radius)}},NodeParser.prototype.parseBackgroundClip=function(container,borderPoints,borders,radius,bounds){var borderArgs=[];switch(container.css("backgroundClip")){case"content-box":case"padding-box":parseCorner(borderArgs,radius[0],radius[1],borderPoints.topLeftInner,borderPoints.topRightInner,bounds.left+borders[3].width,bounds.top+borders[0].width),parseCorner(borderArgs,radius[1],radius[2],borderPoints.topRightInner,borderPoints.bottomRightInner,bounds.left+bounds.width-borders[1].width,bounds.top+borders[0].width),parseCorner(borderArgs,radius[2],radius[3],borderPoints.bottomRightInner,borderPoints.bottomLeftInner,bounds.left+bounds.width-borders[1].width,bounds.top+bounds.height-borders[2].width),parseCorner(borderArgs,radius[3],radius[0],borderPoints.bottomLeftInner,borderPoints.topLeftInner,bounds.left+borders[3].width,bounds.top+bounds.height-borders[2].width);break;default:parseCorner(borderArgs,radius[0],radius[1],borderPoints.topLeftOuter,borderPoints.topRightOuter,bounds.left,bounds.top),parseCorner(borderArgs,radius[1],radius[2],borderPoints.topRightOuter,borderPoints.bottomRightOuter,bounds.left+bounds.width,bounds.top),parseCorner(borderArgs,radius[2],radius[3],borderPoints.bottomRightOuter,borderPoints.bottomLeftOuter,bounds.left+bounds.width,bounds.top+bounds.height),parseCorner(borderArgs,radius[3],radius[0],borderPoints.bottomLeftOuter,borderPoints.topLeftOuter,bounds.left,bounds.top+bounds.height)}return borderArgs},module.exports=NodeParser},{"./color":3,"./fontmetrics":7,"./log":13,"./nodecontainer":14,"./pseudoelementcontainer":18,"./stackingcontext":21,"./textcontainer":25,"./utils":26,punycode:1}],16:[function(_dereq_,module,exports){var XHR=_dereq_("./xhr"),utils=_dereq_("./utils"),log=_dereq_("./log"),createWindowClone=_dereq_("./clone"),decode64=utils.decode64;function Proxy(src,proxyUrl,document){var supportsCORS="withCredentials"in new XMLHttpRequest;if(!proxyUrl)return Promise.reject("No proxy configured");var callback=createCallback(supportsCORS),url=createProxyUrl(proxyUrl,src,callback);return supportsCORS?XHR(url):jsonp(document,url,callback).then((function(response){return decode64(response.content)}))}var proxyCount=0;function jsonp(document,url,callback){return new Promise((function(resolve,reject){var s=document.createElement("script"),cleanup=function(){delete window.html2canvas.proxy[callback],document.body.removeChild(s)};window.html2canvas.proxy[callback]=function(response){cleanup(),resolve(response)},s.src=url,s.onerror=function(e){cleanup(),reject(e)},document.body.appendChild(s)}))}function createCallback(useCORS){return useCORS?"":"html2canvas_"+Date.now()+"_"+ ++proxyCount+"_"+Math.round(1e5*Math.random())}function createProxyUrl(proxyUrl,src,callback){return proxyUrl+"?url="+encodeURIComponent(src)+(callback.length?"&callback=html2canvas.proxy."+callback:"")}function documentFromHTML(src){return function(html){var doc,parser=new DOMParser;try{doc=parser.parseFromString(html,"text/html")}catch(e){log("DOMParser not supported, falling back to createHTMLDocument"),doc=document.implementation.createHTMLDocument("");try{doc.open(),doc.write(html),doc.close()}catch(ee){log("createHTMLDocument write not supported, falling back to document.body.innerHTML"),doc.body.innerHTML=html}}var b=doc.querySelector("base");if(!b||!b.href.host){var base=doc.createElement("base");base.href=src,doc.head.insertBefore(base,doc.head.firstChild)}return doc}}exports.Proxy=Proxy,exports.ProxyURL=function(src,proxyUrl,document){var supportsCORSImage="crossOrigin"in new Image,callback=createCallback(supportsCORSImage),url=createProxyUrl(proxyUrl,src,callback);return supportsCORSImage?Promise.resolve(url):jsonp(document,url,callback).then((function(response){return"data:"+response.type+";base64,"+response.content}))},exports.loadUrlDocument=function(src,proxy,document,width,height,options){return new Proxy(src,proxy,window.document).then(documentFromHTML(src)).then((function(doc){return createWindowClone(doc,document,width,height,options,0,0)}))}},{"./clone":2,"./log":13,"./utils":26,"./xhr":28}],17:[function(_dereq_,module,exports){var ProxyURL=_dereq_("./proxy").ProxyURL;module.exports=function(src,proxy){var link=document.createElement("a");link.href=src,src=link.href,this.src=src,this.image=new Image;var self=this;this.promise=new Promise((function(resolve,reject){self.image.crossOrigin="Anonymous",self.image.onload=resolve,self.image.onerror=reject,new ProxyURL(src,proxy,document).then((function(url){self.image.src=url})).catch(reject)}))}},{"./proxy":16}],18:[function(_dereq_,module,exports){var NodeContainer=_dereq_("./nodecontainer");function PseudoElementContainer(node,parent,type){NodeContainer.call(this,node,parent),this.isPseudoElement=!0,this.before=":before"===type}PseudoElementContainer.prototype.cloneTo=function(stack){PseudoElementContainer.prototype.cloneTo.call(this,stack),stack.isPseudoElement=!0,stack.before=this.before},PseudoElementContainer.prototype=Object.create(NodeContainer.prototype),PseudoElementContainer.prototype.appendToDOM=function(){this.before?this.parent.node.insertBefore(this.node,this.parent.node.firstChild):this.parent.node.appendChild(this.node),this.parent.node.className+=" "+this.getHideClass()},PseudoElementContainer.prototype.cleanDOM=function(){this.node.parentNode.removeChild(this.node),this.parent.node.className=this.parent.node.className.replace(this.getHideClass(),"")},PseudoElementContainer.prototype.getHideClass=function(){return this["PSEUDO_HIDE_ELEMENT_CLASS_"+(this.before?"BEFORE":"AFTER")]},PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE="___html2canvas___pseudoelement_before",PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER="___html2canvas___pseudoelement_after",module.exports=PseudoElementContainer},{"./nodecontainer":14}],19:[function(_dereq_,module,exports){var log=_dereq_("./log");function Renderer(width,height,images,options,document){this.width=width,this.height=height,this.images=images,this.options=options,this.document=document}Renderer.prototype.renderImage=function(container,bounds,borderData,imageContainer){var paddingLeft=container.cssInt("paddingLeft"),paddingTop=container.cssInt("paddingTop"),paddingRight=container.cssInt("paddingRight"),paddingBottom=container.cssInt("paddingBottom"),borders=borderData.borders,width=bounds.width-(borders[1].width+borders[3].width+paddingLeft+paddingRight),height=bounds.height-(borders[0].width+borders[2].width+paddingTop+paddingBottom);this.drawImage(imageContainer,0,0,imageContainer.image.width||width,imageContainer.image.height||height,bounds.left+paddingLeft+borders[3].width,bounds.top+paddingTop+borders[0].width,width,height)},Renderer.prototype.renderBackground=function(container,bounds,borderData){bounds.height>0&&bounds.width>0&&(this.renderBackgroundColor(container,bounds),this.renderBackgroundImage(container,bounds,borderData))},Renderer.prototype.renderBackgroundColor=function(container,bounds){var color=container.color("backgroundColor");color.isTransparent()||this.rectangle(bounds.left,bounds.top,bounds.width,bounds.height,color)},Renderer.prototype.renderBorders=function(borders){borders.forEach(this.renderBorder,this)},Renderer.prototype.renderBorder=function(data){data.color.isTransparent()||null===data.args||this.drawShape(data.args,data.color)},Renderer.prototype.renderBackgroundImage=function(container,bounds,borderData){container.parseBackgroundImages().reverse().forEach((function(backgroundImage,index,arr){switch(backgroundImage.method){case"url":var image=this.images.get(backgroundImage.args[0]);image?this.renderBackgroundRepeating(container,bounds,image,arr.length-(index+1),borderData):log("Error loading background-image",backgroundImage.args[0]);break;case"linear-gradient":case"gradient":var gradientImage=this.images.get(backgroundImage.value);gradientImage?this.renderBackgroundGradient(gradientImage,bounds,borderData):log("Error loading background-image",backgroundImage.args[0]);break;case"none":break;default:log("Unknown background-image type",backgroundImage.args[0])}}),this)},Renderer.prototype.renderBackgroundRepeating=function(container,bounds,imageContainer,index,borderData){var size=container.parseBackgroundSize(bounds,imageContainer.image,index),position=container.parseBackgroundPosition(bounds,imageContainer.image,index,size);switch(container.parseBackgroundRepeat(index)){case"repeat-x":case"repeat no-repeat":this.backgroundRepeatShape(imageContainer,position,size,bounds,bounds.left+borderData[3],bounds.top+position.top+borderData[0],99999,size.height,borderData);break;case"repeat-y":case"no-repeat repeat":this.backgroundRepeatShape(imageContainer,position,size,bounds,bounds.left+position.left+borderData[3],bounds.top+borderData[0],size.width,99999,borderData);break;case"no-repeat":this.backgroundRepeatShape(imageContainer,position,size,bounds,bounds.left+position.left+borderData[3],bounds.top+position.top+borderData[0],size.width,size.height,borderData);break;default:this.renderBackgroundRepeat(imageContainer,position,size,{top:bounds.top,left:bounds.left},borderData[3],borderData[0])}},module.exports=Renderer},{"./log":13}],20:[function(_dereq_,module,exports){var Renderer=_dereq_("../renderer"),LinearGradientContainer=_dereq_("../lineargradientcontainer"),log=_dereq_("../log");function CanvasRenderer(width,height){Renderer.apply(this,arguments),this.canvas=this.options.canvas||this.document.createElement("canvas"),this.options.canvas||(this.canvas.width=width,this.canvas.height=height),this.ctx=this.canvas.getContext("2d"),this.taintCtx=this.document.createElement("canvas").getContext("2d"),this.ctx.textBaseline="bottom",this.variables={},log("Initialized CanvasRenderer with size",width,"x",height)}function hasEntries(array){return array.length>0}CanvasRenderer.prototype=Object.create(Renderer.prototype),CanvasRenderer.prototype.setFillStyle=function(fillStyle){return this.ctx.fillStyle="object"===_typeof2(fillStyle)&&fillStyle.isColor?fillStyle.toString():fillStyle,this.ctx},CanvasRenderer.prototype.rectangle=function(left,top,width,height,color){this.setFillStyle(color).fillRect(left,top,width,height)},CanvasRenderer.prototype.circle=function(left,top,size,color){this.setFillStyle(color),this.ctx.beginPath(),this.ctx.arc(left+size/2,top+size/2,size/2,0,2*Math.PI,!0),this.ctx.closePath(),this.ctx.fill()},CanvasRenderer.prototype.circleStroke=function(left,top,size,color,stroke,strokeColor){this.circle(left,top,size,color),this.ctx.strokeStyle=strokeColor.toString(),this.ctx.stroke()},CanvasRenderer.prototype.drawShape=function(shape,color){this.shape(shape),this.setFillStyle(color).fill()},CanvasRenderer.prototype.taints=function(imageContainer){if(null===imageContainer.tainted){this.taintCtx.drawImage(imageContainer.image,0,0);try{this.taintCtx.getImageData(0,0,1,1),imageContainer.tainted=!1}catch(e){this.taintCtx=document.createElement("canvas").getContext("2d"),imageContainer.tainted=!0}}return imageContainer.tainted},CanvasRenderer.prototype.drawImage=function(imageContainer,sx,sy,sw,sh,dx,dy,dw,dh){this.taints(imageContainer)&&!this.options.allowTaint||this.ctx.drawImage(imageContainer.image,sx,sy,sw,sh,dx,dy,dw,dh)},CanvasRenderer.prototype.clip=function(shapes,callback,context){this.ctx.save(),shapes.filter(hasEntries).forEach((function(shape){this.shape(shape).clip()}),this),callback.call(context),this.ctx.restore()},CanvasRenderer.prototype.shape=function(shape){return this.ctx.beginPath(),shape.forEach((function(point,index){"rect"===point[0]?this.ctx.rect.apply(this.ctx,point.slice(1)):this.ctx[0===index?"moveTo":point[0]+"To"].apply(this.ctx,point.slice(1))}),this),this.ctx.closePath(),this.ctx},CanvasRenderer.prototype.font=function(color,style,variant,weight,size,family){this.setFillStyle(color).font=[style,variant,weight,size,family].join(" ").split(",")[0]},CanvasRenderer.prototype.fontShadow=function(color,offsetX,offsetY,blur){this.setVariable("shadowColor",color.toString()).setVariable("shadowOffsetY",offsetX).setVariable("shadowOffsetX",offsetY).setVariable("shadowBlur",blur)},CanvasRenderer.prototype.clearShadow=function(){this.setVariable("shadowColor","rgba(0,0,0,0)")},CanvasRenderer.prototype.setOpacity=function(opacity){this.ctx.globalAlpha=opacity},CanvasRenderer.prototype.setTransform=function(transform){this.ctx.translate(transform.origin[0],transform.origin[1]),this.ctx.transform.apply(this.ctx,transform.matrix),this.ctx.translate(-transform.origin[0],-transform.origin[1])},CanvasRenderer.prototype.setVariable=function(property,value){return this.variables[property]!==value&&(this.variables[property]=this.ctx[property]=value),this},CanvasRenderer.prototype.text=function(text,left,bottom){this.ctx.fillText(text,left,bottom)},CanvasRenderer.prototype.backgroundRepeatShape=function(imageContainer,backgroundPosition,size,bounds,left,top,width,height,borderData){var shape=[["line",Math.round(left),Math.round(top)],["line",Math.round(left+width),Math.round(top)],["line",Math.round(left+width),Math.round(height+top)],["line",Math.round(left),Math.round(height+top)]];this.clip([shape],(function(){this.renderBackgroundRepeat(imageContainer,backgroundPosition,size,bounds,borderData[3],borderData[0])}),this)},CanvasRenderer.prototype.renderBackgroundRepeat=function(imageContainer,backgroundPosition,size,bounds,borderLeft,borderTop){var offsetX=Math.round(bounds.left+backgroundPosition.left+borderLeft),offsetY=Math.round(bounds.top+backgroundPosition.top+borderTop);this.setFillStyle(this.ctx.createPattern(this.resizeImage(imageContainer,size),"repeat")),this.ctx.translate(offsetX,offsetY),this.ctx.fill(),this.ctx.translate(-offsetX,-offsetY)},CanvasRenderer.prototype.renderBackgroundGradient=function(gradientImage,bounds){if(gradientImage instanceof LinearGradientContainer){var gradient=this.ctx.createLinearGradient(bounds.left+bounds.width*gradientImage.x0,bounds.top+bounds.height*gradientImage.y0,bounds.left+bounds.width*gradientImage.x1,bounds.top+bounds.height*gradientImage.y1);gradientImage.colorStops.forEach((function(colorStop){gradient.addColorStop(colorStop.stop,colorStop.color.toString())})),this.rectangle(bounds.left,bounds.top,bounds.width,bounds.height,gradient)}},CanvasRenderer.prototype.resizeImage=function(imageContainer,size){var image=imageContainer.image;if(image.width===size.width&&image.height===size.height)return image;var canvas=document.createElement("canvas");return canvas.width=size.width,canvas.height=size.height,canvas.getContext("2d").drawImage(image,0,0,image.width,image.height,0,0,size.width,size.height),canvas},module.exports=CanvasRenderer},{"../lineargradientcontainer":12,"../log":13,"../renderer":19}],21:[function(_dereq_,module,exports){var NodeContainer=_dereq_("./nodecontainer");function StackingContext(hasOwnStacking,opacity,element,parent){NodeContainer.call(this,element,parent),this.ownStacking=hasOwnStacking,this.contexts=[],this.children=[],this.opacity=(this.parent?this.parent.stack.opacity:1)*opacity}StackingContext.prototype=Object.create(NodeContainer.prototype),StackingContext.prototype.getParentStack=function(context){var parentStack=this.parent?this.parent.stack:null;return parentStack?parentStack.ownStacking?parentStack:parentStack.getParentStack(context):context.stack},module.exports=StackingContext},{"./nodecontainer":14}],22:[function(_dereq_,module,exports){function Support(document){this.rangeBounds=this.testRangeBounds(document),this.cors=this.testCORS(),this.svg=this.testSVG()}Support.prototype.testRangeBounds=function(document){var range,testElement,support=!1;return document.createRange&&(range=document.createRange()).getBoundingClientRect&&((testElement=document.createElement("boundtest")).style.height="123px",testElement.style.display="block",document.body.appendChild(testElement),range.selectNode(testElement),123===range.getBoundingClientRect().height&&(support=!0),document.body.removeChild(testElement)),support},Support.prototype.testCORS=function(){return void 0!==(new Image).crossOrigin},Support.prototype.testSVG=function(){var img=new Image,canvas=document.createElement("canvas"),ctx=canvas.getContext("2d");img.src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>";try{ctx.drawImage(img,0,0),canvas.toDataURL()}catch(e){return!1}return!0},module.exports=Support},{}],23:[function(_dereq_,module,exports){var XHR=_dereq_("./xhr"),decode64=_dereq_("./utils").decode64;function SVGContainer(src){this.src=src,this.image=null;var self=this;this.promise=this.hasFabric().then((function(){return self.isInline(src)?Promise.resolve(self.inlineFormatting(src)):XHR(src)})).then((function(svg){return new Promise((function(resolve){window.html2canvas.svg.fabric.loadSVGFromString(svg,self.createCanvas.call(self,resolve))}))}))}SVGContainer.prototype.hasFabric=function(){return window.html2canvas.svg&&window.html2canvas.svg.fabric?Promise.resolve():Promise.reject(new Error("html2canvas.svg.js is not loaded, cannot render svg"))},SVGContainer.prototype.inlineFormatting=function(src){return/^data:image\/svg\+xml;base64,/.test(src)?this.decode64(this.removeContentType(src)):this.removeContentType(src)},SVGContainer.prototype.removeContentType=function(src){return src.replace(/^data:image\/svg\+xml(;base64)?,/,"")},SVGContainer.prototype.isInline=function(src){return/^data:image\/svg\+xml/i.test(src)},SVGContainer.prototype.createCanvas=function(resolve){var self=this;return function(objects,options){var canvas=new window.html2canvas.svg.fabric.StaticCanvas("c");self.image=canvas.lowerCanvasEl,canvas.setWidth(options.width).setHeight(options.height).add(window.html2canvas.svg.fabric.util.groupSVGElements(objects,options)).renderAll(),resolve(canvas.lowerCanvasEl)}},SVGContainer.prototype.decode64=function(str){return"function"==typeof window.atob?window.atob(str):decode64(str)},module.exports=SVGContainer},{"./utils":26,"./xhr":28}],24:[function(_dereq_,module,exports){var SVGContainer=_dereq_("./svgcontainer");function SVGNodeContainer(node,_native){this.src=node,this.image=null;var self=this;this.promise=_native?new Promise((function(resolve,reject){self.image=new Image,self.image.onload=resolve,self.image.onerror=reject,self.image.src="data:image/svg+xml,"+(new XMLSerializer).serializeToString(node),!0===self.image.complete&&resolve(self.image)})):this.hasFabric().then((function(){return new Promise((function(resolve){window.html2canvas.svg.fabric.parseSVGDocument(node,self.createCanvas.call(self,resolve))}))}))}SVGNodeContainer.prototype=Object.create(SVGContainer.prototype),module.exports=SVGNodeContainer},{"./svgcontainer":23}],25:[function(_dereq_,module,exports){var NodeContainer=_dereq_("./nodecontainer");function TextContainer(node,parent){NodeContainer.call(this,node,parent)}function capitalize(m,p1,p2){if(m.length>0)return p1+p2.toUpperCase()}TextContainer.prototype=Object.create(NodeContainer.prototype),TextContainer.prototype.applyTextTransform=function(){this.node.data=this.transform(this.parent.css("textTransform"))},TextContainer.prototype.transform=function(transform){var text=this.node.data;switch(transform){case"lowercase":return text.toLowerCase();case"capitalize":return text.replace(/(^|\s|:|-|\(|\))([a-z])/g,capitalize);case"uppercase":return text.toUpperCase();default:return text}},module.exports=TextContainer},{"./nodecontainer":14}],26:[function(_dereq_,module,exports){exports.smallImage=function(){return"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"},exports.bind=function(callback,context){return function(){return callback.apply(context,arguments)}},exports.decode64=function(base64){var i,encoded2,encoded3,encoded4,byte1,byte2,byte3,chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",len=base64.length,output="";for(i=0;i<len;i+=4)byte1=chars.indexOf(base64[i])<<2|(encoded2=chars.indexOf(base64[i+1]))>>4,byte2=(15&encoded2)<<4|(encoded3=chars.indexOf(base64[i+2]))>>2,byte3=(3&encoded3)<<6|(encoded4=chars.indexOf(base64[i+3])),output+=64===encoded3?String.fromCharCode(byte1):64===encoded4||-1===encoded4?String.fromCharCode(byte1,byte2):String.fromCharCode(byte1,byte2,byte3);return output},exports.getBounds=function(node){if(node.getBoundingClientRect){var clientRect=node.getBoundingClientRect(),width=null==node.offsetWidth?clientRect.width:node.offsetWidth;return{top:clientRect.top,bottom:clientRect.bottom||clientRect.top+clientRect.height,right:clientRect.left+width,left:clientRect.left,width:width,height:null==node.offsetHeight?clientRect.height:node.offsetHeight}}return{}},exports.offsetBounds=function(node){var parent=node.offsetParent?exports.offsetBounds(node.offsetParent):{top:0,left:0};return{top:node.offsetTop+parent.top,bottom:node.offsetTop+node.offsetHeight+parent.top,right:node.offsetLeft+parent.left+node.offsetWidth,left:node.offsetLeft+parent.left,width:node.offsetWidth,height:node.offsetHeight}},exports.parseBackgrounds=function(backgroundImage){var method,definition,prefix,prefix_i,block,quote,args,results=[],mode=0,numParen=0,appendResult=function(){method&&('"'===definition.substr(0,1)&&(definition=definition.substr(1,definition.length-2)),definition&&args.push(definition),"-"===method.substr(0,1)&&(prefix_i=method.indexOf("-",1)+1)>0&&(prefix=method.substr(0,prefix_i),method=method.substr(prefix_i)),results.push({prefix:prefix,method:method.toLowerCase(),value:block,args:args,image:null})),args=[],method=prefix=definition=block=""};return args=[],method=prefix=definition=block="",backgroundImage.split("").forEach((function(c){if(!(0===mode&&" \r\n\t".indexOf(c)>-1)){switch(c){case'"':quote?quote===c&&(quote=null):quote=c;break;case"(":if(quote)break;if(0===mode)return mode=1,void(block+=c);numParen++;break;case")":if(quote)break;if(1===mode){if(0===numParen)return mode=0,block+=c,void appendResult();numParen--}break;case",":if(quote)break;if(0===mode)return void appendResult();if(1===mode&&0===numParen&&!method.match(/^url$/i))return args.push(definition),definition="",void(block+=c)}block+=c,0===mode?method+=c:definition+=c}})),appendResult(),results}},{}],27:[function(_dereq_,module,exports){var GradientContainer=_dereq_("./gradientcontainer");function WebkitGradientContainer(imageData){GradientContainer.apply(this,arguments),this.type="linear"===imageData.args[0]?GradientContainer.TYPES.LINEAR:GradientContainer.TYPES.RADIAL}WebkitGradientContainer.prototype=Object.create(GradientContainer.prototype),module.exports=WebkitGradientContainer},{"./gradientcontainer":9}],28:[function(_dereq_,module,exports){module.exports=function(url){return new Promise((function(resolve,reject){var xhr=new XMLHttpRequest;xhr.open("GET",url),xhr.onload=function(){200===xhr.status?resolve(xhr.responseText):reject(new Error(xhr.statusText))},xhr.onerror=function(){reject(new Error("Network Error"))},xhr.send()}))}},{}]},{},[4])(4)})),function(jsPDF){var PLUS="+".charCodeAt(0),SLASH="/".charCodeAt(0),NUMBER="0".charCodeAt(0),LOWER="a".charCodeAt(0),UPPER="A".charCodeAt(0),PLUS_URL_SAFE="-".charCodeAt(0),SLASH_URL_SAFE="_".charCodeAt(0),decode=function(elt){var code=elt.charCodeAt(0);return code===PLUS||code===PLUS_URL_SAFE?62:code===SLASH||code===SLASH_URL_SAFE?63:code<NUMBER?-1:code<NUMBER+10?code-NUMBER+26+26:code<UPPER+26?code-UPPER:code<LOWER+26?code-LOWER+26:void 0};jsPDF.API.TTFFont=function(){function TTFFont(rawData,name,encoding){var data;if(this.rawData=rawData,data=this.contents=new Data(rawData),this.contents.pos=4,"ttcf"===data.readString(4)){if(!name)throw new Error("Must specify a font name for TTC files.");throw new Error("Font "+name+" not found in TTC file.")}data.pos=0,this.parse(),this.subset=new Subset(this),this.registerTTF()}return TTFFont.open=function(filename,name,vfs,encoding){return new TTFFont(function(b64){var i,j,l,tmp,placeHolders,arr;if(b64.length%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var len=b64.length;placeHolders="="===b64.charAt(len-2)?2:"="===b64.charAt(len-1)?1:0,arr=new Uint8Array(3*b64.length/4-placeHolders),l=placeHolders>0?b64.length-4:b64.length;var L=0;function push(v){arr[L++]=v}for(i=0,j=0;i<l;i+=4,j+=3)push((16711680&(tmp=decode(b64.charAt(i))<<18|decode(b64.charAt(i+1))<<12|decode(b64.charAt(i+2))<<6|decode(b64.charAt(i+3))))>>16),push((65280&tmp)>>8),push(255&tmp);return 2===placeHolders?push(255&(tmp=decode(b64.charAt(i))<<2|decode(b64.charAt(i+1))>>4)):1===placeHolders&&(push((tmp=decode(b64.charAt(i))<<10|decode(b64.charAt(i+1))<<4|decode(b64.charAt(i+2))>>2)>>8&255),push(255&tmp)),arr}(vfs),name,encoding)},TTFFont.prototype.parse=function(){return this.directory=new Directory(this.contents),this.head=new HeadTable(this),this.name=new NameTable(this),this.cmap=new CmapTable(this),this.hhea=new HheaTable(this),this.maxp=new MaxpTable(this),this.hmtx=new HmtxTable(this),this.post=new PostTable(this),this.os2=new OS2Table(this),this.loca=new LocaTable(this),this.glyf=new GlyfTable(this),this.ascender=this.os2.exists&&this.os2.ascender||this.hhea.ascender,this.decender=this.os2.exists&&this.os2.decender||this.hhea.decender,this.lineGap=this.os2.exists&&this.os2.lineGap||this.hhea.lineGap,this.bbox=[this.head.xMin,this.head.yMin,this.head.xMax,this.head.yMax]},TTFFont.prototype.registerTTF=function(){var e,hi,low,raw,_ref;if(this.scaleFactor=1e3/this.head.unitsPerEm,this.bbox=function(){var _i,_len,_ref,_results;for(_results=[],_i=0,_len=(_ref=this.bbox).length;_i<_len;_i++)e=_ref[_i],_results.push(Math.round(e*this.scaleFactor));return _results}.call(this),this.stemV=0,this.post.exists?(low=255&(raw=this.post.italic_angle),!0&(hi=raw>>16)&&(hi=-(1+(65535^hi))),this.italicAngle=+(hi+"."+low)):this.italicAngle=0,this.ascender=Math.round(this.ascender*this.scaleFactor),this.decender=Math.round(this.decender*this.scaleFactor),this.lineGap=Math.round(this.lineGap*this.scaleFactor),this.capHeight=this.os2.exists&&this.os2.capHeight||this.ascender,this.xHeight=this.os2.exists&&this.os2.xHeight||0,this.familyClass=(this.os2.exists&&this.os2.familyClass||0)>>8,this.isSerif=1===(_ref=this.familyClass)||2===_ref||3===_ref||4===_ref||5===_ref||7===_ref,this.isScript=10===this.familyClass,this.flags=0,this.post.isFixedPitch&&(this.flags|=1),this.isSerif&&(this.flags|=2),this.isScript&&(this.flags|=8),0!==this.italicAngle&&(this.flags|=64),this.flags|=32,!this.cmap.unicode)throw new Error("No unicode cmap for font")},TTFFont.prototype.characterToGlyph=function(character){var _ref;return(null!=(_ref=this.cmap.unicode)?_ref.codeMap[character]:void 0)||0},TTFFont.prototype.widthOfGlyph=function(glyph){var scale;return scale=1e3/this.head.unitsPerEm,this.hmtx.forGlyph(glyph).advance*scale},TTFFont.prototype.widthOfString=function(string,size,charSpace){var charCode,i,width,_i,_ref;for(width=0,i=_i=0,_ref=(string=""+string).length;0<=_ref?_i<_ref:_i>_ref;i=0<=_ref?++_i:--_i)charCode=string.charCodeAt(i),width+=this.widthOfGlyph(this.characterToGlyph(charCode))+charSpace*(1e3/size)||0;return width*(size/1e3)},TTFFont.prototype.lineHeight=function(size,includeGap){var gap;return null==includeGap&&(includeGap=!1),gap=includeGap?this.lineGap:0,(this.ascender+gap-this.decender)/1e3*size},TTFFont}();var Table,Data=function(){function Data(data){this.data=null!=data?data:[],this.pos=0,this.length=this.data.length}return Data.prototype.readByte=function(){return this.data[this.pos++]},Data.prototype.writeByte=function(byte){return this.data[this.pos++]=byte},Data.prototype.readUInt32=function(){return 16777216*this.readByte()+(this.readByte()<<16)+(this.readByte()<<8)+this.readByte()},Data.prototype.writeUInt32=function(val){return this.writeByte(val>>>24&255),this.writeByte(val>>16&255),this.writeByte(val>>8&255),this.writeByte(255&val)},Data.prototype.readInt32=function(){var int;return(int=this.readUInt32())>=2147483648?int-4294967296:int},Data.prototype.writeInt32=function(val){return val<0&&(val+=4294967296),this.writeUInt32(val)},Data.prototype.readUInt16=function(){return this.readByte()<<8|this.readByte()},Data.prototype.writeUInt16=function(val){return this.writeByte(val>>8&255),this.writeByte(255&val)},Data.prototype.readInt16=function(){var int;return(int=this.readUInt16())>=32768?int-65536:int},Data.prototype.writeInt16=function(val){return val<0&&(val+=65536),this.writeUInt16(val)},Data.prototype.readString=function(length){var i,ret,_i;for(ret=[],i=_i=0;0<=length?_i<length:_i>length;i=0<=length?++_i:--_i)ret[i]=String.fromCharCode(this.readByte());return ret.join("")},Data.prototype.writeString=function(val){var i,_i,_ref,_results;for(_results=[],i=_i=0,_ref=val.length;0<=_ref?_i<_ref:_i>_ref;i=0<=_ref?++_i:--_i)_results.push(this.writeByte(val.charCodeAt(i)));return _results},Data.prototype.readShort=function(){return this.readInt16()},Data.prototype.writeShort=function(val){return this.writeInt16(val)},Data.prototype.readLongLong=function(){var b1,b2,b3,b4,b5,b6,b7,b8;return b1=this.readByte(),b2=this.readByte(),b3=this.readByte(),b4=this.readByte(),b5=this.readByte(),b6=this.readByte(),b7=this.readByte(),b8=this.readByte(),128&b1?-1*(72057594037927940*(255^b1)+281474976710656*(255^b2)+1099511627776*(255^b3)+4294967296*(255^b4)+16777216*(255^b5)+65536*(255^b6)+256*(255^b7)+(255^b8)+1):72057594037927940*b1+281474976710656*b2+1099511627776*b3+4294967296*b4+16777216*b5+65536*b6+256*b7+b8},Data.prototype.readInt=function(){return this.readInt32()},Data.prototype.writeInt=function(val){return this.writeInt32(val)},Data.prototype.read=function(bytes){var buf,_i;for(buf=[],_i=0;0<=bytes?_i<bytes:_i>bytes;0<=bytes?++_i:--_i)buf.push(this.readByte());return buf},Data.prototype.write=function(bytes){var byte,_i,_len,_results;for(_results=[],_i=0,_len=bytes.length;_i<_len;_i++)byte=bytes[_i],_results.push(this.writeByte(byte));return _results},Data}(),Directory=function(){var checksum;function Directory(data){var entry,_i,_ref;for(this.scalarType=data.readInt(),this.tableCount=data.readShort(),this.searchRange=data.readShort(),this.entrySelector=data.readShort(),this.rangeShift=data.readShort(),this.tables={},_i=0,_ref=this.tableCount;0<=_ref?_i<_ref:_i>_ref;0<=_ref?++_i:--_i)entry={tag:data.readString(4),checksum:data.readInt(),offset:data.readInt(),length:data.readInt()},this.tables[entry.tag]=entry}return Directory.prototype.encode=function(tables){var adjustment,directory,directoryLength,entrySelector,headOffset,log2,offset,rangeShift,searchRange,table,tableCount,tableData,tag;for(tag in tableCount=Object.keys(tables).length,log2=Math.log(2),searchRange=16*Math.floor(Math.log(tableCount)/log2),entrySelector=Math.floor(searchRange/log2),rangeShift=16*tableCount-searchRange,(directory=new Data).writeInt(this.scalarType),directory.writeShort(tableCount),directory.writeShort(searchRange),directory.writeShort(entrySelector),directory.writeShort(rangeShift),directoryLength=16*tableCount,offset=directory.pos+directoryLength,headOffset=null,tableData=[],tables)for(table=tables[tag],directory.writeString(tag),directory.writeInt(checksum(table)),directory.writeInt(offset),directory.writeInt(table.length),tableData=tableData.concat(table),"head"===tag&&(headOffset=offset),offset+=table.length;offset%4;)tableData.push(0),offset++;return directory.write(tableData),adjustment=2981146554-checksum(directory.data),directory.pos=headOffset+8,directory.writeUInt32(adjustment),directory.data},checksum=function(data){var sum,tmp,_i,_ref;for(data=__slice.call(data);data.length%4;)data.push(0);for(tmp=new Data(data),sum=0,_i=0,_ref=data.length;_i<_ref;_i+=4)sum+=tmp.readUInt32();return 4294967295&sum},Directory}(),__hasProp={}.hasOwnProperty,__extends=function(child,parent){for(var key in parent)__hasProp.call(parent,key)&&(child[key]=parent[key]);function ctor(){this.constructor=child}return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},HeadTable=function(_super){function HeadTable(){return HeadTable.__super__.constructor.apply(this,arguments)}return __extends(HeadTable,_super),HeadTable.prototype.tag="head",HeadTable.prototype.parse=function(data){return data.pos=this.offset,this.version=data.readInt(),this.revision=data.readInt(),this.checkSumAdjustment=data.readInt(),this.magicNumber=data.readInt(),this.flags=data.readShort(),this.unitsPerEm=data.readShort(),this.created=data.readLongLong(),this.modified=data.readLongLong(),this.xMin=data.readShort(),this.yMin=data.readShort(),this.xMax=data.readShort(),this.yMax=data.readShort(),this.macStyle=data.readShort(),this.lowestRecPPEM=data.readShort(),this.fontDirectionHint=data.readShort(),this.indexToLocFormat=data.readShort(),this.glyphDataFormat=data.readShort()},HeadTable}(Table=function(){function Table(file){var info;this.file=file,info=this.file.directory.tables[this.tag],this.exists=!!info,info&&(this.offset=info.offset,this.length=info.length,this.parse(this.file.contents))}return Table.prototype.parse=function(){},Table.prototype.encode=function(){},Table.prototype.raw=function(){return this.exists?(this.file.contents.pos=this.offset,this.file.contents.read(this.length)):null},Table}()),CmapEntry=function(){function CmapEntry(data,offset){var code,count,endCode,glyphId,glyphIds,i,idDelta,idRangeOffset,saveOffset,segCount,segCountX2,start,startCode,tail,_i,_j,_k,_len;switch(this.platformID=data.readUInt16(),this.encodingID=data.readShort(),this.offset=offset+data.readInt(),saveOffset=data.pos,data.pos=this.offset,this.format=data.readUInt16(),this.length=data.readUInt16(),this.language=data.readUInt16(),this.isUnicode=3===this.platformID&&1===this.encodingID&&4===this.format||0===this.platformID&&4===this.format,this.codeMap={},this.format){case 0:for(i=_i=0;_i<256;i=++_i)this.codeMap[i]=data.readByte();break;case 4:for(segCountX2=data.readUInt16(),segCount=segCountX2/2,data.pos+=6,endCode=function(){var _j,_results;for(_results=[],i=_j=0;0<=segCount?_j<segCount:_j>segCount;i=0<=segCount?++_j:--_j)_results.push(data.readUInt16());return _results}(),data.pos+=2,startCode=function(){var _j,_results;for(_results=[],i=_j=0;0<=segCount?_j<segCount:_j>segCount;i=0<=segCount?++_j:--_j)_results.push(data.readUInt16());return _results}(),idDelta=function(){var _j,_results;for(_results=[],i=_j=0;0<=segCount?_j<segCount:_j>segCount;i=0<=segCount?++_j:--_j)_results.push(data.readUInt16());return _results}(),idRangeOffset=function(){var _j,_results;for(_results=[],i=_j=0;0<=segCount?_j<segCount:_j>segCount;i=0<=segCount?++_j:--_j)_results.push(data.readUInt16());return _results}(),count=(this.length-data.pos+this.offset)/2,glyphIds=function(){var _j,_results;for(_results=[],i=_j=0;0<=count?_j<count:_j>count;i=0<=count?++_j:--_j)_results.push(data.readUInt16());return _results}(),i=_j=0,_len=endCode.length;_j<_len;i=++_j)for(tail=endCode[i],code=_k=start=startCode[i];start<=tail?_k<=tail:_k>=tail;code=start<=tail?++_k:--_k)0===idRangeOffset[i]?glyphId=code+idDelta[i]:0!==(glyphId=glyphIds[idRangeOffset[i]/2+(code-start)-(segCount-i)]||0)&&(glyphId+=idDelta[i]),this.codeMap[code]=65535&glyphId}data.pos=saveOffset}return CmapEntry.encode=function(charmap,encoding){var charMap,code,codeMap,codes,delta,deltas,diff,endCode,endCodes,entrySelector,glyphIDs,i,id,indexes,last,map,nextID,offset,old,rangeOffsets,rangeShift,searchRange,segCount,segCountX2,startCode,startCodes,startGlyph,subtable,_i,_j,_k,_l,_len,_len1,_len2,_len3,_len4,_len5,_len6,_len7,_m,_n,_name,_o,_p,_q;switch(subtable=new Data,codes=Object.keys(charmap).sort((function(a,b){return a-b})),encoding){case"macroman":for(id=0,indexes=function(){var _i,_results;for(_results=[],i=_i=0;_i<256;i=++_i)_results.push(0);return _results}(),map={0:0},codeMap={},_i=0,_len=codes.length;_i<_len;_i++)null==map[_name=charmap[code=codes[_i]]]&&(map[_name]=++id),codeMap[code]={old:charmap[code],new:map[charmap[code]]},indexes[code]=map[charmap[code]];return subtable.writeUInt16(1),subtable.writeUInt16(0),subtable.writeUInt32(12),subtable.writeUInt16(0),subtable.writeUInt16(262),subtable.writeUInt16(0),subtable.write(indexes),{charMap:codeMap,subtable:subtable.data,maxGlyphID:id+1};case"unicode":for(startCodes=[],endCodes=[],nextID=0,map={},charMap={},last=diff=null,_j=0,_len1=codes.length;_j<_len1;_j++)null==map[old=charmap[code=codes[_j]]]&&(map[old]=++nextID),charMap[code]={old:old,new:map[old]},delta=map[old]-code,null!=last&&delta===diff||(last&&endCodes.push(last),startCodes.push(code),diff=delta),last=code;for(last&&endCodes.push(last),endCodes.push(65535),startCodes.push(65535),segCountX2=2*(segCount=startCodes.length),searchRange=2*Math.pow(Math.log(segCount)/Math.LN2,2),entrySelector=Math.log(searchRange/2)/Math.LN2,rangeShift=2*segCount-searchRange,deltas=[],rangeOffsets=[],glyphIDs=[],i=_k=0,_len2=startCodes.length;_k<_len2;i=++_k){if(startCode=startCodes[i],endCode=endCodes[i],65535===startCode){deltas.push(0),rangeOffsets.push(0);break}if(startCode-(startGlyph=charMap[startCode].new)>=32768)for(deltas.push(0),rangeOffsets.push(2*(glyphIDs.length+segCount-i)),code=_l=startCode;startCode<=endCode?_l<=endCode:_l>=endCode;code=startCode<=endCode?++_l:--_l)glyphIDs.push(charMap[code].new);else deltas.push(startGlyph-startCode),rangeOffsets.push(0)}for(subtable.writeUInt16(3),subtable.writeUInt16(1),subtable.writeUInt32(12),subtable.writeUInt16(4),subtable.writeUInt16(16+8*segCount+2*glyphIDs.length),subtable.writeUInt16(0),subtable.writeUInt16(segCountX2),subtable.writeUInt16(searchRange),subtable.writeUInt16(entrySelector),subtable.writeUInt16(rangeShift),_m=0,_len3=endCodes.length;_m<_len3;_m++)code=endCodes[_m],subtable.writeUInt16(code);for(subtable.writeUInt16(0),_n=0,_len4=startCodes.length;_n<_len4;_n++)code=startCodes[_n],subtable.writeUInt16(code);for(_o=0,_len5=deltas.length;_o<_len5;_o++)delta=deltas[_o],subtable.writeUInt16(delta);for(_p=0,_len6=rangeOffsets.length;_p<_len6;_p++)offset=rangeOffsets[_p],subtable.writeUInt16(offset);for(_q=0,_len7=glyphIDs.length;_q<_len7;_q++)id=glyphIDs[_q],subtable.writeUInt16(id);return{charMap:charMap,subtable:subtable.data,maxGlyphID:nextID+1}}},CmapEntry}(),CmapTable=function(_super){function CmapTable(){return CmapTable.__super__.constructor.apply(this,arguments)}return __extends(CmapTable,_super),CmapTable.prototype.tag="cmap",CmapTable.prototype.parse=function(data){var entry,tableCount,_i;for(data.pos=this.offset,this.version=data.readUInt16(),tableCount=data.readUInt16(),this.tables=[],this.unicode=null,_i=0;0<=tableCount?_i<tableCount:_i>tableCount;0<=tableCount?++_i:--_i)entry=new CmapEntry(data,this.offset),this.tables.push(entry),entry.isUnicode&&null==this.unicode&&(this.unicode=entry);return!0},CmapTable.encode=function(charmap,encoding){var result,table;return null==encoding&&(encoding="macroman"),result=CmapEntry.encode(charmap,encoding),(table=new Data).writeUInt16(0),table.writeUInt16(1),result.table=table.data.concat(result.subtable),result},CmapTable}(Table),HheaTable=function(_super){function HheaTable(){return HheaTable.__super__.constructor.apply(this,arguments)}return __extends(HheaTable,_super),HheaTable.prototype.tag="hhea",HheaTable.prototype.parse=function(data){return data.pos=this.offset,this.version=data.readInt(),this.ascender=data.readShort(),this.decender=data.readShort(),this.lineGap=data.readShort(),this.advanceWidthMax=data.readShort(),this.minLeftSideBearing=data.readShort(),this.minRightSideBearing=data.readShort(),this.xMaxExtent=data.readShort(),this.caretSlopeRise=data.readShort(),this.caretSlopeRun=data.readShort(),this.caretOffset=data.readShort(),data.pos+=8,this.metricDataFormat=data.readShort(),this.numberOfMetrics=data.readUInt16()},HheaTable}(Table),OS2Table=function(_super){function OS2Table(){return OS2Table.__super__.constructor.apply(this,arguments)}return __extends(OS2Table,_super),OS2Table.prototype.tag="OS/2",OS2Table.prototype.parse=function(data){if(data.pos=this.offset,this.version=data.readUInt16(),this.averageCharWidth=data.readShort(),this.weightClass=data.readUInt16(),this.widthClass=data.readUInt16(),this.type=data.readShort(),this.ySubscriptXSize=data.readShort(),this.ySubscriptYSize=data.readShort(),this.ySubscriptXOffset=data.readShort(),this.ySubscriptYOffset=data.readShort(),this.ySuperscriptXSize=data.readShort(),this.ySuperscriptYSize=data.readShort(),this.ySuperscriptXOffset=data.readShort(),this.ySuperscriptYOffset=data.readShort(),this.yStrikeoutSize=data.readShort(),this.yStrikeoutPosition=data.readShort(),this.familyClass=data.readShort(),this.panose=function(){var _i,_results;for(_results=[],_i=0;_i<10;++_i)_results.push(data.readByte());return _results}(),this.charRange=function(){var _i,_results;for(_results=[],_i=0;_i<4;++_i)_results.push(data.readInt());return _results}(),this.vendorID=data.readString(4),this.selection=data.readShort(),this.firstCharIndex=data.readShort(),this.lastCharIndex=data.readShort(),this.version>0&&(this.ascent=data.readShort(),this.descent=data.readShort(),this.lineGap=data.readShort(),this.winAscent=data.readShort(),this.winDescent=data.readShort(),this.codePageRange=function(){var _i,_results;for(_results=[],_i=0;_i<2;++_i)_results.push(data.readInt());return _results}(),this.version>1))return this.xHeight=data.readShort(),this.capHeight=data.readShort(),this.defaultChar=data.readShort(),this.breakChar=data.readShort(),this.maxContext=data.readShort()},OS2Table}(Table),PostTable=function(_super){function PostTable(){return PostTable.__super__.constructor.apply(this,arguments)}return __extends(PostTable,_super),PostTable.prototype.tag="post",PostTable.prototype.parse=function(data){var length,numberOfGlyphs,_i,_results;switch(data.pos=this.offset,this.format=data.readInt(),this.italicAngle=data.readInt(),this.underlinePosition=data.readShort(),this.underlineThickness=data.readShort(),this.isFixedPitch=data.readInt(),this.minMemType42=data.readInt(),this.maxMemType42=data.readInt(),this.minMemType1=data.readInt(),this.maxMemType1=data.readInt(),this.format){case 65536:case 196608:break;case 131072:for(numberOfGlyphs=data.readUInt16(),this.glyphNameIndex=[],_i=0;0<=numberOfGlyphs?_i<numberOfGlyphs:_i>numberOfGlyphs;0<=numberOfGlyphs?++_i:--_i)this.glyphNameIndex.push(data.readUInt16());for(this.names=[],_results=[];data.pos<this.offset+this.length;)length=data.readByte(),_results.push(this.names.push(data.readString(length)));return _results;case 151552:return numberOfGlyphs=data.readUInt16(),this.offsets=data.read(numberOfGlyphs);case 262144:return this.map=function(){var _j,_ref,_results1;for(_results1=[],_j=0,_ref=this.file.maxp.numGlyphs;0<=_ref?_j<_ref:_j>_ref;0<=_ref?++_j:--_j)_results1.push(data.readUInt32());return _results1}.call(this)}},PostTable}(Table),NameEntry=function(raw,entry){this.raw=raw,this.length=raw.length,this.platformID=entry.platformID,this.encodingID=entry.encodingID,this.languageID=entry.languageID},NameTable=function(_super){function NameTable(){return NameTable.__super__.constructor.apply(this,arguments)}return __extends(NameTable,_super),NameTable.prototype.tag="name",NameTable.prototype.parse=function(data){var count,entries,entry,i,name,stringOffset,strings,text,_i,_j,_len,_name;for(data.pos=this.offset,data.readShort(),count=data.readShort(),stringOffset=data.readShort(),entries=[],i=_i=0;0<=count?_i<count:_i>count;i=0<=count?++_i:--_i)entries.push({platformID:data.readShort(),encodingID:data.readShort(),languageID:data.readShort(),nameID:data.readShort(),length:data.readShort(),offset:this.offset+stringOffset+data.readShort()});for(strings={},i=_j=0,_len=entries.length;_j<_len;i=++_j)entry=entries[i],data.pos=entry.offset,text=data.readString(entry.length),name=new NameEntry(text,entry),null==strings[_name=entry.nameID]&&(strings[_name]=[]),strings[entry.nameID].push(name);return this.strings=strings,this.copyright=strings[0],this.fontFamily=strings[1],this.fontSubfamily=strings[2],this.uniqueSubfamily=strings[3],this.fontName=strings[4],this.version=strings[5],this.postscriptName=strings[6][0].raw.replace(/[\x00-\x19\x80-\xff]/g,""),this.trademark=strings[7],this.manufacturer=strings[8],this.designer=strings[9],this.description=strings[10],this.vendorUrl=strings[11],this.designerUrl=strings[12],this.license=strings[13],this.licenseUrl=strings[14],this.preferredFamily=strings[15],this.preferredSubfamily=strings[17],this.compatibleFull=strings[18],this.sampleText=strings[19]},NameTable}(Table),MaxpTable=function(_super){function MaxpTable(){return MaxpTable.__super__.constructor.apply(this,arguments)}return __extends(MaxpTable,_super),MaxpTable.prototype.tag="maxp",MaxpTable.prototype.parse=function(data){return data.pos=this.offset,this.version=data.readInt(),this.numGlyphs=data.readUInt16(),this.maxPoints=data.readUInt16(),this.maxContours=data.readUInt16(),this.maxCompositePoints=data.readUInt16(),this.maxComponentContours=data.readUInt16(),this.maxZones=data.readUInt16(),this.maxTwilightPoints=data.readUInt16(),this.maxStorage=data.readUInt16(),this.maxFunctionDefs=data.readUInt16(),this.maxInstructionDefs=data.readUInt16(),this.maxStackElements=data.readUInt16(),this.maxSizeOfInstructions=data.readUInt16(),this.maxComponentElements=data.readUInt16(),this.maxComponentDepth=data.readUInt16()},MaxpTable}(Table),HmtxTable=function(_super){function HmtxTable(){return HmtxTable.__super__.constructor.apply(this,arguments)}return __extends(HmtxTable,_super),HmtxTable.prototype.tag="hmtx",HmtxTable.prototype.parse=function(data){var last,lsbCount,m,_i,_j,_ref,_results;for(data.pos=this.offset,this.metrics=[],_i=0,_ref=this.file.hhea.numberOfMetrics;0<=_ref?_i<_ref:_i>_ref;0<=_ref?++_i:--_i)this.metrics.push({advance:data.readUInt16(),lsb:data.readInt16()});for(lsbCount=this.file.maxp.numGlyphs-this.file.hhea.numberOfMetrics,this.leftSideBearings=function(){var _j,_results;for(_results=[],_j=0;0<=lsbCount?_j<lsbCount:_j>lsbCount;0<=lsbCount?++_j:--_j)_results.push(data.readInt16());return _results}(),this.widths=function(){var _j,_len,_ref1,_results;for(_results=[],_j=0,_len=(_ref1=this.metrics).length;_j<_len;_j++)m=_ref1[_j],_results.push(m.advance);return _results}.call(this),last=this.widths[this.widths.length-1],_results=[],_j=0;0<=lsbCount?_j<lsbCount:_j>lsbCount;0<=lsbCount?++_j:--_j)_results.push(this.widths.push(last));return _results},HmtxTable.prototype.forGlyph=function(id){return id in this.metrics?this.metrics[id]:{advance:this.metrics[this.metrics.length-1].advance,lsb:this.leftSideBearings[id-this.metrics.length]}},HmtxTable}(Table),__slice=[].slice,GlyfTable=function(_super){function GlyfTable(){return GlyfTable.__super__.constructor.apply(this,arguments)}return __extends(GlyfTable,_super),GlyfTable.prototype.tag="glyf",GlyfTable.prototype.parse=function(data){return this.cache={}},GlyfTable.prototype.glyphFor=function(id){var data,index,length,loca,numberOfContours,raw,xMax,xMin,yMax,yMin;return(id=id)in this.cache?this.cache[id]:(loca=this.file.loca,data=this.file.contents,index=loca.indexOf(id),0===(length=loca.lengthOf(id))?this.cache[id]=null:(data.pos=this.offset+index,numberOfContours=(raw=new Data(data.read(length))).readShort(),xMin=raw.readShort(),yMin=raw.readShort(),xMax=raw.readShort(),yMax=raw.readShort(),this.cache[id]=-1===numberOfContours?new CompoundGlyph(raw,xMin,yMin,xMax,yMax):new SimpleGlyph(raw,numberOfContours,xMin,yMin,xMax,yMax),this.cache[id]))},GlyfTable.prototype.encode=function(glyphs,mapping,old2new){var glyph,offsets,table,_i,_len;for(table=[],offsets=[],_i=0,_len=mapping.length;_i<_len;_i++)glyph=glyphs[mapping[_i]],offsets.push(table.length),glyph&&(table=table.concat(glyph.encode(old2new)));return offsets.push(table.length),{table:table,offsets:offsets}},GlyfTable}(Table),SimpleGlyph=function(){function SimpleGlyph(raw,numberOfContours,xMin,yMin,xMax,yMax){this.raw=raw,this.numberOfContours=numberOfContours,this.xMin=xMin,this.yMin=yMin,this.xMax=xMax,this.yMax=yMax,this.compound=!1}return SimpleGlyph.prototype.encode=function(){return this.raw.data},SimpleGlyph}(),CompoundGlyph=function(){function CompoundGlyph(raw,xMin,yMin,xMax,yMax){var data,flags;for(this.raw=raw,this.xMin=xMin,this.yMin=yMin,this.xMax=xMax,this.yMax=yMax,this.compound=!0,this.glyphIDs=[],this.glyphOffsets=[],data=this.raw;flags=data.readShort(),this.glyphOffsets.push(data.pos),this.glyphIDs.push(data.readShort()),32&flags;)data.pos+=1&flags?4:2,128&flags?data.pos+=8:64&flags?data.pos+=4:8&flags&&(data.pos+=2)}return 1,8,32,64,128,CompoundGlyph.prototype.encode=function(mapping){var i,result,_i,_len,_ref;for(result=new Data(__slice.call(this.raw.data)),i=_i=0,_len=(_ref=this.glyphIDs).length;_i<_len;i=++_i)_ref[i],result.pos=this.glyphOffsets[i];return result.data},CompoundGlyph}(),LocaTable=function(_super){function LocaTable(){return LocaTable.__super__.constructor.apply(this,arguments)}return __extends(LocaTable,_super),LocaTable.prototype.tag="loca",LocaTable.prototype.parse=function(data){var format;return data.pos=this.offset,format=this.file.head.indexToLocFormat,this.offsets=0===format?function(){var _i,_ref,_results;for(_results=[],_i=0,_ref=this.length;_i<_ref;_i+=2)_results.push(2*data.readUInt16());return _results}.call(this):function(){var _i,_ref,_results;for(_results=[],_i=0,_ref=this.length;_i<_ref;_i+=4)_results.push(data.readUInt32());return _results}.call(this)},LocaTable.prototype.indexOf=function(id){return this.offsets[id]},LocaTable.prototype.lengthOf=function(id){return this.offsets[id+1]-this.offsets[id]},LocaTable.prototype.encode=function(offsets,activeGlyphs){for(var LocaTable=new Uint32Array(this.offsets.length),glyfPtr=0,listGlyf=0,k=0;k<LocaTable.length;++k)if(LocaTable[k]=glyfPtr,listGlyf<activeGlyphs.length&&activeGlyphs[listGlyf]==k){++listGlyf,LocaTable[k]=glyfPtr;var start=this.offsets[k],len=this.offsets[k+1]-start;len>0&&(glyfPtr+=len)}for(var newLocaTable=new Array(4*LocaTable.length),j=0;j<LocaTable.length;++j)newLocaTable[4*j+3]=255&LocaTable[j],newLocaTable[4*j+2]=(65280&LocaTable[j])>>8,newLocaTable[4*j+1]=(16711680&LocaTable[j])>>16,newLocaTable[4*j]=(4278190080&LocaTable[j])>>24;return newLocaTable},LocaTable}(Table),Subset=function(){function Subset(font){this.font=font,this.subset={},this.unicodes={},this.next=33}return Subset.prototype.generateCmap=function(){var mapping,roman,unicode,unicodeCmap,_ref;for(roman in unicodeCmap=this.font.cmap.tables[0].codeMap,mapping={},_ref=this.subset)unicode=_ref[roman],mapping[roman]=unicodeCmap[unicode];return mapping},Subset.prototype.glyphsFor=function(glyphIDs){var additionalIDs,glyph,glyphs,id,_i,_len,_ref;for(glyphs={},_i=0,_len=glyphIDs.length;_i<_len;_i++)glyphs[id=glyphIDs[_i]]=this.font.glyf.glyphFor(id);for(id in additionalIDs=[],glyphs)(null!=(glyph=glyphs[id])?glyph.compound:void 0)&&additionalIDs.push.apply(additionalIDs,glyph.glyphIDs);if(additionalIDs.length>0)for(id in _ref=this.glyphsFor(additionalIDs))glyph=_ref[id],glyphs[id]=glyph;return glyphs},Subset.prototype.encode=function(glyID){var cmap,code,glyf,glyphs,id,ids,loca,new2old,newIDs,nextGlyphID,old2new,oldID,oldIDs,tables,_ref;for(code in cmap=CmapTable.encode(this.generateCmap(),"unicode"),glyphs=this.glyphsFor(glyID),old2new={0:0},_ref=cmap.charMap)old2new[(ids=_ref[code]).old]=ids.new;for(oldID in nextGlyphID=cmap.maxGlyphID,glyphs)oldID in old2new||(old2new[oldID]=nextGlyphID++);return new2old=function(object){var key,ret;for(key in ret={},object)ret[object[key]]=key;return ret}(old2new),newIDs=Object.keys(new2old).sort((function(a,b){return a-b})),oldIDs=function(){var _i,_len,_results;for(_results=[],_i=0,_len=newIDs.length;_i<_len;_i++)id=newIDs[_i],_results.push(new2old[id]);return _results}(),glyf=this.font.glyf.encode(glyphs,oldIDs,old2new),loca=this.font.loca.encode(glyf.offsets,oldIDs),tables={cmap:this.font.cmap.raw(),glyf:glyf.table,loca:loca,hmtx:this.font.hmtx.raw(),hhea:this.font.hhea.raw(),maxp:this.font.maxp.raw(),post:this.font.post.raw(),name:this.font.name.raw(),head:this.font.head.raw()},this.font.os2.exists&&(tables["OS/2"]=this.font.os2.raw()),this.font.directory.encode(tables)},Subset}();jsPDF.API.PDFObject=function(){var pad;function PDFObject(){}return pad=function(str,length){return(Array(length+1).join("0")+str).slice(-length)},PDFObject.convert=function(object){var e,key,out,val;if(Array.isArray(object))return"["+function(){var _i,_len,_results;for(_results=[],_i=0,_len=object.length;_i<_len;_i++)e=object[_i],_results.push(PDFObject.convert(e));return _results}().join(" ")+"]";if("string"==typeof object)return"/"+object;if(null!=object?object.isString:void 0)return"("+object+")";if(object instanceof Date)return"(D:"+pad(object.getUTCFullYear(),4)+pad(object.getUTCMonth(),2)+pad(object.getUTCDate(),2)+pad(object.getUTCHours(),2)+pad(object.getUTCMinutes(),2)+pad(object.getUTCSeconds(),2)+"Z)";if("[object Object]"==={}.toString.call(object)){for(key in out=["<<"],object)val=object[key],out.push("/"+key+" "+PDFObject.convert(val));return out.push(">>"),out.join("\n")}return""+object},PDFObject}()}(jsPDF),function(global){var PNG;PNG=function(){var makeImage,scratchCanvas,scratchCtx;function PNG(data){var chunkSize,colors,palLen,delayDen,delayNum,frame,index,key,section,palShort,text,_i,_j,_ref;for(this.data=data,this.pos=8,this.palette=[],this.imgData=[],this.transparency={},this.animation=null,this.text={},frame=null;;){switch(chunkSize=this.readUInt32(),section=function(){var _i,_results;for(_results=[],_i=0;_i<4;++_i)_results.push(String.fromCharCode(this.data[this.pos++]));return _results}.call(this).join(""),section){case"IHDR":this.width=this.readUInt32(),this.height=this.readUInt32(),this.bits=this.data[this.pos++],this.colorType=this.data[this.pos++],this.compressionMethod=this.data[this.pos++],this.filterMethod=this.data[this.pos++],this.interlaceMethod=this.data[this.pos++];break;case"acTL":this.animation={numFrames:this.readUInt32(),numPlays:this.readUInt32()||1/0,frames:[]};break;case"PLTE":this.palette=this.read(chunkSize);break;case"fcTL":frame&&this.animation.frames.push(frame),this.pos+=4,frame={width:this.readUInt32(),height:this.readUInt32(),xOffset:this.readUInt32(),yOffset:this.readUInt32()},delayNum=this.readUInt16(),delayDen=this.readUInt16()||100,frame.delay=1e3*delayNum/delayDen,frame.disposeOp=this.data[this.pos++],frame.blendOp=this.data[this.pos++],frame.data=[];break;case"IDAT":case"fdAT":for("fdAT"===section&&(this.pos+=4,chunkSize-=4),data=(null!=frame?frame.data:void 0)||this.imgData,_i=0;0<=chunkSize?_i<chunkSize:_i>chunkSize;0<=chunkSize?++_i:--_i)data.push(this.data[this.pos++]);break;case"tRNS":switch(this.transparency={},this.colorType){case 3:if(palLen=this.palette.length/3,this.transparency.indexed=this.read(chunkSize),this.transparency.indexed.length>palLen)throw new Error("More transparent colors than palette size");if((palShort=palLen-this.transparency.indexed.length)>0)for(_j=0;0<=palShort?_j<palShort:_j>palShort;0<=palShort?++_j:--_j)this.transparency.indexed.push(255);break;case 0:this.transparency.grayscale=this.read(chunkSize)[0];break;case 2:this.transparency.rgb=this.read(chunkSize)}break;case"tEXt":index=(text=this.read(chunkSize)).indexOf(0),key=String.fromCharCode.apply(String,text.slice(0,index)),this.text[key]=String.fromCharCode.apply(String,text.slice(index+1));break;case"IEND":return frame&&this.animation.frames.push(frame),this.colors=function(){switch(this.colorType){case 0:case 3:case 4:return 1;case 2:case 6:return 3}}.call(this),this.hasAlphaChannel=4===(_ref=this.colorType)||6===_ref,colors=this.colors+(this.hasAlphaChannel?1:0),this.pixelBitlength=this.bits*colors,this.colorSpace=function(){switch(this.colors){case 1:return"DeviceGray";case 3:return"DeviceRGB"}}.call(this),void(this.imgData=new Uint8Array(this.imgData));default:this.pos+=chunkSize}if(this.pos+=4,this.pos>this.data.length)throw new Error("Incomplete or corrupt PNG file")}}PNG.load=function(url,canvas,callback){var xhr;return"function"==typeof canvas&&(callback=canvas),(xhr=new XMLHttpRequest).open("GET",url,!0),xhr.responseType="arraybuffer",xhr.onload=function(){var png;return png=new PNG(new Uint8Array(xhr.response||xhr.mozResponseArrayBuffer)),"function"==typeof(null!=canvas?canvas.getContext:void 0)&&png.render(canvas),"function"==typeof callback?callback(png):void 0},xhr.send(null)},PNG.prototype.read=function(bytes){var _i,_results;for(_results=[],_i=0;0<=bytes?_i<bytes:_i>bytes;0<=bytes?++_i:--_i)_results.push(this.data[this.pos++]);return _results},PNG.prototype.readUInt32=function(){return this.data[this.pos++]<<24|this.data[this.pos++]<<16|this.data[this.pos++]<<8|this.data[this.pos++]},PNG.prototype.readUInt16=function(){return this.data[this.pos++]<<8|this.data[this.pos++]},PNG.prototype.decodePixels=function(data){var pixelBytes=this.pixelBitlength/8,fullPixels=new Uint8Array(this.width*this.height*pixelBytes),pos=0,_this=this;if(null==data&&(data=this.imgData),0===data.length)return new Uint8Array(0);function pass(x0,y0,dx,dy){var abyte,c,col,i,left,length,p,pa,paeth,pb,pc,pixels,row,scanlineLength,upper,upperLeft,_i,_j,_k,_l,_m,w=Math.ceil((_this.width-x0)/dx),h=Math.ceil((_this.height-y0)/dy),isFull=_this.width==w&&_this.height==h;for(scanlineLength=pixelBytes*w,pixels=isFull?fullPixels:new Uint8Array(scanlineLength*h),length=data.length,row=0,c=0;row<h&&pos<length;){switch(data[pos++]){case 0:for(i=_i=0;_i<scanlineLength;i=_i+=1)pixels[c++]=data[pos++];break;case 1:for(i=_j=0;_j<scanlineLength;i=_j+=1)abyte=data[pos++],left=i<pixelBytes?0:pixels[c-pixelBytes],pixels[c++]=(abyte+left)%256;break;case 2:for(i=_k=0;_k<scanlineLength;i=_k+=1)abyte=data[pos++],col=(i-i%pixelBytes)/pixelBytes,upper=row&&pixels[(row-1)*scanlineLength+col*pixelBytes+i%pixelBytes],pixels[c++]=(upper+abyte)%256;break;case 3:for(i=_l=0;_l<scanlineLength;i=_l+=1)abyte=data[pos++],col=(i-i%pixelBytes)/pixelBytes,left=i<pixelBytes?0:pixels[c-pixelBytes],upper=row&&pixels[(row-1)*scanlineLength+col*pixelBytes+i%pixelBytes],pixels[c++]=(abyte+Math.floor((left+upper)/2))%256;break;case 4:for(i=_m=0;_m<scanlineLength;i=_m+=1)abyte=data[pos++],col=(i-i%pixelBytes)/pixelBytes,left=i<pixelBytes?0:pixels[c-pixelBytes],0===row?upper=upperLeft=0:(upper=pixels[(row-1)*scanlineLength+col*pixelBytes+i%pixelBytes],upperLeft=col&&pixels[(row-1)*scanlineLength+(col-1)*pixelBytes+i%pixelBytes]),p=left+upper-upperLeft,pa=Math.abs(p-left),pb=Math.abs(p-upper),pc=Math.abs(p-upperLeft),paeth=pa<=pb&&pa<=pc?left:pb<=pc?upper:upperLeft,pixels[c++]=(abyte+paeth)%256;break;default:throw new Error("Invalid filter algorithm: "+data[pos-1])}if(!isFull){var fullPos=((y0+row*dy)*_this.width+x0)*pixelBytes,partPos=row*scanlineLength;for(i=0;i<w;i+=1){for(var j=0;j<pixelBytes;j+=1)fullPixels[fullPos++]=pixels[partPos++];fullPos+=(dx-1)*pixelBytes}}row++}}return data=(data=new FlateStream(data)).getBytes(),1==_this.interlaceMethod?(pass(0,0,8,8),pass(4,0,8,8),pass(0,4,4,8),pass(2,0,4,4),pass(0,2,2,4),pass(1,0,2,2),pass(0,1,1,2)):pass(0,0,1,1),fullPixels},PNG.prototype.decodePalette=function(){var c,i,palette,pos,ret,transparency,_i,_ref,_ref1;for(palette=this.palette,transparency=this.transparency.indexed||[],ret=new Uint8Array((transparency.length||0)+palette.length),pos=0,palette.length,c=0,i=_i=0,_ref=palette.length;_i<_ref;i=_i+=3)ret[pos++]=palette[i],ret[pos++]=palette[i+1],ret[pos++]=palette[i+2],ret[pos++]=null!=(_ref1=transparency[c++])?_ref1:255;return ret},PNG.prototype.copyToImageData=function(imageData,pixels){var alpha,colors,data,i,input,j,k,length,palette,v,_ref;if(colors=this.colors,palette=null,alpha=this.hasAlphaChannel,this.palette.length&&(palette=null!=(_ref=this._decodedPalette)?_ref:this._decodedPalette=this.decodePalette(),colors=4,alpha=!0),length=(data=imageData.data||imageData).length,input=palette||pixels,i=j=0,1===colors)for(;i<length;)k=palette?4*pixels[i/4]:j,v=input[k++],data[i++]=v,data[i++]=v,data[i++]=v,data[i++]=alpha?input[k++]:255,j=k;else for(;i<length;)k=palette?4*pixels[i/4]:j,data[i++]=input[k++],data[i++]=input[k++],data[i++]=input[k++],data[i++]=alpha?input[k++]:255,j=k},PNG.prototype.decode=function(){var ret;return ret=new Uint8Array(this.width*this.height*4),this.copyToImageData(ret,this.decodePixels()),ret};try{scratchCanvas=global.document.createElement("canvas"),scratchCtx=scratchCanvas.getContext("2d")}catch(e){return-1}return makeImage=function(imageData){var img;return scratchCtx.width=imageData.width,scratchCtx.height=imageData.height,scratchCtx.clearRect(0,0,imageData.width,imageData.height),scratchCtx.putImageData(imageData,0,0),(img=new Image).src=scratchCanvas.toDataURL(),img},PNG.prototype.decodeFrames=function(ctx){var frame,i,imageData,pixels,_i,_len,_ref,_results;if(this.animation){for(_results=[],i=_i=0,_len=(_ref=this.animation.frames).length;_i<_len;i=++_i)frame=_ref[i],imageData=ctx.createImageData(frame.width,frame.height),pixels=this.decodePixels(new Uint8Array(frame.data)),this.copyToImageData(imageData,pixels),frame.imageData=imageData,_results.push(frame.image=makeImage(imageData));return _results}},PNG.prototype.renderFrame=function(ctx,number){var frame,frames,prev;return frame=(frames=this.animation.frames)[number],prev=frames[number-1],0===number&&ctx.clearRect(0,0,this.width,this.height),1===(null!=prev?prev.disposeOp:void 0)?ctx.clearRect(prev.xOffset,prev.yOffset,prev.width,prev.height):2===(null!=prev?prev.disposeOp:void 0)&&ctx.putImageData(prev.imageData,prev.xOffset,prev.yOffset),0===frame.blendOp&&ctx.clearRect(frame.xOffset,frame.yOffset,frame.width,frame.height),ctx.drawImage(frame.image,frame.xOffset,frame.yOffset)},PNG.prototype.animate=function(ctx){var _doFrame,frameNumber,frames,numFrames,numPlays,_ref,_this=this;return frameNumber=0,_ref=this.animation,numFrames=_ref.numFrames,frames=_ref.frames,numPlays=_ref.numPlays,(_doFrame=function(){var f,frame;if(f=frameNumber++%numFrames,frame=frames[f],_this.renderFrame(ctx,f),numFrames>1&&frameNumber/numFrames<numPlays)return _this.animation._timeout=setTimeout(_doFrame,frame.delay)})()},PNG.prototype.stopAnimation=function(){var _ref;return clearTimeout(null!=(_ref=this.animation)?_ref._timeout:void 0)},PNG.prototype.render=function(canvas){var ctx,data;return canvas._png&&canvas._png.stopAnimation(),canvas._png=this,canvas.width=this.width,canvas.height=this.height,ctx=canvas.getContext("2d"),this.animation?(this.decodeFrames(ctx),this.animate(ctx)):(data=ctx.createImageData(this.width,this.height),this.copyToImageData(data,this.decodePixels()),ctx.putImageData(data,0,0))},PNG}(),global.PNG=PNG}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||"undefined"!=typeof global&&global||Function('return typeof this === "object" && this.content')()||Function("return this")());var DecodeStream=function(){function constructor(){this.pos=0,this.bufferLength=0,this.eof=!1,this.buffer=null}return constructor.prototype={ensureBuffer:function(requested){var buffer=this.buffer,current=buffer?buffer.byteLength:0;if(requested<current)return buffer;for(var size=512;size<requested;)size<<=1;for(var buffer2=new Uint8Array(size),i=0;i<current;++i)buffer2[i]=buffer[i];return this.buffer=buffer2},getByte:function(){for(var pos=this.pos;this.bufferLength<=pos;){if(this.eof)return null;this.readBlock()}return this.buffer[this.pos++]},getBytes:function(length){var pos=this.pos;if(length){this.ensureBuffer(pos+length);for(var end=pos+length;!this.eof&&this.bufferLength<end;)this.readBlock();var bufEnd=this.bufferLength;end>bufEnd&&(end=bufEnd)}else{for(;!this.eof;)this.readBlock();end=this.bufferLength}return this.pos=end,this.buffer.subarray(pos,end)},lookChar:function(){for(var pos=this.pos;this.bufferLength<=pos;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos])},getChar:function(){for(var pos=this.pos;this.bufferLength<=pos;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos++])},makeSubStream:function(start,length,dict){for(var end=start+length;this.bufferLength<=end&&!this.eof;)this.readBlock();return new Stream(this.buffer,start,length,dict)},skip:function(n){n||(n=1),this.pos+=n},reset:function(){this.pos=0}},constructor}(),FlateStream=function(){if("undefined"!=typeof Uint32Array){var codeLenCodeMap=new Uint32Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),lengthDecode=new Uint32Array([3,4,5,6,7,8,9,10,65547,65549,65551,65553,131091,131095,131099,131103,196643,196651,196659,196667,262211,262227,262243,262259,327811,327843,327875,327907,258,258,258]),distDecode=new Uint32Array([1,2,3,4,65541,65543,131081,131085,196625,196633,262177,262193,327745,327777,393345,393409,459009,459137,524801,525057,590849,591361,657409,658433,724993,727041,794625,798721,868353,876545]),fixedLitCodeTab=[new Uint32Array([459008,524368,524304,524568,459024,524400,524336,590016,459016,524384,524320,589984,524288,524416,524352,590048,459012,524376,524312,589968,459028,524408,524344,590032,459020,524392,524328,59e4,524296,524424,524360,590064,459010,524372,524308,524572,459026,524404,524340,590024,459018,524388,524324,589992,524292,524420,524356,590056,459014,524380,524316,589976,459030,524412,524348,590040,459022,524396,524332,590008,524300,524428,524364,590072,459009,524370,524306,524570,459025,524402,524338,590020,459017,524386,524322,589988,524290,524418,524354,590052,459013,524378,524314,589972,459029,524410,524346,590036,459021,524394,524330,590004,524298,524426,524362,590068,459011,524374,524310,524574,459027,524406,524342,590028,459019,524390,524326,589996,524294,524422,524358,590060,459015,524382,524318,589980,459031,524414,524350,590044,459023,524398,524334,590012,524302,524430,524366,590076,459008,524369,524305,524569,459024,524401,524337,590018,459016,524385,524321,589986,524289,524417,524353,590050,459012,524377,524313,589970,459028,524409,524345,590034,459020,524393,524329,590002,524297,524425,524361,590066,459010,524373,524309,524573,459026,524405,524341,590026,459018,524389,524325,589994,524293,524421,524357,590058,459014,524381,524317,589978,459030,524413,524349,590042,459022,524397,524333,590010,524301,524429,524365,590074,459009,524371,524307,524571,459025,524403,524339,590022,459017,524387,524323,589990,524291,524419,524355,590054,459013,524379,524315,589974,459029,524411,524347,590038,459021,524395,524331,590006,524299,524427,524363,590070,459011,524375,524311,524575,459027,524407,524343,590030,459019,524391,524327,589998,524295,524423,524359,590062,459015,524383,524319,589982,459031,524415,524351,590046,459023,524399,524335,590014,524303,524431,524367,590078,459008,524368,524304,524568,459024,524400,524336,590017,459016,524384,524320,589985,524288,524416,524352,590049,459012,524376,524312,589969,459028,524408,524344,590033,459020,524392,524328,590001,524296,524424,524360,590065,459010,524372,524308,524572,459026,524404,524340,590025,459018,524388,524324,589993,524292,524420,524356,590057,459014,524380,524316,589977,459030,524412,524348,590041,459022,524396,524332,590009,524300,524428,524364,590073,459009,524370,524306,524570,459025,524402,524338,590021,459017,524386,524322,589989,524290,524418,524354,590053,459013,524378,524314,589973,459029,524410,524346,590037,459021,524394,524330,590005,524298,524426,524362,590069,459011,524374,524310,524574,459027,524406,524342,590029,459019,524390,524326,589997,524294,524422,524358,590061,459015,524382,524318,589981,459031,524414,524350,590045,459023,524398,524334,590013,524302,524430,524366,590077,459008,524369,524305,524569,459024,524401,524337,590019,459016,524385,524321,589987,524289,524417,524353,590051,459012,524377,524313,589971,459028,524409,524345,590035,459020,524393,524329,590003,524297,524425,524361,590067,459010,524373,524309,524573,459026,524405,524341,590027,459018,524389,524325,589995,524293,524421,524357,590059,459014,524381,524317,589979,459030,524413,524349,590043,459022,524397,524333,590011,524301,524429,524365,590075,459009,524371,524307,524571,459025,524403,524339,590023,459017,524387,524323,589991,524291,524419,524355,590055,459013,524379,524315,589975,459029,524411,524347,590039,459021,524395,524331,590007,524299,524427,524363,590071,459011,524375,524311,524575,459027,524407,524343,590031,459019,524391,524327,589999,524295,524423,524359,590063,459015,524383,524319,589983,459031,524415,524351,590047,459023,524399,524335,590015,524303,524431,524367,590079]),9],fixedDistCodeTab=[new Uint32Array([327680,327696,327688,327704,327684,327700,327692,327708,327682,327698,327690,327706,327686,327702,327694,0,327681,327697,327689,327705,327685,327701,327693,327709,327683,327699,327691,327707,327687,327703,327695,0]),5];return constructor.prototype=Object.create(DecodeStream.prototype),constructor.prototype.getBits=function(bits){for(var b,codeSize=this.codeSize,codeBuf=this.codeBuf,bytes=this.bytes,bytesPos=this.bytesPos;codeSize<bits;)void 0===(b=bytes[bytesPos++])&&error("Bad encoding in flate stream"),codeBuf|=b<<codeSize,codeSize+=8;return b=codeBuf&(1<<bits)-1,this.codeBuf=codeBuf>>bits,this.codeSize=codeSize-=bits,this.bytesPos=bytesPos,b},constructor.prototype.getCode=function(table){for(var codes=table[0],maxLen=table[1],codeSize=this.codeSize,codeBuf=this.codeBuf,bytes=this.bytes,bytesPos=this.bytesPos;codeSize<maxLen;){var b;void 0===(b=bytes[bytesPos++])&&error("Bad encoding in flate stream"),codeBuf|=b<<codeSize,codeSize+=8}var code=codes[codeBuf&(1<<maxLen)-1],codeLen=code>>16,codeVal=65535&code;return(0==codeSize||codeSize<codeLen||0==codeLen)&&error("Bad encoding in flate stream"),this.codeBuf=codeBuf>>codeLen,this.codeSize=codeSize-codeLen,this.bytesPos=bytesPos,codeVal},constructor.prototype.generateHuffmanTable=function(lengths){for(var n=lengths.length,maxLen=0,i=0;i<n;++i)lengths[i]>maxLen&&(maxLen=lengths[i]);for(var size=1<<maxLen,codes=new Uint32Array(size),len=1,code=0,skip=2;len<=maxLen;++len,code<<=1,skip<<=1)for(var val=0;val<n;++val)if(lengths[val]==len){var code2=0,t=code;for(i=0;i<len;++i)code2=code2<<1|1&t,t>>=1;for(i=code2;i<size;i+=skip)codes[i]=len<<16|val;++code}return[codes,maxLen]},constructor.prototype.readBlock=function(){function repeat(stream,array,len,offset,what){for(var repeat=stream.getBits(len)+offset;repeat-- >0;)array[i++]=what}var hdr=this.getBits(3);if(1&hdr&&(this.eof=!0),0!=(hdr>>=1)){var litCodeTable,distCodeTable;if(1==hdr)litCodeTable=fixedLitCodeTab,distCodeTable=fixedDistCodeTab;else if(2==hdr){for(var numLitCodes=this.getBits(5)+257,numDistCodes=this.getBits(5)+1,numCodeLenCodes=this.getBits(4)+4,codeLenCodeLengths=Array(codeLenCodeMap.length),i=0;i<numCodeLenCodes;)codeLenCodeLengths[codeLenCodeMap[i++]]=this.getBits(3);for(var codeLenCodeTab=this.generateHuffmanTable(codeLenCodeLengths),len=0,codes=(i=0,numLitCodes+numDistCodes),codeLengths=new Array(codes);i<codes;){var code=this.getCode(codeLenCodeTab);16==code?repeat(this,codeLengths,2,3,len):17==code?repeat(this,codeLengths,3,3,len=0):18==code?repeat(this,codeLengths,7,11,len=0):codeLengths[i++]=len=code}litCodeTable=this.generateHuffmanTable(codeLengths.slice(0,numLitCodes)),distCodeTable=this.generateHuffmanTable(codeLengths.slice(numLitCodes,codes))}else error("Unknown block type in flate stream");for(var limit=(buffer=this.buffer)?buffer.length:0,pos=this.bufferLength;;){var code1=this.getCode(litCodeTable);if(code1<256)pos+1>=limit&&(limit=(buffer=this.ensureBuffer(pos+1)).length),buffer[pos++]=code1;else{if(256==code1)return void(this.bufferLength=pos);var code2=(code1=lengthDecode[code1-=257])>>16;code2>0&&(code2=this.getBits(code2));len=(65535&code1)+code2;code1=this.getCode(distCodeTable),(code2=(code1=distDecode[code1])>>16)>0&&(code2=this.getBits(code2));var dist=(65535&code1)+code2;pos+len>=limit&&(limit=(buffer=this.ensureBuffer(pos+len)).length);for(var k=0;k<len;++k,++pos)buffer[pos]=buffer[pos-dist]}}}else{var b,bytes=this.bytes,bytesPos=this.bytesPos;void 0===(b=bytes[bytesPos++])&&error("Bad block header in flate stream");var blockLen=b;void 0===(b=bytes[bytesPos++])&&error("Bad block header in flate stream"),blockLen|=b<<8,void 0===(b=bytes[bytesPos++])&&error("Bad block header in flate stream");var check=b;void 0===(b=bytes[bytesPos++])&&error("Bad block header in flate stream"),(check|=b<<8)!=(65535&~blockLen)&&error("Bad uncompressed block length in flate stream"),this.codeBuf=0,this.codeSize=0;var bufferLength=this.bufferLength,buffer=this.ensureBuffer(bufferLength+blockLen),end=bufferLength+blockLen;this.bufferLength=end;for(var n=bufferLength;n<end;++n){if(void 0===(b=bytes[bytesPos++])){this.eof=!0;break}buffer[n]=b}this.bytesPos=bytesPos}},constructor}function error(e){throw new Error(e)}function constructor(bytes){var bytesPos=0,cmf=bytes[bytesPos++],flg=bytes[bytesPos++];-1!=cmf&&-1!=flg||error("Invalid header in flate stream"),8!=(15&cmf)&&error("Unknown compression method in flate stream"),((cmf<<8)+flg)%31!=0&&error("Bad FCHECK in flate stream"),32&flg&&error("FDICT bit set in flate stream"),this.bytes=bytes,this.bytesPos=2,this.codeSize=0,this.codeBuf=0,DecodeStream.call(this)}}();return function(global){if("object"!==_typeof2(global.console)){global.console={};for(var prop,method,con=global.console,dummy=function(){},properties=["memory"],methods="assert,clear,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn".split(",");prop=properties.pop();)con[prop]||(con[prop]={});for(;method=methods.pop();)con[method]||(con[method]=dummy)}var hasOwnProperty,hasDontEnumBug,dontEnums,dontEnumsLength,b64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";void 0===global.btoa&&(global.btoa=function(data){var h1,h2,h3,h4,bits,i=0,ac=0,enc="",tmp_arr=[];if(!data)return data;do{h1=(bits=data.charCodeAt(i++)<<16|data.charCodeAt(i++)<<8|data.charCodeAt(i++))>>18&63,h2=bits>>12&63,h3=bits>>6&63,h4=63&bits,tmp_arr[ac++]=b64.charAt(h1)+b64.charAt(h2)+b64.charAt(h3)+b64.charAt(h4)}while(i<data.length);enc=tmp_arr.join("");var r=data.length%3;return(r?enc.slice(0,r-3):enc)+"===".slice(r||3)}),void 0===global.atob&&(global.atob=function(data){var o1,o2,o3,h3,h4,bits,i=0,ac=0,tmp_arr=[];if(!data)return data;data+="";do{o1=(bits=b64.indexOf(data.charAt(i++))<<18|b64.indexOf(data.charAt(i++))<<12|(h3=b64.indexOf(data.charAt(i++)))<<6|(h4=b64.indexOf(data.charAt(i++))))>>16&255,o2=bits>>8&255,o3=255&bits,tmp_arr[ac++]=64==h3?String.fromCharCode(o1):64==h4?String.fromCharCode(o1,o2):String.fromCharCode(o1,o2,o3)}while(i<data.length);return tmp_arr.join("")}),Array.prototype.map||(Array.prototype.map=function(fun){if(null==this||"function"!=typeof fun)throw new TypeError;for(var t=Object(this),len=t.length>>>0,res=new Array(len),thisArg=arguments.length>1?arguments[1]:void 0,i=0;i<len;i++)i in t&&(res[i]=fun.call(thisArg,t[i],i,t));return res}),Array.isArray||(Array.isArray=function(arg){return"[object Array]"===Object.prototype.toString.call(arg)}),Array.prototype.forEach||(Array.prototype.forEach=function(fun,thisArg){if(null==this||"function"!=typeof fun)throw new TypeError;for(var t=Object(this),len=t.length>>>0,i=0;i<len;i++)i in t&&fun.call(thisArg,t[i],i,t)}),Object.keys||(Object.keys=(hasOwnProperty=Object.prototype.hasOwnProperty,hasDontEnumBug=!{toString:null}.propertyIsEnumerable("toString"),dontEnumsLength=(dontEnums=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"]).length,function(obj){if("object"!==_typeof2(obj)&&("function"!=typeof obj||null===obj))throw new TypeError;var prop,i,result=[];for(prop in obj)hasOwnProperty.call(obj,prop)&&result.push(prop);if(hasDontEnumBug)for(i=0;i<dontEnumsLength;i++)hasOwnProperty.call(obj,dontEnums[i])&&result.push(dontEnums[i]);return result})),"function"!=typeof Object.assign&&(Object.assign=function(target){if(null==target)throw new TypeError("Cannot convert undefined or null to object");target=Object(target);for(var index=1;index<arguments.length;index++){var source=arguments[index];if(null!=source)for(var key in source)Object.prototype.hasOwnProperty.call(source,key)&&(target[key]=source[key])}return target}),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),String.prototype.trimLeft||(String.prototype.trimLeft=function(){return this.replace(/^\s+/g,"")}),String.prototype.trimRight||(String.prototype.trimRight=function(){return this.replace(/\s+$/g,"")})}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||"undefined"!=typeof global&&global||Function('return typeof this === "object" && this.content')()||Function("return this")()),jsPDF}));
+function(jsPDF){jsPDF.__bidiEngine__=jsPDF.prototype.__bidiEngine__=function(options){var _hasUbatB,_hasUbatS,_isInVisual,_isInRtl,_isOutVisual,_isOutRtl,_isSymmetricSwapping,_UNICODE_TYPES=_bidiUnicodeTypes,_STATE_TABLE_LTR=[[0,3,0,1,0,0,0],[0,3,0,1,2,2,0],[0,3,0,17,2,0,1],[0,3,5,5,4,1,0],[0,3,21,21,4,0,1],[0,3,5,5,4,2,0]],_STATE_TABLE_RTL=[[2,0,1,1,0,1,0],[2,0,1,1,0,2,0],[2,0,2,1,3,2,0],[2,0,2,33,3,1,1]],_TYPE_NAMES_MAP={L:0,R:1,EN:2,AN:3,N:4,B:5,S:6},_UNICODE_RANGES_MAP={0:0,5:1,6:2,7:3,32:4,251:5,254:6,255:7},_SWAP_TABLE=["(",")","(","<",">","<","[","]","[","{","}","{","«","»","«","‹","›","‹","⁅","⁆","⁅","⁽","⁾","⁽","₍","₎","₍","≤","≥","≤","〈","〉","〈","﹙","﹚","﹙","﹛","﹜","﹛","﹝","﹞","﹝","﹤","﹥","﹤"],_LTR_RANGES_REG_EXPR=new RegExp(/^([1-4|9]|1[0-9]|2[0-9]|3[0168]|4[04589]|5[012]|7[78]|159|16[0-9]|17[0-2]|21[569]|22[03489]|250)$/),_lastArabic=!1,_dir=0;this.__bidiEngine__={};var _getCharType=function(ch){var charCode=ch.charCodeAt(),range=charCode>>8,rangeIdx=_UNICODE_RANGES_MAP[range];return void 0!==rangeIdx?_UNICODE_TYPES[256*rangeIdx+(255&charCode)]:252===range||253===range?"AL":_LTR_RANGES_REG_EXPR.test(range)?"L":8===range?"R":"N"},_isContextualDirRtl=function(text){for(var charType,i=0;i<text.length;i++){if("L"===(charType=_getCharType(text.charAt(i))))return!1;if("R"===charType)return!0}return!1},_resolveCharType=function(chars,types,resolvedTypes,index){var wType,nType,i,len,cType=types[index];switch(cType){case"L":case"R":case"LRE":case"RLE":case"LRO":case"RLO":case"PDF":_lastArabic=!1;break;case"N":case"AN":break;case"EN":_lastArabic&&(cType="AN");break;case"AL":_lastArabic=!0,cType="R";break;case"WS":case"BN":cType="N";break;case"CS":index<1||index+1>=types.length||"EN"!==(wType=resolvedTypes[index-1])&&"AN"!==wType||"EN"!==(nType=types[index+1])&&"AN"!==nType?cType="N":_lastArabic&&(nType="AN"),cType=nType===wType?nType:"N";break;case"ES":cType="EN"===(wType=index>0?resolvedTypes[index-1]:"B")&&index+1<types.length&&"EN"===types[index+1]?"EN":"N";break;case"ET":if(index>0&&"EN"===resolvedTypes[index-1]){cType="EN";break}if(_lastArabic){cType="N";break}for(i=index+1,len=types.length;i<len&&"ET"===types[i];)i++;cType=i<len&&"EN"===types[i]?"EN":"N";break;case"NSM":if(_isInVisual&&!_isInRtl){for(len=types.length,i=index+1;i<len&&"NSM"===types[i];)i++;if(i<len){var c=chars[index],rtlCandidate=c>=1425&&c<=2303||64286===c;if(wType=types[i],rtlCandidate&&("R"===wType||"AL"===wType)){cType="R";break}}}cType=index<1||"B"===(wType=types[index-1])?"N":resolvedTypes[index-1];break;case"B":_lastArabic=!1,_hasUbatB=!0,cType=_dir;break;case"S":_hasUbatS=!0,cType="N"}return cType},_invertString=function(text,sourceToTargetMap,levels){var charArray=text.split("");return levels&&_computeLevels(charArray,levels,{hiLevel:_dir}),charArray.reverse(),sourceToTargetMap&&sourceToTargetMap.reverse(),charArray.join("")},_computeLevels=function(chars,levels,params){var action,i,index,newLevel,prevState,condPos=-1,len=chars.length,newState=0,resolvedTypes=[],stateTable=_dir?_STATE_TABLE_RTL:_STATE_TABLE_LTR,types=[];for(_lastArabic=!1,_hasUbatB=!1,_hasUbatS=!1,i=0;i<len;i++)types[i]=_getCharType(chars[i]);for(index=0;index<len;index++){if(prevState=newState,resolvedTypes[index]=_resolveCharType(chars,types,resolvedTypes,index),action=240&(newState=stateTable[prevState][_TYPE_NAMES_MAP[resolvedTypes[index]]]),newState&=15,levels[index]=newLevel=stateTable[newState][5],action>0)if(16===action){for(i=condPos;i<index;i++)levels[i]=1;condPos=-1}else condPos=-1;if(stateTable[newState][6])-1===condPos&&(condPos=index);else if(condPos>-1){for(i=condPos;i<index;i++)levels[i]=newLevel;condPos=-1}"B"===types[index]&&(levels[index]=0),params.hiLevel|=newLevel}_hasUbatS&&function(types,levels,length){for(var i=0;i<length;i++)if("S"===types[i]){levels[i]=_dir;for(var j=i-1;j>=0&&"WS"===types[j];j--)levels[j]=_dir}}(types,levels,len)},_invertByLevel=function(level,charArray,sourceToTargetMap,levels,params){if(!(params.hiLevel<level)){if(1===level&&1===_dir&&!_hasUbatB)return charArray.reverse(),void(sourceToTargetMap&&sourceToTargetMap.reverse());for(var ch,high,end,low,len=charArray.length,start=0;start<len;){if(levels[start]>=level){for(end=start+1;end<len&&levels[end]>=level;)end++;for(low=start,high=end-1;low<high;low++,high--)ch=charArray[low],charArray[low]=charArray[high],charArray[high]=ch,sourceToTargetMap&&(ch=sourceToTargetMap[low],sourceToTargetMap[low]=sourceToTargetMap[high],sourceToTargetMap[high]=ch);start=end}start++}}},_reorder=function(text,sourceToTargetMap,levels){var charArray=text.split(""),params={hiLevel:_dir};return levels||(levels=[]),_computeLevels(charArray,levels,params),function(charArray,levels,params){if(0!==params.hiLevel&&_isSymmetricSwapping)for(var index,i=0;i<charArray.length;i++)1===levels[i]&&(index=_SWAP_TABLE.indexOf(charArray[i]))>=0&&(charArray[i]=_SWAP_TABLE[index+1])}(charArray,levels,params),_invertByLevel(2,charArray,sourceToTargetMap,levels,params),_invertByLevel(1,charArray,sourceToTargetMap,levels,params),charArray.join("")};return this.__bidiEngine__.doBidiReorder=function(text,sourceToTargetMap,levels){if(function(text,sourceToTargetMap){if(sourceToTargetMap)for(var i=0;i<text.length;i++)sourceToTargetMap[i]=i;void 0===_isInRtl&&(_isInRtl=_isContextualDirRtl(text)),void 0===_isOutRtl&&(_isOutRtl=_isContextualDirRtl(text))}(text,sourceToTargetMap),_isInVisual||!_isOutVisual||_isOutRtl)if(_isInVisual&&_isOutVisual&&_isInRtl^_isOutRtl)_dir=_isInRtl?1:0,text=_invertString(text,sourceToTargetMap,levels);else if(!_isInVisual&&_isOutVisual&&_isOutRtl)_dir=_isInRtl?1:0,text=_reorder(text,sourceToTargetMap,levels),text=_invertString(text,sourceToTargetMap);else if(!_isInVisual||_isInRtl||_isOutVisual||_isOutRtl){if(_isInVisual&&!_isOutVisual&&_isInRtl^_isOutRtl)text=_invertString(text,sourceToTargetMap),_isInRtl?(_dir=0,text=_reorder(text,sourceToTargetMap,levels)):(_dir=1,text=_reorder(text,sourceToTargetMap,levels),text=_invertString(text,sourceToTargetMap));else if(_isInVisual&&_isInRtl&&!_isOutVisual&&_isOutRtl)_dir=1,text=_reorder(text,sourceToTargetMap,levels),text=_invertString(text,sourceToTargetMap);else if(!_isInVisual&&!_isOutVisual&&_isInRtl^_isOutRtl){var isSymmetricSwappingOrig=_isSymmetricSwapping;_isInRtl?(_dir=1,text=_reorder(text,sourceToTargetMap,levels),_dir=0,_isSymmetricSwapping=!1,text=_reorder(text,sourceToTargetMap,levels),_isSymmetricSwapping=isSymmetricSwappingOrig):(_dir=0,text=_reorder(text,sourceToTargetMap,levels),text=_invertString(text,sourceToTargetMap),_dir=1,_isSymmetricSwapping=!1,text=_reorder(text,sourceToTargetMap,levels),_isSymmetricSwapping=isSymmetricSwappingOrig,text=_invertString(text,sourceToTargetMap))}}else _dir=0,text=_reorder(text,sourceToTargetMap,levels);else _dir=_isInRtl?1:0,text=_reorder(text,sourceToTargetMap,levels);return text},this.__bidiEngine__.setOptions=function(options){options&&(_isInVisual=options.isInputVisual,_isOutVisual=options.isOutputVisual,_isInRtl=options.isInputRtl,_isOutRtl=options.isOutputRtl,_isSymmetricSwapping=options.isSymmetricSwapping)},this.__bidiEngine__.setOptions(options),this.__bidiEngine__};var _bidiUnicodeTypes=["BN","BN","BN","BN","BN","BN","BN","BN","BN","S","B","S","WS","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","B","B","B","S","WS","N","N","ET","ET","ET","N","N","N","N","N","ES","CS","ES","CS","CS","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","CS","N","N","N","N","N","N","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","N","N","N","N","N","N","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","N","N","N","N","BN","BN","BN","BN","BN","BN","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","CS","N","ET","ET","ET","ET","N","N","N","N","L","N","N","BN","N","N","ET","ET","EN","EN","N","L","N","N","N","EN","L","N","N","N","N","N","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","N","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","N","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","N","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","N","N","L","L","L","L","L","L","L","N","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","N","L","N","N","N","N","N","ET","N","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","R","NSM","R","NSM","NSM","R","NSM","NSM","R","NSM","N","N","N","N","N","N","N","N","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","N","N","N","N","N","R","R","R","R","R","N","N","N","N","N","N","N","N","N","N","N","AN","AN","AN","AN","AN","AN","N","N","AL","ET","ET","AL","CS","AL","N","N","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AL","AL","N","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AN","AN","AN","AN","AN","AN","AN","AN","AN","AN","ET","AN","AN","AL","AL","AL","NSM","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AN","N","NSM","NSM","NSM","NSM","NSM","NSM","AL","AL","NSM","NSM","N","NSM","NSM","NSM","NSM","AL","AL","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","N","AL","AL","NSM","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","N","N","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","AL","N","N","N","N","N","N","N","N","N","N","N","N","N","N","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","R","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","R","R","N","N","N","N","R","N","N","N","N","N","WS","WS","WS","WS","WS","WS","WS","WS","WS","WS","WS","BN","BN","BN","L","R","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","WS","B","LRE","RLE","PDF","LRO","RLO","CS","ET","ET","ET","ET","ET","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","CS","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","WS","BN","BN","BN","BN","BN","N","LRI","RLI","FSI","PDI","BN","BN","BN","BN","BN","BN","EN","L","N","N","EN","EN","EN","EN","EN","EN","ES","ES","N","N","N","L","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","ES","ES","N","N","N","N","L","L","L","L","L","L","L","L","L","L","L","L","L","N","N","N","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","ET","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","L","L","L","L","L","L","L","N","N","N","N","N","N","N","N","N","N","N","N","L","L","L","L","L","N","N","N","N","N","R","NSM","R","R","R","R","R","R","R","R","R","R","ES","R","R","R","R","R","R","R","R","R","R","R","R","R","N","R","R","R","R","R","N","R","N","R","R","N","R","R","N","R","R","R","R","R","R","R","R","R","R","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","NSM","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","CS","N","CS","N","N","CS","N","N","N","N","N","N","N","N","N","ET","N","N","ES","ES","N","N","N","N","N","ET","ET","N","N","N","N","N","AL","AL","AL","AL","AL","N","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","AL","N","N","BN","N","N","N","ET","ET","ET","N","N","N","N","N","ES","CS","ES","CS","CS","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","CS","N","N","N","N","N","N","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","N","N","N","N","N","N","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","N","N","N","N","N","N","N","N","N","N","N","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","N","N","N","L","L","L","L","L","L","N","N","L","L","L","L","L","L","N","N","L","L","L","L","L","L","N","N","L","L","L","N","N","N","ET","ET","N","N","N","ET","ET","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N","N"],bidiEngine=new jsPDF.__bidiEngine__({isInputVisual:!0});jsPDF.API.events.push(["postProcessText",function(args){var text=args.text,options=(args.x,args.y,args.options||{}),tmpText=(args.mutex,options.lang,[]);if(options.isInputVisual="boolean"!=typeof options.isInputVisual||options.isInputVisual,bidiEngine.setOptions(options),"[object Array]"===Object.prototype.toString.call(text)){var i=0;for(tmpText=[],i=0;i<text.length;i+=1)"[object Array]"===Object.prototype.toString.call(text[i])?tmpText.push([bidiEngine.doBidiReorder(text[i][0]),text[i][1],text[i][2]]):tmpText.push([bidiEngine.doBidiReorder(text[i])]);args.text=tmpText}else args.text=bidiEngine.doBidiReorder(text);bidiEngine.setOptions({isInputVisual:!0})}])}(jsPDF),jsPDF.API.TTFFont=function(){function TTFFont(rawData){var data;if(this.rawData=rawData,data=this.contents=new Data(rawData),this.contents.pos=4,"ttcf"===data.readString(4))throw new Error("TTCF not supported.");data.pos=0,this.parse(),this.subset=new Subset(this),this.registerTTF()}return TTFFont.open=function(file){return new TTFFont(file)},TTFFont.prototype.parse=function(){return this.directory=new Directory(this.contents),this.head=new HeadTable(this),this.name=new NameTable(this),this.cmap=new CmapTable(this),this.toUnicode={},this.hhea=new HheaTable(this),this.maxp=new MaxpTable(this),this.hmtx=new HmtxTable(this),this.post=new PostTable(this),this.os2=new OS2Table(this),this.loca=new LocaTable(this),this.glyf=new GlyfTable(this),this.ascender=this.os2.exists&&this.os2.ascender||this.hhea.ascender,this.decender=this.os2.exists&&this.os2.decender||this.hhea.decender,this.lineGap=this.os2.exists&&this.os2.lineGap||this.hhea.lineGap,this.bbox=[this.head.xMin,this.head.yMin,this.head.xMax,this.head.yMax]},TTFFont.prototype.registerTTF=function(){var e,hi,low,raw,_ref;if(this.scaleFactor=1e3/this.head.unitsPerEm,this.bbox=function(){var _i,_len,_ref,_results;for(_results=[],_i=0,_len=(_ref=this.bbox).length;_i<_len;_i++)e=_ref[_i],_results.push(Math.round(e*this.scaleFactor));return _results}.call(this),this.stemV=0,this.post.exists?(low=255&(raw=this.post.italic_angle),0!=(32768&(hi=raw>>16))&&(hi=-(1+(65535^hi))),this.italicAngle=+(hi+"."+low)):this.italicAngle=0,this.ascender=Math.round(this.ascender*this.scaleFactor),this.decender=Math.round(this.decender*this.scaleFactor),this.lineGap=Math.round(this.lineGap*this.scaleFactor),this.capHeight=this.os2.exists&&this.os2.capHeight||this.ascender,this.xHeight=this.os2.exists&&this.os2.xHeight||0,this.familyClass=(this.os2.exists&&this.os2.familyClass||0)>>8,this.isSerif=1===(_ref=this.familyClass)||2===_ref||3===_ref||4===_ref||5===_ref||7===_ref,this.isScript=10===this.familyClass,this.flags=0,this.post.isFixedPitch&&(this.flags|=1),this.isSerif&&(this.flags|=2),this.isScript&&(this.flags|=8),0!==this.italicAngle&&(this.flags|=64),this.flags|=32,!this.cmap.unicode)throw new Error("No unicode cmap for font")},TTFFont.prototype.characterToGlyph=function(character){var _ref;return(null!=(_ref=this.cmap.unicode)?_ref.codeMap[character]:void 0)||0},TTFFont.prototype.widthOfGlyph=function(glyph){var scale;return scale=1e3/this.head.unitsPerEm,this.hmtx.forGlyph(glyph).advance*scale},TTFFont.prototype.widthOfString=function(string,size,charSpace){var charCode,i,width,_ref;for(width=0,i=0,_ref=(string=""+string).length;0<=_ref?i<_ref:i>_ref;i=0<=_ref?++i:--i)charCode=string.charCodeAt(i),width+=this.widthOfGlyph(this.characterToGlyph(charCode))+charSpace*(1e3/size)||0;return width*(size/1e3)},TTFFont.prototype.lineHeight=function(size,includeGap){var gap;return null==includeGap&&(includeGap=!1),gap=includeGap?this.lineGap:0,(this.ascender+gap-this.decender)/1e3*size},TTFFont}();var Table,Data=function(){function Data(data){this.data=null!=data?data:[],this.pos=0,this.length=this.data.length}return Data.prototype.readByte=function(){return this.data[this.pos++]},Data.prototype.writeByte=function(byte){return this.data[this.pos++]=byte},Data.prototype.readUInt32=function(){return 16777216*this.readByte()+(this.readByte()<<16)+(this.readByte()<<8)+this.readByte()},Data.prototype.writeUInt32=function(val){return this.writeByte(val>>>24&255),this.writeByte(val>>16&255),this.writeByte(val>>8&255),this.writeByte(255&val)},Data.prototype.readInt32=function(){var int;return(int=this.readUInt32())>=2147483648?int-4294967296:int},Data.prototype.writeInt32=function(val){return val<0&&(val+=4294967296),this.writeUInt32(val)},Data.prototype.readUInt16=function(){return this.readByte()<<8|this.readByte()},Data.prototype.writeUInt16=function(val){return this.writeByte(val>>8&255),this.writeByte(255&val)},Data.prototype.readInt16=function(){var int;return(int=this.readUInt16())>=32768?int-65536:int},Data.prototype.writeInt16=function(val){return val<0&&(val+=65536),this.writeUInt16(val)},Data.prototype.readString=function(length){var i,ret;for(ret=[],i=0;0<=length?i<length:i>length;i=0<=length?++i:--i)ret[i]=String.fromCharCode(this.readByte());return ret.join("")},Data.prototype.writeString=function(val){var i,_ref,_results;for(_results=[],i=0,_ref=val.length;0<=_ref?i<_ref:i>_ref;i=0<=_ref?++i:--i)_results.push(this.writeByte(val.charCodeAt(i)));return _results},Data.prototype.readShort=function(){return this.readInt16()},Data.prototype.writeShort=function(val){return this.writeInt16(val)},Data.prototype.readLongLong=function(){var b1,b2,b3,b4,b5,b6,b7,b8;return b1=this.readByte(),b2=this.readByte(),b3=this.readByte(),b4=this.readByte(),b5=this.readByte(),b6=this.readByte(),b7=this.readByte(),b8=this.readByte(),128&b1?-1*(72057594037927940*(255^b1)+281474976710656*(255^b2)+1099511627776*(255^b3)+4294967296*(255^b4)+16777216*(255^b5)+65536*(255^b6)+256*(255^b7)+(255^b8)+1):72057594037927940*b1+281474976710656*b2+1099511627776*b3+4294967296*b4+16777216*b5+65536*b6+256*b7+b8},Data.prototype.writeLongLong=function(val){var high,low;return high=Math.floor(val/4294967296),low=4294967295&val,this.writeByte(high>>24&255),this.writeByte(high>>16&255),this.writeByte(high>>8&255),this.writeByte(255&high),this.writeByte(low>>24&255),this.writeByte(low>>16&255),this.writeByte(low>>8&255),this.writeByte(255&low)},Data.prototype.readInt=function(){return this.readInt32()},Data.prototype.writeInt=function(val){return this.writeInt32(val)},Data.prototype.read=function(bytes){var buf,i;for(buf=[],i=0;0<=bytes?i<bytes:i>bytes;i=0<=bytes?++i:--i)buf.push(this.readByte());return buf},Data.prototype.write=function(bytes){var byte,i,_len,_results;for(_results=[],i=0,_len=bytes.length;i<_len;i++)byte=bytes[i],_results.push(this.writeByte(byte));return _results},Data}(),Directory=function(){var checksum;function Directory(data){var entry,i,_ref;for(this.scalarType=data.readInt(),this.tableCount=data.readShort(),this.searchRange=data.readShort(),this.entrySelector=data.readShort(),this.rangeShift=data.readShort(),this.tables={},i=0,_ref=this.tableCount;0<=_ref?i<_ref:i>_ref;i=0<=_ref?++i:--i)entry={tag:data.readString(4),checksum:data.readInt(),offset:data.readInt(),length:data.readInt()},this.tables[entry.tag]=entry}return Directory.prototype.encode=function(tables){var adjustment,directory,directoryLength,entrySelector,headOffset,log2,offset,rangeShift,searchRange,table,tableCount,tableData,tag;for(tag in tableCount=Object.keys(tables).length,log2=Math.log(2),searchRange=16*Math.floor(Math.log(tableCount)/log2),entrySelector=Math.floor(searchRange/log2),rangeShift=16*tableCount-searchRange,(directory=new Data).writeInt(this.scalarType),directory.writeShort(tableCount),directory.writeShort(searchRange),directory.writeShort(entrySelector),directory.writeShort(rangeShift),directoryLength=16*tableCount,offset=directory.pos+directoryLength,headOffset=null,tableData=[],tables)for(table=tables[tag],directory.writeString(tag),directory.writeInt(checksum(table)),directory.writeInt(offset),directory.writeInt(table.length),tableData=tableData.concat(table),"head"===tag&&(headOffset=offset),offset+=table.length;offset%4;)tableData.push(0),offset++;return directory.write(tableData),adjustment=2981146554-checksum(directory.data),directory.pos=headOffset+8,directory.writeUInt32(adjustment),directory.data},checksum=function(data){var i,sum,tmp,_ref;for(data=__slice.call(data);data.length%4;)data.push(0);for(tmp=new Data(data),sum=0,i=0,_ref=data.length;i<_ref;i=i+=4)sum+=tmp.readUInt32();return 4294967295&sum},Directory}(),__hasProp={}.hasOwnProperty,__extends=function(child,parent){for(var key in parent)__hasProp.call(parent,key)&&(child[key]=parent[key]);function ctor(){this.constructor=child}return ctor.prototype=parent.prototype,child.prototype=new ctor,child.__super__=parent.prototype,child},HeadTable=function(_super){function HeadTable(){return HeadTable.__super__.constructor.apply(this,arguments)}return __extends(HeadTable,_super),HeadTable.prototype.tag="head",HeadTable.prototype.parse=function(data){return data.pos=this.offset,this.version=data.readInt(),this.revision=data.readInt(),this.checkSumAdjustment=data.readInt(),this.magicNumber=data.readInt(),this.flags=data.readShort(),this.unitsPerEm=data.readShort(),this.created=data.readLongLong(),this.modified=data.readLongLong(),this.xMin=data.readShort(),this.yMin=data.readShort(),this.xMax=data.readShort(),this.yMax=data.readShort(),this.macStyle=data.readShort(),this.lowestRecPPEM=data.readShort(),this.fontDirectionHint=data.readShort(),this.indexToLocFormat=data.readShort(),this.glyphDataFormat=data.readShort()},HeadTable.prototype.encode=function(indexToLocFormat){var table;return(table=new Data).writeInt(this.version),table.writeInt(this.revision),table.writeInt(this.checkSumAdjustment),table.writeInt(this.magicNumber),table.writeShort(this.flags),table.writeShort(this.unitsPerEm),table.writeLongLong(this.created),table.writeLongLong(this.modified),table.writeShort(this.xMin),table.writeShort(this.yMin),table.writeShort(this.xMax),table.writeShort(this.yMax),table.writeShort(this.macStyle),table.writeShort(this.lowestRecPPEM),table.writeShort(this.fontDirectionHint),table.writeShort(indexToLocFormat),table.writeShort(this.glyphDataFormat),table.data},HeadTable}(Table=function(){function Table(file){var info;this.file=file,info=this.file.directory.tables[this.tag],this.exists=!!info,info&&(this.offset=info.offset,this.length=info.length,this.parse(this.file.contents))}return Table.prototype.parse=function(){},Table.prototype.encode=function(){},Table.prototype.raw=function(){return this.exists?(this.file.contents.pos=this.offset,this.file.contents.read(this.length)):null},Table}()),CmapEntry=function(){function CmapEntry(data,offset){var code,count,endCode,glyphId,glyphIds,i,idDelta,idRangeOffset,saveOffset,segCount,segCountX2,start,startCode,tail,_j,_k,_len;switch(this.platformID=data.readUInt16(),this.encodingID=data.readShort(),this.offset=offset+data.readInt(),saveOffset=data.pos,data.pos=this.offset,this.format=data.readUInt16(),this.length=data.readUInt16(),this.language=data.readUInt16(),this.isUnicode=3===this.platformID&&1===this.encodingID&&4===this.format||0===this.platformID&&4===this.format,this.codeMap={},this.format){case 0:for(i=0;i<256;++i)this.codeMap[i]=data.readByte();break;case 4:for(segCountX2=data.readUInt16(),segCount=segCountX2/2,data.pos+=6,endCode=function(){var _j,_results;for(_results=[],i=_j=0;0<=segCount?_j<segCount:_j>segCount;i=0<=segCount?++_j:--_j)_results.push(data.readUInt16());return _results}(),data.pos+=2,startCode=function(){var _j,_results;for(_results=[],i=_j=0;0<=segCount?_j<segCount:_j>segCount;i=0<=segCount?++_j:--_j)_results.push(data.readUInt16());return _results}(),idDelta=function(){var _j,_results;for(_results=[],i=_j=0;0<=segCount?_j<segCount:_j>segCount;i=0<=segCount?++_j:--_j)_results.push(data.readUInt16());return _results}(),idRangeOffset=function(){var _j,_results;for(_results=[],i=_j=0;0<=segCount?_j<segCount:_j>segCount;i=0<=segCount?++_j:--_j)_results.push(data.readUInt16());return _results}(),count=(this.length-data.pos+this.offset)/2,glyphIds=function(){var _j,_results;for(_results=[],i=_j=0;0<=count?_j<count:_j>count;i=0<=count?++_j:--_j)_results.push(data.readUInt16());return _results}(),i=_j=0,_len=endCode.length;_j<_len;i=++_j)for(tail=endCode[i],code=_k=start=startCode[i];start<=tail?_k<=tail:_k>=tail;code=start<=tail?++_k:--_k)0===idRangeOffset[i]?glyphId=code+idDelta[i]:0!==(glyphId=glyphIds[idRangeOffset[i]/2+(code-start)-(segCount-i)]||0)&&(glyphId+=idDelta[i]),this.codeMap[code]=65535&glyphId}data.pos=saveOffset}return CmapEntry.encode=function(charmap,encoding){var charMap,code,codeMap,codes,delta,deltas,diff,endCode,endCodes,entrySelector,glyphIDs,i,id,indexes,last,map,nextID,offset,old,rangeOffsets,rangeShift,searchRange,segCount,segCountX2,startCode,startCodes,startGlyph,subtable,_i,_j,_k,_l,_len,_len1,_len2,_len3,_len4,_len5,_len6,_len7,_m,_n,_name,_o,_p,_q;switch(subtable=new Data,codes=Object.keys(charmap).sort((function(a,b){return a-b})),encoding){case"macroman":for(id=0,indexes=function(){var _results=[];for(i=0;i<256;++i)_results.push(0);return _results}(),map={0:0},codeMap={},_i=0,_len=codes.length;_i<_len;_i++)null==map[_name=charmap[code=codes[_i]]]&&(map[_name]=++id),codeMap[code]={old:charmap[code],new:map[charmap[code]]},indexes[code]=map[charmap[code]];return subtable.writeUInt16(1),subtable.writeUInt16(0),subtable.writeUInt32(12),subtable.writeUInt16(0),subtable.writeUInt16(262),subtable.writeUInt16(0),subtable.write(indexes),{charMap:codeMap,subtable:subtable.data,maxGlyphID:id+1};case"unicode":for(startCodes=[],endCodes=[],nextID=0,map={},charMap={},last=diff=null,_j=0,_len1=codes.length;_j<_len1;_j++)null==map[old=charmap[code=codes[_j]]]&&(map[old]=++nextID),charMap[code]={old:old,new:map[old]},delta=map[old]-code,null!=last&&delta===diff||(last&&endCodes.push(last),startCodes.push(code),diff=delta),last=code;for(last&&endCodes.push(last),endCodes.push(65535),startCodes.push(65535),segCountX2=2*(segCount=startCodes.length),searchRange=2*Math.pow(Math.log(segCount)/Math.LN2,2),entrySelector=Math.log(searchRange/2)/Math.LN2,rangeShift=2*segCount-searchRange,deltas=[],rangeOffsets=[],glyphIDs=[],i=_k=0,_len2=startCodes.length;_k<_len2;i=++_k){if(startCode=startCodes[i],endCode=endCodes[i],65535===startCode){deltas.push(0),rangeOffsets.push(0);break}if(startCode-(startGlyph=charMap[startCode].new)>=32768)for(deltas.push(0),rangeOffsets.push(2*(glyphIDs.length+segCount-i)),code=_l=startCode;startCode<=endCode?_l<=endCode:_l>=endCode;code=startCode<=endCode?++_l:--_l)glyphIDs.push(charMap[code].new);else deltas.push(startGlyph-startCode),rangeOffsets.push(0)}for(subtable.writeUInt16(3),subtable.writeUInt16(1),subtable.writeUInt32(12),subtable.writeUInt16(4),subtable.writeUInt16(16+8*segCount+2*glyphIDs.length),subtable.writeUInt16(0),subtable.writeUInt16(segCountX2),subtable.writeUInt16(searchRange),subtable.writeUInt16(entrySelector),subtable.writeUInt16(rangeShift),_m=0,_len3=endCodes.length;_m<_len3;_m++)code=endCodes[_m],subtable.writeUInt16(code);for(subtable.writeUInt16(0),_n=0,_len4=startCodes.length;_n<_len4;_n++)code=startCodes[_n],subtable.writeUInt16(code);for(_o=0,_len5=deltas.length;_o<_len5;_o++)delta=deltas[_o],subtable.writeUInt16(delta);for(_p=0,_len6=rangeOffsets.length;_p<_len6;_p++)offset=rangeOffsets[_p],subtable.writeUInt16(offset);for(_q=0,_len7=glyphIDs.length;_q<_len7;_q++)id=glyphIDs[_q],subtable.writeUInt16(id);return{charMap:charMap,subtable:subtable.data,maxGlyphID:nextID+1}}},CmapEntry}(),CmapTable=function(_super){function CmapTable(){return CmapTable.__super__.constructor.apply(this,arguments)}return __extends(CmapTable,_super),CmapTable.prototype.tag="cmap",CmapTable.prototype.parse=function(data){var entry,i,tableCount;for(data.pos=this.offset,this.version=data.readUInt16(),tableCount=data.readUInt16(),this.tables=[],this.unicode=null,i=0;0<=tableCount?i<tableCount:i>tableCount;i=0<=tableCount?++i:--i)entry=new CmapEntry(data,this.offset),this.tables.push(entry),entry.isUnicode&&null==this.unicode&&(this.unicode=entry);return!0},CmapTable.encode=function(charmap,encoding){var result,table;return null==encoding&&(encoding="macroman"),result=CmapEntry.encode(charmap,encoding),(table=new Data).writeUInt16(0),table.writeUInt16(1),result.table=table.data.concat(result.subtable),result},CmapTable}(Table),HheaTable=function(_super){function HheaTable(){return HheaTable.__super__.constructor.apply(this,arguments)}return __extends(HheaTable,_super),HheaTable.prototype.tag="hhea",HheaTable.prototype.parse=function(data){return data.pos=this.offset,this.version=data.readInt(),this.ascender=data.readShort(),this.decender=data.readShort(),this.lineGap=data.readShort(),this.advanceWidthMax=data.readShort(),this.minLeftSideBearing=data.readShort(),this.minRightSideBearing=data.readShort(),this.xMaxExtent=data.readShort(),this.caretSlopeRise=data.readShort(),this.caretSlopeRun=data.readShort(),this.caretOffset=data.readShort(),data.pos+=8,this.metricDataFormat=data.readShort(),this.numberOfMetrics=data.readUInt16()},HheaTable}(Table),OS2Table=function(_super){function OS2Table(){return OS2Table.__super__.constructor.apply(this,arguments)}return __extends(OS2Table,_super),OS2Table.prototype.tag="OS/2",OS2Table.prototype.parse=function(data){if(data.pos=this.offset,this.version=data.readUInt16(),this.averageCharWidth=data.readShort(),this.weightClass=data.readUInt16(),this.widthClass=data.readUInt16(),this.type=data.readShort(),this.ySubscriptXSize=data.readShort(),this.ySubscriptYSize=data.readShort(),this.ySubscriptXOffset=data.readShort(),this.ySubscriptYOffset=data.readShort(),this.ySuperscriptXSize=data.readShort(),this.ySuperscriptYSize=data.readShort(),this.ySuperscriptXOffset=data.readShort(),this.ySuperscriptYOffset=data.readShort(),this.yStrikeoutSize=data.readShort(),this.yStrikeoutPosition=data.readShort(),this.familyClass=data.readShort(),this.panose=function(){var i,_results;for(_results=[],i=0;i<10;++i)_results.push(data.readByte());return _results}(),this.charRange=function(){var i,_results;for(_results=[],i=0;i<4;++i)_results.push(data.readInt());return _results}(),this.vendorID=data.readString(4),this.selection=data.readShort(),this.firstCharIndex=data.readShort(),this.lastCharIndex=data.readShort(),this.version>0&&(this.ascent=data.readShort(),this.descent=data.readShort(),this.lineGap=data.readShort(),this.winAscent=data.readShort(),this.winDescent=data.readShort(),this.codePageRange=function(){var i,_results;for(_results=[],i=0;i<2;i=++i)_results.push(data.readInt());return _results}(),this.version>1))return this.xHeight=data.readShort(),this.capHeight=data.readShort(),this.defaultChar=data.readShort(),this.breakChar=data.readShort(),this.maxContext=data.readShort()},OS2Table}(Table),PostTable=function(_super){function PostTable(){return PostTable.__super__.constructor.apply(this,arguments)}return __extends(PostTable,_super),PostTable.prototype.tag="post",PostTable.prototype.parse=function(data){var length,numberOfGlyphs,_results;switch(data.pos=this.offset,this.format=data.readInt(),this.italicAngle=data.readInt(),this.underlinePosition=data.readShort(),this.underlineThickness=data.readShort(),this.isFixedPitch=data.readInt(),this.minMemType42=data.readInt(),this.maxMemType42=data.readInt(),this.minMemType1=data.readInt(),this.maxMemType1=data.readInt(),this.format){case 65536:case 196608:break;case 131072:var i;for(numberOfGlyphs=data.readUInt16(),this.glyphNameIndex=[],i=0;0<=numberOfGlyphs?i<numberOfGlyphs:i>numberOfGlyphs;i=0<=numberOfGlyphs?++i:--i)this.glyphNameIndex.push(data.readUInt16());for(this.names=[],_results=[];data.pos<this.offset+this.length;)length=data.readByte(),_results.push(this.names.push(data.readString(length)));return _results;case 151552:return numberOfGlyphs=data.readUInt16(),this.offsets=data.read(numberOfGlyphs);case 262144:return this.map=function(){var _j,_ref,_results1;for(_results1=[],i=_j=0,_ref=this.file.maxp.numGlyphs;0<=_ref?_j<_ref:_j>_ref;i=0<=_ref?++_j:--_j)_results1.push(data.readUInt32());return _results1}.call(this)}},PostTable}(Table),NameEntry=function(raw,entry){this.raw=raw,this.length=raw.length,this.platformID=entry.platformID,this.encodingID=entry.encodingID,this.languageID=entry.languageID},NameTable=function(_super){function NameTable(){return NameTable.__super__.constructor.apply(this,arguments)}return __extends(NameTable,_super),NameTable.prototype.tag="name",NameTable.prototype.parse=function(data){var count,entries,entry,i,name,stringOffset,strings,text,_j,_len,_name;for(data.pos=this.offset,data.readShort(),count=data.readShort(),stringOffset=data.readShort(),entries=[],i=0;0<=count?i<count:i>count;i=0<=count?++i:--i)entries.push({platformID:data.readShort(),encodingID:data.readShort(),languageID:data.readShort(),nameID:data.readShort(),length:data.readShort(),offset:this.offset+stringOffset+data.readShort()});for(strings={},i=_j=0,_len=entries.length;_j<_len;i=++_j)entry=entries[i],data.pos=entry.offset,text=data.readString(entry.length),name=new NameEntry(text,entry),null==strings[_name=entry.nameID]&&(strings[_name]=[]),strings[entry.nameID].push(name);this.strings=strings,this.copyright=strings[0],this.fontFamily=strings[1],this.fontSubfamily=strings[2],this.uniqueSubfamily=strings[3],this.fontName=strings[4],this.version=strings[5];try{this.postscriptName=strings[6][0].raw.replace(/[\x00-\x19\x80-\xff]/g,"")}catch(e){this.postscriptName=strings[4][0].raw.replace(/[\x00-\x19\x80-\xff]/g,"")}return this.trademark=strings[7],this.manufacturer=strings[8],this.designer=strings[9],this.description=strings[10],this.vendorUrl=strings[11],this.designerUrl=strings[12],this.license=strings[13],this.licenseUrl=strings[14],this.preferredFamily=strings[15],this.preferredSubfamily=strings[17],this.compatibleFull=strings[18],this.sampleText=strings[19]},NameTable}(Table),MaxpTable=function(_super){function MaxpTable(){return MaxpTable.__super__.constructor.apply(this,arguments)}return __extends(MaxpTable,_super),MaxpTable.prototype.tag="maxp",MaxpTable.prototype.parse=function(data){return data.pos=this.offset,this.version=data.readInt(),this.numGlyphs=data.readUInt16(),this.maxPoints=data.readUInt16(),this.maxContours=data.readUInt16(),this.maxCompositePoints=data.readUInt16(),this.maxComponentContours=data.readUInt16(),this.maxZones=data.readUInt16(),this.maxTwilightPoints=data.readUInt16(),this.maxStorage=data.readUInt16(),this.maxFunctionDefs=data.readUInt16(),this.maxInstructionDefs=data.readUInt16(),this.maxStackElements=data.readUInt16(),this.maxSizeOfInstructions=data.readUInt16(),this.maxComponentElements=data.readUInt16(),this.maxComponentDepth=data.readUInt16()},MaxpTable}(Table),HmtxTable=function(_super){function HmtxTable(){return HmtxTable.__super__.constructor.apply(this,arguments)}return __extends(HmtxTable,_super),HmtxTable.prototype.tag="hmtx",HmtxTable.prototype.parse=function(data){var i,last,lsbCount,m,_j,_ref,_results;for(data.pos=this.offset,this.metrics=[],i=0,_ref=this.file.hhea.numberOfMetrics;0<=_ref?i<_ref:i>_ref;i=0<=_ref?++i:--i)this.metrics.push({advance:data.readUInt16(),lsb:data.readInt16()});for(lsbCount=this.file.maxp.numGlyphs-this.file.hhea.numberOfMetrics,this.leftSideBearings=function(){var _j,_results;for(_results=[],i=_j=0;0<=lsbCount?_j<lsbCount:_j>lsbCount;i=0<=lsbCount?++_j:--_j)_results.push(data.readInt16());return _results}(),this.widths=function(){var _j,_len,_ref1,_results;for(_results=[],_j=0,_len=(_ref1=this.metrics).length;_j<_len;_j++)m=_ref1[_j],_results.push(m.advance);return _results}.call(this),last=this.widths[this.widths.length-1],_results=[],i=_j=0;0<=lsbCount?_j<lsbCount:_j>lsbCount;i=0<=lsbCount?++_j:--_j)_results.push(this.widths.push(last));return _results},HmtxTable.prototype.forGlyph=function(id){return id in this.metrics?this.metrics[id]:{advance:this.metrics[this.metrics.length-1].advance,lsb:this.leftSideBearings[id-this.metrics.length]}},HmtxTable}(Table),__slice=[].slice,GlyfTable=function(_super){function GlyfTable(){return GlyfTable.__super__.constructor.apply(this,arguments)}return __extends(GlyfTable,_super),GlyfTable.prototype.tag="glyf",GlyfTable.prototype.parse=function(){return this.cache={}},GlyfTable.prototype.glyphFor=function(id){var data,index,length,loca,numberOfContours,raw,xMax,xMin,yMax,yMin;return id in this.cache?this.cache[id]:(loca=this.file.loca,data=this.file.contents,index=loca.indexOf(id),0===(length=loca.lengthOf(id))?this.cache[id]=null:(data.pos=this.offset+index,numberOfContours=(raw=new Data(data.read(length))).readShort(),xMin=raw.readShort(),yMin=raw.readShort(),xMax=raw.readShort(),yMax=raw.readShort(),this.cache[id]=-1===numberOfContours?new CompoundGlyph(raw,xMin,yMin,xMax,yMax):new SimpleGlyph(raw,numberOfContours,xMin,yMin,xMax,yMax),this.cache[id]))},GlyfTable.prototype.encode=function(glyphs,mapping,old2new){var glyph,offsets,table,_i,_len;for(table=[],offsets=[],_i=0,_len=mapping.length;_i<_len;_i++)glyph=glyphs[mapping[_i]],offsets.push(table.length),glyph&&(table=table.concat(glyph.encode(old2new)));return offsets.push(table.length),{table:table,offsets:offsets}},GlyfTable}(Table),SimpleGlyph=function(){function SimpleGlyph(raw,numberOfContours,xMin,yMin,xMax,yMax){this.raw=raw,this.numberOfContours=numberOfContours,this.xMin=xMin,this.yMin=yMin,this.xMax=xMax,this.yMax=yMax,this.compound=!1}return SimpleGlyph.prototype.encode=function(){return this.raw.data},SimpleGlyph}(),CompoundGlyph=function(){function CompoundGlyph(raw,xMin,yMin,xMax,yMax){var data,flags;for(this.raw=raw,this.xMin=xMin,this.yMin=yMin,this.xMax=xMax,this.yMax=yMax,this.compound=!0,this.glyphIDs=[],this.glyphOffsets=[],data=this.raw;flags=data.readShort(),this.glyphOffsets.push(data.pos),this.glyphIDs.push(data.readUInt16()),32&flags;)data.pos+=1&flags?4:2,128&flags?data.pos+=8:64&flags?data.pos+=4:8&flags&&(data.pos+=2)}return 1,8,32,64,128,CompoundGlyph.prototype.encode=function(){var i,result,_len;for(result=new Data(__slice.call(this.raw.data)),i=0,_len=this.glyphIDs.length;i<_len;++i)result.pos=this.glyphOffsets[i];return result.data},CompoundGlyph}(),LocaTable=function(_super){function LocaTable(){return LocaTable.__super__.constructor.apply(this,arguments)}return __extends(LocaTable,_super),LocaTable.prototype.tag="loca",LocaTable.prototype.parse=function(data){var format,i;return data.pos=this.offset,format=this.file.head.indexToLocFormat,this.offsets=0===format?function(){var _ref,_results;for(_results=[],i=0,_ref=this.length;i<_ref;i+=2)_results.push(2*data.readUInt16());return _results}.call(this):function(){var _ref,_results;for(_results=[],i=0,_ref=this.length;i<_ref;i+=4)_results.push(data.readUInt32());return _results}.call(this)},LocaTable.prototype.indexOf=function(id){return this.offsets[id]},LocaTable.prototype.lengthOf=function(id){return this.offsets[id+1]-this.offsets[id]},LocaTable.prototype.encode=function(offsets,activeGlyphs){for(var LocaTable=new Uint32Array(this.offsets.length),glyfPtr=0,listGlyf=0,k=0;k<LocaTable.length;++k)if(LocaTable[k]=glyfPtr,listGlyf<activeGlyphs.length&&activeGlyphs[listGlyf]==k){++listGlyf,LocaTable[k]=glyfPtr;var start=this.offsets[k],len=this.offsets[k+1]-start;len>0&&(glyfPtr+=len)}for(var newLocaTable=new Array(4*LocaTable.length),j=0;j<LocaTable.length;++j)newLocaTable[4*j+3]=255&LocaTable[j],newLocaTable[4*j+2]=(65280&LocaTable[j])>>8,newLocaTable[4*j+1]=(16711680&LocaTable[j])>>16,newLocaTable[4*j]=(4278190080&LocaTable[j])>>24;return newLocaTable},LocaTable}(Table),Subset=function(){function Subset(font){this.font=font,this.subset={},this.unicodes={},this.next=33}return Subset.prototype.generateCmap=function(){var mapping,roman,unicode,unicodeCmap,_ref;for(roman in unicodeCmap=this.font.cmap.tables[0].codeMap,mapping={},_ref=this.subset)unicode=_ref[roman],mapping[roman]=unicodeCmap[unicode];return mapping},Subset.prototype.glyphsFor=function(glyphIDs){var additionalIDs,glyph,glyphs,id,_i,_len,_ref;for(glyphs={},_i=0,_len=glyphIDs.length;_i<_len;_i++)glyphs[id=glyphIDs[_i]]=this.font.glyf.glyphFor(id);for(id in additionalIDs=[],glyphs)(null!=(glyph=glyphs[id])?glyph.compound:void 0)&&additionalIDs.push.apply(additionalIDs,glyph.glyphIDs);if(additionalIDs.length>0)for(id in _ref=this.glyphsFor(additionalIDs))glyph=_ref[id],glyphs[id]=glyph;return glyphs},Subset.prototype.encode=function(glyID,indexToLocFormat){var cmap,code,glyf,glyphs,id,ids,loca,new2old,newIDs,nextGlyphID,old2new,oldID,oldIDs,tables,_ref;for(code in cmap=CmapTable.encode(this.generateCmap(),"unicode"),glyphs=this.glyphsFor(glyID),old2new={0:0},_ref=cmap.charMap)old2new[(ids=_ref[code]).old]=ids.new;for(oldID in nextGlyphID=cmap.maxGlyphID,glyphs)oldID in old2new||(old2new[oldID]=nextGlyphID++);return new2old=function(object){var key,ret;for(key in ret={},object)ret[object[key]]=key;return ret}(old2new),newIDs=Object.keys(new2old).sort((function(a,b){return a-b})),oldIDs=function(){var _i,_len,_results;for(_results=[],_i=0,_len=newIDs.length;_i<_len;_i++)id=newIDs[_i],_results.push(new2old[id]);return _results}(),glyf=this.font.glyf.encode(glyphs,oldIDs,old2new),loca=this.font.loca.encode(glyf.offsets,oldIDs),tables={cmap:this.font.cmap.raw(),glyf:glyf.table,loca:loca,hmtx:this.font.hmtx.raw(),hhea:this.font.hhea.raw(),maxp:this.font.maxp.raw(),post:this.font.post.raw(),name:this.font.name.raw(),head:this.font.head.encode(indexToLocFormat)},this.font.os2.exists&&(tables["OS/2"]=this.font.os2.raw()),this.font.directory.encode(tables)},Subset}();return jsPDF.API.PDFObject=function(){var pad;function PDFObject(){}return pad=function(str,length){return(Array(length+1).join("0")+str).slice(-length)},PDFObject.convert=function(object){var e,key,out,val;if(Array.isArray(object))return"["+function(){var _i,_len,_results;for(_results=[],_i=0,_len=object.length;_i<_len;_i++)e=object[_i],_results.push(PDFObject.convert(e));return _results}().join(" ")+"]";if("string"==typeof object)return"/"+object;if(null!=object?object.isString:void 0)return"("+object+")";if(object instanceof Date)return"(D:"+pad(object.getUTCFullYear(),4)+pad(object.getUTCMonth(),2)+pad(object.getUTCDate(),2)+pad(object.getUTCHours(),2)+pad(object.getUTCMinutes(),2)+pad(object.getUTCSeconds(),2)+"Z)";if("[object Object]"==={}.toString.call(object)){for(key in out=["<<"],object)val=object[key],out.push("/"+key+" "+PDFObject.convert(val));return out.push(">>"),out.join("\n")}return""+object},PDFObject}(),exports.AcroForm=AcroForm,exports.AcroFormAppearance=AcroFormAppearance,exports.AcroFormButton=AcroFormButton,exports.AcroFormCheckBox=AcroFormCheckBox,exports.AcroFormChoiceField=AcroFormChoiceField,exports.AcroFormComboBox=AcroFormComboBox,exports.AcroFormEditBox=AcroFormEditBox,exports.AcroFormListBox=AcroFormListBox,exports.AcroFormPasswordField=AcroFormPasswordField,exports.AcroFormPushButton=AcroFormPushButton,exports.AcroFormRadioButton=AcroFormRadioButton,exports.AcroFormTextField=AcroFormTextField,exports.GState=GState,exports.ShadingPattern=ShadingPattern,exports.TilingPattern=TilingPattern,exports.default=jsPDF,exports.jsPDF=jsPDF,Object.defineProperty(exports,"__esModule",{value:!0}),exports.default}));
 
 //# sourceMappingURL=jspdf.min.js.map
\ No newline at end of file
diff --git a/amd/build/jspdf.min.js.map b/amd/build/jspdf.min.js.map
index f9fa69f97b7c4f2e41c44a72d5afc963b15d6429..f2caa79b0c4e3af9f16f420581bde2ba68777b53 100644
--- a/amd/build/jspdf.min.js.map
+++ b/amd/build/jspdf.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"jspdf.min.js","sources":["../src/jspdf.js"],"sourcesContent":["define(function() {\n \n \n  var _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n    return typeof obj;\n  } : function (obj) {\n    return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n  };\n\n\n  /** @preserve\n   * jsPDF - PDF Document creation from JavaScript\n   * Version 1.4.1 Built on 2018-06-06T07:49:28.721Z\n   *                           CommitID 3233f44044\n   *\n   * Copyright (c) 2010-2016 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF\n   *               2010 Aaron Spike, https://github.com/acspike\n   *               2012 Willow Systems Corporation, willow-systems.com\n   *               2012 Pablo Hess, https://github.com/pablohess\n   *               2012 Florian Jenett, https://github.com/fjenett\n   *               2013 Warren Weckesser, https://github.com/warrenweckesser\n   *               2013 Youssef Beddad, https://github.com/lifof\n   *               2013 Lee Driscoll, https://github.com/lsdriscoll\n   *               2013 Stefan Slonevskiy, https://github.com/stefslon\n   *               2013 Jeremy Morel, https://github.com/jmorel\n   *               2013 Christoph Hartmann, https://github.com/chris-rock\n   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria\n   *               2014 James Makes, https://github.com/dollaruw\n   *               2014 Diego Casorran, https://github.com/diegocr\n   *               2014 Steven Spungin, https://github.com/Flamenco\n   *               2014 Kenneth Glassey, https://github.com/Gavvers\n   *\n   * Licensed under the MIT License\n   *\n   * Contributor(s):\n   *    siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango,\n   *    kim3er, mfo, alnorth, Flamenco\n   */\n\n  /**\n   * Creates new jsPDF document object instance.\n   * @name jsPDF\n   * @class\n   * @param orientation {String/Object} Orientation of the first page. Possible values are \"portrait\" or \"landscape\" (or shortcuts \"p\" (Default), \"l\") <br />\n   * Can also be an options object.\n   * @param unit {String}  Measurement unit to be used when coordinates are specified.<br />\n   * Possible values are \"pt\" (points), \"mm\" (Default), \"cm\", \"in\" or \"px\".\n   * @param format {String/Array} The format of the first page. Can be <ul><li>a0 - a10</li><li>b0 - b10</li><li>c0 - c10</li><li>c0 - c10</li><li>dl</li><li>letter</li><li>government-letter</li><li>legal</li><li>junior-legal</li><li>ledger</li><li>tabloid</li><li>credit-card</li></ul><br />\n   * Default is \"a4\". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array , e.g. [595.28, 841.89]\n   * @returns {jsPDF}\n   * @description\n   * If the first parameter (orientation) is an object, it will be interpreted as an object of named parameters\n   * ```\n   * {\n   *  orientation: 'p',\n   *  unit: 'mm',\n   *  format: 'a4',\n   *  hotfixes: [] // an array of hotfix strings to enable\n   * }\n   * ```\n   */\n  var jsPDF = function (global) {\n\n    var pdfVersion = '1.3',\n        pageFormats = { // Size in pt of various paper formats\n      'a0': [2383.94, 3370.39],\n      'a1': [1683.78, 2383.94],\n      'a2': [1190.55, 1683.78],\n      'a3': [841.89, 1190.55],\n      'a4': [595.28, 841.89],\n      'a5': [419.53, 595.28],\n      'a6': [297.64, 419.53],\n      'a7': [209.76, 297.64],\n      'a8': [147.40, 209.76],\n      'a9': [104.88, 147.40],\n      'a10': [73.70, 104.88],\n      'b0': [2834.65, 4008.19],\n      'b1': [2004.09, 2834.65],\n      'b2': [1417.32, 2004.09],\n      'b3': [1000.63, 1417.32],\n      'b4': [708.66, 1000.63],\n      'b5': [498.90, 708.66],\n      'b6': [354.33, 498.90],\n      'b7': [249.45, 354.33],\n      'b8': [175.75, 249.45],\n      'b9': [124.72, 175.75],\n      'b10': [87.87, 124.72],\n      'c0': [2599.37, 3676.54],\n      'c1': [1836.85, 2599.37],\n      'c2': [1298.27, 1836.85],\n      'c3': [918.43, 1298.27],\n      'c4': [649.13, 918.43],\n      'c5': [459.21, 649.13],\n      'c6': [323.15, 459.21],\n      'c7': [229.61, 323.15],\n      'c8': [161.57, 229.61],\n      'c9': [113.39, 161.57],\n      'c10': [79.37, 113.39],\n      'dl': [311.81, 623.62],\n      'letter': [612, 792],\n      'government-letter': [576, 756],\n      'legal': [612, 1008],\n      'junior-legal': [576, 360],\n      'ledger': [1224, 792],\n      'tabloid': [792, 1224],\n      'credit-card': [153, 243]\n    };\n\n    /**\n     * jsPDF's Internal PubSub Implementation.\n     * See mrrio.github.io/jsPDF/doc/symbols/PubSub.html\n     * Backward compatible rewritten on 2014 by\n     * Diego Casorran, https://github.com/diegocr\n     *\n     * @class\n     * @name PubSub\n     * @ignore This should not be in the public docs.\n     */\n    function PubSub(context) {\n      var topics = {};\n\n      this.subscribe = function (topic, callback, once) {\n        if (typeof callback !== 'function') {\n          return false;\n        }\n\n        if (!topics.hasOwnProperty(topic)) {\n          topics[topic] = {};\n        }\n\n        var id = Math.random().toString(35);\n        topics[topic][id] = [callback, !!once];\n\n        return id;\n      };\n\n      this.unsubscribe = function (token) {\n        for (var topic in topics) {\n          if (topics[topic][token]) {\n            delete topics[topic][token];\n            return true;\n          }\n        }\n        return false;\n      };\n\n      this.publish = function (topic) {\n        if (topics.hasOwnProperty(topic)) {\n          var args = Array.prototype.slice.call(arguments, 1),\n              idr = [];\n\n          for (var id in topics[topic]) {\n            var sub = topics[topic][id];\n            try {\n              sub[0].apply(context, args);\n            } catch (ex) {\n              if (global.console) {\n                console.error('jsPDF PubSub Error', ex.message, ex);\n              }\n            }\n            if (sub[1]) idr.push(id);\n          }\n          if (idr.length) idr.forEach(this.unsubscribe);\n        }\n      };\n    }\n\n    /**\n     * @constructor\n     * @private\n     */\n    function jsPDF(orientation, unit, format, compressPdf) {\n      var options = {};\n\n      if ((typeof orientation === 'undefined' ? 'undefined' : _typeof(orientation)) === 'object') {\n        options = orientation;\n\n        orientation = options.orientation;\n        unit = options.unit || unit;\n        format = options.format || format;\n        compressPdf = options.compress || options.compressPdf || compressPdf;\n      }\n\n      // Default options\n      unit = unit || 'mm';\n      format = format || 'a4';\n      orientation = ('' + (orientation || 'P')).toLowerCase();\n\n      var format_as_string = ('' + format).toLowerCase(),\n          compress = !!compressPdf && typeof Uint8Array === 'function',\n          textColor = options.textColor || '0 g',\n          drawColor = options.drawColor || '0 G',\n          activeFontSize = options.fontSize || 16,\n          activeCharSpace = options.charSpace || 0,\n          R2L = options.R2L || false,\n          lineHeightProportion = options.lineHeight || 1.15,\n          lineWidth = options.lineWidth || 0.200025,\n          // 2mm\n      fileId = '00000000000000000000000000000000',\n          objectNumber = 2,\n          // 'n' Current object number\n      outToPages = !1,\n          // switches where out() prints. outToPages true = push to pages obj. outToPages false = doc builder content\n      offsets = [],\n          // List of offsets. Activated and reset by buildDocument(). Pupulated by various calls buildDocument makes.\n      fonts = {},\n          // collection of font objects, where key is fontKey - a dynamically created label for a given font.\n      fontmap = {},\n          // mapping structure fontName > fontStyle > font key - performance layer. See addFont()\n      activeFontKey,\n          // will be string representing the KEY of the font as combination of fontName + fontStyle\n      k,\n          // Scale factor\n      tmp,\n          page = 0,\n          currentPage,\n          pages = [],\n          pagesContext = [],\n          // same index as pages and pagedim\n      pagedim = [],\n          content = [],\n          additionalObjects = [],\n          lineCapID = 0,\n          lineJoinID = 0,\n          content_length = 0,\n          pageWidth,\n          pageHeight,\n          pageMode,\n          zoomMode,\n          layoutMode,\n          creationDate,\n          documentProperties = {\n        'title': '',\n        'subject': '',\n        'author': '',\n        'keywords': '',\n        'creator': ''\n      },\n          API = {},\n          events = new PubSub(API),\n          hotfixes = options.hotfixes || [],\n\n\n      /////////////////////\n      // Private functions\n      /////////////////////\n      generateColorString = function generateColorString(options) {\n        var color;\n\n        var ch1 = options.ch1;\n        var ch2 = options.ch2;\n        var ch3 = options.ch3;\n        var ch4 = options.ch4;\n        var precision = options.precision;\n        var letterArray = options.pdfColorType === \"draw\" ? ['G', 'RG', 'K'] : ['g', 'rg', 'k'];\n\n        if (typeof ch1 === \"string\" && ch1.charAt(0) !== '#') {\n          var rgbColor = new RGBColor(ch1);\n          if (rgbColor.ok) {\n            ch1 = rgbColor.toHex();\n          }\n        }\n        //convert short rgb to long form\n        if (typeof ch1 === \"string\" && /^#[0-9A-Fa-f]{3}$/.test(ch1)) {\n          ch1 = '#' + ch1[1] + ch1[1] + ch1[2] + ch1[2] + ch1[3] + ch1[3];\n        }\n\n        if (typeof ch1 === \"string\" && /^#[0-9A-Fa-f]{6}$/.test(ch1)) {\n          var hex = parseInt(ch1.substr(1), 16);\n          ch1 = hex >> 16 & 255;\n          ch2 = hex >> 8 & 255;\n          ch3 = hex & 255;\n        }\n\n        if (typeof ch2 === \"undefined\" || typeof ch4 === \"undefined\" && ch1 === ch2 && ch2 === ch3) {\n          // Gray color space.\n          if (typeof ch1 === \"string\") {\n            color = ch1 + \" \" + letterArray[0];\n          } else {\n            switch (options.precision) {\n              case 2:\n                color = f2(ch1 / 255) + \" \" + letterArray[0];\n                break;\n              case 3:\n              default:\n                color = f3(ch1 / 255) + \" \" + letterArray[0];\n            }\n          }\n        } else if (typeof ch4 === \"undefined\" || (typeof ch4 === 'undefined' ? 'undefined' : _typeof(ch4)) === \"object\") {\n          // assume RGB\n          if (typeof ch1 === \"string\") {\n            color = [ch1, ch2, ch3, letterArray[1]].join(\" \");\n          } else {\n            switch (options.precision) {\n              case 2:\n                color = [f2(ch1 / 255), f2(ch2 / 255), f2(ch3 / 255), letterArray[1]].join(\" \");\n                break;\n              default:\n              case 3:\n                color = [f3(ch1 / 255), f3(ch2 / 255), f3(ch3 / 255), letterArray[1]].join(\" \");\n            }\n          }\n          // assume RGBA\n          if (ch4 && ch4.a === 0) {\n            //TODO Implement transparency.\n            //WORKAROUND use white for now\n            color = ['255', '255', '255', letterArray[1]].join(\" \");\n          }\n        } else {\n          // assume CMYK\n          if (typeof ch1 === 'string') {\n            color = [ch1, ch2, ch3, ch4, letterArray[2]].join(\" \");\n          } else {\n            switch (options.precision) {\n              case 2:\n                color = [f2(ch1), f2(ch2), f2(ch3), f2(ch4), letterArray[2]].join(\" \");\n                break;\n              case 3:\n              default:\n                color = [f3(ch1), f3(ch2), f3(ch3), f3(ch4), letterArray[2]].join(\" \");\n            }\n          }\n        }\n        return color;\n      },\n          convertDateToPDFDate = function convertDateToPDFDate(parmDate) {\n        var padd2 = function padd2(number) {\n          return ('0' + parseInt(number)).slice(-2);\n        };\n        var result = '';\n        var tzoffset = parmDate.getTimezoneOffset(),\n            tzsign = tzoffset < 0 ? '+' : '-',\n            tzhour = Math.floor(Math.abs(tzoffset / 60)),\n            tzmin = Math.abs(tzoffset % 60),\n            timeZoneString = [tzsign, padd2(tzhour), \"'\", padd2(tzmin), \"'\"].join('');\n\n        result = ['D:', parmDate.getFullYear(), padd2(parmDate.getMonth() + 1), padd2(parmDate.getDate()), padd2(parmDate.getHours()), padd2(parmDate.getMinutes()), padd2(parmDate.getSeconds()), timeZoneString].join('');\n        return result;\n      },\n          convertPDFDateToDate = function convertPDFDateToDate(parmPDFDate) {\n        var year = parseInt(parmPDFDate.substr(2, 4), 10);\n        var month = parseInt(parmPDFDate.substr(6, 2), 10) - 1;\n        var date = parseInt(parmPDFDate.substr(8, 2), 10);\n        var hour = parseInt(parmPDFDate.substr(10, 2), 10);\n        var minutes = parseInt(parmPDFDate.substr(12, 2), 10);\n        var seconds = parseInt(parmPDFDate.substr(14, 2), 10);\n        var timeZoneHour = parseInt(parmPDFDate.substr(16, 2), 10);\n        var timeZoneMinutes = parseInt(parmPDFDate.substr(20, 2), 10);\n\n        var resultingDate = new Date(year, month, date, hour, minutes, seconds, 0);\n        return resultingDate;\n      },\n          setCreationDate = function setCreationDate(date) {\n        var tmpCreationDateString;\n        var regexPDFCreationDate = /^D:(20[0-2][0-9]|203[0-7]|19[7-9][0-9])(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])(0[0-9]|1[0-9]|2[0-3])(0[0-9]|[1-5][0-9])(0[0-9]|[1-5][0-9])(\\+0[0-9]|\\+1[0-4]|\\-0[0-9]|\\-1[0-1])\\'(0[0-9]|[1-5][0-9])\\'?$/;\n        if ((typeof date === 'undefined' ? 'undefined' : _typeof(date)) === undefined) {\n          date = new Date();\n        }\n\n        if ((typeof date === 'undefined' ? 'undefined' : _typeof(date)) === \"object\" && Object.prototype.toString.call(date) === \"[object Date]\") {\n          tmpCreationDateString = convertDateToPDFDate(date);\n        } else if (regexPDFCreationDate.test(date)) {\n          tmpCreationDateString = date;\n        } else {\n          tmpCreationDateString = convertDateToPDFDate(new Date());\n        }\n        creationDate = tmpCreationDateString;\n        return creationDate;\n      },\n          getCreationDate = function getCreationDate(type) {\n        var result = creationDate;\n        if (type === \"jsDate\") {\n          result = convertPDFDateToDate(creationDate);\n        }\n        return result;\n      },\n          setFileId = function setFileId(value) {\n        value = value || \"12345678901234567890123456789012\".split('').map(function () {\n          return \"ABCDEF0123456789\".charAt(Math.floor(Math.random() * 16));\n        }).join('');\n        fileId = value;\n        return fileId;\n      },\n          getFileId = function getFileId() {\n        return fileId;\n      },\n          f2 = function f2(number) {\n        return number.toFixed(2); // Ie, %.2f\n      },\n          f3 = function f3(number) {\n        return number.toFixed(3); // Ie, %.3f\n      },\n          out = function out(string) {\n        string = typeof string === \"string\" ? string : string.toString();\n        if (outToPages) {\n          /* set by beginPage */\n          pages[currentPage].push(string);\n        } else {\n          // +1 for '\\n' that will be used to join 'content'\n          content_length += string.length + 1;\n          content.push(string);\n        }\n      },\n          newObject = function newObject() {\n        // Begin a new object\n        objectNumber++;\n        offsets[objectNumber] = content_length;\n        out(objectNumber + ' 0 obj');\n        return objectNumber;\n      },\n\n      // Does not output the object until after the pages have been output.\n      // Returns an object containing the objectId and content.\n      // All pages have been added so the object ID can be estimated to start right after.\n      // This does not modify the current objectNumber;  It must be updated after the newObjects are output.\n      newAdditionalObject = function newAdditionalObject() {\n        var objId = pages.length * 2 + 1;\n        objId += additionalObjects.length;\n        var obj = {\n          objId: objId,\n          content: ''\n        };\n        additionalObjects.push(obj);\n        return obj;\n      },\n\n      // Does not output the object.  The caller must call newObjectDeferredBegin(oid) before outputing any data\n      newObjectDeferred = function newObjectDeferred() {\n        objectNumber++;\n        offsets[objectNumber] = function () {\n          return content_length;\n        };\n        return objectNumber;\n      },\n          newObjectDeferredBegin = function newObjectDeferredBegin(oid) {\n        offsets[oid] = content_length;\n      },\n          putStream = function putStream(str) {\n        out('stream');\n        out(str);\n        out('endstream');\n      },\n          putPages = function putPages() {\n        var n,\n            p,\n            arr,\n            i,\n            deflater,\n            adler32,\n            adler32cs,\n            wPt,\n            hPt,\n            pageObjectNumbers = [];\n\n        adler32cs = global.adler32cs || jsPDF.API.adler32cs;\n        if (compress && typeof adler32cs === 'undefined') {\n          compress = false;\n        }\n\n        // outToPages = false as set in endDocument(). out() writes to content.\n\n        for (n = 1; n <= page; n++) {\n          pageObjectNumbers.push(newObject());\n          wPt = (pageWidth = pagedim[n].width) * k;\n          hPt = (pageHeight = pagedim[n].height) * k;\n          out('<</Type /Page');\n          out('/Parent 1 0 R');\n          out('/Resources 2 0 R');\n          out('/MediaBox [0 0 ' + f2(wPt) + ' ' + f2(hPt) + ']');\n          // Added for annotation plugin\n          events.publish('putPage', {\n            pageNumber: n,\n            page: pages[n]\n          });\n          out('/Contents ' + (objectNumber + 1) + ' 0 R');\n          out('>>');\n          out('endobj');\n\n          // Page content\n          p = pages[n].join('\\n');\n          newObject();\n          if (compress) {\n            arr = [];\n            i = p.length;\n            while (i--) {\n              arr[i] = p.charCodeAt(i);\n            }\n            adler32 = adler32cs.from(p);\n            deflater = new Deflater(6);\n            deflater.append(new Uint8Array(arr));\n            p = deflater.flush();\n            arr = new Uint8Array(p.length + 6);\n            arr.set(new Uint8Array([120, 156])), arr.set(p, 2);\n            arr.set(new Uint8Array([adler32 & 0xFF, adler32 >> 8 & 0xFF, adler32 >> 16 & 0xFF, adler32 >> 24 & 0xFF]), p.length + 2);\n            p = String.fromCharCode.apply(null, arr);\n            out('<</Length ' + p.length + ' /Filter [/FlateDecode]>>');\n          } else {\n            out('<</Length ' + p.length + '>>');\n          }\n          putStream(p);\n          out('endobj');\n        }\n        offsets[1] = content_length;\n        out('1 0 obj');\n        out('<</Type /Pages');\n        var kids = '/Kids [';\n        for (i = 0; i < page; i++) {\n          kids += pageObjectNumbers[i] + ' 0 R ';\n        }\n        out(kids + ']');\n        out('/Count ' + page);\n        out('>>');\n        out('endobj');\n        events.publish('postPutPages');\n      },\n          putFont = function putFont(font) {\n\n        events.publish('putFont', {\n          font: font,\n          out: out,\n          newObject: newObject\n        });\n        if (font.isAlreadyPutted !== true) {\n          font.objectNumber = newObject();\n          out('<<');\n          out('/Type /Font');\n          out('/BaseFont /' + font.postScriptName);\n          out('/Subtype /Type1');\n          if (typeof font.encoding === 'string') {\n            out('/Encoding /' + font.encoding);\n          }\n          out('/FirstChar 32');\n          out('/LastChar 255');\n          out('>>');\n          out('endobj');\n        }\n      },\n          putFonts = function putFonts() {\n        for (var fontKey in fonts) {\n          if (fonts.hasOwnProperty(fontKey)) {\n            putFont(fonts[fontKey]);\n          }\n        }\n      },\n          putXobjectDict = function putXobjectDict() {\n        // Loop through images, or other data objects\n        events.publish('putXobjectDict');\n      },\n          putResourceDictionary = function putResourceDictionary() {\n        out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');\n        out('/Font <<');\n\n        // Do this for each font, the '1' bit is the index of the font\n        for (var fontKey in fonts) {\n          if (fonts.hasOwnProperty(fontKey)) {\n            out('/' + fontKey + ' ' + fonts[fontKey].objectNumber + ' 0 R');\n          }\n        }\n        out('>>');\n        out('/XObject <<');\n        putXobjectDict();\n        out('>>');\n      },\n          putResources = function putResources() {\n        putFonts();\n        events.publish('putResources');\n        // Resource dictionary\n        offsets[2] = content_length;\n        out('2 0 obj');\n        out('<<');\n        putResourceDictionary();\n        out('>>');\n        out('endobj');\n        events.publish('postPutResources');\n      },\n          putAdditionalObjects = function putAdditionalObjects() {\n        events.publish('putAdditionalObjects');\n        for (var i = 0; i < additionalObjects.length; i++) {\n          var obj = additionalObjects[i];\n          offsets[obj.objId] = content_length;\n          out(obj.objId + ' 0 obj');\n          out(obj.content);        out('endobj');\n        }\n        objectNumber += additionalObjects.length;\n        events.publish('postPutAdditionalObjects');\n      },\n          addToFontDictionary = function addToFontDictionary(fontKey, fontName, fontStyle) {\n        // this is mapping structure for quick font key lookup.\n        // returns the KEY of the font (ex: \"F1\") for a given\n        // pair of font name and type (ex: \"Arial\". \"Italic\")\n        if (!fontmap.hasOwnProperty(fontName)) {\n          fontmap[fontName] = {};\n        }\n        fontmap[fontName][fontStyle] = fontKey;\n      },\n\n      /**\n       * FontObject describes a particular font as member of an instnace of jsPDF\n       *\n       * It's a collection of properties like 'id' (to be used in PDF stream),\n       * 'fontName' (font's family name), 'fontStyle' (font's style variant label)\n       *\n       * @class\n       * @public\n       * @property id {String} PDF-document-instance-specific label assinged to the font.\n       * @property postScriptName {String} PDF specification full name for the font\n       * @property encoding {Object} Encoding_name-to-Font_metrics_object mapping.\n       * @name FontObject\n       * @ignore This should not be in the public docs.\n       */\n      addFont = function addFont(postScriptName, fontName, fontStyle, encoding) {\n        var fontKey = 'F' + (Object.keys(fonts).length + 1).toString(10),\n\n        // This is FontObject\n        font = fonts[fontKey] = {\n          'id': fontKey,\n          'postScriptName': postScriptName,\n          'fontName': fontName,\n          'fontStyle': fontStyle,\n          'encoding': encoding,\n          'metadata': {}\n        };\n        addToFontDictionary(fontKey, fontName, fontStyle);\n        events.publish('addFont', font);\n\n        return fontKey;\n      },\n          addFonts = function addFonts() {\n\n        var HELVETICA = \"helvetica\",\n            TIMES = \"times\",\n            COURIER = \"courier\",\n            NORMAL = \"normal\",\n            BOLD = \"bold\",\n            ITALIC = \"italic\",\n            BOLD_ITALIC = \"bolditalic\",\n            ZAPF = \"zapfdingbats\",\n            SYMBOL = \"symbol\",\n            standardFonts = [['Helvetica', HELVETICA, NORMAL, 'WinAnsiEncoding'], ['Helvetica-Bold', HELVETICA, BOLD, 'WinAnsiEncoding'], ['Helvetica-Oblique', HELVETICA, ITALIC, 'WinAnsiEncoding'], ['Helvetica-BoldOblique', HELVETICA, BOLD_ITALIC, 'WinAnsiEncoding'], ['Courier', COURIER, NORMAL, 'WinAnsiEncoding'], ['Courier-Bold', COURIER, BOLD, 'WinAnsiEncoding'], ['Courier-Oblique', COURIER, ITALIC, 'WinAnsiEncoding'], ['Courier-BoldOblique', COURIER, BOLD_ITALIC, 'WinAnsiEncoding'], ['Times-Roman', TIMES, NORMAL, 'WinAnsiEncoding'], ['Times-Bold', TIMES, BOLD, 'WinAnsiEncoding'], ['Times-Italic', TIMES, ITALIC, 'WinAnsiEncoding'], ['Times-BoldItalic', TIMES, BOLD_ITALIC, 'WinAnsiEncoding'], ['ZapfDingbats', ZAPF, NORMAL, null], ['Symbol', SYMBOL, NORMAL, null]];\n\n        for (var i = 0, l = standardFonts.length; i < l; i++) {\n          var fontKey = addFont(standardFonts[i][0], standardFonts[i][1], standardFonts[i][2], standardFonts[i][3]);\n\n          // adding aliases for standard fonts, this time matching the capitalization\n          var parts = standardFonts[i][0].split('-');\n          addToFontDictionary(fontKey, parts[0], parts[1] || '');\n        }\n        events.publish('addFonts', {\n          fonts: fonts,\n          dictionary: fontmap\n        });\n      },\n          SAFE = function __safeCall(fn) {\n        fn.foo = function __safeCallWrapper() {\n          try {\n            return fn.apply(this, arguments);\n          } catch (e) {\n            var stack = e.stack || '';\n            if (~stack.indexOf(' at ')) stack = stack.split(\" at \")[1];\n            var m = \"Error in function \" + stack.split(\"\\n\")[0].split('<')[0] + \": \" + e.message;\n            if (global.console) {\n              global.console.error(m, e);\n              if (global.alert) alert(m);\n            } else {\n              throw new Error(m);\n            }\n          }\n        };\n        fn.foo.bar = fn;\n        return fn.foo;\n      },\n          to8bitStream = function to8bitStream(text, flags) {\n        /**\n         * PDF 1.3 spec:\n         * \"For text strings encoded in Unicode, the first two bytes must be 254 followed by\n         * 255, representing the Unicode byte order marker, U+FEFF. (This sequence conflicts\n         * with the PDFDocEncoding character sequence thorn ydieresis, which is unlikely\n         * to be a meaningful beginning of a word or phrase.) The remainder of the\n         * string consists of Unicode character codes, according to the UTF-16 encoding\n         * specified in the Unicode standard, version 2.0. Commonly used Unicode values\n         * are represented as 2 bytes per character, with the high-order byte appearing first\n         * in the string.\"\n         *\n         * In other words, if there are chars in a string with char code above 255, we\n         * recode the string to UCS2 BE - string doubles in length and BOM is prepended.\n         *\n         * HOWEVER!\n         * Actual *content* (body) text (as opposed to strings used in document properties etc)\n         * does NOT expect BOM. There, it is treated as a literal GID (Glyph ID)\n         *\n         * Because of Adobe's focus on \"you subset your fonts!\" you are not supposed to have\n         * a font that maps directly Unicode (UCS2 / UTF16BE) code to font GID, but you could\n         * fudge it with \"Identity-H\" encoding and custom CIDtoGID map that mimics Unicode\n         * code page. There, however, all characters in the stream are treated as GIDs,\n         * including BOM, which is the reason we need to skip BOM in content text (i.e. that\n         * that is tied to a font).\n         *\n         * To signal this \"special\" PDFEscape / to8bitStream handling mode,\n         * API.text() function sets (unless you overwrite it with manual values\n         * given to API.text(.., flags) )\n         * flags.autoencode = true\n         * flags.noBOM = true\n         *\n         * ===================================================================================\n         * `flags` properties relied upon:\n         *   .sourceEncoding = string with encoding label.\n         *                     \"Unicode\" by default. = encoding of the incoming text.\n         *                     pass some non-existing encoding name\n         *                     (ex: 'Do not touch my strings! I know what I am doing.')\n         *                     to make encoding code skip the encoding step.\n         *   .outputEncoding = Either valid PDF encoding name\n         *                     (must be supported by jsPDF font metrics, otherwise no encoding)\n         *                     or a JS object, where key = sourceCharCode, value = outputCharCode\n         *                     missing keys will be treated as: sourceCharCode === outputCharCode\n         *   .noBOM\n         *       See comment higher above for explanation for why this is important\n         *   .autoencode\n         *       See comment higher above for explanation for why this is important\n         */\n\n        var i, l, sourceEncoding, encodingBlock, outputEncoding, newtext, isUnicode, ch, bch;\n\n        flags = flags || {};\n        sourceEncoding = flags.sourceEncoding || 'Unicode';\n        outputEncoding = flags.outputEncoding;\n\n        // This 'encoding' section relies on font metrics format\n        // attached to font objects by, among others,\n        // \"Willow Systems' standard_font_metrics plugin\"\n        // see jspdf.plugin.standard_font_metrics.js for format\n        // of the font.metadata.encoding Object.\n        // It should be something like\n        //   .encoding = {'codePages':['WinANSI....'], 'WinANSI...':{code:code, ...}}\n        //   .widths = {0:width, code:width, ..., 'fof':divisor}\n        //   .kerning = {code:{previous_char_code:shift, ..., 'fof':-divisor},...}\n        if ((flags.autoencode || outputEncoding) && fonts[activeFontKey].metadata && fonts[activeFontKey].metadata[sourceEncoding] && fonts[activeFontKey].metadata[sourceEncoding].encoding) {\n          encodingBlock = fonts[activeFontKey].metadata[sourceEncoding].encoding;\n\n          // each font has default encoding. Some have it clearly defined.\n          if (!outputEncoding && fonts[activeFontKey].encoding) {\n            outputEncoding = fonts[activeFontKey].encoding;\n          }\n\n          // Hmmm, the above did not work? Let's try again, in different place.\n          if (!outputEncoding && encodingBlock.codePages) {\n            outputEncoding = encodingBlock.codePages[0]; // let's say, first one is the default\n          }\n\n          if (typeof outputEncoding === 'string') {\n            outputEncoding = encodingBlock[outputEncoding];\n          }\n          // we want output encoding to be a JS Object, where\n          // key = sourceEncoding's character code and\n          // value = outputEncoding's character code.\n          if (outputEncoding) {\n            isUnicode = false;\n            newtext = [];\n            for (i = 0, l = text.length; i < l; i++) {\n              ch = outputEncoding[text.charCodeAt(i)];\n              if (ch) {\n                newtext.push(String.fromCharCode(ch));\n              } else {\n                newtext.push(text[i]);\n              }\n\n              // since we are looping over chars anyway, might as well\n              // check for residual unicodeness\n              if (newtext[i].charCodeAt(0) >> 8) {\n                /* more than 255 */\n                isUnicode = true;\n              }\n            }\n            text = newtext.join('');\n          }\n        }\n\n        i = text.length;\n        // isUnicode may be set to false above. Hence the triple-equal to undefined\n        while (isUnicode === undefined && i !== 0) {\n          if (text.charCodeAt(i - 1) >> 8) {\n            /* more than 255 */\n            isUnicode = true;\n          }\n          i--;\n        }\n        if (!isUnicode) {\n          return text;\n        }\n\n        newtext = flags.noBOM ? [] : [254, 255];\n        for (i = 0, l = text.length; i < l; i++) {\n          ch = text.charCodeAt(i);\n          bch = ch >> 8; // divide by 256\n          if (bch >> 8) {\n            /* something left after dividing by 256 second time */\n            throw new Error(\"Character at position \" + i + \" of string '\" + text + \"' exceeds 16bits. Cannot be encoded into UCS-2 BE\");\n          }\n          newtext.push(bch);\n          newtext.push(ch - (bch << 8));\n        }\n        return String.fromCharCode.apply(undefined, newtext);\n      },\n          pdfEscape = function pdfEscape(text, flags) {\n        /**\n         * Replace '/', '(', and ')' with pdf-safe versions\n         *\n         * Doing to8bitStream does NOT make this PDF display unicode text. For that\n         * we also need to reference a unicode font and embed it - royal pain in the rear.\n         *\n         * There is still a benefit to to8bitStream - PDF simply cannot handle 16bit chars,\n         * which JavaScript Strings are happy to provide. So, while we still cannot display\n         * 2-byte characters property, at least CONDITIONALLY converting (entire string containing)\n         * 16bit chars to (USC-2-BE) 2-bytes per char + BOM streams we ensure that entire PDF\n         * is still parseable.\n         * This will allow immediate support for unicode in document properties strings.\n         */\n        return to8bitStream(text, flags).replace(/\\\\/g, '\\\\\\\\').replace(/\\(/g, '\\\\(').replace(/\\)/g, '\\\\)');\n      },\n          putInfo = function putInfo() {\n        out('/Producer (jsPDF ' + jsPDF.version + ')');\n        for (var key in documentProperties) {\n          if (documentProperties.hasOwnProperty(key) && documentProperties[key]) {\n            out('/' + key.substr(0, 1).toUpperCase() + key.substr(1) + ' (' + pdfEscape(documentProperties[key]) + ')');\n          }\n        }\n        out('/CreationDate (' + creationDate + ')');\n      },\n          putCatalog = function putCatalog() {\n        out('/Type /Catalog');\n        out('/Pages 1 0 R');\n        // PDF13ref Section 7.2.1\n        if (!zoomMode) zoomMode = 'fullwidth';\n        switch (zoomMode) {\n          case 'fullwidth':\n            out('/OpenAction [3 0 R /FitH null]');\n            break;\n          case 'fullheight':\n            out('/OpenAction [3 0 R /FitV null]');\n            break;\n          case 'fullpage':\n            out('/OpenAction [3 0 R /Fit]');\n            break;\n          case 'original':\n            out('/OpenAction [3 0 R /XYZ null null 1]');\n            break;\n          default:\n            var pcn = '' + zoomMode;\n            if (pcn.substr(pcn.length - 1) === '%') zoomMode = parseInt(zoomMode) / 100;\n            if (typeof zoomMode === 'number') {\n              out('/OpenAction [3 0 R /XYZ null null ' + f2(zoomMode) + ']');\n            }\n        }\n        if (!layoutMode) layoutMode = 'continuous';\n        switch (layoutMode) {\n          case 'continuous':\n            out('/PageLayout /OneColumn');\n            break;\n          case 'single':\n            out('/PageLayout /SinglePage');\n            break;\n          case 'two':\n          case 'twoleft':\n            out('/PageLayout /TwoColumnLeft');\n            break;\n          case 'tworight':\n            out('/PageLayout /TwoColumnRight');\n            break;\n        }\n        if (pageMode) {\n          /**\n           * A name object specifying how the document should be displayed when opened:\n           * UseNone      : Neither document outline nor thumbnail images visible -- DEFAULT\n           * UseOutlines  : Document outline visible\n           * UseThumbs    : Thumbnail images visible\n           * FullScreen   : Full-screen mode, with no menu bar, window controls, or any other window visible\n           */\n          out('/PageMode /' + pageMode);\n        }\n        events.publish('putCatalog');\n      },\n          putTrailer = function putTrailer() {\n        out('/Size ' + (objectNumber + 1));\n        out('/Root ' + objectNumber + ' 0 R');\n        out('/Info ' + (objectNumber - 1) + ' 0 R');\n        out(\"/ID [ <\" + fileId + \"> <\" + fileId + \"> ]\");\n      },\n          beginPage = function beginPage(width, height) {\n        // Dimensions are stored as user units and converted to points on output\n        var orientation = typeof height === 'string' && height.toLowerCase();\n        if (typeof width === 'string') {\n          var format = width.toLowerCase();\n          if (pageFormats.hasOwnProperty(format)) {\n            width = pageFormats[format][0] / k;\n            height = pageFormats[format][1] / k;\n          }\n        }\n        if (Array.isArray(width)) {\n          height = width[1];\n          width = width[0];\n        }\n        if (orientation) {\n          switch (orientation.substr(0, 1)) {\n            case 'l':\n              if (height > width) orientation = 's';\n              break;\n            case 'p':\n              if (width > height) orientation = 's';\n              break;\n          }\n          if (orientation === 's') {\n            tmp = width;\n            width = height;\n            height = tmp;\n          }\n        }\n        outToPages = true;\n        pages[++page] = [];\n        pagedim[page] = {\n          width: Number(width) || pageWidth,\n          height: Number(height) || pageHeight\n        };\n        pagesContext[page] = {};\n        _setPage(page);\n      },\n          _addPage = function _addPage() {\n        beginPage.apply(this, arguments);\n        // Set line width\n        out(f2(lineWidth * k) + ' w');\n        // Set draw color\n        out(drawColor);\n        // resurrecting non-default line caps, joins\n        if (lineCapID !== 0) {\n          out(lineCapID + ' J');\n        }\n        if (lineJoinID !== 0) {\n          out(lineJoinID + ' j');\n        }\n        events.publish('addPage', {\n          pageNumber: page\n        });\n      },\n          _deletePage = function _deletePage(n) {\n        if (n > 0 && n <= page) {\n          pages.splice(n, 1);\n          pagedim.splice(n, 1);\n          page--;\n          if (currentPage > page) {\n            currentPage = page;\n          }\n          this.setPage(currentPage);\n        }\n      },\n          _setPage = function _setPage(n) {\n        if (n > 0 && n <= page) {\n          currentPage = n;\n          pageWidth = pagedim[n].width;\n          pageHeight = pagedim[n].height;\n        }\n      },\n\n      /**\n       * Returns a document-specific font key - a label assigned to a\n       * font name + font type combination at the time the font was added\n       * to the font inventory.\n       *\n       * Font key is used as label for the desired font for a block of text\n       * to be added to the PDF document stream.\n       * @private\n       * @function\n       * @param fontName {String} can be undefined on \"falthy\" to indicate \"use current\"\n       * @param fontStyle {String} can be undefined on \"falthy\" to indicate \"use current\"\n       * @returns {String} Font key.\n       */\n      _getFont = function _getFont(fontName, fontStyle, options) {\n        var key = undefined,\n            fontNameLowerCase;\n        options = options || {};\n\n        fontName = fontName !== undefined ? fontName : fonts[activeFontKey].fontName;\n        fontStyle = fontStyle !== undefined ? fontStyle : fonts[activeFontKey].fontStyle;\n        fontNameLowerCase = fontName.toLowerCase();\n\n        if (fontmap[fontNameLowerCase] !== undefined && fontmap[fontNameLowerCase][fontStyle] !== undefined) {\n          key = fontmap[fontNameLowerCase][fontStyle];\n        } else if (fontmap[fontName] !== undefined && fontmap[fontName][fontStyle] !== undefined) {\n          key = fontmap[fontName][fontStyle];\n        } else {\n          if (options.disableWarning === false) {\n            console.warn(\"Unable to look up font label for font '\" + fontName + \"', '\" + fontStyle + \"'. Refer to getFontList() for available fonts.\");\n          }\n        }\n\n        if (!key && !options.noFallback) {\n          key = fontmap['times'][fontStyle];\n          if (key == null) {\n            key = fontmap['times']['normal'];\n          }\n        }\n        return key;\n      },\n          buildDocument = function buildDocument() {\n        outToPages = false; // switches out() to content\n\n        objectNumber = 2;\n        content_length = 0;\n        content = [];\n        offsets = [];\n        additionalObjects = [];\n        // Added for AcroForm\n        events.publish('buildDocument');\n\n        // putHeader()\n        out('%PDF-' + pdfVersion);\n        out(\"%\\xBA\\xDF\\xAC\\xE0\");\n\n        putPages();\n\n        // Must happen after putPages\n        // Modifies current object Id\n        putAdditionalObjects();\n\n        putResources();\n\n        // Info\n        newObject();\n        out('<<');\n        putInfo();\n        out('>>');\n        out('endobj');\n\n        // Catalog\n        newObject();\n        out('<<');\n        putCatalog();\n        out('>>');\n        out('endobj');\n\n        // Cross-ref\n        var o = content_length,\n            i,\n            p = \"0000000000\";\n        out('xref');\n        out('0 ' + (objectNumber + 1));\n        out(p + ' 65535 f ');\n        for (i = 1; i <= objectNumber; i++) {\n          var offset = offsets[i];\n          if (typeof offset === 'function') {\n            out((p + offsets[i]()).slice(-10) + ' 00000 n ');\n          } else {\n            out((p + offsets[i]).slice(-10) + ' 00000 n ');\n          }\n        }\n        // Trailer\n        out('trailer');\n        out('<<');\n        putTrailer();\n        out('>>');\n        out('startxref');\n        out('' + o);\n        out('%%EOF');\n\n        outToPages = true;\n\n        return content.join('\\n');\n      },\n          getStyle = function getStyle(style) {\n        // see path-painting operators in PDF spec\n        var op = 'S'; // stroke\n        if (style === 'F') {\n          op = 'f'; // fill\n        } else if (style === 'FD' || style === 'DF') {\n          op = 'B'; // both\n        } else if (style === 'f' || style === 'f*' || style === 'B' || style === 'B*') {\n          /*\n           Allow direct use of these PDF path-painting operators:\n           - f    fill using nonzero winding number rule\n           - f*    fill using even-odd rule\n           - B    fill then stroke with fill using non-zero winding number rule\n           - B*    fill then stroke with fill using even-odd rule\n           */\n          op = style;\n        }\n        return op;\n      },\n          getArrayBuffer = function getArrayBuffer() {\n        var data = buildDocument(),\n            len = data.length,\n            ab = new ArrayBuffer(len),\n            u8 = new Uint8Array(ab);\n\n        while (len--) {\n          u8[len] = data.charCodeAt(len);\n        }return ab;\n      },\n          getBlob = function getBlob() {\n        return new Blob([getArrayBuffer()], {\n          type: \"application/pdf\"\n        });\n      },\n\n      /**\n       * Generates the PDF document.\n       *\n       * If `type` argument is undefined, output is raw body of resulting PDF returned as a string.\n       *\n       * @param {String} type A string identifying one of the possible output types.\n       * @param {Object} options An object providing some additional signalling to PDF generator.\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name output\n       */\n      _output = SAFE(function (type, options) {\n        var datauri = ('' + type).substr(0, 6) === 'dataur' ? 'data:application/pdf;base64,' + btoa(buildDocument()) : 0;\n\n        switch (type) {\n          case undefined:\n            return buildDocument();\n          case 'save':\n            if ((typeof navigator === 'undefined' ? 'undefined' : _typeof(navigator)) === \"object\" && navigator.getUserMedia) {\n              if (global.URL === undefined || global.URL.createObjectURL === undefined) {\n                return API.output('dataurlnewwindow');\n              }\n            }\n            saveAs(getBlob(), options);\n            if (typeof saveAs.unload === 'function') {\n              if (global.setTimeout) {\n                setTimeout(saveAs.unload, 911);\n              }\n            }\n            break;\n          case 'arraybuffer':\n            return getArrayBuffer();\n          case 'blob':\n            return getBlob();\n          case 'bloburi':\n          case 'bloburl':\n            // User is responsible of calling revokeObjectURL\n            return global.URL && global.URL.createObjectURL(getBlob()) || void 0;\n          case 'datauristring':\n          case 'dataurlstring':\n            return datauri;\n          case 'dataurlnewwindow':\n            var nW = global.open(datauri);\n            if (nW || typeof safari === \"undefined\") return nW;\n          /* pass through */\n          case 'datauri':\n          case 'dataurl':\n            return global.document.location.href = datauri;\n          default:\n            throw new Error('Output type \"' + type + '\" is not supported.');\n        }\n        // @TODO: Add different output options\n      }),\n\n\n      /**\n       * Used to see if a supplied hotfix was requested when the pdf instance was created.\n       * @param {String} hotfixName - The name of the hotfix to check.\n       * @returns {boolean}\n       */\n      hasHotfix = function hasHotfix(hotfixName) {\n        return Array.isArray(hotfixes) === true && hotfixes.indexOf(hotfixName) > -1;\n      };\n\n      switch (unit) {\n        case 'pt':\n          k = 1;\n          break;\n        case 'mm':\n          k = 72 / 25.4;\n          break;\n        case 'cm':\n          k = 72 / 2.54;\n          break;\n        case 'in':\n          k = 72;\n          break;\n        case 'px':\n          if (hasHotfix('px_scaling') == true) {\n            k = 72 / 96;\n          } else {\n            k = 96 / 72;\n          }\n          break;\n        case 'pc':\n          k = 12;\n          break;\n        case 'em':\n          k = 12;\n          break;\n        case 'ex':\n          k = 6;\n          break;\n        default:\n          throw 'Invalid unit: ' + unit;\n      }\n\n      setCreationDate();\n      setFileId();\n\n      //---------------------------------------\n      // Public API\n\n      /**\n       * Object exposing internal API to plugins\n       * @public\n       */\n      API.internal = {\n        'pdfEscape': pdfEscape,\n        'getStyle': getStyle,\n        /**\n         * Returns {FontObject} describing a particular font.\n         * @public\n         * @function\n         * @param fontName {String} (Optional) Font's family name\n         * @param fontStyle {String} (Optional) Font's style variation name (Example:\"Italic\")\n         * @returns {FontObject}\n         */\n        'getFont': function getFont() {\n          return fonts[_getFont.apply(API, arguments)];\n        },\n        'getFontSize': function getFontSize() {\n          return activeFontSize;\n        },\n        'getCharSpace': function getCharSpace() {\n          return activeCharSpace;\n        },\n        'getTextColor': function getTextColor() {\n          var colorEncoded = textColor.split(' ');\n          if (colorEncoded.length === 2 && colorEncoded[1] === 'g') {\n            // convert grayscale value to rgb so that it can be converted to hex for consistency\n            var floatVal = parseFloat(colorEncoded[0]);\n            colorEncoded = [floatVal, floatVal, floatVal, 'r'];\n          }\n          var colorAsHex = '#';\n          for (var i = 0; i < 3; i++) {\n            colorAsHex += ('0' + Math.floor(parseFloat(colorEncoded[i]) * 255).toString(16)).slice(-2);\n          }\n          return colorAsHex;\n        },\n        'getLineHeight': function getLineHeight() {\n          return activeFontSize * lineHeightProportion;\n        },\n        'write': function write(string1 /*, string2, string3, etc */) {\n          out(arguments.length === 1 ? string1 : Array.prototype.join.call(arguments, ' '));\n        },\n        'getCoordinateString': function getCoordinateString(value) {\n          return f2(value * k);\n        },\n        'getVerticalCoordinateString': function getVerticalCoordinateString(value) {\n          return f2((pageHeight - value) * k);\n        },\n        'collections': {},\n        'newObject': newObject,\n        'newAdditionalObject': newAdditionalObject,\n        'newObjectDeferred': newObjectDeferred,\n        'newObjectDeferredBegin': newObjectDeferredBegin,\n        'putStream': putStream,\n        'events': events,\n        // ratio that you use in multiplication of a given \"size\" number to arrive to 'point'\n        // units of measurement.\n        // scaleFactor is set at initialization of the document and calculated against the stated\n        // default measurement units for the document.\n        // If default is \"mm\", k is the number that will turn number in 'mm' into 'points' number.\n        // through multiplication.\n        'scaleFactor': k,\n        'pageSize': {\n          getWidth: function getWidth() {\n            return pageWidth;\n          },\n          getHeight: function getHeight() {\n            return pageHeight;\n          }\n        },\n        'output': function output(type, options) {\n          return _output(type, options);\n        },\n        'getNumberOfPages': function getNumberOfPages() {\n          return pages.length - 1;\n        },\n        'pages': pages,\n        'out': out,\n        'f2': f2,\n        'getPageInfo': function getPageInfo(pageNumberOneBased) {\n          var objId = (pageNumberOneBased - 1) * 2 + 3;\n          return {\n            objId: objId,\n            pageNumber: pageNumberOneBased,\n            pageContext: pagesContext[pageNumberOneBased]\n          };\n        },\n        'getCurrentPageInfo': function getCurrentPageInfo() {\n          var objId = (currentPage - 1) * 2 + 3;\n          return {\n            objId: objId,\n            pageNumber: currentPage,\n            pageContext: pagesContext[currentPage]\n          };\n        },\n        'getPDFVersion': function getPDFVersion() {\n          return pdfVersion;\n        },\n        'hasHotfix': hasHotfix //Expose the hasHotfix check so plugins can also check them.\n      };\n\n      /**\n       * Adds (and transfers the focus to) new page to the PDF document.\n       * @param format {String/Array} The format of the new page. Can be <ul><li>a0 - a10</li><li>b0 - b10</li><li>c0 - c10</li><li>c0 - c10</li><li>dl</li><li>letter</li><li>government-letter</li><li>legal</li><li>junior-legal</li><li>ledger</li><li>tabloid</li><li>credit-card</li></ul><br />\n       * Default is \"a4\". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array , e.g. [595.28, 841.89]\n       * @param orientation {String} Orientation of the new page. Possible values are \"portrait\" or \"landscape\" (or shortcuts \"p\" (Default), \"l\") \n       * @function\n       * @returns {jsPDF}\n       *\n       * @methodOf jsPDF#\n       * @name addPage\n       */\n      API.addPage = function () {\n        _addPage.apply(this, arguments);\n        return this;\n      };\n      /**\n       * Adds (and transfers the focus to) new page to the PDF document.\n       * @function\n       * @returns {jsPDF}\n       *\n       * @methodOf jsPDF#\n       * @name setPage\n       * @param {Number} page Switch the active page to the page number specified\n       * @example\n       * doc = jsPDF()\n       * doc.addPage()\n       * doc.addPage()\n       * doc.text('I am on page 3', 10, 10)\n       * doc.setPage(1)\n       * doc.text('I am on page 1', 10, 10)\n       */\n      API.setPage = function () {\n        _setPage.apply(this, arguments);\n        return this;\n      };\n      API.insertPage = function (beforePage) {\n        this.addPage();\n        this.movePage(currentPage, beforePage);\n        return this;\n      };\n      API.movePage = function (targetPage, beforePage) {\n        if (targetPage > beforePage) {\n          var tmpPages = pages[targetPage];\n          var tmpPagedim = pagedim[targetPage];\n          var tmpPagesContext = pagesContext[targetPage];\n          for (var i = targetPage; i > beforePage; i--) {\n            pages[i] = pages[i - 1];\n            pagedim[i] = pagedim[i - 1];\n            pagesContext[i] = pagesContext[i - 1];\n          }\n          pages[beforePage] = tmpPages;\n          pagedim[beforePage] = tmpPagedim;\n          pagesContext[beforePage] = tmpPagesContext;\n          this.setPage(beforePage);\n        } else if (targetPage < beforePage) {\n          var tmpPages = pages[targetPage];\n          var tmpPagedim = pagedim[targetPage];\n          var tmpPagesContext = pagesContext[targetPage];\n          for (var i = targetPage; i < beforePage; i++) {\n            pages[i] = pages[i + 1];\n            pagedim[i] = pagedim[i + 1];\n            pagesContext[i] = pagesContext[i + 1];\n          }\n          pages[beforePage] = tmpPages;\n          pagedim[beforePage] = tmpPagedim;\n          pagesContext[beforePage] = tmpPagesContext;\n          this.setPage(beforePage);\n        }\n        return this;\n      };\n\n      API.deletePage = function () {\n        _deletePage.apply(this, arguments);\n        return this;\n      };\n\n      API.setCreationDate = function (date) {\n        setCreationDate(date);\n        return this;\n      };\n\n      API.getCreationDate = function (type) {\n        return getCreationDate(type);\n      };\n\n      API.setFileId = function (value) {\n        setFileId(value);\n        return this;\n      };\n\n      API.getFileId = function () {\n        return getFileId();\n      };\n\n      /**\n       * Set the display mode options of the page like zoom and layout.\n       *\n       * @param {integer|String} zoom   You can pass an integer or percentage as\n       * a string. 2 will scale the document up 2x, '200%' will scale up by the\n       * same amount. You can also set it to 'fullwidth', 'fullheight',\n       * 'fullpage', or 'original'.\n       *\n       * Only certain PDF readers support this, such as Adobe Acrobat\n       *\n       * @param {String} layout Layout mode can be: 'continuous' - this is the\n       * default continuous scroll. 'single' - the single page mode only shows one\n       * page at a time. 'twoleft' - two column left mode, first page starts on\n       * the left, and 'tworight' - pages are laid out in two columns, with the\n       * first page on the right. This would be used for books.\n       * @param {String} pmode 'UseOutlines' - it shows the\n       * outline of the document on the left. 'UseThumbs' - shows thumbnails along\n       * the left. 'FullScreen' - prompts the user to enter fullscreen mode.\n       *\n       * @function\n       * @returns {jsPDF}\n       * @name setDisplayMode\n       */\n      API.setDisplayMode = function (zoom, layout, pmode) {\n        zoomMode = zoom;\n        layoutMode = layout;\n        pageMode = pmode;\n\n        var validPageModes = [undefined, null, 'UseNone', 'UseOutlines', 'UseThumbs', 'FullScreen'];\n        if (validPageModes.indexOf(pmode) == -1) {\n          throw new Error('Page mode must be one of UseNone, UseOutlines, UseThumbs, or FullScreen. \"' + pmode + '\" is not recognized.');\n        }\n        return this;\n      };\n\n      /**\n       * Adds text to page. Supports adding multiline text when 'text' argument is an Array of Strings.\n       *\n       * @function\n       * @param {String|Array} text String or array of strings to be added to the page. Each line is shifted one line down per font, spacing settings declared before this call.\n       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n       * @param {Object} options Collection of settings signalling how the text must be encoded. Defaults are sane. If you think you want to pass some flags, you likely can read the source.\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name text\n       */\n      API.text = function (text, x, y, options) {\n        /**\n         * Inserts something like this into PDF\n         *   BT\n         *    /F1 16 Tf  % Font name + size\n         *    16 TL % How many units down for next line in multiline text\n         *    0 g % color\n         *    28.35 813.54 Td % position\n         *    (line one) Tj\n         *    T* (line two) Tj\n         *    T* (line three) Tj\n         *   ET\n         */\n\n        var xtra = '';\n        var isHex = false;\n        var lineHeight = lineHeightProportion;\n\n        var scope = this;\n\n        function ESC(s) {\n          s = s.split(\"\\t\").join(Array(options.TabLen || 9).join(\" \"));\n          return pdfEscape(s, flags);\n        }\n\n        function transformTextToSpecialArray(text) {\n          //we don't want to destroy original text array, so cloning it\n          var sa = text.concat();\n          var da = [];\n          var len = sa.length;\n          var curDa;\n          //we do array.join('text that must not be PDFescaped\")\n          //thus, pdfEscape each component separately\n          while (len--) {\n            curDa = sa.shift();\n            if (typeof curDa === \"string\") {\n              da.push(curDa);\n            } else {\n              if (Object.prototype.toString.call(text) === '[object Array]' && curDa.length === 1) {\n                da.push(curDa[0]);\n              } else {\n                da.push([curDa[0], curDa[1], curDa[2]]);\n              }\n            }\n          }\n          return da;\n        }\n\n        function processTextByFunction(text, processingFunction) {\n          var result;\n          if (typeof text === 'string') {\n            result = processingFunction(text)[0];\n          } else if (Object.prototype.toString.call(text) === '[object Array]') {\n            //we don't want to destroy original text array, so cloning it\n            var sa = text.concat();\n            var da = [];\n            var len = sa.length;\n            var curDa;\n            var tmpResult;\n            //we do array.join('text that must not be PDFescaped\")\n            //thus, pdfEscape each component separately\n            while (len--) {\n              curDa = sa.shift();\n              if (typeof curDa === \"string\") {\n                da.push(processingFunction(curDa)[0]);\n              } else if (Object.prototype.toString.call(curDa) === '[object Array]' && curDa[0] === \"string\") {\n                tmpResult = processingFunction(curDa[0], curDa[1], curDa[2]);\n                da.push([tmpResult[0], tmpResult[1], tmpResult[2]]);\n              }\n            }\n            result = da;\n          }\n          return result;\n        }\n\n        //backwardsCompatibility\n        var tmp;\n\n        // Pre-August-2012 the order of arguments was function(x, y, text, flags)\n        // in effort to make all calls have similar signature like\n        //   function(data, coordinates... , miscellaneous)\n        // this method had its args flipped.\n        // code below allows backward compatibility with old arg order.\n        if (typeof text === 'number') {\n          tmp = y;\n          y = x;\n          x = text;\n          text = tmp;\n        }\n\n        var flags = arguments[3];\n        var angle = arguments[4];\n        var align = arguments[5];\n\n        if ((typeof flags === 'undefined' ? 'undefined' : _typeof(flags)) !== \"object\" || flags === null) {\n          if (typeof angle === 'string') {\n            align = angle;\n            angle = null;\n          }\n          if (typeof flags === 'string') {\n            align = flags;\n            flags = null;\n          }\n          if (typeof flags === 'number') {\n            angle = flags;\n            flags = null;\n          }\n          options = { flags: flags, angle: angle, align: align };\n        }\n\n        //Check if text is of type String\n        var textIsOfTypeString = false;\n        var tmpTextIsOfTypeString = true;\n\n        if (typeof text === 'string') {\n          textIsOfTypeString = true;\n        } else if (Object.prototype.toString.call(text) === '[object Array]') {\n          //we don't want to destroy original text array, so cloning it\n          var sa = text.concat();\n          var da = [];\n          var len = sa.length;\n          var curDa;\n          //we do array.join('text that must not be PDFescaped\")\n          //thus, pdfEscape each component separately\n          while (len--) {\n            curDa = sa.shift();\n            if (typeof curDa !== \"string\" || Object.prototype.toString.call(curDa) === '[object Array]' && typeof curDa[0] !== \"string\") {\n              tmpTextIsOfTypeString = false;\n            }\n          }\n          textIsOfTypeString = tmpTextIsOfTypeString;\n        }\n        if (textIsOfTypeString === false) {\n          throw new Error('Type of text must be string or Array. \"' + text + '\" is not recognized.');\n        }\n\n        //Escaping \n        var activeFontEncoding = fonts[activeFontKey].encoding;\n\n        if (activeFontEncoding === \"WinAnsiEncoding\" || activeFontEncoding === \"StandardEncoding\") {\n          text = processTextByFunction(text, function (text, posX, posY) {\n            return [ESC(text), posX, posY];\n          });\n        }\n        //If there are any newlines in text, we assume\n        //the user wanted to print multiple lines, so break the\n        //text up into an array. If the text is already an array,\n        //we assume the user knows what they are doing.\n        //Convert text into an array anyway to simplify\n        //later code.\n\n        if (typeof text === 'string') {\n          if (text.match(/[\\r?\\n]/)) {\n            text = text.split(/\\r\\n|\\r|\\n/g);\n          } else {\n            text = [text];\n          }\n        }\n\n        //multiline\n        var maxWidth = options.maxWidth || 0;\n\n        if (maxWidth > 0) {\n          if (typeof text === 'string') {\n            text = scope.splitTextToSize(text, maxWidth);\n          } else if (Object.prototype.toString.call(text) === '[object Array]') {\n            text = scope.splitTextToSize(text.join(\" \"), maxWidth);\n          }\n        }\n\n        //creating Payload-Object to make text byRef\n        var payload = {\n          text: text,\n          x: x,\n          y: y,\n          options: options,\n          mutex: {\n            pdfEscape: pdfEscape,\n            activeFontKey: activeFontKey,\n            fonts: fonts,\n            activeFontSize: activeFontSize\n          }\n        };\n        events.publish('preProcessText', payload);\n\n        text = payload.text;\n        options = payload.options;\n        //angle\n\n        var angle = options.angle;\n        var k = scope.internal.scaleFactor;\n        var curY = (scope.internal.pageSize.getHeight() - y) * k;\n        var transformationMatrix = [];\n\n        if (angle) {\n          angle *= Math.PI / 180;\n          var c = Math.cos(angle),\n              s = Math.sin(angle);\n          var f2 = function f2(number) {\n            return number.toFixed(2);\n          };\n          transformationMatrix = [f2(c), f2(s), f2(s * -1), f2(c)];\n        }\n\n        //charSpace\n\n        var charSpace = options.charSpace;\n\n        if (charSpace !== undefined) {\n          xtra += charSpace + \" Tc\\n\";\n        }\n\n        //lang\n\n        var lang = options.lang;\n        var tmpRenderingMode = -1;\n        var parmRenderingMode = options.renderingMode || options.stroke;\n        var pageContext = scope.internal.getCurrentPageInfo().pageContext;\n\n        switch (parmRenderingMode) {\n          case 0:\n          case false:\n          case 'fill':\n            tmpRenderingMode = 0;\n            break;\n          case 1:\n          case true:\n          case 'stroke':\n            tmpRenderingMode = 1;\n            break;\n          case 2:\n          case 'fillThenStroke':\n            tmpRenderingMode = 2;\n            break;\n          case 3:\n          case 'invisible':\n            tmpRenderingMode = 3;\n            break;\n          case 4:\n          case 'fillAndAddForClipping':\n            tmpRenderingMode = 4;\n            break;\n          case 5:\n          case 'strokeAndAddPathForClipping':\n            tmpRenderingMode = 5;\n            break;\n          case 6:\n          case 'fillThenStrokeAndAddToPathForClipping':\n            tmpRenderingMode = 6;\n            break;\n          case 7:\n          case 'addToPathForClipping':\n            tmpRenderingMode = 7;\n            break;\n        }\n\n        var usedRenderingMode = pageContext.usedRenderingMode || -1;\n\n        //if the coder wrote it explicitly to use a specific \n        //renderingMode, then use it\n        if (tmpRenderingMode !== -1) {\n          xtra += tmpRenderingMode + \" Tr\\n\";\n          //otherwise check if we used the rendering Mode already\n          //if so then set the rendering Mode...\n        } else if (usedRenderingMode !== -1) {\n          xtra += \"0 Tr\\n\";\n        }\n\n        if (tmpRenderingMode !== -1) {\n          pageContext.usedRenderingMode = tmpRenderingMode;\n        }\n\n        //align\n\n        var align = options.align || 'left';\n        var leading = activeFontSize * lineHeight;\n        var pageHeight = scope.internal.pageSize.getHeight();\n        var pageWidth = scope.internal.pageSize.getWidth();\n        var k = scope.internal.scaleFactor;\n        var activeFont = fonts[activeFontKey];\n        var charSpace = options.charSpace || activeCharSpace;\n        var maxWidth = options.maxWidth || 0;\n\n        var lineWidths;\n        var flags = {};\n        var wordSpacingPerLine = [];\n\n        if (Object.prototype.toString.call(text) === '[object Array]') {\n          var da = transformTextToSpecialArray(text);\n          var newY;\n          var maxLineLength;\n          var lineWidths;\n          if (align !== \"left\") {\n            lineWidths = da.map(function (v) {\n              return scope.getStringUnitWidth(v, { font: activeFont, charSpace: charSpace, fontSize: activeFontSize }) * activeFontSize / k;\n            });\n          }\n          var maxLineLength = Math.max.apply(Math, lineWidths);\n          //The first line uses the \"main\" Td setting,\n          //and the subsequent lines are offset by the\n          //previous line's x coordinate.\n          var prevWidth = 0;\n          var delta;\n          var newX;\n          if (align === \"right\") {\n            x -= lineWidths[0];\n            text = [];\n            for (var i = 0, len = da.length; i < len; i++) {\n              delta = maxLineLength - lineWidths[i];\n              if (i === 0) {\n                newX = x * k;\n                newY = (pageHeight - y) * k;\n              } else {\n                newX = (prevWidth - lineWidths[i]) * k;\n                newY = -leading;\n              }\n              text.push([da[i], newX, newY]);\n              prevWidth = lineWidths[i];\n            }\n          } else if (align === \"center\") {\n            x -= lineWidths[0] / 2;\n            text = [];\n            for (var i = 0, len = da.length; i < len; i++) {\n              delta = (maxLineLength - lineWidths[i]) / 2;\n              if (i === 0) {\n                newX = x * k;\n                newY = (pageHeight - y) * k;\n              } else {\n                newX = (prevWidth - lineWidths[i]) / 2 * k;\n                newY = -leading;\n              }\n              text.push([da[i], newX, newY]);\n              prevWidth = lineWidths[i];\n            }\n          } else if (align === \"left\") {\n            text = [];\n            for (var i = 0, len = da.length; i < len; i++) {\n              newY = i === 0 ? (pageHeight - y) * k : -leading;\n              newX = i === 0 ? x * k : 0;\n              //text.push([da[i], newX, newY]);\n              text.push(da[i]);\n            }\n          } else if (align === \"justify\") {\n            text = [];\n            var maxWidth = maxWidth !== 0 ? maxWidth : pageWidth;\n\n            for (var i = 0, len = da.length; i < len; i++) {\n              newY = i === 0 ? (pageHeight - y) * k : -leading;\n              newX = i === 0 ? x * k : 0;\n              if (i < len - 1) {\n                wordSpacingPerLine.push(((maxWidth - lineWidths[i]) / (da[i].split(\" \").length - 1) * k).toFixed(2));\n              }\n              text.push([da[i], newX, newY]);\n            }\n          } else {\n            throw new Error('Unrecognized alignment option, use \"left\", \"center\", \"right\" or \"justify\".');\n          }\n        }\n\n        //R2L\n        var doReversing = typeof options.R2L === \"boolean\" ? options.R2L : R2L;\n        if (doReversing === true) {\n          text = processTextByFunction(text, function (text, posX, posY) {\n            return [text.split(\"\").reverse().join(\"\"), posX, posY];\n          });\n        }\n\n        //creating Payload-Object to make text byRef\n        var payload = {\n          text: text,\n          x: x,\n          y: y,\n          options: options,\n          mutex: {\n            pdfEscape: pdfEscape,\n            activeFontKey: activeFontKey,\n            fonts: fonts,\n            activeFontSize: activeFontSize\n          }\n        };\n        events.publish('postProcessText', payload);\n\n        text = payload.text;\n        isHex = payload.mutex.isHex;\n\n        var da = transformTextToSpecialArray(text);\n\n        text = [];\n        var variant = 0;\n        var len = da.length;\n        var posX;\n        var posY;\n        var content;\n        var wordSpacing = '';\n\n        for (var i = 0; i < len; i++) {\n\n          wordSpacing = '';\n          if (Object.prototype.toString.call(da[i]) !== '[object Array]') {\n            posX = parseFloat(x * k).toFixed(2);\n            posY = parseFloat((pageHeight - y) * k).toFixed(2);\n            content = (isHex ? \"<\" : \"(\") + da[i] + (isHex ? \">\" : \")\");\n          } else if (Object.prototype.toString.call(da[i]) === '[object Array]') {\n            posX = parseFloat(da[i][1]).toFixed(2);\n            posY = parseFloat(da[i][2]).toFixed(2);\n            content = (isHex ? \"<\" : \"(\") + da[i][0] + (isHex ? \">\" : \")\");\n            variant = 1;\n          }\n          if (wordSpacingPerLine !== undefined && wordSpacingPerLine[i] !== undefined) {\n            wordSpacing = wordSpacingPerLine[i] + \" Tw\\n\";\n          }\n          //TODO: Kind of a hack?\n          if (transformationMatrix.length !== 0 && i === 0) {\n            text.push(wordSpacing + transformationMatrix.join(\" \") + \" \" + posX + \" \" + posY + \" Tm\\n\" + content);\n          } else if (variant === 1 || variant === 0 && i === 0) {\n            text.push(wordSpacing + posX + \" \" + posY + \" Td\\n\" + content);\n          } else {\n            text.push(wordSpacing + content);\n          }\n        }\n        if (variant === 0) {\n          text = text.join(\" Tj\\nT* \");\n        } else {\n          text = text.join(\" Tj\\n\");\n        }\n\n        text += \" Tj\\n\";\n\n        var result = 'BT\\n/' + activeFontKey + ' ' + activeFontSize + ' Tf\\n' + // font face, style, size\n        (activeFontSize * lineHeight).toFixed(2) + ' TL\\n' + // line spacing\n        textColor + '\\n';\n        result += xtra;\n        result += text;\n        result += \"ET\";\n\n        out(result);\n        return scope;\n      };\n\n      /**\n       * Letter spacing method to print text with gaps\n       *\n       * @function\n       * @param {String|Array} text String to be added to the page.\n       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n       * @param {Number} spacing Spacing (in units declared at inception)\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name lstext\n       * @deprecated We'll be removing this function. It doesn't take character width into account.\n       */\n      API.lstext = function (text, x, y, spacing) {\n        console.warn('jsPDF.lstext is deprecated');\n        for (var i = 0, len = text.length; i < len; i++, x += spacing) {\n          this.text(text[i], x, y);\n        }return this;\n      };\n\n      API.line = function (x1, y1, x2, y2) {\n        return this.lines([[x2 - x1, y2 - y1]], x1, y1);\n      };\n\n      API.clip = function () {\n        // By patrick-roberts, github.com/MrRio/jsPDF/issues/328\n        // Call .clip() after calling .rect() with a style argument of null\n        out('W'); // clip\n        out('S'); // stroke path; necessary for clip to work\n      };\n\n      /**\n       * This fixes the previous function clip(). Perhaps the 'stroke path' hack was due to the missing 'n' instruction?\n       * We introduce the fixed version so as to not break API.\n       * @param fillRule\n       */\n      API.clip_fixed = function (fillRule) {\n        // Call .clip() after calling drawing ops with a style argument of null\n        // W is the PDF clipping op\n        if ('evenodd' === fillRule) {\n          out('W*');\n        } else {\n          out('W');\n        }\n        // End the path object without filling or stroking it.\n        // This operator is a path-painting no-op, used primarily for the side effect of changing the current clipping path\n        // (see Section 4.4.3, “Clipping Path Operators”)\n        out('n');\n      };\n\n      /**\n       * Adds series of curves (straight lines or cubic bezier curves) to canvas, starting at `x`, `y` coordinates.\n       * All data points in `lines` are relative to last line origin.\n       * `x`, `y` become x1,y1 for first line / curve in the set.\n       * For lines you only need to specify [x2, y2] - (ending point) vector against x1, y1 starting point.\n       * For bezier curves you need to specify [x2,y2,x3,y3,x4,y4] - vectors to control points 1, 2, ending point. All vectors are against the start of the curve - x1,y1.\n       *\n       * @example .lines([[2,2],[-2,2],[1,1,2,2,3,3],[2,1]], 212,110, 10) // line, line, bezier curve, line\n       * @param {Array} lines Array of *vector* shifts as pairs (lines) or sextets (cubic bezier curves).\n       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n       * @param {Number} scale (Defaults to [1.0,1.0]) x,y Scaling factor for all vectors. Elements can be any floating number Sub-one makes drawing smaller. Over-one grows the drawing. Negative flips the direction.\n       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.\n       * @param {Boolean} closed If true, the path is closed with a straight line from the end of the last curve to the starting point.\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name lines\n       */\n      API.lines = function (lines, x, y, scale, style, closed) {\n        var scalex, scaley, i, l, leg, x2, y2, x3, y3, x4, y4;\n\n        // Pre-August-2012 the order of arguments was function(x, y, lines, scale, style)\n        // in effort to make all calls have similar signature like\n        //   function(content, coordinateX, coordinateY , miscellaneous)\n        // this method had its args flipped.\n        // code below allows backward compatibility with old arg order.\n        if (typeof lines === 'number') {\n          tmp = y;\n          y = x;\n          x = lines;\n          lines = tmp;\n        }\n\n        scale = scale || [1, 1];\n\n        // starting point\n        out(f3(x * k) + ' ' + f3((pageHeight - y) * k) + ' m ');\n\n        scalex = scale[0];\n        scaley = scale[1];\n        l = lines.length;\n        //, x2, y2 // bezier only. In page default measurement \"units\", *after* scaling\n        //, x3, y3 // bezier only. In page default measurement \"units\", *after* scaling\n        // ending point for all, lines and bezier. . In page default measurement \"units\", *after* scaling\n        x4 = x; // last / ending point = starting point for first item.\n        y4 = y; // last / ending point = starting point for first item.\n\n        for (i = 0; i < l; i++) {\n          leg = lines[i];\n          if (leg.length === 2) {\n            // simple line\n            x4 = leg[0] * scalex + x4; // here last x4 was prior ending point\n            y4 = leg[1] * scaley + y4; // here last y4 was prior ending point\n            out(f3(x4 * k) + ' ' + f3((pageHeight - y4) * k) + ' l');\n          } else {\n            // bezier curve\n            x2 = leg[0] * scalex + x4; // here last x4 is prior ending point\n            y2 = leg[1] * scaley + y4; // here last y4 is prior ending point\n            x3 = leg[2] * scalex + x4; // here last x4 is prior ending point\n            y3 = leg[3] * scaley + y4; // here last y4 is prior ending point\n            x4 = leg[4] * scalex + x4; // here last x4 was prior ending point\n            y4 = leg[5] * scaley + y4; // here last y4 was prior ending point\n            out(f3(x2 * k) + ' ' + f3((pageHeight - y2) * k) + ' ' + f3(x3 * k) + ' ' + f3((pageHeight - y3) * k) + ' ' + f3(x4 * k) + ' ' + f3((pageHeight - y4) * k) + ' c');\n          }\n        }\n\n        if (closed) {\n          out(' h');\n        }\n\n        // stroking / filling / both the path\n        if (style !== null) {\n          out(getStyle(style));\n        }\n        return this;\n      };\n\n      /**\n       * Adds a rectangle to PDF\n       *\n       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n       * @param {Number} w Width (in units declared at inception of PDF document)\n       * @param {Number} h Height (in units declared at inception of PDF document)\n       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name rect\n       */\n      API.rect = function (x, y, w, h, style) {\n        var op = getStyle(style);\n        out([f2(x * k), f2((pageHeight - y) * k), f2(w * k), f2(-h * k), 're'].join(' '));\n\n        if (style !== null) {\n          out(getStyle(style));\n        }\n\n        return this;\n      };\n\n      /**\n       * Adds a triangle to PDF\n       *\n       * @param {Number} x1 Coordinate (in units declared at inception of PDF document) against left edge of the page\n       * @param {Number} y1 Coordinate (in units declared at inception of PDF document) against upper edge of the page\n       * @param {Number} x2 Coordinate (in units declared at inception of PDF document) against left edge of the page\n       * @param {Number} y2 Coordinate (in units declared at inception of PDF document) against upper edge of the page\n       * @param {Number} x3 Coordinate (in units declared at inception of PDF document) against left edge of the page\n       * @param {Number} y3 Coordinate (in units declared at inception of PDF document) against upper edge of the page\n       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name triangle\n       */\n      API.triangle = function (x1, y1, x2, y2, x3, y3, style) {\n        this.lines([[x2 - x1, y2 - y1], // vector to point 2\n        [x3 - x2, y3 - y2], // vector to point 3\n        [x1 - x3, y1 - y3] // closing vector back to point 1\n        ], x1, y1, // start of path\n        [1, 1], style, true);\n        return this;\n      };\n\n      /**\n       * Adds a rectangle with rounded corners to PDF\n       *\n       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n       * @param {Number} w Width (in units declared at inception of PDF document)\n       * @param {Number} h Height (in units declared at inception of PDF document)\n       * @param {Number} rx Radius along x axis (in units declared at inception of PDF document)\n       * @param {Number} rx Radius along y axis (in units declared at inception of PDF document)\n       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name roundedRect\n       */\n      API.roundedRect = function (x, y, w, h, rx, ry, style) {\n        var MyArc = 4 / 3 * (Math.SQRT2 - 1);\n        this.lines([[w - 2 * rx, 0], [rx * MyArc, 0, rx, ry - ry * MyArc, rx, ry], [0, h - 2 * ry], [0, ry * MyArc, -(rx * MyArc), ry, -rx, ry], [-w + 2 * rx, 0], [-(rx * MyArc), 0, -rx, -(ry * MyArc), -rx, -ry], [0, -h + 2 * ry], [0, -(ry * MyArc), rx * MyArc, -ry, rx, -ry]], x + rx, y, // start of path\n        [1, 1], style);\n        return this;\n      };\n\n      /**\n       * Adds an ellipse to PDF\n       *\n       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n       * @param {Number} rx Radius along x axis (in units declared at inception of PDF document)\n       * @param {Number} rx Radius along y axis (in units declared at inception of PDF document)\n       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name ellipse\n       */\n      API.ellipse = function (x, y, rx, ry, style) {\n        var lx = 4 / 3 * (Math.SQRT2 - 1) * rx,\n            ly = 4 / 3 * (Math.SQRT2 - 1) * ry;\n\n        out([f2((x + rx) * k), f2((pageHeight - y) * k), 'm', f2((x + rx) * k), f2((pageHeight - (y - ly)) * k), f2((x + lx) * k), f2((pageHeight - (y - ry)) * k), f2(x * k), f2((pageHeight - (y - ry)) * k), 'c'].join(' '));\n        out([f2((x - lx) * k), f2((pageHeight - (y - ry)) * k), f2((x - rx) * k), f2((pageHeight - (y - ly)) * k), f2((x - rx) * k), f2((pageHeight - y) * k), 'c'].join(' '));\n        out([f2((x - rx) * k), f2((pageHeight - (y + ly)) * k), f2((x - lx) * k), f2((pageHeight - (y + ry)) * k), f2(x * k), f2((pageHeight - (y + ry)) * k), 'c'].join(' '));\n        out([f2((x + lx) * k), f2((pageHeight - (y + ry)) * k), f2((x + rx) * k), f2((pageHeight - (y + ly)) * k), f2((x + rx) * k), f2((pageHeight - y) * k), 'c'].join(' '));\n\n        if (style !== null) {\n          out(getStyle(style));\n        }\n\n        return this;\n      };\n\n      /**\n       * Adds an circle to PDF\n       *\n       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n       * @param {Number} r Radius (in units declared at inception of PDF document)\n       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name circle\n       */\n      API.circle = function (x, y, r, style) {\n        return this.ellipse(x, y, r, r, style);\n      };\n\n      /**\n       * Adds a properties to the PDF document\n       *\n       * @param {Object} A property_name-to-property_value object structure.\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name setProperties\n       */\n      API.setProperties = function (properties) {\n        // copying only those properties we can render.\n        for (var property in documentProperties) {\n          if (documentProperties.hasOwnProperty(property) && properties[property]) {\n            documentProperties[property] = properties[property];\n          }\n        }\n        return this;\n      };\n\n      /**\n       * Sets font size for upcoming text elements.\n       *\n       * @param {Number} size Font size in points.\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name setFontSize\n       */\n      API.setFontSize = function (size) {\n        activeFontSize = size;\n        return this;\n      };\n\n      /**\n       * Sets text font face, variant for upcoming text elements.\n       * See output of jsPDF.getFontList() for possible font names, styles.\n       *\n       * @param {String} fontName Font name or family. Example: \"times\"\n       * @param {String} fontStyle Font style or variant. Example: \"italic\"\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name setFont\n       */\n      API.setFont = function (fontName, fontStyle) {\n        activeFontKey = _getFont(fontName, fontStyle);\n        // if font is not found, the above line blows up and we never go further\n        return this;\n      };\n\n      /**\n       * Switches font style or variant for upcoming text elements,\n       * while keeping the font face or family same.\n       * See output of jsPDF.getFontList() for possible font names, styles.\n       *\n       * @param {String} style Font style or variant. Example: \"italic\"\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name setFontStyle\n       */\n      API.setFontStyle = API.setFontType = function (style) {\n        activeFontKey = _getFont(undefined, style);\n        // if font is not found, the above line blows up and we never go further\n        return this;\n      };\n\n      /**\n       * Returns an object - a tree of fontName to fontStyle relationships available to\n       * active PDF document.\n       *\n       * @public\n       * @function\n       * @returns {Object} Like {'times':['normal', 'italic', ... ], 'arial':['normal', 'bold', ... ], ... }\n       * @methodOf jsPDF#\n       * @name getFontList\n       */\n      API.getFontList = function () {\n        // TODO: iterate over fonts array or return copy of fontmap instead in case more are ever added.\n        var list = {},\n            fontName,\n            fontStyle,\n            tmp;\n\n        for (fontName in fontmap) {\n          if (fontmap.hasOwnProperty(fontName)) {\n            list[fontName] = tmp = [];\n            for (fontStyle in fontmap[fontName]) {\n              if (fontmap[fontName].hasOwnProperty(fontStyle)) {\n                tmp.push(fontStyle);\n              }\n            }\n          }\n        }\n\n        return list;\n      };\n\n      /**\n       * Add a custom font.\n       *\n       * @param {String} Postscript name of the Font.  Example: \"Menlo-Regular\"\n       * @param {String} Name of font-family from @font-face definition.  Example: \"Menlo Regular\"\n       * @param {String} Font style.  Example: \"normal\"\n       * @function\n       * @returns the {fontKey} (same as the internal method)\n       * @methodOf jsPDF#\n       * @name addFont\n       */\n      API.addFont = function (postScriptName, fontName, fontStyle, encoding) {\n        encoding = encoding || 'Identity-H';\n        addFont(postScriptName, fontName, fontStyle, encoding);\n      };\n\n      /**\n       * Sets line width for upcoming lines.\n       *\n       * @param {Number} width Line width (in units declared at inception of PDF document)\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name setLineWidth\n       */\n      API.setLineWidth = function (width) {\n        out((width * k).toFixed(2) + ' w');\n        return this;\n      };\n\n      /**\n       * Sets the stroke color for upcoming elements.\n       *\n       * Depending on the number of arguments given, Gray, RGB, or CMYK\n       * color space is implied.\n       *\n       * When only ch1 is given, \"Gray\" color space is implied and it\n       * must be a value in the range from 0.00 (solid black) to to 1.00 (white)\n       * if values are communicated as String types, or in range from 0 (black)\n       * to 255 (white) if communicated as Number type.\n       * The RGB-like 0-255 range is provided for backward compatibility.\n       *\n       * When only ch1,ch2,ch3 are given, \"RGB\" color space is implied and each\n       * value must be in the range from 0.00 (minimum intensity) to to 1.00\n       * (max intensity) if values are communicated as String types, or\n       * from 0 (min intensity) to to 255 (max intensity) if values are communicated\n       * as Number types.\n       * The RGB-like 0-255 range is provided for backward compatibility.\n       *\n       * When ch1,ch2,ch3,ch4 are given, \"CMYK\" color space is implied and each\n       * value must be a in the range from 0.00 (0% concentration) to to\n       * 1.00 (100% concentration)\n       *\n       * Because JavaScript treats fixed point numbers badly (rounds to\n       * floating point nearest to binary representation) it is highly advised to\n       * communicate the fractional numbers as String types, not JavaScript Number type.\n       *\n       * @param {Number|String} ch1 Color channel value or {String} ch1 color value in hexadecimal, example: '#FFFFFF'\n       * @param {Number|String} ch2 Color channel value\n       * @param {Number|String} ch3 Color channel value\n       * @param {Number|String} ch4 Color channel value\n       *\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name setDrawColor\n       */\n      API.setDrawColor = function (ch1, ch2, ch3, ch4) {\n        var options = {\n          \"ch1\": ch1,\n          \"ch2\": ch2,\n          \"ch3\": ch3,\n          \"ch4\": ch4,\n          \"pdfColorType\": \"draw\",\n          \"precision\": 2\n        };\n\n        out(generateColorString(options));\n        return this;\n      };\n\n      /**\n       * Sets the fill color for upcoming elements.\n       *\n       * Depending on the number of arguments given, Gray, RGB, or CMYK\n       * color space is implied.\n       *\n       * When only ch1 is given, \"Gray\" color space is implied and it\n       * must be a value in the range from 0.00 (solid black) to to 1.00 (white)\n       * if values are communicated as String types, or in range from 0 (black)\n       * to 255 (white) if communicated as Number type.\n       * The RGB-like 0-255 range is provided for backward compatibility.\n       *\n       * When only ch1,ch2,ch3 are given, \"RGB\" color space is implied and each\n       * value must be in the range from 0.00 (minimum intensity) to to 1.00\n       * (max intensity) if values are communicated as String types, or\n       * from 0 (min intensity) to to 255 (max intensity) if values are communicated\n       * as Number types.\n       * The RGB-like 0-255 range is provided for backward compatibility.\n       *\n       * When ch1,ch2,ch3,ch4 are given, \"CMYK\" color space is implied and each\n       * value must be a in the range from 0.00 (0% concentration) to to\n       * 1.00 (100% concentration)\n       *\n       * Because JavaScript treats fixed point numbers badly (rounds to\n       * floating point nearest to binary representation) it is highly advised to\n       * communicate the fractional numbers as String types, not JavaScript Number type.\n       *\n       * @param {Number|String} ch1 Color channel value or {String} ch1 color value in hexadecimal, example: '#FFFFFF'\n       * @param {Number|String} ch2 Color channel value\n       * @param {Number|String} ch3 Color channel value\n       * @param {Number|String} ch4 Color channel value\n       *\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name setFillColor\n       */\n\n      API.setFillColor = function (ch1, ch2, ch3, ch4) {\n        var options = {\n          \"ch1\": ch1,\n          \"ch2\": ch2,\n          \"ch3\": ch3,\n          \"ch4\": ch4,\n          \"pdfColorType\": \"fill\",\n          \"precision\": 2\n        };\n\n        out(generateColorString(options));\n        return this;\n      };\n\n      /**\n       * Sets the text color for upcoming elements.\n       *\n       * Depending on the number of arguments given, Gray, RGB, or CMYK\n       * color space is implied.\n       *\n       * When only ch1 is given, \"Gray\" color space is implied and it\n       * must be a value in the range from 0.00 (solid black) to to 1.00 (white)\n       * if values are communicated as String types, or in range from 0 (black)\n       * to 255 (white) if communicated as Number type.\n       * The RGB-like 0-255 range is provided for backward compatibility.\n       *\n       * When only ch1,ch2,ch3 are given, \"RGB\" color space is implied and each\n       * value must be in the range from 0.00 (minimum intensity) to to 1.00\n       * (max intensity) if values are communicated as String types, or\n       * from 0 (min intensity) to to 255 (max intensity) if values are communicated\n       * as Number types.\n       * The RGB-like 0-255 range is provided for backward compatibility.\n       *\n       * When ch1,ch2,ch3,ch4 are given, \"CMYK\" color space is implied and each\n       * value must be a in the range from 0.00 (0% concentration) to to\n       * 1.00 (100% concentration)\n       *\n       * Because JavaScript treats fixed point numbers badly (rounds to\n       * floating point nearest to binary representation) it is highly advised to\n       * communicate the fractional numbers as String types, not JavaScript Number type.\n       *\n       * @param {Number|String} ch1 Color channel value or {String} ch1 color value in hexadecimal, example: '#FFFFFF'\n       * @param {Number|String} ch2 Color channel value\n       * @param {Number|String} ch3 Color channel value\n       * @param {Number|String} ch4 Color channel value\n       *\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name setTextColor\n       */\n      API.setTextColor = function (ch1, ch2, ch3, ch4) {\n        var options = {\n          \"ch1\": ch1,\n          \"ch2\": ch2,\n          \"ch3\": ch3,\n          \"ch4\": ch4,\n          \"pdfColorType\": \"text\",\n          \"precision\": 3\n        };\n        textColor = generateColorString(options);\n\n        return this;\n      };\n\n      /**\n       * Initializes the default character set that the user wants to be global..\n       *\n       * @param {Number} charSpace\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name setCharSpace\n       */\n\n      API.setCharSpace = function (charSpace) {\n        activeCharSpace = charSpace;\n        return this;\n      };\n\n      /**\n       * Initializes the default character set that the user wants to be global..\n       *\n       * @param {Boolean} boolean\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name setR2L\n       */\n\n      API.setR2L = function (boolean) {\n        R2L = boolean;\n        return this;\n      };\n\n      /**\n       * Is an Object providing a mapping from human-readable to\n       * integer flag values designating the varieties of line cap\n       * and join styles.\n       *\n       * @returns {Object}\n       * @fieldOf jsPDF#\n       * @name CapJoinStyles\n       */\n      API.CapJoinStyles = {\n        0: 0,\n        'butt': 0,\n        'but': 0,\n        'miter': 0,\n        1: 1,\n        'round': 1,\n        'rounded': 1,\n        'circle': 1,\n        2: 2,\n        'projecting': 2,\n        'project': 2,\n        'square': 2,\n        'bevel': 2\n      };\n\n      /**\n       * Sets the line cap styles\n       * See {jsPDF.CapJoinStyles} for variants\n       *\n       * @param {String|Number} style A string or number identifying the type of line cap\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name setLineCap\n       */\n      API.setLineCap = function (style) {\n        var id = this.CapJoinStyles[style];\n        if (id === undefined) {\n          throw new Error(\"Line cap style of '\" + style + \"' is not recognized. See or extend .CapJoinStyles property for valid styles\");\n        }\n        lineCapID = id;\n        out(id + ' J');\n\n        return this;\n      };\n\n      /**\n       * Sets the line join styles\n       * See {jsPDF.CapJoinStyles} for variants\n       *\n       * @param {String|Number} style A string or number identifying the type of line join\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name setLineJoin\n       */\n      API.setLineJoin = function (style) {\n        var id = this.CapJoinStyles[style];\n        if (id === undefined) {\n          throw new Error(\"Line join style of '\" + style + \"' is not recognized. See or extend .CapJoinStyles property for valid styles\");\n        }\n        lineJoinID = id;\n        out(id + ' j');\n\n        return this;\n      };\n\n      // Output is both an internal (for plugins) and external function\n      API.output = _output;\n\n      /**\n       * Saves as PDF document. An alias of jsPDF.output('save', 'filename.pdf')\n       * @param  {String} filename The filename including extension.\n       *\n       * @function\n       * @returns {jsPDF}\n       * @methodOf jsPDF#\n       * @name save\n       */\n      API.save = function (filename) {\n        API.output('save', filename);\n      };\n\n      // applying plugins (more methods) ON TOP of built-in API.\n      // this is intentional as we allow plugins to override\n      // built-ins\n      for (var plugin in jsPDF.API) {\n        if (jsPDF.API.hasOwnProperty(plugin)) {\n          if (plugin === 'events' && jsPDF.API.events.length) {\n            (function (events, newEvents) {\n\n              // jsPDF.API.events is a JS Array of Arrays\n              // where each Array is a pair of event name, handler\n              // Events were added by plugins to the jsPDF instantiator.\n              // These are always added to the new instance and some ran\n              // during instantiation.\n              var eventname, handler_and_args, i;\n\n              for (i = newEvents.length - 1; i !== -1; i--) {\n                // subscribe takes 3 args: 'topic', function, runonce_flag\n                // if undefined, runonce is false.\n                // users can attach callback directly,\n                // or they can attach an array with [callback, runonce_flag]\n                // that's what the \"apply\" magic is for below.\n                eventname = newEvents[i][0];\n                handler_and_args = newEvents[i][1];\n                events.subscribe.apply(events, [eventname].concat(typeof handler_and_args === 'function' ? [handler_and_args] : handler_and_args));\n              }\n            })(events, jsPDF.API.events);\n          } else {\n            API[plugin] = jsPDF.API[plugin];\n          }\n        }\n      }\n\n      //////////////////////////////////////////////////////\n      // continuing initialization of jsPDF Document object\n      //////////////////////////////////////////////////////\n      // Add the first page automatically\n      addFonts();\n      activeFontKey = 'F1';\n      _addPage(format, orientation);\n\n      events.publish('initialized');\n      return API;\n    }\n\n    /**\n     * jsPDF.API is a STATIC property of jsPDF class.\n     * jsPDF.API is an object you can add methods and properties to.\n     * The methods / properties you add will show up in new jsPDF objects.\n     *\n     * One property is prepopulated. It is the 'events' Object. Plugin authors can add topics,\n     * callbacks to this object. These will be reassigned to all new instances of jsPDF.\n     * Examples:\n     * jsPDF.API.events['initialized'] = function(){ 'this' is API object }\n     * jsPDF.API.events['addFont'] = function(added_font_object){ 'this' is API object }\n     *\n     * @static\n     * @public\n     * @memberOf jsPDF\n     * @name API\n     *\n     * @example\n     * jsPDF.API.mymethod = function(){\n     *   // 'this' will be ref to internal API object. see jsPDF source\n     *   // , so you can refer to built-in methods like so:\n     *   //     this.line(....)\n     *   //     this.text(....)\n     * }\n     * var pdfdoc = new jsPDF()\n     * pdfdoc.mymethod() // <- !!!!!!\n     */\n    jsPDF.API = {\n      events: []\n    };\n    jsPDF.version = \"0.0.0\";\n\n    if (typeof define === 'function' && define.amd) {\n      define('jsPDF', function () {\n        return jsPDF;\n      });\n    } else if (typeof module !== 'undefined' && module.exports) {\n      module.exports = jsPDF;\n      module.exports.jsPDF = jsPDF;\n    } else {\n      global.jsPDF = jsPDF;\n    }\n    return jsPDF;\n  }(typeof self !== \"undefined\" && self || typeof window !== \"undefined\" && window || typeof global !== \"undefined\" && global || Function('return typeof this === \"object\" && this.content')() || Function('return this')());\n  // `self` is undefined in Firefox for Android content script context\n  // while `this` is nsIContentFrameMessageManager\n  // with an attribute `content` that corresponds to the window\n  \n\n  /**\n   * jsPDF AcroForm Plugin Copyright (c) 2016 Alexander Weidt,\n   * https://github.com/BiggA94\n   * \n   * Licensed under the MIT License. http://opensource.org/licenses/mit-license\n   */\n\n  (function (jsPDFAPI, globalObj) {\n\n    var scope;\n    var pageHeight;\n    var scaleFactor = 1;\n    var inherit = function inherit(child, parent) {\n      child.prototype = Object.create(parent.prototype);\n      child.prototype.constructor = child;\n    };\n    var scale = function scale(x) {\n      return x * (scaleFactor / 1); // 1 = (96 / 72)\n    };\n\n    var createFormXObject = function createFormXObject(formObject) {\n      var xobj = new AcroFormXObject();\n      var height = AcroFormAppearance.internal.getHeight(formObject) || 0;\n      var width = AcroFormAppearance.internal.getWidth(formObject) || 0;\n      xobj.BBox = [0, 0, width.toFixed(2), height.toFixed(2)];\n      return xobj;\n    };\n\n    var setBitPosition = function setBitPosition(variable, position, value) {\n      variable = variable || 0;\n      value = value || 1;\n\n      var bitMask = 1;\n      bitMask = bitMask << position - 1;\n\n      if (value == 1) {\n        // Set the Bit to 1\n        var variable = variable | bitMask;\n      } else {\n        // Set the Bit to 0\n        var variable = variable & ~bitMask;\n      }\n\n      return variable;\n    };\n\n    /**\n    * Calculating the Ff entry:\n    * \n    * The Ff entry contains flags, that have to be set bitwise In the Following\n    * the number in the Comment is the BitPosition\n    */\n    var calculateFlagsOnOptions = function calculateFlagsOnOptions(flags, opts, PDFVersion) {\n      var PDFVersion = PDFVersion || 1.3;\n      var flags = flags || 0;\n\n      // 1, readOnly\n      if (opts.readOnly == true) {\n        flags = setBitPosition(flags, 1);\n      }\n\n      // 2, required\n      if (opts.required == true) {\n        flags = setBitPosition(flags, 2);\n      }\n\n      // 4, noExport\n      if (opts.noExport == true) {\n        flags = setBitPosition(flags, 3);\n      }\n\n      // 13, multiline\n      if (opts.multiline == true) {\n        flags = setBitPosition(flags, 13);\n      }\n\n      // 14, Password\n      if (opts.password) {\n        flags = setBitPosition(flags, 14);\n      }\n\n      // 15, NoToggleToOff (Radio buttons only\n      if (opts.noToggleToOff) {\n        flags = setBitPosition(flags, 15);\n      }\n\n      // 16, Radio\n      if (opts.radio) {\n        flags = setBitPosition(flags, 16);\n      }\n\n      // 17, Pushbutton\n      if (opts.pushbutton) {\n        flags = setBitPosition(flags, 17);\n      }\n\n      // 18, Combo (If not set, the choiceField is a listBox!!)\n      if (opts.combo) {\n        flags = setBitPosition(flags, 18);\n      }\n\n      // 19, Edit\n      if (opts.edit) {\n        flags = setBitPosition(flags, 19);\n      }\n\n      // 20, Sort\n      if (opts.sort) {\n        flags = setBitPosition(flags, 20);\n      }\n\n      // 21, FileSelect, PDF 1.4...\n      if (opts.fileSelect && PDFVersion >= 1.4) {\n        flags = setBitPosition(flags, 21);\n      }\n\n      // 22, MultiSelect (PDF 1.4)\n      if (opts.multiSelect && PDFVersion >= 1.4) {\n        flags = setBitPosition(flags, 22);\n      }\n\n      // 23, DoNotSpellCheck (PDF 1.4)\n      if (opts.doNotSpellCheck && PDFVersion >= 1.4) {\n        flags = setBitPosition(flags, 23);\n      }\n\n      // 24, DoNotScroll (PDF 1.4)\n      if (opts.doNotScroll == true && PDFVersion >= 1.4) {\n        flags = setBitPosition(flags, 24);\n      }\n\n      // 25, RichText (PDF 1.4)\n      if (opts.richText && PDFVersion >= 1.4) {\n        flags = setBitPosition(flags, 25);\n      }\n\n      return flags;\n    };\n\n    var calculateCoordinates = function calculateCoordinates(args) {\n      var x = args[0];\n      var y = args[1];\n      var w = args[2];\n      var h = args[3];\n\n      var coordinates = {};\n\n      if (Array.isArray(x)) {\n        x[0] = scale(x[0]);\n        x[1] = scale(x[1]);\n        x[2] = scale(x[2]);\n        x[3] = scale(x[3]);\n      } else {\n        x = scale(x);\n        y = scale(y);\n        w = scale(w);\n        h = scale(h);\n      }\n      coordinates.lowerLeft_X = x || 0;\n      coordinates.lowerLeft_Y = scale(pageHeight) - y - h || 0;\n      coordinates.upperRight_X = x + w || 0;\n      coordinates.upperRight_Y = scale(pageHeight) - y || 0;\n\n      return [coordinates.lowerLeft_X.toFixed(2), coordinates.lowerLeft_Y.toFixed(2), coordinates.upperRight_X.toFixed(2), coordinates.upperRight_Y.toFixed(2)];\n    };\n\n    var calculateAppearanceStream = function calculateAppearanceStream(formObject) {\n      if (formObject.appearanceStreamContent) {\n        // If appearanceStream is already set, use it\n        return formObject.appearanceStreamContent;\n      }\n\n      if (!formObject.V && !formObject.DV) {\n        return;\n      }\n\n      // else calculate it\n\n      var stream = [];\n      var text = formObject.V || formObject.DV;\n      var calcRes = calculateX(formObject, text);\n\n      stream.push('/Tx BMC');\n      stream.push('q');\n      stream.push('/F1 ' + calcRes.fontSize.toFixed(2) + ' Tf');\n      stream.push('1 0 0 1 0 0 Tm'); // Text Matrix\n\n      stream.push('BT'); // Begin Text\n      stream.push(calcRes.text);\n\n      stream.push('ET'); // End Text\n      stream.push('Q');\n      stream.push('EMC');\n\n      var appearanceStreamContent = new createFormXObject(formObject);\n      appearanceStreamContent.stream = stream.join(\"\\n\");\n\n      return appearanceStreamContent;\n    };\n\n    var calculateX = function calculateX(formObject, text, font, maxFontSize) {\n      var maxFontSize = maxFontSize || 12;\n      var font = font || \"helvetica\";\n      var returnValue = {\n        text: \"\",\n        fontSize: \"\"\n      };\n      // Remove Brackets\n      text = text.substr(0, 1) == '(' ? text.substr(1) : text;\n      text = text.substr(text.length - 1) == ')' ? text.substr(0, text.length - 1) : text;\n      // split into array of words\n      var textSplit = text.split(' ');\n      var fontSize = maxFontSize; // The Starting fontSize (The Maximum)\n      var lineSpacing = 2;\n      var borderPadding = 2;\n\n      var height = AcroFormAppearance.internal.getHeight(formObject) || 0;\n      height = height < 0 ? -height : height;\n      var width = AcroFormAppearance.internal.getWidth(formObject) || 0;\n      width = width < 0 ? -width : width;\n\n      var isSmallerThanWidth = function isSmallerThanWidth(i, lastLine, fontSize) {\n        if (i + 1 < textSplit.length) {\n          var tmp = lastLine + \" \" + textSplit[i + 1];\n          var TextWidth = calculateFontSpace(tmp, fontSize + \"px\", font).width;\n          var FieldWidth = width - 2 * borderPadding;\n          return TextWidth <= FieldWidth;\n        } else {\n          return false;\n        }\n      };\n\n      fontSize++;\n      FontSize: while (true) {\n        var text = \"\";\n        fontSize--;\n        var textHeight = calculateFontSpace(\"3\", fontSize + \"px\", font).height;\n        var startY = formObject.multiline ? height - fontSize : (height - textHeight) / 2;\n        startY += lineSpacing;\n        var startX = -borderPadding;\n\n        var lastY = startY;\n        var firstWordInLine = 0,\n            lastWordInLine = 0;\n        var lastLength = 0;\n        if (fontSize <= 0) {\n          // In case, the Text doesn't fit at all\n          fontSize = 12;\n          text = \"(...) Tj\\n\";\n          text += \"% Width of Text: \" + calculateFontSpace(text, \"1px\").width + \", FieldWidth:\" + width + \"\\n\";\n          break;\n        }\n\n        lastLength = calculateFontSpace(textSplit[0] + \" \", fontSize + \"px\", font).width;\n\n        var lastLine = \"\";\n        var lineCount = 0;\n        Line: for (var i in textSplit) {\n          lastLine += textSplit[i] + \" \";\n          // Remove last blank\n          lastLine = lastLine.substr(lastLine.length - 1) == \" \" ? lastLine.substr(0, lastLine.length - 1) : lastLine;\n          var key = parseInt(i);\n          lastLength = calculateFontSpace(lastLine + \" \", fontSize + \"px\", font).width;\n          var nextLineIsSmaller = isSmallerThanWidth(key, lastLine, fontSize);\n          var isLastWord = i >= textSplit.length - 1;\n          if (nextLineIsSmaller && !isLastWord) {\n            lastLine += \" \";\n            continue; // Line\n          } else if (!nextLineIsSmaller && !isLastWord) {\n            if (!formObject.multiline) {\n              continue FontSize;\n            } else {\n              if ((textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {\n                // If the Text is higher than the\n                // FieldObject\n                continue FontSize;\n              }\n              lastWordInLine = key;\n              // go on\n            }\n          } else if (isLastWord) {\n            lastWordInLine = key;\n          } else {\n            if (formObject.multiline && (textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {\n              // If the Text is higher than the FieldObject\n              continue FontSize;\n            }\n          }\n\n          var line = '';\n\n          for (var x = firstWordInLine; x <= lastWordInLine; x++) {\n            line += textSplit[x] + ' ';\n          }\n\n          // Remove last blank\n          line = line.substr(line.length - 1) == \" \" ? line.substr(0, line.length - 1) : line;\n          // lastLength -= blankSpace.width;\n          lastLength = calculateFontSpace(line, fontSize + \"px\", font).width;\n\n          // Calculate startX\n          switch (formObject.Q) {\n            case 2:\n              // Right justified\n              startX = width - lastLength - borderPadding;\n              break;\n            case 1:\n              // Q = 1 := Text-Alignment: Center\n              startX = (width - lastLength) / 2;\n              break;\n            case 0:\n            default:\n              startX = borderPadding;\n              break;\n          }\n          text += startX.toFixed(2) + ' ' + lastY.toFixed(2) + ' Td\\n';\n          text += '(' + line + ') Tj\\n';\n          // reset X in PDF\n          text += -startX.toFixed(2) + ' 0 Td\\n';\n\n          // After a Line, adjust y position\n          lastY = -(fontSize + lineSpacing);\n\n          // Reset for next iteration step\n          lastLength = 0;\n          firstWordInLine = lastWordInLine + 1;\n          lineCount++;\n\n          lastLine = \"\";\n          continue Line;\n        }\n        break;\n      }\n\n      returnValue.text = text;\n      returnValue.fontSize = fontSize;\n\n      return returnValue;\n    };\n\n    /**\n    * small workaround for calculating the TextMetric approximately\n    * \n    * @param text\n    * @param fontsize\n    * @returns {TextMetrics} (Has Height and Width)\n    */\n    var calculateFontSpace = function calculateFontSpace(text, fontSize, fontType) {\n      fontType = fontType || \"helvetica\";\n      var font = scope.internal.getFont(fontType);\n      var width = scope.getStringUnitWidth(text, { font: font, fontSize: parseFloat(fontSize), charSpace: 0 }) * parseFloat(fontSize);\n      var height = scope.getStringUnitWidth(\"3\", { font: font, fontSize: parseFloat(fontSize), charSpace: 0 }) * parseFloat(fontSize) * 1.5;\n      var result = { height: height, width: width };\n      return result;\n    };\n\n    var acroformPluginTemplate = {\n      fields: [],\n      xForms: [],\n      /**\n      * acroFormDictionaryRoot contains information about the AcroForm\n      * Dictionary 0: The Event-Token, the AcroFormDictionaryCallback has\n      * 1: The Object ID of the Root\n      */\n      acroFormDictionaryRoot: null,\n      /**\n      * After the PDF gets evaluated, the reference to the root has to be\n      * reset, this indicates, whether the root has already been printed\n      * out\n      */\n      printedOut: false,\n      internal: null,\n      isInitialized: false\n    };\n\n    var annotReferenceCallback = function annotReferenceCallback() {\n      for (var i in scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields) {\n        var formObject = scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields[i];\n        // add Annot Reference!\n        if (formObject.hasAnnotation) {\n          // If theres an Annotation Widget in the Form Object, put the\n          // Reference in the /Annot array\n          createAnnotationReference.call(scope, formObject);\n        }\n      }\n    };\n\n    var putForm = function putForm(formObject) {\n      if (scope.internal.acroformPlugin.printedOut) {\n        scope.internal.acroformPlugin.printedOut = false;\n        scope.internal.acroformPlugin.acroFormDictionaryRoot = null;\n      }\n      if (!scope.internal.acroformPlugin.acroFormDictionaryRoot) {\n        initializeAcroForm.call(scope);\n      }\n      scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields.push(formObject);\n    };\n    /**\n    * Create the Reference to the widgetAnnotation, so that it gets referenced\n    * in the Annot[] int the+ (Requires the Annotation Plugin)\n    */\n    var createAnnotationReference = function createAnnotationReference(object) {\n      var options = {\n        type: 'reference',\n        object: object\n      };\n      scope.annotationPlugin.annotations[scope.internal.getPageInfo(object.page).pageNumber].push(options);\n    };\n\n    // Callbacks\n\n    var putCatalogCallback = function putCatalogCallback() {\n      // Put reference to AcroForm to DocumentCatalog\n      if (typeof scope.internal.acroformPlugin.acroFormDictionaryRoot != 'undefined') {\n        // for safety, shouldn't normally be the case\n        scope.internal.write('/AcroForm ' + scope.internal.acroformPlugin.acroFormDictionaryRoot.objId + ' ' + 0 + ' R');\n      } else {\n        console.log('Root missing...');\n      }\n    };\n\n    /**\n    * Adds /Acroform X 0 R to Document Catalog, and creates the AcroForm\n    * Dictionary\n    */\n    var AcroFormDictionaryCallback = function AcroFormDictionaryCallback() {\n      // Remove event\n      scope.internal.events.unsubscribe(scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID);\n      delete scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID;\n      scope.internal.acroformPlugin.printedOut = true;\n    };\n\n    /**\n    * Creates the single Fields and writes them into the Document\n    * \n    * If fieldArray is set, use the fields that are inside it instead of the\n    * fields from the AcroRoot (for the FormXObjects...)\n    */\n    var createFieldCallback = function createFieldCallback(fieldArray) {\n      var standardFields = !fieldArray;\n\n      if (!fieldArray) {\n        // in case there is no fieldArray specified, we want to print out\n        // the Fields of the AcroForm\n        // Print out Root\n        scope.internal.newObjectDeferredBegin(scope.internal.acroformPlugin.acroFormDictionaryRoot.objId);\n        scope.internal.out(scope.internal.acroformPlugin.acroFormDictionaryRoot.getString());\n      }\n\n      var fieldArray = fieldArray || scope.internal.acroformPlugin.acroFormDictionaryRoot.Kids;\n\n      for (var i in fieldArray) {\n        var form = fieldArray[i];\n\n        var oldRect = form.Rect;\n\n        if (form.Rect) {\n          form.Rect = calculateCoordinates.call(this, form.Rect);\n        }\n\n        // Start Writing the Object\n        scope.internal.newObjectDeferredBegin(form.objId);\n\n        var content = form.objId + \" 0 obj\\n<<\\n\";\n\n        if ((typeof form === 'undefined' ? 'undefined' : _typeof(form)) === \"object\" && typeof form.getContent === \"function\") {\n          content += form.getContent();\n        }\n\n        form.Rect = oldRect;\n\n        if (form.hasAppearanceStream && !form.appearanceStreamContent) {\n          // Calculate Appearance\n          var appearance = calculateAppearanceStream.call(this, form);\n          content += \"/AP << /N \" + appearance + \" >>\\n\";\n\n          scope.internal.acroformPlugin.xForms.push(appearance);\n        }\n\n        // Assume AppearanceStreamContent is a Array with N,R,D (at least\n        // one of them!)\n        if (form.appearanceStreamContent) {\n          content += \"/AP << \";\n          // Iterate over N,R and D\n          for (var k in form.appearanceStreamContent) {\n            var value = form.appearanceStreamContent[k];\n            content += \"/\" + k + \" \";\n            content += \"<< \";\n            if (Object.keys(value).length >= 1 || Array.isArray(value)) {\n              // appearanceStream is an Array or Object!\n              for (var i in value) {\n                var obj = value[i];\n                if (typeof obj === 'function') {\n                  // if Function is referenced, call it in order\n                  // to get the FormXObject\n                  obj = obj.call(this, form);\n                }\n                content += \"/\" + i + \" \" + obj + \" \";\n\n                // In case the XForm is already used, e.g. OffState\n                // of CheckBoxes, don't add it\n                if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj);\n              }\n            } else {\n              var obj = value;\n              if (typeof obj === 'function') {\n                // if Function is referenced, call it in order to\n                // get the FormXObject\n                obj = obj.call(this, form);\n              }\n              content += \"/\" + i + \" \" + obj + \" \\n\";\n              if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj);\n            }\n            content += \" >>\\n\";\n          }\n\n          // appearance stream is a normal Object..\n          content += \">>\\n\";\n        }\n\n        content += \">>\\nendobj\\n\";\n\n        scope.internal.out(content);\n      }\n      if (standardFields) {\n        createXFormObjectCallback.call(this, scope.internal.acroformPlugin.xForms);\n      }\n    };\n\n    var createXFormObjectCallback = function createXFormObjectCallback(fieldArray) {\n      for (var i in fieldArray) {\n        var key = i;\n        var form = fieldArray[i];\n        // Start Writing the Object\n        scope.internal.newObjectDeferredBegin(form && form.objId);\n\n        var content = \"\";\n        if ((typeof form === 'undefined' ? 'undefined' : _typeof(form)) === \"object\" && typeof form.getString === \"function\") {\n          content = form.getString();\n        }\n        scope.internal.out(content);\n\n        delete fieldArray[key];\n      }\n    };\n\n    var initializeAcroForm = function initializeAcroForm() {\n      if (this.internal !== undefined && (this.internal.acroformPlugin === undefined || this.internal.acroformPlugin.isInitialized === false)) {\n\n        scope = this;\n\n        AcroFormField.FieldNum = 0;\n        this.internal.acroformPlugin = JSON.parse(JSON.stringify(acroformPluginTemplate));\n        if (this.internal.acroformPlugin.acroFormDictionaryRoot) {\n          // return;\n          throw new Error(\"Exception while creating AcroformDictionary\");\n        }\n        scaleFactor = scope.internal.scaleFactor;\n        pageHeight = scope.internal.pageSize.getHeight();\n\n        // The Object Number of the AcroForm Dictionary\n        scope.internal.acroformPlugin.acroFormDictionaryRoot = new AcroFormDictionary();\n\n        // add Callback for creating the AcroForm Dictionary\n        scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID = scope.internal.events.subscribe('postPutResources', AcroFormDictionaryCallback);\n\n        scope.internal.events.subscribe('buildDocument', annotReferenceCallback); // buildDocument\n\n        // Register event, that is triggered when the DocumentCatalog is\n        // written, in order to add /AcroForm\n        scope.internal.events.subscribe('putCatalog', putCatalogCallback);\n\n        // Register event, that creates all Fields\n        scope.internal.events.subscribe('postPutPages', createFieldCallback);\n\n        scope.internal.acroformPlugin.isInitialized = true;\n      }\n    };\n\n    var arrayToPdfArray = function arrayToPdfArray(array) {\n      if (Array.isArray(array)) {\n        var content = ' [';\n        for (var i in array) {\n          var element = array[i].toString();\n          content += element;\n          content += i < array.length - 1 ? ' ' : '';\n        }\n        content += ']';\n\n        return content;\n      }\n    };\n\n    var toPdfString = function toPdfString(string) {\n      string = string || \"\";\n\n      // put Bracket at the Beginning of the String\n      if (string.indexOf('(') !== 0) {\n        string = '(' + string;\n      }\n\n      if (string.substring(string.length - 1) != ')') {\n        string += ')';\n      }\n      return string;\n    };\n\n    // ##########################\n    // Classes\n    // ##########################\n\n    var AcroFormPDFObject = function AcroFormPDFObject() {\n      // The Object ID in the PDF Object Model\n      // todo\n      var _objId;\n      Object.defineProperty(this, 'objId', {\n        get: function get$$1() {\n          if (!_objId) {\n            _objId = scope.internal.newObjectDeferred();\n          }\n          if (!_objId) {\n            console.log(\"Couldn't create Object ID\");\n          }\n          return _objId;\n        },\n        configurable: false\n      });\n    };\n\n    AcroFormPDFObject.prototype.toString = function () {\n      return this.objId + \" 0 R\";\n    };\n\n    AcroFormPDFObject.prototype.getString = function () {\n      var res = this.objId + \" 0 obj\\n<<\";\n      var content = this.getContent();\n\n      res += content + \">>\\n\";\n      if (this.stream) {\n        res += \"stream\\n\";\n        res += this.stream;\n        res += \"\\nendstream\\n\";\n      }\n      res += \"endobj\\n\";\n      return res;\n    };\n\n    AcroFormPDFObject.prototype.getContent = function () {\n      /**\n      * Prints out all enumerable Variables from the Object\n      * \n      * @param fieldObject\n      * @returns {string}\n      */\n      var createContentFromFieldObject = function createContentFromFieldObject(fieldObject) {\n        var content = '';\n\n        var keys = Object.keys(fieldObject).filter(function (key) {\n          return key != 'content' && key != 'appearanceStreamContent' && key.substring(0, 1) != \"_\";\n        });\n\n        for (var i in keys) {\n          var key = keys[i];\n          var value = fieldObject[key];\n\n          /*\n          * if (key == 'Rect' && value) { value =\n          * AcroForm.internal.calculateCoordinates.call(jsPDF.API.acroformPlugin.internal,\n          * value); }\n          */\n\n          if (value) {\n            if (Array.isArray(value)) {\n              content += '/' + key + ' ' + arrayToPdfArray(value) + \"\\n\";\n            } else if (value instanceof AcroFormPDFObject) {\n              // In case it is a reference to another PDFObject,\n              // take the referennce number\n              content += '/' + key + ' ' + value.objId + \" 0 R\" + \"\\n\";\n            } else {\n              content += '/' + key + ' ' + value + '\\n';\n            }\n          }\n        }\n        return content;\n      };\n\n      var object = \"\";\n\n      object += createContentFromFieldObject(this);\n      return object;\n    };\n\n    var AcroFormXObject = function AcroFormXObject() {\n      AcroFormPDFObject.call(this);\n      this.Type = \"/XObject\";\n      this.Subtype = \"/Form\";\n      this.FormType = 1;\n      this.BBox;\n      this.Matrix;\n      this.Resources = \"2 0 R\";\n      this.PieceInfo;\n      var _stream;\n      Object.defineProperty(this, 'Length', {\n        enumerable: true,\n        get: function get$$1() {\n          return _stream !== undefined ? _stream.length : 0;\n        }\n      });\n      Object.defineProperty(this, 'stream', {\n        enumerable: false,\n        set: function set$$1(val) {\n          _stream = val.trim();\n        },\n        get: function get$$1() {\n          if (_stream) {\n            return _stream;\n          } else {\n            return null;\n          }\n        }\n      });\n    };\n\n    inherit(AcroFormXObject, AcroFormPDFObject);\n    // ##### The Objects, the User can Create:\n\n    var AcroFormDictionary = function AcroFormDictionary() {\n      AcroFormPDFObject.call(this);\n      var _Kids = [];\n      Object.defineProperty(this, 'Kids', {\n        enumerable: false,\n        configurable: true,\n        get: function get$$1() {\n          if (_Kids.length > 0) {\n            return _Kids;\n          } else {\n            return;\n          }\n        }\n      });\n      Object.defineProperty(this, 'Fields', {\n        enumerable: true,\n        configurable: true,\n        get: function get$$1() {\n          return _Kids;\n        }\n      });\n      // Default Appearance\n      this.DA;\n    };\n\n    inherit(AcroFormDictionary, AcroFormPDFObject);\n\n    // The Field Object contains the Variables, that every Field needs\n    // Rectangle for Appearance: lower_left_X, lower_left_Y, width, height\n    var AcroFormField = function AcroFormField() {\n\n      AcroFormPDFObject.call(this);\n\n      var _Rect;\n      Object.defineProperty(this, 'Rect', {\n        enumerable: true,\n        configurable: false,\n        get: function get$$1() {\n          if (!_Rect) {\n            return;\n          }\n          var tmp = _Rect;\n          // var calculatedRes =\n          // AcroForm.internal.calculateCoordinates(_Rect); // do\n          // later!\n          return tmp;\n        },\n        set: function set$$1(val) {\n          _Rect = val;\n        }\n      });\n\n      var _FT = \"\";\n      Object.defineProperty(this, 'FT', {\n        enumerable: true,\n        set: function set$$1(val) {\n          _FT = val;\n        },\n        get: function get$$1() {\n          return _FT;\n        }\n      });\n      /**\n      * The Partial name of the Field Object. It has to be unique.\n      */\n      var _T;\n\n      Object.defineProperty(this, 'T', {\n        enumerable: true,\n        configurable: false,\n        set: function set$$1(val) {\n          _T = val;\n        },\n        get: function get$$1() {\n          if (!_T || _T.length < 1) {\n            if (this instanceof AcroFormChildClass) {\n              // In case of a Child from a Radio´Group, you don't\n              // need a FieldName!!!\n              return;\n            }\n            return \"(FieldObject\" + AcroFormField.FieldNum++ + \")\";\n          }\n          if (_T.substring(0, 1) == \"(\" && _T.substring(_T.length - 1)) {\n            return _T;\n          }\n          return \"(\" + _T + \")\";\n        }\n      });\n\n      var _DA;\n      // Defines the default appearance (Needed for variable Text)\n      Object.defineProperty(this, 'DA', {\n        enumerable: true,\n        get: function get$$1() {\n          if (!_DA) {\n            return;\n          }\n          return '(' + _DA + ')';\n        },\n        set: function set$$1(val) {\n          _DA = val;\n        }\n      });\n\n      var _DV;\n      // Defines the default value\n      Object.defineProperty(this, 'DV', {\n        enumerable: true,\n        configurable: true,\n        get: function get$$1() {\n          if (!_DV) {\n            return;\n          }\n          return _DV;\n        },\n        set: function set$$1(val) {\n          _DV = val;\n        }\n      });\n\n      var _V;\n      // Defines the default value\n      Object.defineProperty(this, 'V', {\n        enumerable: true,\n        configurable: true,\n        get: function get$$1() {\n          if (!_V) {\n            return;\n          }\n          return _V;\n        },\n        set: function set$$1(val) {\n          _V = val;\n        }\n      });\n\n      // this.Type = \"/Annot\";\n      // this.Subtype = \"/Widget\";\n      Object.defineProperty(this, 'Type', {\n        enumerable: true,\n        get: function get$$1() {\n          return this.hasAnnotation ? \"/Annot\" : null;\n        }\n      });\n\n      Object.defineProperty(this, 'Subtype', {\n        enumerable: true,\n        get: function get$$1() {\n          return this.hasAnnotation ? \"/Widget\" : null;\n        }\n      });\n\n      /**\n      * \n      * @type {Array}\n      */\n      this.BG;\n\n      Object.defineProperty(this, 'hasAnnotation', {\n        enumerable: false,\n        get: function get$$1() {\n          if (this.Rect || this.BC || this.BG) {\n            return true;\n          }\n          return false;\n        }\n      });\n\n      Object.defineProperty(this, 'hasAppearanceStream', {\n        enumerable: false,\n        configurable: true,\n        writable: true\n      });\n\n      Object.defineProperty(this, 'page', {\n        enumerable: false,\n        configurable: true,\n        writable: true\n      });\n    };\n\n    inherit(AcroFormField, AcroFormPDFObject);\n\n    var AcroFormChoiceField = function AcroFormChoiceField() {\n      AcroFormField.call(this);\n      // Field Type = Choice Field\n      this.FT = \"/Ch\";\n      // options\n      this.Opt = [];\n      this.V = '()';\n      // Top Index\n      this.TI = 0;\n      /**\n      * Defines, whether the\n      * \n      * @type {boolean}\n      */\n\n      var _combo = false;\n\n      Object.defineProperty(this, 'combo', {\n        enumerable: false,\n        get: function get$$1() {\n          return _combo;\n        },\n        set: function set$$1(val) {\n          _combo = val;\n        }\n      });\n      /**\n      * Defines, whether the Choice Field is an Edit Field. An Edit Field\n      * is automatically an Combo Field.\n      */\n      Object.defineProperty(this, 'edit', {\n        enumerable: true,\n        set: function set$$1(val) {\n          if (val == true) {\n            this._edit = true;\n            // ComboBox has to be true\n            this.combo = true;\n          } else {\n            this._edit = false;\n          }\n        },\n        get: function get$$1() {\n          if (!this._edit) {\n            return false;\n          }\n          return this._edit;\n        },\n        configurable: false\n      });\n      this.hasAppearanceStream = true;\n    };\n    inherit(AcroFormChoiceField, AcroFormField);\n\n    var AcroFormListBox = function AcroFormListBox() {\n      AcroFormChoiceField.call(this);\n      this.combo = false;\n    };\n    inherit(AcroFormListBox, AcroFormChoiceField);\n\n    var AcroFormComboBox = function AcroFormComboBox() {\n      AcroFormListBox.call(this);\n      this.combo = true;\n    };\n    inherit(AcroFormComboBox, AcroFormListBox);\n\n    var AcroFormEditBox = function AcroFormEditBox() {\n      AcroFormComboBox.call(this);\n      this.edit = true;\n    };\n    inherit(AcroFormEditBox, AcroFormComboBox);\n\n    var AcroFormButton = function AcroFormButton() {\n      AcroFormField.call(this);\n      this.FT = \"/Btn\";\n      // this.hasAnnotation = true;\n    };\n    inherit(AcroFormButton, AcroFormField);\n\n    var AcroFormPushButton = function AcroFormPushButton() {\n      AcroFormButton.call(this);\n\n      var _pushbutton = true;\n      Object.defineProperty(this, 'pushbutton', {\n        enumerable: false,\n        get: function get$$1() {\n          return _pushbutton;\n        },\n        set: function set$$1(val) {\n          _pushbutton = val;\n        }\n      });\n    };\n    inherit(AcroFormPushButton, AcroFormButton);\n\n    var AcroFormRadioButton = function AcroFormRadioButton() {\n      AcroFormButton.call(this);\n\n      var _radio = true;\n      Object.defineProperty(this, 'radio', {\n        enumerable: false,\n        get: function get$$1() {\n          return _radio;\n        },\n        set: function set$$1(val) {\n          _radio = val;\n        }\n      });\n\n      var _Kids = [];\n      Object.defineProperty(this, 'Kids', {\n        enumerable: true,\n        get: function get$$1() {\n          if (_Kids.length > 0) {\n            return _Kids;\n          }\n        }\n      });\n\n      Object.defineProperty(this, '__Kids', {\n        get: function get$$1() {\n          return _Kids;\n        }\n      });\n\n      var _noToggleToOff;\n\n      Object.defineProperty(this, 'noToggleToOff', {\n        enumerable: false,\n        get: function get$$1() {\n          return _noToggleToOff;\n        },\n        set: function set$$1(val) {\n          _noToggleToOff = val;\n        }\n      });\n\n      // this.hasAnnotation = false;\n    };\n    inherit(AcroFormRadioButton, AcroFormButton);\n\n    /*\n    * The Child classs of a RadioButton (the radioGroup) -> The single\n    * Buttons\n    */\n    var AcroFormChildClass = function AcroFormChildClass(parent, name) {\n      AcroFormField.call(this);\n      this.Parent = parent;\n\n      // todo: set AppearanceType as variable that can be set from the\n      // outside...\n      this._AppearanceType = AcroFormAppearance.RadioButton.Circle;\n      // The Default appearanceType is the Circle\n      this.appearanceStreamContent = this._AppearanceType.createAppearanceStream(name);\n\n      // Set Print in the Annot Flag\n      this.F = setBitPosition(this.F, 3, 1);\n\n      // Set AppearanceCharacteristicsDictionary with default appearance\n      // if field is not interacting with user\n      this.MK = this._AppearanceType.createMK();\n      // (8) -> Cross, (1)->  Circle, ()-> nothing\n\n      // Default Appearance is Off\n      this.AS = \"/Off\"; // + name;\n\n      this._Name = name;\n    };\n    inherit(AcroFormChildClass, AcroFormField);\n\n    AcroFormRadioButton.prototype.setAppearance = function (appearance) {\n      if (!('createAppearanceStream' in appearance && 'createMK' in appearance)) {\n        console.log(\"Couldn't assign Appearance to RadioButton. Appearance was Invalid!\");\n        return;\n      }\n      for (var i in this.__Kids) {\n        var child = this.__Kids[i];\n\n        child.appearanceStreamContent = appearance.createAppearanceStream(child._Name);\n        child.MK = appearance.createMK();\n      }\n    };\n\n    AcroFormRadioButton.prototype.createOption = function (name) {\n      var parent = this;\n      var kidCount = this.__Kids.length;\n\n      // Create new Child for RadioGroup\n      var child = new AcroFormChildClass(parent, name);\n      // Add to Parent\n      this.__Kids.push(child);\n\n      jsPDFAPI.addField(child);\n\n      return child;\n    };\n\n    var AcroFormCheckBox = function AcroFormCheckBox() {\n      AcroFormButton.call(this);\n      this.appearanceStreamContent = AcroFormAppearance.CheckBox.createAppearanceStream();\n      this.MK = AcroFormAppearance.CheckBox.createMK();\n      this.AS = \"/On\";\n      this.V = \"/On\";\n    };\n    inherit(AcroFormCheckBox, AcroFormButton);\n\n    var AcroFormTextField = function AcroFormTextField() {\n      AcroFormField.call(this);\n      this.DA = AcroFormAppearance.createDefaultAppearanceStream();\n      this.F = 4;\n      var _V;\n      Object.defineProperty(this, 'V', {\n        get: function get$$1() {\n          if (_V) {\n            return toPdfString(_V);\n          } else {\n            return _V;\n          }\n        },\n        enumerable: true,\n        set: function set$$1(val) {\n          _V = val;\n        }\n      });\n\n      var _DV;\n      Object.defineProperty(this, 'DV', {\n        get: function get$$1() {\n          if (_DV) {\n            return toPdfString(_DV);\n          } else {\n            return _DV;\n          }\n        },\n        enumerable: true,\n        set: function set$$1(val) {\n          _DV = val;\n        }\n      });\n\n      var _multiline = false;\n      Object.defineProperty(this, 'multiline', {\n        enumerable: false,\n        get: function get$$1() {\n          return _multiline;\n        },\n        set: function set$$1(val) {\n          _multiline = val;\n        }\n      });\n\n      /**\n      * For PDF 1.4\n      * \n      * @type {boolean}\n      */\n      var _fileSelect = false;\n      Object.defineProperty(this, 'fileSelect', {\n        enumerable: false,\n        get: function get$$1() {\n          return _fileSelect;\n        },\n        set: function set$$1(val) {\n          _fileSelect = val;\n        }\n      });\n      /**\n      * For PDF 1.4\n      * \n      * @type {boolean}\n      */\n      var _doNotSpellCheck = false;\n      Object.defineProperty(this, 'doNotSpellCheck', {\n        enumerable: false,\n        get: function get$$1() {\n          return _doNotSpellCheck;\n        },\n        set: function set$$1(val) {\n          _doNotSpellCheck = val;\n        }\n      });\n      /**\n      * For PDF 1.4\n      * \n      * @type {boolean}\n      */\n      var _doNotScroll = false;\n      Object.defineProperty(this, 'doNotScroll', {\n        enumerable: false,\n        get: function get$$1() {\n          return _doNotScroll;\n        },\n        set: function set$$1(val) {\n          _doNotScroll = val;\n        }\n      });\n\n      var _MaxLen = false;\n      Object.defineProperty(this, 'MaxLen', {\n        enumerable: true,\n        get: function get$$1() {\n          return _MaxLen;\n        },\n        set: function set$$1(val) {\n          _MaxLen = val;\n        }\n      });\n\n      Object.defineProperty(this, 'hasAppearanceStream', {\n        enumerable: false,\n        get: function get$$1() {\n          return this.V || this.DV;\n        }\n      });\n    };\n    inherit(AcroFormTextField, AcroFormField);\n\n    var AcroFormPasswordField = function AcroFormPasswordField() {\n      AcroFormTextField.call(this);\n\n      var _password = true;\n      Object.defineProperty(this, 'password', {\n        enumerable: false,\n        get: function get$$1() {\n          return _password;\n        },\n        set: function set$$1(val) {\n          _password = val;\n        }\n      });\n    };\n    inherit(AcroFormPasswordField, AcroFormTextField);\n\n    // Contains Methods for creating standard appearances\n    var AcroFormAppearance = {\n      CheckBox: {\n        createAppearanceStream: function createAppearanceStream() {\n          var appearance = {\n            N: {\n              On: AcroFormAppearance.CheckBox.YesNormal\n            },\n            D: {\n              On: AcroFormAppearance.CheckBox.YesPushDown,\n              Off: AcroFormAppearance.CheckBox.OffPushDown\n            }\n          };\n\n          return appearance;\n        },\n        /**\n          * If any other icons are needed, the number between the\n          * brackets can be changed\n          * \n          * @returns {string}\n          */\n        createMK: function createMK() {\n          return \"<< /CA (3)>>\";\n        },\n        /**\n          * Returns the standard On Appearance for a CheckBox\n          * \n          * @returns {AcroFormXObject}\n          */\n        YesPushDown: function YesPushDown(formObject) {\n          var xobj = createFormXObject(formObject);\n          var stream = [];\n          var zapfDingbatsId = scope.internal.getFont(\"zapfdingbats\", \"normal\").id;\n          formObject.Q = 1; // set text-alignment as centered\n          var calcRes = calculateX(formObject, \"3\", \"ZapfDingbats\", 50);\n          stream.push(\"0.749023 g\");\n          stream.push(\"0 0 \" + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + \" \" + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + \" re\");\n          stream.push(\"f\");\n          stream.push(\"BMC\");\n          stream.push(\"q\");\n          stream.push(\"0 0 1 rg\");\n          stream.push(\"/\" + zapfDingbatsId + \" \" + calcRes.fontSize.toFixed(2) + \" Tf 0 g\");\n          stream.push(\"BT\");\n          stream.push(calcRes.text);\n          stream.push(\"ET\");\n          stream.push(\"Q\");\n          stream.push(\"EMC\");\n          xobj.stream = stream.join(\"\\n\");\n          return xobj;\n        },\n\n        YesNormal: function YesNormal(formObject) {\n          var xobj = createFormXObject(formObject);\n          var zapfDingbatsId = scope.internal.getFont(\"zapfdingbats\", \"normal\").id;\n          var stream = [];\n          formObject.Q = 1; // set text-alignment as centered\n          var height = AcroFormAppearance.internal.getHeight(formObject);\n          var width = AcroFormAppearance.internal.getWidth(formObject);\n          var calcRes = calculateX(formObject, \"3\", \"ZapfDingbats\", height * 0.9);\n          stream.push(\"1 g\");\n          stream.push(\"0 0 \" + width.toFixed(2) + \" \" + height.toFixed(2) + \" re\");\n          stream.push(\"f\");\n          stream.push(\"q\");\n          stream.push(\"0 0 1 rg\");\n          stream.push(\"0 0 \" + (width - 1).toFixed(2) + \" \" + (height - 1).toFixed(2) + \" re\");\n          stream.push(\"W\");\n          stream.push(\"n\");\n          stream.push(\"0 g\");\n          stream.push(\"BT\");\n          stream.push(\"/\" + zapfDingbatsId + \" \" + calcRes.fontSize.toFixed(2) + \" Tf 0 g\");\n          stream.push(calcRes.text);\n          stream.push(\"ET\");\n          stream.push(\"Q\");\n          xobj.stream = stream.join(\"\\n\");\n          return xobj;\n        },\n\n        /**\n          * Returns the standard Off Appearance for a CheckBox\n          * \n          * @returns {AcroFormXObject}\n          */\n        OffPushDown: function OffPushDown(formObject) {\n          var xobj = createFormXObject(formObject);\n          var stream = [];\n          stream.push(\"0.749023 g\");\n          stream.push(\"0 0 \" + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + \" \" + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + \" re\");\n          stream.push(\"f\");\n          xobj.stream = stream.join(\"\\n\");\n          return xobj;\n        }\n      },\n\n      RadioButton: {\n        Circle: {\n          createAppearanceStream: function createAppearanceStream(name) {\n            var appearanceStreamContent = {\n              D: {\n                'Off': AcroFormAppearance.RadioButton.Circle.OffPushDown\n              },\n              N: {}\n            };\n            appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Circle.YesNormal;\n            appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Circle.YesPushDown;\n            return appearanceStreamContent;\n          },\n          createMK: function createMK() {\n            return \"<< /CA (l)>>\";\n          },\n\n          YesNormal: function YesNormal(formObject) {\n            var xobj = createFormXObject(formObject);\n            var stream = [];\n            // Make the Radius of the Circle relative to min(height,\n            // width) of formObject\n            var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4;\n            // The Borderpadding...\n            DotRadius *= 0.9;\n            var c = AcroFormAppearance.internal.Bezier_C;\n            /*\n              * The Following is a Circle created with Bezier-Curves.\n              */\n            stream.push(\"q\");\n            stream.push(\"1 0 0 1 \" + AcroFormAppearance.internal.getWidth(formObject) / 2 + \" \" + AcroFormAppearance.internal.getHeight(formObject) / 2 + \" cm\");\n            stream.push(DotRadius + \" 0 m\");\n            stream.push(DotRadius + \" \" + DotRadius * c + \" \" + DotRadius * c + \" \" + DotRadius + \" 0 \" + DotRadius + \" c\");\n            stream.push(\"-\" + DotRadius * c + \" \" + DotRadius + \" -\" + DotRadius + \" \" + DotRadius * c + \" -\" + DotRadius + \" 0 c\");\n            stream.push(\"-\" + DotRadius + \" -\" + DotRadius * c + \" -\" + DotRadius * c + \" -\" + DotRadius + \" 0 -\" + DotRadius + \" c\");\n            stream.push(DotRadius * c + \" -\" + DotRadius + \" \" + DotRadius + \" -\" + DotRadius * c + \" \" + DotRadius + \" 0 c\");\n            stream.push(\"f\");\n            stream.push(\"Q\");\n            xobj.stream = stream.join(\"\\n\");\n            return xobj;\n          },\n          YesPushDown: function YesPushDown(formObject) {\n            var xobj = createFormXObject(formObject);\n            var stream = [];\n            var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4;\n            // The Borderpadding...\n            DotRadius *= 0.9;\n            // Save results for later use; no need to waste\n            // processor ticks on doing math\n            var k = DotRadius * 2;\n            // var c = AcroFormAppearance.internal.Bezier_C;\n            var kc = k * AcroFormAppearance.internal.Bezier_C;\n            var dc = DotRadius * AcroFormAppearance.internal.Bezier_C;\n\n            stream.push(\"0.749023 g\");\n            stream.push(\"q\");\n            stream.push(\"1 0 0 1 \" + (AcroFormAppearance.internal.getWidth(formObject) / 2).toFixed(2) + \" \" + (AcroFormAppearance.internal.getHeight(formObject) / 2).toFixed(2) + \" cm\");\n            stream.push(k + \" 0 m\");\n            stream.push(k + \" \" + kc + \" \" + kc + \" \" + k + \" 0 \" + k + \" c\");\n            stream.push(\"-\" + kc + \" \" + k + \" -\" + k + \" \" + kc + \" -\" + k + \" 0 c\");\n            stream.push(\"-\" + k + \" -\" + kc + \" -\" + kc + \" -\" + k + \" 0 -\" + k + \" c\");\n            stream.push(kc + \" -\" + k + \" \" + k + \" -\" + kc + \" \" + k + \" 0 c\");\n            stream.push(\"f\");\n            stream.push(\"Q\");\n            stream.push(\"0 g\");\n            stream.push(\"q\");\n            stream.push(\"1 0 0 1 \" + (AcroFormAppearance.internal.getWidth(formObject) / 2).toFixed(2) + \" \" + (AcroFormAppearance.internal.getHeight(formObject) / 2).toFixed(2) + \" cm\");\n            stream.push(DotRadius + \" 0 m\");\n            stream.push(\"\" + DotRadius + \" \" + dc + \" \" + dc + \" \" + DotRadius + \" 0 \" + DotRadius + \" c\");\n            stream.push(\"-\" + dc + \" \" + DotRadius + \" -\" + DotRadius + \" \" + dc + \" -\" + DotRadius + \" 0 c\");\n            stream.push(\"-\" + DotRadius + \" -\" + dc + \" -\" + dc + \" -\" + DotRadius + \" 0 -\" + DotRadius + \" c\");\n            stream.push(dc + \" -\" + DotRadius + \" \" + DotRadius + \" -\" + dc + \" \" + DotRadius + \" 0 c\");\n            stream.push(\"f\");\n            stream.push(\"Q\");\n            xobj.stream = stream.join(\"\\n\");\n            return xobj;\n          },\n          OffPushDown: function OffPushDown(formObject) {\n            var xobj = createFormXObject(formObject);\n            var stream = [];\n            var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4;\n            // The Borderpadding...\n            DotRadius *= 0.9;\n            // Save results for later use; no need to waste\n            // processor ticks on doing math\n            var k = DotRadius * 2;\n            // var c = AcroFormAppearance.internal.Bezier_C;\n            var kc = k * AcroFormAppearance.internal.Bezier_C;\n\n            stream.push(\"0.749023 g\");\n            stream.push(\"q\");\n            stream.push(\"1 0 0 1 \" + (AcroFormAppearance.internal.getWidth(formObject) / 2).toFixed(2) + \" \" + (AcroFormAppearance.internal.getHeight(formObject) / 2).toFixed(2) + \" cm\");\n            stream.push(k + \" 0 m\");\n            stream.push(k + \" \" + kc + \" \" + kc + \" \" + k + \" 0 \" + k + \" c\");\n            stream.push(\"-\" + kc + \" \" + k + \" -\" + k + \" \" + kc + \" -\" + k + \" 0 c\");\n            stream.push(\"-\" + k + \" -\" + kc + \" -\" + kc + \" -\" + k + \" 0 -\" + k + \" c\");\n            stream.push(kc + \" -\" + k + \" \" + k + \" -\" + kc + \" \" + k + \" 0 c\");\n            stream.push(\"f\");\n            stream.push(\"Q\");\n            xobj.stream = stream.join(\"\\n\");\n            return xobj;\n          }\n        },\n\n        Cross: {\n          /**\n            * Creates the Actual AppearanceDictionary-References\n            * \n            * @param name\n            * @returns\n            */\n          createAppearanceStream: function createAppearanceStream(name) {\n            var appearanceStreamContent = {\n              D: {\n                'Off': AcroFormAppearance.RadioButton.Cross.OffPushDown\n              },\n              N: {}\n            };\n            appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Cross.YesNormal;\n            appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Cross.YesPushDown;\n            return appearanceStreamContent;\n          },\n          createMK: function createMK() {\n            return \"<< /CA (8)>>\";\n          },\n\n          YesNormal: function YesNormal(formObject) {\n            var xobj = createFormXObject(formObject);\n            var stream = [];\n            var cross = AcroFormAppearance.internal.calculateCross(formObject);\n            stream.push(\"q\");\n            stream.push(\"1 1 \" + (AcroFormAppearance.internal.getWidth(formObject) - 2).toFixed(2) + \" \" + (AcroFormAppearance.internal.getHeight(formObject) - 2).toFixed(2) + \" re\");\n            stream.push(\"W\");\n            stream.push(\"n\");\n            stream.push(cross.x1.x.toFixed(2) + \" \" + cross.x1.y.toFixed(2) + \" m\");\n            stream.push(cross.x2.x.toFixed(2) + \" \" + cross.x2.y.toFixed(2) + \" l\");\n            stream.push(cross.x4.x.toFixed(2) + \" \" + cross.x4.y.toFixed(2) + \" m\");\n            stream.push(cross.x3.x.toFixed(2) + \" \" + cross.x3.y.toFixed(2) + \" l\");\n            stream.push(\"s\");\n            stream.push(\"Q\");\n            xobj.stream = stream.join(\"\\n\");\n            return xobj;\n          },\n          YesPushDown: function YesPushDown(formObject) {\n            var xobj = createFormXObject(formObject);\n            var cross = AcroFormAppearance.internal.calculateCross(formObject);\n            var stream = [];\n            stream.push(\"0.749023 g\");\n            stream.push(\"0 0 \" + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + \" \" + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + \" re\");\n            stream.push(\"f\");\n            stream.push(\"q\");\n            stream.push(\"1 1 \" + (AcroFormAppearance.internal.getWidth(formObject) - 2).toFixed(2) + \" \" + (AcroFormAppearance.internal.getHeight(formObject) - 2).toFixed(2) + \" re\");\n            stream.push(\"W\");\n            stream.push(\"n\");\n            stream.push(cross.x1.x.toFixed(2) + \" \" + cross.x1.y.toFixed(2) + \" m\");\n            stream.push(cross.x2.x.toFixed(2) + \" \" + cross.x2.y.toFixed(2) + \" l\");\n            stream.push(cross.x4.x.toFixed(2) + \" \" + cross.x4.y.toFixed(2) + \" m\");\n            stream.push(cross.x3.x.toFixed(2) + \" \" + cross.x3.y.toFixed(2) + \" l\");\n            stream.push(\"s\");\n            stream.push(\"Q\");\n            xobj.stream = stream.join(\"\\n\");\n            return xobj;\n          },\n          OffPushDown: function OffPushDown(formObject) {\n            var xobj = createFormXObject(formObject);\n            var stream = [];\n            stream.push(\"0.749023 g\");\n            stream.push(\"0 0 \" + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + \" \" + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + \" re\");\n            stream.push(\"f\");\n            xobj.stream = stream.join(\"\\n\");\n            return xobj;\n          }\n        }\n      },\n\n      /**\n        * Returns the standard Appearance\n        * \n        * @returns {AcroFormXObject}\n        */\n      createDefaultAppearanceStream: function createDefaultAppearanceStream(formObject) {\n        // Set Helvetica to Standard Font (size: auto)\n        // Color: Black\n        return \"/F1 0 Tf 0 g\";\n      }\n    };\n\n    AcroFormAppearance.internal = {\n      Bezier_C: 0.551915024494,\n\n      calculateCross: function calculateCross(formObject) {\n        var min = function min(x, y) {\n          return x > y ? y : x;\n        };\n\n        var width = AcroFormAppearance.internal.getWidth(formObject);\n        var height = AcroFormAppearance.internal.getHeight(formObject);\n        var a = min(width, height);\n\n\n        var cross = {\n          x1: { // upperLeft\n            x: (width - a) / 2,\n            y: (height - a) / 2 + a // height - borderPadding\n          },\n          x2: { // lowerRight\n            x: (width - a) / 2 + a,\n            y: (height - a) / 2 // borderPadding\n          },\n          x3: { // lowerLeft\n            x: (width - a) / 2,\n            y: (height - a) / 2 // borderPadding\n          },\n          x4: { // upperRight\n            x: (width - a) / 2 + a,\n            y: (height - a) / 2 + a // height - borderPadding\n          }\n        };\n\n        return cross;\n      }\n    };\n    AcroFormAppearance.internal.getWidth = function (formObject) {\n      var result = 0;\n      if ((typeof formObject === 'undefined' ? 'undefined' : _typeof(formObject)) === \"object\") {\n        result = scale(formObject.Rect[2]); // (formObject.Rect[2] -\n        // formObject.Rect[0]) || 0;\n      }\n      return result;\n    };\n    AcroFormAppearance.internal.getHeight = function (formObject) {\n      var result = 0;\n      if ((typeof formObject === 'undefined' ? 'undefined' : _typeof(formObject)) === \"object\") {\n        result = scale(formObject.Rect[3]); // (formObject.Rect[1] -\n        // formObject.Rect[3]) || 0;\n      }\n      return result;\n    };\n\n    // Public:\n\n    jsPDFAPI.addField = function (fieldObject) {\n      initializeAcroForm.call(this);\n      // var opt = parseOptions(fieldObject);\n      if (fieldObject instanceof AcroFormTextField) {\n        this.addTextField.call(this, fieldObject);\n      } else if (fieldObject instanceof AcroFormChoiceField) {\n        this.addChoiceField.call(this, fieldObject);\n      } else if (fieldObject instanceof AcroFormButton) {\n        this.addButton.call(this, fieldObject);\n      } else if (fieldObject instanceof AcroFormChildClass) {\n        putForm.call(this, fieldObject);\n      } else if (fieldObject) {\n        // try to put..\n        putForm.call(this, fieldObject);\n      }\n      fieldObject.page = scope.internal.getCurrentPageInfo().pageNumber;\n      return this;\n    };\n\n    /**\n    * Button FT = Btn\n    */\n    jsPDFAPI.addButton = function (opts) {\n      initializeAcroForm.call(this);\n      var options = opts || new AcroFormField();\n\n      options.FT = '/Btn';\n      options.Ff = calculateFlagsOnOptions(options.Ff, opts, scope.internal.getPDFVersion());\n\n      putForm.call(this, options);\n    };\n\n    jsPDFAPI.addTextField = function (opts) {\n      initializeAcroForm.call(this);\n      var options = opts || new AcroFormField();\n\n      options.FT = '/Tx';\n\n      options.Ff = calculateFlagsOnOptions(options.Ff, opts, scope.internal.getPDFVersion());\n\n      // Add field\n      putForm.call(this, options);\n    };\n\n    jsPDFAPI.addChoiceField = function (opts) {\n      initializeAcroForm.call(this);\n      var options = opts || new AcroFormField();\n\n      options.FT = '/Ch';\n\n      options.Ff = calculateFlagsOnOptions(options.Ff, opts, scope.internal.getPDFVersion());\n      // options.hasAnnotation = true;\n\n      // Add field\n      putForm.call(this, options);\n    };\n\n    if ((typeof globalObj === 'undefined' ? 'undefined' : _typeof(globalObj)) == \"object\") {\n      globalObj[\"ChoiceField\"] = AcroFormChoiceField;\n      globalObj[\"ListBox\"] = AcroFormListBox;\n      globalObj[\"ComboBox\"] = AcroFormComboBox;\n      globalObj[\"EditBox\"] = AcroFormEditBox;\n      globalObj[\"Button\"] = AcroFormButton;\n      globalObj[\"PushButton\"] = AcroFormPushButton;\n      globalObj[\"RadioButton\"] = AcroFormRadioButton;\n      globalObj[\"CheckBox\"] = AcroFormCheckBox;\n      globalObj[\"TextField\"] = AcroFormTextField;\n      globalObj[\"PasswordField\"] = AcroFormPasswordField;\n\n      // backwardsCompatibility\n      globalObj[\"AcroForm\"] = { Appearance: AcroFormAppearance };\n    }\n\n    jsPDFAPI.AcroFormChoiceField = AcroFormChoiceField;\n    jsPDFAPI.AcroFormListBox = AcroFormListBox;\n    jsPDFAPI.AcroFormComboBox = AcroFormComboBox;\n    jsPDFAPI.AcroFormEditBox = AcroFormEditBox;\n    jsPDFAPI.AcroFormButton = AcroFormButton;\n    jsPDFAPI.AcroFormPushButton = AcroFormPushButton;\n    jsPDFAPI.AcroFormRadioButton = AcroFormRadioButton;\n    jsPDFAPI.AcroFormCheckBox = AcroFormCheckBox;\n    jsPDFAPI.AcroFormTextField = AcroFormTextField;\n    jsPDFAPI.AcroFormPasswordField = AcroFormPasswordField;\n\n    jsPDFAPI.AcroForm = {\n      ChoiceField: AcroFormChoiceField,\n      ListBox: AcroFormListBox,\n      ComboBox: AcroFormComboBox,\n      EditBox: AcroFormEditBox,\n      Button: AcroFormButton,\n      PushButton: AcroFormPushButton,\n      RadioButton: AcroFormRadioButton,\n      CheckBox: AcroFormCheckBox,\n      TextField: AcroFormTextField,\n      PasswordField: AcroFormPasswordField\n    };\n  })(jsPDF.API, typeof window !== \"undefined\" && window || typeof global !== \"undefined\" && global);\n\n  /**\n   * jsPDF addHTML PlugIn\n   * Copyright (c) 2014 Diego Casorran\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n\n  (function (jsPDFAPI) {\n\n      /**\n       * Renders an HTML element to canvas object which added to the PDF\n       *\n       * This feature requires [html2canvas](https://github.com/niklasvh/html2canvas)\n       * or [rasterizeHTML](https://github.com/cburgmer/rasterizeHTML.js)\n       *\n       * @returns {jsPDF}\n       * @name addHTML\n       * @param element {Mixed} HTML Element, or anything supported by html2canvas.\n       * @param x {Number} starting X coordinate in jsPDF instance's declared units.\n       * @param y {Number} starting Y coordinate in jsPDF instance's declared units.\n       * @param options {Object} Additional options, check the code below.\n       * @param callback {Function} to call when the rendering has finished.\n       * NOTE: Every parameter is optional except 'element' and 'callback', in such\n       *       case the image is positioned at 0x0 covering the whole PDF document\n       *       size. Ie, to easily take screenshots of webpages saving them to PDF.\n       * @deprecated This is being replace with a vector-supporting API. See\n       * [this link](https://cdn.rawgit.com/MrRio/jsPDF/master/examples/html2pdf/showcase_supported_html.html)\n       */\n\n      jsPDFAPI.addHTML = function (element, x, y, options, callback) {\n\n          if (typeof html2canvas === 'undefined' && typeof rasterizeHTML === 'undefined') throw new Error('You need either ' + 'https://github.com/niklasvh/html2canvas' + ' or https://github.com/cburgmer/rasterizeHTML.js');\n\n          if (typeof x !== 'number') {\n              options = x;\n              callback = y;\n          }\n\n          if (typeof options === 'function') {\n              callback = options;\n              options = null;\n          }\n\n          if (typeof callback !== 'function') {\n              callback = function callback() {};\n          }\n\n          var I = this.internal,\n              K = I.scaleFactor,\n              W = I.pageSize.getWidth(),\n              H = I.pageSize.getHeight();\n\n          options = options || {};\n          options.onrendered = function (obj) {\n              x = parseInt(x) || 0;\n              y = parseInt(y) || 0;\n              var dim = options.dim || {};\n              var margin = Object.assign({ top: 0, right: 0, bottom: 0, left: 0, useFor: 'content' }, options.margin);\n              var h = dim.h || Math.min(H, obj.height / K);\n              var w = dim.w || Math.min(W, obj.width / K) - x;\n\n              var format = options.format || 'JPEG';\n              var imageCompression = options.imageCompression || 'SLOW';\n\n              var notFittingHeight = obj.height > H - margin.top - margin.bottom;\n\n              if (notFittingHeight && options.pagesplit) {\n                  var cropArea = function cropArea(parmObj, parmX, parmY, parmWidth, parmHeight) {\n                      var canvas = document.createElement('canvas');\n                      canvas.height = parmHeight;\n                      canvas.width = parmWidth;\n                      var ctx = canvas.getContext('2d');\n                      ctx.mozImageSmoothingEnabled = false;\n                      ctx.webkitImageSmoothingEnabled = false;\n                      ctx.msImageSmoothingEnabled = false;\n                      ctx.imageSmoothingEnabled = false;\n                      ctx.fillStyle = options.backgroundColor || '#ffffff';\n                      ctx.fillRect(0, 0, parmWidth, parmHeight);\n                      ctx.drawImage(parmObj, parmX, parmY, parmWidth, parmHeight, 0, 0, parmWidth, parmHeight);\n                      return canvas;\n                  };\n                  var crop = function () {\n                      var cy = 0;\n                      var cx = 0;\n                      var position = {};\n                      var isOverWide = false;\n                      var width;\n                      var height;\n                      while (1) {\n                          cx = 0;\n                          position.top = cy !== 0 ? margin.top : y;\n                          position.left = cy !== 0 ? margin.left : x;\n                          isOverWide = (W - margin.left - margin.right) * K < obj.width;\n                          if (margin.useFor === \"content\") {\n                              if (cy === 0) {\n                                  width = Math.min((W - margin.left) * K, obj.width);\n                                  height = Math.min((H - margin.top) * K, obj.height - cy);\n                              } else {\n                                  width = Math.min(W * K, obj.width);\n                                  height = Math.min(H * K, obj.height - cy);\n                                  position.top = 0;\n                              }\n                          } else {\n                              width = Math.min((W - margin.left - margin.right) * K, obj.width);\n                              height = Math.min((H - margin.bottom - margin.top) * K, obj.height - cy);\n                          }\n                          if (isOverWide) {\n                              while (1) {\n                                  if (margin.useFor === \"content\") {\n                                      if (cx === 0) {\n                                          width = Math.min((W - margin.left) * K, obj.width);\n                                      } else {\n                                          width = Math.min(W * K, obj.width - cx);\n                                          position.left = 0;\n                                      }\n                                  }\n                                  var canvas = cropArea(obj, cx, cy, width, height);\n                                  var args = [canvas, position.left, position.top, canvas.width / K, canvas.height / K, format, null, imageCompression];\n                                  this.addImage.apply(this, args);\n                                  cx += width;\n                                  if (cx >= obj.width) {\n                                      break;\n                                  }\n                                  this.addPage();\n                              }\n                          } else {\n                              var canvas = cropArea(obj, 0, cy, width, height);\n                              var args = [canvas, position.left, position.top, canvas.width / K, canvas.height / K, format, null, imageCompression];\n                              this.addImage.apply(this, args);\n                          }\n                          cy += height;\n                          if (cy >= obj.height) {\n                              break;\n                          }\n                          this.addPage();\n                      }\n                      callback(w, cy, null, args);\n                  }.bind(this);\n                  if (obj.nodeName === 'CANVAS') {\n                      var img = new Image();\n                      img.onload = crop;\n                      img.src = obj.toDataURL(\"image/png\");\n                      obj = img;\n                  } else {\n                      crop();\n                  }\n              } else {\n                  var alias = Math.random().toString(35);\n                  var args = [obj, x, y, w, h, format, alias, imageCompression];\n\n                  this.addImage.apply(this, args);\n\n                  callback(w, h, alias, args);\n              }\n          }.bind(this);\n\n          if (typeof html2canvas !== 'undefined' && !options.rstz) {\n              return html2canvas(element, options);\n          }\n\n          if (typeof rasterizeHTML !== 'undefined') {\n              var meth = 'drawDocument';\n              if (typeof element === 'string') {\n                  meth = /^http/.test(element) ? 'drawURL' : 'drawHTML';\n              }\n              options.width = options.width || W * K;\n              return rasterizeHTML[meth](element, void 0, options).then(function (r) {\n                  options.onrendered(r.image);\n              }, function (e) {\n                  callback(null, e);\n              });\n          }\n\n          return null;\n      };\n  })(jsPDF.API);\n\n  /** @preserve\n   * jsPDF addImage plugin\n   * Copyright (c) 2012 Jason Siefken, https://github.com/siefkenj/\n   *               2013 Chris Dowling, https://github.com/gingerchris\n   *               2013 Trinh Ho, https://github.com/ineedfat\n   *               2013 Edwin Alejandro Perez, https://github.com/eaparango\n   *               2013 Norah Smith, https://github.com/burnburnrocket\n   *               2014 Diego Casorran, https://github.com/diegocr\n   *               2014 James Robb, https://github.com/jamesbrobb\n   *\n   * \n   */\n  (function (jsPDFAPI) {\n\n  \tvar namespace = 'addImage_';\n\n  \tvar imageFileTypeHeaders = {\n  \t\tPNG: [[0x89, 0x50, 0x4e, 0x47]],\n  \t\tTIFF: [[0x4D, 0x4D, 0x00, 0x2A], //Motorola\n  \t\t[0x49, 0x49, 0x2A, 0x00] //Intel\n  \t\t],\n  \t\tJPEG: [[0xFF, 0xD8, 0xFF, 0xE0, undefined, undefined, 0x4A, 0x46, 0x49, 0x46, 0x00], //JFIF\n  \t\t[0xFF, 0xD8, 0xFF, 0xE1, undefined, undefined, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00] //Exif\n  \t\t],\n  \t\tJPEG2000: [[0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20]],\n  \t\tGIF87a: [[0x47, 0x49, 0x46, 0x38, 0x37, 0x61]],\n  \t\tGIF89a: [[0x47, 0x49, 0x46, 0x38, 0x39, 0x61]],\n  \t\tBMP: [[0x42, 0x4D], //BM - Windows 3.1x, 95, NT, ... etc.\n  \t\t[0x42, 0x41], //BA - OS/2 struct bitmap array\n  \t\t[0x43, 0x49], //CI - OS/2 struct color icon\n  \t\t[0x43, 0x50], //CP - OS/2 const color pointer\n  \t\t[0x49, 0x43], //IC - OS/2 struct icon\n  \t\t[0x50, 0x54] //PT - OS/2 pointer\n  \t\t]\n  \t\t/**\n    * Recognize filetype of Image by magic-bytes\n    * \n    * https://en.wikipedia.org/wiki/List_of_file_signatures\n    *\n    * @name getImageFileTypeByImageData\n    * @public\n    * @function\n    * @param {String} imageData as base64 encoded DataUrl\n    * @param {String} format of file if filetype-recognition fails, e.g. 'JPEG'\n    * \n    * @returns {String} filetype of Image\n    * @methodOf jsPDF#\n    */\n  \t};jsPDFAPI.getImageFileTypeByImageData = function (imageData, fallbackFormat) {\n  \t\tfallbackFormat = fallbackFormat || 'UNKNOWN';\n  \t\tvar i;\n  \t\tvar j;\n  \t\tvar result = 'UNKNOWN';\n  \t\tvar headerSchemata;\n  \t\tvar compareResult;\n  \t\tvar fileType;\n\n  \t\tfor (fileType in imageFileTypeHeaders) {\n  \t\t\theaderSchemata = imageFileTypeHeaders[fileType];\n  \t\t\tfor (i = 0; i < headerSchemata.length; i += 1) {\n  \t\t\t\tcompareResult = true;\n  \t\t\t\tfor (j = 0; j < headerSchemata[i].length; j += 1) {\n  \t\t\t\t\tif (headerSchemata[i][j] === undefined) {\n  \t\t\t\t\t\tcontinue;\n  \t\t\t\t\t}\n  \t\t\t\t\tif (headerSchemata[i][j] !== imageData.charCodeAt(j)) {\n  \t\t\t\t\t\tcompareResult = false;\n  \t\t\t\t\t\tbreak;\n  \t\t\t\t\t}\n  \t\t\t\t}\n  \t\t\t\tif (compareResult === true) {\n  \t\t\t\t\tresult = fileType;\n  \t\t\t\t\tbreak;\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n  \t\tif (result === 'UNKNOWN' && fallbackFormat !== 'UNKNOWN') {\n  \t\t\tconsole.warn('FileType of Image not recognized. Processing image as \"' + fallbackFormat + '\".');\n  \t\t\tresult = fallbackFormat;\n  \t\t}\n  \t\treturn result;\n  \t};\n\n  \t// Image functionality ported from pdf.js\n  \tvar putImage = function putImage(img) {\n\n  \t\tvar objectNumber = this.internal.newObject(),\n  \t\t    out = this.internal.write,\n  \t\t    putStream = this.internal.putStream;\n\n  \t\timg['n'] = objectNumber;\n\n  \t\tout('<</Type /XObject');\n  \t\tout('/Subtype /Image');\n  \t\tout('/Width ' + img['w']);\n  \t\tout('/Height ' + img['h']);\n  \t\tif (img['cs'] === this.color_spaces.INDEXED) {\n  \t\t\tout('/ColorSpace [/Indexed /DeviceRGB '\n  \t\t\t// if an indexed png defines more than one colour with transparency, we've created a smask\n  \t\t\t+ (img['pal'].length / 3 - 1) + ' ' + ('smask' in img ? objectNumber + 2 : objectNumber + 1) + ' 0 R]');\n  \t\t} else {\n  \t\t\tout('/ColorSpace /' + img['cs']);\n  \t\t\tif (img['cs'] === this.color_spaces.DEVICE_CMYK) {\n  \t\t\t\tout('/Decode [1 0 1 0 1 0 1 0]');\n  \t\t\t}\n  \t\t}\n  \t\tout('/BitsPerComponent ' + img['bpc']);\n  \t\tif ('f' in img) {\n  \t\t\tout('/Filter /' + img['f']);\n  \t\t}\n  \t\tif ('dp' in img) {\n  \t\t\tout('/DecodeParms <<' + img['dp'] + '>>');\n  \t\t}\n  \t\tif ('trns' in img && img['trns'].constructor == Array) {\n  \t\t\tvar trns = '',\n  \t\t\t    i = 0,\n  \t\t\t    len = img['trns'].length;\n  \t\t\tfor (; i < len; i++) {\n  \t\t\t\ttrns += img['trns'][i] + ' ' + img['trns'][i] + ' ';\n  \t\t\t}out('/Mask [' + trns + ']');\n  \t\t}\n  \t\tif ('smask' in img) {\n  \t\t\tout('/SMask ' + (objectNumber + 1) + ' 0 R');\n  \t\t}\n  \t\tout('/Length ' + img['data'].length + '>>');\n\n  \t\tputStream(img['data']);\n\n  \t\tout('endobj');\n\n  \t\t// Soft mask\n  \t\tif ('smask' in img) {\n  \t\t\tvar dp = '/Predictor ' + img['p'] + ' /Colors 1 /BitsPerComponent ' + img['bpc'] + ' /Columns ' + img['w'];\n  \t\t\tvar smask = { 'w': img['w'], 'h': img['h'], 'cs': 'DeviceGray', 'bpc': img['bpc'], 'dp': dp, 'data': img['smask'] };\n  \t\t\tif ('f' in img) smask.f = img['f'];\n  \t\t\tputImage.call(this, smask);\n  \t\t}\n\n  \t\t//Palette\n  \t\tif (img['cs'] === this.color_spaces.INDEXED) {\n\n  \t\t\tthis.internal.newObject();\n  \t\t\t//out('<< /Filter / ' + img['f'] +' /Length ' + img['pal'].length + '>>');\n  \t\t\t//putStream(zlib.compress(img['pal']));\n  \t\t\tout('<< /Length ' + img['pal'].length + '>>');\n  \t\t\tputStream(this.arrayBufferToBinaryString(new Uint8Array(img['pal'])));\n  \t\t\tout('endobj');\n  \t\t}\n  \t},\n  \t    putResourcesCallback = function putResourcesCallback() {\n  \t\tvar images = this.internal.collections[namespace + 'images'];\n  \t\tfor (var i in images) {\n  \t\t\tputImage.call(this, images[i]);\n  \t\t}\n  \t},\n  \t    putXObjectsDictCallback = function putXObjectsDictCallback() {\n  \t\tvar images = this.internal.collections[namespace + 'images'],\n  \t\t    out = this.internal.write,\n  \t\t    image;\n  \t\tfor (var i in images) {\n  \t\t\timage = images[i];\n  \t\t\tout('/I' + image['i'], image['n'], '0', 'R');\n  \t\t}\n  \t},\n  \t    checkCompressValue = function checkCompressValue(value) {\n  \t\tif (value && typeof value === 'string') value = value.toUpperCase();\n  \t\treturn value in jsPDFAPI.image_compression ? value : jsPDFAPI.image_compression.NONE;\n  \t},\n  \t    getImages = function getImages() {\n  \t\tvar images = this.internal.collections[namespace + 'images'];\n  \t\t//first run, so initialise stuff\n  \t\tif (!images) {\n  \t\t\tthis.internal.collections[namespace + 'images'] = images = {};\n  \t\t\tthis.internal.events.subscribe('putResources', putResourcesCallback);\n  \t\t\tthis.internal.events.subscribe('putXobjectDict', putXObjectsDictCallback);\n  \t\t}\n\n  \t\treturn images;\n  \t},\n  \t    getImageIndex = function getImageIndex(images) {\n  \t\tvar imageIndex = 0;\n\n  \t\tif (images) {\n  \t\t\t// this is NOT the first time this method is ran on this instance of jsPDF object.\n  \t\t\timageIndex = Object.keys ? Object.keys(images).length : function (o) {\n  \t\t\t\tvar i = 0;\n  \t\t\t\tfor (var e in o) {\n  \t\t\t\t\tif (o.hasOwnProperty(e)) {\n  \t\t\t\t\t\ti++;\n  \t\t\t\t\t}\n  \t\t\t\t}\n  \t\t\t\treturn i;\n  \t\t\t}(images);\n  \t\t}\n\n  \t\treturn imageIndex;\n  \t},\n  \t    notDefined = function notDefined(value) {\n  \t\treturn typeof value === 'undefined' || value === null || value.length === 0;\n  \t},\n  \t    generateAliasFromData = function generateAliasFromData(data) {\n  \t\treturn typeof data === 'string' && jsPDFAPI.sHashCode(data);\n  \t},\n  \t    isImageTypeSupported = function isImageTypeSupported(type) {\n  \t\treturn typeof jsPDFAPI[\"process\" + type.toUpperCase()] === \"function\";\n  \t},\n  \t    isDOMElement = function isDOMElement(object) {\n  \t\treturn (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && object.nodeType === 1;\n  \t},\n  \t    createDataURIFromElement = function createDataURIFromElement(element, format) {\n\n  \t\t//if element is an image which uses data url definition, just return the dataurl\n  \t\tif (element.nodeName === 'IMG' && element.hasAttribute('src')) {\n  \t\t\tvar src = '' + element.getAttribute('src');\n  \t\t\tif (src.indexOf('data:image/') === 0) return src;\n\n  \t\t\t// only if the user doesn't care about a format\n  \t\t\tif (!format && /\\.png(?:[?#].*)?$/i.test(src)) format = 'png';\n  \t\t}\n\n  \t\tif (element.nodeName === 'CANVAS') {\n  \t\t\tvar canvas = element;\n  \t\t} else {\n  \t\t\tvar canvas = document.createElement('canvas');\n  \t\t\tcanvas.width = element.clientWidth || element.width;\n  \t\t\tcanvas.height = element.clientHeight || element.height;\n\n  \t\t\tvar ctx = canvas.getContext('2d');\n  \t\t\tif (!ctx) {\n  \t\t\t\tthrow 'addImage requires canvas to be supported by browser.';\n  \t\t\t}\n  \t\t\tctx.drawImage(element, 0, 0, canvas.width, canvas.height);\n  \t\t}\n  \t\treturn canvas.toDataURL(('' + format).toLowerCase() == 'png' ? 'image/png' : 'image/jpeg');\n  \t},\n  \t    checkImagesForAlias = function checkImagesForAlias(alias, images) {\n  \t\tvar cached_info;\n  \t\tif (images) {\n  \t\t\tfor (var e in images) {\n  \t\t\t\tif (alias === images[e].alias) {\n  \t\t\t\t\tcached_info = images[e];\n  \t\t\t\t\tbreak;\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n  \t\treturn cached_info;\n  \t},\n  \t    determineWidthAndHeight = function determineWidthAndHeight(w, h, info) {\n  \t\tif (!w && !h) {\n  \t\t\tw = -96;\n  \t\t\th = -96;\n  \t\t}\n  \t\tif (w < 0) {\n  \t\t\tw = -1 * info['w'] * 72 / w / this.internal.scaleFactor;\n  \t\t}\n  \t\tif (h < 0) {\n  \t\t\th = -1 * info['h'] * 72 / h / this.internal.scaleFactor;\n  \t\t}\n  \t\tif (w === 0) {\n  \t\t\tw = h * info['w'] / info['h'];\n  \t\t}\n  \t\tif (h === 0) {\n  \t\t\th = w * info['h'] / info['w'];\n  \t\t}\n\n  \t\treturn [w, h];\n  \t},\n  \t    writeImageToPDF = function writeImageToPDF(x, y, w, h, info, index, images, rotation) {\n  \t\tvar dims = determineWidthAndHeight.call(this, w, h, info),\n  \t\t    coord = this.internal.getCoordinateString,\n  \t\t    vcoord = this.internal.getVerticalCoordinateString;\n\n  \t\tw = dims[0];\n  \t\th = dims[1];\n\n  \t\timages[index] = info;\n\n  \t\tif (rotation) {\n  \t\t\trotation *= Math.PI / 180;\n  \t\t\tvar c = Math.cos(rotation);\n  \t\t\tvar s = Math.sin(rotation);\n  \t\t\t//like in pdf Reference do it 4 digits instead of 2\n  \t\t\tvar f4 = function f4(number) {\n  \t\t\t\treturn number.toFixed(4);\n  \t\t\t};\n  \t\t\tvar rotationTransformationMatrix = [f4(c), f4(s), f4(s * -1), f4(c), 0, 0, 'cm'];\n  \t\t}\n  \t\tthis.internal.write('q'); //Save graphics state\n  \t\tif (rotation) {\n  \t\t\tthis.internal.write([1, '0', '0', 1, coord(x), vcoord(y + h), 'cm'].join(' ')); //Translate\n  \t\t\tthis.internal.write(rotationTransformationMatrix.join(' ')); //Rotate\n  \t\t\tthis.internal.write([coord(w), '0', '0', coord(h), '0', '0', 'cm'].join(' ')); //Scale\n  \t\t} else {\n  \t\t\tthis.internal.write([coord(w), '0', '0', coord(h), coord(x), vcoord(y + h), 'cm'].join(' ')); //Translate and Scale\n  \t\t}\n  \t\tthis.internal.write('/I' + info['i'] + ' Do'); //Paint Image\n  \t\tthis.internal.write('Q'); //Restore graphics state\n  \t};\n\n  \t/**\n    * COLOR SPACES\n    */\n  \tjsPDFAPI.color_spaces = {\n  \t\tDEVICE_RGB: 'DeviceRGB',\n  \t\tDEVICE_GRAY: 'DeviceGray',\n  \t\tDEVICE_CMYK: 'DeviceCMYK',\n  \t\tCAL_GREY: 'CalGray',\n  \t\tCAL_RGB: 'CalRGB',\n  \t\tLAB: 'Lab',\n  \t\tICC_BASED: 'ICCBased',\n  \t\tINDEXED: 'Indexed',\n  \t\tPATTERN: 'Pattern',\n  \t\tSEPARATION: 'Separation',\n  \t\tDEVICE_N: 'DeviceN'\n  \t};\n\n  \t/**\n    * DECODE METHODS\n    */\n  \tjsPDFAPI.decode = {\n  \t\tDCT_DECODE: 'DCTDecode',\n  \t\tFLATE_DECODE: 'FlateDecode',\n  \t\tLZW_DECODE: 'LZWDecode',\n  \t\tJPX_DECODE: 'JPXDecode',\n  \t\tJBIG2_DECODE: 'JBIG2Decode',\n  \t\tASCII85_DECODE: 'ASCII85Decode',\n  \t\tASCII_HEX_DECODE: 'ASCIIHexDecode',\n  \t\tRUN_LENGTH_DECODE: 'RunLengthDecode',\n  \t\tCCITT_FAX_DECODE: 'CCITTFaxDecode'\n  \t};\n\n  \t/**\n    * IMAGE COMPRESSION TYPES\n    */\n  \tjsPDFAPI.image_compression = {\n  \t\tNONE: 'NONE',\n  \t\tFAST: 'FAST',\n  \t\tMEDIUM: 'MEDIUM',\n  \t\tSLOW: 'SLOW'\n  \t};\n\n  \tjsPDFAPI.sHashCode = function (str) {\n  \t\tstr = str || \"\";\n  \t\treturn Array.prototype.reduce && str.split(\"\").reduce(function (a, b) {\n  \t\t\ta = (a << 5) - a + b.charCodeAt(0);return a & a;\n  \t\t}, 0);\n  \t};\n\n  \tjsPDFAPI.isString = function (object) {\n  \t\treturn typeof object === 'string';\n  \t};\n  \t/**\n   * Validates if given String is a valid Base64-String\n   *\n   * @name validateStringAsBase64\n   * @public\n   * @function\n   * @param {String} possible Base64-String\n   * \n   * @returns {boolean}\n   * @methodOf jsPDF#\n   */\n  \tjsPDFAPI.validateStringAsBase64 = function (possibleBase64String) {\n  \t\tpossibleBase64String = possibleBase64String || '';\n\n  \t\tvar result = true;\n\n  \t\tif (possibleBase64String.length % 4 !== 0) {\n  \t\t\tresult = false;\n  \t\t}\n\n  \t\tif (/[A-Za-z0-9\\/]+/.test(possibleBase64String.substr(0, possibleBase64String.length - 2)) === false) {\n  \t\t\tresult = false;\n  \t\t}\n\n  \t\tif (/[A-Za-z0-9\\/][A-Za-z0-9+\\/]|[A-Za-z0-9+\\/]=|==/.test(possibleBase64String.substr(-2)) === false) {\n  \t\t\tresult = false;\n  \t\t}\n  \t\treturn result;\n  \t};\n\n  \t/**\n    * Strips out and returns info from a valid base64 data URI\n    * @param {String[dataURI]} a valid data URI of format 'data:[<MIME-type>][;base64],<data>'\n    * @returns an Array containing the following\n    * [0] the complete data URI\n    * [1] <MIME-type>\n    * [2] format - the second part of the mime-type i.e 'png' in 'image/png'\n    * [4] <data>\n    */\n  \tjsPDFAPI.extractInfoFromBase64DataURI = function (dataURI) {\n  \t\treturn (/^data:([\\w]+?\\/([\\w]+?));base64,(.+)$/g.exec(dataURI)\n  \t\t);\n  \t};\n\n  \t/**\n    * Check to see if ArrayBuffer is supported\n    * \n    * @returns {boolean}\n      * @methodOf jsPDF#\n    */\n  \tjsPDFAPI.supportsArrayBuffer = function () {\n  \t\treturn typeof ArrayBuffer !== 'undefined' && typeof Uint8Array !== 'undefined';\n  \t};\n\n  \t/**\n    * Tests supplied object to determine if ArrayBuffer\n    * @param {Object[object]}\n    * \n    * @returns {boolean}\n    * @methodOf jsPDF#\n    */\n  \tjsPDFAPI.isArrayBuffer = function (object) {\n  \t\tif (!this.supportsArrayBuffer()) return false;\n  \t\treturn object instanceof ArrayBuffer;\n  \t};\n\n  \t/**\n    * Tests supplied object to determine if it implements the ArrayBufferView (TypedArray) interface\n    * @param {Object[object]}\n    */\n  \tjsPDFAPI.isArrayBufferView = function (object) {\n  \t\tif (!this.supportsArrayBuffer()) return false;\n  \t\tif (typeof Uint32Array === 'undefined') return false;\n  \t\treturn object instanceof Int8Array || object instanceof Uint8Array || typeof Uint8ClampedArray !== 'undefined' && object instanceof Uint8ClampedArray || object instanceof Int16Array || object instanceof Uint16Array || object instanceof Int32Array || object instanceof Uint32Array || object instanceof Float32Array || object instanceof Float64Array;\n  \t};\n\n  \t/**\n   * Convert the Buffer to a Binary String\n   *\n   * @name binaryStringToUint8Array\n   * @public\n   * @function\n   * @param {ArrayBuffer} BinaryString with ImageData\n   * \n   * @returns {Uint8Array}\n   */\n  \tjsPDFAPI.binaryStringToUint8Array = function (binary_string) {\n  \t\t/*\n     * not sure how efficient this will be will bigger files. Is there a native method?\n     */\n  \t\tvar len = binary_string.length;\n  \t\tvar bytes = new Uint8Array(len);\n  \t\tfor (var i = 0; i < len; i++) {\n  \t\t\tbytes[i] = binary_string.charCodeAt(i);\n  \t\t}\n  \t\treturn bytes;\n  \t};\n\n  \t/**\n   * Convert the Buffer to a Binary String\n   *\n   * @name arrayBufferToBinaryString\n   * @public\n   * @function\n   * @param {ArrayBuffer} ArrayBuffer with ImageData\n   * \n   * @returns {String}\n   */\n  \tjsPDFAPI.arrayBufferToBinaryString = function (buffer) {\n\n  \t\tif (typeof atob === \"function\") {\n  \t\t\treturn atob(this.arrayBufferToBase64(buffer));\n  \t\t}\n\n  \t\tif (typeof TextDecoder === \"function\") {\n  \t\t\tvar decoder = new TextDecoder('ascii');\n  \t\t\t// test if the encoding is supported\n  \t\t\tif (decoder.encoding === 'ascii') {\n  \t\t\t\treturn decoder.decode(buffer);\n  \t\t\t}\n  \t\t}\n\n  \t\t//Fallback-solution\n  \t\tvar data = this.isArrayBuffer(buffer) ? buffer : new Uint8Array(buffer);\n  \t\tvar chunkSizeForSlice = 0x5000;\n  \t\tvar binary_string = '';\n  \t\tvar slicesCount = Math.ceil(data.byteLength / chunkSizeForSlice);\n  \t\tfor (var i = 0; i < slicesCount; i++) {\n  \t\t\tbinary_string += String.fromCharCode.apply(null, data.slice(i * chunkSizeForSlice, i * chunkSizeForSlice + chunkSizeForSlice));\n  \t\t}\n  \t\treturn binary_string;\n  \t};\n\n  \t/**\n      * Converts an ArrayBuffer directly to base64\n      *\n      * Taken from  http://jsperf.com/encoding-xhr-image-data/31\n      *\n      * Need to test if this is a better solution for larger files\n      *\n      * @name arrayBufferToBase64\n      * @public\n      * @function\n      * \n      * @returns {String}\n      */\n  \tjsPDFAPI.arrayBufferToBase64 = function (arrayBuffer) {\n  \t\tvar base64 = '';\n  \t\tvar encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n  \t\tvar bytes = new Uint8Array(arrayBuffer);\n  \t\tvar byteLength = bytes.byteLength;\n  \t\tvar byteRemainder = byteLength % 3;\n  \t\tvar mainLength = byteLength - byteRemainder;\n\n  \t\tvar a, b, c, d;\n  \t\tvar chunk;\n\n  \t\t// Main loop deals with bytes in chunks of 3\n  \t\tfor (var i = 0; i < mainLength; i = i + 3) {\n  \t\t\t// Combine the three bytes into a single integer\n  \t\t\tchunk = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];\n\n  \t\t\t// Use bitmasks to extract 6-bit segments from the triplet\n  \t\t\ta = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18\n  \t\t\tb = (chunk & 258048) >> 12; // 258048   = (2^6 - 1) << 12\n  \t\t\tc = (chunk & 4032) >> 6; // 4032     = (2^6 - 1) << 6\n  \t\t\td = chunk & 63; // 63       = 2^6 - 1\n\n  \t\t\t// Convert the raw binary segments to the appropriate ASCII encoding\n  \t\t\tbase64 += encodings[a] + encodings[b] + encodings[c] + encodings[d];\n  \t\t}\n\n  \t\t// Deal with the remaining bytes and padding\n  \t\tif (byteRemainder == 1) {\n  \t\t\tchunk = bytes[mainLength];\n\n  \t\t\ta = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2\n\n  \t\t\t// Set the 4 least significant bits to zero\n  \t\t\tb = (chunk & 3) << 4; // 3   = 2^2 - 1\n\n  \t\t\tbase64 += encodings[a] + encodings[b] + '==';\n  \t\t} else if (byteRemainder == 2) {\n  \t\t\tchunk = bytes[mainLength] << 8 | bytes[mainLength + 1];\n\n  \t\t\ta = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10\n  \t\t\tb = (chunk & 1008) >> 4; // 1008  = (2^6 - 1) << 4\n\n  \t\t\t// Set the 2 least significant bits to zero\n  \t\t\tc = (chunk & 15) << 2; // 15    = 2^4 - 1\n\n  \t\t\tbase64 += encodings[a] + encodings[b] + encodings[c] + '=';\n  \t\t}\n\n  \t\treturn base64;\n  \t};\n\n  \t/**\n      * Converts an ArrayBuffer directly to base64\n      *\n      * Taken from  http://jsperf.com/encoding-xhr-image-data/31\n      *\n      * Need to test if this is a better solution for larger files\n      *\n      * @public\n      * @function\n      * \n      * @returns {String}\n      */\n  \tjsPDFAPI.createImageInfo = function (data, wd, ht, cs, bpc, f, imageIndex, alias, dp, trns, pal, smask, p) {\n  \t\tvar info = {\n  \t\t\talias: alias,\n  \t\t\tw: wd,\n  \t\t\th: ht,\n  \t\t\tcs: cs,\n  \t\t\tbpc: bpc,\n  \t\t\ti: imageIndex,\n  \t\t\tdata: data\n  \t\t\t// n: objectNumber will be added by putImage code\n  \t\t};\n\n  \t\tif (f) info.f = f;\n  \t\tif (dp) info.dp = dp;\n  \t\tif (trns) info.trns = trns;\n  \t\tif (pal) info.pal = pal;\n  \t\tif (smask) info.smask = smask;\n  \t\tif (p) info.p = p; // predictor parameter for PNG compression\n\n  \t\treturn info;\n  \t};\n  \t/**\n   * Adds an Image to the PDF.\n   *\n   * @name addImage\n   * @public\n   * @function\n   * @param {String/Image-Element/Canvas-Element/Uint8Array} imageData as base64 encoded DataUrl or Image-HTMLElement or Canvas-HTMLElement\n   * @param {String} format of file if filetype-recognition fails, e.g. 'JPEG'\n   * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n   * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n   * @param {Number} width of the image (in units declared at inception of PDF document)\n   * @param {Number} height of the Image (in units declared at inception of PDF document)\n   * @param {String} alias of the image (if used multiple times)\n   * @param {String} compression of the generated JPEG, can have the values 'NONE', 'FAST', 'MEDIUM' and 'SLOW'\n   * @param {Number} rotation of the image in degrees (0-359)\n   * \n   * @returns jsPDF\n   * @methodOf jsPDF#\n   */\n  \tjsPDFAPI.addImage = function (imageData, format, x, y, w, h, alias, compression, rotation) {\n\n  \t\tvar tmpImageData = '';\n\n  \t\tif (typeof format !== 'string') {\n  \t\t\tvar tmp = h;\n  \t\t\th = w;\n  \t\t\tw = y;\n  \t\t\ty = x;\n  \t\t\tx = format;\n  \t\t\tformat = tmp;\n  \t\t}\n\n  \t\tif ((typeof imageData === 'undefined' ? 'undefined' : _typeof(imageData)) === 'object' && !isDOMElement(imageData) && \"imageData\" in imageData) {\n  \t\t\tvar options = imageData;\n\n  \t\t\timageData = options.imageData;\n  \t\t\tformat = options.format || format;\n  \t\t\tx = options.x || x || 0;\n  \t\t\ty = options.y || y || 0;\n  \t\t\tw = options.w || w;\n  \t\t\th = options.h || h;\n  \t\t\talias = options.alias || alias;\n  \t\t\tcompression = options.compression || compression;\n  \t\t\trotation = options.rotation || options.angle || rotation;\n  \t\t}\n\n  \t\tif (isNaN(x) || isNaN(y)) {\n  \t\t\tconsole.error('jsPDF.addImage: Invalid coordinates', arguments);\n  \t\t\tthrow new Error('Invalid coordinates passed to jsPDF.addImage');\n  \t\t}\n\n  \t\tvar images = getImages.call(this),\n  \t\t    info;\n\n  \t\tif (!(info = checkImagesForAlias(imageData, images))) {\n  \t\t\tvar dataAsBinaryString;\n\n  \t\t\tif (isDOMElement(imageData)) imageData = createDataURIFromElement(imageData, format);\n\n  \t\t\tif (notDefined(alias)) alias = generateAliasFromData(imageData);\n\n  \t\t\tif (!(info = checkImagesForAlias(alias, images))) {\n  \t\t\t\tif (this.isString(imageData)) {\n  \t\t\t\t\ttmpImageData = this.convertStringToImageData(imageData);\n\n  \t\t\t\t\tif (tmpImageData !== '') {\n  \t\t\t\t\t\timageData = tmpImageData;\n  \t\t\t\t\t} else {\n  \t\t\t\t\t\ttmpImageData = this.loadImageFile(imageData);\n  \t\t\t\t\t\tif (tmpImageData !== undefined) {\n  \t\t\t\t\t\t\timageData = tmpImageData;\n  \t\t\t\t\t\t}\n  \t\t\t\t\t}\n  \t\t\t\t}\n  \t\t\t\tformat = this.getImageFileTypeByImageData(imageData, format);\n\n  \t\t\t\tif (!isImageTypeSupported(format)) throw new Error('addImage does not support files of type \\'' + format + '\\', please ensure that a plugin for \\'' + format + '\\' support is added.');\n\n  \t\t\t\t/**\n       * need to test if it's more efficient to convert all binary strings\n       * to TypedArray - or should we just leave and process as string?\n       */\n  \t\t\t\tif (this.supportsArrayBuffer()) {\n  \t\t\t\t\t// no need to convert if imageData is already uint8array\n  \t\t\t\t\tif (!(imageData instanceof Uint8Array)) {\n  \t\t\t\t\t\tdataAsBinaryString = imageData;\n  \t\t\t\t\t\timageData = this.binaryStringToUint8Array(imageData);\n  \t\t\t\t\t}\n  \t\t\t\t}\n\n  \t\t\t\tinfo = this['process' + format.toUpperCase()](imageData, getImageIndex(images), alias, checkCompressValue(compression), dataAsBinaryString);\n\n  \t\t\t\tif (!info) throw new Error('An unkwown error occurred whilst processing the image');\n  \t\t\t}\n  \t\t}\n  \t\twriteImageToPDF.call(this, x, y, w, h, info, info.i, images, rotation);\n\n  \t\treturn this;\n  \t};\n\n  \tjsPDFAPI.convertStringToImageData = function (stringData) {\n  \t\tvar base64Info;\n  \t\tvar imageData = '';\n  \t\tif (this.isString(stringData)) {\n  \t\t\tvar base64Info = this.extractInfoFromBase64DataURI(stringData);\n\n  \t\t\tif (base64Info !== null) {\n  \t\t\t\tif (jsPDFAPI.validateStringAsBase64(base64Info[3])) {\n  \t\t\t\t\timageData = atob(base64Info[3]); //convert to binary string\n  \t\t\t\t}\n  \t\t\t} else if (jsPDFAPI.validateStringAsBase64(stringData)) {\n  \t\t\t\timageData = atob(stringData);\n  \t\t\t}\n  \t\t}\n  \t\treturn imageData;\n  \t};\n  \t/**\n    * JPEG SUPPORT\n    **/\n\n  \t//takes a string imgData containing the raw bytes of\n  \t//a jpeg image and returns [width, height]\n  \t//Algorithm from: http://www.64lines.com/jpeg-width-height\n  \tvar getJpegSize = function getJpegSize(imgData) {\n\n  \t\tvar width, height, numcomponents;\n  \t\t// Verify we have a valid jpeg header 0xff,0xd8,0xff,0xe0,?,?,'J','F','I','F',0x00\n  \t\tif (!imgData.charCodeAt(0) === 0xff || !imgData.charCodeAt(1) === 0xd8 || !imgData.charCodeAt(2) === 0xff || !imgData.charCodeAt(3) === 0xe0 || !imgData.charCodeAt(6) === 'J'.charCodeAt(0) || !imgData.charCodeAt(7) === 'F'.charCodeAt(0) || !imgData.charCodeAt(8) === 'I'.charCodeAt(0) || !imgData.charCodeAt(9) === 'F'.charCodeAt(0) || !imgData.charCodeAt(10) === 0x00) {\n  \t\t\tthrow new Error('getJpegSize requires a binary string jpeg file');\n  \t\t}\n  \t\tvar blockLength = imgData.charCodeAt(4) * 256 + imgData.charCodeAt(5);\n  \t\tvar i = 4,\n  \t\t    len = imgData.length;\n  \t\twhile (i < len) {\n  \t\t\ti += blockLength;\n  \t\t\tif (imgData.charCodeAt(i) !== 0xff) {\n  \t\t\t\tthrow new Error('getJpegSize could not find the size of the image');\n  \t\t\t}\n  \t\t\tif (imgData.charCodeAt(i + 1) === 0xc0 || //(SOF) Huffman  - Baseline DCT\n  \t\t\timgData.charCodeAt(i + 1) === 0xc1 || //(SOF) Huffman  - Extended sequential DCT\n  \t\t\timgData.charCodeAt(i + 1) === 0xc2 || // Progressive DCT (SOF2)\n  \t\t\timgData.charCodeAt(i + 1) === 0xc3 || // Spatial (sequential) lossless (SOF3)\n  \t\t\timgData.charCodeAt(i + 1) === 0xc4 || // Differential sequential DCT (SOF5)\n  \t\t\timgData.charCodeAt(i + 1) === 0xc5 || // Differential progressive DCT (SOF6)\n  \t\t\timgData.charCodeAt(i + 1) === 0xc6 || // Differential spatial (SOF7)\n  \t\t\timgData.charCodeAt(i + 1) === 0xc7) {\n  \t\t\t\theight = imgData.charCodeAt(i + 5) * 256 + imgData.charCodeAt(i + 6);\n  \t\t\t\twidth = imgData.charCodeAt(i + 7) * 256 + imgData.charCodeAt(i + 8);\n  \t\t\t\tnumcomponents = imgData.charCodeAt(i + 9);\n  \t\t\t\treturn [width, height, numcomponents];\n  \t\t\t} else {\n  \t\t\t\ti += 2;\n  \t\t\t\tblockLength = imgData.charCodeAt(i) * 256 + imgData.charCodeAt(i + 1);\n  \t\t\t}\n  \t\t}\n  \t},\n  \t    getJpegSizeFromBytes = function getJpegSizeFromBytes(data) {\n\n  \t\tvar hdr = data[0] << 8 | data[1];\n\n  \t\tif (hdr !== 0xFFD8) throw new Error('Supplied data is not a JPEG');\n\n  \t\tvar len = data.length,\n  \t\t    block = (data[4] << 8) + data[5],\n  \t\t    pos = 4,\n  \t\t    bytes,\n  \t\t    width,\n  \t\t    height,\n  \t\t    numcomponents;\n\n  \t\twhile (pos < len) {\n  \t\t\tpos += block;\n  \t\t\tbytes = readBytes(data, pos);\n  \t\t\tblock = (bytes[2] << 8) + bytes[3];\n  \t\t\tif ((bytes[1] === 0xC0 || bytes[1] === 0xC2) && bytes[0] === 0xFF && block > 7) {\n  \t\t\t\tbytes = readBytes(data, pos + 5);\n  \t\t\t\twidth = (bytes[2] << 8) + bytes[3];\n  \t\t\t\theight = (bytes[0] << 8) + bytes[1];\n  \t\t\t\tnumcomponents = bytes[4];\n  \t\t\t\treturn { width: width, height: height, numcomponents: numcomponents };\n  \t\t\t}\n\n  \t\t\tpos += 2;\n  \t\t}\n\n  \t\tthrow new Error('getJpegSizeFromBytes could not find the size of the image');\n  \t},\n  \t    readBytes = function readBytes(data, offset) {\n  \t\treturn data.subarray(offset, offset + 5);\n  \t};\n\n  \tjsPDFAPI.processJPEG = function (data, index, alias, compression, dataAsBinaryString, colorSpace) {\n\n  \t\tvar filter = this.decode.DCT_DECODE,\n  \t\t    bpc = 8,\n  \t\t    dims;\n\n  \t\tif (!this.isString(data) && !this.isArrayBuffer(data) && !this.isArrayBufferView(data)) {\n  \t\t\treturn null;\n  \t\t}\n\n  \t\tif (this.isString(data)) {\n  \t\t\tdims = getJpegSize(data);\n  \t\t}\n\n  \t\tif (this.isArrayBuffer(data)) {\n  \t\t\tdata = new Uint8Array(data);\n  \t\t}\n  \t\tif (this.isArrayBufferView(data)) {\n\n  \t\t\tdims = getJpegSizeFromBytes(data);\n\n  \t\t\t// if we already have a stored binary string rep use that\n  \t\t\tdata = dataAsBinaryString || this.arrayBufferToBinaryString(data);\n  \t\t}\n\n  \t\tif (colorSpace === undefined) {\n  \t\t\tswitch (dims.numcomponents) {\n  \t\t\t\tcase 1:\n  \t\t\t\t\tcolorSpace = this.color_spaces.DEVICE_GRAY;\n  \t\t\t\t\tbreak;\n  \t\t\t\tcase 4:\n  \t\t\t\t\tcolorSpace = this.color_spaces.DEVICE_CMYK;\n  \t\t\t\t\tbreak;\n  \t\t\t\tdefault:\n  \t\t\t\tcase 3:\n  \t\t\t\t\tcolorSpace = this.color_spaces.DEVICE_RGB;\n  \t\t\t\t\tbreak;\n  \t\t\t}\n  \t\t}\n\n  \t\treturn this.createImageInfo(data, dims.width, dims.height, colorSpace, bpc, filter, index, alias);\n  \t};\n\n  \tjsPDFAPI.processJPG = function () /*data, index, alias, compression, dataAsBinaryString*/{\n  \t\treturn this.processJPEG.apply(this, arguments);\n  \t};\n\n  \tjsPDFAPI.loadImageFile = function (path, sync, callback) {\n  \t\tsync = sync || true;\n  \t\tcallback = callback || function () {};\n  \t\tvar isNode = Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';\n\n  \t\tvar xhrMethod = function xhrMethod(url, sync, callback) {\n  \t\t\tvar req = new XMLHttpRequest();\n  \t\t\tvar byteArray = [];\n  \t\t\tvar i = 0;\n\n  \t\t\tvar sanitizeUnicode = function sanitizeUnicode(data) {\n  \t\t\t\tvar dataLength = data.length;\n  \t\t\t\tvar StringFromCharCode = String.fromCharCode;\n\n  \t\t\t\t//Transform Unicode to ASCII\n  \t\t\t\tfor (i = 0; i < dataLength; i += 1) {\n  \t\t\t\t\tbyteArray.push(StringFromCharCode(data.charCodeAt(i) & 0xff));\n  \t\t\t\t}\n  \t\t\t\treturn byteArray.join(\"\");\n  \t\t\t};\n\n  \t\t\treq.open('GET', url, !sync);\n  \t\t\t// XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]\n  \t\t\treq.overrideMimeType('text\\/plain; charset=x-user-defined');\n\n  \t\t\tif (sync === false) {\n  \t\t\t\treq.onload = function () {\n  \t\t\t\t\treturn sanitizeUnicode(this.responseText);\n  \t\t\t\t};\n  \t\t\t}\n  \t\t\treq.send(null);\n\n  \t\t\tif (req.status !== 200) {\n  \t\t\t\tconsole.warn('Unable to load file \"' + url + '\"');\n  \t\t\t\treturn;\n  \t\t\t}\n\n  \t\t\tif (sync) {\n  \t\t\t\treturn sanitizeUnicode(req.responseText);\n  \t\t\t}\n  \t\t};\n\n  \t\t//we have a browser and probably no CORS-Problem\n  \t\tif ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) !== undefined && (typeof location === 'undefined' ? 'undefined' : _typeof(location)) === \"object\" && location.protocol.substr(0, 4) === \"http\") {\n  \t\t\treturn xhrMethod(path, sync, callback);\n  \t\t}\n  \t};\n\n  \tjsPDFAPI.getImageProperties = function (imageData) {\n  \t\tvar info;\n  \t\tvar tmpImageData = '';\n  \t\tvar format;\n\n  \t\tif (isDOMElement(imageData)) {\n  \t\t\timageData = createDataURIFromElement(imageData);\n  \t\t}\n\n  \t\tif (this.isString(imageData)) {\n  \t\t\ttmpImageData = this.convertStringToImageData(imageData);\n\n  \t\t\tif (tmpImageData !== '') {\n  \t\t\t\timageData = tmpImageData;\n  \t\t\t} else {\n  \t\t\t\ttmpImageData = this.loadImageFile(imageData);\n  \t\t\t\tif (tmpImageData !== undefined) {\n  \t\t\t\t\timageData = tmpImageData;\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n  \t\tformat = this.getImageFileTypeByImageData(imageData);\n\n  \t\tif (!isImageTypeSupported(format)) throw new Error('addImage does not support files of type \\'' + format + '\\', please ensure that a plugin for \\'' + format + '\\' support is added.');\n\n  \t\t/**\n     * need to test if it's more efficient to convert all binary strings\n     * to TypedArray - or should we just leave and process as string?\n     */\n  \t\tif (this.supportsArrayBuffer()) {\n  \t\t\t// no need to convert if imageData is already uint8array\n  \t\t\tif (!(imageData instanceof Uint8Array)) {\n  \t\t\t\timageData = this.binaryStringToUint8Array(imageData);\n  \t\t\t}\n  \t\t}\n\n  \t\tinfo = this['process' + format.toUpperCase()](imageData);\n\n  \t\tif (!info) {\n  \t\t\tthrow new Error('An unkwown error occurred whilst processing the image');\n  \t\t}\n\n  \t\treturn {\n  \t\t\tfileType: format,\n  \t\t\twidth: info.w,\n  \t\t\theight: info.h,\n  \t\t\tcolorSpace: info.cs,\n  \t\t\tcompressionMode: info.f,\n  \t\t\tbitsPerComponent: info.bpc\n  \t\t};\n  \t};\n  })(jsPDF.API);\n\n  /**\n   * jsPDF Annotations PlugIn\n   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n\n  /**\n   * There are many types of annotations in a PDF document. Annotations are placed\n   * on a page at a particular location. They are not 'attached' to an object.\n   * <br />\n   * This plugin current supports <br />\n   * <li> Goto Page (set pageNumber and top in options)\n   * <li> Goto Name (set name and top in options)\n   * <li> Goto URL (set url in options)\n   * <p>\n   * \tThe destination magnification factor can also be specified when goto is a page number or a named destination. (see documentation below)\n   *  (set magFactor in options).  XYZ is the default.\n   * </p>\n   * <p>\n   *  Links, Text, Popup, and FreeText are supported.\n   * </p>\n   * <p>\n   * Options In PDF spec Not Implemented Yet\n   * <li> link border\n   * <li> named target\n   * <li> page coordinates\n   * <li> destination page scaling and layout\n   * <li> actions other than URL and GotoPage\n   * <li> background / hover actions\n   * </p>\n   */\n\n  /*\n      Destination Magnification Factors\n      See PDF 1.3 Page 386 for meanings and options\n\n      [supported]\n  \tXYZ (options; left top zoom)\n  \tFit (no options)\n  \tFitH (options: top)\n  \tFitV (options: left)\n\n  \t[not supported]\n  \tFitR\n  \tFitB\n  \tFitBH\n  \tFitBV\n   */\n\n  (function (jsPDFAPI) {\n\n  \tvar annotationPlugin = {\n\n  \t\t/**\n     * An array of arrays, indexed by <em>pageNumber</em>.\n     */\n  \t\tannotations: [],\n\n  \t\tf2: function f2(number) {\n  \t\t\treturn number.toFixed(2);\n  \t\t},\n\n  \t\tnotEmpty: function notEmpty(obj) {\n  \t\t\tif (typeof obj != 'undefined') {\n  \t\t\t\tif (obj != '') {\n  \t\t\t\t\treturn true;\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n  \t};\n\n  \tjsPDF.API.annotationPlugin = annotationPlugin;\n\n  \tjsPDF.API.events.push(['addPage', function (info) {\n  \t\tthis.annotationPlugin.annotations[info.pageNumber] = [];\n  \t}]);\n\n  \tjsPDFAPI.events.push(['putPage', function (info) {\n  \t\t//TODO store annotations in pageContext so reorder/remove will not affect them.\n  \t\tvar pageAnnos = this.annotationPlugin.annotations[info.pageNumber];\n\n  \t\tvar found = false;\n  \t\tfor (var a = 0; a < pageAnnos.length && !found; a++) {\n  \t\t\tvar anno = pageAnnos[a];\n  \t\t\tswitch (anno.type) {\n  \t\t\t\tcase 'link':\n  \t\t\t\t\tif (annotationPlugin.notEmpty(anno.options.url) || annotationPlugin.notEmpty(anno.options.pageNumber)) {\n  \t\t\t\t\t\tfound = true;\n  \t\t\t\t\t\tbreak;\n  \t\t\t\t\t}\n  \t\t\t\tcase 'reference':\n  \t\t\t\tcase 'text':\n  \t\t\t\tcase 'freetext':\n  \t\t\t\t\tfound = true;\n  \t\t\t\t\tbreak;\n  \t\t\t}\n  \t\t}\n  \t\tif (found == false) {\n  \t\t\treturn;\n  \t\t}\n\n  \t\tthis.internal.write(\"/Annots [\");\n  \t\tvar f2 = this.annotationPlugin.f2;\n  \t\tvar k = this.internal.scaleFactor;\n  \t\tvar pageHeight = this.internal.pageSize.getHeight();\n  \t\tvar pageInfo = this.internal.getPageInfo(info.pageNumber);\n  \t\tfor (var a = 0; a < pageAnnos.length; a++) {\n  \t\t\tvar anno = pageAnnos[a];\n\n  \t\t\tswitch (anno.type) {\n  \t\t\t\tcase 'reference':\n  \t\t\t\t\t// References to Widget Anotations (for AcroForm Fields)\n  \t\t\t\t\tthis.internal.write(' ' + anno.object.objId + ' 0 R ');\n  \t\t\t\t\tbreak;\n  \t\t\t\tcase 'text':\n  \t\t\t\t\t// Create a an object for both the text and the popup\n  \t\t\t\t\tvar objText = this.internal.newAdditionalObject();\n  \t\t\t\t\tvar objPopup = this.internal.newAdditionalObject();\n\n  \t\t\t\t\tvar title = anno.title || 'Note';\n  \t\t\t\t\tvar rect = \"/Rect [\" + f2(anno.bounds.x * k) + \" \" + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + \" \" + f2((anno.bounds.x + anno.bounds.w) * k) + \" \" + f2((pageHeight - anno.bounds.y) * k) + \"] \";\n  \t\t\t\t\tline = '<</Type /Annot /Subtype /' + 'Text' + ' ' + rect + '/Contents (' + anno.contents + ')';\n  \t\t\t\t\tline += ' /Popup ' + objPopup.objId + \" 0 R\";\n  \t\t\t\t\tline += ' /P ' + pageInfo.objId + \" 0 R\";\n  \t\t\t\t\tline += ' /T (' + title + ') >>';\n  \t\t\t\t\tobjText.content = line;\n\n  \t\t\t\t\tvar parent = objText.objId + ' 0 R';\n  \t\t\t\t\tvar popoff = 30;\n  \t\t\t\t\tvar rect = \"/Rect [\" + f2((anno.bounds.x + popoff) * k) + \" \" + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + \" \" + f2((anno.bounds.x + anno.bounds.w + popoff) * k) + \" \" + f2((pageHeight - anno.bounds.y) * k) + \"] \";\n  \t\t\t\t\t//var rect2 = \"/Rect [\" + f2(anno.bounds.x * k) + \" \" + f2((pageHeight - anno.bounds.y) * k) + \" \" + f2(anno.bounds.x + anno.bounds.w * k) + \" \" + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + \"] \";\n  \t\t\t\t\tline = '<</Type /Annot /Subtype /' + 'Popup' + ' ' + rect + ' /Parent ' + parent;\n  \t\t\t\t\tif (anno.open) {\n  \t\t\t\t\t\tline += ' /Open true';\n  \t\t\t\t\t}\n  \t\t\t\t\tline += ' >>';\n  \t\t\t\t\tobjPopup.content = line;\n\n  \t\t\t\t\tthis.internal.write(objText.objId, '0 R', objPopup.objId, '0 R');\n\n  \t\t\t\t\tbreak;\n  \t\t\t\tcase 'freetext':\n  \t\t\t\t\tvar rect = \"/Rect [\" + f2(anno.bounds.x * k) + \" \" + f2((pageHeight - anno.bounds.y) * k) + \" \" + f2(anno.bounds.x + anno.bounds.w * k) + \" \" + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + \"] \";\n  \t\t\t\t\tvar color = anno.color || '#000000';\n  \t\t\t\t\tline = '<</Type /Annot /Subtype /' + 'FreeText' + ' ' + rect + '/Contents (' + anno.contents + ')';\n  \t\t\t\t\tline += ' /DS(font: Helvetica,sans-serif 12.0pt; text-align:left; color:#' + color + ')';\n  \t\t\t\t\tline += ' /Border [0 0 0]';\n  \t\t\t\t\tline += ' >>';\n  \t\t\t\t\tthis.internal.write(line);\n  \t\t\t\t\tbreak;\n  \t\t\t\tcase 'link':\n  \t\t\t\t\tif (anno.options.name) {\n  \t\t\t\t\t\tvar loc = this.annotations._nameMap[anno.options.name];\n  \t\t\t\t\t\tanno.options.pageNumber = loc.page;\n  \t\t\t\t\t\tanno.options.top = loc.y;\n  \t\t\t\t\t} else {\n  \t\t\t\t\t\tif (!anno.options.top) {\n  \t\t\t\t\t\t\tanno.options.top = 0;\n  \t\t\t\t\t\t}\n  \t\t\t\t\t}\n\n  \t\t\t\t\tvar rect = \"/Rect [\" + f2(anno.x * k) + \" \" + f2((pageHeight - anno.y) * k) + \" \" + f2((anno.x + anno.w) * k) + \" \" + f2((pageHeight - (anno.y + anno.h)) * k) + \"] \";\n\n  \t\t\t\t\tvar line = '';\n  \t\t\t\t\tif (anno.options.url) {\n  \t\t\t\t\t\tline = '<</Type /Annot /Subtype /Link ' + rect + '/Border [0 0 0] /A <</S /URI /URI (' + anno.options.url + ') >>';\n  \t\t\t\t\t} else if (anno.options.pageNumber) {\n  \t\t\t\t\t\t// first page is 0\n  \t\t\t\t\t\tvar info = this.internal.getPageInfo(anno.options.pageNumber);\n  \t\t\t\t\t\tline = '<</Type /Annot /Subtype /Link ' + rect + '/Border [0 0 0] /Dest [' + info.objId + \" 0 R\";\n  \t\t\t\t\t\tanno.options.magFactor = anno.options.magFactor || \"XYZ\";\n  \t\t\t\t\t\tswitch (anno.options.magFactor) {\n  \t\t\t\t\t\t\tcase 'Fit':\n  \t\t\t\t\t\t\t\tline += ' /Fit]';\n  \t\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\t\tcase 'FitH':\n  \t\t\t\t\t\t\t\t//anno.options.top = anno.options.top || f2(pageHeight * k);\n  \t\t\t\t\t\t\t\tline += ' /FitH ' + anno.options.top + ']';\n  \t\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\t\tcase 'FitV':\n  \t\t\t\t\t\t\t\tanno.options.left = anno.options.left || 0;\n  \t\t\t\t\t\t\t\tline += ' /FitV ' + anno.options.left + ']';\n  \t\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\t\tcase 'XYZ':\n  \t\t\t\t\t\t\tdefault:\n  \t\t\t\t\t\t\t\tvar top = f2((pageHeight - anno.options.top) * k); // || f2(pageHeight * k);\n  \t\t\t\t\t\t\t\tanno.options.left = anno.options.left || 0;\n  \t\t\t\t\t\t\t\t// 0 or null zoom will not change zoom factor\n  \t\t\t\t\t\t\t\tif (typeof anno.options.zoom === 'undefined') {\n  \t\t\t\t\t\t\t\t\tanno.options.zoom = 0;\n  \t\t\t\t\t\t\t\t}\n  \t\t\t\t\t\t\t\tline += ' /XYZ ' + anno.options.left + ' ' + top + ' ' + anno.options.zoom + ']';\n  \t\t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\t}\n  \t\t\t\t\t}\n  \t\t\t\t\tif (line != '') {\n  \t\t\t\t\t\tline += \" >>\";\n  \t\t\t\t\t\tthis.internal.write(line);\n  \t\t\t\t\t}\n  \t\t\t\t\tbreak;\n  \t\t\t}\n  \t\t}\n  \t\tthis.internal.write(\"]\");\n  \t}]);\n\n  \tjsPDFAPI.createAnnotation = function (options) {\n  \t\tswitch (options.type) {\n  \t\t\tcase 'link':\n  \t\t\t\tthis.link(options.bounds.x, options.bounds.y, options.bounds.w, options.bounds.h, options);\n  \t\t\t\tbreak;\n  \t\t\tcase 'text':\n  \t\t\tcase 'freetext':\n  \t\t\t\tthis.annotationPlugin.annotations[this.internal.getCurrentPageInfo().pageNumber].push(options);\n  \t\t\t\tbreak;\n  \t\t}\n  \t};\n\n  \t/**\n    * valid options\n    * <li> pageNumber or url [required]\n    * <p>If pageNumber is specified, top and zoom may also be specified</p>\n    */\n  \tjsPDFAPI.link = function (x, y, w, h, options) {\n\n  \t\tthis.annotationPlugin.annotations[this.internal.getCurrentPageInfo().pageNumber].push({\n  \t\t\tx: x,\n  \t\t\ty: y,\n  \t\t\tw: w,\n  \t\t\th: h,\n  \t\t\toptions: options,\n  \t\t\ttype: 'link'\n  \t\t});\n  \t};\n\n  \t/**\n    * Currently only supports single line text.\n    * Returns the width of the text/link\n    */\n  \tjsPDFAPI.textWithLink = function (text, x, y, options) {\n\n  \t\tvar width = this.getTextWidth(text);\n  \t\tvar height = this.internal.getLineHeight() / this.internal.scaleFactor;\n  \t\tthis.text(text, x, y);\n  \t\t//TODO We really need the text baseline height to do this correctly.\n  \t\t// Or ability to draw text on top, bottom, center, or baseline.\n  \t\ty += height * .2;\n  \t\tthis.link(x, y - height, width, height, options);\n  \t\treturn width;\n  \t};\n\n  \t//TODO move into external library\n  \tjsPDFAPI.getTextWidth = function (text) {\n\n  \t\tvar fontSize = this.internal.getFontSize();\n  \t\tvar txtWidth = this.getStringUnitWidth(text) * fontSize / this.internal.scaleFactor;\n  \t\treturn txtWidth;\n  \t};\n\n  \t//TODO move into external library\n  \tjsPDFAPI.getLineHeight = function () {\n  \t\treturn this.internal.getLineHeight();\n  \t};\n\n  \treturn this;\n  })(jsPDF.API);\n\n  (function (jsPDFAPI) {\n\n      var arLangCodes = {\n          \"ar\": \"Arabic (Standard)\",\n          \"ar-DZ\": \"Arabic (Algeria)\",\n          \"ar-BH\": \"Arabic (Bahrain)\",\n          \"ar-EG\": \"Arabic (Egypt)\",\n          \"ar-IQ\": \"Arabic (Iraq)\",\n          \"ar-JO\": \"Arabic (Jordan)\",\n          \"ar-KW\": \"Arabic (Kuwait)\",\n          \"ar-LB\": \"Arabic (Lebanon)\",\n          \"ar-LY\": \"Arabic (Libya)\",\n          \"ar-MA\": \"Arabic (Morocco)\",\n          \"ar-OM\": \"Arabic (Oman)\",\n          \"ar-QA\": \"Arabic (Qatar)\",\n          \"ar-SA\": \"Arabic (Saudi Arabia)\",\n          \"ar-SY\": \"Arabic (Syria)\",\n          \"ar-TN\": \"Arabic (Tunisia)\",\n          \"ar-AE\": \"Arabic (U.A.E.)\",\n          \"ar-YE\": \"Arabic (Yemen)\",\n          \"fa\": \"Persian\",\n          \"fa-IR\": \"Persian/Iran\",\n          \"ur\": \"Urdu\"\n      };\n\n      var arLangCodesKeys = Object.keys(arLangCodes);\n\n      /**\n       * Arabic shape substitutions: char code => (isolated, final, initial, medial).\n       */\n      var arabicSubst = {\n          1569: [65152],\n          1570: [65153, 65154, 65153, 65154],\n          1571: [65155, 65156, 65155, 65156],\n          1572: [65157, 65158],\n          1573: [65159, 65160, 65159, 65160],\n          1574: [65161, 65162, 65163, 65164],\n          1575: [65165, 65166, 65165, 65166],\n          1576: [65167, 65168, 65169, 65170],\n          1577: [65171, 65172],\n          1578: [65173, 65174, 65175, 65176],\n          1579: [65177, 65178, 65179, 65180],\n          1580: [65181, 65182, 65183, 65184],\n          1581: [65185, 65186, 65187, 65188],\n          1582: [65189, 65190, 65191, 65192],\n          1583: [65193, 65194, 65193],\n          1584: [65195, 65196, 65195],\n          1585: [65197, 65198, 65197],\n          1586: [65199, 65200, 65199],\n          1587: [65201, 65202, 65203, 65204],\n          1588: [65205, 65206, 65207, 65208],\n          1589: [65209, 65210, 65211, 65212],\n          1590: [65213, 65214, 65215, 65216],\n          1591: [65217, 65218, 65219, 65220],\n          1592: [65221, 65222, 65223, 65224],\n          1593: [65225, 65226, 65227, 65228],\n          1594: [65229, 65230, 65231, 65232],\n          1601: [65233, 65234, 65235, 65236],\n          1602: [65237, 65238, 65239, 65240],\n          1603: [65241, 65242, 65243, 65244],\n          1604: [65245, 65246, 65247, 65248],\n          1605: [65249, 65250, 65251, 65252],\n          1606: [65253, 65254, 65255, 65256],\n          1607: [65257, 65258, 65259, 65260],\n          1608: [65261, 65262, 65261],\n          1609: [65263, 65264, 64488, 64489],\n          1610: [65265, 65266, 65267, 65268],\n          1649: [64336, 64337],\n          1655: [64477],\n          1657: [64358, 64359, 64360, 64361],\n          1658: [64350, 64351, 64352, 64353],\n          1659: [64338, 64339, 64340, 64341],\n          1662: [64342, 64343, 64344, 64345],\n          1663: [64354, 64355, 64356, 64357],\n          1664: [64346, 64347, 64348, 64349],\n          1667: [64374, 64375, 64376, 64377],\n          1668: [64370, 64371, 64372, 64373],\n          1670: [64378, 64379, 64380, 64381],\n          1671: [64382, 64383, 64384, 64385],\n          1672: [64392, 64393],\n          1676: [64388, 64389],\n          1677: [64386, 64387],\n          1678: [64390, 64391],\n          1681: [64396, 64397],\n          1688: [64394, 64395, 64394],\n          1700: [64362, 64363, 64364, 64365],\n          1702: [64366, 64367, 64368, 64369],\n          1705: [64398, 64399, 64400, 64401],\n          1709: [64467, 64468, 64469, 64470],\n          1711: [64402, 64403, 64404, 64405],\n          1713: [64410, 64411, 64412, 64413],\n          1715: [64406, 64407, 64408, 64409],\n          1722: [64414, 64415],\n          1723: [64416, 64417, 64418, 64419],\n          1726: [64426, 64427, 64428, 64429],\n          1728: [64420, 64421],\n          1729: [64422, 64423, 64424, 64425],\n          1733: [64480, 64481],\n          1734: [64473, 64474],\n          1735: [64471, 64472],\n          1736: [64475, 64476],\n          1737: [64482, 64483],\n          1739: [64478, 64479],\n          1740: [64508, 64509, 64510, 64511],\n          1744: [64484, 64485, 64486, 64487],\n          1746: [64430, 64431],\n          1747: [64432, 64433]\n      };\n      var arabiclaasubst = {\n          1570: [65269, 65270, 65269, 65270],\n          1571: [65271, 65272, 65271, 65272],\n          1573: [65273, 65274, 65273, 65274],\n          1575: [65275, 65276, 65275, 65276]\n      };\n      var arabicorigsubst = {\n          1570: [65153, 65154, 65153, 65154],\n          1571: [65155, 65156, 65155, 65156],\n          1573: [65159, 65160, 65159, 65160],\n          1575: [65165, 65166, 65165, 65166]\n      };\n      var arabic_diacritics = {\n          1612: 64606, // Shadda + Dammatan\n          1613: 64607, // Shadda + Kasratan\n          1614: 64608, // Shadda + Fatha\n          1615: 64609, // Shadda + Damma\n          1616: 64610 // Shadda + Kasra\n      };\n\n      var alfletter = [1570, 1571, 1573, 1575];\n      var endedletter = [1569, 1570, 1571, 1572, 1573, 1575, 1577, 1583, 1584, 1585, 1586, 1608, 1688];\n\n      var isolatedForm = 0;\n      var finalForm = 1;\n      var initialForm = 2;\n      var medialForm = 3;\n\n      //private\n      function isArabicLetter(letter) {\n          return letter !== undefined && arabicSubst[letter.charCodeAt(0)] !== undefined;\n      }\n\n      function isArabicEndLetter(letter) {\n          return letter !== undefined && endedletter.indexOf(letter.charCodeAt(0)) >= 0;\n      }\n\n      function isArabicAlfLetter(letter) {\n          return letter !== undefined && alfletter.indexOf(letter.charCodeAt(0)) >= 0;\n      }\n\n      function arabicLetterHasFinalForm(letter) {\n          return isArabicLetter(letter) && arabicSubst[letter.charCodeAt(0)].length >= 2;\n      }\n\n      function arabicLetterHasMedialForm(letter) {\n          return isArabicLetter(letter) && arabicSubst[letter.charCodeAt(0)].length == 4;\n      }\n\n      function isArabicDiacritic(letter) {\n          return letter !== undefined && arabic_diacritics[letter.charCodeAt(0)] !== undefined;\n      }\n\n      function getCorrectForm(currentChar, beforeChar, nextChar, arabicSubstition) {\n          if (!isArabicLetter(currentChar)) {\n              return -1;\n          }\n\n          arabicSubstition = arabicSubstition || {};\n          arabicSubst = Object.assign(arabicSubst, arabicSubstition);\n\n          if (!arabicLetterHasFinalForm(currentChar) || !isArabicLetter(beforeChar) && !isArabicLetter(nextChar) || !isArabicLetter(nextChar) && isArabicEndLetter(beforeChar) || isArabicEndLetter(currentChar) && !isArabicLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicAlfLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicEndLetter(beforeChar)) {\n              arabicSubst = Object.assign(arabicSubst, arabicorigsubst);\n              return isolatedForm;\n          }\n\n          if (arabicLetterHasMedialForm(currentChar) && isArabicLetter(beforeChar) && !isArabicEndLetter(beforeChar) && isArabicLetter(nextChar) && arabicLetterHasFinalForm(nextChar)) {\n              arabicSubst = Object.assign(arabicSubst, arabicorigsubst);\n              return medialForm;\n          }\n\n          if (isArabicEndLetter(currentChar) || !isArabicLetter(nextChar)) {\n              arabicSubst = Object.assign(arabicSubst, arabicorigsubst);\n              return finalForm;\n          }\n\n          arabicSubst = Object.assign(arabicSubst, arabicorigsubst);\n          return initialForm;\n      }\n\n      var commonSubstition = function commonSubstition(character) {\n          var replacementTable = {\n              '(': ')',\n              ')': '('\n          };\n          return replacementTable[character] || character;\n      };\n\n      var processArabic = jsPDFAPI.processArabic = function (text, reverse) {\n          text = text || \"\";\n          reverse = reverse || false;\n\n          var result = \"\";\n          var i = 0;\n          var position = 0;\n          var currentLetter = \"\";\n          var prevLetter = \"\";\n          var nextLetter = \"\";\n          var resultingLetter;\n\n          var localPrevLetter;\n          var localCurrentLetter;\n          var localNextLetter;\n\n          for (i = 0; i < text.length; i += 1) {\n              currentLetter = text[i];\n              prevLetter = text[i - 1];\n              nextLetter = text[i + 1];\n              if (!isArabicLetter(currentLetter)) {\n                  result += reverse ? commonSubstition(currentLetter) : currentLetter;\n              } else {\n                  if (prevLetter !== undefined && prevLetter.charCodeAt(0) === 1604 && isArabicAlfLetter(currentLetter)) {\n                      localPrevLetter = text[i - 2];\n                      localCurrentLetter = currentLetter;\n                      localNextLetter = text[i + 1];\n                      position = getCorrectForm(localCurrentLetter, localPrevLetter, localNextLetter, arabiclaasubst);\n                      resultingLetter = String.fromCharCode(arabiclaasubst[currentLetter.charCodeAt(0)][position]);\n                      result = result.substr(0, result.length - 1) + resultingLetter;\n                  } else if (prevLetter !== undefined && prevLetter.charCodeAt(0) === 1617 && isArabicDiacritic(currentLetter)) {\n                      localPrevLetter = text[i - 2];\n                      localCurrentLetter = currentLetter;\n                      localNextLetter = text[i + 1];\n                      position = getCorrectForm(localCurrentLetter, localPrevLetter, localNextLetter, arabicorigsubst);\n                      resultingLetter = String.fromCharCode(arabic_diacritics[currentLetter.charCodeAt(0)][position]);\n                      result = result.substr(0, result.length - 1) + resultingLetter;\n                  } else {\n                      position = getCorrectForm(currentLetter, prevLetter, nextLetter, arabicorigsubst);\n                      result += String.fromCharCode(arabicSubst[currentLetter.charCodeAt(0)][position]);\n                  }\n              }\n          }\n          return reverse ? result.split(\"\").reverse().join(\"\") : result;\n      };\n\n      var arabicParserFunction = function arabicParserFunction(args) {\n          var text = args.text;\n          var x = args.x;\n          var y = args.y;\n          var options = args.options || {};\n          var mutex = args.mutex || {};\n          var lang = options.lang;\n          var tmpText = [];\n\n          if (arLangCodesKeys.indexOf(lang) >= 0) {\n              if (Object.prototype.toString.call(text) === '[object Array]') {\n                  var i = 0;\n                  tmpText = [];\n                  for (i = 0; i < text.length; i += 1) {\n                      if (Object.prototype.toString.call(text[i]) === '[object Array]') {\n                          tmpText.push([processArabic(text[i][0], true), text[i][1], text[i][2]]);\n                      } else {\n                          tmpText.push([processArabic(text[i], true)]);\n                      }\n                  }\n                  args.text = tmpText;\n              } else {\n                  args.text = processArabic(text, true);\n              }\n              //force charSpace if not given.\n              if (options.charSpace === undefined) {\n                  args.options.charSpace = 0;\n              }\n              //if R2L is true, set it false.\n              if (options.R2L === true) {\n                  args.options.R2L = false;\n              }\n          }\n      };\n\n      jsPDFAPI.events.push(['preProcessText', arabicParserFunction]);\n  })(jsPDF.API);\n\n  /**\n   * jsPDF Autoprint Plugin\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n\n  /**\n  * Makes the PDF automatically print. This works in Chrome, Firefox, Acrobat\n  * Reader.\n  *\n  * @returns {jsPDF}\n  * @name autoPrint\n  * @example\n  * var doc = new jsPDF()\n  * doc.text(10, 10, 'This is a test')\n  * doc.autoPrint()\n  * doc.save('autoprint.pdf')\n  */\n\n  (function (jsPDFAPI) {\n\n    jsPDFAPI.autoPrint = function (options) {\n\n      var refAutoPrintTag;\n      options = options || {};\n      options.variant = options.variant || 'non-conform';\n\n      switch (options.variant) {\n        case 'javascript':\n          //https://github.com/Rob--W/pdf.js/commit/c676ecb5a0f54677b9f3340c3ef2cf42225453bb\n          this.addJS('print({});');\n          break;\n        case 'non-conform':\n        default:\n          this.internal.events.subscribe('postPutResources', function () {\n            refAutoPrintTag = this.internal.newObject();\n            this.internal.out(\"<<\");\n            this.internal.out(\"/S /Named\");\n            this.internal.out(\"/Type /Action\");\n            this.internal.out(\"/N /Print\");\n            this.internal.out(\">>\");\n            this.internal.out(\"endobj\");\n          });\n\n          this.internal.events.subscribe(\"putCatalog\", function () {\n            this.internal.out(\"/OpenAction \" + refAutoPrintTag + \" 0 R\");\n          });\n          break;\n      }\n      return this;\n    };\n  })(jsPDF.API);\n\n  /**\n   * jsPDF Canvas PlugIn\n   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n\n  /**\n   * This plugin mimics the HTML5 Canvas\n   * \n   * The goal is to provide a way for current canvas users to print directly to a PDF.\n   */\n\n  (function (jsPDFAPI) {\n\n  \tjsPDFAPI.events.push(['initialized', function () {\n  \t\tthis.canvas.pdf = this;\n  \t}]);\n\n  \tjsPDFAPI.canvas = {\n  \t\tgetContext: function getContext(name) {\n  \t\t\tthis.pdf.context2d._canvas = this;\n  \t\t\treturn this.pdf.context2d;\n  \t\t},\n  \t\tchildNodes: []\n  \t};\n\n  \tObject.defineProperty(jsPDFAPI.canvas, 'width', {\n  \t\tget: function get() {\n  \t\t\treturn this._width;\n  \t\t},\n  \t\tset: function set(value) {\n  \t\t\tthis._width = value;\n  \t\t\tthis.getContext('2d').pageWrapX = value + 1;\n  \t\t}\n  \t});\n\n  \tObject.defineProperty(jsPDFAPI.canvas, 'height', {\n  \t\tget: function get() {\n  \t\t\treturn this._height;\n  \t\t},\n  \t\tset: function set(value) {\n  \t\t\tthis._height = value;\n  \t\t\tthis.getContext('2d').pageWrapY = value + 1;\n  \t\t}\n  \t});\n\n  \treturn this;\n  })(jsPDF.API);\n\n  /** ====================================================================\n   * jsPDF Cell plugin\n   * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com\n   *               2013 Eduardo Menezes de Morais, eduardo.morais@usp.br\n   *               2013 Lee Driscoll, https://github.com/lsdriscoll\n   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria\n   *               2014 James Hall, james@parall.ax\n   *               2014 Diego Casorran, https://github.com/diegocr\n   *\n   * \n   * ====================================================================\n   */\n\n  (function (jsPDFAPI) {\n      /*jslint browser:true */\n      /*global document: false, jsPDF */\n\n      var fontName,\n          fontSize,\n          fontStyle,\n          padding = 3,\n          margin = 13,\n          headerFunction,\n          lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined },\n          pages = 1,\n          setLastCellPosition = function setLastCellPosition(x, y, w, h, ln) {\n          lastCellPos = { 'x': x, 'y': y, 'w': w, 'h': h, 'ln': ln };\n      },\n          getLastCellPosition = function getLastCellPosition() {\n          return lastCellPos;\n      },\n          NO_MARGINS = { left: 0, top: 0, bottom: 0 };\n\n      jsPDFAPI.setHeaderFunction = function (func) {\n          headerFunction = func;\n      };\n\n      jsPDFAPI.getTextDimensions = function (txt) {\n          fontName = this.internal.getFont().fontName;\n          fontSize = this.table_font_size || this.internal.getFontSize();\n          fontStyle = this.internal.getFont().fontStyle;\n          // 1 pixel = 0.264583 mm and 1 mm = 72/25.4 point\n          var px2pt = 0.264583 * 72 / 25.4,\n              dimensions,\n              text;\n\n          text = document.createElement('font');\n          text.id = \"jsPDFCell\";\n\n          try {\n              text.style.fontStyle = fontStyle;\n          } catch (e) {\n              text.style.fontWeight = fontStyle;\n          }\n\n          text.style.fontSize = fontSize + 'pt';\n          text.style.fontFamily = fontName;\n          try {\n              text.textContent = txt;\n          } catch (e) {\n              text.innerText = txt;\n          }\n\n          document.body.appendChild(text);\n\n          dimensions = { w: (text.offsetWidth + 1) * px2pt, h: (text.offsetHeight + 1) * px2pt };\n\n          document.body.removeChild(text);\n\n          return dimensions;\n      };\n\n      jsPDFAPI.cellAddPage = function () {\n          var margins = this.margins || NO_MARGINS;\n\n          this.addPage();\n\n          setLastCellPosition(margins.left, margins.top, undefined, undefined);\n          //setLastCellPosition(undefined, undefined, undefined, undefined, undefined);\n          pages += 1;\n      };\n\n      jsPDFAPI.cellInitialize = function () {\n          lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined };\n          pages = 1;\n      };\n\n      jsPDFAPI.cell = function (x, y, w, h, txt, ln, align) {\n          var curCell = getLastCellPosition();\n          var pgAdded = false;\n\n          // If this is not the first cell, we must change its position\n          if (curCell.ln !== undefined) {\n              if (curCell.ln === ln) {\n                  //Same line\n                  x = curCell.x + curCell.w;\n                  y = curCell.y;\n              } else {\n                  //New line\n                  var margins = this.margins || NO_MARGINS;\n                  if (curCell.y + curCell.h + h + margin >= this.internal.pageSize.getHeight() - margins.bottom) {\n                      this.cellAddPage();\n                      pgAdded = true;\n                      if (this.printHeaders && this.tableHeaderRow) {\n                          this.printHeaderRow(ln, true);\n                      }\n                  }\n                  //We ignore the passed y: the lines may have different heights\n                  y = getLastCellPosition().y + getLastCellPosition().h;\n                  if (pgAdded) y = margin + 10;\n              }\n          }\n\n          if (txt[0] !== undefined) {\n              if (this.printingHeaderRow) {\n                  this.rect(x, y, w, h, 'FD');\n              } else {\n                  this.rect(x, y, w, h);\n              }\n              if (align === 'right') {\n                  if (!(txt instanceof Array)) {\n                      txt = [txt];\n                  }\n                  for (var i = 0; i < txt.length; i++) {\n                      var currentLine = txt[i];\n                      var textSize = this.getStringUnitWidth(currentLine) * this.internal.getFontSize();\n                      this.text(currentLine, x + w - textSize - padding, y + this.internal.getLineHeight() * (i + 1));\n                  }\n              } else {\n                  this.text(txt, x + padding, y + this.internal.getLineHeight());\n              }\n          }\n          setLastCellPosition(x, y, w, h, ln);\n          return this;\n      };\n\n      /**\n       * Return the maximum value from an array\n       * @param array\n       * @param comparisonFn\n       * @returns {*}\n       */\n      jsPDFAPI.arrayMax = function (array, comparisonFn) {\n          var max = array[0],\n              i,\n              ln,\n              item;\n\n          for (i = 0, ln = array.length; i < ln; i += 1) {\n              item = array[i];\n\n              if (comparisonFn) {\n                  if (comparisonFn(max, item) === -1) {\n                      max = item;\n                  }\n              } else {\n                  if (item > max) {\n                      max = item;\n                  }\n              }\n          }\n\n          return max;\n      };\n\n      /**\n       * Create a table from a set of data.\n       * @param {Integer} [x] : left-position for top-left corner of table\n       * @param {Integer} [y] top-position for top-left corner of table\n       * @param {Object[]} [data] As array of objects containing key-value pairs corresponding to a row of data.\n       * @param {String[]} [headers] Omit or null to auto-generate headers at a performance cost\n        * @param {Object} [config.printHeaders] True to print column headers at the top of every page\n       * @param {Object} [config.autoSize] True to dynamically set the column widths to match the widest cell value\n       * @param {Object} [config.margins] margin values for left, top, bottom, and width\n       * @param {Object} [config.fontSize] Integer fontSize to use (optional)\n       */\n\n      jsPDFAPI.table = function (x, y, data, headers, config) {\n          if (!data) {\n              throw 'No data for PDF table';\n          }\n\n          var headerNames = [],\n              headerPrompts = [],\n              header,\n              i,\n              ln,\n              cln,\n              columnMatrix = {},\n              columnWidths = {},\n              columnData,\n              column,\n              columnMinWidths = [],\n              j,\n              tableHeaderConfigs = [],\n              model,\n              jln,\n              func,\n\n\n          //set up defaults. If a value is provided in config, defaults will be overwritten:\n          autoSize = false,\n              printHeaders = true,\n              fontSize = 12,\n              margins = NO_MARGINS;\n\n          margins.width = this.internal.pageSize.getWidth();\n\n          if (config) {\n              //override config defaults if the user has specified non-default behavior:\n              if (config.autoSize === true) {\n                  autoSize = true;\n              }\n              if (config.printHeaders === false) {\n                  printHeaders = false;\n              }\n              if (config.fontSize) {\n                  fontSize = config.fontSize;\n              }\n              if (config.css && typeof config.css['font-size'] !== \"undefined\") {\n                  fontSize = config.css['font-size'] * 16;\n              }\n              if (config.margins) {\n                  margins = config.margins;\n              }\n          }\n\n          /**\n           * @property {Number} lnMod\n           * Keep track of the current line number modifier used when creating cells\n           */\n          this.lnMod = 0;\n          lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined }, pages = 1;\n\n          this.printHeaders = printHeaders;\n          this.margins = margins;\n          this.setFontSize(fontSize);\n          this.table_font_size = fontSize;\n\n          // Set header values\n          if (headers === undefined || headers === null) {\n              // No headers defined so we derive from data\n              headerNames = Object.keys(data[0]);\n          } else if (headers[0] && typeof headers[0] !== 'string') {\n              var px2pt = 0.264583 * 72 / 25.4;\n\n              // Split header configs into names and prompts\n              for (i = 0, ln = headers.length; i < ln; i += 1) {\n                  header = headers[i];\n                  headerNames.push(header.name);\n                  headerPrompts.push(header.prompt);\n                  columnWidths[header.name] = header.width * px2pt;\n              }\n          } else {\n              headerNames = headers;\n          }\n\n          if (autoSize) {\n              // Create a matrix of columns e.g., {column_title: [row1_Record, row2_Record]}\n              func = function func(rec) {\n                  return rec[header];\n              };\n\n              for (i = 0, ln = headerNames.length; i < ln; i += 1) {\n                  header = headerNames[i];\n\n                  columnMatrix[header] = data.map(func);\n\n                  // get header width\n                  columnMinWidths.push(this.getTextDimensions(headerPrompts[i] || header).w);\n                  column = columnMatrix[header];\n\n                  // get cell widths\n                  for (j = 0, cln = column.length; j < cln; j += 1) {\n                      columnData = column[j];\n                      columnMinWidths.push(this.getTextDimensions(columnData).w);\n                  }\n\n                  // get final column width\n                  columnWidths[header] = jsPDFAPI.arrayMax(columnMinWidths);\n\n                  //have to reset\n                  columnMinWidths = [];\n              }\n          }\n\n          // -- Construct the table\n\n          if (printHeaders) {\n              var lineHeight = this.calculateLineHeight(headerNames, columnWidths, headerPrompts.length ? headerPrompts : headerNames);\n\n              // Construct the header row\n              for (i = 0, ln = headerNames.length; i < ln; i += 1) {\n                  header = headerNames[i];\n                  tableHeaderConfigs.push([x, y, columnWidths[header], lineHeight, String(headerPrompts.length ? headerPrompts[i] : header)]);\n              }\n\n              // Store the table header config\n              this.setTableHeaderRow(tableHeaderConfigs);\n\n              // Print the header for the start of the table\n              this.printHeaderRow(1, false);\n          }\n\n          // Construct the data rows\n          for (i = 0, ln = data.length; i < ln; i += 1) {\n              var lineHeight;\n              model = data[i];\n              lineHeight = this.calculateLineHeight(headerNames, columnWidths, model);\n\n              for (j = 0, jln = headerNames.length; j < jln; j += 1) {\n                  header = headerNames[j];\n                  this.cell(x, y, columnWidths[header], lineHeight, model[header], i + 2, header.align);\n              }\n          }\n          this.lastCellPos = lastCellPos;\n          this.table_x = x;\n          this.table_y = y;\n          return this;\n      };\n      /**\n       * Calculate the height for containing the highest column\n       * @param {String[]} headerNames is the header, used as keys to the data\n       * @param {Integer[]} columnWidths is size of each column\n       * @param {Object[]} model is the line of data we want to calculate the height of\n       */\n      jsPDFAPI.calculateLineHeight = function (headerNames, columnWidths, model) {\n          var header,\n              lineHeight = 0;\n          for (var j = 0; j < headerNames.length; j++) {\n              header = headerNames[j];\n              model[header] = this.splitTextToSize(String(model[header]), columnWidths[header] - padding);\n              var h = this.internal.getLineHeight() * model[header].length + padding;\n              if (h > lineHeight) lineHeight = h;\n          }\n          return lineHeight;\n      };\n\n      /**\n       * Store the config for outputting a table header\n       * @param {Object[]} config\n       * An array of cell configs that would define a header row: Each config matches the config used by jsPDFAPI.cell\n       * except the ln parameter is excluded\n       */\n      jsPDFAPI.setTableHeaderRow = function (config) {\n          this.tableHeaderRow = config;\n      };\n\n      /**\n       * Output the store header row\n       * @param lineNumber The line number to output the header at\n       */\n      jsPDFAPI.printHeaderRow = function (lineNumber, new_page) {\n          if (!this.tableHeaderRow) {\n              throw 'Property tableHeaderRow does not exist.';\n          }\n\n          var tableHeaderCell, tmpArray, i, ln;\n\n          this.printingHeaderRow = true;\n          if (headerFunction !== undefined) {\n              var position = headerFunction(this, pages);\n              setLastCellPosition(position[0], position[1], position[2], position[3], -1);\n          }\n          this.setFontStyle('bold');\n          var tempHeaderConf = [];\n          for (i = 0, ln = this.tableHeaderRow.length; i < ln; i += 1) {\n              this.setFillColor(200, 200, 200);\n\n              tableHeaderCell = this.tableHeaderRow[i];\n              if (new_page) {\n                  this.margins.top = margin;\n                  tableHeaderCell[1] = this.margins && this.margins.top || 0;\n                  tempHeaderConf.push(tableHeaderCell);\n              }\n              tmpArray = [].concat(tableHeaderCell);\n              this.cell.apply(this, tmpArray.concat(lineNumber));\n          }\n          if (tempHeaderConf.length > 0) {\n              this.setTableHeaderRow(tempHeaderConf);\n          }\n          this.setFontStyle('normal');\n          this.printingHeaderRow = false;\n      };\n  })(jsPDF.API);\n\n  /**\n   * jsPDF Context2D PlugIn Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv\n   *\n   * Licensed under the MIT License. http://opensource.org/licenses/mit-license\n   */\n\n  /**\n   * This plugin mimics the HTML5 Canvas's context2d.\n   *\n   * The goal is to provide a way for current canvas implementations to print directly to a PDF.\n   */\n\n  /**\n   * TODO implement stroke opacity (refactor from fill() method )\n   * TODO transform angle and radii parameters\n   */\n\n  /**\n   * require('jspdf.js'); require('lib/css_colors.js');\n   */\n\n  (function (jsPDFAPI) {\n\n      jsPDFAPI.events.push(['initialized', function () {\n          this.context2d.pdf = this;\n          this.context2d.internal.pdf = this;\n          this.context2d.ctx = new context();\n          this.context2d.ctxStack = [];\n          this.context2d.path = [];\n      }]);\n\n      jsPDFAPI.context2d = {\n          pageWrapXEnabled: false,\n          pageWrapYEnabled: false,\n          pageWrapX: 9999999,\n          pageWrapY: 9999999,\n          ctx: new context(),\n          f2: function f2(number) {\n              return number.toFixed(2);\n          },\n\n          fillRect: function fillRect(x, y, w, h) {\n              if (this._isFillTransparent()) {\n                  return;\n              }\n              x = this._wrapX(x);\n              y = this._wrapY(y);\n\n              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });\n              this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, \"f\");\n          },\n\n          strokeRect: function strokeRect(x, y, w, h) {\n              if (this._isStrokeTransparent()) {\n                  return;\n              }\n              x = this._wrapX(x);\n              y = this._wrapY(y);\n\n              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });\n              this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, \"s\");\n          },\n\n          /**\n           * We cannot clear PDF commands that were already written to PDF, so we use white instead. <br />\n           * As a special case, read a special flag (ignoreClearRect) and do nothing if it is set.\n           * This results in all calls to clearRect() to do nothing, and keep the canvas transparent.\n           * This flag is stored in the save/restore context and is managed the same way as other drawing states.\n           * @param x\n           * @param y\n           * @param w\n           * @param h\n           */\n          clearRect: function clearRect(x, y, w, h) {\n              if (this.ctx.ignoreClearRect) {\n                  return;\n              }\n\n              x = this._wrapX(x);\n              y = this._wrapY(y);\n\n              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });\n              this.save();\n              this.setFillStyle('#ffffff');\n              //TODO This is hack to fill with white.\n              this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, \"f\");\n              this.restore();\n          },\n\n          save: function save() {\n              this.ctx._fontSize = this.pdf.internal.getFontSize();\n              var ctx = new context();\n              ctx.copy(this.ctx);\n              this.ctxStack.push(this.ctx);\n              this.ctx = ctx;\n          },\n\n          restore: function restore() {\n              this.ctx = this.ctxStack.pop();\n              this.setFillStyle(this.ctx.fillStyle);\n              this.setStrokeStyle(this.ctx.strokeStyle);\n              this.setFont(this.ctx.font);\n              this.pdf.setFontSize(this.ctx._fontSize);\n              this.setLineCap(this.ctx.lineCap);\n              this.setLineWidth(this.ctx.lineWidth);\n              this.setLineJoin(this.ctx.lineJoin);\n          },\n\n          rect: function rect(x, y, w, h) {\n              this.moveTo(x, y);\n              this.lineTo(x + w, y);\n              this.lineTo(x + w, y + h);\n              this.lineTo(x, y + h);\n              this.lineTo(x, y); //TODO not needed\n              this.closePath();\n          },\n\n          beginPath: function beginPath() {\n              this.path = [];\n          },\n\n          closePath: function closePath() {\n              this.path.push({\n                  type: 'close'\n              });\n          },\n\n          _getRGBA: function _getRGBA(style) {\n              // get the decimal values of r, g, and b;\n              var r, g, b, a;\n              var rgbColor = new RGBColor(style);\n\n              if (!style) {\n                  return { r: 0, g: 0, b: 0, a: 0, style: style };\n              }\n\n              if (this.internal.rxTransparent.test(style)) {\n                  r = 0;\n                  g = 0;\n                  b = 0;\n                  a = 0;\n              } else {\n                  var m = this.internal.rxRgb.exec(style);\n                  if (m != null) {\n                      r = parseInt(m[1]);\n                      g = parseInt(m[2]);\n                      b = parseInt(m[3]);\n                      a = 1;\n                  } else {\n                      m = this.internal.rxRgba.exec(style);\n                      if (m != null) {\n                          r = parseInt(m[1]);\n                          g = parseInt(m[2]);\n                          b = parseInt(m[3]);\n                          a = parseFloat(m[4]);\n                      } else {\n                          a = 1;\n                          if (style.charAt(0) != '#') {\n                              if (rgbColor.ok) {\n                                  style = rgbColor.toHex();\n                              } else {\n                                  style = '#000000';\n                              }\n                          }\n\n                          if (style.length === 4) {\n                              r = style.substring(1, 2);\n                              r += r;\n                              g = style.substring(2, 3);\n                              g += g;\n                              b = style.substring(3, 4);\n                              b += b;\n                          } else {\n                              r = style.substring(1, 3);\n                              g = style.substring(3, 5);\n                              b = style.substring(5, 7);\n                          }\n                          r = parseInt(r, 16);\n                          g = parseInt(g, 16);\n                          b = parseInt(b, 16);\n                      }\n                  }\n              }\n              return { r: r, g: g, b: b, a: a, style: style };\n          },\n\n          setFillStyle: function setFillStyle(style) {\n              var rgba = this._getRGBA(style);\n\n              this.ctx.fillStyle = style;\n              this.ctx._isFillTransparent = rgba.a === 0;\n              this.ctx._fillOpacity = rgba.a;\n\n              this.pdf.setFillColor(rgba.r, rgba.g, rgba.b, {\n                  a: rgba.a\n              });\n              this.pdf.setTextColor(rgba.r, rgba.g, rgba.b, {\n                  a: rgba.a\n              });\n          },\n\n          setStrokeStyle: function setStrokeStyle(style) {\n              var rgba = this._getRGBA(style);\n\n              this.ctx.strokeStyle = rgba.style;\n              this.ctx._isStrokeTransparent = rgba.a === 0;\n              this.ctx._strokeOpacity = rgba.a;\n\n              //TODO jsPDF to handle rgba\n              if (rgba.a === 0) {\n                  this.pdf.setDrawColor(255, 255, 255);\n              } else if (rgba.a === 1) {\n                  this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b);\n              } else {\n                  //this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b, {a: rgba.a});\n                  this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b);\n              }\n          },\n\n          fillText: function fillText(text, x, y, maxWidth) {\n              if (this._isFillTransparent()) {\n                  return;\n              }\n              x = this._wrapX(x);\n              y = this._wrapY(y);\n\n              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);\n              x = xpt[0];\n              y = xpt[1];\n              var rads = this._matrix_rotation(this.ctx._transform);\n              var degs = rads * 57.2958;\n\n              //TODO only push the clip if it has not been applied to the current PDF context\n              if (this.ctx._clip_path.length > 0) {\n                  var lines;\n                  if (window.outIntercept) {\n                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;\n                  } else {\n                      lines = this.internal.getCurrentPage();\n                  }\n                  lines.push(\"q\");\n                  var origPath = this.path;\n                  this.path = this.ctx._clip_path;\n                  this.ctx._clip_path = [];\n                  this._fill(null, true);\n                  this.ctx._clip_path = this.path;\n                  this.path = origPath;\n              }\n\n              // We only use X axis as scale hint \n              var scale = 1;\n              try {\n                  scale = this._matrix_decompose(this._getTransform()).scale[0];\n              } catch (e) {\n                  console.warn(e);\n              }\n\n              // In some cases the transform was very small (5.715760606202283e-17).  Most likely a canvg rounding error.\n              if (scale < 0.01) {\n                  this.pdf.text(text, x, this._getBaseline(y), null, degs);\n              } else {\n                  var oldSize = this.pdf.internal.getFontSize();\n                  this.pdf.setFontSize(oldSize * scale);\n                  this.pdf.text(text, x, this._getBaseline(y), null, degs);\n                  this.pdf.setFontSize(oldSize);\n              }\n\n              if (this.ctx._clip_path.length > 0) {\n                  lines.push('Q');\n              }\n          },\n\n          strokeText: function strokeText(text, x, y, maxWidth) {\n              if (this._isStrokeTransparent()) {\n                  return;\n              }\n              x = this._wrapX(x);\n              y = this._wrapY(y);\n\n              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);\n              x = xpt[0];\n              y = xpt[1];\n              var rads = this._matrix_rotation(this.ctx._transform);\n              var degs = rads * 57.2958;\n\n              //TODO only push the clip if it has not been applied to the current PDF context\n              if (this.ctx._clip_path.length > 0) {\n                  var lines;\n                  if (window.outIntercept) {\n                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;\n                  } else {\n                      lines = this.internal.getCurrentPage();\n                  }\n                  lines.push(\"q\");\n                  var origPath = this.path;\n                  this.path = this.ctx._clip_path;\n                  this.ctx._clip_path = [];\n                  this._fill(null, true);\n                  this.ctx._clip_path = this.path;\n                  this.path = origPath;\n              }\n\n              var scale = 1;\n              // We only use the X axis as scale hint \n              try {\n                  scale = this._matrix_decompose(this._getTransform()).scale[0];\n              } catch (e) {\n                  console.warn(e);\n              }\n\n              if (scale === 1) {\n                  this.pdf.text(text, x, this._getBaseline(y), {\n                      stroke: true\n                  }, degs);\n              } else {\n                  var oldSize = this.pdf.internal.getFontSize();\n                  this.pdf.setFontSize(oldSize * scale);\n                  this.pdf.text(text, x, this._getBaseline(y), {\n                      stroke: true\n                  }, degs);\n                  this.pdf.setFontSize(oldSize);\n              }\n\n              if (this.ctx._clip_path.length > 0) {\n                  lines.push('Q');\n              }\n          },\n\n          setFont: function setFont(font) {\n              this.ctx.font = font;\n\n              //var rx = /\\s*(\\w+)\\s+(\\w+)\\s+(\\w+)\\s+([\\d\\.]+)(px|pt|em)\\s+[\"']?(\\w+)['\"]?/;\n              var rx = /\\s*(\\w+)\\s+(\\w+)\\s+(\\w+)\\s+([\\d\\.]+)(px|pt|em)\\s+(.*)?/;\n              m = rx.exec(font);\n              if (m != null) {\n                  var fontStyle = m[1];\n                  var fontVariant = m[2];\n                  var fontWeight = m[3];\n                  var fontSize = m[4];\n                  var fontSizeUnit = m[5];\n                  var fontFamily = m[6];\n\n                  if ('px' === fontSizeUnit) {\n                      fontSize = Math.floor(parseFloat(fontSize));\n                      // fontSize = fontSize * 1.25;\n                  } else if ('em' === fontSizeUnit) {\n                      fontSize = Math.floor(parseFloat(fontSize) * this.pdf.getFontSize());\n                  } else {\n                      fontSize = Math.floor(parseFloat(fontSize));\n                  }\n\n                  this.pdf.setFontSize(fontSize);\n\n                  if (fontWeight === 'bold' || fontWeight === '700') {\n                      this.pdf.setFontStyle('bold');\n                  } else {\n                      if (fontStyle === 'italic') {\n                          this.pdf.setFontStyle('italic');\n                      } else {\n                          this.pdf.setFontStyle('normal');\n                      }\n                  }\n                  var style;\n                  if ('bold' === fontWeight || fontWeight === '700') {\n                      style = fontStyle === 'italic' ? 'bolditalic' : 'bold';\n                  } else if (fontStyle === 'italic') {\n                      style = 'italic';\n                  } else {\n                      style = 'normal';\n                  }\n\n                  var parts = fontFamily.toLowerCase().split(/\\s*,\\s*/);\n                  var jsPdfFontName = 'Times';\n\n                  for (var i = 0; i < parts.length; i++) {\n                      if (this.pdf.internal.getFont(parts[i], style, { noFallback: true, disableWarning: true }) !== undefined) {\n                          jsPdfFontName = parts[i];\n                          break;\n                      } else if (style === 'bolditalic' && this.pdf.internal.getFont(parts[i], 'bold', { noFallback: true, disableWarning: true }) !== undefined) {\n                          jsPdfFontName = parts[i];\n                          style = 'bold';\n                      } else if (this.pdf.internal.getFont(parts[i], 'normal', { noFallback: true, disableWarning: true }) !== undefined) {\n                          jsPdfFontName = parts[i];\n                          style = 'normal';\n                          break;\n                      }\n                  }\n\n                  this.pdf.setFont(jsPdfFontName, style);\n              } else {\n                  var rx = /\\s*(\\d+)(pt|px|em)\\s+([\\w \"]+)\\s*([\\w \"]+)?/;\n                  var m = rx.exec(font);\n                  if (m != null) {\n                      var size = m[1];\n                      var unit = m[2];\n                      var name = m[3];\n                      var style = m[4];\n                      if (!style) {\n                          style = 'normal';\n                      }\n                      if ('em' === fontSizeUnit) {\n                          size = Math.floor(parseFloat(fontSize) * this.pdf.getFontSize());\n                      } else {\n                          size = Math.floor(parseFloat(size));\n                      }\n                      this.pdf.setFontSize(size);\n                      this.pdf.setFont(name, style);\n                  }\n              }\n          },\n\n          setTextBaseline: function setTextBaseline(baseline) {\n              this.ctx.textBaseline = baseline;\n          },\n\n          getTextBaseline: function getTextBaseline() {\n              return this.ctx.textBaseline;\n          },\n\n          //TODO implement textAlign\n          setTextAlign: function setTextAlign(align) {\n              this.ctx.textAlign = align;\n          },\n\n          getTextAlign: function getTextAlign() {\n              return this.ctx.textAlign;\n          },\n\n          setLineWidth: function setLineWidth(width) {\n              this.ctx.lineWidth = width;\n              this.pdf.setLineWidth(width);\n          },\n\n          setLineCap: function setLineCap(style) {\n              this.ctx.lineCap = style;\n              this.pdf.setLineCap(style);\n          },\n\n          setLineJoin: function setLineJoin(style) {\n              this.ctx.lineJoin = style;\n              this.pdf.setLineJoin(style);\n          },\n\n          moveTo: function moveTo(x, y) {\n              x = this._wrapX(x);\n              y = this._wrapY(y);\n\n              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);\n              x = xpt[0];\n              y = xpt[1];\n\n              var obj = {\n                  type: 'mt',\n                  x: x,\n                  y: y\n              };\n              this.path.push(obj);\n          },\n\n          _wrapX: function _wrapX(x) {\n              if (this.pageWrapXEnabled) {\n                  return x % this.pageWrapX;\n              } else {\n                  return x;\n              }\n          },\n\n          _wrapY: function _wrapY(y) {\n              if (this.pageWrapYEnabled) {\n                  this._gotoPage(this._page(y));\n                  return (y - this.lastBreak) % this.pageWrapY;\n              } else {\n                  return y;\n              }\n          },\n\n          transform: function transform(a, b, c, d, e, f) {\n              this.ctx._transform = this._matrix_multiply(this.ctx._transform, [a, b, c, d, e, f]);\n          },\n\n          setTransform: function setTransform(a, b, c, d, e, f) {\n              this.ctx._transform = [a, b, c, d, e, f];\n          },\n\n          _getTransform: function _getTransform() {\n              return this.ctx._transform;\n          },\n\n          lastBreak: 0,\n          // Y Position of page breaks.\n          pageBreaks: [],\n          // returns: One-based Page Number\n          // Should only be used if pageWrapYEnabled is true\n          _page: function _page(y) {\n              if (this.pageWrapYEnabled) {\n                  this.lastBreak = 0;\n                  var manualBreaks = 0;\n                  var autoBreaks = 0;\n                  for (var i = 0; i < this.pageBreaks.length; i++) {\n                      if (y >= this.pageBreaks[i]) {\n                          manualBreaks++;\n                          if (this.lastBreak === 0) {\n                              autoBreaks++;\n                          }\n                          var spaceBetweenLastBreak = this.pageBreaks[i] - this.lastBreak;\n                          this.lastBreak = this.pageBreaks[i];\n                          var pagesSinceLastBreak = Math.floor(spaceBetweenLastBreak / this.pageWrapY);\n                          autoBreaks += pagesSinceLastBreak;\n                      }\n                  }\n                  if (this.lastBreak === 0) {\n                      var pagesSinceLastBreak = Math.floor(y / this.pageWrapY) + 1;\n                      autoBreaks += pagesSinceLastBreak;\n                  }\n                  return autoBreaks + manualBreaks;\n              } else {\n                  return this.pdf.internal.getCurrentPageInfo().pageNumber;\n              }\n          },\n\n          _gotoPage: function _gotoPage(pageOneBased) {\n              // This is a stub to be overriden if needed\n          },\n\n          lineTo: function lineTo(x, y) {\n              x = this._wrapX(x);\n              y = this._wrapY(y);\n\n              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);\n              x = xpt[0];\n              y = xpt[1];\n\n              var obj = {\n                  type: 'lt',\n                  x: x,\n                  y: y\n              };\n              this.path.push(obj);\n          },\n\n          bezierCurveTo: function bezierCurveTo(x1, y1, x2, y2, x, y) {\n              x1 = this._wrapX(x1);\n              y1 = this._wrapY(y1);\n              x2 = this._wrapX(x2);\n              y2 = this._wrapY(y2);\n              x = this._wrapX(x);\n              y = this._wrapY(y);\n\n              var xpt;\n              xpt = this._matrix_map_point(this.ctx._transform, [x, y]);\n              x = xpt[0];\n              y = xpt[1];\n              xpt = this._matrix_map_point(this.ctx._transform, [x1, y1]);\n              x1 = xpt[0];\n              y1 = xpt[1];\n              xpt = this._matrix_map_point(this.ctx._transform, [x2, y2]);\n              x2 = xpt[0];\n              y2 = xpt[1];\n\n              var obj = {\n                  type: 'bct',\n                  x1: x1,\n                  y1: y1,\n                  x2: x2,\n                  y2: y2,\n                  x: x,\n                  y: y\n              };\n              this.path.push(obj);\n          },\n\n          quadraticCurveTo: function quadraticCurveTo(x1, y1, x, y) {\n              x1 = this._wrapX(x1);\n              y1 = this._wrapY(y1);\n              x = this._wrapX(x);\n              y = this._wrapY(y);\n\n              var xpt;\n              xpt = this._matrix_map_point(this.ctx._transform, [x, y]);\n              x = xpt[0];\n              y = xpt[1];\n              xpt = this._matrix_map_point(this.ctx._transform, [x1, y1]);\n              x1 = xpt[0];\n              y1 = xpt[1];\n\n              var obj = {\n                  type: 'qct',\n                  x1: x1,\n                  y1: y1,\n                  x: x,\n                  y: y\n              };\n              this.path.push(obj);\n          },\n\n          arc: function arc(x, y, radius, startAngle, endAngle, anticlockwise) {\n              x = this._wrapX(x);\n              y = this._wrapY(y);\n\n              if (!this._matrix_is_identity(this.ctx._transform)) {\n                  var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);\n                  x = xpt[0];\n                  y = xpt[1];\n\n                  var x_radPt0 = this._matrix_map_point(this.ctx._transform, [0, 0]);\n                  var x_radPt = this._matrix_map_point(this.ctx._transform, [0, radius]);\n                  radius = Math.sqrt(Math.pow(x_radPt[0] - x_radPt0[0], 2) + Math.pow(x_radPt[1] - x_radPt0[1], 2));\n\n                  //TODO angles need to be transformed\n              }\n\n              var obj = {\n                  type: 'arc',\n                  x: x,\n                  y: y,\n                  radius: radius,\n                  startAngle: startAngle,\n                  endAngle: endAngle,\n                  anticlockwise: anticlockwise\n              };\n              this.path.push(obj);\n          },\n\n          drawImage: function drawImage(img, x, y, w, h, x2, y2, w2, h2) {\n              if (x2 !== undefined) {\n                  x = x2;\n                  y = y2;\n                  w = w2;\n                  h = h2;\n              }\n              x = this._wrapX(x);\n              y = this._wrapY(y);\n\n              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });\n              var xRect2 = this._matrix_map_rect(this.ctx._transform, { x: x2, y: y2, w: w2, h: h2 });\n\n              // TODO implement source clipping and image scaling\n              var format;\n              var rx = /data:image\\/(\\w+).*/i;\n              var m = rx.exec(img);\n              if (m != null) {\n                  format = m[1];\n              } else {\n                  // format = \"jpeg\";\n                  format = \"png\";\n              }\n\n              this.pdf.addImage(img, format, xRect.x, xRect.y, xRect.w, xRect.h);\n          },\n\n          /**\n           * Multiply the first matrix by the second\n           * @param m1\n           * @param m2\n           * @returns {*[]}\n           * @private\n           */\n          _matrix_multiply: function _matrix_multiply(m2, m1) {\n              var sx = m1[0];\n              var shy = m1[1];\n              var shx = m1[2];\n              var sy = m1[3];\n              var tx = m1[4];\n              var ty = m1[5];\n\n              var t0 = sx * m2[0] + shy * m2[2];\n              var t2 = shx * m2[0] + sy * m2[2];\n              var t4 = tx * m2[0] + ty * m2[2] + m2[4];\n              shy = sx * m2[1] + shy * m2[3];\n              sy = shx * m2[1] + sy * m2[3];\n              ty = tx * m2[1] + ty * m2[3] + m2[5];\n              sx = t0;\n              shx = t2;\n              tx = t4;\n\n              return [sx, shy, shx, sy, tx, ty];\n          },\n\n          _matrix_rotation: function _matrix_rotation(m) {\n              return Math.atan2(m[2], m[0]);\n          },\n\n          _matrix_decompose: function _matrix_decompose(matrix) {\n\n              var a = matrix[0];\n              var b = matrix[1];\n              var c = matrix[2];\n              var d = matrix[3];\n\n              var scaleX = Math.sqrt(a * a + b * b);\n              a /= scaleX;\n              b /= scaleX;\n\n              var shear = a * c + b * d;\n              c -= a * shear;\n              d -= b * shear;\n\n              var scaleY = Math.sqrt(c * c + d * d);\n              c /= scaleY;\n              d /= scaleY;\n              shear /= scaleY;\n\n              if (a * d < b * c) {\n                  a = -a;\n                  b = -b;\n                  shear = -shear;\n                  scaleX = -scaleX;\n              }\n\n              return {\n                  scale: [scaleX, 0, 0, scaleY, 0, 0],\n                  translate: [1, 0, 0, 1, matrix[4], matrix[5]],\n                  rotate: [a, b, -b, a, 0, 0],\n                  skew: [1, 0, shear, 1, 0, 0]\n              };\n          },\n\n          _matrix_map_point: function _matrix_map_point(m1, pt) {\n              var sx = m1[0];\n              var shy = m1[1];\n              var shx = m1[2];\n              var sy = m1[3];\n              var tx = m1[4];\n              var ty = m1[5];\n\n              var px = pt[0];\n              var py = pt[1];\n\n              var x = px * sx + py * shx + tx;\n              var y = px * shy + py * sy + ty;\n              return [x, y];\n          },\n\n          _matrix_map_point_obj: function _matrix_map_point_obj(m1, pt) {\n              var xpt = this._matrix_map_point(m1, [pt.x, pt.y]);\n              return { x: xpt[0], y: xpt[1] };\n          },\n\n          _matrix_map_rect: function _matrix_map_rect(m1, rect) {\n              var p1 = this._matrix_map_point(m1, [rect.x, rect.y]);\n              var p2 = this._matrix_map_point(m1, [rect.x + rect.w, rect.y + rect.h]);\n              return { x: p1[0], y: p1[1], w: p2[0] - p1[0], h: p2[1] - p1[1] };\n          },\n\n          _matrix_is_identity: function _matrix_is_identity(m1) {\n              if (m1[0] != 1) {\n                  return false;\n              }\n              if (m1[1] != 0) {\n                  return false;\n              }\n              if (m1[2] != 0) {\n                  return false;\n              }\n              if (m1[3] != 1) {\n                  return false;\n              }\n              if (m1[4] != 0) {\n                  return false;\n              }\n              if (m1[5] != 0) {\n                  return false;\n              }\n              return true;\n          },\n\n          rotate: function rotate(angle) {\n              var matrix = [Math.cos(angle), Math.sin(angle), -Math.sin(angle), Math.cos(angle), 0.0, 0.0];\n              this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix);\n          },\n\n          scale: function scale(sx, sy) {\n              var matrix = [sx, 0.0, 0.0, sy, 0.0, 0.0];\n              this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix);\n          },\n\n          translate: function translate(x, y) {\n              var matrix = [1.0, 0.0, 0.0, 1.0, x, y];\n              this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix);\n          },\n\n          stroke: function stroke() {\n              if (this.ctx._clip_path.length > 0) {\n\n                  var lines;\n                  if (window.outIntercept) {\n                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;\n                  } else {\n                      lines = this.internal.getCurrentPage();\n                  }\n                  lines.push(\"q\");\n\n                  var origPath = this.path;\n                  this.path = this.ctx._clip_path;\n                  this.ctx._clip_path = [];\n                  this._stroke(true);\n\n                  this.ctx._clip_path = this.path;\n                  this.path = origPath;\n                  this._stroke(false);\n\n                  lines.push(\"Q\");\n              } else {\n                  this._stroke(false);\n              }\n          },\n\n          _stroke: function _stroke(isClip) {\n              if (!isClip && this._isStrokeTransparent()) {\n                  return;\n              }\n\n              //TODO opacity\n\n              var moves = [];\n\n              var xPath = this.path;\n\n              for (var i = 0; i < xPath.length; i++) {\n                  var pt = xPath[i];\n                  switch (pt.type) {\n                      case 'mt':\n                          moves.push({ start: pt, deltas: [], abs: [] });\n                          break;\n                      case 'lt':\n                          var delta = [pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];\n                          moves[moves.length - 1].deltas.push(delta);\n                          moves[moves.length - 1].abs.push(pt);\n                          break;\n                      case 'bct':\n                          var delta = [pt.x1 - xPath[i - 1].x, pt.y1 - xPath[i - 1].y, pt.x2 - xPath[i - 1].x, pt.y2 - xPath[i - 1].y, pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];\n                          moves[moves.length - 1].deltas.push(delta);\n                          break;\n                      case 'qct':\n                          // convert to bezier\n                          var x1 = xPath[i - 1].x + 2.0 / 3.0 * (pt.x1 - xPath[i - 1].x);\n                          var y1 = xPath[i - 1].y + 2.0 / 3.0 * (pt.y1 - xPath[i - 1].y);\n                          var x2 = pt.x + 2.0 / 3.0 * (pt.x1 - pt.x);\n                          var y2 = pt.y + 2.0 / 3.0 * (pt.y1 - pt.y);\n                          var x3 = pt.x;\n                          var y3 = pt.y;\n                          var delta = [x1 - xPath[i - 1].x, y1 - xPath[i - 1].y, x2 - xPath[i - 1].x, y2 - xPath[i - 1].y, x3 - xPath[i - 1].x, y3 - xPath[i - 1].y];\n                          moves[moves.length - 1].deltas.push(delta);\n                          break;\n                      case 'arc':\n                          //TODO this was hack to avoid out-of-bounds issue\n                          // No move-to before drawing the arc\n                          if (moves.length == 0) {\n                              moves.push({ start: { x: 0, y: 0 }, deltas: [], abs: [] });\n                          }\n                          moves[moves.length - 1].arc = true;\n                          if (Array.isArray(moves[moves.length - 1].abs)) {\n                              moves[moves.length - 1].abs.push(pt);\n                          }\n                          break;\n                      case 'close':\n                          break;\n                  }\n              }\n\n              for (var i = 0; i < moves.length; i++) {\n                  var style;\n                  if (i == moves.length - 1) {\n                      style = 's';\n                  } else {\n                      style = null;\n                  }\n                  if (moves[i].arc) {\n                      var arcs = moves[i].abs;\n                      for (var ii = 0; ii < arcs.length; ii++) {\n                          var arc = arcs[ii];\n                          var start = arc.startAngle * 360 / (2 * Math.PI);\n                          var end = arc.endAngle * 360 / (2 * Math.PI);\n                          var x = arc.x;\n                          var y = arc.y;\n                          this.internal.arc2(this, x, y, arc.radius, start, end, arc.anticlockwise, style, isClip);\n                      }\n                  } else {\n                      var x = moves[i].start.x;\n                      var y = moves[i].start.y;\n                      if (!isClip) {\n                          this.pdf.lines(moves[i].deltas, x, y, null, style);\n                      } else {\n                          this.pdf.lines(moves[i].deltas, x, y, null, null);\n                          this.pdf.clip_fixed();\n                      }\n                  }\n              }\n          },\n\n          _isFillTransparent: function _isFillTransparent() {\n              return this.ctx._isFillTransparent || this.globalAlpha == 0;\n          },\n\n          _isStrokeTransparent: function _isStrokeTransparent() {\n              return this.ctx._isStrokeTransparent || this.globalAlpha == 0;\n          },\n\n          fill: function fill(fillRule) {\n              //evenodd or nonzero (default)\n              if (this.ctx._clip_path.length > 0) {\n\n                  var lines;\n                  if (window.outIntercept) {\n                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;\n                  } else {\n                      lines = this.internal.getCurrentPage();\n                  }\n                  lines.push(\"q\");\n\n                  var origPath = this.path;\n                  this.path = this.ctx._clip_path;\n                  this.ctx._clip_path = [];\n                  this._fill(fillRule, true);\n\n                  this.ctx._clip_path = this.path;\n                  this.path = origPath;\n                  this._fill(fillRule, false);\n\n                  lines.push('Q');\n              } else {\n                  this._fill(fillRule, false);\n              }\n          },\n\n          _fill: function _fill(fillRule, isClip) {\n              if (this._isFillTransparent()) {\n                  return;\n              }\n              var v2Support = typeof this.pdf.internal.newObject2 === 'function';\n\n              var lines;\n              if (window.outIntercept) {\n                  lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;\n              } else {\n                  lines = this.internal.getCurrentPage();\n              }\n\n              // if (this.ctx._clip_path.length > 0) {\n              //     lines.push('q');\n              //     var oldPath = this.path;\n              //     this.path = this.ctx._clip_path;\n              //     this.ctx._clip_path = [];\n              //     this._fill(fillRule, true);\n              //     this.ctx._clip_path = this.path;\n              //     this.path = oldPath;\n              //     lines.push('Q');\n              // }\n\n              var moves = [];\n              var outInterceptOld = window.outIntercept;\n\n              if (v2Support) {\n                  // Blend and Mask\n                  switch (this.ctx.globalCompositeOperation) {\n                      case 'normal':\n                      case 'source-over':\n                          break;\n                      case 'destination-in':\n                      case 'destination-out':\n                          //TODO this need to be added to the current group or page\n                          // define a mask stream\n                          var obj = this.pdf.internal.newStreamObject();\n\n                          // define a mask state\n                          var obj2 = this.pdf.internal.newObject2();\n                          obj2.push('<</Type /ExtGState');\n                          obj2.push('/SMask <</S /Alpha /G ' + obj.objId + ' 0 R>>'); // /S /Luminosity will need to define color space\n                          obj2.push('>>');\n\n                          // add mask to page resources\n                          var gsName = 'MASK' + obj2.objId;\n                          this.pdf.internal.addGraphicsState(gsName, obj2.objId);\n\n                          var instruction = '/' + gsName + ' gs';\n                          // add mask to page, group, or stream\n                          lines.splice(0, 0, 'q');\n                          lines.splice(1, 0, instruction);\n                          lines.push('Q');\n\n                          window.outIntercept = obj;\n                          break;\n                      default:\n                          var dictionaryEntry = '/' + this.pdf.internal.blendModeMap[this.ctx.globalCompositeOperation.toUpperCase()];\n                          if (dictionaryEntry) {\n                              this.pdf.internal.out(dictionaryEntry + ' gs');\n                          }\n                          break;\n                  }\n              }\n\n              var alpha = this.ctx.globalAlpha;\n              if (this.ctx._fillOpacity < 1) {\n                  // TODO combine this with global opacity\n                  alpha = this.ctx._fillOpacity;\n              }\n\n              //TODO check for an opacity graphics state that was already created\n              //TODO do not set opacity if current value is already active\n              if (v2Support) {\n                  var objOpac = this.pdf.internal.newObject2();\n                  objOpac.push('<</Type /ExtGState');\n                  //objOpac.push(this.ctx.globalAlpha + \" CA\"); // Stroke\n                  //objOpac.push(this.ctx.globalAlpha + \" ca\"); // Not Stroke\n                  objOpac.push('/CA ' + alpha); // Stroke\n                  objOpac.push('/ca ' + alpha); // Not Stroke\n                  objOpac.push('>>');\n                  var gsName = 'GS_O_' + objOpac.objId;\n                  this.pdf.internal.addGraphicsState(gsName, objOpac.objId);\n                  this.pdf.internal.out('/' + gsName + ' gs');\n              }\n\n              var xPath = this.path;\n\n              for (var i = 0; i < xPath.length; i++) {\n                  var pt = xPath[i];\n                  switch (pt.type) {\n                      case 'mt':\n                          moves.push({ start: pt, deltas: [], abs: [] });\n                          break;\n                      case 'lt':\n                          var delta = [pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];\n                          moves[moves.length - 1].deltas.push(delta);\n                          moves[moves.length - 1].abs.push(pt);\n                          break;\n                      case 'bct':\n                          var delta = [pt.x1 - xPath[i - 1].x, pt.y1 - xPath[i - 1].y, pt.x2 - xPath[i - 1].x, pt.y2 - xPath[i - 1].y, pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];\n                          moves[moves.length - 1].deltas.push(delta);\n                          break;\n                      case 'qct':\n                          // convert to bezier\n                          var x1 = xPath[i - 1].x + 2.0 / 3.0 * (pt.x1 - xPath[i - 1].x);\n                          var y1 = xPath[i - 1].y + 2.0 / 3.0 * (pt.y1 - xPath[i - 1].y);\n                          var x2 = pt.x + 2.0 / 3.0 * (pt.x1 - pt.x);\n                          var y2 = pt.y + 2.0 / 3.0 * (pt.y1 - pt.y);\n                          var x3 = pt.x;\n                          var y3 = pt.y;\n                          var delta = [x1 - xPath[i - 1].x, y1 - xPath[i - 1].y, x2 - xPath[i - 1].x, y2 - xPath[i - 1].y, x3 - xPath[i - 1].x, y3 - xPath[i - 1].y];\n                          moves[moves.length - 1].deltas.push(delta);\n                          break;\n                      case 'arc':\n                          //TODO this was hack to avoid out-of-bounds issue when drawing circle\n                          // No move-to before drawing the arc\n                          if (moves.length === 0) {\n                              moves.push({ deltas: [], abs: [] });\n                          }\n                          moves[moves.length - 1].arc = true;\n                          if (Array.isArray(moves[moves.length - 1].abs)) {\n                              moves[moves.length - 1].abs.push(pt);\n                          }\n                          break;\n                      case 'close':\n                          moves.push({ close: true });\n                          break;\n                  }\n              }\n\n              for (var i = 0; i < moves.length; i++) {\n                  var style;\n                  if (i == moves.length - 1) {\n                      style = 'f';\n                      if (fillRule === 'evenodd') {\n                          style += '*';\n                      }\n                  } else {\n                      style = null;\n                  }\n\n                  if (moves[i].close) {\n                      this.pdf.internal.out('h');\n                      if (style) {\n                          // only fill at final path move\n                          this.pdf.internal.out(style);\n                      }\n                  } else if (moves[i].arc) {\n                      if (moves[i].start) {\n                          this.internal.move2(this, moves[i].start.x, moves[i].start.y);\n                      }\n                      var arcs = moves[i].abs;\n                      for (var ii = 0; ii < arcs.length; ii++) {\n                          var arc = arcs[ii];\n                          //TODO lines deltas were getting in here\n                          if (typeof arc.startAngle !== 'undefined') {\n                              var start = arc.startAngle * 360 / (2 * Math.PI);\n                              var end = arc.endAngle * 360 / (2 * Math.PI);\n                              var x = arc.x;\n                              var y = arc.y;\n                              if (ii === 0) {\n                                  this.internal.move2(this, x, y);\n                              }\n                              this.internal.arc2(this, x, y, arc.radius, start, end, arc.anticlockwise, null, isClip);\n                              if (ii === arcs.length - 1) {\n                                  // The original arc move did not occur because of the algorithm\n                                  if (moves[i].start) {\n                                      var x = moves[i].start.x;\n                                      var y = moves[i].start.y;\n                                      this.internal.line2(c2d, x, y);\n                                  }\n                              }\n                          } else {\n                              this.internal.line2(c2d, arc.x, arc.y);\n                          }\n                      }\n                  } else {\n                      var x = moves[i].start.x;\n                      var y = moves[i].start.y;\n                      if (!isClip) {\n                          this.pdf.lines(moves[i].deltas, x, y, null, style);\n                      } else {\n                          this.pdf.lines(moves[i].deltas, x, y, null, null);\n                          this.pdf.clip_fixed();\n                      }\n                  }\n              }\n\n              window.outIntercept = outInterceptOld;\n\n              // if (this.ctx._clip_path.length > 0) {\n              //     lines.push('Q');\n              // }\n          },\n\n          pushMask: function pushMask() {\n              var v2Support = typeof this.pdf.internal.newObject2 === 'function';\n\n              if (!v2Support) {\n                  console.log('jsPDF v2 not enabled');\n                  return;\n              }\n\n              // define a mask stream\n              var obj = this.pdf.internal.newStreamObject();\n\n              // define a mask state\n              var obj2 = this.pdf.internal.newObject2();\n              obj2.push('<</Type /ExtGState');\n              obj2.push('/SMask <</S /Alpha /G ' + obj.objId + ' 0 R>>'); // /S /Luminosity will need to define color space\n              obj2.push('>>');\n\n              // add mask to page resources\n              var gsName = 'MASK' + obj2.objId;\n              this.pdf.internal.addGraphicsState(gsName, obj2.objId);\n\n              var instruction = '/' + gsName + ' gs';\n              this.pdf.internal.out(instruction);\n          },\n\n          clip: function clip() {\n              //TODO do we reset the path, or just copy it?\n              if (this.ctx._clip_path.length > 0) {\n                  for (var i = 0; i < this.path.length; i++) {\n                      this.ctx._clip_path.push(this.path[i]);\n                  }\n              } else {\n                  this.ctx._clip_path = this.path;\n              }\n              this.path = [];\n          },\n\n          measureText: function measureText(text) {\n              var pdf = this.pdf;\n              return {\n                  getWidth: function getWidth() {\n                      var fontSize = pdf.internal.getFontSize();\n                      var txtWidth = pdf.getStringUnitWidth(text) * fontSize / pdf.internal.scaleFactor;\n                      // Convert points to pixels\n                      txtWidth *= 1.3333;\n                      return txtWidth;\n                  },\n\n                  get width() {\n                      return this.getWidth(text);\n                  }\n              };\n          },\n          _getBaseline: function _getBaseline(y) {\n              var height = parseInt(this.pdf.internal.getFontSize());\n              // TODO Get descent from font descriptor\n              var descent = height * 0.25;\n              switch (this.ctx.textBaseline) {\n                  case 'bottom':\n                      return y - descent;\n                  case 'top':\n                      return y + height;\n                  case 'hanging':\n                      return y + height - descent;\n                  case 'middle':\n                      return y + height / 2 - descent;\n                  case 'ideographic':\n                      // TODO not implemented\n                      return y;\n                  case 'alphabetic':\n                  default:\n                      return y;\n              }\n          }\n      };\n\n      var c2d = jsPDFAPI.context2d;\n\n      // accessor methods\n      Object.defineProperty(c2d, 'fillStyle', {\n          set: function set(value) {\n              this.setFillStyle(value);\n          },\n          get: function get() {\n              return this.ctx.fillStyle;\n          }\n      });\n      Object.defineProperty(c2d, 'strokeStyle', {\n          set: function set(value) {\n              this.setStrokeStyle(value);\n          },\n          get: function get() {\n              return this.ctx.strokeStyle;\n          }\n      });\n      Object.defineProperty(c2d, 'lineWidth', {\n          set: function set(value) {\n              this.setLineWidth(value);\n          },\n          get: function get() {\n              return this.ctx.lineWidth;\n          }\n      });\n      Object.defineProperty(c2d, 'lineCap', {\n          set: function set(val) {\n              this.setLineCap(val);\n          },\n          get: function get() {\n              return this.ctx.lineCap;\n          }\n      });\n      Object.defineProperty(c2d, 'lineJoin', {\n          set: function set(val) {\n              this.setLineJoin(val);\n          },\n          get: function get() {\n              return this.ctx.lineJoin;\n          }\n      });\n      Object.defineProperty(c2d, 'miterLimit', {\n          set: function set(val) {\n              this.ctx.miterLimit = val;\n          },\n          get: function get() {\n              return this.ctx.miterLimit;\n          }\n      });\n      Object.defineProperty(c2d, 'textBaseline', {\n          set: function set(value) {\n              this.setTextBaseline(value);\n          },\n          get: function get() {\n              return this.getTextBaseline();\n          }\n      });\n      Object.defineProperty(c2d, 'textAlign', {\n          set: function set(value) {\n              this.setTextAlign(value);\n          },\n          get: function get() {\n              return this.getTextAlign();\n          }\n      });\n      Object.defineProperty(c2d, 'font', {\n          set: function set(value) {\n              this.setFont(value);\n          },\n          get: function get() {\n              return this.ctx.font;\n          }\n      });\n      Object.defineProperty(c2d, 'globalCompositeOperation', {\n          set: function set(value) {\n              this.ctx.globalCompositeOperation = value;\n          },\n          get: function get() {\n              return this.ctx.globalCompositeOperation;\n          }\n      });\n      Object.defineProperty(c2d, 'globalAlpha', {\n          set: function set(value) {\n              this.ctx.globalAlpha = value;\n          },\n          get: function get() {\n              return this.ctx.globalAlpha;\n          }\n      });\n      Object.defineProperty(c2d, 'canvas', {\n          get: function get() {\n              return { parentNode: false, style: false };\n          }\n      });\n      // Not HTML API\n      Object.defineProperty(c2d, 'ignoreClearRect', {\n          set: function set(value) {\n              this.ctx.ignoreClearRect = value;\n          },\n          get: function get() {\n              return this.ctx.ignoreClearRect;\n          }\n      });\n      // End Not HTML API\n\n      c2d.internal = {};\n\n      c2d.internal.rxRgb = /rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)/;\n      c2d.internal.rxRgba = /rgba\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*([\\d\\.]+)\\s*\\)/;\n      c2d.internal.rxTransparent = /transparent|rgba\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*0+\\s*\\)/;\n\n      // http://hansmuller-flex.blogspot.com/2011/10/more-about-approximating-circular-arcs.html\n      c2d.internal.arc = function (c2d, xc, yc, r, a1, a2, anticlockwise, style) {\n\n          var k = this.pdf.internal.scaleFactor;\n          var pageHeight = this.pdf.internal.pageSize.getHeight();\n          var f2 = this.pdf.internal.f2;\n\n          var a1r = a1 * (Math.PI / 180);\n          var a2r = a2 * (Math.PI / 180);\n          var curves = this.createArc(r, a1r, a2r, anticlockwise);\n\n          for (var i = 0; i < curves.length; i++) {\n              var curve = curves[i];\n              if (i === 0) {\n                  this.pdf.internal.out([f2((curve.x1 + xc) * k), f2((pageHeight - (curve.y1 + yc)) * k), 'm', f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c'].join(' '));\n              } else {\n                  this.pdf.internal.out([f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c'].join(' '));\n              }\n\n              //c2d._lastPoint = {x: curve.x1 + xc, y: curve.y1 + yc};\n              c2d._lastPoint = { x: xc, y: yc };\n              // f2((curve.x1 + xc) * k), f2((pageHeight - (curve.y1 + yc)) * k), 'm', f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c'\n          }\n\n          if (style !== null) {\n              this.pdf.internal.out(this.pdf.internal.getStyle(style));\n          }\n      };\n\n      /**\n       *\n       * @param x Edge point X\n       * @param y Edge point Y\n       * @param r Radius\n       * @param a1 start angle\n       * @param a2 end angle\n       * @param anticlockwise\n       * @param style\n       * @param isClip\n       */\n      c2d.internal.arc2 = function (c2d, x, y, r, a1, a2, anticlockwise, style, isClip) {\n          // we need to convert from cartesian to polar here methinks.\n          var centerX = x; // + r;\n          var centerY = y;\n\n          if (!isClip) {\n              this.arc(c2d, centerX, centerY, r, a1, a2, anticlockwise, style);\n          } else {\n              this.arc(c2d, centerX, centerY, r, a1, a2, anticlockwise, null);\n              this.pdf.clip_fixed();\n          }\n      };\n\n      c2d.internal.move2 = function (c2d, x, y) {\n          var k = this.pdf.internal.scaleFactor;\n          var pageHeight = this.pdf.internal.pageSize.getHeight();\n          var f2 = this.pdf.internal.f2;\n\n          this.pdf.internal.out([f2(x * k), f2((pageHeight - y) * k), 'm'].join(' '));\n          c2d._lastPoint = { x: x, y: y };\n      };\n\n      c2d.internal.line2 = function (c2d, dx, dy) {\n          var k = this.pdf.internal.scaleFactor;\n          var pageHeight = this.pdf.internal.pageSize.getHeight();\n          var f2 = this.pdf.internal.f2;\n\n          //var pt = {x: c2d._lastPoint.x + dx, y: c2d._lastPoint.y + dy};\n          var pt = { x: dx, y: dy };\n\n          this.pdf.internal.out([f2(pt.x * k), f2((pageHeight - pt.y) * k), 'l'].join(' '));\n          //this.pdf.internal.out('f');\n          c2d._lastPoint = pt;\n      };\n\n      /**\n       * Return a array of objects that represent bezier curves which approximate the circular arc centered at the origin, from startAngle to endAngle (radians) with the specified radius.\n       *\n       * Each bezier curve is an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points.\n       */\n\n      c2d.internal.createArc = function (radius, startAngle, endAngle, anticlockwise) {\n          var EPSILON = 0.00001; // Roughly 1/1000th of a degree, see below\n          var twoPI = Math.PI * 2;\n          var piOverTwo = Math.PI / 2.0;\n\n          // normalize startAngle, endAngle to [0, 2PI]\n          var startAngleN = startAngle;\n          if (startAngleN < twoPI || startAngleN > twoPI) {\n              startAngleN = startAngleN % twoPI;\n          }\n          if (startAngleN < 0) {\n              startAngleN = twoPI + startAngleN;\n          }\n\n          while (startAngle > endAngle) {\n              startAngle = startAngle - twoPI;\n          }\n          var totalAngle = Math.abs(endAngle - startAngle);\n          if (totalAngle < twoPI) {\n              if (anticlockwise) {\n                  totalAngle = twoPI - totalAngle;\n              }\n          }\n\n          // Compute the sequence of arc curves, up to PI/2 at a time.\n          var curves = [];\n          var sgn = anticlockwise ? -1 : +1;\n\n          var a1 = startAngleN;\n          for (; totalAngle > EPSILON;) {\n              var remain = sgn * Math.min(totalAngle, piOverTwo);\n              var a2 = a1 + remain;\n              curves.push(this.createSmallArc(radius, a1, a2));\n              totalAngle -= Math.abs(a2 - a1);\n              a1 = a2;\n          }\n\n          return curves;\n      };\n\n      c2d.internal.getCurrentPage = function () {\n          return this.pdf.internal.pages[this.pdf.internal.getCurrentPageInfo().pageNumber];\n      };\n\n      /**\n       * Cubic bezier approximation of a circular arc centered at the origin, from (radians) a1 to a2, where a2-a1 < pi/2. The arc's radius is r.\n       *\n       * Returns an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points.\n       *\n       * This algorithm is based on the approach described in: A. Riškus, \"Approximation of a Cubic Bezier Curve by Circular Arcs and Vice Versa,\" Information Technology and Control, 35(4), 2006 pp. 371-378.\n       */\n\n      c2d.internal.createSmallArc = function (r, a1, a2) {\n          // Compute all four points for an arc that subtends the same total angle\n          // but is centered on the X-axis\n\n          var a = (a2 - a1) / 2.0;\n\n          var x4 = r * Math.cos(a);\n          var y4 = r * Math.sin(a);\n          var x1 = x4;\n          var y1 = -y4;\n\n          var q1 = x1 * x1 + y1 * y1;\n          var q2 = q1 + x1 * x4 + y1 * y4;\n          var k2 = 4 / 3 * (Math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4);\n\n          var x2 = x1 - k2 * y1;\n          var y2 = y1 + k2 * x1;\n          var x3 = x2;\n          var y3 = -y2;\n\n          // Find the arc points' actual locations by computing x1,y1 and x4,y4\n          // and rotating the control points by a + a1\n\n          var ar = a + a1;\n          var cos_ar = Math.cos(ar);\n          var sin_ar = Math.sin(ar);\n\n          return {\n              x1: r * Math.cos(a1),\n              y1: r * Math.sin(a1),\n              x2: x2 * cos_ar - y2 * sin_ar,\n              y2: x2 * sin_ar + y2 * cos_ar,\n              x3: x3 * cos_ar - y3 * sin_ar,\n              y3: x3 * sin_ar + y3 * cos_ar,\n              x4: r * Math.cos(a2),\n              y4: r * Math.sin(a2)\n          };\n      };\n\n      function context() {\n          this._isStrokeTransparent = false;\n          this._strokeOpacity = 1;\n          this.strokeStyle = '#000000';\n          this.fillStyle = '#000000';\n          this._isFillTransparent = false;\n          this._fillOpacity = 1;\n          this.font = \"12pt times\";\n          this.textBaseline = 'alphabetic'; // top,bottom,middle,ideographic,alphabetic,hanging\n          this.textAlign = 'start';\n          this.lineWidth = 1;\n          this.lineJoin = 'miter'; // round, bevel, miter\n          this.lineCap = 'butt'; // butt, round, square\n          this._transform = [1, 0, 0, 1, 0, 0]; // sx, shy, shx, sy, tx, ty\n          this.globalCompositeOperation = 'normal';\n          this.globalAlpha = 1.0;\n          this._clip_path = [];\n\n          // TODO miter limit //default 10\n\n          // Not HTML API\n          this.ignoreClearRect = false;\n\n          this.copy = function (ctx) {\n              this._isStrokeTransparent = ctx._isStrokeTransparent;\n              this._strokeOpacity = ctx._strokeOpacity;\n              this.strokeStyle = ctx.strokeStyle;\n              this._isFillTransparent = ctx._isFillTransparent;\n              this._fillOpacity = ctx._fillOpacity;\n              this.fillStyle = ctx.fillStyle;\n              this.font = ctx.font;\n              this.lineWidth = ctx.lineWidth;\n              this.lineJoin = ctx.lineJoin;\n              this.lineCap = ctx.lineCap;\n              this.textBaseline = ctx.textBaseline;\n              this.textAlign = ctx.textAlign;\n              this._fontSize = ctx._fontSize;\n              this._transform = ctx._transform.slice(0);\n              this.globalCompositeOperation = ctx.globalCompositeOperation;\n              this.globalAlpha = ctx.globalAlpha;\n              this._clip_path = ctx._clip_path.slice(0); //TODO deep copy?\n\n              // Not HTML API\n              this.ignoreClearRect = ctx.ignoreClearRect;\n          };\n      }\n\n      return this;\n  })(jsPDF.API, typeof self !== \"undefined\" && self || typeof window !== \"undefined\" && window || typeof global !== \"undefined\" && global || Function('return typeof this === \"object\" && this.content')() || Function('return this')());\n\n  /** @preserve\n   * jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser\n   * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com\n   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria\n   *               2014 Diego Casorran, https://github.com/diegocr\n   *               2014 Daniel Husar, https://github.com/danielhusar\n   *               2014 Wolfgang Gassler, https://github.com/woolfg\n   *               2014 Steven Spungin, https://github.com/flamenco\n   *\n   * \n   * ====================================================================\n   */\n\n  (function (jsPDFAPI) {\n  \tvar clone, _DrillForContent, FontNameDB, FontStyleMap, TextAlignMap, FontWeightMap, FloatMap, ClearMap, GetCSS, PurgeWhiteSpace, Renderer, ResolveFont, ResolveUnitedNumber, UnitedNumberMap, elementHandledElsewhere, images, loadImgs, checkForFooter, process, tableToJson;\n  \tclone = function () {\n  \t\treturn function (obj) {\n  \t\t\tClone.prototype = obj;\n  \t\t\treturn new Clone();\n  \t\t};\n  \t\tfunction Clone() {}\n  \t}();\n  \tPurgeWhiteSpace = function PurgeWhiteSpace(array) {\n  \t\tvar fragment, i, l, lTrimmed, r, rTrimmed, trailingSpace;\n  \t\ti = 0;\n  \t\tl = array.length;\n  \t\tfragment = void 0;\n  \t\tlTrimmed = false;\n  \t\trTrimmed = false;\n  \t\twhile (!lTrimmed && i !== l) {\n  \t\t\tfragment = array[i] = array[i].trimLeft();\n  \t\t\tif (fragment) {\n  \t\t\t\tlTrimmed = true;\n  \t\t\t}\n  \t\t\ti++;\n  \t\t}\n  \t\ti = l - 1;\n  \t\twhile (l && !rTrimmed && i !== -1) {\n  \t\t\tfragment = array[i] = array[i].trimRight();\n  \t\t\tif (fragment) {\n  \t\t\t\trTrimmed = true;\n  \t\t\t}\n  \t\t\ti--;\n  \t\t}\n  \t\tr = /\\s+$/g;\n  \t\ttrailingSpace = true;\n  \t\ti = 0;\n  \t\twhile (i !== l) {\n  \t\t\t// Leave the line breaks intact\n  \t\t\tif (array[i] != \"\\u2028\") {\n  \t\t\t\tfragment = array[i].replace(/\\s+/g, \" \");\n  \t\t\t\tif (trailingSpace) {\n  \t\t\t\t\tfragment = fragment.trimLeft();\n  \t\t\t\t}\n  \t\t\t\tif (fragment) {\n  \t\t\t\t\ttrailingSpace = r.test(fragment);\n  \t\t\t\t}\n  \t\t\t\tarray[i] = fragment;\n  \t\t\t}\n  \t\t\ti++;\n  \t\t}\n  \t\treturn array;\n  \t};\n  \tRenderer = function Renderer(pdf, x, y, settings) {\n  \t\tthis.pdf = pdf;\n  \t\tthis.x = x;\n  \t\tthis.y = y;\n  \t\tthis.settings = settings;\n  \t\t//list of functions which are called after each element-rendering process\n  \t\tthis.watchFunctions = [];\n  \t\tthis.init();\n  \t\treturn this;\n  \t};\n  \tResolveFont = function ResolveFont(css_font_family_string) {\n  \t\tvar name, part, parts;\n  \t\tname = void 0;\n  \t\tparts = css_font_family_string.split(\",\");\n  \t\tpart = parts.shift();\n  \t\twhile (!name && part) {\n  \t\t\tname = FontNameDB[part.trim().toLowerCase()];\n  \t\t\tpart = parts.shift();\n  \t\t}\n  \t\treturn name;\n  \t};\n  \tResolveUnitedNumber = function ResolveUnitedNumber(css_line_height_string) {\n\n  \t\t//IE8 issues\n  \t\tcss_line_height_string = css_line_height_string === \"auto\" ? \"0px\" : css_line_height_string;\n  \t\tif (css_line_height_string.indexOf(\"em\") > -1 && !isNaN(Number(css_line_height_string.replace(\"em\", \"\")))) {\n  \t\t\tcss_line_height_string = Number(css_line_height_string.replace(\"em\", \"\")) * 18.719 + \"px\";\n  \t\t}\n  \t\tif (css_line_height_string.indexOf(\"pt\") > -1 && !isNaN(Number(css_line_height_string.replace(\"pt\", \"\")))) {\n  \t\t\tcss_line_height_string = Number(css_line_height_string.replace(\"pt\", \"\")) * 1.333 + \"px\";\n  \t\t}\n\n  \t\tvar normal, undef, value;\n  \t\tundef = void 0;\n  \t\tnormal = 16.00;\n  \t\tvalue = UnitedNumberMap[css_line_height_string];\n  \t\tif (value) {\n  \t\t\treturn value;\n  \t\t}\n  \t\tvalue = {\n  \t\t\t\"xx-small\": 9,\n  \t\t\t\"x-small\": 11,\n  \t\t\tsmall: 13,\n  \t\t\tmedium: 16,\n  \t\t\tlarge: 19,\n  \t\t\t\"x-large\": 23,\n  \t\t\t\"xx-large\": 28,\n  \t\t\tauto: 0\n  \t\t}[css_line_height_string];\n\n  \t\tif (value !== undef) {\n  \t\t\treturn UnitedNumberMap[css_line_height_string] = value / normal;\n  \t\t}\n  \t\tif (value = parseFloat(css_line_height_string)) {\n  \t\t\treturn UnitedNumberMap[css_line_height_string] = value / normal;\n  \t\t}\n  \t\tvalue = css_line_height_string.match(/([\\d\\.]+)(px)/);\n  \t\tif (Array.isArray(value) && value.length === 3) {\n  \t\t\treturn UnitedNumberMap[css_line_height_string] = parseFloat(value[1]) / normal;\n  \t\t}\n  \t\treturn UnitedNumberMap[css_line_height_string] = 1;\n  \t};\n  \tGetCSS = function GetCSS(element) {\n  \t\tvar css, tmp, computedCSSElement;\n  \t\tcomputedCSSElement = function (el) {\n  \t\t\tvar compCSS;\n  \t\t\tcompCSS = function (el) {\n  \t\t\t\tif (document.defaultView && document.defaultView.getComputedStyle) {\n  \t\t\t\t\treturn document.defaultView.getComputedStyle(el, null);\n  \t\t\t\t} else if (el.currentStyle) {\n  \t\t\t\t\treturn el.currentStyle;\n  \t\t\t\t} else {\n  \t\t\t\t\treturn el.style;\n  \t\t\t\t}\n  \t\t\t}(el);\n  \t\t\treturn function (prop) {\n  \t\t\t\tprop = prop.replace(/-\\D/g, function (match) {\n  \t\t\t\t\treturn match.charAt(1).toUpperCase();\n  \t\t\t\t});\n  \t\t\t\treturn compCSS[prop];\n  \t\t\t};\n  \t\t}(element);\n  \t\tcss = {};\n  \t\ttmp = void 0;\n  \t\tcss[\"font-family\"] = ResolveFont(computedCSSElement(\"font-family\")) || \"times\";\n  \t\tcss[\"font-style\"] = FontStyleMap[computedCSSElement(\"font-style\")] || \"normal\";\n  \t\tcss[\"text-align\"] = TextAlignMap[computedCSSElement(\"text-align\")] || \"left\";\n  \t\ttmp = FontWeightMap[computedCSSElement(\"font-weight\")] || \"normal\";\n  \t\tif (tmp === \"bold\") {\n  \t\t\tif (css[\"font-style\"] === \"normal\") {\n  \t\t\t\tcss[\"font-style\"] = tmp;\n  \t\t\t} else {\n  \t\t\t\tcss[\"font-style\"] = tmp + css[\"font-style\"];\n  \t\t\t}\n  \t\t}\n  \t\tcss[\"font-size\"] = ResolveUnitedNumber(computedCSSElement(\"font-size\")) || 1;\n  \t\tcss[\"line-height\"] = ResolveUnitedNumber(computedCSSElement(\"line-height\")) || 1;\n  \t\tcss[\"display\"] = computedCSSElement(\"display\") === \"inline\" ? \"inline\" : \"block\";\n\n  \t\ttmp = css[\"display\"] === \"block\";\n  \t\tcss[\"margin-top\"] = tmp && ResolveUnitedNumber(computedCSSElement(\"margin-top\")) || 0;\n  \t\tcss[\"margin-bottom\"] = tmp && ResolveUnitedNumber(computedCSSElement(\"margin-bottom\")) || 0;\n  \t\tcss[\"padding-top\"] = tmp && ResolveUnitedNumber(computedCSSElement(\"padding-top\")) || 0;\n  \t\tcss[\"padding-bottom\"] = tmp && ResolveUnitedNumber(computedCSSElement(\"padding-bottom\")) || 0;\n  \t\tcss[\"margin-left\"] = tmp && ResolveUnitedNumber(computedCSSElement(\"margin-left\")) || 0;\n  \t\tcss[\"margin-right\"] = tmp && ResolveUnitedNumber(computedCSSElement(\"margin-right\")) || 0;\n  \t\tcss[\"padding-left\"] = tmp && ResolveUnitedNumber(computedCSSElement(\"padding-left\")) || 0;\n  \t\tcss[\"padding-right\"] = tmp && ResolveUnitedNumber(computedCSSElement(\"padding-right\")) || 0;\n\n  \t\tcss[\"page-break-before\"] = computedCSSElement(\"page-break-before\") || \"auto\";\n\n  \t\t//float and clearing of floats\n  \t\tcss[\"float\"] = FloatMap[computedCSSElement(\"cssFloat\")] || \"none\";\n  \t\tcss[\"clear\"] = ClearMap[computedCSSElement(\"clear\")] || \"none\";\n\n  \t\tcss[\"color\"] = computedCSSElement(\"color\");\n\n  \t\treturn css;\n  \t};\n  \telementHandledElsewhere = function elementHandledElsewhere(element, renderer, elementHandlers) {\n  \t\tvar handlers, i, isHandledElsewhere, l, classNames;\n  \t\tisHandledElsewhere = false;\n  \t\ti = void 0;\n  \t\tl = void 0;\n  \t\thandlers = elementHandlers[\"#\" + element.id];\n  \t\tif (handlers) {\n  \t\t\tif (typeof handlers === \"function\") {\n  \t\t\t\tisHandledElsewhere = handlers(element, renderer);\n  \t\t\t} else {\n  \t\t\t\ti = 0;\n  \t\t\t\tl = handlers.length;\n  \t\t\t\twhile (!isHandledElsewhere && i !== l) {\n  \t\t\t\t\tisHandledElsewhere = handlers[i](element, renderer);\n  \t\t\t\t\ti++;\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n  \t\thandlers = elementHandlers[element.nodeName];\n  \t\tif (!isHandledElsewhere && handlers) {\n  \t\t\tif (typeof handlers === \"function\") {\n  \t\t\t\tisHandledElsewhere = handlers(element, renderer);\n  \t\t\t} else {\n  \t\t\t\ti = 0;\n  \t\t\t\tl = handlers.length;\n  \t\t\t\twhile (!isHandledElsewhere && i !== l) {\n  \t\t\t\t\tisHandledElsewhere = handlers[i](element, renderer);\n  \t\t\t\t\ti++;\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n\n  \t\t// Try class names\n  \t\tclassNames = typeof element.className === 'string' ? element.className.split(' ') : [];\n  \t\tfor (i = 0; i < classNames.length; i++) {\n  \t\t\thandlers = elementHandlers['.' + classNames[i]];\n  \t\t\tif (!isHandledElsewhere && handlers) {\n  \t\t\t\tif (typeof handlers === \"function\") {\n  \t\t\t\t\tisHandledElsewhere = handlers(element, renderer);\n  \t\t\t\t} else {\n  \t\t\t\t\ti = 0;\n  \t\t\t\t\tl = handlers.length;\n  \t\t\t\t\twhile (!isHandledElsewhere && i !== l) {\n  \t\t\t\t\t\tisHandledElsewhere = handlers[i](element, renderer);\n  \t\t\t\t\t\ti++;\n  \t\t\t\t\t}\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n\n  \t\treturn isHandledElsewhere;\n  \t};\n  \ttableToJson = function tableToJson(table, renderer) {\n  \t\tvar data, headers, i, j, rowData, tableRow, table_obj, table_with, cell, l;\n  \t\tdata = [];\n  \t\theaders = [];\n  \t\ti = 0;\n  \t\tl = table.rows[0].cells.length;\n  \t\ttable_with = table.clientWidth;\n  \t\twhile (i < l) {\n  \t\t\tcell = table.rows[0].cells[i];\n  \t\t\theaders[i] = {\n  \t\t\t\tname: cell.textContent.toLowerCase().replace(/\\s+/g, ''),\n  \t\t\t\tprompt: cell.textContent.replace(/\\r?\\n/g, ''),\n  \t\t\t\twidth: cell.clientWidth / table_with * renderer.pdf.internal.pageSize.getWidth()\n  \t\t\t};\n  \t\t\ti++;\n  \t\t}\n  \t\ti = 1;\n  \t\twhile (i < table.rows.length) {\n  \t\t\ttableRow = table.rows[i];\n  \t\t\trowData = {};\n  \t\t\tj = 0;\n  \t\t\twhile (j < tableRow.cells.length) {\n  \t\t\t\trowData[headers[j].name] = tableRow.cells[j].textContent.replace(/\\r?\\n/g, '');\n  \t\t\t\tj++;\n  \t\t\t}\n  \t\t\tdata.push(rowData);\n  \t\t\ti++;\n  \t\t}\n  \t\treturn table_obj = {\n  \t\t\trows: data,\n  \t\t\theaders: headers\n  \t\t};\n  \t};\n  \tvar SkipNode = {\n  \t\tSCRIPT: 1,\n  \t\tSTYLE: 1,\n  \t\tNOSCRIPT: 1,\n  \t\tOBJECT: 1,\n  \t\tEMBED: 1,\n  \t\tSELECT: 1\n  \t};\n  \tvar listCount = 1;\n  \t_DrillForContent = function DrillForContent(element, renderer, elementHandlers) {\n  \t\tvar cn, cns, fragmentCSS, i, isBlock, l, table2json, cb;\n  \t\tcns = element.childNodes;\n  \t\tcn = void 0;\n  \t\tfragmentCSS = GetCSS(element);\n  \t\tisBlock = fragmentCSS.display === \"block\";\n  \t\tif (isBlock) {\n  \t\t\trenderer.setBlockBoundary();\n  \t\t\trenderer.setBlockStyle(fragmentCSS);\n  \t\t}\n  \t\ti = 0;\n  \t\tl = cns.length;\n  \t\twhile (i < l) {\n  \t\t\tcn = cns[i];\n  \t\t\tif ((typeof cn === \"undefined\" ? \"undefined\" : _typeof(cn)) === \"object\") {\n\n  \t\t\t\t//execute all watcher functions to e.g. reset floating\n  \t\t\t\trenderer.executeWatchFunctions(cn);\n\n  \t\t\t\t/*** HEADER rendering **/\n  \t\t\t\tif (cn.nodeType === 1 && cn.nodeName === 'HEADER') {\n  \t\t\t\t\tvar header = cn;\n  \t\t\t\t\t//store old top margin\n  \t\t\t\t\tvar oldMarginTop = renderer.pdf.margins_doc.top;\n  \t\t\t\t\t//subscribe for new page event and render header first on every page\n  \t\t\t\t\trenderer.pdf.internal.events.subscribe('addPage', function (pageInfo) {\n  \t\t\t\t\t\t//set current y position to old margin\n  \t\t\t\t\t\trenderer.y = oldMarginTop;\n  \t\t\t\t\t\t//render all child nodes of the header element\n  \t\t\t\t\t\t_DrillForContent(header, renderer, elementHandlers);\n  \t\t\t\t\t\t//set margin to old margin + rendered header + 10 space to prevent overlapping\n  \t\t\t\t\t\t//important for other plugins (e.g. table) to start rendering at correct position after header\n  \t\t\t\t\t\trenderer.pdf.margins_doc.top = renderer.y + 10;\n  \t\t\t\t\t\trenderer.y += 10;\n  \t\t\t\t\t}, false);\n  \t\t\t\t}\n\n  \t\t\t\tif (cn.nodeType === 8 && cn.nodeName === \"#comment\") {\n  \t\t\t\t\tif (~cn.textContent.indexOf(\"ADD_PAGE\")) {\n  \t\t\t\t\t\trenderer.pdf.addPage();\n  \t\t\t\t\t\trenderer.y = renderer.pdf.margins_doc.top;\n  \t\t\t\t\t}\n  \t\t\t\t} else if (cn.nodeType === 1 && !SkipNode[cn.nodeName]) {\n  \t\t\t\t\t/*** IMAGE RENDERING ***/\n  \t\t\t\t\tvar cached_image;\n  \t\t\t\t\tif (cn.nodeName === \"IMG\") {\n  \t\t\t\t\t\tvar url = cn.getAttribute(\"src\");\n  \t\t\t\t\t\tcached_image = images[renderer.pdf.sHashCode(url) || url];\n  \t\t\t\t\t}\n  \t\t\t\t\tif (cached_image) {\n  \t\t\t\t\t\tif (renderer.pdf.internal.pageSize.getHeight() - renderer.pdf.margins_doc.bottom < renderer.y + cn.height && renderer.y > renderer.pdf.margins_doc.top) {\n  \t\t\t\t\t\t\trenderer.pdf.addPage();\n  \t\t\t\t\t\t\trenderer.y = renderer.pdf.margins_doc.top;\n  \t\t\t\t\t\t\t//check if we have to set back some values due to e.g. header rendering for new page\n  \t\t\t\t\t\t\trenderer.executeWatchFunctions(cn);\n  \t\t\t\t\t\t}\n\n  \t\t\t\t\t\tvar imagesCSS = GetCSS(cn);\n  \t\t\t\t\t\tvar imageX = renderer.x;\n  \t\t\t\t\t\tvar fontToUnitRatio = 12 / renderer.pdf.internal.scaleFactor;\n\n  \t\t\t\t\t\t//define additional paddings, margins which have to be taken into account for margin calculations\n  \t\t\t\t\t\tvar additionalSpaceLeft = (imagesCSS[\"margin-left\"] + imagesCSS[\"padding-left\"]) * fontToUnitRatio;\n  \t\t\t\t\t\tvar additionalSpaceRight = (imagesCSS[\"margin-right\"] + imagesCSS[\"padding-right\"]) * fontToUnitRatio;\n  \t\t\t\t\t\tvar additionalSpaceTop = (imagesCSS[\"margin-top\"] + imagesCSS[\"padding-top\"]) * fontToUnitRatio;\n  \t\t\t\t\t\tvar additionalSpaceBottom = (imagesCSS[\"margin-bottom\"] + imagesCSS[\"padding-bottom\"]) * fontToUnitRatio;\n\n  \t\t\t\t\t\t//if float is set to right, move the image to the right border\n  \t\t\t\t\t\t//add space if margin is set\n  \t\t\t\t\t\tif (imagesCSS['float'] !== undefined && imagesCSS['float'] === 'right') {\n  \t\t\t\t\t\t\timageX += renderer.settings.width - cn.width - additionalSpaceRight;\n  \t\t\t\t\t\t} else {\n  \t\t\t\t\t\t\timageX += additionalSpaceLeft;\n  \t\t\t\t\t\t}\n\n  \t\t\t\t\t\trenderer.pdf.addImage(cached_image, imageX, renderer.y + additionalSpaceTop, cn.width, cn.height);\n  \t\t\t\t\t\tcached_image = undefined;\n  \t\t\t\t\t\t//if the float prop is specified we have to float the text around the image\n  \t\t\t\t\t\tif (imagesCSS['float'] === 'right' || imagesCSS['float'] === 'left') {\n  \t\t\t\t\t\t\t//add functiont to set back coordinates after image rendering\n  \t\t\t\t\t\t\trenderer.watchFunctions.push(function (diffX, thresholdY, diffWidth, el) {\n  \t\t\t\t\t\t\t\t//undo drawing box adaptions which were set by floating\n  \t\t\t\t\t\t\t\tif (renderer.y >= thresholdY) {\n  \t\t\t\t\t\t\t\t\trenderer.x += diffX;\n  \t\t\t\t\t\t\t\t\trenderer.settings.width += diffWidth;\n  \t\t\t\t\t\t\t\t\treturn true;\n  \t\t\t\t\t\t\t\t} else if (el && el.nodeType === 1 && !SkipNode[el.nodeName] && renderer.x + el.width > renderer.pdf.margins_doc.left + renderer.pdf.margins_doc.width) {\n  \t\t\t\t\t\t\t\t\trenderer.x += diffX;\n  \t\t\t\t\t\t\t\t\trenderer.y = thresholdY;\n  \t\t\t\t\t\t\t\t\trenderer.settings.width += diffWidth;\n  \t\t\t\t\t\t\t\t\treturn true;\n  \t\t\t\t\t\t\t\t} else {\n  \t\t\t\t\t\t\t\t\treturn false;\n  \t\t\t\t\t\t\t\t}\n  \t\t\t\t\t\t\t}.bind(this, imagesCSS['float'] === 'left' ? -cn.width - additionalSpaceLeft - additionalSpaceRight : 0, renderer.y + cn.height + additionalSpaceTop + additionalSpaceBottom, cn.width));\n  \t\t\t\t\t\t\t//reset floating by clear:both divs\n  \t\t\t\t\t\t\t//just set cursorY after the floating element\n  \t\t\t\t\t\t\trenderer.watchFunctions.push(function (yPositionAfterFloating, pages, el) {\n  \t\t\t\t\t\t\t\tif (renderer.y < yPositionAfterFloating && pages === renderer.pdf.internal.getNumberOfPages()) {\n  \t\t\t\t\t\t\t\t\tif (el.nodeType === 1 && GetCSS(el).clear === 'both') {\n  \t\t\t\t\t\t\t\t\t\trenderer.y = yPositionAfterFloating;\n  \t\t\t\t\t\t\t\t\t\treturn true;\n  \t\t\t\t\t\t\t\t\t} else {\n  \t\t\t\t\t\t\t\t\t\treturn false;\n  \t\t\t\t\t\t\t\t\t}\n  \t\t\t\t\t\t\t\t} else {\n  \t\t\t\t\t\t\t\t\treturn true;\n  \t\t\t\t\t\t\t\t}\n  \t\t\t\t\t\t\t}.bind(this, renderer.y + cn.height, renderer.pdf.internal.getNumberOfPages()));\n\n  \t\t\t\t\t\t\t//if floating is set we decrease the available width by the image width\n  \t\t\t\t\t\t\trenderer.settings.width -= cn.width + additionalSpaceLeft + additionalSpaceRight;\n  \t\t\t\t\t\t\t//if left just add the image width to the X coordinate\n  \t\t\t\t\t\t\tif (imagesCSS['float'] === 'left') {\n  \t\t\t\t\t\t\t\trenderer.x += cn.width + additionalSpaceLeft + additionalSpaceRight;\n  \t\t\t\t\t\t\t}\n  \t\t\t\t\t\t} else {\n  \t\t\t\t\t\t\t//if no floating is set, move the rendering cursor after the image height\n  \t\t\t\t\t\t\trenderer.y += cn.height + additionalSpaceTop + additionalSpaceBottom;\n  \t\t\t\t\t\t}\n\n  \t\t\t\t\t\t/*** TABLE RENDERING ***/\n  \t\t\t\t\t} else if (cn.nodeName === \"TABLE\") {\n  \t\t\t\t\t\ttable2json = tableToJson(cn, renderer);\n  \t\t\t\t\t\trenderer.y += 10;\n  \t\t\t\t\t\trenderer.pdf.table(renderer.x, renderer.y, table2json.rows, table2json.headers, {\n  \t\t\t\t\t\t\tautoSize: false,\n  \t\t\t\t\t\t\tprintHeaders: elementHandlers.printHeaders,\n  \t\t\t\t\t\t\tmargins: renderer.pdf.margins_doc,\n  \t\t\t\t\t\t\tcss: GetCSS(cn)\n  \t\t\t\t\t\t});\n  \t\t\t\t\t\trenderer.y = renderer.pdf.lastCellPos.y + renderer.pdf.lastCellPos.h + 20;\n  \t\t\t\t\t} else if (cn.nodeName === \"OL\" || cn.nodeName === \"UL\") {\n  \t\t\t\t\t\tlistCount = 1;\n  \t\t\t\t\t\tif (!elementHandledElsewhere(cn, renderer, elementHandlers)) {\n  \t\t\t\t\t\t\t_DrillForContent(cn, renderer, elementHandlers);\n  \t\t\t\t\t\t}\n  \t\t\t\t\t\trenderer.y += 10;\n  \t\t\t\t\t} else if (cn.nodeName === \"LI\") {\n  \t\t\t\t\t\tvar temp = renderer.x;\n  \t\t\t\t\t\trenderer.x += 20 / renderer.pdf.internal.scaleFactor;\n  \t\t\t\t\t\trenderer.y += 3;\n  \t\t\t\t\t\tif (!elementHandledElsewhere(cn, renderer, elementHandlers)) {\n  \t\t\t\t\t\t\t_DrillForContent(cn, renderer, elementHandlers);\n  \t\t\t\t\t\t}\n  \t\t\t\t\t\trenderer.x = temp;\n  \t\t\t\t\t} else if (cn.nodeName === \"BR\") {\n  \t\t\t\t\t\trenderer.y += fragmentCSS[\"font-size\"] * renderer.pdf.internal.scaleFactor;\n  \t\t\t\t\t\trenderer.addText(\"\\u2028\", clone(fragmentCSS));\n  \t\t\t\t\t} else {\n  \t\t\t\t\t\tif (!elementHandledElsewhere(cn, renderer, elementHandlers)) {\n  \t\t\t\t\t\t\t_DrillForContent(cn, renderer, elementHandlers);\n  \t\t\t\t\t\t}\n  \t\t\t\t\t}\n  \t\t\t\t} else if (cn.nodeType === 3) {\n  \t\t\t\t\tvar value = cn.nodeValue;\n  \t\t\t\t\tif (cn.nodeValue && cn.parentNode.nodeName === \"LI\") {\n  \t\t\t\t\t\tif (cn.parentNode.parentNode.nodeName === \"OL\") {\n  \t\t\t\t\t\t\tvalue = listCount++ + '. ' + value;\n  \t\t\t\t\t\t} else {\n  \t\t\t\t\t\t\tvar fontSize = fragmentCSS[\"font-size\"];\n  \t\t\t\t\t\t\tvar offsetX = (3 - fontSize * 0.75) * renderer.pdf.internal.scaleFactor;\n  \t\t\t\t\t\t\tvar offsetY = fontSize * 0.75 * renderer.pdf.internal.scaleFactor;\n  \t\t\t\t\t\t\tvar radius = fontSize * 1.74 / renderer.pdf.internal.scaleFactor;\n  \t\t\t\t\t\t\tcb = function cb(x, y) {\n  \t\t\t\t\t\t\t\tthis.pdf.circle(x + offsetX, y + offsetY, radius, 'FD');\n  \t\t\t\t\t\t\t};\n  \t\t\t\t\t\t}\n  \t\t\t\t\t}\n  \t\t\t\t\t// Only add the text if the text node is in the body element\n  \t\t\t\t\t// Add compatibility with IE11\n  \t\t\t\t\tif (!!(cn.ownerDocument.body.compareDocumentPosition(cn) & 16)) {\n  \t\t\t\t\t\trenderer.addText(value, fragmentCSS);\n  \t\t\t\t\t}\n  \t\t\t\t} else if (typeof cn === \"string\") {\n  \t\t\t\t\trenderer.addText(cn, fragmentCSS);\n  \t\t\t\t}\n  \t\t\t}\n  \t\t\ti++;\n  \t\t}\n  \t\telementHandlers.outY = renderer.y;\n\n  \t\tif (isBlock) {\n  \t\t\treturn renderer.setBlockBoundary(cb);\n  \t\t}\n  \t};\n  \timages = {};\n  \tloadImgs = function loadImgs(element, renderer, elementHandlers, cb) {\n  \t\tvar imgs = element.getElementsByTagName('img'),\n  \t\t    l = imgs.length,\n  \t\t    found_images,\n  \t\t    x = 0;\n  \t\tfunction done() {\n  \t\t\trenderer.pdf.internal.events.publish('imagesLoaded');\n  \t\t\tcb(found_images);\n  \t\t}\n  \t\tfunction loadImage(url, width, height) {\n  \t\t\tif (!url) return;\n  \t\t\tvar img = new Image();\n  \t\t\tfound_images = ++x;\n  \t\t\timg.crossOrigin = '';\n  \t\t\timg.onerror = img.onload = function () {\n  \t\t\t\tif (img.complete) {\n  \t\t\t\t\t//to support data urls in images, set width and height\n  \t\t\t\t\t//as those values are not recognized automatically\n  \t\t\t\t\tif (img.src.indexOf('data:image/') === 0) {\n  \t\t\t\t\t\timg.width = width || img.width || 0;\n  \t\t\t\t\t\timg.height = height || img.height || 0;\n  \t\t\t\t\t}\n  \t\t\t\t\t//if valid image add to known images array\n  \t\t\t\t\tif (img.width + img.height) {\n  \t\t\t\t\t\tvar hash = renderer.pdf.sHashCode(url) || url;\n  \t\t\t\t\t\timages[hash] = images[hash] || img;\n  \t\t\t\t\t}\n  \t\t\t\t}\n  \t\t\t\tif (! --x) {\n  \t\t\t\t\tdone();\n  \t\t\t\t}\n  \t\t\t};\n  \t\t\timg.src = url;\n  \t\t}\n  \t\twhile (l--) {\n  \t\t\tloadImage(imgs[l].getAttribute(\"src\"), imgs[l].width, imgs[l].height);\n  \t\t}return x || done();\n  \t};\n  \tcheckForFooter = function checkForFooter(elem, renderer, elementHandlers) {\n  \t\t//check if we can found a <footer> element\n  \t\tvar footer = elem.getElementsByTagName(\"footer\");\n  \t\tif (footer.length > 0) {\n\n  \t\t\tfooter = footer[0];\n\n  \t\t\t//bad hack to get height of footer\n  \t\t\t//creat dummy out and check new y after fake rendering\n  \t\t\tvar oldOut = renderer.pdf.internal.write;\n  \t\t\tvar oldY = renderer.y;\n  \t\t\trenderer.pdf.internal.write = function () {};\n  \t\t\t_DrillForContent(footer, renderer, elementHandlers);\n  \t\t\tvar footerHeight = Math.ceil(renderer.y - oldY) + 5;\n  \t\t\trenderer.y = oldY;\n  \t\t\trenderer.pdf.internal.write = oldOut;\n\n  \t\t\t//add 20% to prevent overlapping\n  \t\t\trenderer.pdf.margins_doc.bottom += footerHeight;\n\n  \t\t\t//Create function render header on every page\n  \t\t\tvar renderFooter = function renderFooter(pageInfo) {\n  \t\t\t\tvar pageNumber = pageInfo !== undefined ? pageInfo.pageNumber : 1;\n  \t\t\t\t//set current y position to old margin\n  \t\t\t\tvar oldPosition = renderer.y;\n  \t\t\t\t//render all child nodes of the header element\n  \t\t\t\trenderer.y = renderer.pdf.internal.pageSize.getHeight() - renderer.pdf.margins_doc.bottom;\n  \t\t\t\trenderer.pdf.margins_doc.bottom -= footerHeight;\n\n  \t\t\t\t//check if we have to add page numbers\n  \t\t\t\tvar spans = footer.getElementsByTagName('span');\n  \t\t\t\tfor (var i = 0; i < spans.length; ++i) {\n  \t\t\t\t\t//if we find some span element with class pageCounter, set the page\n  \t\t\t\t\tif ((\" \" + spans[i].className + \" \").replace(/[\\n\\t]/g, \" \").indexOf(\" pageCounter \") > -1) {\n  \t\t\t\t\t\tspans[i].innerHTML = pageNumber;\n  \t\t\t\t\t}\n  \t\t\t\t\t//if we find some span element with class totalPages, set a variable which is replaced after rendering of all pages\n  \t\t\t\t\tif ((\" \" + spans[i].className + \" \").replace(/[\\n\\t]/g, \" \").indexOf(\" totalPages \") > -1) {\n  \t\t\t\t\t\tspans[i].innerHTML = '###jsPDFVarTotalPages###';\n  \t\t\t\t\t}\n  \t\t\t\t}\n\n  \t\t\t\t//render footer content\n  \t\t\t\t_DrillForContent(footer, renderer, elementHandlers);\n  \t\t\t\t//set bottom margin to previous height including the footer height\n  \t\t\t\trenderer.pdf.margins_doc.bottom += footerHeight;\n  \t\t\t\t//important for other plugins (e.g. table) to start rendering at correct position after header\n  \t\t\t\trenderer.y = oldPosition;\n  \t\t\t};\n\n  \t\t\t//check if footer contains totalPages which should be replace at the disoposal of the document\n  \t\t\tvar spans = footer.getElementsByTagName('span');\n  \t\t\tfor (var i = 0; i < spans.length; ++i) {\n  \t\t\t\tif ((\" \" + spans[i].className + \" \").replace(/[\\n\\t]/g, \" \").indexOf(\" totalPages \") > -1) {\n  \t\t\t\t\trenderer.pdf.internal.events.subscribe('htmlRenderingFinished', renderer.pdf.putTotalPages.bind(renderer.pdf, '###jsPDFVarTotalPages###'), true);\n  \t\t\t\t}\n  \t\t\t}\n\n  \t\t\t//register event to render footer on every new page\n  \t\t\trenderer.pdf.internal.events.subscribe('addPage', renderFooter, false);\n  \t\t\t//render footer on first page\n  \t\t\trenderFooter();\n\n  \t\t\t//prevent footer rendering\n  \t\t\tSkipNode['FOOTER'] = 1;\n  \t\t}\n  \t};\n  \tprocess = function process(pdf, element, x, y, settings, callback) {\n  \t\tif (!element) return false;\n  \t\tif (typeof element !== \"string\" && !element.parentNode) element = '' + element.innerHTML;\n  \t\tif (typeof element === \"string\") {\n  \t\t\telement = function (element) {\n  \t\t\t\tvar $frame, $hiddendiv, framename, visuallyhidden;\n  \t\t\t\tframename = \"jsPDFhtmlText\" + Date.now().toString() + (Math.random() * 1000).toFixed(0);\n  \t\t\t\tvisuallyhidden = \"position: absolute !important;\" + \"clip: rect(1px 1px 1px 1px); /* IE6, IE7 */\" + \"clip: rect(1px, 1px, 1px, 1px);\" + \"padding:0 !important;\" + \"border:0 !important;\" + \"height: 1px !important;\" + \"width: 1px !important; \" + \"top:auto;\" + \"left:-100px;\" + \"overflow: hidden;\";\n  \t\t\t\t$hiddendiv = document.createElement('div');\n  \t\t\t\t$hiddendiv.style.cssText = visuallyhidden;\n  \t\t\t\t$hiddendiv.innerHTML = \"<iframe style=\\\"height:1px;width:1px\\\" name=\\\"\" + framename + \"\\\" />\";\n  \t\t\t\tdocument.body.appendChild($hiddendiv);\n  \t\t\t\t$frame = window.frames[framename];\n  \t\t\t\t$frame.document.open();\n  \t\t\t\t$frame.document.writeln(element);\n  \t\t\t\t$frame.document.close();\n  \t\t\t\treturn $frame.document.body;\n  \t\t\t}(element.replace(/<\\/?script[^>]*?>/gi, ''));\n  \t\t}\n  \t\tvar r = new Renderer(pdf, x, y, settings),\n  \t\t    out;\n\n  \t\t// 1. load images\n  \t\t// 2. prepare optional footer elements\n  \t\t// 3. render content\n  \t\tloadImgs.call(this, element, r, settings.elementHandlers, function (found_images) {\n  \t\t\tcheckForFooter(element, r, settings.elementHandlers);\n  \t\t\t_DrillForContent(element, r, settings.elementHandlers);\n  \t\t\t//send event dispose for final taks (e.g. footer totalpage replacement)\n  \t\t\tr.pdf.internal.events.publish('htmlRenderingFinished');\n  \t\t\tout = r.dispose();\n  \t\t\tif (typeof callback === 'function') callback(out);else if (found_images) console.error('jsPDF Warning: rendering issues? provide a callback to fromHTML!');\n  \t\t});\n  \t\treturn out || { x: r.x, y: r.y };\n  \t};\n  \tRenderer.prototype.init = function () {\n  \t\tthis.paragraph = {\n  \t\t\ttext: [],\n  \t\t\tstyle: []\n  \t\t};\n  \t\treturn this.pdf.internal.write(\"q\");\n  \t};\n  \tRenderer.prototype.dispose = function () {\n  \t\tthis.pdf.internal.write(\"Q\");\n  \t\treturn {\n  \t\t\tx: this.x,\n  \t\t\ty: this.y,\n  \t\t\tready: true\n  \t\t};\n  \t};\n\n  \t//Checks if we have to execute some watcher functions\n  \t//e.g. to end text floating around an image\n  \tRenderer.prototype.executeWatchFunctions = function (el) {\n  \t\tvar ret = false;\n  \t\tvar narray = [];\n  \t\tif (this.watchFunctions.length > 0) {\n  \t\t\tfor (var i = 0; i < this.watchFunctions.length; ++i) {\n  \t\t\t\tif (this.watchFunctions[i](el) === true) {\n  \t\t\t\t\tret = true;\n  \t\t\t\t} else {\n  \t\t\t\t\tnarray.push(this.watchFunctions[i]);\n  \t\t\t\t}\n  \t\t\t}\n  \t\t\tthis.watchFunctions = narray;\n  \t\t}\n  \t\treturn ret;\n  \t};\n\n  \tRenderer.prototype.splitFragmentsIntoLines = function (fragments, styles) {\n  \t\tvar currentLineLength, defaultFontSize, ff, fontMetrics, fontMetricsCache, fragment, fragmentChopped, fragmentLength, fragmentSpecificMetrics, fs, k, line, lines, maxLineLength, style;\n  \t\tdefaultFontSize = 12;\n  \t\tk = this.pdf.internal.scaleFactor;\n  \t\tfontMetricsCache = {};\n  \t\tff = void 0;\n  \t\tfs = void 0;\n  \t\tfontMetrics = void 0;\n  \t\tfragment = void 0;\n  \t\tstyle = void 0;\n  \t\tfragmentSpecificMetrics = void 0;\n  \t\tfragmentLength = void 0;\n  \t\tfragmentChopped = void 0;\n  \t\tline = [];\n  \t\tlines = [line];\n  \t\tcurrentLineLength = 0;\n  \t\tmaxLineLength = this.settings.width;\n  \t\twhile (fragments.length) {\n  \t\t\tfragment = fragments.shift();\n  \t\t\tstyle = styles.shift();\n  \t\t\tif (fragment) {\n  \t\t\t\tff = style[\"font-family\"];\n  \t\t\t\tfs = style[\"font-style\"];\n  \t\t\t\tfontMetrics = fontMetricsCache[ff + fs];\n  \t\t\t\tif (!fontMetrics) {\n  \t\t\t\t\tfontMetrics = this.pdf.internal.getFont(ff, fs).metadata.Unicode;\n  \t\t\t\t\tfontMetricsCache[ff + fs] = fontMetrics;\n  \t\t\t\t}\n  \t\t\t\tfragmentSpecificMetrics = {\n  \t\t\t\t\twidths: fontMetrics.widths,\n  \t\t\t\t\tkerning: fontMetrics.kerning,\n  \t\t\t\t\tfontSize: style[\"font-size\"] * defaultFontSize,\n  \t\t\t\t\ttextIndent: currentLineLength\n  \t\t\t\t};\n  \t\t\t\tfragmentLength = this.pdf.getStringUnitWidth(fragment, fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k;\n  \t\t\t\tif (fragment == \"\\u2028\") {\n  \t\t\t\t\tline = [];\n  \t\t\t\t\tlines.push(line);\n  \t\t\t\t} else if (currentLineLength + fragmentLength > maxLineLength) {\n  \t\t\t\t\tfragmentChopped = this.pdf.splitTextToSize(fragment, maxLineLength, fragmentSpecificMetrics);\n  \t\t\t\t\tline.push([fragmentChopped.shift(), style]);\n  \t\t\t\t\twhile (fragmentChopped.length) {\n  \t\t\t\t\t\tline = [[fragmentChopped.shift(), style]];\n  \t\t\t\t\t\tlines.push(line);\n  \t\t\t\t\t}\n  \t\t\t\t\tcurrentLineLength = this.pdf.getStringUnitWidth(line[0][0], fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k;\n  \t\t\t\t} else {\n  \t\t\t\t\tline.push([fragment, style]);\n  \t\t\t\t\tcurrentLineLength += fragmentLength;\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n\n  \t\t//if text alignment was set, set margin/indent of each line\n  \t\tif (style['text-align'] !== undefined && (style['text-align'] === 'center' || style['text-align'] === 'right' || style['text-align'] === 'justify')) {\n  \t\t\tfor (var i = 0; i < lines.length; ++i) {\n  \t\t\t\tvar length = this.pdf.getStringUnitWidth(lines[i][0][0], fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k;\n  \t\t\t\t//if there is more than on line we have to clone the style object as all lines hold a reference on this object\n  \t\t\t\tif (i > 0) {\n  \t\t\t\t\tlines[i][0][1] = clone(lines[i][0][1]);\n  \t\t\t\t}\n  \t\t\t\tvar space = maxLineLength - length;\n\n  \t\t\t\tif (style['text-align'] === 'right') {\n  \t\t\t\t\tlines[i][0][1]['margin-left'] = space;\n  \t\t\t\t\t//if alignment is not right, it has to be center so split the space to the left and the right\n  \t\t\t\t} else if (style['text-align'] === 'center') {\n  \t\t\t\t\tlines[i][0][1]['margin-left'] = space / 2;\n  \t\t\t\t\t//if justify was set, calculate the word spacing and define in by using the css property\n  \t\t\t\t} else if (style['text-align'] === 'justify') {\n  \t\t\t\t\tvar countSpaces = lines[i][0][0].split(' ').length - 1;\n  \t\t\t\t\tlines[i][0][1]['word-spacing'] = space / countSpaces;\n  \t\t\t\t\t//ignore the last line in justify mode\n  \t\t\t\t\tif (i === lines.length - 1) {\n  \t\t\t\t\t\tlines[i][0][1]['word-spacing'] = 0;\n  \t\t\t\t\t}\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n\n  \t\treturn lines;\n  \t};\n  \tRenderer.prototype.RenderTextFragment = function (text, style) {\n  \t\tvar defaultFontSize, font, maxLineHeight;\n\n  \t\tmaxLineHeight = 0;\n  \t\tdefaultFontSize = 12;\n\n  \t\tif (this.pdf.internal.pageSize.getHeight() - this.pdf.margins_doc.bottom < this.y + this.pdf.internal.getFontSize()) {\n  \t\t\tthis.pdf.internal.write(\"ET\", \"Q\");\n  \t\t\tthis.pdf.addPage();\n  \t\t\tthis.y = this.pdf.margins_doc.top;\n  \t\t\tthis.pdf.internal.write(\"q\", \"BT\", this.getPdfColor(style.color), this.pdf.internal.getCoordinateString(this.x), this.pdf.internal.getVerticalCoordinateString(this.y), \"Td\");\n  \t\t\t//move cursor by one line on new page\n  \t\t\tmaxLineHeight = Math.max(maxLineHeight, style[\"line-height\"], style[\"font-size\"]);\n  \t\t\tthis.pdf.internal.write(0, (-1 * defaultFontSize * maxLineHeight).toFixed(2), \"Td\");\n  \t\t}\n\n  \t\tfont = this.pdf.internal.getFont(style[\"font-family\"], style[\"font-style\"]);\n\n  \t\t// text color\n  \t\tvar pdfTextColor = this.getPdfColor(style[\"color\"]);\n  \t\tif (pdfTextColor !== this.lastTextColor) {\n  \t\t\tthis.pdf.internal.write(pdfTextColor);\n  \t\t\tthis.lastTextColor = pdfTextColor;\n  \t\t}\n\n  \t\t//set the word spacing for e.g. justify style\n  \t\tif (style['word-spacing'] !== undefined && style['word-spacing'] > 0) {\n  \t\t\tthis.pdf.internal.write(style['word-spacing'].toFixed(2), \"Tw\");\n  \t\t}\n\n  \t\tthis.pdf.internal.write(\"/\" + font.id, (defaultFontSize * style[\"font-size\"]).toFixed(2), \"Tf\", \"(\" + this.pdf.internal.pdfEscape(text) + \") Tj\");\n\n  \t\t//set the word spacing back to neutral => 0\n  \t\tif (style['word-spacing'] !== undefined) {\n  \t\t\tthis.pdf.internal.write(0, \"Tw\");\n  \t\t}\n  \t};\n\n  \t// Accepts #FFFFFF, rgb(int,int,int), or CSS Color Name\n  \tRenderer.prototype.getPdfColor = function (style) {\n  \t\tvar textColor;\n  \t\tvar r, g, b;\n\n  \t\tvar rgbColor = new RGBColor(style);\n  \t\tvar rx = /rgb\\s*\\(\\s*(\\d+),\\s*(\\d+),\\s*(\\d+\\s*)\\)/;\n  \t\tvar m = rx.exec(style);\n  \t\tif (m != null) {\n  \t\t\tr = parseInt(m[1]);\n  \t\t\tg = parseInt(m[2]);\n  \t\t\tb = parseInt(m[3]);\n  \t\t} else {\n  \t\t\tif (style.charAt(0) != '#') {\n  \t\t\t\tif (rgbColor.ok) {\n  \t\t\t\t\tstyle = rgbColor.toHex();\n  \t\t\t\t} else {\n  \t\t\t\t\tstyle = '#000000';\n  \t\t\t\t}\n  \t\t\t}\n  \t\t\tr = style.substring(1, 3);\n  \t\t\tr = parseInt(r, 16);\n  \t\t\tg = style.substring(3, 5);\n  \t\t\tg = parseInt(g, 16);\n  \t\t\tb = style.substring(5, 7);\n  \t\t\tb = parseInt(b, 16);\n  \t\t}\n\n  \t\tif (typeof r === 'string' && /^#[0-9A-Fa-f]{6}$/.test(r)) {\n  \t\t\tvar hex = parseInt(r.substr(1), 16);\n  \t\t\tr = hex >> 16 & 255;\n  \t\t\tg = hex >> 8 & 255;\n  \t\t\tb = hex & 255;\n  \t\t}\n\n  \t\tvar f3 = this.f3;\n  \t\tif (r === 0 && g === 0 && b === 0 || typeof g === 'undefined') {\n  \t\t\ttextColor = f3(r / 255) + ' g';\n  \t\t} else {\n  \t\t\ttextColor = [f3(r / 255), f3(g / 255), f3(b / 255), 'rg'].join(' ');\n  \t\t}\n  \t\treturn textColor;\n  \t};\n\n  \tRenderer.prototype.f3 = function (number) {\n  \t\treturn number.toFixed(3); // Ie, %.3f\n  \t}, Renderer.prototype.renderParagraph = function (cb) {\n  \t\tvar blockstyle, defaultFontSize, fontToUnitRatio, fragments, i, l, line, lines, maxLineHeight, out, paragraphspacing_after, paragraphspacing_before, priorblockstyle, styles, fontSize;\n  \t\tfragments = PurgeWhiteSpace(this.paragraph.text);\n  \t\tstyles = this.paragraph.style;\n  \t\tblockstyle = this.paragraph.blockstyle;\n  \t\tpriorblockstyle = this.paragraph.priorblockstyle || {};\n  \t\tthis.paragraph = {\n  \t\t\ttext: [],\n  \t\t\tstyle: [],\n  \t\t\tblockstyle: {},\n  \t\t\tpriorblockstyle: blockstyle\n  \t\t};\n  \t\tif (!fragments.join(\"\").trim()) {\n  \t\t\treturn;\n  \t\t}\n  \t\tlines = this.splitFragmentsIntoLines(fragments, styles);\n  \t\tline = void 0;\n  \t\tmaxLineHeight = void 0;\n  \t\tdefaultFontSize = 12;\n  \t\tfontToUnitRatio = defaultFontSize / this.pdf.internal.scaleFactor;\n  \t\tthis.priorMarginBottom = this.priorMarginBottom || 0;\n  \t\tparagraphspacing_before = (Math.max((blockstyle[\"margin-top\"] || 0) - this.priorMarginBottom, 0) + (blockstyle[\"padding-top\"] || 0)) * fontToUnitRatio;\n  \t\tparagraphspacing_after = ((blockstyle[\"margin-bottom\"] || 0) + (blockstyle[\"padding-bottom\"] || 0)) * fontToUnitRatio;\n  \t\tthis.priorMarginBottom = blockstyle[\"margin-bottom\"] || 0;\n\n  \t\tif (blockstyle['page-break-before'] === 'always') {\n  \t\t\tthis.pdf.addPage();\n  \t\t\tthis.y = 0;\n  \t\t\tparagraphspacing_before = ((blockstyle[\"margin-top\"] || 0) + (blockstyle[\"padding-top\"] || 0)) * fontToUnitRatio;\n  \t\t}\n\n  \t\tout = this.pdf.internal.write;\n  \t\ti = void 0;\n  \t\tl = void 0;\n  \t\tthis.y += paragraphspacing_before;\n  \t\tout(\"q\", \"BT 0 g\", this.pdf.internal.getCoordinateString(this.x), this.pdf.internal.getVerticalCoordinateString(this.y), \"Td\");\n\n  \t\t//stores the current indent of cursor position\n  \t\tvar currentIndent = 0;\n\n  \t\twhile (lines.length) {\n  \t\t\tline = lines.shift();\n  \t\t\tmaxLineHeight = 0;\n  \t\t\ti = 0;\n  \t\t\tl = line.length;\n  \t\t\twhile (i !== l) {\n  \t\t\t\tif (line[i][0].trim()) {\n  \t\t\t\t\tmaxLineHeight = Math.max(maxLineHeight, line[i][1][\"line-height\"], line[i][1][\"font-size\"]);\n  \t\t\t\t\tfontSize = line[i][1][\"font-size\"] * 7;\n  \t\t\t\t}\n  \t\t\t\ti++;\n  \t\t\t}\n  \t\t\t//if we have to move the cursor to adapt the indent\n  \t\t\tvar indentMove = 0;\n  \t\t\tvar wantedIndent = 0;\n  \t\t\t//if a margin was added (by e.g. a text-alignment), move the cursor\n  \t\t\tif (line[0][1][\"margin-left\"] !== undefined && line[0][1][\"margin-left\"] > 0) {\n  \t\t\t\twantedIndent = this.pdf.internal.getCoordinateString(line[0][1][\"margin-left\"]);\n  \t\t\t\tindentMove = wantedIndent - currentIndent;\n  \t\t\t\tcurrentIndent = wantedIndent;\n  \t\t\t}\n  \t\t\tvar indentMore = Math.max(blockstyle[\"margin-left\"] || 0, 0) * fontToUnitRatio;\n  \t\t\t//move the cursor\n  \t\t\tout(indentMove + indentMore, (-1 * defaultFontSize * maxLineHeight).toFixed(2), \"Td\");\n  \t\t\ti = 0;\n  \t\t\tl = line.length;\n  \t\t\twhile (i !== l) {\n  \t\t\t\tif (line[i][0]) {\n  \t\t\t\t\tthis.RenderTextFragment(line[i][0], line[i][1]);\n  \t\t\t\t}\n  \t\t\t\ti++;\n  \t\t\t}\n  \t\t\tthis.y += maxLineHeight * fontToUnitRatio;\n\n  \t\t\t//if some watcher function was executed successful, so e.g. margin and widths were changed,\n  \t\t\t//reset line drawing and calculate position and lines again\n  \t\t\t//e.g. to stop text floating around an image\n  \t\t\tif (this.executeWatchFunctions(line[0][1]) && lines.length > 0) {\n  \t\t\t\tvar localFragments = [];\n  \t\t\t\tvar localStyles = [];\n  \t\t\t\t//create fragment array of\n  \t\t\t\tlines.forEach(function (localLine) {\n  \t\t\t\t\tvar i = 0;\n  \t\t\t\t\tvar l = localLine.length;\n  \t\t\t\t\twhile (i !== l) {\n  \t\t\t\t\t\tif (localLine[i][0]) {\n  \t\t\t\t\t\t\tlocalFragments.push(localLine[i][0] + ' ');\n  \t\t\t\t\t\t\tlocalStyles.push(localLine[i][1]);\n  \t\t\t\t\t\t}\n  \t\t\t\t\t\t++i;\n  \t\t\t\t\t}\n  \t\t\t\t});\n  \t\t\t\t//split lines again due to possible coordinate changes\n  \t\t\t\tlines = this.splitFragmentsIntoLines(PurgeWhiteSpace(localFragments), localStyles);\n  \t\t\t\t//reposition the current cursor\n  \t\t\t\tout(\"ET\", \"Q\");\n  \t\t\t\tout(\"q\", \"BT 0 g\", this.pdf.internal.getCoordinateString(this.x), this.pdf.internal.getVerticalCoordinateString(this.y), \"Td\");\n  \t\t\t}\n  \t\t}\n  \t\tif (cb && typeof cb === \"function\") {\n  \t\t\tcb.call(this, this.x - 9, this.y - fontSize / 2);\n  \t\t}\n  \t\tout(\"ET\", \"Q\");\n  \t\treturn this.y += paragraphspacing_after;\n  \t};\n  \tRenderer.prototype.setBlockBoundary = function (cb) {\n  \t\treturn this.renderParagraph(cb);\n  \t};\n  \tRenderer.prototype.setBlockStyle = function (css) {\n  \t\treturn this.paragraph.blockstyle = css;\n  \t};\n  \tRenderer.prototype.addText = function (text, css) {\n  \t\tthis.paragraph.text.push(text);\n  \t\treturn this.paragraph.style.push(css);\n  \t};\n  \tFontNameDB = {\n  \t\thelvetica: \"helvetica\",\n  \t\t\"sans-serif\": \"helvetica\",\n  \t\t\"times new roman\": \"times\",\n  \t\tserif: \"times\",\n  \t\ttimes: \"times\",\n  \t\tmonospace: \"courier\",\n  \t\tcourier: \"courier\"\n  \t};\n  \tFontWeightMap = {\n  \t\t100: \"normal\",\n  \t\t200: \"normal\",\n  \t\t300: \"normal\",\n  \t\t400: \"normal\",\n  \t\t500: \"bold\",\n  \t\t600: \"bold\",\n  \t\t700: \"bold\",\n  \t\t800: \"bold\",\n  \t\t900: \"bold\",\n  \t\tnormal: \"normal\",\n  \t\tbold: \"bold\",\n  \t\tbolder: \"bold\",\n  \t\tlighter: \"normal\"\n  \t};\n  \tFontStyleMap = {\n  \t\tnormal: \"normal\",\n  \t\titalic: \"italic\",\n  \t\toblique: \"italic\"\n  \t};\n  \tTextAlignMap = {\n  \t\tleft: \"left\",\n  \t\tright: \"right\",\n  \t\tcenter: \"center\",\n  \t\tjustify: \"justify\"\n  \t};\n  \tFloatMap = {\n  \t\tnone: 'none',\n  \t\tright: 'right',\n  \t\tleft: 'left'\n  \t};\n  \tClearMap = {\n  \t\tnone: 'none',\n  \t\tboth: 'both'\n  \t};\n  \tUnitedNumberMap = {\n  \t\tnormal: 1\n  \t};\n  \t/**\n    * Converts HTML-formatted text into formatted PDF text.\n    *\n    * Notes:\n    * 2012-07-18\n    * Plugin relies on having browser, DOM around. The HTML is pushed into dom and traversed.\n    * Plugin relies on jQuery for CSS extraction.\n    * Targeting HTML output from Markdown templating, which is a very simple\n    * markup - div, span, em, strong, p. No br-based paragraph separation supported explicitly (but still may work.)\n    * Images, tables are NOT supported.\n    *\n    * @public\n    * @function\n    * @param HTML {String or DOM Element} HTML-formatted text, or pointer to DOM element that is to be rendered into PDF.\n    * @param x {Number} starting X coordinate in jsPDF instance's declared units.\n    * @param y {Number} starting Y coordinate in jsPDF instance's declared units.\n    * @param settings {Object} Additional / optional variables controlling parsing, rendering.\n    * @returns {Object} jsPDF instance\n    */\n  \tjsPDFAPI.fromHTML = function (HTML, x, y, settings, callback, margins) {\n\n  \t\tthis.margins_doc = margins || {\n  \t\t\ttop: 0,\n  \t\t\tbottom: 0\n  \t\t};\n  \t\tif (!settings) settings = {};\n  \t\tif (!settings.elementHandlers) settings.elementHandlers = {};\n\n  \t\treturn process(this, HTML, isNaN(x) ? 4 : x, isNaN(y) ? 4 : y, settings, callback);\n  \t};\n  })(jsPDF.API);\n\n  /** ==================================================================== \n   * jsPDF JavaScript plugin\n   * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com\n   * \n   * \n   * ====================================================================\n   */\n\n  /*global jsPDF */\n\n  (function (jsPDFAPI) {\n\n      var jsNamesObj, jsJsObj, text;\n      jsPDFAPI.addJS = function (txt) {\n          text = txt;\n          this.internal.events.subscribe('postPutResources', function (txt) {\n              jsNamesObj = this.internal.newObject();\n              this.internal.out('<<');\n              this.internal.out('/Names [(EmbeddedJS) ' + (jsNamesObj + 1) + ' 0 R]');\n              this.internal.out('>>');\n              this.internal.out('endobj');\n\n              jsJsObj = this.internal.newObject();\n              this.internal.out('<<');\n              this.internal.out('/S /JavaScript');\n              this.internal.out('/JS (' + text + ')');\n              this.internal.out('>>');\n              this.internal.out('endobj');\n          });\n          this.internal.events.subscribe('putCatalog', function () {\n              if (jsNamesObj !== undefined && jsJsObj !== undefined) {\n                  this.internal.out('/Names <</JavaScript ' + jsNamesObj + ' 0 R>>');\n              }\n          });\n          return this;\n      };\n  })(jsPDF.API);\n\n  /**\n   * jsPDF Outline PlugIn\n   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n  (function (jsPDFAPI) {\n\n  \tjsPDFAPI.events.push(['postPutResources', function () {\n  \t\tvar pdf = this;\n  \t\tvar rx = /^(\\d+) 0 obj$/;\n\n  \t\t// Write action goto objects for each page\n  \t\t// this.outline.destsGoto = [];\n  \t\t// for (var i = 0; i < totalPages; i++) {\n  \t\t// var id = pdf.internal.newObject();\n  \t\t// this.outline.destsGoto.push(id);\n  \t\t// pdf.internal.write(\"<</D[\" + (i * 2 + 3) + \" 0 R /XYZ null\n  \t\t// null null]/S/GoTo>> endobj\");\n  \t\t// }\n  \t\t//\n  \t\t// for (var i = 0; i < dests.length; i++) {\n  \t\t// pdf.internal.write(\"(page_\" + (i + 1) + \")\" + dests[i] + \" 0\n  \t\t// R\");\n  \t\t// }\n  \t\t//\t\t\t\t\n  \t\tif (this.outline.root.children.length > 0) {\n  \t\t\tvar lines = pdf.outline.render().split(/\\r\\n/);\n  \t\t\tfor (var i = 0; i < lines.length; i++) {\n  \t\t\t\tvar line = lines[i];\n  \t\t\t\tvar m = rx.exec(line);\n  \t\t\t\tif (m != null) {\n  \t\t\t\t\tvar oid = m[1];\n  \t\t\t\t\tpdf.internal.newObjectDeferredBegin(oid);\n  \t\t\t\t}\n  \t\t\t\tpdf.internal.write(line);\n  \t\t\t}\n  \t\t}\n\n  \t\t// This code will write named destination for each page reference\n  \t\t// (page_1, etc)\n  \t\tif (this.outline.createNamedDestinations) {\n  \t\t\tvar totalPages = this.internal.pages.length;\n  \t\t\t// WARNING: this assumes jsPDF starts on page 3 and pageIDs\n  \t\t\t// follow 5, 7, 9, etc\n  \t\t\t// Write destination objects for each page\n  \t\t\tvar dests = [];\n  \t\t\tfor (var i = 0; i < totalPages; i++) {\n  \t\t\t\tvar id = pdf.internal.newObject();\n  \t\t\t\tdests.push(id);\n  \t\t\t\tvar info = pdf.internal.getPageInfo(i + 1);\n  \t\t\t\tpdf.internal.write(\"<< /D[\" + info.objId + \" 0 R /XYZ null null null]>> endobj\");\n  \t\t\t}\n\n  \t\t\t// assign a name for each destination\n  \t\t\tvar names2Oid = pdf.internal.newObject();\n  \t\t\tpdf.internal.write('<< /Names [ ');\n  \t\t\tfor (var i = 0; i < dests.length; i++) {\n  \t\t\t\tpdf.internal.write(\"(page_\" + (i + 1) + \")\" + dests[i] + \" 0 R\");\n  \t\t\t}\n  \t\t\tpdf.internal.write(' ] >>', 'endobj');\n\n  \t\t\t// var kids = pdf.internal.newObject();\n  \t\t\t// pdf.internal.write('<< /Kids [ ' + names2Oid + ' 0 R');\n  \t\t\t// pdf.internal.write(' ] >>', 'endobj');\n\n  \t\t\tvar namesOid = pdf.internal.newObject();\n  \t\t\tpdf.internal.write('<< /Dests ' + names2Oid + \" 0 R\");\n  \t\t\tpdf.internal.write('>>', 'endobj');\n  \t\t}\n  \t}]);\n\n  \tjsPDFAPI.events.push(['putCatalog', function () {\n  \t\tvar pdf = this;\n  \t\tif (pdf.outline.root.children.length > 0) {\n  \t\t\tpdf.internal.write(\"/Outlines\", this.outline.makeRef(this.outline.root));\n  \t\t\tif (this.outline.createNamedDestinations) {\n  \t\t\t\tpdf.internal.write(\"/Names \" + namesOid + \" 0 R\");\n  \t\t\t}\n  \t\t\t// Open with Bookmarks showing\n  \t\t\t// pdf.internal.write(\"/PageMode /UseOutlines\");\n  \t\t}\n  \t}]);\n\n  \tjsPDFAPI.events.push(['initialized', function () {\n  \t\tvar pdf = this;\n\n  \t\tpdf.outline = {\n  \t\t\tcreateNamedDestinations: false,\n  \t\t\troot: {\n  \t\t\t\tchildren: []\n  \t\t\t}\n  \t\t};\n\n  \t\t/**\n     * Options: pageNumber\n     */\n  \t\tpdf.outline.add = function (parent, title, options) {\n  \t\t\tvar item = {\n  \t\t\t\ttitle: title,\n  \t\t\t\toptions: options,\n  \t\t\t\tchildren: []\n  \t\t\t};\n  \t\t\tif (parent == null) {\n  \t\t\t\tparent = this.root;\n  \t\t\t}\n  \t\t\tparent.children.push(item);\n  \t\t\treturn item;\n  \t\t};\n\n  \t\tpdf.outline.render = function () {\n  \t\t\tthis.ctx = {};\n  \t\t\tthis.ctx.val = '';\n  \t\t\tthis.ctx.pdf = pdf;\n\n  \t\t\tthis.genIds_r(this.root);\n  \t\t\tthis.renderRoot(this.root);\n  \t\t\tthis.renderItems(this.root);\n\n  \t\t\treturn this.ctx.val;\n  \t\t};\n\n  \t\tpdf.outline.genIds_r = function (node) {\n  \t\t\tnode.id = pdf.internal.newObjectDeferred();\n  \t\t\tfor (var i = 0; i < node.children.length; i++) {\n  \t\t\t\tthis.genIds_r(node.children[i]);\n  \t\t\t}\n  \t\t};\n\n  \t\tpdf.outline.renderRoot = function (node) {\n  \t\t\tthis.objStart(node);\n  \t\t\tthis.line('/Type /Outlines');\n  \t\t\tif (node.children.length > 0) {\n  \t\t\t\tthis.line('/First ' + this.makeRef(node.children[0]));\n  \t\t\t\tthis.line('/Last ' + this.makeRef(node.children[node.children.length - 1]));\n  \t\t\t}\n  \t\t\tthis.line('/Count ' + this.count_r({\n  \t\t\t\tcount: 0\n  \t\t\t}, node));\n  \t\t\tthis.objEnd();\n  \t\t};\n\n  \t\tpdf.outline.renderItems = function (node) {\n  \t\t\tfor (var i = 0; i < node.children.length; i++) {\n  \t\t\t\tvar item = node.children[i];\n  \t\t\t\tthis.objStart(item);\n\n  \t\t\t\tthis.line('/Title ' + this.makeString(item.title));\n\n  \t\t\t\tthis.line('/Parent ' + this.makeRef(node));\n  \t\t\t\tif (i > 0) {\n  \t\t\t\t\tthis.line('/Prev ' + this.makeRef(node.children[i - 1]));\n  \t\t\t\t}\n  \t\t\t\tif (i < node.children.length - 1) {\n  \t\t\t\t\tthis.line('/Next ' + this.makeRef(node.children[i + 1]));\n  \t\t\t\t}\n  \t\t\t\tif (item.children.length > 0) {\n  \t\t\t\t\tthis.line('/First ' + this.makeRef(item.children[0]));\n  \t\t\t\t\tthis.line('/Last ' + this.makeRef(item.children[item.children.length - 1]));\n  \t\t\t\t}\n\n  \t\t\t\tvar count = this.count = this.count_r({\n  \t\t\t\t\tcount: 0\n  \t\t\t\t}, item);\n  \t\t\t\tif (count > 0) {\n  \t\t\t\t\tthis.line('/Count ' + count);\n  \t\t\t\t}\n\n  \t\t\t\tif (item.options) {\n  \t\t\t\t\tif (item.options.pageNumber) {\n  \t\t\t\t\t\t// Explicit Destination\n  \t\t\t\t\t\t//WARNING this assumes page ids are 3,5,7, etc.\n  \t\t\t\t\t\tvar info = pdf.internal.getPageInfo(item.options.pageNumber);\n  \t\t\t\t\t\tthis.line('/Dest ' + '[' + info.objId + ' 0 R /XYZ 0 ' + this.ctx.pdf.internal.pageSize.getHeight() * this.ctx.pdf.internal.scaleFactor + ' 0]');\n  \t\t\t\t\t\t// this line does not work on all clients (pageNumber instead of page ref)\n  \t\t\t\t\t\t//this.line('/Dest ' + '[' + (item.options.pageNumber - 1) + ' /XYZ 0 ' + this.ctx.pdf.internal.pageSize.getHeight() + ' 0]');\n\n  \t\t\t\t\t\t// Named Destination\n  \t\t\t\t\t\t// this.line('/Dest (page_' + (item.options.pageNumber) + ')');\n\n  \t\t\t\t\t\t// Action Destination\n  \t\t\t\t\t\t// var id = pdf.internal.newObject();\n  \t\t\t\t\t\t// pdf.internal.write('<</D[' + (item.options.pageNumber - 1) + ' /XYZ null null null]/S/GoTo>> endobj');\n  \t\t\t\t\t\t// this.line('/A ' + id + ' 0 R' );\n  \t\t\t\t\t}\n  \t\t\t\t}\n  \t\t\t\tthis.objEnd();\n  \t\t\t}\n  \t\t\tfor (var i = 0; i < node.children.length; i++) {\n  \t\t\t\tvar item = node.children[i];\n  \t\t\t\tthis.renderItems(item);\n  \t\t\t}\n  \t\t};\n\n  \t\tpdf.outline.line = function (text) {\n  \t\t\tthis.ctx.val += text + '\\r\\n';\n  \t\t};\n\n  \t\tpdf.outline.makeRef = function (node) {\n  \t\t\treturn node.id + ' 0 R';\n  \t\t};\n\n  \t\tpdf.outline.makeString = function (val) {\n  \t\t\treturn '(' + pdf.internal.pdfEscape(val) + ')';\n  \t\t};\n\n  \t\tpdf.outline.objStart = function (node) {\n  \t\t\tthis.ctx.val += '\\r\\n' + node.id + ' 0 obj' + '\\r\\n<<\\r\\n';\n  \t\t};\n\n  \t\tpdf.outline.objEnd = function (node) {\n  \t\t\tthis.ctx.val += '>> \\r\\n' + 'endobj' + '\\r\\n';\n  \t\t};\n\n  \t\tpdf.outline.count_r = function (ctx, node) {\n  \t\t\tfor (var i = 0; i < node.children.length; i++) {\n  \t\t\t\tctx.count++;\n  \t\t\t\tthis.count_r(ctx, node.children[i]);\n  \t\t\t}\n  \t\t\treturn ctx.count;\n  \t\t};\n  \t}]);\n\n  \treturn this;\n  })(jsPDF.API);\n\n  /**@preserve\n   *  ====================================================================\n   * jsPDF PNG PlugIn\n   * Copyright (c) 2014 James Robb, https://github.com/jamesbrobb\n   *\n   * \n   * ====================================================================\n   */\n\n  (function (jsPDFAPI) {\n\n  \t/*\n    * @see http://www.w3.org/TR/PNG-Chunks.html\n    *\n    Color    Allowed      Interpretation\n    Type     Bit Depths\n   \t   0       1,2,4,8,16  Each pixel is a grayscale sample.\n   \t   2       8,16        Each pixel is an R,G,B triple.\n   \t   3       1,2,4,8     Each pixel is a palette index;\n                          a PLTE chunk must appear.\n   \t   4       8,16        Each pixel is a grayscale sample,\n                          followed by an alpha sample.\n   \t   6       8,16        Each pixel is an R,G,B triple,\n                          followed by an alpha sample.\n   */\n\n  \t/*\n    * PNG filter method types\n    *\n    * @see http://www.w3.org/TR/PNG-Filters.html\n    * @see http://www.libpng.org/pub/png/book/chapter09.html\n    *\n    * This is what the value 'Predictor' in decode params relates to\n    *\n    * 15 is \"optimal prediction\", which means the prediction algorithm can change from line to line.\n    * In that case, you actually have to read the first byte off each line for the prediction algorthim (which should be 0-4, corresponding to PDF 10-14) and select the appropriate unprediction algorithm based on that byte.\n    *\n      0       None\n      1       Sub\n      2       Up\n      3       Average\n      4       Paeth\n    */\n\n  \tvar doesNotHavePngJS = function doesNotHavePngJS() {\n  \t\treturn typeof PNG !== 'function' || typeof FlateStream !== 'function';\n  \t},\n  \t    canCompress = function canCompress(value) {\n  \t\treturn value !== jsPDFAPI.image_compression.NONE && hasCompressionJS();\n  \t},\n  \t    hasCompressionJS = function hasCompressionJS() {\n  \t\tvar inst = typeof Deflater === 'function';\n  \t\tif (!inst) throw new Error(\"requires deflate.js for compression\");\n  \t\treturn inst;\n  \t},\n  \t    compressBytes = function compressBytes(bytes, lineLength, colorsPerPixel, compression) {\n\n  \t\tvar level = 5,\n  \t\t    filter_method = filterUp;\n\n  \t\tswitch (compression) {\n\n  \t\t\tcase jsPDFAPI.image_compression.FAST:\n\n  \t\t\t\tlevel = 3;\n  \t\t\t\tfilter_method = filterSub;\n  \t\t\t\tbreak;\n\n  \t\t\tcase jsPDFAPI.image_compression.MEDIUM:\n\n  \t\t\t\tlevel = 6;\n  \t\t\t\tfilter_method = filterAverage;\n  \t\t\t\tbreak;\n\n  \t\t\tcase jsPDFAPI.image_compression.SLOW:\n\n  \t\t\t\tlevel = 9;\n  \t\t\t\tfilter_method = filterPaeth; //uses to sum to choose best filter for each line\n  \t\t\t\tbreak;\n  \t\t}\n\n  \t\tbytes = applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method);\n\n  \t\tvar header = new Uint8Array(createZlibHeader(level));\n  \t\tvar checksum = adler32(bytes);\n\n  \t\tvar deflate = new Deflater(level);\n  \t\tvar a = deflate.append(bytes);\n  \t\tvar cBytes = deflate.flush();\n\n  \t\tvar len = header.length + a.length + cBytes.length;\n\n  \t\tvar cmpd = new Uint8Array(len + 4);\n  \t\tcmpd.set(header);\n  \t\tcmpd.set(a, header.length);\n  \t\tcmpd.set(cBytes, header.length + a.length);\n\n  \t\tcmpd[len++] = checksum >>> 24 & 0xff;\n  \t\tcmpd[len++] = checksum >>> 16 & 0xff;\n  \t\tcmpd[len++] = checksum >>> 8 & 0xff;\n  \t\tcmpd[len++] = checksum & 0xff;\n\n  \t\treturn jsPDFAPI.arrayBufferToBinaryString(cmpd);\n  \t},\n  \t    createZlibHeader = function createZlibHeader(bytes, level) {\n  \t\t/*\n     * @see http://www.ietf.org/rfc/rfc1950.txt for zlib header\n     */\n  \t\tvar cm = 8;\n  \t\tvar cinfo = Math.LOG2E * Math.log(0x8000) - 8;\n  \t\tvar cmf = cinfo << 4 | cm;\n\n  \t\tvar hdr = cmf << 8;\n  \t\tvar flevel = Math.min(3, (level - 1 & 0xff) >> 1);\n\n  \t\thdr |= flevel << 6;\n  \t\thdr |= 0; //FDICT\n  \t\thdr += 31 - hdr % 31;\n\n  \t\treturn [cmf, hdr & 0xff & 0xff];\n  \t},\n  \t    adler32 = function adler32(array, param) {\n  \t\tvar adler = 1;\n  \t\tvar s1 = adler & 0xffff,\n  \t\t    s2 = adler >>> 16 & 0xffff;\n  \t\tvar len = array.length;\n  \t\tvar tlen;\n  \t\tvar i = 0;\n\n  \t\twhile (len > 0) {\n  \t\t\ttlen = len > param ? param : len;\n  \t\t\tlen -= tlen;\n  \t\t\tdo {\n  \t\t\t\ts1 += array[i++];\n  \t\t\t\ts2 += s1;\n  \t\t\t} while (--tlen);\n\n  \t\t\ts1 %= 65521;\n  \t\t\ts2 %= 65521;\n  \t\t}\n\n  \t\treturn (s2 << 16 | s1) >>> 0;\n  \t},\n  \t    applyPngFilterMethod = function applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method) {\n  \t\tvar lines = bytes.length / lineLength,\n  \t\t    result = new Uint8Array(bytes.length + lines),\n  \t\t    filter_methods = getFilterMethods(),\n  \t\t    i = 0,\n  \t\t    line,\n  \t\t    prevLine,\n  \t\t    offset;\n\n  \t\tfor (; i < lines; i++) {\n  \t\t\toffset = i * lineLength;\n  \t\t\tline = bytes.subarray(offset, offset + lineLength);\n\n  \t\t\tif (filter_method) {\n  \t\t\t\tresult.set(filter_method(line, colorsPerPixel, prevLine), offset + i);\n  \t\t\t} else {\n\n  \t\t\t\tvar j = 0,\n  \t\t\t\t    len = filter_methods.length,\n  \t\t\t\t    results = [];\n\n  \t\t\t\tfor (; j < len; j++) {\n  \t\t\t\t\tresults[j] = filter_methods[j](line, colorsPerPixel, prevLine);\n  \t\t\t\t}var ind = getIndexOfSmallestSum(results.concat());\n\n  \t\t\t\tresult.set(results[ind], offset + i);\n  \t\t\t}\n\n  \t\t\tprevLine = line;\n  \t\t}\n\n  \t\treturn result;\n  \t},\n  \t    filterNone = function filterNone(line, colorsPerPixel, prevLine) {\n  \t\t/*var result = new Uint8Array(line.length + 1);\n    result[0] = 0;\n    result.set(line, 1);*/\n\n  \t\tvar result = Array.apply([], line);\n  \t\tresult.unshift(0);\n\n  \t\treturn result;\n  \t},\n  \t    filterSub = function filterSub(line, colorsPerPixel, prevLine) {\n  \t\tvar result = [],\n  \t\t    i = 0,\n  \t\t    len = line.length,\n  \t\t    left;\n\n  \t\tresult[0] = 1;\n\n  \t\tfor (; i < len; i++) {\n  \t\t\tleft = line[i - colorsPerPixel] || 0;\n  \t\t\tresult[i + 1] = line[i] - left + 0x0100 & 0xff;\n  \t\t}\n\n  \t\treturn result;\n  \t},\n  \t    filterUp = function filterUp(line, colorsPerPixel, prevLine) {\n  \t\tvar result = [],\n  \t\t    i = 0,\n  \t\t    len = line.length,\n  \t\t    up;\n\n  \t\tresult[0] = 2;\n\n  \t\tfor (; i < len; i++) {\n  \t\t\tup = prevLine && prevLine[i] || 0;\n  \t\t\tresult[i + 1] = line[i] - up + 0x0100 & 0xff;\n  \t\t}\n\n  \t\treturn result;\n  \t},\n  \t    filterAverage = function filterAverage(line, colorsPerPixel, prevLine) {\n  \t\tvar result = [],\n  \t\t    i = 0,\n  \t\t    len = line.length,\n  \t\t    left,\n  \t\t    up;\n\n  \t\tresult[0] = 3;\n\n  \t\tfor (; i < len; i++) {\n  \t\t\tleft = line[i - colorsPerPixel] || 0;\n  \t\t\tup = prevLine && prevLine[i] || 0;\n  \t\t\tresult[i + 1] = line[i] + 0x0100 - (left + up >>> 1) & 0xff;\n  \t\t}\n\n  \t\treturn result;\n  \t},\n  \t    filterPaeth = function filterPaeth(line, colorsPerPixel, prevLine) {\n  \t\tvar result = [],\n  \t\t    i = 0,\n  \t\t    len = line.length,\n  \t\t    left,\n  \t\t    up,\n  \t\t    upLeft,\n  \t\t    paeth;\n\n  \t\tresult[0] = 4;\n\n  \t\tfor (; i < len; i++) {\n  \t\t\tleft = line[i - colorsPerPixel] || 0;\n  \t\t\tup = prevLine && prevLine[i] || 0;\n  \t\t\tupLeft = prevLine && prevLine[i - colorsPerPixel] || 0;\n  \t\t\tpaeth = paethPredictor(left, up, upLeft);\n  \t\t\tresult[i + 1] = line[i] - paeth + 0x0100 & 0xff;\n  \t\t}\n\n  \t\treturn result;\n  \t},\n  \t    paethPredictor = function paethPredictor(left, up, upLeft) {\n\n  \t\tvar p = left + up - upLeft,\n  \t\t    pLeft = Math.abs(p - left),\n  \t\t    pUp = Math.abs(p - up),\n  \t\t    pUpLeft = Math.abs(p - upLeft);\n\n  \t\treturn pLeft <= pUp && pLeft <= pUpLeft ? left : pUp <= pUpLeft ? up : upLeft;\n  \t},\n  \t    getFilterMethods = function getFilterMethods() {\n  \t\treturn [filterNone, filterSub, filterUp, filterAverage, filterPaeth];\n  \t},\n  \t    getIndexOfSmallestSum = function getIndexOfSmallestSum(arrays) {\n  \t\tvar i = 0,\n  \t\t    len = arrays.length,\n  \t\t    sum,\n  \t\t    min,\n  \t\t    ind;\n\n  \t\twhile (i < len) {\n  \t\t\tsum = absSum(arrays[i].slice(1));\n\n  \t\t\tif (sum < min || !min) {\n  \t\t\t\tmin = sum;\n  \t\t\t\tind = i;\n  \t\t\t}\n\n  \t\t\ti++;\n  \t\t}\n\n  \t\treturn ind;\n  \t},\n  \t    absSum = function absSum(array) {\n  \t\tvar i = 0,\n  \t\t    len = array.length,\n  \t\t    sum = 0;\n\n  \t\twhile (i < len) {\n  \t\t\tsum += Math.abs(array[i++]);\n  \t\t}return sum;\n  \t},\n  \t    getPredictorFromCompression = function getPredictorFromCompression(compression) {\n  \t\tvar predictor;\n  \t\tswitch (compression) {\n  \t\t\tcase jsPDFAPI.image_compression.FAST:\n  \t\t\t\tpredictor = 11;\n  \t\t\t\tbreak;\n\n  \t\t\tcase jsPDFAPI.image_compression.MEDIUM:\n  \t\t\t\tpredictor = 13;\n  \t\t\t\tbreak;\n\n  \t\t\tcase jsPDFAPI.image_compression.SLOW:\n  \t\t\t\tpredictor = 14;\n  \t\t\t\tbreak;\n\n  \t\t\tdefault:\n  \t\t\t\tpredictor = 12;\n  \t\t\t\tbreak;\n  \t\t}\n  \t\treturn predictor;\n  \t};\n\n  \tjsPDFAPI.processPNG = function (imageData, imageIndex, alias, compression, dataAsBinaryString) {\n\n  \t\tvar colorSpace = this.color_spaces.DEVICE_RGB,\n  \t\t    decode = this.decode.FLATE_DECODE,\n  \t\t    bpc = 8,\n  \t\t    img,\n  \t\t    dp,\n  \t\t    trns,\n  \t\t    colors,\n  \t\t    pal,\n  \t\t    smask;\n\n  \t\t/*\tif(this.isString(imageData)) {\n    \t\t}*/\n\n  \t\tif (this.isArrayBuffer(imageData)) imageData = new Uint8Array(imageData);\n\n  \t\tif (this.isArrayBufferView(imageData)) {\n\n  \t\t\tif (doesNotHavePngJS()) throw new Error(\"PNG support requires png.js and zlib.js\");\n\n  \t\t\timg = new PNG(imageData);\n  \t\t\timageData = img.imgData;\n  \t\t\tbpc = img.bits;\n  \t\t\tcolorSpace = img.colorSpace;\n  \t\t\tcolors = img.colors;\n\n  \t\t\t//logImg(img);\n\n  \t\t\t/*\n      * colorType 6 - Each pixel is an R,G,B triple, followed by an alpha sample.\n      *\n      * colorType 4 - Each pixel is a grayscale sample, followed by an alpha sample.\n      *\n      * Extract alpha to create two separate images, using the alpha as a sMask\n      */\n  \t\t\tif ([4, 6].indexOf(img.colorType) !== -1) {\n\n  \t\t\t\t/*\n       * processes 8 bit RGBA and grayscale + alpha images\n       */\n  \t\t\t\tif (img.bits === 8) {\n\n  \t\t\t\t\tvar pixels = img.pixelBitlength == 32 ? new Uint32Array(img.decodePixels().buffer) : img.pixelBitlength == 16 ? new Uint16Array(img.decodePixels().buffer) : new Uint8Array(img.decodePixels().buffer),\n  \t\t\t\t\t    len = pixels.length,\n  \t\t\t\t\t    imgData = new Uint8Array(len * img.colors),\n  \t\t\t\t\t    alphaData = new Uint8Array(len),\n  \t\t\t\t\t    pDiff = img.pixelBitlength - img.bits,\n  \t\t\t\t\t    i = 0,\n  \t\t\t\t\t    n = 0,\n  \t\t\t\t\t    pixel,\n  \t\t\t\t\t    pbl;\n\n  \t\t\t\t\tfor (; i < len; i++) {\n  \t\t\t\t\t\tpixel = pixels[i];\n  \t\t\t\t\t\tpbl = 0;\n\n  \t\t\t\t\t\twhile (pbl < pDiff) {\n\n  \t\t\t\t\t\t\timgData[n++] = pixel >>> pbl & 0xff;\n  \t\t\t\t\t\t\tpbl = pbl + img.bits;\n  \t\t\t\t\t\t}\n\n  \t\t\t\t\t\talphaData[i] = pixel >>> pbl & 0xff;\n  \t\t\t\t\t}\n  \t\t\t\t}\n\n  \t\t\t\t/*\n       * processes 16 bit RGBA and grayscale + alpha images\n       */\n  \t\t\t\tif (img.bits === 16) {\n\n  \t\t\t\t\tvar pixels = new Uint32Array(img.decodePixels().buffer),\n  \t\t\t\t\t    len = pixels.length,\n  \t\t\t\t\t    imgData = new Uint8Array(len * (32 / img.pixelBitlength) * img.colors),\n  \t\t\t\t\t    alphaData = new Uint8Array(len * (32 / img.pixelBitlength)),\n  \t\t\t\t\t    hasColors = img.colors > 1,\n  \t\t\t\t\t    i = 0,\n  \t\t\t\t\t    n = 0,\n  \t\t\t\t\t    a = 0,\n  \t\t\t\t\t    pixel;\n\n  \t\t\t\t\twhile (i < len) {\n  \t\t\t\t\t\tpixel = pixels[i++];\n\n  \t\t\t\t\t\timgData[n++] = pixel >>> 0 & 0xFF;\n\n  \t\t\t\t\t\tif (hasColors) {\n  \t\t\t\t\t\t\timgData[n++] = pixel >>> 16 & 0xFF;\n\n  \t\t\t\t\t\t\tpixel = pixels[i++];\n  \t\t\t\t\t\t\timgData[n++] = pixel >>> 0 & 0xFF;\n  \t\t\t\t\t\t}\n\n  \t\t\t\t\t\talphaData[a++] = pixel >>> 16 & 0xFF;\n  \t\t\t\t\t}\n\n  \t\t\t\t\tbpc = 8;\n  \t\t\t\t}\n\n  \t\t\t\tif (canCompress(compression)) {\n\n  \t\t\t\t\timageData = compressBytes(imgData, img.width * img.colors, img.colors, compression);\n  \t\t\t\t\tsmask = compressBytes(alphaData, img.width, 1, compression);\n  \t\t\t\t} else {\n\n  \t\t\t\t\timageData = imgData;\n  \t\t\t\t\tsmask = alphaData;\n  \t\t\t\t\tdecode = null;\n  \t\t\t\t}\n  \t\t\t}\n\n  \t\t\t/*\n      * Indexed png. Each pixel is a palette index.\n      */\n  \t\t\tif (img.colorType === 3) {\n\n  \t\t\t\tcolorSpace = this.color_spaces.INDEXED;\n  \t\t\t\tpal = img.palette;\n\n  \t\t\t\tif (img.transparency.indexed) {\n\n  \t\t\t\t\tvar trans = img.transparency.indexed;\n\n  \t\t\t\t\tvar total = 0,\n  \t\t\t\t\t    i = 0,\n  \t\t\t\t\t    len = trans.length;\n\n  \t\t\t\t\tfor (; i < len; ++i) {\n  \t\t\t\t\t\ttotal += trans[i];\n  \t\t\t\t\t}total = total / 255;\n\n  \t\t\t\t\t/*\n        * a single color is specified as 100% transparent (0),\n        * so we set trns to use a /Mask with that index\n        */\n  \t\t\t\t\tif (total === len - 1 && trans.indexOf(0) !== -1) {\n  \t\t\t\t\t\ttrns = [trans.indexOf(0)];\n\n  \t\t\t\t\t\t/*\n         * there's more than one colour within the palette that specifies\n         * a transparency value less than 255, so we unroll the pixels to create an image sMask\n         */\n  \t\t\t\t\t} else if (total !== len) {\n\n  \t\t\t\t\t\tvar pixels = img.decodePixels(),\n  \t\t\t\t\t\t    alphaData = new Uint8Array(pixels.length),\n  \t\t\t\t\t\t    i = 0,\n  \t\t\t\t\t\t    len = pixels.length;\n\n  \t\t\t\t\t\tfor (; i < len; i++) {\n  \t\t\t\t\t\t\talphaData[i] = trans[pixels[i]];\n  \t\t\t\t\t\t}smask = compressBytes(alphaData, img.width, 1);\n  \t\t\t\t\t}\n  \t\t\t\t}\n  \t\t\t}\n\n  \t\t\tvar predictor = getPredictorFromCompression(compression);\n\n  \t\t\tif (decode === this.decode.FLATE_DECODE) dp = '/Predictor ' + predictor + ' /Colors ' + colors + ' /BitsPerComponent ' + bpc + ' /Columns ' + img.width;else\n  \t\t\t\t//remove 'Predictor' as it applies to the type of png filter applied to its IDAT - we only apply with compression\n  \t\t\t\tdp = '/Colors ' + colors + ' /BitsPerComponent ' + bpc + ' /Columns ' + img.width;\n\n  \t\t\tif (this.isArrayBuffer(imageData) || this.isArrayBufferView(imageData)) imageData = this.arrayBufferToBinaryString(imageData);\n\n  \t\t\tif (smask && this.isArrayBuffer(smask) || this.isArrayBufferView(smask)) smask = this.arrayBufferToBinaryString(smask);\n\n  \t\t\treturn this.createImageInfo(imageData, img.width, img.height, colorSpace, bpc, decode, imageIndex, alias, dp, trns, pal, smask, predictor);\n  \t\t}\n\n  \t\tthrow new Error(\"Unsupported PNG image data, try using JPEG instead.\");\n  \t};\n  })(jsPDF.API);\n\n  /**\n   * jsPDF gif Support PlugIn\n   * Copyright (c) 2017 Aras Abbasi \n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n\n  (function (jsPDFAPI) {\n\n  \tjsPDFAPI.processGIF89A = function (imageData, imageIndex, alias, compression, dataAsBinaryString) {\n  \t\tvar reader = new GifReader(imageData);\n  \t\tvar width = reader.width,\n  \t\t    height = reader.height;\n  \t\tvar qu = 100;\n  \t\tvar pixels = [];\n\n  \t\treader.decodeAndBlitFrameRGBA(0, pixels);\n  \t\tvar rawImageData = {\n  \t\t\tdata: pixels,\n  \t\t\twidth: width,\n  \t\t\theight: height\n  \t\t};\n\n  \t\tvar encoder = new JPEGEncoder(qu);\n  \t\tvar data = encoder.encode(rawImageData, qu);\n  \t\treturn jsPDFAPI.processJPEG.call(this, data, imageIndex, alias, compression);\n  \t};\n\n  \tjsPDFAPI.processGIF87A = jsPDFAPI.processGIF89A;\n  })(jsPDF.API);\n\n  /**\n   * jsPDF bmp Support PlugIn\n   * Copyright (c) 2018 Aras Abbasi \n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n\n  (function (jsPDFAPI) {\n\n  \tjsPDFAPI.processBMP = function (imageData, imageIndex, alias, compression, dataAsBinaryString) {\n  \t\tvar reader = new BmpDecoder(imageData, false);\n  \t\tvar width = reader.width,\n  \t\t    height = reader.height;\n  \t\tvar qu = 100;\n  \t\tvar pixels = reader.getData();\n\n  \t\tvar rawImageData = {\n  \t\t\tdata: pixels,\n  \t\t\twidth: width,\n  \t\t\theight: height\n  \t\t};\n\n  \t\tvar encoder = new JPEGEncoder(qu);\n  \t\tvar data = encoder.encode(rawImageData, qu);\n  \t\treturn jsPDFAPI.processJPEG.call(this, data, imageIndex, alias, compression);\n  \t};\n  })(jsPDF.API);\n\n  /**\n   * jsPDF setLanguage Plugin\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n\n  (function (jsPDFAPI) {\n\n      /**\n      * Add Language Tag to PDF\n      *\n      * @returns {jsPDF}\n      * @name setLanguage\n      * @example\n      * var doc = new jsPDF()\n      * doc.text(10, 10, 'This is a test')\n      * doc.setLanguage(\"en-US\")\n      * doc.save('english.pdf')\n      */\n\n      jsPDFAPI.setLanguage = function (langCode) {\n\n          var langCodes = {\n              \"af\": \"Afrikaans\",\n              \"sq\": \"Albanian\",\n              \"ar\": \"Arabic (Standard)\",\n              \"ar-DZ\": \"Arabic (Algeria)\",\n              \"ar-BH\": \"Arabic (Bahrain)\",\n              \"ar-EG\": \"Arabic (Egypt)\",\n              \"ar-IQ\": \"Arabic (Iraq)\",\n              \"ar-JO\": \"Arabic (Jordan)\",\n              \"ar-KW\": \"Arabic (Kuwait)\",\n              \"ar-LB\": \"Arabic (Lebanon)\",\n              \"ar-LY\": \"Arabic (Libya)\",\n              \"ar-MA\": \"Arabic (Morocco)\",\n              \"ar-OM\": \"Arabic (Oman)\",\n              \"ar-QA\": \"Arabic (Qatar)\",\n              \"ar-SA\": \"Arabic (Saudi Arabia)\",\n              \"ar-SY\": \"Arabic (Syria)\",\n              \"ar-TN\": \"Arabic (Tunisia)\",\n              \"ar-AE\": \"Arabic (U.A.E.)\",\n              \"ar-YE\": \"Arabic (Yemen)\",\n              \"an\": \"Aragonese\",\n              \"hy\": \"Armenian\",\n              \"as\": \"Assamese\",\n              \"ast\": \"Asturian\",\n              \"az\": \"Azerbaijani\",\n              \"eu\": \"Basque\",\n              \"be\": \"Belarusian\",\n              \"bn\": \"Bengali\",\n              \"bs\": \"Bosnian\",\n              \"br\": \"Breton\",\n              \"bg\": \"Bulgarian\",\n              \"my\": \"Burmese\",\n              \"ca\": \"Catalan\",\n              \"ch\": \"Chamorro\",\n              \"ce\": \"Chechen\",\n              \"zh\": \"Chinese\",\n              \"zh-HK\": \"Chinese (Hong Kong)\",\n              \"zh-CN\": \"Chinese (PRC)\",\n              \"zh-SG\": \"Chinese (Singapore)\",\n              \"zh-TW\": \"Chinese (Taiwan)\",\n              \"cv\": \"Chuvash\",\n              \"co\": \"Corsican\",\n              \"cr\": \"Cree\",\n              \"hr\": \"Croatian\",\n              \"cs\": \"Czech\",\n              \"da\": \"Danish\",\n              \"nl\": \"Dutch (Standard)\",\n              \"nl-BE\": \"Dutch (Belgian)\",\n              \"en\": \"English\",\n              \"en-AU\": \"English (Australia)\",\n              \"en-BZ\": \"English (Belize)\",\n              \"en-CA\": \"English (Canada)\",\n              \"en-IE\": \"English (Ireland)\",\n              \"en-JM\": \"English (Jamaica)\",\n              \"en-NZ\": \"English (New Zealand)\",\n              \"en-PH\": \"English (Philippines)\",\n              \"en-ZA\": \"English (South Africa)\",\n              \"en-TT\": \"English (Trinidad & Tobago)\",\n              \"en-GB\": \"English (United Kingdom)\",\n              \"en-US\": \"English (United States)\",\n              \"en-ZW\": \"English (Zimbabwe)\",\n              \"eo\": \"Esperanto\",\n              \"et\": \"Estonian\",\n              \"fo\": \"Faeroese\",\n              \"fj\": \"Fijian\",\n              \"fi\": \"Finnish\",\n              \"fr\": \"French (Standard)\",\n              \"fr-BE\": \"French (Belgium)\",\n              \"fr-CA\": \"French (Canada)\",\n              \"fr-FR\": \"French (France)\",\n              \"fr-LU\": \"French (Luxembourg)\",\n              \"fr-MC\": \"French (Monaco)\",\n              \"fr-CH\": \"French (Switzerland)\",\n              \"fy\": \"Frisian\",\n              \"fur\": \"Friulian\",\n              \"gd\": \"Gaelic (Scots)\",\n              \"gd-IE\": \"Gaelic (Irish)\",\n              \"gl\": \"Galacian\",\n              \"ka\": \"Georgian\",\n              \"de\": \"German (Standard)\",\n              \"de-AT\": \"German (Austria)\",\n              \"de-DE\": \"German (Germany)\",\n              \"de-LI\": \"German (Liechtenstein)\",\n              \"de-LU\": \"German (Luxembourg)\",\n              \"de-CH\": \"German (Switzerland)\",\n              \"el\": \"Greek\",\n              \"gu\": \"Gujurati\",\n              \"ht\": \"Haitian\",\n              \"he\": \"Hebrew\",\n              \"hi\": \"Hindi\",\n              \"hu\": \"Hungarian\",\n              \"is\": \"Icelandic\",\n              \"id\": \"Indonesian\",\n              \"iu\": \"Inuktitut\",\n              \"ga\": \"Irish\",\n              \"it\": \"Italian (Standard)\",\n              \"it-CH\": \"Italian (Switzerland)\",\n              \"ja\": \"Japanese\",\n              \"kn\": \"Kannada\",\n              \"ks\": \"Kashmiri\",\n              \"kk\": \"Kazakh\",\n              \"km\": \"Khmer\",\n              \"ky\": \"Kirghiz\",\n              \"tlh\": \"Klingon\",\n              \"ko\": \"Korean\",\n              \"ko-KP\": \"Korean (North Korea)\",\n              \"ko-KR\": \"Korean (South Korea)\",\n              \"la\": \"Latin\",\n              \"lv\": \"Latvian\",\n              \"lt\": \"Lithuanian\",\n              \"lb\": \"Luxembourgish\",\n              \"mk\": \"FYRO Macedonian\",\n              \"ms\": \"Malay\",\n              \"ml\": \"Malayalam\",\n              \"mt\": \"Maltese\",\n              \"mi\": \"Maori\",\n              \"mr\": \"Marathi\",\n              \"mo\": \"Moldavian\",\n              \"nv\": \"Navajo\",\n              \"ng\": \"Ndonga\",\n              \"ne\": \"Nepali\",\n              \"no\": \"Norwegian\",\n              \"nb\": \"Norwegian (Bokmal)\",\n              \"nn\": \"Norwegian (Nynorsk)\",\n              \"oc\": \"Occitan\",\n              \"or\": \"Oriya\",\n              \"om\": \"Oromo\",\n              \"fa\": \"Persian\",\n              \"fa-IR\": \"Persian/Iran\",\n              \"pl\": \"Polish\",\n              \"pt\": \"Portuguese\",\n              \"pt-BR\": \"Portuguese (Brazil)\",\n              \"pa\": \"Punjabi\",\n              \"pa-IN\": \"Punjabi (India)\",\n              \"pa-PK\": \"Punjabi (Pakistan)\",\n              \"qu\": \"Quechua\",\n              \"rm\": \"Rhaeto-Romanic\",\n              \"ro\": \"Romanian\",\n              \"ro-MO\": \"Romanian (Moldavia)\",\n              \"ru\": \"Russian\",\n              \"ru-MO\": \"Russian (Moldavia)\",\n              \"sz\": \"Sami (Lappish)\",\n              \"sg\": \"Sango\",\n              \"sa\": \"Sanskrit\",\n              \"sc\": \"Sardinian\",\n              \"sd\": \"Sindhi\",\n              \"si\": \"Singhalese\",\n              \"sr\": \"Serbian\",\n              \"sk\": \"Slovak\",\n              \"sl\": \"Slovenian\",\n              \"so\": \"Somani\",\n              \"sb\": \"Sorbian\",\n              \"es\": \"Spanish\",\n              \"es-AR\": \"Spanish (Argentina)\",\n              \"es-BO\": \"Spanish (Bolivia)\",\n              \"es-CL\": \"Spanish (Chile)\",\n              \"es-CO\": \"Spanish (Colombia)\",\n              \"es-CR\": \"Spanish (Costa Rica)\",\n              \"es-DO\": \"Spanish (Dominican Republic)\",\n              \"es-EC\": \"Spanish (Ecuador)\",\n              \"es-SV\": \"Spanish (El Salvador)\",\n              \"es-GT\": \"Spanish (Guatemala)\",\n              \"es-HN\": \"Spanish (Honduras)\",\n              \"es-MX\": \"Spanish (Mexico)\",\n              \"es-NI\": \"Spanish (Nicaragua)\",\n              \"es-PA\": \"Spanish (Panama)\",\n              \"es-PY\": \"Spanish (Paraguay)\",\n              \"es-PE\": \"Spanish (Peru)\",\n              \"es-PR\": \"Spanish (Puerto Rico)\",\n              \"es-ES\": \"Spanish (Spain)\",\n              \"es-UY\": \"Spanish (Uruguay)\",\n              \"es-VE\": \"Spanish (Venezuela)\",\n              \"sx\": \"Sutu\",\n              \"sw\": \"Swahili\",\n              \"sv\": \"Swedish\",\n              \"sv-FI\": \"Swedish (Finland)\",\n              \"sv-SV\": \"Swedish (Sweden)\",\n              \"ta\": \"Tamil\",\n              \"tt\": \"Tatar\",\n              \"te\": \"Teluga\",\n              \"th\": \"Thai\",\n              \"tig\": \"Tigre\",\n              \"ts\": \"Tsonga\",\n              \"tn\": \"Tswana\",\n              \"tr\": \"Turkish\",\n              \"tk\": \"Turkmen\",\n              \"uk\": \"Ukrainian\",\n              \"hsb\": \"Upper Sorbian\",\n              \"ur\": \"Urdu\",\n              \"ve\": \"Venda\",\n              \"vi\": \"Vietnamese\",\n              \"vo\": \"Volapuk\",\n              \"wa\": \"Walloon\",\n              \"cy\": \"Welsh\",\n              \"xh\": \"Xhosa\",\n              \"ji\": \"Yiddish\",\n              \"zu\": \"Zulu\"\n          };\n\n          if (this.internal.languageSettings === undefined) {\n              this.internal.languageSettings = {};\n              this.internal.languageSettings.isSubscribed = false;\n          }\n\n          if (langCodes[langCode] !== undefined) {\n              this.internal.languageSettings.languageCode = langCode;\n              if (this.internal.languageSettings.isSubscribed === false) {\n                  this.internal.events.subscribe(\"putCatalog\", function () {\n                      this.internal.write(\"/Lang (\" + this.internal.languageSettings.languageCode + \")\");\n                  });\n                  this.internal.languageSettings.isSubscribed = true;\n              }\n          }\n          return this;\n      };\n  })(jsPDF.API);\n\n  /** @preserve\n   * jsPDF split_text_to_size plugin - MIT license.\n   * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com\n   *               2014 Diego Casorran, https://github.com/diegocr\n   */\n  /**\n   * \n   * ====================================================================\n   */\n\n  (function (API) {\n    /**\n     * Returns an array of length matching length of the 'word' string, with each\n     * cell occupied by the width of the char in that position.\n     * \n     * @function\n     * @param word {String}\n     * @param widths {Object}\n     * @param kerning {Object}\n     * @returns {Array}\n     */\n\n    var getCharWidthsArray = API.getCharWidthsArray = function (text, options) {\n      options = options || {};\n\n      var activeFont = options.font || this.internal.getFont();\n      var fontSize = options.fontSize || this.internal.getFontSize();\n      var charSpace = options.charSpace || this.internal.getCharSpace();\n\n      var widths = options.widths ? options.widths : activeFont.metadata.Unicode.widths;\n      var widthsFractionOf = widths.fof ? widths.fof : 1;\n      var kerning = options.kerning ? options.kerning : activeFont.metadata.Unicode.kerning;\n      var kerningFractionOf = kerning.fof ? kerning.fof : 1;\n\n      var i;\n      var l;\n      var char_code;\n      var prior_char_code = 0; //for kerning\n      var default_char_width = widths[0] || widthsFractionOf;\n      var output = [];\n\n      for (i = 0, l = text.length; i < l; i++) {\n        char_code = text.charCodeAt(i);\n\n        if (typeof activeFont.metadata.widthOfString === \"function\") {\n          output.push((activeFont.metadata.widthOfGlyph(activeFont.metadata.characterToGlyph(char_code)) + charSpace * (1000 / fontSize) || 0) / 1000);\n        } else {\n          output.push((widths[char_code] || default_char_width) / widthsFractionOf + (kerning[char_code] && kerning[char_code][prior_char_code] || 0) / kerningFractionOf);\n        }\n        prior_char_code = char_code;\n      }\n\n      return output;\n    };\n\n    /**\n     * Calculate the sum of a number-array\n     * \n     * @name getArraySum\n     * @public\n     * @function\n     * @param {array} array of numbers\n     * @returns {Number}\n     */\n    var getArraySum = API.getArraySum = function (array) {\n      var i = array.length,\n          output = 0;\n      while (i) {\n        i--;\n        output += array[i];\n      }\n      return output;\n    };\n    /**\n    Returns a widths of string in a given font, if the font size is set as 1 point.\n     In other words, this is \"proportional\" value. For 1 unit of font size, the length\n    of the string will be that much.\n     Multiply by font size to get actual width in *points*\n    Then divide by 72 to get inches or divide by (72/25.6) to get 'mm' etc.\n     @public\n    @function\n    @param\n    @returns {Type}\n    */\n    var getStringUnitWidth = API.getStringUnitWidth = function (text, options) {\n      options = options || {};\n\n      var fontSize = options.fontSize || this.internal.getFontSize();\n      var font = options.font || this.internal.getFont();\n      var charSpace = options.charSpace || this.internal.getCharSpace();\n      var result = 0;\n      if (typeof font.metadata.widthOfString === \"function\") {\n        result = font.metadata.widthOfString(text, fontSize, charSpace) / fontSize;\n      } else {\n        result = getArraySum(getCharWidthsArray.apply(this, arguments));\n      }\n      return result;\n    };\n\n    /**\n    returns array of lines\n    */\n    var splitLongWord = function splitLongWord(word, widths_array, firstLineMaxLen, maxLen) {\n      var answer = [];\n\n      // 1st, chop off the piece that can fit on the hanging line.\n      var i = 0,\n          l = word.length,\n          workingLen = 0;\n      while (i !== l && workingLen + widths_array[i] < firstLineMaxLen) {\n        workingLen += widths_array[i];\n        i++;\n      }\n      // this is first line.\n      answer.push(word.slice(0, i));\n\n      // 2nd. Split the rest into maxLen pieces.\n      var startOfLine = i;\n      workingLen = 0;\n      while (i !== l) {\n        if (workingLen + widths_array[i] > maxLen) {\n          answer.push(word.slice(startOfLine, i));\n          workingLen = 0;\n          startOfLine = i;\n        }\n        workingLen += widths_array[i];\n        i++;\n      }\n      if (startOfLine !== i) {\n        answer.push(word.slice(startOfLine, i));\n      }\n\n      return answer;\n    };\n\n    // Note, all sizing inputs for this function must be in \"font measurement units\"\n    // By default, for PDF, it's \"point\".\n    var splitParagraphIntoLines = function splitParagraphIntoLines(text, maxlen, options) {\n      // at this time works only on Western scripts, ones with space char\n      // separating the words. Feel free to expand.\n\n      if (!options) {\n        options = {};\n      }\n\n      var line = [],\n          lines = [line],\n          line_length = options.textIndent || 0,\n          separator_length = 0,\n          current_word_length = 0,\n          word,\n          widths_array,\n          words = text.split(' '),\n          spaceCharWidth = getCharWidthsArray.apply(this, [' ', options])[0],\n          i,\n          l,\n          tmp,\n          lineIndent;\n\n      if (options.lineIndent === -1) {\n        lineIndent = words[0].length + 2;\n      } else {\n        lineIndent = options.lineIndent || 0;\n      }\n      if (lineIndent) {\n        var pad = Array(lineIndent).join(\" \"),\n            wrds = [];\n        words.map(function (wrd) {\n          wrd = wrd.split(/\\s*\\n/);\n          if (wrd.length > 1) {\n            wrds = wrds.concat(wrd.map(function (wrd, idx) {\n              return (idx && wrd.length ? \"\\n\" : \"\") + wrd;\n            }));\n          } else {\n            wrds.push(wrd[0]);\n          }\n        });\n        words = wrds;\n        lineIndent = getStringUnitWidth.apply(this, [pad, options]);\n      }\n\n      for (i = 0, l = words.length; i < l; i++) {\n        var force = 0;\n\n        word = words[i];\n        if (lineIndent && word[0] == \"\\n\") {\n          word = word.substr(1);\n          force = 1;\n        }\n        widths_array = getCharWidthsArray.apply(this, [word, options]);\n        current_word_length = getArraySum(widths_array);\n\n        if (line_length + separator_length + current_word_length > maxlen || force) {\n          if (current_word_length > maxlen) {\n            // this happens when you have space-less long URLs for example.\n            // we just chop these to size. We do NOT insert hiphens\n            tmp = splitLongWord.apply(this, [word, widths_array, maxlen - (line_length + separator_length), maxlen]);\n            // first line we add to existing line object\n            line.push(tmp.shift()); // it's ok to have extra space indicator there\n            // last line we make into new line object\n            line = [tmp.pop()];\n            // lines in the middle we apped to lines object as whole lines\n            while (tmp.length) {\n              lines.push([tmp.shift()]); // single fragment occupies whole line\n            }\n            current_word_length = getArraySum(widths_array.slice(word.length - (line[0] ? line[0].length : 0)));\n          } else {\n            // just put it on a new line\n            line = [word];\n          }\n\n          // now we attach new line to lines\n          lines.push(line);\n          line_length = current_word_length + lineIndent;\n          separator_length = spaceCharWidth;\n        } else {\n          line.push(word);\n\n          line_length += separator_length + current_word_length;\n          separator_length = spaceCharWidth;\n        }\n      }\n\n      if (lineIndent) {\n        var postProcess = function postProcess(ln, idx) {\n          return (idx ? pad : '') + ln.join(\" \");\n        };\n      } else {\n        var postProcess = function postProcess(ln) {\n          return ln.join(\" \");\n        };\n      }\n\n      return lines.map(postProcess);\n    };\n\n    /**\n    Splits a given string into an array of strings. Uses 'size' value\n    (in measurement units declared as default for the jsPDF instance)\n    and the font's \"widths\" and \"Kerning\" tables, where available, to\n    determine display length of a given string for a given font.\n     We use character's 100% of unit size (height) as width when Width\n    table or other default width is not available.\n     @public\n    @function\n    @param text {String} Unencoded, regular JavaScript (Unicode, UTF-16 / UCS-2) string.\n    @param size {Number} Nominal number, measured in units default to this instance of jsPDF.\n    @param options {Object} Optional flags needed for chopper to do the right thing.\n    @returns {Array} with strings chopped to size.\n    */\n    API.splitTextToSize = function (text, maxlen, options) {\n\n      options = options || {};\n\n      var fsize = options.fontSize || this.internal.getFontSize(),\n          newOptions = function (options) {\n        var widths = {\n          0: 1\n        },\n            kerning = {};\n\n        if (!options.widths || !options.kerning) {\n          var f = this.internal.getFont(options.fontName, options.fontStyle),\n              encoding = 'Unicode';\n          // NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE\n          // Actual JavaScript-native String's 16bit char codes used.\n          // no multi-byte logic here\n\n          if (f.metadata[encoding]) {\n            return {\n              widths: f.metadata[encoding].widths || widths,\n              kerning: f.metadata[encoding].kerning || kerning\n            };\n          } else {\n            return {\n              font: f.metadata,\n              fontSize: this.internal.getFontSize(),\n              charSpace: this.internal.getCharSpace()\n            };\n          }\n        } else {\n          return {\n            widths: options.widths,\n            kerning: options.kerning\n          };\n        }\n\n        // then use default values\n        return {\n          widths: widths,\n          kerning: kerning\n        };\n      }.call(this, options);\n\n      // first we split on end-of-line chars\n      var paragraphs;\n      if (Array.isArray(text)) {\n        paragraphs = text;\n      } else {\n        paragraphs = text.split(/\\r?\\n/);\n      }\n\n      // now we convert size (max length of line) into \"font size units\"\n      // at present time, the \"font size unit\" is always 'point'\n      // 'proportional' means, \"in proportion to font size\"\n      var fontUnit_maxLen = 1.0 * this.internal.scaleFactor * maxlen / fsize;\n      // at this time, fsize is always in \"points\" regardless of the default measurement unit of the doc.\n      // this may change in the future?\n      // until then, proportional_maxlen is likely to be in 'points'\n\n      // If first line is to be indented (shorter or longer) than maxLen\n      // we indicate that by using CSS-style \"text-indent\" option.\n      // here it's in font units too (which is likely 'points')\n      // it can be negative (which makes the first line longer than maxLen)\n      newOptions.textIndent = options.textIndent ? options.textIndent * 1.0 * this.internal.scaleFactor / fsize : 0;\n      newOptions.lineIndent = options.lineIndent;\n\n      var i,\n          l,\n          output = [];\n      for (i = 0, l = paragraphs.length; i < l; i++) {\n        output = output.concat(splitParagraphIntoLines.apply(this, [paragraphs[i], fontUnit_maxLen, newOptions]));\n      }\n\n      return output;\n    };\n  })(jsPDF.API);\n\n  /** @preserve \n  jsPDF standard_fonts_metrics plugin\n  Copyright (c) 2012 Willow Systems Corporation, willow-systems.com\n  MIT license.\n  */\n  (function (API) {\n\n  \t/*\n   # reference (Python) versions of 'compress' and 'uncompress'\n   # only 'uncompress' function is featured lower as JavaScript\n   # if you want to unit test \"roundtrip\", just transcribe the reference\n   # 'compress' function from Python into JavaScript\n   \n   def compress(data):\n   \n   \tkeys =   '0123456789abcdef'\n   \tvalues = 'klmnopqrstuvwxyz'\n   \tmapping = dict(zip(keys, values))\n   \tvals = []\n   \tfor key in data.keys():\n   \t\tvalue = data[key]\n   \t\ttry:\n   \t\t\tkeystring = hex(key)[2:]\n   \t\t\tkeystring = keystring[:-1] + mapping[keystring[-1:]]\n   \t\texcept:\n   \t\t\tkeystring = key.join([\"'\",\"'\"])\n   \t\t\t#print('Keystring is %s' % keystring)\n   \n   \t\ttry:\n   \t\t\tif value < 0:\n   \t\t\t\tvaluestring = hex(value)[3:]\n   \t\t\t\tnumberprefix = '-'\n   \t\t\telse:\n   \t\t\t\tvaluestring = hex(value)[2:]\n   \t\t\t\tnumberprefix = ''\n   \t\t\tvaluestring = numberprefix + valuestring[:-1] + mapping[valuestring[-1:]]\n   \t\texcept:\n   \t\t\tif type(value) == dict:\n   \t\t\t\tvaluestring = compress(value)\n   \t\t\telse:\n   \t\t\t\traise Exception(\"Don't know what to do with value type %s\" % type(value))\n   \n   \t\tvals.append(keystring+valuestring)\n   \t\n   \treturn '{' + ''.join(vals) + '}'\n   \n   def uncompress(data):\n   \n   \tdecoded = '0123456789abcdef'\n   \tencoded = 'klmnopqrstuvwxyz'\n   \tmapping = dict(zip(encoded, decoded))\n   \n   \tsign = +1\n   \tstringmode = False\n   \tstringparts = []\n   \n   \toutput = {}\n   \n   \tactiveobject = output\n   \tparentchain = []\n   \n   \tkeyparts = ''\n   \tvalueparts = ''\n   \n   \tkey = None\n   \n   \tending = set(encoded)\n   \n   \ti = 1\n   \tl = len(data) - 1 # stripping starting, ending {}\n   \twhile i != l: # stripping {}\n   \t\t# -, {, }, ' are special.\n   \n   \t\tch = data[i]\n   \t\ti += 1\n   \n   \t\tif ch == \"'\":\n   \t\t\tif stringmode:\n   \t\t\t\t# end of string mode\n   \t\t\t\tstringmode = False\n   \t\t\t\tkey = ''.join(stringparts)\n   \t\t\telse:\n   \t\t\t\t# start of string mode\n   \t\t\t\tstringmode = True\n   \t\t\t\tstringparts = []\n   \t\telif stringmode == True:\n   \t\t\t#print(\"Adding %s to stringpart\" % ch)\n   \t\t\tstringparts.append(ch)\n   \n   \t\telif ch == '{':\n   \t\t\t# start of object\n   \t\t\tparentchain.append( [activeobject, key] )\n   \t\t\tactiveobject = {}\n   \t\t\tkey = None\n   \t\t\t#DEBUG = True\n   \t\telif ch == '}':\n   \t\t\t# end of object\n   \t\t\tparent, key = parentchain.pop()\n   \t\t\tparent[key] = activeobject\n   \t\t\tkey = None\n   \t\t\tactiveobject = parent\n   \t\t\t#DEBUG = False\n   \n   \t\telif ch == '-':\n   \t\t\tsign = -1\n   \t\telse:\n   \t\t\t# must be number\n   \t\t\tif key == None:\n   \t\t\t\t#debug(\"In Key. It is '%s', ch is '%s'\" % (keyparts, ch))\n   \t\t\t\tif ch in ending:\n   \t\t\t\t\t#debug(\"End of key\")\n   \t\t\t\t\tkeyparts += mapping[ch]\n   \t\t\t\t\tkey = int(keyparts, 16) * sign\n   \t\t\t\t\tsign = +1\n   \t\t\t\t\tkeyparts = ''\n   \t\t\t\telse:\n   \t\t\t\t\tkeyparts += ch\n   \t\t\telse:\n   \t\t\t\t#debug(\"In value. It is '%s', ch is '%s'\" % (valueparts, ch))\n   \t\t\t\tif ch in ending:\n   \t\t\t\t\t#debug(\"End of value\")\n   \t\t\t\t\tvalueparts += mapping[ch]\n   \t\t\t\t\tactiveobject[key] = int(valueparts, 16) * sign\n   \t\t\t\t\tsign = +1\n   \t\t\t\t\tkey = None\n   \t\t\t\t\tvalueparts = ''\n   \t\t\t\telse:\n   \t\t\t\t\tvalueparts += ch\n   \n   \t\t\t#debug(activeobject)\n   \n   \treturn output\n   \n   */\n\n  \t/**\n   Uncompresses data compressed into custom, base16-like format. \n   @public\n   @function\n   @param\n   @returns {Type}\n   */\n\n  \tvar uncompress = function uncompress(data) {\n\n  \t\tvar decoded = '0123456789abcdef',\n  \t\t    encoded = 'klmnopqrstuvwxyz',\n  \t\t    mapping = {};\n\n  \t\tfor (var i = 0; i < encoded.length; i++) {\n  \t\t\tmapping[encoded[i]] = decoded[i];\n  \t\t}\n\n  \t\tvar undef,\n  \t\t    output = {},\n  \t\t    sign = 1,\n  \t\t    stringparts // undef. will be [] in string mode\n\n  \t\t,\n  \t\t    activeobject = output,\n  \t\t    parentchain = [],\n  \t\t    parent_key_pair,\n  \t\t    keyparts = '',\n  \t\t    valueparts = '',\n  \t\t    key // undef. will be Truthy when Key is resolved.\n  \t\t,\n  \t\t    datalen = data.length - 1 // stripping ending }\n  \t\t,\n  \t\t    ch;\n\n  \t\ti = 1; // stripping starting {\n\n  \t\twhile (i != datalen) {\n  \t\t\t// - { } ' are special.\n\n  \t\t\tch = data[i];\n  \t\t\ti += 1;\n\n  \t\t\tif (ch == \"'\") {\n  \t\t\t\tif (stringparts) {\n  \t\t\t\t\t// end of string mode\n  \t\t\t\t\tkey = stringparts.join('');\n  \t\t\t\t\tstringparts = undef;\n  \t\t\t\t} else {\n  \t\t\t\t\t// start of string mode\n  \t\t\t\t\tstringparts = [];\n  \t\t\t\t}\n  \t\t\t} else if (stringparts) {\n  \t\t\t\tstringparts.push(ch);\n  \t\t\t} else if (ch == '{') {\n  \t\t\t\t// start of object\n  \t\t\t\tparentchain.push([activeobject, key]);\n  \t\t\t\tactiveobject = {};\n  \t\t\t\tkey = undef;\n  \t\t\t} else if (ch == '}') {\n  \t\t\t\t// end of object\n  \t\t\t\tparent_key_pair = parentchain.pop();\n  \t\t\t\tparent_key_pair[0][parent_key_pair[1]] = activeobject;\n  \t\t\t\tkey = undef;\n  \t\t\t\tactiveobject = parent_key_pair[0];\n  \t\t\t} else if (ch == '-') {\n  \t\t\t\tsign = -1;\n  \t\t\t} else {\n  \t\t\t\t// must be number\n  \t\t\t\tif (key === undef) {\n  \t\t\t\t\tif (mapping.hasOwnProperty(ch)) {\n  \t\t\t\t\t\tkeyparts += mapping[ch];\n  \t\t\t\t\t\tkey = parseInt(keyparts, 16) * sign;\n  \t\t\t\t\t\tsign = +1;\n  \t\t\t\t\t\tkeyparts = '';\n  \t\t\t\t\t} else {\n  \t\t\t\t\t\tkeyparts += ch;\n  \t\t\t\t\t}\n  \t\t\t\t} else {\n  \t\t\t\t\tif (mapping.hasOwnProperty(ch)) {\n  \t\t\t\t\t\tvalueparts += mapping[ch];\n  \t\t\t\t\t\tactiveobject[key] = parseInt(valueparts, 16) * sign;\n  \t\t\t\t\t\tsign = +1;\n  \t\t\t\t\t\tkey = undef;\n  \t\t\t\t\t\tvalueparts = '';\n  \t\t\t\t\t} else {\n  \t\t\t\t\t\tvalueparts += ch;\n  \t\t\t\t\t}\n  \t\t\t\t}\n  \t\t\t}\n  \t\t} // end while\n\n  \t\treturn output;\n  \t};\n\n  \t// encoding = 'Unicode' \n  \t// NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE. NO clever BOM behavior\n  \t// Actual 16bit char codes used.\n  \t// no multi-byte logic here\n\n  \t// Unicode characters to WinAnsiEncoding:\n  \t// {402: 131, 8211: 150, 8212: 151, 8216: 145, 8217: 146, 8218: 130, 8220: 147, 8221: 148, 8222: 132, 8224: 134, 8225: 135, 8226: 149, 8230: 133, 8364: 128, 8240:137, 8249: 139, 8250: 155, 710: 136, 8482: 153, 338: 140, 339: 156, 732: 152, 352: 138, 353: 154, 376: 159, 381: 142, 382: 158}\n  \t// as you can see, all Unicode chars are outside of 0-255 range. No char code conflicts.\n  \t// this means that you can give Win cp1252 encoded strings to jsPDF for rendering directly\n  \t// as well as give strings with some (supported by these fonts) Unicode characters and \n  \t// these will be mapped to win cp1252 \n  \t// for example, you can send char code (cp1252) 0x80 or (unicode) 0x20AC, getting \"Euro\" glyph displayed in both cases.\n\n  \tvar encodingBlock = {\n  \t\t'codePages': ['WinAnsiEncoding'],\n  \t\t'WinAnsiEncoding': uncompress(\"{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}\")\n  \t},\n  \t    encodings = { 'Unicode': {\n  \t\t\t'Courier': encodingBlock,\n  \t\t\t'Courier-Bold': encodingBlock,\n  \t\t\t'Courier-BoldOblique': encodingBlock,\n  \t\t\t'Courier-Oblique': encodingBlock,\n  \t\t\t'Helvetica': encodingBlock,\n  \t\t\t'Helvetica-Bold': encodingBlock,\n  \t\t\t'Helvetica-BoldOblique': encodingBlock,\n  \t\t\t'Helvetica-Oblique': encodingBlock,\n  \t\t\t'Times-Roman': encodingBlock,\n  \t\t\t'Times-Bold': encodingBlock,\n  \t\t\t'Times-BoldItalic': encodingBlock,\n  \t\t\t'Times-Italic': encodingBlock\n  \t\t\t//\t, 'Symbol'\n  \t\t\t//\t, 'ZapfDingbats'\n  \t\t}\n  \t\t/** \n    Resources:\n    Font metrics data is reprocessed derivative of contents of\n    \"Font Metrics for PDF Core 14 Fonts\" package, which exhibits the following copyright and license:\n    \n    Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.\n    \n    This file and the 14 PostScript(R) AFM files it accompanies may be used,\n    copied, and distributed for any purpose and without charge, with or without\n    modification, provided that all copyright notices are retained; that the AFM\n    files are not distributed without this file; that all modifications to this\n    file or any of the AFM files are prominently noted in the modified file(s);\n    and that this paragraph is not modified. Adobe Systems has no responsibility\n    or obligation to support the use of the AFM files.\n    \n    */\n  \t},\n  \t    fontMetrics = { 'Unicode': {\n  \t\t\t// all sizing numbers are n/fontMetricsFractionOf = one font size unit\n  \t\t\t// this means that if fontMetricsFractionOf = 1000, and letter A's width is 476, it's\n  \t\t\t// width is 476/1000 or 47.6% of its height (regardless of font size)\n  \t\t\t// At this time this value applies to \"widths\" and \"kerning\" numbers.\n\n  \t\t\t// char code 0 represents \"default\" (average) width - use it for chars missing in this table.\n  \t\t\t// key 'fof' represents the \"fontMetricsFractionOf\" value\n\n  \t\t\t'Courier-Oblique': uncompress(\"{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}\"),\n  \t\t\t'Times-BoldItalic': uncompress(\"{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'kerning'{cl{4qu5kt5qt5rs17ss5ts}201s{201ss}201t{cks4lscmscnscoscpscls2wu2yu201ts}201x{2wu2yu}2k{201ts}2w{4qx5kx5ou5qx5rs17su5tu}2x{17su5tu5ou}2y{4qx5kx5ou5qx5rs17ss5ts}'fof'-6ofn{17sw5tw5ou5qw5rs}7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qs}3v{17su5tu5os5qs}7p{17su5tu}ck{4qu5kt5qt5rs17ss5ts}4l{4qu5kt5qt5rs17ss5ts}cm{4qu5kt5qt5rs17ss5ts}cn{4qu5kt5qt5rs17ss5ts}co{4qu5kt5qt5rs17ss5ts}cp{4qu5kt5qt5rs17ss5ts}6l{4qu5ou5qw5rt17su5tu}5q{ckuclucmucnucoucpu4lu}5r{ckuclucmucnucoucpu4lu}7q{cksclscmscnscoscps4ls}6p{4qu5ou5qw5rt17sw5tw}ek{4qu5ou5qw5rt17su5tu}el{4qu5ou5qw5rt17su5tu}em{4qu5ou5qw5rt17su5tu}en{4qu5ou5qw5rt17su5tu}eo{4qu5ou5qw5rt17su5tu}ep{4qu5ou5qw5rt17su5tu}es{17ss5ts5qs4qu}et{4qu5ou5qw5rt17sw5tw}eu{4qu5ou5qw5rt17ss5ts}ev{17ss5ts5qs4qu}6z{17sw5tw5ou5qw5rs}fm{17sw5tw5ou5qw5rs}7n{201ts}fo{17sw5tw5ou5qw5rs}fp{17sw5tw5ou5qw5rs}fq{17sw5tw5ou5qw5rs}7r{cksclscmscnscoscps4ls}fs{17sw5tw5ou5qw5rs}ft{17su5tu}fu{17su5tu}fv{17su5tu}fw{17su5tu}fz{cksclscmscnscoscps4ls}}}\"),\n  \t\t\t'Helvetica-Bold': uncompress(\"{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}\"),\n  \t\t\t'Courier': uncompress(\"{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}\"),\n  \t\t\t'Courier-BoldOblique': uncompress(\"{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}\"),\n  \t\t\t'Times-Bold': uncompress(\"{'widths'{k3q2q5ncx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2l202m2n2n3m2o3m2p6o202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5x4l4s4m4m4n4s4o4s4p4m4q3x4r4y4s4y4t2r4u3m4v4y4w4m4x5y4y4s4z4y5k3x5l4y5m4s5n3r5o4m5p4s5q4s5r6o5s4s5t4s5u4m5v2l5w1w5x2l5y3u5z3m6k2l6l3m6m3r6n2w6o3r6p2w6q2l6r3m6s3r6t1w6u2l6v3r6w1w6x5n6y3r6z3m7k3r7l3r7m2w7n2r7o2l7p3r7q3m7r4s7s3m7t3m7u2w7v2r7w1q7x2r7y3o202l3mcl4sal2lam3man3mao3map3mar3mas2lat4uau1yav3maw3tay4uaz2lbk2sbl3t'fof'6obo2lbp3rbr1tbs2lbu2lbv3mbz3mck4s202k3mcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3rek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3m3u2l17s4s19m3m}'kerning'{cl{4qt5ks5ot5qy5rw17sv5tv}201t{cks4lscmscnscoscpscls4wv}2k{201ts}2w{4qu5ku7mu5os5qx5ru17su5tu}2x{17su5tu5ou5qs}2y{4qv5kv7mu5ot5qz5ru17su5tu}'fof'-6o7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qu}3v{17su5tu5os5qu}fu{17su5tu5ou5qu}7p{17su5tu5ou5qu}ck{4qt5ks5ot5qy5rw17sv5tv}4l{4qt5ks5ot5qy5rw17sv5tv}cm{4qt5ks5ot5qy5rw17sv5tv}cn{4qt5ks5ot5qy5rw17sv5tv}co{4qt5ks5ot5qy5rw17sv5tv}cp{4qt5ks5ot5qy5rw17sv5tv}6l{17st5tt5ou5qu}17s{ckuclucmucnucoucpu4lu4wu}5o{ckuclucmucnucoucpu4lu4wu}5q{ckzclzcmzcnzcozcpz4lz4wu}5r{ckxclxcmxcnxcoxcpx4lx4wu}5t{ckuclucmucnucoucpu4lu4wu}7q{ckuclucmucnucoucpu4lu}6p{17sw5tw5ou5qu}ek{17st5tt5qu}el{17st5tt5ou5qu}em{17st5tt5qu}en{17st5tt5qu}eo{17st5tt5qu}ep{17st5tt5ou5qu}es{17ss5ts5qu}et{17sw5tw5ou5qu}eu{17sw5tw5ou5qu}ev{17ss5ts5qu}6z{17sw5tw5ou5qu5rs}fm{17sw5tw5ou5qu5rs}fn{17sw5tw5ou5qu5rs}fo{17sw5tw5ou5qu5rs}fp{17sw5tw5ou5qu5rs}fq{17sw5tw5ou5qu5rs}7r{cktcltcmtcntcotcpt4lt5os}fs{17sw5tw5ou5qu5rs}ft{17su5tu5ou5qu}7m{5os}fv{17su5tu5ou5qu}fw{17su5tu5ou5qu}fz{cksclscmscnscoscps4ls}}}\"),\n  \t\t\t'Symbol': uncompress(\"{'widths'{k3uaw4r19m3m2k1t2l2l202m2y2n3m2p5n202q6o3k3m2s2l2t2l2v3r2w1t3m3m2y1t2z1wbk2sbl3r'fof'6o3n3m3o3m3p3m3q3m3r3m3s3m3t3m3u1w3v1w3w3r3x3r3y3r3z2wbp3t3l3m5v2l5x2l5z3m2q4yfr3r7v3k7w1o7x3k}'kerning'{'fof'-6o}}\"),\n  \t\t\t'Helvetica': uncompress(\"{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}\"),\n  \t\t\t'Helvetica-BoldOblique': uncompress(\"{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}\"),\n  \t\t\t'ZapfDingbats': uncompress(\"{'widths'{k4u2k1w'fof'6o}'kerning'{'fof'-6o}}\"),\n  \t\t\t'Courier-Bold': uncompress(\"{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}\"),\n  \t\t\t'Times-Italic': uncompress(\"{'widths'{k3n2q4ycx2l201n3m201o5t201s2l201t2l201u2l201w3r201x3r201y3r2k1t2l2l202m2n2n3m2o3m2p5n202q5t2r1p2s2l2t2l2u3m2v4n2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w4n3x4n3y4n3z3m4k5w4l3x4m3x4n4m4o4s4p3x4q3x4r4s4s4s4t2l4u2w4v4m4w3r4x5n4y4m4z4s5k3x5l4s5m3x5n3m5o3r5p4s5q3x5r5n5s3x5t3r5u3r5v2r5w1w5x2r5y2u5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q1w6r3m6s3m6t1w6u1w6v2w6w1w6x4s6y3m6z3m7k3m7l3m7m2r7n2r7o1w7p3m7q2w7r4m7s2w7t2w7u2r7v2s7w1v7x2s7y3q202l3mcl3xal2ram3man3mao3map3mar3mas2lat4wau1vav3maw4nay4waz2lbk2sbl4n'fof'6obo2lbp3mbq3obr1tbs2lbu1zbv3mbz3mck3x202k3mcm3xcn3xco3xcp3xcq5tcr4mcs3xct3xcu3xcv3xcw2l2m2ucy2lcz2ldl4mdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr4nfs3mft3mfu3mfv3mfw3mfz2w203k6o212m6m2dw2l2cq2l3t3m3u2l17s3r19m3m}'kerning'{cl{5kt4qw}201s{201sw}201t{201tw2wy2yy6q-t}201x{2wy2yy}2k{201tw}2w{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}2x{17ss5ts5os}2y{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}'fof'-6o6t{17ss5ts5qs}7t{5os}3v{5qs}7p{17su5tu5qs}ck{5kt4qw}4l{5kt4qw}cm{5kt4qw}cn{5kt4qw}co{5kt4qw}cp{5kt4qw}6l{4qs5ks5ou5qw5ru17su5tu}17s{2ks}5q{ckvclvcmvcnvcovcpv4lv}5r{ckuclucmucnucoucpu4lu}5t{2ks}6p{4qs5ks5ou5qw5ru17su5tu}ek{4qs5ks5ou5qw5ru17su5tu}el{4qs5ks5ou5qw5ru17su5tu}em{4qs5ks5ou5qw5ru17su5tu}en{4qs5ks5ou5qw5ru17su5tu}eo{4qs5ks5ou5qw5ru17su5tu}ep{4qs5ks5ou5qw5ru17su5tu}es{5ks5qs4qs}et{4qs5ks5ou5qw5ru17su5tu}eu{4qs5ks5qw5ru17su5tu}ev{5ks5qs4qs}ex{17ss5ts5qs}6z{4qv5ks5ou5qw5ru17su5tu}fm{4qv5ks5ou5qw5ru17su5tu}fn{4qv5ks5ou5qw5ru17su5tu}fo{4qv5ks5ou5qw5ru17su5tu}fp{4qv5ks5ou5qw5ru17su5tu}fq{4qv5ks5ou5qw5ru17su5tu}7r{5os}fs{4qv5ks5ou5qw5ru17su5tu}ft{17su5tu5qs}fu{17su5tu5qs}fv{17su5tu5qs}fw{17su5tu5qs}}}\"),\n  \t\t\t'Times-Roman': uncompress(\"{'widths'{k3n2q4ycx2l201n3m201o6o201s2l201t2l201u2l201w2w201x2w201y2w2k1t2l2l202m2n2n3m2o3m2p5n202q6o2r1m2s2l2t2l2u3m2v3s2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v1w3w3s3x3s3y3s3z2w4k5w4l4s4m4m4n4m4o4s4p3x4q3r4r4s4s4s4t2l4u2r4v4s4w3x4x5t4y4s4z4s5k3r5l4s5m4m5n3r5o3x5p4s5q4s5r5y5s4s5t4s5u3x5v2l5w1w5x2l5y2z5z3m6k2l6l2w6m3m6n2w6o3m6p2w6q2l6r3m6s3m6t1w6u1w6v3m6w1w6x4y6y3m6z3m7k3m7l3m7m2l7n2r7o1w7p3m7q3m7r4s7s3m7t3m7u2w7v3k7w1o7x3k7y3q202l3mcl4sal2lam3man3mao3map3mar3mas2lat4wau1vav3maw3say4waz2lbk2sbl3s'fof'6obo2lbp3mbq2xbr1tbs2lbu1zbv3mbz2wck4s202k3mcm4scn4sco4scp4scq5tcr4mcs3xct3xcu3xcv3xcw2l2m2tcy2lcz2ldl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek2wel2wem2wen2weo2wep2weq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr3sfs3mft3mfu3mfv3mfw3mfz3m203k6o212m6m2dw2l2cq2l3t3m3u1w17s4s19m3m}'kerning'{cl{4qs5ku17sw5ou5qy5rw201ss5tw201ws}201s{201ss}201t{ckw4lwcmwcnwcowcpwclw4wu201ts}2k{201ts}2w{4qs5kw5os5qx5ru17sx5tx}2x{17sw5tw5ou5qu}2y{4qs5kw5os5qx5ru17sx5tx}'fof'-6o7t{ckuclucmucnucoucpu4lu5os5rs}3u{17su5tu5qs}3v{17su5tu5qs}7p{17sw5tw5qs}ck{4qs5ku17sw5ou5qy5rw201ss5tw201ws}4l{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cm{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cn{4qs5ku17sw5ou5qy5rw201ss5tw201ws}co{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cp{4qs5ku17sw5ou5qy5rw201ss5tw201ws}6l{17su5tu5os5qw5rs}17s{2ktclvcmvcnvcovcpv4lv4wuckv}5o{ckwclwcmwcnwcowcpw4lw4wu}5q{ckyclycmycnycoycpy4ly4wu5ms}5r{cktcltcmtcntcotcpt4lt4ws}5t{2ktclvcmvcnvcovcpv4lv4wuckv}7q{cksclscmscnscoscps4ls}6p{17su5tu5qw5rs}ek{5qs5rs}el{17su5tu5os5qw5rs}em{17su5tu5os5qs5rs}en{17su5qs5rs}eo{5qs5rs}ep{17su5tu5os5qw5rs}es{5qs}et{17su5tu5qw5rs}eu{17su5tu5qs5rs}ev{5qs}6z{17sv5tv5os5qx5rs}fm{5os5qt5rs}fn{17sv5tv5os5qx5rs}fo{17sv5tv5os5qx5rs}fp{5os5qt5rs}fq{5os5qt5rs}7r{ckuclucmucnucoucpu4lu5os}fs{17sv5tv5os5qx5rs}ft{17ss5ts5qs}fu{17sw5tw5qs}fv{17sw5tw5qs}fw{17ss5ts5qs}fz{ckuclucmucnucoucpu4lu5os5rs}}}\"),\n  \t\t\t'Helvetica-Oblique': uncompress(\"{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}\")\n  \t\t} };\n\n  \t/*\n   This event handler is fired when a new jsPDF object is initialized\n   This event handler appends metrics data to standard fonts within\n   that jsPDF instance. The metrics are mapped over Unicode character\n   codes, NOT CIDs or other codes matching the StandardEncoding table of the\n   standard PDF fonts.\n   Future:\n   Also included is the encoding maping table, converting Unicode (UCS-2, UTF-16)\n   char codes to StandardEncoding character codes. The encoding table is to be used\n   somewhere around \"pdfEscape\" call.\n   */\n\n  \tAPI.events.push(['addFont', function (font) {\n  \t\tvar metrics,\n  \t\t    unicode_section,\n  \t\t    encoding = 'Unicode',\n  \t\t    encodingBlock;\n\n  \t\tmetrics = fontMetrics[encoding][font.postScriptName];\n  \t\tif (metrics) {\n  \t\t\tif (font.metadata[encoding]) {\n  \t\t\t\tunicode_section = font.metadata[encoding];\n  \t\t\t} else {\n  \t\t\t\tunicode_section = font.metadata[encoding] = {};\n  \t\t\t}\n\n  \t\t\tunicode_section.widths = metrics.widths;\n  \t\t\tunicode_section.kerning = metrics.kerning;\n  \t\t}\n\n  \t\tencodingBlock = encodings[encoding][font.postScriptName];\n  \t\tif (encodingBlock) {\n  \t\t\tif (font.metadata[encoding]) {\n  \t\t\t\tunicode_section = font.metadata[encoding];\n  \t\t\t} else {\n  \t\t\t\tunicode_section = font.metadata[encoding] = {};\n  \t\t\t}\n\n  \t\t\tunicode_section.encoding = encodingBlock;\n  \t\t\tif (encodingBlock.codePages && encodingBlock.codePages.length) {\n  \t\t\t\tfont.encoding = encodingBlock.codePages[0];\n  \t\t\t}\n  \t\t}\n  \t}]); // end of adding event handler\n  })(jsPDF.API);\n\n  /**\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n  (function (jsPDF, global) {\n\n      jsPDF.API.events.push(['addFont', function (font) {\n          if (jsPDF.API.existsFileInVFS(font.postScriptName)) {\n              font.metadata = jsPDF.API.TTFFont.open(font.postScriptName, font.fontName, jsPDF.API.getFileFromVFS(font.postScriptName), font.encoding);\n              font.metadata.Unicode = font.metadata.Unicode || { encoding: {}, kerning: {}, widths: [] };\n          } else if (font.id.slice(1) > 14) {\n              console.error(\"Font does not exist in FileInVFS, import fonts or remove declaration doc.addFont('\" + font.postScriptName + \"').\");\n          }\n      }]); // end of adding event handler\n  })(jsPDF, typeof self !== \"undefined\" && self || typeof global !== \"undefined\" && global || typeof window !== \"undefined\" && window || Function(\"return this\")());\n\n  /** @preserve\n  jsPDF SVG plugin\n  Copyright (c) 2012 Willow Systems Corporation, willow-systems.com\n  */\n  (function (jsPDFAPI) {\n\n      /**\n      * Parses SVG XML and converts only some of the SVG elements into\n      * PDF elements.\n      *\n      * Supports:\n      * paths\n      * \n      * @name addSvg\n      * @public\n      * @function\n      * @param {String} SVG-Data as Text\n      * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n      * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n      * @param {Number} width of SVG (in units declared at inception of PDF document)\n      * @param {Number} height of SVG (in units declared at inception of PDF document)\n      * @returns {Object} jsPDF-instance\n      */\n\n      jsPDFAPI.addSvg = function (svgtext, x, y, w, h) {\n          // 'this' is _jsPDF object returned when jsPDF is inited (new jsPDF())\n\n          var undef;\n\n          if (x === undef || y === undef) {\n              throw new Error(\"addSVG needs values for 'x' and 'y'\");\n          }\n\n          function InjectCSS(cssbody, document) {\n              var styletag = document.createElement('style');\n              styletag.type = 'text/css';\n              if (styletag.styleSheet) {\n                  // ie\n                  styletag.styleSheet.cssText = cssbody;\n              } else {\n                  // others\n                  styletag.appendChild(document.createTextNode(cssbody));\n              }\n              document.getElementsByTagName(\"head\")[0].appendChild(styletag);\n          }\n\n          function createWorkerNode(document) {\n\n              var frameID = 'childframe' // Date.now().toString() + '_' + (Math.random() * 100).toString()\n              ,\n                  frame = document.createElement('iframe');\n\n              InjectCSS('.jsPDF_sillysvg_iframe {display:none;position:absolute;}', document);\n\n              frame.name = frameID;\n              frame.setAttribute(\"width\", 0);\n              frame.setAttribute(\"height\", 0);\n              frame.setAttribute(\"frameborder\", \"0\");\n              frame.setAttribute(\"scrolling\", \"no\");\n              frame.setAttribute(\"seamless\", \"seamless\");\n              frame.setAttribute(\"class\", \"jsPDF_sillysvg_iframe\");\n\n              document.body.appendChild(frame);\n\n              return frame;\n          }\n\n          function attachSVGToWorkerNode(svgtext, frame) {\n              var framedoc = (frame.contentWindow || frame.contentDocument).document;\n              framedoc.write(svgtext);\n              framedoc.close();\n              return framedoc.getElementsByTagName('svg')[0];\n          }\n\n          function convertPathToPDFLinesArgs(path) {\n              // we will use 'lines' method call. it needs:\n              // - starting coordinate pair\n              // - array of arrays of vector shifts (2-len for line, 6 len for bezier)\n              // - scale array [horizontal, vertical] ratios\n              // - style (stroke, fill, both)\n\n              var x = parseFloat(path[1]),\n                  y = parseFloat(path[2]),\n                  vectors = [],\n                  position = 3,\n                  len = path.length;\n\n              while (position < len) {\n                  if (path[position] === 'c') {\n                      vectors.push([parseFloat(path[position + 1]), parseFloat(path[position + 2]), parseFloat(path[position + 3]), parseFloat(path[position + 4]), parseFloat(path[position + 5]), parseFloat(path[position + 6])]);\n                      position += 7;\n                  } else if (path[position] === 'l') {\n                      vectors.push([parseFloat(path[position + 1]), parseFloat(path[position + 2])]);\n                      position += 3;\n                  } else {\n                      position += 1;\n                  }\n              }\n              return [x, y, vectors];\n          }\n\n          var workernode = createWorkerNode(document),\n              svgnode = attachSVGToWorkerNode(svgtext, workernode),\n              scale = [1, 1],\n              svgw = parseFloat(svgnode.getAttribute('width')),\n              svgh = parseFloat(svgnode.getAttribute('height'));\n\n          if (svgw && svgh) {\n              // setting both w and h makes image stretch to size.\n              // this may distort the image, but fits your demanded size\n              if (w && h) {\n                  scale = [w / svgw, h / svgh];\n              }\n              // if only one is set, that value is set as max and SVG\n              // is scaled proportionately.\n              else if (w) {\n                      scale = [w / svgw, w / svgw];\n                  } else if (h) {\n                      scale = [h / svgh, h / svgh];\n                  }\n          }\n\n          var i,\n              l,\n              tmp,\n              linesargs,\n              items = svgnode.childNodes;\n          for (i = 0, l = items.length; i < l; i++) {\n              tmp = items[i];\n              if (tmp.tagName && tmp.tagName.toUpperCase() === 'PATH') {\n                  linesargs = convertPathToPDFLinesArgs(tmp.getAttribute(\"d\").split(' '));\n                  // path start x coordinate\n                  linesargs[0] = linesargs[0] * scale[0] + x; // where x is upper left X of image\n                  // path start y coordinate\n                  linesargs[1] = linesargs[1] * scale[1] + y; // where y is upper left Y of image\n                  // the rest of lines are vectors. these will adjust with scale value auto.\n                  this.lines.call(this, linesargs[2] // lines\n                  , linesargs[0] // starting x\n                  , linesargs[1] // starting y\n                  , scale);\n              }\n          }\n\n          // clean up\n          // workernode.parentNode.removeChild(workernode)\n\n          return this;\n      };\n\n      //fallback\n      jsPDFAPI.addSVG = jsPDFAPI.addSvg;\n\n      /**\n      * Parses SVG XML and saves it as image into the PDF.\n      *\n      * Depends on canvas-element and canvg\n      *\n      * @name addSvgAsImage\n      * @public\n      * @function\n      * @param {String} SVG-Data as Text\n      * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n      * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n      * @param {Number} width of SVG-Image (in units declared at inception of PDF document)\n      * @param {Number} height of SVG-Image (in units declared at inception of PDF document)\n      * @param {String} alias of SVG-Image (if used multiple times)\n      * @param {String} compression of the generated JPEG, can have the values 'NONE', 'FAST', 'MEDIUM' and 'SLOW'\n      * @param {Number} rotation of the image in degrees (0-359)\n      * \n      * @returns jsPDF\n      * @methodOf jsPDF#\n      */\n      jsPDFAPI.addSvgAsImage = function (svg, x, y, w, h, alias, compression, rotation) {\n\n          if (isNaN(x) || isNaN(y)) {\n              console.error('jsPDF.addSvgAsImage: Invalid coordinates', arguments);\n              throw new Error('Invalid coordinates passed to jsPDF.addSvgAsImage');\n          }\n\n          if (isNaN(w) || isNaN(h)) {\n              console.error('jsPDF.addSvgAsImage: Invalid measurements', arguments);\n              throw new Error('Invalid measurements (width and/or height) passed to jsPDF.addSvgAsImage');\n          }\n\n          var canvas = document.createElement('canvas');\n          canvas.width = w;\n          canvas.height = h;\n          var ctx = canvas.getContext('2d');\n          ctx.fillStyle = '#fff'; /// set white fill style\n          ctx.fillRect(0, 0, canvas.width, canvas.height);\n\n          //load a svg snippet in the canvas with id = 'drawingArea'\n          canvg(canvas, svg, {\n              ignoreMouse: true,\n              ignoreAnimation: true,\n              ignoreDimensions: true,\n              ignoreClear: true\n          });\n\n          this.addImage(canvas.toDataURL(\"image/jpeg\", 1.0), x, y, w, h, compression, rotation);\n          return this;\n      };\n  })(jsPDF.API);\n\n  /** ==================================================================== \n   * jsPDF total_pages plugin\n   * Copyright (c) 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br\n   * \n   * \n   * ====================================================================\n   */\n\n  (function (jsPDFAPI) {\n\n    jsPDFAPI.putTotalPages = function (pageExpression) {\n\n      var replaceExpression = new RegExp(pageExpression, 'g');\n      for (var n = 1; n <= this.internal.getNumberOfPages(); n++) {\n        for (var i = 0; i < this.internal.pages[n].length; i++) {\n          this.internal.pages[n][i] = this.internal.pages[n][i].replace(replaceExpression, this.internal.getNumberOfPages());\n        }\n      }\n      return this;\n    };\n  })(jsPDF.API);\n\n  /**\n   * jsPDF viewerPreferences Plugin\n   * @author Aras Abbasi (github.com/arasabbasi)\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n\n  /**\n  * Adds the ability to set ViewerPreferences and by thus\n  * controlling the way the document is to be presented on the\n  * screen or in print.\n  */\n\n  (function (jsPDFAPI) {\n      /**\n       * Set the ViewerPreferences of the generated PDF\n       *\n       * @param {Object} options Array with the ViewerPreferences<br />\n       * Example: doc.viewerPreferences({\"FitWindow\":true});<br />\n       * <br />\n       * You can set following preferences:<br />\n       * <br/>\n       * <b>HideToolbar</b> <i>(boolean)</i><br />\n       * Default value: false<br />\n       * <br />\n       * <b>HideMenubar</b> <i>(boolean)</i><br />\n       * Default value: false.<br />\n       * <br />\n       * <b>HideWindowUI</b> <i>(boolean)</i><br />\n       * Default value: false.<br />\n       * <br />\n       * <b>FitWindow</b> <i>(boolean)</i><br />\n       * Default value: false.<br />\n       * <br />\n       * <b>CenterWindow</b> <i>(boolean)</i><br />\n       * Default value: false<br />\n       * <br />\n       * <b>DisplayDocTitle</b> <i>(boolean)</i><br />\n       * Default value: false.<br />\n       * <br />\n       * <b>NonFullScreenPageMode</b> <i>(String)</i><br />\n       * Possible values: UseNone, UseOutlines, UseThumbs, UseOC<br />\n       * Default value: UseNone<br/>\n       * <br />\n       * <b>Direction</b> <i>(String)</i><br />\n       * Possible values: L2R, R2L<br />\n       * Default value: L2R.<br />\n       * <br />\n       * <b>ViewArea</b> <i>(String)</i><br />\n       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />\n       * Default value: CropBox.<br />\n       * <br />\n       * <b>ViewClip</b> <i>(String)</i><br />\n       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />\n       * Default value: CropBox<br />\n       * <br />\n       * <b>PrintArea</b> <i>(String)</i><br />\n       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />\n       * Default value: CropBox<br />\n       * <br />\n       * <b>PrintClip</b> <i>(String)</i><br />\n       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />\n       * Default value: CropBox.<br />\n       * <br />\n       * <b>PrintScaling</b> <i>(String)</i><br />\n       * Possible values: AppDefault, None<br />\n       * Default value: AppDefault.<br />\n       * <br />\n       * <b>Duplex</b> <i>(String)</i><br />\n       * Possible values: Simplex, DuplexFlipLongEdge, DuplexFlipShortEdge\n       * Default value: none<br />\n       * <br />\n       * <b>PickTrayByPDFSize</b> <i>(boolean)</i><br />\n       * Default value: false<br />\n       * <br />\n       * <b>PrintPageRange</b> <i>(Array)</i><br />\n       * Example: [[1,5], [7,9]]<br />\n       * Default value: as defined by PDF viewer application<br />\n       * <br />\n       * <b>NumCopies</b> <i>(Number)</i><br />\n       * Possible values: 1, 2, 3, 4, 5<br />\n       * Default value: 1<br />\n       * <br />\n       * For more information see the PDF Reference, sixth edition on Page 577\n       * @param {boolean} doReset True to reset the settings\n       * @function\n       * @returns jsPDF\n       * @methodOf jsPDF#\n       * @example\n       * var doc = new jsPDF()\n       * doc.text('This is a test', 10, 10)\n       * doc.viewerPreferences({'FitWindow': true}, true)\n       * doc.save(\"viewerPreferences.pdf\")\n       *\n       * // Example printing 10 copies, using cropbox, and hiding UI.\n       * doc.viewerPreferences({\n       *   'HideWindowUI': true,\n       *   'PrintArea': 'CropBox',\n       *   'NumCopies': 10\n       * })\n       * @name viewerPreferences\n       */\n\n      jsPDFAPI.viewerPreferences = function (options, doReset) {\n          options = options || {};\n          doReset = doReset || false;\n\n          var configuration;\n          var configurationTemplate = {\n              \"HideToolbar\": { defaultValue: false, value: false, type: \"boolean\", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },\n              \"HideMenubar\": { defaultValue: false, value: false, type: \"boolean\", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },\n              \"HideWindowUI\": { defaultValue: false, value: false, type: \"boolean\", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },\n              \"FitWindow\": { defaultValue: false, value: false, type: \"boolean\", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },\n              \"CenterWindow\": { defaultValue: false, value: false, type: \"boolean\", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },\n              \"DisplayDocTitle\": { defaultValue: false, value: false, type: \"boolean\", explicitSet: false, valueSet: [true, false], pdfVersion: 1.4 },\n              \"NonFullScreenPageMode\": { defaultValue: \"UseNone\", value: \"UseNone\", type: \"name\", explicitSet: false, valueSet: [\"UseNone\", \"UseOutlines\", \"UseThumbs\", \"UseOC\"], pdfVersion: 1.3 },\n              \"Direction\": { defaultValue: \"L2R\", value: \"L2R\", type: \"name\", explicitSet: false, valueSet: [\"L2R\", \"R2L\"], pdfVersion: 1.3 },\n              \"ViewArea\": { defaultValue: \"CropBox\", value: \"CropBox\", type: \"name\", explicitSet: false, valueSet: [\"MediaBox\", \"CropBox\", \"TrimBox\", \"BleedBox\", \"ArtBox\"], pdfVersion: 1.4 },\n              \"ViewClip\": { defaultValue: \"CropBox\", value: \"CropBox\", type: \"name\", explicitSet: false, valueSet: [\"MediaBox\", \"CropBox\", \"TrimBox\", \"BleedBox\", \"ArtBox\"], pdfVersion: 1.4 },\n              \"PrintArea\": { defaultValue: \"CropBox\", value: \"CropBox\", type: \"name\", explicitSet: false, valueSet: [\"MediaBox\", \"CropBox\", \"TrimBox\", \"BleedBox\", \"ArtBox\"], pdfVersion: 1.4 },\n              \"PrintClip\": { defaultValue: \"CropBox\", value: \"CropBox\", type: \"name\", explicitSet: false, valueSet: [\"MediaBox\", \"CropBox\", \"TrimBox\", \"BleedBox\", \"ArtBox\"], pdfVersion: 1.4 },\n              \"PrintScaling\": { defaultValue: \"AppDefault\", value: \"AppDefault\", type: \"name\", explicitSet: false, valueSet: [\"AppDefault\", \"None\"], pdfVersion: 1.6 },\n              \"Duplex\": { defaultValue: \"\", value: \"none\", type: \"name\", explicitSet: false, valueSet: [\"Simplex\", \"DuplexFlipShortEdge\", \"DuplexFlipLongEdge\", \"none\"], pdfVersion: 1.7 },\n              \"PickTrayByPDFSize\": { defaultValue: false, value: false, type: \"boolean\", explicitSet: false, valueSet: [true, false], pdfVersion: 1.7 },\n              \"PrintPageRange\": { defaultValue: \"\", value: \"\", type: \"array\", explicitSet: false, valueSet: null, pdfVersion: 1.7 },\n              \"NumCopies\": { defaultValue: 1, value: 1, type: \"integer\", explicitSet: false, valueSet: null, pdfVersion: 1.7 }\n          };\n\n          var configurationKeys = Object.keys(configurationTemplate);\n\n          var rangeArray = [];\n          var i = 0;\n          var j = 0;\n          var k = 0;\n          var isValid = true;\n\n          var method;\n          var value;\n\n          function arrayContainsElement(array, element) {\n              var iterator;\n              var result = false;\n\n              for (iterator = 0; iterator < array.length; iterator += 1) {\n                  if (array[iterator] === element) {\n                      result = true;\n                  }\n              }\n              return result;\n          }\n\n          if (this.internal.viewerpreferences === undefined) {\n              this.internal.viewerpreferences = {};\n              this.internal.viewerpreferences.configuration = JSON.parse(JSON.stringify(configurationTemplate));\n              this.internal.viewerpreferences.isSubscribed = false;\n          }\n          configuration = this.internal.viewerpreferences.configuration;\n\n          if (options === \"reset\" || doReset === true) {\n              var len = configurationKeys.length;\n\n              for (k = 0; k < len; k += 1) {\n                  configuration[configurationKeys[k]].value = configuration[configurationKeys[k]].defaultValue;\n                  configuration[configurationKeys[k]].explicitSet = false;\n              }\n          }\n\n          if ((typeof options === \"undefined\" ? \"undefined\" : _typeof(options)) === \"object\") {\n              for (method in options) {\n                  value = options[method];\n                  if (arrayContainsElement(configurationKeys, method) && value !== undefined) {\n\n                      if (configuration[method].type === \"boolean\" && typeof value === \"boolean\") {\n                          configuration[method].value = value;\n                      } else if (configuration[method].type === \"name\" && arrayContainsElement(configuration[method].valueSet, value)) {\n                          configuration[method].value = value;\n                      } else if (configuration[method].type === \"integer\" && Number.isInteger(value)) {\n                          configuration[method].value = value;\n                      } else if (configuration[method].type === \"array\") {\n\n                          for (i = 0; i < value.length; i += 1) {\n                              isValid = true;\n                              if (value[i].length === 1 && typeof value[i][0] === \"number\") {\n                                  rangeArray.push(String(value[i]));\n                              } else if (value[i].length > 1) {\n                                  for (j = 0; j < value[i].length; j += 1) {\n                                      if (typeof value[i][j] !== \"number\") {\n                                          isValid = false;\n                                      }\n                                  }\n                                  if (isValid === true) {\n                                      rangeArray.push(String(value[i].join(\"-\")));\n                                  }\n                              }\n                          }\n                          configuration[method].value = String(rangeArray);\n                      } else {\n                          configuration[method].value = configuration[method].defaultValue;\n                      }\n\n                      configuration[method].explicitSet = true;\n                  }\n              }\n          }\n\n          if (this.internal.viewerpreferences.isSubscribed === false) {\n              this.internal.events.subscribe(\"putCatalog\", function () {\n                  var pdfDict = [];\n                  var vPref;\n                  for (vPref in configuration) {\n                      if (configuration[vPref].explicitSet === true) {\n                          if (configuration[vPref].type === \"name\") {\n                              pdfDict.push(\"/\" + vPref + \" /\" + configuration[vPref].value);\n                          } else {\n                              pdfDict.push(\"/\" + vPref + \" \" + configuration[vPref].value);\n                          }\n                      }\n                  }\n                  if (pdfDict.length !== 0) {\n                      this.internal.write(\"/ViewerPreferences\\n<<\\n\" + pdfDict.join(\"\\n\") + \"\\n>>\");\n                  }\n              });\n              this.internal.viewerpreferences.isSubscribed = true;\n          }\n\n          this.internal.viewerpreferences.configuration = configuration;\n          return this;\n      };\n  })(jsPDF.API);\n\n  /** ==================================================================== \n   * jsPDF XMP metadata plugin\n   * Copyright (c) 2016 Jussi Utunen, u-jussi@suomi24.fi\n   * \n   * \n   * ====================================================================\n   */\n\n  /*global jsPDF */\n\n  /**\n  * Adds XMP formatted metadata to PDF\n  *\n  * @param {String} metadata The actual metadata to be added. The metadata shall be stored as XMP simple value. Note that if the metadata string contains XML markup characters \"<\", \">\" or \"&\", those characters should be written using XML entities.\n  * @param {String} namespaceuri Sets the namespace URI for the metadata. Last character should be slash or hash.\n  * @function\n  * @returns {jsPDF}\n  * @methodOf jsPDF#\n  * @name addMetadata\n  */\n\n  (function (jsPDFAPI) {\n\n      var xmpmetadata = \"\";\n      var xmpnamespaceuri = \"\";\n      var metadata_object_number = \"\";\n\n      jsPDFAPI.addMetadata = function (metadata, namespaceuri) {\n          xmpnamespaceuri = namespaceuri || \"http://jspdf.default.namespaceuri/\"; //The namespace URI for an XMP name shall not be empty\n          xmpmetadata = metadata;\n          this.internal.events.subscribe('postPutResources', function () {\n              if (!xmpmetadata) {\n                  metadata_object_number = \"\";\n              } else {\n                  var xmpmeta_beginning = '<x:xmpmeta xmlns:x=\"adobe:ns:meta/\">';\n                  var rdf_beginning = '<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"><rdf:Description rdf:about=\"\" xmlns:jspdf=\"' + xmpnamespaceuri + '\"><jspdf:metadata>';\n                  var rdf_ending = '</jspdf:metadata></rdf:Description></rdf:RDF>';\n                  var xmpmeta_ending = '</x:xmpmeta>';\n                  var utf8_xmpmeta_beginning = unescape(encodeURIComponent(xmpmeta_beginning));\n                  var utf8_rdf_beginning = unescape(encodeURIComponent(rdf_beginning));\n                  var utf8_metadata = unescape(encodeURIComponent(xmpmetadata));\n                  var utf8_rdf_ending = unescape(encodeURIComponent(rdf_ending));\n                  var utf8_xmpmeta_ending = unescape(encodeURIComponent(xmpmeta_ending));\n\n                  var total_len = utf8_rdf_beginning.length + utf8_metadata.length + utf8_rdf_ending.length + utf8_xmpmeta_beginning.length + utf8_xmpmeta_ending.length;\n\n                  metadata_object_number = this.internal.newObject();\n                  this.internal.write('<< /Type /Metadata /Subtype /XML /Length ' + total_len + ' >>');\n                  this.internal.write('stream');\n                  this.internal.write(utf8_xmpmeta_beginning + utf8_rdf_beginning + utf8_metadata + utf8_rdf_ending + utf8_xmpmeta_ending);\n                  this.internal.write('endstream');\n                  this.internal.write('endobj');\n              }\n          });\n          this.internal.events.subscribe('putCatalog', function () {\n              if (metadata_object_number) {\n                  this.internal.write('/Metadata ' + metadata_object_number + ' 0 R');\n              }\n          });\n          return this;\n      };\n  })(jsPDF.API);\n\n  (function (jsPDF, global) {\n\n      var jsPDFAPI = jsPDF.API;\n\n      var glyID = [0];\n      /**************************************************/\n      /* function : toHex                               */\n      /* comment : Replace str with a hex string.       */\n      /**************************************************/\n      function toHex(str) {\n          var hex = '';\n          for (var i = 0; i < str.length; i++) {\n              hex += '' + str.charCodeAt(i).toString(16);\n          }\n          return hex;\n      }\n\n      /***************************************************************************************************/\n      /* function : pdfEscape16                                                                          */\n      /* comment : The character id of a 2-byte string is converted to a hexadecimal number by obtaining */\n      /*   the corresponding glyph id and width, and then adding padding to the string.                  */\n      /***************************************************************************************************/\n      var pdfEscape16 = function pdfEscape16(text, font) {\n          var widths = font.metadata.Unicode.widths;        var padz = [\"\", \"0\", \"00\", \"000\", \"0000\"];\n          var ar = [\"\"];\n          for (var i = 0, l = text.length, t; i < l; ++i) {\n              t = font.metadata.characterToGlyph(text.charCodeAt(i));\n              glyID.push(t);\n              if (widths.indexOf(t) == -1) {\n                  widths.push(t);\n                  widths.push([parseInt(font.metadata.widthOfGlyph(t), 10)]);\n              }\n              if (t == '0') {\n                  //Spaces are not allowed in cmap.\n                  return ar.join(\"\");\n              } else {\n                  t = t.toString(16);\n                  ar.push(padz[4 - t.length], t);\n              }\n          }\n          return ar.join(\"\");\n      };\n\n      var identityHFunction = function identityHFunction(font, out, newObject) {\n\n          if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === 'Identity-H') {\n              //Tag with Identity-H\n              var widths = font.metadata.Unicode.widths;\n              var data = font.metadata.subset.encode(glyID);\n              var pdfOutput = data;\n              var pdfOutput2 = \"\";\n              for (var i = 0; i < pdfOutput.length; i++) {\n                  pdfOutput2 += String.fromCharCode(pdfOutput[i]);\n              }\n              var fontTable = newObject();\n              out('<<');\n              out('/Length ' + pdfOutput2.length);\n              out('/Length1 ' + pdfOutput2.length);\n              out('>>');\n\n              out('stream');\n              out(pdfOutput2);\n              out('endstream');\n              out('endobj');\n\n              var fontDescriptor = newObject();\n              out('<<');\n              out('/Type /FontDescriptor');\n              out('/FontName /' + font.fontName);\n              out('/FontFile2 ' + fontTable + ' 0 R');\n              out('/FontBBox ' + jsPDF.API.PDFObject.convert(font.metadata.bbox));\n              out('/Flags ' + font.metadata.flags);\n              out('/StemV ' + font.metadata.stemV);\n              out('/ItalicAngle ' + font.metadata.italicAngle);\n              out('/Ascent ' + font.metadata.ascender);\n              out('/Descent ' + font.metadata.decender);\n              out('/CapHeight ' + font.metadata.capHeight);\n              out('>>');\n              out('endobj');\n\n              var DescendantFont = newObject();\n              out('<<');\n              out('/Type /Font');\n              out('/BaseFont /' + font.fontName);\n              out('/FontDescriptor ' + fontDescriptor + ' 0 R');\n              out('/W ' + jsPDF.API.PDFObject.convert(widths));\n              out('/CIDToGIDMap /Identity');\n              out('/DW 1000');\n              out('/Subtype /CIDFontType2');\n              out('/CIDSystemInfo');\n              out('<<');\n              out('/Supplement 0');\n              out('/Registry (Adobe)');\n              out('/Ordering (' + font.encoding + ')');\n              out('>>');\n              out('>>');\n              out('endobj');\n\n              font.objectNumber = newObject();\n              out('<<');\n              out('/Type /Font');\n              out('/Subtype /Type0');\n              out('/BaseFont /' + font.fontName);\n              out('/Encoding /' + font.encoding);\n              out('/DescendantFonts [' + DescendantFont + ' 0 R]');\n              out('>>');\n              out('endobj');\n\n              font.isAlreadyPutted = true;\n          }\n      };\n\n      jsPDFAPI.events.push(['putFont', function (args) {\n          identityHFunction(args.font, args.out, args.newObject);\n      }]);\n\n      var winAnsiEncodingFunction = function winAnsiEncodingFunction(font, out, newObject) {\n\n          if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === 'WinAnsiEncoding') {\n              //Tag with WinAnsi encoding\n              var widths = font.metadata.Unicode.widths;\n              var data = font.metadata.rawData;\n              var pdfOutput = data;\n              var pdfOutput2 = \"\";\n              for (var i = 0; i < pdfOutput.length; i++) {\n                  pdfOutput2 += String.fromCharCode(pdfOutput[i]);\n              }\n              var fontTable = newObject();\n              out('<<');\n              out('/Length ' + pdfOutput2.length);\n              out('/Length1 ' + pdfOutput2.length);\n              out('>>');\n              out('stream');\n              out(pdfOutput2);\n              out('endstream');\n              out('endobj');\n              var fontDescriptor = newObject();\n              out('<<');\n              out('/Descent ' + font.metadata.decender);\n              out('/CapHeight ' + font.metadata.capHeight);\n              out('/StemV ' + font.metadata.stemV);\n              out('/Type /FontDescriptor');\n              out('/FontFile2 ' + fontTable + ' 0 R');\n              out('/Flags 96');\n              out('/FontBBox ' + jsPDF.API.PDFObject.convert(font.metadata.bbox));\n              out('/FontName /' + font.fontName);\n              out('/ItalicAngle ' + font.metadata.italicAngle);\n              out('/Ascent ' + font.metadata.ascender);\n              out('>>');\n              out('endobj');\n              font.objectNumber = newObject();\n              for (var i = 0; i < font.metadata.hmtx.widths.length; i++) {\n                  font.metadata.hmtx.widths[i] = parseInt(font.metadata.hmtx.widths[i] * (1000 / font.metadata.head.unitsPerEm)); //Change the width of Em units to Point units.\n              }\n              out('<</Subtype/TrueType/Type/Font/BaseFont/' + font.fontName + '/FontDescriptor ' + fontDescriptor + ' 0 R' + '/Encoding/' + font.encoding + ' /FirstChar 29 /LastChar 255 /Widths ' + jsPDF.API.PDFObject.convert(font.metadata.hmtx.widths) + '>>');\n              out('endobj');\n              font.isAlreadyPutted = true;\n          }\n      };\n\n      jsPDFAPI.events.push(['putFont', function (args) {\n          winAnsiEncodingFunction(args.font, args.out, args.newObject);\n      }]);\n\n      var utf8TextFunction = function utf8TextFunction(args) {\n          var text = args.text || '';\n          var x = args.x;\n          var y = args.y;\n          var options = args.options || {};\n          var mutex = args.mutex || {};\n\n          var pdfEscape = mutex.pdfEscape;\n          var activeFontKey = mutex.activeFontKey;\n          var fonts = mutex.fonts;\n          var key,\n              fontSize = mutex.activeFontSize;\n\n          var str = '',\n              s = 0,\n              cmapConfirm;\n          var strText = '';\n          var attr;\n          var key = activeFontKey;\n          var encoding = fonts[key].encoding;\n\n          if (fonts[key].encoding !== 'Identity-H') {\n              return {\n                  text: text,\n                  x: x,\n                  y: y,\n                  options: options,\n                  mutex: mutex\n              };\n          }\n          strText = text;\n\n          key = attr ? getFont(attr.font, attr.fontStyle) : activeFontKey;\n          if (Object.prototype.toString.call(text) === '[object Array]') {\n              strText = text[0];\n          }\n          for (s = 0; s < strText.length; s += 1) {\n              if (fonts[key].metadata.hasOwnProperty('cmap')) {\n                  cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)];\n                  /*\n                  if (Object.prototype.toString.call(text) === '[object Array]') {\n                             var i = 0;\n                            // for (i = 0; i < text.length; i += 1) {\n                                 if (Object.prototype.toString.call(text[s]) === '[object Array]') {\n                  \tcmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s][0].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id\n                                 } else {\n                                     \n                                 }\n                             //}\n                  \n                         } else {\n                  cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id\n                         }*/\n              }\n              if (!cmapConfirm) {\n                  if (strText[s].charCodeAt(0) < 256 && fonts[key].metadata.hasOwnProperty('Unicode')) {\n                      str += strText[s];\n                  } else {\n                      str += '';\n                  }\n              } else {\n                  str += strText[s];\n              }\n          }\n          var result = '';\n          if (parseInt(key.slice(1)) < 14 || encoding === 'WinAnsiEncoding') {\n              //For the default 13 font\n              result = toHex(pdfEscape(str, key));\n          } else if (encoding === 'Identity-H') {\n              result = pdfEscape16(str, fonts[key]);\n          }\n          mutex.isHex = true;\n\n          return {\n              text: result,\n              x: x,\n              y: y,\n              options: options,\n              mutex: mutex\n          };\n      };\n\n      var utf8EscapeFunction = function utf8EscapeFunction(parms) {\n          var text = parms.text || '',\n              x = parms.x,\n              y = parms.y,\n              options = parms.options,\n              mutex = parms.mutex;\n          var lang = options.lang;\n          var tmpText = [];\n          var args = {\n              text: text,\n              x: x,\n              y: y,\n              options: options,\n              mutex: mutex\n          };\n\n          if (Object.prototype.toString.call(text) === '[object Array]') {\n              var i = 0;\n              for (i = 0; i < text.length; i += 1) {\n                  if (Object.prototype.toString.call(text[i]) === '[object Array]') {\n                      if (text[i].length === 3) {\n                          tmpText.push([utf8TextFunction(Object.assign({}, args, { text: text[i][0] })).text, text[i][1], text[i][2]]);\n                      } else {\n                          tmpText.push(utf8TextFunction(Object.assign({}, args, { text: text[i] })).text);\n                      }\n                  } else {\n                      tmpText.push(utf8TextFunction(Object.assign({}, args, { text: text[i] })).text);\n                  }\n              }\n              parms.text = tmpText;\n          } else {\n              parms.text = utf8TextFunction(Object.assign({}, args, { text: text })).text;\n          }\n      };\n\n      jsPDFAPI.events.push(['postProcessText', utf8EscapeFunction]);\n  })(jsPDF, typeof self !== \"undefined\" && self || typeof global !== \"undefined\" && global || typeof window !== \"undefined\" && window || Function(\"return this\")());\n\n  /**\n   * jsPDF virtual FileSystem functionality\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n\n  /**\n  * Use the vFS to handle files\n  */\n\n  (function (jsPDFAPI) {\n\n      var vFS = {};\n\n      /* Check if the file exists in the vFS\n      * @returns {boolean}\n      * @name existsFileInVFS\n      * @example\n      * doc.existsFileInVFS(\"someFile.txt\");\n      */\n      jsPDFAPI.existsFileInVFS = function (filename) {\n          return vFS.hasOwnProperty(filename);\n      };\n\n      /* Add a file to the vFS\n      * @returns {jsPDF}\n      * @name addFileToVFS\n      * @example\n      * doc.addFileToVFS(\"someFile.txt\", \"BADFACE1\");\n      */\n      jsPDFAPI.addFileToVFS = function (filename, filecontent) {\n          vFS[filename] = filecontent;\n          return this;\n      };\n\n      /* Get the file from the vFS\n      * @returns {string}\n      * @name addFileToVFS\n      * @example\n      * doc.getFileFromVFS(\"someFile.txt\");\n      */\n      jsPDFAPI.getFileFromVFS = function (filename) {\n          if (vFS.hasOwnProperty(filename)) {\n              return vFS[filename];\n          }\n          return null;\n      };\n  })(jsPDF.API);\n\n  /* Blob.js\n   * A Blob implementation.\n   * 2014-07-24\n   *\n   * By Eli Grey, http://eligrey.com\n   * By Devin Samarin, https://github.com/dsamarin\n   * License: X11/MIT\n   *   See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md\n   */\n\n  /*global self, unescape */\n  /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,\n    plusplus: true */\n\n  /*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */\n\n  (function (view) {\n\n  \tview.URL = view.URL || view.webkitURL;\n\n  \tif (view.Blob && view.URL) {\n  \t\ttry {\n  \t\t\tnew Blob;\n  \t\t\treturn;\n  \t\t} catch (e) {}\n  \t}\n\n  \t// Internally we use a BlobBuilder implementation to base Blob off of\n  \t// in order to support older browsers that only have BlobBuilder\n  \tvar BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {\n  \t\tvar\n  \t\t\t  get_class = function(object) {\n  \t\t\t\treturn Object.prototype.toString.call(object).match(/^\\[object\\s(.*)\\]$/)[1];\n  \t\t\t}\n  \t\t\t, FakeBlobBuilder = function BlobBuilder() {\n  \t\t\t\tthis.data = [];\n  \t\t\t}\n  \t\t\t, FakeBlob = function Blob(data, type, encoding) {\n  \t\t\t\tthis.data = data;\n  \t\t\t\tthis.size = data.length;\n  \t\t\t\tthis.type = type;\n  \t\t\t\tthis.encoding = encoding;\n  \t\t\t}\n  \t\t\t, FBB_proto = FakeBlobBuilder.prototype\n  \t\t\t, FB_proto = FakeBlob.prototype\n  \t\t\t, FileReaderSync = view.FileReaderSync\n  \t\t\t, FileException = function(type) {\n  \t\t\t\tthis.code = this[this.name = type];\n  \t\t\t}\n  \t\t\t, file_ex_codes = (\n  \t\t\t\t  \"NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR \"\n  \t\t\t\t+ \"NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR\"\n  \t\t\t).split(\" \")\n  \t\t\t, file_ex_code = file_ex_codes.length\n  \t\t\t, real_URL = view.URL || view.webkitURL || view\n  \t\t\t, real_create_object_URL = real_URL.createObjectURL\n  \t\t\t, real_revoke_object_URL = real_URL.revokeObjectURL\n  \t\t\t, URL = real_URL\n  \t\t\t, btoa = view.btoa\n  \t\t\t, atob = view.atob\n\n  \t\t\t, ArrayBuffer = view.ArrayBuffer\n  \t\t\t, Uint8Array = view.Uint8Array\n\n  \t\t\t, origin = /^[\\w-]+:\\/*\\[?[\\w\\.:-]+\\]?(?::[0-9]+)?/\n  \t\t;\n  \t\tFakeBlob.fake = FB_proto.fake = true;\n  \t\twhile (file_ex_code--) {\n  \t\t\tFileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;\n  \t\t}\n  \t\t// Polyfill URL\n  \t\tif (!real_URL.createObjectURL) {\n  \t\t\tURL = view.URL = function(uri) {\n  \t\t\t\tvar\n  \t\t\t\t\t  uri_info = document.createElementNS(\"http://www.w3.org/1999/xhtml\", \"a\")\n  \t\t\t\t\t, uri_origin\n  \t\t\t\t;\n  \t\t\t\turi_info.href = uri;\n  \t\t\t\tif (!(\"origin\" in uri_info)) {\n  \t\t\t\t\tif (uri_info.protocol.toLowerCase() === \"data:\") {\n  \t\t\t\t\t\turi_info.origin = null;\n  \t\t\t\t\t} else {\n  \t\t\t\t\t\turi_origin = uri.match(origin);\n  \t\t\t\t\t\turi_info.origin = uri_origin && uri_origin[1];\n  \t\t\t\t\t}\n  \t\t\t\t}\n  \t\t\t\treturn uri_info;\n  \t\t\t};\n  \t\t}\n  \t\tURL.createObjectURL = function(blob) {\n  \t\t\tvar\n  \t\t\t\t  type = blob.type\n  \t\t\t\t, data_URI_header\n  \t\t\t;\n  \t\t\tif (type === null) {\n  \t\t\t\ttype = \"application/octet-stream\";\n  \t\t\t}\n  \t\t\tif (blob instanceof FakeBlob) {\n  \t\t\t\tdata_URI_header = \"data:\" + type;\n  \t\t\t\tif (blob.encoding === \"base64\") {\n  \t\t\t\t\treturn data_URI_header + \";base64,\" + blob.data;\n  \t\t\t\t} else if (blob.encoding === \"URI\") {\n  \t\t\t\t\treturn data_URI_header + \",\" + decodeURIComponent(blob.data);\n  \t\t\t\t} if (btoa) {\n  \t\t\t\t\treturn data_URI_header + \";base64,\" + btoa(blob.data);\n  \t\t\t\t} else {\n  \t\t\t\t\treturn data_URI_header + \",\" + encodeURIComponent(blob.data);\n  \t\t\t\t}\n  \t\t\t} else if (real_create_object_URL) {\n  \t\t\t\treturn real_create_object_URL.call(real_URL, blob);\n  \t\t\t}\n  \t\t};\n  \t\tURL.revokeObjectURL = function(object_URL) {\n  \t\t\tif (object_URL.substring(0, 5) !== \"data:\" && real_revoke_object_URL) {\n  \t\t\t\treal_revoke_object_URL.call(real_URL, object_URL);\n  \t\t\t}\n  \t\t};\n  \t\tFBB_proto.append = function(data/*, endings*/) {\n  \t\t\tvar bb = this.data;\n  \t\t\t// decode data to a binary string\n  \t\t\tif (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {\n  \t\t\t\tvar\n  \t\t\t\t\t  str = \"\"\n  \t\t\t\t\t, buf = new Uint8Array(data)\n  \t\t\t\t\t, i = 0\n  \t\t\t\t\t, buf_len = buf.length\n  \t\t\t\t;\n  \t\t\t\tfor (; i < buf_len; i++) {\n  \t\t\t\t\tstr += String.fromCharCode(buf[i]);\n  \t\t\t\t}\n  \t\t\t\tbb.push(str);\n  \t\t\t} else if (get_class(data) === \"Blob\" || get_class(data) === \"File\") {\n  \t\t\t\tif (FileReaderSync) {\n  \t\t\t\t\tvar fr = new FileReaderSync;\n  \t\t\t\t\tbb.push(fr.readAsBinaryString(data));\n  \t\t\t\t} else {\n  \t\t\t\t\t// async FileReader won't work as BlobBuilder is sync\n  \t\t\t\t\tthrow new FileException(\"NOT_READABLE_ERR\");\n  \t\t\t\t}\n  \t\t\t} else if (data instanceof FakeBlob) {\n  \t\t\t\tif (data.encoding === \"base64\" && atob) {\n  \t\t\t\t\tbb.push(atob(data.data));\n  \t\t\t\t} else if (data.encoding === \"URI\") {\n  \t\t\t\t\tbb.push(decodeURIComponent(data.data));\n  \t\t\t\t} else if (data.encoding === \"raw\") {\n  \t\t\t\t\tbb.push(data.data);\n  \t\t\t\t}\n  \t\t\t} else {\n  \t\t\t\tif (typeof data !== \"string\") {\n  \t\t\t\t\tdata += \"\"; // convert unsupported types to strings\n  \t\t\t\t}\n  \t\t\t\t// decode UTF-16 to binary string\n  \t\t\t\tbb.push(unescape(encodeURIComponent(data)));\n  \t\t\t}\n  \t\t};\n  \t\tFBB_proto.getBlob = function(type) {\n  \t\t\tif (!arguments.length) {\n  \t\t\t\ttype = null;\n  \t\t\t}\n  \t\t\treturn new FakeBlob(this.data.join(\"\"), type, \"raw\");\n  \t\t};\n  \t\tFBB_proto.toString = function() {\n  \t\t\treturn \"[object BlobBuilder]\";\n  \t\t};\n  \t\tFB_proto.slice = function(start, end, type) {\n  \t\t\tvar args = arguments.length;\n  \t\t\tif (args < 3) {\n  \t\t\t\ttype = null;\n  \t\t\t}\n  \t\t\treturn new FakeBlob(\n  \t\t\t\t  this.data.slice(start, args > 1 ? end : this.data.length)\n  \t\t\t\t, type\n  \t\t\t\t, this.encoding\n  \t\t\t);\n  \t\t};\n  \t\tFB_proto.toString = function() {\n  \t\t\treturn \"[object Blob]\";\n  \t\t};\n  \t\tFB_proto.close = function() {\n  \t\t\tthis.size = 0;\n  \t\t\tdelete this.data;\n  \t\t};\n  \t\treturn FakeBlobBuilder;\n  \t}(view));\n\n  \tview.Blob = function(blobParts, options) {\n  \t\tvar type = options ? (options.type || \"\") : \"\";\n  \t\tvar builder = new BlobBuilder();\n  \t\tif (blobParts) {\n  \t\t\tfor (var i = 0, len = blobParts.length; i < len; i++) {\n  \t\t\t\tif (Uint8Array && blobParts[i] instanceof Uint8Array) {\n  \t\t\t\t\tbuilder.append(blobParts[i].buffer);\n  \t\t\t\t}\n  \t\t\t\telse {\n  \t\t\t\t\tbuilder.append(blobParts[i]);\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n  \t\tvar blob = builder.getBlob(type);\n  \t\tif (!blob.slice && blob.webkitSlice) {\n  \t\t\tblob.slice = blob.webkitSlice;\n  \t\t}\n  \t\treturn blob;\n  \t};\n\n  \tvar getPrototypeOf = Object.getPrototypeOf || function(object) {\n  \t\treturn object.__proto__;\n  \t};\n  \tview.Blob.prototype = getPrototypeOf(new view.Blob());\n  }(typeof self !== \"undefined\" && self || typeof window !== \"undefined\" && window || window.content || window));\n\n  /* FileSaver.js\n   * A saveAs() FileSaver implementation.\n   * 1.3.2\n   * 2016-06-16 18:25:19\n   *\n   * By Eli Grey, http://eligrey.com\n   * License: MIT\n   *   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md\n   */\n\n  /*global self */\n  /*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */\n\n  /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */\n\n  var saveAs = saveAs || (function(view) {\n  \t// IE <10 is explicitly unsupported\n  \tif (typeof view === \"undefined\" || typeof navigator !== \"undefined\" && /MSIE [1-9]\\./.test(navigator.userAgent)) {\n  \t\treturn;\n  \t}\n  \tvar\n  \t\t  doc = view.document\n  \t\t  // only get URL when necessary in case Blob.js hasn't overridden it yet\n  \t\t, get_URL = function() {\n  \t\t\treturn view.URL || view.webkitURL || view;\n  \t\t}\n  \t\t, save_link = doc.createElementNS(\"http://www.w3.org/1999/xhtml\", \"a\")\n  \t\t, can_use_save_link = \"download\" in save_link\n  \t\t, click = function(node) {\n  \t\t\tvar event = new MouseEvent(\"click\");\n  \t\t\tnode.dispatchEvent(event);\n  \t\t}\n  \t\t, is_safari = /constructor/i.test(view.HTMLElement) || view.safari\n  \t\t, is_chrome_ios =/CriOS\\/[\\d]+/.test(navigator.userAgent)\n  \t\t, throw_outside = function(ex) {\n  \t\t\t(view.setImmediate || view.setTimeout)(function() {\n  \t\t\t\tthrow ex;\n  \t\t\t}, 0);\n  \t\t}\n  \t\t, force_saveable_type = \"application/octet-stream\"\n  \t\t// the Blob API is fundamentally broken as there is no \"downloadfinished\" event to subscribe to\n  \t\t, arbitrary_revoke_timeout = 1000 * 40 // in ms\n  \t\t, revoke = function(file) {\n  \t\t\tvar revoker = function() {\n  \t\t\t\tif (typeof file === \"string\") { // file is an object URL\n  \t\t\t\t\tget_URL().revokeObjectURL(file);\n  \t\t\t\t} else { // file is a File\n  \t\t\t\t\tfile.remove();\n  \t\t\t\t}\n  \t\t\t};\n  \t\t\tsetTimeout(revoker, arbitrary_revoke_timeout);\n  \t\t}\n  \t\t, dispatch = function(filesaver, event_types, event) {\n  \t\t\tevent_types = [].concat(event_types);\n  \t\t\tvar i = event_types.length;\n  \t\t\twhile (i--) {\n  \t\t\t\tvar listener = filesaver[\"on\" + event_types[i]];\n  \t\t\t\tif (typeof listener === \"function\") {\n  \t\t\t\t\ttry {\n  \t\t\t\t\t\tlistener.call(filesaver, event || filesaver);\n  \t\t\t\t\t} catch (ex) {\n  \t\t\t\t\t\tthrow_outside(ex);\n  \t\t\t\t\t}\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n  \t\t, auto_bom = function(blob) {\n  \t\t\t// prepend BOM for UTF-8 XML and text/* types (including HTML)\n  \t\t\t// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF\n  \t\t\tif (/^\\s*(?:text\\/\\S*|application\\/xml|\\S*\\/\\S*\\+xml)\\s*;.*charset\\s*=\\s*utf-8/i.test(blob.type)) {\n  \t\t\t\treturn new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});\n  \t\t\t}\n  \t\t\treturn blob;\n  \t\t}\n  \t\t, FileSaver = function(blob, name, no_auto_bom) {\n  \t\t\tif (!no_auto_bom) {\n  \t\t\t\tblob = auto_bom(blob);\n  \t\t\t}\n  \t\t\t// First try a.download, then web filesystem, then object URLs\n  \t\t\tvar\n  \t\t\t\t  filesaver = this\n  \t\t\t\t, type = blob.type\n  \t\t\t\t, force = type === force_saveable_type\n  \t\t\t\t, object_url\n  \t\t\t\t, dispatch_all = function() {\n  \t\t\t\t\tdispatch(filesaver, \"writestart progress write writeend\".split(\" \"));\n  \t\t\t\t}\n  \t\t\t\t// on any filesys errors revert to saving with object URLs\n  \t\t\t\t, fs_error = function() {\n  \t\t\t\t\tif ((is_chrome_ios || (force && is_safari)) && view.FileReader) {\n  \t\t\t\t\t\t// Safari doesn't allow downloading of blob urls\n  \t\t\t\t\t\tvar reader = new FileReader();\n  \t\t\t\t\t\treader.onloadend = function() {\n  \t\t\t\t\t\t\tvar url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');\n  \t\t\t\t\t\t\tvar popup = view.open(url, '_blank');\n  \t\t\t\t\t\t\tif(!popup) view.location.href = url;\n  \t\t\t\t\t\t\turl=undefined; // release reference before dispatching\n  \t\t\t\t\t\t\tfilesaver.readyState = filesaver.DONE;\n  \t\t\t\t\t\t\tdispatch_all();\n  \t\t\t\t\t\t};\n  \t\t\t\t\t\treader.readAsDataURL(blob);\n  \t\t\t\t\t\tfilesaver.readyState = filesaver.INIT;\n  \t\t\t\t\t\treturn;\n  \t\t\t\t\t}\n  \t\t\t\t\t// don't create more object URLs than needed\n  \t\t\t\t\tif (!object_url) {\n  \t\t\t\t\t\tobject_url = get_URL().createObjectURL(blob);\n  \t\t\t\t\t}\n  \t\t\t\t\tif (force) {\n  \t\t\t\t\t\tview.location.href = object_url;\n  \t\t\t\t\t} else {\n  \t\t\t\t\t\tvar opened = view.open(object_url, \"_blank\");\n  \t\t\t\t\t\tif (!opened) {\n  \t\t\t\t\t\t\t// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html\n  \t\t\t\t\t\t\tview.location.href = object_url;\n  \t\t\t\t\t\t}\n  \t\t\t\t\t}\n  \t\t\t\t\tfilesaver.readyState = filesaver.DONE;\n  \t\t\t\t\tdispatch_all();\n  \t\t\t\t\trevoke(object_url);\n  \t\t\t\t}\n  \t\t\t;\n  \t\t\tfilesaver.readyState = filesaver.INIT;\n\n  \t\t\tif (can_use_save_link) {\n  \t\t\t\tobject_url = get_URL().createObjectURL(blob);\n  \t\t\t\tsetTimeout(function() {\n  \t\t\t\t\tsave_link.href = object_url;\n  \t\t\t\t\tsave_link.download = name;\n  \t\t\t\t\tclick(save_link);\n  \t\t\t\t\tdispatch_all();\n  \t\t\t\t\trevoke(object_url);\n  \t\t\t\t\tfilesaver.readyState = filesaver.DONE;\n  \t\t\t\t});\n  \t\t\t\treturn;\n  \t\t\t}\n\n  \t\t\tfs_error();\n  \t\t}\n  \t\t, FS_proto = FileSaver.prototype\n  \t\t, saveAs = function(blob, name, no_auto_bom) {\n  \t\t\treturn new FileSaver(blob, name || blob.name || \"download\", no_auto_bom);\n  \t\t}\n  \t;\n  \t// IE 10+ (native saveAs)\n  \tif (typeof navigator !== \"undefined\" && navigator.msSaveOrOpenBlob) {\n  \t\treturn function(blob, name, no_auto_bom) {\n  \t\t\tname = name || blob.name || \"download\";\n\n  \t\t\tif (!no_auto_bom) {\n  \t\t\t\tblob = auto_bom(blob);\n  \t\t\t}\n  \t\t\treturn navigator.msSaveOrOpenBlob(blob, name);\n  \t\t};\n  \t}\n\n  \tFS_proto.abort = function(){};\n  \tFS_proto.readyState = FS_proto.INIT = 0;\n  \tFS_proto.WRITING = 1;\n  \tFS_proto.DONE = 2;\n\n  \tFS_proto.error =\n  \tFS_proto.onwritestart =\n  \tFS_proto.onprogress =\n  \tFS_proto.onwrite =\n  \tFS_proto.onabort =\n  \tFS_proto.onerror =\n  \tFS_proto.onwriteend =\n  \t\tnull;\n\n  \treturn saveAs;\n  }(\n  \t   typeof self !== \"undefined\" && self\n  \t|| typeof window !== \"undefined\" && window\n  \t|| window.content\n  ));\n  // `self` is undefined in Firefox for Android content script context\n  // while `this` is nsIContentFrameMessageManager\n  // with an attribute `content` that corresponds to the window\n\n  if (typeof module !== \"undefined\" && module.exports) {\n    module.exports.saveAs = saveAs;\n  } else if ((typeof define !== \"undefined\" && define !== null) && (define.amd !== null)) {\n    define(\"FileSaver.js\", function() {\n      return saveAs;\n    });\n  }\n\n  /*\n   * Copyright (c) 2012 chick307 <chick307@gmail.com>\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n\n  (function(jsPDF, callback) {\n    jsPDF.API.adler32cs = callback();\n  })(jsPDF, function() {\n    var _hasArrayBuffer = typeof ArrayBuffer === 'function' &&\n      typeof Uint8Array === 'function';\n\n    var _Buffer = null, _isBuffer = (function() {\n      if (!_hasArrayBuffer)\n        return function _isBuffer() { return false };\n\n      try {\n        var buffer = {};\n        if (typeof buffer.Buffer === 'function')\n          _Buffer = buffer.Buffer;\n      } catch (error) {}\n\n      return function _isBuffer(value) {\n        return value instanceof ArrayBuffer ||\n          _Buffer !== null && value instanceof _Buffer;\n      };\n    }());\n\n    var _utf8ToBinary = (function() {\n      if (_Buffer !== null) {\n        return function _utf8ToBinary(utf8String) {\n          return new _Buffer(utf8String, 'utf8').toString('binary');\n        };\n      } else {\n        return function _utf8ToBinary(utf8String) {\n          return unescape(encodeURIComponent(utf8String));\n        };\n      }\n    }());\n\n    var MOD = 65521;\n\n    var _update = function _update(checksum, binaryString) {\n      var a = checksum & 0xFFFF, b = checksum >>> 16;\n      for (var i = 0, length = binaryString.length; i < length; i++) {\n        a = (a + (binaryString.charCodeAt(i) & 0xFF)) % MOD;\n        b = (b + a) % MOD;\n      }\n      return (b << 16 | a) >>> 0;\n    };\n\n    var _updateUint8Array = function _updateUint8Array(checksum, uint8Array) {\n      var a = checksum & 0xFFFF, b = checksum >>> 16;\n      for (var i = 0, length = uint8Array.length; i < length; i++) {\n        a = (a + uint8Array[i]) % MOD;\n        b = (b + a) % MOD;\n      }\n      return (b << 16 | a) >>> 0\n    };\n\n    var exports = {};\n\n    var Adler32 = exports.Adler32 = (function() {\n      var ctor = function Adler32(checksum) {\n        if (!(this instanceof ctor)) {\n          throw new TypeError(\n            'Constructor cannot called be as a function.');\n        }\n        if (!isFinite(checksum = checksum == null ? 1 : +checksum)) {\n          throw new Error(\n            'First arguments needs to be a finite number.');\n        }\n        this.checksum = checksum >>> 0;\n      };\n\n      var proto = ctor.prototype = {};\n      proto.constructor = ctor;\n\n      ctor.from = function(from) {\n        from.prototype = proto;\n        return from;\n      }(function from(binaryString) {\n        if (!(this instanceof ctor)) {\n          throw new TypeError(\n            'Constructor cannot called be as a function.');\n        }\n        if (binaryString == null)\n          throw new Error('First argument needs to be a string.');\n        this.checksum = _update(1, binaryString.toString());\n      });\n\n      ctor.fromUtf8 = function(fromUtf8) {\n        fromUtf8.prototype = proto;\n        return fromUtf8;\n      }(function fromUtf8(utf8String) {\n        if (!(this instanceof ctor)) {\n          throw new TypeError(\n            'Constructor cannot called be as a function.');\n        }\n        if (utf8String == null)\n          throw new Error('First argument needs to be a string.');\n        var binaryString = _utf8ToBinary(utf8String.toString());\n        this.checksum = _update(1, binaryString);\n      });\n\n      if (_hasArrayBuffer) {\n        ctor.fromBuffer = function(fromBuffer) {\n          fromBuffer.prototype = proto;\n          return fromBuffer;\n        }(function fromBuffer(buffer) {\n          if (!(this instanceof ctor)) {\n            throw new TypeError(\n              'Constructor cannot called be as a function.');\n          }\n          if (!_isBuffer(buffer))\n            throw new Error('First argument needs to be ArrayBuffer.');\n          var array = new Uint8Array(buffer);\n          return this.checksum = _updateUint8Array(1, array);\n        });\n      }\n\n      proto.update = function update(binaryString) {\n        if (binaryString == null)\n          throw new Error('First argument needs to be a string.');\n        binaryString = binaryString.toString();\n        return this.checksum = _update(this.checksum, binaryString);\n      };\n\n      proto.updateUtf8 = function updateUtf8(utf8String) {\n        if (utf8String == null)\n          throw new Error('First argument needs to be a string.');\n        var binaryString = _utf8ToBinary(utf8String.toString());\n        return this.checksum = _update(this.checksum, binaryString);\n      };\n\n      if (_hasArrayBuffer) {\n        proto.updateBuffer = function updateBuffer(buffer) {\n          if (!_isBuffer(buffer))\n            throw new Error('First argument needs to be ArrayBuffer.');\n          var array = new Uint8Array(buffer);\n          return this.checksum = _updateUint8Array(this.checksum, array);\n        };\n      }\n\n      proto.clone = function clone() {\n        return new Adler32(this.checksum);\n      };\n\n      return ctor;\n    }());\n\n    exports.from = function from(binaryString) {\n      if (binaryString == null)\n        throw new Error('First argument needs to be a string.');\n      return _update(1, binaryString.toString());\n    };\n\n    exports.fromUtf8 = function fromUtf8(utf8String) {\n      if (utf8String == null)\n        throw new Error('First argument needs to be a string.');\n      var binaryString = _utf8ToBinary(utf8String.toString());\n      return _update(1, binaryString);\n    };\n\n    if (_hasArrayBuffer) {\n      exports.fromBuffer = function fromBuffer(buffer) {\n        if (!_isBuffer(buffer))\n          throw new Error('First argument need to be ArrayBuffer.');\n        var array = new Uint8Array(buffer);\n        return _updateUint8Array(1, array);\n      };\n    }\n\n    return exports;\n  });\n\n  // (c) Dean McNamee <dean@gmail.com>, 2013.\n  //\n  // https://github.com/deanm/omggif\n  //\n  // \n  //\n  // omggif is a JavaScript implementation of a GIF 89a encoder and decoder,\n  // including animation and compression.  It does not rely on any specific\n  // underlying system, so should run in the browser, Node, or Plask.\n\n  function GifWriter(buf, width, height, gopts) {\n    var p = 0;\n\n    var gopts = gopts === undefined ? { } : gopts;\n    var loop_count = gopts.loop === undefined ? null : gopts.loop;\n    var global_palette = gopts.palette === undefined ? null : gopts.palette;\n\n    if (width <= 0 || height <= 0 || width > 65535 || height > 65535)\n      throw \"Width/Height invalid.\"\n\n    function check_palette_and_num_colors(palette) {\n      var num_colors = palette.length;\n      if (num_colors < 2 || num_colors > 256 ||  num_colors & (num_colors-1))\n        throw \"Invalid code/color length, must be power of 2 and 2 .. 256.\";\n      return num_colors;\n    }\n\n    // - Header.\n    buf[p++] = 0x47; buf[p++] = 0x49; buf[p++] = 0x46;  // GIF\n    buf[p++] = 0x38; buf[p++] = 0x39; buf[p++] = 0x61;  // 89a\n\n    // Handling of Global Color Table (palette) and background index.\n    var gp_num_colors_pow2 = 0;\n    var background = 0;\n    if (global_palette !== null) {\n      var gp_num_colors = check_palette_and_num_colors(global_palette);\n      while (gp_num_colors >>= 1) ++gp_num_colors_pow2;\n      gp_num_colors = 1 << gp_num_colors_pow2;\n      --gp_num_colors_pow2;\n      if (gopts.background !== undefined) {\n        background = gopts.background;\n        if (background >= gp_num_colors) throw \"Background index out of range.\";\n        // The GIF spec states that a background index of 0 should be ignored, so\n        // this is probably a mistake and you really want to set it to another\n        // slot in the palette.  But actually in the end most browsers, etc end\n        // up ignoring this almost completely (including for dispose background).\n        if (background === 0)\n          throw \"Background index explicitly passed as 0.\";\n      }\n    }\n\n    // - Logical Screen Descriptor.\n    // NOTE(deanm): w/h apparently ignored by implementations, but set anyway.\n    buf[p++] = width & 0xff; buf[p++] = width >> 8 & 0xff;\n    buf[p++] = height & 0xff; buf[p++] = height >> 8 & 0xff;\n    // NOTE: Indicates 0-bpp original color resolution (unused?).\n    buf[p++] = (global_palette !== null ? 0x80 : 0) |  // Global Color Table Flag.\n               gp_num_colors_pow2;  // NOTE: No sort flag (unused?).\n    buf[p++] = background;  // Background Color Index.\n    buf[p++] = 0;  // Pixel aspect ratio (unused?).\n\n    // - Global Color Table\n    if (global_palette !== null) {\n      for (var i = 0, il = global_palette.length; i < il; ++i) {\n        var rgb = global_palette[i];\n        buf[p++] = rgb >> 16 & 0xff;\n        buf[p++] = rgb >> 8 & 0xff;\n        buf[p++] = rgb & 0xff;\n      }\n    }\n\n    if (loop_count !== null) {  // Netscape block for looping.\n      if (loop_count < 0 || loop_count > 65535)\n        throw \"Loop count invalid.\"\n      // Extension code, label, and length.\n      buf[p++] = 0x21; buf[p++] = 0xff; buf[p++] = 0x0b;\n      // NETSCAPE2.0\n      buf[p++] = 0x4e; buf[p++] = 0x45; buf[p++] = 0x54; buf[p++] = 0x53;\n      buf[p++] = 0x43; buf[p++] = 0x41; buf[p++] = 0x50; buf[p++] = 0x45;\n      buf[p++] = 0x32; buf[p++] = 0x2e; buf[p++] = 0x30;\n      // Sub-block\n      buf[p++] = 0x03; buf[p++] = 0x01;\n      buf[p++] = loop_count & 0xff; buf[p++] = loop_count >> 8 & 0xff;\n      buf[p++] = 0x00;  // Terminator.\n    }\n\n\n    var ended = false;\n\n    this.addFrame = function(x, y, w, h, indexed_pixels, opts) {\n      if (ended === true) { --p; ended = false; }  // Un-end.\n\n      opts = opts === undefined ? { } : opts;\n\n      // TODO(deanm): Bounds check x, y.  Do they need to be within the virtual\n      // canvas width/height, I imagine?\n      if (x < 0 || y < 0 || x > 65535 || y > 65535)\n        throw \"x/y invalid.\"\n\n      if (w <= 0 || h <= 0 || w > 65535 || h > 65535)\n        throw \"Width/Height invalid.\"\n\n      if (indexed_pixels.length < w * h)\n        throw \"Not enough pixels for the frame size.\";\n\n      var using_local_palette = true;\n      var palette = opts.palette;\n      if (palette === undefined || palette === null) {\n        using_local_palette = false;\n        palette = global_palette;\n      }\n\n      if (palette === undefined || palette === null)\n        throw \"Must supply either a local or global palette.\";\n\n      var num_colors = check_palette_and_num_colors(palette);\n\n      // Compute the min_code_size (power of 2), destroying num_colors.\n      var min_code_size = 0;\n      while (num_colors >>= 1) ++min_code_size;\n      num_colors = 1 << min_code_size;  // Now we can easily get it back.\n\n      var delay = opts.delay === undefined ? 0 : opts.delay;\n\n      // From the spec:\n      //     0 -   No disposal specified. The decoder is\n      //           not required to take any action.\n      //     1 -   Do not dispose. The graphic is to be left\n      //           in place.\n      //     2 -   Restore to background color. The area used by the\n      //           graphic must be restored to the background color.\n      //     3 -   Restore to previous. The decoder is required to\n      //           restore the area overwritten by the graphic with\n      //           what was there prior to rendering the graphic.\n      //  4-7 -    To be defined.\n      // NOTE(deanm): Dispose background doesn't really work, apparently most\n      // browsers ignore the background palette index and clear to transparency.\n      var disposal = opts.disposal === undefined ? 0 : opts.disposal;\n      if (disposal < 0 || disposal > 3)  // 4-7 is reserved.\n        throw \"Disposal out of range.\";\n\n      var use_transparency = false;\n      var transparent_index = 0;\n      if (opts.transparent !== undefined && opts.transparent !== null) {\n        use_transparency = true;\n        transparent_index = opts.transparent;\n        if (transparent_index < 0 || transparent_index >= num_colors)\n          throw \"Transparent color index.\";\n      }\n\n      if (disposal !== 0 || use_transparency || delay !== 0) {\n        // - Graphics Control Extension\n        buf[p++] = 0x21; buf[p++] = 0xf9;  // Extension / Label.\n        buf[p++] = 4;  // Byte size.\n\n        buf[p++] = disposal << 2 | (use_transparency === true ? 1 : 0);\n        buf[p++] = delay & 0xff; buf[p++] = delay >> 8 & 0xff;\n        buf[p++] = transparent_index;  // Transparent color index.\n        buf[p++] = 0;  // Block Terminator.\n      }\n\n      // - Image Descriptor\n      buf[p++] = 0x2c;  // Image Seperator.\n      buf[p++] = x & 0xff; buf[p++] = x >> 8 & 0xff;  // Left.\n      buf[p++] = y & 0xff; buf[p++] = y >> 8 & 0xff;  // Top.\n      buf[p++] = w & 0xff; buf[p++] = w >> 8 & 0xff;\n      buf[p++] = h & 0xff; buf[p++] = h >> 8 & 0xff;\n      // NOTE: No sort flag (unused?).\n      // TODO(deanm): Support interlace.\n      buf[p++] = using_local_palette === true ? (0x80 | (min_code_size-1)) : 0;\n\n      // - Local Color Table\n      if (using_local_palette === true) {\n        for (var i = 0, il = palette.length; i < il; ++i) {\n          var rgb = palette[i];\n          buf[p++] = rgb >> 16 & 0xff;\n          buf[p++] = rgb >> 8 & 0xff;\n          buf[p++] = rgb & 0xff;\n        }\n      }\n\n      p = GifWriterOutputLZWCodeStream(\n              buf, p, min_code_size < 2 ? 2 : min_code_size, indexed_pixels);\n    };\n\n    this.end = function() {\n      if (ended === false) {\n        buf[p++] = 0x3b;  // Trailer.\n        ended = true;\n      }\n      return p;\n    };\n  }\n\n  // Main compression routine, palette indexes -> LZW code stream.\n  // |index_stream| must have at least one entry.\n  function GifWriterOutputLZWCodeStream(buf, p, min_code_size, index_stream) {\n    buf[p++] = min_code_size;\n    var cur_subblock = p++;  // Pointing at the length field.\n\n    var clear_code = 1 << min_code_size;\n    var code_mask = clear_code - 1;\n    var eoi_code = clear_code + 1;\n    var next_code = eoi_code + 1;\n\n    var cur_code_size = min_code_size + 1;  // Number of bits per code.\n    var cur_shift = 0;\n    // We have at most 12-bit codes, so we should have to hold a max of 19\n    // bits here (and then we would write out).\n    var cur = 0;\n\n    function emit_bytes_to_buffer(bit_block_size) {\n      while (cur_shift >= bit_block_size) {\n        buf[p++] = cur & 0xff;\n        cur >>= 8; cur_shift -= 8;\n        if (p === cur_subblock + 256) {  // Finished a subblock.\n          buf[cur_subblock] = 255;\n          cur_subblock = p++;\n        }\n      }\n    }\n\n    function emit_code(c) {\n      cur |= c << cur_shift;\n      cur_shift += cur_code_size;\n      emit_bytes_to_buffer(8);\n    }\n\n    // I am not an expert on the topic, and I don't want to write a thesis.\n    // However, it is good to outline here the basic algorithm and the few data\n    // structures and optimizations here that make this implementation fast.\n    // The basic idea behind LZW is to build a table of previously seen runs\n    // addressed by a short id (herein called output code).  All data is\n    // referenced by a code, which represents one or more values from the\n    // original input stream.  All input bytes can be referenced as the same\n    // value as an output code.  So if you didn't want any compression, you\n    // could more or less just output the original bytes as codes (there are\n    // some details to this, but it is the idea).  In order to achieve\n    // compression, values greater then the input range (codes can be up to\n    // 12-bit while input only 8-bit) represent a sequence of previously seen\n    // inputs.  The decompressor is able to build the same mapping while\n    // decoding, so there is always a shared common knowledge between the\n    // encoding and decoder, which is also important for \"timing\" aspects like\n    // how to handle variable bit width code encoding.\n    //\n    // One obvious but very important consequence of the table system is there\n    // is always a unique id (at most 12-bits) to map the runs.  'A' might be\n    // 4, then 'AA' might be 10, 'AAA' 11, 'AAAA' 12, etc.  This relationship\n    // can be used for an effecient lookup strategy for the code mapping.  We\n    // need to know if a run has been seen before, and be able to map that run\n    // to the output code.  Since we start with known unique ids (input bytes),\n    // and then from those build more unique ids (table entries), we can\n    // continue this chain (almost like a linked list) to always have small\n    // integer values that represent the current byte chains in the encoder.\n    // This means instead of tracking the input bytes (AAAABCD) to know our\n    // current state, we can track the table entry for AAAABC (it is guaranteed\n    // to exist by the nature of the algorithm) and the next character D.\n    // Therefor the tuple of (table_entry, byte) is guaranteed to also be\n    // unique.  This allows us to create a simple lookup key for mapping input\n    // sequences to codes (table indices) without having to store or search\n    // any of the code sequences.  So if 'AAAA' has a table entry of 12, the\n    // tuple of ('AAAA', K) for any input byte K will be unique, and can be our\n    // key.  This leads to a integer value at most 20-bits, which can always\n    // fit in an SMI value and be used as a fast sparse array / object key.\n\n    // Output code for the current contents of the index buffer.\n    var ib_code = index_stream[0] & code_mask;  // Load first input index.\n    var code_table = { };  // Key'd on our 20-bit \"tuple\".\n\n    emit_code(clear_code);  // Spec says first code should be a clear code.\n\n    // First index already loaded, process the rest of the stream.\n    for (var i = 1, il = index_stream.length; i < il; ++i) {\n      var k = index_stream[i] & code_mask;\n      var cur_key = ib_code << 8 | k;  // (prev, k) unique tuple.\n      var cur_code = code_table[cur_key];  // buffer + k.\n\n      // Check if we have to create a new code table entry.\n      if (cur_code === undefined) {  // We don't have buffer + k.\n        // Emit index buffer (without k).\n        // This is an inline version of emit_code, because this is the core\n        // writing routine of the compressor (and V8 cannot inline emit_code\n        // because it is a closure here in a different context).  Additionally\n        // we can call emit_byte_to_buffer less often, because we can have\n        // 30-bits (from our 31-bit signed SMI), and we know our codes will only\n        // be 12-bits, so can safely have 18-bits there without overflow.\n        // emit_code(ib_code);\n        cur |= ib_code << cur_shift;\n        cur_shift += cur_code_size;\n        while (cur_shift >= 8) {\n          buf[p++] = cur & 0xff;\n          cur >>= 8; cur_shift -= 8;\n          if (p === cur_subblock + 256) {  // Finished a subblock.\n            buf[cur_subblock] = 255;\n            cur_subblock = p++;\n          }\n        }\n\n        if (next_code === 4096) {  // Table full, need a clear.\n          emit_code(clear_code);\n          next_code = eoi_code + 1;\n          cur_code_size = min_code_size + 1;\n          code_table = { };\n        } else {  // Table not full, insert a new entry.\n          // Increase our variable bit code sizes if necessary.  This is a bit\n          // tricky as it is based on \"timing\" between the encoding and\n          // decoder.  From the encoders perspective this should happen after\n          // we've already emitted the index buffer and are about to create the\n          // first table entry that would overflow our current code bit size.\n          if (next_code >= (1 << cur_code_size)) ++cur_code_size;\n          code_table[cur_key] = next_code++;  // Insert into code table.\n        }\n\n        ib_code = k;  // Index buffer to single input k.\n      } else {\n        ib_code = cur_code;  // Index buffer to sequence in code table.\n      }\n    }\n\n    emit_code(ib_code);  // There will still be something in the index buffer.\n    emit_code(eoi_code);  // End Of Information.\n\n    // Flush / finalize the sub-blocks stream to the buffer.\n    emit_bytes_to_buffer(1);\n\n    // Finish the sub-blocks, writing out any unfinished lengths and\n    // terminating with a sub-block of length 0.  If we have already started\n    // but not yet used a sub-block it can just become the terminator.\n    if (cur_subblock + 1 === p) {  // Started but unused.\n      buf[cur_subblock] = 0;\n    } else {  // Started and used, write length and additional terminator block.\n      buf[cur_subblock] = p - cur_subblock - 1;\n      buf[p++] = 0;\n    }\n    return p;\n  }\n\n  function GifReader(buf) {\n    var p = 0;\n\n    // - Header (GIF87a or GIF89a).\n    if (buf[p++] !== 0x47 ||            buf[p++] !== 0x49 || buf[p++] !== 0x46 ||\n        buf[p++] !== 0x38 || (buf[p++]+1 & 0xfd) !== 0x38 || buf[p++] !== 0x61) {\n      throw \"Invalid GIF 87a/89a header.\";\n    }\n\n    // - Logical Screen Descriptor.\n    var width = buf[p++] | buf[p++] << 8;\n    var height = buf[p++] | buf[p++] << 8;\n    var pf0 = buf[p++];  // <Packed Fields>.\n    var global_palette_flag = pf0 >> 7;\n    var num_global_colors_pow2 = pf0 & 0x7;\n    var num_global_colors = 1 << (num_global_colors_pow2 + 1);\n    var background = buf[p++];\n    buf[p++];  // Pixel aspect ratio (unused?).\n\n    var global_palette_offset = null;\n\n    if (global_palette_flag) {\n      global_palette_offset = p;\n      p += num_global_colors * 3;  // Seek past palette.\n    }\n\n    var no_eof = true;\n\n    var frames = [ ];\n\n    var delay = 0;\n    var transparent_index = null;\n    var disposal = 0;  // 0 - No disposal specified.\n    var loop_count = null;\n\n    this.width = width;\n    this.height = height;\n\n    while (no_eof && p < buf.length) {\n      switch (buf[p++]) {\n        case 0x21:  // Graphics Control Extension Block\n          switch (buf[p++]) {\n            case 0xff:  // Application specific block\n              // Try if it's a Netscape block (with animation loop counter).\n              if (buf[p   ] !== 0x0b ||  // 21 FF already read, check block size.\n                  // NETSCAPE2.0\n                  buf[p+1 ] == 0x4e && buf[p+2 ] == 0x45 && buf[p+3 ] == 0x54 &&\n                  buf[p+4 ] == 0x53 && buf[p+5 ] == 0x43 && buf[p+6 ] == 0x41 &&\n                  buf[p+7 ] == 0x50 && buf[p+8 ] == 0x45 && buf[p+9 ] == 0x32 &&\n                  buf[p+10] == 0x2e && buf[p+11] == 0x30 &&\n                  // Sub-block\n                  buf[p+12] == 0x03 && buf[p+13] == 0x01 && buf[p+16] == 0) {\n                p += 14;\n                loop_count = buf[p++] | buf[p++] << 8;\n                p++;  // Skip terminator.\n              } else {  // We don't know what it is, just try to get past it.\n                p += 12;\n                while (true) {  // Seek through subblocks.\n                  var block_size = buf[p++];\n                  if (block_size === 0) break;\n                  p += block_size;\n                }\n              }\n              break;\n\n            case 0xf9:  // Graphics Control Extension\n              if (buf[p++] !== 0x4 || buf[p+4] !== 0)\n                throw \"Invalid graphics extension block.\";\n              var pf1 = buf[p++];\n              delay = buf[p++] | buf[p++] << 8;\n              transparent_index = buf[p++];\n              if ((pf1 & 1) === 0) transparent_index = null;\n              disposal = pf1 >> 2 & 0x7;\n              p++;  // Skip terminator.\n              break;\n\n            case 0xfe:  // Comment Extension.\n              while (true) {  // Seek through subblocks.\n                var block_size = buf[p++];\n                if (block_size === 0) break;\n                // console.log(buf.slice(p, p+block_size).toString('ascii'));\n                p += block_size;\n              }\n              break;\n\n            default:\n              throw \"Unknown graphic control label: 0x\" + buf[p-1].toString(16);\n          }\n          break;\n\n        case 0x2c:  // Image Descriptor.\n          var x = buf[p++] | buf[p++] << 8;\n          var y = buf[p++] | buf[p++] << 8;\n          var w = buf[p++] | buf[p++] << 8;\n          var h = buf[p++] | buf[p++] << 8;\n          var pf2 = buf[p++];\n          var local_palette_flag = pf2 >> 7;\n          var interlace_flag = pf2 >> 6 & 1;\n          var num_local_colors_pow2 = pf2 & 0x7;\n          var num_local_colors = 1 << (num_local_colors_pow2 + 1);\n          var palette_offset = global_palette_offset;\n          var has_local_palette = false;\n          if (local_palette_flag) {\n            var has_local_palette = true;\n            palette_offset = p;  // Override with local palette.\n            p += num_local_colors * 3;  // Seek past palette.\n          }\n\n          var data_offset = p;\n\n          p++;  // codesize\n          while (true) {\n            var block_size = buf[p++];\n            if (block_size === 0) break;\n            p += block_size;\n          }\n\n          frames.push({x: x, y: y, width: w, height: h,\n                       has_local_palette: has_local_palette,\n                       palette_offset: palette_offset,\n                       data_offset: data_offset,\n                       data_length: p - data_offset,\n                       transparent_index: transparent_index,\n                       interlaced: !!interlace_flag,\n                       delay: delay,\n                       disposal: disposal});\n          break;\n\n        case 0x3b:  // Trailer Marker (end of file).\n          no_eof = false;\n          break;\n\n        default:\n          throw \"Unknown gif block: 0x\" + buf[p-1].toString(16);\n          break;\n      }\n    }\n\n    this.numFrames = function() {\n      return frames.length;\n    };\n\n    this.loopCount = function() {\n      return loop_count;\n    };\n\n    this.frameInfo = function(frame_num) {\n      if (frame_num < 0 || frame_num >= frames.length)\n        throw \"Frame index out of range.\";\n      return frames[frame_num];\n    };\n\n    this.decodeAndBlitFrameBGRA = function(frame_num, pixels) {\n      var frame = this.frameInfo(frame_num);\n      var num_pixels = frame.width * frame.height;\n      var index_stream = new Uint8Array(num_pixels);  // At most 8-bit indices.\n      GifReaderLZWOutputIndexStream(\n          buf, frame.data_offset, index_stream, num_pixels);\n      var palette_offset = frame.palette_offset;\n\n      // NOTE(deanm): It seems to be much faster to compare index to 256 than\n      // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in\n      // the profile, not sure if it's related to using a Uint8Array.\n      var trans = frame.transparent_index;\n      if (trans === null) trans = 256;\n\n      // We are possibly just blitting to a portion of the entire frame.\n      // That is a subrect within the framerect, so the additional pixels\n      // must be skipped over after we finished a scanline.\n      var framewidth  = frame.width;\n      var framestride = width - framewidth;\n      var xleft       = framewidth;  // Number of subrect pixels left in scanline.\n\n      // Output indicies of the top left and bottom right corners of the subrect.\n      var opbeg = ((frame.y * width) + frame.x) * 4;\n      var opend = ((frame.y + frame.height) * width + frame.x) * 4;\n      var op    = opbeg;\n\n      var scanstride = framestride * 4;\n\n      // Use scanstride to skip past the rows when interlacing.  This is skipping\n      // 7 rows for the first two passes, then 3 then 1.\n      if (frame.interlaced === true) {\n        scanstride += (framewidth + framestride) * 4 * 7;  // Pass 1.\n      }\n\n      var interlaceskip = 8;  // Tracking the row interval in the current pass.\n\n      for (var i = 0, il = index_stream.length; i < il; ++i) {\n        var index = index_stream[i];\n\n        if (xleft === 0) {  // Beginning of new scan line\n          op += scanstride;\n          xleft = framewidth;\n          if (op >= opend) { // Catch the wrap to switch passes when interlacing.\n            scanstride =\n                framestride + (framewidth + framestride) * 4 * (interlaceskip-1);\n            // interlaceskip / 2 * 4 is interlaceskip << 1.\n            op = opbeg + (framewidth + framestride) * (interlaceskip << 1);\n            interlaceskip >>= 1;\n          }\n        }\n\n        if (index === trans) {\n          op += 4;\n        } else {\n          var r = buf[palette_offset + index * 3];\n          var g = buf[palette_offset + index * 3 + 1];\n          var b = buf[palette_offset + index * 3 + 2];\n          pixels[op++] = b;\n          pixels[op++] = g;\n          pixels[op++] = r;\n          pixels[op++] = 255;\n        }\n        --xleft;\n      }\n    };\n\n    // I will go to copy and paste hell one day...\n    this.decodeAndBlitFrameRGBA = function(frame_num, pixels) {\n      var frame = this.frameInfo(frame_num);\n      var num_pixels = frame.width * frame.height;\n      var index_stream = new Uint8Array(num_pixels);  // At most 8-bit indices.\n      GifReaderLZWOutputIndexStream(\n          buf, frame.data_offset, index_stream, num_pixels);\n      var palette_offset = frame.palette_offset;\n\n      // NOTE(deanm): It seems to be much faster to compare index to 256 than\n      // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in\n      // the profile, not sure if it's related to using a Uint8Array.\n      var trans = frame.transparent_index;\n      if (trans === null) trans = 256;\n\n      // We are possibly just blitting to a portion of the entire frame.\n      // That is a subrect within the framerect, so the additional pixels\n      // must be skipped over after we finished a scanline.\n      var framewidth  = frame.width;\n      var framestride = width - framewidth;\n      var xleft       = framewidth;  // Number of subrect pixels left in scanline.\n\n      // Output indicies of the top left and bottom right corners of the subrect.\n      var opbeg = ((frame.y * width) + frame.x) * 4;\n      var opend = ((frame.y + frame.height) * width + frame.x) * 4;\n      var op    = opbeg;\n\n      var scanstride = framestride * 4;\n\n      // Use scanstride to skip past the rows when interlacing.  This is skipping\n      // 7 rows for the first two passes, then 3 then 1.\n      if (frame.interlaced === true) {\n        scanstride += (framewidth + framestride) * 4 * 7;  // Pass 1.\n      }\n\n      var interlaceskip = 8;  // Tracking the row interval in the current pass.\n\n      for (var i = 0, il = index_stream.length; i < il; ++i) {\n        var index = index_stream[i];\n\n        if (xleft === 0) {  // Beginning of new scan line\n          op += scanstride;\n          xleft = framewidth;\n          if (op >= opend) { // Catch the wrap to switch passes when interlacing.\n            scanstride =\n                framestride + (framewidth + framestride) * 4 * (interlaceskip-1);\n            // interlaceskip / 2 * 4 is interlaceskip << 1.\n            op = opbeg + (framewidth + framestride) * (interlaceskip << 1);\n            interlaceskip >>= 1;\n          }\n        }\n\n        if (index === trans) {\n          op += 4;\n        } else {\n          var r = buf[palette_offset + index * 3];\n          var g = buf[palette_offset + index * 3 + 1];\n          var b = buf[palette_offset + index * 3 + 2];\n          pixels[op++] = r;\n          pixels[op++] = g;\n          pixels[op++] = b;\n          pixels[op++] = 255;\n        }\n        --xleft;\n      }\n    };\n  }\n\n  function GifReaderLZWOutputIndexStream(code_stream, p, output, output_length) {\n    var min_code_size = code_stream[p++];\n\n    var clear_code = 1 << min_code_size;\n    var eoi_code = clear_code + 1;\n    var next_code = eoi_code + 1;\n\n    var cur_code_size = min_code_size + 1;  // Number of bits per code.\n    // NOTE: This shares the same name as the encoder, but has a different\n    // meaning here.  Here this masks each code coming from the code stream.\n    var code_mask = (1 << cur_code_size) - 1;\n    var cur_shift = 0;\n    var cur = 0;\n\n    var op = 0;  // Output pointer.\n    \n    var subblock_size = code_stream[p++];\n\n    // TODO(deanm): Would using a TypedArray be any faster?  At least it would\n    // solve the fast mode / backing store uncertainty.\n    // var code_table = Array(4096);\n    var code_table = new Int32Array(4096);  // Can be signed, we only use 20 bits.\n\n    var prev_code = null;  // Track code-1.\n\n    while (true) {\n      // Read up to two bytes, making sure we always 12-bits for max sized code.\n      while (cur_shift < 16) {\n        if (subblock_size === 0) break;  // No more data to be read.\n\n        cur |= code_stream[p++] << cur_shift;\n        cur_shift += 8;\n\n        if (subblock_size === 1) {  // Never let it get to 0 to hold logic above.\n          subblock_size = code_stream[p++];  // Next subblock.\n        } else {\n          --subblock_size;\n        }\n      }\n\n      // TODO(deanm): We should never really get here, we should have received\n      // and EOI.\n      if (cur_shift < cur_code_size)\n        break;\n\n      var code = cur & code_mask;\n      cur >>= cur_code_size;\n      cur_shift -= cur_code_size;\n\n      // TODO(deanm): Maybe should check that the first code was a clear code,\n      // at least this is what you're supposed to do.  But actually our encoder\n      // now doesn't emit a clear code first anyway.\n      if (code === clear_code) {\n        // We don't actually have to clear the table.  This could be a good idea\n        // for greater error checking, but we don't really do any anyway.  We\n        // will just track it with next_code and overwrite old entries.\n\n        next_code = eoi_code + 1;\n        cur_code_size = min_code_size + 1;\n        code_mask = (1 << cur_code_size) - 1;\n\n        // Don't update prev_code ?\n        prev_code = null;\n        continue;\n      } else if (code === eoi_code) {\n        break;\n      }\n\n      // We have a similar situation as the decoder, where we want to store\n      // variable length entries (code table entries), but we want to do in a\n      // faster manner than an array of arrays.  The code below stores sort of a\n      // linked list within the code table, and then \"chases\" through it to\n      // construct the dictionary entries.  When a new entry is created, just the\n      // last byte is stored, and the rest (prefix) of the entry is only\n      // referenced by its table entry.  Then the code chases through the\n      // prefixes until it reaches a single byte code.  We have to chase twice,\n      // first to compute the length, and then to actually copy the data to the\n      // output (backwards, since we know the length).  The alternative would be\n      // storing something in an intermediate stack, but that doesn't make any\n      // more sense.  I implemented an approach where it also stored the length\n      // in the code table, although it's a bit tricky because you run out of\n      // bits (12 + 12 + 8), but I didn't measure much improvements (the table\n      // entries are generally not the long).  Even when I created benchmarks for\n      // very long table entries the complexity did not seem worth it.\n      // The code table stores the prefix entry in 12 bits and then the suffix\n      // byte in 8 bits, so each entry is 20 bits.\n\n      var chase_code = code < next_code ? code : prev_code;\n\n      // Chase what we will output, either {CODE} or {CODE-1}.\n      var chase_length = 0;\n      var chase = chase_code;\n      while (chase > clear_code) {\n        chase = code_table[chase] >> 8;\n        ++chase_length;\n      }\n\n      var k = chase;\n      \n      var op_end = op + chase_length + (chase_code !== code ? 1 : 0);\n      if (op_end > output_length) {\n        console.log(\"Warning, gif stream longer than expected.\");\n        return;\n      }\n\n      // Already have the first byte from the chase, might as well write it fast.\n      output[op++] = k;\n\n      op += chase_length;\n      var b = op;  // Track pointer, writing backwards.\n\n      if (chase_code !== code)  // The case of emitting {CODE-1} + k.\n        output[op++] = k;\n\n      chase = chase_code;\n      while (chase_length--) {\n        chase = code_table[chase];\n        output[--b] = chase & 0xff;  // Write backwards.\n        chase >>= 8;  // Pull down to the prefix code.\n      }\n\n      if (prev_code !== null && next_code < 4096) {\n        code_table[next_code++] = prev_code << 8 | k;\n        // TODO(deanm): Figure out this clearing vs code growth logic better.  I\n        // have an feeling that it should just happen somewhere else, for now it\n        // is awkward between when we grow past the max and then hit a clear code.\n        // For now just check if we hit the max 12-bits (then a clear code should\n        // follow, also of course encoded in 12-bits).\n        if (next_code >= code_mask+1 && cur_code_size < 12) {\n          ++cur_code_size;\n          code_mask = code_mask << 1 | 1;\n        }\n      }\n\n      prev_code = code;\n    }\n\n    if (op !== output_length) {\n      console.log(\"Warning, gif stream shorter than expected.\");\n    }\n\n    return output;\n  }\n\n  try { exports.GifWriter = GifWriter; exports.GifReader = GifReader; } catch(e) { }  // CommonJS.\n  \n\n  /*\n    Copyright (c) 2008, Adobe Systems Incorporated\n    All rights reserved.\n\n    Redistribution and use in source and binary forms, with or without \n    modification, are permitted provided that the following conditions are\n    met:\n\n    * Redistributions of source code must retain the above copyright notice, \n      this list of conditions and the following disclaimer.\n    \n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the \n      documentation and/or other materials provided with the distribution.\n    \n    * Neither the name of Adobe Systems Incorporated nor the names of its \n      contributors may be used to endorse or promote products derived from \n      this software without specific prior written permission.\n\n    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\n    IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \n    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n  */\n  /*\n  JPEG encoder ported to JavaScript and optimized by Andreas Ritter, www.bytestrom.eu, 11/2009\n\n  Basic GUI blocking jpeg encoder\n  */\n\n  function JPEGEncoder(quality) {\n  \tvar ffloor = Math.floor;\n  \tvar YTable = new Array(64);\n  \tvar UVTable = new Array(64);\n  \tvar fdtbl_Y = new Array(64);\n  \tvar fdtbl_UV = new Array(64);\n  \tvar YDC_HT;\n  \tvar UVDC_HT;\n  \tvar YAC_HT;\n  \tvar UVAC_HT;\n  \t\n  \tvar bitcode = new Array(65535);\n  \tvar category = new Array(65535);\n  \tvar outputfDCTQuant = new Array(64);\n  \tvar DU = new Array(64);\n  \tvar byteout = [];\n  \tvar bytenew = 0;\n  \tvar bytepos = 7;\n  \t\n  \tvar YDU = new Array(64);\n  \tvar UDU = new Array(64);\n  \tvar VDU = new Array(64);\n  \tvar clt = new Array(256);\n  \tvar RGB_YUV_TABLE = new Array(2048);\n  \tvar currentQuality;\n  \t\n  \tvar ZigZag = [\n  \t\t\t 0, 1, 5, 6,14,15,27,28,\n  \t\t\t 2, 4, 7,13,16,26,29,42,\n  \t\t\t 3, 8,12,17,25,30,41,43,\n  \t\t\t 9,11,18,24,31,40,44,53,\n  \t\t\t10,19,23,32,39,45,52,54,\n  \t\t\t20,22,33,38,46,51,55,60,\n  \t\t\t21,34,37,47,50,56,59,61,\n  \t\t\t35,36,48,49,57,58,62,63\n  \t\t];\n  \t\n  \tvar std_dc_luminance_nrcodes = [0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0];\n  \tvar std_dc_luminance_values = [0,1,2,3,4,5,6,7,8,9,10,11];\n  \tvar std_ac_luminance_nrcodes = [0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d];\n  \tvar std_ac_luminance_values = [\n  \t\t\t0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,\n  \t\t\t0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,\n  \t\t\t0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,\n  \t\t\t0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,\n  \t\t\t0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,\n  \t\t\t0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,\n  \t\t\t0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,\n  \t\t\t0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,\n  \t\t\t0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,\n  \t\t\t0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,\n  \t\t\t0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,\n  \t\t\t0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,\n  \t\t\t0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,\n  \t\t\t0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,\n  \t\t\t0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,\n  \t\t\t0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,\n  \t\t\t0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,\n  \t\t\t0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,\n  \t\t\t0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,\n  \t\t\t0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,\n  \t\t\t0xf9,0xfa\n  \t\t];\n  \t\n  \tvar std_dc_chrominance_nrcodes = [0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0];\n  \tvar std_dc_chrominance_values = [0,1,2,3,4,5,6,7,8,9,10,11];\n  \tvar std_ac_chrominance_nrcodes = [0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77];\n  \tvar std_ac_chrominance_values = [\n  \t\t\t0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,\n  \t\t\t0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,\n  \t\t\t0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,\n  \t\t\t0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,\n  \t\t\t0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,\n  \t\t\t0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,\n  \t\t\t0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,\n  \t\t\t0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,\n  \t\t\t0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,\n  \t\t\t0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,\n  \t\t\t0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,\n  \t\t\t0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,\n  \t\t\t0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,\n  \t\t\t0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,\n  \t\t\t0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,\n  \t\t\t0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,\n  \t\t\t0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,\n  \t\t\t0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,\n  \t\t\t0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,\n  \t\t\t0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,\n  \t\t\t0xf9,0xfa\n  \t\t];\n  \t\n  \tfunction initQuantTables(sf){\n  \t\t\tvar YQT = [\n  \t\t\t\t16, 11, 10, 16, 24, 40, 51, 61,\n  \t\t\t\t12, 12, 14, 19, 26, 58, 60, 55,\n  \t\t\t\t14, 13, 16, 24, 40, 57, 69, 56,\n  \t\t\t\t14, 17, 22, 29, 51, 87, 80, 62,\n  \t\t\t\t18, 22, 37, 56, 68,109,103, 77,\n  \t\t\t\t24, 35, 55, 64, 81,104,113, 92,\n  \t\t\t\t49, 64, 78, 87,103,121,120,101,\n  \t\t\t\t72, 92, 95, 98,112,100,103, 99\n  \t\t\t];\n  \t\t\t\n  \t\t\tfor (var i = 0; i < 64; i++) {\n  \t\t\t\tvar t = ffloor((YQT[i]*sf+50)/100);\n  \t\t\t\tif (t < 1) {\n  \t\t\t\t\tt = 1;\n  \t\t\t\t} else if (t > 255) {\n  \t\t\t\t\tt = 255;\n  \t\t\t\t}\n  \t\t\t\tYTable[ZigZag[i]] = t;\n  \t\t\t}\n  \t\t\tvar UVQT = [\n  \t\t\t\t17, 18, 24, 47, 99, 99, 99, 99,\n  \t\t\t\t18, 21, 26, 66, 99, 99, 99, 99,\n  \t\t\t\t24, 26, 56, 99, 99, 99, 99, 99,\n  \t\t\t\t47, 66, 99, 99, 99, 99, 99, 99,\n  \t\t\t\t99, 99, 99, 99, 99, 99, 99, 99,\n  \t\t\t\t99, 99, 99, 99, 99, 99, 99, 99,\n  \t\t\t\t99, 99, 99, 99, 99, 99, 99, 99,\n  \t\t\t\t99, 99, 99, 99, 99, 99, 99, 99\n  \t\t\t];\n  \t\t\tfor (var j = 0; j < 64; j++) {\n  \t\t\t\tvar u = ffloor((UVQT[j]*sf+50)/100);\n  \t\t\t\tif (u < 1) {\n  \t\t\t\t\tu = 1;\n  \t\t\t\t} else if (u > 255) {\n  \t\t\t\t\tu = 255;\n  \t\t\t\t}\n  \t\t\t\tUVTable[ZigZag[j]] = u;\n  \t\t\t}\n  \t\t\tvar aasf = [\n  \t\t\t\t1.0, 1.387039845, 1.306562965, 1.175875602,\n  \t\t\t\t1.0, 0.785694958, 0.541196100, 0.275899379\n  \t\t\t];\n  \t\t\tvar k = 0;\n  \t\t\tfor (var row = 0; row < 8; row++)\n  \t\t\t{\n  \t\t\t\tfor (var col = 0; col < 8; col++)\n  \t\t\t\t{\n  \t\t\t\t\tfdtbl_Y[k]  = (1.0 / (YTable [ZigZag[k]] * aasf[row] * aasf[col] * 8.0));\n  \t\t\t\t\tfdtbl_UV[k] = (1.0 / (UVTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0));\n  \t\t\t\t\tk++;\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n  \t\t\n  \t\tfunction computeHuffmanTbl(nrcodes, std_table){\n  \t\t\tvar codevalue = 0;\n  \t\t\tvar pos_in_table = 0;\n  \t\t\tvar HT = new Array();\n  \t\t\tfor (var k = 1; k <= 16; k++) {\n  \t\t\t\tfor (var j = 1; j <= nrcodes[k]; j++) {\n  \t\t\t\t\tHT[std_table[pos_in_table]] = [];\n  \t\t\t\t\tHT[std_table[pos_in_table]][0] = codevalue;\n  \t\t\t\t\tHT[std_table[pos_in_table]][1] = k;\n  \t\t\t\t\tpos_in_table++;\n  \t\t\t\t\tcodevalue++;\n  \t\t\t\t}\n  \t\t\t\tcodevalue*=2;\n  \t\t\t}\n  \t\t\treturn HT;\n  \t\t}\n  \t\t\n  \t\tfunction initHuffmanTbl()\n  \t\t{\n  \t\t\tYDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values);\n  \t\t\tUVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values);\n  \t\t\tYAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values);\n  \t\t\tUVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values);\n  \t\t}\n  \t\n  \t\tfunction initCategoryNumber()\n  \t\t{\n  \t\t\tvar nrlower = 1;\n  \t\t\tvar nrupper = 2;\n  \t\t\tfor (var cat = 1; cat <= 15; cat++) {\n  \t\t\t\t//Positive numbers\n  \t\t\t\tfor (var nr = nrlower; nr<nrupper; nr++) {\n  \t\t\t\t\tcategory[32767+nr] = cat;\n  \t\t\t\t\tbitcode[32767+nr] = [];\n  \t\t\t\t\tbitcode[32767+nr][1] = cat;\n  \t\t\t\t\tbitcode[32767+nr][0] = nr;\n  \t\t\t\t}\n  \t\t\t\t//Negative numbers\n  \t\t\t\tfor (var nrneg =-(nrupper-1); nrneg<=-nrlower; nrneg++) {\n  \t\t\t\t\tcategory[32767+nrneg] = cat;\n  \t\t\t\t\tbitcode[32767+nrneg] = [];\n  \t\t\t\t\tbitcode[32767+nrneg][1] = cat;\n  \t\t\t\t\tbitcode[32767+nrneg][0] = nrupper-1+nrneg;\n  \t\t\t\t}\n  \t\t\t\tnrlower <<= 1;\n  \t\t\t\tnrupper <<= 1;\n  \t\t\t}\n  \t\t}\n  \t\t\n  \t\tfunction initRGBYUVTable() {\n  \t\t\tfor(var i = 0; i < 256;i++) {\n  \t\t\t\tRGB_YUV_TABLE[i]      \t\t=  19595 * i;\n  \t\t\t\tRGB_YUV_TABLE[(i+ 256)>>0] \t=  38470 * i;\n  \t\t\t\tRGB_YUV_TABLE[(i+ 512)>>0] \t=   7471 * i + 0x8000;\n  \t\t\t\tRGB_YUV_TABLE[(i+ 768)>>0] \t= -11059 * i;\n  \t\t\t\tRGB_YUV_TABLE[(i+1024)>>0] \t= -21709 * i;\n  \t\t\t\tRGB_YUV_TABLE[(i+1280)>>0] \t=  32768 * i + 0x807FFF;\n  \t\t\t\tRGB_YUV_TABLE[(i+1536)>>0] \t= -27439 * i;\n  \t\t\t\tRGB_YUV_TABLE[(i+1792)>>0] \t= - 5329 * i;\n  \t\t\t}\n  \t\t}\n  \t\t\n  \t\t// IO functions\n  \t\tfunction writeBits(bs)\n  \t\t{\n  \t\t\tvar value = bs[0];\n  \t\t\tvar posval = bs[1]-1;\n  \t\t\twhile ( posval >= 0 ) {\n  \t\t\t\tif (value & (1 << posval) ) {\n  \t\t\t\t\tbytenew |= (1 << bytepos);\n  \t\t\t\t}\n  \t\t\t\tposval--;\n  \t\t\t\tbytepos--;\n  \t\t\t\tif (bytepos < 0) {\n  \t\t\t\t\tif (bytenew == 0xFF) {\n  \t\t\t\t\t\twriteByte(0xFF);\n  \t\t\t\t\t\twriteByte(0);\n  \t\t\t\t\t}\n  \t\t\t\t\telse {\n  \t\t\t\t\t\twriteByte(bytenew);\n  \t\t\t\t\t}\n  \t\t\t\t\tbytepos=7;\n  \t\t\t\t\tbytenew=0;\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n  \t\n  \t\tfunction writeByte(value)\n  \t\t{\n  \t\t\t//byteout.push(clt[value]); // write char directly instead of converting later\n        byteout.push(value);\n  \t\t}\n  \t\n  \t\tfunction writeWord(value)\n  \t\t{\n  \t\t\twriteByte((value>>8)&0xFF);\n  \t\t\twriteByte((value   )&0xFF);\n  \t\t}\n  \t\t\n  \t\t// DCT & quantization core\n  \t\tfunction fDCTQuant(data, fdtbl)\n  \t\t{\n  \t\t\tvar d0, d1, d2, d3, d4, d5, d6, d7;\n  \t\t\t/* Pass 1: process rows. */\n  \t\t\tvar dataOff=0;\n  \t\t\tvar i;\n  \t\t\tvar I8 = 8;\n  \t\t\tvar I64 = 64;\n  \t\t\tfor (i=0; i<I8; ++i)\n  \t\t\t{\n  \t\t\t\td0 = data[dataOff];\n  \t\t\t\td1 = data[dataOff+1];\n  \t\t\t\td2 = data[dataOff+2];\n  \t\t\t\td3 = data[dataOff+3];\n  \t\t\t\td4 = data[dataOff+4];\n  \t\t\t\td5 = data[dataOff+5];\n  \t\t\t\td6 = data[dataOff+6];\n  \t\t\t\td7 = data[dataOff+7];\n  \t\t\t\t\n  \t\t\t\tvar tmp0 = d0 + d7;\n  \t\t\t\tvar tmp7 = d0 - d7;\n  \t\t\t\tvar tmp1 = d1 + d6;\n  \t\t\t\tvar tmp6 = d1 - d6;\n  \t\t\t\tvar tmp2 = d2 + d5;\n  \t\t\t\tvar tmp5 = d2 - d5;\n  \t\t\t\tvar tmp3 = d3 + d4;\n  \t\t\t\tvar tmp4 = d3 - d4;\n  \t\n  \t\t\t\t/* Even part */\n  \t\t\t\tvar tmp10 = tmp0 + tmp3;\t/* phase 2 */\n  \t\t\t\tvar tmp13 = tmp0 - tmp3;\n  \t\t\t\tvar tmp11 = tmp1 + tmp2;\n  \t\t\t\tvar tmp12 = tmp1 - tmp2;\n  \t\n  \t\t\t\tdata[dataOff] = tmp10 + tmp11; /* phase 3 */\n  \t\t\t\tdata[dataOff+4] = tmp10 - tmp11;\n  \t\n  \t\t\t\tvar z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */\n  \t\t\t\tdata[dataOff+2] = tmp13 + z1; /* phase 5 */\n  \t\t\t\tdata[dataOff+6] = tmp13 - z1;\n  \t\n  \t\t\t\t/* Odd part */\n  \t\t\t\ttmp10 = tmp4 + tmp5; /* phase 2 */\n  \t\t\t\ttmp11 = tmp5 + tmp6;\n  \t\t\t\ttmp12 = tmp6 + tmp7;\n  \t\n  \t\t\t\t/* The rotator is modified from fig 4-8 to avoid extra negations. */\n  \t\t\t\tvar z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */\n  \t\t\t\tvar z2 = 0.541196100 * tmp10 + z5; /* c2-c6 */\n  \t\t\t\tvar z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */\n  \t\t\t\tvar z3 = tmp11 * 0.707106781; /* c4 */\n  \t\n  \t\t\t\tvar z11 = tmp7 + z3;\t/* phase 5 */\n  \t\t\t\tvar z13 = tmp7 - z3;\n  \t\n  \t\t\t\tdata[dataOff+5] = z13 + z2;\t/* phase 6 */\n  \t\t\t\tdata[dataOff+3] = z13 - z2;\n  \t\t\t\tdata[dataOff+1] = z11 + z4;\n  \t\t\t\tdata[dataOff+7] = z11 - z4;\n  \t\n  \t\t\t\tdataOff += 8; /* advance pointer to next row */\n  \t\t\t}\n  \t\n  \t\t\t/* Pass 2: process columns. */\n  \t\t\tdataOff = 0;\n  \t\t\tfor (i=0; i<I8; ++i)\n  \t\t\t{\n  \t\t\t\td0 = data[dataOff];\n  \t\t\t\td1 = data[dataOff + 8];\n  \t\t\t\td2 = data[dataOff + 16];\n  \t\t\t\td3 = data[dataOff + 24];\n  \t\t\t\td4 = data[dataOff + 32];\n  \t\t\t\td5 = data[dataOff + 40];\n  \t\t\t\td6 = data[dataOff + 48];\n  \t\t\t\td7 = data[dataOff + 56];\n  \t\t\t\t\n  \t\t\t\tvar tmp0p2 = d0 + d7;\n  \t\t\t\tvar tmp7p2 = d0 - d7;\n  \t\t\t\tvar tmp1p2 = d1 + d6;\n  \t\t\t\tvar tmp6p2 = d1 - d6;\n  \t\t\t\tvar tmp2p2 = d2 + d5;\n  \t\t\t\tvar tmp5p2 = d2 - d5;\n  \t\t\t\tvar tmp3p2 = d3 + d4;\n  \t\t\t\tvar tmp4p2 = d3 - d4;\n  \t\n  \t\t\t\t/* Even part */\n  \t\t\t\tvar tmp10p2 = tmp0p2 + tmp3p2;\t/* phase 2 */\n  \t\t\t\tvar tmp13p2 = tmp0p2 - tmp3p2;\n  \t\t\t\tvar tmp11p2 = tmp1p2 + tmp2p2;\n  \t\t\t\tvar tmp12p2 = tmp1p2 - tmp2p2;\n  \t\n  \t\t\t\tdata[dataOff] = tmp10p2 + tmp11p2; /* phase 3 */\n  \t\t\t\tdata[dataOff+32] = tmp10p2 - tmp11p2;\n  \t\n  \t\t\t\tvar z1p2 = (tmp12p2 + tmp13p2) * 0.707106781; /* c4 */\n  \t\t\t\tdata[dataOff+16] = tmp13p2 + z1p2; /* phase 5 */\n  \t\t\t\tdata[dataOff+48] = tmp13p2 - z1p2;\n  \t\n  \t\t\t\t/* Odd part */\n  \t\t\t\ttmp10p2 = tmp4p2 + tmp5p2; /* phase 2 */\n  \t\t\t\ttmp11p2 = tmp5p2 + tmp6p2;\n  \t\t\t\ttmp12p2 = tmp6p2 + tmp7p2;\n  \t\n  \t\t\t\t/* The rotator is modified from fig 4-8 to avoid extra negations. */\n  \t\t\t\tvar z5p2 = (tmp10p2 - tmp12p2) * 0.382683433; /* c6 */\n  \t\t\t\tvar z2p2 = 0.541196100 * tmp10p2 + z5p2; /* c2-c6 */\n  \t\t\t\tvar z4p2 = 1.306562965 * tmp12p2 + z5p2; /* c2+c6 */\n  \t\t\t\tvar z3p2 = tmp11p2 * 0.707106781; /* c4 */\n  \t\n  \t\t\t\tvar z11p2 = tmp7p2 + z3p2;\t/* phase 5 */\n  \t\t\t\tvar z13p2 = tmp7p2 - z3p2;\n  \t\n  \t\t\t\tdata[dataOff+40] = z13p2 + z2p2; /* phase 6 */\n  \t\t\t\tdata[dataOff+24] = z13p2 - z2p2;\n  \t\t\t\tdata[dataOff+ 8] = z11p2 + z4p2;\n  \t\t\t\tdata[dataOff+56] = z11p2 - z4p2;\n  \t\n  \t\t\t\tdataOff++; /* advance pointer to next column */\n  \t\t\t}\n  \t\n  \t\t\t// Quantize/descale the coefficients\n  \t\t\tvar fDCTQuant;\n  \t\t\tfor (i=0; i<I64; ++i)\n  \t\t\t{\n  \t\t\t\t// Apply the quantization and scaling factor & Round to nearest integer\n  \t\t\t\tfDCTQuant = data[i]*fdtbl[i];\n  \t\t\t\toutputfDCTQuant[i] = (fDCTQuant > 0.0) ? ((fDCTQuant + 0.5)|0) : ((fDCTQuant - 0.5)|0);\n  \t\t\t\t//outputfDCTQuant[i] = fround(fDCTQuant);\n\n  \t\t\t}\n  \t\t\treturn outputfDCTQuant;\n  \t\t}\n  \t\t\n  \t\tfunction writeAPP0()\n  \t\t{\n  \t\t\twriteWord(0xFFE0); // marker\n  \t\t\twriteWord(16); // length\n  \t\t\twriteByte(0x4A); // J\n  \t\t\twriteByte(0x46); // F\n  \t\t\twriteByte(0x49); // I\n  \t\t\twriteByte(0x46); // F\n  \t\t\twriteByte(0); // = \"JFIF\",'\\0'\n  \t\t\twriteByte(1); // versionhi\n  \t\t\twriteByte(1); // versionlo\n  \t\t\twriteByte(0); // xyunits\n  \t\t\twriteWord(1); // xdensity\n  \t\t\twriteWord(1); // ydensity\n  \t\t\twriteByte(0); // thumbnwidth\n  \t\t\twriteByte(0); // thumbnheight\n  \t\t}\n  \t\n  \t\tfunction writeSOF0(width, height)\n  \t\t{\n  \t\t\twriteWord(0xFFC0); // marker\n  \t\t\twriteWord(17);   // length, truecolor YUV JPG\n  \t\t\twriteByte(8);    // precision\n  \t\t\twriteWord(height);\n  \t\t\twriteWord(width);\n  \t\t\twriteByte(3);    // nrofcomponents\n  \t\t\twriteByte(1);    // IdY\n  \t\t\twriteByte(0x11); // HVY\n  \t\t\twriteByte(0);    // QTY\n  \t\t\twriteByte(2);    // IdU\n  \t\t\twriteByte(0x11); // HVU\n  \t\t\twriteByte(1);    // QTU\n  \t\t\twriteByte(3);    // IdV\n  \t\t\twriteByte(0x11); // HVV\n  \t\t\twriteByte(1);    // QTV\n  \t\t}\n  \t\n  \t\tfunction writeDQT()\n  \t\t{\n  \t\t\twriteWord(0xFFDB); // marker\n  \t\t\twriteWord(132);\t   // length\n  \t\t\twriteByte(0);\n  \t\t\tfor (var i=0; i<64; i++) {\n  \t\t\t\twriteByte(YTable[i]);\n  \t\t\t}\n  \t\t\twriteByte(1);\n  \t\t\tfor (var j=0; j<64; j++) {\n  \t\t\t\twriteByte(UVTable[j]);\n  \t\t\t}\n  \t\t}\n  \t\n  \t\tfunction writeDHT()\n  \t\t{\n  \t\t\twriteWord(0xFFC4); // marker\n  \t\t\twriteWord(0x01A2); // length\n  \t\n  \t\t\twriteByte(0); // HTYDCinfo\n  \t\t\tfor (var i=0; i<16; i++) {\n  \t\t\t\twriteByte(std_dc_luminance_nrcodes[i+1]);\n  \t\t\t}\n  \t\t\tfor (var j=0; j<=11; j++) {\n  \t\t\t\twriteByte(std_dc_luminance_values[j]);\n  \t\t\t}\n  \t\n  \t\t\twriteByte(0x10); // HTYACinfo\n  \t\t\tfor (var k=0; k<16; k++) {\n  \t\t\t\twriteByte(std_ac_luminance_nrcodes[k+1]);\n  \t\t\t}\n  \t\t\tfor (var l=0; l<=161; l++) {\n  \t\t\t\twriteByte(std_ac_luminance_values[l]);\n  \t\t\t}\n  \t\n  \t\t\twriteByte(1); // HTUDCinfo\n  \t\t\tfor (var m=0; m<16; m++) {\n  \t\t\t\twriteByte(std_dc_chrominance_nrcodes[m+1]);\n  \t\t\t}\n  \t\t\tfor (var n=0; n<=11; n++) {\n  \t\t\t\twriteByte(std_dc_chrominance_values[n]);\n  \t\t\t}\n  \t\n  \t\t\twriteByte(0x11); // HTUACinfo\n  \t\t\tfor (var o=0; o<16; o++) {\n  \t\t\t\twriteByte(std_ac_chrominance_nrcodes[o+1]);\n  \t\t\t}\n  \t\t\tfor (var p=0; p<=161; p++) {\n  \t\t\t\twriteByte(std_ac_chrominance_values[p]);\n  \t\t\t}\n  \t\t}\n  \t\n  \t\tfunction writeSOS()\n  \t\t{\n  \t\t\twriteWord(0xFFDA); // marker\n  \t\t\twriteWord(12); // length\n  \t\t\twriteByte(3); // nrofcomponents\n  \t\t\twriteByte(1); // IdY\n  \t\t\twriteByte(0); // HTY\n  \t\t\twriteByte(2); // IdU\n  \t\t\twriteByte(0x11); // HTU\n  \t\t\twriteByte(3); // IdV\n  \t\t\twriteByte(0x11); // HTV\n  \t\t\twriteByte(0); // Ss\n  \t\t\twriteByte(0x3f); // Se\n  \t\t\twriteByte(0); // Bf\n  \t\t}\n  \t\t\n  \t\tfunction processDU(CDU, fdtbl, DC, HTDC, HTAC){\n  \t\t\tvar EOB = HTAC[0x00];\n  \t\t\tvar M16zeroes = HTAC[0xF0];\n  \t\t\tvar pos;\n  \t\t\tvar I16 = 16;\n  \t\t\tvar I63 = 63;\n  \t\t\tvar I64 = 64;\n  \t\t\tvar DU_DCT = fDCTQuant(CDU, fdtbl);\n  \t\t\t//ZigZag reorder\n  \t\t\tfor (var j=0;j<I64;++j) {\n  \t\t\t\tDU[ZigZag[j]]=DU_DCT[j];\n  \t\t\t}\n  \t\t\tvar Diff = DU[0] - DC; DC = DU[0];\n  \t\t\t//Encode DC\n  \t\t\tif (Diff==0) {\n  \t\t\t\twriteBits(HTDC[0]); // Diff might be 0\n  \t\t\t} else {\n  \t\t\t\tpos = 32767+Diff;\n  \t\t\t\twriteBits(HTDC[category[pos]]);\n  \t\t\t\twriteBits(bitcode[pos]);\n  \t\t\t}\n  \t\t\t//Encode ACs\n  \t\t\tvar end0pos = 63; // was const... which is crazy\n  \t\t\tfor (; (end0pos>0)&&(DU[end0pos]==0); end0pos--) {}\t\t\t//end0pos = first element in reverse order !=0\n  \t\t\tif ( end0pos == 0) {\n  \t\t\t\twriteBits(EOB);\n  \t\t\t\treturn DC;\n  \t\t\t}\n  \t\t\tvar i = 1;\n  \t\t\tvar lng;\n  \t\t\twhile ( i <= end0pos ) {\n  \t\t\t\tvar startpos = i;\n  \t\t\t\tfor (; (DU[i]==0) && (i<=end0pos); ++i) {}\n  \t\t\t\tvar nrzeroes = i-startpos;\n  \t\t\t\tif ( nrzeroes >= I16 ) {\n  \t\t\t\t\tlng = nrzeroes>>4;\n  \t\t\t\t\tfor (var nrmarker=1; nrmarker <= lng; ++nrmarker)\n  \t\t\t\t\t\twriteBits(M16zeroes);\n  \t\t\t\t\tnrzeroes = nrzeroes&0xF;\n  \t\t\t\t}\n  \t\t\t\tpos = 32767+DU[i];\n  \t\t\t\twriteBits(HTAC[(nrzeroes<<4)+category[pos]]);\n  \t\t\t\twriteBits(bitcode[pos]);\n  \t\t\t\ti++;\n  \t\t\t}\n  \t\t\tif ( end0pos != I63 ) {\n  \t\t\t\twriteBits(EOB);\n  \t\t\t}\n  \t\t\treturn DC;\n  \t\t}\n\n  \t\tfunction initCharLookupTable(){\n  \t\t\tvar sfcc = String.fromCharCode;\n  \t\t\tfor(var i=0; i < 256; i++){ ///// ACHTUNG // 255\n  \t\t\t\tclt[i] = sfcc(i);\n  \t\t\t}\n  \t\t}\n  \t\t\n  \t\tthis.encode = function(image,quality) // image data object\n  \t\t{\n  \t\t\tvar time_start = new Date().getTime();\n  \t\t\t\n  \t\t\tif(quality) setQuality(quality);\n  \t\t\t\n  \t\t\t// Initialize bit writer\n  \t\t\tbyteout = new Array();\n  \t\t\tbytenew=0;\n  \t\t\tbytepos=7;\n  \t\n  \t\t\t// Add JPEG headers\n  \t\t\twriteWord(0xFFD8); // SOI\n  \t\t\twriteAPP0();\n  \t\t\twriteDQT();\n  \t\t\twriteSOF0(image.width,image.height);\n  \t\t\twriteDHT();\n  \t\t\twriteSOS();\n\n  \t\n  \t\t\t// Encode 8x8 macroblocks\n  \t\t\tvar DCY=0;\n  \t\t\tvar DCU=0;\n  \t\t\tvar DCV=0;\n  \t\t\t\n  \t\t\tbytenew=0;\n  \t\t\tbytepos=7;\n  \t\t\t\n  \t\t\t\n  \t\t\tthis.encode.displayName = \"_encode_\";\n\n  \t\t\tvar imageData = image.data;\n  \t\t\tvar width = image.width;\n  \t\t\tvar height = image.height;\n\n  \t\t\tvar quadWidth = width*4;\n  \t\t\t\n  \t\t\tvar x, y = 0;\n  \t\t\tvar r, g, b;\n  \t\t\tvar start,p, col,row,pos;\n  \t\t\twhile(y < height){\n  \t\t\t\tx = 0;\n  \t\t\t\twhile(x < quadWidth){\n  \t\t\t\tstart = quadWidth * y + x;\n  \t\t\t\tp = start;\n  \t\t\t\tcol = -1;\n  \t\t\t\trow = 0;\n  \t\t\t\t\n  \t\t\t\tfor(pos=0; pos < 64; pos++){\n  \t\t\t\t\trow = pos >> 3;// /8\n  \t\t\t\t\tcol = ( pos & 7 ) * 4; // %8\n  \t\t\t\t\tp = start + ( row * quadWidth ) + col;\t\t\n  \t\t\t\t\t\n  \t\t\t\t\tif(y+row >= height){ // padding bottom\n  \t\t\t\t\t\tp-= (quadWidth*(y+1+row-height));\n  \t\t\t\t\t}\n\n  \t\t\t\t\tif(x+col >= quadWidth){ // padding right\t\n  \t\t\t\t\t\tp-= ((x+col) - quadWidth +4);\n  \t\t\t\t\t}\n  \t\t\t\t\t\n  \t\t\t\t\tr = imageData[ p++ ];\n  \t\t\t\t\tg = imageData[ p++ ];\n  \t\t\t\t\tb = imageData[ p++ ];\n  \t\t\t\t\t\n  \t\t\t\t\t\n  \t\t\t\t\t/* // calculate YUV values dynamically\n  \t\t\t\t\tYDU[pos]=((( 0.29900)*r+( 0.58700)*g+( 0.11400)*b))-128; //-0x80\n  \t\t\t\t\tUDU[pos]=(((-0.16874)*r+(-0.33126)*g+( 0.50000)*b));\n  \t\t\t\t\tVDU[pos]=((( 0.50000)*r+(-0.41869)*g+(-0.08131)*b));\n  \t\t\t\t\t*/\n  \t\t\t\t\t\n  \t\t\t\t\t// use lookup table (slightly faster)\n  \t\t\t\t\tYDU[pos] = ((RGB_YUV_TABLE[r]             + RGB_YUV_TABLE[(g +  256)>>0] + RGB_YUV_TABLE[(b +  512)>>0]) >> 16)-128;\n  \t\t\t\t\tUDU[pos] = ((RGB_YUV_TABLE[(r +  768)>>0] + RGB_YUV_TABLE[(g + 1024)>>0] + RGB_YUV_TABLE[(b + 1280)>>0]) >> 16)-128;\n  \t\t\t\t\tVDU[pos] = ((RGB_YUV_TABLE[(r + 1280)>>0] + RGB_YUV_TABLE[(g + 1536)>>0] + RGB_YUV_TABLE[(b + 1792)>>0]) >> 16)-128;\n\n  \t\t\t\t}\n  \t\t\t\t\n  \t\t\t\tDCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);\n  \t\t\t\tDCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);\n  \t\t\t\tDCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);\n  \t\t\t\tx+=32;\n  \t\t\t\t}\n  \t\t\t\ty+=8;\n  \t\t\t}\n  \t\t\t\n  \t\t\t\n  \t\t\t////////////////////////////////////////////////////////////////\n  \t\n  \t\t\t// Do the bit alignment of the EOI marker\n  \t\t\tif ( bytepos >= 0 ) {\n  \t\t\t\tvar fillbits = [];\n  \t\t\t\tfillbits[1] = bytepos+1;\n  \t\t\t\tfillbits[0] = (1<<(bytepos+1))-1;\n  \t\t\t\twriteBits(fillbits);\n  \t\t\t}\n  \t\n  \t\t\twriteWord(0xFFD9); //EOI\n\n        return new Uint8Array(byteout);\n        //return new Buffer(byteout);\n\n  \t\t\tvar jpegDataUri = 'data:image/jpeg;base64,' + btoa(byteout.join(''));\n  \t\t\t\n  \t\t\tbyteout = [];\n  \t\t\t\n  \t\t\t// benchmarking\n  \t\t\tvar duration = new Date().getTime() - time_start;\n      \t\t//console.log('Encoding time: '+ duration + 'ms');\n      \t\t//\n  \t\t\t\n  \t\t\treturn jpegDataUri\t\t\t\n  \t};\n  \t\n  \tfunction setQuality(quality){\n  \t\tif (quality <= 0) {\n  \t\t\tquality = 1;\n  \t\t}\n  \t\tif (quality > 100) {\n  \t\t\tquality = 100;\n  \t\t}\n  \t\t\n  \t\tif(currentQuality == quality) return // don't recalc if unchanged\n  \t\t\n  \t\tvar sf = 0;\n  \t\tif (quality < 50) {\n  \t\t\tsf = Math.floor(5000 / quality);\n  \t\t} else {\n  \t\t\tsf = Math.floor(200 - quality*2);\n  \t\t}\n  \t\t\n  \t\tinitQuantTables(sf);\n  \t\tcurrentQuality = quality;\n  \t\t//console.log('Quality set to: '+quality +'%');\n  \t}\n  \t\n  \tfunction init(){\n  \t\tvar time_start = new Date().getTime();\n  \t\tif(!quality) quality = 50;\n  \t\t// Create tables\n  \t\tinitCharLookupTable();\n  \t\tinitHuffmanTbl();\n  \t\tinitCategoryNumber();\n  \t\tinitRGBYUVTable();\n  \t\t\n  \t\tsetQuality(quality);\n  \t\tvar duration = new Date().getTime() - time_start;\n      \t//console.log('Initialization '+ duration + 'ms');\n  \t}\n  \t\n  \tinit();\n  \t\n  }\n\n\n  try { module.exports = JPEGEncoder; } catch(e) { }  // CommonJS.\n\n  /**\n   * @author shaozilee\n   *\n   * Bmp format decoder,support 1bit 4bit 8bit 24bit bmp\n   *\n   */\n\n  function BmpDecoder(buffer,is_with_alpha) {\n    this.pos = 0;\n    this.buffer = buffer;\n    this.datav = new DataView(buffer.buffer);\n    this.is_with_alpha = !!is_with_alpha;\n    this.bottom_up = true;\n    this.flag = String.fromCharCode(this.buffer[0]) + String.fromCharCode(this.buffer[1]);\n    this.pos += 2;\n    if ([\"BM\",\"BA\", \"CI\", \"CP\", \"IC\", \"PT\"].indexOf(this.flag) === -1) throw new Error(\"Invalid BMP File\");\n    this.parseHeader();\n    this.parseBGR();\n  }\n\n  BmpDecoder.prototype.parseHeader = function() {\n    this.fileSize = this.datav.getUint32(this.pos, true); \n    this.pos += 4;\n    this.reserved = this.datav.getUint32(this.pos, true); \n    this.pos += 4;\n    this.offset = this.datav.getUint32(this.pos, true); \n    this.pos += 4;\n    this.headerSize = this.datav.getUint32(this.pos, true); \n    this.pos += 4;\n    this.width = this.datav.getUint32(this.pos, true); \n    this.pos += 4;\n    this.height = this.datav.getInt32(this.pos, true);  this.pos += 4;\n    this.planes = this.datav.getUint16(this.pos, true); \n    this.pos += 2;\n    this.bitPP = this.datav.getUint16(this.pos, true); \n    this.pos += 2;\n    this.compress = this.datav.getUint32(this.pos, true); \n    this.pos += 4;\n    this.rawSize = this.datav.getUint32(this.pos, true); \n    this.pos += 4;\n    this.hr = this.datav.getUint32(this.pos, true); \n    this.pos += 4;\n    this.vr = this.datav.getUint32(this.pos, true); \n    this.pos += 4;\n    this.colors = this.datav.getUint32(this.pos, true); \n    this.pos += 4;\n    this.importantColors = this.datav.getUint32(this.pos, true); \n    this.pos += 4;\n\n    if(this.bitPP === 16 && this.is_with_alpha){\n      this.bitPP = 15;\n    }\n    if (this.bitPP < 15) {\n      var len = this.colors === 0 ? 1 << this.bitPP : this.colors;\n      this.palette = new Array(len);\n      for (var i = 0; i < len; i++) {\n        var blue = this.datav.getUint8(this.pos++, true);      var green = this.datav.getUint8(this.pos++, true);      var red = this.datav.getUint8(this.pos++, true);      var quad = this.datav.getUint8(this.pos++, true);      this.palette[i] = {\n          red: red,\n          green: green,\n          blue: blue,\n          quad: quad\n        };\n      }\n    }\n    if(this.height < 0) {\n      this.height *= -1;\n      this.bottom_up = false;\n    }\n\n  };\n\n  BmpDecoder.prototype.parseBGR = function() {\n    this.pos = this.offset;\n    try {\n      var bitn = \"bit\" + this.bitPP;\n      var len = this.width * this.height * 4;\n      this.data = new Uint8Array(len);\n\n      this[bitn]();\n    } catch (e) {\n      console.log(\"bit decode error:\" + e);\n    }\n\n  };\n\n  BmpDecoder.prototype.bit1 = function() {\n    var xlen = Math.ceil(this.width / 8);\n    var mode = xlen%4;\n    var y = this.height >= 0 ? this.height - 1 : -this.height;\n    for (var y = this.height - 1; y >= 0; y--) {\n      var line = this.bottom_up ? y : this.height - 1 - y;\n      for (var x = 0; x < xlen; x++) {\n        var b = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x*8*4;\n        for (var i = 0; i < 8; i++) {\n          if(x*8+i<this.width){\n            var rgb = this.palette[((b>>(7-i))&0x1)];\n            this.data[location+i*4] = rgb.blue;\n            this.data[location+i*4 + 1] = rgb.green;\n            this.data[location+i*4 + 2] = rgb.red;\n            this.data[location+i*4 + 3] = 0xFF;\n          }else{\n            break;\n          }\n        }\n      }\n\n      if (mode != 0){\n        this.pos+=(4 - mode);\n      }\n    }\n  };\n\n  BmpDecoder.prototype.bit4 = function() {\n    var xlen = Math.ceil(this.width/2);\n    var mode = xlen%4;\n    for (var y = this.height - 1; y >= 0; y--) {\n      var line = this.bottom_up ? y : this.height - 1 - y;\n      for (var x = 0; x < xlen; x++) {\n        var b = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x*2*4;\n\n        var before = b>>4;\n        var after = b&0x0F;\n\n        var rgb = this.palette[before];\n        this.data[location] = rgb.blue;\n        this.data[location + 1] = rgb.green;\n        this.data[location + 2] = rgb.red;\n        this.data[location + 3] = 0xFF;\n\n        if(x*2+1>=this.width)break;\n\n        rgb = this.palette[after];\n        this.data[location+4] = rgb.blue;\n        this.data[location+4 + 1] = rgb.green;\n        this.data[location+4 + 2] = rgb.red;\n        this.data[location+4 + 3] = 0xFF;\n      }\n\n      if (mode != 0){\n        this.pos+=(4 - mode);\n      }\n    }\n\n  };\n\n  BmpDecoder.prototype.bit8 = function() {\n    var mode = this.width%4;\n    for (var y = this.height - 1; y >= 0; y--) {\n      var line = this.bottom_up ? y : this.height - 1 - y;\n      for (var x = 0; x < this.width; x++) {\n        var b = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x*4;\n        if(b < this.palette.length) {\n          var rgb = this.palette[b];\n          this.data[location] = rgb.red;\n          this.data[location + 1] = rgb.green;\n          this.data[location + 2] = rgb.blue;\n          this.data[location + 3] = 0xFF;\n        } else {\n          this.data[location] = 0xFF;\n          this.data[location + 1] = 0xFF;\n          this.data[location + 2] = 0xFF;\n          this.data[location + 3] = 0xFF;\n        }\n      }\n      if (mode != 0){\n        this.pos+=(4 - mode);\n      }\n    }\n  };\n\n  BmpDecoder.prototype.bit15 = function() {\n    var dif_w =this.width % 3;\n    var _11111 = parseInt(\"11111\", 2),_1_5 = _11111;\n    for (var y = this.height - 1; y >= 0; y--) {\n      var line = this.bottom_up ? y : this.height - 1 - y;\n      for (var x = 0; x < this.width; x++) {\n\n        var B = this.datav.getUint16(this.pos, true); \n        this.pos+=2;\n        var blue = (B & _1_5) / _1_5 * 255 | 0;\n        var green = (B >> 5 & _1_5 ) / _1_5 * 255 | 0;\n        var red = (B >> 10 & _1_5) / _1_5 * 255 | 0;\n        var alpha = (B>>15)?0xFF:0x00;\n\n        var location = line * this.width * 4 + x * 4;\n        this.data[location] = red;\n        this.data[location + 1] = green;\n        this.data[location + 2] = blue;\n        this.data[location + 3] = alpha;\n      }\n      //skip extra bytes\n      this.pos += dif_w;\n    }\n  };\n\n  BmpDecoder.prototype.bit16 = function() {\n    var dif_w =this.width % 3;\n    var _11111 = parseInt(\"11111\", 2),_1_5 = _11111;\n    var _111111 = parseInt(\"111111\", 2),_1_6 = _111111;\n    for (var y = this.height - 1; y >= 0; y--) {\n      var line = this.bottom_up ? y : this.height - 1 - y;\n      for (var x = 0; x < this.width; x++) {\n\n        var B = this.datav.getUint16(this.pos, true); \n        this.pos+=2;\n        var alpha = 0xFF;\n        var blue = (B & _1_5) / _1_5 * 255 | 0;\n        var green = (B >> 5 & _1_6 ) / _1_6 * 255 | 0;\n        var red = (B >> 11) / _1_5 * 255 | 0;\n\n        var location = line * this.width * 4 + x * 4;\n        this.data[location] = red;\n        this.data[location + 1] = green;\n        this.data[location + 2] = blue;\n        this.data[location + 3] = alpha;\n      }\n      //skip extra bytes\n      this.pos += dif_w;\n    }\n  };\n\n  BmpDecoder.prototype.bit24 = function() {\n    //when height > 0\n    for (var y = this.height - 1; y >= 0; y--) {\n      var line = this.bottom_up ? y : this.height - 1 - y;\n      for (var x = 0; x < this.width; x++) {\n        var blue = this.datav.getUint8(this.pos++, true);      var green = this.datav.getUint8(this.pos++, true);      var red = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x * 4;\n        this.data[location] = red;\n        this.data[location + 1] = green;\n        this.data[location + 2] = blue;\n        this.data[location + 3] = 0xFF;\n      }\n      //skip extra bytes\n      this.pos += (this.width % 4);\n    }\n\n  };\n\n  /**\n   * add 32bit decode func\n   * @author soubok\n   */\n  BmpDecoder.prototype.bit32 = function() {\n    //when height > 0\n    for (var y = this.height - 1; y >= 0; y--) {\n      var line = this.bottom_up ? y : this.height - 1 - y;\n      for (var x = 0; x < this.width; x++) {\n        var blue = this.datav.getUint8(this.pos++, true);      var green = this.datav.getUint8(this.pos++, true);      var red = this.datav.getUint8(this.pos++, true);      var alpha = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x * 4;\n        this.data[location] = red;\n        this.data[location + 1] = green;\n        this.data[location + 2] = blue;\n        this.data[location + 3] = alpha;\n      }\n      //skip extra bytes\n      //this.pos += (this.width % 4);\n    }\n\n  };\n\n  BmpDecoder.prototype.getData = function() {\n    return this.data;\n  };\n\n  try { \n  \tmodule.exports = function(bmpData) {\n  \t\t  var decoder = new BmpDecoder(bmpData);\n  \t\t  return {\n  \t\t    data: decoder.getData(),\n  \t\t    width: decoder.width,\n  \t\t    height: decoder.height\n  \t\t  };\n  \t\t};\n  } catch(e) { }  // CommonJS.\n  \n\n  /*\n   Copyright (c) 2013 Gildas Lormeau. All rights reserved.\n\n   Redistribution and use in source and binary forms, with or without\n   modification, are permitted provided that the following conditions are met:\n\n   1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n   2. Redistributions in binary form must reproduce the above copyright \n   notice, this list of conditions and the following disclaimer in \n   the documentation and/or other materials provided with the distribution.\n\n   3. The names of the authors may not be used to endorse or promote products\n   derived from this software without specific prior written permission.\n\n   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,\n   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\n   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,\n   INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,\n   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\n   OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\n   EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n   */\n\n  /*\n   * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc.\n   * JZlib is based on zlib-1.1.3, so all credit should go authors\n   * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)\n   * and contributors of zlib.\n   */\n\n  (function(global) {\n\n  \t// Global\n\n  \tvar MAX_BITS = 15;\n  \tvar D_CODES = 30;\n  \tvar BL_CODES = 19;\n\n  \tvar LENGTH_CODES = 29;\n  \tvar LITERALS = 256;\n  \tvar L_CODES = (LITERALS + 1 + LENGTH_CODES);\n  \tvar HEAP_SIZE = (2 * L_CODES + 1);\n\n  \tvar END_BLOCK = 256;\n\n  \t// Bit length codes must not exceed MAX_BL_BITS bits\n  \tvar MAX_BL_BITS = 7;\n\n  \t// repeat previous bit length 3-6 times (2 bits of repeat count)\n  \tvar REP_3_6 = 16;\n\n  \t// repeat a zero length 3-10 times (3 bits of repeat count)\n  \tvar REPZ_3_10 = 17;\n\n  \t// repeat a zero length 11-138 times (7 bits of repeat count)\n  \tvar REPZ_11_138 = 18;\n\n  \t// The lengths of the bit length codes are sent in order of decreasing\n  \t// probability, to avoid transmitting the lengths for unused bit\n  \t// length codes.\n\n  \tvar Buf_size = 8 * 2;\n\n  \t// JZlib version : \"1.0.2\"\n  \tvar Z_DEFAULT_COMPRESSION = -1;\n\n  \t// compression strategy\n  \tvar Z_FILTERED = 1;\n  \tvar Z_HUFFMAN_ONLY = 2;\n  \tvar Z_DEFAULT_STRATEGY = 0;\n\n  \tvar Z_NO_FLUSH = 0;\n  \tvar Z_PARTIAL_FLUSH = 1;\n  \tvar Z_FULL_FLUSH = 3;\n  \tvar Z_FINISH = 4;\n\n  \tvar Z_OK = 0;\n  \tvar Z_STREAM_END = 1;\n  \tvar Z_NEED_DICT = 2;\n  \tvar Z_STREAM_ERROR = -2;\n  \tvar Z_DATA_ERROR = -3;\n  \tvar Z_BUF_ERROR = -5;\n\n  \t// Tree\n\n  \t// see definition of array dist_code below\n  \tvar _dist_code = [ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n  \t\t\t10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n  \t\t\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n  \t\t\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n  \t\t\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n  \t\t\t14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n  \t\t\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19,\n  \t\t\t20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n  \t\t\t24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n  \t\t\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n  \t\t\t27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n  \t\t\t28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29,\n  \t\t\t29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n  \t\t\t29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 ];\n\n  \tfunction Tree() {\n  \t\tvar that = this;\n\n  \t\t// dyn_tree; // the dynamic tree\n  \t\t// max_code; // largest code with non zero frequency\n  \t\t// stat_desc; // the corresponding static tree\n\n  \t\t// Compute the optimal bit lengths for a tree and update the total bit\n  \t\t// length\n  \t\t// for the current block.\n  \t\t// IN assertion: the fields freq and dad are set, heap[heap_max] and\n  \t\t// above are the tree nodes sorted by increasing frequency.\n  \t\t// OUT assertions: the field len is set to the optimal bit length, the\n  \t\t// array bl_count contains the frequencies for each bit length.\n  \t\t// The length opt_len is updated; static_len is also updated if stree is\n  \t\t// not null.\n  \t\tfunction gen_bitlen(s) {\n  \t\t\tvar tree = that.dyn_tree;\n  \t\t\tvar stree = that.stat_desc.static_tree;\n  \t\t\tvar extra = that.stat_desc.extra_bits;\n  \t\t\tvar base = that.stat_desc.extra_base;\n  \t\t\tvar max_length = that.stat_desc.max_length;\n  \t\t\tvar h; // heap index\n  \t\t\tvar n, m; // iterate over the tree elements\n  \t\t\tvar bits; // bit length\n  \t\t\tvar xbits; // extra bits\n  \t\t\tvar f; // frequency\n  \t\t\tvar overflow = 0; // number of elements with bit length too large\n\n  \t\t\tfor (bits = 0; bits <= MAX_BITS; bits++)\n  \t\t\t\ts.bl_count[bits] = 0;\n\n  \t\t\t// In a first pass, compute the optimal bit lengths (which may\n  \t\t\t// overflow in the case of the bit length tree).\n  \t\t\ttree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap\n\n  \t\t\tfor (h = s.heap_max + 1; h < HEAP_SIZE; h++) {\n  \t\t\t\tn = s.heap[h];\n  \t\t\t\tbits = tree[tree[n * 2 + 1] * 2 + 1] + 1;\n  \t\t\t\tif (bits > max_length) {\n  \t\t\t\t\tbits = max_length;\n  \t\t\t\t\toverflow++;\n  \t\t\t\t}\n  \t\t\t\ttree[n * 2 + 1] = bits;\n  \t\t\t\t// We overwrite tree[n*2+1] which is no longer needed\n\n  \t\t\t\tif (n > that.max_code)\n  \t\t\t\t\tcontinue; // not a leaf node\n\n  \t\t\t\ts.bl_count[bits]++;\n  \t\t\t\txbits = 0;\n  \t\t\t\tif (n >= base)\n  \t\t\t\t\txbits = extra[n - base];\n  \t\t\t\tf = tree[n * 2];\n  \t\t\t\ts.opt_len += f * (bits + xbits);\n  \t\t\t\tif (stree)\n  \t\t\t\t\ts.static_len += f * (stree[n * 2 + 1] + xbits);\n  \t\t\t}\n  \t\t\tif (overflow === 0)\n  \t\t\t\treturn;\n\n  \t\t\t// This happens for example on obj2 and pic of the Calgary corpus\n  \t\t\t// Find the first bit length which could increase:\n  \t\t\tdo {\n  \t\t\t\tbits = max_length - 1;\n  \t\t\t\twhile (s.bl_count[bits] === 0)\n  \t\t\t\t\tbits--;\n  \t\t\t\ts.bl_count[bits]--; // move one leaf down the tree\n  \t\t\t\ts.bl_count[bits + 1] += 2; // move one overflow item as its brother\n  \t\t\t\ts.bl_count[max_length]--;\n  \t\t\t\t// The brother of the overflow item also moves one step up,\n  \t\t\t\t// but this does not affect bl_count[max_length]\n  \t\t\t\toverflow -= 2;\n  \t\t\t} while (overflow > 0);\n\n  \t\t\tfor (bits = max_length; bits !== 0; bits--) {\n  \t\t\t\tn = s.bl_count[bits];\n  \t\t\t\twhile (n !== 0) {\n  \t\t\t\t\tm = s.heap[--h];\n  \t\t\t\t\tif (m > that.max_code)\n  \t\t\t\t\t\tcontinue;\n  \t\t\t\t\tif (tree[m * 2 + 1] != bits) {\n  \t\t\t\t\t\ts.opt_len += (bits - tree[m * 2 + 1]) * tree[m * 2];\n  \t\t\t\t\t\ttree[m * 2 + 1] = bits;\n  \t\t\t\t\t}\n  \t\t\t\t\tn--;\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n\n  \t\t// Reverse the first len bits of a code, using straightforward code (a\n  \t\t// faster\n  \t\t// method would use a table)\n  \t\t// IN assertion: 1 <= len <= 15\n  \t\tfunction bi_reverse(code, // the value to invert\n  \t\tlen // its bit length\n  \t\t) {\n  \t\t\tvar res = 0;\n  \t\t\tdo {\n  \t\t\t\tres |= code & 1;\n  \t\t\t\tcode >>>= 1;\n  \t\t\t\tres <<= 1;\n  \t\t\t} while (--len > 0);\n  \t\t\treturn res >>> 1;\n  \t\t}\n\n  \t\t// Generate the codes for a given tree and bit counts (which need not be\n  \t\t// optimal).\n  \t\t// IN assertion: the array bl_count contains the bit length statistics for\n  \t\t// the given tree and the field len is set for all tree elements.\n  \t\t// OUT assertion: the field code is set for all tree elements of non\n  \t\t// zero code length.\n  \t\tfunction gen_codes(tree, // the tree to decorate\n  \t\tmax_code, // largest code with non zero frequency\n  \t\tbl_count // number of codes at each bit length\n  \t\t) {\n  \t\t\tvar next_code = []; // next code value for each\n  \t\t\t// bit length\n  \t\t\tvar code = 0; // running code value\n  \t\t\tvar bits; // bit index\n  \t\t\tvar n; // code index\n  \t\t\tvar len;\n\n  \t\t\t// The distribution counts are first used to generate the code values\n  \t\t\t// without bit reversal.\n  \t\t\tfor (bits = 1; bits <= MAX_BITS; bits++) {\n  \t\t\t\tnext_code[bits] = code = ((code + bl_count[bits - 1]) << 1);\n  \t\t\t}\n\n  \t\t\t// Check that the bit counts in bl_count are consistent. The last code\n  \t\t\t// must be all ones.\n  \t\t\t// Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,\n  \t\t\t// \"inconsistent bit counts\");\n  \t\t\t// Tracev((stderr,\"\\ngen_codes: max_code %d \", max_code));\n\n  \t\t\tfor (n = 0; n <= max_code; n++) {\n  \t\t\t\tlen = tree[n * 2 + 1];\n  \t\t\t\tif (len === 0)\n  \t\t\t\t\tcontinue;\n  \t\t\t\t// Now reverse the bits\n  \t\t\t\ttree[n * 2] = bi_reverse(next_code[len]++, len);\n  \t\t\t}\n  \t\t}\n\n  \t\t// Construct one Huffman tree and assigns the code bit strings and lengths.\n  \t\t// Update the total bit length for the current block.\n  \t\t// IN assertion: the field freq is set for all tree elements.\n  \t\t// OUT assertions: the fields len and code are set to the optimal bit length\n  \t\t// and corresponding code. The length opt_len is updated; static_len is\n  \t\t// also updated if stree is not null. The field max_code is set.\n  \t\tthat.build_tree = function(s) {\n  \t\t\tvar tree = that.dyn_tree;\n  \t\t\tvar stree = that.stat_desc.static_tree;\n  \t\t\tvar elems = that.stat_desc.elems;\n  \t\t\tvar n, m; // iterate over heap elements\n  \t\t\tvar max_code = -1; // largest code with non zero frequency\n  \t\t\tvar node; // new node being created\n\n  \t\t\t// Construct the initial heap, with least frequent element in\n  \t\t\t// heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1].\n  \t\t\t// heap[0] is not used.\n  \t\t\ts.heap_len = 0;\n  \t\t\ts.heap_max = HEAP_SIZE;\n\n  \t\t\tfor (n = 0; n < elems; n++) {\n  \t\t\t\tif (tree[n * 2] !== 0) {\n  \t\t\t\t\ts.heap[++s.heap_len] = max_code = n;\n  \t\t\t\t\ts.depth[n] = 0;\n  \t\t\t\t} else {\n  \t\t\t\t\ttree[n * 2 + 1] = 0;\n  \t\t\t\t}\n  \t\t\t}\n\n  \t\t\t// The pkzip format requires that at least one distance code exists,\n  \t\t\t// and that at least one bit should be sent even if there is only one\n  \t\t\t// possible code. So to avoid special checks later on we force at least\n  \t\t\t// two codes of non zero frequency.\n  \t\t\twhile (s.heap_len < 2) {\n  \t\t\t\tnode = s.heap[++s.heap_len] = max_code < 2 ? ++max_code : 0;\n  \t\t\t\ttree[node * 2] = 1;\n  \t\t\t\ts.depth[node] = 0;\n  \t\t\t\ts.opt_len--;\n  \t\t\t\tif (stree)\n  \t\t\t\t\ts.static_len -= stree[node * 2 + 1];\n  \t\t\t\t// node is 0 or 1 so it does not have extra bits\n  \t\t\t}\n  \t\t\tthat.max_code = max_code;\n\n  \t\t\t// The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,\n  \t\t\t// establish sub-heaps of increasing lengths:\n\n  \t\t\tfor (n = Math.floor(s.heap_len / 2); n >= 1; n--)\n  \t\t\t\ts.pqdownheap(tree, n);\n\n  \t\t\t// Construct the Huffman tree by repeatedly combining the least two\n  \t\t\t// frequent nodes.\n\n  \t\t\tnode = elems; // next internal node of the tree\n  \t\t\tdo {\n  \t\t\t\t// n = node of least frequency\n  \t\t\t\tn = s.heap[1];\n  \t\t\t\ts.heap[1] = s.heap[s.heap_len--];\n  \t\t\t\ts.pqdownheap(tree, 1);\n  \t\t\t\tm = s.heap[1]; // m = node of next least frequency\n\n  \t\t\t\ts.heap[--s.heap_max] = n; // keep the nodes sorted by frequency\n  \t\t\t\ts.heap[--s.heap_max] = m;\n\n  \t\t\t\t// Create a new node father of n and m\n  \t\t\t\ttree[node * 2] = (tree[n * 2] + tree[m * 2]);\n  \t\t\t\ts.depth[node] = Math.max(s.depth[n], s.depth[m]) + 1;\n  \t\t\t\ttree[n * 2 + 1] = tree[m * 2 + 1] = node;\n\n  \t\t\t\t// and insert the new node in the heap\n  \t\t\t\ts.heap[1] = node++;\n  \t\t\t\ts.pqdownheap(tree, 1);\n  \t\t\t} while (s.heap_len >= 2);\n\n  \t\t\ts.heap[--s.heap_max] = s.heap[1];\n\n  \t\t\t// At this point, the fields freq and dad are set. We can now\n  \t\t\t// generate the bit lengths.\n\n  \t\t\tgen_bitlen(s);\n\n  \t\t\t// The field len is now set, we can generate the bit codes\n  \t\t\tgen_codes(tree, that.max_code, s.bl_count);\n  \t\t};\n\n  \t}\n\n  \tTree._length_code = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16,\n  \t\t\t16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20,\n  \t\t\t20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,\n  \t\t\t22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n  \t\t\t24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n  \t\t\t25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n  \t\t\t26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 ];\n\n  \tTree.base_length = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 ];\n\n  \tTree.base_dist = [ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384,\n  \t\t\t24576 ];\n\n  \t// Mapping from a distance to a distance code. dist is the distance - 1 and\n  \t// must not have side effects. _dist_code[256] and _dist_code[257] are never\n  \t// used.\n  \tTree.d_code = function(dist) {\n  \t\treturn ((dist) < 256 ? _dist_code[dist] : _dist_code[256 + ((dist) >>> 7)]);\n  \t};\n\n  \t// extra bits for each length code\n  \tTree.extra_lbits = [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 ];\n\n  \t// extra bits for each distance code\n  \tTree.extra_dbits = [ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 ];\n\n  \t// extra bits for each bit length code\n  \tTree.extra_blbits = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 ];\n\n  \tTree.bl_order = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];\n\n  \t// StaticTree\n\n  \tfunction StaticTree(static_tree, extra_bits, extra_base, elems, max_length) {\n  \t\tvar that = this;\n  \t\tthat.static_tree = static_tree;\n  \t\tthat.extra_bits = extra_bits;\n  \t\tthat.extra_base = extra_base;\n  \t\tthat.elems = elems;\n  \t\tthat.max_length = max_length;\n  \t}\n\n  \tStaticTree.static_ltree = [ 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, 2, 8,\n  \t\t\t130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, 202, 8, 42,\n  \t\t\t8, 170, 8, 106, 8, 234, 8, 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8,\n  \t\t\t22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, 30, 8, 158, 8, 94, 8,\n  \t\t\t222, 8, 62, 8, 190, 8, 126, 8, 254, 8, 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113,\n  \t\t\t8, 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, 5, 8, 133, 8,\n  \t\t\t69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, 77, 8, 205, 8, 45, 8,\n  \t\t\t173, 8, 109, 8, 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9,\n  \t\t\t51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, 171, 9,\n  \t\t\t427, 9, 107, 9, 363, 9, 235, 9, 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379,\n  \t\t\t9, 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, 23,\n  \t\t\t9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, 271, 9, 143, 9,\n  \t\t\t399, 9, 79, 9, 335, 9, 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9,\n  \t\t\t223, 9, 479, 9, 63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, 72, 7,\n  \t\t\t40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8,\n  \t\t\t99, 8, 227, 8 ];\n\n  \tStaticTree.static_dtree = [ 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, 1, 5, 17, 5, 9, 5,\n  \t\t\t25, 5, 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 ];\n\n  \tStaticTree.static_l_desc = new StaticTree(StaticTree.static_ltree, Tree.extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);\n\n  \tStaticTree.static_d_desc = new StaticTree(StaticTree.static_dtree, Tree.extra_dbits, 0, D_CODES, MAX_BITS);\n\n  \tStaticTree.static_bl_desc = new StaticTree(null, Tree.extra_blbits, 0, BL_CODES, MAX_BL_BITS);\n\n  \t// Deflate\n\n  \tvar MAX_MEM_LEVEL = 9;\n  \tvar DEF_MEM_LEVEL = 8;\n\n  \tfunction Config(good_length, max_lazy, nice_length, max_chain, func) {\n  \t\tvar that = this;\n  \t\tthat.good_length = good_length;\n  \t\tthat.max_lazy = max_lazy;\n  \t\tthat.nice_length = nice_length;\n  \t\tthat.max_chain = max_chain;\n  \t\tthat.func = func;\n  \t}\n\n  \tvar STORED = 0;\n  \tvar FAST = 1;\n  \tvar SLOW = 2;\n  \tvar config_table = [ new Config(0, 0, 0, 0, STORED), new Config(4, 4, 8, 4, FAST), new Config(4, 5, 16, 8, FAST), new Config(4, 6, 32, 32, FAST),\n  \t\t\tnew Config(4, 4, 16, 16, SLOW), new Config(8, 16, 32, 32, SLOW), new Config(8, 16, 128, 128, SLOW), new Config(8, 32, 128, 256, SLOW),\n  \t\t\tnew Config(32, 128, 258, 1024, SLOW), new Config(32, 258, 258, 4096, SLOW) ];\n\n  \tvar z_errmsg = [ \"need dictionary\", // Z_NEED_DICT\n  \t// 2\n  \t\"stream end\", // Z_STREAM_END 1\n  \t\"\", // Z_OK 0\n  \t\"\", // Z_ERRNO (-1)\n  \t\"stream error\", // Z_STREAM_ERROR (-2)\n  \t\"data error\", // Z_DATA_ERROR (-3)\n  \t\"\", // Z_MEM_ERROR (-4)\n  \t\"buffer error\", // Z_BUF_ERROR (-5)\n  \t\"\",// Z_VERSION_ERROR (-6)\n  \t\"\" ];\n\n  \t// block not completed, need more input or more output\n  \tvar NeedMore = 0;\n\n  \t// block flush performed\n  \tvar BlockDone = 1;\n\n  \t// finish started, need only more output at next deflate\n  \tvar FinishStarted = 2;\n\n  \t// finish done, accept no more input or output\n  \tvar FinishDone = 3;\n\n  \t// preset dictionary flag in zlib header\n  \tvar PRESET_DICT = 0x20;\n\n  \tvar INIT_STATE = 42;\n  \tvar BUSY_STATE = 113;\n  \tvar FINISH_STATE = 666;\n\n  \t// The deflate compression method\n  \tvar Z_DEFLATED = 8;\n\n  \tvar STORED_BLOCK = 0;\n  \tvar STATIC_TREES = 1;\n  \tvar DYN_TREES = 2;\n\n  \tvar MIN_MATCH = 3;\n  \tvar MAX_MATCH = 258;\n  \tvar MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);\n\n  \tfunction smaller(tree, n, m, depth) {\n  \t\tvar tn2 = tree[n * 2];\n  \t\tvar tm2 = tree[m * 2];\n  \t\treturn (tn2 < tm2 || (tn2 == tm2 && depth[n] <= depth[m]));\n  \t}\n\n  \tfunction Deflate() {\n\n  \t\tvar that = this;\n  \t\tvar strm; // pointer back to this zlib stream\n  \t\tvar status; // as the name implies\n  \t\t// pending_buf; // output still pending\n  \t\tvar pending_buf_size; // size of pending_buf\n  \t\tvar last_flush; // value of flush param for previous deflate call\n\n  \t\tvar w_size; // LZ77 window size (32K by default)\n  \t\tvar w_bits; // log2(w_size) (8..16)\n  \t\tvar w_mask; // w_size - 1\n\n  \t\tvar window;\n  \t\t// Sliding window. Input bytes are read into the second half of the window,\n  \t\t// and move to the first half later to keep a dictionary of at least wSize\n  \t\t// bytes. With this organization, matches are limited to a distance of\n  \t\t// wSize-MAX_MATCH bytes, but this ensures that IO is always\n  \t\t// performed with a length multiple of the block size. Also, it limits\n  \t\t// the window size to 64K, which is quite useful on MSDOS.\n  \t\t// To do: use the user input buffer as sliding window.\n\n  \t\tvar window_size;\n  \t\t// Actual size of window: 2*wSize, except when the user input buffer\n  \t\t// is directly used as sliding window.\n\n  \t\tvar prev;\n  \t\t// Link to older string with same hash index. To limit the size of this\n  \t\t// array to 64K, this link is maintained only for the last 32K strings.\n  \t\t// An index in this array is thus a window index modulo 32K.\n\n  \t\tvar head; // Heads of the hash chains or NIL.\n\n  \t\tvar ins_h; // hash index of string to be inserted\n  \t\tvar hash_size; // number of elements in hash table\n  \t\tvar hash_bits; // log2(hash_size)\n  \t\tvar hash_mask; // hash_size-1\n\n  \t\t// Number of bits by which ins_h must be shifted at each input\n  \t\t// step. It must be such that after MIN_MATCH steps, the oldest\n  \t\t// byte no longer takes part in the hash key, that is:\n  \t\t// hash_shift * MIN_MATCH >= hash_bits\n  \t\tvar hash_shift;\n\n  \t\t// Window position at the beginning of the current output block. Gets\n  \t\t// negative when the window is moved backwards.\n\n  \t\tvar block_start;\n\n  \t\tvar match_length; // length of best match\n  \t\tvar prev_match; // previous match\n  \t\tvar match_available; // set if previous match exists\n  \t\tvar strstart; // start of string to insert\n  \t\tvar match_start; // start of matching string\n  \t\tvar lookahead; // number of valid bytes ahead in window\n\n  \t\t// Length of the best match at previous step. Matches not greater than this\n  \t\t// are discarded. This is used in the lazy match evaluation.\n  \t\tvar prev_length;\n\n  \t\t// To speed up deflation, hash chains are never searched beyond this\n  \t\t// length. A higher limit improves compression ratio but degrades the speed.\n  \t\tvar max_chain_length;\n\n  \t\t// Attempt to find a better match only when the current match is strictly\n  \t\t// smaller than this value. This mechanism is used only for compression\n  \t\t// levels >= 4.\n  \t\tvar max_lazy_match;\n\n  \t\t// Insert new strings in the hash table only if the match length is not\n  \t\t// greater than this length. This saves time but degrades compression.\n  \t\t// max_insert_length is used only for compression levels <= 3.\n\n  \t\tvar level; // compression level (1..9)\n  \t\tvar strategy; // favor or force Huffman coding\n\n  \t\t// Use a faster search when the previous match is longer than this\n  \t\tvar good_match;\n\n  \t\t// Stop searching when current match exceeds this\n  \t\tvar nice_match;\n\n  \t\tvar dyn_ltree; // literal and length tree\n  \t\tvar dyn_dtree; // distance tree\n  \t\tvar bl_tree; // Huffman tree for bit lengths\n\n  \t\tvar l_desc = new Tree(); // desc for literal tree\n  \t\tvar d_desc = new Tree(); // desc for distance tree\n  \t\tvar bl_desc = new Tree(); // desc for bit length tree\n\n  \t\t// that.heap_len; // number of elements in the heap\n  \t\t// that.heap_max; // element of largest frequency\n  \t\t// The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.\n  \t\t// The same heap array is used to build all trees.\n\n  \t\t// Depth of each subtree used as tie breaker for trees of equal frequency\n  \t\tthat.depth = [];\n\n  \t\tvar l_buf; // index for literals or lengths */\n\n  \t\t// Size of match buffer for literals/lengths. There are 4 reasons for\n  \t\t// limiting lit_bufsize to 64K:\n  \t\t// - frequencies can be kept in 16 bit counters\n  \t\t// - if compression is not successful for the first block, all input\n  \t\t// data is still in the window so we can still emit a stored block even\n  \t\t// when input comes from standard input. (This can also be done for\n  \t\t// all blocks if lit_bufsize is not greater than 32K.)\n  \t\t// - if compression is not successful for a file smaller than 64K, we can\n  \t\t// even emit a stored file instead of a stored block (saving 5 bytes).\n  \t\t// This is applicable only for zip (not gzip or zlib).\n  \t\t// - creating new Huffman trees less frequently may not provide fast\n  \t\t// adaptation to changes in the input data statistics. (Take for\n  \t\t// example a binary file with poorly compressible code followed by\n  \t\t// a highly compressible string table.) Smaller buffer sizes give\n  \t\t// fast adaptation but have of course the overhead of transmitting\n  \t\t// trees more frequently.\n  \t\t// - I can't count above 4\n  \t\tvar lit_bufsize;\n\n  \t\tvar last_lit; // running index in l_buf\n\n  \t\t// Buffer for distances. To simplify the code, d_buf and l_buf have\n  \t\t// the same number of elements. To use different lengths, an extra flag\n  \t\t// array would be necessary.\n\n  \t\tvar d_buf; // index of pendig_buf\n\n  \t\t// that.opt_len; // bit length of current block with optimal trees\n  \t\t// that.static_len; // bit length of current block with static trees\n  \t\tvar matches; // number of string matches in current block\n  \t\tvar last_eob_len; // bit length of EOB code for last block\n\n  \t\t// Output buffer. bits are inserted starting at the bottom (least\n  \t\t// significant bits).\n  \t\tvar bi_buf;\n\n  \t\t// Number of valid bits in bi_buf. All bits above the last valid bit\n  \t\t// are always zero.\n  \t\tvar bi_valid;\n\n  \t\t// number of codes at each bit length for an optimal tree\n  \t\tthat.bl_count = [];\n\n  \t\t// heap used to build the Huffman trees\n  \t\tthat.heap = [];\n\n  \t\tdyn_ltree = [];\n  \t\tdyn_dtree = [];\n  \t\tbl_tree = [];\n\n  \t\tfunction lm_init() {\n  \t\t\tvar i;\n  \t\t\twindow_size = 2 * w_size;\n\n  \t\t\thead[hash_size - 1] = 0;\n  \t\t\tfor (i = 0; i < hash_size - 1; i++) {\n  \t\t\t\thead[i] = 0;\n  \t\t\t}\n\n  \t\t\t// Set the default configuration parameters:\n  \t\t\tmax_lazy_match = config_table[level].max_lazy;\n  \t\t\tgood_match = config_table[level].good_length;\n  \t\t\tnice_match = config_table[level].nice_length;\n  \t\t\tmax_chain_length = config_table[level].max_chain;\n\n  \t\t\tstrstart = 0;\n  \t\t\tblock_start = 0;\n  \t\t\tlookahead = 0;\n  \t\t\tmatch_length = prev_length = MIN_MATCH - 1;\n  \t\t\tmatch_available = 0;\n  \t\t\tins_h = 0;\n  \t\t}\n\n  \t\tfunction init_block() {\n  \t\t\tvar i;\n  \t\t\t// Initialize the trees.\n  \t\t\tfor (i = 0; i < L_CODES; i++)\n  \t\t\t\tdyn_ltree[i * 2] = 0;\n  \t\t\tfor (i = 0; i < D_CODES; i++)\n  \t\t\t\tdyn_dtree[i * 2] = 0;\n  \t\t\tfor (i = 0; i < BL_CODES; i++)\n  \t\t\t\tbl_tree[i * 2] = 0;\n\n  \t\t\tdyn_ltree[END_BLOCK * 2] = 1;\n  \t\t\tthat.opt_len = that.static_len = 0;\n  \t\t\tlast_lit = matches = 0;\n  \t\t}\n\n  \t\t// Initialize the tree data structures for a new zlib stream.\n  \t\tfunction tr_init() {\n\n  \t\t\tl_desc.dyn_tree = dyn_ltree;\n  \t\t\tl_desc.stat_desc = StaticTree.static_l_desc;\n\n  \t\t\td_desc.dyn_tree = dyn_dtree;\n  \t\t\td_desc.stat_desc = StaticTree.static_d_desc;\n\n  \t\t\tbl_desc.dyn_tree = bl_tree;\n  \t\t\tbl_desc.stat_desc = StaticTree.static_bl_desc;\n\n  \t\t\tbi_buf = 0;\n  \t\t\tbi_valid = 0;\n  \t\t\tlast_eob_len = 8; // enough lookahead for inflate\n\n  \t\t\t// Initialize the first block of the first file:\n  \t\t\tinit_block();\n  \t\t}\n\n  \t\t// Restore the heap property by moving down the tree starting at node k,\n  \t\t// exchanging a node with the smallest of its two sons if necessary,\n  \t\t// stopping\n  \t\t// when the heap property is re-established (each father smaller than its\n  \t\t// two sons).\n  \t\tthat.pqdownheap = function(tree, // the tree to restore\n  \t\tk // node to move down\n  \t\t) {\n  \t\t\tvar heap = that.heap;\n  \t\t\tvar v = heap[k];\n  \t\t\tvar j = k << 1; // left son of k\n  \t\t\twhile (j <= that.heap_len) {\n  \t\t\t\t// Set j to the smallest of the two sons:\n  \t\t\t\tif (j < that.heap_len && smaller(tree, heap[j + 1], heap[j], that.depth)) {\n  \t\t\t\t\tj++;\n  \t\t\t\t}\n  \t\t\t\t// Exit if v is smaller than both sons\n  \t\t\t\tif (smaller(tree, v, heap[j], that.depth))\n  \t\t\t\t\tbreak;\n\n  \t\t\t\t// Exchange v with the smallest son\n  \t\t\t\theap[k] = heap[j];\n  \t\t\t\tk = j;\n  \t\t\t\t// And continue down the tree, setting j to the left son of k\n  \t\t\t\tj <<= 1;\n  \t\t\t}\n  \t\t\theap[k] = v;\n  \t\t};\n\n  \t\t// Scan a literal or distance tree to determine the frequencies of the codes\n  \t\t// in the bit length tree.\n  \t\tfunction scan_tree(tree,// the tree to be scanned\n  \t\tmax_code // and its largest code of non zero frequency\n  \t\t) {\n  \t\t\tvar n; // iterates over all tree elements\n  \t\t\tvar prevlen = -1; // last emitted length\n  \t\t\tvar curlen; // length of current code\n  \t\t\tvar nextlen = tree[0 * 2 + 1]; // length of next code\n  \t\t\tvar count = 0; // repeat count of the current code\n  \t\t\tvar max_count = 7; // max repeat count\n  \t\t\tvar min_count = 4; // min repeat count\n\n  \t\t\tif (nextlen === 0) {\n  \t\t\t\tmax_count = 138;\n  \t\t\t\tmin_count = 3;\n  \t\t\t}\n  \t\t\ttree[(max_code + 1) * 2 + 1] = 0xffff; // guard\n\n  \t\t\tfor (n = 0; n <= max_code; n++) {\n  \t\t\t\tcurlen = nextlen;\n  \t\t\t\tnextlen = tree[(n + 1) * 2 + 1];\n  \t\t\t\tif (++count < max_count && curlen == nextlen) {\n  \t\t\t\t\tcontinue;\n  \t\t\t\t} else if (count < min_count) {\n  \t\t\t\t\tbl_tree[curlen * 2] += count;\n  \t\t\t\t} else if (curlen !== 0) {\n  \t\t\t\t\tif (curlen != prevlen)\n  \t\t\t\t\t\tbl_tree[curlen * 2]++;\n  \t\t\t\t\tbl_tree[REP_3_6 * 2]++;\n  \t\t\t\t} else if (count <= 10) {\n  \t\t\t\t\tbl_tree[REPZ_3_10 * 2]++;\n  \t\t\t\t} else {\n  \t\t\t\t\tbl_tree[REPZ_11_138 * 2]++;\n  \t\t\t\t}\n  \t\t\t\tcount = 0;\n  \t\t\t\tprevlen = curlen;\n  \t\t\t\tif (nextlen === 0) {\n  \t\t\t\t\tmax_count = 138;\n  \t\t\t\t\tmin_count = 3;\n  \t\t\t\t} else if (curlen == nextlen) {\n  \t\t\t\t\tmax_count = 6;\n  \t\t\t\t\tmin_count = 3;\n  \t\t\t\t} else {\n  \t\t\t\t\tmax_count = 7;\n  \t\t\t\t\tmin_count = 4;\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n\n  \t\t// Construct the Huffman tree for the bit lengths and return the index in\n  \t\t// bl_order of the last bit length code to send.\n  \t\tfunction build_bl_tree() {\n  \t\t\tvar max_blindex; // index of last bit length code of non zero freq\n\n  \t\t\t// Determine the bit length frequencies for literal and distance trees\n  \t\t\tscan_tree(dyn_ltree, l_desc.max_code);\n  \t\t\tscan_tree(dyn_dtree, d_desc.max_code);\n\n  \t\t\t// Build the bit length tree:\n  \t\t\tbl_desc.build_tree(that);\n  \t\t\t// opt_len now includes the length of the tree representations, except\n  \t\t\t// the lengths of the bit lengths codes and the 5+5+4 bits for the\n  \t\t\t// counts.\n\n  \t\t\t// Determine the number of bit length codes to send. The pkzip format\n  \t\t\t// requires that at least 4 bit length codes be sent. (appnote.txt says\n  \t\t\t// 3 but the actual value used is 4.)\n  \t\t\tfor (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {\n  \t\t\t\tif (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] !== 0)\n  \t\t\t\t\tbreak;\n  \t\t\t}\n  \t\t\t// Update opt_len to include the bit length tree and counts\n  \t\t\tthat.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;\n\n  \t\t\treturn max_blindex;\n  \t\t}\n\n  \t\t// Output a byte on the stream.\n  \t\t// IN assertion: there is enough room in pending_buf.\n  \t\tfunction put_byte(p) {\n  \t\t\tthat.pending_buf[that.pending++] = p;\n  \t\t}\n\n  \t\tfunction put_short(w) {\n  \t\t\tput_byte(w & 0xff);\n  \t\t\tput_byte((w >>> 8) & 0xff);\n  \t\t}\n\n  \t\tfunction putShortMSB(b) {\n  \t\t\tput_byte((b >> 8) & 0xff);\n  \t\t\tput_byte((b & 0xff) & 0xff);\n  \t\t}\n\n  \t\tfunction send_bits(value, length) {\n  \t\t\tvar val, len = length;\n  \t\t\tif (bi_valid > Buf_size - len) {\n  \t\t\t\tval = value;\n  \t\t\t\t// bi_buf |= (val << bi_valid);\n  \t\t\t\tbi_buf |= ((val << bi_valid) & 0xffff);\n  \t\t\t\tput_short(bi_buf);\n  \t\t\t\tbi_buf = val >>> (Buf_size - bi_valid);\n  \t\t\t\tbi_valid += len - Buf_size;\n  \t\t\t} else {\n  \t\t\t\t// bi_buf |= (value) << bi_valid;\n  \t\t\t\tbi_buf |= (((value) << bi_valid) & 0xffff);\n  \t\t\t\tbi_valid += len;\n  \t\t\t}\n  \t\t}\n\n  \t\tfunction send_code(c, tree) {\n  \t\t\tvar c2 = c * 2;\n  \t\t\tsend_bits(tree[c2] & 0xffff, tree[c2 + 1] & 0xffff);\n  \t\t}\n\n  \t\t// Send a literal or distance tree in compressed form, using the codes in\n  \t\t// bl_tree.\n  \t\tfunction send_tree(tree,// the tree to be sent\n  \t\tmax_code // and its largest code of non zero frequency\n  \t\t) {\n  \t\t\tvar n; // iterates over all tree elements\n  \t\t\tvar prevlen = -1; // last emitted length\n  \t\t\tvar curlen; // length of current code\n  \t\t\tvar nextlen = tree[0 * 2 + 1]; // length of next code\n  \t\t\tvar count = 0; // repeat count of the current code\n  \t\t\tvar max_count = 7; // max repeat count\n  \t\t\tvar min_count = 4; // min repeat count\n\n  \t\t\tif (nextlen === 0) {\n  \t\t\t\tmax_count = 138;\n  \t\t\t\tmin_count = 3;\n  \t\t\t}\n\n  \t\t\tfor (n = 0; n <= max_code; n++) {\n  \t\t\t\tcurlen = nextlen;\n  \t\t\t\tnextlen = tree[(n + 1) * 2 + 1];\n  \t\t\t\tif (++count < max_count && curlen == nextlen) {\n  \t\t\t\t\tcontinue;\n  \t\t\t\t} else if (count < min_count) {\n  \t\t\t\t\tdo {\n  \t\t\t\t\t\tsend_code(curlen, bl_tree);\n  \t\t\t\t\t} while (--count !== 0);\n  \t\t\t\t} else if (curlen !== 0) {\n  \t\t\t\t\tif (curlen != prevlen) {\n  \t\t\t\t\t\tsend_code(curlen, bl_tree);\n  \t\t\t\t\t\tcount--;\n  \t\t\t\t\t}\n  \t\t\t\t\tsend_code(REP_3_6, bl_tree);\n  \t\t\t\t\tsend_bits(count - 3, 2);\n  \t\t\t\t} else if (count <= 10) {\n  \t\t\t\t\tsend_code(REPZ_3_10, bl_tree);\n  \t\t\t\t\tsend_bits(count - 3, 3);\n  \t\t\t\t} else {\n  \t\t\t\t\tsend_code(REPZ_11_138, bl_tree);\n  \t\t\t\t\tsend_bits(count - 11, 7);\n  \t\t\t\t}\n  \t\t\t\tcount = 0;\n  \t\t\t\tprevlen = curlen;\n  \t\t\t\tif (nextlen === 0) {\n  \t\t\t\t\tmax_count = 138;\n  \t\t\t\t\tmin_count = 3;\n  \t\t\t\t} else if (curlen == nextlen) {\n  \t\t\t\t\tmax_count = 6;\n  \t\t\t\t\tmin_count = 3;\n  \t\t\t\t} else {\n  \t\t\t\t\tmax_count = 7;\n  \t\t\t\t\tmin_count = 4;\n  \t\t\t\t}\n  \t\t\t}\n  \t\t}\n\n  \t\t// Send the header for a block using dynamic Huffman trees: the counts, the\n  \t\t// lengths of the bit length codes, the literal tree and the distance tree.\n  \t\t// IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.\n  \t\tfunction send_all_trees(lcodes, dcodes, blcodes) {\n  \t\t\tvar rank; // index in bl_order\n\n  \t\t\tsend_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt\n  \t\t\tsend_bits(dcodes - 1, 5);\n  \t\t\tsend_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt\n  \t\t\tfor (rank = 0; rank < blcodes; rank++) {\n  \t\t\t\tsend_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3);\n  \t\t\t}\n  \t\t\tsend_tree(dyn_ltree, lcodes - 1); // literal tree\n  \t\t\tsend_tree(dyn_dtree, dcodes - 1); // distance tree\n  \t\t}\n\n  \t\t// Flush the bit buffer, keeping at most 7 bits in it.\n  \t\tfunction bi_flush() {\n  \t\t\tif (bi_valid == 16) {\n  \t\t\t\tput_short(bi_buf);\n  \t\t\t\tbi_buf = 0;\n  \t\t\t\tbi_valid = 0;\n  \t\t\t} else if (bi_valid >= 8) {\n  \t\t\t\tput_byte(bi_buf & 0xff);\n  \t\t\t\tbi_buf >>>= 8;\n  \t\t\t\tbi_valid -= 8;\n  \t\t\t}\n  \t\t}\n\n  \t\t// Send one empty static block to give enough lookahead for inflate.\n  \t\t// This takes 10 bits, of which 7 may remain in the bit buffer.\n  \t\t// The current inflate code requires 9 bits of lookahead. If the\n  \t\t// last two codes for the previous block (real code plus EOB) were coded\n  \t\t// on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode\n  \t\t// the last real code. In this case we send two empty static blocks instead\n  \t\t// of one. (There are no problems if the previous block is stored or fixed.)\n  \t\t// To simplify the code, we assume the worst case of last real code encoded\n  \t\t// on one bit only.\n  \t\tfunction _tr_align() {\n  \t\t\tsend_bits(STATIC_TREES << 1, 3);\n  \t\t\tsend_code(END_BLOCK, StaticTree.static_ltree);\n\n  \t\t\tbi_flush();\n\n  \t\t\t// Of the 10 bits for the empty block, we have already sent\n  \t\t\t// (10 - bi_valid) bits. The lookahead for the last real code (before\n  \t\t\t// the EOB of the previous block) was thus at least one plus the length\n  \t\t\t// of the EOB plus what we have just sent of the empty static block.\n  \t\t\tif (1 + last_eob_len + 10 - bi_valid < 9) {\n  \t\t\t\tsend_bits(STATIC_TREES << 1, 3);\n  \t\t\t\tsend_code(END_BLOCK, StaticTree.static_ltree);\n  \t\t\t\tbi_flush();\n  \t\t\t}\n  \t\t\tlast_eob_len = 7;\n  \t\t}\n\n  \t\t// Save the match info and tally the frequency counts. Return true if\n  \t\t// the current block must be flushed.\n  \t\tfunction _tr_tally(dist, // distance of matched string\n  \t\tlc // match length-MIN_MATCH or unmatched char (if dist==0)\n  \t\t) {\n  \t\t\tvar out_length, in_length, dcode;\n  \t\t\tthat.pending_buf[d_buf + last_lit * 2] = (dist >>> 8) & 0xff;\n  \t\t\tthat.pending_buf[d_buf + last_lit * 2 + 1] = dist & 0xff;\n\n  \t\t\tthat.pending_buf[l_buf + last_lit] = lc & 0xff;\n  \t\t\tlast_lit++;\n\n  \t\t\tif (dist === 0) {\n  \t\t\t\t// lc is the unmatched char\n  \t\t\t\tdyn_ltree[lc * 2]++;\n  \t\t\t} else {\n  \t\t\t\tmatches++;\n  \t\t\t\t// Here, lc is the match length - MIN_MATCH\n  \t\t\t\tdist--; // dist = match distance - 1\n  \t\t\t\tdyn_ltree[(Tree._length_code[lc] + LITERALS + 1) * 2]++;\n  \t\t\t\tdyn_dtree[Tree.d_code(dist) * 2]++;\n  \t\t\t}\n\n  \t\t\tif ((last_lit & 0x1fff) === 0 && level > 2) {\n  \t\t\t\t// Compute an upper bound for the compressed length\n  \t\t\t\tout_length = last_lit * 8;\n  \t\t\t\tin_length = strstart - block_start;\n  \t\t\t\tfor (dcode = 0; dcode < D_CODES; dcode++) {\n  \t\t\t\t\tout_length += dyn_dtree[dcode * 2] * (5 + Tree.extra_dbits[dcode]);\n  \t\t\t\t}\n  \t\t\t\tout_length >>>= 3;\n  \t\t\t\tif ((matches < Math.floor(last_lit / 2)) && out_length < Math.floor(in_length / 2))\n  \t\t\t\t\treturn true;\n  \t\t\t}\n\n  \t\t\treturn (last_lit == lit_bufsize - 1);\n  \t\t\t// We avoid equality with lit_bufsize because of wraparound at 64K\n  \t\t\t// on 16 bit machines and because stored blocks are restricted to\n  \t\t\t// 64K-1 bytes.\n  \t\t}\n\n  \t\t// Send the block data compressed using the given Huffman trees\n  \t\tfunction compress_block(ltree, dtree) {\n  \t\t\tvar dist; // distance of matched string\n  \t\t\tvar lc; // match length or unmatched char (if dist === 0)\n  \t\t\tvar lx = 0; // running index in l_buf\n  \t\t\tvar code; // the code to send\n  \t\t\tvar extra; // number of extra bits to send\n\n  \t\t\tif (last_lit !== 0) {\n  \t\t\t\tdo {\n  \t\t\t\t\tdist = ((that.pending_buf[d_buf + lx * 2] << 8) & 0xff00) | (that.pending_buf[d_buf + lx * 2 + 1] & 0xff);\n  \t\t\t\t\tlc = (that.pending_buf[l_buf + lx]) & 0xff;\n  \t\t\t\t\tlx++;\n\n  \t\t\t\t\tif (dist === 0) {\n  \t\t\t\t\t\tsend_code(lc, ltree); // send a literal byte\n  \t\t\t\t\t} else {\n  \t\t\t\t\t\t// Here, lc is the match length - MIN_MATCH\n  \t\t\t\t\t\tcode = Tree._length_code[lc];\n\n  \t\t\t\t\t\tsend_code(code + LITERALS + 1, ltree); // send the length\n  \t\t\t\t\t\t// code\n  \t\t\t\t\t\textra = Tree.extra_lbits[code];\n  \t\t\t\t\t\tif (extra !== 0) {\n  \t\t\t\t\t\t\tlc -= Tree.base_length[code];\n  \t\t\t\t\t\t\tsend_bits(lc, extra); // send the extra length bits\n  \t\t\t\t\t\t}\n  \t\t\t\t\t\tdist--; // dist is now the match distance - 1\n  \t\t\t\t\t\tcode = Tree.d_code(dist);\n\n  \t\t\t\t\t\tsend_code(code, dtree); // send the distance code\n  \t\t\t\t\t\textra = Tree.extra_dbits[code];\n  \t\t\t\t\t\tif (extra !== 0) {\n  \t\t\t\t\t\t\tdist -= Tree.base_dist[code];\n  \t\t\t\t\t\t\tsend_bits(dist, extra); // send the extra distance bits\n  \t\t\t\t\t\t}\n  \t\t\t\t\t} // literal or match pair ?\n\n  \t\t\t\t\t// Check that the overlay between pending_buf and d_buf+l_buf is\n  \t\t\t\t\t// ok:\n  \t\t\t\t} while (lx < last_lit);\n  \t\t\t}\n\n  \t\t\tsend_code(END_BLOCK, ltree);\n  \t\t\tlast_eob_len = ltree[END_BLOCK * 2 + 1];\n  \t\t}\n\n  \t\t// Flush the bit buffer and align the output on a byte boundary\n  \t\tfunction bi_windup() {\n  \t\t\tif (bi_valid > 8) {\n  \t\t\t\tput_short(bi_buf);\n  \t\t\t} else if (bi_valid > 0) {\n  \t\t\t\tput_byte(bi_buf & 0xff);\n  \t\t\t}\n  \t\t\tbi_buf = 0;\n  \t\t\tbi_valid = 0;\n  \t\t}\n\n  \t\t// Copy a stored block, storing first the length and its\n  \t\t// one's complement if requested.\n  \t\tfunction copy_block(buf, // the input data\n  \t\tlen, // its length\n  \t\theader // true if block header must be written\n  \t\t) {\n  \t\t\tbi_windup(); // align on byte boundary\n  \t\t\tlast_eob_len = 8; // enough lookahead for inflate\n\n  \t\t\tif (header) {\n  \t\t\t\tput_short(len);\n  \t\t\t\tput_short(~len);\n  \t\t\t}\n\n  \t\t\tthat.pending_buf.set(window.subarray(buf, buf + len), that.pending);\n  \t\t\tthat.pending += len;\n  \t\t}\n\n  \t\t// Send a stored block\n  \t\tfunction _tr_stored_block(buf, // input block\n  \t\tstored_len, // length of input block\n  \t\teof // true if this is the last block for a file\n  \t\t) {\n  \t\t\tsend_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type\n  \t\t\tcopy_block(buf, stored_len, true); // with header\n  \t\t}\n\n  \t\t// Determine the best encoding for the current block: dynamic trees, static\n  \t\t// trees or store, and output the encoded block to the zip file.\n  \t\tfunction _tr_flush_block(buf, // input block, or NULL if too old\n  \t\tstored_len, // length of input block\n  \t\teof // true if this is the last block for a file\n  \t\t) {\n  \t\t\tvar opt_lenb, static_lenb;// opt_len and static_len in bytes\n  \t\t\tvar max_blindex = 0; // index of last bit length code of non zero freq\n\n  \t\t\t// Build the Huffman trees unless a stored block is forced\n  \t\t\tif (level > 0) {\n  \t\t\t\t// Construct the literal and distance trees\n  \t\t\t\tl_desc.build_tree(that);\n\n  \t\t\t\td_desc.build_tree(that);\n\n  \t\t\t\t// At this point, opt_len and static_len are the total bit lengths\n  \t\t\t\t// of\n  \t\t\t\t// the compressed block data, excluding the tree representations.\n\n  \t\t\t\t// Build the bit length tree for the above two trees, and get the\n  \t\t\t\t// index\n  \t\t\t\t// in bl_order of the last bit length code to send.\n  \t\t\t\tmax_blindex = build_bl_tree();\n\n  \t\t\t\t// Determine the best encoding. Compute first the block length in\n  \t\t\t\t// bytes\n  \t\t\t\topt_lenb = (that.opt_len + 3 + 7) >>> 3;\n  \t\t\t\tstatic_lenb = (that.static_len + 3 + 7) >>> 3;\n\n  \t\t\t\tif (static_lenb <= opt_lenb)\n  \t\t\t\t\topt_lenb = static_lenb;\n  \t\t\t} else {\n  \t\t\t\topt_lenb = static_lenb = stored_len + 5; // force a stored block\n  \t\t\t}\n\n  \t\t\tif ((stored_len + 4 <= opt_lenb) && buf != -1) {\n  \t\t\t\t// 4: two words for the lengths\n  \t\t\t\t// The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.\n  \t\t\t\t// Otherwise we can't have processed more than WSIZE input bytes\n  \t\t\t\t// since\n  \t\t\t\t// the last block flush, because compression would have been\n  \t\t\t\t// successful. If LIT_BUFSIZE <= WSIZE, it is never too late to\n  \t\t\t\t// transform a block into a stored block.\n  \t\t\t\t_tr_stored_block(buf, stored_len, eof);\n  \t\t\t} else if (static_lenb == opt_lenb) {\n  \t\t\t\tsend_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3);\n  \t\t\t\tcompress_block(StaticTree.static_ltree, StaticTree.static_dtree);\n  \t\t\t} else {\n  \t\t\t\tsend_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3);\n  \t\t\t\tsend_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, max_blindex + 1);\n  \t\t\t\tcompress_block(dyn_ltree, dyn_dtree);\n  \t\t\t}\n\n  \t\t\t// The above check is made mod 2^32, for files larger than 512 MB\n  \t\t\t// and uLong implemented on 32 bits.\n\n  \t\t\tinit_block();\n\n  \t\t\tif (eof) {\n  \t\t\t\tbi_windup();\n  \t\t\t}\n  \t\t}\n\n  \t\tfunction flush_block_only(eof) {\n  \t\t\t_tr_flush_block(block_start >= 0 ? block_start : -1, strstart - block_start, eof);\n  \t\t\tblock_start = strstart;\n  \t\t\tstrm.flush_pending();\n  \t\t}\n\n  \t\t// Fill the window when the lookahead becomes insufficient.\n  \t\t// Updates strstart and lookahead.\n  \t\t//\n  \t\t// IN assertion: lookahead < MIN_LOOKAHEAD\n  \t\t// OUT assertions: strstart <= window_size-MIN_LOOKAHEAD\n  \t\t// At least one byte has been read, or avail_in === 0; reads are\n  \t\t// performed for at least two bytes (required for the zip translate_eol\n  \t\t// option -- not supported here).\n  \t\tfunction fill_window() {\n  \t\t\tvar n, m;\n  \t\t\tvar p;\n  \t\t\tvar more; // Amount of free space at the end of the window.\n\n  \t\t\tdo {\n  \t\t\t\tmore = (window_size - lookahead - strstart);\n\n  \t\t\t\t// Deal with !@#$% 64K limit:\n  \t\t\t\tif (more === 0 && strstart === 0 && lookahead === 0) {\n  \t\t\t\t\tmore = w_size;\n  \t\t\t\t} else if (more == -1) {\n  \t\t\t\t\t// Very unlikely, but possible on 16 bit machine if strstart ==\n  \t\t\t\t\t// 0\n  \t\t\t\t\t// and lookahead == 1 (input done one byte at time)\n  \t\t\t\t\tmore--;\n\n  \t\t\t\t\t// If the window is almost full and there is insufficient\n  \t\t\t\t\t// lookahead,\n  \t\t\t\t\t// move the upper half to the lower one to make room in the\n  \t\t\t\t\t// upper half.\n  \t\t\t\t} else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) {\n  \t\t\t\t\twindow.set(window.subarray(w_size, w_size + w_size), 0);\n\n  \t\t\t\t\tmatch_start -= w_size;\n  \t\t\t\t\tstrstart -= w_size; // we now have strstart >= MAX_DIST\n  \t\t\t\t\tblock_start -= w_size;\n\n  \t\t\t\t\t// Slide the hash table (could be avoided with 32 bit values\n  \t\t\t\t\t// at the expense of memory usage). We slide even when level ==\n  \t\t\t\t\t// 0\n  \t\t\t\t\t// to keep the hash table consistent if we switch back to level\n  \t\t\t\t\t// > 0\n  \t\t\t\t\t// later. (Using level 0 permanently is not an optimal usage of\n  \t\t\t\t\t// zlib, so we don't care about this pathological case.)\n\n  \t\t\t\t\tn = hash_size;\n  \t\t\t\t\tp = n;\n  \t\t\t\t\tdo {\n  \t\t\t\t\t\tm = (head[--p] & 0xffff);\n  \t\t\t\t\t\thead[p] = (m >= w_size ? m - w_size : 0);\n  \t\t\t\t\t} while (--n !== 0);\n\n  \t\t\t\t\tn = w_size;\n  \t\t\t\t\tp = n;\n  \t\t\t\t\tdo {\n  \t\t\t\t\t\tm = (prev[--p] & 0xffff);\n  \t\t\t\t\t\tprev[p] = (m >= w_size ? m - w_size : 0);\n  \t\t\t\t\t\t// If n is not on any hash chain, prev[n] is garbage but\n  \t\t\t\t\t\t// its value will never be used.\n  \t\t\t\t\t} while (--n !== 0);\n  \t\t\t\t\tmore += w_size;\n  \t\t\t\t}\n\n  \t\t\t\tif (strm.avail_in === 0)\n  \t\t\t\t\treturn;\n\n  \t\t\t\t// If there was no sliding:\n  \t\t\t\t// strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&\n  \t\t\t\t// more == window_size - lookahead - strstart\n  \t\t\t\t// => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)\n  \t\t\t\t// => more >= window_size - 2*WSIZE + 2\n  \t\t\t\t// In the BIG_MEM or MMAP case (not yet supported),\n  \t\t\t\t// window_size == input_size + MIN_LOOKAHEAD &&\n  \t\t\t\t// strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.\n  \t\t\t\t// Otherwise, window_size == 2*WSIZE so more >= 2.\n  \t\t\t\t// If there was sliding, more >= WSIZE. So in all cases, more >= 2.\n\n  \t\t\t\tn = strm.read_buf(window, strstart + lookahead, more);\n  \t\t\t\tlookahead += n;\n\n  \t\t\t\t// Initialize the hash value now that we have some input:\n  \t\t\t\tif (lookahead >= MIN_MATCH) {\n  \t\t\t\t\tins_h = window[strstart] & 0xff;\n  \t\t\t\t\tins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;\n  \t\t\t\t}\n  \t\t\t\t// If the whole input has less than MIN_MATCH bytes, ins_h is\n  \t\t\t\t// garbage,\n  \t\t\t\t// but this is not important since only literal bytes will be\n  \t\t\t\t// emitted.\n  \t\t\t} while (lookahead < MIN_LOOKAHEAD && strm.avail_in !== 0);\n  \t\t}\n\n  \t\t// Copy without compression as much as possible from the input stream,\n  \t\t// return\n  \t\t// the current block state.\n  \t\t// This function does not insert new strings in the dictionary since\n  \t\t// uncompressible data is probably not useful. This function is used\n  \t\t// only for the level=0 compression option.\n  \t\t// NOTE: this function should be optimized to avoid extra copying from\n  \t\t// window to pending_buf.\n  \t\tfunction deflate_stored(flush) {\n  \t\t\t// Stored blocks are limited to 0xffff bytes, pending_buf is limited\n  \t\t\t// to pending_buf_size, and each stored block has a 5 byte header:\n\n  \t\t\tvar max_block_size = 0xffff;\n  \t\t\tvar max_start;\n\n  \t\t\tif (max_block_size > pending_buf_size - 5) {\n  \t\t\t\tmax_block_size = pending_buf_size - 5;\n  \t\t\t}\n\n  \t\t\t// Copy as much as possible from input to output:\n  \t\t\twhile (true) {\n  \t\t\t\t// Fill the window as much as possible:\n  \t\t\t\tif (lookahead <= 1) {\n  \t\t\t\t\tfill_window();\n  \t\t\t\t\tif (lookahead === 0 && flush == Z_NO_FLUSH)\n  \t\t\t\t\t\treturn NeedMore;\n  \t\t\t\t\tif (lookahead === 0)\n  \t\t\t\t\t\tbreak; // flush the current block\n  \t\t\t\t}\n\n  \t\t\t\tstrstart += lookahead;\n  \t\t\t\tlookahead = 0;\n\n  \t\t\t\t// Emit a stored block if pending_buf will be full:\n  \t\t\t\tmax_start = block_start + max_block_size;\n  \t\t\t\tif (strstart === 0 || strstart >= max_start) {\n  \t\t\t\t\t// strstart === 0 is possible when wraparound on 16-bit machine\n  \t\t\t\t\tlookahead = (strstart - max_start);\n  \t\t\t\t\tstrstart = max_start;\n\n  \t\t\t\t\tflush_block_only(false);\n  \t\t\t\t\tif (strm.avail_out === 0)\n  \t\t\t\t\t\treturn NeedMore;\n\n  \t\t\t\t}\n\n  \t\t\t\t// Flush if we may have to slide, otherwise block_start may become\n  \t\t\t\t// negative and the data will be gone:\n  \t\t\t\tif (strstart - block_start >= w_size - MIN_LOOKAHEAD) {\n  \t\t\t\t\tflush_block_only(false);\n  \t\t\t\t\tif (strm.avail_out === 0)\n  \t\t\t\t\t\treturn NeedMore;\n  \t\t\t\t}\n  \t\t\t}\n\n  \t\t\tflush_block_only(flush == Z_FINISH);\n  \t\t\tif (strm.avail_out === 0)\n  \t\t\t\treturn (flush == Z_FINISH) ? FinishStarted : NeedMore;\n\n  \t\t\treturn flush == Z_FINISH ? FinishDone : BlockDone;\n  \t\t}\n\n  \t\tfunction longest_match(cur_match) {\n  \t\t\tvar chain_length = max_chain_length; // max hash chain length\n  \t\t\tvar scan = strstart; // current string\n  \t\t\tvar match; // matched string\n  \t\t\tvar len; // length of current match\n  \t\t\tvar best_len = prev_length; // best match length so far\n  \t\t\tvar limit = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0;\n  \t\t\tvar _nice_match = nice_match;\n\n  \t\t\t// Stop when cur_match becomes <= limit. To simplify the code,\n  \t\t\t// we prevent matches with the string of window index 0.\n\n  \t\t\tvar wmask = w_mask;\n\n  \t\t\tvar strend = strstart + MAX_MATCH;\n  \t\t\tvar scan_end1 = window[scan + best_len - 1];\n  \t\t\tvar scan_end = window[scan + best_len];\n\n  \t\t\t// The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of\n  \t\t\t// 16.\n  \t\t\t// It is easy to get rid of this optimization if necessary.\n\n  \t\t\t// Do not waste too much time if we already have a good match:\n  \t\t\tif (prev_length >= good_match) {\n  \t\t\t\tchain_length >>= 2;\n  \t\t\t}\n\n  \t\t\t// Do not look for matches beyond the end of the input. This is\n  \t\t\t// necessary\n  \t\t\t// to make deflate deterministic.\n  \t\t\tif (_nice_match > lookahead)\n  \t\t\t\t_nice_match = lookahead;\n\n  \t\t\tdo {\n  \t\t\t\tmatch = cur_match;\n\n  \t\t\t\t// Skip to next match if the match length cannot increase\n  \t\t\t\t// or if the match length is less than 2:\n  \t\t\t\tif (window[match + best_len] != scan_end || window[match + best_len - 1] != scan_end1 || window[match] != window[scan]\n  \t\t\t\t\t\t|| window[++match] != window[scan + 1])\n  \t\t\t\t\tcontinue;\n\n  \t\t\t\t// The check at best_len-1 can be removed because it will be made\n  \t\t\t\t// again later. (This heuristic is not always a win.)\n  \t\t\t\t// It is not necessary to compare scan[2] and match[2] since they\n  \t\t\t\t// are always equal when the other bytes match, given that\n  \t\t\t\t// the hash keys are equal and that HASH_BITS >= 8.\n  \t\t\t\tscan += 2;\n  \t\t\t\tmatch++;\n\n  \t\t\t\t// We check for insufficient lookahead only every 8th comparison;\n  \t\t\t\t// the 256th check will be made at strstart+258.\n  \t\t\t\tdo {\n  \t\t\t\t} while (window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match]\n  \t\t\t\t\t\t&& window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match]\n  \t\t\t\t\t\t&& window[++scan] == window[++match] && window[++scan] == window[++match] && scan < strend);\n\n  \t\t\t\tlen = MAX_MATCH - (strend - scan);\n  \t\t\t\tscan = strend - MAX_MATCH;\n\n  \t\t\t\tif (len > best_len) {\n  \t\t\t\t\tmatch_start = cur_match;\n  \t\t\t\t\tbest_len = len;\n  \t\t\t\t\tif (len >= _nice_match)\n  \t\t\t\t\t\tbreak;\n  \t\t\t\t\tscan_end1 = window[scan + best_len - 1];\n  \t\t\t\t\tscan_end = window[scan + best_len];\n  \t\t\t\t}\n\n  \t\t\t} while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length !== 0);\n\n  \t\t\tif (best_len <= lookahead)\n  \t\t\t\treturn best_len;\n  \t\t\treturn lookahead;\n  \t\t}\n\n  \t\t// Compress as much as possible from the input stream, return the current\n  \t\t// block state.\n  \t\t// This function does not perform lazy evaluation of matches and inserts\n  \t\t// new strings in the dictionary only for unmatched strings or for short\n  \t\t// matches. It is used only for the fast compression options.\n  \t\tfunction deflate_fast(flush) {\n  \t\t\t// short hash_head = 0; // head of the hash chain\n  \t\t\tvar hash_head = 0; // head of the hash chain\n  \t\t\tvar bflush; // set if current block must be flushed\n\n  \t\t\twhile (true) {\n  \t\t\t\t// Make sure that we always have enough lookahead, except\n  \t\t\t\t// at the end of the input file. We need MAX_MATCH bytes\n  \t\t\t\t// for the next match, plus MIN_MATCH bytes to insert the\n  \t\t\t\t// string following the next match.\n  \t\t\t\tif (lookahead < MIN_LOOKAHEAD) {\n  \t\t\t\t\tfill_window();\n  \t\t\t\t\tif (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {\n  \t\t\t\t\t\treturn NeedMore;\n  \t\t\t\t\t}\n  \t\t\t\t\tif (lookahead === 0)\n  \t\t\t\t\t\tbreak; // flush the current block\n  \t\t\t\t}\n\n  \t\t\t\t// Insert the string window[strstart .. strstart+2] in the\n  \t\t\t\t// dictionary, and set hash_head to the head of the hash chain:\n  \t\t\t\tif (lookahead >= MIN_MATCH) {\n  \t\t\t\t\tins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;\n\n  \t\t\t\t\t// prev[strstart&w_mask]=hash_head=head[ins_h];\n  \t\t\t\t\thash_head = (head[ins_h] & 0xffff);\n  \t\t\t\t\tprev[strstart & w_mask] = head[ins_h];\n  \t\t\t\t\thead[ins_h] = strstart;\n  \t\t\t\t}\n\n  \t\t\t\t// Find the longest match, discarding those <= prev_length.\n  \t\t\t\t// At this point we have always match_length < MIN_MATCH\n\n  \t\t\t\tif (hash_head !== 0 && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) {\n  \t\t\t\t\t// To simplify the code, we prevent matches with the string\n  \t\t\t\t\t// of window index 0 (in particular we have to avoid a match\n  \t\t\t\t\t// of the string with itself at the start of the input file).\n  \t\t\t\t\tif (strategy != Z_HUFFMAN_ONLY) {\n  \t\t\t\t\t\tmatch_length = longest_match(hash_head);\n  \t\t\t\t\t}\n  \t\t\t\t\t// longest_match() sets match_start\n  \t\t\t\t}\n  \t\t\t\tif (match_length >= MIN_MATCH) {\n  \t\t\t\t\t// check_match(strstart, match_start, match_length);\n\n  \t\t\t\t\tbflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH);\n\n  \t\t\t\t\tlookahead -= match_length;\n\n  \t\t\t\t\t// Insert new strings in the hash table only if the match length\n  \t\t\t\t\t// is not too large. This saves time but degrades compression.\n  \t\t\t\t\tif (match_length <= max_lazy_match && lookahead >= MIN_MATCH) {\n  \t\t\t\t\t\tmatch_length--; // string at strstart already in hash table\n  \t\t\t\t\t\tdo {\n  \t\t\t\t\t\t\tstrstart++;\n\n  \t\t\t\t\t\t\tins_h = ((ins_h << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;\n  \t\t\t\t\t\t\t// prev[strstart&w_mask]=hash_head=head[ins_h];\n  \t\t\t\t\t\t\thash_head = (head[ins_h] & 0xffff);\n  \t\t\t\t\t\t\tprev[strstart & w_mask] = head[ins_h];\n  \t\t\t\t\t\t\thead[ins_h] = strstart;\n\n  \t\t\t\t\t\t\t// strstart never exceeds WSIZE-MAX_MATCH, so there are\n  \t\t\t\t\t\t\t// always MIN_MATCH bytes ahead.\n  \t\t\t\t\t\t} while (--match_length !== 0);\n  \t\t\t\t\t\tstrstart++;\n  \t\t\t\t\t} else {\n  \t\t\t\t\t\tstrstart += match_length;\n  \t\t\t\t\t\tmatch_length = 0;\n  \t\t\t\t\t\tins_h = window[strstart] & 0xff;\n\n  \t\t\t\t\t\tins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;\n  \t\t\t\t\t\t// If lookahead < MIN_MATCH, ins_h is garbage, but it does\n  \t\t\t\t\t\t// not\n  \t\t\t\t\t\t// matter since it will be recomputed at next deflate call.\n  \t\t\t\t\t}\n  \t\t\t\t} else {\n  \t\t\t\t\t// No match, output a literal byte\n\n  \t\t\t\t\tbflush = _tr_tally(0, window[strstart] & 0xff);\n  \t\t\t\t\tlookahead--;\n  \t\t\t\t\tstrstart++;\n  \t\t\t\t}\n  \t\t\t\tif (bflush) {\n\n  \t\t\t\t\tflush_block_only(false);\n  \t\t\t\t\tif (strm.avail_out === 0)\n  \t\t\t\t\t\treturn NeedMore;\n  \t\t\t\t}\n  \t\t\t}\n\n  \t\t\tflush_block_only(flush == Z_FINISH);\n  \t\t\tif (strm.avail_out === 0) {\n  \t\t\t\tif (flush == Z_FINISH)\n  \t\t\t\t\treturn FinishStarted;\n  \t\t\t\telse\n  \t\t\t\t\treturn NeedMore;\n  \t\t\t}\n  \t\t\treturn flush == Z_FINISH ? FinishDone : BlockDone;\n  \t\t}\n\n  \t\t// Same as above, but achieves better compression. We use a lazy\n  \t\t// evaluation for matches: a match is finally adopted only if there is\n  \t\t// no better match at the next window position.\n  \t\tfunction deflate_slow(flush) {\n  \t\t\t// short hash_head = 0; // head of hash chain\n  \t\t\tvar hash_head = 0; // head of hash chain\n  \t\t\tvar bflush; // set if current block must be flushed\n  \t\t\tvar max_insert;\n\n  \t\t\t// Process the input block.\n  \t\t\twhile (true) {\n  \t\t\t\t// Make sure that we always have enough lookahead, except\n  \t\t\t\t// at the end of the input file. We need MAX_MATCH bytes\n  \t\t\t\t// for the next match, plus MIN_MATCH bytes to insert the\n  \t\t\t\t// string following the next match.\n\n  \t\t\t\tif (lookahead < MIN_LOOKAHEAD) {\n  \t\t\t\t\tfill_window();\n  \t\t\t\t\tif (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {\n  \t\t\t\t\t\treturn NeedMore;\n  \t\t\t\t\t}\n  \t\t\t\t\tif (lookahead === 0)\n  \t\t\t\t\t\tbreak; // flush the current block\n  \t\t\t\t}\n\n  \t\t\t\t// Insert the string window[strstart .. strstart+2] in the\n  \t\t\t\t// dictionary, and set hash_head to the head of the hash chain:\n\n  \t\t\t\tif (lookahead >= MIN_MATCH) {\n  \t\t\t\t\tins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;\n  \t\t\t\t\t// prev[strstart&w_mask]=hash_head=head[ins_h];\n  \t\t\t\t\thash_head = (head[ins_h] & 0xffff);\n  \t\t\t\t\tprev[strstart & w_mask] = head[ins_h];\n  \t\t\t\t\thead[ins_h] = strstart;\n  \t\t\t\t}\n\n  \t\t\t\t// Find the longest match, discarding those <= prev_length.\n  \t\t\t\tprev_length = match_length;\n  \t\t\t\tprev_match = match_start;\n  \t\t\t\tmatch_length = MIN_MATCH - 1;\n\n  \t\t\t\tif (hash_head !== 0 && prev_length < max_lazy_match && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) {\n  \t\t\t\t\t// To simplify the code, we prevent matches with the string\n  \t\t\t\t\t// of window index 0 (in particular we have to avoid a match\n  \t\t\t\t\t// of the string with itself at the start of the input file).\n\n  \t\t\t\t\tif (strategy != Z_HUFFMAN_ONLY) {\n  \t\t\t\t\t\tmatch_length = longest_match(hash_head);\n  \t\t\t\t\t}\n  \t\t\t\t\t// longest_match() sets match_start\n\n  \t\t\t\t\tif (match_length <= 5 && (strategy == Z_FILTERED || (match_length == MIN_MATCH && strstart - match_start > 4096))) {\n\n  \t\t\t\t\t\t// If prev_match is also MIN_MATCH, match_start is garbage\n  \t\t\t\t\t\t// but we will ignore the current match anyway.\n  \t\t\t\t\t\tmatch_length = MIN_MATCH - 1;\n  \t\t\t\t\t}\n  \t\t\t\t}\n\n  \t\t\t\t// If there was a match at the previous step and the current\n  \t\t\t\t// match is not better, output the previous match:\n  \t\t\t\tif (prev_length >= MIN_MATCH && match_length <= prev_length) {\n  \t\t\t\t\tmax_insert = strstart + lookahead - MIN_MATCH;\n  \t\t\t\t\t// Do not insert strings in hash table beyond this.\n\n  \t\t\t\t\t// check_match(strstart-1, prev_match, prev_length);\n\n  \t\t\t\t\tbflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);\n\n  \t\t\t\t\t// Insert in hash table all strings up to the end of the match.\n  \t\t\t\t\t// strstart-1 and strstart are already inserted. If there is not\n  \t\t\t\t\t// enough lookahead, the last two strings are not inserted in\n  \t\t\t\t\t// the hash table.\n  \t\t\t\t\tlookahead -= prev_length - 1;\n  \t\t\t\t\tprev_length -= 2;\n  \t\t\t\t\tdo {\n  \t\t\t\t\t\tif (++strstart <= max_insert) {\n  \t\t\t\t\t\t\tins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;\n  \t\t\t\t\t\t\t// prev[strstart&w_mask]=hash_head=head[ins_h];\n  \t\t\t\t\t\t\thash_head = (head[ins_h] & 0xffff);\n  \t\t\t\t\t\t\tprev[strstart & w_mask] = head[ins_h];\n  \t\t\t\t\t\t\thead[ins_h] = strstart;\n  \t\t\t\t\t\t}\n  \t\t\t\t\t} while (--prev_length !== 0);\n  \t\t\t\t\tmatch_available = 0;\n  \t\t\t\t\tmatch_length = MIN_MATCH - 1;\n  \t\t\t\t\tstrstart++;\n\n  \t\t\t\t\tif (bflush) {\n  \t\t\t\t\t\tflush_block_only(false);\n  \t\t\t\t\t\tif (strm.avail_out === 0)\n  \t\t\t\t\t\t\treturn NeedMore;\n  \t\t\t\t\t}\n  \t\t\t\t} else if (match_available !== 0) {\n\n  \t\t\t\t\t// If there was no match at the previous position, output a\n  \t\t\t\t\t// single literal. If there was a match but the current match\n  \t\t\t\t\t// is longer, truncate the previous match to a single literal.\n\n  \t\t\t\t\tbflush = _tr_tally(0, window[strstart - 1] & 0xff);\n\n  \t\t\t\t\tif (bflush) {\n  \t\t\t\t\t\tflush_block_only(false);\n  \t\t\t\t\t}\n  \t\t\t\t\tstrstart++;\n  \t\t\t\t\tlookahead--;\n  \t\t\t\t\tif (strm.avail_out === 0)\n  \t\t\t\t\t\treturn NeedMore;\n  \t\t\t\t} else {\n  \t\t\t\t\t// There is no previous match to compare with, wait for\n  \t\t\t\t\t// the next step to decide.\n\n  \t\t\t\t\tmatch_available = 1;\n  \t\t\t\t\tstrstart++;\n  \t\t\t\t\tlookahead--;\n  \t\t\t\t}\n  \t\t\t}\n\n  \t\t\tif (match_available !== 0) {\n  \t\t\t\tbflush = _tr_tally(0, window[strstart - 1] & 0xff);\n  \t\t\t\tmatch_available = 0;\n  \t\t\t}\n  \t\t\tflush_block_only(flush == Z_FINISH);\n\n  \t\t\tif (strm.avail_out === 0) {\n  \t\t\t\tif (flush == Z_FINISH)\n  \t\t\t\t\treturn FinishStarted;\n  \t\t\t\telse\n  \t\t\t\t\treturn NeedMore;\n  \t\t\t}\n\n  \t\t\treturn flush == Z_FINISH ? FinishDone : BlockDone;\n  \t\t}\n\n  \t\tfunction deflateReset(strm) {\n  \t\t\tstrm.total_in = strm.total_out = 0;\n  \t\t\tstrm.msg = null; //\n  \t\t\t\n  \t\t\tthat.pending = 0;\n  \t\t\tthat.pending_out = 0;\n\n  \t\t\tstatus = BUSY_STATE;\n\n  \t\t\tlast_flush = Z_NO_FLUSH;\n\n  \t\t\ttr_init();\n  \t\t\tlm_init();\n  \t\t\treturn Z_OK;\n  \t\t}\n\n  \t\tthat.deflateInit = function(strm, _level, bits, _method, memLevel, _strategy) {\n  \t\t\tif (!_method)\n  \t\t\t\t_method = Z_DEFLATED;\n  \t\t\tif (!memLevel)\n  \t\t\t\tmemLevel = DEF_MEM_LEVEL;\n  \t\t\tif (!_strategy)\n  \t\t\t\t_strategy = Z_DEFAULT_STRATEGY;\n\n  \t\t\t// byte[] my_version=ZLIB_VERSION;\n\n  \t\t\t//\n  \t\t\t// if (!version || version[0] != my_version[0]\n  \t\t\t// || stream_size != sizeof(z_stream)) {\n  \t\t\t// return Z_VERSION_ERROR;\n  \t\t\t// }\n\n  \t\t\tstrm.msg = null;\n\n  \t\t\tif (_level == Z_DEFAULT_COMPRESSION)\n  \t\t\t\t_level = 6;\n\n  \t\t\tif (memLevel < 1 || memLevel > MAX_MEM_LEVEL || _method != Z_DEFLATED || bits < 9 || bits > 15 || _level < 0 || _level > 9 || _strategy < 0\n  \t\t\t\t\t|| _strategy > Z_HUFFMAN_ONLY) {\n  \t\t\t\treturn Z_STREAM_ERROR;\n  \t\t\t}\n\n  \t\t\tstrm.dstate = that;\n\n  \t\t\tw_bits = bits;\n  \t\t\tw_size = 1 << w_bits;\n  \t\t\tw_mask = w_size - 1;\n\n  \t\t\thash_bits = memLevel + 7;\n  \t\t\thash_size = 1 << hash_bits;\n  \t\t\thash_mask = hash_size - 1;\n  \t\t\thash_shift = Math.floor((hash_bits + MIN_MATCH - 1) / MIN_MATCH);\n\n  \t\t\twindow = new Uint8Array(w_size * 2);\n  \t\t\tprev = [];\n  \t\t\thead = [];\n\n  \t\t\tlit_bufsize = 1 << (memLevel + 6); // 16K elements by default\n\n  \t\t\t// We overlay pending_buf and d_buf+l_buf. This works since the average\n  \t\t\t// output size for (length,distance) codes is <= 24 bits.\n  \t\t\tthat.pending_buf = new Uint8Array(lit_bufsize * 4);\n  \t\t\tpending_buf_size = lit_bufsize * 4;\n\n  \t\t\td_buf = Math.floor(lit_bufsize / 2);\n  \t\t\tl_buf = (1 + 2) * lit_bufsize;\n\n  \t\t\tlevel = _level;\n\n  \t\t\tstrategy = _strategy;\n\n  \t\t\treturn deflateReset(strm);\n  \t\t};\n\n  \t\tthat.deflateEnd = function() {\n  \t\t\tif (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) {\n  \t\t\t\treturn Z_STREAM_ERROR;\n  \t\t\t}\n  \t\t\t// Deallocate in reverse order of allocations:\n  \t\t\tthat.pending_buf = null;\n  \t\t\thead = null;\n  \t\t\tprev = null;\n  \t\t\twindow = null;\n  \t\t\t// free\n  \t\t\tthat.dstate = null;\n  \t\t\treturn status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;\n  \t\t};\n\n  \t\tthat.deflateParams = function(strm, _level, _strategy) {\n  \t\t\tvar err = Z_OK;\n\n  \t\t\tif (_level == Z_DEFAULT_COMPRESSION) {\n  \t\t\t\t_level = 6;\n  \t\t\t}\n  \t\t\tif (_level < 0 || _level > 9 || _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) {\n  \t\t\t\treturn Z_STREAM_ERROR;\n  \t\t\t}\n\n  \t\t\tif (config_table[level].func != config_table[_level].func && strm.total_in !== 0) {\n  \t\t\t\t// Flush the last buffer:\n  \t\t\t\terr = strm.deflate(Z_PARTIAL_FLUSH);\n  \t\t\t}\n\n  \t\t\tif (level != _level) {\n  \t\t\t\tlevel = _level;\n  \t\t\t\tmax_lazy_match = config_table[level].max_lazy;\n  \t\t\t\tgood_match = config_table[level].good_length;\n  \t\t\t\tnice_match = config_table[level].nice_length;\n  \t\t\t\tmax_chain_length = config_table[level].max_chain;\n  \t\t\t}\n  \t\t\tstrategy = _strategy;\n  \t\t\treturn err;\n  \t\t};\n\n  \t\tthat.deflateSetDictionary = function(strm, dictionary, dictLength) {\n  \t\t\tvar length = dictLength;\n  \t\t\tvar n, index = 0;\n\n  \t\t\tif (!dictionary || status != INIT_STATE)\n  \t\t\t\treturn Z_STREAM_ERROR;\n\n  \t\t\tif (length < MIN_MATCH)\n  \t\t\t\treturn Z_OK;\n  \t\t\tif (length > w_size - MIN_LOOKAHEAD) {\n  \t\t\t\tlength = w_size - MIN_LOOKAHEAD;\n  \t\t\t\tindex = dictLength - length; // use the tail of the dictionary\n  \t\t\t}\n  \t\t\twindow.set(dictionary.subarray(index, index + length), 0);\n\n  \t\t\tstrstart = length;\n  \t\t\tblock_start = length;\n\n  \t\t\t// Insert all strings in the hash table (except for the last two bytes).\n  \t\t\t// s->lookahead stays null, so s->ins_h will be recomputed at the next\n  \t\t\t// call of fill_window.\n\n  \t\t\tins_h = window[0] & 0xff;\n  \t\t\tins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask;\n\n  \t\t\tfor (n = 0; n <= length - MIN_MATCH; n++) {\n  \t\t\t\tins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;\n  \t\t\t\tprev[n & w_mask] = head[ins_h];\n  \t\t\t\thead[ins_h] = n;\n  \t\t\t}\n  \t\t\treturn Z_OK;\n  \t\t};\n\n  \t\tthat.deflate = function(_strm, flush) {\n  \t\t\tvar i, header, level_flags, old_flush, bstate;\n\n  \t\t\tif (flush > Z_FINISH || flush < 0) {\n  \t\t\t\treturn Z_STREAM_ERROR;\n  \t\t\t}\n\n  \t\t\tif (!_strm.next_out || (!_strm.next_in && _strm.avail_in !== 0) || (status == FINISH_STATE && flush != Z_FINISH)) {\n  \t\t\t\t_strm.msg = z_errmsg[Z_NEED_DICT - (Z_STREAM_ERROR)];\n  \t\t\t\treturn Z_STREAM_ERROR;\n  \t\t\t}\n  \t\t\tif (_strm.avail_out === 0) {\n  \t\t\t\t_strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];\n  \t\t\t\treturn Z_BUF_ERROR;\n  \t\t\t}\n\n  \t\t\tstrm = _strm; // just in case\n  \t\t\told_flush = last_flush;\n  \t\t\tlast_flush = flush;\n\n  \t\t\t// Write the zlib header\n  \t\t\tif (status == INIT_STATE) {\n  \t\t\t\theader = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8;\n  \t\t\t\tlevel_flags = ((level - 1) & 0xff) >> 1;\n\n  \t\t\t\tif (level_flags > 3)\n  \t\t\t\t\tlevel_flags = 3;\n  \t\t\t\theader |= (level_flags << 6);\n  \t\t\t\tif (strstart !== 0)\n  \t\t\t\t\theader |= PRESET_DICT;\n  \t\t\t\theader += 31 - (header % 31);\n\n  \t\t\t\tstatus = BUSY_STATE;\n  \t\t\t\tputShortMSB(header);\n  \t\t\t}\n\n  \t\t\t// Flush as much pending output as possible\n  \t\t\tif (that.pending !== 0) {\n  \t\t\t\tstrm.flush_pending();\n  \t\t\t\tif (strm.avail_out === 0) {\n  \t\t\t\t\t// console.log(\" avail_out==0\");\n  \t\t\t\t\t// Since avail_out is 0, deflate will be called again with\n  \t\t\t\t\t// more output space, but possibly with both pending and\n  \t\t\t\t\t// avail_in equal to zero. There won't be anything to do,\n  \t\t\t\t\t// but this is not an error situation so make sure we\n  \t\t\t\t\t// return OK instead of BUF_ERROR at next call of deflate:\n  \t\t\t\t\tlast_flush = -1;\n  \t\t\t\t\treturn Z_OK;\n  \t\t\t\t}\n\n  \t\t\t\t// Make sure there is something to do and avoid duplicate\n  \t\t\t\t// consecutive\n  \t\t\t\t// flushes. For repeated and useless calls with Z_FINISH, we keep\n  \t\t\t\t// returning Z_STREAM_END instead of Z_BUFF_ERROR.\n  \t\t\t} else if (strm.avail_in === 0 && flush <= old_flush && flush != Z_FINISH) {\n  \t\t\t\tstrm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];\n  \t\t\t\treturn Z_BUF_ERROR;\n  \t\t\t}\n\n  \t\t\t// User must not provide more input after the first FINISH:\n  \t\t\tif (status == FINISH_STATE && strm.avail_in !== 0) {\n  \t\t\t\t_strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];\n  \t\t\t\treturn Z_BUF_ERROR;\n  \t\t\t}\n\n  \t\t\t// Start a new block or continue the current one.\n  \t\t\tif (strm.avail_in !== 0 || lookahead !== 0 || (flush != Z_NO_FLUSH && status != FINISH_STATE)) {\n  \t\t\t\tbstate = -1;\n  \t\t\t\tswitch (config_table[level].func) {\n  \t\t\t\tcase STORED:\n  \t\t\t\t\tbstate = deflate_stored(flush);\n  \t\t\t\t\tbreak;\n  \t\t\t\tcase FAST:\n  \t\t\t\t\tbstate = deflate_fast(flush);\n  \t\t\t\t\tbreak;\n  \t\t\t\tcase SLOW:\n  \t\t\t\t\tbstate = deflate_slow(flush);\n  \t\t\t\t\tbreak;\n  \t\t\t\tdefault:\n  \t\t\t\t}\n\n  \t\t\t\tif (bstate == FinishStarted || bstate == FinishDone) {\n  \t\t\t\t\tstatus = FINISH_STATE;\n  \t\t\t\t}\n  \t\t\t\tif (bstate == NeedMore || bstate == FinishStarted) {\n  \t\t\t\t\tif (strm.avail_out === 0) {\n  \t\t\t\t\t\tlast_flush = -1; // avoid BUF_ERROR next call, see above\n  \t\t\t\t\t}\n  \t\t\t\t\treturn Z_OK;\n  \t\t\t\t\t// If flush != Z_NO_FLUSH && avail_out === 0, the next call\n  \t\t\t\t\t// of deflate should use the same flush parameter to make sure\n  \t\t\t\t\t// that the flush is complete. So we don't have to output an\n  \t\t\t\t\t// empty block here, this will be done at next call. This also\n  \t\t\t\t\t// ensures that for a very small output buffer, we emit at most\n  \t\t\t\t\t// one empty block.\n  \t\t\t\t}\n\n  \t\t\t\tif (bstate == BlockDone) {\n  \t\t\t\t\tif (flush == Z_PARTIAL_FLUSH) {\n  \t\t\t\t\t\t_tr_align();\n  \t\t\t\t\t} else { // FULL_FLUSH or SYNC_FLUSH\n  \t\t\t\t\t\t_tr_stored_block(0, 0, false);\n  \t\t\t\t\t\t// For a full flush, this empty block will be recognized\n  \t\t\t\t\t\t// as a special marker by inflate_sync().\n  \t\t\t\t\t\tif (flush == Z_FULL_FLUSH) {\n  \t\t\t\t\t\t\t// state.head[s.hash_size-1]=0;\n  \t\t\t\t\t\t\tfor (i = 0; i < hash_size/*-1*/; i++)\n  \t\t\t\t\t\t\t\t// forget history\n  \t\t\t\t\t\t\t\thead[i] = 0;\n  \t\t\t\t\t\t}\n  \t\t\t\t\t}\n  \t\t\t\t\tstrm.flush_pending();\n  \t\t\t\t\tif (strm.avail_out === 0) {\n  \t\t\t\t\t\tlast_flush = -1; // avoid BUF_ERROR at next call, see above\n  \t\t\t\t\t\treturn Z_OK;\n  \t\t\t\t\t}\n  \t\t\t\t}\n  \t\t\t}\n\n  \t\t\tif (flush != Z_FINISH)\n  \t\t\t\treturn Z_OK;\n  \t\t\treturn Z_STREAM_END;\n  \t\t};\n  \t}\n\n  \t// ZStream\n\n  \tfunction ZStream() {\n  \t\tvar that = this;\n  \t\tthat.next_in_index = 0;\n  \t\tthat.next_out_index = 0;\n  \t\t// that.next_in; // next input byte\n  \t\tthat.avail_in = 0; // number of bytes available at next_in\n  \t\tthat.total_in = 0; // total nb of input bytes read so far\n  \t\t// that.next_out; // next output byte should be put there\n  \t\tthat.avail_out = 0; // remaining free space at next_out\n  \t\tthat.total_out = 0; // total nb of bytes output so far\n  \t\t// that.msg;\n  \t\t// that.dstate;\n  \t}\n\n  \tZStream.prototype = {\n  \t\tdeflateInit : function(level, bits) {\n  \t\t\tvar that = this;\n  \t\t\tthat.dstate = new Deflate();\n  \t\t\tif (!bits)\n  \t\t\t\tbits = MAX_BITS;\n  \t\t\treturn that.dstate.deflateInit(that, level, bits);\n  \t\t},\n\n  \t\tdeflate : function(flush) {\n  \t\t\tvar that = this;\n  \t\t\tif (!that.dstate) {\n  \t\t\t\treturn Z_STREAM_ERROR;\n  \t\t\t}\n  \t\t\treturn that.dstate.deflate(that, flush);\n  \t\t},\n\n  \t\tdeflateEnd : function() {\n  \t\t\tvar that = this;\n  \t\t\tif (!that.dstate)\n  \t\t\t\treturn Z_STREAM_ERROR;\n  \t\t\tvar ret = that.dstate.deflateEnd();\n  \t\t\tthat.dstate = null;\n  \t\t\treturn ret;\n  \t\t},\n\n  \t\tdeflateParams : function(level, strategy) {\n  \t\t\tvar that = this;\n  \t\t\tif (!that.dstate)\n  \t\t\t\treturn Z_STREAM_ERROR;\n  \t\t\treturn that.dstate.deflateParams(that, level, strategy);\n  \t\t},\n\n  \t\tdeflateSetDictionary : function(dictionary, dictLength) {\n  \t\t\tvar that = this;\n  \t\t\tif (!that.dstate)\n  \t\t\t\treturn Z_STREAM_ERROR;\n  \t\t\treturn that.dstate.deflateSetDictionary(that, dictionary, dictLength);\n  \t\t},\n\n  \t\t// Read a new buffer from the current input stream, update the\n  \t\t// total number of bytes read. All deflate() input goes through\n  \t\t// this function so some applications may wish to modify it to avoid\n  \t\t// allocating a large strm->next_in buffer and copying from it.\n  \t\t// (See also flush_pending()).\n  \t\tread_buf : function(buf, start, size) {\n  \t\t\tvar that = this;\n  \t\t\tvar len = that.avail_in;\n  \t\t\tif (len > size)\n  \t\t\t\tlen = size;\n  \t\t\tif (len === 0)\n  \t\t\t\treturn 0;\n  \t\t\tthat.avail_in -= len;\n  \t\t\tbuf.set(that.next_in.subarray(that.next_in_index, that.next_in_index + len), start);\n  \t\t\tthat.next_in_index += len;\n  \t\t\tthat.total_in += len;\n  \t\t\treturn len;\n  \t\t},\n\n  \t\t// Flush as much pending output as possible. All deflate() output goes\n  \t\t// through this function so some applications may wish to modify it\n  \t\t// to avoid allocating a large strm->next_out buffer and copying into it.\n  \t\t// (See also read_buf()).\n  \t\tflush_pending : function() {\n  \t\t\tvar that = this;\n  \t\t\tvar len = that.dstate.pending;\n\n  \t\t\tif (len > that.avail_out)\n  \t\t\t\tlen = that.avail_out;\n  \t\t\tif (len === 0)\n  \t\t\t\treturn;\n\n  \t\t\t// if (that.dstate.pending_buf.length <= that.dstate.pending_out || that.next_out.length <= that.next_out_index\n  \t\t\t// || that.dstate.pending_buf.length < (that.dstate.pending_out + len) || that.next_out.length < (that.next_out_index +\n  \t\t\t// len)) {\n  \t\t\t// console.log(that.dstate.pending_buf.length + \", \" + that.dstate.pending_out + \", \" + that.next_out.length + \", \" +\n  \t\t\t// that.next_out_index + \", \" + len);\n  \t\t\t// console.log(\"avail_out=\" + that.avail_out);\n  \t\t\t// }\n\n  \t\t\tthat.next_out.set(that.dstate.pending_buf.subarray(that.dstate.pending_out, that.dstate.pending_out + len), that.next_out_index);\n\n  \t\t\tthat.next_out_index += len;\n  \t\t\tthat.dstate.pending_out += len;\n  \t\t\tthat.total_out += len;\n  \t\t\tthat.avail_out -= len;\n  \t\t\tthat.dstate.pending -= len;\n  \t\t\tif (that.dstate.pending === 0) {\n  \t\t\t\tthat.dstate.pending_out = 0;\n  \t\t\t}\n  \t\t}\n  \t};\n\n  \t// Deflater\n\n  \tfunction Deflater(options) {\n  \t\tvar that = this;\n  \t\tvar z = new ZStream();\n  \t\tvar bufsize = 512;\n  \t\tvar flush = Z_NO_FLUSH;\n  \t\tvar buf = new Uint8Array(bufsize);\n  \t\tvar level = options ? options.level : Z_DEFAULT_COMPRESSION;\n  \t\tif (typeof level == \"undefined\")\n  \t\t\tlevel = Z_DEFAULT_COMPRESSION;\n  \t\tz.deflateInit(level);\n  \t\tz.next_out = buf;\n\n  \t\tthat.append = function(data, onprogress) {\n  \t\t\tvar err, buffers = [], lastIndex = 0, bufferIndex = 0, bufferSize = 0, array;\n  \t\t\tif (!data.length)\n  \t\t\t\treturn;\n  \t\t\tz.next_in_index = 0;\n  \t\t\tz.next_in = data;\n  \t\t\tz.avail_in = data.length;\n  \t\t\tdo {\n  \t\t\t\tz.next_out_index = 0;\n  \t\t\t\tz.avail_out = bufsize;\n  \t\t\t\terr = z.deflate(flush);\n  \t\t\t\tif (err != Z_OK)\n  \t\t\t\t\tthrow new Error(\"deflating: \" + z.msg);\n  \t\t\t\tif (z.next_out_index)\n  \t\t\t\t\tif (z.next_out_index == bufsize)\n  \t\t\t\t\t\tbuffers.push(new Uint8Array(buf));\n  \t\t\t\t\telse\n  \t\t\t\t\t\tbuffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));\n  \t\t\t\tbufferSize += z.next_out_index;\n  \t\t\t\tif (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) {\n  \t\t\t\t\tonprogress(z.next_in_index);\n  \t\t\t\t\tlastIndex = z.next_in_index;\n  \t\t\t\t}\n  \t\t\t} while (z.avail_in > 0 || z.avail_out === 0);\n  \t\t\tarray = new Uint8Array(bufferSize);\n  \t\t\tbuffers.forEach(function(chunk) {\n  \t\t\t\tarray.set(chunk, bufferIndex);\n  \t\t\t\tbufferIndex += chunk.length;\n  \t\t\t});\n  \t\t\treturn array;\n  \t\t};\n  \t\tthat.flush = function() {\n  \t\t\tvar err, buffers = [], bufferIndex = 0, bufferSize = 0, array;\n  \t\t\tdo {\n  \t\t\t\tz.next_out_index = 0;\n  \t\t\t\tz.avail_out = bufsize;\n  \t\t\t\terr = z.deflate(Z_FINISH);\n  \t\t\t\tif (err != Z_STREAM_END && err != Z_OK)\n  \t\t\t\t\tthrow new Error(\"deflating: \" + z.msg);\n  \t\t\t\tif (bufsize - z.avail_out > 0)\n  \t\t\t\t\tbuffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));\n  \t\t\t\tbufferSize += z.next_out_index;\n  \t\t\t} while (z.avail_in > 0 || z.avail_out === 0);\n  \t\t\tz.deflateEnd();\n  \t\t\tarray = new Uint8Array(bufferSize);\n  \t\t\tbuffers.forEach(function(chunk) {\n  \t\t\t\tarray.set(chunk, bufferIndex);\n  \t\t\t\tbufferIndex += chunk.length;\n  \t\t\t});\n  \t\t\treturn array;\n  \t\t};\n  \t}\n\n  \t// 'zip' may not be defined in z-worker and some tests\n  \tvar env = global.zip || global;\n  \tenv.Deflater = env._jzlib_Deflater = Deflater;\n  }(typeof self !== \"undefined\" && self || typeof window !== \"undefined\" && window || typeof global !== \"undefined\" && global ||  Function('return typeof this === \"object\" && this.content')() || Function('return this')()));\n  // `self` is undefined in Firefox for Android content script context\n  // while `this` is nsIContentFrameMessageManager\n  // with an attribute `content` that corresponds to the window\n\n  /**\n   * A class to parse color values\n   * @author Stoyan Stefanov <sstoo@gmail.com>\n   * @link   http://www.phpied.com/rgb-color-parser-in-javascript/\n   * @license Use it if you like it\n   */\n   \n  (function ( global ) {\n   \n  \tfunction RGBColor(color_string)\n  \t{\n  \t\tthis.ok = false;\n\n  \t\t// strip any leading #\n  \t\tif (color_string.charAt(0) == '#') { // remove # if any\n  \t\t\tcolor_string = color_string.substr(1,6);\n  \t\t}\n\n  \t\tcolor_string = color_string.replace(/ /g,'');\n  \t\tcolor_string = color_string.toLowerCase();\n\n  \t\tvar channels;\n\n  \t\t// before getting into regexps, try simple matches\n  \t\t// and overwrite the input\n  \t\tvar simple_colors = {\n  \t\t\taliceblue: 'f0f8ff',\n  \t\t\tantiquewhite: 'faebd7',\n  \t\t\taqua: '00ffff',\n  \t\t\taquamarine: '7fffd4',\n  \t\t\tazure: 'f0ffff',\n  \t\t\tbeige: 'f5f5dc',\n  \t\t\tbisque: 'ffe4c4',\n  \t\t\tblack: '000000',\n  \t\t\tblanchedalmond: 'ffebcd',\n  \t\t\tblue: '0000ff',\n  \t\t\tblueviolet: '8a2be2',\n  \t\t\tbrown: 'a52a2a',\n  \t\t\tburlywood: 'deb887',\n  \t\t\tcadetblue: '5f9ea0',\n  \t\t\tchartreuse: '7fff00',\n  \t\t\tchocolate: 'd2691e',\n  \t\t\tcoral: 'ff7f50',\n  \t\t\tcornflowerblue: '6495ed',\n  \t\t\tcornsilk: 'fff8dc',\n  \t\t\tcrimson: 'dc143c',\n  \t\t\tcyan: '00ffff',\n  \t\t\tdarkblue: '00008b',\n  \t\t\tdarkcyan: '008b8b',\n  \t\t\tdarkgoldenrod: 'b8860b',\n  \t\t\tdarkgray: 'a9a9a9',\n  \t\t\tdarkgreen: '006400',\n  \t\t\tdarkkhaki: 'bdb76b',\n  \t\t\tdarkmagenta: '8b008b',\n  \t\t\tdarkolivegreen: '556b2f',\n  \t\t\tdarkorange: 'ff8c00',\n  \t\t\tdarkorchid: '9932cc',\n  \t\t\tdarkred: '8b0000',\n  \t\t\tdarksalmon: 'e9967a',\n  \t\t\tdarkseagreen: '8fbc8f',\n  \t\t\tdarkslateblue: '483d8b',\n  \t\t\tdarkslategray: '2f4f4f',\n  \t\t\tdarkturquoise: '00ced1',\n  \t\t\tdarkviolet: '9400d3',\n  \t\t\tdeeppink: 'ff1493',\n  \t\t\tdeepskyblue: '00bfff',\n  \t\t\tdimgray: '696969',\n  \t\t\tdodgerblue: '1e90ff',\n  \t\t\tfeldspar: 'd19275',\n  \t\t\tfirebrick: 'b22222',\n  \t\t\tfloralwhite: 'fffaf0',\n  \t\t\tforestgreen: '228b22',\n  \t\t\tfuchsia: 'ff00ff',\n  \t\t\tgainsboro: 'dcdcdc',\n  \t\t\tghostwhite: 'f8f8ff',\n  \t\t\tgold: 'ffd700',\n  \t\t\tgoldenrod: 'daa520',\n  \t\t\tgray: '808080',\n  \t\t\tgreen: '008000',\n  \t\t\tgreenyellow: 'adff2f',\n  \t\t\thoneydew: 'f0fff0',\n  \t\t\thotpink: 'ff69b4',\n  \t\t\tindianred : 'cd5c5c',\n  \t\t\tindigo : '4b0082',\n  \t\t\tivory: 'fffff0',\n  \t\t\tkhaki: 'f0e68c',\n  \t\t\tlavender: 'e6e6fa',\n  \t\t\tlavenderblush: 'fff0f5',\n  \t\t\tlawngreen: '7cfc00',\n  \t\t\tlemonchiffon: 'fffacd',\n  \t\t\tlightblue: 'add8e6',\n  \t\t\tlightcoral: 'f08080',\n  \t\t\tlightcyan: 'e0ffff',\n  \t\t\tlightgoldenrodyellow: 'fafad2',\n  \t\t\tlightgrey: 'd3d3d3',\n  \t\t\tlightgreen: '90ee90',\n  \t\t\tlightpink: 'ffb6c1',\n  \t\t\tlightsalmon: 'ffa07a',\n  \t\t\tlightseagreen: '20b2aa',\n  \t\t\tlightskyblue: '87cefa',\n  \t\t\tlightslateblue: '8470ff',\n  \t\t\tlightslategray: '778899',\n  \t\t\tlightsteelblue: 'b0c4de',\n  \t\t\tlightyellow: 'ffffe0',\n  \t\t\tlime: '00ff00',\n  \t\t\tlimegreen: '32cd32',\n  \t\t\tlinen: 'faf0e6',\n  \t\t\tmagenta: 'ff00ff',\n  \t\t\tmaroon: '800000',\n  \t\t\tmediumaquamarine: '66cdaa',\n  \t\t\tmediumblue: '0000cd',\n  \t\t\tmediumorchid: 'ba55d3',\n  \t\t\tmediumpurple: '9370d8',\n  \t\t\tmediumseagreen: '3cb371',\n  \t\t\tmediumslateblue: '7b68ee',\n  \t\t\tmediumspringgreen: '00fa9a',\n  \t\t\tmediumturquoise: '48d1cc',\n  \t\t\tmediumvioletred: 'c71585',\n  \t\t\tmidnightblue: '191970',\n  \t\t\tmintcream: 'f5fffa',\n  \t\t\tmistyrose: 'ffe4e1',\n  \t\t\tmoccasin: 'ffe4b5',\n  \t\t\tnavajowhite: 'ffdead',\n  \t\t\tnavy: '000080',\n  \t\t\toldlace: 'fdf5e6',\n  \t\t\tolive: '808000',\n  \t\t\tolivedrab: '6b8e23',\n  \t\t\torange: 'ffa500',\n  \t\t\torangered: 'ff4500',\n  \t\t\torchid: 'da70d6',\n  \t\t\tpalegoldenrod: 'eee8aa',\n  \t\t\tpalegreen: '98fb98',\n  \t\t\tpaleturquoise: 'afeeee',\n  \t\t\tpalevioletred: 'd87093',\n  \t\t\tpapayawhip: 'ffefd5',\n  \t\t\tpeachpuff: 'ffdab9',\n  \t\t\tperu: 'cd853f',\n  \t\t\tpink: 'ffc0cb',\n  \t\t\tplum: 'dda0dd',\n  \t\t\tpowderblue: 'b0e0e6',\n  \t\t\tpurple: '800080',\n  \t\t\tred: 'ff0000',\n  \t\t\trosybrown: 'bc8f8f',\n  \t\t\troyalblue: '4169e1',\n  \t\t\tsaddlebrown: '8b4513',\n  \t\t\tsalmon: 'fa8072',\n  \t\t\tsandybrown: 'f4a460',\n  \t\t\tseagreen: '2e8b57',\n  \t\t\tseashell: 'fff5ee',\n  \t\t\tsienna: 'a0522d',\n  \t\t\tsilver: 'c0c0c0',\n  \t\t\tskyblue: '87ceeb',\n  \t\t\tslateblue: '6a5acd',\n  \t\t\tslategray: '708090',\n  \t\t\tsnow: 'fffafa',\n  \t\t\tspringgreen: '00ff7f',\n  \t\t\tsteelblue: '4682b4',\n  \t\t\ttan: 'd2b48c',\n  \t\t\tteal: '008080',\n  \t\t\tthistle: 'd8bfd8',\n  \t\t\ttomato: 'ff6347',\n  \t\t\tturquoise: '40e0d0',\n  \t\t\tviolet: 'ee82ee',\n  \t\t\tvioletred: 'd02090',\n  \t\t\twheat: 'f5deb3',\n  \t\t\twhite: 'ffffff',\n  \t\t\twhitesmoke: 'f5f5f5',\n  \t\t\tyellow: 'ffff00',\n  \t\t\tyellowgreen: '9acd32'\n  \t\t};\n  \t\tfor (var key in simple_colors) {\n  \t\t\tif (color_string == key) {\n  \t\t\t\tcolor_string = simple_colors[key];\n  \t\t\t}\n  \t\t}\n  \t\t// emd of simple type-in colors\n\n  \t\t// array of color definition objects\n  \t\tvar color_defs = [\n  \t\t\t{\n  \t\t\t\tre: /^rgb\\((\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})\\)$/,\n  \t\t\t\texample: ['rgb(123, 234, 45)', 'rgb(255,234,245)'],\n  \t\t\t\tprocess: function (bits){\n  \t\t\t\t\treturn [\n  \t\t\t\t\t\tparseInt(bits[1]),\n  \t\t\t\t\t\tparseInt(bits[2]),\n  \t\t\t\t\t\tparseInt(bits[3])\n  \t\t\t\t\t];\n  \t\t\t\t}\n  \t\t\t},\n  \t\t\t{\n  \t\t\t\tre: /^(\\w{2})(\\w{2})(\\w{2})$/,\n  \t\t\t\texample: ['#00ff00', '336699'],\n  \t\t\t\tprocess: function (bits){\n  \t\t\t\t\treturn [\n  \t\t\t\t\t\tparseInt(bits[1], 16),\n  \t\t\t\t\t\tparseInt(bits[2], 16),\n  \t\t\t\t\t\tparseInt(bits[3], 16)\n  \t\t\t\t\t];\n  \t\t\t\t}\n  \t\t\t},\n  \t\t\t{\n  \t\t\t\tre: /^(\\w{1})(\\w{1})(\\w{1})$/,\n  \t\t\t\texample: ['#fb0', 'f0f'],\n  \t\t\t\tprocess: function (bits){\n  \t\t\t\t\treturn [\n  \t\t\t\t\t\tparseInt(bits[1] + bits[1], 16),\n  \t\t\t\t\t\tparseInt(bits[2] + bits[2], 16),\n  \t\t\t\t\t\tparseInt(bits[3] + bits[3], 16)\n  \t\t\t\t\t];\n  \t\t\t\t}\n  \t\t\t}\n  \t\t];\n\n  \t\t// search through the definitions to find a match\n  \t\tfor (var i = 0; i < color_defs.length; i++) {\n  \t\t\tvar re = color_defs[i].re;\n  \t\t\tvar processor = color_defs[i].process;\n  \t\t\tvar bits = re.exec(color_string);\n  \t\t\tif (bits) {\n  \t\t\t\tchannels = processor(bits);\n  \t\t\t\tthis.r = channels[0];\n  \t\t\t\tthis.g = channels[1];\n  \t\t\t\tthis.b = channels[2];\n  \t\t\t\tthis.ok = true;\n  \t\t\t}\n\n  \t\t}\n\n  \t\t// validate/cleanup values\n  \t\tthis.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);\n  \t\tthis.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g);\n  \t\tthis.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b);\n\n  \t\t// some getters\n  \t\tthis.toRGB = function () {\n  \t\t\treturn 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')';\n  \t\t};\n  \t\tthis.toHex = function () {\n  \t\t\tvar r = this.r.toString(16);\n  \t\t\tvar g = this.g.toString(16);\n  \t\t\tvar b = this.b.toString(16);\n  \t\t\tif (r.length == 1) r = '0' + r;\n  \t\t\tif (g.length == 1) g = '0' + g;\n  \t\t\tif (b.length == 1) b = '0' + b;\n  \t\t\treturn '#' + r + g + b;\n  \t\t};\n\n  \t\t// help\n  \t\tthis.getHelpXML = function () {\n\n  \t\t\tvar examples = new Array();\n  \t\t\t// add regexps\n  \t\t\tfor (var i = 0; i < color_defs.length; i++) {\n  \t\t\t\tvar example = color_defs[i].example;\n  \t\t\t\tfor (var j = 0; j < example.length; j++) {\n  \t\t\t\t\texamples[examples.length] = example[j];\n  \t\t\t\t}\n  \t\t\t}\n  \t\t\t// add type-in colors\n  \t\t\tfor (var sc in simple_colors) {\n  \t\t\t\texamples[examples.length] = sc;\n  \t\t\t}\n\n  \t\t\tvar xml = document.createElement('ul');\n  \t\t\txml.setAttribute('id', 'rgbcolor-examples');\n  \t\t\tfor (var i = 0; i < examples.length; i++) {\n  \t\t\t\ttry {\n  \t\t\t\t\tvar list_item = document.createElement('li');\n  \t\t\t\t\tvar list_color = new RGBColor(examples[i]);\n  \t\t\t\t\tvar example_div = document.createElement('div');\n  \t\t\t\t\texample_div.style.cssText =\n  \t\t\t\t\t\t\t'margin: 3px; '\n  \t\t\t\t\t\t\t+ 'border: 1px solid black; '\n  \t\t\t\t\t\t\t+ 'background:' + list_color.toHex() + '; '\n  \t\t\t\t\t\t\t+ 'color:' + list_color.toHex()\n  \t\t\t\t\t;\n  \t\t\t\t\texample_div.appendChild(document.createTextNode('test'));\n  \t\t\t\t\tvar list_item_value = document.createTextNode(\n  \t\t\t\t\t\t' ' + examples[i] + ' -> ' + list_color.toRGB() + ' -> ' + list_color.toHex()\n  \t\t\t\t\t);\n  \t\t\t\t\tlist_item.appendChild(example_div);\n  \t\t\t\t\tlist_item.appendChild(list_item_value);\n  \t\t\t\t\txml.appendChild(list_item);\n\n  \t\t\t\t} catch(e){}\n  \t\t\t}\n  \t\t\treturn xml;\n\n  \t\t};\n\n  \t}\n\n      // export as AMD...\n      if ( typeof define !== 'undefined' && define.amd ) {\n          define('RGBColor', function () { return RGBColor; });\n      }\n\n      // ...or as browserify\n      else if (typeof module !== 'undefined' && module.exports ) {\n          module.exports = RGBColor;\n      }\n\n      global.RGBColor = RGBColor;\n  \t\n  }(typeof self !== \"undefined\" && self || typeof window !== \"undefined\" && window || typeof global !== \"undefined\" && global ||  Function('return typeof this === \"object\" && this.content')() || Function('return this')()));\n  // `self` is undefined in Firefox for Android content script context\n  // while `this` is nsIContentFrameMessageManager\n  // with an attribute `content` that corresponds to the window\n\n  /*\n    html2canvas 0.5.0-beta3 <http://html2canvas.hertzen.com>\n    Copyright (c) 2016 Niklas von Hertzen\n\n    Released under  License\n  */\n\n  !function(e){if(\"object\"==typeof exports&&\"undefined\"!=typeof module)module.exports=e();else if(\"function\"==typeof define&&define.amd)define(\"html2canvas\",[],e);else{var f;\"undefined\"!=typeof window?f=window:\"undefined\"!=typeof global?f=global:\"undefined\"!=typeof self&&(f=self),f.html2canvas=e();}}(function(){var define;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r);}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){\n  (function (global){\n  (function(root) {\n\n  \t/** Detect free variables */\n  \tvar freeExports = typeof exports == 'object' && exports;\n  \tvar freeModule = typeof module == 'object' && module &&\n  \t\tmodule.exports == freeExports && module;\n  \tvar freeGlobal = typeof global == 'object' && global;\n  \tif (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {\n  \t\troot = freeGlobal;\n  \t}\n\n  \t/**\n  \t * The `punycode` object.\n  \t * @name punycode\n  \t * @type Object\n  \t */\n  \tvar punycode,\n\n  \t/** Highest positive signed 32-bit float value */\n  \tmaxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1\n\n  \t/** Bootstring parameters */\n  \tbase = 36,\n  \ttMin = 1,\n  \ttMax = 26,\n  \tskew = 38,\n  \tdamp = 700,\n  \tinitialBias = 72,\n  \tinitialN = 128, // 0x80\n  \tdelimiter = '-', // '\\x2D'\n\n  \t/** Regular expressions */\n  \tregexPunycode = /^xn--/,\n  \tregexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars\n  \tregexSeparators = /\\x2E|\\u3002|\\uFF0E|\\uFF61/g, // RFC 3490 separators\n\n  \t/** Error messages */\n  \terrors = {\n  \t\t'overflow': 'Overflow: input needs wider integers to process',\n  \t\t'not-basic': 'Illegal input >= 0x80 (not a basic code point)',\n  \t\t'invalid-input': 'Invalid input'\n  \t},\n\n  \t/** Convenience shortcuts */\n  \tbaseMinusTMin = base - tMin,\n  \tfloor = Math.floor,\n  \tstringFromCharCode = String.fromCharCode,\n\n  \t/** Temporary variable */\n  \tkey;\n\n  \t/*--------------------------------------------------------------------------*/\n\n  \t/**\n  \t * A generic error utility function.\n  \t * @private\n  \t * @param {String} type The error type.\n  \t * @returns {Error} Throws a `RangeError` with the applicable error message.\n  \t */\n  \tfunction error(type) {\n  \t\tthrow RangeError(errors[type]);\n  \t}\n\n  \t/**\n  \t * A generic `Array#map` utility function.\n  \t * @private\n  \t * @param {Array} array The array to iterate over.\n  \t * @param {Function} callback The function that gets called for every array\n  \t * item.\n  \t * @returns {Array} A new array of values returned by the callback function.\n  \t */\n  \tfunction map(array, fn) {\n  \t\tvar length = array.length;\n  \t\twhile (length--) {\n  \t\t\tarray[length] = fn(array[length]);\n  \t\t}\n  \t\treturn array;\n  \t}\n\n  \t/**\n  \t * A simple `Array#map`-like wrapper to work with domain name strings.\n  \t * @private\n  \t * @param {String} domain The domain name.\n  \t * @param {Function} callback The function that gets called for every\n  \t * character.\n  \t * @returns {Array} A new string of characters returned by the callback\n  \t * function.\n  \t */\n  \tfunction mapDomain(string, fn) {\n  \t\treturn map(string.split(regexSeparators), fn).join('.');\n  \t}\n\n  \t/**\n  \t * Creates an array containing the numeric code points of each Unicode\n  \t * character in the string. While JavaScript uses UCS-2 internally,\n  \t * this function will convert a pair of surrogate halves (each of which\n  \t * UCS-2 exposes as separate characters) into a single code point,\n  \t * matching UTF-16.\n  \t * @see `punycode.ucs2.encode`\n  \t * @see <http://mathiasbynens.be/notes/javascript-encoding>\n  \t * @memberOf punycode.ucs2\n  \t * @name decode\n  \t * @param {String} string The Unicode input string (UCS-2).\n  \t * @returns {Array} The new array of code points.\n  \t */\n  \tfunction ucs2decode(string) {\n  \t\tvar output = [],\n  \t\t    counter = 0,\n  \t\t    length = string.length,\n  \t\t    value,\n  \t\t    extra;\n  \t\twhile (counter < length) {\n  \t\t\tvalue = string.charCodeAt(counter++);\n  \t\t\tif (value >= 0xD800 && value <= 0xDBFF && counter < length) {\n  \t\t\t\t// high surrogate, and there is a next character\n  \t\t\t\textra = string.charCodeAt(counter++);\n  \t\t\t\tif ((extra & 0xFC00) == 0xDC00) { // low surrogate\n  \t\t\t\t\toutput.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);\n  \t\t\t\t} else {\n  \t\t\t\t\t// unmatched surrogate; only append this code unit, in case the next\n  \t\t\t\t\t// code unit is the high surrogate of a surrogate pair\n  \t\t\t\t\toutput.push(value);\n  \t\t\t\t\tcounter--;\n  \t\t\t\t}\n  \t\t\t} else {\n  \t\t\t\toutput.push(value);\n  \t\t\t}\n  \t\t}\n  \t\treturn output;\n  \t}\n\n  \t/**\n  \t * Creates a string based on an array of numeric code points.\n  \t * @see `punycode.ucs2.decode`\n  \t * @memberOf punycode.ucs2\n  \t * @name encode\n  \t * @param {Array} codePoints The array of numeric code points.\n  \t * @returns {String} The new Unicode string (UCS-2).\n  \t */\n  \tfunction ucs2encode(array) {\n  \t\treturn map(array, function(value) {\n  \t\t\tvar output = '';\n  \t\t\tif (value > 0xFFFF) {\n  \t\t\t\tvalue -= 0x10000;\n  \t\t\t\toutput += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);\n  \t\t\t\tvalue = 0xDC00 | value & 0x3FF;\n  \t\t\t}\n  \t\t\toutput += stringFromCharCode(value);\n  \t\t\treturn output;\n  \t\t}).join('');\n  \t}\n\n  \t/**\n  \t * Converts a basic code point into a digit/integer.\n  \t * @see `digitToBasic()`\n  \t * @private\n  \t * @param {Number} codePoint The basic numeric code point value.\n  \t * @returns {Number} The numeric value of a basic code point (for use in\n  \t * representing integers) in the range `0` to `base - 1`, or `base` if\n  \t * the code point does not represent a value.\n  \t */\n  \tfunction basicToDigit(codePoint) {\n  \t\tif (codePoint - 48 < 10) {\n  \t\t\treturn codePoint - 22;\n  \t\t}\n  \t\tif (codePoint - 65 < 26) {\n  \t\t\treturn codePoint - 65;\n  \t\t}\n  \t\tif (codePoint - 97 < 26) {\n  \t\t\treturn codePoint - 97;\n  \t\t}\n  \t\treturn base;\n  \t}\n\n  \t/**\n  \t * Converts a digit/integer into a basic code point.\n  \t * @see `basicToDigit()`\n  \t * @private\n  \t * @param {Number} digit The numeric value of a basic code point.\n  \t * @returns {Number} The basic code point whose value (when used for\n  \t * representing integers) is `digit`, which needs to be in the range\n  \t * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is\n  \t * used; else, the lowercase form is used. The behavior is undefined\n  \t * if `flag` is non-zero and `digit` has no uppercase form.\n  \t */\n  \tfunction digitToBasic(digit, flag) {\n  \t\t//  0..25 map to ASCII a..z or A..Z\n  \t\t// 26..35 map to ASCII 0..9\n  \t\treturn digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);\n  \t}\n\n  \t/**\n  \t * Bias adaptation function as per section 3.4 of RFC 3492.\n  \t * http://tools.ietf.org/html/rfc3492#section-3.4\n  \t * @private\n  \t */\n  \tfunction adapt(delta, numPoints, firstTime) {\n  \t\tvar k = 0;\n  \t\tdelta = firstTime ? floor(delta / damp) : delta >> 1;\n  \t\tdelta += floor(delta / numPoints);\n  \t\tfor (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {\n  \t\t\tdelta = floor(delta / baseMinusTMin);\n  \t\t}\n  \t\treturn floor(k + (baseMinusTMin + 1) * delta / (delta + skew));\n  \t}\n\n  \t/**\n  \t * Converts a Punycode string of ASCII-only symbols to a string of Unicode\n  \t * symbols.\n  \t * @memberOf punycode\n  \t * @param {String} input The Punycode string of ASCII-only symbols.\n  \t * @returns {String} The resulting string of Unicode symbols.\n  \t */\n  \tfunction decode(input) {\n  \t\t// Don't use UCS-2\n  \t\tvar output = [],\n  \t\t    inputLength = input.length,\n  \t\t    out,\n  \t\t    i = 0,\n  \t\t    n = initialN,\n  \t\t    bias = initialBias,\n  \t\t    basic,\n  \t\t    j,\n  \t\t    index,\n  \t\t    oldi,\n  \t\t    w,\n  \t\t    k,\n  \t\t    digit,\n  \t\t    t,\n  \t\t    /** Cached calculation results */\n  \t\t    baseMinusT;\n\n  \t\t// Handle the basic code points: let `basic` be the number of input code\n  \t\t// points before the last delimiter, or `0` if there is none, then copy\n  \t\t// the first basic code points to the output.\n\n  \t\tbasic = input.lastIndexOf(delimiter);\n  \t\tif (basic < 0) {\n  \t\t\tbasic = 0;\n  \t\t}\n\n  \t\tfor (j = 0; j < basic; ++j) {\n  \t\t\t// if it's not a basic code point\n  \t\t\tif (input.charCodeAt(j) >= 0x80) {\n  \t\t\t\terror('not-basic');\n  \t\t\t}\n  \t\t\toutput.push(input.charCodeAt(j));\n  \t\t}\n\n  \t\t// Main decoding loop: start just after the last delimiter if any basic code\n  \t\t// points were copied; start at the beginning otherwise.\n\n  \t\tfor (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {\n\n  \t\t\t// `index` is the index of the next character to be consumed.\n  \t\t\t// Decode a generalized variable-length integer into `delta`,\n  \t\t\t// which gets added to `i`. The overflow checking is easier\n  \t\t\t// if we increase `i` as we go, then subtract off its starting\n  \t\t\t// value at the end to obtain `delta`.\n  \t\t\tfor (oldi = i, w = 1, k = base; /* no condition */; k += base) {\n\n  \t\t\t\tif (index >= inputLength) {\n  \t\t\t\t\terror('invalid-input');\n  \t\t\t\t}\n\n  \t\t\t\tdigit = basicToDigit(input.charCodeAt(index++));\n\n  \t\t\t\tif (digit >= base || digit > floor((maxInt - i) / w)) {\n  \t\t\t\t\terror('overflow');\n  \t\t\t\t}\n\n  \t\t\t\ti += digit * w;\n  \t\t\t\tt = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n\n  \t\t\t\tif (digit < t) {\n  \t\t\t\t\tbreak;\n  \t\t\t\t}\n\n  \t\t\t\tbaseMinusT = base - t;\n  \t\t\t\tif (w > floor(maxInt / baseMinusT)) {\n  \t\t\t\t\terror('overflow');\n  \t\t\t\t}\n\n  \t\t\t\tw *= baseMinusT;\n\n  \t\t\t}\n\n  \t\t\tout = output.length + 1;\n  \t\t\tbias = adapt(i - oldi, out, oldi == 0);\n\n  \t\t\t// `i` was supposed to wrap around from `out` to `0`,\n  \t\t\t// incrementing `n` each time, so we'll fix that now:\n  \t\t\tif (floor(i / out) > maxInt - n) {\n  \t\t\t\terror('overflow');\n  \t\t\t}\n\n  \t\t\tn += floor(i / out);\n  \t\t\ti %= out;\n\n  \t\t\t// Insert `n` at position `i` of the output\n  \t\t\toutput.splice(i++, 0, n);\n\n  \t\t}\n\n  \t\treturn ucs2encode(output);\n  \t}\n\n  \t/**\n  \t * Converts a string of Unicode symbols to a Punycode string of ASCII-only\n  \t * symbols.\n  \t * @memberOf punycode\n  \t * @param {String} input The string of Unicode symbols.\n  \t * @returns {String} The resulting Punycode string of ASCII-only symbols.\n  \t */\n  \tfunction encode(input) {\n  \t\tvar n,\n  \t\t    delta,\n  \t\t    handledCPCount,\n  \t\t    basicLength,\n  \t\t    bias,\n  \t\t    j,\n  \t\t    m,\n  \t\t    q,\n  \t\t    k,\n  \t\t    t,\n  \t\t    currentValue,\n  \t\t    output = [],\n  \t\t    /** `inputLength` will hold the number of code points in `input`. */\n  \t\t    inputLength,\n  \t\t    /** Cached calculation results */\n  \t\t    handledCPCountPlusOne,\n  \t\t    baseMinusT,\n  \t\t    qMinusT;\n\n  \t\t// Convert the input in UCS-2 to Unicode\n  \t\tinput = ucs2decode(input);\n\n  \t\t// Cache the length\n  \t\tinputLength = input.length;\n\n  \t\t// Initialize the state\n  \t\tn = initialN;\n  \t\tdelta = 0;\n  \t\tbias = initialBias;\n\n  \t\t// Handle the basic code points\n  \t\tfor (j = 0; j < inputLength; ++j) {\n  \t\t\tcurrentValue = input[j];\n  \t\t\tif (currentValue < 0x80) {\n  \t\t\t\toutput.push(stringFromCharCode(currentValue));\n  \t\t\t}\n  \t\t}\n\n  \t\thandledCPCount = basicLength = output.length;\n\n  \t\t// `handledCPCount` is the number of code points that have been handled;\n  \t\t// `basicLength` is the number of basic code points.\n\n  \t\t// Finish the basic string - if it is not empty - with a delimiter\n  \t\tif (basicLength) {\n  \t\t\toutput.push(delimiter);\n  \t\t}\n\n  \t\t// Main encoding loop:\n  \t\twhile (handledCPCount < inputLength) {\n\n  \t\t\t// All non-basic code points < n have been handled already. Find the next\n  \t\t\t// larger one:\n  \t\t\tfor (m = maxInt, j = 0; j < inputLength; ++j) {\n  \t\t\t\tcurrentValue = input[j];\n  \t\t\t\tif (currentValue >= n && currentValue < m) {\n  \t\t\t\t\tm = currentValue;\n  \t\t\t\t}\n  \t\t\t}\n\n  \t\t\t// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,\n  \t\t\t// but guard against overflow\n  \t\t\thandledCPCountPlusOne = handledCPCount + 1;\n  \t\t\tif (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {\n  \t\t\t\terror('overflow');\n  \t\t\t}\n\n  \t\t\tdelta += (m - n) * handledCPCountPlusOne;\n  \t\t\tn = m;\n\n  \t\t\tfor (j = 0; j < inputLength; ++j) {\n  \t\t\t\tcurrentValue = input[j];\n\n  \t\t\t\tif (currentValue < n && ++delta > maxInt) {\n  \t\t\t\t\terror('overflow');\n  \t\t\t\t}\n\n  \t\t\t\tif (currentValue == n) {\n  \t\t\t\t\t// Represent delta as a generalized variable-length integer\n  \t\t\t\t\tfor (q = delta, k = base; /* no condition */; k += base) {\n  \t\t\t\t\t\tt = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);\n  \t\t\t\t\t\tif (q < t) {\n  \t\t\t\t\t\t\tbreak;\n  \t\t\t\t\t\t}\n  \t\t\t\t\t\tqMinusT = q - t;\n  \t\t\t\t\t\tbaseMinusT = base - t;\n  \t\t\t\t\t\toutput.push(\n  \t\t\t\t\t\t\tstringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))\n  \t\t\t\t\t\t);\n  \t\t\t\t\t\tq = floor(qMinusT / baseMinusT);\n  \t\t\t\t\t}\n\n  \t\t\t\t\toutput.push(stringFromCharCode(digitToBasic(q, 0)));\n  \t\t\t\t\tbias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);\n  \t\t\t\t\tdelta = 0;\n  \t\t\t\t\t++handledCPCount;\n  \t\t\t\t}\n  \t\t\t}\n\n  \t\t\t++delta;\n  \t\t\t++n;\n\n  \t\t}\n  \t\treturn output.join('');\n  \t}\n\n  \t/**\n  \t * Converts a Punycode string representing a domain name to Unicode. Only the\n  \t * Punycoded parts of the domain name will be converted, i.e. it doesn't\n  \t * matter if you call it on a string that has already been converted to\n  \t * Unicode.\n  \t * @memberOf punycode\n  \t * @param {String} domain The Punycode domain name to convert to Unicode.\n  \t * @returns {String} The Unicode representation of the given Punycode\n  \t * string.\n  \t */\n  \tfunction toUnicode(domain) {\n  \t\treturn mapDomain(domain, function(string) {\n  \t\t\treturn regexPunycode.test(string)\n  \t\t\t\t? decode(string.slice(4).toLowerCase())\n  \t\t\t\t: string;\n  \t\t});\n  \t}\n\n  \t/**\n  \t * Converts a Unicode string representing a domain name to Punycode. Only the\n  \t * non-ASCII parts of the domain name will be converted, i.e. it doesn't\n  \t * matter if you call it with a domain that's already in ASCII.\n  \t * @memberOf punycode\n  \t * @param {String} domain The domain name to convert, as a Unicode string.\n  \t * @returns {String} The Punycode representation of the given domain name.\n  \t */\n  \tfunction toASCII(domain) {\n  \t\treturn mapDomain(domain, function(string) {\n  \t\t\treturn regexNonASCII.test(string)\n  \t\t\t\t? 'xn--' + encode(string)\n  \t\t\t\t: string;\n  \t\t});\n  \t}\n\n  \t/*--------------------------------------------------------------------------*/\n\n  \t/** Define the public API */\n  \tpunycode = {\n  \t\t/**\n  \t\t * A string representing the current Punycode.js version number.\n  \t\t * @memberOf punycode\n  \t\t * @type String\n  \t\t */\n  \t\t'version': '1.2.4',\n  \t\t/**\n  \t\t * An object of methods to convert from JavaScript's internal character\n  \t\t * representation (UCS-2) to Unicode code points, and back.\n  \t\t * @see <http://mathiasbynens.be/notes/javascript-encoding>\n  \t\t * @memberOf punycode\n  \t\t * @type Object\n  \t\t */\n  \t\t'ucs2': {\n  \t\t\t'decode': ucs2decode,\n  \t\t\t'encode': ucs2encode\n  \t\t},\n  \t\t'decode': decode,\n  \t\t'encode': encode,\n  \t\t'toASCII': toASCII,\n  \t\t'toUnicode': toUnicode\n  \t};\n\n  \t/** Expose `punycode` */\n  \t// Some AMD build optimizers, like r.js, check for specific condition patterns\n  \t// like the following:\n  \tif (\n  \t\ttypeof define == 'function' &&\n  \t\ttypeof define.amd == 'object' && define.amd && false\n  \t) {\n  \t\tdefine('punycode', function() {\n  \t\t\treturn punycode;\n  \t\t});\n  \t} else if (freeExports && !freeExports.nodeType) {\n  \t\tif (freeModule) { // in Node.js or RingoJS v0.8.0+\n  \t\t\tfreeModule.exports = punycode;\n  \t\t} else { // in Narwhal or RingoJS v0.7.0-\n  \t\t\tfor (key in punycode) {\n  \t\t\t\tpunycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);\n  \t\t\t}\n  \t\t}\n  \t} else { // in Rhino or a web browser\n  \t\troot.punycode = punycode;\n  \t}\n\n  }(this));\n\n  }).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {});\n  },{}],2:[function(_dereq_,module,exports){\n  var log = _dereq_('./log');\n\n  function restoreOwnerScroll(ownerDocument, x, y) {\n      if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {\n          ownerDocument.defaultView.scrollTo(x, y);\n      }\n  }\n\n  function cloneCanvasContents(canvas, clonedCanvas) {\n      try {\n          if (clonedCanvas) {\n              clonedCanvas.width = canvas.width;\n              clonedCanvas.height = canvas.height;\n              clonedCanvas.getContext(\"2d\").putImageData(canvas.getContext(\"2d\").getImageData(0, 0, canvas.width, canvas.height), 0, 0);\n          }\n      } catch(e) {\n          log(\"Unable to copy canvas content from\", canvas, e);\n      }\n  }\n\n  function cloneNode(node, javascriptEnabled) {\n      var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);\n\n      var child = node.firstChild;\n      while(child) {\n          if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {\n              clone.appendChild(cloneNode(child, javascriptEnabled));\n          }\n          child = child.nextSibling;\n      }\n\n      if (node.nodeType === 1) {\n          clone._scrollTop = node.scrollTop;\n          clone._scrollLeft = node.scrollLeft;\n          if (node.nodeName === \"CANVAS\") {\n              cloneCanvasContents(node, clone);\n          } else if (node.nodeName === \"TEXTAREA\" || node.nodeName === \"SELECT\") {\n              clone.value = node.value;\n          }\n      }\n\n      return clone;\n  }\n\n  function initNode(node) {\n      if (node.nodeType === 1) {\n          node.scrollTop = node._scrollTop;\n          node.scrollLeft = node._scrollLeft;\n\n          var child = node.firstChild;\n          while(child) {\n              initNode(child);\n              child = child.nextSibling;\n          }\n      }\n  }\n\n  module.exports = function(ownerDocument, containerDocument, width, height, options, x ,y) {\n      var documentElement = cloneNode(ownerDocument.documentElement, options.javascriptEnabled);\n      var container = containerDocument.createElement(\"iframe\");\n\n      container.className = \"html2canvas-container\";\n      container.style.visibility = \"hidden\";\n      container.style.position = \"fixed\";\n      container.style.left = \"-10000px\";\n      container.style.top = \"0px\";\n      container.style.border = \"0\";\n      container.width = width;\n      container.height = height;\n      container.scrolling = \"no\"; // ios won't scroll without it\n      containerDocument.body.appendChild(container);\n\n      return new Promise(function(resolve) {\n          var documentClone = container.contentWindow.document;\n\n          /* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle\n           if window url is about:blank, we can assign the url to current by writing onto the document\n           */\n          container.contentWindow.onload = container.onload = function() {\n              var interval = setInterval(function() {\n                  if (documentClone.body.childNodes.length > 0) {\n                      initNode(documentClone.documentElement);\n                      clearInterval(interval);\n                      if (options.type === \"view\") {\n                          container.contentWindow.scrollTo(x, y);\n                          if ((/(iPad|iPhone|iPod)/g).test(navigator.userAgent) && (container.contentWindow.scrollY !== y || container.contentWindow.scrollX !== x)) {\n                              documentClone.documentElement.style.top = (-y) + \"px\";\n                              documentClone.documentElement.style.left = (-x) + \"px\";\n                              documentClone.documentElement.style.position = 'absolute';\n                          }\n                      }\n                      resolve(container);\n                  }\n              }, 50);\n          };\n\n          documentClone.open();\n          documentClone.write(\"<!DOCTYPE html><html></html>\");\n          // Chrome scrolls the parent document for some reason after the write to the cloned window???\n          restoreOwnerScroll(ownerDocument, x, y);\n          documentClone.replaceChild(documentClone.adoptNode(documentElement), documentClone.documentElement);\n          documentClone.close();\n      });\n  };\n\n  },{\"./log\":13}],3:[function(_dereq_,module,exports){\n  // http://dev.w3.org/csswg/css-color/\n\n  function Color(value) {\n      this.r = 0;\n      this.g = 0;\n      this.b = 0;\n      this.a = null;\n      var result = this.fromArray(value) ||\n          this.namedColor(value) ||\n          this.rgb(value) ||\n          this.rgba(value) ||\n          this.hex6(value) ||\n          this.hex3(value);\n  }\n\n  Color.prototype.darken = function(amount) {\n      var a = 1 - amount;\n      return  new Color([\n          Math.round(this.r * a),\n          Math.round(this.g * a),\n          Math.round(this.b * a),\n          this.a\n      ]);\n  };\n\n  Color.prototype.isTransparent = function() {\n      return this.a === 0;\n  };\n\n  Color.prototype.isBlack = function() {\n      return this.r === 0 && this.g === 0 && this.b === 0;\n  };\n\n  Color.prototype.fromArray = function(array) {\n      if (Array.isArray(array)) {\n          this.r = Math.min(array[0], 255);\n          this.g = Math.min(array[1], 255);\n          this.b = Math.min(array[2], 255);\n          if (array.length > 3) {\n              this.a = array[3];\n          }\n      }\n\n      return (Array.isArray(array));\n  };\n\n  var _hex3 = /^#([a-f0-9]{3})$/i;\n\n  Color.prototype.hex3 = function(value) {\n      var match = null;\n      if ((match = value.match(_hex3)) !== null) {\n          this.r = parseInt(match[1][0] + match[1][0], 16);\n          this.g = parseInt(match[1][1] + match[1][1], 16);\n          this.b = parseInt(match[1][2] + match[1][2], 16);\n      }\n      return match !== null;\n  };\n\n  var _hex6 = /^#([a-f0-9]{6})$/i;\n\n  Color.prototype.hex6 = function(value) {\n      var match = null;\n      if ((match = value.match(_hex6)) !== null) {\n          this.r = parseInt(match[1].substring(0, 2), 16);\n          this.g = parseInt(match[1].substring(2, 4), 16);\n          this.b = parseInt(match[1].substring(4, 6), 16);\n      }\n      return match !== null;\n  };\n\n\n  var _rgb = /^rgb\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*\\)$/;\n\n  Color.prototype.rgb = function(value) {\n      var match = null;\n      if ((match = value.match(_rgb)) !== null) {\n          this.r = Number(match[1]);\n          this.g = Number(match[2]);\n          this.b = Number(match[3]);\n      }\n      return match !== null;\n  };\n\n  var _rgba = /^rgba\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d?\\.?\\d+)\\s*\\)$/;\n\n  Color.prototype.rgba = function(value) {\n      var match = null;\n      if ((match = value.match(_rgba)) !== null) {\n          this.r = Number(match[1]);\n          this.g = Number(match[2]);\n          this.b = Number(match[3]);\n          this.a = Number(match[4]);\n      }\n      return match !== null;\n  };\n\n  Color.prototype.toString = function() {\n      return this.a !== null && this.a !== 1 ?\n      \"rgba(\" + [this.r, this.g, this.b, this.a].join(\",\") + \")\" :\n      \"rgb(\" + [this.r, this.g, this.b].join(\",\") + \")\";\n  };\n\n  Color.prototype.namedColor = function(value) {\n      value = value.toLowerCase();\n      var color = colors[value];\n      if (color) {\n          this.r = color[0];\n          this.g = color[1];\n          this.b = color[2];\n      } else if (value === \"transparent\") {\n          this.r = this.g = this.b = this.a = 0;\n          return true;\n      }\n\n      return !!color;\n  };\n\n  Color.prototype.isColor = true;\n\n  // JSON.stringify([].slice.call($$('.named-color-table tr'), 1).map(function(row) { return [row.childNodes[3].textContent, row.childNodes[5].textContent.trim().split(\",\").map(Number)] }).reduce(function(data, row) {data[row[0]] = row[1]; return data}, {}))\n  var colors = {\n      \"aliceblue\": [240, 248, 255],\n      \"antiquewhite\": [250, 235, 215],\n      \"aqua\": [0, 255, 255],\n      \"aquamarine\": [127, 255, 212],\n      \"azure\": [240, 255, 255],\n      \"beige\": [245, 245, 220],\n      \"bisque\": [255, 228, 196],\n      \"black\": [0, 0, 0],\n      \"blanchedalmond\": [255, 235, 205],\n      \"blue\": [0, 0, 255],\n      \"blueviolet\": [138, 43, 226],\n      \"brown\": [165, 42, 42],\n      \"burlywood\": [222, 184, 135],\n      \"cadetblue\": [95, 158, 160],\n      \"chartreuse\": [127, 255, 0],\n      \"chocolate\": [210, 105, 30],\n      \"coral\": [255, 127, 80],\n      \"cornflowerblue\": [100, 149, 237],\n      \"cornsilk\": [255, 248, 220],\n      \"crimson\": [220, 20, 60],\n      \"cyan\": [0, 255, 255],\n      \"darkblue\": [0, 0, 139],\n      \"darkcyan\": [0, 139, 139],\n      \"darkgoldenrod\": [184, 134, 11],\n      \"darkgray\": [169, 169, 169],\n      \"darkgreen\": [0, 100, 0],\n      \"darkgrey\": [169, 169, 169],\n      \"darkkhaki\": [189, 183, 107],\n      \"darkmagenta\": [139, 0, 139],\n      \"darkolivegreen\": [85, 107, 47],\n      \"darkorange\": [255, 140, 0],\n      \"darkorchid\": [153, 50, 204],\n      \"darkred\": [139, 0, 0],\n      \"darksalmon\": [233, 150, 122],\n      \"darkseagreen\": [143, 188, 143],\n      \"darkslateblue\": [72, 61, 139],\n      \"darkslategray\": [47, 79, 79],\n      \"darkslategrey\": [47, 79, 79],\n      \"darkturquoise\": [0, 206, 209],\n      \"darkviolet\": [148, 0, 211],\n      \"deeppink\": [255, 20, 147],\n      \"deepskyblue\": [0, 191, 255],\n      \"dimgray\": [105, 105, 105],\n      \"dimgrey\": [105, 105, 105],\n      \"dodgerblue\": [30, 144, 255],\n      \"firebrick\": [178, 34, 34],\n      \"floralwhite\": [255, 250, 240],\n      \"forestgreen\": [34, 139, 34],\n      \"fuchsia\": [255, 0, 255],\n      \"gainsboro\": [220, 220, 220],\n      \"ghostwhite\": [248, 248, 255],\n      \"gold\": [255, 215, 0],\n      \"goldenrod\": [218, 165, 32],\n      \"gray\": [128, 128, 128],\n      \"green\": [0, 128, 0],\n      \"greenyellow\": [173, 255, 47],\n      \"grey\": [128, 128, 128],\n      \"honeydew\": [240, 255, 240],\n      \"hotpink\": [255, 105, 180],\n      \"indianred\": [205, 92, 92],\n      \"indigo\": [75, 0, 130],\n      \"ivory\": [255, 255, 240],\n      \"khaki\": [240, 230, 140],\n      \"lavender\": [230, 230, 250],\n      \"lavenderblush\": [255, 240, 245],\n      \"lawngreen\": [124, 252, 0],\n      \"lemonchiffon\": [255, 250, 205],\n      \"lightblue\": [173, 216, 230],\n      \"lightcoral\": [240, 128, 128],\n      \"lightcyan\": [224, 255, 255],\n      \"lightgoldenrodyellow\": [250, 250, 210],\n      \"lightgray\": [211, 211, 211],\n      \"lightgreen\": [144, 238, 144],\n      \"lightgrey\": [211, 211, 211],\n      \"lightpink\": [255, 182, 193],\n      \"lightsalmon\": [255, 160, 122],\n      \"lightseagreen\": [32, 178, 170],\n      \"lightskyblue\": [135, 206, 250],\n      \"lightslategray\": [119, 136, 153],\n      \"lightslategrey\": [119, 136, 153],\n      \"lightsteelblue\": [176, 196, 222],\n      \"lightyellow\": [255, 255, 224],\n      \"lime\": [0, 255, 0],\n      \"limegreen\": [50, 205, 50],\n      \"linen\": [250, 240, 230],\n      \"magenta\": [255, 0, 255],\n      \"maroon\": [128, 0, 0],\n      \"mediumaquamarine\": [102, 205, 170],\n      \"mediumblue\": [0, 0, 205],\n      \"mediumorchid\": [186, 85, 211],\n      \"mediumpurple\": [147, 112, 219],\n      \"mediumseagreen\": [60, 179, 113],\n      \"mediumslateblue\": [123, 104, 238],\n      \"mediumspringgreen\": [0, 250, 154],\n      \"mediumturquoise\": [72, 209, 204],\n      \"mediumvioletred\": [199, 21, 133],\n      \"midnightblue\": [25, 25, 112],\n      \"mintcream\": [245, 255, 250],\n      \"mistyrose\": [255, 228, 225],\n      \"moccasin\": [255, 228, 181],\n      \"navajowhite\": [255, 222, 173],\n      \"navy\": [0, 0, 128],\n      \"oldlace\": [253, 245, 230],\n      \"olive\": [128, 128, 0],\n      \"olivedrab\": [107, 142, 35],\n      \"orange\": [255, 165, 0],\n      \"orangered\": [255, 69, 0],\n      \"orchid\": [218, 112, 214],\n      \"palegoldenrod\": [238, 232, 170],\n      \"palegreen\": [152, 251, 152],\n      \"paleturquoise\": [175, 238, 238],\n      \"palevioletred\": [219, 112, 147],\n      \"papayawhip\": [255, 239, 213],\n      \"peachpuff\": [255, 218, 185],\n      \"peru\": [205, 133, 63],\n      \"pink\": [255, 192, 203],\n      \"plum\": [221, 160, 221],\n      \"powderblue\": [176, 224, 230],\n      \"purple\": [128, 0, 128],\n      \"rebeccapurple\": [102, 51, 153],\n      \"red\": [255, 0, 0],\n      \"rosybrown\": [188, 143, 143],\n      \"royalblue\": [65, 105, 225],\n      \"saddlebrown\": [139, 69, 19],\n      \"salmon\": [250, 128, 114],\n      \"sandybrown\": [244, 164, 96],\n      \"seagreen\": [46, 139, 87],\n      \"seashell\": [255, 245, 238],\n      \"sienna\": [160, 82, 45],\n      \"silver\": [192, 192, 192],\n      \"skyblue\": [135, 206, 235],\n      \"slateblue\": [106, 90, 205],\n      \"slategray\": [112, 128, 144],\n      \"slategrey\": [112, 128, 144],\n      \"snow\": [255, 250, 250],\n      \"springgreen\": [0, 255, 127],\n      \"steelblue\": [70, 130, 180],\n      \"tan\": [210, 180, 140],\n      \"teal\": [0, 128, 128],\n      \"thistle\": [216, 191, 216],\n      \"tomato\": [255, 99, 71],\n      \"turquoise\": [64, 224, 208],\n      \"violet\": [238, 130, 238],\n      \"wheat\": [245, 222, 179],\n      \"white\": [255, 255, 255],\n      \"whitesmoke\": [245, 245, 245],\n      \"yellow\": [255, 255, 0],\n      \"yellowgreen\": [154, 205, 50]\n  };\n\n  module.exports = Color;\n\n  },{}],4:[function(_dereq_,module,exports){\n  var Support = _dereq_('./support');\n  var CanvasRenderer = _dereq_('./renderers/canvas');\n  var ImageLoader = _dereq_('./imageloader');\n  var NodeParser = _dereq_('./nodeparser');\n  var NodeContainer = _dereq_('./nodecontainer');\n  var log = _dereq_('./log');\n  var utils = _dereq_('./utils');\n  var createWindowClone = _dereq_('./clone');\n  var loadUrlDocument = _dereq_('./proxy').loadUrlDocument;\n  var getBounds = utils.getBounds;\n\n  var html2canvasNodeAttribute = \"data-html2canvas-node\";\n  var html2canvasCloneIndex = 0;\n\n  function html2canvas(nodeList, options) {\n      var index = html2canvasCloneIndex++;\n      options = options || {};\n      if (options.logging) {\n          log.options.logging = true;\n          log.options.start = Date.now();\n      }\n\n      options.async = typeof(options.async) === \"undefined\" ? true : options.async;\n      options.allowTaint = typeof(options.allowTaint) === \"undefined\" ? false : options.allowTaint;\n      options.removeContainer = typeof(options.removeContainer) === \"undefined\" ? true : options.removeContainer;\n      options.javascriptEnabled = typeof(options.javascriptEnabled) === \"undefined\" ? false : options.javascriptEnabled;\n      options.imageTimeout = typeof(options.imageTimeout) === \"undefined\" ? 10000 : options.imageTimeout;\n      options.renderer = typeof(options.renderer) === \"function\" ? options.renderer : CanvasRenderer;\n      options.strict = !!options.strict;\n\n      if (typeof(nodeList) === \"string\") {\n          if (typeof(options.proxy) !== \"string\") {\n              return Promise.reject(\"Proxy must be used when rendering url\");\n          }\n          var width = options.width != null ? options.width : window.innerWidth;\n          var height = options.height != null ? options.height : window.innerHeight;\n          return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, width, height, options).then(function(container) {\n              return renderWindow(container.contentWindow.document.documentElement, container, options, width, height);\n          });\n      }\n\n      var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0];\n      node.setAttribute(html2canvasNodeAttribute + index, index);\n      return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) {\n          if (typeof(options.onrendered) === \"function\") {\n              log(\"options.onrendered is deprecated, html2canvas returns a Promise containing the canvas\");\n              options.onrendered(canvas);\n          }\n          return canvas;\n      });\n  }\n\n  html2canvas.CanvasRenderer = CanvasRenderer;\n  html2canvas.NodeContainer = NodeContainer;\n  html2canvas.log = log;\n  html2canvas.utils = utils;\n\n  var html2canvasExport = (typeof(document) === \"undefined\" || typeof(Object.create) !== \"function\" || typeof(document.createElement(\"canvas\").getContext) !== \"function\") ? function() {\n      return Promise.reject(\"No canvas support\");\n  } : html2canvas;\n\n  module.exports = html2canvasExport;\n\n  if (typeof(define) === 'function' && define.amd && false) {\n      define('html2canvas', [], function() {\n          return html2canvasExport;\n      });\n  }\n\n  function renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) {\n      return createWindowClone(document, document, windowWidth, windowHeight, options, document.defaultView.pageXOffset, document.defaultView.pageYOffset).then(function(container) {\n          log(\"Document cloned\");\n          var attributeName = html2canvasNodeAttribute + html2canvasIndex;\n          var selector = \"[\" + attributeName + \"='\" + html2canvasIndex + \"']\";\n          document.querySelector(selector).removeAttribute(attributeName);\n          var clonedWindow = container.contentWindow;\n          var node = clonedWindow.document.querySelector(selector);\n          var oncloneHandler = (typeof(options.onclone) === \"function\") ? Promise.resolve(options.onclone(clonedWindow.document)) : Promise.resolve(true);\n          return oncloneHandler.then(function() {\n              return renderWindow(node, container, options, windowWidth, windowHeight);\n          });\n      });\n  }\n\n  function renderWindow(node, container, options, windowWidth, windowHeight) {\n      var clonedWindow = container.contentWindow;\n      var support = new Support(clonedWindow.document);\n      var imageLoader = new ImageLoader(options, support);\n      var bounds = getBounds(node);\n      var width = options.type === \"view\" ? windowWidth : documentWidth(clonedWindow.document);\n      var height = options.type === \"view\" ? windowHeight : documentHeight(clonedWindow.document);\n      var renderer = new options.renderer(width, height, imageLoader, options, document);\n      var parser = new NodeParser(node, renderer, support, imageLoader, options);\n      return parser.ready.then(function() {\n          log(\"Finished rendering\");\n          var canvas;\n\n          if (options.type === \"view\") {\n              canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0});\n          } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement || options.canvas != null) {\n              canvas = renderer.canvas;\n          } else {\n              canvas = crop(renderer.canvas, {width:  options.width != null ? options.width : bounds.width, height: options.height != null ? options.height : bounds.height, top: bounds.top, left: bounds.left, x: 0, y: 0});\n          }\n\n          cleanupContainer(container, options);\n          return canvas;\n      });\n  }\n\n  function cleanupContainer(container, options) {\n      if (options.removeContainer) {\n          container.parentNode.removeChild(container);\n          log(\"Cleaned up container\");\n      }\n  }\n\n  function crop(canvas, bounds) {\n      var croppedCanvas = document.createElement(\"canvas\");\n      var x1 = Math.min(canvas.width - 1, Math.max(0, bounds.left));\n      var x2 = Math.min(canvas.width, Math.max(1, bounds.left + bounds.width));\n      var y1 = Math.min(canvas.height - 1, Math.max(0, bounds.top));\n      var y2 = Math.min(canvas.height, Math.max(1, bounds.top + bounds.height));\n      croppedCanvas.width = bounds.width;\n      croppedCanvas.height =  bounds.height;\n      var width = x2-x1;\n      var height = y2-y1;\n      log(\"Cropping canvas at:\", \"left:\", bounds.left, \"top:\", bounds.top, \"width:\", width, \"height:\", height);\n      log(\"Resulting crop with width\", bounds.width, \"and height\", bounds.height, \"with x\", x1, \"and y\", y1);\n      croppedCanvas.getContext(\"2d\").drawImage(canvas, x1, y1, width, height, bounds.x, bounds.y, width, height);\n      return croppedCanvas;\n  }\n\n  function documentWidth (doc) {\n      return Math.max(\n          Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth),\n          Math.max(doc.body.offsetWidth, doc.documentElement.offsetWidth),\n          Math.max(doc.body.clientWidth, doc.documentElement.clientWidth)\n      );\n  }\n\n  function documentHeight (doc) {\n      return Math.max(\n          Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight),\n          Math.max(doc.body.offsetHeight, doc.documentElement.offsetHeight),\n          Math.max(doc.body.clientHeight, doc.documentElement.clientHeight)\n      );\n  }\n\n  function absoluteUrl(url) {\n      var link = document.createElement(\"a\");\n      link.href = url;\n      link.href = link.href;\n      return link;\n  }\n\n  },{\"./clone\":2,\"./imageloader\":11,\"./log\":13,\"./nodecontainer\":14,\"./nodeparser\":15,\"./proxy\":16,\"./renderers/canvas\":20,\"./support\":22,\"./utils\":26}],5:[function(_dereq_,module,exports){\n  var log = _dereq_('./log');\n  var smallImage = _dereq_('./utils').smallImage;\n\n  function DummyImageContainer(src) {\n      this.src = src;\n      log(\"DummyImageContainer for\", src);\n      if (!this.promise || !this.image) {\n          log(\"Initiating DummyImageContainer\");\n          DummyImageContainer.prototype.image = new Image();\n          var image = this.image;\n          DummyImageContainer.prototype.promise = new Promise(function(resolve, reject) {\n              image.onload = resolve;\n              image.onerror = reject;\n              image.src = smallImage();\n              if (image.complete === true) {\n                  resolve(image);\n              }\n          });\n      }\n  }\n\n  module.exports = DummyImageContainer;\n\n  },{\"./log\":13,\"./utils\":26}],6:[function(_dereq_,module,exports){\n  var smallImage = _dereq_('./utils').smallImage;\n\n  function Font(family, size) {\n      var container = document.createElement('div'),\n          img = document.createElement('img'),\n          span = document.createElement('span'),\n          sampleText = 'Hidden Text',\n          baseline,\n          middle;\n\n      container.style.visibility = \"hidden\";\n      container.style.fontFamily = family;\n      container.style.fontSize = size;\n      container.style.margin = 0;\n      container.style.padding = 0;\n\n      document.body.appendChild(container);\n\n      img.src = smallImage();\n      img.width = 1;\n      img.height = 1;\n\n      img.style.margin = 0;\n      img.style.padding = 0;\n      img.style.verticalAlign = \"baseline\";\n\n      span.style.fontFamily = family;\n      span.style.fontSize = size;\n      span.style.margin = 0;\n      span.style.padding = 0;\n\n      span.appendChild(document.createTextNode(sampleText));\n      container.appendChild(span);\n      container.appendChild(img);\n      baseline = (img.offsetTop - span.offsetTop) + 1;\n\n      container.removeChild(span);\n      container.appendChild(document.createTextNode(sampleText));\n\n      container.style.lineHeight = \"normal\";\n      img.style.verticalAlign = \"super\";\n\n      middle = (img.offsetTop-container.offsetTop) + 1;\n\n      document.body.removeChild(container);\n\n      this.baseline = baseline;\n      this.lineWidth = 1;\n      this.middle = middle;\n  }\n\n  module.exports = Font;\n\n  },{\"./utils\":26}],7:[function(_dereq_,module,exports){\n  var Font = _dereq_('./font');\n\n  function FontMetrics() {\n      this.data = {};\n  }\n\n  FontMetrics.prototype.getMetrics = function(family, size) {\n      if (this.data[family + \"-\" + size] === undefined) {\n          this.data[family + \"-\" + size] = new Font(family, size);\n      }\n      return this.data[family + \"-\" + size];\n  };\n\n  module.exports = FontMetrics;\n\n  },{\"./font\":6}],8:[function(_dereq_,module,exports){\n  var utils = _dereq_('./utils');\n  var getBounds = utils.getBounds;\n  var loadUrlDocument = _dereq_('./proxy').loadUrlDocument;\n\n  function FrameContainer(container, sameOrigin, options) {\n      this.image = null;\n      this.src = container;\n      var self = this;\n      var bounds = getBounds(container);\n      this.promise = (!sameOrigin ? this.proxyLoad(options.proxy, bounds, options) : new Promise(function(resolve) {\n          if (container.contentWindow.document.URL === \"about:blank\" || container.contentWindow.document.documentElement == null) {\n              container.contentWindow.onload = container.onload = function() {\n                  resolve(container);\n              };\n          } else {\n              resolve(container);\n          }\n      })).then(function(container) {\n          var html2canvas = _dereq_('./core');\n          return html2canvas(container.contentWindow.document.documentElement, {type: 'view', width: container.width, height: container.height, proxy: options.proxy, javascriptEnabled: options.javascriptEnabled, removeContainer: options.removeContainer, allowTaint: options.allowTaint, imageTimeout: options.imageTimeout / 2});\n      }).then(function(canvas) {\n          return self.image = canvas;\n      });\n  }\n\n  FrameContainer.prototype.proxyLoad = function(proxy, bounds, options) {\n      var container = this.src;\n      return loadUrlDocument(container.src, proxy, container.ownerDocument, bounds.width, bounds.height, options);\n  };\n\n  module.exports = FrameContainer;\n\n  },{\"./core\":4,\"./proxy\":16,\"./utils\":26}],9:[function(_dereq_,module,exports){\n  function GradientContainer(imageData) {\n      this.src = imageData.value;\n      this.colorStops = [];\n      this.type = null;\n      this.x0 = 0.5;\n      this.y0 = 0.5;\n      this.x1 = 0.5;\n      this.y1 = 0.5;\n      this.promise = Promise.resolve(true);\n  }\n\n  GradientContainer.TYPES = {\n      LINEAR: 1,\n      RADIAL: 2\n  };\n\n  // TODO: support hsl[a], negative %/length values\n  // TODO: support <angle> (e.g. -?\\d{1,3}(?:\\.\\d+)deg, etc. : https://developer.mozilla.org/docs/Web/CSS/angle )\n  GradientContainer.REGEXP_COLORSTOP = /^\\s*(rgba?\\(\\s*\\d{1,3},\\s*\\d{1,3},\\s*\\d{1,3}(?:,\\s*[0-9\\.]+)?\\s*\\)|[a-z]{3,20}|#[a-f0-9]{3,6})(?:\\s+(\\d{1,3}(?:\\.\\d+)?)(%|px)?)?(?:\\s|$)/i;\n\n  module.exports = GradientContainer;\n\n  },{}],10:[function(_dereq_,module,exports){\n  function ImageContainer(src, cors) {\n      this.src = src;\n      this.image = new Image();\n      var self = this;\n      this.tainted = null;\n      this.promise = new Promise(function(resolve, reject) {\n          self.image.onload = resolve;\n          self.image.onerror = reject;\n          if (cors) {\n              self.image.crossOrigin = \"anonymous\";\n          }\n          self.image.src = src;\n          if (self.image.complete === true) {\n              resolve(self.image);\n          }\n      });\n  }\n\n  module.exports = ImageContainer;\n\n  },{}],11:[function(_dereq_,module,exports){\n  var log = _dereq_('./log');\n  var ImageContainer = _dereq_('./imagecontainer');\n  var DummyImageContainer = _dereq_('./dummyimagecontainer');\n  var ProxyImageContainer = _dereq_('./proxyimagecontainer');\n  var FrameContainer = _dereq_('./framecontainer');\n  var SVGContainer = _dereq_('./svgcontainer');\n  var SVGNodeContainer = _dereq_('./svgnodecontainer');\n  var LinearGradientContainer = _dereq_('./lineargradientcontainer');\n  var WebkitGradientContainer = _dereq_('./webkitgradientcontainer');\n  var bind = _dereq_('./utils').bind;\n\n  function ImageLoader(options, support) {\n      this.link = null;\n      this.options = options;\n      this.support = support;\n      this.origin = this.getOrigin(window.location.href);\n  }\n\n  ImageLoader.prototype.findImages = function(nodes) {\n      var images = [];\n      nodes.reduce(function(imageNodes, container) {\n          switch(container.node.nodeName) {\n          case \"IMG\":\n              return imageNodes.concat([{\n                  args: [container.node.src],\n                  method: \"url\"\n              }]);\n          case \"svg\":\n          case \"IFRAME\":\n              return imageNodes.concat([{\n                  args: [container.node],\n                  method: container.node.nodeName\n              }]);\n          }\n          return imageNodes;\n      }, []).forEach(this.addImage(images, this.loadImage), this);\n      return images;\n  };\n\n  ImageLoader.prototype.findBackgroundImage = function(images, container) {\n      container.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(images, this.loadImage), this);\n      return images;\n  };\n\n  ImageLoader.prototype.addImage = function(images, callback) {\n      return function(newImage) {\n          newImage.args.forEach(function(image) {\n              if (!this.imageExists(images, image)) {\n                  images.splice(0, 0, callback.call(this, newImage));\n                  log('Added image #' + (images.length), typeof(image) === \"string\" ? image.substring(0, 100) : image);\n              }\n          }, this);\n      };\n  };\n\n  ImageLoader.prototype.hasImageBackground = function(imageData) {\n      return imageData.method !== \"none\";\n  };\n\n  ImageLoader.prototype.loadImage = function(imageData) {\n      if (imageData.method === \"url\") {\n          var src = imageData.args[0];\n          if (this.isSVG(src) && !this.support.svg && !this.options.allowTaint) {\n              return new SVGContainer(src);\n          } else if (src.match(/data:image\\/.*;base64,/i)) {\n              return new ImageContainer(src.replace(/url\\(['\"]{0,}|['\"]{0,}\\)$/ig, ''), false);\n          } else if (this.isSameOrigin(src) || this.options.allowTaint === true || this.isSVG(src)) {\n              return new ImageContainer(src, false);\n          } else if (this.support.cors && !this.options.allowTaint && this.options.useCORS) {\n              return new ImageContainer(src, true);\n          } else if (this.options.proxy) {\n              return new ProxyImageContainer(src, this.options.proxy);\n          } else {\n              return new DummyImageContainer(src);\n          }\n      } else if (imageData.method === \"linear-gradient\") {\n          return new LinearGradientContainer(imageData);\n      } else if (imageData.method === \"gradient\") {\n          return new WebkitGradientContainer(imageData);\n      } else if (imageData.method === \"svg\") {\n          return new SVGNodeContainer(imageData.args[0], this.support.svg);\n      } else if (imageData.method === \"IFRAME\") {\n          return new FrameContainer(imageData.args[0], this.isSameOrigin(imageData.args[0].src), this.options);\n      } else {\n          return new DummyImageContainer(imageData);\n      }\n  };\n\n  ImageLoader.prototype.isSVG = function(src) {\n      return src.substring(src.length - 3).toLowerCase() === \"svg\" || SVGContainer.prototype.isInline(src);\n  };\n\n  ImageLoader.prototype.imageExists = function(images, src) {\n      return images.some(function(image) {\n          return image.src === src;\n      });\n  };\n\n  ImageLoader.prototype.isSameOrigin = function(url) {\n      return (this.getOrigin(url) === this.origin);\n  };\n\n  ImageLoader.prototype.getOrigin = function(url) {\n      var link = this.link || (this.link = document.createElement(\"a\"));\n      link.href = url;\n      link.href = link.href; // IE9, LOL! - http://jsfiddle.net/niklasvh/2e48b/\n      return link.protocol + link.hostname + link.port;\n  };\n\n  ImageLoader.prototype.getPromise = function(container) {\n      return this.timeout(container, this.options.imageTimeout)['catch'](function() {\n          var dummy = new DummyImageContainer(container.src);\n          return dummy.promise.then(function(image) {\n              container.image = image;\n          });\n      });\n  };\n\n  ImageLoader.prototype.get = function(src) {\n      var found = null;\n      return this.images.some(function(img) {\n          return (found = img).src === src;\n      }) ? found : null;\n  };\n\n  ImageLoader.prototype.fetch = function(nodes) {\n      this.images = nodes.reduce(bind(this.findBackgroundImage, this), this.findImages(nodes));\n      this.images.forEach(function(image, index) {\n          image.promise.then(function() {\n              log(\"Succesfully loaded image #\"+ (index+1), image);\n          }, function(e) {\n              log(\"Failed loading image #\"+ (index+1), image, e);\n          });\n      });\n      this.ready = Promise.all(this.images.map(this.getPromise, this));\n      log(\"Finished searching images\");\n      return this;\n  };\n\n  ImageLoader.prototype.timeout = function(container, timeout) {\n      var timer;\n      var promise = Promise.race([container.promise, new Promise(function(res, reject) {\n          timer = setTimeout(function() {\n              log(\"Timed out loading image\", container);\n              reject(container);\n          }, timeout);\n      })]).then(function(container) {\n          clearTimeout(timer);\n          return container;\n      });\n      promise['catch'](function() {\n          clearTimeout(timer);\n      });\n      return promise;\n  };\n\n  module.exports = ImageLoader;\n\n  },{\"./dummyimagecontainer\":5,\"./framecontainer\":8,\"./imagecontainer\":10,\"./lineargradientcontainer\":12,\"./log\":13,\"./proxyimagecontainer\":17,\"./svgcontainer\":23,\"./svgnodecontainer\":24,\"./utils\":26,\"./webkitgradientcontainer\":27}],12:[function(_dereq_,module,exports){\n  var GradientContainer = _dereq_('./gradientcontainer');\n  var Color = _dereq_('./color');\n\n  function LinearGradientContainer(imageData) {\n      GradientContainer.apply(this, arguments);\n      this.type = GradientContainer.TYPES.LINEAR;\n\n      var hasDirection = LinearGradientContainer.REGEXP_DIRECTION.test( imageData.args[0] ) ||\n          !GradientContainer.REGEXP_COLORSTOP.test( imageData.args[0] );\n\n      if (hasDirection) {\n          imageData.args[0].split(/\\s+/).reverse().forEach(function(position, index) {\n              switch(position) {\n              case \"left\":\n                  this.x0 = 0;\n                  this.x1 = 1;\n                  break;\n              case \"top\":\n                  this.y0 = 0;\n                  this.y1 = 1;\n                  break;\n              case \"right\":\n                  this.x0 = 1;\n                  this.x1 = 0;\n                  break;\n              case \"bottom\":\n                  this.y0 = 1;\n                  this.y1 = 0;\n                  break;\n              case \"to\":\n                  var y0 = this.y0;\n                  var x0 = this.x0;\n                  this.y0 = this.y1;\n                  this.x0 = this.x1;\n                  this.x1 = x0;\n                  this.y1 = y0;\n                  break;\n              case \"center\":\n                  break; // centered by default\n              // Firefox internally converts position keywords to percentages:\n              // http://www.w3.org/TR/2010/WD-CSS2-20101207/colors.html#propdef-background-position\n              default: // percentage or absolute length\n                  // TODO: support absolute start point positions (e.g., use bounds to convert px to a ratio)\n                  var ratio = parseFloat(position, 10) * 1e-2;\n                  if (isNaN(ratio)) { // invalid or unhandled value\n                      break;\n                  }\n                  if (index === 0) {\n                      this.y0 = ratio;\n                      this.y1 = 1 - this.y0;\n                  } else {\n                      this.x0 = ratio;\n                      this.x1 = 1 - this.x0;\n                  }\n                  break;\n              }\n          }, this);\n      } else {\n          this.y0 = 0;\n          this.y1 = 1;\n      }\n\n      this.colorStops = imageData.args.slice(hasDirection ? 1 : 0).map(function(colorStop) {\n          var colorStopMatch = colorStop.match(GradientContainer.REGEXP_COLORSTOP);\n          var value = +colorStopMatch[2];\n          var unit = value === 0 ? \"%\" : colorStopMatch[3]; // treat \"0\" as \"0%\"\n          return {\n              color: new Color(colorStopMatch[1]),\n              // TODO: support absolute stop positions (e.g., compute gradient line length & convert px to ratio)\n              stop: unit === \"%\" ? value / 100 : null\n          };\n      });\n\n      if (this.colorStops[0].stop === null) {\n          this.colorStops[0].stop = 0;\n      }\n\n      if (this.colorStops[this.colorStops.length - 1].stop === null) {\n          this.colorStops[this.colorStops.length - 1].stop = 1;\n      }\n\n      // calculates and fills-in explicit stop positions when omitted from rule\n      this.colorStops.forEach(function(colorStop, index) {\n          if (colorStop.stop === null) {\n              this.colorStops.slice(index).some(function(find, count) {\n                  if (find.stop !== null) {\n                      colorStop.stop = ((find.stop - this.colorStops[index - 1].stop) / (count + 1)) + this.colorStops[index - 1].stop;\n                      return true;\n                  } else {\n                      return false;\n                  }\n              }, this);\n          }\n      }, this);\n  }\n\n  LinearGradientContainer.prototype = Object.create(GradientContainer.prototype);\n\n  // TODO: support <angle> (e.g. -?\\d{1,3}(?:\\.\\d+)deg, etc. : https://developer.mozilla.org/docs/Web/CSS/angle )\n  LinearGradientContainer.REGEXP_DIRECTION = /^\\s*(?:to|left|right|top|bottom|center|\\d{1,3}(?:\\.\\d+)?%?)(?:\\s|$)/i;\n\n  module.exports = LinearGradientContainer;\n\n  },{\"./color\":3,\"./gradientcontainer\":9}],13:[function(_dereq_,module,exports){\n  var logger = function() {\n      if (logger.options.logging && window.console && window.console.log) {\n          Function.prototype.bind.call(window.console.log, (window.console)).apply(window.console, [(Date.now() - logger.options.start) + \"ms\", \"html2canvas:\"].concat([].slice.call(arguments, 0)));\n      }\n  };\n\n  logger.options = {logging: false};\n  module.exports = logger;\n\n  },{}],14:[function(_dereq_,module,exports){\n  var Color = _dereq_('./color');\n  var utils = _dereq_('./utils');\n  var getBounds = utils.getBounds;\n  var parseBackgrounds = utils.parseBackgrounds;\n  var offsetBounds = utils.offsetBounds;\n\n  function NodeContainer(node, parent) {\n      this.node = node;\n      this.parent = parent;\n      this.stack = null;\n      this.bounds = null;\n      this.borders = null;\n      this.clip = [];\n      this.backgroundClip = [];\n      this.offsetBounds = null;\n      this.visible = null;\n      this.computedStyles = null;\n      this.colors = {};\n      this.styles = {};\n      this.backgroundImages = null;\n      this.transformData = null;\n      this.transformMatrix = null;\n      this.isPseudoElement = false;\n      this.opacity = null;\n  }\n\n  NodeContainer.prototype.cloneTo = function(stack) {\n      stack.visible = this.visible;\n      stack.borders = this.borders;\n      stack.bounds = this.bounds;\n      stack.clip = this.clip;\n      stack.backgroundClip = this.backgroundClip;\n      stack.computedStyles = this.computedStyles;\n      stack.styles = this.styles;\n      stack.backgroundImages = this.backgroundImages;\n      stack.opacity = this.opacity;\n  };\n\n  NodeContainer.prototype.getOpacity = function() {\n      return this.opacity === null ? (this.opacity = this.cssFloat('opacity')) : this.opacity;\n  };\n\n  NodeContainer.prototype.assignStack = function(stack) {\n      this.stack = stack;\n      stack.children.push(this);\n  };\n\n  NodeContainer.prototype.isElementVisible = function() {\n      return this.node.nodeType === Node.TEXT_NODE ? this.parent.visible : (\n          this.css('display') !== \"none\" &&\n          this.css('visibility') !== \"hidden\" &&\n          !this.node.hasAttribute(\"data-html2canvas-ignore\") &&\n          (this.node.nodeName !== \"INPUT\" || this.node.getAttribute(\"type\") !== \"hidden\")\n      );\n  };\n\n  NodeContainer.prototype.css = function(attribute) {\n      if (!this.computedStyles) {\n          this.computedStyles = this.isPseudoElement ? this.parent.computedStyle(this.before ? \":before\" : \":after\") : this.computedStyle(null);\n      }\n\n      return this.styles[attribute] || (this.styles[attribute] = this.computedStyles[attribute]);\n  };\n\n  NodeContainer.prototype.prefixedCss = function(attribute) {\n      var prefixes = [\"webkit\", \"moz\", \"ms\", \"o\"];\n      var value = this.css(attribute);\n      if (value === undefined) {\n          prefixes.some(function(prefix) {\n              value = this.css(prefix + attribute.substr(0, 1).toUpperCase() + attribute.substr(1));\n              return value !== undefined;\n          }, this);\n      }\n      return value === undefined ? null : value;\n  };\n\n  NodeContainer.prototype.computedStyle = function(type) {\n      return this.node.ownerDocument.defaultView.getComputedStyle(this.node, type);\n  };\n\n  NodeContainer.prototype.cssInt = function(attribute) {\n      var value = parseInt(this.css(attribute), 10);\n      return (isNaN(value)) ? 0 : value; // borders in old IE are throwing 'medium' for demo.html\n  };\n\n  NodeContainer.prototype.color = function(attribute) {\n      return this.colors[attribute] || (this.colors[attribute] = new Color(this.css(attribute)));\n  };\n\n  NodeContainer.prototype.cssFloat = function(attribute) {\n      var value = parseFloat(this.css(attribute));\n      return (isNaN(value)) ? 0 : value;\n  };\n\n  NodeContainer.prototype.fontWeight = function() {\n      var weight = this.css(\"fontWeight\");\n      switch(parseInt(weight, 10)){\n      case 401:\n          weight = \"bold\";\n          break;\n      case 400:\n          weight = \"normal\";\n          break;\n      }\n      return weight;\n  };\n\n  NodeContainer.prototype.parseClip = function() {\n      var matches = this.css('clip').match(this.CLIP);\n      if (matches) {\n          return {\n              top: parseInt(matches[1], 10),\n              right: parseInt(matches[2], 10),\n              bottom: parseInt(matches[3], 10),\n              left: parseInt(matches[4], 10)\n          };\n      }\n      return null;\n  };\n\n  NodeContainer.prototype.parseBackgroundImages = function() {\n      return this.backgroundImages || (this.backgroundImages = parseBackgrounds(this.css(\"backgroundImage\")));\n  };\n\n  NodeContainer.prototype.cssList = function(property, index) {\n      var value = (this.css(property) || '').split(',');\n      value = value[index || 0] || value[0] || 'auto';\n      value = value.trim().split(' ');\n      if (value.length === 1) {\n          value = [value[0], isPercentage(value[0]) ? 'auto' : value[0]];\n      }\n      return value;\n  };\n\n  NodeContainer.prototype.parseBackgroundSize = function(bounds, image, index) {\n      var size = this.cssList(\"backgroundSize\", index);\n      var width, height;\n\n      if (isPercentage(size[0])) {\n          width = bounds.width * parseFloat(size[0]) / 100;\n      } else if (/contain|cover/.test(size[0])) {\n          var targetRatio = bounds.width / bounds.height, currentRatio = image.width / image.height;\n          return (targetRatio < currentRatio ^ size[0] === 'contain') ?  {width: bounds.height * currentRatio, height: bounds.height} : {width: bounds.width, height: bounds.width / currentRatio};\n      } else {\n          width = parseInt(size[0], 10);\n      }\n\n      if (size[0] === 'auto' && size[1] === 'auto') {\n          height = image.height;\n      } else if (size[1] === 'auto') {\n          height = width / image.width * image.height;\n      } else if (isPercentage(size[1])) {\n          height =  bounds.height * parseFloat(size[1]) / 100;\n      } else {\n          height = parseInt(size[1], 10);\n      }\n\n      if (size[0] === 'auto') {\n          width = height / image.height * image.width;\n      }\n\n      return {width: width, height: height};\n  };\n\n  NodeContainer.prototype.parseBackgroundPosition = function(bounds, image, index, backgroundSize) {\n      var position = this.cssList('backgroundPosition', index);\n      var left, top;\n\n      if (isPercentage(position[0])){\n          left = (bounds.width - (backgroundSize || image).width) * (parseFloat(position[0]) / 100);\n      } else {\n          left = parseInt(position[0], 10);\n      }\n\n      if (position[1] === 'auto') {\n          top = left / image.width * image.height;\n      } else if (isPercentage(position[1])){\n          top =  (bounds.height - (backgroundSize || image).height) * parseFloat(position[1]) / 100;\n      } else {\n          top = parseInt(position[1], 10);\n      }\n\n      if (position[0] === 'auto') {\n          left = top / image.height * image.width;\n      }\n\n      return {left: left, top: top};\n  };\n\n  NodeContainer.prototype.parseBackgroundRepeat = function(index) {\n      return this.cssList(\"backgroundRepeat\", index)[0];\n  };\n\n  NodeContainer.prototype.parseTextShadows = function() {\n      var textShadow = this.css(\"textShadow\");\n      var results = [];\n\n      if (textShadow && textShadow !== 'none') {\n          var shadows = textShadow.match(this.TEXT_SHADOW_PROPERTY);\n          for (var i = 0; shadows && (i < shadows.length); i++) {\n              var s = shadows[i].match(this.TEXT_SHADOW_VALUES);\n              results.push({\n                  color: new Color(s[0]),\n                  offsetX: s[1] ? parseFloat(s[1].replace('px', '')) : 0,\n                  offsetY: s[2] ? parseFloat(s[2].replace('px', '')) : 0,\n                  blur: s[3] ? s[3].replace('px', '') : 0\n              });\n          }\n      }\n      return results;\n  };\n\n  NodeContainer.prototype.parseTransform = function() {\n      if (!this.transformData) {\n          if (this.hasTransform()) {\n              var offset = this.parseBounds();\n              var origin = this.prefixedCss(\"transformOrigin\").split(\" \").map(removePx).map(asFloat);\n              origin[0] += offset.left;\n              origin[1] += offset.top;\n              this.transformData = {\n                  origin: origin,\n                  matrix: this.parseTransformMatrix()\n              };\n          } else {\n              this.transformData = {\n                  origin: [0, 0],\n                  matrix: [1, 0, 0, 1, 0, 0]\n              };\n          }\n      }\n      return this.transformData;\n  };\n\n  NodeContainer.prototype.parseTransformMatrix = function() {\n      if (!this.transformMatrix) {\n          var transform = this.prefixedCss(\"transform\");\n          var matrix = transform ? parseMatrix(transform.match(this.MATRIX_PROPERTY)) : null;\n          this.transformMatrix = matrix ? matrix : [1, 0, 0, 1, 0, 0];\n      }\n      return this.transformMatrix;\n  };\n\n  NodeContainer.prototype.parseBounds = function() {\n      return this.bounds || (this.bounds = this.hasTransform() ? offsetBounds(this.node) : getBounds(this.node));\n  };\n\n  NodeContainer.prototype.hasTransform = function() {\n      return this.parseTransformMatrix().join(\",\") !== \"1,0,0,1,0,0\" || (this.parent && this.parent.hasTransform());\n  };\n\n  NodeContainer.prototype.getValue = function() {\n      var value = this.node.value || \"\";\n      if (this.node.tagName === \"SELECT\") {\n          value = selectionValue(this.node);\n      } else if (this.node.type === \"password\") {\n          value = Array(value.length + 1).join('\\u2022'); // jshint ignore:line\n      }\n      return value.length === 0 ? (this.node.placeholder || \"\") : value;\n  };\n\n  NodeContainer.prototype.MATRIX_PROPERTY = /(matrix|matrix3d)\\((.+)\\)/;\n  NodeContainer.prototype.TEXT_SHADOW_PROPERTY = /((rgba|rgb)\\([^\\)]+\\)(\\s-?\\d+px){0,})/g;\n  NodeContainer.prototype.TEXT_SHADOW_VALUES = /(-?\\d+px)|(#.+)|(rgb\\(.+\\))|(rgba\\(.+\\))/g;\n  NodeContainer.prototype.CLIP = /^rect\\((\\d+)px,? (\\d+)px,? (\\d+)px,? (\\d+)px\\)$/;\n\n  function selectionValue(node) {\n      var option = node.options[node.selectedIndex || 0];\n      return option ? (option.text || \"\") : \"\";\n  }\n\n  function parseMatrix(match) {\n      if (match && match[1] === \"matrix\") {\n          return match[2].split(\",\").map(function(s) {\n              return parseFloat(s.trim());\n          });\n      } else if (match && match[1] === \"matrix3d\") {\n          var matrix3d = match[2].split(\",\").map(function(s) {\n            return parseFloat(s.trim());\n          });\n          return [matrix3d[0], matrix3d[1], matrix3d[4], matrix3d[5], matrix3d[12], matrix3d[13]];\n      }\n  }\n\n  function isPercentage(value) {\n      return value.toString().indexOf(\"%\") !== -1;\n  }\n\n  function removePx(str) {\n      return str.replace(\"px\", \"\");\n  }\n\n  function asFloat(str) {\n      return parseFloat(str);\n  }\n\n  module.exports = NodeContainer;\n\n  },{\"./color\":3,\"./utils\":26}],15:[function(_dereq_,module,exports){\n  var log = _dereq_('./log');\n  var punycode = _dereq_('punycode');\n  var NodeContainer = _dereq_('./nodecontainer');\n  var TextContainer = _dereq_('./textcontainer');\n  var PseudoElementContainer = _dereq_('./pseudoelementcontainer');\n  var FontMetrics = _dereq_('./fontmetrics');\n  var Color = _dereq_('./color');\n  var StackingContext = _dereq_('./stackingcontext');\n  var utils = _dereq_('./utils');\n  var bind = utils.bind;\n  var getBounds = utils.getBounds;\n  var parseBackgrounds = utils.parseBackgrounds;\n  var offsetBounds = utils.offsetBounds;\n\n  function NodeParser(element, renderer, support, imageLoader, options) {\n      log(\"Starting NodeParser\");\n      this.renderer = renderer;\n      this.options = options;\n      this.range = null;\n      this.support = support;\n      this.renderQueue = [];\n      this.stack = new StackingContext(true, 1, element.ownerDocument, null);\n      var parent = new NodeContainer(element, null);\n      if (options.background) {\n          renderer.rectangle(0, 0, renderer.width, renderer.height, new Color(options.background));\n      }\n      if (element === element.ownerDocument.documentElement) {\n          // http://www.w3.org/TR/css3-background/#special-backgrounds\n          var canvasBackground = new NodeContainer(parent.color('backgroundColor').isTransparent() ? element.ownerDocument.body : element.ownerDocument.documentElement, null);\n          renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.color('backgroundColor'));\n      }\n      parent.visibile = parent.isElementVisible();\n      this.createPseudoHideStyles(element.ownerDocument);\n      this.disableAnimations(element.ownerDocument);\n      this.nodes = flatten([parent].concat(this.getChildren(parent)).filter(function(container) {\n          return container.visible = container.isElementVisible();\n      }).map(this.getPseudoElements, this));\n      this.fontMetrics = new FontMetrics();\n      log(\"Fetched nodes, total:\", this.nodes.length);\n      log(\"Calculate overflow clips\");\n      this.calculateOverflowClips();\n      log(\"Start fetching images\");\n      this.images = imageLoader.fetch(this.nodes.filter(isElement));\n      this.ready = this.images.ready.then(bind(function() {\n          log(\"Images loaded, starting parsing\");\n          log(\"Creating stacking contexts\");\n          this.createStackingContexts();\n          log(\"Sorting stacking contexts\");\n          this.sortStackingContexts(this.stack);\n          this.parse(this.stack);\n          log(\"Render queue created with \" + this.renderQueue.length + \" items\");\n          return new Promise(bind(function(resolve) {\n              if (!options.async) {\n                  this.renderQueue.forEach(this.paint, this);\n                  resolve();\n              } else if (typeof(options.async) === \"function\") {\n                  options.async.call(this, this.renderQueue, resolve);\n              } else if (this.renderQueue.length > 0){\n                  this.renderIndex = 0;\n                  this.asyncRenderer(this.renderQueue, resolve);\n              } else {\n                  resolve();\n              }\n          }, this));\n      }, this));\n  }\n\n  NodeParser.prototype.calculateOverflowClips = function() {\n      this.nodes.forEach(function(container) {\n          if (isElement(container)) {\n              if (isPseudoElement(container)) {\n                  container.appendToDOM();\n              }\n              container.borders = this.parseBorders(container);\n              var clip = (container.css('overflow') === \"hidden\") ? [container.borders.clip] : [];\n              var cssClip = container.parseClip();\n              if (cssClip && [\"absolute\", \"fixed\"].indexOf(container.css('position')) !== -1) {\n                  clip.push([[\"rect\",\n                          container.bounds.left + cssClip.left,\n                          container.bounds.top + cssClip.top,\n                          cssClip.right - cssClip.left,\n                          cssClip.bottom - cssClip.top\n                  ]]);\n              }\n              container.clip = hasParentClip(container) ? container.parent.clip.concat(clip) : clip;\n              container.backgroundClip = (container.css('overflow') !== \"hidden\") ? container.clip.concat([container.borders.clip]) : container.clip;\n              if (isPseudoElement(container)) {\n                  container.cleanDOM();\n              }\n          } else if (isTextNode(container)) {\n              container.clip = hasParentClip(container) ? container.parent.clip : [];\n          }\n          if (!isPseudoElement(container)) {\n              container.bounds = null;\n          }\n      }, this);\n  };\n\n  function hasParentClip(container) {\n      return container.parent && container.parent.clip.length;\n  }\n\n  NodeParser.prototype.asyncRenderer = function(queue, resolve, asyncTimer) {\n      asyncTimer = asyncTimer || Date.now();\n      this.paint(queue[this.renderIndex++]);\n      if (queue.length === this.renderIndex) {\n          resolve();\n      } else if (asyncTimer + 20 > Date.now()) {\n          this.asyncRenderer(queue, resolve, asyncTimer);\n      } else {\n          setTimeout(bind(function() {\n              this.asyncRenderer(queue, resolve);\n          }, this), 0);\n      }\n  };\n\n  NodeParser.prototype.createPseudoHideStyles = function(document) {\n      this.createStyles(document, '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + ':before { content: \"\" !important; display: none !important; }' +\n          '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER + ':after { content: \"\" !important; display: none !important; }');\n  };\n\n  NodeParser.prototype.disableAnimations = function(document) {\n      this.createStyles(document, '* { -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; animation: none !important; ' +\n          '-webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important;}');\n  };\n\n  NodeParser.prototype.createStyles = function(document, styles) {\n      var hidePseudoElements = document.createElement('style');\n      hidePseudoElements.innerHTML = styles;\n      document.body.appendChild(hidePseudoElements);\n  };\n\n  NodeParser.prototype.getPseudoElements = function(container) {\n      var nodes = [[container]];\n      if (container.node.nodeType === Node.ELEMENT_NODE) {\n          var before = this.getPseudoElement(container, \":before\");\n          var after = this.getPseudoElement(container, \":after\");\n\n          if (before) {\n              nodes.push(before);\n          }\n\n          if (after) {\n              nodes.push(after);\n          }\n      }\n      return flatten(nodes);\n  };\n\n  function toCamelCase(str) {\n      return str.replace(/(\\-[a-z])/g, function(match){\n          return match.toUpperCase().replace('-','');\n      });\n  }\n\n  NodeParser.prototype.getPseudoElement = function(container, type) {\n      var style = container.computedStyle(type);\n      if(!style || !style.content || style.content === \"none\" || style.content === \"-moz-alt-content\" || style.display === \"none\") {\n          return null;\n      }\n\n      var content = stripQuotes(style.content);\n      var isImage = content.substr(0, 3) === 'url';\n      var pseudoNode = document.createElement(isImage ? 'img' : 'html2canvaspseudoelement');\n      var pseudoContainer = new PseudoElementContainer(pseudoNode, container, type);\n\n      for (var i = style.length-1; i >= 0; i--) {\n          var property = toCamelCase(style.item(i));\n          pseudoNode.style[property] = style[property];\n      }\n\n      pseudoNode.className = PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + \" \" + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER;\n\n      if (isImage) {\n          pseudoNode.src = parseBackgrounds(content)[0].args[0];\n          return [pseudoContainer];\n      } else {\n          var text = document.createTextNode(content);\n          pseudoNode.appendChild(text);\n          return [pseudoContainer, new TextContainer(text, pseudoContainer)];\n      }\n  };\n\n\n  NodeParser.prototype.getChildren = function(parentContainer) {\n      return flatten([].filter.call(parentContainer.node.childNodes, renderableNode).map(function(node) {\n          var container = [node.nodeType === Node.TEXT_NODE ? new TextContainer(node, parentContainer) : new NodeContainer(node, parentContainer)].filter(nonIgnoredElement);\n          return node.nodeType === Node.ELEMENT_NODE && container.length && node.tagName !== \"TEXTAREA\" ? (container[0].isElementVisible() ? container.concat(this.getChildren(container[0])) : []) : container;\n      }, this));\n  };\n\n  NodeParser.prototype.newStackingContext = function(container, hasOwnStacking) {\n      var stack = new StackingContext(hasOwnStacking, container.getOpacity(), container.node, container.parent);\n      container.cloneTo(stack);\n      var parentStack = hasOwnStacking ? stack.getParentStack(this) : stack.parent.stack;\n      parentStack.contexts.push(stack);\n      container.stack = stack;\n  };\n\n  NodeParser.prototype.createStackingContexts = function() {\n      this.nodes.forEach(function(container) {\n          if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || container.hasTransform())) {\n              this.newStackingContext(container, true);\n          } else if (isElement(container) && ((isPositioned(container) && zIndex0(container)) || isInlineBlock(container) || isFloating(container))) {\n              this.newStackingContext(container, false);\n          } else {\n              container.assignStack(container.parent.stack);\n          }\n      }, this);\n  };\n\n  NodeParser.prototype.isBodyWithTransparentRoot = function(container) {\n      return container.node.nodeName === \"BODY\" && container.parent.color('backgroundColor').isTransparent();\n  };\n\n  NodeParser.prototype.isRootElement = function(container) {\n      return container.parent === null;\n  };\n\n  NodeParser.prototype.sortStackingContexts = function(stack) {\n      stack.contexts.sort(zIndexSort(stack.contexts.slice(0)));\n      stack.contexts.forEach(this.sortStackingContexts, this);\n  };\n\n  NodeParser.prototype.parseTextBounds = function(container) {\n      return function(text, index, textList) {\n          if (container.parent.css(\"textDecoration\").substr(0, 4) !== \"none\" || text.trim().length !== 0) {\n              if (this.support.rangeBounds && !container.parent.hasTransform()) {\n                  var offset = textList.slice(0, index).join(\"\").length;\n                  return this.getRangeBounds(container.node, offset, text.length);\n              } else if (container.node && typeof(container.node.data) === \"string\") {\n                  var replacementNode = container.node.splitText(text.length);\n                  var bounds = this.getWrapperBounds(container.node, container.parent.hasTransform());\n                  container.node = replacementNode;\n                  return bounds;\n              }\n          } else if(!this.support.rangeBounds || container.parent.hasTransform()){\n              container.node = container.node.splitText(text.length);\n          }\n          return {};\n      };\n  };\n\n  NodeParser.prototype.getWrapperBounds = function(node, transform) {\n      var wrapper = node.ownerDocument.createElement('html2canvaswrapper');\n      var parent = node.parentNode,\n          backupText = node.cloneNode(true);\n\n      wrapper.appendChild(node.cloneNode(true));\n      parent.replaceChild(wrapper, node);\n      var bounds = transform ? offsetBounds(wrapper) : getBounds(wrapper);\n      parent.replaceChild(backupText, wrapper);\n      return bounds;\n  };\n\n  NodeParser.prototype.getRangeBounds = function(node, offset, length) {\n      var range = this.range || (this.range = node.ownerDocument.createRange());\n      range.setStart(node, offset);\n      range.setEnd(node, offset + length);\n      return range.getBoundingClientRect();\n  };\n\n  function ClearTransform() {}\n\n  NodeParser.prototype.parse = function(stack) {\n      // http://www.w3.org/TR/CSS21/visuren.html#z-index\n      var negativeZindex = stack.contexts.filter(negativeZIndex); // 2. the child stacking contexts with negative stack levels (most negative first).\n      var descendantElements = stack.children.filter(isElement);\n      var descendantNonFloats = descendantElements.filter(not(isFloating));\n      var nonInlineNonPositionedDescendants = descendantNonFloats.filter(not(isPositioned)).filter(not(inlineLevel)); // 3 the in-flow, non-inline-level, non-positioned descendants.\n      var nonPositionedFloats = descendantElements.filter(not(isPositioned)).filter(isFloating); // 4. the non-positioned floats.\n      var inFlow = descendantNonFloats.filter(not(isPositioned)).filter(inlineLevel); // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.\n      var stackLevel0 = stack.contexts.concat(descendantNonFloats.filter(isPositioned)).filter(zIndex0); // 6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.\n      var text = stack.children.filter(isTextNode).filter(hasText);\n      var positiveZindex = stack.contexts.filter(positiveZIndex); // 7. the child stacking contexts with positive stack levels (least positive first).\n      negativeZindex.concat(nonInlineNonPositionedDescendants).concat(nonPositionedFloats)\n          .concat(inFlow).concat(stackLevel0).concat(text).concat(positiveZindex).forEach(function(container) {\n              this.renderQueue.push(container);\n              if (isStackingContext(container)) {\n                  this.parse(container);\n                  this.renderQueue.push(new ClearTransform());\n              }\n          }, this);\n  };\n\n  NodeParser.prototype.paint = function(container) {\n      try {\n          if (container instanceof ClearTransform) {\n              this.renderer.ctx.restore();\n          } else if (isTextNode(container)) {\n              if (isPseudoElement(container.parent)) {\n                  container.parent.appendToDOM();\n              }\n              this.paintText(container);\n              if (isPseudoElement(container.parent)) {\n                  container.parent.cleanDOM();\n              }\n          } else {\n              this.paintNode(container);\n          }\n      } catch(e) {\n          log(e);\n          if (this.options.strict) {\n              throw e;\n          }\n      }\n  };\n\n  NodeParser.prototype.paintNode = function(container) {\n      if (isStackingContext(container)) {\n          this.renderer.setOpacity(container.opacity);\n          this.renderer.ctx.save();\n          if (container.hasTransform()) {\n              this.renderer.setTransform(container.parseTransform());\n          }\n      }\n\n      if (container.node.nodeName === \"INPUT\" && container.node.type === \"checkbox\") {\n          this.paintCheckbox(container);\n      } else if (container.node.nodeName === \"INPUT\" && container.node.type === \"radio\") {\n          this.paintRadio(container);\n      } else {\n          this.paintElement(container);\n      }\n  };\n\n  NodeParser.prototype.paintElement = function(container) {\n      var bounds = container.parseBounds();\n      this.renderer.clip(container.backgroundClip, function() {\n          this.renderer.renderBackground(container, bounds, container.borders.borders.map(getWidth));\n      }, this);\n\n      this.renderer.clip(container.clip, function() {\n          this.renderer.renderBorders(container.borders.borders);\n      }, this);\n\n      this.renderer.clip(container.backgroundClip, function() {\n          switch (container.node.nodeName) {\n          case \"svg\":\n          case \"IFRAME\":\n              var imgContainer = this.images.get(container.node);\n              if (imgContainer) {\n                  this.renderer.renderImage(container, bounds, container.borders, imgContainer);\n              } else {\n                  log(\"Error loading <\" + container.node.nodeName + \">\", container.node);\n              }\n              break;\n          case \"IMG\":\n              var imageContainer = this.images.get(container.node.src);\n              if (imageContainer) {\n                  this.renderer.renderImage(container, bounds, container.borders, imageContainer);\n              } else {\n                  log(\"Error loading <img>\", container.node.src);\n              }\n              break;\n          case \"CANVAS\":\n              this.renderer.renderImage(container, bounds, container.borders, {image: container.node});\n              break;\n          case \"SELECT\":\n          case \"INPUT\":\n          case \"TEXTAREA\":\n              this.paintFormValue(container);\n              break;\n          }\n      }, this);\n  };\n\n  NodeParser.prototype.paintCheckbox = function(container) {\n      var b = container.parseBounds();\n\n      var size = Math.min(b.width, b.height);\n      var bounds = {width: size - 1, height: size - 1, top: b.top, left: b.left};\n      var r = [3, 3];\n      var radius = [r, r, r, r];\n      var borders = [1,1,1,1].map(function(w) {\n          return {color: new Color('#A5A5A5'), width: w};\n      });\n\n      var borderPoints = calculateCurvePoints(bounds, radius, borders);\n\n      this.renderer.clip(container.backgroundClip, function() {\n          this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, new Color(\"#DEDEDE\"));\n          this.renderer.renderBorders(calculateBorders(borders, bounds, borderPoints, radius));\n          if (container.node.checked) {\n              this.renderer.font(new Color('#424242'), 'normal', 'normal', 'bold', (size - 3) + \"px\", 'arial');\n              this.renderer.text(\"\\u2714\", bounds.left + size / 6, bounds.top + size - 1);\n          }\n      }, this);\n  };\n\n  NodeParser.prototype.paintRadio = function(container) {\n      var bounds = container.parseBounds();\n\n      var size = Math.min(bounds.width, bounds.height) - 2;\n\n      this.renderer.clip(container.backgroundClip, function() {\n          this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, new Color('#DEDEDE'), 1, new Color('#A5A5A5'));\n          if (container.node.checked) {\n              this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), new Color('#424242'));\n          }\n      }, this);\n  };\n\n  NodeParser.prototype.paintFormValue = function(container) {\n      var value = container.getValue();\n      if (value.length > 0) {\n          var document = container.node.ownerDocument;\n          var wrapper = document.createElement('html2canvaswrapper');\n          var properties = ['lineHeight', 'textAlign', 'fontFamily', 'fontWeight', 'fontSize', 'color',\n              'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom',\n              'width', 'height', 'borderLeftStyle', 'borderTopStyle', 'borderLeftWidth', 'borderTopWidth',\n              'boxSizing', 'whiteSpace', 'wordWrap'];\n\n          properties.forEach(function(property) {\n              try {\n                  wrapper.style[property] = container.css(property);\n              } catch(e) {\n                  // Older IE has issues with \"border\"\n                  log(\"html2canvas: Parse: Exception caught in renderFormValue: \" + e.message);\n              }\n          });\n          var bounds = container.parseBounds();\n          wrapper.style.position = \"fixed\";\n          wrapper.style.left = bounds.left + \"px\";\n          wrapper.style.top = bounds.top + \"px\";\n          wrapper.textContent = value;\n          document.body.appendChild(wrapper);\n          this.paintText(new TextContainer(wrapper.firstChild, container));\n          document.body.removeChild(wrapper);\n      }\n  };\n\n  NodeParser.prototype.paintText = function(container) {\n      container.applyTextTransform();\n      var characters = punycode.ucs2.decode(container.node.data);\n      var textList = (!this.options.letterRendering || noLetterSpacing(container)) && !hasUnicode(container.node.data) ? getWords(characters) : characters.map(function(character) {\n          return punycode.ucs2.encode([character]);\n      });\n\n      var weight = container.parent.fontWeight();\n      var size = container.parent.css('fontSize');\n      var family = container.parent.css('fontFamily');\n      var shadows = container.parent.parseTextShadows();\n\n      this.renderer.font(container.parent.color('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);\n      if (shadows.length) {\n          // TODO: support multiple text shadows\n          this.renderer.fontShadow(shadows[0].color, shadows[0].offsetX, shadows[0].offsetY, shadows[0].blur);\n      } else {\n          this.renderer.clearShadow();\n      }\n\n      this.renderer.clip(container.parent.clip, function() {\n          textList.map(this.parseTextBounds(container), this).forEach(function(bounds, index) {\n              if (bounds && /^\\s*$/.test(textList[index]) === false) {\n                  this.renderer.text(textList[index], bounds.left, bounds.bottom);\n                  this.renderTextDecoration(container.parent, bounds, this.fontMetrics.getMetrics(family, size));\n              }\n          }, this);\n      }, this);\n  };\n\n  NodeParser.prototype.renderTextDecoration = function(container, bounds, metrics) {\n      switch(container.css(\"textDecoration\").split(\" \")[0]) {\n      case \"underline\":\n          // Draws a line at the baseline of the font\n          // TODO As some browsers display the line as more than 1px if the font-size is big, need to take that into account both in position and size\n          this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.color(\"color\"));\n          break;\n      case \"overline\":\n          this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.color(\"color\"));\n          break;\n      case \"line-through\":\n          // TODO try and find exact position for line-through\n          this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.color(\"color\"));\n          break;\n      }\n  };\n\n  var borderColorTransforms = {\n      inset: [\n          [\"darken\", 0.60],\n          [\"darken\", 0.10],\n          [\"darken\", 0.10],\n          [\"darken\", 0.60]\n      ]\n  };\n\n  NodeParser.prototype.parseBorders = function(container) {\n      var nodeBounds = container.parseBounds();\n      var radius = getBorderRadiusData(container);\n      var borders = [\"Top\", \"Right\", \"Bottom\", \"Left\"].map(function(side, index) {\n          var style = container.css('border' + side + 'Style');\n          var color = container.color('border' + side + 'Color');\n          if (style === \"inset\" && color.isBlack()) {\n              color = new Color([255, 255, 255, color.a]); // this is wrong, but\n          }\n          var colorTransform = borderColorTransforms[style] ? borderColorTransforms[style][index] : null;\n          return {\n              width: container.cssInt('border' + side + 'Width'),\n              color: colorTransform ? color[colorTransform[0]](colorTransform[1]) : color,\n              args: null\n          };\n      });\n      var borderPoints = calculateCurvePoints(nodeBounds, radius, borders);\n\n      return {\n          clip: this.parseBackgroundClip(container, borderPoints, borders, radius, nodeBounds),\n          borders: calculateBorders(borders, nodeBounds, borderPoints, radius)\n      };\n  };\n\n  function calculateBorders(borders, nodeBounds, borderPoints, radius) {\n      return borders.map(function(border, borderSide) {\n          if (border.width > 0) {\n              var bx = nodeBounds.left;\n              var by = nodeBounds.top;\n              var bw = nodeBounds.width;\n              var bh = nodeBounds.height - (borders[2].width);\n\n              switch(borderSide) {\n              case 0:\n                  // top border\n                  bh = borders[0].width;\n                  border.args = drawSide({\n                          c1: [bx, by],\n                          c2: [bx + bw, by],\n                          c3: [bx + bw - borders[1].width, by + bh],\n                          c4: [bx + borders[3].width, by + bh]\n                      }, radius[0], radius[1],\n                      borderPoints.topLeftOuter, borderPoints.topLeftInner, borderPoints.topRightOuter, borderPoints.topRightInner);\n                  break;\n              case 1:\n                  // right border\n                  bx = nodeBounds.left + nodeBounds.width - (borders[1].width);\n                  bw = borders[1].width;\n\n                  border.args = drawSide({\n                          c1: [bx + bw, by],\n                          c2: [bx + bw, by + bh + borders[2].width],\n                          c3: [bx, by + bh],\n                          c4: [bx, by + borders[0].width]\n                      }, radius[1], radius[2],\n                      borderPoints.topRightOuter, borderPoints.topRightInner, borderPoints.bottomRightOuter, borderPoints.bottomRightInner);\n                  break;\n              case 2:\n                  // bottom border\n                  by = (by + nodeBounds.height) - (borders[2].width);\n                  bh = borders[2].width;\n                  border.args = drawSide({\n                          c1: [bx + bw, by + bh],\n                          c2: [bx, by + bh],\n                          c3: [bx + borders[3].width, by],\n                          c4: [bx + bw - borders[3].width, by]\n                      }, radius[2], radius[3],\n                      borderPoints.bottomRightOuter, borderPoints.bottomRightInner, borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner);\n                  break;\n              case 3:\n                  // left border\n                  bw = borders[3].width;\n                  border.args = drawSide({\n                          c1: [bx, by + bh + borders[2].width],\n                          c2: [bx, by],\n                          c3: [bx + bw, by + borders[0].width],\n                          c4: [bx + bw, by + bh]\n                      }, radius[3], radius[0],\n                      borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner, borderPoints.topLeftOuter, borderPoints.topLeftInner);\n                  break;\n              }\n          }\n          return border;\n      });\n  }\n\n  NodeParser.prototype.parseBackgroundClip = function(container, borderPoints, borders, radius, bounds) {\n      var backgroundClip = container.css('backgroundClip'),\n          borderArgs = [];\n\n      switch(backgroundClip) {\n      case \"content-box\":\n      case \"padding-box\":\n          parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftInner, borderPoints.topRightInner, bounds.left + borders[3].width, bounds.top + borders[0].width);\n          parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightInner, borderPoints.bottomRightInner, bounds.left + bounds.width - borders[1].width, bounds.top + borders[0].width);\n          parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightInner, borderPoints.bottomLeftInner, bounds.left + bounds.width - borders[1].width, bounds.top + bounds.height - borders[2].width);\n          parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftInner, borderPoints.topLeftInner, bounds.left + borders[3].width, bounds.top + bounds.height - borders[2].width);\n          break;\n\n      default:\n          parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftOuter, borderPoints.topRightOuter, bounds.left, bounds.top);\n          parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightOuter, borderPoints.bottomRightOuter, bounds.left + bounds.width, bounds.top);\n          parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightOuter, borderPoints.bottomLeftOuter, bounds.left + bounds.width, bounds.top + bounds.height);\n          parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftOuter, borderPoints.topLeftOuter, bounds.left, bounds.top + bounds.height);\n          break;\n      }\n\n      return borderArgs;\n  };\n\n  function getCurvePoints(x, y, r1, r2) {\n      var kappa = 4 * ((Math.sqrt(2) - 1) / 3);\n      var ox = (r1) * kappa, // control point offset horizontal\n          oy = (r2) * kappa, // control point offset vertical\n          xm = x + r1, // x-middle\n          ym = y + r2; // y-middle\n      return {\n          topLeft: bezierCurve({x: x, y: ym}, {x: x, y: ym - oy}, {x: xm - ox, y: y}, {x: xm, y: y}),\n          topRight: bezierCurve({x: x, y: y}, {x: x + ox,y: y}, {x: xm, y: ym - oy}, {x: xm, y: ym}),\n          bottomRight: bezierCurve({x: xm, y: y}, {x: xm, y: y + oy}, {x: x + ox, y: ym}, {x: x, y: ym}),\n          bottomLeft: bezierCurve({x: xm, y: ym}, {x: xm - ox, y: ym}, {x: x, y: y + oy}, {x: x, y:y})\n      };\n  }\n\n  function calculateCurvePoints(bounds, borderRadius, borders) {\n      var x = bounds.left,\n          y = bounds.top,\n          width = bounds.width,\n          height = bounds.height,\n\n          tlh = borderRadius[0][0] < width / 2 ? borderRadius[0][0] : width / 2,\n          tlv = borderRadius[0][1] < height / 2 ? borderRadius[0][1] : height / 2,\n          trh = borderRadius[1][0] < width / 2 ? borderRadius[1][0] : width / 2,\n          trv = borderRadius[1][1] < height / 2 ? borderRadius[1][1] : height / 2,\n          brh = borderRadius[2][0] < width / 2 ? borderRadius[2][0] : width / 2,\n          brv = borderRadius[2][1] < height / 2 ? borderRadius[2][1] : height / 2,\n          blh = borderRadius[3][0] < width / 2 ? borderRadius[3][0] : width / 2,\n          blv = borderRadius[3][1] < height / 2 ? borderRadius[3][1] : height / 2;\n\n      var topWidth = width - trh,\n          rightHeight = height - brv,\n          bottomWidth = width - brh,\n          leftHeight = height - blv;\n\n      return {\n          topLeftOuter: getCurvePoints(x, y, tlh, tlv).topLeft.subdivide(0.5),\n          topLeftInner: getCurvePoints(x + borders[3].width, y + borders[0].width, Math.max(0, tlh - borders[3].width), Math.max(0, tlv - borders[0].width)).topLeft.subdivide(0.5),\n          topRightOuter: getCurvePoints(x + topWidth, y, trh, trv).topRight.subdivide(0.5),\n          topRightInner: getCurvePoints(x + Math.min(topWidth, width + borders[3].width), y + borders[0].width, (topWidth > width + borders[3].width) ? 0 :trh - borders[3].width, trv - borders[0].width).topRight.subdivide(0.5),\n          bottomRightOuter: getCurvePoints(x + bottomWidth, y + rightHeight, brh, brv).bottomRight.subdivide(0.5),\n          bottomRightInner: getCurvePoints(x + Math.min(bottomWidth, width - borders[3].width), y + Math.min(rightHeight, height + borders[0].width), Math.max(0, brh - borders[1].width),  brv - borders[2].width).bottomRight.subdivide(0.5),\n          bottomLeftOuter: getCurvePoints(x, y + leftHeight, blh, blv).bottomLeft.subdivide(0.5),\n          bottomLeftInner: getCurvePoints(x + borders[3].width, y + leftHeight, Math.max(0, blh - borders[3].width), blv - borders[2].width).bottomLeft.subdivide(0.5)\n      };\n  }\n\n  function bezierCurve(start, startControl, endControl, end) {\n      var lerp = function (a, b, t) {\n          return {\n              x: a.x + (b.x - a.x) * t,\n              y: a.y + (b.y - a.y) * t\n          };\n      };\n\n      return {\n          start: start,\n          startControl: startControl,\n          endControl: endControl,\n          end: end,\n          subdivide: function(t) {\n              var ab = lerp(start, startControl, t),\n                  bc = lerp(startControl, endControl, t),\n                  cd = lerp(endControl, end, t),\n                  abbc = lerp(ab, bc, t),\n                  bccd = lerp(bc, cd, t),\n                  dest = lerp(abbc, bccd, t);\n              return [bezierCurve(start, ab, abbc, dest), bezierCurve(dest, bccd, cd, end)];\n          },\n          curveTo: function(borderArgs) {\n              borderArgs.push([\"bezierCurve\", startControl.x, startControl.y, endControl.x, endControl.y, end.x, end.y]);\n          },\n          curveToReversed: function(borderArgs) {\n              borderArgs.push([\"bezierCurve\", endControl.x, endControl.y, startControl.x, startControl.y, start.x, start.y]);\n          }\n      };\n  }\n\n  function drawSide(borderData, radius1, radius2, outer1, inner1, outer2, inner2) {\n      var borderArgs = [];\n\n      if (radius1[0] > 0 || radius1[1] > 0) {\n          borderArgs.push([\"line\", outer1[1].start.x, outer1[1].start.y]);\n          outer1[1].curveTo(borderArgs);\n      } else {\n          borderArgs.push([ \"line\", borderData.c1[0], borderData.c1[1]]);\n      }\n\n      if (radius2[0] > 0 || radius2[1] > 0) {\n          borderArgs.push([\"line\", outer2[0].start.x, outer2[0].start.y]);\n          outer2[0].curveTo(borderArgs);\n          borderArgs.push([\"line\", inner2[0].end.x, inner2[0].end.y]);\n          inner2[0].curveToReversed(borderArgs);\n      } else {\n          borderArgs.push([\"line\", borderData.c2[0], borderData.c2[1]]);\n          borderArgs.push([\"line\", borderData.c3[0], borderData.c3[1]]);\n      }\n\n      if (radius1[0] > 0 || radius1[1] > 0) {\n          borderArgs.push([\"line\", inner1[1].end.x, inner1[1].end.y]);\n          inner1[1].curveToReversed(borderArgs);\n      } else {\n          borderArgs.push([\"line\", borderData.c4[0], borderData.c4[1]]);\n      }\n\n      return borderArgs;\n  }\n\n  function parseCorner(borderArgs, radius1, radius2, corner1, corner2, x, y) {\n      if (radius1[0] > 0 || radius1[1] > 0) {\n          borderArgs.push([\"line\", corner1[0].start.x, corner1[0].start.y]);\n          corner1[0].curveTo(borderArgs);\n          corner1[1].curveTo(borderArgs);\n      } else {\n          borderArgs.push([\"line\", x, y]);\n      }\n\n      if (radius2[0] > 0 || radius2[1] > 0) {\n          borderArgs.push([\"line\", corner2[0].start.x, corner2[0].start.y]);\n      }\n  }\n\n  function negativeZIndex(container) {\n      return container.cssInt(\"zIndex\") < 0;\n  }\n\n  function positiveZIndex(container) {\n      return container.cssInt(\"zIndex\") > 0;\n  }\n\n  function zIndex0(container) {\n      return container.cssInt(\"zIndex\") === 0;\n  }\n\n  function inlineLevel(container) {\n      return [\"inline\", \"inline-block\", \"inline-table\"].indexOf(container.css(\"display\")) !== -1;\n  }\n\n  function isStackingContext(container) {\n      return (container instanceof StackingContext);\n  }\n\n  function hasText(container) {\n      return container.node.data.trim().length > 0;\n  }\n\n  function noLetterSpacing(container) {\n      return (/^(normal|none|0px)$/.test(container.parent.css(\"letterSpacing\")));\n  }\n\n  function getBorderRadiusData(container) {\n      return [\"TopLeft\", \"TopRight\", \"BottomRight\", \"BottomLeft\"].map(function(side) {\n          var value = container.css('border' + side + 'Radius');\n          var arr = value.split(\" \");\n          if (arr.length <= 1) {\n              arr[1] = arr[0];\n          }\n          return arr.map(asInt);\n      });\n  }\n\n  function renderableNode(node) {\n      return (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.ELEMENT_NODE);\n  }\n\n  function isPositionedForStacking(container) {\n      var position = container.css(\"position\");\n      var zIndex = ([\"absolute\", \"relative\", \"fixed\"].indexOf(position) !== -1) ? container.css(\"zIndex\") : \"auto\";\n      return zIndex !== \"auto\";\n  }\n\n  function isPositioned(container) {\n      return container.css(\"position\") !== \"static\";\n  }\n\n  function isFloating(container) {\n      return container.css(\"float\") !== \"none\";\n  }\n\n  function isInlineBlock(container) {\n      return [\"inline-block\", \"inline-table\"].indexOf(container.css(\"display\")) !== -1;\n  }\n\n  function not(callback) {\n      var context = this;\n      return function() {\n          return !callback.apply(context, arguments);\n      };\n  }\n\n  function isElement(container) {\n      return container.node.nodeType === Node.ELEMENT_NODE;\n  }\n\n  function isPseudoElement(container) {\n      return container.isPseudoElement === true;\n  }\n\n  function isTextNode(container) {\n      return container.node.nodeType === Node.TEXT_NODE;\n  }\n\n  function zIndexSort(contexts) {\n      return function(a, b) {\n          return (a.cssInt(\"zIndex\") + (contexts.indexOf(a) / contexts.length)) - (b.cssInt(\"zIndex\") + (contexts.indexOf(b) / contexts.length));\n      };\n  }\n\n  function hasOpacity(container) {\n      return container.getOpacity() < 1;\n  }\n\n  function asInt(value) {\n      return parseInt(value, 10);\n  }\n\n  function getWidth(border) {\n      return border.width;\n  }\n\n  function nonIgnoredElement(nodeContainer) {\n      return (nodeContainer.node.nodeType !== Node.ELEMENT_NODE || [\"SCRIPT\", \"HEAD\", \"TITLE\", \"OBJECT\", \"BR\", \"OPTION\"].indexOf(nodeContainer.node.nodeName) === -1);\n  }\n\n  function flatten(arrays) {\n      return [].concat.apply([], arrays);\n  }\n\n  function stripQuotes(content) {\n      var first = content.substr(0, 1);\n      return (first === content.substr(content.length - 1) && first.match(/'|\"/)) ? content.substr(1, content.length - 2) : content;\n  }\n\n  function getWords(characters) {\n      var words = [], i = 0, onWordBoundary = false, word;\n      while(characters.length) {\n          if (isWordBoundary(characters[i]) === onWordBoundary) {\n              word = characters.splice(0, i);\n              if (word.length) {\n                  words.push(punycode.ucs2.encode(word));\n              }\n              onWordBoundary =! onWordBoundary;\n              i = 0;\n          } else {\n              i++;\n          }\n\n          if (i >= characters.length) {\n              word = characters.splice(0, i);\n              if (word.length) {\n                  words.push(punycode.ucs2.encode(word));\n              }\n          }\n      }\n      return words;\n  }\n\n  function isWordBoundary(characterCode) {\n      return [\n          32, // <space>\n          13, // \\r\n          10, // \\n\n          9, // \\t\n          45 // -\n      ].indexOf(characterCode) !== -1;\n  }\n\n  function hasUnicode(string) {\n      return (/[^\\u0000-\\u00ff]/).test(string);\n  }\n\n  module.exports = NodeParser;\n\n  },{\"./color\":3,\"./fontmetrics\":7,\"./log\":13,\"./nodecontainer\":14,\"./pseudoelementcontainer\":18,\"./stackingcontext\":21,\"./textcontainer\":25,\"./utils\":26,\"punycode\":1}],16:[function(_dereq_,module,exports){\n  var XHR = _dereq_('./xhr');\n  var utils = _dereq_('./utils');\n  var log = _dereq_('./log');\n  var createWindowClone = _dereq_('./clone');\n  var decode64 = utils.decode64;\n\n  function Proxy(src, proxyUrl, document) {\n      var supportsCORS = ('withCredentials' in new XMLHttpRequest());\n      if (!proxyUrl) {\n          return Promise.reject(\"No proxy configured\");\n      }\n      var callback = createCallback(supportsCORS);\n      var url = createProxyUrl(proxyUrl, src, callback);\n\n      return supportsCORS ? XHR(url) : (jsonp(document, url, callback).then(function(response) {\n          return decode64(response.content);\n      }));\n  }\n  var proxyCount = 0;\n\n  function ProxyURL(src, proxyUrl, document) {\n      var supportsCORSImage = ('crossOrigin' in new Image());\n      var callback = createCallback(supportsCORSImage);\n      var url = createProxyUrl(proxyUrl, src, callback);\n      return (supportsCORSImage ? Promise.resolve(url) : jsonp(document, url, callback).then(function(response) {\n          return \"data:\" + response.type + \";base64,\" + response.content;\n      }));\n  }\n\n  function jsonp(document, url, callback) {\n      return new Promise(function(resolve, reject) {\n          var s = document.createElement(\"script\");\n          var cleanup = function() {\n              delete window.html2canvas.proxy[callback];\n              document.body.removeChild(s);\n          };\n          window.html2canvas.proxy[callback] = function(response) {\n              cleanup();\n              resolve(response);\n          };\n          s.src = url;\n          s.onerror = function(e) {\n              cleanup();\n              reject(e);\n          };\n          document.body.appendChild(s);\n      });\n  }\n\n  function createCallback(useCORS) {\n      return !useCORS ? \"html2canvas_\" + Date.now() + \"_\" + (++proxyCount) + \"_\" + Math.round(Math.random() * 100000) : \"\";\n  }\n\n  function createProxyUrl(proxyUrl, src, callback) {\n      return proxyUrl + \"?url=\" + encodeURIComponent(src) + (callback.length ? \"&callback=html2canvas.proxy.\" + callback : \"\");\n  }\n\n  function documentFromHTML(src) {\n      return function(html) {\n          var parser = new DOMParser(), doc;\n          try {\n              doc = parser.parseFromString(html, \"text/html\");\n          } catch(e) {\n              log(\"DOMParser not supported, falling back to createHTMLDocument\");\n              doc = document.implementation.createHTMLDocument(\"\");\n              try {\n                  doc.open();\n                  doc.write(html);\n                  doc.close();\n              } catch(ee) {\n                  log(\"createHTMLDocument write not supported, falling back to document.body.innerHTML\");\n                  doc.body.innerHTML = html; // ie9 doesnt support writing to documentElement\n              }\n          }\n\n          var b = doc.querySelector(\"base\");\n          if (!b || !b.href.host) {\n              var base = doc.createElement(\"base\");\n              base.href = src;\n              doc.head.insertBefore(base, doc.head.firstChild);\n          }\n\n          return doc;\n      };\n  }\n\n  function loadUrlDocument(src, proxy, document, width, height, options) {\n      return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) {\n          return createWindowClone(doc, document, width, height, options, 0, 0);\n      });\n  }\n\n  exports.Proxy = Proxy;\n  exports.ProxyURL = ProxyURL;\n  exports.loadUrlDocument = loadUrlDocument;\n\n  },{\"./clone\":2,\"./log\":13,\"./utils\":26,\"./xhr\":28}],17:[function(_dereq_,module,exports){\n  var ProxyURL = _dereq_('./proxy').ProxyURL;\n\n  function ProxyImageContainer(src, proxy) {\n      var link = document.createElement(\"a\");\n      link.href = src;\n      src = link.href;\n      this.src = src;\n      this.image = new Image();\n      var self = this;\n      this.promise = new Promise(function(resolve, reject) {\n          self.image.crossOrigin = \"Anonymous\";\n          self.image.onload = resolve;\n          self.image.onerror = reject;\n\n          new ProxyURL(src, proxy, document).then(function(url) {\n              self.image.src = url;\n          })['catch'](reject);\n      });\n  }\n\n  module.exports = ProxyImageContainer;\n\n  },{\"./proxy\":16}],18:[function(_dereq_,module,exports){\n  var NodeContainer = _dereq_('./nodecontainer');\n\n  function PseudoElementContainer(node, parent, type) {\n      NodeContainer.call(this, node, parent);\n      this.isPseudoElement = true;\n      this.before = type === \":before\";\n  }\n\n  PseudoElementContainer.prototype.cloneTo = function(stack) {\n      PseudoElementContainer.prototype.cloneTo.call(this, stack);\n      stack.isPseudoElement = true;\n      stack.before = this.before;\n  };\n\n  PseudoElementContainer.prototype = Object.create(NodeContainer.prototype);\n\n  PseudoElementContainer.prototype.appendToDOM = function() {\n      if (this.before) {\n          this.parent.node.insertBefore(this.node, this.parent.node.firstChild);\n      } else {\n          this.parent.node.appendChild(this.node);\n      }\n      this.parent.node.className += \" \" + this.getHideClass();\n  };\n\n  PseudoElementContainer.prototype.cleanDOM = function() {\n      this.node.parentNode.removeChild(this.node);\n      this.parent.node.className = this.parent.node.className.replace(this.getHideClass(), \"\");\n  };\n\n  PseudoElementContainer.prototype.getHideClass = function() {\n      return this[\"PSEUDO_HIDE_ELEMENT_CLASS_\" + (this.before ? \"BEFORE\" : \"AFTER\")];\n  };\n\n  PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE = \"___html2canvas___pseudoelement_before\";\n  PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER = \"___html2canvas___pseudoelement_after\";\n\n  module.exports = PseudoElementContainer;\n\n  },{\"./nodecontainer\":14}],19:[function(_dereq_,module,exports){\n  var log = _dereq_('./log');\n\n  function Renderer(width, height, images, options, document) {\n      this.width = width;\n      this.height = height;\n      this.images = images;\n      this.options = options;\n      this.document = document;\n  }\n\n  Renderer.prototype.renderImage = function(container, bounds, borderData, imageContainer) {\n      var paddingLeft = container.cssInt('paddingLeft'),\n          paddingTop = container.cssInt('paddingTop'),\n          paddingRight = container.cssInt('paddingRight'),\n          paddingBottom = container.cssInt('paddingBottom'),\n          borders = borderData.borders;\n\n      var width = bounds.width - (borders[1].width + borders[3].width + paddingLeft + paddingRight);\n      var height = bounds.height - (borders[0].width + borders[2].width + paddingTop + paddingBottom);\n      this.drawImage(\n          imageContainer,\n          0,\n          0,\n          imageContainer.image.width || width,\n          imageContainer.image.height || height,\n          bounds.left + paddingLeft + borders[3].width,\n          bounds.top + paddingTop + borders[0].width,\n          width,\n          height\n      );\n  };\n\n  Renderer.prototype.renderBackground = function(container, bounds, borderData) {\n      if (bounds.height > 0 && bounds.width > 0) {\n          this.renderBackgroundColor(container, bounds);\n          this.renderBackgroundImage(container, bounds, borderData);\n      }\n  };\n\n  Renderer.prototype.renderBackgroundColor = function(container, bounds) {\n      var color = container.color(\"backgroundColor\");\n      if (!color.isTransparent()) {\n          this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, color);\n      }\n  };\n\n  Renderer.prototype.renderBorders = function(borders) {\n      borders.forEach(this.renderBorder, this);\n  };\n\n  Renderer.prototype.renderBorder = function(data) {\n      if (!data.color.isTransparent() && data.args !== null) {\n          this.drawShape(data.args, data.color);\n      }\n  };\n\n  Renderer.prototype.renderBackgroundImage = function(container, bounds, borderData) {\n      var backgroundImages = container.parseBackgroundImages();\n      backgroundImages.reverse().forEach(function(backgroundImage, index, arr) {\n          switch(backgroundImage.method) {\n          case \"url\":\n              var image = this.images.get(backgroundImage.args[0]);\n              if (image) {\n                  this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);\n              } else {\n                  log(\"Error loading background-image\", backgroundImage.args[0]);\n              }\n              break;\n          case \"linear-gradient\":\n          case \"gradient\":\n              var gradientImage = this.images.get(backgroundImage.value);\n              if (gradientImage) {\n                  this.renderBackgroundGradient(gradientImage, bounds, borderData);\n              } else {\n                  log(\"Error loading background-image\", backgroundImage.args[0]);\n              }\n              break;\n          case \"none\":\n              break;\n          default:\n              log(\"Unknown background-image type\", backgroundImage.args[0]);\n          }\n      }, this);\n  };\n\n  Renderer.prototype.renderBackgroundRepeating = function(container, bounds, imageContainer, index, borderData) {\n      var size = container.parseBackgroundSize(bounds, imageContainer.image, index);\n      var position = container.parseBackgroundPosition(bounds, imageContainer.image, index, size);\n      var repeat = container.parseBackgroundRepeat(index);\n      switch (repeat) {\n      case \"repeat-x\":\n      case \"repeat no-repeat\":\n          this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + borderData[3], bounds.top + position.top + borderData[0], 99999, size.height, borderData);\n          break;\n      case \"repeat-y\":\n      case \"no-repeat repeat\":\n          this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + borderData[0], size.width, 99999, borderData);\n          break;\n      case \"no-repeat\":\n          this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + position.top + borderData[0], size.width, size.height, borderData);\n          break;\n      default:\n          this.renderBackgroundRepeat(imageContainer, position, size, {top: bounds.top, left: bounds.left}, borderData[3], borderData[0]);\n          break;\n      }\n  };\n\n  module.exports = Renderer;\n\n  },{\"./log\":13}],20:[function(_dereq_,module,exports){\n  var Renderer = _dereq_('../renderer');\n  var LinearGradientContainer = _dereq_('../lineargradientcontainer');\n  var log = _dereq_('../log');\n\n  function CanvasRenderer(width, height) {\n      Renderer.apply(this, arguments);\n      this.canvas = this.options.canvas || this.document.createElement(\"canvas\");\n      if (!this.options.canvas) {\n          this.canvas.width = width;\n          this.canvas.height = height;\n      }\n      this.ctx = this.canvas.getContext(\"2d\");\n      this.taintCtx = this.document.createElement(\"canvas\").getContext(\"2d\");\n      this.ctx.textBaseline = \"bottom\";\n      this.variables = {};\n      log(\"Initialized CanvasRenderer with size\", width, \"x\", height);\n  }\n\n  CanvasRenderer.prototype = Object.create(Renderer.prototype);\n\n  CanvasRenderer.prototype.setFillStyle = function(fillStyle) {\n      this.ctx.fillStyle = typeof(fillStyle) === \"object\" && !!fillStyle.isColor ? fillStyle.toString() : fillStyle;\n      return this.ctx;\n  };\n\n  CanvasRenderer.prototype.rectangle = function(left, top, width, height, color) {\n      this.setFillStyle(color).fillRect(left, top, width, height);\n  };\n\n  CanvasRenderer.prototype.circle = function(left, top, size, color) {\n      this.setFillStyle(color);\n      this.ctx.beginPath();\n      this.ctx.arc(left + size / 2, top + size / 2, size / 2, 0, Math.PI*2, true);\n      this.ctx.closePath();\n      this.ctx.fill();\n  };\n\n  CanvasRenderer.prototype.circleStroke = function(left, top, size, color, stroke, strokeColor) {\n      this.circle(left, top, size, color);\n      this.ctx.strokeStyle = strokeColor.toString();\n      this.ctx.stroke();\n  };\n\n  CanvasRenderer.prototype.drawShape = function(shape, color) {\n      this.shape(shape);\n      this.setFillStyle(color).fill();\n  };\n\n  CanvasRenderer.prototype.taints = function(imageContainer) {\n      if (imageContainer.tainted === null) {\n          this.taintCtx.drawImage(imageContainer.image, 0, 0);\n          try {\n              this.taintCtx.getImageData(0, 0, 1, 1);\n              imageContainer.tainted = false;\n          } catch(e) {\n              this.taintCtx = document.createElement(\"canvas\").getContext(\"2d\");\n              imageContainer.tainted = true;\n          }\n      }\n\n      return imageContainer.tainted;\n  };\n\n  CanvasRenderer.prototype.drawImage = function(imageContainer, sx, sy, sw, sh, dx, dy, dw, dh) {\n      if (!this.taints(imageContainer) || this.options.allowTaint) {\n          this.ctx.drawImage(imageContainer.image, sx, sy, sw, sh, dx, dy, dw, dh);\n      }\n  };\n\n  CanvasRenderer.prototype.clip = function(shapes, callback, context) {\n      this.ctx.save();\n      shapes.filter(hasEntries).forEach(function(shape) {\n          this.shape(shape).clip();\n      }, this);\n      callback.call(context);\n      this.ctx.restore();\n  };\n\n  CanvasRenderer.prototype.shape = function(shape) {\n      this.ctx.beginPath();\n      shape.forEach(function(point, index) {\n          if (point[0] === \"rect\") {\n              this.ctx.rect.apply(this.ctx, point.slice(1));\n          } else {\n              this.ctx[(index === 0) ? \"moveTo\" : point[0] + \"To\" ].apply(this.ctx, point.slice(1));\n          }\n      }, this);\n      this.ctx.closePath();\n      return this.ctx;\n  };\n\n  CanvasRenderer.prototype.font = function(color, style, variant, weight, size, family) {\n      this.setFillStyle(color).font = [style, variant, weight, size, family].join(\" \").split(\",\")[0];\n  };\n\n  CanvasRenderer.prototype.fontShadow = function(color, offsetX, offsetY, blur) {\n      this.setVariable(\"shadowColor\", color.toString())\n          .setVariable(\"shadowOffsetY\", offsetX)\n          .setVariable(\"shadowOffsetX\", offsetY)\n          .setVariable(\"shadowBlur\", blur);\n  };\n\n  CanvasRenderer.prototype.clearShadow = function() {\n      this.setVariable(\"shadowColor\", \"rgba(0,0,0,0)\");\n  };\n\n  CanvasRenderer.prototype.setOpacity = function(opacity) {\n      this.ctx.globalAlpha = opacity;\n  };\n\n  CanvasRenderer.prototype.setTransform = function(transform) {\n      this.ctx.translate(transform.origin[0], transform.origin[1]);\n      this.ctx.transform.apply(this.ctx, transform.matrix);\n      this.ctx.translate(-transform.origin[0], -transform.origin[1]);\n  };\n\n  CanvasRenderer.prototype.setVariable = function(property, value) {\n      if (this.variables[property] !== value) {\n          this.variables[property] = this.ctx[property] = value;\n      }\n\n      return this;\n  };\n\n  CanvasRenderer.prototype.text = function(text, left, bottom) {\n      this.ctx.fillText(text, left, bottom);\n  };\n\n  CanvasRenderer.prototype.backgroundRepeatShape = function(imageContainer, backgroundPosition, size, bounds, left, top, width, height, borderData) {\n      var shape = [\n          [\"line\", Math.round(left), Math.round(top)],\n          [\"line\", Math.round(left + width), Math.round(top)],\n          [\"line\", Math.round(left + width), Math.round(height + top)],\n          [\"line\", Math.round(left), Math.round(height + top)]\n      ];\n      this.clip([shape], function() {\n          this.renderBackgroundRepeat(imageContainer, backgroundPosition, size, bounds, borderData[3], borderData[0]);\n      }, this);\n  };\n\n  CanvasRenderer.prototype.renderBackgroundRepeat = function(imageContainer, backgroundPosition, size, bounds, borderLeft, borderTop) {\n      var offsetX = Math.round(bounds.left + backgroundPosition.left + borderLeft), offsetY = Math.round(bounds.top + backgroundPosition.top + borderTop);\n      this.setFillStyle(this.ctx.createPattern(this.resizeImage(imageContainer, size), \"repeat\"));\n      this.ctx.translate(offsetX, offsetY);\n      this.ctx.fill();\n      this.ctx.translate(-offsetX, -offsetY);\n  };\n\n  CanvasRenderer.prototype.renderBackgroundGradient = function(gradientImage, bounds) {\n      if (gradientImage instanceof LinearGradientContainer) {\n          var gradient = this.ctx.createLinearGradient(\n              bounds.left + bounds.width * gradientImage.x0,\n              bounds.top + bounds.height * gradientImage.y0,\n              bounds.left +  bounds.width * gradientImage.x1,\n              bounds.top +  bounds.height * gradientImage.y1);\n          gradientImage.colorStops.forEach(function(colorStop) {\n              gradient.addColorStop(colorStop.stop, colorStop.color.toString());\n          });\n          this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, gradient);\n      }\n  };\n\n  CanvasRenderer.prototype.resizeImage = function(imageContainer, size) {\n      var image = imageContainer.image;\n      if(image.width === size.width && image.height === size.height) {\n          return image;\n      }\n\n      var ctx, canvas = document.createElement('canvas');\n      canvas.width = size.width;\n      canvas.height = size.height;\n      ctx = canvas.getContext(\"2d\");\n      ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, size.width, size.height );\n      return canvas;\n  };\n\n  function hasEntries(array) {\n      return array.length > 0;\n  }\n\n  module.exports = CanvasRenderer;\n\n  },{\"../lineargradientcontainer\":12,\"../log\":13,\"../renderer\":19}],21:[function(_dereq_,module,exports){\n  var NodeContainer = _dereq_('./nodecontainer');\n\n  function StackingContext(hasOwnStacking, opacity, element, parent) {\n      NodeContainer.call(this, element, parent);\n      this.ownStacking = hasOwnStacking;\n      this.contexts = [];\n      this.children = [];\n      this.opacity = (this.parent ? this.parent.stack.opacity : 1) * opacity;\n  }\n\n  StackingContext.prototype = Object.create(NodeContainer.prototype);\n\n  StackingContext.prototype.getParentStack = function(context) {\n      var parentStack = (this.parent) ? this.parent.stack : null;\n      return parentStack ? (parentStack.ownStacking ? parentStack : parentStack.getParentStack(context)) : context.stack;\n  };\n\n  module.exports = StackingContext;\n\n  },{\"./nodecontainer\":14}],22:[function(_dereq_,module,exports){\n  function Support(document) {\n      this.rangeBounds = this.testRangeBounds(document);\n      this.cors = this.testCORS();\n      this.svg = this.testSVG();\n  }\n\n  Support.prototype.testRangeBounds = function(document) {\n      var range, testElement, rangeBounds, rangeHeight, support = false;\n\n      if (document.createRange) {\n          range = document.createRange();\n          if (range.getBoundingClientRect) {\n              testElement = document.createElement('boundtest');\n              testElement.style.height = \"123px\";\n              testElement.style.display = \"block\";\n              document.body.appendChild(testElement);\n\n              range.selectNode(testElement);\n              rangeBounds = range.getBoundingClientRect();\n              rangeHeight = rangeBounds.height;\n\n              if (rangeHeight === 123) {\n                  support = true;\n              }\n              document.body.removeChild(testElement);\n          }\n      }\n\n      return support;\n  };\n\n  Support.prototype.testCORS = function() {\n      return typeof((new Image()).crossOrigin) !== \"undefined\";\n  };\n\n  Support.prototype.testSVG = function() {\n      var img = new Image();\n      var canvas = document.createElement(\"canvas\");\n      var ctx =  canvas.getContext(\"2d\");\n      img.src = \"data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>\";\n\n      try {\n          ctx.drawImage(img, 0, 0);\n          canvas.toDataURL();\n      } catch(e) {\n          return false;\n      }\n      return true;\n  };\n\n  module.exports = Support;\n\n  },{}],23:[function(_dereq_,module,exports){\n  var XHR = _dereq_('./xhr');\n  var decode64 = _dereq_('./utils').decode64;\n\n  function SVGContainer(src) {\n      this.src = src;\n      this.image = null;\n      var self = this;\n\n      this.promise = this.hasFabric().then(function() {\n          return (self.isInline(src) ? Promise.resolve(self.inlineFormatting(src)) : XHR(src));\n      }).then(function(svg) {\n          return new Promise(function(resolve) {\n              window.html2canvas.svg.fabric.loadSVGFromString(svg, self.createCanvas.call(self, resolve));\n          });\n      });\n  }\n\n  SVGContainer.prototype.hasFabric = function() {\n      return !window.html2canvas.svg || !window.html2canvas.svg.fabric ? Promise.reject(new Error(\"html2canvas.svg.js is not loaded, cannot render svg\")) : Promise.resolve();\n  };\n\n  SVGContainer.prototype.inlineFormatting = function(src) {\n      return (/^data:image\\/svg\\+xml;base64,/.test(src)) ? this.decode64(this.removeContentType(src)) : this.removeContentType(src);\n  };\n\n  SVGContainer.prototype.removeContentType = function(src) {\n      return src.replace(/^data:image\\/svg\\+xml(;base64)?,/,'');\n  };\n\n  SVGContainer.prototype.isInline = function(src) {\n      return (/^data:image\\/svg\\+xml/i.test(src));\n  };\n\n  SVGContainer.prototype.createCanvas = function(resolve) {\n      var self = this;\n      return function (objects, options) {\n          var canvas = new window.html2canvas.svg.fabric.StaticCanvas('c');\n          self.image = canvas.lowerCanvasEl;\n          canvas\n              .setWidth(options.width)\n              .setHeight(options.height)\n              .add(window.html2canvas.svg.fabric.util.groupSVGElements(objects, options))\n              .renderAll();\n          resolve(canvas.lowerCanvasEl);\n      };\n  };\n\n  SVGContainer.prototype.decode64 = function(str) {\n      return (typeof(window.atob) === \"function\") ? window.atob(str) : decode64(str);\n  };\n\n  module.exports = SVGContainer;\n\n  },{\"./utils\":26,\"./xhr\":28}],24:[function(_dereq_,module,exports){\n  var SVGContainer = _dereq_('./svgcontainer');\n\n  function SVGNodeContainer(node, _native) {\n      this.src = node;\n      this.image = null;\n      var self = this;\n\n      this.promise = _native ? new Promise(function(resolve, reject) {\n          self.image = new Image();\n          self.image.onload = resolve;\n          self.image.onerror = reject;\n          self.image.src = \"data:image/svg+xml,\" + (new XMLSerializer()).serializeToString(node);\n          if (self.image.complete === true) {\n              resolve(self.image);\n          }\n      }) : this.hasFabric().then(function() {\n          return new Promise(function(resolve) {\n              window.html2canvas.svg.fabric.parseSVGDocument(node, self.createCanvas.call(self, resolve));\n          });\n      });\n  }\n\n  SVGNodeContainer.prototype = Object.create(SVGContainer.prototype);\n\n  module.exports = SVGNodeContainer;\n\n  },{\"./svgcontainer\":23}],25:[function(_dereq_,module,exports){\n  var NodeContainer = _dereq_('./nodecontainer');\n\n  function TextContainer(node, parent) {\n      NodeContainer.call(this, node, parent);\n  }\n\n  TextContainer.prototype = Object.create(NodeContainer.prototype);\n\n  TextContainer.prototype.applyTextTransform = function() {\n      this.node.data = this.transform(this.parent.css(\"textTransform\"));\n  };\n\n  TextContainer.prototype.transform = function(transform) {\n      var text = this.node.data;\n      switch(transform){\n          case \"lowercase\":\n              return text.toLowerCase();\n          case \"capitalize\":\n              return text.replace(/(^|\\s|:|-|\\(|\\))([a-z])/g, capitalize);\n          case \"uppercase\":\n              return text.toUpperCase();\n          default:\n              return text;\n      }\n  };\n\n  function capitalize(m, p1, p2) {\n      if (m.length > 0) {\n          return p1 + p2.toUpperCase();\n      }\n  }\n\n  module.exports = TextContainer;\n\n  },{\"./nodecontainer\":14}],26:[function(_dereq_,module,exports){\n  exports.smallImage = function smallImage() {\n      return \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\";\n  };\n\n  exports.bind = function(callback, context) {\n      return function() {\n          return callback.apply(context, arguments);\n      };\n  };\n\n  /*\n   * base64-arraybuffer\n   * https://github.com/niklasvh/base64-arraybuffer\n   *\n   * Copyright (c) 2012 Niklas von Hertzen\n   * Licensed under the MIT license.\n   */\n\n  exports.decode64 = function(base64) {\n      var chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n      var len = base64.length, i, encoded1, encoded2, encoded3, encoded4, byte1, byte2, byte3;\n\n      var output = \"\";\n\n      for (i = 0; i < len; i+=4) {\n          encoded1 = chars.indexOf(base64[i]);\n          encoded2 = chars.indexOf(base64[i+1]);\n          encoded3 = chars.indexOf(base64[i+2]);\n          encoded4 = chars.indexOf(base64[i+3]);\n\n          byte1 = (encoded1 << 2) | (encoded2 >> 4);\n          byte2 = ((encoded2 & 15) << 4) | (encoded3 >> 2);\n          byte3 = ((encoded3 & 3) << 6) | encoded4;\n          if (encoded3 === 64) {\n              output += String.fromCharCode(byte1);\n          } else if (encoded4 === 64 || encoded4 === -1) {\n              output += String.fromCharCode(byte1, byte2);\n          } else{\n              output += String.fromCharCode(byte1, byte2, byte3);\n          }\n      }\n\n      return output;\n  };\n\n  exports.getBounds = function(node) {\n      if (node.getBoundingClientRect) {\n          var clientRect = node.getBoundingClientRect();\n          var width = node.offsetWidth == null ? clientRect.width : node.offsetWidth;\n          return {\n              top: clientRect.top,\n              bottom: clientRect.bottom || (clientRect.top + clientRect.height),\n              right: clientRect.left + width,\n              left: clientRect.left,\n              width:  width,\n              height: node.offsetHeight == null ? clientRect.height : node.offsetHeight\n          };\n      }\n      return {};\n  };\n\n  exports.offsetBounds = function(node) {\n      var parent = node.offsetParent ? exports.offsetBounds(node.offsetParent) : {top: 0, left: 0};\n\n      return {\n          top: node.offsetTop + parent.top,\n          bottom: node.offsetTop + node.offsetHeight + parent.top,\n          right: node.offsetLeft + parent.left + node.offsetWidth,\n          left: node.offsetLeft + parent.left,\n          width: node.offsetWidth,\n          height: node.offsetHeight\n      };\n  };\n\n  exports.parseBackgrounds = function(backgroundImage) {\n      var whitespace = ' \\r\\n\\t',\n          method, definition, prefix, prefix_i, block, results = [],\n          mode = 0, numParen = 0, quote, args;\n      var appendResult = function() {\n          if(method) {\n              if (definition.substr(0, 1) === '\"') {\n                  definition = definition.substr(1, definition.length - 2);\n              }\n              if (definition) {\n                  args.push(definition);\n              }\n              if (method.substr(0, 1) === '-' && (prefix_i = method.indexOf('-', 1 ) + 1) > 0) {\n                  prefix = method.substr(0, prefix_i);\n                  method = method.substr(prefix_i);\n              }\n              results.push({\n                  prefix: prefix,\n                  method: method.toLowerCase(),\n                  value: block,\n                  args: args,\n                  image: null\n              });\n          }\n          args = [];\n          method = prefix = definition = block = '';\n      };\n      args = [];\n      method = prefix = definition = block = '';\n      backgroundImage.split(\"\").forEach(function(c) {\n          if (mode === 0 && whitespace.indexOf(c) > -1) {\n              return;\n          }\n          switch(c) {\n          case '\"':\n              if(!quote) {\n                  quote = c;\n              } else if(quote === c) {\n                  quote = null;\n              }\n              break;\n          case '(':\n              if(quote) {\n                  break;\n              } else if(mode === 0) {\n                  mode = 1;\n                  block += c;\n                  return;\n              } else {\n                  numParen++;\n              }\n              break;\n          case ')':\n              if (quote) {\n                  break;\n              } else if(mode === 1) {\n                  if(numParen === 0) {\n                      mode = 0;\n                      block += c;\n                      appendResult();\n                      return;\n                  } else {\n                      numParen--;\n                  }\n              }\n              break;\n\n          case ',':\n              if (quote) {\n                  break;\n              } else if(mode === 0) {\n                  appendResult();\n                  return;\n              } else if (mode === 1) {\n                  if (numParen === 0 && !method.match(/^url$/i)) {\n                      args.push(definition);\n                      definition = '';\n                      block += c;\n                      return;\n                  }\n              }\n              break;\n          }\n\n          block += c;\n          if (mode === 0) {\n              method += c;\n          } else {\n              definition += c;\n          }\n      });\n\n      appendResult();\n      return results;\n  };\n\n  },{}],27:[function(_dereq_,module,exports){\n  var GradientContainer = _dereq_('./gradientcontainer');\n\n  function WebkitGradientContainer(imageData) {\n      GradientContainer.apply(this, arguments);\n      this.type = imageData.args[0] === \"linear\" ? GradientContainer.TYPES.LINEAR : GradientContainer.TYPES.RADIAL;\n  }\n\n  WebkitGradientContainer.prototype = Object.create(GradientContainer.prototype);\n\n  module.exports = WebkitGradientContainer;\n\n  },{\"./gradientcontainer\":9}],28:[function(_dereq_,module,exports){\n  function XHR(url) {\n      return new Promise(function(resolve, reject) {\n          var xhr = new XMLHttpRequest();\n          xhr.open('GET', url);\n\n          xhr.onload = function() {\n              if (xhr.status === 200) {\n                  resolve(xhr.responseText);\n              } else {\n                  reject(new Error(xhr.statusText));\n              }\n          };\n\n          xhr.onerror = function() {\n              reject(new Error(\"Network Error\"));\n          };\n\n          xhr.send();\n      });\n  }\n\n  module.exports = XHR;\n\n  },{}]},{},[4])(4)\n  });\n\n  /************************************************\n   * Title : custom font                          *\n   * Start Data : 2017. 01. 22.                   *\n   * Comment : TEXT API                           *\n   ************************************************/\n\n  /******************************\n   * jsPDF extension API Design *\n   * ****************************/\n  (function(jsPDF){\n      var PLUS = '+'.charCodeAt(0);\n      var SLASH = '/'.charCodeAt(0);\n      var NUMBER = '0'.charCodeAt(0);\n      var LOWER = 'a'.charCodeAt(0);\n      var UPPER = 'A'.charCodeAt(0);\n      var PLUS_URL_SAFE = '-'.charCodeAt(0);\n      var SLASH_URL_SAFE = '_'.charCodeAt(0);\n\n      /*****************************************************************/\n      /* function : b64ToByteArray                                     */\n      /* comment : Base64 encoded TTF file contents (b64) are decoded  */\n      /*     by Byte array and stored.                                 */\n      /*****************************************************************/\n      var b64ToByteArray = function(b64) {\n          var i, j, l, tmp, placeHolders, arr;\n          if (b64.length % 4 > 0) {\n              throw new Error('Invalid string. Length must be a multiple of 4')\n          }\n          // the number of equal signs (place holders)\n          // if there are two placeholders, than the two characters before it\n          // represent one byte\n          // if there is only one, then the three characters before it represent 2 bytes\n          // this is just a cheap hack to not do indexOf twice\n          var len = b64.length;\n          placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0;\n              // base64 is 4/3 + up to two characters of the original data\n          arr = new Uint8Array(b64.length * 3 / 4 - placeHolders);\n              // if there are placeholders, only get up to the last complete 4 chars\n          l = placeHolders > 0 ? b64.length - 4 : b64.length;\n          var L = 0;\n\n          function push(v) {\n              arr[L++] = v;\n          }\n          for (i = 0, j = 0; i < l; i += 4, j += 3) {\n              tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3));\n              push((tmp & 0xFF0000) >> 16);\n              push((tmp & 0xFF00) >> 8);\n              push(tmp & 0xFF);\n          }\n          if (placeHolders === 2) {\n              tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4);\n              push(tmp & 0xFF);\n          }\n          else if (placeHolders === 1) {\n              tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2);\n              push((tmp >> 8) & 0xFF);\n              push(tmp & 0xFF);\n          }\n          return arr\n      };\n\n      /***************************************************************/\n      /* function : decode                                           */\n      /* comment : Change the base64 encoded font's content to match */\n      /*   the base64 index value.                                   */\n      /***************************************************************/\n      var decode = function(elt) {\n          var code = elt.charCodeAt(0);\n          if (code === PLUS || code === PLUS_URL_SAFE) return 62 // '+'\n          if (code === SLASH || code === SLASH_URL_SAFE) return 63 // '/'\n          if (code < NUMBER) return -1 //no match\n          if (code < NUMBER + 10) return code - NUMBER + 26 + 26\n          if (code < UPPER + 26) return code - UPPER\n          if (code < LOWER + 26) return code - LOWER + 26\n      };\n\n      jsPDF.API.TTFFont = (function () {\n          /************************************************************************/\n          /* function : open                                                       */\n          /* comment : Decode the encoded ttf content and create a TTFFont object. */\n          /************************************************************************/\n          TTFFont.open = function (filename, name, vfs, encoding) {\n              var contents;\n              contents = b64ToByteArray(vfs);\n              return new TTFFont(contents, name, encoding);\n          };\n          /***************************************************************/\n          /* function : TTFFont gernerator                               */\n          /* comment : Decode TTF contents are parsed, Data,             */\n          /* Subset object is created, and registerTTF function is called.*/\n          /***************************************************************/\n          function TTFFont(rawData, name, encoding) {\n              var data;\n              this.rawData = rawData;\n              data = this.contents = new Data(rawData);\n              this.contents.pos = 4;\n              if (data.readString(4) === 'ttcf') {\n                  if (!name) {\n                      throw new Error(\"Must specify a font name for TTC files.\");\n                  }\n                  throw new Error(\"Font \" + name + \" not found in TTC file.\");\n              }\n              else {\n                  data.pos = 0;\n                  this.parse();\n                  this.subset = new Subset(this);\n                  this.registerTTF();\n              }\n          }\n          /********************************************************/\n          /* function : parse                                     */\n          /* comment : TTF Parses the file contents by each table.*/\n          /********************************************************/\n          TTFFont.prototype.parse = function () {\n              this.directory = new Directory(this.contents);\n              this.head = new HeadTable(this);\n              this.name = new NameTable(this);\n              this.cmap = new CmapTable(this);\n              this.hhea = new HheaTable(this);\n              this.maxp = new MaxpTable(this);\n              this.hmtx = new HmtxTable(this);\n              this.post = new PostTable(this);\n              this.os2 = new OS2Table(this);\n              this.loca = new LocaTable(this);\n              this.glyf = new GlyfTable(this);\n              this.ascender = (this.os2.exists && this.os2.ascender) || this.hhea.ascender;\n              this.decender = (this.os2.exists && this.os2.decender) || this.hhea.decender;\n              this.lineGap = (this.os2.exists && this.os2.lineGap) || this.hhea.lineGap;\n              return this.bbox = [this.head.xMin, this.head.yMin, this.head.xMax, this.head.yMax];\n          };\n          /***************************************************************/\n          /* function : registerTTF                                      */\n          /* comment : Get the value to assign pdf font descriptors.     */\n          /***************************************************************/\n          TTFFont.prototype.registerTTF = function () {\n              var e, hi, low, raw, _ref;\n              this.scaleFactor = 1000.0 / this.head.unitsPerEm;\n              this.bbox = (function () {\n                  var _i, _len, _ref, _results;\n                  _ref = this.bbox;\n                  _results = [];\n                  for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n                      e = _ref[_i];\n                      _results.push(Math.round(e * this.scaleFactor));\n                  }\n                  return _results;\n              }).call(this);\n              this.stemV = 0;\n              if (this.post.exists) {\n                  raw = this.post.italic_angle;\n                  hi = raw >> 16;\n                  low = raw & 0xFF;\n                  if (hi & 0x8000 !== 0) {\n                      hi = -((hi ^ 0xFFFF) + 1);\n                  }\n                  this.italicAngle = +(\"\" + hi + \".\" + low);\n              }\n              else {\n                  this.italicAngle = 0;\n              }\n              this.ascender = Math.round(this.ascender * this.scaleFactor);\n              this.decender = Math.round(this.decender * this.scaleFactor);\n              this.lineGap = Math.round(this.lineGap * this.scaleFactor);\n              this.capHeight = (this.os2.exists && this.os2.capHeight) || this.ascender;\n              this.xHeight = (this.os2.exists && this.os2.xHeight) || 0;\n              this.familyClass = (this.os2.exists && this.os2.familyClass || 0) >> 8;\n              this.isSerif = (_ref = this.familyClass) === 1 || _ref === 2 || _ref === 3 || _ref === 4 || _ref === 5 || _ref === 7;\n              this.isScript = this.familyClass === 10;\n              this.flags = 0;\n              if (this.post.isFixedPitch) {\n                  this.flags |= 1 << 0;\n              }\n              if (this.isSerif) {\n                  this.flags |= 1 << 1;\n              }\n              if (this.isScript) {\n                  this.flags |= 1 << 3;\n              }\n              if (this.italicAngle !== 0) {\n                  this.flags |= 1 << 6;\n              }\n              this.flags |= 1 << 5;\n              if (!this.cmap.unicode) {\n                  throw new Error('No unicode cmap for font');\n              }\n          };\n          TTFFont.prototype.characterToGlyph = function (character) {\n              var _ref;\n              return ((_ref = this.cmap.unicode) != null ? _ref.codeMap[character] : void 0) || 0;\n          };\n          TTFFont.prototype.widthOfGlyph = function (glyph) {\n              var scale;\n              scale = 1000.0 / this.head.unitsPerEm;\n              return this.hmtx.forGlyph(glyph).advance * scale;\n          };\n          TTFFont.prototype.widthOfString = function (string, size, charSpace) {\n              var charCode, i, scale, width, _i, _ref, charSpace;\n              string = '' + string;\n              width = 0;\n              for (i = _i = 0, _ref = string.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n                  charCode = string.charCodeAt(i);\n                  width += (this.widthOfGlyph(this.characterToGlyph(charCode)) + charSpace * (1000/ size)) || 0;\n              }\n              scale = size / 1000;\n              return width * scale;\n          };\n          TTFFont.prototype.lineHeight = function (size, includeGap) {\n              var gap;\n              if (includeGap == null) {\n                  includeGap = false;\n              }\n              gap = includeGap ? this.lineGap : 0;\n              return (this.ascender + gap - this.decender) / 1000 * size;\n          };\n          return TTFFont;\n      })();\n\n      /************************************************************************************************/\n      /* function : Data                                                                              */\n      /* comment : The ttf data decoded and stored in an array is read and written to the Data object.*/\n      /************************************************************************************************/\n      var Data = (function () {\n          function Data(data) {\n              this.data = data != null ? data : [];\n              this.pos = 0;\n              this.length = this.data.length;\n          }\n          Data.prototype.readByte = function () {\n              return this.data[this.pos++];\n          };\n          Data.prototype.writeByte = function (byte) {\n              return this.data[this.pos++] = byte;\n          };\n          Data.prototype.readUInt32 = function () {\n              var b1, b2, b3, b4;\n              b1 = this.readByte() * 0x1000000;\n              b2 = this.readByte() << 16;\n              b3 = this.readByte() << 8;\n              b4 = this.readByte();\n              return b1 + b2 + b3 + b4;\n          };\n          Data.prototype.writeUInt32 = function (val) {\n              this.writeByte((val >>> 24) & 0xff);\n              this.writeByte((val >> 16) & 0xff);\n              this.writeByte((val >> 8) & 0xff);\n              return this.writeByte(val & 0xff);\n          };\n          Data.prototype.readInt32 = function () {\n              var int;\n              int = this.readUInt32();\n              if (int >= 0x80000000) {\n                  return int - 0x100000000;\n              }\n              else {\n                  return int;\n              }\n          };\n          Data.prototype.writeInt32 = function (val) {\n              if (val < 0) {\n                  val += 0x100000000;\n              }\n              return this.writeUInt32(val);\n          };\n          Data.prototype.readUInt16 = function () {\n              var b1, b2;\n              b1 = this.readByte() << 8;\n              b2 = this.readByte();\n              return b1 | b2;\n          };\n          Data.prototype.writeUInt16 = function (val) {\n              this.writeByte((val >> 8) & 0xff);\n              return this.writeByte(val & 0xff);\n          };\n          Data.prototype.readInt16 = function () {\n              var int;\n              int = this.readUInt16();\n              if (int >= 0x8000) {\n                  return int - 0x10000;\n              }\n              else {\n                  return int;\n              }\n          };\n          Data.prototype.writeInt16 = function (val) {\n              if (val < 0) {\n                  val += 0x10000;\n              }\n              return this.writeUInt16(val);\n          };\n          Data.prototype.readString = function (length) {\n              var i, ret, _i;\n              ret = [];\n              for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) {\n                  ret[i] = String.fromCharCode(this.readByte());\n              }\n              return ret.join('');\n          };\n          Data.prototype.writeString = function (val) {\n              var i, _i, _ref, _results;\n              _results = [];\n              for (i = _i = 0, _ref = val.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n                  _results.push(this.writeByte(val.charCodeAt(i)));\n              }\n              return _results;\n          };\n          /*Data.prototype.stringAt = function (pos, length) {\n              this.pos = pos;\n              return this.readString(length);\n          };*/\n          Data.prototype.readShort = function () {\n              return this.readInt16();\n          };\n          Data.prototype.writeShort = function (val) {\n              return this.writeInt16(val);\n          };\n          Data.prototype.readLongLong = function () {\n              var b1, b2, b3, b4, b5, b6, b7, b8;\n              b1 = this.readByte();\n              b2 = this.readByte();\n              b3 = this.readByte();\n              b4 = this.readByte();\n              b5 = this.readByte();\n              b6 = this.readByte();\n              b7 = this.readByte();\n              b8 = this.readByte();\n              if (b1 & 0x80) {\n                  return ((b1 ^ 0xff) * 0x100000000000000 + (b2 ^ 0xff) * 0x1000000000000 + (b3 ^ 0xff) * 0x10000000000 + (b4 ^ 0xff) * 0x100000000 + (b5 ^ 0xff) * 0x1000000 + (b6 ^ 0xff) * 0x10000 + (b7 ^ 0xff) * 0x100 + (b8 ^ 0xff) + 1) * -1;\n              }\n              return b1 * 0x100000000000000 + b2 * 0x1000000000000 + b3 * 0x10000000000 + b4 * 0x100000000 + b5 * 0x1000000 + b6 * 0x10000 + b7 * 0x100 + b8;\n          };\n          /*Data.prototype.writeLongLong = function (val) {\n              var high, low;\n              high = Math.floor(val / 0x100000000);\n              low = val & 0xffffffff;\n              this.writeByte((high >> 24) & 0xff);\n              this.writeByte((high >> 16) & 0xff);\n              this.writeByte((high >> 8) & 0xff);\n              this.writeByte(high & 0xff);\n              this.writeByte((low >> 24) & 0xff);\n              this.writeByte((low >> 16) & 0xff);\n              this.writeByte((low >> 8) & 0xff);\n              return this.writeByte(low & 0xff);\n          };*/\n          Data.prototype.readInt = function () {\n              return this.readInt32();\n          };\n          Data.prototype.writeInt = function (val) {\n              return this.writeInt32(val);\n          };\n          /*Data.prototype.slice = function (start, end) {\n              return this.data.slice(start, end);\n          };*/\n          Data.prototype.read = function (bytes) {\n              var buf, i, _i;\n              buf = [];\n              for (i = _i = 0; 0 <= bytes ? _i < bytes : _i > bytes; i = 0 <= bytes ? ++_i : --_i) {\n                  buf.push(this.readByte());\n              }\n              return buf;\n          };\n          Data.prototype.write = function (bytes) {\n              var byte, _i, _len, _results;\n              _results = [];\n              for (_i = 0, _len = bytes.length; _i < _len; _i++) {\n                  byte = bytes[_i];\n                  _results.push(this.writeByte(byte));\n              }\n              return _results;\n          };\n          return Data;\n      })();\n\n      var Directory = (function () {\n          var checksum;\n\n          /*****************************************************************************************************/\n          /* function : Directory generator                                                                    */\n          /* comment : Initialize the offset, tag, length, and checksum for each table for the font to be used.*/\n          /*****************************************************************************************************/\n          function Directory(data) {\n              var entry, i, _i, _ref;\n              this.scalarType = data.readInt();\n              this.tableCount = data.readShort();\n              this.searchRange = data.readShort();\n              this.entrySelector = data.readShort();\n              this.rangeShift = data.readShort();\n              this.tables = {};\n              for (i = _i = 0, _ref = this.tableCount; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n                  entry = {\n                      tag: data.readString(4)\n                      , checksum: data.readInt()\n                      , offset: data.readInt()\n                      , length: data.readInt()\n                  };\n                  this.tables[entry.tag] = entry;\n              }\n          }\n          /********************************************************************************************************/\n          /* function : encode                                                                                    */\n          /* comment : It encodes and stores the font table object and information used for the directory object. */\n          /********************************************************************************************************/\n          Directory.prototype.encode = function (tables) {\n              var adjustment, directory, directoryLength, entrySelector, headOffset, log2, offset, rangeShift, searchRange, sum, table, tableCount, tableData, tag;\n              tableCount = Object.keys(tables).length;\n              log2 = Math.log(2);\n              searchRange = Math.floor(Math.log(tableCount) / log2) * 16;\n              entrySelector = Math.floor(searchRange / log2);\n              rangeShift = tableCount * 16 - searchRange;\n              directory = new Data;\n              directory.writeInt(this.scalarType);\n              directory.writeShort(tableCount);\n              directory.writeShort(searchRange);\n              directory.writeShort(entrySelector);\n              directory.writeShort(rangeShift);\n              directoryLength = tableCount * 16;\n              offset = directory.pos + directoryLength;\n              headOffset = null;\n              tableData = [];\n              for (tag in tables) {\n                  table = tables[tag];\n                  directory.writeString(tag);\n                  directory.writeInt(checksum(table));\n                  directory.writeInt(offset);\n                  directory.writeInt(table.length);\n                  tableData = tableData.concat(table);\n                  if (tag === 'head') {\n                      headOffset = offset;\n                  }\n                  offset += table.length;\n                  while (offset % 4) {\n                      tableData.push(0);\n                      offset++;\n                  }\n              }\n              directory.write(tableData);\n              sum = checksum(directory.data);\n              adjustment = 0xB1B0AFBA - sum;\n              directory.pos = headOffset + 8;\n              directory.writeUInt32(adjustment);\n              return directory.data;\n          };\n          /***************************************************************/\n          /* function : checksum                                         */\n          /* comment : Duplicate the table for the tag.                  */\n          /***************************************************************/\n          checksum = function (data) {\n              var i, sum, tmp, _i, _ref;\n              data = __slice.call(data);\n              while (data.length % 4) {\n                  data.push(0);\n              }\n              tmp = new Data(data);\n              sum = 0;\n              for (i = _i = 0, _ref = data.length; _i < _ref; i = _i += 4) {\n                  sum += tmp.readUInt32();\n              }\n              return sum & 0xFFFFFFFF;\n          };\n          return Directory;\n      })();\n\n      var Table, __hasProp = {}.hasOwnProperty\n          , __extends = function (child, parent) {\n              for (var key in parent) {\n                  if (__hasProp.call(parent, key)) child[key] = parent[key];\n              }\n\n              function ctor() {\n                  this.constructor = child;\n              }\n              ctor.prototype = parent.prototype;\n              child.prototype = new ctor();\n              child.__super__ = parent.prototype;\n              return child;\n      };\n      /***************************************************************/\n      /* function : Table                                            */\n      /* comment : Save info for each table, and parse the table.    */\n      /***************************************************************/\n      Table = (function () {\n          function Table(file) {\n              var info;\n              this.file = file;\n              info = this.file.directory.tables[this.tag];\n              this.exists = !!info;\n              if (info) {\n                  this.offset = info.offset, this.length = info.length;\n                  this.parse(this.file.contents);\n              }\n          }\n          Table.prototype.parse = function () {};\n          Table.prototype.encode = function () {};\n          Table.prototype.raw = function () {\n              if (!this.exists) {\n                  return null;\n              }\n              this.file.contents.pos = this.offset;\n              return this.file.contents.read(this.length);\n          };\n          return Table;\n      })();\n\n      var HeadTable = (function (_super) {\n          __extends(HeadTable, _super);\n\n          function HeadTable() {\n              return HeadTable.__super__.constructor.apply(this, arguments);\n          }\n          HeadTable.prototype.tag = 'head';\n          HeadTable.prototype.parse = function (data) {\n              data.pos = this.offset;\n              this.version = data.readInt();\n              this.revision = data.readInt();\n              this.checkSumAdjustment = data.readInt();\n              this.magicNumber = data.readInt();\n              this.flags = data.readShort();\n              this.unitsPerEm = data.readShort();\n              this.created = data.readLongLong();\n              this.modified = data.readLongLong();\n              this.xMin = data.readShort();\n              this.yMin = data.readShort();\n              this.xMax = data.readShort();\n              this.yMax = data.readShort();\n              this.macStyle = data.readShort();\n              this.lowestRecPPEM = data.readShort();\n              this.fontDirectionHint = data.readShort();\n              this.indexToLocFormat = data.readShort();\n              return this.glyphDataFormat = data.readShort();\n          };\n          /*HeadTable.prototype.encode = function (loca) {\n              var table;\n              table = new Data;\n              table.writeInt(this.version);\n              table.writeInt(this.revision);\n              table.writeInt(this.checkSumAdjustment);\n              table.writeInt(this.magicNumber);\n              table.writeShort(this.flags);\n              table.writeShort(this.unitsPerEm);\n              table.writeLongLong(this.created);\n              table.writeLongLong(this.modified);\n              table.writeShort(this.xMin);\n              table.writeShort(this.yMin);\n              table.writeShort(this.xMax);\n              table.writeShort(this.yMax);\n              table.writeShort(this.macStyle);\n              table.writeShort(this.lowestRecPPEM);\n              table.writeShort(this.fontDirectionHint);\n              table.writeShort(loca.type);\n              table.writeShort(this.glyphDataFormat);\n              return table.data;\n          };*/\n          return HeadTable;\n      })(Table);\n\n      /************************************************************************************/\n      /* function : CmapEntry                                                             */\n      /* comment : Cmap Initializes and encodes object information (required by pdf spec).*/\n      /************************************************************************************/\n      var CmapEntry = (function () {\n          function CmapEntry(data, offset) {\n              var code, count, endCode, glyphId, glyphIds, i, idDelta, idRangeOffset, index, saveOffset, segCount, segCountX2, start, startCode, tail, _i, _j, _k, _len;\n              this.platformID = data.readUInt16();\n              this.encodingID = data.readShort();\n              this.offset = offset + data.readInt();\n              saveOffset = data.pos;\n              data.pos = this.offset;\n              this.format = data.readUInt16();\n              this.length = data.readUInt16();\n              this.language = data.readUInt16();\n              this.isUnicode = (this.platformID === 3 && this.encodingID === 1 && this.format === 4) || this.platformID === 0 && this.format === 4;\n              this.codeMap = {};\n              switch (this.format) {\n              case 0:\n                  for (i = _i = 0; _i < 256; i = ++_i) {\n                      this.codeMap[i] = data.readByte();\n                  }\n                  break;\n              case 4:\n                  segCountX2 = data.readUInt16();\n                  segCount = segCountX2 / 2;\n                  data.pos += 6;\n                  endCode = (function () {\n                      var _j, _results;\n                      _results = [];\n                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {\n                          _results.push(data.readUInt16());\n                      }\n                      return _results;\n                  })();\n                  data.pos += 2;\n                  startCode = (function () {\n                      var _j, _results;\n                      _results = [];\n                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {\n                          _results.push(data.readUInt16());\n                      }\n                      return _results;\n                  })();\n                  idDelta = (function () {\n                      var _j, _results;\n                      _results = [];\n                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {\n                          _results.push(data.readUInt16());\n                      }\n                      return _results;\n                  })();\n                  idRangeOffset = (function () {\n                      var _j, _results;\n                      _results = [];\n                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {\n                          _results.push(data.readUInt16());\n                      }\n                      return _results;\n                  })();\n                  count = (this.length - data.pos + this.offset) / 2;\n                  glyphIds = (function () {\n                      var _j, _results;\n                      _results = [];\n                      for (i = _j = 0; 0 <= count ? _j < count : _j > count; i = 0 <= count ? ++_j : --_j) {\n                          _results.push(data.readUInt16());\n                      }\n                      return _results;\n                  })();\n                  for (i = _j = 0, _len = endCode.length; _j < _len; i = ++_j) {\n                      tail = endCode[i];\n                      start = startCode[i];\n                      for (code = _k = start; start <= tail ? _k <= tail : _k >= tail; code = start <= tail ? ++_k : --_k) {\n                          if (idRangeOffset[i] === 0) {\n                              glyphId = code + idDelta[i];\n                          }\n                          else {\n                              index = idRangeOffset[i] / 2 + (code - start) - (segCount - i);\n                              glyphId = glyphIds[index] || 0;\n                              if (glyphId !== 0) {\n                                  glyphId += idDelta[i];\n                              }\n                          }\n                          this.codeMap[code] = glyphId & 0xFFFF;\n                      }\n                  }\n              }\n              data.pos = saveOffset;\n          }\n          CmapEntry.encode = function (charmap, encoding) {\n              var charMap, code, codeMap, codes, delta, deltas, diff, endCode, endCodes, entrySelector, glyphIDs, i, id, indexes, last, map, nextID, offset, old, rangeOffsets, rangeShift, result, searchRange, segCount, segCountX2, startCode, startCodes, startGlyph, subtable, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _len6, _len7, _m, _n, _name, _o, _p, _q;\n              subtable = new Data;\n              codes = Object.keys(charmap).sort(function (a, b) {\n                  return a - b;\n              });\n              switch (encoding) {\n              case 'macroman':\n                  id = 0;\n                  indexes = (function () {\n                      var _i, _results;\n                      _results = [];\n                      for (i = _i = 0; _i < 256; i = ++_i) {\n                          _results.push(0);\n                      }\n                      return _results;\n                  })();\n                  map = {\n                      0: 0\n                  };\n                  codeMap = {};\n                  for (_i = 0, _len = codes.length; _i < _len; _i++) {\n                      code = codes[_i];\n                      if (map[_name = charmap[code]] == null) {\n                          map[_name] = ++id;\n                      }\n                      codeMap[code] = {\n                          old: charmap[code]\n                          , \"new\": map[charmap[code]]\n                      };\n                      indexes[code] = map[charmap[code]];\n                  }\n                  subtable.writeUInt16(1);\n                  subtable.writeUInt16(0);\n                  subtable.writeUInt32(12);\n                  subtable.writeUInt16(0);\n                  subtable.writeUInt16(262);\n                  subtable.writeUInt16(0);\n                  subtable.write(indexes);\n                  return result = {\n                      charMap: codeMap\n                      , subtable: subtable.data\n                      , maxGlyphID: id + 1\n                  };\n              case 'unicode':\n                  startCodes = [];\n                  endCodes = [];\n                  nextID = 0;\n                  map = {};\n                  charMap = {};\n                  last = diff = null;\n                  for (_j = 0, _len1 = codes.length; _j < _len1; _j++) {\n                      code = codes[_j];\n                      old = charmap[code];\n                      if (map[old] == null) {\n                          map[old] = ++nextID;\n                      }\n                      charMap[code] = {\n                          old: old\n                          , \"new\": map[old]\n                      };\n                      delta = map[old] - code;\n                      if ((last == null) || delta !== diff) {\n                          if (last) {\n                              endCodes.push(last);\n                          }\n                          startCodes.push(code);\n                          diff = delta;\n                      }\n                      last = code;\n                  }\n                  if (last) {\n                      endCodes.push(last);\n                  }\n                  endCodes.push(0xFFFF);\n                  startCodes.push(0xFFFF);\n                  segCount = startCodes.length;\n                  segCountX2 = segCount * 2;\n                  searchRange = 2 * Math.pow(Math.log(segCount) / Math.LN2, 2);\n                  entrySelector = Math.log(searchRange / 2) / Math.LN2;\n                  rangeShift = 2 * segCount - searchRange;\n                  deltas = [];\n                  rangeOffsets = [];\n                  glyphIDs = [];\n                  for (i = _k = 0, _len2 = startCodes.length; _k < _len2; i = ++_k) {\n                      startCode = startCodes[i];\n                      endCode = endCodes[i];\n                      if (startCode === 0xFFFF) {\n                          deltas.push(0);\n                          rangeOffsets.push(0);\n                          break;\n                      }\n                      startGlyph = charMap[startCode][\"new\"];\n                      if (startCode - startGlyph >= 0x8000) {\n                          deltas.push(0);\n                          rangeOffsets.push(2 * (glyphIDs.length + segCount - i));\n                          for (code = _l = startCode; startCode <= endCode ? _l <= endCode : _l >= endCode; code = startCode <= endCode ? ++_l : --_l) {\n                              glyphIDs.push(charMap[code][\"new\"]);\n                          }\n                      }\n                      else {\n                          deltas.push(startGlyph - startCode);\n                          rangeOffsets.push(0);\n                      }\n                  }\n                  subtable.writeUInt16(3);\n                  subtable.writeUInt16(1);\n                  subtable.writeUInt32(12);\n                  subtable.writeUInt16(4);\n                  subtable.writeUInt16(16 + segCount * 8 + glyphIDs.length * 2);\n                  subtable.writeUInt16(0);\n                  subtable.writeUInt16(segCountX2);\n                  subtable.writeUInt16(searchRange);\n                  subtable.writeUInt16(entrySelector);\n                  subtable.writeUInt16(rangeShift);\n                  for (_m = 0, _len3 = endCodes.length; _m < _len3; _m++) {\n                      code = endCodes[_m];\n                      subtable.writeUInt16(code);\n                  }\n                  subtable.writeUInt16(0);\n                  for (_n = 0, _len4 = startCodes.length; _n < _len4; _n++) {\n                      code = startCodes[_n];\n                      subtable.writeUInt16(code);\n                  }\n                  for (_o = 0, _len5 = deltas.length; _o < _len5; _o++) {\n                      delta = deltas[_o];\n                      subtable.writeUInt16(delta);\n                  }\n                  for (_p = 0, _len6 = rangeOffsets.length; _p < _len6; _p++) {\n                      offset = rangeOffsets[_p];\n                      subtable.writeUInt16(offset);\n                  }\n                  for (_q = 0, _len7 = glyphIDs.length; _q < _len7; _q++) {\n                      id = glyphIDs[_q];\n                      subtable.writeUInt16(id);\n                  }\n                  return result = {\n                      charMap: charMap\n                      , subtable: subtable.data\n                      , maxGlyphID: nextID + 1\n                  };\n              }\n          };\n          return CmapEntry;\n      })();\n\n      var CmapTable = (function (_super) {\n          __extends(CmapTable, _super);\n\n          function CmapTable() {\n              return CmapTable.__super__.constructor.apply(this, arguments);\n          }\n          CmapTable.prototype.tag = 'cmap';\n          CmapTable.prototype.parse = function (data) {\n              var entry, i, tableCount, _i;\n              data.pos = this.offset;\n              this.version = data.readUInt16();\n              tableCount = data.readUInt16();\n              this.tables = [];\n              this.unicode = null;\n              for (i = _i = 0; 0 <= tableCount ? _i < tableCount : _i > tableCount; i = 0 <= tableCount ? ++_i : --_i) {\n                  entry = new CmapEntry(data, this.offset);\n                  this.tables.push(entry);\n                  if (entry.isUnicode) {\n                      if (this.unicode == null) {\n                          this.unicode = entry;\n                      }\n                  }\n              }\n              return true;\n          };\n          /*************************************************************************/\n          /* function : encode                                                     */\n          /* comment : Encode the cmap table corresponding to the input character. */\n          /*************************************************************************/\n          CmapTable.encode = function (charmap, encoding) {\n              var result, table;\n              if (encoding == null) {\n                  encoding = 'macroman';\n              }\n              result = CmapEntry.encode(charmap, encoding);\n              table = new Data;\n              table.writeUInt16(0);\n              table.writeUInt16(1);\n              result.table = table.data.concat(result.subtable);\n              return result;\n          };\n          return CmapTable;\n      })(Table);\n\n      var HheaTable = (function (_super) {\n          __extends(HheaTable, _super);\n\n          function HheaTable() {\n              return HheaTable.__super__.constructor.apply(this, arguments);\n          }\n          HheaTable.prototype.tag = 'hhea';\n          HheaTable.prototype.parse = function (data) {\n              data.pos = this.offset;\n              this.version = data.readInt();\n              this.ascender = data.readShort();\n              this.decender = data.readShort();\n              this.lineGap = data.readShort();\n              this.advanceWidthMax = data.readShort();\n              this.minLeftSideBearing = data.readShort();\n              this.minRightSideBearing = data.readShort();\n              this.xMaxExtent = data.readShort();\n              this.caretSlopeRise = data.readShort();\n              this.caretSlopeRun = data.readShort();\n              this.caretOffset = data.readShort();\n              data.pos += 4 * 2;\n              this.metricDataFormat = data.readShort();\n              return this.numberOfMetrics = data.readUInt16();\n          };\n          /*HheaTable.prototype.encode = function (ids) {\n              var i, table, _i, _ref;\n              table = new Data;\n              table.writeInt(this.version);\n              table.writeShort(this.ascender);\n              table.writeShort(this.decender);\n              table.writeShort(this.lineGap);\n              table.writeShort(this.advanceWidthMax);\n              table.writeShort(this.minLeftSideBearing);\n              table.writeShort(this.minRightSideBearing);\n              table.writeShort(this.xMaxExtent);\n              table.writeShort(this.caretSlopeRise);\n              table.writeShort(this.caretSlopeRun);\n              table.writeShort(this.caretOffset);\n              for (i = _i = 0, _ref = 4 * 2; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n                  table.writeByte(0);\n              }\n              table.writeShort(this.metricDataFormat);\n              table.writeUInt16(ids.length);\n              return table.data;\n          };*/\n          return HheaTable;\n      })(Table);\n\n      var OS2Table = (function (_super) {\n          __extends(OS2Table, _super);\n\n          function OS2Table() {\n              return OS2Table.__super__.constructor.apply(this, arguments);\n          }\n          OS2Table.prototype.tag = 'OS/2';\n          OS2Table.prototype.parse = function (data) {\n              var i;\n              data.pos = this.offset;\n              this.version = data.readUInt16();\n              this.averageCharWidth = data.readShort();\n              this.weightClass = data.readUInt16();\n              this.widthClass = data.readUInt16();\n              this.type = data.readShort();\n              this.ySubscriptXSize = data.readShort();\n              this.ySubscriptYSize = data.readShort();\n              this.ySubscriptXOffset = data.readShort();\n              this.ySubscriptYOffset = data.readShort();\n              this.ySuperscriptXSize = data.readShort();\n              this.ySuperscriptYSize = data.readShort();\n              this.ySuperscriptXOffset = data.readShort();\n              this.ySuperscriptYOffset = data.readShort();\n              this.yStrikeoutSize = data.readShort();\n              this.yStrikeoutPosition = data.readShort();\n              this.familyClass = data.readShort();\n              this.panose = (function () {\n                  var _i, _results;\n                  _results = [];\n                  for (i = _i = 0; _i < 10; i = ++_i) {\n                      _results.push(data.readByte());\n                  }\n                  return _results;\n              })();\n              this.charRange = (function () {\n                  var _i, _results;\n                  _results = [];\n                  for (i = _i = 0; _i < 4; i = ++_i) {\n                      _results.push(data.readInt());\n                  }\n                  return _results;\n              })();\n              this.vendorID = data.readString(4);\n              this.selection = data.readShort();\n              this.firstCharIndex = data.readShort();\n              this.lastCharIndex = data.readShort();\n              if (this.version > 0) {\n                  this.ascent = data.readShort();\n                  this.descent = data.readShort();\n                  this.lineGap = data.readShort();\n                  this.winAscent = data.readShort();\n                  this.winDescent = data.readShort();\n                  this.codePageRange = (function () {\n                      var _i, _results;\n                      _results = [];\n                      for (i = _i = 0; _i < 2; i = ++_i) {\n                          _results.push(data.readInt());\n                      }\n                      return _results;\n                  })();\n                  if (this.version > 1) {\n                      this.xHeight = data.readShort();\n                      this.capHeight = data.readShort();\n                      this.defaultChar = data.readShort();\n                      this.breakChar = data.readShort();\n                      return this.maxContext = data.readShort();\n                  }\n              }\n          };\n          /*OS2Table.prototype.encode = function () {\n              return this.raw();\n          };*/\n          return OS2Table;\n      })(Table);\n\n      var PostTable = (function (_super) {\n          __extends(PostTable, _super);\n\n          function PostTable() {\n              return PostTable.__super__.constructor.apply(this, arguments);\n          }\n          PostTable.prototype.tag = 'post';\n          PostTable.prototype.parse = function (data) {\n              var i, length, numberOfGlyphs, _i, _results;\n              data.pos = this.offset;\n              this.format = data.readInt();\n              this.italicAngle = data.readInt();\n              this.underlinePosition = data.readShort();\n              this.underlineThickness = data.readShort();\n              this.isFixedPitch = data.readInt();\n              this.minMemType42 = data.readInt();\n              this.maxMemType42 = data.readInt();\n              this.minMemType1 = data.readInt();\n              this.maxMemType1 = data.readInt();\n              switch (this.format) {\n              case 0x00010000:\n                  break;\n              case 0x00020000:\n                  numberOfGlyphs = data.readUInt16();\n                  this.glyphNameIndex = [];\n                  for (i = _i = 0; 0 <= numberOfGlyphs ? _i < numberOfGlyphs : _i > numberOfGlyphs; i = 0 <= numberOfGlyphs ? ++_i : --_i) {\n                      this.glyphNameIndex.push(data.readUInt16());\n                  }\n                  this.names = [];\n                  _results = [];\n                  while (data.pos < this.offset + this.length) {\n                      length = data.readByte();\n                      _results.push(this.names.push(data.readString(length)));\n                  }\n                  return _results;\n                  break;\n              case 0x00025000:\n                  numberOfGlyphs = data.readUInt16();\n                  return this.offsets = data.read(numberOfGlyphs);\n              case 0x00030000:\n                  break;\n              case 0x00040000:\n                  return this.map = (function () {\n                      var _j, _ref, _results1;\n                      _results1 = [];\n                      for (i = _j = 0, _ref = this.file.maxp.numGlyphs; 0 <= _ref ? _j < _ref : _j > _ref; i = 0 <= _ref ? ++_j : --_j) {\n                          _results1.push(data.readUInt32());\n                      }\n                      return _results1;\n                  }).call(this);\n              }\n          };\n          return PostTable;\n      })(Table);\n\n      /*********************************************************************************************************/\n      /* function : NameEntry                                                                                  */\n      /* comment : Store copyright information, platformID, encodingID, and languageID in the NameEntry object.*/\n      /*********************************************************************************************************/\n      var NameEntry = (function () {\n          function NameEntry(raw, entry) {\n              this.raw = raw;\n              this.length = raw.length;\n              this.platformID = entry.platformID;\n              this.encodingID = entry.encodingID;\n              this.languageID = entry.languageID;\n          }\n          return NameEntry;\n      })();\n\n      var NameTable = (function (_super) {\n          __extends(NameTable, _super);\n\n          function NameTable() {\n              return NameTable.__super__.constructor.apply(this, arguments);\n          }\n          NameTable.prototype.tag = 'name';\n          NameTable.prototype.parse = function (data) {\n              var count, entries, entry, format, i, name, stringOffset, strings, text, _i, _j, _len, _name;\n              data.pos = this.offset;\n              format = data.readShort();\n              count = data.readShort();\n              stringOffset = data.readShort();\n              entries = [];\n              for (i = _i = 0; 0 <= count ? _i < count : _i > count; i = 0 <= count ? ++_i : --_i) {\n                  entries.push({\n                      platformID: data.readShort()\n                      , encodingID: data.readShort()\n                      , languageID: data.readShort()\n                      , nameID: data.readShort()\n                      , length: data.readShort()\n                      , offset: this.offset + stringOffset + data.readShort()\n                  });\n              }\n              strings = {};\n              for (i = _j = 0, _len = entries.length; _j < _len; i = ++_j) {\n                  entry = entries[i];\n                  data.pos = entry.offset;\n                  text = data.readString(entry.length);\n                  name = new NameEntry(text, entry);\n                  if (strings[_name = entry.nameID] == null) {\n                      strings[_name] = [];\n                  }\n                  strings[entry.nameID].push(name);\n              }\n              this.strings = strings;\n              this.copyright = strings[0];\n              this.fontFamily = strings[1];\n              this.fontSubfamily = strings[2];\n              this.uniqueSubfamily = strings[3];\n              this.fontName = strings[4];\n              this.version = strings[5];\n              this.postscriptName = strings[6][0].raw.replace(/[\\x00-\\x19\\x80-\\xff]/g, \"\");\n              this.trademark = strings[7];\n              this.manufacturer = strings[8];\n              this.designer = strings[9];\n              this.description = strings[10];\n              this.vendorUrl = strings[11];\n              this.designerUrl = strings[12];\n              this.license = strings[13];\n              this.licenseUrl = strings[14];\n              this.preferredFamily = strings[15];\n              this.preferredSubfamily = strings[17];\n              this.compatibleFull = strings[18];\n              return this.sampleText = strings[19];\n          };\n          /*NameTable.prototype.encode = function () {\n              var id, list, nameID, nameTable, postscriptName, strCount, strTable, string, strings, table, val, _i, _len, _ref;\n              strings = {};\n              _ref = this.strings;\n              for (id in _ref) {\n                  val = _ref[id];\n                  strings[id] = val;\n              }\n              postscriptName = new NameEntry(\"\" + subsetTag + \"+\" + this.postscriptName, {\n                  platformID: 1\n                  , encodingID: 0\n                  , languageID: 0\n              });\n              strings[6] = [postscriptName];\n              subsetTag = successorOf(subsetTag);\n              strCount = 0;\n              for (id in strings) {\n                  list = strings[id];\n                  if (list != null) {\n                      strCount += list.length;\n                  }\n              }\n              table = new Data;\n              strTable = new Data;\n              table.writeShort(0);\n              table.writeShort(strCount);\n              table.writeShort(6 + 12 * strCount);\n              for (nameID in strings) {\n                  list = strings[nameID];\n                  if (list != null) {\n                      for (_i = 0, _len = list.length; _i < _len; _i++) {\n                          string = list[_i];\n                          table.writeShort(string.platformID);\n                          table.writeShort(string.encodingID);\n                          table.writeShort(string.languageID);\n                          table.writeShort(nameID);\n                          table.writeShort(string.length);\n                          table.writeShort(strTable.pos);\n                          strTable.writeString(string.raw);\n                      }\n                  }\n              }\n              return nameTable = {\n                  postscriptName: postscriptName.raw\n                  , table: table.data.concat(strTable.data)\n              };\n          };*/\n          return NameTable;\n      })(Table);\n\n      var MaxpTable = (function (_super) {\n          __extends(MaxpTable, _super);\n\n          function MaxpTable() {\n              return MaxpTable.__super__.constructor.apply(this, arguments);\n          }\n          MaxpTable.prototype.tag = 'maxp';\n          MaxpTable.prototype.parse = function (data) {\n              data.pos = this.offset;\n              this.version = data.readInt();\n              this.numGlyphs = data.readUInt16();\n              this.maxPoints = data.readUInt16();\n              this.maxContours = data.readUInt16();\n              this.maxCompositePoints = data.readUInt16();\n              this.maxComponentContours = data.readUInt16();\n              this.maxZones = data.readUInt16();\n              this.maxTwilightPoints = data.readUInt16();\n              this.maxStorage = data.readUInt16();\n              this.maxFunctionDefs = data.readUInt16();\n              this.maxInstructionDefs = data.readUInt16();\n              this.maxStackElements = data.readUInt16();\n              this.maxSizeOfInstructions = data.readUInt16();\n              this.maxComponentElements = data.readUInt16();\n              return this.maxComponentDepth = data.readUInt16();\n          };\n          /*MaxpTable.prototype.encode = function (ids) {\n              var table;\n              table = new Data;\n              table.writeInt(this.version);\n              table.writeUInt16(ids.length);\n              table.writeUInt16(this.maxPoints);\n              table.writeUInt16(this.maxContours);\n              table.writeUInt16(this.maxCompositePoints);\n              table.writeUInt16(this.maxComponentContours);\n              table.writeUInt16(this.maxZones);\n              table.writeUInt16(this.maxTwilightPoints);\n              table.writeUInt16(this.maxStorage);\n              table.writeUInt16(this.maxFunctionDefs);\n              table.writeUInt16(this.maxInstructionDefs);\n              table.writeUInt16(this.maxStackElements);\n              table.writeUInt16(this.maxSizeOfInstructions);\n              table.writeUInt16(this.maxComponentElements);\n              table.writeUInt16(this.maxComponentDepth);\n              return table.data;\n          };*/\n          return MaxpTable;\n      })(Table);\n\n      var HmtxTable = (function (_super) {\n          __extends(HmtxTable, _super);\n\n          function HmtxTable() {\n              return HmtxTable.__super__.constructor.apply(this, arguments);\n          }\n          HmtxTable.prototype.tag = 'hmtx';\n          HmtxTable.prototype.parse = function (data) {\n              var i, last, lsbCount, m, _i, _j, _ref, _results;\n              data.pos = this.offset;\n              this.metrics = [];\n              for (i = _i = 0, _ref = this.file.hhea.numberOfMetrics; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n                  this.metrics.push({\n                      advance: data.readUInt16()\n                      , lsb: data.readInt16()\n                  });\n              }\n              lsbCount = this.file.maxp.numGlyphs - this.file.hhea.numberOfMetrics;\n              this.leftSideBearings = (function () {\n                  var _j, _results;\n                  _results = [];\n                  for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) {\n                      _results.push(data.readInt16());\n                  }\n                  return _results;\n              })();\n              this.widths = (function () {\n                  var _j, _len, _ref1, _results;\n                  _ref1 = this.metrics;\n                  _results = [];\n                  for (_j = 0, _len = _ref1.length; _j < _len; _j++) {\n                      m = _ref1[_j];\n                      _results.push(m.advance);\n                  }\n                  return _results;\n              }).call(this);\n              last = this.widths[this.widths.length - 1];\n              _results = [];\n              for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) {\n                  _results.push(this.widths.push(last));\n              }\n              return _results;\n          };\n          /***************************************************************/\n          /* function : forGlyph                                         */\n          /* comment : Returns the advance width and lsb for this glyph. */\n          /***************************************************************/\n          HmtxTable.prototype.forGlyph = function (id) {\n              var metrics;\n              if (id in this.metrics) {\n                  return this.metrics[id];\n              }\n              return metrics = {\n                  advance: this.metrics[this.metrics.length - 1].advance\n                  , lsb: this.leftSideBearings[id - this.metrics.length]\n              };\n          };\n          /*HmtxTable.prototype.encode = function (mapping) {\n              var id, metric, table, _i, _len;\n              table = new Data;\n              for (_i = 0, _len = mapping.length; _i < _len; _i++) {\n                  id = mapping[_i];\n                  metric = this.forGlyph(id);\n                  table.writeUInt16(metric.advance);\n                  table.writeUInt16(metric.lsb);\n              }\n              return table.data;\n          };*/\n          return HmtxTable;\n      })(Table);\n\n      var __slice = [].slice;\n\n      var GlyfTable = (function (_super) {\n          __extends(GlyfTable, _super);\n\n          function GlyfTable() {\n              return GlyfTable.__super__.constructor.apply(this, arguments);\n          }\n          GlyfTable.prototype.tag = 'glyf';\n          GlyfTable.prototype.parse = function (data) {\n              return this.cache = {};\n          };\n          GlyfTable.prototype.glyphFor = function (id) {\n              id = id;\n              var data, index, length, loca, numberOfContours, raw, xMax, xMin, yMax, yMin;\n              if (id in this.cache) {\n                  return this.cache[id];\n              }\n              loca = this.file.loca;\n              data = this.file.contents;\n              index = loca.indexOf(id);\n              length = loca.lengthOf(id);\n              if (length === 0) {\n                  return this.cache[id] = null;\n              }\n              data.pos = this.offset + index;\n              raw = new Data(data.read(length));\n              numberOfContours = raw.readShort();\n              xMin = raw.readShort();\n              yMin = raw.readShort();\n              xMax = raw.readShort();\n              yMax = raw.readShort();\n              if (numberOfContours === -1) {\n                  this.cache[id] = new CompoundGlyph(raw, xMin, yMin, xMax, yMax);\n              }\n              else {\n                  this.cache[id] = new SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax);\n              }\n              return this.cache[id];\n          };\n          GlyfTable.prototype.encode = function (glyphs, mapping, old2new) {\n              var glyph, id, offsets, table, _i, _len;\n              table = [];\n              offsets = [];\n              for (_i = 0, _len = mapping.length; _i < _len; _i++) {\n                  id = mapping[_i];\n                  glyph = glyphs[id];\n                  offsets.push(table.length);\n                  if (glyph) {\n                      table = table.concat(glyph.encode(old2new));\n                  }\n              }\n              offsets.push(table.length);\n              return {\n                  table: table\n                  , offsets: offsets\n              };\n          };\n          return GlyfTable;\n      })(Table);\n\n      var SimpleGlyph = (function () {\n          /**************************************************************************/\n          /* function : SimpleGlyph                                                 */\n          /* comment : Stores raw, xMin, yMin, xMax, and yMax values for this glyph.*/\n          /**************************************************************************/\n          function SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax) {\n              this.raw = raw;\n              this.numberOfContours = numberOfContours;\n              this.xMin = xMin;\n              this.yMin = yMin;\n              this.xMax = xMax;\n              this.yMax = yMax;\n              this.compound = false;\n          }\n          SimpleGlyph.prototype.encode = function () {\n              return this.raw.data;\n          };\n          return SimpleGlyph;\n      })();\n\n      var CompoundGlyph = (function () {\n          var ARG_1_AND_2_ARE_WORDS, MORE_COMPONENTS, WE_HAVE_AN_X_AND_Y_SCALE, WE_HAVE_A_SCALE, WE_HAVE_A_TWO_BY_TWO;\n          ARG_1_AND_2_ARE_WORDS = 0x0001;\n          WE_HAVE_A_SCALE = 0x0008;\n          MORE_COMPONENTS = 0x0020;\n          WE_HAVE_AN_X_AND_Y_SCALE = 0x0040;\n          WE_HAVE_A_TWO_BY_TWO = 0x0080;\n\n          /********************************************************************************************************************/\n          /* function : CompoundGlypg generator                                                                               */\n          /* comment : It stores raw, xMin, yMin, xMax, yMax, glyph id, and glyph offset for the corresponding compound glyph.*/\n          /********************************************************************************************************************/\n          function CompoundGlyph(raw, xMin, yMin, xMax, yMax) {\n              var data, flags;\n              this.raw = raw;\n              this.xMin = xMin;\n              this.yMin = yMin;\n              this.xMax = xMax;\n              this.yMax = yMax;\n              this.compound = true;\n              this.glyphIDs = [];\n              this.glyphOffsets = [];\n              data = this.raw;\n              while (true) {\n                  flags = data.readShort();\n                  this.glyphOffsets.push(data.pos);\n                  this.glyphIDs.push(data.readShort());\n                  if (!(flags & MORE_COMPONENTS)) {\n                      break;\n                  }\n                  if (flags & ARG_1_AND_2_ARE_WORDS) {\n                      data.pos += 4;\n                  }\n                  else {\n                      data.pos += 2;\n                  }\n                  if (flags & WE_HAVE_A_TWO_BY_TWO) {\n                      data.pos += 8;\n                  }\n                  else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {\n                      data.pos += 4;\n                  }\n                  else if (flags & WE_HAVE_A_SCALE) {\n                      data.pos += 2;\n                  }\n              }\n          }\n          /****************************************************************************************************************/\n          /* function : CompoundGlypg encode                                                                              */\n          /* comment : After creating a table for the characters you typed, you call directory.encode to encode the table.*/\n          /****************************************************************************************************************/\n          CompoundGlyph.prototype.encode = function (mapping) {\n              var i, id, result, _i, _len, _ref;\n              result = new Data(__slice.call(this.raw.data));\n              _ref = this.glyphIDs;\n              for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {\n                  id = _ref[i];\n                  result.pos = this.glyphOffsets[i];\n              }\n              return result.data;\n          };\n          return CompoundGlyph;\n      })();\n\n      var LocaTable = (function (_super) {\n          __extends(LocaTable, _super);\n\n          function LocaTable() {\n              return LocaTable.__super__.constructor.apply(this, arguments);\n          }\n          LocaTable.prototype.tag = 'loca';\n          LocaTable.prototype.parse = function (data) {\n              var format, i;\n              data.pos = this.offset;\n              format = this.file.head.indexToLocFormat;\n              if (format === 0) {\n                  return this.offsets = (function () {\n                      var _i, _ref, _results;\n                      _results = [];\n                      for (i = _i = 0, _ref = this.length; _i < _ref; i = _i += 2) {\n                          _results.push(data.readUInt16() * 2);\n                      }\n                      return _results;\n                  }).call(this);\n              }\n              else {\n                  return this.offsets = (function () {\n                      var _i, _ref, _results;\n                      _results = [];\n                      for (i = _i = 0, _ref = this.length; _i < _ref; i = _i += 4) {\n                          _results.push(data.readUInt32());\n                      }\n                      return _results;\n                  }).call(this);\n              }\n          };\n          LocaTable.prototype.indexOf = function (id) {\n              return this.offsets[id];\n          };\n          LocaTable.prototype.lengthOf = function (id) {\n              return this.offsets[id + 1] - this.offsets[id];\n          };\n          LocaTable.prototype.encode = function (offsets, activeGlyphs) {\n              var LocaTable = new Uint32Array(this.offsets.length);\n              var glyfPtr = 0;\n              var listGlyf = 0;\n              for (var k = 0; k < LocaTable.length; ++k) {\n                  LocaTable[k] = glyfPtr;\n                  if (listGlyf < activeGlyphs.length && activeGlyphs[listGlyf] == k) {\n                      ++listGlyf;\n                      LocaTable[k] = glyfPtr;\n                      var start = this.offsets[k];\n                      var len = this.offsets[k + 1] - start;\n                      if (len > 0) {\n                          glyfPtr += len;\n                      }\n                  }\n              }\n              var newLocaTable = new Array(LocaTable.length * 4);\n              for (var j = 0; j < LocaTable.length; ++j) {\n                  newLocaTable[4 * j + 3] = (LocaTable[j] & 0x000000ff);\n                  newLocaTable[4 * j + 2] = (LocaTable[j] & 0x0000ff00) >> 8;\n                  newLocaTable[4 * j + 1] = (LocaTable[j] & 0x00ff0000) >> 16;\n                  newLocaTable[4 * j] = (LocaTable[j] & 0xff000000) >> 24;\n              }\n              return newLocaTable;\n          };\n          return LocaTable;\n      })(Table);\n\n      /************************************************************************************/\n      /* function : invert                                                                */\n      /* comment : Change the object's (key: value) to create an object with (value: key).*/\n      /************************************************************************************/\n      var invert = function (object) {\n          var key, ret, val;\n          ret = {};\n          for (key in object) {\n              val = object[key];\n              ret[val] = key;\n          }\n          return ret;\n      };\n\n      /*var successorOf = function (input) {\n          var added, alphabet, carry, i, index, isUpperCase, last, length, next, result;\n          alphabet = 'abcdefghijklmnopqrstuvwxyz';\n          length = alphabet.length;\n          result = input;\n          i = input.length;\n          while (i >= 0) {\n              last = input.charAt(--i);\n              if (isNaN(last)) {\n                  index = alphabet.indexOf(last.toLowerCase());\n                  if (index === -1) {\n                      next = last;\n                      carry = true;\n                  }\n                  else {\n                      next = alphabet.charAt((index + 1) % length);\n                      isUpperCase = last === last.toUpperCase();\n                      if (isUpperCase) {\n                          next = next.toUpperCase();\n                      }\n                      carry = index + 1 >= length;\n                      if (carry && i === 0) {\n                          added = isUpperCase ? 'A' : 'a';\n                          result = added + next + result.slice(1);\n                          break;\n                      }\n                  }\n              }\n              else {\n                  next = +last + 1;\n                  carry = next > 9;\n                  if (carry) {\n                      next = 0;\n                  }\n                  if (carry && i === 0) {\n                      result = '1' + next + result.slice(1);\n                      break;\n                  }\n              }\n              result = result.slice(0, i) + next + result.slice(i + 1);\n              if (!carry) {\n                  break;\n              }\n          }\n          return result;\n      };*/\n\n      var Subset = (function () {\n          function Subset(font) {\n              this.font = font;\n              this.subset = {};\n              this.unicodes = {};\n              this.next = 33;\n          }\n          /*Subset.prototype.use = function (character) {\n              var i, _i, _ref;\n              if (typeof character === 'string') {\n                  for (i = _i = 0, _ref = character.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n                      this.use(character.charCodeAt(i));\n                  }\n                  return;\n              }\n              if (!this.unicodes[character]) {\n                  this.subset[this.next] = character;\n                  return this.unicodes[character] = this.next++;\n              }\n          };*/\n          /*Subset.prototype.encodeText = function (text) {\n              var char, i, string, _i, _ref;\n              string = '';\n              for (i = _i = 0, _ref = text.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n                  char = this.unicodes[text.charCodeAt(i)];\n                  string += String.fromCharCode(char);\n              }\n              return string;\n          };*/\n          /***************************************************************/\n          /* function : generateCmap                                     */\n          /* comment : Returns the unicode cmap for this font.         */\n          /***************************************************************/\n          Subset.prototype.generateCmap = function () {\n              var mapping, roman, unicode, unicodeCmap, _ref;\n              unicodeCmap = this.font.cmap.tables[0].codeMap;\n              mapping = {};\n              _ref = this.subset;\n              for (roman in _ref) {\n                  unicode = _ref[roman];\n                  mapping[roman] = unicodeCmap[unicode];\n              }\n              return mapping;\n          };\n          /*Subset.prototype.glyphIDs = function () {\n              var ret, roman, unicode, unicodeCmap, val, _ref;\n              unicodeCmap = this.font.cmap.tables[0].codeMap;\n              ret = [0];\n              _ref = this.subset;\n              for (roman in _ref) {\n                  unicode = _ref[roman];\n                  val = unicodeCmap[unicode];\n                  if ((val != null) && __indexOf.call(ret, val) < 0) {\n                      ret.push(val);\n                  }\n              }\n              return ret.sort();\n          };*/\n          /******************************************************************/\n          /* function : glyphsFor                                           */\n          /* comment : Returns simple glyph objects for the input character.*/\n          /******************************************************************/\n          Subset.prototype.glyphsFor = function (glyphIDs) {\n              var additionalIDs, glyph, glyphs, id, _i, _len, _ref;\n              glyphs = {};\n              for (_i = 0, _len = glyphIDs.length; _i < _len; _i++) {\n                  id = glyphIDs[_i];\n                  glyphs[id] = this.font.glyf.glyphFor(id);\n              }\n              additionalIDs = [];\n              for (id in glyphs) {\n                  glyph = glyphs[id];\n                  if (glyph != null ? glyph.compound : void 0) {\n                      additionalIDs.push.apply(additionalIDs, glyph.glyphIDs);\n                  }\n              }\n              if (additionalIDs.length > 0) {\n                  _ref = this.glyphsFor(additionalIDs);\n                  for (id in _ref) {\n                      glyph = _ref[id];\n                      glyphs[id] = glyph;\n                  }\n              }\n              return glyphs;\n          };\n          /***************************************************************/\n          /* function : encode                                           */\n          /* comment : Encode various tables for the characters you use. */\n          /***************************************************************/\n          Subset.prototype.encode = function (glyID) {\n              var cmap, code, glyf, glyphs, id, ids, loca, new2old, newIDs, nextGlyphID, old2new, oldID, oldIDs, tables, _ref;\n              cmap = CmapTable.encode(this.generateCmap(), 'unicode');\n              glyphs = this.glyphsFor(glyID);\n              old2new = {\n                  0: 0\n              };\n              _ref = cmap.charMap;\n              for (code in _ref) {\n                  ids = _ref[code];\n                  old2new[ids.old] = ids[\"new\"];\n              }\n              nextGlyphID = cmap.maxGlyphID;\n              for (oldID in glyphs) {\n                  if (!(oldID in old2new)) {\n                      old2new[oldID] = nextGlyphID++;\n                  }\n              }\n              new2old = invert(old2new);\n              newIDs = Object.keys(new2old).sort(function (a, b) {\n                  return a - b;\n              });\n              oldIDs = (function () {\n                  var _i, _len, _results;\n                  _results = [];\n                  for (_i = 0, _len = newIDs.length; _i < _len; _i++) {\n                      id = newIDs[_i];\n                      _results.push(new2old[id]);\n                  }\n                  return _results;\n              })();\n              glyf = this.font.glyf.encode(glyphs, oldIDs, old2new);\n              loca = this.font.loca.encode(glyf.offsets, oldIDs);\n              tables = {\n                  cmap: this.font.cmap.raw()\n                  , glyf: glyf.table\n                  , loca: loca\n                  , hmtx: this.font.hmtx.raw()\n                  , hhea: this.font.hhea.raw()\n                  , maxp: this.font.maxp.raw()\n                  , post: this.font.post.raw()\n                  , name: this.font.name.raw()\n                  , head: this.font.head.raw()\n              };\n              if (this.font.os2.exists) {\n                  tables['OS/2'] = this.font.os2.raw();\n              }\n              return this.font.directory.encode(tables);\n          };\n          return Subset;\n      })();\n\n      jsPDF.API.PDFObject = (function () {\n          var pad;\n\n          function PDFObject() {}\n          pad = function (str, length) {\n              return (Array(length + 1).join('0') + str).slice(-length);\n          };\n          /*****************************************************************************/\n          /* function : convert                                                        */\n          /* comment :Converts pdf tag's / FontBBox and array values in / W to strings */\n          /*****************************************************************************/\n          PDFObject.convert = function (object) {\n              var e, items, key, out, val;\n              if (Array.isArray(object)) {\n                  items = ((function () {\n                      var _i, _len, _results;\n                      _results = [];\n                      for (_i = 0, _len = object.length; _i < _len; _i++) {\n                          e = object[_i];\n                          _results.push(PDFObject.convert(e));\n                      }\n                      return _results;\n                  })()).join(' ');\n                  return '[' + items + ']';\n              }\n              else if (typeof object === 'string') {\n                  return '/' + object;\n              }\n              else if (object != null ? object.isString : void 0) {\n                  return '(' + object + ')';\n              }\n              else if (object instanceof Date) {\n                  return '(D:' + pad(object.getUTCFullYear(), 4) + pad(object.getUTCMonth(), 2) + pad(object.getUTCDate(), 2) + pad(object.getUTCHours(), 2) + pad(object.getUTCMinutes(), 2) + pad(object.getUTCSeconds(), 2) + 'Z)';\n              }\n              else if ({}.toString.call(object) === '[object Object]') {\n                  out = ['<<'];\n                  for (key in object) {\n                      val = object[key];\n                      out.push('/' + key + ' ' + PDFObject.convert(val));\n                  }\n                  out.push('>>');\n                  return out.join('\\n');\n              }\n              else {\n                  return '' + object;\n              }\n          };\n          return PDFObject;\n      })();\n  })(jsPDF);\n\n  // Generated by CoffeeScript 1.4.0\n\n  /*\n  # PNG.js\n  # Copyright (c) 2011 Devon Govett\n  # MIT LICENSE\n  # \n  # \n  */\n\n\n  (function(global) {\n    var PNG;\n\n    PNG = (function() {\n      var APNG_BLEND_OP_SOURCE, APNG_DISPOSE_OP_BACKGROUND, APNG_DISPOSE_OP_PREVIOUS, makeImage, scratchCanvas, scratchCtx;\n\n      PNG.load = function(url, canvas, callback) {\n        var xhr;\n        if (typeof canvas === 'function') {\n          callback = canvas;\n        }\n        xhr = new XMLHttpRequest;\n        xhr.open(\"GET\", url, true);\n        xhr.responseType = \"arraybuffer\";\n        xhr.onload = function() {\n          var data, png;\n          data = new Uint8Array(xhr.response || xhr.mozResponseArrayBuffer);\n          png = new PNG(data);\n          if (typeof (canvas != null ? canvas.getContext : void 0) === 'function') {\n            png.render(canvas);\n          }\n          return typeof callback === \"function\" ? callback(png) : void 0;\n        };\n        return xhr.send(null);\n      };\n\n      APNG_DISPOSE_OP_BACKGROUND = 1;\n\n      APNG_DISPOSE_OP_PREVIOUS = 2;\n\n      APNG_BLEND_OP_SOURCE = 0;\n\n      function PNG(data) {\n        var chunkSize, colors, palLen, delayDen, delayNum, frame, i, index, key, section, palShort, text, _i, _j, _ref;\n        this.data = data;\n        this.pos = 8;\n        this.palette = [];\n        this.imgData = [];\n        this.transparency = {};\n        this.animation = null;\n        this.text = {};\n        frame = null;\n        while (true) {\n          chunkSize = this.readUInt32();\n          section = ((function() {\n            var _i, _results;\n            _results = [];\n            for (i = _i = 0; _i < 4; i = ++_i) {\n              _results.push(String.fromCharCode(this.data[this.pos++]));\n            }\n            return _results;\n          }).call(this)).join('');\n          switch (section) {\n            case 'IHDR':\n              this.width = this.readUInt32();\n              this.height = this.readUInt32();\n              this.bits = this.data[this.pos++];\n              this.colorType = this.data[this.pos++];\n              this.compressionMethod = this.data[this.pos++];\n              this.filterMethod = this.data[this.pos++];\n              this.interlaceMethod = this.data[this.pos++];\n              break;\n            case 'acTL':\n              this.animation = {\n                numFrames: this.readUInt32(),\n                numPlays: this.readUInt32() || Infinity,\n                frames: []\n              };\n              break;\n            case 'PLTE':\n              this.palette = this.read(chunkSize);\n              break;\n            case 'fcTL':\n              if (frame) {\n                this.animation.frames.push(frame);\n              }\n              this.pos += 4;\n              frame = {\n                width: this.readUInt32(),\n                height: this.readUInt32(),\n                xOffset: this.readUInt32(),\n                yOffset: this.readUInt32()\n              };\n              delayNum = this.readUInt16();\n              delayDen = this.readUInt16() || 100;\n              frame.delay = 1000 * delayNum / delayDen;\n              frame.disposeOp = this.data[this.pos++];\n              frame.blendOp = this.data[this.pos++];\n              frame.data = [];\n              break;\n            case 'IDAT':\n            case 'fdAT':\n              if (section === 'fdAT') {\n                this.pos += 4;\n                chunkSize -= 4;\n              }\n              data = (frame != null ? frame.data : void 0) || this.imgData;\n              for (i = _i = 0; 0 <= chunkSize ? _i < chunkSize : _i > chunkSize; i = 0 <= chunkSize ? ++_i : --_i) {\n                data.push(this.data[this.pos++]);\n              }\n              break;\n            case 'tRNS':\n              this.transparency = {};\n              switch (this.colorType) {\n                case 3:\n              \tpalLen = this.palette.length/3;\n                  this.transparency.indexed = this.read(chunkSize);\n                  if(this.transparency.indexed.length > palLen)\n                  \tthrow new Error('More transparent colors than palette size');\n                  /*\n                   * According to the PNG spec trns should be increased to the same size as palette if shorter\n                   */\n                  //palShort = 255 - this.transparency.indexed.length;\n                  palShort = palLen - this.transparency.indexed.length;\n                  if (palShort > 0) {\n                    for (i = _j = 0; 0 <= palShort ? _j < palShort : _j > palShort; i = 0 <= palShort ? ++_j : --_j) {\n                      this.transparency.indexed.push(255);\n                    }\n                  }\n                  break;\n                case 0:\n                  this.transparency.grayscale = this.read(chunkSize)[0];\n                  break;\n                case 2:\n                  this.transparency.rgb = this.read(chunkSize);\n              }\n              break;\n            case 'tEXt':\n              text = this.read(chunkSize);\n              index = text.indexOf(0);\n              key = String.fromCharCode.apply(String, text.slice(0, index));\n              this.text[key] = String.fromCharCode.apply(String, text.slice(index + 1));\n              break;\n            case 'IEND':\n              if (frame) {\n                this.animation.frames.push(frame);\n              }\n              this.colors = (function() {\n                switch (this.colorType) {\n                  case 0:\n                  case 3:\n                  case 4:\n                    return 1;\n                  case 2:\n                  case 6:\n                    return 3;\n                }\n              }).call(this);\n              this.hasAlphaChannel = (_ref = this.colorType) === 4 || _ref === 6;\n              colors = this.colors + (this.hasAlphaChannel ? 1 : 0);\n              this.pixelBitlength = this.bits * colors;\n              this.colorSpace = (function() {\n                switch (this.colors) {\n                  case 1:\n                    return 'DeviceGray';\n                  case 3:\n                    return 'DeviceRGB';\n                }\n              }).call(this);\n              this.imgData = new Uint8Array(this.imgData);\n              return;\n            default:\n              this.pos += chunkSize;\n          }\n          this.pos += 4;\n          if (this.pos > this.data.length) {\n            throw new Error(\"Incomplete or corrupt PNG file\");\n          }\n        }\n        return;\n      }\n\n      PNG.prototype.read = function(bytes) {\n        var i, _i, _results;\n        _results = [];\n        for (i = _i = 0; 0 <= bytes ? _i < bytes : _i > bytes; i = 0 <= bytes ? ++_i : --_i) {\n          _results.push(this.data[this.pos++]);\n        }\n        return _results;\n      };\n\n      PNG.prototype.readUInt32 = function() {\n        var b1, b2, b3, b4;\n        b1 = this.data[this.pos++] << 24;\n        b2 = this.data[this.pos++] << 16;\n        b3 = this.data[this.pos++] << 8;\n        b4 = this.data[this.pos++];\n        return b1 | b2 | b3 | b4;\n      };\n\n      PNG.prototype.readUInt16 = function() {\n        var b1, b2;\n        b1 = this.data[this.pos++] << 8;\n        b2 = this.data[this.pos++];\n        return b1 | b2;\n      };\n\n\n      PNG.prototype.decodePixels = function(data) {\n        var pixelBytes = this.pixelBitlength / 8;\n        var fullPixels = new Uint8Array(this.width * this.height * pixelBytes);\n        var pos = 0;\n        var _this = this;\n        \n        if (data == null) {\n            data = this.imgData;\n        }\n        if (data.length === 0) {\n            return new Uint8Array(0);\n        }\n        \n        data = new FlateStream(data);\n        data = data.getBytes();\n        function pass (x0, y0, dx, dy) {\n            var abyte, c, col, i, left, length, p, pa, paeth, pb, pc, pixels, row, scanlineLength, upper, upperLeft, _i, _j, _k, _l, _m;\n            var w = Math.ceil((_this.width - x0) / dx), h = Math.ceil((_this.height - y0) / dy);\n            var isFull = _this.width == w && _this.height == h;\n            scanlineLength = pixelBytes * w;\n            pixels = isFull ? fullPixels : new Uint8Array(scanlineLength * h);\n            length = data.length;\n            row = 0;\n            c = 0;\n            while (row < h && pos < length) {\n              switch (data[pos++]) {\n                case 0:\n                  for (i = _i = 0; _i < scanlineLength; i = _i += 1) {\n                    pixels[c++] = data[pos++];\n                  }\n                  break;\n                case 1:\n                  for (i = _j = 0; _j < scanlineLength; i = _j += 1) {\n                    abyte = data[pos++];\n                    left = i < pixelBytes ? 0 : pixels[c - pixelBytes];\n                    pixels[c++] = (abyte + left) % 256;\n                  }\n                  break;\n                case 2:\n                  for (i = _k = 0; _k < scanlineLength; i = _k += 1) {\n                    abyte = data[pos++];\n                    col = (i - (i % pixelBytes)) / pixelBytes;\n                    upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];\n                    pixels[c++] = (upper + abyte) % 256;\n                  }\n                  break;\n                case 3:\n                  for (i = _l = 0; _l < scanlineLength; i = _l += 1) {\n                    abyte = data[pos++];\n                    col = (i - (i % pixelBytes)) / pixelBytes;\n                    left = i < pixelBytes ? 0 : pixels[c - pixelBytes];\n                    upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];\n                    pixels[c++] = (abyte + Math.floor((left + upper) / 2)) % 256;\n                  }\n                  break;\n                case 4:\n                  for (i = _m = 0; _m < scanlineLength; i = _m += 1) {\n                    abyte = data[pos++];\n                    col = (i - (i % pixelBytes)) / pixelBytes;\n                    left = i < pixelBytes ? 0 : pixels[c - pixelBytes];\n                    if (row === 0) {\n                      upper = upperLeft = 0;\n                    } else {\n                      upper = pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];\n                      upperLeft = col && pixels[(row - 1) * scanlineLength + (col - 1) * pixelBytes + (i % pixelBytes)];\n                    }\n                    p = left + upper - upperLeft;\n                    pa = Math.abs(p - left);\n                    pb = Math.abs(p - upper);\n                    pc = Math.abs(p - upperLeft);\n                    if (pa <= pb && pa <= pc) {\n                      paeth = left;\n                    } else if (pb <= pc) {\n                      paeth = upper;\n                    } else {\n                      paeth = upperLeft;\n                    }\n                    pixels[c++] = (abyte + paeth) % 256;\n                  }\n                  break;\n                default:\n                  throw new Error(\"Invalid filter algorithm: \" + data[pos - 1]);\n              }\n              if (!isFull) {\n                  var fullPos = ((y0 + row * dy) * _this.width + x0) * pixelBytes;\n                  var partPos = row * scanlineLength;\n                  for (i = 0; i < w; i += 1) {\n                    for (var j = 0; j < pixelBytes; j += 1)\n                      fullPixels[fullPos++] = pixels[partPos++];\n                    fullPos += (dx - 1) * pixelBytes;\n                  }\n                }\n              row++;\n            }\n        }\n        if (_this.interlaceMethod == 1) {\n            /*\n              1 6 4 6 2 6 4 6\n              7 7 7 7 7 7 7 7\n              5 6 5 6 5 6 5 6\n              7 7 7 7 7 7 7 7\n              3 6 4 6 3 6 4 6\n              7 7 7 7 7 7 7 7\n              5 6 5 6 5 6 5 6\n              7 7 7 7 7 7 7 7\n            */\n            pass(0, 0, 8, 8); // 1\n            /* NOTE these seem to follow the pattern:\n             * pass(x, 0, 2*x, 2*x);\n             * pass(0, x,   x, 2*x);\n             * with x being 4, 2, 1.\n             */\n            pass(4, 0, 8, 8); // 2\n            pass(0, 4, 4, 8); // 3\n\n            pass(2, 0, 4, 4); // 4\n            pass(0, 2, 2, 4); // 5\n\n            pass(1, 0, 2, 2); // 6\n            pass(0, 1, 1, 2); // 7\n          } else {\n            pass(0, 0, 1, 1);\n          }\n        return fullPixels;\n      };\n\n      PNG.prototype.decodePalette = function() {\n        var c, i, length, palette, pos, ret, transparency, _i, _ref, _ref1;\n        palette = this.palette;\n        transparency = this.transparency.indexed || [];\n        ret = new Uint8Array((transparency.length || 0) + palette.length);\n        pos = 0;\n        length = palette.length;\n        c = 0;\n        for (i = _i = 0, _ref = palette.length; _i < _ref; i = _i += 3) {\n          ret[pos++] = palette[i];\n          ret[pos++] = palette[i + 1];\n          ret[pos++] = palette[i + 2];\n          ret[pos++] = (_ref1 = transparency[c++]) != null ? _ref1 : 255;\n        }\n        return ret;\n      };\n\n      PNG.prototype.copyToImageData = function(imageData, pixels) {\n        var alpha, colors, data, i, input, j, k, length, palette, v, _ref;\n        colors = this.colors;\n        palette = null;\n        alpha = this.hasAlphaChannel;\n        if (this.palette.length) {\n          palette = (_ref = this._decodedPalette) != null ? _ref : this._decodedPalette = this.decodePalette();\n          colors = 4;\n          alpha = true;\n        }\n        data = imageData.data || imageData;\n        length = data.length;\n        input = palette || pixels;\n        i = j = 0;\n        if (colors === 1) {\n          while (i < length) {\n            k = palette ? pixels[i / 4] * 4 : j;\n            v = input[k++];\n            data[i++] = v;\n            data[i++] = v;\n            data[i++] = v;\n            data[i++] = alpha ? input[k++] : 255;\n            j = k;\n          }\n        } else {\n          while (i < length) {\n            k = palette ? pixels[i / 4] * 4 : j;\n            data[i++] = input[k++];\n            data[i++] = input[k++];\n            data[i++] = input[k++];\n            data[i++] = alpha ? input[k++] : 255;\n            j = k;\n          }\n        }\n      };\n\n      PNG.prototype.decode = function() {\n        var ret;\n        ret = new Uint8Array(this.width * this.height * 4);\n        this.copyToImageData(ret, this.decodePixels());\n        return ret;\n      };\n\n      try {\n          scratchCanvas = global.document.createElement('canvas');\n          scratchCtx = scratchCanvas.getContext('2d');\n      } catch(e) {\n          return -1;\n      }\n\n      makeImage = function(imageData) {\n        var img;\n        scratchCtx.width = imageData.width;\n        scratchCtx.height = imageData.height;\n        scratchCtx.clearRect(0, 0, imageData.width, imageData.height);\n        scratchCtx.putImageData(imageData, 0, 0);\n        img = new Image;\n        img.src = scratchCanvas.toDataURL();\n        return img;\n      };\n\n      PNG.prototype.decodeFrames = function(ctx) {\n        var frame, i, imageData, pixels, _i, _len, _ref, _results;\n        if (!this.animation) {\n          return;\n        }\n        _ref = this.animation.frames;\n        _results = [];\n        for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {\n          frame = _ref[i];\n          imageData = ctx.createImageData(frame.width, frame.height);\n          pixels = this.decodePixels(new Uint8Array(frame.data));\n          this.copyToImageData(imageData, pixels);\n          frame.imageData = imageData;\n          _results.push(frame.image = makeImage(imageData));\n        }\n        return _results;\n      };\n\n      PNG.prototype.renderFrame = function(ctx, number) {\n        var frame, frames, prev;\n        frames = this.animation.frames;\n        frame = frames[number];\n        prev = frames[number - 1];\n        if (number === 0) {\n          ctx.clearRect(0, 0, this.width, this.height);\n        }\n        if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_BACKGROUND) {\n          ctx.clearRect(prev.xOffset, prev.yOffset, prev.width, prev.height);\n        } else if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_PREVIOUS) {\n          ctx.putImageData(prev.imageData, prev.xOffset, prev.yOffset);\n        }\n        if (frame.blendOp === APNG_BLEND_OP_SOURCE) {\n          ctx.clearRect(frame.xOffset, frame.yOffset, frame.width, frame.height);\n        }\n        return ctx.drawImage(frame.image, frame.xOffset, frame.yOffset);\n      };\n\n      PNG.prototype.animate = function(ctx) {\n        var doFrame, frameNumber, frames, numFrames, numPlays, _ref,\n          _this = this;\n        frameNumber = 0;\n        _ref = this.animation, numFrames = _ref.numFrames, frames = _ref.frames, numPlays = _ref.numPlays;\n        return (doFrame = function() {\n          var f, frame;\n          f = frameNumber++ % numFrames;\n          frame = frames[f];\n          _this.renderFrame(ctx, f);\n          if (numFrames > 1 && frameNumber / numFrames < numPlays) {\n            return _this.animation._timeout = setTimeout(doFrame, frame.delay);\n          }\n        })();\n      };\n\n      PNG.prototype.stopAnimation = function() {\n        var _ref;\n        return clearTimeout((_ref = this.animation) != null ? _ref._timeout : void 0);\n      };\n\n      PNG.prototype.render = function(canvas) {\n        var ctx, data;\n        if (canvas._png) {\n          canvas._png.stopAnimation();\n        }\n        canvas._png = this;\n        canvas.width = this.width;\n        canvas.height = this.height;\n        ctx = canvas.getContext(\"2d\");\n        if (this.animation) {\n          this.decodeFrames(ctx);\n          return this.animate(ctx);\n        } else {\n          data = ctx.createImageData(this.width, this.height);\n          this.copyToImageData(data, this.decodePixels());\n          return ctx.putImageData(data, 0, 0);\n        }\n      };\n\n      return PNG;\n\n    })();\n\n    global.PNG = PNG;\n\n  }(typeof self !== \"undefined\" && self || typeof window !== \"undefined\" && window || typeof global !== \"undefined\" && global ||  Function('return typeof this === \"object\" && this.content')() || Function('return this')()));\n  // `self` is undefined in Firefox for Android content script context\n  // while `this` is nsIContentFrameMessageManager\n  // with an attribute `content` that corresponds to the window\n\n  /*\n   * Extracted from pdf.js\n   * https://github.com/andreasgal/pdf.js\n   *\n   * Copyright (c) 2011 Mozilla Foundation\n   *\n   * Contributors: Andreas Gal <gal@mozilla.com>\n   *               Chris G Jones <cjones@mozilla.com>\n   *               Shaon Barman <shaon.barman@gmail.com>\n   *               Vivien Nicolas <21@vingtetun.org>\n   *               Justin D'Arcangelo <justindarc@gmail.com>\n   *               Yury Delendik\n   *\n   * \n   */\n\n  var DecodeStream = (function() {\n    function constructor() {\n      this.pos = 0;\n      this.bufferLength = 0;\n      this.eof = false;\n      this.buffer = null;\n    }\n\n    constructor.prototype = {\n      ensureBuffer: function decodestream_ensureBuffer(requested) {\n        var buffer = this.buffer;\n        var current = buffer ? buffer.byteLength : 0;\n        if (requested < current)\n          return buffer;\n        var size = 512;\n        while (size < requested)\n          size <<= 1;\n        var buffer2 = new Uint8Array(size);\n        for (var i = 0; i < current; ++i)\n          buffer2[i] = buffer[i];\n        return this.buffer = buffer2;\n      },\n      getByte: function decodestream_getByte() {\n        var pos = this.pos;\n        while (this.bufferLength <= pos) {\n          if (this.eof)\n            return null;\n          this.readBlock();\n        }\n        return this.buffer[this.pos++];\n      },\n      getBytes: function decodestream_getBytes(length) {\n        var pos = this.pos;\n\n        if (length) {\n          this.ensureBuffer(pos + length);\n          var end = pos + length;\n\n          while (!this.eof && this.bufferLength < end)\n            this.readBlock();\n\n          var bufEnd = this.bufferLength;\n          if (end > bufEnd)\n            end = bufEnd;\n        } else {\n          while (!this.eof)\n            this.readBlock();\n\n          var end = this.bufferLength;\n        }\n\n        this.pos = end;\n        return this.buffer.subarray(pos, end);\n      },\n      lookChar: function decodestream_lookChar() {\n        var pos = this.pos;\n        while (this.bufferLength <= pos) {\n          if (this.eof)\n            return null;\n          this.readBlock();\n        }\n        return String.fromCharCode(this.buffer[this.pos]);\n      },\n      getChar: function decodestream_getChar() {\n        var pos = this.pos;\n        while (this.bufferLength <= pos) {\n          if (this.eof)\n            return null;\n          this.readBlock();\n        }\n        return String.fromCharCode(this.buffer[this.pos++]);\n      },\n      makeSubStream: function decodestream_makeSubstream(start, length, dict) {\n        var end = start + length;\n        while (this.bufferLength <= end && !this.eof)\n          this.readBlock();\n        return new Stream(this.buffer, start, length, dict);\n      },\n      skip: function decodestream_skip(n) {\n        if (!n)\n          n = 1;\n        this.pos += n;\n      },\n      reset: function decodestream_reset() {\n        this.pos = 0;\n      }\n    };\n\n    return constructor;\n  })();\n\n  var FlateStream = (function() {\n    if (typeof Uint32Array === 'undefined') {\n      return undefined;\n    }\n    var codeLenCodeMap = new Uint32Array([\n      16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15\n    ]);\n\n    var lengthDecode = new Uint32Array([\n      0x00003, 0x00004, 0x00005, 0x00006, 0x00007, 0x00008, 0x00009, 0x0000a,\n      0x1000b, 0x1000d, 0x1000f, 0x10011, 0x20013, 0x20017, 0x2001b, 0x2001f,\n      0x30023, 0x3002b, 0x30033, 0x3003b, 0x40043, 0x40053, 0x40063, 0x40073,\n      0x50083, 0x500a3, 0x500c3, 0x500e3, 0x00102, 0x00102, 0x00102\n    ]);\n\n    var distDecode = new Uint32Array([\n      0x00001, 0x00002, 0x00003, 0x00004, 0x10005, 0x10007, 0x20009, 0x2000d,\n      0x30011, 0x30019, 0x40021, 0x40031, 0x50041, 0x50061, 0x60081, 0x600c1,\n      0x70101, 0x70181, 0x80201, 0x80301, 0x90401, 0x90601, 0xa0801, 0xa0c01,\n      0xb1001, 0xb1801, 0xc2001, 0xc3001, 0xd4001, 0xd6001\n    ]);\n\n    var fixedLitCodeTab = [new Uint32Array([\n      0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c0,\n      0x70108, 0x80060, 0x80020, 0x900a0, 0x80000, 0x80080, 0x80040, 0x900e0,\n      0x70104, 0x80058, 0x80018, 0x90090, 0x70114, 0x80078, 0x80038, 0x900d0,\n      0x7010c, 0x80068, 0x80028, 0x900b0, 0x80008, 0x80088, 0x80048, 0x900f0,\n      0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c8,\n      0x7010a, 0x80064, 0x80024, 0x900a8, 0x80004, 0x80084, 0x80044, 0x900e8,\n      0x70106, 0x8005c, 0x8001c, 0x90098, 0x70116, 0x8007c, 0x8003c, 0x900d8,\n      0x7010e, 0x8006c, 0x8002c, 0x900b8, 0x8000c, 0x8008c, 0x8004c, 0x900f8,\n      0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c4,\n      0x70109, 0x80062, 0x80022, 0x900a4, 0x80002, 0x80082, 0x80042, 0x900e4,\n      0x70105, 0x8005a, 0x8001a, 0x90094, 0x70115, 0x8007a, 0x8003a, 0x900d4,\n      0x7010d, 0x8006a, 0x8002a, 0x900b4, 0x8000a, 0x8008a, 0x8004a, 0x900f4,\n      0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cc,\n      0x7010b, 0x80066, 0x80026, 0x900ac, 0x80006, 0x80086, 0x80046, 0x900ec,\n      0x70107, 0x8005e, 0x8001e, 0x9009c, 0x70117, 0x8007e, 0x8003e, 0x900dc,\n      0x7010f, 0x8006e, 0x8002e, 0x900bc, 0x8000e, 0x8008e, 0x8004e, 0x900fc,\n      0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c2,\n      0x70108, 0x80061, 0x80021, 0x900a2, 0x80001, 0x80081, 0x80041, 0x900e2,\n      0x70104, 0x80059, 0x80019, 0x90092, 0x70114, 0x80079, 0x80039, 0x900d2,\n      0x7010c, 0x80069, 0x80029, 0x900b2, 0x80009, 0x80089, 0x80049, 0x900f2,\n      0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900ca,\n      0x7010a, 0x80065, 0x80025, 0x900aa, 0x80005, 0x80085, 0x80045, 0x900ea,\n      0x70106, 0x8005d, 0x8001d, 0x9009a, 0x70116, 0x8007d, 0x8003d, 0x900da,\n      0x7010e, 0x8006d, 0x8002d, 0x900ba, 0x8000d, 0x8008d, 0x8004d, 0x900fa,\n      0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c6,\n      0x70109, 0x80063, 0x80023, 0x900a6, 0x80003, 0x80083, 0x80043, 0x900e6,\n      0x70105, 0x8005b, 0x8001b, 0x90096, 0x70115, 0x8007b, 0x8003b, 0x900d6,\n      0x7010d, 0x8006b, 0x8002b, 0x900b6, 0x8000b, 0x8008b, 0x8004b, 0x900f6,\n      0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900ce,\n      0x7010b, 0x80067, 0x80027, 0x900ae, 0x80007, 0x80087, 0x80047, 0x900ee,\n      0x70107, 0x8005f, 0x8001f, 0x9009e, 0x70117, 0x8007f, 0x8003f, 0x900de,\n      0x7010f, 0x8006f, 0x8002f, 0x900be, 0x8000f, 0x8008f, 0x8004f, 0x900fe,\n      0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c1,\n      0x70108, 0x80060, 0x80020, 0x900a1, 0x80000, 0x80080, 0x80040, 0x900e1,\n      0x70104, 0x80058, 0x80018, 0x90091, 0x70114, 0x80078, 0x80038, 0x900d1,\n      0x7010c, 0x80068, 0x80028, 0x900b1, 0x80008, 0x80088, 0x80048, 0x900f1,\n      0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c9,\n      0x7010a, 0x80064, 0x80024, 0x900a9, 0x80004, 0x80084, 0x80044, 0x900e9,\n      0x70106, 0x8005c, 0x8001c, 0x90099, 0x70116, 0x8007c, 0x8003c, 0x900d9,\n      0x7010e, 0x8006c, 0x8002c, 0x900b9, 0x8000c, 0x8008c, 0x8004c, 0x900f9,\n      0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c5,\n      0x70109, 0x80062, 0x80022, 0x900a5, 0x80002, 0x80082, 0x80042, 0x900e5,\n      0x70105, 0x8005a, 0x8001a, 0x90095, 0x70115, 0x8007a, 0x8003a, 0x900d5,\n      0x7010d, 0x8006a, 0x8002a, 0x900b5, 0x8000a, 0x8008a, 0x8004a, 0x900f5,\n      0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cd,\n      0x7010b, 0x80066, 0x80026, 0x900ad, 0x80006, 0x80086, 0x80046, 0x900ed,\n      0x70107, 0x8005e, 0x8001e, 0x9009d, 0x70117, 0x8007e, 0x8003e, 0x900dd,\n      0x7010f, 0x8006e, 0x8002e, 0x900bd, 0x8000e, 0x8008e, 0x8004e, 0x900fd,\n      0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c3,\n      0x70108, 0x80061, 0x80021, 0x900a3, 0x80001, 0x80081, 0x80041, 0x900e3,\n      0x70104, 0x80059, 0x80019, 0x90093, 0x70114, 0x80079, 0x80039, 0x900d3,\n      0x7010c, 0x80069, 0x80029, 0x900b3, 0x80009, 0x80089, 0x80049, 0x900f3,\n      0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900cb,\n      0x7010a, 0x80065, 0x80025, 0x900ab, 0x80005, 0x80085, 0x80045, 0x900eb,\n      0x70106, 0x8005d, 0x8001d, 0x9009b, 0x70116, 0x8007d, 0x8003d, 0x900db,\n      0x7010e, 0x8006d, 0x8002d, 0x900bb, 0x8000d, 0x8008d, 0x8004d, 0x900fb,\n      0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c7,\n      0x70109, 0x80063, 0x80023, 0x900a7, 0x80003, 0x80083, 0x80043, 0x900e7,\n      0x70105, 0x8005b, 0x8001b, 0x90097, 0x70115, 0x8007b, 0x8003b, 0x900d7,\n      0x7010d, 0x8006b, 0x8002b, 0x900b7, 0x8000b, 0x8008b, 0x8004b, 0x900f7,\n      0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900cf,\n      0x7010b, 0x80067, 0x80027, 0x900af, 0x80007, 0x80087, 0x80047, 0x900ef,\n      0x70107, 0x8005f, 0x8001f, 0x9009f, 0x70117, 0x8007f, 0x8003f, 0x900df,\n      0x7010f, 0x8006f, 0x8002f, 0x900bf, 0x8000f, 0x8008f, 0x8004f, 0x900ff\n    ]), 9];\n\n    var fixedDistCodeTab = [new Uint32Array([\n      0x50000, 0x50010, 0x50008, 0x50018, 0x50004, 0x50014, 0x5000c, 0x5001c,\n      0x50002, 0x50012, 0x5000a, 0x5001a, 0x50006, 0x50016, 0x5000e, 0x00000,\n      0x50001, 0x50011, 0x50009, 0x50019, 0x50005, 0x50015, 0x5000d, 0x5001d,\n      0x50003, 0x50013, 0x5000b, 0x5001b, 0x50007, 0x50017, 0x5000f, 0x00000\n    ]), 5];\n    \n    function error(e) {\n        throw new Error(e)\n    }\n\n    function constructor(bytes) {\n      //var bytes = stream.getBytes();\n      var bytesPos = 0;\n\n      var cmf = bytes[bytesPos++];\n      var flg = bytes[bytesPos++];\n      if (cmf == -1 || flg == -1)\n        error('Invalid header in flate stream');\n      if ((cmf & 0x0f) != 0x08)\n        error('Unknown compression method in flate stream');\n      if ((((cmf << 8) + flg) % 31) != 0)\n        error('Bad FCHECK in flate stream');\n      if (flg & 0x20)\n        error('FDICT bit set in flate stream');\n\n      this.bytes = bytes;\n      this.bytesPos = bytesPos;\n\n      this.codeSize = 0;\n      this.codeBuf = 0;\n\n      DecodeStream.call(this);\n    }\n\n    constructor.prototype = Object.create(DecodeStream.prototype);\n\n    constructor.prototype.getBits = function(bits) {\n      var codeSize = this.codeSize;\n      var codeBuf = this.codeBuf;\n      var bytes = this.bytes;\n      var bytesPos = this.bytesPos;\n\n      var b;\n      while (codeSize < bits) {\n        if (typeof (b = bytes[bytesPos++]) == 'undefined')\n          error('Bad encoding in flate stream');\n        codeBuf |= b << codeSize;\n        codeSize += 8;\n      }\n      b = codeBuf & ((1 << bits) - 1);\n      this.codeBuf = codeBuf >> bits;\n      this.codeSize = codeSize -= bits;\n      this.bytesPos = bytesPos;\n      return b;\n    };\n\n    constructor.prototype.getCode = function(table) {\n      var codes = table[0];\n      var maxLen = table[1];\n      var codeSize = this.codeSize;\n      var codeBuf = this.codeBuf;\n      var bytes = this.bytes;\n      var bytesPos = this.bytesPos;\n\n      while (codeSize < maxLen) {\n        var b;\n        if (typeof (b = bytes[bytesPos++]) == 'undefined')\n          error('Bad encoding in flate stream');\n        codeBuf |= (b << codeSize);\n        codeSize += 8;\n      }\n      var code = codes[codeBuf & ((1 << maxLen) - 1)];\n      var codeLen = code >> 16;\n      var codeVal = code & 0xffff;\n      if (codeSize == 0 || codeSize < codeLen || codeLen == 0)\n        error('Bad encoding in flate stream');\n      this.codeBuf = (codeBuf >> codeLen);\n      this.codeSize = (codeSize - codeLen);\n      this.bytesPos = bytesPos;\n      return codeVal;\n    };\n\n    constructor.prototype.generateHuffmanTable = function(lengths) {\n      var n = lengths.length;\n\n      // find max code length\n      var maxLen = 0;\n      for (var i = 0; i < n; ++i) {\n        if (lengths[i] > maxLen)\n          maxLen = lengths[i];\n      }\n\n      // build the table\n      var size = 1 << maxLen;\n      var codes = new Uint32Array(size);\n      for (var len = 1, code = 0, skip = 2;\n           len <= maxLen;\n           ++len, code <<= 1, skip <<= 1) {\n        for (var val = 0; val < n; ++val) {\n          if (lengths[val] == len) {\n            // bit-reverse the code\n            var code2 = 0;\n            var t = code;\n            for (var i = 0; i < len; ++i) {\n              code2 = (code2 << 1) | (t & 1);\n              t >>= 1;\n            }\n\n            // fill the table entries\n            for (var i = code2; i < size; i += skip)\n              codes[i] = (len << 16) | val;\n\n            ++code;\n          }\n        }\n      }\n\n      return [codes, maxLen];\n    };\n\n    constructor.prototype.readBlock = function() {\n      function repeat(stream, array, len, offset, what) {\n        var repeat = stream.getBits(len) + offset;\n        while (repeat-- > 0)\n          array[i++] = what;\n      }\n\n      // read block header\n      var hdr = this.getBits(3);\n      if (hdr & 1)\n        this.eof = true;\n      hdr >>= 1;\n\n      if (hdr == 0) { // uncompressed block\n        var bytes = this.bytes;\n        var bytesPos = this.bytesPos;\n        var b;\n\n        if (typeof (b = bytes[bytesPos++]) == 'undefined')\n          error('Bad block header in flate stream');\n        var blockLen = b;\n        if (typeof (b = bytes[bytesPos++]) == 'undefined')\n          error('Bad block header in flate stream');\n        blockLen |= (b << 8);\n        if (typeof (b = bytes[bytesPos++]) == 'undefined')\n          error('Bad block header in flate stream');\n        var check = b;\n        if (typeof (b = bytes[bytesPos++]) == 'undefined')\n          error('Bad block header in flate stream');\n        check |= (b << 8);\n        if (check != (~blockLen & 0xffff))\n          error('Bad uncompressed block length in flate stream');\n\n        this.codeBuf = 0;\n        this.codeSize = 0;\n\n        var bufferLength = this.bufferLength;\n        var buffer = this.ensureBuffer(bufferLength + blockLen);\n        var end = bufferLength + blockLen;\n        this.bufferLength = end;\n        for (var n = bufferLength; n < end; ++n) {\n          if (typeof (b = bytes[bytesPos++]) == 'undefined') {\n            this.eof = true;\n            break;\n          }\n          buffer[n] = b;\n        }\n        this.bytesPos = bytesPos;\n        return;\n      }\n\n      var litCodeTable;\n      var distCodeTable;\n      if (hdr == 1) { // compressed block, fixed codes\n        litCodeTable = fixedLitCodeTab;\n        distCodeTable = fixedDistCodeTab;\n      } else if (hdr == 2) { // compressed block, dynamic codes\n        var numLitCodes = this.getBits(5) + 257;\n        var numDistCodes = this.getBits(5) + 1;\n        var numCodeLenCodes = this.getBits(4) + 4;\n\n        // build the code lengths code table\n        var codeLenCodeLengths = Array(codeLenCodeMap.length);\n        var i = 0;\n        while (i < numCodeLenCodes)\n          codeLenCodeLengths[codeLenCodeMap[i++]] = this.getBits(3);\n        var codeLenCodeTab = this.generateHuffmanTable(codeLenCodeLengths);\n\n        // build the literal and distance code tables\n        var len = 0;\n        var i = 0;\n        var codes = numLitCodes + numDistCodes;\n        var codeLengths = new Array(codes);\n        while (i < codes) {\n          var code = this.getCode(codeLenCodeTab);\n          if (code == 16) {\n            repeat(this, codeLengths, 2, 3, len);\n          } else if (code == 17) {\n            repeat(this, codeLengths, 3, 3, len = 0);\n          } else if (code == 18) {\n            repeat(this, codeLengths, 7, 11, len = 0);\n          } else {\n            codeLengths[i++] = len = code;\n          }\n        }\n\n        litCodeTable =\n          this.generateHuffmanTable(codeLengths.slice(0, numLitCodes));\n        distCodeTable =\n          this.generateHuffmanTable(codeLengths.slice(numLitCodes, codes));\n      } else {\n        error('Unknown block type in flate stream');\n      }\n\n      var buffer = this.buffer;\n      var limit = buffer ? buffer.length : 0;\n      var pos = this.bufferLength;\n      while (true) {\n        var code1 = this.getCode(litCodeTable);\n        if (code1 < 256) {\n          if (pos + 1 >= limit) {\n            buffer = this.ensureBuffer(pos + 1);\n            limit = buffer.length;\n          }\n          buffer[pos++] = code1;\n          continue;\n        }\n        if (code1 == 256) {\n          this.bufferLength = pos;\n          return;\n        }\n        code1 -= 257;\n        code1 = lengthDecode[code1];\n        var code2 = code1 >> 16;\n        if (code2 > 0)\n          code2 = this.getBits(code2);\n        var len = (code1 & 0xffff) + code2;\n        code1 = this.getCode(distCodeTable);\n        code1 = distDecode[code1];\n        code2 = code1 >> 16;\n        if (code2 > 0)\n          code2 = this.getBits(code2);\n        var dist = (code1 & 0xffff) + code2;\n        if (pos + len >= limit) {\n          buffer = this.ensureBuffer(pos + len);\n          limit = buffer.length;\n        }\n        for (var k = 0; k < len; ++k, ++pos)\n          buffer[pos] = buffer[pos - dist];\n      }\n    };\n\n    return constructor;\n  })();\n\n  /**\n   * JavaScript Polyfill functions for jsPDF\n   * Collected from public resources by\n   * https://github.com/diegocr\n   */\n\n  (function (global) {\n      \n      if (typeof global.console !== \"object\") {\n          // Console-polyfill. MIT license.\n          // https://github.com/paulmillr/console-polyfill\n          // Make it safe to do console.log() always.\n          global.console = {};\n          \n          var con = global.console;\n          var prop, method;\n          var dummy = function() {};\n          var properties = ['memory'];\n          var methods = ('assert,clear,count,debug,dir,dirxml,error,exception,group,' +\n           'groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,' +\n           'show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn').split(',');\n          while (prop = properties.pop()) if (!con[prop]) con[prop] = {};\n          while (method = methods.pop()) if (!con[method]) con[method] = dummy;\n      }\n\n      var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\n\n      if (typeof global.btoa === 'undefined') {\n          global.btoa = function(data) {\n              //  discuss at: http://phpjs.org/functions/base64_encode/\n              // original by: Tyler Akins (http://rumkin.com)\n              // improved by: Bayron Guevara\n              // improved by: Thunder.m\n              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)\n              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)\n              // improved by: Rafal Kukawski (http://kukawski.pl)\n              // bugfixed by: Pellentesque Malesuada\n              //   example 1: base64_encode('Kevin van Zonneveld');\n              //   returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA=='\n\n              var o1,o2,o3,h1,h2,h3,h4,bits,i = 0,ac = 0,enc = '',tmp_arr = [];\n\n              if (!data) {\n                  return data;\n              }\n\n              do { // pack three octets into four hexets\n                  o1 = data.charCodeAt(i++);\n                  o2 = data.charCodeAt(i++);\n                  o3 = data.charCodeAt(i++);\n\n                  bits = o1 << 16 | o2 << 8 | o3;\n\n                  h1 = bits >> 18 & 0x3f;\n                  h2 = bits >> 12 & 0x3f;\n                  h3 = bits >> 6 & 0x3f;\n                  h4 = bits & 0x3f;\n\n                  // use hexets to index into b64, and append result to encoded string\n                  tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);\n              } while (i < data.length);\n\n              enc = tmp_arr.join('');\n\n              var r = data.length % 3;\n\n              return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3);\n          };\n      }\n\n      if (typeof global.atob === 'undefined') {\n          global.atob = function(data) {\n              //  discuss at: http://phpjs.org/functions/base64_decode/\n              // original by: Tyler Akins (http://rumkin.com)\n              // improved by: Thunder.m\n              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)\n              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)\n              //    input by: Aman Gupta\n              //    input by: Brett Zamir (http://brett-zamir.me)\n              // bugfixed by: Onno Marsman\n              // bugfixed by: Pellentesque Malesuada\n              // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)\n              //   example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA==');\n              //   returns 1: 'Kevin van Zonneveld'\n\n              var o1,o2,o3,h1,h2,h3,h4,bits,i = 0,ac = 0,dec = '',tmp_arr = [];\n\n              if (!data) {\n                  return data;\n              }\n\n              data += '';\n\n              do { // unpack four hexets into three octets using index points in b64\n                  h1 = b64.indexOf(data.charAt(i++));\n                  h2 = b64.indexOf(data.charAt(i++));\n                  h3 = b64.indexOf(data.charAt(i++));\n                  h4 = b64.indexOf(data.charAt(i++));\n\n                  bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;\n\n                  o1 = bits >> 16 & 0xff;\n                  o2 = bits >> 8 & 0xff;\n                  o3 = bits & 0xff;\n\n                  if (h3 == 64) {\n                      tmp_arr[ac++] = String.fromCharCode(o1);\n                  } else if (h4 == 64) {\n                      tmp_arr[ac++] = String.fromCharCode(o1, o2);\n                  } else {\n                      tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);\n                  }\n              } while (i < data.length);\n\n              dec = tmp_arr.join('');\n\n              return dec;\n          };\n      }\n\n      if (!Array.prototype.map) {\n          Array.prototype.map = function(fun /*, thisArg */) {\n              if (this === void 0 || this === null || typeof fun !== \"function\")\n                  throw new TypeError();\n\n              var t = Object(this), len = t.length >>> 0, res = new Array(len);\n              var thisArg = arguments.length > 1 ? arguments[1] : void 0;\n              for (var i = 0; i < len; i++) {\n                  // NOTE: Absolute correctness would demand Object.defineProperty\n                  //       be used.  But this method is fairly new, and failure is\n                  //       possible only if Object.prototype or Array.prototype\n                  //       has a property |i| (very unlikely), so use a less-correct\n                  //       but more portable alternative.\n                  if (i in t)\n                      res[i] = fun.call(thisArg, t[i], i, t);\n              }\n\n              return res;\n          };\n      }\n\n\n      if(!Array.isArray) {\n          Array.isArray = function(arg) {\n              return Object.prototype.toString.call(arg) === '[object Array]';\n          };\n      }\n\n      if (!Array.prototype.forEach) {\n          Array.prototype.forEach = function(fun, thisArg) {\n\n              if (this === void 0 || this === null || typeof fun !== \"function\")\n                  throw new TypeError();\n\n              var t = Object(this), len = t.length >>> 0;\n              for (var i = 0; i < len; i++) {\n                  if (i in t)\n                      fun.call(thisArg, t[i], i, t);\n              }\n          };\n      }\n      \n      if (!Object.keys) {\n          Object.keys = (function () {\n\n              var hasOwnProperty = Object.prototype.hasOwnProperty,\n                  hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),\n                  dontEnums = ['toString','toLocaleString','valueOf','hasOwnProperty',\n                      'isPrototypeOf','propertyIsEnumerable','constructor'],\n                  dontEnumsLength = dontEnums.length;\n\n              return function (obj) {\n                  if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {\n                      throw new TypeError();\n                  }\n                  var result = [], prop, i;\n\n                  for (prop in obj) {\n                      if (hasOwnProperty.call(obj, prop)) {\n                          result.push(prop);\n                      }\n                  }\n\n                  if (hasDontEnumBug) {\n                      for (i = 0; i < dontEnumsLength; i++) {\n                          if (hasOwnProperty.call(obj, dontEnums[i])) {\n                              result.push(dontEnums[i]);\n                          }\n                      }\n                  }\n                  return result;\n              };\n          }());\n      }\n      \n      if (typeof Object.assign != 'function') {\n            Object.assign = function(target) {\n              if (target == null) {\n                throw new TypeError('Cannot convert undefined or null to object');\n              }\n\n              target = Object(target);\n              for (var index = 1; index < arguments.length; index++) {\n                var source = arguments[index];\n                if (source != null) {\n                  for (var key in source) {\n                    if (Object.prototype.hasOwnProperty.call(source, key)) {\n                      target[key] = source[key];\n                    }\n                  }\n                }\n              }\n              return target;\n            };\n          }\n\n      if (!String.prototype.trim) {\n          String.prototype.trim = function () {\n              return this.replace(/^\\s+|\\s+$/g, '');\n          };\n      }\n      if (!String.prototype.trimLeft) {\n          String.prototype.trimLeft = function() {\n              return this.replace(/^\\s+/g, \"\");\n          };\n      }\n      if (!String.prototype.trimRight) {\n          String.prototype.trimRight = function() {\n              return this.replace(/\\s+$/g, \"\");\n          };\n      }\n\n\n  }(typeof self !== \"undefined\" && self || typeof window !== \"undefined\" && window || typeof global !== \"undefined\" && global ||  Function('return typeof this === \"object\" && this.content')() || Function('return this')()));\n  // `self` is undefined in Firefox for Android content script context\n  // while `this` is nsIContentFrameMessageManager\n  // with an attribute `content` that corresponds to the window\n\n  return jsPDF;\n\n\n});"],"names":["define","API","getCharWidthsArray","getArraySum","getStringUnitWidth","splitLongWord","splitParagraphIntoLines","_typeof","Symbol","_typeof2","iterator","obj","constructor","prototype","jsPDF","global","pageFormats","PubSub","context","topics","subscribe","topic","callback","once","hasOwnProperty","id","Math","random","toString","unsubscribe","token","publish","args","Array","slice","call","arguments","idr","sub","apply","ex","console","error","message","push","length","forEach","this","orientation","unit","format","compressPdf","options","compress","toLowerCase","activeFontKey","k","tmp","currentPage","pageWidth","pageHeight","pageMode","zoomMode","layoutMode","creationDate","fn","Uint8Array","textColor","drawColor","activeFontSize","fontSize","activeCharSpace","charSpace","R2L","lineHeightProportion","lineHeight","lineWidth","fileId","objectNumber","outToPages","offsets","fonts","fontmap","page","pages","pagesContext","pagedim","content","additionalObjects","lineCapID","lineJoinID","content_length","documentProperties","events","hotfixes","generateColorString","color","ch1","ch2","ch3","ch4","letterArray","precision","pdfColorType","charAt","rgbColor","RGBColor","ok","toHex","test","hex","parseInt","substr","f2","f3","join","a","convertDateToPDFDate","parmDate","padd2","number","tzoffset","getTimezoneOffset","tzsign","tzhour","floor","abs","tzmin","timeZoneString","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","setCreationDate","date","tmpCreationDateString","undefined","Date","Object","getCreationDate","type","parmPDFDate","year","month","hour","minutes","seconds","result","setFileId","value","split","map","toFixed","out","string","newObject","putStream","str","putResourceDictionary","fontKey","putResources","font","isAlreadyPutted","postScriptName","encoding","putFonts","addToFontDictionary","fontName","fontStyle","addFont","keys","pdfEscape","text","flags","i","l","sourceEncoding","encodingBlock","outputEncoding","newtext","isUnicode","ch","bch","autoencode","metadata","codePages","charCodeAt","String","fromCharCode","noBOM","Error","to8bitStream","replace","beginPage","width","height","isArray","Number","_setPage","_addPage","pageNumber","_deletePage","n","splice","setPage","_getFont","fontNameLowerCase","key","disableWarning","warn","noFallback","buildDocument","p","arr","deflater","adler32","adler32cs","wPt","hPt","pageObjectNumbers","from","Deflater","append","flush","set","kids","putPages","objId","putAdditionalObjects","version","toUpperCase","putInfo","pcn","putCatalog","o","offset","getStyle","style","op","getArrayBuffer","data","len","ab","ArrayBuffer","u8","getBlob","Blob","_output","datauri","btoa","navigator","getUserMedia","URL","createObjectURL","output","saveAs","unload","setTimeout","nW","open","safari","document","location","href","foo","e","stack","indexOf","m","alert","bar","hasHotfix","hotfixName","plugin","internal","colorEncoded","floatVal","parseFloat","colorAsHex","string1","oid","getWidth","getHeight","pageNumberOneBased","pageContext","addPage","insertPage","beforePage","movePage","targetPage","tmpPages","tmpPagedim","tmpPagesContext","deletePage","getFileId","setDisplayMode","zoom","layout","pmode","x","y","xtra","isHex","scope","ESC","s","TabLen","transformTextToSpecialArray","curDa","sa","concat","da","shift","processTextByFunction","processingFunction","tmpResult","angle","align","textIsOfTypeString","tmpTextIsOfTypeString","activeFontEncoding","posX","posY","match","maxWidth","splitTextToSize","payload","mutex","scaleFactor","transformationMatrix","pageSize","PI","c","cos","sin","lang","tmpRenderingMode","parmRenderingMode","renderingMode","stroke","getCurrentPageInfo","usedRenderingMode","leading","activeFont","wordSpacingPerLine","newY","lineWidths","v","newX","maxLineLength","max","prevWidth","doReversing","reverse","variant","wordSpacing","lstext","spacing","line","x1","y1","x2","y2","lines","clip","clip_fixed","fillRule","scale","closed","scalex","scaley","leg","x3","y3","x4","y4","rect","w","h","triangle","roundedRect","rx","ry","MyArc","SQRT2","ellipse","lx","ly","circle","r","setProperties","properties","property","setFontSize","size","setFont","setFontStyle","setFontType","getFontList","list","setLineWidth","setDrawColor","setFillColor","setTextColor","setCharSpace","setR2L","boolean","CapJoinStyles","setLineCap","setLineJoin","save","filename","newEvents","eventname","handler_and_args","standardFonts","parts","dictionary","addFonts","amd","module","exports","self","window","Function","jsPDFAPI","globalObj","inherit","child","parent","create","createFormXObject","formObject","xobj","AcroFormXObject","AcroFormAppearance","BBox","setBitPosition","variable","position","bitMask","calculateFlagsOnOptions","opts","PDFVersion","readOnly","required","noExport","multiline","password","noToggleToOff","radio","pushbutton","combo","edit","sort","fileSelect","multiSelect","doNotSpellCheck","doNotScroll","richText","calculateCoordinates","coordinates","lowerLeft_X","lowerLeft_Y","upperRight_X","upperRight_Y","calculateAppearanceStream","appearanceStreamContent","V","DV","stream","calcRes","calculateX","maxFontSize","returnValue","textSplit","isSmallerThanWidth","lastLine","calculateFontSpace","FontSize","textHeight","startY","startX","lastY","firstWordInLine","lastWordInLine","lastLength","lineCount","nextLineIsSmaller","isLastWord","Q","fontType","getFont","acroformPluginTemplate","fields","xForms","acroFormDictionaryRoot","printedOut","isInitialized","annotReferenceCallback","acroformPlugin","Fields","hasAnnotation","createAnnotationReference","putForm","initializeAcroForm","object","annotationPlugin","annotations","getPageInfo","putCatalogCallback","write","log","AcroFormDictionaryCallback","_eventID","createFieldCallback","fieldArray","standardFields","newObjectDeferredBegin","getString","Kids","form","oldRect","Rect","getContent","hasAppearanceStream","appearance","createXFormObjectCallback","AcroFormField","FieldNum","JSON","parse","stringify","AcroFormDictionary","arrayToPdfArray","array","toPdfString","substring","AcroFormPDFObject","_objId","defineProperty","get","newObjectDeferred","configurable","res","fieldObject","filter","createContentFromFieldObject","_stream","Type","Subtype","FormType","Matrix","Resources","PieceInfo","enumerable","val","trim","_Kids","DA","_Rect","_T","_DA","_DV","_V","_FT","AcroFormChildClass","BG","BC","writable","AcroFormChoiceField","FT","Opt","TI","_combo","_edit","AcroFormListBox","AcroFormComboBox","AcroFormEditBox","AcroFormButton","AcroFormPushButton","_pushbutton","AcroFormRadioButton","_radio","_noToggleToOff","name","Parent","_AppearanceType","RadioButton","Circle","createAppearanceStream","F","MK","createMK","AS","_Name","setAppearance","__Kids","createOption","addField","AcroFormCheckBox","CheckBox","AcroFormTextField","createDefaultAppearanceStream","_multiline","_fileSelect","_doNotSpellCheck","_doNotScroll","_MaxLen","AcroFormPasswordField","_password","N","On","YesNormal","D","YesPushDown","Off","OffPushDown","zapfDingbatsId","DotRadius","Bezier_C","kc","dc","Cross","cross","calculateCross","addTextField","addChoiceField","addButton","Ff","getPDFVersion","Appearance","AcroForm","ChoiceField","ListBox","ComboBox","EditBox","Button","PushButton","TextField","PasswordField","addHTML","element","html2canvas","rasterizeHTML","I","K","W","H","onrendered","dim","margin","assign","top","right","bottom","left","useFor","min","imageCompression","pagesplit","cropArea","parmObj","parmX","parmY","parmWidth","parmHeight","canvas","createElement","ctx","getContext","mozImageSmoothingEnabled","webkitImageSmoothingEnabled","msImageSmoothingEnabled","imageSmoothingEnabled","fillStyle","backgroundColor","fillRect","drawImage","crop","cy","cx","isOverWide","addImage","bind","nodeName","img","Image","onload","src","toDataURL","alias","rstz","meth","then","image","imageFileTypeHeaders","PNG","TIFF","JPEG","JPEG2000","GIF87a","GIF89a","BMP","getImageFileTypeByImageData","imageData","fallbackFormat","j","headerSchemata","compareResult","fileType","putImage","color_spaces","INDEXED","DEVICE_CMYK","trns","dp","smask","f","arrayBufferToBinaryString","putResourcesCallback","images","collections","putXObjectsDictCallback","checkCompressValue","image_compression","NONE","getImages","getImageIndex","imageIndex","notDefined","generateAliasFromData","sHashCode","isImageTypeSupported","isDOMElement","nodeType","createDataURIFromElement","hasAttribute","getAttribute","clientWidth","clientHeight","checkImagesForAlias","cached_info","determineWidthAndHeight","info","writeImageToPDF","index","rotation","dims","coord","getCoordinateString","vcoord","getVerticalCoordinateString","f4","rotationTransformationMatrix","DEVICE_RGB","DEVICE_GRAY","CAL_GREY","CAL_RGB","LAB","ICC_BASED","PATTERN","SEPARATION","DEVICE_N","decode","DCT_DECODE","FLATE_DECODE","LZW_DECODE","JPX_DECODE","JBIG2_DECODE","ASCII85_DECODE","ASCII_HEX_DECODE","RUN_LENGTH_DECODE","CCITT_FAX_DECODE","FAST","MEDIUM","SLOW","reduce","b","isString","validateStringAsBase64","possibleBase64String","extractInfoFromBase64DataURI","dataURI","exec","supportsArrayBuffer","isArrayBuffer","isArrayBufferView","Uint32Array","Int8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Float32Array","Float64Array","binaryStringToUint8Array","binary_string","bytes","buffer","atob","arrayBufferToBase64","TextDecoder","decoder","slicesCount","ceil","byteLength","arrayBuffer","chunk","base64","encodings","byteRemainder","mainLength","createImageInfo","wd","ht","cs","bpc","pal","compression","tmpImageData","isNaN","dataAsBinaryString","convertStringToImageData","loadImageFile","stringData","base64Info","readBytes","subarray","processJPEG","colorSpace","imgData","blockLength","getJpegSize","block","pos","numcomponents","getJpegSizeFromBytes","processJPG","path","sync","process","protocol","url","req","XMLHttpRequest","byteArray","sanitizeUnicode","dataLength","StringFromCharCode","overrideMimeType","responseText","send","status","xhrMethod","getImageProperties","compressionMode","bitsPerComponent","notEmpty","pageAnnos","found","anno","pageInfo","objText","newAdditionalObject","objPopup","title","bounds","contents","loc","_nameMap","magFactor","createAnnotation","link","textWithLink","getTextWidth","getLineHeight","getFontSize","arLangCodesKeys","arabicSubst","arabiclaasubst","arabicorigsubst","arabic_diacritics","alfletter","endedletter","isArabicLetter","letter","isArabicEndLetter","isArabicAlfLetter","arabicLetterHasFinalForm","getCorrectForm","currentChar","beforeChar","nextChar","arabicSubstition","processArabic","resultingLetter","character","currentLetter","prevLetter","nextLetter","tmpText","autoPrint","refAutoPrintTag","addJS","pdf","context2d","_canvas","childNodes","_width","pageWrapX","_height","pageWrapY","headerFunction","lastCellPos","ln","setLastCellPosition","getLastCellPosition","NO_MARGINS","setHeaderFunction","func","getTextDimensions","txt","table_font_size","dimensions","px2pt","fontWeight","fontFamily","textContent","innerText","body","appendChild","offsetWidth","offsetHeight","removeChild","cellAddPage","margins","cellInitialize","cell","curCell","pgAdded","printHeaders","tableHeaderRow","printHeaderRow","printingHeaderRow","currentLine","textSize","arrayMax","comparisonFn","item","table","headers","config","header","cln","columnData","column","model","jln","headerNames","headerPrompts","columnMatrix","columnWidths","columnMinWidths","tableHeaderConfigs","autoSize","css","lnMod","prompt","rec","calculateLineHeight","setTableHeaderRow","table_x","table_y","lineNumber","new_page","tableHeaderCell","tmpArray","tempHeaderConf","ctxStack","pageWrapXEnabled","pageWrapYEnabled","_isFillTransparent","_wrapX","_wrapY","xRect","_matrix_map_rect","_transform","strokeRect","_isStrokeTransparent","clearRect","ignoreClearRect","setFillStyle","restore","_fontSize","copy","pop","setStrokeStyle","strokeStyle","lineCap","lineJoin","moveTo","lineTo","closePath","beginPath","_getRGBA","g","rxTransparent","rxRgb","rxRgba","rgba","_fillOpacity","_strokeOpacity","fillText","xpt","_matrix_map_point","degs","_matrix_rotation","_clip_path","outIntercept","getCurrentPage","origPath","_fill","_matrix_decompose","_getTransform","_getBaseline","oldSize","strokeText","fontSizeUnit","jsPdfFontName","setTextBaseline","baseline","textBaseline","getTextBaseline","setTextAlign","textAlign","getTextAlign","_gotoPage","_page","lastBreak","transform","d","_matrix_multiply","setTransform","pageBreaks","manualBreaks","autoBreaks","spaceBetweenLastBreak","pageOneBased","bezierCurveTo","quadraticCurveTo","arc","radius","startAngle","endAngle","anticlockwise","_matrix_is_identity","x_radPt0","x_radPt","sqrt","pow","w2","h2","m2","m1","sx","shy","shx","sy","tx","ty","t0","t2","t4","atan2","matrix","scaleX","shear","scaleY","translate","rotate","skew","pt","px","py","_matrix_map_point_obj","p1","p2","_stroke","isClip","moves","xPath","start","deltas","delta","arcs","ii","end","arc2","globalAlpha","fill","v2Support","newObject2","outInterceptOld","globalCompositeOperation","newStreamObject","obj2","gsName","addGraphicsState","instruction","dictionaryEntry","blendModeMap","alpha","objOpac","close","move2","line2","c2d","pushMask","measureText","txtWidth","descent","miterLimit","parentNode","xc","yc","a1","a2","a1r","a2r","curves","createArc","curve","_lastPoint","centerX","centerY","dx","dy","twoPI","piOverTwo","startAngleN","totalAngle","sgn","createSmallArc","q1","q2","k2","ar","cos_ar","sin_ar","clone","_DrillForContent","FontNameDB","FontStyleMap","TextAlignMap","FontWeightMap","FloatMap","ClearMap","GetCSS","PurgeWhiteSpace","Renderer","ResolveFont","ResolveUnitedNumber","UnitedNumberMap","elementHandledElsewhere","loadImgs","checkForFooter","tableToJson","Clone","fragment","lTrimmed","rTrimmed","trailingSpace","trimLeft","trimRight","css_font_family_string","part","css_line_height_string","small","medium","large","auto","computedCSSElement","compCSS","el","defaultView","getComputedStyle","currentStyle","prop","renderer","elementHandlers","handlers","isHandledElsewhere","classNames","className","rowData","tableRow","table_with","rows","cells","SkipNode","SCRIPT","STYLE","NOSCRIPT","OBJECT","EMBED","SELECT","listCount","cn","cns","fragmentCSS","isBlock","table2json","cb","display","setBlockBoundary","setBlockStyle","executeWatchFunctions","oldMarginTop","margins_doc","nodeValue","offsetX","offsetY","ownerDocument","compareDocumentPosition","addText","cached_image","imagesCSS","imageX","fontToUnitRatio","additionalSpaceLeft","additionalSpaceRight","additionalSpaceTop","additionalSpaceBottom","settings","watchFunctions","diffX","thresholdY","diffWidth","yPositionAfterFloating","getNumberOfPages","clear","temp","outY","found_images","imgs","getElementsByTagName","done","loadImage","crossOrigin","onerror","complete","hash","elem","footer","oldOut","oldY","footerHeight","renderFooter","oldPosition","spans","innerHTML","putTotalPages","$frame","$hiddendiv","framename","now","cssText","frames","writeln","dispose","init","paragraph","ready","ret","narray","splitFragmentsIntoLines","fragments","styles","currentLineLength","ff","fontMetrics","fontMetricsCache","fragmentChopped","fragmentLength","fragmentSpecificMetrics","fs","Unicode","widths","kerning","textIndent","space","countSpaces","RenderTextFragment","maxLineHeight","getPdfColor","pdfTextColor","lastTextColor","renderParagraph","blockstyle","paragraphspacing_after","paragraphspacing_before","priorblockstyle","priorMarginBottom","currentIndent","indentMove","wantedIndent","localFragments","localStyles","localLine","helvetica","serif","times","monospace","courier","normal","bold","bolder","lighter","italic","oblique","center","justify","none","both","fromHTML","HTML","jsNamesObj","jsJsObj","outline","root","children","render","createNamedDestinations","totalPages","dests","names2Oid","makeRef","namesOid","add","genIds_r","renderRoot","renderItems","node","objStart","count_r","count","objEnd","makeString","hasCompressionJS","inst","compressBytes","lineLength","colorsPerPixel","level","filter_method","filterUp","filterSub","filterAverage","filterPaeth","applyPngFilterMethod","createZlibHeader","checksum","deflate","cBytes","cmpd","cmf","LOG2E","hdr","param","tlen","s1","adler","s2","prevLine","filter_methods","getFilterMethods","results","ind","getIndexOfSmallestSum","filterNone","unshift","up","upLeft","paeth","paethPredictor","pLeft","pUp","pUpLeft","arrays","sum","absSum","processPNG","colors","FlateStream","bits","colorType","pbl","pixels","pixelBitlength","decodePixels","alphaData","pDiff","pixel","hasColors","palette","transparency","indexed","trans","total","predictor","getPredictorFromCompression","processGIF89A","reader","GifReader","decodeAndBlitFrameRGBA","rawImageData","JPEGEncoder","encode","processGIF87A","processBMP","BmpDecoder","getData","setLanguage","langCode","languageSettings","isSubscribed","languageCode","char_code","getCharSpace","widthsFractionOf","fof","kerningFractionOf","prior_char_code","default_char_width","widthOfString","widthOfGlyph","characterToGlyph","word","widths_array","firstLineMaxLen","maxLen","answer","workingLen","startOfLine","maxlen","lineIndent","line_length","separator_length","current_word_length","words","spaceCharWidth","pad","wrds","wrd","idx","force","postProcess","paragraphs","fsize","newOptions","fontUnit_maxLen","uncompress","mapping","stringparts","parent_key_pair","sign","activeobject","parentchain","keyparts","valueparts","datalen","undef","metrics","unicode_section","existsFileInVFS","TTFFont","getFileFromVFS","addSvg","svgtext","convertPathToPDFLinesArgs","vectors","svgnode","frame","framedoc","contentWindow","contentDocument","attachSVGToWorkerNode","cssbody","styletag","styleSheet","createTextNode","InjectCSS","setAttribute","createWorkerNode","svgw","svgh","linesargs","items","tagName","addSVG","addSvgAsImage","svg","canvg","ignoreMouse","ignoreAnimation","ignoreDimensions","ignoreClear","pageExpression","replaceExpression","RegExp","viewerPreferences","doReset","configuration","method","configurationTemplate","defaultValue","explicitSet","valueSet","pdfVersion","configurationKeys","rangeArray","isValid","arrayContainsElement","viewerpreferences","isInteger","vPref","pdfDict","xmpmetadata","xmpnamespaceuri","metadata_object_number","addMetadata","namespaceuri","rdf_beginning","utf8_xmpmeta_beginning","unescape","encodeURIComponent","utf8_rdf_beginning","utf8_metadata","utf8_rdf_ending","utf8_xmpmeta_ending","total_len","glyID","pdfOutput","subset","pdfOutput2","fontTable","fontDescriptor","PDFObject","convert","bbox","stemV","italicAngle","ascender","decender","capHeight","DescendantFont","identityHFunction","rawData","hmtx","head","unitsPerEm","winAnsiEncodingFunction","utf8TextFunction","cmapConfirm","strText","cmap","unicode","codeMap","t","padz","pdfEscape16","parms","vFS","addFileToVFS","filecontent","view","webkitURL","BlobBuilder","WebKitBlobBuilder","MozBlobBuilder","get_class","FakeBlobBuilder","FakeBlob","FBB_proto","FB_proto","FileReaderSync","FileException","code","file_ex_codes","file_ex_code","real_URL","real_create_object_URL","real_revoke_object_URL","revokeObjectURL","origin","fake","uri","uri_origin","uri_info","createElementNS","blob","data_URI_header","decodeURIComponent","object_URL","bb","buf","buf_len","fr","readAsBinaryString","blobParts","builder","webkitSlice","getPrototypeOf","__proto__","userAgent","doc","get_URL","save_link","can_use_save_link","is_safari","HTMLElement","is_chrome_ios","throw_outside","setImmediate","revoke","file","remove","auto_bom","FileSaver","no_auto_bom","object_url","filesaver","dispatch_all","event_types","event","listener","dispatch","readyState","INIT","download","MouseEvent","dispatchEvent","DONE","FileReader","onloadend","readAsDataURL","fs_error","FS_proto","msSaveOrOpenBlob","abort","WRITING","onwritestart","onprogress","onwrite","onabort","onwriteend","pf0","global_palette_flag","num_global_colors","global_palette_offset","no_eof","delay","transparent_index","disposal","loop_count","block_size","pf1","pf2","interlace_flag","palette_offset","has_local_palette","data_offset","data_length","interlaced","numFrames","loopCount","frameInfo","frame_num","decodeAndBlitFrameBGRA","num_pixels","index_stream","GifReaderLZWOutputIndexStream","framewidth","framestride","xleft","opbeg","opend","scanstride","interlaceskip","il","code_stream","output_length","min_code_size","clear_code","eoi_code","next_code","cur_code_size","code_mask","cur_shift","cur","subblock_size","code_table","prev_code","chase_code","chase_length","chase","_hasArrayBuffer","_Buffer","_isBuffer","Buffer","_utf8ToBinary","utf8String","MOD","_update","binaryString","_updateUint8Array","uint8Array","Adler32","ctor","TypeError","isFinite","proto","fromUtf8","fromBuffer","update","updateUtf8","updateBuffer","GifWriter","gopts","loop","global_palette","check_palette_and_num_colors","num_colors","gp_num_colors_pow2","background","gp_num_colors","rgb","ended","addFrame","indexed_pixels","using_local_palette","use_transparency","transparent","cur_subblock","emit_bytes_to_buffer","bit_block_size","emit_code","ib_code","cur_key","cur_code","GifWriterOutputLZWCodeStream","quality","YDC_HT","UVDC_HT","YAC_HT","UVAC_HT","currentQuality","ffloor","YTable","UVTable","fdtbl_Y","fdtbl_UV","bitcode","category","outputfDCTQuant","DU","byteout","bytenew","bytepos","YDU","UDU","VDU","clt","RGB_YUV_TABLE","ZigZag","std_dc_luminance_nrcodes","std_dc_luminance_values","std_ac_luminance_nrcodes","std_ac_luminance_values","std_dc_chrominance_nrcodes","std_dc_chrominance_values","std_ac_chrominance_nrcodes","std_ac_chrominance_values","computeHuffmanTbl","nrcodes","std_table","codevalue","pos_in_table","HT","writeBits","bs","posval","writeByte","writeWord","processDU","CDU","fdtbl","DC","HTDC","HTAC","EOB","M16zeroes","DU_DCT","d0","d1","d2","d3","d4","d5","d6","d7","fDCTQuant","dataOff","tmp0","tmp7","tmp1","tmp6","tmp2","tmp5","tmp3","tmp4","tmp10","tmp13","tmp11","tmp12","z1","z5","z2","z4","z3","z11","z13","tmp0p2","tmp7p2","tmp1p2","tmp6p2","tmp2p2","tmp5p2","tmp3p2","tmp4p2","tmp10p2","tmp13p2","tmp11p2","tmp12p2","z1p2","z5p2","z2p2","z4p2","z3p2","z11p2","z13p2","Diff","end0pos","lng","startpos","nrzeroes","nrmarker","setQuality","sf","YQT","UVQT","u","aasf","row","col","initQuantTables","getTime","writeDQT","writeSOF0","writeDHT","DCY","DCU","DCV","displayName","quadWidth","fillbits","sfcc","initCharLookupTable","nrlower","nrupper","cat","nr","nrneg","initCategoryNumber","initRGBYUVTable","is_with_alpha","datav","DataView","bottom_up","flag","parseHeader","parseBGR","fileSize","getUint32","reserved","headerSize","getInt32","planes","getUint16","bitPP","rawSize","hr","vr","importantColors","blue","getUint8","green","red","quad","bitn","bit1","xlen","mode","bit4","before","after","bit8","bit15","dif_w","_1_5","B","bit16","_1_6","bit24","bit32","bmpData","_dist_code","Tree","that","bi_reverse","build_tree","tree","dyn_tree","stree","stat_desc","static_tree","elems","max_code","heap_len","heap_max","heap","depth","opt_len","static_len","pqdownheap","xbits","extra","extra_bits","base","extra_base","max_length","overflow","bl_count","gen_bitlen","gen_codes","StaticTree","_length_code","base_length","base_dist","d_code","dist","extra_lbits","extra_dbits","extra_blbits","bl_order","static_ltree","static_dtree","static_l_desc","LITERALS","static_d_desc","static_bl_desc","Config","good_length","max_lazy","nice_length","max_chain","config_table","z_errmsg","smaller","tn2","tm2","Deflate","strm","pending_buf_size","last_flush","w_size","w_bits","w_mask","window_size","prev","ins_h","hash_size","hash_bits","hash_mask","hash_shift","block_start","match_length","prev_match","match_available","strstart","match_start","lookahead","prev_length","max_chain_length","max_lazy_match","strategy","good_match","nice_match","dyn_ltree","dyn_dtree","bl_tree","l_buf","lit_bufsize","last_lit","d_buf","matches","last_eob_len","bi_buf","bi_valid","l_desc","d_desc","bl_desc","init_block","END_BLOCK","scan_tree","curlen","prevlen","nextlen","max_count","min_count","REP_3_6","REPZ_3_10","REPZ_11_138","put_byte","pending_buf","pending","put_short","send_bits","send_code","c2","send_tree","bi_flush","_tr_tally","lc","out_length","in_length","dcode","compress_block","ltree","dtree","bi_windup","_tr_stored_block","stored_len","eof","copy_block","_tr_flush_block","opt_lenb","static_lenb","max_blindex","BL_CODES","build_bl_tree","lcodes","dcodes","blcodes","rank","send_all_trees","flush_block_only","flush_pending","fill_window","more","MAX_MATCH","avail_in","read_buf","longest_match","cur_match","chain_length","scan","best_len","limit","_nice_match","wmask","strend","scan_end1","scan_end","deflateReset","total_in","total_out","msg","pending_out","MIN_MATCH","lm_init","deflateInit","_level","_method","memLevel","_strategy","dstate","deflateEnd","deflateParams","err","deflateSetDictionary","dictLength","_strm","level_flags","old_flush","bstate","next_out","next_in","Z_NEED_DICT","avail_out","max_start","max_block_size","deflate_stored","bflush","hash_head","deflate_fast","max_insert","deflate_slow","STATIC_TREES","ZStream","next_in_index","next_out_index","env","zip","_jzlib_Deflater","z","buffers","lastIndex","bufferIndex","bufferSize","color_string","channels","simple_colors","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","feldspar","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslateblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","violetred","wheat","white","whitesmoke","yellow","yellowgreen","color_defs","re","example","processor","toRGB","getHelpXML","examples","sc","xml","list_item","list_color","example_div","list_item_value","require","_dereq_","freeExports","freeModule","freeGlobal","punycode","maxInt","regexPunycode","regexNonASCII","regexSeparators","errors","stringFromCharCode","RangeError","mapDomain","ucs2decode","counter","ucs2encode","digitToBasic","digit","adapt","numPoints","firstTime","baseMinusTMin","input","basic","oldi","baseMinusT","codePoint","inputLength","bias","lastIndexOf","handledCPCount","basicLength","q","currentValue","handledCPCountPlusOne","qMinusT","domain","cloneNode","javascriptEnabled","firstChild","nextSibling","_scrollTop","scrollTop","_scrollLeft","scrollLeft","clonedCanvas","putImageData","getImageData","cloneCanvasContents","initNode","containerDocument","documentElement","container","visibility","border","scrolling","Promise","resolve","documentClone","interval","setInterval","clearInterval","scrollTo","scrollY","scrollX","pageXOffset","pageYOffset","restoreOwnerScroll","replaceChild","adoptNode","Color","fromArray","namedColor","hex6","hex3","darken","amount","round","isTransparent","isBlack","_hex3","_hex6","_rgb","_rgba","isColor","Support","CanvasRenderer","ImageLoader","NodeParser","NodeContainer","utils","createWindowClone","loadUrlDocument","getBounds","html2canvasCloneIndex","nodeList","logging","async","allowTaint","removeContainer","imageTimeout","strict","proxy","reject","innerWidth","innerHeight","renderWindow","windowWidth","windowHeight","html2canvasIndex","attributeName","selector","querySelector","removeAttribute","clonedWindow","onclone","renderDocument","html2canvasExport","support","imageLoader","scrollWidth","scrollHeight","documentHeight","cleanupContainer","croppedCanvas","smallImage","DummyImageContainer","promise","family","middle","span","padding","verticalAlign","offsetTop","Font","FontMetrics","getMetrics","FrameContainer","sameOrigin","proxyLoad","GradientContainer","colorStops","x0","y0","TYPES","LINEAR","RADIAL","REGEXP_COLORSTOP","cors","tainted","ImageContainer","ProxyImageContainer","SVGContainer","SVGNodeContainer","LinearGradientContainer","WebkitGradientContainer","getOrigin","findImages","nodes","imageNodes","findBackgroundImage","parseBackgroundImages","hasImageBackground","newImage","imageExists","isSVG","isSameOrigin","useCORS","isInline","some","hostname","port","getPromise","timeout","fetch","all","timer","race","clearTimeout","hasDirection","REGEXP_DIRECTION","ratio","colorStop","colorStopMatch","stop","find","logger","parseBackgrounds","offsetBounds","borders","backgroundClip","visible","computedStyles","backgroundImages","transformData","transformMatrix","isPseudoElement","opacity","isPercentage","removePx","asFloat","cloneTo","getOpacity","cssFloat","assignStack","isElementVisible","Node","TEXT_NODE","attribute","computedStyle","prefixedCss","prefix","cssInt","weight","parseClip","CLIP","cssList","parseBackgroundSize","targetRatio","currentRatio","parseBackgroundPosition","backgroundSize","parseBackgroundRepeat","parseTextShadows","textShadow","shadows","TEXT_SHADOW_PROPERTY","TEXT_SHADOW_VALUES","blur","parseTransform","hasTransform","parseBounds","parseTransformMatrix","matrix3d","parseMatrix","MATRIX_PROPERTY","getValue","option","selectedIndex","placeholder","TextContainer","PseudoElementContainer","StackingContext","range","renderQueue","rectangle","canvasBackground","visibile","createPseudoHideStyles","disableAnimations","flatten","getChildren","getPseudoElements","calculateOverflowClips","isElement","createStackingContexts","sortStackingContexts","renderIndex","asyncRenderer","paint","hasParentClip","ClearTransform","appendToDOM","parseBorders","cssClip","cleanDOM","isTextNode","queue","asyncTimer","createStyles","PSEUDO_HIDE_ELEMENT_CLASS_BEFORE","PSEUDO_HIDE_ELEMENT_CLASS_AFTER","hidePseudoElements","ELEMENT_NODE","getPseudoElement","first","stripQuotes","isImage","pseudoNode","pseudoContainer","parentContainer","renderableNode","nonIgnoredElement","newStackingContext","hasOwnStacking","getParentStack","contexts","isRootElement","hasOpacity","isPositionedForStacking","isBodyWithTransparentRoot","isPositioned","zIndex0","isInlineBlock","isFloating","parseTextBounds","textList","rangeBounds","getRangeBounds","replacementNode","splitText","getWrapperBounds","wrapper","backupText","createRange","setStart","setEnd","getBoundingClientRect","negativeZindex","negativeZIndex","descendantElements","descendantNonFloats","not","nonInlineNonPositionedDescendants","inlineLevel","nonPositionedFloats","inFlow","stackLevel0","hasText","positiveZindex","positiveZIndex","isStackingContext","paintText","paintNode","setOpacity","paintCheckbox","paintRadio","paintElement","renderBackground","renderBorders","imgContainer","renderImage","imageContainer","paintFormValue","borderPoints","calculateCurvePoints","calculateBorders","checked","circleStroke","applyTextTransform","characters","ucs2","letterRendering","noLetterSpacing","onWordBoundary","isWordBoundary","getWords","fontShadow","clearShadow","renderTextDecoration","borderColorTransforms","inset","nodeBounds","borderSide","bx","by","bw","bh","drawSide","c1","c3","c4","topLeftOuter","topLeftInner","topRightOuter","topRightInner","bottomRightOuter","bottomRightInner","bottomLeftOuter","bottomLeftInner","getCurvePoints","r1","r2","kappa","ox","oy","xm","ym","topLeft","bezierCurve","topRight","bottomRight","bottomLeft","borderRadius","tlh","tlv","trh","trv","brh","brv","blh","blv","topWidth","rightHeight","bottomWidth","leftHeight","subdivide","startControl","endControl","lerp","bc","cd","abbc","bccd","dest","curveTo","borderArgs","curveToReversed","borderData","radius1","radius2","outer1","inner1","outer2","inner2","parseCorner","corner1","corner2","asInt","nodeContainer","characterCode","side","getBorderRadiusData","colorTransform","parseBackgroundClip","XHR","decode64","Proxy","proxyUrl","supportsCORS","createCallback","createProxyUrl","jsonp","response","proxyCount","cleanup","documentFromHTML","html","parser","DOMParser","parseFromString","implementation","createHTMLDocument","ee","host","insertBefore","ProxyURL","supportsCORSImage","getHideClass","paddingLeft","paddingTop","paddingRight","paddingBottom","renderBackgroundColor","renderBackgroundImage","renderBorder","drawShape","backgroundImage","renderBackgroundRepeating","gradientImage","renderBackgroundGradient","backgroundRepeatShape","renderBackgroundRepeat","taintCtx","variables","hasEntries","strokeColor","shape","taints","sw","sh","dw","dh","shapes","point","setVariable","backgroundPosition","borderLeft","borderTop","createPattern","resizeImage","gradient","createLinearGradient","addColorStop","ownStacking","parentStack","testRangeBounds","testCORS","testSVG","testElement","selectNode","hasFabric","inlineFormatting","fabric","loadSVGFromString","createCanvas","removeContentType","objects","StaticCanvas","lowerCanvasEl","setWidth","setHeight","util","groupSVGElements","renderAll","_native","XMLSerializer","serializeToString","parseSVGDocument","capitalize","encoded2","encoded3","encoded4","byte1","byte2","byte3","chars","clientRect","offsetParent","offsetLeft","definition","prefix_i","quote","numParen","appendResult","xhr","statusText","PLUS","SLASH","NUMBER","LOWER","UPPER","PLUS_URL_SAFE","SLASH_URL_SAFE","elt","Data","readString","Subset","registerTTF","vfs","b64","placeHolders","L","b64ToByteArray","directory","Directory","HeadTable","NameTable","CmapTable","hhea","HheaTable","maxp","MaxpTable","HmtxTable","post","PostTable","os2","OS2Table","loca","LocaTable","glyf","GlyfTable","exists","lineGap","xMin","yMin","xMax","yMax","hi","low","raw","_ref","_i","_len","_results","italic_angle","xHeight","familyClass","isSerif","isScript","isFixedPitch","glyph","forGlyph","advance","charCode","includeGap","gap","Table","readByte","byte","readUInt32","writeUInt32","readInt32","int","writeInt32","readUInt16","writeUInt16","readInt16","writeInt16","writeString","readShort","writeShort","readLongLong","b1","b2","b3","b4","b5","b6","b7","b8","readInt","writeInt","read","entry","scalarType","tableCount","searchRange","entrySelector","rangeShift","tables","tag","adjustment","directoryLength","headOffset","log2","tableData","__slice","__hasProp","__extends","__super__","_super","revision","checkSumAdjustment","magicNumber","created","modified","macStyle","lowestRecPPEM","fontDirectionHint","indexToLocFormat","glyphDataFormat","CmapEntry","endCode","glyphId","glyphIds","idDelta","idRangeOffset","saveOffset","segCount","segCountX2","startCode","tail","_j","_k","platformID","encodingID","language","charmap","charMap","codes","diff","endCodes","glyphIDs","indexes","last","nextID","old","rangeOffsets","startCodes","startGlyph","subtable","_l","_len1","_len2","_len3","_len4","_len5","_len6","_len7","_m","_n","_name","_o","_p","_q","maxGlyphID","LN2","advanceWidthMax","minLeftSideBearing","minRightSideBearing","xMaxExtent","caretSlopeRise","caretSlopeRun","caretOffset","metricDataFormat","numberOfMetrics","averageCharWidth","weightClass","widthClass","ySubscriptXSize","ySubscriptYSize","ySubscriptXOffset","ySubscriptYOffset","ySuperscriptXSize","ySuperscriptYSize","ySuperscriptXOffset","ySuperscriptYOffset","yStrikeoutSize","yStrikeoutPosition","panose","charRange","vendorID","selection","firstCharIndex","lastCharIndex","ascent","winAscent","winDescent","codePageRange","defaultChar","breakChar","maxContext","numberOfGlyphs","underlinePosition","underlineThickness","minMemType42","maxMemType42","minMemType1","maxMemType1","glyphNameIndex","names","_results1","numGlyphs","NameEntry","languageID","entries","stringOffset","strings","nameID","copyright","fontSubfamily","uniqueSubfamily","postscriptName","trademark","manufacturer","designer","description","vendorUrl","designerUrl","license","licenseUrl","preferredFamily","preferredSubfamily","compatibleFull","sampleText","maxPoints","maxContours","maxCompositePoints","maxComponentContours","maxZones","maxTwilightPoints","maxStorage","maxFunctionDefs","maxInstructionDefs","maxStackElements","maxSizeOfInstructions","maxComponentElements","maxComponentDepth","lsbCount","lsb","leftSideBearings","_ref1","cache","glyphFor","numberOfContours","lengthOf","CompoundGlyph","SimpleGlyph","glyphs","old2new","compound","glyphOffsets","activeGlyphs","glyfPtr","listGlyf","newLocaTable","unicodes","next","generateCmap","roman","unicodeCmap","glyphsFor","additionalIDs","ids","new2old","newIDs","nextGlyphID","oldID","oldIDs","invert","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","getUTCSeconds","makeImage","scratchCanvas","scratchCtx","chunkSize","palLen","delayDen","delayNum","section","palShort","animation","compressionMethod","filterMethod","interlaceMethod","numPlays","Infinity","xOffset","yOffset","disposeOp","blendOp","grayscale","hasAlphaChannel","load","responseType","png","mozResponseArrayBuffer","pixelBytes","fullPixels","_this","pass","abyte","pa","pb","pc","scanlineLength","upper","upperLeft","isFull","fullPos","partPos","getBytes","decodePalette","copyToImageData","_decodedPalette","decodeFrames","createImageData","renderFrame","animate","doFrame","frameNumber","_timeout","stopAnimation","_png","DecodeStream","bufferLength","ensureBuffer","requested","current","buffer2","getByte","readBlock","bufEnd","lookChar","getChar","makeSubStream","dict","Stream","skip","reset","codeLenCodeMap","lengthDecode","distDecode","fixedLitCodeTab","fixedDistCodeTab","getBits","codeSize","codeBuf","bytesPos","getCode","codeLen","codeVal","generateHuffmanTable","lengths","code2","repeat","what","litCodeTable","distCodeTable","numLitCodes","numDistCodes","numCodeLenCodes","codeLenCodeLengths","codeLenCodeTab","codeLengths","code1","blockLen","check","flg","con","dummy","methods","hasDontEnumBug","dontEnums","dontEnumsLength","h1","h3","h4","ac","enc","tmp_arr","o1","o2","o3","fun","thisArg","arg","propertyIsEnumerable","target","source"],"mappings":"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,YACA,2BACG,qBACH,kBACG,8BACA,2BACA,2BACA,4BACA,4BACA,gCACA,gCACA,iCACA,sCACA,mCACA,kCACA,wBACH,eACA,cACA,cACA,YACA,aACA,4BACG,2BACA,0BACA,0BACA,8BACA,0BACA,0BACH,cACC,cACD,yBACG,oBACH,cACA,cACA,4BACG,2BACA,2BACA,iCACA,8BACA,0BACH,WACA,cACA,aACA,YACA,WACA,eACA,eACA,gBACA,eACA,WACA,6BACG,2BACH,cACA,aACA,cACA,YACA,WACA,cACC,aACD,iBACG,+BACA,0BACH,WACA,aACA,gBACA,mBACA,qBACA,WACA,eACA,aACA,WACA,aACA,eACA,YACA,YACA,YACA,eACA,wBACA,yBACA,aACA,WACA,WACA,kBACG,kBACH,YACA,qBACG,yBACH,kBACG,0BACA,wBACH,aACA,oBACA,mBACG,yBACH,kBACG,wBACH,oBACA,WACA,cACA,eACA,YACA,gBACA,aACA,YACA,eACA,YACA,aACA,kBACG,8BACA,4BACA,0BACA,6BACA,+BACA,uCACA,4BACA,gCACA,8BACA,6BACA,2BACA,8BACA,2BACA,6BACA,yBACA,gCACA,0BACA,4BACA,yBACH,UACA,aACA,kBACG,4BACA,sBACH,WACA,WACA,YACA,WACC,WACD,YACA,YACA,aACA,aACA,gBACC,mBACD,UACA,WACA,gBACA,aACA,aACA,WACA,WACA,aACA,QAQIwwC,iBACL9nC,SAAS+nC,iBAAiBE,aAAeH,UACM,IAAhDn2C,KAAKqO,SAAS+nC,iBAAiBC,oBAC1BhoC,SAASvL,OAAOzE,UAAU,cAAc,gBACpCgQ,SAAS6O,MAAM,UAAYld,KAAKqO,SAAS+nC,iBAAiBE,aAAe,aAE7EjoC,SAAS+nC,iBAAiBC,cAAe,IAG/Cr2C,OAEZjC,MAAMb;;;;;;AAYEA,IA4TRa,MAAMb,IAhTHC,mBAAqBD,IAAIC,mBAAqB,SAAU4K,KAAM1H,aAY5D4H,EACAC,EACAquC,UAXA7jC,YAFJrS,QAAUA,SAAW,IAEI+G,MAAQpH,KAAKqO,SAAS0N,UAC3Cxa,SAAWlB,QAAQkB,UAAYvB,KAAKqO,SAAS2lB,cAC7CvyB,UAAYpB,QAAQoB,WAAazB,KAAKqO,SAASmoC,eAE/C7I,OAASttC,QAAQstC,OAASttC,QAAQstC,OAASj7B,WAAW/J,SAAS+kC,QAAQC,OACvE8I,iBAAmB9I,OAAO+I,IAAM/I,OAAO+I,IAAM,EAC7C9I,QAAUvtC,QAAQutC,QAAUvtC,QAAQutC,QAAUl7B,WAAW/J,SAAS+kC,QAAQE,QAC1E+I,kBAAoB/I,QAAQ8I,IAAM9I,QAAQ8I,IAAM,EAKhDE,gBAAkB,EAClBC,mBAAqBlJ,OAAO,IAAM8I,iBAClCxpC,OAAS,OAERhF,EAAI,EAAGC,EAAIH,KAAKjI,OAAQmI,EAAIC,EAAGD,IAClCsuC,UAAYxuC,KAAKc,WAAWZ,GAEqB,mBAAtCyK,WAAW/J,SAASmuC,cAC7B7pC,OAAOpN,MAAM6S,WAAW/J,SAASouC,aAAarkC,WAAW/J,SAASquC,iBAAiBT,YAAc90C,WAAa,IAAOF,WAAa,GAAK,KAEvI0L,OAAOpN,MAAM8tC,OAAO4I,YAAcM,oBAAsBJ,kBAAoB7I,QAAQ2I,YAAc3I,QAAQ2I,WAAWK,kBAAoB,GAAKD,mBAEhJC,gBAAkBL,iBAGbtpC,QAYL7P,YAAcF,IAAIE,YAAc,SAAUshB,eACxCzW,EAAIyW,MAAM5e,OACVmN,OAAS,EACNhF,GAELgF,QAAUyR,QADVzW,UAGKgF,QAaL5P,mBAAqBH,IAAIG,mBAAqB,SAAU0K,KAAM1H,aAG5DkB,UAFJlB,QAAUA,SAAW,IAEEkB,UAAYvB,KAAKqO,SAAS2lB,cAC7C5sB,KAAO/G,QAAQ+G,MAAQpH,KAAKqO,SAAS0N,UACrCta,UAAYpB,QAAQoB,WAAazB,KAAKqO,SAASmoC,qBAER,mBAAhCpvC,KAAKuB,SAASmuC,cACd1vC,KAAKuB,SAASmuC,cAAc/uC,KAAMxG,SAAUE,WAAaF,SAEzDnE,YAAYD,mBAAmBqC,MAAMQ,KAAMX,aAQpD/B,cAAgB,SAAuB25C,KAAMC,aAAcC,gBAAiBC,gBAC1EC,OAAS,GAGTpvC,EAAI,EACJC,EAAI+uC,KAAKn3C,OACTw3C,WAAa,EACVrvC,IAAMC,GAAKovC,WAAaJ,aAAajvC,GAAKkvC,iBAC/CG,YAAcJ,aAAajvC,GAC3BA,IAGFovC,OAAOx3C,KAAKo3C,KAAK93C,MAAM,EAAG8I,QAGtBsvC,YAActvC,MAClBqvC,WAAa,EACNrvC,IAAMC,GACPovC,WAAaJ,aAAajvC,GAAKmvC,SACjCC,OAAOx3C,KAAKo3C,KAAK93C,MAAMo4C,YAAatvC,IACpCqvC,WAAa,EACbC,YAActvC,GAEhBqvC,YAAcJ,aAAajvC,GAC3BA,WAEEsvC,cAAgBtvC,GAClBovC,OAAOx3C,KAAKo3C,KAAK93C,MAAMo4C,YAAatvC,IAG/BovC,QAKL95C,wBAA0B,SAAiCwK,KAAMyvC,OAAQn3C,SAItEA,UACHA,QAAU,QAQR42C,KACAC,aAGAjvC,EACAC,EACAxH,IACA+2C,WAZAhkC,KAAO,GACPK,MAAQ,CAACL,MACTikC,YAAcr3C,QAAQwtC,YAAc,EACpC8J,iBAAmB,EACnBC,oBAAsB,EAGtBC,MAAQ9vC,KAAKtB,MAAM,KACnBqxC,eAAiB36C,mBAAmBqC,MAAMQ,KAAM,CAAC,IAAKK,UAAU,MAOlEo3C,YAD0B,IAAxBp3C,QAAQo3C,WACGI,MAAM,GAAG/3C,OAAS,EAElBO,QAAQo3C,YAAc,EAErB,KACVM,IAAM74C,MAAMu4C,YAAYrzC,KAAK,KAC7B4zC,KAAO,GACXH,MAAMnxC,KAAI,SAAUuxC,MAClBA,IAAMA,IAAIxxC,MAAM,UACR3G,OAAS,EACfk4C,KAAOA,KAAKvnC,OAAOwnC,IAAIvxC,KAAI,SAAUuxC,IAAKC,YAChCA,KAAOD,IAAIn4C,OAAS,KAAO,IAAMm4C,QAG3CD,KAAKn4C,KAAKo4C,IAAI,OAGlBJ,MAAQG,KACRP,WAAap6C,mBAAmBmC,MAAMQ,KAAM,CAAC+3C,IAAK13C,cAG/C4H,EAAI,EAAGC,EAAI2vC,MAAM/3C,OAAQmI,EAAIC,EAAGD,IAAK,KACpCkwC,MAAQ,KAEZlB,KAAOY,MAAM5vC,GACTwvC,YAAyB,MAAXR,KAAK,KACrBA,KAAOA,KAAKhzC,OAAO,GACnBk0C,MAAQ,GAEVjB,aAAe/5C,mBAAmBqC,MAAMQ,KAAM,CAACi3C,KAAM52C,UAGjDq3C,YAAcC,kBAFlBC,oBAAsBx6C,YAAY85C,eAEyBM,QAAUW,MAAO,IACtEP,oBAAsBJ,OAAQ,KAGhC92C,IAAMpD,cAAckC,MAAMQ,KAAM,CAACi3C,KAAMC,aAAcM,QAAUE,YAAcC,kBAAmBH,SAEhG/jC,KAAK5T,KAAKa,IAAIiQ,SAEd8C,KAAO,CAAC/S,IAAI66B,OAEL76B,IAAIZ,QACTgU,MAAMjU,KAAK,CAACa,IAAIiQ,UAElBinC,oBAAsBx6C,YAAY85C,aAAa/3C,MAAM83C,KAAKn3C,QAAU2T,KAAK,GAAKA,KAAK,GAAG3T,OAAS,UAG/F2T,KAAO,CAACwjC,MAIVnjC,MAAMjU,KAAK4T,MACXikC,YAAcE,oBAAsBH,WACpCE,iBAAmBG,oBAEnBrkC,KAAK5T,KAAKo3C,MAEVS,aAAeC,iBAAmBC,oBAClCD,iBAAmBG,kBAInBL,eACEW,YAAc,SAAqB9hB,GAAI4hB,YACjCA,IAAMH,IAAM,IAAMzhB,GAAGlyB,KAAK,WAGhCg0C,YAAc,SAAqB9hB,WAC9BA,GAAGlyB,KAAK,aAIZ0P,MAAMpN,IAAI0xC,cAiBnBl7C,IAAIsU,gBAAkB,SAAUzJ,KAAMyvC,OAAQn3C,aA6CxCg4C,WAzCAC,OAFJj4C,QAAUA,SAAW,IAEDkB,UAAYvB,KAAKqO,SAAS2lB,cAC1CukB,WAAa,SAAUl4C,aACrBstC,OAAS,GACR,GAEDC,QAAU,MAETvtC,QAAQstC,QAAWttC,QAAQutC,cAoBvB,CACLD,OAAQttC,QAAQstC,OAChBC,QAASvtC,QAAQutC,aArBf3jB,EAAIjqB,KAAKqO,SAAS0N,QAAQ1b,QAAQqH,SAAUrH,QAAQsH,kBAMpDsiB,EAAEthB,SAAF,QACK,CACLglC,OAAQ1jB,EAAEthB,SAAF,QAAqBglC,QAAUA,OACvCC,QAAS3jB,EAAEthB,SAAF,QAAqBilC,SAAWA,SAGpC,CACLxmC,KAAM6iB,EAAEthB,SACRpH,SAAUvB,KAAKqO,SAAS2lB,cACxBvyB,UAAWzB,KAAKqO,SAASmoC,iBAe/Bp3C,KAAKY,KAAMK,SAKXg4C,WADEn5C,MAAMqK,QAAQxB,MACHA,KAEAA,KAAKtB,MAAM,aAMtB+xC,gBAAkB,EAAMx4C,KAAKqO,SAASsD,YAAc6lC,OAASc,MASjEC,WAAW1K,WAAaxtC,QAAQwtC,WAAkC,EAArBxtC,QAAQwtC,WAAmB7tC,KAAKqO,SAASsD,YAAc2mC,MAAQ,EAC5GC,WAAWd,WAAap3C,QAAQo3C,eAE5BxvC,EACAC,EACA+E,OAAS,OACRhF,EAAI,EAAGC,EAAImwC,WAAWv4C,OAAQmI,EAAIC,EAAGD,IACxCgF,OAASA,OAAOwD,OAAOlT,wBAAwBiC,MAAMQ,KAAM,CAACq4C,WAAWpwC,GAAIuwC,gBAAiBD,qBAGvFtrC;;;;;;SASA/P,SA0INu7C,WAAa,SAAoBtsC,cAIhCusC,QAAU,GAELzwC,EAAI,EAAGA,EAHF,mBAGcnI,OAAQmI,IACnCywC,QAJa,mBAIGzwC,IALH,mBAKiBA,OAM3B0wC,YAKAC,gBAGA1uC,IAIA1B,GAdAyE,OAAS,GACT4rC,KAAO,EAIPC,aAAe7rC,OACf8rC,YAAc,GAEdC,SAAW,GACXC,WAAa,GAGbC,QAAU/sC,KAAKrM,OAAS,MAI5BmI,EAAI,EAEGA,GAAKixC,SAGX1wC,GAAK2D,KAAKlE,GACVA,GAAK,EAEK,KAANO,GACCmwC,aAEHzuC,IAAMyuC,YAAYv0C,KAAK,IACvBu0C,YA7BCQ,WAgCDR,YAAc,GAELA,YACVA,YAAY94C,KAAK2I,IACD,KAANA,IAEVuwC,YAAYl5C,KAAK,CAACi5C,aAAc5uC,MAChC4uC,aAAe,GACf5uC,IAxCEivC,WAyCc,KAAN3wC,KAEVowC,gBAAkBG,YAAYxd,OACd,GAAGqd,gBAAgB,IAAME,aACzC5uC,IA7CEivC,UA8CFL,aAAeF,gBAAgB,IACf,KAANpwC,GACVqwC,MAAQ,EAhDNM,YAmDEjvC,IACCwuC,QAAQj6C,eAAe+J,KAC1BwwC,UAAYN,QAAQlwC,IACpB0B,IAAMlG,SAASg1C,SAAU,IAAMH,KAC/BA,KAAO,EACPG,SAAW,IAEXA,UAAYxwC,GAGTkwC,QAAQj6C,eAAe+J,KAC1BywC,YAAcP,QAAQlwC,IACtBswC,aAAa5uC,KAAOlG,SAASi1C,WAAY,IAAMJ,KAC/CA,KAAO,EACP3uC,IAjEAivC,UAkEAF,WAAa,IAEbA,YAAczwC,UAMXyE,QAgBJ7E,cAAgB,WACN,CAAC,mCACKqwC,WAAW,+JAE3B5oB,UAAY,SAAa,SAChBznB,6BACKA,oCACOA,gCACJA,wBACNA,+BACKA,sCACOA,kCACJA,4BACNA,2BACDA,iCACMA,6BACJA,gBAqBdglC,YAAc,SAAa,mBASVqL,WAAW,gEACVA,WAAW,myDACbA,WAAW,wnDAClBA,WAAW,mEACCA,WAAW,0DACpBA,WAAW,g0DACfA,WAAW,gOACRA,WAAW,wsDACCA,WAAW,6nDACpBA,WAAW,gEACXA,WAAW,4DACXA,WAAW,msDACZA,WAAW,83DACLA,WAAW,krDAelCv7C,IAAI4F,OAAOjD,KAAK,CAAC,UAAW,SAAUuH,UACjCgyC,QACAC,gBAEAjxC,eAEJgxC,QAAUhM,YAAW,QAAWhmC,KAAKE,oBAGnC+xC,gBADGjyC,KAAKuB,SAAL,QACevB,KAAKuB,SAAL,QAEAvB,KAAKuB,SAAL,QAA0B,IAG7BglC,OAASyL,QAAQzL,OACjC0L,gBAAgBzL,QAAUwL,QAAQxL,UAGnCxlC,cAAgBynB,UAAS,QAAWzoB,KAAKE,oBAGvC+xC,gBADGjyC,KAAKuB,SAAL,QACevB,KAAKuB,SAAL,QAEAvB,KAAKuB,SAAL,QAA0B,IAG7BpB,SAAWa,cACvBA,cAAcQ,WAAaR,cAAcQ,UAAU9I,SACtDsH,KAAKG,SAAWa,cAAcQ,UAAU,SAIzC7K,MAAMb,cAOEa,MAAOC,QAEdD,MAAMb,IAAI4F,OAAOjD,KAAK,CAAC,UAAW,SAAUuH,MACpCrJ,MAAMb,IAAIo8C,gBAAgBlyC,KAAKE,iBAC/BF,KAAKuB,SAAW5K,MAAMb,IAAIq8C,QAAQjsC,KAAKlG,KAAKE,eAAgBF,KAAKM,SAAU3J,MAAMb,IAAIs8C,eAAepyC,KAAKE,gBAAiBF,KAAKG,UAC/HH,KAAKuB,SAAS+kC,QAAUtmC,KAAKuB,SAAS+kC,SAAW,CAAEnmC,SAAU,GAAIqmC,QAAS,GAAID,OAAQ,KAC/EvmC,KAAK1I,GAAGS,MAAM,GAAK,IAC1BO,QAAQC,MAAM,qFAAuFyH,KAAKE,eAAiB,WAGpIvJ,MAAuB,oBAAT0Z,MAAwBA,MAA0B,oBAAXzZ,QAA0BA,QAA4B,oBAAX0Z,QAA0BA,QAAUC,SAAS,cAATA;;;;;SAM5HC,UAoBPA,SAAS6hC,OAAS,SAAUC,QAAS5pC,EAAGC,EAAG6E,EAAGC,MAGtCskC,YAEArpC,GAFAqpC,YAEeppC,QACT,IAAI9G,MAAM,gDA4CX0wC,0BAA0BjoB,cAO3B5hB,EAAItB,WAAWkjB,KAAK,IACpB3hB,EAAIvB,WAAWkjB,KAAK,IACpBkoB,QAAU,GACVlhC,SAAW,EACXtM,IAAMslB,KAAK5xB,OAER4Y,SAAWtM,KACS,MAAnBslB,KAAKhZ,WACLkhC,QAAQ/5C,KAAK,CAAC2O,WAAWkjB,KAAKhZ,SAAW,IAAKlK,WAAWkjB,KAAKhZ,SAAW,IAAKlK,WAAWkjB,KAAKhZ,SAAW,IAAKlK,WAAWkjB,KAAKhZ,SAAW,IAAKlK,WAAWkjB,KAAKhZ,SAAW,IAAKlK,WAAWkjB,KAAKhZ,SAAW,MACzMA,UAAY,GACc,MAAnBgZ,KAAKhZ,WACZkhC,QAAQ/5C,KAAK,CAAC2O,WAAWkjB,KAAKhZ,SAAW,IAAKlK,WAAWkjB,KAAKhZ,SAAW,MACzEA,UAAY,GAEZA,UAAY,QAGb,CAAC5I,EAAGC,EAAG6pC,aAIdC,iBAnC2BH,QAASI,WAChCC,UAAYD,MAAME,eAAiBF,MAAMG,iBAAiBzsC,gBAC9DusC,SAAS78B,MAAMw8B,SACfK,SAASlX,QACFkX,SAAS9O,qBAAqB,OAAO,GA+BlCiP,CAAsBR,iBAxDVlsC,cAIlBssC,MAAQtsC,SAASuZ,cAAc,0BAjBpBozB,QAAS3sC,cACpB4sC,SAAW5sC,SAASuZ,cAAc,SACtCqzB,SAASr0C,KAAO,WACZq0C,SAASC,WAETD,SAASC,WAAW/N,QAAU6N,QAG9BC,SAAS9iB,YAAY9pB,SAAS8sC,eAAeH,UAEjD3sC,SAASy9B,qBAAqB,QAAQ,GAAG3T,YAAY8iB,UASrDG,CAAU,2DAA4D/sC,UAEtEssC,MAAMl4B,KANQ,aAOdk4B,MAAMU,aAAa,QAAS,GAC5BV,MAAMU,aAAa,SAAU,GAC7BV,MAAMU,aAAa,cAAe,KAClCV,MAAMU,aAAa,YAAa,MAChCV,MAAMU,aAAa,WAAY,YAC/BV,MAAMU,aAAa,QAAS,yBAE5BhtC,SAAS6pB,KAAKC,YAAYwiB,OAEnBA,MAqCMW,CAAiBjtC,WAE9B0G,MAAQ,CAAC,EAAG,GACZwmC,KAAOlsC,WAAWqrC,QAAQxuB,aAAa,UACvCsvB,KAAOnsC,WAAWqrC,QAAQxuB,aAAa,WAEvCqvB,MAAQC,OAGJ/lC,GAAKC,EACLX,MAAQ,CAACU,EAAI8lC,KAAM7lC,EAAI8lC,MAIlB/lC,EACDV,MAAQ,CAACU,EAAI8lC,KAAM9lC,EAAI8lC,MAChB7lC,IACPX,MAAQ,CAACW,EAAI8lC,KAAM9lC,EAAI8lC,YAI/B1yC,EACAC,EACAxH,IACAk6C,UACAC,MAAQhB,QAAQ9jB,eACf9tB,EAAI,EAAGC,EAAI2yC,MAAM/6C,OAAQmI,EAAIC,EAAGD,KACjCvH,IAAMm6C,MAAM5yC,IACJ6yC,SAAyC,SAA9Bp6C,IAAIo6C,QAAQrvC,iBAC3BmvC,UAAYjB,0BAA0Bj5C,IAAI2qB,aAAa,KAAK5kB,MAAM,OAExD,GAAKm0C,UAAU,GAAK1mC,MAAM,GAAKpE,EAEzC8qC,UAAU,GAAKA,UAAU,GAAK1mC,MAAM,GAAKnE,OAEpC+D,MAAM1U,KAAKY,KAAM46C,UAAU,GAC9BA,UAAU,GACVA,UAAU,GACV1mC,eAOHlU,MAIX4X,SAASmjC,OAASnjC,SAAS6hC,OAsB3B7hC,SAASojC,cAAgB,SAAUC,IAAKnrC,EAAGC,EAAG6E,EAAGC,EAAGyT,MAAOgI,YAAaxE,aAEhE0E,MAAM1gB,IAAM0gB,MAAMzgB,SAClBrQ,QAAQC,MAAM,2CAA4CN,WACpD,IAAI4J,MAAM,wDAGhBunB,MAAM5b,IAAM4b,MAAM3b,SAClBnV,QAAQC,MAAM,4CAA6CN,WACrD,IAAI4J,MAAM,gFAGhB6d,OAAStZ,SAASuZ,cAAc,UACpCD,OAAOzd,MAAQuL,EACfkS,OAAOxd,OAASuL,MACZmS,IAAMF,OAAOG,WAAW,aAC5BD,IAAIM,UAAY,OAChBN,IAAIQ,SAAS,EAAG,EAAGV,OAAOzd,MAAOyd,OAAOxd,QAGxC4xC,MAAMp0B,OAAQm0B,IAAK,CACfE,aAAa,EACbC,iBAAiB,EACjBC,kBAAkB,EAClBC,aAAa,SAGZxzB,SAAShB,OAAOuB,UAAU,aAAc,GAAMvY,EAAGC,EAAG6E,EAAGC,EAAGyb,YAAaxE,UACrE9rB,OAEZjC,MAAMb,cAUE0a,UAETA,SAASq0B,cAAgB,SAAUsP,wBAE7BC,kBAAoB,IAAIC,OAAOF,eAAgB,KAC1C1xC,EAAI,EAAGA,GAAK7J,KAAKqO,SAASs8B,mBAAoB9gC,QAChD,IAAI5B,EAAI,EAAGA,EAAIjI,KAAKqO,SAAShM,MAAMwH,GAAG/J,OAAQmI,SAC5CoG,SAAShM,MAAMwH,GAAG5B,GAAKjI,KAAKqO,SAAShM,MAAMwH,GAAG5B,GAAGkB,QAAQqyC,kBAAmBx7C,KAAKqO,SAASs8B,2BAG5F3qC,OAERjC,MAAMb,cAeE0a,UA0FPA,SAAS8jC,kBAAoB,SAAUr7C,QAASs7C,aAIxCC,cAHJv7C,QAAUA,SAAW,GACrBs7C,QAAUA,UAAW,MA+BjBE,OACAr1C,MA7BAs1C,sBAAwB,aACT,CAAEC,cAAc,EAAOv1C,OAAO,EAAOT,KAAM,UAAWi2C,aAAa,EAAOC,SAAU,EAAC,GAAM,GAAQC,WAAY,iBAC/G,CAAEH,cAAc,EAAOv1C,OAAO,EAAOT,KAAM,UAAWi2C,aAAa,EAAOC,SAAU,EAAC,GAAM,GAAQC,WAAY,kBAC9G,CAAEH,cAAc,EAAOv1C,OAAO,EAAOT,KAAM,UAAWi2C,aAAa,EAAOC,SAAU,EAAC,GAAM,GAAQC,WAAY,eAClH,CAAEH,cAAc,EAAOv1C,OAAO,EAAOT,KAAM,UAAWi2C,aAAa,EAAOC,SAAU,EAAC,GAAM,GAAQC,WAAY,kBAC5G,CAAEH,cAAc,EAAOv1C,OAAO,EAAOT,KAAM,UAAWi2C,aAAa,EAAOC,SAAU,EAAC,GAAM,GAAQC,WAAY,qBAC5G,CAAEH,cAAc,EAAOv1C,OAAO,EAAOT,KAAM,UAAWi2C,aAAa,EAAOC,SAAU,EAAC,GAAM,GAAQC,WAAY,2BACzG,CAAEH,aAAc,UAAWv1C,MAAO,UAAWT,KAAM,OAAQi2C,aAAa,EAAOC,SAAU,CAAC,UAAW,cAAe,YAAa,SAAUC,WAAY,eACnK,CAAEH,aAAc,MAAOv1C,MAAO,MAAOT,KAAM,OAAQi2C,aAAa,EAAOC,SAAU,CAAC,MAAO,OAAQC,WAAY,cAC9G,CAAEH,aAAc,UAAWv1C,MAAO,UAAWT,KAAM,OAAQi2C,aAAa,EAAOC,SAAU,CAAC,WAAY,UAAW,UAAW,WAAY,UAAWC,WAAY,cAC/J,CAAEH,aAAc,UAAWv1C,MAAO,UAAWT,KAAM,OAAQi2C,aAAa,EAAOC,SAAU,CAAC,WAAY,UAAW,UAAW,WAAY,UAAWC,WAAY,eAC9J,CAAEH,aAAc,UAAWv1C,MAAO,UAAWT,KAAM,OAAQi2C,aAAa,EAAOC,SAAU,CAAC,WAAY,UAAW,UAAW,WAAY,UAAWC,WAAY,eAC/J,CAAEH,aAAc,UAAWv1C,MAAO,UAAWT,KAAM,OAAQi2C,aAAa,EAAOC,SAAU,CAAC,WAAY,UAAW,UAAW,WAAY,UAAWC,WAAY,kBAC5J,CAAEH,aAAc,aAAcv1C,MAAO,aAAcT,KAAM,OAAQi2C,aAAa,EAAOC,SAAU,CAAC,aAAc,QAASC,WAAY,YACzI,CAAEH,aAAc,GAAIv1C,MAAO,OAAQT,KAAM,OAAQi2C,aAAa,EAAOC,SAAU,CAAC,UAAW,sBAAuB,qBAAsB,QAASC,WAAY,uBAClJ,CAAEH,cAAc,EAAOv1C,OAAO,EAAOT,KAAM,UAAWi2C,aAAa,EAAOC,SAAU,EAAC,GAAM,GAAQC,WAAY,oBAClH,CAAEH,aAAc,GAAIv1C,MAAO,GAAIT,KAAM,QAASi2C,aAAa,EAAOC,SAAU,KAAMC,WAAY,eACnG,CAAEH,aAAc,EAAGv1C,MAAO,EAAGT,KAAM,UAAWi2C,aAAa,EAAOC,SAAU,KAAMC,WAAY,MAG3GC,kBAAoBt2C,OAAOgC,KAAKi0C,uBAEhCM,WAAa,GACbn0C,EAAI,EACJqhB,EAAI,EACJ7oB,EAAI,EACJ47C,SAAU,WAKLC,qBAAqB59B,MAAO2G,aAC7B1nB,SACA2I,QAAS,MAER3I,SAAW,EAAGA,SAAW+gB,MAAM5e,OAAQnC,UAAY,EAChD+gB,MAAM/gB,YAAc0nB,UACpB/e,QAAS,UAGVA,eAG6BX,IAApC3F,KAAKqO,SAASkuC,yBACTluC,SAASkuC,kBAAoB,QAC7BluC,SAASkuC,kBAAkBX,cAAgBv9B,KAAKC,MAAMD,KAAKE,UAAUu9B,6BACrEztC,SAASkuC,kBAAkBlG,cAAe,GAEnDuF,cAAgB57C,KAAKqO,SAASkuC,kBAAkBX,cAEhC,UAAZv7C,UAAmC,IAAZs7C,QAAkB,KACrCvvC,IAAM+vC,kBAAkBr8C,WAEvBW,EAAI,EAAGA,EAAI2L,IAAK3L,GAAK,EACtBm7C,cAAcO,kBAAkB17C,IAAI+F,MAAQo1C,cAAcO,kBAAkB17C,IAAIs7C,aAChFH,cAAcO,kBAAkB17C,IAAIu7C,aAAc,KAIgB,iBAAlD,IAAZ37C,QAA0B,YAAc7C,QAAQ6C,cACnDw7C,UAAUx7C,WACXmG,MAAQnG,QAAQw7C,QACZS,qBAAqBH,kBAAmBN,cAAqBl2C,IAAVa,MAAqB,IAErC,YAA/Bo1C,cAAcC,QAAQ91C,MAAuC,kBAAVS,MACnDo1C,cAAcC,QAAQr1C,MAAQA,WAC3B,GAAmC,SAA/Bo1C,cAAcC,QAAQ91C,MAAmBu2C,qBAAqBV,cAAcC,QAAQI,SAAUz1C,OACrGo1C,cAAcC,QAAQr1C,MAAQA,WAC3B,GAAmC,YAA/Bo1C,cAAcC,QAAQ91C,MAAsByD,OAAOgzC,UAAUh2C,OACpEo1C,cAAcC,QAAQr1C,MAAQA,WAC3B,GAAmC,UAA/Bo1C,cAAcC,QAAQ91C,KAAkB,KAE1CkC,EAAI,EAAGA,EAAIzB,MAAM1G,OAAQmI,GAAK,KAC/Bo0C,SAAU,EACc,IAApB71C,MAAMyB,GAAGnI,QAAuC,iBAAhB0G,MAAMyB,GAAG,GACzCm0C,WAAWv8C,KAAKiJ,OAAOtC,MAAMyB,UAC1B,GAAIzB,MAAMyB,GAAGnI,OAAS,EAAG,KACvBwpB,EAAI,EAAGA,EAAI9iB,MAAMyB,GAAGnI,OAAQwpB,GAAK,EACP,iBAAhB9iB,MAAMyB,GAAGqhB,KAChB+yB,SAAU,IAGF,IAAZA,SACAD,WAAWv8C,KAAKiJ,OAAOtC,MAAMyB,GAAG7D,KAAK,OAIjDw3C,cAAcC,QAAQr1C,MAAQsC,OAAOszC,iBAErCR,cAAcC,QAAQr1C,MAAQo1C,cAAcC,QAAQE,aAGxDH,cAAcC,QAAQG,aAAc,SAKK,IAAjDh8C,KAAKqO,SAASkuC,kBAAkBlG,oBAC3BhoC,SAASvL,OAAOzE,UAAU,cAAc,eAErCo+C,MADAC,QAAU,OAETD,SAASb,eAC+B,IAArCA,cAAca,OAAOT,cACa,SAA9BJ,cAAca,OAAO12C,KACrB22C,QAAQ78C,KAAK,IAAM48C,MAAQ,KAAOb,cAAca,OAAOj2C,OAEvDk2C,QAAQ78C,KAAK,IAAM48C,MAAQ,IAAMb,cAAca,OAAOj2C,QAI3C,IAAnBk2C,QAAQ58C,aACHuO,SAAS6O,MAAM,2BAA6Bw/B,QAAQt4C,KAAK,MAAQ,gBAGzEiK,SAASkuC,kBAAkBlG,cAAe,QAG9ChoC,SAASkuC,kBAAkBX,cAAgBA,cACzC57C,OAEZjC,MAAMb,cAuBE0a,cAEH+kC,YAAc,GACdC,gBAAkB,GAClBC,uBAAyB,GAE7BjlC,SAASklC,YAAc,SAAUn0C,SAAUo0C,qBACvCH,gBAAkBG,cAAgB,qCAClCJ,YAAch0C,cACT0F,SAASvL,OAAOzE,UAAU,oBAAoB,cAC1Cs+C,YAEE,KAECK,cAAgB,+GAAiHJ,gBAAkB,qBAGnJK,uBAAyBC,SAASC,mBAJd,yCAKpBC,mBAAqBF,SAASC,mBAAmBH,gBACjDK,cAAgBH,SAASC,mBAAmBR,cAC5CW,gBAAkBJ,SAASC,mBALd,kDAMbI,oBAAsBL,SAASC,mBALd,iBAOjBK,UAAYJ,mBAAmBt9C,OAASu9C,cAAcv9C,OAASw9C,gBAAgBx9C,OAASm9C,uBAAuBn9C,OAASy9C,oBAAoBz9C,OAEhJ+8C,uBAAyB78C,KAAKqO,SAASvH,iBAClCuH,SAAS6O,MAAM,4CAA8CsgC,UAAY,YACzEnvC,SAAS6O,MAAM,eACf7O,SAAS6O,MAAM+/B,uBAAyBG,mBAAqBC,cAAgBC,gBAAkBC,0BAC/FlvC,SAAS6O,MAAM,kBACf7O,SAAS6O,MAAM,eAnBpB2/B,uBAAyB,WAsB5BxuC,SAASvL,OAAOzE,UAAU,cAAc,WACrCw+C,6BACKxuC,SAAS6O,MAAM,aAAe2/B,uBAAyB,WAG7D78C,OAEZjC,MAAMb,cAEEa,MAAOC,YAEV4Z,SAAW7Z,MAAMb,IAEjBugD,MAAQ,CAAC,GA4Gb7lC,SAAS9U,OAAOjD,KAAK,CAAC,UAAW,SAAUZ,OArEnB,SAA2BmI,KAAMR,IAAKE,cAEtDM,KAAKuB,oBAAoB5K,MAAMb,IAAIq8C,SAA6B,eAAlBnyC,KAAKG,SAA2B,SAE1EomC,OAASvmC,KAAKuB,SAAS+kC,QAAQC,OAE/B+P,UADOt2C,KAAKuB,SAASg1C,OAAO9H,OAAO4H,OAEnCG,WAAa,GACR31C,EAAI,EAAGA,EAAIy1C,UAAU59C,OAAQmI,IAClC21C,YAAc90C,OAAOC,aAAa20C,UAAUz1C,QAE5C41C,UAAY/2C,YAChBF,IAAI,MACJA,IAAI,WAAag3C,WAAW99C,QAC5B8G,IAAI,YAAcg3C,WAAW99C,QAC7B8G,IAAI,MAEJA,IAAI,UACJA,IAAIg3C,YACJh3C,IAAI,aACJA,IAAI,cAEAk3C,eAAiBh3C,YACrBF,IAAI,MACJA,IAAI,yBACJA,IAAI,cAAgBQ,KAAKM,UACzBd,IAAI,cAAgBi3C,UAAY,QAChCj3C,IAAI,aAAe7I,MAAMb,IAAI6gD,UAAUC,QAAQ52C,KAAKuB,SAASs1C,OAC7Dr3C,IAAI,UAAYQ,KAAKuB,SAASX,OAC9BpB,IAAI,UAAYQ,KAAKuB,SAASu1C,OAC9Bt3C,IAAI,gBAAkBQ,KAAKuB,SAASw1C,aACpCv3C,IAAI,WAAaQ,KAAKuB,SAASy1C,UAC/Bx3C,IAAI,YAAcQ,KAAKuB,SAAS01C,UAChCz3C,IAAI,cAAgBQ,KAAKuB,SAAS21C,WAClC13C,IAAI,MACJA,IAAI,cAEA23C,eAAiBz3C,YACrBF,IAAI,MACJA,IAAI,eACJA,IAAI,cAAgBQ,KAAKM,UACzBd,IAAI,mBAAqBk3C,eAAiB,QAC1Cl3C,IAAI,MAAQ7I,MAAMb,IAAI6gD,UAAUC,QAAQrQ,SACxC/mC,IAAI,0BACJA,IAAI,YACJA,IAAI,0BACJA,IAAI,kBACJA,IAAI,MACJA,IAAI,iBACJA,IAAI,qBACJA,IAAI,cAAgBQ,KAAKG,SAAW,KACpCX,IAAI,MACJA,IAAI,MACJA,IAAI,UAEJQ,KAAKrF,aAAe+E,YACpBF,IAAI,MACJA,IAAI,eACJA,IAAI,mBACJA,IAAI,cAAgBQ,KAAKM,UACzBd,IAAI,cAAgBQ,KAAKG,UACzBX,IAAI,qBAAuB23C,eAAiB,SAC5C33C,IAAI,MACJA,IAAI,UAEJQ,KAAKC,iBAAkB,GAK3Bm3C,CAAkBv/C,KAAKmI,KAAMnI,KAAK2H,IAAK3H,KAAK6H,cA+ChD8Q,SAAS9U,OAAOjD,KAAK,CAAC,UAAW,SAAUZ,OA5Cb,SAAiCmI,KAAMR,IAAKE,cAElEM,KAAKuB,oBAAoB5K,MAAMb,IAAIq8C,SAA6B,oBAAlBnyC,KAAKG,SAAgC,CAEtEH,KAAKuB,SAAS+kC,QAAQC,eAE/B+P,UADOt2C,KAAKuB,SAAS81C,QAErBb,WAAa,GACR31C,EAAI,EAAGA,EAAIy1C,UAAU59C,OAAQmI,IAClC21C,YAAc90C,OAAOC,aAAa20C,UAAUz1C,QAE5C41C,UAAY/2C,YAChBF,IAAI,MACJA,IAAI,WAAag3C,WAAW99C,QAC5B8G,IAAI,YAAcg3C,WAAW99C,QAC7B8G,IAAI,MACJA,IAAI,UACJA,IAAIg3C,YACJh3C,IAAI,aACJA,IAAI,cACAk3C,eAAiBh3C,gBACrBF,IAAI,MACJA,IAAI,YAAcQ,KAAKuB,SAAS01C,UAChCz3C,IAAI,cAAgBQ,KAAKuB,SAAS21C,WAClC13C,IAAI,UAAYQ,KAAKuB,SAASu1C,OAC9Bt3C,IAAI,yBACJA,IAAI,cAAgBi3C,UAAY,QAChCj3C,IAAI,aACJA,IAAI,aAAe7I,MAAMb,IAAI6gD,UAAUC,QAAQ52C,KAAKuB,SAASs1C,OAC7Dr3C,IAAI,cAAgBQ,KAAKM,UACzBd,IAAI,gBAAkBQ,KAAKuB,SAASw1C,aACpCv3C,IAAI,WAAaQ,KAAKuB,SAASy1C,UAC/Bx3C,IAAI,MACJA,IAAI,UACJQ,KAAKrF,aAAe+E,YACXmB,EAAI,EAAGA,EAAIb,KAAKuB,SAAS+1C,KAAK/Q,OAAO7tC,OAAQmI,IAClDb,KAAKuB,SAAS+1C,KAAK/Q,OAAO1lC,GAAKjE,SAASoD,KAAKuB,SAAS+1C,KAAK/Q,OAAO1lC,IAAM,IAAOb,KAAKuB,SAASg2C,KAAKC,aAEtGh4C,IAAI,0CAA4CQ,KAAKM,SAAW,mBAAqBo2C,eAAjF,iBAA0H12C,KAAKG,SAAW,wCAA0CxJ,MAAMb,IAAI6gD,UAAUC,QAAQ52C,KAAKuB,SAAS+1C,KAAK/Q,QAAU,MACjP/mC,IAAI,UACJQ,KAAKC,iBAAkB,GAK3Bw3C,CAAwB5/C,KAAKmI,KAAMnI,KAAK2H,IAAK3H,KAAK6H,kBAGlDg4C,iBAAmB,SAA0B7/C,UAezC8/C,YAGA70C,IAjBAnC,KAAO9I,KAAK8I,MAAQ,GACpB+H,EAAI7Q,KAAK6Q,EACTC,EAAI9Q,KAAK8Q,EACT1P,QAAUpB,KAAKoB,SAAW,GAC1BqR,MAAQzS,KAAKyS,OAAS,GAEtB5J,UAAY4J,MAAM5J,UAClBtH,cAAgBkR,MAAMlR,cACtB0B,MAAQwP,MAAMxP,MAId8E,KAFW0K,MAAMpQ,eAEX,IACN8O,EAAI,EAEJ4uC,QAAU,GAGVz3C,SAAWrF,MADXgI,IAAM1J,eACgB+G,YAEE,eAAxBrF,MAAMgI,KAAK3C,eACJ,CACHQ,KAAMA,KACN+H,EAAGA,EACHC,EAAGA,EACH1P,QAASA,QACTqR,MAAOA,WAGfstC,QAAUj3C,KAEVmC,IAAkD1J,cACL,mBAAzCqF,OAAO/H,UAAUe,SAASO,KAAK2I,QAC/Bi3C,QAAUj3C,KAAK,IAEdqI,EAAI,EAAGA,EAAI4uC,QAAQl/C,OAAQsQ,GAAK,EAC7BlO,MAAMgI,KAAKvB,SAASlK,eAAe,UACnCsgD,YAAc78C,MAAMgI,KAAKvB,SAASs2C,KAAKC,QAAQC,QAAQH,QAAQ5uC,GAAGvH,WAAW,KAgB5Ek2C,aACGC,QAAQ5uC,GAAGvH,WAAW,GAAK,KAAO3G,MAAMgI,KAAKvB,SAASlK,eAAe,WAMzEuI,KAAOg4C,QAAQ5uC,GAHXpJ,KAAO,OAMfV,OAAS,UACTtC,SAASkG,IAAI/K,MAAM,IAAM,IAAmB,oBAAboI,SAE/BjB,gBA9NOU,aACPjD,IAAM,GACDkE,EAAI,EAAGA,EAAIjB,IAAIlH,OAAQmI,IAC5BlE,KAAO,GAAKiD,IAAI6B,WAAWZ,GAAGpJ,SAAS,WAEpCkF,IAyNMF,CAAMiE,UAAUd,IAAKkD,MACV,eAAb3C,WACPjB,OAnNU,SAAqByB,KAAMX,cAGRg4C,EAF7BzR,OAASvmC,KAAKuB,SAAS+kC,QAAQC,OAAmB0R,KAAO,CAAC,GAAI,IAAK,KAAM,MAAO,QAChFva,GAAK,CAAC,IACD78B,EAAI,EAAGC,EAAIH,KAAKjI,OAAWmI,EAAIC,IAAKD,EAAG,IAC5Cm3C,EAAIh4C,KAAKuB,SAASquC,iBAAiBjvC,KAAKc,WAAWZ,IACnDw1C,MAAM59C,KAAKu/C,IACe,GAAtBzR,OAAO7/B,QAAQsxC,KACfzR,OAAO9tC,KAAKu/C,GACZzR,OAAO9tC,KAAK,CAACmE,SAASoD,KAAKuB,SAASouC,aAAaqI,GAAI,OAEhD,KAALA,SAEOta,GAAG1gC,KAAK,IAEfg7C,EAAIA,EAAEvgD,SAAS,IACfimC,GAAGjlC,KAAKw/C,KAAK,EAAID,EAAEt/C,QAASs/C,UAG7Bta,GAAG1gC,KAAK,IAiMFk7C,CAAYt4C,IAAK9E,MAAMgI,OAEpCwH,MAAMzB,OAAQ,EAEP,CACHlI,KAAMzB,OACNwJ,EAAGA,EACHC,EAAGA,EACH1P,QAASA,QACTqR,MAAOA,QAuCfkG,SAAS9U,OAAOjD,KAAK,CAAC,kBAnCG,SAA4B0/C,WAC7Cx3C,KAAOw3C,MAAMx3C,MAAQ,GACrB+H,EAAIyvC,MAAMzvC,EACVC,EAAIwvC,MAAMxvC,EACV1P,QAAUk/C,MAAMl/C,QAChBqR,MAAQ6tC,MAAM7tC,MAEd8jB,SADOn1B,QAAQ6R,KACL,IACVjT,KAAO,CACP8I,KAAMA,KACN+H,EAAGA,EACHC,EAAGA,EACH1P,QAASA,QACTqR,MAAOA,UAGkC,mBAAzC7L,OAAO/H,UAAUe,SAASO,KAAK2I,MAA4B,KACvDE,EAAI,MACHA,EAAI,EAAGA,EAAIF,KAAKjI,OAAQmI,GAAK,EACkB,mBAA5CpC,OAAO/H,UAAUe,SAASO,KAAK2I,KAAKE,KACb,IAAnBF,KAAKE,GAAGnI,OACR01B,QAAQ31B,KAAK,CAACi/C,iBAAiBj5C,OAAOkgB,OAAO,GAAI9mB,KAAM,CAAE8I,KAAMA,KAAKE,GAAG,MAAOF,KAAMA,KAAKE,GAAG,GAAIF,KAAKE,GAAG,KAK5GutB,QAAQ31B,KAAKi/C,iBAAiBj5C,OAAOkgB,OAAO,GAAI9mB,KAAM,CAAE8I,KAAMA,KAAKE,MAAOF,MAGlFw3C,MAAMx3C,KAAOytB,aAEb+pB,MAAMx3C,KAAO+2C,iBAAiBj5C,OAAOkgB,OAAO,GAAI9mB,KAAM,CAAE8I,KAAMA,QAASA,SAKhFhK,MAAuB,oBAAT0Z,MAAwBA,MAA0B,oBAAXzZ,QAA0BA,QAA4B,oBAAX0Z,QAA0BA,QAAUC,SAAS,cAATA,aAa5HC,cAEH4nC,IAAM,GAQV5nC,SAAS0hC,gBAAkB,SAAUxiC,iBAC1B0oC,IAAI/gD,eAAeqY,WAS9Bc,SAAS6nC,aAAe,SAAU3oC,SAAU4oC,oBACxCF,IAAI1oC,UAAY4oC,YACT1/C,MASX4X,SAAS4hC,eAAiB,SAAU1iC,iBAC5B0oC,IAAI/gD,eAAeqY,UACZ0oC,IAAI1oC,UAER,OAEZ/Y,MAAMb,cAkBEyiD,SAEVA,KAAK5yC,IAAM4yC,KAAK5yC,KAAO4yC,KAAKC,UAExBD,KAAKlzC,MAAQkzC,KAAK5yC,wBAEhBN,KAEH,MAAOmB,QAKNiyC,YAAcF,KAAKE,aAAeF,KAAKG,mBAAqBH,KAAKI,gBAAmB,SAASJ,UAE7FK,UAAY,SAASnjC,eACfhX,OAAO/H,UAAUe,SAASO,KAAKyd,QAAQvL,MAAM,sBAAsB,IAEzE2uC,gBAAkB,gBACd9zC,KAAO,IAEX+zC,SAAW,SAAc/zC,KAAMpG,KAAMwB,eACjC4E,KAAOA,UACP0J,KAAO1J,KAAKrM,YACZiG,KAAOA,UACPwB,SAAWA,UAEf44C,UAAYF,gBAAgBniD,UAC5BsiD,SAAWF,SAASpiD,UACpBuiD,eAAiBV,KAAKU,eACtBC,cAAgB,SAASv6C,WACrBw6C,KAAOvgD,KAAKA,KAAK4hB,KAAO7b,OAE5By6C,cAAgB,8HAGhB/5C,MAAM,KACNg6C,aAAeD,cAAc1gD,OAC7B4gD,SAAWf,KAAK5yC,KAAO4yC,KAAKC,WAAaD,KACzCgB,uBAAyBD,SAAS1zC,gBAClC4zC,uBAAyBF,SAASG,gBAClC9zC,IAAM2zC,SACN9zC,KAAO+yC,KAAK/yC,KACZuiB,KAAOwwB,KAAKxwB,KAEZ7iB,YAAcqzC,KAAKrzC,YACnBnL,WAAaw+C,KAAKx+C,WAElB2/C,OAAS,6CAEZZ,SAASa,KAAOX,SAASW,MAAO,EACzBN,gBACNH,cAAcxiD,UAAU0iD,cAAcC,eAAiBA,aAAe,SAGlEC,SAAS1zC,kBACbD,IAAM4yC,KAAK5yC,IAAM,SAASi0C,SAGtBC,WADAC,SAAW1zC,SAAS2zC,gBAAgB,+BAAgC,YAGvED,SAASxzC,KAAOszC,IACV,WAAYE,WACuB,UAApCA,SAASrvB,SAAStxB,cACrB2gD,SAASJ,OAAS,MAElBG,WAAaD,IAAI1vC,MAAMwvC,QACvBI,SAASJ,OAASG,YAAcA,WAAW,KAGtCC,WAGTn0C,IAAIC,gBAAkB,SAASo0C,UAG3BC,gBADAt7C,KAAOq7C,KAAKr7C,YAGF,OAATA,OACHA,KAAO,4BAEJq7C,gBAAgBlB,UACnBmB,gBAAkB,QAAUt7C,KACN,WAAlBq7C,KAAK75C,SACD85C,gBAAkB,WAAaD,KAAKj1C,KACf,QAAlBi1C,KAAK75C,SACR85C,gBAAkB,IAAMC,mBAAmBF,KAAKj1C,MAClDS,KACEy0C,gBAAkB,WAAaz0C,KAAKw0C,KAAKj1C,MAEzCk1C,gBAAkB,IAAMlE,mBAAmBiE,KAAKj1C,OAE9Cw0C,uBACHA,uBAAuBvhD,KAAKshD,SAAUU,WADvC,GAIRr0C,IAAI8zC,gBAAkB,SAASU,YACK,UAA/BA,WAAW3iC,UAAU,EAAG,IAAkBgiC,wBAC7CA,uBAAuBxhD,KAAKshD,SAAUa,aAGxCpB,UAAUl1C,OAAS,SAASkB,UACvBq1C,GAAKxhD,KAAKmM,QAEVhL,aAAegL,gBAAgBG,aAAeH,gBAAgBhL,YAAa,SAE3E6F,IAAM,GACNy6C,IAAM,IAAItgD,WAAWgL,MACrBlE,EAAI,EACJy5C,QAAUD,IAAI3hD,OAEVmI,EAAIy5C,QAASz5C,IACnBjB,KAAO8B,OAAOC,aAAa04C,IAAIx5C,IAEhCu5C,GAAG3hD,KAAKmH,UACF,GAAwB,SAApBg5C,UAAU7zC,OAAwC,SAApB6zC,UAAU7zC,MAAkB,KAChEk0C,qBAKG,IAAIC,cAAc,wBAJpBqB,GAAK,IAAItB,eACbmB,GAAG3hD,KAAK8hD,GAAGC,mBAAmBz1C,YAKrBA,gBAAgB+zC,SACJ,WAAlB/zC,KAAK5E,UAAyB4nB,KACjCqyB,GAAG3hD,KAAKsvB,KAAKhjB,KAAKA,OACU,QAAlBA,KAAK5E,SACfi6C,GAAG3hD,KAAKyhD,mBAAmBn1C,KAAKA,OACJ,QAAlBA,KAAK5E,UACfi6C,GAAG3hD,KAAKsM,KAAKA,OAGM,iBAATA,OACVA,MAAQ,IAGTq1C,GAAG3hD,KAAKq9C,SAASC,mBAAmBhxC,UAGtCg0C,UAAU3zC,QAAU,SAASzG,aACvB1G,UAAUS,SACdiG,KAAO,MAED,IAAIm6C,SAASlgD,KAAKmM,KAAK/H,KAAK,IAAK2B,KAAM,QAE/Co6C,UAAUthD,SAAW,iBACb,wBAERuhD,SAASjhD,MAAQ,SAASoiC,MAAOK,IAAK77B,UACjC9G,KAAOI,UAAUS,cACjBb,KAAO,IACV8G,KAAO,MAED,IAAIm6C,SACRlgD,KAAKmM,KAAKhN,MAAMoiC,MAAOtiC,KAAO,EAAI2iC,IAAM5hC,KAAKmM,KAAKrM,QAClDiG,KACA/F,KAAKuH,WAGT64C,SAASvhD,SAAW,iBACZ,iBAERuhD,SAASvd,MAAQ,gBACXhtB,KAAO,SACL7V,KAAKmM,MAEN8zC,gBAzJgF,CA0JtFN,MAEFA,KAAKlzC,KAAO,SAASo1C,UAAWxhD,aAC3B0F,KAAO1F,SAAWA,QAAQ0F,MAAc,GACxC+7C,QAAU,IAAIjC,eACdgC,cACE,IAAI55C,EAAI,EAAGmE,IAAMy1C,UAAU/hD,OAAQmI,EAAImE,IAAKnE,IAC5C9G,YAAc0gD,UAAU55C,aAAc9G,WACzC2gD,QAAQ72C,OAAO42C,UAAU55C,GAAGinB,QAG5B4yB,QAAQ72C,OAAO42C,UAAU55C,QAIxBm5C,KAAOU,QAAQt1C,QAAQzG,aACtBq7C,KAAKjiD,OAASiiD,KAAKW,cACvBX,KAAKjiD,MAAQiiD,KAAKW,aAEZX,UAGJY,eAAiBn8C,OAAOm8C,gBAAkB,SAASnlC,eAC/CA,OAAOolC,WAEftC,KAAKlzC,KAAK3O,UAAYkkD,eAAe,IAAIrC,KAAKlzC,OAC7B,oBAATgL,MAAwBA,MAA0B,oBAAXC,QAA0BA,QAAUA,OAAOlV,SAAWkV,YAiBlGxK,OAASA,QAAW,SAASyyC,gBAEZ,IAATA,MAA6C,oBAAd9yC,WAA6B,eAAe/I,KAAK+I,UAAUq1C,iBAIlGC,IAAMxC,KAAKnyC,SAEX40C,QAAU,kBACJzC,KAAK5yC,KAAO4yC,KAAKC,WAAaD,MAEpC0C,UAAYF,IAAIhB,gBAAgB,+BAAgC,KAChEmB,kBAAoB,aAAcD,UAKlCE,UAAY,eAAez+C,KAAK67C,KAAK6C,cAAgB7C,KAAKpyC,OAC1Dk1C,cAAe,eAAe3+C,KAAK+I,UAAUq1C,WAC7CQ,cAAgB,SAASjjD,KACzBkgD,KAAKgD,cAAgBhD,KAAKvyC,aAAY,iBAChC3N,KACJ,IAKFmjD,OAAS,SAASC,MAQnBz1C,YAPc,WACO,iBAATy1C,KACVT,UAAUvB,gBAAgBgC,MAE1BA,KAAKC,WANqB,MAyB3BC,SAAW,SAAS3B,YAGjB,6EAA6Et9C,KAAKs9C,KAAKr7C,MACnF,IAAI0G,KAAK,CAAC3D,OAAOC,aAAa,OAASq4C,MAAO,CAACr7C,KAAMq7C,KAAKr7C,OAE3Dq7C,MAEN4B,UAAY,SAAS5B,KAAMx/B,KAAMqhC,aAC7BA,cACJ7B,KAAO2B,SAAS3B,WAOd8B,WAHAC,UAAYnjD,KAEZm4C,MA3CoB,6BA0CbiJ,KAAKr7C,KAGZq9C,aAAe,YAhCN,SAASD,UAAWE,YAAaC,eAEzCr7C,GADJo7C,YAAc,GAAG5yC,OAAO4yC,cACJvjD,OACbmI,KAAK,KACPs7C,SAAWJ,UAAU,KAAOE,YAAYp7C,OACpB,mBAAbs7C,aAETA,SAASnkD,KAAK+jD,UAAWG,OAASH,WACjC,MAAO1jD,IACRijD,cAAcjjD,MAwBf+jD,CAASL,UAAW,qCAAqC18C,MAAM,UAqCjE08C,UAAUM,WAAaN,UAAUO,KAE7BpB,yBACHY,WAAad,UAAUp1C,gBAAgBo0C,WACvCh0C,YAAW,WAlGH,IAAS8jC,KACdoS,MAkGFjB,UAAU30C,KAAOw1C,WACjBb,UAAUsB,SAAW/hC,KApGLsvB,KAqGVmR,UApGJiB,MAAQ,IAAIM,WAAW,SAC3B1S,KAAK2S,cAAcP,OAoGjBF,eACAR,OAAOM,YACPC,UAAUM,WAAaN,UAAUW,SA5CrB,eACPrB,eAAkBtK,OAASoK,YAAe5C,KAAKoE,WAAY,KAE3DvO,OAAS,IAAIuO,kBACjBvO,OAAOwO,UAAY,eACdlyB,IAAM2wB,cAAgBjN,OAAOlvC,OAASkvC,OAAOlvC,OAAO6C,QAAQ,eAAgB,yBACpEw2C,KAAKryC,KAAKwkB,IAAK,YAChB6tB,KAAKlyC,SAASC,KAAOokB,KAChCA,SAAInsB,EACJw9C,UAAUM,WAAaN,UAAUW,KACjCV,gBAED5N,OAAOyO,cAAc7C,WACrB+B,UAAUM,WAAaN,UAAUO,OAI7BR,aACJA,WAAad,UAAUp1C,gBAAgBo0C,OAEpCjJ,OACHwH,KAAKlyC,SAASC,KAAOw1C,WAERvD,KAAKryC,KAAK41C,WAAY,YAGlCvD,KAAKlyC,SAASC,KAAOw1C,YAGvBC,UAAUM,WAAaN,UAAUW,KACjCV,eACAR,OAAOM,YAkBTgB,IAECC,SAAWnB,UAAUllD,gBAMC,oBAAd+O,WAA6BA,UAAUu3C,iBAC1C,SAAShD,KAAMx/B,KAAMqhC,oBAC3BrhC,KAAOA,MAAQw/B,KAAKx/B,MAAQ,WAEvBqhC,cACJ7B,KAAO2B,SAAS3B,OAEVv0C,UAAUu3C,iBAAiBhD,KAAMx/B,QAI1CuiC,SAASE,MAAQ,aACjBF,SAASV,WAAaU,SAAST,KAAO,EACtCS,SAASG,QAAU,EACnBH,SAASL,KAAO,EAEhBK,SAASxkD,MACTwkD,SAASI,aACTJ,SAASK,WACTL,SAASM,QACTN,SAASO,QACTP,SAAS9Y,QACT8Y,SAASQ,WACR,KA5BW,SAASvD,KAAMx/B,KAAMqhC,oBACxB,IAAID,UAAU5B,KAAMx/B,MAAQw/B,KAAKx/B,MAAQ,WAAYqhC,gBA9HvC,CA6JJ,oBAATxrC,MAAwBA,MACb,oBAAXC,QAA0BA,QACjCA,OAAOlV,kBAghBFizC,UAAUgM,SACbl3C,EAAI,KAGS,KAAbk3C,IAAIl3C,MAAyC,KAAbk3C,IAAIl3C,MAA8B,KAAbk3C,IAAIl3C,MAC5C,KAAbk3C,IAAIl3C,MAAyC,KAAvBk3C,IAAIl3C,KAAK,EAAI,MAA+B,KAAbk3C,IAAIl3C,UACrD,kCAIJlB,MAAQo4C,IAAIl3C,KAAOk3C,IAAIl3C,MAAQ,EAC/BjB,OAASm4C,IAAIl3C,KAAOk3C,IAAIl3C,MAAQ,EAChCq6C,IAAMnD,IAAIl3C,KACVs6C,oBAAsBD,KAAO,EAE7BE,kBAAoB,IADW,EAANF,KAC0B,EACtCnD,IAAIl3C,KACrBk3C,IAAIl3C,SAEAw6C,sBAAwB,KAExBF,sBACFE,sBAAwBx6C,EACxBA,GAAyB,EAApBu6C,uBAGHE,QAAS,EAETzY,OAAS,GAET0Y,MAAQ,EACRC,kBAAoB,KACpBC,SAAW,EACXC,WAAa,cAEZ/7C,MAAQA,WACRC,OAASA,OAEP07C,QAAUz6C,EAAIk3C,IAAI3hD,eACf2hD,IAAIl3C,WACL,UACKk3C,IAAIl3C,WACL,OAEe,KAAdk3C,IAAIl3C,IAES,IAAbk3C,IAAIl3C,EAAE,IAA4B,IAAbk3C,IAAIl3C,EAAE,IAA4B,IAAbk3C,IAAIl3C,EAAE,IACnC,IAAbk3C,IAAIl3C,EAAE,IAA4B,IAAbk3C,IAAIl3C,EAAE,IAA4B,IAAbk3C,IAAIl3C,EAAE,IACnC,IAAbk3C,IAAIl3C,EAAE,IAA4B,IAAbk3C,IAAIl3C,EAAE,IAA4B,IAAbk3C,IAAIl3C,EAAE,IACnC,IAAbk3C,IAAIl3C,EAAE,KAA4B,IAAbk3C,IAAIl3C,EAAE,KAEd,GAAbk3C,IAAIl3C,EAAE,KAA4B,GAAbk3C,IAAIl3C,EAAE,KAA4B,GAAbk3C,IAAIl3C,EAAE,IAClDA,GAAK,GACL66C,WAAa3D,IAAIl3C,KAAOk3C,IAAIl3C,MAAQ,EACpCA,aAEAA,GAAK,KACQ,IAEQ,KADf86C,WAAa5D,IAAIl3C,MACC,MACtBA,GAAK86C,sBAKN,OACc,IAAb5D,IAAIl3C,MAA6B,IAAbk3C,IAAIl3C,EAAE,GAC5B,KAAM,wCACJ+6C,IAAM7D,IAAIl3C,KACd06C,MAAQxD,IAAIl3C,KAAOk3C,IAAIl3C,MAAQ,EAC/B26C,kBAAoBzD,IAAIl3C,KACN,IAAP,EAAN+6C,OAAgBJ,kBAAoB,MACzCC,SAAWG,KAAO,EAAI,EACtB/6C,eAGG,WACU,IAEQ,KADf86C,WAAa5D,IAAIl3C,MACC,MAEtBA,GAAK86C,8BAKD,oCAAsC5D,IAAIl3C,EAAE,GAAG1L,SAAS,eAI/D,OACCiR,EAAI2xC,IAAIl3C,KAAOk3C,IAAIl3C,MAAQ,EAC3BwF,EAAI0xC,IAAIl3C,KAAOk3C,IAAIl3C,MAAQ,EAC3BqK,EAAI6sC,IAAIl3C,KAAOk3C,IAAIl3C,MAAQ,EAC3BsK,EAAI4sC,IAAIl3C,KAAOk3C,IAAIl3C,MAAQ,EAC3Bg7C,IAAM9D,IAAIl3C,KAEVi7C,eAAiBD,KAAO,EAAI,EAG5BE,eAAiBV,sBACjBW,mBAAoB,KALCH,KAAO,EAMR,CAClBG,mBAAoB,EACxBD,eAAiBl7C,EACjBA,GAAwB,GANH,IADW,EAANg7C,KACyB,OASjDI,YAAcp7C,MAElBA,MACa,KACP86C,cACe,KADfA,WAAa5D,IAAIl3C,MACC,MACtBA,GAAK86C,WAGP9Y,OAAO1sC,KAAK,CAACiQ,EAAGA,EAAGC,EAAGA,EAAG1G,MAAOuL,EAAGtL,OAAQuL,EAC9B6wC,kBAAmBA,kBACnBD,eAAgBA,eAChBE,YAAaA,YACbC,YAAar7C,EAAIo7C,YACjBT,kBAAmBA,kBACnBW,aAAcL,eACdP,MAAOA,MACPE,SAAUA,sBAGpB,GACHH,QAAS,qBAIH,wBAA0BvD,IAAIl3C,EAAE,GAAG1L,SAAS,SAKnDinD,UAAY,kBACRvZ,OAAOzsC,aAGXimD,UAAY,kBACRX,iBAGJY,UAAY,SAASC,cACpBA,UAAY,GAAKA,WAAa1Z,OAAOzsC,OACvC,KAAM,mCACDysC,OAAO0Z,iBAGXC,uBAAyB,SAASD,UAAWxR,YAC5CqF,MAAQ95C,KAAKgmD,UAAUC,WACvBE,WAAarM,MAAMzwC,MAAQywC,MAAMxwC,OACjC88C,aAAe,IAAIjlD,WAAWglD,YAClCE,8BACI5E,IAAK3H,MAAM6L,YAAaS,aAAcD,gBACtCV,eAAiB3L,MAAM2L,eAKvBtQ,MAAQ2E,MAAMoL,kBACJ,OAAV/P,QAAgBA,MAAQ,SAKxBmR,WAAcxM,MAAMzwC,MACpBk9C,YAAcl9C,MAAQi9C,WACtBE,MAAcF,WAGdG,MAAwC,GAA9B3M,MAAM/pC,EAAI1G,MAASywC,MAAMhqC,GACnC42C,MAAuD,IAA7C5M,MAAM/pC,EAAI+pC,MAAMxwC,QAAUD,MAAQywC,MAAMhqC,GAClD7D,GAAQw6C,MAERE,WAA2B,EAAdJ,aAIQ,IAArBzM,MAAM+L,aACRc,YAA2C,GAA5BL,WAAaC,aAAmB,WAG7CK,cAAgB,EAEX3+C,EAAI,EAAG4+C,GAAKT,aAAatmD,OAAQmI,EAAI4+C,KAAM5+C,EAAG,KACjD4jB,MAAQu6B,aAAan+C,MAEX,IAAVu+C,QAEFA,MAAQF,YADRr6C,IAAM06C,aAEID,QACRC,WACIJ,YAA2C,GAA5BD,WAAaC,cAAoBK,cAAc,GAElE36C,GAAKw6C,OAASH,WAAaC,cAAgBK,eAAiB,GAC5DA,gBAAkB,IAIlB/6B,QAAUspB,MACZlpC,IAAM,MACD,KACDuJ,EAAIisC,IAAIgE,eAAyB,EAAR55B,OACzBoQ,EAAIwlB,IAAIgE,eAAyB,EAAR55B,MAAY,GACrCgC,EAAI4zB,IAAIgE,eAAyB,EAAR55B,MAAY,GACzC4oB,OAAOxoC,MAAQ4hB,EACf4mB,OAAOxoC,MAAQgwB,EACfwY,OAAOxoC,MAAQuJ,EACfi/B,OAAOxoC,MAAQ,MAEfu6C,aAKD9Q,uBAAyB,SAASuQ,UAAWxR,YAC5CqF,MAAQ95C,KAAKgmD,UAAUC,WACvBE,WAAarM,MAAMzwC,MAAQywC,MAAMxwC,OACjC88C,aAAe,IAAIjlD,WAAWglD,YAClCE,8BACI5E,IAAK3H,MAAM6L,YAAaS,aAAcD,gBACtCV,eAAiB3L,MAAM2L,eAKvBtQ,MAAQ2E,MAAMoL,kBACJ,OAAV/P,QAAgBA,MAAQ,SAKxBmR,WAAcxM,MAAMzwC,MACpBk9C,YAAcl9C,MAAQi9C,WACtBE,MAAcF,WAGdG,MAAwC,GAA9B3M,MAAM/pC,EAAI1G,MAASywC,MAAMhqC,GACnC42C,MAAuD,IAA7C5M,MAAM/pC,EAAI+pC,MAAMxwC,QAAUD,MAAQywC,MAAMhqC,GAClD7D,GAAQw6C,MAERE,WAA2B,EAAdJ,aAIQ,IAArBzM,MAAM+L,aACRc,YAA2C,GAA5BL,WAAaC,aAAmB,WAG7CK,cAAgB,EAEX3+C,EAAI,EAAG4+C,GAAKT,aAAatmD,OAAQmI,EAAI4+C,KAAM5+C,EAAG,KACjD4jB,MAAQu6B,aAAan+C,MAEX,IAAVu+C,QAEFA,MAAQF,YADRr6C,IAAM06C,aAEID,QACRC,WACIJ,YAA2C,GAA5BD,WAAaC,cAAoBK,cAAc,GAElE36C,GAAKw6C,OAASH,WAAaC,cAAgBK,eAAiB,GAC5DA,gBAAkB,IAIlB/6B,QAAUspB,MACZlpC,IAAM,MACD,KACDuJ,EAAIisC,IAAIgE,eAAyB,EAAR55B,OACzBoQ,EAAIwlB,IAAIgE,eAAyB,EAAR55B,MAAY,GACrCgC,EAAI4zB,IAAIgE,eAAyB,EAAR55B,MAAY,GACzC4oB,OAAOxoC,MAAQuJ,EACfi/B,OAAOxoC,MAAQgwB,EACfwY,OAAOxoC,MAAQ4hB,EACf4mB,OAAOxoC,MAAQ,MAEfu6C,iBAKCH,8BAA8BS,YAAav8C,EAAG0C,OAAQ85C,uBACzDC,cAAgBF,YAAYv8C,KAE5B08C,WAAa,GAAKD,cAClBE,SAAWD,WAAa,EACxBE,UAAYD,SAAW,EAEvBE,cAAgBJ,cAAgB,EAGhCK,WAAa,GAAKD,eAAiB,EACnCE,UAAY,EACZC,IAAM,EAENt7C,GAAK,EAELu7C,cAAgBV,YAAYv8C,KAK5Bk9C,WAAa,IAAI74B,WAAW,MAE5B84B,UAAY,OAEH,MAEJJ,UAAY,IACK,IAAlBE,eAEJD,KAAOT,YAAYv8C,MAAQ+8C,UAC3BA,WAAa,EAES,IAAlBE,cACFA,cAAgBV,YAAYv8C,OAE1Bi9C,iBAMFF,UAAYF,cACd,UAEE7G,KAAOgH,IAAMF,aACjBE,MAAQH,cACRE,WAAaF,cAKT7G,OAAS0G,YAYN,GAAI1G,OAAS2G,uBAuBhBS,WAAapH,KAAO4G,UAAY5G,KAAOmH,UAGvCE,aAAe,EACfC,MAAQF,WACLE,MAAQZ,YACbY,MAAQJ,WAAWI,QAAU,IAC3BD,iBAGAnnD,EAAIonD,SAEK57C,GAAK27C,cAAgBD,aAAepH,KAAO,EAAI,GAC/CwG,0BACXrnD,QAAQyd,IAAI,6CAKdlQ,OAAOhB,MAAQxL,MAGXotB,EADJ5hB,IAAM27C,iBAGFD,aAAepH,OACjBtzC,OAAOhB,MAAQxL,GAEjBonD,MAAQF,WACDC,gBACLC,MAAQJ,WAAWI,OACnB56C,SAAS4gB,GAAa,IAARg6B,MACdA,QAAU,EAGM,OAAdH,WAAsBP,UAAY,OACpCM,WAAWN,aAAeO,WAAa,EAAIjnD,EAMvC0mD,WAAaE,UAAU,GAAKD,cAAgB,OAC5CA,cACFC,UAAYA,WAAa,EAAI,IAIjCK,UAAYnH,UA7EV4G,UAAYD,SAAW,EAEvBG,WAAa,IADbD,cAAgBJ,cAAgB,IACG,EAGnCU,UAAY,YA2EZz7C,KAAO86C,eACTrnD,QAAQyd,IAAI,8CAGPlQ,OAr7Ba,oBAAXsK,QAA0BA,OAAOC,QAC1CD,OAAOC,QAAQtK,OAASA,OACI,oBAAXjQ,QAAqC,OAAXA,QAAoC,OAAfA,OAAOqa,KACvEra,OAAO,gBAAgB,kBACdiQ,mBAWDnP,MAAOQ,UACfR,MAAMb,IAAIyN,UACF,eACJm9C,gBAAyC,mBAAhBx7C,aACL,mBAAfnL,WAEL4mD,QAAU,KAAMC,UAAa,eAC1BF,gBACH,OAAO,kBAA8B,WAGjC54B,OAAS,GACgB,mBAAlBA,OAAO+4B,SAChBF,QAAU74B,OAAO+4B,QACnB,MAAOtoD,eAEF,SAAmB6G,cACjBA,iBAAiB8F,aACV,OAAZy7C,SAAoBvhD,iBAAiBuhD,SAZV,GAgB7BG,cACc,OAAZH,QACK,SAAuBI,mBACrB,IAAIJ,QAAQI,WAAY,QAAQtpD,SAAS,WAG3C,SAAuBspD,mBACrBjL,SAASC,mBAAmBgL,cAKrCC,IAAM,MAENC,QAAU,SAAiBhW,SAAUiW,sBACnCjkD,EAAe,MAAXguC,SAAmBxkB,EAAIwkB,WAAa,GACnCpqC,EAAI,EAAGnI,OAASwoD,aAAaxoD,OAAQmI,EAAInI,OAAQmI,IAExD4lB,GAAKA,GADLxpB,GAAKA,GAAkC,IAA7BikD,aAAaz/C,WAAWZ,KAAcmgD,MAClCA,WAERv6B,GAAK,GAAKxpB,KAAO,GAGvBkkD,kBAAoB,SAA2BlW,SAAUmW,oBACvDnkD,EAAe,MAAXguC,SAAmBxkB,EAAIwkB,WAAa,GACnCpqC,EAAI,EAAGnI,OAAS0oD,WAAW1oD,OAAQmI,EAAInI,OAAQmI,IAEtD4lB,GAAKA,GADLxpB,GAAKA,EAAImkD,WAAWvgD,IAAMmgD,MACZA,WAERv6B,GAAK,GAAKxpB,KAAO,GAGvBmT,QAAU,GAEVixC,QAAUjxC,QAAQixC,SAChBC,KAAO,SAAiBrW,eACpBryC,gBAAgB0oD,YACd,IAAIC,UACR,mDAECC,SAASvW,SAAuB,MAAZA,SAAmB,GAAKA,gBACzC,IAAIppC,MACR,qDAECopC,SAAWA,WAAa,GAG3BwW,MAAQH,KAAK5qD,UAAY,GAC7B+qD,MAAMhrD,YAAc6qD,KAEpBA,KAAK39C,OAAgBA,KAGnB,SAAcu9C,mBACRtoD,gBAAgB0oD,YACd,IAAIC,UACR,kDAEgB,MAAhBL,aACF,MAAM,IAAIr/C,MAAM,6CACbopC,SAAWgW,QAAQ,EAAGC,aAAazpD,cATnCf,UAAY+qD,MACV99C,MAWT29C,KAAKI,WAAoBA,SAGvB,SAAkBX,iBACZnoD,gBAAgB0oD,YACd,IAAIC,UACR,kDAEc,MAAdR,WACF,MAAM,IAAIl/C,MAAM,4CACdq/C,aAAeJ,cAAcC,WAAWtpD,iBACvCwzC,SAAWgW,QAAQ,EAAGC,gBAVlBxqD,UAAY+qD,MACdC,UAYLhB,kBACFY,KAAKK,aAAsBA,WAGzB,SAAoB75B,aACdlvB,gBAAgB0oD,YACd,IAAIC,UACR,mDAECX,UAAU94B,QACb,MAAM,IAAIjmB,MAAM,+CACdyV,MAAQ,IAAIvd,WAAW+tB,eACpBlvB,KAAKqyC,SAAWkW,kBAAkB,EAAG7pC,SAVjC5gB,UAAY+qD,MAChBE,aAaXF,MAAMG,OAAS,SAAgBV,iBACT,MAAhBA,aACF,MAAM,IAAIr/C,MAAM,+CAClBq/C,aAAeA,aAAazpD,WACrBmB,KAAKqyC,SAAWgW,QAAQroD,KAAKqyC,SAAUiW,eAGhDO,MAAMI,WAAa,SAAoBd,eACnB,MAAdA,WACF,MAAM,IAAIl/C,MAAM,4CACdq/C,aAAeJ,cAAcC,WAAWtpD,mBACrCmB,KAAKqyC,SAAWgW,QAAQroD,KAAKqyC,SAAUiW,eAG5CR,kBACFe,MAAMK,aAAe,SAAsBh6B,YACpC84B,UAAU94B,QACb,MAAM,IAAIjmB,MAAM,+CACdyV,MAAQ,IAAIvd,WAAW+tB,eACpBlvB,KAAKqyC,SAAWkW,kBAAkBvoD,KAAKqyC,SAAU3zB,SAI5DmqC,MAAM5jB,MAAQ,kBACL,IAAIwjB,QAAQzoD,KAAKqyC,WAGnBqW,MAtFwB,IAgBV39C,KAaI+9C,SAeIC,WA3CzBL,KAYAG,MA4ENrxC,QAAQzM,KAAO,SAAcu9C,iBACP,MAAhBA,aACF,MAAM,IAAIr/C,MAAM,+CACXo/C,QAAQ,EAAGC,aAAazpD,aAGjC2Y,QAAQsxC,SAAW,SAAkBX,eACjB,MAAdA,WACF,MAAM,IAAIl/C,MAAM,4CACdq/C,aAAeJ,cAAcC,WAAWtpD,mBACrCwpD,QAAQ,EAAGC,eAGhBR,kBACFtwC,QAAQuxC,WAAa,SAAoB75B,YAClC84B,UAAU94B,QACb,MAAM,IAAIjmB,MAAM,8CACdyV,MAAQ,IAAIvd,WAAW+tB,eACpBq5B,kBAAkB,EAAG7pC,gBAIzBlH,QAtKejZ,IACrBR,WAu6BGyZ,QAAQ2xC,mBArvBK1H,IAAKp4C,MAAOC,OAAQ8/C,WACjC7+C,EAAI,EAGJ66C,gBAA4Bz/C,KAD5ByjD,WAAkBzjD,IAAVyjD,MAAsB,GAAMA,OACjBC,KAAqB,KAAOD,MAAMC,KACrDC,oBAAmC3jD,IAAlByjD,MAAMpU,QAAwB,KAAOoU,MAAMpU,WAE5D3rC,OAAS,GAAKC,QAAU,GAAKD,MAAQ,OAASC,OAAS,MACzD,KAAM,iCAECigD,6BAA6BvU,aAChCwU,WAAaxU,QAAQl1C,UACrB0pD,WAAa,GAAKA,WAAa,KAAQA,WAAcA,WAAW,EAClE,KAAM,qEACDA,WAIT/H,IAAIl3C,KAAO,GAAMk3C,IAAIl3C,KAAO,GAAMk3C,IAAIl3C,KAAO,GAC7Ck3C,IAAIl3C,KAAO,GAAMk3C,IAAIl3C,KAAO,GAAMk3C,IAAIl3C,KAAO,OAGzCk/C,mBAAqB,EACrBC,WAAa,KACM,OAAnBJ,eAAyB,SACvBK,cAAgBJ,6BAA6BD,gBAC1CK,gBAAkB,KAAKF,sBAC9BE,cAAgB,GAAKF,qBACnBA,wBACuB9jD,IAArByjD,MAAMM,WAA0B,KAClCA,WAAaN,MAAMM,aACDC,cAAe,KAAM,oCAKpB,IAAfD,WACF,KAAM,+CAMZjI,IAAIl3C,KAAe,IAARlB,MAAco4C,IAAIl3C,KAAOlB,OAAS,EAAI,IACjDo4C,IAAIl3C,KAAgB,IAATjB,OAAem4C,IAAIl3C,KAAOjB,QAAU,EAAI,IAEnDm4C,IAAIl3C,MAA2B,OAAnB++C,eAA0B,IAAO,GAClCG,mBACXhI,IAAIl3C,KAAOm/C,WACXjI,IAAIl3C,KAAO,EAGY,OAAnB++C,mBACG,IAAIrhD,EAAI,EAAG4+C,GAAKyC,eAAexpD,OAAQmI,EAAI4+C,KAAM5+C,EAAG,KACnD2hD,IAAMN,eAAerhD,GACzBw5C,IAAIl3C,KAAOq/C,KAAO,GAAK,IACvBnI,IAAIl3C,KAAOq/C,KAAO,EAAI,IACtBnI,IAAIl3C,KAAa,IAANq/C,OAII,OAAfxE,WAAqB,IACnBA,WAAa,GAAKA,WAAa,MACjC,KAAM,sBAER3D,IAAIl3C,KAAO,GAAMk3C,IAAIl3C,KAAO,IAAMk3C,IAAIl3C,KAAO,GAE7Ck3C,IAAIl3C,KAAO,GAAMk3C,IAAIl3C,KAAO,GAAMk3C,IAAIl3C,KAAO,GAAMk3C,IAAIl3C,KAAO,GAC9Dk3C,IAAIl3C,KAAO,GAAMk3C,IAAIl3C,KAAO,GAAMk3C,IAAIl3C,KAAO,GAAMk3C,IAAIl3C,KAAO,GAC9Dk3C,IAAIl3C,KAAO,GAAMk3C,IAAIl3C,KAAO,GAAMk3C,IAAIl3C,KAAO,GAE7Ck3C,IAAIl3C,KAAO,EAAMk3C,IAAIl3C,KAAO,EAC5Bk3C,IAAIl3C,KAAoB,IAAb66C,WAAmB3D,IAAIl3C,KAAO66C,YAAc,EAAI,IAC3D3D,IAAIl3C,KAAO,MAITs/C,OAAQ,OAEPC,SAAW,SAASh6C,EAAGC,EAAG6E,EAAGC,EAAGk1C,eAAgBlxC,UACrC,IAAVgxC,UAAoBt/C,EAAGs/C,OAAQ,GAEnChxC,UAAgBlT,IAATkT,KAAqB,GAAMA,KAI9B/I,EAAI,GAAKC,EAAI,GAAKD,EAAI,OAASC,EAAI,MACrC,KAAM,kBAEJ6E,GAAK,GAAKC,GAAK,GAAKD,EAAI,OAASC,EAAI,MACvC,KAAM,2BAEJk1C,eAAejqD,OAAS8U,EAAIC,EAC9B,KAAM,4CAEJm1C,qBAAsB,EACtBhV,QAAUn8B,KAAKm8B,WACfA,MAAAA,UACFgV,qBAAsB,EACtBhV,QAAUsU,gBAGRtU,MAAAA,QACF,KAAM,wDAEJwU,WAAaD,6BAA6BvU,SAG1CgS,cAAgB,EACbwC,aAAe,KAAKxC,cAC3BwC,WAAa,GAAKxC,kBAEd/B,WAAuBt/C,IAAfkT,KAAKosC,MAAsB,EAAIpsC,KAAKosC,MAe5CE,cAA6Bx/C,IAAlBkT,KAAKssC,SAAyB,EAAItsC,KAAKssC,YAClDA,SAAW,GAAKA,SAAW,EAC7B,KAAM,6BAEJ8E,kBAAmB,EACnB/E,kBAAoB,UACCv/C,IAArBkT,KAAKqxC,aAAkD,OAArBrxC,KAAKqxC,cACzCD,kBAAmB,GACnB/E,kBAAoBrsC,KAAKqxC,aACD,GAAKhF,mBAAqBsE,YAChD,KAAM,+BAGO,IAAbrE,UAAkB8E,kBAA8B,IAAVhF,SAExCxD,IAAIl3C,KAAO,GAAMk3C,IAAIl3C,KAAO,IAC5Bk3C,IAAIl3C,KAAO,EAEXk3C,IAAIl3C,KAAO46C,UAAY,IAA0B,IAArB8E,iBAA4B,EAAI,GAC5DxI,IAAIl3C,KAAe,IAAR06C,MAAcxD,IAAIl3C,KAAO06C,OAAS,EAAI,IACjDxD,IAAIl3C,KAAO26C,kBACXzD,IAAIl3C,KAAO,GAIbk3C,IAAIl3C,KAAO,GACXk3C,IAAIl3C,KAAW,IAAJuF,EAAU2xC,IAAIl3C,KAAOuF,GAAK,EAAI,IACzC2xC,IAAIl3C,KAAW,IAAJwF,EAAU0xC,IAAIl3C,KAAOwF,GAAK,EAAI,IACzC0xC,IAAIl3C,KAAW,IAAJqK,EAAU6sC,IAAIl3C,KAAOqK,GAAK,EAAI,IACzC6sC,IAAIl3C,KAAW,IAAJsK,EAAU4sC,IAAIl3C,KAAOsK,GAAK,EAAI,IAGzC4sC,IAAIl3C,MAA+B,IAAxBy/C,oBAAgC,IAAQhD,cAAc,EAAM,GAG3C,IAAxBgD,wBACG,IAAI/hD,EAAI,EAAG4+C,GAAK7R,QAAQl1C,OAAQmI,EAAI4+C,KAAM5+C,EAAG,KAC5C2hD,IAAM5U,QAAQ/sC,GAClBw5C,IAAIl3C,KAAOq/C,KAAO,GAAK,IACvBnI,IAAIl3C,KAAOq/C,KAAO,EAAI,IACtBnI,IAAIl3C,KAAa,IAANq/C,IAIfr/C,WAekCk3C,IAAKl3C,EAAGy8C,cAAeZ,cAC3D3E,IAAIl3C,KAAOy8C,kBACPmD,aAAe5/C,IAEf08C,WAAa,GAAKD,cAClBK,UAAYJ,WAAa,EACzBC,SAAWD,WAAa,EACxBE,UAAYD,SAAW,EAEvBE,cAAgBJ,cAAgB,EAChCM,UAAY,EAGZC,IAAM,WAED6C,qBAAqBC,qBACrB/C,WAAa+C,gBAClB5I,IAAIl3C,KAAa,IAANg9C,IACXA,MAAQ,EAAGD,WAAa,EACpB/8C,IAAM4/C,aAAe,MACvB1I,IAAI0I,cAAgB,IACpBA,aAAe5/C,cAKZ+/C,UAAUv4C,GACjBw1C,KAAOx1C,GAAKu1C,UACZA,WAAaF,cACbgD,qBAAqB,OAyCnBG,QAAUnE,aAAa,GAAKiB,UAC5BI,WAAa,GAEjB6C,UAAUrD,gBAGL,IAAIh/C,EAAI,EAAG4+C,GAAKT,aAAatmD,OAAQmI,EAAI4+C,KAAM5+C,EAAG,KACjDxH,EAAI2lD,aAAan+C,GAAKo/C,UACtBmD,QAAUD,SAAW,EAAI9pD,EACzBgqD,SAAWhD,WAAW+C,iBAGT7kD,IAAb8kD,SAAwB,KAS1BlD,KAAOgD,SAAWjD,UAClBA,WAAaF,cACNE,WAAa,GAClB7F,IAAIl3C,KAAa,IAANg9C,IACXA,MAAQ,EAAGD,WAAa,EACpB/8C,IAAM4/C,aAAe,MACvB1I,IAAI0I,cAAgB,IACpBA,aAAe5/C,KAID,OAAd48C,WACFmD,UAAUrD,YACVE,UAAYD,SAAW,EACvBE,cAAgBJ,cAAgB,EAChCS,WAAa,KAOTN,WAAc,GAAKC,iBAAkBA,cACzCK,WAAW+C,SAAWrD,aAGxBoD,QAAU9pD,OAEV8pD,QAAUE,gBAIdH,UAAUC,SACVD,UAAUpD,UAGVkD,qBAAqB,GAKjBD,aAAe,IAAM5/C,EACvBk3C,IAAI0I,cAAgB,GAEpB1I,IAAI0I,cAAgB5/C,EAAI4/C,aAAe,EACvC1I,IAAIl3C,KAAO,GAENA,EAzJDmgD,CACIjJ,IAAKl3C,EAAGy8C,cAAgB,EAAI,EAAIA,cAAe+C,sBAGpDnoB,IAAM,kBACK,IAAVioB,QACFpI,IAAIl3C,KAAO,GACXs/C,OAAQ,GAEHt/C,IAikB0BiN,QAAQi+B,UAAYA,UAAa,MAAM7nC,aAwCnEgoC,YAAY+U,aAMhBC,OACAC,QACAC,OACAC,QAeAC,eAvBAC,OAAStsD,KAAKmG,MACdomD,OAAS,IAAIhsD,MAAM,IACnBisD,QAAU,IAAIjsD,MAAM,IACpBksD,QAAU,IAAIlsD,MAAM,IACpBmsD,SAAW,IAAInsD,MAAM,IAMrBosD,QAAU,IAAIpsD,MAAM,OACpBqsD,SAAW,IAAIrsD,MAAM,OACrBssD,gBAAkB,IAAItsD,MAAM,IAC5BusD,GAAK,IAAIvsD,MAAM,IACfwsD,QAAU,GACVC,QAAU,EACVC,QAAU,EAEVC,IAAM,IAAI3sD,MAAM,IAChB4sD,IAAM,IAAI5sD,MAAM,IAChB6sD,IAAM,IAAI7sD,MAAM,IAChB8sD,IAAM,IAAI9sD,MAAM,KAChB+sD,cAAgB,IAAI/sD,MAAM,MAG1BgtD,OAAS,CACV,EAAG,EAAG,EAAG,EAAE,GAAG,GAAG,GAAG,GACpB,EAAG,EAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GACpB,EAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GACpB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GACrB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GACrB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GACrB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GACrB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAGnBC,yBAA2B,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAC5DC,wBAA0B,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,IAClDC,yBAA2B,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,KAC5DC,wBAA0B,CAC5B,EAAK,EAAK,EAAK,EAAK,EAAK,GAAK,EAAK,GACnC,GAAK,GAAK,GAAK,EAAK,GAAK,GAAK,GAAK,EACnC,GAAK,IAAK,GAAK,GAAK,IAAK,IAAK,IAAK,EACnC,GAAK,GAAK,IAAK,IAAK,GAAK,GAAK,IAAK,IACnC,GAAK,GAAK,GAAK,IAAK,IAAK,EAAK,GAAK,GACnC,GAAK,GAAK,GAAK,GAAK,GAAK,GAAK,GAAK,GACnC,GAAK,GAAK,GAAK,GAAK,GAAK,GAAK,GAAK,GACnC,GAAK,GAAK,GAAK,GAAK,GAAK,GAAK,GAAK,GACnC,GAAK,GAAK,GAAK,GAAK,GAAK,GAAK,GAAK,GACnC,GAAK,GAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,KAGHC,2BAA6B,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAC9DC,0BAA4B,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,IACpDC,2BAA6B,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,KAC9DC,0BAA4B,CAC9B,EAAK,EAAK,EAAK,EAAK,GAAK,EAAK,EAAK,GACnC,GAAK,EAAK,GAAK,GAAK,GAAK,EAAK,GAAK,IACnC,GAAK,GAAK,GAAK,IAAK,EAAK,GAAK,GAAK,IACnC,IAAK,IAAK,IAAK,EAAK,GAAK,GAAK,GAAK,IACnC,GAAK,GAAK,IAAK,IAAK,GAAK,GAAK,GAAK,GACnC,IAAK,GAAK,IAAK,GAAK,GAAK,GAAK,GAAK,GACnC,GAAK,GAAK,GAAK,GAAK,GAAK,GAAK,GAAK,GACnC,GAAK,GAAK,GAAK,GAAK,GAAK,GAAK,GAAK,GACnC,GAAK,GAAK,GAAK,GAAK,GAAK,GAAK,GAAK,GACnC,GAAK,GAAK,GAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACnC,IAAK,cA2DGC,kBAAkBC,QAASC,mBAC/BC,UAAY,EACZC,aAAe,EACfC,GAAK,IAAI9tD,MACJuB,EAAI,EAAGA,GAAK,GAAIA,IAAK,KACxB,IAAI6oB,EAAI,EAAGA,GAAKsjC,QAAQnsD,GAAI6oB,IAChC0jC,GAAGH,UAAUE,eAAiB,GAC9BC,GAAGH,UAAUE,eAAe,GAAKD,UACjCE,GAAGH,UAAUE,eAAe,GAAKtsD,EACjCssD,eACAD,YAEDA,WAAW,SAELE,YAiDCC,UAAUC,YAEd1mD,MAAQ0mD,GAAG,GACXC,OAASD,GAAG,GAAG,EACXC,QAAU,GACb3mD,MAAS,GAAK2mD,SACjBxB,SAAY,GAAKC,SAElBuB,WACAvB,QACc,IACE,KAAXD,SACHyB,UAAU,KACVA,UAAU,IAGVA,UAAUzB,SAEXC,QAAQ,EACRD,QAAQ,YAKFyB,UAAU5mD,OAGfklD,QAAQ7rD,KAAK2G,gBAGR6mD,UAAU7mD,OAElB4mD,UAAW5mD,OAAO,EAAG,KACrB4mD,UAAqB,IAAV5mD,gBAkPH8mD,UAAUC,IAAKC,MAAOC,GAAIC,KAAMC,cAGpCr8B,IAFAs8B,IAAMD,KAAK,GACXE,UAAYF,KAAK,KAKjBG,gBArPc3hD,KAAMqhD,WAEpBO,GAAIC,GAAIC,GAAIC,GAAIC,GAAIC,GAAIC,GAAIC,GAG5BrmD,EAoHAsmD,UArHAC,QAAQ,MAIPvmD,EAAE,EAAGA,EAFD,IAESA,EAClB,CACC8lD,GAAK5hD,KAAKqiD,SACVR,GAAK7hD,KAAKqiD,QAAQ,GAClBP,GAAK9hD,KAAKqiD,QAAQ,GAClBN,GAAK/hD,KAAKqiD,QAAQ,GAClBL,GAAKhiD,KAAKqiD,QAAQ,GAClBJ,GAAKjiD,KAAKqiD,QAAQ,GAClBH,GAAKliD,KAAKqiD,QAAQ,OAGdC,KAAOV,IAFXO,GAAKniD,KAAKqiD,QAAQ,IAGdE,KAAOX,GAAKO,GACZK,KAAOX,GAAKK,GACZO,KAAOZ,GAAKK,GACZQ,KAAOZ,GAAKG,GACZU,KAAOb,GAAKG,GACZW,KAAOb,GAAKC,GACZa,KAAOd,GAAKC,GAGZc,MAAQR,KAAOM,KACfG,MAAQT,KAAOM,KACfI,MAAQR,KAAOE,KACfO,MAAQT,KAAOE,KAEnB1iD,KAAKqiD,SAAWS,MAAQE,MACxBhjD,KAAKqiD,QAAQ,GAAKS,MAAQE,UAEtBE,GAAuB,YAAjBD,MAAQF,OAClB/iD,KAAKqiD,QAAQ,GAAKU,MAAQG,GAC1BljD,KAAKqiD,QAAQ,GAAKU,MAAQG,OAQtBC,GAAuB,aAL3BL,MAAQD,KAAOF,OAEfM,MAAQR,KAAOF,OAIXa,GAAK,SAAcN,MAAQK,GAC3BE,GAAK,YAAcJ,MAAQE,GAC3BG,GAAa,YAPjBN,MAAQL,KAAOF,MASXc,IAAMhB,KAAOe,GACbE,IAAMjB,KAAOe,GAEjBtjD,KAAKqiD,QAAQ,GAAKmB,IAAMJ,GACxBpjD,KAAKqiD,QAAQ,GAAKmB,IAAMJ,GACxBpjD,KAAKqiD,QAAQ,GAAKkB,IAAMF,GACxBrjD,KAAKqiD,QAAQ,GAAKkB,IAAMF,GAExBhB,SAAW,MAIZA,QAAU,EACLvmD,EAAE,EAAGA,EA3DD,IA2DSA,EAClB,CACC8lD,GAAK5hD,KAAKqiD,SACVR,GAAK7hD,KAAKqiD,QAAU,GACpBP,GAAK9hD,KAAKqiD,QAAU,IACpBN,GAAK/hD,KAAKqiD,QAAU,IACpBL,GAAKhiD,KAAKqiD,QAAU,IACpBJ,GAAKjiD,KAAKqiD,QAAU,IACpBH,GAAKliD,KAAKqiD,QAAU,QAGhBoB,OAAS7B,IAFbO,GAAKniD,KAAKqiD,QAAU,KAGhBqB,OAAS9B,GAAKO,GACdwB,OAAS9B,GAAKK,GACd0B,OAAS/B,GAAKK,GACd2B,OAAS/B,GAAKG,GACd6B,OAAShC,GAAKG,GACd8B,OAAShC,GAAKC,GACdgC,OAASjC,GAAKC,GAGdiC,QAAUR,OAASM,OACnBG,QAAUT,OAASM,OACnBI,QAAUR,OAASE,OACnBO,QAAUT,OAASE,OAEvB7jD,KAAKqiD,SAAW4B,QAAUE,QAC1BnkD,KAAKqiD,QAAQ,IAAM4B,QAAUE,YAEzBE,KAA6B,YAArBD,QAAUF,SACtBlkD,KAAKqiD,QAAQ,IAAM6B,QAAUG,KAC7BrkD,KAAKqiD,QAAQ,IAAM6B,QAAUG,SAQzBC,KAA6B,aALjCL,QAAUD,OAASF,SAEnBM,QAAUR,OAASF,SAIfa,KAAO,SAAcN,QAAUK,KAC/BE,KAAO,YAAcJ,QAAUE,KAC/BG,KAAiB,YAPrBN,QAAUL,OAASF,QASfc,MAAQhB,OAASe,KACjBE,MAAQjB,OAASe,KAErBzkD,KAAKqiD,QAAQ,IAAMsC,MAAQJ,KAC3BvkD,KAAKqiD,QAAQ,IAAMsC,MAAQJ,KAC3BvkD,KAAKqiD,QAAS,GAAKqC,MAAQF,KAC3BxkD,KAAKqiD,QAAQ,IAAMqC,MAAQF,KAE3BnC,cAKIvmD,EAAE,EAAGA,EAnHA,KAmHSA,EAGlBsmD,UAAYpiD,KAAKlE,GAAGulD,MAAMvlD,GAC1BujD,gBAAgBvjD,GAAMsmD,UAAY,EAASA,UAAY,GAAK,EAAOA,UAAY,GAAK,SAI9E/C,gBAmHM+C,CAAUhB,IAAKC,OAEnBlkC,EAAE,EAAEA,EAHH,KAGWA,EACpBmiC,GAAGS,OAAO5iC,IAAIwkC,OAAOxkC,OAElBynC,KAAOtF,GAAG,GAAKgC,GAAIA,GAAKhC,GAAG,GAErB,GAANsF,KACH9D,UAAUS,KAAK,KAGfT,UAAUS,KAAKnC,SADfj6B,IAAM,MAAMy/B,QAEZ9D,UAAU3B,QAAQh6B,eAGf0/B,QAAU,GACNA,QAAQ,GAAkB,GAAbvF,GAAGuF,SAAcA,cACtB,GAAXA,eACJ/D,UAAUW,KACHH,WAGJwD,IADAhpD,EAAI,EAEAA,GAAK+oD,SAAU,SAClBE,SAAWjpD,EACA,GAAPwjD,GAAGxjD,IAAWA,GAAG+oD,UAAY/oD,OACjCkpD,SAAWlpD,EAAEipD,YACZC,UA9BI,GA8Bc,CACtBF,IAAME,UAAU,MACX,IAAIC,SAAS,EAAGA,UAAYH,MAAOG,SACvCnE,UAAUY,WACXsD,UAAoB,GAErB7/B,IAAM,MAAMm6B,GAAGxjD,GACfglD,UAAUU,MAAMwD,UAAU,GAAG5F,SAASj6B,OACtC27B,UAAU3B,QAAQh6B,MAClBrpB,WAtCS,IAwCL+oD,SACJ/D,UAAUW,KAEJH,YA6HA4D,WAAW1G,YACfA,SAAW,IACdA,QAAU,GAEPA,QAAU,MACbA,QAAU,KAGRK,gBAAkBL,mBA/jBG2G,YACnBC,IAAM,CACT,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAC5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAC5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAC5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAC5B,GAAI,GAAI,GAAI,GAAI,GAAG,IAAI,IAAK,GAC5B,GAAI,GAAI,GAAI,GAAI,GAAG,IAAI,IAAK,GAC5B,GAAI,GAAI,GAAI,GAAG,IAAI,IAAI,IAAI,IAC3B,GAAI,GAAI,GAAI,GAAG,IAAI,IAAI,IAAK,IAGpBtpD,EAAI,EAAGA,EAAI,GAAIA,IAAK,KACxBm3C,EAAI6L,QAAQsG,IAAItpD,GAAGqpD,GAAG,IAAI,KAC1BlS,EAAI,EACPA,EAAI,EACMA,EAAI,MACdA,EAAI,KAEL8L,OAAOgB,OAAOjkD,IAAMm3C,UAEjBoS,KAAO,CACV,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAC5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAC5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAC5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAC5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAC5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAC5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAC5B,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,IAEpBloC,EAAI,EAAGA,EAAI,GAAIA,IAAK,KACxBmoC,EAAIxG,QAAQuG,KAAKloC,GAAGgoC,GAAG,IAAI,KAC3BG,EAAI,EACPA,EAAI,EACMA,EAAI,MACdA,EAAI,KAELtG,QAAQe,OAAO5iC,IAAMmoC,UAElBC,KAAO,CACV,EAAK,YAAa,YAAa,YAC/B,EAAK,WAAa,SAAa,YAE5BjxD,EAAI,EACCkxD,IAAM,EAAGA,IAAM,EAAGA,UAErB,IAAIC,IAAM,EAAGA,IAAM,EAAGA,MAE1BxG,QAAQ3qD,GAAO,GAAOyqD,OAAQgB,OAAOzrD,IAAMixD,KAAKC,KAAOD,KAAKE,KAAO,GACnEvG,SAAS5qD,GAAM,GAAO0qD,QAAQe,OAAOzrD,IAAMixD,KAAKC,KAAOD,KAAKE,KAAO,GACnEnxD,KAqhBHoxD,CANIlH,QAAU,GACRhsD,KAAKmG,MAAM,IAAO6lD,SAElBhsD,KAAKmG,MAAM,IAAc,EAAR6lD,UAIvBK,eAAiBL,cArIZ9U,OAAS,SAASntB,MAAMiiC,UAEX,IAAI/kD,MAAOksD,UAEzBnH,SAAS0G,WAAW1G,SAGvBe,QAAU,IAAIxsD,MACdysD,QAAQ,EACRC,QAAQ,EAGRyB,UAAU,OA7KVA,UAAU,OACVA,UAAU,IACVD,UAAU,IACVA,UAAU,IACVA,UAAU,IACVA,UAAU,IACVA,UAAU,GACVA,UAAU,GACVA,UAAU,GACVA,UAAU,GACVC,UAAU,GACVA,UAAU,GACVD,UAAU,GACVA,UAAU,cAwBVC,UAAU,OACVA,UAAU,KACVD,UAAU,OACL,IAAInlD,EAAE,EAAGA,EAAE,GAAIA,IACnBmlD,UAAUlC,OAAOjjD,IAElBmlD,UAAU,OACL,IAAI9jC,EAAE,EAAGA,EAAE,GAAIA,IACnB8jC,UAAUjC,QAAQ7hC,IAkInByoC,YA/JkB1oD,MAAOC,QAEzB+jD,UAAU,OACVA,UAAU,IACVD,UAAU,GACVC,UAAU/jD,QACV+jD,UAAUhkD,OACV+jD,UAAU,GACVA,UAAU,GACVA,UAAU,IACVA,UAAU,GACVA,UAAU,GACVA,UAAU,IACVA,UAAU,GACVA,UAAU,GACVA,UAAU,IACVA,UAAU,GAgJV4E,CAAUtpC,MAAMrf,MAAMqf,MAAMpf,mBA7H5B+jD,UAAU,OACVA,UAAU,KAEVD,UAAU,OACL,IAAInlD,EAAE,EAAGA,EAAE,GAAIA,IACnBmlD,UAAUjB,yBAAyBlkD,EAAE,QAEjC,IAAIqhB,EAAE,EAAGA,GAAG,GAAIA,IACpB8jC,UAAUhB,wBAAwB9iC,IAGnC8jC,UAAU,QACL,IAAI3sD,EAAE,EAAGA,EAAE,GAAIA,IACnB2sD,UAAUf,yBAAyB5rD,EAAE,QAEjC,IAAIyH,EAAE,EAAGA,GAAG,IAAKA,IACrBklD,UAAUd,wBAAwBpkD,IAGnCklD,UAAU,OACL,IAAIr/C,EAAE,EAAGA,EAAE,GAAIA,IACnBq/C,UAAUb,2BAA2Bx+C,EAAE,QAEnC,IAAIlE,EAAE,EAAGA,GAAG,GAAIA,IACpBujD,UAAUZ,0BAA0B3iD,IAGrCujD,UAAU,QACL,IAAIvhD,EAAE,EAAGA,EAAE,GAAIA,IACnBuhD,UAAUX,2BAA2B5gD,EAAE,QAEnC,IAAItB,EAAE,EAAGA,GAAG,IAAKA,IACrB6iD,UAAUV,0BAA0BniD,IA8FrC0nD,GAxFA5E,UAAU,OACVA,UAAU,IACVD,UAAU,GACVA,UAAU,GACVA,UAAU,GACVA,UAAU,GACVA,UAAU,IACVA,UAAU,GACVA,UAAU,IACVA,UAAU,GACVA,UAAU,IACVA,UAAU,OAkFN8E,IAAI,EACJC,IAAI,EACJC,IAAI,EAERzG,QAAQ,EACRC,QAAQ,OAGH/V,OAAOwc,YAAc,mBAQtBviD,EACA0F,EAAGymB,EAAGpO,EACN0T,MAAMh3B,EAAGqnD,IAAID,IAAIrgC,IARjBlI,UAAYV,MAAMvc,KAClB9C,MAAQqf,MAAMrf,MACdC,OAASof,MAAMpf,OAEfgpD,UAAkB,EAANjpD,MAET0G,EAAI,EAGLA,EAAIzG,QAAO,KAChBwG,EAAI,EACEA,EAAIwiD,WAAU,KAEpB/nD,EADAg3B,MAAQ+wB,UAAYviD,EAAID,EAExB8hD,KAAO,EACPD,IAAM,EAEFrgC,IAAI,EAAGA,IAAM,GAAIA,MAGpB/mB,EAAIg3B,OAFJowB,IAAMrgC,KAAO,GAEOghC,WADpBV,IAAoB,GAAN,EAANtgC,MAGLvhB,EAAE4hD,KAAOroD,SACXiB,GAAK+nD,WAAWviD,EAAE,EAAE4hD,IAAIroD,SAGtBwG,EAAE8hD,KAAOU,YACX/nD,GAAMuF,EAAE8hD,IAAOU,UAAW,GAG3B98C,EAAI4T,UAAW7e,KACf0xB,EAAI7S,UAAW7e,KACfsjB,EAAIzE,UAAW7e,KAUfshD,IAAIv6B,MAAS26B,cAAcz2C,GAAiBy2C,cAAehwB,EAAK,KAAM,GAAKgwB,cAAep+B,EAAK,KAAM,IAAO,IAAI,IAChHi+B,IAAIx6B,MAAS26B,cAAez2C,EAAK,KAAM,GAAKy2C,cAAehwB,EAAI,MAAO,GAAKgwB,cAAep+B,EAAI,MAAO,IAAO,IAAI,IAChHk+B,IAAIz6B,MAAS26B,cAAez2C,EAAI,MAAO,GAAKy2C,cAAehwB,EAAI,MAAO,GAAKgwB,cAAep+B,EAAI,MAAO,IAAO,IAAI,IAIjHqkC,IAAM5E,UAAUzB,IAAKT,QAAS8G,IAAKtH,OAAQE,QAC3CqH,IAAM7E,UAAUxB,IAAKT,SAAU8G,IAAKtH,QAASE,SAC7CqH,IAAM9E,UAAUvB,IAAKV,SAAU+G,IAAKvH,QAASE,SAC7Cj7C,GAAG,GAEHC,GAAG,KAOC67C,SAAW,EAAI,KACf2G,SAAW,GACfA,SAAS,GAAK3G,QAAQ,EACtB2G,SAAS,IAAM,GAAI3G,QAAQ,GAAI,EAC/BqB,UAAUsF,iBAGXlF,UAAU,OAEA,IAAIlsD,WAAWuqD,sBAsCT,IAAI9lD,MAAOksD,UACxBnH,UAASA,QAAU,uBAjJlB6H,KAAO1pD,OAAOC,aACVd,EAAE,EAAGA,EAAI,IAAKA,IACrB+jD,IAAI/jD,GAAKuqD,KAAKvqD,GAiJhBwqD,GAtgBC7H,OAAS+B,kBAAkBR,yBAAyBC,yBACpDvB,QAAU8B,kBAAkBJ,2BAA2BC,2BACvD1B,OAAS6B,kBAAkBN,yBAAyBC,yBACpDvB,QAAU4B,kBAAkBF,2BAA2BC,8CAKnDgG,QAAU,EACVC,QAAU,EACLC,IAAM,EAAGA,KAAO,GAAIA,MAAO,KAE9B,IAAIC,GAAKH,QAASG,GAAGF,QAASE,KAClCtH,SAAS,MAAMsH,IAAMD,IACrBtH,QAAQ,MAAMuH,IAAM,GACpBvH,QAAQ,MAAMuH,IAAI,GAAKD,IACvBtH,QAAQ,MAAMuH,IAAI,GAAKA,OAGnB,IAAIC,QAASH,QAAQ,GAAIG,QAAQJ,QAASI,QAC9CvH,SAAS,MAAMuH,OAASF,IACxBtH,QAAQ,MAAMwH,OAAS,GACvBxH,QAAQ,MAAMwH,OAAO,GAAKF,IAC1BtH,QAAQ,MAAMwH,OAAO,GAAKH,QAAQ,EAAEG,MAErCJ,UAAY,EACZC,UAAY,GA8edI,kBAzeK,IAAI9qD,EAAI,EAAGA,EAAI,IAAIA,IACtBgkD,cAAchkD,GAAa,MAAQA,EACnCgkD,cAAehkD,EAAG,KAAM,GAAO,MAAQA,EACvCgkD,cAAehkD,EAAG,KAAM,GAAQ,KAAOA,EAAI,MAC3CgkD,cAAehkD,EAAG,KAAM,IAAO,MAAQA,EACvCgkD,cAAehkD,EAAE,MAAO,IAAO,MAAQA,EACvCgkD,cAAehkD,EAAE,MAAO,GAAO,MAAQA,EAAI,QAC3CgkD,cAAehkD,EAAE,MAAO,IAAO,MAAQA,EACvCgkD,cAAehkD,EAAE,MAAO,IAAQ,KAAOA,EAkezC+qD,GAEA3B,WAAW1G,UACI,IAAI/kD,MAAOksD,UAI3BplB,OAKKn1B,OAAOC,QAAUo+B,YAAe,MAAMhoC,aASnCooC,WAAW9mB,OAAO+jC,uBACpB3hC,IAAM,OACNpC,OAASA,YACTgkC,MAAQ,IAAIC,SAASjkC,OAAOA,aAC5B+jC,gBAAkBA,mBAClBG,WAAY,OACZC,KAAOvqD,OAAOC,aAAa/I,KAAKkvB,OAAO,IAAMpmB,OAAOC,aAAa/I,KAAKkvB,OAAO,SAC7EoC,KAAO,GACoD,IAA5D,CAAC,KAAK,KAAM,KAAM,KAAM,KAAM,MAAMxjB,QAAQ9N,KAAKqzD,MAAc,MAAM,IAAIpqD,MAAM,yBAC9EqqD,mBACAC,WAGPvd,WAAWl4C,UAAUw1D,YAAc,mBAC5BE,SAAWxzD,KAAKkzD,MAAMO,UAAUzzD,KAAKsxB,KAAK,QAC1CA,KAAO,OACPoiC,SAAW1zD,KAAKkzD,MAAMO,UAAUzzD,KAAKsxB,KAAK,QAC1CA,KAAO,OACPxlB,OAAS9L,KAAKkzD,MAAMO,UAAUzzD,KAAKsxB,KAAK,QACxCA,KAAO,OACPqiC,WAAa3zD,KAAKkzD,MAAMO,UAAUzzD,KAAKsxB,KAAK,QAC5CA,KAAO,OACPjoB,MAAQrJ,KAAKkzD,MAAMO,UAAUzzD,KAAKsxB,KAAK,QACvCA,KAAO,OACPhoB,OAAStJ,KAAKkzD,MAAMU,SAAS5zD,KAAKsxB,KAAK,QAAaA,KAAO,OAC3DuiC,OAAS7zD,KAAKkzD,MAAMY,UAAU9zD,KAAKsxB,KAAK,QACxCA,KAAO,OACPyiC,MAAQ/zD,KAAKkzD,MAAMY,UAAU9zD,KAAKsxB,KAAK,QACvCA,KAAO,OACPhxB,SAAWN,KAAKkzD,MAAMO,UAAUzzD,KAAKsxB,KAAK,QAC1CA,KAAO,OACP0iC,QAAUh0D,KAAKkzD,MAAMO,UAAUzzD,KAAKsxB,KAAK,QACzCA,KAAO,OACP2iC,GAAKj0D,KAAKkzD,MAAMO,UAAUzzD,KAAKsxB,KAAK,QACpCA,KAAO,OACP4iC,GAAKl0D,KAAKkzD,MAAMO,UAAUzzD,KAAKsxB,KAAK,QACpCA,KAAO,OACP8iB,OAASp0C,KAAKkzD,MAAMO,UAAUzzD,KAAKsxB,KAAK,QACxCA,KAAO,OACP6iC,gBAAkBn0D,KAAKkzD,MAAMO,UAAUzzD,KAAKsxB,KAAK,QACjDA,KAAO,EAEM,KAAftxB,KAAK+zD,OAAgB/zD,KAAKizD,qBACtBc,MAAQ,IAEX/zD,KAAK+zD,MAAQ,GAAI,KACf3nD,IAAsB,IAAhBpM,KAAKo0C,OAAe,GAAKp0C,KAAK+zD,MAAQ/zD,KAAKo0C,YAChDY,QAAU,IAAI91C,MAAMkN,SACpB,IAAInE,EAAI,EAAGA,EAAImE,IAAKnE,IAAK,KACxBmsD,KAAOp0D,KAAKkzD,MAAMmB,SAASr0D,KAAKsxB,OAAO,GAAgBgjC,MAAQt0D,KAAKkzD,MAAMmB,SAASr0D,KAAKsxB,OAAO,GAAgBijC,IAAMv0D,KAAKkzD,MAAMmB,SAASr0D,KAAKsxB,OAAO,GAAgBkjC,KAAOx0D,KAAKkzD,MAAMmB,SAASr0D,KAAKsxB,OAAO,QAAiB0jB,QAAQ/sC,GAAK,CAC5OssD,IAAKA,IACLD,MAAOA,MACPF,KAAMA,KACNI,KAAMA,OAITx0D,KAAKsJ,OAAS,SACVA,SAAW,OACX8pD,WAAY,IAKrBpd,WAAWl4C,UAAUy1D,SAAW,gBACzBjiC,IAAMtxB,KAAK8L,eAEV2oD,KAAO,MAAQz0D,KAAK+zD,MACpB3nD,IAAMpM,KAAKqJ,MAAQrJ,KAAKsJ,OAAS,OAChC6C,KAAO,IAAIhL,WAAWiL,UAEtBqoD,QACL,MAAO7mD,GACPlO,QAAQyd,IAAI,oBAAsBvP,KAKtCooC,WAAWl4C,UAAU42D,KAAO,eACtBC,KAAOh2D,KAAK6wB,KAAKxvB,KAAKqJ,MAAQ,GAC9BurD,KAAOD,KAAK,EACZ5kD,EAAI/P,KAAKsJ,QAAU,EAAItJ,KAAKsJ,OAAS,GAAKtJ,KAAKsJ,WAC1CyG,EAAI/P,KAAKsJ,OAAS,EAAGyG,GAAK,EAAGA,IAAK,SACrC0D,KAAOzT,KAAKozD,UAAYrjD,EAAI/P,KAAKsJ,OAAS,EAAIyG,EACzCD,EAAI,EAAGA,EAAI6kD,KAAM7kD,YACpB+d,EAAI7tB,KAAKkzD,MAAMmB,SAASr0D,KAAKsxB,OAAO,GAAgB7jB,SAAWgG,KAAOzT,KAAKqJ,MAAQ,EAAM,EAAFyG,EAAI,EACtF7H,EAAI,EAAGA,EAAI,GACb,EAAF6H,EAAI7H,EAAEjI,KAAKqJ,MADOpB,IAAK,KAEpB2hD,IAAM5pD,KAAKg1C,QAAUnnB,GAAI,EAAE5lB,EAAI,QAC9BkE,KAAKsB,SAAW,EAAFxF,GAAO2hD,IAAIwK,UACzBjoD,KAAKsB,SAAW,EAAFxF,EAAM,GAAK2hD,IAAI0K,WAC7BnoD,KAAKsB,SAAW,EAAFxF,EAAM,GAAK2hD,IAAI2K,SAC7BpoD,KAAKsB,SAAW,EAAFxF,EAAM,GAAK,IAOxB,GAAR2sD,YACGtjC,KAAM,EAAIsjC,QAKrB5e,WAAWl4C,UAAU+2D,KAAO,mBACtBF,KAAOh2D,KAAK6wB,KAAKxvB,KAAKqJ,MAAM,GAC5BurD,KAAOD,KAAK,EACP5kD,EAAI/P,KAAKsJ,OAAS,EAAGyG,GAAK,EAAGA,IAAK,SACrC0D,KAAOzT,KAAKozD,UAAYrjD,EAAI/P,KAAKsJ,OAAS,EAAIyG,EACzCD,EAAI,EAAGA,EAAI6kD,KAAM7kD,IAAK,KACzB+d,EAAI7tB,KAAKkzD,MAAMmB,SAASr0D,KAAKsxB,OAAO,GAAgB7jB,SAAWgG,KAAOzT,KAAKqJ,MAAQ,EAAM,EAAFyG,EAAI,EAE3FglD,OAASjnC,GAAG,EACZknC,MAAU,GAAFlnC,EAER+7B,IAAM5pD,KAAKg1C,QAAQ8f,gBAClB3oD,KAAKsB,UAAYm8C,IAAIwK,UACrBjoD,KAAKsB,SAAW,GAAKm8C,IAAI0K,WACzBnoD,KAAKsB,SAAW,GAAKm8C,IAAI2K,SACzBpoD,KAAKsB,SAAW,GAAK,IAErB,EAAFqC,EAAI,GAAG9P,KAAKqJ,MAAM,MAErBugD,IAAM5pD,KAAKg1C,QAAQ+f,YACd5oD,KAAKsB,SAAS,GAAKm8C,IAAIwK,UACvBjoD,KAAKsB,SAAS,EAAI,GAAKm8C,IAAI0K,WAC3BnoD,KAAKsB,SAAS,EAAI,GAAKm8C,IAAI2K,SAC3BpoD,KAAKsB,SAAS,EAAI,GAAK,IAGlB,GAARmnD,YACGtjC,KAAM,EAAIsjC,QAMrB5e,WAAWl4C,UAAUk3D,KAAO,mBACtBJ,KAAO50D,KAAKqJ,MAAM,EACb0G,EAAI/P,KAAKsJ,OAAS,EAAGyG,GAAK,EAAGA,IAAK,SACrC0D,KAAOzT,KAAKozD,UAAYrjD,EAAI/P,KAAKsJ,OAAS,EAAIyG,EACzCD,EAAI,EAAGA,EAAI9P,KAAKqJ,MAAOyG,IAAK,KAC/B+d,EAAI7tB,KAAKkzD,MAAMmB,SAASr0D,KAAKsxB,OAAO,GAAgB7jB,SAAWgG,KAAOzT,KAAKqJ,MAAQ,EAAM,EAAFyG,KACxF+d,EAAI7tB,KAAKg1C,QAAQl1C,OAAQ,KACtB8pD,IAAM5pD,KAAKg1C,QAAQnnB,QAClB1hB,KAAKsB,UAAYm8C,IAAI2K,SACrBpoD,KAAKsB,SAAW,GAAKm8C,IAAI0K,WACzBnoD,KAAKsB,SAAW,GAAKm8C,IAAIwK,UACzBjoD,KAAKsB,SAAW,GAAK,cAErBtB,KAAKsB,UAAY,SACjBtB,KAAKsB,SAAW,GAAK,SACrBtB,KAAKsB,SAAW,GAAK,SACrBtB,KAAKsB,SAAW,GAAK,IAGlB,GAARmnD,YACGtjC,KAAM,EAAIsjC,QAKrB5e,WAAWl4C,UAAUm3D,MAAQ,mBACvBC,MAAOl1D,KAAKqJ,MAAQ,EACU8rD,KAArBnxD,SAAS,QAAS,GACtB+L,EAAI/P,KAAKsJ,OAAS,EAAGyG,GAAK,EAAGA,IAAK,SACrC0D,KAAOzT,KAAKozD,UAAYrjD,EAAI/P,KAAKsJ,OAAS,EAAIyG,EACzCD,EAAI,EAAGA,EAAI9P,KAAKqJ,MAAOyG,IAAK,KAE/BslD,EAAIp1D,KAAKkzD,MAAMY,UAAU9zD,KAAKsxB,KAAK,QAClCA,KAAK,MACN8iC,MAAQgB,EAAID,MAAQA,KAAO,IAAM,EACjCb,OAASc,GAAK,EAAID,MAASA,KAAO,IAAM,EACxCZ,KAAOa,GAAK,GAAKD,MAAQA,KAAO,IAAM,EACtCxyB,MAASyyB,GAAG,GAAI,IAAK,EAErB3nD,SAAWgG,KAAOzT,KAAKqJ,MAAQ,EAAQ,EAAJyG,OAClC3D,KAAKsB,UAAY8mD,SACjBpoD,KAAKsB,SAAW,GAAK6mD,WACrBnoD,KAAKsB,SAAW,GAAK2mD,UACrBjoD,KAAKsB,SAAW,GAAKk1B,WAGvBrR,KAAO4jC,QAIhBlf,WAAWl4C,UAAUu3D,MAAQ,mBACvBH,MAAOl1D,KAAKqJ,MAAQ,EACU8rD,KAArBnxD,SAAS,QAAS,GACKsxD,KAAtBtxD,SAAS,SAAU,GACxB+L,EAAI/P,KAAKsJ,OAAS,EAAGyG,GAAK,EAAGA,IAAK,SACrC0D,KAAOzT,KAAKozD,UAAYrjD,EAAI/P,KAAKsJ,OAAS,EAAIyG,EACzCD,EAAI,EAAGA,EAAI9P,KAAKqJ,MAAOyG,IAAK,KAE/BslD,EAAIp1D,KAAKkzD,MAAMY,UAAU9zD,KAAKsxB,KAAK,QAClCA,KAAK,MAEN8iC,MAAQgB,EAAID,MAAQA,KAAO,IAAM,EACjCb,OAASc,GAAK,EAAIE,MAASA,KAAO,IAAM,EACxCf,KAAOa,GAAK,IAAMD,KAAO,IAAM,EAE/B1nD,SAAWgG,KAAOzT,KAAKqJ,MAAQ,EAAQ,EAAJyG,OAClC3D,KAAKsB,UAAY8mD,SACjBpoD,KAAKsB,SAAW,GAAK6mD,WACrBnoD,KAAKsB,SAAW,GAAK2mD,UACrBjoD,KAAKsB,SAAW,GATT,SAYT6jB,KAAO4jC,QAIhBlf,WAAWl4C,UAAUy3D,MAAQ,eAEtB,IAAIxlD,EAAI/P,KAAKsJ,OAAS,EAAGyG,GAAK,EAAGA,IAAK,SACrC0D,KAAOzT,KAAKozD,UAAYrjD,EAAI/P,KAAKsJ,OAAS,EAAIyG,EACzCD,EAAI,EAAGA,EAAI9P,KAAKqJ,MAAOyG,IAAK,KAC/BskD,KAAOp0D,KAAKkzD,MAAMmB,SAASr0D,KAAKsxB,OAAO,GAAgBgjC,MAAQt0D,KAAKkzD,MAAMmB,SAASr0D,KAAKsxB,OAAO,GAAgBijC,IAAMv0D,KAAKkzD,MAAMmB,SAASr0D,KAAKsxB,OAAO,GAAgB7jB,SAAWgG,KAAOzT,KAAKqJ,MAAQ,EAAQ,EAAJyG,OACvM3D,KAAKsB,UAAY8mD,SACjBpoD,KAAKsB,SAAW,GAAK6mD,WACrBnoD,KAAKsB,SAAW,GAAK2mD,UACrBjoD,KAAKsB,SAAW,GAAK,SAGvB6jB,KAAQtxB,KAAKqJ,MAAQ,IAS9B2sC,WAAWl4C,UAAU03D,MAAQ,eAEtB,IAAIzlD,EAAI/P,KAAKsJ,OAAS,EAAGyG,GAAK,EAAGA,YAChC0D,KAAOzT,KAAKozD,UAAYrjD,EAAI/P,KAAKsJ,OAAS,EAAIyG,EACzCD,EAAI,EAAGA,EAAI9P,KAAKqJ,MAAOyG,IAAK,KAC/BskD,KAAOp0D,KAAKkzD,MAAMmB,SAASr0D,KAAKsxB,OAAO,GAAgBgjC,MAAQt0D,KAAKkzD,MAAMmB,SAASr0D,KAAKsxB,OAAO,GAAgBijC,IAAMv0D,KAAKkzD,MAAMmB,SAASr0D,KAAKsxB,OAAO,GAAgBqR,MAAQ3iC,KAAKkzD,MAAMmB,SAASr0D,KAAKsxB,OAAO,GAAgB7jB,SAAWgG,KAAOzT,KAAKqJ,MAAQ,EAAQ,EAAJyG,OAC/P3D,KAAKsB,UAAY8mD,SACjBpoD,KAAKsB,SAAW,GAAK6mD,WACrBnoD,KAAKsB,SAAW,GAAK2mD,UACrBjoD,KAAKsB,SAAW,GAAKk1B,QAQhCqT,WAAWl4C,UAAUm4C,QAAU,kBACtBj2C,KAAKmM,UAIboL,OAAOC,QAAU,SAASi+C,aACnBnmC,QAAU,IAAI0mB,WAAWyf,eACtB,CACLtpD,KAAMmjB,QAAQ2mB,UACd5sC,MAAOimB,QAAQjmB,MACfC,OAAQgmB,QAAQhmB,SAGpB,MAAMsE,cAsCE5P,YAwDL03D,WAAa,CAAE,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GACrJ,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAChJ,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAChJ,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAChJ,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAChJ,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAChJ,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,EAAG,EAAG,GAAI,GAAI,GAAI,GAAI,GAAI,GAC9I,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAChJ,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAChJ,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,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EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,EAAG,EAAG,IAAK,EAC/I,GAAI,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,GAAI,EAC7I,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAChJ,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EACjJ,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAC7I,EAAG,IAAK,EAAG,IAAK,EAAG,EAAG,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAC/I,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG,GAAI,EAAG,IAAK,EAAG,IAAK,EAAG,IAAK,EAAG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,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,KAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAAS,OAC/D,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"}
\ No newline at end of file
+{"version":3,"file":"jspdf.min.js","sources":["../src/jspdf.js"],"sourcesContent":["/** @license\n *\n * jsPDF - PDF Document creation from JavaScript\n * Version 2.5.1 Built on 2022-01-28T15:37:57.789Z\n *                      CommitID 00000000\n *\n * Copyright (c) 2010-2021 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF\n *               2015-2021 yWorks GmbH, http://www.yworks.com\n *               2015-2021 Lukas Holländer <lukas.hollaender@yworks.com>, https://github.com/HackbrettXXX\n *               2016-2018 Aras Abbasi <aras.abbasi@gmail.com>\n *               2010 Aaron Spike, https://github.com/acspike\n *               2012 Willow Systems Corporation, https://github.com/willowsystems\n *               2012 Pablo Hess, https://github.com/pablohess\n *               2012 Florian Jenett, https://github.com/fjenett\n *               2013 Warren Weckesser, https://github.com/warrenweckesser\n *               2013 Youssef Beddad, https://github.com/lifof\n *               2013 Lee Driscoll, https://github.com/lsdriscoll\n *               2013 Stefan Slonevskiy, https://github.com/stefslon\n *               2013 Jeremy Morel, https://github.com/jmorel\n *               2013 Christoph Hartmann, https://github.com/chris-rock\n *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria\n *               2014 James Makes, https://github.com/dollaruw\n *               2014 Diego Casorran, https://github.com/diegocr\n *               2014 Steven Spungin, https://github.com/Flamenco\n *               2014 Kenneth Glassey, https://github.com/Gavvers\n *\n * Permission is hereby granted, free of charge, to any person obtaining\n * a copy of this software and associated documentation files (the\n * \"Software\"), to deal in the Software without restriction, including\n * without limitation the rights to use, copy, modify, merge, publish,\n * distribute, sublicense, and/or sell copies of the Software, and to\n * permit persons to whom the Software is furnished to do so, subject to\n * the following conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n * Contributor(s):\n *    siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango,\n *    kim3er, mfo, alnorth, Flamenco\n */\n\n (function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (global = global || self, factory(global.jspdf = {}));\n}(this, (function (exports) { 'use strict';\n\n  function _typeof(obj) {\n    \"@babel/helpers - typeof\";\n\n    if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n      _typeof = function (obj) {\n        return typeof obj;\n      };\n    } else {\n      _typeof = function (obj) {\n        return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n      };\n    }\n\n    return _typeof(obj);\n  }\n\n  var globalObject = function () {\n    return \"undefined\" !== typeof window ? window : \"undefined\" !== typeof global ? global : \"undefined\" !== typeof self ? self : this;\n  }();\n\n  function consoleLog() {\n    if (globalObject.console && typeof globalObject.console.log === \"function\") {\n      globalObject.console.log.apply(globalObject.console, arguments);\n    }\n  }\n\n  function consoleWarn(str) {\n    if (globalObject.console) {\n      if (typeof globalObject.console.warn === \"function\") {\n        globalObject.console.warn.apply(globalObject.console, arguments);\n      } else {\n        consoleLog.call(null, arguments);\n      }\n    }\n  }\n\n  function consoleError(str) {\n    if (globalObject.console) {\n      if (typeof globalObject.console.error === \"function\") {\n        globalObject.console.error.apply(globalObject.console, arguments);\n      } else {\n        consoleLog(str);\n      }\n    }\n  }\n\n  var console = {\n    log: consoleLog,\n    warn: consoleWarn,\n    error: consoleError\n  };\n\n  function bom(blob, opts) {\n    if (typeof opts === \"undefined\") opts = {\n      autoBom: false\n    };else if (_typeof(opts) !== \"object\") {\n      console.warn(\"Deprecated: Expected third argument to be a object\");\n      opts = {\n        autoBom: !opts\n      };\n    } // prepend BOM for UTF-8 XML and text/* types (including HTML)\n    // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF\n\n    if (opts.autoBom && /^\\s*(?:text\\/\\S*|application\\/xml|\\S*\\/\\S*\\+xml)\\s*;.*charset\\s*=\\s*utf-8/i.test(blob.type)) {\n      return new Blob([String.fromCharCode(0xfeff), blob], {\n        type: blob.type\n      });\n    }\n\n    return blob;\n  }\n\n  function download(url, name, opts) {\n    var xhr = new XMLHttpRequest();\n    xhr.open(\"GET\", url);\n    xhr.responseType = \"blob\";\n\n    xhr.onload = function () {\n      saveAs(xhr.response, name, opts);\n    };\n\n    xhr.onerror = function () {\n      console.error(\"could not download file\");\n    };\n\n    xhr.send();\n  }\n\n  function corsEnabled(url) {\n    var xhr = new XMLHttpRequest(); // use sync to avoid popup blocker\n\n    xhr.open(\"HEAD\", url, false);\n\n    try {\n      xhr.send();\n    } catch (e) {}\n\n    return xhr.status >= 200 && xhr.status <= 299;\n  } // `a.click()` doesn't work for all browsers (#465)\n\n\n  function click(node) {\n    try {\n      node.dispatchEvent(new MouseEvent(\"click\"));\n    } catch (e) {\n      var evt = document.createEvent(\"MouseEvents\");\n      evt.initMouseEvent(\"click\", true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);\n      node.dispatchEvent(evt);\n    }\n  }\n\n  var saveAs = globalObject.saveAs || ( // probably in some web worker\n  (typeof window === \"undefined\" ? \"undefined\" : _typeof(window)) !== \"object\" || window !== globalObject ? function saveAs() {\n    /* noop */\n  } : // Use download attribute first if possible (#193 Lumia mobile) unless this is a native app\n  typeof HTMLAnchorElement !== \"undefined\" && \"download\" in HTMLAnchorElement.prototype ? function saveAs(blob, name, opts) {\n    var URL = globalObject.URL || globalObject.webkitURL;\n    var a = document.createElement(\"a\");\n    name = name || blob.name || \"download\";\n    a.download = name;\n    a.rel = \"noopener\"; // tabnabbing\n    // TODO: detect chrome extensions & packaged apps\n    // a.target = '_blank'\n\n    if (typeof blob === \"string\") {\n      // Support regular links\n      a.href = blob;\n\n      if (a.origin !== location.origin) {\n        corsEnabled(a.href) ? download(blob, name, opts) : click(a, a.target = \"_blank\");\n      } else {\n        click(a);\n      }\n    } else {\n      // Support blobs\n      a.href = URL.createObjectURL(blob);\n      setTimeout(function () {\n        URL.revokeObjectURL(a.href);\n      }, 4e4); // 40s\n\n      setTimeout(function () {\n        click(a);\n      }, 0);\n    }\n  } : // Use msSaveOrOpenBlob as a second approach\n  \"msSaveOrOpenBlob\" in navigator ? function saveAs(blob, name, opts) {\n    name = name || blob.name || \"download\";\n\n    if (typeof blob === \"string\") {\n      if (corsEnabled(blob)) {\n        download(blob, name, opts);\n      } else {\n        var a = document.createElement(\"a\");\n        a.href = blob;\n        a.target = \"_blank\";\n        setTimeout(function () {\n          click(a);\n        });\n      }\n    } else {\n      navigator.msSaveOrOpenBlob(bom(blob, opts), name);\n    }\n  } : // Fallback to using FileReader and a popup\n  function saveAs(blob, name, opts, popup) {\n    // Open a popup immediately do go around popup blocker\n    // Mostly only available on user interaction and the fileReader is async so...\n    popup = popup || open(\"\", \"_blank\");\n\n    if (popup) {\n      popup.document.title = popup.document.body.innerText = \"downloading...\";\n    }\n\n    if (typeof blob === \"string\") return download(blob, name, opts);\n    var force = blob.type === \"application/octet-stream\";\n\n    var isSafari = /constructor/i.test(globalObject.HTMLElement) || globalObject.safari;\n\n    var isChromeIOS = /CriOS\\/[\\d]+/.test(navigator.userAgent);\n\n    if ((isChromeIOS || force && isSafari) && (typeof FileReader === \"undefined\" ? \"undefined\" : _typeof(FileReader)) === \"object\") {\n      // Safari doesn't allow downloading of blob URLs\n      var reader = new FileReader();\n\n      reader.onloadend = function () {\n        var url = reader.result;\n        url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, \"data:attachment/file;\");\n        if (popup) popup.location.href = url;else location = url;\n        popup = null; // reverse-tabnabbing #460\n      };\n\n      reader.readAsDataURL(blob);\n    } else {\n      var URL = globalObject.URL || globalObject.webkitURL;\n      var url = URL.createObjectURL(blob);\n      if (popup) popup.location = url;else location.href = url;\n      popup = null; // reverse-tabnabbing #460\n\n      setTimeout(function () {\n        URL.revokeObjectURL(url);\n      }, 4e4); // 40s\n    }\n  });\n\n  /**\n   * A class to parse color values\n   * @author Stoyan Stefanov <sstoo@gmail.com>\n   * {@link   http://www.phpied.com/rgb-color-parser-in-javascript/}\n   * @license Use it if you like it\n   */\n  function RGBColor(color_string) {\n    color_string = color_string || \"\";\n    this.ok = false; // strip any leading #\n\n    if (color_string.charAt(0) == \"#\") {\n      // remove # if any\n      color_string = color_string.substr(1, 6);\n    }\n\n    color_string = color_string.replace(/ /g, \"\");\n    color_string = color_string.toLowerCase();\n    var channels; // before getting into regexps, try simple matches\n    // and overwrite the input\n\n    var simple_colors = {\n      aliceblue: \"f0f8ff\",\n      antiquewhite: \"faebd7\",\n      aqua: \"00ffff\",\n      aquamarine: \"7fffd4\",\n      azure: \"f0ffff\",\n      beige: \"f5f5dc\",\n      bisque: \"ffe4c4\",\n      black: \"000000\",\n      blanchedalmond: \"ffebcd\",\n      blue: \"0000ff\",\n      blueviolet: \"8a2be2\",\n      brown: \"a52a2a\",\n      burlywood: \"deb887\",\n      cadetblue: \"5f9ea0\",\n      chartreuse: \"7fff00\",\n      chocolate: \"d2691e\",\n      coral: \"ff7f50\",\n      cornflowerblue: \"6495ed\",\n      cornsilk: \"fff8dc\",\n      crimson: \"dc143c\",\n      cyan: \"00ffff\",\n      darkblue: \"00008b\",\n      darkcyan: \"008b8b\",\n      darkgoldenrod: \"b8860b\",\n      darkgray: \"a9a9a9\",\n      darkgreen: \"006400\",\n      darkkhaki: \"bdb76b\",\n      darkmagenta: \"8b008b\",\n      darkolivegreen: \"556b2f\",\n      darkorange: \"ff8c00\",\n      darkorchid: \"9932cc\",\n      darkred: \"8b0000\",\n      darksalmon: \"e9967a\",\n      darkseagreen: \"8fbc8f\",\n      darkslateblue: \"483d8b\",\n      darkslategray: \"2f4f4f\",\n      darkturquoise: \"00ced1\",\n      darkviolet: \"9400d3\",\n      deeppink: \"ff1493\",\n      deepskyblue: \"00bfff\",\n      dimgray: \"696969\",\n      dodgerblue: \"1e90ff\",\n      feldspar: \"d19275\",\n      firebrick: \"b22222\",\n      floralwhite: \"fffaf0\",\n      forestgreen: \"228b22\",\n      fuchsia: \"ff00ff\",\n      gainsboro: \"dcdcdc\",\n      ghostwhite: \"f8f8ff\",\n      gold: \"ffd700\",\n      goldenrod: \"daa520\",\n      gray: \"808080\",\n      green: \"008000\",\n      greenyellow: \"adff2f\",\n      honeydew: \"f0fff0\",\n      hotpink: \"ff69b4\",\n      indianred: \"cd5c5c\",\n      indigo: \"4b0082\",\n      ivory: \"fffff0\",\n      khaki: \"f0e68c\",\n      lavender: \"e6e6fa\",\n      lavenderblush: \"fff0f5\",\n      lawngreen: \"7cfc00\",\n      lemonchiffon: \"fffacd\",\n      lightblue: \"add8e6\",\n      lightcoral: \"f08080\",\n      lightcyan: \"e0ffff\",\n      lightgoldenrodyellow: \"fafad2\",\n      lightgrey: \"d3d3d3\",\n      lightgreen: \"90ee90\",\n      lightpink: \"ffb6c1\",\n      lightsalmon: \"ffa07a\",\n      lightseagreen: \"20b2aa\",\n      lightskyblue: \"87cefa\",\n      lightslateblue: \"8470ff\",\n      lightslategray: \"778899\",\n      lightsteelblue: \"b0c4de\",\n      lightyellow: \"ffffe0\",\n      lime: \"00ff00\",\n      limegreen: \"32cd32\",\n      linen: \"faf0e6\",\n      magenta: \"ff00ff\",\n      maroon: \"800000\",\n      mediumaquamarine: \"66cdaa\",\n      mediumblue: \"0000cd\",\n      mediumorchid: \"ba55d3\",\n      mediumpurple: \"9370d8\",\n      mediumseagreen: \"3cb371\",\n      mediumslateblue: \"7b68ee\",\n      mediumspringgreen: \"00fa9a\",\n      mediumturquoise: \"48d1cc\",\n      mediumvioletred: \"c71585\",\n      midnightblue: \"191970\",\n      mintcream: \"f5fffa\",\n      mistyrose: \"ffe4e1\",\n      moccasin: \"ffe4b5\",\n      navajowhite: \"ffdead\",\n      navy: \"000080\",\n      oldlace: \"fdf5e6\",\n      olive: \"808000\",\n      olivedrab: \"6b8e23\",\n      orange: \"ffa500\",\n      orangered: \"ff4500\",\n      orchid: \"da70d6\",\n      palegoldenrod: \"eee8aa\",\n      palegreen: \"98fb98\",\n      paleturquoise: \"afeeee\",\n      palevioletred: \"d87093\",\n      papayawhip: \"ffefd5\",\n      peachpuff: \"ffdab9\",\n      peru: \"cd853f\",\n      pink: \"ffc0cb\",\n      plum: \"dda0dd\",\n      powderblue: \"b0e0e6\",\n      purple: \"800080\",\n      red: \"ff0000\",\n      rosybrown: \"bc8f8f\",\n      royalblue: \"4169e1\",\n      saddlebrown: \"8b4513\",\n      salmon: \"fa8072\",\n      sandybrown: \"f4a460\",\n      seagreen: \"2e8b57\",\n      seashell: \"fff5ee\",\n      sienna: \"a0522d\",\n      silver: \"c0c0c0\",\n      skyblue: \"87ceeb\",\n      slateblue: \"6a5acd\",\n      slategray: \"708090\",\n      snow: \"fffafa\",\n      springgreen: \"00ff7f\",\n      steelblue: \"4682b4\",\n      tan: \"d2b48c\",\n      teal: \"008080\",\n      thistle: \"d8bfd8\",\n      tomato: \"ff6347\",\n      turquoise: \"40e0d0\",\n      violet: \"ee82ee\",\n      violetred: \"d02090\",\n      wheat: \"f5deb3\",\n      white: \"ffffff\",\n      whitesmoke: \"f5f5f5\",\n      yellow: \"ffff00\",\n      yellowgreen: \"9acd32\"\n    };\n    color_string = simple_colors[color_string] || color_string; // array of color definition objects\n\n    var color_defs = [{\n      re: /^rgb\\((\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})\\)$/,\n      example: [\"rgb(123, 234, 45)\", \"rgb(255,234,245)\"],\n      process: function process(bits) {\n        return [parseInt(bits[1]), parseInt(bits[2]), parseInt(bits[3])];\n      }\n    }, {\n      re: /^(\\w{2})(\\w{2})(\\w{2})$/,\n      example: [\"#00ff00\", \"336699\"],\n      process: function process(bits) {\n        return [parseInt(bits[1], 16), parseInt(bits[2], 16), parseInt(bits[3], 16)];\n      }\n    }, {\n      re: /^(\\w{1})(\\w{1})(\\w{1})$/,\n      example: [\"#fb0\", \"f0f\"],\n      process: function process(bits) {\n        return [parseInt(bits[1] + bits[1], 16), parseInt(bits[2] + bits[2], 16), parseInt(bits[3] + bits[3], 16)];\n      }\n    }]; // search through the definitions to find a match\n\n    for (var i = 0; i < color_defs.length; i++) {\n      var re = color_defs[i].re;\n      var processor = color_defs[i].process;\n      var bits = re.exec(color_string);\n\n      if (bits) {\n        channels = processor(bits);\n        this.r = channels[0];\n        this.g = channels[1];\n        this.b = channels[2];\n        this.ok = true;\n      }\n    } // validate/cleanup values\n\n\n    this.r = this.r < 0 || isNaN(this.r) ? 0 : this.r > 255 ? 255 : this.r;\n    this.g = this.g < 0 || isNaN(this.g) ? 0 : this.g > 255 ? 255 : this.g;\n    this.b = this.b < 0 || isNaN(this.b) ? 0 : this.b > 255 ? 255 : this.b; // some getters\n\n    this.toRGB = function () {\n      return \"rgb(\" + this.r + \", \" + this.g + \", \" + this.b + \")\";\n    };\n\n    this.toHex = function () {\n      var r = this.r.toString(16);\n      var g = this.g.toString(16);\n      var b = this.b.toString(16);\n      if (r.length == 1) r = \"0\" + r;\n      if (g.length == 1) g = \"0\" + g;\n      if (b.length == 1) b = \"0\" + b;\n      return \"#\" + r + g + b;\n    };\n  }\n\n  var atob, btoa;\n\n  (function () {\n    atob = globalObject.atob.bind(globalObject);\n    btoa = globalObject.btoa.bind(globalObject);\n    return;\n  })();\n\n  /**\n   * @license\n   * Joseph Myers does not specify a particular license for his work.\n   *\n   * Author: Joseph Myers\n   * Accessed from: http://www.myersdaily.org/joseph/javascript/md5.js\n   *\n   * Modified by: Owen Leong\n   */\n  function md5cycle(x, k) {\n    var a = x[0],\n        b = x[1],\n        c = x[2],\n        d = x[3];\n    a = ff(a, b, c, d, k[0], 7, -680876936);\n    d = ff(d, a, b, c, k[1], 12, -389564586);\n    c = ff(c, d, a, b, k[2], 17, 606105819);\n    b = ff(b, c, d, a, k[3], 22, -1044525330);\n    a = ff(a, b, c, d, k[4], 7, -176418897);\n    d = ff(d, a, b, c, k[5], 12, 1200080426);\n    c = ff(c, d, a, b, k[6], 17, -1473231341);\n    b = ff(b, c, d, a, k[7], 22, -45705983);\n    a = ff(a, b, c, d, k[8], 7, 1770035416);\n    d = ff(d, a, b, c, k[9], 12, -1958414417);\n    c = ff(c, d, a, b, k[10], 17, -42063);\n    b = ff(b, c, d, a, k[11], 22, -1990404162);\n    a = ff(a, b, c, d, k[12], 7, 1804603682);\n    d = ff(d, a, b, c, k[13], 12, -40341101);\n    c = ff(c, d, a, b, k[14], 17, -1502002290);\n    b = ff(b, c, d, a, k[15], 22, 1236535329);\n    a = gg(a, b, c, d, k[1], 5, -165796510);\n    d = gg(d, a, b, c, k[6], 9, -1069501632);\n    c = gg(c, d, a, b, k[11], 14, 643717713);\n    b = gg(b, c, d, a, k[0], 20, -373897302);\n    a = gg(a, b, c, d, k[5], 5, -701558691);\n    d = gg(d, a, b, c, k[10], 9, 38016083);\n    c = gg(c, d, a, b, k[15], 14, -660478335);\n    b = gg(b, c, d, a, k[4], 20, -405537848);\n    a = gg(a, b, c, d, k[9], 5, 568446438);\n    d = gg(d, a, b, c, k[14], 9, -1019803690);\n    c = gg(c, d, a, b, k[3], 14, -187363961);\n    b = gg(b, c, d, a, k[8], 20, 1163531501);\n    a = gg(a, b, c, d, k[13], 5, -1444681467);\n    d = gg(d, a, b, c, k[2], 9, -51403784);\n    c = gg(c, d, a, b, k[7], 14, 1735328473);\n    b = gg(b, c, d, a, k[12], 20, -1926607734);\n    a = hh(a, b, c, d, k[5], 4, -378558);\n    d = hh(d, a, b, c, k[8], 11, -2022574463);\n    c = hh(c, d, a, b, k[11], 16, 1839030562);\n    b = hh(b, c, d, a, k[14], 23, -35309556);\n    a = hh(a, b, c, d, k[1], 4, -1530992060);\n    d = hh(d, a, b, c, k[4], 11, 1272893353);\n    c = hh(c, d, a, b, k[7], 16, -155497632);\n    b = hh(b, c, d, a, k[10], 23, -1094730640);\n    a = hh(a, b, c, d, k[13], 4, 681279174);\n    d = hh(d, a, b, c, k[0], 11, -358537222);\n    c = hh(c, d, a, b, k[3], 16, -722521979);\n    b = hh(b, c, d, a, k[6], 23, 76029189);\n    a = hh(a, b, c, d, k[9], 4, -640364487);\n    d = hh(d, a, b, c, k[12], 11, -421815835);\n    c = hh(c, d, a, b, k[15], 16, 530742520);\n    b = hh(b, c, d, a, k[2], 23, -995338651);\n    a = ii(a, b, c, d, k[0], 6, -198630844);\n    d = ii(d, a, b, c, k[7], 10, 1126891415);\n    c = ii(c, d, a, b, k[14], 15, -1416354905);\n    b = ii(b, c, d, a, k[5], 21, -57434055);\n    a = ii(a, b, c, d, k[12], 6, 1700485571);\n    d = ii(d, a, b, c, k[3], 10, -1894986606);\n    c = ii(c, d, a, b, k[10], 15, -1051523);\n    b = ii(b, c, d, a, k[1], 21, -2054922799);\n    a = ii(a, b, c, d, k[8], 6, 1873313359);\n    d = ii(d, a, b, c, k[15], 10, -30611744);\n    c = ii(c, d, a, b, k[6], 15, -1560198380);\n    b = ii(b, c, d, a, k[13], 21, 1309151649);\n    a = ii(a, b, c, d, k[4], 6, -145523070);\n    d = ii(d, a, b, c, k[11], 10, -1120210379);\n    c = ii(c, d, a, b, k[2], 15, 718787259);\n    b = ii(b, c, d, a, k[9], 21, -343485551);\n    x[0] = add32(a, x[0]);\n    x[1] = add32(b, x[1]);\n    x[2] = add32(c, x[2]);\n    x[3] = add32(d, x[3]);\n  }\n\n  function cmn(q, a, b, x, s, t) {\n    a = add32(add32(a, q), add32(x, t));\n    return add32(a << s | a >>> 32 - s, b);\n  }\n\n  function ff(a, b, c, d, x, s, t) {\n    return cmn(b & c | ~b & d, a, b, x, s, t);\n  }\n\n  function gg(a, b, c, d, x, s, t) {\n    return cmn(b & d | c & ~d, a, b, x, s, t);\n  }\n\n  function hh(a, b, c, d, x, s, t) {\n    return cmn(b ^ c ^ d, a, b, x, s, t);\n  }\n\n  function ii(a, b, c, d, x, s, t) {\n    return cmn(c ^ (b | ~d), a, b, x, s, t);\n  }\n\n  function md51(s) {\n    // txt = '';\n    var n = s.length,\n        state = [1732584193, -271733879, -1732584194, 271733878],\n        i;\n\n    for (i = 64; i <= s.length; i += 64) {\n      md5cycle(state, md5blk(s.substring(i - 64, i)));\n    }\n\n    s = s.substring(i - 64);\n    var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n\n    for (i = 0; i < s.length; i++) {\n      tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3);\n    }\n\n    tail[i >> 2] |= 0x80 << (i % 4 << 3);\n\n    if (i > 55) {\n      md5cycle(state, tail);\n\n      for (i = 0; i < 16; i++) {\n        tail[i] = 0;\n      }\n    }\n\n    tail[14] = n * 8;\n    md5cycle(state, tail);\n    return state;\n  }\n  /* there needs to be support for Unicode here,\n   * unless we pretend that we can redefine the MD-5\n   * algorithm for multi-byte characters (perhaps\n   * by adding every four 16-bit characters and\n   * shortening the sum to 32 bits). Otherwise\n   * I suggest performing MD-5 as if every character\n   * was two bytes--e.g., 0040 0025 = @%--but then\n   * how will an ordinary MD-5 sum be matched?\n   * There is no way to standardize text to something\n   * like UTF-8 before transformation; speed cost is\n   * utterly prohibitive. The JavaScript standard\n   * itself needs to look at this: it should start\n   * providing access to strings as preformed UTF-8\n   * 8-bit unsigned value arrays.\n   */\n\n\n  function md5blk(s) {\n    /* I figured global was faster.   */\n    var md5blks = [],\n        i;\n    /* Andy King said do it this way. */\n\n    for (i = 0; i < 64; i += 4) {\n      md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);\n    }\n\n    return md5blks;\n  }\n\n  var hex_chr = \"0123456789abcdef\".split(\"\");\n\n  function rhex(n) {\n    var s = \"\",\n        j = 0;\n\n    for (; j < 4; j++) {\n      s += hex_chr[n >> j * 8 + 4 & 0x0f] + hex_chr[n >> j * 8 & 0x0f];\n    }\n\n    return s;\n  }\n\n  function hex(x) {\n    for (var i = 0; i < x.length; i++) {\n      x[i] = rhex(x[i]);\n    }\n\n    return x.join(\"\");\n  } // Converts a 4-byte number to byte string\n\n\n  function singleToByteString(n) {\n    return String.fromCharCode((n & 0xff) >> 0, (n & 0xff00) >> 8, (n & 0xff0000) >> 16, (n & 0xff000000) >> 24);\n  } // Converts an array of numbers to a byte string\n\n\n  function toByteString(x) {\n    return x.map(singleToByteString).join(\"\");\n  } // Returns the MD5 hash as a byte string\n\n\n  function md5Bin(s) {\n    return toByteString(md51(s));\n  } // Returns MD5 hash as a hex string\n\n\n  function md5(s) {\n    return hex(md51(s));\n  }\n\n  var md5Check = md5(\"hello\") != \"5d41402abc4b2a76b9719d911017c592\";\n\n  function add32(a, b) {\n    if (md5Check) {\n      /* if the md5Check does not match\n       the expected value, we're dealing\n       with an old browser and need\n       this function. */\n      var lsw = (a & 0xffff) + (b & 0xffff),\n          msw = (a >> 16) + (b >> 16) + (lsw >> 16);\n      return msw << 16 | lsw & 0xffff;\n    } else {\n      /* this function is much faster,\n      so if possible we use it. Some IEs\n      are the only ones I know of that\n      need the idiotic second function,\n      generated by an if clause.  */\n      return a + b & 0xffffffff;\n    }\n  }\n\n  /**\n   * @license\n   * FPDF is released under a permissive license: there is no usage restriction.\n   * You may embed it freely in your application (commercial or not), with or\n   * without modifications.\n   *\n   * Reference: http://www.fpdf.org/en/script/script37.php\n   */\n  function repeat(str, num) {\n    return new Array(num + 1).join(str);\n  }\n  /**\n   * Converts a byte string to a hex string\n   *\n   * @name rc4\n   * @function\n   * @param {string} key Byte string of encryption key\n   * @param {string} data Byte string of data to be encrypted\n   * @returns {string} Encrypted string\n   */\n\n\n  function rc4(key, data) {\n    var lastKey, lastState;\n\n    if (key !== lastKey) {\n      var k = repeat(key, (256 / key.length >> 0) + 1);\n      var state = [];\n\n      for (var i = 0; i < 256; i++) {\n        state[i] = i;\n      }\n\n      var j = 0;\n\n      for (var i = 0; i < 256; i++) {\n        var t = state[i];\n        j = (j + t + k.charCodeAt(i)) % 256;\n        state[i] = state[j];\n        state[j] = t;\n      }\n\n      lastKey = key;\n      lastState = state;\n    } else {\n      state = lastState;\n    }\n\n    var length = data.length;\n    var a = 0;\n    var b = 0;\n    var out = \"\";\n\n    for (var i = 0; i < length; i++) {\n      a = (a + 1) % 256;\n      t = state[a];\n      b = (b + t) % 256;\n      state[a] = state[b];\n      state[b] = t;\n      k = state[(state[a] + state[b]) % 256];\n      out += String.fromCharCode(data.charCodeAt(i) ^ k);\n    }\n\n    return out;\n  }\n\n  /**\n   * @license\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   * Author: Owen Leong (@owenl131)\n   * Date: 15 Oct 2020\n   * References:\n   * https://www.cs.cmu.edu/~dst/Adobe/Gallery/anon21jul01-pdf-encryption.txt\n   * https://github.com/foliojs/pdfkit/blob/master/lib/security.js\n   * http://www.fpdf.org/en/script/script37.php\n   */\n  var permissionOptions = {\n    print: 4,\n    modify: 8,\n    copy: 16,\n    \"annot-forms\": 32\n  };\n  /**\n   * Initializes encryption settings\n   *\n   * @name constructor\n   * @function\n   * @param {Array} permissions Permissions allowed for user, \"print\", \"modify\", \"copy\" and \"annot-forms\".\n   * @param {String} userPassword Permissions apply to this user. Leaving this empty means the document\n   *                              is not password protected but viewer has the above permissions.\n   * @param {String} ownerPassword Owner has full functionalities to the file.\n   * @param {String} fileId As hex string, should be same as the file ID in the trailer.\n   * @example\n   * var security = new PDFSecurity([\"print\"])\n   */\n\n  function PDFSecurity(permissions, userPassword, ownerPassword, fileId) {\n    this.v = 1; // algorithm 1, future work can add in more recent encryption schemes\n\n    this.r = 2; // revision 2\n    // set flags for what functionalities the user can access\n\n    var protection = 192;\n    permissions.forEach(function (perm) {\n      if (typeof permissionOptions.perm !== \"undefined\") {\n        throw new Error(\"Invalid permission: \" + perm);\n      }\n\n      protection += permissionOptions[perm];\n    }); // padding is used to pad the passwords to 32 bytes, also is hashed and stored in the final PDF\n\n    this.padding = \"\\x28\\xBF\\x4E\\x5E\\x4E\\x75\\x8A\\x41\\x64\\x00\\x4E\\x56\\xFF\\xFA\\x01\\x08\" + \"\\x2E\\x2E\\x00\\xB6\\xD0\\x68\\x3E\\x80\\x2F\\x0C\\xA9\\xFE\\x64\\x53\\x69\\x7A\";\n    var paddedUserPassword = (userPassword + this.padding).substr(0, 32);\n    var paddedOwnerPassword = (ownerPassword + this.padding).substr(0, 32);\n    this.O = this.processOwnerPassword(paddedUserPassword, paddedOwnerPassword);\n    this.P = -((protection ^ 255) + 1);\n    this.encryptionKey = md5Bin(paddedUserPassword + this.O + this.lsbFirstWord(this.P) + this.hexToBytes(fileId)).substr(0, 5);\n    this.U = rc4(this.encryptionKey, this.padding);\n  }\n  /**\n   * Breaks down a 4-byte number into its individual bytes, with the least significant bit first\n   *\n   * @name lsbFirstWord\n   * @function\n   * @param {number} data 32-bit number\n   * @returns {Array}\n   */\n\n\n  PDFSecurity.prototype.lsbFirstWord = function (data) {\n    return String.fromCharCode(data >> 0 & 0xff, data >> 8 & 0xff, data >> 16 & 0xff, data >> 24 & 0xff);\n  };\n  /**\n   * Converts a byte string to a hex string\n   *\n   * @name toHexString\n   * @function\n   * @param {String} byteString Byte string\n   * @returns {String}\n   */\n\n\n  PDFSecurity.prototype.toHexString = function (byteString) {\n    return byteString.split(\"\").map(function (byte) {\n      return (\"0\" + (byte.charCodeAt(0) & 0xff).toString(16)).slice(-2);\n    }).join(\"\");\n  };\n  /**\n   * Converts a hex string to a byte string\n   *\n   * @name hexToBytes\n   * @function\n   * @param {String} hex Hex string\n   * @returns {String}\n   */\n\n\n  PDFSecurity.prototype.hexToBytes = function (hex) {\n    for (var bytes = [], c = 0; c < hex.length; c += 2) {\n      bytes.push(String.fromCharCode(parseInt(hex.substr(c, 2), 16)));\n    }\n\n    return bytes.join(\"\");\n  };\n  /**\n   * Computes the 'O' field in the encryption dictionary\n   *\n   * @name processOwnerPassword\n   * @function\n   * @param {String} paddedUserPassword Byte string of padded user password\n   * @param {String} paddedOwnerPassword Byte string of padded owner password\n   * @returns {String}\n   */\n\n\n  PDFSecurity.prototype.processOwnerPassword = function (paddedUserPassword, paddedOwnerPassword) {\n    var key = md5Bin(paddedOwnerPassword).substr(0, 5);\n    return rc4(key, paddedUserPassword);\n  };\n  /**\n   * Returns an encryptor function which can take in a byte string and returns the encrypted version\n   *\n   * @name encryptor\n   * @function\n   * @param {number} objectId\n   * @param {number} generation Not sure what this is for, you can set it to 0\n   * @returns {Function}\n   * @example\n   * out(\"stream\");\n   * encryptor = security.encryptor(object.id, 0);\n   * out(encryptor(data));\n   * out(\"endstream\");\n   */\n\n\n  PDFSecurity.prototype.encryptor = function (objectId, generation) {\n    var key = md5Bin(this.encryptionKey + String.fromCharCode(objectId & 0xff, objectId >> 8 & 0xff, objectId >> 16 & 0xff, generation & 0xff, generation >> 8 & 0xff)).substr(0, 10);\n    return function (data) {\n      return rc4(key, data);\n    };\n  };\n\n  /**\n   * Convert string to `PDF Name Object`.\n   * Detail: PDF Reference 1.3 - Chapter 3.2.4 Name Object\n   * @param str\n   */\n  function toPDFName(str) {\n    // eslint-disable-next-line no-control-regex\n    if (/[^\\u0000-\\u00ff]/.test(str)) {\n      // non ascii string\n      throw new Error(\"Invalid PDF Name Object: \" + str + \", Only accept ASCII characters.\");\n    }\n\n    var result = \"\",\n        strLength = str.length;\n\n    for (var i = 0; i < strLength; i++) {\n      var charCode = str.charCodeAt(i);\n\n      if (charCode < 0x21 || charCode === 0x23\n      /* # */\n      || charCode === 0x25\n      /* % */\n      || charCode === 0x28\n      /* ( */\n      || charCode === 0x29\n      /* ) */\n      || charCode === 0x2f\n      /* / */\n      || charCode === 0x3c\n      /* < */\n      || charCode === 0x3e\n      /* > */\n      || charCode === 0x5b\n      /* [ */\n      || charCode === 0x5d\n      /* ] */\n      || charCode === 0x7b\n      /* { */\n      || charCode === 0x7d\n      /* } */\n      || charCode > 0x7e) {\n        // Char    CharCode    hexStr   paddingHexStr    Result\n        // \"\\t\"    9           9        09               #09\n        // \" \"     32          20       20               #20\n        // \"©\"     169         a9       a9               #a9\n        var hexStr = charCode.toString(16),\n            paddingHexStr = (\"0\" + hexStr).slice(-2);\n        result += \"#\" + paddingHexStr;\n      } else {\n        // Other ASCII printable characters between 0x21 <= X <= 0x7e\n        result += str[i];\n      }\n    }\n\n    return result;\n  }\n\n  /**\n   * jsPDF's Internal PubSub Implementation.\n   * Backward compatible rewritten on 2014 by\n   * Diego Casorran, https://github.com/diegocr\n   *\n   * @class\n   * @name PubSub\n   * @ignore\n   */\n\n  function PubSub(context) {\n    if (_typeof(context) !== \"object\") {\n      throw new Error(\"Invalid Context passed to initialize PubSub (jsPDF-module)\");\n    }\n\n    var topics = {};\n\n    this.subscribe = function (topic, callback, once) {\n      once = once || false;\n\n      if (typeof topic !== \"string\" || typeof callback !== \"function\" || typeof once !== \"boolean\") {\n        throw new Error(\"Invalid arguments passed to PubSub.subscribe (jsPDF-module)\");\n      }\n\n      if (!topics.hasOwnProperty(topic)) {\n        topics[topic] = {};\n      }\n\n      var token = Math.random().toString(35);\n      topics[topic][token] = [callback, !!once];\n      return token;\n    };\n\n    this.unsubscribe = function (token) {\n      for (var topic in topics) {\n        if (topics[topic][token]) {\n          delete topics[topic][token];\n\n          if (Object.keys(topics[topic]).length === 0) {\n            delete topics[topic];\n          }\n\n          return true;\n        }\n      }\n\n      return false;\n    };\n\n    this.publish = function (topic) {\n      if (topics.hasOwnProperty(topic)) {\n        var args = Array.prototype.slice.call(arguments, 1),\n            tokens = [];\n\n        for (var token in topics[topic]) {\n          var sub = topics[topic][token];\n\n          try {\n            sub[0].apply(context, args);\n          } catch (ex) {\n            if (globalObject.console) {\n              console.error(\"jsPDF PubSub Error\", ex.message, ex);\n            }\n          }\n\n          if (sub[1]) tokens.push(token);\n        }\n\n        if (tokens.length) tokens.forEach(this.unsubscribe);\n      }\n    };\n\n    this.getTopics = function () {\n      return topics;\n    };\n  }\n\n  function GState(parameters) {\n    if (!(this instanceof GState)) {\n      return new GState(parameters);\n    }\n    /**\n     * @name GState#opacity\n     * @type {any}\n     */\n\n    /**\n     * @name GState#stroke-opacity\n     * @type {any}\n     */\n\n\n    var supported = \"opacity,stroke-opacity\".split(\",\");\n\n    for (var p in parameters) {\n      if (parameters.hasOwnProperty(p) && supported.indexOf(p) >= 0) {\n        this[p] = parameters[p];\n      }\n    }\n    /**\n     * @name GState#id\n     * @type {string}\n     */\n\n\n    this.id = \"\"; // set by addGState()\n\n    /**\n     * @name GState#objectNumber\n     * @type {number}\n     */\n\n    this.objectNumber = -1; // will be set by putGState()\n  }\n\n  GState.prototype.equals = function equals(other) {\n    var ignore = \"id,objectNumber,equals\";\n    var p;\n    if (!other || _typeof(other) !== _typeof(this)) return false;\n    var count = 0;\n\n    for (p in this) {\n      if (ignore.indexOf(p) >= 0) continue;\n      if (this.hasOwnProperty(p) && !other.hasOwnProperty(p)) return false;\n      if (this[p] !== other[p]) return false;\n      count++;\n    }\n\n    for (p in other) {\n      if (other.hasOwnProperty(p) && ignore.indexOf(p) < 0) count--;\n    }\n\n    return count === 0;\n  };\n\n  function Pattern(gState, matrix) {\n    this.gState = gState;\n    this.matrix = matrix;\n    this.id = \"\"; // set by addPattern()\n\n    this.objectNumber = -1; // will be set by putPattern()\n  }\n\n  function ShadingPattern(type, coords, colors, gState, matrix) {\n    if (!(this instanceof ShadingPattern)) {\n      return new ShadingPattern(type, coords, colors, gState, matrix);\n    } // see putPattern() for information how they are realized\n\n\n    this.type = type === \"axial\" ? 2 : 3;\n    this.coords = coords;\n    this.colors = colors;\n    Pattern.call(this, gState, matrix);\n  }\n\n  function TilingPattern(boundingBox, xStep, yStep, gState, matrix) {\n    if (!(this instanceof TilingPattern)) {\n      return new TilingPattern(boundingBox, xStep, yStep, gState, matrix);\n    }\n\n    this.boundingBox = boundingBox;\n    this.xStep = xStep;\n    this.yStep = yStep;\n    this.stream = \"\"; // set by endTilingPattern();\n\n    this.cloneIndex = 0;\n    Pattern.call(this, gState, matrix);\n  }\n  /**\n   * Creates new jsPDF document object instance.\n   * @name jsPDF\n   * @class\n   * @param {Object} [options] - Collection of settings initializing the jsPDF-instance\n   * @param {string} [options.orientation=portrait] - Orientation of the first page. Possible values are \"portrait\" or \"landscape\" (or shortcuts \"p\" or \"l\").<br />\n   * @param {string} [options.unit=mm] Measurement unit (base unit) to be used when coordinates are specified.<br />\n   * Possible values are \"pt\" (points), \"mm\", \"cm\", \"in\", \"px\", \"pc\", \"em\" or \"ex\". Note that in order to get the correct scaling for \"px\"\n   * units, you need to enable the hotfix \"px_scaling\" by setting options.hotfixes = [\"px_scaling\"].\n   * @param {string/Array} [options.format=a4] The format of the first page. Can be:<ul><li>a0 - a10</li><li>b0 - b10</li><li>c0 - c10</li><li>dl</li><li>letter</li><li>government-letter</li><li>legal</li><li>junior-legal</li><li>ledger</li><li>tabloid</li><li>credit-card</li></ul><br />\n   * Default is \"a4\". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array, e.g. [595.28, 841.89]\n   * @param {boolean} [options.putOnlyUsedFonts=false] Only put fonts into the PDF, which were used.\n   * @param {boolean} [options.compress=false] Compress the generated PDF.\n   * @param {number} [options.precision=16] Precision of the element-positions.\n   * @param {number} [options.userUnit=1.0] Not to be confused with the base unit. Please inform yourself before you use it.\n   * @param {string[]} [options.hotfixes] An array of strings to enable hotfixes such as correct pixel scaling.\n   * @param {Object} [options.encryption]\n   * @param {string} [options.encryption.userPassword] Password for the user bound by the given permissions list.\n   * @param {string} [options.encryption.ownerPassword] Both userPassword and ownerPassword should be set for proper authentication.\n   * @param {string[]} [options.encryption.userPermissions] Array of permissions \"print\", \"modify\", \"copy\", \"annot-forms\", accessible by the user.\n   * @param {number|\"smart\"} [options.floatPrecision=16]\n   * @returns {jsPDF} jsPDF-instance\n   * @description\n   * ```\n   * {\n   *  orientation: 'p',\n   *  unit: 'mm',\n   *  format: 'a4',\n   *  putOnlyUsedFonts:true,\n   *  floatPrecision: 16 // or \"smart\", default is 16\n   * }\n   * ```\n   *\n   * @constructor\n   */\n\n\n  function jsPDF(options) {\n    var orientation = typeof arguments[0] === \"string\" ? arguments[0] : \"p\";\n    var unit = arguments[1];\n    var format = arguments[2];\n    var compressPdf = arguments[3];\n    var filters = [];\n    var userUnit = 1.0;\n    var precision;\n    var floatPrecision = 16;\n    var defaultPathOperation = \"S\";\n    var encryptionOptions = null;\n    options = options || {};\n\n    if (_typeof(options) === \"object\") {\n      orientation = options.orientation;\n      unit = options.unit || unit;\n      format = options.format || format;\n      compressPdf = options.compress || options.compressPdf || compressPdf;\n      encryptionOptions = options.encryption || null;\n\n      if (encryptionOptions !== null) {\n        encryptionOptions.userPassword = encryptionOptions.userPassword || \"\";\n        encryptionOptions.ownerPassword = encryptionOptions.ownerPassword || \"\";\n        encryptionOptions.userPermissions = encryptionOptions.userPermissions || [];\n      }\n\n      userUnit = typeof options.userUnit === \"number\" ? Math.abs(options.userUnit) : 1.0;\n\n      if (typeof options.precision !== \"undefined\") {\n        precision = options.precision;\n      }\n\n      if (typeof options.floatPrecision !== \"undefined\") {\n        floatPrecision = options.floatPrecision;\n      }\n\n      defaultPathOperation = options.defaultPathOperation || \"S\";\n    }\n\n    filters = options.filters || (compressPdf === true ? [\"FlateEncode\"] : filters);\n    unit = unit || \"mm\";\n    orientation = (\"\" + (orientation || \"P\")).toLowerCase();\n    var putOnlyUsedFonts = options.putOnlyUsedFonts || false;\n    var usedFonts = {};\n    var API = {\n      internal: {},\n      __private__: {}\n    };\n    API.__private__.PubSub = PubSub;\n    var pdfVersion = \"1.3\";\n\n    var getPdfVersion = API.__private__.getPdfVersion = function () {\n      return pdfVersion;\n    };\n\n    API.__private__.setPdfVersion = function (value) {\n      pdfVersion = value;\n    }; // Size in pt of various paper formats\n\n\n    var pageFormats = {\n      a0: [2383.94, 3370.39],\n      a1: [1683.78, 2383.94],\n      a2: [1190.55, 1683.78],\n      a3: [841.89, 1190.55],\n      a4: [595.28, 841.89],\n      a5: [419.53, 595.28],\n      a6: [297.64, 419.53],\n      a7: [209.76, 297.64],\n      a8: [147.4, 209.76],\n      a9: [104.88, 147.4],\n      a10: [73.7, 104.88],\n      b0: [2834.65, 4008.19],\n      b1: [2004.09, 2834.65],\n      b2: [1417.32, 2004.09],\n      b3: [1000.63, 1417.32],\n      b4: [708.66, 1000.63],\n      b5: [498.9, 708.66],\n      b6: [354.33, 498.9],\n      b7: [249.45, 354.33],\n      b8: [175.75, 249.45],\n      b9: [124.72, 175.75],\n      b10: [87.87, 124.72],\n      c0: [2599.37, 3676.54],\n      c1: [1836.85, 2599.37],\n      c2: [1298.27, 1836.85],\n      c3: [918.43, 1298.27],\n      c4: [649.13, 918.43],\n      c5: [459.21, 649.13],\n      c6: [323.15, 459.21],\n      c7: [229.61, 323.15],\n      c8: [161.57, 229.61],\n      c9: [113.39, 161.57],\n      c10: [79.37, 113.39],\n      dl: [311.81, 623.62],\n      letter: [612, 792],\n      \"government-letter\": [576, 756],\n      legal: [612, 1008],\n      \"junior-legal\": [576, 360],\n      ledger: [1224, 792],\n      tabloid: [792, 1224],\n      \"credit-card\": [153, 243]\n    };\n\n    API.__private__.getPageFormats = function () {\n      return pageFormats;\n    };\n\n    var getPageFormat = API.__private__.getPageFormat = function (value) {\n      return pageFormats[value];\n    };\n\n    format = format || \"a4\";\n    var ApiMode = {\n      COMPAT: \"compat\",\n      ADVANCED: \"advanced\"\n    };\n    var apiMode = ApiMode.COMPAT;\n\n    function advancedAPI() {\n      // prepend global change of basis matrix\n      // (Now, instead of converting every coordinate to the pdf coordinate system, we apply a matrix\n      // that does this job for us (however, texts, images and similar objects must be drawn bottom up))\n      this.saveGraphicsState();\n      out(new Matrix(scaleFactor, 0, 0, -scaleFactor, 0, getPageHeight() * scaleFactor).toString() + \" cm\");\n      this.setFontSize(this.getFontSize() / scaleFactor); // The default in MrRio's implementation is \"S\" (stroke), whereas the default in the yWorks implementation\n      // was \"n\" (none). Although this has nothing to do with transforms, we should use the API switch here.\n\n      defaultPathOperation = \"n\";\n      apiMode = ApiMode.ADVANCED;\n    }\n\n    function compatAPI() {\n      this.restoreGraphicsState();\n      defaultPathOperation = \"S\";\n      apiMode = ApiMode.COMPAT;\n    }\n    /**\n     * @function combineFontStyleAndFontWeight\n     * @param {string} fontStyle Fontstyle or variant. Example: \"italic\".\n     * @param {number | string} fontWeight Weight of the Font. Example: \"normal\" | 400\n     * @returns {string}\n     * @private\n     */\n\n\n    var combineFontStyleAndFontWeight = API.__private__.combineFontStyleAndFontWeight = function (fontStyle, fontWeight) {\n      if (fontStyle == \"bold\" && fontWeight == \"normal\" || fontStyle == \"bold\" && fontWeight == 400 || fontStyle == \"normal\" && fontWeight == \"italic\" || fontStyle == \"bold\" && fontWeight == \"italic\") {\n        throw new Error(\"Invalid Combination of fontweight and fontstyle\");\n      }\n\n      if (fontWeight) {\n        fontStyle = fontWeight == 400 || fontWeight === \"normal\" ? fontStyle === \"italic\" ? \"italic\" : \"normal\" : (fontWeight == 700 || fontWeight === \"bold\") && fontStyle === \"normal\" ? \"bold\" : (fontWeight == 700 ? \"bold\" : fontWeight) + \"\" + fontStyle;\n      }\n\n      return fontStyle;\n    };\n    /**\n     * @callback ApiSwitchBody\n     * @param {jsPDF} pdf\n     */\n\n    /**\n     * For compatibility reasons jsPDF offers two API modes which differ in the way they convert between the the usual\n     * screen coordinates and the PDF coordinate system.\n     *   - \"compat\": Offers full compatibility across all plugins but does not allow arbitrary transforms\n     *   - \"advanced\": Allows arbitrary transforms and more advanced features like pattern fills. Some plugins might\n     *     not support this mode, though.\n     * Initial mode is \"compat\".\n     *\n     * You can either provide a callback to the body argument, which means that jsPDF will automatically switch back to\n     * the original API mode afterwards; or you can omit the callback and switch back manually using {@link compatAPI}.\n     *\n     * Note, that the calls to {@link saveGraphicsState} and {@link restoreGraphicsState} need to be balanced within the\n     * callback or between calls of this method and its counterpart {@link compatAPI}. Calls to {@link beginFormObject}\n     * or {@link beginTilingPattern} need to be closed by their counterparts before switching back to \"compat\" API mode.\n     *\n     * @param {ApiSwitchBody=} body When provided, this callback will be called after the API mode has been switched.\n     * The API mode will be switched back automatically afterwards.\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name advancedAPI\n     */\n\n\n    API.advancedAPI = function (body) {\n      var doSwitch = apiMode === ApiMode.COMPAT;\n\n      if (doSwitch) {\n        advancedAPI.call(this);\n      }\n\n      if (typeof body !== \"function\") {\n        return this;\n      }\n\n      body(this);\n\n      if (doSwitch) {\n        compatAPI.call(this);\n      }\n\n      return this;\n    };\n    /**\n     * Switches to \"compat\" API mode. See {@link advancedAPI} for more details.\n     *\n     * @param {ApiSwitchBody=} body When provided, this callback will be called after the API mode has been switched.\n     * The API mode will be switched back automatically afterwards.\n     * @return {jsPDF}\n     * @memberof jsPDF#\n     * @name compatApi\n     */\n\n\n    API.compatAPI = function (body) {\n      var doSwitch = apiMode === ApiMode.ADVANCED;\n\n      if (doSwitch) {\n        compatAPI.call(this);\n      }\n\n      if (typeof body !== \"function\") {\n        return this;\n      }\n\n      body(this);\n\n      if (doSwitch) {\n        advancedAPI.call(this);\n      }\n\n      return this;\n    };\n    /**\n     * @return {boolean} True iff the current API mode is \"advanced\". See {@link advancedAPI}.\n     * @memberof jsPDF#\n     * @name isAdvancedAPI\n     */\n\n\n    API.isAdvancedAPI = function () {\n      return apiMode === ApiMode.ADVANCED;\n    };\n\n    var advancedApiModeTrap = function advancedApiModeTrap(methodName) {\n      if (apiMode !== ApiMode.ADVANCED) {\n        throw new Error(methodName + \" is only available in 'advanced' API mode. \" + \"You need to call advancedAPI() first.\");\n      }\n    };\n\n    var roundToPrecision = API.roundToPrecision = API.__private__.roundToPrecision = function (number, parmPrecision) {\n      var tmpPrecision = precision || parmPrecision;\n\n      if (isNaN(number) || isNaN(tmpPrecision)) {\n        throw new Error(\"Invalid argument passed to jsPDF.roundToPrecision\");\n      }\n\n      return number.toFixed(tmpPrecision).replace(/0+$/, \"\");\n    }; // high precision float\n\n\n    var hpf;\n\n    if (typeof floatPrecision === \"number\") {\n      hpf = API.hpf = API.__private__.hpf = function (number) {\n        if (isNaN(number)) {\n          throw new Error(\"Invalid argument passed to jsPDF.hpf\");\n        }\n\n        return roundToPrecision(number, floatPrecision);\n      };\n    } else if (floatPrecision === \"smart\") {\n      hpf = API.hpf = API.__private__.hpf = function (number) {\n        if (isNaN(number)) {\n          throw new Error(\"Invalid argument passed to jsPDF.hpf\");\n        }\n\n        if (number > -1 && number < 1) {\n          return roundToPrecision(number, 16);\n        } else {\n          return roundToPrecision(number, 5);\n        }\n      };\n    } else {\n      hpf = API.hpf = API.__private__.hpf = function (number) {\n        if (isNaN(number)) {\n          throw new Error(\"Invalid argument passed to jsPDF.hpf\");\n        }\n\n        return roundToPrecision(number, 16);\n      };\n    }\n\n    var f2 = API.f2 = API.__private__.f2 = function (number) {\n      if (isNaN(number)) {\n        throw new Error(\"Invalid argument passed to jsPDF.f2\");\n      }\n\n      return roundToPrecision(number, 2);\n    };\n\n    var f3 = API.__private__.f3 = function (number) {\n      if (isNaN(number)) {\n        throw new Error(\"Invalid argument passed to jsPDF.f3\");\n      }\n\n      return roundToPrecision(number, 3);\n    };\n\n    var scale = API.scale = API.__private__.scale = function (number) {\n      if (isNaN(number)) {\n        throw new Error(\"Invalid argument passed to jsPDF.scale\");\n      }\n\n      if (apiMode === ApiMode.COMPAT) {\n        return number * scaleFactor;\n      } else if (apiMode === ApiMode.ADVANCED) {\n        return number;\n      }\n    };\n\n    var transformY = function transformY(y) {\n      if (apiMode === ApiMode.COMPAT) {\n        return getPageHeight() - y;\n      } else if (apiMode === ApiMode.ADVANCED) {\n        return y;\n      }\n    };\n\n    var transformScaleY = function transformScaleY(y) {\n      return scale(transformY(y));\n    };\n    /**\n     * @name setPrecision\n     * @memberof jsPDF#\n     * @function\n     * @instance\n     * @param {string} precision\n     * @returns {jsPDF}\n     */\n\n\n    API.__private__.setPrecision = API.setPrecision = function (value) {\n      if (typeof parseInt(value, 10) === \"number\") {\n        precision = parseInt(value, 10);\n      }\n    };\n\n    var fileId = \"00000000000000000000000000000000\";\n\n    var getFileId = API.__private__.getFileId = function () {\n      return fileId;\n    };\n\n    var setFileId = API.__private__.setFileId = function (value) {\n      if (typeof value !== \"undefined\" && /^[a-fA-F0-9]{32}$/.test(value)) {\n        fileId = value.toUpperCase();\n      } else {\n        fileId = fileId.split(\"\").map(function () {\n          return \"ABCDEF0123456789\".charAt(Math.floor(Math.random() * 16));\n        }).join(\"\");\n      }\n\n      if (encryptionOptions !== null) {\n        encryption = new PDFSecurity(encryptionOptions.userPermissions, encryptionOptions.userPassword, encryptionOptions.ownerPassword, fileId);\n      }\n\n      return fileId;\n    };\n    /**\n     * @name setFileId\n     * @memberof jsPDF#\n     * @function\n     * @instance\n     * @param {string} value GUID.\n     * @returns {jsPDF}\n     */\n\n\n    API.setFileId = function (value) {\n      setFileId(value);\n      return this;\n    };\n    /**\n     * @name getFileId\n     * @memberof jsPDF#\n     * @function\n     * @instance\n     *\n     * @returns {string} GUID.\n     */\n\n\n    API.getFileId = function () {\n      return getFileId();\n    };\n\n    var creationDate;\n\n    var convertDateToPDFDate = API.__private__.convertDateToPDFDate = function (parmDate) {\n      var result = \"\";\n      var tzoffset = parmDate.getTimezoneOffset(),\n          tzsign = tzoffset < 0 ? \"+\" : \"-\",\n          tzhour = Math.floor(Math.abs(tzoffset / 60)),\n          tzmin = Math.abs(tzoffset % 60),\n          timeZoneString = [tzsign, padd2(tzhour), \"'\", padd2(tzmin), \"'\"].join(\"\");\n      result = [\"D:\", parmDate.getFullYear(), padd2(parmDate.getMonth() + 1), padd2(parmDate.getDate()), padd2(parmDate.getHours()), padd2(parmDate.getMinutes()), padd2(parmDate.getSeconds()), timeZoneString].join(\"\");\n      return result;\n    };\n\n    var convertPDFDateToDate = API.__private__.convertPDFDateToDate = function (parmPDFDate) {\n      var year = parseInt(parmPDFDate.substr(2, 4), 10);\n      var month = parseInt(parmPDFDate.substr(6, 2), 10) - 1;\n      var date = parseInt(parmPDFDate.substr(8, 2), 10);\n      var hour = parseInt(parmPDFDate.substr(10, 2), 10);\n      var minutes = parseInt(parmPDFDate.substr(12, 2), 10);\n      var seconds = parseInt(parmPDFDate.substr(14, 2), 10); // var timeZoneHour = parseInt(parmPDFDate.substr(16, 2), 10);\n      // var timeZoneMinutes = parseInt(parmPDFDate.substr(20, 2), 10);\n\n      var resultingDate = new Date(year, month, date, hour, minutes, seconds, 0);\n      return resultingDate;\n    };\n\n    var setCreationDate = API.__private__.setCreationDate = function (date) {\n      var tmpCreationDateString;\n      var regexPDFCreationDate = /^D:(20[0-2][0-9]|203[0-7]|19[7-9][0-9])(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])(0[0-9]|1[0-9]|2[0-3])(0[0-9]|[1-5][0-9])(0[0-9]|[1-5][0-9])(\\+0[0-9]|\\+1[0-4]|-0[0-9]|-1[0-1])'(0[0-9]|[1-5][0-9])'?$/;\n\n      if (typeof date === \"undefined\") {\n        date = new Date();\n      }\n\n      if (date instanceof Date) {\n        tmpCreationDateString = convertDateToPDFDate(date);\n      } else if (regexPDFCreationDate.test(date)) {\n        tmpCreationDateString = date;\n      } else {\n        throw new Error(\"Invalid argument passed to jsPDF.setCreationDate\");\n      }\n\n      creationDate = tmpCreationDateString;\n      return creationDate;\n    };\n\n    var getCreationDate = API.__private__.getCreationDate = function (type) {\n      var result = creationDate;\n\n      if (type === \"jsDate\") {\n        result = convertPDFDateToDate(creationDate);\n      }\n\n      return result;\n    };\n    /**\n     * @name setCreationDate\n     * @memberof jsPDF#\n     * @function\n     * @instance\n     * @param {Object} date\n     * @returns {jsPDF}\n     */\n\n\n    API.setCreationDate = function (date) {\n      setCreationDate(date);\n      return this;\n    };\n    /**\n     * @name getCreationDate\n     * @memberof jsPDF#\n     * @function\n     * @instance\n     * @param {Object} type\n     * @returns {Object}\n     */\n\n\n    API.getCreationDate = function (type) {\n      return getCreationDate(type);\n    };\n\n    var padd2 = API.__private__.padd2 = function (number) {\n      return (\"0\" + parseInt(number)).slice(-2);\n    };\n\n    var padd2Hex = API.__private__.padd2Hex = function (hexString) {\n      hexString = hexString.toString();\n      return (\"00\" + hexString).substr(hexString.length);\n    };\n\n    var objectNumber = 0; // 'n' Current object number\n\n    var offsets = []; // List of offsets. Activated and reset by buildDocument(). Pupulated by various calls buildDocument makes.\n\n    var content = [];\n    var contentLength = 0;\n    var additionalObjects = [];\n    var pages = [];\n    var currentPage;\n    var hasCustomDestination = false;\n    var outputDestination = content;\n\n    var resetDocument = function resetDocument() {\n      //reset fields relevant for objectNumber generation and xref.\n      objectNumber = 0;\n      contentLength = 0;\n      content = [];\n      offsets = [];\n      additionalObjects = [];\n      rootDictionaryObjId = newObjectDeferred();\n      resourceDictionaryObjId = newObjectDeferred();\n    };\n\n    API.__private__.setCustomOutputDestination = function (destination) {\n      hasCustomDestination = true;\n      outputDestination = destination;\n    };\n\n    var setOutputDestination = function setOutputDestination(destination) {\n      if (!hasCustomDestination) {\n        outputDestination = destination;\n      }\n    };\n\n    API.__private__.resetCustomOutputDestination = function () {\n      hasCustomDestination = false;\n      outputDestination = content;\n    };\n\n    var out = API.__private__.out = function (string) {\n      string = string.toString();\n      contentLength += string.length + 1;\n      outputDestination.push(string);\n      return outputDestination;\n    };\n\n    var write = API.__private__.write = function (value) {\n      return out(arguments.length === 1 ? value.toString() : Array.prototype.join.call(arguments, \" \"));\n    };\n\n    var getArrayBuffer = API.__private__.getArrayBuffer = function (data) {\n      var len = data.length,\n          ab = new ArrayBuffer(len),\n          u8 = new Uint8Array(ab);\n\n      while (len--) {\n        u8[len] = data.charCodeAt(len);\n      }\n\n      return ab;\n    };\n\n    var standardFonts = [[\"Helvetica\", \"helvetica\", \"normal\", \"WinAnsiEncoding\"], [\"Helvetica-Bold\", \"helvetica\", \"bold\", \"WinAnsiEncoding\"], [\"Helvetica-Oblique\", \"helvetica\", \"italic\", \"WinAnsiEncoding\"], [\"Helvetica-BoldOblique\", \"helvetica\", \"bolditalic\", \"WinAnsiEncoding\"], [\"Courier\", \"courier\", \"normal\", \"WinAnsiEncoding\"], [\"Courier-Bold\", \"courier\", \"bold\", \"WinAnsiEncoding\"], [\"Courier-Oblique\", \"courier\", \"italic\", \"WinAnsiEncoding\"], [\"Courier-BoldOblique\", \"courier\", \"bolditalic\", \"WinAnsiEncoding\"], [\"Times-Roman\", \"times\", \"normal\", \"WinAnsiEncoding\"], [\"Times-Bold\", \"times\", \"bold\", \"WinAnsiEncoding\"], [\"Times-Italic\", \"times\", \"italic\", \"WinAnsiEncoding\"], [\"Times-BoldItalic\", \"times\", \"bolditalic\", \"WinAnsiEncoding\"], [\"ZapfDingbats\", \"zapfdingbats\", \"normal\", null], [\"Symbol\", \"symbol\", \"normal\", null]];\n\n    API.__private__.getStandardFonts = function () {\n      return standardFonts;\n    };\n\n    var activeFontSize = options.fontSize || 16;\n    /**\n     * Sets font size for upcoming text elements.\n     *\n     * @param {number} size Font size in points.\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name setFontSize\n     */\n\n    API.__private__.setFontSize = API.setFontSize = function (size) {\n      if (apiMode === ApiMode.ADVANCED) {\n        activeFontSize = size / scaleFactor;\n      } else {\n        activeFontSize = size;\n      }\n\n      return this;\n    };\n    /**\n     * Gets the fontsize for upcoming text elements.\n     *\n     * @function\n     * @instance\n     * @returns {number}\n     * @memberof jsPDF#\n     * @name getFontSize\n     */\n\n\n    var getFontSize = API.__private__.getFontSize = API.getFontSize = function () {\n      if (apiMode === ApiMode.COMPAT) {\n        return activeFontSize;\n      } else {\n        return activeFontSize * scaleFactor;\n      }\n    };\n\n    var R2L = options.R2L || false;\n    /**\n     * Set value of R2L functionality.\n     *\n     * @param {boolean} value\n     * @function\n     * @instance\n     * @returns {jsPDF} jsPDF-instance\n     * @memberof jsPDF#\n     * @name setR2L\n     */\n\n    API.__private__.setR2L = API.setR2L = function (value) {\n      R2L = value;\n      return this;\n    };\n    /**\n     * Get value of R2L functionality.\n     *\n     * @function\n     * @instance\n     * @returns {boolean} jsPDF-instance\n     * @memberof jsPDF#\n     * @name getR2L\n     */\n\n\n    API.__private__.getR2L = API.getR2L = function () {\n      return R2L;\n    };\n\n    var zoomMode; // default: 1;\n\n    var setZoomMode = API.__private__.setZoomMode = function (zoom) {\n      var validZoomModes = [undefined, null, \"fullwidth\", \"fullheight\", \"fullpage\", \"original\"];\n\n      if (/^(?:\\d+\\.\\d*|\\d*\\.\\d+|\\d+)%$/.test(zoom)) {\n        zoomMode = zoom;\n      } else if (!isNaN(zoom)) {\n        zoomMode = parseInt(zoom, 10);\n      } else if (validZoomModes.indexOf(zoom) !== -1) {\n        zoomMode = zoom;\n      } else {\n        throw new Error('zoom must be Integer (e.g. 2), a percentage Value (e.g. 300%) or fullwidth, fullheight, fullpage, original. \"' + zoom + '\" is not recognized.');\n      }\n    };\n\n    API.__private__.getZoomMode = function () {\n      return zoomMode;\n    };\n\n    var pageMode; // default: 'UseOutlines';\n\n    var setPageMode = API.__private__.setPageMode = function (pmode) {\n      var validPageModes = [undefined, null, \"UseNone\", \"UseOutlines\", \"UseThumbs\", \"FullScreen\"];\n\n      if (validPageModes.indexOf(pmode) == -1) {\n        throw new Error('Page mode must be one of UseNone, UseOutlines, UseThumbs, or FullScreen. \"' + pmode + '\" is not recognized.');\n      }\n\n      pageMode = pmode;\n    };\n\n    API.__private__.getPageMode = function () {\n      return pageMode;\n    };\n\n    var layoutMode; // default: 'continuous';\n\n    var setLayoutMode = API.__private__.setLayoutMode = function (layout) {\n      var validLayoutModes = [undefined, null, \"continuous\", \"single\", \"twoleft\", \"tworight\", \"two\"];\n\n      if (validLayoutModes.indexOf(layout) == -1) {\n        throw new Error('Layout mode must be one of continuous, single, twoleft, tworight. \"' + layout + '\" is not recognized.');\n      }\n\n      layoutMode = layout;\n    };\n\n    API.__private__.getLayoutMode = function () {\n      return layoutMode;\n    };\n    /**\n     * Set the display mode options of the page like zoom and layout.\n     *\n     * @name setDisplayMode\n     * @memberof jsPDF#\n     * @function\n     * @instance\n     * @param {integer|String} zoom   You can pass an integer or percentage as\n     * a string. 2 will scale the document up 2x, '200%' will scale up by the\n     * same amount. You can also set it to 'fullwidth', 'fullheight',\n     * 'fullpage', or 'original'.\n     *\n     * Only certain PDF readers support this, such as Adobe Acrobat.\n     *\n     * @param {string} layout Layout mode can be: 'continuous' - this is the\n     * default continuous scroll. 'single' - the single page mode only shows one\n     * page at a time. 'twoleft' - two column left mode, first page starts on\n     * the left, and 'tworight' - pages are laid out in two columns, with the\n     * first page on the right. This would be used for books.\n     * @param {string} pmode 'UseOutlines' - it shows the\n     * outline of the document on the left. 'UseThumbs' - shows thumbnails along\n     * the left. 'FullScreen' - prompts the user to enter fullscreen mode.\n     *\n     * @returns {jsPDF}\n     */\n\n\n    API.__private__.setDisplayMode = API.setDisplayMode = function (zoom, layout, pmode) {\n      setZoomMode(zoom);\n      setLayoutMode(layout);\n      setPageMode(pmode);\n      return this;\n    };\n\n    var documentProperties = {\n      title: \"\",\n      subject: \"\",\n      author: \"\",\n      keywords: \"\",\n      creator: \"\"\n    };\n\n    API.__private__.getDocumentProperty = function (key) {\n      if (Object.keys(documentProperties).indexOf(key) === -1) {\n        throw new Error(\"Invalid argument passed to jsPDF.getDocumentProperty\");\n      }\n\n      return documentProperties[key];\n    };\n\n    API.__private__.getDocumentProperties = function () {\n      return documentProperties;\n    };\n    /**\n     * Adds a properties to the PDF document.\n     *\n     * @param {Object} A property_name-to-property_value object structure.\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name setDocumentProperties\n     */\n\n\n    API.__private__.setDocumentProperties = API.setProperties = API.setDocumentProperties = function (properties) {\n      // copying only those properties we can render.\n      for (var property in documentProperties) {\n        if (documentProperties.hasOwnProperty(property) && properties[property]) {\n          documentProperties[property] = properties[property];\n        }\n      }\n\n      return this;\n    };\n\n    API.__private__.setDocumentProperty = function (key, value) {\n      if (Object.keys(documentProperties).indexOf(key) === -1) {\n        throw new Error(\"Invalid arguments passed to jsPDF.setDocumentProperty\");\n      }\n\n      return documentProperties[key] = value;\n    };\n\n    var fonts = {}; // collection of font objects, where key is fontKey - a dynamically created label for a given font.\n\n    var fontmap = {}; // mapping structure fontName > fontStyle > font key - performance layer. See addFont()\n\n    var activeFontKey; // will be string representing the KEY of the font as combination of fontName + fontStyle\n\n    var fontStateStack = []; //\n\n    var patterns = {}; // collection of pattern objects\n\n    var patternMap = {}; // see fonts\n\n    var gStates = {}; // collection of graphic state objects\n\n    var gStatesMap = {}; // see fonts\n\n    var activeGState = null;\n    var scaleFactor; // Scale factor\n\n    var page = 0;\n    var pagesContext = [];\n    var events = new PubSub(API);\n    var hotfixes = options.hotfixes || [];\n    var renderTargets = {};\n    var renderTargetMap = {};\n    var renderTargetStack = [];\n    var pageX;\n    var pageY;\n    var pageMatrix; // only used for FormObjects\n\n    /**\n     * A matrix object for 2D homogenous transformations: <br>\n     * | a b 0 | <br>\n     * | c d 0 | <br>\n     * | e f 1 | <br>\n     * pdf multiplies matrices righthand: v' = v x m1 x m2 x ...\n     *\n     * @class\n     * @name Matrix\n     * @param {number} sx\n     * @param {number} shy\n     * @param {number} shx\n     * @param {number} sy\n     * @param {number} tx\n     * @param {number} ty\n     * @constructor\n     */\n\n    var Matrix = function Matrix(sx, shy, shx, sy, tx, ty) {\n      if (!(this instanceof Matrix)) {\n        return new Matrix(sx, shy, shx, sy, tx, ty);\n      }\n\n      if (isNaN(sx)) sx = 1;\n      if (isNaN(shy)) shy = 0;\n      if (isNaN(shx)) shx = 0;\n      if (isNaN(sy)) sy = 1;\n      if (isNaN(tx)) tx = 0;\n      if (isNaN(ty)) ty = 0;\n      this._matrix = [sx, shy, shx, sy, tx, ty];\n    };\n    /**\n     * @name sx\n     * @memberof Matrix#\n     */\n\n\n    Object.defineProperty(Matrix.prototype, \"sx\", {\n      get: function get() {\n        return this._matrix[0];\n      },\n      set: function set(value) {\n        this._matrix[0] = value;\n      }\n    });\n    /**\n     * @name shy\n     * @memberof Matrix#\n     */\n\n    Object.defineProperty(Matrix.prototype, \"shy\", {\n      get: function get() {\n        return this._matrix[1];\n      },\n      set: function set(value) {\n        this._matrix[1] = value;\n      }\n    });\n    /**\n     * @name shx\n     * @memberof Matrix#\n     */\n\n    Object.defineProperty(Matrix.prototype, \"shx\", {\n      get: function get() {\n        return this._matrix[2];\n      },\n      set: function set(value) {\n        this._matrix[2] = value;\n      }\n    });\n    /**\n     * @name sy\n     * @memberof Matrix#\n     */\n\n    Object.defineProperty(Matrix.prototype, \"sy\", {\n      get: function get() {\n        return this._matrix[3];\n      },\n      set: function set(value) {\n        this._matrix[3] = value;\n      }\n    });\n    /**\n     * @name tx\n     * @memberof Matrix#\n     */\n\n    Object.defineProperty(Matrix.prototype, \"tx\", {\n      get: function get() {\n        return this._matrix[4];\n      },\n      set: function set(value) {\n        this._matrix[4] = value;\n      }\n    });\n    /**\n     * @name ty\n     * @memberof Matrix#\n     */\n\n    Object.defineProperty(Matrix.prototype, \"ty\", {\n      get: function get() {\n        return this._matrix[5];\n      },\n      set: function set(value) {\n        this._matrix[5] = value;\n      }\n    });\n    Object.defineProperty(Matrix.prototype, \"a\", {\n      get: function get() {\n        return this._matrix[0];\n      },\n      set: function set(value) {\n        this._matrix[0] = value;\n      }\n    });\n    Object.defineProperty(Matrix.prototype, \"b\", {\n      get: function get() {\n        return this._matrix[1];\n      },\n      set: function set(value) {\n        this._matrix[1] = value;\n      }\n    });\n    Object.defineProperty(Matrix.prototype, \"c\", {\n      get: function get() {\n        return this._matrix[2];\n      },\n      set: function set(value) {\n        this._matrix[2] = value;\n      }\n    });\n    Object.defineProperty(Matrix.prototype, \"d\", {\n      get: function get() {\n        return this._matrix[3];\n      },\n      set: function set(value) {\n        this._matrix[3] = value;\n      }\n    });\n    Object.defineProperty(Matrix.prototype, \"e\", {\n      get: function get() {\n        return this._matrix[4];\n      },\n      set: function set(value) {\n        this._matrix[4] = value;\n      }\n    });\n    Object.defineProperty(Matrix.prototype, \"f\", {\n      get: function get() {\n        return this._matrix[5];\n      },\n      set: function set(value) {\n        this._matrix[5] = value;\n      }\n    });\n    /**\n     * @name rotation\n     * @memberof Matrix#\n     */\n\n    Object.defineProperty(Matrix.prototype, \"rotation\", {\n      get: function get() {\n        return Math.atan2(this.shx, this.sx);\n      }\n    });\n    /**\n     * @name scaleX\n     * @memberof Matrix#\n     */\n\n    Object.defineProperty(Matrix.prototype, \"scaleX\", {\n      get: function get() {\n        return this.decompose().scale.sx;\n      }\n    });\n    /**\n     * @name scaleY\n     * @memberof Matrix#\n     */\n\n    Object.defineProperty(Matrix.prototype, \"scaleY\", {\n      get: function get() {\n        return this.decompose().scale.sy;\n      }\n    });\n    /**\n     * @name isIdentity\n     * @memberof Matrix#\n     */\n\n    Object.defineProperty(Matrix.prototype, \"isIdentity\", {\n      get: function get() {\n        if (this.sx !== 1) {\n          return false;\n        }\n\n        if (this.shy !== 0) {\n          return false;\n        }\n\n        if (this.shx !== 0) {\n          return false;\n        }\n\n        if (this.sy !== 1) {\n          return false;\n        }\n\n        if (this.tx !== 0) {\n          return false;\n        }\n\n        if (this.ty !== 0) {\n          return false;\n        }\n\n        return true;\n      }\n    });\n    /**\n     * Join the Matrix Values to a String\n     *\n     * @function join\n     * @param {string} separator Specifies a string to separate each pair of adjacent elements of the array. The separator is converted to a string if necessary. If omitted, the array elements are separated with a comma (\",\"). If separator is an empty string, all elements are joined without any characters in between them.\n     * @returns {string} A string with all array elements joined.\n     * @memberof Matrix#\n     */\n\n    Matrix.prototype.join = function (separator) {\n      return [this.sx, this.shy, this.shx, this.sy, this.tx, this.ty].map(hpf).join(separator);\n    };\n    /**\n     * Multiply the matrix with given Matrix\n     *\n     * @function multiply\n     * @param matrix\n     * @returns {Matrix}\n     * @memberof Matrix#\n     */\n\n\n    Matrix.prototype.multiply = function (matrix) {\n      var sx = matrix.sx * this.sx + matrix.shy * this.shx;\n      var shy = matrix.sx * this.shy + matrix.shy * this.sy;\n      var shx = matrix.shx * this.sx + matrix.sy * this.shx;\n      var sy = matrix.shx * this.shy + matrix.sy * this.sy;\n      var tx = matrix.tx * this.sx + matrix.ty * this.shx + this.tx;\n      var ty = matrix.tx * this.shy + matrix.ty * this.sy + this.ty;\n      return new Matrix(sx, shy, shx, sy, tx, ty);\n    };\n    /**\n     * @function decompose\n     * @memberof Matrix#\n     */\n\n\n    Matrix.prototype.decompose = function () {\n      var a = this.sx;\n      var b = this.shy;\n      var c = this.shx;\n      var d = this.sy;\n      var e = this.tx;\n      var f = this.ty;\n      var scaleX = Math.sqrt(a * a + b * b);\n      a /= scaleX;\n      b /= scaleX;\n      var shear = a * c + b * d;\n      c -= a * shear;\n      d -= b * shear;\n      var scaleY = Math.sqrt(c * c + d * d);\n      c /= scaleY;\n      d /= scaleY;\n      shear /= scaleY;\n\n      if (a * d < b * c) {\n        a = -a;\n        b = -b;\n        shear = -shear;\n        scaleX = -scaleX;\n      }\n\n      return {\n        scale: new Matrix(scaleX, 0, 0, scaleY, 0, 0),\n        translate: new Matrix(1, 0, 0, 1, e, f),\n        rotate: new Matrix(a, b, -b, a, 0, 0),\n        skew: new Matrix(1, 0, shear, 1, 0, 0)\n      };\n    };\n    /**\n     * @function toString\n     * @memberof Matrix#\n     */\n\n\n    Matrix.prototype.toString = function (parmPrecision) {\n      return this.join(\" \");\n    };\n    /**\n     * @function inversed\n     * @memberof Matrix#\n     */\n\n\n    Matrix.prototype.inversed = function () {\n      var a = this.sx,\n          b = this.shy,\n          c = this.shx,\n          d = this.sy,\n          e = this.tx,\n          f = this.ty;\n      var quot = 1 / (a * d - b * c);\n      var aInv = d * quot;\n      var bInv = -b * quot;\n      var cInv = -c * quot;\n      var dInv = a * quot;\n      var eInv = -aInv * e - cInv * f;\n      var fInv = -bInv * e - dInv * f;\n      return new Matrix(aInv, bInv, cInv, dInv, eInv, fInv);\n    };\n    /**\n     * @function applyToPoint\n     * @memberof Matrix#\n     */\n\n\n    Matrix.prototype.applyToPoint = function (pt) {\n      var x = pt.x * this.sx + pt.y * this.shx + this.tx;\n      var y = pt.x * this.shy + pt.y * this.sy + this.ty;\n      return new Point(x, y);\n    };\n    /**\n     * @function applyToRectangle\n     * @memberof Matrix#\n     */\n\n\n    Matrix.prototype.applyToRectangle = function (rect) {\n      var pt1 = this.applyToPoint(rect);\n      var pt2 = this.applyToPoint(new Point(rect.x + rect.w, rect.y + rect.h));\n      return new Rectangle(pt1.x, pt1.y, pt2.x - pt1.x, pt2.y - pt1.y);\n    };\n    /**\n     * Clone the Matrix\n     *\n     * @function clone\n     * @memberof Matrix#\n     * @name clone\n     * @instance\n     */\n\n\n    Matrix.prototype.clone = function () {\n      var sx = this.sx;\n      var shy = this.shy;\n      var shx = this.shx;\n      var sy = this.sy;\n      var tx = this.tx;\n      var ty = this.ty;\n      return new Matrix(sx, shy, shx, sy, tx, ty);\n    };\n\n    API.Matrix = Matrix;\n    /**\n     * Multiplies two matrices. (see {@link Matrix})\n     * @param {Matrix} m1\n     * @param {Matrix} m2\n     * @memberof jsPDF#\n     * @name matrixMult\n     */\n\n    var matrixMult = API.matrixMult = function (m1, m2) {\n      return m2.multiply(m1);\n    };\n    /**\n     * The identity matrix (equivalent to new Matrix(1, 0, 0, 1, 0, 0)).\n     * @type {Matrix}\n     * @memberof! jsPDF#\n     * @name identityMatrix\n     */\n\n\n    var identityMatrix = new Matrix(1, 0, 0, 1, 0, 0);\n    API.unitMatrix = API.identityMatrix = identityMatrix;\n    /**\n     * Adds a new pattern for later use.\n     * @param {String} key The key by it can be referenced later. The keys must be unique!\n     * @param {API.Pattern} pattern The pattern\n     */\n\n    var addPattern = function addPattern(key, pattern) {\n      // only add it if it is not already present (the keys provided by the user must be unique!)\n      if (patternMap[key]) return;\n      var prefix = pattern instanceof ShadingPattern ? \"Sh\" : \"P\";\n      var patternKey = prefix + (Object.keys(patterns).length + 1).toString(10);\n      pattern.id = patternKey;\n      patternMap[key] = patternKey;\n      patterns[patternKey] = pattern;\n      events.publish(\"addPattern\", pattern);\n    };\n    /**\n     * A pattern describing a shading pattern.\n     *\n     * Only available in \"advanced\" API mode.\n     *\n     * @param {String} type One of \"axial\" or \"radial\"\n     * @param {Array<Number>} coords Either [x1, y1, x2, y2] for \"axial\" type describing the two interpolation points\n     * or [x1, y1, r, x2, y2, r2] for \"radial\" describing inner and the outer circle.\n     * @param {Array<Object>} colors An array of objects with the fields \"offset\" and \"color\". \"offset\" describes\n     * the offset in parameter space [0, 1]. \"color\" is an array of length 3 describing RGB values in [0, 255].\n     * @param {GState=} gState An additional graphics state that gets applied to the pattern (optional).\n     * @param {Matrix=} matrix A matrix that describes the transformation between the pattern coordinate system\n     * and the use coordinate system (optional).\n     * @constructor\n     * @extends API.Pattern\n     */\n\n\n    API.ShadingPattern = ShadingPattern;\n    /**\n     * A PDF Tiling pattern.\n     *\n     * Only available in \"advanced\" API mode.\n     *\n     * @param {Array.<Number>} boundingBox The bounding box at which one pattern cell gets clipped.\n     * @param {Number} xStep Horizontal spacing between pattern cells.\n     * @param {Number} yStep Vertical spacing between pattern cells.\n     * @param {API.GState=} gState An additional graphics state that gets applied to the pattern (optional).\n     * @param {Matrix=} matrix A matrix that describes the transformation between the pattern coordinate system\n     * and the use coordinate system (optional).\n     * @constructor\n     * @extends API.Pattern\n     */\n\n    API.TilingPattern = TilingPattern;\n    /**\n     * Adds a new {@link API.ShadingPattern} for later use. Only available in \"advanced\" API mode.\n     * @param {String} key\n     * @param {Pattern} pattern\n     * @function\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name addPattern\n     */\n\n    API.addShadingPattern = function (key, pattern) {\n      advancedApiModeTrap(\"addShadingPattern()\");\n      addPattern(key, pattern);\n      return this;\n    };\n    /**\n     * Begins a new tiling pattern. All subsequent render calls are drawn to this pattern until {@link API.endTilingPattern}\n     * gets called. Only available in \"advanced\" API mode.\n     * @param {API.Pattern} pattern\n     * @memberof jsPDF#\n     * @name beginTilingPattern\n     */\n\n\n    API.beginTilingPattern = function (pattern) {\n      advancedApiModeTrap(\"beginTilingPattern()\");\n      beginNewRenderTarget(pattern.boundingBox[0], pattern.boundingBox[1], pattern.boundingBox[2] - pattern.boundingBox[0], pattern.boundingBox[3] - pattern.boundingBox[1], pattern.matrix);\n    };\n    /**\n     * Ends a tiling pattern and sets the render target to the one active before {@link API.beginTilingPattern} has been called.\n     *\n     * Only available in \"advanced\" API mode.\n     *\n     * @param {string} key A unique key that is used to reference this pattern at later use.\n     * @param {API.Pattern} pattern The pattern to end.\n     * @memberof jsPDF#\n     * @name endTilingPattern\n     */\n\n\n    API.endTilingPattern = function (key, pattern) {\n      advancedApiModeTrap(\"endTilingPattern()\"); // retrieve the stream\n\n      pattern.stream = pages[currentPage].join(\"\\n\");\n      addPattern(key, pattern);\n      events.publish(\"endTilingPattern\", pattern); // restore state from stack\n\n      renderTargetStack.pop().restore();\n    };\n\n    var newObject = API.__private__.newObject = function () {\n      var oid = newObjectDeferred();\n      newObjectDeferredBegin(oid, true);\n      return oid;\n    }; // Does not output the object.  The caller must call newObjectDeferredBegin(oid) before outputing any data\n\n\n    var newObjectDeferred = API.__private__.newObjectDeferred = function () {\n      objectNumber++;\n\n      offsets[objectNumber] = function () {\n        return contentLength;\n      };\n\n      return objectNumber;\n    };\n\n    var newObjectDeferredBegin = function newObjectDeferredBegin(oid, doOutput) {\n      doOutput = typeof doOutput === \"boolean\" ? doOutput : false;\n      offsets[oid] = contentLength;\n\n      if (doOutput) {\n        out(oid + \" 0 obj\");\n      }\n\n      return oid;\n    }; // Does not output the object until after the pages have been output.\n    // Returns an object containing the objectId and content.\n    // All pages have been added so the object ID can be estimated to start right after.\n    // This does not modify the current objectNumber;  It must be updated after the newObjects are output.\n\n\n    var newAdditionalObject = API.__private__.newAdditionalObject = function () {\n      var objId = newObjectDeferred();\n      var obj = {\n        objId: objId,\n        content: \"\"\n      };\n      additionalObjects.push(obj);\n      return obj;\n    };\n\n    var rootDictionaryObjId = newObjectDeferred();\n    var resourceDictionaryObjId = newObjectDeferred(); /////////////////////\n    // Private functions\n    /////////////////////\n\n    var decodeColorString = API.__private__.decodeColorString = function (color) {\n      var colorEncoded = color.split(\" \");\n\n      if (colorEncoded.length === 2 && (colorEncoded[1] === \"g\" || colorEncoded[1] === \"G\")) {\n        // convert grayscale value to rgb so that it can be converted to hex for consistency\n        var floatVal = parseFloat(colorEncoded[0]);\n        colorEncoded = [floatVal, floatVal, floatVal, \"r\"];\n      } else if (colorEncoded.length === 5 && (colorEncoded[4] === \"k\" || colorEncoded[4] === \"K\")) {\n        // convert CMYK values to rbg so that it can be converted to hex for consistency\n        var red = (1.0 - colorEncoded[0]) * (1.0 - colorEncoded[3]);\n        var green = (1.0 - colorEncoded[1]) * (1.0 - colorEncoded[3]);\n        var blue = (1.0 - colorEncoded[2]) * (1.0 - colorEncoded[3]);\n        colorEncoded = [red, green, blue, \"r\"];\n      }\n\n      var colorAsRGB = \"#\";\n\n      for (var i = 0; i < 3; i++) {\n        colorAsRGB += (\"0\" + Math.floor(parseFloat(colorEncoded[i]) * 255).toString(16)).slice(-2);\n      }\n\n      return colorAsRGB;\n    };\n\n    var encodeColorString = API.__private__.encodeColorString = function (options) {\n      var color;\n\n      if (typeof options === \"string\") {\n        options = {\n          ch1: options\n        };\n      }\n\n      var ch1 = options.ch1;\n      var ch2 = options.ch2;\n      var ch3 = options.ch3;\n      var ch4 = options.ch4;\n      var letterArray = options.pdfColorType === \"draw\" ? [\"G\", \"RG\", \"K\"] : [\"g\", \"rg\", \"k\"];\n\n      if (typeof ch1 === \"string\" && ch1.charAt(0) !== \"#\") {\n        var rgbColor = new RGBColor(ch1);\n\n        if (rgbColor.ok) {\n          ch1 = rgbColor.toHex();\n        } else if (!/^\\d*\\.?\\d*$/.test(ch1)) {\n          throw new Error('Invalid color \"' + ch1 + '\" passed to jsPDF.encodeColorString.');\n        }\n      } //convert short rgb to long form\n\n\n      if (typeof ch1 === \"string\" && /^#[0-9A-Fa-f]{3}$/.test(ch1)) {\n        ch1 = \"#\" + ch1[1] + ch1[1] + ch1[2] + ch1[2] + ch1[3] + ch1[3];\n      }\n\n      if (typeof ch1 === \"string\" && /^#[0-9A-Fa-f]{6}$/.test(ch1)) {\n        var hex = parseInt(ch1.substr(1), 16);\n        ch1 = hex >> 16 & 255;\n        ch2 = hex >> 8 & 255;\n        ch3 = hex & 255;\n      }\n\n      if (typeof ch2 === \"undefined\" || typeof ch4 === \"undefined\" && ch1 === ch2 && ch2 === ch3) {\n        // Gray color space.\n        if (typeof ch1 === \"string\") {\n          color = ch1 + \" \" + letterArray[0];\n        } else {\n          switch (options.precision) {\n            case 2:\n              color = f2(ch1 / 255) + \" \" + letterArray[0];\n              break;\n\n            case 3:\n            default:\n              color = f3(ch1 / 255) + \" \" + letterArray[0];\n          }\n        }\n      } else if (typeof ch4 === \"undefined\" || _typeof(ch4) === \"object\") {\n        // assume RGBA\n        if (ch4 && !isNaN(ch4.a)) {\n          //TODO Implement transparency.\n          //WORKAROUND use white for now, if transparent, otherwise handle as rgb\n          if (ch4.a === 0) {\n            color = [\"1.\", \"1.\", \"1.\", letterArray[1]].join(\" \");\n            return color;\n          }\n        } // assume RGB\n\n\n        if (typeof ch1 === \"string\") {\n          color = [ch1, ch2, ch3, letterArray[1]].join(\" \");\n        } else {\n          switch (options.precision) {\n            case 2:\n              color = [f2(ch1 / 255), f2(ch2 / 255), f2(ch3 / 255), letterArray[1]].join(\" \");\n              break;\n\n            default:\n            case 3:\n              color = [f3(ch1 / 255), f3(ch2 / 255), f3(ch3 / 255), letterArray[1]].join(\" \");\n          }\n        }\n      } else {\n        // assume CMYK\n        if (typeof ch1 === \"string\") {\n          color = [ch1, ch2, ch3, ch4, letterArray[2]].join(\" \");\n        } else {\n          switch (options.precision) {\n            case 2:\n              color = [f2(ch1), f2(ch2), f2(ch3), f2(ch4), letterArray[2]].join(\" \");\n              break;\n\n            case 3:\n            default:\n              color = [f3(ch1), f3(ch2), f3(ch3), f3(ch4), letterArray[2]].join(\" \");\n          }\n        }\n      }\n\n      return color;\n    };\n\n    var getFilters = API.__private__.getFilters = function () {\n      return filters;\n    };\n\n    var putStream = API.__private__.putStream = function (options) {\n      options = options || {};\n      var data = options.data || \"\";\n      var filters = options.filters || getFilters();\n      var alreadyAppliedFilters = options.alreadyAppliedFilters || [];\n      var addLength1 = options.addLength1 || false;\n      var valueOfLength1 = data.length;\n      var objectId = options.objectId;\n\n      var encryptor = function encryptor(data) {\n        return data;\n      };\n\n      if (encryptionOptions !== null && typeof objectId == \"undefined\") {\n        throw new Error(\"ObjectId must be passed to putStream for file encryption\");\n      }\n\n      if (encryptionOptions !== null) {\n        encryptor = encryption.encryptor(objectId, 0);\n      }\n\n      var processedData = {};\n\n      if (filters === true) {\n        filters = [\"FlateEncode\"];\n      }\n\n      var keyValues = options.additionalKeyValues || [];\n\n      if (typeof jsPDF.API.processDataByFilters !== \"undefined\") {\n        processedData = jsPDF.API.processDataByFilters(data, filters);\n      } else {\n        processedData = {\n          data: data,\n          reverseChain: []\n        };\n      }\n\n      var filterAsString = processedData.reverseChain + (Array.isArray(alreadyAppliedFilters) ? alreadyAppliedFilters.join(\" \") : alreadyAppliedFilters.toString());\n\n      if (processedData.data.length !== 0) {\n        keyValues.push({\n          key: \"Length\",\n          value: processedData.data.length\n        });\n\n        if (addLength1 === true) {\n          keyValues.push({\n            key: \"Length1\",\n            value: valueOfLength1\n          });\n        }\n      }\n\n      if (filterAsString.length != 0) {\n        if (filterAsString.split(\"/\").length - 1 === 1) {\n          keyValues.push({\n            key: \"Filter\",\n            value: filterAsString\n          });\n        } else {\n          keyValues.push({\n            key: \"Filter\",\n            value: \"[\" + filterAsString + \"]\"\n          });\n\n          for (var j = 0; j < keyValues.length; j += 1) {\n            if (keyValues[j].key === \"DecodeParms\") {\n              var decodeParmsArray = [];\n\n              for (var i = 0; i < processedData.reverseChain.split(\"/\").length - 1; i += 1) {\n                decodeParmsArray.push(\"null\");\n              }\n\n              decodeParmsArray.push(keyValues[j].value);\n              keyValues[j].value = \"[\" + decodeParmsArray.join(\" \") + \"]\";\n            }\n          }\n        }\n      }\n\n      out(\"<<\");\n\n      for (var k = 0; k < keyValues.length; k++) {\n        out(\"/\" + keyValues[k].key + \" \" + keyValues[k].value);\n      }\n\n      out(\">>\");\n\n      if (processedData.data.length !== 0) {\n        out(\"stream\");\n        out(encryptor(processedData.data));\n        out(\"endstream\");\n      }\n    };\n\n    var putPage = API.__private__.putPage = function (page) {\n      var pageNumber = page.number;\n      var data = page.data;\n      var pageObjectNumber = page.objId;\n      var pageContentsObjId = page.contentsObjId;\n      newObjectDeferredBegin(pageObjectNumber, true);\n      out(\"<</Type /Page\");\n      out(\"/Parent \" + page.rootDictionaryObjId + \" 0 R\");\n      out(\"/Resources \" + page.resourceDictionaryObjId + \" 0 R\");\n      out(\"/MediaBox [\" + parseFloat(hpf(page.mediaBox.bottomLeftX)) + \" \" + parseFloat(hpf(page.mediaBox.bottomLeftY)) + \" \" + hpf(page.mediaBox.topRightX) + \" \" + hpf(page.mediaBox.topRightY) + \"]\");\n\n      if (page.cropBox !== null) {\n        out(\"/CropBox [\" + hpf(page.cropBox.bottomLeftX) + \" \" + hpf(page.cropBox.bottomLeftY) + \" \" + hpf(page.cropBox.topRightX) + \" \" + hpf(page.cropBox.topRightY) + \"]\");\n      }\n\n      if (page.bleedBox !== null) {\n        out(\"/BleedBox [\" + hpf(page.bleedBox.bottomLeftX) + \" \" + hpf(page.bleedBox.bottomLeftY) + \" \" + hpf(page.bleedBox.topRightX) + \" \" + hpf(page.bleedBox.topRightY) + \"]\");\n      }\n\n      if (page.trimBox !== null) {\n        out(\"/TrimBox [\" + hpf(page.trimBox.bottomLeftX) + \" \" + hpf(page.trimBox.bottomLeftY) + \" \" + hpf(page.trimBox.topRightX) + \" \" + hpf(page.trimBox.topRightY) + \"]\");\n      }\n\n      if (page.artBox !== null) {\n        out(\"/ArtBox [\" + hpf(page.artBox.bottomLeftX) + \" \" + hpf(page.artBox.bottomLeftY) + \" \" + hpf(page.artBox.topRightX) + \" \" + hpf(page.artBox.topRightY) + \"]\");\n      }\n\n      if (typeof page.userUnit === \"number\" && page.userUnit !== 1.0) {\n        out(\"/UserUnit \" + page.userUnit);\n      }\n\n      events.publish(\"putPage\", {\n        objId: pageObjectNumber,\n        pageContext: pagesContext[pageNumber],\n        pageNumber: pageNumber,\n        page: data\n      });\n      out(\"/Contents \" + pageContentsObjId + \" 0 R\");\n      out(\">>\");\n      out(\"endobj\"); // Page content\n\n      var pageContent = data.join(\"\\n\");\n\n      if (apiMode === ApiMode.ADVANCED) {\n        // if the user forgot to switch back to COMPAT mode, we must balance the graphics stack again\n        pageContent += \"\\nQ\";\n      }\n\n      newObjectDeferredBegin(pageContentsObjId, true);\n      putStream({\n        data: pageContent,\n        filters: getFilters(),\n        objectId: pageContentsObjId\n      });\n      out(\"endobj\");\n      return pageObjectNumber;\n    };\n\n    var putPages = API.__private__.putPages = function () {\n      var n,\n          i,\n          pageObjectNumbers = [];\n\n      for (n = 1; n <= page; n++) {\n        pagesContext[n].objId = newObjectDeferred();\n        pagesContext[n].contentsObjId = newObjectDeferred();\n      }\n\n      for (n = 1; n <= page; n++) {\n        pageObjectNumbers.push(putPage({\n          number: n,\n          data: pages[n],\n          objId: pagesContext[n].objId,\n          contentsObjId: pagesContext[n].contentsObjId,\n          mediaBox: pagesContext[n].mediaBox,\n          cropBox: pagesContext[n].cropBox,\n          bleedBox: pagesContext[n].bleedBox,\n          trimBox: pagesContext[n].trimBox,\n          artBox: pagesContext[n].artBox,\n          userUnit: pagesContext[n].userUnit,\n          rootDictionaryObjId: rootDictionaryObjId,\n          resourceDictionaryObjId: resourceDictionaryObjId\n        }));\n      }\n\n      newObjectDeferredBegin(rootDictionaryObjId, true);\n      out(\"<</Type /Pages\");\n      var kids = \"/Kids [\";\n\n      for (i = 0; i < page; i++) {\n        kids += pageObjectNumbers[i] + \" 0 R \";\n      }\n\n      out(kids + \"]\");\n      out(\"/Count \" + page);\n      out(\">>\");\n      out(\"endobj\");\n      events.publish(\"postPutPages\");\n    };\n\n    var putFont = function putFont(font) {\n      events.publish(\"putFont\", {\n        font: font,\n        out: out,\n        newObject: newObject,\n        putStream: putStream\n      });\n\n      if (font.isAlreadyPutted !== true) {\n        font.objectNumber = newObject();\n        out(\"<<\");\n        out(\"/Type /Font\");\n        out(\"/BaseFont /\" + toPDFName(font.postScriptName));\n        out(\"/Subtype /Type1\");\n\n        if (typeof font.encoding === \"string\") {\n          out(\"/Encoding /\" + font.encoding);\n        }\n\n        out(\"/FirstChar 32\");\n        out(\"/LastChar 255\");\n        out(\">>\");\n        out(\"endobj\");\n      }\n    };\n\n    var putFonts = function putFonts() {\n      for (var fontKey in fonts) {\n        if (fonts.hasOwnProperty(fontKey)) {\n          if (putOnlyUsedFonts === false || putOnlyUsedFonts === true && usedFonts.hasOwnProperty(fontKey)) {\n            putFont(fonts[fontKey]);\n          }\n        }\n      }\n    };\n\n    var putXObject = function putXObject(xObject) {\n      xObject.objectNumber = newObject();\n      var options = [];\n      options.push({\n        key: \"Type\",\n        value: \"/XObject\"\n      });\n      options.push({\n        key: \"Subtype\",\n        value: \"/Form\"\n      });\n      options.push({\n        key: \"BBox\",\n        value: \"[\" + [hpf(xObject.x), hpf(xObject.y), hpf(xObject.x + xObject.width), hpf(xObject.y + xObject.height)].join(\" \") + \"]\"\n      });\n      options.push({\n        key: \"Matrix\",\n        value: \"[\" + xObject.matrix.toString() + \"]\"\n      }); // TODO: /Resources\n\n      var stream = xObject.pages[1].join(\"\\n\");\n      putStream({\n        data: stream,\n        additionalKeyValues: options,\n        objectId: xObject.objectNumber\n      });\n      out(\"endobj\");\n    };\n\n    var putXObjects = function putXObjects() {\n      for (var xObjectKey in renderTargets) {\n        if (renderTargets.hasOwnProperty(xObjectKey)) {\n          putXObject(renderTargets[xObjectKey]);\n        }\n      }\n    };\n\n    var interpolateAndEncodeRGBStream = function interpolateAndEncodeRGBStream(colors, numberSamples) {\n      var tValues = [];\n      var t;\n      var dT = 1.0 / (numberSamples - 1);\n\n      for (t = 0.0; t < 1.0; t += dT) {\n        tValues.push(t);\n      }\n\n      tValues.push(1.0); // add first and last control point if not present\n\n      if (colors[0].offset != 0.0) {\n        var c0 = {\n          offset: 0.0,\n          color: colors[0].color\n        };\n        colors.unshift(c0);\n      }\n\n      if (colors[colors.length - 1].offset != 1.0) {\n        var c1 = {\n          offset: 1.0,\n          color: colors[colors.length - 1].color\n        };\n        colors.push(c1);\n      }\n\n      var out = \"\";\n      var index = 0;\n\n      for (var i = 0; i < tValues.length; i++) {\n        t = tValues[i];\n\n        while (t > colors[index + 1].offset) {\n          index++;\n        }\n\n        var a = colors[index].offset;\n        var b = colors[index + 1].offset;\n        var d = (t - a) / (b - a);\n        var aColor = colors[index].color;\n        var bColor = colors[index + 1].color;\n        out += padd2Hex(Math.round((1 - d) * aColor[0] + d * bColor[0]).toString(16)) + padd2Hex(Math.round((1 - d) * aColor[1] + d * bColor[1]).toString(16)) + padd2Hex(Math.round((1 - d) * aColor[2] + d * bColor[2]).toString(16));\n      }\n\n      return out.trim();\n    };\n\n    var putShadingPattern = function putShadingPattern(pattern, numberSamples) {\n      /*\n         Axial patterns shade between the two points specified in coords, radial patterns between the inner\n         and outer circle.\n         The user can specify an array (colors) that maps t-Values in [0, 1] to RGB colors. These are now\n         interpolated to equidistant samples and written to pdf as a sample (type 0) function.\n         */\n      // The number of color samples that should be used to describe the shading.\n      // The higher, the more accurate the gradient will be.\n      numberSamples || (numberSamples = 21);\n      var funcObjectNumber = newObject();\n      var stream = interpolateAndEncodeRGBStream(pattern.colors, numberSamples);\n      var options = [];\n      options.push({\n        key: \"FunctionType\",\n        value: \"0\"\n      });\n      options.push({\n        key: \"Domain\",\n        value: \"[0.0 1.0]\"\n      });\n      options.push({\n        key: \"Size\",\n        value: \"[\" + numberSamples + \"]\"\n      });\n      options.push({\n        key: \"BitsPerSample\",\n        value: \"8\"\n      });\n      options.push({\n        key: \"Range\",\n        value: \"[0.0 1.0 0.0 1.0 0.0 1.0]\"\n      });\n      options.push({\n        key: \"Decode\",\n        value: \"[0.0 1.0 0.0 1.0 0.0 1.0]\"\n      });\n      putStream({\n        data: stream,\n        additionalKeyValues: options,\n        alreadyAppliedFilters: [\"/ASCIIHexDecode\"],\n        objectId: funcObjectNumber\n      });\n      out(\"endobj\");\n      pattern.objectNumber = newObject();\n      out(\"<< /ShadingType \" + pattern.type);\n      out(\"/ColorSpace /DeviceRGB\");\n      var coords = \"/Coords [\" + hpf(parseFloat(pattern.coords[0])) + \" \" + // x1\n      hpf(parseFloat(pattern.coords[1])) + \" \"; // y1\n\n      if (pattern.type === 2) {\n        // axial\n        coords += hpf(parseFloat(pattern.coords[2])) + \" \" + // x2\n        hpf(parseFloat(pattern.coords[3])); // y2\n      } else {\n        // radial\n        coords += hpf(parseFloat(pattern.coords[2])) + \" \" + // r1\n        hpf(parseFloat(pattern.coords[3])) + \" \" + // x2\n        hpf(parseFloat(pattern.coords[4])) + \" \" + // y2\n        hpf(parseFloat(pattern.coords[5])); // r2\n      }\n\n      coords += \"]\";\n      out(coords);\n\n      if (pattern.matrix) {\n        out(\"/Matrix [\" + pattern.matrix.toString() + \"]\");\n      }\n\n      out(\"/Function \" + funcObjectNumber + \" 0 R\");\n      out(\"/Extend [true true]\");\n      out(\">>\");\n      out(\"endobj\");\n    };\n\n    var putTilingPattern = function putTilingPattern(pattern, deferredResourceDictionaryIds) {\n      var resourcesObjectId = newObjectDeferred();\n      var patternObjectId = newObject();\n      deferredResourceDictionaryIds.push({\n        resourcesOid: resourcesObjectId,\n        objectOid: patternObjectId\n      });\n      pattern.objectNumber = patternObjectId;\n      var options = [];\n      options.push({\n        key: \"Type\",\n        value: \"/Pattern\"\n      });\n      options.push({\n        key: \"PatternType\",\n        value: \"1\"\n      }); // tiling pattern\n\n      options.push({\n        key: \"PaintType\",\n        value: \"1\"\n      }); // colored tiling pattern\n\n      options.push({\n        key: \"TilingType\",\n        value: \"1\"\n      }); // constant spacing\n\n      options.push({\n        key: \"BBox\",\n        value: \"[\" + pattern.boundingBox.map(hpf).join(\" \") + \"]\"\n      });\n      options.push({\n        key: \"XStep\",\n        value: hpf(pattern.xStep)\n      });\n      options.push({\n        key: \"YStep\",\n        value: hpf(pattern.yStep)\n      });\n      options.push({\n        key: \"Resources\",\n        value: resourcesObjectId + \" 0 R\"\n      });\n\n      if (pattern.matrix) {\n        options.push({\n          key: \"Matrix\",\n          value: \"[\" + pattern.matrix.toString() + \"]\"\n        });\n      }\n\n      putStream({\n        data: pattern.stream,\n        additionalKeyValues: options,\n        objectId: pattern.objectNumber\n      });\n      out(\"endobj\");\n    };\n\n    var putPatterns = function putPatterns(deferredResourceDictionaryIds) {\n      var patternKey;\n\n      for (patternKey in patterns) {\n        if (patterns.hasOwnProperty(patternKey)) {\n          if (patterns[patternKey] instanceof ShadingPattern) {\n            putShadingPattern(patterns[patternKey]);\n          } else if (patterns[patternKey] instanceof TilingPattern) {\n            putTilingPattern(patterns[patternKey], deferredResourceDictionaryIds);\n          }\n        }\n      }\n    };\n\n    var putGState = function putGState(gState) {\n      gState.objectNumber = newObject();\n      out(\"<<\");\n\n      for (var p in gState) {\n        switch (p) {\n          case \"opacity\":\n            out(\"/ca \" + f2(gState[p]));\n            break;\n\n          case \"stroke-opacity\":\n            out(\"/CA \" + f2(gState[p]));\n            break;\n        }\n      }\n\n      out(\">>\");\n      out(\"endobj\");\n    };\n\n    var putGStates = function putGStates() {\n      var gStateKey;\n\n      for (gStateKey in gStates) {\n        if (gStates.hasOwnProperty(gStateKey)) {\n          putGState(gStates[gStateKey]);\n        }\n      }\n    };\n\n    var putXobjectDict = function putXobjectDict() {\n      out(\"/XObject <<\");\n\n      for (var xObjectKey in renderTargets) {\n        if (renderTargets.hasOwnProperty(xObjectKey) && renderTargets[xObjectKey].objectNumber >= 0) {\n          out(\"/\" + xObjectKey + \" \" + renderTargets[xObjectKey].objectNumber + \" 0 R\");\n        }\n      } // Loop through images, or other data objects\n\n\n      events.publish(\"putXobjectDict\");\n      out(\">>\");\n    };\n\n    var putEncryptionDict = function putEncryptionDict() {\n      encryption.oid = newObject();\n      out(\"<<\");\n      out(\"/Filter /Standard\");\n      out(\"/V \" + encryption.v);\n      out(\"/R \" + encryption.r);\n      out(\"/U <\" + encryption.toHexString(encryption.U) + \">\");\n      out(\"/O <\" + encryption.toHexString(encryption.O) + \">\");\n      out(\"/P \" + encryption.P);\n      out(\">>\");\n      out(\"endobj\");\n    };\n\n    var putFontDict = function putFontDict() {\n      out(\"/Font <<\");\n\n      for (var fontKey in fonts) {\n        if (fonts.hasOwnProperty(fontKey)) {\n          if (putOnlyUsedFonts === false || putOnlyUsedFonts === true && usedFonts.hasOwnProperty(fontKey)) {\n            out(\"/\" + fontKey + \" \" + fonts[fontKey].objectNumber + \" 0 R\");\n          }\n        }\n      }\n\n      out(\">>\");\n    };\n\n    var putShadingPatternDict = function putShadingPatternDict() {\n      if (Object.keys(patterns).length > 0) {\n        out(\"/Shading <<\");\n\n        for (var patternKey in patterns) {\n          if (patterns.hasOwnProperty(patternKey) && patterns[patternKey] instanceof ShadingPattern && patterns[patternKey].objectNumber >= 0) {\n            out(\"/\" + patternKey + \" \" + patterns[patternKey].objectNumber + \" 0 R\");\n          }\n        }\n\n        events.publish(\"putShadingPatternDict\");\n        out(\">>\");\n      }\n    };\n\n    var putTilingPatternDict = function putTilingPatternDict(objectOid) {\n      if (Object.keys(patterns).length > 0) {\n        out(\"/Pattern <<\");\n\n        for (var patternKey in patterns) {\n          if (patterns.hasOwnProperty(patternKey) && patterns[patternKey] instanceof API.TilingPattern && patterns[patternKey].objectNumber >= 0 && patterns[patternKey].objectNumber < objectOid // prevent cyclic dependencies\n          ) {\n              out(\"/\" + patternKey + \" \" + patterns[patternKey].objectNumber + \" 0 R\");\n            }\n        }\n\n        events.publish(\"putTilingPatternDict\");\n        out(\">>\");\n      }\n    };\n\n    var putGStatesDict = function putGStatesDict() {\n      if (Object.keys(gStates).length > 0) {\n        var gStateKey;\n        out(\"/ExtGState <<\");\n\n        for (gStateKey in gStates) {\n          if (gStates.hasOwnProperty(gStateKey) && gStates[gStateKey].objectNumber >= 0) {\n            out(\"/\" + gStateKey + \" \" + gStates[gStateKey].objectNumber + \" 0 R\");\n          }\n        }\n\n        events.publish(\"putGStateDict\");\n        out(\">>\");\n      }\n    };\n\n    var putResourceDictionary = function putResourceDictionary(objectIds) {\n      newObjectDeferredBegin(objectIds.resourcesOid, true);\n      out(\"<<\");\n      out(\"/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\");\n      putFontDict();\n      putShadingPatternDict();\n      putTilingPatternDict(objectIds.objectOid);\n      putGStatesDict();\n      putXobjectDict();\n      out(\">>\");\n      out(\"endobj\");\n    };\n\n    var putResources = function putResources() {\n      // FormObjects, Patterns etc. might use other FormObjects/Patterns/Images\n      // which means their resource dictionaries must contain the already resolved\n      // object ids. For this reason we defer the serialization of the resource\n      // dicts until all objects have been serialized and have object ids.\n      //\n      // In order to prevent cyclic dependencies (which Adobe Reader doesn't like),\n      // we only put all oids that are smaller than the oid of the object the\n      // resource dict belongs to. This is correct behavior, since the streams\n      // may only use other objects that have already been defined and thus appear\n      // earlier in their respective collection.\n      // Currently, this only affects tiling patterns, but a (more) correct\n      // implementation of FormObjects would also define their own resource dicts.\n      var deferredResourceDictionaryIds = [];\n      putFonts();\n      putGStates();\n      putXObjects();\n      putPatterns(deferredResourceDictionaryIds);\n      events.publish(\"putResources\");\n      deferredResourceDictionaryIds.forEach(putResourceDictionary);\n      putResourceDictionary({\n        resourcesOid: resourceDictionaryObjId,\n        objectOid: Number.MAX_SAFE_INTEGER // output all objects\n\n      });\n      events.publish(\"postPutResources\");\n    };\n\n    var putAdditionalObjects = function putAdditionalObjects() {\n      events.publish(\"putAdditionalObjects\");\n\n      for (var i = 0; i < additionalObjects.length; i++) {\n        var obj = additionalObjects[i];\n        newObjectDeferredBegin(obj.objId, true);\n        out(obj.content);\n        out(\"endobj\");\n      }\n\n      events.publish(\"postPutAdditionalObjects\");\n    };\n\n    var addFontToFontDictionary = function addFontToFontDictionary(font) {\n      fontmap[font.fontName] = fontmap[font.fontName] || {};\n      fontmap[font.fontName][font.fontStyle] = font.id;\n    };\n\n    var addFont = function addFont(postScriptName, fontName, fontStyle, encoding, isStandardFont) {\n      var font = {\n        id: \"F\" + (Object.keys(fonts).length + 1).toString(10),\n        postScriptName: postScriptName,\n        fontName: fontName,\n        fontStyle: fontStyle,\n        encoding: encoding,\n        isStandardFont: isStandardFont || false,\n        metadata: {}\n      };\n      events.publish(\"addFont\", {\n        font: font,\n        instance: this\n      });\n      fonts[font.id] = font;\n      addFontToFontDictionary(font);\n      return font.id;\n    };\n\n    var addFonts = function addFonts(arrayOfFonts) {\n      for (var i = 0, l = standardFonts.length; i < l; i++) {\n        var fontKey = addFont.call(this, arrayOfFonts[i][0], arrayOfFonts[i][1], arrayOfFonts[i][2], standardFonts[i][3], true);\n\n        if (putOnlyUsedFonts === false) {\n          usedFonts[fontKey] = true;\n        } // adding aliases for standard fonts, this time matching the capitalization\n\n\n        var parts = arrayOfFonts[i][0].split(\"-\");\n        addFontToFontDictionary({\n          id: fontKey,\n          fontName: parts[0],\n          fontStyle: parts[1] || \"\"\n        });\n      }\n\n      events.publish(\"addFonts\", {\n        fonts: fonts,\n        dictionary: fontmap\n      });\n    };\n\n    var SAFE = function __safeCall(fn) {\n      fn.foo = function __safeCallWrapper() {\n        try {\n          return fn.apply(this, arguments);\n        } catch (e) {\n          var stack = e.stack || \"\";\n          if (~stack.indexOf(\" at \")) stack = stack.split(\" at \")[1];\n          var m = \"Error in function \" + stack.split(\"\\n\")[0].split(\"<\")[0] + \": \" + e.message;\n\n          if (globalObject.console) {\n            globalObject.console.error(m, e);\n            if (globalObject.alert) alert(m);\n          } else {\n            throw new Error(m);\n          }\n        }\n      };\n\n      fn.foo.bar = fn;\n      return fn.foo;\n    };\n\n    var to8bitStream = function to8bitStream(text, flags) {\n      /**\n       * PDF 1.3 spec:\n       * \"For text strings encoded in Unicode, the first two bytes must be 254 followed by\n       * 255, representing the Unicode byte order marker, U+FEFF. (This sequence conflicts\n       * with the PDFDocEncoding character sequence thorn ydieresis, which is unlikely\n       * to be a meaningful beginning of a word or phrase.) The remainder of the\n       * string consists of Unicode character codes, according to the UTF-16 encoding\n       * specified in the Unicode standard, version 2.0. Commonly used Unicode values\n       * are represented as 2 bytes per character, with the high-order byte appearing first\n       * in the string.\"\n       *\n       * In other words, if there are chars in a string with char code above 255, we\n       * recode the string to UCS2 BE - string doubles in length and BOM is prepended.\n       *\n       * HOWEVER!\n       * Actual *content* (body) text (as opposed to strings used in document properties etc)\n       * does NOT expect BOM. There, it is treated as a literal GID (Glyph ID)\n       *\n       * Because of Adobe's focus on \"you subset your fonts!\" you are not supposed to have\n       * a font that maps directly Unicode (UCS2 / UTF16BE) code to font GID, but you could\n       * fudge it with \"Identity-H\" encoding and custom CIDtoGID map that mimics Unicode\n       * code page. There, however, all characters in the stream are treated as GIDs,\n       * including BOM, which is the reason we need to skip BOM in content text (i.e. that\n       * that is tied to a font).\n       *\n       * To signal this \"special\" PDFEscape / to8bitStream handling mode,\n       * API.text() function sets (unless you overwrite it with manual values\n       * given to API.text(.., flags) )\n       * flags.autoencode = true\n       * flags.noBOM = true\n       *\n       * ===================================================================================\n       * `flags` properties relied upon:\n       *   .sourceEncoding = string with encoding label.\n       *                     \"Unicode\" by default. = encoding of the incoming text.\n       *                     pass some non-existing encoding name\n       *                     (ex: 'Do not touch my strings! I know what I am doing.')\n       *                     to make encoding code skip the encoding step.\n       *   .outputEncoding = Either valid PDF encoding name\n       *                     (must be supported by jsPDF font metrics, otherwise no encoding)\n       *                     or a JS object, where key = sourceCharCode, value = outputCharCode\n       *                     missing keys will be treated as: sourceCharCode === outputCharCode\n       *   .noBOM\n       *       See comment higher above for explanation for why this is important\n       *   .autoencode\n       *       See comment higher above for explanation for why this is important\n       */\n      var i, l, sourceEncoding, encodingBlock, outputEncoding, newtext, isUnicode, ch, bch;\n      flags = flags || {};\n      sourceEncoding = flags.sourceEncoding || \"Unicode\";\n      outputEncoding = flags.outputEncoding; // This 'encoding' section relies on font metrics format\n      // attached to font objects by, among others,\n      // \"Willow Systems' standard_font_metrics plugin\"\n      // see jspdf.plugin.standard_font_metrics.js for format\n      // of the font.metadata.encoding Object.\n      // It should be something like\n      //   .encoding = {'codePages':['WinANSI....'], 'WinANSI...':{code:code, ...}}\n      //   .widths = {0:width, code:width, ..., 'fof':divisor}\n      //   .kerning = {code:{previous_char_code:shift, ..., 'fof':-divisor},...}\n\n      if ((flags.autoencode || outputEncoding) && fonts[activeFontKey].metadata && fonts[activeFontKey].metadata[sourceEncoding] && fonts[activeFontKey].metadata[sourceEncoding].encoding) {\n        encodingBlock = fonts[activeFontKey].metadata[sourceEncoding].encoding; // each font has default encoding. Some have it clearly defined.\n\n        if (!outputEncoding && fonts[activeFontKey].encoding) {\n          outputEncoding = fonts[activeFontKey].encoding;\n        } // Hmmm, the above did not work? Let's try again, in different place.\n\n\n        if (!outputEncoding && encodingBlock.codePages) {\n          outputEncoding = encodingBlock.codePages[0]; // let's say, first one is the default\n        }\n\n        if (typeof outputEncoding === \"string\") {\n          outputEncoding = encodingBlock[outputEncoding];\n        } // we want output encoding to be a JS Object, where\n        // key = sourceEncoding's character code and\n        // value = outputEncoding's character code.\n\n\n        if (outputEncoding) {\n          isUnicode = false;\n          newtext = [];\n\n          for (i = 0, l = text.length; i < l; i++) {\n            ch = outputEncoding[text.charCodeAt(i)];\n\n            if (ch) {\n              newtext.push(String.fromCharCode(ch));\n            } else {\n              newtext.push(text[i]);\n            } // since we are looping over chars anyway, might as well\n            // check for residual unicodeness\n\n\n            if (newtext[i].charCodeAt(0) >> 8) {\n              /* more than 255 */\n              isUnicode = true;\n            }\n          }\n\n          text = newtext.join(\"\");\n        }\n      }\n\n      i = text.length; // isUnicode may be set to false above. Hence the triple-equal to undefined\n\n      while (isUnicode === undefined && i !== 0) {\n        if (text.charCodeAt(i - 1) >> 8) {\n          /* more than 255 */\n          isUnicode = true;\n        }\n\n        i--;\n      }\n\n      if (!isUnicode) {\n        return text;\n      }\n\n      newtext = flags.noBOM ? [] : [254, 255];\n\n      for (i = 0, l = text.length; i < l; i++) {\n        ch = text.charCodeAt(i);\n        bch = ch >> 8; // divide by 256\n\n        if (bch >> 8) {\n          /* something left after dividing by 256 second time */\n          throw new Error(\"Character at position \" + i + \" of string '\" + text + \"' exceeds 16bits. Cannot be encoded into UCS-2 BE\");\n        }\n\n        newtext.push(bch);\n        newtext.push(ch - (bch << 8));\n      }\n\n      return String.fromCharCode.apply(undefined, newtext);\n    };\n\n    var pdfEscape = API.__private__.pdfEscape = API.pdfEscape = function (text, flags) {\n      /**\n       * Replace '/', '(', and ')' with pdf-safe versions\n       *\n       * Doing to8bitStream does NOT make this PDF display unicode text. For that\n       * we also need to reference a unicode font and embed it - royal pain in the rear.\n       *\n       * There is still a benefit to to8bitStream - PDF simply cannot handle 16bit chars,\n       * which JavaScript Strings are happy to provide. So, while we still cannot display\n       * 2-byte characters property, at least CONDITIONALLY converting (entire string containing)\n       * 16bit chars to (USC-2-BE) 2-bytes per char + BOM streams we ensure that entire PDF\n       * is still parseable.\n       * This will allow immediate support for unicode in document properties strings.\n       */\n      return to8bitStream(text, flags).replace(/\\\\/g, \"\\\\\\\\\").replace(/\\(/g, \"\\\\(\").replace(/\\)/g, \"\\\\)\");\n    };\n\n    var beginPage = API.__private__.beginPage = function (format) {\n      pages[++page] = [];\n      pagesContext[page] = {\n        objId: 0,\n        contentsObjId: 0,\n        userUnit: Number(userUnit),\n        artBox: null,\n        bleedBox: null,\n        cropBox: null,\n        trimBox: null,\n        mediaBox: {\n          bottomLeftX: 0,\n          bottomLeftY: 0,\n          topRightX: Number(format[0]),\n          topRightY: Number(format[1])\n        }\n      };\n\n      _setPage(page);\n\n      setOutputDestination(pages[currentPage]);\n    };\n\n    var _addPage = function _addPage(parmFormat, parmOrientation) {\n      var dimensions, width, height;\n      orientation = parmOrientation || orientation;\n\n      if (typeof parmFormat === \"string\") {\n        dimensions = getPageFormat(parmFormat.toLowerCase());\n\n        if (Array.isArray(dimensions)) {\n          width = dimensions[0];\n          height = dimensions[1];\n        }\n      }\n\n      if (Array.isArray(parmFormat)) {\n        width = parmFormat[0] * scaleFactor;\n        height = parmFormat[1] * scaleFactor;\n      }\n\n      if (isNaN(width)) {\n        width = format[0];\n        height = format[1];\n      }\n\n      if (width > 14400 || height > 14400) {\n        console.warn(\"A page in a PDF can not be wider or taller than 14400 userUnit. jsPDF limits the width/height to 14400\");\n        width = Math.min(14400, width);\n        height = Math.min(14400, height);\n      }\n\n      format = [width, height];\n\n      switch (orientation.substr(0, 1)) {\n        case \"l\":\n          if (height > width) {\n            format = [height, width];\n          }\n\n          break;\n\n        case \"p\":\n          if (width > height) {\n            format = [height, width];\n          }\n\n          break;\n      }\n\n      beginPage(format); // Set line width\n\n      setLineWidth(lineWidth); // Set draw color\n\n      out(strokeColor); // resurrecting non-default line caps, joins\n\n      if (lineCapID !== 0) {\n        out(lineCapID + \" J\");\n      }\n\n      if (lineJoinID !== 0) {\n        out(lineJoinID + \" j\");\n      }\n\n      events.publish(\"addPage\", {\n        pageNumber: page\n      });\n    };\n\n    var _deletePage = function _deletePage(n) {\n      if (n > 0 && n <= page) {\n        pages.splice(n, 1);\n        pagesContext.splice(n, 1);\n        page--;\n\n        if (currentPage > page) {\n          currentPage = page;\n        }\n\n        this.setPage(currentPage);\n      }\n    };\n\n    var _setPage = function _setPage(n) {\n      if (n > 0 && n <= page) {\n        currentPage = n;\n      }\n    };\n\n    var getNumberOfPages = API.__private__.getNumberOfPages = API.getNumberOfPages = function () {\n      return pages.length - 1;\n    };\n    /**\n     * Returns a document-specific font key - a label assigned to a\n     * font name + font type combination at the time the font was added\n     * to the font inventory.\n     *\n     * Font key is used as label for the desired font for a block of text\n     * to be added to the PDF document stream.\n     * @private\n     * @function\n     * @param fontName {string} can be undefined on \"falthy\" to indicate \"use current\"\n     * @param fontStyle {string} can be undefined on \"falthy\" to indicate \"use current\"\n     * @returns {string} Font key.\n     * @ignore\n     */\n\n\n    var getFont = function getFont(fontName, fontStyle, options) {\n      var key = undefined,\n          fontNameLowerCase;\n      options = options || {};\n      fontName = fontName !== undefined ? fontName : fonts[activeFontKey].fontName;\n      fontStyle = fontStyle !== undefined ? fontStyle : fonts[activeFontKey].fontStyle;\n      fontNameLowerCase = fontName.toLowerCase();\n\n      if (fontmap[fontNameLowerCase] !== undefined && fontmap[fontNameLowerCase][fontStyle] !== undefined) {\n        key = fontmap[fontNameLowerCase][fontStyle];\n      } else if (fontmap[fontName] !== undefined && fontmap[fontName][fontStyle] !== undefined) {\n        key = fontmap[fontName][fontStyle];\n      } else {\n        if (options.disableWarning === false) {\n          console.warn(\"Unable to look up font label for font '\" + fontName + \"', '\" + fontStyle + \"'. Refer to getFontList() for available fonts.\");\n        }\n      }\n\n      if (!key && !options.noFallback) {\n        key = fontmap[\"times\"][fontStyle];\n\n        if (key == null) {\n          key = fontmap[\"times\"][\"normal\"];\n        }\n      }\n\n      return key;\n    };\n\n    var putInfo = API.__private__.putInfo = function () {\n      var objectId = newObject();\n\n      var encryptor = function encryptor(data) {\n        return data;\n      };\n\n      if (encryptionOptions !== null) {\n        encryptor = encryption.encryptor(objectId, 0);\n      }\n\n      out(\"<<\");\n      out(\"/Producer (\" + pdfEscape(encryptor(\"jsPDF \" + jsPDF.version)) + \")\");\n\n      for (var key in documentProperties) {\n        if (documentProperties.hasOwnProperty(key) && documentProperties[key]) {\n          out(\"/\" + key.substr(0, 1).toUpperCase() + key.substr(1) + \" (\" + pdfEscape(encryptor(documentProperties[key])) + \")\");\n        }\n      }\n\n      out(\"/CreationDate (\" + pdfEscape(encryptor(creationDate)) + \")\");\n      out(\">>\");\n      out(\"endobj\");\n    };\n\n    var putCatalog = API.__private__.putCatalog = function (options) {\n      options = options || {};\n      var tmpRootDictionaryObjId = options.rootDictionaryObjId || rootDictionaryObjId;\n      newObject();\n      out(\"<<\");\n      out(\"/Type /Catalog\");\n      out(\"/Pages \" + tmpRootDictionaryObjId + \" 0 R\"); // PDF13ref Section 7.2.1\n\n      if (!zoomMode) zoomMode = \"fullwidth\";\n\n      switch (zoomMode) {\n        case \"fullwidth\":\n          out(\"/OpenAction [3 0 R /FitH null]\");\n          break;\n\n        case \"fullheight\":\n          out(\"/OpenAction [3 0 R /FitV null]\");\n          break;\n\n        case \"fullpage\":\n          out(\"/OpenAction [3 0 R /Fit]\");\n          break;\n\n        case \"original\":\n          out(\"/OpenAction [3 0 R /XYZ null null 1]\");\n          break;\n\n        default:\n          var pcn = \"\" + zoomMode;\n          if (pcn.substr(pcn.length - 1) === \"%\") zoomMode = parseInt(zoomMode) / 100;\n\n          if (typeof zoomMode === \"number\") {\n            out(\"/OpenAction [3 0 R /XYZ null null \" + f2(zoomMode) + \"]\");\n          }\n\n      }\n\n      if (!layoutMode) layoutMode = \"continuous\";\n\n      switch (layoutMode) {\n        case \"continuous\":\n          out(\"/PageLayout /OneColumn\");\n          break;\n\n        case \"single\":\n          out(\"/PageLayout /SinglePage\");\n          break;\n\n        case \"two\":\n        case \"twoleft\":\n          out(\"/PageLayout /TwoColumnLeft\");\n          break;\n\n        case \"tworight\":\n          out(\"/PageLayout /TwoColumnRight\");\n          break;\n      }\n\n      if (pageMode) {\n        /**\n         * A name object specifying how the document should be displayed when opened:\n         * UseNone      : Neither document outline nor thumbnail images visible -- DEFAULT\n         * UseOutlines  : Document outline visible\n         * UseThumbs    : Thumbnail images visible\n         * FullScreen   : Full-screen mode, with no menu bar, window controls, or any other window visible\n         */\n        out(\"/PageMode /\" + pageMode);\n      }\n\n      events.publish(\"putCatalog\");\n      out(\">>\");\n      out(\"endobj\");\n    };\n\n    var putTrailer = API.__private__.putTrailer = function () {\n      out(\"trailer\");\n      out(\"<<\");\n      out(\"/Size \" + (objectNumber + 1)); // Root and Info must be the last and second last objects written respectively\n\n      out(\"/Root \" + objectNumber + \" 0 R\");\n      out(\"/Info \" + (objectNumber - 1) + \" 0 R\");\n\n      if (encryptionOptions !== null) {\n        out(\"/Encrypt \" + encryption.oid + \" 0 R\");\n      }\n\n      out(\"/ID [ <\" + fileId + \"> <\" + fileId + \"> ]\");\n      out(\">>\");\n    };\n\n    var putHeader = API.__private__.putHeader = function () {\n      out(\"%PDF-\" + pdfVersion);\n      out(\"%\\xBA\\xDF\\xAC\\xE0\");\n    };\n\n    var putXRef = API.__private__.putXRef = function () {\n      var p = \"0000000000\";\n      out(\"xref\");\n      out(\"0 \" + (objectNumber + 1));\n      out(\"0000000000 65535 f \");\n\n      for (var i = 1; i <= objectNumber; i++) {\n        var offset = offsets[i];\n\n        if (typeof offset === \"function\") {\n          out((p + offsets[i]()).slice(-10) + \" 00000 n \");\n        } else {\n          if (typeof offsets[i] !== \"undefined\") {\n            out((p + offsets[i]).slice(-10) + \" 00000 n \");\n          } else {\n            out(\"0000000000 00000 n \");\n          }\n        }\n      }\n    };\n\n    var buildDocument = API.__private__.buildDocument = function () {\n      resetDocument();\n      setOutputDestination(content);\n      events.publish(\"buildDocument\");\n      putHeader();\n      putPages();\n      putAdditionalObjects();\n      putResources();\n      if (encryptionOptions !== null) putEncryptionDict();\n      putInfo();\n      putCatalog();\n      var offsetOfXRef = contentLength;\n      putXRef();\n      putTrailer();\n      out(\"startxref\");\n      out(\"\" + offsetOfXRef);\n      out(\"%%EOF\");\n      setOutputDestination(pages[currentPage]);\n      return content.join(\"\\n\");\n    };\n\n    var getBlob = API.__private__.getBlob = function (data) {\n      return new Blob([getArrayBuffer(data)], {\n        type: \"application/pdf\"\n      });\n    };\n    /**\n     * Generates the PDF document.\n     *\n     * If `type` argument is undefined, output is raw body of resulting PDF returned as a string.\n     *\n     * @param {string} type A string identifying one of the possible output types.<br/>\n     *                      Possible values are: <br/>\n     *                          'arraybuffer' -> (ArrayBuffer)<br/>\n     *                          'blob' -> (Blob)<br/>\n     *                          'bloburi'/'bloburl' -> (string)<br/>\n     *                          'datauristring'/'dataurlstring' -> (string)<br/>\n     *                          'datauri'/'dataurl' -> (undefined) -> change location to generated datauristring/dataurlstring<br/>\n     *                          'dataurlnewwindow' -> (window | null | undefined) throws error if global isn't a window object(node)<br/>\n     *                          'pdfobjectnewwindow' -> (window | null) throws error if global isn't a window object(node)<br/>\n     *                          'pdfjsnewwindow' -> (wind | null)\n     * @param {Object|string} options An object providing some additional signalling to PDF generator.<br/>\n     *                                Possible options are 'filename'.<br/>\n     *                                A string can be passed instead of {filename:string} and defaults to 'generated.pdf'\n     * @function\n     * @instance\n     * @returns {string|window|ArrayBuffer|Blob|jsPDF|null|undefined}\n     * @memberof jsPDF#\n     * @name output\n     */\n\n\n    var output = API.output = API.__private__.output = SAFE(function output(type, options) {\n      options = options || {};\n\n      if (typeof options === \"string\") {\n        options = {\n          filename: options\n        };\n      } else {\n        options.filename = options.filename || \"generated.pdf\";\n      }\n\n      switch (type) {\n        case undefined:\n          return buildDocument();\n\n        case \"save\":\n          API.save(options.filename);\n          break;\n\n        case \"arraybuffer\":\n          return getArrayBuffer(buildDocument());\n\n        case \"blob\":\n          return getBlob(buildDocument());\n\n        case \"bloburi\":\n        case \"bloburl\":\n          // Developer is responsible of calling revokeObjectURL\n          if (typeof globalObject.URL !== \"undefined\" && typeof globalObject.URL.createObjectURL === \"function\") {\n            return globalObject.URL && globalObject.URL.createObjectURL(getBlob(buildDocument())) || void 0;\n          } else {\n            console.warn(\"bloburl is not supported by your system, because URL.createObjectURL is not supported by your browser.\");\n          }\n\n          break;\n\n        case \"datauristring\":\n        case \"dataurlstring\":\n          var dataURI = \"\";\n          var pdfDocument = buildDocument();\n\n          try {\n            dataURI = btoa(pdfDocument);\n          } catch (e) {\n            dataURI = btoa(unescape(encodeURIComponent(pdfDocument)));\n          }\n\n          return \"data:application/pdf;filename=\" + options.filename + \";base64,\" + dataURI;\n\n        case \"pdfobjectnewwindow\":\n          if (Object.prototype.toString.call(globalObject) === \"[object Window]\") {\n            var pdfObjectUrl = \"https://cdnjs.cloudflare.com/ajax/libs/pdfobject/2.1.1/pdfobject.min.js\";\n            var integrity = ' integrity=\"sha512-4ze/a9/4jqu+tX9dfOqJYSvyYd5M6qum/3HpCLr+/Jqf0whc37VUbkpNGHR7/8pSnCFw47T1fmIpwBV7UySh3g==\" crossorigin=\"anonymous\"';\n\n            if (options.pdfObjectUrl) {\n              pdfObjectUrl = options.pdfObjectUrl;\n              integrity = \"\";\n            }\n\n            var htmlForNewWindow = \"<html>\" + '<style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;}  </style><body><script src=\"' + pdfObjectUrl + '\"' + integrity + '></script><script >PDFObject.embed(\"' + this.output(\"dataurlstring\") + '\", ' + JSON.stringify(options) + \");</script></body></html>\";\n            var nW = globalObject.open();\n\n            if (nW !== null) {\n              nW.document.write(htmlForNewWindow);\n            }\n\n            return nW;\n          } else {\n            throw new Error(\"The option pdfobjectnewwindow just works in a browser-environment.\");\n          }\n\n        case \"pdfjsnewwindow\":\n          if (Object.prototype.toString.call(globalObject) === \"[object Window]\") {\n            var pdfJsUrl = options.pdfJsUrl || \"examples/PDF.js/web/viewer.html\";\n            var htmlForPDFjsNewWindow = \"<html>\" + \"<style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;}  </style>\" + '<body><iframe id=\"pdfViewer\" src=\"' + pdfJsUrl + \"?file=&downloadName=\" + options.filename + '\" width=\"500px\" height=\"400px\" />' + \"</body></html>\";\n            var PDFjsNewWindow = globalObject.open();\n\n            if (PDFjsNewWindow !== null) {\n              PDFjsNewWindow.document.write(htmlForPDFjsNewWindow);\n              var scope = this;\n\n              PDFjsNewWindow.document.documentElement.querySelector(\"#pdfViewer\").onload = function () {\n                PDFjsNewWindow.document.title = options.filename;\n                PDFjsNewWindow.document.documentElement.querySelector(\"#pdfViewer\").contentWindow.PDFViewerApplication.open(scope.output(\"bloburl\"));\n              };\n            }\n\n            return PDFjsNewWindow;\n          } else {\n            throw new Error(\"The option pdfjsnewwindow just works in a browser-environment.\");\n          }\n\n        case \"dataurlnewwindow\":\n          if (Object.prototype.toString.call(globalObject) === \"[object Window]\") {\n            var htmlForDataURLNewWindow = \"<html>\" + \"<style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;}  </style>\" + \"<body>\" + '<iframe src=\"' + this.output(\"datauristring\", options) + '\"></iframe>' + \"</body></html>\";\n            var dataURLNewWindow = globalObject.open();\n\n            if (dataURLNewWindow !== null) {\n              dataURLNewWindow.document.write(htmlForDataURLNewWindow);\n              dataURLNewWindow.document.title = options.filename;\n            }\n\n            if (dataURLNewWindow || typeof safari === \"undefined\") return dataURLNewWindow;\n          } else {\n            throw new Error(\"The option dataurlnewwindow just works in a browser-environment.\");\n          }\n\n          break;\n\n        case \"datauri\":\n        case \"dataurl\":\n          return globalObject.document.location.href = this.output(\"datauristring\", options);\n\n        default:\n          return null;\n      }\n    });\n    /**\n     * Used to see if a supplied hotfix was requested when the pdf instance was created.\n     * @param {string} hotfixName - The name of the hotfix to check.\n     * @returns {boolean}\n     */\n\n    var hasHotfix = function hasHotfix(hotfixName) {\n      return Array.isArray(hotfixes) === true && hotfixes.indexOf(hotfixName) > -1;\n    };\n\n    switch (unit) {\n      case \"pt\":\n        scaleFactor = 1;\n        break;\n\n      case \"mm\":\n        scaleFactor = 72 / 25.4;\n        break;\n\n      case \"cm\":\n        scaleFactor = 72 / 2.54;\n        break;\n\n      case \"in\":\n        scaleFactor = 72;\n        break;\n\n      case \"px\":\n        if (hasHotfix(\"px_scaling\") == true) {\n          scaleFactor = 72 / 96;\n        } else {\n          scaleFactor = 96 / 72;\n        }\n\n        break;\n\n      case \"pc\":\n        scaleFactor = 12;\n        break;\n\n      case \"em\":\n        scaleFactor = 12;\n        break;\n\n      case \"ex\":\n        scaleFactor = 6;\n        break;\n\n      default:\n        if (typeof unit === \"number\") {\n          scaleFactor = unit;\n        } else {\n          throw new Error(\"Invalid unit: \" + unit);\n        }\n\n    }\n\n    var encryption = null;\n    setCreationDate();\n    setFileId();\n\n    var getEncryptor = function getEncryptor(objectId) {\n      if (encryptionOptions !== null) {\n        return encryption.encryptor(objectId, 0);\n      }\n\n      return function (data) {\n        return data;\n      };\n    }; //---------------------------------------\n    // Public API\n\n\n    var getPageInfo = API.__private__.getPageInfo = API.getPageInfo = function (pageNumberOneBased) {\n      if (isNaN(pageNumberOneBased) || pageNumberOneBased % 1 !== 0) {\n        throw new Error(\"Invalid argument passed to jsPDF.getPageInfo\");\n      }\n\n      var objId = pagesContext[pageNumberOneBased].objId;\n      return {\n        objId: objId,\n        pageNumber: pageNumberOneBased,\n        pageContext: pagesContext[pageNumberOneBased]\n      };\n    };\n\n    var getPageInfoByObjId = API.__private__.getPageInfoByObjId = function (objId) {\n      if (isNaN(objId) || objId % 1 !== 0) {\n        throw new Error(\"Invalid argument passed to jsPDF.getPageInfoByObjId\");\n      }\n\n      for (var pageNumber in pagesContext) {\n        if (pagesContext[pageNumber].objId === objId) {\n          break;\n        }\n      }\n\n      return getPageInfo(pageNumber);\n    };\n\n    var getCurrentPageInfo = API.__private__.getCurrentPageInfo = API.getCurrentPageInfo = function () {\n      return {\n        objId: pagesContext[currentPage].objId,\n        pageNumber: currentPage,\n        pageContext: pagesContext[currentPage]\n      };\n    };\n    /**\n     * Adds (and transfers the focus to) new page to the PDF document.\n     * @param format {String/Array} The format of the new page. Can be: <ul><li>a0 - a10</li><li>b0 - b10</li><li>c0 - c10</li><li>dl</li><li>letter</li><li>government-letter</li><li>legal</li><li>junior-legal</li><li>ledger</li><li>tabloid</li><li>credit-card</li></ul><br />\n     * Default is \"a4\". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array, e.g. [595.28, 841.89]\n     * @param orientation {string} Orientation of the new page. Possible values are \"portrait\" or \"landscape\" (or shortcuts \"p\" (Default), \"l\").\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     *\n     * @memberof jsPDF#\n     * @name addPage\n     */\n\n\n    API.addPage = function () {\n      _addPage.apply(this, arguments);\n\n      return this;\n    };\n    /**\n     * Adds (and transfers the focus to) new page to the PDF document.\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     *\n     * @memberof jsPDF#\n     * @name setPage\n     * @param {number} page Switch the active page to the page number specified (indexed starting at 1).\n     * @example\n     * doc = jsPDF()\n     * doc.addPage()\n     * doc.addPage()\n     * doc.text('I am on page 3', 10, 10)\n     * doc.setPage(1)\n     * doc.text('I am on page 1', 10, 10)\n     */\n\n\n    API.setPage = function () {\n      _setPage.apply(this, arguments);\n\n      setOutputDestination.call(this, pages[currentPage]);\n      return this;\n    };\n    /**\n     * @name insertPage\n     * @memberof jsPDF#\n     *\n     * @function\n     * @instance\n     * @param {Object} beforePage\n     * @returns {jsPDF}\n     */\n\n\n    API.insertPage = function (beforePage) {\n      this.addPage();\n      this.movePage(currentPage, beforePage);\n      return this;\n    };\n    /**\n     * @name movePage\n     * @memberof jsPDF#\n     * @function\n     * @instance\n     * @param {number} targetPage\n     * @param {number} beforePage\n     * @returns {jsPDF}\n     */\n\n\n    API.movePage = function (targetPage, beforePage) {\n      var tmpPages, tmpPagesContext;\n\n      if (targetPage > beforePage) {\n        tmpPages = pages[targetPage];\n        tmpPagesContext = pagesContext[targetPage];\n\n        for (var i = targetPage; i > beforePage; i--) {\n          pages[i] = pages[i - 1];\n          pagesContext[i] = pagesContext[i - 1];\n        }\n\n        pages[beforePage] = tmpPages;\n        pagesContext[beforePage] = tmpPagesContext;\n        this.setPage(beforePage);\n      } else if (targetPage < beforePage) {\n        tmpPages = pages[targetPage];\n        tmpPagesContext = pagesContext[targetPage];\n\n        for (var j = targetPage; j < beforePage; j++) {\n          pages[j] = pages[j + 1];\n          pagesContext[j] = pagesContext[j + 1];\n        }\n\n        pages[beforePage] = tmpPages;\n        pagesContext[beforePage] = tmpPagesContext;\n        this.setPage(beforePage);\n      }\n\n      return this;\n    };\n    /**\n     * Deletes a page from the PDF.\n     * @name deletePage\n     * @memberof jsPDF#\n     * @function\n     * @param {number} targetPage\n     * @instance\n     * @returns {jsPDF}\n     */\n\n\n    API.deletePage = function () {\n      _deletePage.apply(this, arguments);\n\n      return this;\n    };\n    /**\n     * Adds text to page. Supports adding multiline text when 'text' argument is an Array of Strings.\n     *\n     * @function\n     * @instance\n     * @param {String|Array} text String or array of strings to be added to the page. Each line is shifted one line down per font, spacing settings declared before this call.\n     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page.\n     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page.\n     * @param {Object} [options] - Collection of settings signaling how the text must be encoded.\n     * @param {string} [options.align=left] - The alignment of the text, possible values: left, center, right, justify.\n     * @param {string} [options.baseline=alphabetic] - Sets text baseline used when drawing the text, possible values: alphabetic, ideographic, bottom, top, middle, hanging\n     * @param {number|Matrix} [options.angle=0] - Rotate the text clockwise or counterclockwise. Expects the angle in degree.\n     * @param {number} [options.rotationDirection=1] - Direction of the rotation. 0 = clockwise, 1 = counterclockwise.\n     * @param {number} [options.charSpace=0] - The space between each letter.\n     * @param {number} [options.horizontalScale=1] - Horizontal scale of the text as a factor of the regular size.\n     * @param {number} [options.lineHeightFactor=1.15] - The lineheight of each line.\n     * @param {Object} [options.flags] - Flags for to8bitStream.\n     * @param {boolean} [options.flags.noBOM=true] - Don't add BOM to Unicode-text.\n     * @param {boolean} [options.flags.autoencode=true] - Autoencode the Text.\n     * @param {number} [options.maxWidth=0] - Split the text by given width, 0 = no split.\n     * @param {string} [options.renderingMode=fill] - Set how the text should be rendered, possible values: fill, stroke, fillThenStroke, invisible, fillAndAddForClipping, strokeAndAddPathForClipping, fillThenStrokeAndAddToPathForClipping, addToPathForClipping.\n     * @param {boolean} [options.isInputVisual] - Option for the BidiEngine\n     * @param {boolean} [options.isOutputVisual] - Option for the BidiEngine\n     * @param {boolean} [options.isInputRtl] - Option for the BidiEngine\n     * @param {boolean} [options.isOutputRtl] - Option for the BidiEngine\n     * @param {boolean} [options.isSymmetricSwapping] - Option for the BidiEngine\n     * @param {number|Matrix} transform If transform is a number the text will be rotated by this value around the anchor set by x and y.\n     *\n     * If it is a Matrix, this matrix gets directly applied to the text, which allows shearing\n     * effects etc.; the x and y offsets are then applied AFTER the coordinate system has been established by this\n     * matrix. This means passing a rotation matrix that is equivalent to some rotation angle will in general yield a\n     * DIFFERENT result. A matrix is only allowed in \"advanced\" API mode.\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name text\n     */\n\n\n    API.__private__.text = API.text = function (text, x, y, options, transform) {\n      /*\n       * Inserts something like this into PDF\n       *   BT\n       *    /F1 16 Tf  % Font name + size\n       *    16 TL % How many units down for next line in multiline text\n       *    0 g % color\n       *    28.35 813.54 Td % position\n       *    (line one) Tj\n       *    T* (line two) Tj\n       *    T* (line three) Tj\n       *   ET\n       */\n      options = options || {};\n      var scope = options.scope || this;\n      var payload, da, angle, align, charSpace, maxWidth, flags, horizontalScale; // Pre-August-2012 the order of arguments was function(x, y, text, flags)\n      // in effort to make all calls have similar signature like\n      //   function(data, coordinates... , miscellaneous)\n      // this method had its args flipped.\n      // code below allows backward compatibility with old arg order.\n\n      if (typeof text === \"number\" && typeof x === \"number\" && (typeof y === \"string\" || Array.isArray(y))) {\n        var tmp = y;\n        y = x;\n        x = text;\n        text = tmp;\n      }\n\n      var transformationMatrix;\n\n      if (arguments[3] instanceof Matrix === false) {\n        flags = arguments[3];\n        angle = arguments[4];\n        align = arguments[5];\n\n        if (_typeof(flags) !== \"object\" || flags === null) {\n          if (typeof angle === \"string\") {\n            align = angle;\n            angle = null;\n          }\n\n          if (typeof flags === \"string\") {\n            align = flags;\n            flags = null;\n          }\n\n          if (typeof flags === \"number\") {\n            angle = flags;\n            flags = null;\n          }\n\n          options = {\n            flags: flags,\n            angle: angle,\n            align: align\n          };\n        }\n      } else {\n        advancedApiModeTrap(\"The transform parameter of text() with a Matrix value\");\n        transformationMatrix = transform;\n      }\n\n      if (isNaN(x) || isNaN(y) || typeof text === \"undefined\" || text === null) {\n        throw new Error(\"Invalid arguments passed to jsPDF.text\");\n      }\n\n      if (text.length === 0) {\n        return scope;\n      }\n\n      var xtra = \"\";\n      var isHex = false;\n      var lineHeight = typeof options.lineHeightFactor === \"number\" ? options.lineHeightFactor : lineHeightFactor;\n      var scaleFactor = scope.internal.scaleFactor;\n\n      function ESC(s) {\n        s = s.split(\"\\t\").join(Array(options.TabLen || 9).join(\" \"));\n        return pdfEscape(s, flags);\n      }\n\n      function transformTextToSpecialArray(text) {\n        //we don't want to destroy original text array, so cloning it\n        var sa = text.concat();\n        var da = [];\n        var len = sa.length;\n        var curDa; //we do array.join('text that must not be PDFescaped\")\n        //thus, pdfEscape each component separately\n\n        while (len--) {\n          curDa = sa.shift();\n\n          if (typeof curDa === \"string\") {\n            da.push(curDa);\n          } else {\n            if (Array.isArray(text) && (curDa.length === 1 || curDa[1] === undefined && curDa[2] === undefined)) {\n              da.push(curDa[0]);\n            } else {\n              da.push([curDa[0], curDa[1], curDa[2]]);\n            }\n          }\n        }\n\n        return da;\n      }\n\n      function processTextByFunction(text, processingFunction) {\n        var result;\n\n        if (typeof text === \"string\") {\n          result = processingFunction(text)[0];\n        } else if (Array.isArray(text)) {\n          //we don't want to destroy original text array, so cloning it\n          var sa = text.concat();\n          var da = [];\n          var len = sa.length;\n          var curDa;\n          var tmpResult; //we do array.join('text that must not be PDFescaped\")\n          //thus, pdfEscape each component separately\n\n          while (len--) {\n            curDa = sa.shift();\n\n            if (typeof curDa === \"string\") {\n              da.push(processingFunction(curDa)[0]);\n            } else if (Array.isArray(curDa) && typeof curDa[0] === \"string\") {\n              tmpResult = processingFunction(curDa[0], curDa[1], curDa[2]);\n              da.push([tmpResult[0], tmpResult[1], tmpResult[2]]);\n            }\n          }\n\n          result = da;\n        }\n\n        return result;\n      } //Check if text is of type String\n\n\n      var textIsOfTypeString = false;\n      var tmpTextIsOfTypeString = true;\n\n      if (typeof text === \"string\") {\n        textIsOfTypeString = true;\n      } else if (Array.isArray(text)) {\n        //we don't want to destroy original text array, so cloning it\n        var sa = text.concat();\n        da = [];\n        var len = sa.length;\n        var curDa; //we do array.join('text that must not be PDFescaped\")\n        //thus, pdfEscape each component separately\n\n        while (len--) {\n          curDa = sa.shift();\n\n          if (typeof curDa !== \"string\" || Array.isArray(curDa) && typeof curDa[0] !== \"string\") {\n            tmpTextIsOfTypeString = false;\n          }\n        }\n\n        textIsOfTypeString = tmpTextIsOfTypeString;\n      }\n\n      if (textIsOfTypeString === false) {\n        throw new Error('Type of text must be string or Array. \"' + text + '\" is not recognized.');\n      } //If there are any newlines in text, we assume\n      //the user wanted to print multiple lines, so break the\n      //text up into an array. If the text is already an array,\n      //we assume the user knows what they are doing.\n      //Convert text into an array anyway to simplify\n      //later code.\n\n\n      if (typeof text === \"string\") {\n        if (text.match(/[\\r?\\n]/)) {\n          text = text.split(/\\r\\n|\\r|\\n/g);\n        } else {\n          text = [text];\n        }\n      } //baseline\n\n\n      var height = activeFontSize / scope.internal.scaleFactor;\n      var descent = height * (lineHeight - 1);\n\n      switch (options.baseline) {\n        case \"bottom\":\n          y -= descent;\n          break;\n\n        case \"top\":\n          y += height - descent;\n          break;\n\n        case \"hanging\":\n          y += height - 2 * descent;\n          break;\n\n        case \"middle\":\n          y += height / 2 - descent;\n          break;\n      } //multiline\n\n\n      maxWidth = options.maxWidth || 0;\n\n      if (maxWidth > 0) {\n        if (typeof text === \"string\") {\n          text = scope.splitTextToSize(text, maxWidth);\n        } else if (Object.prototype.toString.call(text) === \"[object Array]\") {\n          text = text.reduce(function (acc, textLine) {\n            return acc.concat(scope.splitTextToSize(textLine, maxWidth));\n          }, []);\n        }\n      } //creating Payload-Object to make text byRef\n\n\n      payload = {\n        text: text,\n        x: x,\n        y: y,\n        options: options,\n        mutex: {\n          pdfEscape: pdfEscape,\n          activeFontKey: activeFontKey,\n          fonts: fonts,\n          activeFontSize: activeFontSize\n        }\n      };\n      events.publish(\"preProcessText\", payload);\n      text = payload.text;\n      options = payload.options; //angle\n\n      angle = options.angle;\n\n      if (transformationMatrix instanceof Matrix === false && angle && typeof angle === \"number\") {\n        angle *= Math.PI / 180;\n\n        if (options.rotationDirection === 0) {\n          angle = -angle;\n        }\n\n        if (apiMode === ApiMode.ADVANCED) {\n          angle = -angle;\n        }\n\n        var c = Math.cos(angle);\n        var s = Math.sin(angle);\n        transformationMatrix = new Matrix(c, s, -s, c, 0, 0);\n      } else if (angle && angle instanceof Matrix) {\n        transformationMatrix = angle;\n      }\n\n      if (apiMode === ApiMode.ADVANCED && !transformationMatrix) {\n        transformationMatrix = identityMatrix;\n      } //charSpace\n\n\n      charSpace = options.charSpace || activeCharSpace;\n\n      if (typeof charSpace !== \"undefined\") {\n        xtra += hpf(scale(charSpace)) + \" Tc\\n\";\n        this.setCharSpace(this.getCharSpace() || 0);\n      }\n\n      horizontalScale = options.horizontalScale;\n\n      if (typeof horizontalScale !== \"undefined\") {\n        xtra += hpf(horizontalScale * 100) + \" Tz\\n\";\n      } //lang\n\n\n      var lang = options.lang;\n\n\n      var renderingMode = -1;\n      var parmRenderingMode = typeof options.renderingMode !== \"undefined\" ? options.renderingMode : options.stroke;\n      var pageContext = scope.internal.getCurrentPageInfo().pageContext;\n\n      switch (parmRenderingMode) {\n        case 0:\n        case false:\n        case \"fill\":\n          renderingMode = 0;\n          break;\n\n        case 1:\n        case true:\n        case \"stroke\":\n          renderingMode = 1;\n          break;\n\n        case 2:\n        case \"fillThenStroke\":\n          renderingMode = 2;\n          break;\n\n        case 3:\n        case \"invisible\":\n          renderingMode = 3;\n          break;\n\n        case 4:\n        case \"fillAndAddForClipping\":\n          renderingMode = 4;\n          break;\n\n        case 5:\n        case \"strokeAndAddPathForClipping\":\n          renderingMode = 5;\n          break;\n\n        case 6:\n        case \"fillThenStrokeAndAddToPathForClipping\":\n          renderingMode = 6;\n          break;\n\n        case 7:\n        case \"addToPathForClipping\":\n          renderingMode = 7;\n          break;\n      }\n\n      var usedRenderingMode = typeof pageContext.usedRenderingMode !== \"undefined\" ? pageContext.usedRenderingMode : -1; //if the coder wrote it explicitly to use a specific\n      //renderingMode, then use it\n\n      if (renderingMode !== -1) {\n        xtra += renderingMode + \" Tr\\n\"; //otherwise check if we used the rendering Mode already\n        //if so then set the rendering Mode...\n      } else if (usedRenderingMode !== -1) {\n        xtra += \"0 Tr\\n\";\n      }\n\n      if (renderingMode !== -1) {\n        pageContext.usedRenderingMode = renderingMode;\n      } //align\n\n\n      align = options.align || \"left\";\n      var leading = activeFontSize * lineHeight;\n      var pageWidth = scope.internal.pageSize.getWidth();\n      var activeFont = fonts[activeFontKey];\n      charSpace = options.charSpace || activeCharSpace;\n      maxWidth = options.maxWidth || 0;\n      var lineWidths;\n      flags = Object.assign({\n        autoencode: true,\n        noBOM: true\n      }, options.flags);\n      var wordSpacingPerLine = [];\n\n      if (Object.prototype.toString.call(text) === \"[object Array]\") {\n        da = transformTextToSpecialArray(text);\n        var newY;\n\n        if (align !== \"left\") {\n          lineWidths = da.map(function (v) {\n            return scope.getStringUnitWidth(v, {\n              font: activeFont,\n              charSpace: charSpace,\n              fontSize: activeFontSize,\n              doKerning: false\n            }) * activeFontSize / scaleFactor;\n          });\n        } //The first line uses the \"main\" Td setting,\n        //and the subsequent lines are offset by the\n        //previous line's x coordinate.\n\n\n        var prevWidth = 0;\n        var newX;\n\n        if (align === \"right\") {\n          //The passed in x coordinate defines the\n          //rightmost point of the text.\n          x -= lineWidths[0];\n          text = [];\n          len = da.length;\n\n          for (var i = 0; i < len; i++) {\n            if (i === 0) {\n              newX = getHorizontalCoordinate(x);\n              newY = getVerticalCoordinate(y);\n            } else {\n              newX = scale(prevWidth - lineWidths[i]);\n              newY = -leading;\n            }\n\n            text.push([da[i], newX, newY]);\n            prevWidth = lineWidths[i];\n          }\n        } else if (align === \"center\") {\n          //The passed in x coordinate defines\n          //the center point.\n          x -= lineWidths[0] / 2;\n          text = [];\n          len = da.length;\n\n          for (var j = 0; j < len; j++) {\n            if (j === 0) {\n              newX = getHorizontalCoordinate(x);\n              newY = getVerticalCoordinate(y);\n            } else {\n              newX = scale((prevWidth - lineWidths[j]) / 2);\n              newY = -leading;\n            }\n\n            text.push([da[j], newX, newY]);\n            prevWidth = lineWidths[j];\n          }\n        } else if (align === \"left\") {\n          text = [];\n          len = da.length;\n\n          for (var h = 0; h < len; h++) {\n            text.push(da[h]);\n          }\n        } else if (align === \"justify\") {\n          text = [];\n          len = da.length;\n          maxWidth = maxWidth !== 0 ? maxWidth : pageWidth;\n\n          for (var l = 0; l < len; l++) {\n            newY = l === 0 ? getVerticalCoordinate(y) : -leading;\n            newX = l === 0 ? getHorizontalCoordinate(x) : 0;\n\n            if (l < len - 1) {\n              wordSpacingPerLine.push(hpf(scale((maxWidth - lineWidths[l]) / (da[l].split(\" \").length - 1))));\n            } else {\n              wordSpacingPerLine.push(0);\n            }\n\n            text.push([da[l], newX, newY]);\n          }\n        } else {\n          throw new Error('Unrecognized alignment option, use \"left\", \"center\", \"right\" or \"justify\".');\n        }\n      } //R2L\n\n\n      var doReversing = typeof options.R2L === \"boolean\" ? options.R2L : R2L;\n\n      if (doReversing === true) {\n        text = processTextByFunction(text, function (text, posX, posY) {\n          return [text.split(\"\").reverse().join(\"\"), posX, posY];\n        });\n      } //creating Payload-Object to make text byRef\n\n\n      payload = {\n        text: text,\n        x: x,\n        y: y,\n        options: options,\n        mutex: {\n          pdfEscape: pdfEscape,\n          activeFontKey: activeFontKey,\n          fonts: fonts,\n          activeFontSize: activeFontSize\n        }\n      };\n      events.publish(\"postProcessText\", payload);\n      text = payload.text;\n      isHex = payload.mutex.isHex || false; //Escaping\n\n      var activeFontEncoding = fonts[activeFontKey].encoding;\n\n      if (activeFontEncoding === \"WinAnsiEncoding\" || activeFontEncoding === \"StandardEncoding\") {\n        text = processTextByFunction(text, function (text, posX, posY) {\n          return [ESC(text), posX, posY];\n        });\n      }\n\n      da = transformTextToSpecialArray(text);\n      text = [];\n      var STRING = 0;\n      var ARRAY = 1;\n      var variant = Array.isArray(da[0]) ? ARRAY : STRING;\n      var posX;\n      var posY;\n      var content;\n      var wordSpacing = \"\";\n\n      var generatePosition = function generatePosition(parmPosX, parmPosY, parmTransformationMatrix) {\n        var position = \"\";\n\n        if (parmTransformationMatrix instanceof Matrix) {\n          // It is kind of more intuitive to apply a plain rotation around the text anchor set by x and y\n          // but when the user supplies an arbitrary transformation matrix, the x and y offsets should be applied\n          // in the coordinate system established by this matrix\n          if (typeof options.angle === \"number\") {\n            parmTransformationMatrix = matrixMult(parmTransformationMatrix, new Matrix(1, 0, 0, 1, parmPosX, parmPosY));\n          } else {\n            parmTransformationMatrix = matrixMult(new Matrix(1, 0, 0, 1, parmPosX, parmPosY), parmTransformationMatrix);\n          }\n\n          if (apiMode === ApiMode.ADVANCED) {\n            parmTransformationMatrix = matrixMult(new Matrix(1, 0, 0, -1, 0, 0), parmTransformationMatrix);\n          }\n\n          position = parmTransformationMatrix.join(\" \") + \" Tm\\n\";\n        } else {\n          position = hpf(parmPosX) + \" \" + hpf(parmPosY) + \" Td\\n\";\n        }\n\n        return position;\n      };\n\n      for (var lineIndex = 0; lineIndex < da.length; lineIndex++) {\n        wordSpacing = \"\";\n\n        switch (variant) {\n          case ARRAY:\n            content = (isHex ? \"<\" : \"(\") + da[lineIndex][0] + (isHex ? \">\" : \")\");\n            posX = parseFloat(da[lineIndex][1]);\n            posY = parseFloat(da[lineIndex][2]);\n            break;\n\n          case STRING:\n            content = (isHex ? \"<\" : \"(\") + da[lineIndex] + (isHex ? \">\" : \")\");\n            posX = getHorizontalCoordinate(x);\n            posY = getVerticalCoordinate(y);\n            break;\n        }\n\n        if (typeof wordSpacingPerLine !== \"undefined\" && typeof wordSpacingPerLine[lineIndex] !== \"undefined\") {\n          wordSpacing = wordSpacingPerLine[lineIndex] + \" Tw\\n\";\n        }\n\n        if (lineIndex === 0) {\n          text.push(wordSpacing + generatePosition(posX, posY, transformationMatrix) + content);\n        } else if (variant === STRING) {\n          text.push(wordSpacing + content);\n        } else if (variant === ARRAY) {\n          text.push(wordSpacing + generatePosition(posX, posY, transformationMatrix) + content);\n        }\n      }\n\n      text = variant === STRING ? text.join(\" Tj\\nT* \") : text.join(\" Tj\\n\");\n      text += \" Tj\\n\";\n      var result = \"BT\\n/\";\n      result += activeFontKey + \" \" + activeFontSize + \" Tf\\n\"; // font face, style, size\n\n      result += hpf(activeFontSize * lineHeight) + \" TL\\n\"; // line spacing\n\n      result += textColor + \"\\n\";\n      result += xtra;\n      result += text;\n      result += \"ET\";\n      out(result);\n      usedFonts[activeFontKey] = true;\n      return scope;\n    }; // PDF supports these path painting and clip path operators:\n    //\n    // S - stroke\n    // s - close/stroke\n    // f (F) - fill non-zero\n    // f* - fill evenodd\n    // B - fill stroke nonzero\n    // B* - fill stroke evenodd\n    // b - close fill stroke nonzero\n    // b* - close fill stroke evenodd\n    // n - nothing (consume path)\n    // W - clip nonzero\n    // W* - clip evenodd\n    //\n    // In order to keep the API small, we omit the close-and-fill/stroke operators and provide a separate close()\n    // method.\n\n    /**\n     *\n     * @name clip\n     * @function\n     * @instance\n     * @param {string} rule Only possible value is 'evenodd'\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @description All .clip() after calling drawing ops with a style argument of null.\n     */\n\n\n    var clip = API.__private__.clip = API.clip = function (rule) {\n      // Call .clip() after calling drawing ops with a style argument of null\n      // W is the PDF clipping op\n      if (\"evenodd\" === rule) {\n        out(\"W*\");\n      } else {\n        out(\"W\");\n      }\n\n      return this;\n    };\n    /**\n     * @name clipEvenOdd\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @description Modify the current clip path by intersecting it with the current path using the even-odd rule. Note\n     * that this will NOT consume the current path. In order to only use this path for clipping call\n     * {@link API.discardPath} afterwards.\n     */\n\n\n    API.clipEvenOdd = function () {\n      return clip(\"evenodd\");\n    };\n    /**\n     * Consumes the current path without any effect. Mainly used in combination with {@link clip} or\n     * {@link clipEvenOdd}. The PDF \"n\" operator.\n     * @name discardPath\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     */\n\n\n    API.__private__.discardPath = API.discardPath = function () {\n      out(\"n\");\n      return this;\n    };\n\n    var isValidStyle = API.__private__.isValidStyle = function (style) {\n      var validStyleVariants = [undefined, null, \"S\", \"D\", \"F\", \"DF\", \"FD\", \"f\", \"f*\", \"B\", \"B*\", \"n\"];\n      var result = false;\n\n      if (validStyleVariants.indexOf(style) !== -1) {\n        result = true;\n      }\n\n      return result;\n    };\n\n    API.__private__.setDefaultPathOperation = API.setDefaultPathOperation = function (operator) {\n      if (isValidStyle(operator)) {\n        defaultPathOperation = operator;\n      }\n\n      return this;\n    };\n\n    var getStyle = API.__private__.getStyle = API.getStyle = function (style) {\n      // see path-painting operators in PDF spec\n      var op = defaultPathOperation; // stroke\n\n      switch (style) {\n        case \"D\":\n        case \"S\":\n          op = \"S\"; // stroke\n\n          break;\n\n        case \"F\":\n          op = \"f\"; // fill\n\n          break;\n\n        case \"FD\":\n        case \"DF\":\n          op = \"B\";\n          break;\n\n        case \"f\":\n        case \"f*\":\n        case \"B\":\n        case \"B*\":\n          /*\n                 Allow direct use of these PDF path-painting operators:\n                 - f    fill using nonzero winding number rule\n                 - f*    fill using even-odd rule\n                 - B    fill then stroke with fill using non-zero winding number rule\n                 - B*    fill then stroke with fill using even-odd rule\n                 */\n          op = style;\n          break;\n      }\n\n      return op;\n    };\n    /**\n     * Close the current path. The PDF \"h\" operator.\n     * @name close\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     */\n\n\n    var close = API.close = function () {\n      out(\"h\");\n      return this;\n    };\n    /**\n     * Stroke the path. The PDF \"S\" operator.\n     * @name stroke\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     */\n\n\n    API.stroke = function () {\n      out(\"S\");\n      return this;\n    };\n    /**\n     * Fill the current path using the nonzero winding number rule. If a pattern is provided, the path will be filled\n     * with this pattern, otherwise with the current fill color. Equivalent to the PDF \"f\" operator.\n     * @name fill\n     * @function\n     * @instance\n     * @param {PatternData=} pattern If provided the path will be filled with this pattern\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     */\n\n\n    API.fill = function (pattern) {\n      fillWithOptionalPattern(\"f\", pattern);\n      return this;\n    };\n    /**\n     * Fill the current path using the even-odd rule. The PDF f* operator.\n     * @see API.fill\n     * @name fillEvenOdd\n     * @function\n     * @instance\n     * @param {PatternData=} pattern If provided the path will be filled with this pattern\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     */\n\n\n    API.fillEvenOdd = function (pattern) {\n      fillWithOptionalPattern(\"f*\", pattern);\n      return this;\n    };\n    /**\n     * Fill using the nonzero winding number rule and then stroke the current Path. The PDF \"B\" operator.\n     * @see API.fill\n     * @name fillStroke\n     * @function\n     * @instance\n     * @param {PatternData=} pattern If provided the path will be stroked with this pattern\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     */\n\n\n    API.fillStroke = function (pattern) {\n      fillWithOptionalPattern(\"B\", pattern);\n      return this;\n    };\n    /**\n     * Fill using the even-odd rule and then stroke the current Path. The PDF \"B\" operator.\n     * @see API.fill\n     * @name fillStrokeEvenOdd\n     * @function\n     * @instance\n     * @param {PatternData=} pattern If provided the path will be fill-stroked with this pattern\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     */\n\n\n    API.fillStrokeEvenOdd = function (pattern) {\n      fillWithOptionalPattern(\"B*\", pattern);\n      return this;\n    };\n\n    var fillWithOptionalPattern = function fillWithOptionalPattern(style, pattern) {\n      if (_typeof(pattern) === \"object\") {\n        fillWithPattern(pattern, style);\n      } else {\n        out(style);\n      }\n    };\n\n    var putStyle = function putStyle(style) {\n      if (style === null || apiMode === ApiMode.ADVANCED && style === undefined) {\n        return;\n      }\n\n      style = getStyle(style); // stroking / filling / both the path\n\n      out(style);\n    };\n\n    function cloneTilingPattern(patternKey, boundingBox, xStep, yStep, matrix) {\n      var clone = new TilingPattern(boundingBox || this.boundingBox, xStep || this.xStep, yStep || this.yStep, this.gState, matrix || this.matrix);\n      clone.stream = this.stream;\n      var key = patternKey + \"$$\" + this.cloneIndex++ + \"$$\";\n      addPattern(key, clone);\n      return clone;\n    }\n\n    var fillWithPattern = function fillWithPattern(patternData, style) {\n      var patternId = patternMap[patternData.key];\n      var pattern = patterns[patternId];\n\n      if (pattern instanceof ShadingPattern) {\n        out(\"q\");\n        out(clipRuleFromStyle(style));\n\n        if (pattern.gState) {\n          API.setGState(pattern.gState);\n        }\n\n        out(patternData.matrix.toString() + \" cm\");\n        out(\"/\" + patternId + \" sh\");\n        out(\"Q\");\n      } else if (pattern instanceof TilingPattern) {\n        // pdf draws patterns starting at the bottom left corner and they are not affected by the global transformation,\n        // so we must flip them\n        var matrix = new Matrix(1, 0, 0, -1, 0, getPageHeight());\n\n        if (patternData.matrix) {\n          matrix = matrix.multiply(patternData.matrix || identityMatrix); // we cannot apply a matrix to the pattern on use so we must abuse the pattern matrix and create new instances\n          // for each use\n\n          patternId = cloneTilingPattern.call(pattern, patternData.key, patternData.boundingBox, patternData.xStep, patternData.yStep, matrix).id;\n        }\n\n        out(\"q\");\n        out(\"/Pattern cs\");\n        out(\"/\" + patternId + \" scn\");\n\n        if (pattern.gState) {\n          API.setGState(pattern.gState);\n        }\n\n        out(style);\n        out(\"Q\");\n      }\n    };\n\n    var clipRuleFromStyle = function clipRuleFromStyle(style) {\n      switch (style) {\n        case \"f\":\n        case \"F\":\n          return \"W n\";\n\n        case \"f*\":\n          return \"W* n\";\n\n        case \"B\":\n          return \"W S\";\n\n        case \"B*\":\n          return \"W* S\";\n        // these two are for compatibility reasons (in the past, calling any primitive method with a shading pattern\n        // and \"n\"/\"S\" as style would still fill/fill and stroke the path)\n\n        case \"S\":\n          return \"W S\";\n\n        case \"n\":\n          return \"W n\";\n      }\n    };\n    /**\n     * Begin a new subpath by moving the current point to coordinates (x, y). The PDF \"m\" operator.\n     * @param {number} x\n     * @param {number} y\n     * @name moveTo\n     * @function\n     * @instance\n     * @memberof jsPDF#\n     * @returns {jsPDF}\n     */\n\n\n    var moveTo = API.moveTo = function (x, y) {\n      out(hpf(scale(x)) + \" \" + hpf(transformScaleY(y)) + \" m\");\n      return this;\n    };\n    /**\n     * Append a straight line segment from the current point to the point (x, y). The PDF \"l\" operator.\n     * @param {number} x\n     * @param {number} y\n     * @memberof jsPDF#\n     * @name lineTo\n     * @function\n     * @instance\n     * @memberof jsPDF#\n     * @returns {jsPDF}\n     */\n\n\n    var lineTo = API.lineTo = function (x, y) {\n      out(hpf(scale(x)) + \" \" + hpf(transformScaleY(y)) + \" l\");\n      return this;\n    };\n    /**\n     * Append a cubic Bézier curve to the current path. The curve shall extend from the current point to the point\n     * (x3, y3), using (x1, y1) and (x2, y2) as Bézier control points. The new current point shall be (x3, x3).\n     * @param {number} x1\n     * @param {number} y1\n     * @param {number} x2\n     * @param {number} y2\n     * @param {number} x3\n     * @param {number} y3\n     * @memberof jsPDF#\n     * @name curveTo\n     * @function\n     * @instance\n     * @memberof jsPDF#\n     * @returns {jsPDF}\n     */\n\n\n    var curveTo = API.curveTo = function (x1, y1, x2, y2, x3, y3) {\n      out([hpf(scale(x1)), hpf(transformScaleY(y1)), hpf(scale(x2)), hpf(transformScaleY(y2)), hpf(scale(x3)), hpf(transformScaleY(y3)), \"c\"].join(\" \"));\n      return this;\n    };\n    /**\n     * Draw a line on the current page.\n     *\n     * @name line\n     * @function\n     * @instance\n     * @param {number} x1\n     * @param {number} y1\n     * @param {number} x2\n     * @param {number} y2\n     * @param {string} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument. default: 'S'\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     */\n\n\n    API.__private__.line = API.line = function (x1, y1, x2, y2, style) {\n      if (isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2) || !isValidStyle(style)) {\n        throw new Error(\"Invalid arguments passed to jsPDF.line\");\n      }\n\n      if (apiMode === ApiMode.COMPAT) {\n        return this.lines([[x2 - x1, y2 - y1]], x1, y1, [1, 1], style || \"S\");\n      } else {\n        return this.lines([[x2 - x1, y2 - y1]], x1, y1, [1, 1]).stroke();\n      }\n    };\n    /**\n     * @typedef {Object} PatternData\n     * {Matrix|undefined} matrix\n     * {Number|undefined} xStep\n     * {Number|undefined} yStep\n     * {Array.<Number>|undefined} boundingBox\n     */\n\n    /**\n     * Adds series of curves (straight lines or cubic bezier curves) to canvas, starting at `x`, `y` coordinates.\n     * All data points in `lines` are relative to last line origin.\n     * `x`, `y` become x1,y1 for first line / curve in the set.\n     * For lines you only need to specify [x2, y2] - (ending point) vector against x1, y1 starting point.\n     * For bezier curves you need to specify [x2,y2,x3,y3,x4,y4] - vectors to control points 1, 2, ending point. All vectors are against the start of the curve - x1,y1.\n     *\n     * @example .lines([[2,2],[-2,2],[1,1,2,2,3,3],[2,1]], 212,110, [1,1], 'F', false) // line, line, bezier curve, line\n     * @param {Array} lines Array of *vector* shifts as pairs (lines) or sextets (cubic bezier curves).\n     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n     * @param {number} scale (Defaults to [1.0,1.0]) x,y Scaling factor for all vectors. Elements can be any floating number Sub-one makes drawing smaller. Over-one grows the drawing. Negative flips the direction.\n     * @param {string=} style A string specifying the painting style or null. Valid styles include:\n     * 'S' [default] - stroke,\n     * 'F' - fill,\n     * and 'DF' (or 'FD') -  fill then stroke.\n     * In \"compat\" API mode, a null value postpones setting the style so that a shape may be composed using multiple\n     * method calls. The last drawing method call used to define the shape should not have a null style argument.\n     *\n     * In \"advanced\" API mode this parameter is deprecated.\n     * @param {Boolean=} closed If true, the path is closed with a straight line from the end of the last curve to the starting point.\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name lines\n     */\n\n\n    API.__private__.lines = API.lines = function (lines, x, y, scale, style, closed) {\n      var scalex, scaley, i, l, leg, x2, y2, x3, y3, x4, y4, tmp; // Pre-August-2012 the order of arguments was function(x, y, lines, scale, style)\n      // in effort to make all calls have similar signature like\n      //   function(content, coordinateX, coordinateY , miscellaneous)\n      // this method had its args flipped.\n      // code below allows backward compatibility with old arg order.\n\n      if (typeof lines === \"number\") {\n        tmp = y;\n        y = x;\n        x = lines;\n        lines = tmp;\n      }\n\n      scale = scale || [1, 1];\n      closed = closed || false;\n\n      if (isNaN(x) || isNaN(y) || !Array.isArray(lines) || !Array.isArray(scale) || !isValidStyle(style) || typeof closed !== \"boolean\") {\n        throw new Error(\"Invalid arguments passed to jsPDF.lines\");\n      } // starting point\n\n\n      moveTo(x, y);\n      scalex = scale[0];\n      scaley = scale[1];\n      l = lines.length; //, x2, y2 // bezier only. In page default measurement \"units\", *after* scaling\n      //, x3, y3 // bezier only. In page default measurement \"units\", *after* scaling\n      // ending point for all, lines and bezier. . In page default measurement \"units\", *after* scaling\n\n      x4 = x; // last / ending point = starting point for first item.\n\n      y4 = y; // last / ending point = starting point for first item.\n\n      for (i = 0; i < l; i++) {\n        leg = lines[i];\n\n        if (leg.length === 2) {\n          // simple line\n          x4 = leg[0] * scalex + x4; // here last x4 was prior ending point\n\n          y4 = leg[1] * scaley + y4; // here last y4 was prior ending point\n\n          lineTo(x4, y4);\n        } else {\n          // bezier curve\n          x2 = leg[0] * scalex + x4; // here last x4 is prior ending point\n\n          y2 = leg[1] * scaley + y4; // here last y4 is prior ending point\n\n          x3 = leg[2] * scalex + x4; // here last x4 is prior ending point\n\n          y3 = leg[3] * scaley + y4; // here last y4 is prior ending point\n\n          x4 = leg[4] * scalex + x4; // here last x4 was prior ending point\n\n          y4 = leg[5] * scaley + y4; // here last y4 was prior ending point\n\n          curveTo(x2, y2, x3, y3, x4, y4);\n        }\n      }\n\n      if (closed) {\n        close();\n      }\n\n      putStyle(style);\n      return this;\n    };\n    /**\n     * Similar to {@link API.lines} but all coordinates are interpreted as absolute coordinates instead of relative.\n     * @param {Array<Object>} lines An array of {op: operator, c: coordinates} object, where op is one of \"m\" (move to), \"l\" (line to)\n     * \"c\" (cubic bezier curve) and \"h\" (close (sub)path)). c is an array of coordinates. \"m\" and \"l\" expect two, \"c\"\n     * six and \"h\" an empty array (or undefined).\n     * @function\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name path\n     */\n\n\n    API.path = function (lines) {\n      for (var i = 0; i < lines.length; i++) {\n        var leg = lines[i];\n        var coords = leg.c;\n\n        switch (leg.op) {\n          case \"m\":\n            moveTo(coords[0], coords[1]);\n            break;\n\n          case \"l\":\n            lineTo(coords[0], coords[1]);\n            break;\n\n          case \"c\":\n            curveTo.apply(this, coords);\n            break;\n\n          case \"h\":\n            close();\n            break;\n        }\n      }\n\n      return this;\n    };\n    /**\n     * Adds a rectangle to PDF.\n     *\n     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n     * @param {number} w Width (in units declared at inception of PDF document)\n     * @param {number} h Height (in units declared at inception of PDF document)\n     * @param {string=} style A string specifying the painting style or null. Valid styles include:\n     * 'S' [default] - stroke,\n     * 'F' - fill,\n     * and 'DF' (or 'FD') -  fill then stroke.\n     * In \"compat\" API mode, a null value postpones setting the style so that a shape may be composed using multiple\n     * method calls. The last drawing method call used to define the shape should not have a null style argument.\n     *\n     * In \"advanced\" API mode this parameter is deprecated.\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name rect\n     */\n\n\n    API.__private__.rect = API.rect = function (x, y, w, h, style) {\n      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h) || !isValidStyle(style)) {\n        throw new Error(\"Invalid arguments passed to jsPDF.rect\");\n      }\n\n      if (apiMode === ApiMode.COMPAT) {\n        h = -h;\n      }\n\n      out([hpf(scale(x)), hpf(transformScaleY(y)), hpf(scale(w)), hpf(scale(h)), \"re\"].join(\" \"));\n      putStyle(style);\n      return this;\n    };\n    /**\n     * Adds a triangle to PDF.\n     *\n     * @param {number} x1 Coordinate (in units declared at inception of PDF document) against left edge of the page\n     * @param {number} y1 Coordinate (in units declared at inception of PDF document) against upper edge of the page\n     * @param {number} x2 Coordinate (in units declared at inception of PDF document) against left edge of the page\n     * @param {number} y2 Coordinate (in units declared at inception of PDF document) against upper edge of the page\n     * @param {number} x3 Coordinate (in units declared at inception of PDF document) against left edge of the page\n     * @param {number} y3 Coordinate (in units declared at inception of PDF document) against upper edge of the page\n     * @param {string=} style A string specifying the painting style or null. Valid styles include:\n     * 'S' [default] - stroke,\n     * 'F' - fill,\n     * and 'DF' (or 'FD') -  fill then stroke.\n     * In \"compat\" API mode, a null value postpones setting the style so that a shape may be composed using multiple\n     * method calls. The last drawing method call used to define the shape should not have a null style argument.\n     *\n     * In \"advanced\" API mode this parameter is deprecated.\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name triangle\n     */\n\n\n    API.__private__.triangle = API.triangle = function (x1, y1, x2, y2, x3, y3, style) {\n      if (isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2) || isNaN(x3) || isNaN(y3) || !isValidStyle(style)) {\n        throw new Error(\"Invalid arguments passed to jsPDF.triangle\");\n      }\n\n      this.lines([[x2 - x1, y2 - y1], // vector to point 2\n      [x3 - x2, y3 - y2], // vector to point 3\n      [x1 - x3, y1 - y3] // closing vector back to point 1\n      ], x1, y1, // start of path\n      [1, 1], style, true);\n      return this;\n    };\n    /**\n     * Adds a rectangle with rounded corners to PDF.\n     *\n     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n     * @param {number} w Width (in units declared at inception of PDF document)\n     * @param {number} h Height (in units declared at inception of PDF document)\n     * @param {number} rx Radius along x axis (in units declared at inception of PDF document)\n     * @param {number} ry Radius along y axis (in units declared at inception of PDF document)\n     * @param {string=} style A string specifying the painting style or null. Valid styles include:\n     * 'S' [default] - stroke,\n     * 'F' - fill,\n     * and 'DF' (or 'FD') -  fill then stroke.\n     * In \"compat\" API mode, a null value postpones setting the style so that a shape may be composed using multiple\n     * method calls. The last drawing method call used to define the shape should not have a null style argument.\n     *\n     * In \"advanced\" API mode this parameter is deprecated.\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name roundedRect\n     */\n\n\n    API.__private__.roundedRect = API.roundedRect = function (x, y, w, h, rx, ry, style) {\n      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h) || isNaN(rx) || isNaN(ry) || !isValidStyle(style)) {\n        throw new Error(\"Invalid arguments passed to jsPDF.roundedRect\");\n      }\n\n      var MyArc = 4 / 3 * (Math.SQRT2 - 1);\n      rx = Math.min(rx, w * 0.5);\n      ry = Math.min(ry, h * 0.5);\n      this.lines([[w - 2 * rx, 0], [rx * MyArc, 0, rx, ry - ry * MyArc, rx, ry], [0, h - 2 * ry], [0, ry * MyArc, -(rx * MyArc), ry, -rx, ry], [-w + 2 * rx, 0], [-(rx * MyArc), 0, -rx, -(ry * MyArc), -rx, -ry], [0, -h + 2 * ry], [0, -(ry * MyArc), rx * MyArc, -ry, rx, -ry]], x + rx, y, // start of path\n      [1, 1], style, true);\n      return this;\n    };\n    /**\n     * Adds an ellipse to PDF.\n     *\n     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n     * @param {number} rx Radius along x axis (in units declared at inception of PDF document)\n     * @param {number} ry Radius along y axis (in units declared at inception of PDF document)\n     * @param {string=} style A string specifying the painting style or null. Valid styles include:\n     * 'S' [default] - stroke,\n     * 'F' - fill,\n     * and 'DF' (or 'FD') -  fill then stroke.\n     * In \"compat\" API mode, a null value postpones setting the style so that a shape may be composed using multiple\n     * method calls. The last drawing method call used to define the shape should not have a null style argument.\n     *\n     * In \"advanced\" API mode this parameter is deprecated.\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name ellipse\n     */\n\n\n    API.__private__.ellipse = API.ellipse = function (x, y, rx, ry, style) {\n      if (isNaN(x) || isNaN(y) || isNaN(rx) || isNaN(ry) || !isValidStyle(style)) {\n        throw new Error(\"Invalid arguments passed to jsPDF.ellipse\");\n      }\n\n      var lx = 4 / 3 * (Math.SQRT2 - 1) * rx,\n          ly = 4 / 3 * (Math.SQRT2 - 1) * ry;\n      moveTo(x + rx, y);\n      curveTo(x + rx, y - ly, x + lx, y - ry, x, y - ry);\n      curveTo(x - lx, y - ry, x - rx, y - ly, x - rx, y);\n      curveTo(x - rx, y + ly, x - lx, y + ry, x, y + ry);\n      curveTo(x + lx, y + ry, x + rx, y + ly, x + rx, y);\n      putStyle(style);\n      return this;\n    };\n    /**\n     * Adds an circle to PDF.\n     *\n     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n     * @param {number} r Radius (in units declared at inception of PDF document)\n     * @param {string=} style A string specifying the painting style or null. Valid styles include:\n     * 'S' [default] - stroke,\n     * 'F' - fill,\n     * and 'DF' (or 'FD') -  fill then stroke.\n     * In \"compat\" API mode, a null value postpones setting the style so that a shape may be composed using multiple\n     * method calls. The last drawing method call used to define the shape should not have a null style argument.\n     *\n     * In \"advanced\" API mode this parameter is deprecated.\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name circle\n     */\n\n\n    API.__private__.circle = API.circle = function (x, y, r, style) {\n      if (isNaN(x) || isNaN(y) || isNaN(r) || !isValidStyle(style)) {\n        throw new Error(\"Invalid arguments passed to jsPDF.circle\");\n      }\n\n      return this.ellipse(x, y, r, r, style);\n    };\n    /**\n     * Sets text font face, variant for upcoming text elements.\n     * See output of jsPDF.getFontList() for possible font names, styles.\n     *\n     * @param {string} fontName Font name or family. Example: \"times\".\n     * @param {string} fontStyle Font style or variant. Example: \"italic\".\n     * @param {number | string} fontWeight Weight of the Font. Example: \"normal\" | 400\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name setFont\n     */\n\n\n    API.setFont = function (fontName, fontStyle, fontWeight) {\n      if (fontWeight) {\n        fontStyle = combineFontStyleAndFontWeight(fontStyle, fontWeight);\n      }\n\n      activeFontKey = getFont(fontName, fontStyle, {\n        disableWarning: false\n      });\n      return this;\n    };\n    /**\n     * Gets text font face, variant for upcoming text elements.\n     *\n     * @function\n     * @instance\n     * @returns {Object}\n     * @memberof jsPDF#\n     * @name getFont\n     */\n\n\n    var getFontEntry = API.__private__.getFont = API.getFont = function () {\n      return fonts[getFont.apply(API, arguments)];\n    };\n    /**\n     * Returns an object - a tree of fontName to fontStyle relationships available to\n     * active PDF document.\n     *\n     * @public\n     * @function\n     * @instance\n     * @returns {Object} Like {'times':['normal', 'italic', ... ], 'arial':['normal', 'bold', ... ], ... }\n     * @memberof jsPDF#\n     * @name getFontList\n     */\n\n\n    API.__private__.getFontList = API.getFontList = function () {\n      var list = {},\n          fontName,\n          fontStyle;\n\n      for (fontName in fontmap) {\n        if (fontmap.hasOwnProperty(fontName)) {\n          list[fontName] = [];\n\n          for (fontStyle in fontmap[fontName]) {\n            if (fontmap[fontName].hasOwnProperty(fontStyle)) {\n              list[fontName].push(fontStyle);\n            }\n          }\n        }\n      }\n\n      return list;\n    };\n    /**\n     * Add a custom font to the current instance.\n     *\n     * @param {string} postScriptName PDF specification full name for the font.\n     * @param {string} id PDF-document-instance-specific label assinged to the font.\n     * @param {string} fontStyle Style of the Font.\n     * @param {number | string} fontWeight Weight of the Font.\n     * @param {Object} encoding Encoding_name-to-Font_metrics_object mapping.\n     * @function\n     * @instance\n     * @memberof jsPDF#\n     * @name addFont\n     * @returns {string} fontId\n     */\n\n\n    API.addFont = function (postScriptName, fontName, fontStyle, fontWeight, encoding) {\n      var encodingOptions = [\"StandardEncoding\", \"MacRomanEncoding\", \"Identity-H\", \"WinAnsiEncoding\"];\n\n      if (arguments[3] && encodingOptions.indexOf(arguments[3]) !== -1) {\n        //IE 11 fix\n        encoding = arguments[3];\n      } else if (arguments[3] && encodingOptions.indexOf(arguments[3]) == -1) {\n        fontStyle = combineFontStyleAndFontWeight(fontStyle, fontWeight);\n      }\n\n      encoding = encoding || \"Identity-H\";\n      return addFont.call(this, postScriptName, fontName, fontStyle, encoding);\n    };\n\n    var lineWidth = options.lineWidth || 0.200025; // 2mm\n\n    /**\n     * Gets the line width, default: 0.200025.\n     *\n     * @function\n     * @instance\n     * @returns {number} lineWidth\n     * @memberof jsPDF#\n     * @name getLineWidth\n     */\n\n    var getLineWidth = API.__private__.getLineWidth = API.getLineWidth = function () {\n      return lineWidth;\n    };\n    /**\n     * Sets line width for upcoming lines.\n     *\n     * @param {number} width Line width (in units declared at inception of PDF document).\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name setLineWidth\n     */\n\n\n    var setLineWidth = API.__private__.setLineWidth = API.setLineWidth = function (width) {\n      lineWidth = width;\n      out(hpf(scale(width)) + \" w\");\n      return this;\n    };\n    /**\n     * Sets the dash pattern for upcoming lines.\n     *\n     * To reset the settings simply call the method without any parameters.\n     * @param {Array<number>} dashArray An array containing 0-2 numbers. The first number sets the length of the\n     * dashes, the second number the length of the gaps. If the second number is missing, the gaps are considered\n     * to be as long as the dashes. An empty array means solid, unbroken lines.\n     * @param {number} dashPhase The phase lines start with.\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name setLineDashPattern\n     */\n\n\n    API.__private__.setLineDash = jsPDF.API.setLineDash = jsPDF.API.setLineDashPattern = function (dashArray, dashPhase) {\n      dashArray = dashArray || [];\n      dashPhase = dashPhase || 0;\n\n      if (isNaN(dashPhase) || !Array.isArray(dashArray)) {\n        throw new Error(\"Invalid arguments passed to jsPDF.setLineDash\");\n      }\n\n      dashArray = dashArray.map(function (x) {\n        return hpf(scale(x));\n      }).join(\" \");\n      dashPhase = hpf(scale(dashPhase));\n      out(\"[\" + dashArray + \"] \" + dashPhase + \" d\");\n      return this;\n    };\n\n    var lineHeightFactor;\n\n    var getLineHeight = API.__private__.getLineHeight = API.getLineHeight = function () {\n      return activeFontSize * lineHeightFactor;\n    };\n\n    API.__private__.getLineHeight = API.getLineHeight = function () {\n      return activeFontSize * lineHeightFactor;\n    };\n    /**\n     * Sets the LineHeightFactor of proportion.\n     *\n     * @param {number} value LineHeightFactor value. Default: 1.15.\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name setLineHeightFactor\n     */\n\n\n    var setLineHeightFactor = API.__private__.setLineHeightFactor = API.setLineHeightFactor = function (value) {\n      value = value || 1.15;\n\n      if (typeof value === \"number\") {\n        lineHeightFactor = value;\n      }\n\n      return this;\n    };\n    /**\n     * Gets the LineHeightFactor, default: 1.15.\n     *\n     * @function\n     * @instance\n     * @returns {number} lineHeightFactor\n     * @memberof jsPDF#\n     * @name getLineHeightFactor\n     */\n\n\n    var getLineHeightFactor = API.__private__.getLineHeightFactor = API.getLineHeightFactor = function () {\n      return lineHeightFactor;\n    };\n\n    setLineHeightFactor(options.lineHeight);\n\n    var getHorizontalCoordinate = API.__private__.getHorizontalCoordinate = function (value) {\n      return scale(value);\n    };\n\n    var getVerticalCoordinate = API.__private__.getVerticalCoordinate = function (value) {\n      if (apiMode === ApiMode.ADVANCED) {\n        return value;\n      } else {\n        var pageHeight = pagesContext[currentPage].mediaBox.topRightY - pagesContext[currentPage].mediaBox.bottomLeftY;\n        return pageHeight - scale(value);\n      }\n    };\n\n    var getHorizontalCoordinateString = API.__private__.getHorizontalCoordinateString = API.getHorizontalCoordinateString = function (value) {\n      return hpf(getHorizontalCoordinate(value));\n    };\n\n    var getVerticalCoordinateString = API.__private__.getVerticalCoordinateString = API.getVerticalCoordinateString = function (value) {\n      return hpf(getVerticalCoordinate(value));\n    };\n\n    var strokeColor = options.strokeColor || \"0 G\";\n    /**\n     *  Gets the stroke color for upcoming elements.\n     *\n     * @function\n     * @instance\n     * @returns {string} colorAsHex\n     * @memberof jsPDF#\n     * @name getDrawColor\n     */\n\n    API.__private__.getStrokeColor = API.getDrawColor = function () {\n      return decodeColorString(strokeColor);\n    };\n    /**\n     * Sets the stroke color for upcoming elements.\n     *\n     * Depending on the number of arguments given, Gray, RGB, or CMYK\n     * color space is implied.\n     *\n     * When only ch1 is given, \"Gray\" color space is implied and it\n     * must be a value in the range from 0.00 (solid black) to to 1.00 (white)\n     * if values are communicated as String types, or in range from 0 (black)\n     * to 255 (white) if communicated as Number type.\n     * The RGB-like 0-255 range is provided for backward compatibility.\n     *\n     * When only ch1,ch2,ch3 are given, \"RGB\" color space is implied and each\n     * value must be in the range from 0.00 (minimum intensity) to to 1.00\n     * (max intensity) if values are communicated as String types, or\n     * from 0 (min intensity) to to 255 (max intensity) if values are communicated\n     * as Number types.\n     * The RGB-like 0-255 range is provided for backward compatibility.\n     *\n     * When ch1,ch2,ch3,ch4 are given, \"CMYK\" color space is implied and each\n     * value must be a in the range from 0.00 (0% concentration) to to\n     * 1.00 (100% concentration)\n     *\n     * Because JavaScript treats fixed point numbers badly (rounds to\n     * floating point nearest to binary representation) it is highly advised to\n     * communicate the fractional numbers as String types, not JavaScript Number type.\n     *\n     * @param {Number|String} ch1 Color channel value or {string} ch1 color value in hexadecimal, example: '#FFFFFF'.\n     * @param {Number} ch2 Color channel value.\n     * @param {Number} ch3 Color channel value.\n     * @param {Number} ch4 Color channel value.\n     *\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name setDrawColor\n     */\n\n\n    API.__private__.setStrokeColor = API.setDrawColor = function (ch1, ch2, ch3, ch4) {\n      var options = {\n        ch1: ch1,\n        ch2: ch2,\n        ch3: ch3,\n        ch4: ch4,\n        pdfColorType: \"draw\",\n        precision: 2\n      };\n      strokeColor = encodeColorString(options);\n      out(strokeColor);\n      return this;\n    };\n\n    var fillColor = options.fillColor || \"0 g\";\n    /**\n     * Gets the fill color for upcoming elements.\n     *\n     * @function\n     * @instance\n     * @returns {string} colorAsHex\n     * @memberof jsPDF#\n     * @name getFillColor\n     */\n\n    API.__private__.getFillColor = API.getFillColor = function () {\n      return decodeColorString(fillColor);\n    };\n    /**\n     * Sets the fill color for upcoming elements.\n     *\n     * Depending on the number of arguments given, Gray, RGB, or CMYK\n     * color space is implied.\n     *\n     * When only ch1 is given, \"Gray\" color space is implied and it\n     * must be a value in the range from 0.00 (solid black) to to 1.00 (white)\n     * if values are communicated as String types, or in range from 0 (black)\n     * to 255 (white) if communicated as Number type.\n     * The RGB-like 0-255 range is provided for backward compatibility.\n     *\n     * When only ch1,ch2,ch3 are given, \"RGB\" color space is implied and each\n     * value must be in the range from 0.00 (minimum intensity) to to 1.00\n     * (max intensity) if values are communicated as String types, or\n     * from 0 (min intensity) to to 255 (max intensity) if values are communicated\n     * as Number types.\n     * The RGB-like 0-255 range is provided for backward compatibility.\n     *\n     * When ch1,ch2,ch3,ch4 are given, \"CMYK\" color space is implied and each\n     * value must be a in the range from 0.00 (0% concentration) to to\n     * 1.00 (100% concentration)\n     *\n     * Because JavaScript treats fixed point numbers badly (rounds to\n     * floating point nearest to binary representation) it is highly advised to\n     * communicate the fractional numbers as String types, not JavaScript Number type.\n     *\n     * @param {Number|String} ch1 Color channel value or {string} ch1 color value in hexadecimal, example: '#FFFFFF'.\n     * @param {Number} ch2 Color channel value.\n     * @param {Number} ch3 Color channel value.\n     * @param {Number} ch4 Color channel value.\n     *\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name setFillColor\n     */\n\n\n    API.__private__.setFillColor = API.setFillColor = function (ch1, ch2, ch3, ch4) {\n      var options = {\n        ch1: ch1,\n        ch2: ch2,\n        ch3: ch3,\n        ch4: ch4,\n        pdfColorType: \"fill\",\n        precision: 2\n      };\n      fillColor = encodeColorString(options);\n      out(fillColor);\n      return this;\n    };\n\n    var textColor = options.textColor || \"0 g\";\n    /**\n     * Gets the text color for upcoming elements.\n     *\n     * @function\n     * @instance\n     * @returns {string} colorAsHex\n     * @memberof jsPDF#\n     * @name getTextColor\n     */\n\n    var getTextColor = API.__private__.getTextColor = API.getTextColor = function () {\n      return decodeColorString(textColor);\n    };\n    /**\n     * Sets the text color for upcoming elements.\n     *\n     * Depending on the number of arguments given, Gray, RGB, or CMYK\n     * color space is implied.\n     *\n     * When only ch1 is given, \"Gray\" color space is implied and it\n     * must be a value in the range from 0.00 (solid black) to to 1.00 (white)\n     * if values are communicated as String types, or in range from 0 (black)\n     * to 255 (white) if communicated as Number type.\n     * The RGB-like 0-255 range is provided for backward compatibility.\n     *\n     * When only ch1,ch2,ch3 are given, \"RGB\" color space is implied and each\n     * value must be in the range from 0.00 (minimum intensity) to to 1.00\n     * (max intensity) if values are communicated as String types, or\n     * from 0 (min intensity) to to 255 (max intensity) if values are communicated\n     * as Number types.\n     * The RGB-like 0-255 range is provided for backward compatibility.\n     *\n     * When ch1,ch2,ch3,ch4 are given, \"CMYK\" color space is implied and each\n     * value must be a in the range from 0.00 (0% concentration) to to\n     * 1.00 (100% concentration)\n     *\n     * Because JavaScript treats fixed point numbers badly (rounds to\n     * floating point nearest to binary representation) it is highly advised to\n     * communicate the fractional numbers as String types, not JavaScript Number type.\n     *\n     * @param {Number|String} ch1 Color channel value or {string} ch1 color value in hexadecimal, example: '#FFFFFF'.\n     * @param {Number} ch2 Color channel value.\n     * @param {Number} ch3 Color channel value.\n     * @param {Number} ch4 Color channel value.\n     *\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name setTextColor\n     */\n\n\n    API.__private__.setTextColor = API.setTextColor = function (ch1, ch2, ch3, ch4) {\n      var options = {\n        ch1: ch1,\n        ch2: ch2,\n        ch3: ch3,\n        ch4: ch4,\n        pdfColorType: \"text\",\n        precision: 3\n      };\n      textColor = encodeColorString(options);\n      return this;\n    };\n\n    var activeCharSpace = options.charSpace;\n    /**\n     * Get global value of CharSpace.\n     *\n     * @function\n     * @instance\n     * @returns {number} charSpace\n     * @memberof jsPDF#\n     * @name getCharSpace\n     */\n\n    var getCharSpace = API.__private__.getCharSpace = API.getCharSpace = function () {\n      return parseFloat(activeCharSpace || 0);\n    };\n    /**\n     * Set global value of CharSpace.\n     *\n     * @param {number} charSpace\n     * @function\n     * @instance\n     * @returns {jsPDF} jsPDF-instance\n     * @memberof jsPDF#\n     * @name setCharSpace\n     */\n\n\n    API.__private__.setCharSpace = API.setCharSpace = function (charSpace) {\n      if (isNaN(charSpace)) {\n        throw new Error(\"Invalid argument passed to jsPDF.setCharSpace\");\n      }\n\n      activeCharSpace = charSpace;\n      return this;\n    };\n\n    var lineCapID = 0;\n    /**\n     * Is an Object providing a mapping from human-readable to\n     * integer flag values designating the varieties of line cap\n     * and join styles.\n     *\n     * @memberof jsPDF#\n     * @name CapJoinStyles\n     */\n\n    API.CapJoinStyles = {\n      0: 0,\n      butt: 0,\n      but: 0,\n      miter: 0,\n      1: 1,\n      round: 1,\n      rounded: 1,\n      circle: 1,\n      2: 2,\n      projecting: 2,\n      project: 2,\n      square: 2,\n      bevel: 2\n    };\n    /**\n     * Sets the line cap styles.\n     * See {jsPDF.CapJoinStyles} for variants.\n     *\n     * @param {String|Number} style A string or number identifying the type of line cap.\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name setLineCap\n     */\n\n    API.__private__.setLineCap = API.setLineCap = function (style) {\n      var id = API.CapJoinStyles[style];\n\n      if (id === undefined) {\n        throw new Error(\"Line cap style of '\" + style + \"' is not recognized. See or extend .CapJoinStyles property for valid styles\");\n      }\n\n      lineCapID = id;\n      out(id + \" J\");\n      return this;\n    };\n\n    var lineJoinID = 0;\n    /**\n     * Sets the line join styles.\n     * See {jsPDF.CapJoinStyles} for variants.\n     *\n     * @param {String|Number} style A string or number identifying the type of line join.\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name setLineJoin\n     */\n\n    API.__private__.setLineJoin = API.setLineJoin = function (style) {\n      var id = API.CapJoinStyles[style];\n\n      if (id === undefined) {\n        throw new Error(\"Line join style of '\" + style + \"' is not recognized. See or extend .CapJoinStyles property for valid styles\");\n      }\n\n      lineJoinID = id;\n      out(id + \" j\");\n      return this;\n    };\n    /**\n     * Sets the miterLimit property, which effects the maximum miter length.\n     *\n     * @param {number} length The length of the miter\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name setLineMiterLimit\n     */\n\n    API.__private__.setLineMiterLimit = API.__private__.setMiterLimit = API.setLineMiterLimit = API.setMiterLimit = function (length) {\n      length = length || 0;\n\n      if (isNaN(length)) {\n        throw new Error(\"Invalid argument passed to jsPDF.setLineMiterLimit\");\n      }\n\n      out(hpf(scale(length)) + \" M\");\n      return this;\n    };\n    /**\n     * An object representing a pdf graphics state.\n     * @class GState\n     */\n\n    /**\n     *\n     * @param parameters A parameter object that contains all properties this graphics state wants to set.\n     * Supported are: opacity, stroke-opacity\n     * @constructor\n     */\n\n\n    API.GState = GState;\n    /**\n     * Sets a either previously added {@link GState} (via {@link addGState}) or a new {@link GState}.\n     * @param {String|GState} gState If type is string, a previously added GState is used, if type is GState\n     * it will be added before use.\n     * @function\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name setGState\n     */\n\n    API.setGState = function (gState) {\n      if (typeof gState === \"string\") {\n        gState = gStates[gStatesMap[gState]];\n      } else {\n        gState = addGState(null, gState);\n      }\n\n      if (!gState.equals(activeGState)) {\n        out(\"/\" + gState.id + \" gs\");\n        activeGState = gState;\n      }\n    };\n    /**\n     * Adds a new Graphics State. Duplicates are automatically eliminated.\n     * @param {String} key Might also be null, if no later reference to this gState is needed\n     * @param {Object} gState The gState object\n     */\n\n\n    var addGState = function addGState(key, gState) {\n      // only add it if it is not already present (the keys provided by the user must be unique!)\n      if (key && gStatesMap[key]) return;\n      var duplicate = false;\n\n      for (var s in gStates) {\n        if (gStates.hasOwnProperty(s)) {\n          if (gStates[s].equals(gState)) {\n            duplicate = true;\n            break;\n          }\n        }\n      }\n\n      if (duplicate) {\n        gState = gStates[s];\n      } else {\n        var gStateKey = \"GS\" + (Object.keys(gStates).length + 1).toString(10);\n        gStates[gStateKey] = gState;\n        gState.id = gStateKey;\n      } // several user keys may point to the same GState object\n\n\n      key && (gStatesMap[key] = gState.id);\n      events.publish(\"addGState\", gState);\n      return gState;\n    };\n    /**\n     * Adds a new {@link GState} for later use. See {@link setGState}.\n     * @param {String} key\n     * @param {GState} gState\n     * @function\n     * @instance\n     * @returns {jsPDF}\n     *\n     * @memberof jsPDF#\n     * @name addGState\n     */\n\n\n    API.addGState = function (key, gState) {\n      addGState(key, gState);\n      return this;\n    };\n    /**\n     * Saves the current graphics state (\"pushes it on the stack\"). It can be restored by {@link restoreGraphicsState}\n     * later. Here, the general pdf graphics state is meant, also including the current transformation matrix,\n     * fill and stroke colors etc.\n     * @function\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name saveGraphicsState\n     */\n\n\n    API.saveGraphicsState = function () {\n      out(\"q\"); // as we cannot set font key and size independently we must keep track of both\n\n      fontStateStack.push({\n        key: activeFontKey,\n        size: activeFontSize,\n        color: textColor\n      });\n      return this;\n    };\n    /**\n     * Restores a previously saved graphics state saved by {@link saveGraphicsState} (\"pops the stack\").\n     * @function\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name restoreGraphicsState\n     */\n\n\n    API.restoreGraphicsState = function () {\n      out(\"Q\"); // restore previous font state\n\n      var fontState = fontStateStack.pop();\n      activeFontKey = fontState.key;\n      activeFontSize = fontState.size;\n      textColor = fontState.color;\n      activeGState = null;\n      return this;\n    };\n    /**\n     * Appends this matrix to the left of all previously applied matrices.\n     *\n     * @param {Matrix} matrix\n     * @function\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name setCurrentTransformationMatrix\n     */\n\n\n    API.setCurrentTransformationMatrix = function (matrix) {\n      out(matrix.toString() + \" cm\");\n      return this;\n    };\n    /**\n     * Inserts a debug comment into the generated pdf.\n     * @function\n     * @instance\n     * @param {String} text\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name comment\n     */\n\n\n    API.comment = function (text) {\n      out(\"#\" + text);\n      return this;\n    };\n    /**\n     * Point\n     */\n\n\n    var Point = function Point(x, y) {\n      var _x = x || 0;\n\n      Object.defineProperty(this, \"x\", {\n        enumerable: true,\n        get: function get() {\n          return _x;\n        },\n        set: function set(value) {\n          if (!isNaN(value)) {\n            _x = parseFloat(value);\n          }\n        }\n      });\n\n      var _y = y || 0;\n\n      Object.defineProperty(this, \"y\", {\n        enumerable: true,\n        get: function get() {\n          return _y;\n        },\n        set: function set(value) {\n          if (!isNaN(value)) {\n            _y = parseFloat(value);\n          }\n        }\n      });\n      var _type = \"pt\";\n      Object.defineProperty(this, \"type\", {\n        enumerable: true,\n        get: function get() {\n          return _type;\n        },\n        set: function set(value) {\n          _type = value.toString();\n        }\n      });\n      return this;\n    };\n    /**\n     * Rectangle\n     */\n\n\n    var Rectangle = function Rectangle(x, y, w, h) {\n      Point.call(this, x, y);\n      this.type = \"rect\";\n\n      var _w = w || 0;\n\n      Object.defineProperty(this, \"w\", {\n        enumerable: true,\n        get: function get() {\n          return _w;\n        },\n        set: function set(value) {\n          if (!isNaN(value)) {\n            _w = parseFloat(value);\n          }\n        }\n      });\n\n      var _h = h || 0;\n\n      Object.defineProperty(this, \"h\", {\n        enumerable: true,\n        get: function get() {\n          return _h;\n        },\n        set: function set(value) {\n          if (!isNaN(value)) {\n            _h = parseFloat(value);\n          }\n        }\n      });\n      return this;\n    };\n    /**\n     * FormObject/RenderTarget\n     */\n\n\n    var RenderTarget = function RenderTarget() {\n      this.page = page;\n      this.currentPage = currentPage;\n      this.pages = pages.slice(0);\n      this.pagesContext = pagesContext.slice(0);\n      this.x = pageX;\n      this.y = pageY;\n      this.matrix = pageMatrix;\n      this.width = getPageWidth(currentPage);\n      this.height = getPageHeight(currentPage);\n      this.outputDestination = outputDestination;\n      this.id = \"\"; // set by endFormObject()\n\n      this.objectNumber = -1; // will be set by putXObject()\n    };\n\n    RenderTarget.prototype.restore = function () {\n      page = this.page;\n      currentPage = this.currentPage;\n      pagesContext = this.pagesContext;\n      pages = this.pages;\n      pageX = this.x;\n      pageY = this.y;\n      pageMatrix = this.matrix;\n      setPageWidth(currentPage, this.width);\n      setPageHeight(currentPage, this.height);\n      outputDestination = this.outputDestination;\n    };\n\n    var beginNewRenderTarget = function beginNewRenderTarget(x, y, width, height, matrix) {\n      // save current state\n      renderTargetStack.push(new RenderTarget()); // clear pages\n\n      page = currentPage = 0;\n      pages = [];\n      pageX = x;\n      pageY = y;\n      pageMatrix = matrix;\n      beginPage([width, height]);\n    };\n\n    var endFormObject = function endFormObject(key) {\n      // only add it if it is not already present (the keys provided by the user must be unique!)\n      if (renderTargetMap[key]) {\n        renderTargetStack.pop().restore();\n        return;\n      } // save the created xObject\n\n\n      var newXObject = new RenderTarget();\n      var xObjectId = \"Xo\" + (Object.keys(renderTargets).length + 1).toString(10);\n      newXObject.id = xObjectId;\n      renderTargetMap[key] = xObjectId;\n      renderTargets[xObjectId] = newXObject;\n      events.publish(\"addFormObject\", newXObject); // restore state from stack\n\n      renderTargetStack.pop().restore();\n    };\n    /**\n     * Starts a new pdf form object, which means that all consequent draw calls target a new independent object\n     * until {@link endFormObject} is called. The created object can be referenced and drawn later using\n     * {@link doFormObject}. Nested form objects are possible.\n     * x, y, width, height set the bounding box that is used to clip the content.\n     *\n     * @param {number} x\n     * @param {number} y\n     * @param {number} width\n     * @param {number} height\n     * @param {Matrix} matrix The matrix that will be applied to convert the form objects coordinate system to\n     * the parent's.\n     * @function\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name beginFormObject\n     */\n\n\n    API.beginFormObject = function (x, y, width, height, matrix) {\n      // The user can set the output target to a new form object. Nested form objects are possible.\n      // Currently, they use the resource dictionary of the surrounding stream. This should be changed, as\n      // the PDF-Spec states:\n      // \"In PDF 1.2 and later versions, form XObjects may be independent of the content streams in which\n      // they appear, and this is strongly recommended although not requiredIn PDF 1.2 and later versions,\n      // form XObjects may be independent of the content streams in which they appear, and this is strongly\n      // recommended although not required\"\n      beginNewRenderTarget(x, y, width, height, matrix);\n      return this;\n    };\n    /**\n     * Completes and saves the form object.\n     * @param {String} key The key by which this form object can be referenced.\n     * @function\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name endFormObject\n     */\n\n\n    API.endFormObject = function (key) {\n      endFormObject(key);\n      return this;\n    };\n    /**\n     * Draws the specified form object by referencing to the respective pdf XObject created with\n     * {@link API.beginFormObject} and {@link endFormObject}.\n     * The location is determined by matrix.\n     *\n     * @param {String} key The key to the form object.\n     * @param {Matrix} matrix The matrix applied before drawing the form object.\n     * @function\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name doFormObject\n     */\n\n\n    API.doFormObject = function (key, matrix) {\n      var xObject = renderTargets[renderTargetMap[key]];\n      out(\"q\");\n      out(matrix.toString() + \" cm\");\n      out(\"/\" + xObject.id + \" Do\");\n      out(\"Q\");\n      return this;\n    };\n    /**\n     * Returns the form object specified by key.\n     * @param key {String}\n     * @returns {{x: number, y: number, width: number, height: number, matrix: Matrix}}\n     * @function\n     * @returns {jsPDF}\n     * @memberof jsPDF#\n     * @name getFormObject\n     */\n\n\n    API.getFormObject = function (key) {\n      var xObject = renderTargets[renderTargetMap[key]];\n      return {\n        x: xObject.x,\n        y: xObject.y,\n        width: xObject.width,\n        height: xObject.height,\n        matrix: xObject.matrix\n      };\n    };\n    /**\n     * Saves as PDF document. An alias of jsPDF.output('save', 'filename.pdf').\n     * Uses FileSaver.js-method saveAs.\n     *\n     * @memberof jsPDF#\n     * @name save\n     * @function\n     * @instance\n     * @param  {string} filename The filename including extension.\n     * @param  {Object} options An Object with additional options, possible options: 'returnPromise'.\n     * @returns {jsPDF|Promise} jsPDF-instance     */\n\n\n    API.save = function (filename, options) {\n      filename = filename || \"generated.pdf\";\n      options = options || {};\n      options.returnPromise = options.returnPromise || false;\n\n      if (options.returnPromise === false) {\n        saveAs(getBlob(buildDocument()), filename);\n\n        if (typeof saveAs.unload === \"function\") {\n          if (globalObject.setTimeout) {\n            setTimeout(saveAs.unload, 911);\n          }\n        }\n\n        return this;\n      } else {\n        return new Promise(function (resolve, reject) {\n          try {\n            var result = saveAs(getBlob(buildDocument()), filename);\n\n            if (typeof saveAs.unload === \"function\") {\n              if (globalObject.setTimeout) {\n                setTimeout(saveAs.unload, 911);\n              }\n            }\n\n            resolve(result);\n          } catch (e) {\n            reject(e.message);\n          }\n        });\n      }\n    }; // applying plugins (more methods) ON TOP of built-in API.\n    // this is intentional as we allow plugins to override\n    // built-ins\n\n\n    for (var plugin in jsPDF.API) {\n      if (jsPDF.API.hasOwnProperty(plugin)) {\n        if (plugin === \"events\" && jsPDF.API.events.length) {\n          (function (events, newEvents) {\n            // jsPDF.API.events is a JS Array of Arrays\n            // where each Array is a pair of event name, handler\n            // Events were added by plugins to the jsPDF instantiator.\n            // These are always added to the new instance and some ran\n            // during instantiation.\n            var eventname, handler_and_args, i;\n\n            for (i = newEvents.length - 1; i !== -1; i--) {\n              // subscribe takes 3 args: 'topic', function, runonce_flag\n              // if undefined, runonce is false.\n              // users can attach callback directly,\n              // or they can attach an array with [callback, runonce_flag]\n              // that's what the \"apply\" magic is for below.\n              eventname = newEvents[i][0];\n              handler_and_args = newEvents[i][1];\n              events.subscribe.apply(events, [eventname].concat(typeof handler_and_args === \"function\" ? [handler_and_args] : handler_and_args));\n            }\n          })(events, jsPDF.API.events);\n        } else {\n          API[plugin] = jsPDF.API[plugin];\n        }\n      }\n    }\n\n    var getPageWidth = API.getPageWidth = function (pageNumber) {\n      pageNumber = pageNumber || currentPage;\n      return (pagesContext[pageNumber].mediaBox.topRightX - pagesContext[pageNumber].mediaBox.bottomLeftX) / scaleFactor;\n    };\n\n    var setPageWidth = API.setPageWidth = function (pageNumber, value) {\n      pagesContext[pageNumber].mediaBox.topRightX = value * scaleFactor + pagesContext[pageNumber].mediaBox.bottomLeftX;\n    };\n\n    var getPageHeight = API.getPageHeight = function (pageNumber) {\n      pageNumber = pageNumber || currentPage;\n      return (pagesContext[pageNumber].mediaBox.topRightY - pagesContext[pageNumber].mediaBox.bottomLeftY) / scaleFactor;\n    };\n\n    var setPageHeight = API.setPageHeight = function (pageNumber, value) {\n      pagesContext[pageNumber].mediaBox.topRightY = value * scaleFactor + pagesContext[pageNumber].mediaBox.bottomLeftY;\n    };\n    /**\n     * Object exposing internal API to plugins\n     * @public\n     * @ignore\n     */\n\n\n    API.internal = {\n      pdfEscape: pdfEscape,\n      getStyle: getStyle,\n      getFont: getFontEntry,\n      getFontSize: getFontSize,\n      getCharSpace: getCharSpace,\n      getTextColor: getTextColor,\n      getLineHeight: getLineHeight,\n      getLineHeightFactor: getLineHeightFactor,\n      getLineWidth: getLineWidth,\n      write: write,\n      getHorizontalCoordinate: getHorizontalCoordinate,\n      getVerticalCoordinate: getVerticalCoordinate,\n      getCoordinateString: getHorizontalCoordinateString,\n      getVerticalCoordinateString: getVerticalCoordinateString,\n      collections: {},\n      newObject: newObject,\n      newAdditionalObject: newAdditionalObject,\n      newObjectDeferred: newObjectDeferred,\n      newObjectDeferredBegin: newObjectDeferredBegin,\n      getFilters: getFilters,\n      putStream: putStream,\n      events: events,\n      scaleFactor: scaleFactor,\n      pageSize: {\n        getWidth: function getWidth() {\n          return getPageWidth(currentPage);\n        },\n        setWidth: function setWidth(value) {\n          setPageWidth(currentPage, value);\n        },\n        getHeight: function getHeight() {\n          return getPageHeight(currentPage);\n        },\n        setHeight: function setHeight(value) {\n          setPageHeight(currentPage, value);\n        }\n      },\n      encryptionOptions: encryptionOptions,\n      encryption: encryption,\n      getEncryptor: getEncryptor,\n      output: output,\n      getNumberOfPages: getNumberOfPages,\n      pages: pages,\n      out: out,\n      f2: f2,\n      f3: f3,\n      getPageInfo: getPageInfo,\n      getPageInfoByObjId: getPageInfoByObjId,\n      getCurrentPageInfo: getCurrentPageInfo,\n      getPDFVersion: getPdfVersion,\n      Point: Point,\n      Rectangle: Rectangle,\n      Matrix: Matrix,\n      hasHotfix: hasHotfix //Expose the hasHotfix check so plugins can also check them.\n\n    };\n    Object.defineProperty(API.internal.pageSize, \"width\", {\n      get: function get() {\n        return getPageWidth(currentPage);\n      },\n      set: function set(value) {\n        setPageWidth(currentPage, value);\n      },\n      enumerable: true,\n      configurable: true\n    });\n    Object.defineProperty(API.internal.pageSize, \"height\", {\n      get: function get() {\n        return getPageHeight(currentPage);\n      },\n      set: function set(value) {\n        setPageHeight(currentPage, value);\n      },\n      enumerable: true,\n      configurable: true\n    }); //////////////////////////////////////////////////////\n    // continuing initialization of jsPDF Document object\n    //////////////////////////////////////////////////////\n    // Add the first page automatically\n\n    addFonts.call(API, standardFonts);\n    activeFontKey = \"F1\";\n\n    _addPage(format, orientation);\n\n    events.publish(\"initialized\");\n    return API;\n  }\n  /**\n   * jsPDF.API is a STATIC property of jsPDF class.\n   * jsPDF.API is an object you can add methods and properties to.\n   * The methods / properties you add will show up in new jsPDF objects.\n   *\n   * One property is prepopulated. It is the 'events' Object. Plugin authors can add topics,\n   * callbacks to this object. These will be reassigned to all new instances of jsPDF.\n   *\n   * @static\n   * @public\n   * @memberof jsPDF#\n   * @name API\n   *\n   * @example\n   * jsPDF.API.mymethod = function(){\n   *   // 'this' will be ref to internal API object. see jsPDF source\n   *   // , so you can refer to built-in methods like so:\n   *   //     this.line(....)\n   *   //     this.text(....)\n   * }\n   * var pdfdoc = new jsPDF()\n   * pdfdoc.mymethod() // <- !!!!!!\n   */\n\n\n  jsPDF.API = {\n    events: []\n  };\n  /**\n   * The version of jsPDF.\n   * @name version\n   * @type {string}\n   * @memberof jsPDF#\n   */\n\n  jsPDF.version = \"2.5.1\";\n\n  var jsPDFAPI = jsPDF.API;\n  var scaleFactor = 1;\n\n  var pdfEscape = function pdfEscape(value) {\n    return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\\(/g, \"\\\\(\").replace(/\\)/g, \"\\\\)\");\n  };\n\n  var pdfUnescape = function pdfUnescape(value) {\n    return value.replace(/\\\\\\\\/g, \"\\\\\").replace(/\\\\\\(/g, \"(\").replace(/\\\\\\)/g, \")\");\n  };\n\n  var f2 = function f2(number) {\n    return number.toFixed(2); // Ie, %.2f\n  };\n\n  var f5 = function f5(number) {\n    return number.toFixed(5); // Ie, %.2f\n  };\n\n  jsPDFAPI.__acroform__ = {};\n\n  var inherit = function inherit(child, parent) {\n    child.prototype = Object.create(parent.prototype);\n    child.prototype.constructor = child;\n  };\n\n  var scale = function scale(x) {\n    return x * scaleFactor;\n  };\n\n  var createFormXObject = function createFormXObject(formObject) {\n    var xobj = new AcroFormXObject();\n    var height = AcroFormAppearance.internal.getHeight(formObject) || 0;\n    var width = AcroFormAppearance.internal.getWidth(formObject) || 0;\n    xobj.BBox = [0, 0, Number(f2(width)), Number(f2(height))];\n    return xobj;\n  };\n  /**\n   * Bit-Operations\n   */\n\n\n  var setBit = jsPDFAPI.__acroform__.setBit = function (number, bitPosition) {\n    number = number || 0;\n    bitPosition = bitPosition || 0;\n\n    if (isNaN(number) || isNaN(bitPosition)) {\n      throw new Error(\"Invalid arguments passed to jsPDF.API.__acroform__.setBit\");\n    }\n\n    var bitMask = 1 << bitPosition;\n    number |= bitMask;\n    return number;\n  };\n\n  var clearBit = jsPDFAPI.__acroform__.clearBit = function (number, bitPosition) {\n    number = number || 0;\n    bitPosition = bitPosition || 0;\n\n    if (isNaN(number) || isNaN(bitPosition)) {\n      throw new Error(\"Invalid arguments passed to jsPDF.API.__acroform__.clearBit\");\n    }\n\n    var bitMask = 1 << bitPosition;\n    number &= ~bitMask;\n    return number;\n  };\n\n  var getBit = jsPDFAPI.__acroform__.getBit = function (number, bitPosition) {\n    if (isNaN(number) || isNaN(bitPosition)) {\n      throw new Error(\"Invalid arguments passed to jsPDF.API.__acroform__.getBit\");\n    }\n\n    return (number & 1 << bitPosition) === 0 ? 0 : 1;\n  };\n  /*\n   * Ff starts counting the bit position at 1 and not like javascript at 0\n   */\n\n\n  var getBitForPdf = jsPDFAPI.__acroform__.getBitForPdf = function (number, bitPosition) {\n    if (isNaN(number) || isNaN(bitPosition)) {\n      throw new Error(\"Invalid arguments passed to jsPDF.API.__acroform__.getBitForPdf\");\n    }\n\n    return getBit(number, bitPosition - 1);\n  };\n\n  var setBitForPdf = jsPDFAPI.__acroform__.setBitForPdf = function (number, bitPosition) {\n    if (isNaN(number) || isNaN(bitPosition)) {\n      throw new Error(\"Invalid arguments passed to jsPDF.API.__acroform__.setBitForPdf\");\n    }\n\n    return setBit(number, bitPosition - 1);\n  };\n\n  var clearBitForPdf = jsPDFAPI.__acroform__.clearBitForPdf = function (number, bitPosition) {\n    if (isNaN(number) || isNaN(bitPosition)) {\n      throw new Error(\"Invalid arguments passed to jsPDF.API.__acroform__.clearBitForPdf\");\n    }\n\n    return clearBit(number, bitPosition - 1);\n  };\n\n  var calculateCoordinates = jsPDFAPI.__acroform__.calculateCoordinates = function (args, scope) {\n    var getHorizontalCoordinate = scope.internal.getHorizontalCoordinate;\n    var getVerticalCoordinate = scope.internal.getVerticalCoordinate;\n    var x = args[0];\n    var y = args[1];\n    var w = args[2];\n    var h = args[3];\n    var coordinates = {};\n    coordinates.lowerLeft_X = getHorizontalCoordinate(x) || 0;\n    coordinates.lowerLeft_Y = getVerticalCoordinate(y + h) || 0;\n    coordinates.upperRight_X = getHorizontalCoordinate(x + w) || 0;\n    coordinates.upperRight_Y = getVerticalCoordinate(y) || 0;\n    return [Number(f2(coordinates.lowerLeft_X)), Number(f2(coordinates.lowerLeft_Y)), Number(f2(coordinates.upperRight_X)), Number(f2(coordinates.upperRight_Y))];\n  };\n\n  var calculateAppearanceStream = function calculateAppearanceStream(formObject) {\n    if (formObject.appearanceStreamContent) {\n      return formObject.appearanceStreamContent;\n    }\n\n    if (!formObject.V && !formObject.DV) {\n      return;\n    } // else calculate it\n\n\n    var stream = [];\n    var text = formObject._V || formObject.DV;\n    var calcRes = calculateX(formObject, text);\n    var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id; //PDF 32000-1:2008, page 444\n\n    stream.push(\"/Tx BMC\");\n    stream.push(\"q\");\n    stream.push(\"BT\"); // Begin Text\n\n    stream.push(formObject.scope.__private__.encodeColorString(formObject.color));\n    stream.push(\"/\" + fontKey + \" \" + f2(calcRes.fontSize) + \" Tf\");\n    stream.push(\"1 0 0 1 0 0 Tm\"); // Transformation Matrix\n\n    stream.push(calcRes.text);\n    stream.push(\"ET\"); // End Text\n\n    stream.push(\"Q\");\n    stream.push(\"EMC\");\n    var appearanceStreamContent = createFormXObject(formObject);\n    appearanceStreamContent.scope = formObject.scope;\n    appearanceStreamContent.stream = stream.join(\"\\n\");\n    return appearanceStreamContent;\n  };\n\n  var calculateX = function calculateX(formObject, text) {\n    var maxFontSize = formObject.fontSize === 0 ? formObject.maxFontSize : formObject.fontSize;\n    var returnValue = {\n      text: \"\",\n      fontSize: \"\"\n    }; // Remove Brackets\n\n    text = text.substr(0, 1) == \"(\" ? text.substr(1) : text;\n    text = text.substr(text.length - 1) == \")\" ? text.substr(0, text.length - 1) : text; // split into array of words\n\n    var textSplit = text.split(\" \");\n\n    if (formObject.multiline) {\n      textSplit = textSplit.map(function (word) {\n        return word.split(\"\\n\");\n      });\n    } else {\n      textSplit = textSplit.map(function (word) {\n        return [word];\n      });\n    }\n\n    var fontSize = maxFontSize; // The Starting fontSize (The Maximum)\n\n    var lineSpacing = 2;\n    var borderPadding = 2;\n    var height = AcroFormAppearance.internal.getHeight(formObject) || 0;\n    height = height < 0 ? -height : height;\n    var width = AcroFormAppearance.internal.getWidth(formObject) || 0;\n    width = width < 0 ? -width : width;\n\n    var isSmallerThanWidth = function isSmallerThanWidth(i, lastLine, fontSize) {\n      if (i + 1 < textSplit.length) {\n        var tmp = lastLine + \" \" + textSplit[i + 1][0];\n        var TextWidth = calculateFontSpace(tmp, formObject, fontSize).width;\n        var FieldWidth = width - 2 * borderPadding;\n        return TextWidth <= FieldWidth;\n      } else {\n        return false;\n      }\n    };\n\n    fontSize++;\n\n    FontSize: while (fontSize > 0) {\n      text = \"\";\n      fontSize--;\n      var textHeight = calculateFontSpace(\"3\", formObject, fontSize).height;\n      var startY = formObject.multiline ? height - fontSize : (height - textHeight) / 2;\n      startY += lineSpacing;\n      var startX;\n      var lastY = startY;\n      var firstWordInLine = 0,\n          lastWordInLine = 0;\n      var lastLength;\n      var currWord = 0;\n\n      if (fontSize <= 0) {\n        // In case, the Text doesn't fit at all\n        fontSize = 12;\n        text = \"(...) Tj\\n\";\n        text += \"% Width of Text: \" + calculateFontSpace(text, formObject, fontSize).width + \", FieldWidth:\" + width + \"\\n\";\n        break;\n      }\n\n      var lastLine = \"\";\n      var lineCount = 0;\n\n      Line: for (var i = 0; i < textSplit.length; i++) {\n        if (textSplit.hasOwnProperty(i)) {\n          var isWithNewLine = false;\n\n          if (textSplit[i].length !== 1 && currWord !== textSplit[i].length - 1) {\n            if ((textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {\n              continue FontSize;\n            }\n\n            lastLine += textSplit[i][currWord];\n            isWithNewLine = true;\n            lastWordInLine = i;\n            i--;\n          } else {\n            lastLine += textSplit[i][currWord] + \" \";\n            lastLine = lastLine.substr(lastLine.length - 1) == \" \" ? lastLine.substr(0, lastLine.length - 1) : lastLine;\n            var key = parseInt(i);\n            var nextLineIsSmaller = isSmallerThanWidth(key, lastLine, fontSize);\n            var isLastWord = i >= textSplit.length - 1;\n\n            if (nextLineIsSmaller && !isLastWord) {\n              lastLine += \" \";\n              currWord = 0;\n              continue; // Line\n            } else if (!nextLineIsSmaller && !isLastWord) {\n              if (!formObject.multiline) {\n                continue FontSize;\n              } else {\n                if ((textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {\n                  // If the Text is higher than the\n                  // FieldObject\n                  continue FontSize;\n                }\n\n                lastWordInLine = key; // go on\n              }\n            } else if (isLastWord) {\n              lastWordInLine = key;\n            } else {\n              if (formObject.multiline && (textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {\n                // If the Text is higher than the FieldObject\n                continue FontSize;\n              }\n            }\n          } // Remove last blank\n\n\n          var line = \"\";\n\n          for (var x = firstWordInLine; x <= lastWordInLine; x++) {\n            var currLine = textSplit[x];\n\n            if (formObject.multiline) {\n              if (x === lastWordInLine) {\n                line += currLine[currWord] + \" \";\n                currWord = (currWord + 1) % currLine.length;\n                continue;\n              }\n\n              if (x === firstWordInLine) {\n                line += currLine[currLine.length - 1] + \" \";\n                continue;\n              }\n            }\n\n            line += currLine[0] + \" \";\n          } // Remove last blank\n\n\n          line = line.substr(line.length - 1) == \" \" ? line.substr(0, line.length - 1) : line; // lastLength -= blankSpace.width;\n\n          lastLength = calculateFontSpace(line, formObject, fontSize).width; // Calculate startX\n\n          switch (formObject.textAlign) {\n            case \"right\":\n              startX = width - lastLength - borderPadding;\n              break;\n\n            case \"center\":\n              startX = (width - lastLength) / 2;\n              break;\n\n            case \"left\":\n            default:\n              startX = borderPadding;\n              break;\n          }\n\n          text += f2(startX) + \" \" + f2(lastY) + \" Td\\n\";\n          text += \"(\" + pdfEscape(line) + \") Tj\\n\"; // reset X in PDF\n\n          text += -f2(startX) + \" 0 Td\\n\"; // After a Line, adjust y position\n\n          lastY = -(fontSize + lineSpacing); // Reset for next iteration step\n\n          lastLength = 0;\n          firstWordInLine = isWithNewLine ? lastWordInLine : lastWordInLine + 1;\n          lineCount++;\n          lastLine = \"\";\n          continue Line;\n        }\n      }\n\n      break;\n    }\n\n    returnValue.text = text;\n    returnValue.fontSize = fontSize;\n    return returnValue;\n  };\n  /**\n   * Small workaround for calculating the TextMetric approximately.\n   *\n   * @param text\n   * @param fontsize\n   * @returns {TextMetrics} (Has Height and Width)\n   */\n\n\n  var calculateFontSpace = function calculateFontSpace(text, formObject, fontSize) {\n    var font = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle);\n    var width = formObject.scope.getStringUnitWidth(text, {\n      font: font,\n      fontSize: parseFloat(fontSize),\n      charSpace: 0\n    }) * parseFloat(fontSize);\n    var height = formObject.scope.getStringUnitWidth(\"3\", {\n      font: font,\n      fontSize: parseFloat(fontSize),\n      charSpace: 0\n    }) * parseFloat(fontSize) * 1.5;\n    return {\n      height: height,\n      width: width\n    };\n  };\n\n  var acroformPluginTemplate = {\n    fields: [],\n    xForms: [],\n\n    /**\n     * acroFormDictionaryRoot contains information about the AcroForm\n     * Dictionary 0: The Event-Token, the AcroFormDictionaryCallback has\n     * 1: The Object ID of the Root\n     */\n    acroFormDictionaryRoot: null,\n\n    /**\n     * After the PDF gets evaluated, the reference to the root has to be\n     * reset, this indicates, whether the root has already been printed\n     * out\n     */\n    printedOut: false,\n    internal: null,\n    isInitialized: false\n  };\n\n  var annotReferenceCallback = function annotReferenceCallback(scope) {\n    //set objId to undefined and force it to get a new objId on buildDocument\n    scope.internal.acroformPlugin.acroFormDictionaryRoot.objId = undefined;\n    var fields = scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields;\n\n    for (var i in fields) {\n      if (fields.hasOwnProperty(i)) {\n        var formObject = fields[i]; //set objId to undefined and force it to get a new objId on buildDocument\n\n        formObject.objId = undefined; // add Annot Reference!\n\n        if (formObject.hasAnnotation) {\n          // If theres an Annotation Widget in the Form Object, put the\n          // Reference in the /Annot array\n          createAnnotationReference(formObject, scope);\n        }\n      }\n    }\n  };\n\n  var putForm = function putForm(formObject) {\n    if (formObject.scope.internal.acroformPlugin.printedOut) {\n      formObject.scope.internal.acroformPlugin.printedOut = false;\n      formObject.scope.internal.acroformPlugin.acroFormDictionaryRoot = null;\n    }\n\n    formObject.scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields.push(formObject);\n  };\n  /**\n   * Create the Reference to the widgetAnnotation, so that it gets referenced\n   * in the Annot[] int the+ (Requires the Annotation Plugin)\n   */\n\n\n  var createAnnotationReference = function createAnnotationReference(object, scope) {\n    var options = {\n      type: \"reference\",\n      object: object\n    };\n\n    var findEntry = function findEntry(entry) {\n      return entry.type === options.type && entry.object === options.object;\n    };\n\n    if (scope.internal.getPageInfo(object.page).pageContext.annotations.find(findEntry) === undefined) {\n      scope.internal.getPageInfo(object.page).pageContext.annotations.push(options);\n    }\n  }; // Callbacks\n\n\n  var putCatalogCallback = function putCatalogCallback(scope) {\n    // Put reference to AcroForm to DocumentCatalog\n    if (typeof scope.internal.acroformPlugin.acroFormDictionaryRoot !== \"undefined\") {\n      // for safety, shouldn't normally be the case\n      scope.internal.write(\"/AcroForm \" + scope.internal.acroformPlugin.acroFormDictionaryRoot.objId + \" \" + 0 + \" R\");\n    } else {\n      throw new Error(\"putCatalogCallback: Root missing.\");\n    }\n  };\n  /**\n   * Adds /Acroform X 0 R to Document Catalog, and creates the AcroForm\n   * Dictionary\n   */\n\n\n  var AcroFormDictionaryCallback = function AcroFormDictionaryCallback(scope) {\n    // Remove event\n    scope.internal.events.unsubscribe(scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID);\n    delete scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID;\n    scope.internal.acroformPlugin.printedOut = true;\n  };\n  /**\n   * Creates the single Fields and writes them into the Document\n   *\n   * If fieldArray is set, use the fields that are inside it instead of the\n   * fields from the AcroRoot (for the FormXObjects...)\n   */\n\n\n  var createFieldCallback = function createFieldCallback(fieldArray, scope) {\n    var standardFields = !fieldArray;\n\n    if (!fieldArray) {\n      // in case there is no fieldArray specified, we want to print out\n      // the Fields of the AcroForm\n      // Print out Root\n      scope.internal.newObjectDeferredBegin(scope.internal.acroformPlugin.acroFormDictionaryRoot.objId, true);\n      scope.internal.acroformPlugin.acroFormDictionaryRoot.putStream();\n    }\n\n    fieldArray = fieldArray || scope.internal.acroformPlugin.acroFormDictionaryRoot.Kids;\n\n    for (var i in fieldArray) {\n      if (fieldArray.hasOwnProperty(i)) {\n        var fieldObject = fieldArray[i];\n        var keyValueList = [];\n        var oldRect = fieldObject.Rect;\n\n        if (fieldObject.Rect) {\n          fieldObject.Rect = calculateCoordinates(fieldObject.Rect, scope);\n        } // Start Writing the Object\n\n\n        scope.internal.newObjectDeferredBegin(fieldObject.objId, true);\n        fieldObject.DA = AcroFormAppearance.createDefaultAppearanceStream(fieldObject);\n\n        if (_typeof(fieldObject) === \"object\" && typeof fieldObject.getKeyValueListForStream === \"function\") {\n          keyValueList = fieldObject.getKeyValueListForStream();\n        }\n\n        fieldObject.Rect = oldRect;\n\n        if (fieldObject.hasAppearanceStream && !fieldObject.appearanceStreamContent) {\n          // Calculate Appearance\n          var appearance = calculateAppearanceStream(fieldObject);\n          keyValueList.push({\n            key: \"AP\",\n            value: \"<</N \" + appearance + \">>\"\n          });\n          scope.internal.acroformPlugin.xForms.push(appearance);\n        } // Assume AppearanceStreamContent is a Array with N,R,D (at least\n        // one of them!)\n\n\n        if (fieldObject.appearanceStreamContent) {\n          var appearanceStreamString = \"\"; // Iterate over N,R and D\n\n          for (var k in fieldObject.appearanceStreamContent) {\n            if (fieldObject.appearanceStreamContent.hasOwnProperty(k)) {\n              var value = fieldObject.appearanceStreamContent[k];\n              appearanceStreamString += \"/\" + k + \" \";\n              appearanceStreamString += \"<<\";\n\n              if (Object.keys(value).length >= 1 || Array.isArray(value)) {\n                // appearanceStream is an Array or Object!\n                for (var i in value) {\n                  if (value.hasOwnProperty(i)) {\n                    var obj = value[i];\n\n                    if (typeof obj === \"function\") {\n                      // if Function is referenced, call it in order\n                      // to get the FormXObject\n                      obj = obj.call(scope, fieldObject);\n                    }\n\n                    appearanceStreamString += \"/\" + i + \" \" + obj + \" \"; // In case the XForm is already used, e.g. OffState\n                    // of CheckBoxes, don't add it\n\n                    if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj);\n                  }\n                }\n              } else {\n                obj = value;\n\n                if (typeof obj === \"function\") {\n                  // if Function is referenced, call it in order to\n                  // get the FormXObject\n                  obj = obj.call(scope, fieldObject);\n                }\n\n                appearanceStreamString += \"/\" + i + \" \" + obj;\n                if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj);\n              }\n\n              appearanceStreamString += \">>\";\n            }\n          } // appearance stream is a normal Object..\n\n\n          keyValueList.push({\n            key: \"AP\",\n            value: \"<<\\n\" + appearanceStreamString + \">>\"\n          });\n        }\n\n        scope.internal.putStream({\n          additionalKeyValues: keyValueList,\n          objectId: fieldObject.objId\n        });\n        scope.internal.out(\"endobj\");\n      }\n    }\n\n    if (standardFields) {\n      createXFormObjectCallback(scope.internal.acroformPlugin.xForms, scope);\n    }\n  };\n\n  var createXFormObjectCallback = function createXFormObjectCallback(fieldArray, scope) {\n    for (var i in fieldArray) {\n      if (fieldArray.hasOwnProperty(i)) {\n        var key = i;\n        var fieldObject = fieldArray[i]; // Start Writing the Object\n\n        scope.internal.newObjectDeferredBegin(fieldObject.objId, true);\n\n        if (_typeof(fieldObject) === \"object\" && typeof fieldObject.putStream === \"function\") {\n          fieldObject.putStream();\n        }\n\n        delete fieldArray[key];\n      }\n    }\n  };\n\n  var initializeAcroForm = function initializeAcroForm(scope, formObject) {\n    formObject.scope = scope;\n\n    if (scope.internal !== undefined && (scope.internal.acroformPlugin === undefined || scope.internal.acroformPlugin.isInitialized === false)) {\n      AcroFormField.FieldNum = 0;\n      scope.internal.acroformPlugin = JSON.parse(JSON.stringify(acroformPluginTemplate));\n\n      if (scope.internal.acroformPlugin.acroFormDictionaryRoot) {\n        throw new Error(\"Exception while creating AcroformDictionary\");\n      }\n\n      scaleFactor = scope.internal.scaleFactor; // The Object Number of the AcroForm Dictionary\n\n      scope.internal.acroformPlugin.acroFormDictionaryRoot = new AcroFormDictionary();\n      scope.internal.acroformPlugin.acroFormDictionaryRoot.scope = scope; // add Callback for creating the AcroForm Dictionary\n\n      scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID = scope.internal.events.subscribe(\"postPutResources\", function () {\n        AcroFormDictionaryCallback(scope);\n      });\n      scope.internal.events.subscribe(\"buildDocument\", function () {\n        annotReferenceCallback(scope);\n      }); // buildDocument\n      // Register event, that is triggered when the DocumentCatalog is\n      // written, in order to add /AcroForm\n\n      scope.internal.events.subscribe(\"putCatalog\", function () {\n        putCatalogCallback(scope);\n      }); // Register event, that creates all Fields\n\n      scope.internal.events.subscribe(\"postPutPages\", function (fieldArray) {\n        createFieldCallback(fieldArray, scope);\n      });\n      scope.internal.acroformPlugin.isInitialized = true;\n    }\n  }; //PDF 32000-1:2008, page 26, 7.3.6\n\n\n  var arrayToPdfArray = jsPDFAPI.__acroform__.arrayToPdfArray = function (array, objId, scope) {\n    var encryptor = function encryptor(data) {\n      return data;\n    };\n\n    if (Array.isArray(array)) {\n      var content = \"[\";\n\n      for (var i = 0; i < array.length; i++) {\n        if (i !== 0) {\n          content += \" \";\n        }\n\n        switch (_typeof(array[i])) {\n          case \"boolean\":\n          case \"number\":\n          case \"object\":\n            content += array[i].toString();\n            break;\n\n          case \"string\":\n            if (array[i].substr(0, 1) !== \"/\") {\n              if (typeof objId !== \"undefined\" && scope) encryptor = scope.internal.getEncryptor(objId);\n              content += \"(\" + pdfEscape(encryptor(array[i].toString())) + \")\";\n            } else {\n              content += array[i].toString();\n            }\n\n            break;\n        }\n      }\n\n      content += \"]\";\n      return content;\n    }\n\n    throw new Error(\"Invalid argument passed to jsPDF.__acroform__.arrayToPdfArray\");\n  };\n\n  function getMatches(string, regex, index) {\n    index || (index = 1); // default to the first capturing group\n\n    var matches = [];\n    var match;\n\n    while (match = regex.exec(string)) {\n      matches.push(match[index]);\n    }\n\n    return matches;\n  }\n\n  var pdfArrayToStringArray = function pdfArrayToStringArray(array) {\n    var result = [];\n\n    if (typeof array === \"string\") {\n      result = getMatches(array, /\\((.*?)\\)/g);\n    }\n\n    return result;\n  };\n\n  var toPdfString = function toPdfString(string, objId, scope) {\n    var encryptor = function encryptor(data) {\n      return data;\n    };\n\n    if (typeof objId !== \"undefined\" && scope) encryptor = scope.internal.getEncryptor(objId);\n    string = string || \"\";\n    string.toString();\n    string = \"(\" + pdfEscape(encryptor(string)) + \")\";\n    return string;\n  }; // ##########################\n  // Classes\n  // ##########################\n\n  /**\n   * @class AcroFormPDFObject\n   * @classdesc A AcroFormPDFObject\n   */\n\n\n  var AcroFormPDFObject = function AcroFormPDFObject() {\n    this._objId = undefined;\n    this._scope = undefined;\n    /**\n     * @name AcroFormPDFObject#objId\n     * @type {any}\n     */\n\n    Object.defineProperty(this, \"objId\", {\n      get: function get() {\n        if (typeof this._objId === \"undefined\") {\n          if (typeof this.scope === \"undefined\") {\n            return undefined;\n          }\n\n          this._objId = this.scope.internal.newObjectDeferred();\n        }\n\n        return this._objId;\n      },\n      set: function set(value) {\n        this._objId = value;\n      }\n    });\n    Object.defineProperty(this, \"scope\", {\n      value: this._scope,\n      writable: true\n    });\n  };\n  /**\n   * @function AcroFormPDFObject.toString\n   */\n\n\n  AcroFormPDFObject.prototype.toString = function () {\n    return this.objId + \" 0 R\";\n  };\n\n  AcroFormPDFObject.prototype.putStream = function () {\n    var keyValueList = this.getKeyValueListForStream();\n    this.scope.internal.putStream({\n      data: this.stream,\n      additionalKeyValues: keyValueList,\n      objectId: this.objId\n    });\n    this.scope.internal.out(\"endobj\");\n  };\n  /**\n   * Returns an key-value-List of all non-configurable Variables from the Object\n   *\n   * @name getKeyValueListForStream\n   * @returns {string}\n   */\n\n\n  AcroFormPDFObject.prototype.getKeyValueListForStream = function () {\n    var keyValueList = [];\n    var keys = Object.getOwnPropertyNames(this).filter(function (key) {\n      return key != \"content\" && key != \"appearanceStreamContent\" && key != \"scope\" && key != \"objId\" && key.substring(0, 1) != \"_\";\n    });\n\n    for (var i in keys) {\n      if (Object.getOwnPropertyDescriptor(this, keys[i]).configurable === false) {\n        var key = keys[i];\n        var value = this[key];\n\n        if (value) {\n          if (Array.isArray(value)) {\n            keyValueList.push({\n              key: key,\n              value: arrayToPdfArray(value, this.objId, this.scope)\n            });\n          } else if (value instanceof AcroFormPDFObject) {\n            // In case it is a reference to another PDFObject,\n            // take the reference number\n            value.scope = this.scope;\n            keyValueList.push({\n              key: key,\n              value: value.objId + \" 0 R\"\n            });\n          } else if (typeof value !== \"function\") {\n            keyValueList.push({\n              key: key,\n              value: value\n            });\n          }\n        }\n      }\n    }\n\n    return keyValueList;\n  };\n\n  var AcroFormXObject = function AcroFormXObject() {\n    AcroFormPDFObject.call(this);\n    Object.defineProperty(this, \"Type\", {\n      value: \"/XObject\",\n      configurable: false,\n      writable: true\n    });\n    Object.defineProperty(this, \"Subtype\", {\n      value: \"/Form\",\n      configurable: false,\n      writable: true\n    });\n    Object.defineProperty(this, \"FormType\", {\n      value: 1,\n      configurable: false,\n      writable: true\n    });\n    var _BBox = [];\n    Object.defineProperty(this, \"BBox\", {\n      configurable: false,\n      get: function get() {\n        return _BBox;\n      },\n      set: function set(value) {\n        _BBox = value;\n      }\n    });\n    Object.defineProperty(this, \"Resources\", {\n      value: \"2 0 R\",\n      configurable: false,\n      writable: true\n    });\n\n    var _stream;\n\n    Object.defineProperty(this, \"stream\", {\n      enumerable: false,\n      configurable: true,\n      set: function set(value) {\n        _stream = value.trim();\n      },\n      get: function get() {\n        if (_stream) {\n          return _stream;\n        } else {\n          return null;\n        }\n      }\n    });\n  };\n\n  inherit(AcroFormXObject, AcroFormPDFObject);\n\n  var AcroFormDictionary = function AcroFormDictionary() {\n    AcroFormPDFObject.call(this);\n    var _Kids = [];\n    Object.defineProperty(this, \"Kids\", {\n      enumerable: false,\n      configurable: true,\n      get: function get() {\n        if (_Kids.length > 0) {\n          return _Kids;\n        } else {\n          return undefined;\n        }\n      }\n    });\n    Object.defineProperty(this, \"Fields\", {\n      enumerable: false,\n      configurable: false,\n      get: function get() {\n        return _Kids;\n      }\n    }); // Default Appearance\n\n    var _DA;\n\n    Object.defineProperty(this, \"DA\", {\n      enumerable: false,\n      configurable: false,\n      get: function get() {\n        if (!_DA) {\n          return undefined;\n        }\n\n        var encryptor = function encryptor(data) {\n          return data;\n        };\n\n        if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId);\n        return \"(\" + pdfEscape(encryptor(_DA)) + \")\";\n      },\n      set: function set(value) {\n        _DA = value;\n      }\n    });\n  };\n\n  inherit(AcroFormDictionary, AcroFormPDFObject);\n  /**\n   * The Field Object contains the Variables, that every Field needs\n   *\n   * @class AcroFormField\n   * @classdesc An AcroForm FieldObject\n   */\n\n  var AcroFormField = function AcroFormField() {\n    AcroFormPDFObject.call(this); //Annotation-Flag See Table 165\n\n    var _F = 4;\n    Object.defineProperty(this, \"F\", {\n      enumerable: false,\n      configurable: false,\n      get: function get() {\n        return _F;\n      },\n      set: function set(value) {\n        if (!isNaN(value)) {\n          _F = value;\n        } else {\n          throw new Error('Invalid value \"' + value + '\" for attribute F supplied.');\n        }\n      }\n    });\n    /**\n     * (PDF 1.2) If set, print the annotation when the page is printed. If clear, never print the annotation, regardless of wether is is displayed on the screen.\n     * NOTE 2 This can be useful for annotations representing interactive pushbuttons, which would serve no meaningful purpose on the printed page.\n     *\n     * @name AcroFormField#showWhenPrinted\n     * @default true\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"showWhenPrinted\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(_F, 3));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.F = setBitForPdf(_F, 3);\n        } else {\n          this.F = clearBitForPdf(_F, 3);\n        }\n      }\n    });\n    var _Ff = 0;\n    Object.defineProperty(this, \"Ff\", {\n      enumerable: false,\n      configurable: false,\n      get: function get() {\n        return _Ff;\n      },\n      set: function set(value) {\n        if (!isNaN(value)) {\n          _Ff = value;\n        } else {\n          throw new Error('Invalid value \"' + value + '\" for attribute Ff supplied.');\n        }\n      }\n    });\n    var _Rect = [];\n    Object.defineProperty(this, \"Rect\", {\n      enumerable: false,\n      configurable: false,\n      get: function get() {\n        if (_Rect.length === 0) {\n          return undefined;\n        }\n\n        return _Rect;\n      },\n      set: function set(value) {\n        if (typeof value !== \"undefined\") {\n          _Rect = value;\n        } else {\n          _Rect = [];\n        }\n      }\n    });\n    /**\n     * The x-position of the field.\n     *\n     * @name AcroFormField#x\n     * @default null\n     * @type {number}\n     */\n\n    Object.defineProperty(this, \"x\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        if (!_Rect || isNaN(_Rect[0])) {\n          return 0;\n        }\n\n        return _Rect[0];\n      },\n      set: function set(value) {\n        _Rect[0] = value;\n      }\n    });\n    /**\n     * The y-position of the field.\n     *\n     * @name AcroFormField#y\n     * @default null\n     * @type {number}\n     */\n\n    Object.defineProperty(this, \"y\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        if (!_Rect || isNaN(_Rect[1])) {\n          return 0;\n        }\n\n        return _Rect[1];\n      },\n      set: function set(value) {\n        _Rect[1] = value;\n      }\n    });\n    /**\n     * The width of the field.\n     *\n     * @name AcroFormField#width\n     * @default null\n     * @type {number}\n     */\n\n    Object.defineProperty(this, \"width\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        if (!_Rect || isNaN(_Rect[2])) {\n          return 0;\n        }\n\n        return _Rect[2];\n      },\n      set: function set(value) {\n        _Rect[2] = value;\n      }\n    });\n    /**\n     * The height of the field.\n     *\n     * @name AcroFormField#height\n     * @default null\n     * @type {number}\n     */\n\n    Object.defineProperty(this, \"height\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        if (!_Rect || isNaN(_Rect[3])) {\n          return 0;\n        }\n\n        return _Rect[3];\n      },\n      set: function set(value) {\n        _Rect[3] = value;\n      }\n    });\n    var _FT = \"\";\n    Object.defineProperty(this, \"FT\", {\n      enumerable: true,\n      configurable: false,\n      get: function get() {\n        return _FT;\n      },\n      set: function set(value) {\n        switch (value) {\n          case \"/Btn\":\n          case \"/Tx\":\n          case \"/Ch\":\n          case \"/Sig\":\n            _FT = value;\n            break;\n\n          default:\n            throw new Error('Invalid value \"' + value + '\" for attribute FT supplied.');\n        }\n      }\n    });\n    var _T = null;\n    Object.defineProperty(this, \"T\", {\n      enumerable: true,\n      configurable: false,\n      get: function get() {\n        if (!_T || _T.length < 1) {\n          // In case of a Child from a Radio´Group, you don't need a FieldName\n          if (this instanceof AcroFormChildClass) {\n            return undefined;\n          }\n\n          _T = \"FieldObject\" + AcroFormField.FieldNum++;\n        }\n\n        var encryptor = function encryptor(data) {\n          return data;\n        };\n\n        if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId);\n        return \"(\" + pdfEscape(encryptor(_T)) + \")\";\n      },\n      set: function set(value) {\n        _T = value.toString();\n      }\n    });\n    /**\n     * (Optional) The partial field name (see 12.7.3.2, “Field Names”).\n     *\n     * @name AcroFormField#fieldName\n     * @default null\n     * @type {string}\n     */\n\n    Object.defineProperty(this, \"fieldName\", {\n      configurable: true,\n      enumerable: true,\n      get: function get() {\n        return _T;\n      },\n      set: function set(value) {\n        _T = value;\n      }\n    });\n    var _fontName = \"helvetica\";\n    /**\n     * The fontName of the font to be used.\n     *\n     * @name AcroFormField#fontName\n     * @default 'helvetica'\n     * @type {string}\n     */\n\n    Object.defineProperty(this, \"fontName\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return _fontName;\n      },\n      set: function set(value) {\n        _fontName = value;\n      }\n    });\n    var _fontStyle = \"normal\";\n    /**\n     * The fontStyle of the font to be used.\n     *\n     * @name AcroFormField#fontStyle\n     * @default 'normal'\n     * @type {string}\n     */\n\n    Object.defineProperty(this, \"fontStyle\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return _fontStyle;\n      },\n      set: function set(value) {\n        _fontStyle = value;\n      }\n    });\n    var _fontSize = 0;\n    /**\n     * The fontSize of the font to be used.\n     *\n     * @name AcroFormField#fontSize\n     * @default 0 (for auto)\n     * @type {number}\n     */\n\n    Object.defineProperty(this, \"fontSize\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return _fontSize;\n      },\n      set: function set(value) {\n        _fontSize = value;\n      }\n    });\n    var _maxFontSize = undefined;\n    /**\n     * The maximum fontSize of the font to be used.\n     *\n     * @name AcroFormField#maxFontSize\n     * @default 0 (for auto)\n     * @type {number}\n     */\n\n    Object.defineProperty(this, \"maxFontSize\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        if (_maxFontSize === undefined) {\n          // use the old default value here - the value is some kind of random as it depends on the scaleFactor (user unit)\n          // (\"50\" is transformed to the \"user space\" but then used in \"pdf space\")\n          return 50 / scaleFactor;\n        } else {\n          return _maxFontSize;\n        }\n      },\n      set: function set(value) {\n        _maxFontSize = value;\n      }\n    });\n    var _color = \"black\";\n    /**\n     * The color of the text\n     *\n     * @name AcroFormField#color\n     * @default 'black'\n     * @type {string|rgba}\n     */\n\n    Object.defineProperty(this, \"color\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return _color;\n      },\n      set: function set(value) {\n        _color = value;\n      }\n    });\n    var _DA = \"/F1 0 Tf 0 g\"; // Defines the default appearance (Needed for variable Text)\n\n    Object.defineProperty(this, \"DA\", {\n      enumerable: true,\n      configurable: false,\n      get: function get() {\n        if (!_DA || this instanceof AcroFormChildClass || this instanceof AcroFormTextField) {\n          return undefined;\n        }\n\n        return toPdfString(_DA, this.objId, this.scope);\n      },\n      set: function set(value) {\n        value = value.toString();\n        _DA = value;\n      }\n    });\n    var _DV = null;\n    Object.defineProperty(this, \"DV\", {\n      enumerable: false,\n      configurable: false,\n      get: function get() {\n        if (!_DV) {\n          return undefined;\n        }\n\n        if (this instanceof AcroFormButton === false) {\n          return toPdfString(_DV, this.objId, this.scope);\n        }\n\n        return _DV;\n      },\n      set: function set(value) {\n        value = value.toString();\n\n        if (this instanceof AcroFormButton === false) {\n          if (value.substr(0, 1) === \"(\") {\n            _DV = pdfUnescape(value.substr(1, value.length - 2));\n          } else {\n            _DV = pdfUnescape(value);\n          }\n        } else {\n          _DV = value;\n        }\n      }\n    });\n    /**\n     * (Optional; inheritable) The default value to which the field reverts when a reset-form action is executed (see 12.7.5.3, “Reset-Form Action”). The format of this value is the same as that of value.\n     *\n     * @name AcroFormField#defaultValue\n     * @default null\n     * @type {any}\n     */\n\n    Object.defineProperty(this, \"defaultValue\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        if (this instanceof AcroFormButton === true) {\n          return pdfUnescape(_DV.substr(1, _DV.length - 1));\n        } else {\n          return _DV;\n        }\n      },\n      set: function set(value) {\n        value = value.toString();\n\n        if (this instanceof AcroFormButton === true) {\n          _DV = \"/\" + value;\n        } else {\n          _DV = value;\n        }\n      }\n    });\n    var _V = null;\n    Object.defineProperty(this, \"_V\", {\n      enumerable: false,\n      configurable: false,\n      get: function get() {\n        if (!_V) {\n          return undefined;\n        }\n\n        return _V;\n      },\n      set: function set(value) {\n        this.V = value;\n      }\n    });\n    Object.defineProperty(this, \"V\", {\n      enumerable: false,\n      configurable: false,\n      get: function get() {\n        if (!_V) {\n          return undefined;\n        }\n\n        if (this instanceof AcroFormButton === false) {\n          return toPdfString(_V, this.objId, this.scope);\n        }\n\n        return _V;\n      },\n      set: function set(value) {\n        value = value.toString();\n\n        if (this instanceof AcroFormButton === false) {\n          if (value.substr(0, 1) === \"(\") {\n            _V = pdfUnescape(value.substr(1, value.length - 2));\n          } else {\n            _V = pdfUnescape(value);\n          }\n        } else {\n          _V = value;\n        }\n      }\n    });\n    /**\n     * (Optional; inheritable) The field’s value, whose format varies depending on the field type. See the descriptions of individual field types for further information.\n     *\n     * @name AcroFormField#value\n     * @default null\n     * @type {any}\n     */\n\n    Object.defineProperty(this, \"value\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        if (this instanceof AcroFormButton === true) {\n          return pdfUnescape(_V.substr(1, _V.length - 1));\n        } else {\n          return _V;\n        }\n      },\n      set: function set(value) {\n        value = value.toString();\n\n        if (this instanceof AcroFormButton === true) {\n          _V = \"/\" + value;\n        } else {\n          _V = value;\n        }\n      }\n    });\n    /**\n     * Check if field has annotations\n     *\n     * @name AcroFormField#hasAnnotation\n     * @readonly\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"hasAnnotation\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return this.Rect;\n      }\n    });\n    Object.defineProperty(this, \"Type\", {\n      enumerable: true,\n      configurable: false,\n      get: function get() {\n        return this.hasAnnotation ? \"/Annot\" : null;\n      }\n    });\n    Object.defineProperty(this, \"Subtype\", {\n      enumerable: true,\n      configurable: false,\n      get: function get() {\n        return this.hasAnnotation ? \"/Widget\" : null;\n      }\n    });\n    var _hasAppearanceStream = false;\n    /**\n     * true if field has an appearanceStream\n     *\n     * @name AcroFormField#hasAppearanceStream\n     * @readonly\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"hasAppearanceStream\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return _hasAppearanceStream;\n      },\n      set: function set(value) {\n        value = Boolean(value);\n        _hasAppearanceStream = value;\n      }\n    });\n    /**\n     * The page on which the AcroFormField is placed\n     *\n     * @name AcroFormField#page\n     * @type {number}\n     */\n\n    var _page;\n\n    Object.defineProperty(this, \"page\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        if (!_page) {\n          return undefined;\n        }\n\n        return _page;\n      },\n      set: function set(value) {\n        _page = value;\n      }\n    });\n    /**\n     * If set, the user may not change the value of the field. Any associated widget annotations will not interact with the user; that is, they will not respond to mouse clicks or change their appearance in response to mouse motions. This flag is useful for fields whose values are computed or imported from a database.\n     *\n     * @name AcroFormField#readOnly\n     * @default false\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"readOnly\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 1));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 1);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 1);\n        }\n      }\n    });\n    /**\n     * If set, the field shall have a value at the time it is exported by a submitform action (see 12.7.5.2, “Submit-Form Action”).\n     *\n     * @name AcroFormField#required\n     * @default false\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"required\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 2));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 2);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 2);\n        }\n      }\n    });\n    /**\n     * If set, the field shall not be exported by a submit-form action (see 12.7.5.2, “Submit-Form Action”)\n     *\n     * @name AcroFormField#noExport\n     * @default false\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"noExport\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 3));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 3);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 3);\n        }\n      }\n    });\n    var _Q = null;\n    Object.defineProperty(this, \"Q\", {\n      enumerable: true,\n      configurable: false,\n      get: function get() {\n        if (_Q === null) {\n          return undefined;\n        }\n\n        return _Q;\n      },\n      set: function set(value) {\n        if ([0, 1, 2].indexOf(value) !== -1) {\n          _Q = value;\n        } else {\n          throw new Error('Invalid value \"' + value + '\" for attribute Q supplied.');\n        }\n      }\n    });\n    /**\n     * (Optional; inheritable) A code specifying the form of quadding (justification) that shall be used in displaying the text:\n     * 'left', 'center', 'right'\n     *\n     * @name AcroFormField#textAlign\n     * @default 'left'\n     * @type {string}\n     */\n\n    Object.defineProperty(this, \"textAlign\", {\n      get: function get() {\n        var result;\n\n        switch (_Q) {\n          case 0:\n          default:\n            result = \"left\";\n            break;\n\n          case 1:\n            result = \"center\";\n            break;\n\n          case 2:\n            result = \"right\";\n            break;\n        }\n\n        return result;\n      },\n      configurable: true,\n      enumerable: true,\n      set: function set(value) {\n        switch (value) {\n          case \"right\":\n          case 2:\n            _Q = 2;\n            break;\n\n          case \"center\":\n          case 1:\n            _Q = 1;\n            break;\n\n          case \"left\":\n          case 0:\n          default:\n            _Q = 0;\n        }\n      }\n    });\n  };\n\n  inherit(AcroFormField, AcroFormPDFObject);\n  /**\n   * @class AcroFormChoiceField\n   * @extends AcroFormField\n   */\n\n  var AcroFormChoiceField = function AcroFormChoiceField() {\n    AcroFormField.call(this); // Field Type = Choice Field\n\n    this.FT = \"/Ch\"; // options\n\n    this.V = \"()\";\n    this.fontName = \"zapfdingbats\"; // Top Index\n\n    var _TI = 0;\n    Object.defineProperty(this, \"TI\", {\n      enumerable: true,\n      configurable: false,\n      get: function get() {\n        return _TI;\n      },\n      set: function set(value) {\n        _TI = value;\n      }\n    });\n    /**\n     * (Optional) For scrollable list boxes, the top index (the index in the Opt array of the first option visible in the list). Default value: 0.\n     *\n     * @name AcroFormChoiceField#topIndex\n     * @default 0\n     * @type {number}\n     */\n\n    Object.defineProperty(this, \"topIndex\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return _TI;\n      },\n      set: function set(value) {\n        _TI = value;\n      }\n    });\n    var _Opt = [];\n    Object.defineProperty(this, \"Opt\", {\n      enumerable: true,\n      configurable: false,\n      get: function get() {\n        return arrayToPdfArray(_Opt, this.objId, this.scope);\n      },\n      set: function set(value) {\n        _Opt = pdfArrayToStringArray(value);\n      }\n    });\n    /**\n     * @memberof AcroFormChoiceField\n     * @name getOptions\n     * @function\n     * @instance\n     * @returns {array} array of Options\n     */\n\n    this.getOptions = function () {\n      return _Opt;\n    };\n    /**\n     * @memberof AcroFormChoiceField\n     * @name setOptions\n     * @function\n     * @instance\n     * @param {array} value\n     */\n\n\n    this.setOptions = function (value) {\n      _Opt = value;\n\n      if (this.sort) {\n        _Opt.sort();\n      }\n    };\n    /**\n     * @memberof AcroFormChoiceField\n     * @name addOption\n     * @function\n     * @instance\n     * @param {string} value\n     */\n\n\n    this.addOption = function (value) {\n      value = value || \"\";\n      value = value.toString();\n\n      _Opt.push(value);\n\n      if (this.sort) {\n        _Opt.sort();\n      }\n    };\n    /**\n     * @memberof AcroFormChoiceField\n     * @name removeOption\n     * @function\n     * @instance\n     * @param {string} value\n     * @param {boolean} allEntries (default: false)\n     */\n\n\n    this.removeOption = function (value, allEntries) {\n      allEntries = allEntries || false;\n      value = value || \"\";\n      value = value.toString();\n\n      while (_Opt.indexOf(value) !== -1) {\n        _Opt.splice(_Opt.indexOf(value), 1);\n\n        if (allEntries === false) {\n          break;\n        }\n      }\n    };\n    /**\n     * If set, the field is a combo box; if clear, the field is a list box.\n     *\n     * @name AcroFormChoiceField#combo\n     * @default false\n     * @type {boolean}\n     */\n\n\n    Object.defineProperty(this, \"combo\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 18));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 18);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 18);\n        }\n      }\n    });\n    /**\n     * If set, the combo box shall include an editable text box as well as a drop-down list; if clear, it shall include only a drop-down list. This flag shall be used only if the Combo flag is set.\n     *\n     * @name AcroFormChoiceField#edit\n     * @default false\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"edit\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 19));\n      },\n      set: function set(value) {\n        //PDF 32000-1:2008, page 444\n        if (this.combo === true) {\n          if (Boolean(value) === true) {\n            this.Ff = setBitForPdf(this.Ff, 19);\n          } else {\n            this.Ff = clearBitForPdf(this.Ff, 19);\n          }\n        }\n      }\n    });\n    /**\n     * If set, the field’s option items shall be sorted alphabetically. This flag is intended for use by writers, not by readers. Conforming readers shall display the options in the order in which they occur in the Opt array (see Table 231).\n     *\n     * @name AcroFormChoiceField#sort\n     * @default false\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"sort\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 20));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 20);\n\n          _Opt.sort();\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 20);\n        }\n      }\n    });\n    /**\n     * (PDF 1.4) If set, more than one of the field’s option items may be selected simultaneously; if clear, at most one item shall be selected\n     *\n     * @name AcroFormChoiceField#multiSelect\n     * @default false\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"multiSelect\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 22));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 22);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 22);\n        }\n      }\n    });\n    /**\n     * (PDF 1.4) If set, text entered in the field shall not be spellchecked. This flag shall not be used unless the Combo and Edit flags are both set.\n     *\n     * @name AcroFormChoiceField#doNotSpellCheck\n     * @default false\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"doNotSpellCheck\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 23));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 23);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 23);\n        }\n      }\n    });\n    /**\n     * (PDF 1.5) If set, the new value shall be committed as soon as a selection is made (commonly with the pointing device). In this case, supplying a value for a field involves three actions: selecting the field for fill-in, selecting a choice for the fill-in value, and leaving that field, which finalizes or “commits” the data choice and triggers any actions associated with the entry or changing of this data. If this flag is on, then processing does not wait for leaving the field action to occur, but immediately proceeds to the third step.\n     * This option enables applications to perform an action once a selection is made, without requiring the user to exit the field. If clear, the new value is not committed until the user exits the field.\n     *\n     * @name AcroFormChoiceField#commitOnSelChange\n     * @default false\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"commitOnSelChange\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 27));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 27);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 27);\n        }\n      }\n    });\n    this.hasAppearanceStream = false;\n  };\n\n  inherit(AcroFormChoiceField, AcroFormField);\n  /**\n   * @class AcroFormListBox\n   * @extends AcroFormChoiceField\n   * @extends AcroFormField\n   */\n\n  var AcroFormListBox = function AcroFormListBox() {\n    AcroFormChoiceField.call(this);\n    this.fontName = \"helvetica\"; //PDF 32000-1:2008, page 444\n\n    this.combo = false;\n  };\n\n  inherit(AcroFormListBox, AcroFormChoiceField);\n  /**\n   * @class AcroFormComboBox\n   * @extends AcroFormListBox\n   * @extends AcroFormChoiceField\n   * @extends AcroFormField\n   */\n\n  var AcroFormComboBox = function AcroFormComboBox() {\n    AcroFormListBox.call(this);\n    this.combo = true;\n  };\n\n  inherit(AcroFormComboBox, AcroFormListBox);\n  /**\n   * @class AcroFormEditBox\n   * @extends AcroFormComboBox\n   * @extends AcroFormListBox\n   * @extends AcroFormChoiceField\n   * @extends AcroFormField\n   */\n\n  var AcroFormEditBox = function AcroFormEditBox() {\n    AcroFormComboBox.call(this);\n    this.edit = true;\n  };\n\n  inherit(AcroFormEditBox, AcroFormComboBox);\n  /**\n   * @class AcroFormButton\n   * @extends AcroFormField\n   */\n\n  var AcroFormButton = function AcroFormButton() {\n    AcroFormField.call(this);\n    this.FT = \"/Btn\";\n    /**\n     * (Radio buttons only) If set, exactly one radio button shall be selected at all times; selecting the currently selected button has no effect. If clear, clicking the selected button deselects it, leaving no button selected.\n     *\n     * @name AcroFormButton#noToggleToOff\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"noToggleToOff\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 15));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 15);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 15);\n        }\n      }\n    });\n    /**\n     * If set, the field is a set of radio buttons; if clear, the field is a checkbox. This flag may be set only if the Pushbutton flag is clear.\n     *\n     * @name AcroFormButton#radio\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"radio\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 16));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 16);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 16);\n        }\n      }\n    });\n    /**\n     * If set, the field is a pushbutton that does not retain a permanent value.\n     *\n     * @name AcroFormButton#pushButton\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"pushButton\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 17));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 17);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 17);\n        }\n      }\n    });\n    /**\n     * (PDF 1.5) If set, a group of radio buttons within a radio button field that use the same value for the on state will turn on and off in unison; that is if one is checked, they are all checked. If clear, the buttons are mutually exclusive (the same behavior as HTML radio buttons).\n     *\n     * @name AcroFormButton#radioIsUnison\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"radioIsUnison\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 26));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 26);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 26);\n        }\n      }\n    });\n    var _MK = {};\n    Object.defineProperty(this, \"MK\", {\n      enumerable: false,\n      configurable: false,\n      get: function get() {\n        var encryptor = function encryptor(data) {\n          return data;\n        };\n\n        if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId);\n\n        if (Object.keys(_MK).length !== 0) {\n          var result = [];\n          result.push(\"<<\");\n          var key;\n\n          for (key in _MK) {\n            result.push(\"/\" + key + \" (\" + pdfEscape(encryptor(_MK[key])) + \")\");\n          }\n\n          result.push(\">>\");\n          return result.join(\"\\n\");\n        }\n\n        return undefined;\n      },\n      set: function set(value) {\n        if (_typeof(value) === \"object\") {\n          _MK = value;\n        }\n      }\n    });\n    /**\n     * From the PDF reference:\n     * (Optional, button fields only) The widget annotation's normal caption which shall be displayed when it is not interacting with the user.\n     * Unlike the remaining entries listed in this Table which apply only to widget annotations associated with pushbutton fields (see Pushbuttons in 12.7.4.2, \"Button Fields\"), the CA entry may be used with any type of button field, including check boxes (see Check Boxes in 12.7.4.2, \"Button Fields\") and radio buttons (Radio Buttons in 12.7.4.2, \"Button Fields\").\n     *\n     * - '8' = Cross,\n     * - 'l' =  Circle,\n     * - '' = nothing\n     * @name AcroFormButton#caption\n     * @type {string}\n     */\n\n    Object.defineProperty(this, \"caption\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return _MK.CA || \"\";\n      },\n      set: function set(value) {\n        if (typeof value === \"string\") {\n          _MK.CA = value;\n        }\n      }\n    });\n\n    var _AS;\n\n    Object.defineProperty(this, \"AS\", {\n      enumerable: false,\n      configurable: false,\n      get: function get() {\n        return _AS;\n      },\n      set: function set(value) {\n        _AS = value;\n      }\n    });\n    /**\n     * (Required if the appearance dictionary AP contains one or more subdictionaries; PDF 1.2) The annotation's appearance state, which selects the applicable appearance stream from an appearance subdictionary (see Section 12.5.5, \"Appearance Streams\")\n     *\n     * @name AcroFormButton#appearanceState\n     * @type {any}\n     */\n\n    Object.defineProperty(this, \"appearanceState\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return _AS.substr(1, _AS.length - 1);\n      },\n      set: function set(value) {\n        _AS = \"/\" + value;\n      }\n    });\n  };\n\n  inherit(AcroFormButton, AcroFormField);\n  /**\n   * @class AcroFormPushButton\n   * @extends AcroFormButton\n   * @extends AcroFormField\n   */\n\n  var AcroFormPushButton = function AcroFormPushButton() {\n    AcroFormButton.call(this);\n    this.pushButton = true;\n  };\n\n  inherit(AcroFormPushButton, AcroFormButton);\n  /**\n   * @class AcroFormRadioButton\n   * @extends AcroFormButton\n   * @extends AcroFormField\n   */\n\n  var AcroFormRadioButton = function AcroFormRadioButton() {\n    AcroFormButton.call(this);\n    this.radio = true;\n    this.pushButton = false;\n    var _Kids = [];\n    Object.defineProperty(this, \"Kids\", {\n      enumerable: true,\n      configurable: false,\n      get: function get() {\n        return _Kids;\n      },\n      set: function set(value) {\n        if (typeof value !== \"undefined\") {\n          _Kids = value;\n        } else {\n          _Kids = [];\n        }\n      }\n    });\n  };\n\n  inherit(AcroFormRadioButton, AcroFormButton);\n  /**\n   * The Child class of a RadioButton (the radioGroup) -> The single Buttons\n   *\n   * @class AcroFormChildClass\n   * @extends AcroFormField\n   * @ignore\n   */\n\n  var AcroFormChildClass = function AcroFormChildClass() {\n    AcroFormField.call(this);\n\n    var _parent;\n\n    Object.defineProperty(this, \"Parent\", {\n      enumerable: false,\n      configurable: false,\n      get: function get() {\n        return _parent;\n      },\n      set: function set(value) {\n        _parent = value;\n      }\n    });\n\n    var _optionName;\n\n    Object.defineProperty(this, \"optionName\", {\n      enumerable: false,\n      configurable: true,\n      get: function get() {\n        return _optionName;\n      },\n      set: function set(value) {\n        _optionName = value;\n      }\n    });\n    var _MK = {};\n    Object.defineProperty(this, \"MK\", {\n      enumerable: false,\n      configurable: false,\n      get: function get() {\n        var encryptor = function encryptor(data) {\n          return data;\n        };\n\n        if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId);\n        var result = [];\n        result.push(\"<<\");\n        var key;\n\n        for (key in _MK) {\n          result.push(\"/\" + key + \" (\" + pdfEscape(encryptor(_MK[key])) + \")\");\n        }\n\n        result.push(\">>\");\n        return result.join(\"\\n\");\n      },\n      set: function set(value) {\n        if (_typeof(value) === \"object\") {\n          _MK = value;\n        }\n      }\n    });\n    /**\n     * From the PDF reference:\n     * (Optional, button fields only) The widget annotation's normal caption which shall be displayed when it is not interacting with the user.\n     * Unlike the remaining entries listed in this Table which apply only to widget annotations associated with pushbutton fields (see Pushbuttons in 12.7.4.2, \"Button Fields\"), the CA entry may be used with any type of button field, including check boxes (see Check Boxes in 12.7.4.2, \"Button Fields\") and radio buttons (Radio Buttons in 12.7.4.2, \"Button Fields\").\n     *\n     * - '8' = Cross,\n     * - 'l' =  Circle,\n     * - '' = nothing\n     * @name AcroFormButton#caption\n     * @type {string}\n     */\n\n    Object.defineProperty(this, \"caption\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return _MK.CA || \"\";\n      },\n      set: function set(value) {\n        if (typeof value === \"string\") {\n          _MK.CA = value;\n        }\n      }\n    });\n\n    var _AS;\n\n    Object.defineProperty(this, \"AS\", {\n      enumerable: false,\n      configurable: false,\n      get: function get() {\n        return _AS;\n      },\n      set: function set(value) {\n        _AS = value;\n      }\n    });\n    /**\n     * (Required if the appearance dictionary AP contains one or more subdictionaries; PDF 1.2) The annotation's appearance state, which selects the applicable appearance stream from an appearance subdictionary (see Section 12.5.5, \"Appearance Streams\")\n     *\n     * @name AcroFormButton#appearanceState\n     * @type {any}\n     */\n\n    Object.defineProperty(this, \"appearanceState\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return _AS.substr(1, _AS.length - 1);\n      },\n      set: function set(value) {\n        _AS = \"/\" + value;\n      }\n    });\n    this.caption = \"l\";\n    this.appearanceState = \"Off\"; // todo: set AppearanceType as variable that can be set from the\n    // outside...\n\n    this._AppearanceType = AcroFormAppearance.RadioButton.Circle; // The Default appearanceType is the Circle\n\n    this.appearanceStreamContent = this._AppearanceType.createAppearanceStream(this.optionName);\n  };\n\n  inherit(AcroFormChildClass, AcroFormField);\n\n  AcroFormRadioButton.prototype.setAppearance = function (appearance) {\n    if (!(\"createAppearanceStream\" in appearance && \"getCA\" in appearance)) {\n      throw new Error(\"Couldn't assign Appearance to RadioButton. Appearance was Invalid!\");\n    }\n\n    for (var objId in this.Kids) {\n      if (this.Kids.hasOwnProperty(objId)) {\n        var child = this.Kids[objId];\n        child.appearanceStreamContent = appearance.createAppearanceStream(child.optionName);\n        child.caption = appearance.getCA();\n      }\n    }\n  };\n\n  AcroFormRadioButton.prototype.createOption = function (name) {\n    // Create new Child for RadioGroup\n    var child = new AcroFormChildClass();\n    child.Parent = this;\n    child.optionName = name; // Add to Parent\n\n    this.Kids.push(child);\n    addField.call(this.scope, child);\n    return child;\n  };\n  /**\n   * @class AcroFormCheckBox\n   * @extends AcroFormButton\n   * @extends AcroFormField\n   */\n\n\n  var AcroFormCheckBox = function AcroFormCheckBox() {\n    AcroFormButton.call(this);\n    this.fontName = \"zapfdingbats\";\n    this.caption = \"3\";\n    this.appearanceState = \"On\";\n    this.value = \"On\";\n    this.textAlign = \"center\";\n    this.appearanceStreamContent = AcroFormAppearance.CheckBox.createAppearanceStream();\n  };\n\n  inherit(AcroFormCheckBox, AcroFormButton);\n  /**\n   * @class AcroFormTextField\n   * @extends AcroFormField\n   */\n\n  var AcroFormTextField = function AcroFormTextField() {\n    AcroFormField.call(this);\n    this.FT = \"/Tx\";\n    /**\n     * If set, the field may contain multiple lines of text; if clear, the field’s text shall be restricted to a single line.\n     *\n     * @name AcroFormTextField#multiline\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"multiline\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 13));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 13);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 13);\n        }\n      }\n    });\n    /**\n     * (PDF 1.4) If set, the text entered in the field represents the pathname of a file whose contents shall be submitted as the value of the field.\n     *\n     * @name AcroFormTextField#fileSelect\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"fileSelect\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 21));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 21);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 21);\n        }\n      }\n    });\n    /**\n     * (PDF 1.4) If set, text entered in the field shall not be spell-checked.\n     *\n     * @name AcroFormTextField#doNotSpellCheck\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"doNotSpellCheck\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 23));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 23);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 23);\n        }\n      }\n    });\n    /**\n     * (PDF 1.4) If set, the field shall not scroll (horizontally for single-line fields, vertically for multiple-line fields) to accommodate more text than fits within its annotation rectangle. Once the field is full, no further text shall be accepted for interactive form filling; for noninteractive form filling, the filler should take care not to add more character than will visibly fit in the defined area.\n     *\n     * @name AcroFormTextField#doNotScroll\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"doNotScroll\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 24));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 24);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 24);\n        }\n      }\n    });\n    /**\n     * (PDF 1.5) May be set only if the MaxLen entry is present in the text field dictionary (see Table 229) and if the Multiline, Password, and FileSelect flags are clear. If set, the field shall be automatically divided into as many equally spaced positions, or combs, as the value of MaxLen, and the text is laid out into those combs.\n     *\n     * @name AcroFormTextField#comb\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"comb\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 25));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 25);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 25);\n        }\n      }\n    });\n    /**\n     * (PDF 1.5) If set, the value of this field shall be a rich text string (see 12.7.3.4, “Rich Text Strings”). If the field has a value, the RV entry of the field dictionary (Table 222) shall specify the rich text string.\n     *\n     * @name AcroFormTextField#richText\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"richText\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 26));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 26);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 26);\n        }\n      }\n    });\n    var _MaxLen = null;\n    Object.defineProperty(this, \"MaxLen\", {\n      enumerable: true,\n      configurable: false,\n      get: function get() {\n        return _MaxLen;\n      },\n      set: function set(value) {\n        _MaxLen = value;\n      }\n    });\n    /**\n     * (Optional; inheritable) The maximum length of the field’s text, in characters.\n     *\n     * @name AcroFormTextField#maxLength\n     * @type {number}\n     */\n\n    Object.defineProperty(this, \"maxLength\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return _MaxLen;\n      },\n      set: function set(value) {\n        if (Number.isInteger(value)) {\n          _MaxLen = value;\n        }\n      }\n    });\n    Object.defineProperty(this, \"hasAppearanceStream\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return this.V || this.DV;\n      }\n    });\n  };\n\n  inherit(AcroFormTextField, AcroFormField);\n  /**\n   * @class AcroFormPasswordField\n   * @extends AcroFormTextField\n   * @extends AcroFormField\n   */\n\n  var AcroFormPasswordField = function AcroFormPasswordField() {\n    AcroFormTextField.call(this);\n    /**\n     * If set, the field is intended for entering a secure password that should not be echoed visibly to the screen. Characters typed from the keyboard shall instead be echoed in some unreadable form, such as asterisks or bullet characters.\n     * NOTE To protect password confidentiality, readers should never store the value of the text field in the PDF file if this flag is set.\n     *\n     * @name AcroFormTextField#password\n     * @type {boolean}\n     */\n\n    Object.defineProperty(this, \"password\", {\n      enumerable: true,\n      configurable: true,\n      get: function get() {\n        return Boolean(getBitForPdf(this.Ff, 14));\n      },\n      set: function set(value) {\n        if (Boolean(value) === true) {\n          this.Ff = setBitForPdf(this.Ff, 14);\n        } else {\n          this.Ff = clearBitForPdf(this.Ff, 14);\n        }\n      }\n    });\n    this.password = true;\n  };\n\n  inherit(AcroFormPasswordField, AcroFormTextField); // Contains Methods for creating standard appearances\n\n  var AcroFormAppearance = {\n    CheckBox: {\n      createAppearanceStream: function createAppearanceStream() {\n        var appearance = {\n          N: {\n            On: AcroFormAppearance.CheckBox.YesNormal\n          },\n          D: {\n            On: AcroFormAppearance.CheckBox.YesPushDown,\n            Off: AcroFormAppearance.CheckBox.OffPushDown\n          }\n        };\n        return appearance;\n      },\n\n      /**\n       * Returns the standard On Appearance for a CheckBox\n       *\n       * @returns {AcroFormXObject}\n       */\n      YesPushDown: function YesPushDown(formObject) {\n        var xobj = createFormXObject(formObject);\n        xobj.scope = formObject.scope;\n        var stream = [];\n        var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id;\n\n        var encodedColor = formObject.scope.__private__.encodeColorString(formObject.color);\n\n        var calcRes = calculateX(formObject, formObject.caption);\n        stream.push(\"0.749023 g\");\n        stream.push(\"0 0 \" + f2(AcroFormAppearance.internal.getWidth(formObject)) + \" \" + f2(AcroFormAppearance.internal.getHeight(formObject)) + \" re\");\n        stream.push(\"f\");\n        stream.push(\"BMC\");\n        stream.push(\"q\");\n        stream.push(\"0 0 1 rg\");\n        stream.push(\"/\" + fontKey + \" \" + f2(calcRes.fontSize) + \" Tf \" + encodedColor);\n        stream.push(\"BT\");\n        stream.push(calcRes.text);\n        stream.push(\"ET\");\n        stream.push(\"Q\");\n        stream.push(\"EMC\");\n        xobj.stream = stream.join(\"\\n\");\n        return xobj;\n      },\n      YesNormal: function YesNormal(formObject) {\n        var xobj = createFormXObject(formObject);\n        xobj.scope = formObject.scope;\n        var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id;\n\n        var encodedColor = formObject.scope.__private__.encodeColorString(formObject.color);\n\n        var stream = [];\n        var height = AcroFormAppearance.internal.getHeight(formObject);\n        var width = AcroFormAppearance.internal.getWidth(formObject);\n        var calcRes = calculateX(formObject, formObject.caption);\n        stream.push(\"1 g\");\n        stream.push(\"0 0 \" + f2(width) + \" \" + f2(height) + \" re\");\n        stream.push(\"f\");\n        stream.push(\"q\");\n        stream.push(\"0 0 1 rg\");\n        stream.push(\"0 0 \" + f2(width - 1) + \" \" + f2(height - 1) + \" re\");\n        stream.push(\"W\");\n        stream.push(\"n\");\n        stream.push(\"0 g\");\n        stream.push(\"BT\");\n        stream.push(\"/\" + fontKey + \" \" + f2(calcRes.fontSize) + \" Tf \" + encodedColor);\n        stream.push(calcRes.text);\n        stream.push(\"ET\");\n        stream.push(\"Q\");\n        xobj.stream = stream.join(\"\\n\");\n        return xobj;\n      },\n\n      /**\n       * Returns the standard Off Appearance for a CheckBox\n       *\n       * @returns {AcroFormXObject}\n       */\n      OffPushDown: function OffPushDown(formObject) {\n        var xobj = createFormXObject(formObject);\n        xobj.scope = formObject.scope;\n        var stream = [];\n        stream.push(\"0.749023 g\");\n        stream.push(\"0 0 \" + f2(AcroFormAppearance.internal.getWidth(formObject)) + \" \" + f2(AcroFormAppearance.internal.getHeight(formObject)) + \" re\");\n        stream.push(\"f\");\n        xobj.stream = stream.join(\"\\n\");\n        return xobj;\n      }\n    },\n    RadioButton: {\n      Circle: {\n        createAppearanceStream: function createAppearanceStream(name) {\n          var appearanceStreamContent = {\n            D: {\n              Off: AcroFormAppearance.RadioButton.Circle.OffPushDown\n            },\n            N: {}\n          };\n          appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Circle.YesNormal;\n          appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Circle.YesPushDown;\n          return appearanceStreamContent;\n        },\n        getCA: function getCA() {\n          return \"l\";\n        },\n        YesNormal: function YesNormal(formObject) {\n          var xobj = createFormXObject(formObject);\n          xobj.scope = formObject.scope;\n          var stream = []; // Make the Radius of the Circle relative to min(height, width) of formObject\n\n          var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4; // The Borderpadding...\n\n          DotRadius = Number((DotRadius * 0.9).toFixed(5));\n          var c = AcroFormAppearance.internal.Bezier_C;\n          var DotRadiusBezier = Number((DotRadius * c).toFixed(5));\n          /*\n           * The Following is a Circle created with Bezier-Curves.\n           */\n\n          stream.push(\"q\");\n          stream.push(\"1 0 0 1 \" + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + \" \" + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + \" cm\");\n          stream.push(DotRadius + \" 0 m\");\n          stream.push(DotRadius + \" \" + DotRadiusBezier + \" \" + DotRadiusBezier + \" \" + DotRadius + \" 0 \" + DotRadius + \" c\");\n          stream.push(\"-\" + DotRadiusBezier + \" \" + DotRadius + \" -\" + DotRadius + \" \" + DotRadiusBezier + \" -\" + DotRadius + \" 0 c\");\n          stream.push(\"-\" + DotRadius + \" -\" + DotRadiusBezier + \" -\" + DotRadiusBezier + \" -\" + DotRadius + \" 0 -\" + DotRadius + \" c\");\n          stream.push(DotRadiusBezier + \" -\" + DotRadius + \" \" + DotRadius + \" -\" + DotRadiusBezier + \" \" + DotRadius + \" 0 c\");\n          stream.push(\"f\");\n          stream.push(\"Q\");\n          xobj.stream = stream.join(\"\\n\");\n          return xobj;\n        },\n        YesPushDown: function YesPushDown(formObject) {\n          var xobj = createFormXObject(formObject);\n          xobj.scope = formObject.scope;\n          var stream = [];\n          var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4; // The Borderpadding...\n\n          DotRadius = Number((DotRadius * 0.9).toFixed(5)); // Save results for later use; no need to waste\n          // processor ticks on doing math\n\n          var k = Number((DotRadius * 2).toFixed(5));\n          var kc = Number((k * AcroFormAppearance.internal.Bezier_C).toFixed(5));\n          var dc = Number((DotRadius * AcroFormAppearance.internal.Bezier_C).toFixed(5));\n          stream.push(\"0.749023 g\");\n          stream.push(\"q\");\n          stream.push(\"1 0 0 1 \" + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + \" \" + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + \" cm\");\n          stream.push(k + \" 0 m\");\n          stream.push(k + \" \" + kc + \" \" + kc + \" \" + k + \" 0 \" + k + \" c\");\n          stream.push(\"-\" + kc + \" \" + k + \" -\" + k + \" \" + kc + \" -\" + k + \" 0 c\");\n          stream.push(\"-\" + k + \" -\" + kc + \" -\" + kc + \" -\" + k + \" 0 -\" + k + \" c\");\n          stream.push(kc + \" -\" + k + \" \" + k + \" -\" + kc + \" \" + k + \" 0 c\");\n          stream.push(\"f\");\n          stream.push(\"Q\");\n          stream.push(\"0 g\");\n          stream.push(\"q\");\n          stream.push(\"1 0 0 1 \" + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + \" \" + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + \" cm\");\n          stream.push(DotRadius + \" 0 m\");\n          stream.push(\"\" + DotRadius + \" \" + dc + \" \" + dc + \" \" + DotRadius + \" 0 \" + DotRadius + \" c\");\n          stream.push(\"-\" + dc + \" \" + DotRadius + \" -\" + DotRadius + \" \" + dc + \" -\" + DotRadius + \" 0 c\");\n          stream.push(\"-\" + DotRadius + \" -\" + dc + \" -\" + dc + \" -\" + DotRadius + \" 0 -\" + DotRadius + \" c\");\n          stream.push(dc + \" -\" + DotRadius + \" \" + DotRadius + \" -\" + dc + \" \" + DotRadius + \" 0 c\");\n          stream.push(\"f\");\n          stream.push(\"Q\");\n          xobj.stream = stream.join(\"\\n\");\n          return xobj;\n        },\n        OffPushDown: function OffPushDown(formObject) {\n          var xobj = createFormXObject(formObject);\n          xobj.scope = formObject.scope;\n          var stream = [];\n          var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4; // The Borderpadding...\n\n          DotRadius = Number((DotRadius * 0.9).toFixed(5)); // Save results for later use; no need to waste\n          // processor ticks on doing math\n\n          var k = Number((DotRadius * 2).toFixed(5));\n          var kc = Number((k * AcroFormAppearance.internal.Bezier_C).toFixed(5));\n          stream.push(\"0.749023 g\");\n          stream.push(\"q\");\n          stream.push(\"1 0 0 1 \" + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + \" \" + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + \" cm\");\n          stream.push(k + \" 0 m\");\n          stream.push(k + \" \" + kc + \" \" + kc + \" \" + k + \" 0 \" + k + \" c\");\n          stream.push(\"-\" + kc + \" \" + k + \" -\" + k + \" \" + kc + \" -\" + k + \" 0 c\");\n          stream.push(\"-\" + k + \" -\" + kc + \" -\" + kc + \" -\" + k + \" 0 -\" + k + \" c\");\n          stream.push(kc + \" -\" + k + \" \" + k + \" -\" + kc + \" \" + k + \" 0 c\");\n          stream.push(\"f\");\n          stream.push(\"Q\");\n          xobj.stream = stream.join(\"\\n\");\n          return xobj;\n        }\n      },\n      Cross: {\n        /**\n         * Creates the Actual AppearanceDictionary-References\n         *\n         * @param {string} name\n         * @returns {Object}\n         * @ignore\n         */\n        createAppearanceStream: function createAppearanceStream(name) {\n          var appearanceStreamContent = {\n            D: {\n              Off: AcroFormAppearance.RadioButton.Cross.OffPushDown\n            },\n            N: {}\n          };\n          appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Cross.YesNormal;\n          appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Cross.YesPushDown;\n          return appearanceStreamContent;\n        },\n        getCA: function getCA() {\n          return \"8\";\n        },\n        YesNormal: function YesNormal(formObject) {\n          var xobj = createFormXObject(formObject);\n          xobj.scope = formObject.scope;\n          var stream = [];\n          var cross = AcroFormAppearance.internal.calculateCross(formObject);\n          stream.push(\"q\");\n          stream.push(\"1 1 \" + f2(AcroFormAppearance.internal.getWidth(formObject) - 2) + \" \" + f2(AcroFormAppearance.internal.getHeight(formObject) - 2) + \" re\");\n          stream.push(\"W\");\n          stream.push(\"n\");\n          stream.push(f2(cross.x1.x) + \" \" + f2(cross.x1.y) + \" m\");\n          stream.push(f2(cross.x2.x) + \" \" + f2(cross.x2.y) + \" l\");\n          stream.push(f2(cross.x4.x) + \" \" + f2(cross.x4.y) + \" m\");\n          stream.push(f2(cross.x3.x) + \" \" + f2(cross.x3.y) + \" l\");\n          stream.push(\"s\");\n          stream.push(\"Q\");\n          xobj.stream = stream.join(\"\\n\");\n          return xobj;\n        },\n        YesPushDown: function YesPushDown(formObject) {\n          var xobj = createFormXObject(formObject);\n          xobj.scope = formObject.scope;\n          var cross = AcroFormAppearance.internal.calculateCross(formObject);\n          var stream = [];\n          stream.push(\"0.749023 g\");\n          stream.push(\"0 0 \" + f2(AcroFormAppearance.internal.getWidth(formObject)) + \" \" + f2(AcroFormAppearance.internal.getHeight(formObject)) + \" re\");\n          stream.push(\"f\");\n          stream.push(\"q\");\n          stream.push(\"1 1 \" + f2(AcroFormAppearance.internal.getWidth(formObject) - 2) + \" \" + f2(AcroFormAppearance.internal.getHeight(formObject) - 2) + \" re\");\n          stream.push(\"W\");\n          stream.push(\"n\");\n          stream.push(f2(cross.x1.x) + \" \" + f2(cross.x1.y) + \" m\");\n          stream.push(f2(cross.x2.x) + \" \" + f2(cross.x2.y) + \" l\");\n          stream.push(f2(cross.x4.x) + \" \" + f2(cross.x4.y) + \" m\");\n          stream.push(f2(cross.x3.x) + \" \" + f2(cross.x3.y) + \" l\");\n          stream.push(\"s\");\n          stream.push(\"Q\");\n          xobj.stream = stream.join(\"\\n\");\n          return xobj;\n        },\n        OffPushDown: function OffPushDown(formObject) {\n          var xobj = createFormXObject(formObject);\n          xobj.scope = formObject.scope;\n          var stream = [];\n          stream.push(\"0.749023 g\");\n          stream.push(\"0 0 \" + f2(AcroFormAppearance.internal.getWidth(formObject)) + \" \" + f2(AcroFormAppearance.internal.getHeight(formObject)) + \" re\");\n          stream.push(\"f\");\n          xobj.stream = stream.join(\"\\n\");\n          return xobj;\n        }\n      }\n    },\n\n    /**\n     * Returns the standard Appearance\n     *\n     * @returns {AcroFormXObject}\n     */\n    createDefaultAppearanceStream: function createDefaultAppearanceStream(formObject) {\n      // Set Helvetica to Standard Font (size: auto)\n      // Color: Black\n      var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id;\n\n      var encodedColor = formObject.scope.__private__.encodeColorString(formObject.color);\n\n      var fontSize = formObject.fontSize;\n      var result = \"/\" + fontKey + \" \" + fontSize + \" Tf \" + encodedColor;\n      return result;\n    }\n  };\n  AcroFormAppearance.internal = {\n    Bezier_C: 0.551915024494,\n    calculateCross: function calculateCross(formObject) {\n      var width = AcroFormAppearance.internal.getWidth(formObject);\n      var height = AcroFormAppearance.internal.getHeight(formObject);\n      var a = Math.min(width, height);\n      var cross = {\n        x1: {\n          // upperLeft\n          x: (width - a) / 2,\n          y: (height - a) / 2 + a // height - borderPadding\n\n        },\n        x2: {\n          // lowerRight\n          x: (width - a) / 2 + a,\n          y: (height - a) / 2 // borderPadding\n\n        },\n        x3: {\n          // lowerLeft\n          x: (width - a) / 2,\n          y: (height - a) / 2 // borderPadding\n\n        },\n        x4: {\n          // upperRight\n          x: (width - a) / 2 + a,\n          y: (height - a) / 2 + a // height - borderPadding\n\n        }\n      };\n      return cross;\n    }\n  };\n\n  AcroFormAppearance.internal.getWidth = function (formObject) {\n    var result = 0;\n\n    if (_typeof(formObject) === \"object\") {\n      result = scale(formObject.Rect[2]);\n    }\n\n    return result;\n  };\n\n  AcroFormAppearance.internal.getHeight = function (formObject) {\n    var result = 0;\n\n    if (_typeof(formObject) === \"object\") {\n      result = scale(formObject.Rect[3]);\n    }\n\n    return result;\n  }; // Public:\n\n  /**\n   * Add an AcroForm-Field to the jsPDF-instance\n   *\n   * @name addField\n   * @function\n   * @instance\n   * @param {Object} fieldObject\n   * @returns {jsPDF}\n   */\n\n\n  var addField = jsPDFAPI.addField = function (fieldObject) {\n    initializeAcroForm(this, fieldObject);\n\n    if (fieldObject instanceof AcroFormField) {\n      putForm(fieldObject);\n    } else {\n      throw new Error(\"Invalid argument passed to jsPDF.addField.\");\n    }\n\n    fieldObject.page = fieldObject.scope.internal.getCurrentPageInfo().pageNumber;\n    return this;\n  };\n\n  jsPDFAPI.AcroFormChoiceField = AcroFormChoiceField;\n  jsPDFAPI.AcroFormListBox = AcroFormListBox;\n  jsPDFAPI.AcroFormComboBox = AcroFormComboBox;\n  jsPDFAPI.AcroFormEditBox = AcroFormEditBox;\n  jsPDFAPI.AcroFormButton = AcroFormButton;\n  jsPDFAPI.AcroFormPushButton = AcroFormPushButton;\n  jsPDFAPI.AcroFormRadioButton = AcroFormRadioButton;\n  jsPDFAPI.AcroFormCheckBox = AcroFormCheckBox;\n  jsPDFAPI.AcroFormTextField = AcroFormTextField;\n  jsPDFAPI.AcroFormPasswordField = AcroFormPasswordField;\n  jsPDFAPI.AcroFormAppearance = AcroFormAppearance;\n  jsPDFAPI.AcroForm = {\n    ChoiceField: AcroFormChoiceField,\n    ListBox: AcroFormListBox,\n    ComboBox: AcroFormComboBox,\n    EditBox: AcroFormEditBox,\n    Button: AcroFormButton,\n    PushButton: AcroFormPushButton,\n    RadioButton: AcroFormRadioButton,\n    CheckBox: AcroFormCheckBox,\n    TextField: AcroFormTextField,\n    PasswordField: AcroFormPasswordField,\n    Appearance: AcroFormAppearance\n  };\n  jsPDF.AcroForm = {\n    ChoiceField: AcroFormChoiceField,\n    ListBox: AcroFormListBox,\n    ComboBox: AcroFormComboBox,\n    EditBox: AcroFormEditBox,\n    Button: AcroFormButton,\n    PushButton: AcroFormPushButton,\n    RadioButton: AcroFormRadioButton,\n    CheckBox: AcroFormCheckBox,\n    TextField: AcroFormTextField,\n    PasswordField: AcroFormPasswordField,\n    Appearance: AcroFormAppearance\n  };\n  var AcroForm = jsPDF.AcroForm;\n\n  (function (jsPDFAPI) {\n\n    var namespace = \"addImage_\";\n    jsPDFAPI.__addimage__ = {};\n    var UNKNOWN = \"UNKNOWN\"; // Heuristic selection of a good batch for large array .apply. Not limiting make the call overflow.\n    // With too small batch iteration will be slow as more calls are made,\n    // higher values cause larger and slower garbage collection.\n\n    var ARRAY_APPLY_BATCH = 8192;\n    var imageFileTypeHeaders = {\n      PNG: [[0x89, 0x50, 0x4e, 0x47]],\n      TIFF: [[0x4d, 0x4d, 0x00, 0x2a], //Motorola\n      [0x49, 0x49, 0x2a, 0x00] //Intel\n      ],\n      JPEG: [[0xff, 0xd8, 0xff, 0xe0, undefined, undefined, 0x4a, 0x46, 0x49, 0x46, 0x00], //JFIF\n      [0xff, 0xd8, 0xff, 0xe1, undefined, undefined, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00], //Exif\n      [0xff, 0xd8, 0xff, 0xdb], //JPEG RAW\n      [0xff, 0xd8, 0xff, 0xee] //EXIF RAW\n      ],\n      JPEG2000: [[0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20]],\n      GIF87a: [[0x47, 0x49, 0x46, 0x38, 0x37, 0x61]],\n      GIF89a: [[0x47, 0x49, 0x46, 0x38, 0x39, 0x61]],\n      WEBP: [[0x52, 0x49, 0x46, 0x46, undefined, undefined, undefined, undefined, 0x57, 0x45, 0x42, 0x50]],\n      BMP: [[0x42, 0x4d], //BM - Windows 3.1x, 95, NT, ... etc.\n      [0x42, 0x41], //BA - OS/2 struct bitmap array\n      [0x43, 0x49], //CI - OS/2 struct color icon\n      [0x43, 0x50], //CP - OS/2 const color pointer\n      [0x49, 0x43], //IC - OS/2 struct icon\n      [0x50, 0x54] //PT - OS/2 pointer\n      ]\n    };\n    /**\n     * Recognize filetype of Image by magic-bytes\n     *\n     * https://en.wikipedia.org/wiki/List_of_file_signatures\n     *\n     * @name getImageFileTypeByImageData\n     * @public\n     * @function\n     * @param {string|arraybuffer} imageData imageData as binary String or arraybuffer\n     * @param {string} format format of file if filetype-recognition fails, e.g. 'JPEG'\n     *\n     * @returns {string} filetype of Image\n     */\n\n    var getImageFileTypeByImageData = jsPDFAPI.__addimage__.getImageFileTypeByImageData = function (imageData, fallbackFormat) {\n      fallbackFormat = fallbackFormat || UNKNOWN;\n      var i;\n      var j;\n      var result = UNKNOWN;\n      var headerSchemata;\n      var compareResult;\n      var fileType;\n\n      if (fallbackFormat === \"RGBA\" || imageData.data !== undefined && imageData.data instanceof Uint8ClampedArray && \"height\" in imageData && \"width\" in imageData) {\n        return \"RGBA\";\n      }\n\n      if (isArrayBufferView(imageData)) {\n        for (fileType in imageFileTypeHeaders) {\n          headerSchemata = imageFileTypeHeaders[fileType];\n\n          for (i = 0; i < headerSchemata.length; i += 1) {\n            compareResult = true;\n\n            for (j = 0; j < headerSchemata[i].length; j += 1) {\n              if (headerSchemata[i][j] === undefined) {\n                continue;\n              }\n\n              if (headerSchemata[i][j] !== imageData[j]) {\n                compareResult = false;\n                break;\n              }\n            }\n\n            if (compareResult === true) {\n              result = fileType;\n              break;\n            }\n          }\n        }\n      } else {\n        for (fileType in imageFileTypeHeaders) {\n          headerSchemata = imageFileTypeHeaders[fileType];\n\n          for (i = 0; i < headerSchemata.length; i += 1) {\n            compareResult = true;\n\n            for (j = 0; j < headerSchemata[i].length; j += 1) {\n              if (headerSchemata[i][j] === undefined) {\n                continue;\n              }\n\n              if (headerSchemata[i][j] !== imageData.charCodeAt(j)) {\n                compareResult = false;\n                break;\n              }\n            }\n\n            if (compareResult === true) {\n              result = fileType;\n              break;\n            }\n          }\n        }\n      }\n\n      if (result === UNKNOWN && fallbackFormat !== UNKNOWN) {\n        result = fallbackFormat;\n      }\n\n      return result;\n    }; // Image functionality ported from pdf.js\n\n\n    var putImage = function putImage(image) {\n      var out = this.internal.write;\n      var putStream = this.internal.putStream;\n      var getFilters = this.internal.getFilters;\n      var filter = getFilters();\n\n      while (filter.indexOf(\"FlateEncode\") !== -1) {\n        filter.splice(filter.indexOf(\"FlateEncode\"), 1);\n      }\n\n      image.objectId = this.internal.newObject();\n      var additionalKeyValues = [];\n      additionalKeyValues.push({\n        key: \"Type\",\n        value: \"/XObject\"\n      });\n      additionalKeyValues.push({\n        key: \"Subtype\",\n        value: \"/Image\"\n      });\n      additionalKeyValues.push({\n        key: \"Width\",\n        value: image.width\n      });\n      additionalKeyValues.push({\n        key: \"Height\",\n        value: image.height\n      });\n\n      if (image.colorSpace === color_spaces.INDEXED) {\n        additionalKeyValues.push({\n          key: \"ColorSpace\",\n          value: \"[/Indexed /DeviceRGB \" + ( // if an indexed png defines more than one colour with transparency, we've created a sMask\n          image.palette.length / 3 - 1) + \" \" + (\"sMask\" in image && typeof image.sMask !== \"undefined\" ? image.objectId + 2 : image.objectId + 1) + \" 0 R]\"\n        });\n      } else {\n        additionalKeyValues.push({\n          key: \"ColorSpace\",\n          value: \"/\" + image.colorSpace\n        });\n\n        if (image.colorSpace === color_spaces.DEVICE_CMYK) {\n          additionalKeyValues.push({\n            key: \"Decode\",\n            value: \"[1 0 1 0 1 0 1 0]\"\n          });\n        }\n      }\n\n      additionalKeyValues.push({\n        key: \"BitsPerComponent\",\n        value: image.bitsPerComponent\n      });\n\n      if (\"decodeParameters\" in image && typeof image.decodeParameters !== \"undefined\") {\n        additionalKeyValues.push({\n          key: \"DecodeParms\",\n          value: \"<<\" + image.decodeParameters + \">>\"\n        });\n      }\n\n      if (\"transparency\" in image && Array.isArray(image.transparency)) {\n        var transparency = \"\",\n            i = 0,\n            len = image.transparency.length;\n\n        for (; i < len; i++) {\n          transparency += image.transparency[i] + \" \" + image.transparency[i] + \" \";\n        }\n\n        additionalKeyValues.push({\n          key: \"Mask\",\n          value: \"[\" + transparency + \"]\"\n        });\n      }\n\n      if (typeof image.sMask !== \"undefined\") {\n        additionalKeyValues.push({\n          key: \"SMask\",\n          value: image.objectId + 1 + \" 0 R\"\n        });\n      }\n\n      var alreadyAppliedFilters = typeof image.filter !== \"undefined\" ? [\"/\" + image.filter] : undefined;\n      putStream({\n        data: image.data,\n        additionalKeyValues: additionalKeyValues,\n        alreadyAppliedFilters: alreadyAppliedFilters,\n        objectId: image.objectId\n      });\n      out(\"endobj\"); // Soft mask\n\n      if (\"sMask\" in image && typeof image.sMask !== \"undefined\") {\n        var decodeParameters = \"/Predictor \" + image.predictor + \" /Colors 1 /BitsPerComponent \" + image.bitsPerComponent + \" /Columns \" + image.width;\n        var sMask = {\n          width: image.width,\n          height: image.height,\n          colorSpace: \"DeviceGray\",\n          bitsPerComponent: image.bitsPerComponent,\n          decodeParameters: decodeParameters,\n          data: image.sMask\n        };\n\n        if (\"filter\" in image) {\n          sMask.filter = image.filter;\n        }\n\n        putImage.call(this, sMask);\n      } //Palette\n\n\n      if (image.colorSpace === color_spaces.INDEXED) {\n        var objId = this.internal.newObject(); //out('<< /Filter / ' + img['f'] +' /Length ' + img['pal'].length + '>>');\n        //putStream(zlib.compress(img['pal']));\n\n        putStream({\n          data: arrayBufferToBinaryString(new Uint8Array(image.palette)),\n          objectId: objId\n        });\n        out(\"endobj\");\n      }\n    };\n\n    var putResourcesCallback = function putResourcesCallback() {\n      var images = this.internal.collections[namespace + \"images\"];\n\n      for (var i in images) {\n        putImage.call(this, images[i]);\n      }\n    };\n\n    var putXObjectsDictCallback = function putXObjectsDictCallback() {\n      var images = this.internal.collections[namespace + \"images\"],\n          out = this.internal.write,\n          image;\n\n      for (var i in images) {\n        image = images[i];\n        out(\"/I\" + image.index, image.objectId, \"0\", \"R\");\n      }\n    };\n\n    var checkCompressValue = function checkCompressValue(value) {\n      if (value && typeof value === \"string\") value = value.toUpperCase();\n      return value in jsPDFAPI.image_compression ? value : image_compression.NONE;\n    };\n\n    var initialize = function initialize() {\n      if (!this.internal.collections[namespace + \"images\"]) {\n        this.internal.collections[namespace + \"images\"] = {};\n        this.internal.events.subscribe(\"putResources\", putResourcesCallback);\n        this.internal.events.subscribe(\"putXobjectDict\", putXObjectsDictCallback);\n      }\n    };\n\n    var getImages = function getImages() {\n      var images = this.internal.collections[namespace + \"images\"];\n      initialize.call(this);\n      return images;\n    };\n\n    var getImageIndex = function getImageIndex() {\n      return Object.keys(this.internal.collections[namespace + \"images\"]).length;\n    };\n\n    var notDefined = function notDefined(value) {\n      return typeof value === \"undefined\" || value === null || value.length === 0;\n    };\n\n    var generateAliasFromImageData = function generateAliasFromImageData(imageData) {\n      if (typeof imageData === \"string\" || isArrayBufferView(imageData)) {\n        return sHashCode(imageData);\n      } else if (isArrayBufferView(imageData.data)) {\n        return sHashCode(imageData.data);\n      }\n\n      return null;\n    };\n\n    var isImageTypeSupported = function isImageTypeSupported(type) {\n      return typeof jsPDFAPI[\"process\" + type.toUpperCase()] === \"function\";\n    };\n\n    var isDOMElement = function isDOMElement(object) {\n      return _typeof(object) === \"object\" && object.nodeType === 1;\n    };\n\n    var getImageDataFromElement = function getImageDataFromElement(element, format) {\n      //if element is an image which uses data url definition, just return the dataurl\n      if (element.nodeName === \"IMG\" && element.hasAttribute(\"src\")) {\n        var src = \"\" + element.getAttribute(\"src\"); //is base64 encoded dataUrl, directly process it\n\n        if (src.indexOf(\"data:image/\") === 0) {\n          return atob(unescape(src).split(\"base64,\").pop());\n        } //it is probably an url, try to load it\n\n\n        var tmpImageData = jsPDFAPI.loadFile(src, true);\n\n        if (tmpImageData !== undefined) {\n          return tmpImageData;\n        }\n      }\n\n      if (element.nodeName === \"CANVAS\") {\n        if (element.width === 0 || element.height === 0) {\n          throw new Error(\"Given canvas must have data. Canvas width: \" + element.width + \", height: \" + element.height);\n        }\n\n        var mimeType;\n\n        switch (format) {\n          case \"PNG\":\n            mimeType = \"image/png\";\n            break;\n\n          case \"WEBP\":\n            mimeType = \"image/webp\";\n            break;\n\n          case \"JPEG\":\n          case \"JPG\":\n          default:\n            mimeType = \"image/jpeg\";\n            break;\n        }\n\n        return atob(element.toDataURL(mimeType, 1.0).split(\"base64,\").pop());\n      }\n    };\n\n    var checkImagesForAlias = function checkImagesForAlias(alias) {\n      var images = this.internal.collections[namespace + \"images\"];\n\n      if (images) {\n        for (var e in images) {\n          if (alias === images[e].alias) {\n            return images[e];\n          }\n        }\n      }\n    };\n\n    var determineWidthAndHeight = function determineWidthAndHeight(width, height, image) {\n      if (!width && !height) {\n        width = -96;\n        height = -96;\n      }\n\n      if (width < 0) {\n        width = -1 * image.width * 72 / width / this.internal.scaleFactor;\n      }\n\n      if (height < 0) {\n        height = -1 * image.height * 72 / height / this.internal.scaleFactor;\n      }\n\n      if (width === 0) {\n        width = height * image.width / image.height;\n      }\n\n      if (height === 0) {\n        height = width * image.height / image.width;\n      }\n\n      return [width, height];\n    };\n\n    var writeImageToPDF = function writeImageToPDF(x, y, width, height, image, rotation) {\n      var dims = determineWidthAndHeight.call(this, width, height, image),\n          coord = this.internal.getCoordinateString,\n          vcoord = this.internal.getVerticalCoordinateString;\n      var images = getImages.call(this);\n      width = dims[0];\n      height = dims[1];\n      images[image.index] = image;\n\n      if (rotation) {\n        rotation *= Math.PI / 180;\n        var c = Math.cos(rotation);\n        var s = Math.sin(rotation); //like in pdf Reference do it 4 digits instead of 2\n\n        var f4 = function f4(number) {\n          return number.toFixed(4);\n        };\n\n        var rotationTransformationMatrix = [f4(c), f4(s), f4(s * -1), f4(c), 0, 0, \"cm\"];\n      }\n\n      this.internal.write(\"q\"); //Save graphics state\n\n      if (rotation) {\n        this.internal.write([1, \"0\", \"0\", 1, coord(x), vcoord(y + height), \"cm\"].join(\" \")); //Translate\n\n        this.internal.write(rotationTransformationMatrix.join(\" \")); //Rotate\n\n        this.internal.write([coord(width), \"0\", \"0\", coord(height), \"0\", \"0\", \"cm\"].join(\" \")); //Scale\n      } else {\n        this.internal.write([coord(width), \"0\", \"0\", coord(height), coord(x), vcoord(y + height), \"cm\"].join(\" \")); //Translate and Scale\n      }\n\n      if (this.isAdvancedAPI()) {\n        // draw image bottom up when in \"advanced\" API mode\n        this.internal.write([1, 0, 0, -1, 0, 0, \"cm\"].join(\" \"));\n      }\n\n      this.internal.write(\"/I\" + image.index + \" Do\"); //Paint Image\n\n      this.internal.write(\"Q\"); //Restore graphics state\n    };\n    /**\n     * COLOR SPACES\n     */\n\n\n    var color_spaces = jsPDFAPI.color_spaces = {\n      DEVICE_RGB: \"DeviceRGB\",\n      DEVICE_GRAY: \"DeviceGray\",\n      DEVICE_CMYK: \"DeviceCMYK\",\n      CAL_GREY: \"CalGray\",\n      CAL_RGB: \"CalRGB\",\n      LAB: \"Lab\",\n      ICC_BASED: \"ICCBased\",\n      INDEXED: \"Indexed\",\n      PATTERN: \"Pattern\",\n      SEPARATION: \"Separation\",\n      DEVICE_N: \"DeviceN\"\n    };\n    /**\n     * DECODE METHODS\n     */\n\n    jsPDFAPI.decode = {\n      DCT_DECODE: \"DCTDecode\",\n      FLATE_DECODE: \"FlateDecode\",\n      LZW_DECODE: \"LZWDecode\",\n      JPX_DECODE: \"JPXDecode\",\n      JBIG2_DECODE: \"JBIG2Decode\",\n      ASCII85_DECODE: \"ASCII85Decode\",\n      ASCII_HEX_DECODE: \"ASCIIHexDecode\",\n      RUN_LENGTH_DECODE: \"RunLengthDecode\",\n      CCITT_FAX_DECODE: \"CCITTFaxDecode\"\n    };\n    /**\n     * IMAGE COMPRESSION TYPES\n     */\n\n    var image_compression = jsPDFAPI.image_compression = {\n      NONE: \"NONE\",\n      FAST: \"FAST\",\n      MEDIUM: \"MEDIUM\",\n      SLOW: \"SLOW\"\n    };\n    /**\n     * @name sHashCode\n     * @function\n     * @param {string} data\n     * @returns {string}\n     */\n\n    var sHashCode = jsPDFAPI.__addimage__.sHashCode = function (data) {\n      var hash = 0,\n          i,\n          len;\n\n      if (typeof data === \"string\") {\n        len = data.length;\n\n        for (i = 0; i < len; i++) {\n          hash = (hash << 5) - hash + data.charCodeAt(i);\n          hash |= 0; // Convert to 32bit integer\n        }\n      } else if (isArrayBufferView(data)) {\n        len = data.byteLength / 2;\n\n        for (i = 0; i < len; i++) {\n          hash = (hash << 5) - hash + data[i];\n          hash |= 0; // Convert to 32bit integer\n        }\n      }\n\n      return hash;\n    };\n    /**\n     * Validates if given String is a valid Base64-String\n     *\n     * @name validateStringAsBase64\n     * @public\n     * @function\n     * @param {String} possible Base64-String\n     *\n     * @returns {boolean}\n     */\n\n\n    var validateStringAsBase64 = jsPDFAPI.__addimage__.validateStringAsBase64 = function (possibleBase64String) {\n      possibleBase64String = possibleBase64String || \"\";\n      possibleBase64String.toString().trim();\n      var result = true;\n\n      if (possibleBase64String.length === 0) {\n        result = false;\n      }\n\n      if (possibleBase64String.length % 4 !== 0) {\n        result = false;\n      }\n\n      if (/^[A-Za-z0-9+/]+$/.test(possibleBase64String.substr(0, possibleBase64String.length - 2)) === false) {\n        result = false;\n      }\n\n      if (/^[A-Za-z0-9/][A-Za-z0-9+/]|[A-Za-z0-9+/]=|==$/.test(possibleBase64String.substr(-2)) === false) {\n        result = false;\n      }\n\n      return result;\n    };\n    /**\n     * Strips out and returns info from a valid base64 data URI\n     *\n     * @name extractImageFromDataUrl\n     * @function\n     * @param {string} dataUrl a valid data URI of format 'data:[<MIME-type>][;base64],<data>'\n     * @returns {Array}an Array containing the following\n     * [0] the complete data URI\n     * [1] <MIME-type>\n     * [2] format - the second part of the mime-type i.e 'png' in 'image/png'\n     * [4] <data>\n     */\n\n\n    var extractImageFromDataUrl = jsPDFAPI.__addimage__.extractImageFromDataUrl = function (dataUrl) {\n      dataUrl = dataUrl || \"\";\n      var dataUrlParts = dataUrl.split(\"base64,\");\n      var result = null;\n\n      if (dataUrlParts.length === 2) {\n        var extractedInfo = /^data:(\\w*\\/\\w*);*(charset=(?!charset=)[\\w=-]*)*;*$/.exec(dataUrlParts[0]);\n\n        if (Array.isArray(extractedInfo)) {\n          result = {\n            mimeType: extractedInfo[1],\n            charset: extractedInfo[2],\n            data: dataUrlParts[1]\n          };\n        }\n      }\n\n      return result;\n    };\n    /**\n     * Check to see if ArrayBuffer is supported\n     *\n     * @name supportsArrayBuffer\n     * @function\n     * @returns {boolean}\n     */\n\n\n    var supportsArrayBuffer = jsPDFAPI.__addimage__.supportsArrayBuffer = function () {\n      return typeof ArrayBuffer !== \"undefined\" && typeof Uint8Array !== \"undefined\";\n    };\n    /**\n     * Tests supplied object to determine if ArrayBuffer\n     *\n     * @name isArrayBuffer\n     * @function\n     * @param {Object} object an Object\n     *\n     * @returns {boolean}\n     */\n\n\n    jsPDFAPI.__addimage__.isArrayBuffer = function (object) {\n      return supportsArrayBuffer() && object instanceof ArrayBuffer;\n    };\n    /**\n     * Tests supplied object to determine if it implements the ArrayBufferView (TypedArray) interface\n     *\n     * @name isArrayBufferView\n     * @function\n     * @param {Object} object an Object\n     * @returns {boolean}\n     */\n\n\n    var isArrayBufferView = jsPDFAPI.__addimage__.isArrayBufferView = function (object) {\n      return supportsArrayBuffer() && typeof Uint32Array !== \"undefined\" && (object instanceof Int8Array || object instanceof Uint8Array || typeof Uint8ClampedArray !== \"undefined\" && object instanceof Uint8ClampedArray || object instanceof Int16Array || object instanceof Uint16Array || object instanceof Int32Array || object instanceof Uint32Array || object instanceof Float32Array || object instanceof Float64Array);\n    };\n    /**\n     * Convert Binary String to ArrayBuffer\n     *\n     * @name binaryStringToUint8Array\n     * @public\n     * @function\n     * @param {string} BinaryString with ImageData\n     * @returns {Uint8Array}\n     */\n\n\n    var binaryStringToUint8Array = jsPDFAPI.__addimage__.binaryStringToUint8Array = function (binary_string) {\n      var len = binary_string.length;\n      var bytes = new Uint8Array(len);\n\n      for (var i = 0; i < len; i++) {\n        bytes[i] = binary_string.charCodeAt(i);\n      }\n\n      return bytes;\n    };\n    /**\n     * Convert the Buffer to a Binary String\n     *\n     * @name arrayBufferToBinaryString\n     * @public\n     * @function\n     * @param {ArrayBuffer|ArrayBufferView} ArrayBuffer buffer or bufferView with ImageData\n     *\n     * @returns {String}\n     */\n\n\n    var arrayBufferToBinaryString = jsPDFAPI.__addimage__.arrayBufferToBinaryString = function (buffer) {\n      var out = \"\"; // There are calls with both ArrayBuffer and already converted Uint8Array or other BufferView.\n      // Do not copy the array if input is already an array.\n\n      var buf = isArrayBufferView(buffer) ? buffer : new Uint8Array(buffer);\n\n      for (var i = 0; i < buf.length; i += ARRAY_APPLY_BATCH) {\n        // Limit the amount of characters being parsed to prevent overflow.\n        // Note that while TextDecoder would be faster, it does not have the same\n        // functionality as fromCharCode with any provided encodings as of 3/2021.\n        out += String.fromCharCode.apply(null, buf.subarray(i, i + ARRAY_APPLY_BATCH));\n      }\n\n      return out;\n    };\n    /**\n     * Possible parameter for addImage, an RGBA buffer with size.\n     *\n     * @typedef {Object} RGBAData\n     * @property {Uint8ClampedArray} data - Single dimensional array of RGBA values. For example from canvas getImageData.\n     * @property {number} width - Image width as the data does not carry this information in itself.\n     * @property {number} height - Image height as the data does not carry this information in itself.\n     */\n\n    /**\n     * Adds an Image to the PDF.\n     *\n     * @name addImage\n     * @public\n     * @function\n     * @param {string|HTMLImageElement|HTMLCanvasElement|Uint8Array|RGBAData} imageData imageData as base64 encoded DataUrl or Image-HTMLElement or Canvas-HTMLElement or object containing RGBA array (like output from canvas.getImageData).\n     * @param {string} format format of file if filetype-recognition fails or in case of a Canvas-Element needs to be specified (default for Canvas is JPEG), e.g. 'JPEG', 'PNG', 'WEBP'\n     * @param {number} x x Coordinate (in units declared at inception of PDF document) against left edge of the page\n     * @param {number} y y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n     * @param {number} width width of the image (in units declared at inception of PDF document)\n     * @param {number} height height of the Image (in units declared at inception of PDF document)\n     * @param {string} alias alias of the image (if used multiple times)\n     * @param {string} compression compression of the generated JPEG, can have the values 'NONE', 'FAST', 'MEDIUM' and 'SLOW'\n     * @param {number} rotation rotation of the image in degrees (0-359)\n     *\n     * @returns jsPDF\n     */\n\n\n    jsPDFAPI.addImage = function () {\n      var imageData, format, x, y, w, h, alias, compression, rotation;\n      imageData = arguments[0];\n\n      if (typeof arguments[1] === \"number\") {\n        format = UNKNOWN;\n        x = arguments[1];\n        y = arguments[2];\n        w = arguments[3];\n        h = arguments[4];\n        alias = arguments[5];\n        compression = arguments[6];\n        rotation = arguments[7];\n      } else {\n        format = arguments[1];\n        x = arguments[2];\n        y = arguments[3];\n        w = arguments[4];\n        h = arguments[5];\n        alias = arguments[6];\n        compression = arguments[7];\n        rotation = arguments[8];\n      }\n\n      if (_typeof(imageData) === \"object\" && !isDOMElement(imageData) && \"imageData\" in imageData) {\n        var options = imageData;\n        imageData = options.imageData;\n        format = options.format || format || UNKNOWN;\n        x = options.x || x || 0;\n        y = options.y || y || 0;\n        w = options.w || options.width || w;\n        h = options.h || options.height || h;\n        alias = options.alias || alias;\n        compression = options.compression || compression;\n        rotation = options.rotation || options.angle || rotation;\n      } //If compression is not explicitly set, determine if we should use compression\n\n\n      var filter = this.internal.getFilters();\n\n      if (compression === undefined && filter.indexOf(\"FlateEncode\") !== -1) {\n        compression = \"SLOW\";\n      }\n\n      if (isNaN(x) || isNaN(y)) {\n        throw new Error(\"Invalid coordinates passed to jsPDF.addImage\");\n      }\n\n      initialize.call(this);\n      var image = processImageData.call(this, imageData, format, alias, compression);\n      writeImageToPDF.call(this, x, y, w, h, image, rotation);\n      return this;\n    };\n\n    var processImageData = function processImageData(imageData, format, alias, compression) {\n      var result, dataAsBinaryString;\n\n      if (typeof imageData === \"string\" && getImageFileTypeByImageData(imageData) === UNKNOWN) {\n        imageData = unescape(imageData);\n        var tmpImageData = convertBase64ToBinaryString(imageData, false);\n\n        if (tmpImageData !== \"\") {\n          imageData = tmpImageData;\n        } else {\n          tmpImageData = jsPDFAPI.loadFile(imageData, true);\n\n          if (tmpImageData !== undefined) {\n            imageData = tmpImageData;\n          }\n        }\n      }\n\n      if (isDOMElement(imageData)) {\n        imageData = getImageDataFromElement(imageData, format);\n      }\n\n      format = getImageFileTypeByImageData(imageData, format);\n\n      if (!isImageTypeSupported(format)) {\n        throw new Error(\"addImage does not support files of type '\" + format + \"', please ensure that a plugin for '\" + format + \"' support is added.\");\n      } // now do the heavy lifting\n\n\n      if (notDefined(alias)) {\n        alias = generateAliasFromImageData(imageData);\n      }\n\n      result = checkImagesForAlias.call(this, alias);\n\n      if (!result) {\n        if (supportsArrayBuffer()) {\n          // no need to convert if imageData is already uint8array\n          if (!(imageData instanceof Uint8Array) && format !== \"RGBA\") {\n            dataAsBinaryString = imageData;\n            imageData = binaryStringToUint8Array(imageData);\n          }\n        }\n\n        result = this[\"process\" + format.toUpperCase()](imageData, getImageIndex.call(this), alias, checkCompressValue(compression), dataAsBinaryString);\n      }\n\n      if (!result) {\n        throw new Error(\"An unknown error occurred whilst processing the image.\");\n      }\n\n      return result;\n    };\n    /**\n     * @name convertBase64ToBinaryString\n     * @function\n     * @param {string} stringData\n     * @returns {string} binary string\n     */\n\n\n    var convertBase64ToBinaryString = jsPDFAPI.__addimage__.convertBase64ToBinaryString = function (stringData, throwError) {\n      throwError = typeof throwError === \"boolean\" ? throwError : true;\n      var base64Info;\n      var imageData = \"\";\n      var rawData;\n\n      if (typeof stringData === \"string\") {\n        base64Info = extractImageFromDataUrl(stringData);\n        rawData = base64Info !== null ? base64Info.data : stringData;\n\n        try {\n          imageData = atob(rawData);\n        } catch (e) {\n          if (throwError) {\n            if (!validateStringAsBase64(rawData)) {\n              throw new Error(\"Supplied Data is not a valid base64-String jsPDF.convertBase64ToBinaryString \");\n            } else {\n              throw new Error(\"atob-Error in jsPDF.convertBase64ToBinaryString \" + e.message);\n            }\n          }\n        }\n      }\n\n      return imageData;\n    };\n    /**\n     * @name getImageProperties\n     * @function\n     * @param {Object} imageData\n     * @returns {Object}\n     */\n\n\n    jsPDFAPI.getImageProperties = function (imageData) {\n      var image;\n      var tmpImageData = \"\";\n      var format;\n\n      if (isDOMElement(imageData)) {\n        imageData = getImageDataFromElement(imageData);\n      }\n\n      if (typeof imageData === \"string\" && getImageFileTypeByImageData(imageData) === UNKNOWN) {\n        tmpImageData = convertBase64ToBinaryString(imageData, false);\n\n        if (tmpImageData === \"\") {\n          tmpImageData = jsPDFAPI.loadFile(imageData) || \"\";\n        }\n\n        imageData = tmpImageData;\n      }\n\n      format = getImageFileTypeByImageData(imageData);\n\n      if (!isImageTypeSupported(format)) {\n        throw new Error(\"addImage does not support files of type '\" + format + \"', please ensure that a plugin for '\" + format + \"' support is added.\");\n      }\n\n      if (supportsArrayBuffer() && !(imageData instanceof Uint8Array)) {\n        imageData = binaryStringToUint8Array(imageData);\n      }\n\n      image = this[\"process\" + format.toUpperCase()](imageData);\n\n      if (!image) {\n        throw new Error(\"An unknown error occurred whilst processing the image\");\n      }\n\n      image.fileType = format;\n      return image;\n    };\n  })(jsPDF.API);\n\n  /**\n   * @license\n   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n\n  (function (jsPDFAPI) {\n\n    var notEmpty = function notEmpty(obj) {\n      if (typeof obj != \"undefined\") {\n        if (obj != \"\") {\n          return true;\n        }\n      }\n    };\n\n    jsPDF.API.events.push([\"addPage\", function (addPageData) {\n      var pageInfo = this.internal.getPageInfo(addPageData.pageNumber);\n      pageInfo.pageContext.annotations = [];\n    }]);\n    jsPDFAPI.events.push([\"putPage\", function (putPageData) {\n      var getHorizontalCoordinateString = this.internal.getCoordinateString;\n      var getVerticalCoordinateString = this.internal.getVerticalCoordinateString;\n      var pageInfo = this.internal.getPageInfoByObjId(putPageData.objId);\n      var pageAnnos = putPageData.pageContext.annotations;\n      var anno, rect, line;\n      var found = false;\n\n      for (var a = 0; a < pageAnnos.length && !found; a++) {\n        anno = pageAnnos[a];\n\n        switch (anno.type) {\n          case \"link\":\n            if (notEmpty(anno.options.url) || notEmpty(anno.options.pageNumber)) {\n              found = true;\n            }\n\n            break;\n\n          case \"reference\":\n          case \"text\":\n          case \"freetext\":\n            found = true;\n            break;\n        }\n      }\n\n      if (found == false) {\n        return;\n      }\n\n      this.internal.write(\"/Annots [\");\n\n      for (var i = 0; i < pageAnnos.length; i++) {\n        anno = pageAnnos[i];\n        var escape = this.internal.pdfEscape;\n        var encryptor = this.internal.getEncryptor(putPageData.objId);\n\n        switch (anno.type) {\n          case \"reference\":\n            // References to Widget Annotations (for AcroForm Fields)\n            this.internal.write(\" \" + anno.object.objId + \" 0 R \");\n            break;\n\n          case \"text\":\n            // Create a an object for both the text and the popup\n            var objText = this.internal.newAdditionalObject();\n            var objPopup = this.internal.newAdditionalObject();\n            var encryptorText = this.internal.getEncryptor(objText.objId);\n            var title = anno.title || \"Note\";\n            rect = \"/Rect [\" + getHorizontalCoordinateString(anno.bounds.x) + \" \" + getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) + \" \" + getHorizontalCoordinateString(anno.bounds.x + anno.bounds.w) + \" \" + getVerticalCoordinateString(anno.bounds.y) + \"] \";\n            line = \"<</Type /Annot /Subtype /\" + \"Text\" + \" \" + rect + \"/Contents (\" + escape(encryptorText(anno.contents)) + \")\";\n            line += \" /Popup \" + objPopup.objId + \" 0 R\";\n            line += \" /P \" + pageInfo.objId + \" 0 R\";\n            line += \" /T (\" + escape(encryptorText(title)) + \") >>\";\n            objText.content = line;\n            var parent = objText.objId + \" 0 R\";\n            var popoff = 30;\n            rect = \"/Rect [\" + getHorizontalCoordinateString(anno.bounds.x + popoff) + \" \" + getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) + \" \" + getHorizontalCoordinateString(anno.bounds.x + anno.bounds.w + popoff) + \" \" + getVerticalCoordinateString(anno.bounds.y) + \"] \";\n            line = \"<</Type /Annot /Subtype /\" + \"Popup\" + \" \" + rect + \" /Parent \" + parent;\n\n            if (anno.open) {\n              line += \" /Open true\";\n            }\n\n            line += \" >>\";\n            objPopup.content = line;\n            this.internal.write(objText.objId, \"0 R\", objPopup.objId, \"0 R\");\n            break;\n\n          case \"freetext\":\n            rect = \"/Rect [\" + getHorizontalCoordinateString(anno.bounds.x) + \" \" + getVerticalCoordinateString(anno.bounds.y) + \" \" + getHorizontalCoordinateString(anno.bounds.x + anno.bounds.w) + \" \" + getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) + \"] \";\n            var color = anno.color || \"#000000\";\n            line = \"<</Type /Annot /Subtype /\" + \"FreeText\" + \" \" + rect + \"/Contents (\" + escape(encryptor(anno.contents)) + \")\";\n            line += \" /DS(font: Helvetica,sans-serif 12.0pt; text-align:left; color:#\" + color + \")\";\n            line += \" /Border [0 0 0]\";\n            line += \" >>\";\n            this.internal.write(line);\n            break;\n\n          case \"link\":\n            if (anno.options.name) {\n              var loc = this.annotations._nameMap[anno.options.name];\n              anno.options.pageNumber = loc.page;\n              anno.options.top = loc.y;\n            } else {\n              if (!anno.options.top) {\n                anno.options.top = 0;\n              }\n            }\n\n            rect = \"/Rect [\" + anno.finalBounds.x + \" \" + anno.finalBounds.y + \" \" + anno.finalBounds.w + \" \" + anno.finalBounds.h + \"] \";\n            line = \"\";\n\n            if (anno.options.url) {\n              line = \"<</Type /Annot /Subtype /Link \" + rect + \"/Border [0 0 0] /A <</S /URI /URI (\" + escape(encryptor(anno.options.url)) + \") >>\";\n            } else if (anno.options.pageNumber) {\n              // first page is 0\n              var info = this.internal.getPageInfo(anno.options.pageNumber);\n              line = \"<</Type /Annot /Subtype /Link \" + rect + \"/Border [0 0 0] /Dest [\" + info.objId + \" 0 R\";\n              anno.options.magFactor = anno.options.magFactor || \"XYZ\";\n\n              switch (anno.options.magFactor) {\n                case \"Fit\":\n                  line += \" /Fit]\";\n                  break;\n\n                case \"FitH\":\n                  line += \" /FitH \" + anno.options.top + \"]\";\n                  break;\n\n                case \"FitV\":\n                  anno.options.left = anno.options.left || 0;\n                  line += \" /FitV \" + anno.options.left + \"]\";\n                  break;\n\n                case \"XYZ\":\n                default:\n                  var top = getVerticalCoordinateString(anno.options.top);\n                  anno.options.left = anno.options.left || 0; // 0 or null zoom will not change zoom factor\n\n                  if (typeof anno.options.zoom === \"undefined\") {\n                    anno.options.zoom = 0;\n                  }\n\n                  line += \" /XYZ \" + anno.options.left + \" \" + top + \" \" + anno.options.zoom + \"]\";\n                  break;\n              }\n            }\n\n            if (line != \"\") {\n              line += \" >>\";\n              this.internal.write(line);\n            }\n\n            break;\n        }\n      }\n\n      this.internal.write(\"]\");\n    }]);\n    /**\n     * @name createAnnotation\n     * @function\n     * @param {Object} options\n     */\n\n    jsPDFAPI.createAnnotation = function (options) {\n      var pageInfo = this.internal.getCurrentPageInfo();\n\n      switch (options.type) {\n        case \"link\":\n          this.link(options.bounds.x, options.bounds.y, options.bounds.w, options.bounds.h, options);\n          break;\n\n        case \"text\":\n        case \"freetext\":\n          pageInfo.pageContext.annotations.push(options);\n          break;\n      }\n    };\n    /**\n     * Create a link\n     *\n     * valid options\n     * <li> pageNumber or url [required]\n     * <p>If pageNumber is specified, top and zoom may also be specified</p>\n     * @name link\n     * @function\n     * @param {number} x\n     * @param {number} y\n     * @param {number} w\n     * @param {number} h\n     * @param {Object} options\n     */\n\n\n    jsPDFAPI.link = function (x, y, w, h, options) {\n      var pageInfo = this.internal.getCurrentPageInfo();\n      var getHorizontalCoordinateString = this.internal.getCoordinateString;\n      var getVerticalCoordinateString = this.internal.getVerticalCoordinateString;\n      pageInfo.pageContext.annotations.push({\n        finalBounds: {\n          x: getHorizontalCoordinateString(x),\n          y: getVerticalCoordinateString(y),\n          w: getHorizontalCoordinateString(x + w),\n          h: getVerticalCoordinateString(y + h)\n        },\n        options: options,\n        type: \"link\"\n      });\n    };\n    /**\n     * Currently only supports single line text.\n     * Returns the width of the text/link\n     *\n     * @name textWithLink\n     * @function\n     * @param {string} text\n     * @param {number} x\n     * @param {number} y\n     * @param {Object} options\n     * @returns {number} width the width of the text/link\n     */\n\n\n    jsPDFAPI.textWithLink = function (text, x, y, options) {\n      var totalLineWidth = this.getTextWidth(text);\n      var lineHeight = this.internal.getLineHeight() / this.internal.scaleFactor;\n      var linkHeight, linkWidth; // Checking if maxWidth option is passed to determine lineWidth and number of lines for each line\n\n      if (options.maxWidth !== undefined) {\n        var maxWidth = options.maxWidth;\n        linkWidth = maxWidth;\n        var numOfLines = this.splitTextToSize(text, linkWidth).length;\n        linkHeight = Math.ceil(lineHeight * numOfLines);\n      } else {\n        linkWidth = totalLineWidth;\n        linkHeight = lineHeight;\n      }\n\n      this.text(text, x, y, options); //TODO We really need the text baseline height to do this correctly.\n      // Or ability to draw text on top, bottom, center, or baseline.\n\n      y += lineHeight * 0.2; //handle x position based on the align option\n\n      if (options.align === \"center\") {\n        x = x - totalLineWidth / 2; //since starting from center move the x position by half of text width\n      }\n\n      if (options.align === \"right\") {\n        x = x - totalLineWidth;\n      }\n\n      this.link(x, y - lineHeight, linkWidth, linkHeight, options);\n      return totalLineWidth;\n    }; //TODO move into external library\n\n    /**\n     * @name getTextWidth\n     * @function\n     * @param {string} text\n     * @returns {number} txtWidth\n     */\n\n\n    jsPDFAPI.getTextWidth = function (text) {\n      var fontSize = this.internal.getFontSize();\n      var txtWidth = this.getStringUnitWidth(text) * fontSize / this.internal.scaleFactor;\n      return txtWidth;\n    };\n\n    return this;\n  })(jsPDF.API);\n\n  /**\n   * @license\n   * Copyright (c) 2017 Aras Abbasi\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n  /**\n   * jsPDF arabic parser PlugIn\n   *\n   * @name arabic\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n    /**\n     * Arabic shape substitutions: char code => (isolated, final, initial, medial).\n     * Arabic Substition A\n     */\n\n    var arabicSubstitionA = {\n      0x0621: [0xfe80],\n      // ARABIC LETTER HAMZA\n      0x0622: [0xfe81, 0xfe82],\n      // ARABIC LETTER ALEF WITH MADDA ABOVE\n      0x0623: [0xfe83, 0xfe84],\n      // ARABIC LETTER ALEF WITH HAMZA ABOVE\n      0x0624: [0xfe85, 0xfe86],\n      // ARABIC LETTER WAW WITH HAMZA ABOVE\n      0x0625: [0xfe87, 0xfe88],\n      // ARABIC LETTER ALEF WITH HAMZA BELOW\n      0x0626: [0xfe89, 0xfe8a, 0xfe8b, 0xfe8c],\n      // ARABIC LETTER YEH WITH HAMZA ABOVE\n      0x0627: [0xfe8d, 0xfe8e],\n      // ARABIC LETTER ALEF\n      0x0628: [0xfe8f, 0xfe90, 0xfe91, 0xfe92],\n      // ARABIC LETTER BEH\n      0x0629: [0xfe93, 0xfe94],\n      // ARABIC LETTER TEH MARBUTA\n      0x062a: [0xfe95, 0xfe96, 0xfe97, 0xfe98],\n      // ARABIC LETTER TEH\n      0x062b: [0xfe99, 0xfe9a, 0xfe9b, 0xfe9c],\n      // ARABIC LETTER THEH\n      0x062c: [0xfe9d, 0xfe9e, 0xfe9f, 0xfea0],\n      // ARABIC LETTER JEEM\n      0x062d: [0xfea1, 0xfea2, 0xfea3, 0xfea4],\n      // ARABIC LETTER HAH\n      0x062e: [0xfea5, 0xfea6, 0xfea7, 0xfea8],\n      // ARABIC LETTER KHAH\n      0x062f: [0xfea9, 0xfeaa],\n      // ARABIC LETTER DAL\n      0x0630: [0xfeab, 0xfeac],\n      // ARABIC LETTER THAL\n      0x0631: [0xfead, 0xfeae],\n      // ARABIC LETTER REH\n      0x0632: [0xfeaf, 0xfeb0],\n      // ARABIC LETTER ZAIN\n      0x0633: [0xfeb1, 0xfeb2, 0xfeb3, 0xfeb4],\n      // ARABIC LETTER SEEN\n      0x0634: [0xfeb5, 0xfeb6, 0xfeb7, 0xfeb8],\n      // ARABIC LETTER SHEEN\n      0x0635: [0xfeb9, 0xfeba, 0xfebb, 0xfebc],\n      // ARABIC LETTER SAD\n      0x0636: [0xfebd, 0xfebe, 0xfebf, 0xfec0],\n      // ARABIC LETTER DAD\n      0x0637: [0xfec1, 0xfec2, 0xfec3, 0xfec4],\n      // ARABIC LETTER TAH\n      0x0638: [0xfec5, 0xfec6, 0xfec7, 0xfec8],\n      // ARABIC LETTER ZAH\n      0x0639: [0xfec9, 0xfeca, 0xfecb, 0xfecc],\n      // ARABIC LETTER AIN\n      0x063a: [0xfecd, 0xfece, 0xfecf, 0xfed0],\n      // ARABIC LETTER GHAIN\n      0x0641: [0xfed1, 0xfed2, 0xfed3, 0xfed4],\n      // ARABIC LETTER FEH\n      0x0642: [0xfed5, 0xfed6, 0xfed7, 0xfed8],\n      // ARABIC LETTER QAF\n      0x0643: [0xfed9, 0xfeda, 0xfedb, 0xfedc],\n      // ARABIC LETTER KAF\n      0x0644: [0xfedd, 0xfede, 0xfedf, 0xfee0],\n      // ARABIC LETTER LAM\n      0x0645: [0xfee1, 0xfee2, 0xfee3, 0xfee4],\n      // ARABIC LETTER MEEM\n      0x0646: [0xfee5, 0xfee6, 0xfee7, 0xfee8],\n      // ARABIC LETTER NOON\n      0x0647: [0xfee9, 0xfeea, 0xfeeb, 0xfeec],\n      // ARABIC LETTER HEH\n      0x0648: [0xfeed, 0xfeee],\n      // ARABIC LETTER WAW\n      0x0649: [0xfeef, 0xfef0, 64488, 64489],\n      // ARABIC LETTER ALEF MAKSURA\n      0x064a: [0xfef1, 0xfef2, 0xfef3, 0xfef4],\n      // ARABIC LETTER YEH\n      0x0671: [0xfb50, 0xfb51],\n      // ARABIC LETTER ALEF WASLA\n      0x0677: [0xfbdd],\n      // ARABIC LETTER U WITH HAMZA ABOVE\n      0x0679: [0xfb66, 0xfb67, 0xfb68, 0xfb69],\n      // ARABIC LETTER TTEH\n      0x067a: [0xfb5e, 0xfb5f, 0xfb60, 0xfb61],\n      // ARABIC LETTER TTEHEH\n      0x067b: [0xfb52, 0xfb53, 0xfb54, 0xfb55],\n      // ARABIC LETTER BEEH\n      0x067e: [0xfb56, 0xfb57, 0xfb58, 0xfb59],\n      // ARABIC LETTER PEH\n      0x067f: [0xfb62, 0xfb63, 0xfb64, 0xfb65],\n      // ARABIC LETTER TEHEH\n      0x0680: [0xfb5a, 0xfb5b, 0xfb5c, 0xfb5d],\n      // ARABIC LETTER BEHEH\n      0x0683: [0xfb76, 0xfb77, 0xfb78, 0xfb79],\n      // ARABIC LETTER NYEH\n      0x0684: [0xfb72, 0xfb73, 0xfb74, 0xfb75],\n      // ARABIC LETTER DYEH\n      0x0686: [0xfb7a, 0xfb7b, 0xfb7c, 0xfb7d],\n      // ARABIC LETTER TCHEH\n      0x0687: [0xfb7e, 0xfb7f, 0xfb80, 0xfb81],\n      // ARABIC LETTER TCHEHEH\n      0x0688: [0xfb88, 0xfb89],\n      // ARABIC LETTER DDAL\n      0x068c: [0xfb84, 0xfb85],\n      // ARABIC LETTER DAHAL\n      0x068d: [0xfb82, 0xfb83],\n      // ARABIC LETTER DDAHAL\n      0x068e: [0xfb86, 0xfb87],\n      // ARABIC LETTER DUL\n      0x0691: [0xfb8c, 0xfb8d],\n      // ARABIC LETTER RREH\n      0x0698: [0xfb8a, 0xfb8b],\n      // ARABIC LETTER JEH\n      0x06a4: [0xfb6a, 0xfb6b, 0xfb6c, 0xfb6d],\n      // ARABIC LETTER VEH\n      0x06a6: [0xfb6e, 0xfb6f, 0xfb70, 0xfb71],\n      // ARABIC LETTER PEHEH\n      0x06a9: [0xfb8e, 0xfb8f, 0xfb90, 0xfb91],\n      // ARABIC LETTER KEHEH\n      0x06ad: [0xfbd3, 0xfbd4, 0xfbd5, 0xfbd6],\n      // ARABIC LETTER NG\n      0x06af: [0xfb92, 0xfb93, 0xfb94, 0xfb95],\n      // ARABIC LETTER GAF\n      0x06b1: [0xfb9a, 0xfb9b, 0xfb9c, 0xfb9d],\n      // ARABIC LETTER NGOEH\n      0x06b3: [0xfb96, 0xfb97, 0xfb98, 0xfb99],\n      // ARABIC LETTER GUEH\n      0x06ba: [0xfb9e, 0xfb9f],\n      // ARABIC LETTER NOON GHUNNA\n      0x06bb: [0xfba0, 0xfba1, 0xfba2, 0xfba3],\n      // ARABIC LETTER RNOON\n      0x06be: [0xfbaa, 0xfbab, 0xfbac, 0xfbad],\n      // ARABIC LETTER HEH DOACHASHMEE\n      0x06c0: [0xfba4, 0xfba5],\n      // ARABIC LETTER HEH WITH YEH ABOVE\n      0x06c1: [0xfba6, 0xfba7, 0xfba8, 0xfba9],\n      // ARABIC LETTER HEH GOAL\n      0x06c5: [0xfbe0, 0xfbe1],\n      // ARABIC LETTER KIRGHIZ OE\n      0x06c6: [0xfbd9, 0xfbda],\n      // ARABIC LETTER OE\n      0x06c7: [0xfbd7, 0xfbd8],\n      // ARABIC LETTER U\n      0x06c8: [0xfbdb, 0xfbdc],\n      // ARABIC LETTER YU\n      0x06c9: [0xfbe2, 0xfbe3],\n      // ARABIC LETTER KIRGHIZ YU\n      0x06cb: [0xfbde, 0xfbdf],\n      // ARABIC LETTER VE\n      0x06cc: [0xfbfc, 0xfbfd, 0xfbfe, 0xfbff],\n      // ARABIC LETTER FARSI YEH\n      0x06d0: [0xfbe4, 0xfbe5, 0xfbe6, 0xfbe7],\n      //ARABIC LETTER E\n      0x06d2: [0xfbae, 0xfbaf],\n      // ARABIC LETTER YEH BARREE\n      0x06d3: [0xfbb0, 0xfbb1] // ARABIC LETTER YEH BARREE WITH HAMZA ABOVE\n\n    };\n    /*\n      var ligaturesSubstitutionA = {\n          0xFBEA: []// ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM\n      };\n      */\n\n    var ligatures = {\n      0xfedf: {\n        0xfe82: 0xfef5,\n        // ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM\n        0xfe84: 0xfef7,\n        // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM\n        0xfe88: 0xfef9,\n        // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM\n        0xfe8e: 0xfefb // ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM\n\n      },\n      0xfee0: {\n        0xfe82: 0xfef6,\n        // ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM\n        0xfe84: 0xfef8,\n        // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM\n        0xfe88: 0xfefa,\n        // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM\n        0xfe8e: 0xfefc // ARABIC LIGATURE LAM WITH ALEF FINAL FORM\n\n      },\n      0xfe8d: {\n        0xfedf: {\n          0xfee0: {\n            0xfeea: 0xfdf2\n          }\n        }\n      },\n      // ALLAH\n      0x0651: {\n        0x064c: 0xfc5e,\n        // Shadda + Dammatan\n        0x064d: 0xfc5f,\n        // Shadda + Kasratan\n        0x064e: 0xfc60,\n        // Shadda + Fatha\n        0x064f: 0xfc61,\n        // Shadda + Damma\n        0x0650: 0xfc62 // Shadda + Kasra\n\n      }\n    };\n    var arabic_diacritics = {\n      1612: 64606,\n      // Shadda + Dammatan\n      1613: 64607,\n      // Shadda + Kasratan\n      1614: 64608,\n      // Shadda + Fatha\n      1615: 64609,\n      // Shadda + Damma\n      1616: 64610 // Shadda + Kasra\n\n    };\n    var alfletter = [1570, 1571, 1573, 1575];\n    var noChangeInForm = -1;\n    var isolatedForm = 0;\n    var finalForm = 1;\n    var initialForm = 2;\n    var medialForm = 3;\n    jsPDFAPI.__arabicParser__ = {}; //private\n\n    var isInArabicSubstitutionA = jsPDFAPI.__arabicParser__.isInArabicSubstitutionA = function (letter) {\n      return typeof arabicSubstitionA[letter.charCodeAt(0)] !== \"undefined\";\n    };\n\n    var isArabicLetter = jsPDFAPI.__arabicParser__.isArabicLetter = function (letter) {\n      return typeof letter === \"string\" && /^[\\u0600-\\u06FF\\u0750-\\u077F\\u08A0-\\u08FF\\uFB50-\\uFDFF\\uFE70-\\uFEFF]+$/.test(letter);\n    };\n\n    var isArabicEndLetter = jsPDFAPI.__arabicParser__.isArabicEndLetter = function (letter) {\n      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length <= 2;\n    };\n\n    var isArabicAlfLetter = jsPDFAPI.__arabicParser__.isArabicAlfLetter = function (letter) {\n      return isArabicLetter(letter) && alfletter.indexOf(letter.charCodeAt(0)) >= 0;\n    };\n\n    jsPDFAPI.__arabicParser__.arabicLetterHasIsolatedForm = function (letter) {\n      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length >= 1;\n    };\n\n    var arabicLetterHasFinalForm = jsPDFAPI.__arabicParser__.arabicLetterHasFinalForm = function (letter) {\n      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length >= 2;\n    };\n\n    jsPDFAPI.__arabicParser__.arabicLetterHasInitialForm = function (letter) {\n      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length >= 3;\n    };\n\n    var arabicLetterHasMedialForm = jsPDFAPI.__arabicParser__.arabicLetterHasMedialForm = function (letter) {\n      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length == 4;\n    };\n\n    var resolveLigatures = jsPDFAPI.__arabicParser__.resolveLigatures = function (letters) {\n      var i = 0;\n      var tmpLigatures = ligatures;\n      var result = \"\";\n      var effectedLetters = 0;\n\n      for (i = 0; i < letters.length; i += 1) {\n        if (typeof tmpLigatures[letters.charCodeAt(i)] !== \"undefined\") {\n          effectedLetters++;\n          tmpLigatures = tmpLigatures[letters.charCodeAt(i)];\n\n          if (typeof tmpLigatures === \"number\") {\n            result += String.fromCharCode(tmpLigatures);\n            tmpLigatures = ligatures;\n            effectedLetters = 0;\n          }\n\n          if (i === letters.length - 1) {\n            tmpLigatures = ligatures;\n            result += letters.charAt(i - (effectedLetters - 1));\n            i = i - (effectedLetters - 1);\n            effectedLetters = 0;\n          }\n        } else {\n          tmpLigatures = ligatures;\n          result += letters.charAt(i - effectedLetters);\n          i = i - effectedLetters;\n          effectedLetters = 0;\n        }\n      }\n\n      return result;\n    };\n\n    jsPDFAPI.__arabicParser__.isArabicDiacritic = function (letter) {\n      return letter !== undefined && arabic_diacritics[letter.charCodeAt(0)] !== undefined;\n    };\n\n    var getCorrectForm = jsPDFAPI.__arabicParser__.getCorrectForm = function (currentChar, beforeChar, nextChar) {\n      if (!isArabicLetter(currentChar)) {\n        return -1;\n      }\n\n      if (isInArabicSubstitutionA(currentChar) === false) {\n        return noChangeInForm;\n      }\n\n      if (!arabicLetterHasFinalForm(currentChar) || !isArabicLetter(beforeChar) && !isArabicLetter(nextChar) || !isArabicLetter(nextChar) && isArabicEndLetter(beforeChar) || isArabicEndLetter(currentChar) && !isArabicLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicAlfLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicEndLetter(beforeChar)) {\n        return isolatedForm;\n      }\n\n      if (arabicLetterHasMedialForm(currentChar) && isArabicLetter(beforeChar) && !isArabicEndLetter(beforeChar) && isArabicLetter(nextChar) && arabicLetterHasFinalForm(nextChar)) {\n        return medialForm;\n      }\n\n      if (isArabicEndLetter(currentChar) || !isArabicLetter(nextChar)) {\n        return finalForm;\n      }\n\n      return initialForm;\n    };\n    /**\n     * @name processArabic\n     * @function\n     * @param {string} text\n     * @returns {string}\n     */\n\n\n    var parseArabic = function parseArabic(text) {\n      text = text || \"\";\n      var result = \"\";\n      var i = 0;\n      var j = 0;\n      var position = 0;\n      var currentLetter = \"\";\n      var prevLetter = \"\";\n      var nextLetter = \"\";\n      var words = text.split(\"\\\\s+\");\n      var newWords = [];\n\n      for (i = 0; i < words.length; i += 1) {\n        newWords.push(\"\");\n\n        for (j = 0; j < words[i].length; j += 1) {\n          currentLetter = words[i][j];\n          prevLetter = words[i][j - 1];\n          nextLetter = words[i][j + 1];\n\n          if (isArabicLetter(currentLetter)) {\n            position = getCorrectForm(currentLetter, prevLetter, nextLetter);\n\n            if (position !== -1) {\n              newWords[i] += String.fromCharCode(arabicSubstitionA[currentLetter.charCodeAt(0)][position]);\n            } else {\n              newWords[i] += currentLetter;\n            }\n          } else {\n            newWords[i] += currentLetter;\n          }\n        }\n\n        newWords[i] = resolveLigatures(newWords[i]);\n      }\n\n      result = newWords.join(\" \");\n      return result;\n    };\n\n    var processArabic = jsPDFAPI.__arabicParser__.processArabic = jsPDFAPI.processArabic = function () {\n      var text = typeof arguments[0] === \"string\" ? arguments[0] : arguments[0].text;\n      var tmpText = [];\n      var result;\n\n      if (Array.isArray(text)) {\n        var i = 0;\n        tmpText = [];\n\n        for (i = 0; i < text.length; i += 1) {\n          if (Array.isArray(text[i])) {\n            tmpText.push([parseArabic(text[i][0]), text[i][1], text[i][2]]);\n          } else {\n            tmpText.push([parseArabic(text[i])]);\n          }\n        }\n\n        result = tmpText;\n      } else {\n        result = parseArabic(text);\n      }\n\n      if (typeof arguments[0] === \"string\") {\n        return result;\n      } else {\n        arguments[0].text = result;\n        return arguments[0];\n      }\n    };\n\n    jsPDFAPI.events.push([\"preProcessText\", processArabic]);\n  })(jsPDF.API);\n\n  /** @license\n   * jsPDF Autoprint Plugin\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n  /**\n   * @name autoprint\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n    /**\n     * Makes the PDF automatically open the print-Dialog when opened in a PDF-viewer.\n     *\n     * @name autoPrint\n     * @function\n     * @param {Object} options (optional) Set the attribute variant to 'non-conform' (default) or 'javascript' to activate different methods of automatic printing when opening in a PDF-viewer .\n     * @returns {jsPDF}\n     * @example\n     * var doc = new jsPDF();\n     * doc.text(10, 10, 'This is a test');\n     * doc.autoPrint({variant: 'non-conform'});\n     * doc.save('autoprint.pdf');\n     */\n\n    jsPDFAPI.autoPrint = function (options) {\n\n      var refAutoPrintTag;\n      options = options || {};\n      options.variant = options.variant || \"non-conform\";\n\n      switch (options.variant) {\n        case \"javascript\":\n          //https://github.com/Rob--W/pdf.js/commit/c676ecb5a0f54677b9f3340c3ef2cf42225453bb\n          this.addJS(\"print({});\");\n          break;\n\n        case \"non-conform\":\n        default:\n          this.internal.events.subscribe(\"postPutResources\", function () {\n            refAutoPrintTag = this.internal.newObject();\n            this.internal.out(\"<<\");\n            this.internal.out(\"/S /Named\");\n            this.internal.out(\"/Type /Action\");\n            this.internal.out(\"/N /Print\");\n            this.internal.out(\">>\");\n            this.internal.out(\"endobj\");\n          });\n          this.internal.events.subscribe(\"putCatalog\", function () {\n            this.internal.out(\"/OpenAction \" + refAutoPrintTag + \" 0 R\");\n          });\n          break;\n      }\n\n      return this;\n    };\n  })(jsPDF.API);\n\n  /**\n   * @license\n   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n  /**\n   * jsPDF Canvas PlugIn\n   * This plugin mimics the HTML5 Canvas\n   *\n   * The goal is to provide a way for current canvas users to print directly to a PDF.\n   * @name canvas\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n    /**\n     * @class Canvas\n     * @classdesc A Canvas Wrapper for jsPDF\n     */\n\n    var Canvas = function Canvas() {\n      var jsPdfInstance = undefined;\n      Object.defineProperty(this, \"pdf\", {\n        get: function get() {\n          return jsPdfInstance;\n        },\n        set: function set(value) {\n          jsPdfInstance = value;\n        }\n      });\n      var _width = 150;\n      /**\n       * The height property is a positive integer reflecting the height HTML attribute of the <canvas> element interpreted in CSS pixels. When the attribute is not specified, or if it is set to an invalid value, like a negative, the default value of 150 is used.\n       * This is one of the two properties, the other being width, that controls the size of the canvas.\n       *\n       * @name width\n       */\n\n      Object.defineProperty(this, \"width\", {\n        get: function get() {\n          return _width;\n        },\n        set: function set(value) {\n          if (isNaN(value) || Number.isInteger(value) === false || value < 0) {\n            _width = 150;\n          } else {\n            _width = value;\n          }\n\n          if (this.getContext(\"2d\").pageWrapXEnabled) {\n            this.getContext(\"2d\").pageWrapX = _width + 1;\n          }\n        }\n      });\n      var _height = 300;\n      /**\n       * The width property is a positive integer reflecting the width HTML attribute of the <canvas> element interpreted in CSS pixels. When the attribute is not specified, or if it is set to an invalid value, like a negative, the default value of 300 is used.\n       * This is one of the two properties, the other being height, that controls the size of the canvas.\n       *\n       * @name height\n       */\n\n      Object.defineProperty(this, \"height\", {\n        get: function get() {\n          return _height;\n        },\n        set: function set(value) {\n          if (isNaN(value) || Number.isInteger(value) === false || value < 0) {\n            _height = 300;\n          } else {\n            _height = value;\n          }\n\n          if (this.getContext(\"2d\").pageWrapYEnabled) {\n            this.getContext(\"2d\").pageWrapY = _height + 1;\n          }\n        }\n      });\n      var _childNodes = [];\n      Object.defineProperty(this, \"childNodes\", {\n        get: function get() {\n          return _childNodes;\n        },\n        set: function set(value) {\n          _childNodes = value;\n        }\n      });\n      var _style = {};\n      Object.defineProperty(this, \"style\", {\n        get: function get() {\n          return _style;\n        },\n        set: function set(value) {\n          _style = value;\n        }\n      });\n      Object.defineProperty(this, \"parentNode\", {});\n    };\n    /**\n     * The getContext() method returns a drawing context on the canvas, or null if the context identifier is not supported.\n     *\n     * @name getContext\n     * @function\n     * @param {string} contextType Is a String containing the context identifier defining the drawing context associated to the canvas. Possible value is \"2d\", leading to the creation of a Context2D object representing a two-dimensional rendering context.\n     * @param {object} contextAttributes\n     */\n\n\n    Canvas.prototype.getContext = function (contextType, contextAttributes) {\n      contextType = contextType || \"2d\";\n      var key;\n\n      if (contextType !== \"2d\") {\n        return null;\n      }\n\n      for (key in contextAttributes) {\n        if (this.pdf.context2d.hasOwnProperty(key)) {\n          this.pdf.context2d[key] = contextAttributes[key];\n        }\n      }\n\n      this.pdf.context2d._canvas = this;\n      return this.pdf.context2d;\n    };\n    /**\n     * The toDataURL() method is just a stub to throw an error if accidently called.\n     *\n     * @name toDataURL\n     * @function\n     */\n\n\n    Canvas.prototype.toDataURL = function () {\n      throw new Error(\"toDataURL is not implemented.\");\n    };\n\n    jsPDFAPI.events.push([\"initialized\", function () {\n      this.canvas = new Canvas();\n      this.canvas.pdf = this;\n    }]);\n    return this;\n  })(jsPDF.API);\n\n  /**\n   * @name cell\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n\n    var NO_MARGINS = {\n      left: 0,\n      top: 0,\n      bottom: 0,\n      right: 0\n    };\n    var px2pt = 0.264583 * 72 / 25.4;\n    var printingHeaderRow = false;\n\n    var _initialize = function _initialize() {\n      if (typeof this.internal.__cell__ === \"undefined\") {\n        this.internal.__cell__ = {};\n        this.internal.__cell__.padding = 3;\n        this.internal.__cell__.headerFunction = undefined;\n        this.internal.__cell__.margins = Object.assign({}, NO_MARGINS);\n        this.internal.__cell__.margins.width = this.getPageWidth();\n\n        _reset.call(this);\n      }\n    };\n\n    var _reset = function _reset() {\n      this.internal.__cell__.lastCell = new Cell();\n      this.internal.__cell__.pages = 1;\n    };\n\n    var Cell = function Cell() {\n      var _x = arguments[0];\n      Object.defineProperty(this, \"x\", {\n        enumerable: true,\n        get: function get() {\n          return _x;\n        },\n        set: function set(value) {\n          _x = value;\n        }\n      });\n      var _y = arguments[1];\n      Object.defineProperty(this, \"y\", {\n        enumerable: true,\n        get: function get() {\n          return _y;\n        },\n        set: function set(value) {\n          _y = value;\n        }\n      });\n      var _width = arguments[2];\n      Object.defineProperty(this, \"width\", {\n        enumerable: true,\n        get: function get() {\n          return _width;\n        },\n        set: function set(value) {\n          _width = value;\n        }\n      });\n      var _height = arguments[3];\n      Object.defineProperty(this, \"height\", {\n        enumerable: true,\n        get: function get() {\n          return _height;\n        },\n        set: function set(value) {\n          _height = value;\n        }\n      });\n      var _text = arguments[4];\n      Object.defineProperty(this, \"text\", {\n        enumerable: true,\n        get: function get() {\n          return _text;\n        },\n        set: function set(value) {\n          _text = value;\n        }\n      });\n      var _lineNumber = arguments[5];\n      Object.defineProperty(this, \"lineNumber\", {\n        enumerable: true,\n        get: function get() {\n          return _lineNumber;\n        },\n        set: function set(value) {\n          _lineNumber = value;\n        }\n      });\n      var _align = arguments[6];\n      Object.defineProperty(this, \"align\", {\n        enumerable: true,\n        get: function get() {\n          return _align;\n        },\n        set: function set(value) {\n          _align = value;\n        }\n      });\n      return this;\n    };\n\n    Cell.prototype.clone = function () {\n      return new Cell(this.x, this.y, this.width, this.height, this.text, this.lineNumber, this.align);\n    };\n\n    Cell.prototype.toArray = function () {\n      return [this.x, this.y, this.width, this.height, this.text, this.lineNumber, this.align];\n    };\n    /**\n     * @name setHeaderFunction\n     * @function\n     * @param {function} func\n     */\n\n\n    jsPDFAPI.setHeaderFunction = function (func) {\n      _initialize.call(this);\n\n      this.internal.__cell__.headerFunction = typeof func === \"function\" ? func : undefined;\n      return this;\n    };\n    /**\n     * @name getTextDimensions\n     * @function\n     * @param {string} txt\n     * @returns {Object} dimensions\n     */\n\n\n    jsPDFAPI.getTextDimensions = function (text, options) {\n      _initialize.call(this);\n\n      options = options || {};\n      var fontSize = options.fontSize || this.getFontSize();\n      var font = options.font || this.getFont();\n      var scaleFactor = options.scaleFactor || this.internal.scaleFactor;\n      var width = 0;\n      var amountOfLines = 0;\n      var height = 0;\n      var tempWidth = 0;\n      var scope = this;\n\n      if (!Array.isArray(text) && typeof text !== \"string\") {\n        if (typeof text === \"number\") {\n          text = String(text);\n        } else {\n          throw new Error(\"getTextDimensions expects text-parameter to be of type String or type Number or an Array of Strings.\");\n        }\n      }\n\n      var maxWidth = options.maxWidth;\n\n      if (maxWidth > 0) {\n        if (typeof text === \"string\") {\n          text = this.splitTextToSize(text, maxWidth);\n        } else if (Object.prototype.toString.call(text) === \"[object Array]\") {\n          text = text.reduce(function (acc, textLine) {\n            return acc.concat(scope.splitTextToSize(textLine, maxWidth));\n          }, []);\n        }\n      } else {\n        // Without the else clause, it will not work if you do not pass along maxWidth\n        text = Array.isArray(text) ? text : [text];\n      }\n\n      for (var i = 0; i < text.length; i++) {\n        tempWidth = this.getStringUnitWidth(text[i], {\n          font: font\n        }) * fontSize;\n\n        if (width < tempWidth) {\n          width = tempWidth;\n        }\n      }\n\n      if (width !== 0) {\n        amountOfLines = text.length;\n      }\n\n      width = width / scaleFactor;\n      height = Math.max((amountOfLines * fontSize * this.getLineHeightFactor() - fontSize * (this.getLineHeightFactor() - 1)) / scaleFactor, 0);\n      return {\n        w: width,\n        h: height\n      };\n    };\n    /**\n     * @name cellAddPage\n     * @function\n     */\n\n\n    jsPDFAPI.cellAddPage = function () {\n      _initialize.call(this);\n\n      this.addPage();\n      var margins = this.internal.__cell__.margins || NO_MARGINS;\n      this.internal.__cell__.lastCell = new Cell(margins.left, margins.top, undefined, undefined);\n      this.internal.__cell__.pages += 1;\n      return this;\n    };\n    /**\n     * @name cell\n     * @function\n     * @param {number} x\n     * @param {number} y\n     * @param {number} width\n     * @param {number} height\n     * @param {string} text\n     * @param {number} lineNumber lineNumber\n     * @param {string} align\n     * @return {jsPDF} jsPDF-instance\n     */\n\n\n    var cell = jsPDFAPI.cell = function () {\n      var currentCell;\n\n      if (arguments[0] instanceof Cell) {\n        currentCell = arguments[0];\n      } else {\n        currentCell = new Cell(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);\n      }\n\n      _initialize.call(this);\n\n      var lastCell = this.internal.__cell__.lastCell;\n      var padding = this.internal.__cell__.padding;\n      var margins = this.internal.__cell__.margins || NO_MARGINS;\n      var tableHeaderRow = this.internal.__cell__.tableHeaderRow;\n      var printHeaders = this.internal.__cell__.printHeaders; // If this is not the first cell, we must change its position\n\n      if (typeof lastCell.lineNumber !== \"undefined\") {\n        if (lastCell.lineNumber === currentCell.lineNumber) {\n          //Same line\n          currentCell.x = (lastCell.x || 0) + (lastCell.width || 0);\n          currentCell.y = lastCell.y || 0;\n        } else {\n          //New line\n          if (lastCell.y + lastCell.height + currentCell.height + margins.bottom > this.getPageHeight()) {\n            this.cellAddPage();\n            currentCell.y = margins.top;\n\n            if (printHeaders && tableHeaderRow) {\n              this.printHeaderRow(currentCell.lineNumber, true);\n              currentCell.y += tableHeaderRow[0].height;\n            }\n          } else {\n            currentCell.y = lastCell.y + lastCell.height || currentCell.y;\n          }\n        }\n      }\n\n      if (typeof currentCell.text[0] !== \"undefined\") {\n        this.rect(currentCell.x, currentCell.y, currentCell.width, currentCell.height, printingHeaderRow === true ? \"FD\" : undefined);\n\n        if (currentCell.align === \"right\") {\n          this.text(currentCell.text, currentCell.x + currentCell.width - padding, currentCell.y + padding, {\n            align: \"right\",\n            baseline: \"top\"\n          });\n        } else if (currentCell.align === \"center\") {\n          this.text(currentCell.text, currentCell.x + currentCell.width / 2, currentCell.y + padding, {\n            align: \"center\",\n            baseline: \"top\",\n            maxWidth: currentCell.width - padding - padding\n          });\n        } else {\n          this.text(currentCell.text, currentCell.x + padding, currentCell.y + padding, {\n            align: \"left\",\n            baseline: \"top\",\n            maxWidth: currentCell.width - padding - padding\n          });\n        }\n      }\n\n      this.internal.__cell__.lastCell = currentCell;\n      return this;\n    };\n    /**\n       * Create a table from a set of data.\n       * @name table\n       * @function\n       * @param {Integer} [x] : left-position for top-left corner of table\n       * @param {Integer} [y] top-position for top-left corner of table\n       * @param {Object[]} [data] An array of objects containing key-value pairs corresponding to a row of data.\n       * @param {String[]} [headers] Omit or null to auto-generate headers at a performance cost\n        * @param {Object} [config.printHeaders] True to print column headers at the top of every page\n       * @param {Object} [config.autoSize] True to dynamically set the column widths to match the widest cell value\n       * @param {Object} [config.margins] margin values for left, top, bottom, and width\n       * @param {Object} [config.fontSize] Integer fontSize to use (optional)\n       * @param {Object} [config.padding] cell-padding in pt to use (optional)\n       * @param {Object} [config.headerBackgroundColor] default is #c8c8c8 (optional)\n       * @param {Object} [config.headerTextColor] default is #000 (optional)\n       * @param {Object} [config.rowStart] callback to handle before print each row (optional)\n       * @param {Object} [config.cellStart] callback to handle before print each cell (optional)\n       * @returns {jsPDF} jsPDF-instance\n       */\n\n\n    jsPDFAPI.table = function (x, y, data, headers, config) {\n      _initialize.call(this);\n\n      if (!data) {\n        throw new Error(\"No data for PDF table.\");\n      }\n\n      config = config || {};\n      var headerNames = [],\n          headerLabels = [],\n          headerAligns = [],\n          i,\n          columnMatrix = {},\n          columnWidths = {},\n          column,\n          columnMinWidths = [],\n          j,\n          tableHeaderConfigs = [],\n          //set up defaults. If a value is provided in config, defaults will be overwritten:\n      autoSize = config.autoSize || false,\n          printHeaders = config.printHeaders === false ? false : true,\n          fontSize = config.css && typeof config.css[\"font-size\"] !== \"undefined\" ? config.css[\"font-size\"] * 16 : config.fontSize || 12,\n          margins = config.margins || Object.assign({\n        width: this.getPageWidth()\n      }, NO_MARGINS),\n          padding = typeof config.padding === \"number\" ? config.padding : 3,\n          headerBackgroundColor = config.headerBackgroundColor || \"#c8c8c8\",\n          headerTextColor = config.headerTextColor || \"#000\";\n\n      _reset.call(this);\n\n      this.internal.__cell__.printHeaders = printHeaders;\n      this.internal.__cell__.margins = margins;\n      this.internal.__cell__.table_font_size = fontSize;\n      this.internal.__cell__.padding = padding;\n      this.internal.__cell__.headerBackgroundColor = headerBackgroundColor;\n      this.internal.__cell__.headerTextColor = headerTextColor;\n      this.setFontSize(fontSize); // Set header values\n\n      if (headers === undefined || headers === null) {\n        // No headers defined so we derive from data\n        headerNames = Object.keys(data[0]);\n        headerLabels = headerNames;\n        headerAligns = headerNames.map(function () {\n          return \"left\";\n        });\n      } else if (Array.isArray(headers) && _typeof(headers[0]) === \"object\") {\n        headerNames = headers.map(function (header) {\n          return header.name;\n        });\n        headerLabels = headers.map(function (header) {\n          return header.prompt || header.name || \"\";\n        });\n        headerAligns = headers.map(function (header) {\n          return header.align || \"left\";\n        }); // Split header configs into names and prompts\n\n        for (i = 0; i < headers.length; i += 1) {\n          columnWidths[headers[i].name] = headers[i].width * px2pt;\n        }\n      } else if (Array.isArray(headers) && typeof headers[0] === \"string\") {\n        headerNames = headers;\n        headerLabels = headerNames;\n        headerAligns = headerNames.map(function () {\n          return \"left\";\n        });\n      }\n\n      if (autoSize || Array.isArray(headers) && typeof headers[0] === \"string\") {\n        var headerName;\n\n        for (i = 0; i < headerNames.length; i += 1) {\n          headerName = headerNames[i]; // Create a matrix of columns e.g., {column_title: [row1_Record, row2_Record]}\n\n          columnMatrix[headerName] = data.map(function (rec) {\n            return rec[headerName];\n          }); // get header width\n\n          this.setFont(undefined, \"bold\");\n          columnMinWidths.push(this.getTextDimensions(headerLabels[i], {\n            fontSize: this.internal.__cell__.table_font_size,\n            scaleFactor: this.internal.scaleFactor\n          }).w);\n          column = columnMatrix[headerName]; // get cell widths\n\n          this.setFont(undefined, \"normal\");\n\n          for (j = 0; j < column.length; j += 1) {\n            columnMinWidths.push(this.getTextDimensions(column[j], {\n              fontSize: this.internal.__cell__.table_font_size,\n              scaleFactor: this.internal.scaleFactor\n            }).w);\n          } // get final column width\n\n\n          columnWidths[headerName] = Math.max.apply(null, columnMinWidths) + padding + padding; //have to reset\n\n          columnMinWidths = [];\n        }\n      } // -- Construct the table\n\n\n      if (printHeaders) {\n        var row = {};\n\n        for (i = 0; i < headerNames.length; i += 1) {\n          row[headerNames[i]] = {};\n          row[headerNames[i]].text = headerLabels[i];\n          row[headerNames[i]].align = headerAligns[i];\n        }\n\n        var rowHeight = calculateLineHeight.call(this, row, columnWidths); // Construct the header row\n\n        tableHeaderConfigs = headerNames.map(function (value) {\n          return new Cell(x, y, columnWidths[value], rowHeight, row[value].text, undefined, row[value].align);\n        }); // Store the table header config\n\n        this.setTableHeaderRow(tableHeaderConfigs); // Print the header for the start of the table\n\n        this.printHeaderRow(1, false);\n      } // Construct the data rows\n\n\n      var align = headers.reduce(function (pv, cv) {\n        pv[cv.name] = cv.align;\n        return pv;\n      }, {});\n\n      for (i = 0; i < data.length; i += 1) {\n        if (\"rowStart\" in config && config.rowStart instanceof Function) {\n          config.rowStart({\n            row: i,\n            data: data[i]\n          }, this);\n        }\n\n        var lineHeight = calculateLineHeight.call(this, data[i], columnWidths);\n\n        for (j = 0; j < headerNames.length; j += 1) {\n          var cellData = data[i][headerNames[j]];\n\n          if (\"cellStart\" in config && config.cellStart instanceof Function) {\n            config.cellStart({\n              row: i,\n              col: j,\n              data: cellData\n            }, this);\n          }\n\n          cell.call(this, new Cell(x, y, columnWidths[headerNames[j]], lineHeight, cellData, i + 2, align[headerNames[j]]));\n        }\n      }\n\n      this.internal.__cell__.table_x = x;\n      this.internal.__cell__.table_y = y;\n      return this;\n    };\n    /**\n     * Calculate the height for containing the highest column\n     *\n     * @name calculateLineHeight\n     * @function\n     * @param {Object[]} model is the line of data we want to calculate the height of\n     * @param {Integer[]} columnWidths is size of each column\n     * @returns {number} lineHeight\n     * @private\n     */\n\n\n    var calculateLineHeight = function calculateLineHeight(model, columnWidths) {\n      var padding = this.internal.__cell__.padding;\n      var fontSize = this.internal.__cell__.table_font_size;\n      var scaleFactor = this.internal.scaleFactor;\n      return Object.keys(model).map(function (key) {\n        var value = model[key];\n        return this.splitTextToSize(value.hasOwnProperty(\"text\") ? value.text : value, columnWidths[key] - padding - padding);\n      }, this).map(function (value) {\n        return this.getLineHeightFactor() * value.length * fontSize / scaleFactor + padding + padding;\n      }, this).reduce(function (pv, cv) {\n        return Math.max(pv, cv);\n      }, 0);\n    };\n    /**\n     * Store the config for outputting a table header\n     *\n     * @name setTableHeaderRow\n     * @function\n     * @param {Object[]} config\n     * An array of cell configs that would define a header row: Each config matches the config used by jsPDFAPI.cell\n     * except the lineNumber parameter is excluded\n     */\n\n\n    jsPDFAPI.setTableHeaderRow = function (config) {\n      _initialize.call(this);\n\n      this.internal.__cell__.tableHeaderRow = config;\n    };\n    /**\n     * Output the store header row\n     *\n     * @name printHeaderRow\n     * @function\n     * @param {number} lineNumber The line number to output the header at\n     * @param {boolean} new_page\n     */\n\n\n    jsPDFAPI.printHeaderRow = function (lineNumber, new_page) {\n      _initialize.call(this);\n\n      if (!this.internal.__cell__.tableHeaderRow) {\n        throw new Error(\"Property tableHeaderRow does not exist.\");\n      }\n\n      var tableHeaderCell;\n      printingHeaderRow = true;\n\n      if (typeof this.internal.__cell__.headerFunction === \"function\") {\n        var position = this.internal.__cell__.headerFunction(this, this.internal.__cell__.pages);\n\n        this.internal.__cell__.lastCell = new Cell(position[0], position[1], position[2], position[3], undefined, -1);\n      }\n\n      this.setFont(undefined, \"bold\");\n      var tempHeaderConf = [];\n\n      for (var i = 0; i < this.internal.__cell__.tableHeaderRow.length; i += 1) {\n        tableHeaderCell = this.internal.__cell__.tableHeaderRow[i].clone();\n\n        if (new_page) {\n          tableHeaderCell.y = this.internal.__cell__.margins.top || 0;\n          tempHeaderConf.push(tableHeaderCell);\n        }\n\n        tableHeaderCell.lineNumber = lineNumber;\n        var currentTextColor = this.getTextColor();\n        this.setTextColor(this.internal.__cell__.headerTextColor);\n        this.setFillColor(this.internal.__cell__.headerBackgroundColor);\n        cell.call(this, tableHeaderCell);\n        this.setTextColor(currentTextColor);\n      }\n\n      if (tempHeaderConf.length > 0) {\n        this.setTableHeaderRow(tempHeaderConf);\n      }\n\n      this.setFont(undefined, \"normal\");\n      printingHeaderRow = false;\n    };\n  })(jsPDF.API);\n\n  function toLookup(arr) {\n    return arr.reduce(function (lookup, name, index) {\n      lookup[name] = index;\n      return lookup;\n    }, {});\n  }\n\n  var fontStyleOrder = {\n    italic: [\"italic\", \"oblique\", \"normal\"],\n    oblique: [\"oblique\", \"italic\", \"normal\"],\n    normal: [\"normal\", \"oblique\", \"italic\"]\n  };\n  var fontStretchOrder = [\"ultra-condensed\", \"extra-condensed\", \"condensed\", \"semi-condensed\", \"normal\", \"semi-expanded\", \"expanded\", \"extra-expanded\", \"ultra-expanded\"]; // For a given font-stretch value, we need to know where to start our search\n  // from in the fontStretchOrder list.\n\n  var fontStretchLookup = toLookup(fontStretchOrder);\n  var fontWeights = [100, 200, 300, 400, 500, 600, 700, 800, 900];\n  var fontWeightsLookup = toLookup(fontWeights);\n\n  function normalizeFontStretch(stretch) {\n    stretch = stretch || \"normal\";\n    return typeof fontStretchLookup[stretch] === \"number\" ? stretch : \"normal\";\n  }\n\n  function normalizeFontStyle(style) {\n    style = style || \"normal\";\n    return fontStyleOrder[style] ? style : \"normal\";\n  }\n\n  function normalizeFontWeight(weight) {\n    if (!weight) {\n      return 400;\n    }\n\n    if (typeof weight === \"number\") {\n      // Ignore values which aren't valid font-weights.\n      return weight >= 100 && weight <= 900 && weight % 100 === 0 ? weight : 400;\n    }\n\n    if (/^\\d00$/.test(weight)) {\n      return parseInt(weight);\n    }\n\n    switch (weight) {\n      case \"bold\":\n        return 700;\n\n      case \"normal\":\n      default:\n        return 400;\n    }\n  }\n\n  function normalizeFontFace(fontFace) {\n    var family = fontFace.family.replace(/\"|'/g, \"\").toLowerCase();\n    var style = normalizeFontStyle(fontFace.style);\n    var weight = normalizeFontWeight(fontFace.weight);\n    var stretch = normalizeFontStretch(fontFace.stretch);\n    return {\n      family: family,\n      style: style,\n      weight: weight,\n      stretch: stretch,\n      src: fontFace.src || [],\n      // The ref property maps this font-face to the font\n      // added by the .addFont() method.\n      ref: fontFace.ref || {\n        name: family,\n        style: [stretch, style, weight].join(\" \")\n      }\n    };\n  }\n  /**\n   * Turns a list of font-faces into a map, for easier lookup when resolving\n   * fonts.\n   * @private\n   */\n\n  function buildFontFaceMap(fontFaces) {\n    var map = {};\n\n    for (var i = 0; i < fontFaces.length; ++i) {\n      var normalized = normalizeFontFace(fontFaces[i]);\n      var name = normalized.family;\n      var stretch = normalized.stretch;\n      var style = normalized.style;\n      var weight = normalized.weight;\n      map[name] = map[name] || {};\n      map[name][stretch] = map[name][stretch] || {};\n      map[name][stretch][style] = map[name][stretch][style] || {};\n      map[name][stretch][style][weight] = normalized;\n    }\n\n    return map;\n  }\n  /**\n   * Searches a map of stretches, weights, etc. in the given direction and\n   * then, if no match has been found, in the opposite directions.\n   *\n   * @param {Object.<string, any>} matchingSet A map of the various font variations.\n   * @param {any[]} order The order of the different variations\n   * @param {number} pivot The starting point of the search in the order list.\n   * @param {number} dir The initial direction of the search (desc = -1, asc = 1)\n   * @private\n   */\n\n  function searchFromPivot(matchingSet, order, pivot, dir) {\n    var i;\n\n    for (i = pivot; i >= 0 && i < order.length; i += dir) {\n      if (matchingSet[order[i]]) {\n        return matchingSet[order[i]];\n      }\n    }\n\n    for (i = pivot; i >= 0 && i < order.length; i -= dir) {\n      if (matchingSet[order[i]]) {\n        return matchingSet[order[i]];\n      }\n    }\n  }\n\n  function resolveFontStretch(stretch, matchingSet) {\n    if (matchingSet[stretch]) {\n      return matchingSet[stretch];\n    }\n\n    var pivot = fontStretchLookup[stretch]; // If the font-stretch value is normal or more condensed, we want to\n    // start with a descending search, otherwise we should do ascending.\n\n    var dir = pivot <= fontStretchLookup[\"normal\"] ? -1 : 1;\n    var match = searchFromPivot(matchingSet, fontStretchOrder, pivot, dir);\n\n    if (!match) {\n      // Since a font-family cannot exist without having at least one stretch value\n      // we should never reach this point.\n      throw new Error(\"Could not find a matching font-stretch value for \" + stretch);\n    }\n\n    return match;\n  }\n\n  function resolveFontStyle(fontStyle, matchingSet) {\n    if (matchingSet[fontStyle]) {\n      return matchingSet[fontStyle];\n    }\n\n    var ordering = fontStyleOrder[fontStyle];\n\n    for (var i = 0; i < ordering.length; ++i) {\n      if (matchingSet[ordering[i]]) {\n        return matchingSet[ordering[i]];\n      }\n    } // Since a font-family cannot exist without having at least one style value\n    // we should never reach this point.\n\n\n    throw new Error(\"Could not find a matching font-style for \" + fontStyle);\n  }\n\n  function resolveFontWeight(weight, matchingSet) {\n    if (matchingSet[weight]) {\n      return matchingSet[weight];\n    }\n\n    if (weight === 400 && matchingSet[500]) {\n      return matchingSet[500];\n    }\n\n    if (weight === 500 && matchingSet[400]) {\n      return matchingSet[400];\n    }\n\n    var pivot = fontWeightsLookup[weight]; // If the font-stretch value is normal or more condensed, we want to\n    // start with a descending search, otherwise we should do ascending.\n\n    var dir = weight < 400 ? -1 : 1;\n    var match = searchFromPivot(matchingSet, fontWeights, pivot, dir);\n\n    if (!match) {\n      // Since a font-family cannot exist without having at least one stretch value\n      // we should never reach this point.\n      throw new Error(\"Could not find a matching font-weight for value \" + weight);\n    }\n\n    return match;\n  }\n\n  var defaultGenericFontFamilies = {\n    \"sans-serif\": \"helvetica\",\n    fixed: \"courier\",\n    monospace: \"courier\",\n    terminal: \"courier\",\n    cursive: \"times\",\n    fantasy: \"times\",\n    serif: \"times\"\n  };\n  var systemFonts = {\n    caption: \"times\",\n    icon: \"times\",\n    menu: \"times\",\n    \"message-box\": \"times\",\n    \"small-caption\": \"times\",\n    \"status-bar\": \"times\"\n  };\n\n  function ruleToString(rule) {\n    return [rule.stretch, rule.style, rule.weight, rule.family].join(\" \");\n  }\n\n  function resolveFontFace(fontFaceMap, rules, opts) {\n    opts = opts || {};\n    var defaultFontFamily = opts.defaultFontFamily || \"times\";\n    var genericFontFamilies = Object.assign({}, defaultGenericFontFamilies, opts.genericFontFamilies || {});\n    var rule = null;\n    var matches = null;\n\n    for (var i = 0; i < rules.length; ++i) {\n      rule = normalizeFontFace(rules[i]);\n\n      if (genericFontFamilies[rule.family]) {\n        rule.family = genericFontFamilies[rule.family];\n      }\n\n      if (fontFaceMap.hasOwnProperty(rule.family)) {\n        matches = fontFaceMap[rule.family];\n        break;\n      }\n    } // Always fallback to a known font family.\n\n\n    matches = matches || fontFaceMap[defaultFontFamily];\n\n    if (!matches) {\n      // At this point we should definitiely have a font family, but if we\n      // don't there is something wrong with our configuration\n      throw new Error(\"Could not find a font-family for the rule '\" + ruleToString(rule) + \"' and default family '\" + defaultFontFamily + \"'.\");\n    }\n\n    matches = resolveFontStretch(rule.stretch, matches);\n    matches = resolveFontStyle(rule.style, matches);\n    matches = resolveFontWeight(rule.weight, matches);\n\n    if (!matches) {\n      // We should've fount\n      throw new Error(\"Failed to resolve a font for the rule '\" + ruleToString(rule) + \"'.\");\n    }\n\n    return matches;\n  }\n\n  function eatWhiteSpace(input) {\n    return input.trimLeft();\n  }\n\n  function parseQuotedFontFamily(input, quote) {\n    var index = 0;\n\n    while (index < input.length) {\n      var current = input.charAt(index);\n\n      if (current === quote) {\n        return [input.substring(0, index), input.substring(index + 1)];\n      }\n\n      index += 1;\n    } // Unexpected end of input\n\n\n    return null;\n  }\n\n  function parseNonQuotedFontFamily(input) {\n    // It implements part of the identifier parser here: https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n    //\n    // NOTE: This parser pretty much ignores escaped identifiers and that there is a thing called unicode.\n    //\n    // Breakdown of regexp:\n    // -[a-z_]     - when identifier starts with a hyphen, you're not allowed to have another hyphen or a digit\n    // [a-z_]      - allow a-z and underscore at beginning of input\n    // [a-z0-9_-]* - after that, anything goes\n    var match = input.match(/^(-[a-z_]|[a-z_])[a-z0-9_-]*/i); // non quoted value contains illegal characters\n\n    if (match === null) {\n      return null;\n    }\n\n    return [match[0], input.substring(match[0].length)];\n  }\n\n  var defaultFont = [\"times\"];\n  function parseFontFamily(input) {\n    var result = [];\n    var ch, parsed;\n    var remaining = input.trim();\n\n    if (remaining === \"\") {\n      return defaultFont;\n    }\n\n    if (remaining in systemFonts) {\n      return [systemFonts[remaining]];\n    }\n\n    while (remaining !== \"\") {\n      parsed = null;\n      remaining = eatWhiteSpace(remaining);\n      ch = remaining.charAt(0);\n\n      switch (ch) {\n        case '\"':\n        case \"'\":\n          parsed = parseQuotedFontFamily(remaining.substring(1), ch);\n          break;\n\n        default:\n          parsed = parseNonQuotedFontFamily(remaining);\n          break;\n      }\n\n      if (parsed === null) {\n        return defaultFont;\n      }\n\n      result.push(parsed[0]);\n      remaining = eatWhiteSpace(parsed[1]); // We expect end of input or a comma separator here\n\n      if (remaining !== \"\" && remaining.charAt(0) !== \",\") {\n        return defaultFont;\n      }\n\n      remaining = remaining.replace(/^,/, \"\");\n    }\n\n    return result;\n  }\n\n  /**\n   * This plugin mimics the HTML5 CanvasRenderingContext2D.\n   *\n   * The goal is to provide a way for current canvas implementations to print directly to a PDF.\n   *\n   * @name context2d\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n\n    var ContextLayer = function ContextLayer(ctx) {\n      ctx = ctx || {};\n      this.isStrokeTransparent = ctx.isStrokeTransparent || false;\n      this.strokeOpacity = ctx.strokeOpacity || 1;\n      this.strokeStyle = ctx.strokeStyle || \"#000000\";\n      this.fillStyle = ctx.fillStyle || \"#000000\";\n      this.isFillTransparent = ctx.isFillTransparent || false;\n      this.fillOpacity = ctx.fillOpacity || 1;\n      this.font = ctx.font || \"10px sans-serif\";\n      this.textBaseline = ctx.textBaseline || \"alphabetic\";\n      this.textAlign = ctx.textAlign || \"left\";\n      this.lineWidth = ctx.lineWidth || 1;\n      this.lineJoin = ctx.lineJoin || \"miter\";\n      this.lineCap = ctx.lineCap || \"butt\";\n      this.path = ctx.path || [];\n      this.transform = typeof ctx.transform !== \"undefined\" ? ctx.transform.clone() : new Matrix();\n      this.globalCompositeOperation = ctx.globalCompositeOperation || \"normal\";\n      this.globalAlpha = ctx.globalAlpha || 1.0;\n      this.clip_path = ctx.clip_path || [];\n      this.currentPoint = ctx.currentPoint || new Point();\n      this.miterLimit = ctx.miterLimit || 10.0;\n      this.lastPoint = ctx.lastPoint || new Point();\n      this.lineDashOffset = ctx.lineDashOffset || 0.0;\n      this.lineDash = ctx.lineDash || [];\n      this.margin = ctx.margin || [0, 0, 0, 0];\n      this.prevPageLastElemOffset = ctx.prevPageLastElemOffset || 0;\n      this.ignoreClearRect = typeof ctx.ignoreClearRect === \"boolean\" ? ctx.ignoreClearRect : true;\n      return this;\n    }; //stub\n\n\n    var f2, getHorizontalCoordinateString, getVerticalCoordinateString, getHorizontalCoordinate, getVerticalCoordinate, Point, Rectangle, Matrix, _ctx;\n\n    jsPDFAPI.events.push([\"initialized\", function () {\n      this.context2d = new Context2D(this);\n      f2 = this.internal.f2;\n      getHorizontalCoordinateString = this.internal.getCoordinateString;\n      getVerticalCoordinateString = this.internal.getVerticalCoordinateString;\n      getHorizontalCoordinate = this.internal.getHorizontalCoordinate;\n      getVerticalCoordinate = this.internal.getVerticalCoordinate;\n      Point = this.internal.Point;\n      Rectangle = this.internal.Rectangle;\n      Matrix = this.internal.Matrix;\n      _ctx = new ContextLayer();\n    }]);\n\n    var Context2D = function Context2D(pdf) {\n      Object.defineProperty(this, \"canvas\", {\n        get: function get() {\n          return {\n            parentNode: false,\n            style: false\n          };\n        }\n      });\n      var _pdf = pdf;\n      Object.defineProperty(this, \"pdf\", {\n        get: function get() {\n          return _pdf;\n        }\n      });\n      var _pageWrapXEnabled = false;\n      /**\n       * @name pageWrapXEnabled\n       * @type {boolean}\n       * @default false\n       */\n\n      Object.defineProperty(this, \"pageWrapXEnabled\", {\n        get: function get() {\n          return _pageWrapXEnabled;\n        },\n        set: function set(value) {\n          _pageWrapXEnabled = Boolean(value);\n        }\n      });\n      var _pageWrapYEnabled = false;\n      /**\n       * @name pageWrapYEnabled\n       * @type {boolean}\n       * @default true\n       */\n\n      Object.defineProperty(this, \"pageWrapYEnabled\", {\n        get: function get() {\n          return _pageWrapYEnabled;\n        },\n        set: function set(value) {\n          _pageWrapYEnabled = Boolean(value);\n        }\n      });\n      var _posX = 0;\n      /**\n       * @name posX\n       * @type {number}\n       * @default 0\n       */\n\n      Object.defineProperty(this, \"posX\", {\n        get: function get() {\n          return _posX;\n        },\n        set: function set(value) {\n          if (!isNaN(value)) {\n            _posX = value;\n          }\n        }\n      });\n      var _posY = 0;\n      /**\n       * @name posY\n       * @type {number}\n       * @default 0\n       */\n\n      Object.defineProperty(this, \"posY\", {\n        get: function get() {\n          return _posY;\n        },\n        set: function set(value) {\n          if (!isNaN(value)) {\n            _posY = value;\n          }\n        }\n      });\n      /**\n       * Gets or sets the page margin when using auto paging. Has no effect when {@link autoPaging} is off.\n       * @name margin\n       * @type {number|number[]}\n       * @default [0, 0, 0, 0]\n       */\n\n      Object.defineProperty(this, \"margin\", {\n        get: function get() {\n          return _ctx.margin;\n        },\n        set: function set(value) {\n          var margin;\n\n          if (typeof value === \"number\") {\n            margin = [value, value, value, value];\n          } else {\n            margin = new Array(4);\n            margin[0] = value[0];\n            margin[1] = value.length >= 2 ? value[1] : margin[0];\n            margin[2] = value.length >= 3 ? value[2] : margin[0];\n            margin[3] = value.length >= 4 ? value[3] : margin[1];\n          }\n\n          _ctx.margin = margin;\n        }\n      });\n      var _autoPaging = false;\n      /**\n       * Gets or sets the auto paging mode. When auto paging is enabled, the context2d will automatically draw on the\n       * next page if a shape or text chunk doesn't fit entirely on the current page. The context2d will create new\n       * pages if required.\n       *\n       * Context2d supports different modes:\n       * <ul>\n       * <li>\n       *   <code>false</code>: Auto paging is disabled.\n       * </li>\n       * <li>\n       *   <code>true</code> or <code>'slice'</code>: Will cut shapes or text chunks across page breaks. Will possibly\n       *   slice text in half, making it difficult to read.\n       * </li>\n       * <li>\n       *   <code>'text'</code>: Trys not to cut text in half across page breaks. Works best for documents consisting\n       *   mostly of a single column of text.\n       * </li>\n       * </ul>\n       * @name Context2D#autoPaging\n       * @type {boolean|\"slice\"|\"text\"}\n       * @default false\n       */\n\n      Object.defineProperty(this, \"autoPaging\", {\n        get: function get() {\n          return _autoPaging;\n        },\n        set: function set(value) {\n          _autoPaging = value;\n        }\n      });\n      var lastBreak = 0;\n      /**\n       * @name lastBreak\n       * @type {number}\n       * @default 0\n       */\n\n      Object.defineProperty(this, \"lastBreak\", {\n        get: function get() {\n          return lastBreak;\n        },\n        set: function set(value) {\n          lastBreak = value;\n        }\n      });\n      var pageBreaks = [];\n      /**\n       * Y Position of page breaks.\n       * @name pageBreaks\n       * @type {number}\n       * @default 0\n       */\n\n      Object.defineProperty(this, \"pageBreaks\", {\n        get: function get() {\n          return pageBreaks;\n        },\n        set: function set(value) {\n          pageBreaks = value;\n        }\n      });\n      /**\n       * @name ctx\n       * @type {object}\n       * @default {}\n       */\n\n      Object.defineProperty(this, \"ctx\", {\n        get: function get() {\n          return _ctx;\n        },\n        set: function set(value) {\n          if (value instanceof ContextLayer) {\n            _ctx = value;\n          }\n        }\n      });\n      /**\n       * @name path\n       * @type {array}\n       * @default []\n       */\n\n      Object.defineProperty(this, \"path\", {\n        get: function get() {\n          return _ctx.path;\n        },\n        set: function set(value) {\n          _ctx.path = value;\n        }\n      });\n      /**\n       * @name ctxStack\n       * @type {array}\n       * @default []\n       */\n\n      var _ctxStack = [];\n      Object.defineProperty(this, \"ctxStack\", {\n        get: function get() {\n          return _ctxStack;\n        },\n        set: function set(value) {\n          _ctxStack = value;\n        }\n      });\n      /**\n       * Sets or returns the color, gradient, or pattern used to fill the drawing\n       *\n       * @name fillStyle\n       * @default #000000\n       * @property {(color|gradient|pattern)} value The color of the drawing. Default value is #000000<br />\n       * A gradient object (linear or radial) used to fill the drawing (not supported by context2d)<br />\n       * A pattern object to use to fill the drawing (not supported by context2d)\n       */\n\n      Object.defineProperty(this, \"fillStyle\", {\n        get: function get() {\n          return this.ctx.fillStyle;\n        },\n        set: function set(value) {\n          var rgba;\n          rgba = getRGBA(value);\n          this.ctx.fillStyle = rgba.style;\n          this.ctx.isFillTransparent = rgba.a === 0;\n          this.ctx.fillOpacity = rgba.a;\n          this.pdf.setFillColor(rgba.r, rgba.g, rgba.b, {\n            a: rgba.a\n          });\n          this.pdf.setTextColor(rgba.r, rgba.g, rgba.b, {\n            a: rgba.a\n          });\n        }\n      });\n      /**\n       * Sets or returns the color, gradient, or pattern used for strokes\n       *\n       * @name strokeStyle\n       * @default #000000\n       * @property {color} color A CSS color value that indicates the stroke color of the drawing. Default value is #000000 (not supported by context2d)\n       * @property {gradient} gradient A gradient object (linear or radial) used to create a gradient stroke (not supported by context2d)\n       * @property {pattern} pattern A pattern object used to create a pattern stroke (not supported by context2d)\n       */\n\n      Object.defineProperty(this, \"strokeStyle\", {\n        get: function get() {\n          return this.ctx.strokeStyle;\n        },\n        set: function set(value) {\n          var rgba = getRGBA(value);\n          this.ctx.strokeStyle = rgba.style;\n          this.ctx.isStrokeTransparent = rgba.a === 0;\n          this.ctx.strokeOpacity = rgba.a;\n\n          if (rgba.a === 0) {\n            this.pdf.setDrawColor(255, 255, 255);\n          } else if (rgba.a === 1) {\n            this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b);\n          } else {\n            this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b);\n          }\n        }\n      });\n      /**\n       * Sets or returns the style of the end caps for a line\n       *\n       * @name lineCap\n       * @default butt\n       * @property {(butt|round|square)} lineCap butt A flat edge is added to each end of the line <br/>\n       * round A rounded end cap is added to each end of the line<br/>\n       * square A square end cap is added to each end of the line<br/>\n       */\n\n      Object.defineProperty(this, \"lineCap\", {\n        get: function get() {\n          return this.ctx.lineCap;\n        },\n        set: function set(value) {\n          if ([\"butt\", \"round\", \"square\"].indexOf(value) !== -1) {\n            this.ctx.lineCap = value;\n            this.pdf.setLineCap(value);\n          }\n        }\n      });\n      /**\n       * Sets or returns the current line width\n       *\n       * @name lineWidth\n       * @default 1\n       * @property {number} lineWidth The current line width, in pixels\n       */\n\n      Object.defineProperty(this, \"lineWidth\", {\n        get: function get() {\n          return this.ctx.lineWidth;\n        },\n        set: function set(value) {\n          if (!isNaN(value)) {\n            this.ctx.lineWidth = value;\n            this.pdf.setLineWidth(value);\n          }\n        }\n      });\n      /**\n       * Sets or returns the type of corner created, when two lines meet\n       */\n\n      Object.defineProperty(this, \"lineJoin\", {\n        get: function get() {\n          return this.ctx.lineJoin;\n        },\n        set: function set(value) {\n          if ([\"bevel\", \"round\", \"miter\"].indexOf(value) !== -1) {\n            this.ctx.lineJoin = value;\n            this.pdf.setLineJoin(value);\n          }\n        }\n      });\n      /**\n       * A number specifying the miter limit ratio in coordinate space units. Zero, negative, Infinity, and NaN values are ignored. The default value is 10.0.\n       *\n       * @name miterLimit\n       * @default 10\n       */\n\n      Object.defineProperty(this, \"miterLimit\", {\n        get: function get() {\n          return this.ctx.miterLimit;\n        },\n        set: function set(value) {\n          if (!isNaN(value)) {\n            this.ctx.miterLimit = value;\n            this.pdf.setMiterLimit(value);\n          }\n        }\n      });\n      Object.defineProperty(this, \"textBaseline\", {\n        get: function get() {\n          return this.ctx.textBaseline;\n        },\n        set: function set(value) {\n          this.ctx.textBaseline = value;\n        }\n      });\n      Object.defineProperty(this, \"textAlign\", {\n        get: function get() {\n          return this.ctx.textAlign;\n        },\n        set: function set(value) {\n          if ([\"right\", \"end\", \"center\", \"left\", \"start\"].indexOf(value) !== -1) {\n            this.ctx.textAlign = value;\n          }\n        }\n      });\n      var _fontFaceMap = null;\n\n      function getFontFaceMap(pdf, fontFaces) {\n        if (_fontFaceMap === null) {\n          var fontMap = pdf.getFontList();\n          var convertedFontFaces = convertToFontFaces(fontMap);\n          _fontFaceMap = buildFontFaceMap(convertedFontFaces.concat(fontFaces));\n        }\n\n        return _fontFaceMap;\n      }\n\n      function convertToFontFaces(fontMap) {\n        var fontFaces = [];\n        Object.keys(fontMap).forEach(function (family) {\n          var styles = fontMap[family];\n          styles.forEach(function (style) {\n            var fontFace = null;\n\n            switch (style) {\n              case \"bold\":\n                fontFace = {\n                  family: family,\n                  weight: \"bold\"\n                };\n                break;\n\n              case \"italic\":\n                fontFace = {\n                  family: family,\n                  style: \"italic\"\n                };\n                break;\n\n              case \"bolditalic\":\n                fontFace = {\n                  family: family,\n                  weight: \"bold\",\n                  style: \"italic\"\n                };\n                break;\n\n              case \"\":\n              case \"normal\":\n                fontFace = {\n                  family: family\n                };\n                break;\n            } // If font-face is still null here, it is a font with some styling we don't recognize and\n            // cannot map or it is a font added via the fontFaces option of .html().\n\n\n            if (fontFace !== null) {\n              fontFace.ref = {\n                name: family,\n                style: style\n              };\n              fontFaces.push(fontFace);\n            }\n          });\n        });\n        return fontFaces;\n      }\n\n      var _fontFaces = null;\n      /**\n       * A map of available font-faces, as passed in the options of\n       * .html(). If set a limited implementation of the font style matching\n       * algorithm defined by https://www.w3.org/TR/css-fonts-3/#font-matching-algorithm\n       * will be used. If not set it will fallback to previous behavior.\n       */\n\n      Object.defineProperty(this, \"fontFaces\", {\n        get: function get() {\n          return _fontFaces;\n        },\n        set: function set(value) {\n          _fontFaceMap = null;\n          _fontFaces = value;\n        }\n      });\n      Object.defineProperty(this, \"font\", {\n        get: function get() {\n          return this.ctx.font;\n        },\n        set: function set(value) {\n          this.ctx.font = value;\n          var rx, matches; //source: https://stackoverflow.com/a/10136041\n          // eslint-disable-next-line no-useless-escape\n\n          rx = /^\\s*(?=(?:(?:[-a-z]+\\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\\1|\\2|\\3)\\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\\d]+(?:\\%|in|[cem]m|ex|p[ctx]))(?:\\s*\\/\\s*(normal|[.\\d]+(?:\\%|in|[cem]m|ex|p[ctx])))?\\s*([-_,\\\"\\'\\sa-z]+?)\\s*$/i;\n          matches = rx.exec(value);\n\n          if (matches !== null) {\n            var fontStyle = matches[1];\n            var fontVariant = matches[2];\n            var fontWeight = matches[3];\n            var fontSize = matches[4];\n            var lineHeight = matches[5];\n            var fontFamily = matches[6];\n          } else {\n            return;\n          }\n\n          var rxFontSize = /^([.\\d]+)((?:%|in|[cem]m|ex|p[ctx]))$/i;\n          var fontSizeUnit = rxFontSize.exec(fontSize)[2];\n\n          if (\"px\" === fontSizeUnit) {\n            fontSize = Math.floor(parseFloat(fontSize) * this.pdf.internal.scaleFactor);\n          } else if (\"em\" === fontSizeUnit) {\n            fontSize = Math.floor(parseFloat(fontSize) * this.pdf.getFontSize());\n          } else {\n            fontSize = Math.floor(parseFloat(fontSize) * this.pdf.internal.scaleFactor);\n          }\n\n          this.pdf.setFontSize(fontSize);\n          var parts = parseFontFamily(fontFamily);\n\n          if (this.fontFaces) {\n            var fontFaceMap = getFontFaceMap(this.pdf, this.fontFaces);\n            var rules = parts.map(function (ff) {\n              return {\n                family: ff,\n                stretch: \"normal\",\n                // TODO: Extract font-stretch from font rule (perhaps write proper parser for it?)\n                weight: fontWeight,\n                style: fontStyle\n              };\n            });\n            var font = resolveFontFace(fontFaceMap, rules);\n            this.pdf.setFont(font.ref.name, font.ref.style);\n            return;\n          }\n\n          var style = \"\";\n\n          if (fontWeight === \"bold\" || parseInt(fontWeight, 10) >= 700 || fontStyle === \"bold\") {\n            style = \"bold\";\n          }\n\n          if (fontStyle === \"italic\") {\n            style += \"italic\";\n          }\n\n          if (style.length === 0) {\n            style = \"normal\";\n          }\n\n          var jsPdfFontName = \"\";\n          var fallbackFonts = {\n            arial: \"Helvetica\",\n            Arial: \"Helvetica\",\n            verdana: \"Helvetica\",\n            Verdana: \"Helvetica\",\n            helvetica: \"Helvetica\",\n            Helvetica: \"Helvetica\",\n            \"sans-serif\": \"Helvetica\",\n            fixed: \"Courier\",\n            monospace: \"Courier\",\n            terminal: \"Courier\",\n            cursive: \"Times\",\n            fantasy: \"Times\",\n            serif: \"Times\"\n          };\n\n          for (var i = 0; i < parts.length; i++) {\n            if (this.pdf.internal.getFont(parts[i], style, {\n              noFallback: true,\n              disableWarning: true\n            }) !== undefined) {\n              jsPdfFontName = parts[i];\n              break;\n            } else if (style === \"bolditalic\" && this.pdf.internal.getFont(parts[i], \"bold\", {\n              noFallback: true,\n              disableWarning: true\n            }) !== undefined) {\n              jsPdfFontName = parts[i];\n              style = \"bold\";\n            } else if (this.pdf.internal.getFont(parts[i], \"normal\", {\n              noFallback: true,\n              disableWarning: true\n            }) !== undefined) {\n              jsPdfFontName = parts[i];\n              style = \"normal\";\n              break;\n            }\n          }\n\n          if (jsPdfFontName === \"\") {\n            for (var j = 0; j < parts.length; j++) {\n              if (fallbackFonts[parts[j]]) {\n                jsPdfFontName = fallbackFonts[parts[j]];\n                break;\n              }\n            }\n          }\n\n          jsPdfFontName = jsPdfFontName === \"\" ? \"Times\" : jsPdfFontName;\n          this.pdf.setFont(jsPdfFontName, style);\n        }\n      });\n      Object.defineProperty(this, \"globalCompositeOperation\", {\n        get: function get() {\n          return this.ctx.globalCompositeOperation;\n        },\n        set: function set(value) {\n          this.ctx.globalCompositeOperation = value;\n        }\n      });\n      Object.defineProperty(this, \"globalAlpha\", {\n        get: function get() {\n          return this.ctx.globalAlpha;\n        },\n        set: function set(value) {\n          this.ctx.globalAlpha = value;\n        }\n      });\n      /**\n       * A float specifying the amount of the line dash offset. The default value is 0.0.\n       *\n       * @name lineDashOffset\n       * @default 0.0\n       */\n\n      Object.defineProperty(this, \"lineDashOffset\", {\n        get: function get() {\n          return this.ctx.lineDashOffset;\n        },\n        set: function set(value) {\n          this.ctx.lineDashOffset = value;\n          setLineDash.call(this);\n        }\n      }); // Not HTML API\n\n      Object.defineProperty(this, \"lineDash\", {\n        get: function get() {\n          return this.ctx.lineDash;\n        },\n        set: function set(value) {\n          this.ctx.lineDash = value;\n          setLineDash.call(this);\n        }\n      }); // Not HTML API\n\n      Object.defineProperty(this, \"ignoreClearRect\", {\n        get: function get() {\n          return this.ctx.ignoreClearRect;\n        },\n        set: function set(value) {\n          this.ctx.ignoreClearRect = Boolean(value);\n        }\n      });\n    };\n    /**\n     * Sets the line dash pattern used when stroking lines.\n     * @name setLineDash\n     * @function\n     * @description It uses an array of values that specify alternating lengths of lines and gaps which describe the pattern.\n     */\n\n\n    Context2D.prototype.setLineDash = function (dashArray) {\n      this.lineDash = dashArray;\n    };\n    /**\n     * gets the current line dash pattern.\n     * @name getLineDash\n     * @function\n     * @returns {Array} An Array of numbers that specify distances to alternately draw a line and a gap (in coordinate space units). If the number, when setting the elements, is odd, the elements of the array get copied and concatenated. For example, setting the line dash to [5, 15, 25] will result in getting back [5, 15, 25, 5, 15, 25].\n     */\n\n\n    Context2D.prototype.getLineDash = function () {\n      if (this.lineDash.length % 2) {\n        // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getLineDash#return_value\n        return this.lineDash.concat(this.lineDash);\n      } else {\n        // The copied value is returned to prevent contamination from outside.\n        return this.lineDash.slice();\n      }\n    };\n\n    Context2D.prototype.fill = function () {\n      pathPreProcess.call(this, \"fill\", false);\n    };\n    /**\n     * Actually draws the path you have defined\n     *\n     * @name stroke\n     * @function\n     * @description The stroke() method actually draws the path you have defined with all those moveTo() and lineTo() methods. The default color is black.\n     */\n\n\n    Context2D.prototype.stroke = function () {\n      pathPreProcess.call(this, \"stroke\", false);\n    };\n    /**\n     * Begins a path, or resets the current\n     *\n     * @name beginPath\n     * @function\n     * @description The beginPath() method begins a path, or resets the current path.\n     */\n\n\n    Context2D.prototype.beginPath = function () {\n      this.path = [{\n        type: \"begin\"\n      }];\n    };\n    /**\n     * Moves the path to the specified point in the canvas, without creating a line\n     *\n     * @name moveTo\n     * @function\n     * @param x {Number} The x-coordinate of where to move the path to\n     * @param y {Number} The y-coordinate of where to move the path to\n     */\n\n\n    Context2D.prototype.moveTo = function (x, y) {\n      if (isNaN(x) || isNaN(y)) {\n        console.error(\"jsPDF.context2d.moveTo: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.moveTo\");\n      }\n\n      var pt = this.ctx.transform.applyToPoint(new Point(x, y));\n      this.path.push({\n        type: \"mt\",\n        x: pt.x,\n        y: pt.y\n      });\n      this.ctx.lastPoint = new Point(x, y);\n    };\n    /**\n     * Creates a path from the current point back to the starting point\n     *\n     * @name closePath\n     * @function\n     * @description The closePath() method creates a path from the current point back to the starting point.\n     */\n\n\n    Context2D.prototype.closePath = function () {\n      var pathBegin = new Point(0, 0);\n      var i = 0;\n\n      for (i = this.path.length - 1; i !== -1; i--) {\n        if (this.path[i].type === \"begin\") {\n          if (_typeof(this.path[i + 1]) === \"object\" && typeof this.path[i + 1].x === \"number\") {\n            pathBegin = new Point(this.path[i + 1].x, this.path[i + 1].y);\n            break;\n          }\n        }\n      }\n\n      this.path.push({\n        type: \"close\"\n      });\n      this.ctx.lastPoint = new Point(pathBegin.x, pathBegin.y);\n    };\n    /**\n     * Adds a new point and creates a line to that point from the last specified point in the canvas\n     *\n     * @name lineTo\n     * @function\n     * @param x The x-coordinate of where to create the line to\n     * @param y The y-coordinate of where to create the line to\n     * @description The lineTo() method adds a new point and creates a line TO that point FROM the last specified point in the canvas (this method does not draw the line).\n     */\n\n\n    Context2D.prototype.lineTo = function (x, y) {\n      if (isNaN(x) || isNaN(y)) {\n        console.error(\"jsPDF.context2d.lineTo: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.lineTo\");\n      }\n\n      var pt = this.ctx.transform.applyToPoint(new Point(x, y));\n      this.path.push({\n        type: \"lt\",\n        x: pt.x,\n        y: pt.y\n      });\n      this.ctx.lastPoint = new Point(pt.x, pt.y);\n    };\n    /**\n     * Clips a region of any shape and size from the original canvas\n     *\n     * @name clip\n     * @function\n     * @description The clip() method clips a region of any shape and size from the original canvas.\n     */\n\n\n    Context2D.prototype.clip = function () {\n      this.ctx.clip_path = JSON.parse(JSON.stringify(this.path));\n      pathPreProcess.call(this, null, true);\n    };\n    /**\n     * Creates a cubic Bézier curve\n     *\n     * @name quadraticCurveTo\n     * @function\n     * @param cpx {Number} The x-coordinate of the Bézier control point\n     * @param cpy {Number} The y-coordinate of the Bézier control point\n     * @param x {Number} The x-coordinate of the ending point\n     * @param y {Number} The y-coordinate of the ending point\n     * @description The quadraticCurveTo() method adds a point to the current path by using the specified control points that represent a quadratic Bézier curve.<br /><br /> A quadratic Bézier curve requires two points. The first point is a control point that is used in the quadratic Bézier calculation and the second point is the ending point for the curve. The starting point for the curve is the last point in the current path. If a path does not exist, use the beginPath() and moveTo() methods to define a starting point.\n     */\n\n\n    Context2D.prototype.quadraticCurveTo = function (cpx, cpy, x, y) {\n      if (isNaN(x) || isNaN(y) || isNaN(cpx) || isNaN(cpy)) {\n        console.error(\"jsPDF.context2d.quadraticCurveTo: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.quadraticCurveTo\");\n      }\n\n      var pt0 = this.ctx.transform.applyToPoint(new Point(x, y));\n      var pt1 = this.ctx.transform.applyToPoint(new Point(cpx, cpy));\n      this.path.push({\n        type: \"qct\",\n        x1: pt1.x,\n        y1: pt1.y,\n        x: pt0.x,\n        y: pt0.y\n      });\n      this.ctx.lastPoint = new Point(pt0.x, pt0.y);\n    };\n    /**\n     * Creates a cubic Bézier curve\n     *\n     * @name bezierCurveTo\n     * @function\n     * @param cp1x {Number} The x-coordinate of the first Bézier control point\n     * @param cp1y {Number} The y-coordinate of the first Bézier control point\n     * @param cp2x {Number} The x-coordinate of the second Bézier control point\n     * @param cp2y {Number} The y-coordinate of the second Bézier control point\n     * @param x {Number} The x-coordinate of the ending point\n     * @param y {Number} The y-coordinate of the ending point\n     * @description The bezierCurveTo() method adds a point to the current path by using the specified control points that represent a cubic Bézier curve. <br /><br />A cubic bezier curve requires three points. The first two points are control points that are used in the cubic Bézier calculation and the last point is the ending point for the curve.  The starting point for the curve is the last point in the current path. If a path does not exist, use the beginPath() and moveTo() methods to define a starting point.\n     */\n\n\n    Context2D.prototype.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {\n      if (isNaN(x) || isNaN(y) || isNaN(cp1x) || isNaN(cp1y) || isNaN(cp2x) || isNaN(cp2y)) {\n        console.error(\"jsPDF.context2d.bezierCurveTo: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.bezierCurveTo\");\n      }\n\n      var pt0 = this.ctx.transform.applyToPoint(new Point(x, y));\n      var pt1 = this.ctx.transform.applyToPoint(new Point(cp1x, cp1y));\n      var pt2 = this.ctx.transform.applyToPoint(new Point(cp2x, cp2y));\n      this.path.push({\n        type: \"bct\",\n        x1: pt1.x,\n        y1: pt1.y,\n        x2: pt2.x,\n        y2: pt2.y,\n        x: pt0.x,\n        y: pt0.y\n      });\n      this.ctx.lastPoint = new Point(pt0.x, pt0.y);\n    };\n    /**\n     * Creates an arc/curve (used to create circles, or parts of circles)\n     *\n     * @name arc\n     * @function\n     * @param x {Number} The x-coordinate of the center of the circle\n     * @param y {Number} The y-coordinate of the center of the circle\n     * @param radius {Number} The radius of the circle\n     * @param startAngle {Number} The starting angle, in radians (0 is at the 3 o'clock position of the arc's circle)\n     * @param endAngle {Number} The ending angle, in radians\n     * @param counterclockwise {Boolean} Optional. Specifies whether the drawing should be counterclockwise or clockwise. False is default, and indicates clockwise, while true indicates counter-clockwise.\n     * @description The arc() method creates an arc/curve (used to create circles, or parts of circles).\n     */\n\n\n    Context2D.prototype.arc = function (x, y, radius, startAngle, endAngle, counterclockwise) {\n      if (isNaN(x) || isNaN(y) || isNaN(radius) || isNaN(startAngle) || isNaN(endAngle)) {\n        console.error(\"jsPDF.context2d.arc: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.arc\");\n      }\n\n      counterclockwise = Boolean(counterclockwise);\n\n      if (!this.ctx.transform.isIdentity) {\n        var xpt = this.ctx.transform.applyToPoint(new Point(x, y));\n        x = xpt.x;\n        y = xpt.y;\n        var x_radPt = this.ctx.transform.applyToPoint(new Point(0, radius));\n        var x_radPt0 = this.ctx.transform.applyToPoint(new Point(0, 0));\n        radius = Math.sqrt(Math.pow(x_radPt.x - x_radPt0.x, 2) + Math.pow(x_radPt.y - x_radPt0.y, 2));\n      }\n\n      if (Math.abs(endAngle - startAngle) >= 2 * Math.PI) {\n        startAngle = 0;\n        endAngle = 2 * Math.PI;\n      }\n\n      this.path.push({\n        type: \"arc\",\n        x: x,\n        y: y,\n        radius: radius,\n        startAngle: startAngle,\n        endAngle: endAngle,\n        counterclockwise: counterclockwise\n      }); // this.ctx.lastPoint(new Point(pt.x,pt.y));\n    };\n    /**\n     * Creates an arc/curve between two tangents\n     *\n     * @name arcTo\n     * @function\n     * @param x1 {Number} The x-coordinate of the first tangent\n     * @param y1 {Number} The y-coordinate of the first tangent\n     * @param x2 {Number} The x-coordinate of the second tangent\n     * @param y2 {Number} The y-coordinate of the second tangent\n     * @param radius The radius of the arc\n     * @description The arcTo() method creates an arc/curve between two tangents on the canvas.\n     */\n    // eslint-disable-next-line no-unused-vars\n\n\n    Context2D.prototype.arcTo = function (x1, y1, x2, y2, radius) {\n      throw new Error(\"arcTo not implemented.\");\n    };\n    /**\n     * Creates a rectangle\n     *\n     * @name rect\n     * @function\n     * @param x {Number} The x-coordinate of the upper-left corner of the rectangle\n     * @param y {Number} The y-coordinate of the upper-left corner of the rectangle\n     * @param w {Number} The width of the rectangle, in pixels\n     * @param h {Number} The height of the rectangle, in pixels\n     * @description The rect() method creates a rectangle.\n     */\n\n\n    Context2D.prototype.rect = function (x, y, w, h) {\n      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) {\n        console.error(\"jsPDF.context2d.rect: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.rect\");\n      }\n\n      this.moveTo(x, y);\n      this.lineTo(x + w, y);\n      this.lineTo(x + w, y + h);\n      this.lineTo(x, y + h);\n      this.lineTo(x, y);\n      this.lineTo(x + w, y);\n      this.lineTo(x, y);\n    };\n    /**\n     * Draws a \"filled\" rectangle\n     *\n     * @name fillRect\n     * @function\n     * @param x {Number} The x-coordinate of the upper-left corner of the rectangle\n     * @param y {Number} The y-coordinate of the upper-left corner of the rectangle\n     * @param w {Number} The width of the rectangle, in pixels\n     * @param h {Number} The height of the rectangle, in pixels\n     * @description The fillRect() method draws a \"filled\" rectangle. The default color of the fill is black.\n     */\n\n\n    Context2D.prototype.fillRect = function (x, y, w, h) {\n      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) {\n        console.error(\"jsPDF.context2d.fillRect: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.fillRect\");\n      }\n\n      if (isFillTransparent.call(this)) {\n        return;\n      }\n\n      var tmp = {};\n\n      if (this.lineCap !== \"butt\") {\n        tmp.lineCap = this.lineCap;\n        this.lineCap = \"butt\";\n      }\n\n      if (this.lineJoin !== \"miter\") {\n        tmp.lineJoin = this.lineJoin;\n        this.lineJoin = \"miter\";\n      }\n\n      this.beginPath();\n      this.rect(x, y, w, h);\n      this.fill();\n\n      if (tmp.hasOwnProperty(\"lineCap\")) {\n        this.lineCap = tmp.lineCap;\n      }\n\n      if (tmp.hasOwnProperty(\"lineJoin\")) {\n        this.lineJoin = tmp.lineJoin;\n      }\n    };\n    /**\n     *     Draws a rectangle (no fill)\n     *\n     * @name strokeRect\n     * @function\n     * @param x {Number} The x-coordinate of the upper-left corner of the rectangle\n     * @param y {Number} The y-coordinate of the upper-left corner of the rectangle\n     * @param w {Number} The width of the rectangle, in pixels\n     * @param h {Number} The height of the rectangle, in pixels\n     * @description The strokeRect() method draws a rectangle (no fill). The default color of the stroke is black.\n     */\n\n\n    Context2D.prototype.strokeRect = function strokeRect(x, y, w, h) {\n      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) {\n        console.error(\"jsPDF.context2d.strokeRect: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.strokeRect\");\n      }\n\n      if (isStrokeTransparent.call(this)) {\n        return;\n      }\n\n      this.beginPath();\n      this.rect(x, y, w, h);\n      this.stroke();\n    };\n    /**\n     * Clears the specified pixels within a given rectangle\n     *\n     * @name clearRect\n     * @function\n     * @param x {Number} The x-coordinate of the upper-left corner of the rectangle\n     * @param y {Number} The y-coordinate of the upper-left corner of the rectangle\n     * @param w {Number} The width of the rectangle to clear, in pixels\n     * @param h {Number} The height of the rectangle to clear, in pixels\n     * @description We cannot clear PDF commands that were already written to PDF, so we use white instead. <br />\n     * As a special case, read a special flag (ignoreClearRect) and do nothing if it is set.\n     * This results in all calls to clearRect() to do nothing, and keep the canvas transparent.\n     * This flag is stored in the save/restore context and is managed the same way as other drawing states.\n     *\n     */\n\n\n    Context2D.prototype.clearRect = function (x, y, w, h) {\n      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) {\n        console.error(\"jsPDF.context2d.clearRect: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.clearRect\");\n      }\n\n      if (this.ignoreClearRect) {\n        return;\n      }\n\n      this.fillStyle = \"#ffffff\";\n      this.fillRect(x, y, w, h);\n    };\n    /**\n     * Saves the state of the current context\n     *\n     * @name save\n     * @function\n     */\n\n\n    Context2D.prototype.save = function (doStackPush) {\n      doStackPush = typeof doStackPush === \"boolean\" ? doStackPush : true;\n      var tmpPageNumber = this.pdf.internal.getCurrentPageInfo().pageNumber;\n\n      for (var i = 0; i < this.pdf.internal.getNumberOfPages(); i++) {\n        this.pdf.setPage(i + 1);\n        this.pdf.internal.out(\"q\");\n      }\n\n      this.pdf.setPage(tmpPageNumber);\n\n      if (doStackPush) {\n        this.ctx.fontSize = this.pdf.internal.getFontSize();\n        var ctx = new ContextLayer(this.ctx);\n        this.ctxStack.push(this.ctx);\n        this.ctx = ctx;\n      }\n    };\n    /**\n     * Returns previously saved path state and attributes\n     *\n     * @name restore\n     * @function\n     */\n\n\n    Context2D.prototype.restore = function (doStackPop) {\n      doStackPop = typeof doStackPop === \"boolean\" ? doStackPop : true;\n      var tmpPageNumber = this.pdf.internal.getCurrentPageInfo().pageNumber;\n\n      for (var i = 0; i < this.pdf.internal.getNumberOfPages(); i++) {\n        this.pdf.setPage(i + 1);\n        this.pdf.internal.out(\"Q\");\n      }\n\n      this.pdf.setPage(tmpPageNumber);\n\n      if (doStackPop && this.ctxStack.length !== 0) {\n        this.ctx = this.ctxStack.pop();\n        this.fillStyle = this.ctx.fillStyle;\n        this.strokeStyle = this.ctx.strokeStyle;\n        this.font = this.ctx.font;\n        this.lineCap = this.ctx.lineCap;\n        this.lineWidth = this.ctx.lineWidth;\n        this.lineJoin = this.ctx.lineJoin;\n        this.lineDash = this.ctx.lineDash;\n        this.lineDashOffset = this.ctx.lineDashOffset;\n      }\n    };\n    /**\n     * @name toDataURL\n     * @function\n     */\n\n\n    Context2D.prototype.toDataURL = function () {\n      throw new Error(\"toDataUrl not implemented.\");\n    }; //helper functions\n\n    /**\n     * Get the decimal values of r, g, b and a\n     *\n     * @name getRGBA\n     * @function\n     * @private\n     * @ignore\n     */\n\n\n    var getRGBA = function getRGBA(style) {\n      var rxRgb = /rgb\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\)/;\n      var rxRgba = /rgba\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*([\\d.]+)\\s*\\)/;\n      var rxTransparent = /transparent|rgba\\s*\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*0+\\s*\\)/;\n      var r, g, b, a;\n\n      if (style.isCanvasGradient === true) {\n        style = style.getColor();\n      }\n\n      if (!style) {\n        return {\n          r: 0,\n          g: 0,\n          b: 0,\n          a: 0,\n          style: style\n        };\n      }\n\n      if (rxTransparent.test(style)) {\n        r = 0;\n        g = 0;\n        b = 0;\n        a = 0;\n      } else {\n        var matches = rxRgb.exec(style);\n\n        if (matches !== null) {\n          r = parseInt(matches[1]);\n          g = parseInt(matches[2]);\n          b = parseInt(matches[3]);\n          a = 1;\n        } else {\n          matches = rxRgba.exec(style);\n\n          if (matches !== null) {\n            r = parseInt(matches[1]);\n            g = parseInt(matches[2]);\n            b = parseInt(matches[3]);\n            a = parseFloat(matches[4]);\n          } else {\n            a = 1;\n\n            if (typeof style === \"string\" && style.charAt(0) !== \"#\") {\n              var rgbColor = new RGBColor(style);\n\n              if (rgbColor.ok) {\n                style = rgbColor.toHex();\n              } else {\n                style = \"#000000\";\n              }\n            }\n\n            if (style.length === 4) {\n              r = style.substring(1, 2);\n              r += r;\n              g = style.substring(2, 3);\n              g += g;\n              b = style.substring(3, 4);\n              b += b;\n            } else {\n              r = style.substring(1, 3);\n              g = style.substring(3, 5);\n              b = style.substring(5, 7);\n            }\n\n            r = parseInt(r, 16);\n            g = parseInt(g, 16);\n            b = parseInt(b, 16);\n          }\n        }\n      }\n\n      return {\n        r: r,\n        g: g,\n        b: b,\n        a: a,\n        style: style\n      };\n    };\n    /**\n     * @name isFillTransparent\n     * @function\n     * @private\n     * @ignore\n     * @returns {Boolean}\n     */\n\n\n    var isFillTransparent = function isFillTransparent() {\n      return this.ctx.isFillTransparent || this.globalAlpha == 0;\n    };\n    /**\n     * @name isStrokeTransparent\n     * @function\n     * @private\n     * @ignore\n     * @returns {Boolean}\n     */\n\n\n    var isStrokeTransparent = function isStrokeTransparent() {\n      return Boolean(this.ctx.isStrokeTransparent || this.globalAlpha == 0);\n    };\n    /**\n     * Draws \"filled\" text on the canvas\n     *\n     * @name fillText\n     * @function\n     * @param text {String} Specifies the text that will be written on the canvas\n     * @param x {Number} The x coordinate where to start painting the text (relative to the canvas)\n     * @param y {Number} The y coordinate where to start painting the text (relative to the canvas)\n     * @param maxWidth {Number} Optional. The maximum allowed width of the text, in pixels\n     * @description The fillText() method draws filled text on the canvas. The default color of the text is black.\n     */\n\n\n    Context2D.prototype.fillText = function (text, x, y, maxWidth) {\n      if (isNaN(x) || isNaN(y) || typeof text !== \"string\") {\n        console.error(\"jsPDF.context2d.fillText: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.fillText\");\n      }\n\n      maxWidth = isNaN(maxWidth) ? undefined : maxWidth;\n\n      if (isFillTransparent.call(this)) {\n        return;\n      }\n\n      var degs = rad2deg(this.ctx.transform.rotation); // We only use X axis as scale hint\n\n      var scale = this.ctx.transform.scaleX;\n      putText.call(this, {\n        text: text,\n        x: x,\n        y: y,\n        scale: scale,\n        angle: degs,\n        align: this.textAlign,\n        maxWidth: maxWidth\n      });\n    };\n    /**\n     * Draws text on the canvas (no fill)\n     *\n     * @name strokeText\n     * @function\n     * @param text {String} Specifies the text that will be written on the canvas\n     * @param x {Number} The x coordinate where to start painting the text (relative to the canvas)\n     * @param y {Number} The y coordinate where to start painting the text (relative to the canvas)\n     * @param maxWidth {Number} Optional. The maximum allowed width of the text, in pixels\n     * @description The strokeText() method draws text (with no fill) on the canvas. The default color of the text is black.\n     */\n\n\n    Context2D.prototype.strokeText = function (text, x, y, maxWidth) {\n      if (isNaN(x) || isNaN(y) || typeof text !== \"string\") {\n        console.error(\"jsPDF.context2d.strokeText: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.strokeText\");\n      }\n\n      if (isStrokeTransparent.call(this)) {\n        return;\n      }\n\n      maxWidth = isNaN(maxWidth) ? undefined : maxWidth;\n      var degs = rad2deg(this.ctx.transform.rotation);\n      var scale = this.ctx.transform.scaleX;\n      putText.call(this, {\n        text: text,\n        x: x,\n        y: y,\n        scale: scale,\n        renderingMode: \"stroke\",\n        angle: degs,\n        align: this.textAlign,\n        maxWidth: maxWidth\n      });\n    };\n    /**\n     * Returns an object that contains the width of the specified text\n     *\n     * @name measureText\n     * @function\n     * @param text {String} The text to be measured\n     * @description The measureText() method returns an object that contains the width of the specified text, in pixels.\n     * @returns {Number}\n     */\n\n\n    Context2D.prototype.measureText = function (text) {\n      if (typeof text !== \"string\") {\n        console.error(\"jsPDF.context2d.measureText: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.measureText\");\n      }\n\n      var pdf = this.pdf;\n      var k = this.pdf.internal.scaleFactor;\n      var fontSize = pdf.internal.getFontSize();\n      var txtWidth = pdf.getStringUnitWidth(text) * fontSize / pdf.internal.scaleFactor;\n      txtWidth *= Math.round(k * 96 / 72 * 10000) / 10000;\n\n      var TextMetrics = function TextMetrics(options) {\n        options = options || {};\n\n        var _width = options.width || 0;\n\n        Object.defineProperty(this, \"width\", {\n          get: function get() {\n            return _width;\n          }\n        });\n        return this;\n      };\n\n      return new TextMetrics({\n        width: txtWidth\n      });\n    }; //Transformations\n\n    /**\n     * Scales the current drawing bigger or smaller\n     *\n     * @name scale\n     * @function\n     * @param scalewidth {Number} Scales the width of the current drawing (1=100%, 0.5=50%, 2=200%, etc.)\n     * @param scaleheight {Number} Scales the height of the current drawing (1=100%, 0.5=50%, 2=200%, etc.)\n     * @description The scale() method scales the current drawing, bigger or smaller.\n     */\n\n\n    Context2D.prototype.scale = function (scalewidth, scaleheight) {\n      if (isNaN(scalewidth) || isNaN(scaleheight)) {\n        console.error(\"jsPDF.context2d.scale: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.scale\");\n      }\n\n      var matrix = new Matrix(scalewidth, 0.0, 0.0, scaleheight, 0.0, 0.0);\n      this.ctx.transform = this.ctx.transform.multiply(matrix);\n    };\n    /**\n     * Rotates the current drawing\n     *\n     * @name rotate\n     * @function\n     * @param angle {Number} The rotation angle, in radians.\n     * @description To calculate from degrees to radians: degrees*Math.PI/180. <br />\n     * Example: to rotate 5 degrees, specify the following: 5*Math.PI/180\n     */\n\n\n    Context2D.prototype.rotate = function (angle) {\n      if (isNaN(angle)) {\n        console.error(\"jsPDF.context2d.rotate: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.rotate\");\n      }\n\n      var matrix = new Matrix(Math.cos(angle), Math.sin(angle), -Math.sin(angle), Math.cos(angle), 0.0, 0.0);\n      this.ctx.transform = this.ctx.transform.multiply(matrix);\n    };\n    /**\n     * Remaps the (0,0) position on the canvas\n     *\n     * @name translate\n     * @function\n     * @param x {Number} The value to add to horizontal (x) coordinates\n     * @param y {Number} The value to add to vertical (y) coordinates\n     * @description The translate() method remaps the (0,0) position on the canvas.\n     */\n\n\n    Context2D.prototype.translate = function (x, y) {\n      if (isNaN(x) || isNaN(y)) {\n        console.error(\"jsPDF.context2d.translate: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.translate\");\n      }\n\n      var matrix = new Matrix(1.0, 0.0, 0.0, 1.0, x, y);\n      this.ctx.transform = this.ctx.transform.multiply(matrix);\n    };\n    /**\n     * Replaces the current transformation matrix for the drawing\n     *\n     * @name transform\n     * @function\n     * @param a {Number} Horizontal scaling\n     * @param b {Number} Horizontal skewing\n     * @param c {Number} Vertical skewing\n     * @param d {Number} Vertical scaling\n     * @param e {Number} Horizontal moving\n     * @param f {Number} Vertical moving\n     * @description Each object on the canvas has a current transformation matrix.<br /><br />The transform() method replaces the current transformation matrix. It multiplies the current transformation matrix with the matrix described by:<br /><br /><br /><br />a    c    e<br /><br />b    d    f<br /><br />0    0    1<br /><br />In other words, the transform() method lets you scale, rotate, move, and skew the current context.\n     */\n\n\n    Context2D.prototype.transform = function (a, b, c, d, e, f) {\n      if (isNaN(a) || isNaN(b) || isNaN(c) || isNaN(d) || isNaN(e) || isNaN(f)) {\n        console.error(\"jsPDF.context2d.transform: Invalid arguments\", arguments);\n        throw new Error(\"Invalid arguments passed to jsPDF.context2d.transform\");\n      }\n\n      var matrix = new Matrix(a, b, c, d, e, f);\n      this.ctx.transform = this.ctx.transform.multiply(matrix);\n    };\n    /**\n     * Resets the current transform to the identity matrix. Then runs transform()\n     *\n     * @name setTransform\n     * @function\n     * @param a {Number} Horizontal scaling\n     * @param b {Number} Horizontal skewing\n     * @param c {Number} Vertical skewing\n     * @param d {Number} Vertical scaling\n     * @param e {Number} Horizontal moving\n     * @param f {Number} Vertical moving\n     * @description Each object on the canvas has a current transformation matrix. <br /><br />The setTransform() method resets the current transform to the identity matrix, and then runs transform() with the same arguments.<br /><br />In other words, the setTransform() method lets you scale, rotate, move, and skew the current context.\n     */\n\n\n    Context2D.prototype.setTransform = function (a, b, c, d, e, f) {\n      a = isNaN(a) ? 1 : a;\n      b = isNaN(b) ? 0 : b;\n      c = isNaN(c) ? 0 : c;\n      d = isNaN(d) ? 1 : d;\n      e = isNaN(e) ? 0 : e;\n      f = isNaN(f) ? 0 : f;\n      this.ctx.transform = new Matrix(a, b, c, d, e, f);\n    };\n\n    var hasMargins = function hasMargins() {\n      return this.margin[0] > 0 || this.margin[1] > 0 || this.margin[2] > 0 || this.margin[3] > 0;\n    };\n    /**\n     * Draws an image, canvas, or video onto the canvas\n     *\n     * @function\n     * @param img {} Specifies the image, canvas, or video element to use\n     * @param sx {Number} Optional. The x coordinate where to start clipping\n     * @param sy {Number} Optional. The y coordinate where to start clipping\n     * @param swidth {Number} Optional. The width of the clipped image\n     * @param sheight {Number} Optional. The height of the clipped image\n     * @param x {Number} The x coordinate where to place the image on the canvas\n     * @param y {Number} The y coordinate where to place the image on the canvas\n     * @param width {Number} Optional. The width of the image to use (stretch or reduce the image)\n     * @param height {Number} Optional. The height of the image to use (stretch or reduce the image)\n     */\n\n\n    Context2D.prototype.drawImage = function (img, sx, sy, swidth, sheight, x, y, width, height) {\n      var imageProperties = this.pdf.getImageProperties(img);\n      var factorX = 1;\n      var factorY = 1;\n      var clipFactorX = 1;\n      var clipFactorY = 1;\n\n      if (typeof swidth !== \"undefined\" && typeof width !== \"undefined\") {\n        clipFactorX = width / swidth;\n        clipFactorY = height / sheight;\n        factorX = imageProperties.width / swidth * width / swidth;\n        factorY = imageProperties.height / sheight * height / sheight;\n      } //is sx and sy are set and x and y not, set x and y with values of sx and sy\n\n\n      if (typeof x === \"undefined\") {\n        x = sx;\n        y = sy;\n        sx = 0;\n        sy = 0;\n      }\n\n      if (typeof swidth !== \"undefined\" && typeof width === \"undefined\") {\n        width = swidth;\n        height = sheight;\n      }\n\n      if (typeof swidth === \"undefined\" && typeof width === \"undefined\") {\n        width = imageProperties.width;\n        height = imageProperties.height;\n      }\n\n      var decomposedTransformationMatrix = this.ctx.transform.decompose();\n      var angle = rad2deg(decomposedTransformationMatrix.rotate.shx);\n      var matrix = new Matrix();\n      matrix = matrix.multiply(decomposedTransformationMatrix.translate);\n      matrix = matrix.multiply(decomposedTransformationMatrix.skew);\n      matrix = matrix.multiply(decomposedTransformationMatrix.scale);\n      var xRect = matrix.applyToRectangle(new Rectangle(x - sx * clipFactorX, y - sy * clipFactorY, swidth * factorX, sheight * factorY));\n      var pageArray = getPagesByPath.call(this, xRect);\n      var pages = [];\n\n      for (var ii = 0; ii < pageArray.length; ii += 1) {\n        if (pages.indexOf(pageArray[ii]) === -1) {\n          pages.push(pageArray[ii]);\n        }\n      }\n\n      sortPages(pages);\n      var clipPath;\n\n      if (this.autoPaging) {\n        var min = pages[0];\n        var max = pages[pages.length - 1];\n\n        for (var i = min; i < max + 1; i++) {\n          this.pdf.setPage(i);\n          var pageWidthMinusMargins = this.pdf.internal.pageSize.width - this.margin[3] - this.margin[1];\n          var topMargin = i === 1 ? this.posY + this.margin[0] : this.margin[0];\n          var firstPageHeight = this.pdf.internal.pageSize.height - this.posY - this.margin[0] - this.margin[2];\n          var pageHeightMinusMargins = this.pdf.internal.pageSize.height - this.margin[0] - this.margin[2];\n          var previousPageHeightSum = i === 1 ? 0 : firstPageHeight + (i - 2) * pageHeightMinusMargins;\n\n          if (this.ctx.clip_path.length !== 0) {\n            var tmpPaths = this.path;\n            clipPath = JSON.parse(JSON.stringify(this.ctx.clip_path));\n            this.path = pathPositionRedo(clipPath, this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset);\n            drawPaths.call(this, \"fill\", true);\n            this.path = tmpPaths;\n          }\n\n          var tmpRect = JSON.parse(JSON.stringify(xRect));\n          tmpRect = pathPositionRedo([tmpRect], this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset)[0];\n          var needsClipping = (i > min || i < max) && hasMargins.call(this);\n\n          if (needsClipping) {\n            this.pdf.saveGraphicsState();\n            this.pdf.rect(this.margin[3], this.margin[0], pageWidthMinusMargins, pageHeightMinusMargins, null).clip().discardPath();\n          }\n\n          this.pdf.addImage(img, \"JPEG\", tmpRect.x, tmpRect.y, tmpRect.w, tmpRect.h, null, null, angle);\n\n          if (needsClipping) {\n            this.pdf.restoreGraphicsState();\n          }\n        }\n      } else {\n        this.pdf.addImage(img, \"JPEG\", xRect.x, xRect.y, xRect.w, xRect.h, null, null, angle);\n      }\n    };\n\n    var getPagesByPath = function getPagesByPath(path, pageWrapX, pageWrapY) {\n      var result = [];\n      pageWrapX = pageWrapX || this.pdf.internal.pageSize.width;\n      pageWrapY = pageWrapY || this.pdf.internal.pageSize.height - this.margin[0] - this.margin[2];\n      var yOffset = this.posY + this.ctx.prevPageLastElemOffset;\n\n      switch (path.type) {\n        default:\n        case \"mt\":\n        case \"lt\":\n          result.push(Math.floor((path.y + yOffset) / pageWrapY) + 1);\n          break;\n\n        case \"arc\":\n          result.push(Math.floor((path.y + yOffset - path.radius) / pageWrapY) + 1);\n          result.push(Math.floor((path.y + yOffset + path.radius) / pageWrapY) + 1);\n          break;\n\n        case \"qct\":\n          var rectOfQuadraticCurve = getQuadraticCurveBoundary(this.ctx.lastPoint.x, this.ctx.lastPoint.y, path.x1, path.y1, path.x, path.y);\n          result.push(Math.floor((rectOfQuadraticCurve.y + yOffset) / pageWrapY) + 1);\n          result.push(Math.floor((rectOfQuadraticCurve.y + rectOfQuadraticCurve.h + yOffset) / pageWrapY) + 1);\n          break;\n\n        case \"bct\":\n          var rectOfBezierCurve = getBezierCurveBoundary(this.ctx.lastPoint.x, this.ctx.lastPoint.y, path.x1, path.y1, path.x2, path.y2, path.x, path.y);\n          result.push(Math.floor((rectOfBezierCurve.y + yOffset) / pageWrapY) + 1);\n          result.push(Math.floor((rectOfBezierCurve.y + rectOfBezierCurve.h + yOffset) / pageWrapY) + 1);\n          break;\n\n        case \"rect\":\n          result.push(Math.floor((path.y + yOffset) / pageWrapY) + 1);\n          result.push(Math.floor((path.y + path.h + yOffset) / pageWrapY) + 1);\n      }\n\n      for (var i = 0; i < result.length; i += 1) {\n        while (this.pdf.internal.getNumberOfPages() < result[i]) {\n          addPage.call(this);\n        }\n      }\n\n      return result;\n    };\n\n    var addPage = function addPage() {\n      var fillStyle = this.fillStyle;\n      var strokeStyle = this.strokeStyle;\n      var font = this.font;\n      var lineCap = this.lineCap;\n      var lineWidth = this.lineWidth;\n      var lineJoin = this.lineJoin;\n      this.pdf.addPage();\n      this.fillStyle = fillStyle;\n      this.strokeStyle = strokeStyle;\n      this.font = font;\n      this.lineCap = lineCap;\n      this.lineWidth = lineWidth;\n      this.lineJoin = lineJoin;\n    };\n\n    var pathPositionRedo = function pathPositionRedo(paths, x, y) {\n      for (var i = 0; i < paths.length; i++) {\n        switch (paths[i].type) {\n          case \"bct\":\n            paths[i].x2 += x;\n            paths[i].y2 += y;\n\n          case \"qct\":\n            paths[i].x1 += x;\n            paths[i].y1 += y;\n\n          case \"mt\":\n          case \"lt\":\n          case \"arc\":\n          default:\n            paths[i].x += x;\n            paths[i].y += y;\n        }\n      }\n\n      return paths;\n    };\n\n    var sortPages = function sortPages(pages) {\n      return pages.sort(function (a, b) {\n        return a - b;\n      });\n    };\n\n    var pathPreProcess = function pathPreProcess(rule, isClip) {\n      var fillStyle = this.fillStyle;\n      var strokeStyle = this.strokeStyle;\n      var lineCap = this.lineCap;\n      var oldLineWidth = this.lineWidth;\n      var lineWidth = Math.abs(oldLineWidth * this.ctx.transform.scaleX);\n      var lineJoin = this.lineJoin;\n      var origPath = JSON.parse(JSON.stringify(this.path));\n      var xPath = JSON.parse(JSON.stringify(this.path));\n      var clipPath;\n      var tmpPath;\n      var pages = [];\n\n      for (var i = 0; i < xPath.length; i++) {\n        if (typeof xPath[i].x !== \"undefined\") {\n          var page = getPagesByPath.call(this, xPath[i]);\n\n          for (var ii = 0; ii < page.length; ii += 1) {\n            if (pages.indexOf(page[ii]) === -1) {\n              pages.push(page[ii]);\n            }\n          }\n        }\n      }\n\n      for (var j = 0; j < pages.length; j++) {\n        while (this.pdf.internal.getNumberOfPages() < pages[j]) {\n          addPage.call(this);\n        }\n      }\n\n      sortPages(pages);\n\n      if (this.autoPaging) {\n        var min = pages[0];\n        var max = pages[pages.length - 1];\n\n        for (var k = min; k < max + 1; k++) {\n          this.pdf.setPage(k);\n          this.fillStyle = fillStyle;\n          this.strokeStyle = strokeStyle;\n          this.lineCap = lineCap;\n          this.lineWidth = lineWidth;\n          this.lineJoin = lineJoin;\n          var pageWidthMinusMargins = this.pdf.internal.pageSize.width - this.margin[3] - this.margin[1];\n          var topMargin = k === 1 ? this.posY + this.margin[0] : this.margin[0];\n          var firstPageHeight = this.pdf.internal.pageSize.height - this.posY - this.margin[0] - this.margin[2];\n          var pageHeightMinusMargins = this.pdf.internal.pageSize.height - this.margin[0] - this.margin[2];\n          var previousPageHeightSum = k === 1 ? 0 : firstPageHeight + (k - 2) * pageHeightMinusMargins;\n\n          if (this.ctx.clip_path.length !== 0) {\n            var tmpPaths = this.path;\n            clipPath = JSON.parse(JSON.stringify(this.ctx.clip_path));\n            this.path = pathPositionRedo(clipPath, this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset);\n            drawPaths.call(this, rule, true);\n            this.path = tmpPaths;\n          }\n\n          tmpPath = JSON.parse(JSON.stringify(origPath));\n          this.path = pathPositionRedo(tmpPath, this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset);\n\n          if (isClip === false || k === 0) {\n            var needsClipping = (k > min || k < max) && hasMargins.call(this);\n\n            if (needsClipping) {\n              this.pdf.saveGraphicsState();\n              this.pdf.rect(this.margin[3], this.margin[0], pageWidthMinusMargins, pageHeightMinusMargins, null).clip().discardPath();\n            }\n\n            drawPaths.call(this, rule, isClip);\n\n            if (needsClipping) {\n              this.pdf.restoreGraphicsState();\n            }\n          }\n\n          this.lineWidth = oldLineWidth;\n        }\n      } else {\n        this.lineWidth = lineWidth;\n        drawPaths.call(this, rule, isClip);\n        this.lineWidth = oldLineWidth;\n      }\n\n      this.path = origPath;\n    };\n    /**\n     * Processes the paths\n     *\n     * @function\n     * @param rule {String}\n     * @param isClip {Boolean}\n     * @private\n     * @ignore\n     */\n\n\n    var drawPaths = function drawPaths(rule, isClip) {\n      if (rule === \"stroke\" && !isClip && isStrokeTransparent.call(this)) {\n        return;\n      }\n\n      if (rule !== \"stroke\" && !isClip && isFillTransparent.call(this)) {\n        return;\n      }\n\n      var moves = []; //var alpha = (this.ctx.fillOpacity < 1) ? this.ctx.fillOpacity : this.ctx.globalAlpha;\n\n      var delta;\n      var xPath = this.path;\n\n      for (var i = 0; i < xPath.length; i++) {\n        var pt = xPath[i];\n\n        switch (pt.type) {\n          case \"begin\":\n            moves.push({\n              begin: true\n            });\n            break;\n\n          case \"close\":\n            moves.push({\n              close: true\n            });\n            break;\n\n          case \"mt\":\n            moves.push({\n              start: pt,\n              deltas: [],\n              abs: []\n            });\n            break;\n\n          case \"lt\":\n            var iii = moves.length;\n\n            if (xPath[i - 1] && !isNaN(xPath[i - 1].x)) {\n              delta = [pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];\n\n              if (iii > 0) {\n                for (iii; iii >= 0; iii--) {\n                  if (moves[iii - 1].close !== true && moves[iii - 1].begin !== true) {\n                    moves[iii - 1].deltas.push(delta);\n                    moves[iii - 1].abs.push(pt);\n                    break;\n                  }\n                }\n              }\n            }\n\n            break;\n\n          case \"bct\":\n            delta = [pt.x1 - xPath[i - 1].x, pt.y1 - xPath[i - 1].y, pt.x2 - xPath[i - 1].x, pt.y2 - xPath[i - 1].y, pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];\n            moves[moves.length - 1].deltas.push(delta);\n            break;\n\n          case \"qct\":\n            var x1 = xPath[i - 1].x + 2.0 / 3.0 * (pt.x1 - xPath[i - 1].x);\n            var y1 = xPath[i - 1].y + 2.0 / 3.0 * (pt.y1 - xPath[i - 1].y);\n            var x2 = pt.x + 2.0 / 3.0 * (pt.x1 - pt.x);\n            var y2 = pt.y + 2.0 / 3.0 * (pt.y1 - pt.y);\n            var x3 = pt.x;\n            var y3 = pt.y;\n            delta = [x1 - xPath[i - 1].x, y1 - xPath[i - 1].y, x2 - xPath[i - 1].x, y2 - xPath[i - 1].y, x3 - xPath[i - 1].x, y3 - xPath[i - 1].y];\n            moves[moves.length - 1].deltas.push(delta);\n            break;\n\n          case \"arc\":\n            moves.push({\n              deltas: [],\n              abs: [],\n              arc: true\n            });\n\n            if (Array.isArray(moves[moves.length - 1].abs)) {\n              moves[moves.length - 1].abs.push(pt);\n            }\n\n            break;\n        }\n      }\n\n      var style;\n\n      if (!isClip) {\n        if (rule === \"stroke\") {\n          style = \"stroke\";\n        } else {\n          style = \"fill\";\n        }\n      } else {\n        style = null;\n      }\n\n      var began = false;\n\n      for (var k = 0; k < moves.length; k++) {\n        if (moves[k].arc) {\n          var arcs = moves[k].abs;\n\n          for (var ii = 0; ii < arcs.length; ii++) {\n            var arc = arcs[ii];\n\n            if (arc.type === \"arc\") {\n              drawArc.call(this, arc.x, arc.y, arc.radius, arc.startAngle, arc.endAngle, arc.counterclockwise, undefined, isClip, !began);\n            } else {\n              drawLine.call(this, arc.x, arc.y);\n            }\n\n            began = true;\n          }\n        } else if (moves[k].close === true) {\n          this.pdf.internal.out(\"h\");\n          began = false;\n        } else if (moves[k].begin !== true) {\n          var x = moves[k].start.x;\n          var y = moves[k].start.y;\n          drawLines.call(this, moves[k].deltas, x, y);\n          began = true;\n        }\n      }\n\n      if (style) {\n        putStyle.call(this, style);\n      }\n\n      if (isClip) {\n        doClip.call(this);\n      }\n    };\n\n    var getBaseline = function getBaseline(y) {\n      var height = this.pdf.internal.getFontSize() / this.pdf.internal.scaleFactor;\n      var descent = height * (this.pdf.internal.getLineHeightFactor() - 1);\n\n      switch (this.ctx.textBaseline) {\n        case \"bottom\":\n          return y - descent;\n\n        case \"top\":\n          return y + height - descent;\n\n        case \"hanging\":\n          return y + height - 2 * descent;\n\n        case \"middle\":\n          return y + height / 2 - descent;\n\n        case \"ideographic\":\n          // TODO not implemented\n          return y;\n\n        case \"alphabetic\":\n        default:\n          return y;\n      }\n    };\n\n    var getTextBottom = function getTextBottom(yBaseLine) {\n      var height = this.pdf.internal.getFontSize() / this.pdf.internal.scaleFactor;\n      var descent = height * (this.pdf.internal.getLineHeightFactor() - 1);\n      return yBaseLine + descent;\n    };\n\n    Context2D.prototype.createLinearGradient = function createLinearGradient() {\n      var canvasGradient = function canvasGradient() {};\n\n      canvasGradient.colorStops = [];\n\n      canvasGradient.addColorStop = function (offset, color) {\n        this.colorStops.push([offset, color]);\n      };\n\n      canvasGradient.getColor = function () {\n        if (this.colorStops.length === 0) {\n          return \"#000000\";\n        }\n\n        return this.colorStops[0][1];\n      };\n\n      canvasGradient.isCanvasGradient = true;\n      return canvasGradient;\n    };\n\n    Context2D.prototype.createPattern = function createPattern() {\n      return this.createLinearGradient();\n    };\n\n    Context2D.prototype.createRadialGradient = function createRadialGradient() {\n      return this.createLinearGradient();\n    };\n    /**\n     *\n     * @param x Edge point X\n     * @param y Edge point Y\n     * @param r Radius\n     * @param a1 start angle\n     * @param a2 end angle\n     * @param counterclockwise\n     * @param style\n     * @param isClip\n     */\n\n\n    var drawArc = function drawArc(x, y, r, a1, a2, counterclockwise, style, isClip, includeMove) {\n      // http://hansmuller-flex.blogspot.com/2011/10/more-about-approximating-circular-arcs.html\n      var curves = createArc.call(this, r, a1, a2, counterclockwise);\n\n      for (var i = 0; i < curves.length; i++) {\n        var curve = curves[i];\n\n        if (i === 0) {\n          if (includeMove) {\n            doMove.call(this, curve.x1 + x, curve.y1 + y);\n          } else {\n            drawLine.call(this, curve.x1 + x, curve.y1 + y);\n          }\n        }\n\n        drawCurve.call(this, x, y, curve.x2, curve.y2, curve.x3, curve.y3, curve.x4, curve.y4);\n      }\n\n      if (!isClip) {\n        putStyle.call(this, style);\n      } else {\n        doClip.call(this);\n      }\n    };\n\n    var putStyle = function putStyle(style) {\n      switch (style) {\n        case \"stroke\":\n          this.pdf.internal.out(\"S\");\n          break;\n\n        case \"fill\":\n          this.pdf.internal.out(\"f\");\n          break;\n      }\n    };\n\n    var doClip = function doClip() {\n      this.pdf.clip();\n      this.pdf.discardPath();\n    };\n\n    var doMove = function doMove(x, y) {\n      this.pdf.internal.out(getHorizontalCoordinateString(x) + \" \" + getVerticalCoordinateString(y) + \" m\");\n    };\n\n    var putText = function putText(options) {\n      var textAlign;\n\n      switch (options.align) {\n        case \"right\":\n        case \"end\":\n          textAlign = \"right\";\n          break;\n\n        case \"center\":\n          textAlign = \"center\";\n          break;\n\n        case \"left\":\n        case \"start\":\n        default:\n          textAlign = \"left\";\n          break;\n      }\n\n      var textDimensions = this.pdf.getTextDimensions(options.text);\n      var yBaseLine = getBaseline.call(this, options.y);\n      var yBottom = getTextBottom.call(this, yBaseLine);\n      var yTop = yBottom - textDimensions.h;\n      var pt = this.ctx.transform.applyToPoint(new Point(options.x, yBaseLine));\n      var decomposedTransformationMatrix = this.ctx.transform.decompose();\n      var matrix = new Matrix();\n      matrix = matrix.multiply(decomposedTransformationMatrix.translate);\n      matrix = matrix.multiply(decomposedTransformationMatrix.skew);\n      matrix = matrix.multiply(decomposedTransformationMatrix.scale);\n      var baselineRect = this.ctx.transform.applyToRectangle(new Rectangle(options.x, yBaseLine, textDimensions.w, textDimensions.h));\n      var textBounds = matrix.applyToRectangle(new Rectangle(options.x, yTop, textDimensions.w, textDimensions.h));\n      var pageArray = getPagesByPath.call(this, textBounds);\n      var pages = [];\n\n      for (var ii = 0; ii < pageArray.length; ii += 1) {\n        if (pages.indexOf(pageArray[ii]) === -1) {\n          pages.push(pageArray[ii]);\n        }\n      }\n\n      sortPages(pages);\n      var clipPath, oldSize, oldLineWidth;\n\n      if (this.autoPaging) {\n        var min = pages[0];\n        var max = pages[pages.length - 1];\n\n        for (var i = min; i < max + 1; i++) {\n          this.pdf.setPage(i);\n          var topMargin = i === 1 ? this.posY + this.margin[0] : this.margin[0];\n          var firstPageHeight = this.pdf.internal.pageSize.height - this.posY - this.margin[0] - this.margin[2];\n          var pageHeightMinusBottomMargin = this.pdf.internal.pageSize.height - this.margin[2];\n          var pageHeightMinusMargins = pageHeightMinusBottomMargin - this.margin[0];\n          var pageWidthMinusRightMargin = this.pdf.internal.pageSize.width - this.margin[1];\n          var pageWidthMinusMargins = pageWidthMinusRightMargin - this.margin[3];\n          var previousPageHeightSum = i === 1 ? 0 : firstPageHeight + (i - 2) * pageHeightMinusMargins;\n\n          if (this.ctx.clip_path.length !== 0) {\n            var tmpPaths = this.path;\n            clipPath = JSON.parse(JSON.stringify(this.ctx.clip_path));\n            this.path = pathPositionRedo(clipPath, this.posX + this.margin[3], -1 * previousPageHeightSum + topMargin);\n            drawPaths.call(this, \"fill\", true);\n            this.path = tmpPaths;\n          }\n\n          var textBoundsOnPage = pathPositionRedo([JSON.parse(JSON.stringify(textBounds))], this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset)[0];\n\n          if (options.scale >= 0.01) {\n            oldSize = this.pdf.internal.getFontSize();\n            this.pdf.setFontSize(oldSize * options.scale);\n            oldLineWidth = this.lineWidth;\n            this.lineWidth = oldLineWidth * options.scale;\n          }\n\n          var doSlice = this.autoPaging !== \"text\";\n\n          if (doSlice || textBoundsOnPage.y + textBoundsOnPage.h <= pageHeightMinusBottomMargin) {\n            if (doSlice || textBoundsOnPage.y >= topMargin && textBoundsOnPage.x <= pageWidthMinusRightMargin) {\n              var croppedText = doSlice ? options.text : this.pdf.splitTextToSize(options.text, options.maxWidth || pageWidthMinusRightMargin - textBoundsOnPage.x)[0];\n              var baseLineRectOnPage = pathPositionRedo([JSON.parse(JSON.stringify(baselineRect))], this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset)[0];\n              var needsClipping = doSlice && (i > min || i < max) && hasMargins.call(this);\n\n              if (needsClipping) {\n                this.pdf.saveGraphicsState();\n                this.pdf.rect(this.margin[3], this.margin[0], pageWidthMinusMargins, pageHeightMinusMargins, null).clip().discardPath();\n              }\n\n              this.pdf.text(croppedText, baseLineRectOnPage.x, baseLineRectOnPage.y, {\n                angle: options.angle,\n                align: textAlign,\n                renderingMode: options.renderingMode\n              });\n\n              if (needsClipping) {\n                this.pdf.restoreGraphicsState();\n              }\n            }\n          } else {\n            // This text is the last element of the page, but it got cut off due to the margin\n            // so we render it in the next page\n            if (textBoundsOnPage.y < pageHeightMinusBottomMargin) {\n              // As a result, all other elements have their y offset increased\n              this.ctx.prevPageLastElemOffset += pageHeightMinusBottomMargin - textBoundsOnPage.y;\n            }\n          }\n\n          if (options.scale >= 0.01) {\n            this.pdf.setFontSize(oldSize);\n            this.lineWidth = oldLineWidth;\n          }\n        }\n      } else {\n        if (options.scale >= 0.01) {\n          oldSize = this.pdf.internal.getFontSize();\n          this.pdf.setFontSize(oldSize * options.scale);\n          oldLineWidth = this.lineWidth;\n          this.lineWidth = oldLineWidth * options.scale;\n        }\n\n        this.pdf.text(options.text, pt.x + this.posX, pt.y + this.posY, {\n          angle: options.angle,\n          align: textAlign,\n          renderingMode: options.renderingMode,\n          maxWidth: options.maxWidth\n        });\n\n        if (options.scale >= 0.01) {\n          this.pdf.setFontSize(oldSize);\n          this.lineWidth = oldLineWidth;\n        }\n      }\n    };\n\n    var drawLine = function drawLine(x, y, prevX, prevY) {\n      prevX = prevX || 0;\n      prevY = prevY || 0;\n      this.pdf.internal.out(getHorizontalCoordinateString(x + prevX) + \" \" + getVerticalCoordinateString(y + prevY) + \" l\");\n    };\n\n    var drawLines = function drawLines(lines, x, y) {\n      return this.pdf.lines(lines, x, y, null, null);\n    };\n\n    var drawCurve = function drawCurve(x, y, x1, y1, x2, y2, x3, y3) {\n      this.pdf.internal.out([f2(getHorizontalCoordinate(x1 + x)), f2(getVerticalCoordinate(y1 + y)), f2(getHorizontalCoordinate(x2 + x)), f2(getVerticalCoordinate(y2 + y)), f2(getHorizontalCoordinate(x3 + x)), f2(getVerticalCoordinate(y3 + y)), \"c\"].join(\" \"));\n    };\n    /**\n     * Return a array of objects that represent bezier curves which approximate the circular arc centered at the origin, from startAngle to endAngle (radians) with the specified radius.\n     *\n     * Each bezier curve is an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points.\n     * @function createArc\n     */\n\n\n    var createArc = function createArc(radius, startAngle, endAngle, anticlockwise) {\n      var EPSILON = 0.00001; // Roughly 1/1000th of a degree, see below\n\n      var twoPi = Math.PI * 2;\n      var halfPi = Math.PI / 2.0;\n\n      while (startAngle > endAngle) {\n        startAngle = startAngle - twoPi;\n      }\n\n      var totalAngle = Math.abs(endAngle - startAngle);\n\n      if (totalAngle < twoPi) {\n        if (anticlockwise) {\n          totalAngle = twoPi - totalAngle;\n        }\n      } // Compute the sequence of arc curves, up to PI/2 at a time.\n\n\n      var curves = []; // clockwise or counterclockwise\n\n      var sgn = anticlockwise ? -1 : +1;\n      var a1 = startAngle;\n\n      for (; totalAngle > EPSILON;) {\n        var remain = sgn * Math.min(totalAngle, halfPi);\n        var a2 = a1 + remain;\n        curves.push(createSmallArc.call(this, radius, a1, a2));\n        totalAngle -= Math.abs(a2 - a1);\n        a1 = a2;\n      }\n\n      return curves;\n    };\n    /**\n     * Cubic bezier approximation of a circular arc centered at the origin, from (radians) a1 to a2, where a2-a1 < pi/2. The arc's radius is r.\n     *\n     * Returns an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points.\n     *\n     * This algorithm is based on the approach described in: A. Riškus, \"Approximation of a Cubic Bezier Curve by Circular Arcs and Vice Versa,\" Information Technology and Control, 35(4), 2006 pp. 371-378.\n     */\n\n\n    var createSmallArc = function createSmallArc(r, a1, a2) {\n      var a = (a2 - a1) / 2.0;\n      var x4 = r * Math.cos(a);\n      var y4 = r * Math.sin(a);\n      var x1 = x4;\n      var y1 = -y4;\n      var q1 = x1 * x1 + y1 * y1;\n      var q2 = q1 + x1 * x4 + y1 * y4;\n      var k2 = 4 / 3 * (Math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4);\n      var x2 = x1 - k2 * y1;\n      var y2 = y1 + k2 * x1;\n      var x3 = x2;\n      var y3 = -y2;\n      var ar = a + a1;\n      var cos_ar = Math.cos(ar);\n      var sin_ar = Math.sin(ar);\n      return {\n        x1: r * Math.cos(a1),\n        y1: r * Math.sin(a1),\n        x2: x2 * cos_ar - y2 * sin_ar,\n        y2: x2 * sin_ar + y2 * cos_ar,\n        x3: x3 * cos_ar - y3 * sin_ar,\n        y3: x3 * sin_ar + y3 * cos_ar,\n        x4: r * Math.cos(a2),\n        y4: r * Math.sin(a2)\n      };\n    };\n\n    var rad2deg = function rad2deg(value) {\n      return value * 180 / Math.PI;\n    };\n\n    var getQuadraticCurveBoundary = function getQuadraticCurveBoundary(sx, sy, cpx, cpy, ex, ey) {\n      var midX1 = sx + (cpx - sx) * 0.5;\n      var midY1 = sy + (cpy - sy) * 0.5;\n      var midX2 = ex + (cpx - ex) * 0.5;\n      var midY2 = ey + (cpy - ey) * 0.5;\n      var resultX1 = Math.min(sx, ex, midX1, midX2);\n      var resultX2 = Math.max(sx, ex, midX1, midX2);\n      var resultY1 = Math.min(sy, ey, midY1, midY2);\n      var resultY2 = Math.max(sy, ey, midY1, midY2);\n      return new Rectangle(resultX1, resultY1, resultX2 - resultX1, resultY2 - resultY1);\n    }; //De Casteljau algorithm\n\n\n    var getBezierCurveBoundary = function getBezierCurveBoundary(ax, ay, bx, by, cx, cy, dx, dy) {\n      var tobx = bx - ax;\n      var toby = by - ay;\n      var tocx = cx - bx;\n      var tocy = cy - by;\n      var todx = dx - cx;\n      var tody = dy - cy;\n      var precision = 40;\n      var d, i, px, py, qx, qy, rx, ry, tx, ty, sx, sy, x, y, minx, miny, maxx, maxy, toqx, toqy, torx, tory, totx, toty;\n\n      for (i = 0; i < precision + 1; i++) {\n        d = i / precision;\n        px = ax + d * tobx;\n        py = ay + d * toby;\n        qx = bx + d * tocx;\n        qy = by + d * tocy;\n        rx = cx + d * todx;\n        ry = cy + d * tody;\n        toqx = qx - px;\n        toqy = qy - py;\n        torx = rx - qx;\n        tory = ry - qy;\n        sx = px + d * toqx;\n        sy = py + d * toqy;\n        tx = qx + d * torx;\n        ty = qy + d * tory;\n        totx = tx - sx;\n        toty = ty - sy;\n        x = sx + d * totx;\n        y = sy + d * toty;\n\n        if (i == 0) {\n          minx = x;\n          miny = y;\n          maxx = x;\n          maxy = y;\n        } else {\n          minx = Math.min(minx, x);\n          miny = Math.min(miny, y);\n          maxx = Math.max(maxx, x);\n          maxy = Math.max(maxy, y);\n        }\n      }\n\n      return new Rectangle(Math.round(minx), Math.round(miny), Math.round(maxx - minx), Math.round(maxy - miny));\n    };\n\n    var getPrevLineDashValue = function getPrevLineDashValue(lineDash, lineDashOffset) {\n      return JSON.stringify({\n        lineDash: lineDash,\n        lineDashOffset: lineDashOffset\n      });\n    };\n\n    var setLineDash = function setLineDash() {\n      // Avoid unnecessary line dash declarations.\n      if (!this.prevLineDash && !this.ctx.lineDash.length && !this.ctx.lineDashOffset) {\n        return;\n      } // Avoid unnecessary line dash declarations.\n\n\n      var nextLineDash = getPrevLineDashValue(this.ctx.lineDash, this.ctx.lineDashOffset);\n\n      if (this.prevLineDash !== nextLineDash) {\n        this.pdf.setLineDash(this.ctx.lineDash, this.ctx.lineDashOffset);\n        this.prevLineDash = nextLineDash;\n      }\n    };\n  })(jsPDF.API);\n\n  // DEFLATE is a complex format; to read this code, you should probably check the RFC first:\n  // https://tools.ietf.org/html/rfc1951\n  // You may also wish to take a look at the guide I made about this program:\n  // https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad\n  // Much of the following code is similar to that of UZIP.js:\n  // https://github.com/photopea/UZIP.js\n  // Many optimizations have been made, so the bundle size is ultimately smaller but performance is similar.\n  // Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint\n  // is better for memory in most engines (I *think*).\n  // Mediocre shim\n  var Worker;\n\n  try {\n    Worker = require('worker_threads').Worker;\n  } catch (e) {}\n\n  var u8 = Uint8Array,\n      u16 = Uint16Array,\n      u32 = Uint32Array; // fixed length extra bits\n\n  var fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0,\n  /* unused */\n  0, 0,\n  /* impossible */\n  0]); // fixed distance extra bits\n  // see fleb note\n\n  var fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,\n  /* unused */\n  0, 0]); // code length index map\n\n  var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); // get base, reverse index map from extra bits\n\n  var freb = function (eb, start) {\n    var b = new u16(31);\n\n    for (var i = 0; i < 31; ++i) {\n      b[i] = start += 1 << eb[i - 1];\n    } // numbers here are at max 18 bits\n\n\n    var r = new u32(b[30]);\n\n    for (var i = 1; i < 30; ++i) {\n      for (var j = b[i]; j < b[i + 1]; ++j) {\n        r[j] = j - b[i] << 5 | i;\n      }\n    }\n\n    return [b, r];\n  };\n\n  var _a = freb(fleb, 2),\n      fl = _a[0],\n      revfl = _a[1]; // we can ignore the fact that the other numbers are wrong; they never happen anyway\n\n\n  fl[28] = 258, revfl[258] = 28;\n\n  var _b = freb(fdeb, 0),\n      fd = _b[0],\n      revfd = _b[1]; // map of value to reverse (assuming 16 bits)\n\n\n  var rev = new u16(32768);\n\n  for (var i = 0; i < 32768; ++i) {\n    // reverse table algorithm from SO\n    var x = (i & 0xAAAA) >>> 1 | (i & 0x5555) << 1;\n    x = (x & 0xCCCC) >>> 2 | (x & 0x3333) << 2;\n    x = (x & 0xF0F0) >>> 4 | (x & 0x0F0F) << 4;\n    rev[i] = ((x & 0xFF00) >>> 8 | (x & 0x00FF) << 8) >>> 1;\n  } // create huffman tree from u8 \"map\": index -> code length for code index\n  // mb (max bits) must be at most 15\n  // TODO: optimize/split up?\n\n\n  var hMap = function (cd, mb, r) {\n    var s = cd.length; // index\n\n    var i = 0; // u16 \"map\": index -> # of codes with bit length = index\n\n    var l = new u16(mb); // length of cd must be 288 (total # of codes)\n\n    for (; i < s; ++i) ++l[cd[i] - 1]; // u16 \"map\": index -> minimum code for bit length = index\n\n\n    var le = new u16(mb);\n\n    for (i = 0; i < mb; ++i) {\n      le[i] = le[i - 1] + l[i - 1] << 1;\n    }\n\n    var co;\n\n    if (r) {\n      // u16 \"map\": index -> number of actual bits, symbol for code\n      co = new u16(1 << mb); // bits to remove for reverser\n\n      var rvb = 15 - mb;\n\n      for (i = 0; i < s; ++i) {\n        // ignore 0 lengths\n        if (cd[i]) {\n          // num encoding both symbol and bits read\n          var sv = i << 4 | cd[i]; // free bits\n\n          var r_1 = mb - cd[i]; // start value\n\n          var v = le[cd[i] - 1]++ << r_1; // m is end value\n\n          for (var m = v | (1 << r_1) - 1; v <= m; ++v) {\n            // every 16 bit value starting with the code yields the same result\n            co[rev[v] >>> rvb] = sv;\n          }\n        }\n      }\n    } else {\n      co = new u16(s);\n\n      for (i = 0; i < s; ++i) co[i] = rev[le[cd[i] - 1]++] >>> 15 - cd[i];\n    }\n\n    return co;\n  }; // fixed length tree\n\n\n  var flt = new u8(288);\n\n  for (var i = 0; i < 144; ++i) flt[i] = 8;\n\n  for (var i = 144; i < 256; ++i) flt[i] = 9;\n\n  for (var i = 256; i < 280; ++i) flt[i] = 7;\n\n  for (var i = 280; i < 288; ++i) flt[i] = 8; // fixed distance tree\n\n\n  var fdt = new u8(32);\n\n  for (var i = 0; i < 32; ++i) fdt[i] = 5; // fixed length map\n\n\n  var flm = /*#__PURE__*/hMap(flt, 9, 0),\n      flrm = /*#__PURE__*/hMap(flt, 9, 1); // fixed distance map\n\n  var fdm = /*#__PURE__*/hMap(fdt, 5, 0),\n      fdrm = /*#__PURE__*/hMap(fdt, 5, 1); // find max of array\n\n  var max = function (a) {\n    var m = a[0];\n\n    for (var i = 1; i < a.length; ++i) {\n      if (a[i] > m) m = a[i];\n    }\n\n    return m;\n  }; // read d, starting at bit p and mask with m\n\n\n  var bits = function (d, p, m) {\n    var o = p / 8 >> 0;\n    return (d[o] | d[o + 1] << 8) >>> (p & 7) & m;\n  }; // read d, starting at bit p continuing for at least 16 bits\n\n\n  var bits16 = function (d, p) {\n    var o = p / 8 >> 0;\n    return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >>> (p & 7);\n  }; // get end of byte\n\n\n  var shft = function (p) {\n    return (p / 8 >> 0) + (p & 7 && 1);\n  }; // typed array slice - allows garbage collector to free original reference,\n  // while being more compatible than .slice\n\n\n  var slc = function (v, s, e) {\n    if (s == null || s < 0) s = 0;\n    if (e == null || e > v.length) e = v.length; // can't use .constructor in case user-supplied\n\n    var n = new (v instanceof u16 ? u16 : v instanceof u32 ? u32 : u8)(e - s);\n    n.set(v.subarray(s, e));\n    return n;\n  }; // expands raw DEFLATE data\n\n\n  var inflt = function (dat, buf, st) {\n    // source length\n    var sl = dat.length; // have to estimate size\n\n    var noBuf = !buf || st; // no state\n\n    var noSt = !st || st.i;\n    if (!st) st = {}; // Assumes roughly 33% compression ratio average\n\n    if (!buf) buf = new u8(sl * 3); // ensure buffer can fit at least l elements\n\n    var cbuf = function (l) {\n      var bl = buf.length; // need to increase size to fit\n\n      if (l > bl) {\n        // Double or set to necessary, whichever is greater\n        var nbuf = new u8(Math.max(bl * 2, l));\n        nbuf.set(buf);\n        buf = nbuf;\n      }\n    }; //  last chunk         bitpos           bytes\n\n\n    var final = st.f || 0,\n        pos = st.p || 0,\n        bt = st.b || 0,\n        lm = st.l,\n        dm = st.d,\n        lbt = st.m,\n        dbt = st.n; // total bits\n\n    var tbts = sl * 8;\n\n    do {\n      if (!lm) {\n        // BFINAL - this is only 1 when last chunk is next\n        st.f = final = bits(dat, pos, 1); // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman\n\n        var type = bits(dat, pos + 1, 3);\n        pos += 3;\n\n        if (!type) {\n          // go to end of byte boundary\n          var s = shft(pos) + 4,\n              l = dat[s - 4] | dat[s - 3] << 8,\n              t = s + l;\n\n          if (t > sl) {\n            if (noSt) throw 'unexpected EOF';\n            break;\n          } // ensure size\n\n\n          if (noBuf) cbuf(bt + l); // Copy over uncompressed data\n\n          buf.set(dat.subarray(s, t), bt); // Get new bitpos, update byte count\n\n          st.b = bt += l, st.p = pos = t * 8;\n          continue;\n        } else if (type == 1) lm = flrm, dm = fdrm, lbt = 9, dbt = 5;else if (type == 2) {\n          //  literal                            lengths\n          var hLit = bits(dat, pos, 31) + 257,\n              hcLen = bits(dat, pos + 10, 15) + 4;\n          var tl = hLit + bits(dat, pos + 5, 31) + 1;\n          pos += 14; // length+distance tree\n\n          var ldt = new u8(tl); // code length tree\n\n          var clt = new u8(19);\n\n          for (var i = 0; i < hcLen; ++i) {\n            // use index map to get real code\n            clt[clim[i]] = bits(dat, pos + i * 3, 7);\n          }\n\n          pos += hcLen * 3; // code lengths bits\n\n          var clb = max(clt),\n              clbmsk = (1 << clb) - 1;\n          if (!noSt && pos + tl * (clb + 7) > tbts) break; // code lengths map\n\n          var clm = hMap(clt, clb, 1);\n\n          for (var i = 0; i < tl;) {\n            var r = clm[bits(dat, pos, clbmsk)]; // bits read\n\n            pos += r & 15; // symbol\n\n            var s = r >>> 4; // code length to copy\n\n            if (s < 16) {\n              ldt[i++] = s;\n            } else {\n              //  copy   count\n              var c = 0,\n                  n = 0;\n              if (s == 16) n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];else if (s == 17) n = 3 + bits(dat, pos, 7), pos += 3;else if (s == 18) n = 11 + bits(dat, pos, 127), pos += 7;\n\n              while (n--) ldt[i++] = c;\n            }\n          } //    length tree                 distance tree\n\n\n          var lt = ldt.subarray(0, hLit),\n              dt = ldt.subarray(hLit); // max length bits\n\n          lbt = max(lt); // max dist bits\n\n          dbt = max(dt);\n          lm = hMap(lt, lbt, 1);\n          dm = hMap(dt, dbt, 1);\n        } else throw 'invalid block type';\n\n        if (pos > tbts) throw 'unexpected EOF';\n      } // Make sure the buffer can hold this + the largest possible addition\n      // Maximum chunk size (practically, theoretically infinite) is 2^17;\n\n\n      if (noBuf) cbuf(bt + 131072);\n      var lms = (1 << lbt) - 1,\n          dms = (1 << dbt) - 1;\n      var mxa = lbt + dbt + 18;\n\n      while (noSt || pos + mxa < tbts) {\n        // bits read, code\n        var c = lm[bits16(dat, pos) & lms],\n            sym = c >>> 4;\n        pos += c & 15;\n        if (pos > tbts) throw 'unexpected EOF';\n        if (!c) throw 'invalid length/literal';\n        if (sym < 256) buf[bt++] = sym;else if (sym == 256) {\n          lm = null;\n          break;\n        } else {\n          var add = sym - 254; // no extra bits needed if less\n\n          if (sym > 264) {\n            // index\n            var i = sym - 257,\n                b = fleb[i];\n            add = bits(dat, pos, (1 << b) - 1) + fl[i];\n            pos += b;\n          } // dist\n\n\n          var d = dm[bits16(dat, pos) & dms],\n              dsym = d >>> 4;\n          if (!d) throw 'invalid distance';\n          pos += d & 15;\n          var dt = fd[dsym];\n\n          if (dsym > 3) {\n            var b = fdeb[dsym];\n            dt += bits16(dat, pos) & (1 << b) - 1, pos += b;\n          }\n\n          if (pos > tbts) throw 'unexpected EOF';\n          if (noBuf) cbuf(bt + 131072);\n          var end = bt + add;\n\n          for (; bt < end; bt += 4) {\n            buf[bt] = buf[bt - dt];\n            buf[bt + 1] = buf[bt + 1 - dt];\n            buf[bt + 2] = buf[bt + 2 - dt];\n            buf[bt + 3] = buf[bt + 3 - dt];\n          }\n\n          bt = end;\n        }\n      }\n\n      st.l = lm, st.p = pos, st.b = bt;\n      if (lm) final = 1, st.m = lbt, st.d = dm, st.n = dbt;\n    } while (!final);\n\n    return bt == buf.length ? buf : slc(buf, 0, bt);\n  }; // starting at p, write the minimum number of bits that can hold v to d\n\n\n  var wbits = function (d, p, v) {\n    v <<= p & 7;\n    var o = p / 8 >> 0;\n    d[o] |= v;\n    d[o + 1] |= v >>> 8;\n  }; // starting at p, write the minimum number of bits (>8) that can hold v to d\n\n\n  var wbits16 = function (d, p, v) {\n    v <<= p & 7;\n    var o = p / 8 >> 0;\n    d[o] |= v;\n    d[o + 1] |= v >>> 8;\n    d[o + 2] |= v >>> 16;\n  }; // creates code lengths from a frequency table\n\n\n  var hTree = function (d, mb) {\n    // Need extra info to make a tree\n    var t = [];\n\n    for (var i = 0; i < d.length; ++i) {\n      if (d[i]) t.push({\n        s: i,\n        f: d[i]\n      });\n    }\n\n    var s = t.length;\n    var t2 = t.slice();\n    if (!s) return [new u8(0), 0];\n\n    if (s == 1) {\n      var v = new u8(t[0].s + 1);\n      v[t[0].s] = 1;\n      return [v, 1];\n    }\n\n    t.sort(function (a, b) {\n      return a.f - b.f;\n    }); // after i2 reaches last ind, will be stopped\n    // freq must be greater than largest possible number of symbols\n\n    t.push({\n      s: -1,\n      f: 25001\n    });\n    var l = t[0],\n        r = t[1],\n        i0 = 0,\n        i1 = 1,\n        i2 = 2;\n    t[0] = {\n      s: -1,\n      f: l.f + r.f,\n      l: l,\n      r: r\n    }; // efficient algorithm from UZIP.js\n    // i0 is lookbehind, i2 is lookahead - after processing two low-freq\n    // symbols that combined have high freq, will start processing i2 (high-freq,\n    // non-composite) symbols instead\n    // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/\n\n    while (i1 != s - 1) {\n      l = t[t[i0].f < t[i2].f ? i0++ : i2++];\n      r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];\n      t[i1++] = {\n        s: -1,\n        f: l.f + r.f,\n        l: l,\n        r: r\n      };\n    }\n\n    var maxSym = t2[0].s;\n\n    for (var i = 1; i < s; ++i) {\n      if (t2[i].s > maxSym) maxSym = t2[i].s;\n    } // code lengths\n\n\n    var tr = new u16(maxSym + 1); // max bits in tree\n\n    var mbt = ln(t[i1 - 1], tr, 0);\n\n    if (mbt > mb) {\n      // more algorithms from UZIP.js\n      // TODO: find out how this code works (debt)\n      //  ind    debt\n      var i = 0,\n          dt = 0; //    left            cost\n\n      var lft = mbt - mb,\n          cst = 1 << lft;\n      t2.sort(function (a, b) {\n        return tr[b.s] - tr[a.s] || a.f - b.f;\n      });\n\n      for (; i < s; ++i) {\n        var i2_1 = t2[i].s;\n\n        if (tr[i2_1] > mb) {\n          dt += cst - (1 << mbt - tr[i2_1]);\n          tr[i2_1] = mb;\n        } else break;\n      }\n\n      dt >>>= lft;\n\n      while (dt > 0) {\n        var i2_2 = t2[i].s;\n        if (tr[i2_2] < mb) dt -= 1 << mb - tr[i2_2]++ - 1;else ++i;\n      }\n\n      for (; i >= 0 && dt; --i) {\n        var i2_3 = t2[i].s;\n\n        if (tr[i2_3] == mb) {\n          --tr[i2_3];\n          ++dt;\n        }\n      }\n\n      mbt = mb;\n    }\n\n    return [new u8(tr), mbt];\n  }; // get the max length and assign length codes\n\n\n  var ln = function (n, l, d) {\n    return n.s == -1 ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1)) : l[n.s] = d;\n  }; // length codes generation\n\n\n  var lc = function (c) {\n    var s = c.length; // Note that the semicolon was intentional\n\n    while (s && !c[--s]);\n\n    var cl = new u16(++s); //  ind      num         streak\n\n    var cli = 0,\n        cln = c[0],\n        cls = 1;\n\n    var w = function (v) {\n      cl[cli++] = v;\n    };\n\n    for (var i = 1; i <= s; ++i) {\n      if (c[i] == cln && i != s) ++cls;else {\n        if (!cln && cls > 2) {\n          for (; cls > 138; cls -= 138) w(32754);\n\n          if (cls > 2) {\n            w(cls > 10 ? cls - 11 << 5 | 28690 : cls - 3 << 5 | 12305);\n            cls = 0;\n          }\n        } else if (cls > 3) {\n          w(cln), --cls;\n\n          for (; cls > 6; cls -= 6) w(8304);\n\n          if (cls > 2) w(cls - 3 << 5 | 8208), cls = 0;\n        }\n\n        while (cls--) w(cln);\n\n        cls = 1;\n        cln = c[i];\n      }\n    }\n\n    return [cl.subarray(0, cli), s];\n  }; // calculate the length of output from tree, code lengths\n\n\n  var clen = function (cf, cl) {\n    var l = 0;\n\n    for (var i = 0; i < cl.length; ++i) l += cf[i] * cl[i];\n\n    return l;\n  }; // writes a fixed block\n  // returns the new bit pos\n\n\n  var wfblk = function (out, pos, dat) {\n    // no need to write 00 as type: TypedArray defaults to 0\n    var s = dat.length;\n    var o = shft(pos + 2);\n    out[o] = s & 255;\n    out[o + 1] = s >>> 8;\n    out[o + 2] = out[o] ^ 255;\n    out[o + 3] = out[o + 1] ^ 255;\n\n    for (var i = 0; i < s; ++i) out[o + i + 4] = dat[i];\n\n    return (o + 4 + s) * 8;\n  }; // writes a block\n\n\n  var wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) {\n    wbits(out, p++, final);\n    ++lf[256];\n\n    var _a = hTree(lf, 15),\n        dlt = _a[0],\n        mlb = _a[1];\n\n    var _b = hTree(df, 15),\n        ddt = _b[0],\n        mdb = _b[1];\n\n    var _c = lc(dlt),\n        lclt = _c[0],\n        nlc = _c[1];\n\n    var _d = lc(ddt),\n        lcdt = _d[0],\n        ndc = _d[1];\n\n    var lcfreq = new u16(19);\n\n    for (var i = 0; i < lclt.length; ++i) lcfreq[lclt[i] & 31]++;\n\n    for (var i = 0; i < lcdt.length; ++i) lcfreq[lcdt[i] & 31]++;\n\n    var _e = hTree(lcfreq, 7),\n        lct = _e[0],\n        mlcb = _e[1];\n\n    var nlcc = 19;\n\n    for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc);\n\n    var flen = bl + 5 << 3;\n    var ftlen = clen(lf, flt) + clen(df, fdt) + eb;\n    var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + (2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18]);\n    if (flen <= ftlen && flen <= dtlen) return wfblk(out, p, dat.subarray(bs, bs + bl));\n    var lm, ll, dm, dl;\n    wbits(out, p, 1 + (dtlen < ftlen)), p += 2;\n\n    if (dtlen < ftlen) {\n      lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;\n      var llm = hMap(lct, mlcb, 0);\n      wbits(out, p, nlc - 257);\n      wbits(out, p + 5, ndc - 1);\n      wbits(out, p + 10, nlcc - 4);\n      p += 14;\n\n      for (var i = 0; i < nlcc; ++i) wbits(out, p + 3 * i, lct[clim[i]]);\n\n      p += 3 * nlcc;\n      var lcts = [lclt, lcdt];\n\n      for (var it = 0; it < 2; ++it) {\n        var clct = lcts[it];\n\n        for (var i = 0; i < clct.length; ++i) {\n          var len = clct[i] & 31;\n          wbits(out, p, llm[len]), p += lct[len];\n          if (len > 15) wbits(out, p, clct[i] >>> 5 & 127), p += clct[i] >>> 12;\n        }\n      }\n    } else {\n      lm = flm, ll = flt, dm = fdm, dl = fdt;\n    }\n\n    for (var i = 0; i < li; ++i) {\n      if (syms[i] > 255) {\n        var len = syms[i] >>> 18 & 31;\n        wbits16(out, p, lm[len + 257]), p += ll[len + 257];\n        if (len > 7) wbits(out, p, syms[i] >>> 23 & 31), p += fleb[len];\n        var dst = syms[i] & 31;\n        wbits16(out, p, dm[dst]), p += dl[dst];\n        if (dst > 3) wbits16(out, p, syms[i] >>> 5 & 8191), p += fdeb[dst];\n      } else {\n        wbits16(out, p, lm[syms[i]]), p += ll[syms[i]];\n      }\n    }\n\n    wbits16(out, p, lm[256]);\n    return p + ll[256];\n  }; // deflate options (nice << 13) | chain\n\n\n  var deo = /*#__PURE__*/new u32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]); // empty\n\n  var et = /*#__PURE__*/new u8(0); // compresses data into a raw DEFLATE buffer\n\n  var dflt = function (dat, lvl, plvl, pre, post, lst) {\n    var s = dat.length;\n    var o = new u8(pre + s + 5 * (1 + Math.floor(s / 7000)) + post); // writing to this writes to the output buffer\n\n    var w = o.subarray(pre, o.length - post);\n    var pos = 0;\n\n    if (!lvl || s < 8) {\n      for (var i = 0; i <= s; i += 65535) {\n        // end\n        var e = i + 65535;\n\n        if (e < s) {\n          // write full block\n          pos = wfblk(w, pos, dat.subarray(i, e));\n        } else {\n          // write final block\n          w[i] = lst;\n          pos = wfblk(w, pos, dat.subarray(i, s));\n        }\n      }\n    } else {\n      var opt = deo[lvl - 1];\n      var n = opt >>> 13,\n          c = opt & 8191;\n      var msk_1 = (1 << plvl) - 1; //    prev 2-byte val map    curr 2-byte val map\n\n      var prev = new u16(32768),\n          head = new u16(msk_1 + 1);\n      var bs1_1 = Math.ceil(plvl / 3),\n          bs2_1 = 2 * bs1_1;\n\n      var hsh = function (i) {\n        return (dat[i] ^ dat[i + 1] << bs1_1 ^ dat[i + 2] << bs2_1) & msk_1;\n      }; // 24576 is an arbitrary number of maximum symbols per block\n      // 424 buffer for last block\n\n\n      var syms = new u32(25000); // length/literal freq   distance freq\n\n      var lf = new u16(288),\n          df = new u16(32); //  l/lcnt  exbits  index  l/lind  waitdx  bitpos\n\n      var lc_1 = 0,\n          eb = 0,\n          i = 0,\n          li = 0,\n          wi = 0,\n          bs = 0;\n\n      for (; i < s; ++i) {\n        // hash value\n        var hv = hsh(i); // index mod 32768\n\n        var imod = i & 32767; // previous index with this value\n\n        var pimod = head[hv];\n        prev[imod] = pimod;\n        head[hv] = imod; // We always should modify head and prev, but only add symbols if\n        // this data is not yet processed (\"wait\" for wait index)\n\n        if (wi <= i) {\n          // bytes remaining\n          var rem = s - i;\n\n          if ((lc_1 > 7000 || li > 24576) && rem > 423) {\n            pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);\n            li = lc_1 = eb = 0, bs = i;\n\n            for (var j = 0; j < 286; ++j) lf[j] = 0;\n\n            for (var j = 0; j < 30; ++j) df[j] = 0;\n          } //  len    dist   chain\n\n\n          var l = 2,\n              d = 0,\n              ch_1 = c,\n              dif = imod - pimod & 32767;\n\n          if (rem > 2 && hv == hsh(i - dif)) {\n            var maxn = Math.min(n, rem) - 1;\n            var maxd = Math.min(32767, i); // max possible length\n            // not capped at dif because decompressors implement \"rolling\" index population\n\n            var ml = Math.min(258, rem);\n\n            while (dif <= maxd && --ch_1 && imod != pimod) {\n              if (dat[i + l] == dat[i + l - dif]) {\n                var nl = 0;\n\n                for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl);\n\n                if (nl > l) {\n                  l = nl, d = dif; // break out early when we reach \"nice\" (we are satisfied enough)\n\n                  if (nl > maxn) break; // now, find the rarest 2-byte sequence within this\n                  // length of literals and search for that instead.\n                  // Much faster than just using the start\n\n                  var mmd = Math.min(dif, nl - 2);\n                  var md = 0;\n\n                  for (var j = 0; j < mmd; ++j) {\n                    var ti = i - dif + j + 32768 & 32767;\n                    var pti = prev[ti];\n                    var cd = ti - pti + 32768 & 32767;\n                    if (cd > md) md = cd, pimod = ti;\n                  }\n                }\n              } // check the previous match\n\n\n              imod = pimod, pimod = prev[imod];\n              dif += imod - pimod + 32768 & 32767;\n            }\n          } // d will be nonzero only when a match was found\n\n\n          if (d) {\n            // store both dist and len data in one Uint32\n            // Make sure this is recognized as a len/dist with 28th bit (2^28)\n            syms[li++] = 268435456 | revfl[l] << 18 | revfd[d];\n            var lin = revfl[l] & 31,\n                din = revfd[d] & 31;\n            eb += fleb[lin] + fdeb[din];\n            ++lf[257 + lin];\n            ++df[din];\n            wi = i + l;\n            ++lc_1;\n          } else {\n            syms[li++] = dat[i];\n            ++lf[dat[i]];\n          }\n        }\n      }\n\n      pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos); // this is the easiest way to avoid needing to maintain state\n\n      if (!lst) pos = wfblk(w, pos, et);\n    }\n\n    return slc(o, 0, pre + shft(pos) + post);\n  }; // CRC32 table\n\n\n  var adler = function () {\n    var a = 1,\n        b = 0;\n    return {\n      p: function (d) {\n        // closures have awful performance\n        var n = a,\n            m = b;\n        var l = d.length;\n\n        for (var i = 0; i != l;) {\n          var e = Math.min(i + 5552, l);\n\n          for (; i < e; ++i) n += d[i], m += n;\n\n          n %= 65521, m %= 65521;\n        }\n\n        a = n, b = m;\n      },\n      d: function () {\n        return (a >>> 8 << 16 | (b & 255) << 8 | b >>> 8) + ((a & 255) << 23) * 2;\n      }\n    };\n  };\n\n  var dopt = function (dat, opt, pre, post, st) {\n    return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 12 + opt.mem, pre, post, !st);\n  }; // Walmart object spread\n\n\n  var wbytes = function (d, b, v) {\n    for (; v; ++b) d[b] = v, v >>>= 8;\n  }; // gzip header\n\n\n  var zlh = function (c, o) {\n    var lv = o.level,\n        fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2;\n    c[0] = 120, c[1] = fl << 6 | (fl ? 32 - 2 * fl : 1);\n  }; // zlib valid\n\n\n  var zlv = function (d) {\n    if ((d[0] & 15) != 8 || d[0] >>> 4 > 7 || (d[0] << 8 | d[1]) % 31) throw 'invalid zlib data';\n    if (d[1] & 32) throw 'invalid zlib data: preset dictionaries not supported';\n  };\n  /**\n   * Compress data with Zlib\n   * @param data The data to compress\n   * @param opts The compression options\n   * @returns The zlib-compressed version of the data\n   */\n\n  function zlibSync(data, opts) {\n    if (opts === void 0) {\n      opts = {};\n    }\n\n    var a = adler();\n    a.p(data);\n    var d = dopt(data, opts, 2, 4);\n    return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d;\n  }\n  /**\n   * Expands Zlib data\n   * @param data The data to decompress\n   * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.\n   * @returns The decompressed version of the data\n   */\n\n  function unzlibSync(data, out) {\n    return inflt((zlv(data), data.subarray(2, -4)), out);\n  } // Default algorithm for compression (used because having a known output size allows faster decompression)\n\n  /**\n   * @license\n   * jsPDF filters PlugIn\n   * Copyright (c) 2014 Aras Abbasi\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n\n  (function (jsPDFAPI) {\n\n    var ASCII85Encode = function ASCII85Encode(a) {\n      var b, c, d, e, f, g, h, i, j, k; // eslint-disable-next-line no-control-regex\n\n      for (!/[^\\x00-\\xFF]/.test(a), b = \"\\x00\\x00\\x00\\x00\".slice(a.length % 4 || 4), a += b, c = [], d = 0, e = a.length; e > d; d += 4) {\n        f = (a.charCodeAt(d) << 24) + (a.charCodeAt(d + 1) << 16) + (a.charCodeAt(d + 2) << 8) + a.charCodeAt(d + 3), 0 !== f ? (k = f % 85, f = (f - k) / 85, j = f % 85, f = (f - j) / 85, i = f % 85, f = (f - i) / 85, h = f % 85, f = (f - h) / 85, g = f % 85, c.push(g + 33, h + 33, i + 33, j + 33, k + 33)) : c.push(122);\n      }\n\n      return function (a, b) {\n        for (var c = b; c > 0; c--) {\n          a.pop();\n        }\n      }(c, b.length), String.fromCharCode.apply(String, c) + \"~>\";\n    };\n\n    var ASCII85Decode = function ASCII85Decode(a) {\n      var c,\n          d,\n          e,\n          f,\n          g,\n          h = String,\n          l = \"length\",\n          w = 255,\n          x = \"charCodeAt\",\n          y = \"slice\",\n          z = \"replace\";\n\n      for (\"~>\" === a[y](-2), a = a[y](0, -2)[z](/\\s/g, \"\")[z](\"z\", \"!!!!!\"), c = \"uuuuu\"[y](a[l] % 5 || 5), a += c, e = [], f = 0, g = a[l]; g > f; f += 5) {\n        d = 52200625 * (a[x](f) - 33) + 614125 * (a[x](f + 1) - 33) + 7225 * (a[x](f + 2) - 33) + 85 * (a[x](f + 3) - 33) + (a[x](f + 4) - 33), e.push(w & d >> 24, w & d >> 16, w & d >> 8, w & d);\n      }\n\n      return function (a, b) {\n        for (var c = b; c > 0; c--) {\n          a.pop();\n        }\n      }(e, c[l]), h.fromCharCode.apply(h, e);\n    };\n\n    var ASCIIHexEncode = function ASCIIHexEncode(value) {\n      return value.split(\"\").map(function (value) {\n        return (\"0\" + value.charCodeAt().toString(16)).slice(-2);\n      }).join(\"\") + \">\";\n    };\n\n    var ASCIIHexDecode = function ASCIIHexDecode(value) {\n      var regexCheckIfHex = new RegExp(/^([0-9A-Fa-f]{2})+$/);\n      value = value.replace(/\\s/g, \"\");\n\n      if (value.indexOf(\">\") !== -1) {\n        value = value.substr(0, value.indexOf(\">\"));\n      }\n\n      if (value.length % 2) {\n        value += \"0\";\n      }\n\n      if (regexCheckIfHex.test(value) === false) {\n        return \"\";\n      }\n\n      var result = \"\";\n\n      for (var i = 0; i < value.length; i += 2) {\n        result += String.fromCharCode(\"0x\" + (value[i] + value[i + 1]));\n      }\n\n      return result;\n    };\n    /*\n    var FlatePredictors = {\n        None: 1,\n        TIFF: 2,\n        PNG_None: 10,\n        PNG_Sub: 11,\n        PNG_Up: 12,\n        PNG_Average: 13,\n        PNG_Paeth: 14,\n        PNG_Optimum: 15\n    };\n    */\n\n\n    var FlateEncode = function FlateEncode(data) {\n      var arr = new Uint8Array(data.length);\n      var i = data.length;\n\n      while (i--) {\n        arr[i] = data.charCodeAt(i);\n      }\n\n      arr = zlibSync(arr);\n      data = arr.reduce(function (data, byte) {\n        return data + String.fromCharCode(byte);\n      }, \"\");\n      return data;\n    };\n\n    jsPDFAPI.processDataByFilters = function (origData, filterChain) {\n\n      var i = 0;\n      var data = origData || \"\";\n      var reverseChain = [];\n      filterChain = filterChain || [];\n\n      if (typeof filterChain === \"string\") {\n        filterChain = [filterChain];\n      }\n\n      for (i = 0; i < filterChain.length; i += 1) {\n        switch (filterChain[i]) {\n          case \"ASCII85Decode\":\n          case \"/ASCII85Decode\":\n            data = ASCII85Decode(data);\n            reverseChain.push(\"/ASCII85Encode\");\n            break;\n\n          case \"ASCII85Encode\":\n          case \"/ASCII85Encode\":\n            data = ASCII85Encode(data);\n            reverseChain.push(\"/ASCII85Decode\");\n            break;\n\n          case \"ASCIIHexDecode\":\n          case \"/ASCIIHexDecode\":\n            data = ASCIIHexDecode(data);\n            reverseChain.push(\"/ASCIIHexEncode\");\n            break;\n\n          case \"ASCIIHexEncode\":\n          case \"/ASCIIHexEncode\":\n            data = ASCIIHexEncode(data);\n            reverseChain.push(\"/ASCIIHexDecode\");\n            break;\n\n          case \"FlateEncode\":\n          case \"/FlateEncode\":\n            data = FlateEncode(data);\n            reverseChain.push(\"/FlateDecode\");\n            break;\n\n          default:\n            throw new Error('The filter: \"' + filterChain[i] + '\" is not implemented');\n        }\n      }\n\n      return {\n        data: data,\n        reverseChain: reverseChain.reverse().join(\" \")\n      };\n    };\n  })(jsPDF.API);\n\n  /**\n   * @license\n   * jsPDF fileloading PlugIn\n   * Copyright (c) 2018 Aras Abbasi (aras.abbasi@gmail.com)\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n  /**\n   * @name fileloading\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n    /**\n     * @name loadFile\n     * @function\n     * @param {string} url\n     * @param {boolean} sync\n     * @param {function} callback\n     * @returns {string|undefined} result\n     */\n\n    jsPDFAPI.loadFile = function (url, sync, callback) {\n      return browserRequest(url, sync, callback);\n    };\n    /**\n     * @name loadImageFile\n     * @function\n     * @param {string} path\n     * @param {boolean} sync\n     * @param {function} callback\n     */\n\n\n    jsPDFAPI.loadImageFile = jsPDFAPI.loadFile;\n\n    function browserRequest(url, sync, callback) {\n      sync = sync === false ? false : true;\n      callback = typeof callback === \"function\" ? callback : function () {};\n      var result = undefined;\n\n      var xhr = function xhr(url, sync, callback) {\n        var request = new XMLHttpRequest();\n        var i = 0;\n\n        var sanitizeUnicode = function sanitizeUnicode(data) {\n          var dataLength = data.length;\n          var charArray = [];\n          var StringFromCharCode = String.fromCharCode; //Transform Unicode to ASCII\n\n          for (i = 0; i < dataLength; i += 1) {\n            charArray.push(StringFromCharCode(data.charCodeAt(i) & 0xff));\n          }\n\n          return charArray.join(\"\");\n        };\n\n        request.open(\"GET\", url, !sync); // XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]\n\n        request.overrideMimeType(\"text/plain; charset=x-user-defined\");\n\n        if (sync === false) {\n          request.onload = function () {\n            if (request.status === 200) {\n              callback(sanitizeUnicode(this.responseText));\n            } else {\n              callback(undefined);\n            }\n          };\n        }\n\n        request.send(null);\n\n        if (sync && request.status === 200) {\n          return sanitizeUnicode(request.responseText);\n        }\n      };\n\n      try {\n        result = xhr(url, sync, callback); // eslint-disable-next-line no-empty\n      } catch (e) {}\n\n      return result;\n    }\n  })(jsPDF.API);\n\n  /**\n   * jsPDF html PlugIn\n   *\n   * @name html\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n\n    function loadHtml2Canvas() {\n      return function () {\n        if (globalObject[\"html2canvas\"]) {\n          return Promise.resolve(globalObject[\"html2canvas\"]);\n        }\n\n        if ((typeof exports === \"undefined\" ? \"undefined\" : _typeof(exports)) === \"object\" && typeof module !== \"undefined\") {\n          return new Promise(function (resolve, reject) {\n            try {\n              resolve(require(\"html2canvas\"));\n            } catch (e) {\n              reject(e);\n            }\n          });\n        }\n\n        if (typeof define === \"function\" && define.amd) {\n          return new Promise(function (resolve, reject) {\n            try {\n              require([\"html2canvas\"], resolve);\n            } catch (e) {\n              reject(e);\n            }\n          });\n        }\n\n        return Promise.reject(new Error(\"Could not load html2canvas\"));\n      }().catch(function (e) {\n        return Promise.reject(new Error(\"Could not load html2canvas: \" + e));\n      }).then(function (html2canvas) {\n        return html2canvas.default ? html2canvas.default : html2canvas;\n      });\n    }\n\n    function loadDomPurify() {\n      return function () {\n        if (globalObject[\"DOMPurify\"]) {\n          return Promise.resolve(globalObject[\"DOMPurify\"]);\n        }\n\n        if ((typeof exports === \"undefined\" ? \"undefined\" : _typeof(exports)) === \"object\" && typeof module !== \"undefined\") {\n          return new Promise(function (resolve, reject) {\n            try {\n              resolve(require(\"dompurify\"));\n            } catch (e) {\n              reject(e);\n            }\n          });\n        }\n\n        if (typeof define === \"function\" && define.amd) {\n          return new Promise(function (resolve, reject) {\n            try {\n              require([\"dompurify\"], resolve);\n            } catch (e) {\n              reject(e);\n            }\n          });\n        }\n\n        return Promise.reject(new Error(\"Could not load dompurify\"));\n      }().catch(function (e) {\n        return Promise.reject(new Error(\"Could not load dompurify: \" + e));\n      }).then(function (dompurify) {\n        return dompurify.default ? dompurify.default : dompurify;\n      });\n    }\n    /**\n     * Determine the type of a variable/object.\n     *\n     * @private\n     * @ignore\n     */\n\n\n    var objType = function objType(obj) {\n      var type = _typeof(obj);\n\n      if (type === \"undefined\") return \"undefined\";else if (type === \"string\" || obj instanceof String) return \"string\";else if (type === \"number\" || obj instanceof Number) return \"number\";else if (type === \"function\" || obj instanceof Function) return \"function\";else if (!!obj && obj.constructor === Array) return \"array\";else if (obj && obj.nodeType === 1) return \"element\";else if (type === \"object\") return \"object\";else return \"unknown\";\n    };\n    /**\n     * Create an HTML element with optional className, innerHTML, and style.\n     *\n     * @private\n     * @ignore\n     */\n\n\n    var createElement = function createElement(tagName, opt) {\n      var el = document.createElement(tagName);\n      if (opt.className) el.className = opt.className;\n\n      if (opt.innerHTML && opt.dompurify) {\n        el.innerHTML = opt.dompurify.sanitize(opt.innerHTML);\n      }\n\n      for (var key in opt.style) {\n        el.style[key] = opt.style[key];\n      }\n\n      return el;\n    };\n    /**\n     * Deep-clone a node and preserve contents/properties.\n     *\n     * @private\n     * @ignore\n     */\n\n\n    var cloneNode = function cloneNode(node, javascriptEnabled) {\n      // Recursively clone the node.\n      var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);\n\n      for (var child = node.firstChild; child; child = child.nextSibling) {\n        if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== \"SCRIPT\") {\n          clone.appendChild(cloneNode(child, javascriptEnabled));\n        }\n      }\n\n      if (node.nodeType === 1) {\n        // Preserve contents/properties of special nodes.\n        if (node.nodeName === \"CANVAS\") {\n          clone.width = node.width;\n          clone.height = node.height;\n          clone.getContext(\"2d\").drawImage(node, 0, 0);\n        } else if (node.nodeName === \"TEXTAREA\" || node.nodeName === \"SELECT\") {\n          clone.value = node.value;\n        } // Preserve the node's scroll position when it loads.\n\n\n        clone.addEventListener(\"load\", function () {\n          clone.scrollTop = node.scrollTop;\n          clone.scrollLeft = node.scrollLeft;\n        }, true);\n      } // Return the cloned node.\n\n\n      return clone;\n    };\n    /* ----- CONSTRUCTOR ----- */\n\n\n    var Worker = function Worker(opt) {\n      // Create the root parent for the proto chain, and the starting Worker.\n      var root = Object.assign(Worker.convert(Promise.resolve()), JSON.parse(JSON.stringify(Worker.template)));\n      var self = Worker.convert(Promise.resolve(), root); // Set progress, optional settings, and return.\n\n      self = self.setProgress(1, Worker, 1, [Worker]);\n      self = self.set(opt);\n      return self;\n    }; // Boilerplate for subclassing Promise.\n\n\n    Worker.prototype = Object.create(Promise.prototype);\n    Worker.prototype.constructor = Worker; // Converts/casts promises into Workers.\n\n    Worker.convert = function convert(promise, inherit) {\n      // Uses prototypal inheritance to receive changes made to ancestors' properties.\n      promise.__proto__ = inherit || Worker.prototype;\n      return promise;\n    };\n\n    Worker.template = {\n      prop: {\n        src: null,\n        container: null,\n        overlay: null,\n        canvas: null,\n        img: null,\n        pdf: null,\n        pageSize: null,\n        callback: function callback() {}\n      },\n      progress: {\n        val: 0,\n        state: null,\n        n: 0,\n        stack: []\n      },\n      opt: {\n        filename: \"file.pdf\",\n        margin: [0, 0, 0, 0],\n        enableLinks: true,\n        x: 0,\n        y: 0,\n        html2canvas: {},\n        jsPDF: {},\n        backgroundColor: \"transparent\"\n      }\n    };\n    /* ----- FROM / TO ----- */\n\n    Worker.prototype.from = function from(src, type) {\n      function getType(src) {\n        switch (objType(src)) {\n          case \"string\":\n            return \"string\";\n\n          case \"element\":\n            return src.nodeName.toLowerCase() === \"canvas\" ? \"canvas\" : \"element\";\n\n          default:\n            return \"unknown\";\n        }\n      }\n\n      return this.then(function from_main() {\n        type = type || getType(src);\n\n        switch (type) {\n          case \"string\":\n            return this.then(loadDomPurify).then(function (dompurify) {\n              return this.set({\n                src: createElement(\"div\", {\n                  innerHTML: src,\n                  dompurify: dompurify\n                })\n              });\n            });\n\n          case \"element\":\n            return this.set({\n              src: src\n            });\n\n          case \"canvas\":\n            return this.set({\n              canvas: src\n            });\n\n          case \"img\":\n            return this.set({\n              img: src\n            });\n\n          default:\n            return this.error(\"Unknown source type.\");\n        }\n      });\n    };\n\n    Worker.prototype.to = function to(target) {\n      // Route the 'to' request to the appropriate method.\n      switch (target) {\n        case \"container\":\n          return this.toContainer();\n\n        case \"canvas\":\n          return this.toCanvas();\n\n        case \"img\":\n          return this.toImg();\n\n        case \"pdf\":\n          return this.toPdf();\n\n        default:\n          return this.error(\"Invalid target.\");\n      }\n    };\n\n    Worker.prototype.toContainer = function toContainer() {\n      // Set up function prerequisites.\n      var prereqs = [function checkSrc() {\n        return this.prop.src || this.error(\"Cannot duplicate - no source HTML.\");\n      }, function checkPageSize() {\n        return this.prop.pageSize || this.setPageSize();\n      }];\n      return this.thenList(prereqs).then(function toContainer_main() {\n        // Define the CSS styles for the container and its overlay parent.\n        var overlayCSS = {\n          position: \"fixed\",\n          overflow: \"hidden\",\n          zIndex: 1000,\n          left: \"-100000px\",\n          right: 0,\n          bottom: 0,\n          top: 0\n        };\n        var containerCSS = {\n          position: \"relative\",\n          display: \"inline-block\",\n          width: (typeof this.opt.width === \"number\" && !isNaN(this.opt.width) && typeof this.opt.windowWidth === \"number\" && !isNaN(this.opt.windowWidth) ? this.opt.windowWidth : Math.max(this.prop.src.clientWidth, this.prop.src.scrollWidth, this.prop.src.offsetWidth)) + \"px\",\n          left: 0,\n          right: 0,\n          top: 0,\n          margin: \"auto\",\n          backgroundColor: this.opt.backgroundColor\n        }; // Set the overlay to hidden (could be changed in the future to provide a print preview).\n\n        var source = cloneNode(this.prop.src, this.opt.html2canvas.javascriptEnabled);\n\n        if (source.tagName === \"BODY\") {\n          containerCSS.height = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight) + \"px\";\n        }\n\n        this.prop.overlay = createElement(\"div\", {\n          className: \"html2pdf__overlay\",\n          style: overlayCSS\n        });\n        this.prop.container = createElement(\"div\", {\n          className: \"html2pdf__container\",\n          style: containerCSS\n        });\n        this.prop.container.appendChild(source);\n        this.prop.container.firstChild.appendChild(createElement(\"div\", {\n          style: {\n            clear: \"both\",\n            border: \"0 none transparent\",\n            margin: 0,\n            padding: 0,\n            height: 0\n          }\n        }));\n        this.prop.container.style.float = \"none\";\n        this.prop.overlay.appendChild(this.prop.container);\n        document.body.appendChild(this.prop.overlay);\n        this.prop.container.firstChild.style.position = \"relative\";\n        this.prop.container.height = Math.max(this.prop.container.firstChild.clientHeight, this.prop.container.firstChild.scrollHeight, this.prop.container.firstChild.offsetHeight) + \"px\";\n      });\n    };\n\n    Worker.prototype.toCanvas = function toCanvas() {\n      // Set up function prerequisites.\n      var prereqs = [function checkContainer() {\n        return document.body.contains(this.prop.container) || this.toContainer();\n      }]; // Fulfill prereqs then create the canvas.\n\n      return this.thenList(prereqs).then(loadHtml2Canvas).then(function toCanvas_main(html2canvas) {\n        // Handle old-fashioned 'onrendered' argument.\n        var options = Object.assign({}, this.opt.html2canvas);\n        delete options.onrendered;\n        return html2canvas(this.prop.container, options);\n      }).then(function toCanvas_post(canvas) {\n        // Handle old-fashioned 'onrendered' argument.\n        var onRendered = this.opt.html2canvas.onrendered || function () {};\n\n        onRendered(canvas);\n        this.prop.canvas = canvas;\n        document.body.removeChild(this.prop.overlay);\n      });\n    };\n\n    Worker.prototype.toContext2d = function toContext2d() {\n      // Set up function prerequisites.\n      var prereqs = [function checkContainer() {\n        return document.body.contains(this.prop.container) || this.toContainer();\n      }]; // Fulfill prereqs then create the canvas.\n\n      return this.thenList(prereqs).then(loadHtml2Canvas).then(function toContext2d_main(html2canvas) {\n        // Handle old-fashioned 'onrendered' argument.\n        var pdf = this.opt.jsPDF;\n        var fontFaces = this.opt.fontFaces;\n        var scale = typeof this.opt.width === \"number\" && !isNaN(this.opt.width) && typeof this.opt.windowWidth === \"number\" && !isNaN(this.opt.windowWidth) ? this.opt.width / this.opt.windowWidth : 1;\n        var options = Object.assign({\n          async: true,\n          allowTaint: true,\n          scale: scale,\n          scrollX: this.opt.scrollX || 0,\n          scrollY: this.opt.scrollY || 0,\n          backgroundColor: \"#ffffff\",\n          imageTimeout: 15000,\n          logging: true,\n          proxy: null,\n          removeContainer: true,\n          foreignObjectRendering: false,\n          useCORS: false\n        }, this.opt.html2canvas);\n        delete options.onrendered;\n        pdf.context2d.autoPaging = typeof this.opt.autoPaging === \"undefined\" ? true : this.opt.autoPaging;\n        pdf.context2d.posX = this.opt.x;\n        pdf.context2d.posY = this.opt.y;\n        pdf.context2d.margin = this.opt.margin;\n        pdf.context2d.fontFaces = fontFaces;\n\n        if (fontFaces) {\n          for (var i = 0; i < fontFaces.length; ++i) {\n            var font = fontFaces[i];\n            var src = font.src.find(function (src) {\n              return src.format === \"truetype\";\n            });\n\n            if (src) {\n              pdf.addFont(src.url, font.ref.name, font.ref.style);\n            }\n          }\n        }\n\n        options.windowHeight = options.windowHeight || 0;\n        options.windowHeight = options.windowHeight == 0 ? Math.max(this.prop.container.clientHeight, this.prop.container.scrollHeight, this.prop.container.offsetHeight) : options.windowHeight;\n        pdf.context2d.save(true);\n        return html2canvas(this.prop.container, options);\n      }).then(function toContext2d_post(canvas) {\n        this.opt.jsPDF.context2d.restore(true); // Handle old-fashioned 'onrendered' argument.\n\n        var onRendered = this.opt.html2canvas.onrendered || function () {};\n\n        onRendered(canvas);\n        this.prop.canvas = canvas;\n        document.body.removeChild(this.prop.overlay);\n      });\n    };\n\n    Worker.prototype.toImg = function toImg() {\n      // Set up function prerequisites.\n      var prereqs = [function checkCanvas() {\n        return this.prop.canvas || this.toCanvas();\n      }]; // Fulfill prereqs then create the image.\n\n      return this.thenList(prereqs).then(function toImg_main() {\n        var imgData = this.prop.canvas.toDataURL(\"image/\" + this.opt.image.type, this.opt.image.quality);\n        this.prop.img = document.createElement(\"img\");\n        this.prop.img.src = imgData;\n      });\n    };\n\n    Worker.prototype.toPdf = function toPdf() {\n      // Set up function prerequisites.\n      var prereqs = [function checkContext2d() {\n        return this.toContext2d();\n      } //function checkCanvas() { return this.prop.canvas || this.toCanvas(); }\n      ]; // Fulfill prereqs then create the image.\n\n      return this.thenList(prereqs).then(function toPdf_main() {\n        // Create local copies of frequently used properties.\n        this.prop.pdf = this.prop.pdf || this.opt.jsPDF;\n      });\n    };\n    /* ----- OUTPUT / SAVE ----- */\n\n\n    Worker.prototype.output = function output(type, options, src) {\n      // Redirect requests to the correct function (outputPdf / outputImg).\n      src = src || \"pdf\";\n\n      if (src.toLowerCase() === \"img\" || src.toLowerCase() === \"image\") {\n        return this.outputImg(type, options);\n      } else {\n        return this.outputPdf(type, options);\n      }\n    };\n\n    Worker.prototype.outputPdf = function outputPdf(type, options) {\n      // Set up function prerequisites.\n      var prereqs = [function checkPdf() {\n        return this.prop.pdf || this.toPdf();\n      }]; // Fulfill prereqs then perform the appropriate output.\n\n      return this.thenList(prereqs).then(function outputPdf_main() {\n        /* Currently implemented output types:\n         *    https://rawgit.com/MrRio/jsPDF/master/docs/jspdf.js.html#line992\n         *  save(options), arraybuffer, blob, bloburi/bloburl,\n         *  datauristring/dataurlstring, dataurlnewwindow, datauri/dataurl\n         */\n        return this.prop.pdf.output(type, options);\n      });\n    };\n\n    Worker.prototype.outputImg = function outputImg(type) {\n      // Set up function prerequisites.\n      var prereqs = [function checkImg() {\n        return this.prop.img || this.toImg();\n      }]; // Fulfill prereqs then perform the appropriate output.\n\n      return this.thenList(prereqs).then(function outputImg_main() {\n        switch (type) {\n          case undefined:\n          case \"img\":\n            return this.prop.img;\n\n          case \"datauristring\":\n          case \"dataurlstring\":\n            return this.prop.img.src;\n\n          case \"datauri\":\n          case \"dataurl\":\n            return document.location.href = this.prop.img.src;\n\n          default:\n            throw 'Image output type \"' + type + '\" is not supported.';\n        }\n      });\n    };\n\n    Worker.prototype.save = function save(filename) {\n      // Set up function prerequisites.\n      var prereqs = [function checkPdf() {\n        return this.prop.pdf || this.toPdf();\n      }]; // Fulfill prereqs, update the filename (if provided), and save the PDF.\n\n      return this.thenList(prereqs).set(filename ? {\n        filename: filename\n      } : null).then(function save_main() {\n        this.prop.pdf.save(this.opt.filename);\n      });\n    };\n\n    Worker.prototype.doCallback = function doCallback() {\n      // Set up function prerequisites.\n      var prereqs = [function checkPdf() {\n        return this.prop.pdf || this.toPdf();\n      }]; // Fulfill prereqs, update the filename (if provided), and save the PDF.\n\n      return this.thenList(prereqs).then(function doCallback_main() {\n        this.prop.callback(this.prop.pdf);\n      });\n    };\n    /* ----- SET / GET ----- */\n\n\n    Worker.prototype.set = function set(opt) {\n      // TODO: Implement ordered pairs?\n      // Silently ignore invalid or empty input.\n      if (objType(opt) !== \"object\") {\n        return this;\n      } // Build an array of setter functions to queue.\n\n\n      var fns = Object.keys(opt || {}).map(function (key) {\n        if (key in Worker.template.prop) {\n          // Set pre-defined properties.\n          return function set_prop() {\n            this.prop[key] = opt[key];\n          };\n        } else {\n          switch (key) {\n            case \"margin\":\n              return this.setMargin.bind(this, opt.margin);\n\n            case \"jsPDF\":\n              return function set_jsPDF() {\n                this.opt.jsPDF = opt.jsPDF;\n                return this.setPageSize();\n              };\n\n            case \"pageSize\":\n              return this.setPageSize.bind(this, opt.pageSize);\n\n            default:\n              // Set any other properties in opt.\n              return function set_opt() {\n                this.opt[key] = opt[key];\n              };\n          }\n        }\n      }, this); // Set properties within the promise chain.\n\n      return this.then(function set_main() {\n        return this.thenList(fns);\n      });\n    };\n\n    Worker.prototype.get = function get(key, cbk) {\n      return this.then(function get_main() {\n        // Fetch the requested property, either as a predefined prop or in opt.\n        var val = key in Worker.template.prop ? this.prop[key] : this.opt[key];\n        return cbk ? cbk(val) : val;\n      });\n    };\n\n    Worker.prototype.setMargin = function setMargin(margin) {\n      return this.then(function setMargin_main() {\n        // Parse the margin property.\n        switch (objType(margin)) {\n          case \"number\":\n            margin = [margin, margin, margin, margin];\n          // eslint-disable-next-line no-fallthrough\n\n          case \"array\":\n            if (margin.length === 2) {\n              margin = [margin[0], margin[1], margin[0], margin[1]];\n            }\n\n            if (margin.length === 4) {\n              break;\n            }\n\n          // eslint-disable-next-line no-fallthrough\n\n          default:\n            return this.error(\"Invalid margin array.\");\n        } // Set the margin property, then update pageSize.\n\n\n        this.opt.margin = margin;\n      }).then(this.setPageSize);\n    };\n\n    Worker.prototype.setPageSize = function setPageSize(pageSize) {\n      function toPx(val, k) {\n        return Math.floor(val * k / 72 * 96);\n      }\n\n      return this.then(function setPageSize_main() {\n        // Retrieve page-size based on jsPDF settings, if not explicitly provided.\n        pageSize = pageSize || jsPDF.getPageSize(this.opt.jsPDF); // Add 'inner' field if not present.\n\n        if (!pageSize.hasOwnProperty(\"inner\")) {\n          pageSize.inner = {\n            width: pageSize.width - this.opt.margin[1] - this.opt.margin[3],\n            height: pageSize.height - this.opt.margin[0] - this.opt.margin[2]\n          };\n          pageSize.inner.px = {\n            width: toPx(pageSize.inner.width, pageSize.k),\n            height: toPx(pageSize.inner.height, pageSize.k)\n          };\n          pageSize.inner.ratio = pageSize.inner.height / pageSize.inner.width;\n        } // Attach pageSize to this.\n\n\n        this.prop.pageSize = pageSize;\n      });\n    };\n\n    Worker.prototype.setProgress = function setProgress(val, state, n, stack) {\n      // Immediately update all progress values.\n      if (val != null) this.progress.val = val;\n      if (state != null) this.progress.state = state;\n      if (n != null) this.progress.n = n;\n      if (stack != null) this.progress.stack = stack;\n      this.progress.ratio = this.progress.val / this.progress.state; // Return this for command chaining.\n\n      return this;\n    };\n\n    Worker.prototype.updateProgress = function updateProgress(val, state, n, stack) {\n      // Immediately update all progress values, using setProgress.\n      return this.setProgress(val ? this.progress.val + val : null, state ? state : null, n ? this.progress.n + n : null, stack ? this.progress.stack.concat(stack) : null);\n    };\n    /* ----- PROMISE MAPPING ----- */\n\n\n    Worker.prototype.then = function then(onFulfilled, onRejected) {\n      // Wrap `this` for encapsulation.\n      var self = this;\n      return this.thenCore(onFulfilled, onRejected, function then_main(onFulfilled, onRejected) {\n        // Update progress while queuing, calling, and resolving `then`.\n        self.updateProgress(null, null, 1, [onFulfilled]);\n        return Promise.prototype.then.call(this, function then_pre(val) {\n          self.updateProgress(null, onFulfilled);\n          return val;\n        }).then(onFulfilled, onRejected).then(function then_post(val) {\n          self.updateProgress(1);\n          return val;\n        });\n      });\n    };\n\n    Worker.prototype.thenCore = function thenCore(onFulfilled, onRejected, thenBase) {\n      // Handle optional thenBase parameter.\n      thenBase = thenBase || Promise.prototype.then; // Wrap `this` for encapsulation and bind it to the promise handlers.\n\n      var self = this;\n\n      if (onFulfilled) {\n        onFulfilled = onFulfilled.bind(self);\n      }\n\n      if (onRejected) {\n        onRejected = onRejected.bind(self);\n      } // Cast self into a Promise to avoid polyfills recursively defining `then`.\n\n\n      var isNative = Promise.toString().indexOf(\"[native code]\") !== -1 && Promise.name === \"Promise\";\n      var selfPromise = isNative ? self : Worker.convert(Object.assign({}, self), Promise.prototype); // Return the promise, after casting it into a Worker and preserving props.\n\n      var returnVal = thenBase.call(selfPromise, onFulfilled, onRejected);\n      return Worker.convert(returnVal, self.__proto__);\n    };\n\n    Worker.prototype.thenExternal = function thenExternal(onFulfilled, onRejected) {\n      // Call `then` and return a standard promise (exits the Worker chain).\n      return Promise.prototype.then.call(this, onFulfilled, onRejected);\n    };\n\n    Worker.prototype.thenList = function thenList(fns) {\n      // Queue a series of promise 'factories' into the promise chain.\n      var self = this;\n      fns.forEach(function thenList_forEach(fn) {\n        self = self.thenCore(fn);\n      });\n      return self;\n    };\n\n    Worker.prototype[\"catch\"] = function (onRejected) {\n      // Bind `this` to the promise handler, call `catch`, and return a Worker.\n      if (onRejected) {\n        onRejected = onRejected.bind(this);\n      }\n\n      var returnVal = Promise.prototype[\"catch\"].call(this, onRejected);\n      return Worker.convert(returnVal, this);\n    };\n\n    Worker.prototype.catchExternal = function catchExternal(onRejected) {\n      // Call `catch` and return a standard promise (exits the Worker chain).\n      return Promise.prototype[\"catch\"].call(this, onRejected);\n    };\n\n    Worker.prototype.error = function error(msg) {\n      // Throw the error in the Promise chain.\n      return this.then(function error_main() {\n        throw new Error(msg);\n      });\n    };\n    /* ----- ALIASES ----- */\n\n\n    Worker.prototype.using = Worker.prototype.set;\n    Worker.prototype.saveAs = Worker.prototype.save;\n    Worker.prototype.export = Worker.prototype.output;\n    Worker.prototype.run = Worker.prototype.then; // Get dimensions of a PDF page, as determined by jsPDF.\n\n    jsPDF.getPageSize = function (orientation, unit, format) {\n      // Decode options object\n      if (_typeof(orientation) === \"object\") {\n        var options = orientation;\n        orientation = options.orientation;\n        unit = options.unit || unit;\n        format = options.format || format;\n      } // Default options\n\n\n      unit = unit || \"mm\";\n      format = format || \"a4\";\n      orientation = (\"\" + (orientation || \"P\")).toLowerCase();\n      var format_as_string = (\"\" + format).toLowerCase(); // Size in pt of various paper formats\n\n      var pageFormats = {\n        a0: [2383.94, 3370.39],\n        a1: [1683.78, 2383.94],\n        a2: [1190.55, 1683.78],\n        a3: [841.89, 1190.55],\n        a4: [595.28, 841.89],\n        a5: [419.53, 595.28],\n        a6: [297.64, 419.53],\n        a7: [209.76, 297.64],\n        a8: [147.4, 209.76],\n        a9: [104.88, 147.4],\n        a10: [73.7, 104.88],\n        b0: [2834.65, 4008.19],\n        b1: [2004.09, 2834.65],\n        b2: [1417.32, 2004.09],\n        b3: [1000.63, 1417.32],\n        b4: [708.66, 1000.63],\n        b5: [498.9, 708.66],\n        b6: [354.33, 498.9],\n        b7: [249.45, 354.33],\n        b8: [175.75, 249.45],\n        b9: [124.72, 175.75],\n        b10: [87.87, 124.72],\n        c0: [2599.37, 3676.54],\n        c1: [1836.85, 2599.37],\n        c2: [1298.27, 1836.85],\n        c3: [918.43, 1298.27],\n        c4: [649.13, 918.43],\n        c5: [459.21, 649.13],\n        c6: [323.15, 459.21],\n        c7: [229.61, 323.15],\n        c8: [161.57, 229.61],\n        c9: [113.39, 161.57],\n        c10: [79.37, 113.39],\n        dl: [311.81, 623.62],\n        letter: [612, 792],\n        \"government-letter\": [576, 756],\n        legal: [612, 1008],\n        \"junior-legal\": [576, 360],\n        ledger: [1224, 792],\n        tabloid: [792, 1224],\n        \"credit-card\": [153, 243]\n      };\n      var k; // Unit conversion\n\n      switch (unit) {\n        case \"pt\":\n          k = 1;\n          break;\n\n        case \"mm\":\n          k = 72 / 25.4;\n          break;\n\n        case \"cm\":\n          k = 72 / 2.54;\n          break;\n\n        case \"in\":\n          k = 72;\n          break;\n\n        case \"px\":\n          k = 72 / 96;\n          break;\n\n        case \"pc\":\n          k = 12;\n          break;\n\n        case \"em\":\n          k = 12;\n          break;\n\n        case \"ex\":\n          k = 6;\n          break;\n\n        default:\n          throw \"Invalid unit: \" + unit;\n      }\n\n      var pageHeight = 0;\n      var pageWidth = 0; // Dimensions are stored as user units and converted to points on output\n\n      if (pageFormats.hasOwnProperty(format_as_string)) {\n        pageHeight = pageFormats[format_as_string][1] / k;\n        pageWidth = pageFormats[format_as_string][0] / k;\n      } else {\n        try {\n          pageHeight = format[1];\n          pageWidth = format[0];\n        } catch (err) {\n          throw new Error(\"Invalid format: \" + format);\n        }\n      }\n\n      var tmp; // Handle page orientation\n\n      if (orientation === \"p\" || orientation === \"portrait\") {\n        orientation = \"p\";\n\n        if (pageWidth > pageHeight) {\n          tmp = pageWidth;\n          pageWidth = pageHeight;\n          pageHeight = tmp;\n        }\n      } else if (orientation === \"l\" || orientation === \"landscape\") {\n        orientation = \"l\";\n\n        if (pageHeight > pageWidth) {\n          tmp = pageWidth;\n          pageWidth = pageHeight;\n          pageHeight = tmp;\n        }\n      } else {\n        throw \"Invalid orientation: \" + orientation;\n      } // Return information (k is the unit conversion ratio from pts)\n\n\n      var info = {\n        width: pageWidth,\n        height: pageHeight,\n        unit: unit,\n        k: k,\n        orientation: orientation\n      };\n      return info;\n    };\n    /**\n     * @typedef FontFace\n     *\n     * The font-face type implements an interface similar to that of the font-face CSS rule,\n     * and is used by jsPDF to match fonts when the font property of CanvasRenderingContext2D\n     * is updated.\n     *\n     * All properties expect values similar to those in the font-face CSS rule. A difference\n     * is the font-family, which do not need to be enclosed in double-quotes when containing\n     * spaces like in CSS.\n     *\n     * @property {string} family The name of the font-family.\n     * @property {string|undefined} style The style that this font-face defines, e.g. 'italic'.\n     * @property {string|number|undefined} weight The weight of the font, either as a string or a number (400, 500, 600, e.g.)\n     * @property {string|undefined} stretch The stretch of the font, e.g. condensed, normal, expanded.\n     * @property {Object[]} src A list of URLs from where fonts of various formats can be fetched.\n     * @property {string} [src] url A URL to a font of a specific format.\n     * @property {string} [src] format Format of the font referenced by the URL.\n     */\n\n    /**\n     * Generate a PDF from an HTML element or string using.\n     *\n     * @name html\n     * @function\n     * @param {HTMLElement|string} source The source HTMLElement or a string containing HTML.\n     * @param {Object} [options] Collection of settings\n     * @param {function} [options.callback] The mandatory callback-function gets as first parameter the current jsPDF instance\n     * @param {(number|number[])=} [options.margin] Page margins [top, right, bottom, left]. Default is 0.\n     * @param {(boolean|'slice'|'text')=} [options.autoPaging] The auto paging mode.\n     * <ul>\n     * <li>\n     *   <code>false</code>: Auto paging is disabled.\n     * </li>\n     * <li>\n     *   <code>true</code> or <code>'slice'</code>: Will cut shapes or text chunks across page breaks. Will possibly\n     *   slice text in half, making it difficult to read.\n     * </li>\n     * <li>\n     *   <code>'text'</code>: Trys not to cut text in half across page breaks. Works best for documents consisting\n     *   mostly of a single column of text.\n     * </li>\n     * </ul>\n     * Default is <code>true</code>.\n     * @param {string} [options.filename] name of the file\n     * @param {HTMLOptionImage} [options.image] image settings when converting HTML to image\n     * @param {Html2CanvasOptions} [options.html2canvas] html2canvas options\n     * @param {FontFace[]} [options.fontFaces] A list of font-faces to match when resolving fonts. Fonts will be added to the PDF based on the specified URL. If omitted, the font match algorithm falls back to old algorithm.\n     * @param {jsPDF} [options.jsPDF] jsPDF instance\n     * @param {number=} [options.x] x position on the PDF document in jsPDF units.\n     * @param {number=} [options.y] y position on the PDF document in jsPDF units.\n     * @param {number=} [options.width] The target width in the PDF document in jsPDF units. The rendered element will be\n     * scaled such that it fits into the specified width. Has no effect if either the <code>html2canvas.scale<code> is\n     * specified or the <code>windowWidth</code> option is NOT specified.\n     * @param {number=} [options.windowWidth] The window width in CSS pixels. In contrast to the\n     * <code>html2canvas.windowWidth</code> option, this option affects the actual container size while rendering and\n     * does NOT affect CSS media queries. This option only has an effect, if the <code>width<code> option is also specified.\n     *\n     * @example\n     * var doc = new jsPDF();\n     *\n     * doc.html(document.body, {\n     *    callback: function (doc) {\n     *      doc.save();\n     *    },\n     *    x: 10,\n     *    y: 10\n     * });\n     */\n\n\n    jsPDFAPI.html = function (src, options) {\n\n      options = options || {};\n\n      options.callback = options.callback || function () {};\n\n      options.html2canvas = options.html2canvas || {};\n      options.html2canvas.canvas = options.html2canvas.canvas || this.canvas;\n      options.jsPDF = options.jsPDF || this;\n      options.fontFaces = options.fontFaces ? options.fontFaces.map(normalizeFontFace) : null; // Create a new worker with the given options.\n\n      var worker = new Worker(options);\n\n      if (!options.worker) {\n        // If worker is not set to true, perform the traditional 'simple' operation.\n        return worker.from(src).doCallback();\n      } else {\n        // Otherwise, return the worker for new Promise-based operation.\n        return worker;\n      }\n    };\n  })(jsPDF.API);\n\n  /**\n   * @license\n   * ====================================================================\n   * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com\n   *\n   * Permission is hereby granted, free of charge, to any person obtaining\n   * a copy of this software and associated documentation files (the\n   * \"Software\"), to deal in the Software without restriction, including\n   * without limitation the rights to use, copy, modify, merge, publish,\n   * distribute, sublicense, and/or sell copies of the Software, and to\n   * permit persons to whom the Software is furnished to do so, subject to\n   * the following conditions:\n   *\n   * The above copyright notice and this permission notice shall be\n   * included in all copies or substantial portions of the Software.\n   *\n   * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n   * ====================================================================\n   */\n  /**\n   * jsPDF JavaScript plugin\n   *\n   * @name javascript\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n\n    var jsNamesObj, jsJsObj, text;\n    /**\n     * @name addJS\n     * @function\n     * @param {string} javascript The javascript to be embedded into the PDF-file.\n     * @returns {jsPDF}\n     */\n\n    jsPDFAPI.addJS = function (javascript) {\n      text = javascript;\n      this.internal.events.subscribe(\"postPutResources\", function () {\n        jsNamesObj = this.internal.newObject();\n        this.internal.out(\"<<\");\n        this.internal.out(\"/Names [(EmbeddedJS) \" + (jsNamesObj + 1) + \" 0 R]\");\n        this.internal.out(\">>\");\n        this.internal.out(\"endobj\");\n        jsJsObj = this.internal.newObject();\n        this.internal.out(\"<<\");\n        this.internal.out(\"/S /JavaScript\");\n        this.internal.out(\"/JS (\" + text + \")\");\n        this.internal.out(\">>\");\n        this.internal.out(\"endobj\");\n      });\n      this.internal.events.subscribe(\"putCatalog\", function () {\n        if (jsNamesObj !== undefined && jsJsObj !== undefined) {\n          this.internal.out(\"/Names <</JavaScript \" + jsNamesObj + \" 0 R>>\");\n        }\n      });\n      return this;\n    };\n  })(jsPDF.API);\n\n  /**\n   * @license\n   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n  /**\n   * jsPDF Outline PlugIn\n   *\n   * Generates a PDF Outline\n   * @name outline\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n\n    var namesOid; //var destsGoto = [];\n\n    jsPDFAPI.events.push([\"postPutResources\", function () {\n      var pdf = this;\n      var rx = /^(\\d+) 0 obj$/; // Write action goto objects for each page\n      // this.outline.destsGoto = [];\n      // for (var i = 0; i < totalPages; i++) {\n      // var id = pdf.internal.newObject();\n      // this.outline.destsGoto.push(id);\n      // pdf.internal.write(\"<</D[\" + (i * 2 + 3) + \" 0 R /XYZ null\n      // null null]/S/GoTo>> endobj\");\n      // }\n      //\n      // for (var i = 0; i < dests.length; i++) {\n      // pdf.internal.write(\"(page_\" + (i + 1) + \")\" + dests[i] + \" 0\n      // R\");\n      // }\n      //\n\n      if (this.outline.root.children.length > 0) {\n        var lines = pdf.outline.render().split(/\\r\\n/);\n\n        for (var i = 0; i < lines.length; i++) {\n          var line = lines[i];\n          var m = rx.exec(line);\n\n          if (m != null) {\n            var oid = m[1];\n            pdf.internal.newObjectDeferredBegin(oid, false);\n          }\n\n          pdf.internal.write(line);\n        }\n      } // This code will write named destination for each page reference\n      // (page_1, etc)\n\n\n      if (this.outline.createNamedDestinations) {\n        var totalPages = this.internal.pages.length; // WARNING: this assumes jsPDF starts on page 3 and pageIDs\n        // follow 5, 7, 9, etc\n        // Write destination objects for each page\n\n        var dests = [];\n\n        for (var i = 0; i < totalPages; i++) {\n          var id = pdf.internal.newObject();\n          dests.push(id);\n          var info = pdf.internal.getPageInfo(i + 1);\n          pdf.internal.write(\"<< /D[\" + info.objId + \" 0 R /XYZ null null null]>> endobj\");\n        } // assign a name for each destination\n\n\n        var names2Oid = pdf.internal.newObject();\n        pdf.internal.write(\"<< /Names [ \");\n\n        for (var i = 0; i < dests.length; i++) {\n          pdf.internal.write(\"(page_\" + (i + 1) + \")\" + dests[i] + \" 0 R\");\n        }\n\n        pdf.internal.write(\" ] >>\", \"endobj\"); // var kids = pdf.internal.newObject();\n        // pdf.internal.write('<< /Kids [ ' + names2Oid + ' 0 R');\n        // pdf.internal.write(' ] >>', 'endobj');\n\n        namesOid = pdf.internal.newObject();\n        pdf.internal.write(\"<< /Dests \" + names2Oid + \" 0 R\");\n        pdf.internal.write(\">>\", \"endobj\");\n      }\n    }]);\n    jsPDFAPI.events.push([\"putCatalog\", function () {\n      var pdf = this;\n\n      if (pdf.outline.root.children.length > 0) {\n        pdf.internal.write(\"/Outlines\", this.outline.makeRef(this.outline.root));\n\n        if (this.outline.createNamedDestinations) {\n          pdf.internal.write(\"/Names \" + namesOid + \" 0 R\");\n        } // Open with Bookmarks showing\n        // pdf.internal.write(\"/PageMode /UseOutlines\");\n\n      }\n    }]);\n    jsPDFAPI.events.push([\"initialized\", function () {\n      var pdf = this;\n      pdf.outline = {\n        createNamedDestinations: false,\n        root: {\n          children: []\n        }\n      };\n      /**\n       * Options: pageNumber\n       */\n\n      pdf.outline.add = function (parent, title, options) {\n        var item = {\n          title: title,\n          options: options,\n          children: []\n        };\n\n        if (parent == null) {\n          parent = this.root;\n        }\n\n        parent.children.push(item);\n        return item;\n      };\n\n      pdf.outline.render = function () {\n        this.ctx = {};\n        this.ctx.val = \"\";\n        this.ctx.pdf = pdf;\n        this.genIds_r(this.root);\n        this.renderRoot(this.root);\n        this.renderItems(this.root);\n        return this.ctx.val;\n      };\n\n      pdf.outline.genIds_r = function (node) {\n        node.id = pdf.internal.newObjectDeferred();\n\n        for (var i = 0; i < node.children.length; i++) {\n          this.genIds_r(node.children[i]);\n        }\n      };\n\n      pdf.outline.renderRoot = function (node) {\n        this.objStart(node);\n        this.line(\"/Type /Outlines\");\n\n        if (node.children.length > 0) {\n          this.line(\"/First \" + this.makeRef(node.children[0]));\n          this.line(\"/Last \" + this.makeRef(node.children[node.children.length - 1]));\n        }\n\n        this.line(\"/Count \" + this.count_r({\n          count: 0\n        }, node));\n        this.objEnd();\n      };\n\n      pdf.outline.renderItems = function (node) {\n        var getVerticalCoordinateString = this.ctx.pdf.internal.getVerticalCoordinateString;\n\n        for (var i = 0; i < node.children.length; i++) {\n          var item = node.children[i];\n          this.objStart(item);\n          this.line(\"/Title \" + this.makeString(item.title));\n          this.line(\"/Parent \" + this.makeRef(node));\n\n          if (i > 0) {\n            this.line(\"/Prev \" + this.makeRef(node.children[i - 1]));\n          }\n\n          if (i < node.children.length - 1) {\n            this.line(\"/Next \" + this.makeRef(node.children[i + 1]));\n          }\n\n          if (item.children.length > 0) {\n            this.line(\"/First \" + this.makeRef(item.children[0]));\n            this.line(\"/Last \" + this.makeRef(item.children[item.children.length - 1]));\n          }\n\n          var count = this.count = this.count_r({\n            count: 0\n          }, item);\n\n          if (count > 0) {\n            this.line(\"/Count \" + count);\n          }\n\n          if (item.options) {\n            if (item.options.pageNumber) {\n              // Explicit Destination\n              //WARNING this assumes page ids are 3,5,7, etc.\n              var info = pdf.internal.getPageInfo(item.options.pageNumber);\n              this.line(\"/Dest \" + \"[\" + info.objId + \" 0 R /XYZ 0 \" + getVerticalCoordinateString(0) + \" 0]\"); // this line does not work on all clients (pageNumber instead of page ref)\n              //this.line('/Dest ' + '[' + (item.options.pageNumber - 1) + ' /XYZ 0 ' + this.ctx.pdf.internal.pageSize.getHeight() + ' 0]');\n              // Named Destination\n              // this.line('/Dest (page_' + (item.options.pageNumber) + ')');\n              // Action Destination\n              // var id = pdf.internal.newObject();\n              // pdf.internal.write('<</D[' + (item.options.pageNumber - 1) + ' /XYZ null null null]/S/GoTo>> endobj');\n              // this.line('/A ' + id + ' 0 R' );\n            }\n          }\n\n          this.objEnd();\n        }\n\n        for (var z = 0; z < node.children.length; z++) {\n          this.renderItems(node.children[z]);\n        }\n      };\n\n      pdf.outline.line = function (text) {\n        this.ctx.val += text + \"\\r\\n\";\n      };\n\n      pdf.outline.makeRef = function (node) {\n        return node.id + \" 0 R\";\n      };\n\n      pdf.outline.makeString = function (val) {\n        return \"(\" + pdf.internal.pdfEscape(val) + \")\";\n      };\n\n      pdf.outline.objStart = function (node) {\n        this.ctx.val += \"\\r\\n\" + node.id + \" 0 obj\" + \"\\r\\n<<\\r\\n\";\n      };\n\n      pdf.outline.objEnd = function () {\n        this.ctx.val += \">> \\r\\n\" + \"endobj\" + \"\\r\\n\";\n      };\n\n      pdf.outline.count_r = function (ctx, node) {\n        for (var i = 0; i < node.children.length; i++) {\n          ctx.count++;\n          this.count_r(ctx, node.children[i]);\n        }\n\n        return ctx.count;\n      };\n    }]);\n    return this;\n  })(jsPDF.API);\n\n  /**\n   * @license\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n  /**\n   * jsPDF jpeg Support PlugIn\n   *\n   * @name jpeg_support\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n    /**\n     * 0xc0 (SOF) Huffman  - Baseline DCT\n     * 0xc1 (SOF) Huffman  - Extended sequential DCT\n     * 0xc2 Progressive DCT (SOF2)\n     * 0xc3 Spatial (sequential) lossless (SOF3)\n     * 0xc4 Differential sequential DCT (SOF5)\n     * 0xc5 Differential progressive DCT (SOF6)\n     * 0xc6 Differential spatial (SOF7)\n     * 0xc7\n     */\n\n    var markers = [0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7]; //takes a string imgData containing the raw bytes of\n    //a jpeg image and returns [width, height]\n    //Algorithm from: http://www.64lines.com/jpeg-width-height\n\n    var getJpegInfo = function getJpegInfo(imgData) {\n      var width, height, numcomponents;\n      var blockLength = imgData.charCodeAt(4) * 256 + imgData.charCodeAt(5);\n      var len = imgData.length;\n      var result = {\n        width: 0,\n        height: 0,\n        numcomponents: 1\n      };\n\n      for (var i = 4; i < len; i += 2) {\n        i += blockLength;\n\n        if (markers.indexOf(imgData.charCodeAt(i + 1)) !== -1) {\n          height = imgData.charCodeAt(i + 5) * 256 + imgData.charCodeAt(i + 6);\n          width = imgData.charCodeAt(i + 7) * 256 + imgData.charCodeAt(i + 8);\n          numcomponents = imgData.charCodeAt(i + 9);\n          result = {\n            width: width,\n            height: height,\n            numcomponents: numcomponents\n          };\n          break;\n        } else {\n          blockLength = imgData.charCodeAt(i + 2) * 256 + imgData.charCodeAt(i + 3);\n        }\n      }\n\n      return result;\n    };\n    /**\n     * @ignore\n     */\n\n\n    jsPDFAPI.processJPEG = function (data, index, alias, compression, dataAsBinaryString, colorSpace) {\n      var filter = this.decode.DCT_DECODE,\n          bpc = 8,\n          dims,\n          result = null;\n\n      if (typeof data === \"string\" || this.__addimage__.isArrayBuffer(data) || this.__addimage__.isArrayBufferView(data)) {\n        // if we already have a stored binary string rep use that\n        data = dataAsBinaryString || data;\n        data = this.__addimage__.isArrayBuffer(data) ? new Uint8Array(data) : data;\n        data = this.__addimage__.isArrayBufferView(data) ? this.__addimage__.arrayBufferToBinaryString(data) : data;\n        dims = getJpegInfo(data);\n\n        switch (dims.numcomponents) {\n          case 1:\n            colorSpace = this.color_spaces.DEVICE_GRAY;\n            break;\n\n          case 4:\n            colorSpace = this.color_spaces.DEVICE_CMYK;\n            break;\n\n          case 3:\n            colorSpace = this.color_spaces.DEVICE_RGB;\n            break;\n        }\n\n        result = {\n          data: data,\n          width: dims.width,\n          height: dims.height,\n          colorSpace: colorSpace,\n          bitsPerComponent: bpc,\n          filter: filter,\n          index: index,\n          alias: alias\n        };\n      }\n\n      return result;\n    };\n  })(jsPDF.API);\n\n  // Generated by CoffeeScript 1.4.0\n\n  var PNG = function () {\n    var APNG_BLEND_OP_SOURCE, APNG_DISPOSE_OP_BACKGROUND, APNG_DISPOSE_OP_PREVIOUS, makeImage, scratchCanvas, scratchCtx;\n    APNG_DISPOSE_OP_BACKGROUND = 1;\n    APNG_DISPOSE_OP_PREVIOUS = 2;\n    APNG_BLEND_OP_SOURCE = 0;\n\n    function PNG(data) {\n      var chunkSize, colors, palLen, delayDen, delayNum, frame, i, index, key, section, palShort, text, _i, _j, _ref;\n\n      this.data = data;\n      this.pos = 8;\n      this.palette = [];\n      this.imgData = [];\n      this.transparency = {};\n      this.animation = null;\n      this.text = {};\n      frame = null;\n\n      while (true) {\n        chunkSize = this.readUInt32();\n\n        section = function () {\n          var _i, _results;\n\n          _results = [];\n\n          for (i = _i = 0; _i < 4; i = ++_i) {\n            _results.push(String.fromCharCode(this.data[this.pos++]));\n          }\n\n          return _results;\n        }.call(this).join(\"\");\n\n        switch (section) {\n          case \"IHDR\":\n            this.width = this.readUInt32();\n            this.height = this.readUInt32();\n            this.bits = this.data[this.pos++];\n            this.colorType = this.data[this.pos++];\n            this.compressionMethod = this.data[this.pos++];\n            this.filterMethod = this.data[this.pos++];\n            this.interlaceMethod = this.data[this.pos++];\n            break;\n\n          case \"acTL\":\n            this.animation = {\n              numFrames: this.readUInt32(),\n              numPlays: this.readUInt32() || Infinity,\n              frames: []\n            };\n            break;\n\n          case \"PLTE\":\n            this.palette = this.read(chunkSize);\n            break;\n\n          case \"fcTL\":\n            if (frame) {\n              this.animation.frames.push(frame);\n            }\n\n            this.pos += 4;\n            frame = {\n              width: this.readUInt32(),\n              height: this.readUInt32(),\n              xOffset: this.readUInt32(),\n              yOffset: this.readUInt32()\n            };\n            delayNum = this.readUInt16();\n            delayDen = this.readUInt16() || 100;\n            frame.delay = 1000 * delayNum / delayDen;\n            frame.disposeOp = this.data[this.pos++];\n            frame.blendOp = this.data[this.pos++];\n            frame.data = [];\n            break;\n\n          case \"IDAT\":\n          case \"fdAT\":\n            if (section === \"fdAT\") {\n              this.pos += 4;\n              chunkSize -= 4;\n            }\n\n            data = (frame != null ? frame.data : void 0) || this.imgData;\n\n            for (i = _i = 0; 0 <= chunkSize ? _i < chunkSize : _i > chunkSize; i = 0 <= chunkSize ? ++_i : --_i) {\n              data.push(this.data[this.pos++]);\n            }\n\n            break;\n\n          case \"tRNS\":\n            this.transparency = {};\n\n            switch (this.colorType) {\n              case 3:\n                palLen = this.palette.length / 3;\n                this.transparency.indexed = this.read(chunkSize);\n                if (this.transparency.indexed.length > palLen) throw new Error(\"More transparent colors than palette size\");\n                /*\n                 * According to the PNG spec trns should be increased to the same size as palette if shorter\n                 */\n                //palShort = 255 - this.transparency.indexed.length;\n\n                palShort = palLen - this.transparency.indexed.length;\n\n                if (palShort > 0) {\n                  for (i = _j = 0; 0 <= palShort ? _j < palShort : _j > palShort; i = 0 <= palShort ? ++_j : --_j) {\n                    this.transparency.indexed.push(255);\n                  }\n                }\n\n                break;\n\n              case 0:\n                this.transparency.grayscale = this.read(chunkSize)[0];\n                break;\n\n              case 2:\n                this.transparency.rgb = this.read(chunkSize);\n            }\n\n            break;\n\n          case \"tEXt\":\n            text = this.read(chunkSize);\n            index = text.indexOf(0);\n            key = String.fromCharCode.apply(String, text.slice(0, index));\n            this.text[key] = String.fromCharCode.apply(String, text.slice(index + 1));\n            break;\n\n          case \"IEND\":\n            if (frame) {\n              this.animation.frames.push(frame);\n            }\n\n            this.colors = function () {\n              switch (this.colorType) {\n                case 0:\n                case 3:\n                case 4:\n                  return 1;\n\n                case 2:\n                case 6:\n                  return 3;\n              }\n            }.call(this);\n\n            this.hasAlphaChannel = (_ref = this.colorType) === 4 || _ref === 6;\n            colors = this.colors + (this.hasAlphaChannel ? 1 : 0);\n            this.pixelBitlength = this.bits * colors;\n\n            this.colorSpace = function () {\n              switch (this.colors) {\n                case 1:\n                  return \"DeviceGray\";\n\n                case 3:\n                  return \"DeviceRGB\";\n              }\n            }.call(this);\n\n            this.imgData = new Uint8Array(this.imgData);\n            return;\n\n          default:\n            this.pos += chunkSize;\n        }\n\n        this.pos += 4;\n\n        if (this.pos > this.data.length) {\n          throw new Error(\"Incomplete or corrupt PNG file\");\n        }\n      }\n    }\n\n    PNG.prototype.read = function (bytes) {\n      var i, _i, _results;\n\n      _results = [];\n\n      for (i = _i = 0; 0 <= bytes ? _i < bytes : _i > bytes; i = 0 <= bytes ? ++_i : --_i) {\n        _results.push(this.data[this.pos++]);\n      }\n\n      return _results;\n    };\n\n    PNG.prototype.readUInt32 = function () {\n      var b1, b2, b3, b4;\n      b1 = this.data[this.pos++] << 24;\n      b2 = this.data[this.pos++] << 16;\n      b3 = this.data[this.pos++] << 8;\n      b4 = this.data[this.pos++];\n      return b1 | b2 | b3 | b4;\n    };\n\n    PNG.prototype.readUInt16 = function () {\n      var b1, b2;\n      b1 = this.data[this.pos++] << 8;\n      b2 = this.data[this.pos++];\n      return b1 | b2;\n    };\n\n    PNG.prototype.decodePixels = function (data) {\n      var pixelBytes = this.pixelBitlength / 8;\n      var fullPixels = new Uint8Array(this.width * this.height * pixelBytes);\n      var pos = 0;\n\n      var _this = this;\n\n      if (data == null) {\n        data = this.imgData;\n      }\n\n      if (data.length === 0) {\n        return new Uint8Array(0);\n      }\n\n      data = unzlibSync(data);\n\n      function pass(x0, y0, dx, dy) {\n        var abyte, c, col, i, left, length, p, pa, paeth, pb, pc, pixels, row, scanlineLength, upper, upperLeft, _i, _j, _k, _l, _m;\n\n        var w = Math.ceil((_this.width - x0) / dx),\n            h = Math.ceil((_this.height - y0) / dy);\n        var isFull = _this.width == w && _this.height == h;\n        scanlineLength = pixelBytes * w;\n        pixels = isFull ? fullPixels : new Uint8Array(scanlineLength * h);\n        length = data.length;\n        row = 0;\n        c = 0;\n\n        while (row < h && pos < length) {\n          switch (data[pos++]) {\n            case 0:\n              for (i = _i = 0; _i < scanlineLength; i = _i += 1) {\n                pixels[c++] = data[pos++];\n              }\n\n              break;\n\n            case 1:\n              for (i = _j = 0; _j < scanlineLength; i = _j += 1) {\n                abyte = data[pos++];\n                left = i < pixelBytes ? 0 : pixels[c - pixelBytes];\n                pixels[c++] = (abyte + left) % 256;\n              }\n\n              break;\n\n            case 2:\n              for (i = _k = 0; _k < scanlineLength; i = _k += 1) {\n                abyte = data[pos++];\n                col = (i - i % pixelBytes) / pixelBytes;\n                upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + i % pixelBytes];\n                pixels[c++] = (upper + abyte) % 256;\n              }\n\n              break;\n\n            case 3:\n              for (i = _l = 0; _l < scanlineLength; i = _l += 1) {\n                abyte = data[pos++];\n                col = (i - i % pixelBytes) / pixelBytes;\n                left = i < pixelBytes ? 0 : pixels[c - pixelBytes];\n                upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + i % pixelBytes];\n                pixels[c++] = (abyte + Math.floor((left + upper) / 2)) % 256;\n              }\n\n              break;\n\n            case 4:\n              for (i = _m = 0; _m < scanlineLength; i = _m += 1) {\n                abyte = data[pos++];\n                col = (i - i % pixelBytes) / pixelBytes;\n                left = i < pixelBytes ? 0 : pixels[c - pixelBytes];\n\n                if (row === 0) {\n                  upper = upperLeft = 0;\n                } else {\n                  upper = pixels[(row - 1) * scanlineLength + col * pixelBytes + i % pixelBytes];\n                  upperLeft = col && pixels[(row - 1) * scanlineLength + (col - 1) * pixelBytes + i % pixelBytes];\n                }\n\n                p = left + upper - upperLeft;\n                pa = Math.abs(p - left);\n                pb = Math.abs(p - upper);\n                pc = Math.abs(p - upperLeft);\n\n                if (pa <= pb && pa <= pc) {\n                  paeth = left;\n                } else if (pb <= pc) {\n                  paeth = upper;\n                } else {\n                  paeth = upperLeft;\n                }\n\n                pixels[c++] = (abyte + paeth) % 256;\n              }\n\n              break;\n\n            default:\n              throw new Error(\"Invalid filter algorithm: \" + data[pos - 1]);\n          }\n\n          if (!isFull) {\n            var fullPos = ((y0 + row * dy) * _this.width + x0) * pixelBytes;\n            var partPos = row * scanlineLength;\n\n            for (i = 0; i < w; i += 1) {\n              for (var j = 0; j < pixelBytes; j += 1) {\n                fullPixels[fullPos++] = pixels[partPos++];\n              }\n\n              fullPos += (dx - 1) * pixelBytes;\n            }\n          }\n\n          row++;\n        }\n      }\n\n      if (_this.interlaceMethod == 1) {\n        /*\n            1 6 4 6 2 6 4 6\n            7 7 7 7 7 7 7 7\n            5 6 5 6 5 6 5 6\n            7 7 7 7 7 7 7 7\n            3 6 4 6 3 6 4 6\n            7 7 7 7 7 7 7 7\n            5 6 5 6 5 6 5 6\n            7 7 7 7 7 7 7 7\n          */\n        pass(0, 0, 8, 8); // 1\n\n        /* NOTE these seem to follow the pattern:\n         * pass(x, 0, 2*x, 2*x);\n         * pass(0, x,   x, 2*x);\n         * with x being 4, 2, 1.\n         */\n\n        pass(4, 0, 8, 8); // 2\n\n        pass(0, 4, 4, 8); // 3\n\n        pass(2, 0, 4, 4); // 4\n\n        pass(0, 2, 2, 4); // 5\n\n        pass(1, 0, 2, 2); // 6\n\n        pass(0, 1, 1, 2); // 7\n      } else {\n        pass(0, 0, 1, 1);\n      }\n\n      return fullPixels;\n    };\n\n    PNG.prototype.decodePalette = function () {\n      var c, i, length, palette, pos, ret, transparency, _i, _ref, _ref1;\n\n      palette = this.palette;\n      transparency = this.transparency.indexed || [];\n      ret = new Uint8Array((transparency.length || 0) + palette.length);\n      pos = 0;\n      length = palette.length;\n      c = 0;\n\n      for (i = _i = 0, _ref = length; _i < _ref; i = _i += 3) {\n        ret[pos++] = palette[i];\n        ret[pos++] = palette[i + 1];\n        ret[pos++] = palette[i + 2];\n        ret[pos++] = (_ref1 = transparency[c++]) != null ? _ref1 : 255;\n      }\n\n      return ret;\n    };\n\n    PNG.prototype.copyToImageData = function (imageData, pixels) {\n      var alpha, colors, data, i, input, j, k, length, palette, v, _ref;\n\n      colors = this.colors;\n      palette = null;\n      alpha = this.hasAlphaChannel;\n\n      if (this.palette.length) {\n        palette = (_ref = this._decodedPalette) != null ? _ref : this._decodedPalette = this.decodePalette();\n        colors = 4;\n        alpha = true;\n      }\n\n      data = imageData.data || imageData;\n      length = data.length;\n      input = palette || pixels;\n      i = j = 0;\n\n      if (colors === 1) {\n        while (i < length) {\n          k = palette ? pixels[i / 4] * 4 : j;\n          v = input[k++];\n          data[i++] = v;\n          data[i++] = v;\n          data[i++] = v;\n          data[i++] = alpha ? input[k++] : 255;\n          j = k;\n        }\n      } else {\n        while (i < length) {\n          k = palette ? pixels[i / 4] * 4 : j;\n          data[i++] = input[k++];\n          data[i++] = input[k++];\n          data[i++] = input[k++];\n          data[i++] = alpha ? input[k++] : 255;\n          j = k;\n        }\n      }\n    };\n\n    PNG.prototype.decode = function () {\n      var ret;\n      ret = new Uint8Array(this.width * this.height * 4);\n      this.copyToImageData(ret, this.decodePixels());\n      return ret;\n    };\n\n    var hasBrowserCanvas = function hasBrowserCanvas() {\n      if (Object.prototype.toString.call(globalObject) === \"[object Window]\") {\n        try {\n          scratchCanvas = globalObject.document.createElement(\"canvas\");\n          scratchCtx = scratchCanvas.getContext(\"2d\");\n        } catch (e) {\n          return false;\n        }\n\n        return true;\n      }\n\n      return false;\n    };\n\n    hasBrowserCanvas();\n\n    makeImage = function makeImage(imageData) {\n      if (hasBrowserCanvas() === true) {\n        var img;\n        scratchCtx.width = imageData.width;\n        scratchCtx.height = imageData.height;\n        scratchCtx.clearRect(0, 0, imageData.width, imageData.height);\n        scratchCtx.putImageData(imageData, 0, 0);\n        img = new Image();\n        img.src = scratchCanvas.toDataURL();\n        return img;\n      }\n\n      throw new Error(\"This method requires a Browser with Canvas-capability.\");\n    };\n\n    PNG.prototype.decodeFrames = function (ctx) {\n      var frame, i, imageData, pixels, _i, _len, _ref, _results;\n\n      if (!this.animation) {\n        return;\n      }\n\n      _ref = this.animation.frames;\n      _results = [];\n\n      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {\n        frame = _ref[i];\n        imageData = ctx.createImageData(frame.width, frame.height);\n        pixels = this.decodePixels(new Uint8Array(frame.data));\n        this.copyToImageData(imageData, pixels);\n        frame.imageData = imageData;\n\n        _results.push(frame.image = makeImage(imageData));\n      }\n\n      return _results;\n    };\n\n    PNG.prototype.renderFrame = function (ctx, number) {\n      var frame, frames, prev;\n      frames = this.animation.frames;\n      frame = frames[number];\n      prev = frames[number - 1];\n\n      if (number === 0) {\n        ctx.clearRect(0, 0, this.width, this.height);\n      }\n\n      if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_BACKGROUND) {\n        ctx.clearRect(prev.xOffset, prev.yOffset, prev.width, prev.height);\n      } else if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_PREVIOUS) {\n        ctx.putImageData(prev.imageData, prev.xOffset, prev.yOffset);\n      }\n\n      if (frame.blendOp === APNG_BLEND_OP_SOURCE) {\n        ctx.clearRect(frame.xOffset, frame.yOffset, frame.width, frame.height);\n      }\n\n      return ctx.drawImage(frame.image, frame.xOffset, frame.yOffset);\n    };\n\n    PNG.prototype.animate = function (ctx) {\n      var _doFrame,\n          frameNumber,\n          frames,\n          numFrames,\n          numPlays,\n          _ref,\n          _this = this;\n\n      frameNumber = 0;\n      _ref = this.animation, numFrames = _ref.numFrames, frames = _ref.frames, numPlays = _ref.numPlays;\n      return (_doFrame = function doFrame() {\n        var f, frame;\n        f = frameNumber++ % numFrames;\n        frame = frames[f];\n\n        _this.renderFrame(ctx, f);\n\n        if (numFrames > 1 && frameNumber / numFrames < numPlays) {\n          return _this.animation._timeout = setTimeout(_doFrame, frame.delay);\n        }\n      })();\n    };\n\n    PNG.prototype.stopAnimation = function () {\n      var _ref;\n\n      return clearTimeout((_ref = this.animation) != null ? _ref._timeout : void 0);\n    };\n\n    PNG.prototype.render = function (canvas) {\n      var ctx, data;\n\n      if (canvas._png) {\n        canvas._png.stopAnimation();\n      }\n\n      canvas._png = this;\n      canvas.width = this.width;\n      canvas.height = this.height;\n      ctx = canvas.getContext(\"2d\");\n\n      if (this.animation) {\n        this.decodeFrames(ctx);\n        return this.animate(ctx);\n      } else {\n        data = ctx.createImageData(this.width, this.height);\n        this.copyToImageData(data, this.decodePixels());\n        return ctx.putImageData(data, 0, 0);\n      }\n    };\n\n    return PNG;\n  }();\n\n  /**\n   * @license\n   *\n   * Copyright (c) 2014 James Robb, https://github.com/jamesbrobb\n   *\n   * Permission is hereby granted, free of charge, to any person obtaining\n   * a copy of this software and associated documentation files (the\n   * \"Software\"), to deal in the Software without restriction, including\n   * without limitation the rights to use, copy, modify, merge, publish,\n   * distribute, sublicense, and/or sell copies of the Software, and to\n   * permit persons to whom the Software is furnished to do so, subject to\n   * the following conditions:\n   *\n   * The above copyright notice and this permission notice shall be\n   * included in all copies or substantial portions of the Software.\n   *\n   * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n   * ====================================================================\n   */\n  /**\n   * jsPDF PNG PlugIn\n   * @name png_support\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n    /*\n     * @see http://www.w3.org/TR/PNG-Chunks.html\n     *\n     Color    Allowed      Interpretation\n     Type     Bit Depths\n        0       1,2,4,8,16  Each pixel is a grayscale sample.\n        2       8,16        Each pixel is an R,G,B triple.\n        3       1,2,4,8     Each pixel is a palette index;\n                           a PLTE chunk must appear.\n        4       8,16        Each pixel is a grayscale sample,\n                           followed by an alpha sample.\n        6       8,16        Each pixel is an R,G,B triple,\n                           followed by an alpha sample.\n    */\n\n    /*\n     * PNG filter method types\n     *\n     * @see http://www.w3.org/TR/PNG-Filters.html\n     * @see http://www.libpng.org/pub/png/book/chapter09.html\n     *\n     * This is what the value 'Predictor' in decode params relates to\n     *\n     * 15 is \"optimal prediction\", which means the prediction algorithm can change from line to line.\n     * In that case, you actually have to read the first byte off each line for the prediction algorthim (which should be 0-4, corresponding to PDF 10-14) and select the appropriate unprediction algorithm based on that byte.\n     *\n       0       None\n       1       Sub\n       2       Up\n       3       Average\n       4       Paeth\n     */\n\n    var canCompress = function canCompress(value) {\n      return value !== jsPDFAPI.image_compression.NONE && hasCompressionJS();\n    };\n\n    var hasCompressionJS = function hasCompressionJS() {\n      return typeof zlibSync === \"function\";\n    };\n\n    var compressBytes = function compressBytes(bytes, lineLength, colorsPerPixel, compression) {\n      var level = 4;\n      var filter_method = filterUp;\n\n      switch (compression) {\n        case jsPDFAPI.image_compression.FAST:\n          level = 1;\n          filter_method = filterSub;\n          break;\n\n        case jsPDFAPI.image_compression.MEDIUM:\n          level = 6;\n          filter_method = filterAverage;\n          break;\n\n        case jsPDFAPI.image_compression.SLOW:\n          level = 9;\n          filter_method = filterPaeth;\n          break;\n      }\n\n      bytes = applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method);\n      var dat = zlibSync(bytes, {\n        level: level\n      });\n      return jsPDFAPI.__addimage__.arrayBufferToBinaryString(dat);\n    };\n\n    var applyPngFilterMethod = function applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method) {\n      var lines = bytes.length / lineLength,\n          result = new Uint8Array(bytes.length + lines),\n          filter_methods = getFilterMethods(),\n          line,\n          prevLine,\n          offset;\n\n      for (var i = 0; i < lines; i += 1) {\n        offset = i * lineLength;\n        line = bytes.subarray(offset, offset + lineLength);\n\n        if (filter_method) {\n          result.set(filter_method(line, colorsPerPixel, prevLine), offset + i);\n        } else {\n          var len = filter_methods.length,\n              results = [];\n\n          for (var j; j < len; j += 1) {\n            results[j] = filter_methods[j](line, colorsPerPixel, prevLine);\n          }\n\n          var ind = getIndexOfSmallestSum(results.concat());\n          result.set(results[ind], offset + i);\n        }\n\n        prevLine = line;\n      }\n\n      return result;\n    };\n\n    var filterNone = function filterNone(line) {\n      /*var result = new Uint8Array(line.length + 1);\n      result[0] = 0;\n      result.set(line, 1);*/\n      var result = Array.apply([], line);\n      result.unshift(0);\n      return result;\n    };\n\n    var filterSub = function filterSub(line, colorsPerPixel) {\n      var result = [],\n          len = line.length,\n          left;\n      result[0] = 1;\n\n      for (var i = 0; i < len; i += 1) {\n        left = line[i - colorsPerPixel] || 0;\n        result[i + 1] = line[i] - left + 0x0100 & 0xff;\n      }\n\n      return result;\n    };\n\n    var filterUp = function filterUp(line, colorsPerPixel, prevLine) {\n      var result = [],\n          len = line.length,\n          up;\n      result[0] = 2;\n\n      for (var i = 0; i < len; i += 1) {\n        up = prevLine && prevLine[i] || 0;\n        result[i + 1] = line[i] - up + 0x0100 & 0xff;\n      }\n\n      return result;\n    };\n\n    var filterAverage = function filterAverage(line, colorsPerPixel, prevLine) {\n      var result = [],\n          len = line.length,\n          left,\n          up;\n      result[0] = 3;\n\n      for (var i = 0; i < len; i += 1) {\n        left = line[i - colorsPerPixel] || 0;\n        up = prevLine && prevLine[i] || 0;\n        result[i + 1] = line[i] + 0x0100 - (left + up >>> 1) & 0xff;\n      }\n\n      return result;\n    };\n\n    var filterPaeth = function filterPaeth(line, colorsPerPixel, prevLine) {\n      var result = [],\n          len = line.length,\n          left,\n          up,\n          upLeft,\n          paeth;\n      result[0] = 4;\n\n      for (var i = 0; i < len; i += 1) {\n        left = line[i - colorsPerPixel] || 0;\n        up = prevLine && prevLine[i] || 0;\n        upLeft = prevLine && prevLine[i - colorsPerPixel] || 0;\n        paeth = paethPredictor(left, up, upLeft);\n        result[i + 1] = line[i] - paeth + 0x0100 & 0xff;\n      }\n\n      return result;\n    };\n\n    var paethPredictor = function paethPredictor(left, up, upLeft) {\n      if (left === up && up === upLeft) {\n        return left;\n      }\n\n      var pLeft = Math.abs(up - upLeft),\n          pUp = Math.abs(left - upLeft),\n          pUpLeft = Math.abs(left + up - upLeft - upLeft);\n      return pLeft <= pUp && pLeft <= pUpLeft ? left : pUp <= pUpLeft ? up : upLeft;\n    };\n\n    var getFilterMethods = function getFilterMethods() {\n      return [filterNone, filterSub, filterUp, filterAverage, filterPaeth];\n    };\n\n    var getIndexOfSmallestSum = function getIndexOfSmallestSum(arrays) {\n      var sum = arrays.map(function (value) {\n        return value.reduce(function (pv, cv) {\n          return pv + Math.abs(cv);\n        }, 0);\n      });\n      return sum.indexOf(Math.min.apply(null, sum));\n    };\n\n    var getPredictorFromCompression = function getPredictorFromCompression(compression) {\n      var predictor;\n\n      switch (compression) {\n        case jsPDFAPI.image_compression.FAST:\n          predictor = 11;\n          break;\n\n        case jsPDFAPI.image_compression.MEDIUM:\n          predictor = 13;\n          break;\n\n        case jsPDFAPI.image_compression.SLOW:\n          predictor = 14;\n          break;\n\n        default:\n          predictor = 12;\n          break;\n      }\n\n      return predictor;\n    };\n    /**\n     * @name processPNG\n     * @function\n     * @ignore\n     */\n\n\n    jsPDFAPI.processPNG = function (imageData, index, alias, compression) {\n\n      var colorSpace,\n          filter = this.decode.FLATE_DECODE,\n          bitsPerComponent,\n          image,\n          decodeParameters = \"\",\n          trns,\n          colors,\n          pal,\n          smask,\n          pixels,\n          len,\n          alphaData,\n          imgData,\n          hasColors,\n          pixel,\n          i,\n          n;\n      if (this.__addimage__.isArrayBuffer(imageData)) imageData = new Uint8Array(imageData);\n\n      if (this.__addimage__.isArrayBufferView(imageData)) {\n        image = new PNG(imageData);\n        imageData = image.imgData;\n        bitsPerComponent = image.bits;\n        colorSpace = image.colorSpace;\n        colors = image.colors;\n        /*\n         * colorType 6 - Each pixel is an R,G,B triple, followed by an alpha sample.\n         *\n         * colorType 4 - Each pixel is a grayscale sample, followed by an alpha sample.\n         *\n         * Extract alpha to create two separate images, using the alpha as a sMask\n         */\n\n        if ([4, 6].indexOf(image.colorType) !== -1) {\n          /*\n           * processes 8 bit RGBA and grayscale + alpha images\n           */\n          if (image.bits === 8) {\n            pixels = image.pixelBitlength == 32 ? new Uint32Array(image.decodePixels().buffer) : image.pixelBitlength == 16 ? new Uint16Array(image.decodePixels().buffer) : new Uint8Array(image.decodePixels().buffer);\n            len = pixels.length;\n            imgData = new Uint8Array(len * image.colors);\n            alphaData = new Uint8Array(len);\n            var pDiff = image.pixelBitlength - image.bits;\n            i = 0;\n            n = 0;\n            var pbl;\n\n            for (; i < len; i++) {\n              pixel = pixels[i];\n              pbl = 0;\n\n              while (pbl < pDiff) {\n                imgData[n++] = pixel >>> pbl & 0xff;\n                pbl = pbl + image.bits;\n              }\n\n              alphaData[i] = pixel >>> pbl & 0xff;\n            }\n          }\n          /*\n           * processes 16 bit RGBA and grayscale + alpha images\n           */\n\n\n          if (image.bits === 16) {\n            pixels = new Uint32Array(image.decodePixels().buffer);\n            len = pixels.length;\n            imgData = new Uint8Array(len * (32 / image.pixelBitlength) * image.colors);\n            alphaData = new Uint8Array(len * (32 / image.pixelBitlength));\n            hasColors = image.colors > 1;\n            i = 0;\n            n = 0;\n            var a = 0;\n\n            while (i < len) {\n              pixel = pixels[i++];\n              imgData[n++] = pixel >>> 0 & 0xff;\n\n              if (hasColors) {\n                imgData[n++] = pixel >>> 16 & 0xff;\n                pixel = pixels[i++];\n                imgData[n++] = pixel >>> 0 & 0xff;\n              }\n\n              alphaData[a++] = pixel >>> 16 & 0xff;\n            }\n\n            bitsPerComponent = 8;\n          }\n\n          if (canCompress(compression)) {\n            imageData = compressBytes(imgData, image.width * image.colors, image.colors, compression);\n            smask = compressBytes(alphaData, image.width, 1, compression);\n          } else {\n            imageData = imgData;\n            smask = alphaData;\n            filter = undefined;\n          }\n        }\n        /*\n         * Indexed png. Each pixel is a palette index.\n         */\n\n\n        if (image.colorType === 3) {\n          colorSpace = this.color_spaces.INDEXED;\n          pal = image.palette;\n\n          if (image.transparency.indexed) {\n            var trans = image.transparency.indexed;\n            var total = 0;\n            i = 0;\n            len = trans.length;\n\n            for (; i < len; ++i) {\n              total += trans[i];\n            }\n\n            total = total / 255;\n            /*\n             * a single color is specified as 100% transparent (0),\n             * so we set trns to use a /Mask with that index\n             */\n\n            if (total === len - 1 && trans.indexOf(0) !== -1) {\n              trns = [trans.indexOf(0)];\n              /*\n               * there's more than one colour within the palette that specifies\n               * a transparency value less than 255, so we unroll the pixels to create an image sMask\n               */\n            } else if (total !== len) {\n              pixels = image.decodePixels();\n              alphaData = new Uint8Array(pixels.length);\n              i = 0;\n              len = pixels.length;\n\n              for (; i < len; i++) {\n                alphaData[i] = trans[pixels[i]];\n              }\n\n              smask = compressBytes(alphaData, image.width, 1);\n            }\n          }\n        }\n\n        var predictor = getPredictorFromCompression(compression);\n\n        if (filter === this.decode.FLATE_DECODE) {\n          decodeParameters = \"/Predictor \" + predictor + \" \";\n        }\n\n        decodeParameters += \"/Colors \" + colors + \" /BitsPerComponent \" + bitsPerComponent + \" /Columns \" + image.width;\n\n        if (this.__addimage__.isArrayBuffer(imageData) || this.__addimage__.isArrayBufferView(imageData)) {\n          imageData = this.__addimage__.arrayBufferToBinaryString(imageData);\n        }\n\n        if (smask && this.__addimage__.isArrayBuffer(smask) || this.__addimage__.isArrayBufferView(smask)) {\n          smask = this.__addimage__.arrayBufferToBinaryString(smask);\n        }\n\n        return {\n          alias: alias,\n          data: imageData,\n          index: index,\n          filter: filter,\n          decodeParameters: decodeParameters,\n          transparency: trns,\n          palette: pal,\n          sMask: smask,\n          predictor: predictor,\n          width: image.width,\n          height: image.height,\n          bitsPerComponent: bitsPerComponent,\n          colorSpace: colorSpace\n        };\n      }\n    };\n  })(jsPDF.API);\n\n  /**\n   * @license\n   * (c) Dean McNamee <dean@gmail.com>, 2013.\n   *\n   * https://github.com/deanm/omggif\n   *\n   * Permission is hereby granted, free of charge, to any person obtaining a copy\n   * of this software and associated documentation files (the \"Software\"), to\n   * deal in the Software without restriction, including without limitation the\n   * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n   * sell copies of the Software, and to permit persons to whom the Software is\n   * furnished to do so, subject to the following conditions:\n   *\n   * The above copyright notice and this permission notice shall be included in\n   * all copies or substantial portions of the Software.\n   *\n   * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n   * IN THE SOFTWARE.\n   *\n   * omggif is a JavaScript implementation of a GIF 89a encoder and decoder,\n   * including animation and compression.  It does not rely on any specific\n   * underlying system, so should run in the browser, Node, or Plask.\n   */\n\n  function GifReader(buf) {\n    var p = 0; // - Header (GIF87a or GIF89a).\n\n    if (buf[p++] !== 0x47 || buf[p++] !== 0x49 || buf[p++] !== 0x46 || buf[p++] !== 0x38 || (buf[p++] + 1 & 0xfd) !== 0x38 || buf[p++] !== 0x61) {\n      throw new Error(\"Invalid GIF 87a/89a header.\");\n    } // - Logical Screen Descriptor.\n\n\n    var width = buf[p++] | buf[p++] << 8;\n    var height = buf[p++] | buf[p++] << 8;\n    var pf0 = buf[p++]; // <Packed Fields>.\n\n    var global_palette_flag = pf0 >> 7;\n    var num_global_colors_pow2 = pf0 & 0x7;\n    var num_global_colors = 1 << num_global_colors_pow2 + 1;\n    var background = buf[p++];\n    buf[p++]; // Pixel aspect ratio (unused?).\n\n    var global_palette_offset = null;\n    var global_palette_size = null;\n\n    if (global_palette_flag) {\n      global_palette_offset = p;\n      global_palette_size = num_global_colors;\n      p += num_global_colors * 3; // Seek past palette.\n    }\n\n    var no_eof = true;\n    var frames = [];\n    var delay = 0;\n    var transparent_index = null;\n    var disposal = 0; // 0 - No disposal specified.\n\n    var loop_count = null;\n    this.width = width;\n    this.height = height;\n\n    while (no_eof && p < buf.length) {\n      switch (buf[p++]) {\n        case 0x21:\n          // Graphics Control Extension Block\n          switch (buf[p++]) {\n            case 0xff:\n              // Application specific block\n              // Try if it's a Netscape block (with animation loop counter).\n              if (buf[p] !== 0x0b || // 21 FF already read, check block size.\n              // NETSCAPE2.0\n              buf[p + 1] == 0x4e && buf[p + 2] == 0x45 && buf[p + 3] == 0x54 && buf[p + 4] == 0x53 && buf[p + 5] == 0x43 && buf[p + 6] == 0x41 && buf[p + 7] == 0x50 && buf[p + 8] == 0x45 && buf[p + 9] == 0x32 && buf[p + 10] == 0x2e && buf[p + 11] == 0x30 && // Sub-block\n              buf[p + 12] == 0x03 && buf[p + 13] == 0x01 && buf[p + 16] == 0) {\n                p += 14;\n                loop_count = buf[p++] | buf[p++] << 8;\n                p++; // Skip terminator.\n              } else {\n                // We don't know what it is, just try to get past it.\n                p += 12;\n\n                while (true) {\n                  // Seek through subblocks.\n                  var block_size = buf[p++]; // Bad block size (ex: undefined from an out of bounds read).\n\n                  if (!(block_size >= 0)) throw Error(\"Invalid block size\");\n                  if (block_size === 0) break; // 0 size is terminator\n\n                  p += block_size;\n                }\n              }\n\n              break;\n\n            case 0xf9:\n              // Graphics Control Extension\n              if (buf[p++] !== 0x4 || buf[p + 4] !== 0) throw new Error(\"Invalid graphics extension block.\");\n              var pf1 = buf[p++];\n              delay = buf[p++] | buf[p++] << 8;\n              transparent_index = buf[p++];\n              if ((pf1 & 1) === 0) transparent_index = null;\n              disposal = pf1 >> 2 & 0x7;\n              p++; // Skip terminator.\n\n              break;\n\n            case 0xfe:\n              // Comment Extension.\n              while (true) {\n                // Seek through subblocks.\n                var block_size = buf[p++]; // Bad block size (ex: undefined from an out of bounds read).\n\n                if (!(block_size >= 0)) throw Error(\"Invalid block size\");\n                if (block_size === 0) break; // 0 size is terminator\n                // console.log(buf.slice(p, p+block_size).toString('ascii'));\n\n                p += block_size;\n              }\n\n              break;\n\n            default:\n              throw new Error(\"Unknown graphic control label: 0x\" + buf[p - 1].toString(16));\n          }\n\n          break;\n\n        case 0x2c:\n          // Image Descriptor.\n          var x = buf[p++] | buf[p++] << 8;\n          var y = buf[p++] | buf[p++] << 8;\n          var w = buf[p++] | buf[p++] << 8;\n          var h = buf[p++] | buf[p++] << 8;\n          var pf2 = buf[p++];\n          var local_palette_flag = pf2 >> 7;\n          var interlace_flag = pf2 >> 6 & 1;\n          var num_local_colors_pow2 = pf2 & 0x7;\n          var num_local_colors = 1 << num_local_colors_pow2 + 1;\n          var palette_offset = global_palette_offset;\n          var palette_size = global_palette_size;\n          var has_local_palette = false;\n\n          if (local_palette_flag) {\n            var has_local_palette = true;\n            palette_offset = p; // Override with local palette.\n\n            palette_size = num_local_colors;\n            p += num_local_colors * 3; // Seek past palette.\n          }\n\n          var data_offset = p;\n          p++; // codesize\n\n          while (true) {\n            var block_size = buf[p++]; // Bad block size (ex: undefined from an out of bounds read).\n\n            if (!(block_size >= 0)) throw Error(\"Invalid block size\");\n            if (block_size === 0) break; // 0 size is terminator\n\n            p += block_size;\n          }\n\n          frames.push({\n            x: x,\n            y: y,\n            width: w,\n            height: h,\n            has_local_palette: has_local_palette,\n            palette_offset: palette_offset,\n            palette_size: palette_size,\n            data_offset: data_offset,\n            data_length: p - data_offset,\n            transparent_index: transparent_index,\n            interlaced: !!interlace_flag,\n            delay: delay,\n            disposal: disposal\n          });\n          break;\n\n        case 0x3b:\n          // Trailer Marker (end of file).\n          no_eof = false;\n          break;\n\n        default:\n          throw new Error(\"Unknown gif block: 0x\" + buf[p - 1].toString(16));\n      }\n    }\n\n    this.numFrames = function () {\n      return frames.length;\n    };\n\n    this.loopCount = function () {\n      return loop_count;\n    };\n\n    this.frameInfo = function (frame_num) {\n      if (frame_num < 0 || frame_num >= frames.length) throw new Error(\"Frame index out of range.\");\n      return frames[frame_num];\n    };\n\n    this.decodeAndBlitFrameBGRA = function (frame_num, pixels) {\n      var frame = this.frameInfo(frame_num);\n      var num_pixels = frame.width * frame.height;\n      var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices.\n\n      GifReaderLZWOutputIndexStream(buf, frame.data_offset, index_stream, num_pixels);\n      var palette_offset = frame.palette_offset; // NOTE(deanm): It seems to be much faster to compare index to 256 than\n      // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in\n      // the profile, not sure if it's related to using a Uint8Array.\n\n      var trans = frame.transparent_index;\n      if (trans === null) trans = 256; // We are possibly just blitting to a portion of the entire frame.\n      // That is a subrect within the framerect, so the additional pixels\n      // must be skipped over after we finished a scanline.\n\n      var framewidth = frame.width;\n      var framestride = width - framewidth;\n      var xleft = framewidth; // Number of subrect pixels left in scanline.\n      // Output indices of the top left and bottom right corners of the subrect.\n\n      var opbeg = (frame.y * width + frame.x) * 4;\n      var opend = ((frame.y + frame.height) * width + frame.x) * 4;\n      var op = opbeg;\n      var scanstride = framestride * 4; // Use scanstride to skip past the rows when interlacing.  This is skipping\n      // 7 rows for the first two passes, then 3 then 1.\n\n      if (frame.interlaced === true) {\n        scanstride += width * 4 * 7; // Pass 1.\n      }\n\n      var interlaceskip = 8; // Tracking the row interval in the current pass.\n\n      for (var i = 0, il = index_stream.length; i < il; ++i) {\n        var index = index_stream[i];\n\n        if (xleft === 0) {\n          // Beginning of new scan line\n          op += scanstride;\n          xleft = framewidth;\n\n          if (op >= opend) {\n            // Catch the wrap to switch passes when interlacing.\n            scanstride = framestride * 4 + width * 4 * (interlaceskip - 1); // interlaceskip / 2 * 4 is interlaceskip << 1.\n\n            op = opbeg + (framewidth + framestride) * (interlaceskip << 1);\n            interlaceskip >>= 1;\n          }\n        }\n\n        if (index === trans) {\n          op += 4;\n        } else {\n          var r = buf[palette_offset + index * 3];\n          var g = buf[palette_offset + index * 3 + 1];\n          var b = buf[palette_offset + index * 3 + 2];\n          pixels[op++] = b;\n          pixels[op++] = g;\n          pixels[op++] = r;\n          pixels[op++] = 255;\n        }\n\n        --xleft;\n      }\n    }; // I will go to copy and paste hell one day...\n\n\n    this.decodeAndBlitFrameRGBA = function (frame_num, pixels) {\n      var frame = this.frameInfo(frame_num);\n      var num_pixels = frame.width * frame.height;\n      var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices.\n\n      GifReaderLZWOutputIndexStream(buf, frame.data_offset, index_stream, num_pixels);\n      var palette_offset = frame.palette_offset; // NOTE(deanm): It seems to be much faster to compare index to 256 than\n      // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in\n      // the profile, not sure if it's related to using a Uint8Array.\n\n      var trans = frame.transparent_index;\n      if (trans === null) trans = 256; // We are possibly just blitting to a portion of the entire frame.\n      // That is a subrect within the framerect, so the additional pixels\n      // must be skipped over after we finished a scanline.\n\n      var framewidth = frame.width;\n      var framestride = width - framewidth;\n      var xleft = framewidth; // Number of subrect pixels left in scanline.\n      // Output indices of the top left and bottom right corners of the subrect.\n\n      var opbeg = (frame.y * width + frame.x) * 4;\n      var opend = ((frame.y + frame.height) * width + frame.x) * 4;\n      var op = opbeg;\n      var scanstride = framestride * 4; // Use scanstride to skip past the rows when interlacing.  This is skipping\n      // 7 rows for the first two passes, then 3 then 1.\n\n      if (frame.interlaced === true) {\n        scanstride += width * 4 * 7; // Pass 1.\n      }\n\n      var interlaceskip = 8; // Tracking the row interval in the current pass.\n\n      for (var i = 0, il = index_stream.length; i < il; ++i) {\n        var index = index_stream[i];\n\n        if (xleft === 0) {\n          // Beginning of new scan line\n          op += scanstride;\n          xleft = framewidth;\n\n          if (op >= opend) {\n            // Catch the wrap to switch passes when interlacing.\n            scanstride = framestride * 4 + width * 4 * (interlaceskip - 1); // interlaceskip / 2 * 4 is interlaceskip << 1.\n\n            op = opbeg + (framewidth + framestride) * (interlaceskip << 1);\n            interlaceskip >>= 1;\n          }\n        }\n\n        if (index === trans) {\n          op += 4;\n        } else {\n          var r = buf[palette_offset + index * 3];\n          var g = buf[palette_offset + index * 3 + 1];\n          var b = buf[palette_offset + index * 3 + 2];\n          pixels[op++] = r;\n          pixels[op++] = g;\n          pixels[op++] = b;\n          pixels[op++] = 255;\n        }\n\n        --xleft;\n      }\n    };\n  }\n\n  function GifReaderLZWOutputIndexStream(code_stream, p, output, output_length) {\n    var min_code_size = code_stream[p++];\n    var clear_code = 1 << min_code_size;\n    var eoi_code = clear_code + 1;\n    var next_code = eoi_code + 1;\n    var cur_code_size = min_code_size + 1; // Number of bits per code.\n    // NOTE: This shares the same name as the encoder, but has a different\n    // meaning here.  Here this masks each code coming from the code stream.\n\n    var code_mask = (1 << cur_code_size) - 1;\n    var cur_shift = 0;\n    var cur = 0;\n    var op = 0; // Output pointer.\n\n    var subblock_size = code_stream[p++]; // TODO(deanm): Would using a TypedArray be any faster?  At least it would\n    // solve the fast mode / backing store uncertainty.\n    // var code_table = Array(4096);\n\n    var code_table = new Int32Array(4096); // Can be signed, we only use 20 bits.\n\n    var prev_code = null; // Track code-1.\n\n    while (true) {\n      // Read up to two bytes, making sure we always 12-bits for max sized code.\n      while (cur_shift < 16) {\n        if (subblock_size === 0) break; // No more data to be read.\n\n        cur |= code_stream[p++] << cur_shift;\n        cur_shift += 8;\n\n        if (subblock_size === 1) {\n          // Never let it get to 0 to hold logic above.\n          subblock_size = code_stream[p++]; // Next subblock.\n        } else {\n          --subblock_size;\n        }\n      } // TODO(deanm): We should never really get here, we should have received\n      // and EOI.\n\n\n      if (cur_shift < cur_code_size) break;\n      var code = cur & code_mask;\n      cur >>= cur_code_size;\n      cur_shift -= cur_code_size; // TODO(deanm): Maybe should check that the first code was a clear code,\n      // at least this is what you're supposed to do.  But actually our encoder\n      // now doesn't emit a clear code first anyway.\n\n      if (code === clear_code) {\n        // We don't actually have to clear the table.  This could be a good idea\n        // for greater error checking, but we don't really do any anyway.  We\n        // will just track it with next_code and overwrite old entries.\n        next_code = eoi_code + 1;\n        cur_code_size = min_code_size + 1;\n        code_mask = (1 << cur_code_size) - 1; // Don't update prev_code ?\n\n        prev_code = null;\n        continue;\n      } else if (code === eoi_code) {\n        break;\n      } // We have a similar situation as the decoder, where we want to store\n      // variable length entries (code table entries), but we want to do in a\n      // faster manner than an array of arrays.  The code below stores sort of a\n      // linked list within the code table, and then \"chases\" through it to\n      // construct the dictionary entries.  When a new entry is created, just the\n      // last byte is stored, and the rest (prefix) of the entry is only\n      // referenced by its table entry.  Then the code chases through the\n      // prefixes until it reaches a single byte code.  We have to chase twice,\n      // first to compute the length, and then to actually copy the data to the\n      // output (backwards, since we know the length).  The alternative would be\n      // storing something in an intermediate stack, but that doesn't make any\n      // more sense.  I implemented an approach where it also stored the length\n      // in the code table, although it's a bit tricky because you run out of\n      // bits (12 + 12 + 8), but I didn't measure much improvements (the table\n      // entries are generally not the long).  Even when I created benchmarks for\n      // very long table entries the complexity did not seem worth it.\n      // The code table stores the prefix entry in 12 bits and then the suffix\n      // byte in 8 bits, so each entry is 20 bits.\n\n\n      var chase_code = code < next_code ? code : prev_code; // Chase what we will output, either {CODE} or {CODE-1}.\n\n      var chase_length = 0;\n      var chase = chase_code;\n\n      while (chase > clear_code) {\n        chase = code_table[chase] >> 8;\n        ++chase_length;\n      }\n\n      var k = chase;\n      var op_end = op + chase_length + (chase_code !== code ? 1 : 0);\n\n      if (op_end > output_length) {\n        console.log(\"Warning, gif stream longer than expected.\");\n        return;\n      } // Already have the first byte from the chase, might as well write it fast.\n\n\n      output[op++] = k;\n      op += chase_length;\n      var b = op; // Track pointer, writing backwards.\n\n      if (chase_code !== code) // The case of emitting {CODE-1} + k.\n        output[op++] = k;\n      chase = chase_code;\n\n      while (chase_length--) {\n        chase = code_table[chase];\n        output[--b] = chase & 0xff; // Write backwards.\n\n        chase >>= 8; // Pull down to the prefix code.\n      }\n\n      if (prev_code !== null && next_code < 4096) {\n        code_table[next_code++] = prev_code << 8 | k; // TODO(deanm): Figure out this clearing vs code growth logic better.  I\n        // have an feeling that it should just happen somewhere else, for now it\n        // is awkward between when we grow past the max and then hit a clear code.\n        // For now just check if we hit the max 12-bits (then a clear code should\n        // follow, also of course encoded in 12-bits).\n\n        if (next_code >= code_mask + 1 && cur_code_size < 12) {\n          ++cur_code_size;\n          code_mask = code_mask << 1 | 1;\n        }\n      }\n\n      prev_code = code;\n    }\n\n    if (op !== output_length) {\n      console.log(\"Warning, gif stream shorter than expected.\");\n    }\n\n    return output;\n  }\n\n  /**\n   * @license\n    Copyright (c) 2008, Adobe Systems Incorporated\n    All rights reserved.\n\n    Redistribution and use in source and binary forms, with or without \n    modification, are permitted provided that the following conditions are\n    met:\n\n    * Redistributions of source code must retain the above copyright notice, \n      this list of conditions and the following disclaimer.\n    \n    * Redistributions in binary form must reproduce the above copyright\n      notice, this list of conditions and the following disclaimer in the \n      documentation and/or other materials provided with the distribution.\n    \n    * Neither the name of Adobe Systems Incorporated nor the names of its \n      contributors may be used to endorse or promote products derived from \n      this software without specific prior written permission.\n\n    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\n    IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \n    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n  */\n\n  /*\n  JPEG encoder ported to JavaScript and optimized by Andreas Ritter, www.bytestrom.eu, 11/2009\n\n  Basic GUI blocking jpeg encoder\n  */\n  function JPEGEncoder(quality) {\n    var ffloor = Math.floor;\n    var YTable = new Array(64);\n    var UVTable = new Array(64);\n    var fdtbl_Y = new Array(64);\n    var fdtbl_UV = new Array(64);\n    var YDC_HT;\n    var UVDC_HT;\n    var YAC_HT;\n    var UVAC_HT;\n    var bitcode = new Array(65535);\n    var category = new Array(65535);\n    var outputfDCTQuant = new Array(64);\n    var DU = new Array(64);\n    var byteout = [];\n    var bytenew = 0;\n    var bytepos = 7;\n    var YDU = new Array(64);\n    var UDU = new Array(64);\n    var VDU = new Array(64);\n    var clt = new Array(256);\n    var RGB_YUV_TABLE = new Array(2048);\n    var currentQuality;\n    var ZigZag = [0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63];\n    var std_dc_luminance_nrcodes = [0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0];\n    var std_dc_luminance_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];\n    var std_ac_luminance_nrcodes = [0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d];\n    var std_ac_luminance_values = [0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa];\n    var std_dc_chrominance_nrcodes = [0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0];\n    var std_dc_chrominance_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];\n    var std_ac_chrominance_nrcodes = [0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77];\n    var std_ac_chrominance_values = [0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa];\n\n    function initQuantTables(sf) {\n      var YQT = [16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99];\n\n      for (var i = 0; i < 64; i++) {\n        var t = ffloor((YQT[i] * sf + 50) / 100);\n        t = Math.min(Math.max(t, 1), 255);\n        YTable[ZigZag[i]] = t;\n      }\n\n      var UVQT = [17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99];\n\n      for (var j = 0; j < 64; j++) {\n        var u = ffloor((UVQT[j] * sf + 50) / 100);\n        u = Math.min(Math.max(u, 1), 255);\n        UVTable[ZigZag[j]] = u;\n      }\n\n      var aasf = [1.0, 1.387039845, 1.306562965, 1.175875602, 1.0, 0.785694958, 0.5411961, 0.275899379];\n      var k = 0;\n\n      for (var row = 0; row < 8; row++) {\n        for (var col = 0; col < 8; col++) {\n          fdtbl_Y[k] = 1.0 / (YTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0);\n          fdtbl_UV[k] = 1.0 / (UVTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0);\n          k++;\n        }\n      }\n    }\n\n    function computeHuffmanTbl(nrcodes, std_table) {\n      var codevalue = 0;\n      var pos_in_table = 0;\n      var HT = new Array();\n\n      for (var k = 1; k <= 16; k++) {\n        for (var j = 1; j <= nrcodes[k]; j++) {\n          HT[std_table[pos_in_table]] = [];\n          HT[std_table[pos_in_table]][0] = codevalue;\n          HT[std_table[pos_in_table]][1] = k;\n          pos_in_table++;\n          codevalue++;\n        }\n\n        codevalue *= 2;\n      }\n\n      return HT;\n    }\n\n    function initHuffmanTbl() {\n      YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes, std_dc_luminance_values);\n      UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes, std_dc_chrominance_values);\n      YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes, std_ac_luminance_values);\n      UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes, std_ac_chrominance_values);\n    }\n\n    function initCategoryNumber() {\n      var nrlower = 1;\n      var nrupper = 2;\n\n      for (var cat = 1; cat <= 15; cat++) {\n        //Positive numbers\n        for (var nr = nrlower; nr < nrupper; nr++) {\n          category[32767 + nr] = cat;\n          bitcode[32767 + nr] = [];\n          bitcode[32767 + nr][1] = cat;\n          bitcode[32767 + nr][0] = nr;\n        } //Negative numbers\n\n\n        for (var nrneg = -(nrupper - 1); nrneg <= -nrlower; nrneg++) {\n          category[32767 + nrneg] = cat;\n          bitcode[32767 + nrneg] = [];\n          bitcode[32767 + nrneg][1] = cat;\n          bitcode[32767 + nrneg][0] = nrupper - 1 + nrneg;\n        }\n\n        nrlower <<= 1;\n        nrupper <<= 1;\n      }\n    }\n\n    function initRGBYUVTable() {\n      for (var i = 0; i < 256; i++) {\n        RGB_YUV_TABLE[i] = 19595 * i;\n        RGB_YUV_TABLE[i + 256 >> 0] = 38470 * i;\n        RGB_YUV_TABLE[i + 512 >> 0] = 7471 * i + 0x8000;\n        RGB_YUV_TABLE[i + 768 >> 0] = -11059 * i;\n        RGB_YUV_TABLE[i + 1024 >> 0] = -21709 * i;\n        RGB_YUV_TABLE[i + 1280 >> 0] = 32768 * i + 0x807fff;\n        RGB_YUV_TABLE[i + 1536 >> 0] = -27439 * i;\n        RGB_YUV_TABLE[i + 1792 >> 0] = -5329 * i;\n      }\n    } // IO functions\n\n\n    function writeBits(bs) {\n      var value = bs[0];\n      var posval = bs[1] - 1;\n\n      while (posval >= 0) {\n        if (value & 1 << posval) {\n          bytenew |= 1 << bytepos;\n        }\n\n        posval--;\n        bytepos--;\n\n        if (bytepos < 0) {\n          if (bytenew == 0xff) {\n            writeByte(0xff);\n            writeByte(0);\n          } else {\n            writeByte(bytenew);\n          }\n\n          bytepos = 7;\n          bytenew = 0;\n        }\n      }\n    }\n\n    function writeByte(value) {\n      //byteout.push(clt[value]); // write char directly instead of converting later\n      byteout.push(value);\n    }\n\n    function writeWord(value) {\n      writeByte(value >> 8 & 0xff);\n      writeByte(value & 0xff);\n    } // DCT & quantization core\n\n\n    function fDCTQuant(data, fdtbl) {\n      var d0, d1, d2, d3, d4, d5, d6, d7;\n      /* Pass 1: process rows. */\n\n      var dataOff = 0;\n      var i;\n      var I8 = 8;\n      var I64 = 64;\n\n      for (i = 0; i < I8; ++i) {\n        d0 = data[dataOff];\n        d1 = data[dataOff + 1];\n        d2 = data[dataOff + 2];\n        d3 = data[dataOff + 3];\n        d4 = data[dataOff + 4];\n        d5 = data[dataOff + 5];\n        d6 = data[dataOff + 6];\n        d7 = data[dataOff + 7];\n        var tmp0 = d0 + d7;\n        var tmp7 = d0 - d7;\n        var tmp1 = d1 + d6;\n        var tmp6 = d1 - d6;\n        var tmp2 = d2 + d5;\n        var tmp5 = d2 - d5;\n        var tmp3 = d3 + d4;\n        var tmp4 = d3 - d4;\n        /* Even part */\n\n        var tmp10 = tmp0 + tmp3;\n        /* phase 2 */\n\n        var tmp13 = tmp0 - tmp3;\n        var tmp11 = tmp1 + tmp2;\n        var tmp12 = tmp1 - tmp2;\n        data[dataOff] = tmp10 + tmp11;\n        /* phase 3 */\n\n        data[dataOff + 4] = tmp10 - tmp11;\n        var z1 = (tmp12 + tmp13) * 0.707106781;\n        /* c4 */\n\n        data[dataOff + 2] = tmp13 + z1;\n        /* phase 5 */\n\n        data[dataOff + 6] = tmp13 - z1;\n        /* Odd part */\n\n        tmp10 = tmp4 + tmp5;\n        /* phase 2 */\n\n        tmp11 = tmp5 + tmp6;\n        tmp12 = tmp6 + tmp7;\n        /* The rotator is modified from fig 4-8 to avoid extra negations. */\n\n        var z5 = (tmp10 - tmp12) * 0.382683433;\n        /* c6 */\n\n        var z2 = 0.5411961 * tmp10 + z5;\n        /* c2-c6 */\n\n        var z4 = 1.306562965 * tmp12 + z5;\n        /* c2+c6 */\n\n        var z3 = tmp11 * 0.707106781;\n        /* c4 */\n\n        var z11 = tmp7 + z3;\n        /* phase 5 */\n\n        var z13 = tmp7 - z3;\n        data[dataOff + 5] = z13 + z2;\n        /* phase 6 */\n\n        data[dataOff + 3] = z13 - z2;\n        data[dataOff + 1] = z11 + z4;\n        data[dataOff + 7] = z11 - z4;\n        dataOff += 8;\n        /* advance pointer to next row */\n      }\n      /* Pass 2: process columns. */\n\n\n      dataOff = 0;\n\n      for (i = 0; i < I8; ++i) {\n        d0 = data[dataOff];\n        d1 = data[dataOff + 8];\n        d2 = data[dataOff + 16];\n        d3 = data[dataOff + 24];\n        d4 = data[dataOff + 32];\n        d5 = data[dataOff + 40];\n        d6 = data[dataOff + 48];\n        d7 = data[dataOff + 56];\n        var tmp0p2 = d0 + d7;\n        var tmp7p2 = d0 - d7;\n        var tmp1p2 = d1 + d6;\n        var tmp6p2 = d1 - d6;\n        var tmp2p2 = d2 + d5;\n        var tmp5p2 = d2 - d5;\n        var tmp3p2 = d3 + d4;\n        var tmp4p2 = d3 - d4;\n        /* Even part */\n\n        var tmp10p2 = tmp0p2 + tmp3p2;\n        /* phase 2 */\n\n        var tmp13p2 = tmp0p2 - tmp3p2;\n        var tmp11p2 = tmp1p2 + tmp2p2;\n        var tmp12p2 = tmp1p2 - tmp2p2;\n        data[dataOff] = tmp10p2 + tmp11p2;\n        /* phase 3 */\n\n        data[dataOff + 32] = tmp10p2 - tmp11p2;\n        var z1p2 = (tmp12p2 + tmp13p2) * 0.707106781;\n        /* c4 */\n\n        data[dataOff + 16] = tmp13p2 + z1p2;\n        /* phase 5 */\n\n        data[dataOff + 48] = tmp13p2 - z1p2;\n        /* Odd part */\n\n        tmp10p2 = tmp4p2 + tmp5p2;\n        /* phase 2 */\n\n        tmp11p2 = tmp5p2 + tmp6p2;\n        tmp12p2 = tmp6p2 + tmp7p2;\n        /* The rotator is modified from fig 4-8 to avoid extra negations. */\n\n        var z5p2 = (tmp10p2 - tmp12p2) * 0.382683433;\n        /* c6 */\n\n        var z2p2 = 0.5411961 * tmp10p2 + z5p2;\n        /* c2-c6 */\n\n        var z4p2 = 1.306562965 * tmp12p2 + z5p2;\n        /* c2+c6 */\n\n        var z3p2 = tmp11p2 * 0.707106781;\n        /* c4 */\n\n        var z11p2 = tmp7p2 + z3p2;\n        /* phase 5 */\n\n        var z13p2 = tmp7p2 - z3p2;\n        data[dataOff + 40] = z13p2 + z2p2;\n        /* phase 6 */\n\n        data[dataOff + 24] = z13p2 - z2p2;\n        data[dataOff + 8] = z11p2 + z4p2;\n        data[dataOff + 56] = z11p2 - z4p2;\n        dataOff++;\n        /* advance pointer to next column */\n      } // Quantize/descale the coefficients\n\n\n      var fDCTQuant;\n\n      for (i = 0; i < I64; ++i) {\n        // Apply the quantization and scaling factor & Round to nearest integer\n        fDCTQuant = data[i] * fdtbl[i];\n        outputfDCTQuant[i] = fDCTQuant > 0.0 ? fDCTQuant + 0.5 | 0 : fDCTQuant - 0.5 | 0; //outputfDCTQuant[i] = fround(fDCTQuant);\n      }\n\n      return outputfDCTQuant;\n    }\n\n    function writeAPP0() {\n      writeWord(0xffe0); // marker\n\n      writeWord(16); // length\n\n      writeByte(0x4a); // J\n\n      writeByte(0x46); // F\n\n      writeByte(0x49); // I\n\n      writeByte(0x46); // F\n\n      writeByte(0); // = \"JFIF\",'\\0'\n\n      writeByte(1); // versionhi\n\n      writeByte(1); // versionlo\n\n      writeByte(0); // xyunits\n\n      writeWord(1); // xdensity\n\n      writeWord(1); // ydensity\n\n      writeByte(0); // thumbnwidth\n\n      writeByte(0); // thumbnheight\n    }\n\n    function writeSOF0(width, height) {\n      writeWord(0xffc0); // marker\n\n      writeWord(17); // length, truecolor YUV JPG\n\n      writeByte(8); // precision\n\n      writeWord(height);\n      writeWord(width);\n      writeByte(3); // nrofcomponents\n\n      writeByte(1); // IdY\n\n      writeByte(0x11); // HVY\n\n      writeByte(0); // QTY\n\n      writeByte(2); // IdU\n\n      writeByte(0x11); // HVU\n\n      writeByte(1); // QTU\n\n      writeByte(3); // IdV\n\n      writeByte(0x11); // HVV\n\n      writeByte(1); // QTV\n    }\n\n    function writeDQT() {\n      writeWord(0xffdb); // marker\n\n      writeWord(132); // length\n\n      writeByte(0);\n\n      for (var i = 0; i < 64; i++) {\n        writeByte(YTable[i]);\n      }\n\n      writeByte(1);\n\n      for (var j = 0; j < 64; j++) {\n        writeByte(UVTable[j]);\n      }\n    }\n\n    function writeDHT() {\n      writeWord(0xffc4); // marker\n\n      writeWord(0x01a2); // length\n\n      writeByte(0); // HTYDCinfo\n\n      for (var i = 0; i < 16; i++) {\n        writeByte(std_dc_luminance_nrcodes[i + 1]);\n      }\n\n      for (var j = 0; j <= 11; j++) {\n        writeByte(std_dc_luminance_values[j]);\n      }\n\n      writeByte(0x10); // HTYACinfo\n\n      for (var k = 0; k < 16; k++) {\n        writeByte(std_ac_luminance_nrcodes[k + 1]);\n      }\n\n      for (var l = 0; l <= 161; l++) {\n        writeByte(std_ac_luminance_values[l]);\n      }\n\n      writeByte(1); // HTUDCinfo\n\n      for (var m = 0; m < 16; m++) {\n        writeByte(std_dc_chrominance_nrcodes[m + 1]);\n      }\n\n      for (var n = 0; n <= 11; n++) {\n        writeByte(std_dc_chrominance_values[n]);\n      }\n\n      writeByte(0x11); // HTUACinfo\n\n      for (var o = 0; o < 16; o++) {\n        writeByte(std_ac_chrominance_nrcodes[o + 1]);\n      }\n\n      for (var p = 0; p <= 161; p++) {\n        writeByte(std_ac_chrominance_values[p]);\n      }\n    }\n\n    function writeSOS() {\n      writeWord(0xffda); // marker\n\n      writeWord(12); // length\n\n      writeByte(3); // nrofcomponents\n\n      writeByte(1); // IdY\n\n      writeByte(0); // HTY\n\n      writeByte(2); // IdU\n\n      writeByte(0x11); // HTU\n\n      writeByte(3); // IdV\n\n      writeByte(0x11); // HTV\n\n      writeByte(0); // Ss\n\n      writeByte(0x3f); // Se\n\n      writeByte(0); // Bf\n    }\n\n    function processDU(CDU, fdtbl, DC, HTDC, HTAC) {\n      var EOB = HTAC[0x00];\n      var M16zeroes = HTAC[0xf0];\n      var pos;\n      var I16 = 16;\n      var I63 = 63;\n      var I64 = 64;\n      var DU_DCT = fDCTQuant(CDU, fdtbl); //ZigZag reorder\n\n      for (var j = 0; j < I64; ++j) {\n        DU[ZigZag[j]] = DU_DCT[j];\n      }\n\n      var Diff = DU[0] - DC;\n      DC = DU[0]; //Encode DC\n\n      if (Diff == 0) {\n        writeBits(HTDC[0]); // Diff might be 0\n      } else {\n        pos = 32767 + Diff;\n        writeBits(HTDC[category[pos]]);\n        writeBits(bitcode[pos]);\n      } //Encode ACs\n\n\n      var end0pos = 63; // was const... which is crazy\n\n      while (end0pos > 0 && DU[end0pos] == 0) {\n        end0pos--;\n      } //end0pos = first element in reverse order !=0\n\n\n      if (end0pos == 0) {\n        writeBits(EOB);\n        return DC;\n      }\n\n      var i = 1;\n      var lng;\n\n      while (i <= end0pos) {\n        var startpos = i;\n\n        while (DU[i] == 0 && i <= end0pos) {\n          ++i;\n        }\n\n        var nrzeroes = i - startpos;\n\n        if (nrzeroes >= I16) {\n          lng = nrzeroes >> 4;\n\n          for (var nrmarker = 1; nrmarker <= lng; ++nrmarker) {\n            writeBits(M16zeroes);\n          }\n\n          nrzeroes = nrzeroes & 0xf;\n        }\n\n        pos = 32767 + DU[i];\n        writeBits(HTAC[(nrzeroes << 4) + category[pos]]);\n        writeBits(bitcode[pos]);\n        i++;\n      }\n\n      if (end0pos != I63) {\n        writeBits(EOB);\n      }\n\n      return DC;\n    }\n\n    function initCharLookupTable() {\n      var sfcc = String.fromCharCode;\n\n      for (var i = 0; i < 256; i++) {\n        ///// ACHTUNG // 255\n        clt[i] = sfcc(i);\n      }\n    }\n\n    this.encode = function (image, quality // image data object\n    ) {\n      if (quality) setQuality(quality); // Initialize bit writer\n\n      byteout = new Array();\n      bytenew = 0;\n      bytepos = 7; // Add JPEG headers\n\n      writeWord(0xffd8); // SOI\n\n      writeAPP0();\n      writeDQT();\n      writeSOF0(image.width, image.height);\n      writeDHT();\n      writeSOS(); // Encode 8x8 macroblocks\n\n      var DCY = 0;\n      var DCU = 0;\n      var DCV = 0;\n      bytenew = 0;\n      bytepos = 7;\n      this.encode.displayName = \"_encode_\";\n      var imageData = image.data;\n      var width = image.width;\n      var height = image.height;\n      var quadWidth = width * 4;\n      var x,\n          y = 0;\n      var r, g, b;\n      var start, p, col, row, pos;\n\n      while (y < height) {\n        x = 0;\n\n        while (x < quadWidth) {\n          start = quadWidth * y + x;\n          col = -1;\n          row = 0;\n\n          for (pos = 0; pos < 64; pos++) {\n            row = pos >> 3; // /8\n\n            col = (pos & 7) * 4; // %8\n\n            p = start + row * quadWidth + col;\n\n            if (y + row >= height) {\n              // padding bottom\n              p -= quadWidth * (y + 1 + row - height);\n            }\n\n            if (x + col >= quadWidth) {\n              // padding right\n              p -= x + col - quadWidth + 4;\n            }\n\n            r = imageData[p++];\n            g = imageData[p++];\n            b = imageData[p++];\n            /* // calculate YUV values dynamically\n            YDU[pos]=((( 0.29900)*r+( 0.58700)*g+( 0.11400)*b))-128; //-0x80\n            UDU[pos]=(((-0.16874)*r+(-0.33126)*g+( 0.50000)*b));\n            VDU[pos]=((( 0.50000)*r+(-0.41869)*g+(-0.08131)*b));\n            */\n            // use lookup table (slightly faster)\n\n            YDU[pos] = (RGB_YUV_TABLE[r] + RGB_YUV_TABLE[g + 256 >> 0] + RGB_YUV_TABLE[b + 512 >> 0] >> 16) - 128;\n            UDU[pos] = (RGB_YUV_TABLE[r + 768 >> 0] + RGB_YUV_TABLE[g + 1024 >> 0] + RGB_YUV_TABLE[b + 1280 >> 0] >> 16) - 128;\n            VDU[pos] = (RGB_YUV_TABLE[r + 1280 >> 0] + RGB_YUV_TABLE[g + 1536 >> 0] + RGB_YUV_TABLE[b + 1792 >> 0] >> 16) - 128;\n          }\n\n          DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);\n          DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);\n          DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);\n          x += 32;\n        }\n\n        y += 8;\n      } ////////////////////////////////////////////////////////////////\n      // Do the bit alignment of the EOI marker\n\n\n      if (bytepos >= 0) {\n        var fillbits = [];\n        fillbits[1] = bytepos + 1;\n        fillbits[0] = (1 << bytepos + 1) - 1;\n        writeBits(fillbits);\n      }\n\n      writeWord(0xffd9); //EOI\n\n      return new Uint8Array(byteout);\n    };\n\n    function setQuality(quality) {\n      quality = Math.min(Math.max(quality, 1), 100);\n      if (currentQuality == quality) return; // don't recalc if unchanged\n\n      var sf = quality < 50 ? Math.floor(5000 / quality) : Math.floor(200 - quality * 2);\n      initQuantTables(sf);\n      currentQuality = quality; //console.log('Quality set to: '+quality +'%');\n    }\n\n    function init() {\n      quality = quality || 50; // Create tables\n\n      initCharLookupTable();\n      initHuffmanTbl();\n      initCategoryNumber();\n      initRGBYUVTable();\n      setQuality(quality);\n    }\n\n    init();\n  }\n\n  /**\n   * @license\n   * Copyright (c) 2017 Aras Abbasi\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n  /**\n   * jsPDF Gif Support PlugIn\n   *\n   * @name gif_support\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n\n    jsPDFAPI.processGIF89A = function (imageData, index, alias, compression) {\n      var reader = new GifReader(imageData);\n      var width = reader.width,\n          height = reader.height;\n      var qu = 100;\n      var pixels = [];\n      reader.decodeAndBlitFrameRGBA(0, pixels);\n      var rawImageData = {\n        data: pixels,\n        width: width,\n        height: height\n      };\n      var encoder = new JPEGEncoder(qu);\n      var data = encoder.encode(rawImageData, qu);\n      return jsPDFAPI.processJPEG.call(this, data, index, alias, compression);\n    };\n\n    jsPDFAPI.processGIF87A = jsPDFAPI.processGIF89A;\n  })(jsPDF.API);\n\n  /**\n   * @author shaozilee\n   *\n   * Bmp format decoder,support 1bit 4bit 8bit 24bit bmp\n   *\n   */\n\n  function BmpDecoder(buffer, is_with_alpha) {\n    this.pos = 0;\n    this.buffer = buffer;\n    this.datav = new DataView(buffer.buffer);\n    this.is_with_alpha = !!is_with_alpha;\n    this.bottom_up = true;\n    this.flag = String.fromCharCode(this.buffer[0]) + String.fromCharCode(this.buffer[1]);\n    this.pos += 2;\n    if ([\"BM\", \"BA\", \"CI\", \"CP\", \"IC\", \"PT\"].indexOf(this.flag) === -1) throw new Error(\"Invalid BMP File\");\n    this.parseHeader();\n    this.parseBGR();\n  }\n\n  BmpDecoder.prototype.parseHeader = function () {\n    this.fileSize = this.datav.getUint32(this.pos, true);\n    this.pos += 4;\n    this.reserved = this.datav.getUint32(this.pos, true);\n    this.pos += 4;\n    this.offset = this.datav.getUint32(this.pos, true);\n    this.pos += 4;\n    this.headerSize = this.datav.getUint32(this.pos, true);\n    this.pos += 4;\n    this.width = this.datav.getUint32(this.pos, true);\n    this.pos += 4;\n    this.height = this.datav.getInt32(this.pos, true);\n    this.pos += 4;\n    this.planes = this.datav.getUint16(this.pos, true);\n    this.pos += 2;\n    this.bitPP = this.datav.getUint16(this.pos, true);\n    this.pos += 2;\n    this.compress = this.datav.getUint32(this.pos, true);\n    this.pos += 4;\n    this.rawSize = this.datav.getUint32(this.pos, true);\n    this.pos += 4;\n    this.hr = this.datav.getUint32(this.pos, true);\n    this.pos += 4;\n    this.vr = this.datav.getUint32(this.pos, true);\n    this.pos += 4;\n    this.colors = this.datav.getUint32(this.pos, true);\n    this.pos += 4;\n    this.importantColors = this.datav.getUint32(this.pos, true);\n    this.pos += 4;\n\n    if (this.bitPP === 16 && this.is_with_alpha) {\n      this.bitPP = 15;\n    }\n\n    if (this.bitPP < 15) {\n      var len = this.colors === 0 ? 1 << this.bitPP : this.colors;\n      this.palette = new Array(len);\n\n      for (var i = 0; i < len; i++) {\n        var blue = this.datav.getUint8(this.pos++, true);\n        var green = this.datav.getUint8(this.pos++, true);\n        var red = this.datav.getUint8(this.pos++, true);\n        var quad = this.datav.getUint8(this.pos++, true);\n        this.palette[i] = {\n          red: red,\n          green: green,\n          blue: blue,\n          quad: quad\n        };\n      }\n    }\n\n    if (this.height < 0) {\n      this.height *= -1;\n      this.bottom_up = false;\n    }\n  };\n\n  BmpDecoder.prototype.parseBGR = function () {\n    this.pos = this.offset;\n\n    try {\n      var bitn = \"bit\" + this.bitPP;\n      var len = this.width * this.height * 4;\n      this.data = new Uint8Array(len);\n      this[bitn]();\n    } catch (e) {\n      console.log(\"bit decode error:\" + e);\n    }\n  };\n\n  BmpDecoder.prototype.bit1 = function () {\n    var xlen = Math.ceil(this.width / 8);\n    var mode = xlen % 4;\n    var y;\n\n    for (y = this.height - 1; y >= 0; y--) {\n      var line = this.bottom_up ? y : this.height - 1 - y;\n\n      for (var x = 0; x < xlen; x++) {\n        var b = this.datav.getUint8(this.pos++, true);\n        var location = line * this.width * 4 + x * 8 * 4;\n\n        for (var i = 0; i < 8; i++) {\n          if (x * 8 + i < this.width) {\n            var rgb = this.palette[b >> 7 - i & 0x1];\n            this.data[location + i * 4] = rgb.blue;\n            this.data[location + i * 4 + 1] = rgb.green;\n            this.data[location + i * 4 + 2] = rgb.red;\n            this.data[location + i * 4 + 3] = 0xff;\n          } else {\n            break;\n          }\n        }\n      }\n\n      if (mode !== 0) {\n        this.pos += 4 - mode;\n      }\n    }\n  };\n\n  BmpDecoder.prototype.bit4 = function () {\n    var xlen = Math.ceil(this.width / 2);\n    var mode = xlen % 4;\n\n    for (var y = this.height - 1; y >= 0; y--) {\n      var line = this.bottom_up ? y : this.height - 1 - y;\n\n      for (var x = 0; x < xlen; x++) {\n        var b = this.datav.getUint8(this.pos++, true);\n        var location = line * this.width * 4 + x * 2 * 4;\n        var before = b >> 4;\n        var after = b & 0x0f;\n        var rgb = this.palette[before];\n        this.data[location] = rgb.blue;\n        this.data[location + 1] = rgb.green;\n        this.data[location + 2] = rgb.red;\n        this.data[location + 3] = 0xff;\n        if (x * 2 + 1 >= this.width) break;\n        rgb = this.palette[after];\n        this.data[location + 4] = rgb.blue;\n        this.data[location + 4 + 1] = rgb.green;\n        this.data[location + 4 + 2] = rgb.red;\n        this.data[location + 4 + 3] = 0xff;\n      }\n\n      if (mode !== 0) {\n        this.pos += 4 - mode;\n      }\n    }\n  };\n\n  BmpDecoder.prototype.bit8 = function () {\n    var mode = this.width % 4;\n\n    for (var y = this.height - 1; y >= 0; y--) {\n      var line = this.bottom_up ? y : this.height - 1 - y;\n\n      for (var x = 0; x < this.width; x++) {\n        var b = this.datav.getUint8(this.pos++, true);\n        var location = line * this.width * 4 + x * 4;\n\n        if (b < this.palette.length) {\n          var rgb = this.palette[b];\n          this.data[location] = rgb.red;\n          this.data[location + 1] = rgb.green;\n          this.data[location + 2] = rgb.blue;\n          this.data[location + 3] = 0xff;\n        } else {\n          this.data[location] = 0xff;\n          this.data[location + 1] = 0xff;\n          this.data[location + 2] = 0xff;\n          this.data[location + 3] = 0xff;\n        }\n      }\n\n      if (mode !== 0) {\n        this.pos += 4 - mode;\n      }\n    }\n  };\n\n  BmpDecoder.prototype.bit15 = function () {\n    var dif_w = this.width % 3;\n\n    var _11111 = parseInt(\"11111\", 2),\n        _1_5 = _11111;\n\n    for (var y = this.height - 1; y >= 0; y--) {\n      var line = this.bottom_up ? y : this.height - 1 - y;\n\n      for (var x = 0; x < this.width; x++) {\n        var B = this.datav.getUint16(this.pos, true);\n        this.pos += 2;\n        var blue = (B & _1_5) / _1_5 * 255 | 0;\n        var green = (B >> 5 & _1_5) / _1_5 * 255 | 0;\n        var red = (B >> 10 & _1_5) / _1_5 * 255 | 0;\n        var alpha = B >> 15 ? 0xff : 0x00;\n        var location = line * this.width * 4 + x * 4;\n        this.data[location] = red;\n        this.data[location + 1] = green;\n        this.data[location + 2] = blue;\n        this.data[location + 3] = alpha;\n      } //skip extra bytes\n\n\n      this.pos += dif_w;\n    }\n  };\n\n  BmpDecoder.prototype.bit16 = function () {\n    var dif_w = this.width % 3;\n\n    var _11111 = parseInt(\"11111\", 2),\n        _1_5 = _11111;\n\n    var _111111 = parseInt(\"111111\", 2),\n        _1_6 = _111111;\n\n    for (var y = this.height - 1; y >= 0; y--) {\n      var line = this.bottom_up ? y : this.height - 1 - y;\n\n      for (var x = 0; x < this.width; x++) {\n        var B = this.datav.getUint16(this.pos, true);\n        this.pos += 2;\n        var alpha = 0xff;\n        var blue = (B & _1_5) / _1_5 * 255 | 0;\n        var green = (B >> 5 & _1_6) / _1_6 * 255 | 0;\n        var red = (B >> 11) / _1_5 * 255 | 0;\n        var location = line * this.width * 4 + x * 4;\n        this.data[location] = red;\n        this.data[location + 1] = green;\n        this.data[location + 2] = blue;\n        this.data[location + 3] = alpha;\n      } //skip extra bytes\n\n\n      this.pos += dif_w;\n    }\n  };\n\n  BmpDecoder.prototype.bit24 = function () {\n    //when height > 0\n    for (var y = this.height - 1; y >= 0; y--) {\n      var line = this.bottom_up ? y : this.height - 1 - y;\n\n      for (var x = 0; x < this.width; x++) {\n        var blue = this.datav.getUint8(this.pos++, true);\n        var green = this.datav.getUint8(this.pos++, true);\n        var red = this.datav.getUint8(this.pos++, true);\n        var location = line * this.width * 4 + x * 4;\n        this.data[location] = red;\n        this.data[location + 1] = green;\n        this.data[location + 2] = blue;\n        this.data[location + 3] = 0xff;\n      } //skip extra bytes\n\n\n      this.pos += this.width % 4;\n    }\n  };\n  /**\n   * add 32bit decode func\n   * @author soubok\n   */\n\n\n  BmpDecoder.prototype.bit32 = function () {\n    //when height > 0\n    for (var y = this.height - 1; y >= 0; y--) {\n      var line = this.bottom_up ? y : this.height - 1 - y;\n\n      for (var x = 0; x < this.width; x++) {\n        var blue = this.datav.getUint8(this.pos++, true);\n        var green = this.datav.getUint8(this.pos++, true);\n        var red = this.datav.getUint8(this.pos++, true);\n        var alpha = this.datav.getUint8(this.pos++, true);\n        var location = line * this.width * 4 + x * 4;\n        this.data[location] = red;\n        this.data[location + 1] = green;\n        this.data[location + 2] = blue;\n        this.data[location + 3] = alpha;\n      } //skip extra bytes\n      //this.pos += (this.width % 4);\n\n    }\n  };\n\n  BmpDecoder.prototype.getData = function () {\n    return this.data;\n  };\n\n  /**\n   * @license\n   * Copyright (c) 2018 Aras Abbasi\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n\n  /**\n   * jsPDF bmp Support PlugIn\n   * @name bmp_support\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n\n    jsPDFAPI.processBMP = function (imageData, index, alias, compression) {\n      var reader = new BmpDecoder(imageData, false);\n      var width = reader.width,\n          height = reader.height;\n      var qu = 100;\n      var pixels = reader.getData();\n      var rawImageData = {\n        data: pixels,\n        width: width,\n        height: height\n      };\n      var encoder = new JPEGEncoder(qu);\n      var data = encoder.encode(rawImageData, qu);\n      return jsPDFAPI.processJPEG.call(this, data, index, alias, compression);\n    };\n  })(jsPDF.API);\n\n  function WebPDecoder(imageData) {\n\n    function x(F) {\n      if (!F) throw Error(\"assert :P\");\n    }\n\n    function fa(F, L, J) {\n      for (var H = 0; 4 > H; H++) {\n        if (F[L + H] != J.charCodeAt(H)) return !0;\n      }\n\n      return !1;\n    }\n\n    function I(F, L, J, H, Z) {\n      for (var O = 0; O < Z; O++) {\n        F[L + O] = J[H + O];\n      }\n    }\n\n    function M(F, L, J, H) {\n      for (var Z = 0; Z < H; Z++) {\n        F[L + Z] = J;\n      }\n    }\n\n    function V(F) {\n      return new Int32Array(F);\n    }\n\n    function wa(F, L) {\n      for (var J = [], H = 0; H < F; H++) {\n        J.push(new L());\n      }\n\n      return J;\n    }\n\n    function wb() {\n      function F(J, H, Z) {\n        for (var O = Z[H], L = 0; L < O; L++) {\n          J.push(Z.length > H + 1 ? [] : 0);\n          if (Z.length < H + 1) break;\n          F(J[L], H + 1, Z);\n        }\n      }\n\n      var L = [];\n      F(L, 0, [3, 11]);\n      return L;\n    }\n\n    function Ed(F, L) {\n      function J(H, O, F) {\n        for (var Z = F[O], ma = 0; ma < Z; ma++) {\n          H.push(F.length > O + 1 ? [] : new L());\n          if (F.length < O + 1) break;\n          J(H[ma], O + 1, F);\n        }\n      }\n\n      var H = [];\n      J(H, 0, F);\n      return H;\n    }\n\n    var _WebPDecoder = function _WebPDecoder() {\n      var self = this;\n\n      function L(a, b) {\n        for (var c = 1 << b - 1 >>> 0; a & c;) {\n          c >>>= 1;\n        }\n\n        return c ? (a & c - 1) + c : a;\n      }\n\n      function J(a, b, c, d, e) {\n        x(!(d % c));\n\n        do {\n          d -= c, a[b + d] = e;\n        } while (0 < d);\n      }\n\n      function H(a, b, c, d, e, f) {\n        var g = b,\n            h = 1 << c,\n            k,\n            l,\n            m = V(16),\n            n = V(16);\n        x(0 != e);\n        x(null != d);\n        x(null != a);\n        x(0 < c);\n\n        for (l = 0; l < e; ++l) {\n          if (15 < d[l]) return 0;\n          ++m[d[l]];\n        }\n\n        if (m[0] == e) return 0;\n        n[1] = 0;\n\n        for (k = 1; 15 > k; ++k) {\n          if (m[k] > 1 << k) return 0;\n          n[k + 1] = n[k] + m[k];\n        }\n\n        for (l = 0; l < e; ++l) {\n          k = d[l], 0 < d[l] && (f[n[k]++] = l);\n        }\n\n        if (1 == n[15]) return d = new O(), d.g = 0, d.value = f[0], J(a, g, 1, h, d), h;\n        var r = -1,\n            q = h - 1,\n            t = 0,\n            v = 1,\n            p = 1,\n            u,\n            w = 1 << c;\n        l = 0;\n        k = 1;\n\n        for (e = 2; k <= c; ++k, e <<= 1) {\n          p <<= 1;\n          v += p;\n          p -= m[k];\n          if (0 > p) return 0;\n\n          for (; 0 < m[k]; --m[k]) {\n            d = new O(), d.g = k, d.value = f[l++], J(a, g + t, e, w, d), t = L(t, k);\n          }\n        }\n\n        k = c + 1;\n\n        for (e = 2; 15 >= k; ++k, e <<= 1) {\n          p <<= 1;\n          v += p;\n          p -= m[k];\n          if (0 > p) return 0;\n\n          for (; 0 < m[k]; --m[k]) {\n            d = new O();\n\n            if ((t & q) != r) {\n              g += w;\n              r = k;\n\n              for (u = 1 << r - c; 15 > r;) {\n                u -= m[r];\n                if (0 >= u) break;\n                ++r;\n                u <<= 1;\n              }\n\n              u = r - c;\n              w = 1 << u;\n              h += w;\n              r = t & q;\n              a[b + r].g = u + c;\n              a[b + r].value = g - b - r;\n            }\n\n            d.g = k - c;\n            d.value = f[l++];\n            J(a, g + (t >> c), e, w, d);\n            t = L(t, k);\n          }\n        }\n\n        return v != 2 * n[15] - 1 ? 0 : h;\n      }\n\n      function Z(a, b, c, d, e) {\n        x(2328 >= e);\n        if (512 >= e) var f = V(512);else if (f = V(e), null == f) return 0;\n        return H(a, b, c, d, e, f);\n      }\n\n      function O() {\n        this.value = this.g = 0;\n      }\n\n      function Fd() {\n        this.value = this.g = 0;\n      }\n\n      function Ub() {\n        this.G = wa(5, O);\n        this.H = V(5);\n        this.jc = this.Qb = this.qb = this.nd = 0;\n        this.pd = wa(xb, Fd);\n      }\n\n      function ma(a, b, c, d) {\n        x(null != a);\n        x(null != b);\n        x(2147483648 > d);\n        a.Ca = 254;\n        a.I = 0;\n        a.b = -8;\n        a.Ka = 0;\n        a.oa = b;\n        a.pa = c;\n        a.Jd = b;\n        a.Yc = c + d;\n        a.Zc = 4 <= d ? c + d - 4 + 1 : c;\n        Qa(a);\n      }\n\n      function na(a, b) {\n        for (var c = 0; 0 < b--;) {\n          c |= K(a, 128) << b;\n        }\n\n        return c;\n      }\n\n      function ca(a, b) {\n        var c = na(a, b);\n        return G(a) ? -c : c;\n      }\n\n      function cb(a, b, c, d) {\n        var e,\n            f = 0;\n        x(null != a);\n        x(null != b);\n        x(4294967288 > d);\n        a.Sb = d;\n        a.Ra = 0;\n        a.u = 0;\n        a.h = 0;\n        4 < d && (d = 4);\n\n        for (e = 0; e < d; ++e) {\n          f += b[c + e] << 8 * e;\n        }\n\n        a.Ra = f;\n        a.bb = d;\n        a.oa = b;\n        a.pa = c;\n      }\n\n      function Vb(a) {\n        for (; 8 <= a.u && a.bb < a.Sb;) {\n          a.Ra >>>= 8, a.Ra += a.oa[a.pa + a.bb] << ob - 8 >>> 0, ++a.bb, a.u -= 8;\n        }\n\n        db(a) && (a.h = 1, a.u = 0);\n      }\n\n      function D(a, b) {\n        x(0 <= b);\n\n        if (!a.h && b <= Gd) {\n          var c = pb(a) & Hd[b];\n          a.u += b;\n          Vb(a);\n          return c;\n        }\n\n        a.h = 1;\n        return a.u = 0;\n      }\n\n      function Wb() {\n        this.b = this.Ca = this.I = 0;\n        this.oa = [];\n        this.pa = 0;\n        this.Jd = [];\n        this.Yc = 0;\n        this.Zc = [];\n        this.Ka = 0;\n      }\n\n      function Ra() {\n        this.Ra = 0;\n        this.oa = [];\n        this.h = this.u = this.bb = this.Sb = this.pa = 0;\n      }\n\n      function pb(a) {\n        return a.Ra >>> (a.u & ob - 1) >>> 0;\n      }\n\n      function db(a) {\n        x(a.bb <= a.Sb);\n        return a.h || a.bb == a.Sb && a.u > ob;\n      }\n\n      function qb(a, b) {\n        a.u = b;\n        a.h = db(a);\n      }\n\n      function Sa(a) {\n        a.u >= Xb && (x(a.u >= Xb), Vb(a));\n      }\n\n      function Qa(a) {\n        x(null != a && null != a.oa);\n        a.pa < a.Zc ? (a.I = (a.oa[a.pa++] | a.I << 8) >>> 0, a.b += 8) : (x(null != a && null != a.oa), a.pa < a.Yc ? (a.b += 8, a.I = a.oa[a.pa++] | a.I << 8) : a.Ka ? a.b = 0 : (a.I <<= 8, a.b += 8, a.Ka = 1));\n      }\n\n      function G(a) {\n        return na(a, 1);\n      }\n\n      function K(a, b) {\n        var c = a.Ca;\n        0 > a.b && Qa(a);\n        var d = a.b,\n            e = c * b >>> 8,\n            f = (a.I >>> d > e) + 0;\n        f ? (c -= e, a.I -= e + 1 << d >>> 0) : c = e + 1;\n        d = c;\n\n        for (e = 0; 256 <= d;) {\n          e += 8, d >>= 8;\n        }\n\n        d = 7 ^ e + Id[d];\n        a.b -= d;\n        a.Ca = (c << d) - 1;\n        return f;\n      }\n\n      function ra(a, b, c) {\n        a[b + 0] = c >> 24 & 255;\n        a[b + 1] = c >> 16 & 255;\n        a[b + 2] = c >> 8 & 255;\n        a[b + 3] = c >> 0 & 255;\n      }\n\n      function Ta(a, b) {\n        return a[b + 0] << 0 | a[b + 1] << 8;\n      }\n\n      function Yb(a, b) {\n        return Ta(a, b) | a[b + 2] << 16;\n      }\n\n      function Ha(a, b) {\n        return Ta(a, b) | Ta(a, b + 2) << 16;\n      }\n\n      function Zb(a, b) {\n        var c = 1 << b;\n        x(null != a);\n        x(0 < b);\n        a.X = V(c);\n        if (null == a.X) return 0;\n        a.Mb = 32 - b;\n        a.Xa = b;\n        return 1;\n      }\n\n      function $b(a, b) {\n        x(null != a);\n        x(null != b);\n        x(a.Xa == b.Xa);\n        I(b.X, 0, a.X, 0, 1 << b.Xa);\n      }\n\n      function ac() {\n        this.X = [];\n        this.Xa = this.Mb = 0;\n      }\n\n      function bc(a, b, c, d) {\n        x(null != c);\n        x(null != d);\n        var e = c[0],\n            f = d[0];\n        0 == e && (e = (a * f + b / 2) / b);\n        0 == f && (f = (b * e + a / 2) / a);\n        if (0 >= e || 0 >= f) return 0;\n        c[0] = e;\n        d[0] = f;\n        return 1;\n      }\n\n      function xa(a, b) {\n        return a + (1 << b) - 1 >>> b;\n      }\n\n      function yb(a, b) {\n        return ((a & 4278255360) + (b & 4278255360) >>> 0 & 4278255360) + ((a & 16711935) + (b & 16711935) >>> 0 & 16711935) >>> 0;\n      }\n\n      function X(a, b) {\n        self[b] = function (b, d, e, f, g, h, k) {\n          var c;\n\n          for (c = 0; c < g; ++c) {\n            var m = self[a](h[k + c - 1], e, f + c);\n            h[k + c] = yb(b[d + c], m);\n          }\n        };\n      }\n\n      function Jd() {\n        this.ud = this.hd = this.jd = 0;\n      }\n\n      function aa(a, b) {\n        return (((a ^ b) & 4278124286) >>> 1) + (a & b) >>> 0;\n      }\n\n      function sa(a) {\n        if (0 <= a && 256 > a) return a;\n        if (0 > a) return 0;\n        if (255 < a) return 255;\n      }\n\n      function eb(a, b) {\n        return sa(a + (a - b + 0.5 >> 1));\n      }\n\n      function Ia(a, b, c) {\n        return Math.abs(b - c) - Math.abs(a - c);\n      }\n\n      function cc(a, b, c, d, e, f, g) {\n        d = f[g - 1];\n\n        for (c = 0; c < e; ++c) {\n          f[g + c] = d = yb(a[b + c], d);\n        }\n      }\n\n      function Kd(a, b, c, d, e) {\n        var f;\n\n        for (f = 0; f < c; ++f) {\n          var g = a[b + f],\n              h = g >> 8 & 255,\n              k = g & 16711935,\n              k = k + ((h << 16) + h),\n              k = k & 16711935;\n          d[e + f] = (g & 4278255360) + k >>> 0;\n        }\n      }\n\n      function dc(a, b) {\n        b.jd = a >> 0 & 255;\n        b.hd = a >> 8 & 255;\n        b.ud = a >> 16 & 255;\n      }\n\n      function Ld(a, b, c, d, e, f) {\n        var g;\n\n        for (g = 0; g < d; ++g) {\n          var h = b[c + g],\n              k = h >>> 8,\n              l = h >>> 16,\n              m = h,\n              l = l + ((a.jd << 24 >> 24) * (k << 24 >> 24) >>> 5),\n              l = l & 255,\n              m = m + ((a.hd << 24 >> 24) * (k << 24 >> 24) >>> 5),\n              m = m + ((a.ud << 24 >> 24) * (l << 24 >> 24) >>> 5),\n              m = m & 255;\n          e[f + g] = (h & 4278255360) + (l << 16) + m;\n        }\n      }\n\n      function ec(a, b, c, d, e) {\n        self[b] = function (a, b, c, k, l, m, n, r, q) {\n          for (k = n; k < r; ++k) {\n            for (n = 0; n < q; ++n) {\n              l[m++] = e(c[d(a[b++])]);\n            }\n          }\n        };\n\n        self[a] = function (a, b, h, k, l, m, n) {\n          var f = 8 >> a.b,\n              g = a.Ea,\n              t = a.K[0],\n              v = a.w;\n          if (8 > f) for (a = (1 << a.b) - 1, v = (1 << f) - 1; b < h; ++b) {\n            var p = 0,\n                u;\n\n            for (u = 0; u < g; ++u) {\n              u & a || (p = d(k[l++])), m[n++] = e(t[p & v]), p >>= f;\n            }\n          } else self[\"VP8LMapColor\" + c](k, l, t, v, m, n, b, h, g);\n        };\n      }\n\n      function Md(a, b, c, d, e) {\n        for (c = b + c; b < c;) {\n          var f = a[b++];\n          d[e++] = f >> 16 & 255;\n          d[e++] = f >> 8 & 255;\n          d[e++] = f >> 0 & 255;\n        }\n      }\n\n      function Nd(a, b, c, d, e) {\n        for (c = b + c; b < c;) {\n          var f = a[b++];\n          d[e++] = f >> 16 & 255;\n          d[e++] = f >> 8 & 255;\n          d[e++] = f >> 0 & 255;\n          d[e++] = f >> 24 & 255;\n        }\n      }\n\n      function Od(a, b, c, d, e) {\n        for (c = b + c; b < c;) {\n          var f = a[b++],\n              g = f >> 16 & 240 | f >> 12 & 15,\n              f = f >> 0 & 240 | f >> 28 & 15;\n          d[e++] = g;\n          d[e++] = f;\n        }\n      }\n\n      function Pd(a, b, c, d, e) {\n        for (c = b + c; b < c;) {\n          var f = a[b++],\n              g = f >> 16 & 248 | f >> 13 & 7,\n              f = f >> 5 & 224 | f >> 3 & 31;\n          d[e++] = g;\n          d[e++] = f;\n        }\n      }\n\n      function Qd(a, b, c, d, e) {\n        for (c = b + c; b < c;) {\n          var f = a[b++];\n          d[e++] = f >> 0 & 255;\n          d[e++] = f >> 8 & 255;\n          d[e++] = f >> 16 & 255;\n        }\n      }\n\n      function fb(a, b, c, d, e, f) {\n        if (0 == f) for (c = b + c; b < c;) {\n          f = a[b++], ra(d, (f[0] >> 24 | f[1] >> 8 & 65280 | f[2] << 8 & 16711680 | f[3] << 24) >>> 0), e += 32;\n        } else I(d, e, a, b, c);\n      }\n\n      function gb(a, b) {\n        self[b][0] = self[a + \"0\"];\n        self[b][1] = self[a + \"1\"];\n        self[b][2] = self[a + \"2\"];\n        self[b][3] = self[a + \"3\"];\n        self[b][4] = self[a + \"4\"];\n        self[b][5] = self[a + \"5\"];\n        self[b][6] = self[a + \"6\"];\n        self[b][7] = self[a + \"7\"];\n        self[b][8] = self[a + \"8\"];\n        self[b][9] = self[a + \"9\"];\n        self[b][10] = self[a + \"10\"];\n        self[b][11] = self[a + \"11\"];\n        self[b][12] = self[a + \"12\"];\n        self[b][13] = self[a + \"13\"];\n        self[b][14] = self[a + \"0\"];\n        self[b][15] = self[a + \"0\"];\n      }\n\n      function hb(a) {\n        return a == zb || a == Ab || a == Ja || a == Bb;\n      }\n\n      function Rd() {\n        this.eb = [];\n        this.size = this.A = this.fb = 0;\n      }\n\n      function Sd() {\n        this.y = [];\n        this.f = [];\n        this.ea = [];\n        this.F = [];\n        this.Tc = this.Ed = this.Cd = this.Fd = this.lb = this.Db = this.Ab = this.fa = this.J = this.W = this.N = this.O = 0;\n      }\n\n      function Cb() {\n        this.Rd = this.height = this.width = this.S = 0;\n        this.f = {};\n        this.f.RGBA = new Rd();\n        this.f.kb = new Sd();\n        this.sd = null;\n      }\n\n      function Td() {\n        this.width = [0];\n        this.height = [0];\n        this.Pd = [0];\n        this.Qd = [0];\n        this.format = [0];\n      }\n\n      function Ud() {\n        this.Id = this.fd = this.Md = this.hb = this.ib = this.da = this.bd = this.cd = this.j = this.v = this.Da = this.Sd = this.ob = 0;\n      }\n\n      function Vd(a) {\n        alert(\"todo:WebPSamplerProcessPlane\");\n        return a.T;\n      }\n\n      function Wd(a, b) {\n        var c = a.T,\n            d = b.ba.f.RGBA,\n            e = d.eb,\n            f = d.fb + a.ka * d.A,\n            g = P[b.ba.S],\n            h = a.y,\n            k = a.O,\n            l = a.f,\n            m = a.N,\n            n = a.ea,\n            r = a.W,\n            q = b.cc,\n            t = b.dc,\n            v = b.Mc,\n            p = b.Nc,\n            u = a.ka,\n            w = a.ka + a.T,\n            y = a.U,\n            A = y + 1 >> 1;\n        0 == u ? g(h, k, null, null, l, m, n, r, l, m, n, r, e, f, null, null, y) : (g(b.ec, b.fc, h, k, q, t, v, p, l, m, n, r, e, f - d.A, e, f, y), ++c);\n\n        for (; u + 2 < w; u += 2) {\n          q = l, t = m, v = n, p = r, m += a.Rc, r += a.Rc, f += 2 * d.A, k += 2 * a.fa, g(h, k - a.fa, h, k, q, t, v, p, l, m, n, r, e, f - d.A, e, f, y);\n        }\n\n        k += a.fa;\n        a.j + w < a.o ? (I(b.ec, b.fc, h, k, y), I(b.cc, b.dc, l, m, A), I(b.Mc, b.Nc, n, r, A), c--) : w & 1 || g(h, k, null, null, l, m, n, r, l, m, n, r, e, f + d.A, null, null, y);\n        return c;\n      }\n\n      function Xd(a, b, c) {\n        var d = a.F,\n            e = [a.J];\n\n        if (null != d) {\n          var f = a.U,\n              g = b.ba.S,\n              h = g == ya || g == Ja;\n          b = b.ba.f.RGBA;\n          var k = [0],\n              l = a.ka;\n          k[0] = a.T;\n          a.Kb && (0 == l ? --k[0] : (--l, e[0] -= a.width), a.j + a.ka + a.T == a.o && (k[0] = a.o - a.j - l));\n          var m = b.eb,\n              l = b.fb + l * b.A;\n          a = fc(d, e[0], a.width, f, k, m, l + (h ? 0 : 3), b.A);\n          x(c == k);\n          a && hb(g) && za(m, l, h, f, k, b.A);\n        }\n\n        return 0;\n      }\n\n      function gc(a) {\n        var b = a.ma,\n            c = b.ba.S,\n            d = 11 > c,\n            e = c == Ua || c == Va || c == ya || c == Db || 12 == c || hb(c);\n        b.memory = null;\n        b.Ib = null;\n        b.Jb = null;\n        b.Nd = null;\n        if (!hc(b.Oa, a, e ? 11 : 12)) return 0;\n        e && hb(c) && ic();\n        if (a.da) alert(\"todo:use_scaling\");else {\n          if (d) {\n            if (b.Ib = Vd, a.Kb) {\n              c = a.U + 1 >> 1;\n              b.memory = V(a.U + 2 * c);\n              if (null == b.memory) return 0;\n              b.ec = b.memory;\n              b.fc = 0;\n              b.cc = b.ec;\n              b.dc = b.fc + a.U;\n              b.Mc = b.cc;\n              b.Nc = b.dc + c;\n              b.Ib = Wd;\n              ic();\n            }\n          } else alert(\"todo:EmitYUV\");\n\n          e && (b.Jb = Xd, d && Aa());\n        }\n\n        if (d && !jc) {\n          for (a = 0; 256 > a; ++a) {\n            Yd[a] = 89858 * (a - 128) + Ba >> Wa, Zd[a] = -22014 * (a - 128) + Ba, $d[a] = -45773 * (a - 128), ae[a] = 113618 * (a - 128) + Ba >> Wa;\n          }\n\n          for (a = ta; a < Eb; ++a) {\n            b = 76283 * (a - 16) + Ba >> Wa, be[a - ta] = ga(b, 255), ce[a - ta] = ga(b + 8 >> 4, 15);\n          }\n\n          jc = 1;\n        }\n\n        return 1;\n      }\n\n      function kc(a) {\n        var b = a.ma,\n            c = a.U,\n            d = a.T;\n        x(!(a.ka & 1));\n        if (0 >= c || 0 >= d) return 0;\n        c = b.Ib(a, b);\n        null != b.Jb && b.Jb(a, b, c);\n        b.Dc += c;\n        return 1;\n      }\n\n      function lc(a) {\n        a.ma.memory = null;\n      }\n\n      function mc(a, b, c, d) {\n        if (47 != D(a, 8)) return 0;\n        b[0] = D(a, 14) + 1;\n        c[0] = D(a, 14) + 1;\n        d[0] = D(a, 1);\n        return 0 != D(a, 3) ? 0 : !a.h;\n      }\n\n      function ib(a, b) {\n        if (4 > a) return a + 1;\n        var c = a - 2 >> 1;\n        return (2 + (a & 1) << c) + D(b, c) + 1;\n      }\n\n      function nc(a, b) {\n        if (120 < b) return b - 120;\n        var c = de[b - 1],\n            c = (c >> 4) * a + (8 - (c & 15));\n        return 1 <= c ? c : 1;\n      }\n\n      function ua(a, b, c) {\n        var d = pb(c);\n        b += d & 255;\n        var e = a[b].g - 8;\n        0 < e && (qb(c, c.u + 8), d = pb(c), b += a[b].value, b += d & (1 << e) - 1);\n        qb(c, c.u + a[b].g);\n        return a[b].value;\n      }\n\n      function ub(a, b, c) {\n        c.g += a.g;\n        c.value += a.value << b >>> 0;\n        x(8 >= c.g);\n        return a.g;\n      }\n\n      function ha(a, b, c) {\n        var d = a.xc;\n        b = 0 == d ? 0 : a.vc[a.md * (c >> d) + (b >> d)];\n        x(b < a.Wb);\n        return a.Ya[b];\n      }\n\n      function oc(a, b, c, d) {\n        var e = a.ab,\n            f = a.c * b,\n            g = a.C;\n        b = g + b;\n        var h = c,\n            k = d;\n        d = a.Ta;\n\n        for (c = a.Ua; 0 < e--;) {\n          var l = a.gc[e],\n              m = g,\n              n = b,\n              r = h,\n              q = k,\n              k = d,\n              h = c,\n              t = l.Ea;\n          x(m < n);\n          x(n <= l.nc);\n\n          switch (l.hc) {\n            case 2:\n              pc(r, q, (n - m) * t, k, h);\n              break;\n\n            case 0:\n              var v = l,\n                  p = m,\n                  u = n,\n                  w = k,\n                  y = h,\n                  A = v.Ea;\n              0 == p && (ee(r, q, null, null, 1, w, y), cc(r, q + 1, 0, 0, A - 1, w, y + 1), q += A, y += A, ++p);\n\n              for (var E = 1 << v.b, B = E - 1, C = xa(A, v.b), N = v.K, v = v.w + (p >> v.b) * C; p < u;) {\n                var z = N,\n                    Q = v,\n                    S = 1;\n\n                for (fe(r, q, w, y - A, 1, w, y); S < A;) {\n                  var K = qc[z[Q++] >> 8 & 15],\n                      D = (S & ~B) + E;\n                  D > A && (D = A);\n                  K(r, q + +S, w, y + S - A, D - S, w, y + S);\n                  S = D;\n                }\n\n                q += A;\n                y += A;\n                ++p;\n                p & B || (v += C);\n              }\n\n              n != l.nc && I(k, h - t, k, h + (n - m - 1) * t, t);\n              break;\n\n            case 1:\n              t = r;\n              u = q;\n              r = l.Ea;\n              q = 1 << l.b;\n              w = q - 1;\n              y = r & ~w;\n              A = r - y;\n              p = xa(r, l.b);\n              E = l.K;\n\n              for (l = l.w + (m >> l.b) * p; m < n;) {\n                B = E;\n                C = l;\n                N = new Jd();\n                v = u + y;\n\n                for (z = u + r; u < v;) {\n                  dc(B[C++], N), Fb(N, t, u, q, k, h), u += q, h += q;\n                }\n\n                u < z && (dc(B[C++], N), Fb(N, t, u, A, k, h), u += A, h += A);\n                ++m;\n                m & w || (l += p);\n              }\n\n              break;\n\n            case 3:\n              if (r == k && q == h && 0 < l.b) {\n                y = (n - m) * xa(l.Ea, l.b);\n                t = h + (n - m) * t - y;\n                u = k;\n                r = t;\n                q = k;\n                w = h;\n                A = y;\n                p = [];\n\n                for (y = A - 1; 0 <= y; --y) {\n                  p[y] = q[w + y];\n                }\n\n                for (y = A - 1; 0 <= y; --y) {\n                  u[r + y] = p[y];\n                }\n\n                rc(l, m, n, k, t, k, h);\n              } else rc(l, m, n, r, q, k, h);\n\n          }\n\n          h = d;\n          k = c;\n        }\n\n        k != c && I(d, c, h, k, f);\n      }\n\n      function ge(a, b) {\n        var c = a.V,\n            d = a.Ba + a.c * a.C,\n            e = b - a.C;\n        x(b <= a.l.o);\n        x(16 >= e);\n\n        if (0 < e) {\n          var f = a.l,\n              g = a.Ta,\n              h = a.Ua,\n              k = f.width;\n          oc(a, e, c, d);\n          h = [h];\n          c = a.C;\n          d = b;\n          e = h;\n          x(c < d);\n          x(f.v < f.va);\n          d > f.o && (d = f.o);\n\n          if (c < f.j) {\n            var l = f.j - c,\n                c = f.j;\n            e[0] += l * k;\n          }\n\n          c >= d ? c = 0 : (e[0] += 4 * f.v, f.ka = c - f.j, f.U = f.va - f.v, f.T = d - c, c = 1);\n\n          if (c) {\n            h = h[0];\n            c = a.ca;\n\n            if (11 > c.S) {\n              for (var m = c.f.RGBA, d = c.S, e = f.U, f = f.T, l = m.eb, n = m.A, r = f, m = m.fb + a.Ma * m.A; 0 < r--;) {\n                var q = g,\n                    t = h,\n                    v = e,\n                    p = l,\n                    u = m;\n\n                switch (d) {\n                  case Ca:\n                    sc(q, t, v, p, u);\n                    break;\n\n                  case Ua:\n                    Gb(q, t, v, p, u);\n                    break;\n\n                  case zb:\n                    Gb(q, t, v, p, u);\n                    za(p, u, 0, v, 1, 0);\n                    break;\n\n                  case tc:\n                    uc(q, t, v, p, u);\n                    break;\n\n                  case Va:\n                    fb(q, t, v, p, u, 1);\n                    break;\n\n                  case Ab:\n                    fb(q, t, v, p, u, 1);\n                    za(p, u, 0, v, 1, 0);\n                    break;\n\n                  case ya:\n                    fb(q, t, v, p, u, 0);\n                    break;\n\n                  case Ja:\n                    fb(q, t, v, p, u, 0);\n                    za(p, u, 1, v, 1, 0);\n                    break;\n\n                  case Db:\n                    Hb(q, t, v, p, u);\n                    break;\n\n                  case Bb:\n                    Hb(q, t, v, p, u);\n                    vc(p, u, v, 1, 0);\n                    break;\n\n                  case wc:\n                    xc(q, t, v, p, u);\n                    break;\n\n                  default:\n                    x(0);\n                }\n\n                h += k;\n                m += n;\n              }\n\n              a.Ma += f;\n            } else alert(\"todo:EmitRescaledRowsYUVA\");\n\n            x(a.Ma <= c.height);\n          }\n        }\n\n        a.C = b;\n        x(a.C <= a.i);\n      }\n\n      function yc(a) {\n        var b;\n        if (0 < a.ua) return 0;\n\n        for (b = 0; b < a.Wb; ++b) {\n          var c = a.Ya[b].G,\n              d = a.Ya[b].H;\n          if (0 < c[1][d[1] + 0].g || 0 < c[2][d[2] + 0].g || 0 < c[3][d[3] + 0].g) return 0;\n        }\n\n        return 1;\n      }\n\n      function zc(a, b, c, d, e, f) {\n        if (0 != a.Z) {\n          var g = a.qd,\n              h = a.rd;\n\n          for (x(null != ia[a.Z]); b < c; ++b) {\n            ia[a.Z](g, h, d, e, d, e, f), g = d, h = e, e += f;\n          }\n\n          a.qd = g;\n          a.rd = h;\n        }\n      }\n\n      function Ib(a, b) {\n        var c = a.l.ma,\n            d = 0 == c.Z || 1 == c.Z ? a.l.j : a.C,\n            d = a.C < d ? d : a.C;\n        x(b <= a.l.o);\n\n        if (b > d) {\n          var e = a.l.width,\n              f = c.ca,\n              g = c.tb + e * d,\n              h = a.V,\n              k = a.Ba + a.c * d,\n              l = a.gc;\n          x(1 == a.ab);\n          x(3 == l[0].hc);\n          he(l[0], d, b, h, k, f, g);\n          zc(c, d, b, f, g, e);\n        }\n\n        a.C = a.Ma = b;\n      }\n\n      function Jb(a, b, c, d, e, f, g) {\n        var h = a.$ / d,\n            k = a.$ % d,\n            l = a.m,\n            m = a.s,\n            n = c + a.$,\n            r = n;\n        e = c + d * e;\n        var q = c + d * f,\n            t = 280 + m.ua,\n            v = a.Pb ? h : 16777216,\n            p = 0 < m.ua ? m.Wa : null,\n            u = m.wc,\n            w = n < q ? ha(m, k, h) : null;\n        x(a.C < f);\n        x(q <= e);\n        var y = !1;\n\n        a: for (;;) {\n          for (; y || n < q;) {\n            var A = 0;\n\n            if (h >= v) {\n              var v = a,\n                  E = n - c;\n              x(v.Pb);\n              v.wd = v.m;\n              v.xd = E;\n              0 < v.s.ua && $b(v.s.Wa, v.s.vb);\n              v = h + ie;\n            }\n\n            k & u || (w = ha(m, k, h));\n            x(null != w);\n            w.Qb && (b[n] = w.qb, y = !0);\n            if (!y) if (Sa(l), w.jc) {\n              var A = l,\n                  E = b,\n                  B = n,\n                  C = w.pd[pb(A) & xb - 1];\n              x(w.jc);\n              256 > C.g ? (qb(A, A.u + C.g), E[B] = C.value, A = 0) : (qb(A, A.u + C.g - 256), x(256 <= C.value), A = C.value);\n              0 == A && (y = !0);\n            } else A = ua(w.G[0], w.H[0], l);\n            if (l.h) break;\n\n            if (y || 256 > A) {\n              if (!y) if (w.nd) b[n] = (w.qb | A << 8) >>> 0;else {\n                Sa(l);\n                y = ua(w.G[1], w.H[1], l);\n                Sa(l);\n                E = ua(w.G[2], w.H[2], l);\n                B = ua(w.G[3], w.H[3], l);\n                if (l.h) break;\n                b[n] = (B << 24 | y << 16 | A << 8 | E) >>> 0;\n              }\n              y = !1;\n              ++n;\n              ++k;\n              if (k >= d && (k = 0, ++h, null != g && h <= f && !(h % 16) && g(a, h), null != p)) for (; r < n;) {\n                A = b[r++], p.X[(506832829 * A & 4294967295) >>> p.Mb] = A;\n              }\n            } else if (280 > A) {\n              A = ib(A - 256, l);\n              E = ua(w.G[4], w.H[4], l);\n              Sa(l);\n              E = ib(E, l);\n              E = nc(d, E);\n              if (l.h) break;\n              if (n - c < E || e - n < A) break a;else for (B = 0; B < A; ++B) {\n                b[n + B] = b[n + B - E];\n              }\n              n += A;\n\n              for (k += A; k >= d;) {\n                k -= d, ++h, null != g && h <= f && !(h % 16) && g(a, h);\n              }\n\n              x(n <= e);\n              k & u && (w = ha(m, k, h));\n              if (null != p) for (; r < n;) {\n                A = b[r++], p.X[(506832829 * A & 4294967295) >>> p.Mb] = A;\n              }\n            } else if (A < t) {\n              y = A - 280;\n\n              for (x(null != p); r < n;) {\n                A = b[r++], p.X[(506832829 * A & 4294967295) >>> p.Mb] = A;\n              }\n\n              A = n;\n              E = p;\n              x(!(y >>> E.Xa));\n              b[A] = E.X[y];\n              y = !0;\n            } else break a;\n\n            y || x(l.h == db(l));\n          }\n\n          if (a.Pb && l.h && n < e) x(a.m.h), a.a = 5, a.m = a.wd, a.$ = a.xd, 0 < a.s.ua && $b(a.s.vb, a.s.Wa);else if (l.h) break a;else null != g && g(a, h > f ? f : h), a.a = 0, a.$ = n - c;\n          return 1;\n        }\n\n        a.a = 3;\n        return 0;\n      }\n\n      function Ac(a) {\n        x(null != a);\n        a.vc = null;\n        a.yc = null;\n        a.Ya = null;\n        var b = a.Wa;\n        null != b && (b.X = null);\n        a.vb = null;\n        x(null != a);\n      }\n\n      function Bc() {\n        var a = new je();\n        if (null == a) return null;\n        a.a = 0;\n        a.xb = Cc;\n        gb(\"Predictor\", \"VP8LPredictors\");\n        gb(\"Predictor\", \"VP8LPredictors_C\");\n        gb(\"PredictorAdd\", \"VP8LPredictorsAdd\");\n        gb(\"PredictorAdd\", \"VP8LPredictorsAdd_C\");\n        pc = Kd;\n        Fb = Ld;\n        sc = Md;\n        Gb = Nd;\n        Hb = Od;\n        xc = Pd;\n        uc = Qd;\n        self.VP8LMapColor32b = ke;\n        self.VP8LMapColor8b = le;\n        return a;\n      }\n\n      function rb(a, b, c, d, e) {\n        var f = 1,\n            g = [a],\n            h = [b],\n            k = d.m,\n            l = d.s,\n            m = null,\n            n = 0;\n\n        a: for (;;) {\n          if (c) for (; f && D(k, 1);) {\n            var r = g,\n                q = h,\n                t = d,\n                v = 1,\n                p = t.m,\n                u = t.gc[t.ab],\n                w = D(p, 2);\n            if (t.Oc & 1 << w) f = 0;else {\n              t.Oc |= 1 << w;\n              u.hc = w;\n              u.Ea = r[0];\n              u.nc = q[0];\n              u.K = [null];\n              ++t.ab;\n              x(4 >= t.ab);\n\n              switch (w) {\n                case 0:\n                case 1:\n                  u.b = D(p, 3) + 2;\n                  v = rb(xa(u.Ea, u.b), xa(u.nc, u.b), 0, t, u.K);\n                  u.K = u.K[0];\n                  break;\n\n                case 3:\n                  var y = D(p, 8) + 1,\n                      A = 16 < y ? 0 : 4 < y ? 1 : 2 < y ? 2 : 3;\n                  r[0] = xa(u.Ea, A);\n                  u.b = A;\n                  var v = rb(y, 1, 0, t, u.K),\n                      E;\n\n                  if (E = v) {\n                    var B,\n                        C = y,\n                        N = u,\n                        z = 1 << (8 >> N.b),\n                        Q = V(z);\n                    if (null == Q) E = 0;else {\n                      var S = N.K[0],\n                          K = N.w;\n                      Q[0] = N.K[0][0];\n\n                      for (B = 1; B < 1 * C; ++B) {\n                        Q[B] = yb(S[K + B], Q[B - 1]);\n                      }\n\n                      for (; B < 4 * z; ++B) {\n                        Q[B] = 0;\n                      }\n\n                      N.K[0] = null;\n                      N.K[0] = Q;\n                      E = 1;\n                    }\n                  }\n\n                  v = E;\n                  break;\n\n                case 2:\n                  break;\n\n                default:\n                  x(0);\n              }\n\n              f = v;\n            }\n          }\n          g = g[0];\n          h = h[0];\n\n          if (f && D(k, 1) && (n = D(k, 4), f = 1 <= n && 11 >= n, !f)) {\n            d.a = 3;\n            break a;\n          }\n\n          var H;\n          if (H = f) b: {\n            var F = d,\n                G = g,\n                L = h,\n                J = n,\n                T = c,\n                Da,\n                ba,\n                X = F.m,\n                R = F.s,\n                P = [null],\n                U,\n                W = 1,\n                aa = 0,\n                na = me[J];\n\n            c: for (;;) {\n              if (T && D(X, 1)) {\n                var ca = D(X, 3) + 2,\n                    ga = xa(G, ca),\n                    ka = xa(L, ca),\n                    qa = ga * ka;\n                if (!rb(ga, ka, 0, F, P)) break c;\n                P = P[0];\n                R.xc = ca;\n\n                for (Da = 0; Da < qa; ++Da) {\n                  var ia = P[Da] >> 8 & 65535;\n                  P[Da] = ia;\n                  ia >= W && (W = ia + 1);\n                }\n              }\n\n              if (X.h) break c;\n\n              for (ba = 0; 5 > ba; ++ba) {\n                var Y = Dc[ba];\n                !ba && 0 < J && (Y += 1 << J);\n                aa < Y && (aa = Y);\n              }\n\n              var ma = wa(W * na, O);\n              var ua = W,\n                  va = wa(ua, Ub);\n              if (null == va) var la = null;else x(65536 >= ua), la = va;\n              var ha = V(aa);\n\n              if (null == la || null == ha || null == ma) {\n                F.a = 1;\n                break c;\n              }\n\n              var pa = ma;\n\n              for (Da = U = 0; Da < W; ++Da) {\n                var ja = la[Da],\n                    da = ja.G,\n                    ea = ja.H,\n                    Fa = 0,\n                    ra = 1,\n                    Ha = 0;\n\n                for (ba = 0; 5 > ba; ++ba) {\n                  Y = Dc[ba];\n                  da[ba] = pa;\n                  ea[ba] = U;\n                  !ba && 0 < J && (Y += 1 << J);\n\n                  d: {\n                    var sa,\n                        za = Y,\n                        ta = F,\n                        oa = ha,\n                        db = pa,\n                        eb = U,\n                        Ia = 0,\n                        Ka = ta.m,\n                        fb = D(Ka, 1);\n                    M(oa, 0, 0, za);\n\n                    if (fb) {\n                      var gb = D(Ka, 1) + 1,\n                          hb = D(Ka, 1),\n                          Ja = D(Ka, 0 == hb ? 1 : 8);\n                      oa[Ja] = 1;\n                      2 == gb && (Ja = D(Ka, 8), oa[Ja] = 1);\n                      var ya = 1;\n                    } else {\n                      var Ua = V(19),\n                          Va = D(Ka, 4) + 4;\n\n                      if (19 < Va) {\n                        ta.a = 3;\n                        var Aa = 0;\n                        break d;\n                      }\n\n                      for (sa = 0; sa < Va; ++sa) {\n                        Ua[ne[sa]] = D(Ka, 3);\n                      }\n\n                      var Ba = void 0,\n                          sb = void 0,\n                          Wa = ta,\n                          ib = Ua,\n                          Ca = za,\n                          Xa = oa,\n                          Oa = 0,\n                          La = Wa.m,\n                          Ya = 8,\n                          Za = wa(128, O);\n\n                      e: for (;;) {\n                        if (!Z(Za, 0, 7, ib, 19)) break e;\n\n                        if (D(La, 1)) {\n                          var kb = 2 + 2 * D(La, 3),\n                              Ba = 2 + D(La, kb);\n                          if (Ba > Ca) break e;\n                        } else Ba = Ca;\n\n                        for (sb = 0; sb < Ca && Ba--;) {\n                          Sa(La);\n                          var $a = Za[0 + (pb(La) & 127)];\n                          qb(La, La.u + $a.g);\n                          var jb = $a.value;\n                          if (16 > jb) Xa[sb++] = jb, 0 != jb && (Ya = jb);else {\n                            var lb = 16 == jb,\n                                ab = jb - 16,\n                                mb = oe[ab],\n                                bb = D(La, pe[ab]) + mb;\n                            if (sb + bb > Ca) break e;else for (var nb = lb ? Ya : 0; 0 < bb--;) {\n                              Xa[sb++] = nb;\n                            }\n                          }\n                        }\n\n                        Oa = 1;\n                        break e;\n                      }\n\n                      Oa || (Wa.a = 3);\n                      ya = Oa;\n                    }\n\n                    (ya = ya && !Ka.h) && (Ia = Z(db, eb, 8, oa, za));\n                    ya && 0 != Ia ? Aa = Ia : (ta.a = 3, Aa = 0);\n                  }\n\n                  if (0 == Aa) break c;\n                  ra && 1 == qe[ba] && (ra = 0 == pa[U].g);\n                  Fa += pa[U].g;\n                  U += Aa;\n\n                  if (3 >= ba) {\n                    var Pa = ha[0],\n                        tb;\n\n                    for (tb = 1; tb < Y; ++tb) {\n                      ha[tb] > Pa && (Pa = ha[tb]);\n                    }\n\n                    Ha += Pa;\n                  }\n                }\n\n                ja.nd = ra;\n                ja.Qb = 0;\n                ra && (ja.qb = (da[3][ea[3] + 0].value << 24 | da[1][ea[1] + 0].value << 16 | da[2][ea[2] + 0].value) >>> 0, 0 == Fa && 256 > da[0][ea[0] + 0].value && (ja.Qb = 1, ja.qb += da[0][ea[0] + 0].value << 8));\n                ja.jc = !ja.Qb && 6 > Ha;\n\n                if (ja.jc) {\n                  var Ga,\n                      Ea = ja;\n\n                  for (Ga = 0; Ga < xb; ++Ga) {\n                    var Ma = Ga,\n                        Na = Ea.pd[Ma],\n                        vb = Ea.G[0][Ea.H[0] + Ma];\n                    256 <= vb.value ? (Na.g = vb.g + 256, Na.value = vb.value) : (Na.g = 0, Na.value = 0, Ma >>= ub(vb, 8, Na), Ma >>= ub(Ea.G[1][Ea.H[1] + Ma], 16, Na), Ma >>= ub(Ea.G[2][Ea.H[2] + Ma], 0, Na), ub(Ea.G[3][Ea.H[3] + Ma], 24, Na));\n                  }\n                }\n              }\n\n              R.vc = P;\n              R.Wb = W;\n              R.Ya = la;\n              R.yc = ma;\n              H = 1;\n              break b;\n            }\n\n            H = 0;\n          }\n          f = H;\n\n          if (!f) {\n            d.a = 3;\n            break a;\n          }\n\n          if (0 < n) {\n            if (l.ua = 1 << n, !Zb(l.Wa, n)) {\n              d.a = 1;\n              f = 0;\n              break a;\n            }\n          } else l.ua = 0;\n\n          var Qa = d,\n              cb = g,\n              ob = h,\n              Ra = Qa.s,\n              Ta = Ra.xc;\n          Qa.c = cb;\n          Qa.i = ob;\n          Ra.md = xa(cb, Ta);\n          Ra.wc = 0 == Ta ? -1 : (1 << Ta) - 1;\n\n          if (c) {\n            d.xb = re;\n            break a;\n          }\n\n          m = V(g * h);\n\n          if (null == m) {\n            d.a = 1;\n            f = 0;\n            break a;\n          }\n\n          f = (f = Jb(d, m, 0, g, h, h, null)) && !k.h;\n          break a;\n        }\n\n        f ? (null != e ? e[0] = m : (x(null == m), x(c)), d.$ = 0, c || Ac(l)) : Ac(l);\n        return f;\n      }\n\n      function Ec(a, b) {\n        var c = a.c * a.i,\n            d = c + b + 16 * b;\n        x(a.c <= b);\n        a.V = V(d);\n        if (null == a.V) return a.Ta = null, a.Ua = 0, a.a = 1, 0;\n        a.Ta = a.V;\n        a.Ua = a.Ba + c + b;\n        return 1;\n      }\n\n      function se(a, b) {\n        var c = a.C,\n            d = b - c,\n            e = a.V,\n            f = a.Ba + a.c * c;\n\n        for (x(b <= a.l.o); 0 < d;) {\n          var g = 16 < d ? 16 : d,\n              h = a.l.ma,\n              k = a.l.width,\n              l = k * g,\n              m = h.ca,\n              n = h.tb + k * c,\n              r = a.Ta,\n              q = a.Ua;\n          oc(a, g, e, f);\n          Fc(r, q, m, n, l);\n          zc(h, c, c + g, m, n, k);\n          d -= g;\n          e += g * a.c;\n          c += g;\n        }\n\n        x(c == b);\n        a.C = a.Ma = b;\n      }\n\n      function te(a, b) {\n        var c = [0],\n            d = [0],\n            e = [0];\n\n        a: for (;;) {\n          if (null == a) return 0;\n          if (null == b) return a.a = 2, 0;\n          a.l = b;\n          a.a = 0;\n          cb(a.m, b.data, b.w, b.ha);\n\n          if (!mc(a.m, c, d, e)) {\n            a.a = 3;\n            break a;\n          }\n\n          a.xb = Cc;\n          b.width = c[0];\n          b.height = d[0];\n          if (!rb(c[0], d[0], 1, a, null)) break a;\n          return 1;\n        }\n\n        x(0 != a.a);\n        return 0;\n      }\n\n      function ue() {\n        this.ub = this.yd = this.td = this.Rb = 0;\n      }\n\n      function ve() {\n        this.Kd = this.Ld = this.Ud = this.Td = this.i = this.c = 0;\n      }\n\n      function we() {\n        this.Fb = this.Bb = this.Cb = 0;\n        this.Zb = V(4);\n        this.Lb = V(4);\n      }\n\n      function Gc() {\n        this.Yb = wb();\n      }\n\n      function xe() {\n        this.jb = V(3);\n        this.Wc = Ed([4, 8], Gc);\n        this.Xc = Ed([4, 17], Gc);\n      }\n\n      function ye() {\n        this.Pc = this.wb = this.Tb = this.zd = 0;\n        this.vd = new V(4);\n        this.od = new V(4);\n      }\n\n      function Xa() {\n        this.ld = this.La = this.dd = this.tc = 0;\n      }\n\n      function Hc() {\n        this.Na = this.la = 0;\n      }\n\n      function ze() {\n        this.Sc = [0, 0];\n        this.Eb = [0, 0];\n        this.Qc = [0, 0];\n        this.ia = this.lc = 0;\n      }\n\n      function Kb() {\n        this.ad = V(384);\n        this.Za = 0;\n        this.Ob = V(16);\n        this.$b = this.Ad = this.ia = this.Gc = this.Hc = this.Dd = 0;\n      }\n\n      function Ae() {\n        this.uc = this.M = this.Nb = 0;\n        this.wa = Array(new Xa());\n        this.Y = 0;\n        this.ya = Array(new Kb());\n        this.aa = 0;\n        this.l = new Oa();\n      }\n\n      function Ic() {\n        this.y = V(16);\n        this.f = V(8);\n        this.ea = V(8);\n      }\n\n      function Be() {\n        this.cb = this.a = 0;\n        this.sc = \"\";\n        this.m = new Wb();\n        this.Od = new ue();\n        this.Kc = new ve();\n        this.ed = new ye();\n        this.Qa = new we();\n        this.Ic = this.$c = this.Aa = 0;\n        this.D = new Ae();\n        this.Xb = this.Va = this.Hb = this.zb = this.yb = this.Ub = this.za = 0;\n        this.Jc = wa(8, Wb);\n        this.ia = 0;\n        this.pb = wa(4, ze);\n        this.Pa = new xe();\n        this.Bd = this.kc = 0;\n        this.Ac = [];\n        this.Bc = 0;\n        this.zc = [0, 0, 0, 0];\n        this.Gd = Array(new Ic());\n        this.Hd = 0;\n        this.rb = Array(new Hc());\n        this.sb = 0;\n        this.wa = Array(new Xa());\n        this.Y = 0;\n        this.oc = [];\n        this.pc = 0;\n        this.sa = [];\n        this.ta = 0;\n        this.qa = [];\n        this.ra = 0;\n        this.Ha = [];\n        this.B = this.R = this.Ia = 0;\n        this.Ec = [];\n        this.M = this.ja = this.Vb = this.Fc = 0;\n        this.ya = Array(new Kb());\n        this.L = this.aa = 0;\n        this.gd = Ed([4, 2], Xa);\n        this.ga = null;\n        this.Fa = [];\n        this.Cc = this.qc = this.P = 0;\n        this.Gb = [];\n        this.Uc = 0;\n        this.mb = [];\n        this.nb = 0;\n        this.rc = [];\n        this.Ga = this.Vc = 0;\n      }\n\n      function ga(a, b) {\n        return 0 > a ? 0 : a > b ? b : a;\n      }\n\n      function Oa() {\n        this.T = this.U = this.ka = this.height = this.width = 0;\n        this.y = [];\n        this.f = [];\n        this.ea = [];\n        this.Rc = this.fa = this.W = this.N = this.O = 0;\n        this.ma = \"void\";\n        this.put = \"VP8IoPutHook\";\n        this.ac = \"VP8IoSetupHook\";\n        this.bc = \"VP8IoTeardownHook\";\n        this.ha = this.Kb = 0;\n        this.data = [];\n        this.hb = this.ib = this.da = this.o = this.j = this.va = this.v = this.Da = this.ob = this.w = 0;\n        this.F = [];\n        this.J = 0;\n      }\n\n      function Ce() {\n        var a = new Be();\n        null != a && (a.a = 0, a.sc = \"OK\", a.cb = 0, a.Xb = 0, oa || (oa = De));\n        return a;\n      }\n\n      function T(a, b, c) {\n        0 == a.a && (a.a = b, a.sc = c, a.cb = 0);\n        return 0;\n      }\n\n      function Jc(a, b, c) {\n        return 3 <= c && 157 == a[b + 0] && 1 == a[b + 1] && 42 == a[b + 2];\n      }\n\n      function Kc(a, b) {\n        if (null == a) return 0;\n        a.a = 0;\n        a.sc = \"OK\";\n        if (null == b) return T(a, 2, \"null VP8Io passed to VP8GetHeaders()\");\n        var c = b.data;\n        var d = b.w;\n        var e = b.ha;\n        if (4 > e) return T(a, 7, \"Truncated header.\");\n        var f = c[d + 0] | c[d + 1] << 8 | c[d + 2] << 16;\n        var g = a.Od;\n        g.Rb = !(f & 1);\n        g.td = f >> 1 & 7;\n        g.yd = f >> 4 & 1;\n        g.ub = f >> 5;\n        if (3 < g.td) return T(a, 3, \"Incorrect keyframe parameters.\");\n        if (!g.yd) return T(a, 4, \"Frame not displayable.\");\n        d += 3;\n        e -= 3;\n        var h = a.Kc;\n\n        if (g.Rb) {\n          if (7 > e) return T(a, 7, \"cannot parse picture header\");\n          if (!Jc(c, d, e)) return T(a, 3, \"Bad code word\");\n          h.c = (c[d + 4] << 8 | c[d + 3]) & 16383;\n          h.Td = c[d + 4] >> 6;\n          h.i = (c[d + 6] << 8 | c[d + 5]) & 16383;\n          h.Ud = c[d + 6] >> 6;\n          d += 7;\n          e -= 7;\n          a.za = h.c + 15 >> 4;\n          a.Ub = h.i + 15 >> 4;\n          b.width = h.c;\n          b.height = h.i;\n          b.Da = 0;\n          b.j = 0;\n          b.v = 0;\n          b.va = b.width;\n          b.o = b.height;\n          b.da = 0;\n          b.ib = b.width;\n          b.hb = b.height;\n          b.U = b.width;\n          b.T = b.height;\n          f = a.Pa;\n          M(f.jb, 0, 255, f.jb.length);\n          f = a.Qa;\n          x(null != f);\n          f.Cb = 0;\n          f.Bb = 0;\n          f.Fb = 1;\n          M(f.Zb, 0, 0, f.Zb.length);\n          M(f.Lb, 0, 0, f.Lb);\n        }\n\n        if (g.ub > e) return T(a, 7, \"bad partition length\");\n        f = a.m;\n        ma(f, c, d, g.ub);\n        d += g.ub;\n        e -= g.ub;\n        g.Rb && (h.Ld = G(f), h.Kd = G(f));\n        h = a.Qa;\n        var k = a.Pa,\n            l;\n        x(null != f);\n        x(null != h);\n        h.Cb = G(f);\n\n        if (h.Cb) {\n          h.Bb = G(f);\n\n          if (G(f)) {\n            h.Fb = G(f);\n\n            for (l = 0; 4 > l; ++l) {\n              h.Zb[l] = G(f) ? ca(f, 7) : 0;\n            }\n\n            for (l = 0; 4 > l; ++l) {\n              h.Lb[l] = G(f) ? ca(f, 6) : 0;\n            }\n          }\n\n          if (h.Bb) for (l = 0; 3 > l; ++l) {\n            k.jb[l] = G(f) ? na(f, 8) : 255;\n          }\n        } else h.Bb = 0;\n\n        if (f.Ka) return T(a, 3, \"cannot parse segment header\");\n        h = a.ed;\n        h.zd = G(f);\n        h.Tb = na(f, 6);\n        h.wb = na(f, 3);\n        h.Pc = G(f);\n\n        if (h.Pc && G(f)) {\n          for (k = 0; 4 > k; ++k) {\n            G(f) && (h.vd[k] = ca(f, 6));\n          }\n\n          for (k = 0; 4 > k; ++k) {\n            G(f) && (h.od[k] = ca(f, 6));\n          }\n        }\n\n        a.L = 0 == h.Tb ? 0 : h.zd ? 1 : 2;\n        if (f.Ka) return T(a, 3, \"cannot parse filter header\");\n        l = d;\n        var m = e;\n        e = l;\n        d = l + m;\n        h = m;\n        a.Xb = (1 << na(a.m, 2)) - 1;\n        k = a.Xb;\n        if (m < 3 * k) c = 7;else {\n          l += 3 * k;\n          h -= 3 * k;\n\n          for (m = 0; m < k; ++m) {\n            var n = c[e + 0] | c[e + 1] << 8 | c[e + 2] << 16;\n            n > h && (n = h);\n            ma(a.Jc[+m], c, l, n);\n            l += n;\n            h -= n;\n            e += 3;\n          }\n\n          ma(a.Jc[+k], c, l, h);\n          c = l < d ? 0 : 5;\n        }\n        if (0 != c) return T(a, c, \"cannot parse partitions\");\n        l = a.m;\n        c = na(l, 7);\n        e = G(l) ? ca(l, 4) : 0;\n        d = G(l) ? ca(l, 4) : 0;\n        h = G(l) ? ca(l, 4) : 0;\n        k = G(l) ? ca(l, 4) : 0;\n        l = G(l) ? ca(l, 4) : 0;\n        m = a.Qa;\n\n        for (n = 0; 4 > n; ++n) {\n          if (m.Cb) {\n            var r = m.Zb[n];\n            m.Fb || (r += c);\n          } else if (0 < n) {\n            a.pb[n] = a.pb[0];\n            continue;\n          } else r = c;\n\n          var q = a.pb[n];\n          q.Sc[0] = Lb[ga(r + e, 127)];\n          q.Sc[1] = Mb[ga(r + 0, 127)];\n          q.Eb[0] = 2 * Lb[ga(r + d, 127)];\n          q.Eb[1] = 101581 * Mb[ga(r + h, 127)] >> 16;\n          8 > q.Eb[1] && (q.Eb[1] = 8);\n          q.Qc[0] = Lb[ga(r + k, 117)];\n          q.Qc[1] = Mb[ga(r + l, 127)];\n          q.lc = r + l;\n        }\n\n        if (!g.Rb) return T(a, 4, \"Not a key frame.\");\n        G(f);\n        g = a.Pa;\n\n        for (c = 0; 4 > c; ++c) {\n          for (e = 0; 8 > e; ++e) {\n            for (d = 0; 3 > d; ++d) {\n              for (h = 0; 11 > h; ++h) {\n                k = K(f, Ee[c][e][d][h]) ? na(f, 8) : Fe[c][e][d][h], g.Wc[c][e].Yb[d][h] = k;\n              }\n            }\n          }\n\n          for (e = 0; 17 > e; ++e) {\n            g.Xc[c][e] = g.Wc[c][Ge[e]];\n          }\n        }\n\n        a.kc = G(f);\n        a.kc && (a.Bd = na(f, 8));\n        return a.cb = 1;\n      }\n\n      function De(a, b, c, d, e, f, g) {\n        var h = b[e].Yb[c];\n\n        for (c = 0; 16 > e; ++e) {\n          if (!K(a, h[c + 0])) return e;\n\n          for (; !K(a, h[c + 1]);) {\n            if (h = b[++e].Yb[0], c = 0, 16 == e) return 16;\n          }\n\n          var k = b[e + 1].Yb;\n\n          if (K(a, h[c + 2])) {\n            var l = a,\n                m = h,\n                n = c;\n            var r = 0;\n            if (K(l, m[n + 3])) {\n              if (K(l, m[n + 6])) {\n                h = 0;\n                r = K(l, m[n + 8]);\n                m = K(l, m[n + 9 + r]);\n                n = 2 * r + m;\n                r = 0;\n\n                for (m = He[n]; m[h]; ++h) {\n                  r += r + K(l, m[h]);\n                }\n\n                r += 3 + (8 << n);\n              } else K(l, m[n + 7]) ? (r = 7 + 2 * K(l, 165), r += K(l, 145)) : r = 5 + K(l, 159);\n            } else K(l, m[n + 4]) ? r = 3 + K(l, m[n + 5]) : r = 2;\n            h = k[2];\n          } else r = 1, h = k[1];\n\n          k = g + Ie[e];\n          l = a;\n          0 > l.b && Qa(l);\n          var m = l.b,\n              n = l.Ca >> 1,\n              q = n - (l.I >> m) >> 31;\n          --l.b;\n          l.Ca += q;\n          l.Ca |= 1;\n          l.I -= (n + 1 & q) << m;\n          f[k] = ((r ^ q) - q) * d[(0 < e) + 0];\n        }\n\n        return 16;\n      }\n\n      function Lc(a) {\n        var b = a.rb[a.sb - 1];\n        b.la = 0;\n        b.Na = 0;\n        M(a.zc, 0, 0, a.zc.length);\n        a.ja = 0;\n      }\n\n      function Je(a, b) {\n        for (a.M = 0; a.M < a.Va; ++a.M) {\n          var c = a.Jc[a.M & a.Xb],\n              d = a.m,\n              e = a,\n              f;\n\n          for (f = 0; f < e.za; ++f) {\n            var g = d;\n            var h = e;\n            var k = h.Ac,\n                l = h.Bc + 4 * f,\n                m = h.zc,\n                n = h.ya[h.aa + f];\n            h.Qa.Bb ? n.$b = K(g, h.Pa.jb[0]) ? 2 + K(g, h.Pa.jb[2]) : K(g, h.Pa.jb[1]) : n.$b = 0;\n            h.kc && (n.Ad = K(g, h.Bd));\n            n.Za = !K(g, 145) + 0;\n\n            if (n.Za) {\n              var r = n.Ob,\n                  q = 0;\n\n              for (h = 0; 4 > h; ++h) {\n                var t = m[0 + h];\n                var v;\n\n                for (v = 0; 4 > v; ++v) {\n                  t = Ke[k[l + v]][t];\n\n                  for (var p = Mc[K(g, t[0])]; 0 < p;) {\n                    p = Mc[2 * p + K(g, t[p])];\n                  }\n\n                  t = -p;\n                  k[l + v] = t;\n                }\n\n                I(r, q, k, l, 4);\n                q += 4;\n                m[0 + h] = t;\n              }\n            } else t = K(g, 156) ? K(g, 128) ? 1 : 3 : K(g, 163) ? 2 : 0, n.Ob[0] = t, M(k, l, t, 4), M(m, 0, t, 4);\n\n            n.Dd = K(g, 142) ? K(g, 114) ? K(g, 183) ? 1 : 3 : 2 : 0;\n          }\n\n          if (e.m.Ka) return T(a, 7, \"Premature end-of-partition0 encountered.\");\n\n          for (; a.ja < a.za; ++a.ja) {\n            d = a;\n            e = c;\n            g = d.rb[d.sb - 1];\n            k = d.rb[d.sb + d.ja];\n            f = d.ya[d.aa + d.ja];\n            if (l = d.kc ? f.Ad : 0) g.la = k.la = 0, f.Za || (g.Na = k.Na = 0), f.Hc = 0, f.Gc = 0, f.ia = 0;else {\n              var u,\n                  w,\n                  g = k,\n                  k = e,\n                  l = d.Pa.Xc,\n                  m = d.ya[d.aa + d.ja],\n                  n = d.pb[m.$b];\n              h = m.ad;\n              r = 0;\n              q = d.rb[d.sb - 1];\n              t = v = 0;\n              M(h, r, 0, 384);\n\n              if (m.Za) {\n                var y = 0;\n                var A = l[3];\n              } else {\n                p = V(16);\n                var E = g.Na + q.Na;\n                E = oa(k, l[1], E, n.Eb, 0, p, 0);\n                g.Na = q.Na = (0 < E) + 0;\n                if (1 < E) Nc(p, 0, h, r);else {\n                  var B = p[0] + 3 >> 3;\n\n                  for (p = 0; 256 > p; p += 16) {\n                    h[r + p] = B;\n                  }\n                }\n                y = 1;\n                A = l[0];\n              }\n\n              var C = g.la & 15;\n              var N = q.la & 15;\n\n              for (p = 0; 4 > p; ++p) {\n                var z = N & 1;\n\n                for (B = w = 0; 4 > B; ++B) {\n                  E = z + (C & 1), E = oa(k, A, E, n.Sc, y, h, r), z = E > y, C = C >> 1 | z << 7, w = w << 2 | (3 < E ? 3 : 1 < E ? 2 : 0 != h[r + 0]), r += 16;\n                }\n\n                C >>= 4;\n                N = N >> 1 | z << 7;\n                v = (v << 8 | w) >>> 0;\n              }\n\n              A = C;\n              y = N >> 4;\n\n              for (u = 0; 4 > u; u += 2) {\n                w = 0;\n                C = g.la >> 4 + u;\n                N = q.la >> 4 + u;\n\n                for (p = 0; 2 > p; ++p) {\n                  z = N & 1;\n\n                  for (B = 0; 2 > B; ++B) {\n                    E = z + (C & 1), E = oa(k, l[2], E, n.Qc, 0, h, r), z = 0 < E, C = C >> 1 | z << 3, w = w << 2 | (3 < E ? 3 : 1 < E ? 2 : 0 != h[r + 0]), r += 16;\n                  }\n\n                  C >>= 2;\n                  N = N >> 1 | z << 5;\n                }\n\n                t |= w << 4 * u;\n                A |= C << 4 << u;\n                y |= (N & 240) << u;\n              }\n\n              g.la = A;\n              q.la = y;\n              m.Hc = v;\n              m.Gc = t;\n              m.ia = t & 43690 ? 0 : n.ia;\n              l = !(v | t);\n            }\n            0 < d.L && (d.wa[d.Y + d.ja] = d.gd[f.$b][f.Za], d.wa[d.Y + d.ja].La |= !l);\n            if (e.Ka) return T(a, 7, \"Premature end-of-file encountered.\");\n          }\n\n          Lc(a);\n          c = a;\n          d = b;\n          e = 1;\n          f = c.D;\n          g = 0 < c.L && c.M >= c.zb && c.M <= c.Va;\n          if (0 == c.Aa) a: {\n            f.M = c.M, f.uc = g, Oc(c, f), e = 1;\n            w = c.D;\n            f = w.Nb;\n            t = Ya[c.L];\n            g = t * c.R;\n            k = t / 2 * c.B;\n            p = 16 * f * c.R;\n            B = 8 * f * c.B;\n            l = c.sa;\n            m = c.ta - g + p;\n            n = c.qa;\n            h = c.ra - k + B;\n            r = c.Ha;\n            q = c.Ia - k + B;\n            C = w.M;\n            N = 0 == C;\n            v = C >= c.Va - 1;\n            2 == c.Aa && Oc(c, w);\n            if (w.uc) for (E = c, z = E.D.M, x(E.D.uc), w = E.yb; w < E.Hb; ++w) {\n              var Q = E;\n              y = w;\n              A = z;\n              var S = Q.D,\n                  D = S.Nb;\n              u = Q.R;\n              var S = S.wa[S.Y + y],\n                  F = Q.sa,\n                  H = Q.ta + 16 * D * u + 16 * y,\n                  J = S.dd,\n                  G = S.tc;\n              if (0 != G) if (x(3 <= G), 1 == Q.L) 0 < y && Pc(F, H, u, G + 4), S.La && Qc(F, H, u, G), 0 < A && Rc(F, H, u, G + 4), S.La && Sc(F, H, u, G);else {\n                var L = Q.B,\n                    O = Q.qa,\n                    P = Q.ra + 8 * D * L + 8 * y,\n                    R = Q.Ha,\n                    Q = Q.Ia + 8 * D * L + 8 * y,\n                    D = S.ld;\n                0 < y && (Tc(F, H, u, G + 4, J, D), Uc(O, P, R, Q, L, G + 4, J, D));\n                S.La && (Vc(F, H, u, G, J, D), Wc(O, P, R, Q, L, G, J, D));\n                0 < A && (Xc(F, H, u, G + 4, J, D), Yc(O, P, R, Q, L, G + 4, J, D));\n                S.La && (Zc(F, H, u, G, J, D), $c(O, P, R, Q, L, G, J, D));\n              }\n            }\n            c.ia && alert(\"todo:DitherRow\");\n\n            if (null != d.put) {\n              w = 16 * C;\n              C = 16 * (C + 1);\n              N ? (d.y = c.sa, d.O = c.ta + p, d.f = c.qa, d.N = c.ra + B, d.ea = c.Ha, d.W = c.Ia + B) : (w -= t, d.y = l, d.O = m, d.f = n, d.N = h, d.ea = r, d.W = q);\n              v || (C -= t);\n              C > d.o && (C = d.o);\n              d.F = null;\n              d.J = null;\n\n              if (null != c.Fa && 0 < c.Fa.length && w < C && (d.J = Le(c, d, w, C - w), d.F = c.mb, null == d.F && 0 == d.F.length)) {\n                e = T(c, 3, \"Could not decode alpha data.\");\n                break a;\n              }\n\n              w < d.j && (t = d.j - w, w = d.j, x(!(t & 1)), d.O += c.R * t, d.N += c.B * (t >> 1), d.W += c.B * (t >> 1), null != d.F && (d.J += d.width * t));\n              w < C && (d.O += d.v, d.N += d.v >> 1, d.W += d.v >> 1, null != d.F && (d.J += d.v), d.ka = w - d.j, d.U = d.va - d.v, d.T = C - w, e = d.put(d));\n            }\n\n            f + 1 != c.Ic || v || (I(c.sa, c.ta - g, l, m + 16 * c.R, g), I(c.qa, c.ra - k, n, h + 8 * c.B, k), I(c.Ha, c.Ia - k, r, q + 8 * c.B, k));\n          }\n          if (!e) return T(a, 6, \"Output aborted.\");\n        }\n\n        return 1;\n      }\n\n      function Me(a, b) {\n        if (null == a) return 0;\n        if (null == b) return T(a, 2, \"NULL VP8Io parameter in VP8Decode().\");\n        if (!a.cb && !Kc(a, b)) return 0;\n        x(a.cb);\n\n        if (null == b.ac || b.ac(b)) {\n          b.ob && (a.L = 0);\n          var c = Ya[a.L];\n          2 == a.L ? (a.yb = 0, a.zb = 0) : (a.yb = b.v - c >> 4, a.zb = b.j - c >> 4, 0 > a.yb && (a.yb = 0), 0 > a.zb && (a.zb = 0));\n          a.Va = b.o + 15 + c >> 4;\n          a.Hb = b.va + 15 + c >> 4;\n          a.Hb > a.za && (a.Hb = a.za);\n          a.Va > a.Ub && (a.Va = a.Ub);\n\n          if (0 < a.L) {\n            var d = a.ed;\n\n            for (c = 0; 4 > c; ++c) {\n              var e;\n\n              if (a.Qa.Cb) {\n                var f = a.Qa.Lb[c];\n                a.Qa.Fb || (f += d.Tb);\n              } else f = d.Tb;\n\n              for (e = 0; 1 >= e; ++e) {\n                var g = a.gd[c][e],\n                    h = f;\n                d.Pc && (h += d.vd[0], e && (h += d.od[0]));\n                h = 0 > h ? 0 : 63 < h ? 63 : h;\n\n                if (0 < h) {\n                  var k = h;\n                  0 < d.wb && (k = 4 < d.wb ? k >> 2 : k >> 1, k > 9 - d.wb && (k = 9 - d.wb));\n                  1 > k && (k = 1);\n                  g.dd = k;\n                  g.tc = 2 * h + k;\n                  g.ld = 40 <= h ? 2 : 15 <= h ? 1 : 0;\n                } else g.tc = 0;\n\n                g.La = e;\n              }\n            }\n          }\n\n          c = 0;\n        } else T(a, 6, \"Frame setup failed\"), c = a.a;\n\n        if (c = 0 == c) {\n          if (c) {\n            a.$c = 0;\n            0 < a.Aa || (a.Ic = Ne);\n\n            b: {\n              c = a.Ic;\n              var k = a.za,\n                  d = 4 * k,\n                  l = 32 * k,\n                  m = k + 1,\n                  n = 0 < a.L ? k * (0 < a.Aa ? 2 : 1) : 0,\n                  r = (2 == a.Aa ? 2 : 1) * k;\n              e = 3 * (16 * c + Ya[a.L]) / 2 * l;\n              f = null != a.Fa && 0 < a.Fa.length ? a.Kc.c * a.Kc.i : 0;\n              g = d + 832 + e + f;\n              if (g != g) c = 0;else {\n                if (g > a.Vb) {\n                  a.Vb = 0;\n                  a.Ec = V(g);\n                  a.Fc = 0;\n\n                  if (null == a.Ec) {\n                    c = T(a, 1, \"no memory during frame initialization.\");\n                    break b;\n                  }\n\n                  a.Vb = g;\n                }\n\n                g = a.Ec;\n                h = a.Fc;\n                a.Ac = g;\n                a.Bc = h;\n                h += d;\n                a.Gd = wa(l, Ic);\n                a.Hd = 0;\n                a.rb = wa(m + 1, Hc);\n                a.sb = 1;\n                a.wa = n ? wa(n, Xa) : null;\n                a.Y = 0;\n                a.D.Nb = 0;\n                a.D.wa = a.wa;\n                a.D.Y = a.Y;\n                0 < a.Aa && (a.D.Y += k);\n                x(!0);\n                a.oc = g;\n                a.pc = h;\n                h += 832;\n                a.ya = wa(r, Kb);\n                a.aa = 0;\n                a.D.ya = a.ya;\n                a.D.aa = a.aa;\n                2 == a.Aa && (a.D.aa += k);\n                a.R = 16 * k;\n                a.B = 8 * k;\n                l = Ya[a.L];\n                k = l * a.R;\n                l = l / 2 * a.B;\n                a.sa = g;\n                a.ta = h + k;\n                a.qa = a.sa;\n                a.ra = a.ta + 16 * c * a.R + l;\n                a.Ha = a.qa;\n                a.Ia = a.ra + 8 * c * a.B + l;\n                a.$c = 0;\n                h += e;\n                a.mb = f ? g : null;\n                a.nb = f ? h : null;\n                x(h + f <= a.Fc + a.Vb);\n                Lc(a);\n                M(a.Ac, a.Bc, 0, d);\n                c = 1;\n              }\n            }\n\n            if (c) {\n              b.ka = 0;\n              b.y = a.sa;\n              b.O = a.ta;\n              b.f = a.qa;\n              b.N = a.ra;\n              b.ea = a.Ha;\n              b.Vd = a.Ia;\n              b.fa = a.R;\n              b.Rc = a.B;\n              b.F = null;\n              b.J = 0;\n\n              if (!ad) {\n                for (c = -255; 255 >= c; ++c) {\n                  bd[255 + c] = 0 > c ? -c : c;\n                }\n\n                for (c = -1020; 1020 >= c; ++c) {\n                  cd[1020 + c] = -128 > c ? -128 : 127 < c ? 127 : c;\n                }\n\n                for (c = -112; 112 >= c; ++c) {\n                  dd[112 + c] = -16 > c ? -16 : 15 < c ? 15 : c;\n                }\n\n                for (c = -255; 510 >= c; ++c) {\n                  ed[255 + c] = 0 > c ? 0 : 255 < c ? 255 : c;\n                }\n\n                ad = 1;\n              }\n\n              Nc = Oe;\n              Za = Pe;\n              Nb = Qe;\n              pa = Re;\n              Ob = Se;\n              fd = Te;\n              Xc = Ue;\n              Tc = Ve;\n              Yc = We;\n              Uc = Xe;\n              Zc = Ye;\n              Vc = Ze;\n              $c = $e;\n              Wc = af;\n              Rc = gd;\n              Pc = hd;\n              Sc = bf;\n              Qc = cf;\n              W[0] = df;\n              W[1] = ef;\n              W[2] = ff;\n              W[3] = gf;\n              W[4] = hf;\n              W[5] = jf;\n              W[6] = kf;\n              W[7] = lf;\n              W[8] = mf;\n              W[9] = nf;\n              Y[0] = of;\n              Y[1] = pf;\n              Y[2] = qf;\n              Y[3] = rf;\n              Y[4] = sf;\n              Y[5] = tf;\n              Y[6] = uf;\n              ka[0] = vf;\n              ka[1] = wf;\n              ka[2] = xf;\n              ka[3] = yf;\n              ka[4] = zf;\n              ka[5] = Af;\n              ka[6] = Bf;\n              c = 1;\n            } else c = 0;\n          }\n\n          c && (c = Je(a, b));\n          null != b.bc && b.bc(b);\n          c &= 1;\n        }\n\n        if (!c) return 0;\n        a.cb = 0;\n        return c;\n      }\n\n      function qa(a, b, c, d, e) {\n        e = a[b + c + 32 * d] + (e >> 3);\n        a[b + c + 32 * d] = e & -256 ? 0 > e ? 0 : 255 : e;\n      }\n\n      function kb(a, b, c, d, e, f) {\n        qa(a, b, 0, c, d + e);\n        qa(a, b, 1, c, d + f);\n        qa(a, b, 2, c, d - f);\n        qa(a, b, 3, c, d - e);\n      }\n\n      function da(a) {\n        return (20091 * a >> 16) + a;\n      }\n\n      function id(a, b, c, d) {\n        var e = 0,\n            f;\n        var g = V(16);\n\n        for (f = 0; 4 > f; ++f) {\n          var h = a[b + 0] + a[b + 8];\n          var k = a[b + 0] - a[b + 8];\n          var l = (35468 * a[b + 4] >> 16) - da(a[b + 12]);\n          var m = da(a[b + 4]) + (35468 * a[b + 12] >> 16);\n          g[e + 0] = h + m;\n          g[e + 1] = k + l;\n          g[e + 2] = k - l;\n          g[e + 3] = h - m;\n          e += 4;\n          b++;\n        }\n\n        for (f = e = 0; 4 > f; ++f) {\n          a = g[e + 0] + 4, h = a + g[e + 8], k = a - g[e + 8], l = (35468 * g[e + 4] >> 16) - da(g[e + 12]), m = da(g[e + 4]) + (35468 * g[e + 12] >> 16), qa(c, d, 0, 0, h + m), qa(c, d, 1, 0, k + l), qa(c, d, 2, 0, k - l), qa(c, d, 3, 0, h - m), e++, d += 32;\n        }\n      }\n\n      function Te(a, b, c, d) {\n        var e = a[b + 0] + 4,\n            f = 35468 * a[b + 4] >> 16,\n            g = da(a[b + 4]),\n            h = 35468 * a[b + 1] >> 16;\n        a = da(a[b + 1]);\n        kb(c, d, 0, e + g, a, h);\n        kb(c, d, 1, e + f, a, h);\n        kb(c, d, 2, e - f, a, h);\n        kb(c, d, 3, e - g, a, h);\n      }\n\n      function Pe(a, b, c, d, e) {\n        id(a, b, c, d);\n        e && id(a, b + 16, c, d + 4);\n      }\n\n      function Qe(a, b, c, d) {\n        Za(a, b + 0, c, d, 1);\n        Za(a, b + 32, c, d + 128, 1);\n      }\n\n      function Re(a, b, c, d) {\n        a = a[b + 0] + 4;\n        var e;\n\n        for (e = 0; 4 > e; ++e) {\n          for (b = 0; 4 > b; ++b) {\n            qa(c, d, b, e, a);\n          }\n        }\n      }\n\n      function Se(a, b, c, d) {\n        a[b + 0] && pa(a, b + 0, c, d);\n        a[b + 16] && pa(a, b + 16, c, d + 4);\n        a[b + 32] && pa(a, b + 32, c, d + 128);\n        a[b + 48] && pa(a, b + 48, c, d + 128 + 4);\n      }\n\n      function Oe(a, b, c, d) {\n        var e = V(16),\n            f;\n\n        for (f = 0; 4 > f; ++f) {\n          var g = a[b + 0 + f] + a[b + 12 + f];\n          var h = a[b + 4 + f] + a[b + 8 + f];\n          var k = a[b + 4 + f] - a[b + 8 + f];\n          var l = a[b + 0 + f] - a[b + 12 + f];\n          e[0 + f] = g + h;\n          e[8 + f] = g - h;\n          e[4 + f] = l + k;\n          e[12 + f] = l - k;\n        }\n\n        for (f = 0; 4 > f; ++f) {\n          a = e[0 + 4 * f] + 3, g = a + e[3 + 4 * f], h = e[1 + 4 * f] + e[2 + 4 * f], k = e[1 + 4 * f] - e[2 + 4 * f], l = a - e[3 + 4 * f], c[d + 0] = g + h >> 3, c[d + 16] = l + k >> 3, c[d + 32] = g - h >> 3, c[d + 48] = l - k >> 3, d += 64;\n        }\n      }\n\n      function Pb(a, b, c) {\n        var d = b - 32,\n            e = R,\n            f = 255 - a[d - 1],\n            g;\n\n        for (g = 0; g < c; ++g) {\n          var h = e,\n              k = f + a[b - 1],\n              l;\n\n          for (l = 0; l < c; ++l) {\n            a[b + l] = h[k + a[d + l]];\n          }\n\n          b += 32;\n        }\n      }\n\n      function ef(a, b) {\n        Pb(a, b, 4);\n      }\n\n      function wf(a, b) {\n        Pb(a, b, 8);\n      }\n\n      function pf(a, b) {\n        Pb(a, b, 16);\n      }\n\n      function qf(a, b) {\n        var c;\n\n        for (c = 0; 16 > c; ++c) {\n          I(a, b + 32 * c, a, b - 32, 16);\n        }\n      }\n\n      function rf(a, b) {\n        var c;\n\n        for (c = 16; 0 < c; --c) {\n          M(a, b, a[b - 1], 16), b += 32;\n        }\n      }\n\n      function $a(a, b, c) {\n        var d;\n\n        for (d = 0; 16 > d; ++d) {\n          M(b, c + 32 * d, a, 16);\n        }\n      }\n\n      function of(a, b) {\n        var c = 16,\n            d;\n\n        for (d = 0; 16 > d; ++d) {\n          c += a[b - 1 + 32 * d] + a[b + d - 32];\n        }\n\n        $a(c >> 5, a, b);\n      }\n\n      function sf(a, b) {\n        var c = 8,\n            d;\n\n        for (d = 0; 16 > d; ++d) {\n          c += a[b - 1 + 32 * d];\n        }\n\n        $a(c >> 4, a, b);\n      }\n\n      function tf(a, b) {\n        var c = 8,\n            d;\n\n        for (d = 0; 16 > d; ++d) {\n          c += a[b + d - 32];\n        }\n\n        $a(c >> 4, a, b);\n      }\n\n      function uf(a, b) {\n        $a(128, a, b);\n      }\n\n      function z(a, b, c) {\n        return a + 2 * b + c + 2 >> 2;\n      }\n\n      function ff(a, b) {\n        var c = b - 32,\n            c = new Uint8Array([z(a[c - 1], a[c + 0], a[c + 1]), z(a[c + 0], a[c + 1], a[c + 2]), z(a[c + 1], a[c + 2], a[c + 3]), z(a[c + 2], a[c + 3], a[c + 4])]),\n            d;\n\n        for (d = 0; 4 > d; ++d) {\n          I(a, b + 32 * d, c, 0, c.length);\n        }\n      }\n\n      function gf(a, b) {\n        var c = a[b - 1],\n            d = a[b - 1 + 32],\n            e = a[b - 1 + 64],\n            f = a[b - 1 + 96];\n        ra(a, b + 0, 16843009 * z(a[b - 1 - 32], c, d));\n        ra(a, b + 32, 16843009 * z(c, d, e));\n        ra(a, b + 64, 16843009 * z(d, e, f));\n        ra(a, b + 96, 16843009 * z(e, f, f));\n      }\n\n      function df(a, b) {\n        var c = 4,\n            d;\n\n        for (d = 0; 4 > d; ++d) {\n          c += a[b + d - 32] + a[b - 1 + 32 * d];\n        }\n\n        c >>= 3;\n\n        for (d = 0; 4 > d; ++d) {\n          M(a, b + 32 * d, c, 4);\n        }\n      }\n\n      function hf(a, b) {\n        var c = a[b - 1 + 0],\n            d = a[b - 1 + 32],\n            e = a[b - 1 + 64],\n            f = a[b - 1 - 32],\n            g = a[b + 0 - 32],\n            h = a[b + 1 - 32],\n            k = a[b + 2 - 32],\n            l = a[b + 3 - 32];\n        a[b + 0 + 96] = z(d, e, a[b - 1 + 96]);\n        a[b + 1 + 96] = a[b + 0 + 64] = z(c, d, e);\n        a[b + 2 + 96] = a[b + 1 + 64] = a[b + 0 + 32] = z(f, c, d);\n        a[b + 3 + 96] = a[b + 2 + 64] = a[b + 1 + 32] = a[b + 0 + 0] = z(g, f, c);\n        a[b + 3 + 64] = a[b + 2 + 32] = a[b + 1 + 0] = z(h, g, f);\n        a[b + 3 + 32] = a[b + 2 + 0] = z(k, h, g);\n        a[b + 3 + 0] = z(l, k, h);\n      }\n\n      function kf(a, b) {\n        var c = a[b + 1 - 32],\n            d = a[b + 2 - 32],\n            e = a[b + 3 - 32],\n            f = a[b + 4 - 32],\n            g = a[b + 5 - 32],\n            h = a[b + 6 - 32],\n            k = a[b + 7 - 32];\n        a[b + 0 + 0] = z(a[b + 0 - 32], c, d);\n        a[b + 1 + 0] = a[b + 0 + 32] = z(c, d, e);\n        a[b + 2 + 0] = a[b + 1 + 32] = a[b + 0 + 64] = z(d, e, f);\n        a[b + 3 + 0] = a[b + 2 + 32] = a[b + 1 + 64] = a[b + 0 + 96] = z(e, f, g);\n        a[b + 3 + 32] = a[b + 2 + 64] = a[b + 1 + 96] = z(f, g, h);\n        a[b + 3 + 64] = a[b + 2 + 96] = z(g, h, k);\n        a[b + 3 + 96] = z(h, k, k);\n      }\n\n      function jf(a, b) {\n        var c = a[b - 1 + 0],\n            d = a[b - 1 + 32],\n            e = a[b - 1 + 64],\n            f = a[b - 1 - 32],\n            g = a[b + 0 - 32],\n            h = a[b + 1 - 32],\n            k = a[b + 2 - 32],\n            l = a[b + 3 - 32];\n        a[b + 0 + 0] = a[b + 1 + 64] = f + g + 1 >> 1;\n        a[b + 1 + 0] = a[b + 2 + 64] = g + h + 1 >> 1;\n        a[b + 2 + 0] = a[b + 3 + 64] = h + k + 1 >> 1;\n        a[b + 3 + 0] = k + l + 1 >> 1;\n        a[b + 0 + 96] = z(e, d, c);\n        a[b + 0 + 64] = z(d, c, f);\n        a[b + 0 + 32] = a[b + 1 + 96] = z(c, f, g);\n        a[b + 1 + 32] = a[b + 2 + 96] = z(f, g, h);\n        a[b + 2 + 32] = a[b + 3 + 96] = z(g, h, k);\n        a[b + 3 + 32] = z(h, k, l);\n      }\n\n      function lf(a, b) {\n        var c = a[b + 0 - 32],\n            d = a[b + 1 - 32],\n            e = a[b + 2 - 32],\n            f = a[b + 3 - 32],\n            g = a[b + 4 - 32],\n            h = a[b + 5 - 32],\n            k = a[b + 6 - 32],\n            l = a[b + 7 - 32];\n        a[b + 0 + 0] = c + d + 1 >> 1;\n        a[b + 1 + 0] = a[b + 0 + 64] = d + e + 1 >> 1;\n        a[b + 2 + 0] = a[b + 1 + 64] = e + f + 1 >> 1;\n        a[b + 3 + 0] = a[b + 2 + 64] = f + g + 1 >> 1;\n        a[b + 0 + 32] = z(c, d, e);\n        a[b + 1 + 32] = a[b + 0 + 96] = z(d, e, f);\n        a[b + 2 + 32] = a[b + 1 + 96] = z(e, f, g);\n        a[b + 3 + 32] = a[b + 2 + 96] = z(f, g, h);\n        a[b + 3 + 64] = z(g, h, k);\n        a[b + 3 + 96] = z(h, k, l);\n      }\n\n      function nf(a, b) {\n        var c = a[b - 1 + 0],\n            d = a[b - 1 + 32],\n            e = a[b - 1 + 64],\n            f = a[b - 1 + 96];\n        a[b + 0 + 0] = c + d + 1 >> 1;\n        a[b + 2 + 0] = a[b + 0 + 32] = d + e + 1 >> 1;\n        a[b + 2 + 32] = a[b + 0 + 64] = e + f + 1 >> 1;\n        a[b + 1 + 0] = z(c, d, e);\n        a[b + 3 + 0] = a[b + 1 + 32] = z(d, e, f);\n        a[b + 3 + 32] = a[b + 1 + 64] = z(e, f, f);\n        a[b + 3 + 64] = a[b + 2 + 64] = a[b + 0 + 96] = a[b + 1 + 96] = a[b + 2 + 96] = a[b + 3 + 96] = f;\n      }\n\n      function mf(a, b) {\n        var c = a[b - 1 + 0],\n            d = a[b - 1 + 32],\n            e = a[b - 1 + 64],\n            f = a[b - 1 + 96],\n            g = a[b - 1 - 32],\n            h = a[b + 0 - 32],\n            k = a[b + 1 - 32],\n            l = a[b + 2 - 32];\n        a[b + 0 + 0] = a[b + 2 + 32] = c + g + 1 >> 1;\n        a[b + 0 + 32] = a[b + 2 + 64] = d + c + 1 >> 1;\n        a[b + 0 + 64] = a[b + 2 + 96] = e + d + 1 >> 1;\n        a[b + 0 + 96] = f + e + 1 >> 1;\n        a[b + 3 + 0] = z(h, k, l);\n        a[b + 2 + 0] = z(g, h, k);\n        a[b + 1 + 0] = a[b + 3 + 32] = z(c, g, h);\n        a[b + 1 + 32] = a[b + 3 + 64] = z(d, c, g);\n        a[b + 1 + 64] = a[b + 3 + 96] = z(e, d, c);\n        a[b + 1 + 96] = z(f, e, d);\n      }\n\n      function xf(a, b) {\n        var c;\n\n        for (c = 0; 8 > c; ++c) {\n          I(a, b + 32 * c, a, b - 32, 8);\n        }\n      }\n\n      function yf(a, b) {\n        var c;\n\n        for (c = 0; 8 > c; ++c) {\n          M(a, b, a[b - 1], 8), b += 32;\n        }\n      }\n\n      function lb(a, b, c) {\n        var d;\n\n        for (d = 0; 8 > d; ++d) {\n          M(b, c + 32 * d, a, 8);\n        }\n      }\n\n      function vf(a, b) {\n        var c = 8,\n            d;\n\n        for (d = 0; 8 > d; ++d) {\n          c += a[b + d - 32] + a[b - 1 + 32 * d];\n        }\n\n        lb(c >> 4, a, b);\n      }\n\n      function Af(a, b) {\n        var c = 4,\n            d;\n\n        for (d = 0; 8 > d; ++d) {\n          c += a[b + d - 32];\n        }\n\n        lb(c >> 3, a, b);\n      }\n\n      function zf(a, b) {\n        var c = 4,\n            d;\n\n        for (d = 0; 8 > d; ++d) {\n          c += a[b - 1 + 32 * d];\n        }\n\n        lb(c >> 3, a, b);\n      }\n\n      function Bf(a, b) {\n        lb(128, a, b);\n      }\n\n      function ab(a, b, c) {\n        var d = a[b - c],\n            e = a[b + 0],\n            f = 3 * (e - d) + Qb[1020 + a[b - 2 * c] - a[b + c]],\n            g = mb[112 + (f + 4 >> 3)];\n        a[b - c] = R[255 + d + mb[112 + (f + 3 >> 3)]];\n        a[b + 0] = R[255 + e - g];\n      }\n\n      function jd(a, b, c, d) {\n        var e = a[b + 0],\n            f = a[b + c];\n        return U[255 + a[b - 2 * c] - a[b - c]] > d || U[255 + f - e] > d;\n      }\n\n      function kd(a, b, c, d) {\n        return 4 * U[255 + a[b - c] - a[b + 0]] + U[255 + a[b - 2 * c] - a[b + c]] <= d;\n      }\n\n      function ld(a, b, c, d, e) {\n        var f = a[b - 3 * c],\n            g = a[b - 2 * c],\n            h = a[b - c],\n            k = a[b + 0],\n            l = a[b + c],\n            m = a[b + 2 * c],\n            n = a[b + 3 * c];\n        return 4 * U[255 + h - k] + U[255 + g - l] > d ? 0 : U[255 + a[b - 4 * c] - f] <= e && U[255 + f - g] <= e && U[255 + g - h] <= e && U[255 + n - m] <= e && U[255 + m - l] <= e && U[255 + l - k] <= e;\n      }\n\n      function gd(a, b, c, d) {\n        var e = 2 * d + 1;\n\n        for (d = 0; 16 > d; ++d) {\n          kd(a, b + d, c, e) && ab(a, b + d, c);\n        }\n      }\n\n      function hd(a, b, c, d) {\n        var e = 2 * d + 1;\n\n        for (d = 0; 16 > d; ++d) {\n          kd(a, b + d * c, 1, e) && ab(a, b + d * c, 1);\n        }\n      }\n\n      function bf(a, b, c, d) {\n        var e;\n\n        for (e = 3; 0 < e; --e) {\n          b += 4 * c, gd(a, b, c, d);\n        }\n      }\n\n      function cf(a, b, c, d) {\n        var e;\n\n        for (e = 3; 0 < e; --e) {\n          b += 4, hd(a, b, c, d);\n        }\n      }\n\n      function ea(a, b, c, d, e, f, g, h) {\n        for (f = 2 * f + 1; 0 < e--;) {\n          if (ld(a, b, c, f, g)) if (jd(a, b, c, h)) ab(a, b, c);else {\n            var k = a,\n                l = b,\n                m = c,\n                n = k[l - 2 * m],\n                r = k[l - m],\n                q = k[l + 0],\n                t = k[l + m],\n                v = k[l + 2 * m],\n                p = Qb[1020 + 3 * (q - r) + Qb[1020 + n - t]],\n                u = 27 * p + 63 >> 7,\n                w = 18 * p + 63 >> 7,\n                p = 9 * p + 63 >> 7;\n            k[l - 3 * m] = R[255 + k[l - 3 * m] + p];\n            k[l - 2 * m] = R[255 + n + w];\n            k[l - m] = R[255 + r + u];\n            k[l + 0] = R[255 + q - u];\n            k[l + m] = R[255 + t - w];\n            k[l + 2 * m] = R[255 + v - p];\n          }\n          b += d;\n        }\n      }\n\n      function Fa(a, b, c, d, e, f, g, h) {\n        for (f = 2 * f + 1; 0 < e--;) {\n          if (ld(a, b, c, f, g)) if (jd(a, b, c, h)) ab(a, b, c);else {\n            var k = a,\n                l = b,\n                m = c,\n                n = k[l - m],\n                r = k[l + 0],\n                q = k[l + m],\n                t = 3 * (r - n),\n                v = mb[112 + (t + 4 >> 3)],\n                t = mb[112 + (t + 3 >> 3)],\n                p = v + 1 >> 1;\n            k[l - 2 * m] = R[255 + k[l - 2 * m] + p];\n            k[l - m] = R[255 + n + t];\n            k[l + 0] = R[255 + r - v];\n            k[l + m] = R[255 + q - p];\n          }\n          b += d;\n        }\n      }\n\n      function Ue(a, b, c, d, e, f) {\n        ea(a, b, c, 1, 16, d, e, f);\n      }\n\n      function Ve(a, b, c, d, e, f) {\n        ea(a, b, 1, c, 16, d, e, f);\n      }\n\n      function Ye(a, b, c, d, e, f) {\n        var g;\n\n        for (g = 3; 0 < g; --g) {\n          b += 4 * c, Fa(a, b, c, 1, 16, d, e, f);\n        }\n      }\n\n      function Ze(a, b, c, d, e, f) {\n        var g;\n\n        for (g = 3; 0 < g; --g) {\n          b += 4, Fa(a, b, 1, c, 16, d, e, f);\n        }\n      }\n\n      function We(a, b, c, d, e, f, g, h) {\n        ea(a, b, e, 1, 8, f, g, h);\n        ea(c, d, e, 1, 8, f, g, h);\n      }\n\n      function Xe(a, b, c, d, e, f, g, h) {\n        ea(a, b, 1, e, 8, f, g, h);\n        ea(c, d, 1, e, 8, f, g, h);\n      }\n\n      function $e(a, b, c, d, e, f, g, h) {\n        Fa(a, b + 4 * e, e, 1, 8, f, g, h);\n        Fa(c, d + 4 * e, e, 1, 8, f, g, h);\n      }\n\n      function af(a, b, c, d, e, f, g, h) {\n        Fa(a, b + 4, 1, e, 8, f, g, h);\n        Fa(c, d + 4, 1, e, 8, f, g, h);\n      }\n\n      function Cf() {\n        this.ba = new Cb();\n        this.ec = [];\n        this.cc = [];\n        this.Mc = [];\n        this.Dc = this.Nc = this.dc = this.fc = 0;\n        this.Oa = new Ud();\n        this.memory = 0;\n        this.Ib = \"OutputFunc\";\n        this.Jb = \"OutputAlphaFunc\";\n        this.Nd = \"OutputRowFunc\";\n      }\n\n      function md() {\n        this.data = [];\n        this.offset = this.kd = this.ha = this.w = 0;\n        this.na = [];\n        this.xa = this.gb = this.Ja = this.Sa = this.P = 0;\n      }\n\n      function Df() {\n        this.nc = this.Ea = this.b = this.hc = 0;\n        this.K = [];\n        this.w = 0;\n      }\n\n      function Ef() {\n        this.ua = 0;\n        this.Wa = new ac();\n        this.vb = new ac();\n        this.md = this.xc = this.wc = 0;\n        this.vc = [];\n        this.Wb = 0;\n        this.Ya = new Ub();\n        this.yc = new O();\n      }\n\n      function je() {\n        this.xb = this.a = 0;\n        this.l = new Oa();\n        this.ca = new Cb();\n        this.V = [];\n        this.Ba = 0;\n        this.Ta = [];\n        this.Ua = 0;\n        this.m = new Ra();\n        this.Pb = 0;\n        this.wd = new Ra();\n        this.Ma = this.$ = this.C = this.i = this.c = this.xd = 0;\n        this.s = new Ef();\n        this.ab = 0;\n        this.gc = wa(4, Df);\n        this.Oc = 0;\n      }\n\n      function Ff() {\n        this.Lc = this.Z = this.$a = this.i = this.c = 0;\n        this.l = new Oa();\n        this.ic = 0;\n        this.ca = [];\n        this.tb = 0;\n        this.qd = null;\n        this.rd = 0;\n      }\n\n      function Rb(a, b, c, d, e, f, g) {\n        a = null == a ? 0 : a[b + 0];\n\n        for (b = 0; b < g; ++b) {\n          e[f + b] = a + c[d + b] & 255, a = e[f + b];\n        }\n      }\n\n      function Gf(a, b, c, d, e, f, g) {\n        if (null == a) Rb(null, null, c, d, e, f, g);else {\n          var h;\n\n          for (h = 0; h < g; ++h) {\n            e[f + h] = a[b + h] + c[d + h] & 255;\n          }\n        }\n      }\n\n      function Hf(a, b, c, d, e, f, g) {\n        if (null == a) Rb(null, null, c, d, e, f, g);else {\n          var h = a[b + 0],\n              k = h,\n              l = h,\n              m;\n\n          for (m = 0; m < g; ++m) {\n            h = a[b + m], k = l + h - k, l = c[d + m] + (k & -256 ? 0 > k ? 0 : 255 : k) & 255, k = h, e[f + m] = l;\n          }\n        }\n      }\n\n      function Le(a, b, c, d) {\n        var e = b.width,\n            f = b.o;\n        x(null != a && null != b);\n        if (0 > c || 0 >= d || c + d > f) return null;\n\n        if (!a.Cc) {\n          if (null == a.ga) {\n            a.ga = new Ff();\n            var g;\n            (g = null == a.ga) || (g = b.width * b.o, x(0 == a.Gb.length), a.Gb = V(g), a.Uc = 0, null == a.Gb ? g = 0 : (a.mb = a.Gb, a.nb = a.Uc, a.rc = null, g = 1), g = !g);\n\n            if (!g) {\n              g = a.ga;\n              var h = a.Fa,\n                  k = a.P,\n                  l = a.qc,\n                  m = a.mb,\n                  n = a.nb,\n                  r = k + 1,\n                  q = l - 1,\n                  t = g.l;\n              x(null != h && null != m && null != b);\n              ia[0] = null;\n              ia[1] = Rb;\n              ia[2] = Gf;\n              ia[3] = Hf;\n              g.ca = m;\n              g.tb = n;\n              g.c = b.width;\n              g.i = b.height;\n              x(0 < g.c && 0 < g.i);\n              if (1 >= l) b = 0;else if (g.$a = h[k + 0] >> 0 & 3, g.Z = h[k + 0] >> 2 & 3, g.Lc = h[k + 0] >> 4 & 3, k = h[k + 0] >> 6 & 3, 0 > g.$a || 1 < g.$a || 4 <= g.Z || 1 < g.Lc || k) b = 0;else if (t.put = kc, t.ac = gc, t.bc = lc, t.ma = g, t.width = b.width, t.height = b.height, t.Da = b.Da, t.v = b.v, t.va = b.va, t.j = b.j, t.o = b.o, g.$a) b: {\n                x(1 == g.$a), b = Bc();\n\n                c: for (;;) {\n                  if (null == b) {\n                    b = 0;\n                    break b;\n                  }\n\n                  x(null != g);\n                  g.mc = b;\n                  b.c = g.c;\n                  b.i = g.i;\n                  b.l = g.l;\n                  b.l.ma = g;\n                  b.l.width = g.c;\n                  b.l.height = g.i;\n                  b.a = 0;\n                  cb(b.m, h, r, q);\n                  if (!rb(g.c, g.i, 1, b, null)) break c;\n                  1 == b.ab && 3 == b.gc[0].hc && yc(b.s) ? (g.ic = 1, h = b.c * b.i, b.Ta = null, b.Ua = 0, b.V = V(h), b.Ba = 0, null == b.V ? (b.a = 1, b = 0) : b = 1) : (g.ic = 0, b = Ec(b, g.c));\n                  if (!b) break c;\n                  b = 1;\n                  break b;\n                }\n\n                g.mc = null;\n                b = 0;\n              } else b = q >= g.c * g.i;\n              g = !b;\n            }\n\n            if (g) return null;\n            1 != a.ga.Lc ? a.Ga = 0 : d = f - c;\n          }\n\n          x(null != a.ga);\n          x(c + d <= f);\n\n          a: {\n            h = a.ga;\n            b = h.c;\n            f = h.l.o;\n\n            if (0 == h.$a) {\n              r = a.rc;\n              q = a.Vc;\n              t = a.Fa;\n              k = a.P + 1 + c * b;\n              l = a.mb;\n              m = a.nb + c * b;\n              x(k <= a.P + a.qc);\n              if (0 != h.Z) for (x(null != ia[h.Z]), g = 0; g < d; ++g) {\n                ia[h.Z](r, q, t, k, l, m, b), r = l, q = m, m += b, k += b;\n              } else for (g = 0; g < d; ++g) {\n                I(l, m, t, k, b), r = l, q = m, m += b, k += b;\n              }\n              a.rc = r;\n              a.Vc = q;\n            } else {\n              x(null != h.mc);\n              b = c + d;\n              g = h.mc;\n              x(null != g);\n              x(b <= g.i);\n              if (g.C >= b) b = 1;else if (h.ic || Aa(), h.ic) {\n                var h = g.V,\n                    r = g.Ba,\n                    q = g.c,\n                    v = g.i,\n                    t = 1,\n                    k = g.$ / q,\n                    l = g.$ % q,\n                    m = g.m,\n                    n = g.s,\n                    p = g.$,\n                    u = q * v,\n                    w = q * b,\n                    y = n.wc,\n                    A = p < w ? ha(n, l, k) : null;\n                x(p <= u);\n                x(b <= v);\n                x(yc(n));\n\n                c: for (;;) {\n                  for (; !m.h && p < w;) {\n                    l & y || (A = ha(n, l, k));\n                    x(null != A);\n                    Sa(m);\n                    v = ua(A.G[0], A.H[0], m);\n                    if (256 > v) h[r + p] = v, ++p, ++l, l >= q && (l = 0, ++k, k <= b && !(k % 16) && Ib(g, k));else if (280 > v) {\n                      var v = ib(v - 256, m);\n                      var E = ua(A.G[4], A.H[4], m);\n                      Sa(m);\n                      E = ib(E, m);\n                      E = nc(q, E);\n\n                      if (p >= E && u - p >= v) {\n                        var B;\n\n                        for (B = 0; B < v; ++B) {\n                          h[r + p + B] = h[r + p + B - E];\n                        }\n                      } else {\n                        t = 0;\n                        break c;\n                      }\n\n                      p += v;\n\n                      for (l += v; l >= q;) {\n                        l -= q, ++k, k <= b && !(k % 16) && Ib(g, k);\n                      }\n\n                      p < w && l & y && (A = ha(n, l, k));\n                    } else {\n                      t = 0;\n                      break c;\n                    }\n                    x(m.h == db(m));\n                  }\n\n                  Ib(g, k > b ? b : k);\n                  break c;\n                }\n\n                !t || m.h && p < u ? (t = 0, g.a = m.h ? 5 : 3) : g.$ = p;\n                b = t;\n              } else b = Jb(g, g.V, g.Ba, g.c, g.i, b, se);\n\n              if (!b) {\n                d = 0;\n                break a;\n              }\n            }\n\n            c + d >= f && (a.Cc = 1);\n            d = 1;\n          }\n\n          if (!d) return null;\n          if (a.Cc && (d = a.ga, null != d && (d.mc = null), a.ga = null, 0 < a.Ga)) return alert(\"todo:WebPDequantizeLevels\"), null;\n        }\n\n        return a.nb + c * e;\n      }\n\n      function If(a, b, c, d, e, f) {\n        for (; 0 < e--;) {\n          var g = a,\n              h = b + (c ? 1 : 0),\n              k = a,\n              l = b + (c ? 0 : 3),\n              m;\n\n          for (m = 0; m < d; ++m) {\n            var n = k[l + 4 * m];\n            255 != n && (n *= 32897, g[h + 4 * m + 0] = g[h + 4 * m + 0] * n >> 23, g[h + 4 * m + 1] = g[h + 4 * m + 1] * n >> 23, g[h + 4 * m + 2] = g[h + 4 * m + 2] * n >> 23);\n          }\n\n          b += f;\n        }\n      }\n\n      function Jf(a, b, c, d, e) {\n        for (; 0 < d--;) {\n          var f;\n\n          for (f = 0; f < c; ++f) {\n            var g = a[b + 2 * f + 0],\n                h = a[b + 2 * f + 1],\n                k = h & 15,\n                l = 4369 * k,\n                h = (h & 240 | h >> 4) * l >> 16;\n            a[b + 2 * f + 0] = (g & 240 | g >> 4) * l >> 16 & 240 | (g & 15 | g << 4) * l >> 16 >> 4 & 15;\n            a[b + 2 * f + 1] = h & 240 | k;\n          }\n\n          b += e;\n        }\n      }\n\n      function Kf(a, b, c, d, e, f, g, h) {\n        var k = 255,\n            l,\n            m;\n\n        for (m = 0; m < e; ++m) {\n          for (l = 0; l < d; ++l) {\n            var n = a[b + l];\n            f[g + 4 * l] = n;\n            k &= n;\n          }\n\n          b += c;\n          g += h;\n        }\n\n        return 255 != k;\n      }\n\n      function Lf(a, b, c, d, e) {\n        var f;\n\n        for (f = 0; f < e; ++f) {\n          c[d + f] = a[b + f] >> 8;\n        }\n      }\n\n      function Aa() {\n        za = If;\n        vc = Jf;\n        fc = Kf;\n        Fc = Lf;\n      }\n\n      function va(a, b, c) {\n        self[a] = function (a, e, f, g, h, k, l, m, n, r, q, t, v, p, u, w, y) {\n          var d,\n              E = y - 1 >> 1;\n          var B = h[k + 0] | l[m + 0] << 16;\n          var C = n[r + 0] | q[t + 0] << 16;\n          x(null != a);\n          var z = 3 * B + C + 131074 >> 2;\n          b(a[e + 0], z & 255, z >> 16, v, p);\n          null != f && (z = 3 * C + B + 131074 >> 2, b(f[g + 0], z & 255, z >> 16, u, w));\n\n          for (d = 1; d <= E; ++d) {\n            var D = h[k + d] | l[m + d] << 16;\n            var G = n[r + d] | q[t + d] << 16;\n            var F = B + D + C + G + 524296;\n            var H = F + 2 * (D + C) >> 3;\n            F = F + 2 * (B + G) >> 3;\n            z = H + B >> 1;\n            B = F + D >> 1;\n            b(a[e + 2 * d - 1], z & 255, z >> 16, v, p + (2 * d - 1) * c);\n            b(a[e + 2 * d - 0], B & 255, B >> 16, v, p + (2 * d - 0) * c);\n            null != f && (z = F + C >> 1, B = H + G >> 1, b(f[g + 2 * d - 1], z & 255, z >> 16, u, w + (2 * d - 1) * c), b(f[g + 2 * d + 0], B & 255, B >> 16, u, w + (2 * d + 0) * c));\n            B = D;\n            C = G;\n          }\n\n          y & 1 || (z = 3 * B + C + 131074 >> 2, b(a[e + y - 1], z & 255, z >> 16, v, p + (y - 1) * c), null != f && (z = 3 * C + B + 131074 >> 2, b(f[g + y - 1], z & 255, z >> 16, u, w + (y - 1) * c)));\n        };\n      }\n\n      function ic() {\n        P[Ca] = Mf;\n        P[Ua] = nd;\n        P[tc] = Nf;\n        P[Va] = od;\n        P[ya] = pd;\n        P[Db] = qd;\n        P[wc] = Of;\n        P[zb] = nd;\n        P[Ab] = od;\n        P[Ja] = pd;\n        P[Bb] = qd;\n      }\n\n      function Sb(a) {\n        return a & ~Pf ? 0 > a ? 0 : 255 : a >> rd;\n      }\n\n      function bb(a, b) {\n        return Sb((19077 * a >> 8) + (26149 * b >> 8) - 14234);\n      }\n\n      function nb(a, b, c) {\n        return Sb((19077 * a >> 8) - (6419 * b >> 8) - (13320 * c >> 8) + 8708);\n      }\n\n      function Pa(a, b) {\n        return Sb((19077 * a >> 8) + (33050 * b >> 8) - 17685);\n      }\n\n      function Ga(a, b, c, d, e) {\n        d[e + 0] = bb(a, c);\n        d[e + 1] = nb(a, b, c);\n        d[e + 2] = Pa(a, b);\n      }\n\n      function Tb(a, b, c, d, e) {\n        d[e + 0] = Pa(a, b);\n        d[e + 1] = nb(a, b, c);\n        d[e + 2] = bb(a, c);\n      }\n\n      function sd(a, b, c, d, e) {\n        var f = nb(a, b, c);\n        b = f << 3 & 224 | Pa(a, b) >> 3;\n        d[e + 0] = bb(a, c) & 248 | f >> 5;\n        d[e + 1] = b;\n      }\n\n      function td(a, b, c, d, e) {\n        var f = Pa(a, b) & 240 | 15;\n        d[e + 0] = bb(a, c) & 240 | nb(a, b, c) >> 4;\n        d[e + 1] = f;\n      }\n\n      function ud(a, b, c, d, e) {\n        d[e + 0] = 255;\n        Ga(a, b, c, d, e + 1);\n      }\n\n      function vd(a, b, c, d, e) {\n        Tb(a, b, c, d, e);\n        d[e + 3] = 255;\n      }\n\n      function wd(a, b, c, d, e) {\n        Ga(a, b, c, d, e);\n        d[e + 3] = 255;\n      }\n\n      function ga(a, b) {\n        return 0 > a ? 0 : a > b ? b : a;\n      }\n\n      function la(a, b, c) {\n        self[a] = function (a, e, f, g, h, k, l, m, n) {\n          for (var d = m + (n & -2) * c; m != d;) {\n            b(a[e + 0], f[g + 0], h[k + 0], l, m), b(a[e + 1], f[g + 0], h[k + 0], l, m + c), e += 2, ++g, ++k, m += 2 * c;\n          }\n\n          n & 1 && b(a[e + 0], f[g + 0], h[k + 0], l, m);\n        };\n      }\n\n      function xd(a, b, c) {\n        return 0 == c ? 0 == a ? 0 == b ? 6 : 5 : 0 == b ? 4 : 0 : c;\n      }\n\n      function yd(a, b, c, d, e) {\n        switch (a >>> 30) {\n          case 3:\n            Za(b, c, d, e, 0);\n            break;\n\n          case 2:\n            fd(b, c, d, e);\n            break;\n\n          case 1:\n            pa(b, c, d, e);\n        }\n      }\n\n      function Oc(a, b) {\n        var c,\n            d,\n            e = b.M,\n            f = b.Nb,\n            g = a.oc,\n            h = a.pc + 40,\n            k = a.oc,\n            l = a.pc + 584,\n            m = a.oc,\n            n = a.pc + 600;\n\n        for (c = 0; 16 > c; ++c) {\n          g[h + 32 * c - 1] = 129;\n        }\n\n        for (c = 0; 8 > c; ++c) {\n          k[l + 32 * c - 1] = 129, m[n + 32 * c - 1] = 129;\n        }\n\n        0 < e ? g[h - 1 - 32] = k[l - 1 - 32] = m[n - 1 - 32] = 129 : (M(g, h - 32 - 1, 127, 21), M(k, l - 32 - 1, 127, 9), M(m, n - 32 - 1, 127, 9));\n\n        for (d = 0; d < a.za; ++d) {\n          var r = b.ya[b.aa + d];\n\n          if (0 < d) {\n            for (c = -1; 16 > c; ++c) {\n              I(g, h + 32 * c - 4, g, h + 32 * c + 12, 4);\n            }\n\n            for (c = -1; 8 > c; ++c) {\n              I(k, l + 32 * c - 4, k, l + 32 * c + 4, 4), I(m, n + 32 * c - 4, m, n + 32 * c + 4, 4);\n            }\n          }\n\n          var q = a.Gd,\n              t = a.Hd + d,\n              v = r.ad,\n              p = r.Hc;\n          0 < e && (I(g, h - 32, q[t].y, 0, 16), I(k, l - 32, q[t].f, 0, 8), I(m, n - 32, q[t].ea, 0, 8));\n\n          if (r.Za) {\n            var u = g;\n            var w = h - 32 + 16;\n            0 < e && (d >= a.za - 1 ? M(u, w, q[t].y[15], 4) : I(u, w, q[t + 1].y, 0, 4));\n\n            for (c = 0; 4 > c; c++) {\n              u[w + 128 + c] = u[w + 256 + c] = u[w + 384 + c] = u[w + 0 + c];\n            }\n\n            for (c = 0; 16 > c; ++c, p <<= 2) {\n              u = g, w = h + zd[c], W[r.Ob[c]](u, w), yd(p, v, 16 * +c, u, w);\n            }\n          } else if (u = xd(d, e, r.Ob[0]), Y[u](g, h), 0 != p) for (c = 0; 16 > c; ++c, p <<= 2) {\n            yd(p, v, 16 * +c, g, h + zd[c]);\n          }\n\n          c = r.Gc;\n          u = xd(d, e, r.Dd);\n          ka[u](k, l);\n          ka[u](m, n);\n          r = c >> 0;\n          p = v;\n          u = k;\n          w = l;\n          r & 255 && (r & 170 ? Nb(p, 256, u, w) : Ob(p, 256, u, w));\n          c >>= 8;\n          r = m;\n          p = n;\n          c & 255 && (c & 170 ? Nb(v, 320, r, p) : Ob(v, 320, r, p));\n          e < a.Ub - 1 && (I(q[t].y, 0, g, h + 480, 16), I(q[t].f, 0, k, l + 224, 8), I(q[t].ea, 0, m, n + 224, 8));\n          c = 8 * f * a.B;\n          q = a.sa;\n          t = a.ta + 16 * d + 16 * f * a.R;\n          v = a.qa;\n          r = a.ra + 8 * d + c;\n          p = a.Ha;\n          u = a.Ia + 8 * d + c;\n\n          for (c = 0; 16 > c; ++c) {\n            I(q, t + c * a.R, g, h + 32 * c, 16);\n          }\n\n          for (c = 0; 8 > c; ++c) {\n            I(v, r + c * a.B, k, l + 32 * c, 8), I(p, u + c * a.B, m, n + 32 * c, 8);\n          }\n        }\n      }\n\n      function Ad(a, b, c, d, e, f, g, h, k) {\n        var l = [0],\n            m = [0],\n            n = 0,\n            r = null != k ? k.kd : 0,\n            q = null != k ? k : new md();\n        if (null == a || 12 > c) return 7;\n        q.data = a;\n        q.w = b;\n        q.ha = c;\n        b = [b];\n        c = [c];\n        q.gb = [q.gb];\n\n        a: {\n          var t = b;\n          var v = c;\n          var p = q.gb;\n          x(null != a);\n          x(null != v);\n          x(null != p);\n          p[0] = 0;\n\n          if (12 <= v[0] && !fa(a, t[0], \"RIFF\")) {\n            if (fa(a, t[0] + 8, \"WEBP\")) {\n              p = 3;\n              break a;\n            }\n\n            var u = Ha(a, t[0] + 4);\n\n            if (12 > u || 4294967286 < u) {\n              p = 3;\n              break a;\n            }\n\n            if (r && u > v[0] - 8) {\n              p = 7;\n              break a;\n            }\n\n            p[0] = u;\n            t[0] += 12;\n            v[0] -= 12;\n          }\n\n          p = 0;\n        }\n\n        if (0 != p) return p;\n        u = 0 < q.gb[0];\n\n        for (c = c[0];;) {\n          t = [0];\n          n = [n];\n\n          a: {\n            var w = a;\n            v = b;\n            p = c;\n            var y = n,\n                A = l,\n                z = m,\n                B = t;\n            y[0] = 0;\n            if (8 > p[0]) p = 7;else {\n              if (!fa(w, v[0], \"VP8X\")) {\n                if (10 != Ha(w, v[0] + 4)) {\n                  p = 3;\n                  break a;\n                }\n\n                if (18 > p[0]) {\n                  p = 7;\n                  break a;\n                }\n\n                var C = Ha(w, v[0] + 8);\n                var D = 1 + Yb(w, v[0] + 12);\n                w = 1 + Yb(w, v[0] + 15);\n\n                if (2147483648 <= D * w) {\n                  p = 3;\n                  break a;\n                }\n\n                null != B && (B[0] = C);\n                null != A && (A[0] = D);\n                null != z && (z[0] = w);\n                v[0] += 18;\n                p[0] -= 18;\n                y[0] = 1;\n              }\n\n              p = 0;\n            }\n          }\n\n          n = n[0];\n          t = t[0];\n          if (0 != p) return p;\n          v = !!(t & 2);\n          if (!u && n) return 3;\n          null != f && (f[0] = !!(t & 16));\n          null != g && (g[0] = v);\n          null != h && (h[0] = 0);\n          g = l[0];\n          t = m[0];\n\n          if (n && v && null == k) {\n            p = 0;\n            break;\n          }\n\n          if (4 > c) {\n            p = 7;\n            break;\n          }\n\n          if (u && n || !u && !n && !fa(a, b[0], \"ALPH\")) {\n            c = [c];\n            q.na = [q.na];\n            q.P = [q.P];\n            q.Sa = [q.Sa];\n\n            a: {\n              C = a;\n              p = b;\n              u = c;\n              var y = q.gb,\n                  A = q.na,\n                  z = q.P,\n                  B = q.Sa;\n              D = 22;\n              x(null != C);\n              x(null != u);\n              w = p[0];\n              var F = u[0];\n              x(null != A);\n              x(null != B);\n              A[0] = null;\n              z[0] = null;\n\n              for (B[0] = 0;;) {\n                p[0] = w;\n                u[0] = F;\n\n                if (8 > F) {\n                  p = 7;\n                  break a;\n                }\n\n                var G = Ha(C, w + 4);\n\n                if (4294967286 < G) {\n                  p = 3;\n                  break a;\n                }\n\n                var H = 8 + G + 1 & -2;\n                D += H;\n\n                if (0 < y && D > y) {\n                  p = 3;\n                  break a;\n                }\n\n                if (!fa(C, w, \"VP8 \") || !fa(C, w, \"VP8L\")) {\n                  p = 0;\n                  break a;\n                }\n\n                if (F[0] < H) {\n                  p = 7;\n                  break a;\n                }\n\n                fa(C, w, \"ALPH\") || (A[0] = C, z[0] = w + 8, B[0] = G);\n                w += H;\n                F -= H;\n              }\n            }\n\n            c = c[0];\n            q.na = q.na[0];\n            q.P = q.P[0];\n            q.Sa = q.Sa[0];\n            if (0 != p) break;\n          }\n\n          c = [c];\n          q.Ja = [q.Ja];\n          q.xa = [q.xa];\n\n          a: if (y = a, p = b, u = c, A = q.gb[0], z = q.Ja, B = q.xa, C = p[0], w = !fa(y, C, \"VP8 \"), D = !fa(y, C, \"VP8L\"), x(null != y), x(null != u), x(null != z), x(null != B), 8 > u[0]) p = 7;else {\n            if (w || D) {\n              y = Ha(y, C + 4);\n\n              if (12 <= A && y > A - 12) {\n                p = 3;\n                break a;\n              }\n\n              if (r && y > u[0] - 8) {\n                p = 7;\n                break a;\n              }\n\n              z[0] = y;\n              p[0] += 8;\n              u[0] -= 8;\n              B[0] = D;\n            } else B[0] = 5 <= u[0] && 47 == y[C + 0] && !(y[C + 4] >> 5), z[0] = u[0];\n\n            p = 0;\n          }\n\n          c = c[0];\n          q.Ja = q.Ja[0];\n          q.xa = q.xa[0];\n          b = b[0];\n          if (0 != p) break;\n          if (4294967286 < q.Ja) return 3;\n          null == h || v || (h[0] = q.xa ? 2 : 1);\n          g = [g];\n          t = [t];\n\n          if (q.xa) {\n            if (5 > c) {\n              p = 7;\n              break;\n            }\n\n            h = g;\n            r = t;\n            v = f;\n            null == a || 5 > c ? a = 0 : 5 <= c && 47 == a[b + 0] && !(a[b + 4] >> 5) ? (u = [0], y = [0], A = [0], z = new Ra(), cb(z, a, b, c), mc(z, u, y, A) ? (null != h && (h[0] = u[0]), null != r && (r[0] = y[0]), null != v && (v[0] = A[0]), a = 1) : a = 0) : a = 0;\n          } else {\n            if (10 > c) {\n              p = 7;\n              break;\n            }\n\n            h = t;\n            null == a || 10 > c || !Jc(a, b + 3, c - 3) ? a = 0 : (r = a[b + 0] | a[b + 1] << 8 | a[b + 2] << 16, v = (a[b + 7] << 8 | a[b + 6]) & 16383, a = (a[b + 9] << 8 | a[b + 8]) & 16383, r & 1 || 3 < (r >> 1 & 7) || !(r >> 4 & 1) || r >> 5 >= q.Ja || !v || !a ? a = 0 : (g && (g[0] = v), h && (h[0] = a), a = 1));\n          }\n\n          if (!a) return 3;\n          g = g[0];\n          t = t[0];\n          if (n && (l[0] != g || m[0] != t)) return 3;\n          null != k && (k[0] = q, k.offset = b - k.w, x(4294967286 > b - k.w), x(k.offset == k.ha - c));\n          break;\n        }\n\n        return 0 == p || 7 == p && n && null == k ? (null != f && (f[0] |= null != q.na && 0 < q.na.length), null != d && (d[0] = g), null != e && (e[0] = t), 0) : p;\n      }\n\n      function hc(a, b, c) {\n        var d = b.width,\n            e = b.height,\n            f = 0,\n            g = 0,\n            h = d,\n            k = e;\n        b.Da = null != a && 0 < a.Da;\n        if (b.Da && (h = a.cd, k = a.bd, f = a.v, g = a.j, 11 > c || (f &= -2, g &= -2), 0 > f || 0 > g || 0 >= h || 0 >= k || f + h > d || g + k > e)) return 0;\n        b.v = f;\n        b.j = g;\n        b.va = f + h;\n        b.o = g + k;\n        b.U = h;\n        b.T = k;\n        b.da = null != a && 0 < a.da;\n\n        if (b.da) {\n          c = [a.ib];\n          f = [a.hb];\n          if (!bc(h, k, c, f)) return 0;\n          b.ib = c[0];\n          b.hb = f[0];\n        }\n\n        b.ob = null != a && a.ob;\n        b.Kb = null == a || !a.Sd;\n        b.da && (b.ob = b.ib < 3 * d / 4 && b.hb < 3 * e / 4, b.Kb = 0);\n        return 1;\n      }\n\n      function Bd(a) {\n        if (null == a) return 2;\n\n        if (11 > a.S) {\n          var b = a.f.RGBA;\n          b.fb += (a.height - 1) * b.A;\n          b.A = -b.A;\n        } else b = a.f.kb, a = a.height, b.O += (a - 1) * b.fa, b.fa = -b.fa, b.N += (a - 1 >> 1) * b.Ab, b.Ab = -b.Ab, b.W += (a - 1 >> 1) * b.Db, b.Db = -b.Db, null != b.F && (b.J += (a - 1) * b.lb, b.lb = -b.lb);\n\n        return 0;\n      }\n\n      function Cd(a, b, c, d) {\n        if (null == d || 0 >= a || 0 >= b) return 2;\n\n        if (null != c) {\n          if (c.Da) {\n            var e = c.cd,\n                f = c.bd,\n                g = c.v & -2,\n                h = c.j & -2;\n            if (0 > g || 0 > h || 0 >= e || 0 >= f || g + e > a || h + f > b) return 2;\n            a = e;\n            b = f;\n          }\n\n          if (c.da) {\n            e = [c.ib];\n            f = [c.hb];\n            if (!bc(a, b, e, f)) return 2;\n            a = e[0];\n            b = f[0];\n          }\n        }\n\n        d.width = a;\n        d.height = b;\n\n        a: {\n          var k = d.width;\n          var l = d.height;\n          a = d.S;\n          if (0 >= k || 0 >= l || !(a >= Ca && 13 > a)) a = 2;else {\n            if (0 >= d.Rd && null == d.sd) {\n              var g = f = e = b = 0,\n                  h = k * Dd[a],\n                  m = h * l;\n              11 > a || (b = (k + 1) / 2, f = (l + 1) / 2 * b, 12 == a && (e = k, g = e * l));\n              l = V(m + 2 * f + g);\n\n              if (null == l) {\n                a = 1;\n                break a;\n              }\n\n              d.sd = l;\n              11 > a ? (k = d.f.RGBA, k.eb = l, k.fb = 0, k.A = h, k.size = m) : (k = d.f.kb, k.y = l, k.O = 0, k.fa = h, k.Fd = m, k.f = l, k.N = 0 + m, k.Ab = b, k.Cd = f, k.ea = l, k.W = 0 + m + f, k.Db = b, k.Ed = f, 12 == a && (k.F = l, k.J = 0 + m + 2 * f), k.Tc = g, k.lb = e);\n            }\n\n            b = 1;\n            e = d.S;\n            f = d.width;\n            g = d.height;\n            if (e >= Ca && 13 > e) {\n              if (11 > e) a = d.f.RGBA, h = Math.abs(a.A), b &= h * (g - 1) + f <= a.size, b &= h >= f * Dd[e], b &= null != a.eb;else {\n                a = d.f.kb;\n                h = (f + 1) / 2;\n                m = (g + 1) / 2;\n                k = Math.abs(a.fa);\n                var l = Math.abs(a.Ab),\n                    n = Math.abs(a.Db),\n                    r = Math.abs(a.lb),\n                    q = r * (g - 1) + f;\n                b &= k * (g - 1) + f <= a.Fd;\n                b &= l * (m - 1) + h <= a.Cd;\n                b &= n * (m - 1) + h <= a.Ed;\n                b = b & k >= f & l >= h & n >= h;\n                b &= null != a.y;\n                b &= null != a.f;\n                b &= null != a.ea;\n                12 == e && (b &= r >= f, b &= q <= a.Tc, b &= null != a.F);\n              }\n            } else b = 0;\n            a = b ? 0 : 2;\n          }\n        }\n\n        if (0 != a) return a;\n        null != c && c.fd && (a = Bd(d));\n        return a;\n      }\n\n      var xb = 64,\n          Hd = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215],\n          Gd = 24,\n          ob = 32,\n          Xb = 8,\n          Id = [0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7];\n      X(\"Predictor0\", \"PredictorAdd0\");\n\n      self.Predictor0 = function () {\n        return 4278190080;\n      };\n\n      self.Predictor1 = function (a) {\n        return a;\n      };\n\n      self.Predictor2 = function (a, b, c) {\n        return b[c + 0];\n      };\n\n      self.Predictor3 = function (a, b, c) {\n        return b[c + 1];\n      };\n\n      self.Predictor4 = function (a, b, c) {\n        return b[c - 1];\n      };\n\n      self.Predictor5 = function (a, b, c) {\n        return aa(aa(a, b[c + 1]), b[c + 0]);\n      };\n\n      self.Predictor6 = function (a, b, c) {\n        return aa(a, b[c - 1]);\n      };\n\n      self.Predictor7 = function (a, b, c) {\n        return aa(a, b[c + 0]);\n      };\n\n      self.Predictor8 = function (a, b, c) {\n        return aa(b[c - 1], b[c + 0]);\n      };\n\n      self.Predictor9 = function (a, b, c) {\n        return aa(b[c + 0], b[c + 1]);\n      };\n\n      self.Predictor10 = function (a, b, c) {\n        return aa(aa(a, b[c - 1]), aa(b[c + 0], b[c + 1]));\n      };\n\n      self.Predictor11 = function (a, b, c) {\n        var d = b[c + 0];\n        b = b[c - 1];\n        return 0 >= Ia(d >> 24 & 255, a >> 24 & 255, b >> 24 & 255) + Ia(d >> 16 & 255, a >> 16 & 255, b >> 16 & 255) + Ia(d >> 8 & 255, a >> 8 & 255, b >> 8 & 255) + Ia(d & 255, a & 255, b & 255) ? d : a;\n      };\n\n      self.Predictor12 = function (a, b, c) {\n        var d = b[c + 0];\n        b = b[c - 1];\n        return (sa((a >> 24 & 255) + (d >> 24 & 255) - (b >> 24 & 255)) << 24 | sa((a >> 16 & 255) + (d >> 16 & 255) - (b >> 16 & 255)) << 16 | sa((a >> 8 & 255) + (d >> 8 & 255) - (b >> 8 & 255)) << 8 | sa((a & 255) + (d & 255) - (b & 255))) >>> 0;\n      };\n\n      self.Predictor13 = function (a, b, c) {\n        var d = b[c - 1];\n        a = aa(a, b[c + 0]);\n        return (eb(a >> 24 & 255, d >> 24 & 255) << 24 | eb(a >> 16 & 255, d >> 16 & 255) << 16 | eb(a >> 8 & 255, d >> 8 & 255) << 8 | eb(a >> 0 & 255, d >> 0 & 255)) >>> 0;\n      };\n\n      var ee = self.PredictorAdd0;\n      self.PredictorAdd1 = cc;\n      X(\"Predictor2\", \"PredictorAdd2\");\n      X(\"Predictor3\", \"PredictorAdd3\");\n      X(\"Predictor4\", \"PredictorAdd4\");\n      X(\"Predictor5\", \"PredictorAdd5\");\n      X(\"Predictor6\", \"PredictorAdd6\");\n      X(\"Predictor7\", \"PredictorAdd7\");\n      X(\"Predictor8\", \"PredictorAdd8\");\n      X(\"Predictor9\", \"PredictorAdd9\");\n      X(\"Predictor10\", \"PredictorAdd10\");\n      X(\"Predictor11\", \"PredictorAdd11\");\n      X(\"Predictor12\", \"PredictorAdd12\");\n      X(\"Predictor13\", \"PredictorAdd13\");\n      var fe = self.PredictorAdd2;\n      ec(\"ColorIndexInverseTransform\", \"MapARGB\", \"32b\", function (a) {\n        return a >> 8 & 255;\n      }, function (a) {\n        return a;\n      });\n      ec(\"VP8LColorIndexInverseTransformAlpha\", \"MapAlpha\", \"8b\", function (a) {\n        return a;\n      }, function (a) {\n        return a >> 8 & 255;\n      });\n      var rc = self.ColorIndexInverseTransform,\n          ke = self.MapARGB,\n          he = self.VP8LColorIndexInverseTransformAlpha,\n          le = self.MapAlpha,\n          pc,\n          qc = self.VP8LPredictorsAdd = [];\n      qc.length = 16;\n      (self.VP8LPredictors = []).length = 16;\n      (self.VP8LPredictorsAdd_C = []).length = 16;\n      (self.VP8LPredictors_C = []).length = 16;\n      var Fb,\n          sc,\n          Gb,\n          Hb,\n          xc,\n          uc,\n          bd = V(511),\n          cd = V(2041),\n          dd = V(225),\n          ed = V(767),\n          ad = 0,\n          Qb = cd,\n          mb = dd,\n          R = ed,\n          U = bd,\n          Ca = 0,\n          Ua = 1,\n          tc = 2,\n          Va = 3,\n          ya = 4,\n          Db = 5,\n          wc = 6,\n          zb = 7,\n          Ab = 8,\n          Ja = 9,\n          Bb = 10,\n          pe = [2, 3, 7],\n          oe = [3, 3, 11],\n          Dc = [280, 256, 256, 256, 40],\n          qe = [0, 1, 1, 1, 0],\n          ne = [17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],\n          de = [24, 7, 23, 25, 40, 6, 39, 41, 22, 26, 38, 42, 56, 5, 55, 57, 21, 27, 54, 58, 37, 43, 72, 4, 71, 73, 20, 28, 53, 59, 70, 74, 36, 44, 88, 69, 75, 52, 60, 3, 87, 89, 19, 29, 86, 90, 35, 45, 68, 76, 85, 91, 51, 61, 104, 2, 103, 105, 18, 30, 102, 106, 34, 46, 84, 92, 67, 77, 101, 107, 50, 62, 120, 1, 119, 121, 83, 93, 17, 31, 100, 108, 66, 78, 118, 122, 33, 47, 117, 123, 49, 63, 99, 109, 82, 94, 0, 116, 124, 65, 79, 16, 32, 98, 110, 48, 115, 125, 81, 95, 64, 114, 126, 97, 111, 80, 113, 127, 96, 112],\n          me = [2954, 2956, 2958, 2962, 2970, 2986, 3018, 3082, 3212, 3468, 3980, 5004],\n          ie = 8,\n          Lb = [4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 91, 93, 95, 96, 98, 100, 101, 102, 104, 106, 108, 110, 112, 114, 116, 118, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 143, 145, 148, 151, 154, 157],\n          Mb = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 119, 122, 125, 128, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284],\n          oa = null,\n          He = [[173, 148, 140, 0], [176, 155, 140, 135, 0], [180, 157, 141, 134, 130, 0], [254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0]],\n          Ie = [0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15],\n          Mc = [-0, 1, -1, 2, -2, 3, 4, 6, -3, 5, -4, -5, -6, 7, -7, 8, -8, -9],\n          Fe = [[[[128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128]], [[253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128], [189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128], [106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128]], [[1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128], [181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128], [78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128]], [[1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128], [184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128], [77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128]], [[1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128], [170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128], [37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128]], [[1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128], [207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128], [102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128]], [[1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128], [177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128], [80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128]], [[1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128]]], [[[198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62], [131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1], [68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128]], [[1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128], [184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128], [81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128]], [[1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128], [99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128], [23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128]], [[1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128], [109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128], [44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128]], [[1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128], [94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128], [22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128]], [[1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128], [124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128], [35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128]], [[1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128], [121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128], [45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128]], [[1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128], [203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128], [137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128]]], [[[253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128], [175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128], [73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128]], [[1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128], [239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128], [155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128]], [[1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128], [201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128], [69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128]], [[1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128], [223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128], [141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128]], [[1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128], [190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128], [149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128]], [[1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128], [247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128], [240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128]], [[1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128], [213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128], [55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128]], [[128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128]]], [[[202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255], [126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128], [61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128]], [[1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128], [166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128], [39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128]], [[1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128], [124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128], [24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128]], [[1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128], [149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128], [28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128]], [[1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128], [123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128], [20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128]], [[1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128], [168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128], [47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128]], [[1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128], [141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128], [42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128]], [[1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128]]]],\n          Ke = [[[231, 120, 48, 89, 115, 113, 120, 152, 112], [152, 179, 64, 126, 170, 118, 46, 70, 95], [175, 69, 143, 80, 85, 82, 72, 155, 103], [56, 58, 10, 171, 218, 189, 17, 13, 152], [114, 26, 17, 163, 44, 195, 21, 10, 173], [121, 24, 80, 195, 26, 62, 44, 64, 85], [144, 71, 10, 38, 171, 213, 144, 34, 26], [170, 46, 55, 19, 136, 160, 33, 206, 71], [63, 20, 8, 114, 114, 208, 12, 9, 226], [81, 40, 11, 96, 182, 84, 29, 16, 36]], [[134, 183, 89, 137, 98, 101, 106, 165, 148], [72, 187, 100, 130, 157, 111, 32, 75, 80], [66, 102, 167, 99, 74, 62, 40, 234, 128], [41, 53, 9, 178, 241, 141, 26, 8, 107], [74, 43, 26, 146, 73, 166, 49, 23, 157], [65, 38, 105, 160, 51, 52, 31, 115, 128], [104, 79, 12, 27, 217, 255, 87, 17, 7], [87, 68, 71, 44, 114, 51, 15, 186, 23], [47, 41, 14, 110, 182, 183, 21, 17, 194], [66, 45, 25, 102, 197, 189, 23, 18, 22]], [[88, 88, 147, 150, 42, 46, 45, 196, 205], [43, 97, 183, 117, 85, 38, 35, 179, 61], [39, 53, 200, 87, 26, 21, 43, 232, 171], [56, 34, 51, 104, 114, 102, 29, 93, 77], [39, 28, 85, 171, 58, 165, 90, 98, 64], [34, 22, 116, 206, 23, 34, 43, 166, 73], [107, 54, 32, 26, 51, 1, 81, 43, 31], [68, 25, 106, 22, 64, 171, 36, 225, 114], [34, 19, 21, 102, 132, 188, 16, 76, 124], [62, 18, 78, 95, 85, 57, 50, 48, 51]], [[193, 101, 35, 159, 215, 111, 89, 46, 111], [60, 148, 31, 172, 219, 228, 21, 18, 111], [112, 113, 77, 85, 179, 255, 38, 120, 114], [40, 42, 1, 196, 245, 209, 10, 25, 109], [88, 43, 29, 140, 166, 213, 37, 43, 154], [61, 63, 30, 155, 67, 45, 68, 1, 209], [100, 80, 8, 43, 154, 1, 51, 26, 71], [142, 78, 78, 16, 255, 128, 34, 197, 171], [41, 40, 5, 102, 211, 183, 4, 1, 221], [51, 50, 17, 168, 209, 192, 23, 25, 82]], [[138, 31, 36, 171, 27, 166, 38, 44, 229], [67, 87, 58, 169, 82, 115, 26, 59, 179], [63, 59, 90, 180, 59, 166, 93, 73, 154], [40, 40, 21, 116, 143, 209, 34, 39, 175], [47, 15, 16, 183, 34, 223, 49, 45, 183], [46, 17, 33, 183, 6, 98, 15, 32, 183], [57, 46, 22, 24, 128, 1, 54, 17, 37], [65, 32, 73, 115, 28, 128, 23, 128, 205], [40, 3, 9, 115, 51, 192, 18, 6, 223], [87, 37, 9, 115, 59, 77, 64, 21, 47]], [[104, 55, 44, 218, 9, 54, 53, 130, 226], [64, 90, 70, 205, 40, 41, 23, 26, 57], [54, 57, 112, 184, 5, 41, 38, 166, 213], [30, 34, 26, 133, 152, 116, 10, 32, 134], [39, 19, 53, 221, 26, 114, 32, 73, 255], [31, 9, 65, 234, 2, 15, 1, 118, 73], [75, 32, 12, 51, 192, 255, 160, 43, 51], [88, 31, 35, 67, 102, 85, 55, 186, 85], [56, 21, 23, 111, 59, 205, 45, 37, 192], [55, 38, 70, 124, 73, 102, 1, 34, 98]], [[125, 98, 42, 88, 104, 85, 117, 175, 82], [95, 84, 53, 89, 128, 100, 113, 101, 45], [75, 79, 123, 47, 51, 128, 81, 171, 1], [57, 17, 5, 71, 102, 57, 53, 41, 49], [38, 33, 13, 121, 57, 73, 26, 1, 85], [41, 10, 67, 138, 77, 110, 90, 47, 114], [115, 21, 2, 10, 102, 255, 166, 23, 6], [101, 29, 16, 10, 85, 128, 101, 196, 26], [57, 18, 10, 102, 102, 213, 34, 20, 43], [117, 20, 15, 36, 163, 128, 68, 1, 26]], [[102, 61, 71, 37, 34, 53, 31, 243, 192], [69, 60, 71, 38, 73, 119, 28, 222, 37], [68, 45, 128, 34, 1, 47, 11, 245, 171], [62, 17, 19, 70, 146, 85, 55, 62, 70], [37, 43, 37, 154, 100, 163, 85, 160, 1], [63, 9, 92, 136, 28, 64, 32, 201, 85], [75, 15, 9, 9, 64, 255, 184, 119, 16], [86, 6, 28, 5, 64, 255, 25, 248, 1], [56, 8, 17, 132, 137, 255, 55, 116, 128], [58, 15, 20, 82, 135, 57, 26, 121, 40]], [[164, 50, 31, 137, 154, 133, 25, 35, 218], [51, 103, 44, 131, 131, 123, 31, 6, 158], [86, 40, 64, 135, 148, 224, 45, 183, 128], [22, 26, 17, 131, 240, 154, 14, 1, 209], [45, 16, 21, 91, 64, 222, 7, 1, 197], [56, 21, 39, 155, 60, 138, 23, 102, 213], [83, 12, 13, 54, 192, 255, 68, 47, 28], [85, 26, 85, 85, 128, 128, 32, 146, 171], [18, 11, 7, 63, 144, 171, 4, 4, 246], [35, 27, 10, 146, 174, 171, 12, 26, 128]], [[190, 80, 35, 99, 180, 80, 126, 54, 45], [85, 126, 47, 87, 176, 51, 41, 20, 32], [101, 75, 128, 139, 118, 146, 116, 128, 85], [56, 41, 15, 176, 236, 85, 37, 9, 62], [71, 30, 17, 119, 118, 255, 17, 18, 138], [101, 38, 60, 138, 55, 70, 43, 26, 142], [146, 36, 19, 30, 171, 255, 97, 27, 20], [138, 45, 61, 62, 219, 1, 81, 188, 64], [32, 41, 20, 117, 151, 142, 20, 21, 163], [112, 19, 12, 61, 195, 128, 48, 4, 24]]],\n          Ee = [[[[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255], [223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255], [249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255], [234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255], [239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255], [251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255], [250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]], [[[217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255], [234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255]], [[255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255]], [[255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255], [249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255], [247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255], [250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]], [[[186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255], [234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255], [251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255]], [[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255]], [[255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]], [[[248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255], [248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255], [246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255], [252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255]], [[255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255], [248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255], [253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255]], [[255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255], [245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255], [253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255], [252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255], [249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255], [250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]]],\n          Ge = [0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 0],\n          Nc,\n          Y = [],\n          W = [],\n          ka = [],\n          Za,\n          fd,\n          Nb,\n          pa,\n          Ob,\n          Xc,\n          Tc,\n          Yc,\n          Uc,\n          Zc,\n          Vc,\n          $c,\n          Wc,\n          Rc,\n          Pc,\n          Sc,\n          Qc,\n          re = 1,\n          Cc = 2,\n          ia = [],\n          za,\n          vc,\n          fc,\n          Fc,\n          P = [];\n      va(\"UpsampleRgbLinePair\", Ga, 3);\n      va(\"UpsampleBgrLinePair\", Tb, 3);\n      va(\"UpsampleRgbaLinePair\", wd, 4);\n      va(\"UpsampleBgraLinePair\", vd, 4);\n      va(\"UpsampleArgbLinePair\", ud, 4);\n      va(\"UpsampleRgba4444LinePair\", td, 2);\n      va(\"UpsampleRgb565LinePair\", sd, 2);\n      var Mf = self.UpsampleRgbLinePair,\n          Nf = self.UpsampleBgrLinePair,\n          nd = self.UpsampleRgbaLinePair,\n          od = self.UpsampleBgraLinePair,\n          pd = self.UpsampleArgbLinePair,\n          qd = self.UpsampleRgba4444LinePair,\n          Of = self.UpsampleRgb565LinePair,\n          Wa = 16,\n          Ba = 1 << Wa - 1,\n          ta = -227,\n          Eb = 482,\n          rd = 6,\n          Pf = (256 << rd) - 1,\n          jc = 0,\n          Yd = V(256),\n          ae = V(256),\n          $d = V(256),\n          Zd = V(256),\n          be = V(Eb - ta),\n          ce = V(Eb - ta);\n      la(\"YuvToRgbRow\", Ga, 3);\n      la(\"YuvToBgrRow\", Tb, 3);\n      la(\"YuvToRgbaRow\", wd, 4);\n      la(\"YuvToBgraRow\", vd, 4);\n      la(\"YuvToArgbRow\", ud, 4);\n      la(\"YuvToRgba4444Row\", td, 2);\n      la(\"YuvToRgb565Row\", sd, 2);\n      var zd = [0, 4, 8, 12, 128, 132, 136, 140, 256, 260, 264, 268, 384, 388, 392, 396],\n          Ya = [0, 2, 8],\n          Qf = [8, 7, 6, 4, 4, 2, 2, 2, 1, 1, 1, 1],\n          Ne = 1;\n\n      this.WebPDecodeRGBA = function (a, b, c, d, e) {\n        var f = Ua;\n        var g = new Cf(),\n            h = new Cb();\n        g.ba = h;\n        h.S = f;\n        h.width = [h.width];\n        h.height = [h.height];\n        var k = h.width;\n        var l = h.height,\n            m = new Td();\n        if (null == m || null == a) var n = 2;else x(null != m), n = Ad(a, b, c, m.width, m.height, m.Pd, m.Qd, m.format, null);\n        0 != n ? k = 0 : (null != k && (k[0] = m.width[0]), null != l && (l[0] = m.height[0]), k = 1);\n\n        if (k) {\n          h.width = h.width[0];\n          h.height = h.height[0];\n          null != d && (d[0] = h.width);\n          null != e && (e[0] = h.height);\n\n          b: {\n            d = new Oa();\n            e = new md();\n            e.data = a;\n            e.w = b;\n            e.ha = c;\n            e.kd = 1;\n            b = [0];\n            x(null != e);\n            a = Ad(e.data, e.w, e.ha, null, null, null, b, null, e);\n            (0 == a || 7 == a) && b[0] && (a = 4);\n            b = a;\n\n            if (0 == b) {\n              x(null != g);\n              d.data = e.data;\n              d.w = e.w + e.offset;\n              d.ha = e.ha - e.offset;\n              d.put = kc;\n              d.ac = gc;\n              d.bc = lc;\n              d.ma = g;\n\n              if (e.xa) {\n                a = Bc();\n\n                if (null == a) {\n                  g = 1;\n                  break b;\n                }\n\n                if (te(a, d)) {\n                  b = Cd(d.width, d.height, g.Oa, g.ba);\n\n                  if (d = 0 == b) {\n                    c: {\n                      d = a;\n\n                      d: for (;;) {\n                        if (null == d) {\n                          d = 0;\n                          break c;\n                        }\n\n                        x(null != d.s.yc);\n                        x(null != d.s.Ya);\n                        x(0 < d.s.Wb);\n                        c = d.l;\n                        x(null != c);\n                        e = c.ma;\n                        x(null != e);\n\n                        if (0 != d.xb) {\n                          d.ca = e.ba;\n                          d.tb = e.tb;\n                          x(null != d.ca);\n\n                          if (!hc(e.Oa, c, Va)) {\n                            d.a = 2;\n                            break d;\n                          }\n\n                          if (!Ec(d, c.width)) break d;\n                          if (c.da) break d;\n                          (c.da || hb(d.ca.S)) && Aa();\n                          11 > d.ca.S || (alert(\"todo:WebPInitConvertARGBToYUV\"), null != d.ca.f.kb.F && Aa());\n\n                          if (d.Pb && 0 < d.s.ua && null == d.s.vb.X && !Zb(d.s.vb, d.s.Wa.Xa)) {\n                            d.a = 1;\n                            break d;\n                          }\n\n                          d.xb = 0;\n                        }\n\n                        if (!Jb(d, d.V, d.Ba, d.c, d.i, c.o, ge)) break d;\n                        e.Dc = d.Ma;\n                        d = 1;\n                        break c;\n                      }\n\n                      x(0 != d.a);\n                      d = 0;\n                    }\n\n                    d = !d;\n                  }\n\n                  d && (b = a.a);\n                } else b = a.a;\n              } else {\n                a = new Ce();\n\n                if (null == a) {\n                  g = 1;\n                  break b;\n                }\n\n                a.Fa = e.na;\n                a.P = e.P;\n                a.qc = e.Sa;\n\n                if (Kc(a, d)) {\n                  if (b = Cd(d.width, d.height, g.Oa, g.ba), 0 == b) {\n                    a.Aa = 0;\n                    c = g.Oa;\n                    e = a;\n                    x(null != e);\n\n                    if (null != c) {\n                      k = c.Md;\n                      k = 0 > k ? 0 : 100 < k ? 255 : 255 * k / 100;\n\n                      if (0 < k) {\n                        for (l = m = 0; 4 > l; ++l) {\n                          n = e.pb[l], 12 > n.lc && (n.ia = k * Qf[0 > n.lc ? 0 : n.lc] >> 3), m |= n.ia;\n                        }\n\n                        m && (alert(\"todo:VP8InitRandom\"), e.ia = 1);\n                      }\n\n                      e.Ga = c.Id;\n                      100 < e.Ga ? e.Ga = 100 : 0 > e.Ga && (e.Ga = 0);\n                    }\n\n                    Me(a, d) || (b = a.a);\n                  }\n                } else b = a.a;\n              }\n\n              0 == b && null != g.Oa && g.Oa.fd && (b = Bd(g.ba));\n            }\n\n            g = b;\n          }\n\n          f = 0 != g ? null : 11 > f ? h.f.RGBA.eb : h.f.kb.y;\n        } else f = null;\n\n        return f;\n      };\n\n      var Dd = [3, 4, 3, 4, 4, 2, 2, 4, 4, 4, 2, 1, 1];\n    };\n\n    new _WebPDecoder();\n    /** @license\n     * Copyright (c) 2017 Dominik Homberger\n    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n    https://webpjs.appspot.com\n    WebPRiffParser dominikhlbg@gmail.com\n    */\n\n    function memcmp(data, data_off, str, size) {\n      for (var i = 0; i < size; i++) {\n        if (data[data_off + i] != str.charCodeAt(i)) return true;\n      }\n\n      return false;\n    }\n\n    function GetTag(data, data_off) {\n      var str = \"\";\n\n      for (var i = 0; i < 4; i++) {\n        str += String.fromCharCode(data[data_off++]);\n      }\n\n      return str;\n    }\n\n    function GetLE16(data, data_off) {\n      return data[data_off + 0] << 0 | data[data_off + 1] << 8;\n    }\n\n    function GetLE24(data, data_off) {\n      return (data[data_off + 0] << 0 | data[data_off + 1] << 8 | data[data_off + 2] << 16) >>> 0;\n    }\n\n    function GetLE32(data, data_off) {\n      return (data[data_off + 0] << 0 | data[data_off + 1] << 8 | data[data_off + 2] << 16 | data[data_off + 3] << 24) >>> 0;\n    }\n\n    function WebPRiffParser(src, src_off) {\n      var imagearray = {};\n      var i = 0;\n      var alpha_chunk = false;\n      var alpha_size = 0;\n      var alpha_offset = 0;\n      imagearray[\"frames\"] = [];\n      if (memcmp(src, src_off, \"RIFF\", 4)) return;\n      src_off += 4;\n      var riff_size = GetLE32(src, src_off) + 8;\n      src_off += 8;\n\n      while (src_off < src.length) {\n        var fourcc = GetTag(src, src_off);\n        src_off += 4;\n        var payload_size = GetLE32(src, src_off);\n        src_off += 4;\n        var payload_size_padded = payload_size + (payload_size & 1);\n\n        switch (fourcc) {\n          case \"VP8 \":\n          case \"VP8L\":\n            if (typeof imagearray[\"frames\"][i] === \"undefined\") imagearray[\"frames\"][i] = {};\n            var obj = imagearray[\"frames\"][i];\n            var height = [0];\n            var width = [0];\n            obj[\"src_off\"] = alpha_chunk ? alpha_offset : src_off - 8;\n            obj[\"src_size\"] = alpha_size + payload_size + 8; //var rgba = webpdecoder.WebPDecodeRGBA(src,(alpha_chunk?alpha_offset:src_off-8),alpha_size+payload_size+8,width,height);\n            //imagearray[i]={'rgba':rgba,'width':width[0],'height':height[0]};\n\n            i++;\n\n            if (alpha_chunk) {\n              alpha_chunk = false;\n              alpha_size = 0;\n              alpha_offset = 0;\n            }\n\n            break;\n\n          case \"VP8X\":\n            var obj = imagearray[\"header\"] = {};\n            var feature_flags = obj[\"feature_flags\"] = src[src_off];\n            var src_off_ = src_off + 4;\n            var canvas_width = obj[\"canvas_width\"] = 1 + GetLE24(src, src_off_);\n            src_off_ += 3;\n            var canvas_height = obj[\"canvas_height\"] = 1 + GetLE24(src, src_off_);\n            src_off_ += 3;\n            break;\n\n          case \"ALPH\":\n            alpha_chunk = true;\n            alpha_size = payload_size_padded + 8;\n            alpha_offset = src_off - 8;\n            break;\n\n          case \"ANIM\":\n            var obj = imagearray[\"header\"];\n            var bgcolor = obj[\"bgcolor\"] = GetLE32(src, src_off);\n            src_off_ = src_off + 4;\n            var loop_count = obj[\"loop_count\"] = GetLE16(src, src_off_);\n            src_off_ += 2;\n            break;\n\n          case \"ANMF\":\n            var offset_x = 0,\n                offset_y = 0,\n                width = 0,\n                height = 0,\n                duration = 0,\n                blend = 0,\n                dispose = 0,\n                temp = 0;\n            var obj = imagearray[\"frames\"][i] = {};\n            obj[\"offset_x\"] = offset_x = 2 * GetLE24(src, src_off);\n            src_off += 3;\n            obj[\"offset_y\"] = offset_y = 2 * GetLE24(src, src_off);\n            src_off += 3;\n            obj[\"width\"] = width = 1 + GetLE24(src, src_off);\n            src_off += 3;\n            obj[\"height\"] = height = 1 + GetLE24(src, src_off);\n            src_off += 3;\n            obj[\"duration\"] = duration = GetLE24(src, src_off);\n            src_off += 3;\n            temp = src[src_off++];\n            obj[\"dispose\"] = dispose = temp & 1;\n            obj[\"blend\"] = blend = temp >> 1 & 1;\n            break;\n        }\n\n        if (fourcc != \"ANMF\") src_off += payload_size_padded;\n      }\n\n      return imagearray;\n    }\n\n    var height = [0];\n    var width = [0];\n    var pixels = [];\n    var webpdecoder = new _WebPDecoder();\n    var response = imageData;\n    var imagearray = WebPRiffParser(response, 0);\n    imagearray[\"response\"] = response;\n    imagearray[\"rgbaoutput\"] = true;\n    imagearray[\"dataurl\"] = false;\n    var header = imagearray[\"header\"] ? imagearray[\"header\"] : null;\n    var frames = imagearray[\"frames\"] ? imagearray[\"frames\"] : null;\n\n    if (header) {\n      header[\"loop_counter\"] = header[\"loop_count\"];\n      height = [header[\"canvas_height\"]];\n      width = [header[\"canvas_width\"]];\n\n      for (var f = 0; f < frames.length; f++) {\n        if (frames[f][\"blend\"] == 0) {\n          break;\n        }\n      }\n    }\n\n    var frame = frames[0];\n    var rgba = webpdecoder.WebPDecodeRGBA(response, frame[\"src_off\"], frame[\"src_size\"], width, height);\n    frame[\"rgba\"] = rgba;\n    frame[\"imgwidth\"] = width[0];\n    frame[\"imgheight\"] = height[0];\n\n    for (var i = 0; i < width[0] * height[0] * 4; i++) {\n      pixels[i] = rgba[i];\n    }\n\n    this.width = width;\n    this.height = height;\n    this.data = pixels;\n    return this;\n  }\n\n  WebPDecoder.prototype.getData = function () {\n    return this.data;\n  };\n\n  /**\n   * @license\n   * Copyright (c) 2019 Aras Abbasi\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n  /**\n   * jsPDF webp Support PlugIn\n   *\n   * @name webp_support\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n\n    jsPDFAPI.processWEBP = function (imageData, index, alias, compression) {\n      var reader = new WebPDecoder(imageData, false);\n      var width = reader.width,\n          height = reader.height;\n      var qu = 100;\n      var pixels = reader.getData();\n      var rawImageData = {\n        data: pixels,\n        width: width,\n        height: height\n      };\n      var encoder = new JPEGEncoder(qu);\n      var data = encoder.encode(rawImageData, qu);\n      return jsPDFAPI.processJPEG.call(this, data, index, alias, compression);\n    };\n  })(jsPDF.API);\n\n  /**\n   * @license\n   *\n   * Copyright (c) 2021 Antti Palola, https://github.com/Pantura\n   *\n   * Permission is hereby granted, free of charge, to any person obtaining\n   * a copy of this software and associated documentation files (the\n   * \"Software\"), to deal in the Software without restriction, including\n   * without limitation the rights to use, copy, modify, merge, publish,\n   * distribute, sublicense, and/or sell copies of the Software, and to\n   * permit persons to whom the Software is furnished to do so, subject to\n   * the following conditions:\n   *\n   * The above copyright notice and this permission notice shall be\n   * included in all copies or substantial portions of the Software.\n   *\n   * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n   * ====================================================================\n   */\n  /**\n   * jsPDF RGBA array PlugIn\n   * @name rgba_support\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n    /**\n     * @name processRGBA\n     * @function\n     *\n     * Process RGBA Array. This is a one-dimension array with pixel data [red, green, blue, alpha, red, green, ...].\n     * RGBA array data can be obtained from DOM canvas getImageData.\n     * @ignore\n     */\n\n    jsPDFAPI.processRGBA = function (imageData, index, alias) {\n\n      var imagePixels = imageData.data;\n      var length = imagePixels.length; // jsPDF takes alpha data separately so extract that.\n\n      var rgbOut = new Uint8Array(length / 4 * 3);\n      var alphaOut = new Uint8Array(length / 4);\n      var outIndex = 0;\n      var alphaIndex = 0;\n\n      for (var i = 0; i < length; i += 4) {\n        var r = imagePixels[i];\n        var g = imagePixels[i + 1];\n        var b = imagePixels[i + 2];\n        var alpha = imagePixels[i + 3];\n        rgbOut[outIndex++] = r;\n        rgbOut[outIndex++] = g;\n        rgbOut[outIndex++] = b;\n        alphaOut[alphaIndex++] = alpha;\n      }\n\n      var rgbData = this.__addimage__.arrayBufferToBinaryString(rgbOut);\n\n      var alphaData = this.__addimage__.arrayBufferToBinaryString(alphaOut);\n\n      return {\n        alpha: alphaData,\n        data: rgbData,\n        index: index,\n        alias: alias,\n        colorSpace: \"DeviceRGB\",\n        bitsPerComponent: 8,\n        width: imageData.width,\n        height: imageData.height\n      };\n    };\n  })(jsPDF.API);\n\n  /**\n   * @license\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n  /**\n   * jsPDF setLanguage Plugin\n   *\n   * @name setLanguage\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n    /**\n     * Add Language Tag to the generated PDF\n     *\n     * @name setLanguage\n     * @function\n     * @param {string} langCode The Language code as ISO-639-1 (e.g. 'en') or as country language code (e.g. 'en-GB').\n     * @returns {jsPDF}\n     * @example\n     * var doc = new jsPDF()\n     * doc.text(10, 10, 'This is a test')\n     * doc.setLanguage(\"en-US\")\n     * doc.save('english.pdf')\n     */\n\n    jsPDFAPI.setLanguage = function (langCode) {\n\n      var langCodes = {\n        af: \"Afrikaans\",\n        sq: \"Albanian\",\n        ar: \"Arabic (Standard)\",\n        \"ar-DZ\": \"Arabic (Algeria)\",\n        \"ar-BH\": \"Arabic (Bahrain)\",\n        \"ar-EG\": \"Arabic (Egypt)\",\n        \"ar-IQ\": \"Arabic (Iraq)\",\n        \"ar-JO\": \"Arabic (Jordan)\",\n        \"ar-KW\": \"Arabic (Kuwait)\",\n        \"ar-LB\": \"Arabic (Lebanon)\",\n        \"ar-LY\": \"Arabic (Libya)\",\n        \"ar-MA\": \"Arabic (Morocco)\",\n        \"ar-OM\": \"Arabic (Oman)\",\n        \"ar-QA\": \"Arabic (Qatar)\",\n        \"ar-SA\": \"Arabic (Saudi Arabia)\",\n        \"ar-SY\": \"Arabic (Syria)\",\n        \"ar-TN\": \"Arabic (Tunisia)\",\n        \"ar-AE\": \"Arabic (U.A.E.)\",\n        \"ar-YE\": \"Arabic (Yemen)\",\n        an: \"Aragonese\",\n        hy: \"Armenian\",\n        as: \"Assamese\",\n        ast: \"Asturian\",\n        az: \"Azerbaijani\",\n        eu: \"Basque\",\n        be: \"Belarusian\",\n        bn: \"Bengali\",\n        bs: \"Bosnian\",\n        br: \"Breton\",\n        bg: \"Bulgarian\",\n        my: \"Burmese\",\n        ca: \"Catalan\",\n        ch: \"Chamorro\",\n        ce: \"Chechen\",\n        zh: \"Chinese\",\n        \"zh-HK\": \"Chinese (Hong Kong)\",\n        \"zh-CN\": \"Chinese (PRC)\",\n        \"zh-SG\": \"Chinese (Singapore)\",\n        \"zh-TW\": \"Chinese (Taiwan)\",\n        cv: \"Chuvash\",\n        co: \"Corsican\",\n        cr: \"Cree\",\n        hr: \"Croatian\",\n        cs: \"Czech\",\n        da: \"Danish\",\n        nl: \"Dutch (Standard)\",\n        \"nl-BE\": \"Dutch (Belgian)\",\n        en: \"English\",\n        \"en-AU\": \"English (Australia)\",\n        \"en-BZ\": \"English (Belize)\",\n        \"en-CA\": \"English (Canada)\",\n        \"en-IE\": \"English (Ireland)\",\n        \"en-JM\": \"English (Jamaica)\",\n        \"en-NZ\": \"English (New Zealand)\",\n        \"en-PH\": \"English (Philippines)\",\n        \"en-ZA\": \"English (South Africa)\",\n        \"en-TT\": \"English (Trinidad & Tobago)\",\n        \"en-GB\": \"English (United Kingdom)\",\n        \"en-US\": \"English (United States)\",\n        \"en-ZW\": \"English (Zimbabwe)\",\n        eo: \"Esperanto\",\n        et: \"Estonian\",\n        fo: \"Faeroese\",\n        fj: \"Fijian\",\n        fi: \"Finnish\",\n        fr: \"French (Standard)\",\n        \"fr-BE\": \"French (Belgium)\",\n        \"fr-CA\": \"French (Canada)\",\n        \"fr-FR\": \"French (France)\",\n        \"fr-LU\": \"French (Luxembourg)\",\n        \"fr-MC\": \"French (Monaco)\",\n        \"fr-CH\": \"French (Switzerland)\",\n        fy: \"Frisian\",\n        fur: \"Friulian\",\n        gd: \"Gaelic (Scots)\",\n        \"gd-IE\": \"Gaelic (Irish)\",\n        gl: \"Galacian\",\n        ka: \"Georgian\",\n        de: \"German (Standard)\",\n        \"de-AT\": \"German (Austria)\",\n        \"de-DE\": \"German (Germany)\",\n        \"de-LI\": \"German (Liechtenstein)\",\n        \"de-LU\": \"German (Luxembourg)\",\n        \"de-CH\": \"German (Switzerland)\",\n        el: \"Greek\",\n        gu: \"Gujurati\",\n        ht: \"Haitian\",\n        he: \"Hebrew\",\n        hi: \"Hindi\",\n        hu: \"Hungarian\",\n        is: \"Icelandic\",\n        id: \"Indonesian\",\n        iu: \"Inuktitut\",\n        ga: \"Irish\",\n        it: \"Italian (Standard)\",\n        \"it-CH\": \"Italian (Switzerland)\",\n        ja: \"Japanese\",\n        kn: \"Kannada\",\n        ks: \"Kashmiri\",\n        kk: \"Kazakh\",\n        km: \"Khmer\",\n        ky: \"Kirghiz\",\n        tlh: \"Klingon\",\n        ko: \"Korean\",\n        \"ko-KP\": \"Korean (North Korea)\",\n        \"ko-KR\": \"Korean (South Korea)\",\n        la: \"Latin\",\n        lv: \"Latvian\",\n        lt: \"Lithuanian\",\n        lb: \"Luxembourgish\",\n        mk: \"North Macedonia\",\n        ms: \"Malay\",\n        ml: \"Malayalam\",\n        mt: \"Maltese\",\n        mi: \"Maori\",\n        mr: \"Marathi\",\n        mo: \"Moldavian\",\n        nv: \"Navajo\",\n        ng: \"Ndonga\",\n        ne: \"Nepali\",\n        no: \"Norwegian\",\n        nb: \"Norwegian (Bokmal)\",\n        nn: \"Norwegian (Nynorsk)\",\n        oc: \"Occitan\",\n        or: \"Oriya\",\n        om: \"Oromo\",\n        fa: \"Persian\",\n        \"fa-IR\": \"Persian/Iran\",\n        pl: \"Polish\",\n        pt: \"Portuguese\",\n        \"pt-BR\": \"Portuguese (Brazil)\",\n        pa: \"Punjabi\",\n        \"pa-IN\": \"Punjabi (India)\",\n        \"pa-PK\": \"Punjabi (Pakistan)\",\n        qu: \"Quechua\",\n        rm: \"Rhaeto-Romanic\",\n        ro: \"Romanian\",\n        \"ro-MO\": \"Romanian (Moldavia)\",\n        ru: \"Russian\",\n        \"ru-MO\": \"Russian (Moldavia)\",\n        sz: \"Sami (Lappish)\",\n        sg: \"Sango\",\n        sa: \"Sanskrit\",\n        sc: \"Sardinian\",\n        sd: \"Sindhi\",\n        si: \"Singhalese\",\n        sr: \"Serbian\",\n        sk: \"Slovak\",\n        sl: \"Slovenian\",\n        so: \"Somani\",\n        sb: \"Sorbian\",\n        es: \"Spanish\",\n        \"es-AR\": \"Spanish (Argentina)\",\n        \"es-BO\": \"Spanish (Bolivia)\",\n        \"es-CL\": \"Spanish (Chile)\",\n        \"es-CO\": \"Spanish (Colombia)\",\n        \"es-CR\": \"Spanish (Costa Rica)\",\n        \"es-DO\": \"Spanish (Dominican Republic)\",\n        \"es-EC\": \"Spanish (Ecuador)\",\n        \"es-SV\": \"Spanish (El Salvador)\",\n        \"es-GT\": \"Spanish (Guatemala)\",\n        \"es-HN\": \"Spanish (Honduras)\",\n        \"es-MX\": \"Spanish (Mexico)\",\n        \"es-NI\": \"Spanish (Nicaragua)\",\n        \"es-PA\": \"Spanish (Panama)\",\n        \"es-PY\": \"Spanish (Paraguay)\",\n        \"es-PE\": \"Spanish (Peru)\",\n        \"es-PR\": \"Spanish (Puerto Rico)\",\n        \"es-ES\": \"Spanish (Spain)\",\n        \"es-UY\": \"Spanish (Uruguay)\",\n        \"es-VE\": \"Spanish (Venezuela)\",\n        sx: \"Sutu\",\n        sw: \"Swahili\",\n        sv: \"Swedish\",\n        \"sv-FI\": \"Swedish (Finland)\",\n        \"sv-SV\": \"Swedish (Sweden)\",\n        ta: \"Tamil\",\n        tt: \"Tatar\",\n        te: \"Teluga\",\n        th: \"Thai\",\n        tig: \"Tigre\",\n        ts: \"Tsonga\",\n        tn: \"Tswana\",\n        tr: \"Turkish\",\n        tk: \"Turkmen\",\n        uk: \"Ukrainian\",\n        hsb: \"Upper Sorbian\",\n        ur: \"Urdu\",\n        ve: \"Venda\",\n        vi: \"Vietnamese\",\n        vo: \"Volapuk\",\n        wa: \"Walloon\",\n        cy: \"Welsh\",\n        xh: \"Xhosa\",\n        ji: \"Yiddish\",\n        zu: \"Zulu\"\n      };\n\n      if (this.internal.languageSettings === undefined) {\n        this.internal.languageSettings = {};\n        this.internal.languageSettings.isSubscribed = false;\n      }\n\n      if (langCodes[langCode] !== undefined) {\n        this.internal.languageSettings.languageCode = langCode;\n\n        if (this.internal.languageSettings.isSubscribed === false) {\n          this.internal.events.subscribe(\"putCatalog\", function () {\n            this.internal.write(\"/Lang (\" + this.internal.languageSettings.languageCode + \")\");\n          });\n          this.internal.languageSettings.isSubscribed = true;\n        }\n      }\n\n      return this;\n    };\n  })(jsPDF.API);\n\n  /**\n   * jsPDF split_text_to_size plugin\n   *\n   * @name split_text_to_size\n   * @module\n   */\n\n  (function (API) {\n    /**\n     * Returns an array of length matching length of the 'word' string, with each\n     * cell occupied by the width of the char in that position.\n     *\n     * @name getCharWidthsArray\n     * @function\n     * @param {string} text\n     * @param {Object} options\n     * @returns {Array}\n     */\n\n    var getCharWidthsArray = API.getCharWidthsArray = function (text, options) {\n      options = options || {};\n      var activeFont = options.font || this.internal.getFont();\n      var fontSize = options.fontSize || this.internal.getFontSize();\n      var charSpace = options.charSpace || this.internal.getCharSpace();\n      var widths = options.widths ? options.widths : activeFont.metadata.Unicode.widths;\n      var widthsFractionOf = widths.fof ? widths.fof : 1;\n      var kerning = options.kerning ? options.kerning : activeFont.metadata.Unicode.kerning;\n      var kerningFractionOf = kerning.fof ? kerning.fof : 1;\n      var doKerning = options.doKerning === false ? false : true;\n      var kerningValue = 0;\n      var i;\n      var length = text.length;\n      var char_code;\n      var prior_char_code = 0; //for kerning\n\n      var default_char_width = widths[0] || widthsFractionOf;\n      var output = [];\n\n      for (i = 0; i < length; i++) {\n        char_code = text.charCodeAt(i);\n\n        if (typeof activeFont.metadata.widthOfString === \"function\") {\n          output.push((activeFont.metadata.widthOfGlyph(activeFont.metadata.characterToGlyph(char_code)) + charSpace * (1000 / fontSize) || 0) / 1000);\n        } else {\n          if (doKerning && _typeof(kerning[char_code]) === \"object\" && !isNaN(parseInt(kerning[char_code][prior_char_code], 10))) {\n            kerningValue = kerning[char_code][prior_char_code] / kerningFractionOf;\n          } else {\n            kerningValue = 0;\n          }\n\n          output.push((widths[char_code] || default_char_width) / widthsFractionOf + kerningValue);\n        }\n\n        prior_char_code = char_code;\n      }\n\n      return output;\n    };\n    /**\n     * Returns a widths of string in a given font, if the font size is set as 1 point.\n     *\n     * In other words, this is \"proportional\" value. For 1 unit of font size, the length\n     * of the string will be that much.\n     *\n     * Multiply by font size to get actual width in *points*\n     * Then divide by 72 to get inches or divide by (72/25.6) to get 'mm' etc.\n     *\n     * @name getStringUnitWidth\n     * @public\n     * @function\n     * @param {string} text\n     * @param {string} options\n     * @returns {number} result\n     */\n\n\n    var getStringUnitWidth = API.getStringUnitWidth = function (text, options) {\n      options = options || {};\n      var fontSize = options.fontSize || this.internal.getFontSize();\n      var font = options.font || this.internal.getFont();\n      var charSpace = options.charSpace || this.internal.getCharSpace();\n      var result = 0;\n\n      if (API.processArabic) {\n        text = API.processArabic(text);\n      }\n\n      if (typeof font.metadata.widthOfString === \"function\") {\n        result = font.metadata.widthOfString(text, fontSize, charSpace) / fontSize;\n      } else {\n        result = getCharWidthsArray.apply(this, arguments).reduce(function (pv, cv) {\n          return pv + cv;\n        }, 0);\n      }\n\n      return result;\n    };\n    /**\n    returns array of lines\n    */\n\n\n    var splitLongWord = function splitLongWord(word, widths_array, firstLineMaxLen, maxLen) {\n      var answer = []; // 1st, chop off the piece that can fit on the hanging line.\n\n      var i = 0,\n          l = word.length,\n          workingLen = 0;\n\n      while (i !== l && workingLen + widths_array[i] < firstLineMaxLen) {\n        workingLen += widths_array[i];\n        i++;\n      } // this is first line.\n\n\n      answer.push(word.slice(0, i)); // 2nd. Split the rest into maxLen pieces.\n\n      var startOfLine = i;\n      workingLen = 0;\n\n      while (i !== l) {\n        if (workingLen + widths_array[i] > maxLen) {\n          answer.push(word.slice(startOfLine, i));\n          workingLen = 0;\n          startOfLine = i;\n        }\n\n        workingLen += widths_array[i];\n        i++;\n      }\n\n      if (startOfLine !== i) {\n        answer.push(word.slice(startOfLine, i));\n      }\n\n      return answer;\n    }; // Note, all sizing inputs for this function must be in \"font measurement units\"\n    // By default, for PDF, it's \"point\".\n\n\n    var splitParagraphIntoLines = function splitParagraphIntoLines(text, maxlen, options) {\n      // at this time works only on Western scripts, ones with space char\n      // separating the words. Feel free to expand.\n      if (!options) {\n        options = {};\n      }\n\n      var line = [],\n          lines = [line],\n          line_length = options.textIndent || 0,\n          separator_length = 0,\n          current_word_length = 0,\n          word,\n          widths_array,\n          words = text.split(\" \"),\n          spaceCharWidth = getCharWidthsArray.apply(this, [\" \", options])[0],\n          i,\n          l,\n          tmp,\n          lineIndent;\n\n      if (options.lineIndent === -1) {\n        lineIndent = words[0].length + 2;\n      } else {\n        lineIndent = options.lineIndent || 0;\n      }\n\n      if (lineIndent) {\n        var pad = Array(lineIndent).join(\" \"),\n            wrds = [];\n        words.map(function (wrd) {\n          wrd = wrd.split(/\\s*\\n/);\n\n          if (wrd.length > 1) {\n            wrds = wrds.concat(wrd.map(function (wrd, idx) {\n              return (idx && wrd.length ? \"\\n\" : \"\") + wrd;\n            }));\n          } else {\n            wrds.push(wrd[0]);\n          }\n        });\n        words = wrds;\n        lineIndent = getStringUnitWidth.apply(this, [pad, options]);\n      }\n\n      for (i = 0, l = words.length; i < l; i++) {\n        var force = 0;\n        word = words[i];\n\n        if (lineIndent && word[0] == \"\\n\") {\n          word = word.substr(1);\n          force = 1;\n        }\n\n        widths_array = getCharWidthsArray.apply(this, [word, options]);\n        current_word_length = widths_array.reduce(function (pv, cv) {\n          return pv + cv;\n        }, 0);\n\n        if (line_length + separator_length + current_word_length > maxlen || force) {\n          if (current_word_length > maxlen) {\n            // this happens when you have space-less long URLs for example.\n            // we just chop these to size. We do NOT insert hiphens\n            tmp = splitLongWord.apply(this, [word, widths_array, maxlen - (line_length + separator_length), maxlen]); // first line we add to existing line object\n\n            line.push(tmp.shift()); // it's ok to have extra space indicator there\n            // last line we make into new line object\n\n            line = [tmp.pop()]; // lines in the middle we apped to lines object as whole lines\n\n            while (tmp.length) {\n              lines.push([tmp.shift()]); // single fragment occupies whole line\n            }\n\n            current_word_length = widths_array.slice(word.length - (line[0] ? line[0].length : 0)).reduce(function (pv, cv) {\n              return pv + cv;\n            }, 0);\n          } else {\n            // just put it on a new line\n            line = [word];\n          } // now we attach new line to lines\n\n\n          lines.push(line);\n          line_length = current_word_length + lineIndent;\n          separator_length = spaceCharWidth;\n        } else {\n          line.push(word);\n          line_length += separator_length + current_word_length;\n          separator_length = spaceCharWidth;\n        }\n      }\n\n      var postProcess;\n\n      if (lineIndent) {\n        postProcess = function postProcess(ln, idx) {\n          return (idx ? pad : \"\") + ln.join(\" \");\n        };\n      } else {\n        postProcess = function postProcess(ln) {\n          return ln.join(\" \");\n        };\n      }\n\n      return lines.map(postProcess);\n    };\n    /**\n     * Splits a given string into an array of strings. Uses 'size' value\n     * (in measurement units declared as default for the jsPDF instance)\n     * and the font's \"widths\" and \"Kerning\" tables, where available, to\n     * determine display length of a given string for a given font.\n     *\n     * We use character's 100% of unit size (height) as width when Width\n     * table or other default width is not available.\n     *\n     * @name splitTextToSize\n     * @public\n     * @function\n     * @param {string} text Unencoded, regular JavaScript (Unicode, UTF-16 / UCS-2) string.\n     * @param {number} size Nominal number, measured in units default to this instance of jsPDF.\n     * @param {Object} options Optional flags needed for chopper to do the right thing.\n     * @returns {Array} array Array with strings chopped to size.\n     */\n\n\n    API.splitTextToSize = function (text, maxlen, options) {\n\n      options = options || {};\n\n      var fsize = options.fontSize || this.internal.getFontSize(),\n          newOptions = function (options) {\n        var widths = {\n          0: 1\n        },\n            kerning = {};\n\n        if (!options.widths || !options.kerning) {\n          var f = this.internal.getFont(options.fontName, options.fontStyle),\n              encoding = \"Unicode\"; // NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE\n          // Actual JavaScript-native String's 16bit char codes used.\n          // no multi-byte logic here\n\n          if (f.metadata[encoding]) {\n            return {\n              widths: f.metadata[encoding].widths || widths,\n              kerning: f.metadata[encoding].kerning || kerning\n            };\n          } else {\n            return {\n              font: f.metadata,\n              fontSize: this.internal.getFontSize(),\n              charSpace: this.internal.getCharSpace()\n            };\n          }\n        } else {\n          return {\n            widths: options.widths,\n            kerning: options.kerning\n          };\n        }\n      }.call(this, options); // first we split on end-of-line chars\n\n\n      var paragraphs;\n\n      if (Array.isArray(text)) {\n        paragraphs = text;\n      } else {\n        paragraphs = String(text).split(/\\r?\\n/);\n      } // now we convert size (max length of line) into \"font size units\"\n      // at present time, the \"font size unit\" is always 'point'\n      // 'proportional' means, \"in proportion to font size\"\n\n\n      var fontUnit_maxLen = 1.0 * this.internal.scaleFactor * maxlen / fsize; // at this time, fsize is always in \"points\" regardless of the default measurement unit of the doc.\n      // this may change in the future?\n      // until then, proportional_maxlen is likely to be in 'points'\n      // If first line is to be indented (shorter or longer) than maxLen\n      // we indicate that by using CSS-style \"text-indent\" option.\n      // here it's in font units too (which is likely 'points')\n      // it can be negative (which makes the first line longer than maxLen)\n\n      newOptions.textIndent = options.textIndent ? options.textIndent * 1.0 * this.internal.scaleFactor / fsize : 0;\n      newOptions.lineIndent = options.lineIndent;\n      var i,\n          l,\n          output = [];\n\n      for (i = 0, l = paragraphs.length; i < l; i++) {\n        output = output.concat(splitParagraphIntoLines.apply(this, [paragraphs[i], fontUnit_maxLen, newOptions]));\n      }\n\n      return output;\n    };\n  })(jsPDF.API);\n\n  /**\n   * This file adds the standard font metrics to jsPDF.\n   *\n   * Font metrics data is reprocessed derivative of contents of\n   * \"Font Metrics for PDF Core 14 Fonts\" package, which exhibits the following copyright and license:\n   *\n   * Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.\n   *\n   * This file and the 14 PostScript(R) AFM files it accompanies may be used,\n   * copied, and distributed for any purpose and without charge, with or without\n   * modification, provided that all copyright notices are retained; that the AFM\n   * files are not distributed without this file; that all modifications to this\n   * file or any of the AFM files are prominently noted in the modified file(s);\n   * and that this paragraph is not modified. Adobe Systems has no responsibility\n   * or obligation to support the use of the AFM files.\n   *\n   * @name standard_fonts_metrics\n   * @module\n   */\n\n  (function (API) {\n\n    API.__fontmetrics__ = API.__fontmetrics__ || {};\n    var decoded = \"0123456789abcdef\",\n        encoded = \"klmnopqrstuvwxyz\",\n        mappingUncompress = {},\n        mappingCompress = {};\n\n    for (var i = 0; i < encoded.length; i++) {\n      mappingUncompress[encoded[i]] = decoded[i];\n      mappingCompress[decoded[i]] = encoded[i];\n    }\n\n    var hex = function hex(value) {\n      return \"0x\" + parseInt(value, 10).toString(16);\n    };\n\n    var compress = API.__fontmetrics__.compress = function (data) {\n      var vals = [\"{\"];\n      var value, keystring, valuestring, numberprefix;\n\n      for (var key in data) {\n        value = data[key];\n\n        if (!isNaN(parseInt(key, 10))) {\n          key = parseInt(key, 10);\n          keystring = hex(key).slice(2);\n          keystring = keystring.slice(0, -1) + mappingCompress[keystring.slice(-1)];\n        } else {\n          keystring = \"'\" + key + \"'\";\n        }\n\n        if (typeof value == \"number\") {\n          if (value < 0) {\n            valuestring = hex(value).slice(3);\n            numberprefix = \"-\";\n          } else {\n            valuestring = hex(value).slice(2);\n            numberprefix = \"\";\n          }\n\n          valuestring = numberprefix + valuestring.slice(0, -1) + mappingCompress[valuestring.slice(-1)];\n        } else {\n          if (_typeof(value) === \"object\") {\n            valuestring = compress(value);\n          } else {\n            throw new Error(\"Don't know what to do with value type \" + _typeof(value) + \".\");\n          }\n        }\n\n        vals.push(keystring + valuestring);\n      }\n\n      vals.push(\"}\");\n      return vals.join(\"\");\n    };\n    /**\n     * Uncompresses data compressed into custom, base16-like format.\n     *\n     * @public\n     * @function\n     * @param\n     * @returns {Type}\n     */\n\n\n    var uncompress = API.__fontmetrics__.uncompress = function (data) {\n      if (typeof data !== \"string\") {\n        throw new Error(\"Invalid argument passed to uncompress.\");\n      }\n\n      var output = {},\n          sign = 1,\n          stringparts,\n          // undef. will be [] in string mode\n      activeobject = output,\n          parentchain = [],\n          parent_key_pair,\n          keyparts = \"\",\n          valueparts = \"\",\n          key,\n          // undef. will be Truthy when Key is resolved.\n      datalen = data.length - 1,\n          // stripping ending }\n      ch;\n\n      for (var i = 1; i < datalen; i += 1) {\n        // - { } ' are special.\n        ch = data[i];\n\n        if (ch == \"'\") {\n          if (stringparts) {\n            // end of string mode\n            key = stringparts.join(\"\");\n            stringparts = undefined;\n          } else {\n            // start of string mode\n            stringparts = [];\n          }\n        } else if (stringparts) {\n          stringparts.push(ch);\n        } else if (ch == \"{\") {\n          // start of object\n          parentchain.push([activeobject, key]);\n          activeobject = {};\n          key = undefined;\n        } else if (ch == \"}\") {\n          // end of object\n          parent_key_pair = parentchain.pop();\n          parent_key_pair[0][parent_key_pair[1]] = activeobject;\n          key = undefined;\n          activeobject = parent_key_pair[0];\n        } else if (ch == \"-\") {\n          sign = -1;\n        } else {\n          // must be number\n          if (key === undefined) {\n            if (mappingUncompress.hasOwnProperty(ch)) {\n              keyparts += mappingUncompress[ch];\n              key = parseInt(keyparts, 16) * sign;\n              sign = +1;\n              keyparts = \"\";\n            } else {\n              keyparts += ch;\n            }\n          } else {\n            if (mappingUncompress.hasOwnProperty(ch)) {\n              valueparts += mappingUncompress[ch];\n              activeobject[key] = parseInt(valueparts, 16) * sign;\n              sign = +1;\n              key = undefined;\n              valueparts = \"\";\n            } else {\n              valueparts += ch;\n            }\n          }\n        }\n      }\n\n      return output;\n    }; // encoding = 'Unicode'\n    // NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE. NO clever BOM behavior\n    // Actual 16bit char codes used.\n    // no multi-byte logic here\n    // Unicode characters to WinAnsiEncoding:\n    // {402: 131, 8211: 150, 8212: 151, 8216: 145, 8217: 146, 8218: 130, 8220: 147, 8221: 148, 8222: 132, 8224: 134, 8225: 135, 8226: 149, 8230: 133, 8364: 128, 8240:137, 8249: 139, 8250: 155, 710: 136, 8482: 153, 338: 140, 339: 156, 732: 152, 352: 138, 353: 154, 376: 159, 381: 142, 382: 158}\n    // as you can see, all Unicode chars are outside of 0-255 range. No char code conflicts.\n    // this means that you can give Win cp1252 encoded strings to jsPDF for rendering directly\n    // as well as give strings with some (supported by these fonts) Unicode characters and\n    // these will be mapped to win cp1252\n    // for example, you can send char code (cp1252) 0x80 or (unicode) 0x20AC, getting \"Euro\" glyph displayed in both cases.\n\n\n    var encodingBlock = {\n      codePages: [\"WinAnsiEncoding\"],\n      WinAnsiEncoding: uncompress(\"{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}\")\n    };\n    var encodings = {\n      Unicode: {\n        Courier: encodingBlock,\n        \"Courier-Bold\": encodingBlock,\n        \"Courier-BoldOblique\": encodingBlock,\n        \"Courier-Oblique\": encodingBlock,\n        Helvetica: encodingBlock,\n        \"Helvetica-Bold\": encodingBlock,\n        \"Helvetica-BoldOblique\": encodingBlock,\n        \"Helvetica-Oblique\": encodingBlock,\n        \"Times-Roman\": encodingBlock,\n        \"Times-Bold\": encodingBlock,\n        \"Times-BoldItalic\": encodingBlock,\n        \"Times-Italic\": encodingBlock //\t, 'Symbol'\n        //\t, 'ZapfDingbats'\n\n      }\n    };\n    var fontMetrics = {\n      Unicode: {\n        // all sizing numbers are n/fontMetricsFractionOf = one font size unit\n        // this means that if fontMetricsFractionOf = 1000, and letter A's width is 476, it's\n        // width is 476/1000 or 47.6% of its height (regardless of font size)\n        // At this time this value applies to \"widths\" and \"kerning\" numbers.\n        // char code 0 represents \"default\" (average) width - use it for chars missing in this table.\n        // key 'fof' represents the \"fontMetricsFractionOf\" value\n        \"Courier-Oblique\": uncompress(\"{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}\"),\n        \"Times-BoldItalic\": uncompress(\"{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'kerning'{cl{4qu5kt5qt5rs17ss5ts}201s{201ss}201t{cks4lscmscnscoscpscls2wu2yu201ts}201x{2wu2yu}2k{201ts}2w{4qx5kx5ou5qx5rs17su5tu}2x{17su5tu5ou}2y{4qx5kx5ou5qx5rs17ss5ts}'fof'-6ofn{17sw5tw5ou5qw5rs}7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qs}3v{17su5tu5os5qs}7p{17su5tu}ck{4qu5kt5qt5rs17ss5ts}4l{4qu5kt5qt5rs17ss5ts}cm{4qu5kt5qt5rs17ss5ts}cn{4qu5kt5qt5rs17ss5ts}co{4qu5kt5qt5rs17ss5ts}cp{4qu5kt5qt5rs17ss5ts}6l{4qu5ou5qw5rt17su5tu}5q{ckuclucmucnucoucpu4lu}5r{ckuclucmucnucoucpu4lu}7q{cksclscmscnscoscps4ls}6p{4qu5ou5qw5rt17sw5tw}ek{4qu5ou5qw5rt17su5tu}el{4qu5ou5qw5rt17su5tu}em{4qu5ou5qw5rt17su5tu}en{4qu5ou5qw5rt17su5tu}eo{4qu5ou5qw5rt17su5tu}ep{4qu5ou5qw5rt17su5tu}es{17ss5ts5qs4qu}et{4qu5ou5qw5rt17sw5tw}eu{4qu5ou5qw5rt17ss5ts}ev{17ss5ts5qs4qu}6z{17sw5tw5ou5qw5rs}fm{17sw5tw5ou5qw5rs}7n{201ts}fo{17sw5tw5ou5qw5rs}fp{17sw5tw5ou5qw5rs}fq{17sw5tw5ou5qw5rs}7r{cksclscmscnscoscps4ls}fs{17sw5tw5ou5qw5rs}ft{17su5tu}fu{17su5tu}fv{17su5tu}fw{17su5tu}fz{cksclscmscnscoscps4ls}}}\"),\n        \"Helvetica-Bold\": uncompress(\"{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}\"),\n        Courier: uncompress(\"{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}\"),\n        \"Courier-BoldOblique\": uncompress(\"{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}\"),\n        \"Times-Bold\": uncompress(\"{'widths'{k3q2q5ncx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2l202m2n2n3m2o3m2p6o202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5x4l4s4m4m4n4s4o4s4p4m4q3x4r4y4s4y4t2r4u3m4v4y4w4m4x5y4y4s4z4y5k3x5l4y5m4s5n3r5o4m5p4s5q4s5r6o5s4s5t4s5u4m5v2l5w1w5x2l5y3u5z3m6k2l6l3m6m3r6n2w6o3r6p2w6q2l6r3m6s3r6t1w6u2l6v3r6w1w6x5n6y3r6z3m7k3r7l3r7m2w7n2r7o2l7p3r7q3m7r4s7s3m7t3m7u2w7v2r7w1q7x2r7y3o202l3mcl4sal2lam3man3mao3map3mar3mas2lat4uau1yav3maw3tay4uaz2lbk2sbl3t'fof'6obo2lbp3rbr1tbs2lbu2lbv3mbz3mck4s202k3mcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3rek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3m3u2l17s4s19m3m}'kerning'{cl{4qt5ks5ot5qy5rw17sv5tv}201t{cks4lscmscnscoscpscls4wv}2k{201ts}2w{4qu5ku7mu5os5qx5ru17su5tu}2x{17su5tu5ou5qs}2y{4qv5kv7mu5ot5qz5ru17su5tu}'fof'-6o7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qu}3v{17su5tu5os5qu}fu{17su5tu5ou5qu}7p{17su5tu5ou5qu}ck{4qt5ks5ot5qy5rw17sv5tv}4l{4qt5ks5ot5qy5rw17sv5tv}cm{4qt5ks5ot5qy5rw17sv5tv}cn{4qt5ks5ot5qy5rw17sv5tv}co{4qt5ks5ot5qy5rw17sv5tv}cp{4qt5ks5ot5qy5rw17sv5tv}6l{17st5tt5ou5qu}17s{ckuclucmucnucoucpu4lu4wu}5o{ckuclucmucnucoucpu4lu4wu}5q{ckzclzcmzcnzcozcpz4lz4wu}5r{ckxclxcmxcnxcoxcpx4lx4wu}5t{ckuclucmucnucoucpu4lu4wu}7q{ckuclucmucnucoucpu4lu}6p{17sw5tw5ou5qu}ek{17st5tt5qu}el{17st5tt5ou5qu}em{17st5tt5qu}en{17st5tt5qu}eo{17st5tt5qu}ep{17st5tt5ou5qu}es{17ss5ts5qu}et{17sw5tw5ou5qu}eu{17sw5tw5ou5qu}ev{17ss5ts5qu}6z{17sw5tw5ou5qu5rs}fm{17sw5tw5ou5qu5rs}fn{17sw5tw5ou5qu5rs}fo{17sw5tw5ou5qu5rs}fp{17sw5tw5ou5qu5rs}fq{17sw5tw5ou5qu5rs}7r{cktcltcmtcntcotcpt4lt5os}fs{17sw5tw5ou5qu5rs}ft{17su5tu5ou5qu}7m{5os}fv{17su5tu5ou5qu}fw{17su5tu5ou5qu}fz{cksclscmscnscoscps4ls}}}\"),\n        Symbol: uncompress(\"{'widths'{k3uaw4r19m3m2k1t2l2l202m2y2n3m2p5n202q6o3k3m2s2l2t2l2v3r2w1t3m3m2y1t2z1wbk2sbl3r'fof'6o3n3m3o3m3p3m3q3m3r3m3s3m3t3m3u1w3v1w3w3r3x3r3y3r3z2wbp3t3l3m5v2l5x2l5z3m2q4yfr3r7v3k7w1o7x3k}'kerning'{'fof'-6o}}\"),\n        Helvetica: uncompress(\"{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}\"),\n        \"Helvetica-BoldOblique\": uncompress(\"{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}\"),\n        ZapfDingbats: uncompress(\"{'widths'{k4u2k1w'fof'6o}'kerning'{'fof'-6o}}\"),\n        \"Courier-Bold\": uncompress(\"{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}\"),\n        \"Times-Italic\": uncompress(\"{'widths'{k3n2q4ycx2l201n3m201o5t201s2l201t2l201u2l201w3r201x3r201y3r2k1t2l2l202m2n2n3m2o3m2p5n202q5t2r1p2s2l2t2l2u3m2v4n2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w4n3x4n3y4n3z3m4k5w4l3x4m3x4n4m4o4s4p3x4q3x4r4s4s4s4t2l4u2w4v4m4w3r4x5n4y4m4z4s5k3x5l4s5m3x5n3m5o3r5p4s5q3x5r5n5s3x5t3r5u3r5v2r5w1w5x2r5y2u5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q1w6r3m6s3m6t1w6u1w6v2w6w1w6x4s6y3m6z3m7k3m7l3m7m2r7n2r7o1w7p3m7q2w7r4m7s2w7t2w7u2r7v2s7w1v7x2s7y3q202l3mcl3xal2ram3man3mao3map3mar3mas2lat4wau1vav3maw4nay4waz2lbk2sbl4n'fof'6obo2lbp3mbq3obr1tbs2lbu1zbv3mbz3mck3x202k3mcm3xcn3xco3xcp3xcq5tcr4mcs3xct3xcu3xcv3xcw2l2m2ucy2lcz2ldl4mdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr4nfs3mft3mfu3mfv3mfw3mfz2w203k6o212m6m2dw2l2cq2l3t3m3u2l17s3r19m3m}'kerning'{cl{5kt4qw}201s{201sw}201t{201tw2wy2yy6q-t}201x{2wy2yy}2k{201tw}2w{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}2x{17ss5ts5os}2y{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}'fof'-6o6t{17ss5ts5qs}7t{5os}3v{5qs}7p{17su5tu5qs}ck{5kt4qw}4l{5kt4qw}cm{5kt4qw}cn{5kt4qw}co{5kt4qw}cp{5kt4qw}6l{4qs5ks5ou5qw5ru17su5tu}17s{2ks}5q{ckvclvcmvcnvcovcpv4lv}5r{ckuclucmucnucoucpu4lu}5t{2ks}6p{4qs5ks5ou5qw5ru17su5tu}ek{4qs5ks5ou5qw5ru17su5tu}el{4qs5ks5ou5qw5ru17su5tu}em{4qs5ks5ou5qw5ru17su5tu}en{4qs5ks5ou5qw5ru17su5tu}eo{4qs5ks5ou5qw5ru17su5tu}ep{4qs5ks5ou5qw5ru17su5tu}es{5ks5qs4qs}et{4qs5ks5ou5qw5ru17su5tu}eu{4qs5ks5qw5ru17su5tu}ev{5ks5qs4qs}ex{17ss5ts5qs}6z{4qv5ks5ou5qw5ru17su5tu}fm{4qv5ks5ou5qw5ru17su5tu}fn{4qv5ks5ou5qw5ru17su5tu}fo{4qv5ks5ou5qw5ru17su5tu}fp{4qv5ks5ou5qw5ru17su5tu}fq{4qv5ks5ou5qw5ru17su5tu}7r{5os}fs{4qv5ks5ou5qw5ru17su5tu}ft{17su5tu5qs}fu{17su5tu5qs}fv{17su5tu5qs}fw{17su5tu5qs}}}\"),\n        \"Times-Roman\": uncompress(\"{'widths'{k3n2q4ycx2l201n3m201o6o201s2l201t2l201u2l201w2w201x2w201y2w2k1t2l2l202m2n2n3m2o3m2p5n202q6o2r1m2s2l2t2l2u3m2v3s2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v1w3w3s3x3s3y3s3z2w4k5w4l4s4m4m4n4m4o4s4p3x4q3r4r4s4s4s4t2l4u2r4v4s4w3x4x5t4y4s4z4s5k3r5l4s5m4m5n3r5o3x5p4s5q4s5r5y5s4s5t4s5u3x5v2l5w1w5x2l5y2z5z3m6k2l6l2w6m3m6n2w6o3m6p2w6q2l6r3m6s3m6t1w6u1w6v3m6w1w6x4y6y3m6z3m7k3m7l3m7m2l7n2r7o1w7p3m7q3m7r4s7s3m7t3m7u2w7v3k7w1o7x3k7y3q202l3mcl4sal2lam3man3mao3map3mar3mas2lat4wau1vav3maw3say4waz2lbk2sbl3s'fof'6obo2lbp3mbq2xbr1tbs2lbu1zbv3mbz2wck4s202k3mcm4scn4sco4scp4scq5tcr4mcs3xct3xcu3xcv3xcw2l2m2tcy2lcz2ldl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek2wel2wem2wen2weo2wep2weq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr3sfs3mft3mfu3mfv3mfw3mfz3m203k6o212m6m2dw2l2cq2l3t3m3u1w17s4s19m3m}'kerning'{cl{4qs5ku17sw5ou5qy5rw201ss5tw201ws}201s{201ss}201t{ckw4lwcmwcnwcowcpwclw4wu201ts}2k{201ts}2w{4qs5kw5os5qx5ru17sx5tx}2x{17sw5tw5ou5qu}2y{4qs5kw5os5qx5ru17sx5tx}'fof'-6o7t{ckuclucmucnucoucpu4lu5os5rs}3u{17su5tu5qs}3v{17su5tu5qs}7p{17sw5tw5qs}ck{4qs5ku17sw5ou5qy5rw201ss5tw201ws}4l{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cm{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cn{4qs5ku17sw5ou5qy5rw201ss5tw201ws}co{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cp{4qs5ku17sw5ou5qy5rw201ss5tw201ws}6l{17su5tu5os5qw5rs}17s{2ktclvcmvcnvcovcpv4lv4wuckv}5o{ckwclwcmwcnwcowcpw4lw4wu}5q{ckyclycmycnycoycpy4ly4wu5ms}5r{cktcltcmtcntcotcpt4lt4ws}5t{2ktclvcmvcnvcovcpv4lv4wuckv}7q{cksclscmscnscoscps4ls}6p{17su5tu5qw5rs}ek{5qs5rs}el{17su5tu5os5qw5rs}em{17su5tu5os5qs5rs}en{17su5qs5rs}eo{5qs5rs}ep{17su5tu5os5qw5rs}es{5qs}et{17su5tu5qw5rs}eu{17su5tu5qs5rs}ev{5qs}6z{17sv5tv5os5qx5rs}fm{5os5qt5rs}fn{17sv5tv5os5qx5rs}fo{17sv5tv5os5qx5rs}fp{5os5qt5rs}fq{5os5qt5rs}7r{ckuclucmucnucoucpu4lu5os}fs{17sv5tv5os5qx5rs}ft{17ss5ts5qs}fu{17sw5tw5qs}fv{17sw5tw5qs}fw{17ss5ts5qs}fz{ckuclucmucnucoucpu4lu5os5rs}}}\"),\n        \"Helvetica-Oblique\": uncompress(\"{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}\")\n      }\n    };\n    /*\n    This event handler is fired when a new jsPDF object is initialized\n    This event handler appends metrics data to standard fonts within\n    that jsPDF instance. The metrics are mapped over Unicode character\n    codes, NOT CIDs or other codes matching the StandardEncoding table of the\n    standard PDF fonts.\n    Future:\n    Also included is the encoding maping table, converting Unicode (UCS-2, UTF-16)\n    char codes to StandardEncoding character codes. The encoding table is to be used\n    somewhere around \"pdfEscape\" call.\n    */\n\n    API.events.push([\"addFont\", function (data) {\n      var font = data.font;\n      var metrics = fontMetrics[\"Unicode\"][font.postScriptName];\n\n      if (metrics) {\n        font.metadata[\"Unicode\"] = {};\n        font.metadata[\"Unicode\"].widths = metrics.widths;\n        font.metadata[\"Unicode\"].kerning = metrics.kerning;\n      }\n\n      var encodingBlock = encodings[\"Unicode\"][font.postScriptName];\n\n      if (encodingBlock) {\n        font.metadata[\"Unicode\"].encoding = encodingBlock;\n        font.encoding = encodingBlock.codePages[0];\n      }\n    }]); // end of adding event handler\n  })(jsPDF.API);\n\n  /**\n   * @license\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n  /**\n   * @name ttfsupport\n   * @module\n   */\n\n  (function (jsPDF) {\n\n    var binaryStringToUint8Array = function binaryStringToUint8Array(binary_string) {\n      var len = binary_string.length;\n      var bytes = new Uint8Array(len);\n\n      for (var i = 0; i < len; i++) {\n        bytes[i] = binary_string.charCodeAt(i);\n      }\n\n      return bytes;\n    };\n\n    var addFont = function addFont(font, file) {\n      // eslint-disable-next-line no-control-regex\n      if (/^\\x00\\x01\\x00\\x00/.test(file)) {\n        file = binaryStringToUint8Array(file);\n      } else {\n        file = binaryStringToUint8Array(atob(file));\n      }\n\n      font.metadata = jsPDF.API.TTFFont.open(file);\n      font.metadata.Unicode = font.metadata.Unicode || {\n        encoding: {},\n        kerning: {},\n        widths: []\n      };\n      font.metadata.glyIdsUsed = [0];\n    };\n\n    jsPDF.API.events.push([\"addFont\", function (data) {\n      var file = undefined;\n      var font = data.font;\n      var instance = data.instance;\n\n      if (font.isStandardFont) {\n        return;\n      }\n\n      if (typeof instance !== \"undefined\") {\n        if (instance.existsFileInVFS(font.postScriptName) === false) {\n          file = instance.loadFile(font.postScriptName);\n        } else {\n          file = instance.getFileFromVFS(font.postScriptName);\n        }\n\n        if (typeof file !== \"string\") {\n          throw new Error(\"Font is not stored as string-data in vFS, import fonts or remove declaration doc.addFont('\" + font.postScriptName + \"').\");\n        }\n\n        addFont(font, file);\n      } else {\n        throw new Error(\"Font does not exist in vFS, import fonts or remove declaration doc.addFont('\" + font.postScriptName + \"').\");\n      }\n    }]); // end of adding event handler\n  })(jsPDF);\n\n  /**\n   * jsPDF SVG plugin\n   *\n   * @name svg\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n\n    function loadCanvg() {\n      return function () {\n        if (globalObject[\"canvg\"]) {\n          return Promise.resolve(globalObject[\"canvg\"]);\n        }\n\n        if ((typeof exports === \"undefined\" ? \"undefined\" : _typeof(exports)) === \"object\" && typeof module !== \"undefined\") {\n          return new Promise(function (resolve, reject) {\n            try {\n              resolve(require(\"canvg\"));\n            } catch (e) {\n              reject(e);\n            }\n          });\n        }\n\n        if (typeof define === \"function\" && define.amd) {\n          return new Promise(function (resolve, reject) {\n            try {\n              require([\"canvg\"], resolve);\n            } catch (e) {\n              reject(e);\n            }\n          });\n        }\n\n        return Promise.reject(new Error(\"Could not load canvg\"));\n      }().catch(function (e) {\n        return Promise.reject(new Error(\"Could not load canvg: \" + e));\n      }).then(function (canvg) {\n        return canvg.default ? canvg.default : canvg;\n      });\n    }\n    /**\n     * Parses SVG XML and saves it as image into the PDF.\n     *\n     * Depends on canvas-element and canvg\n     *\n     * @name addSvgAsImage\n     * @public\n     * @function\n     * @param {string} SVG-Data as Text\n     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page\n     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page\n     * @param {number} width of SVG-Image (in units declared at inception of PDF document)\n     * @param {number} height of SVG-Image (in units declared at inception of PDF document)\n     * @param {string} alias of SVG-Image (if used multiple times)\n     * @param {string} compression of the generated JPEG, can have the values 'NONE', 'FAST', 'MEDIUM' and 'SLOW'\n     * @param {number} rotation of the image in degrees (0-359)\n     *\n     * @returns jsPDF jsPDF-instance\n     */\n\n\n    jsPDFAPI.addSvgAsImage = function (svg, x, y, w, h, alias, compression, rotation) {\n      if (isNaN(x) || isNaN(y)) {\n        console.error(\"jsPDF.addSvgAsImage: Invalid coordinates\", arguments);\n        throw new Error(\"Invalid coordinates passed to jsPDF.addSvgAsImage\");\n      }\n\n      if (isNaN(w) || isNaN(h)) {\n        console.error(\"jsPDF.addSvgAsImage: Invalid measurements\", arguments);\n        throw new Error(\"Invalid measurements (width and/or height) passed to jsPDF.addSvgAsImage\");\n      }\n\n      var canvas = document.createElement(\"canvas\");\n      canvas.width = w;\n      canvas.height = h;\n      var ctx = canvas.getContext(\"2d\");\n      ctx.fillStyle = \"#fff\"; /// set white fill style\n\n      ctx.fillRect(0, 0, canvas.width, canvas.height);\n      var options = {\n        ignoreMouse: true,\n        ignoreAnimation: true,\n        ignoreDimensions: true\n      };\n      var doc = this;\n      return loadCanvg().then(function (canvg) {\n        return canvg.fromString(ctx, svg, options);\n      }, function () {\n        return Promise.reject(new Error(\"Could not load canvg.\"));\n      }).then(function (instance) {\n        return instance.render(options);\n      }).then(function () {\n        doc.addImage(canvas.toDataURL(\"image/jpeg\", 1.0), x, y, w, h, compression, rotation);\n      });\n    };\n  })(jsPDF.API);\n\n  /**\n   * @license\n   * ====================================================================\n   * Copyright (c) 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br\n   *\n   * Permission is hereby granted, free of charge, to any person obtaining\n   * a copy of this software and associated documentation files (the\n   * \"Software\"), to deal in the Software without restriction, including\n   * without limitation the rights to use, copy, modify, merge, publish,\n   * distribute, sublicense, and/or sell copies of the Software, and to\n   * permit persons to whom the Software is furnished to do so, subject to\n   * the following conditions:\n   *\n   * The above copyright notice and this permission notice shall be\n   * included in all copies or substantial portions of the Software.\n   *\n   * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n   * ====================================================================\n   */\n  /**\n   * jsPDF total_pages plugin\n   * @name total_pages\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n    /**\n     * @name putTotalPages\n     * @function\n     * @param {string} pageExpression Regular Expression\n     * @returns {jsPDF} jsPDF-instance\n     */\n\n    jsPDFAPI.putTotalPages = function (pageExpression) {\n\n      var replaceExpression;\n      var totalNumberOfPages = 0;\n\n      if (parseInt(this.internal.getFont().id.substr(1), 10) < 15) {\n        replaceExpression = new RegExp(pageExpression, \"g\");\n        totalNumberOfPages = this.internal.getNumberOfPages();\n      } else {\n        replaceExpression = new RegExp(this.pdfEscape16(pageExpression, this.internal.getFont()), \"g\");\n        totalNumberOfPages = this.pdfEscape16(this.internal.getNumberOfPages() + \"\", this.internal.getFont());\n      }\n\n      for (var n = 1; n <= this.internal.getNumberOfPages(); n++) {\n        for (var i = 0; i < this.internal.pages[n].length; i++) {\n          this.internal.pages[n][i] = this.internal.pages[n][i].replace(replaceExpression, totalNumberOfPages);\n        }\n      }\n\n      return this;\n    };\n  })(jsPDF.API);\n\n  /**\n   * Adds the ability to set ViewerPreferences and by thus\n   * controlling the way the document is to be presented on the\n   * screen or in print.\n   * @name viewerpreferences\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n    /**\n     * Set the ViewerPreferences of the generated PDF\n     *\n     * @name viewerPreferences\n     * @function\n     * @public\n     * @param {Object} options Array with the ViewerPreferences<br />\n     * Example: doc.viewerPreferences({\"FitWindow\":true});<br />\n     * <br />\n     * You can set following preferences:<br />\n     * <br/>\n     * <b>HideToolbar</b> <i>(boolean)</i><br />\n     * Default value: false<br />\n     * <br />\n     * <b>HideMenubar</b> <i>(boolean)</i><br />\n     * Default value: false.<br />\n     * <br />\n     * <b>HideWindowUI</b> <i>(boolean)</i><br />\n     * Default value: false.<br />\n     * <br />\n     * <b>FitWindow</b> <i>(boolean)</i><br />\n     * Default value: false.<br />\n     * <br />\n     * <b>CenterWindow</b> <i>(boolean)</i><br />\n     * Default value: false<br />\n     * <br />\n     * <b>DisplayDocTitle</b> <i>(boolean)</i><br />\n     * Default value: false.<br />\n     * <br />\n     * <b>NonFullScreenPageMode</b> <i>(string)</i><br />\n     * Possible values: UseNone, UseOutlines, UseThumbs, UseOC<br />\n     * Default value: UseNone<br/>\n     * <br />\n     * <b>Direction</b> <i>(string)</i><br />\n     * Possible values: L2R, R2L<br />\n     * Default value: L2R.<br />\n     * <br />\n     * <b>ViewArea</b> <i>(string)</i><br />\n     * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />\n     * Default value: CropBox.<br />\n     * <br />\n     * <b>ViewClip</b> <i>(string)</i><br />\n     * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />\n     * Default value: CropBox<br />\n     * <br />\n     * <b>PrintArea</b> <i>(string)</i><br />\n     * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />\n     * Default value: CropBox<br />\n     * <br />\n     * <b>PrintClip</b> <i>(string)</i><br />\n     * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />\n     * Default value: CropBox.<br />\n     * <br />\n     * <b>PrintScaling</b> <i>(string)</i><br />\n     * Possible values: AppDefault, None<br />\n     * Default value: AppDefault.<br />\n     * <br />\n     * <b>Duplex</b> <i>(string)</i><br />\n     * Possible values: Simplex, DuplexFlipLongEdge, DuplexFlipShortEdge\n     * Default value: none<br />\n     * <br />\n     * <b>PickTrayByPDFSize</b> <i>(boolean)</i><br />\n     * Default value: false<br />\n     * <br />\n     * <b>PrintPageRange</b> <i>(Array)</i><br />\n     * Example: [[1,5], [7,9]]<br />\n     * Default value: as defined by PDF viewer application<br />\n     * <br />\n     * <b>NumCopies</b> <i>(Number)</i><br />\n     * Possible values: 1, 2, 3, 4, 5<br />\n     * Default value: 1<br />\n     * <br />\n     * For more information see the PDF Reference, sixth edition on Page 577\n     * @param {boolean} doReset True to reset the settings\n     * @function\n     * @returns jsPDF jsPDF-instance\n     * @example\n     * var doc = new jsPDF()\n     * doc.text('This is a test', 10, 10)\n     * doc.viewerPreferences({'FitWindow': true}, true)\n     * doc.save(\"viewerPreferences.pdf\")\n     *\n     * // Example printing 10 copies, using cropbox, and hiding UI.\n     * doc.viewerPreferences({\n     *   'HideWindowUI': true,\n     *   'PrintArea': 'CropBox',\n     *   'NumCopies': 10\n     * })\n     */\n\n    jsPDFAPI.viewerPreferences = function (options, doReset) {\n      options = options || {};\n      doReset = doReset || false;\n      var configuration;\n      var configurationTemplate = {\n        HideToolbar: {\n          defaultValue: false,\n          value: false,\n          type: \"boolean\",\n          explicitSet: false,\n          valueSet: [true, false],\n          pdfVersion: 1.3\n        },\n        HideMenubar: {\n          defaultValue: false,\n          value: false,\n          type: \"boolean\",\n          explicitSet: false,\n          valueSet: [true, false],\n          pdfVersion: 1.3\n        },\n        HideWindowUI: {\n          defaultValue: false,\n          value: false,\n          type: \"boolean\",\n          explicitSet: false,\n          valueSet: [true, false],\n          pdfVersion: 1.3\n        },\n        FitWindow: {\n          defaultValue: false,\n          value: false,\n          type: \"boolean\",\n          explicitSet: false,\n          valueSet: [true, false],\n          pdfVersion: 1.3\n        },\n        CenterWindow: {\n          defaultValue: false,\n          value: false,\n          type: \"boolean\",\n          explicitSet: false,\n          valueSet: [true, false],\n          pdfVersion: 1.3\n        },\n        DisplayDocTitle: {\n          defaultValue: false,\n          value: false,\n          type: \"boolean\",\n          explicitSet: false,\n          valueSet: [true, false],\n          pdfVersion: 1.4\n        },\n        NonFullScreenPageMode: {\n          defaultValue: \"UseNone\",\n          value: \"UseNone\",\n          type: \"name\",\n          explicitSet: false,\n          valueSet: [\"UseNone\", \"UseOutlines\", \"UseThumbs\", \"UseOC\"],\n          pdfVersion: 1.3\n        },\n        Direction: {\n          defaultValue: \"L2R\",\n          value: \"L2R\",\n          type: \"name\",\n          explicitSet: false,\n          valueSet: [\"L2R\", \"R2L\"],\n          pdfVersion: 1.3\n        },\n        ViewArea: {\n          defaultValue: \"CropBox\",\n          value: \"CropBox\",\n          type: \"name\",\n          explicitSet: false,\n          valueSet: [\"MediaBox\", \"CropBox\", \"TrimBox\", \"BleedBox\", \"ArtBox\"],\n          pdfVersion: 1.4\n        },\n        ViewClip: {\n          defaultValue: \"CropBox\",\n          value: \"CropBox\",\n          type: \"name\",\n          explicitSet: false,\n          valueSet: [\"MediaBox\", \"CropBox\", \"TrimBox\", \"BleedBox\", \"ArtBox\"],\n          pdfVersion: 1.4\n        },\n        PrintArea: {\n          defaultValue: \"CropBox\",\n          value: \"CropBox\",\n          type: \"name\",\n          explicitSet: false,\n          valueSet: [\"MediaBox\", \"CropBox\", \"TrimBox\", \"BleedBox\", \"ArtBox\"],\n          pdfVersion: 1.4\n        },\n        PrintClip: {\n          defaultValue: \"CropBox\",\n          value: \"CropBox\",\n          type: \"name\",\n          explicitSet: false,\n          valueSet: [\"MediaBox\", \"CropBox\", \"TrimBox\", \"BleedBox\", \"ArtBox\"],\n          pdfVersion: 1.4\n        },\n        PrintScaling: {\n          defaultValue: \"AppDefault\",\n          value: \"AppDefault\",\n          type: \"name\",\n          explicitSet: false,\n          valueSet: [\"AppDefault\", \"None\"],\n          pdfVersion: 1.6\n        },\n        Duplex: {\n          defaultValue: \"\",\n          value: \"none\",\n          type: \"name\",\n          explicitSet: false,\n          valueSet: [\"Simplex\", \"DuplexFlipShortEdge\", \"DuplexFlipLongEdge\", \"none\"],\n          pdfVersion: 1.7\n        },\n        PickTrayByPDFSize: {\n          defaultValue: false,\n          value: false,\n          type: \"boolean\",\n          explicitSet: false,\n          valueSet: [true, false],\n          pdfVersion: 1.7\n        },\n        PrintPageRange: {\n          defaultValue: \"\",\n          value: \"\",\n          type: \"array\",\n          explicitSet: false,\n          valueSet: null,\n          pdfVersion: 1.7\n        },\n        NumCopies: {\n          defaultValue: 1,\n          value: 1,\n          type: \"integer\",\n          explicitSet: false,\n          valueSet: null,\n          pdfVersion: 1.7\n        }\n      };\n      var configurationKeys = Object.keys(configurationTemplate);\n      var rangeArray = [];\n      var i = 0;\n      var j = 0;\n      var k = 0;\n      var isValid;\n      var method;\n      var value;\n\n      function arrayContainsElement(array, element) {\n        var iterator;\n        var result = false;\n\n        for (iterator = 0; iterator < array.length; iterator += 1) {\n          if (array[iterator] === element) {\n            result = true;\n          }\n        }\n\n        return result;\n      }\n\n      if (this.internal.viewerpreferences === undefined) {\n        this.internal.viewerpreferences = {};\n        this.internal.viewerpreferences.configuration = JSON.parse(JSON.stringify(configurationTemplate));\n        this.internal.viewerpreferences.isSubscribed = false;\n      }\n\n      configuration = this.internal.viewerpreferences.configuration;\n\n      if (options === \"reset\" || doReset === true) {\n        var len = configurationKeys.length;\n\n        for (k = 0; k < len; k += 1) {\n          configuration[configurationKeys[k]].value = configuration[configurationKeys[k]].defaultValue;\n          configuration[configurationKeys[k]].explicitSet = false;\n        }\n      }\n\n      if (_typeof(options) === \"object\") {\n        for (method in options) {\n          value = options[method];\n\n          if (arrayContainsElement(configurationKeys, method) && value !== undefined) {\n            if (configuration[method].type === \"boolean\" && typeof value === \"boolean\") {\n              configuration[method].value = value;\n            } else if (configuration[method].type === \"name\" && arrayContainsElement(configuration[method].valueSet, value)) {\n              configuration[method].value = value;\n            } else if (configuration[method].type === \"integer\" && Number.isInteger(value)) {\n              configuration[method].value = value;\n            } else if (configuration[method].type === \"array\") {\n              for (i = 0; i < value.length; i += 1) {\n                isValid = true;\n\n                if (value[i].length === 1 && typeof value[i][0] === \"number\") {\n                  rangeArray.push(String(value[i] - 1));\n                } else if (value[i].length > 1) {\n                  for (j = 0; j < value[i].length; j += 1) {\n                    if (typeof value[i][j] !== \"number\") {\n                      isValid = false;\n                    }\n                  }\n\n                  if (isValid === true) {\n                    rangeArray.push([value[i][0] - 1, value[i][1] - 1].join(\" \"));\n                  }\n                }\n              }\n\n              configuration[method].value = \"[\" + rangeArray.join(\" \") + \"]\";\n            } else {\n              configuration[method].value = configuration[method].defaultValue;\n            }\n\n            configuration[method].explicitSet = true;\n          }\n        }\n      }\n\n      if (this.internal.viewerpreferences.isSubscribed === false) {\n        this.internal.events.subscribe(\"putCatalog\", function () {\n          var pdfDict = [];\n          var vPref;\n\n          for (vPref in configuration) {\n            if (configuration[vPref].explicitSet === true) {\n              if (configuration[vPref].type === \"name\") {\n                pdfDict.push(\"/\" + vPref + \" /\" + configuration[vPref].value);\n              } else {\n                pdfDict.push(\"/\" + vPref + \" \" + configuration[vPref].value);\n              }\n            }\n          }\n\n          if (pdfDict.length !== 0) {\n            this.internal.write(\"/ViewerPreferences\\n<<\\n\" + pdfDict.join(\"\\n\") + \"\\n>>\");\n          }\n        });\n        this.internal.viewerpreferences.isSubscribed = true;\n      }\n\n      this.internal.viewerpreferences.configuration = configuration;\n      return this;\n    };\n  })(jsPDF.API);\n\n  /** ====================================================================\n   * @license\n   * jsPDF XMP metadata plugin\n   * Copyright (c) 2016 Jussi Utunen, u-jussi@suomi24.fi\n   *\n   * Permission is hereby granted, free of charge, to any person obtaining\n   * a copy of this software and associated documentation files (the\n   * \"Software\"), to deal in the Software without restriction, including\n   * without limitation the rights to use, copy, modify, merge, publish,\n   * distribute, sublicense, and/or sell copies of the Software, and to\n   * permit persons to whom the Software is furnished to do so, subject to\n   * the following conditions:\n   *\n   * The above copyright notice and this permission notice shall be\n   * included in all copies or substantial portions of the Software.\n   *\n   * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n   * ====================================================================\n   */\n  /**\n   * @name xmp_metadata\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n\n    var postPutResources = function postPutResources() {\n      var xmpmeta_beginning = '<x:xmpmeta xmlns:x=\"adobe:ns:meta/\">';\n      var rdf_beginning = '<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"><rdf:Description rdf:about=\"\" xmlns:jspdf=\"' + this.internal.__metadata__.namespaceuri + '\"><jspdf:metadata>';\n      var rdf_ending = \"</jspdf:metadata></rdf:Description></rdf:RDF>\";\n      var xmpmeta_ending = \"</x:xmpmeta>\";\n      var utf8_xmpmeta_beginning = unescape(encodeURIComponent(xmpmeta_beginning));\n      var utf8_rdf_beginning = unescape(encodeURIComponent(rdf_beginning));\n      var utf8_metadata = unescape(encodeURIComponent(this.internal.__metadata__.metadata));\n      var utf8_rdf_ending = unescape(encodeURIComponent(rdf_ending));\n      var utf8_xmpmeta_ending = unescape(encodeURIComponent(xmpmeta_ending));\n      var total_len = utf8_rdf_beginning.length + utf8_metadata.length + utf8_rdf_ending.length + utf8_xmpmeta_beginning.length + utf8_xmpmeta_ending.length;\n      this.internal.__metadata__.metadata_object_number = this.internal.newObject();\n      this.internal.write(\"<< /Type /Metadata /Subtype /XML /Length \" + total_len + \" >>\");\n      this.internal.write(\"stream\");\n      this.internal.write(utf8_xmpmeta_beginning + utf8_rdf_beginning + utf8_metadata + utf8_rdf_ending + utf8_xmpmeta_ending);\n      this.internal.write(\"endstream\");\n      this.internal.write(\"endobj\");\n    };\n\n    var putCatalog = function putCatalog() {\n      if (this.internal.__metadata__.metadata_object_number) {\n        this.internal.write(\"/Metadata \" + this.internal.__metadata__.metadata_object_number + \" 0 R\");\n      }\n    };\n    /**\n     * Adds XMP formatted metadata to PDF\n     *\n     * @name addMetadata\n     * @function\n     * @param {String} metadata The actual metadata to be added. The metadata shall be stored as XMP simple value. Note that if the metadata string contains XML markup characters \"<\", \">\" or \"&\", those characters should be written using XML entities.\n     * @param {String} namespaceuri Sets the namespace URI for the metadata. Last character should be slash or hash.\n     * @returns {jsPDF} jsPDF-instance\n     */\n\n\n    jsPDFAPI.addMetadata = function (metadata, namespaceuri) {\n      if (typeof this.internal.__metadata__ === \"undefined\") {\n        this.internal.__metadata__ = {\n          metadata: metadata,\n          namespaceuri: namespaceuri || \"http://jspdf.default.namespaceuri/\"\n        };\n        this.internal.events.subscribe(\"putCatalog\", putCatalog);\n        this.internal.events.subscribe(\"postPutResources\", postPutResources);\n      }\n\n      return this;\n    };\n  })(jsPDF.API);\n\n  /**\n   * @name utf8\n   * @module\n   */\n\n  (function (jsPDF) {\n\n    var jsPDFAPI = jsPDF.API;\n    /***************************************************************************************************/\n\n    /* function : pdfEscape16                                                                          */\n\n    /* comment : The character id of a 2-byte string is converted to a hexadecimal number by obtaining */\n\n    /*   the corresponding glyph id and width, and then adding padding to the string.                  */\n\n    /***************************************************************************************************/\n\n    var pdfEscape16 = jsPDFAPI.pdfEscape16 = function (text, font) {\n      var widths = font.metadata.Unicode.widths;\n      var padz = [\"\", \"0\", \"00\", \"000\", \"0000\"];\n      var ar = [\"\"];\n\n      for (var i = 0, l = text.length, t; i < l; ++i) {\n        t = font.metadata.characterToGlyph(text.charCodeAt(i));\n        font.metadata.glyIdsUsed.push(t);\n        font.metadata.toUnicode[t] = text.charCodeAt(i);\n\n        if (widths.indexOf(t) == -1) {\n          widths.push(t);\n          widths.push([parseInt(font.metadata.widthOfGlyph(t), 10)]);\n        }\n\n        if (t == \"0\") {\n          //Spaces are not allowed in cmap.\n          return ar.join(\"\");\n        } else {\n          t = t.toString(16);\n          ar.push(padz[4 - t.length], t);\n        }\n      }\n\n      return ar.join(\"\");\n    };\n\n    var toUnicodeCmap = function toUnicodeCmap(map) {\n      var code, codes, range, unicode, unicodeMap, _i, _len;\n\n      unicodeMap = \"/CIDInit /ProcSet findresource begin\\n12 dict begin\\nbegincmap\\n/CIDSystemInfo <<\\n  /Registry (Adobe)\\n  /Ordering (UCS)\\n  /Supplement 0\\n>> def\\n/CMapName /Adobe-Identity-UCS def\\n/CMapType 2 def\\n1 begincodespacerange\\n<0000><ffff>\\nendcodespacerange\";\n      codes = Object.keys(map).sort(function (a, b) {\n        return a - b;\n      });\n      range = [];\n\n      for (_i = 0, _len = codes.length; _i < _len; _i++) {\n        code = codes[_i];\n\n        if (range.length >= 100) {\n          unicodeMap += \"\\n\" + range.length + \" beginbfchar\\n\" + range.join(\"\\n\") + \"\\nendbfchar\";\n          range = [];\n        }\n\n        if (map[code] !== undefined && map[code] !== null && typeof map[code].toString === \"function\") {\n          unicode = (\"0000\" + map[code].toString(16)).slice(-4);\n          code = (\"0000\" + (+code).toString(16)).slice(-4);\n          range.push(\"<\" + code + \"><\" + unicode + \">\");\n        }\n      }\n\n      if (range.length) {\n        unicodeMap += \"\\n\" + range.length + \" beginbfchar\\n\" + range.join(\"\\n\") + \"\\nendbfchar\\n\";\n      }\n\n      unicodeMap += \"endcmap\\nCMapName currentdict /CMap defineresource pop\\nend\\nend\";\n      return unicodeMap;\n    };\n\n    var identityHFunction = function identityHFunction(options) {\n      var font = options.font;\n      var out = options.out;\n      var newObject = options.newObject;\n      var putStream = options.putStream;\n\n      if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === \"Identity-H\") {\n        //Tag with Identity-H\n        var widths = font.metadata.Unicode.widths;\n        var data = font.metadata.subset.encode(font.metadata.glyIdsUsed, 1);\n        var pdfOutput = data;\n        var pdfOutput2 = \"\";\n\n        for (var i = 0; i < pdfOutput.length; i++) {\n          pdfOutput2 += String.fromCharCode(pdfOutput[i]);\n        }\n\n        var fontTable = newObject();\n        putStream({\n          data: pdfOutput2,\n          addLength1: true,\n          objectId: fontTable\n        });\n        out(\"endobj\");\n        var cmap = newObject();\n        var cmapData = toUnicodeCmap(font.metadata.toUnicode);\n        putStream({\n          data: cmapData,\n          addLength1: true,\n          objectId: cmap\n        });\n        out(\"endobj\");\n        var fontDescriptor = newObject();\n        out(\"<<\");\n        out(\"/Type /FontDescriptor\");\n        out(\"/FontName /\" + toPDFName(font.fontName));\n        out(\"/FontFile2 \" + fontTable + \" 0 R\");\n        out(\"/FontBBox \" + jsPDF.API.PDFObject.convert(font.metadata.bbox));\n        out(\"/Flags \" + font.metadata.flags);\n        out(\"/StemV \" + font.metadata.stemV);\n        out(\"/ItalicAngle \" + font.metadata.italicAngle);\n        out(\"/Ascent \" + font.metadata.ascender);\n        out(\"/Descent \" + font.metadata.decender);\n        out(\"/CapHeight \" + font.metadata.capHeight);\n        out(\">>\");\n        out(\"endobj\");\n        var DescendantFont = newObject();\n        out(\"<<\");\n        out(\"/Type /Font\");\n        out(\"/BaseFont /\" + toPDFName(font.fontName));\n        out(\"/FontDescriptor \" + fontDescriptor + \" 0 R\");\n        out(\"/W \" + jsPDF.API.PDFObject.convert(widths));\n        out(\"/CIDToGIDMap /Identity\");\n        out(\"/DW 1000\");\n        out(\"/Subtype /CIDFontType2\");\n        out(\"/CIDSystemInfo\");\n        out(\"<<\");\n        out(\"/Supplement 0\");\n        out(\"/Registry (Adobe)\");\n        out(\"/Ordering (\" + font.encoding + \")\");\n        out(\">>\");\n        out(\">>\");\n        out(\"endobj\");\n        font.objectNumber = newObject();\n        out(\"<<\");\n        out(\"/Type /Font\");\n        out(\"/Subtype /Type0\");\n        out(\"/ToUnicode \" + cmap + \" 0 R\");\n        out(\"/BaseFont /\" + toPDFName(font.fontName));\n        out(\"/Encoding /\" + font.encoding);\n        out(\"/DescendantFonts [\" + DescendantFont + \" 0 R]\");\n        out(\">>\");\n        out(\"endobj\");\n        font.isAlreadyPutted = true;\n      }\n    };\n\n    jsPDFAPI.events.push([\"putFont\", function (args) {\n      identityHFunction(args);\n    }]);\n\n    var winAnsiEncodingFunction = function winAnsiEncodingFunction(options) {\n      var font = options.font;\n      var out = options.out;\n      var newObject = options.newObject;\n      var putStream = options.putStream;\n\n      if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === \"WinAnsiEncoding\") {\n        //Tag with WinAnsi encoding\n        var data = font.metadata.rawData;\n        var pdfOutput = data;\n        var pdfOutput2 = \"\";\n\n        for (var i = 0; i < pdfOutput.length; i++) {\n          pdfOutput2 += String.fromCharCode(pdfOutput[i]);\n        }\n\n        var fontTable = newObject();\n        putStream({\n          data: pdfOutput2,\n          addLength1: true,\n          objectId: fontTable\n        });\n        out(\"endobj\");\n        var cmap = newObject();\n        var cmapData = toUnicodeCmap(font.metadata.toUnicode);\n        putStream({\n          data: cmapData,\n          addLength1: true,\n          objectId: cmap\n        });\n        out(\"endobj\");\n        var fontDescriptor = newObject();\n        out(\"<<\");\n        out(\"/Descent \" + font.metadata.decender);\n        out(\"/CapHeight \" + font.metadata.capHeight);\n        out(\"/StemV \" + font.metadata.stemV);\n        out(\"/Type /FontDescriptor\");\n        out(\"/FontFile2 \" + fontTable + \" 0 R\");\n        out(\"/Flags 96\");\n        out(\"/FontBBox \" + jsPDF.API.PDFObject.convert(font.metadata.bbox));\n        out(\"/FontName /\" + toPDFName(font.fontName));\n        out(\"/ItalicAngle \" + font.metadata.italicAngle);\n        out(\"/Ascent \" + font.metadata.ascender);\n        out(\">>\");\n        out(\"endobj\");\n        font.objectNumber = newObject();\n\n        for (var j = 0; j < font.metadata.hmtx.widths.length; j++) {\n          font.metadata.hmtx.widths[j] = parseInt(font.metadata.hmtx.widths[j] * (1000 / font.metadata.head.unitsPerEm)); //Change the width of Em units to Point units.\n        }\n\n        out(\"<</Subtype/TrueType/Type/Font/ToUnicode \" + cmap + \" 0 R/BaseFont/\" + toPDFName(font.fontName) + \"/FontDescriptor \" + fontDescriptor + \" 0 R\" + \"/Encoding/\" + font.encoding + \" /FirstChar 29 /LastChar 255 /Widths \" + jsPDF.API.PDFObject.convert(font.metadata.hmtx.widths) + \">>\");\n        out(\"endobj\");\n        font.isAlreadyPutted = true;\n      }\n    };\n\n    jsPDFAPI.events.push([\"putFont\", function (args) {\n      winAnsiEncodingFunction(args);\n    }]);\n\n    var utf8TextFunction = function utf8TextFunction(args) {\n      var text = args.text || \"\";\n      var x = args.x;\n      var y = args.y;\n      var options = args.options || {};\n      var mutex = args.mutex || {};\n      var pdfEscape = mutex.pdfEscape;\n      var activeFontKey = mutex.activeFontKey;\n      var fonts = mutex.fonts;\n      var key = activeFontKey;\n      var str = \"\",\n          s = 0,\n          cmapConfirm;\n      var strText = \"\";\n      var encoding = fonts[key].encoding;\n\n      if (fonts[key].encoding !== \"Identity-H\") {\n        return {\n          text: text,\n          x: x,\n          y: y,\n          options: options,\n          mutex: mutex\n        };\n      }\n\n      strText = text;\n      key = activeFontKey;\n\n      if (Array.isArray(text)) {\n        strText = text[0];\n      }\n\n      for (s = 0; s < strText.length; s += 1) {\n        if (fonts[key].metadata.hasOwnProperty(\"cmap\")) {\n          cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)];\n          /*\n               if (Object.prototype.toString.call(text) === '[object Array]') {\n                  var i = 0;\n                 // for (i = 0; i < text.length; i += 1) {\n                      if (Object.prototype.toString.call(text[s]) === '[object Array]') {\n                          cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s][0].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id\n                      } else {\n                       }\n                  //}\n               } else {\n                  cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id\n              }*/\n        }\n\n        if (!cmapConfirm) {\n          if (strText[s].charCodeAt(0) < 256 && fonts[key].metadata.hasOwnProperty(\"Unicode\")) {\n            str += strText[s];\n          } else {\n            str += \"\";\n          }\n        } else {\n          str += strText[s];\n        }\n      }\n\n      var result = \"\";\n\n      if (parseInt(key.slice(1)) < 14 || encoding === \"WinAnsiEncoding\") {\n        //For the default 13 font\n        result = pdfEscape(str, key).split(\"\").map(function (cv) {\n          return cv.charCodeAt(0).toString(16);\n        }).join(\"\");\n      } else if (encoding === \"Identity-H\") {\n        result = pdfEscape16(str, fonts[key]);\n      }\n\n      mutex.isHex = true;\n      return {\n        text: result,\n        x: x,\n        y: y,\n        options: options,\n        mutex: mutex\n      };\n    };\n\n    var utf8EscapeFunction = function utf8EscapeFunction(parms) {\n      var text = parms.text || \"\",\n          x = parms.x,\n          y = parms.y,\n          options = parms.options,\n          mutex = parms.mutex;\n      var tmpText = [];\n      var args = {\n        text: text,\n        x: x,\n        y: y,\n        options: options,\n        mutex: mutex\n      };\n\n      if (Array.isArray(text)) {\n        var i = 0;\n\n        for (i = 0; i < text.length; i += 1) {\n          if (Array.isArray(text[i])) {\n            if (text[i].length === 3) {\n              tmpText.push([utf8TextFunction(Object.assign({}, args, {\n                text: text[i][0]\n              })).text, text[i][1], text[i][2]]);\n            } else {\n              tmpText.push(utf8TextFunction(Object.assign({}, args, {\n                text: text[i]\n              })).text);\n            }\n          } else {\n            tmpText.push(utf8TextFunction(Object.assign({}, args, {\n              text: text[i]\n            })).text);\n          }\n        }\n\n        parms.text = tmpText;\n      } else {\n        parms.text = utf8TextFunction(Object.assign({}, args, {\n          text: text\n        })).text;\n      }\n    };\n\n    jsPDFAPI.events.push([\"postProcessText\", utf8EscapeFunction]);\n  })(jsPDF);\n\n  /**\n   * @license\n   * jsPDF virtual FileSystem functionality\n   *\n   * Licensed under the MIT License.\n   * http://opensource.org/licenses/mit-license\n   */\n  /**\n   * Use the vFS to handle files\n   *\n   * @name vFS\n   * @module\n   */\n\n  (function (jsPDFAPI) {\n\n    var _initializeVFS = function _initializeVFS() {\n      if (typeof this.internal.vFS === \"undefined\") {\n        this.internal.vFS = {};\n      }\n\n      return true;\n    };\n    /**\n     * Check if the file exists in the vFS\n     *\n     * @name existsFileInVFS\n     * @function\n     * @param {string} Possible filename in the vFS.\n     * @returns {boolean}\n     * @example\n     * doc.existsFileInVFS(\"someFile.txt\");\n     */\n\n\n    jsPDFAPI.existsFileInVFS = function (filename) {\n      _initializeVFS.call(this);\n\n      return typeof this.internal.vFS[filename] !== \"undefined\";\n    };\n    /**\n     * Add a file to the vFS\n     *\n     * @name addFileToVFS\n     * @function\n     * @param {string} filename The name of the file which should be added.\n     * @param {string} filecontent The content of the file.\n     * @returns {jsPDF}\n     * @example\n     * doc.addFileToVFS(\"someFile.txt\", \"BADFACE1\");\n     */\n\n\n    jsPDFAPI.addFileToVFS = function (filename, filecontent) {\n      _initializeVFS.call(this);\n\n      this.internal.vFS[filename] = filecontent;\n      return this;\n    };\n    /**\n     * Get the file from the vFS\n     *\n     * @name getFileFromVFS\n     * @function\n     * @param {string} The name of the file which gets requested.\n     * @returns {string}\n     * @example\n     * doc.getFileFromVFS(\"someFile.txt\");\n     */\n\n\n    jsPDFAPI.getFileFromVFS = function (filename) {\n      _initializeVFS.call(this);\n\n      if (typeof this.internal.vFS[filename] !== \"undefined\") {\n        return this.internal.vFS[filename];\n      }\n\n      return null;\n    };\n  })(jsPDF.API);\n\n  /**\n   * @license\n   * Unicode Bidi Engine based on the work of Alex Shensis (@asthensis)\n   * MIT License\n   */\n\n  (function (jsPDF) {\n    /**\n     * Table of Unicode types.\n     *\n     * Generated by:\n     *\n     * var bidi = require(\"./bidi/index\");\n     * var bidi_accumulate = bidi.slice(0, 256).concat(bidi.slice(0x0500, 0x0500 + 256 * 3)).\n     * concat(bidi.slice(0x2000, 0x2000 + 256)).concat(bidi.slice(0xFB00, 0xFB00 + 256)).\n     * concat(bidi.slice(0xFE00, 0xFE00 + 2 * 256));\n     *\n     * for( var i = 0; i < bidi_accumulate.length; i++) {\n     * \tif(bidi_accumulate[i] === undefined || bidi_accumulate[i] === 'ON')\n     * \t\tbidi_accumulate[i] = 'N'; //mark as neutral to conserve space and substitute undefined\n     * }\n     * var bidiAccumulateStr = 'return [ \"' + bidi_accumulate.toString().replace(/,/g, '\", \"') + '\" ];';\n     * require(\"fs\").writeFile('unicode-types.js', bidiAccumulateStr);\n     *\n     * Based on:\n     * https://github.com/mathiasbynens/unicode-8.0.0\n     */\n\n    var bidiUnicodeTypes = [\"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"S\", \"B\", \"S\", \"WS\", \"B\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"B\", \"B\", \"B\", \"S\", \"WS\", \"N\", \"N\", \"ET\", \"ET\", \"ET\", \"N\", \"N\", \"N\", \"N\", \"N\", \"ES\", \"CS\", \"ES\", \"CS\", \"CS\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"CS\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"N\", \"N\", \"N\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"B\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"CS\", \"N\", \"ET\", \"ET\", \"ET\", \"ET\", \"N\", \"N\", \"N\", \"N\", \"L\", \"N\", \"N\", \"BN\", \"N\", \"N\", \"ET\", \"ET\", \"EN\", \"EN\", \"N\", \"L\", \"N\", \"N\", \"N\", \"EN\", \"L\", \"N\", \"N\", \"N\", \"N\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"L\", \"N\", \"N\", \"N\", \"N\", \"N\", \"ET\", \"N\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"R\", \"NSM\", \"R\", \"NSM\", \"NSM\", \"R\", \"NSM\", \"NSM\", \"R\", \"NSM\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"N\", \"N\", \"N\", \"N\", \"N\", \"R\", \"R\", \"R\", \"R\", \"R\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"N\", \"N\", \"AL\", \"ET\", \"ET\", \"AL\", \"CS\", \"AL\", \"N\", \"N\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"AL\", \"AL\", \"N\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"AN\", \"ET\", \"AN\", \"AN\", \"AL\", \"AL\", \"AL\", \"NSM\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"AN\", \"N\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"AL\", \"AL\", \"NSM\", \"NSM\", \"N\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"AL\", \"AL\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"N\", \"AL\", \"AL\", \"NSM\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"N\", \"N\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"AL\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"R\", \"R\", \"N\", \"N\", \"N\", \"N\", \"R\", \"N\", \"N\", \"N\", \"N\", \"N\", \"WS\", \"WS\", \"WS\", \"WS\", \"WS\", \"WS\", \"WS\", \"WS\", \"WS\", \"WS\", \"WS\", \"BN\", \"BN\", \"BN\", \"L\", \"R\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"WS\", \"B\", \"LRE\", \"RLE\", \"PDF\", \"LRO\", \"RLO\", \"CS\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"CS\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"WS\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"N\", \"LRI\", \"RLI\", \"FSI\", \"PDI\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"BN\", \"EN\", \"L\", \"N\", \"N\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"ES\", \"ES\", \"N\", \"N\", \"N\", \"L\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"ES\", \"ES\", \"N\", \"N\", \"N\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"N\", \"N\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"ET\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"N\", \"N\", \"N\", \"N\", \"R\", \"NSM\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"ES\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"N\", \"R\", \"R\", \"R\", \"R\", \"R\", \"N\", \"R\", \"N\", \"R\", \"R\", \"N\", \"R\", \"R\", \"N\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"R\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"NSM\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"CS\", \"N\", \"CS\", \"N\", \"N\", \"CS\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"ET\", \"N\", \"N\", \"ES\", \"ES\", \"N\", \"N\", \"N\", \"N\", \"N\", \"ET\", \"ET\", \"N\", \"N\", \"N\", \"N\", \"N\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"N\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"AL\", \"N\", \"N\", \"BN\", \"N\", \"N\", \"N\", \"ET\", \"ET\", \"ET\", \"N\", \"N\", \"N\", \"N\", \"N\", \"ES\", \"CS\", \"ES\", \"CS\", \"CS\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"EN\", \"CS\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"N\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"N\", \"L\", \"L\", \"L\", \"L\", \"L\", \"L\", \"N\", \"N\", \"L\", \"L\", \"L\", \"N\", \"N\", \"N\", \"ET\", \"ET\", \"N\", \"N\", \"N\", \"ET\", \"ET\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\", \"N\"];\n    /**\n     * Unicode Bidi algorithm compliant Bidi engine.\n     * For reference see http://unicode.org/reports/tr9/\n     */\n\n    /**\n     * constructor ( options )\n     *\n     * Initializes Bidi engine\n     *\n     * @param {Object} See 'setOptions' below for detailed description.\n     * options are cashed between invocation of 'doBidiReorder' method\n     *\n     * sample usage pattern of BidiEngine:\n     * var opt = {\n     * \tisInputVisual: true,\n     * \tisInputRtl: false,\n     * \tisOutputVisual: false,\n     * \tisOutputRtl: false,\n     * \tisSymmetricSwapping: true\n     * }\n     * var sourceToTarget = [], levels = [];\n     * var bidiEng = Globalize.bidiEngine(opt);\n     * var src = \"text string to be reordered\";\n     * var ret = bidiEng.doBidiReorder(src, sourceToTarget, levels);\n     */\n\n    jsPDF.__bidiEngine__ = jsPDF.prototype.__bidiEngine__ = function (options) {\n      var _UNICODE_TYPES = _bidiUnicodeTypes;\n      var _STATE_TABLE_LTR = [[0, 3, 0, 1, 0, 0, 0], [0, 3, 0, 1, 2, 2, 0], [0, 3, 0, 0x11, 2, 0, 1], [0, 3, 5, 5, 4, 1, 0], [0, 3, 0x15, 0x15, 4, 0, 1], [0, 3, 5, 5, 4, 2, 0]];\n      var _STATE_TABLE_RTL = [[2, 0, 1, 1, 0, 1, 0], [2, 0, 1, 1, 0, 2, 0], [2, 0, 2, 1, 3, 2, 0], [2, 0, 2, 0x21, 3, 1, 1]];\n      var _TYPE_NAMES_MAP = {\n        L: 0,\n        R: 1,\n        EN: 2,\n        AN: 3,\n        N: 4,\n        B: 5,\n        S: 6\n      };\n      var _UNICODE_RANGES_MAP = {\n        0: 0,\n        5: 1,\n        6: 2,\n        7: 3,\n        0x20: 4,\n        0xfb: 5,\n        0xfe: 6,\n        0xff: 7\n      };\n      var _SWAP_TABLE = [\"(\", \")\", \"(\", \"<\", \">\", \"<\", \"[\", \"]\", \"[\", \"{\", \"}\", \"{\", \"\\xAB\", \"\\xBB\", \"\\xAB\", \"\\u2039\", \"\\u203A\", \"\\u2039\", \"\\u2045\", \"\\u2046\", \"\\u2045\", \"\\u207D\", \"\\u207E\", \"\\u207D\", \"\\u208D\", \"\\u208E\", \"\\u208D\", \"\\u2264\", \"\\u2265\", \"\\u2264\", \"\\u2329\", \"\\u232A\", \"\\u2329\", \"\\uFE59\", \"\\uFE5A\", \"\\uFE59\", \"\\uFE5B\", \"\\uFE5C\", \"\\uFE5B\", \"\\uFE5D\", \"\\uFE5E\", \"\\uFE5D\", \"\\uFE64\", \"\\uFE65\", \"\\uFE64\"];\n\n      var _LTR_RANGES_REG_EXPR = new RegExp(/^([1-4|9]|1[0-9]|2[0-9]|3[0168]|4[04589]|5[012]|7[78]|159|16[0-9]|17[0-2]|21[569]|22[03489]|250)$/);\n\n      var _lastArabic = false,\n          _hasUbatB,\n          _hasUbatS,\n          DIR_LTR = 0,\n          DIR_RTL = 1,\n          _isInVisual,\n          _isInRtl,\n          _isOutVisual,\n          _isOutRtl,\n          _isSymmetricSwapping,\n          _dir = DIR_LTR;\n\n      this.__bidiEngine__ = {};\n\n      var _init = function _init(text, sourceToTargetMap) {\n        if (sourceToTargetMap) {\n          for (var i = 0; i < text.length; i++) {\n            sourceToTargetMap[i] = i;\n          }\n        }\n\n        if (_isInRtl === undefined) {\n          _isInRtl = _isContextualDirRtl(text);\n        }\n\n        if (_isOutRtl === undefined) {\n          _isOutRtl = _isContextualDirRtl(text);\n        }\n      }; // for reference see 3.2 in http://unicode.org/reports/tr9/\n      //\n\n\n      var _getCharType = function _getCharType(ch) {\n        var charCode = ch.charCodeAt(),\n            range = charCode >> 8,\n            rangeIdx = _UNICODE_RANGES_MAP[range];\n\n        if (rangeIdx !== undefined) {\n          return _UNICODE_TYPES[rangeIdx * 256 + (charCode & 0xff)];\n        } else if (range === 0xfc || range === 0xfd) {\n          return \"AL\";\n        } else if (_LTR_RANGES_REG_EXPR.test(range)) {\n          //unlikely case\n          return \"L\";\n        } else if (range === 8) {\n          // even less likely\n          return \"R\";\n        }\n\n        return \"N\"; //undefined type, mark as neutral\n      };\n\n      var _isContextualDirRtl = function _isContextualDirRtl(text) {\n        for (var i = 0, charType; i < text.length; i++) {\n          charType = _getCharType(text.charAt(i));\n\n          if (charType === \"L\") {\n            return false;\n          } else if (charType === \"R\") {\n            return true;\n          }\n        }\n\n        return false;\n      }; // for reference see 3.3.4 & 3.3.5 in http://unicode.org/reports/tr9/\n      //\n\n\n      var _resolveCharType = function _resolveCharType(chars, types, resolvedTypes, index) {\n        var cType = types[index],\n            wType,\n            nType,\n            i,\n            len;\n\n        switch (cType) {\n          case \"L\":\n          case \"R\":\n            _lastArabic = false;\n            break;\n\n          case \"N\":\n          case \"AN\":\n            break;\n\n          case \"EN\":\n            if (_lastArabic) {\n              cType = \"AN\";\n            }\n\n            break;\n\n          case \"AL\":\n            _lastArabic = true;\n            cType = \"R\";\n            break;\n\n          case \"WS\":\n            cType = \"N\";\n            break;\n\n          case \"CS\":\n            if (index < 1 || index + 1 >= types.length || (wType = resolvedTypes[index - 1]) !== \"EN\" && wType !== \"AN\" || (nType = types[index + 1]) !== \"EN\" && nType !== \"AN\") {\n              cType = \"N\";\n            } else if (_lastArabic) {\n              nType = \"AN\";\n            }\n\n            cType = nType === wType ? nType : \"N\";\n            break;\n\n          case \"ES\":\n            wType = index > 0 ? resolvedTypes[index - 1] : \"B\";\n            cType = wType === \"EN\" && index + 1 < types.length && types[index + 1] === \"EN\" ? \"EN\" : \"N\";\n            break;\n\n          case \"ET\":\n            if (index > 0 && resolvedTypes[index - 1] === \"EN\") {\n              cType = \"EN\";\n              break;\n            } else if (_lastArabic) {\n              cType = \"N\";\n              break;\n            }\n\n            i = index + 1;\n            len = types.length;\n\n            while (i < len && types[i] === \"ET\") {\n              i++;\n            }\n\n            if (i < len && types[i] === \"EN\") {\n              cType = \"EN\";\n            } else {\n              cType = \"N\";\n            }\n\n            break;\n\n          case \"NSM\":\n            if (_isInVisual && !_isInRtl) {\n              //V->L\n              len = types.length;\n              i = index + 1;\n\n              while (i < len && types[i] === \"NSM\") {\n                i++;\n              }\n\n              if (i < len) {\n                var c = chars[index];\n                var rtlCandidate = c >= 0x0591 && c <= 0x08ff || c === 0xfb1e;\n                wType = types[i];\n\n                if (rtlCandidate && (wType === \"R\" || wType === \"AL\")) {\n                  cType = \"R\";\n                  break;\n                }\n              }\n            }\n\n            if (index < 1 || (wType = types[index - 1]) === \"B\") {\n              cType = \"N\";\n            } else {\n              cType = resolvedTypes[index - 1];\n            }\n\n            break;\n\n          case \"B\":\n            _lastArabic = false;\n            _hasUbatB = true;\n            cType = _dir;\n            break;\n\n          case \"S\":\n            _hasUbatS = true;\n            cType = \"N\";\n            break;\n\n          case \"LRE\":\n          case \"RLE\":\n          case \"LRO\":\n          case \"RLO\":\n          case \"PDF\":\n            _lastArabic = false;\n            break;\n\n          case \"BN\":\n            cType = \"N\";\n            break;\n        }\n\n        return cType;\n      };\n\n      var _handleUbatS = function _handleUbatS(types, levels, length) {\n        for (var i = 0; i < length; i++) {\n          if (types[i] === \"S\") {\n            levels[i] = _dir;\n\n            for (var j = i - 1; j >= 0; j--) {\n              if (types[j] === \"WS\") {\n                levels[j] = _dir;\n              } else {\n                break;\n              }\n            }\n          }\n        }\n      };\n\n      var _invertString = function _invertString(text, sourceToTargetMap, levels) {\n        var charArray = text.split(\"\");\n\n        if (levels) {\n          _computeLevels(charArray, levels, {\n            hiLevel: _dir\n          });\n        }\n\n        charArray.reverse();\n        sourceToTargetMap && sourceToTargetMap.reverse();\n        return charArray.join(\"\");\n      }; // For reference see 3.3 in http://unicode.org/reports/tr9/\n      //\n\n\n      var _computeLevels = function _computeLevels(chars, levels, params) {\n        var action,\n            condition,\n            i,\n            index,\n            newLevel,\n            prevState,\n            condPos = -1,\n            len = chars.length,\n            newState = 0,\n            resolvedTypes = [],\n            stateTable = _dir ? _STATE_TABLE_RTL : _STATE_TABLE_LTR,\n            types = [];\n        _lastArabic = false;\n        _hasUbatB = false;\n        _hasUbatS = false;\n\n        for (i = 0; i < len; i++) {\n          types[i] = _getCharType(chars[i]);\n        }\n\n        for (index = 0; index < len; index++) {\n          prevState = newState;\n          resolvedTypes[index] = _resolveCharType(chars, types, resolvedTypes, index);\n          newState = stateTable[prevState][_TYPE_NAMES_MAP[resolvedTypes[index]]];\n          action = newState & 0xf0;\n          newState &= 0x0f;\n          levels[index] = newLevel = stateTable[newState][5];\n\n          if (action > 0) {\n            if (action === 0x10) {\n              for (i = condPos; i < index; i++) {\n                levels[i] = 1;\n              }\n\n              condPos = -1;\n            } else {\n              condPos = -1;\n            }\n          }\n\n          condition = stateTable[newState][6];\n\n          if (condition) {\n            if (condPos === -1) {\n              condPos = index;\n            }\n          } else {\n            if (condPos > -1) {\n              for (i = condPos; i < index; i++) {\n                levels[i] = newLevel;\n              }\n\n              condPos = -1;\n            }\n          }\n\n          if (types[index] === \"B\") {\n            levels[index] = 0;\n          }\n\n          params.hiLevel |= newLevel;\n        }\n\n        if (_hasUbatS) {\n          _handleUbatS(types, levels, len);\n        }\n      }; // for reference see 3.4 in http://unicode.org/reports/tr9/\n      //\n\n\n      var _invertByLevel = function _invertByLevel(level, charArray, sourceToTargetMap, levels, params) {\n        if (params.hiLevel < level) {\n          return;\n        }\n\n        if (level === 1 && _dir === DIR_RTL && !_hasUbatB) {\n          charArray.reverse();\n          sourceToTargetMap && sourceToTargetMap.reverse();\n          return;\n        }\n\n        var ch,\n            high,\n            end,\n            low,\n            len = charArray.length,\n            start = 0;\n\n        while (start < len) {\n          if (levels[start] >= level) {\n            end = start + 1;\n\n            while (end < len && levels[end] >= level) {\n              end++;\n            }\n\n            for (low = start, high = end - 1; low < high; low++, high--) {\n              ch = charArray[low];\n              charArray[low] = charArray[high];\n              charArray[high] = ch;\n\n              if (sourceToTargetMap) {\n                ch = sourceToTargetMap[low];\n                sourceToTargetMap[low] = sourceToTargetMap[high];\n                sourceToTargetMap[high] = ch;\n              }\n            }\n\n            start = end;\n          }\n\n          start++;\n        }\n      }; // for reference see 7 & BD16 in http://unicode.org/reports/tr9/\n      //\n\n\n      var _symmetricSwap = function _symmetricSwap(charArray, levels, params) {\n        if (params.hiLevel !== 0 && _isSymmetricSwapping) {\n          for (var i = 0, index; i < charArray.length; i++) {\n            if (levels[i] === 1) {\n              index = _SWAP_TABLE.indexOf(charArray[i]);\n\n              if (index >= 0) {\n                charArray[i] = _SWAP_TABLE[index + 1];\n              }\n            }\n          }\n        }\n      };\n\n      var _reorder = function _reorder(text, sourceToTargetMap, levels) {\n        var charArray = text.split(\"\"),\n            params = {\n          hiLevel: _dir\n        };\n\n        if (!levels) {\n          levels = [];\n        }\n\n        _computeLevels(charArray, levels, params);\n\n        _symmetricSwap(charArray, levels, params);\n\n        _invertByLevel(DIR_RTL + 1, charArray, sourceToTargetMap, levels, params);\n\n        _invertByLevel(DIR_RTL, charArray, sourceToTargetMap, levels, params);\n\n        return charArray.join(\"\");\n      }; // doBidiReorder( text, sourceToTargetMap, levels )\n      // Performs Bidi reordering by implementing Unicode Bidi algorithm.\n      // Returns reordered string\n      // @text [String]:\n      // - input string to be reordered, this is input parameter\n      // $sourceToTargetMap [Array] (optional)\n      // - resultant mapping between input and output strings, this is output parameter\n      // $levels [Array] (optional)\n      // - array of calculated Bidi levels, , this is output parameter\n\n\n      this.__bidiEngine__.doBidiReorder = function (text, sourceToTargetMap, levels) {\n        _init(text, sourceToTargetMap);\n\n        if (!_isInVisual && _isOutVisual && !_isOutRtl) {\n          // LLTR->VLTR, LRTL->VLTR\n          _dir = _isInRtl ? DIR_RTL : DIR_LTR;\n          text = _reorder(text, sourceToTargetMap, levels);\n        } else if (_isInVisual && _isOutVisual && _isInRtl ^ _isOutRtl) {\n          // VRTL->VLTR, VLTR->VRTL\n          _dir = _isInRtl ? DIR_RTL : DIR_LTR;\n          text = _invertString(text, sourceToTargetMap, levels);\n        } else if (!_isInVisual && _isOutVisual && _isOutRtl) {\n          // LLTR->VRTL, LRTL->VRTL\n          _dir = _isInRtl ? DIR_RTL : DIR_LTR;\n          text = _reorder(text, sourceToTargetMap, levels);\n          text = _invertString(text, sourceToTargetMap);\n        } else if (_isInVisual && !_isInRtl && !_isOutVisual && !_isOutRtl) {\n          // VLTR->LLTR\n          _dir = DIR_LTR;\n          text = _reorder(text, sourceToTargetMap, levels);\n        } else if (_isInVisual && !_isOutVisual && _isInRtl ^ _isOutRtl) {\n          // VLTR->LRTL, VRTL->LLTR\n          text = _invertString(text, sourceToTargetMap);\n\n          if (_isInRtl) {\n            //LLTR -> VLTR\n            _dir = DIR_LTR;\n            text = _reorder(text, sourceToTargetMap, levels);\n          } else {\n            //LRTL -> VRTL\n            _dir = DIR_RTL;\n            text = _reorder(text, sourceToTargetMap, levels);\n            text = _invertString(text, sourceToTargetMap);\n          }\n        } else if (_isInVisual && _isInRtl && !_isOutVisual && _isOutRtl) {\n          //  VRTL->LRTL\n          _dir = DIR_RTL;\n          text = _reorder(text, sourceToTargetMap, levels);\n          text = _invertString(text, sourceToTargetMap);\n        } else if (!_isInVisual && !_isOutVisual && _isInRtl ^ _isOutRtl) {\n          // LRTL->LLTR, LLTR->LRTL\n          var isSymmetricSwappingOrig = _isSymmetricSwapping;\n\n          if (_isInRtl) {\n            //LRTL->LLTR\n            _dir = DIR_RTL;\n            text = _reorder(text, sourceToTargetMap, levels);\n            _dir = DIR_LTR;\n            _isSymmetricSwapping = false;\n            text = _reorder(text, sourceToTargetMap, levels);\n            _isSymmetricSwapping = isSymmetricSwappingOrig;\n          } else {\n            //LLTR->LRTL\n            _dir = DIR_LTR;\n            text = _reorder(text, sourceToTargetMap, levels);\n            text = _invertString(text, sourceToTargetMap);\n            _dir = DIR_RTL;\n            _isSymmetricSwapping = false;\n            text = _reorder(text, sourceToTargetMap, levels);\n            _isSymmetricSwapping = isSymmetricSwappingOrig;\n            text = _invertString(text, sourceToTargetMap);\n          }\n        }\n\n        return text;\n      };\n      /**\n       * @name setOptions( options )\n       * @function\n       * Sets options for Bidi conversion\n       * @param {Object}:\n       * - isInputVisual {boolean} (defaults to false): allowed values: true(Visual mode), false(Logical mode)\n       * - isInputRtl {boolean}: allowed values true(Right-to-left direction), false (Left-to-right directiion), undefined(Contectual direction, i.e.direction defined by first strong character of input string)\n       * - isOutputVisual {boolean} (defaults to false): allowed values: true(Visual mode), false(Logical mode)\n       * - isOutputRtl {boolean}: allowed values true(Right-to-left direction), false (Left-to-right directiion), undefined(Contectual direction, i.e.direction defined by first strong characterof input string)\n       * - isSymmetricSwapping {boolean} (defaults to false): allowed values true(needs symmetric swapping), false (no need in symmetric swapping),\n       */\n\n\n      this.__bidiEngine__.setOptions = function (options) {\n        if (options) {\n          _isInVisual = options.isInputVisual;\n          _isOutVisual = options.isOutputVisual;\n          _isInRtl = options.isInputRtl;\n          _isOutRtl = options.isOutputRtl;\n          _isSymmetricSwapping = options.isSymmetricSwapping;\n        }\n      };\n\n      this.__bidiEngine__.setOptions(options);\n\n      return this.__bidiEngine__;\n    };\n\n    var _bidiUnicodeTypes = bidiUnicodeTypes;\n    var bidiEngine = new jsPDF.__bidiEngine__({\n      isInputVisual: true\n    });\n\n    var bidiEngineFunction = function bidiEngineFunction(args) {\n      var text = args.text;\n      var x = args.x;\n      var y = args.y;\n      var options = args.options || {};\n      var mutex = args.mutex || {};\n      var lang = options.lang;\n      var tmpText = [];\n      options.isInputVisual = typeof options.isInputVisual === \"boolean\" ? options.isInputVisual : true;\n      bidiEngine.setOptions(options);\n\n      if (Object.prototype.toString.call(text) === \"[object Array]\") {\n        var i = 0;\n        tmpText = [];\n\n        for (i = 0; i < text.length; i += 1) {\n          if (Object.prototype.toString.call(text[i]) === \"[object Array]\") {\n            tmpText.push([bidiEngine.doBidiReorder(text[i][0]), text[i][1], text[i][2]]);\n          } else {\n            tmpText.push([bidiEngine.doBidiReorder(text[i])]);\n          }\n        }\n\n        args.text = tmpText;\n      } else {\n        args.text = bidiEngine.doBidiReorder(text);\n      }\n\n      bidiEngine.setOptions({\n        isInputVisual: true\n      });\n    };\n\n    jsPDF.API.events.push([\"postProcessText\", bidiEngineFunction]);\n  })(jsPDF);\n\n  /* eslint-disable no-control-regex */\n\n  jsPDF.API.TTFFont = function () {\n    /************************************************************************/\n\n    /* function : open                                                       */\n\n    /* comment : Decode the encoded ttf content and create a TTFFont object. */\n\n    /************************************************************************/\n    TTFFont.open = function (file) {\n      return new TTFFont(file);\n    };\n    /***************************************************************/\n\n    /* function : TTFFont gernerator                               */\n\n    /* comment : Decode TTF contents are parsed, Data,             */\n\n    /* Subset object is created, and registerTTF function is called.*/\n\n    /***************************************************************/\n\n\n    function TTFFont(rawData) {\n      var data;\n      this.rawData = rawData;\n      data = this.contents = new Data(rawData);\n      this.contents.pos = 4;\n\n      if (data.readString(4) === \"ttcf\") {\n        throw new Error(\"TTCF not supported.\");\n      } else {\n        data.pos = 0;\n        this.parse();\n        this.subset = new Subset(this);\n        this.registerTTF();\n      }\n    }\n    /********************************************************/\n\n    /* function : parse                                     */\n\n    /* comment : TTF Parses the file contents by each table.*/\n\n    /********************************************************/\n\n\n    TTFFont.prototype.parse = function () {\n      this.directory = new Directory(this.contents);\n      this.head = new HeadTable(this);\n      this.name = new NameTable(this);\n      this.cmap = new CmapTable(this);\n      this.toUnicode = {};\n      this.hhea = new HheaTable(this);\n      this.maxp = new MaxpTable(this);\n      this.hmtx = new HmtxTable(this);\n      this.post = new PostTable(this);\n      this.os2 = new OS2Table(this);\n      this.loca = new LocaTable(this);\n      this.glyf = new GlyfTable(this);\n      this.ascender = this.os2.exists && this.os2.ascender || this.hhea.ascender;\n      this.decender = this.os2.exists && this.os2.decender || this.hhea.decender;\n      this.lineGap = this.os2.exists && this.os2.lineGap || this.hhea.lineGap;\n      return this.bbox = [this.head.xMin, this.head.yMin, this.head.xMax, this.head.yMax];\n    };\n    /***************************************************************/\n\n    /* function : registerTTF                                      */\n\n    /* comment : Get the value to assign pdf font descriptors.     */\n\n    /***************************************************************/\n\n\n    TTFFont.prototype.registerTTF = function () {\n      var e, hi, low, raw, _ref;\n\n      this.scaleFactor = 1000.0 / this.head.unitsPerEm;\n\n      this.bbox = function () {\n        var _i, _len, _ref, _results;\n\n        _ref = this.bbox;\n        _results = [];\n\n        for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n          e = _ref[_i];\n\n          _results.push(Math.round(e * this.scaleFactor));\n        }\n\n        return _results;\n      }.call(this);\n\n      this.stemV = 0;\n\n      if (this.post.exists) {\n        raw = this.post.italic_angle;\n        hi = raw >> 16;\n        low = raw & 0xff;\n\n        if ((hi & 0x8000) !== 0) {\n          hi = -((hi ^ 0xffff) + 1);\n        }\n\n        this.italicAngle = +(\"\" + hi + \".\" + low);\n      } else {\n        this.italicAngle = 0;\n      }\n\n      this.ascender = Math.round(this.ascender * this.scaleFactor);\n      this.decender = Math.round(this.decender * this.scaleFactor);\n      this.lineGap = Math.round(this.lineGap * this.scaleFactor);\n      this.capHeight = this.os2.exists && this.os2.capHeight || this.ascender;\n      this.xHeight = this.os2.exists && this.os2.xHeight || 0;\n      this.familyClass = (this.os2.exists && this.os2.familyClass || 0) >> 8;\n      this.isSerif = (_ref = this.familyClass) === 1 || _ref === 2 || _ref === 3 || _ref === 4 || _ref === 5 || _ref === 7;\n      this.isScript = this.familyClass === 10;\n      this.flags = 0;\n\n      if (this.post.isFixedPitch) {\n        this.flags |= 1 << 0;\n      }\n\n      if (this.isSerif) {\n        this.flags |= 1 << 1;\n      }\n\n      if (this.isScript) {\n        this.flags |= 1 << 3;\n      }\n\n      if (this.italicAngle !== 0) {\n        this.flags |= 1 << 6;\n      }\n\n      this.flags |= 1 << 5;\n\n      if (!this.cmap.unicode) {\n        throw new Error(\"No unicode cmap for font\");\n      }\n    };\n\n    TTFFont.prototype.characterToGlyph = function (character) {\n      var _ref;\n\n      return ((_ref = this.cmap.unicode) != null ? _ref.codeMap[character] : void 0) || 0;\n    };\n\n    TTFFont.prototype.widthOfGlyph = function (glyph) {\n      var scale;\n      scale = 1000.0 / this.head.unitsPerEm;\n      return this.hmtx.forGlyph(glyph).advance * scale;\n    };\n\n    TTFFont.prototype.widthOfString = function (string, size, charSpace) {\n      var charCode, i, scale, width, _ref;\n\n      string = \"\" + string;\n      width = 0;\n\n      for (i = 0, _ref = string.length; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) {\n        charCode = string.charCodeAt(i);\n        width += this.widthOfGlyph(this.characterToGlyph(charCode)) + charSpace * (1000 / size) || 0;\n      }\n\n      scale = size / 1000;\n      return width * scale;\n    };\n\n    TTFFont.prototype.lineHeight = function (size, includeGap) {\n      var gap;\n\n      if (includeGap == null) {\n        includeGap = false;\n      }\n\n      gap = includeGap ? this.lineGap : 0;\n      return (this.ascender + gap - this.decender) / 1000 * size;\n    };\n\n    return TTFFont;\n  }();\n  /************************************************************************************************/\n\n  /* function : Data                                                                              */\n\n  /* comment : The ttf data decoded and stored in an array is read and written to the Data object.*/\n\n  /************************************************************************************************/\n\n\n  var Data = function () {\n    function Data(data) {\n      this.data = data != null ? data : [];\n      this.pos = 0;\n      this.length = this.data.length;\n    }\n\n    Data.prototype.readByte = function () {\n      return this.data[this.pos++];\n    };\n\n    Data.prototype.writeByte = function (byte) {\n      return this.data[this.pos++] = byte;\n    };\n\n    Data.prototype.readUInt32 = function () {\n      var b1, b2, b3, b4;\n      b1 = this.readByte() * 0x1000000;\n      b2 = this.readByte() << 16;\n      b3 = this.readByte() << 8;\n      b4 = this.readByte();\n      return b1 + b2 + b3 + b4;\n    };\n\n    Data.prototype.writeUInt32 = function (val) {\n      this.writeByte(val >>> 24 & 0xff);\n      this.writeByte(val >> 16 & 0xff);\n      this.writeByte(val >> 8 & 0xff);\n      return this.writeByte(val & 0xff);\n    };\n\n    Data.prototype.readInt32 = function () {\n      var int;\n      int = this.readUInt32();\n\n      if (int >= 0x80000000) {\n        return int - 0x100000000;\n      } else {\n        return int;\n      }\n    };\n\n    Data.prototype.writeInt32 = function (val) {\n      if (val < 0) {\n        val += 0x100000000;\n      }\n\n      return this.writeUInt32(val);\n    };\n\n    Data.prototype.readUInt16 = function () {\n      var b1, b2;\n      b1 = this.readByte() << 8;\n      b2 = this.readByte();\n      return b1 | b2;\n    };\n\n    Data.prototype.writeUInt16 = function (val) {\n      this.writeByte(val >> 8 & 0xff);\n      return this.writeByte(val & 0xff);\n    };\n\n    Data.prototype.readInt16 = function () {\n      var int;\n      int = this.readUInt16();\n\n      if (int >= 0x8000) {\n        return int - 0x10000;\n      } else {\n        return int;\n      }\n    };\n\n    Data.prototype.writeInt16 = function (val) {\n      if (val < 0) {\n        val += 0x10000;\n      }\n\n      return this.writeUInt16(val);\n    };\n\n    Data.prototype.readString = function (length) {\n      var i, ret;\n      ret = [];\n\n      for (i = 0; 0 <= length ? i < length : i > length; i = 0 <= length ? ++i : --i) {\n        ret[i] = String.fromCharCode(this.readByte());\n      }\n\n      return ret.join(\"\");\n    };\n\n    Data.prototype.writeString = function (val) {\n      var i, _ref, _results;\n\n      _results = [];\n\n      for (i = 0, _ref = val.length; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) {\n        _results.push(this.writeByte(val.charCodeAt(i)));\n      }\n\n      return _results;\n    };\n    /*Data.prototype.stringAt = function (pos, length) {\n              this.pos = pos;\n              return this.readString(length);\n          };*/\n\n\n    Data.prototype.readShort = function () {\n      return this.readInt16();\n    };\n\n    Data.prototype.writeShort = function (val) {\n      return this.writeInt16(val);\n    };\n\n    Data.prototype.readLongLong = function () {\n      var b1, b2, b3, b4, b5, b6, b7, b8;\n      b1 = this.readByte();\n      b2 = this.readByte();\n      b3 = this.readByte();\n      b4 = this.readByte();\n      b5 = this.readByte();\n      b6 = this.readByte();\n      b7 = this.readByte();\n      b8 = this.readByte();\n\n      if (b1 & 0x80) {\n        return ((b1 ^ 0xff) * 0x100000000000000 + (b2 ^ 0xff) * 0x1000000000000 + (b3 ^ 0xff) * 0x10000000000 + (b4 ^ 0xff) * 0x100000000 + (b5 ^ 0xff) * 0x1000000 + (b6 ^ 0xff) * 0x10000 + (b7 ^ 0xff) * 0x100 + (b8 ^ 0xff) + 1) * -1;\n      }\n\n      return b1 * 0x100000000000000 + b2 * 0x1000000000000 + b3 * 0x10000000000 + b4 * 0x100000000 + b5 * 0x1000000 + b6 * 0x10000 + b7 * 0x100 + b8;\n    };\n\n    Data.prototype.writeLongLong = function (val) {\n      var high, low;\n      high = Math.floor(val / 0x100000000);\n      low = val & 0xffffffff;\n      this.writeByte(high >> 24 & 0xff);\n      this.writeByte(high >> 16 & 0xff);\n      this.writeByte(high >> 8 & 0xff);\n      this.writeByte(high & 0xff);\n      this.writeByte(low >> 24 & 0xff);\n      this.writeByte(low >> 16 & 0xff);\n      this.writeByte(low >> 8 & 0xff);\n      return this.writeByte(low & 0xff);\n    };\n\n    Data.prototype.readInt = function () {\n      return this.readInt32();\n    };\n\n    Data.prototype.writeInt = function (val) {\n      return this.writeInt32(val);\n    };\n    /*Data.prototype.slice = function (start, end) {\n              return this.data.slice(start, end);\n          };*/\n\n\n    Data.prototype.read = function (bytes) {\n      var buf, i;\n      buf = [];\n\n      for (i = 0; 0 <= bytes ? i < bytes : i > bytes; i = 0 <= bytes ? ++i : --i) {\n        buf.push(this.readByte());\n      }\n\n      return buf;\n    };\n\n    Data.prototype.write = function (bytes) {\n      var byte, i, _len, _results;\n\n      _results = [];\n\n      for (i = 0, _len = bytes.length; i < _len; i++) {\n        byte = bytes[i];\n\n        _results.push(this.writeByte(byte));\n      }\n\n      return _results;\n    };\n\n    return Data;\n  }();\n\n  var Directory = function () {\n    var checksum;\n    /*****************************************************************************************************/\n\n    /* function : Directory generator                                                                    */\n\n    /* comment : Initialize the offset, tag, length, and checksum for each table for the font to be used.*/\n\n    /*****************************************************************************************************/\n\n    function Directory(data) {\n      var entry, i, _ref;\n\n      this.scalarType = data.readInt();\n      this.tableCount = data.readShort();\n      this.searchRange = data.readShort();\n      this.entrySelector = data.readShort();\n      this.rangeShift = data.readShort();\n      this.tables = {};\n\n      for (i = 0, _ref = this.tableCount; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) {\n        entry = {\n          tag: data.readString(4),\n          checksum: data.readInt(),\n          offset: data.readInt(),\n          length: data.readInt()\n        };\n        this.tables[entry.tag] = entry;\n      }\n    }\n    /********************************************************************************************************/\n\n    /* function : encode                                                                                    */\n\n    /* comment : It encodes and stores the font table object and information used for the directory object. */\n\n    /********************************************************************************************************/\n\n\n    Directory.prototype.encode = function (tables) {\n      var adjustment, directory, directoryLength, entrySelector, headOffset, log2, offset, rangeShift, searchRange, sum, table, tableCount, tableData, tag;\n      tableCount = Object.keys(tables).length;\n      log2 = Math.log(2);\n      searchRange = Math.floor(Math.log(tableCount) / log2) * 16;\n      entrySelector = Math.floor(searchRange / log2);\n      rangeShift = tableCount * 16 - searchRange;\n      directory = new Data();\n      directory.writeInt(this.scalarType);\n      directory.writeShort(tableCount);\n      directory.writeShort(searchRange);\n      directory.writeShort(entrySelector);\n      directory.writeShort(rangeShift);\n      directoryLength = tableCount * 16;\n      offset = directory.pos + directoryLength;\n      headOffset = null;\n      tableData = [];\n\n      for (tag in tables) {\n        table = tables[tag];\n        directory.writeString(tag);\n        directory.writeInt(checksum(table));\n        directory.writeInt(offset);\n        directory.writeInt(table.length);\n        tableData = tableData.concat(table);\n\n        if (tag === \"head\") {\n          headOffset = offset;\n        }\n\n        offset += table.length;\n\n        while (offset % 4) {\n          tableData.push(0);\n          offset++;\n        }\n      }\n\n      directory.write(tableData);\n      sum = checksum(directory.data);\n      adjustment = 0xb1b0afba - sum;\n      directory.pos = headOffset + 8;\n      directory.writeUInt32(adjustment);\n      return directory.data;\n    };\n    /***************************************************************/\n\n    /* function : checksum                                         */\n\n    /* comment : Duplicate the table for the tag.                  */\n\n    /***************************************************************/\n\n\n    checksum = function checksum(data) {\n      var i, sum, tmp, _ref;\n\n      data = __slice.call(data);\n\n      while (data.length % 4) {\n        data.push(0);\n      }\n\n      tmp = new Data(data);\n      sum = 0;\n\n      for (i = 0, _ref = data.length; i < _ref; i = i += 4) {\n        sum += tmp.readUInt32();\n      }\n\n      return sum & 0xffffffff;\n    };\n\n    return Directory;\n  }();\n\n  var Table,\n      __hasProp = {}.hasOwnProperty,\n      __extends = function __extends(child, parent) {\n    for (var key in parent) {\n      if (__hasProp.call(parent, key)) child[key] = parent[key];\n    }\n\n    function ctor() {\n      this.constructor = child;\n    }\n\n    ctor.prototype = parent.prototype;\n    child.prototype = new ctor();\n    child.__super__ = parent.prototype;\n    return child;\n  };\n  /***************************************************************/\n\n  /* function : Table                                            */\n\n  /* comment : Save info for each table, and parse the table.    */\n\n  /***************************************************************/\n\n\n  Table = function () {\n    function Table(file) {\n      var info;\n      this.file = file;\n      info = this.file.directory.tables[this.tag];\n      this.exists = !!info;\n\n      if (info) {\n        this.offset = info.offset, this.length = info.length;\n        this.parse(this.file.contents);\n      }\n    }\n\n    Table.prototype.parse = function () {};\n\n    Table.prototype.encode = function () {};\n\n    Table.prototype.raw = function () {\n      if (!this.exists) {\n        return null;\n      }\n\n      this.file.contents.pos = this.offset;\n      return this.file.contents.read(this.length);\n    };\n\n    return Table;\n  }();\n\n  var HeadTable = function (_super) {\n    __extends(HeadTable, _super);\n\n    function HeadTable() {\n      return HeadTable.__super__.constructor.apply(this, arguments);\n    }\n\n    HeadTable.prototype.tag = \"head\";\n\n    HeadTable.prototype.parse = function (data) {\n      data.pos = this.offset;\n      this.version = data.readInt();\n      this.revision = data.readInt();\n      this.checkSumAdjustment = data.readInt();\n      this.magicNumber = data.readInt();\n      this.flags = data.readShort();\n      this.unitsPerEm = data.readShort();\n      this.created = data.readLongLong();\n      this.modified = data.readLongLong();\n      this.xMin = data.readShort();\n      this.yMin = data.readShort();\n      this.xMax = data.readShort();\n      this.yMax = data.readShort();\n      this.macStyle = data.readShort();\n      this.lowestRecPPEM = data.readShort();\n      this.fontDirectionHint = data.readShort();\n      this.indexToLocFormat = data.readShort();\n      return this.glyphDataFormat = data.readShort();\n    };\n\n    HeadTable.prototype.encode = function (indexToLocFormat) {\n      var table;\n      table = new Data();\n      table.writeInt(this.version);\n      table.writeInt(this.revision);\n      table.writeInt(this.checkSumAdjustment);\n      table.writeInt(this.magicNumber);\n      table.writeShort(this.flags);\n      table.writeShort(this.unitsPerEm);\n      table.writeLongLong(this.created);\n      table.writeLongLong(this.modified);\n      table.writeShort(this.xMin);\n      table.writeShort(this.yMin);\n      table.writeShort(this.xMax);\n      table.writeShort(this.yMax);\n      table.writeShort(this.macStyle);\n      table.writeShort(this.lowestRecPPEM);\n      table.writeShort(this.fontDirectionHint);\n      table.writeShort(indexToLocFormat);\n      table.writeShort(this.glyphDataFormat);\n      return table.data;\n    };\n\n    return HeadTable;\n  }(Table);\n  /************************************************************************************/\n\n  /* function : CmapEntry                                                             */\n\n  /* comment : Cmap Initializes and encodes object information (required by pdf spec).*/\n\n  /************************************************************************************/\n\n\n  var CmapEntry = function () {\n    function CmapEntry(data, offset) {\n      var code, count, endCode, glyphId, glyphIds, i, idDelta, idRangeOffset, index, saveOffset, segCount, segCountX2, start, startCode, tail, _j, _k, _len;\n\n      this.platformID = data.readUInt16();\n      this.encodingID = data.readShort();\n      this.offset = offset + data.readInt();\n      saveOffset = data.pos;\n      data.pos = this.offset;\n      this.format = data.readUInt16();\n      this.length = data.readUInt16();\n      this.language = data.readUInt16();\n      this.isUnicode = this.platformID === 3 && this.encodingID === 1 && this.format === 4 || this.platformID === 0 && this.format === 4;\n      this.codeMap = {};\n\n      switch (this.format) {\n        case 0:\n          for (i = 0; i < 256; ++i) {\n            this.codeMap[i] = data.readByte();\n          }\n\n          break;\n\n        case 4:\n          segCountX2 = data.readUInt16();\n          segCount = segCountX2 / 2;\n          data.pos += 6;\n\n          endCode = function () {\n            var _j, _results;\n\n            _results = [];\n\n            for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {\n              _results.push(data.readUInt16());\n            }\n\n            return _results;\n          }();\n\n          data.pos += 2;\n\n          startCode = function () {\n            var _j, _results;\n\n            _results = [];\n\n            for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {\n              _results.push(data.readUInt16());\n            }\n\n            return _results;\n          }();\n\n          idDelta = function () {\n            var _j, _results;\n\n            _results = [];\n\n            for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {\n              _results.push(data.readUInt16());\n            }\n\n            return _results;\n          }();\n\n          idRangeOffset = function () {\n            var _j, _results;\n\n            _results = [];\n\n            for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {\n              _results.push(data.readUInt16());\n            }\n\n            return _results;\n          }();\n\n          count = (this.length - data.pos + this.offset) / 2;\n\n          glyphIds = function () {\n            var _j, _results;\n\n            _results = [];\n\n            for (i = _j = 0; 0 <= count ? _j < count : _j > count; i = 0 <= count ? ++_j : --_j) {\n              _results.push(data.readUInt16());\n            }\n\n            return _results;\n          }();\n\n          for (i = _j = 0, _len = endCode.length; _j < _len; i = ++_j) {\n            tail = endCode[i];\n            start = startCode[i];\n\n            for (code = _k = start; start <= tail ? _k <= tail : _k >= tail; code = start <= tail ? ++_k : --_k) {\n              if (idRangeOffset[i] === 0) {\n                glyphId = code + idDelta[i];\n              } else {\n                index = idRangeOffset[i] / 2 + (code - start) - (segCount - i);\n                glyphId = glyphIds[index] || 0;\n\n                if (glyphId !== 0) {\n                  glyphId += idDelta[i];\n                }\n              }\n\n              this.codeMap[code] = glyphId & 0xffff;\n            }\n          }\n\n      }\n\n      data.pos = saveOffset;\n    }\n\n    CmapEntry.encode = function (charmap, encoding) {\n      var charMap, code, codeMap, codes, delta, deltas, diff, endCode, endCodes, entrySelector, glyphIDs, i, id, indexes, last, map, nextID, offset, old, rangeOffsets, rangeShift, searchRange, segCount, segCountX2, startCode, startCodes, startGlyph, subtable, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _len6, _len7, _m, _n, _name, _o, _p, _q;\n\n      subtable = new Data();\n      codes = Object.keys(charmap).sort(function (a, b) {\n        return a - b;\n      });\n\n      switch (encoding) {\n        case \"macroman\":\n          id = 0;\n\n          indexes = function () {\n            var _results = [];\n\n            for (i = 0; i < 256; ++i) {\n              _results.push(0);\n            }\n\n            return _results;\n          }();\n\n          map = {\n            0: 0\n          };\n          codeMap = {};\n\n          for (_i = 0, _len = codes.length; _i < _len; _i++) {\n            code = codes[_i];\n\n            if (map[_name = charmap[code]] == null) {\n              map[_name] = ++id;\n            }\n\n            codeMap[code] = {\n              old: charmap[code],\n              new: map[charmap[code]]\n            };\n            indexes[code] = map[charmap[code]];\n          }\n\n          subtable.writeUInt16(1);\n          subtable.writeUInt16(0);\n          subtable.writeUInt32(12);\n          subtable.writeUInt16(0);\n          subtable.writeUInt16(262);\n          subtable.writeUInt16(0);\n          subtable.write(indexes);\n          return {\n            charMap: codeMap,\n            subtable: subtable.data,\n            maxGlyphID: id + 1\n          };\n\n        case \"unicode\":\n          startCodes = [];\n          endCodes = [];\n          nextID = 0;\n          map = {};\n          charMap = {};\n          last = diff = null;\n\n          for (_j = 0, _len1 = codes.length; _j < _len1; _j++) {\n            code = codes[_j];\n            old = charmap[code];\n\n            if (map[old] == null) {\n              map[old] = ++nextID;\n            }\n\n            charMap[code] = {\n              old: old,\n              new: map[old]\n            };\n            delta = map[old] - code;\n\n            if (last == null || delta !== diff) {\n              if (last) {\n                endCodes.push(last);\n              }\n\n              startCodes.push(code);\n              diff = delta;\n            }\n\n            last = code;\n          }\n\n          if (last) {\n            endCodes.push(last);\n          }\n\n          endCodes.push(0xffff);\n          startCodes.push(0xffff);\n          segCount = startCodes.length;\n          segCountX2 = segCount * 2;\n          searchRange = 2 * Math.pow(Math.log(segCount) / Math.LN2, 2);\n          entrySelector = Math.log(searchRange / 2) / Math.LN2;\n          rangeShift = 2 * segCount - searchRange;\n          deltas = [];\n          rangeOffsets = [];\n          glyphIDs = [];\n\n          for (i = _k = 0, _len2 = startCodes.length; _k < _len2; i = ++_k) {\n            startCode = startCodes[i];\n            endCode = endCodes[i];\n\n            if (startCode === 0xffff) {\n              deltas.push(0);\n              rangeOffsets.push(0);\n              break;\n            }\n\n            startGlyph = charMap[startCode][\"new\"];\n\n            if (startCode - startGlyph >= 0x8000) {\n              deltas.push(0);\n              rangeOffsets.push(2 * (glyphIDs.length + segCount - i));\n\n              for (code = _l = startCode; startCode <= endCode ? _l <= endCode : _l >= endCode; code = startCode <= endCode ? ++_l : --_l) {\n                glyphIDs.push(charMap[code][\"new\"]);\n              }\n            } else {\n              deltas.push(startGlyph - startCode);\n              rangeOffsets.push(0);\n            }\n          }\n\n          subtable.writeUInt16(3);\n          subtable.writeUInt16(1);\n          subtable.writeUInt32(12);\n          subtable.writeUInt16(4);\n          subtable.writeUInt16(16 + segCount * 8 + glyphIDs.length * 2);\n          subtable.writeUInt16(0);\n          subtable.writeUInt16(segCountX2);\n          subtable.writeUInt16(searchRange);\n          subtable.writeUInt16(entrySelector);\n          subtable.writeUInt16(rangeShift);\n\n          for (_m = 0, _len3 = endCodes.length; _m < _len3; _m++) {\n            code = endCodes[_m];\n            subtable.writeUInt16(code);\n          }\n\n          subtable.writeUInt16(0);\n\n          for (_n = 0, _len4 = startCodes.length; _n < _len4; _n++) {\n            code = startCodes[_n];\n            subtable.writeUInt16(code);\n          }\n\n          for (_o = 0, _len5 = deltas.length; _o < _len5; _o++) {\n            delta = deltas[_o];\n            subtable.writeUInt16(delta);\n          }\n\n          for (_p = 0, _len6 = rangeOffsets.length; _p < _len6; _p++) {\n            offset = rangeOffsets[_p];\n            subtable.writeUInt16(offset);\n          }\n\n          for (_q = 0, _len7 = glyphIDs.length; _q < _len7; _q++) {\n            id = glyphIDs[_q];\n            subtable.writeUInt16(id);\n          }\n\n          return {\n            charMap: charMap,\n            subtable: subtable.data,\n            maxGlyphID: nextID + 1\n          };\n      }\n    };\n\n    return CmapEntry;\n  }();\n\n  var CmapTable = function (_super) {\n    __extends(CmapTable, _super);\n\n    function CmapTable() {\n      return CmapTable.__super__.constructor.apply(this, arguments);\n    }\n\n    CmapTable.prototype.tag = \"cmap\";\n\n    CmapTable.prototype.parse = function (data) {\n      var entry, i, tableCount;\n      data.pos = this.offset;\n      this.version = data.readUInt16();\n      tableCount = data.readUInt16();\n      this.tables = [];\n      this.unicode = null;\n\n      for (i = 0; 0 <= tableCount ? i < tableCount : i > tableCount; i = 0 <= tableCount ? ++i : --i) {\n        entry = new CmapEntry(data, this.offset);\n        this.tables.push(entry);\n\n        if (entry.isUnicode) {\n          if (this.unicode == null) {\n            this.unicode = entry;\n          }\n        }\n      }\n\n      return true;\n    };\n    /*************************************************************************/\n\n    /* function : encode                                                     */\n\n    /* comment : Encode the cmap table corresponding to the input character. */\n\n    /*************************************************************************/\n\n\n    CmapTable.encode = function (charmap, encoding) {\n      var result, table;\n\n      if (encoding == null) {\n        encoding = \"macroman\";\n      }\n\n      result = CmapEntry.encode(charmap, encoding);\n      table = new Data();\n      table.writeUInt16(0);\n      table.writeUInt16(1);\n      result.table = table.data.concat(result.subtable);\n      return result;\n    };\n\n    return CmapTable;\n  }(Table);\n\n  var HheaTable = function (_super) {\n    __extends(HheaTable, _super);\n\n    function HheaTable() {\n      return HheaTable.__super__.constructor.apply(this, arguments);\n    }\n\n    HheaTable.prototype.tag = \"hhea\";\n\n    HheaTable.prototype.parse = function (data) {\n      data.pos = this.offset;\n      this.version = data.readInt();\n      this.ascender = data.readShort();\n      this.decender = data.readShort();\n      this.lineGap = data.readShort();\n      this.advanceWidthMax = data.readShort();\n      this.minLeftSideBearing = data.readShort();\n      this.minRightSideBearing = data.readShort();\n      this.xMaxExtent = data.readShort();\n      this.caretSlopeRise = data.readShort();\n      this.caretSlopeRun = data.readShort();\n      this.caretOffset = data.readShort();\n      data.pos += 4 * 2;\n      this.metricDataFormat = data.readShort();\n      return this.numberOfMetrics = data.readUInt16();\n    };\n    /*HheaTable.prototype.encode = function (ids) {\n              var i, table, _i, _ref;\n              table = new Data;\n              table.writeInt(this.version);\n              table.writeShort(this.ascender);\n              table.writeShort(this.decender);\n              table.writeShort(this.lineGap);\n              table.writeShort(this.advanceWidthMax);\n              table.writeShort(this.minLeftSideBearing);\n              table.writeShort(this.minRightSideBearing);\n              table.writeShort(this.xMaxExtent);\n              table.writeShort(this.caretSlopeRise);\n              table.writeShort(this.caretSlopeRun);\n              table.writeShort(this.caretOffset);\n              for (i = _i = 0, _ref = 4 * 2; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n                  table.writeByte(0);\n              }\n              table.writeShort(this.metricDataFormat);\n              table.writeUInt16(ids.length);\n              return table.data;\n          };*/\n\n\n    return HheaTable;\n  }(Table);\n\n  var OS2Table = function (_super) {\n    __extends(OS2Table, _super);\n\n    function OS2Table() {\n      return OS2Table.__super__.constructor.apply(this, arguments);\n    }\n\n    OS2Table.prototype.tag = \"OS/2\";\n\n    OS2Table.prototype.parse = function (data) {\n      data.pos = this.offset;\n      this.version = data.readUInt16();\n      this.averageCharWidth = data.readShort();\n      this.weightClass = data.readUInt16();\n      this.widthClass = data.readUInt16();\n      this.type = data.readShort();\n      this.ySubscriptXSize = data.readShort();\n      this.ySubscriptYSize = data.readShort();\n      this.ySubscriptXOffset = data.readShort();\n      this.ySubscriptYOffset = data.readShort();\n      this.ySuperscriptXSize = data.readShort();\n      this.ySuperscriptYSize = data.readShort();\n      this.ySuperscriptXOffset = data.readShort();\n      this.ySuperscriptYOffset = data.readShort();\n      this.yStrikeoutSize = data.readShort();\n      this.yStrikeoutPosition = data.readShort();\n      this.familyClass = data.readShort();\n\n      this.panose = function () {\n        var i, _results;\n\n        _results = [];\n\n        for (i = 0; i < 10; ++i) {\n          _results.push(data.readByte());\n        }\n\n        return _results;\n      }();\n\n      this.charRange = function () {\n        var i, _results;\n\n        _results = [];\n\n        for (i = 0; i < 4; ++i) {\n          _results.push(data.readInt());\n        }\n\n        return _results;\n      }();\n\n      this.vendorID = data.readString(4);\n      this.selection = data.readShort();\n      this.firstCharIndex = data.readShort();\n      this.lastCharIndex = data.readShort();\n\n      if (this.version > 0) {\n        this.ascent = data.readShort();\n        this.descent = data.readShort();\n        this.lineGap = data.readShort();\n        this.winAscent = data.readShort();\n        this.winDescent = data.readShort();\n\n        this.codePageRange = function () {\n          var i, _results;\n\n          _results = [];\n\n          for (i = 0; i < 2; i = ++i) {\n            _results.push(data.readInt());\n          }\n\n          return _results;\n        }();\n\n        if (this.version > 1) {\n          this.xHeight = data.readShort();\n          this.capHeight = data.readShort();\n          this.defaultChar = data.readShort();\n          this.breakChar = data.readShort();\n          return this.maxContext = data.readShort();\n        }\n      }\n    };\n    /*OS2Table.prototype.encode = function () {\n              return this.raw();\n          };*/\n\n\n    return OS2Table;\n  }(Table);\n\n  var PostTable = function (_super) {\n\n    __extends(PostTable, _super);\n\n    function PostTable() {\n      return PostTable.__super__.constructor.apply(this, arguments);\n    }\n\n    PostTable.prototype.tag = \"post\";\n\n    PostTable.prototype.parse = function (data) {\n      var length, numberOfGlyphs, _results;\n\n      data.pos = this.offset;\n      this.format = data.readInt();\n      this.italicAngle = data.readInt();\n      this.underlinePosition = data.readShort();\n      this.underlineThickness = data.readShort();\n      this.isFixedPitch = data.readInt();\n      this.minMemType42 = data.readInt();\n      this.maxMemType42 = data.readInt();\n      this.minMemType1 = data.readInt();\n      this.maxMemType1 = data.readInt();\n\n      switch (this.format) {\n        case 0x00010000:\n          break;\n\n        case 0x00020000:\n          numberOfGlyphs = data.readUInt16();\n          this.glyphNameIndex = [];\n          var i;\n\n          for (i = 0; 0 <= numberOfGlyphs ? i < numberOfGlyphs : i > numberOfGlyphs; i = 0 <= numberOfGlyphs ? ++i : --i) {\n            this.glyphNameIndex.push(data.readUInt16());\n          }\n\n          this.names = [];\n          _results = [];\n\n          while (data.pos < this.offset + this.length) {\n            length = data.readByte();\n\n            _results.push(this.names.push(data.readString(length)));\n          }\n\n          return _results;\n\n        case 0x00025000:\n          numberOfGlyphs = data.readUInt16();\n          return this.offsets = data.read(numberOfGlyphs);\n\n        case 0x00030000:\n          break;\n\n        case 0x00040000:\n          return this.map = function () {\n            var _j, _ref, _results1;\n\n            _results1 = [];\n\n            for (i = _j = 0, _ref = this.file.maxp.numGlyphs; 0 <= _ref ? _j < _ref : _j > _ref; i = 0 <= _ref ? ++_j : --_j) {\n              _results1.push(data.readUInt32());\n            }\n\n            return _results1;\n          }.call(this);\n      }\n    };\n    return PostTable;\n  }(Table);\n  /*********************************************************************************************************/\n\n  /* function : NameEntry                                                                                  */\n\n  /* comment : Store copyright information, platformID, encodingID, and languageID in the NameEntry object.*/\n\n  /*********************************************************************************************************/\n\n\n  var NameEntry = function () {\n    function NameEntry(raw, entry) {\n      this.raw = raw;\n      this.length = raw.length;\n      this.platformID = entry.platformID;\n      this.encodingID = entry.encodingID;\n      this.languageID = entry.languageID;\n    }\n\n    return NameEntry;\n  }();\n\n  var NameTable = function (_super) {\n\n    __extends(NameTable, _super);\n\n    function NameTable() {\n      return NameTable.__super__.constructor.apply(this, arguments);\n    }\n\n    NameTable.prototype.tag = \"name\";\n\n    NameTable.prototype.parse = function (data) {\n      var count, entries, entry, i, name, stringOffset, strings, text, _j, _len, _name;\n\n      data.pos = this.offset;\n      data.readShort(); //format\n\n      count = data.readShort();\n      stringOffset = data.readShort();\n      entries = [];\n\n      for (i = 0; 0 <= count ? i < count : i > count; i = 0 <= count ? ++i : --i) {\n        entries.push({\n          platformID: data.readShort(),\n          encodingID: data.readShort(),\n          languageID: data.readShort(),\n          nameID: data.readShort(),\n          length: data.readShort(),\n          offset: this.offset + stringOffset + data.readShort()\n        });\n      }\n\n      strings = {};\n\n      for (i = _j = 0, _len = entries.length; _j < _len; i = ++_j) {\n        entry = entries[i];\n        data.pos = entry.offset;\n        text = data.readString(entry.length);\n        name = new NameEntry(text, entry);\n\n        if (strings[_name = entry.nameID] == null) {\n          strings[_name] = [];\n        }\n\n        strings[entry.nameID].push(name);\n      }\n\n      this.strings = strings;\n      this.copyright = strings[0];\n      this.fontFamily = strings[1];\n      this.fontSubfamily = strings[2];\n      this.uniqueSubfamily = strings[3];\n      this.fontName = strings[4];\n      this.version = strings[5];\n\n      try {\n        this.postscriptName = strings[6][0].raw.replace(/[\\x00-\\x19\\x80-\\xff]/g, \"\");\n      } catch (e) {\n        this.postscriptName = strings[4][0].raw.replace(/[\\x00-\\x19\\x80-\\xff]/g, \"\");\n      }\n\n      this.trademark = strings[7];\n      this.manufacturer = strings[8];\n      this.designer = strings[9];\n      this.description = strings[10];\n      this.vendorUrl = strings[11];\n      this.designerUrl = strings[12];\n      this.license = strings[13];\n      this.licenseUrl = strings[14];\n      this.preferredFamily = strings[15];\n      this.preferredSubfamily = strings[17];\n      this.compatibleFull = strings[18];\n      return this.sampleText = strings[19];\n    };\n    /*NameTable.prototype.encode = function () {\n              var id, list, nameID, nameTable, postscriptName, strCount, strTable, string, strings, table, val, _i, _len, _ref;\n              strings = {};\n              _ref = this.strings;\n              for (id in _ref) {\n                  val = _ref[id];\n                  strings[id] = val;\n              }\n              postscriptName = new NameEntry(\"\" + subsetTag + \"+\" + this.postscriptName, {\n                  platformID: 1\n                  , encodingID: 0\n                  , languageID: 0\n              });\n              strings[6] = [postscriptName];\n              subsetTag = successorOf(subsetTag);\n              strCount = 0;\n              for (id in strings) {\n                  list = strings[id];\n                  if (list != null) {\n                      strCount += list.length;\n                  }\n              }\n              table = new Data;\n              strTable = new Data;\n              table.writeShort(0);\n              table.writeShort(strCount);\n              table.writeShort(6 + 12 * strCount);\n              for (nameID in strings) {\n                  list = strings[nameID];\n                  if (list != null) {\n                      for (_i = 0, _len = list.length; _i < _len; _i++) {\n                          string = list[_i];\n                          table.writeShort(string.platformID);\n                          table.writeShort(string.encodingID);\n                          table.writeShort(string.languageID);\n                          table.writeShort(nameID);\n                          table.writeShort(string.length);\n                          table.writeShort(strTable.pos);\n                          strTable.writeString(string.raw);\n                      }\n                  }\n              }\n              return nameTable = {\n                  postscriptName: postscriptName.raw\n                  , table: table.data.concat(strTable.data)\n              };\n          };*/\n\n    return NameTable;\n  }(Table);\n\n  var MaxpTable = function (_super) {\n    __extends(MaxpTable, _super);\n\n    function MaxpTable() {\n      return MaxpTable.__super__.constructor.apply(this, arguments);\n    }\n\n    MaxpTable.prototype.tag = \"maxp\";\n\n    MaxpTable.prototype.parse = function (data) {\n      data.pos = this.offset;\n      this.version = data.readInt();\n      this.numGlyphs = data.readUInt16();\n      this.maxPoints = data.readUInt16();\n      this.maxContours = data.readUInt16();\n      this.maxCompositePoints = data.readUInt16();\n      this.maxComponentContours = data.readUInt16();\n      this.maxZones = data.readUInt16();\n      this.maxTwilightPoints = data.readUInt16();\n      this.maxStorage = data.readUInt16();\n      this.maxFunctionDefs = data.readUInt16();\n      this.maxInstructionDefs = data.readUInt16();\n      this.maxStackElements = data.readUInt16();\n      this.maxSizeOfInstructions = data.readUInt16();\n      this.maxComponentElements = data.readUInt16();\n      return this.maxComponentDepth = data.readUInt16();\n    };\n    /*MaxpTable.prototype.encode = function (ids) {\n              var table;\n              table = new Data;\n              table.writeInt(this.version);\n              table.writeUInt16(ids.length);\n              table.writeUInt16(this.maxPoints);\n              table.writeUInt16(this.maxContours);\n              table.writeUInt16(this.maxCompositePoints);\n              table.writeUInt16(this.maxComponentContours);\n              table.writeUInt16(this.maxZones);\n              table.writeUInt16(this.maxTwilightPoints);\n              table.writeUInt16(this.maxStorage);\n              table.writeUInt16(this.maxFunctionDefs);\n              table.writeUInt16(this.maxInstructionDefs);\n              table.writeUInt16(this.maxStackElements);\n              table.writeUInt16(this.maxSizeOfInstructions);\n              table.writeUInt16(this.maxComponentElements);\n              table.writeUInt16(this.maxComponentDepth);\n              return table.data;\n          };*/\n\n\n    return MaxpTable;\n  }(Table);\n\n  var HmtxTable = function (_super) {\n    __extends(HmtxTable, _super);\n\n    function HmtxTable() {\n      return HmtxTable.__super__.constructor.apply(this, arguments);\n    }\n\n    HmtxTable.prototype.tag = \"hmtx\";\n\n    HmtxTable.prototype.parse = function (data) {\n      var i, last, lsbCount, m, _j, _ref, _results;\n\n      data.pos = this.offset;\n      this.metrics = [];\n\n      for (i = 0, _ref = this.file.hhea.numberOfMetrics; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) {\n        this.metrics.push({\n          advance: data.readUInt16(),\n          lsb: data.readInt16()\n        });\n      }\n\n      lsbCount = this.file.maxp.numGlyphs - this.file.hhea.numberOfMetrics;\n\n      this.leftSideBearings = function () {\n        var _j, _results;\n\n        _results = [];\n\n        for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) {\n          _results.push(data.readInt16());\n        }\n\n        return _results;\n      }();\n\n      this.widths = function () {\n        var _j, _len, _ref1, _results;\n\n        _ref1 = this.metrics;\n        _results = [];\n\n        for (_j = 0, _len = _ref1.length; _j < _len; _j++) {\n          m = _ref1[_j];\n\n          _results.push(m.advance);\n        }\n\n        return _results;\n      }.call(this);\n\n      last = this.widths[this.widths.length - 1];\n      _results = [];\n\n      for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) {\n        _results.push(this.widths.push(last));\n      }\n\n      return _results;\n    };\n    /***************************************************************/\n\n    /* function : forGlyph                                         */\n\n    /* comment : Returns the advance width and lsb for this glyph. */\n\n    /***************************************************************/\n\n\n    HmtxTable.prototype.forGlyph = function (id) {\n      if (id in this.metrics) {\n        return this.metrics[id];\n      }\n\n      return {\n        advance: this.metrics[this.metrics.length - 1].advance,\n        lsb: this.leftSideBearings[id - this.metrics.length]\n      };\n    };\n    /*HmtxTable.prototype.encode = function (mapping) {\n              var id, metric, table, _i, _len;\n              table = new Data;\n              for (_i = 0, _len = mapping.length; _i < _len; _i++) {\n                  id = mapping[_i];\n                  metric = this.forGlyph(id);\n                  table.writeUInt16(metric.advance);\n                  table.writeUInt16(metric.lsb);\n              }\n              return table.data;\n          };*/\n\n\n    return HmtxTable;\n  }(Table);\n\n  var __slice = [].slice;\n\n  var GlyfTable = function (_super) {\n    __extends(GlyfTable, _super);\n\n    function GlyfTable() {\n      return GlyfTable.__super__.constructor.apply(this, arguments);\n    }\n\n    GlyfTable.prototype.tag = \"glyf\";\n\n    GlyfTable.prototype.parse = function () {\n      return this.cache = {};\n    };\n\n    GlyfTable.prototype.glyphFor = function (id) {\n      var data, index, length, loca, numberOfContours, raw, xMax, xMin, yMax, yMin;\n\n      if (id in this.cache) {\n        return this.cache[id];\n      }\n\n      loca = this.file.loca;\n      data = this.file.contents;\n      index = loca.indexOf(id);\n      length = loca.lengthOf(id);\n\n      if (length === 0) {\n        return this.cache[id] = null;\n      }\n\n      data.pos = this.offset + index;\n      raw = new Data(data.read(length));\n      numberOfContours = raw.readShort();\n      xMin = raw.readShort();\n      yMin = raw.readShort();\n      xMax = raw.readShort();\n      yMax = raw.readShort();\n\n      if (numberOfContours === -1) {\n        this.cache[id] = new CompoundGlyph(raw, xMin, yMin, xMax, yMax);\n      } else {\n        this.cache[id] = new SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax);\n      }\n\n      return this.cache[id];\n    };\n\n    GlyfTable.prototype.encode = function (glyphs, mapping, old2new) {\n      var glyph, id, offsets, table, _i, _len;\n\n      table = [];\n      offsets = [];\n\n      for (_i = 0, _len = mapping.length; _i < _len; _i++) {\n        id = mapping[_i];\n        glyph = glyphs[id];\n        offsets.push(table.length);\n\n        if (glyph) {\n          table = table.concat(glyph.encode(old2new));\n        }\n      }\n\n      offsets.push(table.length);\n      return {\n        table: table,\n        offsets: offsets\n      };\n    };\n\n    return GlyfTable;\n  }(Table);\n\n  var SimpleGlyph = function () {\n    /**************************************************************************/\n\n    /* function : SimpleGlyph                                                 */\n\n    /* comment : Stores raw, xMin, yMin, xMax, and yMax values for this glyph.*/\n\n    /**************************************************************************/\n    function SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax) {\n      this.raw = raw;\n      this.numberOfContours = numberOfContours;\n      this.xMin = xMin;\n      this.yMin = yMin;\n      this.xMax = xMax;\n      this.yMax = yMax;\n      this.compound = false;\n    }\n\n    SimpleGlyph.prototype.encode = function () {\n      return this.raw.data;\n    };\n\n    return SimpleGlyph;\n  }();\n\n  var CompoundGlyph = function () {\n    var ARG_1_AND_2_ARE_WORDS, MORE_COMPONENTS, WE_HAVE_AN_X_AND_Y_SCALE, WE_HAVE_A_SCALE, WE_HAVE_A_TWO_BY_TWO;\n    ARG_1_AND_2_ARE_WORDS = 0x0001;\n    WE_HAVE_A_SCALE = 0x0008;\n    MORE_COMPONENTS = 0x0020;\n    WE_HAVE_AN_X_AND_Y_SCALE = 0x0040;\n    WE_HAVE_A_TWO_BY_TWO = 0x0080;\n    /********************************************************************************************************************/\n\n    /* function : CompoundGlypg generator                                                                               */\n\n    /* comment : It stores raw, xMin, yMin, xMax, yMax, glyph id, and glyph offset for the corresponding compound glyph.*/\n\n    /********************************************************************************************************************/\n\n    function CompoundGlyph(raw, xMin, yMin, xMax, yMax) {\n      var data, flags;\n      this.raw = raw;\n      this.xMin = xMin;\n      this.yMin = yMin;\n      this.xMax = xMax;\n      this.yMax = yMax;\n      this.compound = true;\n      this.glyphIDs = [];\n      this.glyphOffsets = [];\n      data = this.raw;\n\n      while (true) {\n        flags = data.readShort();\n        this.glyphOffsets.push(data.pos);\n        this.glyphIDs.push(data.readUInt16());\n\n        if (!(flags & MORE_COMPONENTS)) {\n          break;\n        }\n\n        if (flags & ARG_1_AND_2_ARE_WORDS) {\n          data.pos += 4;\n        } else {\n          data.pos += 2;\n        }\n\n        if (flags & WE_HAVE_A_TWO_BY_TWO) {\n          data.pos += 8;\n        } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {\n          data.pos += 4;\n        } else if (flags & WE_HAVE_A_SCALE) {\n          data.pos += 2;\n        }\n      }\n    }\n    /****************************************************************************************************************/\n\n    /* function : CompoundGlypg encode                                                                              */\n\n    /* comment : After creating a table for the characters you typed, you call directory.encode to encode the table.*/\n\n    /****************************************************************************************************************/\n\n\n    CompoundGlyph.prototype.encode = function () {\n      var i, result, _len, _ref;\n\n      result = new Data(__slice.call(this.raw.data));\n      _ref = this.glyphIDs;\n\n      for (i = 0, _len = _ref.length; i < _len; ++i) {\n        result.pos = this.glyphOffsets[i];\n      }\n\n      return result.data;\n    };\n\n    return CompoundGlyph;\n  }();\n\n  var LocaTable = function (_super) {\n    __extends(LocaTable, _super);\n\n    function LocaTable() {\n      return LocaTable.__super__.constructor.apply(this, arguments);\n    }\n\n    LocaTable.prototype.tag = \"loca\";\n\n    LocaTable.prototype.parse = function (data) {\n      var format, i;\n      data.pos = this.offset;\n      format = this.file.head.indexToLocFormat;\n\n      if (format === 0) {\n        return this.offsets = function () {\n          var _ref, _results;\n\n          _results = [];\n\n          for (i = 0, _ref = this.length; i < _ref; i += 2) {\n            _results.push(data.readUInt16() * 2);\n          }\n\n          return _results;\n        }.call(this);\n      } else {\n        return this.offsets = function () {\n          var _ref, _results;\n\n          _results = [];\n\n          for (i = 0, _ref = this.length; i < _ref; i += 4) {\n            _results.push(data.readUInt32());\n          }\n\n          return _results;\n        }.call(this);\n      }\n    };\n\n    LocaTable.prototype.indexOf = function (id) {\n      return this.offsets[id];\n    };\n\n    LocaTable.prototype.lengthOf = function (id) {\n      return this.offsets[id + 1] - this.offsets[id];\n    };\n\n    LocaTable.prototype.encode = function (offsets, activeGlyphs) {\n      var LocaTable = new Uint32Array(this.offsets.length);\n      var glyfPtr = 0;\n      var listGlyf = 0;\n\n      for (var k = 0; k < LocaTable.length; ++k) {\n        LocaTable[k] = glyfPtr;\n\n        if (listGlyf < activeGlyphs.length && activeGlyphs[listGlyf] == k) {\n          ++listGlyf;\n          LocaTable[k] = glyfPtr;\n          var start = this.offsets[k];\n          var len = this.offsets[k + 1] - start;\n\n          if (len > 0) {\n            glyfPtr += len;\n          }\n        }\n      }\n\n      var newLocaTable = new Array(LocaTable.length * 4);\n\n      for (var j = 0; j < LocaTable.length; ++j) {\n        newLocaTable[4 * j + 3] = LocaTable[j] & 0x000000ff;\n        newLocaTable[4 * j + 2] = (LocaTable[j] & 0x0000ff00) >> 8;\n        newLocaTable[4 * j + 1] = (LocaTable[j] & 0x00ff0000) >> 16;\n        newLocaTable[4 * j] = (LocaTable[j] & 0xff000000) >> 24;\n      }\n\n      return newLocaTable;\n    };\n\n    return LocaTable;\n  }(Table);\n  /************************************************************************************/\n\n  /* function : invert                                                                */\n\n  /* comment : Change the object's (key: value) to create an object with (value: key).*/\n\n  /************************************************************************************/\n\n\n  var invert = function invert(object) {\n    var key, ret, val;\n    ret = {};\n\n    for (key in object) {\n      val = object[key];\n      ret[val] = key;\n    }\n\n    return ret;\n  };\n  /*var successorOf = function (input) {\n          var added, alphabet, carry, i, index, isUpperCase, last, length, next, result;\n          alphabet = 'abcdefghijklmnopqrstuvwxyz';\n          length = alphabet.length;\n          result = input;\n          i = input.length;\n          while (i >= 0) {\n              last = input.charAt(--i);\n              if (isNaN(last)) {\n                  index = alphabet.indexOf(last.toLowerCase());\n                  if (index === -1) {\n                      next = last;\n                      carry = true;\n                  }\n                  else {\n                      next = alphabet.charAt((index + 1) % length);\n                      isUpperCase = last === last.toUpperCase();\n                      if (isUpperCase) {\n                          next = next.toUpperCase();\n                      }\n                      carry = index + 1 >= length;\n                      if (carry && i === 0) {\n                          added = isUpperCase ? 'A' : 'a';\n                          result = added + next + result.slice(1);\n                          break;\n                      }\n                  }\n              }\n              else {\n                  next = +last + 1;\n                  carry = next > 9;\n                  if (carry) {\n                      next = 0;\n                  }\n                  if (carry && i === 0) {\n                      result = '1' + next + result.slice(1);\n                      break;\n                  }\n              }\n              result = result.slice(0, i) + next + result.slice(i + 1);\n              if (!carry) {\n                  break;\n              }\n          }\n          return result;\n      };*/\n\n\n  var Subset = function () {\n    function Subset(font) {\n      this.font = font;\n      this.subset = {};\n      this.unicodes = {};\n      this.next = 33;\n    }\n    /*Subset.prototype.use = function (character) {\n              var i, _i, _ref;\n              if (typeof character === 'string') {\n                  for (i = _i = 0, _ref = character.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n                      this.use(character.charCodeAt(i));\n                  }\n                  return;\n              }\n              if (!this.unicodes[character]) {\n                  this.subset[this.next] = character;\n                  return this.unicodes[character] = this.next++;\n              }\n          };*/\n\n    /*Subset.prototype.encodeText = function (text) {\n              var char, i, string, _i, _ref;\n              string = '';\n              for (i = _i = 0, _ref = text.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n                  char = this.unicodes[text.charCodeAt(i)];\n                  string += String.fromCharCode(char);\n              }\n              return string;\n          };*/\n\n    /***************************************************************/\n\n    /* function : generateCmap                                     */\n\n    /* comment : Returns the unicode cmap for this font.         */\n\n    /***************************************************************/\n\n\n    Subset.prototype.generateCmap = function () {\n      var mapping, roman, unicode, unicodeCmap, _ref;\n\n      unicodeCmap = this.font.cmap.tables[0].codeMap;\n      mapping = {};\n      _ref = this.subset;\n\n      for (roman in _ref) {\n        unicode = _ref[roman];\n        mapping[roman] = unicodeCmap[unicode];\n      }\n\n      return mapping;\n    };\n    /*Subset.prototype.glyphIDs = function () {\n              var ret, roman, unicode, unicodeCmap, val, _ref;\n              unicodeCmap = this.font.cmap.tables[0].codeMap;\n              ret = [0];\n              _ref = this.subset;\n              for (roman in _ref) {\n                  unicode = _ref[roman];\n                  val = unicodeCmap[unicode];\n                  if ((val != null) && __indexOf.call(ret, val) < 0) {\n                      ret.push(val);\n                  }\n              }\n              return ret.sort();\n          };*/\n\n    /******************************************************************/\n\n    /* function : glyphsFor                                           */\n\n    /* comment : Returns simple glyph objects for the input character.*/\n\n    /******************************************************************/\n\n\n    Subset.prototype.glyphsFor = function (glyphIDs) {\n      var additionalIDs, glyph, glyphs, id, _i, _len, _ref;\n\n      glyphs = {};\n\n      for (_i = 0, _len = glyphIDs.length; _i < _len; _i++) {\n        id = glyphIDs[_i];\n        glyphs[id] = this.font.glyf.glyphFor(id);\n      }\n\n      additionalIDs = [];\n\n      for (id in glyphs) {\n        glyph = glyphs[id];\n\n        if (glyph != null ? glyph.compound : void 0) {\n          additionalIDs.push.apply(additionalIDs, glyph.glyphIDs);\n        }\n      }\n\n      if (additionalIDs.length > 0) {\n        _ref = this.glyphsFor(additionalIDs);\n\n        for (id in _ref) {\n          glyph = _ref[id];\n          glyphs[id] = glyph;\n        }\n      }\n\n      return glyphs;\n    };\n    /***************************************************************/\n\n    /* function : encode                                           */\n\n    /* comment : Encode various tables for the characters you use. */\n\n    /***************************************************************/\n\n\n    Subset.prototype.encode = function (glyID, indexToLocFormat) {\n      var cmap, code, glyf, glyphs, id, ids, loca, new2old, newIDs, nextGlyphID, old2new, oldID, oldIDs, tables, _ref;\n\n      cmap = CmapTable.encode(this.generateCmap(), \"unicode\");\n      glyphs = this.glyphsFor(glyID);\n      old2new = {\n        0: 0\n      };\n      _ref = cmap.charMap;\n\n      for (code in _ref) {\n        ids = _ref[code];\n        old2new[ids.old] = ids[\"new\"];\n      }\n\n      nextGlyphID = cmap.maxGlyphID;\n\n      for (oldID in glyphs) {\n        if (!(oldID in old2new)) {\n          old2new[oldID] = nextGlyphID++;\n        }\n      }\n\n      new2old = invert(old2new);\n      newIDs = Object.keys(new2old).sort(function (a, b) {\n        return a - b;\n      });\n\n      oldIDs = function () {\n        var _i, _len, _results;\n\n        _results = [];\n\n        for (_i = 0, _len = newIDs.length; _i < _len; _i++) {\n          id = newIDs[_i];\n\n          _results.push(new2old[id]);\n        }\n\n        return _results;\n      }();\n\n      glyf = this.font.glyf.encode(glyphs, oldIDs, old2new);\n      loca = this.font.loca.encode(glyf.offsets, oldIDs);\n      tables = {\n        cmap: this.font.cmap.raw(),\n        glyf: glyf.table,\n        loca: loca,\n        hmtx: this.font.hmtx.raw(),\n        hhea: this.font.hhea.raw(),\n        maxp: this.font.maxp.raw(),\n        post: this.font.post.raw(),\n        name: this.font.name.raw(),\n        head: this.font.head.encode(indexToLocFormat)\n      };\n\n      if (this.font.os2.exists) {\n        tables[\"OS/2\"] = this.font.os2.raw();\n      }\n\n      return this.font.directory.encode(tables);\n    };\n\n    return Subset;\n  }();\n\n  jsPDF.API.PDFObject = function () {\n    var pad;\n\n    function PDFObject() {}\n\n    pad = function pad(str, length) {\n      return (Array(length + 1).join(\"0\") + str).slice(-length);\n    };\n    /*****************************************************************************/\n\n    /* function : convert                                                        */\n\n    /* comment :Converts pdf tag's / FontBBox and array values in / W to strings */\n\n    /*****************************************************************************/\n\n\n    PDFObject.convert = function (object) {\n      var e, items, key, out, val;\n\n      if (Array.isArray(object)) {\n        items = function () {\n          var _i, _len, _results;\n\n          _results = [];\n\n          for (_i = 0, _len = object.length; _i < _len; _i++) {\n            e = object[_i];\n\n            _results.push(PDFObject.convert(e));\n          }\n\n          return _results;\n        }().join(\" \");\n\n        return \"[\" + items + \"]\";\n      } else if (typeof object === \"string\") {\n        return \"/\" + object;\n      } else if (object != null ? object.isString : void 0) {\n        return \"(\" + object + \")\";\n      } else if (object instanceof Date) {\n        return \"(D:\" + pad(object.getUTCFullYear(), 4) + pad(object.getUTCMonth(), 2) + pad(object.getUTCDate(), 2) + pad(object.getUTCHours(), 2) + pad(object.getUTCMinutes(), 2) + pad(object.getUTCSeconds(), 2) + \"Z)\";\n      } else if ({}.toString.call(object) === \"[object Object]\") {\n        out = [\"<<\"];\n\n        for (key in object) {\n          val = object[key];\n          out.push(\"/\" + key + \" \" + PDFObject.convert(val));\n        }\n\n        out.push(\">>\");\n        return out.join(\"\\n\");\n      } else {\n        return \"\" + object;\n      }\n    };\n\n    return PDFObject;\n  }();\n\n  exports.AcroForm = AcroForm;\n  exports.AcroFormAppearance = AcroFormAppearance;\n  exports.AcroFormButton = AcroFormButton;\n  exports.AcroFormCheckBox = AcroFormCheckBox;\n  exports.AcroFormChoiceField = AcroFormChoiceField;\n  exports.AcroFormComboBox = AcroFormComboBox;\n  exports.AcroFormEditBox = AcroFormEditBox;\n  exports.AcroFormListBox = AcroFormListBox;\n  exports.AcroFormPasswordField = AcroFormPasswordField;\n  exports.AcroFormPushButton = AcroFormPushButton;\n  exports.AcroFormRadioButton = AcroFormRadioButton;\n  exports.AcroFormTextField = AcroFormTextField;\n  exports.GState = GState;\n  exports.ShadingPattern = ShadingPattern;\n  exports.TilingPattern = TilingPattern;\n  exports.default = jsPDF;\n  exports.jsPDF = jsPDF;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n//# sourceMappingURL=jspdf.umd.js.map\n"],"names":["global","factory","exports","module","define","amd","self","jspdf","this","_typeof","obj","Symbol","iterator","constructor","prototype","globalObject","window","consoleLog","console","log","apply","arguments","warn","str","call","error","download","url","name","opts","xhr","XMLHttpRequest","open","responseType","onload","saveAs","response","onerror","send","corsEnabled","e","status","click","node","dispatchEvent","MouseEvent","evt","document","createEvent","initMouseEvent","atob","btoa","HTMLAnchorElement","blob","URL","webkitURL","a","createElement","rel","href","origin","location","target","createObjectURL","setTimeout","revokeObjectURL","navigator","msSaveOrOpenBlob","autoBom","test","type","Blob","String","fromCharCode","bom","popup","title","body","innerText","force","isSafari","HTMLElement","safari","isChromeIOS","userAgent","FileReader","reader","onloadend","result","replace","readAsDataURL","RGBColor","color_string","channels","ok","charAt","substr","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","feldspar","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslateblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","violetred","wheat","white","whitesmoke","yellow","yellowgreen","toLowerCase","color_defs","re","example","process","bits","parseInt","i","length","processor","exec","r","g","b","isNaN","toRGB","toHex","toString","md5cycle","x","k","c","d","ff","gg","hh","ii","add32","cmn","q","s","t","md51","n","state","md5blk","substring","tail","charCodeAt","md5blks","bind","hex_chr","split","rhex","j","singleToByteString","md5Bin","map","join","toByteString","md5Check","hex","lsw","rc4","key","data","lastKey","lastState","num","Array","out","permissionOptions","print","modify","copy","PDFSecurity","permissions","userPassword","ownerPassword","fileId","v","protection","forEach","perm","Error","padding","paddedUserPassword","paddedOwnerPassword","O","processOwnerPassword","P","encryptionKey","lsbFirstWord","hexToBytes","U","toPDFName","strLength","charCode","slice","PubSub","context","topics","subscribe","topic","callback","once","hasOwnProperty","token","Math","random","unsubscribe","Object","keys","publish","args","tokens","sub","ex","message","push","getTopics","GState","parameters","supported","p","indexOf","id","objectNumber","Pattern","gState","matrix","ShadingPattern","coords","colors","TilingPattern","boundingBox","xStep","yStep","stream","cloneIndex","jsPDF","options","precision","orientation","unit","format","compressPdf","filters","userUnit","floatPrecision","defaultPathOperation","encryptionOptions","compress","encryption","userPermissions","abs","putOnlyUsedFonts","usedFonts","API","internal","__private__","pdfVersion","getPdfVersion","setPdfVersion","value","pageFormats","a0","a1","a2","a3","a4","a5","a6","a7","a8","a9","a10","b0","b1","b2","b3","b4","b5","b6","b7","b8","b9","b10","c0","c1","c2","c3","c4","c5","c6","c7","c8","c9","c10","dl","letter","legal","ledger","tabloid","getPageFormats","getPageFormat","ApiMode","COMPAT","ADVANCED","apiMode","advancedAPI","saveGraphicsState","Matrix","scaleFactor","getPageHeight","setFontSize","getFontSize","compatAPI","restoreGraphicsState","combineFontStyleAndFontWeight","fontStyle","fontWeight","doSwitch","isAdvancedAPI","hpf","advancedApiModeTrap","methodName","roundToPrecision","number","parmPrecision","tmpPrecision","toFixed","f2","f3","scale","transformY","y","transformScaleY","setPrecision","creationDate","getFileId","setFileId","toUpperCase","floor","convertDateToPDFDate","parmDate","tzoffset","getTimezoneOffset","tzsign","tzhour","tzmin","timeZoneString","padd2","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","convertPDFDateToDate","parmPDFDate","year","month","date","hour","minutes","seconds","Date","setCreationDate","tmpCreationDateString","getCreationDate","currentPage","padd2Hex","hexString","offsets","content","contentLength","additionalObjects","pages","hasCustomDestination","outputDestination","resetDocument","rootDictionaryObjId","newObjectDeferred","resourceDictionaryObjId","setCustomOutputDestination","destination","setOutputDestination","resetCustomOutputDestination","string","write","getArrayBuffer","len","ab","ArrayBuffer","u8","Uint8Array","standardFonts","getStandardFonts","activeFontSize","fontSize","size","zoomMode","R2L","setR2L","getR2L","pageMode","setZoomMode","zoom","validZoomModes","undefined","getZoomMode","layoutMode","setPageMode","pmode","getPageMode","setLayoutMode","layout","getLayoutMode","setDisplayMode","documentProperties","subject","author","keywords","creator","getDocumentProperty","getDocumentProperties","setDocumentProperties","setProperties","properties","property","setDocumentProperty","activeFontKey","pageX","pageY","pageMatrix","fonts","fontmap","fontStateStack","patterns","patternMap","gStates","gStatesMap","activeGState","page","pagesContext","events","hotfixes","renderTargets","renderTargetMap","renderTargetStack","sx","shy","shx","sy","tx","ty","_matrix","defineProperty","get","set","atan2","decompose","separator","multiply","f","scaleX","sqrt","shear","scaleY","translate","rotate","skew","inversed","quot","aInv","bInv","cInv","dInv","applyToPoint","pt","Point","applyToRectangle","rect","pt1","pt2","w","h","Rectangle","clone","matrixMult","m1","m2","identityMatrix","unitMatrix","addPattern","pattern","patternKey","addShadingPattern","beginTilingPattern","beginNewRenderTarget","endTilingPattern","pop","restore","newObject","oid","newObjectDeferredBegin","doOutput","newAdditionalObject","objId","decodeColorString","color","colorEncoded","floatVal","parseFloat","colorAsRGB","encodeColorString","ch1","ch2","ch3","ch4","letterArray","pdfColorType","rgbColor","getFilters","putStream","alreadyAppliedFilters","addLength1","valueOfLength1","objectId","encryptor","processedData","keyValues","additionalKeyValues","filterAsString","processDataByFilters","reverseChain","isArray","decodeParmsArray","putPage","pageNumber","pageObjectNumber","pageContentsObjId","contentsObjId","mediaBox","bottomLeftX","bottomLeftY","topRightX","topRightY","cropBox","bleedBox","trimBox","artBox","pageContext","pageContent","putPages","pageObjectNumbers","kids","putFont","font","isAlreadyPutted","postScriptName","encoding","putFonts","fontKey","putXObject","xObject","width","height","putXObjects","xObjectKey","interpolateAndEncodeRGBStream","numberSamples","tValues","dT","offset","unshift","index","aColor","bColor","round","trim","putShadingPattern","funcObjectNumber","putTilingPattern","deferredResourceDictionaryIds","resourcesObjectId","patternObjectId","resourcesOid","objectOid","putPatterns","putGState","putGStates","gStateKey","putXobjectDict","putEncryptionDict","toHexString","putFontDict","putShadingPatternDict","putTilingPatternDict","putGStatesDict","putResourceDictionary","objectIds","putResources","Number","MAX_SAFE_INTEGER","putAdditionalObjects","addFontToFontDictionary","fontName","addFont","isStandardFont","metadata","instance","addFonts","arrayOfFonts","l","parts","dictionary","SAFE","fn","foo","stack","m","alert","bar","to8bitStream","text","flags","sourceEncoding","encodingBlock","outputEncoding","newtext","isUnicode","ch","bch","autoencode","codePages","noBOM","pdfEscape","beginPage","_setPage","_addPage","parmFormat","parmOrientation","dimensions","min","setLineWidth","lineWidth","strokeColor","lineCapID","lineJoinID","_deletePage","splice","setPage","getNumberOfPages","getFont","fontNameLowerCase","disableWarning","noFallback","putInfo","version","putCatalog","tmpRootDictionaryObjId","pcn","putTrailer","putHeader","putXRef","buildDocument","offsetOfXRef","getBlob","output","filename","save","dataURI","pdfDocument","unescape","encodeURIComponent","pdfObjectUrl","integrity","htmlForNewWindow","JSON","stringify","nW","htmlForPDFjsNewWindow","pdfJsUrl","PDFjsNewWindow","scope","documentElement","querySelector","contentWindow","PDFViewerApplication","htmlForDataURLNewWindow","dataURLNewWindow","hasHotfix","hotfixName","getEncryptor","getPageInfo","pageNumberOneBased","getPageInfoByObjId","getCurrentPageInfo","addPage","insertPage","beforePage","movePage","targetPage","tmpPages","tmpPagesContext","deletePage","transform","payload","da","angle","align","charSpace","maxWidth","horizontalScale","transformationMatrix","tmp","xtra","isHex","lineHeight","lineHeightFactor","ESC","TabLen","transformTextToSpecialArray","curDa","sa","concat","shift","processTextByFunction","processingFunction","tmpResult","textIsOfTypeString","tmpTextIsOfTypeString","match","descent","baseline","splitTextToSize","reduce","acc","textLine","mutex","PI","rotationDirection","cos","sin","activeCharSpace","setCharSpace","getCharSpace","lang","renderingMode","parmRenderingMode","stroke","usedRenderingMode","lineWidths","leading","pageWidth","pageSize","getWidth","activeFont","assign","wordSpacingPerLine","newY","getStringUnitWidth","doKerning","newX","prevWidth","getHorizontalCoordinate","getVerticalCoordinate","doReversing","posX","posY","reverse","activeFontEncoding","STRING","ARRAY","variant","wordSpacing","generatePosition","parmPosX","parmPosY","parmTransformationMatrix","position","lineIndex","textColor","clip","rule","clipEvenOdd","discardPath","isValidStyle","style","setDefaultPathOperation","operator","getStyle","op","close","fill","fillWithOptionalPattern","fillEvenOdd","fillStroke","fillStrokeEvenOdd","fillWithPattern","putStyle","cloneTilingPattern","patternData","patternId","clipRuleFromStyle","setGState","moveTo","lineTo","curveTo","x1","y1","x2","y2","x3","y3","line","lines","closed","scalex","scaley","leg","x4","y4","path","triangle","roundedRect","rx","ry","MyArc","SQRT2","ellipse","lx","ly","circle","setFont","getFontEntry","getFontList","list","encodingOptions","getLineWidth","setLineDash","setLineDashPattern","dashArray","dashPhase","getLineHeight","setLineHeightFactor","getLineHeightFactor","getHorizontalCoordinateString","getVerticalCoordinateString","getStrokeColor","getDrawColor","setStrokeColor","setDrawColor","fillColor","getFillColor","setFillColor","getTextColor","setTextColor","CapJoinStyles","butt","but","miter","rounded","projecting","project","square","bevel","setLineCap","setLineJoin","setLineMiterLimit","setMiterLimit","addGState","equals","duplicate","fontState","setCurrentTransformationMatrix","comment","_x","enumerable","_y","_type","_w","_h","RenderTarget","getPageWidth","setPageWidth","setPageHeight","endFormObject","newXObject","xObjectId","plugin","beginFormObject","doFormObject","getFormObject","returnPromise","unload","Promise","resolve","reject","newEvents","eventname","handler_and_args","getCoordinateString","collections","setWidth","getHeight","setHeight","getPDFVersion","configurable","byteString","byte","bytes","generation","other","ignore","count","jsPDFAPI","pdfUnescape","f5","__acroform__","inherit","child","parent","create","createFormXObject","formObject","xobj","AcroFormXObject","AcroFormAppearance","BBox","setBit","bitPosition","clearBit","getBit","getBitForPdf","setBitForPdf","clearBitForPdf","calculateCoordinates","coordinates","lowerLeft_X","lowerLeft_Y","upperRight_X","upperRight_Y","calculateAppearanceStream","appearanceStreamContent","V","DV","_V","calcRes","calculateX","maxFontSize","returnValue","textSplit","multiline","word","isSmallerThanWidth","lastLine","calculateFontSpace","FontSize","startX","lastLength","textHeight","startY","lastY","firstWordInLine","lastWordInLine","currWord","lineCount","isWithNewLine","nextLineIsSmaller","isLastWord","currLine","textAlign","acroformPluginTemplate","fields","xForms","acroFormDictionaryRoot","printedOut","isInitialized","createAnnotationReference","object","annotations","find","entry","createXFormObjectCallback","fieldArray","fieldObject","initializeAcroForm","acroformPlugin","AcroFormField","FieldNum","parse","AcroFormDictionary","_eventID","AcroFormDictionaryCallback","Fields","hasAnnotation","annotReferenceCallback","putCatalogCallback","standardFields","Kids","keyValueList","oldRect","Rect","DA","createDefaultAppearanceStream","getKeyValueListForStream","hasAppearanceStream","appearance","appearanceStreamString","createFieldCallback","arrayToPdfArray","array","toPdfString","AcroFormPDFObject","_objId","_scope","writable","getOwnPropertyNames","filter","getOwnPropertyDescriptor","_stream","_BBox","_DA","_Kids","_F","Boolean","F","_Ff","_Rect","_FT","_T","AcroFormChildClass","_fontName","_fontStyle","_fontSize","_maxFontSize","_color","AcroFormTextField","_DV","AcroFormButton","_page","_hasAppearanceStream","Ff","_Q","AcroFormChoiceField","FT","_TI","_Opt","regex","matches","getMatches","getOptions","setOptions","sort","addOption","removeOption","allEntries","combo","AcroFormListBox","AcroFormComboBox","AcroFormEditBox","edit","_AS","_MK","CA","AcroFormPushButton","pushButton","AcroFormRadioButton","radio","_parent","_optionName","caption","appearanceState","_AppearanceType","RadioButton","Circle","createAppearanceStream","optionName","setAppearance","getCA","createOption","Parent","addField","AcroFormCheckBox","CheckBox","_MaxLen","isInteger","AcroFormPasswordField","password","N","On","YesNormal","D","YesPushDown","Off","OffPushDown","encodedColor","DotRadius","Bezier_C","DotRadiusBezier","kc","dc","Cross","cross","calculateCross","AcroForm","ChoiceField","ListBox","ComboBox","EditBox","Button","PushButton","TextField","PasswordField","Appearance","toLookup","arr","lookup","__addimage__","UNKNOWN","imageFileTypeHeaders","PNG","TIFF","JPEG","JPEG2000","GIF87a","GIF89a","WEBP","BMP","getImageFileTypeByImageData","imageData","fallbackFormat","headerSchemata","compareResult","fileType","Uint8ClampedArray","isArrayBufferView","putImage","image","colorSpace","color_spaces","INDEXED","palette","sMask","DEVICE_CMYK","bitsPerComponent","decodeParameters","transparency","predictor","arrayBufferToBinaryString","putResourcesCallback","images","putXObjectsDictCallback","initialize","getImages","getImageIndex","isImageTypeSupported","isDOMElement","nodeType","getImageDataFromElement","element","nodeName","hasAttribute","src","getAttribute","tmpImageData","loadFile","mimeType","toDataURL","checkImagesForAlias","alias","determineWidthAndHeight","writeImageToPDF","rotation","dims","coord","vcoord","f4","rotationTransformationMatrix","DEVICE_RGB","DEVICE_GRAY","CAL_GREY","CAL_RGB","LAB","ICC_BASED","PATTERN","SEPARATION","DEVICE_N","decode","DCT_DECODE","FLATE_DECODE","LZW_DECODE","JPX_DECODE","JBIG2_DECODE","ASCII85_DECODE","ASCII_HEX_DECODE","RUN_LENGTH_DECODE","CCITT_FAX_DECODE","image_compression","NONE","FAST","MEDIUM","SLOW","sHashCode","hash","byteLength","validateStringAsBase64","possibleBase64String","extractImageFromDataUrl","dataUrl","dataUrlParts","extractedInfo","charset","supportsArrayBuffer","isArrayBuffer","Uint32Array","Int8Array","Int16Array","Uint16Array","Int32Array","Float32Array","Float64Array","binaryStringToUint8Array","binary_string","buffer","buf","subarray","addImage","compression","processImageData","dataAsBinaryString","convertBase64ToBinaryString","generateAliasFromImageData","checkCompressValue","stringData","throwError","base64Info","rawData","getImageProperties","notEmpty","addPageData","putPageData","anno","pageInfo","pageAnnos","found","escape","objText","objPopup","encryptorText","bounds","contents","loc","_nameMap","top","finalBounds","magFactor","left","createAnnotation","link","textWithLink","linkHeight","linkWidth","totalLineWidth","getTextWidth","numOfLines","ceil","arabicSubstitionA","ligatures","arabic_diacritics","alfletter","__arabicParser__","isInArabicSubstitutionA","isArabicLetter","isArabicEndLetter","isArabicAlfLetter","arabicLetterHasIsolatedForm","arabicLetterHasFinalForm","arabicLetterHasInitialForm","arabicLetterHasMedialForm","resolveLigatures","letters","tmpLigatures","effectedLetters","isArabicDiacritic","getCorrectForm","currentChar","beforeChar","nextChar","parseArabic","currentLetter","prevLetter","nextLetter","words","newWords","processArabic","tmpText","autoPrint","refAutoPrintTag","addJS","Canvas","jsPdfInstance","_width","getContext","pageWrapXEnabled","pageWrapX","_height","pageWrapYEnabled","pageWrapY","_childNodes","_style","contextType","contextAttributes","pdf","context2d","_canvas","canvas","NO_MARGINS","bottom","right","printingHeaderRow","_initialize","__cell__","headerFunction","margins","_reset","lastCell","Cell","_text","_lineNumber","_align","lineNumber","toArray","setHeaderFunction","func","getTextDimensions","amountOfLines","tempWidth","max","cellAddPage","cell","currentCell","tableHeaderRow","printHeaders","printHeaderRow","table","headers","config","column","headerName","headerNames","headerLabels","headerAligns","columnMatrix","columnWidths","columnMinWidths","tableHeaderConfigs","autoSize","css","headerBackgroundColor","headerTextColor","table_font_size","header","prompt","rec","row","rowHeight","calculateLineHeight","setTableHeaderRow","pv","cv","rowStart","Function","cellData","cellStart","col","table_x","table_y","model","new_page","tableHeaderCell","tempHeaderConf","currentTextColor","fontStyleOrder","italic","oblique","normal","fontStretchOrder","fontStretchLookup","fontWeights","fontWeightsLookup","normalizeFontFace","fontFace","family","normalizeFontStyle","weight","normalizeFontWeight","stretch","normalizeFontStretch","ref","searchFromPivot","matchingSet","order","pivot","dir","defaultGenericFontFamilies","fixed","monospace","terminal","cursive","fantasy","serif","systemFonts","icon","menu","ruleToString","resolveFontFace","fontFaceMap","rules","defaultFontFamily","genericFontFamilies","resolveFontStretch","ordering","resolveFontStyle","resolveFontWeight","eatWhiteSpace","input","trimLeft","parseQuotedFontFamily","quote","parseNonQuotedFontFamily","defaultFont","_ctx","ContextLayer","ctx","isStrokeTransparent","strokeOpacity","strokeStyle","fillStyle","isFillTransparent","fillOpacity","textBaseline","lineJoin","lineCap","globalCompositeOperation","globalAlpha","clip_path","currentPoint","miterLimit","lastPoint","lineDashOffset","lineDash","margin","prevPageLastElemOffset","ignoreClearRect","Context2D","parentNode","_pdf","_pageWrapXEnabled","_pageWrapYEnabled","_posX","_posY","_autoPaging","lastBreak","pageBreaks","_ctxStack","rgba","getRGBA","_fontFaceMap","getFontFaceMap","fontFaces","convertedFontFaces","fontMap","convertToFontFaces","normalized","buildFontFaceMap","_fontFaces","fontFamily","fontSizeUnit","parsed","remaining","parseFontFamily","jsPdfFontName","fallbackFonts","arial","Arial","verdana","Verdana","helvetica","Helvetica","getLineDash","pathPreProcess","beginPath","closePath","pathBegin","quadraticCurveTo","cpx","cpy","pt0","bezierCurveTo","cp1x","cp1y","cp2x","cp2y","arc","radius","startAngle","endAngle","counterclockwise","isIdentity","xpt","x_radPt","x_radPt0","pow","arcTo","fillRect","strokeRect","clearRect","doStackPush","tmpPageNumber","ctxStack","doStackPop","isCanvasGradient","getColor","fillText","degs","rad2deg","putText","strokeText","measureText","txtWidth","TextMetrics","scalewidth","scaleheight","setTransform","hasMargins","drawImage","img","swidth","sheight","imageProperties","factorX","factorY","clipFactorX","clipFactorY","clipPath","decomposedTransformationMatrix","xRect","pageArray","getPagesByPath","sortPages","autoPaging","pageWidthMinusMargins","topMargin","firstPageHeight","pageHeightMinusMargins","previousPageHeightSum","tmpPaths","pathPositionRedo","drawPaths","tmpRect","needsClipping","yOffset","rectOfQuadraticCurve","getQuadraticCurveBoundary","rectOfBezierCurve","getBezierCurveBoundary","paths","isClip","tmpPath","oldLineWidth","origPath","xPath","delta","moves","begin","start","deltas","iii","began","arcs","drawArc","drawLine","drawLines","doClip","getBaseline","getTextBottom","yBaseLine","createLinearGradient","canvasGradient","colorStops","addColorStop","createPattern","createRadialGradient","includeMove","curves","createArc","curve","doMove","drawCurve","textDimensions","yTop","oldSize","baselineRect","textBounds","pageHeightMinusBottomMargin","pageWidthMinusRightMargin","textBoundsOnPage","doSlice","croppedText","baseLineRectOnPage","prevX","prevY","anticlockwise","twoPi","halfPi","totalAngle","sgn","createSmallArc","q1","q2","k2","ar","cos_ar","sin_ar","ey","midX1","midY1","midX2","midY2","resultX1","resultX2","resultY1","resultY2","ax","ay","bx","by","cx","cy","dx","dy","px","py","qx","qy","minx","miny","maxx","maxy","tobx","toby","tocx","tocy","todx","tody","prevLineDash","nextLineDash","require","Worker","u16","u32","fleb","fdeb","clim","freb","eb","_a","fl","revfl","_b","fd","revfd","rev","hMap","cd","mb","co","le","rvb","sv","r_1","flt","fdt","flm","flrm","fdm","fdrm","o","bits16","shft","slc","wbits","wbits16","hTree","t2","i0","i1","i2","maxSym","tr","mbt","ln","dt","lft","cst","i2_1","i2_2","i2_3","lc","cl","cli","cln","cls","clen","cf","wfblk","pos","dat","wblk","final","syms","lf","df","li","bs","bl","dlt","mlb","ddt","mdb","_c","lclt","nlc","_d","lcdt","ndc","lcfreq","_e","lct","mlcb","nlcc","lm","ll","dm","flen","ftlen","dtlen","llm","lcts","it","clct","dst","deo","et","dopt","opt","pre","post","st","lvl","plvl","lst","msk_1","prev","head","bs1_1","bs2_1","hsh","lc_1","wi","hv","imod","pimod","rem","ch_1","dif","maxn","maxd","ml","nl","mmd","md","ti","lin","din","dflt","level","mem","zlibSync","adler","lv","zlh","wbytes","unzlibSync","sl","noBuf","noSt","cbuf","nbuf","bt","lbt","dbt","tbts","hLit","hcLen","tl","ldt","clt","clb","clbmsk","clm","lt","lms","dms","mxa","sym","add","dsym","end","inflt","zlv","ASCII85Encode","ASCII85Decode","z","ASCIIHexDecode","regexCheckIfHex","RegExp","FlateEncode","origData","filterChain","sync","request","sanitizeUnicode","dataLength","charArray","StringFromCharCode","overrideMimeType","responseText","browserRequest","loadImageFile","loadHtml2Canvas","catch","then","html2canvas","default","loadDomPurify","dompurify","objType","tagName","el","className","innerHTML","sanitize","cloneNode","javascriptEnabled","createTextNode","nodeValue","firstChild","nextSibling","appendChild","addEventListener","scrollTop","scrollLeft","root","convert","template","setProgress","promise","__proto__","prop","container","overlay","progress","val","enableLinks","backgroundColor","from","getType","to","toContainer","toCanvas","toImg","toPdf","thenList","setPageSize","containerCSS","display","windowWidth","clientWidth","scrollWidth","offsetWidth","source","scrollHeight","offsetHeight","clientHeight","overflow","zIndex","clear","border","float","prereqs","contains","onrendered","removeChild","toContext2d","async","allowTaint","scrollX","scrollY","imageTimeout","logging","proxy","removeContainer","foreignObjectRendering","useCORS","windowHeight","imgData","quality","outputImg","outputPdf","doCallback","fns","setMargin","cbk","toPx","getPageSize","inner","ratio","updateProgress","onFulfilled","onRejected","thenCore","thenBase","selfPromise","returnVal","thenExternal","catchExternal","msg","using","export","run","format_as_string","pageHeight","err","html","worker","jsNamesObj","jsJsObj","javascript","namesOid","outline","children","render","createNamedDestinations","totalPages","dests","info","names2Oid","makeRef","item","genIds_r","renderRoot","renderItems","objStart","count_r","objEnd","makeString","markers","processJPEG","blockLength","numcomponents","getJpegInfo","getCharWidthsArray","splitLongWord","splitParagraphIntoLines","makeImage","scratchCanvas","scratchCtx","chunkSize","palLen","delayDen","delayNum","frame","section","palShort","_i","_j","_ref","animation","readUInt32","_results","colorType","compressionMethod","filterMethod","interlaceMethod","numFrames","numPlays","Infinity","frames","read","xOffset","readUInt16","delay","disposeOp","blendOp","indexed","grayscale","rgb","hasAlphaChannel","pixelBitlength","decodePixels","pixelBytes","fullPixels","_this","pass","x0","y0","abyte","pa","paeth","pb","pc","pixels","scanlineLength","upper","upperLeft","_k","_l","_m","isFull","fullPos","partPos","decodePalette","ret","_ref1","copyToImageData","alpha","_decodedPalette","hasBrowserCanvas","putImageData","Image","decodeFrames","_len","createImageData","renderFrame","animate","_doFrame","frameNumber","_timeout","stopAnimation","clearTimeout","_png","GifReader","pf0","global_palette_flag","num_global_colors","global_palette_offset","global_palette_size","no_eof","transparent_index","disposal","loop_count","block_size","pf1","pf2","interlace_flag","num_local_colors","palette_offset","palette_size","has_local_palette","data_offset","data_length","interlaced","loopCount","frameInfo","frame_num","decodeAndBlitFrameBGRA","num_pixels","index_stream","GifReaderLZWOutputIndexStream","trans","framewidth","framestride","xleft","opbeg","opend","scanstride","interlaceskip","il","decodeAndBlitFrameRGBA","code_stream","output_length","min_code_size","clear_code","eoi_code","next_code","cur_code_size","code_mask","cur_shift","cur","subblock_size","code_table","prev_code","code","chase_code","chase_length","chase","JPEGEncoder","YDC_HT","UVDC_HT","YAC_HT","UVAC_HT","currentQuality","ffloor","YTable","UVTable","fdtbl_Y","fdtbl_UV","bitcode","category","outputfDCTQuant","DU","byteout","bytenew","bytepos","YDU","UDU","VDU","RGB_YUV_TABLE","ZigZag","std_dc_luminance_nrcodes","std_dc_luminance_values","std_ac_luminance_nrcodes","std_ac_luminance_values","std_dc_chrominance_nrcodes","std_dc_chrominance_values","std_ac_chrominance_nrcodes","std_ac_chrominance_values","computeHuffmanTbl","nrcodes","std_table","codevalue","pos_in_table","HT","writeBits","posval","writeByte","writeWord","processDU","CDU","fdtbl","DC","HTDC","HTAC","EOB","M16zeroes","DU_DCT","d0","d1","d2","d3","d4","d5","d6","d7","fDCTQuant","dataOff","tmp0","tmp7","tmp1","tmp6","tmp2","tmp5","tmp3","tmp4","tmp10","tmp13","tmp11","tmp12","z1","z5","z2","z4","z3","z11","z13","tmp0p2","tmp7p2","tmp1p2","tmp6p2","tmp2p2","tmp5p2","tmp3p2","tmp4p2","tmp10p2","tmp13p2","tmp11p2","tmp12p2","z1p2","z5p2","z2p2","z4p2","z3p2","z11p2","z13p2","Diff","end0pos","lng","startpos","nrzeroes","nrmarker","setQuality","sf","YQT","UVQT","u","aasf","initQuantTables","encode","writeDQT","writeSOF0","writeDHT","DCY","DCU","DCV","displayName","quadWidth","fillbits","sfcc","initCharLookupTable","nrlower","nrupper","cat","nr","nrneg","initCategoryNumber","initRGBYUVTable","BmpDecoder","is_with_alpha","datav","DataView","bottom_up","flag","parseHeader","parseBGR","WebPDecoder","fa","L","J","H","I","Z","M","wa","Ed","ma","_WebPDecoder","Fd","Ub","G","jc","Qb","qb","nd","pd","xb","Ca","Ka","oa","Jd","Yc","Zc","Qa","na","K","ca","cb","Sb","Ra","bb","Vb","ob","db","Gd","Hd","Wb","Sa","Xb","Id","ra","Ta","Yb","Ha","Zb","X","Mb","Xa","$b","ac","bc","xa","yb","ud","hd","jd","aa","Ia","cc","Kd","Ld","ec","Ea","Md","Nd","Od","Pd","Qd","fb","gb","hb","zb","Ab","Ja","Bb","Rd","A","Sd","ea","Tc","Cd","lb","Db","W","Cb","S","RGBA","kb","sd","Td","Ud","ib","bd","Da","Vd","T","Wd","ba","ka","Mc","Nc","fc","Rc","Xd","ya","Kb","za","gc","Ua","Va","memory","Ib","Jb","hc","Oa","ic","Aa","Yd","Ba","Wa","Zd","$d","ae","ta","Eb","be","ga","ce","Dc","mc","nc","de","ua","ub","ha","xc","vc","Ya","oc","C","ee","E","B","Q","fe","qc","Fb","rc","ge","va","Ma","sc","Gb","tc","uc","Hb","wc","yc","zc","qd","rd","ia","tb","he","$","Pb","wd","xd","vb","ie","Ac","Bc","je","Cc","VP8LMapColor32b","ke","VP8LMapColor8b","rb","Oc","R","me","qa","Y","la","ja","Fa","ne","sb","La","Za","$a","jb","oe","pe","nb","qe","Pa","Ga","Na","Ec","se","Fc","ue","yd","td","Rb","ve","we","Lb","Gc","wb","xe","Wc","Xc","ye","Pc","Tb","zd","vd","od","ld","dd","Hc","ze","Sc","Qc","ad","Ob","Ad","Dd","Ae","Nb","Ic","Be","Kc","ed","$c","Jc","Bd","gd","Uc","Vc","put","Ce","De","Ee","Fe","Ge","He","Ie","Lc","Me","Ne","Oe","Pe","Qe","Re","Se","Te","Ue","Ve","We","Xe","Ye","Ze","$e","af","bf","ef","gf","hf","jf","kf","mf","nf","of","pf","qf","rf","tf","uf","vf","wf","xf","yf","zf","Af","Bf","Ke","Le","Je","kd","Cf","Df","Ef","Gf","Hf","If","Jf","Kf","Lf","Mf","Nf","Of","Pf","Predictor0","Predictor1","Predictor2","Predictor3","Predictor4","Predictor5","Predictor6","Predictor7","Predictor8","Predictor9","Predictor10","Predictor11","Predictor12","Predictor13","PredictorAdd0","PredictorAdd1","PredictorAdd2","ColorIndexInverseTransform","MapARGB","VP8LColorIndexInverseTransformAlpha","MapAlpha","VP8LPredictorsAdd","VP8LPredictors","VP8LPredictorsAdd_C","VP8LPredictors_C","UpsampleRgbLinePair","UpsampleBgrLinePair","UpsampleRgbaLinePair","UpsampleBgraLinePair","UpsampleArgbLinePair","UpsampleRgba4444LinePair","UpsampleRgb565LinePair","Qf","WebPDecodeRGBA","te","GetTag","data_off","GetLE24","GetLE32","webpdecoder","imagearray","src_off","alpha_chunk","alpha_size","alpha_offset","memcmp","fourcc","payload_size","payload_size_padded","src_off_","temp","WebPRiffParser","hasCompressionJS","compressBytes","lineLength","colorsPerPixel","filter_method","filterUp","filterSub","filterAverage","filterPaeth","applyPngFilterMethod","prevLine","filter_methods","getFilterMethods","results","ind","getIndexOfSmallestSum","filterNone","up","upLeft","paethPredictor","pLeft","pUp","pUpLeft","arrays","sum","processPNG","trns","pal","smask","alphaData","hasColors","pixel","pbl","pDiff","total","getPredictorFromCompression","processGIF89A","rawImageData","processGIF87A","fileSize","getUint32","reserved","headerSize","getInt32","planes","getUint16","bitPP","rawSize","hr","vr","importantColors","getUint8","quad","bitn","bit1","xlen","mode","bit4","before","after","bit8","bit15","dif_w","_1_5","bit16","_1_6","bit24","bit32","getData","processBMP","processWEBP","processRGBA","imagePixels","rgbOut","alphaOut","outIndex","alphaIndex","rgbData","setLanguage","langCode","languageSettings","isSubscribed","sq","an","hy","as","ast","az","eu","bn","br","bg","my","zh","cr","cs","en","eo","fo","fj","fi","fr","fy","fur","gl","gu","ht","hi","hu","is","iu","kn","ks","kk","km","ky","tlh","ko","mk","ms","mt","mi","mr","mo","nv","ng","no","nn","or","om","pl","qu","rm","ro","ru","sz","sg","si","sr","sk","so","es","sw","tt","th","tig","ts","tn","tk","uk","hsb","ur","vi","vo","xh","ji","zu","languageCode","char_code","widths","Unicode","widthsFractionOf","fof","kerning","kerningFractionOf","kerningValue","prior_char_code","default_char_width","widthOfString","widthOfGlyph","characterToGlyph","widths_array","firstLineMaxLen","maxLen","answer","workingLen","startOfLine","maxlen","lineIndent","postProcess","line_length","textIndent","separator_length","current_word_length","spaceCharWidth","pad","wrds","wrd","idx","paragraphs","fsize","newOptions","fontUnit_maxLen","__fontmetrics__","encoded","mappingUncompress","mappingCompress","keystring","valuestring","numberprefix","vals","uncompress","stringparts","parent_key_pair","sign","activeobject","parentchain","keyparts","valueparts","datalen","WinAnsiEncoding","encodings","Courier","fontMetrics","ZapfDingbats","metrics","file","existsFileInVFS","getFileFromVFS","TTFFont","glyIdsUsed","loadCanvg","canvg","addSvgAsImage","svg","ignoreMouse","ignoreAnimation","ignoreDimensions","doc","fromString","putTotalPages","pageExpression","replaceExpression","totalNumberOfPages","pdfEscape16","viewerPreferences","doReset","configuration","isValid","method","configurationTemplate","HideToolbar","defaultValue","explicitSet","valueSet","HideMenubar","HideWindowUI","FitWindow","CenterWindow","DisplayDocTitle","NonFullScreenPageMode","Direction","ViewArea","ViewClip","PrintArea","PrintClip","PrintScaling","Duplex","PickTrayByPDFSize","PrintPageRange","NumCopies","configurationKeys","rangeArray","arrayContainsElement","viewerpreferences","vPref","pdfDict","postPutResources","rdf_beginning","__metadata__","namespaceuri","utf8_xmpmeta_beginning","utf8_rdf_beginning","utf8_metadata","utf8_rdf_ending","utf8_xmpmeta_ending","total_len","metadata_object_number","addMetadata","padz","toUnicode","toUnicodeCmap","codes","range","unicode","unicodeMap","pdfOutput","subset","pdfOutput2","fontTable","cmap","fontDescriptor","PDFObject","bbox","stemV","italicAngle","ascender","decender","capHeight","DescendantFont","identityHFunction","hmtx","unitsPerEm","winAnsiEncodingFunction","utf8TextFunction","cmapConfirm","strText","codeMap","parms","_initializeVFS","vFS","addFileToVFS","filecontent","__bidiEngine__","_hasUbatB","_hasUbatS","_isInVisual","_isInRtl","_isOutVisual","_isOutRtl","_isSymmetricSwapping","_UNICODE_TYPES","_bidiUnicodeTypes","_STATE_TABLE_LTR","_STATE_TABLE_RTL","_TYPE_NAMES_MAP","EN","AN","_UNICODE_RANGES_MAP","_SWAP_TABLE","_LTR_RANGES_REG_EXPR","_lastArabic","_dir","_getCharType","rangeIdx","_isContextualDirRtl","charType","_resolveCharType","chars","types","resolvedTypes","wType","nType","cType","rtlCandidate","_invertString","sourceToTargetMap","levels","_computeLevels","hiLevel","params","action","newLevel","prevState","condPos","newState","stateTable","_handleUbatS","_invertByLevel","high","low","_reorder","_symmetricSwap","DIR_RTL","doBidiReorder","_init","isSymmetricSwappingOrig","isInputVisual","isOutputVisual","isInputRtl","isOutputRtl","isSymmetricSwapping","bidiEngine","Data","readString","Subset","registerTTF","directory","Directory","HeadTable","NameTable","CmapTable","hhea","HheaTable","maxp","MaxpTable","HmtxTable","PostTable","os2","OS2Table","loca","LocaTable","glyf","GlyfTable","exists","lineGap","xMin","yMin","xMax","yMax","raw","italic_angle","xHeight","familyClass","isSerif","isScript","isFixedPitch","character","glyph","forGlyph","advance","includeGap","gap","Table","readByte","writeUInt32","readInt32","int","writeInt32","writeUInt16","readInt16","writeInt16","writeString","readShort","writeShort","readLongLong","writeLongLong","readInt","writeInt","checksum","scalarType","tableCount","searchRange","entrySelector","rangeShift","tables","tag","adjustment","directoryLength","headOffset","log2","tableData","__slice","__hasProp","__extends","ctor","__super__","_super","revision","checkSumAdjustment","magicNumber","created","modified","macStyle","lowestRecPPEM","fontDirectionHint","indexToLocFormat","glyphDataFormat","CmapEntry","endCode","glyphId","glyphIds","idDelta","idRangeOffset","saveOffset","segCount","segCountX2","startCode","platformID","encodingID","language","charmap","charMap","diff","endCodes","glyphIDs","indexes","last","nextID","old","rangeOffsets","startCodes","startGlyph","subtable","_len1","_len2","_len3","_len4","_len5","_len6","_len7","_n","_name","_o","_p","_q","new","maxGlyphID","LN2","advanceWidthMax","minLeftSideBearing","minRightSideBearing","xMaxExtent","caretSlopeRise","caretSlopeRun","caretOffset","metricDataFormat","numberOfMetrics","averageCharWidth","weightClass","widthClass","ySubscriptXSize","ySubscriptYSize","ySubscriptXOffset","ySubscriptYOffset","ySuperscriptXSize","ySuperscriptYSize","ySuperscriptXOffset","ySuperscriptYOffset","yStrikeoutSize","yStrikeoutPosition","panose","charRange","vendorID","selection","firstCharIndex","lastCharIndex","ascent","winAscent","winDescent","codePageRange","defaultChar","breakChar","maxContext","numberOfGlyphs","underlinePosition","underlineThickness","minMemType42","maxMemType42","minMemType1","maxMemType1","glyphNameIndex","names","_results1","numGlyphs","NameEntry","languageID","entries","stringOffset","strings","nameID","copyright","fontSubfamily","uniqueSubfamily","postscriptName","trademark","manufacturer","designer","description","vendorUrl","designerUrl","license","licenseUrl","preferredFamily","preferredSubfamily","compatibleFull","sampleText","maxPoints","maxContours","maxCompositePoints","maxComponentContours","maxZones","maxTwilightPoints","maxStorage","maxFunctionDefs","maxInstructionDefs","maxStackElements","maxSizeOfInstructions","maxComponentElements","maxComponentDepth","lsbCount","lsb","leftSideBearings","cache","glyphFor","numberOfContours","lengthOf","CompoundGlyph","SimpleGlyph","glyphs","mapping","old2new","compound","glyphOffsets","activeGlyphs","glyfPtr","listGlyf","newLocaTable","unicodes","next","generateCmap","roman","unicodeCmap","glyphsFor","additionalIDs","glyID","ids","new2old","newIDs","nextGlyphID","oldID","oldIDs","invert","isString","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","getUTCSeconds"],"mappings":"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AAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KACthBlK,GAAK,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAChjB3B,GAAK,KACLqO,GAAK,CAAC,CAAC,IAAK,IAAK,IAAK,GAAI,CAAC,IAAK,IAAK,IAAK,IAAK,GAAI,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IACzIC,GAAK,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GAAI,GAAI,GAAI,EAAG,GAAI,GAAI,IACxDtJ,GAAK,EAAE,EAAG,GAAI,EAAG,GAAI,EAAG,EAAG,EAAG,GAAI,EAAG,GAAI,GAAI,GAAI,EAAG,GAAI,EAAG,GAAI,GAAI,GACnEmJ,GAAK,CAAC,CAAC,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,OAAQ,CAAC,CAAC,CAAC,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,CAAC,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,OAAQ,CAAC,CAAC,CAAC,IAAK,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,OAAQ,CAAC,CAAC,CAAC,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,EAAG,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,EAAG,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,QACryK0C,GAAK,CAAC,CAAC,CAAC,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,IAAK,CAAC,IAAK,GAAI,IAAK,GAAI,GAAI,GAAI,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,KAAM,CAAC,IAAK,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,GAAI,KAAM,CAAC,IAAK,GAAI,GAAI,IAAK,GAAI,GAAI,GAAI,GAAI,IAAK,CAAC,IAAK,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,CAAC,IAAK,GAAI,GAAI,GAAI,IAAK,IAAK,GAAI,IAAK,IAAK,CAAC,GAAI,GAAI,EAAG,IAAK,IAAK,IAAK,GAAI,EAAG,KAAM,CAAC,GAAI,GAAI,GAAI,GAAI,IAAK,GAAI,GAAI,GAAI,KAAM,CAAC,CAAC,IAAK,IAAK,GAAI,IAAK,GAAI,IAAK,IAAK,IAAK,KAAM,CAAC,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,GAAI,GAAI,IAAK,CAAC,GAAI,IAAK,IAAK,GAAI,GAAI,GAAI,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,EAAG,IAAK,IAAK,IAAK,GAAI,EAAG,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,GAAI,IAAK,KAAM,CAAC,IAAK,GAAI,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,GAAI,CAAC,GAAI,GAAI,GAAI,GAAI,IAAK,GAAI,GAAI,IAAK,IAAK,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,KAAM,CAAC,CAAC,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,GAAI,IAAK,IAAK,CAAC,GAAI,GAAI,IAAK,GAAI,GAAI,GAAI,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,IAAK,CAAC,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,GAAI,IAAK,CAAC,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,GAAI,IAAK,IAAK,CAAC,IAAK,GAAI,GAAI,GAAI,GAAI,EAAG,GAAI,GAAI,IAAK,CAAC,GAAI,GAAI,IAAK,GAAI,GAAI,IAAK,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,KAAM,CAAC,CAAC,IAAK,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,KAAM,CAAC,IAAK,IAAK,GAAI,GAAI,IAAK,IAAK,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,EAAG,IAAK,IAAK,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,GAAI,GAAI,GAAI,EAAG,KAAM,CAAC,IAAK,GAAI,EAAG,GAAI,IAAK,EAAG,GAAI,GAAI,IAAK,CAAC,IAAK,GAAI,GAAI,GAAI,IAAK,IAAK,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,EAAG,IAAK,IAAK,IAAK,EAAG,EAAG,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,KAAM,CAAC,CAAC,IAAK,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,EAAG,GAAI,GAAI,GAAI,KAAM,CAAC,GAAI,GAAI,GAAI,GAAI,IAAK,EAAG,GAAI,GAAI,IAAK,CAAC,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,IAAK,KAAM,CAAC,GAAI,EAAG,EAAG,IAAK,GAAI,IAAK,GAAI,EAAG,KAAM,CAAC,GAAI,GAAI,EAAG,IAAK,GAAI,GAAI,GAAI,GAAI,KAAM,CAAC,CAAC,IAAK,GAAI,GAAI,IAAK,EAAG,GAAI,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,GAAI,GAAI,GAAI,GAAI,IAAK,CAAC,GAAI,GAAI,IAAK,IAAK,EAAG,GAAI,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,EAAG,GAAI,IAAK,EAAG,GAAI,EAAG,IAAK,IAAK,CAAC,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,CAAC,GAAI,GAAI,GAAI,GAAI,IAAK,GAAI,GAAI,IAAK,IAAK,CAAC,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,EAAG,GAAI,KAAM,CAAC,CAAC,IAAK,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,IAAK,IAAK,CAAC,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,CAAC,GAAI,GAAI,IAAK,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,CAAC,GAAI,GAAI,EAAG,GAAI,IAAK,GAAI,GAAI,GAAI,IAAK,CAAC,GAAI,GAAI,GAAI,IAAK,GAAI,GAAI,GAAI,EAAG,IAAK,CAAC,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,GAAI,KAAM,CAAC,IAAK,GAAI,EAAG,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,CAAC,IAAK,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,IAAK,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,IAAK,CAAC,IAAK,GAAI,GAAI,GAAI,IAAK,IAAK,GAAI,EAAG,KAAM,CAAC,CAAC,IAAK,GAAI,GAAI,GAAI,GAAI,GAAI,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,IAAK,CAAC,GAAI,GAAI,IAAK,GAAI,EAAG,GAAI,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,GAAI,GAAI,IAAK,GAAI,GAAI,GAAI,IAAK,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,GAAI,CAAC,GAAI,EAAG,GAAI,IAAK,GAAI,GAAI,GAAI,IAAK,IAAK,CAAC,GAAI,GAAI,EAAG,EAAG,GAAI,IAAK,IAAK,IAAK,IAAK,CAAC,GAAI,EAAG,GAAI,EAAG,GAAI,IAAK,GAAI,IAAK,GAAI,CAAC,GAAI,EAAG,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,GAAI,GAAI,IAAK,GAAI,GAAI,IAAK,KAAM,CAAC,CAAC,IAAK,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,KAAM,CAAC,GAAI,IAAK,GAAI,IAAK,IAAK,IAAK,GAAI,EAAG,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,EAAG,KAAM,CAAC,GAAI,GAAI,GAAI,GAAI,GAAI,IAAK,EAAG,EAAG,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,CAAC,GAAI,GAAI,GAAI,GAAI,IAAK,IAAK,GAAI,IAAK,KAAM,CAAC,GAAI,GAAI,EAAG,GAAI,IAAK,IAAK,EAAG,EAAG,KAAM,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,MAAO,CAAC,CAAC,IAAK,GAAI,GAAI,GAAI,IAAK,GAAI,IAAK,GAAI,IAAK,CAAC,GAAI,IAAK,GAAI,GAAI,IAAK,GAAI,GAAI,GAAI,IAAK,CAAC,IAAK,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,EAAG,IAAK,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,KAAM,CAAC,IAAK,GAAI,GAAI,IAAK,GAAI,GAAI,GAAI,GAAI,KAAM,CAAC,IAAK,GAAI,GAAI,GAAI,IAAK,IAAK,GAAI,GAAI,IAAK,CAAC,IAAK,GAAI,GAAI,GAAI,IAAK,EAAG,GAAI,IAAK,IAAK,CAAC,GAAI,GAAI,GAAI,IAAK,IAAK,IAAK,GAAI,GAAI,KAAM,CAAC,IAAK,GAAI,GAAI,GAAI,IAAK,IAAK,GAAI,EAAG,MACrgI3C,GAAK,CAAC,CAAC,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,OAAQ,CAAC,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,OAAQ,CAAC,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,OAAQ,CAAC,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,CAAC,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,QACt6KE,GAAK,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GAEtDjE,EAAI,GACJnG,EAAI,GACJe,GAAK,GAkBL/rE,GAAK,EACL0wE,GAAK,EACLZ,GAAK,GAKLhrE,EAAI,GACRoqE,GAAG,sBAAuBgD,GAAI,GAC9BhD,GAAG,sBAAuBmE,GAAI,GAC9BnE,GAAG,uBAAwBiB,GAAI,GAC/BjB,GAAG,uBAAwBqE,GAAI,GAC/BrE,GAAG,uBAAwBhG,GAAI,GAC/BgG,GAAG,2BAA4BuD,GAAI,GACnCvD,GAAG,yBAA0B7D,GAAI,OAC7BqN,GAAKtnF,KAAKmpF,oBACV5B,GAAKvnF,KAAKopF,oBACV7T,GAAKv1E,KAAKqpF,qBACVjH,GAAKpiF,KAAKspF,qBACV9T,GAAKx1E,KAAKupF,qBACV/K,GAAKx+E,KAAKwpF,yBACVhC,GAAKxnF,KAAKypF,uBACVzN,GAAK,GACLD,GAAK,GAAKC,GAAK,EACfI,IAAM,IACNC,GAAK,IACLoC,GAAK,EACLgJ,IAAM,KAAOhJ,IAAM,EACnBrJ,GAAK,EACL0G,GAAK/4C,EAAE,KACPo5C,GAAKp5C,EAAE,KACPm5C,GAAKn5C,EAAE,KACPk5C,GAAKl5C,EAAE,KACPu5C,GAAKv5C,EAAEs5C,GAAKD,IACZI,GAAKz5C,EAAEs5C,GAAKD,IAChB4D,GAAG,cAAec,GAAI,GACtBd,GAAG,cAAeiC,GAAI,GACtBjC,GAAG,eAAgBjB,GAAI,GACvBiB,GAAG,eAAgBmC,GAAI,GACvBnC,GAAG,eAAgBlI,GAAI,GACvBkI,GAAG,mBAAoBqB,GAAI,GAC3BrB,GAAG,iBAAkB/F,GAAI,OACrBiI,GAAK,CAAC,EAAG,EAAG,EAAG,GAAI,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAC1EhF,GAAK,CAAC,EAAG,EAAG,GACZwM,GAAK,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GACvCrF,GAAK,OAEJsF,eAAiB,SAAUzmF,EAAGqM,EAAGQ,EAAGC,EAAG9N,OACtC2iB,EAAIw2D,GACJ/rE,EAAI,IAAIu3E,GACR1gE,EAAI,IAAI0zD,GACZvqE,EAAEorE,GAAKv0D,EACPA,EAAE2zD,EAAIj1D,EACNsB,EAAEgF,MAAQ,CAAChF,EAAEgF,OACbhF,EAAEiF,OAAS,CAACjF,EAAEiF,YACVtb,EAAIqW,EAAEgF,MACNgD,EAAIhI,EAAEiF,OACNsD,EAAI,IAAIwrD,MACR,MAAQxrD,GAAK,MAAQxrB,EAAG,IAAIyN,EAAI,OAAOd,EAAE,MAAQ6e,GAAI/d,EAAIkyE,GAAG3/E,EAAGqM,EAAGQ,EAAG2e,EAAEvD,MAAOuD,EAAEtD,OAAQsD,EAAEiqD,GAAIjqD,EAAEkqD,GAAIlqD,EAAEzX,OAAQ,YAC7GtG,EAAIb,EAAI,GAAK,MAAQA,IAAMA,EAAE,GAAK4e,EAAEvD,MAAM,IAAK,MAAQgD,IAAMA,EAAE,GAAKO,EAAEtD,OAAO,IAAKtb,EAAI,GAEvFA,EAAG,CACLqW,EAAEgF,MAAQhF,EAAEgF,MAAM,GAClBhF,EAAEiF,OAASjF,EAAEiF,OAAO,SACZpb,IAAMA,EAAE,GAAKmW,EAAEgF,aACfjpB,IAAMA,EAAE,GAAKikB,EAAEiF,QAEvB7b,EAAG,IACDS,EAAI,IAAI2rE,IACRz5E,EAAI,IAAIm1D,IACNplD,KAAO/O,EACThB,EAAEgkB,EAAI3W,EACNrN,EAAE66E,GAAKhtE,EACP7N,EAAE0kF,GAAK,EACPr3E,EAAI,CAAC,GACLM,EAAE,MAAQ3N,IAET,IADDgB,EAAI2/E,GAAG3gF,EAAE+P,KAAM/P,EAAEgkB,EAAGhkB,EAAE66E,GAAI,KAAM,KAAM,KAAMxtE,EAAG,KAAMrN,KAC1C,GAAKgB,IAAMqM,EAAE,KAAOrM,EAAI,GAG/B,IAFJqM,EAAIrM,GAEQ,IACV2M,EAAE,MAAQP,GACVU,EAAEiC,KAAO/P,EAAE+P,KACXjC,EAAEkW,EAAIhkB,EAAEgkB,EAAIhkB,EAAEypB,OACd3b,EAAE+sE,GAAK76E,EAAE66E,GAAK76E,EAAEypB,OAChB3b,EAAE2zE,IAAMh3C,GACR38B,EAAE0nE,GAAK0D,GACPprE,EAAE2nE,GAAK/kB,GACP5iD,EAAE+kE,GAAKzlE,EAEHpN,EAAE01E,GAAI,IAGJ,OAFJ10E,EAAIk8E,MAEW,CACb9vE,EAAI,QACEC,cA7jFNrM,EAAGqM,OACTQ,EAAI,CAAC,GACLC,EAAI,CAAC,GACL9N,EAAI,CAAC,GAETgB,EAAG,OAAS,IACN,MAAQA,EAAG,OAAO,KAClB,MAAQqM,EAAG,OAAOrM,EAAEA,EAAI,EAAG,KAC/BA,EAAEirB,EAAI5e,EACNrM,EAAEA,EAAI,EACNkzE,GAAGlzE,EAAEwrB,EAAGnf,EAAE0C,KAAM1C,EAAE2W,EAAG3W,EAAEwtE,KAElBL,GAAGx5E,EAAEwrB,EAAG3e,EAAGC,EAAG9N,GAAI,CACrBgB,EAAEA,EAAI,QACAA,KAGRA,EAAEuyE,GAAK6J,GACP/vE,EAAE4b,MAAQpb,EAAE,GACZR,EAAE6b,OAASpb,EAAE,IACR0vE,GAAG3vE,EAAE,GAAIC,EAAE,GAAI,EAAG9M,EAAG,MAAO,MAAMA,SAChC,SAGT2M,EAAE,GAAK3M,EAAEA,GACF,EAuiFK0mF,CAAG1mF,EAAG8M,GAAI,IAGRA,EAAI,IAFRT,EAAIkqE,GAAGzpE,EAAEmb,MAAOnb,EAAEob,OAAQ9b,EAAEqsE,GAAIrsE,EAAEorE,KAElB,CACd3qE,EAAG,CACDC,EAAI9M,EAEJ8M,EAAG,OAAS,IACN,MAAQA,EAAG,CACbA,EAAI,QACED,KAGRF,EAAE,MAAQG,EAAEQ,EAAE8tE,IACdzuE,EAAE,MAAQG,EAAEQ,EAAE0sE,IACdrtE,EAAE,EAAIG,EAAEQ,EAAEqmE,IAEVhnE,EAAE,OADFE,EAAIC,EAAEme,IAGNte,EAAE,OADF3N,EAAI6N,EAAEglE,KAGF,GAAK/kE,EAAEylE,GAAI,IACbzlE,EAAEmmE,GAAKj0E,EAAEw4E,GACT1qE,EAAE2uE,GAAKz8E,EAAEy8E,GACT9uE,EAAE,MAAQG,EAAEmmE,KAEPuF,GAAGx5E,EAAEy5E,GAAI5rE,EAAGurE,IAAK,CACpBtrE,EAAE9M,EAAI,QACA8M,MAGHgxE,GAAGhxE,EAAGD,EAAEob,OAAQ,MAAMnb,KACvBD,EAAEmkB,GAAI,MAAMlkB,MACfD,EAAEmkB,IAAM6kD,GAAG/oE,EAAEmmE,GAAG2D,KAAO+B,QACnB7rE,EAAEmmE,GAAG2D,IAAMnrD,MAAM,iCAAkC,MAAQ3e,EAAEmmE,GAAGtxD,EAAEm1D,GAAG/xC,GAAK4zC,MAE3E7rE,EAAE8uE,IAAM,EAAI9uE,EAAEQ,EAAEqsE,IAAM,MAAQ7sE,EAAEQ,EAAEyuE,GAAG3H,IAAMD,GAAGrnE,EAAEQ,EAAEyuE,GAAIjvE,EAAEQ,EAAEwrE,GAAGxE,IAAK,CACpExnE,EAAE9M,EAAI,QACA8M,EAGRA,EAAEylE,GAAK,MAGJgG,GAAGzrE,EAAGA,EAAE+yB,EAAG/yB,EAAE+rE,GAAI/rE,EAAED,EAAGC,EAAEf,EAAGc,EAAEwhD,EAAGssB,IAAK,MAAM7tE,EAChD9N,EAAEu6E,GAAKzsE,EAAE+tE,GACT/tE,EAAI,QACED,EAGRF,EAAE,GAAKG,EAAE9M,GACT8M,EAAI,EAGNA,GAAKA,EAGPA,IAAMT,EAAIrM,EAAEA,QACPqM,EAAIrM,EAAEA,MACR,IAGD,OAFJA,EAAI,IAAI0gF,IAEO,CACbt0E,EAAI,QACEC,KAGRrM,EAAEg9E,GAAKh+E,EAAE+zE,GACT/yE,EAAEwQ,EAAIxR,EAAEwR,EACRxQ,EAAEw6E,GAAKx7E,EAAE40E,GAELqM,GAAGjgF,EAAG8M,OACmC,IAAvCT,EAAIkqE,GAAGzpE,EAAEmb,MAAOnb,EAAEob,OAAQ9b,EAAEqsE,GAAIrsE,EAAEorE,KAAa,IACjDx3E,EAAE24E,GAAK,EACP9rE,EAAIT,EAAEqsE,GAEN9rE,EAAE,OADF3N,EAAIgB,IAGA,MAAQ6M,EAAG,IAIT,GAFJD,EAAI,GADJA,EAAIC,EAAEyoE,IACM,EAAI,IAAM1oE,EAAI,IAAM,IAAMA,EAAI,KAE/B,KACJqe,EAAIO,EAAI,EAAG,EAAIP,IAAKA,EACV,IAAbxd,EAAIzO,EAAEkkE,GAAGj4C,IAAWykC,KAAOjiD,EAAE+tE,GAAK5uE,EAAI45E,GAAG,EAAI/4E,EAAEiiD,GAAK,EAAIjiD,EAAEiiD,KAAO,GAAIlkC,GAAK/d,EAAE+tE,GAG9EhwD,IAAMC,MAAM,sBAAuBzsB,EAAEw8E,GAAK,GAG5Cx8E,EAAE4+E,GAAK/wE,EAAEinE,OACH90E,EAAE4+E,GAAK5+E,EAAE4+E,GAAK,IAAM,EAAI5+E,EAAE4+E,KAAO5+E,EAAE4+E,GAAK,GAGhDsD,GAAGlhF,EAAG8M,KAAOT,EAAIrM,EAAEA,SAEhBqM,EAAIrM,EAAEA,KAGVqM,GAAK,MAAQD,EAAEqsE,IAAMrsE,EAAEqsE,GAAGrrB,KAAO/gD,EAAIg0E,GAAGj0E,EAAEorE,KAGjDprE,EAAIC,EAGNsV,EAAI,GAAKvV,EAAI,KAAO,GAAKuV,EAAIsB,EAAEtB,EAAEk1D,KAAK9pB,GAAK9pC,EAAEtB,EAAEm1D,GAAGp9D,OAC7CiI,EAAI,YAEJA,OAGLi+D,GAAK,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,aAqBvC+G,OAAO53E,KAAM63E,kBAChB7oF,IAAM,GAEDgO,EAAI,EAAGA,EAAI,EAAGA,IACrBhO,KAAOiD,OAAOC,aAAa8N,KAAK63E,oBAG3B7oF,aAOA8oF,QAAQ93E,KAAM63E,iBACb73E,KAAK63E,SAAW,IAAM,EAAI73E,KAAK63E,SAAW,IAAM,EAAI73E,KAAK63E,SAAW,IAAM,MAAQ,WAGnFE,QAAQ/3E,KAAM63E,iBACb73E,KAAK63E,SAAW,IAAM,EAAI73E,KAAK63E,SAAW,IAAM,EAAI73E,KAAK63E,SAAW,IAAM,GAAK73E,KAAK63E,SAAW,IAAM,MAAQ,MArCnH9U,iBAwIA5pD,OAAS,CAAC,GACVD,MAAQ,CAAC,GACTm7C,OAAS,GACT2jB,YAAc,IAAIjV,aAClBlzE,SAAW2sC,UACXy7C,oBArGoBx5C,IAAKy5C,aACvBD,WAAa,GACbj7E,EAAI,EACJm7E,aAAc,EACdC,WAAa,EACbC,aAAe,KACnBJ,WAAU,OAAa;;;;;;;;;SApCTj4E,KAAM63E,SAAU7oF,IAAK4f,UAC9B,IAAI5R,EAAI,EAAGA,EAAI4R,KAAM5R,OACpBgD,KAAK63E,SAAW76E,IAAMhO,IAAI+P,WAAW/B,GAAI,OAAO,SAG/C,EAgCHs7E,CAAO75C,IAAKy5C,QAAS,OAAQ,QAnBlBl4E,KAAM63E,SAqBLE,QAAQt5C,IADxBy5C,SAAW,OAEXA,SAAW,EAEJA,QAAUz5C,IAAIxhC,QAAQ,KACvBs7E,OAASX,OAAOn5C,IAAKy5C,SAErBM,aAAeT,QAAQt5C,IAD3By5C,SAAW,GAEXA,SAAW,MACPO,oBAAsBD,cAA+B,EAAfA,qBAElCD,YACD,WACA,YACoC,IAA5BN,WAAU,OAAWj7E,KAAoBi7E,WAAU,OAAWj7E,GAAK,KAC1E7O,IAAM8pF,WAAU,OAAWj7E,IAG5B,QAAcm7E,YAAcE,aAAeH,QAAU,EACxD/pF,IAAG,SAAeiqF,WAAaI,aAAe,EAG9Cx7E,IAEIm7E,cACFA,aAAc,EACdC,WAAa,EACbC,aAAe,aAKd,QACClqF,IAAM8pF,WAAU,OAAa,IACV,cAAoBx5C,IAAIy5C,aAC3CQ,SAAWR,QAAU,EACN/pF,IAAG,aAAmB,EAAI2pF,QAAQr5C,IAAKi6C,UAC1DA,UAAY,EACQvqF,IAAG,cAAoB,EAAI2pF,QAAQr5C,IAAKi6C,UAC5DA,UAAY,YAGT,OACHP,aAAc,EACdC,WAAaK,oBAAsB,EACnCJ,aAAeH,QAAU,YAGtB,QACC/pF,IAAM8pF,WAAU,QACH,QAAcF,QAAQt5C,IAAKy5C,SAC5CQ,SAAWR,QAAU,EACJ/pF,IAAG,YAxEX6R,KAwEoCy+B,MAxE9Bo5C,SAwEmCa,UAvEjC,IAAM,EAAI14E,KAAK63E,SAAW,IAAM,EAwEjDa,UAAY,YAGT,WAQCC,KACAxqF,KAAAA,IAAM8pF,WAAU,OAAWj7E,GAAK,IACjC,SAA0B,EAAI86E,QAAQr5C,IAAKy5C,SAC9CA,SAAW,EACX/pF,IAAG,SAA0B,EAAI2pF,QAAQr5C,IAAKy5C,SAC9CA,SAAW,EACX/pF,IAAG,MAAoB,EAAI2pF,QAAQr5C,IAAKy5C,SACxCA,SAAW,EACX/pF,IAAG,OAAsB,EAAI2pF,QAAQr5C,IAAKy5C,SAC1CA,SAAW,EACX/pF,IAAG,SAA0B2pF,QAAQr5C,IAAKy5C,SAC1CA,SAAW,EACXS,KAAOl6C,IAAIy5C,WACX/pF,IAAG,QAA+B,EAAPwqF,KAC3BxqF,IAAG,MAAoBwqF,MAAQ,EAAI,EAIzB,QAAVJ,SAAkBL,SAAWO,4BAG5BR,YAQQW,CAAe/oF,SAAU,GAC1CooF,WAAU,SAAepoF,SACzBooF,WAAU,YAAiB,EAC3BA,WAAU,SAAc,MACpBjtC,OAASitC,WAAU,OAAaA,WAAU,OAAa,KACvDplB,OAASolB,WAAU,OAAaA,WAAU,OAAa,QAEvDjtC,OAAQ,CACVA,OAAM,aAAmBA,OAAM,WAC/B7xB,OAAS,CAAC6xB,OAAM,eAChB9xB,MAAQ,CAAC8xB,OAAM,kBAEV,IAAIp4B,EAAI,EAAGA,EAAIigD,OAAO51D,QACC,GAAtB41D,OAAOjgD,GAAP,MAD6BA,UAOjCi/C,MAAQgB,OAAO,GACfrhB,KAAOwmC,YAAYN,eAAe7nF,SAAUgiE,MAAK,QAAaA,MAAK,SAAc34C,MAAOC,QAC5F04C,MAAK,KAAWrgB,KAChBqgB,MAAK,SAAe34C,MAAM,GAC1B24C,MAAK,UAAgB14C,OAAO,OAEvB,IAAInc,EAAI,EAAGA,EAAIkc,MAAM,GAAKC,OAAO,GAAK,EAAGnc,IAC5Cq3D,OAAOr3D,GAAKw0C,KAAKx0C,eAGdkc,MAAQA,WACRC,OAASA,YACTnZ,KAAOq0D,OACLpmE,eA9xMEghC,cAsCL4pD,iBAAmB,kBACd,GAGLC,cAAgB,SAAuBlqD,MAAOmqD,WAAYC,eAAgBt2C,iBACxE+iB,MAAQ,EACRwzB,cAAgBC,gBAEZx2C,kBACDzT,SAAS2R,kBAAkBE,KAC9B2kB,MAAQ,EACRwzB,cAAgBE,qBAGblqD,SAAS2R,kBAAkBG,OAC9B0kB,MAAQ,EACRwzB,cAAgBG,yBAGbnqD,SAAS2R,kBAAkBI,KAC9BykB,MAAQ,EACRwzB,cAAgBI,gBAKhBj4B,IAAMuE,SADV/2B,MAAQ0qD,qBAAqB1qD,MAAOmqD,WAAYC,eAAgBC,eACtC,CACxBxzB,MAAOA,eAEFx2B,SAAS2M,aAAa+B,0BAA0ByjB,MAGrDk4B,qBAAuB,SAA8B1qD,MAAOmqD,WAAYC,eAAgBC,uBAItFrwD,KACA2wD,SACA7/D,OALAmP,MAAQ+F,MAAM3xB,OAAS87E,WACvB9lF,OAAS,IAAIsb,WAAWqgB,MAAM3xB,OAAS4rB,OACvC2wD,eAAiBC,mBAKZz8E,EAAI,EAAGA,EAAI6rB,MAAO7rB,GAAK,EAAG,IACjC0c,OAAS1c,EAAI+7E,WACbnwD,KAAOgG,MAAM4T,SAAS9oB,OAAQA,OAASq/D,YAEnCE,cACFhmF,OAAOsf,IAAI0mE,cAAcrwD,KAAMowD,eAAgBO,UAAW7/D,OAAS1c,OAC9D,SAIIqC,EAHL8O,IAAMqrE,eAAev8E,OACrBy8E,QAAU,GAEFr6E,EAAI8O,IAAK9O,GAAK,EACxBq6E,QAAQr6E,GAAKm6E,eAAen6E,GAAGupB,KAAMowD,eAAgBO,cAGnDI,IAAMC,sBAAsBF,QAAQx2D,UACxCjwB,OAAOsf,IAAImnE,QAAQC,KAAMjgE,OAAS1c,GAGpCu8E,SAAW3wD,YAGN31B,QAGL4mF,WAAa,SAAoBjxD,UAI/B31B,OAASmN,MAAMvR,MAAM,GAAI+5B,aAC7B31B,OAAO0mB,QAAQ,GACR1mB,QAGLkmF,UAAY,SAAmBvwD,KAAMowD,oBAGnCz0C,KAFAtxC,OAAS,GACTkb,IAAMya,KAAK3rB,OAEfhK,OAAO,GAAK,MAEP,IAAI+J,EAAI,EAAGA,EAAImR,IAAKnR,GAAK,EAC5BunC,KAAO3b,KAAK5rB,EAAIg8E,iBAAmB,EACnC/lF,OAAO+J,EAAI,GAAK4rB,KAAK5rB,GAAKunC,KAAO,IAAS,WAGrCtxC,QAGLimF,SAAW,SAAkBtwD,KAAMowD,eAAgBO,cAGjDO,GAFA7mF,OAAS,GACTkb,IAAMya,KAAK3rB,OAEfhK,OAAO,GAAK,MAEP,IAAI+J,EAAI,EAAGA,EAAImR,IAAKnR,GAAK,EAC5B88E,GAAKP,UAAYA,SAASv8E,IAAM,EAChC/J,OAAO+J,EAAI,GAAK4rB,KAAK5rB,GAAK88E,GAAK,IAAS,WAGnC7mF,QAGLmmF,cAAgB,SAAuBxwD,KAAMowD,eAAgBO,cAG3Dh1C,KACAu1C,GAHA7mF,OAAS,GACTkb,IAAMya,KAAK3rB,OAGfhK,OAAO,GAAK,MAEP,IAAI+J,EAAI,EAAGA,EAAImR,IAAKnR,GAAK,EAC5BunC,KAAO3b,KAAK5rB,EAAIg8E,iBAAmB,EACnCc,GAAKP,UAAYA,SAASv8E,IAAM,EAChC/J,OAAO+J,EAAI,GAAK4rB,KAAK5rB,GAAK,KAAUunC,KAAOu1C,KAAO,GAAK,WAGlD7mF,QAGLomF,YAAc,SAAqBzwD,KAAMowD,eAAgBO,cAGvDh1C,KACAu1C,GACAC,OACA7lB,MALAjhE,OAAS,GACTkb,IAAMya,KAAK3rB,OAKfhK,OAAO,GAAK,MAEP,IAAI+J,EAAI,EAAGA,EAAImR,IAAKnR,GAAK,EAC5BunC,KAAO3b,KAAK5rB,EAAIg8E,iBAAmB,EACnCc,GAAKP,UAAYA,SAASv8E,IAAM,EAChC+8E,OAASR,UAAYA,SAASv8E,EAAIg8E,iBAAmB,EACrD9kB,MAAQ8lB,eAAez1C,KAAMu1C,GAAIC,QACjC9mF,OAAO+J,EAAI,GAAK4rB,KAAK5rB,GAAKk3D,MAAQ,IAAS,WAGtCjhE,QAGL+mF,eAAiB,SAAwBz1C,KAAMu1C,GAAIC,WACjDx1C,OAASu1C,IAAMA,KAAOC,cACjBx1C,SAGL01C,MAAQt3E,KAAK+C,IAAIo0E,GAAKC,QACtBG,IAAMv3E,KAAK+C,IAAI6+B,KAAOw1C,QACtBI,QAAUx3E,KAAK+C,IAAI6+B,KAAOu1C,GAAKC,OAASA,eACrCE,OAASC,KAAOD,OAASE,QAAU51C,KAAO21C,KAAOC,QAAUL,GAAKC,QAGrEN,iBAAmB,iBACd,CAACI,WAAYV,UAAWD,SAAUE,cAAeC,cAGtDO,sBAAwB,SAA+BQ,YACrDC,IAAMD,OAAO56E,KAAI,SAAU2G,cACtBA,MAAM0d,QAAO,SAAU0nB,GAAIC,WACzBD,GAAK5oC,KAAK+C,IAAI8lC,MACpB,aAEE6uC,IAAIz2E,QAAQjB,KAAKqb,IAAInvB,MAAM,KAAMwrF,OAiC1CprD,SAASqrD,WAAa,SAAU99C,UAAW5iB,MAAOolB,MAAO0D,iBAEnDzF,WAEAM,iBACAP,MAEAu9C,KACAn2E,OACAo2E,IACAC,MACApmB,OACAlmD,IACAusE,UACA/sB,QACAgtB,UACAC,MACA59E,EACA0B,EAfA82B,OAASvnC,KAAKiyC,OAAOE,aAGrB5C,iBAAmB,MAanBvvC,KAAK2tC,aAAagG,cAAcpF,aAAYA,UAAY,IAAIjuB,WAAWiuB,YAEvEvuC,KAAK2tC,aAAakB,kBAAkBN,WAAY,IAElDA,WADAQ,MAAQ,IAAIjB,IAAIS,YACEmxB,QAClBpwB,iBAAmBP,MAAMlgC,KACzBmgC,WAAaD,MAAMC,WACnB74B,OAAS44B,MAAM54B,QAS0B,IAArC,CAAC,EAAG,GAAGR,QAAQo5B,MAAMs1B,WAAmB,IAIvB,IAAft1B,MAAMlgC,KAAY,CAEpBqR,KADAkmD,OAAiC,IAAxBr3B,MAAMw2B,eAAuB,IAAI3xB,YAAY7E,MAAMy2B,eAAenxB,QAAkC,IAAxBtF,MAAMw2B,eAAuB,IAAIxxB,YAAYhF,MAAMy2B,eAAenxB,QAAU,IAAI/zB,WAAWyuB,MAAMy2B,eAAenxB,SACxLrlC,OACb0wD,QAAU,IAAIp/C,WAAWJ,IAAM6uB,MAAM54B,QACrCs2E,UAAY,IAAInsE,WAAWJ,SAIvB0sE,IAHAC,MAAQ99C,MAAMw2B,eAAiBx2B,MAAMlgC,SACzCE,EAAI,EACJ0B,EAAI,EAGG1B,EAAImR,IAAKnR,IAAK,KACnB49E,MAAQvmB,OAAOr3D,GACf69E,IAAM,EAECA,IAAMC,OACXntB,QAAQjvD,KAAOk8E,QAAUC,IAAM,IAC/BA,KAAY79C,MAAMlgC,KAGpB49E,UAAU19E,GAAK49E,QAAUC,IAAM,QAQhB,KAAf79C,MAAMlgC,KAAa,CAErBqR,KADAkmD,OAAS,IAAIxyB,YAAY7E,MAAMy2B,eAAenxB,SACjCrlC,OACb0wD,QAAU,IAAIp/C,WAAWJ,KAAO,GAAK6uB,MAAMw2B,gBAAkBx2B,MAAM54B,QACnEs2E,UAAY,IAAInsE,WAAWJ,KAAO,GAAK6uB,MAAMw2B,iBAC7CmnB,UAAY39C,MAAM54B,OAAS,EAC3BpH,EAAI,EACJ0B,EAAI,UACAzN,EAAI,EAED+L,EAAImR,KACTysE,MAAQvmB,OAAOr3D,KACf2wD,QAAQjvD,KAAOk8E,QAAU,EAAI,IAEzBD,YACFhtB,QAAQjvD,KAAOk8E,QAAU,GAAK,IAC9BA,MAAQvmB,OAAOr3D,KACf2wD,QAAQjvD,KAAOk8E,QAAU,EAAI,KAG/BF,UAAUzpF,KAAO2pF,QAAU,GAAK,IAGlCr9C,iBAAmB,EAGLmF,cA9RHzT,SAAS2R,kBAAkBC,MAAQg4C,oBA+R9Cr8C,UAAYs8C,cAAcnrB,QAAS3wB,MAAM9jB,MAAQ8jB,MAAM54B,OAAQ44B,MAAM54B,OAAQs+B,aAC7E+3C,MAAQ3B,cAAc4B,UAAW19C,MAAM9jB,MAAO,EAAGwpB,eAEjDlG,UAAYmxB,QACZ8sB,MAAQC,UACRllD,YAASnmB,MAQW,IAApB2tB,MAAMs1B,YACRr1B,WAAahvC,KAAKivC,aAAaC,QAC/Bq9C,IAAMx9C,MAAMI,QAERJ,MAAMS,aAAa21B,SAAS,KAC1B2E,MAAQ/6B,MAAMS,aAAa21B,QAC3B2nB,MAAQ,MACZ/9E,EAAI,EACJmR,IAAM4pD,MAAM96D,OAELD,EAAImR,MAAOnR,EAChB+9E,OAAShjB,MAAM/6D,OAGjB+9E,OAAgB,OAMF5sE,IAAM,IAA2B,IAAtB4pD,MAAMn0D,QAAQ,GACrC22E,KAAO,CAACxiB,MAAMn0D,QAAQ,SAKjB,GAAIm3E,QAAU5sE,IAAK,KACxBkmD,OAASr3B,MAAMy2B,eACfinB,UAAY,IAAInsE,WAAW8lD,OAAOp3D,QAClCD,EAAI,EACJmR,IAAMkmD,OAAOp3D,OAEND,EAAImR,IAAKnR,IACd09E,UAAU19E,GAAK+6D,MAAM1D,OAAOr3D,IAG9By9E,MAAQ3B,cAAc4B,UAAW19C,MAAM9jB,MAAO,QAKhDwkB,UAjL0B,SAAqCgF,iBACjEhF,iBAEIgF,kBACDzT,SAAS2R,kBAAkBE,KAC9BpD,UAAY,cAGTzO,SAAS2R,kBAAkBG,OAC9BrD,UAAY,cAGTzO,SAAS2R,kBAAkBI,KAC9BtD,UAAY,iBAIZA,UAAY,UAITA,UA4JWs9C,CAA4Bt4C,oBAExClN,SAAWvnC,KAAKiyC,OAAOE,eACzB5C,iBAAmB,cAAgBE,UAAY,KAGjDF,kBAAoB,WAAap5B,OAAS,sBAAwBm5B,iBAAmB,aAAeP,MAAM9jB,OAEtGjrB,KAAK2tC,aAAagG,cAAcpF,YAAcvuC,KAAK2tC,aAAakB,kBAAkBN,cACpFA,UAAYvuC,KAAK2tC,aAAa+B,0BAA0BnB,aAGtDi+C,OAASxsF,KAAK2tC,aAAagG,cAAc64C,QAAUxsF,KAAK2tC,aAAakB,kBAAkB29C,UACzFA,MAAQxsF,KAAK2tC,aAAa+B,0BAA0B88C,QAG/C,CACLz7C,MAAOA,MACPh/B,KAAMw8B,UACN5iB,MAAOA,MACP4b,OAAQA,OACRgI,iBAAkBA,iBAClBC,aAAc88C,KACdn9C,QAASo9C,IACTn9C,MAAOo9C,MACP/8C,UAAWA,UACXxkB,MAAO8jB,MAAM9jB,MACbC,OAAQ6jB,MAAM7jB,OACdokB,iBAAkBA,iBAClBN,WAAYA,eAIjBt4B,MAAMkB,cAwrCEopB,UAETA,SAASgsD,cAAgB,SAAUz+C,UAAW5iB,MAAOolB,MAAO0D,iBACtD3vC,OAAS,IAAIojE,UAAU35B,WACvBtjB,MAAQnmB,OAAOmmB,MACfC,OAASpmB,OAAOomB,OAEhBk7C,OAAS,GACbthE,OAAOylE,uBAAuB,EAAGnE,YAC7B6mB,aAAe,CACjBl7E,KAAMq0D,OACNn7C,MAAOA,MACPC,OAAQA,QAGNnZ,KADU,IAAI05D,YART,KASU+G,OAAOya,aATjB,YAUFjsD,SAAS8hC,YAAY9hE,KAAKhB,KAAM+R,KAAM4Z,MAAOolB,MAAO0D,cAG7DzT,SAASksD,cAAgBlsD,SAASgsD,eACjCt2E,MAAMkB,KAsBT+7D,WAAWrzE,UAAU2zE,YAAc,mBAC5BkZ,SAAWntF,KAAK6zE,MAAMuZ,UAAUptF,KAAKkzD,KAAK,QAC1CA,KAAO,OACPm6B,SAAWrtF,KAAK6zE,MAAMuZ,UAAUptF,KAAKkzD,KAAK,QAC1CA,KAAO,OACPznC,OAASzrB,KAAK6zE,MAAMuZ,UAAUptF,KAAKkzD,KAAK,QACxCA,KAAO,OACPo6B,WAAattF,KAAK6zE,MAAMuZ,UAAUptF,KAAKkzD,KAAK,QAC5CA,KAAO,OACPjoC,MAAQjrB,KAAK6zE,MAAMuZ,UAAUptF,KAAKkzD,KAAK,QACvCA,KAAO,OACPhoC,OAASlrB,KAAK6zE,MAAM0Z,SAASvtF,KAAKkzD,KAAK,QACvCA,KAAO,OACPs6B,OAASxtF,KAAK6zE,MAAM4Z,UAAUztF,KAAKkzD,KAAK,QACxCA,KAAO,OACPw6B,MAAQ1tF,KAAK6zE,MAAM4Z,UAAUztF,KAAKkzD,KAAK,QACvCA,KAAO,OACP57C,SAAWtX,KAAK6zE,MAAMuZ,UAAUptF,KAAKkzD,KAAK,QAC1CA,KAAO,OACPy6B,QAAU3tF,KAAK6zE,MAAMuZ,UAAUptF,KAAKkzD,KAAK,QACzCA,KAAO,OACP06B,GAAK5tF,KAAK6zE,MAAMuZ,UAAUptF,KAAKkzD,KAAK,QACpCA,KAAO,OACP26B,GAAK7tF,KAAK6zE,MAAMuZ,UAAUptF,KAAKkzD,KAAK,QACpCA,KAAO,OACP/8C,OAASnW,KAAK6zE,MAAMuZ,UAAUptF,KAAKkzD,KAAK,QACxCA,KAAO,OACP46B,gBAAkB9tF,KAAK6zE,MAAMuZ,UAAUptF,KAAKkzD,KAAK,QACjDA,KAAO,EAEO,KAAflzD,KAAK0tF,OAAgB1tF,KAAK4zE,qBACvB8Z,MAAQ,IAGX1tF,KAAK0tF,MAAQ,GAAI,KACfxtE,IAAsB,IAAhBlgB,KAAKmW,OAAe,GAAKnW,KAAK0tF,MAAQ1tF,KAAKmW,YAChDg5B,QAAU,IAAIh9B,MAAM+N,SAEpB,IAAInR,EAAI,EAAGA,EAAImR,IAAKnR,IAAK,KACxB7I,KAAOlG,KAAK6zE,MAAMka,SAAS/tF,KAAKkzD,OAAO,GACvCrqD,MAAQ7I,KAAK6zE,MAAMka,SAAS/tF,KAAKkzD,OAAO,GACxCtmD,IAAM5M,KAAK6zE,MAAMka,SAAS/tF,KAAKkzD,OAAO,GACtC86B,KAAOhuF,KAAK6zE,MAAMka,SAAS/tF,KAAKkzD,OAAO,QACtC/jB,QAAQpgC,GAAK,CAChBnC,IAAKA,IACL/D,MAAOA,MACP3C,KAAMA,KACN8nF,KAAMA,OAKRhuF,KAAKkrB,OAAS,SACXA,SAAW,OACX6oD,WAAY,IAIrBJ,WAAWrzE,UAAU4zE,SAAW,gBACzBhhB,IAAMlzD,KAAKyrB,eAGVwiE,KAAO,MAAQjuF,KAAK0tF,MACpBxtE,IAAMlgB,KAAKirB,MAAQjrB,KAAKkrB,OAAS,OAChCnZ,KAAO,IAAIuO,WAAWJ,UACtB+tE,QACL,MAAOjsF,GACPtB,QAAQC,IAAI,oBAAsBqB,KAItC2xE,WAAWrzE,UAAU4tF,KAAO,eAGtBxxE,EAFAyxE,KAAOz5E,KAAKqiC,KAAK/2C,KAAKirB,MAAQ,GAC9BmjE,KAAOD,KAAO,MAGbzxE,EAAI1c,KAAKkrB,OAAS,EAAGxO,GAAK,EAAGA,IAAK,SACjCie,KAAO36B,KAAK+zE,UAAYr3D,EAAI1c,KAAKkrB,OAAS,EAAIxO,EAEzC/M,EAAI,EAAGA,EAAIw+E,KAAMx+E,YACpBN,EAAIrP,KAAK6zE,MAAMka,SAAS/tF,KAAKkzD,OAAO,GACpC7vD,SAAWs3B,KAAO36B,KAAKirB,MAAQ,EAAQ,EAAJtb,EAAQ,EAEtCZ,EAAI,EAAGA,EAAI,GACV,EAAJY,EAAQZ,EAAI/O,KAAKirB,MADAlc,IAAK,KAEpBs2D,IAAMrlE,KAAKmvC,QAAQ9/B,GAAK,EAAIN,EAAI,QAC/BgD,KAAK1O,SAAe,EAAJ0L,GAASs2D,IAAIn/D,UAC7B6L,KAAK1O,SAAe,EAAJ0L,EAAQ,GAAKs2D,IAAIx8D,WACjCkJ,KAAK1O,SAAe,EAAJ0L,EAAQ,GAAKs2D,IAAIz4D,SACjCmF,KAAK1O,SAAe,EAAJ0L,EAAQ,GAAK,IAO3B,IAATq/E,YACGl7B,KAAO,EAAIk7B,QAKtBza,WAAWrzE,UAAU+tF,KAAO,mBACtBF,KAAOz5E,KAAKqiC,KAAK/2C,KAAKirB,MAAQ,GAC9BmjE,KAAOD,KAAO,EAETzxE,EAAI1c,KAAKkrB,OAAS,EAAGxO,GAAK,EAAGA,IAAK,SACrCie,KAAO36B,KAAK+zE,UAAYr3D,EAAI1c,KAAKkrB,OAAS,EAAIxO,EAEzC/M,EAAI,EAAGA,EAAIw+E,KAAMx+E,IAAK,KACzBN,EAAIrP,KAAK6zE,MAAMka,SAAS/tF,KAAKkzD,OAAO,GACpC7vD,SAAWs3B,KAAO36B,KAAKirB,MAAQ,EAAQ,EAAJtb,EAAQ,EAC3C2+E,OAASj/E,GAAK,EACdk/E,MAAY,GAAJl/E,EACRg2D,IAAMrlE,KAAKmvC,QAAQm/C,gBAClBv8E,KAAK1O,UAAYgiE,IAAIn/D,UACrB6L,KAAK1O,SAAW,GAAKgiE,IAAIx8D,WACzBkJ,KAAK1O,SAAW,GAAKgiE,IAAIz4D,SACzBmF,KAAK1O,SAAW,GAAK,IAClB,EAAJsM,EAAQ,GAAK3P,KAAKirB,MAAO,MAC7Bo6C,IAAMrlE,KAAKmvC,QAAQo/C,YACdx8E,KAAK1O,SAAW,GAAKgiE,IAAIn/D,UACzB6L,KAAK1O,SAAW,EAAI,GAAKgiE,IAAIx8D,WAC7BkJ,KAAK1O,SAAW,EAAI,GAAKgiE,IAAIz4D,SAC7BmF,KAAK1O,SAAW,EAAI,GAAK,IAGnB,IAAT+qF,YACGl7B,KAAO,EAAIk7B,QAKtBza,WAAWrzE,UAAUkuF,KAAO,mBACtBJ,KAAOpuF,KAAKirB,MAAQ,EAEfvO,EAAI1c,KAAKkrB,OAAS,EAAGxO,GAAK,EAAGA,IAAK,SACrCie,KAAO36B,KAAK+zE,UAAYr3D,EAAI1c,KAAKkrB,OAAS,EAAIxO,EAEzC/M,EAAI,EAAGA,EAAI3P,KAAKirB,MAAOtb,IAAK,KAC/BN,EAAIrP,KAAK6zE,MAAMka,SAAS/tF,KAAKkzD,OAAO,GACpC7vD,SAAWs3B,KAAO36B,KAAKirB,MAAQ,EAAQ,EAAJtb,KAEnCN,EAAIrP,KAAKmvC,QAAQngC,OAAQ,KACvBq2D,IAAMrlE,KAAKmvC,QAAQ9/B,QAClB0C,KAAK1O,UAAYgiE,IAAIz4D,SACrBmF,KAAK1O,SAAW,GAAKgiE,IAAIx8D,WACzBkJ,KAAK1O,SAAW,GAAKgiE,IAAIn/D,UACzB6L,KAAK1O,SAAW,GAAK,cAErB0O,KAAK1O,UAAY,SACjB0O,KAAK1O,SAAW,GAAK,SACrB0O,KAAK1O,SAAW,GAAK,SACrB0O,KAAK1O,SAAW,GAAK,IAIjB,IAAT+qF,YACGl7B,KAAO,EAAIk7B,QAKtBza,WAAWrzE,UAAUmuF,MAAQ,mBACvBC,MAAQ1uF,KAAKirB,MAAQ,EAGrB0jE,KADS7/E,SAAS,QAAS,GAGtB4N,EAAI1c,KAAKkrB,OAAS,EAAGxO,GAAK,EAAGA,IAAK,SACrCie,KAAO36B,KAAK+zE,UAAYr3D,EAAI1c,KAAKkrB,OAAS,EAAIxO,EAEzC/M,EAAI,EAAGA,EAAI3P,KAAKirB,MAAOtb,IAAK,KAC/B0tE,EAAIr9E,KAAK6zE,MAAM4Z,UAAUztF,KAAKkzD,KAAK,QAClCA,KAAO,MACRhtD,MAAQm3E,EAAIsR,MAAQA,KAAO,IAAM,EACjC9lF,OAASw0E,GAAK,EAAIsR,MAAQA,KAAO,IAAM,EACvC/hF,KAAOywE,GAAK,GAAKsR,MAAQA,KAAO,IAAM,EACtCznB,MAAQmW,GAAK,GAAK,IAAO,EACzBh6E,SAAWs3B,KAAO36B,KAAKirB,MAAQ,EAAQ,EAAJtb,OAClCoC,KAAK1O,UAAYuJ,SACjBmF,KAAK1O,SAAW,GAAKwF,WACrBkJ,KAAK1O,SAAW,GAAK6C,UACrB6L,KAAK1O,SAAW,GAAK6jE,WAIvBhU,KAAOw7B,QAIhB/a,WAAWrzE,UAAUsuF,MAAQ,mBACvBF,MAAQ1uF,KAAKirB,MAAQ,EAGrB0jE,KADS7/E,SAAS,QAAS,GAI3B+/E,KADU//E,SAAS,SAAU,GAGxB4N,EAAI1c,KAAKkrB,OAAS,EAAGxO,GAAK,EAAGA,IAAK,SACrCie,KAAO36B,KAAK+zE,UAAYr3D,EAAI1c,KAAKkrB,OAAS,EAAIxO,EAEzC/M,EAAI,EAAGA,EAAI3P,KAAKirB,MAAOtb,IAAK,KAC/B0tE,EAAIr9E,KAAK6zE,MAAM4Z,UAAUztF,KAAKkzD,KAAK,QAClCA,KAAO,MAERhtD,MAAQm3E,EAAIsR,MAAQA,KAAO,IAAM,EACjC9lF,OAASw0E,GAAK,EAAIwR,MAAQA,KAAO,IAAM,EACvCjiF,KAAOywE,GAAK,IAAMsR,KAAO,IAAM,EAC/BtrF,SAAWs3B,KAAO36B,KAAKirB,MAAQ,EAAQ,EAAJtb,OAClCoC,KAAK1O,UAAYuJ,SACjBmF,KAAK1O,SAAW,GAAKwF,WACrBkJ,KAAK1O,SAAW,GAAK6C,UACrB6L,KAAK1O,SAAW,GART,SAYT6vD,KAAOw7B,QAIhB/a,WAAWrzE,UAAUwuF,MAAQ,eAEtB,IAAIpyE,EAAI1c,KAAKkrB,OAAS,EAAGxO,GAAK,EAAGA,IAAK,SACrCie,KAAO36B,KAAK+zE,UAAYr3D,EAAI1c,KAAKkrB,OAAS,EAAIxO,EAEzC/M,EAAI,EAAGA,EAAI3P,KAAKirB,MAAOtb,IAAK,KAC/BzJ,KAAOlG,KAAK6zE,MAAMka,SAAS/tF,KAAKkzD,OAAO,GACvCrqD,MAAQ7I,KAAK6zE,MAAMka,SAAS/tF,KAAKkzD,OAAO,GACxCtmD,IAAM5M,KAAK6zE,MAAMka,SAAS/tF,KAAKkzD,OAAO,GACtC7vD,SAAWs3B,KAAO36B,KAAKirB,MAAQ,EAAQ,EAAJtb,OAClCoC,KAAK1O,UAAYuJ,SACjBmF,KAAK1O,SAAW,GAAKwF,WACrBkJ,KAAK1O,SAAW,GAAK6C,UACrB6L,KAAK1O,SAAW,GAAK,SAIvB6vD,KAAOlzD,KAAKirB,MAAQ,IAS7B0oD,WAAWrzE,UAAUyuF,MAAQ,eAEtB,IAAIryE,EAAI1c,KAAKkrB,OAAS,EAAGxO,GAAK,EAAGA,YAChCie,KAAO36B,KAAK+zE,UAAYr3D,EAAI1c,KAAKkrB,OAAS,EAAIxO,EAEzC/M,EAAI,EAAGA,EAAI3P,KAAKirB,MAAOtb,IAAK,KAC/BzJ,KAAOlG,KAAK6zE,MAAMka,SAAS/tF,KAAKkzD,OAAO,GACvCrqD,MAAQ7I,KAAK6zE,MAAMka,SAAS/tF,KAAKkzD,OAAO,GACxCtmD,IAAM5M,KAAK6zE,MAAMka,SAAS/tF,KAAKkzD,OAAO,GACtCgU,MAAQlnE,KAAK6zE,MAAMka,SAAS/tF,KAAKkzD,OAAO,GACxC7vD,SAAWs3B,KAAO36B,KAAKirB,MAAQ,EAAQ,EAAJtb,OAClCoC,KAAK1O,UAAYuJ,SACjBmF,KAAK1O,SAAW,GAAKwF,WACrBkJ,KAAK1O,SAAW,GAAK6C,UACrB6L,KAAK1O,SAAW,GAAK6jE,QAOhCyM,WAAWrzE,UAAU0uF,QAAU,kBACtBhvF,KAAK+R;;;;;;;;SAiBHivB,UAETA,SAASiuD,WAAa,SAAU1gD,UAAW5iB,MAAOolB,MAAO0D,iBACnD3vC,OAAS,IAAI6uE,WAAWplC,WAAW,GACnCtjB,MAAQnmB,OAAOmmB,MACfC,OAASpmB,OAAOomB,OAGhB+hE,aAAe,CACjBl7E,KAFWjN,OAAOkqF,UAGlB/jE,MAAOA,MACPC,OAAQA,QAGNnZ,KADU,IAAI05D,YAPT,KAQU+G,OAAOya,aARjB,YASFjsD,SAAS8hC,YAAY9hE,KAAKhB,KAAM+R,KAAM4Z,MAAOolB,MAAO0D,eAE5D/9B,MAAMkB,KAs3ITu8D,YAAY7zE,UAAU0uF,QAAU,kBACvBhvF,KAAK+R;;;;;;;;SAiBHivB,UAETA,SAASkuD,YAAc,SAAU3gD,UAAW5iB,MAAOolB,MAAO0D,iBACpD3vC,OAAS,IAAIqvE,YAAY5lC,WAAW,GACpCtjB,MAAQnmB,OAAOmmB,MACfC,OAASpmB,OAAOomB,OAGhB+hE,aAAe,CACjBl7E,KAFWjN,OAAOkqF,UAGlB/jE,MAAOA,MACPC,OAAQA,QAGNnZ,KADU,IAAI05D,YAPT,KAQU+G,OAAOya,aARjB,YASFjsD,SAAS8hC,YAAY9hE,KAAKhB,KAAM+R,KAAM4Z,MAAOolB,MAAO0D,eAE5D/9B,MAAMkB;;;;;;;;;;;;;;;;;;;;;;;;;;SAiCEopB,UAUTA,SAASmuD,YAAc,SAAU5gD,UAAW5iB,MAAOolB,eAE7Cq+C,YAAc7gD,UAAUx8B,KACxB/C,OAASogF,YAAYpgF,OAErBqgF,OAAS,IAAI/uE,WAAWtR,OAAS,EAAI,GACrCsgF,SAAW,IAAIhvE,WAAWtR,OAAS,GACnCugF,SAAW,EACXC,WAAa,EAERzgF,EAAI,EAAGA,EAAIC,OAAQD,GAAK,EAAG,KAC9BI,EAAIigF,YAAYrgF,GAChBK,EAAIggF,YAAYrgF,EAAI,GACpBM,EAAI+/E,YAAYrgF,EAAI,GACpBm4D,MAAQkoB,YAAYrgF,EAAI,GAC5BsgF,OAAOE,YAAcpgF,EACrBkgF,OAAOE,YAAcngF,EACrBigF,OAAOE,YAAclgF,EACrBigF,SAASE,cAAgBtoB,UAGvBuoB,QAAUzvF,KAAK2tC,aAAa+B,0BAA0B2/C,cAInD,CACLnoB,MAHclnE,KAAK2tC,aAAa+B,0BAA0B4/C,UAI1Dv9E,KAAM09E,QACN9jE,MAAOA,MACPolB,MAAOA,MACP/B,WAAY,YACZM,iBAAkB,EAClBrkB,MAAOsjB,UAAUtjB,MACjBC,OAAQqjB,UAAUrjB,UAGrBxU,MAAMkB;;;;;;SAcEopB,UAeTA,SAAS0uD,YAAc,SAAUC,sBAyMQvuE,IAAnCphB,KAAK6X,SAAS+3E,wBACX/3E,SAAS+3E,iBAAmB,QAC5B/3E,SAAS+3E,iBAAiBC,cAAe,QAGpBzuE,IA5MZ,CACd6jE,GAAI,YACJ6K,GAAI,WACJ3iC,GAAI,4BACK,2BACA,2BACA,yBACA,wBACA,0BACA,0BACA,2BACA,yBACA,2BACA,wBACA,yBACA,gCACA,yBACA,2BACA,0BACA,iBACT4iC,GAAI,YACJC,GAAI,WACJC,GAAI,WACJC,IAAK,WACLC,GAAI,cACJC,GAAI,SACJhU,GAAI,aACJiU,GAAI,UACJ38B,GAAI,UACJ48B,GAAI,SACJC,GAAI,YACJC,GAAI,UACJva,GAAI,UACJ9mD,GAAI,WACJmtD,GAAI,UACJmU,GAAI,kBACK,8BACA,wBACA,8BACA,mBACTlzC,GAAI,UACJmT,GAAI,WACJggC,GAAI,OACJ9C,GAAI,WACJ+C,GAAI,QACJ38D,GAAI,SACJijC,GAAI,2BACK,kBACT25B,GAAI,kBACK,8BACA,2BACA,2BACA,4BACA,4BACA,gCACA,gCACA,iCACA,sCACA,mCACA,kCACA,qBACTC,GAAI,YACJt7B,GAAI,WACJu7B,GAAI,WACJC,GAAI,SACJC,GAAI,UACJC,GAAI,4BACK,2BACA,0BACA,0BACA,8BACA,0BACA,uBACTC,GAAI,UACJC,IAAK,WACL7N,GAAI,yBACK,iBACT8N,GAAI,WACJ3W,GAAI,WACJiC,GAAI,4BACK,2BACA,2BACA,iCACA,8BACA,uBACTnhB,GAAI,QACJ81B,GAAI,WACJC,GAAI,UACJ5S,GAAI,SACJ6S,GAAI,QACJC,GAAI,YACJC,GAAI,YACJ77E,GAAI,aACJ87E,GAAI,YACJrV,GAAI,QACJlnB,GAAI,6BACK,wBACT4qB,GAAI,WACJ4R,GAAI,UACJC,GAAI,WACJC,GAAI,SACJC,GAAI,QACJC,GAAI,UACJC,IAAK,UACLC,GAAI,iBACK,+BACA,uBACTnS,GAAI,QACJloB,GAAI,UACJqB,GAAI,aACJugB,GAAI,gBACJ0Y,GAAI,kBACJC,GAAI,QACJn7B,GAAI,YACJo7B,GAAI,UACJC,GAAI,QACJC,GAAI,UACJC,GAAI,YACJC,GAAI,SACJC,GAAI,SACJxS,GAAI,SACJyS,GAAI,YACJjS,GAAI,qBACJkS,GAAI,sBACJ1V,GAAI,UACJ2V,GAAI,QACJC,GAAI,QACJze,GAAI,kBACK,eACT0e,GAAI,SACJptE,GAAI,qBACK,sBACTsgD,GAAI,kBACK,0BACA,qBACT+sB,GAAI,UACJC,GAAI,iBACJC,GAAI,mBACK,sBACTC,GAAI,kBACK,qBACTC,GAAI,iBACJC,GAAI,QACJp+D,GAAI,WACJ8oD,GAAI,YACJ/D,GAAI,SACJsZ,GAAI,aACJC,GAAI,UACJC,GAAI,SACJv7B,GAAI,YACJw7B,GAAI,SACJtT,GAAI,UACJuT,GAAI,kBACK,8BACA,4BACA,0BACA,6BACA,+BACA,uCACA,4BACA,gCACA,8BACA,6BACA,2BACA,8BACA,2BACA,6BACA,yBACA,gCACA,0BACA,4BACA,sBACT5vE,GAAI,OACJ6vE,GAAI,UACJ7iC,GAAI,kBACK,4BACA,mBACTqrB,GAAI,QACJyX,GAAI,QACJjK,GAAI,SACJkK,GAAI,OACJC,IAAK,QACLC,GAAI,SACJC,GAAI,SACJ9hC,GAAI,UACJ+hC,GAAI,UACJC,GAAI,YACJC,IAAK,gBACLC,GAAI,OACJ9S,GAAI,QACJ+S,GAAI,aACJC,GAAI,UACJ1f,GAAI,UACJvmB,GAAI,QACJkmC,GAAI,QACJC,GAAI,UACJC,GAAI,QAQQ7E,iBACP93E,SAAS+3E,iBAAiB6E,aAAe9E,UAEM,IAAhD3vF,KAAK6X,SAAS+3E,iBAAiBC,oBAC5Bh4E,SAAS2L,OAAOpP,UAAU,cAAc,gBACtCyD,SAASmI,MAAM,UAAYhgB,KAAK6X,SAAS+3E,iBAAiB6E,aAAe,aAE3E58E,SAAS+3E,iBAAiBC,cAAe,IAI3C7vF,OAER0W,MAAMkB,KASEA,IAwURlB,MAAMkB,IA5THsrD,mBAAqBtrD,IAAIsrD,mBAAqB,SAAUt0C,KAAMjY,aAW5D5H,EAEA2lF,UAXAz9D,YADJtgB,QAAUA,SAAW,IACI8T,MAAQzqB,KAAK6X,SAAS4Y,UAC3C/P,SAAW/J,QAAQ+J,UAAY1gB,KAAK6X,SAASyD,cAC7C6Y,UAAYxd,QAAQwd,WAAan0B,KAAK6X,SAASye,eAC/Cq+D,OAASh+E,QAAQg+E,OAASh+E,QAAQg+E,OAAS19D,WAAWpJ,SAAS+mE,QAAQD,OACvEE,iBAAmBF,OAAOG,IAAMH,OAAOG,IAAM,EAC7CC,QAAUp+E,QAAQo+E,QAAUp+E,QAAQo+E,QAAU99D,WAAWpJ,SAAS+mE,QAAQG,QAC1EC,kBAAoBD,QAAQD,IAAMC,QAAQD,IAAM,EAChDx9D,WAAkC,IAAtB3gB,QAAQ2gB,UACpB29D,aAAe,EAEfjmF,OAAS4f,KAAK5f,OAEdkmF,gBAAkB,EAElBC,mBAAqBR,OAAO,IAAME,iBAClCrjE,OAAS,OAERziB,EAAI,EAAGA,EAAIC,OAAQD,IACtB2lF,UAAY9lE,KAAK9d,WAAW/B,GAEqB,mBAAtCkoB,WAAWpJ,SAASunE,cAC7B5jE,OAAOnc,MAAM4hB,WAAWpJ,SAASwnE,aAAap+D,WAAWpJ,SAASynE,iBAAiBZ,YAAcvgE,WAAa,IAAOzT,WAAa,GAAK,MAGrIu0E,aADE39D,WAA6C,WAAhCr3B,QAAQ80F,QAAQL,cAA6BplF,MAAMR,SAASimF,QAAQL,WAAWQ,iBAAkB,KACjGH,QAAQL,WAAWQ,iBAAmBF,kBAEtC,EAGjBxjE,OAAOnc,MAAMs/E,OAAOD,YAAcS,oBAAsBN,iBAAmBI,eAG7EC,gBAAkBR,iBAGbljE,QAoBL6F,mBAAqBzf,IAAIyf,mBAAqB,SAAUzI,KAAMjY,aAE5D+J,UADJ/J,QAAUA,SAAW,IACE+J,UAAY1gB,KAAK6X,SAASyD,cAC7CmP,KAAO9T,QAAQ8T,MAAQzqB,KAAK6X,SAAS4Y,UACrC0D,UAAYxd,QAAQwd,WAAan0B,KAAK6X,SAASye,sBAG/C1e,IAAIghC,gBACNhqB,KAAOhX,IAAIghC,cAAchqB,OAGgB,mBAAhCnE,KAAKoD,SAASunE,cACd3qE,KAAKoD,SAASunE,cAAcxmE,KAAMlO,SAAUyT,WAAazT,SAEzDwiD,mBAAmBtiE,MAAMZ,KAAMa,WAAW+0B,QAAO,SAAU0nB,GAAIC,WAC/DD,GAAKC,KACX,IAUH4lB,cAAgB,SAAuB7/B,KAAMiyD,aAAcC,gBAAiBC,gBAC1EC,OAAS,GAET3mF,EAAI,EACJkf,EAAIqV,KAAKt0B,OACT2mF,WAAa,EAEV5mF,IAAMkf,GAAK0nE,WAAaJ,aAAaxmF,GAAKymF,iBAC/CG,YAAcJ,aAAaxmF,GAC3BA,IAIF2mF,OAAOrgF,KAAKiuB,KAAKtvB,MAAM,EAAGjF,QAEtB6mF,YAAc7mF,MAClB4mF,WAAa,EAEN5mF,IAAMkf,GACP0nE,WAAaJ,aAAaxmF,GAAK0mF,SACjCC,OAAOrgF,KAAKiuB,KAAKtvB,MAAM4hF,YAAa7mF,IACpC4mF,WAAa,EACbC,YAAc7mF,GAGhB4mF,YAAcJ,aAAaxmF,GAC3BA,WAGE6mF,cAAgB7mF,GAClB2mF,OAAOrgF,KAAKiuB,KAAKtvB,MAAM4hF,YAAa7mF,IAG/B2mF,QAKLtyB,wBAA0B,SAAiCx0C,KAAMinE,OAAQl/E,SAGtEA,UACHA,QAAU,QAQR2sB,KACAiyD,aAGAxmF,EACAkf,EACAsG,IACAuhE,WA0EAC,YAtFAp7D,KAAO,GACPC,MAAQ,CAACD,MACTq7D,YAAcr/E,QAAQs/E,YAAc,EACpCC,iBAAmB,EACnBC,oBAAsB,EAGtBz9C,MAAQ9pB,KAAK1d,MAAM,KACnBklF,eAAiBlzB,mBAAmBtiE,MAAMZ,KAAM,CAAC,IAAK2W,UAAU,MAOlEm/E,YAD0B,IAAxBn/E,QAAQm/E,WACGp9C,MAAM,GAAG1pC,OAAS,EAElB2H,QAAQm/E,YAAc,EAGrB,KACVO,IAAMlkF,MAAM2jF,YAAYtkF,KAAK,KAC7B8kF,KAAO,GACX59C,MAAMnnC,KAAI,SAAUglF,MAClBA,IAAMA,IAAIrlF,MAAM,UAERlC,OAAS,EACfsnF,KAAOA,KAAKrhE,OAAOshE,IAAIhlF,KAAI,SAAUglF,IAAKC,YAChCA,KAAOD,IAAIvnF,OAAS,KAAO,IAAMunF,QAG3CD,KAAKjhF,KAAKkhF,IAAI,OAGlB79C,MAAQ49C,KACRR,WAAaz+D,mBAAmBz2B,MAAMZ,KAAM,CAACq2F,IAAK1/E,cAG/C5H,EAAI,EAAGkf,EAAIyqB,MAAM1pC,OAAQD,EAAIkf,EAAGlf,IAAK,KACpCxK,MAAQ,KACZ++B,KAAOoV,MAAM3pC,GAET+mF,YAAyB,MAAXxyD,KAAK,KACrBA,KAAOA,KAAK99B,OAAO,GACnBjB,MAAQ,GAQNyxF,YAAcE,kBAJlBC,qBADAZ,aAAeryB,mBAAmBtiE,MAAMZ,KAAM,CAACsjC,KAAM3sB,WAClBif,QAAO,SAAU0nB,GAAIC,WAC/CD,GAAKC,KACX,IAEwDs4C,QAAUtxF,MAAO,IACtE4xF,oBAAsBN,OAAQ,KAGhCthE,IAAM4uC,cAAcviE,MAAMZ,KAAM,CAACsjC,KAAMiyD,aAAcM,QAAUG,YAAcE,kBAAmBL,SAEhGl7D,KAAKtlB,KAAKkf,IAAIW,SAGdyF,KAAO,CAACpG,IAAIvN,OAELuN,IAAIvlB,QACT4rB,MAAMvlB,KAAK,CAACkf,IAAIW,UAGlBihE,oBAAsBZ,aAAavhF,MAAMsvB,KAAKt0B,QAAU2rB,KAAK,GAAKA,KAAK,GAAG3rB,OAAS,IAAI4mB,QAAO,SAAU0nB,GAAIC,WACnGD,GAAKC,KACX,QAGH5iB,KAAO,CAAC2I,MAIV1I,MAAMvlB,KAAKslB,MACXq7D,YAAcG,oBAAsBL,WACpCI,iBAAmBE,oBAEnBz7D,KAAKtlB,KAAKiuB,MACV0yD,aAAeE,iBAAmBC,oBAClCD,iBAAmBE,sBAOrBL,YADED,WACY,SAAqB3jC,GAAIqkC,YAC7BA,IAAMH,IAAM,IAAMlkC,GAAG3gD,KAAK,MAGtB,SAAqB2gD,WAC1BA,GAAG3gD,KAAK,MAIZopB,MAAMrpB,IAAIwkF,cAqBnBn+E,IAAI+d,gBAAkB,SAAU/G,KAAMinE,OAAQl/E,aAsCxC8/E,WAlCAC,OAFJ//E,QAAUA,SAAW,IAED+J,UAAY1gB,KAAK6X,SAASyD,cAC1Cq7E,WAAa,SAAUhgF,YAMpBA,QAAQg+E,QAAWh+E,QAAQo+E,cAmBvB,CACLJ,OAAQh+E,QAAQg+E,OAChBI,QAASp+E,QAAQo+E,aApBfpwE,EAAI3kB,KAAK6X,SAAS4Y,QAAQ9Z,QAAQ+W,SAAU/W,QAAQ+E,kBAKpDiJ,EAAEkJ,SAAF,QACK,CACL8mE,OAAQhwE,EAAEkJ,SAAF,QAAqB8mE,QAbtB,GACR,GAaCI,QAASpwE,EAAEkJ,SAAF,QAAqBknE,SAXtB,IAcH,CACLtqE,KAAM9F,EAAEkJ,SACRnN,SAAU1gB,KAAK6X,SAASyD,cACxB6Y,UAAWn0B,KAAK6X,SAASye,iBAS/Bt1B,KAAKhB,KAAM2W,SAMX8/E,WADEtkF,MAAMgX,QAAQyF,MACHA,KAEA5qB,OAAO4qB,MAAM1d,MAAM,aAM9B0lF,gBAAkB,EAAM52F,KAAK6X,SAASsD,YAAc06E,OAASa,MAQjEC,WAAWV,WAAat/E,QAAQs/E,WAAkC,EAArBt/E,QAAQs/E,WAAmBj2F,KAAK6X,SAASsD,YAAcu7E,MAAQ,EAC5GC,WAAWb,WAAan/E,QAAQm/E,eAC5B/mF,EACAkf,EACAuD,OAAS,OAERziB,EAAI,EAAGkf,EAAIwoE,WAAWznF,OAAQD,EAAIkf,EAAGlf,IACxCyiB,OAASA,OAAOyD,OAAOmuC,wBAAwBxiE,MAAMZ,KAAM,CAACy2F,WAAW1nF,GAAI6nF,gBAAiBD,qBAGvFnlE,iBAwBA5Z,KAETA,IAAIi/E,gBAAkBj/E,IAAIi/E,iBAAmB,WAEzCC,QAAU,mBACVC,kBAAoB,GACpBC,gBAAkB,GAEbjoF,EAAI,EAAGA,EAAI+nF,QAAQ9nF,OAAQD,IAClCgoF,kBAAkBD,QAAQ/nF,IANd,mBAM4BA,GACxCioF,gBAPY,mBAOYjoF,IAAM+nF,QAAQ/nF,OAGpC4C,IAAM,SAAauG,aACd,KAAOpJ,SAASoJ,MAAO,IAAIzI,SAAS,KAGzC6H,SAAWM,IAAIi/E,gBAAgBv/E,SAAW,SAAUvF,UAElDmG,MAAO++E,UAAWC,YAAaC,aAD/BC,KAAO,CAAC,SAGP,IAAItlF,OAAOC,KAAM,IACpBmG,MAAQnG,KAAKD,KAERxC,MAAMR,SAASgD,IAAK,KAKvBmlF,UAAY,IAAMnlF,IAAM,KAJxBA,IAAMhD,SAASgD,IAAK,IAEpBmlF,WADAA,UAAYtlF,IAAIG,KAAKkC,MAAM,IACLA,MAAM,GAAI,GAAKgjF,gBAAgBC,UAAUjjF,OAAO,KAKpD,iBAATkE,MACLA,MAAQ,GACVg/E,YAAcvlF,IAAIuG,OAAOlE,MAAM,GAC/BmjF,aAAe,MAEfD,YAAcvlF,IAAIuG,OAAOlE,MAAM,GAC/BmjF,aAAe,IAGjBD,YAAcC,aAAeD,YAAYljF,MAAM,GAAI,GAAKgjF,gBAAgBE,YAAYljF,OAAO,QACtF,IACkB,WAAnB/T,QAAQiY,aAGJ,IAAIhF,MAAM,yCAA2CjT,QAAQiY,OAAS,KAF5Eg/E,YAAc5/E,SAASY,OAM3Bk/E,KAAK/hF,KAAK4hF,UAAYC,oBAGxBE,KAAK/hF,KAAK,KACH+hF,KAAK5lF,KAAK,KAYf6lF,WAAaz/E,IAAIi/E,gBAAgBQ,WAAa,SAAUtlF,SACtC,iBAATA,WACH,IAAImB,MAAM,kDAKdokF,YAIAC,gBAGAzlF,IAIJqd,GAbIqC,OAAS,GACTgmE,KAAO,EAGXC,aAAejmE,OACXkmE,YAAc,GAEdC,SAAW,GACXC,WAAa,GAGjBC,QAAU9lF,KAAK/C,OAAS,EAIfD,EAAI,EAAGA,EAAI8oF,QAAS9oF,GAAK,EAItB,MAFVogB,GAAKpd,KAAKhD,IAGJuoF,aAEFxlF,IAAMwlF,YAAY9lF,KAAK,IACvB8lF,iBAAcl2E,GAGdk2E,YAAc,GAEPA,YACTA,YAAYjiF,KAAK8Z,IACF,KAANA,IAETuoE,YAAYriF,KAAK,CAACoiF,aAAc3lF,MAChC2lF,aAAe,GACf3lF,SAAMsP,GACS,KAAN+N,KAETooE,gBAAkBG,YAAY1wE,OACd,GAAGuwE,gBAAgB,IAAME,aACzC3lF,SAAMsP,EACNq2E,aAAeF,gBAAgB,IAChB,KAANpoE,GACTqoE,MAAQ,OAGIp2E,IAARtP,IACEilF,kBAAkBviF,eAAe2a,KACnCwoE,UAAYZ,kBAAkB5nE,IAC9Brd,IAAMhD,SAAS6oF,SAAU,IAAMH,KAC/BA,KAAO,EACPG,SAAW,IAEXA,UAAYxoE,GAGV4nE,kBAAkBviF,eAAe2a,KACnCyoE,YAAcb,kBAAkB5nE,IAChCsoE,aAAa3lF,KAAOhD,SAAS8oF,WAAY,IAAMJ,KAC/CA,KAAO,EACP1lF,SAAMsP,EACNw2E,WAAa,IAEbA,YAAczoE,UAMfqC,QAcLzC,cAAgB,CAClBO,UAAW,CAAC,mBACZwoE,gBAAiBT,WAAW,+JAE1BU,UAAY,CACdnD,QAAS,CACPoD,QAASjpE,6BACOA,oCACOA,gCACJA,cACnB+1B,UAAW/1B,+BACOA,sCACOA,kCACJA,4BACNA,2BACDA,iCACMA,6BACJA,gBAKhBkpE,YAAc,CAChBrD,QAAS,mBAOYyC,WAAW,gEACVA,WAAW,myDACbA,WAAW,gnDAC7BW,QAASX,WAAW,mEACGA,WAAW,0DACpBA,WAAW,yzDACzBl3F,OAAQk3F,WAAW,sNACnBvyC,UAAWuyC,WAAW,wsDACGA,WAAW,gnDACpCa,aAAcb,WAAW,gEACTA,WAAW,4DACXA,WAAW,msDACZA,WAAW,83DACLA,WAAW,krDAepCz/E,IAAI4L,OAAOnO,KAAK,CAAC,UAAW,SAAUtD,UAChC0Y,KAAO1Y,KAAK0Y,KACZ0tE,QAAUF,YAAW,QAAYxtE,KAAKE,gBAEtCwtE,UACF1tE,KAAKoD,SAAL,QAA2B,GAC3BpD,KAAKoD,SAAL,QAAyB8mE,OAASwD,QAAQxD,OAC1ClqE,KAAKoD,SAAL,QAAyBknE,QAAUoD,QAAQpD,aAGzChmE,cAAgBgpE,UAAS,QAAYttE,KAAKE,gBAE1CoE,gBACFtE,KAAKoD,SAAL,QAAyBjD,SAAWmE,cACpCtE,KAAKG,SAAWmE,cAAcO,UAAU,QAG3C5Y,MAAMkB;;;;;;SAYElB,WAELy9B,yBAA2B,SAAkCC,uBAC3Dl0B,IAAMk0B,cAAcplC,OACpB2xB,MAAQ,IAAIrgB,WAAWJ,KAElBnR,EAAI,EAAGA,EAAImR,IAAKnR,IACvB4xB,MAAM5xB,GAAKqlC,cAActjC,WAAW/B,UAG/B4xB,OAoBTjqB,MAAMkB,IAAI4L,OAAOnO,KAAK,CAAC,UAAW,SAAUtD,UACtCqmF,UAAOh3E,EACPqJ,KAAO1Y,KAAK0Y,KACZqD,SAAW/b,KAAK+b,aAEhBrD,KAAKmD,wBAIe,IAAbE,eAaH,IAAI5a,MAAM,+EAAiFuX,KAAKE,eAAiB,UANnG,iBALlBytE,MADoD,IAAlDtqE,SAASuqE,gBAAgB5tE,KAAKE,gBACzBmD,SAAS6iB,SAASlmB,KAAKE,gBAEvBmD,SAASwqE,eAAe7tE,KAAKE,uBAI9B,IAAIzX,MAAM,6FAA+FuX,KAAKE,eAAiB,QAlC7H,SAAiBF,KAAM2tE,MAGjCA,KADE,oBAAoBv0F,KAAKu0F,MACpBjkD,yBAAyBikD,MAEzBjkD,yBAAyBzxC,KAAK01F,OAGvC3tE,KAAKoD,SAAWnX,MAAMkB,IAAI2gF,QAAQ/2F,KAAK42F,MACvC3tE,KAAKoD,SAAS+mE,QAAUnqE,KAAKoD,SAAS+mE,SAAW,CAC/ChqE,SAAU,GACVmqE,QAAS,GACTJ,OAAQ,IAEVlqE,KAAKoD,SAAS2qE,WAAa,CAAC,GAuB1B7qE,CAAQlD,KAAM2tE,WAKjB1hF,gBASQsqB,mBAEAy3D,mBAEDl4F,aAAY,MACPq/B,QAAQC,QAAQt/B,aAAY,OAGqC,iBAAlD,IAAZb,QAA0B,YAAcO,QAAQP,WAA4C,oBAAXC,OACpF,IAAIigC,SAAQ,SAAUC,QAASC,YAElCD,QAAQ0vB,QAAQ,UAChB,MAAOvtD,GACP89B,OAAO99B,OAKS,mBAAXpC,QAAyBA,OAAOC,IAClC,IAAI+/B,SAAQ,SAAUC,QAASC,YAElCyvB,QAAQ,CAAC,SAAU1vB,SACnB,MAAO79B,GACP89B,OAAO99B,OAKN49B,QAAQE,OAAO,IAAI5sB,MAAM,0BAC9B6nD,OAAM,SAAU/4D,UACX49B,QAAQE,OAAO,IAAI5sB,MAAM,yBAA2BlR,OAC1Dg5D,MAAK,SAAU09B,cACTA,MAAMx9B,QAAUw9B,MAAMx9B,QAAUw9B,SAwB3C13D,SAAS23D,cAAgB,SAAUC,IAAKjpF,EAAG+M,EAAGsJ,EAAGC,EAAG8qB,MAAO0D,YAAavD,aAClE5hC,MAAMK,IAAML,MAAMoN,SACpBhc,QAAQO,MAAM,2CAA4CJ,WACpD,IAAIqS,MAAM,wDAGd5D,MAAM0W,IAAM1W,MAAM2W,SACpBvlB,QAAQO,MAAM,4CAA6CJ,WACrD,IAAIqS,MAAM,gFAGd+mC,OAAS13C,SAASU,cAAc,UACpCg3C,OAAOhvB,MAAQjF,EACfi0B,OAAO/uB,OAASjF,MACZs7B,IAAMtH,OAAOb,WAAW,MAC5BmI,IAAII,UAAY,OAEhBJ,IAAIiF,SAAS,EAAG,EAAGvM,OAAOhvB,MAAOgvB,OAAO/uB,YACpCvU,QAAU,CACZkiF,aAAa,EACbC,iBAAiB,EACjBC,kBAAkB,GAEhBC,IAAMh5F,YACHy4F,YAAYz9B,MAAK,SAAU09B,cACzBA,MAAMO,WAAW13C,IAAKq3C,IAAKjiF,YACjC,kBACMipB,QAAQE,OAAO,IAAI5sB,MAAM,6BAC/B8nD,MAAK,SAAUltC,iBACTA,SAASg0C,OAAOnrD,YACtBqkD,MAAK,WACNg+B,IAAIxkD,SAASyF,OAAOpJ,UAAU,aAAc,GAAMlhC,EAAG+M,EAAGsJ,EAAGC,EAAGwuB,YAAavD,eAG9Ex6B,MAAMkB;;;;;;;;;;;;;;;;;;;;;;;;;;SAiCEopB,UAQTA,SAASk4D,cAAgB,SAAUC,oBAE7BC,kBACAC,mBAAqB,EAErBvqF,SAAS9O,KAAK6X,SAAS4Y,UAAU7a,GAAGpQ,OAAO,GAAI,IAAM,IACvD4zF,kBAAoB,IAAIp/B,OAAOm/B,eAAgB,KAC/CE,mBAAqBr5F,KAAK6X,SAAS2Y,qBAEnC4oE,kBAAoB,IAAIp/B,OAAOh6D,KAAKs5F,YAAYH,eAAgBn5F,KAAK6X,SAAS4Y,WAAY,KAC1F4oE,mBAAqBr5F,KAAKs5F,YAAYt5F,KAAK6X,SAAS2Y,mBAAqB,GAAIxwB,KAAK6X,SAAS4Y,gBAGxF,IAAIhgB,EAAI,EAAGA,GAAKzQ,KAAK6X,SAAS2Y,mBAAoB/f,QAChD,IAAI1B,EAAI,EAAGA,EAAI/O,KAAK6X,SAASuH,MAAM3O,GAAGzB,OAAQD,SAC5C8I,SAASuH,MAAM3O,GAAG1B,GAAK/O,KAAK6X,SAASuH,MAAM3O,GAAG1B,GAAG9J,QAAQm0F,kBAAmBC,2BAI9Er5F,OAER0W,MAAMkB,cAUEopB,UA2FTA,SAASu4D,kBAAoB,SAAU5iF,QAAS6iF,aAG1CC,cAFJ9iF,QAAUA,SAAW,GACrB6iF,QAAUA,UAAW,MAiJjBE,QACAC,OACAzhF,MAjJA0hF,sBAAwB,CAC1BC,YAAa,CACXC,cAAc,EACd5hF,OAAO,EACPpU,KAAM,UACNi2F,aAAa,EACbC,SAAU,EAAC,GAAM,GACjBjiF,WAAY,KAEdkiF,YAAa,CACXH,cAAc,EACd5hF,OAAO,EACPpU,KAAM,UACNi2F,aAAa,EACbC,SAAU,EAAC,GAAM,GACjBjiF,WAAY,KAEdmiF,aAAc,CACZJ,cAAc,EACd5hF,OAAO,EACPpU,KAAM,UACNi2F,aAAa,EACbC,SAAU,EAAC,GAAM,GACjBjiF,WAAY,KAEdoiF,UAAW,CACTL,cAAc,EACd5hF,OAAO,EACPpU,KAAM,UACNi2F,aAAa,EACbC,SAAU,EAAC,GAAM,GACjBjiF,WAAY,KAEdqiF,aAAc,CACZN,cAAc,EACd5hF,OAAO,EACPpU,KAAM,UACNi2F,aAAa,EACbC,SAAU,EAAC,GAAM,GACjBjiF,WAAY,KAEdsiF,gBAAiB,CACfP,cAAc,EACd5hF,OAAO,EACPpU,KAAM,UACNi2F,aAAa,EACbC,SAAU,EAAC,GAAM,GACjBjiF,WAAY,KAEduiF,sBAAuB,CACrBR,aAAc,UACd5hF,MAAO,UACPpU,KAAM,OACNi2F,aAAa,EACbC,SAAU,CAAC,UAAW,cAAe,YAAa,SAClDjiF,WAAY,KAEdwiF,UAAW,CACTT,aAAc,MACd5hF,MAAO,MACPpU,KAAM,OACNi2F,aAAa,EACbC,SAAU,CAAC,MAAO,OAClBjiF,WAAY,KAEdyiF,SAAU,CACRV,aAAc,UACd5hF,MAAO,UACPpU,KAAM,OACNi2F,aAAa,EACbC,SAAU,CAAC,WAAY,UAAW,UAAW,WAAY,UACzDjiF,WAAY,KAEd0iF,SAAU,CACRX,aAAc,UACd5hF,MAAO,UACPpU,KAAM,OACNi2F,aAAa,EACbC,SAAU,CAAC,WAAY,UAAW,UAAW,WAAY,UACzDjiF,WAAY,KAEd2iF,UAAW,CACTZ,aAAc,UACd5hF,MAAO,UACPpU,KAAM,OACNi2F,aAAa,EACbC,SAAU,CAAC,WAAY,UAAW,UAAW,WAAY,UACzDjiF,WAAY,KAEd4iF,UAAW,CACTb,aAAc,UACd5hF,MAAO,UACPpU,KAAM,OACNi2F,aAAa,EACbC,SAAU,CAAC,WAAY,UAAW,UAAW,WAAY,UACzDjiF,WAAY,KAEd6iF,aAAc,CACZd,aAAc,aACd5hF,MAAO,aACPpU,KAAM,OACNi2F,aAAa,EACbC,SAAU,CAAC,aAAc,QACzBjiF,WAAY,KAEd8iF,OAAQ,CACNf,aAAc,GACd5hF,MAAO,OACPpU,KAAM,OACNi2F,aAAa,EACbC,SAAU,CAAC,UAAW,sBAAuB,qBAAsB,QACnEjiF,WAAY,KAEd+iF,kBAAmB,CACjBhB,cAAc,EACd5hF,OAAO,EACPpU,KAAM,UACNi2F,aAAa,EACbC,SAAU,EAAC,GAAM,GACjBjiF,WAAY,KAEdgjF,eAAgB,CACdjB,aAAc,GACd5hF,MAAO,GACPpU,KAAM,QACNi2F,aAAa,EACbC,SAAU,KACVjiF,WAAY,KAEdijF,UAAW,CACTlB,aAAc,EACd5hF,MAAO,EACPpU,KAAM,UACNi2F,aAAa,EACbC,SAAU,KACVjiF,WAAY,MAGZkjF,kBAAoBpmF,OAAOC,KAAK8kF,uBAChCsB,WAAa,GACbnsF,EAAI,EACJqC,EAAI,EACJxB,EAAI,WAKCurF,qBAAqBn0D,MAAOqJ,aAC/BjwC,SACA4E,QAAS,MAER5E,SAAW,EAAGA,SAAW4mC,MAAMh4B,OAAQ5O,UAAY,EAClD4mC,MAAM5mC,YAAciwC,UACtBrrC,QAAS,UAINA,eAG+Boc,IAApCphB,KAAK6X,SAASujF,yBACXvjF,SAASujF,kBAAoB,QAC7BvjF,SAASujF,kBAAkB3B,cAAgBvnE,KAAKyT,MAAMzT,KAAKC,UAAUynE,6BACrE/hF,SAASujF,kBAAkBvL,cAAe,GAGjD4J,cAAgBz5F,KAAK6X,SAASujF,kBAAkB3B,cAEhC,UAAZ9iF,UAAmC,IAAZ6iF,QAAkB,KACvCt5E,IAAM+6E,kBAAkBjsF,WAEvBY,EAAI,EAAGA,EAAIsQ,IAAKtQ,GAAK,EACxB6pF,cAAcwB,kBAAkBrrF,IAAIsI,MAAQuhF,cAAcwB,kBAAkBrrF,IAAIkqF,aAChFL,cAAcwB,kBAAkBrrF,IAAImqF,aAAc,KAI7B,WAArB95F,QAAQ0W,aACLgjF,UAAUhjF,WACbuB,MAAQvB,QAAQgjF,QAEZwB,qBAAqBF,kBAAmBtB,cAAqBv4E,IAAVlJ,MAAqB,IACvC,YAA/BuhF,cAAcE,QAAQ71F,MAAuC,kBAAVoU,MACrDuhF,cAAcE,QAAQzhF,MAAQA,WACzB,GAAmC,SAA/BuhF,cAAcE,QAAQ71F,MAAmBq3F,qBAAqB1B,cAAcE,QAAQK,SAAU9hF,OACvGuhF,cAAcE,QAAQzhF,MAAQA,WACzB,GAAmC,YAA/BuhF,cAAcE,QAAQ71F,MAAsBwpB,OAAOqe,UAAUzzB,OACtEuhF,cAAcE,QAAQzhF,MAAQA,WACzB,GAAmC,UAA/BuhF,cAAcE,QAAQ71F,KAAkB,KAC5CiL,EAAI,EAAGA,EAAImJ,MAAMlJ,OAAQD,GAAK,KACjC2qF,SAAU,EAEc,IAApBxhF,MAAMnJ,GAAGC,QAAuC,iBAAhBkJ,MAAMnJ,GAAG,GAC3CmsF,WAAW7lF,KAAKrR,OAAOkU,MAAMnJ,GAAK,SAC7B,GAAImJ,MAAMnJ,GAAGC,OAAS,EAAG,KACzBoC,EAAI,EAAGA,EAAI8G,MAAMnJ,GAAGC,OAAQoC,GAAK,EACT,iBAAhB8G,MAAMnJ,GAAGqC,KAClBsoF,SAAU,IAIE,IAAZA,SACFwB,WAAW7lF,KAAK,CAAC6C,MAAMnJ,GAAG,GAAK,EAAGmJ,MAAMnJ,GAAG,GAAK,GAAGyC,KAAK,MAK9DioF,cAAcE,QAAQzhF,MAAQ,IAAMgjF,WAAW1pF,KAAK,KAAO,SAE3DioF,cAAcE,QAAQzhF,MAAQuhF,cAAcE,QAAQG,aAGtDL,cAAcE,QAAQI,aAAc,SAKW,IAAjD/5F,KAAK6X,SAASujF,kBAAkBvL,oBAC7Bh4E,SAAS2L,OAAOpP,UAAU,cAAc,eAEvCinF,MADAC,QAAU,OAGTD,SAAS5B,eAC6B,IAArCA,cAAc4B,OAAOtB,cACW,SAA9BN,cAAc4B,OAAOv3F,KACvBw3F,QAAQjmF,KAAK,IAAMgmF,MAAQ,KAAO5B,cAAc4B,OAAOnjF,OAEvDojF,QAAQjmF,KAAK,IAAMgmF,MAAQ,IAAM5B,cAAc4B,OAAOnjF,QAKrC,IAAnBojF,QAAQtsF,aACL6I,SAASmI,MAAM,2BAA6Bs7E,QAAQ9pF,KAAK,MAAQ,gBAGrEqG,SAASujF,kBAAkBvL,cAAe,QAG5Ch4E,SAASujF,kBAAkB3B,cAAgBA,cACzCz5F,OAER0W,MAAMkB;;;;;;;;;;;;;;;;;;;;;;;;;;SAgCEopB,cAELu6D,iBAAmB,eAEjBC,cAAgB,+GAAiHx7F,KAAK6X,SAAS4jF,aAAaC,aAAe,qBAG3KC,uBAAyB9pE,SAASC,mBAJd,yCAKpB8pE,mBAAqB/pE,SAASC,mBAAmB0pE,gBACjDK,cAAgBhqE,SAASC,mBAAmB9xB,KAAK6X,SAAS4jF,aAAa5tE,WACvEiuE,gBAAkBjqE,SAASC,mBALd,kDAMbiqE,oBAAsBlqE,SAASC,mBALd,iBAMjBkqE,UAAYJ,mBAAmB5sF,OAAS6sF,cAAc7sF,OAAS8sF,gBAAgB9sF,OAAS2sF,uBAAuB3sF,OAAS+sF,oBAAoB/sF,YAC3I6I,SAAS4jF,aAAaQ,uBAAyBj8F,KAAK6X,SAASqP,iBAC7DrP,SAASmI,MAAM,4CAA8Cg8E,UAAY,YACzEnkF,SAASmI,MAAM,eACfnI,SAASmI,MAAM27E,uBAAyBC,mBAAqBC,cAAgBC,gBAAkBC,0BAC/FlkF,SAASmI,MAAM,kBACfnI,SAASmI,MAAM,WAGlB+Q,WAAa,WACX/wB,KAAK6X,SAAS4jF,aAAaQ,6BACxBpkF,SAASmI,MAAM,aAAehgB,KAAK6X,SAAS4jF,aAAaQ,uBAAyB,SAc3Fj7D,SAASk7D,YAAc,SAAUruE,SAAU6tE,0BACC,IAA/B17F,KAAK6X,SAAS4jF,oBAClB5jF,SAAS4jF,aAAe,CAC3B5tE,SAAUA,SACV6tE,aAAcA,cAAgB,2CAE3B7jF,SAAS2L,OAAOpP,UAAU,aAAc2c,iBACxClZ,SAAS2L,OAAOpP,UAAU,mBAAoBmnF,mBAG9Cv7F,OAER0W,MAAMkB,cAOElB,WAELsqB,SAAWtqB,MAAMkB,IAWjB0hF,YAAct4D,SAASs4D,YAAc,SAAU1qE,KAAMnE,cAKtBla,EAJ7BokF,OAASlqE,KAAKoD,SAAS+mE,QAAQD,OAC/BwH,KAAO,CAAC,GAAI,IAAK,KAAM,MAAO,QAC9BhvC,GAAK,CAAC,IAEDp+C,EAAI,EAAGkf,EAAIW,KAAK5f,OAAWD,EAAIkf,IAAKlf,EAAG,IAC9CwB,EAAIka,KAAKoD,SAASynE,iBAAiB1mE,KAAK9d,WAAW/B,IACnD0b,KAAKoD,SAAS2qE,WAAWnjF,KAAK9E,GAC9Bka,KAAKoD,SAASuuE,UAAU7rF,GAAKqe,KAAK9d,WAAW/B,IAEnB,GAAtB4lF,OAAOh/E,QAAQpF,KACjBokF,OAAOt/E,KAAK9E,GACZokF,OAAOt/E,KAAK,CAACvG,SAAS2b,KAAKoD,SAASwnE,aAAa9kF,GAAI,OAG9C,KAALA,SAEK48C,GAAG37C,KAAK,IAEfjB,EAAIA,EAAEd,SAAS,IACf09C,GAAG93C,KAAK8mF,KAAK,EAAI5rF,EAAEvB,QAASuB,UAIzB48C,GAAG37C,KAAK,KAGb6qF,cAAgB,SAAuB9qF,SACrC85D,KAAMixB,MAAOC,MAAOC,QAASC,WAAY14B,GAAIyD,SAEjDi1B,WAAa,iQAIbF,MAAQ,GAEHx4B,GAAK,EAAGyD,MALb80B,MAAQznF,OAAOC,KAAKvD,KAAKm4B,MAAK,SAAU1mC,EAAGqM,UAClCrM,EAAIqM,MAIaL,OAAQ+0D,GAAKyD,KAAMzD,KAC3CsH,KAAOixB,MAAMv4B,IAETw4B,MAAMvtF,QAAU,MAClBytF,YAAc,KAAOF,MAAMvtF,OAAS,iBAAmButF,MAAM/qF,KAAK,MAAQ,cAC1E+qF,MAAQ,SAGQn7E,IAAd7P,IAAI85D,OAAqC,OAAd95D,IAAI85D,OAAgD,mBAAvB95D,IAAI85D,MAAM57D,WACpE+sF,SAAW,OAASjrF,IAAI85D,MAAM57D,SAAS,KAAKuE,OAAO,GACnDq3D,MAAQ,SAAWA,MAAM57D,SAAS,KAAKuE,OAAO,GAC9CuoF,MAAMlnF,KAAK,IAAMg2D,KAAO,KAAOmxB,QAAU,aAIzCD,MAAMvtF,SACRytF,YAAc,KAAOF,MAAMvtF,OAAS,iBAAmButF,MAAM/qF,KAAK,MAAQ,iBAG5EirF,YAAc,oEAiFhBz7D,SAASxd,OAAOnO,KAAK,CAAC,UAAW,SAAUL,OA7EnB,SAA2B2B,aAC7C8T,KAAO9T,QAAQ8T,KACfrY,IAAMuE,QAAQvE,IACd8U,UAAYvQ,QAAQuQ,UACpBqB,UAAY5R,QAAQ4R,aAEpBkC,KAAKoD,oBAAoBnX,MAAMkB,IAAI2gF,SAA6B,eAAlB9tE,KAAKG,SAA2B,SAE5E+pE,OAASlqE,KAAKoD,SAAS+mE,QAAQD,OAE/B+H,UADOjyE,KAAKoD,SAAS8uE,OAAOnqB,OAAO/nD,KAAKoD,SAAS2qE,WAAY,GAE7DoE,WAAa,GAER7tF,EAAI,EAAGA,EAAI2tF,UAAU1tF,OAAQD,IACpC6tF,YAAc54F,OAAOC,aAAay4F,UAAU3tF,QAG1C8tF,UAAY31E,YAChBqB,UAAU,CACRxW,KAAM6qF,WACNn0E,YAAY,EACZE,SAAUk0E,YAEZzqF,IAAI,cACA0qF,KAAO51E,YAEXqB,UAAU,CACRxW,KAFasqF,cAAc5xE,KAAKoD,SAASuuE,WAGzC3zE,YAAY,EACZE,SAAUm0E,OAEZ1qF,IAAI,cACA2qF,eAAiB71E,YACrB9U,IAAI,MACJA,IAAI,yBACJA,IAAI,cAAgByB,UAAU4W,KAAKiD,WACnCtb,IAAI,cAAgByqF,UAAY,QAChCzqF,IAAI,aAAesE,MAAMkB,IAAIolF,UAAU1gC,QAAQ7xC,KAAKoD,SAASovE,OAC7D7qF,IAAI,UAAYqY,KAAKoD,SAASgB,OAC9Bzc,IAAI,UAAYqY,KAAKoD,SAASqvE,OAC9B9qF,IAAI,gBAAkBqY,KAAKoD,SAASsvE,aACpC/qF,IAAI,WAAaqY,KAAKoD,SAASuvE,UAC/BhrF,IAAI,YAAcqY,KAAKoD,SAASwvE,UAChCjrF,IAAI,cAAgBqY,KAAKoD,SAASyvE,WAClClrF,IAAI,MACJA,IAAI,cACAmrF,eAAiBr2E,YACrB9U,IAAI,MACJA,IAAI,eACJA,IAAI,cAAgByB,UAAU4W,KAAKiD,WACnCtb,IAAI,mBAAqB2qF,eAAiB,QAC1C3qF,IAAI,MAAQsE,MAAMkB,IAAIolF,UAAU1gC,QAAQq4B,SACxCviF,IAAI,0BACJA,IAAI,YACJA,IAAI,0BACJA,IAAI,kBACJA,IAAI,MACJA,IAAI,iBACJA,IAAI,qBACJA,IAAI,cAAgBqY,KAAKG,SAAW,KACpCxY,IAAI,MACJA,IAAI,MACJA,IAAI,UACJqY,KAAK5U,aAAeqR,YACpB9U,IAAI,MACJA,IAAI,eACJA,IAAI,mBACJA,IAAI,cAAgB0qF,KAAO,QAC3B1qF,IAAI,cAAgByB,UAAU4W,KAAKiD,WACnCtb,IAAI,cAAgBqY,KAAKG,UACzBxY,IAAI,qBAAuBmrF,eAAiB,SAC5CnrF,IAAI,MACJA,IAAI,UACJqY,KAAKC,iBAAkB,GAKzB8yE,CAAkBxoF,SA4DpBgsB,SAASxd,OAAOnO,KAAK,CAAC,UAAW,SAAUL,OAzDb,SAAiC2B,aACzD8T,KAAO9T,QAAQ8T,KACfrY,IAAMuE,QAAQvE,IACd8U,UAAYvQ,QAAQuQ,UACpBqB,UAAY5R,QAAQ4R,aAEpBkC,KAAKoD,oBAAoBnX,MAAMkB,IAAI2gF,SAA6B,oBAAlB9tE,KAAKG,SAAgC,SAGjF8xE,UADOjyE,KAAKoD,SAASqnB,QAErB0nD,WAAa,GAER7tF,EAAI,EAAGA,EAAI2tF,UAAU1tF,OAAQD,IACpC6tF,YAAc54F,OAAOC,aAAay4F,UAAU3tF,QAG1C8tF,UAAY31E,YAChBqB,UAAU,CACRxW,KAAM6qF,WACNn0E,YAAY,EACZE,SAAUk0E,YAEZzqF,IAAI,cACA0qF,KAAO51E,YAEXqB,UAAU,CACRxW,KAFasqF,cAAc5xE,KAAKoD,SAASuuE,WAGzC3zE,YAAY,EACZE,SAAUm0E,OAEZ1qF,IAAI,cACA2qF,eAAiB71E,YACrB9U,IAAI,MACJA,IAAI,YAAcqY,KAAKoD,SAASwvE,UAChCjrF,IAAI,cAAgBqY,KAAKoD,SAASyvE,WAClClrF,IAAI,UAAYqY,KAAKoD,SAASqvE,OAC9B9qF,IAAI,yBACJA,IAAI,cAAgByqF,UAAY,QAChCzqF,IAAI,aACJA,IAAI,aAAesE,MAAMkB,IAAIolF,UAAU1gC,QAAQ7xC,KAAKoD,SAASovE,OAC7D7qF,IAAI,cAAgByB,UAAU4W,KAAKiD,WACnCtb,IAAI,gBAAkBqY,KAAKoD,SAASsvE,aACpC/qF,IAAI,WAAaqY,KAAKoD,SAASuvE,UAC/BhrF,IAAI,MACJA,IAAI,UACJqY,KAAK5U,aAAeqR,gBAEf,IAAI9V,EAAI,EAAGA,EAAIqZ,KAAKoD,SAAS4vE,KAAK9I,OAAO3lF,OAAQoC,IACpDqZ,KAAKoD,SAAS4vE,KAAK9I,OAAOvjF,GAAKtC,SAAS2b,KAAKoD,SAAS4vE,KAAK9I,OAAOvjF,IAAM,IAAOqZ,KAAKoD,SAASqoC,KAAKwnC,aAGpGtrF,IAAI,2CAA6C0qF,KAAO,iBAAmBjpF,UAAU4W,KAAKiD,UAAY,mBAAqBqvE,eAAvH,iBAAgKtyE,KAAKG,SAAW,wCAA0ClU,MAAMkB,IAAIolF,UAAU1gC,QAAQ7xC,KAAKoD,SAAS4vE,KAAK9I,QAAU,MACvRviF,IAAI,UACJqY,KAAKC,iBAAkB,GAKzBizE,CAAwB3oF,aAGtB4oF,iBAAmB,SAA0B5oF,UAY3C6oF,YAXAjvE,KAAO5Z,KAAK4Z,MAAQ,GACpBjf,EAAIqF,KAAKrF,EACT+M,EAAI1H,KAAK0H,EACT/F,QAAU3B,KAAK2B,SAAW,GAC1Bof,MAAQ/gB,KAAK+gB,OAAS,GACtBvG,UAAYuG,MAAMvG,UAClB9M,cAAgBqT,MAAMrT,cACtBI,MAAQiT,MAAMjT,MACdhR,IAAM4Q,cACN3hB,IAAM,GACNuP,EAAI,EAEJwtF,QAAU,GACVlzE,SAAW9H,MAAMhR,KAAK8Y,YAEE,eAAxB9H,MAAMhR,KAAK8Y,eACN,CACLgE,KAAMA,KACNjf,EAAGA,EACH+M,EAAGA,EACH/F,QAASA,QACTof,MAAOA,WAIX+nE,QAAUlvE,KACV9c,IAAM4Q,cAEFvQ,MAAMgX,QAAQyF,QAChBkvE,QAAUlvE,KAAK,IAGZte,EAAI,EAAGA,EAAIwtF,QAAQ9uF,OAAQsB,GAAK,EAC/BwS,MAAMhR,KAAK+b,SAASrZ,eAAe,UACrCqpF,YAAc/6E,MAAMhR,KAAK+b,SAASivE,KAAKN,QAAQuB,QAAQD,QAAQxtF,GAAGQ,WAAW,KAe1E+sF,aACCC,QAAQxtF,GAAGQ,WAAW,GAAK,KAAOgS,MAAMhR,KAAK+b,SAASrZ,eAAe,WAMzEzT,KAAO+8F,QAAQxtF,GAHbvP,KAAO,OAOTiE,OAAS,UAET8J,SAASgD,IAAIkC,MAAM,IAAM,IAAmB,oBAAb4W,SAEjC5lB,OAASwqB,UAAUzuB,IAAK+Q,KAAKZ,MAAM,IAAIK,KAAI,SAAUgsC,WAC5CA,GAAGzsC,WAAW,GAAGrB,SAAS,OAChC+B,KAAK,IACc,eAAboZ,WACT5lB,OAASs0F,YAAYv4F,IAAK+hB,MAAMhR,OAGlCikB,MAAMtB,OAAQ,EACP,CACL7F,KAAM5pB,OACN2K,EAAGA,EACH+M,EAAGA,EACH/F,QAASA,QACTof,MAAOA,QAgDXiL,SAASxd,OAAOnO,KAAK,CAAC,kBA5CG,SAA4B2oF,WAC/CpvE,KAAOovE,MAAMpvE,MAAQ,GAKrBiqB,QAAU,GACV7jC,KAAO,CACT4Z,KAAMA,KACNjf,EAPMquF,MAAMruF,EAQZ+M,EAPMshF,MAAMthF,EAQZ/F,QAPYqnF,MAAMrnF,QAQlBof,MAPUioE,MAAMjoE,UAUd5jB,MAAMgX,QAAQyF,MAAO,KACnB7f,EAAI,MAEHA,EAAI,EAAGA,EAAI6f,KAAK5f,OAAQD,GAAK,EAC5BoD,MAAMgX,QAAQyF,KAAK7f,KACE,IAAnB6f,KAAK7f,GAAGC,OACV6pC,QAAQxjC,KAAK,CAACuoF,iBAAiB/oF,OAAOqiB,OAAO,GAAIliB,KAAM,CACrD4Z,KAAMA,KAAK7f,GAAG,MACZ6f,KAAMA,KAAK7f,GAAG,GAAI6f,KAAK7f,GAAG,KAOhC8pC,QAAQxjC,KAAKuoF,iBAAiB/oF,OAAOqiB,OAAO,GAAIliB,KAAM,CACpD4Z,KAAMA,KAAK7f,MACT6f,MAIRovE,MAAMpvE,KAAOiqB,aAEbmlD,MAAMpvE,KAAOgvE,iBAAiB/oF,OAAOqiB,OAAO,GAAIliB,KAAM,CACpD4Z,KAAMA,QACJA,SAKPlY;;;;;;;;SAgBQsqB,cAELi9D,eAAiB,uBACc,IAAtBj+F,KAAK6X,SAASqmF,WAClBrmF,SAASqmF,IAAM,KAGf,GAcTl9D,SAASq3D,gBAAkB,SAAU5mE,iBACnCwsE,eAAej9F,KAAKhB,WAE0B,IAAhCA,KAAK6X,SAASqmF,IAAIzsE,WAelCuP,SAASm9D,aAAe,SAAU1sE,SAAU2sE,oBAC1CH,eAAej9F,KAAKhB,WAEf6X,SAASqmF,IAAIzsE,UAAY2sE,YACvBp+F,MAcTghC,SAASs3D,eAAiB,SAAU7mE,iBAClCwsE,eAAej9F,KAAKhB,WAEuB,IAAhCA,KAAK6X,SAASqmF,IAAIzsE,UACpBzxB,KAAK6X,SAASqmF,IAAIzsE,UAGpB,OAER/a,MAAMkB;;;;;;SAQElB,OAkDTA,MAAM2nF,eAAiB3nF,MAAMpW,UAAU+9F,eAAiB,SAAU1nF,aA4B5D2nF,UACAC,UAGAC,YACAC,SACAC,aACAC,UACAC,qBAnCAC,eAAiBC,kBACjBC,iBAAmB,CAAC,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GAAI,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GAAI,CAAC,EAAG,EAAG,EAAG,GAAM,EAAG,EAAG,GAAI,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GAAI,CAAC,EAAG,EAAG,GAAM,GAAM,EAAG,EAAG,GAAI,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,IACnKC,iBAAmB,CAAC,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GAAI,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GAAI,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,EAAG,GAAI,CAAC,EAAG,EAAG,EAAG,GAAM,EAAG,EAAG,IAC/GC,gBAAkB,CACpB5qB,EAAG,EACHqL,EAAG,EACHwf,GAAI,EACJC,GAAI,EACJrzD,EAAG,EACHuxC,EAAG,EACHzD,EAAG,GAEDwlB,oBAAsB,GACrB,IACA,IACA,IACA,KACG,MACA,MACA,MACA,GAEJC,YAAc,CAAC,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAQ,IAAQ,IAAQ,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,IAAU,KAErYC,qBAAuB,IAAItlC,OAAO,qGAElCulC,aAAc,EAUdC,KAPU,OASTnB,eAAiB,OAoBlBoB,aAAe,SAAsBtwE,QACnCpb,SAAWob,GAAGre,aACdyrF,MAAQxoF,UAAY,EACpB2rF,SAAWN,oBAAoB7C,mBAElBn7E,IAAbs+E,SACKb,eAA0B,IAAXa,UAA6B,IAAX3rF,WACrB,MAAVwoF,OAA4B,MAAVA,MACpB,KACE+C,qBAAqBz7F,KAAK04F,OAE5B,IACY,IAAVA,MAEF,IAGF,KAGLoD,oBAAsB,SAA6B/wE,UAChD,IAAWgxE,SAAP7wF,EAAI,EAAaA,EAAI6f,KAAK5f,OAAQD,IAAK,IAG7B,OAFjB6wF,SAAWH,aAAa7wE,KAAKrpB,OAAOwJ,YAG3B,EACF,GAAiB,MAAb6wF,gBACF,SAIJ,GAKLC,iBAAmB,SAA0BC,MAAOC,MAAOC,cAAer0E,WAExEs0E,MACAC,MACAnxF,EACAmR,IAJAigF,MAAQJ,MAAMp0E,cAMVw0E,WACD,QACA,QAwGA,UACA,UACA,UACA,UACA,MACHZ,aAAc,YAzGX,QACA,eAGA,KACCA,cACFY,MAAQ,gBAKP,KACHZ,aAAc,EACdY,MAAQ,cAGL,SA4FA,KACHA,MAAQ,cAzFL,KACCx0E,MAAQ,GAAKA,MAAQ,GAAKo0E,MAAM/wF,QAAiD,QAAtCixF,MAAQD,cAAcr0E,MAAQ,KAA0B,OAAVs0E,OAAiD,QAA9BC,MAAQH,MAAMp0E,MAAQ,KAA0B,OAAVu0E,MACpJC,MAAQ,IACCZ,cACTW,MAAQ,MAGVC,MAAQD,QAAUD,MAAQC,MAAQ,cAG/B,KAEHC,MAAkB,QADlBF,MAAQt0E,MAAQ,EAAIq0E,cAAcr0E,MAAQ,GAAK,MACrBA,MAAQ,EAAIo0E,MAAM/wF,QAA+B,OAArB+wF,MAAMp0E,MAAQ,GAAc,KAAO,cAGtF,QACCA,MAAQ,GAAkC,OAA7Bq0E,cAAcr0E,MAAQ,GAAa,CAClDw0E,MAAQ,WAEH,GAAIZ,YAAa,CACtBY,MAAQ,cAIVpxF,EAAI4c,MAAQ,EACZzL,IAAM6/E,MAAM/wF,OAELD,EAAImR,KAAoB,OAAb6/E,MAAMhxF,IACtBA,IAIAoxF,MADEpxF,EAAImR,KAAoB,OAAb6/E,MAAMhxF,GACX,KAEA,cAKP,SACCyvF,cAAgBC,SAAU,KAE5Bv+E,IAAM6/E,MAAM/wF,OACZD,EAAI4c,MAAQ,EAEL5c,EAAImR,KAAoB,QAAb6/E,MAAMhxF,IACtBA,OAGEA,EAAImR,IAAK,KACPrQ,EAAIiwF,MAAMn0E,OACVy0E,aAAevwF,GAAK,MAAUA,GAAK,MAAgB,QAANA,KACjDowF,MAAQF,MAAMhxF,GAEVqxF,eAA2B,MAAVH,OAA2B,OAAVA,OAAiB,CACrDE,MAAQ,YAOZA,MADEx0E,MAAQ,GAAoC,OAA9Bs0E,MAAQF,MAAMp0E,MAAQ,IAC9B,IAEAq0E,cAAcr0E,MAAQ,aAK7B,IACH4zE,aAAc,EACdjB,WAAY,EACZ6B,MAAQX,eAGL,IACHjB,WAAY,EACZ4B,MAAQ,WAgBLA,OAmBLE,cAAgB,SAAuBzxE,KAAM0xE,kBAAmBC,YAC9D/lC,UAAY5rC,KAAK1d,MAAM,WAEvBqvF,QACFC,eAAehmC,UAAW+lC,OAAQ,CAChCE,QAASjB,OAIbhlC,UAAU1iC,UACVwoE,mBAAqBA,kBAAkBxoE,UAChC0iC,UAAUhpD,KAAK,KAKpBgvF,eAAiB,SAAwBV,MAAOS,OAAQG,YACtDC,OAEA5xF,EACA4c,MACAi1E,SACAC,UACAC,SAAW,EACX5gF,IAAM4/E,MAAM9wF,OACZ+xF,SAAW,EACXf,cAAgB,GAChBgB,WAAaxB,KAAOR,iBAAmBD,iBACvCgB,MAAQ,OACZR,aAAc,EACdjB,WAAY,EACZC,WAAY,EAEPxvF,EAAI,EAAGA,EAAImR,IAAKnR,IACnBgxF,MAAMhxF,GAAK0wF,aAAaK,MAAM/wF,QAG3B4c,MAAQ,EAAGA,MAAQzL,IAAKyL,QAAS,IACpCk1E,UAAYE,SACZf,cAAcr0E,OAASk0E,iBAAiBC,MAAOC,MAAOC,cAAer0E,OAErEg1E,OAAoB,KADpBI,SAAWC,WAAWH,WAAW5B,gBAAgBe,cAAcr0E,UAE/Do1E,UAAY,GACZR,OAAO50E,OAASi1E,SAAWI,WAAWD,UAAU,GAE5CJ,OAAS,KACI,KAAXA,OAAiB,KACd5xF,EAAI+xF,QAAS/xF,EAAI4c,MAAO5c,IAC3BwxF,OAAOxxF,GAAK,EAGd+xF,SAAW,OAEXA,SAAW,KAIHE,WAAWD,UAAU,IAGd,IAAbD,UACFA,QAAUn1E,eAGRm1E,SAAW,EAAG,KACX/xF,EAAI+xF,QAAS/xF,EAAI4c,MAAO5c,IAC3BwxF,OAAOxxF,GAAK6xF,SAGdE,SAAW,EAIM,MAAjBf,MAAMp0E,SACR40E,OAAO50E,OAAS,GAGlB+0E,OAAOD,SAAWG,SAGhBrC,WAhGa,SAAsBwB,MAAOQ,OAAQvxF,YACjD,IAAID,EAAI,EAAGA,EAAIC,OAAQD,OACT,MAAbgxF,MAAMhxF,GAAY,CACpBwxF,OAAOxxF,GAAKywF,SAEP,IAAIpuF,EAAIrC,EAAI,EAAGqC,GAAK,GACN,OAAb2uF,MAAM3uF,GADgBA,IAExBmvF,OAAOnvF,GAAKouF,MA0FlByB,CAAalB,MAAOQ,OAAQrgF,MAM5BghF,eAAiB,SAAwB1pC,MAAOgD,UAAW8lC,kBAAmBC,OAAQG,aACpFA,OAAOD,QAAUjpC,WAIP,IAAVA,OA7SQ,IA6SOgoC,OAAqBlB,iBACtC9jC,UAAU1iC,eACVwoE,mBAAqBA,kBAAkBxoE,mBAIrC3I,GACAgyE,KACA3nC,IACA4nC,IACAlhF,IAAMs6C,UAAUxrD,OAChBq7C,MAAQ,EAELA,MAAQnqC,KAAK,IACdqgF,OAAOl2C,QAAUmN,MAAO,KAC1BgC,IAAMnP,MAAQ,EAEPmP,IAAMt5C,KAAOqgF,OAAO/mC,MAAQhC,OACjCgC,UAGG4nC,IAAM/2C,MAAO82C,KAAO3nC,IAAM,EAAG4nC,IAAMD,KAAMC,MAAOD,OACnDhyE,GAAKqrC,UAAU4mC,KACf5mC,UAAU4mC,KAAO5mC,UAAU2mC,MAC3B3mC,UAAU2mC,MAAQhyE,GAEdmxE,oBACFnxE,GAAKmxE,kBAAkBc,KACvBd,kBAAkBc,KAAOd,kBAAkBa,MAC3Cb,kBAAkBa,MAAQhyE,IAI9Bk7B,MAAQmP,IAGVnP,WAoBAg3C,SAAW,SAAkBzyE,KAAM0xE,kBAAmBC,YACpD/lC,UAAY5rC,KAAK1d,MAAM,IACvBwvF,OAAS,CACXD,QAASjB,aAGNe,SACHA,OAAS,IAGXC,eAAehmC,UAAW+lC,OAAQG,QAxBf,SAAwBlmC,UAAW+lC,OAAQG,WACvC,IAAnBA,OAAOD,SAAiB7B,yBACrB,IAAWjzE,MAAP5c,EAAI,EAAUA,EAAIyrD,UAAUxrD,OAAQD,IACzB,IAAdwxF,OAAOxxF,KACT4c,MAAQ0zE,YAAY1pF,QAAQ6kD,UAAUzrD,MAEzB,IACXyrD,UAAUzrD,GAAKswF,YAAY1zE,MAAQ,IAmB3C21E,CAAe9mC,UAAW+lC,OAAQG,QAElCQ,eAAeK,EAAa/mC,UAAW8lC,kBAAmBC,OAAQG,QAElEQ,eArXY,EAqXY1mC,UAAW8lC,kBAAmBC,OAAQG,QAEvDlmC,UAAUhpD,KAAK,iBAYnB6sF,eAAemD,cAAgB,SAAU5yE,KAAM0xE,kBAAmBC,WAzX3D,SAAe3xE,KAAM0xE,sBAC3BA,sBACG,IAAIvxF,EAAI,EAAGA,EAAI6f,KAAK5f,OAAQD,IAC/BuxF,kBAAkBvxF,GAAKA,OAIVqS,IAAbq9E,WACFA,SAAWkB,oBAAoB/wE,YAGfxN,IAAdu9E,YACFA,UAAYgB,oBAAoB/wE,OA8WlC6yE,CAAM7yE,KAAM0xE,mBAEP9B,cAAeE,cAAiBC,UAI9B,GAAIH,aAAeE,cAAgBD,SAAWE,UAEnDa,KAAOf,SA5YG,EADA,EA8YV7vE,KAAOyxE,cAAczxE,KAAM0xE,kBAAmBC,aACzC,IAAK/B,aAAeE,cAAgBC,UAEzCa,KAAOf,SAhZG,EADA,EAkZV7vE,KAAOyyE,SAASzyE,KAAM0xE,kBAAmBC,QACzC3xE,KAAOyxE,cAAczxE,KAAM0xE,wBACtB,IAAI9B,aAAgBC,UAAaC,cAAiBC,WAIlD,GAAIH,cAAgBE,cAAgBD,SAAWE,UAEpD/vE,KAAOyxE,cAAczxE,KAAM0xE,mBAEvB7B,UAEFe,KA9ZQ,EA+ZR5wE,KAAOyyE,SAASzyE,KAAM0xE,kBAAmBC,UAGzCf,KAjaQ,EAkaR5wE,KAAOyyE,SAASzyE,KAAM0xE,kBAAmBC,QACzC3xE,KAAOyxE,cAAczxE,KAAM0xE,yBAExB,GAAI9B,aAAeC,WAAaC,cAAgBC,UAErDa,KAvaU,EAwaV5wE,KAAOyyE,SAASzyE,KAAM0xE,kBAAmBC,QACzC3xE,KAAOyxE,cAAczxE,KAAM0xE,wBACtB,IAAK9B,cAAgBE,cAAgBD,SAAWE,UAAW,KAE5D+C,wBAA0B9C,qBAE1BH,UAEFe,KAhbQ,EAibR5wE,KAAOyyE,SAASzyE,KAAM0xE,kBAAmBC,QACzCf,KAnbQ,EAobRZ,sBAAuB,EACvBhwE,KAAOyyE,SAASzyE,KAAM0xE,kBAAmBC,QACzC3B,qBAAuB8C,0BAGvBlC,KAzbQ,EA0bR5wE,KAAOyyE,SAASzyE,KAAM0xE,kBAAmBC,QACzC3xE,KAAOyxE,cAAczxE,KAAM0xE,mBAC3Bd,KA3bQ,EA4bRZ,sBAAuB,EACvBhwE,KAAOyyE,SAASzyE,KAAM0xE,kBAAmBC,QACzC3B,qBAAuB8C,wBACvB9yE,KAAOyxE,cAAczxE,KAAM0xE,0BA1C7Bd,KAtZU,EAuZV5wE,KAAOyyE,SAASzyE,KAAM0xE,kBAAmBC,aAdzCf,KAAOf,SAxYG,EADA,EA0YV7vE,KAAOyyE,SAASzyE,KAAM0xE,kBAAmBC,eA0DpC3xE,WAeJyvE,eAAe50D,WAAa,SAAU9yB,SACrCA,UACF6nF,YAAc7nF,QAAQgrF,cACtBjD,aAAe/nF,QAAQirF,eACvBnD,SAAW9nF,QAAQkrF,WACnBlD,UAAYhoF,QAAQmrF,YACpBlD,qBAAuBjoF,QAAQorF,2BAI9B1D,eAAe50D,WAAW9yB,SAExB3W,KAAKq+F,oBAGVS,kBA5hBmB,CAAC,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,KAAM,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,KAAM,IAAK,IAAK,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,IAAK,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,IAAK,MAAO,IAAK,MAAO,MAAO,IAAK,MAAO,MAAO,IAAK,MAAO,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,KAAM,KAAM,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,MAAO,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,KAAM,IAAK,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,KAAM,KAAM,MAAO,MAAO,IAAK,MAAO,MAAO,MAAO,MAAO,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,KAAM,KAAM,MAAO,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,IAAK,MAAO,MAAO,MAAO,MAAO,MAAO,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,MAAO,MAAO,MAAO,MAAO,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,IAAK,KAAM,IAAK,IAAK,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,IAAK,IAAK,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,KAAM,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK,IAAK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"}
\ No newline at end of file
diff --git a/amd/src/jspdf.js b/amd/src/jspdf.js
index 66810c9370e458ad112de2a339a6bb968f3f33ef..dbe1c10072620002171fd6aa0377a1c06cbf4d05 100644
--- a/amd/src/jspdf.js
+++ b/amd/src/jspdf.js
@@ -1,22721 +1,28833 @@
-define(function() {
- 
- 
-  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
-    return typeof obj;
-  } : function (obj) {
-    return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
-  };
+/** @license
+ *
+ * jsPDF - PDF Document creation from JavaScript
+ * Version 2.5.1 Built on 2022-01-28T15:37:57.789Z
+ *                      CommitID 00000000
+ *
+ * Copyright (c) 2010-2021 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF
+ *               2015-2021 yWorks GmbH, http://www.yworks.com
+ *               2015-2021 Lukas Holländer <lukas.hollaender@yworks.com>, https://github.com/HackbrettXXX
+ *               2016-2018 Aras Abbasi <aras.abbasi@gmail.com>
+ *               2010 Aaron Spike, https://github.com/acspike
+ *               2012 Willow Systems Corporation, https://github.com/willowsystems
+ *               2012 Pablo Hess, https://github.com/pablohess
+ *               2012 Florian Jenett, https://github.com/fjenett
+ *               2013 Warren Weckesser, https://github.com/warrenweckesser
+ *               2013 Youssef Beddad, https://github.com/lifof
+ *               2013 Lee Driscoll, https://github.com/lsdriscoll
+ *               2013 Stefan Slonevskiy, https://github.com/stefslon
+ *               2013 Jeremy Morel, https://github.com/jmorel
+ *               2013 Christoph Hartmann, https://github.com/chris-rock
+ *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
+ *               2014 James Makes, https://github.com/dollaruw
+ *               2014 Diego Casorran, https://github.com/diegocr
+ *               2014 Steven Spungin, https://github.com/Flamenco
+ *               2014 Kenneth Glassey, https://github.com/Gavvers
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Contributor(s):
+ *    siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango,
+ *    kim3er, mfo, alnorth, Flamenco
+ */
+
+ (function (global, factory) {
+  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+  typeof define === 'function' && define.amd ? define(['exports'], factory) :
+  (global = global || self, factory(global.jspdf = {}));
+}(this, (function (exports) { 'use strict';
+
+  function _typeof(obj) {
+    "@babel/helpers - typeof";
+
+    if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
+      _typeof = function (obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function (obj) {
+        return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+      };
+    }
 
+    return _typeof(obj);
+  }
 
-  /** @preserve
-   * jsPDF - PDF Document creation from JavaScript
-   * Version 1.4.1 Built on 2018-06-06T07:49:28.721Z
-   *                           CommitID 3233f44044
-   *
-   * Copyright (c) 2010-2016 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF
-   *               2010 Aaron Spike, https://github.com/acspike
-   *               2012 Willow Systems Corporation, willow-systems.com
-   *               2012 Pablo Hess, https://github.com/pablohess
-   *               2012 Florian Jenett, https://github.com/fjenett
-   *               2013 Warren Weckesser, https://github.com/warrenweckesser
-   *               2013 Youssef Beddad, https://github.com/lifof
-   *               2013 Lee Driscoll, https://github.com/lsdriscoll
-   *               2013 Stefan Slonevskiy, https://github.com/stefslon
-   *               2013 Jeremy Morel, https://github.com/jmorel
-   *               2013 Christoph Hartmann, https://github.com/chris-rock
-   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
-   *               2014 James Makes, https://github.com/dollaruw
-   *               2014 Diego Casorran, https://github.com/diegocr
-   *               2014 Steven Spungin, https://github.com/Flamenco
-   *               2014 Kenneth Glassey, https://github.com/Gavvers
-   *
-   * Licensed under the MIT License
-   *
-   * Contributor(s):
-   *    siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango,
-   *    kim3er, mfo, alnorth, Flamenco
-   */
+  var globalObject = function () {
+    return "undefined" !== typeof window ? window : "undefined" !== typeof global ? global : "undefined" !== typeof self ? self : this;
+  }();
 
-  /**
-   * Creates new jsPDF document object instance.
-   * @name jsPDF
-   * @class
-   * @param orientation {String/Object} Orientation of the first page. Possible values are "portrait" or "landscape" (or shortcuts "p" (Default), "l") <br />
-   * Can also be an options object.
-   * @param unit {String}  Measurement unit to be used when coordinates are specified.<br />
-   * Possible values are "pt" (points), "mm" (Default), "cm", "in" or "px".
-   * @param format {String/Array} The format of the first page. Can be <ul><li>a0 - a10</li><li>b0 - b10</li><li>c0 - c10</li><li>c0 - c10</li><li>dl</li><li>letter</li><li>government-letter</li><li>legal</li><li>junior-legal</li><li>ledger</li><li>tabloid</li><li>credit-card</li></ul><br />
-   * Default is "a4". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array , e.g. [595.28, 841.89]
-   * @returns {jsPDF}
-   * @description
-   * If the first parameter (orientation) is an object, it will be interpreted as an object of named parameters
-   * ```
-   * {
-   *  orientation: 'p',
-   *  unit: 'mm',
-   *  format: 'a4',
-   *  hotfixes: [] // an array of hotfix strings to enable
-   * }
-   * ```
-   */
-  var jsPDF = function (global) {
-
-    var pdfVersion = '1.3',
-        pageFormats = { // Size in pt of various paper formats
-      'a0': [2383.94, 3370.39],
-      'a1': [1683.78, 2383.94],
-      'a2': [1190.55, 1683.78],
-      'a3': [841.89, 1190.55],
-      'a4': [595.28, 841.89],
-      'a5': [419.53, 595.28],
-      'a6': [297.64, 419.53],
-      'a7': [209.76, 297.64],
-      'a8': [147.40, 209.76],
-      'a9': [104.88, 147.40],
-      'a10': [73.70, 104.88],
-      'b0': [2834.65, 4008.19],
-      'b1': [2004.09, 2834.65],
-      'b2': [1417.32, 2004.09],
-      'b3': [1000.63, 1417.32],
-      'b4': [708.66, 1000.63],
-      'b5': [498.90, 708.66],
-      'b6': [354.33, 498.90],
-      'b7': [249.45, 354.33],
-      'b8': [175.75, 249.45],
-      'b9': [124.72, 175.75],
-      'b10': [87.87, 124.72],
-      'c0': [2599.37, 3676.54],
-      'c1': [1836.85, 2599.37],
-      'c2': [1298.27, 1836.85],
-      'c3': [918.43, 1298.27],
-      'c4': [649.13, 918.43],
-      'c5': [459.21, 649.13],
-      'c6': [323.15, 459.21],
-      'c7': [229.61, 323.15],
-      'c8': [161.57, 229.61],
-      'c9': [113.39, 161.57],
-      'c10': [79.37, 113.39],
-      'dl': [311.81, 623.62],
-      'letter': [612, 792],
-      'government-letter': [576, 756],
-      'legal': [612, 1008],
-      'junior-legal': [576, 360],
-      'ledger': [1224, 792],
-      'tabloid': [792, 1224],
-      'credit-card': [153, 243]
-    };
-
-    /**
-     * jsPDF's Internal PubSub Implementation.
-     * See mrrio.github.io/jsPDF/doc/symbols/PubSub.html
-     * Backward compatible rewritten on 2014 by
-     * Diego Casorran, https://github.com/diegocr
-     *
-     * @class
-     * @name PubSub
-     * @ignore This should not be in the public docs.
-     */
-    function PubSub(context) {
-      var topics = {};
+  function consoleLog() {
+    if (globalObject.console && typeof globalObject.console.log === "function") {
+      globalObject.console.log.apply(globalObject.console, arguments);
+    }
+  }
 
-      this.subscribe = function (topic, callback, once) {
-        if (typeof callback !== 'function') {
-          return false;
-        }
+  function consoleWarn(str) {
+    if (globalObject.console) {
+      if (typeof globalObject.console.warn === "function") {
+        globalObject.console.warn.apply(globalObject.console, arguments);
+      } else {
+        consoleLog.call(null, arguments);
+      }
+    }
+  }
 
-        if (!topics.hasOwnProperty(topic)) {
-          topics[topic] = {};
-        }
+  function consoleError(str) {
+    if (globalObject.console) {
+      if (typeof globalObject.console.error === "function") {
+        globalObject.console.error.apply(globalObject.console, arguments);
+      } else {
+        consoleLog(str);
+      }
+    }
+  }
 
-        var id = Math.random().toString(35);
-        topics[topic][id] = [callback, !!once];
+  var console = {
+    log: consoleLog,
+    warn: consoleWarn,
+    error: consoleError
+  };
 
-        return id;
+  function bom(blob, opts) {
+    if (typeof opts === "undefined") opts = {
+      autoBom: false
+    };else if (_typeof(opts) !== "object") {
+      console.warn("Deprecated: Expected third argument to be a object");
+      opts = {
+        autoBom: !opts
       };
+    } // prepend BOM for UTF-8 XML and text/* types (including HTML)
+    // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
 
-      this.unsubscribe = function (token) {
-        for (var topic in topics) {
-          if (topics[topic][token]) {
-            delete topics[topic][token];
-            return true;
-          }
-        }
-        return false;
-      };
+    if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
+      return new Blob([String.fromCharCode(0xfeff), blob], {
+        type: blob.type
+      });
+    }
 
-      this.publish = function (topic) {
-        if (topics.hasOwnProperty(topic)) {
-          var args = Array.prototype.slice.call(arguments, 1),
-              idr = [];
+    return blob;
+  }
 
-          for (var id in topics[topic]) {
-            var sub = topics[topic][id];
-            try {
-              sub[0].apply(context, args);
-            } catch (ex) {
-              if (global.console) {
-                console.error('jsPDF PubSub Error', ex.message, ex);
-              }
-            }
-            if (sub[1]) idr.push(id);
-          }
-          if (idr.length) idr.forEach(this.unsubscribe);
-        }
-      };
-    }
+  function download(url, name, opts) {
+    var xhr = new XMLHttpRequest();
+    xhr.open("GET", url);
+    xhr.responseType = "blob";
 
-    /**
-     * @constructor
-     * @private
-     */
-    function jsPDF(orientation, unit, format, compressPdf) {
-      var options = {};
+    xhr.onload = function () {
+      saveAs(xhr.response, name, opts);
+    };
 
-      if ((typeof orientation === 'undefined' ? 'undefined' : _typeof(orientation)) === 'object') {
-        options = orientation;
+    xhr.onerror = function () {
+      console.error("could not download file");
+    };
 
-        orientation = options.orientation;
-        unit = options.unit || unit;
-        format = options.format || format;
-        compressPdf = options.compress || options.compressPdf || compressPdf;
-      }
-
-      // Default options
-      unit = unit || 'mm';
-      format = format || 'a4';
-      orientation = ('' + (orientation || 'P')).toLowerCase();
-
-      var format_as_string = ('' + format).toLowerCase(),
-          compress = !!compressPdf && typeof Uint8Array === 'function',
-          textColor = options.textColor || '0 g',
-          drawColor = options.drawColor || '0 G',
-          activeFontSize = options.fontSize || 16,
-          activeCharSpace = options.charSpace || 0,
-          R2L = options.R2L || false,
-          lineHeightProportion = options.lineHeight || 1.15,
-          lineWidth = options.lineWidth || 0.200025,
-          // 2mm
-      fileId = '00000000000000000000000000000000',
-          objectNumber = 2,
-          // 'n' Current object number
-      outToPages = !1,
-          // switches where out() prints. outToPages true = push to pages obj. outToPages false = doc builder content
-      offsets = [],
-          // List of offsets. Activated and reset by buildDocument(). Pupulated by various calls buildDocument makes.
-      fonts = {},
-          // collection of font objects, where key is fontKey - a dynamically created label for a given font.
-      fontmap = {},
-          // mapping structure fontName > fontStyle > font key - performance layer. See addFont()
-      activeFontKey,
-          // will be string representing the KEY of the font as combination of fontName + fontStyle
-      k,
-          // Scale factor
-      tmp,
-          page = 0,
-          currentPage,
-          pages = [],
-          pagesContext = [],
-          // same index as pages and pagedim
-      pagedim = [],
-          content = [],
-          additionalObjects = [],
-          lineCapID = 0,
-          lineJoinID = 0,
-          content_length = 0,
-          pageWidth,
-          pageHeight,
-          pageMode,
-          zoomMode,
-          layoutMode,
-          creationDate,
-          documentProperties = {
-        'title': '',
-        'subject': '',
-        'author': '',
-        'keywords': '',
-        'creator': ''
-      },
-          API = {},
-          events = new PubSub(API),
-          hotfixes = options.hotfixes || [],
-
-
-      /////////////////////
-      // Private functions
-      /////////////////////
-      generateColorString = function generateColorString(options) {
-        var color;
-
-        var ch1 = options.ch1;
-        var ch2 = options.ch2;
-        var ch3 = options.ch3;
-        var ch4 = options.ch4;
-        var precision = options.precision;
-        var letterArray = options.pdfColorType === "draw" ? ['G', 'RG', 'K'] : ['g', 'rg', 'k'];
-
-        if (typeof ch1 === "string" && ch1.charAt(0) !== '#') {
-          var rgbColor = new RGBColor(ch1);
-          if (rgbColor.ok) {
-            ch1 = rgbColor.toHex();
-          }
-        }
-        //convert short rgb to long form
-        if (typeof ch1 === "string" && /^#[0-9A-Fa-f]{3}$/.test(ch1)) {
-          ch1 = '#' + ch1[1] + ch1[1] + ch1[2] + ch1[2] + ch1[3] + ch1[3];
-        }
+    xhr.send();
+  }
 
-        if (typeof ch1 === "string" && /^#[0-9A-Fa-f]{6}$/.test(ch1)) {
-          var hex = parseInt(ch1.substr(1), 16);
-          ch1 = hex >> 16 & 255;
-          ch2 = hex >> 8 & 255;
-          ch3 = hex & 255;
-        }
+  function corsEnabled(url) {
+    var xhr = new XMLHttpRequest(); // use sync to avoid popup blocker
 
-        if (typeof ch2 === "undefined" || typeof ch4 === "undefined" && ch1 === ch2 && ch2 === ch3) {
-          // Gray color space.
-          if (typeof ch1 === "string") {
-            color = ch1 + " " + letterArray[0];
-          } else {
-            switch (options.precision) {
-              case 2:
-                color = f2(ch1 / 255) + " " + letterArray[0];
-                break;
-              case 3:
-              default:
-                color = f3(ch1 / 255) + " " + letterArray[0];
-            }
-          }
-        } else if (typeof ch4 === "undefined" || (typeof ch4 === 'undefined' ? 'undefined' : _typeof(ch4)) === "object") {
-          // assume RGB
-          if (typeof ch1 === "string") {
-            color = [ch1, ch2, ch3, letterArray[1]].join(" ");
-          } else {
-            switch (options.precision) {
-              case 2:
-                color = [f2(ch1 / 255), f2(ch2 / 255), f2(ch3 / 255), letterArray[1]].join(" ");
-                break;
-              default:
-              case 3:
-                color = [f3(ch1 / 255), f3(ch2 / 255), f3(ch3 / 255), letterArray[1]].join(" ");
-            }
-          }
-          // assume RGBA
-          if (ch4 && ch4.a === 0) {
-            //TODO Implement transparency.
-            //WORKAROUND use white for now
-            color = ['255', '255', '255', letterArray[1]].join(" ");
-          }
-        } else {
-          // assume CMYK
-          if (typeof ch1 === 'string') {
-            color = [ch1, ch2, ch3, ch4, letterArray[2]].join(" ");
-          } else {
-            switch (options.precision) {
-              case 2:
-                color = [f2(ch1), f2(ch2), f2(ch3), f2(ch4), letterArray[2]].join(" ");
-                break;
-              case 3:
-              default:
-                color = [f3(ch1), f3(ch2), f3(ch3), f3(ch4), letterArray[2]].join(" ");
-            }
-          }
-        }
-        return color;
-      },
-          convertDateToPDFDate = function convertDateToPDFDate(parmDate) {
-        var padd2 = function padd2(number) {
-          return ('0' + parseInt(number)).slice(-2);
-        };
-        var result = '';
-        var tzoffset = parmDate.getTimezoneOffset(),
-            tzsign = tzoffset < 0 ? '+' : '-',
-            tzhour = Math.floor(Math.abs(tzoffset / 60)),
-            tzmin = Math.abs(tzoffset % 60),
-            timeZoneString = [tzsign, padd2(tzhour), "'", padd2(tzmin), "'"].join('');
-
-        result = ['D:', parmDate.getFullYear(), padd2(parmDate.getMonth() + 1), padd2(parmDate.getDate()), padd2(parmDate.getHours()), padd2(parmDate.getMinutes()), padd2(parmDate.getSeconds()), timeZoneString].join('');
-        return result;
-      },
-          convertPDFDateToDate = function convertPDFDateToDate(parmPDFDate) {
-        var year = parseInt(parmPDFDate.substr(2, 4), 10);
-        var month = parseInt(parmPDFDate.substr(6, 2), 10) - 1;
-        var date = parseInt(parmPDFDate.substr(8, 2), 10);
-        var hour = parseInt(parmPDFDate.substr(10, 2), 10);
-        var minutes = parseInt(parmPDFDate.substr(12, 2), 10);
-        var seconds = parseInt(parmPDFDate.substr(14, 2), 10);
-        var timeZoneHour = parseInt(parmPDFDate.substr(16, 2), 10);
-        var timeZoneMinutes = parseInt(parmPDFDate.substr(20, 2), 10);
-
-        var resultingDate = new Date(year, month, date, hour, minutes, seconds, 0);
-        return resultingDate;
-      },
-          setCreationDate = function setCreationDate(date) {
-        var tmpCreationDateString;
-        var regexPDFCreationDate = /^D:(20[0-2][0-9]|203[0-7]|19[7-9][0-9])(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])(0[0-9]|1[0-9]|2[0-3])(0[0-9]|[1-5][0-9])(0[0-9]|[1-5][0-9])(\+0[0-9]|\+1[0-4]|\-0[0-9]|\-1[0-1])\'(0[0-9]|[1-5][0-9])\'?$/;
-        if ((typeof date === 'undefined' ? 'undefined' : _typeof(date)) === undefined) {
-          date = new Date();
-        }
+    xhr.open("HEAD", url, false);
 
-        if ((typeof date === 'undefined' ? 'undefined' : _typeof(date)) === "object" && Object.prototype.toString.call(date) === "[object Date]") {
-          tmpCreationDateString = convertDateToPDFDate(date);
-        } else if (regexPDFCreationDate.test(date)) {
-          tmpCreationDateString = date;
-        } else {
-          tmpCreationDateString = convertDateToPDFDate(new Date());
-        }
-        creationDate = tmpCreationDateString;
-        return creationDate;
-      },
-          getCreationDate = function getCreationDate(type) {
-        var result = creationDate;
-        if (type === "jsDate") {
-          result = convertPDFDateToDate(creationDate);
-        }
-        return result;
-      },
-          setFileId = function setFileId(value) {
-        value = value || "12345678901234567890123456789012".split('').map(function () {
-          return "ABCDEF0123456789".charAt(Math.floor(Math.random() * 16));
-        }).join('');
-        fileId = value;
-        return fileId;
-      },
-          getFileId = function getFileId() {
-        return fileId;
-      },
-          f2 = function f2(number) {
-        return number.toFixed(2); // Ie, %.2f
-      },
-          f3 = function f3(number) {
-        return number.toFixed(3); // Ie, %.3f
-      },
-          out = function out(string) {
-        string = typeof string === "string" ? string : string.toString();
-        if (outToPages) {
-          /* set by beginPage */
-          pages[currentPage].push(string);
-        } else {
-          // +1 for '\n' that will be used to join 'content'
-          content_length += string.length + 1;
-          content.push(string);
-        }
-      },
-          newObject = function newObject() {
-        // Begin a new object
-        objectNumber++;
-        offsets[objectNumber] = content_length;
-        out(objectNumber + ' 0 obj');
-        return objectNumber;
-      },
+    try {
+      xhr.send();
+    } catch (e) {}
 
-      // Does not output the object until after the pages have been output.
-      // Returns an object containing the objectId and content.
-      // All pages have been added so the object ID can be estimated to start right after.
-      // This does not modify the current objectNumber;  It must be updated after the newObjects are output.
-      newAdditionalObject = function newAdditionalObject() {
-        var objId = pages.length * 2 + 1;
-        objId += additionalObjects.length;
-        var obj = {
-          objId: objId,
-          content: ''
-        };
-        additionalObjects.push(obj);
-        return obj;
-      },
+    return xhr.status >= 200 && xhr.status <= 299;
+  } // `a.click()` doesn't work for all browsers (#465)
 
-      // Does not output the object.  The caller must call newObjectDeferredBegin(oid) before outputing any data
-      newObjectDeferred = function newObjectDeferred() {
-        objectNumber++;
-        offsets[objectNumber] = function () {
-          return content_length;
-        };
-        return objectNumber;
-      },
-          newObjectDeferredBegin = function newObjectDeferredBegin(oid) {
-        offsets[oid] = content_length;
-      },
-          putStream = function putStream(str) {
-        out('stream');
-        out(str);
-        out('endstream');
-      },
-          putPages = function putPages() {
-        var n,
-            p,
-            arr,
-            i,
-            deflater,
-            adler32,
-            adler32cs,
-            wPt,
-            hPt,
-            pageObjectNumbers = [];
-
-        adler32cs = global.adler32cs || jsPDF.API.adler32cs;
-        if (compress && typeof adler32cs === 'undefined') {
-          compress = false;
-        }
-
-        // outToPages = false as set in endDocument(). out() writes to content.
-
-        for (n = 1; n <= page; n++) {
-          pageObjectNumbers.push(newObject());
-          wPt = (pageWidth = pagedim[n].width) * k;
-          hPt = (pageHeight = pagedim[n].height) * k;
-          out('<</Type /Page');
-          out('/Parent 1 0 R');
-          out('/Resources 2 0 R');
-          out('/MediaBox [0 0 ' + f2(wPt) + ' ' + f2(hPt) + ']');
-          // Added for annotation plugin
-          events.publish('putPage', {
-            pageNumber: n,
-            page: pages[n]
-          });
-          out('/Contents ' + (objectNumber + 1) + ' 0 R');
-          out('>>');
-          out('endobj');
-
-          // Page content
-          p = pages[n].join('\n');
-          newObject();
-          if (compress) {
-            arr = [];
-            i = p.length;
-            while (i--) {
-              arr[i] = p.charCodeAt(i);
-            }
-            adler32 = adler32cs.from(p);
-            deflater = new Deflater(6);
-            deflater.append(new Uint8Array(arr));
-            p = deflater.flush();
-            arr = new Uint8Array(p.length + 6);
-            arr.set(new Uint8Array([120, 156])), arr.set(p, 2);
-            arr.set(new Uint8Array([adler32 & 0xFF, adler32 >> 8 & 0xFF, adler32 >> 16 & 0xFF, adler32 >> 24 & 0xFF]), p.length + 2);
-            p = String.fromCharCode.apply(null, arr);
-            out('<</Length ' + p.length + ' /Filter [/FlateDecode]>>');
-          } else {
-            out('<</Length ' + p.length + '>>');
-          }
-          putStream(p);
-          out('endobj');
-        }
-        offsets[1] = content_length;
-        out('1 0 obj');
-        out('<</Type /Pages');
-        var kids = '/Kids [';
-        for (i = 0; i < page; i++) {
-          kids += pageObjectNumbers[i] + ' 0 R ';
-        }
-        out(kids + ']');
-        out('/Count ' + page);
-        out('>>');
-        out('endobj');
-        events.publish('postPutPages');
-      },
-          putFont = function putFont(font) {
 
-        events.publish('putFont', {
-          font: font,
-          out: out,
-          newObject: newObject
-        });
-        if (font.isAlreadyPutted !== true) {
-          font.objectNumber = newObject();
-          out('<<');
-          out('/Type /Font');
-          out('/BaseFont /' + font.postScriptName);
-          out('/Subtype /Type1');
-          if (typeof font.encoding === 'string') {
-            out('/Encoding /' + font.encoding);
-          }
-          out('/FirstChar 32');
-          out('/LastChar 255');
-          out('>>');
-          out('endobj');
-        }
-      },
-          putFonts = function putFonts() {
-        for (var fontKey in fonts) {
-          if (fonts.hasOwnProperty(fontKey)) {
-            putFont(fonts[fontKey]);
-          }
-        }
-      },
-          putXobjectDict = function putXobjectDict() {
-        // Loop through images, or other data objects
-        events.publish('putXobjectDict');
-      },
-          putResourceDictionary = function putResourceDictionary() {
-        out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
-        out('/Font <<');
-
-        // Do this for each font, the '1' bit is the index of the font
-        for (var fontKey in fonts) {
-          if (fonts.hasOwnProperty(fontKey)) {
-            out('/' + fontKey + ' ' + fonts[fontKey].objectNumber + ' 0 R');
-          }
-        }
-        out('>>');
-        out('/XObject <<');
-        putXobjectDict();
-        out('>>');
-      },
-          putResources = function putResources() {
-        putFonts();
-        events.publish('putResources');
-        // Resource dictionary
-        offsets[2] = content_length;
-        out('2 0 obj');
-        out('<<');
-        putResourceDictionary();
-        out('>>');
-        out('endobj');
-        events.publish('postPutResources');
-      },
-          putAdditionalObjects = function putAdditionalObjects() {
-        events.publish('putAdditionalObjects');
-        for (var i = 0; i < additionalObjects.length; i++) {
-          var obj = additionalObjects[i];
-          offsets[obj.objId] = content_length;
-          out(obj.objId + ' 0 obj');
-          out(obj.content);        out('endobj');
-        }
-        objectNumber += additionalObjects.length;
-        events.publish('postPutAdditionalObjects');
-      },
-          addToFontDictionary = function addToFontDictionary(fontKey, fontName, fontStyle) {
-        // this is mapping structure for quick font key lookup.
-        // returns the KEY of the font (ex: "F1") for a given
-        // pair of font name and type (ex: "Arial". "Italic")
-        if (!fontmap.hasOwnProperty(fontName)) {
-          fontmap[fontName] = {};
-        }
-        fontmap[fontName][fontStyle] = fontKey;
-      },
+  function click(node) {
+    try {
+      node.dispatchEvent(new MouseEvent("click"));
+    } catch (e) {
+      var evt = document.createEvent("MouseEvents");
+      evt.initMouseEvent("click", true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
+      node.dispatchEvent(evt);
+    }
+  }
 
-      /**
-       * FontObject describes a particular font as member of an instnace of jsPDF
-       *
-       * It's a collection of properties like 'id' (to be used in PDF stream),
-       * 'fontName' (font's family name), 'fontStyle' (font's style variant label)
-       *
-       * @class
-       * @public
-       * @property id {String} PDF-document-instance-specific label assinged to the font.
-       * @property postScriptName {String} PDF specification full name for the font
-       * @property encoding {Object} Encoding_name-to-Font_metrics_object mapping.
-       * @name FontObject
-       * @ignore This should not be in the public docs.
-       */
-      addFont = function addFont(postScriptName, fontName, fontStyle, encoding) {
-        var fontKey = 'F' + (Object.keys(fonts).length + 1).toString(10),
-
-        // This is FontObject
-        font = fonts[fontKey] = {
-          'id': fontKey,
-          'postScriptName': postScriptName,
-          'fontName': fontName,
-          'fontStyle': fontStyle,
-          'encoding': encoding,
-          'metadata': {}
-        };
-        addToFontDictionary(fontKey, fontName, fontStyle);
-        events.publish('addFont', font);
+  var saveAs = globalObject.saveAs || ( // probably in some web worker
+  (typeof window === "undefined" ? "undefined" : _typeof(window)) !== "object" || window !== globalObject ? function saveAs() {
+    /* noop */
+  } : // Use download attribute first if possible (#193 Lumia mobile) unless this is a native app
+  typeof HTMLAnchorElement !== "undefined" && "download" in HTMLAnchorElement.prototype ? function saveAs(blob, name, opts) {
+    var URL = globalObject.URL || globalObject.webkitURL;
+    var a = document.createElement("a");
+    name = name || blob.name || "download";
+    a.download = name;
+    a.rel = "noopener"; // tabnabbing
+    // TODO: detect chrome extensions & packaged apps
+    // a.target = '_blank'
+
+    if (typeof blob === "string") {
+      // Support regular links
+      a.href = blob;
+
+      if (a.origin !== location.origin) {
+        corsEnabled(a.href) ? download(blob, name, opts) : click(a, a.target = "_blank");
+      } else {
+        click(a);
+      }
+    } else {
+      // Support blobs
+      a.href = URL.createObjectURL(blob);
+      setTimeout(function () {
+        URL.revokeObjectURL(a.href);
+      }, 4e4); // 40s
+
+      setTimeout(function () {
+        click(a);
+      }, 0);
+    }
+  } : // Use msSaveOrOpenBlob as a second approach
+  "msSaveOrOpenBlob" in navigator ? function saveAs(blob, name, opts) {
+    name = name || blob.name || "download";
 
-        return fontKey;
-      },
-          addFonts = function addFonts() {
-
-        var HELVETICA = "helvetica",
-            TIMES = "times",
-            COURIER = "courier",
-            NORMAL = "normal",
-            BOLD = "bold",
-            ITALIC = "italic",
-            BOLD_ITALIC = "bolditalic",
-            ZAPF = "zapfdingbats",
-            SYMBOL = "symbol",
-            standardFonts = [['Helvetica', HELVETICA, NORMAL, 'WinAnsiEncoding'], ['Helvetica-Bold', HELVETICA, BOLD, 'WinAnsiEncoding'], ['Helvetica-Oblique', HELVETICA, ITALIC, 'WinAnsiEncoding'], ['Helvetica-BoldOblique', HELVETICA, BOLD_ITALIC, 'WinAnsiEncoding'], ['Courier', COURIER, NORMAL, 'WinAnsiEncoding'], ['Courier-Bold', COURIER, BOLD, 'WinAnsiEncoding'], ['Courier-Oblique', COURIER, ITALIC, 'WinAnsiEncoding'], ['Courier-BoldOblique', COURIER, BOLD_ITALIC, 'WinAnsiEncoding'], ['Times-Roman', TIMES, NORMAL, 'WinAnsiEncoding'], ['Times-Bold', TIMES, BOLD, 'WinAnsiEncoding'], ['Times-Italic', TIMES, ITALIC, 'WinAnsiEncoding'], ['Times-BoldItalic', TIMES, BOLD_ITALIC, 'WinAnsiEncoding'], ['ZapfDingbats', ZAPF, NORMAL, null], ['Symbol', SYMBOL, NORMAL, null]];
-
-        for (var i = 0, l = standardFonts.length; i < l; i++) {
-          var fontKey = addFont(standardFonts[i][0], standardFonts[i][1], standardFonts[i][2], standardFonts[i][3]);
-
-          // adding aliases for standard fonts, this time matching the capitalization
-          var parts = standardFonts[i][0].split('-');
-          addToFontDictionary(fontKey, parts[0], parts[1] || '');
-        }
-        events.publish('addFonts', {
-          fonts: fonts,
-          dictionary: fontmap
+    if (typeof blob === "string") {
+      if (corsEnabled(blob)) {
+        download(blob, name, opts);
+      } else {
+        var a = document.createElement("a");
+        a.href = blob;
+        a.target = "_blank";
+        setTimeout(function () {
+          click(a);
         });
-      },
-          SAFE = function __safeCall(fn) {
-        fn.foo = function __safeCallWrapper() {
-          try {
-            return fn.apply(this, arguments);
-          } catch (e) {
-            var stack = e.stack || '';
-            if (~stack.indexOf(' at ')) stack = stack.split(" at ")[1];
-            var m = "Error in function " + stack.split("\n")[0].split('<')[0] + ": " + e.message;
-            if (global.console) {
-              global.console.error(m, e);
-              if (global.alert) alert(m);
-            } else {
-              throw new Error(m);
-            }
-          }
-        };
-        fn.foo.bar = fn;
-        return fn.foo;
-      },
-          to8bitStream = function to8bitStream(text, flags) {
-        /**
-         * PDF 1.3 spec:
-         * "For text strings encoded in Unicode, the first two bytes must be 254 followed by
-         * 255, representing the Unicode byte order marker, U+FEFF. (This sequence conflicts
-         * with the PDFDocEncoding character sequence thorn ydieresis, which is unlikely
-         * to be a meaningful beginning of a word or phrase.) The remainder of the
-         * string consists of Unicode character codes, according to the UTF-16 encoding
-         * specified in the Unicode standard, version 2.0. Commonly used Unicode values
-         * are represented as 2 bytes per character, with the high-order byte appearing first
-         * in the string."
-         *
-         * In other words, if there are chars in a string with char code above 255, we
-         * recode the string to UCS2 BE - string doubles in length and BOM is prepended.
-         *
-         * HOWEVER!
-         * Actual *content* (body) text (as opposed to strings used in document properties etc)
-         * does NOT expect BOM. There, it is treated as a literal GID (Glyph ID)
-         *
-         * Because of Adobe's focus on "you subset your fonts!" you are not supposed to have
-         * a font that maps directly Unicode (UCS2 / UTF16BE) code to font GID, but you could
-         * fudge it with "Identity-H" encoding and custom CIDtoGID map that mimics Unicode
-         * code page. There, however, all characters in the stream are treated as GIDs,
-         * including BOM, which is the reason we need to skip BOM in content text (i.e. that
-         * that is tied to a font).
-         *
-         * To signal this "special" PDFEscape / to8bitStream handling mode,
-         * API.text() function sets (unless you overwrite it with manual values
-         * given to API.text(.., flags) )
-         * flags.autoencode = true
-         * flags.noBOM = true
-         *
-         * ===================================================================================
-         * `flags` properties relied upon:
-         *   .sourceEncoding = string with encoding label.
-         *                     "Unicode" by default. = encoding of the incoming text.
-         *                     pass some non-existing encoding name
-         *                     (ex: 'Do not touch my strings! I know what I am doing.')
-         *                     to make encoding code skip the encoding step.
-         *   .outputEncoding = Either valid PDF encoding name
-         *                     (must be supported by jsPDF font metrics, otherwise no encoding)
-         *                     or a JS object, where key = sourceCharCode, value = outputCharCode
-         *                     missing keys will be treated as: sourceCharCode === outputCharCode
-         *   .noBOM
-         *       See comment higher above for explanation for why this is important
-         *   .autoencode
-         *       See comment higher above for explanation for why this is important
-         */
+      }
+    } else {
+      navigator.msSaveOrOpenBlob(bom(blob, opts), name);
+    }
+  } : // Fallback to using FileReader and a popup
+  function saveAs(blob, name, opts, popup) {
+    // Open a popup immediately do go around popup blocker
+    // Mostly only available on user interaction and the fileReader is async so...
+    popup = popup || open("", "_blank");
+
+    if (popup) {
+      popup.document.title = popup.document.body.innerText = "downloading...";
+    }
 
-        var i, l, sourceEncoding, encodingBlock, outputEncoding, newtext, isUnicode, ch, bch;
-
-        flags = flags || {};
-        sourceEncoding = flags.sourceEncoding || 'Unicode';
-        outputEncoding = flags.outputEncoding;
-
-        // This 'encoding' section relies on font metrics format
-        // attached to font objects by, among others,
-        // "Willow Systems' standard_font_metrics plugin"
-        // see jspdf.plugin.standard_font_metrics.js for format
-        // of the font.metadata.encoding Object.
-        // It should be something like
-        //   .encoding = {'codePages':['WinANSI....'], 'WinANSI...':{code:code, ...}}
-        //   .widths = {0:width, code:width, ..., 'fof':divisor}
-        //   .kerning = {code:{previous_char_code:shift, ..., 'fof':-divisor},...}
-        if ((flags.autoencode || outputEncoding) && fonts[activeFontKey].metadata && fonts[activeFontKey].metadata[sourceEncoding] && fonts[activeFontKey].metadata[sourceEncoding].encoding) {
-          encodingBlock = fonts[activeFontKey].metadata[sourceEncoding].encoding;
-
-          // each font has default encoding. Some have it clearly defined.
-          if (!outputEncoding && fonts[activeFontKey].encoding) {
-            outputEncoding = fonts[activeFontKey].encoding;
-          }
+    if (typeof blob === "string") return download(blob, name, opts);
+    var force = blob.type === "application/octet-stream";
 
-          // Hmmm, the above did not work? Let's try again, in different place.
-          if (!outputEncoding && encodingBlock.codePages) {
-            outputEncoding = encodingBlock.codePages[0]; // let's say, first one is the default
-          }
+    var isSafari = /constructor/i.test(globalObject.HTMLElement) || globalObject.safari;
 
-          if (typeof outputEncoding === 'string') {
-            outputEncoding = encodingBlock[outputEncoding];
-          }
-          // we want output encoding to be a JS Object, where
-          // key = sourceEncoding's character code and
-          // value = outputEncoding's character code.
-          if (outputEncoding) {
-            isUnicode = false;
-            newtext = [];
-            for (i = 0, l = text.length; i < l; i++) {
-              ch = outputEncoding[text.charCodeAt(i)];
-              if (ch) {
-                newtext.push(String.fromCharCode(ch));
-              } else {
-                newtext.push(text[i]);
-              }
+    var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);
 
-              // since we are looping over chars anyway, might as well
-              // check for residual unicodeness
-              if (newtext[i].charCodeAt(0) >> 8) {
-                /* more than 255 */
-                isUnicode = true;
-              }
-            }
-            text = newtext.join('');
-          }
-        }
+    if ((isChromeIOS || force && isSafari) && (typeof FileReader === "undefined" ? "undefined" : _typeof(FileReader)) === "object") {
+      // Safari doesn't allow downloading of blob URLs
+      var reader = new FileReader();
 
-        i = text.length;
-        // isUnicode may be set to false above. Hence the triple-equal to undefined
-        while (isUnicode === undefined && i !== 0) {
-          if (text.charCodeAt(i - 1) >> 8) {
-            /* more than 255 */
-            isUnicode = true;
-          }
-          i--;
-        }
-        if (!isUnicode) {
-          return text;
-        }
+      reader.onloadend = function () {
+        var url = reader.result;
+        url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, "data:attachment/file;");
+        if (popup) popup.location.href = url;else location = url;
+        popup = null; // reverse-tabnabbing #460
+      };
 
-        newtext = flags.noBOM ? [] : [254, 255];
-        for (i = 0, l = text.length; i < l; i++) {
-          ch = text.charCodeAt(i);
-          bch = ch >> 8; // divide by 256
-          if (bch >> 8) {
-            /* something left after dividing by 256 second time */
-            throw new Error("Character at position " + i + " of string '" + text + "' exceeds 16bits. Cannot be encoded into UCS-2 BE");
-          }
-          newtext.push(bch);
-          newtext.push(ch - (bch << 8));
-        }
-        return String.fromCharCode.apply(undefined, newtext);
-      },
-          pdfEscape = function pdfEscape(text, flags) {
-        /**
-         * Replace '/', '(', and ')' with pdf-safe versions
-         *
-         * Doing to8bitStream does NOT make this PDF display unicode text. For that
-         * we also need to reference a unicode font and embed it - royal pain in the rear.
-         *
-         * There is still a benefit to to8bitStream - PDF simply cannot handle 16bit chars,
-         * which JavaScript Strings are happy to provide. So, while we still cannot display
-         * 2-byte characters property, at least CONDITIONALLY converting (entire string containing)
-         * 16bit chars to (USC-2-BE) 2-bytes per char + BOM streams we ensure that entire PDF
-         * is still parseable.
-         * This will allow immediate support for unicode in document properties strings.
-         */
-        return to8bitStream(text, flags).replace(/\\/g, '\\\\').replace(/\(/g, '\\(').replace(/\)/g, '\\)');
-      },
-          putInfo = function putInfo() {
-        out('/Producer (jsPDF ' + jsPDF.version + ')');
-        for (var key in documentProperties) {
-          if (documentProperties.hasOwnProperty(key) && documentProperties[key]) {
-            out('/' + key.substr(0, 1).toUpperCase() + key.substr(1) + ' (' + pdfEscape(documentProperties[key]) + ')');
-          }
-        }
-        out('/CreationDate (' + creationDate + ')');
-      },
-          putCatalog = function putCatalog() {
-        out('/Type /Catalog');
-        out('/Pages 1 0 R');
-        // PDF13ref Section 7.2.1
-        if (!zoomMode) zoomMode = 'fullwidth';
-        switch (zoomMode) {
-          case 'fullwidth':
-            out('/OpenAction [3 0 R /FitH null]');
-            break;
-          case 'fullheight':
-            out('/OpenAction [3 0 R /FitV null]');
-            break;
-          case 'fullpage':
-            out('/OpenAction [3 0 R /Fit]');
-            break;
-          case 'original':
-            out('/OpenAction [3 0 R /XYZ null null 1]');
-            break;
-          default:
-            var pcn = '' + zoomMode;
-            if (pcn.substr(pcn.length - 1) === '%') zoomMode = parseInt(zoomMode) / 100;
-            if (typeof zoomMode === 'number') {
-              out('/OpenAction [3 0 R /XYZ null null ' + f2(zoomMode) + ']');
-            }
-        }
-        if (!layoutMode) layoutMode = 'continuous';
-        switch (layoutMode) {
-          case 'continuous':
-            out('/PageLayout /OneColumn');
-            break;
-          case 'single':
-            out('/PageLayout /SinglePage');
-            break;
-          case 'two':
-          case 'twoleft':
-            out('/PageLayout /TwoColumnLeft');
-            break;
-          case 'tworight':
-            out('/PageLayout /TwoColumnRight');
-            break;
-        }
-        if (pageMode) {
-          /**
-           * A name object specifying how the document should be displayed when opened:
-           * UseNone      : Neither document outline nor thumbnail images visible -- DEFAULT
-           * UseOutlines  : Document outline visible
-           * UseThumbs    : Thumbnail images visible
-           * FullScreen   : Full-screen mode, with no menu bar, window controls, or any other window visible
-           */
-          out('/PageMode /' + pageMode);
-        }
-        events.publish('putCatalog');
-      },
-          putTrailer = function putTrailer() {
-        out('/Size ' + (objectNumber + 1));
-        out('/Root ' + objectNumber + ' 0 R');
-        out('/Info ' + (objectNumber - 1) + ' 0 R');
-        out("/ID [ <" + fileId + "> <" + fileId + "> ]");
-      },
-          beginPage = function beginPage(width, height) {
-        // Dimensions are stored as user units and converted to points on output
-        var orientation = typeof height === 'string' && height.toLowerCase();
-        if (typeof width === 'string') {
-          var format = width.toLowerCase();
-          if (pageFormats.hasOwnProperty(format)) {
-            width = pageFormats[format][0] / k;
-            height = pageFormats[format][1] / k;
-          }
-        }
-        if (Array.isArray(width)) {
-          height = width[1];
-          width = width[0];
-        }
-        if (orientation) {
-          switch (orientation.substr(0, 1)) {
-            case 'l':
-              if (height > width) orientation = 's';
-              break;
-            case 'p':
-              if (width > height) orientation = 's';
-              break;
-          }
-          if (orientation === 's') {
-            tmp = width;
-            width = height;
-            height = tmp;
-          }
-        }
-        outToPages = true;
-        pages[++page] = [];
-        pagedim[page] = {
-          width: Number(width) || pageWidth,
-          height: Number(height) || pageHeight
-        };
-        pagesContext[page] = {};
-        _setPage(page);
-      },
-          _addPage = function _addPage() {
-        beginPage.apply(this, arguments);
-        // Set line width
-        out(f2(lineWidth * k) + ' w');
-        // Set draw color
-        out(drawColor);
-        // resurrecting non-default line caps, joins
-        if (lineCapID !== 0) {
-          out(lineCapID + ' J');
-        }
-        if (lineJoinID !== 0) {
-          out(lineJoinID + ' j');
-        }
-        events.publish('addPage', {
-          pageNumber: page
-        });
-      },
-          _deletePage = function _deletePage(n) {
-        if (n > 0 && n <= page) {
-          pages.splice(n, 1);
-          pagedim.splice(n, 1);
-          page--;
-          if (currentPage > page) {
-            currentPage = page;
-          }
-          this.setPage(currentPage);
-        }
-      },
-          _setPage = function _setPage(n) {
-        if (n > 0 && n <= page) {
-          currentPage = n;
-          pageWidth = pagedim[n].width;
-          pageHeight = pagedim[n].height;
-        }
-      },
+      reader.readAsDataURL(blob);
+    } else {
+      var URL = globalObject.URL || globalObject.webkitURL;
+      var url = URL.createObjectURL(blob);
+      if (popup) popup.location = url;else location.href = url;
+      popup = null; // reverse-tabnabbing #460
+
+      setTimeout(function () {
+        URL.revokeObjectURL(url);
+      }, 4e4); // 40s
+    }
+  });
 
-      /**
-       * Returns a document-specific font key - a label assigned to a
-       * font name + font type combination at the time the font was added
-       * to the font inventory.
-       *
-       * Font key is used as label for the desired font for a block of text
-       * to be added to the PDF document stream.
-       * @private
-       * @function
-       * @param fontName {String} can be undefined on "falthy" to indicate "use current"
-       * @param fontStyle {String} can be undefined on "falthy" to indicate "use current"
-       * @returns {String} Font key.
-       */
-      _getFont = function _getFont(fontName, fontStyle, options) {
-        var key = undefined,
-            fontNameLowerCase;
-        options = options || {};
+  /**
+   * A class to parse color values
+   * @author Stoyan Stefanov <sstoo@gmail.com>
+   * {@link   http://www.phpied.com/rgb-color-parser-in-javascript/}
+   * @license Use it if you like it
+   */
+  function RGBColor(color_string) {
+    color_string = color_string || "";
+    this.ok = false; // strip any leading #
 
-        fontName = fontName !== undefined ? fontName : fonts[activeFontKey].fontName;
-        fontStyle = fontStyle !== undefined ? fontStyle : fonts[activeFontKey].fontStyle;
-        fontNameLowerCase = fontName.toLowerCase();
+    if (color_string.charAt(0) == "#") {
+      // remove # if any
+      color_string = color_string.substr(1, 6);
+    }
 
-        if (fontmap[fontNameLowerCase] !== undefined && fontmap[fontNameLowerCase][fontStyle] !== undefined) {
-          key = fontmap[fontNameLowerCase][fontStyle];
-        } else if (fontmap[fontName] !== undefined && fontmap[fontName][fontStyle] !== undefined) {
-          key = fontmap[fontName][fontStyle];
-        } else {
-          if (options.disableWarning === false) {
-            console.warn("Unable to look up font label for font '" + fontName + "', '" + fontStyle + "'. Refer to getFontList() for available fonts.");
-          }
-        }
+    color_string = color_string.replace(/ /g, "");
+    color_string = color_string.toLowerCase();
+    var channels; // before getting into regexps, try simple matches
+    // and overwrite the input
+
+    var simple_colors = {
+      aliceblue: "f0f8ff",
+      antiquewhite: "faebd7",
+      aqua: "00ffff",
+      aquamarine: "7fffd4",
+      azure: "f0ffff",
+      beige: "f5f5dc",
+      bisque: "ffe4c4",
+      black: "000000",
+      blanchedalmond: "ffebcd",
+      blue: "0000ff",
+      blueviolet: "8a2be2",
+      brown: "a52a2a",
+      burlywood: "deb887",
+      cadetblue: "5f9ea0",
+      chartreuse: "7fff00",
+      chocolate: "d2691e",
+      coral: "ff7f50",
+      cornflowerblue: "6495ed",
+      cornsilk: "fff8dc",
+      crimson: "dc143c",
+      cyan: "00ffff",
+      darkblue: "00008b",
+      darkcyan: "008b8b",
+      darkgoldenrod: "b8860b",
+      darkgray: "a9a9a9",
+      darkgreen: "006400",
+      darkkhaki: "bdb76b",
+      darkmagenta: "8b008b",
+      darkolivegreen: "556b2f",
+      darkorange: "ff8c00",
+      darkorchid: "9932cc",
+      darkred: "8b0000",
+      darksalmon: "e9967a",
+      darkseagreen: "8fbc8f",
+      darkslateblue: "483d8b",
+      darkslategray: "2f4f4f",
+      darkturquoise: "00ced1",
+      darkviolet: "9400d3",
+      deeppink: "ff1493",
+      deepskyblue: "00bfff",
+      dimgray: "696969",
+      dodgerblue: "1e90ff",
+      feldspar: "d19275",
+      firebrick: "b22222",
+      floralwhite: "fffaf0",
+      forestgreen: "228b22",
+      fuchsia: "ff00ff",
+      gainsboro: "dcdcdc",
+      ghostwhite: "f8f8ff",
+      gold: "ffd700",
+      goldenrod: "daa520",
+      gray: "808080",
+      green: "008000",
+      greenyellow: "adff2f",
+      honeydew: "f0fff0",
+      hotpink: "ff69b4",
+      indianred: "cd5c5c",
+      indigo: "4b0082",
+      ivory: "fffff0",
+      khaki: "f0e68c",
+      lavender: "e6e6fa",
+      lavenderblush: "fff0f5",
+      lawngreen: "7cfc00",
+      lemonchiffon: "fffacd",
+      lightblue: "add8e6",
+      lightcoral: "f08080",
+      lightcyan: "e0ffff",
+      lightgoldenrodyellow: "fafad2",
+      lightgrey: "d3d3d3",
+      lightgreen: "90ee90",
+      lightpink: "ffb6c1",
+      lightsalmon: "ffa07a",
+      lightseagreen: "20b2aa",
+      lightskyblue: "87cefa",
+      lightslateblue: "8470ff",
+      lightslategray: "778899",
+      lightsteelblue: "b0c4de",
+      lightyellow: "ffffe0",
+      lime: "00ff00",
+      limegreen: "32cd32",
+      linen: "faf0e6",
+      magenta: "ff00ff",
+      maroon: "800000",
+      mediumaquamarine: "66cdaa",
+      mediumblue: "0000cd",
+      mediumorchid: "ba55d3",
+      mediumpurple: "9370d8",
+      mediumseagreen: "3cb371",
+      mediumslateblue: "7b68ee",
+      mediumspringgreen: "00fa9a",
+      mediumturquoise: "48d1cc",
+      mediumvioletred: "c71585",
+      midnightblue: "191970",
+      mintcream: "f5fffa",
+      mistyrose: "ffe4e1",
+      moccasin: "ffe4b5",
+      navajowhite: "ffdead",
+      navy: "000080",
+      oldlace: "fdf5e6",
+      olive: "808000",
+      olivedrab: "6b8e23",
+      orange: "ffa500",
+      orangered: "ff4500",
+      orchid: "da70d6",
+      palegoldenrod: "eee8aa",
+      palegreen: "98fb98",
+      paleturquoise: "afeeee",
+      palevioletred: "d87093",
+      papayawhip: "ffefd5",
+      peachpuff: "ffdab9",
+      peru: "cd853f",
+      pink: "ffc0cb",
+      plum: "dda0dd",
+      powderblue: "b0e0e6",
+      purple: "800080",
+      red: "ff0000",
+      rosybrown: "bc8f8f",
+      royalblue: "4169e1",
+      saddlebrown: "8b4513",
+      salmon: "fa8072",
+      sandybrown: "f4a460",
+      seagreen: "2e8b57",
+      seashell: "fff5ee",
+      sienna: "a0522d",
+      silver: "c0c0c0",
+      skyblue: "87ceeb",
+      slateblue: "6a5acd",
+      slategray: "708090",
+      snow: "fffafa",
+      springgreen: "00ff7f",
+      steelblue: "4682b4",
+      tan: "d2b48c",
+      teal: "008080",
+      thistle: "d8bfd8",
+      tomato: "ff6347",
+      turquoise: "40e0d0",
+      violet: "ee82ee",
+      violetred: "d02090",
+      wheat: "f5deb3",
+      white: "ffffff",
+      whitesmoke: "f5f5f5",
+      yellow: "ffff00",
+      yellowgreen: "9acd32"
+    };
+    color_string = simple_colors[color_string] || color_string; // array of color definition objects
 
-        if (!key && !options.noFallback) {
-          key = fontmap['times'][fontStyle];
-          if (key == null) {
-            key = fontmap['times']['normal'];
-          }
-        }
-        return key;
-      },
-          buildDocument = function buildDocument() {
-        outToPages = false; // switches out() to content
-
-        objectNumber = 2;
-        content_length = 0;
-        content = [];
-        offsets = [];
-        additionalObjects = [];
-        // Added for AcroForm
-        events.publish('buildDocument');
-
-        // putHeader()
-        out('%PDF-' + pdfVersion);
-        out("%\xBA\xDF\xAC\xE0");
-
-        putPages();
-
-        // Must happen after putPages
-        // Modifies current object Id
-        putAdditionalObjects();
-
-        putResources();
-
-        // Info
-        newObject();
-        out('<<');
-        putInfo();
-        out('>>');
-        out('endobj');
-
-        // Catalog
-        newObject();
-        out('<<');
-        putCatalog();
-        out('>>');
-        out('endobj');
-
-        // Cross-ref
-        var o = content_length,
-            i,
-            p = "0000000000";
-        out('xref');
-        out('0 ' + (objectNumber + 1));
-        out(p + ' 65535 f ');
-        for (i = 1; i <= objectNumber; i++) {
-          var offset = offsets[i];
-          if (typeof offset === 'function') {
-            out((p + offsets[i]()).slice(-10) + ' 00000 n ');
-          } else {
-            out((p + offsets[i]).slice(-10) + ' 00000 n ');
-          }
-        }
-        // Trailer
-        out('trailer');
-        out('<<');
-        putTrailer();
-        out('>>');
-        out('startxref');
-        out('' + o);
-        out('%%EOF');
+    var color_defs = [{
+      re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
+      example: ["rgb(123, 234, 45)", "rgb(255,234,245)"],
+      process: function process(bits) {
+        return [parseInt(bits[1]), parseInt(bits[2]), parseInt(bits[3])];
+      }
+    }, {
+      re: /^(\w{2})(\w{2})(\w{2})$/,
+      example: ["#00ff00", "336699"],
+      process: function process(bits) {
+        return [parseInt(bits[1], 16), parseInt(bits[2], 16), parseInt(bits[3], 16)];
+      }
+    }, {
+      re: /^(\w{1})(\w{1})(\w{1})$/,
+      example: ["#fb0", "f0f"],
+      process: function process(bits) {
+        return [parseInt(bits[1] + bits[1], 16), parseInt(bits[2] + bits[2], 16), parseInt(bits[3] + bits[3], 16)];
+      }
+    }]; // search through the definitions to find a match
+
+    for (var i = 0; i < color_defs.length; i++) {
+      var re = color_defs[i].re;
+      var processor = color_defs[i].process;
+      var bits = re.exec(color_string);
+
+      if (bits) {
+        channels = processor(bits);
+        this.r = channels[0];
+        this.g = channels[1];
+        this.b = channels[2];
+        this.ok = true;
+      }
+    } // validate/cleanup values
 
-        outToPages = true;
 
-        return content.join('\n');
-      },
-          getStyle = function getStyle(style) {
-        // see path-painting operators in PDF spec
-        var op = 'S'; // stroke
-        if (style === 'F') {
-          op = 'f'; // fill
-        } else if (style === 'FD' || style === 'DF') {
-          op = 'B'; // both
-        } else if (style === 'f' || style === 'f*' || style === 'B' || style === 'B*') {
-          /*
-           Allow direct use of these PDF path-painting operators:
-           - f    fill using nonzero winding number rule
-           - f*    fill using even-odd rule
-           - B    fill then stroke with fill using non-zero winding number rule
-           - B*    fill then stroke with fill using even-odd rule
-           */
-          op = style;
-        }
-        return op;
-      },
-          getArrayBuffer = function getArrayBuffer() {
-        var data = buildDocument(),
-            len = data.length,
-            ab = new ArrayBuffer(len),
-            u8 = new Uint8Array(ab);
+    this.r = this.r < 0 || isNaN(this.r) ? 0 : this.r > 255 ? 255 : this.r;
+    this.g = this.g < 0 || isNaN(this.g) ? 0 : this.g > 255 ? 255 : this.g;
+    this.b = this.b < 0 || isNaN(this.b) ? 0 : this.b > 255 ? 255 : this.b; // some getters
 
-        while (len--) {
-          u8[len] = data.charCodeAt(len);
-        }return ab;
-      },
-          getBlob = function getBlob() {
-        return new Blob([getArrayBuffer()], {
-          type: "application/pdf"
-        });
-      },
+    this.toRGB = function () {
+      return "rgb(" + this.r + ", " + this.g + ", " + this.b + ")";
+    };
 
-      /**
-       * Generates the PDF document.
-       *
-       * If `type` argument is undefined, output is raw body of resulting PDF returned as a string.
-       *
-       * @param {String} type A string identifying one of the possible output types.
-       * @param {Object} options An object providing some additional signalling to PDF generator.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name output
-       */
-      _output = SAFE(function (type, options) {
-        var datauri = ('' + type).substr(0, 6) === 'dataur' ? 'data:application/pdf;base64,' + btoa(buildDocument()) : 0;
+    this.toHex = function () {
+      var r = this.r.toString(16);
+      var g = this.g.toString(16);
+      var b = this.b.toString(16);
+      if (r.length == 1) r = "0" + r;
+      if (g.length == 1) g = "0" + g;
+      if (b.length == 1) b = "0" + b;
+      return "#" + r + g + b;
+    };
+  }
 
-        switch (type) {
-          case undefined:
-            return buildDocument();
-          case 'save':
-            if ((typeof navigator === 'undefined' ? 'undefined' : _typeof(navigator)) === "object" && navigator.getUserMedia) {
-              if (global.URL === undefined || global.URL.createObjectURL === undefined) {
-                return API.output('dataurlnewwindow');
-              }
-            }
-            saveAs(getBlob(), options);
-            if (typeof saveAs.unload === 'function') {
-              if (global.setTimeout) {
-                setTimeout(saveAs.unload, 911);
-              }
-            }
-            break;
-          case 'arraybuffer':
-            return getArrayBuffer();
-          case 'blob':
-            return getBlob();
-          case 'bloburi':
-          case 'bloburl':
-            // User is responsible of calling revokeObjectURL
-            return global.URL && global.URL.createObjectURL(getBlob()) || void 0;
-          case 'datauristring':
-          case 'dataurlstring':
-            return datauri;
-          case 'dataurlnewwindow':
-            var nW = global.open(datauri);
-            if (nW || typeof safari === "undefined") return nW;
-          /* pass through */
-          case 'datauri':
-          case 'dataurl':
-            return global.document.location.href = datauri;
-          default:
-            throw new Error('Output type "' + type + '" is not supported.');
-        }
-        // @TODO: Add different output options
-      }),
+  var atob, btoa;
 
+  (function () {
+    atob = globalObject.atob.bind(globalObject);
+    btoa = globalObject.btoa.bind(globalObject);
+    return;
+  })();
 
-      /**
-       * Used to see if a supplied hotfix was requested when the pdf instance was created.
-       * @param {String} hotfixName - The name of the hotfix to check.
-       * @returns {boolean}
-       */
-      hasHotfix = function hasHotfix(hotfixName) {
-        return Array.isArray(hotfixes) === true && hotfixes.indexOf(hotfixName) > -1;
-      };
+  /**
+   * @license
+   * Joseph Myers does not specify a particular license for his work.
+   *
+   * Author: Joseph Myers
+   * Accessed from: http://www.myersdaily.org/joseph/javascript/md5.js
+   *
+   * Modified by: Owen Leong
+   */
+  function md5cycle(x, k) {
+    var a = x[0],
+        b = x[1],
+        c = x[2],
+        d = x[3];
+    a = ff(a, b, c, d, k[0], 7, -680876936);
+    d = ff(d, a, b, c, k[1], 12, -389564586);
+    c = ff(c, d, a, b, k[2], 17, 606105819);
+    b = ff(b, c, d, a, k[3], 22, -1044525330);
+    a = ff(a, b, c, d, k[4], 7, -176418897);
+    d = ff(d, a, b, c, k[5], 12, 1200080426);
+    c = ff(c, d, a, b, k[6], 17, -1473231341);
+    b = ff(b, c, d, a, k[7], 22, -45705983);
+    a = ff(a, b, c, d, k[8], 7, 1770035416);
+    d = ff(d, a, b, c, k[9], 12, -1958414417);
+    c = ff(c, d, a, b, k[10], 17, -42063);
+    b = ff(b, c, d, a, k[11], 22, -1990404162);
+    a = ff(a, b, c, d, k[12], 7, 1804603682);
+    d = ff(d, a, b, c, k[13], 12, -40341101);
+    c = ff(c, d, a, b, k[14], 17, -1502002290);
+    b = ff(b, c, d, a, k[15], 22, 1236535329);
+    a = gg(a, b, c, d, k[1], 5, -165796510);
+    d = gg(d, a, b, c, k[6], 9, -1069501632);
+    c = gg(c, d, a, b, k[11], 14, 643717713);
+    b = gg(b, c, d, a, k[0], 20, -373897302);
+    a = gg(a, b, c, d, k[5], 5, -701558691);
+    d = gg(d, a, b, c, k[10], 9, 38016083);
+    c = gg(c, d, a, b, k[15], 14, -660478335);
+    b = gg(b, c, d, a, k[4], 20, -405537848);
+    a = gg(a, b, c, d, k[9], 5, 568446438);
+    d = gg(d, a, b, c, k[14], 9, -1019803690);
+    c = gg(c, d, a, b, k[3], 14, -187363961);
+    b = gg(b, c, d, a, k[8], 20, 1163531501);
+    a = gg(a, b, c, d, k[13], 5, -1444681467);
+    d = gg(d, a, b, c, k[2], 9, -51403784);
+    c = gg(c, d, a, b, k[7], 14, 1735328473);
+    b = gg(b, c, d, a, k[12], 20, -1926607734);
+    a = hh(a, b, c, d, k[5], 4, -378558);
+    d = hh(d, a, b, c, k[8], 11, -2022574463);
+    c = hh(c, d, a, b, k[11], 16, 1839030562);
+    b = hh(b, c, d, a, k[14], 23, -35309556);
+    a = hh(a, b, c, d, k[1], 4, -1530992060);
+    d = hh(d, a, b, c, k[4], 11, 1272893353);
+    c = hh(c, d, a, b, k[7], 16, -155497632);
+    b = hh(b, c, d, a, k[10], 23, -1094730640);
+    a = hh(a, b, c, d, k[13], 4, 681279174);
+    d = hh(d, a, b, c, k[0], 11, -358537222);
+    c = hh(c, d, a, b, k[3], 16, -722521979);
+    b = hh(b, c, d, a, k[6], 23, 76029189);
+    a = hh(a, b, c, d, k[9], 4, -640364487);
+    d = hh(d, a, b, c, k[12], 11, -421815835);
+    c = hh(c, d, a, b, k[15], 16, 530742520);
+    b = hh(b, c, d, a, k[2], 23, -995338651);
+    a = ii(a, b, c, d, k[0], 6, -198630844);
+    d = ii(d, a, b, c, k[7], 10, 1126891415);
+    c = ii(c, d, a, b, k[14], 15, -1416354905);
+    b = ii(b, c, d, a, k[5], 21, -57434055);
+    a = ii(a, b, c, d, k[12], 6, 1700485571);
+    d = ii(d, a, b, c, k[3], 10, -1894986606);
+    c = ii(c, d, a, b, k[10], 15, -1051523);
+    b = ii(b, c, d, a, k[1], 21, -2054922799);
+    a = ii(a, b, c, d, k[8], 6, 1873313359);
+    d = ii(d, a, b, c, k[15], 10, -30611744);
+    c = ii(c, d, a, b, k[6], 15, -1560198380);
+    b = ii(b, c, d, a, k[13], 21, 1309151649);
+    a = ii(a, b, c, d, k[4], 6, -145523070);
+    d = ii(d, a, b, c, k[11], 10, -1120210379);
+    c = ii(c, d, a, b, k[2], 15, 718787259);
+    b = ii(b, c, d, a, k[9], 21, -343485551);
+    x[0] = add32(a, x[0]);
+    x[1] = add32(b, x[1]);
+    x[2] = add32(c, x[2]);
+    x[3] = add32(d, x[3]);
+  }
 
-      switch (unit) {
-        case 'pt':
-          k = 1;
-          break;
-        case 'mm':
-          k = 72 / 25.4;
-          break;
-        case 'cm':
-          k = 72 / 2.54;
-          break;
-        case 'in':
-          k = 72;
-          break;
-        case 'px':
-          if (hasHotfix('px_scaling') == true) {
-            k = 72 / 96;
-          } else {
-            k = 96 / 72;
-          }
-          break;
-        case 'pc':
-          k = 12;
-          break;
-        case 'em':
-          k = 12;
-          break;
-        case 'ex':
-          k = 6;
-          break;
-        default:
-          throw 'Invalid unit: ' + unit;
-      }
+  function cmn(q, a, b, x, s, t) {
+    a = add32(add32(a, q), add32(x, t));
+    return add32(a << s | a >>> 32 - s, b);
+  }
 
-      setCreationDate();
-      setFileId();
+  function ff(a, b, c, d, x, s, t) {
+    return cmn(b & c | ~b & d, a, b, x, s, t);
+  }
 
-      //---------------------------------------
-      // Public API
+  function gg(a, b, c, d, x, s, t) {
+    return cmn(b & d | c & ~d, a, b, x, s, t);
+  }
 
-      /**
-       * Object exposing internal API to plugins
-       * @public
-       */
-      API.internal = {
-        'pdfEscape': pdfEscape,
-        'getStyle': getStyle,
-        /**
-         * Returns {FontObject} describing a particular font.
-         * @public
-         * @function
-         * @param fontName {String} (Optional) Font's family name
-         * @param fontStyle {String} (Optional) Font's style variation name (Example:"Italic")
-         * @returns {FontObject}
-         */
-        'getFont': function getFont() {
-          return fonts[_getFont.apply(API, arguments)];
-        },
-        'getFontSize': function getFontSize() {
-          return activeFontSize;
-        },
-        'getCharSpace': function getCharSpace() {
-          return activeCharSpace;
-        },
-        'getTextColor': function getTextColor() {
-          var colorEncoded = textColor.split(' ');
-          if (colorEncoded.length === 2 && colorEncoded[1] === 'g') {
-            // convert grayscale value to rgb so that it can be converted to hex for consistency
-            var floatVal = parseFloat(colorEncoded[0]);
-            colorEncoded = [floatVal, floatVal, floatVal, 'r'];
-          }
-          var colorAsHex = '#';
-          for (var i = 0; i < 3; i++) {
-            colorAsHex += ('0' + Math.floor(parseFloat(colorEncoded[i]) * 255).toString(16)).slice(-2);
-          }
-          return colorAsHex;
-        },
-        'getLineHeight': function getLineHeight() {
-          return activeFontSize * lineHeightProportion;
-        },
-        'write': function write(string1 /*, string2, string3, etc */) {
-          out(arguments.length === 1 ? string1 : Array.prototype.join.call(arguments, ' '));
-        },
-        'getCoordinateString': function getCoordinateString(value) {
-          return f2(value * k);
-        },
-        'getVerticalCoordinateString': function getVerticalCoordinateString(value) {
-          return f2((pageHeight - value) * k);
-        },
-        'collections': {},
-        'newObject': newObject,
-        'newAdditionalObject': newAdditionalObject,
-        'newObjectDeferred': newObjectDeferred,
-        'newObjectDeferredBegin': newObjectDeferredBegin,
-        'putStream': putStream,
-        'events': events,
-        // ratio that you use in multiplication of a given "size" number to arrive to 'point'
-        // units of measurement.
-        // scaleFactor is set at initialization of the document and calculated against the stated
-        // default measurement units for the document.
-        // If default is "mm", k is the number that will turn number in 'mm' into 'points' number.
-        // through multiplication.
-        'scaleFactor': k,
-        'pageSize': {
-          getWidth: function getWidth() {
-            return pageWidth;
-          },
-          getHeight: function getHeight() {
-            return pageHeight;
-          }
-        },
-        'output': function output(type, options) {
-          return _output(type, options);
-        },
-        'getNumberOfPages': function getNumberOfPages() {
-          return pages.length - 1;
-        },
-        'pages': pages,
-        'out': out,
-        'f2': f2,
-        'getPageInfo': function getPageInfo(pageNumberOneBased) {
-          var objId = (pageNumberOneBased - 1) * 2 + 3;
-          return {
-            objId: objId,
-            pageNumber: pageNumberOneBased,
-            pageContext: pagesContext[pageNumberOneBased]
-          };
-        },
-        'getCurrentPageInfo': function getCurrentPageInfo() {
-          var objId = (currentPage - 1) * 2 + 3;
-          return {
-            objId: objId,
-            pageNumber: currentPage,
-            pageContext: pagesContext[currentPage]
-          };
-        },
-        'getPDFVersion': function getPDFVersion() {
-          return pdfVersion;
-        },
-        'hasHotfix': hasHotfix //Expose the hasHotfix check so plugins can also check them.
-      };
+  function hh(a, b, c, d, x, s, t) {
+    return cmn(b ^ c ^ d, a, b, x, s, t);
+  }
 
-      /**
-       * Adds (and transfers the focus to) new page to the PDF document.
-       * @param format {String/Array} The format of the new page. Can be <ul><li>a0 - a10</li><li>b0 - b10</li><li>c0 - c10</li><li>c0 - c10</li><li>dl</li><li>letter</li><li>government-letter</li><li>legal</li><li>junior-legal</li><li>ledger</li><li>tabloid</li><li>credit-card</li></ul><br />
-       * Default is "a4". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array , e.g. [595.28, 841.89]
-       * @param orientation {String} Orientation of the new page. Possible values are "portrait" or "landscape" (or shortcuts "p" (Default), "l") 
-       * @function
-       * @returns {jsPDF}
-       *
-       * @methodOf jsPDF#
-       * @name addPage
-       */
-      API.addPage = function () {
-        _addPage.apply(this, arguments);
-        return this;
-      };
-      /**
-       * Adds (and transfers the focus to) new page to the PDF document.
-       * @function
-       * @returns {jsPDF}
-       *
-       * @methodOf jsPDF#
-       * @name setPage
-       * @param {Number} page Switch the active page to the page number specified
-       * @example
-       * doc = jsPDF()
-       * doc.addPage()
-       * doc.addPage()
-       * doc.text('I am on page 3', 10, 10)
-       * doc.setPage(1)
-       * doc.text('I am on page 1', 10, 10)
-       */
-      API.setPage = function () {
-        _setPage.apply(this, arguments);
-        return this;
-      };
-      API.insertPage = function (beforePage) {
-        this.addPage();
-        this.movePage(currentPage, beforePage);
-        return this;
-      };
-      API.movePage = function (targetPage, beforePage) {
-        if (targetPage > beforePage) {
-          var tmpPages = pages[targetPage];
-          var tmpPagedim = pagedim[targetPage];
-          var tmpPagesContext = pagesContext[targetPage];
-          for (var i = targetPage; i > beforePage; i--) {
-            pages[i] = pages[i - 1];
-            pagedim[i] = pagedim[i - 1];
-            pagesContext[i] = pagesContext[i - 1];
-          }
-          pages[beforePage] = tmpPages;
-          pagedim[beforePage] = tmpPagedim;
-          pagesContext[beforePage] = tmpPagesContext;
-          this.setPage(beforePage);
-        } else if (targetPage < beforePage) {
-          var tmpPages = pages[targetPage];
-          var tmpPagedim = pagedim[targetPage];
-          var tmpPagesContext = pagesContext[targetPage];
-          for (var i = targetPage; i < beforePage; i++) {
-            pages[i] = pages[i + 1];
-            pagedim[i] = pagedim[i + 1];
-            pagesContext[i] = pagesContext[i + 1];
-          }
-          pages[beforePage] = tmpPages;
-          pagedim[beforePage] = tmpPagedim;
-          pagesContext[beforePage] = tmpPagesContext;
-          this.setPage(beforePage);
-        }
-        return this;
-      };
+  function ii(a, b, c, d, x, s, t) {
+    return cmn(c ^ (b | ~d), a, b, x, s, t);
+  }
 
-      API.deletePage = function () {
-        _deletePage.apply(this, arguments);
-        return this;
-      };
+  function md51(s) {
+    // txt = '';
+    var n = s.length,
+        state = [1732584193, -271733879, -1732584194, 271733878],
+        i;
 
-      API.setCreationDate = function (date) {
-        setCreationDate(date);
-        return this;
-      };
+    for (i = 64; i <= s.length; i += 64) {
+      md5cycle(state, md5blk(s.substring(i - 64, i)));
+    }
 
-      API.getCreationDate = function (type) {
-        return getCreationDate(type);
-      };
+    s = s.substring(i - 64);
+    var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
 
-      API.setFileId = function (value) {
-        setFileId(value);
-        return this;
-      };
+    for (i = 0; i < s.length; i++) {
+      tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3);
+    }
 
-      API.getFileId = function () {
-        return getFileId();
-      };
+    tail[i >> 2] |= 0x80 << (i % 4 << 3);
 
-      /**
-       * Set the display mode options of the page like zoom and layout.
-       *
-       * @param {integer|String} zoom   You can pass an integer or percentage as
-       * a string. 2 will scale the document up 2x, '200%' will scale up by the
-       * same amount. You can also set it to 'fullwidth', 'fullheight',
-       * 'fullpage', or 'original'.
-       *
-       * Only certain PDF readers support this, such as Adobe Acrobat
-       *
-       * @param {String} layout Layout mode can be: 'continuous' - this is the
-       * default continuous scroll. 'single' - the single page mode only shows one
-       * page at a time. 'twoleft' - two column left mode, first page starts on
-       * the left, and 'tworight' - pages are laid out in two columns, with the
-       * first page on the right. This would be used for books.
-       * @param {String} pmode 'UseOutlines' - it shows the
-       * outline of the document on the left. 'UseThumbs' - shows thumbnails along
-       * the left. 'FullScreen' - prompts the user to enter fullscreen mode.
-       *
-       * @function
-       * @returns {jsPDF}
-       * @name setDisplayMode
-       */
-      API.setDisplayMode = function (zoom, layout, pmode) {
-        zoomMode = zoom;
-        layoutMode = layout;
-        pageMode = pmode;
+    if (i > 55) {
+      md5cycle(state, tail);
 
-        var validPageModes = [undefined, null, 'UseNone', 'UseOutlines', 'UseThumbs', 'FullScreen'];
-        if (validPageModes.indexOf(pmode) == -1) {
-          throw new Error('Page mode must be one of UseNone, UseOutlines, UseThumbs, or FullScreen. "' + pmode + '" is not recognized.');
-        }
-        return this;
-      };
+      for (i = 0; i < 16; i++) {
+        tail[i] = 0;
+      }
+    }
 
-      /**
-       * Adds text to page. Supports adding multiline text when 'text' argument is an Array of Strings.
-       *
-       * @function
-       * @param {String|Array} text String or array of strings to be added to the page. Each line is shifted one line down per font, spacing settings declared before this call.
-       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Object} options Collection of settings signalling how the text must be encoded. Defaults are sane. If you think you want to pass some flags, you likely can read the source.
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name text
-       */
-      API.text = function (text, x, y, options) {
-        /**
-         * Inserts something like this into PDF
-         *   BT
-         *    /F1 16 Tf  % Font name + size
-         *    16 TL % How many units down for next line in multiline text
-         *    0 g % color
-         *    28.35 813.54 Td % position
-         *    (line one) Tj
-         *    T* (line two) Tj
-         *    T* (line three) Tj
-         *   ET
-         */
+    tail[14] = n * 8;
+    md5cycle(state, tail);
+    return state;
+  }
+  /* there needs to be support for Unicode here,
+   * unless we pretend that we can redefine the MD-5
+   * algorithm for multi-byte characters (perhaps
+   * by adding every four 16-bit characters and
+   * shortening the sum to 32 bits). Otherwise
+   * I suggest performing MD-5 as if every character
+   * was two bytes--e.g., 0040 0025 = @%--but then
+   * how will an ordinary MD-5 sum be matched?
+   * There is no way to standardize text to something
+   * like UTF-8 before transformation; speed cost is
+   * utterly prohibitive. The JavaScript standard
+   * itself needs to look at this: it should start
+   * providing access to strings as preformed UTF-8
+   * 8-bit unsigned value arrays.
+   */
 
-        var xtra = '';
-        var isHex = false;
-        var lineHeight = lineHeightProportion;
 
-        var scope = this;
+  function md5blk(s) {
+    /* I figured global was faster.   */
+    var md5blks = [],
+        i;
+    /* Andy King said do it this way. */
 
-        function ESC(s) {
-          s = s.split("\t").join(Array(options.TabLen || 9).join(" "));
-          return pdfEscape(s, flags);
-        }
+    for (i = 0; i < 64; i += 4) {
+      md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
+    }
 
-        function transformTextToSpecialArray(text) {
-          //we don't want to destroy original text array, so cloning it
-          var sa = text.concat();
-          var da = [];
-          var len = sa.length;
-          var curDa;
-          //we do array.join('text that must not be PDFescaped")
-          //thus, pdfEscape each component separately
-          while (len--) {
-            curDa = sa.shift();
-            if (typeof curDa === "string") {
-              da.push(curDa);
-            } else {
-              if (Object.prototype.toString.call(text) === '[object Array]' && curDa.length === 1) {
-                da.push(curDa[0]);
-              } else {
-                da.push([curDa[0], curDa[1], curDa[2]]);
-              }
-            }
-          }
-          return da;
-        }
-
-        function processTextByFunction(text, processingFunction) {
-          var result;
-          if (typeof text === 'string') {
-            result = processingFunction(text)[0];
-          } else if (Object.prototype.toString.call(text) === '[object Array]') {
-            //we don't want to destroy original text array, so cloning it
-            var sa = text.concat();
-            var da = [];
-            var len = sa.length;
-            var curDa;
-            var tmpResult;
-            //we do array.join('text that must not be PDFescaped")
-            //thus, pdfEscape each component separately
-            while (len--) {
-              curDa = sa.shift();
-              if (typeof curDa === "string") {
-                da.push(processingFunction(curDa)[0]);
-              } else if (Object.prototype.toString.call(curDa) === '[object Array]' && curDa[0] === "string") {
-                tmpResult = processingFunction(curDa[0], curDa[1], curDa[2]);
-                da.push([tmpResult[0], tmpResult[1], tmpResult[2]]);
-              }
-            }
-            result = da;
-          }
-          return result;
-        }
+    return md5blks;
+  }
 
-        //backwardsCompatibility
-        var tmp;
+  var hex_chr = "0123456789abcdef".split("");
 
-        // Pre-August-2012 the order of arguments was function(x, y, text, flags)
-        // in effort to make all calls have similar signature like
-        //   function(data, coordinates... , miscellaneous)
-        // this method had its args flipped.
-        // code below allows backward compatibility with old arg order.
-        if (typeof text === 'number') {
-          tmp = y;
-          y = x;
-          x = text;
-          text = tmp;
-        }
+  function rhex(n) {
+    var s = "",
+        j = 0;
 
-        var flags = arguments[3];
-        var angle = arguments[4];
-        var align = arguments[5];
+    for (; j < 4; j++) {
+      s += hex_chr[n >> j * 8 + 4 & 0x0f] + hex_chr[n >> j * 8 & 0x0f];
+    }
 
-        if ((typeof flags === 'undefined' ? 'undefined' : _typeof(flags)) !== "object" || flags === null) {
-          if (typeof angle === 'string') {
-            align = angle;
-            angle = null;
-          }
-          if (typeof flags === 'string') {
-            align = flags;
-            flags = null;
-          }
-          if (typeof flags === 'number') {
-            angle = flags;
-            flags = null;
-          }
-          options = { flags: flags, angle: angle, align: align };
-        }
+    return s;
+  }
 
-        //Check if text is of type String
-        var textIsOfTypeString = false;
-        var tmpTextIsOfTypeString = true;
+  function hex(x) {
+    for (var i = 0; i < x.length; i++) {
+      x[i] = rhex(x[i]);
+    }
 
-        if (typeof text === 'string') {
-          textIsOfTypeString = true;
-        } else if (Object.prototype.toString.call(text) === '[object Array]') {
-          //we don't want to destroy original text array, so cloning it
-          var sa = text.concat();
-          var da = [];
-          var len = sa.length;
-          var curDa;
-          //we do array.join('text that must not be PDFescaped")
-          //thus, pdfEscape each component separately
-          while (len--) {
-            curDa = sa.shift();
-            if (typeof curDa !== "string" || Object.prototype.toString.call(curDa) === '[object Array]' && typeof curDa[0] !== "string") {
-              tmpTextIsOfTypeString = false;
-            }
-          }
-          textIsOfTypeString = tmpTextIsOfTypeString;
-        }
-        if (textIsOfTypeString === false) {
-          throw new Error('Type of text must be string or Array. "' + text + '" is not recognized.');
-        }
+    return x.join("");
+  } // Converts a 4-byte number to byte string
 
-        //Escaping 
-        var activeFontEncoding = fonts[activeFontKey].encoding;
 
-        if (activeFontEncoding === "WinAnsiEncoding" || activeFontEncoding === "StandardEncoding") {
-          text = processTextByFunction(text, function (text, posX, posY) {
-            return [ESC(text), posX, posY];
-          });
-        }
-        //If there are any newlines in text, we assume
-        //the user wanted to print multiple lines, so break the
-        //text up into an array. If the text is already an array,
-        //we assume the user knows what they are doing.
-        //Convert text into an array anyway to simplify
-        //later code.
+  function singleToByteString(n) {
+    return String.fromCharCode((n & 0xff) >> 0, (n & 0xff00) >> 8, (n & 0xff0000) >> 16, (n & 0xff000000) >> 24);
+  } // Converts an array of numbers to a byte string
 
-        if (typeof text === 'string') {
-          if (text.match(/[\r?\n]/)) {
-            text = text.split(/\r\n|\r|\n/g);
-          } else {
-            text = [text];
-          }
-        }
 
-        //multiline
-        var maxWidth = options.maxWidth || 0;
+  function toByteString(x) {
+    return x.map(singleToByteString).join("");
+  } // Returns the MD5 hash as a byte string
 
-        if (maxWidth > 0) {
-          if (typeof text === 'string') {
-            text = scope.splitTextToSize(text, maxWidth);
-          } else if (Object.prototype.toString.call(text) === '[object Array]') {
-            text = scope.splitTextToSize(text.join(" "), maxWidth);
-          }
-        }
 
-        //creating Payload-Object to make text byRef
-        var payload = {
-          text: text,
-          x: x,
-          y: y,
-          options: options,
-          mutex: {
-            pdfEscape: pdfEscape,
-            activeFontKey: activeFontKey,
-            fonts: fonts,
-            activeFontSize: activeFontSize
-          }
-        };
-        events.publish('preProcessText', payload);
-
-        text = payload.text;
-        options = payload.options;
-        //angle
-
-        var angle = options.angle;
-        var k = scope.internal.scaleFactor;
-        var curY = (scope.internal.pageSize.getHeight() - y) * k;
-        var transformationMatrix = [];
-
-        if (angle) {
-          angle *= Math.PI / 180;
-          var c = Math.cos(angle),
-              s = Math.sin(angle);
-          var f2 = function f2(number) {
-            return number.toFixed(2);
-          };
-          transformationMatrix = [f2(c), f2(s), f2(s * -1), f2(c)];
-        }
+  function md5Bin(s) {
+    return toByteString(md51(s));
+  } // Returns MD5 hash as a hex string
 
-        //charSpace
 
-        var charSpace = options.charSpace;
+  function md5(s) {
+    return hex(md51(s));
+  }
 
-        if (charSpace !== undefined) {
-          xtra += charSpace + " Tc\n";
-        }
+  var md5Check = md5("hello") != "5d41402abc4b2a76b9719d911017c592";
+
+  function add32(a, b) {
+    if (md5Check) {
+      /* if the md5Check does not match
+       the expected value, we're dealing
+       with an old browser and need
+       this function. */
+      var lsw = (a & 0xffff) + (b & 0xffff),
+          msw = (a >> 16) + (b >> 16) + (lsw >> 16);
+      return msw << 16 | lsw & 0xffff;
+    } else {
+      /* this function is much faster,
+      so if possible we use it. Some IEs
+      are the only ones I know of that
+      need the idiotic second function,
+      generated by an if clause.  */
+      return a + b & 0xffffffff;
+    }
+  }
 
-        //lang
+  /**
+   * @license
+   * FPDF is released under a permissive license: there is no usage restriction.
+   * You may embed it freely in your application (commercial or not), with or
+   * without modifications.
+   *
+   * Reference: http://www.fpdf.org/en/script/script37.php
+   */
+  function repeat(str, num) {
+    return new Array(num + 1).join(str);
+  }
+  /**
+   * Converts a byte string to a hex string
+   *
+   * @name rc4
+   * @function
+   * @param {string} key Byte string of encryption key
+   * @param {string} data Byte string of data to be encrypted
+   * @returns {string} Encrypted string
+   */
 
-        var lang = options.lang;
-        var tmpRenderingMode = -1;
-        var parmRenderingMode = options.renderingMode || options.stroke;
-        var pageContext = scope.internal.getCurrentPageInfo().pageContext;
 
-        switch (parmRenderingMode) {
-          case 0:
-          case false:
-          case 'fill':
-            tmpRenderingMode = 0;
-            break;
-          case 1:
-          case true:
-          case 'stroke':
-            tmpRenderingMode = 1;
-            break;
-          case 2:
-          case 'fillThenStroke':
-            tmpRenderingMode = 2;
-            break;
-          case 3:
-          case 'invisible':
-            tmpRenderingMode = 3;
-            break;
-          case 4:
-          case 'fillAndAddForClipping':
-            tmpRenderingMode = 4;
-            break;
-          case 5:
-          case 'strokeAndAddPathForClipping':
-            tmpRenderingMode = 5;
-            break;
-          case 6:
-          case 'fillThenStrokeAndAddToPathForClipping':
-            tmpRenderingMode = 6;
-            break;
-          case 7:
-          case 'addToPathForClipping':
-            tmpRenderingMode = 7;
-            break;
-        }
+  function rc4(key, data) {
+    var lastKey, lastState;
 
-        var usedRenderingMode = pageContext.usedRenderingMode || -1;
+    if (key !== lastKey) {
+      var k = repeat(key, (256 / key.length >> 0) + 1);
+      var state = [];
 
-        //if the coder wrote it explicitly to use a specific 
-        //renderingMode, then use it
-        if (tmpRenderingMode !== -1) {
-          xtra += tmpRenderingMode + " Tr\n";
-          //otherwise check if we used the rendering Mode already
-          //if so then set the rendering Mode...
-        } else if (usedRenderingMode !== -1) {
-          xtra += "0 Tr\n";
-        }
+      for (var i = 0; i < 256; i++) {
+        state[i] = i;
+      }
 
-        if (tmpRenderingMode !== -1) {
-          pageContext.usedRenderingMode = tmpRenderingMode;
-        }
+      var j = 0;
 
-        //align
+      for (var i = 0; i < 256; i++) {
+        var t = state[i];
+        j = (j + t + k.charCodeAt(i)) % 256;
+        state[i] = state[j];
+        state[j] = t;
+      }
 
-        var align = options.align || 'left';
-        var leading = activeFontSize * lineHeight;
-        var pageHeight = scope.internal.pageSize.getHeight();
-        var pageWidth = scope.internal.pageSize.getWidth();
-        var k = scope.internal.scaleFactor;
-        var activeFont = fonts[activeFontKey];
-        var charSpace = options.charSpace || activeCharSpace;
-        var maxWidth = options.maxWidth || 0;
+      lastKey = key;
+      lastState = state;
+    } else {
+      state = lastState;
+    }
 
-        var lineWidths;
-        var flags = {};
-        var wordSpacingPerLine = [];
+    var length = data.length;
+    var a = 0;
+    var b = 0;
+    var out = "";
+
+    for (var i = 0; i < length; i++) {
+      a = (a + 1) % 256;
+      t = state[a];
+      b = (b + t) % 256;
+      state[a] = state[b];
+      state[b] = t;
+      k = state[(state[a] + state[b]) % 256];
+      out += String.fromCharCode(data.charCodeAt(i) ^ k);
+    }
 
-        if (Object.prototype.toString.call(text) === '[object Array]') {
-          var da = transformTextToSpecialArray(text);
-          var newY;
-          var maxLineLength;
-          var lineWidths;
-          if (align !== "left") {
-            lineWidths = da.map(function (v) {
-              return scope.getStringUnitWidth(v, { font: activeFont, charSpace: charSpace, fontSize: activeFontSize }) * activeFontSize / k;
-            });
-          }
-          var maxLineLength = Math.max.apply(Math, lineWidths);
-          //The first line uses the "main" Td setting,
-          //and the subsequent lines are offset by the
-          //previous line's x coordinate.
-          var prevWidth = 0;
-          var delta;
-          var newX;
-          if (align === "right") {
-            x -= lineWidths[0];
-            text = [];
-            for (var i = 0, len = da.length; i < len; i++) {
-              delta = maxLineLength - lineWidths[i];
-              if (i === 0) {
-                newX = x * k;
-                newY = (pageHeight - y) * k;
-              } else {
-                newX = (prevWidth - lineWidths[i]) * k;
-                newY = -leading;
-              }
-              text.push([da[i], newX, newY]);
-              prevWidth = lineWidths[i];
-            }
-          } else if (align === "center") {
-            x -= lineWidths[0] / 2;
-            text = [];
-            for (var i = 0, len = da.length; i < len; i++) {
-              delta = (maxLineLength - lineWidths[i]) / 2;
-              if (i === 0) {
-                newX = x * k;
-                newY = (pageHeight - y) * k;
-              } else {
-                newX = (prevWidth - lineWidths[i]) / 2 * k;
-                newY = -leading;
-              }
-              text.push([da[i], newX, newY]);
-              prevWidth = lineWidths[i];
-            }
-          } else if (align === "left") {
-            text = [];
-            for (var i = 0, len = da.length; i < len; i++) {
-              newY = i === 0 ? (pageHeight - y) * k : -leading;
-              newX = i === 0 ? x * k : 0;
-              //text.push([da[i], newX, newY]);
-              text.push(da[i]);
-            }
-          } else if (align === "justify") {
-            text = [];
-            var maxWidth = maxWidth !== 0 ? maxWidth : pageWidth;
-
-            for (var i = 0, len = da.length; i < len; i++) {
-              newY = i === 0 ? (pageHeight - y) * k : -leading;
-              newX = i === 0 ? x * k : 0;
-              if (i < len - 1) {
-                wordSpacingPerLine.push(((maxWidth - lineWidths[i]) / (da[i].split(" ").length - 1) * k).toFixed(2));
-              }
-              text.push([da[i], newX, newY]);
-            }
-          } else {
-            throw new Error('Unrecognized alignment option, use "left", "center", "right" or "justify".');
-          }
-        }
+    return out;
+  }
 
-        //R2L
-        var doReversing = typeof options.R2L === "boolean" ? options.R2L : R2L;
-        if (doReversing === true) {
-          text = processTextByFunction(text, function (text, posX, posY) {
-            return [text.split("").reverse().join(""), posX, posY];
-          });
-        }
+  /**
+   * @license
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   * Author: Owen Leong (@owenl131)
+   * Date: 15 Oct 2020
+   * References:
+   * https://www.cs.cmu.edu/~dst/Adobe/Gallery/anon21jul01-pdf-encryption.txt
+   * https://github.com/foliojs/pdfkit/blob/master/lib/security.js
+   * http://www.fpdf.org/en/script/script37.php
+   */
+  var permissionOptions = {
+    print: 4,
+    modify: 8,
+    copy: 16,
+    "annot-forms": 32
+  };
+  /**
+   * Initializes encryption settings
+   *
+   * @name constructor
+   * @function
+   * @param {Array} permissions Permissions allowed for user, "print", "modify", "copy" and "annot-forms".
+   * @param {String} userPassword Permissions apply to this user. Leaving this empty means the document
+   *                              is not password protected but viewer has the above permissions.
+   * @param {String} ownerPassword Owner has full functionalities to the file.
+   * @param {String} fileId As hex string, should be same as the file ID in the trailer.
+   * @example
+   * var security = new PDFSecurity(["print"])
+   */
 
-        //creating Payload-Object to make text byRef
-        var payload = {
-          text: text,
-          x: x,
-          y: y,
-          options: options,
-          mutex: {
-            pdfEscape: pdfEscape,
-            activeFontKey: activeFontKey,
-            fonts: fonts,
-            activeFontSize: activeFontSize
-          }
-        };
-        events.publish('postProcessText', payload);
-
-        text = payload.text;
-        isHex = payload.mutex.isHex;
-
-        var da = transformTextToSpecialArray(text);
-
-        text = [];
-        var variant = 0;
-        var len = da.length;
-        var posX;
-        var posY;
-        var content;
-        var wordSpacing = '';
-
-        for (var i = 0; i < len; i++) {
-
-          wordSpacing = '';
-          if (Object.prototype.toString.call(da[i]) !== '[object Array]') {
-            posX = parseFloat(x * k).toFixed(2);
-            posY = parseFloat((pageHeight - y) * k).toFixed(2);
-            content = (isHex ? "<" : "(") + da[i] + (isHex ? ">" : ")");
-          } else if (Object.prototype.toString.call(da[i]) === '[object Array]') {
-            posX = parseFloat(da[i][1]).toFixed(2);
-            posY = parseFloat(da[i][2]).toFixed(2);
-            content = (isHex ? "<" : "(") + da[i][0] + (isHex ? ">" : ")");
-            variant = 1;
-          }
-          if (wordSpacingPerLine !== undefined && wordSpacingPerLine[i] !== undefined) {
-            wordSpacing = wordSpacingPerLine[i] + " Tw\n";
-          }
-          //TODO: Kind of a hack?
-          if (transformationMatrix.length !== 0 && i === 0) {
-            text.push(wordSpacing + transformationMatrix.join(" ") + " " + posX + " " + posY + " Tm\n" + content);
-          } else if (variant === 1 || variant === 0 && i === 0) {
-            text.push(wordSpacing + posX + " " + posY + " Td\n" + content);
-          } else {
-            text.push(wordSpacing + content);
-          }
-        }
-        if (variant === 0) {
-          text = text.join(" Tj\nT* ");
-        } else {
-          text = text.join(" Tj\n");
-        }
+  function PDFSecurity(permissions, userPassword, ownerPassword, fileId) {
+    this.v = 1; // algorithm 1, future work can add in more recent encryption schemes
 
-        text += " Tj\n";
+    this.r = 2; // revision 2
+    // set flags for what functionalities the user can access
 
-        var result = 'BT\n/' + activeFontKey + ' ' + activeFontSize + ' Tf\n' + // font face, style, size
-        (activeFontSize * lineHeight).toFixed(2) + ' TL\n' + // line spacing
-        textColor + '\n';
-        result += xtra;
-        result += text;
-        result += "ET";
+    var protection = 192;
+    permissions.forEach(function (perm) {
+      if (typeof permissionOptions.perm !== "undefined") {
+        throw new Error("Invalid permission: " + perm);
+      }
 
-        out(result);
-        return scope;
-      };
+      protection += permissionOptions[perm];
+    }); // padding is used to pad the passwords to 32 bytes, also is hashed and stored in the final PDF
 
-      /**
-       * Letter spacing method to print text with gaps
-       *
-       * @function
-       * @param {String|Array} text String to be added to the page.
-       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} spacing Spacing (in units declared at inception)
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name lstext
-       * @deprecated We'll be removing this function. It doesn't take character width into account.
-       */
-      API.lstext = function (text, x, y, spacing) {
-        console.warn('jsPDF.lstext is deprecated');
-        for (var i = 0, len = text.length; i < len; i++, x += spacing) {
-          this.text(text[i], x, y);
-        }return this;
-      };
+    this.padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF\xFA\x01\x08" + "\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C\xA9\xFE\x64\x53\x69\x7A";
+    var paddedUserPassword = (userPassword + this.padding).substr(0, 32);
+    var paddedOwnerPassword = (ownerPassword + this.padding).substr(0, 32);
+    this.O = this.processOwnerPassword(paddedUserPassword, paddedOwnerPassword);
+    this.P = -((protection ^ 255) + 1);
+    this.encryptionKey = md5Bin(paddedUserPassword + this.O + this.lsbFirstWord(this.P) + this.hexToBytes(fileId)).substr(0, 5);
+    this.U = rc4(this.encryptionKey, this.padding);
+  }
+  /**
+   * Breaks down a 4-byte number into its individual bytes, with the least significant bit first
+   *
+   * @name lsbFirstWord
+   * @function
+   * @param {number} data 32-bit number
+   * @returns {Array}
+   */
 
-      API.line = function (x1, y1, x2, y2) {
-        return this.lines([[x2 - x1, y2 - y1]], x1, y1);
-      };
 
-      API.clip = function () {
-        // By patrick-roberts, github.com/MrRio/jsPDF/issues/328
-        // Call .clip() after calling .rect() with a style argument of null
-        out('W'); // clip
-        out('S'); // stroke path; necessary for clip to work
-      };
+  PDFSecurity.prototype.lsbFirstWord = function (data) {
+    return String.fromCharCode(data >> 0 & 0xff, data >> 8 & 0xff, data >> 16 & 0xff, data >> 24 & 0xff);
+  };
+  /**
+   * Converts a byte string to a hex string
+   *
+   * @name toHexString
+   * @function
+   * @param {String} byteString Byte string
+   * @returns {String}
+   */
 
-      /**
-       * This fixes the previous function clip(). Perhaps the 'stroke path' hack was due to the missing 'n' instruction?
-       * We introduce the fixed version so as to not break API.
-       * @param fillRule
-       */
-      API.clip_fixed = function (fillRule) {
-        // Call .clip() after calling drawing ops with a style argument of null
-        // W is the PDF clipping op
-        if ('evenodd' === fillRule) {
-          out('W*');
-        } else {
-          out('W');
-        }
-        // End the path object without filling or stroking it.
-        // This operator is a path-painting no-op, used primarily for the side effect of changing the current clipping path
-        // (see Section 4.4.3, “Clipping Path Operators”)
-        out('n');
-      };
 
-      /**
-       * Adds series of curves (straight lines or cubic bezier curves) to canvas, starting at `x`, `y` coordinates.
-       * All data points in `lines` are relative to last line origin.
-       * `x`, `y` become x1,y1 for first line / curve in the set.
-       * For lines you only need to specify [x2, y2] - (ending point) vector against x1, y1 starting point.
-       * For bezier curves you need to specify [x2,y2,x3,y3,x4,y4] - vectors to control points 1, 2, ending point. All vectors are against the start of the curve - x1,y1.
-       *
-       * @example .lines([[2,2],[-2,2],[1,1,2,2,3,3],[2,1]], 212,110, 10) // line, line, bezier curve, line
-       * @param {Array} lines Array of *vector* shifts as pairs (lines) or sextets (cubic bezier curves).
-       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} scale (Defaults to [1.0,1.0]) x,y Scaling factor for all vectors. Elements can be any floating number Sub-one makes drawing smaller. Over-one grows the drawing. Negative flips the direction.
-       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
-       * @param {Boolean} closed If true, the path is closed with a straight line from the end of the last curve to the starting point.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name lines
-       */
-      API.lines = function (lines, x, y, scale, style, closed) {
-        var scalex, scaley, i, l, leg, x2, y2, x3, y3, x4, y4;
-
-        // Pre-August-2012 the order of arguments was function(x, y, lines, scale, style)
-        // in effort to make all calls have similar signature like
-        //   function(content, coordinateX, coordinateY , miscellaneous)
-        // this method had its args flipped.
-        // code below allows backward compatibility with old arg order.
-        if (typeof lines === 'number') {
-          tmp = y;
-          y = x;
-          x = lines;
-          lines = tmp;
-        }
-
-        scale = scale || [1, 1];
-
-        // starting point
-        out(f3(x * k) + ' ' + f3((pageHeight - y) * k) + ' m ');
-
-        scalex = scale[0];
-        scaley = scale[1];
-        l = lines.length;
-        //, x2, y2 // bezier only. In page default measurement "units", *after* scaling
-        //, x3, y3 // bezier only. In page default measurement "units", *after* scaling
-        // ending point for all, lines and bezier. . In page default measurement "units", *after* scaling
-        x4 = x; // last / ending point = starting point for first item.
-        y4 = y; // last / ending point = starting point for first item.
-
-        for (i = 0; i < l; i++) {
-          leg = lines[i];
-          if (leg.length === 2) {
-            // simple line
-            x4 = leg[0] * scalex + x4; // here last x4 was prior ending point
-            y4 = leg[1] * scaley + y4; // here last y4 was prior ending point
-            out(f3(x4 * k) + ' ' + f3((pageHeight - y4) * k) + ' l');
-          } else {
-            // bezier curve
-            x2 = leg[0] * scalex + x4; // here last x4 is prior ending point
-            y2 = leg[1] * scaley + y4; // here last y4 is prior ending point
-            x3 = leg[2] * scalex + x4; // here last x4 is prior ending point
-            y3 = leg[3] * scaley + y4; // here last y4 is prior ending point
-            x4 = leg[4] * scalex + x4; // here last x4 was prior ending point
-            y4 = leg[5] * scaley + y4; // here last y4 was prior ending point
-            out(f3(x2 * k) + ' ' + f3((pageHeight - y2) * k) + ' ' + f3(x3 * k) + ' ' + f3((pageHeight - y3) * k) + ' ' + f3(x4 * k) + ' ' + f3((pageHeight - y4) * k) + ' c');
-          }
-        }
+  PDFSecurity.prototype.toHexString = function (byteString) {
+    return byteString.split("").map(function (byte) {
+      return ("0" + (byte.charCodeAt(0) & 0xff).toString(16)).slice(-2);
+    }).join("");
+  };
+  /**
+   * Converts a hex string to a byte string
+   *
+   * @name hexToBytes
+   * @function
+   * @param {String} hex Hex string
+   * @returns {String}
+   */
 
-        if (closed) {
-          out(' h');
-        }
 
-        // stroking / filling / both the path
-        if (style !== null) {
-          out(getStyle(style));
-        }
-        return this;
-      };
+  PDFSecurity.prototype.hexToBytes = function (hex) {
+    for (var bytes = [], c = 0; c < hex.length; c += 2) {
+      bytes.push(String.fromCharCode(parseInt(hex.substr(c, 2), 16)));
+    }
 
-      /**
-       * Adds a rectangle to PDF
-       *
-       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} w Width (in units declared at inception of PDF document)
-       * @param {Number} h Height (in units declared at inception of PDF document)
-       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name rect
-       */
-      API.rect = function (x, y, w, h, style) {
-        var op = getStyle(style);
-        out([f2(x * k), f2((pageHeight - y) * k), f2(w * k), f2(-h * k), 're'].join(' '));
+    return bytes.join("");
+  };
+  /**
+   * Computes the 'O' field in the encryption dictionary
+   *
+   * @name processOwnerPassword
+   * @function
+   * @param {String} paddedUserPassword Byte string of padded user password
+   * @param {String} paddedOwnerPassword Byte string of padded owner password
+   * @returns {String}
+   */
 
-        if (style !== null) {
-          out(getStyle(style));
-        }
 
-        return this;
-      };
+  PDFSecurity.prototype.processOwnerPassword = function (paddedUserPassword, paddedOwnerPassword) {
+    var key = md5Bin(paddedOwnerPassword).substr(0, 5);
+    return rc4(key, paddedUserPassword);
+  };
+  /**
+   * Returns an encryptor function which can take in a byte string and returns the encrypted version
+   *
+   * @name encryptor
+   * @function
+   * @param {number} objectId
+   * @param {number} generation Not sure what this is for, you can set it to 0
+   * @returns {Function}
+   * @example
+   * out("stream");
+   * encryptor = security.encryptor(object.id, 0);
+   * out(encryptor(data));
+   * out("endstream");
+   */
 
-      /**
-       * Adds a triangle to PDF
-       *
-       * @param {Number} x1 Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y1 Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} x2 Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y2 Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} x3 Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y3 Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name triangle
-       */
-      API.triangle = function (x1, y1, x2, y2, x3, y3, style) {
-        this.lines([[x2 - x1, y2 - y1], // vector to point 2
-        [x3 - x2, y3 - y2], // vector to point 3
-        [x1 - x3, y1 - y3] // closing vector back to point 1
-        ], x1, y1, // start of path
-        [1, 1], style, true);
-        return this;
-      };
 
-      /**
-       * Adds a rectangle with rounded corners to PDF
-       *
-       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} w Width (in units declared at inception of PDF document)
-       * @param {Number} h Height (in units declared at inception of PDF document)
-       * @param {Number} rx Radius along x axis (in units declared at inception of PDF document)
-       * @param {Number} rx Radius along y axis (in units declared at inception of PDF document)
-       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name roundedRect
-       */
-      API.roundedRect = function (x, y, w, h, rx, ry, style) {
-        var MyArc = 4 / 3 * (Math.SQRT2 - 1);
-        this.lines([[w - 2 * rx, 0], [rx * MyArc, 0, rx, ry - ry * MyArc, rx, ry], [0, h - 2 * ry], [0, ry * MyArc, -(rx * MyArc), ry, -rx, ry], [-w + 2 * rx, 0], [-(rx * MyArc), 0, -rx, -(ry * MyArc), -rx, -ry], [0, -h + 2 * ry], [0, -(ry * MyArc), rx * MyArc, -ry, rx, -ry]], x + rx, y, // start of path
-        [1, 1], style);
-        return this;
-      };
+  PDFSecurity.prototype.encryptor = function (objectId, generation) {
+    var key = md5Bin(this.encryptionKey + String.fromCharCode(objectId & 0xff, objectId >> 8 & 0xff, objectId >> 16 & 0xff, generation & 0xff, generation >> 8 & 0xff)).substr(0, 10);
+    return function (data) {
+      return rc4(key, data);
+    };
+  };
 
-      /**
-       * Adds an ellipse to PDF
-       *
-       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} rx Radius along x axis (in units declared at inception of PDF document)
-       * @param {Number} rx Radius along y axis (in units declared at inception of PDF document)
-       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name ellipse
-       */
-      API.ellipse = function (x, y, rx, ry, style) {
-        var lx = 4 / 3 * (Math.SQRT2 - 1) * rx,
-            ly = 4 / 3 * (Math.SQRT2 - 1) * ry;
+  /**
+   * Convert string to `PDF Name Object`.
+   * Detail: PDF Reference 1.3 - Chapter 3.2.4 Name Object
+   * @param str
+   */
+  function toPDFName(str) {
+    // eslint-disable-next-line no-control-regex
+    if (/[^\u0000-\u00ff]/.test(str)) {
+      // non ascii string
+      throw new Error("Invalid PDF Name Object: " + str + ", Only accept ASCII characters.");
+    }
 
-        out([f2((x + rx) * k), f2((pageHeight - y) * k), 'm', f2((x + rx) * k), f2((pageHeight - (y - ly)) * k), f2((x + lx) * k), f2((pageHeight - (y - ry)) * k), f2(x * k), f2((pageHeight - (y - ry)) * k), 'c'].join(' '));
-        out([f2((x - lx) * k), f2((pageHeight - (y - ry)) * k), f2((x - rx) * k), f2((pageHeight - (y - ly)) * k), f2((x - rx) * k), f2((pageHeight - y) * k), 'c'].join(' '));
-        out([f2((x - rx) * k), f2((pageHeight - (y + ly)) * k), f2((x - lx) * k), f2((pageHeight - (y + ry)) * k), f2(x * k), f2((pageHeight - (y + ry)) * k), 'c'].join(' '));
-        out([f2((x + lx) * k), f2((pageHeight - (y + ry)) * k), f2((x + rx) * k), f2((pageHeight - (y + ly)) * k), f2((x + rx) * k), f2((pageHeight - y) * k), 'c'].join(' '));
+    var result = "",
+        strLength = str.length;
+
+    for (var i = 0; i < strLength; i++) {
+      var charCode = str.charCodeAt(i);
+
+      if (charCode < 0x21 || charCode === 0x23
+      /* # */
+      || charCode === 0x25
+      /* % */
+      || charCode === 0x28
+      /* ( */
+      || charCode === 0x29
+      /* ) */
+      || charCode === 0x2f
+      /* / */
+      || charCode === 0x3c
+      /* < */
+      || charCode === 0x3e
+      /* > */
+      || charCode === 0x5b
+      /* [ */
+      || charCode === 0x5d
+      /* ] */
+      || charCode === 0x7b
+      /* { */
+      || charCode === 0x7d
+      /* } */
+      || charCode > 0x7e) {
+        // Char    CharCode    hexStr   paddingHexStr    Result
+        // "\t"    9           9        09               #09
+        // " "     32          20       20               #20
+        // "©"     169         a9       a9               #a9
+        var hexStr = charCode.toString(16),
+            paddingHexStr = ("0" + hexStr).slice(-2);
+        result += "#" + paddingHexStr;
+      } else {
+        // Other ASCII printable characters between 0x21 <= X <= 0x7e
+        result += str[i];
+      }
+    }
 
-        if (style !== null) {
-          out(getStyle(style));
-        }
+    return result;
+  }
 
-        return this;
-      };
+  /**
+   * jsPDF's Internal PubSub Implementation.
+   * Backward compatible rewritten on 2014 by
+   * Diego Casorran, https://github.com/diegocr
+   *
+   * @class
+   * @name PubSub
+   * @ignore
+   */
 
-      /**
-       * Adds an circle to PDF
-       *
-       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} r Radius (in units declared at inception of PDF document)
-       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name circle
-       */
-      API.circle = function (x, y, r, style) {
-        return this.ellipse(x, y, r, r, style);
-      };
+  function PubSub(context) {
+    if (_typeof(context) !== "object") {
+      throw new Error("Invalid Context passed to initialize PubSub (jsPDF-module)");
+    }
 
-      /**
-       * Adds a properties to the PDF document
-       *
-       * @param {Object} A property_name-to-property_value object structure.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setProperties
-       */
-      API.setProperties = function (properties) {
-        // copying only those properties we can render.
-        for (var property in documentProperties) {
-          if (documentProperties.hasOwnProperty(property) && properties[property]) {
-            documentProperties[property] = properties[property];
+    var topics = {};
+
+    this.subscribe = function (topic, callback, once) {
+      once = once || false;
+
+      if (typeof topic !== "string" || typeof callback !== "function" || typeof once !== "boolean") {
+        throw new Error("Invalid arguments passed to PubSub.subscribe (jsPDF-module)");
+      }
+
+      if (!topics.hasOwnProperty(topic)) {
+        topics[topic] = {};
+      }
+
+      var token = Math.random().toString(35);
+      topics[topic][token] = [callback, !!once];
+      return token;
+    };
+
+    this.unsubscribe = function (token) {
+      for (var topic in topics) {
+        if (topics[topic][token]) {
+          delete topics[topic][token];
+
+          if (Object.keys(topics[topic]).length === 0) {
+            delete topics[topic];
           }
+
+          return true;
         }
-        return this;
-      };
+      }
 
-      /**
-       * Sets font size for upcoming text elements.
-       *
-       * @param {Number} size Font size in points.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setFontSize
-       */
-      API.setFontSize = function (size) {
-        activeFontSize = size;
-        return this;
-      };
+      return false;
+    };
 
-      /**
-       * Sets text font face, variant for upcoming text elements.
-       * See output of jsPDF.getFontList() for possible font names, styles.
-       *
-       * @param {String} fontName Font name or family. Example: "times"
-       * @param {String} fontStyle Font style or variant. Example: "italic"
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setFont
-       */
-      API.setFont = function (fontName, fontStyle) {
-        activeFontKey = _getFont(fontName, fontStyle);
-        // if font is not found, the above line blows up and we never go further
-        return this;
-      };
+    this.publish = function (topic) {
+      if (topics.hasOwnProperty(topic)) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            tokens = [];
 
-      /**
-       * Switches font style or variant for upcoming text elements,
-       * while keeping the font face or family same.
-       * See output of jsPDF.getFontList() for possible font names, styles.
-       *
-       * @param {String} style Font style or variant. Example: "italic"
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setFontStyle
-       */
-      API.setFontStyle = API.setFontType = function (style) {
-        activeFontKey = _getFont(undefined, style);
-        // if font is not found, the above line blows up and we never go further
-        return this;
-      };
+        for (var token in topics[topic]) {
+          var sub = topics[topic][token];
 
-      /**
-       * Returns an object - a tree of fontName to fontStyle relationships available to
-       * active PDF document.
-       *
-       * @public
-       * @function
-       * @returns {Object} Like {'times':['normal', 'italic', ... ], 'arial':['normal', 'bold', ... ], ... }
-       * @methodOf jsPDF#
-       * @name getFontList
-       */
-      API.getFontList = function () {
-        // TODO: iterate over fonts array or return copy of fontmap instead in case more are ever added.
-        var list = {},
-            fontName,
-            fontStyle,
-            tmp;
-
-        for (fontName in fontmap) {
-          if (fontmap.hasOwnProperty(fontName)) {
-            list[fontName] = tmp = [];
-            for (fontStyle in fontmap[fontName]) {
-              if (fontmap[fontName].hasOwnProperty(fontStyle)) {
-                tmp.push(fontStyle);
-              }
+          try {
+            sub[0].apply(context, args);
+          } catch (ex) {
+            if (globalObject.console) {
+              console.error("jsPDF PubSub Error", ex.message, ex);
             }
           }
+
+          if (sub[1]) tokens.push(token);
         }
 
-        return list;
-      };
+        if (tokens.length) tokens.forEach(this.unsubscribe);
+      }
+    };
 
-      /**
-       * Add a custom font.
-       *
-       * @param {String} Postscript name of the Font.  Example: "Menlo-Regular"
-       * @param {String} Name of font-family from @font-face definition.  Example: "Menlo Regular"
-       * @param {String} Font style.  Example: "normal"
-       * @function
-       * @returns the {fontKey} (same as the internal method)
-       * @methodOf jsPDF#
-       * @name addFont
-       */
-      API.addFont = function (postScriptName, fontName, fontStyle, encoding) {
-        encoding = encoding || 'Identity-H';
-        addFont(postScriptName, fontName, fontStyle, encoding);
-      };
+    this.getTopics = function () {
+      return topics;
+    };
+  }
 
-      /**
-       * Sets line width for upcoming lines.
-       *
-       * @param {Number} width Line width (in units declared at inception of PDF document)
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setLineWidth
-       */
-      API.setLineWidth = function (width) {
-        out((width * k).toFixed(2) + ' w');
-        return this;
-      };
+  function GState(parameters) {
+    if (!(this instanceof GState)) {
+      return new GState(parameters);
+    }
+    /**
+     * @name GState#opacity
+     * @type {any}
+     */
 
-      /**
-       * Sets the stroke color for upcoming elements.
-       *
-       * Depending on the number of arguments given, Gray, RGB, or CMYK
-       * color space is implied.
-       *
-       * When only ch1 is given, "Gray" color space is implied and it
-       * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
-       * if values are communicated as String types, or in range from 0 (black)
-       * to 255 (white) if communicated as Number type.
-       * The RGB-like 0-255 range is provided for backward compatibility.
-       *
-       * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
-       * value must be in the range from 0.00 (minimum intensity) to to 1.00
-       * (max intensity) if values are communicated as String types, or
-       * from 0 (min intensity) to to 255 (max intensity) if values are communicated
-       * as Number types.
-       * The RGB-like 0-255 range is provided for backward compatibility.
-       *
-       * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
-       * value must be a in the range from 0.00 (0% concentration) to to
-       * 1.00 (100% concentration)
-       *
-       * Because JavaScript treats fixed point numbers badly (rounds to
-       * floating point nearest to binary representation) it is highly advised to
-       * communicate the fractional numbers as String types, not JavaScript Number type.
-       *
-       * @param {Number|String} ch1 Color channel value or {String} ch1 color value in hexadecimal, example: '#FFFFFF'
-       * @param {Number|String} ch2 Color channel value
-       * @param {Number|String} ch3 Color channel value
-       * @param {Number|String} ch4 Color channel value
-       *
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setDrawColor
-       */
-      API.setDrawColor = function (ch1, ch2, ch3, ch4) {
-        var options = {
-          "ch1": ch1,
-          "ch2": ch2,
-          "ch3": ch3,
-          "ch4": ch4,
-          "pdfColorType": "draw",
-          "precision": 2
-        };
+    /**
+     * @name GState#stroke-opacity
+     * @type {any}
+     */
 
-        out(generateColorString(options));
-        return this;
-      };
 
-      /**
-       * Sets the fill color for upcoming elements.
-       *
-       * Depending on the number of arguments given, Gray, RGB, or CMYK
-       * color space is implied.
-       *
-       * When only ch1 is given, "Gray" color space is implied and it
-       * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
-       * if values are communicated as String types, or in range from 0 (black)
-       * to 255 (white) if communicated as Number type.
-       * The RGB-like 0-255 range is provided for backward compatibility.
-       *
-       * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
-       * value must be in the range from 0.00 (minimum intensity) to to 1.00
-       * (max intensity) if values are communicated as String types, or
-       * from 0 (min intensity) to to 255 (max intensity) if values are communicated
-       * as Number types.
-       * The RGB-like 0-255 range is provided for backward compatibility.
-       *
-       * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
-       * value must be a in the range from 0.00 (0% concentration) to to
-       * 1.00 (100% concentration)
-       *
-       * Because JavaScript treats fixed point numbers badly (rounds to
-       * floating point nearest to binary representation) it is highly advised to
-       * communicate the fractional numbers as String types, not JavaScript Number type.
-       *
-       * @param {Number|String} ch1 Color channel value or {String} ch1 color value in hexadecimal, example: '#FFFFFF'
-       * @param {Number|String} ch2 Color channel value
-       * @param {Number|String} ch3 Color channel value
-       * @param {Number|String} ch4 Color channel value
-       *
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setFillColor
-       */
+    var supported = "opacity,stroke-opacity".split(",");
 
-      API.setFillColor = function (ch1, ch2, ch3, ch4) {
-        var options = {
-          "ch1": ch1,
-          "ch2": ch2,
-          "ch3": ch3,
-          "ch4": ch4,
-          "pdfColorType": "fill",
-          "precision": 2
-        };
+    for (var p in parameters) {
+      if (parameters.hasOwnProperty(p) && supported.indexOf(p) >= 0) {
+        this[p] = parameters[p];
+      }
+    }
+    /**
+     * @name GState#id
+     * @type {string}
+     */
 
-        out(generateColorString(options));
-        return this;
-      };
 
-      /**
-       * Sets the text color for upcoming elements.
-       *
-       * Depending on the number of arguments given, Gray, RGB, or CMYK
-       * color space is implied.
-       *
-       * When only ch1 is given, "Gray" color space is implied and it
-       * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
-       * if values are communicated as String types, or in range from 0 (black)
-       * to 255 (white) if communicated as Number type.
-       * The RGB-like 0-255 range is provided for backward compatibility.
-       *
-       * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
-       * value must be in the range from 0.00 (minimum intensity) to to 1.00
-       * (max intensity) if values are communicated as String types, or
-       * from 0 (min intensity) to to 255 (max intensity) if values are communicated
-       * as Number types.
-       * The RGB-like 0-255 range is provided for backward compatibility.
-       *
-       * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
-       * value must be a in the range from 0.00 (0% concentration) to to
-       * 1.00 (100% concentration)
-       *
-       * Because JavaScript treats fixed point numbers badly (rounds to
-       * floating point nearest to binary representation) it is highly advised to
-       * communicate the fractional numbers as String types, not JavaScript Number type.
-       *
-       * @param {Number|String} ch1 Color channel value or {String} ch1 color value in hexadecimal, example: '#FFFFFF'
-       * @param {Number|String} ch2 Color channel value
-       * @param {Number|String} ch3 Color channel value
-       * @param {Number|String} ch4 Color channel value
-       *
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setTextColor
-       */
-      API.setTextColor = function (ch1, ch2, ch3, ch4) {
-        var options = {
-          "ch1": ch1,
-          "ch2": ch2,
-          "ch3": ch3,
-          "ch4": ch4,
-          "pdfColorType": "text",
-          "precision": 3
-        };
-        textColor = generateColorString(options);
+    this.id = ""; // set by addGState()
 
-        return this;
-      };
+    /**
+     * @name GState#objectNumber
+     * @type {number}
+     */
 
-      /**
-       * Initializes the default character set that the user wants to be global..
-       *
-       * @param {Number} charSpace
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setCharSpace
-       */
+    this.objectNumber = -1; // will be set by putGState()
+  }
 
-      API.setCharSpace = function (charSpace) {
-        activeCharSpace = charSpace;
-        return this;
-      };
+  GState.prototype.equals = function equals(other) {
+    var ignore = "id,objectNumber,equals";
+    var p;
+    if (!other || _typeof(other) !== _typeof(this)) return false;
+    var count = 0;
+
+    for (p in this) {
+      if (ignore.indexOf(p) >= 0) continue;
+      if (this.hasOwnProperty(p) && !other.hasOwnProperty(p)) return false;
+      if (this[p] !== other[p]) return false;
+      count++;
+    }
 
-      /**
-       * Initializes the default character set that the user wants to be global..
-       *
-       * @param {Boolean} boolean
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setR2L
-       */
+    for (p in other) {
+      if (other.hasOwnProperty(p) && ignore.indexOf(p) < 0) count--;
+    }
 
-      API.setR2L = function (boolean) {
-        R2L = boolean;
-        return this;
-      };
+    return count === 0;
+  };
 
-      /**
-       * Is an Object providing a mapping from human-readable to
-       * integer flag values designating the varieties of line cap
-       * and join styles.
-       *
-       * @returns {Object}
-       * @fieldOf jsPDF#
-       * @name CapJoinStyles
-       */
-      API.CapJoinStyles = {
-        0: 0,
-        'butt': 0,
-        'but': 0,
-        'miter': 0,
-        1: 1,
-        'round': 1,
-        'rounded': 1,
-        'circle': 1,
-        2: 2,
-        'projecting': 2,
-        'project': 2,
-        'square': 2,
-        'bevel': 2
-      };
+  function Pattern(gState, matrix) {
+    this.gState = gState;
+    this.matrix = matrix;
+    this.id = ""; // set by addPattern()
 
-      /**
-       * Sets the line cap styles
-       * See {jsPDF.CapJoinStyles} for variants
-       *
-       * @param {String|Number} style A string or number identifying the type of line cap
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setLineCap
-       */
-      API.setLineCap = function (style) {
-        var id = this.CapJoinStyles[style];
-        if (id === undefined) {
-          throw new Error("Line cap style of '" + style + "' is not recognized. See or extend .CapJoinStyles property for valid styles");
-        }
-        lineCapID = id;
-        out(id + ' J');
+    this.objectNumber = -1; // will be set by putPattern()
+  }
 
-        return this;
-      };
+  function ShadingPattern(type, coords, colors, gState, matrix) {
+    if (!(this instanceof ShadingPattern)) {
+      return new ShadingPattern(type, coords, colors, gState, matrix);
+    } // see putPattern() for information how they are realized
 
-      /**
-       * Sets the line join styles
-       * See {jsPDF.CapJoinStyles} for variants
-       *
-       * @param {String|Number} style A string or number identifying the type of line join
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setLineJoin
-       */
-      API.setLineJoin = function (style) {
-        var id = this.CapJoinStyles[style];
-        if (id === undefined) {
-          throw new Error("Line join style of '" + style + "' is not recognized. See or extend .CapJoinStyles property for valid styles");
-        }
-        lineJoinID = id;
-        out(id + ' j');
 
-        return this;
-      };
+    this.type = type === "axial" ? 2 : 3;
+    this.coords = coords;
+    this.colors = colors;
+    Pattern.call(this, gState, matrix);
+  }
 
-      // Output is both an internal (for plugins) and external function
-      API.output = _output;
+  function TilingPattern(boundingBox, xStep, yStep, gState, matrix) {
+    if (!(this instanceof TilingPattern)) {
+      return new TilingPattern(boundingBox, xStep, yStep, gState, matrix);
+    }
 
-      /**
-       * Saves as PDF document. An alias of jsPDF.output('save', 'filename.pdf')
-       * @param  {String} filename The filename including extension.
-       *
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name save
-       */
-      API.save = function (filename) {
-        API.output('save', filename);
-      };
+    this.boundingBox = boundingBox;
+    this.xStep = xStep;
+    this.yStep = yStep;
+    this.stream = ""; // set by endTilingPattern();
 
-      // applying plugins (more methods) ON TOP of built-in API.
-      // this is intentional as we allow plugins to override
-      // built-ins
-      for (var plugin in jsPDF.API) {
-        if (jsPDF.API.hasOwnProperty(plugin)) {
-          if (plugin === 'events' && jsPDF.API.events.length) {
-            (function (events, newEvents) {
-
-              // jsPDF.API.events is a JS Array of Arrays
-              // where each Array is a pair of event name, handler
-              // Events were added by plugins to the jsPDF instantiator.
-              // These are always added to the new instance and some ran
-              // during instantiation.
-              var eventname, handler_and_args, i;
-
-              for (i = newEvents.length - 1; i !== -1; i--) {
-                // subscribe takes 3 args: 'topic', function, runonce_flag
-                // if undefined, runonce is false.
-                // users can attach callback directly,
-                // or they can attach an array with [callback, runonce_flag]
-                // that's what the "apply" magic is for below.
-                eventname = newEvents[i][0];
-                handler_and_args = newEvents[i][1];
-                events.subscribe.apply(events, [eventname].concat(typeof handler_and_args === 'function' ? [handler_and_args] : handler_and_args));
-              }
-            })(events, jsPDF.API.events);
-          } else {
-            API[plugin] = jsPDF.API[plugin];
-          }
-        }
-      }
+    this.cloneIndex = 0;
+    Pattern.call(this, gState, matrix);
+  }
+  /**
+   * Creates new jsPDF document object instance.
+   * @name jsPDF
+   * @class
+   * @param {Object} [options] - Collection of settings initializing the jsPDF-instance
+   * @param {string} [options.orientation=portrait] - Orientation of the first page. Possible values are "portrait" or "landscape" (or shortcuts "p" or "l").<br />
+   * @param {string} [options.unit=mm] Measurement unit (base unit) to be used when coordinates are specified.<br />
+   * Possible values are "pt" (points), "mm", "cm", "in", "px", "pc", "em" or "ex". Note that in order to get the correct scaling for "px"
+   * units, you need to enable the hotfix "px_scaling" by setting options.hotfixes = ["px_scaling"].
+   * @param {string/Array} [options.format=a4] The format of the first page. Can be:<ul><li>a0 - a10</li><li>b0 - b10</li><li>c0 - c10</li><li>dl</li><li>letter</li><li>government-letter</li><li>legal</li><li>junior-legal</li><li>ledger</li><li>tabloid</li><li>credit-card</li></ul><br />
+   * Default is "a4". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array, e.g. [595.28, 841.89]
+   * @param {boolean} [options.putOnlyUsedFonts=false] Only put fonts into the PDF, which were used.
+   * @param {boolean} [options.compress=false] Compress the generated PDF.
+   * @param {number} [options.precision=16] Precision of the element-positions.
+   * @param {number} [options.userUnit=1.0] Not to be confused with the base unit. Please inform yourself before you use it.
+   * @param {string[]} [options.hotfixes] An array of strings to enable hotfixes such as correct pixel scaling.
+   * @param {Object} [options.encryption]
+   * @param {string} [options.encryption.userPassword] Password for the user bound by the given permissions list.
+   * @param {string} [options.encryption.ownerPassword] Both userPassword and ownerPassword should be set for proper authentication.
+   * @param {string[]} [options.encryption.userPermissions] Array of permissions "print", "modify", "copy", "annot-forms", accessible by the user.
+   * @param {number|"smart"} [options.floatPrecision=16]
+   * @returns {jsPDF} jsPDF-instance
+   * @description
+   * ```
+   * {
+   *  orientation: 'p',
+   *  unit: 'mm',
+   *  format: 'a4',
+   *  putOnlyUsedFonts:true,
+   *  floatPrecision: 16 // or "smart", default is 16
+   * }
+   * ```
+   *
+   * @constructor
+   */
 
-      //////////////////////////////////////////////////////
-      // continuing initialization of jsPDF Document object
-      //////////////////////////////////////////////////////
-      // Add the first page automatically
-      addFonts();
-      activeFontKey = 'F1';
-      _addPage(format, orientation);
 
-      events.publish('initialized');
-      return API;
-    }
+  function jsPDF(options) {
+    var orientation = typeof arguments[0] === "string" ? arguments[0] : "p";
+    var unit = arguments[1];
+    var format = arguments[2];
+    var compressPdf = arguments[3];
+    var filters = [];
+    var userUnit = 1.0;
+    var precision;
+    var floatPrecision = 16;
+    var defaultPathOperation = "S";
+    var encryptionOptions = null;
+    options = options || {};
+
+    if (_typeof(options) === "object") {
+      orientation = options.orientation;
+      unit = options.unit || unit;
+      format = options.format || format;
+      compressPdf = options.compress || options.compressPdf || compressPdf;
+      encryptionOptions = options.encryption || null;
+
+      if (encryptionOptions !== null) {
+        encryptionOptions.userPassword = encryptionOptions.userPassword || "";
+        encryptionOptions.ownerPassword = encryptionOptions.ownerPassword || "";
+        encryptionOptions.userPermissions = encryptionOptions.userPermissions || [];
+      }
 
-    /**
-     * jsPDF.API is a STATIC property of jsPDF class.
-     * jsPDF.API is an object you can add methods and properties to.
-     * The methods / properties you add will show up in new jsPDF objects.
-     *
-     * One property is prepopulated. It is the 'events' Object. Plugin authors can add topics,
-     * callbacks to this object. These will be reassigned to all new instances of jsPDF.
-     * Examples:
-     * jsPDF.API.events['initialized'] = function(){ 'this' is API object }
-     * jsPDF.API.events['addFont'] = function(added_font_object){ 'this' is API object }
-     *
-     * @static
-     * @public
-     * @memberOf jsPDF
-     * @name API
-     *
-     * @example
-     * jsPDF.API.mymethod = function(){
-     *   // 'this' will be ref to internal API object. see jsPDF source
-     *   // , so you can refer to built-in methods like so:
-     *   //     this.line(....)
-     *   //     this.text(....)
-     * }
-     * var pdfdoc = new jsPDF()
-     * pdfdoc.mymethod() // <- !!!!!!
-     */
-    jsPDF.API = {
-      events: []
-    };
-    jsPDF.version = "0.0.0";
+      userUnit = typeof options.userUnit === "number" ? Math.abs(options.userUnit) : 1.0;
 
-    if (typeof define === 'function' && define.amd) {
-      define('jsPDF', function () {
-        return jsPDF;
-      });
-    } else if (typeof module !== 'undefined' && module.exports) {
-      module.exports = jsPDF;
-      module.exports.jsPDF = jsPDF;
-    } else {
-      global.jsPDF = jsPDF;
-    }
-    return jsPDF;
-  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global || Function('return typeof this === "object" && this.content')() || Function('return this')());
-  // `self` is undefined in Firefox for Android content script context
-  // while `this` is nsIContentFrameMessageManager
-  // with an attribute `content` that corresponds to the window
-  
+      if (typeof options.precision !== "undefined") {
+        precision = options.precision;
+      }
 
-  /**
-   * jsPDF AcroForm Plugin Copyright (c) 2016 Alexander Weidt,
-   * https://github.com/BiggA94
-   * 
-   * Licensed under the MIT License. http://opensource.org/licenses/mit-license
-   */
+      if (typeof options.floatPrecision !== "undefined") {
+        floatPrecision = options.floatPrecision;
+      }
 
-  (function (jsPDFAPI, globalObj) {
+      defaultPathOperation = options.defaultPathOperation || "S";
+    }
 
-    var scope;
-    var pageHeight;
-    var scaleFactor = 1;
-    var inherit = function inherit(child, parent) {
-      child.prototype = Object.create(parent.prototype);
-      child.prototype.constructor = child;
-    };
-    var scale = function scale(x) {
-      return x * (scaleFactor / 1); // 1 = (96 / 72)
+    filters = options.filters || (compressPdf === true ? ["FlateEncode"] : filters);
+    unit = unit || "mm";
+    orientation = ("" + (orientation || "P")).toLowerCase();
+    var putOnlyUsedFonts = options.putOnlyUsedFonts || false;
+    var usedFonts = {};
+    var API = {
+      internal: {},
+      __private__: {}
     };
+    API.__private__.PubSub = PubSub;
+    var pdfVersion = "1.3";
 
-    var createFormXObject = function createFormXObject(formObject) {
-      var xobj = new AcroFormXObject();
-      var height = AcroFormAppearance.internal.getHeight(formObject) || 0;
-      var width = AcroFormAppearance.internal.getWidth(formObject) || 0;
-      xobj.BBox = [0, 0, width.toFixed(2), height.toFixed(2)];
-      return xobj;
+    var getPdfVersion = API.__private__.getPdfVersion = function () {
+      return pdfVersion;
     };
 
-    var setBitPosition = function setBitPosition(variable, position, value) {
-      variable = variable || 0;
-      value = value || 1;
+    API.__private__.setPdfVersion = function (value) {
+      pdfVersion = value;
+    }; // Size in pt of various paper formats
+
+
+    var pageFormats = {
+      a0: [2383.94, 3370.39],
+      a1: [1683.78, 2383.94],
+      a2: [1190.55, 1683.78],
+      a3: [841.89, 1190.55],
+      a4: [595.28, 841.89],
+      a5: [419.53, 595.28],
+      a6: [297.64, 419.53],
+      a7: [209.76, 297.64],
+      a8: [147.4, 209.76],
+      a9: [104.88, 147.4],
+      a10: [73.7, 104.88],
+      b0: [2834.65, 4008.19],
+      b1: [2004.09, 2834.65],
+      b2: [1417.32, 2004.09],
+      b3: [1000.63, 1417.32],
+      b4: [708.66, 1000.63],
+      b5: [498.9, 708.66],
+      b6: [354.33, 498.9],
+      b7: [249.45, 354.33],
+      b8: [175.75, 249.45],
+      b9: [124.72, 175.75],
+      b10: [87.87, 124.72],
+      c0: [2599.37, 3676.54],
+      c1: [1836.85, 2599.37],
+      c2: [1298.27, 1836.85],
+      c3: [918.43, 1298.27],
+      c4: [649.13, 918.43],
+      c5: [459.21, 649.13],
+      c6: [323.15, 459.21],
+      c7: [229.61, 323.15],
+      c8: [161.57, 229.61],
+      c9: [113.39, 161.57],
+      c10: [79.37, 113.39],
+      dl: [311.81, 623.62],
+      letter: [612, 792],
+      "government-letter": [576, 756],
+      legal: [612, 1008],
+      "junior-legal": [576, 360],
+      ledger: [1224, 792],
+      tabloid: [792, 1224],
+      "credit-card": [153, 243]
+    };
 
-      var bitMask = 1;
-      bitMask = bitMask << position - 1;
+    API.__private__.getPageFormats = function () {
+      return pageFormats;
+    };
 
-      if (value == 1) {
-        // Set the Bit to 1
-        var variable = variable | bitMask;
-      } else {
-        // Set the Bit to 0
-        var variable = variable & ~bitMask;
-      }
+    var getPageFormat = API.__private__.getPageFormat = function (value) {
+      return pageFormats[value];
+    };
 
-      return variable;
+    format = format || "a4";
+    var ApiMode = {
+      COMPAT: "compat",
+      ADVANCED: "advanced"
     };
+    var apiMode = ApiMode.COMPAT;
+
+    function advancedAPI() {
+      // prepend global change of basis matrix
+      // (Now, instead of converting every coordinate to the pdf coordinate system, we apply a matrix
+      // that does this job for us (however, texts, images and similar objects must be drawn bottom up))
+      this.saveGraphicsState();
+      out(new Matrix(scaleFactor, 0, 0, -scaleFactor, 0, getPageHeight() * scaleFactor).toString() + " cm");
+      this.setFontSize(this.getFontSize() / scaleFactor); // The default in MrRio's implementation is "S" (stroke), whereas the default in the yWorks implementation
+      // was "n" (none). Although this has nothing to do with transforms, we should use the API switch here.
+
+      defaultPathOperation = "n";
+      apiMode = ApiMode.ADVANCED;
+    }
 
+    function compatAPI() {
+      this.restoreGraphicsState();
+      defaultPathOperation = "S";
+      apiMode = ApiMode.COMPAT;
+    }
     /**
-    * Calculating the Ff entry:
-    * 
-    * The Ff entry contains flags, that have to be set bitwise In the Following
-    * the number in the Comment is the BitPosition
-    */
-    var calculateFlagsOnOptions = function calculateFlagsOnOptions(flags, opts, PDFVersion) {
-      var PDFVersion = PDFVersion || 1.3;
-      var flags = flags || 0;
+     * @function combineFontStyleAndFontWeight
+     * @param {string} fontStyle Fontstyle or variant. Example: "italic".
+     * @param {number | string} fontWeight Weight of the Font. Example: "normal" | 400
+     * @returns {string}
+     * @private
+     */
 
-      // 1, readOnly
-      if (opts.readOnly == true) {
-        flags = setBitPosition(flags, 1);
-      }
 
-      // 2, required
-      if (opts.required == true) {
-        flags = setBitPosition(flags, 2);
+    var combineFontStyleAndFontWeight = API.__private__.combineFontStyleAndFontWeight = function (fontStyle, fontWeight) {
+      if (fontStyle == "bold" && fontWeight == "normal" || fontStyle == "bold" && fontWeight == 400 || fontStyle == "normal" && fontWeight == "italic" || fontStyle == "bold" && fontWeight == "italic") {
+        throw new Error("Invalid Combination of fontweight and fontstyle");
       }
 
-      // 4, noExport
-      if (opts.noExport == true) {
-        flags = setBitPosition(flags, 3);
+      if (fontWeight) {
+        fontStyle = fontWeight == 400 || fontWeight === "normal" ? fontStyle === "italic" ? "italic" : "normal" : (fontWeight == 700 || fontWeight === "bold") && fontStyle === "normal" ? "bold" : (fontWeight == 700 ? "bold" : fontWeight) + "" + fontStyle;
       }
 
-      // 13, multiline
-      if (opts.multiline == true) {
-        flags = setBitPosition(flags, 13);
-      }
+      return fontStyle;
+    };
+    /**
+     * @callback ApiSwitchBody
+     * @param {jsPDF} pdf
+     */
 
-      // 14, Password
-      if (opts.password) {
-        flags = setBitPosition(flags, 14);
-      }
+    /**
+     * For compatibility reasons jsPDF offers two API modes which differ in the way they convert between the the usual
+     * screen coordinates and the PDF coordinate system.
+     *   - "compat": Offers full compatibility across all plugins but does not allow arbitrary transforms
+     *   - "advanced": Allows arbitrary transforms and more advanced features like pattern fills. Some plugins might
+     *     not support this mode, though.
+     * Initial mode is "compat".
+     *
+     * You can either provide a callback to the body argument, which means that jsPDF will automatically switch back to
+     * the original API mode afterwards; or you can omit the callback and switch back manually using {@link compatAPI}.
+     *
+     * Note, that the calls to {@link saveGraphicsState} and {@link restoreGraphicsState} need to be balanced within the
+     * callback or between calls of this method and its counterpart {@link compatAPI}. Calls to {@link beginFormObject}
+     * or {@link beginTilingPattern} need to be closed by their counterparts before switching back to "compat" API mode.
+     *
+     * @param {ApiSwitchBody=} body When provided, this callback will be called after the API mode has been switched.
+     * The API mode will be switched back automatically afterwards.
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name advancedAPI
+     */
 
-      // 15, NoToggleToOff (Radio buttons only
-      if (opts.noToggleToOff) {
-        flags = setBitPosition(flags, 15);
-      }
 
-      // 16, Radio
-      if (opts.radio) {
-        flags = setBitPosition(flags, 16);
-      }
+    API.advancedAPI = function (body) {
+      var doSwitch = apiMode === ApiMode.COMPAT;
 
-      // 17, Pushbutton
-      if (opts.pushbutton) {
-        flags = setBitPosition(flags, 17);
+      if (doSwitch) {
+        advancedAPI.call(this);
       }
 
-      // 18, Combo (If not set, the choiceField is a listBox!!)
-      if (opts.combo) {
-        flags = setBitPosition(flags, 18);
+      if (typeof body !== "function") {
+        return this;
       }
 
-      // 19, Edit
-      if (opts.edit) {
-        flags = setBitPosition(flags, 19);
-      }
+      body(this);
 
-      // 20, Sort
-      if (opts.sort) {
-        flags = setBitPosition(flags, 20);
+      if (doSwitch) {
+        compatAPI.call(this);
       }
 
-      // 21, FileSelect, PDF 1.4...
-      if (opts.fileSelect && PDFVersion >= 1.4) {
-        flags = setBitPosition(flags, 21);
-      }
+      return this;
+    };
+    /**
+     * Switches to "compat" API mode. See {@link advancedAPI} for more details.
+     *
+     * @param {ApiSwitchBody=} body When provided, this callback will be called after the API mode has been switched.
+     * The API mode will be switched back automatically afterwards.
+     * @return {jsPDF}
+     * @memberof jsPDF#
+     * @name compatApi
+     */
 
-      // 22, MultiSelect (PDF 1.4)
-      if (opts.multiSelect && PDFVersion >= 1.4) {
-        flags = setBitPosition(flags, 22);
-      }
 
-      // 23, DoNotSpellCheck (PDF 1.4)
-      if (opts.doNotSpellCheck && PDFVersion >= 1.4) {
-        flags = setBitPosition(flags, 23);
+    API.compatAPI = function (body) {
+      var doSwitch = apiMode === ApiMode.ADVANCED;
+
+      if (doSwitch) {
+        compatAPI.call(this);
       }
 
-      // 24, DoNotScroll (PDF 1.4)
-      if (opts.doNotScroll == true && PDFVersion >= 1.4) {
-        flags = setBitPosition(flags, 24);
+      if (typeof body !== "function") {
+        return this;
       }
 
-      // 25, RichText (PDF 1.4)
-      if (opts.richText && PDFVersion >= 1.4) {
-        flags = setBitPosition(flags, 25);
+      body(this);
+
+      if (doSwitch) {
+        advancedAPI.call(this);
       }
 
-      return flags;
+      return this;
     };
+    /**
+     * @return {boolean} True iff the current API mode is "advanced". See {@link advancedAPI}.
+     * @memberof jsPDF#
+     * @name isAdvancedAPI
+     */
 
-    var calculateCoordinates = function calculateCoordinates(args) {
-      var x = args[0];
-      var y = args[1];
-      var w = args[2];
-      var h = args[3];
 
-      var coordinates = {};
+    API.isAdvancedAPI = function () {
+      return apiMode === ApiMode.ADVANCED;
+    };
 
-      if (Array.isArray(x)) {
-        x[0] = scale(x[0]);
-        x[1] = scale(x[1]);
-        x[2] = scale(x[2]);
-        x[3] = scale(x[3]);
-      } else {
-        x = scale(x);
-        y = scale(y);
-        w = scale(w);
-        h = scale(h);
+    var advancedApiModeTrap = function advancedApiModeTrap(methodName) {
+      if (apiMode !== ApiMode.ADVANCED) {
+        throw new Error(methodName + " is only available in 'advanced' API mode. " + "You need to call advancedAPI() first.");
       }
-      coordinates.lowerLeft_X = x || 0;
-      coordinates.lowerLeft_Y = scale(pageHeight) - y - h || 0;
-      coordinates.upperRight_X = x + w || 0;
-      coordinates.upperRight_Y = scale(pageHeight) - y || 0;
-
-      return [coordinates.lowerLeft_X.toFixed(2), coordinates.lowerLeft_Y.toFixed(2), coordinates.upperRight_X.toFixed(2), coordinates.upperRight_Y.toFixed(2)];
     };
 
-    var calculateAppearanceStream = function calculateAppearanceStream(formObject) {
-      if (formObject.appearanceStreamContent) {
-        // If appearanceStream is already set, use it
-        return formObject.appearanceStreamContent;
-      }
+    var roundToPrecision = API.roundToPrecision = API.__private__.roundToPrecision = function (number, parmPrecision) {
+      var tmpPrecision = precision || parmPrecision;
 
-      if (!formObject.V && !formObject.DV) {
-        return;
+      if (isNaN(number) || isNaN(tmpPrecision)) {
+        throw new Error("Invalid argument passed to jsPDF.roundToPrecision");
       }
 
-      // else calculate it
-
-      var stream = [];
-      var text = formObject.V || formObject.DV;
-      var calcRes = calculateX(formObject, text);
-
-      stream.push('/Tx BMC');
-      stream.push('q');
-      stream.push('/F1 ' + calcRes.fontSize.toFixed(2) + ' Tf');
-      stream.push('1 0 0 1 0 0 Tm'); // Text Matrix
+      return number.toFixed(tmpPrecision).replace(/0+$/, "");
+    }; // high precision float
 
-      stream.push('BT'); // Begin Text
-      stream.push(calcRes.text);
 
-      stream.push('ET'); // End Text
-      stream.push('Q');
-      stream.push('EMC');
+    var hpf;
 
-      var appearanceStreamContent = new createFormXObject(formObject);
-      appearanceStreamContent.stream = stream.join("\n");
-
-      return appearanceStreamContent;
-    };
+    if (typeof floatPrecision === "number") {
+      hpf = API.hpf = API.__private__.hpf = function (number) {
+        if (isNaN(number)) {
+          throw new Error("Invalid argument passed to jsPDF.hpf");
+        }
 
-    var calculateX = function calculateX(formObject, text, font, maxFontSize) {
-      var maxFontSize = maxFontSize || 12;
-      var font = font || "helvetica";
-      var returnValue = {
-        text: "",
-        fontSize: ""
+        return roundToPrecision(number, floatPrecision);
       };
-      // Remove Brackets
-      text = text.substr(0, 1) == '(' ? text.substr(1) : text;
-      text = text.substr(text.length - 1) == ')' ? text.substr(0, text.length - 1) : text;
-      // split into array of words
-      var textSplit = text.split(' ');
-      var fontSize = maxFontSize; // The Starting fontSize (The Maximum)
-      var lineSpacing = 2;
-      var borderPadding = 2;
-
-      var height = AcroFormAppearance.internal.getHeight(formObject) || 0;
-      height = height < 0 ? -height : height;
-      var width = AcroFormAppearance.internal.getWidth(formObject) || 0;
-      width = width < 0 ? -width : width;
-
-      var isSmallerThanWidth = function isSmallerThanWidth(i, lastLine, fontSize) {
-        if (i + 1 < textSplit.length) {
-          var tmp = lastLine + " " + textSplit[i + 1];
-          var TextWidth = calculateFontSpace(tmp, fontSize + "px", font).width;
-          var FieldWidth = width - 2 * borderPadding;
-          return TextWidth <= FieldWidth;
+    } else if (floatPrecision === "smart") {
+      hpf = API.hpf = API.__private__.hpf = function (number) {
+        if (isNaN(number)) {
+          throw new Error("Invalid argument passed to jsPDF.hpf");
+        }
+
+        if (number > -1 && number < 1) {
+          return roundToPrecision(number, 16);
         } else {
-          return false;
+          return roundToPrecision(number, 5);
         }
       };
-
-      fontSize++;
-      FontSize: while (true) {
-        var text = "";
-        fontSize--;
-        var textHeight = calculateFontSpace("3", fontSize + "px", font).height;
-        var startY = formObject.multiline ? height - fontSize : (height - textHeight) / 2;
-        startY += lineSpacing;
-        var startX = -borderPadding;
-
-        var lastY = startY;
-        var firstWordInLine = 0,
-            lastWordInLine = 0;
-        var lastLength = 0;
-        if (fontSize <= 0) {
-          // In case, the Text doesn't fit at all
-          fontSize = 12;
-          text = "(...) Tj\n";
-          text += "% Width of Text: " + calculateFontSpace(text, "1px").width + ", FieldWidth:" + width + "\n";
-          break;
+    } else {
+      hpf = API.hpf = API.__private__.hpf = function (number) {
+        if (isNaN(number)) {
+          throw new Error("Invalid argument passed to jsPDF.hpf");
         }
 
-        lastLength = calculateFontSpace(textSplit[0] + " ", fontSize + "px", font).width;
-
-        var lastLine = "";
-        var lineCount = 0;
-        Line: for (var i in textSplit) {
-          lastLine += textSplit[i] + " ";
-          // Remove last blank
-          lastLine = lastLine.substr(lastLine.length - 1) == " " ? lastLine.substr(0, lastLine.length - 1) : lastLine;
-          var key = parseInt(i);
-          lastLength = calculateFontSpace(lastLine + " ", fontSize + "px", font).width;
-          var nextLineIsSmaller = isSmallerThanWidth(key, lastLine, fontSize);
-          var isLastWord = i >= textSplit.length - 1;
-          if (nextLineIsSmaller && !isLastWord) {
-            lastLine += " ";
-            continue; // Line
-          } else if (!nextLineIsSmaller && !isLastWord) {
-            if (!formObject.multiline) {
-              continue FontSize;
-            } else {
-              if ((textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {
-                // If the Text is higher than the
-                // FieldObject
-                continue FontSize;
-              }
-              lastWordInLine = key;
-              // go on
-            }
-          } else if (isLastWord) {
-            lastWordInLine = key;
-          } else {
-            if (formObject.multiline && (textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {
-              // If the Text is higher than the FieldObject
-              continue FontSize;
-            }
-          }
-
-          var line = '';
-
-          for (var x = firstWordInLine; x <= lastWordInLine; x++) {
-            line += textSplit[x] + ' ';
-          }
-
-          // Remove last blank
-          line = line.substr(line.length - 1) == " " ? line.substr(0, line.length - 1) : line;
-          // lastLength -= blankSpace.width;
-          lastLength = calculateFontSpace(line, fontSize + "px", font).width;
-
-          // Calculate startX
-          switch (formObject.Q) {
-            case 2:
-              // Right justified
-              startX = width - lastLength - borderPadding;
-              break;
-            case 1:
-              // Q = 1 := Text-Alignment: Center
-              startX = (width - lastLength) / 2;
-              break;
-            case 0:
-            default:
-              startX = borderPadding;
-              break;
-          }
-          text += startX.toFixed(2) + ' ' + lastY.toFixed(2) + ' Td\n';
-          text += '(' + line + ') Tj\n';
-          // reset X in PDF
-          text += -startX.toFixed(2) + ' 0 Td\n';
-
-          // After a Line, adjust y position
-          lastY = -(fontSize + lineSpacing);
-
-          // Reset for next iteration step
-          lastLength = 0;
-          firstWordInLine = lastWordInLine + 1;
-          lineCount++;
+        return roundToPrecision(number, 16);
+      };
+    }
 
-          lastLine = "";
-          continue Line;
-        }
-        break;
+    var f2 = API.f2 = API.__private__.f2 = function (number) {
+      if (isNaN(number)) {
+        throw new Error("Invalid argument passed to jsPDF.f2");
       }
 
-      returnValue.text = text;
-      returnValue.fontSize = fontSize;
-
-      return returnValue;
+      return roundToPrecision(number, 2);
     };
 
-    /**
-    * small workaround for calculating the TextMetric approximately
-    * 
-    * @param text
-    * @param fontsize
-    * @returns {TextMetrics} (Has Height and Width)
-    */
-    var calculateFontSpace = function calculateFontSpace(text, fontSize, fontType) {
-      fontType = fontType || "helvetica";
-      var font = scope.internal.getFont(fontType);
-      var width = scope.getStringUnitWidth(text, { font: font, fontSize: parseFloat(fontSize), charSpace: 0 }) * parseFloat(fontSize);
-      var height = scope.getStringUnitWidth("3", { font: font, fontSize: parseFloat(fontSize), charSpace: 0 }) * parseFloat(fontSize) * 1.5;
-      var result = { height: height, width: width };
-      return result;
-    };
+    var f3 = API.__private__.f3 = function (number) {
+      if (isNaN(number)) {
+        throw new Error("Invalid argument passed to jsPDF.f3");
+      }
 
-    var acroformPluginTemplate = {
-      fields: [],
-      xForms: [],
-      /**
-      * acroFormDictionaryRoot contains information about the AcroForm
-      * Dictionary 0: The Event-Token, the AcroFormDictionaryCallback has
-      * 1: The Object ID of the Root
-      */
-      acroFormDictionaryRoot: null,
-      /**
-      * After the PDF gets evaluated, the reference to the root has to be
-      * reset, this indicates, whether the root has already been printed
-      * out
-      */
-      printedOut: false,
-      internal: null,
-      isInitialized: false
+      return roundToPrecision(number, 3);
     };
 
-    var annotReferenceCallback = function annotReferenceCallback() {
-      for (var i in scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields) {
-        var formObject = scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields[i];
-        // add Annot Reference!
-        if (formObject.hasAnnotation) {
-          // If theres an Annotation Widget in the Form Object, put the
-          // Reference in the /Annot array
-          createAnnotationReference.call(scope, formObject);
-        }
+    var scale = API.scale = API.__private__.scale = function (number) {
+      if (isNaN(number)) {
+        throw new Error("Invalid argument passed to jsPDF.scale");
       }
-    };
 
-    var putForm = function putForm(formObject) {
-      if (scope.internal.acroformPlugin.printedOut) {
-        scope.internal.acroformPlugin.printedOut = false;
-        scope.internal.acroformPlugin.acroFormDictionaryRoot = null;
-      }
-      if (!scope.internal.acroformPlugin.acroFormDictionaryRoot) {
-        initializeAcroForm.call(scope);
+      if (apiMode === ApiMode.COMPAT) {
+        return number * scaleFactor;
+      } else if (apiMode === ApiMode.ADVANCED) {
+        return number;
       }
-      scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields.push(formObject);
-    };
-    /**
-    * Create the Reference to the widgetAnnotation, so that it gets referenced
-    * in the Annot[] int the+ (Requires the Annotation Plugin)
-    */
-    var createAnnotationReference = function createAnnotationReference(object) {
-      var options = {
-        type: 'reference',
-        object: object
-      };
-      scope.annotationPlugin.annotations[scope.internal.getPageInfo(object.page).pageNumber].push(options);
     };
 
-    // Callbacks
-
-    var putCatalogCallback = function putCatalogCallback() {
-      // Put reference to AcroForm to DocumentCatalog
-      if (typeof scope.internal.acroformPlugin.acroFormDictionaryRoot != 'undefined') {
-        // for safety, shouldn't normally be the case
-        scope.internal.write('/AcroForm ' + scope.internal.acroformPlugin.acroFormDictionaryRoot.objId + ' ' + 0 + ' R');
-      } else {
-        console.log('Root missing...');
+    var transformY = function transformY(y) {
+      if (apiMode === ApiMode.COMPAT) {
+        return getPageHeight() - y;
+      } else if (apiMode === ApiMode.ADVANCED) {
+        return y;
       }
     };
 
-    /**
-    * Adds /Acroform X 0 R to Document Catalog, and creates the AcroForm
-    * Dictionary
-    */
-    var AcroFormDictionaryCallback = function AcroFormDictionaryCallback() {
-      // Remove event
-      scope.internal.events.unsubscribe(scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID);
-      delete scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID;
-      scope.internal.acroformPlugin.printedOut = true;
+    var transformScaleY = function transformScaleY(y) {
+      return scale(transformY(y));
     };
-
     /**
-    * Creates the single Fields and writes them into the Document
-    * 
-    * If fieldArray is set, use the fields that are inside it instead of the
-    * fields from the AcroRoot (for the FormXObjects...)
-    */
-    var createFieldCallback = function createFieldCallback(fieldArray) {
-      var standardFields = !fieldArray;
+     * @name setPrecision
+     * @memberof jsPDF#
+     * @function
+     * @instance
+     * @param {string} precision
+     * @returns {jsPDF}
+     */
 
-      if (!fieldArray) {
-        // in case there is no fieldArray specified, we want to print out
-        // the Fields of the AcroForm
-        // Print out Root
-        scope.internal.newObjectDeferredBegin(scope.internal.acroformPlugin.acroFormDictionaryRoot.objId);
-        scope.internal.out(scope.internal.acroformPlugin.acroFormDictionaryRoot.getString());
-      }
 
-      var fieldArray = fieldArray || scope.internal.acroformPlugin.acroFormDictionaryRoot.Kids;
+    API.__private__.setPrecision = API.setPrecision = function (value) {
+      if (typeof parseInt(value, 10) === "number") {
+        precision = parseInt(value, 10);
+      }
+    };
 
-      for (var i in fieldArray) {
-        var form = fieldArray[i];
+    var fileId = "00000000000000000000000000000000";
 
-        var oldRect = form.Rect;
+    var getFileId = API.__private__.getFileId = function () {
+      return fileId;
+    };
 
-        if (form.Rect) {
-          form.Rect = calculateCoordinates.call(this, form.Rect);
-        }
+    var setFileId = API.__private__.setFileId = function (value) {
+      if (typeof value !== "undefined" && /^[a-fA-F0-9]{32}$/.test(value)) {
+        fileId = value.toUpperCase();
+      } else {
+        fileId = fileId.split("").map(function () {
+          return "ABCDEF0123456789".charAt(Math.floor(Math.random() * 16));
+        }).join("");
+      }
 
-        // Start Writing the Object
-        scope.internal.newObjectDeferredBegin(form.objId);
+      if (encryptionOptions !== null) {
+        encryption = new PDFSecurity(encryptionOptions.userPermissions, encryptionOptions.userPassword, encryptionOptions.ownerPassword, fileId);
+      }
 
-        var content = form.objId + " 0 obj\n<<\n";
+      return fileId;
+    };
+    /**
+     * @name setFileId
+     * @memberof jsPDF#
+     * @function
+     * @instance
+     * @param {string} value GUID.
+     * @returns {jsPDF}
+     */
 
-        if ((typeof form === 'undefined' ? 'undefined' : _typeof(form)) === "object" && typeof form.getContent === "function") {
-          content += form.getContent();
-        }
 
-        form.Rect = oldRect;
+    API.setFileId = function (value) {
+      setFileId(value);
+      return this;
+    };
+    /**
+     * @name getFileId
+     * @memberof jsPDF#
+     * @function
+     * @instance
+     *
+     * @returns {string} GUID.
+     */
 
-        if (form.hasAppearanceStream && !form.appearanceStreamContent) {
-          // Calculate Appearance
-          var appearance = calculateAppearanceStream.call(this, form);
-          content += "/AP << /N " + appearance + " >>\n";
 
-          scope.internal.acroformPlugin.xForms.push(appearance);
-        }
+    API.getFileId = function () {
+      return getFileId();
+    };
 
-        // Assume AppearanceStreamContent is a Array with N,R,D (at least
-        // one of them!)
-        if (form.appearanceStreamContent) {
-          content += "/AP << ";
-          // Iterate over N,R and D
-          for (var k in form.appearanceStreamContent) {
-            var value = form.appearanceStreamContent[k];
-            content += "/" + k + " ";
-            content += "<< ";
-            if (Object.keys(value).length >= 1 || Array.isArray(value)) {
-              // appearanceStream is an Array or Object!
-              for (var i in value) {
-                var obj = value[i];
-                if (typeof obj === 'function') {
-                  // if Function is referenced, call it in order
-                  // to get the FormXObject
-                  obj = obj.call(this, form);
-                }
-                content += "/" + i + " " + obj + " ";
+    var creationDate;
 
-                // In case the XForm is already used, e.g. OffState
-                // of CheckBoxes, don't add it
-                if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj);
-              }
-            } else {
-              var obj = value;
-              if (typeof obj === 'function') {
-                // if Function is referenced, call it in order to
-                // get the FormXObject
-                obj = obj.call(this, form);
-              }
-              content += "/" + i + " " + obj + " \n";
-              if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj);
-            }
-            content += " >>\n";
-          }
+    var convertDateToPDFDate = API.__private__.convertDateToPDFDate = function (parmDate) {
+      var result = "";
+      var tzoffset = parmDate.getTimezoneOffset(),
+          tzsign = tzoffset < 0 ? "+" : "-",
+          tzhour = Math.floor(Math.abs(tzoffset / 60)),
+          tzmin = Math.abs(tzoffset % 60),
+          timeZoneString = [tzsign, padd2(tzhour), "'", padd2(tzmin), "'"].join("");
+      result = ["D:", parmDate.getFullYear(), padd2(parmDate.getMonth() + 1), padd2(parmDate.getDate()), padd2(parmDate.getHours()), padd2(parmDate.getMinutes()), padd2(parmDate.getSeconds()), timeZoneString].join("");
+      return result;
+    };
 
-          // appearance stream is a normal Object..
-          content += ">>\n";
-        }
+    var convertPDFDateToDate = API.__private__.convertPDFDateToDate = function (parmPDFDate) {
+      var year = parseInt(parmPDFDate.substr(2, 4), 10);
+      var month = parseInt(parmPDFDate.substr(6, 2), 10) - 1;
+      var date = parseInt(parmPDFDate.substr(8, 2), 10);
+      var hour = parseInt(parmPDFDate.substr(10, 2), 10);
+      var minutes = parseInt(parmPDFDate.substr(12, 2), 10);
+      var seconds = parseInt(parmPDFDate.substr(14, 2), 10); // var timeZoneHour = parseInt(parmPDFDate.substr(16, 2), 10);
+      // var timeZoneMinutes = parseInt(parmPDFDate.substr(20, 2), 10);
+
+      var resultingDate = new Date(year, month, date, hour, minutes, seconds, 0);
+      return resultingDate;
+    };
 
-        content += ">>\nendobj\n";
+    var setCreationDate = API.__private__.setCreationDate = function (date) {
+      var tmpCreationDateString;
+      var regexPDFCreationDate = /^D:(20[0-2][0-9]|203[0-7]|19[7-9][0-9])(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])(0[0-9]|1[0-9]|2[0-3])(0[0-9]|[1-5][0-9])(0[0-9]|[1-5][0-9])(\+0[0-9]|\+1[0-4]|-0[0-9]|-1[0-1])'(0[0-9]|[1-5][0-9])'?$/;
 
-        scope.internal.out(content);
+      if (typeof date === "undefined") {
+        date = new Date();
       }
-      if (standardFields) {
-        createXFormObjectCallback.call(this, scope.internal.acroformPlugin.xForms);
+
+      if (date instanceof Date) {
+        tmpCreationDateString = convertDateToPDFDate(date);
+      } else if (regexPDFCreationDate.test(date)) {
+        tmpCreationDateString = date;
+      } else {
+        throw new Error("Invalid argument passed to jsPDF.setCreationDate");
       }
-    };
 
-    var createXFormObjectCallback = function createXFormObjectCallback(fieldArray) {
-      for (var i in fieldArray) {
-        var key = i;
-        var form = fieldArray[i];
-        // Start Writing the Object
-        scope.internal.newObjectDeferredBegin(form && form.objId);
+      creationDate = tmpCreationDateString;
+      return creationDate;
+    };
 
-        var content = "";
-        if ((typeof form === 'undefined' ? 'undefined' : _typeof(form)) === "object" && typeof form.getString === "function") {
-          content = form.getString();
-        }
-        scope.internal.out(content);
+    var getCreationDate = API.__private__.getCreationDate = function (type) {
+      var result = creationDate;
 
-        delete fieldArray[key];
+      if (type === "jsDate") {
+        result = convertPDFDateToDate(creationDate);
       }
-    };
-
-    var initializeAcroForm = function initializeAcroForm() {
-      if (this.internal !== undefined && (this.internal.acroformPlugin === undefined || this.internal.acroformPlugin.isInitialized === false)) {
 
-        scope = this;
+      return result;
+    };
+    /**
+     * @name setCreationDate
+     * @memberof jsPDF#
+     * @function
+     * @instance
+     * @param {Object} date
+     * @returns {jsPDF}
+     */
 
-        AcroFormField.FieldNum = 0;
-        this.internal.acroformPlugin = JSON.parse(JSON.stringify(acroformPluginTemplate));
-        if (this.internal.acroformPlugin.acroFormDictionaryRoot) {
-          // return;
-          throw new Error("Exception while creating AcroformDictionary");
-        }
-        scaleFactor = scope.internal.scaleFactor;
-        pageHeight = scope.internal.pageSize.getHeight();
 
-        // The Object Number of the AcroForm Dictionary
-        scope.internal.acroformPlugin.acroFormDictionaryRoot = new AcroFormDictionary();
+    API.setCreationDate = function (date) {
+      setCreationDate(date);
+      return this;
+    };
+    /**
+     * @name getCreationDate
+     * @memberof jsPDF#
+     * @function
+     * @instance
+     * @param {Object} type
+     * @returns {Object}
+     */
 
-        // add Callback for creating the AcroForm Dictionary
-        scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID = scope.internal.events.subscribe('postPutResources', AcroFormDictionaryCallback);
 
-        scope.internal.events.subscribe('buildDocument', annotReferenceCallback); // buildDocument
+    API.getCreationDate = function (type) {
+      return getCreationDate(type);
+    };
 
-        // Register event, that is triggered when the DocumentCatalog is
-        // written, in order to add /AcroForm
-        scope.internal.events.subscribe('putCatalog', putCatalogCallback);
+    var padd2 = API.__private__.padd2 = function (number) {
+      return ("0" + parseInt(number)).slice(-2);
+    };
 
-        // Register event, that creates all Fields
-        scope.internal.events.subscribe('postPutPages', createFieldCallback);
+    var padd2Hex = API.__private__.padd2Hex = function (hexString) {
+      hexString = hexString.toString();
+      return ("00" + hexString).substr(hexString.length);
+    };
 
-        scope.internal.acroformPlugin.isInitialized = true;
-      }
+    var objectNumber = 0; // 'n' Current object number
+
+    var offsets = []; // List of offsets. Activated and reset by buildDocument(). Pupulated by various calls buildDocument makes.
+
+    var content = [];
+    var contentLength = 0;
+    var additionalObjects = [];
+    var pages = [];
+    var currentPage;
+    var hasCustomDestination = false;
+    var outputDestination = content;
+
+    var resetDocument = function resetDocument() {
+      //reset fields relevant for objectNumber generation and xref.
+      objectNumber = 0;
+      contentLength = 0;
+      content = [];
+      offsets = [];
+      additionalObjects = [];
+      rootDictionaryObjId = newObjectDeferred();
+      resourceDictionaryObjId = newObjectDeferred();
     };
 
-    var arrayToPdfArray = function arrayToPdfArray(array) {
-      if (Array.isArray(array)) {
-        var content = ' [';
-        for (var i in array) {
-          var element = array[i].toString();
-          content += element;
-          content += i < array.length - 1 ? ' ' : '';
-        }
-        content += ']';
+    API.__private__.setCustomOutputDestination = function (destination) {
+      hasCustomDestination = true;
+      outputDestination = destination;
+    };
 
-        return content;
+    var setOutputDestination = function setOutputDestination(destination) {
+      if (!hasCustomDestination) {
+        outputDestination = destination;
       }
     };
 
-    var toPdfString = function toPdfString(string) {
-      string = string || "";
+    API.__private__.resetCustomOutputDestination = function () {
+      hasCustomDestination = false;
+      outputDestination = content;
+    };
 
-      // put Bracket at the Beginning of the String
-      if (string.indexOf('(') !== 0) {
-        string = '(' + string;
-      }
+    var out = API.__private__.out = function (string) {
+      string = string.toString();
+      contentLength += string.length + 1;
+      outputDestination.push(string);
+      return outputDestination;
+    };
 
-      if (string.substring(string.length - 1) != ')') {
-        string += ')';
-      }
-      return string;
+    var write = API.__private__.write = function (value) {
+      return out(arguments.length === 1 ? value.toString() : Array.prototype.join.call(arguments, " "));
     };
 
-    // ##########################
-    // Classes
-    // ##########################
+    var getArrayBuffer = API.__private__.getArrayBuffer = function (data) {
+      var len = data.length,
+          ab = new ArrayBuffer(len),
+          u8 = new Uint8Array(ab);
 
-    var AcroFormPDFObject = function AcroFormPDFObject() {
-      // The Object ID in the PDF Object Model
-      // todo
-      var _objId;
-      Object.defineProperty(this, 'objId', {
-        get: function get$$1() {
-          if (!_objId) {
-            _objId = scope.internal.newObjectDeferred();
-          }
-          if (!_objId) {
-            console.log("Couldn't create Object ID");
-          }
-          return _objId;
-        },
-        configurable: false
-      });
-    };
+      while (len--) {
+        u8[len] = data.charCodeAt(len);
+      }
 
-    AcroFormPDFObject.prototype.toString = function () {
-      return this.objId + " 0 R";
+      return ab;
     };
 
-    AcroFormPDFObject.prototype.getString = function () {
-      var res = this.objId + " 0 obj\n<<";
-      var content = this.getContent();
+    var standardFonts = [["Helvetica", "helvetica", "normal", "WinAnsiEncoding"], ["Helvetica-Bold", "helvetica", "bold", "WinAnsiEncoding"], ["Helvetica-Oblique", "helvetica", "italic", "WinAnsiEncoding"], ["Helvetica-BoldOblique", "helvetica", "bolditalic", "WinAnsiEncoding"], ["Courier", "courier", "normal", "WinAnsiEncoding"], ["Courier-Bold", "courier", "bold", "WinAnsiEncoding"], ["Courier-Oblique", "courier", "italic", "WinAnsiEncoding"], ["Courier-BoldOblique", "courier", "bolditalic", "WinAnsiEncoding"], ["Times-Roman", "times", "normal", "WinAnsiEncoding"], ["Times-Bold", "times", "bold", "WinAnsiEncoding"], ["Times-Italic", "times", "italic", "WinAnsiEncoding"], ["Times-BoldItalic", "times", "bolditalic", "WinAnsiEncoding"], ["ZapfDingbats", "zapfdingbats", "normal", null], ["Symbol", "symbol", "normal", null]];
 
-      res += content + ">>\n";
-      if (this.stream) {
-        res += "stream\n";
-        res += this.stream;
-        res += "\nendstream\n";
-      }
-      res += "endobj\n";
-      return res;
+    API.__private__.getStandardFonts = function () {
+      return standardFonts;
     };
 
-    AcroFormPDFObject.prototype.getContent = function () {
-      /**
-      * Prints out all enumerable Variables from the Object
-      * 
-      * @param fieldObject
-      * @returns {string}
-      */
-      var createContentFromFieldObject = function createContentFromFieldObject(fieldObject) {
-        var content = '';
-
-        var keys = Object.keys(fieldObject).filter(function (key) {
-          return key != 'content' && key != 'appearanceStreamContent' && key.substring(0, 1) != "_";
-        });
-
-        for (var i in keys) {
-          var key = keys[i];
-          var value = fieldObject[key];
-
-          /*
-          * if (key == 'Rect' && value) { value =
-          * AcroForm.internal.calculateCoordinates.call(jsPDF.API.acroformPlugin.internal,
-          * value); }
-          */
-
-          if (value) {
-            if (Array.isArray(value)) {
-              content += '/' + key + ' ' + arrayToPdfArray(value) + "\n";
-            } else if (value instanceof AcroFormPDFObject) {
-              // In case it is a reference to another PDFObject,
-              // take the referennce number
-              content += '/' + key + ' ' + value.objId + " 0 R" + "\n";
-            } else {
-              content += '/' + key + ' ' + value + '\n';
-            }
-          }
-        }
-        return content;
-      };
+    var activeFontSize = options.fontSize || 16;
+    /**
+     * Sets font size for upcoming text elements.
+     *
+     * @param {number} size Font size in points.
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name setFontSize
+     */
 
-      var object = "";
+    API.__private__.setFontSize = API.setFontSize = function (size) {
+      if (apiMode === ApiMode.ADVANCED) {
+        activeFontSize = size / scaleFactor;
+      } else {
+        activeFontSize = size;
+      }
 
-      object += createContentFromFieldObject(this);
-      return object;
+      return this;
     };
+    /**
+     * Gets the fontsize for upcoming text elements.
+     *
+     * @function
+     * @instance
+     * @returns {number}
+     * @memberof jsPDF#
+     * @name getFontSize
+     */
 
-    var AcroFormXObject = function AcroFormXObject() {
-      AcroFormPDFObject.call(this);
-      this.Type = "/XObject";
-      this.Subtype = "/Form";
-      this.FormType = 1;
-      this.BBox;
-      this.Matrix;
-      this.Resources = "2 0 R";
-      this.PieceInfo;
-      var _stream;
-      Object.defineProperty(this, 'Length', {
-        enumerable: true,
-        get: function get$$1() {
-          return _stream !== undefined ? _stream.length : 0;
-        }
-      });
-      Object.defineProperty(this, 'stream', {
-        enumerable: false,
-        set: function set$$1(val) {
-          _stream = val.trim();
-        },
-        get: function get$$1() {
-          if (_stream) {
-            return _stream;
-          } else {
-            return null;
-          }
-        }
-      });
+
+    var getFontSize = API.__private__.getFontSize = API.getFontSize = function () {
+      if (apiMode === ApiMode.COMPAT) {
+        return activeFontSize;
+      } else {
+        return activeFontSize * scaleFactor;
+      }
     };
 
-    inherit(AcroFormXObject, AcroFormPDFObject);
-    // ##### The Objects, the User can Create:
+    var R2L = options.R2L || false;
+    /**
+     * Set value of R2L functionality.
+     *
+     * @param {boolean} value
+     * @function
+     * @instance
+     * @returns {jsPDF} jsPDF-instance
+     * @memberof jsPDF#
+     * @name setR2L
+     */
 
-    var AcroFormDictionary = function AcroFormDictionary() {
-      AcroFormPDFObject.call(this);
-      var _Kids = [];
-      Object.defineProperty(this, 'Kids', {
-        enumerable: false,
-        configurable: true,
-        get: function get$$1() {
-          if (_Kids.length > 0) {
-            return _Kids;
-          } else {
-            return;
-          }
-        }
-      });
-      Object.defineProperty(this, 'Fields', {
-        enumerable: true,
-        configurable: true,
-        get: function get$$1() {
-          return _Kids;
-        }
-      });
-      // Default Appearance
-      this.DA;
+    API.__private__.setR2L = API.setR2L = function (value) {
+      R2L = value;
+      return this;
     };
+    /**
+     * Get value of R2L functionality.
+     *
+     * @function
+     * @instance
+     * @returns {boolean} jsPDF-instance
+     * @memberof jsPDF#
+     * @name getR2L
+     */
 
-    inherit(AcroFormDictionary, AcroFormPDFObject);
 
-    // The Field Object contains the Variables, that every Field needs
-    // Rectangle for Appearance: lower_left_X, lower_left_Y, width, height
-    var AcroFormField = function AcroFormField() {
+    API.__private__.getR2L = API.getR2L = function () {
+      return R2L;
+    };
 
-      AcroFormPDFObject.call(this);
+    var zoomMode; // default: 1;
 
-      var _Rect;
-      Object.defineProperty(this, 'Rect', {
-        enumerable: true,
-        configurable: false,
-        get: function get$$1() {
-          if (!_Rect) {
-            return;
-          }
-          var tmp = _Rect;
-          // var calculatedRes =
-          // AcroForm.internal.calculateCoordinates(_Rect); // do
-          // later!
-          return tmp;
-        },
-        set: function set$$1(val) {
-          _Rect = val;
-        }
-      });
+    var setZoomMode = API.__private__.setZoomMode = function (zoom) {
+      var validZoomModes = [undefined, null, "fullwidth", "fullheight", "fullpage", "original"];
 
-      var _FT = "";
-      Object.defineProperty(this, 'FT', {
-        enumerable: true,
-        set: function set$$1(val) {
-          _FT = val;
-        },
-        get: function get$$1() {
-          return _FT;
-        }
-      });
-      /**
-      * The Partial name of the Field Object. It has to be unique.
-      */
-      var _T;
+      if (/^(?:\d+\.\d*|\d*\.\d+|\d+)%$/.test(zoom)) {
+        zoomMode = zoom;
+      } else if (!isNaN(zoom)) {
+        zoomMode = parseInt(zoom, 10);
+      } else if (validZoomModes.indexOf(zoom) !== -1) {
+        zoomMode = zoom;
+      } else {
+        throw new Error('zoom must be Integer (e.g. 2), a percentage Value (e.g. 300%) or fullwidth, fullheight, fullpage, original. "' + zoom + '" is not recognized.');
+      }
+    };
 
-      Object.defineProperty(this, 'T', {
-        enumerable: true,
-        configurable: false,
-        set: function set$$1(val) {
-          _T = val;
-        },
-        get: function get$$1() {
-          if (!_T || _T.length < 1) {
-            if (this instanceof AcroFormChildClass) {
-              // In case of a Child from a Radio´Group, you don't
-              // need a FieldName!!!
-              return;
-            }
-            return "(FieldObject" + AcroFormField.FieldNum++ + ")";
-          }
-          if (_T.substring(0, 1) == "(" && _T.substring(_T.length - 1)) {
-            return _T;
-          }
-          return "(" + _T + ")";
-        }
-      });
+    API.__private__.getZoomMode = function () {
+      return zoomMode;
+    };
 
-      var _DA;
-      // Defines the default appearance (Needed for variable Text)
-      Object.defineProperty(this, 'DA', {
-        enumerable: true,
-        get: function get$$1() {
-          if (!_DA) {
-            return;
-          }
-          return '(' + _DA + ')';
-        },
-        set: function set$$1(val) {
-          _DA = val;
-        }
-      });
+    var pageMode; // default: 'UseOutlines';
 
-      var _DV;
-      // Defines the default value
-      Object.defineProperty(this, 'DV', {
-        enumerable: true,
-        configurable: true,
-        get: function get$$1() {
-          if (!_DV) {
-            return;
-          }
-          return _DV;
-        },
-        set: function set$$1(val) {
-          _DV = val;
-        }
-      });
+    var setPageMode = API.__private__.setPageMode = function (pmode) {
+      var validPageModes = [undefined, null, "UseNone", "UseOutlines", "UseThumbs", "FullScreen"];
 
-      var _V;
-      // Defines the default value
-      Object.defineProperty(this, 'V', {
-        enumerable: true,
-        configurable: true,
-        get: function get$$1() {
-          if (!_V) {
-            return;
-          }
-          return _V;
-        },
-        set: function set$$1(val) {
-          _V = val;
-        }
-      });
+      if (validPageModes.indexOf(pmode) == -1) {
+        throw new Error('Page mode must be one of UseNone, UseOutlines, UseThumbs, or FullScreen. "' + pmode + '" is not recognized.');
+      }
 
-      // this.Type = "/Annot";
-      // this.Subtype = "/Widget";
-      Object.defineProperty(this, 'Type', {
-        enumerable: true,
-        get: function get$$1() {
-          return this.hasAnnotation ? "/Annot" : null;
-        }
-      });
+      pageMode = pmode;
+    };
 
-      Object.defineProperty(this, 'Subtype', {
-        enumerable: true,
-        get: function get$$1() {
-          return this.hasAnnotation ? "/Widget" : null;
-        }
-      });
+    API.__private__.getPageMode = function () {
+      return pageMode;
+    };
 
-      /**
-      * 
-      * @type {Array}
-      */
-      this.BG;
+    var layoutMode; // default: 'continuous';
 
-      Object.defineProperty(this, 'hasAnnotation', {
-        enumerable: false,
-        get: function get$$1() {
-          if (this.Rect || this.BC || this.BG) {
-            return true;
-          }
-          return false;
-        }
-      });
+    var setLayoutMode = API.__private__.setLayoutMode = function (layout) {
+      var validLayoutModes = [undefined, null, "continuous", "single", "twoleft", "tworight", "two"];
 
-      Object.defineProperty(this, 'hasAppearanceStream', {
-        enumerable: false,
-        configurable: true,
-        writable: true
-      });
+      if (validLayoutModes.indexOf(layout) == -1) {
+        throw new Error('Layout mode must be one of continuous, single, twoleft, tworight. "' + layout + '" is not recognized.');
+      }
 
-      Object.defineProperty(this, 'page', {
-        enumerable: false,
-        configurable: true,
-        writable: true
-      });
+      layoutMode = layout;
     };
 
-    inherit(AcroFormField, AcroFormPDFObject);
-
-    var AcroFormChoiceField = function AcroFormChoiceField() {
-      AcroFormField.call(this);
-      // Field Type = Choice Field
-      this.FT = "/Ch";
-      // options
-      this.Opt = [];
-      this.V = '()';
-      // Top Index
-      this.TI = 0;
-      /**
-      * Defines, whether the
-      * 
-      * @type {boolean}
-      */
+    API.__private__.getLayoutMode = function () {
+      return layoutMode;
+    };
+    /**
+     * Set the display mode options of the page like zoom and layout.
+     *
+     * @name setDisplayMode
+     * @memberof jsPDF#
+     * @function
+     * @instance
+     * @param {integer|String} zoom   You can pass an integer or percentage as
+     * a string. 2 will scale the document up 2x, '200%' will scale up by the
+     * same amount. You can also set it to 'fullwidth', 'fullheight',
+     * 'fullpage', or 'original'.
+     *
+     * Only certain PDF readers support this, such as Adobe Acrobat.
+     *
+     * @param {string} layout Layout mode can be: 'continuous' - this is the
+     * default continuous scroll. 'single' - the single page mode only shows one
+     * page at a time. 'twoleft' - two column left mode, first page starts on
+     * the left, and 'tworight' - pages are laid out in two columns, with the
+     * first page on the right. This would be used for books.
+     * @param {string} pmode 'UseOutlines' - it shows the
+     * outline of the document on the left. 'UseThumbs' - shows thumbnails along
+     * the left. 'FullScreen' - prompts the user to enter fullscreen mode.
+     *
+     * @returns {jsPDF}
+     */
 
-      var _combo = false;
 
-      Object.defineProperty(this, 'combo', {
-        enumerable: false,
-        get: function get$$1() {
-          return _combo;
-        },
-        set: function set$$1(val) {
-          _combo = val;
-        }
-      });
-      /**
-      * Defines, whether the Choice Field is an Edit Field. An Edit Field
-      * is automatically an Combo Field.
-      */
-      Object.defineProperty(this, 'edit', {
-        enumerable: true,
-        set: function set$$1(val) {
-          if (val == true) {
-            this._edit = true;
-            // ComboBox has to be true
-            this.combo = true;
-          } else {
-            this._edit = false;
-          }
-        },
-        get: function get$$1() {
-          if (!this._edit) {
-            return false;
-          }
-          return this._edit;
-        },
-        configurable: false
-      });
-      this.hasAppearanceStream = true;
+    API.__private__.setDisplayMode = API.setDisplayMode = function (zoom, layout, pmode) {
+      setZoomMode(zoom);
+      setLayoutMode(layout);
+      setPageMode(pmode);
+      return this;
     };
-    inherit(AcroFormChoiceField, AcroFormField);
 
-    var AcroFormListBox = function AcroFormListBox() {
-      AcroFormChoiceField.call(this);
-      this.combo = false;
+    var documentProperties = {
+      title: "",
+      subject: "",
+      author: "",
+      keywords: "",
+      creator: ""
     };
-    inherit(AcroFormListBox, AcroFormChoiceField);
 
-    var AcroFormComboBox = function AcroFormComboBox() {
-      AcroFormListBox.call(this);
-      this.combo = true;
-    };
-    inherit(AcroFormComboBox, AcroFormListBox);
+    API.__private__.getDocumentProperty = function (key) {
+      if (Object.keys(documentProperties).indexOf(key) === -1) {
+        throw new Error("Invalid argument passed to jsPDF.getDocumentProperty");
+      }
 
-    var AcroFormEditBox = function AcroFormEditBox() {
-      AcroFormComboBox.call(this);
-      this.edit = true;
+      return documentProperties[key];
     };
-    inherit(AcroFormEditBox, AcroFormComboBox);
 
-    var AcroFormButton = function AcroFormButton() {
-      AcroFormField.call(this);
-      this.FT = "/Btn";
-      // this.hasAnnotation = true;
+    API.__private__.getDocumentProperties = function () {
+      return documentProperties;
     };
-    inherit(AcroFormButton, AcroFormField);
+    /**
+     * Adds a properties to the PDF document.
+     *
+     * @param {Object} A property_name-to-property_value object structure.
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name setDocumentProperties
+     */
 
-    var AcroFormPushButton = function AcroFormPushButton() {
-      AcroFormButton.call(this);
 
-      var _pushbutton = true;
-      Object.defineProperty(this, 'pushbutton', {
-        enumerable: false,
-        get: function get$$1() {
-          return _pushbutton;
-        },
-        set: function set$$1(val) {
-          _pushbutton = val;
+    API.__private__.setDocumentProperties = API.setProperties = API.setDocumentProperties = function (properties) {
+      // copying only those properties we can render.
+      for (var property in documentProperties) {
+        if (documentProperties.hasOwnProperty(property) && properties[property]) {
+          documentProperties[property] = properties[property];
         }
-      });
+      }
+
+      return this;
     };
-    inherit(AcroFormPushButton, AcroFormButton);
 
-    var AcroFormRadioButton = function AcroFormRadioButton() {
-      AcroFormButton.call(this);
+    API.__private__.setDocumentProperty = function (key, value) {
+      if (Object.keys(documentProperties).indexOf(key) === -1) {
+        throw new Error("Invalid arguments passed to jsPDF.setDocumentProperty");
+      }
 
-      var _radio = true;
-      Object.defineProperty(this, 'radio', {
-        enumerable: false,
-        get: function get$$1() {
-          return _radio;
-        },
-        set: function set$$1(val) {
-          _radio = val;
-        }
-      });
+      return documentProperties[key] = value;
+    };
 
-      var _Kids = [];
-      Object.defineProperty(this, 'Kids', {
-        enumerable: true,
-        get: function get$$1() {
-          if (_Kids.length > 0) {
-            return _Kids;
-          }
-        }
-      });
+    var fonts = {}; // collection of font objects, where key is fontKey - a dynamically created label for a given font.
 
-      Object.defineProperty(this, '__Kids', {
-        get: function get$$1() {
-          return _Kids;
-        }
-      });
+    var fontmap = {}; // mapping structure fontName > fontStyle > font key - performance layer. See addFont()
 
-      var _noToggleToOff;
+    var activeFontKey; // will be string representing the KEY of the font as combination of fontName + fontStyle
 
-      Object.defineProperty(this, 'noToggleToOff', {
-        enumerable: false,
-        get: function get$$1() {
-          return _noToggleToOff;
-        },
-        set: function set$$1(val) {
-          _noToggleToOff = val;
-        }
-      });
+    var fontStateStack = []; //
 
-      // this.hasAnnotation = false;
-    };
-    inherit(AcroFormRadioButton, AcroFormButton);
+    var patterns = {}; // collection of pattern objects
 
-    /*
-    * The Child classs of a RadioButton (the radioGroup) -> The single
-    * Buttons
-    */
-    var AcroFormChildClass = function AcroFormChildClass(parent, name) {
-      AcroFormField.call(this);
-      this.Parent = parent;
+    var patternMap = {}; // see fonts
 
-      // todo: set AppearanceType as variable that can be set from the
-      // outside...
-      this._AppearanceType = AcroFormAppearance.RadioButton.Circle;
-      // The Default appearanceType is the Circle
-      this.appearanceStreamContent = this._AppearanceType.createAppearanceStream(name);
+    var gStates = {}; // collection of graphic state objects
 
-      // Set Print in the Annot Flag
-      this.F = setBitPosition(this.F, 3, 1);
+    var gStatesMap = {}; // see fonts
 
-      // Set AppearanceCharacteristicsDictionary with default appearance
-      // if field is not interacting with user
-      this.MK = this._AppearanceType.createMK();
-      // (8) -> Cross, (1)->  Circle, ()-> nothing
+    var activeGState = null;
+    var scaleFactor; // Scale factor
 
-      // Default Appearance is Off
-      this.AS = "/Off"; // + name;
+    var page = 0;
+    var pagesContext = [];
+    var events = new PubSub(API);
+    var hotfixes = options.hotfixes || [];
+    var renderTargets = {};
+    var renderTargetMap = {};
+    var renderTargetStack = [];
+    var pageX;
+    var pageY;
+    var pageMatrix; // only used for FormObjects
 
-      this._Name = name;
-    };
-    inherit(AcroFormChildClass, AcroFormField);
+    /**
+     * A matrix object for 2D homogenous transformations: <br>
+     * | a b 0 | <br>
+     * | c d 0 | <br>
+     * | e f 1 | <br>
+     * pdf multiplies matrices righthand: v' = v x m1 x m2 x ...
+     *
+     * @class
+     * @name Matrix
+     * @param {number} sx
+     * @param {number} shy
+     * @param {number} shx
+     * @param {number} sy
+     * @param {number} tx
+     * @param {number} ty
+     * @constructor
+     */
 
-    AcroFormRadioButton.prototype.setAppearance = function (appearance) {
-      if (!('createAppearanceStream' in appearance && 'createMK' in appearance)) {
-        console.log("Couldn't assign Appearance to RadioButton. Appearance was Invalid!");
-        return;
+    var Matrix = function Matrix(sx, shy, shx, sy, tx, ty) {
+      if (!(this instanceof Matrix)) {
+        return new Matrix(sx, shy, shx, sy, tx, ty);
       }
-      for (var i in this.__Kids) {
-        var child = this.__Kids[i];
 
-        child.appearanceStreamContent = appearance.createAppearanceStream(child._Name);
-        child.MK = appearance.createMK();
-      }
+      if (isNaN(sx)) sx = 1;
+      if (isNaN(shy)) shy = 0;
+      if (isNaN(shx)) shx = 0;
+      if (isNaN(sy)) sy = 1;
+      if (isNaN(tx)) tx = 0;
+      if (isNaN(ty)) ty = 0;
+      this._matrix = [sx, shy, shx, sy, tx, ty];
     };
+    /**
+     * @name sx
+     * @memberof Matrix#
+     */
 
-    AcroFormRadioButton.prototype.createOption = function (name) {
-      var parent = this;
-      var kidCount = this.__Kids.length;
 
-      // Create new Child for RadioGroup
-      var child = new AcroFormChildClass(parent, name);
-      // Add to Parent
-      this.__Kids.push(child);
+    Object.defineProperty(Matrix.prototype, "sx", {
+      get: function get() {
+        return this._matrix[0];
+      },
+      set: function set(value) {
+        this._matrix[0] = value;
+      }
+    });
+    /**
+     * @name shy
+     * @memberof Matrix#
+     */
 
-      jsPDFAPI.addField(child);
+    Object.defineProperty(Matrix.prototype, "shy", {
+      get: function get() {
+        return this._matrix[1];
+      },
+      set: function set(value) {
+        this._matrix[1] = value;
+      }
+    });
+    /**
+     * @name shx
+     * @memberof Matrix#
+     */
 
-      return child;
-    };
+    Object.defineProperty(Matrix.prototype, "shx", {
+      get: function get() {
+        return this._matrix[2];
+      },
+      set: function set(value) {
+        this._matrix[2] = value;
+      }
+    });
+    /**
+     * @name sy
+     * @memberof Matrix#
+     */
 
-    var AcroFormCheckBox = function AcroFormCheckBox() {
-      AcroFormButton.call(this);
-      this.appearanceStreamContent = AcroFormAppearance.CheckBox.createAppearanceStream();
-      this.MK = AcroFormAppearance.CheckBox.createMK();
-      this.AS = "/On";
-      this.V = "/On";
-    };
-    inherit(AcroFormCheckBox, AcroFormButton);
+    Object.defineProperty(Matrix.prototype, "sy", {
+      get: function get() {
+        return this._matrix[3];
+      },
+      set: function set(value) {
+        this._matrix[3] = value;
+      }
+    });
+    /**
+     * @name tx
+     * @memberof Matrix#
+     */
 
-    var AcroFormTextField = function AcroFormTextField() {
-      AcroFormField.call(this);
-      this.DA = AcroFormAppearance.createDefaultAppearanceStream();
-      this.F = 4;
-      var _V;
-      Object.defineProperty(this, 'V', {
-        get: function get$$1() {
-          if (_V) {
-            return toPdfString(_V);
-          } else {
-            return _V;
-          }
-        },
-        enumerable: true,
-        set: function set$$1(val) {
-          _V = val;
-        }
-      });
+    Object.defineProperty(Matrix.prototype, "tx", {
+      get: function get() {
+        return this._matrix[4];
+      },
+      set: function set(value) {
+        this._matrix[4] = value;
+      }
+    });
+    /**
+     * @name ty
+     * @memberof Matrix#
+     */
 
-      var _DV;
-      Object.defineProperty(this, 'DV', {
-        get: function get$$1() {
-          if (_DV) {
-            return toPdfString(_DV);
-          } else {
-            return _DV;
-          }
-        },
-        enumerable: true,
-        set: function set$$1(val) {
-          _DV = val;
-        }
-      });
+    Object.defineProperty(Matrix.prototype, "ty", {
+      get: function get() {
+        return this._matrix[5];
+      },
+      set: function set(value) {
+        this._matrix[5] = value;
+      }
+    });
+    Object.defineProperty(Matrix.prototype, "a", {
+      get: function get() {
+        return this._matrix[0];
+      },
+      set: function set(value) {
+        this._matrix[0] = value;
+      }
+    });
+    Object.defineProperty(Matrix.prototype, "b", {
+      get: function get() {
+        return this._matrix[1];
+      },
+      set: function set(value) {
+        this._matrix[1] = value;
+      }
+    });
+    Object.defineProperty(Matrix.prototype, "c", {
+      get: function get() {
+        return this._matrix[2];
+      },
+      set: function set(value) {
+        this._matrix[2] = value;
+      }
+    });
+    Object.defineProperty(Matrix.prototype, "d", {
+      get: function get() {
+        return this._matrix[3];
+      },
+      set: function set(value) {
+        this._matrix[3] = value;
+      }
+    });
+    Object.defineProperty(Matrix.prototype, "e", {
+      get: function get() {
+        return this._matrix[4];
+      },
+      set: function set(value) {
+        this._matrix[4] = value;
+      }
+    });
+    Object.defineProperty(Matrix.prototype, "f", {
+      get: function get() {
+        return this._matrix[5];
+      },
+      set: function set(value) {
+        this._matrix[5] = value;
+      }
+    });
+    /**
+     * @name rotation
+     * @memberof Matrix#
+     */
 
-      var _multiline = false;
-      Object.defineProperty(this, 'multiline', {
-        enumerable: false,
-        get: function get$$1() {
-          return _multiline;
-        },
-        set: function set$$1(val) {
-          _multiline = val;
-        }
-      });
+    Object.defineProperty(Matrix.prototype, "rotation", {
+      get: function get() {
+        return Math.atan2(this.shx, this.sx);
+      }
+    });
+    /**
+     * @name scaleX
+     * @memberof Matrix#
+     */
 
-      /**
-      * For PDF 1.4
-      * 
-      * @type {boolean}
-      */
-      var _fileSelect = false;
-      Object.defineProperty(this, 'fileSelect', {
-        enumerable: false,
-        get: function get$$1() {
-          return _fileSelect;
-        },
-        set: function set$$1(val) {
-          _fileSelect = val;
-        }
-      });
-      /**
-      * For PDF 1.4
-      * 
-      * @type {boolean}
-      */
-      var _doNotSpellCheck = false;
-      Object.defineProperty(this, 'doNotSpellCheck', {
-        enumerable: false,
-        get: function get$$1() {
-          return _doNotSpellCheck;
-        },
-        set: function set$$1(val) {
-          _doNotSpellCheck = val;
+    Object.defineProperty(Matrix.prototype, "scaleX", {
+      get: function get() {
+        return this.decompose().scale.sx;
+      }
+    });
+    /**
+     * @name scaleY
+     * @memberof Matrix#
+     */
+
+    Object.defineProperty(Matrix.prototype, "scaleY", {
+      get: function get() {
+        return this.decompose().scale.sy;
+      }
+    });
+    /**
+     * @name isIdentity
+     * @memberof Matrix#
+     */
+
+    Object.defineProperty(Matrix.prototype, "isIdentity", {
+      get: function get() {
+        if (this.sx !== 1) {
+          return false;
         }
-      });
-      /**
-      * For PDF 1.4
-      * 
-      * @type {boolean}
-      */
-      var _doNotScroll = false;
-      Object.defineProperty(this, 'doNotScroll', {
-        enumerable: false,
-        get: function get$$1() {
-          return _doNotScroll;
-        },
-        set: function set$$1(val) {
-          _doNotScroll = val;
+
+        if (this.shy !== 0) {
+          return false;
         }
-      });
 
-      var _MaxLen = false;
-      Object.defineProperty(this, 'MaxLen', {
-        enumerable: true,
-        get: function get$$1() {
-          return _MaxLen;
-        },
-        set: function set$$1(val) {
-          _MaxLen = val;
+        if (this.shx !== 0) {
+          return false;
         }
-      });
 
-      Object.defineProperty(this, 'hasAppearanceStream', {
-        enumerable: false,
-        get: function get$$1() {
-          return this.V || this.DV;
+        if (this.sy !== 1) {
+          return false;
         }
-      });
-    };
-    inherit(AcroFormTextField, AcroFormField);
 
-    var AcroFormPasswordField = function AcroFormPasswordField() {
-      AcroFormTextField.call(this);
+        if (this.tx !== 0) {
+          return false;
+        }
 
-      var _password = true;
-      Object.defineProperty(this, 'password', {
-        enumerable: false,
-        get: function get$$1() {
-          return _password;
-        },
-        set: function set$$1(val) {
-          _password = val;
+        if (this.ty !== 0) {
+          return false;
         }
-      });
+
+        return true;
+      }
+    });
+    /**
+     * Join the Matrix Values to a String
+     *
+     * @function join
+     * @param {string} separator Specifies a string to separate each pair of adjacent elements of the array. The separator is converted to a string if necessary. If omitted, the array elements are separated with a comma (","). If separator is an empty string, all elements are joined without any characters in between them.
+     * @returns {string} A string with all array elements joined.
+     * @memberof Matrix#
+     */
+
+    Matrix.prototype.join = function (separator) {
+      return [this.sx, this.shy, this.shx, this.sy, this.tx, this.ty].map(hpf).join(separator);
     };
-    inherit(AcroFormPasswordField, AcroFormTextField);
+    /**
+     * Multiply the matrix with given Matrix
+     *
+     * @function multiply
+     * @param matrix
+     * @returns {Matrix}
+     * @memberof Matrix#
+     */
 
-    // Contains Methods for creating standard appearances
-    var AcroFormAppearance = {
-      CheckBox: {
-        createAppearanceStream: function createAppearanceStream() {
-          var appearance = {
-            N: {
-              On: AcroFormAppearance.CheckBox.YesNormal
-            },
-            D: {
-              On: AcroFormAppearance.CheckBox.YesPushDown,
-              Off: AcroFormAppearance.CheckBox.OffPushDown
-            }
-          };
 
-          return appearance;
-        },
-        /**
-          * If any other icons are needed, the number between the
-          * brackets can be changed
-          * 
-          * @returns {string}
-          */
-        createMK: function createMK() {
-          return "<< /CA (3)>>";
-        },
-        /**
-          * Returns the standard On Appearance for a CheckBox
-          * 
-          * @returns {AcroFormXObject}
-          */
-        YesPushDown: function YesPushDown(formObject) {
-          var xobj = createFormXObject(formObject);
-          var stream = [];
-          var zapfDingbatsId = scope.internal.getFont("zapfdingbats", "normal").id;
-          formObject.Q = 1; // set text-alignment as centered
-          var calcRes = calculateX(formObject, "3", "ZapfDingbats", 50);
-          stream.push("0.749023 g");
-          stream.push("0 0 " + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + " " + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + " re");
-          stream.push("f");
-          stream.push("BMC");
-          stream.push("q");
-          stream.push("0 0 1 rg");
-          stream.push("/" + zapfDingbatsId + " " + calcRes.fontSize.toFixed(2) + " Tf 0 g");
-          stream.push("BT");
-          stream.push(calcRes.text);
-          stream.push("ET");
-          stream.push("Q");
-          stream.push("EMC");
-          xobj.stream = stream.join("\n");
-          return xobj;
-        },
+    Matrix.prototype.multiply = function (matrix) {
+      var sx = matrix.sx * this.sx + matrix.shy * this.shx;
+      var shy = matrix.sx * this.shy + matrix.shy * this.sy;
+      var shx = matrix.shx * this.sx + matrix.sy * this.shx;
+      var sy = matrix.shx * this.shy + matrix.sy * this.sy;
+      var tx = matrix.tx * this.sx + matrix.ty * this.shx + this.tx;
+      var ty = matrix.tx * this.shy + matrix.ty * this.sy + this.ty;
+      return new Matrix(sx, shy, shx, sy, tx, ty);
+    };
+    /**
+     * @function decompose
+     * @memberof Matrix#
+     */
 
-        YesNormal: function YesNormal(formObject) {
-          var xobj = createFormXObject(formObject);
-          var zapfDingbatsId = scope.internal.getFont("zapfdingbats", "normal").id;
-          var stream = [];
-          formObject.Q = 1; // set text-alignment as centered
-          var height = AcroFormAppearance.internal.getHeight(formObject);
-          var width = AcroFormAppearance.internal.getWidth(formObject);
-          var calcRes = calculateX(formObject, "3", "ZapfDingbats", height * 0.9);
-          stream.push("1 g");
-          stream.push("0 0 " + width.toFixed(2) + " " + height.toFixed(2) + " re");
-          stream.push("f");
-          stream.push("q");
-          stream.push("0 0 1 rg");
-          stream.push("0 0 " + (width - 1).toFixed(2) + " " + (height - 1).toFixed(2) + " re");
-          stream.push("W");
-          stream.push("n");
-          stream.push("0 g");
-          stream.push("BT");
-          stream.push("/" + zapfDingbatsId + " " + calcRes.fontSize.toFixed(2) + " Tf 0 g");
-          stream.push(calcRes.text);
-          stream.push("ET");
-          stream.push("Q");
-          xobj.stream = stream.join("\n");
-          return xobj;
-        },
 
-        /**
-          * Returns the standard Off Appearance for a CheckBox
-          * 
-          * @returns {AcroFormXObject}
-          */
-        OffPushDown: function OffPushDown(formObject) {
-          var xobj = createFormXObject(formObject);
-          var stream = [];
-          stream.push("0.749023 g");
-          stream.push("0 0 " + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + " " + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + " re");
-          stream.push("f");
-          xobj.stream = stream.join("\n");
-          return xobj;
-        }
-      },
+    Matrix.prototype.decompose = function () {
+      var a = this.sx;
+      var b = this.shy;
+      var c = this.shx;
+      var d = this.sy;
+      var e = this.tx;
+      var f = this.ty;
+      var scaleX = Math.sqrt(a * a + b * b);
+      a /= scaleX;
+      b /= scaleX;
+      var shear = a * c + b * d;
+      c -= a * shear;
+      d -= b * shear;
+      var scaleY = Math.sqrt(c * c + d * d);
+      c /= scaleY;
+      d /= scaleY;
+      shear /= scaleY;
+
+      if (a * d < b * c) {
+        a = -a;
+        b = -b;
+        shear = -shear;
+        scaleX = -scaleX;
+      }
 
-      RadioButton: {
-        Circle: {
-          createAppearanceStream: function createAppearanceStream(name) {
-            var appearanceStreamContent = {
-              D: {
-                'Off': AcroFormAppearance.RadioButton.Circle.OffPushDown
-              },
-              N: {}
-            };
-            appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Circle.YesNormal;
-            appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Circle.YesPushDown;
-            return appearanceStreamContent;
-          },
-          createMK: function createMK() {
-            return "<< /CA (l)>>";
-          },
+      return {
+        scale: new Matrix(scaleX, 0, 0, scaleY, 0, 0),
+        translate: new Matrix(1, 0, 0, 1, e, f),
+        rotate: new Matrix(a, b, -b, a, 0, 0),
+        skew: new Matrix(1, 0, shear, 1, 0, 0)
+      };
+    };
+    /**
+     * @function toString
+     * @memberof Matrix#
+     */
 
-          YesNormal: function YesNormal(formObject) {
-            var xobj = createFormXObject(formObject);
-            var stream = [];
-            // Make the Radius of the Circle relative to min(height,
-            // width) of formObject
-            var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4;
-            // The Borderpadding...
-            DotRadius *= 0.9;
-            var c = AcroFormAppearance.internal.Bezier_C;
-            /*
-              * The Following is a Circle created with Bezier-Curves.
-              */
-            stream.push("q");
-            stream.push("1 0 0 1 " + AcroFormAppearance.internal.getWidth(formObject) / 2 + " " + AcroFormAppearance.internal.getHeight(formObject) / 2 + " cm");
-            stream.push(DotRadius + " 0 m");
-            stream.push(DotRadius + " " + DotRadius * c + " " + DotRadius * c + " " + DotRadius + " 0 " + DotRadius + " c");
-            stream.push("-" + DotRadius * c + " " + DotRadius + " -" + DotRadius + " " + DotRadius * c + " -" + DotRadius + " 0 c");
-            stream.push("-" + DotRadius + " -" + DotRadius * c + " -" + DotRadius * c + " -" + DotRadius + " 0 -" + DotRadius + " c");
-            stream.push(DotRadius * c + " -" + DotRadius + " " + DotRadius + " -" + DotRadius * c + " " + DotRadius + " 0 c");
-            stream.push("f");
-            stream.push("Q");
-            xobj.stream = stream.join("\n");
-            return xobj;
-          },
-          YesPushDown: function YesPushDown(formObject) {
-            var xobj = createFormXObject(formObject);
-            var stream = [];
-            var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4;
-            // The Borderpadding...
-            DotRadius *= 0.9;
-            // Save results for later use; no need to waste
-            // processor ticks on doing math
-            var k = DotRadius * 2;
-            // var c = AcroFormAppearance.internal.Bezier_C;
-            var kc = k * AcroFormAppearance.internal.Bezier_C;
-            var dc = DotRadius * AcroFormAppearance.internal.Bezier_C;
-
-            stream.push("0.749023 g");
-            stream.push("q");
-            stream.push("1 0 0 1 " + (AcroFormAppearance.internal.getWidth(formObject) / 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) / 2).toFixed(2) + " cm");
-            stream.push(k + " 0 m");
-            stream.push(k + " " + kc + " " + kc + " " + k + " 0 " + k + " c");
-            stream.push("-" + kc + " " + k + " -" + k + " " + kc + " -" + k + " 0 c");
-            stream.push("-" + k + " -" + kc + " -" + kc + " -" + k + " 0 -" + k + " c");
-            stream.push(kc + " -" + k + " " + k + " -" + kc + " " + k + " 0 c");
-            stream.push("f");
-            stream.push("Q");
-            stream.push("0 g");
-            stream.push("q");
-            stream.push("1 0 0 1 " + (AcroFormAppearance.internal.getWidth(formObject) / 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) / 2).toFixed(2) + " cm");
-            stream.push(DotRadius + " 0 m");
-            stream.push("" + DotRadius + " " + dc + " " + dc + " " + DotRadius + " 0 " + DotRadius + " c");
-            stream.push("-" + dc + " " + DotRadius + " -" + DotRadius + " " + dc + " -" + DotRadius + " 0 c");
-            stream.push("-" + DotRadius + " -" + dc + " -" + dc + " -" + DotRadius + " 0 -" + DotRadius + " c");
-            stream.push(dc + " -" + DotRadius + " " + DotRadius + " -" + dc + " " + DotRadius + " 0 c");
-            stream.push("f");
-            stream.push("Q");
-            xobj.stream = stream.join("\n");
-            return xobj;
-          },
-          OffPushDown: function OffPushDown(formObject) {
-            var xobj = createFormXObject(formObject);
-            var stream = [];
-            var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4;
-            // The Borderpadding...
-            DotRadius *= 0.9;
-            // Save results for later use; no need to waste
-            // processor ticks on doing math
-            var k = DotRadius * 2;
-            // var c = AcroFormAppearance.internal.Bezier_C;
-            var kc = k * AcroFormAppearance.internal.Bezier_C;
-
-            stream.push("0.749023 g");
-            stream.push("q");
-            stream.push("1 0 0 1 " + (AcroFormAppearance.internal.getWidth(formObject) / 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) / 2).toFixed(2) + " cm");
-            stream.push(k + " 0 m");
-            stream.push(k + " " + kc + " " + kc + " " + k + " 0 " + k + " c");
-            stream.push("-" + kc + " " + k + " -" + k + " " + kc + " -" + k + " 0 c");
-            stream.push("-" + k + " -" + kc + " -" + kc + " -" + k + " 0 -" + k + " c");
-            stream.push(kc + " -" + k + " " + k + " -" + kc + " " + k + " 0 c");
-            stream.push("f");
-            stream.push("Q");
-            xobj.stream = stream.join("\n");
-            return xobj;
-          }
-        },
 
-        Cross: {
-          /**
-            * Creates the Actual AppearanceDictionary-References
-            * 
-            * @param name
-            * @returns
-            */
-          createAppearanceStream: function createAppearanceStream(name) {
-            var appearanceStreamContent = {
-              D: {
-                'Off': AcroFormAppearance.RadioButton.Cross.OffPushDown
-              },
-              N: {}
-            };
-            appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Cross.YesNormal;
-            appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Cross.YesPushDown;
-            return appearanceStreamContent;
-          },
-          createMK: function createMK() {
-            return "<< /CA (8)>>";
-          },
+    Matrix.prototype.toString = function (parmPrecision) {
+      return this.join(" ");
+    };
+    /**
+     * @function inversed
+     * @memberof Matrix#
+     */
 
-          YesNormal: function YesNormal(formObject) {
-            var xobj = createFormXObject(formObject);
-            var stream = [];
-            var cross = AcroFormAppearance.internal.calculateCross(formObject);
-            stream.push("q");
-            stream.push("1 1 " + (AcroFormAppearance.internal.getWidth(formObject) - 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) - 2).toFixed(2) + " re");
-            stream.push("W");
-            stream.push("n");
-            stream.push(cross.x1.x.toFixed(2) + " " + cross.x1.y.toFixed(2) + " m");
-            stream.push(cross.x2.x.toFixed(2) + " " + cross.x2.y.toFixed(2) + " l");
-            stream.push(cross.x4.x.toFixed(2) + " " + cross.x4.y.toFixed(2) + " m");
-            stream.push(cross.x3.x.toFixed(2) + " " + cross.x3.y.toFixed(2) + " l");
-            stream.push("s");
-            stream.push("Q");
-            xobj.stream = stream.join("\n");
-            return xobj;
-          },
-          YesPushDown: function YesPushDown(formObject) {
-            var xobj = createFormXObject(formObject);
-            var cross = AcroFormAppearance.internal.calculateCross(formObject);
-            var stream = [];
-            stream.push("0.749023 g");
-            stream.push("0 0 " + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + " " + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + " re");
-            stream.push("f");
-            stream.push("q");
-            stream.push("1 1 " + (AcroFormAppearance.internal.getWidth(formObject) - 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) - 2).toFixed(2) + " re");
-            stream.push("W");
-            stream.push("n");
-            stream.push(cross.x1.x.toFixed(2) + " " + cross.x1.y.toFixed(2) + " m");
-            stream.push(cross.x2.x.toFixed(2) + " " + cross.x2.y.toFixed(2) + " l");
-            stream.push(cross.x4.x.toFixed(2) + " " + cross.x4.y.toFixed(2) + " m");
-            stream.push(cross.x3.x.toFixed(2) + " " + cross.x3.y.toFixed(2) + " l");
-            stream.push("s");
-            stream.push("Q");
-            xobj.stream = stream.join("\n");
-            return xobj;
-          },
-          OffPushDown: function OffPushDown(formObject) {
-            var xobj = createFormXObject(formObject);
-            var stream = [];
-            stream.push("0.749023 g");
-            stream.push("0 0 " + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + " " + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + " re");
-            stream.push("f");
-            xobj.stream = stream.join("\n");
-            return xobj;
-          }
-        }
-      },
 
-      /**
-        * Returns the standard Appearance
-        * 
-        * @returns {AcroFormXObject}
-        */
-      createDefaultAppearanceStream: function createDefaultAppearanceStream(formObject) {
-        // Set Helvetica to Standard Font (size: auto)
-        // Color: Black
-        return "/F1 0 Tf 0 g";
-      }
+    Matrix.prototype.inversed = function () {
+      var a = this.sx,
+          b = this.shy,
+          c = this.shx,
+          d = this.sy,
+          e = this.tx,
+          f = this.ty;
+      var quot = 1 / (a * d - b * c);
+      var aInv = d * quot;
+      var bInv = -b * quot;
+      var cInv = -c * quot;
+      var dInv = a * quot;
+      var eInv = -aInv * e - cInv * f;
+      var fInv = -bInv * e - dInv * f;
+      return new Matrix(aInv, bInv, cInv, dInv, eInv, fInv);
     };
+    /**
+     * @function applyToPoint
+     * @memberof Matrix#
+     */
 
-    AcroFormAppearance.internal = {
-      Bezier_C: 0.551915024494,
 
-      calculateCross: function calculateCross(formObject) {
-        var min = function min(x, y) {
-          return x > y ? y : x;
-        };
+    Matrix.prototype.applyToPoint = function (pt) {
+      var x = pt.x * this.sx + pt.y * this.shx + this.tx;
+      var y = pt.x * this.shy + pt.y * this.sy + this.ty;
+      return new Point(x, y);
+    };
+    /**
+     * @function applyToRectangle
+     * @memberof Matrix#
+     */
 
-        var width = AcroFormAppearance.internal.getWidth(formObject);
-        var height = AcroFormAppearance.internal.getHeight(formObject);
-        var a = min(width, height);
 
+    Matrix.prototype.applyToRectangle = function (rect) {
+      var pt1 = this.applyToPoint(rect);
+      var pt2 = this.applyToPoint(new Point(rect.x + rect.w, rect.y + rect.h));
+      return new Rectangle(pt1.x, pt1.y, pt2.x - pt1.x, pt2.y - pt1.y);
+    };
+    /**
+     * Clone the Matrix
+     *
+     * @function clone
+     * @memberof Matrix#
+     * @name clone
+     * @instance
+     */
 
-        var cross = {
-          x1: { // upperLeft
-            x: (width - a) / 2,
-            y: (height - a) / 2 + a // height - borderPadding
-          },
-          x2: { // lowerRight
-            x: (width - a) / 2 + a,
-            y: (height - a) / 2 // borderPadding
-          },
-          x3: { // lowerLeft
-            x: (width - a) / 2,
-            y: (height - a) / 2 // borderPadding
-          },
-          x4: { // upperRight
-            x: (width - a) / 2 + a,
-            y: (height - a) / 2 + a // height - borderPadding
-          }
-        };
 
-        return cross;
-      }
+    Matrix.prototype.clone = function () {
+      var sx = this.sx;
+      var shy = this.shy;
+      var shx = this.shx;
+      var sy = this.sy;
+      var tx = this.tx;
+      var ty = this.ty;
+      return new Matrix(sx, shy, shx, sy, tx, ty);
     };
-    AcroFormAppearance.internal.getWidth = function (formObject) {
-      var result = 0;
-      if ((typeof formObject === 'undefined' ? 'undefined' : _typeof(formObject)) === "object") {
-        result = scale(formObject.Rect[2]); // (formObject.Rect[2] -
-        // formObject.Rect[0]) || 0;
-      }
-      return result;
+
+    API.Matrix = Matrix;
+    /**
+     * Multiplies two matrices. (see {@link Matrix})
+     * @param {Matrix} m1
+     * @param {Matrix} m2
+     * @memberof jsPDF#
+     * @name matrixMult
+     */
+
+    var matrixMult = API.matrixMult = function (m1, m2) {
+      return m2.multiply(m1);
     };
-    AcroFormAppearance.internal.getHeight = function (formObject) {
-      var result = 0;
-      if ((typeof formObject === 'undefined' ? 'undefined' : _typeof(formObject)) === "object") {
-        result = scale(formObject.Rect[3]); // (formObject.Rect[1] -
-        // formObject.Rect[3]) || 0;
-      }
-      return result;
+    /**
+     * The identity matrix (equivalent to new Matrix(1, 0, 0, 1, 0, 0)).
+     * @type {Matrix}
+     * @memberof! jsPDF#
+     * @name identityMatrix
+     */
+
+
+    var identityMatrix = new Matrix(1, 0, 0, 1, 0, 0);
+    API.unitMatrix = API.identityMatrix = identityMatrix;
+    /**
+     * Adds a new pattern for later use.
+     * @param {String} key The key by it can be referenced later. The keys must be unique!
+     * @param {API.Pattern} pattern The pattern
+     */
+
+    var addPattern = function addPattern(key, pattern) {
+      // only add it if it is not already present (the keys provided by the user must be unique!)
+      if (patternMap[key]) return;
+      var prefix = pattern instanceof ShadingPattern ? "Sh" : "P";
+      var patternKey = prefix + (Object.keys(patterns).length + 1).toString(10);
+      pattern.id = patternKey;
+      patternMap[key] = patternKey;
+      patterns[patternKey] = pattern;
+      events.publish("addPattern", pattern);
     };
+    /**
+     * A pattern describing a shading pattern.
+     *
+     * Only available in "advanced" API mode.
+     *
+     * @param {String} type One of "axial" or "radial"
+     * @param {Array<Number>} coords Either [x1, y1, x2, y2] for "axial" type describing the two interpolation points
+     * or [x1, y1, r, x2, y2, r2] for "radial" describing inner and the outer circle.
+     * @param {Array<Object>} colors An array of objects with the fields "offset" and "color". "offset" describes
+     * the offset in parameter space [0, 1]. "color" is an array of length 3 describing RGB values in [0, 255].
+     * @param {GState=} gState An additional graphics state that gets applied to the pattern (optional).
+     * @param {Matrix=} matrix A matrix that describes the transformation between the pattern coordinate system
+     * and the use coordinate system (optional).
+     * @constructor
+     * @extends API.Pattern
+     */
+
 
-    // Public:
-
-    jsPDFAPI.addField = function (fieldObject) {
-      initializeAcroForm.call(this);
-      // var opt = parseOptions(fieldObject);
-      if (fieldObject instanceof AcroFormTextField) {
-        this.addTextField.call(this, fieldObject);
-      } else if (fieldObject instanceof AcroFormChoiceField) {
-        this.addChoiceField.call(this, fieldObject);
-      } else if (fieldObject instanceof AcroFormButton) {
-        this.addButton.call(this, fieldObject);
-      } else if (fieldObject instanceof AcroFormChildClass) {
-        putForm.call(this, fieldObject);
-      } else if (fieldObject) {
-        // try to put..
-        putForm.call(this, fieldObject);
-      }
-      fieldObject.page = scope.internal.getCurrentPageInfo().pageNumber;
+    API.ShadingPattern = ShadingPattern;
+    /**
+     * A PDF Tiling pattern.
+     *
+     * Only available in "advanced" API mode.
+     *
+     * @param {Array.<Number>} boundingBox The bounding box at which one pattern cell gets clipped.
+     * @param {Number} xStep Horizontal spacing between pattern cells.
+     * @param {Number} yStep Vertical spacing between pattern cells.
+     * @param {API.GState=} gState An additional graphics state that gets applied to the pattern (optional).
+     * @param {Matrix=} matrix A matrix that describes the transformation between the pattern coordinate system
+     * and the use coordinate system (optional).
+     * @constructor
+     * @extends API.Pattern
+     */
+
+    API.TilingPattern = TilingPattern;
+    /**
+     * Adds a new {@link API.ShadingPattern} for later use. Only available in "advanced" API mode.
+     * @param {String} key
+     * @param {Pattern} pattern
+     * @function
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name addPattern
+     */
+
+    API.addShadingPattern = function (key, pattern) {
+      advancedApiModeTrap("addShadingPattern()");
+      addPattern(key, pattern);
       return this;
     };
+    /**
+     * Begins a new tiling pattern. All subsequent render calls are drawn to this pattern until {@link API.endTilingPattern}
+     * gets called. Only available in "advanced" API mode.
+     * @param {API.Pattern} pattern
+     * @memberof jsPDF#
+     * @name beginTilingPattern
+     */
 
+
+    API.beginTilingPattern = function (pattern) {
+      advancedApiModeTrap("beginTilingPattern()");
+      beginNewRenderTarget(pattern.boundingBox[0], pattern.boundingBox[1], pattern.boundingBox[2] - pattern.boundingBox[0], pattern.boundingBox[3] - pattern.boundingBox[1], pattern.matrix);
+    };
     /**
-    * Button FT = Btn
-    */
-    jsPDFAPI.addButton = function (opts) {
-      initializeAcroForm.call(this);
-      var options = opts || new AcroFormField();
+     * Ends a tiling pattern and sets the render target to the one active before {@link API.beginTilingPattern} has been called.
+     *
+     * Only available in "advanced" API mode.
+     *
+     * @param {string} key A unique key that is used to reference this pattern at later use.
+     * @param {API.Pattern} pattern The pattern to end.
+     * @memberof jsPDF#
+     * @name endTilingPattern
+     */
+
+
+    API.endTilingPattern = function (key, pattern) {
+      advancedApiModeTrap("endTilingPattern()"); // retrieve the stream
 
-      options.FT = '/Btn';
-      options.Ff = calculateFlagsOnOptions(options.Ff, opts, scope.internal.getPDFVersion());
+      pattern.stream = pages[currentPage].join("\n");
+      addPattern(key, pattern);
+      events.publish("endTilingPattern", pattern); // restore state from stack
 
-      putForm.call(this, options);
+      renderTargetStack.pop().restore();
     };
 
-    jsPDFAPI.addTextField = function (opts) {
-      initializeAcroForm.call(this);
-      var options = opts || new AcroFormField();
+    var newObject = API.__private__.newObject = function () {
+      var oid = newObjectDeferred();
+      newObjectDeferredBegin(oid, true);
+      return oid;
+    }; // Does not output the object.  The caller must call newObjectDeferredBegin(oid) before outputing any data
 
-      options.FT = '/Tx';
 
-      options.Ff = calculateFlagsOnOptions(options.Ff, opts, scope.internal.getPDFVersion());
+    var newObjectDeferred = API.__private__.newObjectDeferred = function () {
+      objectNumber++;
 
-      // Add field
-      putForm.call(this, options);
+      offsets[objectNumber] = function () {
+        return contentLength;
+      };
+
+      return objectNumber;
     };
 
-    jsPDFAPI.addChoiceField = function (opts) {
-      initializeAcroForm.call(this);
-      var options = opts || new AcroFormField();
+    var newObjectDeferredBegin = function newObjectDeferredBegin(oid, doOutput) {
+      doOutput = typeof doOutput === "boolean" ? doOutput : false;
+      offsets[oid] = contentLength;
+
+      if (doOutput) {
+        out(oid + " 0 obj");
+      }
 
-      options.FT = '/Ch';
+      return oid;
+    }; // Does not output the object until after the pages have been output.
+    // Returns an object containing the objectId and content.
+    // All pages have been added so the object ID can be estimated to start right after.
+    // This does not modify the current objectNumber;  It must be updated after the newObjects are output.
 
-      options.Ff = calculateFlagsOnOptions(options.Ff, opts, scope.internal.getPDFVersion());
-      // options.hasAnnotation = true;
 
-      // Add field
-      putForm.call(this, options);
+    var newAdditionalObject = API.__private__.newAdditionalObject = function () {
+      var objId = newObjectDeferred();
+      var obj = {
+        objId: objId,
+        content: ""
+      };
+      additionalObjects.push(obj);
+      return obj;
     };
 
-    if ((typeof globalObj === 'undefined' ? 'undefined' : _typeof(globalObj)) == "object") {
-      globalObj["ChoiceField"] = AcroFormChoiceField;
-      globalObj["ListBox"] = AcroFormListBox;
-      globalObj["ComboBox"] = AcroFormComboBox;
-      globalObj["EditBox"] = AcroFormEditBox;
-      globalObj["Button"] = AcroFormButton;
-      globalObj["PushButton"] = AcroFormPushButton;
-      globalObj["RadioButton"] = AcroFormRadioButton;
-      globalObj["CheckBox"] = AcroFormCheckBox;
-      globalObj["TextField"] = AcroFormTextField;
-      globalObj["PasswordField"] = AcroFormPasswordField;
+    var rootDictionaryObjId = newObjectDeferred();
+    var resourceDictionaryObjId = newObjectDeferred(); /////////////////////
+    // Private functions
+    /////////////////////
+
+    var decodeColorString = API.__private__.decodeColorString = function (color) {
+      var colorEncoded = color.split(" ");
+
+      if (colorEncoded.length === 2 && (colorEncoded[1] === "g" || colorEncoded[1] === "G")) {
+        // convert grayscale value to rgb so that it can be converted to hex for consistency
+        var floatVal = parseFloat(colorEncoded[0]);
+        colorEncoded = [floatVal, floatVal, floatVal, "r"];
+      } else if (colorEncoded.length === 5 && (colorEncoded[4] === "k" || colorEncoded[4] === "K")) {
+        // convert CMYK values to rbg so that it can be converted to hex for consistency
+        var red = (1.0 - colorEncoded[0]) * (1.0 - colorEncoded[3]);
+        var green = (1.0 - colorEncoded[1]) * (1.0 - colorEncoded[3]);
+        var blue = (1.0 - colorEncoded[2]) * (1.0 - colorEncoded[3]);
+        colorEncoded = [red, green, blue, "r"];
+      }
 
-      // backwardsCompatibility
-      globalObj["AcroForm"] = { Appearance: AcroFormAppearance };
-    }
+      var colorAsRGB = "#";
 
-    jsPDFAPI.AcroFormChoiceField = AcroFormChoiceField;
-    jsPDFAPI.AcroFormListBox = AcroFormListBox;
-    jsPDFAPI.AcroFormComboBox = AcroFormComboBox;
-    jsPDFAPI.AcroFormEditBox = AcroFormEditBox;
-    jsPDFAPI.AcroFormButton = AcroFormButton;
-    jsPDFAPI.AcroFormPushButton = AcroFormPushButton;
-    jsPDFAPI.AcroFormRadioButton = AcroFormRadioButton;
-    jsPDFAPI.AcroFormCheckBox = AcroFormCheckBox;
-    jsPDFAPI.AcroFormTextField = AcroFormTextField;
-    jsPDFAPI.AcroFormPasswordField = AcroFormPasswordField;
-
-    jsPDFAPI.AcroForm = {
-      ChoiceField: AcroFormChoiceField,
-      ListBox: AcroFormListBox,
-      ComboBox: AcroFormComboBox,
-      EditBox: AcroFormEditBox,
-      Button: AcroFormButton,
-      PushButton: AcroFormPushButton,
-      RadioButton: AcroFormRadioButton,
-      CheckBox: AcroFormCheckBox,
-      TextField: AcroFormTextField,
-      PasswordField: AcroFormPasswordField
-    };
-  })(jsPDF.API, typeof window !== "undefined" && window || typeof global !== "undefined" && global);
+      for (var i = 0; i < 3; i++) {
+        colorAsRGB += ("0" + Math.floor(parseFloat(colorEncoded[i]) * 255).toString(16)).slice(-2);
+      }
 
-  /**
-   * jsPDF addHTML PlugIn
-   * Copyright (c) 2014 Diego Casorran
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
+      return colorAsRGB;
+    };
 
-  (function (jsPDFAPI) {
+    var encodeColorString = API.__private__.encodeColorString = function (options) {
+      var color;
 
-      /**
-       * Renders an HTML element to canvas object which added to the PDF
-       *
-       * This feature requires [html2canvas](https://github.com/niklasvh/html2canvas)
-       * or [rasterizeHTML](https://github.com/cburgmer/rasterizeHTML.js)
-       *
-       * @returns {jsPDF}
-       * @name addHTML
-       * @param element {Mixed} HTML Element, or anything supported by html2canvas.
-       * @param x {Number} starting X coordinate in jsPDF instance's declared units.
-       * @param y {Number} starting Y coordinate in jsPDF instance's declared units.
-       * @param options {Object} Additional options, check the code below.
-       * @param callback {Function} to call when the rendering has finished.
-       * NOTE: Every parameter is optional except 'element' and 'callback', in such
-       *       case the image is positioned at 0x0 covering the whole PDF document
-       *       size. Ie, to easily take screenshots of webpages saving them to PDF.
-       * @deprecated This is being replace with a vector-supporting API. See
-       * [this link](https://cdn.rawgit.com/MrRio/jsPDF/master/examples/html2pdf/showcase_supported_html.html)
-       */
+      if (typeof options === "string") {
+        options = {
+          ch1: options
+        };
+      }
 
-      jsPDFAPI.addHTML = function (element, x, y, options, callback) {
+      var ch1 = options.ch1;
+      var ch2 = options.ch2;
+      var ch3 = options.ch3;
+      var ch4 = options.ch4;
+      var letterArray = options.pdfColorType === "draw" ? ["G", "RG", "K"] : ["g", "rg", "k"];
 
-          if (typeof html2canvas === 'undefined' && typeof rasterizeHTML === 'undefined') throw new Error('You need either ' + 'https://github.com/niklasvh/html2canvas' + ' or https://github.com/cburgmer/rasterizeHTML.js');
+      if (typeof ch1 === "string" && ch1.charAt(0) !== "#") {
+        var rgbColor = new RGBColor(ch1);
 
-          if (typeof x !== 'number') {
-              options = x;
-              callback = y;
-          }
+        if (rgbColor.ok) {
+          ch1 = rgbColor.toHex();
+        } else if (!/^\d*\.?\d*$/.test(ch1)) {
+          throw new Error('Invalid color "' + ch1 + '" passed to jsPDF.encodeColorString.');
+        }
+      } //convert short rgb to long form
 
-          if (typeof options === 'function') {
-              callback = options;
-              options = null;
-          }
 
-          if (typeof callback !== 'function') {
-              callback = function callback() {};
-          }
+      if (typeof ch1 === "string" && /^#[0-9A-Fa-f]{3}$/.test(ch1)) {
+        ch1 = "#" + ch1[1] + ch1[1] + ch1[2] + ch1[2] + ch1[3] + ch1[3];
+      }
 
-          var I = this.internal,
-              K = I.scaleFactor,
-              W = I.pageSize.getWidth(),
-              H = I.pageSize.getHeight();
-
-          options = options || {};
-          options.onrendered = function (obj) {
-              x = parseInt(x) || 0;
-              y = parseInt(y) || 0;
-              var dim = options.dim || {};
-              var margin = Object.assign({ top: 0, right: 0, bottom: 0, left: 0, useFor: 'content' }, options.margin);
-              var h = dim.h || Math.min(H, obj.height / K);
-              var w = dim.w || Math.min(W, obj.width / K) - x;
-
-              var format = options.format || 'JPEG';
-              var imageCompression = options.imageCompression || 'SLOW';
-
-              var notFittingHeight = obj.height > H - margin.top - margin.bottom;
-
-              if (notFittingHeight && options.pagesplit) {
-                  var cropArea = function cropArea(parmObj, parmX, parmY, parmWidth, parmHeight) {
-                      var canvas = document.createElement('canvas');
-                      canvas.height = parmHeight;
-                      canvas.width = parmWidth;
-                      var ctx = canvas.getContext('2d');
-                      ctx.mozImageSmoothingEnabled = false;
-                      ctx.webkitImageSmoothingEnabled = false;
-                      ctx.msImageSmoothingEnabled = false;
-                      ctx.imageSmoothingEnabled = false;
-                      ctx.fillStyle = options.backgroundColor || '#ffffff';
-                      ctx.fillRect(0, 0, parmWidth, parmHeight);
-                      ctx.drawImage(parmObj, parmX, parmY, parmWidth, parmHeight, 0, 0, parmWidth, parmHeight);
-                      return canvas;
-                  };
-                  var crop = function () {
-                      var cy = 0;
-                      var cx = 0;
-                      var position = {};
-                      var isOverWide = false;
-                      var width;
-                      var height;
-                      while (1) {
-                          cx = 0;
-                          position.top = cy !== 0 ? margin.top : y;
-                          position.left = cy !== 0 ? margin.left : x;
-                          isOverWide = (W - margin.left - margin.right) * K < obj.width;
-                          if (margin.useFor === "content") {
-                              if (cy === 0) {
-                                  width = Math.min((W - margin.left) * K, obj.width);
-                                  height = Math.min((H - margin.top) * K, obj.height - cy);
-                              } else {
-                                  width = Math.min(W * K, obj.width);
-                                  height = Math.min(H * K, obj.height - cy);
-                                  position.top = 0;
-                              }
-                          } else {
-                              width = Math.min((W - margin.left - margin.right) * K, obj.width);
-                              height = Math.min((H - margin.bottom - margin.top) * K, obj.height - cy);
-                          }
-                          if (isOverWide) {
-                              while (1) {
-                                  if (margin.useFor === "content") {
-                                      if (cx === 0) {
-                                          width = Math.min((W - margin.left) * K, obj.width);
-                                      } else {
-                                          width = Math.min(W * K, obj.width - cx);
-                                          position.left = 0;
-                                      }
-                                  }
-                                  var canvas = cropArea(obj, cx, cy, width, height);
-                                  var args = [canvas, position.left, position.top, canvas.width / K, canvas.height / K, format, null, imageCompression];
-                                  this.addImage.apply(this, args);
-                                  cx += width;
-                                  if (cx >= obj.width) {
-                                      break;
-                                  }
-                                  this.addPage();
-                              }
-                          } else {
-                              var canvas = cropArea(obj, 0, cy, width, height);
-                              var args = [canvas, position.left, position.top, canvas.width / K, canvas.height / K, format, null, imageCompression];
-                              this.addImage.apply(this, args);
-                          }
-                          cy += height;
-                          if (cy >= obj.height) {
-                              break;
-                          }
-                          this.addPage();
-                      }
-                      callback(w, cy, null, args);
-                  }.bind(this);
-                  if (obj.nodeName === 'CANVAS') {
-                      var img = new Image();
-                      img.onload = crop;
-                      img.src = obj.toDataURL("image/png");
-                      obj = img;
-                  } else {
-                      crop();
-                  }
-              } else {
-                  var alias = Math.random().toString(35);
-                  var args = [obj, x, y, w, h, format, alias, imageCompression];
+      if (typeof ch1 === "string" && /^#[0-9A-Fa-f]{6}$/.test(ch1)) {
+        var hex = parseInt(ch1.substr(1), 16);
+        ch1 = hex >> 16 & 255;
+        ch2 = hex >> 8 & 255;
+        ch3 = hex & 255;
+      }
+
+      if (typeof ch2 === "undefined" || typeof ch4 === "undefined" && ch1 === ch2 && ch2 === ch3) {
+        // Gray color space.
+        if (typeof ch1 === "string") {
+          color = ch1 + " " + letterArray[0];
+        } else {
+          switch (options.precision) {
+            case 2:
+              color = f2(ch1 / 255) + " " + letterArray[0];
+              break;
+
+            case 3:
+            default:
+              color = f3(ch1 / 255) + " " + letterArray[0];
+          }
+        }
+      } else if (typeof ch4 === "undefined" || _typeof(ch4) === "object") {
+        // assume RGBA
+        if (ch4 && !isNaN(ch4.a)) {
+          //TODO Implement transparency.
+          //WORKAROUND use white for now, if transparent, otherwise handle as rgb
+          if (ch4.a === 0) {
+            color = ["1.", "1.", "1.", letterArray[1]].join(" ");
+            return color;
+          }
+        } // assume RGB
 
-                  this.addImage.apply(this, args);
 
-                  callback(w, h, alias, args);
-              }
-          }.bind(this);
+        if (typeof ch1 === "string") {
+          color = [ch1, ch2, ch3, letterArray[1]].join(" ");
+        } else {
+          switch (options.precision) {
+            case 2:
+              color = [f2(ch1 / 255), f2(ch2 / 255), f2(ch3 / 255), letterArray[1]].join(" ");
+              break;
 
-          if (typeof html2canvas !== 'undefined' && !options.rstz) {
-              return html2canvas(element, options);
+            default:
+            case 3:
+              color = [f3(ch1 / 255), f3(ch2 / 255), f3(ch3 / 255), letterArray[1]].join(" ");
           }
+        }
+      } else {
+        // assume CMYK
+        if (typeof ch1 === "string") {
+          color = [ch1, ch2, ch3, ch4, letterArray[2]].join(" ");
+        } else {
+          switch (options.precision) {
+            case 2:
+              color = [f2(ch1), f2(ch2), f2(ch3), f2(ch4), letterArray[2]].join(" ");
+              break;
 
-          if (typeof rasterizeHTML !== 'undefined') {
-              var meth = 'drawDocument';
-              if (typeof element === 'string') {
-                  meth = /^http/.test(element) ? 'drawURL' : 'drawHTML';
-              }
-              options.width = options.width || W * K;
-              return rasterizeHTML[meth](element, void 0, options).then(function (r) {
-                  options.onrendered(r.image);
-              }, function (e) {
-                  callback(null, e);
-              });
+            case 3:
+            default:
+              color = [f3(ch1), f3(ch2), f3(ch3), f3(ch4), letterArray[2]].join(" ");
           }
+        }
+      }
 
-          return null;
+      return color;
+    };
+
+    var getFilters = API.__private__.getFilters = function () {
+      return filters;
+    };
+
+    var putStream = API.__private__.putStream = function (options) {
+      options = options || {};
+      var data = options.data || "";
+      var filters = options.filters || getFilters();
+      var alreadyAppliedFilters = options.alreadyAppliedFilters || [];
+      var addLength1 = options.addLength1 || false;
+      var valueOfLength1 = data.length;
+      var objectId = options.objectId;
+
+      var encryptor = function encryptor(data) {
+        return data;
       };
-  })(jsPDF.API);
 
-  /** @preserve
-   * jsPDF addImage plugin
-   * Copyright (c) 2012 Jason Siefken, https://github.com/siefkenj/
-   *               2013 Chris Dowling, https://github.com/gingerchris
-   *               2013 Trinh Ho, https://github.com/ineedfat
-   *               2013 Edwin Alejandro Perez, https://github.com/eaparango
-   *               2013 Norah Smith, https://github.com/burnburnrocket
-   *               2014 Diego Casorran, https://github.com/diegocr
-   *               2014 James Robb, https://github.com/jamesbrobb
-   *
-   * 
-   */
-  (function (jsPDFAPI) {
+      if (encryptionOptions !== null && typeof objectId == "undefined") {
+        throw new Error("ObjectId must be passed to putStream for file encryption");
+      }
 
-  	var namespace = 'addImage_';
-
-  	var imageFileTypeHeaders = {
-  		PNG: [[0x89, 0x50, 0x4e, 0x47]],
-  		TIFF: [[0x4D, 0x4D, 0x00, 0x2A], //Motorola
-  		[0x49, 0x49, 0x2A, 0x00] //Intel
-  		],
-  		JPEG: [[0xFF, 0xD8, 0xFF, 0xE0, undefined, undefined, 0x4A, 0x46, 0x49, 0x46, 0x00], //JFIF
-  		[0xFF, 0xD8, 0xFF, 0xE1, undefined, undefined, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00] //Exif
-  		],
-  		JPEG2000: [[0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20]],
-  		GIF87a: [[0x47, 0x49, 0x46, 0x38, 0x37, 0x61]],
-  		GIF89a: [[0x47, 0x49, 0x46, 0x38, 0x39, 0x61]],
-  		BMP: [[0x42, 0x4D], //BM - Windows 3.1x, 95, NT, ... etc.
-  		[0x42, 0x41], //BA - OS/2 struct bitmap array
-  		[0x43, 0x49], //CI - OS/2 struct color icon
-  		[0x43, 0x50], //CP - OS/2 const color pointer
-  		[0x49, 0x43], //IC - OS/2 struct icon
-  		[0x50, 0x54] //PT - OS/2 pointer
-  		]
-  		/**
-    * Recognize filetype of Image by magic-bytes
-    * 
-    * https://en.wikipedia.org/wiki/List_of_file_signatures
-    *
-    * @name getImageFileTypeByImageData
-    * @public
-    * @function
-    * @param {String} imageData as base64 encoded DataUrl
-    * @param {String} format of file if filetype-recognition fails, e.g. 'JPEG'
-    * 
-    * @returns {String} filetype of Image
-    * @methodOf jsPDF#
-    */
-  	};jsPDFAPI.getImageFileTypeByImageData = function (imageData, fallbackFormat) {
-  		fallbackFormat = fallbackFormat || 'UNKNOWN';
-  		var i;
-  		var j;
-  		var result = 'UNKNOWN';
-  		var headerSchemata;
-  		var compareResult;
-  		var fileType;
-
-  		for (fileType in imageFileTypeHeaders) {
-  			headerSchemata = imageFileTypeHeaders[fileType];
-  			for (i = 0; i < headerSchemata.length; i += 1) {
-  				compareResult = true;
-  				for (j = 0; j < headerSchemata[i].length; j += 1) {
-  					if (headerSchemata[i][j] === undefined) {
-  						continue;
-  					}
-  					if (headerSchemata[i][j] !== imageData.charCodeAt(j)) {
-  						compareResult = false;
-  						break;
-  					}
-  				}
-  				if (compareResult === true) {
-  					result = fileType;
-  					break;
-  				}
-  			}
-  		}
-  		if (result === 'UNKNOWN' && fallbackFormat !== 'UNKNOWN') {
-  			console.warn('FileType of Image not recognized. Processing image as "' + fallbackFormat + '".');
-  			result = fallbackFormat;
-  		}
-  		return result;
-  	};
-
-  	// Image functionality ported from pdf.js
-  	var putImage = function putImage(img) {
-
-  		var objectNumber = this.internal.newObject(),
-  		    out = this.internal.write,
-  		    putStream = this.internal.putStream;
-
-  		img['n'] = objectNumber;
-
-  		out('<</Type /XObject');
-  		out('/Subtype /Image');
-  		out('/Width ' + img['w']);
-  		out('/Height ' + img['h']);
-  		if (img['cs'] === this.color_spaces.INDEXED) {
-  			out('/ColorSpace [/Indexed /DeviceRGB '
-  			// if an indexed png defines more than one colour with transparency, we've created a smask
-  			+ (img['pal'].length / 3 - 1) + ' ' + ('smask' in img ? objectNumber + 2 : objectNumber + 1) + ' 0 R]');
-  		} else {
-  			out('/ColorSpace /' + img['cs']);
-  			if (img['cs'] === this.color_spaces.DEVICE_CMYK) {
-  				out('/Decode [1 0 1 0 1 0 1 0]');
-  			}
-  		}
-  		out('/BitsPerComponent ' + img['bpc']);
-  		if ('f' in img) {
-  			out('/Filter /' + img['f']);
-  		}
-  		if ('dp' in img) {
-  			out('/DecodeParms <<' + img['dp'] + '>>');
-  		}
-  		if ('trns' in img && img['trns'].constructor == Array) {
-  			var trns = '',
-  			    i = 0,
-  			    len = img['trns'].length;
-  			for (; i < len; i++) {
-  				trns += img['trns'][i] + ' ' + img['trns'][i] + ' ';
-  			}out('/Mask [' + trns + ']');
-  		}
-  		if ('smask' in img) {
-  			out('/SMask ' + (objectNumber + 1) + ' 0 R');
-  		}
-  		out('/Length ' + img['data'].length + '>>');
-
-  		putStream(img['data']);
-
-  		out('endobj');
-
-  		// Soft mask
-  		if ('smask' in img) {
-  			var dp = '/Predictor ' + img['p'] + ' /Colors 1 /BitsPerComponent ' + img['bpc'] + ' /Columns ' + img['w'];
-  			var smask = { 'w': img['w'], 'h': img['h'], 'cs': 'DeviceGray', 'bpc': img['bpc'], 'dp': dp, 'data': img['smask'] };
-  			if ('f' in img) smask.f = img['f'];
-  			putImage.call(this, smask);
-  		}
-
-  		//Palette
-  		if (img['cs'] === this.color_spaces.INDEXED) {
-
-  			this.internal.newObject();
-  			//out('<< /Filter / ' + img['f'] +' /Length ' + img['pal'].length + '>>');
-  			//putStream(zlib.compress(img['pal']));
-  			out('<< /Length ' + img['pal'].length + '>>');
-  			putStream(this.arrayBufferToBinaryString(new Uint8Array(img['pal'])));
-  			out('endobj');
-  		}
-  	},
-  	    putResourcesCallback = function putResourcesCallback() {
-  		var images = this.internal.collections[namespace + 'images'];
-  		for (var i in images) {
-  			putImage.call(this, images[i]);
-  		}
-  	},
-  	    putXObjectsDictCallback = function putXObjectsDictCallback() {
-  		var images = this.internal.collections[namespace + 'images'],
-  		    out = this.internal.write,
-  		    image;
-  		for (var i in images) {
-  			image = images[i];
-  			out('/I' + image['i'], image['n'], '0', 'R');
-  		}
-  	},
-  	    checkCompressValue = function checkCompressValue(value) {
-  		if (value && typeof value === 'string') value = value.toUpperCase();
-  		return value in jsPDFAPI.image_compression ? value : jsPDFAPI.image_compression.NONE;
-  	},
-  	    getImages = function getImages() {
-  		var images = this.internal.collections[namespace + 'images'];
-  		//first run, so initialise stuff
-  		if (!images) {
-  			this.internal.collections[namespace + 'images'] = images = {};
-  			this.internal.events.subscribe('putResources', putResourcesCallback);
-  			this.internal.events.subscribe('putXobjectDict', putXObjectsDictCallback);
-  		}
-
-  		return images;
-  	},
-  	    getImageIndex = function getImageIndex(images) {
-  		var imageIndex = 0;
-
-  		if (images) {
-  			// this is NOT the first time this method is ran on this instance of jsPDF object.
-  			imageIndex = Object.keys ? Object.keys(images).length : function (o) {
-  				var i = 0;
-  				for (var e in o) {
-  					if (o.hasOwnProperty(e)) {
-  						i++;
-  					}
-  				}
-  				return i;
-  			}(images);
-  		}
-
-  		return imageIndex;
-  	},
-  	    notDefined = function notDefined(value) {
-  		return typeof value === 'undefined' || value === null || value.length === 0;
-  	},
-  	    generateAliasFromData = function generateAliasFromData(data) {
-  		return typeof data === 'string' && jsPDFAPI.sHashCode(data);
-  	},
-  	    isImageTypeSupported = function isImageTypeSupported(type) {
-  		return typeof jsPDFAPI["process" + type.toUpperCase()] === "function";
-  	},
-  	    isDOMElement = function isDOMElement(object) {
-  		return (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && object.nodeType === 1;
-  	},
-  	    createDataURIFromElement = function createDataURIFromElement(element, format) {
-
-  		//if element is an image which uses data url definition, just return the dataurl
-  		if (element.nodeName === 'IMG' && element.hasAttribute('src')) {
-  			var src = '' + element.getAttribute('src');
-  			if (src.indexOf('data:image/') === 0) return src;
-
-  			// only if the user doesn't care about a format
-  			if (!format && /\.png(?:[?#].*)?$/i.test(src)) format = 'png';
-  		}
-
-  		if (element.nodeName === 'CANVAS') {
-  			var canvas = element;
-  		} else {
-  			var canvas = document.createElement('canvas');
-  			canvas.width = element.clientWidth || element.width;
-  			canvas.height = element.clientHeight || element.height;
-
-  			var ctx = canvas.getContext('2d');
-  			if (!ctx) {
-  				throw 'addImage requires canvas to be supported by browser.';
-  			}
-  			ctx.drawImage(element, 0, 0, canvas.width, canvas.height);
-  		}
-  		return canvas.toDataURL(('' + format).toLowerCase() == 'png' ? 'image/png' : 'image/jpeg');
-  	},
-  	    checkImagesForAlias = function checkImagesForAlias(alias, images) {
-  		var cached_info;
-  		if (images) {
-  			for (var e in images) {
-  				if (alias === images[e].alias) {
-  					cached_info = images[e];
-  					break;
-  				}
-  			}
-  		}
-  		return cached_info;
-  	},
-  	    determineWidthAndHeight = function determineWidthAndHeight(w, h, info) {
-  		if (!w && !h) {
-  			w = -96;
-  			h = -96;
-  		}
-  		if (w < 0) {
-  			w = -1 * info['w'] * 72 / w / this.internal.scaleFactor;
-  		}
-  		if (h < 0) {
-  			h = -1 * info['h'] * 72 / h / this.internal.scaleFactor;
-  		}
-  		if (w === 0) {
-  			w = h * info['w'] / info['h'];
-  		}
-  		if (h === 0) {
-  			h = w * info['h'] / info['w'];
-  		}
-
-  		return [w, h];
-  	},
-  	    writeImageToPDF = function writeImageToPDF(x, y, w, h, info, index, images, rotation) {
-  		var dims = determineWidthAndHeight.call(this, w, h, info),
-  		    coord = this.internal.getCoordinateString,
-  		    vcoord = this.internal.getVerticalCoordinateString;
-
-  		w = dims[0];
-  		h = dims[1];
-
-  		images[index] = info;
-
-  		if (rotation) {
-  			rotation *= Math.PI / 180;
-  			var c = Math.cos(rotation);
-  			var s = Math.sin(rotation);
-  			//like in pdf Reference do it 4 digits instead of 2
-  			var f4 = function f4(number) {
-  				return number.toFixed(4);
-  			};
-  			var rotationTransformationMatrix = [f4(c), f4(s), f4(s * -1), f4(c), 0, 0, 'cm'];
-  		}
-  		this.internal.write('q'); //Save graphics state
-  		if (rotation) {
-  			this.internal.write([1, '0', '0', 1, coord(x), vcoord(y + h), 'cm'].join(' ')); //Translate
-  			this.internal.write(rotationTransformationMatrix.join(' ')); //Rotate
-  			this.internal.write([coord(w), '0', '0', coord(h), '0', '0', 'cm'].join(' ')); //Scale
-  		} else {
-  			this.internal.write([coord(w), '0', '0', coord(h), coord(x), vcoord(y + h), 'cm'].join(' ')); //Translate and Scale
-  		}
-  		this.internal.write('/I' + info['i'] + ' Do'); //Paint Image
-  		this.internal.write('Q'); //Restore graphics state
-  	};
-
-  	/**
-    * COLOR SPACES
-    */
-  	jsPDFAPI.color_spaces = {
-  		DEVICE_RGB: 'DeviceRGB',
-  		DEVICE_GRAY: 'DeviceGray',
-  		DEVICE_CMYK: 'DeviceCMYK',
-  		CAL_GREY: 'CalGray',
-  		CAL_RGB: 'CalRGB',
-  		LAB: 'Lab',
-  		ICC_BASED: 'ICCBased',
-  		INDEXED: 'Indexed',
-  		PATTERN: 'Pattern',
-  		SEPARATION: 'Separation',
-  		DEVICE_N: 'DeviceN'
-  	};
-
-  	/**
-    * DECODE METHODS
-    */
-  	jsPDFAPI.decode = {
-  		DCT_DECODE: 'DCTDecode',
-  		FLATE_DECODE: 'FlateDecode',
-  		LZW_DECODE: 'LZWDecode',
-  		JPX_DECODE: 'JPXDecode',
-  		JBIG2_DECODE: 'JBIG2Decode',
-  		ASCII85_DECODE: 'ASCII85Decode',
-  		ASCII_HEX_DECODE: 'ASCIIHexDecode',
-  		RUN_LENGTH_DECODE: 'RunLengthDecode',
-  		CCITT_FAX_DECODE: 'CCITTFaxDecode'
-  	};
-
-  	/**
-    * IMAGE COMPRESSION TYPES
-    */
-  	jsPDFAPI.image_compression = {
-  		NONE: 'NONE',
-  		FAST: 'FAST',
-  		MEDIUM: 'MEDIUM',
-  		SLOW: 'SLOW'
-  	};
-
-  	jsPDFAPI.sHashCode = function (str) {
-  		str = str || "";
-  		return Array.prototype.reduce && str.split("").reduce(function (a, b) {
-  			a = (a << 5) - a + b.charCodeAt(0);return a & a;
-  		}, 0);
-  	};
-
-  	jsPDFAPI.isString = function (object) {
-  		return typeof object === 'string';
-  	};
-  	/**
-   * Validates if given String is a valid Base64-String
-   *
-   * @name validateStringAsBase64
-   * @public
-   * @function
-   * @param {String} possible Base64-String
-   * 
-   * @returns {boolean}
-   * @methodOf jsPDF#
-   */
-  	jsPDFAPI.validateStringAsBase64 = function (possibleBase64String) {
-  		possibleBase64String = possibleBase64String || '';
-
-  		var result = true;
-
-  		if (possibleBase64String.length % 4 !== 0) {
-  			result = false;
-  		}
-
-  		if (/[A-Za-z0-9\/]+/.test(possibleBase64String.substr(0, possibleBase64String.length - 2)) === false) {
-  			result = false;
-  		}
-
-  		if (/[A-Za-z0-9\/][A-Za-z0-9+\/]|[A-Za-z0-9+\/]=|==/.test(possibleBase64String.substr(-2)) === false) {
-  			result = false;
-  		}
-  		return result;
-  	};
-
-  	/**
-    * Strips out and returns info from a valid base64 data URI
-    * @param {String[dataURI]} a valid data URI of format 'data:[<MIME-type>][;base64],<data>'
-    * @returns an Array containing the following
-    * [0] the complete data URI
-    * [1] <MIME-type>
-    * [2] format - the second part of the mime-type i.e 'png' in 'image/png'
-    * [4] <data>
-    */
-  	jsPDFAPI.extractInfoFromBase64DataURI = function (dataURI) {
-  		return (/^data:([\w]+?\/([\w]+?));base64,(.+)$/g.exec(dataURI)
-  		);
-  	};
-
-  	/**
-    * Check to see if ArrayBuffer is supported
-    * 
-    * @returns {boolean}
-      * @methodOf jsPDF#
-    */
-  	jsPDFAPI.supportsArrayBuffer = function () {
-  		return typeof ArrayBuffer !== 'undefined' && typeof Uint8Array !== 'undefined';
-  	};
-
-  	/**
-    * Tests supplied object to determine if ArrayBuffer
-    * @param {Object[object]}
-    * 
-    * @returns {boolean}
-    * @methodOf jsPDF#
-    */
-  	jsPDFAPI.isArrayBuffer = function (object) {
-  		if (!this.supportsArrayBuffer()) return false;
-  		return object instanceof ArrayBuffer;
-  	};
-
-  	/**
-    * Tests supplied object to determine if it implements the ArrayBufferView (TypedArray) interface
-    * @param {Object[object]}
-    */
-  	jsPDFAPI.isArrayBufferView = function (object) {
-  		if (!this.supportsArrayBuffer()) return false;
-  		if (typeof Uint32Array === 'undefined') return false;
-  		return object instanceof Int8Array || object instanceof Uint8Array || typeof Uint8ClampedArray !== 'undefined' && object instanceof Uint8ClampedArray || object instanceof Int16Array || object instanceof Uint16Array || object instanceof Int32Array || object instanceof Uint32Array || object instanceof Float32Array || object instanceof Float64Array;
-  	};
-
-  	/**
-   * Convert the Buffer to a Binary String
-   *
-   * @name binaryStringToUint8Array
-   * @public
-   * @function
-   * @param {ArrayBuffer} BinaryString with ImageData
-   * 
-   * @returns {Uint8Array}
-   */
-  	jsPDFAPI.binaryStringToUint8Array = function (binary_string) {
-  		/*
-     * not sure how efficient this will be will bigger files. Is there a native method?
-     */
-  		var len = binary_string.length;
-  		var bytes = new Uint8Array(len);
-  		for (var i = 0; i < len; i++) {
-  			bytes[i] = binary_string.charCodeAt(i);
-  		}
-  		return bytes;
-  	};
-
-  	/**
-   * Convert the Buffer to a Binary String
-   *
-   * @name arrayBufferToBinaryString
-   * @public
-   * @function
-   * @param {ArrayBuffer} ArrayBuffer with ImageData
-   * 
-   * @returns {String}
-   */
-  	jsPDFAPI.arrayBufferToBinaryString = function (buffer) {
-
-  		if (typeof atob === "function") {
-  			return atob(this.arrayBufferToBase64(buffer));
-  		}
-
-  		if (typeof TextDecoder === "function") {
-  			var decoder = new TextDecoder('ascii');
-  			// test if the encoding is supported
-  			if (decoder.encoding === 'ascii') {
-  				return decoder.decode(buffer);
-  			}
-  		}
-
-  		//Fallback-solution
-  		var data = this.isArrayBuffer(buffer) ? buffer : new Uint8Array(buffer);
-  		var chunkSizeForSlice = 0x5000;
-  		var binary_string = '';
-  		var slicesCount = Math.ceil(data.byteLength / chunkSizeForSlice);
-  		for (var i = 0; i < slicesCount; i++) {
-  			binary_string += String.fromCharCode.apply(null, data.slice(i * chunkSizeForSlice, i * chunkSizeForSlice + chunkSizeForSlice));
-  		}
-  		return binary_string;
-  	};
-
-  	/**
-      * Converts an ArrayBuffer directly to base64
-      *
-      * Taken from  http://jsperf.com/encoding-xhr-image-data/31
-      *
-      * Need to test if this is a better solution for larger files
-      *
-      * @name arrayBufferToBase64
-      * @public
-      * @function
-      * 
-      * @returns {String}
-      */
-  	jsPDFAPI.arrayBufferToBase64 = function (arrayBuffer) {
-  		var base64 = '';
-  		var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
-
-  		var bytes = new Uint8Array(arrayBuffer);
-  		var byteLength = bytes.byteLength;
-  		var byteRemainder = byteLength % 3;
-  		var mainLength = byteLength - byteRemainder;
-
-  		var a, b, c, d;
-  		var chunk;
-
-  		// Main loop deals with bytes in chunks of 3
-  		for (var i = 0; i < mainLength; i = i + 3) {
-  			// Combine the three bytes into a single integer
-  			chunk = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
-
-  			// Use bitmasks to extract 6-bit segments from the triplet
-  			a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18
-  			b = (chunk & 258048) >> 12; // 258048   = (2^6 - 1) << 12
-  			c = (chunk & 4032) >> 6; // 4032     = (2^6 - 1) << 6
-  			d = chunk & 63; // 63       = 2^6 - 1
-
-  			// Convert the raw binary segments to the appropriate ASCII encoding
-  			base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d];
-  		}
-
-  		// Deal with the remaining bytes and padding
-  		if (byteRemainder == 1) {
-  			chunk = bytes[mainLength];
-
-  			a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2
-
-  			// Set the 4 least significant bits to zero
-  			b = (chunk & 3) << 4; // 3   = 2^2 - 1
-
-  			base64 += encodings[a] + encodings[b] + '==';
-  		} else if (byteRemainder == 2) {
-  			chunk = bytes[mainLength] << 8 | bytes[mainLength + 1];
-
-  			a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10
-  			b = (chunk & 1008) >> 4; // 1008  = (2^6 - 1) << 4
-
-  			// Set the 2 least significant bits to zero
-  			c = (chunk & 15) << 2; // 15    = 2^4 - 1
-
-  			base64 += encodings[a] + encodings[b] + encodings[c] + '=';
-  		}
-
-  		return base64;
-  	};
-
-  	/**
-      * Converts an ArrayBuffer directly to base64
-      *
-      * Taken from  http://jsperf.com/encoding-xhr-image-data/31
-      *
-      * Need to test if this is a better solution for larger files
-      *
-      * @public
-      * @function
-      * 
-      * @returns {String}
-      */
-  	jsPDFAPI.createImageInfo = function (data, wd, ht, cs, bpc, f, imageIndex, alias, dp, trns, pal, smask, p) {
-  		var info = {
-  			alias: alias,
-  			w: wd,
-  			h: ht,
-  			cs: cs,
-  			bpc: bpc,
-  			i: imageIndex,
-  			data: data
-  			// n: objectNumber will be added by putImage code
-  		};
-
-  		if (f) info.f = f;
-  		if (dp) info.dp = dp;
-  		if (trns) info.trns = trns;
-  		if (pal) info.pal = pal;
-  		if (smask) info.smask = smask;
-  		if (p) info.p = p; // predictor parameter for PNG compression
-
-  		return info;
-  	};
-  	/**
-   * Adds an Image to the PDF.
-   *
-   * @name addImage
-   * @public
-   * @function
-   * @param {String/Image-Element/Canvas-Element/Uint8Array} imageData as base64 encoded DataUrl or Image-HTMLElement or Canvas-HTMLElement
-   * @param {String} format of file if filetype-recognition fails, e.g. 'JPEG'
-   * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-   * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-   * @param {Number} width of the image (in units declared at inception of PDF document)
-   * @param {Number} height of the Image (in units declared at inception of PDF document)
-   * @param {String} alias of the image (if used multiple times)
-   * @param {String} compression of the generated JPEG, can have the values 'NONE', 'FAST', 'MEDIUM' and 'SLOW'
-   * @param {Number} rotation of the image in degrees (0-359)
-   * 
-   * @returns jsPDF
-   * @methodOf jsPDF#
-   */
-  	jsPDFAPI.addImage = function (imageData, format, x, y, w, h, alias, compression, rotation) {
-
-  		var tmpImageData = '';
-
-  		if (typeof format !== 'string') {
-  			var tmp = h;
-  			h = w;
-  			w = y;
-  			y = x;
-  			x = format;
-  			format = tmp;
-  		}
-
-  		if ((typeof imageData === 'undefined' ? 'undefined' : _typeof(imageData)) === 'object' && !isDOMElement(imageData) && "imageData" in imageData) {
-  			var options = imageData;
-
-  			imageData = options.imageData;
-  			format = options.format || format;
-  			x = options.x || x || 0;
-  			y = options.y || y || 0;
-  			w = options.w || w;
-  			h = options.h || h;
-  			alias = options.alias || alias;
-  			compression = options.compression || compression;
-  			rotation = options.rotation || options.angle || rotation;
-  		}
-
-  		if (isNaN(x) || isNaN(y)) {
-  			console.error('jsPDF.addImage: Invalid coordinates', arguments);
-  			throw new Error('Invalid coordinates passed to jsPDF.addImage');
-  		}
-
-  		var images = getImages.call(this),
-  		    info;
-
-  		if (!(info = checkImagesForAlias(imageData, images))) {
-  			var dataAsBinaryString;
-
-  			if (isDOMElement(imageData)) imageData = createDataURIFromElement(imageData, format);
-
-  			if (notDefined(alias)) alias = generateAliasFromData(imageData);
-
-  			if (!(info = checkImagesForAlias(alias, images))) {
-  				if (this.isString(imageData)) {
-  					tmpImageData = this.convertStringToImageData(imageData);
-
-  					if (tmpImageData !== '') {
-  						imageData = tmpImageData;
-  					} else {
-  						tmpImageData = this.loadImageFile(imageData);
-  						if (tmpImageData !== undefined) {
-  							imageData = tmpImageData;
-  						}
-  					}
-  				}
-  				format = this.getImageFileTypeByImageData(imageData, format);
-
-  				if (!isImageTypeSupported(format)) throw new Error('addImage does not support files of type \'' + format + '\', please ensure that a plugin for \'' + format + '\' support is added.');
-
-  				/**
-       * need to test if it's more efficient to convert all binary strings
-       * to TypedArray - or should we just leave and process as string?
-       */
-  				if (this.supportsArrayBuffer()) {
-  					// no need to convert if imageData is already uint8array
-  					if (!(imageData instanceof Uint8Array)) {
-  						dataAsBinaryString = imageData;
-  						imageData = this.binaryStringToUint8Array(imageData);
-  					}
-  				}
-
-  				info = this['process' + format.toUpperCase()](imageData, getImageIndex(images), alias, checkCompressValue(compression), dataAsBinaryString);
-
-  				if (!info) throw new Error('An unkwown error occurred whilst processing the image');
-  			}
-  		}
-  		writeImageToPDF.call(this, x, y, w, h, info, info.i, images, rotation);
-
-  		return this;
-  	};
-
-  	jsPDFAPI.convertStringToImageData = function (stringData) {
-  		var base64Info;
-  		var imageData = '';
-  		if (this.isString(stringData)) {
-  			var base64Info = this.extractInfoFromBase64DataURI(stringData);
-
-  			if (base64Info !== null) {
-  				if (jsPDFAPI.validateStringAsBase64(base64Info[3])) {
-  					imageData = atob(base64Info[3]); //convert to binary string
-  				}
-  			} else if (jsPDFAPI.validateStringAsBase64(stringData)) {
-  				imageData = atob(stringData);
-  			}
-  		}
-  		return imageData;
-  	};
-  	/**
-    * JPEG SUPPORT
-    **/
-
-  	//takes a string imgData containing the raw bytes of
-  	//a jpeg image and returns [width, height]
-  	//Algorithm from: http://www.64lines.com/jpeg-width-height
-  	var getJpegSize = function getJpegSize(imgData) {
-
-  		var width, height, numcomponents;
-  		// Verify we have a valid jpeg header 0xff,0xd8,0xff,0xe0,?,?,'J','F','I','F',0x00
-  		if (!imgData.charCodeAt(0) === 0xff || !imgData.charCodeAt(1) === 0xd8 || !imgData.charCodeAt(2) === 0xff || !imgData.charCodeAt(3) === 0xe0 || !imgData.charCodeAt(6) === 'J'.charCodeAt(0) || !imgData.charCodeAt(7) === 'F'.charCodeAt(0) || !imgData.charCodeAt(8) === 'I'.charCodeAt(0) || !imgData.charCodeAt(9) === 'F'.charCodeAt(0) || !imgData.charCodeAt(10) === 0x00) {
-  			throw new Error('getJpegSize requires a binary string jpeg file');
-  		}
-  		var blockLength = imgData.charCodeAt(4) * 256 + imgData.charCodeAt(5);
-  		var i = 4,
-  		    len = imgData.length;
-  		while (i < len) {
-  			i += blockLength;
-  			if (imgData.charCodeAt(i) !== 0xff) {
-  				throw new Error('getJpegSize could not find the size of the image');
-  			}
-  			if (imgData.charCodeAt(i + 1) === 0xc0 || //(SOF) Huffman  - Baseline DCT
-  			imgData.charCodeAt(i + 1) === 0xc1 || //(SOF) Huffman  - Extended sequential DCT
-  			imgData.charCodeAt(i + 1) === 0xc2 || // Progressive DCT (SOF2)
-  			imgData.charCodeAt(i + 1) === 0xc3 || // Spatial (sequential) lossless (SOF3)
-  			imgData.charCodeAt(i + 1) === 0xc4 || // Differential sequential DCT (SOF5)
-  			imgData.charCodeAt(i + 1) === 0xc5 || // Differential progressive DCT (SOF6)
-  			imgData.charCodeAt(i + 1) === 0xc6 || // Differential spatial (SOF7)
-  			imgData.charCodeAt(i + 1) === 0xc7) {
-  				height = imgData.charCodeAt(i + 5) * 256 + imgData.charCodeAt(i + 6);
-  				width = imgData.charCodeAt(i + 7) * 256 + imgData.charCodeAt(i + 8);
-  				numcomponents = imgData.charCodeAt(i + 9);
-  				return [width, height, numcomponents];
-  			} else {
-  				i += 2;
-  				blockLength = imgData.charCodeAt(i) * 256 + imgData.charCodeAt(i + 1);
-  			}
-  		}
-  	},
-  	    getJpegSizeFromBytes = function getJpegSizeFromBytes(data) {
-
-  		var hdr = data[0] << 8 | data[1];
-
-  		if (hdr !== 0xFFD8) throw new Error('Supplied data is not a JPEG');
-
-  		var len = data.length,
-  		    block = (data[4] << 8) + data[5],
-  		    pos = 4,
-  		    bytes,
-  		    width,
-  		    height,
-  		    numcomponents;
-
-  		while (pos < len) {
-  			pos += block;
-  			bytes = readBytes(data, pos);
-  			block = (bytes[2] << 8) + bytes[3];
-  			if ((bytes[1] === 0xC0 || bytes[1] === 0xC2) && bytes[0] === 0xFF && block > 7) {
-  				bytes = readBytes(data, pos + 5);
-  				width = (bytes[2] << 8) + bytes[3];
-  				height = (bytes[0] << 8) + bytes[1];
-  				numcomponents = bytes[4];
-  				return { width: width, height: height, numcomponents: numcomponents };
-  			}
-
-  			pos += 2;
-  		}
-
-  		throw new Error('getJpegSizeFromBytes could not find the size of the image');
-  	},
-  	    readBytes = function readBytes(data, offset) {
-  		return data.subarray(offset, offset + 5);
-  	};
-
-  	jsPDFAPI.processJPEG = function (data, index, alias, compression, dataAsBinaryString, colorSpace) {
-
-  		var filter = this.decode.DCT_DECODE,
-  		    bpc = 8,
-  		    dims;
-
-  		if (!this.isString(data) && !this.isArrayBuffer(data) && !this.isArrayBufferView(data)) {
-  			return null;
-  		}
-
-  		if (this.isString(data)) {
-  			dims = getJpegSize(data);
-  		}
-
-  		if (this.isArrayBuffer(data)) {
-  			data = new Uint8Array(data);
-  		}
-  		if (this.isArrayBufferView(data)) {
-
-  			dims = getJpegSizeFromBytes(data);
-
-  			// if we already have a stored binary string rep use that
-  			data = dataAsBinaryString || this.arrayBufferToBinaryString(data);
-  		}
-
-  		if (colorSpace === undefined) {
-  			switch (dims.numcomponents) {
-  				case 1:
-  					colorSpace = this.color_spaces.DEVICE_GRAY;
-  					break;
-  				case 4:
-  					colorSpace = this.color_spaces.DEVICE_CMYK;
-  					break;
-  				default:
-  				case 3:
-  					colorSpace = this.color_spaces.DEVICE_RGB;
-  					break;
-  			}
-  		}
-
-  		return this.createImageInfo(data, dims.width, dims.height, colorSpace, bpc, filter, index, alias);
-  	};
-
-  	jsPDFAPI.processJPG = function () /*data, index, alias, compression, dataAsBinaryString*/{
-  		return this.processJPEG.apply(this, arguments);
-  	};
-
-  	jsPDFAPI.loadImageFile = function (path, sync, callback) {
-  		sync = sync || true;
-  		callback = callback || function () {};
-  		var isNode = Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
-
-  		var xhrMethod = function xhrMethod(url, sync, callback) {
-  			var req = new XMLHttpRequest();
-  			var byteArray = [];
-  			var i = 0;
-
-  			var sanitizeUnicode = function sanitizeUnicode(data) {
-  				var dataLength = data.length;
-  				var StringFromCharCode = String.fromCharCode;
-
-  				//Transform Unicode to ASCII
-  				for (i = 0; i < dataLength; i += 1) {
-  					byteArray.push(StringFromCharCode(data.charCodeAt(i) & 0xff));
-  				}
-  				return byteArray.join("");
-  			};
-
-  			req.open('GET', url, !sync);
-  			// XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
-  			req.overrideMimeType('text\/plain; charset=x-user-defined');
-
-  			if (sync === false) {
-  				req.onload = function () {
-  					return sanitizeUnicode(this.responseText);
-  				};
-  			}
-  			req.send(null);
-
-  			if (req.status !== 200) {
-  				console.warn('Unable to load file "' + url + '"');
-  				return;
-  			}
-
-  			if (sync) {
-  				return sanitizeUnicode(req.responseText);
-  			}
-  		};
-
-  		//we have a browser and probably no CORS-Problem
-  		if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) !== undefined && (typeof location === 'undefined' ? 'undefined' : _typeof(location)) === "object" && location.protocol.substr(0, 4) === "http") {
-  			return xhrMethod(path, sync, callback);
-  		}
-  	};
-
-  	jsPDFAPI.getImageProperties = function (imageData) {
-  		var info;
-  		var tmpImageData = '';
-  		var format;
-
-  		if (isDOMElement(imageData)) {
-  			imageData = createDataURIFromElement(imageData);
-  		}
-
-  		if (this.isString(imageData)) {
-  			tmpImageData = this.convertStringToImageData(imageData);
-
-  			if (tmpImageData !== '') {
-  				imageData = tmpImageData;
-  			} else {
-  				tmpImageData = this.loadImageFile(imageData);
-  				if (tmpImageData !== undefined) {
-  					imageData = tmpImageData;
-  				}
-  			}
-  		}
-  		format = this.getImageFileTypeByImageData(imageData);
-
-  		if (!isImageTypeSupported(format)) throw new Error('addImage does not support files of type \'' + format + '\', please ensure that a plugin for \'' + format + '\' support is added.');
-
-  		/**
-     * need to test if it's more efficient to convert all binary strings
-     * to TypedArray - or should we just leave and process as string?
-     */
-  		if (this.supportsArrayBuffer()) {
-  			// no need to convert if imageData is already uint8array
-  			if (!(imageData instanceof Uint8Array)) {
-  				imageData = this.binaryStringToUint8Array(imageData);
-  			}
-  		}
-
-  		info = this['process' + format.toUpperCase()](imageData);
-
-  		if (!info) {
-  			throw new Error('An unkwown error occurred whilst processing the image');
-  		}
-
-  		return {
-  			fileType: format,
-  			width: info.w,
-  			height: info.h,
-  			colorSpace: info.cs,
-  			compressionMode: info.f,
-  			bitsPerComponent: info.bpc
-  		};
-  	};
-  })(jsPDF.API);
+      if (encryptionOptions !== null) {
+        encryptor = encryption.encryptor(objectId, 0);
+      }
 
-  /**
-   * jsPDF Annotations PlugIn
-   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
+      var processedData = {};
 
-  /**
-   * There are many types of annotations in a PDF document. Annotations are placed
-   * on a page at a particular location. They are not 'attached' to an object.
-   * <br />
-   * This plugin current supports <br />
-   * <li> Goto Page (set pageNumber and top in options)
-   * <li> Goto Name (set name and top in options)
-   * <li> Goto URL (set url in options)
-   * <p>
-   * 	The destination magnification factor can also be specified when goto is a page number or a named destination. (see documentation below)
-   *  (set magFactor in options).  XYZ is the default.
-   * </p>
-   * <p>
-   *  Links, Text, Popup, and FreeText are supported.
-   * </p>
-   * <p>
-   * Options In PDF spec Not Implemented Yet
-   * <li> link border
-   * <li> named target
-   * <li> page coordinates
-   * <li> destination page scaling and layout
-   * <li> actions other than URL and GotoPage
-   * <li> background / hover actions
-   * </p>
-   */
+      if (filters === true) {
+        filters = ["FlateEncode"];
+      }
 
-  /*
-      Destination Magnification Factors
-      See PDF 1.3 Page 386 for meanings and options
-
-      [supported]
-  	XYZ (options; left top zoom)
-  	Fit (no options)
-  	FitH (options: top)
-  	FitV (options: left)
-
-  	[not supported]
-  	FitR
-  	FitB
-  	FitBH
-  	FitBV
-   */
+      var keyValues = options.additionalKeyValues || [];
 
-  (function (jsPDFAPI) {
+      if (typeof jsPDF.API.processDataByFilters !== "undefined") {
+        processedData = jsPDF.API.processDataByFilters(data, filters);
+      } else {
+        processedData = {
+          data: data,
+          reverseChain: []
+        };
+      }
 
-  	var annotationPlugin = {
-
-  		/**
-     * An array of arrays, indexed by <em>pageNumber</em>.
-     */
-  		annotations: [],
-
-  		f2: function f2(number) {
-  			return number.toFixed(2);
-  		},
-
-  		notEmpty: function notEmpty(obj) {
-  			if (typeof obj != 'undefined') {
-  				if (obj != '') {
-  					return true;
-  				}
-  			}
-  		}
-  	};
-
-  	jsPDF.API.annotationPlugin = annotationPlugin;
-
-  	jsPDF.API.events.push(['addPage', function (info) {
-  		this.annotationPlugin.annotations[info.pageNumber] = [];
-  	}]);
-
-  	jsPDFAPI.events.push(['putPage', function (info) {
-  		//TODO store annotations in pageContext so reorder/remove will not affect them.
-  		var pageAnnos = this.annotationPlugin.annotations[info.pageNumber];
-
-  		var found = false;
-  		for (var a = 0; a < pageAnnos.length && !found; a++) {
-  			var anno = pageAnnos[a];
-  			switch (anno.type) {
-  				case 'link':
-  					if (annotationPlugin.notEmpty(anno.options.url) || annotationPlugin.notEmpty(anno.options.pageNumber)) {
-  						found = true;
-  						break;
-  					}
-  				case 'reference':
-  				case 'text':
-  				case 'freetext':
-  					found = true;
-  					break;
-  			}
-  		}
-  		if (found == false) {
-  			return;
-  		}
-
-  		this.internal.write("/Annots [");
-  		var f2 = this.annotationPlugin.f2;
-  		var k = this.internal.scaleFactor;
-  		var pageHeight = this.internal.pageSize.getHeight();
-  		var pageInfo = this.internal.getPageInfo(info.pageNumber);
-  		for (var a = 0; a < pageAnnos.length; a++) {
-  			var anno = pageAnnos[a];
-
-  			switch (anno.type) {
-  				case 'reference':
-  					// References to Widget Anotations (for AcroForm Fields)
-  					this.internal.write(' ' + anno.object.objId + ' 0 R ');
-  					break;
-  				case 'text':
-  					// Create a an object for both the text and the popup
-  					var objText = this.internal.newAdditionalObject();
-  					var objPopup = this.internal.newAdditionalObject();
-
-  					var title = anno.title || 'Note';
-  					var rect = "/Rect [" + f2(anno.bounds.x * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + " " + f2((anno.bounds.x + anno.bounds.w) * k) + " " + f2((pageHeight - anno.bounds.y) * k) + "] ";
-  					line = '<</Type /Annot /Subtype /' + 'Text' + ' ' + rect + '/Contents (' + anno.contents + ')';
-  					line += ' /Popup ' + objPopup.objId + " 0 R";
-  					line += ' /P ' + pageInfo.objId + " 0 R";
-  					line += ' /T (' + title + ') >>';
-  					objText.content = line;
-
-  					var parent = objText.objId + ' 0 R';
-  					var popoff = 30;
-  					var rect = "/Rect [" + f2((anno.bounds.x + popoff) * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + " " + f2((anno.bounds.x + anno.bounds.w + popoff) * k) + " " + f2((pageHeight - anno.bounds.y) * k) + "] ";
-  					//var rect2 = "/Rect [" + f2(anno.bounds.x * k) + " " + f2((pageHeight - anno.bounds.y) * k) + " " + f2(anno.bounds.x + anno.bounds.w * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + "] ";
-  					line = '<</Type /Annot /Subtype /' + 'Popup' + ' ' + rect + ' /Parent ' + parent;
-  					if (anno.open) {
-  						line += ' /Open true';
-  					}
-  					line += ' >>';
-  					objPopup.content = line;
-
-  					this.internal.write(objText.objId, '0 R', objPopup.objId, '0 R');
-
-  					break;
-  				case 'freetext':
-  					var rect = "/Rect [" + f2(anno.bounds.x * k) + " " + f2((pageHeight - anno.bounds.y) * k) + " " + f2(anno.bounds.x + anno.bounds.w * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + "] ";
-  					var color = anno.color || '#000000';
-  					line = '<</Type /Annot /Subtype /' + 'FreeText' + ' ' + rect + '/Contents (' + anno.contents + ')';
-  					line += ' /DS(font: Helvetica,sans-serif 12.0pt; text-align:left; color:#' + color + ')';
-  					line += ' /Border [0 0 0]';
-  					line += ' >>';
-  					this.internal.write(line);
-  					break;
-  				case 'link':
-  					if (anno.options.name) {
-  						var loc = this.annotations._nameMap[anno.options.name];
-  						anno.options.pageNumber = loc.page;
-  						anno.options.top = loc.y;
-  					} else {
-  						if (!anno.options.top) {
-  							anno.options.top = 0;
-  						}
-  					}
-
-  					var rect = "/Rect [" + f2(anno.x * k) + " " + f2((pageHeight - anno.y) * k) + " " + f2((anno.x + anno.w) * k) + " " + f2((pageHeight - (anno.y + anno.h)) * k) + "] ";
-
-  					var line = '';
-  					if (anno.options.url) {
-  						line = '<</Type /Annot /Subtype /Link ' + rect + '/Border [0 0 0] /A <</S /URI /URI (' + anno.options.url + ') >>';
-  					} else if (anno.options.pageNumber) {
-  						// first page is 0
-  						var info = this.internal.getPageInfo(anno.options.pageNumber);
-  						line = '<</Type /Annot /Subtype /Link ' + rect + '/Border [0 0 0] /Dest [' + info.objId + " 0 R";
-  						anno.options.magFactor = anno.options.magFactor || "XYZ";
-  						switch (anno.options.magFactor) {
-  							case 'Fit':
-  								line += ' /Fit]';
-  								break;
-  							case 'FitH':
-  								//anno.options.top = anno.options.top || f2(pageHeight * k);
-  								line += ' /FitH ' + anno.options.top + ']';
-  								break;
-  							case 'FitV':
-  								anno.options.left = anno.options.left || 0;
-  								line += ' /FitV ' + anno.options.left + ']';
-  								break;
-  							case 'XYZ':
-  							default:
-  								var top = f2((pageHeight - anno.options.top) * k); // || f2(pageHeight * k);
-  								anno.options.left = anno.options.left || 0;
-  								// 0 or null zoom will not change zoom factor
-  								if (typeof anno.options.zoom === 'undefined') {
-  									anno.options.zoom = 0;
-  								}
-  								line += ' /XYZ ' + anno.options.left + ' ' + top + ' ' + anno.options.zoom + ']';
-  								break;
-  						}
-  					}
-  					if (line != '') {
-  						line += " >>";
-  						this.internal.write(line);
-  					}
-  					break;
-  			}
-  		}
-  		this.internal.write("]");
-  	}]);
-
-  	jsPDFAPI.createAnnotation = function (options) {
-  		switch (options.type) {
-  			case 'link':
-  				this.link(options.bounds.x, options.bounds.y, options.bounds.w, options.bounds.h, options);
-  				break;
-  			case 'text':
-  			case 'freetext':
-  				this.annotationPlugin.annotations[this.internal.getCurrentPageInfo().pageNumber].push(options);
-  				break;
-  		}
-  	};
-
-  	/**
-    * valid options
-    * <li> pageNumber or url [required]
-    * <p>If pageNumber is specified, top and zoom may also be specified</p>
-    */
-  	jsPDFAPI.link = function (x, y, w, h, options) {
-
-  		this.annotationPlugin.annotations[this.internal.getCurrentPageInfo().pageNumber].push({
-  			x: x,
-  			y: y,
-  			w: w,
-  			h: h,
-  			options: options,
-  			type: 'link'
-  		});
-  	};
-
-  	/**
-    * Currently only supports single line text.
-    * Returns the width of the text/link
-    */
-  	jsPDFAPI.textWithLink = function (text, x, y, options) {
-
-  		var width = this.getTextWidth(text);
-  		var height = this.internal.getLineHeight() / this.internal.scaleFactor;
-  		this.text(text, x, y);
-  		//TODO We really need the text baseline height to do this correctly.
-  		// Or ability to draw text on top, bottom, center, or baseline.
-  		y += height * .2;
-  		this.link(x, y - height, width, height, options);
-  		return width;
-  	};
-
-  	//TODO move into external library
-  	jsPDFAPI.getTextWidth = function (text) {
-
-  		var fontSize = this.internal.getFontSize();
-  		var txtWidth = this.getStringUnitWidth(text) * fontSize / this.internal.scaleFactor;
-  		return txtWidth;
-  	};
-
-  	//TODO move into external library
-  	jsPDFAPI.getLineHeight = function () {
-  		return this.internal.getLineHeight();
-  	};
-
-  	return this;
-  })(jsPDF.API);
+      var filterAsString = processedData.reverseChain + (Array.isArray(alreadyAppliedFilters) ? alreadyAppliedFilters.join(" ") : alreadyAppliedFilters.toString());
 
-  (function (jsPDFAPI) {
+      if (processedData.data.length !== 0) {
+        keyValues.push({
+          key: "Length",
+          value: processedData.data.length
+        });
 
-      var arLangCodes = {
-          "ar": "Arabic (Standard)",
-          "ar-DZ": "Arabic (Algeria)",
-          "ar-BH": "Arabic (Bahrain)",
-          "ar-EG": "Arabic (Egypt)",
-          "ar-IQ": "Arabic (Iraq)",
-          "ar-JO": "Arabic (Jordan)",
-          "ar-KW": "Arabic (Kuwait)",
-          "ar-LB": "Arabic (Lebanon)",
-          "ar-LY": "Arabic (Libya)",
-          "ar-MA": "Arabic (Morocco)",
-          "ar-OM": "Arabic (Oman)",
-          "ar-QA": "Arabic (Qatar)",
-          "ar-SA": "Arabic (Saudi Arabia)",
-          "ar-SY": "Arabic (Syria)",
-          "ar-TN": "Arabic (Tunisia)",
-          "ar-AE": "Arabic (U.A.E.)",
-          "ar-YE": "Arabic (Yemen)",
-          "fa": "Persian",
-          "fa-IR": "Persian/Iran",
-          "ur": "Urdu"
-      };
+        if (addLength1 === true) {
+          keyValues.push({
+            key: "Length1",
+            value: valueOfLength1
+          });
+        }
+      }
+
+      if (filterAsString.length != 0) {
+        if (filterAsString.split("/").length - 1 === 1) {
+          keyValues.push({
+            key: "Filter",
+            value: filterAsString
+          });
+        } else {
+          keyValues.push({
+            key: "Filter",
+            value: "[" + filterAsString + "]"
+          });
 
-      var arLangCodesKeys = Object.keys(arLangCodes);
+          for (var j = 0; j < keyValues.length; j += 1) {
+            if (keyValues[j].key === "DecodeParms") {
+              var decodeParmsArray = [];
 
-      /**
-       * Arabic shape substitutions: char code => (isolated, final, initial, medial).
-       */
-      var arabicSubst = {
-          1569: [65152],
-          1570: [65153, 65154, 65153, 65154],
-          1571: [65155, 65156, 65155, 65156],
-          1572: [65157, 65158],
-          1573: [65159, 65160, 65159, 65160],
-          1574: [65161, 65162, 65163, 65164],
-          1575: [65165, 65166, 65165, 65166],
-          1576: [65167, 65168, 65169, 65170],
-          1577: [65171, 65172],
-          1578: [65173, 65174, 65175, 65176],
-          1579: [65177, 65178, 65179, 65180],
-          1580: [65181, 65182, 65183, 65184],
-          1581: [65185, 65186, 65187, 65188],
-          1582: [65189, 65190, 65191, 65192],
-          1583: [65193, 65194, 65193],
-          1584: [65195, 65196, 65195],
-          1585: [65197, 65198, 65197],
-          1586: [65199, 65200, 65199],
-          1587: [65201, 65202, 65203, 65204],
-          1588: [65205, 65206, 65207, 65208],
-          1589: [65209, 65210, 65211, 65212],
-          1590: [65213, 65214, 65215, 65216],
-          1591: [65217, 65218, 65219, 65220],
-          1592: [65221, 65222, 65223, 65224],
-          1593: [65225, 65226, 65227, 65228],
-          1594: [65229, 65230, 65231, 65232],
-          1601: [65233, 65234, 65235, 65236],
-          1602: [65237, 65238, 65239, 65240],
-          1603: [65241, 65242, 65243, 65244],
-          1604: [65245, 65246, 65247, 65248],
-          1605: [65249, 65250, 65251, 65252],
-          1606: [65253, 65254, 65255, 65256],
-          1607: [65257, 65258, 65259, 65260],
-          1608: [65261, 65262, 65261],
-          1609: [65263, 65264, 64488, 64489],
-          1610: [65265, 65266, 65267, 65268],
-          1649: [64336, 64337],
-          1655: [64477],
-          1657: [64358, 64359, 64360, 64361],
-          1658: [64350, 64351, 64352, 64353],
-          1659: [64338, 64339, 64340, 64341],
-          1662: [64342, 64343, 64344, 64345],
-          1663: [64354, 64355, 64356, 64357],
-          1664: [64346, 64347, 64348, 64349],
-          1667: [64374, 64375, 64376, 64377],
-          1668: [64370, 64371, 64372, 64373],
-          1670: [64378, 64379, 64380, 64381],
-          1671: [64382, 64383, 64384, 64385],
-          1672: [64392, 64393],
-          1676: [64388, 64389],
-          1677: [64386, 64387],
-          1678: [64390, 64391],
-          1681: [64396, 64397],
-          1688: [64394, 64395, 64394],
-          1700: [64362, 64363, 64364, 64365],
-          1702: [64366, 64367, 64368, 64369],
-          1705: [64398, 64399, 64400, 64401],
-          1709: [64467, 64468, 64469, 64470],
-          1711: [64402, 64403, 64404, 64405],
-          1713: [64410, 64411, 64412, 64413],
-          1715: [64406, 64407, 64408, 64409],
-          1722: [64414, 64415],
-          1723: [64416, 64417, 64418, 64419],
-          1726: [64426, 64427, 64428, 64429],
-          1728: [64420, 64421],
-          1729: [64422, 64423, 64424, 64425],
-          1733: [64480, 64481],
-          1734: [64473, 64474],
-          1735: [64471, 64472],
-          1736: [64475, 64476],
-          1737: [64482, 64483],
-          1739: [64478, 64479],
-          1740: [64508, 64509, 64510, 64511],
-          1744: [64484, 64485, 64486, 64487],
-          1746: [64430, 64431],
-          1747: [64432, 64433]
-      };
-      var arabiclaasubst = {
-          1570: [65269, 65270, 65269, 65270],
-          1571: [65271, 65272, 65271, 65272],
-          1573: [65273, 65274, 65273, 65274],
-          1575: [65275, 65276, 65275, 65276]
-      };
-      var arabicorigsubst = {
-          1570: [65153, 65154, 65153, 65154],
-          1571: [65155, 65156, 65155, 65156],
-          1573: [65159, 65160, 65159, 65160],
-          1575: [65165, 65166, 65165, 65166]
-      };
-      var arabic_diacritics = {
-          1612: 64606, // Shadda + Dammatan
-          1613: 64607, // Shadda + Kasratan
-          1614: 64608, // Shadda + Fatha
-          1615: 64609, // Shadda + Damma
-          1616: 64610 // Shadda + Kasra
-      };
+              for (var i = 0; i < processedData.reverseChain.split("/").length - 1; i += 1) {
+                decodeParmsArray.push("null");
+              }
 
-      var alfletter = [1570, 1571, 1573, 1575];
-      var endedletter = [1569, 1570, 1571, 1572, 1573, 1575, 1577, 1583, 1584, 1585, 1586, 1608, 1688];
+              decodeParmsArray.push(keyValues[j].value);
+              keyValues[j].value = "[" + decodeParmsArray.join(" ") + "]";
+            }
+          }
+        }
+      }
 
-      var isolatedForm = 0;
-      var finalForm = 1;
-      var initialForm = 2;
-      var medialForm = 3;
+      out("<<");
 
-      //private
-      function isArabicLetter(letter) {
-          return letter !== undefined && arabicSubst[letter.charCodeAt(0)] !== undefined;
+      for (var k = 0; k < keyValues.length; k++) {
+        out("/" + keyValues[k].key + " " + keyValues[k].value);
       }
 
-      function isArabicEndLetter(letter) {
-          return letter !== undefined && endedletter.indexOf(letter.charCodeAt(0)) >= 0;
+      out(">>");
+
+      if (processedData.data.length !== 0) {
+        out("stream");
+        out(encryptor(processedData.data));
+        out("endstream");
       }
+    };
 
-      function isArabicAlfLetter(letter) {
-          return letter !== undefined && alfletter.indexOf(letter.charCodeAt(0)) >= 0;
+    var putPage = API.__private__.putPage = function (page) {
+      var pageNumber = page.number;
+      var data = page.data;
+      var pageObjectNumber = page.objId;
+      var pageContentsObjId = page.contentsObjId;
+      newObjectDeferredBegin(pageObjectNumber, true);
+      out("<</Type /Page");
+      out("/Parent " + page.rootDictionaryObjId + " 0 R");
+      out("/Resources " + page.resourceDictionaryObjId + " 0 R");
+      out("/MediaBox [" + parseFloat(hpf(page.mediaBox.bottomLeftX)) + " " + parseFloat(hpf(page.mediaBox.bottomLeftY)) + " " + hpf(page.mediaBox.topRightX) + " " + hpf(page.mediaBox.topRightY) + "]");
+
+      if (page.cropBox !== null) {
+        out("/CropBox [" + hpf(page.cropBox.bottomLeftX) + " " + hpf(page.cropBox.bottomLeftY) + " " + hpf(page.cropBox.topRightX) + " " + hpf(page.cropBox.topRightY) + "]");
       }
 
-      function arabicLetterHasFinalForm(letter) {
-          return isArabicLetter(letter) && arabicSubst[letter.charCodeAt(0)].length >= 2;
+      if (page.bleedBox !== null) {
+        out("/BleedBox [" + hpf(page.bleedBox.bottomLeftX) + " " + hpf(page.bleedBox.bottomLeftY) + " " + hpf(page.bleedBox.topRightX) + " " + hpf(page.bleedBox.topRightY) + "]");
       }
 
-      function arabicLetterHasMedialForm(letter) {
-          return isArabicLetter(letter) && arabicSubst[letter.charCodeAt(0)].length == 4;
+      if (page.trimBox !== null) {
+        out("/TrimBox [" + hpf(page.trimBox.bottomLeftX) + " " + hpf(page.trimBox.bottomLeftY) + " " + hpf(page.trimBox.topRightX) + " " + hpf(page.trimBox.topRightY) + "]");
       }
 
-      function isArabicDiacritic(letter) {
-          return letter !== undefined && arabic_diacritics[letter.charCodeAt(0)] !== undefined;
+      if (page.artBox !== null) {
+        out("/ArtBox [" + hpf(page.artBox.bottomLeftX) + " " + hpf(page.artBox.bottomLeftY) + " " + hpf(page.artBox.topRightX) + " " + hpf(page.artBox.topRightY) + "]");
       }
 
-      function getCorrectForm(currentChar, beforeChar, nextChar, arabicSubstition) {
-          if (!isArabicLetter(currentChar)) {
-              return -1;
-          }
+      if (typeof page.userUnit === "number" && page.userUnit !== 1.0) {
+        out("/UserUnit " + page.userUnit);
+      }
 
-          arabicSubstition = arabicSubstition || {};
-          arabicSubst = Object.assign(arabicSubst, arabicSubstition);
+      events.publish("putPage", {
+        objId: pageObjectNumber,
+        pageContext: pagesContext[pageNumber],
+        pageNumber: pageNumber,
+        page: data
+      });
+      out("/Contents " + pageContentsObjId + " 0 R");
+      out(">>");
+      out("endobj"); // Page content
 
-          if (!arabicLetterHasFinalForm(currentChar) || !isArabicLetter(beforeChar) && !isArabicLetter(nextChar) || !isArabicLetter(nextChar) && isArabicEndLetter(beforeChar) || isArabicEndLetter(currentChar) && !isArabicLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicAlfLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicEndLetter(beforeChar)) {
-              arabicSubst = Object.assign(arabicSubst, arabicorigsubst);
-              return isolatedForm;
-          }
+      var pageContent = data.join("\n");
 
-          if (arabicLetterHasMedialForm(currentChar) && isArabicLetter(beforeChar) && !isArabicEndLetter(beforeChar) && isArabicLetter(nextChar) && arabicLetterHasFinalForm(nextChar)) {
-              arabicSubst = Object.assign(arabicSubst, arabicorigsubst);
-              return medialForm;
-          }
+      if (apiMode === ApiMode.ADVANCED) {
+        // if the user forgot to switch back to COMPAT mode, we must balance the graphics stack again
+        pageContent += "\nQ";
+      }
 
-          if (isArabicEndLetter(currentChar) || !isArabicLetter(nextChar)) {
-              arabicSubst = Object.assign(arabicSubst, arabicorigsubst);
-              return finalForm;
-          }
+      newObjectDeferredBegin(pageContentsObjId, true);
+      putStream({
+        data: pageContent,
+        filters: getFilters(),
+        objectId: pageContentsObjId
+      });
+      out("endobj");
+      return pageObjectNumber;
+    };
 
-          arabicSubst = Object.assign(arabicSubst, arabicorigsubst);
-          return initialForm;
+    var putPages = API.__private__.putPages = function () {
+      var n,
+          i,
+          pageObjectNumbers = [];
+
+      for (n = 1; n <= page; n++) {
+        pagesContext[n].objId = newObjectDeferred();
+        pagesContext[n].contentsObjId = newObjectDeferred();
       }
 
-      var commonSubstition = function commonSubstition(character) {
-          var replacementTable = {
-              '(': ')',
-              ')': '('
-          };
-          return replacementTable[character] || character;
-      };
+      for (n = 1; n <= page; n++) {
+        pageObjectNumbers.push(putPage({
+          number: n,
+          data: pages[n],
+          objId: pagesContext[n].objId,
+          contentsObjId: pagesContext[n].contentsObjId,
+          mediaBox: pagesContext[n].mediaBox,
+          cropBox: pagesContext[n].cropBox,
+          bleedBox: pagesContext[n].bleedBox,
+          trimBox: pagesContext[n].trimBox,
+          artBox: pagesContext[n].artBox,
+          userUnit: pagesContext[n].userUnit,
+          rootDictionaryObjId: rootDictionaryObjId,
+          resourceDictionaryObjId: resourceDictionaryObjId
+        }));
+      }
 
-      var processArabic = jsPDFAPI.processArabic = function (text, reverse) {
-          text = text || "";
-          reverse = reverse || false;
-
-          var result = "";
-          var i = 0;
-          var position = 0;
-          var currentLetter = "";
-          var prevLetter = "";
-          var nextLetter = "";
-          var resultingLetter;
-
-          var localPrevLetter;
-          var localCurrentLetter;
-          var localNextLetter;
-
-          for (i = 0; i < text.length; i += 1) {
-              currentLetter = text[i];
-              prevLetter = text[i - 1];
-              nextLetter = text[i + 1];
-              if (!isArabicLetter(currentLetter)) {
-                  result += reverse ? commonSubstition(currentLetter) : currentLetter;
-              } else {
-                  if (prevLetter !== undefined && prevLetter.charCodeAt(0) === 1604 && isArabicAlfLetter(currentLetter)) {
-                      localPrevLetter = text[i - 2];
-                      localCurrentLetter = currentLetter;
-                      localNextLetter = text[i + 1];
-                      position = getCorrectForm(localCurrentLetter, localPrevLetter, localNextLetter, arabiclaasubst);
-                      resultingLetter = String.fromCharCode(arabiclaasubst[currentLetter.charCodeAt(0)][position]);
-                      result = result.substr(0, result.length - 1) + resultingLetter;
-                  } else if (prevLetter !== undefined && prevLetter.charCodeAt(0) === 1617 && isArabicDiacritic(currentLetter)) {
-                      localPrevLetter = text[i - 2];
-                      localCurrentLetter = currentLetter;
-                      localNextLetter = text[i + 1];
-                      position = getCorrectForm(localCurrentLetter, localPrevLetter, localNextLetter, arabicorigsubst);
-                      resultingLetter = String.fromCharCode(arabic_diacritics[currentLetter.charCodeAt(0)][position]);
-                      result = result.substr(0, result.length - 1) + resultingLetter;
-                  } else {
-                      position = getCorrectForm(currentLetter, prevLetter, nextLetter, arabicorigsubst);
-                      result += String.fromCharCode(arabicSubst[currentLetter.charCodeAt(0)][position]);
-                  }
-              }
-          }
-          return reverse ? result.split("").reverse().join("") : result;
-      };
+      newObjectDeferredBegin(rootDictionaryObjId, true);
+      out("<</Type /Pages");
+      var kids = "/Kids [";
 
-      var arabicParserFunction = function arabicParserFunction(args) {
-          var text = args.text;
-          var x = args.x;
-          var y = args.y;
-          var options = args.options || {};
-          var mutex = args.mutex || {};
-          var lang = options.lang;
-          var tmpText = [];
-
-          if (arLangCodesKeys.indexOf(lang) >= 0) {
-              if (Object.prototype.toString.call(text) === '[object Array]') {
-                  var i = 0;
-                  tmpText = [];
-                  for (i = 0; i < text.length; i += 1) {
-                      if (Object.prototype.toString.call(text[i]) === '[object Array]') {
-                          tmpText.push([processArabic(text[i][0], true), text[i][1], text[i][2]]);
-                      } else {
-                          tmpText.push([processArabic(text[i], true)]);
-                      }
-                  }
-                  args.text = tmpText;
-              } else {
-                  args.text = processArabic(text, true);
-              }
-              //force charSpace if not given.
-              if (options.charSpace === undefined) {
-                  args.options.charSpace = 0;
-              }
-              //if R2L is true, set it false.
-              if (options.R2L === true) {
-                  args.options.R2L = false;
-              }
-          }
-      };
+      for (i = 0; i < page; i++) {
+        kids += pageObjectNumbers[i] + " 0 R ";
+      }
 
-      jsPDFAPI.events.push(['preProcessText', arabicParserFunction]);
-  })(jsPDF.API);
+      out(kids + "]");
+      out("/Count " + page);
+      out(">>");
+      out("endobj");
+      events.publish("postPutPages");
+    };
 
-  /**
-   * jsPDF Autoprint Plugin
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
+    var putFont = function putFont(font) {
+      events.publish("putFont", {
+        font: font,
+        out: out,
+        newObject: newObject,
+        putStream: putStream
+      });
 
-  /**
-  * Makes the PDF automatically print. This works in Chrome, Firefox, Acrobat
-  * Reader.
-  *
-  * @returns {jsPDF}
-  * @name autoPrint
-  * @example
-  * var doc = new jsPDF()
-  * doc.text(10, 10, 'This is a test')
-  * doc.autoPrint()
-  * doc.save('autoprint.pdf')
-  */
+      if (font.isAlreadyPutted !== true) {
+        font.objectNumber = newObject();
+        out("<<");
+        out("/Type /Font");
+        out("/BaseFont /" + toPDFName(font.postScriptName));
+        out("/Subtype /Type1");
 
-  (function (jsPDFAPI) {
+        if (typeof font.encoding === "string") {
+          out("/Encoding /" + font.encoding);
+        }
 
-    jsPDFAPI.autoPrint = function (options) {
+        out("/FirstChar 32");
+        out("/LastChar 255");
+        out(">>");
+        out("endobj");
+      }
+    };
 
-      var refAutoPrintTag;
-      options = options || {};
-      options.variant = options.variant || 'non-conform';
+    var putFonts = function putFonts() {
+      for (var fontKey in fonts) {
+        if (fonts.hasOwnProperty(fontKey)) {
+          if (putOnlyUsedFonts === false || putOnlyUsedFonts === true && usedFonts.hasOwnProperty(fontKey)) {
+            putFont(fonts[fontKey]);
+          }
+        }
+      }
+    };
 
-      switch (options.variant) {
-        case 'javascript':
-          //https://github.com/Rob--W/pdf.js/commit/c676ecb5a0f54677b9f3340c3ef2cf42225453bb
-          this.addJS('print({});');
-          break;
-        case 'non-conform':
-        default:
-          this.internal.events.subscribe('postPutResources', function () {
-            refAutoPrintTag = this.internal.newObject();
-            this.internal.out("<<");
-            this.internal.out("/S /Named");
-            this.internal.out("/Type /Action");
-            this.internal.out("/N /Print");
-            this.internal.out(">>");
-            this.internal.out("endobj");
-          });
+    var putXObject = function putXObject(xObject) {
+      xObject.objectNumber = newObject();
+      var options = [];
+      options.push({
+        key: "Type",
+        value: "/XObject"
+      });
+      options.push({
+        key: "Subtype",
+        value: "/Form"
+      });
+      options.push({
+        key: "BBox",
+        value: "[" + [hpf(xObject.x), hpf(xObject.y), hpf(xObject.x + xObject.width), hpf(xObject.y + xObject.height)].join(" ") + "]"
+      });
+      options.push({
+        key: "Matrix",
+        value: "[" + xObject.matrix.toString() + "]"
+      }); // TODO: /Resources
+
+      var stream = xObject.pages[1].join("\n");
+      putStream({
+        data: stream,
+        additionalKeyValues: options,
+        objectId: xObject.objectNumber
+      });
+      out("endobj");
+    };
 
-          this.internal.events.subscribe("putCatalog", function () {
-            this.internal.out("/OpenAction " + refAutoPrintTag + " 0 R");
-          });
-          break;
+    var putXObjects = function putXObjects() {
+      for (var xObjectKey in renderTargets) {
+        if (renderTargets.hasOwnProperty(xObjectKey)) {
+          putXObject(renderTargets[xObjectKey]);
+        }
       }
-      return this;
     };
-  })(jsPDF.API);
 
-  /**
-   * jsPDF Canvas PlugIn
-   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
+    var interpolateAndEncodeRGBStream = function interpolateAndEncodeRGBStream(colors, numberSamples) {
+      var tValues = [];
+      var t;
+      var dT = 1.0 / (numberSamples - 1);
 
-  /**
-   * This plugin mimics the HTML5 Canvas
-   * 
-   * The goal is to provide a way for current canvas users to print directly to a PDF.
-   */
+      for (t = 0.0; t < 1.0; t += dT) {
+        tValues.push(t);
+      }
 
-  (function (jsPDFAPI) {
+      tValues.push(1.0); // add first and last control point if not present
 
-  	jsPDFAPI.events.push(['initialized', function () {
-  		this.canvas.pdf = this;
-  	}]);
-
-  	jsPDFAPI.canvas = {
-  		getContext: function getContext(name) {
-  			this.pdf.context2d._canvas = this;
-  			return this.pdf.context2d;
-  		},
-  		childNodes: []
-  	};
-
-  	Object.defineProperty(jsPDFAPI.canvas, 'width', {
-  		get: function get() {
-  			return this._width;
-  		},
-  		set: function set(value) {
-  			this._width = value;
-  			this.getContext('2d').pageWrapX = value + 1;
-  		}
-  	});
-
-  	Object.defineProperty(jsPDFAPI.canvas, 'height', {
-  		get: function get() {
-  			return this._height;
-  		},
-  		set: function set(value) {
-  			this._height = value;
-  			this.getContext('2d').pageWrapY = value + 1;
-  		}
-  	});
-
-  	return this;
-  })(jsPDF.API);
+      if (colors[0].offset != 0.0) {
+        var c0 = {
+          offset: 0.0,
+          color: colors[0].color
+        };
+        colors.unshift(c0);
+      }
 
-  /** ====================================================================
-   * jsPDF Cell plugin
-   * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
-   *               2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
-   *               2013 Lee Driscoll, https://github.com/lsdriscoll
-   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
-   *               2014 James Hall, james@parall.ax
-   *               2014 Diego Casorran, https://github.com/diegocr
-   *
-   * 
-   * ====================================================================
-   */
+      if (colors[colors.length - 1].offset != 1.0) {
+        var c1 = {
+          offset: 1.0,
+          color: colors[colors.length - 1].color
+        };
+        colors.push(c1);
+      }
 
-  (function (jsPDFAPI) {
-      /*jslint browser:true */
-      /*global document: false, jsPDF */
-
-      var fontName,
-          fontSize,
-          fontStyle,
-          padding = 3,
-          margin = 13,
-          headerFunction,
-          lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined },
-          pages = 1,
-          setLastCellPosition = function setLastCellPosition(x, y, w, h, ln) {
-          lastCellPos = { 'x': x, 'y': y, 'w': w, 'h': h, 'ln': ln };
-      },
-          getLastCellPosition = function getLastCellPosition() {
-          return lastCellPos;
-      },
-          NO_MARGINS = { left: 0, top: 0, bottom: 0 };
+      var out = "";
+      var index = 0;
 
-      jsPDFAPI.setHeaderFunction = function (func) {
-          headerFunction = func;
-      };
+      for (var i = 0; i < tValues.length; i++) {
+        t = tValues[i];
 
-      jsPDFAPI.getTextDimensions = function (txt) {
-          fontName = this.internal.getFont().fontName;
-          fontSize = this.table_font_size || this.internal.getFontSize();
-          fontStyle = this.internal.getFont().fontStyle;
-          // 1 pixel = 0.264583 mm and 1 mm = 72/25.4 point
-          var px2pt = 0.264583 * 72 / 25.4,
-              dimensions,
-              text;
+        while (t > colors[index + 1].offset) {
+          index++;
+        }
 
-          text = document.createElement('font');
-          text.id = "jsPDFCell";
+        var a = colors[index].offset;
+        var b = colors[index + 1].offset;
+        var d = (t - a) / (b - a);
+        var aColor = colors[index].color;
+        var bColor = colors[index + 1].color;
+        out += padd2Hex(Math.round((1 - d) * aColor[0] + d * bColor[0]).toString(16)) + padd2Hex(Math.round((1 - d) * aColor[1] + d * bColor[1]).toString(16)) + padd2Hex(Math.round((1 - d) * aColor[2] + d * bColor[2]).toString(16));
+      }
 
-          try {
-              text.style.fontStyle = fontStyle;
-          } catch (e) {
-              text.style.fontWeight = fontStyle;
-          }
+      return out.trim();
+    };
 
-          text.style.fontSize = fontSize + 'pt';
-          text.style.fontFamily = fontName;
-          try {
-              text.textContent = txt;
-          } catch (e) {
-              text.innerText = txt;
-          }
+    var putShadingPattern = function putShadingPattern(pattern, numberSamples) {
+      /*
+         Axial patterns shade between the two points specified in coords, radial patterns between the inner
+         and outer circle.
+         The user can specify an array (colors) that maps t-Values in [0, 1] to RGB colors. These are now
+         interpolated to equidistant samples and written to pdf as a sample (type 0) function.
+         */
+      // The number of color samples that should be used to describe the shading.
+      // The higher, the more accurate the gradient will be.
+      numberSamples || (numberSamples = 21);
+      var funcObjectNumber = newObject();
+      var stream = interpolateAndEncodeRGBStream(pattern.colors, numberSamples);
+      var options = [];
+      options.push({
+        key: "FunctionType",
+        value: "0"
+      });
+      options.push({
+        key: "Domain",
+        value: "[0.0 1.0]"
+      });
+      options.push({
+        key: "Size",
+        value: "[" + numberSamples + "]"
+      });
+      options.push({
+        key: "BitsPerSample",
+        value: "8"
+      });
+      options.push({
+        key: "Range",
+        value: "[0.0 1.0 0.0 1.0 0.0 1.0]"
+      });
+      options.push({
+        key: "Decode",
+        value: "[0.0 1.0 0.0 1.0 0.0 1.0]"
+      });
+      putStream({
+        data: stream,
+        additionalKeyValues: options,
+        alreadyAppliedFilters: ["/ASCIIHexDecode"],
+        objectId: funcObjectNumber
+      });
+      out("endobj");
+      pattern.objectNumber = newObject();
+      out("<< /ShadingType " + pattern.type);
+      out("/ColorSpace /DeviceRGB");
+      var coords = "/Coords [" + hpf(parseFloat(pattern.coords[0])) + " " + // x1
+      hpf(parseFloat(pattern.coords[1])) + " "; // y1
+
+      if (pattern.type === 2) {
+        // axial
+        coords += hpf(parseFloat(pattern.coords[2])) + " " + // x2
+        hpf(parseFloat(pattern.coords[3])); // y2
+      } else {
+        // radial
+        coords += hpf(parseFloat(pattern.coords[2])) + " " + // r1
+        hpf(parseFloat(pattern.coords[3])) + " " + // x2
+        hpf(parseFloat(pattern.coords[4])) + " " + // y2
+        hpf(parseFloat(pattern.coords[5])); // r2
+      }
 
-          document.body.appendChild(text);
+      coords += "]";
+      out(coords);
 
-          dimensions = { w: (text.offsetWidth + 1) * px2pt, h: (text.offsetHeight + 1) * px2pt };
+      if (pattern.matrix) {
+        out("/Matrix [" + pattern.matrix.toString() + "]");
+      }
 
-          document.body.removeChild(text);
+      out("/Function " + funcObjectNumber + " 0 R");
+      out("/Extend [true true]");
+      out(">>");
+      out("endobj");
+    };
 
-          return dimensions;
-      };
+    var putTilingPattern = function putTilingPattern(pattern, deferredResourceDictionaryIds) {
+      var resourcesObjectId = newObjectDeferred();
+      var patternObjectId = newObject();
+      deferredResourceDictionaryIds.push({
+        resourcesOid: resourcesObjectId,
+        objectOid: patternObjectId
+      });
+      pattern.objectNumber = patternObjectId;
+      var options = [];
+      options.push({
+        key: "Type",
+        value: "/Pattern"
+      });
+      options.push({
+        key: "PatternType",
+        value: "1"
+      }); // tiling pattern
+
+      options.push({
+        key: "PaintType",
+        value: "1"
+      }); // colored tiling pattern
+
+      options.push({
+        key: "TilingType",
+        value: "1"
+      }); // constant spacing
+
+      options.push({
+        key: "BBox",
+        value: "[" + pattern.boundingBox.map(hpf).join(" ") + "]"
+      });
+      options.push({
+        key: "XStep",
+        value: hpf(pattern.xStep)
+      });
+      options.push({
+        key: "YStep",
+        value: hpf(pattern.yStep)
+      });
+      options.push({
+        key: "Resources",
+        value: resourcesObjectId + " 0 R"
+      });
 
-      jsPDFAPI.cellAddPage = function () {
-          var margins = this.margins || NO_MARGINS;
+      if (pattern.matrix) {
+        options.push({
+          key: "Matrix",
+          value: "[" + pattern.matrix.toString() + "]"
+        });
+      }
 
-          this.addPage();
+      putStream({
+        data: pattern.stream,
+        additionalKeyValues: options,
+        objectId: pattern.objectNumber
+      });
+      out("endobj");
+    };
 
-          setLastCellPosition(margins.left, margins.top, undefined, undefined);
-          //setLastCellPosition(undefined, undefined, undefined, undefined, undefined);
-          pages += 1;
-      };
+    var putPatterns = function putPatterns(deferredResourceDictionaryIds) {
+      var patternKey;
 
-      jsPDFAPI.cellInitialize = function () {
-          lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined };
-          pages = 1;
-      };
+      for (patternKey in patterns) {
+        if (patterns.hasOwnProperty(patternKey)) {
+          if (patterns[patternKey] instanceof ShadingPattern) {
+            putShadingPattern(patterns[patternKey]);
+          } else if (patterns[patternKey] instanceof TilingPattern) {
+            putTilingPattern(patterns[patternKey], deferredResourceDictionaryIds);
+          }
+        }
+      }
+    };
 
-      jsPDFAPI.cell = function (x, y, w, h, txt, ln, align) {
-          var curCell = getLastCellPosition();
-          var pgAdded = false;
+    var putGState = function putGState(gState) {
+      gState.objectNumber = newObject();
+      out("<<");
 
-          // If this is not the first cell, we must change its position
-          if (curCell.ln !== undefined) {
-              if (curCell.ln === ln) {
-                  //Same line
-                  x = curCell.x + curCell.w;
-                  y = curCell.y;
-              } else {
-                  //New line
-                  var margins = this.margins || NO_MARGINS;
-                  if (curCell.y + curCell.h + h + margin >= this.internal.pageSize.getHeight() - margins.bottom) {
-                      this.cellAddPage();
-                      pgAdded = true;
-                      if (this.printHeaders && this.tableHeaderRow) {
-                          this.printHeaderRow(ln, true);
-                      }
-                  }
-                  //We ignore the passed y: the lines may have different heights
-                  y = getLastCellPosition().y + getLastCellPosition().h;
-                  if (pgAdded) y = margin + 10;
-              }
-          }
+      for (var p in gState) {
+        switch (p) {
+          case "opacity":
+            out("/ca " + f2(gState[p]));
+            break;
 
-          if (txt[0] !== undefined) {
-              if (this.printingHeaderRow) {
-                  this.rect(x, y, w, h, 'FD');
-              } else {
-                  this.rect(x, y, w, h);
-              }
-              if (align === 'right') {
-                  if (!(txt instanceof Array)) {
-                      txt = [txt];
-                  }
-                  for (var i = 0; i < txt.length; i++) {
-                      var currentLine = txt[i];
-                      var textSize = this.getStringUnitWidth(currentLine) * this.internal.getFontSize();
-                      this.text(currentLine, x + w - textSize - padding, y + this.internal.getLineHeight() * (i + 1));
-                  }
-              } else {
-                  this.text(txt, x + padding, y + this.internal.getLineHeight());
-              }
-          }
-          setLastCellPosition(x, y, w, h, ln);
-          return this;
-      };
+          case "stroke-opacity":
+            out("/CA " + f2(gState[p]));
+            break;
+        }
+      }
 
-      /**
-       * Return the maximum value from an array
-       * @param array
-       * @param comparisonFn
-       * @returns {*}
-       */
-      jsPDFAPI.arrayMax = function (array, comparisonFn) {
-          var max = array[0],
-              i,
-              ln,
-              item;
-
-          for (i = 0, ln = array.length; i < ln; i += 1) {
-              item = array[i];
-
-              if (comparisonFn) {
-                  if (comparisonFn(max, item) === -1) {
-                      max = item;
-                  }
-              } else {
-                  if (item > max) {
-                      max = item;
-                  }
-              }
-          }
+      out(">>");
+      out("endobj");
+    };
 
-          return max;
-      };
+    var putGStates = function putGStates() {
+      var gStateKey;
 
-      /**
-       * Create a table from a set of data.
-       * @param {Integer} [x] : left-position for top-left corner of table
-       * @param {Integer} [y] top-position for top-left corner of table
-       * @param {Object[]} [data] As array of objects containing key-value pairs corresponding to a row of data.
-       * @param {String[]} [headers] Omit or null to auto-generate headers at a performance cost
-        * @param {Object} [config.printHeaders] True to print column headers at the top of every page
-       * @param {Object} [config.autoSize] True to dynamically set the column widths to match the widest cell value
-       * @param {Object} [config.margins] margin values for left, top, bottom, and width
-       * @param {Object} [config.fontSize] Integer fontSize to use (optional)
-       */
+      for (gStateKey in gStates) {
+        if (gStates.hasOwnProperty(gStateKey)) {
+          putGState(gStates[gStateKey]);
+        }
+      }
+    };
 
-      jsPDFAPI.table = function (x, y, data, headers, config) {
-          if (!data) {
-              throw 'No data for PDF table';
-          }
+    var putXobjectDict = function putXobjectDict() {
+      out("/XObject <<");
 
-          var headerNames = [],
-              headerPrompts = [],
-              header,
-              i,
-              ln,
-              cln,
-              columnMatrix = {},
-              columnWidths = {},
-              columnData,
-              column,
-              columnMinWidths = [],
-              j,
-              tableHeaderConfigs = [],
-              model,
-              jln,
-              func,
+      for (var xObjectKey in renderTargets) {
+        if (renderTargets.hasOwnProperty(xObjectKey) && renderTargets[xObjectKey].objectNumber >= 0) {
+          out("/" + xObjectKey + " " + renderTargets[xObjectKey].objectNumber + " 0 R");
+        }
+      } // Loop through images, or other data objects
 
 
-          //set up defaults. If a value is provided in config, defaults will be overwritten:
-          autoSize = false,
-              printHeaders = true,
-              fontSize = 12,
-              margins = NO_MARGINS;
+      events.publish("putXobjectDict");
+      out(">>");
+    };
 
-          margins.width = this.internal.pageSize.getWidth();
+    var putEncryptionDict = function putEncryptionDict() {
+      encryption.oid = newObject();
+      out("<<");
+      out("/Filter /Standard");
+      out("/V " + encryption.v);
+      out("/R " + encryption.r);
+      out("/U <" + encryption.toHexString(encryption.U) + ">");
+      out("/O <" + encryption.toHexString(encryption.O) + ">");
+      out("/P " + encryption.P);
+      out(">>");
+      out("endobj");
+    };
 
-          if (config) {
-              //override config defaults if the user has specified non-default behavior:
-              if (config.autoSize === true) {
-                  autoSize = true;
-              }
-              if (config.printHeaders === false) {
-                  printHeaders = false;
-              }
-              if (config.fontSize) {
-                  fontSize = config.fontSize;
-              }
-              if (config.css && typeof config.css['font-size'] !== "undefined") {
-                  fontSize = config.css['font-size'] * 16;
-              }
-              if (config.margins) {
-                  margins = config.margins;
-              }
-          }
+    var putFontDict = function putFontDict() {
+      out("/Font <<");
 
-          /**
-           * @property {Number} lnMod
-           * Keep track of the current line number modifier used when creating cells
-           */
-          this.lnMod = 0;
-          lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined }, pages = 1;
-
-          this.printHeaders = printHeaders;
-          this.margins = margins;
-          this.setFontSize(fontSize);
-          this.table_font_size = fontSize;
-
-          // Set header values
-          if (headers === undefined || headers === null) {
-              // No headers defined so we derive from data
-              headerNames = Object.keys(data[0]);
-          } else if (headers[0] && typeof headers[0] !== 'string') {
-              var px2pt = 0.264583 * 72 / 25.4;
-
-              // Split header configs into names and prompts
-              for (i = 0, ln = headers.length; i < ln; i += 1) {
-                  header = headers[i];
-                  headerNames.push(header.name);
-                  headerPrompts.push(header.prompt);
-                  columnWidths[header.name] = header.width * px2pt;
-              }
-          } else {
-              headerNames = headers;
+      for (var fontKey in fonts) {
+        if (fonts.hasOwnProperty(fontKey)) {
+          if (putOnlyUsedFonts === false || putOnlyUsedFonts === true && usedFonts.hasOwnProperty(fontKey)) {
+            out("/" + fontKey + " " + fonts[fontKey].objectNumber + " 0 R");
           }
+        }
+      }
 
-          if (autoSize) {
-              // Create a matrix of columns e.g., {column_title: [row1_Record, row2_Record]}
-              func = function func(rec) {
-                  return rec[header];
-              };
+      out(">>");
+    };
 
-              for (i = 0, ln = headerNames.length; i < ln; i += 1) {
-                  header = headerNames[i];
+    var putShadingPatternDict = function putShadingPatternDict() {
+      if (Object.keys(patterns).length > 0) {
+        out("/Shading <<");
 
-                  columnMatrix[header] = data.map(func);
+        for (var patternKey in patterns) {
+          if (patterns.hasOwnProperty(patternKey) && patterns[patternKey] instanceof ShadingPattern && patterns[patternKey].objectNumber >= 0) {
+            out("/" + patternKey + " " + patterns[patternKey].objectNumber + " 0 R");
+          }
+        }
 
-                  // get header width
-                  columnMinWidths.push(this.getTextDimensions(headerPrompts[i] || header).w);
-                  column = columnMatrix[header];
+        events.publish("putShadingPatternDict");
+        out(">>");
+      }
+    };
 
-                  // get cell widths
-                  for (j = 0, cln = column.length; j < cln; j += 1) {
-                      columnData = column[j];
-                      columnMinWidths.push(this.getTextDimensions(columnData).w);
-                  }
+    var putTilingPatternDict = function putTilingPatternDict(objectOid) {
+      if (Object.keys(patterns).length > 0) {
+        out("/Pattern <<");
 
-                  // get final column width
-                  columnWidths[header] = jsPDFAPI.arrayMax(columnMinWidths);
+        for (var patternKey in patterns) {
+          if (patterns.hasOwnProperty(patternKey) && patterns[patternKey] instanceof API.TilingPattern && patterns[patternKey].objectNumber >= 0 && patterns[patternKey].objectNumber < objectOid // prevent cyclic dependencies
+          ) {
+              out("/" + patternKey + " " + patterns[patternKey].objectNumber + " 0 R");
+            }
+        }
 
-                  //have to reset
-                  columnMinWidths = [];
-              }
-          }
+        events.publish("putTilingPatternDict");
+        out(">>");
+      }
+    };
 
-          // -- Construct the table
+    var putGStatesDict = function putGStatesDict() {
+      if (Object.keys(gStates).length > 0) {
+        var gStateKey;
+        out("/ExtGState <<");
 
-          if (printHeaders) {
-              var lineHeight = this.calculateLineHeight(headerNames, columnWidths, headerPrompts.length ? headerPrompts : headerNames);
+        for (gStateKey in gStates) {
+          if (gStates.hasOwnProperty(gStateKey) && gStates[gStateKey].objectNumber >= 0) {
+            out("/" + gStateKey + " " + gStates[gStateKey].objectNumber + " 0 R");
+          }
+        }
 
-              // Construct the header row
-              for (i = 0, ln = headerNames.length; i < ln; i += 1) {
-                  header = headerNames[i];
-                  tableHeaderConfigs.push([x, y, columnWidths[header], lineHeight, String(headerPrompts.length ? headerPrompts[i] : header)]);
-              }
+        events.publish("putGStateDict");
+        out(">>");
+      }
+    };
 
-              // Store the table header config
-              this.setTableHeaderRow(tableHeaderConfigs);
+    var putResourceDictionary = function putResourceDictionary(objectIds) {
+      newObjectDeferredBegin(objectIds.resourcesOid, true);
+      out("<<");
+      out("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]");
+      putFontDict();
+      putShadingPatternDict();
+      putTilingPatternDict(objectIds.objectOid);
+      putGStatesDict();
+      putXobjectDict();
+      out(">>");
+      out("endobj");
+    };
 
-              // Print the header for the start of the table
-              this.printHeaderRow(1, false);
-          }
+    var putResources = function putResources() {
+      // FormObjects, Patterns etc. might use other FormObjects/Patterns/Images
+      // which means their resource dictionaries must contain the already resolved
+      // object ids. For this reason we defer the serialization of the resource
+      // dicts until all objects have been serialized and have object ids.
+      //
+      // In order to prevent cyclic dependencies (which Adobe Reader doesn't like),
+      // we only put all oids that are smaller than the oid of the object the
+      // resource dict belongs to. This is correct behavior, since the streams
+      // may only use other objects that have already been defined and thus appear
+      // earlier in their respective collection.
+      // Currently, this only affects tiling patterns, but a (more) correct
+      // implementation of FormObjects would also define their own resource dicts.
+      var deferredResourceDictionaryIds = [];
+      putFonts();
+      putGStates();
+      putXObjects();
+      putPatterns(deferredResourceDictionaryIds);
+      events.publish("putResources");
+      deferredResourceDictionaryIds.forEach(putResourceDictionary);
+      putResourceDictionary({
+        resourcesOid: resourceDictionaryObjId,
+        objectOid: Number.MAX_SAFE_INTEGER // output all objects
 
-          // Construct the data rows
-          for (i = 0, ln = data.length; i < ln; i += 1) {
-              var lineHeight;
-              model = data[i];
-              lineHeight = this.calculateLineHeight(headerNames, columnWidths, model);
+      });
+      events.publish("postPutResources");
+    };
 
-              for (j = 0, jln = headerNames.length; j < jln; j += 1) {
-                  header = headerNames[j];
-                  this.cell(x, y, columnWidths[header], lineHeight, model[header], i + 2, header.align);
-              }
-          }
-          this.lastCellPos = lastCellPos;
-          this.table_x = x;
-          this.table_y = y;
-          return this;
-      };
-      /**
-       * Calculate the height for containing the highest column
-       * @param {String[]} headerNames is the header, used as keys to the data
-       * @param {Integer[]} columnWidths is size of each column
-       * @param {Object[]} model is the line of data we want to calculate the height of
-       */
-      jsPDFAPI.calculateLineHeight = function (headerNames, columnWidths, model) {
-          var header,
-              lineHeight = 0;
-          for (var j = 0; j < headerNames.length; j++) {
-              header = headerNames[j];
-              model[header] = this.splitTextToSize(String(model[header]), columnWidths[header] - padding);
-              var h = this.internal.getLineHeight() * model[header].length + padding;
-              if (h > lineHeight) lineHeight = h;
-          }
-          return lineHeight;
-      };
+    var putAdditionalObjects = function putAdditionalObjects() {
+      events.publish("putAdditionalObjects");
 
-      /**
-       * Store the config for outputting a table header
-       * @param {Object[]} config
-       * An array of cell configs that would define a header row: Each config matches the config used by jsPDFAPI.cell
-       * except the ln parameter is excluded
-       */
-      jsPDFAPI.setTableHeaderRow = function (config) {
-          this.tableHeaderRow = config;
-      };
+      for (var i = 0; i < additionalObjects.length; i++) {
+        var obj = additionalObjects[i];
+        newObjectDeferredBegin(obj.objId, true);
+        out(obj.content);
+        out("endobj");
+      }
 
-      /**
-       * Output the store header row
-       * @param lineNumber The line number to output the header at
-       */
-      jsPDFAPI.printHeaderRow = function (lineNumber, new_page) {
-          if (!this.tableHeaderRow) {
-              throw 'Property tableHeaderRow does not exist.';
-          }
+      events.publish("postPutAdditionalObjects");
+    };
 
-          var tableHeaderCell, tmpArray, i, ln;
+    var addFontToFontDictionary = function addFontToFontDictionary(font) {
+      fontmap[font.fontName] = fontmap[font.fontName] || {};
+      fontmap[font.fontName][font.fontStyle] = font.id;
+    };
 
-          this.printingHeaderRow = true;
-          if (headerFunction !== undefined) {
-              var position = headerFunction(this, pages);
-              setLastCellPosition(position[0], position[1], position[2], position[3], -1);
-          }
-          this.setFontStyle('bold');
-          var tempHeaderConf = [];
-          for (i = 0, ln = this.tableHeaderRow.length; i < ln; i += 1) {
-              this.setFillColor(200, 200, 200);
-
-              tableHeaderCell = this.tableHeaderRow[i];
-              if (new_page) {
-                  this.margins.top = margin;
-                  tableHeaderCell[1] = this.margins && this.margins.top || 0;
-                  tempHeaderConf.push(tableHeaderCell);
-              }
-              tmpArray = [].concat(tableHeaderCell);
-              this.cell.apply(this, tmpArray.concat(lineNumber));
-          }
-          if (tempHeaderConf.length > 0) {
-              this.setTableHeaderRow(tempHeaderConf);
-          }
-          this.setFontStyle('normal');
-          this.printingHeaderRow = false;
+    var addFont = function addFont(postScriptName, fontName, fontStyle, encoding, isStandardFont) {
+      var font = {
+        id: "F" + (Object.keys(fonts).length + 1).toString(10),
+        postScriptName: postScriptName,
+        fontName: fontName,
+        fontStyle: fontStyle,
+        encoding: encoding,
+        isStandardFont: isStandardFont || false,
+        metadata: {}
       };
-  })(jsPDF.API);
+      events.publish("addFont", {
+        font: font,
+        instance: this
+      });
+      fonts[font.id] = font;
+      addFontToFontDictionary(font);
+      return font.id;
+    };
 
-  /**
-   * jsPDF Context2D PlugIn Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv
-   *
-   * Licensed under the MIT License. http://opensource.org/licenses/mit-license
-   */
+    var addFonts = function addFonts(arrayOfFonts) {
+      for (var i = 0, l = standardFonts.length; i < l; i++) {
+        var fontKey = addFont.call(this, arrayOfFonts[i][0], arrayOfFonts[i][1], arrayOfFonts[i][2], standardFonts[i][3], true);
 
-  /**
-   * This plugin mimics the HTML5 Canvas's context2d.
-   *
-   * The goal is to provide a way for current canvas implementations to print directly to a PDF.
-   */
+        if (putOnlyUsedFonts === false) {
+          usedFonts[fontKey] = true;
+        } // adding aliases for standard fonts, this time matching the capitalization
 
-  /**
-   * TODO implement stroke opacity (refactor from fill() method )
-   * TODO transform angle and radii parameters
-   */
 
-  /**
-   * require('jspdf.js'); require('lib/css_colors.js');
-   */
+        var parts = arrayOfFonts[i][0].split("-");
+        addFontToFontDictionary({
+          id: fontKey,
+          fontName: parts[0],
+          fontStyle: parts[1] || ""
+        });
+      }
 
-  (function (jsPDFAPI) {
+      events.publish("addFonts", {
+        fonts: fonts,
+        dictionary: fontmap
+      });
+    };
 
-      jsPDFAPI.events.push(['initialized', function () {
-          this.context2d.pdf = this;
-          this.context2d.internal.pdf = this;
-          this.context2d.ctx = new context();
-          this.context2d.ctxStack = [];
-          this.context2d.path = [];
-      }]);
-
-      jsPDFAPI.context2d = {
-          pageWrapXEnabled: false,
-          pageWrapYEnabled: false,
-          pageWrapX: 9999999,
-          pageWrapY: 9999999,
-          ctx: new context(),
-          f2: function f2(number) {
-              return number.toFixed(2);
-          },
+    var SAFE = function __safeCall(fn) {
+      fn.foo = function __safeCallWrapper() {
+        try {
+          return fn.apply(this, arguments);
+        } catch (e) {
+          var stack = e.stack || "";
+          if (~stack.indexOf(" at ")) stack = stack.split(" at ")[1];
+          var m = "Error in function " + stack.split("\n")[0].split("<")[0] + ": " + e.message;
+
+          if (globalObject.console) {
+            globalObject.console.error(m, e);
+            if (globalObject.alert) alert(m);
+          } else {
+            throw new Error(m);
+          }
+        }
+      };
 
-          fillRect: function fillRect(x, y, w, h) {
-              if (this._isFillTransparent()) {
-                  return;
-              }
-              x = this._wrapX(x);
-              y = this._wrapY(y);
+      fn.foo.bar = fn;
+      return fn.foo;
+    };
 
-              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });
-              this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, "f");
-          },
+    var to8bitStream = function to8bitStream(text, flags) {
+      /**
+       * PDF 1.3 spec:
+       * "For text strings encoded in Unicode, the first two bytes must be 254 followed by
+       * 255, representing the Unicode byte order marker, U+FEFF. (This sequence conflicts
+       * with the PDFDocEncoding character sequence thorn ydieresis, which is unlikely
+       * to be a meaningful beginning of a word or phrase.) The remainder of the
+       * string consists of Unicode character codes, according to the UTF-16 encoding
+       * specified in the Unicode standard, version 2.0. Commonly used Unicode values
+       * are represented as 2 bytes per character, with the high-order byte appearing first
+       * in the string."
+       *
+       * In other words, if there are chars in a string with char code above 255, we
+       * recode the string to UCS2 BE - string doubles in length and BOM is prepended.
+       *
+       * HOWEVER!
+       * Actual *content* (body) text (as opposed to strings used in document properties etc)
+       * does NOT expect BOM. There, it is treated as a literal GID (Glyph ID)
+       *
+       * Because of Adobe's focus on "you subset your fonts!" you are not supposed to have
+       * a font that maps directly Unicode (UCS2 / UTF16BE) code to font GID, but you could
+       * fudge it with "Identity-H" encoding and custom CIDtoGID map that mimics Unicode
+       * code page. There, however, all characters in the stream are treated as GIDs,
+       * including BOM, which is the reason we need to skip BOM in content text (i.e. that
+       * that is tied to a font).
+       *
+       * To signal this "special" PDFEscape / to8bitStream handling mode,
+       * API.text() function sets (unless you overwrite it with manual values
+       * given to API.text(.., flags) )
+       * flags.autoencode = true
+       * flags.noBOM = true
+       *
+       * ===================================================================================
+       * `flags` properties relied upon:
+       *   .sourceEncoding = string with encoding label.
+       *                     "Unicode" by default. = encoding of the incoming text.
+       *                     pass some non-existing encoding name
+       *                     (ex: 'Do not touch my strings! I know what I am doing.')
+       *                     to make encoding code skip the encoding step.
+       *   .outputEncoding = Either valid PDF encoding name
+       *                     (must be supported by jsPDF font metrics, otherwise no encoding)
+       *                     or a JS object, where key = sourceCharCode, value = outputCharCode
+       *                     missing keys will be treated as: sourceCharCode === outputCharCode
+       *   .noBOM
+       *       See comment higher above for explanation for why this is important
+       *   .autoencode
+       *       See comment higher above for explanation for why this is important
+       */
+      var i, l, sourceEncoding, encodingBlock, outputEncoding, newtext, isUnicode, ch, bch;
+      flags = flags || {};
+      sourceEncoding = flags.sourceEncoding || "Unicode";
+      outputEncoding = flags.outputEncoding; // This 'encoding' section relies on font metrics format
+      // attached to font objects by, among others,
+      // "Willow Systems' standard_font_metrics plugin"
+      // see jspdf.plugin.standard_font_metrics.js for format
+      // of the font.metadata.encoding Object.
+      // It should be something like
+      //   .encoding = {'codePages':['WinANSI....'], 'WinANSI...':{code:code, ...}}
+      //   .widths = {0:width, code:width, ..., 'fof':divisor}
+      //   .kerning = {code:{previous_char_code:shift, ..., 'fof':-divisor},...}
+
+      if ((flags.autoencode || outputEncoding) && fonts[activeFontKey].metadata && fonts[activeFontKey].metadata[sourceEncoding] && fonts[activeFontKey].metadata[sourceEncoding].encoding) {
+        encodingBlock = fonts[activeFontKey].metadata[sourceEncoding].encoding; // each font has default encoding. Some have it clearly defined.
+
+        if (!outputEncoding && fonts[activeFontKey].encoding) {
+          outputEncoding = fonts[activeFontKey].encoding;
+        } // Hmmm, the above did not work? Let's try again, in different place.
+
+
+        if (!outputEncoding && encodingBlock.codePages) {
+          outputEncoding = encodingBlock.codePages[0]; // let's say, first one is the default
+        }
 
-          strokeRect: function strokeRect(x, y, w, h) {
-              if (this._isStrokeTransparent()) {
-                  return;
-              }
-              x = this._wrapX(x);
-              y = this._wrapY(y);
+        if (typeof outputEncoding === "string") {
+          outputEncoding = encodingBlock[outputEncoding];
+        } // we want output encoding to be a JS Object, where
+        // key = sourceEncoding's character code and
+        // value = outputEncoding's character code.
 
-              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });
-              this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, "s");
-          },
 
-          /**
-           * We cannot clear PDF commands that were already written to PDF, so we use white instead. <br />
-           * As a special case, read a special flag (ignoreClearRect) and do nothing if it is set.
-           * This results in all calls to clearRect() to do nothing, and keep the canvas transparent.
-           * This flag is stored in the save/restore context and is managed the same way as other drawing states.
-           * @param x
-           * @param y
-           * @param w
-           * @param h
-           */
-          clearRect: function clearRect(x, y, w, h) {
-              if (this.ctx.ignoreClearRect) {
-                  return;
-              }
+        if (outputEncoding) {
+          isUnicode = false;
+          newtext = [];
 
-              x = this._wrapX(x);
-              y = this._wrapY(y);
+          for (i = 0, l = text.length; i < l; i++) {
+            ch = outputEncoding[text.charCodeAt(i)];
 
-              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });
-              this.save();
-              this.setFillStyle('#ffffff');
-              //TODO This is hack to fill with white.
-              this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, "f");
-              this.restore();
-          },
+            if (ch) {
+              newtext.push(String.fromCharCode(ch));
+            } else {
+              newtext.push(text[i]);
+            } // since we are looping over chars anyway, might as well
+            // check for residual unicodeness
 
-          save: function save() {
-              this.ctx._fontSize = this.pdf.internal.getFontSize();
-              var ctx = new context();
-              ctx.copy(this.ctx);
-              this.ctxStack.push(this.ctx);
-              this.ctx = ctx;
-          },
 
-          restore: function restore() {
-              this.ctx = this.ctxStack.pop();
-              this.setFillStyle(this.ctx.fillStyle);
-              this.setStrokeStyle(this.ctx.strokeStyle);
-              this.setFont(this.ctx.font);
-              this.pdf.setFontSize(this.ctx._fontSize);
-              this.setLineCap(this.ctx.lineCap);
-              this.setLineWidth(this.ctx.lineWidth);
-              this.setLineJoin(this.ctx.lineJoin);
-          },
+            if (newtext[i].charCodeAt(0) >> 8) {
+              /* more than 255 */
+              isUnicode = true;
+            }
+          }
 
-          rect: function rect(x, y, w, h) {
-              this.moveTo(x, y);
-              this.lineTo(x + w, y);
-              this.lineTo(x + w, y + h);
-              this.lineTo(x, y + h);
-              this.lineTo(x, y); //TODO not needed
-              this.closePath();
-          },
+          text = newtext.join("");
+        }
+      }
 
-          beginPath: function beginPath() {
-              this.path = [];
-          },
+      i = text.length; // isUnicode may be set to false above. Hence the triple-equal to undefined
 
-          closePath: function closePath() {
-              this.path.push({
-                  type: 'close'
-              });
-          },
+      while (isUnicode === undefined && i !== 0) {
+        if (text.charCodeAt(i - 1) >> 8) {
+          /* more than 255 */
+          isUnicode = true;
+        }
 
-          _getRGBA: function _getRGBA(style) {
-              // get the decimal values of r, g, and b;
-              var r, g, b, a;
-              var rgbColor = new RGBColor(style);
+        i--;
+      }
 
-              if (!style) {
-                  return { r: 0, g: 0, b: 0, a: 0, style: style };
-              }
+      if (!isUnicode) {
+        return text;
+      }
 
-              if (this.internal.rxTransparent.test(style)) {
-                  r = 0;
-                  g = 0;
-                  b = 0;
-                  a = 0;
-              } else {
-                  var m = this.internal.rxRgb.exec(style);
-                  if (m != null) {
-                      r = parseInt(m[1]);
-                      g = parseInt(m[2]);
-                      b = parseInt(m[3]);
-                      a = 1;
-                  } else {
-                      m = this.internal.rxRgba.exec(style);
-                      if (m != null) {
-                          r = parseInt(m[1]);
-                          g = parseInt(m[2]);
-                          b = parseInt(m[3]);
-                          a = parseFloat(m[4]);
-                      } else {
-                          a = 1;
-                          if (style.charAt(0) != '#') {
-                              if (rgbColor.ok) {
-                                  style = rgbColor.toHex();
-                              } else {
-                                  style = '#000000';
-                              }
-                          }
+      newtext = flags.noBOM ? [] : [254, 255];
 
-                          if (style.length === 4) {
-                              r = style.substring(1, 2);
-                              r += r;
-                              g = style.substring(2, 3);
-                              g += g;
-                              b = style.substring(3, 4);
-                              b += b;
-                          } else {
-                              r = style.substring(1, 3);
-                              g = style.substring(3, 5);
-                              b = style.substring(5, 7);
-                          }
-                          r = parseInt(r, 16);
-                          g = parseInt(g, 16);
-                          b = parseInt(b, 16);
-                      }
-                  }
-              }
-              return { r: r, g: g, b: b, a: a, style: style };
-          },
+      for (i = 0, l = text.length; i < l; i++) {
+        ch = text.charCodeAt(i);
+        bch = ch >> 8; // divide by 256
 
-          setFillStyle: function setFillStyle(style) {
-              var rgba = this._getRGBA(style);
+        if (bch >> 8) {
+          /* something left after dividing by 256 second time */
+          throw new Error("Character at position " + i + " of string '" + text + "' exceeds 16bits. Cannot be encoded into UCS-2 BE");
+        }
 
-              this.ctx.fillStyle = style;
-              this.ctx._isFillTransparent = rgba.a === 0;
-              this.ctx._fillOpacity = rgba.a;
+        newtext.push(bch);
+        newtext.push(ch - (bch << 8));
+      }
 
-              this.pdf.setFillColor(rgba.r, rgba.g, rgba.b, {
-                  a: rgba.a
-              });
-              this.pdf.setTextColor(rgba.r, rgba.g, rgba.b, {
-                  a: rgba.a
-              });
-          },
+      return String.fromCharCode.apply(undefined, newtext);
+    };
 
-          setStrokeStyle: function setStrokeStyle(style) {
-              var rgba = this._getRGBA(style);
+    var pdfEscape = API.__private__.pdfEscape = API.pdfEscape = function (text, flags) {
+      /**
+       * Replace '/', '(', and ')' with pdf-safe versions
+       *
+       * Doing to8bitStream does NOT make this PDF display unicode text. For that
+       * we also need to reference a unicode font and embed it - royal pain in the rear.
+       *
+       * There is still a benefit to to8bitStream - PDF simply cannot handle 16bit chars,
+       * which JavaScript Strings are happy to provide. So, while we still cannot display
+       * 2-byte characters property, at least CONDITIONALLY converting (entire string containing)
+       * 16bit chars to (USC-2-BE) 2-bytes per char + BOM streams we ensure that entire PDF
+       * is still parseable.
+       * This will allow immediate support for unicode in document properties strings.
+       */
+      return to8bitStream(text, flags).replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)");
+    };
 
-              this.ctx.strokeStyle = rgba.style;
-              this.ctx._isStrokeTransparent = rgba.a === 0;
-              this.ctx._strokeOpacity = rgba.a;
+    var beginPage = API.__private__.beginPage = function (format) {
+      pages[++page] = [];
+      pagesContext[page] = {
+        objId: 0,
+        contentsObjId: 0,
+        userUnit: Number(userUnit),
+        artBox: null,
+        bleedBox: null,
+        cropBox: null,
+        trimBox: null,
+        mediaBox: {
+          bottomLeftX: 0,
+          bottomLeftY: 0,
+          topRightX: Number(format[0]),
+          topRightY: Number(format[1])
+        }
+      };
 
-              //TODO jsPDF to handle rgba
-              if (rgba.a === 0) {
-                  this.pdf.setDrawColor(255, 255, 255);
-              } else if (rgba.a === 1) {
-                  this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b);
-              } else {
-                  //this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b, {a: rgba.a});
-                  this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b);
-              }
-          },
+      _setPage(page);
 
-          fillText: function fillText(text, x, y, maxWidth) {
-              if (this._isFillTransparent()) {
-                  return;
-              }
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
-              x = xpt[0];
-              y = xpt[1];
-              var rads = this._matrix_rotation(this.ctx._transform);
-              var degs = rads * 57.2958;
-
-              //TODO only push the clip if it has not been applied to the current PDF context
-              if (this.ctx._clip_path.length > 0) {
-                  var lines;
-                  if (window.outIntercept) {
-                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
-                  } else {
-                      lines = this.internal.getCurrentPage();
-                  }
-                  lines.push("q");
-                  var origPath = this.path;
-                  this.path = this.ctx._clip_path;
-                  this.ctx._clip_path = [];
-                  this._fill(null, true);
-                  this.ctx._clip_path = this.path;
-                  this.path = origPath;
-              }
+      setOutputDestination(pages[currentPage]);
+    };
 
-              // We only use X axis as scale hint 
-              var scale = 1;
-              try {
-                  scale = this._matrix_decompose(this._getTransform()).scale[0];
-              } catch (e) {
-                  console.warn(e);
-              }
+    var _addPage = function _addPage(parmFormat, parmOrientation) {
+      var dimensions, width, height;
+      orientation = parmOrientation || orientation;
 
-              // In some cases the transform was very small (5.715760606202283e-17).  Most likely a canvg rounding error.
-              if (scale < 0.01) {
-                  this.pdf.text(text, x, this._getBaseline(y), null, degs);
-              } else {
-                  var oldSize = this.pdf.internal.getFontSize();
-                  this.pdf.setFontSize(oldSize * scale);
-                  this.pdf.text(text, x, this._getBaseline(y), null, degs);
-                  this.pdf.setFontSize(oldSize);
-              }
+      if (typeof parmFormat === "string") {
+        dimensions = getPageFormat(parmFormat.toLowerCase());
 
-              if (this.ctx._clip_path.length > 0) {
-                  lines.push('Q');
-              }
-          },
+        if (Array.isArray(dimensions)) {
+          width = dimensions[0];
+          height = dimensions[1];
+        }
+      }
 
-          strokeText: function strokeText(text, x, y, maxWidth) {
-              if (this._isStrokeTransparent()) {
-                  return;
-              }
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
-              x = xpt[0];
-              y = xpt[1];
-              var rads = this._matrix_rotation(this.ctx._transform);
-              var degs = rads * 57.2958;
-
-              //TODO only push the clip if it has not been applied to the current PDF context
-              if (this.ctx._clip_path.length > 0) {
-                  var lines;
-                  if (window.outIntercept) {
-                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
-                  } else {
-                      lines = this.internal.getCurrentPage();
-                  }
-                  lines.push("q");
-                  var origPath = this.path;
-                  this.path = this.ctx._clip_path;
-                  this.ctx._clip_path = [];
-                  this._fill(null, true);
-                  this.ctx._clip_path = this.path;
-                  this.path = origPath;
-              }
+      if (Array.isArray(parmFormat)) {
+        width = parmFormat[0] * scaleFactor;
+        height = parmFormat[1] * scaleFactor;
+      }
 
-              var scale = 1;
-              // We only use the X axis as scale hint 
-              try {
-                  scale = this._matrix_decompose(this._getTransform()).scale[0];
-              } catch (e) {
-                  console.warn(e);
-              }
+      if (isNaN(width)) {
+        width = format[0];
+        height = format[1];
+      }
 
-              if (scale === 1) {
-                  this.pdf.text(text, x, this._getBaseline(y), {
-                      stroke: true
-                  }, degs);
-              } else {
-                  var oldSize = this.pdf.internal.getFontSize();
-                  this.pdf.setFontSize(oldSize * scale);
-                  this.pdf.text(text, x, this._getBaseline(y), {
-                      stroke: true
-                  }, degs);
-                  this.pdf.setFontSize(oldSize);
-              }
+      if (width > 14400 || height > 14400) {
+        console.warn("A page in a PDF can not be wider or taller than 14400 userUnit. jsPDF limits the width/height to 14400");
+        width = Math.min(14400, width);
+        height = Math.min(14400, height);
+      }
 
-              if (this.ctx._clip_path.length > 0) {
-                  lines.push('Q');
-              }
-          },
+      format = [width, height];
 
-          setFont: function setFont(font) {
-              this.ctx.font = font;
-
-              //var rx = /\s*(\w+)\s+(\w+)\s+(\w+)\s+([\d\.]+)(px|pt|em)\s+["']?(\w+)['"]?/;
-              var rx = /\s*(\w+)\s+(\w+)\s+(\w+)\s+([\d\.]+)(px|pt|em)\s+(.*)?/;
-              m = rx.exec(font);
-              if (m != null) {
-                  var fontStyle = m[1];
-                  var fontVariant = m[2];
-                  var fontWeight = m[3];
-                  var fontSize = m[4];
-                  var fontSizeUnit = m[5];
-                  var fontFamily = m[6];
-
-                  if ('px' === fontSizeUnit) {
-                      fontSize = Math.floor(parseFloat(fontSize));
-                      // fontSize = fontSize * 1.25;
-                  } else if ('em' === fontSizeUnit) {
-                      fontSize = Math.floor(parseFloat(fontSize) * this.pdf.getFontSize());
-                  } else {
-                      fontSize = Math.floor(parseFloat(fontSize));
-                  }
+      switch (orientation.substr(0, 1)) {
+        case "l":
+          if (height > width) {
+            format = [height, width];
+          }
 
-                  this.pdf.setFontSize(fontSize);
+          break;
 
-                  if (fontWeight === 'bold' || fontWeight === '700') {
-                      this.pdf.setFontStyle('bold');
-                  } else {
-                      if (fontStyle === 'italic') {
-                          this.pdf.setFontStyle('italic');
-                      } else {
-                          this.pdf.setFontStyle('normal');
-                      }
-                  }
-                  var style;
-                  if ('bold' === fontWeight || fontWeight === '700') {
-                      style = fontStyle === 'italic' ? 'bolditalic' : 'bold';
-                  } else if (fontStyle === 'italic') {
-                      style = 'italic';
-                  } else {
-                      style = 'normal';
-                  }
+        case "p":
+          if (width > height) {
+            format = [height, width];
+          }
 
-                  var parts = fontFamily.toLowerCase().split(/\s*,\s*/);
-                  var jsPdfFontName = 'Times';
+          break;
+      }
 
-                  for (var i = 0; i < parts.length; i++) {
-                      if (this.pdf.internal.getFont(parts[i], style, { noFallback: true, disableWarning: true }) !== undefined) {
-                          jsPdfFontName = parts[i];
-                          break;
-                      } else if (style === 'bolditalic' && this.pdf.internal.getFont(parts[i], 'bold', { noFallback: true, disableWarning: true }) !== undefined) {
-                          jsPdfFontName = parts[i];
-                          style = 'bold';
-                      } else if (this.pdf.internal.getFont(parts[i], 'normal', { noFallback: true, disableWarning: true }) !== undefined) {
-                          jsPdfFontName = parts[i];
-                          style = 'normal';
-                          break;
-                      }
-                  }
+      beginPage(format); // Set line width
 
-                  this.pdf.setFont(jsPdfFontName, style);
-              } else {
-                  var rx = /\s*(\d+)(pt|px|em)\s+([\w "]+)\s*([\w "]+)?/;
-                  var m = rx.exec(font);
-                  if (m != null) {
-                      var size = m[1];
-                      var unit = m[2];
-                      var name = m[3];
-                      var style = m[4];
-                      if (!style) {
-                          style = 'normal';
-                      }
-                      if ('em' === fontSizeUnit) {
-                          size = Math.floor(parseFloat(fontSize) * this.pdf.getFontSize());
-                      } else {
-                          size = Math.floor(parseFloat(size));
-                      }
-                      this.pdf.setFontSize(size);
-                      this.pdf.setFont(name, style);
-                  }
-              }
-          },
+      setLineWidth(lineWidth); // Set draw color
 
-          setTextBaseline: function setTextBaseline(baseline) {
-              this.ctx.textBaseline = baseline;
-          },
+      out(strokeColor); // resurrecting non-default line caps, joins
 
-          getTextBaseline: function getTextBaseline() {
-              return this.ctx.textBaseline;
-          },
+      if (lineCapID !== 0) {
+        out(lineCapID + " J");
+      }
 
-          //TODO implement textAlign
-          setTextAlign: function setTextAlign(align) {
-              this.ctx.textAlign = align;
-          },
+      if (lineJoinID !== 0) {
+        out(lineJoinID + " j");
+      }
 
-          getTextAlign: function getTextAlign() {
-              return this.ctx.textAlign;
-          },
+      events.publish("addPage", {
+        pageNumber: page
+      });
+    };
 
-          setLineWidth: function setLineWidth(width) {
-              this.ctx.lineWidth = width;
-              this.pdf.setLineWidth(width);
-          },
+    var _deletePage = function _deletePage(n) {
+      if (n > 0 && n <= page) {
+        pages.splice(n, 1);
+        pagesContext.splice(n, 1);
+        page--;
 
-          setLineCap: function setLineCap(style) {
-              this.ctx.lineCap = style;
-              this.pdf.setLineCap(style);
-          },
+        if (currentPage > page) {
+          currentPage = page;
+        }
 
-          setLineJoin: function setLineJoin(style) {
-              this.ctx.lineJoin = style;
-              this.pdf.setLineJoin(style);
-          },
+        this.setPage(currentPage);
+      }
+    };
 
-          moveTo: function moveTo(x, y) {
-              x = this._wrapX(x);
-              y = this._wrapY(y);
+    var _setPage = function _setPage(n) {
+      if (n > 0 && n <= page) {
+        currentPage = n;
+      }
+    };
 
-              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
-              x = xpt[0];
-              y = xpt[1];
+    var getNumberOfPages = API.__private__.getNumberOfPages = API.getNumberOfPages = function () {
+      return pages.length - 1;
+    };
+    /**
+     * Returns a document-specific font key - a label assigned to a
+     * font name + font type combination at the time the font was added
+     * to the font inventory.
+     *
+     * Font key is used as label for the desired font for a block of text
+     * to be added to the PDF document stream.
+     * @private
+     * @function
+     * @param fontName {string} can be undefined on "falthy" to indicate "use current"
+     * @param fontStyle {string} can be undefined on "falthy" to indicate "use current"
+     * @returns {string} Font key.
+     * @ignore
+     */
 
-              var obj = {
-                  type: 'mt',
-                  x: x,
-                  y: y
-              };
-              this.path.push(obj);
-          },
 
-          _wrapX: function _wrapX(x) {
-              if (this.pageWrapXEnabled) {
-                  return x % this.pageWrapX;
-              } else {
-                  return x;
-              }
-          },
+    var getFont = function getFont(fontName, fontStyle, options) {
+      var key = undefined,
+          fontNameLowerCase;
+      options = options || {};
+      fontName = fontName !== undefined ? fontName : fonts[activeFontKey].fontName;
+      fontStyle = fontStyle !== undefined ? fontStyle : fonts[activeFontKey].fontStyle;
+      fontNameLowerCase = fontName.toLowerCase();
+
+      if (fontmap[fontNameLowerCase] !== undefined && fontmap[fontNameLowerCase][fontStyle] !== undefined) {
+        key = fontmap[fontNameLowerCase][fontStyle];
+      } else if (fontmap[fontName] !== undefined && fontmap[fontName][fontStyle] !== undefined) {
+        key = fontmap[fontName][fontStyle];
+      } else {
+        if (options.disableWarning === false) {
+          console.warn("Unable to look up font label for font '" + fontName + "', '" + fontStyle + "'. Refer to getFontList() for available fonts.");
+        }
+      }
 
-          _wrapY: function _wrapY(y) {
-              if (this.pageWrapYEnabled) {
-                  this._gotoPage(this._page(y));
-                  return (y - this.lastBreak) % this.pageWrapY;
-              } else {
-                  return y;
-              }
-          },
+      if (!key && !options.noFallback) {
+        key = fontmap["times"][fontStyle];
 
-          transform: function transform(a, b, c, d, e, f) {
-              this.ctx._transform = this._matrix_multiply(this.ctx._transform, [a, b, c, d, e, f]);
-          },
+        if (key == null) {
+          key = fontmap["times"]["normal"];
+        }
+      }
 
-          setTransform: function setTransform(a, b, c, d, e, f) {
-              this.ctx._transform = [a, b, c, d, e, f];
-          },
+      return key;
+    };
 
-          _getTransform: function _getTransform() {
-              return this.ctx._transform;
-          },
+    var putInfo = API.__private__.putInfo = function () {
+      var objectId = newObject();
 
-          lastBreak: 0,
-          // Y Position of page breaks.
-          pageBreaks: [],
-          // returns: One-based Page Number
-          // Should only be used if pageWrapYEnabled is true
-          _page: function _page(y) {
-              if (this.pageWrapYEnabled) {
-                  this.lastBreak = 0;
-                  var manualBreaks = 0;
-                  var autoBreaks = 0;
-                  for (var i = 0; i < this.pageBreaks.length; i++) {
-                      if (y >= this.pageBreaks[i]) {
-                          manualBreaks++;
-                          if (this.lastBreak === 0) {
-                              autoBreaks++;
-                          }
-                          var spaceBetweenLastBreak = this.pageBreaks[i] - this.lastBreak;
-                          this.lastBreak = this.pageBreaks[i];
-                          var pagesSinceLastBreak = Math.floor(spaceBetweenLastBreak / this.pageWrapY);
-                          autoBreaks += pagesSinceLastBreak;
-                      }
-                  }
-                  if (this.lastBreak === 0) {
-                      var pagesSinceLastBreak = Math.floor(y / this.pageWrapY) + 1;
-                      autoBreaks += pagesSinceLastBreak;
-                  }
-                  return autoBreaks + manualBreaks;
-              } else {
-                  return this.pdf.internal.getCurrentPageInfo().pageNumber;
-              }
-          },
+      var encryptor = function encryptor(data) {
+        return data;
+      };
 
-          _gotoPage: function _gotoPage(pageOneBased) {
-              // This is a stub to be overriden if needed
-          },
+      if (encryptionOptions !== null) {
+        encryptor = encryption.encryptor(objectId, 0);
+      }
 
-          lineTo: function lineTo(x, y) {
-              x = this._wrapX(x);
-              y = this._wrapY(y);
+      out("<<");
+      out("/Producer (" + pdfEscape(encryptor("jsPDF " + jsPDF.version)) + ")");
 
-              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
-              x = xpt[0];
-              y = xpt[1];
+      for (var key in documentProperties) {
+        if (documentProperties.hasOwnProperty(key) && documentProperties[key]) {
+          out("/" + key.substr(0, 1).toUpperCase() + key.substr(1) + " (" + pdfEscape(encryptor(documentProperties[key])) + ")");
+        }
+      }
 
-              var obj = {
-                  type: 'lt',
-                  x: x,
-                  y: y
-              };
-              this.path.push(obj);
-          },
+      out("/CreationDate (" + pdfEscape(encryptor(creationDate)) + ")");
+      out(">>");
+      out("endobj");
+    };
 
-          bezierCurveTo: function bezierCurveTo(x1, y1, x2, y2, x, y) {
-              x1 = this._wrapX(x1);
-              y1 = this._wrapY(y1);
-              x2 = this._wrapX(x2);
-              y2 = this._wrapY(y2);
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xpt;
-              xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
-              x = xpt[0];
-              y = xpt[1];
-              xpt = this._matrix_map_point(this.ctx._transform, [x1, y1]);
-              x1 = xpt[0];
-              y1 = xpt[1];
-              xpt = this._matrix_map_point(this.ctx._transform, [x2, y2]);
-              x2 = xpt[0];
-              y2 = xpt[1];
-
-              var obj = {
-                  type: 'bct',
-                  x1: x1,
-                  y1: y1,
-                  x2: x2,
-                  y2: y2,
-                  x: x,
-                  y: y
-              };
-              this.path.push(obj);
-          },
+    var putCatalog = API.__private__.putCatalog = function (options) {
+      options = options || {};
+      var tmpRootDictionaryObjId = options.rootDictionaryObjId || rootDictionaryObjId;
+      newObject();
+      out("<<");
+      out("/Type /Catalog");
+      out("/Pages " + tmpRootDictionaryObjId + " 0 R"); // PDF13ref Section 7.2.1
 
-          quadraticCurveTo: function quadraticCurveTo(x1, y1, x, y) {
-              x1 = this._wrapX(x1);
-              y1 = this._wrapY(y1);
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xpt;
-              xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
-              x = xpt[0];
-              y = xpt[1];
-              xpt = this._matrix_map_point(this.ctx._transform, [x1, y1]);
-              x1 = xpt[0];
-              y1 = xpt[1];
-
-              var obj = {
-                  type: 'qct',
-                  x1: x1,
-                  y1: y1,
-                  x: x,
-                  y: y
-              };
-              this.path.push(obj);
-          },
+      if (!zoomMode) zoomMode = "fullwidth";
 
-          arc: function arc(x, y, radius, startAngle, endAngle, anticlockwise) {
-              x = this._wrapX(x);
-              y = this._wrapY(y);
+      switch (zoomMode) {
+        case "fullwidth":
+          out("/OpenAction [3 0 R /FitH null]");
+          break;
 
-              if (!this._matrix_is_identity(this.ctx._transform)) {
-                  var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
-                  x = xpt[0];
-                  y = xpt[1];
+        case "fullheight":
+          out("/OpenAction [3 0 R /FitV null]");
+          break;
 
-                  var x_radPt0 = this._matrix_map_point(this.ctx._transform, [0, 0]);
-                  var x_radPt = this._matrix_map_point(this.ctx._transform, [0, radius]);
-                  radius = Math.sqrt(Math.pow(x_radPt[0] - x_radPt0[0], 2) + Math.pow(x_radPt[1] - x_radPt0[1], 2));
+        case "fullpage":
+          out("/OpenAction [3 0 R /Fit]");
+          break;
 
-                  //TODO angles need to be transformed
-              }
+        case "original":
+          out("/OpenAction [3 0 R /XYZ null null 1]");
+          break;
 
-              var obj = {
-                  type: 'arc',
-                  x: x,
-                  y: y,
-                  radius: radius,
-                  startAngle: startAngle,
-                  endAngle: endAngle,
-                  anticlockwise: anticlockwise
-              };
-              this.path.push(obj);
-          },
+        default:
+          var pcn = "" + zoomMode;
+          if (pcn.substr(pcn.length - 1) === "%") zoomMode = parseInt(zoomMode) / 100;
 
-          drawImage: function drawImage(img, x, y, w, h, x2, y2, w2, h2) {
-              if (x2 !== undefined) {
-                  x = x2;
-                  y = y2;
-                  w = w2;
-                  h = h2;
-              }
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });
-              var xRect2 = this._matrix_map_rect(this.ctx._transform, { x: x2, y: y2, w: w2, h: h2 });
-
-              // TODO implement source clipping and image scaling
-              var format;
-              var rx = /data:image\/(\w+).*/i;
-              var m = rx.exec(img);
-              if (m != null) {
-                  format = m[1];
-              } else {
-                  // format = "jpeg";
-                  format = "png";
-              }
+          if (typeof zoomMode === "number") {
+            out("/OpenAction [3 0 R /XYZ null null " + f2(zoomMode) + "]");
+          }
 
-              this.pdf.addImage(img, format, xRect.x, xRect.y, xRect.w, xRect.h);
-          },
+      }
 
-          /**
-           * Multiply the first matrix by the second
-           * @param m1
-           * @param m2
-           * @returns {*[]}
-           * @private
-           */
-          _matrix_multiply: function _matrix_multiply(m2, m1) {
-              var sx = m1[0];
-              var shy = m1[1];
-              var shx = m1[2];
-              var sy = m1[3];
-              var tx = m1[4];
-              var ty = m1[5];
-
-              var t0 = sx * m2[0] + shy * m2[2];
-              var t2 = shx * m2[0] + sy * m2[2];
-              var t4 = tx * m2[0] + ty * m2[2] + m2[4];
-              shy = sx * m2[1] + shy * m2[3];
-              sy = shx * m2[1] + sy * m2[3];
-              ty = tx * m2[1] + ty * m2[3] + m2[5];
-              sx = t0;
-              shx = t2;
-              tx = t4;
-
-              return [sx, shy, shx, sy, tx, ty];
-          },
+      if (!layoutMode) layoutMode = "continuous";
 
-          _matrix_rotation: function _matrix_rotation(m) {
-              return Math.atan2(m[2], m[0]);
-          },
+      switch (layoutMode) {
+        case "continuous":
+          out("/PageLayout /OneColumn");
+          break;
 
-          _matrix_decompose: function _matrix_decompose(matrix) {
+        case "single":
+          out("/PageLayout /SinglePage");
+          break;
 
-              var a = matrix[0];
-              var b = matrix[1];
-              var c = matrix[2];
-              var d = matrix[3];
+        case "two":
+        case "twoleft":
+          out("/PageLayout /TwoColumnLeft");
+          break;
 
-              var scaleX = Math.sqrt(a * a + b * b);
-              a /= scaleX;
-              b /= scaleX;
-
-              var shear = a * c + b * d;
-              c -= a * shear;
-              d -= b * shear;
-
-              var scaleY = Math.sqrt(c * c + d * d);
-              c /= scaleY;
-              d /= scaleY;
-              shear /= scaleY;
-
-              if (a * d < b * c) {
-                  a = -a;
-                  b = -b;
-                  shear = -shear;
-                  scaleX = -scaleX;
-              }
+        case "tworight":
+          out("/PageLayout /TwoColumnRight");
+          break;
+      }
 
-              return {
-                  scale: [scaleX, 0, 0, scaleY, 0, 0],
-                  translate: [1, 0, 0, 1, matrix[4], matrix[5]],
-                  rotate: [a, b, -b, a, 0, 0],
-                  skew: [1, 0, shear, 1, 0, 0]
-              };
-          },
+      if (pageMode) {
+        /**
+         * A name object specifying how the document should be displayed when opened:
+         * UseNone      : Neither document outline nor thumbnail images visible -- DEFAULT
+         * UseOutlines  : Document outline visible
+         * UseThumbs    : Thumbnail images visible
+         * FullScreen   : Full-screen mode, with no menu bar, window controls, or any other window visible
+         */
+        out("/PageMode /" + pageMode);
+      }
 
-          _matrix_map_point: function _matrix_map_point(m1, pt) {
-              var sx = m1[0];
-              var shy = m1[1];
-              var shx = m1[2];
-              var sy = m1[3];
-              var tx = m1[4];
-              var ty = m1[5];
+      events.publish("putCatalog");
+      out(">>");
+      out("endobj");
+    };
 
-              var px = pt[0];
-              var py = pt[1];
+    var putTrailer = API.__private__.putTrailer = function () {
+      out("trailer");
+      out("<<");
+      out("/Size " + (objectNumber + 1)); // Root and Info must be the last and second last objects written respectively
 
-              var x = px * sx + py * shx + tx;
-              var y = px * shy + py * sy + ty;
-              return [x, y];
-          },
+      out("/Root " + objectNumber + " 0 R");
+      out("/Info " + (objectNumber - 1) + " 0 R");
 
-          _matrix_map_point_obj: function _matrix_map_point_obj(m1, pt) {
-              var xpt = this._matrix_map_point(m1, [pt.x, pt.y]);
-              return { x: xpt[0], y: xpt[1] };
-          },
+      if (encryptionOptions !== null) {
+        out("/Encrypt " + encryption.oid + " 0 R");
+      }
 
-          _matrix_map_rect: function _matrix_map_rect(m1, rect) {
-              var p1 = this._matrix_map_point(m1, [rect.x, rect.y]);
-              var p2 = this._matrix_map_point(m1, [rect.x + rect.w, rect.y + rect.h]);
-              return { x: p1[0], y: p1[1], w: p2[0] - p1[0], h: p2[1] - p1[1] };
-          },
+      out("/ID [ <" + fileId + "> <" + fileId + "> ]");
+      out(">>");
+    };
 
-          _matrix_is_identity: function _matrix_is_identity(m1) {
-              if (m1[0] != 1) {
-                  return false;
-              }
-              if (m1[1] != 0) {
-                  return false;
-              }
-              if (m1[2] != 0) {
-                  return false;
-              }
-              if (m1[3] != 1) {
-                  return false;
-              }
-              if (m1[4] != 0) {
-                  return false;
-              }
-              if (m1[5] != 0) {
-                  return false;
-              }
-              return true;
-          },
+    var putHeader = API.__private__.putHeader = function () {
+      out("%PDF-" + pdfVersion);
+      out("%\xBA\xDF\xAC\xE0");
+    };
 
-          rotate: function rotate(angle) {
-              var matrix = [Math.cos(angle), Math.sin(angle), -Math.sin(angle), Math.cos(angle), 0.0, 0.0];
-              this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix);
-          },
+    var putXRef = API.__private__.putXRef = function () {
+      var p = "0000000000";
+      out("xref");
+      out("0 " + (objectNumber + 1));
+      out("0000000000 65535 f ");
 
-          scale: function scale(sx, sy) {
-              var matrix = [sx, 0.0, 0.0, sy, 0.0, 0.0];
-              this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix);
-          },
+      for (var i = 1; i <= objectNumber; i++) {
+        var offset = offsets[i];
 
-          translate: function translate(x, y) {
-              var matrix = [1.0, 0.0, 0.0, 1.0, x, y];
-              this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix);
-          },
+        if (typeof offset === "function") {
+          out((p + offsets[i]()).slice(-10) + " 00000 n ");
+        } else {
+          if (typeof offsets[i] !== "undefined") {
+            out((p + offsets[i]).slice(-10) + " 00000 n ");
+          } else {
+            out("0000000000 00000 n ");
+          }
+        }
+      }
+    };
 
-          stroke: function stroke() {
-              if (this.ctx._clip_path.length > 0) {
+    var buildDocument = API.__private__.buildDocument = function () {
+      resetDocument();
+      setOutputDestination(content);
+      events.publish("buildDocument");
+      putHeader();
+      putPages();
+      putAdditionalObjects();
+      putResources();
+      if (encryptionOptions !== null) putEncryptionDict();
+      putInfo();
+      putCatalog();
+      var offsetOfXRef = contentLength;
+      putXRef();
+      putTrailer();
+      out("startxref");
+      out("" + offsetOfXRef);
+      out("%%EOF");
+      setOutputDestination(pages[currentPage]);
+      return content.join("\n");
+    };
 
-                  var lines;
-                  if (window.outIntercept) {
-                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
-                  } else {
-                      lines = this.internal.getCurrentPage();
-                  }
-                  lines.push("q");
+    var getBlob = API.__private__.getBlob = function (data) {
+      return new Blob([getArrayBuffer(data)], {
+        type: "application/pdf"
+      });
+    };
+    /**
+     * Generates the PDF document.
+     *
+     * If `type` argument is undefined, output is raw body of resulting PDF returned as a string.
+     *
+     * @param {string} type A string identifying one of the possible output types.<br/>
+     *                      Possible values are: <br/>
+     *                          'arraybuffer' -> (ArrayBuffer)<br/>
+     *                          'blob' -> (Blob)<br/>
+     *                          'bloburi'/'bloburl' -> (string)<br/>
+     *                          'datauristring'/'dataurlstring' -> (string)<br/>
+     *                          'datauri'/'dataurl' -> (undefined) -> change location to generated datauristring/dataurlstring<br/>
+     *                          'dataurlnewwindow' -> (window | null | undefined) throws error if global isn't a window object(node)<br/>
+     *                          'pdfobjectnewwindow' -> (window | null) throws error if global isn't a window object(node)<br/>
+     *                          'pdfjsnewwindow' -> (wind | null)
+     * @param {Object|string} options An object providing some additional signalling to PDF generator.<br/>
+     *                                Possible options are 'filename'.<br/>
+     *                                A string can be passed instead of {filename:string} and defaults to 'generated.pdf'
+     * @function
+     * @instance
+     * @returns {string|window|ArrayBuffer|Blob|jsPDF|null|undefined}
+     * @memberof jsPDF#
+     * @name output
+     */
 
-                  var origPath = this.path;
-                  this.path = this.ctx._clip_path;
-                  this.ctx._clip_path = [];
-                  this._stroke(true);
 
-                  this.ctx._clip_path = this.path;
-                  this.path = origPath;
-                  this._stroke(false);
+    var output = API.output = API.__private__.output = SAFE(function output(type, options) {
+      options = options || {};
 
-                  lines.push("Q");
-              } else {
-                  this._stroke(false);
-              }
-          },
+      if (typeof options === "string") {
+        options = {
+          filename: options
+        };
+      } else {
+        options.filename = options.filename || "generated.pdf";
+      }
 
-          _stroke: function _stroke(isClip) {
-              if (!isClip && this._isStrokeTransparent()) {
-                  return;
-              }
+      switch (type) {
+        case undefined:
+          return buildDocument();
 
-              //TODO opacity
+        case "save":
+          API.save(options.filename);
+          break;
 
-              var moves = [];
+        case "arraybuffer":
+          return getArrayBuffer(buildDocument());
 
-              var xPath = this.path;
+        case "blob":
+          return getBlob(buildDocument());
 
-              for (var i = 0; i < xPath.length; i++) {
-                  var pt = xPath[i];
-                  switch (pt.type) {
-                      case 'mt':
-                          moves.push({ start: pt, deltas: [], abs: [] });
-                          break;
-                      case 'lt':
-                          var delta = [pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
-                          moves[moves.length - 1].deltas.push(delta);
-                          moves[moves.length - 1].abs.push(pt);
-                          break;
-                      case 'bct':
-                          var delta = [pt.x1 - xPath[i - 1].x, pt.y1 - xPath[i - 1].y, pt.x2 - xPath[i - 1].x, pt.y2 - xPath[i - 1].y, pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
-                          moves[moves.length - 1].deltas.push(delta);
-                          break;
-                      case 'qct':
-                          // convert to bezier
-                          var x1 = xPath[i - 1].x + 2.0 / 3.0 * (pt.x1 - xPath[i - 1].x);
-                          var y1 = xPath[i - 1].y + 2.0 / 3.0 * (pt.y1 - xPath[i - 1].y);
-                          var x2 = pt.x + 2.0 / 3.0 * (pt.x1 - pt.x);
-                          var y2 = pt.y + 2.0 / 3.0 * (pt.y1 - pt.y);
-                          var x3 = pt.x;
-                          var y3 = pt.y;
-                          var delta = [x1 - xPath[i - 1].x, y1 - xPath[i - 1].y, x2 - xPath[i - 1].x, y2 - xPath[i - 1].y, x3 - xPath[i - 1].x, y3 - xPath[i - 1].y];
-                          moves[moves.length - 1].deltas.push(delta);
-                          break;
-                      case 'arc':
-                          //TODO this was hack to avoid out-of-bounds issue
-                          // No move-to before drawing the arc
-                          if (moves.length == 0) {
-                              moves.push({ start: { x: 0, y: 0 }, deltas: [], abs: [] });
-                          }
-                          moves[moves.length - 1].arc = true;
-                          if (Array.isArray(moves[moves.length - 1].abs)) {
-                              moves[moves.length - 1].abs.push(pt);
-                          }
-                          break;
-                      case 'close':
-                          break;
-                  }
-              }
+        case "bloburi":
+        case "bloburl":
+          // Developer is responsible of calling revokeObjectURL
+          if (typeof globalObject.URL !== "undefined" && typeof globalObject.URL.createObjectURL === "function") {
+            return globalObject.URL && globalObject.URL.createObjectURL(getBlob(buildDocument())) || void 0;
+          } else {
+            console.warn("bloburl is not supported by your system, because URL.createObjectURL is not supported by your browser.");
+          }
 
-              for (var i = 0; i < moves.length; i++) {
-                  var style;
-                  if (i == moves.length - 1) {
-                      style = 's';
-                  } else {
-                      style = null;
-                  }
-                  if (moves[i].arc) {
-                      var arcs = moves[i].abs;
-                      for (var ii = 0; ii < arcs.length; ii++) {
-                          var arc = arcs[ii];
-                          var start = arc.startAngle * 360 / (2 * Math.PI);
-                          var end = arc.endAngle * 360 / (2 * Math.PI);
-                          var x = arc.x;
-                          var y = arc.y;
-                          this.internal.arc2(this, x, y, arc.radius, start, end, arc.anticlockwise, style, isClip);
-                      }
-                  } else {
-                      var x = moves[i].start.x;
-                      var y = moves[i].start.y;
-                      if (!isClip) {
-                          this.pdf.lines(moves[i].deltas, x, y, null, style);
-                      } else {
-                          this.pdf.lines(moves[i].deltas, x, y, null, null);
-                          this.pdf.clip_fixed();
-                      }
-                  }
-              }
-          },
+          break;
 
-          _isFillTransparent: function _isFillTransparent() {
-              return this.ctx._isFillTransparent || this.globalAlpha == 0;
-          },
+        case "datauristring":
+        case "dataurlstring":
+          var dataURI = "";
+          var pdfDocument = buildDocument();
 
-          _isStrokeTransparent: function _isStrokeTransparent() {
-              return this.ctx._isStrokeTransparent || this.globalAlpha == 0;
-          },
+          try {
+            dataURI = btoa(pdfDocument);
+          } catch (e) {
+            dataURI = btoa(unescape(encodeURIComponent(pdfDocument)));
+          }
 
-          fill: function fill(fillRule) {
-              //evenodd or nonzero (default)
-              if (this.ctx._clip_path.length > 0) {
+          return "data:application/pdf;filename=" + options.filename + ";base64," + dataURI;
 
-                  var lines;
-                  if (window.outIntercept) {
-                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
-                  } else {
-                      lines = this.internal.getCurrentPage();
-                  }
-                  lines.push("q");
+        case "pdfobjectnewwindow":
+          if (Object.prototype.toString.call(globalObject) === "[object Window]") {
+            var pdfObjectUrl = "https://cdnjs.cloudflare.com/ajax/libs/pdfobject/2.1.1/pdfobject.min.js";
+            var integrity = ' integrity="sha512-4ze/a9/4jqu+tX9dfOqJYSvyYd5M6qum/3HpCLr+/Jqf0whc37VUbkpNGHR7/8pSnCFw47T1fmIpwBV7UySh3g==" crossorigin="anonymous"';
 
-                  var origPath = this.path;
-                  this.path = this.ctx._clip_path;
-                  this.ctx._clip_path = [];
-                  this._fill(fillRule, true);
+            if (options.pdfObjectUrl) {
+              pdfObjectUrl = options.pdfObjectUrl;
+              integrity = "";
+            }
 
-                  this.ctx._clip_path = this.path;
-                  this.path = origPath;
-                  this._fill(fillRule, false);
+            var htmlForNewWindow = "<html>" + '<style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;}  </style><body><script src="' + pdfObjectUrl + '"' + integrity + '></script><script >PDFObject.embed("' + this.output("dataurlstring") + '", ' + JSON.stringify(options) + ");</script></body></html>";
+            var nW = globalObject.open();
 
-                  lines.push('Q');
-              } else {
-                  this._fill(fillRule, false);
-              }
-          },
+            if (nW !== null) {
+              nW.document.write(htmlForNewWindow);
+            }
 
-          _fill: function _fill(fillRule, isClip) {
-              if (this._isFillTransparent()) {
-                  return;
-              }
-              var v2Support = typeof this.pdf.internal.newObject2 === 'function';
+            return nW;
+          } else {
+            throw new Error("The option pdfobjectnewwindow just works in a browser-environment.");
+          }
 
-              var lines;
-              if (window.outIntercept) {
-                  lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
-              } else {
-                  lines = this.internal.getCurrentPage();
-              }
+        case "pdfjsnewwindow":
+          if (Object.prototype.toString.call(globalObject) === "[object Window]") {
+            var pdfJsUrl = options.pdfJsUrl || "examples/PDF.js/web/viewer.html";
+            var htmlForPDFjsNewWindow = "<html>" + "<style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;}  </style>" + '<body><iframe id="pdfViewer" src="' + pdfJsUrl + "?file=&downloadName=" + options.filename + '" width="500px" height="400px" />' + "</body></html>";
+            var PDFjsNewWindow = globalObject.open();
 
-              // if (this.ctx._clip_path.length > 0) {
-              //     lines.push('q');
-              //     var oldPath = this.path;
-              //     this.path = this.ctx._clip_path;
-              //     this.ctx._clip_path = [];
-              //     this._fill(fillRule, true);
-              //     this.ctx._clip_path = this.path;
-              //     this.path = oldPath;
-              //     lines.push('Q');
-              // }
-
-              var moves = [];
-              var outInterceptOld = window.outIntercept;
-
-              if (v2Support) {
-                  // Blend and Mask
-                  switch (this.ctx.globalCompositeOperation) {
-                      case 'normal':
-                      case 'source-over':
-                          break;
-                      case 'destination-in':
-                      case 'destination-out':
-                          //TODO this need to be added to the current group or page
-                          // define a mask stream
-                          var obj = this.pdf.internal.newStreamObject();
-
-                          // define a mask state
-                          var obj2 = this.pdf.internal.newObject2();
-                          obj2.push('<</Type /ExtGState');
-                          obj2.push('/SMask <</S /Alpha /G ' + obj.objId + ' 0 R>>'); // /S /Luminosity will need to define color space
-                          obj2.push('>>');
-
-                          // add mask to page resources
-                          var gsName = 'MASK' + obj2.objId;
-                          this.pdf.internal.addGraphicsState(gsName, obj2.objId);
-
-                          var instruction = '/' + gsName + ' gs';
-                          // add mask to page, group, or stream
-                          lines.splice(0, 0, 'q');
-                          lines.splice(1, 0, instruction);
-                          lines.push('Q');
-
-                          window.outIntercept = obj;
-                          break;
-                      default:
-                          var dictionaryEntry = '/' + this.pdf.internal.blendModeMap[this.ctx.globalCompositeOperation.toUpperCase()];
-                          if (dictionaryEntry) {
-                              this.pdf.internal.out(dictionaryEntry + ' gs');
-                          }
-                          break;
-                  }
-              }
+            if (PDFjsNewWindow !== null) {
+              PDFjsNewWindow.document.write(htmlForPDFjsNewWindow);
+              var scope = this;
 
-              var alpha = this.ctx.globalAlpha;
-              if (this.ctx._fillOpacity < 1) {
-                  // TODO combine this with global opacity
-                  alpha = this.ctx._fillOpacity;
-              }
+              PDFjsNewWindow.document.documentElement.querySelector("#pdfViewer").onload = function () {
+                PDFjsNewWindow.document.title = options.filename;
+                PDFjsNewWindow.document.documentElement.querySelector("#pdfViewer").contentWindow.PDFViewerApplication.open(scope.output("bloburl"));
+              };
+            }
 
-              //TODO check for an opacity graphics state that was already created
-              //TODO do not set opacity if current value is already active
-              if (v2Support) {
-                  var objOpac = this.pdf.internal.newObject2();
-                  objOpac.push('<</Type /ExtGState');
-                  //objOpac.push(this.ctx.globalAlpha + " CA"); // Stroke
-                  //objOpac.push(this.ctx.globalAlpha + " ca"); // Not Stroke
-                  objOpac.push('/CA ' + alpha); // Stroke
-                  objOpac.push('/ca ' + alpha); // Not Stroke
-                  objOpac.push('>>');
-                  var gsName = 'GS_O_' + objOpac.objId;
-                  this.pdf.internal.addGraphicsState(gsName, objOpac.objId);
-                  this.pdf.internal.out('/' + gsName + ' gs');
-              }
+            return PDFjsNewWindow;
+          } else {
+            throw new Error("The option pdfjsnewwindow just works in a browser-environment.");
+          }
 
-              var xPath = this.path;
+        case "dataurlnewwindow":
+          if (Object.prototype.toString.call(globalObject) === "[object Window]") {
+            var htmlForDataURLNewWindow = "<html>" + "<style>html, body { padding: 0; margin: 0; } iframe { width: 100%; height: 100%; border: 0;}  </style>" + "<body>" + '<iframe src="' + this.output("datauristring", options) + '"></iframe>' + "</body></html>";
+            var dataURLNewWindow = globalObject.open();
 
-              for (var i = 0; i < xPath.length; i++) {
-                  var pt = xPath[i];
-                  switch (pt.type) {
-                      case 'mt':
-                          moves.push({ start: pt, deltas: [], abs: [] });
-                          break;
-                      case 'lt':
-                          var delta = [pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
-                          moves[moves.length - 1].deltas.push(delta);
-                          moves[moves.length - 1].abs.push(pt);
-                          break;
-                      case 'bct':
-                          var delta = [pt.x1 - xPath[i - 1].x, pt.y1 - xPath[i - 1].y, pt.x2 - xPath[i - 1].x, pt.y2 - xPath[i - 1].y, pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
-                          moves[moves.length - 1].deltas.push(delta);
-                          break;
-                      case 'qct':
-                          // convert to bezier
-                          var x1 = xPath[i - 1].x + 2.0 / 3.0 * (pt.x1 - xPath[i - 1].x);
-                          var y1 = xPath[i - 1].y + 2.0 / 3.0 * (pt.y1 - xPath[i - 1].y);
-                          var x2 = pt.x + 2.0 / 3.0 * (pt.x1 - pt.x);
-                          var y2 = pt.y + 2.0 / 3.0 * (pt.y1 - pt.y);
-                          var x3 = pt.x;
-                          var y3 = pt.y;
-                          var delta = [x1 - xPath[i - 1].x, y1 - xPath[i - 1].y, x2 - xPath[i - 1].x, y2 - xPath[i - 1].y, x3 - xPath[i - 1].x, y3 - xPath[i - 1].y];
-                          moves[moves.length - 1].deltas.push(delta);
-                          break;
-                      case 'arc':
-                          //TODO this was hack to avoid out-of-bounds issue when drawing circle
-                          // No move-to before drawing the arc
-                          if (moves.length === 0) {
-                              moves.push({ deltas: [], abs: [] });
-                          }
-                          moves[moves.length - 1].arc = true;
-                          if (Array.isArray(moves[moves.length - 1].abs)) {
-                              moves[moves.length - 1].abs.push(pt);
-                          }
-                          break;
-                      case 'close':
-                          moves.push({ close: true });
-                          break;
-                  }
-              }
+            if (dataURLNewWindow !== null) {
+              dataURLNewWindow.document.write(htmlForDataURLNewWindow);
+              dataURLNewWindow.document.title = options.filename;
+            }
 
-              for (var i = 0; i < moves.length; i++) {
-                  var style;
-                  if (i == moves.length - 1) {
-                      style = 'f';
-                      if (fillRule === 'evenodd') {
-                          style += '*';
-                      }
-                  } else {
-                      style = null;
-                  }
+            if (dataURLNewWindow || typeof safari === "undefined") return dataURLNewWindow;
+          } else {
+            throw new Error("The option dataurlnewwindow just works in a browser-environment.");
+          }
 
-                  if (moves[i].close) {
-                      this.pdf.internal.out('h');
-                      if (style) {
-                          // only fill at final path move
-                          this.pdf.internal.out(style);
-                      }
-                  } else if (moves[i].arc) {
-                      if (moves[i].start) {
-                          this.internal.move2(this, moves[i].start.x, moves[i].start.y);
-                      }
-                      var arcs = moves[i].abs;
-                      for (var ii = 0; ii < arcs.length; ii++) {
-                          var arc = arcs[ii];
-                          //TODO lines deltas were getting in here
-                          if (typeof arc.startAngle !== 'undefined') {
-                              var start = arc.startAngle * 360 / (2 * Math.PI);
-                              var end = arc.endAngle * 360 / (2 * Math.PI);
-                              var x = arc.x;
-                              var y = arc.y;
-                              if (ii === 0) {
-                                  this.internal.move2(this, x, y);
-                              }
-                              this.internal.arc2(this, x, y, arc.radius, start, end, arc.anticlockwise, null, isClip);
-                              if (ii === arcs.length - 1) {
-                                  // The original arc move did not occur because of the algorithm
-                                  if (moves[i].start) {
-                                      var x = moves[i].start.x;
-                                      var y = moves[i].start.y;
-                                      this.internal.line2(c2d, x, y);
-                                  }
-                              }
-                          } else {
-                              this.internal.line2(c2d, arc.x, arc.y);
-                          }
-                      }
-                  } else {
-                      var x = moves[i].start.x;
-                      var y = moves[i].start.y;
-                      if (!isClip) {
-                          this.pdf.lines(moves[i].deltas, x, y, null, style);
-                      } else {
-                          this.pdf.lines(moves[i].deltas, x, y, null, null);
-                          this.pdf.clip_fixed();
-                      }
-                  }
-              }
+          break;
 
-              window.outIntercept = outInterceptOld;
+        case "datauri":
+        case "dataurl":
+          return globalObject.document.location.href = this.output("datauristring", options);
 
-              // if (this.ctx._clip_path.length > 0) {
-              //     lines.push('Q');
-              // }
-          },
+        default:
+          return null;
+      }
+    });
+    /**
+     * Used to see if a supplied hotfix was requested when the pdf instance was created.
+     * @param {string} hotfixName - The name of the hotfix to check.
+     * @returns {boolean}
+     */
 
-          pushMask: function pushMask() {
-              var v2Support = typeof this.pdf.internal.newObject2 === 'function';
+    var hasHotfix = function hasHotfix(hotfixName) {
+      return Array.isArray(hotfixes) === true && hotfixes.indexOf(hotfixName) > -1;
+    };
 
-              if (!v2Support) {
-                  console.log('jsPDF v2 not enabled');
-                  return;
-              }
+    switch (unit) {
+      case "pt":
+        scaleFactor = 1;
+        break;
 
-              // define a mask stream
-              var obj = this.pdf.internal.newStreamObject();
+      case "mm":
+        scaleFactor = 72 / 25.4;
+        break;
 
-              // define a mask state
-              var obj2 = this.pdf.internal.newObject2();
-              obj2.push('<</Type /ExtGState');
-              obj2.push('/SMask <</S /Alpha /G ' + obj.objId + ' 0 R>>'); // /S /Luminosity will need to define color space
-              obj2.push('>>');
+      case "cm":
+        scaleFactor = 72 / 2.54;
+        break;
 
-              // add mask to page resources
-              var gsName = 'MASK' + obj2.objId;
-              this.pdf.internal.addGraphicsState(gsName, obj2.objId);
+      case "in":
+        scaleFactor = 72;
+        break;
 
-              var instruction = '/' + gsName + ' gs';
-              this.pdf.internal.out(instruction);
-          },
+      case "px":
+        if (hasHotfix("px_scaling") == true) {
+          scaleFactor = 72 / 96;
+        } else {
+          scaleFactor = 96 / 72;
+        }
 
-          clip: function clip() {
-              //TODO do we reset the path, or just copy it?
-              if (this.ctx._clip_path.length > 0) {
-                  for (var i = 0; i < this.path.length; i++) {
-                      this.ctx._clip_path.push(this.path[i]);
-                  }
-              } else {
-                  this.ctx._clip_path = this.path;
-              }
-              this.path = [];
-          },
+        break;
 
-          measureText: function measureText(text) {
-              var pdf = this.pdf;
-              return {
-                  getWidth: function getWidth() {
-                      var fontSize = pdf.internal.getFontSize();
-                      var txtWidth = pdf.getStringUnitWidth(text) * fontSize / pdf.internal.scaleFactor;
-                      // Convert points to pixels
-                      txtWidth *= 1.3333;
-                      return txtWidth;
-                  },
-
-                  get width() {
-                      return this.getWidth(text);
-                  }
-              };
-          },
-          _getBaseline: function _getBaseline(y) {
-              var height = parseInt(this.pdf.internal.getFontSize());
-              // TODO Get descent from font descriptor
-              var descent = height * 0.25;
-              switch (this.ctx.textBaseline) {
-                  case 'bottom':
-                      return y - descent;
-                  case 'top':
-                      return y + height;
-                  case 'hanging':
-                      return y + height - descent;
-                  case 'middle':
-                      return y + height / 2 - descent;
-                  case 'ideographic':
-                      // TODO not implemented
-                      return y;
-                  case 'alphabetic':
-                  default:
-                      return y;
-              }
-          }
-      };
+      case "pc":
+        scaleFactor = 12;
+        break;
 
-      var c2d = jsPDFAPI.context2d;
+      case "em":
+        scaleFactor = 12;
+        break;
 
-      // accessor methods
-      Object.defineProperty(c2d, 'fillStyle', {
-          set: function set(value) {
-              this.setFillStyle(value);
-          },
-          get: function get() {
-              return this.ctx.fillStyle;
-          }
-      });
-      Object.defineProperty(c2d, 'strokeStyle', {
-          set: function set(value) {
-              this.setStrokeStyle(value);
-          },
-          get: function get() {
-              return this.ctx.strokeStyle;
-          }
-      });
-      Object.defineProperty(c2d, 'lineWidth', {
-          set: function set(value) {
-              this.setLineWidth(value);
-          },
-          get: function get() {
-              return this.ctx.lineWidth;
-          }
-      });
-      Object.defineProperty(c2d, 'lineCap', {
-          set: function set(val) {
-              this.setLineCap(val);
-          },
-          get: function get() {
-              return this.ctx.lineCap;
-          }
-      });
-      Object.defineProperty(c2d, 'lineJoin', {
-          set: function set(val) {
-              this.setLineJoin(val);
-          },
-          get: function get() {
-              return this.ctx.lineJoin;
-          }
-      });
-      Object.defineProperty(c2d, 'miterLimit', {
-          set: function set(val) {
-              this.ctx.miterLimit = val;
-          },
-          get: function get() {
-              return this.ctx.miterLimit;
-          }
-      });
-      Object.defineProperty(c2d, 'textBaseline', {
-          set: function set(value) {
-              this.setTextBaseline(value);
-          },
-          get: function get() {
-              return this.getTextBaseline();
-          }
-      });
-      Object.defineProperty(c2d, 'textAlign', {
-          set: function set(value) {
-              this.setTextAlign(value);
-          },
-          get: function get() {
-              return this.getTextAlign();
-          }
-      });
-      Object.defineProperty(c2d, 'font', {
-          set: function set(value) {
-              this.setFont(value);
-          },
-          get: function get() {
-              return this.ctx.font;
-          }
-      });
-      Object.defineProperty(c2d, 'globalCompositeOperation', {
-          set: function set(value) {
-              this.ctx.globalCompositeOperation = value;
-          },
-          get: function get() {
-              return this.ctx.globalCompositeOperation;
-          }
-      });
-      Object.defineProperty(c2d, 'globalAlpha', {
-          set: function set(value) {
-              this.ctx.globalAlpha = value;
-          },
-          get: function get() {
-              return this.ctx.globalAlpha;
-          }
-      });
-      Object.defineProperty(c2d, 'canvas', {
-          get: function get() {
-              return { parentNode: false, style: false };
-          }
-      });
-      // Not HTML API
-      Object.defineProperty(c2d, 'ignoreClearRect', {
-          set: function set(value) {
-              this.ctx.ignoreClearRect = value;
-          },
-          get: function get() {
-              return this.ctx.ignoreClearRect;
-          }
-      });
-      // End Not HTML API
+      case "ex":
+        scaleFactor = 6;
+        break;
 
-      c2d.internal = {};
+      default:
+        if (typeof unit === "number") {
+          scaleFactor = unit;
+        } else {
+          throw new Error("Invalid unit: " + unit);
+        }
 
-      c2d.internal.rxRgb = /rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/;
-      c2d.internal.rxRgba = /rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/;
-      c2d.internal.rxTransparent = /transparent|rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*0+\s*\)/;
+    }
 
-      // http://hansmuller-flex.blogspot.com/2011/10/more-about-approximating-circular-arcs.html
-      c2d.internal.arc = function (c2d, xc, yc, r, a1, a2, anticlockwise, style) {
+    var encryption = null;
+    setCreationDate();
+    setFileId();
 
-          var k = this.pdf.internal.scaleFactor;
-          var pageHeight = this.pdf.internal.pageSize.getHeight();
-          var f2 = this.pdf.internal.f2;
+    var getEncryptor = function getEncryptor(objectId) {
+      if (encryptionOptions !== null) {
+        return encryption.encryptor(objectId, 0);
+      }
 
-          var a1r = a1 * (Math.PI / 180);
-          var a2r = a2 * (Math.PI / 180);
-          var curves = this.createArc(r, a1r, a2r, anticlockwise);
+      return function (data) {
+        return data;
+      };
+    }; //---------------------------------------
+    // Public API
 
-          for (var i = 0; i < curves.length; i++) {
-              var curve = curves[i];
-              if (i === 0) {
-                  this.pdf.internal.out([f2((curve.x1 + xc) * k), f2((pageHeight - (curve.y1 + yc)) * k), 'm', f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c'].join(' '));
-              } else {
-                  this.pdf.internal.out([f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c'].join(' '));
-              }
 
-              //c2d._lastPoint = {x: curve.x1 + xc, y: curve.y1 + yc};
-              c2d._lastPoint = { x: xc, y: yc };
-              // f2((curve.x1 + xc) * k), f2((pageHeight - (curve.y1 + yc)) * k), 'm', f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c'
-          }
+    var getPageInfo = API.__private__.getPageInfo = API.getPageInfo = function (pageNumberOneBased) {
+      if (isNaN(pageNumberOneBased) || pageNumberOneBased % 1 !== 0) {
+        throw new Error("Invalid argument passed to jsPDF.getPageInfo");
+      }
 
-          if (style !== null) {
-              this.pdf.internal.out(this.pdf.internal.getStyle(style));
-          }
+      var objId = pagesContext[pageNumberOneBased].objId;
+      return {
+        objId: objId,
+        pageNumber: pageNumberOneBased,
+        pageContext: pagesContext[pageNumberOneBased]
       };
+    };
 
-      /**
-       *
-       * @param x Edge point X
-       * @param y Edge point Y
-       * @param r Radius
-       * @param a1 start angle
-       * @param a2 end angle
-       * @param anticlockwise
-       * @param style
-       * @param isClip
-       */
-      c2d.internal.arc2 = function (c2d, x, y, r, a1, a2, anticlockwise, style, isClip) {
-          // we need to convert from cartesian to polar here methinks.
-          var centerX = x; // + r;
-          var centerY = y;
+    var getPageInfoByObjId = API.__private__.getPageInfoByObjId = function (objId) {
+      if (isNaN(objId) || objId % 1 !== 0) {
+        throw new Error("Invalid argument passed to jsPDF.getPageInfoByObjId");
+      }
 
-          if (!isClip) {
-              this.arc(c2d, centerX, centerY, r, a1, a2, anticlockwise, style);
-          } else {
-              this.arc(c2d, centerX, centerY, r, a1, a2, anticlockwise, null);
-              this.pdf.clip_fixed();
-          }
-      };
+      for (var pageNumber in pagesContext) {
+        if (pagesContext[pageNumber].objId === objId) {
+          break;
+        }
+      }
 
-      c2d.internal.move2 = function (c2d, x, y) {
-          var k = this.pdf.internal.scaleFactor;
-          var pageHeight = this.pdf.internal.pageSize.getHeight();
-          var f2 = this.pdf.internal.f2;
+      return getPageInfo(pageNumber);
+    };
 
-          this.pdf.internal.out([f2(x * k), f2((pageHeight - y) * k), 'm'].join(' '));
-          c2d._lastPoint = { x: x, y: y };
+    var getCurrentPageInfo = API.__private__.getCurrentPageInfo = API.getCurrentPageInfo = function () {
+      return {
+        objId: pagesContext[currentPage].objId,
+        pageNumber: currentPage,
+        pageContext: pagesContext[currentPage]
       };
+    };
+    /**
+     * Adds (and transfers the focus to) new page to the PDF document.
+     * @param format {String/Array} The format of the new page. Can be: <ul><li>a0 - a10</li><li>b0 - b10</li><li>c0 - c10</li><li>dl</li><li>letter</li><li>government-letter</li><li>legal</li><li>junior-legal</li><li>ledger</li><li>tabloid</li><li>credit-card</li></ul><br />
+     * Default is "a4". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array, e.g. [595.28, 841.89]
+     * @param orientation {string} Orientation of the new page. Possible values are "portrait" or "landscape" (or shortcuts "p" (Default), "l").
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     *
+     * @memberof jsPDF#
+     * @name addPage
+     */
 
-      c2d.internal.line2 = function (c2d, dx, dy) {
-          var k = this.pdf.internal.scaleFactor;
-          var pageHeight = this.pdf.internal.pageSize.getHeight();
-          var f2 = this.pdf.internal.f2;
-
-          //var pt = {x: c2d._lastPoint.x + dx, y: c2d._lastPoint.y + dy};
-          var pt = { x: dx, y: dy };
 
-          this.pdf.internal.out([f2(pt.x * k), f2((pageHeight - pt.y) * k), 'l'].join(' '));
-          //this.pdf.internal.out('f');
-          c2d._lastPoint = pt;
-      };
+    API.addPage = function () {
+      _addPage.apply(this, arguments);
 
-      /**
-       * Return a array of objects that represent bezier curves which approximate the circular arc centered at the origin, from startAngle to endAngle (radians) with the specified radius.
-       *
-       * Each bezier curve is an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points.
-       */
+      return this;
+    };
+    /**
+     * Adds (and transfers the focus to) new page to the PDF document.
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     *
+     * @memberof jsPDF#
+     * @name setPage
+     * @param {number} page Switch the active page to the page number specified (indexed starting at 1).
+     * @example
+     * doc = jsPDF()
+     * doc.addPage()
+     * doc.addPage()
+     * doc.text('I am on page 3', 10, 10)
+     * doc.setPage(1)
+     * doc.text('I am on page 1', 10, 10)
+     */
 
-      c2d.internal.createArc = function (radius, startAngle, endAngle, anticlockwise) {
-          var EPSILON = 0.00001; // Roughly 1/1000th of a degree, see below
-          var twoPI = Math.PI * 2;
-          var piOverTwo = Math.PI / 2.0;
 
-          // normalize startAngle, endAngle to [0, 2PI]
-          var startAngleN = startAngle;
-          if (startAngleN < twoPI || startAngleN > twoPI) {
-              startAngleN = startAngleN % twoPI;
-          }
-          if (startAngleN < 0) {
-              startAngleN = twoPI + startAngleN;
-          }
+    API.setPage = function () {
+      _setPage.apply(this, arguments);
 
-          while (startAngle > endAngle) {
-              startAngle = startAngle - twoPI;
+      setOutputDestination.call(this, pages[currentPage]);
+      return this;
+    };
+    /**
+     * @name insertPage
+     * @memberof jsPDF#
+     *
+     * @function
+     * @instance
+     * @param {Object} beforePage
+     * @returns {jsPDF}
+     */
+
+
+    API.insertPage = function (beforePage) {
+      this.addPage();
+      this.movePage(currentPage, beforePage);
+      return this;
+    };
+    /**
+     * @name movePage
+     * @memberof jsPDF#
+     * @function
+     * @instance
+     * @param {number} targetPage
+     * @param {number} beforePage
+     * @returns {jsPDF}
+     */
+
+
+    API.movePage = function (targetPage, beforePage) {
+      var tmpPages, tmpPagesContext;
+
+      if (targetPage > beforePage) {
+        tmpPages = pages[targetPage];
+        tmpPagesContext = pagesContext[targetPage];
+
+        for (var i = targetPage; i > beforePage; i--) {
+          pages[i] = pages[i - 1];
+          pagesContext[i] = pagesContext[i - 1];
+        }
+
+        pages[beforePage] = tmpPages;
+        pagesContext[beforePage] = tmpPagesContext;
+        this.setPage(beforePage);
+      } else if (targetPage < beforePage) {
+        tmpPages = pages[targetPage];
+        tmpPagesContext = pagesContext[targetPage];
+
+        for (var j = targetPage; j < beforePage; j++) {
+          pages[j] = pages[j + 1];
+          pagesContext[j] = pagesContext[j + 1];
+        }
+
+        pages[beforePage] = tmpPages;
+        pagesContext[beforePage] = tmpPagesContext;
+        this.setPage(beforePage);
+      }
+
+      return this;
+    };
+    /**
+     * Deletes a page from the PDF.
+     * @name deletePage
+     * @memberof jsPDF#
+     * @function
+     * @param {number} targetPage
+     * @instance
+     * @returns {jsPDF}
+     */
+
+
+    API.deletePage = function () {
+      _deletePage.apply(this, arguments);
+
+      return this;
+    };
+    /**
+     * Adds text to page. Supports adding multiline text when 'text' argument is an Array of Strings.
+     *
+     * @function
+     * @instance
+     * @param {String|Array} text String or array of strings to be added to the page. Each line is shifted one line down per font, spacing settings declared before this call.
+     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page.
+     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page.
+     * @param {Object} [options] - Collection of settings signaling how the text must be encoded.
+     * @param {string} [options.align=left] - The alignment of the text, possible values: left, center, right, justify.
+     * @param {string} [options.baseline=alphabetic] - Sets text baseline used when drawing the text, possible values: alphabetic, ideographic, bottom, top, middle, hanging
+     * @param {number|Matrix} [options.angle=0] - Rotate the text clockwise or counterclockwise. Expects the angle in degree.
+     * @param {number} [options.rotationDirection=1] - Direction of the rotation. 0 = clockwise, 1 = counterclockwise.
+     * @param {number} [options.charSpace=0] - The space between each letter.
+     * @param {number} [options.horizontalScale=1] - Horizontal scale of the text as a factor of the regular size.
+     * @param {number} [options.lineHeightFactor=1.15] - The lineheight of each line.
+     * @param {Object} [options.flags] - Flags for to8bitStream.
+     * @param {boolean} [options.flags.noBOM=true] - Don't add BOM to Unicode-text.
+     * @param {boolean} [options.flags.autoencode=true] - Autoencode the Text.
+     * @param {number} [options.maxWidth=0] - Split the text by given width, 0 = no split.
+     * @param {string} [options.renderingMode=fill] - Set how the text should be rendered, possible values: fill, stroke, fillThenStroke, invisible, fillAndAddForClipping, strokeAndAddPathForClipping, fillThenStrokeAndAddToPathForClipping, addToPathForClipping.
+     * @param {boolean} [options.isInputVisual] - Option for the BidiEngine
+     * @param {boolean} [options.isOutputVisual] - Option for the BidiEngine
+     * @param {boolean} [options.isInputRtl] - Option for the BidiEngine
+     * @param {boolean} [options.isOutputRtl] - Option for the BidiEngine
+     * @param {boolean} [options.isSymmetricSwapping] - Option for the BidiEngine
+     * @param {number|Matrix} transform If transform is a number the text will be rotated by this value around the anchor set by x and y.
+     *
+     * If it is a Matrix, this matrix gets directly applied to the text, which allows shearing
+     * effects etc.; the x and y offsets are then applied AFTER the coordinate system has been established by this
+     * matrix. This means passing a rotation matrix that is equivalent to some rotation angle will in general yield a
+     * DIFFERENT result. A matrix is only allowed in "advanced" API mode.
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name text
+     */
+
+
+    API.__private__.text = API.text = function (text, x, y, options, transform) {
+      /*
+       * Inserts something like this into PDF
+       *   BT
+       *    /F1 16 Tf  % Font name + size
+       *    16 TL % How many units down for next line in multiline text
+       *    0 g % color
+       *    28.35 813.54 Td % position
+       *    (line one) Tj
+       *    T* (line two) Tj
+       *    T* (line three) Tj
+       *   ET
+       */
+      options = options || {};
+      var scope = options.scope || this;
+      var payload, da, angle, align, charSpace, maxWidth, flags, horizontalScale; // Pre-August-2012 the order of arguments was function(x, y, text, flags)
+      // in effort to make all calls have similar signature like
+      //   function(data, coordinates... , miscellaneous)
+      // this method had its args flipped.
+      // code below allows backward compatibility with old arg order.
+
+      if (typeof text === "number" && typeof x === "number" && (typeof y === "string" || Array.isArray(y))) {
+        var tmp = y;
+        y = x;
+        x = text;
+        text = tmp;
+      }
+
+      var transformationMatrix;
+
+      if (arguments[3] instanceof Matrix === false) {
+        flags = arguments[3];
+        angle = arguments[4];
+        align = arguments[5];
+
+        if (_typeof(flags) !== "object" || flags === null) {
+          if (typeof angle === "string") {
+            align = angle;
+            angle = null;
           }
-          var totalAngle = Math.abs(endAngle - startAngle);
-          if (totalAngle < twoPI) {
-              if (anticlockwise) {
-                  totalAngle = twoPI - totalAngle;
-              }
+
+          if (typeof flags === "string") {
+            align = flags;
+            flags = null;
           }
 
-          // Compute the sequence of arc curves, up to PI/2 at a time.
-          var curves = [];
-          var sgn = anticlockwise ? -1 : +1;
-
-          var a1 = startAngleN;
-          for (; totalAngle > EPSILON;) {
-              var remain = sgn * Math.min(totalAngle, piOverTwo);
-              var a2 = a1 + remain;
-              curves.push(this.createSmallArc(radius, a1, a2));
-              totalAngle -= Math.abs(a2 - a1);
-              a1 = a2;
+          if (typeof flags === "number") {
+            angle = flags;
+            flags = null;
           }
 
-          return curves;
-      };
+          options = {
+            flags: flags,
+            angle: angle,
+            align: align
+          };
+        }
+      } else {
+        advancedApiModeTrap("The transform parameter of text() with a Matrix value");
+        transformationMatrix = transform;
+      }
 
-      c2d.internal.getCurrentPage = function () {
-          return this.pdf.internal.pages[this.pdf.internal.getCurrentPageInfo().pageNumber];
-      };
+      if (isNaN(x) || isNaN(y) || typeof text === "undefined" || text === null) {
+        throw new Error("Invalid arguments passed to jsPDF.text");
+      }
 
-      /**
-       * Cubic bezier approximation of a circular arc centered at the origin, from (radians) a1 to a2, where a2-a1 < pi/2. The arc's radius is r.
-       *
-       * Returns an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points.
-       *
-       * This algorithm is based on the approach described in: A. Riškus, "Approximation of a Cubic Bezier Curve by Circular Arcs and Vice Versa," Information Technology and Control, 35(4), 2006 pp. 371-378.
-       */
+      if (text.length === 0) {
+        return scope;
+      }
 
-      c2d.internal.createSmallArc = function (r, a1, a2) {
-          // Compute all four points for an arc that subtends the same total angle
-          // but is centered on the X-axis
+      var xtra = "";
+      var isHex = false;
+      var lineHeight = typeof options.lineHeightFactor === "number" ? options.lineHeightFactor : lineHeightFactor;
+      var scaleFactor = scope.internal.scaleFactor;
 
-          var a = (a2 - a1) / 2.0;
+      function ESC(s) {
+        s = s.split("\t").join(Array(options.TabLen || 9).join(" "));
+        return pdfEscape(s, flags);
+      }
 
-          var x4 = r * Math.cos(a);
-          var y4 = r * Math.sin(a);
-          var x1 = x4;
-          var y1 = -y4;
+      function transformTextToSpecialArray(text) {
+        //we don't want to destroy original text array, so cloning it
+        var sa = text.concat();
+        var da = [];
+        var len = sa.length;
+        var curDa; //we do array.join('text that must not be PDFescaped")
+        //thus, pdfEscape each component separately
 
-          var q1 = x1 * x1 + y1 * y1;
-          var q2 = q1 + x1 * x4 + y1 * y4;
-          var k2 = 4 / 3 * (Math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4);
+        while (len--) {
+          curDa = sa.shift();
 
-          var x2 = x1 - k2 * y1;
-          var y2 = y1 + k2 * x1;
-          var x3 = x2;
-          var y3 = -y2;
+          if (typeof curDa === "string") {
+            da.push(curDa);
+          } else {
+            if (Array.isArray(text) && (curDa.length === 1 || curDa[1] === undefined && curDa[2] === undefined)) {
+              da.push(curDa[0]);
+            } else {
+              da.push([curDa[0], curDa[1], curDa[2]]);
+            }
+          }
+        }
 
-          // Find the arc points' actual locations by computing x1,y1 and x4,y4
-          // and rotating the control points by a + a1
+        return da;
+      }
 
-          var ar = a + a1;
-          var cos_ar = Math.cos(ar);
-          var sin_ar = Math.sin(ar);
+      function processTextByFunction(text, processingFunction) {
+        var result;
 
-          return {
-              x1: r * Math.cos(a1),
-              y1: r * Math.sin(a1),
-              x2: x2 * cos_ar - y2 * sin_ar,
-              y2: x2 * sin_ar + y2 * cos_ar,
-              x3: x3 * cos_ar - y3 * sin_ar,
-              y3: x3 * sin_ar + y3 * cos_ar,
-              x4: r * Math.cos(a2),
-              y4: r * Math.sin(a2)
-          };
-      };
+        if (typeof text === "string") {
+          result = processingFunction(text)[0];
+        } else if (Array.isArray(text)) {
+          //we don't want to destroy original text array, so cloning it
+          var sa = text.concat();
+          var da = [];
+          var len = sa.length;
+          var curDa;
+          var tmpResult; //we do array.join('text that must not be PDFescaped")
+          //thus, pdfEscape each component separately
 
-      function context() {
-          this._isStrokeTransparent = false;
-          this._strokeOpacity = 1;
-          this.strokeStyle = '#000000';
-          this.fillStyle = '#000000';
-          this._isFillTransparent = false;
-          this._fillOpacity = 1;
-          this.font = "12pt times";
-          this.textBaseline = 'alphabetic'; // top,bottom,middle,ideographic,alphabetic,hanging
-          this.textAlign = 'start';
-          this.lineWidth = 1;
-          this.lineJoin = 'miter'; // round, bevel, miter
-          this.lineCap = 'butt'; // butt, round, square
-          this._transform = [1, 0, 0, 1, 0, 0]; // sx, shy, shx, sy, tx, ty
-          this.globalCompositeOperation = 'normal';
-          this.globalAlpha = 1.0;
-          this._clip_path = [];
-
-          // TODO miter limit //default 10
-
-          // Not HTML API
-          this.ignoreClearRect = false;
-
-          this.copy = function (ctx) {
-              this._isStrokeTransparent = ctx._isStrokeTransparent;
-              this._strokeOpacity = ctx._strokeOpacity;
-              this.strokeStyle = ctx.strokeStyle;
-              this._isFillTransparent = ctx._isFillTransparent;
-              this._fillOpacity = ctx._fillOpacity;
-              this.fillStyle = ctx.fillStyle;
-              this.font = ctx.font;
-              this.lineWidth = ctx.lineWidth;
-              this.lineJoin = ctx.lineJoin;
-              this.lineCap = ctx.lineCap;
-              this.textBaseline = ctx.textBaseline;
-              this.textAlign = ctx.textAlign;
-              this._fontSize = ctx._fontSize;
-              this._transform = ctx._transform.slice(0);
-              this.globalCompositeOperation = ctx.globalCompositeOperation;
-              this.globalAlpha = ctx.globalAlpha;
-              this._clip_path = ctx._clip_path.slice(0); //TODO deep copy?
-
-              // Not HTML API
-              this.ignoreClearRect = ctx.ignoreClearRect;
-          };
-      }
+          while (len--) {
+            curDa = sa.shift();
 
-      return this;
-  })(jsPDF.API, typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global || Function('return typeof this === "object" && this.content')() || Function('return this')());
-
-  /** @preserve
-   * jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser
-   * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
-   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
-   *               2014 Diego Casorran, https://github.com/diegocr
-   *               2014 Daniel Husar, https://github.com/danielhusar
-   *               2014 Wolfgang Gassler, https://github.com/woolfg
-   *               2014 Steven Spungin, https://github.com/flamenco
-   *
-   * 
-   * ====================================================================
-   */
+            if (typeof curDa === "string") {
+              da.push(processingFunction(curDa)[0]);
+            } else if (Array.isArray(curDa) && typeof curDa[0] === "string") {
+              tmpResult = processingFunction(curDa[0], curDa[1], curDa[2]);
+              da.push([tmpResult[0], tmpResult[1], tmpResult[2]]);
+            }
+          }
 
-  (function (jsPDFAPI) {
-  	var clone, _DrillForContent, FontNameDB, FontStyleMap, TextAlignMap, FontWeightMap, FloatMap, ClearMap, GetCSS, PurgeWhiteSpace, Renderer, ResolveFont, ResolveUnitedNumber, UnitedNumberMap, elementHandledElsewhere, images, loadImgs, checkForFooter, process, tableToJson;
-  	clone = function () {
-  		return function (obj) {
-  			Clone.prototype = obj;
-  			return new Clone();
-  		};
-  		function Clone() {}
-  	}();
-  	PurgeWhiteSpace = function PurgeWhiteSpace(array) {
-  		var fragment, i, l, lTrimmed, r, rTrimmed, trailingSpace;
-  		i = 0;
-  		l = array.length;
-  		fragment = void 0;
-  		lTrimmed = false;
-  		rTrimmed = false;
-  		while (!lTrimmed && i !== l) {
-  			fragment = array[i] = array[i].trimLeft();
-  			if (fragment) {
-  				lTrimmed = true;
-  			}
-  			i++;
-  		}
-  		i = l - 1;
-  		while (l && !rTrimmed && i !== -1) {
-  			fragment = array[i] = array[i].trimRight();
-  			if (fragment) {
-  				rTrimmed = true;
-  			}
-  			i--;
-  		}
-  		r = /\s+$/g;
-  		trailingSpace = true;
-  		i = 0;
-  		while (i !== l) {
-  			// Leave the line breaks intact
-  			if (array[i] != "\u2028") {
-  				fragment = array[i].replace(/\s+/g, " ");
-  				if (trailingSpace) {
-  					fragment = fragment.trimLeft();
-  				}
-  				if (fragment) {
-  					trailingSpace = r.test(fragment);
-  				}
-  				array[i] = fragment;
-  			}
-  			i++;
-  		}
-  		return array;
-  	};
-  	Renderer = function Renderer(pdf, x, y, settings) {
-  		this.pdf = pdf;
-  		this.x = x;
-  		this.y = y;
-  		this.settings = settings;
-  		//list of functions which are called after each element-rendering process
-  		this.watchFunctions = [];
-  		this.init();
-  		return this;
-  	};
-  	ResolveFont = function ResolveFont(css_font_family_string) {
-  		var name, part, parts;
-  		name = void 0;
-  		parts = css_font_family_string.split(",");
-  		part = parts.shift();
-  		while (!name && part) {
-  			name = FontNameDB[part.trim().toLowerCase()];
-  			part = parts.shift();
-  		}
-  		return name;
-  	};
-  	ResolveUnitedNumber = function ResolveUnitedNumber(css_line_height_string) {
-
-  		//IE8 issues
-  		css_line_height_string = css_line_height_string === "auto" ? "0px" : css_line_height_string;
-  		if (css_line_height_string.indexOf("em") > -1 && !isNaN(Number(css_line_height_string.replace("em", "")))) {
-  			css_line_height_string = Number(css_line_height_string.replace("em", "")) * 18.719 + "px";
-  		}
-  		if (css_line_height_string.indexOf("pt") > -1 && !isNaN(Number(css_line_height_string.replace("pt", "")))) {
-  			css_line_height_string = Number(css_line_height_string.replace("pt", "")) * 1.333 + "px";
-  		}
-
-  		var normal, undef, value;
-  		undef = void 0;
-  		normal = 16.00;
-  		value = UnitedNumberMap[css_line_height_string];
-  		if (value) {
-  			return value;
-  		}
-  		value = {
-  			"xx-small": 9,
-  			"x-small": 11,
-  			small: 13,
-  			medium: 16,
-  			large: 19,
-  			"x-large": 23,
-  			"xx-large": 28,
-  			auto: 0
-  		}[css_line_height_string];
-
-  		if (value !== undef) {
-  			return UnitedNumberMap[css_line_height_string] = value / normal;
-  		}
-  		if (value = parseFloat(css_line_height_string)) {
-  			return UnitedNumberMap[css_line_height_string] = value / normal;
-  		}
-  		value = css_line_height_string.match(/([\d\.]+)(px)/);
-  		if (Array.isArray(value) && value.length === 3) {
-  			return UnitedNumberMap[css_line_height_string] = parseFloat(value[1]) / normal;
-  		}
-  		return UnitedNumberMap[css_line_height_string] = 1;
-  	};
-  	GetCSS = function GetCSS(element) {
-  		var css, tmp, computedCSSElement;
-  		computedCSSElement = function (el) {
-  			var compCSS;
-  			compCSS = function (el) {
-  				if (document.defaultView && document.defaultView.getComputedStyle) {
-  					return document.defaultView.getComputedStyle(el, null);
-  				} else if (el.currentStyle) {
-  					return el.currentStyle;
-  				} else {
-  					return el.style;
-  				}
-  			}(el);
-  			return function (prop) {
-  				prop = prop.replace(/-\D/g, function (match) {
-  					return match.charAt(1).toUpperCase();
-  				});
-  				return compCSS[prop];
-  			};
-  		}(element);
-  		css = {};
-  		tmp = void 0;
-  		css["font-family"] = ResolveFont(computedCSSElement("font-family")) || "times";
-  		css["font-style"] = FontStyleMap[computedCSSElement("font-style")] || "normal";
-  		css["text-align"] = TextAlignMap[computedCSSElement("text-align")] || "left";
-  		tmp = FontWeightMap[computedCSSElement("font-weight")] || "normal";
-  		if (tmp === "bold") {
-  			if (css["font-style"] === "normal") {
-  				css["font-style"] = tmp;
-  			} else {
-  				css["font-style"] = tmp + css["font-style"];
-  			}
-  		}
-  		css["font-size"] = ResolveUnitedNumber(computedCSSElement("font-size")) || 1;
-  		css["line-height"] = ResolveUnitedNumber(computedCSSElement("line-height")) || 1;
-  		css["display"] = computedCSSElement("display") === "inline" ? "inline" : "block";
-
-  		tmp = css["display"] === "block";
-  		css["margin-top"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-top")) || 0;
-  		css["margin-bottom"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-bottom")) || 0;
-  		css["padding-top"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-top")) || 0;
-  		css["padding-bottom"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-bottom")) || 0;
-  		css["margin-left"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-left")) || 0;
-  		css["margin-right"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-right")) || 0;
-  		css["padding-left"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-left")) || 0;
-  		css["padding-right"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-right")) || 0;
-
-  		css["page-break-before"] = computedCSSElement("page-break-before") || "auto";
-
-  		//float and clearing of floats
-  		css["float"] = FloatMap[computedCSSElement("cssFloat")] || "none";
-  		css["clear"] = ClearMap[computedCSSElement("clear")] || "none";
-
-  		css["color"] = computedCSSElement("color");
-
-  		return css;
-  	};
-  	elementHandledElsewhere = function elementHandledElsewhere(element, renderer, elementHandlers) {
-  		var handlers, i, isHandledElsewhere, l, classNames;
-  		isHandledElsewhere = false;
-  		i = void 0;
-  		l = void 0;
-  		handlers = elementHandlers["#" + element.id];
-  		if (handlers) {
-  			if (typeof handlers === "function") {
-  				isHandledElsewhere = handlers(element, renderer);
-  			} else {
-  				i = 0;
-  				l = handlers.length;
-  				while (!isHandledElsewhere && i !== l) {
-  					isHandledElsewhere = handlers[i](element, renderer);
-  					i++;
-  				}
-  			}
-  		}
-  		handlers = elementHandlers[element.nodeName];
-  		if (!isHandledElsewhere && handlers) {
-  			if (typeof handlers === "function") {
-  				isHandledElsewhere = handlers(element, renderer);
-  			} else {
-  				i = 0;
-  				l = handlers.length;
-  				while (!isHandledElsewhere && i !== l) {
-  					isHandledElsewhere = handlers[i](element, renderer);
-  					i++;
-  				}
-  			}
-  		}
-
-  		// Try class names
-  		classNames = typeof element.className === 'string' ? element.className.split(' ') : [];
-  		for (i = 0; i < classNames.length; i++) {
-  			handlers = elementHandlers['.' + classNames[i]];
-  			if (!isHandledElsewhere && handlers) {
-  				if (typeof handlers === "function") {
-  					isHandledElsewhere = handlers(element, renderer);
-  				} else {
-  					i = 0;
-  					l = handlers.length;
-  					while (!isHandledElsewhere && i !== l) {
-  						isHandledElsewhere = handlers[i](element, renderer);
-  						i++;
-  					}
-  				}
-  			}
-  		}
-
-  		return isHandledElsewhere;
-  	};
-  	tableToJson = function tableToJson(table, renderer) {
-  		var data, headers, i, j, rowData, tableRow, table_obj, table_with, cell, l;
-  		data = [];
-  		headers = [];
-  		i = 0;
-  		l = table.rows[0].cells.length;
-  		table_with = table.clientWidth;
-  		while (i < l) {
-  			cell = table.rows[0].cells[i];
-  			headers[i] = {
-  				name: cell.textContent.toLowerCase().replace(/\s+/g, ''),
-  				prompt: cell.textContent.replace(/\r?\n/g, ''),
-  				width: cell.clientWidth / table_with * renderer.pdf.internal.pageSize.getWidth()
-  			};
-  			i++;
-  		}
-  		i = 1;
-  		while (i < table.rows.length) {
-  			tableRow = table.rows[i];
-  			rowData = {};
-  			j = 0;
-  			while (j < tableRow.cells.length) {
-  				rowData[headers[j].name] = tableRow.cells[j].textContent.replace(/\r?\n/g, '');
-  				j++;
-  			}
-  			data.push(rowData);
-  			i++;
-  		}
-  		return table_obj = {
-  			rows: data,
-  			headers: headers
-  		};
-  	};
-  	var SkipNode = {
-  		SCRIPT: 1,
-  		STYLE: 1,
-  		NOSCRIPT: 1,
-  		OBJECT: 1,
-  		EMBED: 1,
-  		SELECT: 1
-  	};
-  	var listCount = 1;
-  	_DrillForContent = function DrillForContent(element, renderer, elementHandlers) {
-  		var cn, cns, fragmentCSS, i, isBlock, l, table2json, cb;
-  		cns = element.childNodes;
-  		cn = void 0;
-  		fragmentCSS = GetCSS(element);
-  		isBlock = fragmentCSS.display === "block";
-  		if (isBlock) {
-  			renderer.setBlockBoundary();
-  			renderer.setBlockStyle(fragmentCSS);
-  		}
-  		i = 0;
-  		l = cns.length;
-  		while (i < l) {
-  			cn = cns[i];
-  			if ((typeof cn === "undefined" ? "undefined" : _typeof(cn)) === "object") {
-
-  				//execute all watcher functions to e.g. reset floating
-  				renderer.executeWatchFunctions(cn);
-
-  				/*** HEADER rendering **/
-  				if (cn.nodeType === 1 && cn.nodeName === 'HEADER') {
-  					var header = cn;
-  					//store old top margin
-  					var oldMarginTop = renderer.pdf.margins_doc.top;
-  					//subscribe for new page event and render header first on every page
-  					renderer.pdf.internal.events.subscribe('addPage', function (pageInfo) {
-  						//set current y position to old margin
-  						renderer.y = oldMarginTop;
-  						//render all child nodes of the header element
-  						_DrillForContent(header, renderer, elementHandlers);
-  						//set margin to old margin + rendered header + 10 space to prevent overlapping
-  						//important for other plugins (e.g. table) to start rendering at correct position after header
-  						renderer.pdf.margins_doc.top = renderer.y + 10;
-  						renderer.y += 10;
-  					}, false);
-  				}
-
-  				if (cn.nodeType === 8 && cn.nodeName === "#comment") {
-  					if (~cn.textContent.indexOf("ADD_PAGE")) {
-  						renderer.pdf.addPage();
-  						renderer.y = renderer.pdf.margins_doc.top;
-  					}
-  				} else if (cn.nodeType === 1 && !SkipNode[cn.nodeName]) {
-  					/*** IMAGE RENDERING ***/
-  					var cached_image;
-  					if (cn.nodeName === "IMG") {
-  						var url = cn.getAttribute("src");
-  						cached_image = images[renderer.pdf.sHashCode(url) || url];
-  					}
-  					if (cached_image) {
-  						if (renderer.pdf.internal.pageSize.getHeight() - renderer.pdf.margins_doc.bottom < renderer.y + cn.height && renderer.y > renderer.pdf.margins_doc.top) {
-  							renderer.pdf.addPage();
-  							renderer.y = renderer.pdf.margins_doc.top;
-  							//check if we have to set back some values due to e.g. header rendering for new page
-  							renderer.executeWatchFunctions(cn);
-  						}
-
-  						var imagesCSS = GetCSS(cn);
-  						var imageX = renderer.x;
-  						var fontToUnitRatio = 12 / renderer.pdf.internal.scaleFactor;
-
-  						//define additional paddings, margins which have to be taken into account for margin calculations
-  						var additionalSpaceLeft = (imagesCSS["margin-left"] + imagesCSS["padding-left"]) * fontToUnitRatio;
-  						var additionalSpaceRight = (imagesCSS["margin-right"] + imagesCSS["padding-right"]) * fontToUnitRatio;
-  						var additionalSpaceTop = (imagesCSS["margin-top"] + imagesCSS["padding-top"]) * fontToUnitRatio;
-  						var additionalSpaceBottom = (imagesCSS["margin-bottom"] + imagesCSS["padding-bottom"]) * fontToUnitRatio;
-
-  						//if float is set to right, move the image to the right border
-  						//add space if margin is set
-  						if (imagesCSS['float'] !== undefined && imagesCSS['float'] === 'right') {
-  							imageX += renderer.settings.width - cn.width - additionalSpaceRight;
-  						} else {
-  							imageX += additionalSpaceLeft;
-  						}
-
-  						renderer.pdf.addImage(cached_image, imageX, renderer.y + additionalSpaceTop, cn.width, cn.height);
-  						cached_image = undefined;
-  						//if the float prop is specified we have to float the text around the image
-  						if (imagesCSS['float'] === 'right' || imagesCSS['float'] === 'left') {
-  							//add functiont to set back coordinates after image rendering
-  							renderer.watchFunctions.push(function (diffX, thresholdY, diffWidth, el) {
-  								//undo drawing box adaptions which were set by floating
-  								if (renderer.y >= thresholdY) {
-  									renderer.x += diffX;
-  									renderer.settings.width += diffWidth;
-  									return true;
-  								} else if (el && el.nodeType === 1 && !SkipNode[el.nodeName] && renderer.x + el.width > renderer.pdf.margins_doc.left + renderer.pdf.margins_doc.width) {
-  									renderer.x += diffX;
-  									renderer.y = thresholdY;
-  									renderer.settings.width += diffWidth;
-  									return true;
-  								} else {
-  									return false;
-  								}
-  							}.bind(this, imagesCSS['float'] === 'left' ? -cn.width - additionalSpaceLeft - additionalSpaceRight : 0, renderer.y + cn.height + additionalSpaceTop + additionalSpaceBottom, cn.width));
-  							//reset floating by clear:both divs
-  							//just set cursorY after the floating element
-  							renderer.watchFunctions.push(function (yPositionAfterFloating, pages, el) {
-  								if (renderer.y < yPositionAfterFloating && pages === renderer.pdf.internal.getNumberOfPages()) {
-  									if (el.nodeType === 1 && GetCSS(el).clear === 'both') {
-  										renderer.y = yPositionAfterFloating;
-  										return true;
-  									} else {
-  										return false;
-  									}
-  								} else {
-  									return true;
-  								}
-  							}.bind(this, renderer.y + cn.height, renderer.pdf.internal.getNumberOfPages()));
-
-  							//if floating is set we decrease the available width by the image width
-  							renderer.settings.width -= cn.width + additionalSpaceLeft + additionalSpaceRight;
-  							//if left just add the image width to the X coordinate
-  							if (imagesCSS['float'] === 'left') {
-  								renderer.x += cn.width + additionalSpaceLeft + additionalSpaceRight;
-  							}
-  						} else {
-  							//if no floating is set, move the rendering cursor after the image height
-  							renderer.y += cn.height + additionalSpaceTop + additionalSpaceBottom;
-  						}
-
-  						/*** TABLE RENDERING ***/
-  					} else if (cn.nodeName === "TABLE") {
-  						table2json = tableToJson(cn, renderer);
-  						renderer.y += 10;
-  						renderer.pdf.table(renderer.x, renderer.y, table2json.rows, table2json.headers, {
-  							autoSize: false,
-  							printHeaders: elementHandlers.printHeaders,
-  							margins: renderer.pdf.margins_doc,
-  							css: GetCSS(cn)
-  						});
-  						renderer.y = renderer.pdf.lastCellPos.y + renderer.pdf.lastCellPos.h + 20;
-  					} else if (cn.nodeName === "OL" || cn.nodeName === "UL") {
-  						listCount = 1;
-  						if (!elementHandledElsewhere(cn, renderer, elementHandlers)) {
-  							_DrillForContent(cn, renderer, elementHandlers);
-  						}
-  						renderer.y += 10;
-  					} else if (cn.nodeName === "LI") {
-  						var temp = renderer.x;
-  						renderer.x += 20 / renderer.pdf.internal.scaleFactor;
-  						renderer.y += 3;
-  						if (!elementHandledElsewhere(cn, renderer, elementHandlers)) {
-  							_DrillForContent(cn, renderer, elementHandlers);
-  						}
-  						renderer.x = temp;
-  					} else if (cn.nodeName === "BR") {
-  						renderer.y += fragmentCSS["font-size"] * renderer.pdf.internal.scaleFactor;
-  						renderer.addText("\u2028", clone(fragmentCSS));
-  					} else {
-  						if (!elementHandledElsewhere(cn, renderer, elementHandlers)) {
-  							_DrillForContent(cn, renderer, elementHandlers);
-  						}
-  					}
-  				} else if (cn.nodeType === 3) {
-  					var value = cn.nodeValue;
-  					if (cn.nodeValue && cn.parentNode.nodeName === "LI") {
-  						if (cn.parentNode.parentNode.nodeName === "OL") {
-  							value = listCount++ + '. ' + value;
-  						} else {
-  							var fontSize = fragmentCSS["font-size"];
-  							var offsetX = (3 - fontSize * 0.75) * renderer.pdf.internal.scaleFactor;
-  							var offsetY = fontSize * 0.75 * renderer.pdf.internal.scaleFactor;
-  							var radius = fontSize * 1.74 / renderer.pdf.internal.scaleFactor;
-  							cb = function cb(x, y) {
-  								this.pdf.circle(x + offsetX, y + offsetY, radius, 'FD');
-  							};
-  						}
-  					}
-  					// Only add the text if the text node is in the body element
-  					// Add compatibility with IE11
-  					if (!!(cn.ownerDocument.body.compareDocumentPosition(cn) & 16)) {
-  						renderer.addText(value, fragmentCSS);
-  					}
-  				} else if (typeof cn === "string") {
-  					renderer.addText(cn, fragmentCSS);
-  				}
-  			}
-  			i++;
-  		}
-  		elementHandlers.outY = renderer.y;
-
-  		if (isBlock) {
-  			return renderer.setBlockBoundary(cb);
-  		}
-  	};
-  	images = {};
-  	loadImgs = function loadImgs(element, renderer, elementHandlers, cb) {
-  		var imgs = element.getElementsByTagName('img'),
-  		    l = imgs.length,
-  		    found_images,
-  		    x = 0;
-  		function done() {
-  			renderer.pdf.internal.events.publish('imagesLoaded');
-  			cb(found_images);
-  		}
-  		function loadImage(url, width, height) {
-  			if (!url) return;
-  			var img = new Image();
-  			found_images = ++x;
-  			img.crossOrigin = '';
-  			img.onerror = img.onload = function () {
-  				if (img.complete) {
-  					//to support data urls in images, set width and height
-  					//as those values are not recognized automatically
-  					if (img.src.indexOf('data:image/') === 0) {
-  						img.width = width || img.width || 0;
-  						img.height = height || img.height || 0;
-  					}
-  					//if valid image add to known images array
-  					if (img.width + img.height) {
-  						var hash = renderer.pdf.sHashCode(url) || url;
-  						images[hash] = images[hash] || img;
-  					}
-  				}
-  				if (! --x) {
-  					done();
-  				}
-  			};
-  			img.src = url;
-  		}
-  		while (l--) {
-  			loadImage(imgs[l].getAttribute("src"), imgs[l].width, imgs[l].height);
-  		}return x || done();
-  	};
-  	checkForFooter = function checkForFooter(elem, renderer, elementHandlers) {
-  		//check if we can found a <footer> element
-  		var footer = elem.getElementsByTagName("footer");
-  		if (footer.length > 0) {
-
-  			footer = footer[0];
-
-  			//bad hack to get height of footer
-  			//creat dummy out and check new y after fake rendering
-  			var oldOut = renderer.pdf.internal.write;
-  			var oldY = renderer.y;
-  			renderer.pdf.internal.write = function () {};
-  			_DrillForContent(footer, renderer, elementHandlers);
-  			var footerHeight = Math.ceil(renderer.y - oldY) + 5;
-  			renderer.y = oldY;
-  			renderer.pdf.internal.write = oldOut;
-
-  			//add 20% to prevent overlapping
-  			renderer.pdf.margins_doc.bottom += footerHeight;
-
-  			//Create function render header on every page
-  			var renderFooter = function renderFooter(pageInfo) {
-  				var pageNumber = pageInfo !== undefined ? pageInfo.pageNumber : 1;
-  				//set current y position to old margin
-  				var oldPosition = renderer.y;
-  				//render all child nodes of the header element
-  				renderer.y = renderer.pdf.internal.pageSize.getHeight() - renderer.pdf.margins_doc.bottom;
-  				renderer.pdf.margins_doc.bottom -= footerHeight;
-
-  				//check if we have to add page numbers
-  				var spans = footer.getElementsByTagName('span');
-  				for (var i = 0; i < spans.length; ++i) {
-  					//if we find some span element with class pageCounter, set the page
-  					if ((" " + spans[i].className + " ").replace(/[\n\t]/g, " ").indexOf(" pageCounter ") > -1) {
-  						spans[i].innerHTML = pageNumber;
-  					}
-  					//if we find some span element with class totalPages, set a variable which is replaced after rendering of all pages
-  					if ((" " + spans[i].className + " ").replace(/[\n\t]/g, " ").indexOf(" totalPages ") > -1) {
-  						spans[i].innerHTML = '###jsPDFVarTotalPages###';
-  					}
-  				}
-
-  				//render footer content
-  				_DrillForContent(footer, renderer, elementHandlers);
-  				//set bottom margin to previous height including the footer height
-  				renderer.pdf.margins_doc.bottom += footerHeight;
-  				//important for other plugins (e.g. table) to start rendering at correct position after header
-  				renderer.y = oldPosition;
-  			};
-
-  			//check if footer contains totalPages which should be replace at the disoposal of the document
-  			var spans = footer.getElementsByTagName('span');
-  			for (var i = 0; i < spans.length; ++i) {
-  				if ((" " + spans[i].className + " ").replace(/[\n\t]/g, " ").indexOf(" totalPages ") > -1) {
-  					renderer.pdf.internal.events.subscribe('htmlRenderingFinished', renderer.pdf.putTotalPages.bind(renderer.pdf, '###jsPDFVarTotalPages###'), true);
-  				}
-  			}
-
-  			//register event to render footer on every new page
-  			renderer.pdf.internal.events.subscribe('addPage', renderFooter, false);
-  			//render footer on first page
-  			renderFooter();
-
-  			//prevent footer rendering
-  			SkipNode['FOOTER'] = 1;
-  		}
-  	};
-  	process = function process(pdf, element, x, y, settings, callback) {
-  		if (!element) return false;
-  		if (typeof element !== "string" && !element.parentNode) element = '' + element.innerHTML;
-  		if (typeof element === "string") {
-  			element = function (element) {
-  				var $frame, $hiddendiv, framename, visuallyhidden;
-  				framename = "jsPDFhtmlText" + Date.now().toString() + (Math.random() * 1000).toFixed(0);
-  				visuallyhidden = "position: absolute !important;" + "clip: rect(1px 1px 1px 1px); /* IE6, IE7 */" + "clip: rect(1px, 1px, 1px, 1px);" + "padding:0 !important;" + "border:0 !important;" + "height: 1px !important;" + "width: 1px !important; " + "top:auto;" + "left:-100px;" + "overflow: hidden;";
-  				$hiddendiv = document.createElement('div');
-  				$hiddendiv.style.cssText = visuallyhidden;
-  				$hiddendiv.innerHTML = "<iframe style=\"height:1px;width:1px\" name=\"" + framename + "\" />";
-  				document.body.appendChild($hiddendiv);
-  				$frame = window.frames[framename];
-  				$frame.document.open();
-  				$frame.document.writeln(element);
-  				$frame.document.close();
-  				return $frame.document.body;
-  			}(element.replace(/<\/?script[^>]*?>/gi, ''));
-  		}
-  		var r = new Renderer(pdf, x, y, settings),
-  		    out;
-
-  		// 1. load images
-  		// 2. prepare optional footer elements
-  		// 3. render content
-  		loadImgs.call(this, element, r, settings.elementHandlers, function (found_images) {
-  			checkForFooter(element, r, settings.elementHandlers);
-  			_DrillForContent(element, r, settings.elementHandlers);
-  			//send event dispose for final taks (e.g. footer totalpage replacement)
-  			r.pdf.internal.events.publish('htmlRenderingFinished');
-  			out = r.dispose();
-  			if (typeof callback === 'function') callback(out);else if (found_images) console.error('jsPDF Warning: rendering issues? provide a callback to fromHTML!');
-  		});
-  		return out || { x: r.x, y: r.y };
-  	};
-  	Renderer.prototype.init = function () {
-  		this.paragraph = {
-  			text: [],
-  			style: []
-  		};
-  		return this.pdf.internal.write("q");
-  	};
-  	Renderer.prototype.dispose = function () {
-  		this.pdf.internal.write("Q");
-  		return {
-  			x: this.x,
-  			y: this.y,
-  			ready: true
-  		};
-  	};
-
-  	//Checks if we have to execute some watcher functions
-  	//e.g. to end text floating around an image
-  	Renderer.prototype.executeWatchFunctions = function (el) {
-  		var ret = false;
-  		var narray = [];
-  		if (this.watchFunctions.length > 0) {
-  			for (var i = 0; i < this.watchFunctions.length; ++i) {
-  				if (this.watchFunctions[i](el) === true) {
-  					ret = true;
-  				} else {
-  					narray.push(this.watchFunctions[i]);
-  				}
-  			}
-  			this.watchFunctions = narray;
-  		}
-  		return ret;
-  	};
-
-  	Renderer.prototype.splitFragmentsIntoLines = function (fragments, styles) {
-  		var currentLineLength, defaultFontSize, ff, fontMetrics, fontMetricsCache, fragment, fragmentChopped, fragmentLength, fragmentSpecificMetrics, fs, k, line, lines, maxLineLength, style;
-  		defaultFontSize = 12;
-  		k = this.pdf.internal.scaleFactor;
-  		fontMetricsCache = {};
-  		ff = void 0;
-  		fs = void 0;
-  		fontMetrics = void 0;
-  		fragment = void 0;
-  		style = void 0;
-  		fragmentSpecificMetrics = void 0;
-  		fragmentLength = void 0;
-  		fragmentChopped = void 0;
-  		line = [];
-  		lines = [line];
-  		currentLineLength = 0;
-  		maxLineLength = this.settings.width;
-  		while (fragments.length) {
-  			fragment = fragments.shift();
-  			style = styles.shift();
-  			if (fragment) {
-  				ff = style["font-family"];
-  				fs = style["font-style"];
-  				fontMetrics = fontMetricsCache[ff + fs];
-  				if (!fontMetrics) {
-  					fontMetrics = this.pdf.internal.getFont(ff, fs).metadata.Unicode;
-  					fontMetricsCache[ff + fs] = fontMetrics;
-  				}
-  				fragmentSpecificMetrics = {
-  					widths: fontMetrics.widths,
-  					kerning: fontMetrics.kerning,
-  					fontSize: style["font-size"] * defaultFontSize,
-  					textIndent: currentLineLength
-  				};
-  				fragmentLength = this.pdf.getStringUnitWidth(fragment, fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k;
-  				if (fragment == "\u2028") {
-  					line = [];
-  					lines.push(line);
-  				} else if (currentLineLength + fragmentLength > maxLineLength) {
-  					fragmentChopped = this.pdf.splitTextToSize(fragment, maxLineLength, fragmentSpecificMetrics);
-  					line.push([fragmentChopped.shift(), style]);
-  					while (fragmentChopped.length) {
-  						line = [[fragmentChopped.shift(), style]];
-  						lines.push(line);
-  					}
-  					currentLineLength = this.pdf.getStringUnitWidth(line[0][0], fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k;
-  				} else {
-  					line.push([fragment, style]);
-  					currentLineLength += fragmentLength;
-  				}
-  			}
-  		}
-
-  		//if text alignment was set, set margin/indent of each line
-  		if (style['text-align'] !== undefined && (style['text-align'] === 'center' || style['text-align'] === 'right' || style['text-align'] === 'justify')) {
-  			for (var i = 0; i < lines.length; ++i) {
-  				var length = this.pdf.getStringUnitWidth(lines[i][0][0], fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k;
-  				//if there is more than on line we have to clone the style object as all lines hold a reference on this object
-  				if (i > 0) {
-  					lines[i][0][1] = clone(lines[i][0][1]);
-  				}
-  				var space = maxLineLength - length;
-
-  				if (style['text-align'] === 'right') {
-  					lines[i][0][1]['margin-left'] = space;
-  					//if alignment is not right, it has to be center so split the space to the left and the right
-  				} else if (style['text-align'] === 'center') {
-  					lines[i][0][1]['margin-left'] = space / 2;
-  					//if justify was set, calculate the word spacing and define in by using the css property
-  				} else if (style['text-align'] === 'justify') {
-  					var countSpaces = lines[i][0][0].split(' ').length - 1;
-  					lines[i][0][1]['word-spacing'] = space / countSpaces;
-  					//ignore the last line in justify mode
-  					if (i === lines.length - 1) {
-  						lines[i][0][1]['word-spacing'] = 0;
-  					}
-  				}
-  			}
-  		}
-
-  		return lines;
-  	};
-  	Renderer.prototype.RenderTextFragment = function (text, style) {
-  		var defaultFontSize, font, maxLineHeight;
-
-  		maxLineHeight = 0;
-  		defaultFontSize = 12;
-
-  		if (this.pdf.internal.pageSize.getHeight() - this.pdf.margins_doc.bottom < this.y + this.pdf.internal.getFontSize()) {
-  			this.pdf.internal.write("ET", "Q");
-  			this.pdf.addPage();
-  			this.y = this.pdf.margins_doc.top;
-  			this.pdf.internal.write("q", "BT", this.getPdfColor(style.color), this.pdf.internal.getCoordinateString(this.x), this.pdf.internal.getVerticalCoordinateString(this.y), "Td");
-  			//move cursor by one line on new page
-  			maxLineHeight = Math.max(maxLineHeight, style["line-height"], style["font-size"]);
-  			this.pdf.internal.write(0, (-1 * defaultFontSize * maxLineHeight).toFixed(2), "Td");
-  		}
-
-  		font = this.pdf.internal.getFont(style["font-family"], style["font-style"]);
-
-  		// text color
-  		var pdfTextColor = this.getPdfColor(style["color"]);
-  		if (pdfTextColor !== this.lastTextColor) {
-  			this.pdf.internal.write(pdfTextColor);
-  			this.lastTextColor = pdfTextColor;
-  		}
-
-  		//set the word spacing for e.g. justify style
-  		if (style['word-spacing'] !== undefined && style['word-spacing'] > 0) {
-  			this.pdf.internal.write(style['word-spacing'].toFixed(2), "Tw");
-  		}
-
-  		this.pdf.internal.write("/" + font.id, (defaultFontSize * style["font-size"]).toFixed(2), "Tf", "(" + this.pdf.internal.pdfEscape(text) + ") Tj");
-
-  		//set the word spacing back to neutral => 0
-  		if (style['word-spacing'] !== undefined) {
-  			this.pdf.internal.write(0, "Tw");
-  		}
-  	};
-
-  	// Accepts #FFFFFF, rgb(int,int,int), or CSS Color Name
-  	Renderer.prototype.getPdfColor = function (style) {
-  		var textColor;
-  		var r, g, b;
-
-  		var rgbColor = new RGBColor(style);
-  		var rx = /rgb\s*\(\s*(\d+),\s*(\d+),\s*(\d+\s*)\)/;
-  		var m = rx.exec(style);
-  		if (m != null) {
-  			r = parseInt(m[1]);
-  			g = parseInt(m[2]);
-  			b = parseInt(m[3]);
-  		} else {
-  			if (style.charAt(0) != '#') {
-  				if (rgbColor.ok) {
-  					style = rgbColor.toHex();
-  				} else {
-  					style = '#000000';
-  				}
-  			}
-  			r = style.substring(1, 3);
-  			r = parseInt(r, 16);
-  			g = style.substring(3, 5);
-  			g = parseInt(g, 16);
-  			b = style.substring(5, 7);
-  			b = parseInt(b, 16);
-  		}
-
-  		if (typeof r === 'string' && /^#[0-9A-Fa-f]{6}$/.test(r)) {
-  			var hex = parseInt(r.substr(1), 16);
-  			r = hex >> 16 & 255;
-  			g = hex >> 8 & 255;
-  			b = hex & 255;
-  		}
-
-  		var f3 = this.f3;
-  		if (r === 0 && g === 0 && b === 0 || typeof g === 'undefined') {
-  			textColor = f3(r / 255) + ' g';
-  		} else {
-  			textColor = [f3(r / 255), f3(g / 255), f3(b / 255), 'rg'].join(' ');
-  		}
-  		return textColor;
-  	};
-
-  	Renderer.prototype.f3 = function (number) {
-  		return number.toFixed(3); // Ie, %.3f
-  	}, Renderer.prototype.renderParagraph = function (cb) {
-  		var blockstyle, defaultFontSize, fontToUnitRatio, fragments, i, l, line, lines, maxLineHeight, out, paragraphspacing_after, paragraphspacing_before, priorblockstyle, styles, fontSize;
-  		fragments = PurgeWhiteSpace(this.paragraph.text);
-  		styles = this.paragraph.style;
-  		blockstyle = this.paragraph.blockstyle;
-  		priorblockstyle = this.paragraph.priorblockstyle || {};
-  		this.paragraph = {
-  			text: [],
-  			style: [],
-  			blockstyle: {},
-  			priorblockstyle: blockstyle
-  		};
-  		if (!fragments.join("").trim()) {
-  			return;
-  		}
-  		lines = this.splitFragmentsIntoLines(fragments, styles);
-  		line = void 0;
-  		maxLineHeight = void 0;
-  		defaultFontSize = 12;
-  		fontToUnitRatio = defaultFontSize / this.pdf.internal.scaleFactor;
-  		this.priorMarginBottom = this.priorMarginBottom || 0;
-  		paragraphspacing_before = (Math.max((blockstyle["margin-top"] || 0) - this.priorMarginBottom, 0) + (blockstyle["padding-top"] || 0)) * fontToUnitRatio;
-  		paragraphspacing_after = ((blockstyle["margin-bottom"] || 0) + (blockstyle["padding-bottom"] || 0)) * fontToUnitRatio;
-  		this.priorMarginBottom = blockstyle["margin-bottom"] || 0;
-
-  		if (blockstyle['page-break-before'] === 'always') {
-  			this.pdf.addPage();
-  			this.y = 0;
-  			paragraphspacing_before = ((blockstyle["margin-top"] || 0) + (blockstyle["padding-top"] || 0)) * fontToUnitRatio;
-  		}
-
-  		out = this.pdf.internal.write;
-  		i = void 0;
-  		l = void 0;
-  		this.y += paragraphspacing_before;
-  		out("q", "BT 0 g", this.pdf.internal.getCoordinateString(this.x), this.pdf.internal.getVerticalCoordinateString(this.y), "Td");
-
-  		//stores the current indent of cursor position
-  		var currentIndent = 0;
-
-  		while (lines.length) {
-  			line = lines.shift();
-  			maxLineHeight = 0;
-  			i = 0;
-  			l = line.length;
-  			while (i !== l) {
-  				if (line[i][0].trim()) {
-  					maxLineHeight = Math.max(maxLineHeight, line[i][1]["line-height"], line[i][1]["font-size"]);
-  					fontSize = line[i][1]["font-size"] * 7;
-  				}
-  				i++;
-  			}
-  			//if we have to move the cursor to adapt the indent
-  			var indentMove = 0;
-  			var wantedIndent = 0;
-  			//if a margin was added (by e.g. a text-alignment), move the cursor
-  			if (line[0][1]["margin-left"] !== undefined && line[0][1]["margin-left"] > 0) {
-  				wantedIndent = this.pdf.internal.getCoordinateString(line[0][1]["margin-left"]);
-  				indentMove = wantedIndent - currentIndent;
-  				currentIndent = wantedIndent;
-  			}
-  			var indentMore = Math.max(blockstyle["margin-left"] || 0, 0) * fontToUnitRatio;
-  			//move the cursor
-  			out(indentMove + indentMore, (-1 * defaultFontSize * maxLineHeight).toFixed(2), "Td");
-  			i = 0;
-  			l = line.length;
-  			while (i !== l) {
-  				if (line[i][0]) {
-  					this.RenderTextFragment(line[i][0], line[i][1]);
-  				}
-  				i++;
-  			}
-  			this.y += maxLineHeight * fontToUnitRatio;
-
-  			//if some watcher function was executed successful, so e.g. margin and widths were changed,
-  			//reset line drawing and calculate position and lines again
-  			//e.g. to stop text floating around an image
-  			if (this.executeWatchFunctions(line[0][1]) && lines.length > 0) {
-  				var localFragments = [];
-  				var localStyles = [];
-  				//create fragment array of
-  				lines.forEach(function (localLine) {
-  					var i = 0;
-  					var l = localLine.length;
-  					while (i !== l) {
-  						if (localLine[i][0]) {
-  							localFragments.push(localLine[i][0] + ' ');
-  							localStyles.push(localLine[i][1]);
-  						}
-  						++i;
-  					}
-  				});
-  				//split lines again due to possible coordinate changes
-  				lines = this.splitFragmentsIntoLines(PurgeWhiteSpace(localFragments), localStyles);
-  				//reposition the current cursor
-  				out("ET", "Q");
-  				out("q", "BT 0 g", this.pdf.internal.getCoordinateString(this.x), this.pdf.internal.getVerticalCoordinateString(this.y), "Td");
-  			}
-  		}
-  		if (cb && typeof cb === "function") {
-  			cb.call(this, this.x - 9, this.y - fontSize / 2);
-  		}
-  		out("ET", "Q");
-  		return this.y += paragraphspacing_after;
-  	};
-  	Renderer.prototype.setBlockBoundary = function (cb) {
-  		return this.renderParagraph(cb);
-  	};
-  	Renderer.prototype.setBlockStyle = function (css) {
-  		return this.paragraph.blockstyle = css;
-  	};
-  	Renderer.prototype.addText = function (text, css) {
-  		this.paragraph.text.push(text);
-  		return this.paragraph.style.push(css);
-  	};
-  	FontNameDB = {
-  		helvetica: "helvetica",
-  		"sans-serif": "helvetica",
-  		"times new roman": "times",
-  		serif: "times",
-  		times: "times",
-  		monospace: "courier",
-  		courier: "courier"
-  	};
-  	FontWeightMap = {
-  		100: "normal",
-  		200: "normal",
-  		300: "normal",
-  		400: "normal",
-  		500: "bold",
-  		600: "bold",
-  		700: "bold",
-  		800: "bold",
-  		900: "bold",
-  		normal: "normal",
-  		bold: "bold",
-  		bolder: "bold",
-  		lighter: "normal"
-  	};
-  	FontStyleMap = {
-  		normal: "normal",
-  		italic: "italic",
-  		oblique: "italic"
-  	};
-  	TextAlignMap = {
-  		left: "left",
-  		right: "right",
-  		center: "center",
-  		justify: "justify"
-  	};
-  	FloatMap = {
-  		none: 'none',
-  		right: 'right',
-  		left: 'left'
-  	};
-  	ClearMap = {
-  		none: 'none',
-  		both: 'both'
-  	};
-  	UnitedNumberMap = {
-  		normal: 1
-  	};
-  	/**
-    * Converts HTML-formatted text into formatted PDF text.
-    *
-    * Notes:
-    * 2012-07-18
-    * Plugin relies on having browser, DOM around. The HTML is pushed into dom and traversed.
-    * Plugin relies on jQuery for CSS extraction.
-    * Targeting HTML output from Markdown templating, which is a very simple
-    * markup - div, span, em, strong, p. No br-based paragraph separation supported explicitly (but still may work.)
-    * Images, tables are NOT supported.
-    *
-    * @public
-    * @function
-    * @param HTML {String or DOM Element} HTML-formatted text, or pointer to DOM element that is to be rendered into PDF.
-    * @param x {Number} starting X coordinate in jsPDF instance's declared units.
-    * @param y {Number} starting Y coordinate in jsPDF instance's declared units.
-    * @param settings {Object} Additional / optional variables controlling parsing, rendering.
-    * @returns {Object} jsPDF instance
-    */
-  	jsPDFAPI.fromHTML = function (HTML, x, y, settings, callback, margins) {
+          result = da;
+        }
 
-  		this.margins_doc = margins || {
-  			top: 0,
-  			bottom: 0
-  		};
-  		if (!settings) settings = {};
-  		if (!settings.elementHandlers) settings.elementHandlers = {};
+        return result;
+      } //Check if text is of type String
 
-  		return process(this, HTML, isNaN(x) ? 4 : x, isNaN(y) ? 4 : y, settings, callback);
-  	};
-  })(jsPDF.API);
 
-  /** ==================================================================== 
-   * jsPDF JavaScript plugin
-   * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
-   * 
-   * 
-   * ====================================================================
-   */
+      var textIsOfTypeString = false;
+      var tmpTextIsOfTypeString = true;
 
-  /*global jsPDF */
+      if (typeof text === "string") {
+        textIsOfTypeString = true;
+      } else if (Array.isArray(text)) {
+        //we don't want to destroy original text array, so cloning it
+        var sa = text.concat();
+        da = [];
+        var len = sa.length;
+        var curDa; //we do array.join('text that must not be PDFescaped")
+        //thus, pdfEscape each component separately
 
-  (function (jsPDFAPI) {
+        while (len--) {
+          curDa = sa.shift();
 
-      var jsNamesObj, jsJsObj, text;
-      jsPDFAPI.addJS = function (txt) {
-          text = txt;
-          this.internal.events.subscribe('postPutResources', function (txt) {
-              jsNamesObj = this.internal.newObject();
-              this.internal.out('<<');
-              this.internal.out('/Names [(EmbeddedJS) ' + (jsNamesObj + 1) + ' 0 R]');
-              this.internal.out('>>');
-              this.internal.out('endobj');
-
-              jsJsObj = this.internal.newObject();
-              this.internal.out('<<');
-              this.internal.out('/S /JavaScript');
-              this.internal.out('/JS (' + text + ')');
-              this.internal.out('>>');
-              this.internal.out('endobj');
-          });
-          this.internal.events.subscribe('putCatalog', function () {
-              if (jsNamesObj !== undefined && jsJsObj !== undefined) {
-                  this.internal.out('/Names <</JavaScript ' + jsNamesObj + ' 0 R>>');
-              }
-          });
-          return this;
-      };
-  })(jsPDF.API);
+          if (typeof curDa !== "string" || Array.isArray(curDa) && typeof curDa[0] !== "string") {
+            tmpTextIsOfTypeString = false;
+          }
+        }
 
-  /**
-   * jsPDF Outline PlugIn
-   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
-  (function (jsPDFAPI) {
+        textIsOfTypeString = tmpTextIsOfTypeString;
+      }
 
-  	jsPDFAPI.events.push(['postPutResources', function () {
-  		var pdf = this;
-  		var rx = /^(\d+) 0 obj$/;
-
-  		// Write action goto objects for each page
-  		// this.outline.destsGoto = [];
-  		// for (var i = 0; i < totalPages; i++) {
-  		// var id = pdf.internal.newObject();
-  		// this.outline.destsGoto.push(id);
-  		// pdf.internal.write("<</D[" + (i * 2 + 3) + " 0 R /XYZ null
-  		// null null]/S/GoTo>> endobj");
-  		// }
-  		//
-  		// for (var i = 0; i < dests.length; i++) {
-  		// pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0
-  		// R");
-  		// }
-  		//				
-  		if (this.outline.root.children.length > 0) {
-  			var lines = pdf.outline.render().split(/\r\n/);
-  			for (var i = 0; i < lines.length; i++) {
-  				var line = lines[i];
-  				var m = rx.exec(line);
-  				if (m != null) {
-  					var oid = m[1];
-  					pdf.internal.newObjectDeferredBegin(oid);
-  				}
-  				pdf.internal.write(line);
-  			}
-  		}
-
-  		// This code will write named destination for each page reference
-  		// (page_1, etc)
-  		if (this.outline.createNamedDestinations) {
-  			var totalPages = this.internal.pages.length;
-  			// WARNING: this assumes jsPDF starts on page 3 and pageIDs
-  			// follow 5, 7, 9, etc
-  			// Write destination objects for each page
-  			var dests = [];
-  			for (var i = 0; i < totalPages; i++) {
-  				var id = pdf.internal.newObject();
-  				dests.push(id);
-  				var info = pdf.internal.getPageInfo(i + 1);
-  				pdf.internal.write("<< /D[" + info.objId + " 0 R /XYZ null null null]>> endobj");
-  			}
-
-  			// assign a name for each destination
-  			var names2Oid = pdf.internal.newObject();
-  			pdf.internal.write('<< /Names [ ');
-  			for (var i = 0; i < dests.length; i++) {
-  				pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0 R");
-  			}
-  			pdf.internal.write(' ] >>', 'endobj');
-
-  			// var kids = pdf.internal.newObject();
-  			// pdf.internal.write('<< /Kids [ ' + names2Oid + ' 0 R');
-  			// pdf.internal.write(' ] >>', 'endobj');
-
-  			var namesOid = pdf.internal.newObject();
-  			pdf.internal.write('<< /Dests ' + names2Oid + " 0 R");
-  			pdf.internal.write('>>', 'endobj');
-  		}
-  	}]);
-
-  	jsPDFAPI.events.push(['putCatalog', function () {
-  		var pdf = this;
-  		if (pdf.outline.root.children.length > 0) {
-  			pdf.internal.write("/Outlines", this.outline.makeRef(this.outline.root));
-  			if (this.outline.createNamedDestinations) {
-  				pdf.internal.write("/Names " + namesOid + " 0 R");
-  			}
-  			// Open with Bookmarks showing
-  			// pdf.internal.write("/PageMode /UseOutlines");
-  		}
-  	}]);
-
-  	jsPDFAPI.events.push(['initialized', function () {
-  		var pdf = this;
-
-  		pdf.outline = {
-  			createNamedDestinations: false,
-  			root: {
-  				children: []
-  			}
-  		};
-
-  		/**
-     * Options: pageNumber
-     */
-  		pdf.outline.add = function (parent, title, options) {
-  			var item = {
-  				title: title,
-  				options: options,
-  				children: []
-  			};
-  			if (parent == null) {
-  				parent = this.root;
-  			}
-  			parent.children.push(item);
-  			return item;
-  		};
-
-  		pdf.outline.render = function () {
-  			this.ctx = {};
-  			this.ctx.val = '';
-  			this.ctx.pdf = pdf;
-
-  			this.genIds_r(this.root);
-  			this.renderRoot(this.root);
-  			this.renderItems(this.root);
-
-  			return this.ctx.val;
-  		};
-
-  		pdf.outline.genIds_r = function (node) {
-  			node.id = pdf.internal.newObjectDeferred();
-  			for (var i = 0; i < node.children.length; i++) {
-  				this.genIds_r(node.children[i]);
-  			}
-  		};
-
-  		pdf.outline.renderRoot = function (node) {
-  			this.objStart(node);
-  			this.line('/Type /Outlines');
-  			if (node.children.length > 0) {
-  				this.line('/First ' + this.makeRef(node.children[0]));
-  				this.line('/Last ' + this.makeRef(node.children[node.children.length - 1]));
-  			}
-  			this.line('/Count ' + this.count_r({
-  				count: 0
-  			}, node));
-  			this.objEnd();
-  		};
-
-  		pdf.outline.renderItems = function (node) {
-  			for (var i = 0; i < node.children.length; i++) {
-  				var item = node.children[i];
-  				this.objStart(item);
-
-  				this.line('/Title ' + this.makeString(item.title));
-
-  				this.line('/Parent ' + this.makeRef(node));
-  				if (i > 0) {
-  					this.line('/Prev ' + this.makeRef(node.children[i - 1]));
-  				}
-  				if (i < node.children.length - 1) {
-  					this.line('/Next ' + this.makeRef(node.children[i + 1]));
-  				}
-  				if (item.children.length > 0) {
-  					this.line('/First ' + this.makeRef(item.children[0]));
-  					this.line('/Last ' + this.makeRef(item.children[item.children.length - 1]));
-  				}
-
-  				var count = this.count = this.count_r({
-  					count: 0
-  				}, item);
-  				if (count > 0) {
-  					this.line('/Count ' + count);
-  				}
-
-  				if (item.options) {
-  					if (item.options.pageNumber) {
-  						// Explicit Destination
-  						//WARNING this assumes page ids are 3,5,7, etc.
-  						var info = pdf.internal.getPageInfo(item.options.pageNumber);
-  						this.line('/Dest ' + '[' + info.objId + ' 0 R /XYZ 0 ' + this.ctx.pdf.internal.pageSize.getHeight() * this.ctx.pdf.internal.scaleFactor + ' 0]');
-  						// this line does not work on all clients (pageNumber instead of page ref)
-  						//this.line('/Dest ' + '[' + (item.options.pageNumber - 1) + ' /XYZ 0 ' + this.ctx.pdf.internal.pageSize.getHeight() + ' 0]');
-
-  						// Named Destination
-  						// this.line('/Dest (page_' + (item.options.pageNumber) + ')');
-
-  						// Action Destination
-  						// var id = pdf.internal.newObject();
-  						// pdf.internal.write('<</D[' + (item.options.pageNumber - 1) + ' /XYZ null null null]/S/GoTo>> endobj');
-  						// this.line('/A ' + id + ' 0 R' );
-  					}
-  				}
-  				this.objEnd();
-  			}
-  			for (var i = 0; i < node.children.length; i++) {
-  				var item = node.children[i];
-  				this.renderItems(item);
-  			}
-  		};
-
-  		pdf.outline.line = function (text) {
-  			this.ctx.val += text + '\r\n';
-  		};
-
-  		pdf.outline.makeRef = function (node) {
-  			return node.id + ' 0 R';
-  		};
-
-  		pdf.outline.makeString = function (val) {
-  			return '(' + pdf.internal.pdfEscape(val) + ')';
-  		};
-
-  		pdf.outline.objStart = function (node) {
-  			this.ctx.val += '\r\n' + node.id + ' 0 obj' + '\r\n<<\r\n';
-  		};
-
-  		pdf.outline.objEnd = function (node) {
-  			this.ctx.val += '>> \r\n' + 'endobj' + '\r\n';
-  		};
-
-  		pdf.outline.count_r = function (ctx, node) {
-  			for (var i = 0; i < node.children.length; i++) {
-  				ctx.count++;
-  				this.count_r(ctx, node.children[i]);
-  			}
-  			return ctx.count;
-  		};
-  	}]);
-
-  	return this;
-  })(jsPDF.API);
+      if (textIsOfTypeString === false) {
+        throw new Error('Type of text must be string or Array. "' + text + '" is not recognized.');
+      } //If there are any newlines in text, we assume
+      //the user wanted to print multiple lines, so break the
+      //text up into an array. If the text is already an array,
+      //we assume the user knows what they are doing.
+      //Convert text into an array anyway to simplify
+      //later code.
 
-  /**@preserve
-   *  ====================================================================
-   * jsPDF PNG PlugIn
-   * Copyright (c) 2014 James Robb, https://github.com/jamesbrobb
-   *
-   * 
-   * ====================================================================
-   */
 
-  (function (jsPDFAPI) {
+      if (typeof text === "string") {
+        if (text.match(/[\r?\n]/)) {
+          text = text.split(/\r\n|\r|\n/g);
+        } else {
+          text = [text];
+        }
+      } //baseline
 
-  	/*
-    * @see http://www.w3.org/TR/PNG-Chunks.html
-    *
-    Color    Allowed      Interpretation
-    Type     Bit Depths
-   	   0       1,2,4,8,16  Each pixel is a grayscale sample.
-   	   2       8,16        Each pixel is an R,G,B triple.
-   	   3       1,2,4,8     Each pixel is a palette index;
-                          a PLTE chunk must appear.
-   	   4       8,16        Each pixel is a grayscale sample,
-                          followed by an alpha sample.
-   	   6       8,16        Each pixel is an R,G,B triple,
-                          followed by an alpha sample.
-   */
 
-  	/*
-    * PNG filter method types
-    *
-    * @see http://www.w3.org/TR/PNG-Filters.html
-    * @see http://www.libpng.org/pub/png/book/chapter09.html
-    *
-    * This is what the value 'Predictor' in decode params relates to
-    *
-    * 15 is "optimal prediction", which means the prediction algorithm can change from line to line.
-    * In that case, you actually have to read the first byte off each line for the prediction algorthim (which should be 0-4, corresponding to PDF 10-14) and select the appropriate unprediction algorithm based on that byte.
-    *
-      0       None
-      1       Sub
-      2       Up
-      3       Average
-      4       Paeth
-    */
+      var height = activeFontSize / scope.internal.scaleFactor;
+      var descent = height * (lineHeight - 1);
 
-  	var doesNotHavePngJS = function doesNotHavePngJS() {
-  		return typeof PNG !== 'function' || typeof FlateStream !== 'function';
-  	},
-  	    canCompress = function canCompress(value) {
-  		return value !== jsPDFAPI.image_compression.NONE && hasCompressionJS();
-  	},
-  	    hasCompressionJS = function hasCompressionJS() {
-  		var inst = typeof Deflater === 'function';
-  		if (!inst) throw new Error("requires deflate.js for compression");
-  		return inst;
-  	},
-  	    compressBytes = function compressBytes(bytes, lineLength, colorsPerPixel, compression) {
-
-  		var level = 5,
-  		    filter_method = filterUp;
-
-  		switch (compression) {
-
-  			case jsPDFAPI.image_compression.FAST:
-
-  				level = 3;
-  				filter_method = filterSub;
-  				break;
-
-  			case jsPDFAPI.image_compression.MEDIUM:
-
-  				level = 6;
-  				filter_method = filterAverage;
-  				break;
-
-  			case jsPDFAPI.image_compression.SLOW:
-
-  				level = 9;
-  				filter_method = filterPaeth; //uses to sum to choose best filter for each line
-  				break;
-  		}
-
-  		bytes = applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method);
-
-  		var header = new Uint8Array(createZlibHeader(level));
-  		var checksum = adler32(bytes);
-
-  		var deflate = new Deflater(level);
-  		var a = deflate.append(bytes);
-  		var cBytes = deflate.flush();
-
-  		var len = header.length + a.length + cBytes.length;
-
-  		var cmpd = new Uint8Array(len + 4);
-  		cmpd.set(header);
-  		cmpd.set(a, header.length);
-  		cmpd.set(cBytes, header.length + a.length);
-
-  		cmpd[len++] = checksum >>> 24 & 0xff;
-  		cmpd[len++] = checksum >>> 16 & 0xff;
-  		cmpd[len++] = checksum >>> 8 & 0xff;
-  		cmpd[len++] = checksum & 0xff;
-
-  		return jsPDFAPI.arrayBufferToBinaryString(cmpd);
-  	},
-  	    createZlibHeader = function createZlibHeader(bytes, level) {
-  		/*
-     * @see http://www.ietf.org/rfc/rfc1950.txt for zlib header
-     */
-  		var cm = 8;
-  		var cinfo = Math.LOG2E * Math.log(0x8000) - 8;
-  		var cmf = cinfo << 4 | cm;
-
-  		var hdr = cmf << 8;
-  		var flevel = Math.min(3, (level - 1 & 0xff) >> 1);
-
-  		hdr |= flevel << 6;
-  		hdr |= 0; //FDICT
-  		hdr += 31 - hdr % 31;
-
-  		return [cmf, hdr & 0xff & 0xff];
-  	},
-  	    adler32 = function adler32(array, param) {
-  		var adler = 1;
-  		var s1 = adler & 0xffff,
-  		    s2 = adler >>> 16 & 0xffff;
-  		var len = array.length;
-  		var tlen;
-  		var i = 0;
-
-  		while (len > 0) {
-  			tlen = len > param ? param : len;
-  			len -= tlen;
-  			do {
-  				s1 += array[i++];
-  				s2 += s1;
-  			} while (--tlen);
-
-  			s1 %= 65521;
-  			s2 %= 65521;
-  		}
-
-  		return (s2 << 16 | s1) >>> 0;
-  	},
-  	    applyPngFilterMethod = function applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method) {
-  		var lines = bytes.length / lineLength,
-  		    result = new Uint8Array(bytes.length + lines),
-  		    filter_methods = getFilterMethods(),
-  		    i = 0,
-  		    line,
-  		    prevLine,
-  		    offset;
-
-  		for (; i < lines; i++) {
-  			offset = i * lineLength;
-  			line = bytes.subarray(offset, offset + lineLength);
-
-  			if (filter_method) {
-  				result.set(filter_method(line, colorsPerPixel, prevLine), offset + i);
-  			} else {
-
-  				var j = 0,
-  				    len = filter_methods.length,
-  				    results = [];
-
-  				for (; j < len; j++) {
-  					results[j] = filter_methods[j](line, colorsPerPixel, prevLine);
-  				}var ind = getIndexOfSmallestSum(results.concat());
-
-  				result.set(results[ind], offset + i);
-  			}
-
-  			prevLine = line;
-  		}
-
-  		return result;
-  	},
-  	    filterNone = function filterNone(line, colorsPerPixel, prevLine) {
-  		/*var result = new Uint8Array(line.length + 1);
-    result[0] = 0;
-    result.set(line, 1);*/
-
-  		var result = Array.apply([], line);
-  		result.unshift(0);
-
-  		return result;
-  	},
-  	    filterSub = function filterSub(line, colorsPerPixel, prevLine) {
-  		var result = [],
-  		    i = 0,
-  		    len = line.length,
-  		    left;
-
-  		result[0] = 1;
-
-  		for (; i < len; i++) {
-  			left = line[i - colorsPerPixel] || 0;
-  			result[i + 1] = line[i] - left + 0x0100 & 0xff;
-  		}
-
-  		return result;
-  	},
-  	    filterUp = function filterUp(line, colorsPerPixel, prevLine) {
-  		var result = [],
-  		    i = 0,
-  		    len = line.length,
-  		    up;
-
-  		result[0] = 2;
-
-  		for (; i < len; i++) {
-  			up = prevLine && prevLine[i] || 0;
-  			result[i + 1] = line[i] - up + 0x0100 & 0xff;
-  		}
-
-  		return result;
-  	},
-  	    filterAverage = function filterAverage(line, colorsPerPixel, prevLine) {
-  		var result = [],
-  		    i = 0,
-  		    len = line.length,
-  		    left,
-  		    up;
-
-  		result[0] = 3;
-
-  		for (; i < len; i++) {
-  			left = line[i - colorsPerPixel] || 0;
-  			up = prevLine && prevLine[i] || 0;
-  			result[i + 1] = line[i] + 0x0100 - (left + up >>> 1) & 0xff;
-  		}
-
-  		return result;
-  	},
-  	    filterPaeth = function filterPaeth(line, colorsPerPixel, prevLine) {
-  		var result = [],
-  		    i = 0,
-  		    len = line.length,
-  		    left,
-  		    up,
-  		    upLeft,
-  		    paeth;
-
-  		result[0] = 4;
-
-  		for (; i < len; i++) {
-  			left = line[i - colorsPerPixel] || 0;
-  			up = prevLine && prevLine[i] || 0;
-  			upLeft = prevLine && prevLine[i - colorsPerPixel] || 0;
-  			paeth = paethPredictor(left, up, upLeft);
-  			result[i + 1] = line[i] - paeth + 0x0100 & 0xff;
-  		}
-
-  		return result;
-  	},
-  	    paethPredictor = function paethPredictor(left, up, upLeft) {
-
-  		var p = left + up - upLeft,
-  		    pLeft = Math.abs(p - left),
-  		    pUp = Math.abs(p - up),
-  		    pUpLeft = Math.abs(p - upLeft);
-
-  		return pLeft <= pUp && pLeft <= pUpLeft ? left : pUp <= pUpLeft ? up : upLeft;
-  	},
-  	    getFilterMethods = function getFilterMethods() {
-  		return [filterNone, filterSub, filterUp, filterAverage, filterPaeth];
-  	},
-  	    getIndexOfSmallestSum = function getIndexOfSmallestSum(arrays) {
-  		var i = 0,
-  		    len = arrays.length,
-  		    sum,
-  		    min,
-  		    ind;
-
-  		while (i < len) {
-  			sum = absSum(arrays[i].slice(1));
-
-  			if (sum < min || !min) {
-  				min = sum;
-  				ind = i;
-  			}
-
-  			i++;
-  		}
-
-  		return ind;
-  	},
-  	    absSum = function absSum(array) {
-  		var i = 0,
-  		    len = array.length,
-  		    sum = 0;
-
-  		while (i < len) {
-  			sum += Math.abs(array[i++]);
-  		}return sum;
-  	},
-  	    getPredictorFromCompression = function getPredictorFromCompression(compression) {
-  		var predictor;
-  		switch (compression) {
-  			case jsPDFAPI.image_compression.FAST:
-  				predictor = 11;
-  				break;
-
-  			case jsPDFAPI.image_compression.MEDIUM:
-  				predictor = 13;
-  				break;
-
-  			case jsPDFAPI.image_compression.SLOW:
-  				predictor = 14;
-  				break;
-
-  			default:
-  				predictor = 12;
-  				break;
-  		}
-  		return predictor;
-  	};
-
-  	jsPDFAPI.processPNG = function (imageData, imageIndex, alias, compression, dataAsBinaryString) {
-
-  		var colorSpace = this.color_spaces.DEVICE_RGB,
-  		    decode = this.decode.FLATE_DECODE,
-  		    bpc = 8,
-  		    img,
-  		    dp,
-  		    trns,
-  		    colors,
-  		    pal,
-  		    smask;
-
-  		/*	if(this.isString(imageData)) {
-    		}*/
-
-  		if (this.isArrayBuffer(imageData)) imageData = new Uint8Array(imageData);
-
-  		if (this.isArrayBufferView(imageData)) {
-
-  			if (doesNotHavePngJS()) throw new Error("PNG support requires png.js and zlib.js");
-
-  			img = new PNG(imageData);
-  			imageData = img.imgData;
-  			bpc = img.bits;
-  			colorSpace = img.colorSpace;
-  			colors = img.colors;
-
-  			//logImg(img);
-
-  			/*
-      * colorType 6 - Each pixel is an R,G,B triple, followed by an alpha sample.
-      *
-      * colorType 4 - Each pixel is a grayscale sample, followed by an alpha sample.
-      *
-      * Extract alpha to create two separate images, using the alpha as a sMask
-      */
-  			if ([4, 6].indexOf(img.colorType) !== -1) {
+      switch (options.baseline) {
+        case "bottom":
+          y -= descent;
+          break;
 
-  				/*
-       * processes 8 bit RGBA and grayscale + alpha images
-       */
-  				if (img.bits === 8) {
-
-  					var pixels = img.pixelBitlength == 32 ? new Uint32Array(img.decodePixels().buffer) : img.pixelBitlength == 16 ? new Uint16Array(img.decodePixels().buffer) : new Uint8Array(img.decodePixels().buffer),
-  					    len = pixels.length,
-  					    imgData = new Uint8Array(len * img.colors),
-  					    alphaData = new Uint8Array(len),
-  					    pDiff = img.pixelBitlength - img.bits,
-  					    i = 0,
-  					    n = 0,
-  					    pixel,
-  					    pbl;
-
-  					for (; i < len; i++) {
-  						pixel = pixels[i];
-  						pbl = 0;
-
-  						while (pbl < pDiff) {
-
-  							imgData[n++] = pixel >>> pbl & 0xff;
-  							pbl = pbl + img.bits;
-  						}
-
-  						alphaData[i] = pixel >>> pbl & 0xff;
-  					}
-  				}
-
-  				/*
-       * processes 16 bit RGBA and grayscale + alpha images
-       */
-  				if (img.bits === 16) {
+        case "top":
+          y += height - descent;
+          break;
 
-  					var pixels = new Uint32Array(img.decodePixels().buffer),
-  					    len = pixels.length,
-  					    imgData = new Uint8Array(len * (32 / img.pixelBitlength) * img.colors),
-  					    alphaData = new Uint8Array(len * (32 / img.pixelBitlength)),
-  					    hasColors = img.colors > 1,
-  					    i = 0,
-  					    n = 0,
-  					    a = 0,
-  					    pixel;
+        case "hanging":
+          y += height - 2 * descent;
+          break;
 
-  					while (i < len) {
-  						pixel = pixels[i++];
+        case "middle":
+          y += height / 2 - descent;
+          break;
+      } //multiline
 
-  						imgData[n++] = pixel >>> 0 & 0xFF;
 
-  						if (hasColors) {
-  							imgData[n++] = pixel >>> 16 & 0xFF;
+      maxWidth = options.maxWidth || 0;
 
-  							pixel = pixels[i++];
-  							imgData[n++] = pixel >>> 0 & 0xFF;
-  						}
+      if (maxWidth > 0) {
+        if (typeof text === "string") {
+          text = scope.splitTextToSize(text, maxWidth);
+        } else if (Object.prototype.toString.call(text) === "[object Array]") {
+          text = text.reduce(function (acc, textLine) {
+            return acc.concat(scope.splitTextToSize(textLine, maxWidth));
+          }, []);
+        }
+      } //creating Payload-Object to make text byRef
 
-  						alphaData[a++] = pixel >>> 16 & 0xFF;
-  					}
 
-  					bpc = 8;
-  				}
+      payload = {
+        text: text,
+        x: x,
+        y: y,
+        options: options,
+        mutex: {
+          pdfEscape: pdfEscape,
+          activeFontKey: activeFontKey,
+          fonts: fonts,
+          activeFontSize: activeFontSize
+        }
+      };
+      events.publish("preProcessText", payload);
+      text = payload.text;
+      options = payload.options; //angle
 
-  				if (canCompress(compression)) {
+      angle = options.angle;
 
-  					imageData = compressBytes(imgData, img.width * img.colors, img.colors, compression);
-  					smask = compressBytes(alphaData, img.width, 1, compression);
-  				} else {
+      if (transformationMatrix instanceof Matrix === false && angle && typeof angle === "number") {
+        angle *= Math.PI / 180;
 
-  					imageData = imgData;
-  					smask = alphaData;
-  					decode = null;
-  				}
-  			}
+        if (options.rotationDirection === 0) {
+          angle = -angle;
+        }
 
-  			/*
-      * Indexed png. Each pixel is a palette index.
-      */
-  			if (img.colorType === 3) {
+        if (apiMode === ApiMode.ADVANCED) {
+          angle = -angle;
+        }
 
-  				colorSpace = this.color_spaces.INDEXED;
-  				pal = img.palette;
+        var c = Math.cos(angle);
+        var s = Math.sin(angle);
+        transformationMatrix = new Matrix(c, s, -s, c, 0, 0);
+      } else if (angle && angle instanceof Matrix) {
+        transformationMatrix = angle;
+      }
 
-  				if (img.transparency.indexed) {
+      if (apiMode === ApiMode.ADVANCED && !transformationMatrix) {
+        transformationMatrix = identityMatrix;
+      } //charSpace
 
-  					var trans = img.transparency.indexed;
 
-  					var total = 0,
-  					    i = 0,
-  					    len = trans.length;
+      charSpace = options.charSpace || activeCharSpace;
 
-  					for (; i < len; ++i) {
-  						total += trans[i];
-  					}total = total / 255;
+      if (typeof charSpace !== "undefined") {
+        xtra += hpf(scale(charSpace)) + " Tc\n";
+        this.setCharSpace(this.getCharSpace() || 0);
+      }
 
-  					/*
-        * a single color is specified as 100% transparent (0),
-        * so we set trns to use a /Mask with that index
-        */
-  					if (total === len - 1 && trans.indexOf(0) !== -1) {
-  						trns = [trans.indexOf(0)];
+      horizontalScale = options.horizontalScale;
 
-  						/*
-         * there's more than one colour within the palette that specifies
-         * a transparency value less than 255, so we unroll the pixels to create an image sMask
-         */
-  					} else if (total !== len) {
+      if (typeof horizontalScale !== "undefined") {
+        xtra += hpf(horizontalScale * 100) + " Tz\n";
+      } //lang
 
-  						var pixels = img.decodePixels(),
-  						    alphaData = new Uint8Array(pixels.length),
-  						    i = 0,
-  						    len = pixels.length;
 
-  						for (; i < len; i++) {
-  							alphaData[i] = trans[pixels[i]];
-  						}smask = compressBytes(alphaData, img.width, 1);
-  					}
-  				}
-  			}
+      var lang = options.lang;
 
-  			var predictor = getPredictorFromCompression(compression);
 
-  			if (decode === this.decode.FLATE_DECODE) dp = '/Predictor ' + predictor + ' /Colors ' + colors + ' /BitsPerComponent ' + bpc + ' /Columns ' + img.width;else
-  				//remove 'Predictor' as it applies to the type of png filter applied to its IDAT - we only apply with compression
-  				dp = '/Colors ' + colors + ' /BitsPerComponent ' + bpc + ' /Columns ' + img.width;
+      var renderingMode = -1;
+      var parmRenderingMode = typeof options.renderingMode !== "undefined" ? options.renderingMode : options.stroke;
+      var pageContext = scope.internal.getCurrentPageInfo().pageContext;
 
-  			if (this.isArrayBuffer(imageData) || this.isArrayBufferView(imageData)) imageData = this.arrayBufferToBinaryString(imageData);
+      switch (parmRenderingMode) {
+        case 0:
+        case false:
+        case "fill":
+          renderingMode = 0;
+          break;
 
-  			if (smask && this.isArrayBuffer(smask) || this.isArrayBufferView(smask)) smask = this.arrayBufferToBinaryString(smask);
+        case 1:
+        case true:
+        case "stroke":
+          renderingMode = 1;
+          break;
 
-  			return this.createImageInfo(imageData, img.width, img.height, colorSpace, bpc, decode, imageIndex, alias, dp, trns, pal, smask, predictor);
-  		}
+        case 2:
+        case "fillThenStroke":
+          renderingMode = 2;
+          break;
 
-  		throw new Error("Unsupported PNG image data, try using JPEG instead.");
-  	};
-  })(jsPDF.API);
+        case 3:
+        case "invisible":
+          renderingMode = 3;
+          break;
 
-  /**
-   * jsPDF gif Support PlugIn
-   * Copyright (c) 2017 Aras Abbasi 
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
+        case 4:
+        case "fillAndAddForClipping":
+          renderingMode = 4;
+          break;
 
-  (function (jsPDFAPI) {
+        case 5:
+        case "strokeAndAddPathForClipping":
+          renderingMode = 5;
+          break;
 
-  	jsPDFAPI.processGIF89A = function (imageData, imageIndex, alias, compression, dataAsBinaryString) {
-  		var reader = new GifReader(imageData);
-  		var width = reader.width,
-  		    height = reader.height;
-  		var qu = 100;
-  		var pixels = [];
-
-  		reader.decodeAndBlitFrameRGBA(0, pixels);
-  		var rawImageData = {
-  			data: pixels,
-  			width: width,
-  			height: height
-  		};
-
-  		var encoder = new JPEGEncoder(qu);
-  		var data = encoder.encode(rawImageData, qu);
-  		return jsPDFAPI.processJPEG.call(this, data, imageIndex, alias, compression);
-  	};
-
-  	jsPDFAPI.processGIF87A = jsPDFAPI.processGIF89A;
-  })(jsPDF.API);
+        case 6:
+        case "fillThenStrokeAndAddToPathForClipping":
+          renderingMode = 6;
+          break;
 
-  /**
-   * jsPDF bmp Support PlugIn
-   * Copyright (c) 2018 Aras Abbasi 
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
+        case 7:
+        case "addToPathForClipping":
+          renderingMode = 7;
+          break;
+      }
 
-  (function (jsPDFAPI) {
+      var usedRenderingMode = typeof pageContext.usedRenderingMode !== "undefined" ? pageContext.usedRenderingMode : -1; //if the coder wrote it explicitly to use a specific
+      //renderingMode, then use it
 
-  	jsPDFAPI.processBMP = function (imageData, imageIndex, alias, compression, dataAsBinaryString) {
-  		var reader = new BmpDecoder(imageData, false);
-  		var width = reader.width,
-  		    height = reader.height;
-  		var qu = 100;
-  		var pixels = reader.getData();
-
-  		var rawImageData = {
-  			data: pixels,
-  			width: width,
-  			height: height
-  		};
-
-  		var encoder = new JPEGEncoder(qu);
-  		var data = encoder.encode(rawImageData, qu);
-  		return jsPDFAPI.processJPEG.call(this, data, imageIndex, alias, compression);
-  	};
-  })(jsPDF.API);
+      if (renderingMode !== -1) {
+        xtra += renderingMode + " Tr\n"; //otherwise check if we used the rendering Mode already
+        //if so then set the rendering Mode...
+      } else if (usedRenderingMode !== -1) {
+        xtra += "0 Tr\n";
+      }
 
-  /**
-   * jsPDF setLanguage Plugin
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
+      if (renderingMode !== -1) {
+        pageContext.usedRenderingMode = renderingMode;
+      } //align
+
+
+      align = options.align || "left";
+      var leading = activeFontSize * lineHeight;
+      var pageWidth = scope.internal.pageSize.getWidth();
+      var activeFont = fonts[activeFontKey];
+      charSpace = options.charSpace || activeCharSpace;
+      maxWidth = options.maxWidth || 0;
+      var lineWidths;
+      flags = Object.assign({
+        autoencode: true,
+        noBOM: true
+      }, options.flags);
+      var wordSpacingPerLine = [];
+
+      if (Object.prototype.toString.call(text) === "[object Array]") {
+        da = transformTextToSpecialArray(text);
+        var newY;
+
+        if (align !== "left") {
+          lineWidths = da.map(function (v) {
+            return scope.getStringUnitWidth(v, {
+              font: activeFont,
+              charSpace: charSpace,
+              fontSize: activeFontSize,
+              doKerning: false
+            }) * activeFontSize / scaleFactor;
+          });
+        } //The first line uses the "main" Td setting,
+        //and the subsequent lines are offset by the
+        //previous line's x coordinate.
 
-  (function (jsPDFAPI) {
 
-      /**
-      * Add Language Tag to PDF
-      *
-      * @returns {jsPDF}
-      * @name setLanguage
-      * @example
-      * var doc = new jsPDF()
-      * doc.text(10, 10, 'This is a test')
-      * doc.setLanguage("en-US")
-      * doc.save('english.pdf')
-      */
+        var prevWidth = 0;
+        var newX;
 
-      jsPDFAPI.setLanguage = function (langCode) {
-
-          var langCodes = {
-              "af": "Afrikaans",
-              "sq": "Albanian",
-              "ar": "Arabic (Standard)",
-              "ar-DZ": "Arabic (Algeria)",
-              "ar-BH": "Arabic (Bahrain)",
-              "ar-EG": "Arabic (Egypt)",
-              "ar-IQ": "Arabic (Iraq)",
-              "ar-JO": "Arabic (Jordan)",
-              "ar-KW": "Arabic (Kuwait)",
-              "ar-LB": "Arabic (Lebanon)",
-              "ar-LY": "Arabic (Libya)",
-              "ar-MA": "Arabic (Morocco)",
-              "ar-OM": "Arabic (Oman)",
-              "ar-QA": "Arabic (Qatar)",
-              "ar-SA": "Arabic (Saudi Arabia)",
-              "ar-SY": "Arabic (Syria)",
-              "ar-TN": "Arabic (Tunisia)",
-              "ar-AE": "Arabic (U.A.E.)",
-              "ar-YE": "Arabic (Yemen)",
-              "an": "Aragonese",
-              "hy": "Armenian",
-              "as": "Assamese",
-              "ast": "Asturian",
-              "az": "Azerbaijani",
-              "eu": "Basque",
-              "be": "Belarusian",
-              "bn": "Bengali",
-              "bs": "Bosnian",
-              "br": "Breton",
-              "bg": "Bulgarian",
-              "my": "Burmese",
-              "ca": "Catalan",
-              "ch": "Chamorro",
-              "ce": "Chechen",
-              "zh": "Chinese",
-              "zh-HK": "Chinese (Hong Kong)",
-              "zh-CN": "Chinese (PRC)",
-              "zh-SG": "Chinese (Singapore)",
-              "zh-TW": "Chinese (Taiwan)",
-              "cv": "Chuvash",
-              "co": "Corsican",
-              "cr": "Cree",
-              "hr": "Croatian",
-              "cs": "Czech",
-              "da": "Danish",
-              "nl": "Dutch (Standard)",
-              "nl-BE": "Dutch (Belgian)",
-              "en": "English",
-              "en-AU": "English (Australia)",
-              "en-BZ": "English (Belize)",
-              "en-CA": "English (Canada)",
-              "en-IE": "English (Ireland)",
-              "en-JM": "English (Jamaica)",
-              "en-NZ": "English (New Zealand)",
-              "en-PH": "English (Philippines)",
-              "en-ZA": "English (South Africa)",
-              "en-TT": "English (Trinidad & Tobago)",
-              "en-GB": "English (United Kingdom)",
-              "en-US": "English (United States)",
-              "en-ZW": "English (Zimbabwe)",
-              "eo": "Esperanto",
-              "et": "Estonian",
-              "fo": "Faeroese",
-              "fj": "Fijian",
-              "fi": "Finnish",
-              "fr": "French (Standard)",
-              "fr-BE": "French (Belgium)",
-              "fr-CA": "French (Canada)",
-              "fr-FR": "French (France)",
-              "fr-LU": "French (Luxembourg)",
-              "fr-MC": "French (Monaco)",
-              "fr-CH": "French (Switzerland)",
-              "fy": "Frisian",
-              "fur": "Friulian",
-              "gd": "Gaelic (Scots)",
-              "gd-IE": "Gaelic (Irish)",
-              "gl": "Galacian",
-              "ka": "Georgian",
-              "de": "German (Standard)",
-              "de-AT": "German (Austria)",
-              "de-DE": "German (Germany)",
-              "de-LI": "German (Liechtenstein)",
-              "de-LU": "German (Luxembourg)",
-              "de-CH": "German (Switzerland)",
-              "el": "Greek",
-              "gu": "Gujurati",
-              "ht": "Haitian",
-              "he": "Hebrew",
-              "hi": "Hindi",
-              "hu": "Hungarian",
-              "is": "Icelandic",
-              "id": "Indonesian",
-              "iu": "Inuktitut",
-              "ga": "Irish",
-              "it": "Italian (Standard)",
-              "it-CH": "Italian (Switzerland)",
-              "ja": "Japanese",
-              "kn": "Kannada",
-              "ks": "Kashmiri",
-              "kk": "Kazakh",
-              "km": "Khmer",
-              "ky": "Kirghiz",
-              "tlh": "Klingon",
-              "ko": "Korean",
-              "ko-KP": "Korean (North Korea)",
-              "ko-KR": "Korean (South Korea)",
-              "la": "Latin",
-              "lv": "Latvian",
-              "lt": "Lithuanian",
-              "lb": "Luxembourgish",
-              "mk": "FYRO Macedonian",
-              "ms": "Malay",
-              "ml": "Malayalam",
-              "mt": "Maltese",
-              "mi": "Maori",
-              "mr": "Marathi",
-              "mo": "Moldavian",
-              "nv": "Navajo",
-              "ng": "Ndonga",
-              "ne": "Nepali",
-              "no": "Norwegian",
-              "nb": "Norwegian (Bokmal)",
-              "nn": "Norwegian (Nynorsk)",
-              "oc": "Occitan",
-              "or": "Oriya",
-              "om": "Oromo",
-              "fa": "Persian",
-              "fa-IR": "Persian/Iran",
-              "pl": "Polish",
-              "pt": "Portuguese",
-              "pt-BR": "Portuguese (Brazil)",
-              "pa": "Punjabi",
-              "pa-IN": "Punjabi (India)",
-              "pa-PK": "Punjabi (Pakistan)",
-              "qu": "Quechua",
-              "rm": "Rhaeto-Romanic",
-              "ro": "Romanian",
-              "ro-MO": "Romanian (Moldavia)",
-              "ru": "Russian",
-              "ru-MO": "Russian (Moldavia)",
-              "sz": "Sami (Lappish)",
-              "sg": "Sango",
-              "sa": "Sanskrit",
-              "sc": "Sardinian",
-              "sd": "Sindhi",
-              "si": "Singhalese",
-              "sr": "Serbian",
-              "sk": "Slovak",
-              "sl": "Slovenian",
-              "so": "Somani",
-              "sb": "Sorbian",
-              "es": "Spanish",
-              "es-AR": "Spanish (Argentina)",
-              "es-BO": "Spanish (Bolivia)",
-              "es-CL": "Spanish (Chile)",
-              "es-CO": "Spanish (Colombia)",
-              "es-CR": "Spanish (Costa Rica)",
-              "es-DO": "Spanish (Dominican Republic)",
-              "es-EC": "Spanish (Ecuador)",
-              "es-SV": "Spanish (El Salvador)",
-              "es-GT": "Spanish (Guatemala)",
-              "es-HN": "Spanish (Honduras)",
-              "es-MX": "Spanish (Mexico)",
-              "es-NI": "Spanish (Nicaragua)",
-              "es-PA": "Spanish (Panama)",
-              "es-PY": "Spanish (Paraguay)",
-              "es-PE": "Spanish (Peru)",
-              "es-PR": "Spanish (Puerto Rico)",
-              "es-ES": "Spanish (Spain)",
-              "es-UY": "Spanish (Uruguay)",
-              "es-VE": "Spanish (Venezuela)",
-              "sx": "Sutu",
-              "sw": "Swahili",
-              "sv": "Swedish",
-              "sv-FI": "Swedish (Finland)",
-              "sv-SV": "Swedish (Sweden)",
-              "ta": "Tamil",
-              "tt": "Tatar",
-              "te": "Teluga",
-              "th": "Thai",
-              "tig": "Tigre",
-              "ts": "Tsonga",
-              "tn": "Tswana",
-              "tr": "Turkish",
-              "tk": "Turkmen",
-              "uk": "Ukrainian",
-              "hsb": "Upper Sorbian",
-              "ur": "Urdu",
-              "ve": "Venda",
-              "vi": "Vietnamese",
-              "vo": "Volapuk",
-              "wa": "Walloon",
-              "cy": "Welsh",
-              "xh": "Xhosa",
-              "ji": "Yiddish",
-              "zu": "Zulu"
-          };
+        if (align === "right") {
+          //The passed in x coordinate defines the
+          //rightmost point of the text.
+          x -= lineWidths[0];
+          text = [];
+          len = da.length;
+
+          for (var i = 0; i < len; i++) {
+            if (i === 0) {
+              newX = getHorizontalCoordinate(x);
+              newY = getVerticalCoordinate(y);
+            } else {
+              newX = scale(prevWidth - lineWidths[i]);
+              newY = -leading;
+            }
+
+            text.push([da[i], newX, newY]);
+            prevWidth = lineWidths[i];
+          }
+        } else if (align === "center") {
+          //The passed in x coordinate defines
+          //the center point.
+          x -= lineWidths[0] / 2;
+          text = [];
+          len = da.length;
+
+          for (var j = 0; j < len; j++) {
+            if (j === 0) {
+              newX = getHorizontalCoordinate(x);
+              newY = getVerticalCoordinate(y);
+            } else {
+              newX = scale((prevWidth - lineWidths[j]) / 2);
+              newY = -leading;
+            }
 
-          if (this.internal.languageSettings === undefined) {
-              this.internal.languageSettings = {};
-              this.internal.languageSettings.isSubscribed = false;
+            text.push([da[j], newX, newY]);
+            prevWidth = lineWidths[j];
           }
+        } else if (align === "left") {
+          text = [];
+          len = da.length;
 
-          if (langCodes[langCode] !== undefined) {
-              this.internal.languageSettings.languageCode = langCode;
-              if (this.internal.languageSettings.isSubscribed === false) {
-                  this.internal.events.subscribe("putCatalog", function () {
-                      this.internal.write("/Lang (" + this.internal.languageSettings.languageCode + ")");
-                  });
-                  this.internal.languageSettings.isSubscribed = true;
-              }
+          for (var h = 0; h < len; h++) {
+            text.push(da[h]);
           }
-          return this;
-      };
-  })(jsPDF.API);
+        } else if (align === "justify") {
+          text = [];
+          len = da.length;
+          maxWidth = maxWidth !== 0 ? maxWidth : pageWidth;
 
-  /** @preserve
-   * jsPDF split_text_to_size plugin - MIT license.
-   * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
-   *               2014 Diego Casorran, https://github.com/diegocr
-   */
-  /**
-   * 
-   * ====================================================================
-   */
+          for (var l = 0; l < len; l++) {
+            newY = l === 0 ? getVerticalCoordinate(y) : -leading;
+            newX = l === 0 ? getHorizontalCoordinate(x) : 0;
 
-  (function (API) {
-    /**
-     * Returns an array of length matching length of the 'word' string, with each
-     * cell occupied by the width of the char in that position.
-     * 
-     * @function
-     * @param word {String}
-     * @param widths {Object}
-     * @param kerning {Object}
-     * @returns {Array}
-     */
+            if (l < len - 1) {
+              wordSpacingPerLine.push(hpf(scale((maxWidth - lineWidths[l]) / (da[l].split(" ").length - 1))));
+            } else {
+              wordSpacingPerLine.push(0);
+            }
 
-    var getCharWidthsArray = API.getCharWidthsArray = function (text, options) {
-      options = options || {};
+            text.push([da[l], newX, newY]);
+          }
+        } else {
+          throw new Error('Unrecognized alignment option, use "left", "center", "right" or "justify".');
+        }
+      } //R2L
 
-      var activeFont = options.font || this.internal.getFont();
-      var fontSize = options.fontSize || this.internal.getFontSize();
-      var charSpace = options.charSpace || this.internal.getCharSpace();
 
-      var widths = options.widths ? options.widths : activeFont.metadata.Unicode.widths;
-      var widthsFractionOf = widths.fof ? widths.fof : 1;
-      var kerning = options.kerning ? options.kerning : activeFont.metadata.Unicode.kerning;
-      var kerningFractionOf = kerning.fof ? kerning.fof : 1;
+      var doReversing = typeof options.R2L === "boolean" ? options.R2L : R2L;
 
-      var i;
-      var l;
-      var char_code;
-      var prior_char_code = 0; //for kerning
-      var default_char_width = widths[0] || widthsFractionOf;
-      var output = [];
+      if (doReversing === true) {
+        text = processTextByFunction(text, function (text, posX, posY) {
+          return [text.split("").reverse().join(""), posX, posY];
+        });
+      } //creating Payload-Object to make text byRef
 
-      for (i = 0, l = text.length; i < l; i++) {
-        char_code = text.charCodeAt(i);
 
-        if (typeof activeFont.metadata.widthOfString === "function") {
-          output.push((activeFont.metadata.widthOfGlyph(activeFont.metadata.characterToGlyph(char_code)) + charSpace * (1000 / fontSize) || 0) / 1000);
-        } else {
-          output.push((widths[char_code] || default_char_width) / widthsFractionOf + (kerning[char_code] && kerning[char_code][prior_char_code] || 0) / kerningFractionOf);
+      payload = {
+        text: text,
+        x: x,
+        y: y,
+        options: options,
+        mutex: {
+          pdfEscape: pdfEscape,
+          activeFontKey: activeFontKey,
+          fonts: fonts,
+          activeFontSize: activeFontSize
         }
-        prior_char_code = char_code;
-      }
+      };
+      events.publish("postProcessText", payload);
+      text = payload.text;
+      isHex = payload.mutex.isHex || false; //Escaping
 
-      return output;
-    };
+      var activeFontEncoding = fonts[activeFontKey].encoding;
 
-    /**
-     * Calculate the sum of a number-array
-     * 
-     * @name getArraySum
-     * @public
-     * @function
-     * @param {array} array of numbers
-     * @returns {Number}
-     */
-    var getArraySum = API.getArraySum = function (array) {
-      var i = array.length,
-          output = 0;
-      while (i) {
-        i--;
-        output += array[i];
+      if (activeFontEncoding === "WinAnsiEncoding" || activeFontEncoding === "StandardEncoding") {
+        text = processTextByFunction(text, function (text, posX, posY) {
+          return [ESC(text), posX, posY];
+        });
       }
-      return output;
-    };
-    /**
-    Returns a widths of string in a given font, if the font size is set as 1 point.
-     In other words, this is "proportional" value. For 1 unit of font size, the length
-    of the string will be that much.
-     Multiply by font size to get actual width in *points*
-    Then divide by 72 to get inches or divide by (72/25.6) to get 'mm' etc.
-     @public
-    @function
-    @param
-    @returns {Type}
-    */
-    var getStringUnitWidth = API.getStringUnitWidth = function (text, options) {
-      options = options || {};
 
-      var fontSize = options.fontSize || this.internal.getFontSize();
-      var font = options.font || this.internal.getFont();
-      var charSpace = options.charSpace || this.internal.getCharSpace();
-      var result = 0;
-      if (typeof font.metadata.widthOfString === "function") {
-        result = font.metadata.widthOfString(text, fontSize, charSpace) / fontSize;
-      } else {
-        result = getArraySum(getCharWidthsArray.apply(this, arguments));
-      }
-      return result;
-    };
-
-    /**
-    returns array of lines
-    */
-    var splitLongWord = function splitLongWord(word, widths_array, firstLineMaxLen, maxLen) {
-      var answer = [];
+      da = transformTextToSpecialArray(text);
+      text = [];
+      var STRING = 0;
+      var ARRAY = 1;
+      var variant = Array.isArray(da[0]) ? ARRAY : STRING;
+      var posX;
+      var posY;
+      var content;
+      var wordSpacing = "";
+
+      var generatePosition = function generatePosition(parmPosX, parmPosY, parmTransformationMatrix) {
+        var position = "";
+
+        if (parmTransformationMatrix instanceof Matrix) {
+          // It is kind of more intuitive to apply a plain rotation around the text anchor set by x and y
+          // but when the user supplies an arbitrary transformation matrix, the x and y offsets should be applied
+          // in the coordinate system established by this matrix
+          if (typeof options.angle === "number") {
+            parmTransformationMatrix = matrixMult(parmTransformationMatrix, new Matrix(1, 0, 0, 1, parmPosX, parmPosY));
+          } else {
+            parmTransformationMatrix = matrixMult(new Matrix(1, 0, 0, 1, parmPosX, parmPosY), parmTransformationMatrix);
+          }
 
-      // 1st, chop off the piece that can fit on the hanging line.
-      var i = 0,
-          l = word.length,
-          workingLen = 0;
-      while (i !== l && workingLen + widths_array[i] < firstLineMaxLen) {
-        workingLen += widths_array[i];
-        i++;
-      }
-      // this is first line.
-      answer.push(word.slice(0, i));
+          if (apiMode === ApiMode.ADVANCED) {
+            parmTransformationMatrix = matrixMult(new Matrix(1, 0, 0, -1, 0, 0), parmTransformationMatrix);
+          }
 
-      // 2nd. Split the rest into maxLen pieces.
-      var startOfLine = i;
-      workingLen = 0;
-      while (i !== l) {
-        if (workingLen + widths_array[i] > maxLen) {
-          answer.push(word.slice(startOfLine, i));
-          workingLen = 0;
-          startOfLine = i;
+          position = parmTransformationMatrix.join(" ") + " Tm\n";
+        } else {
+          position = hpf(parmPosX) + " " + hpf(parmPosY) + " Td\n";
         }
-        workingLen += widths_array[i];
-        i++;
-      }
-      if (startOfLine !== i) {
-        answer.push(word.slice(startOfLine, i));
-      }
 
-      return answer;
-    };
-
-    // Note, all sizing inputs for this function must be in "font measurement units"
-    // By default, for PDF, it's "point".
-    var splitParagraphIntoLines = function splitParagraphIntoLines(text, maxlen, options) {
-      // at this time works only on Western scripts, ones with space char
-      // separating the words. Feel free to expand.
+        return position;
+      };
 
-      if (!options) {
-        options = {};
-      }
+      for (var lineIndex = 0; lineIndex < da.length; lineIndex++) {
+        wordSpacing = "";
 
-      var line = [],
-          lines = [line],
-          line_length = options.textIndent || 0,
-          separator_length = 0,
-          current_word_length = 0,
-          word,
-          widths_array,
-          words = text.split(' '),
-          spaceCharWidth = getCharWidthsArray.apply(this, [' ', options])[0],
-          i,
-          l,
-          tmp,
-          lineIndent;
+        switch (variant) {
+          case ARRAY:
+            content = (isHex ? "<" : "(") + da[lineIndex][0] + (isHex ? ">" : ")");
+            posX = parseFloat(da[lineIndex][1]);
+            posY = parseFloat(da[lineIndex][2]);
+            break;
 
-      if (options.lineIndent === -1) {
-        lineIndent = words[0].length + 2;
-      } else {
-        lineIndent = options.lineIndent || 0;
-      }
-      if (lineIndent) {
-        var pad = Array(lineIndent).join(" "),
-            wrds = [];
-        words.map(function (wrd) {
-          wrd = wrd.split(/\s*\n/);
-          if (wrd.length > 1) {
-            wrds = wrds.concat(wrd.map(function (wrd, idx) {
-              return (idx && wrd.length ? "\n" : "") + wrd;
-            }));
-          } else {
-            wrds.push(wrd[0]);
-          }
-        });
-        words = wrds;
-        lineIndent = getStringUnitWidth.apply(this, [pad, options]);
-      }
+          case STRING:
+            content = (isHex ? "<" : "(") + da[lineIndex] + (isHex ? ">" : ")");
+            posX = getHorizontalCoordinate(x);
+            posY = getVerticalCoordinate(y);
+            break;
+        }
 
-      for (i = 0, l = words.length; i < l; i++) {
-        var force = 0;
+        if (typeof wordSpacingPerLine !== "undefined" && typeof wordSpacingPerLine[lineIndex] !== "undefined") {
+          wordSpacing = wordSpacingPerLine[lineIndex] + " Tw\n";
+        }
 
-        word = words[i];
-        if (lineIndent && word[0] == "\n") {
-          word = word.substr(1);
-          force = 1;
+        if (lineIndex === 0) {
+          text.push(wordSpacing + generatePosition(posX, posY, transformationMatrix) + content);
+        } else if (variant === STRING) {
+          text.push(wordSpacing + content);
+        } else if (variant === ARRAY) {
+          text.push(wordSpacing + generatePosition(posX, posY, transformationMatrix) + content);
         }
-        widths_array = getCharWidthsArray.apply(this, [word, options]);
-        current_word_length = getArraySum(widths_array);
+      }
 
-        if (line_length + separator_length + current_word_length > maxlen || force) {
-          if (current_word_length > maxlen) {
-            // this happens when you have space-less long URLs for example.
-            // we just chop these to size. We do NOT insert hiphens
-            tmp = splitLongWord.apply(this, [word, widths_array, maxlen - (line_length + separator_length), maxlen]);
-            // first line we add to existing line object
-            line.push(tmp.shift()); // it's ok to have extra space indicator there
-            // last line we make into new line object
-            line = [tmp.pop()];
-            // lines in the middle we apped to lines object as whole lines
-            while (tmp.length) {
-              lines.push([tmp.shift()]); // single fragment occupies whole line
-            }
-            current_word_length = getArraySum(widths_array.slice(word.length - (line[0] ? line[0].length : 0)));
-          } else {
-            // just put it on a new line
-            line = [word];
-          }
+      text = variant === STRING ? text.join(" Tj\nT* ") : text.join(" Tj\n");
+      text += " Tj\n";
+      var result = "BT\n/";
+      result += activeFontKey + " " + activeFontSize + " Tf\n"; // font face, style, size
+
+      result += hpf(activeFontSize * lineHeight) + " TL\n"; // line spacing
+
+      result += textColor + "\n";
+      result += xtra;
+      result += text;
+      result += "ET";
+      out(result);
+      usedFonts[activeFontKey] = true;
+      return scope;
+    }; // PDF supports these path painting and clip path operators:
+    //
+    // S - stroke
+    // s - close/stroke
+    // f (F) - fill non-zero
+    // f* - fill evenodd
+    // B - fill stroke nonzero
+    // B* - fill stroke evenodd
+    // b - close fill stroke nonzero
+    // b* - close fill stroke evenodd
+    // n - nothing (consume path)
+    // W - clip nonzero
+    // W* - clip evenodd
+    //
+    // In order to keep the API small, we omit the close-and-fill/stroke operators and provide a separate close()
+    // method.
 
-          // now we attach new line to lines
-          lines.push(line);
-          line_length = current_word_length + lineIndent;
-          separator_length = spaceCharWidth;
-        } else {
-          line.push(word);
+    /**
+     *
+     * @name clip
+     * @function
+     * @instance
+     * @param {string} rule Only possible value is 'evenodd'
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @description All .clip() after calling drawing ops with a style argument of null.
+     */
 
-          line_length += separator_length + current_word_length;
-          separator_length = spaceCharWidth;
-        }
-      }
 
-      if (lineIndent) {
-        var postProcess = function postProcess(ln, idx) {
-          return (idx ? pad : '') + ln.join(" ");
-        };
+    var clip = API.__private__.clip = API.clip = function (rule) {
+      // Call .clip() after calling drawing ops with a style argument of null
+      // W is the PDF clipping op
+      if ("evenodd" === rule) {
+        out("W*");
       } else {
-        var postProcess = function postProcess(ln) {
-          return ln.join(" ");
-        };
+        out("W");
       }
 
-      return lines.map(postProcess);
+      return this;
     };
-
     /**
-    Splits a given string into an array of strings. Uses 'size' value
-    (in measurement units declared as default for the jsPDF instance)
-    and the font's "widths" and "Kerning" tables, where available, to
-    determine display length of a given string for a given font.
-     We use character's 100% of unit size (height) as width when Width
-    table or other default width is not available.
-     @public
-    @function
-    @param text {String} Unencoded, regular JavaScript (Unicode, UTF-16 / UCS-2) string.
-    @param size {Number} Nominal number, measured in units default to this instance of jsPDF.
-    @param options {Object} Optional flags needed for chopper to do the right thing.
-    @returns {Array} with strings chopped to size.
-    */
-    API.splitTextToSize = function (text, maxlen, options) {
+     * @name clipEvenOdd
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @description Modify the current clip path by intersecting it with the current path using the even-odd rule. Note
+     * that this will NOT consume the current path. In order to only use this path for clipping call
+     * {@link API.discardPath} afterwards.
+     */
 
-      options = options || {};
 
-      var fsize = options.fontSize || this.internal.getFontSize(),
-          newOptions = function (options) {
-        var widths = {
-          0: 1
-        },
-            kerning = {};
+    API.clipEvenOdd = function () {
+      return clip("evenodd");
+    };
+    /**
+     * Consumes the current path without any effect. Mainly used in combination with {@link clip} or
+     * {@link clipEvenOdd}. The PDF "n" operator.
+     * @name discardPath
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     */
 
-        if (!options.widths || !options.kerning) {
-          var f = this.internal.getFont(options.fontName, options.fontStyle),
-              encoding = 'Unicode';
-          // NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE
-          // Actual JavaScript-native String's 16bit char codes used.
-          // no multi-byte logic here
 
-          if (f.metadata[encoding]) {
-            return {
-              widths: f.metadata[encoding].widths || widths,
-              kerning: f.metadata[encoding].kerning || kerning
-            };
-          } else {
-            return {
-              font: f.metadata,
-              fontSize: this.internal.getFontSize(),
-              charSpace: this.internal.getCharSpace()
-            };
-          }
-        } else {
-          return {
-            widths: options.widths,
-            kerning: options.kerning
-          };
-        }
+    API.__private__.discardPath = API.discardPath = function () {
+      out("n");
+      return this;
+    };
 
-        // then use default values
-        return {
-          widths: widths,
-          kerning: kerning
-        };
-      }.call(this, options);
+    var isValidStyle = API.__private__.isValidStyle = function (style) {
+      var validStyleVariants = [undefined, null, "S", "D", "F", "DF", "FD", "f", "f*", "B", "B*", "n"];
+      var result = false;
 
-      // first we split on end-of-line chars
-      var paragraphs;
-      if (Array.isArray(text)) {
-        paragraphs = text;
-      } else {
-        paragraphs = text.split(/\r?\n/);
+      if (validStyleVariants.indexOf(style) !== -1) {
+        result = true;
       }
 
-      // now we convert size (max length of line) into "font size units"
-      // at present time, the "font size unit" is always 'point'
-      // 'proportional' means, "in proportion to font size"
-      var fontUnit_maxLen = 1.0 * this.internal.scaleFactor * maxlen / fsize;
-      // at this time, fsize is always in "points" regardless of the default measurement unit of the doc.
-      // this may change in the future?
-      // until then, proportional_maxlen is likely to be in 'points'
-
-      // If first line is to be indented (shorter or longer) than maxLen
-      // we indicate that by using CSS-style "text-indent" option.
-      // here it's in font units too (which is likely 'points')
-      // it can be negative (which makes the first line longer than maxLen)
-      newOptions.textIndent = options.textIndent ? options.textIndent * 1.0 * this.internal.scaleFactor / fsize : 0;
-      newOptions.lineIndent = options.lineIndent;
+      return result;
+    };
 
-      var i,
-          l,
-          output = [];
-      for (i = 0, l = paragraphs.length; i < l; i++) {
-        output = output.concat(splitParagraphIntoLines.apply(this, [paragraphs[i], fontUnit_maxLen, newOptions]));
+    API.__private__.setDefaultPathOperation = API.setDefaultPathOperation = function (operator) {
+      if (isValidStyle(operator)) {
+        defaultPathOperation = operator;
       }
 
-      return output;
+      return this;
     };
-  })(jsPDF.API);
 
-  /** @preserve 
-  jsPDF standard_fonts_metrics plugin
-  Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
-  MIT license.
-  */
-  (function (API) {
+    var getStyle = API.__private__.getStyle = API.getStyle = function (style) {
+      // see path-painting operators in PDF spec
+      var op = defaultPathOperation; // stroke
 
-  	/*
-   # reference (Python) versions of 'compress' and 'uncompress'
-   # only 'uncompress' function is featured lower as JavaScript
-   # if you want to unit test "roundtrip", just transcribe the reference
-   # 'compress' function from Python into JavaScript
-   
-   def compress(data):
-   
-   	keys =   '0123456789abcdef'
-   	values = 'klmnopqrstuvwxyz'
-   	mapping = dict(zip(keys, values))
-   	vals = []
-   	for key in data.keys():
-   		value = data[key]
-   		try:
-   			keystring = hex(key)[2:]
-   			keystring = keystring[:-1] + mapping[keystring[-1:]]
-   		except:
-   			keystring = key.join(["'","'"])
-   			#print('Keystring is %s' % keystring)
-   
-   		try:
-   			if value < 0:
-   				valuestring = hex(value)[3:]
-   				numberprefix = '-'
-   			else:
-   				valuestring = hex(value)[2:]
-   				numberprefix = ''
-   			valuestring = numberprefix + valuestring[:-1] + mapping[valuestring[-1:]]
-   		except:
-   			if type(value) == dict:
-   				valuestring = compress(value)
-   			else:
-   				raise Exception("Don't know what to do with value type %s" % type(value))
-   
-   		vals.append(keystring+valuestring)
-   	
-   	return '{' + ''.join(vals) + '}'
-   
-   def uncompress(data):
-   
-   	decoded = '0123456789abcdef'
-   	encoded = 'klmnopqrstuvwxyz'
-   	mapping = dict(zip(encoded, decoded))
-   
-   	sign = +1
-   	stringmode = False
-   	stringparts = []
-   
-   	output = {}
-   
-   	activeobject = output
-   	parentchain = []
-   
-   	keyparts = ''
-   	valueparts = ''
-   
-   	key = None
-   
-   	ending = set(encoded)
-   
-   	i = 1
-   	l = len(data) - 1 # stripping starting, ending {}
-   	while i != l: # stripping {}
-   		# -, {, }, ' are special.
-   
-   		ch = data[i]
-   		i += 1
-   
-   		if ch == "'":
-   			if stringmode:
-   				# end of string mode
-   				stringmode = False
-   				key = ''.join(stringparts)
-   			else:
-   				# start of string mode
-   				stringmode = True
-   				stringparts = []
-   		elif stringmode == True:
-   			#print("Adding %s to stringpart" % ch)
-   			stringparts.append(ch)
-   
-   		elif ch == '{':
-   			# start of object
-   			parentchain.append( [activeobject, key] )
-   			activeobject = {}
-   			key = None
-   			#DEBUG = True
-   		elif ch == '}':
-   			# end of object
-   			parent, key = parentchain.pop()
-   			parent[key] = activeobject
-   			key = None
-   			activeobject = parent
-   			#DEBUG = False
-   
-   		elif ch == '-':
-   			sign = -1
-   		else:
-   			# must be number
-   			if key == None:
-   				#debug("In Key. It is '%s', ch is '%s'" % (keyparts, ch))
-   				if ch in ending:
-   					#debug("End of key")
-   					keyparts += mapping[ch]
-   					key = int(keyparts, 16) * sign
-   					sign = +1
-   					keyparts = ''
-   				else:
-   					keyparts += ch
-   			else:
-   				#debug("In value. It is '%s', ch is '%s'" % (valueparts, ch))
-   				if ch in ending:
-   					#debug("End of value")
-   					valueparts += mapping[ch]
-   					activeobject[key] = int(valueparts, 16) * sign
-   					sign = +1
-   					key = None
-   					valueparts = ''
-   				else:
-   					valueparts += ch
-   
-   			#debug(activeobject)
-   
-   	return output
-   
-   */
+      switch (style) {
+        case "D":
+        case "S":
+          op = "S"; // stroke
 
-  	/**
-   Uncompresses data compressed into custom, base16-like format. 
-   @public
-   @function
-   @param
-   @returns {Type}
-   */
+          break;
 
-  	var uncompress = function uncompress(data) {
-
-  		var decoded = '0123456789abcdef',
-  		    encoded = 'klmnopqrstuvwxyz',
-  		    mapping = {};
-
-  		for (var i = 0; i < encoded.length; i++) {
-  			mapping[encoded[i]] = decoded[i];
-  		}
-
-  		var undef,
-  		    output = {},
-  		    sign = 1,
-  		    stringparts // undef. will be [] in string mode
-
-  		,
-  		    activeobject = output,
-  		    parentchain = [],
-  		    parent_key_pair,
-  		    keyparts = '',
-  		    valueparts = '',
-  		    key // undef. will be Truthy when Key is resolved.
-  		,
-  		    datalen = data.length - 1 // stripping ending }
-  		,
-  		    ch;
-
-  		i = 1; // stripping starting {
-
-  		while (i != datalen) {
-  			// - { } ' are special.
-
-  			ch = data[i];
-  			i += 1;
-
-  			if (ch == "'") {
-  				if (stringparts) {
-  					// end of string mode
-  					key = stringparts.join('');
-  					stringparts = undef;
-  				} else {
-  					// start of string mode
-  					stringparts = [];
-  				}
-  			} else if (stringparts) {
-  				stringparts.push(ch);
-  			} else if (ch == '{') {
-  				// start of object
-  				parentchain.push([activeobject, key]);
-  				activeobject = {};
-  				key = undef;
-  			} else if (ch == '}') {
-  				// end of object
-  				parent_key_pair = parentchain.pop();
-  				parent_key_pair[0][parent_key_pair[1]] = activeobject;
-  				key = undef;
-  				activeobject = parent_key_pair[0];
-  			} else if (ch == '-') {
-  				sign = -1;
-  			} else {
-  				// must be number
-  				if (key === undef) {
-  					if (mapping.hasOwnProperty(ch)) {
-  						keyparts += mapping[ch];
-  						key = parseInt(keyparts, 16) * sign;
-  						sign = +1;
-  						keyparts = '';
-  					} else {
-  						keyparts += ch;
-  					}
-  				} else {
-  					if (mapping.hasOwnProperty(ch)) {
-  						valueparts += mapping[ch];
-  						activeobject[key] = parseInt(valueparts, 16) * sign;
-  						sign = +1;
-  						key = undef;
-  						valueparts = '';
-  					} else {
-  						valueparts += ch;
-  					}
-  				}
-  			}
-  		} // end while
-
-  		return output;
-  	};
-
-  	// encoding = 'Unicode' 
-  	// NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE. NO clever BOM behavior
-  	// Actual 16bit char codes used.
-  	// no multi-byte logic here
-
-  	// Unicode characters to WinAnsiEncoding:
-  	// {402: 131, 8211: 150, 8212: 151, 8216: 145, 8217: 146, 8218: 130, 8220: 147, 8221: 148, 8222: 132, 8224: 134, 8225: 135, 8226: 149, 8230: 133, 8364: 128, 8240:137, 8249: 139, 8250: 155, 710: 136, 8482: 153, 338: 140, 339: 156, 732: 152, 352: 138, 353: 154, 376: 159, 381: 142, 382: 158}
-  	// as you can see, all Unicode chars are outside of 0-255 range. No char code conflicts.
-  	// this means that you can give Win cp1252 encoded strings to jsPDF for rendering directly
-  	// as well as give strings with some (supported by these fonts) Unicode characters and 
-  	// these will be mapped to win cp1252 
-  	// for example, you can send char code (cp1252) 0x80 or (unicode) 0x20AC, getting "Euro" glyph displayed in both cases.
-
-  	var encodingBlock = {
-  		'codePages': ['WinAnsiEncoding'],
-  		'WinAnsiEncoding': uncompress("{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}")
-  	},
-  	    encodings = { 'Unicode': {
-  			'Courier': encodingBlock,
-  			'Courier-Bold': encodingBlock,
-  			'Courier-BoldOblique': encodingBlock,
-  			'Courier-Oblique': encodingBlock,
-  			'Helvetica': encodingBlock,
-  			'Helvetica-Bold': encodingBlock,
-  			'Helvetica-BoldOblique': encodingBlock,
-  			'Helvetica-Oblique': encodingBlock,
-  			'Times-Roman': encodingBlock,
-  			'Times-Bold': encodingBlock,
-  			'Times-BoldItalic': encodingBlock,
-  			'Times-Italic': encodingBlock
-  			//	, 'Symbol'
-  			//	, 'ZapfDingbats'
-  		}
-  		/** 
-    Resources:
-    Font metrics data is reprocessed derivative of contents of
-    "Font Metrics for PDF Core 14 Fonts" package, which exhibits the following copyright and license:
-    
-    Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
-    
-    This file and the 14 PostScript(R) AFM files it accompanies may be used,
-    copied, and distributed for any purpose and without charge, with or without
-    modification, provided that all copyright notices are retained; that the AFM
-    files are not distributed without this file; that all modifications to this
-    file or any of the AFM files are prominently noted in the modified file(s);
-    and that this paragraph is not modified. Adobe Systems has no responsibility
-    or obligation to support the use of the AFM files.
-    
-    */
-  	},
-  	    fontMetrics = { 'Unicode': {
-  			// all sizing numbers are n/fontMetricsFractionOf = one font size unit
-  			// this means that if fontMetricsFractionOf = 1000, and letter A's width is 476, it's
-  			// width is 476/1000 or 47.6% of its height (regardless of font size)
-  			// At this time this value applies to "widths" and "kerning" numbers.
-
-  			// char code 0 represents "default" (average) width - use it for chars missing in this table.
-  			// key 'fof' represents the "fontMetricsFractionOf" value
-
-  			'Courier-Oblique': uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
-  			'Times-BoldItalic': uncompress("{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'kerning'{cl{4qu5kt5qt5rs17ss5ts}201s{201ss}201t{cks4lscmscnscoscpscls2wu2yu201ts}201x{2wu2yu}2k{201ts}2w{4qx5kx5ou5qx5rs17su5tu}2x{17su5tu5ou}2y{4qx5kx5ou5qx5rs17ss5ts}'fof'-6ofn{17sw5tw5ou5qw5rs}7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qs}3v{17su5tu5os5qs}7p{17su5tu}ck{4qu5kt5qt5rs17ss5ts}4l{4qu5kt5qt5rs17ss5ts}cm{4qu5kt5qt5rs17ss5ts}cn{4qu5kt5qt5rs17ss5ts}co{4qu5kt5qt5rs17ss5ts}cp{4qu5kt5qt5rs17ss5ts}6l{4qu5ou5qw5rt17su5tu}5q{ckuclucmucnucoucpu4lu}5r{ckuclucmucnucoucpu4lu}7q{cksclscmscnscoscps4ls}6p{4qu5ou5qw5rt17sw5tw}ek{4qu5ou5qw5rt17su5tu}el{4qu5ou5qw5rt17su5tu}em{4qu5ou5qw5rt17su5tu}en{4qu5ou5qw5rt17su5tu}eo{4qu5ou5qw5rt17su5tu}ep{4qu5ou5qw5rt17su5tu}es{17ss5ts5qs4qu}et{4qu5ou5qw5rt17sw5tw}eu{4qu5ou5qw5rt17ss5ts}ev{17ss5ts5qs4qu}6z{17sw5tw5ou5qw5rs}fm{17sw5tw5ou5qw5rs}7n{201ts}fo{17sw5tw5ou5qw5rs}fp{17sw5tw5ou5qw5rs}fq{17sw5tw5ou5qw5rs}7r{cksclscmscnscoscps4ls}fs{17sw5tw5ou5qw5rs}ft{17su5tu}fu{17su5tu}fv{17su5tu}fw{17su5tu}fz{cksclscmscnscoscps4ls}}}"),
-  			'Helvetica-Bold': uncompress("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),
-  			'Courier': uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
-  			'Courier-BoldOblique': uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
-  			'Times-Bold': uncompress("{'widths'{k3q2q5ncx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2l202m2n2n3m2o3m2p6o202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5x4l4s4m4m4n4s4o4s4p4m4q3x4r4y4s4y4t2r4u3m4v4y4w4m4x5y4y4s4z4y5k3x5l4y5m4s5n3r5o4m5p4s5q4s5r6o5s4s5t4s5u4m5v2l5w1w5x2l5y3u5z3m6k2l6l3m6m3r6n2w6o3r6p2w6q2l6r3m6s3r6t1w6u2l6v3r6w1w6x5n6y3r6z3m7k3r7l3r7m2w7n2r7o2l7p3r7q3m7r4s7s3m7t3m7u2w7v2r7w1q7x2r7y3o202l3mcl4sal2lam3man3mao3map3mar3mas2lat4uau1yav3maw3tay4uaz2lbk2sbl3t'fof'6obo2lbp3rbr1tbs2lbu2lbv3mbz3mck4s202k3mcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3rek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3m3u2l17s4s19m3m}'kerning'{cl{4qt5ks5ot5qy5rw17sv5tv}201t{cks4lscmscnscoscpscls4wv}2k{201ts}2w{4qu5ku7mu5os5qx5ru17su5tu}2x{17su5tu5ou5qs}2y{4qv5kv7mu5ot5qz5ru17su5tu}'fof'-6o7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qu}3v{17su5tu5os5qu}fu{17su5tu5ou5qu}7p{17su5tu5ou5qu}ck{4qt5ks5ot5qy5rw17sv5tv}4l{4qt5ks5ot5qy5rw17sv5tv}cm{4qt5ks5ot5qy5rw17sv5tv}cn{4qt5ks5ot5qy5rw17sv5tv}co{4qt5ks5ot5qy5rw17sv5tv}cp{4qt5ks5ot5qy5rw17sv5tv}6l{17st5tt5ou5qu}17s{ckuclucmucnucoucpu4lu4wu}5o{ckuclucmucnucoucpu4lu4wu}5q{ckzclzcmzcnzcozcpz4lz4wu}5r{ckxclxcmxcnxcoxcpx4lx4wu}5t{ckuclucmucnucoucpu4lu4wu}7q{ckuclucmucnucoucpu4lu}6p{17sw5tw5ou5qu}ek{17st5tt5qu}el{17st5tt5ou5qu}em{17st5tt5qu}en{17st5tt5qu}eo{17st5tt5qu}ep{17st5tt5ou5qu}es{17ss5ts5qu}et{17sw5tw5ou5qu}eu{17sw5tw5ou5qu}ev{17ss5ts5qu}6z{17sw5tw5ou5qu5rs}fm{17sw5tw5ou5qu5rs}fn{17sw5tw5ou5qu5rs}fo{17sw5tw5ou5qu5rs}fp{17sw5tw5ou5qu5rs}fq{17sw5tw5ou5qu5rs}7r{cktcltcmtcntcotcpt4lt5os}fs{17sw5tw5ou5qu5rs}ft{17su5tu5ou5qu}7m{5os}fv{17su5tu5ou5qu}fw{17su5tu5ou5qu}fz{cksclscmscnscoscps4ls}}}"),
-  			'Symbol': uncompress("{'widths'{k3uaw4r19m3m2k1t2l2l202m2y2n3m2p5n202q6o3k3m2s2l2t2l2v3r2w1t3m3m2y1t2z1wbk2sbl3r'fof'6o3n3m3o3m3p3m3q3m3r3m3s3m3t3m3u1w3v1w3w3r3x3r3y3r3z2wbp3t3l3m5v2l5x2l5z3m2q4yfr3r7v3k7w1o7x3k}'kerning'{'fof'-6o}}"),
-  			'Helvetica': uncompress("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}"),
-  			'Helvetica-BoldOblique': uncompress("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),
-  			'ZapfDingbats': uncompress("{'widths'{k4u2k1w'fof'6o}'kerning'{'fof'-6o}}"),
-  			'Courier-Bold': uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
-  			'Times-Italic': uncompress("{'widths'{k3n2q4ycx2l201n3m201o5t201s2l201t2l201u2l201w3r201x3r201y3r2k1t2l2l202m2n2n3m2o3m2p5n202q5t2r1p2s2l2t2l2u3m2v4n2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w4n3x4n3y4n3z3m4k5w4l3x4m3x4n4m4o4s4p3x4q3x4r4s4s4s4t2l4u2w4v4m4w3r4x5n4y4m4z4s5k3x5l4s5m3x5n3m5o3r5p4s5q3x5r5n5s3x5t3r5u3r5v2r5w1w5x2r5y2u5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q1w6r3m6s3m6t1w6u1w6v2w6w1w6x4s6y3m6z3m7k3m7l3m7m2r7n2r7o1w7p3m7q2w7r4m7s2w7t2w7u2r7v2s7w1v7x2s7y3q202l3mcl3xal2ram3man3mao3map3mar3mas2lat4wau1vav3maw4nay4waz2lbk2sbl4n'fof'6obo2lbp3mbq3obr1tbs2lbu1zbv3mbz3mck3x202k3mcm3xcn3xco3xcp3xcq5tcr4mcs3xct3xcu3xcv3xcw2l2m2ucy2lcz2ldl4mdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr4nfs3mft3mfu3mfv3mfw3mfz2w203k6o212m6m2dw2l2cq2l3t3m3u2l17s3r19m3m}'kerning'{cl{5kt4qw}201s{201sw}201t{201tw2wy2yy6q-t}201x{2wy2yy}2k{201tw}2w{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}2x{17ss5ts5os}2y{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}'fof'-6o6t{17ss5ts5qs}7t{5os}3v{5qs}7p{17su5tu5qs}ck{5kt4qw}4l{5kt4qw}cm{5kt4qw}cn{5kt4qw}co{5kt4qw}cp{5kt4qw}6l{4qs5ks5ou5qw5ru17su5tu}17s{2ks}5q{ckvclvcmvcnvcovcpv4lv}5r{ckuclucmucnucoucpu4lu}5t{2ks}6p{4qs5ks5ou5qw5ru17su5tu}ek{4qs5ks5ou5qw5ru17su5tu}el{4qs5ks5ou5qw5ru17su5tu}em{4qs5ks5ou5qw5ru17su5tu}en{4qs5ks5ou5qw5ru17su5tu}eo{4qs5ks5ou5qw5ru17su5tu}ep{4qs5ks5ou5qw5ru17su5tu}es{5ks5qs4qs}et{4qs5ks5ou5qw5ru17su5tu}eu{4qs5ks5qw5ru17su5tu}ev{5ks5qs4qs}ex{17ss5ts5qs}6z{4qv5ks5ou5qw5ru17su5tu}fm{4qv5ks5ou5qw5ru17su5tu}fn{4qv5ks5ou5qw5ru17su5tu}fo{4qv5ks5ou5qw5ru17su5tu}fp{4qv5ks5ou5qw5ru17su5tu}fq{4qv5ks5ou5qw5ru17su5tu}7r{5os}fs{4qv5ks5ou5qw5ru17su5tu}ft{17su5tu5qs}fu{17su5tu5qs}fv{17su5tu5qs}fw{17su5tu5qs}}}"),
-  			'Times-Roman': uncompress("{'widths'{k3n2q4ycx2l201n3m201o6o201s2l201t2l201u2l201w2w201x2w201y2w2k1t2l2l202m2n2n3m2o3m2p5n202q6o2r1m2s2l2t2l2u3m2v3s2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v1w3w3s3x3s3y3s3z2w4k5w4l4s4m4m4n4m4o4s4p3x4q3r4r4s4s4s4t2l4u2r4v4s4w3x4x5t4y4s4z4s5k3r5l4s5m4m5n3r5o3x5p4s5q4s5r5y5s4s5t4s5u3x5v2l5w1w5x2l5y2z5z3m6k2l6l2w6m3m6n2w6o3m6p2w6q2l6r3m6s3m6t1w6u1w6v3m6w1w6x4y6y3m6z3m7k3m7l3m7m2l7n2r7o1w7p3m7q3m7r4s7s3m7t3m7u2w7v3k7w1o7x3k7y3q202l3mcl4sal2lam3man3mao3map3mar3mas2lat4wau1vav3maw3say4waz2lbk2sbl3s'fof'6obo2lbp3mbq2xbr1tbs2lbu1zbv3mbz2wck4s202k3mcm4scn4sco4scp4scq5tcr4mcs3xct3xcu3xcv3xcw2l2m2tcy2lcz2ldl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek2wel2wem2wen2weo2wep2weq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr3sfs3mft3mfu3mfv3mfw3mfz3m203k6o212m6m2dw2l2cq2l3t3m3u1w17s4s19m3m}'kerning'{cl{4qs5ku17sw5ou5qy5rw201ss5tw201ws}201s{201ss}201t{ckw4lwcmwcnwcowcpwclw4wu201ts}2k{201ts}2w{4qs5kw5os5qx5ru17sx5tx}2x{17sw5tw5ou5qu}2y{4qs5kw5os5qx5ru17sx5tx}'fof'-6o7t{ckuclucmucnucoucpu4lu5os5rs}3u{17su5tu5qs}3v{17su5tu5qs}7p{17sw5tw5qs}ck{4qs5ku17sw5ou5qy5rw201ss5tw201ws}4l{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cm{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cn{4qs5ku17sw5ou5qy5rw201ss5tw201ws}co{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cp{4qs5ku17sw5ou5qy5rw201ss5tw201ws}6l{17su5tu5os5qw5rs}17s{2ktclvcmvcnvcovcpv4lv4wuckv}5o{ckwclwcmwcnwcowcpw4lw4wu}5q{ckyclycmycnycoycpy4ly4wu5ms}5r{cktcltcmtcntcotcpt4lt4ws}5t{2ktclvcmvcnvcovcpv4lv4wuckv}7q{cksclscmscnscoscps4ls}6p{17su5tu5qw5rs}ek{5qs5rs}el{17su5tu5os5qw5rs}em{17su5tu5os5qs5rs}en{17su5qs5rs}eo{5qs5rs}ep{17su5tu5os5qw5rs}es{5qs}et{17su5tu5qw5rs}eu{17su5tu5qs5rs}ev{5qs}6z{17sv5tv5os5qx5rs}fm{5os5qt5rs}fn{17sv5tv5os5qx5rs}fo{17sv5tv5os5qx5rs}fp{5os5qt5rs}fq{5os5qt5rs}7r{ckuclucmucnucoucpu4lu5os}fs{17sv5tv5os5qx5rs}ft{17ss5ts5qs}fu{17sw5tw5qs}fv{17sw5tw5qs}fw{17ss5ts5qs}fz{ckuclucmucnucoucpu4lu5os5rs}}}"),
-  			'Helvetica-Oblique': uncompress("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}")
-  		} };
-
-  	/*
-   This event handler is fired when a new jsPDF object is initialized
-   This event handler appends metrics data to standard fonts within
-   that jsPDF instance. The metrics are mapped over Unicode character
-   codes, NOT CIDs or other codes matching the StandardEncoding table of the
-   standard PDF fonts.
-   Future:
-   Also included is the encoding maping table, converting Unicode (UCS-2, UTF-16)
-   char codes to StandardEncoding character codes. The encoding table is to be used
-   somewhere around "pdfEscape" call.
-   */
+        case "F":
+          op = "f"; // fill
 
-  	API.events.push(['addFont', function (font) {
-  		var metrics,
-  		    unicode_section,
-  		    encoding = 'Unicode',
-  		    encodingBlock;
-
-  		metrics = fontMetrics[encoding][font.postScriptName];
-  		if (metrics) {
-  			if (font.metadata[encoding]) {
-  				unicode_section = font.metadata[encoding];
-  			} else {
-  				unicode_section = font.metadata[encoding] = {};
-  			}
-
-  			unicode_section.widths = metrics.widths;
-  			unicode_section.kerning = metrics.kerning;
-  		}
-
-  		encodingBlock = encodings[encoding][font.postScriptName];
-  		if (encodingBlock) {
-  			if (font.metadata[encoding]) {
-  				unicode_section = font.metadata[encoding];
-  			} else {
-  				unicode_section = font.metadata[encoding] = {};
-  			}
-
-  			unicode_section.encoding = encodingBlock;
-  			if (encodingBlock.codePages && encodingBlock.codePages.length) {
-  				font.encoding = encodingBlock.codePages[0];
-  			}
-  		}
-  	}]); // end of adding event handler
-  })(jsPDF.API);
+          break;
 
-  /**
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
-  (function (jsPDF, global) {
-
-      jsPDF.API.events.push(['addFont', function (font) {
-          if (jsPDF.API.existsFileInVFS(font.postScriptName)) {
-              font.metadata = jsPDF.API.TTFFont.open(font.postScriptName, font.fontName, jsPDF.API.getFileFromVFS(font.postScriptName), font.encoding);
-              font.metadata.Unicode = font.metadata.Unicode || { encoding: {}, kerning: {}, widths: [] };
-          } else if (font.id.slice(1) > 14) {
-              console.error("Font does not exist in FileInVFS, import fonts or remove declaration doc.addFont('" + font.postScriptName + "').");
-          }
-      }]); // end of adding event handler
-  })(jsPDF, typeof self !== "undefined" && self || typeof global !== "undefined" && global || typeof window !== "undefined" && window || Function("return this")());
+        case "FD":
+        case "DF":
+          op = "B";
+          break;
 
-  /** @preserve
-  jsPDF SVG plugin
-  Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
-  */
-  (function (jsPDFAPI) {
+        case "f":
+        case "f*":
+        case "B":
+        case "B*":
+          /*
+                 Allow direct use of these PDF path-painting operators:
+                 - f    fill using nonzero winding number rule
+                 - f*    fill using even-odd rule
+                 - B    fill then stroke with fill using non-zero winding number rule
+                 - B*    fill then stroke with fill using even-odd rule
+                 */
+          op = style;
+          break;
+      }
 
-      /**
-      * Parses SVG XML and converts only some of the SVG elements into
-      * PDF elements.
-      *
-      * Supports:
-      * paths
-      * 
-      * @name addSvg
-      * @public
-      * @function
-      * @param {String} SVG-Data as Text
-      * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-      * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-      * @param {Number} width of SVG (in units declared at inception of PDF document)
-      * @param {Number} height of SVG (in units declared at inception of PDF document)
-      * @returns {Object} jsPDF-instance
-      */
+      return op;
+    };
+    /**
+     * Close the current path. The PDF "h" operator.
+     * @name close
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     */
 
-      jsPDFAPI.addSvg = function (svgtext, x, y, w, h) {
-          // 'this' is _jsPDF object returned when jsPDF is inited (new jsPDF())
 
-          var undef;
+    var close = API.close = function () {
+      out("h");
+      return this;
+    };
+    /**
+     * Stroke the path. The PDF "S" operator.
+     * @name stroke
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     */
 
-          if (x === undef || y === undef) {
-              throw new Error("addSVG needs values for 'x' and 'y'");
-          }
 
-          function InjectCSS(cssbody, document) {
-              var styletag = document.createElement('style');
-              styletag.type = 'text/css';
-              if (styletag.styleSheet) {
-                  // ie
-                  styletag.styleSheet.cssText = cssbody;
-              } else {
-                  // others
-                  styletag.appendChild(document.createTextNode(cssbody));
-              }
-              document.getElementsByTagName("head")[0].appendChild(styletag);
-          }
+    API.stroke = function () {
+      out("S");
+      return this;
+    };
+    /**
+     * Fill the current path using the nonzero winding number rule. If a pattern is provided, the path will be filled
+     * with this pattern, otherwise with the current fill color. Equivalent to the PDF "f" operator.
+     * @name fill
+     * @function
+     * @instance
+     * @param {PatternData=} pattern If provided the path will be filled with this pattern
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     */
 
-          function createWorkerNode(document) {
 
-              var frameID = 'childframe' // Date.now().toString() + '_' + (Math.random() * 100).toString()
-              ,
-                  frame = document.createElement('iframe');
+    API.fill = function (pattern) {
+      fillWithOptionalPattern("f", pattern);
+      return this;
+    };
+    /**
+     * Fill the current path using the even-odd rule. The PDF f* operator.
+     * @see API.fill
+     * @name fillEvenOdd
+     * @function
+     * @instance
+     * @param {PatternData=} pattern If provided the path will be filled with this pattern
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     */
 
-              InjectCSS('.jsPDF_sillysvg_iframe {display:none;position:absolute;}', document);
 
-              frame.name = frameID;
-              frame.setAttribute("width", 0);
-              frame.setAttribute("height", 0);
-              frame.setAttribute("frameborder", "0");
-              frame.setAttribute("scrolling", "no");
-              frame.setAttribute("seamless", "seamless");
-              frame.setAttribute("class", "jsPDF_sillysvg_iframe");
+    API.fillEvenOdd = function (pattern) {
+      fillWithOptionalPattern("f*", pattern);
+      return this;
+    };
+    /**
+     * Fill using the nonzero winding number rule and then stroke the current Path. The PDF "B" operator.
+     * @see API.fill
+     * @name fillStroke
+     * @function
+     * @instance
+     * @param {PatternData=} pattern If provided the path will be stroked with this pattern
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     */
 
-              document.body.appendChild(frame);
 
-              return frame;
-          }
+    API.fillStroke = function (pattern) {
+      fillWithOptionalPattern("B", pattern);
+      return this;
+    };
+    /**
+     * Fill using the even-odd rule and then stroke the current Path. The PDF "B" operator.
+     * @see API.fill
+     * @name fillStrokeEvenOdd
+     * @function
+     * @instance
+     * @param {PatternData=} pattern If provided the path will be fill-stroked with this pattern
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     */
 
-          function attachSVGToWorkerNode(svgtext, frame) {
-              var framedoc = (frame.contentWindow || frame.contentDocument).document;
-              framedoc.write(svgtext);
-              framedoc.close();
-              return framedoc.getElementsByTagName('svg')[0];
-          }
 
-          function convertPathToPDFLinesArgs(path) {
-              // we will use 'lines' method call. it needs:
-              // - starting coordinate pair
-              // - array of arrays of vector shifts (2-len for line, 6 len for bezier)
-              // - scale array [horizontal, vertical] ratios
-              // - style (stroke, fill, both)
-
-              var x = parseFloat(path[1]),
-                  y = parseFloat(path[2]),
-                  vectors = [],
-                  position = 3,
-                  len = path.length;
-
-              while (position < len) {
-                  if (path[position] === 'c') {
-                      vectors.push([parseFloat(path[position + 1]), parseFloat(path[position + 2]), parseFloat(path[position + 3]), parseFloat(path[position + 4]), parseFloat(path[position + 5]), parseFloat(path[position + 6])]);
-                      position += 7;
-                  } else if (path[position] === 'l') {
-                      vectors.push([parseFloat(path[position + 1]), parseFloat(path[position + 2])]);
-                      position += 3;
-                  } else {
-                      position += 1;
-                  }
-              }
-              return [x, y, vectors];
-          }
-
-          var workernode = createWorkerNode(document),
-              svgnode = attachSVGToWorkerNode(svgtext, workernode),
-              scale = [1, 1],
-              svgw = parseFloat(svgnode.getAttribute('width')),
-              svgh = parseFloat(svgnode.getAttribute('height'));
-
-          if (svgw && svgh) {
-              // setting both w and h makes image stretch to size.
-              // this may distort the image, but fits your demanded size
-              if (w && h) {
-                  scale = [w / svgw, h / svgh];
-              }
-              // if only one is set, that value is set as max and SVG
-              // is scaled proportionately.
-              else if (w) {
-                      scale = [w / svgw, w / svgw];
-                  } else if (h) {
-                      scale = [h / svgh, h / svgh];
-                  }
-          }
+    API.fillStrokeEvenOdd = function (pattern) {
+      fillWithOptionalPattern("B*", pattern);
+      return this;
+    };
 
-          var i,
-              l,
-              tmp,
-              linesargs,
-              items = svgnode.childNodes;
-          for (i = 0, l = items.length; i < l; i++) {
-              tmp = items[i];
-              if (tmp.tagName && tmp.tagName.toUpperCase() === 'PATH') {
-                  linesargs = convertPathToPDFLinesArgs(tmp.getAttribute("d").split(' '));
-                  // path start x coordinate
-                  linesargs[0] = linesargs[0] * scale[0] + x; // where x is upper left X of image
-                  // path start y coordinate
-                  linesargs[1] = linesargs[1] * scale[1] + y; // where y is upper left Y of image
-                  // the rest of lines are vectors. these will adjust with scale value auto.
-                  this.lines.call(this, linesargs[2] // lines
-                  , linesargs[0] // starting x
-                  , linesargs[1] // starting y
-                  , scale);
-              }
-          }
+    var fillWithOptionalPattern = function fillWithOptionalPattern(style, pattern) {
+      if (_typeof(pattern) === "object") {
+        fillWithPattern(pattern, style);
+      } else {
+        out(style);
+      }
+    };
 
-          // clean up
-          // workernode.parentNode.removeChild(workernode)
+    var putStyle = function putStyle(style) {
+      if (style === null || apiMode === ApiMode.ADVANCED && style === undefined) {
+        return;
+      }
 
-          return this;
-      };
+      style = getStyle(style); // stroking / filling / both the path
 
-      //fallback
-      jsPDFAPI.addSVG = jsPDFAPI.addSvg;
+      out(style);
+    };
 
-      /**
-      * Parses SVG XML and saves it as image into the PDF.
-      *
-      * Depends on canvas-element and canvg
-      *
-      * @name addSvgAsImage
-      * @public
-      * @function
-      * @param {String} SVG-Data as Text
-      * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-      * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-      * @param {Number} width of SVG-Image (in units declared at inception of PDF document)
-      * @param {Number} height of SVG-Image (in units declared at inception of PDF document)
-      * @param {String} alias of SVG-Image (if used multiple times)
-      * @param {String} compression of the generated JPEG, can have the values 'NONE', 'FAST', 'MEDIUM' and 'SLOW'
-      * @param {Number} rotation of the image in degrees (0-359)
-      * 
-      * @returns jsPDF
-      * @methodOf jsPDF#
-      */
-      jsPDFAPI.addSvgAsImage = function (svg, x, y, w, h, alias, compression, rotation) {
+    function cloneTilingPattern(patternKey, boundingBox, xStep, yStep, matrix) {
+      var clone = new TilingPattern(boundingBox || this.boundingBox, xStep || this.xStep, yStep || this.yStep, this.gState, matrix || this.matrix);
+      clone.stream = this.stream;
+      var key = patternKey + "$$" + this.cloneIndex++ + "$$";
+      addPattern(key, clone);
+      return clone;
+    }
 
-          if (isNaN(x) || isNaN(y)) {
-              console.error('jsPDF.addSvgAsImage: Invalid coordinates', arguments);
-              throw new Error('Invalid coordinates passed to jsPDF.addSvgAsImage');
-          }
+    var fillWithPattern = function fillWithPattern(patternData, style) {
+      var patternId = patternMap[patternData.key];
+      var pattern = patterns[patternId];
 
-          if (isNaN(w) || isNaN(h)) {
-              console.error('jsPDF.addSvgAsImage: Invalid measurements', arguments);
-              throw new Error('Invalid measurements (width and/or height) passed to jsPDF.addSvgAsImage');
-          }
+      if (pattern instanceof ShadingPattern) {
+        out("q");
+        out(clipRuleFromStyle(style));
 
-          var canvas = document.createElement('canvas');
-          canvas.width = w;
-          canvas.height = h;
-          var ctx = canvas.getContext('2d');
-          ctx.fillStyle = '#fff'; /// set white fill style
-          ctx.fillRect(0, 0, canvas.width, canvas.height);
-
-          //load a svg snippet in the canvas with id = 'drawingArea'
-          canvg(canvas, svg, {
-              ignoreMouse: true,
-              ignoreAnimation: true,
-              ignoreDimensions: true,
-              ignoreClear: true
-          });
+        if (pattern.gState) {
+          API.setGState(pattern.gState);
+        }
 
-          this.addImage(canvas.toDataURL("image/jpeg", 1.0), x, y, w, h, compression, rotation);
-          return this;
-      };
-  })(jsPDF.API);
+        out(patternData.matrix.toString() + " cm");
+        out("/" + patternId + " sh");
+        out("Q");
+      } else if (pattern instanceof TilingPattern) {
+        // pdf draws patterns starting at the bottom left corner and they are not affected by the global transformation,
+        // so we must flip them
+        var matrix = new Matrix(1, 0, 0, -1, 0, getPageHeight());
 
-  /** ==================================================================== 
-   * jsPDF total_pages plugin
-   * Copyright (c) 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
-   * 
-   * 
-   * ====================================================================
-   */
+        if (patternData.matrix) {
+          matrix = matrix.multiply(patternData.matrix || identityMatrix); // we cannot apply a matrix to the pattern on use so we must abuse the pattern matrix and create new instances
+          // for each use
 
-  (function (jsPDFAPI) {
+          patternId = cloneTilingPattern.call(pattern, patternData.key, patternData.boundingBox, patternData.xStep, patternData.yStep, matrix).id;
+        }
 
-    jsPDFAPI.putTotalPages = function (pageExpression) {
+        out("q");
+        out("/Pattern cs");
+        out("/" + patternId + " scn");
 
-      var replaceExpression = new RegExp(pageExpression, 'g');
-      for (var n = 1; n <= this.internal.getNumberOfPages(); n++) {
-        for (var i = 0; i < this.internal.pages[n].length; i++) {
-          this.internal.pages[n][i] = this.internal.pages[n][i].replace(replaceExpression, this.internal.getNumberOfPages());
+        if (pattern.gState) {
+          API.setGState(pattern.gState);
         }
+
+        out(style);
+        out("Q");
       }
-      return this;
     };
-  })(jsPDF.API);
-
-  /**
-   * jsPDF viewerPreferences Plugin
-   * @author Aras Abbasi (github.com/arasabbasi)
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
 
-  /**
-  * Adds the ability to set ViewerPreferences and by thus
-  * controlling the way the document is to be presented on the
-  * screen or in print.
-  */
+    var clipRuleFromStyle = function clipRuleFromStyle(style) {
+      switch (style) {
+        case "f":
+        case "F":
+          return "W n";
 
-  (function (jsPDFAPI) {
-      /**
-       * Set the ViewerPreferences of the generated PDF
-       *
-       * @param {Object} options Array with the ViewerPreferences<br />
-       * Example: doc.viewerPreferences({"FitWindow":true});<br />
-       * <br />
-       * You can set following preferences:<br />
-       * <br/>
-       * <b>HideToolbar</b> <i>(boolean)</i><br />
-       * Default value: false<br />
-       * <br />
-       * <b>HideMenubar</b> <i>(boolean)</i><br />
-       * Default value: false.<br />
-       * <br />
-       * <b>HideWindowUI</b> <i>(boolean)</i><br />
-       * Default value: false.<br />
-       * <br />
-       * <b>FitWindow</b> <i>(boolean)</i><br />
-       * Default value: false.<br />
-       * <br />
-       * <b>CenterWindow</b> <i>(boolean)</i><br />
-       * Default value: false<br />
-       * <br />
-       * <b>DisplayDocTitle</b> <i>(boolean)</i><br />
-       * Default value: false.<br />
-       * <br />
-       * <b>NonFullScreenPageMode</b> <i>(String)</i><br />
-       * Possible values: UseNone, UseOutlines, UseThumbs, UseOC<br />
-       * Default value: UseNone<br/>
-       * <br />
-       * <b>Direction</b> <i>(String)</i><br />
-       * Possible values: L2R, R2L<br />
-       * Default value: L2R.<br />
-       * <br />
-       * <b>ViewArea</b> <i>(String)</i><br />
-       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
-       * Default value: CropBox.<br />
-       * <br />
-       * <b>ViewClip</b> <i>(String)</i><br />
-       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
-       * Default value: CropBox<br />
-       * <br />
-       * <b>PrintArea</b> <i>(String)</i><br />
-       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
-       * Default value: CropBox<br />
-       * <br />
-       * <b>PrintClip</b> <i>(String)</i><br />
-       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
-       * Default value: CropBox.<br />
-       * <br />
-       * <b>PrintScaling</b> <i>(String)</i><br />
-       * Possible values: AppDefault, None<br />
-       * Default value: AppDefault.<br />
-       * <br />
-       * <b>Duplex</b> <i>(String)</i><br />
-       * Possible values: Simplex, DuplexFlipLongEdge, DuplexFlipShortEdge
-       * Default value: none<br />
-       * <br />
-       * <b>PickTrayByPDFSize</b> <i>(boolean)</i><br />
-       * Default value: false<br />
-       * <br />
-       * <b>PrintPageRange</b> <i>(Array)</i><br />
-       * Example: [[1,5], [7,9]]<br />
-       * Default value: as defined by PDF viewer application<br />
-       * <br />
-       * <b>NumCopies</b> <i>(Number)</i><br />
-       * Possible values: 1, 2, 3, 4, 5<br />
-       * Default value: 1<br />
-       * <br />
-       * For more information see the PDF Reference, sixth edition on Page 577
-       * @param {boolean} doReset True to reset the settings
-       * @function
-       * @returns jsPDF
-       * @methodOf jsPDF#
-       * @example
-       * var doc = new jsPDF()
-       * doc.text('This is a test', 10, 10)
-       * doc.viewerPreferences({'FitWindow': true}, true)
-       * doc.save("viewerPreferences.pdf")
-       *
-       * // Example printing 10 copies, using cropbox, and hiding UI.
-       * doc.viewerPreferences({
-       *   'HideWindowUI': true,
-       *   'PrintArea': 'CropBox',
-       *   'NumCopies': 10
-       * })
-       * @name viewerPreferences
-       */
+        case "f*":
+          return "W* n";
 
-      jsPDFAPI.viewerPreferences = function (options, doReset) {
-          options = options || {};
-          doReset = doReset || false;
-
-          var configuration;
-          var configurationTemplate = {
-              "HideToolbar": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
-              "HideMenubar": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
-              "HideWindowUI": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
-              "FitWindow": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
-              "CenterWindow": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
-              "DisplayDocTitle": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.4 },
-              "NonFullScreenPageMode": { defaultValue: "UseNone", value: "UseNone", type: "name", explicitSet: false, valueSet: ["UseNone", "UseOutlines", "UseThumbs", "UseOC"], pdfVersion: 1.3 },
-              "Direction": { defaultValue: "L2R", value: "L2R", type: "name", explicitSet: false, valueSet: ["L2R", "R2L"], pdfVersion: 1.3 },
-              "ViewArea": { defaultValue: "CropBox", value: "CropBox", type: "name", explicitSet: false, valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], pdfVersion: 1.4 },
-              "ViewClip": { defaultValue: "CropBox", value: "CropBox", type: "name", explicitSet: false, valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], pdfVersion: 1.4 },
-              "PrintArea": { defaultValue: "CropBox", value: "CropBox", type: "name", explicitSet: false, valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], pdfVersion: 1.4 },
-              "PrintClip": { defaultValue: "CropBox", value: "CropBox", type: "name", explicitSet: false, valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], pdfVersion: 1.4 },
-              "PrintScaling": { defaultValue: "AppDefault", value: "AppDefault", type: "name", explicitSet: false, valueSet: ["AppDefault", "None"], pdfVersion: 1.6 },
-              "Duplex": { defaultValue: "", value: "none", type: "name", explicitSet: false, valueSet: ["Simplex", "DuplexFlipShortEdge", "DuplexFlipLongEdge", "none"], pdfVersion: 1.7 },
-              "PickTrayByPDFSize": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.7 },
-              "PrintPageRange": { defaultValue: "", value: "", type: "array", explicitSet: false, valueSet: null, pdfVersion: 1.7 },
-              "NumCopies": { defaultValue: 1, value: 1, type: "integer", explicitSet: false, valueSet: null, pdfVersion: 1.7 }
-          };
+        case "B":
+          return "W S";
 
-          var configurationKeys = Object.keys(configurationTemplate);
+        case "B*":
+          return "W* S";
+        // these two are for compatibility reasons (in the past, calling any primitive method with a shading pattern
+        // and "n"/"S" as style would still fill/fill and stroke the path)
 
-          var rangeArray = [];
-          var i = 0;
-          var j = 0;
-          var k = 0;
-          var isValid = true;
+        case "S":
+          return "W S";
 
-          var method;
-          var value;
+        case "n":
+          return "W n";
+      }
+    };
+    /**
+     * Begin a new subpath by moving the current point to coordinates (x, y). The PDF "m" operator.
+     * @param {number} x
+     * @param {number} y
+     * @name moveTo
+     * @function
+     * @instance
+     * @memberof jsPDF#
+     * @returns {jsPDF}
+     */
 
-          function arrayContainsElement(array, element) {
-              var iterator;
-              var result = false;
 
-              for (iterator = 0; iterator < array.length; iterator += 1) {
-                  if (array[iterator] === element) {
-                      result = true;
-                  }
-              }
-              return result;
-          }
+    var moveTo = API.moveTo = function (x, y) {
+      out(hpf(scale(x)) + " " + hpf(transformScaleY(y)) + " m");
+      return this;
+    };
+    /**
+     * Append a straight line segment from the current point to the point (x, y). The PDF "l" operator.
+     * @param {number} x
+     * @param {number} y
+     * @memberof jsPDF#
+     * @name lineTo
+     * @function
+     * @instance
+     * @memberof jsPDF#
+     * @returns {jsPDF}
+     */
 
-          if (this.internal.viewerpreferences === undefined) {
-              this.internal.viewerpreferences = {};
-              this.internal.viewerpreferences.configuration = JSON.parse(JSON.stringify(configurationTemplate));
-              this.internal.viewerpreferences.isSubscribed = false;
-          }
-          configuration = this.internal.viewerpreferences.configuration;
 
-          if (options === "reset" || doReset === true) {
-              var len = configurationKeys.length;
+    var lineTo = API.lineTo = function (x, y) {
+      out(hpf(scale(x)) + " " + hpf(transformScaleY(y)) + " l");
+      return this;
+    };
+    /**
+     * Append a cubic Bézier curve to the current path. The curve shall extend from the current point to the point
+     * (x3, y3), using (x1, y1) and (x2, y2) as Bézier control points. The new current point shall be (x3, x3).
+     * @param {number} x1
+     * @param {number} y1
+     * @param {number} x2
+     * @param {number} y2
+     * @param {number} x3
+     * @param {number} y3
+     * @memberof jsPDF#
+     * @name curveTo
+     * @function
+     * @instance
+     * @memberof jsPDF#
+     * @returns {jsPDF}
+     */
 
-              for (k = 0; k < len; k += 1) {
-                  configuration[configurationKeys[k]].value = configuration[configurationKeys[k]].defaultValue;
-                  configuration[configurationKeys[k]].explicitSet = false;
-              }
-          }
 
-          if ((typeof options === "undefined" ? "undefined" : _typeof(options)) === "object") {
-              for (method in options) {
-                  value = options[method];
-                  if (arrayContainsElement(configurationKeys, method) && value !== undefined) {
-
-                      if (configuration[method].type === "boolean" && typeof value === "boolean") {
-                          configuration[method].value = value;
-                      } else if (configuration[method].type === "name" && arrayContainsElement(configuration[method].valueSet, value)) {
-                          configuration[method].value = value;
-                      } else if (configuration[method].type === "integer" && Number.isInteger(value)) {
-                          configuration[method].value = value;
-                      } else if (configuration[method].type === "array") {
-
-                          for (i = 0; i < value.length; i += 1) {
-                              isValid = true;
-                              if (value[i].length === 1 && typeof value[i][0] === "number") {
-                                  rangeArray.push(String(value[i]));
-                              } else if (value[i].length > 1) {
-                                  for (j = 0; j < value[i].length; j += 1) {
-                                      if (typeof value[i][j] !== "number") {
-                                          isValid = false;
-                                      }
-                                  }
-                                  if (isValid === true) {
-                                      rangeArray.push(String(value[i].join("-")));
-                                  }
-                              }
-                          }
-                          configuration[method].value = String(rangeArray);
-                      } else {
-                          configuration[method].value = configuration[method].defaultValue;
-                      }
+    var curveTo = API.curveTo = function (x1, y1, x2, y2, x3, y3) {
+      out([hpf(scale(x1)), hpf(transformScaleY(y1)), hpf(scale(x2)), hpf(transformScaleY(y2)), hpf(scale(x3)), hpf(transformScaleY(y3)), "c"].join(" "));
+      return this;
+    };
+    /**
+     * Draw a line on the current page.
+     *
+     * @name line
+     * @function
+     * @instance
+     * @param {number} x1
+     * @param {number} y1
+     * @param {number} x2
+     * @param {number} y2
+     * @param {string} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument. default: 'S'
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     */
 
-                      configuration[method].explicitSet = true;
-                  }
-              }
-          }
 
-          if (this.internal.viewerpreferences.isSubscribed === false) {
-              this.internal.events.subscribe("putCatalog", function () {
-                  var pdfDict = [];
-                  var vPref;
-                  for (vPref in configuration) {
-                      if (configuration[vPref].explicitSet === true) {
-                          if (configuration[vPref].type === "name") {
-                              pdfDict.push("/" + vPref + " /" + configuration[vPref].value);
-                          } else {
-                              pdfDict.push("/" + vPref + " " + configuration[vPref].value);
-                          }
-                      }
-                  }
-                  if (pdfDict.length !== 0) {
-                      this.internal.write("/ViewerPreferences\n<<\n" + pdfDict.join("\n") + "\n>>");
-                  }
-              });
-              this.internal.viewerpreferences.isSubscribed = true;
-          }
+    API.__private__.line = API.line = function (x1, y1, x2, y2, style) {
+      if (isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2) || !isValidStyle(style)) {
+        throw new Error("Invalid arguments passed to jsPDF.line");
+      }
 
-          this.internal.viewerpreferences.configuration = configuration;
-          return this;
-      };
-  })(jsPDF.API);
+      if (apiMode === ApiMode.COMPAT) {
+        return this.lines([[x2 - x1, y2 - y1]], x1, y1, [1, 1], style || "S");
+      } else {
+        return this.lines([[x2 - x1, y2 - y1]], x1, y1, [1, 1]).stroke();
+      }
+    };
+    /**
+     * @typedef {Object} PatternData
+     * {Matrix|undefined} matrix
+     * {Number|undefined} xStep
+     * {Number|undefined} yStep
+     * {Array.<Number>|undefined} boundingBox
+     */
 
-  /** ==================================================================== 
-   * jsPDF XMP metadata plugin
-   * Copyright (c) 2016 Jussi Utunen, u-jussi@suomi24.fi
-   * 
-   * 
-   * ====================================================================
-   */
+    /**
+     * Adds series of curves (straight lines or cubic bezier curves) to canvas, starting at `x`, `y` coordinates.
+     * All data points in `lines` are relative to last line origin.
+     * `x`, `y` become x1,y1 for first line / curve in the set.
+     * For lines you only need to specify [x2, y2] - (ending point) vector against x1, y1 starting point.
+     * For bezier curves you need to specify [x2,y2,x3,y3,x4,y4] - vectors to control points 1, 2, ending point. All vectors are against the start of the curve - x1,y1.
+     *
+     * @example .lines([[2,2],[-2,2],[1,1,2,2,3,3],[2,1]], 212,110, [1,1], 'F', false) // line, line, bezier curve, line
+     * @param {Array} lines Array of *vector* shifts as pairs (lines) or sextets (cubic bezier curves).
+     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
+     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
+     * @param {number} scale (Defaults to [1.0,1.0]) x,y Scaling factor for all vectors. Elements can be any floating number Sub-one makes drawing smaller. Over-one grows the drawing. Negative flips the direction.
+     * @param {string=} style A string specifying the painting style or null. Valid styles include:
+     * 'S' [default] - stroke,
+     * 'F' - fill,
+     * and 'DF' (or 'FD') -  fill then stroke.
+     * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple
+     * method calls. The last drawing method call used to define the shape should not have a null style argument.
+     *
+     * In "advanced" API mode this parameter is deprecated.
+     * @param {Boolean=} closed If true, the path is closed with a straight line from the end of the last curve to the starting point.
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name lines
+     */
 
-  /*global jsPDF */
 
-  /**
-  * Adds XMP formatted metadata to PDF
-  *
-  * @param {String} metadata The actual metadata to be added. The metadata shall be stored as XMP simple value. Note that if the metadata string contains XML markup characters "<", ">" or "&", those characters should be written using XML entities.
-  * @param {String} namespaceuri Sets the namespace URI for the metadata. Last character should be slash or hash.
-  * @function
-  * @returns {jsPDF}
-  * @methodOf jsPDF#
-  * @name addMetadata
-  */
+    API.__private__.lines = API.lines = function (lines, x, y, scale, style, closed) {
+      var scalex, scaley, i, l, leg, x2, y2, x3, y3, x4, y4, tmp; // Pre-August-2012 the order of arguments was function(x, y, lines, scale, style)
+      // in effort to make all calls have similar signature like
+      //   function(content, coordinateX, coordinateY , miscellaneous)
+      // this method had its args flipped.
+      // code below allows backward compatibility with old arg order.
 
-  (function (jsPDFAPI) {
+      if (typeof lines === "number") {
+        tmp = y;
+        y = x;
+        x = lines;
+        lines = tmp;
+      }
 
-      var xmpmetadata = "";
-      var xmpnamespaceuri = "";
-      var metadata_object_number = "";
+      scale = scale || [1, 1];
+      closed = closed || false;
 
-      jsPDFAPI.addMetadata = function (metadata, namespaceuri) {
-          xmpnamespaceuri = namespaceuri || "http://jspdf.default.namespaceuri/"; //The namespace URI for an XMP name shall not be empty
-          xmpmetadata = metadata;
-          this.internal.events.subscribe('postPutResources', function () {
-              if (!xmpmetadata) {
-                  metadata_object_number = "";
-              } else {
-                  var xmpmeta_beginning = '<x:xmpmeta xmlns:x="adobe:ns:meta/">';
-                  var rdf_beginning = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:jspdf="' + xmpnamespaceuri + '"><jspdf:metadata>';
-                  var rdf_ending = '</jspdf:metadata></rdf:Description></rdf:RDF>';
-                  var xmpmeta_ending = '</x:xmpmeta>';
-                  var utf8_xmpmeta_beginning = unescape(encodeURIComponent(xmpmeta_beginning));
-                  var utf8_rdf_beginning = unescape(encodeURIComponent(rdf_beginning));
-                  var utf8_metadata = unescape(encodeURIComponent(xmpmetadata));
-                  var utf8_rdf_ending = unescape(encodeURIComponent(rdf_ending));
-                  var utf8_xmpmeta_ending = unescape(encodeURIComponent(xmpmeta_ending));
-
-                  var total_len = utf8_rdf_beginning.length + utf8_metadata.length + utf8_rdf_ending.length + utf8_xmpmeta_beginning.length + utf8_xmpmeta_ending.length;
-
-                  metadata_object_number = this.internal.newObject();
-                  this.internal.write('<< /Type /Metadata /Subtype /XML /Length ' + total_len + ' >>');
-                  this.internal.write('stream');
-                  this.internal.write(utf8_xmpmeta_beginning + utf8_rdf_beginning + utf8_metadata + utf8_rdf_ending + utf8_xmpmeta_ending);
-                  this.internal.write('endstream');
-                  this.internal.write('endobj');
-              }
-          });
-          this.internal.events.subscribe('putCatalog', function () {
-              if (metadata_object_number) {
-                  this.internal.write('/Metadata ' + metadata_object_number + ' 0 R');
-              }
-          });
-          return this;
-      };
-  })(jsPDF.API);
+      if (isNaN(x) || isNaN(y) || !Array.isArray(lines) || !Array.isArray(scale) || !isValidStyle(style) || typeof closed !== "boolean") {
+        throw new Error("Invalid arguments passed to jsPDF.lines");
+      } // starting point
 
-  (function (jsPDF, global) {
 
-      var jsPDFAPI = jsPDF.API;
+      moveTo(x, y);
+      scalex = scale[0];
+      scaley = scale[1];
+      l = lines.length; //, x2, y2 // bezier only. In page default measurement "units", *after* scaling
+      //, x3, y3 // bezier only. In page default measurement "units", *after* scaling
+      // ending point for all, lines and bezier. . In page default measurement "units", *after* scaling
 
-      var glyID = [0];
-      /**************************************************/
-      /* function : toHex                               */
-      /* comment : Replace str with a hex string.       */
-      /**************************************************/
-      function toHex(str) {
-          var hex = '';
-          for (var i = 0; i < str.length; i++) {
-              hex += '' + str.charCodeAt(i).toString(16);
-          }
-          return hex;
-      }
-
-      /***************************************************************************************************/
-      /* function : pdfEscape16                                                                          */
-      /* comment : The character id of a 2-byte string is converted to a hexadecimal number by obtaining */
-      /*   the corresponding glyph id and width, and then adding padding to the string.                  */
-      /***************************************************************************************************/
-      var pdfEscape16 = function pdfEscape16(text, font) {
-          var widths = font.metadata.Unicode.widths;        var padz = ["", "0", "00", "000", "0000"];
-          var ar = [""];
-          for (var i = 0, l = text.length, t; i < l; ++i) {
-              t = font.metadata.characterToGlyph(text.charCodeAt(i));
-              glyID.push(t);
-              if (widths.indexOf(t) == -1) {
-                  widths.push(t);
-                  widths.push([parseInt(font.metadata.widthOfGlyph(t), 10)]);
-              }
-              if (t == '0') {
-                  //Spaces are not allowed in cmap.
-                  return ar.join("");
-              } else {
-                  t = t.toString(16);
-                  ar.push(padz[4 - t.length], t);
-              }
-          }
-          return ar.join("");
-      };
+      x4 = x; // last / ending point = starting point for first item.
 
-      var identityHFunction = function identityHFunction(font, out, newObject) {
+      y4 = y; // last / ending point = starting point for first item.
 
-          if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === 'Identity-H') {
-              //Tag with Identity-H
-              var widths = font.metadata.Unicode.widths;
-              var data = font.metadata.subset.encode(glyID);
-              var pdfOutput = data;
-              var pdfOutput2 = "";
-              for (var i = 0; i < pdfOutput.length; i++) {
-                  pdfOutput2 += String.fromCharCode(pdfOutput[i]);
-              }
-              var fontTable = newObject();
-              out('<<');
-              out('/Length ' + pdfOutput2.length);
-              out('/Length1 ' + pdfOutput2.length);
-              out('>>');
-
-              out('stream');
-              out(pdfOutput2);
-              out('endstream');
-              out('endobj');
-
-              var fontDescriptor = newObject();
-              out('<<');
-              out('/Type /FontDescriptor');
-              out('/FontName /' + font.fontName);
-              out('/FontFile2 ' + fontTable + ' 0 R');
-              out('/FontBBox ' + jsPDF.API.PDFObject.convert(font.metadata.bbox));
-              out('/Flags ' + font.metadata.flags);
-              out('/StemV ' + font.metadata.stemV);
-              out('/ItalicAngle ' + font.metadata.italicAngle);
-              out('/Ascent ' + font.metadata.ascender);
-              out('/Descent ' + font.metadata.decender);
-              out('/CapHeight ' + font.metadata.capHeight);
-              out('>>');
-              out('endobj');
-
-              var DescendantFont = newObject();
-              out('<<');
-              out('/Type /Font');
-              out('/BaseFont /' + font.fontName);
-              out('/FontDescriptor ' + fontDescriptor + ' 0 R');
-              out('/W ' + jsPDF.API.PDFObject.convert(widths));
-              out('/CIDToGIDMap /Identity');
-              out('/DW 1000');
-              out('/Subtype /CIDFontType2');
-              out('/CIDSystemInfo');
-              out('<<');
-              out('/Supplement 0');
-              out('/Registry (Adobe)');
-              out('/Ordering (' + font.encoding + ')');
-              out('>>');
-              out('>>');
-              out('endobj');
-
-              font.objectNumber = newObject();
-              out('<<');
-              out('/Type /Font');
-              out('/Subtype /Type0');
-              out('/BaseFont /' + font.fontName);
-              out('/Encoding /' + font.encoding);
-              out('/DescendantFonts [' + DescendantFont + ' 0 R]');
-              out('>>');
-              out('endobj');
-
-              font.isAlreadyPutted = true;
-          }
-      };
+      for (i = 0; i < l; i++) {
+        leg = lines[i];
 
-      jsPDFAPI.events.push(['putFont', function (args) {
-          identityHFunction(args.font, args.out, args.newObject);
-      }]);
+        if (leg.length === 2) {
+          // simple line
+          x4 = leg[0] * scalex + x4; // here last x4 was prior ending point
 
-      var winAnsiEncodingFunction = function winAnsiEncodingFunction(font, out, newObject) {
+          y4 = leg[1] * scaley + y4; // here last y4 was prior ending point
 
-          if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === 'WinAnsiEncoding') {
-              //Tag with WinAnsi encoding
-              var widths = font.metadata.Unicode.widths;
-              var data = font.metadata.rawData;
-              var pdfOutput = data;
-              var pdfOutput2 = "";
-              for (var i = 0; i < pdfOutput.length; i++) {
-                  pdfOutput2 += String.fromCharCode(pdfOutput[i]);
-              }
-              var fontTable = newObject();
-              out('<<');
-              out('/Length ' + pdfOutput2.length);
-              out('/Length1 ' + pdfOutput2.length);
-              out('>>');
-              out('stream');
-              out(pdfOutput2);
-              out('endstream');
-              out('endobj');
-              var fontDescriptor = newObject();
-              out('<<');
-              out('/Descent ' + font.metadata.decender);
-              out('/CapHeight ' + font.metadata.capHeight);
-              out('/StemV ' + font.metadata.stemV);
-              out('/Type /FontDescriptor');
-              out('/FontFile2 ' + fontTable + ' 0 R');
-              out('/Flags 96');
-              out('/FontBBox ' + jsPDF.API.PDFObject.convert(font.metadata.bbox));
-              out('/FontName /' + font.fontName);
-              out('/ItalicAngle ' + font.metadata.italicAngle);
-              out('/Ascent ' + font.metadata.ascender);
-              out('>>');
-              out('endobj');
-              font.objectNumber = newObject();
-              for (var i = 0; i < font.metadata.hmtx.widths.length; i++) {
-                  font.metadata.hmtx.widths[i] = parseInt(font.metadata.hmtx.widths[i] * (1000 / font.metadata.head.unitsPerEm)); //Change the width of Em units to Point units.
-              }
-              out('<</Subtype/TrueType/Type/Font/BaseFont/' + font.fontName + '/FontDescriptor ' + fontDescriptor + ' 0 R' + '/Encoding/' + font.encoding + ' /FirstChar 29 /LastChar 255 /Widths ' + jsPDF.API.PDFObject.convert(font.metadata.hmtx.widths) + '>>');
-              out('endobj');
-              font.isAlreadyPutted = true;
-          }
-      };
+          lineTo(x4, y4);
+        } else {
+          // bezier curve
+          x2 = leg[0] * scalex + x4; // here last x4 is prior ending point
 
-      jsPDFAPI.events.push(['putFont', function (args) {
-          winAnsiEncodingFunction(args.font, args.out, args.newObject);
-      }]);
-
-      var utf8TextFunction = function utf8TextFunction(args) {
-          var text = args.text || '';
-          var x = args.x;
-          var y = args.y;
-          var options = args.options || {};
-          var mutex = args.mutex || {};
-
-          var pdfEscape = mutex.pdfEscape;
-          var activeFontKey = mutex.activeFontKey;
-          var fonts = mutex.fonts;
-          var key,
-              fontSize = mutex.activeFontSize;
-
-          var str = '',
-              s = 0,
-              cmapConfirm;
-          var strText = '';
-          var attr;
-          var key = activeFontKey;
-          var encoding = fonts[key].encoding;
-
-          if (fonts[key].encoding !== 'Identity-H') {
-              return {
-                  text: text,
-                  x: x,
-                  y: y,
-                  options: options,
-                  mutex: mutex
-              };
-          }
-          strText = text;
+          y2 = leg[1] * scaley + y4; // here last y4 is prior ending point
 
-          key = attr ? getFont(attr.font, attr.fontStyle) : activeFontKey;
-          if (Object.prototype.toString.call(text) === '[object Array]') {
-              strText = text[0];
-          }
-          for (s = 0; s < strText.length; s += 1) {
-              if (fonts[key].metadata.hasOwnProperty('cmap')) {
-                  cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)];
-                  /*
-                  if (Object.prototype.toString.call(text) === '[object Array]') {
-                             var i = 0;
-                            // for (i = 0; i < text.length; i += 1) {
-                                 if (Object.prototype.toString.call(text[s]) === '[object Array]') {
-                  	cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s][0].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id
-                                 } else {
-                                     
-                                 }
-                             //}
-                  
-                         } else {
-                  cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id
-                         }*/
-              }
-              if (!cmapConfirm) {
-                  if (strText[s].charCodeAt(0) < 256 && fonts[key].metadata.hasOwnProperty('Unicode')) {
-                      str += strText[s];
-                  } else {
-                      str += '';
-                  }
-              } else {
-                  str += strText[s];
-              }
-          }
-          var result = '';
-          if (parseInt(key.slice(1)) < 14 || encoding === 'WinAnsiEncoding') {
-              //For the default 13 font
-              result = toHex(pdfEscape(str, key));
-          } else if (encoding === 'Identity-H') {
-              result = pdfEscape16(str, fonts[key]);
-          }
-          mutex.isHex = true;
+          x3 = leg[2] * scalex + x4; // here last x4 is prior ending point
 
-          return {
-              text: result,
-              x: x,
-              y: y,
-              options: options,
-              mutex: mutex
-          };
-      };
+          y3 = leg[3] * scaley + y4; // here last y4 is prior ending point
 
-      var utf8EscapeFunction = function utf8EscapeFunction(parms) {
-          var text = parms.text || '',
-              x = parms.x,
-              y = parms.y,
-              options = parms.options,
-              mutex = parms.mutex;
-          var lang = options.lang;
-          var tmpText = [];
-          var args = {
-              text: text,
-              x: x,
-              y: y,
-              options: options,
-              mutex: mutex
-          };
+          x4 = leg[4] * scalex + x4; // here last x4 was prior ending point
 
-          if (Object.prototype.toString.call(text) === '[object Array]') {
-              var i = 0;
-              for (i = 0; i < text.length; i += 1) {
-                  if (Object.prototype.toString.call(text[i]) === '[object Array]') {
-                      if (text[i].length === 3) {
-                          tmpText.push([utf8TextFunction(Object.assign({}, args, { text: text[i][0] })).text, text[i][1], text[i][2]]);
-                      } else {
-                          tmpText.push(utf8TextFunction(Object.assign({}, args, { text: text[i] })).text);
-                      }
-                  } else {
-                      tmpText.push(utf8TextFunction(Object.assign({}, args, { text: text[i] })).text);
-                  }
-              }
-              parms.text = tmpText;
-          } else {
-              parms.text = utf8TextFunction(Object.assign({}, args, { text: text })).text;
-          }
-      };
+          y4 = leg[5] * scaley + y4; // here last y4 was prior ending point
 
-      jsPDFAPI.events.push(['postProcessText', utf8EscapeFunction]);
-  })(jsPDF, typeof self !== "undefined" && self || typeof global !== "undefined" && global || typeof window !== "undefined" && window || Function("return this")());
+          curveTo(x2, y2, x3, y3, x4, y4);
+        }
+      }
 
-  /**
-   * jsPDF virtual FileSystem functionality
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
+      if (closed) {
+        close();
+      }
 
-  /**
-  * Use the vFS to handle files
-  */
+      putStyle(style);
+      return this;
+    };
+    /**
+     * Similar to {@link API.lines} but all coordinates are interpreted as absolute coordinates instead of relative.
+     * @param {Array<Object>} lines An array of {op: operator, c: coordinates} object, where op is one of "m" (move to), "l" (line to)
+     * "c" (cubic bezier curve) and "h" (close (sub)path)). c is an array of coordinates. "m" and "l" expect two, "c"
+     * six and "h" an empty array (or undefined).
+     * @function
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name path
+     */
 
-  (function (jsPDFAPI) {
 
-      var vFS = {};
+    API.path = function (lines) {
+      for (var i = 0; i < lines.length; i++) {
+        var leg = lines[i];
+        var coords = leg.c;
 
-      /* Check if the file exists in the vFS
-      * @returns {boolean}
-      * @name existsFileInVFS
-      * @example
-      * doc.existsFileInVFS("someFile.txt");
-      */
-      jsPDFAPI.existsFileInVFS = function (filename) {
-          return vFS.hasOwnProperty(filename);
-      };
+        switch (leg.op) {
+          case "m":
+            moveTo(coords[0], coords[1]);
+            break;
 
-      /* Add a file to the vFS
-      * @returns {jsPDF}
-      * @name addFileToVFS
-      * @example
-      * doc.addFileToVFS("someFile.txt", "BADFACE1");
-      */
-      jsPDFAPI.addFileToVFS = function (filename, filecontent) {
-          vFS[filename] = filecontent;
-          return this;
-      };
+          case "l":
+            lineTo(coords[0], coords[1]);
+            break;
 
-      /* Get the file from the vFS
-      * @returns {string}
-      * @name addFileToVFS
-      * @example
-      * doc.getFileFromVFS("someFile.txt");
-      */
-      jsPDFAPI.getFileFromVFS = function (filename) {
-          if (vFS.hasOwnProperty(filename)) {
-              return vFS[filename];
-          }
-          return null;
-      };
-  })(jsPDF.API);
+          case "c":
+            curveTo.apply(this, coords);
+            break;
 
-  /* Blob.js
-   * A Blob implementation.
-   * 2014-07-24
-   *
-   * By Eli Grey, http://eligrey.com
-   * By Devin Samarin, https://github.com/dsamarin
-   * License: X11/MIT
-   *   See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md
-   */
+          case "h":
+            close();
+            break;
+        }
+      }
 
-  /*global self, unescape */
-  /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
-    plusplus: true */
-
-  /*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
-
-  (function (view) {
-
-  	view.URL = view.URL || view.webkitURL;
-
-  	if (view.Blob && view.URL) {
-  		try {
-  			new Blob;
-  			return;
-  		} catch (e) {}
-  	}
-
-  	// Internally we use a BlobBuilder implementation to base Blob off of
-  	// in order to support older browsers that only have BlobBuilder
-  	var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {
-  		var
-  			  get_class = function(object) {
-  				return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
-  			}
-  			, FakeBlobBuilder = function BlobBuilder() {
-  				this.data = [];
-  			}
-  			, FakeBlob = function Blob(data, type, encoding) {
-  				this.data = data;
-  				this.size = data.length;
-  				this.type = type;
-  				this.encoding = encoding;
-  			}
-  			, FBB_proto = FakeBlobBuilder.prototype
-  			, FB_proto = FakeBlob.prototype
-  			, FileReaderSync = view.FileReaderSync
-  			, FileException = function(type) {
-  				this.code = this[this.name = type];
-  			}
-  			, file_ex_codes = (
-  				  "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
-  				+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
-  			).split(" ")
-  			, file_ex_code = file_ex_codes.length
-  			, real_URL = view.URL || view.webkitURL || view
-  			, real_create_object_URL = real_URL.createObjectURL
-  			, real_revoke_object_URL = real_URL.revokeObjectURL
-  			, URL = real_URL
-  			, btoa = view.btoa
-  			, atob = view.atob
-
-  			, ArrayBuffer = view.ArrayBuffer
-  			, Uint8Array = view.Uint8Array
-
-  			, origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/
-  		;
-  		FakeBlob.fake = FB_proto.fake = true;
-  		while (file_ex_code--) {
-  			FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
-  		}
-  		// Polyfill URL
-  		if (!real_URL.createObjectURL) {
-  			URL = view.URL = function(uri) {
-  				var
-  					  uri_info = document.createElementNS("http://www.w3.org/1999/xhtml", "a")
-  					, uri_origin
-  				;
-  				uri_info.href = uri;
-  				if (!("origin" in uri_info)) {
-  					if (uri_info.protocol.toLowerCase() === "data:") {
-  						uri_info.origin = null;
-  					} else {
-  						uri_origin = uri.match(origin);
-  						uri_info.origin = uri_origin && uri_origin[1];
-  					}
-  				}
-  				return uri_info;
-  			};
-  		}
-  		URL.createObjectURL = function(blob) {
-  			var
-  				  type = blob.type
-  				, data_URI_header
-  			;
-  			if (type === null) {
-  				type = "application/octet-stream";
-  			}
-  			if (blob instanceof FakeBlob) {
-  				data_URI_header = "data:" + type;
-  				if (blob.encoding === "base64") {
-  					return data_URI_header + ";base64," + blob.data;
-  				} else if (blob.encoding === "URI") {
-  					return data_URI_header + "," + decodeURIComponent(blob.data);
-  				} if (btoa) {
-  					return data_URI_header + ";base64," + btoa(blob.data);
-  				} else {
-  					return data_URI_header + "," + encodeURIComponent(blob.data);
-  				}
-  			} else if (real_create_object_URL) {
-  				return real_create_object_URL.call(real_URL, blob);
-  			}
-  		};
-  		URL.revokeObjectURL = function(object_URL) {
-  			if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
-  				real_revoke_object_URL.call(real_URL, object_URL);
-  			}
-  		};
-  		FBB_proto.append = function(data/*, endings*/) {
-  			var bb = this.data;
-  			// decode data to a binary string
-  			if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
-  				var
-  					  str = ""
-  					, buf = new Uint8Array(data)
-  					, i = 0
-  					, buf_len = buf.length
-  				;
-  				for (; i < buf_len; i++) {
-  					str += String.fromCharCode(buf[i]);
-  				}
-  				bb.push(str);
-  			} else if (get_class(data) === "Blob" || get_class(data) === "File") {
-  				if (FileReaderSync) {
-  					var fr = new FileReaderSync;
-  					bb.push(fr.readAsBinaryString(data));
-  				} else {
-  					// async FileReader won't work as BlobBuilder is sync
-  					throw new FileException("NOT_READABLE_ERR");
-  				}
-  			} else if (data instanceof FakeBlob) {
-  				if (data.encoding === "base64" && atob) {
-  					bb.push(atob(data.data));
-  				} else if (data.encoding === "URI") {
-  					bb.push(decodeURIComponent(data.data));
-  				} else if (data.encoding === "raw") {
-  					bb.push(data.data);
-  				}
-  			} else {
-  				if (typeof data !== "string") {
-  					data += ""; // convert unsupported types to strings
-  				}
-  				// decode UTF-16 to binary string
-  				bb.push(unescape(encodeURIComponent(data)));
-  			}
-  		};
-  		FBB_proto.getBlob = function(type) {
-  			if (!arguments.length) {
-  				type = null;
-  			}
-  			return new FakeBlob(this.data.join(""), type, "raw");
-  		};
-  		FBB_proto.toString = function() {
-  			return "[object BlobBuilder]";
-  		};
-  		FB_proto.slice = function(start, end, type) {
-  			var args = arguments.length;
-  			if (args < 3) {
-  				type = null;
-  			}
-  			return new FakeBlob(
-  				  this.data.slice(start, args > 1 ? end : this.data.length)
-  				, type
-  				, this.encoding
-  			);
-  		};
-  		FB_proto.toString = function() {
-  			return "[object Blob]";
-  		};
-  		FB_proto.close = function() {
-  			this.size = 0;
-  			delete this.data;
-  		};
-  		return FakeBlobBuilder;
-  	}(view));
-
-  	view.Blob = function(blobParts, options) {
-  		var type = options ? (options.type || "") : "";
-  		var builder = new BlobBuilder();
-  		if (blobParts) {
-  			for (var i = 0, len = blobParts.length; i < len; i++) {
-  				if (Uint8Array && blobParts[i] instanceof Uint8Array) {
-  					builder.append(blobParts[i].buffer);
-  				}
-  				else {
-  					builder.append(blobParts[i]);
-  				}
-  			}
-  		}
-  		var blob = builder.getBlob(type);
-  		if (!blob.slice && blob.webkitSlice) {
-  			blob.slice = blob.webkitSlice;
-  		}
-  		return blob;
-  	};
-
-  	var getPrototypeOf = Object.getPrototypeOf || function(object) {
-  		return object.__proto__;
-  	};
-  	view.Blob.prototype = getPrototypeOf(new view.Blob());
-  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || window.content || window));
-
-  /* FileSaver.js
-   * A saveAs() FileSaver implementation.
-   * 1.3.2
-   * 2016-06-16 18:25:19
-   *
-   * By Eli Grey, http://eligrey.com
-   * License: MIT
-   *   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
-   */
+      return this;
+    };
+    /**
+     * Adds a rectangle to PDF.
+     *
+     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
+     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
+     * @param {number} w Width (in units declared at inception of PDF document)
+     * @param {number} h Height (in units declared at inception of PDF document)
+     * @param {string=} style A string specifying the painting style or null. Valid styles include:
+     * 'S' [default] - stroke,
+     * 'F' - fill,
+     * and 'DF' (or 'FD') -  fill then stroke.
+     * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple
+     * method calls. The last drawing method call used to define the shape should not have a null style argument.
+     *
+     * In "advanced" API mode this parameter is deprecated.
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name rect
+     */
 
-  /*global self */
-  /*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
-
-  /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
-
-  var saveAs = saveAs || (function(view) {
-  	// IE <10 is explicitly unsupported
-  	if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
-  		return;
-  	}
-  	var
-  		  doc = view.document
-  		  // only get URL when necessary in case Blob.js hasn't overridden it yet
-  		, get_URL = function() {
-  			return view.URL || view.webkitURL || view;
-  		}
-  		, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
-  		, can_use_save_link = "download" in save_link
-  		, click = function(node) {
-  			var event = new MouseEvent("click");
-  			node.dispatchEvent(event);
-  		}
-  		, is_safari = /constructor/i.test(view.HTMLElement) || view.safari
-  		, is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent)
-  		, throw_outside = function(ex) {
-  			(view.setImmediate || view.setTimeout)(function() {
-  				throw ex;
-  			}, 0);
-  		}
-  		, force_saveable_type = "application/octet-stream"
-  		// the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
-  		, arbitrary_revoke_timeout = 1000 * 40 // in ms
-  		, revoke = function(file) {
-  			var revoker = function() {
-  				if (typeof file === "string") { // file is an object URL
-  					get_URL().revokeObjectURL(file);
-  				} else { // file is a File
-  					file.remove();
-  				}
-  			};
-  			setTimeout(revoker, arbitrary_revoke_timeout);
-  		}
-  		, dispatch = function(filesaver, event_types, event) {
-  			event_types = [].concat(event_types);
-  			var i = event_types.length;
-  			while (i--) {
-  				var listener = filesaver["on" + event_types[i]];
-  				if (typeof listener === "function") {
-  					try {
-  						listener.call(filesaver, event || filesaver);
-  					} catch (ex) {
-  						throw_outside(ex);
-  					}
-  				}
-  			}
-  		}
-  		, auto_bom = function(blob) {
-  			// prepend BOM for UTF-8 XML and text/* types (including HTML)
-  			// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
-  			if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
-  				return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});
-  			}
-  			return blob;
-  		}
-  		, FileSaver = function(blob, name, no_auto_bom) {
-  			if (!no_auto_bom) {
-  				blob = auto_bom(blob);
-  			}
-  			// First try a.download, then web filesystem, then object URLs
-  			var
-  				  filesaver = this
-  				, type = blob.type
-  				, force = type === force_saveable_type
-  				, object_url
-  				, dispatch_all = function() {
-  					dispatch(filesaver, "writestart progress write writeend".split(" "));
-  				}
-  				// on any filesys errors revert to saving with object URLs
-  				, fs_error = function() {
-  					if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {
-  						// Safari doesn't allow downloading of blob urls
-  						var reader = new FileReader();
-  						reader.onloadend = function() {
-  							var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');
-  							var popup = view.open(url, '_blank');
-  							if(!popup) view.location.href = url;
-  							url=undefined; // release reference before dispatching
-  							filesaver.readyState = filesaver.DONE;
-  							dispatch_all();
-  						};
-  						reader.readAsDataURL(blob);
-  						filesaver.readyState = filesaver.INIT;
-  						return;
-  					}
-  					// don't create more object URLs than needed
-  					if (!object_url) {
-  						object_url = get_URL().createObjectURL(blob);
-  					}
-  					if (force) {
-  						view.location.href = object_url;
-  					} else {
-  						var opened = view.open(object_url, "_blank");
-  						if (!opened) {
-  							// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
-  							view.location.href = object_url;
-  						}
-  					}
-  					filesaver.readyState = filesaver.DONE;
-  					dispatch_all();
-  					revoke(object_url);
-  				}
-  			;
-  			filesaver.readyState = filesaver.INIT;
-
-  			if (can_use_save_link) {
-  				object_url = get_URL().createObjectURL(blob);
-  				setTimeout(function() {
-  					save_link.href = object_url;
-  					save_link.download = name;
-  					click(save_link);
-  					dispatch_all();
-  					revoke(object_url);
-  					filesaver.readyState = filesaver.DONE;
-  				});
-  				return;
-  			}
-
-  			fs_error();
-  		}
-  		, FS_proto = FileSaver.prototype
-  		, saveAs = function(blob, name, no_auto_bom) {
-  			return new FileSaver(blob, name || blob.name || "download", no_auto_bom);
-  		}
-  	;
-  	// IE 10+ (native saveAs)
-  	if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
-  		return function(blob, name, no_auto_bom) {
-  			name = name || blob.name || "download";
-
-  			if (!no_auto_bom) {
-  				blob = auto_bom(blob);
-  			}
-  			return navigator.msSaveOrOpenBlob(blob, name);
-  		};
-  	}
-
-  	FS_proto.abort = function(){};
-  	FS_proto.readyState = FS_proto.INIT = 0;
-  	FS_proto.WRITING = 1;
-  	FS_proto.DONE = 2;
-
-  	FS_proto.error =
-  	FS_proto.onwritestart =
-  	FS_proto.onprogress =
-  	FS_proto.onwrite =
-  	FS_proto.onabort =
-  	FS_proto.onerror =
-  	FS_proto.onwriteend =
-  		null;
-
-  	return saveAs;
-  }(
-  	   typeof self !== "undefined" && self
-  	|| typeof window !== "undefined" && window
-  	|| window.content
-  ));
-  // `self` is undefined in Firefox for Android content script context
-  // while `this` is nsIContentFrameMessageManager
-  // with an attribute `content` that corresponds to the window
-
-  if (typeof module !== "undefined" && module.exports) {
-    module.exports.saveAs = saveAs;
-  } else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) {
-    define("FileSaver.js", function() {
-      return saveAs;
-    });
-  }
 
-  /*
-   * Copyright (c) 2012 chick307 <chick307@gmail.com>
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
+    API.__private__.rect = API.rect = function (x, y, w, h, style) {
+      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h) || !isValidStyle(style)) {
+        throw new Error("Invalid arguments passed to jsPDF.rect");
+      }
 
-  (function(jsPDF, callback) {
-    jsPDF.API.adler32cs = callback();
-  })(jsPDF, function() {
-    var _hasArrayBuffer = typeof ArrayBuffer === 'function' &&
-      typeof Uint8Array === 'function';
+      if (apiMode === ApiMode.COMPAT) {
+        h = -h;
+      }
 
-    var _Buffer = null, _isBuffer = (function() {
-      if (!_hasArrayBuffer)
-        return function _isBuffer() { return false };
+      out([hpf(scale(x)), hpf(transformScaleY(y)), hpf(scale(w)), hpf(scale(h)), "re"].join(" "));
+      putStyle(style);
+      return this;
+    };
+    /**
+     * Adds a triangle to PDF.
+     *
+     * @param {number} x1 Coordinate (in units declared at inception of PDF document) against left edge of the page
+     * @param {number} y1 Coordinate (in units declared at inception of PDF document) against upper edge of the page
+     * @param {number} x2 Coordinate (in units declared at inception of PDF document) against left edge of the page
+     * @param {number} y2 Coordinate (in units declared at inception of PDF document) against upper edge of the page
+     * @param {number} x3 Coordinate (in units declared at inception of PDF document) against left edge of the page
+     * @param {number} y3 Coordinate (in units declared at inception of PDF document) against upper edge of the page
+     * @param {string=} style A string specifying the painting style or null. Valid styles include:
+     * 'S' [default] - stroke,
+     * 'F' - fill,
+     * and 'DF' (or 'FD') -  fill then stroke.
+     * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple
+     * method calls. The last drawing method call used to define the shape should not have a null style argument.
+     *
+     * In "advanced" API mode this parameter is deprecated.
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name triangle
+     */
 
-      try {
-        var buffer = {};
-        if (typeof buffer.Buffer === 'function')
-          _Buffer = buffer.Buffer;
-      } catch (error) {}
-
-      return function _isBuffer(value) {
-        return value instanceof ArrayBuffer ||
-          _Buffer !== null && value instanceof _Buffer;
-      };
-    }());
 
-    var _utf8ToBinary = (function() {
-      if (_Buffer !== null) {
-        return function _utf8ToBinary(utf8String) {
-          return new _Buffer(utf8String, 'utf8').toString('binary');
-        };
-      } else {
-        return function _utf8ToBinary(utf8String) {
-          return unescape(encodeURIComponent(utf8String));
-        };
+    API.__private__.triangle = API.triangle = function (x1, y1, x2, y2, x3, y3, style) {
+      if (isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2) || isNaN(x3) || isNaN(y3) || !isValidStyle(style)) {
+        throw new Error("Invalid arguments passed to jsPDF.triangle");
       }
-    }());
 
-    var MOD = 65521;
+      this.lines([[x2 - x1, y2 - y1], // vector to point 2
+      [x3 - x2, y3 - y2], // vector to point 3
+      [x1 - x3, y1 - y3] // closing vector back to point 1
+      ], x1, y1, // start of path
+      [1, 1], style, true);
+      return this;
+    };
+    /**
+     * Adds a rectangle with rounded corners to PDF.
+     *
+     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
+     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
+     * @param {number} w Width (in units declared at inception of PDF document)
+     * @param {number} h Height (in units declared at inception of PDF document)
+     * @param {number} rx Radius along x axis (in units declared at inception of PDF document)
+     * @param {number} ry Radius along y axis (in units declared at inception of PDF document)
+     * @param {string=} style A string specifying the painting style or null. Valid styles include:
+     * 'S' [default] - stroke,
+     * 'F' - fill,
+     * and 'DF' (or 'FD') -  fill then stroke.
+     * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple
+     * method calls. The last drawing method call used to define the shape should not have a null style argument.
+     *
+     * In "advanced" API mode this parameter is deprecated.
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name roundedRect
+     */
+
 
-    var _update = function _update(checksum, binaryString) {
-      var a = checksum & 0xFFFF, b = checksum >>> 16;
-      for (var i = 0, length = binaryString.length; i < length; i++) {
-        a = (a + (binaryString.charCodeAt(i) & 0xFF)) % MOD;
-        b = (b + a) % MOD;
+    API.__private__.roundedRect = API.roundedRect = function (x, y, w, h, rx, ry, style) {
+      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h) || isNaN(rx) || isNaN(ry) || !isValidStyle(style)) {
+        throw new Error("Invalid arguments passed to jsPDF.roundedRect");
       }
-      return (b << 16 | a) >>> 0;
+
+      var MyArc = 4 / 3 * (Math.SQRT2 - 1);
+      rx = Math.min(rx, w * 0.5);
+      ry = Math.min(ry, h * 0.5);
+      this.lines([[w - 2 * rx, 0], [rx * MyArc, 0, rx, ry - ry * MyArc, rx, ry], [0, h - 2 * ry], [0, ry * MyArc, -(rx * MyArc), ry, -rx, ry], [-w + 2 * rx, 0], [-(rx * MyArc), 0, -rx, -(ry * MyArc), -rx, -ry], [0, -h + 2 * ry], [0, -(ry * MyArc), rx * MyArc, -ry, rx, -ry]], x + rx, y, // start of path
+      [1, 1], style, true);
+      return this;
     };
+    /**
+     * Adds an ellipse to PDF.
+     *
+     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
+     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
+     * @param {number} rx Radius along x axis (in units declared at inception of PDF document)
+     * @param {number} ry Radius along y axis (in units declared at inception of PDF document)
+     * @param {string=} style A string specifying the painting style or null. Valid styles include:
+     * 'S' [default] - stroke,
+     * 'F' - fill,
+     * and 'DF' (or 'FD') -  fill then stroke.
+     * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple
+     * method calls. The last drawing method call used to define the shape should not have a null style argument.
+     *
+     * In "advanced" API mode this parameter is deprecated.
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name ellipse
+     */
+
 
-    var _updateUint8Array = function _updateUint8Array(checksum, uint8Array) {
-      var a = checksum & 0xFFFF, b = checksum >>> 16;
-      for (var i = 0, length = uint8Array.length; i < length; i++) {
-        a = (a + uint8Array[i]) % MOD;
-        b = (b + a) % MOD;
+    API.__private__.ellipse = API.ellipse = function (x, y, rx, ry, style) {
+      if (isNaN(x) || isNaN(y) || isNaN(rx) || isNaN(ry) || !isValidStyle(style)) {
+        throw new Error("Invalid arguments passed to jsPDF.ellipse");
       }
-      return (b << 16 | a) >>> 0
+
+      var lx = 4 / 3 * (Math.SQRT2 - 1) * rx,
+          ly = 4 / 3 * (Math.SQRT2 - 1) * ry;
+      moveTo(x + rx, y);
+      curveTo(x + rx, y - ly, x + lx, y - ry, x, y - ry);
+      curveTo(x - lx, y - ry, x - rx, y - ly, x - rx, y);
+      curveTo(x - rx, y + ly, x - lx, y + ry, x, y + ry);
+      curveTo(x + lx, y + ry, x + rx, y + ly, x + rx, y);
+      putStyle(style);
+      return this;
     };
+    /**
+     * Adds an circle to PDF.
+     *
+     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
+     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
+     * @param {number} r Radius (in units declared at inception of PDF document)
+     * @param {string=} style A string specifying the painting style or null. Valid styles include:
+     * 'S' [default] - stroke,
+     * 'F' - fill,
+     * and 'DF' (or 'FD') -  fill then stroke.
+     * In "compat" API mode, a null value postpones setting the style so that a shape may be composed using multiple
+     * method calls. The last drawing method call used to define the shape should not have a null style argument.
+     *
+     * In "advanced" API mode this parameter is deprecated.
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name circle
+     */
 
-    var exports = {};
 
-    var Adler32 = exports.Adler32 = (function() {
-      var ctor = function Adler32(checksum) {
-        if (!(this instanceof ctor)) {
-          throw new TypeError(
-            'Constructor cannot called be as a function.');
-        }
-        if (!isFinite(checksum = checksum == null ? 1 : +checksum)) {
-          throw new Error(
-            'First arguments needs to be a finite number.');
-        }
-        this.checksum = checksum >>> 0;
-      };
+    API.__private__.circle = API.circle = function (x, y, r, style) {
+      if (isNaN(x) || isNaN(y) || isNaN(r) || !isValidStyle(style)) {
+        throw new Error("Invalid arguments passed to jsPDF.circle");
+      }
 
-      var proto = ctor.prototype = {};
-      proto.constructor = ctor;
+      return this.ellipse(x, y, r, r, style);
+    };
+    /**
+     * Sets text font face, variant for upcoming text elements.
+     * See output of jsPDF.getFontList() for possible font names, styles.
+     *
+     * @param {string} fontName Font name or family. Example: "times".
+     * @param {string} fontStyle Font style or variant. Example: "italic".
+     * @param {number | string} fontWeight Weight of the Font. Example: "normal" | 400
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name setFont
+     */
 
-      ctor.from = function(from) {
-        from.prototype = proto;
-        return from;
-      }(function from(binaryString) {
-        if (!(this instanceof ctor)) {
-          throw new TypeError(
-            'Constructor cannot called be as a function.');
-        }
-        if (binaryString == null)
-          throw new Error('First argument needs to be a string.');
-        this.checksum = _update(1, binaryString.toString());
-      });
 
-      ctor.fromUtf8 = function(fromUtf8) {
-        fromUtf8.prototype = proto;
-        return fromUtf8;
-      }(function fromUtf8(utf8String) {
-        if (!(this instanceof ctor)) {
-          throw new TypeError(
-            'Constructor cannot called be as a function.');
-        }
-        if (utf8String == null)
-          throw new Error('First argument needs to be a string.');
-        var binaryString = _utf8ToBinary(utf8String.toString());
-        this.checksum = _update(1, binaryString);
-      });
+    API.setFont = function (fontName, fontStyle, fontWeight) {
+      if (fontWeight) {
+        fontStyle = combineFontStyleAndFontWeight(fontStyle, fontWeight);
+      }
 
-      if (_hasArrayBuffer) {
-        ctor.fromBuffer = function(fromBuffer) {
-          fromBuffer.prototype = proto;
-          return fromBuffer;
-        }(function fromBuffer(buffer) {
-          if (!(this instanceof ctor)) {
-            throw new TypeError(
-              'Constructor cannot called be as a function.');
-          }
-          if (!_isBuffer(buffer))
-            throw new Error('First argument needs to be ArrayBuffer.');
-          var array = new Uint8Array(buffer);
-          return this.checksum = _updateUint8Array(1, array);
-        });
-      }
+      activeFontKey = getFont(fontName, fontStyle, {
+        disableWarning: false
+      });
+      return this;
+    };
+    /**
+     * Gets text font face, variant for upcoming text elements.
+     *
+     * @function
+     * @instance
+     * @returns {Object}
+     * @memberof jsPDF#
+     * @name getFont
+     */
 
-      proto.update = function update(binaryString) {
-        if (binaryString == null)
-          throw new Error('First argument needs to be a string.');
-        binaryString = binaryString.toString();
-        return this.checksum = _update(this.checksum, binaryString);
-      };
 
-      proto.updateUtf8 = function updateUtf8(utf8String) {
-        if (utf8String == null)
-          throw new Error('First argument needs to be a string.');
-        var binaryString = _utf8ToBinary(utf8String.toString());
-        return this.checksum = _update(this.checksum, binaryString);
-      };
+    var getFontEntry = API.__private__.getFont = API.getFont = function () {
+      return fonts[getFont.apply(API, arguments)];
+    };
+    /**
+     * Returns an object - a tree of fontName to fontStyle relationships available to
+     * active PDF document.
+     *
+     * @public
+     * @function
+     * @instance
+     * @returns {Object} Like {'times':['normal', 'italic', ... ], 'arial':['normal', 'bold', ... ], ... }
+     * @memberof jsPDF#
+     * @name getFontList
+     */
 
-      if (_hasArrayBuffer) {
-        proto.updateBuffer = function updateBuffer(buffer) {
-          if (!_isBuffer(buffer))
-            throw new Error('First argument needs to be ArrayBuffer.');
-          var array = new Uint8Array(buffer);
-          return this.checksum = _updateUint8Array(this.checksum, array);
-        };
-      }
 
-      proto.clone = function clone() {
-        return new Adler32(this.checksum);
-      };
+    API.__private__.getFontList = API.getFontList = function () {
+      var list = {},
+          fontName,
+          fontStyle;
 
-      return ctor;
-    }());
+      for (fontName in fontmap) {
+        if (fontmap.hasOwnProperty(fontName)) {
+          list[fontName] = [];
 
-    exports.from = function from(binaryString) {
-      if (binaryString == null)
-        throw new Error('First argument needs to be a string.');
-      return _update(1, binaryString.toString());
-    };
+          for (fontStyle in fontmap[fontName]) {
+            if (fontmap[fontName].hasOwnProperty(fontStyle)) {
+              list[fontName].push(fontStyle);
+            }
+          }
+        }
+      }
 
-    exports.fromUtf8 = function fromUtf8(utf8String) {
-      if (utf8String == null)
-        throw new Error('First argument needs to be a string.');
-      var binaryString = _utf8ToBinary(utf8String.toString());
-      return _update(1, binaryString);
+      return list;
     };
+    /**
+     * Add a custom font to the current instance.
+     *
+     * @param {string} postScriptName PDF specification full name for the font.
+     * @param {string} id PDF-document-instance-specific label assinged to the font.
+     * @param {string} fontStyle Style of the Font.
+     * @param {number | string} fontWeight Weight of the Font.
+     * @param {Object} encoding Encoding_name-to-Font_metrics_object mapping.
+     * @function
+     * @instance
+     * @memberof jsPDF#
+     * @name addFont
+     * @returns {string} fontId
+     */
 
-    if (_hasArrayBuffer) {
-      exports.fromBuffer = function fromBuffer(buffer) {
-        if (!_isBuffer(buffer))
-          throw new Error('First argument need to be ArrayBuffer.');
-        var array = new Uint8Array(buffer);
-        return _updateUint8Array(1, array);
-      };
-    }
-
-    return exports;
-  });
-
-  // (c) Dean McNamee <dean@gmail.com>, 2013.
-  //
-  // https://github.com/deanm/omggif
-  //
-  // 
-  //
-  // omggif is a JavaScript implementation of a GIF 89a encoder and decoder,
-  // including animation and compression.  It does not rely on any specific
-  // underlying system, so should run in the browser, Node, or Plask.
-
-  function GifWriter(buf, width, height, gopts) {
-    var p = 0;
-
-    var gopts = gopts === undefined ? { } : gopts;
-    var loop_count = gopts.loop === undefined ? null : gopts.loop;
-    var global_palette = gopts.palette === undefined ? null : gopts.palette;
-
-    if (width <= 0 || height <= 0 || width > 65535 || height > 65535)
-      throw "Width/Height invalid."
-
-    function check_palette_and_num_colors(palette) {
-      var num_colors = palette.length;
-      if (num_colors < 2 || num_colors > 256 ||  num_colors & (num_colors-1))
-        throw "Invalid code/color length, must be power of 2 and 2 .. 256.";
-      return num_colors;
-    }
 
-    // - Header.
-    buf[p++] = 0x47; buf[p++] = 0x49; buf[p++] = 0x46;  // GIF
-    buf[p++] = 0x38; buf[p++] = 0x39; buf[p++] = 0x61;  // 89a
-
-    // Handling of Global Color Table (palette) and background index.
-    var gp_num_colors_pow2 = 0;
-    var background = 0;
-    if (global_palette !== null) {
-      var gp_num_colors = check_palette_and_num_colors(global_palette);
-      while (gp_num_colors >>= 1) ++gp_num_colors_pow2;
-      gp_num_colors = 1 << gp_num_colors_pow2;
-      --gp_num_colors_pow2;
-      if (gopts.background !== undefined) {
-        background = gopts.background;
-        if (background >= gp_num_colors) throw "Background index out of range.";
-        // The GIF spec states that a background index of 0 should be ignored, so
-        // this is probably a mistake and you really want to set it to another
-        // slot in the palette.  But actually in the end most browsers, etc end
-        // up ignoring this almost completely (including for dispose background).
-        if (background === 0)
-          throw "Background index explicitly passed as 0.";
-      }
-    }
+    API.addFont = function (postScriptName, fontName, fontStyle, fontWeight, encoding) {
+      var encodingOptions = ["StandardEncoding", "MacRomanEncoding", "Identity-H", "WinAnsiEncoding"];
 
-    // - Logical Screen Descriptor.
-    // NOTE(deanm): w/h apparently ignored by implementations, but set anyway.
-    buf[p++] = width & 0xff; buf[p++] = width >> 8 & 0xff;
-    buf[p++] = height & 0xff; buf[p++] = height >> 8 & 0xff;
-    // NOTE: Indicates 0-bpp original color resolution (unused?).
-    buf[p++] = (global_palette !== null ? 0x80 : 0) |  // Global Color Table Flag.
-               gp_num_colors_pow2;  // NOTE: No sort flag (unused?).
-    buf[p++] = background;  // Background Color Index.
-    buf[p++] = 0;  // Pixel aspect ratio (unused?).
-
-    // - Global Color Table
-    if (global_palette !== null) {
-      for (var i = 0, il = global_palette.length; i < il; ++i) {
-        var rgb = global_palette[i];
-        buf[p++] = rgb >> 16 & 0xff;
-        buf[p++] = rgb >> 8 & 0xff;
-        buf[p++] = rgb & 0xff;
+      if (arguments[3] && encodingOptions.indexOf(arguments[3]) !== -1) {
+        //IE 11 fix
+        encoding = arguments[3];
+      } else if (arguments[3] && encodingOptions.indexOf(arguments[3]) == -1) {
+        fontStyle = combineFontStyleAndFontWeight(fontStyle, fontWeight);
       }
-    }
 
-    if (loop_count !== null) {  // Netscape block for looping.
-      if (loop_count < 0 || loop_count > 65535)
-        throw "Loop count invalid."
-      // Extension code, label, and length.
-      buf[p++] = 0x21; buf[p++] = 0xff; buf[p++] = 0x0b;
-      // NETSCAPE2.0
-      buf[p++] = 0x4e; buf[p++] = 0x45; buf[p++] = 0x54; buf[p++] = 0x53;
-      buf[p++] = 0x43; buf[p++] = 0x41; buf[p++] = 0x50; buf[p++] = 0x45;
-      buf[p++] = 0x32; buf[p++] = 0x2e; buf[p++] = 0x30;
-      // Sub-block
-      buf[p++] = 0x03; buf[p++] = 0x01;
-      buf[p++] = loop_count & 0xff; buf[p++] = loop_count >> 8 & 0xff;
-      buf[p++] = 0x00;  // Terminator.
-    }
+      encoding = encoding || "Identity-H";
+      return addFont.call(this, postScriptName, fontName, fontStyle, encoding);
+    };
 
+    var lineWidth = options.lineWidth || 0.200025; // 2mm
 
-    var ended = false;
+    /**
+     * Gets the line width, default: 0.200025.
+     *
+     * @function
+     * @instance
+     * @returns {number} lineWidth
+     * @memberof jsPDF#
+     * @name getLineWidth
+     */
 
-    this.addFrame = function(x, y, w, h, indexed_pixels, opts) {
-      if (ended === true) { --p; ended = false; }  // Un-end.
+    var getLineWidth = API.__private__.getLineWidth = API.getLineWidth = function () {
+      return lineWidth;
+    };
+    /**
+     * Sets line width for upcoming lines.
+     *
+     * @param {number} width Line width (in units declared at inception of PDF document).
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name setLineWidth
+     */
 
-      opts = opts === undefined ? { } : opts;
 
-      // TODO(deanm): Bounds check x, y.  Do they need to be within the virtual
-      // canvas width/height, I imagine?
-      if (x < 0 || y < 0 || x > 65535 || y > 65535)
-        throw "x/y invalid."
+    var setLineWidth = API.__private__.setLineWidth = API.setLineWidth = function (width) {
+      lineWidth = width;
+      out(hpf(scale(width)) + " w");
+      return this;
+    };
+    /**
+     * Sets the dash pattern for upcoming lines.
+     *
+     * To reset the settings simply call the method without any parameters.
+     * @param {Array<number>} dashArray An array containing 0-2 numbers. The first number sets the length of the
+     * dashes, the second number the length of the gaps. If the second number is missing, the gaps are considered
+     * to be as long as the dashes. An empty array means solid, unbroken lines.
+     * @param {number} dashPhase The phase lines start with.
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name setLineDashPattern
+     */
 
-      if (w <= 0 || h <= 0 || w > 65535 || h > 65535)
-        throw "Width/Height invalid."
 
-      if (indexed_pixels.length < w * h)
-        throw "Not enough pixels for the frame size.";
+    API.__private__.setLineDash = jsPDF.API.setLineDash = jsPDF.API.setLineDashPattern = function (dashArray, dashPhase) {
+      dashArray = dashArray || [];
+      dashPhase = dashPhase || 0;
 
-      var using_local_palette = true;
-      var palette = opts.palette;
-      if (palette === undefined || palette === null) {
-        using_local_palette = false;
-        palette = global_palette;
+      if (isNaN(dashPhase) || !Array.isArray(dashArray)) {
+        throw new Error("Invalid arguments passed to jsPDF.setLineDash");
       }
 
-      if (palette === undefined || palette === null)
-        throw "Must supply either a local or global palette.";
+      dashArray = dashArray.map(function (x) {
+        return hpf(scale(x));
+      }).join(" ");
+      dashPhase = hpf(scale(dashPhase));
+      out("[" + dashArray + "] " + dashPhase + " d");
+      return this;
+    };
 
-      var num_colors = check_palette_and_num_colors(palette);
+    var lineHeightFactor;
+
+    var getLineHeight = API.__private__.getLineHeight = API.getLineHeight = function () {
+      return activeFontSize * lineHeightFactor;
+    };
 
-      // Compute the min_code_size (power of 2), destroying num_colors.
-      var min_code_size = 0;
-      while (num_colors >>= 1) ++min_code_size;
-      num_colors = 1 << min_code_size;  // Now we can easily get it back.
+    API.__private__.getLineHeight = API.getLineHeight = function () {
+      return activeFontSize * lineHeightFactor;
+    };
+    /**
+     * Sets the LineHeightFactor of proportion.
+     *
+     * @param {number} value LineHeightFactor value. Default: 1.15.
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name setLineHeightFactor
+     */
 
-      var delay = opts.delay === undefined ? 0 : opts.delay;
 
-      // From the spec:
-      //     0 -   No disposal specified. The decoder is
-      //           not required to take any action.
-      //     1 -   Do not dispose. The graphic is to be left
-      //           in place.
-      //     2 -   Restore to background color. The area used by the
-      //           graphic must be restored to the background color.
-      //     3 -   Restore to previous. The decoder is required to
-      //           restore the area overwritten by the graphic with
-      //           what was there prior to rendering the graphic.
-      //  4-7 -    To be defined.
-      // NOTE(deanm): Dispose background doesn't really work, apparently most
-      // browsers ignore the background palette index and clear to transparency.
-      var disposal = opts.disposal === undefined ? 0 : opts.disposal;
-      if (disposal < 0 || disposal > 3)  // 4-7 is reserved.
-        throw "Disposal out of range.";
+    var setLineHeightFactor = API.__private__.setLineHeightFactor = API.setLineHeightFactor = function (value) {
+      value = value || 1.15;
 
-      var use_transparency = false;
-      var transparent_index = 0;
-      if (opts.transparent !== undefined && opts.transparent !== null) {
-        use_transparency = true;
-        transparent_index = opts.transparent;
-        if (transparent_index < 0 || transparent_index >= num_colors)
-          throw "Transparent color index.";
+      if (typeof value === "number") {
+        lineHeightFactor = value;
       }
 
-      if (disposal !== 0 || use_transparency || delay !== 0) {
-        // - Graphics Control Extension
-        buf[p++] = 0x21; buf[p++] = 0xf9;  // Extension / Label.
-        buf[p++] = 4;  // Byte size.
+      return this;
+    };
+    /**
+     * Gets the LineHeightFactor, default: 1.15.
+     *
+     * @function
+     * @instance
+     * @returns {number} lineHeightFactor
+     * @memberof jsPDF#
+     * @name getLineHeightFactor
+     */
 
-        buf[p++] = disposal << 2 | (use_transparency === true ? 1 : 0);
-        buf[p++] = delay & 0xff; buf[p++] = delay >> 8 & 0xff;
-        buf[p++] = transparent_index;  // Transparent color index.
-        buf[p++] = 0;  // Block Terminator.
-      }
 
-      // - Image Descriptor
-      buf[p++] = 0x2c;  // Image Seperator.
-      buf[p++] = x & 0xff; buf[p++] = x >> 8 & 0xff;  // Left.
-      buf[p++] = y & 0xff; buf[p++] = y >> 8 & 0xff;  // Top.
-      buf[p++] = w & 0xff; buf[p++] = w >> 8 & 0xff;
-      buf[p++] = h & 0xff; buf[p++] = h >> 8 & 0xff;
-      // NOTE: No sort flag (unused?).
-      // TODO(deanm): Support interlace.
-      buf[p++] = using_local_palette === true ? (0x80 | (min_code_size-1)) : 0;
+    var getLineHeightFactor = API.__private__.getLineHeightFactor = API.getLineHeightFactor = function () {
+      return lineHeightFactor;
+    };
 
-      // - Local Color Table
-      if (using_local_palette === true) {
-        for (var i = 0, il = palette.length; i < il; ++i) {
-          var rgb = palette[i];
-          buf[p++] = rgb >> 16 & 0xff;
-          buf[p++] = rgb >> 8 & 0xff;
-          buf[p++] = rgb & 0xff;
-        }
-      }
+    setLineHeightFactor(options.lineHeight);
 
-      p = GifWriterOutputLZWCodeStream(
-              buf, p, min_code_size < 2 ? 2 : min_code_size, indexed_pixels);
+    var getHorizontalCoordinate = API.__private__.getHorizontalCoordinate = function (value) {
+      return scale(value);
     };
 
-    this.end = function() {
-      if (ended === false) {
-        buf[p++] = 0x3b;  // Trailer.
-        ended = true;
+    var getVerticalCoordinate = API.__private__.getVerticalCoordinate = function (value) {
+      if (apiMode === ApiMode.ADVANCED) {
+        return value;
+      } else {
+        var pageHeight = pagesContext[currentPage].mediaBox.topRightY - pagesContext[currentPage].mediaBox.bottomLeftY;
+        return pageHeight - scale(value);
       }
-      return p;
     };
-  }
 
-  // Main compression routine, palette indexes -> LZW code stream.
-  // |index_stream| must have at least one entry.
-  function GifWriterOutputLZWCodeStream(buf, p, min_code_size, index_stream) {
-    buf[p++] = min_code_size;
-    var cur_subblock = p++;  // Pointing at the length field.
+    var getHorizontalCoordinateString = API.__private__.getHorizontalCoordinateString = API.getHorizontalCoordinateString = function (value) {
+      return hpf(getHorizontalCoordinate(value));
+    };
 
-    var clear_code = 1 << min_code_size;
-    var code_mask = clear_code - 1;
-    var eoi_code = clear_code + 1;
-    var next_code = eoi_code + 1;
+    var getVerticalCoordinateString = API.__private__.getVerticalCoordinateString = API.getVerticalCoordinateString = function (value) {
+      return hpf(getVerticalCoordinate(value));
+    };
 
-    var cur_code_size = min_code_size + 1;  // Number of bits per code.
-    var cur_shift = 0;
-    // We have at most 12-bit codes, so we should have to hold a max of 19
-    // bits here (and then we would write out).
-    var cur = 0;
+    var strokeColor = options.strokeColor || "0 G";
+    /**
+     *  Gets the stroke color for upcoming elements.
+     *
+     * @function
+     * @instance
+     * @returns {string} colorAsHex
+     * @memberof jsPDF#
+     * @name getDrawColor
+     */
 
-    function emit_bytes_to_buffer(bit_block_size) {
-      while (cur_shift >= bit_block_size) {
-        buf[p++] = cur & 0xff;
-        cur >>= 8; cur_shift -= 8;
-        if (p === cur_subblock + 256) {  // Finished a subblock.
-          buf[cur_subblock] = 255;
-          cur_subblock = p++;
-        }
-      }
-    }
+    API.__private__.getStrokeColor = API.getDrawColor = function () {
+      return decodeColorString(strokeColor);
+    };
+    /**
+     * Sets the stroke color for upcoming elements.
+     *
+     * Depending on the number of arguments given, Gray, RGB, or CMYK
+     * color space is implied.
+     *
+     * When only ch1 is given, "Gray" color space is implied and it
+     * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
+     * if values are communicated as String types, or in range from 0 (black)
+     * to 255 (white) if communicated as Number type.
+     * The RGB-like 0-255 range is provided for backward compatibility.
+     *
+     * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
+     * value must be in the range from 0.00 (minimum intensity) to to 1.00
+     * (max intensity) if values are communicated as String types, or
+     * from 0 (min intensity) to to 255 (max intensity) if values are communicated
+     * as Number types.
+     * The RGB-like 0-255 range is provided for backward compatibility.
+     *
+     * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
+     * value must be a in the range from 0.00 (0% concentration) to to
+     * 1.00 (100% concentration)
+     *
+     * Because JavaScript treats fixed point numbers badly (rounds to
+     * floating point nearest to binary representation) it is highly advised to
+     * communicate the fractional numbers as String types, not JavaScript Number type.
+     *
+     * @param {Number|String} ch1 Color channel value or {string} ch1 color value in hexadecimal, example: '#FFFFFF'.
+     * @param {Number} ch2 Color channel value.
+     * @param {Number} ch3 Color channel value.
+     * @param {Number} ch4 Color channel value.
+     *
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name setDrawColor
+     */
 
-    function emit_code(c) {
-      cur |= c << cur_shift;
-      cur_shift += cur_code_size;
-      emit_bytes_to_buffer(8);
-    }
 
-    // I am not an expert on the topic, and I don't want to write a thesis.
-    // However, it is good to outline here the basic algorithm and the few data
-    // structures and optimizations here that make this implementation fast.
-    // The basic idea behind LZW is to build a table of previously seen runs
-    // addressed by a short id (herein called output code).  All data is
-    // referenced by a code, which represents one or more values from the
-    // original input stream.  All input bytes can be referenced as the same
-    // value as an output code.  So if you didn't want any compression, you
-    // could more or less just output the original bytes as codes (there are
-    // some details to this, but it is the idea).  In order to achieve
-    // compression, values greater then the input range (codes can be up to
-    // 12-bit while input only 8-bit) represent a sequence of previously seen
-    // inputs.  The decompressor is able to build the same mapping while
-    // decoding, so there is always a shared common knowledge between the
-    // encoding and decoder, which is also important for "timing" aspects like
-    // how to handle variable bit width code encoding.
-    //
-    // One obvious but very important consequence of the table system is there
-    // is always a unique id (at most 12-bits) to map the runs.  'A' might be
-    // 4, then 'AA' might be 10, 'AAA' 11, 'AAAA' 12, etc.  This relationship
-    // can be used for an effecient lookup strategy for the code mapping.  We
-    // need to know if a run has been seen before, and be able to map that run
-    // to the output code.  Since we start with known unique ids (input bytes),
-    // and then from those build more unique ids (table entries), we can
-    // continue this chain (almost like a linked list) to always have small
-    // integer values that represent the current byte chains in the encoder.
-    // This means instead of tracking the input bytes (AAAABCD) to know our
-    // current state, we can track the table entry for AAAABC (it is guaranteed
-    // to exist by the nature of the algorithm) and the next character D.
-    // Therefor the tuple of (table_entry, byte) is guaranteed to also be
-    // unique.  This allows us to create a simple lookup key for mapping input
-    // sequences to codes (table indices) without having to store or search
-    // any of the code sequences.  So if 'AAAA' has a table entry of 12, the
-    // tuple of ('AAAA', K) for any input byte K will be unique, and can be our
-    // key.  This leads to a integer value at most 20-bits, which can always
-    // fit in an SMI value and be used as a fast sparse array / object key.
-
-    // Output code for the current contents of the index buffer.
-    var ib_code = index_stream[0] & code_mask;  // Load first input index.
-    var code_table = { };  // Key'd on our 20-bit "tuple".
-
-    emit_code(clear_code);  // Spec says first code should be a clear code.
-
-    // First index already loaded, process the rest of the stream.
-    for (var i = 1, il = index_stream.length; i < il; ++i) {
-      var k = index_stream[i] & code_mask;
-      var cur_key = ib_code << 8 | k;  // (prev, k) unique tuple.
-      var cur_code = code_table[cur_key];  // buffer + k.
-
-      // Check if we have to create a new code table entry.
-      if (cur_code === undefined) {  // We don't have buffer + k.
-        // Emit index buffer (without k).
-        // This is an inline version of emit_code, because this is the core
-        // writing routine of the compressor (and V8 cannot inline emit_code
-        // because it is a closure here in a different context).  Additionally
-        // we can call emit_byte_to_buffer less often, because we can have
-        // 30-bits (from our 31-bit signed SMI), and we know our codes will only
-        // be 12-bits, so can safely have 18-bits there without overflow.
-        // emit_code(ib_code);
-        cur |= ib_code << cur_shift;
-        cur_shift += cur_code_size;
-        while (cur_shift >= 8) {
-          buf[p++] = cur & 0xff;
-          cur >>= 8; cur_shift -= 8;
-          if (p === cur_subblock + 256) {  // Finished a subblock.
-            buf[cur_subblock] = 255;
-            cur_subblock = p++;
-          }
-        }
+    API.__private__.setStrokeColor = API.setDrawColor = function (ch1, ch2, ch3, ch4) {
+      var options = {
+        ch1: ch1,
+        ch2: ch2,
+        ch3: ch3,
+        ch4: ch4,
+        pdfColorType: "draw",
+        precision: 2
+      };
+      strokeColor = encodeColorString(options);
+      out(strokeColor);
+      return this;
+    };
 
-        if (next_code === 4096) {  // Table full, need a clear.
-          emit_code(clear_code);
-          next_code = eoi_code + 1;
-          cur_code_size = min_code_size + 1;
-          code_table = { };
-        } else {  // Table not full, insert a new entry.
-          // Increase our variable bit code sizes if necessary.  This is a bit
-          // tricky as it is based on "timing" between the encoding and
-          // decoder.  From the encoders perspective this should happen after
-          // we've already emitted the index buffer and are about to create the
-          // first table entry that would overflow our current code bit size.
-          if (next_code >= (1 << cur_code_size)) ++cur_code_size;
-          code_table[cur_key] = next_code++;  // Insert into code table.
-        }
+    var fillColor = options.fillColor || "0 g";
+    /**
+     * Gets the fill color for upcoming elements.
+     *
+     * @function
+     * @instance
+     * @returns {string} colorAsHex
+     * @memberof jsPDF#
+     * @name getFillColor
+     */
 
-        ib_code = k;  // Index buffer to single input k.
-      } else {
-        ib_code = cur_code;  // Index buffer to sequence in code table.
-      }
-    }
+    API.__private__.getFillColor = API.getFillColor = function () {
+      return decodeColorString(fillColor);
+    };
+    /**
+     * Sets the fill color for upcoming elements.
+     *
+     * Depending on the number of arguments given, Gray, RGB, or CMYK
+     * color space is implied.
+     *
+     * When only ch1 is given, "Gray" color space is implied and it
+     * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
+     * if values are communicated as String types, or in range from 0 (black)
+     * to 255 (white) if communicated as Number type.
+     * The RGB-like 0-255 range is provided for backward compatibility.
+     *
+     * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
+     * value must be in the range from 0.00 (minimum intensity) to to 1.00
+     * (max intensity) if values are communicated as String types, or
+     * from 0 (min intensity) to to 255 (max intensity) if values are communicated
+     * as Number types.
+     * The RGB-like 0-255 range is provided for backward compatibility.
+     *
+     * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
+     * value must be a in the range from 0.00 (0% concentration) to to
+     * 1.00 (100% concentration)
+     *
+     * Because JavaScript treats fixed point numbers badly (rounds to
+     * floating point nearest to binary representation) it is highly advised to
+     * communicate the fractional numbers as String types, not JavaScript Number type.
+     *
+     * @param {Number|String} ch1 Color channel value or {string} ch1 color value in hexadecimal, example: '#FFFFFF'.
+     * @param {Number} ch2 Color channel value.
+     * @param {Number} ch3 Color channel value.
+     * @param {Number} ch4 Color channel value.
+     *
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name setFillColor
+     */
 
-    emit_code(ib_code);  // There will still be something in the index buffer.
-    emit_code(eoi_code);  // End Of Information.
 
-    // Flush / finalize the sub-blocks stream to the buffer.
-    emit_bytes_to_buffer(1);
+    API.__private__.setFillColor = API.setFillColor = function (ch1, ch2, ch3, ch4) {
+      var options = {
+        ch1: ch1,
+        ch2: ch2,
+        ch3: ch3,
+        ch4: ch4,
+        pdfColorType: "fill",
+        precision: 2
+      };
+      fillColor = encodeColorString(options);
+      out(fillColor);
+      return this;
+    };
 
-    // Finish the sub-blocks, writing out any unfinished lengths and
-    // terminating with a sub-block of length 0.  If we have already started
-    // but not yet used a sub-block it can just become the terminator.
-    if (cur_subblock + 1 === p) {  // Started but unused.
-      buf[cur_subblock] = 0;
-    } else {  // Started and used, write length and additional terminator block.
-      buf[cur_subblock] = p - cur_subblock - 1;
-      buf[p++] = 0;
-    }
-    return p;
-  }
+    var textColor = options.textColor || "0 g";
+    /**
+     * Gets the text color for upcoming elements.
+     *
+     * @function
+     * @instance
+     * @returns {string} colorAsHex
+     * @memberof jsPDF#
+     * @name getTextColor
+     */
 
-  function GifReader(buf) {
-    var p = 0;
+    var getTextColor = API.__private__.getTextColor = API.getTextColor = function () {
+      return decodeColorString(textColor);
+    };
+    /**
+     * Sets the text color for upcoming elements.
+     *
+     * Depending on the number of arguments given, Gray, RGB, or CMYK
+     * color space is implied.
+     *
+     * When only ch1 is given, "Gray" color space is implied and it
+     * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
+     * if values are communicated as String types, or in range from 0 (black)
+     * to 255 (white) if communicated as Number type.
+     * The RGB-like 0-255 range is provided for backward compatibility.
+     *
+     * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
+     * value must be in the range from 0.00 (minimum intensity) to to 1.00
+     * (max intensity) if values are communicated as String types, or
+     * from 0 (min intensity) to to 255 (max intensity) if values are communicated
+     * as Number types.
+     * The RGB-like 0-255 range is provided for backward compatibility.
+     *
+     * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
+     * value must be a in the range from 0.00 (0% concentration) to to
+     * 1.00 (100% concentration)
+     *
+     * Because JavaScript treats fixed point numbers badly (rounds to
+     * floating point nearest to binary representation) it is highly advised to
+     * communicate the fractional numbers as String types, not JavaScript Number type.
+     *
+     * @param {Number|String} ch1 Color channel value or {string} ch1 color value in hexadecimal, example: '#FFFFFF'.
+     * @param {Number} ch2 Color channel value.
+     * @param {Number} ch3 Color channel value.
+     * @param {Number} ch4 Color channel value.
+     *
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name setTextColor
+     */
 
-    // - Header (GIF87a or GIF89a).
-    if (buf[p++] !== 0x47 ||            buf[p++] !== 0x49 || buf[p++] !== 0x46 ||
-        buf[p++] !== 0x38 || (buf[p++]+1 & 0xfd) !== 0x38 || buf[p++] !== 0x61) {
-      throw "Invalid GIF 87a/89a header.";
-    }
 
-    // - Logical Screen Descriptor.
-    var width = buf[p++] | buf[p++] << 8;
-    var height = buf[p++] | buf[p++] << 8;
-    var pf0 = buf[p++];  // <Packed Fields>.
-    var global_palette_flag = pf0 >> 7;
-    var num_global_colors_pow2 = pf0 & 0x7;
-    var num_global_colors = 1 << (num_global_colors_pow2 + 1);
-    var background = buf[p++];
-    buf[p++];  // Pixel aspect ratio (unused?).
+    API.__private__.setTextColor = API.setTextColor = function (ch1, ch2, ch3, ch4) {
+      var options = {
+        ch1: ch1,
+        ch2: ch2,
+        ch3: ch3,
+        ch4: ch4,
+        pdfColorType: "text",
+        precision: 3
+      };
+      textColor = encodeColorString(options);
+      return this;
+    };
 
-    var global_palette_offset = null;
+    var activeCharSpace = options.charSpace;
+    /**
+     * Get global value of CharSpace.
+     *
+     * @function
+     * @instance
+     * @returns {number} charSpace
+     * @memberof jsPDF#
+     * @name getCharSpace
+     */
 
-    if (global_palette_flag) {
-      global_palette_offset = p;
-      p += num_global_colors * 3;  // Seek past palette.
-    }
+    var getCharSpace = API.__private__.getCharSpace = API.getCharSpace = function () {
+      return parseFloat(activeCharSpace || 0);
+    };
+    /**
+     * Set global value of CharSpace.
+     *
+     * @param {number} charSpace
+     * @function
+     * @instance
+     * @returns {jsPDF} jsPDF-instance
+     * @memberof jsPDF#
+     * @name setCharSpace
+     */
 
-    var no_eof = true;
 
-    var frames = [ ];
+    API.__private__.setCharSpace = API.setCharSpace = function (charSpace) {
+      if (isNaN(charSpace)) {
+        throw new Error("Invalid argument passed to jsPDF.setCharSpace");
+      }
 
-    var delay = 0;
-    var transparent_index = null;
-    var disposal = 0;  // 0 - No disposal specified.
-    var loop_count = null;
+      activeCharSpace = charSpace;
+      return this;
+    };
 
-    this.width = width;
-    this.height = height;
+    var lineCapID = 0;
+    /**
+     * Is an Object providing a mapping from human-readable to
+     * integer flag values designating the varieties of line cap
+     * and join styles.
+     *
+     * @memberof jsPDF#
+     * @name CapJoinStyles
+     */
 
-    while (no_eof && p < buf.length) {
-      switch (buf[p++]) {
-        case 0x21:  // Graphics Control Extension Block
-          switch (buf[p++]) {
-            case 0xff:  // Application specific block
-              // Try if it's a Netscape block (with animation loop counter).
-              if (buf[p   ] !== 0x0b ||  // 21 FF already read, check block size.
-                  // NETSCAPE2.0
-                  buf[p+1 ] == 0x4e && buf[p+2 ] == 0x45 && buf[p+3 ] == 0x54 &&
-                  buf[p+4 ] == 0x53 && buf[p+5 ] == 0x43 && buf[p+6 ] == 0x41 &&
-                  buf[p+7 ] == 0x50 && buf[p+8 ] == 0x45 && buf[p+9 ] == 0x32 &&
-                  buf[p+10] == 0x2e && buf[p+11] == 0x30 &&
-                  // Sub-block
-                  buf[p+12] == 0x03 && buf[p+13] == 0x01 && buf[p+16] == 0) {
-                p += 14;
-                loop_count = buf[p++] | buf[p++] << 8;
-                p++;  // Skip terminator.
-              } else {  // We don't know what it is, just try to get past it.
-                p += 12;
-                while (true) {  // Seek through subblocks.
-                  var block_size = buf[p++];
-                  if (block_size === 0) break;
-                  p += block_size;
-                }
-              }
-              break;
+    API.CapJoinStyles = {
+      0: 0,
+      butt: 0,
+      but: 0,
+      miter: 0,
+      1: 1,
+      round: 1,
+      rounded: 1,
+      circle: 1,
+      2: 2,
+      projecting: 2,
+      project: 2,
+      square: 2,
+      bevel: 2
+    };
+    /**
+     * Sets the line cap styles.
+     * See {jsPDF.CapJoinStyles} for variants.
+     *
+     * @param {String|Number} style A string or number identifying the type of line cap.
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name setLineCap
+     */
 
-            case 0xf9:  // Graphics Control Extension
-              if (buf[p++] !== 0x4 || buf[p+4] !== 0)
-                throw "Invalid graphics extension block.";
-              var pf1 = buf[p++];
-              delay = buf[p++] | buf[p++] << 8;
-              transparent_index = buf[p++];
-              if ((pf1 & 1) === 0) transparent_index = null;
-              disposal = pf1 >> 2 & 0x7;
-              p++;  // Skip terminator.
-              break;
+    API.__private__.setLineCap = API.setLineCap = function (style) {
+      var id = API.CapJoinStyles[style];
 
-            case 0xfe:  // Comment Extension.
-              while (true) {  // Seek through subblocks.
-                var block_size = buf[p++];
-                if (block_size === 0) break;
-                // console.log(buf.slice(p, p+block_size).toString('ascii'));
-                p += block_size;
-              }
-              break;
+      if (id === undefined) {
+        throw new Error("Line cap style of '" + style + "' is not recognized. See or extend .CapJoinStyles property for valid styles");
+      }
 
-            default:
-              throw "Unknown graphic control label: 0x" + buf[p-1].toString(16);
-          }
-          break;
+      lineCapID = id;
+      out(id + " J");
+      return this;
+    };
 
-        case 0x2c:  // Image Descriptor.
-          var x = buf[p++] | buf[p++] << 8;
-          var y = buf[p++] | buf[p++] << 8;
-          var w = buf[p++] | buf[p++] << 8;
-          var h = buf[p++] | buf[p++] << 8;
-          var pf2 = buf[p++];
-          var local_palette_flag = pf2 >> 7;
-          var interlace_flag = pf2 >> 6 & 1;
-          var num_local_colors_pow2 = pf2 & 0x7;
-          var num_local_colors = 1 << (num_local_colors_pow2 + 1);
-          var palette_offset = global_palette_offset;
-          var has_local_palette = false;
-          if (local_palette_flag) {
-            var has_local_palette = true;
-            palette_offset = p;  // Override with local palette.
-            p += num_local_colors * 3;  // Seek past palette.
-          }
+    var lineJoinID = 0;
+    /**
+     * Sets the line join styles.
+     * See {jsPDF.CapJoinStyles} for variants.
+     *
+     * @param {String|Number} style A string or number identifying the type of line join.
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name setLineJoin
+     */
 
-          var data_offset = p;
+    API.__private__.setLineJoin = API.setLineJoin = function (style) {
+      var id = API.CapJoinStyles[style];
 
-          p++;  // codesize
-          while (true) {
-            var block_size = buf[p++];
-            if (block_size === 0) break;
-            p += block_size;
-          }
+      if (id === undefined) {
+        throw new Error("Line join style of '" + style + "' is not recognized. See or extend .CapJoinStyles property for valid styles");
+      }
 
-          frames.push({x: x, y: y, width: w, height: h,
-                       has_local_palette: has_local_palette,
-                       palette_offset: palette_offset,
-                       data_offset: data_offset,
-                       data_length: p - data_offset,
-                       transparent_index: transparent_index,
-                       interlaced: !!interlace_flag,
-                       delay: delay,
-                       disposal: disposal});
-          break;
+      lineJoinID = id;
+      out(id + " j");
+      return this;
+    };
+    /**
+     * Sets the miterLimit property, which effects the maximum miter length.
+     *
+     * @param {number} length The length of the miter
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name setLineMiterLimit
+     */
 
-        case 0x3b:  // Trailer Marker (end of file).
-          no_eof = false;
-          break;
+    API.__private__.setLineMiterLimit = API.__private__.setMiterLimit = API.setLineMiterLimit = API.setMiterLimit = function (length) {
+      length = length || 0;
 
-        default:
-          throw "Unknown gif block: 0x" + buf[p-1].toString(16);
-          break;
+      if (isNaN(length)) {
+        throw new Error("Invalid argument passed to jsPDF.setLineMiterLimit");
       }
-    }
 
-    this.numFrames = function() {
-      return frames.length;
+      out(hpf(scale(length)) + " M");
+      return this;
     };
+    /**
+     * An object representing a pdf graphics state.
+     * @class GState
+     */
 
-    this.loopCount = function() {
-      return loop_count;
-    };
-
-    this.frameInfo = function(frame_num) {
-      if (frame_num < 0 || frame_num >= frames.length)
-        throw "Frame index out of range.";
-      return frames[frame_num];
-    };
-
-    this.decodeAndBlitFrameBGRA = function(frame_num, pixels) {
-      var frame = this.frameInfo(frame_num);
-      var num_pixels = frame.width * frame.height;
-      var index_stream = new Uint8Array(num_pixels);  // At most 8-bit indices.
-      GifReaderLZWOutputIndexStream(
-          buf, frame.data_offset, index_stream, num_pixels);
-      var palette_offset = frame.palette_offset;
-
-      // NOTE(deanm): It seems to be much faster to compare index to 256 than
-      // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in
-      // the profile, not sure if it's related to using a Uint8Array.
-      var trans = frame.transparent_index;
-      if (trans === null) trans = 256;
+    /**
+     *
+     * @param parameters A parameter object that contains all properties this graphics state wants to set.
+     * Supported are: opacity, stroke-opacity
+     * @constructor
+     */
 
-      // We are possibly just blitting to a portion of the entire frame.
-      // That is a subrect within the framerect, so the additional pixels
-      // must be skipped over after we finished a scanline.
-      var framewidth  = frame.width;
-      var framestride = width - framewidth;
-      var xleft       = framewidth;  // Number of subrect pixels left in scanline.
 
-      // Output indicies of the top left and bottom right corners of the subrect.
-      var opbeg = ((frame.y * width) + frame.x) * 4;
-      var opend = ((frame.y + frame.height) * width + frame.x) * 4;
-      var op    = opbeg;
+    API.GState = GState;
+    /**
+     * Sets a either previously added {@link GState} (via {@link addGState}) or a new {@link GState}.
+     * @param {String|GState} gState If type is string, a previously added GState is used, if type is GState
+     * it will be added before use.
+     * @function
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name setGState
+     */
 
-      var scanstride = framestride * 4;
+    API.setGState = function (gState) {
+      if (typeof gState === "string") {
+        gState = gStates[gStatesMap[gState]];
+      } else {
+        gState = addGState(null, gState);
+      }
 
-      // Use scanstride to skip past the rows when interlacing.  This is skipping
-      // 7 rows for the first two passes, then 3 then 1.
-      if (frame.interlaced === true) {
-        scanstride += (framewidth + framestride) * 4 * 7;  // Pass 1.
+      if (!gState.equals(activeGState)) {
+        out("/" + gState.id + " gs");
+        activeGState = gState;
       }
+    };
+    /**
+     * Adds a new Graphics State. Duplicates are automatically eliminated.
+     * @param {String} key Might also be null, if no later reference to this gState is needed
+     * @param {Object} gState The gState object
+     */
 
-      var interlaceskip = 8;  // Tracking the row interval in the current pass.
 
-      for (var i = 0, il = index_stream.length; i < il; ++i) {
-        var index = index_stream[i];
+    var addGState = function addGState(key, gState) {
+      // only add it if it is not already present (the keys provided by the user must be unique!)
+      if (key && gStatesMap[key]) return;
+      var duplicate = false;
 
-        if (xleft === 0) {  // Beginning of new scan line
-          op += scanstride;
-          xleft = framewidth;
-          if (op >= opend) { // Catch the wrap to switch passes when interlacing.
-            scanstride =
-                framestride + (framewidth + framestride) * 4 * (interlaceskip-1);
-            // interlaceskip / 2 * 4 is interlaceskip << 1.
-            op = opbeg + (framewidth + framestride) * (interlaceskip << 1);
-            interlaceskip >>= 1;
+      for (var s in gStates) {
+        if (gStates.hasOwnProperty(s)) {
+          if (gStates[s].equals(gState)) {
+            duplicate = true;
+            break;
           }
         }
-
-        if (index === trans) {
-          op += 4;
-        } else {
-          var r = buf[palette_offset + index * 3];
-          var g = buf[palette_offset + index * 3 + 1];
-          var b = buf[palette_offset + index * 3 + 2];
-          pixels[op++] = b;
-          pixels[op++] = g;
-          pixels[op++] = r;
-          pixels[op++] = 255;
-        }
-        --xleft;
       }
-    };
 
-    // I will go to copy and paste hell one day...
-    this.decodeAndBlitFrameRGBA = function(frame_num, pixels) {
-      var frame = this.frameInfo(frame_num);
-      var num_pixels = frame.width * frame.height;
-      var index_stream = new Uint8Array(num_pixels);  // At most 8-bit indices.
-      GifReaderLZWOutputIndexStream(
-          buf, frame.data_offset, index_stream, num_pixels);
-      var palette_offset = frame.palette_offset;
+      if (duplicate) {
+        gState = gStates[s];
+      } else {
+        var gStateKey = "GS" + (Object.keys(gStates).length + 1).toString(10);
+        gStates[gStateKey] = gState;
+        gState.id = gStateKey;
+      } // several user keys may point to the same GState object
 
-      // NOTE(deanm): It seems to be much faster to compare index to 256 than
-      // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in
-      // the profile, not sure if it's related to using a Uint8Array.
-      var trans = frame.transparent_index;
-      if (trans === null) trans = 256;
 
-      // We are possibly just blitting to a portion of the entire frame.
-      // That is a subrect within the framerect, so the additional pixels
-      // must be skipped over after we finished a scanline.
-      var framewidth  = frame.width;
-      var framestride = width - framewidth;
-      var xleft       = framewidth;  // Number of subrect pixels left in scanline.
+      key && (gStatesMap[key] = gState.id);
+      events.publish("addGState", gState);
+      return gState;
+    };
+    /**
+     * Adds a new {@link GState} for later use. See {@link setGState}.
+     * @param {String} key
+     * @param {GState} gState
+     * @function
+     * @instance
+     * @returns {jsPDF}
+     *
+     * @memberof jsPDF#
+     * @name addGState
+     */
 
-      // Output indicies of the top left and bottom right corners of the subrect.
-      var opbeg = ((frame.y * width) + frame.x) * 4;
-      var opend = ((frame.y + frame.height) * width + frame.x) * 4;
-      var op    = opbeg;
 
-      var scanstride = framestride * 4;
+    API.addGState = function (key, gState) {
+      addGState(key, gState);
+      return this;
+    };
+    /**
+     * Saves the current graphics state ("pushes it on the stack"). It can be restored by {@link restoreGraphicsState}
+     * later. Here, the general pdf graphics state is meant, also including the current transformation matrix,
+     * fill and stroke colors etc.
+     * @function
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name saveGraphicsState
+     */
 
-      // Use scanstride to skip past the rows when interlacing.  This is skipping
-      // 7 rows for the first two passes, then 3 then 1.
-      if (frame.interlaced === true) {
-        scanstride += (framewidth + framestride) * 4 * 7;  // Pass 1.
-      }
 
-      var interlaceskip = 8;  // Tracking the row interval in the current pass.
+    API.saveGraphicsState = function () {
+      out("q"); // as we cannot set font key and size independently we must keep track of both
 
-      for (var i = 0, il = index_stream.length; i < il; ++i) {
-        var index = index_stream[i];
+      fontStateStack.push({
+        key: activeFontKey,
+        size: activeFontSize,
+        color: textColor
+      });
+      return this;
+    };
+    /**
+     * Restores a previously saved graphics state saved by {@link saveGraphicsState} ("pops the stack").
+     * @function
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name restoreGraphicsState
+     */
 
-        if (xleft === 0) {  // Beginning of new scan line
-          op += scanstride;
-          xleft = framewidth;
-          if (op >= opend) { // Catch the wrap to switch passes when interlacing.
-            scanstride =
-                framestride + (framewidth + framestride) * 4 * (interlaceskip-1);
-            // interlaceskip / 2 * 4 is interlaceskip << 1.
-            op = opbeg + (framewidth + framestride) * (interlaceskip << 1);
-            interlaceskip >>= 1;
-          }
-        }
 
-        if (index === trans) {
-          op += 4;
-        } else {
-          var r = buf[palette_offset + index * 3];
-          var g = buf[palette_offset + index * 3 + 1];
-          var b = buf[palette_offset + index * 3 + 2];
-          pixels[op++] = r;
-          pixels[op++] = g;
-          pixels[op++] = b;
-          pixels[op++] = 255;
-        }
-        --xleft;
-      }
+    API.restoreGraphicsState = function () {
+      out("Q"); // restore previous font state
+
+      var fontState = fontStateStack.pop();
+      activeFontKey = fontState.key;
+      activeFontSize = fontState.size;
+      textColor = fontState.color;
+      activeGState = null;
+      return this;
     };
-  }
+    /**
+     * Appends this matrix to the left of all previously applied matrices.
+     *
+     * @param {Matrix} matrix
+     * @function
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name setCurrentTransformationMatrix
+     */
 
-  function GifReaderLZWOutputIndexStream(code_stream, p, output, output_length) {
-    var min_code_size = code_stream[p++];
 
-    var clear_code = 1 << min_code_size;
-    var eoi_code = clear_code + 1;
-    var next_code = eoi_code + 1;
+    API.setCurrentTransformationMatrix = function (matrix) {
+      out(matrix.toString() + " cm");
+      return this;
+    };
+    /**
+     * Inserts a debug comment into the generated pdf.
+     * @function
+     * @instance
+     * @param {String} text
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name comment
+     */
 
-    var cur_code_size = min_code_size + 1;  // Number of bits per code.
-    // NOTE: This shares the same name as the encoder, but has a different
-    // meaning here.  Here this masks each code coming from the code stream.
-    var code_mask = (1 << cur_code_size) - 1;
-    var cur_shift = 0;
-    var cur = 0;
 
-    var op = 0;  // Output pointer.
-    
-    var subblock_size = code_stream[p++];
+    API.comment = function (text) {
+      out("#" + text);
+      return this;
+    };
+    /**
+     * Point
+     */
 
-    // TODO(deanm): Would using a TypedArray be any faster?  At least it would
-    // solve the fast mode / backing store uncertainty.
-    // var code_table = Array(4096);
-    var code_table = new Int32Array(4096);  // Can be signed, we only use 20 bits.
 
-    var prev_code = null;  // Track code-1.
+    var Point = function Point(x, y) {
+      var _x = x || 0;
 
-    while (true) {
-      // Read up to two bytes, making sure we always 12-bits for max sized code.
-      while (cur_shift < 16) {
-        if (subblock_size === 0) break;  // No more data to be read.
+      Object.defineProperty(this, "x", {
+        enumerable: true,
+        get: function get() {
+          return _x;
+        },
+        set: function set(value) {
+          if (!isNaN(value)) {
+            _x = parseFloat(value);
+          }
+        }
+      });
 
-        cur |= code_stream[p++] << cur_shift;
-        cur_shift += 8;
+      var _y = y || 0;
 
-        if (subblock_size === 1) {  // Never let it get to 0 to hold logic above.
-          subblock_size = code_stream[p++];  // Next subblock.
-        } else {
-          --subblock_size;
+      Object.defineProperty(this, "y", {
+        enumerable: true,
+        get: function get() {
+          return _y;
+        },
+        set: function set(value) {
+          if (!isNaN(value)) {
+            _y = parseFloat(value);
+          }
         }
-      }
-
-      // TODO(deanm): We should never really get here, we should have received
-      // and EOI.
-      if (cur_shift < cur_code_size)
-        break;
+      });
+      var _type = "pt";
+      Object.defineProperty(this, "type", {
+        enumerable: true,
+        get: function get() {
+          return _type;
+        },
+        set: function set(value) {
+          _type = value.toString();
+        }
+      });
+      return this;
+    };
+    /**
+     * Rectangle
+     */
 
-      var code = cur & code_mask;
-      cur >>= cur_code_size;
-      cur_shift -= cur_code_size;
 
-      // TODO(deanm): Maybe should check that the first code was a clear code,
-      // at least this is what you're supposed to do.  But actually our encoder
-      // now doesn't emit a clear code first anyway.
-      if (code === clear_code) {
-        // We don't actually have to clear the table.  This could be a good idea
-        // for greater error checking, but we don't really do any anyway.  We
-        // will just track it with next_code and overwrite old entries.
+    var Rectangle = function Rectangle(x, y, w, h) {
+      Point.call(this, x, y);
+      this.type = "rect";
 
-        next_code = eoi_code + 1;
-        cur_code_size = min_code_size + 1;
-        code_mask = (1 << cur_code_size) - 1;
+      var _w = w || 0;
 
-        // Don't update prev_code ?
-        prev_code = null;
-        continue;
-      } else if (code === eoi_code) {
-        break;
-      }
+      Object.defineProperty(this, "w", {
+        enumerable: true,
+        get: function get() {
+          return _w;
+        },
+        set: function set(value) {
+          if (!isNaN(value)) {
+            _w = parseFloat(value);
+          }
+        }
+      });
 
-      // We have a similar situation as the decoder, where we want to store
-      // variable length entries (code table entries), but we want to do in a
-      // faster manner than an array of arrays.  The code below stores sort of a
-      // linked list within the code table, and then "chases" through it to
-      // construct the dictionary entries.  When a new entry is created, just the
-      // last byte is stored, and the rest (prefix) of the entry is only
-      // referenced by its table entry.  Then the code chases through the
-      // prefixes until it reaches a single byte code.  We have to chase twice,
-      // first to compute the length, and then to actually copy the data to the
-      // output (backwards, since we know the length).  The alternative would be
-      // storing something in an intermediate stack, but that doesn't make any
-      // more sense.  I implemented an approach where it also stored the length
-      // in the code table, although it's a bit tricky because you run out of
-      // bits (12 + 12 + 8), but I didn't measure much improvements (the table
-      // entries are generally not the long).  Even when I created benchmarks for
-      // very long table entries the complexity did not seem worth it.
-      // The code table stores the prefix entry in 12 bits and then the suffix
-      // byte in 8 bits, so each entry is 20 bits.
+      var _h = h || 0;
 
-      var chase_code = code < next_code ? code : prev_code;
+      Object.defineProperty(this, "h", {
+        enumerable: true,
+        get: function get() {
+          return _h;
+        },
+        set: function set(value) {
+          if (!isNaN(value)) {
+            _h = parseFloat(value);
+          }
+        }
+      });
+      return this;
+    };
+    /**
+     * FormObject/RenderTarget
+     */
 
-      // Chase what we will output, either {CODE} or {CODE-1}.
-      var chase_length = 0;
-      var chase = chase_code;
-      while (chase > clear_code) {
-        chase = code_table[chase] >> 8;
-        ++chase_length;
-      }
 
-      var k = chase;
-      
-      var op_end = op + chase_length + (chase_code !== code ? 1 : 0);
-      if (op_end > output_length) {
-        console.log("Warning, gif stream longer than expected.");
-        return;
-      }
+    var RenderTarget = function RenderTarget() {
+      this.page = page;
+      this.currentPage = currentPage;
+      this.pages = pages.slice(0);
+      this.pagesContext = pagesContext.slice(0);
+      this.x = pageX;
+      this.y = pageY;
+      this.matrix = pageMatrix;
+      this.width = getPageWidth(currentPage);
+      this.height = getPageHeight(currentPage);
+      this.outputDestination = outputDestination;
+      this.id = ""; // set by endFormObject()
+
+      this.objectNumber = -1; // will be set by putXObject()
+    };
 
-      // Already have the first byte from the chase, might as well write it fast.
-      output[op++] = k;
+    RenderTarget.prototype.restore = function () {
+      page = this.page;
+      currentPage = this.currentPage;
+      pagesContext = this.pagesContext;
+      pages = this.pages;
+      pageX = this.x;
+      pageY = this.y;
+      pageMatrix = this.matrix;
+      setPageWidth(currentPage, this.width);
+      setPageHeight(currentPage, this.height);
+      outputDestination = this.outputDestination;
+    };
 
-      op += chase_length;
-      var b = op;  // Track pointer, writing backwards.
+    var beginNewRenderTarget = function beginNewRenderTarget(x, y, width, height, matrix) {
+      // save current state
+      renderTargetStack.push(new RenderTarget()); // clear pages
 
-      if (chase_code !== code)  // The case of emitting {CODE-1} + k.
-        output[op++] = k;
+      page = currentPage = 0;
+      pages = [];
+      pageX = x;
+      pageY = y;
+      pageMatrix = matrix;
+      beginPage([width, height]);
+    };
 
-      chase = chase_code;
-      while (chase_length--) {
-        chase = code_table[chase];
-        output[--b] = chase & 0xff;  // Write backwards.
-        chase >>= 8;  // Pull down to the prefix code.
-      }
+    var endFormObject = function endFormObject(key) {
+      // only add it if it is not already present (the keys provided by the user must be unique!)
+      if (renderTargetMap[key]) {
+        renderTargetStack.pop().restore();
+        return;
+      } // save the created xObject
 
-      if (prev_code !== null && next_code < 4096) {
-        code_table[next_code++] = prev_code << 8 | k;
-        // TODO(deanm): Figure out this clearing vs code growth logic better.  I
-        // have an feeling that it should just happen somewhere else, for now it
-        // is awkward between when we grow past the max and then hit a clear code.
-        // For now just check if we hit the max 12-bits (then a clear code should
-        // follow, also of course encoded in 12-bits).
-        if (next_code >= code_mask+1 && cur_code_size < 12) {
-          ++cur_code_size;
-          code_mask = code_mask << 1 | 1;
-        }
-      }
 
-      prev_code = code;
-    }
+      var newXObject = new RenderTarget();
+      var xObjectId = "Xo" + (Object.keys(renderTargets).length + 1).toString(10);
+      newXObject.id = xObjectId;
+      renderTargetMap[key] = xObjectId;
+      renderTargets[xObjectId] = newXObject;
+      events.publish("addFormObject", newXObject); // restore state from stack
 
-    if (op !== output_length) {
-      console.log("Warning, gif stream shorter than expected.");
-    }
+      renderTargetStack.pop().restore();
+    };
+    /**
+     * Starts a new pdf form object, which means that all consequent draw calls target a new independent object
+     * until {@link endFormObject} is called. The created object can be referenced and drawn later using
+     * {@link doFormObject}. Nested form objects are possible.
+     * x, y, width, height set the bounding box that is used to clip the content.
+     *
+     * @param {number} x
+     * @param {number} y
+     * @param {number} width
+     * @param {number} height
+     * @param {Matrix} matrix The matrix that will be applied to convert the form objects coordinate system to
+     * the parent's.
+     * @function
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name beginFormObject
+     */
 
-    return output;
-  }
 
-  try { exports.GifWriter = GifWriter; exports.GifReader = GifReader; } catch(e) { }  // CommonJS.
-  
+    API.beginFormObject = function (x, y, width, height, matrix) {
+      // The user can set the output target to a new form object. Nested form objects are possible.
+      // Currently, they use the resource dictionary of the surrounding stream. This should be changed, as
+      // the PDF-Spec states:
+      // "In PDF 1.2 and later versions, form XObjects may be independent of the content streams in which
+      // they appear, and this is strongly recommended although not requiredIn PDF 1.2 and later versions,
+      // form XObjects may be independent of the content streams in which they appear, and this is strongly
+      // recommended although not required"
+      beginNewRenderTarget(x, y, width, height, matrix);
+      return this;
+    };
+    /**
+     * Completes and saves the form object.
+     * @param {String} key The key by which this form object can be referenced.
+     * @function
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name endFormObject
+     */
 
-  /*
-    Copyright (c) 2008, Adobe Systems Incorporated
-    All rights reserved.
 
-    Redistribution and use in source and binary forms, with or without 
-    modification, are permitted provided that the following conditions are
-    met:
+    API.endFormObject = function (key) {
+      endFormObject(key);
+      return this;
+    };
+    /**
+     * Draws the specified form object by referencing to the respective pdf XObject created with
+     * {@link API.beginFormObject} and {@link endFormObject}.
+     * The location is determined by matrix.
+     *
+     * @param {String} key The key to the form object.
+     * @param {Matrix} matrix The matrix applied before drawing the form object.
+     * @function
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name doFormObject
+     */
 
-    * Redistributions of source code must retain the above copyright notice, 
-      this list of conditions and the following disclaimer.
-    
-    * Redistributions in binary form must reproduce the above copyright
-      notice, this list of conditions and the following disclaimer in the 
-      documentation and/or other materials provided with the distribution.
-    
-    * Neither the name of Adobe Systems Incorporated nor the names of its 
-      contributors may be used to endorse or promote products derived from 
-      this software without specific prior written permission.
 
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
-    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-  */
-  /*
-  JPEG encoder ported to JavaScript and optimized by Andreas Ritter, www.bytestrom.eu, 11/2009
+    API.doFormObject = function (key, matrix) {
+      var xObject = renderTargets[renderTargetMap[key]];
+      out("q");
+      out(matrix.toString() + " cm");
+      out("/" + xObject.id + " Do");
+      out("Q");
+      return this;
+    };
+    /**
+     * Returns the form object specified by key.
+     * @param key {String}
+     * @returns {{x: number, y: number, width: number, height: number, matrix: Matrix}}
+     * @function
+     * @returns {jsPDF}
+     * @memberof jsPDF#
+     * @name getFormObject
+     */
 
-  Basic GUI blocking jpeg encoder
-  */
 
-  function JPEGEncoder(quality) {
-  	var ffloor = Math.floor;
-  	var YTable = new Array(64);
-  	var UVTable = new Array(64);
-  	var fdtbl_Y = new Array(64);
-  	var fdtbl_UV = new Array(64);
-  	var YDC_HT;
-  	var UVDC_HT;
-  	var YAC_HT;
-  	var UVAC_HT;
-  	
-  	var bitcode = new Array(65535);
-  	var category = new Array(65535);
-  	var outputfDCTQuant = new Array(64);
-  	var DU = new Array(64);
-  	var byteout = [];
-  	var bytenew = 0;
-  	var bytepos = 7;
-  	
-  	var YDU = new Array(64);
-  	var UDU = new Array(64);
-  	var VDU = new Array(64);
-  	var clt = new Array(256);
-  	var RGB_YUV_TABLE = new Array(2048);
-  	var currentQuality;
-  	
-  	var ZigZag = [
-  			 0, 1, 5, 6,14,15,27,28,
-  			 2, 4, 7,13,16,26,29,42,
-  			 3, 8,12,17,25,30,41,43,
-  			 9,11,18,24,31,40,44,53,
-  			10,19,23,32,39,45,52,54,
-  			20,22,33,38,46,51,55,60,
-  			21,34,37,47,50,56,59,61,
-  			35,36,48,49,57,58,62,63
-  		];
-  	
-  	var std_dc_luminance_nrcodes = [0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0];
-  	var std_dc_luminance_values = [0,1,2,3,4,5,6,7,8,9,10,11];
-  	var std_ac_luminance_nrcodes = [0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d];
-  	var std_ac_luminance_values = [
-  			0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,
-  			0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
-  			0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,
-  			0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,
-  			0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,
-  			0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,
-  			0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,
-  			0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
-  			0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
-  			0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
-  			0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
-  			0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
-  			0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,
-  			0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
-  			0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,
-  			0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,
-  			0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,
-  			0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,
-  			0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,
-  			0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,
-  			0xf9,0xfa
-  		];
-  	
-  	var std_dc_chrominance_nrcodes = [0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0];
-  	var std_dc_chrominance_values = [0,1,2,3,4,5,6,7,8,9,10,11];
-  	var std_ac_chrominance_nrcodes = [0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77];
-  	var std_ac_chrominance_values = [
-  			0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,
-  			0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
-  			0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,
-  			0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,
-  			0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,
-  			0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,
-  			0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,
-  			0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,
-  			0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,
-  			0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,
-  			0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,
-  			0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,
-  			0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,
-  			0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,
-  			0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,
-  			0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,
-  			0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,
-  			0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,
-  			0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,
-  			0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,
-  			0xf9,0xfa
-  		];
-  	
-  	function initQuantTables(sf){
-  			var YQT = [
-  				16, 11, 10, 16, 24, 40, 51, 61,
-  				12, 12, 14, 19, 26, 58, 60, 55,
-  				14, 13, 16, 24, 40, 57, 69, 56,
-  				14, 17, 22, 29, 51, 87, 80, 62,
-  				18, 22, 37, 56, 68,109,103, 77,
-  				24, 35, 55, 64, 81,104,113, 92,
-  				49, 64, 78, 87,103,121,120,101,
-  				72, 92, 95, 98,112,100,103, 99
-  			];
-  			
-  			for (var i = 0; i < 64; i++) {
-  				var t = ffloor((YQT[i]*sf+50)/100);
-  				if (t < 1) {
-  					t = 1;
-  				} else if (t > 255) {
-  					t = 255;
-  				}
-  				YTable[ZigZag[i]] = t;
-  			}
-  			var UVQT = [
-  				17, 18, 24, 47, 99, 99, 99, 99,
-  				18, 21, 26, 66, 99, 99, 99, 99,
-  				24, 26, 56, 99, 99, 99, 99, 99,
-  				47, 66, 99, 99, 99, 99, 99, 99,
-  				99, 99, 99, 99, 99, 99, 99, 99,
-  				99, 99, 99, 99, 99, 99, 99, 99,
-  				99, 99, 99, 99, 99, 99, 99, 99,
-  				99, 99, 99, 99, 99, 99, 99, 99
-  			];
-  			for (var j = 0; j < 64; j++) {
-  				var u = ffloor((UVQT[j]*sf+50)/100);
-  				if (u < 1) {
-  					u = 1;
-  				} else if (u > 255) {
-  					u = 255;
-  				}
-  				UVTable[ZigZag[j]] = u;
-  			}
-  			var aasf = [
-  				1.0, 1.387039845, 1.306562965, 1.175875602,
-  				1.0, 0.785694958, 0.541196100, 0.275899379
-  			];
-  			var k = 0;
-  			for (var row = 0; row < 8; row++)
-  			{
-  				for (var col = 0; col < 8; col++)
-  				{
-  					fdtbl_Y[k]  = (1.0 / (YTable [ZigZag[k]] * aasf[row] * aasf[col] * 8.0));
-  					fdtbl_UV[k] = (1.0 / (UVTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0));
-  					k++;
-  				}
-  			}
-  		}
-  		
-  		function computeHuffmanTbl(nrcodes, std_table){
-  			var codevalue = 0;
-  			var pos_in_table = 0;
-  			var HT = new Array();
-  			for (var k = 1; k <= 16; k++) {
-  				for (var j = 1; j <= nrcodes[k]; j++) {
-  					HT[std_table[pos_in_table]] = [];
-  					HT[std_table[pos_in_table]][0] = codevalue;
-  					HT[std_table[pos_in_table]][1] = k;
-  					pos_in_table++;
-  					codevalue++;
-  				}
-  				codevalue*=2;
-  			}
-  			return HT;
-  		}
-  		
-  		function initHuffmanTbl()
-  		{
-  			YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values);
-  			UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values);
-  			YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values);
-  			UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values);
-  		}
-  	
-  		function initCategoryNumber()
-  		{
-  			var nrlower = 1;
-  			var nrupper = 2;
-  			for (var cat = 1; cat <= 15; cat++) {
-  				//Positive numbers
-  				for (var nr = nrlower; nr<nrupper; nr++) {
-  					category[32767+nr] = cat;
-  					bitcode[32767+nr] = [];
-  					bitcode[32767+nr][1] = cat;
-  					bitcode[32767+nr][0] = nr;
-  				}
-  				//Negative numbers
-  				for (var nrneg =-(nrupper-1); nrneg<=-nrlower; nrneg++) {
-  					category[32767+nrneg] = cat;
-  					bitcode[32767+nrneg] = [];
-  					bitcode[32767+nrneg][1] = cat;
-  					bitcode[32767+nrneg][0] = nrupper-1+nrneg;
-  				}
-  				nrlower <<= 1;
-  				nrupper <<= 1;
-  			}
-  		}
-  		
-  		function initRGBYUVTable() {
-  			for(var i = 0; i < 256;i++) {
-  				RGB_YUV_TABLE[i]      		=  19595 * i;
-  				RGB_YUV_TABLE[(i+ 256)>>0] 	=  38470 * i;
-  				RGB_YUV_TABLE[(i+ 512)>>0] 	=   7471 * i + 0x8000;
-  				RGB_YUV_TABLE[(i+ 768)>>0] 	= -11059 * i;
-  				RGB_YUV_TABLE[(i+1024)>>0] 	= -21709 * i;
-  				RGB_YUV_TABLE[(i+1280)>>0] 	=  32768 * i + 0x807FFF;
-  				RGB_YUV_TABLE[(i+1536)>>0] 	= -27439 * i;
-  				RGB_YUV_TABLE[(i+1792)>>0] 	= - 5329 * i;
-  			}
-  		}
-  		
-  		// IO functions
-  		function writeBits(bs)
-  		{
-  			var value = bs[0];
-  			var posval = bs[1]-1;
-  			while ( posval >= 0 ) {
-  				if (value & (1 << posval) ) {
-  					bytenew |= (1 << bytepos);
-  				}
-  				posval--;
-  				bytepos--;
-  				if (bytepos < 0) {
-  					if (bytenew == 0xFF) {
-  						writeByte(0xFF);
-  						writeByte(0);
-  					}
-  					else {
-  						writeByte(bytenew);
-  					}
-  					bytepos=7;
-  					bytenew=0;
-  				}
-  			}
-  		}
-  	
-  		function writeByte(value)
-  		{
-  			//byteout.push(clt[value]); // write char directly instead of converting later
-        byteout.push(value);
-  		}
-  	
-  		function writeWord(value)
-  		{
-  			writeByte((value>>8)&0xFF);
-  			writeByte((value   )&0xFF);
-  		}
-  		
-  		// DCT & quantization core
-  		function fDCTQuant(data, fdtbl)
-  		{
-  			var d0, d1, d2, d3, d4, d5, d6, d7;
-  			/* Pass 1: process rows. */
-  			var dataOff=0;
-  			var i;
-  			var I8 = 8;
-  			var I64 = 64;
-  			for (i=0; i<I8; ++i)
-  			{
-  				d0 = data[dataOff];
-  				d1 = data[dataOff+1];
-  				d2 = data[dataOff+2];
-  				d3 = data[dataOff+3];
-  				d4 = data[dataOff+4];
-  				d5 = data[dataOff+5];
-  				d6 = data[dataOff+6];
-  				d7 = data[dataOff+7];
-  				
-  				var tmp0 = d0 + d7;
-  				var tmp7 = d0 - d7;
-  				var tmp1 = d1 + d6;
-  				var tmp6 = d1 - d6;
-  				var tmp2 = d2 + d5;
-  				var tmp5 = d2 - d5;
-  				var tmp3 = d3 + d4;
-  				var tmp4 = d3 - d4;
-  	
-  				/* Even part */
-  				var tmp10 = tmp0 + tmp3;	/* phase 2 */
-  				var tmp13 = tmp0 - tmp3;
-  				var tmp11 = tmp1 + tmp2;
-  				var tmp12 = tmp1 - tmp2;
-  	
-  				data[dataOff] = tmp10 + tmp11; /* phase 3 */
-  				data[dataOff+4] = tmp10 - tmp11;
-  	
-  				var z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */
-  				data[dataOff+2] = tmp13 + z1; /* phase 5 */
-  				data[dataOff+6] = tmp13 - z1;
-  	
-  				/* Odd part */
-  				tmp10 = tmp4 + tmp5; /* phase 2 */
-  				tmp11 = tmp5 + tmp6;
-  				tmp12 = tmp6 + tmp7;
-  	
-  				/* The rotator is modified from fig 4-8 to avoid extra negations. */
-  				var z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */
-  				var z2 = 0.541196100 * tmp10 + z5; /* c2-c6 */
-  				var z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */
-  				var z3 = tmp11 * 0.707106781; /* c4 */
-  	
-  				var z11 = tmp7 + z3;	/* phase 5 */
-  				var z13 = tmp7 - z3;
-  	
-  				data[dataOff+5] = z13 + z2;	/* phase 6 */
-  				data[dataOff+3] = z13 - z2;
-  				data[dataOff+1] = z11 + z4;
-  				data[dataOff+7] = z11 - z4;
-  	
-  				dataOff += 8; /* advance pointer to next row */
-  			}
-  	
-  			/* Pass 2: process columns. */
-  			dataOff = 0;
-  			for (i=0; i<I8; ++i)
-  			{
-  				d0 = data[dataOff];
-  				d1 = data[dataOff + 8];
-  				d2 = data[dataOff + 16];
-  				d3 = data[dataOff + 24];
-  				d4 = data[dataOff + 32];
-  				d5 = data[dataOff + 40];
-  				d6 = data[dataOff + 48];
-  				d7 = data[dataOff + 56];
-  				
-  				var tmp0p2 = d0 + d7;
-  				var tmp7p2 = d0 - d7;
-  				var tmp1p2 = d1 + d6;
-  				var tmp6p2 = d1 - d6;
-  				var tmp2p2 = d2 + d5;
-  				var tmp5p2 = d2 - d5;
-  				var tmp3p2 = d3 + d4;
-  				var tmp4p2 = d3 - d4;
-  	
-  				/* Even part */
-  				var tmp10p2 = tmp0p2 + tmp3p2;	/* phase 2 */
-  				var tmp13p2 = tmp0p2 - tmp3p2;
-  				var tmp11p2 = tmp1p2 + tmp2p2;
-  				var tmp12p2 = tmp1p2 - tmp2p2;
-  	
-  				data[dataOff] = tmp10p2 + tmp11p2; /* phase 3 */
-  				data[dataOff+32] = tmp10p2 - tmp11p2;
-  	
-  				var z1p2 = (tmp12p2 + tmp13p2) * 0.707106781; /* c4 */
-  				data[dataOff+16] = tmp13p2 + z1p2; /* phase 5 */
-  				data[dataOff+48] = tmp13p2 - z1p2;
-  	
-  				/* Odd part */
-  				tmp10p2 = tmp4p2 + tmp5p2; /* phase 2 */
-  				tmp11p2 = tmp5p2 + tmp6p2;
-  				tmp12p2 = tmp6p2 + tmp7p2;
-  	
-  				/* The rotator is modified from fig 4-8 to avoid extra negations. */
-  				var z5p2 = (tmp10p2 - tmp12p2) * 0.382683433; /* c6 */
-  				var z2p2 = 0.541196100 * tmp10p2 + z5p2; /* c2-c6 */
-  				var z4p2 = 1.306562965 * tmp12p2 + z5p2; /* c2+c6 */
-  				var z3p2 = tmp11p2 * 0.707106781; /* c4 */
-  	
-  				var z11p2 = tmp7p2 + z3p2;	/* phase 5 */
-  				var z13p2 = tmp7p2 - z3p2;
-  	
-  				data[dataOff+40] = z13p2 + z2p2; /* phase 6 */
-  				data[dataOff+24] = z13p2 - z2p2;
-  				data[dataOff+ 8] = z11p2 + z4p2;
-  				data[dataOff+56] = z11p2 - z4p2;
-  	
-  				dataOff++; /* advance pointer to next column */
-  			}
-  	
-  			// Quantize/descale the coefficients
-  			var fDCTQuant;
-  			for (i=0; i<I64; ++i)
-  			{
-  				// Apply the quantization and scaling factor & Round to nearest integer
-  				fDCTQuant = data[i]*fdtbl[i];
-  				outputfDCTQuant[i] = (fDCTQuant > 0.0) ? ((fDCTQuant + 0.5)|0) : ((fDCTQuant - 0.5)|0);
-  				//outputfDCTQuant[i] = fround(fDCTQuant);
-
-  			}
-  			return outputfDCTQuant;
-  		}
-  		
-  		function writeAPP0()
-  		{
-  			writeWord(0xFFE0); // marker
-  			writeWord(16); // length
-  			writeByte(0x4A); // J
-  			writeByte(0x46); // F
-  			writeByte(0x49); // I
-  			writeByte(0x46); // F
-  			writeByte(0); // = "JFIF",'\0'
-  			writeByte(1); // versionhi
-  			writeByte(1); // versionlo
-  			writeByte(0); // xyunits
-  			writeWord(1); // xdensity
-  			writeWord(1); // ydensity
-  			writeByte(0); // thumbnwidth
-  			writeByte(0); // thumbnheight
-  		}
-  	
-  		function writeSOF0(width, height)
-  		{
-  			writeWord(0xFFC0); // marker
-  			writeWord(17);   // length, truecolor YUV JPG
-  			writeByte(8);    // precision
-  			writeWord(height);
-  			writeWord(width);
-  			writeByte(3);    // nrofcomponents
-  			writeByte(1);    // IdY
-  			writeByte(0x11); // HVY
-  			writeByte(0);    // QTY
-  			writeByte(2);    // IdU
-  			writeByte(0x11); // HVU
-  			writeByte(1);    // QTU
-  			writeByte(3);    // IdV
-  			writeByte(0x11); // HVV
-  			writeByte(1);    // QTV
-  		}
-  	
-  		function writeDQT()
-  		{
-  			writeWord(0xFFDB); // marker
-  			writeWord(132);	   // length
-  			writeByte(0);
-  			for (var i=0; i<64; i++) {
-  				writeByte(YTable[i]);
-  			}
-  			writeByte(1);
-  			for (var j=0; j<64; j++) {
-  				writeByte(UVTable[j]);
-  			}
-  		}
-  	
-  		function writeDHT()
-  		{
-  			writeWord(0xFFC4); // marker
-  			writeWord(0x01A2); // length
-  	
-  			writeByte(0); // HTYDCinfo
-  			for (var i=0; i<16; i++) {
-  				writeByte(std_dc_luminance_nrcodes[i+1]);
-  			}
-  			for (var j=0; j<=11; j++) {
-  				writeByte(std_dc_luminance_values[j]);
-  			}
-  	
-  			writeByte(0x10); // HTYACinfo
-  			for (var k=0; k<16; k++) {
-  				writeByte(std_ac_luminance_nrcodes[k+1]);
-  			}
-  			for (var l=0; l<=161; l++) {
-  				writeByte(std_ac_luminance_values[l]);
-  			}
-  	
-  			writeByte(1); // HTUDCinfo
-  			for (var m=0; m<16; m++) {
-  				writeByte(std_dc_chrominance_nrcodes[m+1]);
-  			}
-  			for (var n=0; n<=11; n++) {
-  				writeByte(std_dc_chrominance_values[n]);
-  			}
-  	
-  			writeByte(0x11); // HTUACinfo
-  			for (var o=0; o<16; o++) {
-  				writeByte(std_ac_chrominance_nrcodes[o+1]);
-  			}
-  			for (var p=0; p<=161; p++) {
-  				writeByte(std_ac_chrominance_values[p]);
-  			}
-  		}
-  	
-  		function writeSOS()
-  		{
-  			writeWord(0xFFDA); // marker
-  			writeWord(12); // length
-  			writeByte(3); // nrofcomponents
-  			writeByte(1); // IdY
-  			writeByte(0); // HTY
-  			writeByte(2); // IdU
-  			writeByte(0x11); // HTU
-  			writeByte(3); // IdV
-  			writeByte(0x11); // HTV
-  			writeByte(0); // Ss
-  			writeByte(0x3f); // Se
-  			writeByte(0); // Bf
-  		}
-  		
-  		function processDU(CDU, fdtbl, DC, HTDC, HTAC){
-  			var EOB = HTAC[0x00];
-  			var M16zeroes = HTAC[0xF0];
-  			var pos;
-  			var I16 = 16;
-  			var I63 = 63;
-  			var I64 = 64;
-  			var DU_DCT = fDCTQuant(CDU, fdtbl);
-  			//ZigZag reorder
-  			for (var j=0;j<I64;++j) {
-  				DU[ZigZag[j]]=DU_DCT[j];
-  			}
-  			var Diff = DU[0] - DC; DC = DU[0];
-  			//Encode DC
-  			if (Diff==0) {
-  				writeBits(HTDC[0]); // Diff might be 0
-  			} else {
-  				pos = 32767+Diff;
-  				writeBits(HTDC[category[pos]]);
-  				writeBits(bitcode[pos]);
-  			}
-  			//Encode ACs
-  			var end0pos = 63; // was const... which is crazy
-  			for (; (end0pos>0)&&(DU[end0pos]==0); end0pos--) {}			//end0pos = first element in reverse order !=0
-  			if ( end0pos == 0) {
-  				writeBits(EOB);
-  				return DC;
-  			}
-  			var i = 1;
-  			var lng;
-  			while ( i <= end0pos ) {
-  				var startpos = i;
-  				for (; (DU[i]==0) && (i<=end0pos); ++i) {}
-  				var nrzeroes = i-startpos;
-  				if ( nrzeroes >= I16 ) {
-  					lng = nrzeroes>>4;
-  					for (var nrmarker=1; nrmarker <= lng; ++nrmarker)
-  						writeBits(M16zeroes);
-  					nrzeroes = nrzeroes&0xF;
-  				}
-  				pos = 32767+DU[i];
-  				writeBits(HTAC[(nrzeroes<<4)+category[pos]]);
-  				writeBits(bitcode[pos]);
-  				i++;
-  			}
-  			if ( end0pos != I63 ) {
-  				writeBits(EOB);
-  			}
-  			return DC;
-  		}
-
-  		function initCharLookupTable(){
-  			var sfcc = String.fromCharCode;
-  			for(var i=0; i < 256; i++){ ///// ACHTUNG // 255
-  				clt[i] = sfcc(i);
-  			}
-  		}
-  		
-  		this.encode = function(image,quality) // image data object
-  		{
-  			var time_start = new Date().getTime();
-  			
-  			if(quality) setQuality(quality);
-  			
-  			// Initialize bit writer
-  			byteout = new Array();
-  			bytenew=0;
-  			bytepos=7;
-  	
-  			// Add JPEG headers
-  			writeWord(0xFFD8); // SOI
-  			writeAPP0();
-  			writeDQT();
-  			writeSOF0(image.width,image.height);
-  			writeDHT();
-  			writeSOS();
-
-  	
-  			// Encode 8x8 macroblocks
-  			var DCY=0;
-  			var DCU=0;
-  			var DCV=0;
-  			
-  			bytenew=0;
-  			bytepos=7;
-  			
-  			
-  			this.encode.displayName = "_encode_";
-
-  			var imageData = image.data;
-  			var width = image.width;
-  			var height = image.height;
-
-  			var quadWidth = width*4;
-  			
-  			var x, y = 0;
-  			var r, g, b;
-  			var start,p, col,row,pos;
-  			while(y < height){
-  				x = 0;
-  				while(x < quadWidth){
-  				start = quadWidth * y + x;
-  				p = start;
-  				col = -1;
-  				row = 0;
-  				
-  				for(pos=0; pos < 64; pos++){
-  					row = pos >> 3;// /8
-  					col = ( pos & 7 ) * 4; // %8
-  					p = start + ( row * quadWidth ) + col;		
-  					
-  					if(y+row >= height){ // padding bottom
-  						p-= (quadWidth*(y+1+row-height));
-  					}
-
-  					if(x+col >= quadWidth){ // padding right	
-  						p-= ((x+col) - quadWidth +4);
-  					}
-  					
-  					r = imageData[ p++ ];
-  					g = imageData[ p++ ];
-  					b = imageData[ p++ ];
-  					
-  					
-  					/* // calculate YUV values dynamically
-  					YDU[pos]=((( 0.29900)*r+( 0.58700)*g+( 0.11400)*b))-128; //-0x80
-  					UDU[pos]=(((-0.16874)*r+(-0.33126)*g+( 0.50000)*b));
-  					VDU[pos]=((( 0.50000)*r+(-0.41869)*g+(-0.08131)*b));
-  					*/
-  					
-  					// use lookup table (slightly faster)
-  					YDU[pos] = ((RGB_YUV_TABLE[r]             + RGB_YUV_TABLE[(g +  256)>>0] + RGB_YUV_TABLE[(b +  512)>>0]) >> 16)-128;
-  					UDU[pos] = ((RGB_YUV_TABLE[(r +  768)>>0] + RGB_YUV_TABLE[(g + 1024)>>0] + RGB_YUV_TABLE[(b + 1280)>>0]) >> 16)-128;
-  					VDU[pos] = ((RGB_YUV_TABLE[(r + 1280)>>0] + RGB_YUV_TABLE[(g + 1536)>>0] + RGB_YUV_TABLE[(b + 1792)>>0]) >> 16)-128;
-
-  				}
-  				
-  				DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
-  				DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
-  				DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
-  				x+=32;
-  				}
-  				y+=8;
-  			}
-  			
-  			
-  			////////////////////////////////////////////////////////////////
-  	
-  			// Do the bit alignment of the EOI marker
-  			if ( bytepos >= 0 ) {
-  				var fillbits = [];
-  				fillbits[1] = bytepos+1;
-  				fillbits[0] = (1<<(bytepos+1))-1;
-  				writeBits(fillbits);
-  			}
-  	
-  			writeWord(0xFFD9); //EOI
-
-        return new Uint8Array(byteout);
-        //return new Buffer(byteout);
-
-  			var jpegDataUri = 'data:image/jpeg;base64,' + btoa(byteout.join(''));
-  			
-  			byteout = [];
-  			
-  			// benchmarking
-  			var duration = new Date().getTime() - time_start;
-      		//console.log('Encoding time: '+ duration + 'ms');
-      		//
-  			
-  			return jpegDataUri			
-  	};
-  	
-  	function setQuality(quality){
-  		if (quality <= 0) {
-  			quality = 1;
-  		}
-  		if (quality > 100) {
-  			quality = 100;
-  		}
-  		
-  		if(currentQuality == quality) return // don't recalc if unchanged
-  		
-  		var sf = 0;
-  		if (quality < 50) {
-  			sf = Math.floor(5000 / quality);
-  		} else {
-  			sf = Math.floor(200 - quality*2);
-  		}
-  		
-  		initQuantTables(sf);
-  		currentQuality = quality;
-  		//console.log('Quality set to: '+quality +'%');
-  	}
-  	
-  	function init(){
-  		var time_start = new Date().getTime();
-  		if(!quality) quality = 50;
-  		// Create tables
-  		initCharLookupTable();
-  		initHuffmanTbl();
-  		initCategoryNumber();
-  		initRGBYUVTable();
-  		
-  		setQuality(quality);
-  		var duration = new Date().getTime() - time_start;
-      	//console.log('Initialization '+ duration + 'ms');
-  	}
-  	
-  	init();
-  	
-  }
+    API.getFormObject = function (key) {
+      var xObject = renderTargets[renderTargetMap[key]];
+      return {
+        x: xObject.x,
+        y: xObject.y,
+        width: xObject.width,
+        height: xObject.height,
+        matrix: xObject.matrix
+      };
+    };
+    /**
+     * Saves as PDF document. An alias of jsPDF.output('save', 'filename.pdf').
+     * Uses FileSaver.js-method saveAs.
+     *
+     * @memberof jsPDF#
+     * @name save
+     * @function
+     * @instance
+     * @param  {string} filename The filename including extension.
+     * @param  {Object} options An Object with additional options, possible options: 'returnPromise'.
+     * @returns {jsPDF|Promise} jsPDF-instance     */
+
+
+    API.save = function (filename, options) {
+      filename = filename || "generated.pdf";
+      options = options || {};
+      options.returnPromise = options.returnPromise || false;
+
+      if (options.returnPromise === false) {
+        saveAs(getBlob(buildDocument()), filename);
+
+        if (typeof saveAs.unload === "function") {
+          if (globalObject.setTimeout) {
+            setTimeout(saveAs.unload, 911);
+          }
+        }
+
+        return this;
+      } else {
+        return new Promise(function (resolve, reject) {
+          try {
+            var result = saveAs(getBlob(buildDocument()), filename);
+
+            if (typeof saveAs.unload === "function") {
+              if (globalObject.setTimeout) {
+                setTimeout(saveAs.unload, 911);
+              }
+            }
+
+            resolve(result);
+          } catch (e) {
+            reject(e.message);
+          }
+        });
+      }
+    }; // applying plugins (more methods) ON TOP of built-in API.
+    // this is intentional as we allow plugins to override
+    // built-ins
+
+
+    for (var plugin in jsPDF.API) {
+      if (jsPDF.API.hasOwnProperty(plugin)) {
+        if (plugin === "events" && jsPDF.API.events.length) {
+          (function (events, newEvents) {
+            // jsPDF.API.events is a JS Array of Arrays
+            // where each Array is a pair of event name, handler
+            // Events were added by plugins to the jsPDF instantiator.
+            // These are always added to the new instance and some ran
+            // during instantiation.
+            var eventname, handler_and_args, i;
+
+            for (i = newEvents.length - 1; i !== -1; i--) {
+              // subscribe takes 3 args: 'topic', function, runonce_flag
+              // if undefined, runonce is false.
+              // users can attach callback directly,
+              // or they can attach an array with [callback, runonce_flag]
+              // that's what the "apply" magic is for below.
+              eventname = newEvents[i][0];
+              handler_and_args = newEvents[i][1];
+              events.subscribe.apply(events, [eventname].concat(typeof handler_and_args === "function" ? [handler_and_args] : handler_and_args));
+            }
+          })(events, jsPDF.API.events);
+        } else {
+          API[plugin] = jsPDF.API[plugin];
+        }
+      }
+    }
+
+    var getPageWidth = API.getPageWidth = function (pageNumber) {
+      pageNumber = pageNumber || currentPage;
+      return (pagesContext[pageNumber].mediaBox.topRightX - pagesContext[pageNumber].mediaBox.bottomLeftX) / scaleFactor;
+    };
+
+    var setPageWidth = API.setPageWidth = function (pageNumber, value) {
+      pagesContext[pageNumber].mediaBox.topRightX = value * scaleFactor + pagesContext[pageNumber].mediaBox.bottomLeftX;
+    };
+
+    var getPageHeight = API.getPageHeight = function (pageNumber) {
+      pageNumber = pageNumber || currentPage;
+      return (pagesContext[pageNumber].mediaBox.topRightY - pagesContext[pageNumber].mediaBox.bottomLeftY) / scaleFactor;
+    };
+
+    var setPageHeight = API.setPageHeight = function (pageNumber, value) {
+      pagesContext[pageNumber].mediaBox.topRightY = value * scaleFactor + pagesContext[pageNumber].mediaBox.bottomLeftY;
+    };
+    /**
+     * Object exposing internal API to plugins
+     * @public
+     * @ignore
+     */
+
+
+    API.internal = {
+      pdfEscape: pdfEscape,
+      getStyle: getStyle,
+      getFont: getFontEntry,
+      getFontSize: getFontSize,
+      getCharSpace: getCharSpace,
+      getTextColor: getTextColor,
+      getLineHeight: getLineHeight,
+      getLineHeightFactor: getLineHeightFactor,
+      getLineWidth: getLineWidth,
+      write: write,
+      getHorizontalCoordinate: getHorizontalCoordinate,
+      getVerticalCoordinate: getVerticalCoordinate,
+      getCoordinateString: getHorizontalCoordinateString,
+      getVerticalCoordinateString: getVerticalCoordinateString,
+      collections: {},
+      newObject: newObject,
+      newAdditionalObject: newAdditionalObject,
+      newObjectDeferred: newObjectDeferred,
+      newObjectDeferredBegin: newObjectDeferredBegin,
+      getFilters: getFilters,
+      putStream: putStream,
+      events: events,
+      scaleFactor: scaleFactor,
+      pageSize: {
+        getWidth: function getWidth() {
+          return getPageWidth(currentPage);
+        },
+        setWidth: function setWidth(value) {
+          setPageWidth(currentPage, value);
+        },
+        getHeight: function getHeight() {
+          return getPageHeight(currentPage);
+        },
+        setHeight: function setHeight(value) {
+          setPageHeight(currentPage, value);
+        }
+      },
+      encryptionOptions: encryptionOptions,
+      encryption: encryption,
+      getEncryptor: getEncryptor,
+      output: output,
+      getNumberOfPages: getNumberOfPages,
+      pages: pages,
+      out: out,
+      f2: f2,
+      f3: f3,
+      getPageInfo: getPageInfo,
+      getPageInfoByObjId: getPageInfoByObjId,
+      getCurrentPageInfo: getCurrentPageInfo,
+      getPDFVersion: getPdfVersion,
+      Point: Point,
+      Rectangle: Rectangle,
+      Matrix: Matrix,
+      hasHotfix: hasHotfix //Expose the hasHotfix check so plugins can also check them.
+
+    };
+    Object.defineProperty(API.internal.pageSize, "width", {
+      get: function get() {
+        return getPageWidth(currentPage);
+      },
+      set: function set(value) {
+        setPageWidth(currentPage, value);
+      },
+      enumerable: true,
+      configurable: true
+    });
+    Object.defineProperty(API.internal.pageSize, "height", {
+      get: function get() {
+        return getPageHeight(currentPage);
+      },
+      set: function set(value) {
+        setPageHeight(currentPage, value);
+      },
+      enumerable: true,
+      configurable: true
+    }); //////////////////////////////////////////////////////
+    // continuing initialization of jsPDF Document object
+    //////////////////////////////////////////////////////
+    // Add the first page automatically
 
+    addFonts.call(API, standardFonts);
+    activeFontKey = "F1";
 
-  try { module.exports = JPEGEncoder; } catch(e) { }  // CommonJS.
+    _addPage(format, orientation);
 
+    events.publish("initialized");
+    return API;
+  }
   /**
-   * @author shaozilee
+   * jsPDF.API is a STATIC property of jsPDF class.
+   * jsPDF.API is an object you can add methods and properties to.
+   * The methods / properties you add will show up in new jsPDF objects.
    *
-   * Bmp format decoder,support 1bit 4bit 8bit 24bit bmp
+   * One property is prepopulated. It is the 'events' Object. Plugin authors can add topics,
+   * callbacks to this object. These will be reassigned to all new instances of jsPDF.
+   *
+   * @static
+   * @public
+   * @memberof jsPDF#
+   * @name API
    *
+   * @example
+   * jsPDF.API.mymethod = function(){
+   *   // 'this' will be ref to internal API object. see jsPDF source
+   *   // , so you can refer to built-in methods like so:
+   *   //     this.line(....)
+   *   //     this.text(....)
+   * }
+   * var pdfdoc = new jsPDF()
+   * pdfdoc.mymethod() // <- !!!!!!
    */
 
-  function BmpDecoder(buffer,is_with_alpha) {
-    this.pos = 0;
-    this.buffer = buffer;
-    this.datav = new DataView(buffer.buffer);
-    this.is_with_alpha = !!is_with_alpha;
-    this.bottom_up = true;
-    this.flag = String.fromCharCode(this.buffer[0]) + String.fromCharCode(this.buffer[1]);
-    this.pos += 2;
-    if (["BM","BA", "CI", "CP", "IC", "PT"].indexOf(this.flag) === -1) throw new Error("Invalid BMP File");
-    this.parseHeader();
-    this.parseBGR();
-  }
 
-  BmpDecoder.prototype.parseHeader = function() {
-    this.fileSize = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.reserved = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.offset = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.headerSize = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.width = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.height = this.datav.getInt32(this.pos, true);  this.pos += 4;
-    this.planes = this.datav.getUint16(this.pos, true); 
-    this.pos += 2;
-    this.bitPP = this.datav.getUint16(this.pos, true); 
-    this.pos += 2;
-    this.compress = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.rawSize = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.hr = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.vr = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.colors = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.importantColors = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
+  jsPDF.API = {
+    events: []
+  };
+  /**
+   * The version of jsPDF.
+   * @name version
+   * @type {string}
+   * @memberof jsPDF#
+   */
 
-    if(this.bitPP === 16 && this.is_with_alpha){
-      this.bitPP = 15;
-    }
-    if (this.bitPP < 15) {
-      var len = this.colors === 0 ? 1 << this.bitPP : this.colors;
-      this.palette = new Array(len);
-      for (var i = 0; i < len; i++) {
-        var blue = this.datav.getUint8(this.pos++, true);      var green = this.datav.getUint8(this.pos++, true);      var red = this.datav.getUint8(this.pos++, true);      var quad = this.datav.getUint8(this.pos++, true);      this.palette[i] = {
-          red: red,
-          green: green,
-          blue: blue,
-          quad: quad
-        };
-      }
-    }
-    if(this.height < 0) {
-      this.height *= -1;
-      this.bottom_up = false;
-    }
+  jsPDF.version = "2.5.1";
 
+  var jsPDFAPI = jsPDF.API;
+  var scaleFactor = 1;
+
+  var pdfEscape = function pdfEscape(value) {
+    return value.replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)");
   };
 
-  BmpDecoder.prototype.parseBGR = function() {
-    this.pos = this.offset;
-    try {
-      var bitn = "bit" + this.bitPP;
-      var len = this.width * this.height * 4;
-      this.data = new Uint8Array(len);
+  var pdfUnescape = function pdfUnescape(value) {
+    return value.replace(/\\\\/g, "\\").replace(/\\\(/g, "(").replace(/\\\)/g, ")");
+  };
 
-      this[bitn]();
-    } catch (e) {
-      console.log("bit decode error:" + e);
-    }
+  var f2 = function f2(number) {
+    return number.toFixed(2); // Ie, %.2f
+  };
 
+  var f5 = function f5(number) {
+    return number.toFixed(5); // Ie, %.2f
   };
 
-  BmpDecoder.prototype.bit1 = function() {
-    var xlen = Math.ceil(this.width / 8);
-    var mode = xlen%4;
-    var y = this.height >= 0 ? this.height - 1 : -this.height;
-    for (var y = this.height - 1; y >= 0; y--) {
-      var line = this.bottom_up ? y : this.height - 1 - y;
-      for (var x = 0; x < xlen; x++) {
-        var b = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x*8*4;
-        for (var i = 0; i < 8; i++) {
-          if(x*8+i<this.width){
-            var rgb = this.palette[((b>>(7-i))&0x1)];
-            this.data[location+i*4] = rgb.blue;
-            this.data[location+i*4 + 1] = rgb.green;
-            this.data[location+i*4 + 2] = rgb.red;
-            this.data[location+i*4 + 3] = 0xFF;
-          }else{
-            break;
-          }
-        }
-      }
+  jsPDFAPI.__acroform__ = {};
 
-      if (mode != 0){
-        this.pos+=(4 - mode);
-      }
-    }
+  var inherit = function inherit(child, parent) {
+    child.prototype = Object.create(parent.prototype);
+    child.prototype.constructor = child;
   };
 
-  BmpDecoder.prototype.bit4 = function() {
-    var xlen = Math.ceil(this.width/2);
-    var mode = xlen%4;
-    for (var y = this.height - 1; y >= 0; y--) {
-      var line = this.bottom_up ? y : this.height - 1 - y;
-      for (var x = 0; x < xlen; x++) {
-        var b = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x*2*4;
-
-        var before = b>>4;
-        var after = b&0x0F;
+  var scale = function scale(x) {
+    return x * scaleFactor;
+  };
 
-        var rgb = this.palette[before];
-        this.data[location] = rgb.blue;
-        this.data[location + 1] = rgb.green;
-        this.data[location + 2] = rgb.red;
-        this.data[location + 3] = 0xFF;
+  var createFormXObject = function createFormXObject(formObject) {
+    var xobj = new AcroFormXObject();
+    var height = AcroFormAppearance.internal.getHeight(formObject) || 0;
+    var width = AcroFormAppearance.internal.getWidth(formObject) || 0;
+    xobj.BBox = [0, 0, Number(f2(width)), Number(f2(height))];
+    return xobj;
+  };
+  /**
+   * Bit-Operations
+   */
 
-        if(x*2+1>=this.width)break;
 
-        rgb = this.palette[after];
-        this.data[location+4] = rgb.blue;
-        this.data[location+4 + 1] = rgb.green;
-        this.data[location+4 + 2] = rgb.red;
-        this.data[location+4 + 3] = 0xFF;
-      }
+  var setBit = jsPDFAPI.__acroform__.setBit = function (number, bitPosition) {
+    number = number || 0;
+    bitPosition = bitPosition || 0;
 
-      if (mode != 0){
-        this.pos+=(4 - mode);
-      }
+    if (isNaN(number) || isNaN(bitPosition)) {
+      throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.setBit");
     }
 
+    var bitMask = 1 << bitPosition;
+    number |= bitMask;
+    return number;
   };
 
-  BmpDecoder.prototype.bit8 = function() {
-    var mode = this.width%4;
-    for (var y = this.height - 1; y >= 0; y--) {
-      var line = this.bottom_up ? y : this.height - 1 - y;
-      for (var x = 0; x < this.width; x++) {
-        var b = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x*4;
-        if(b < this.palette.length) {
-          var rgb = this.palette[b];
-          this.data[location] = rgb.red;
-          this.data[location + 1] = rgb.green;
-          this.data[location + 2] = rgb.blue;
-          this.data[location + 3] = 0xFF;
-        } else {
-          this.data[location] = 0xFF;
-          this.data[location + 1] = 0xFF;
-          this.data[location + 2] = 0xFF;
-          this.data[location + 3] = 0xFF;
-        }
-      }
-      if (mode != 0){
-        this.pos+=(4 - mode);
-      }
-    }
-  };
+  var clearBit = jsPDFAPI.__acroform__.clearBit = function (number, bitPosition) {
+    number = number || 0;
+    bitPosition = bitPosition || 0;
 
-  BmpDecoder.prototype.bit15 = function() {
-    var dif_w =this.width % 3;
-    var _11111 = parseInt("11111", 2),_1_5 = _11111;
-    for (var y = this.height - 1; y >= 0; y--) {
-      var line = this.bottom_up ? y : this.height - 1 - y;
-      for (var x = 0; x < this.width; x++) {
+    if (isNaN(number) || isNaN(bitPosition)) {
+      throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.clearBit");
+    }
 
-        var B = this.datav.getUint16(this.pos, true); 
-        this.pos+=2;
-        var blue = (B & _1_5) / _1_5 * 255 | 0;
-        var green = (B >> 5 & _1_5 ) / _1_5 * 255 | 0;
-        var red = (B >> 10 & _1_5) / _1_5 * 255 | 0;
-        var alpha = (B>>15)?0xFF:0x00;
+    var bitMask = 1 << bitPosition;
+    number &= ~bitMask;
+    return number;
+  };
 
-        var location = line * this.width * 4 + x * 4;
-        this.data[location] = red;
-        this.data[location + 1] = green;
-        this.data[location + 2] = blue;
-        this.data[location + 3] = alpha;
-      }
-      //skip extra bytes
-      this.pos += dif_w;
+  var getBit = jsPDFAPI.__acroform__.getBit = function (number, bitPosition) {
+    if (isNaN(number) || isNaN(bitPosition)) {
+      throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.getBit");
     }
-  };
 
-  BmpDecoder.prototype.bit16 = function() {
-    var dif_w =this.width % 3;
-    var _11111 = parseInt("11111", 2),_1_5 = _11111;
-    var _111111 = parseInt("111111", 2),_1_6 = _111111;
-    for (var y = this.height - 1; y >= 0; y--) {
-      var line = this.bottom_up ? y : this.height - 1 - y;
-      for (var x = 0; x < this.width; x++) {
+    return (number & 1 << bitPosition) === 0 ? 0 : 1;
+  };
+  /*
+   * Ff starts counting the bit position at 1 and not like javascript at 0
+   */
 
-        var B = this.datav.getUint16(this.pos, true); 
-        this.pos+=2;
-        var alpha = 0xFF;
-        var blue = (B & _1_5) / _1_5 * 255 | 0;
-        var green = (B >> 5 & _1_6 ) / _1_6 * 255 | 0;
-        var red = (B >> 11) / _1_5 * 255 | 0;
 
-        var location = line * this.width * 4 + x * 4;
-        this.data[location] = red;
-        this.data[location + 1] = green;
-        this.data[location + 2] = blue;
-        this.data[location + 3] = alpha;
-      }
-      //skip extra bytes
-      this.pos += dif_w;
+  var getBitForPdf = jsPDFAPI.__acroform__.getBitForPdf = function (number, bitPosition) {
+    if (isNaN(number) || isNaN(bitPosition)) {
+      throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.getBitForPdf");
     }
+
+    return getBit(number, bitPosition - 1);
   };
 
-  BmpDecoder.prototype.bit24 = function() {
-    //when height > 0
-    for (var y = this.height - 1; y >= 0; y--) {
-      var line = this.bottom_up ? y : this.height - 1 - y;
-      for (var x = 0; x < this.width; x++) {
-        var blue = this.datav.getUint8(this.pos++, true);      var green = this.datav.getUint8(this.pos++, true);      var red = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x * 4;
-        this.data[location] = red;
-        this.data[location + 1] = green;
-        this.data[location + 2] = blue;
-        this.data[location + 3] = 0xFF;
-      }
-      //skip extra bytes
-      this.pos += (this.width % 4);
+  var setBitForPdf = jsPDFAPI.__acroform__.setBitForPdf = function (number, bitPosition) {
+    if (isNaN(number) || isNaN(bitPosition)) {
+      throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.setBitForPdf");
     }
 
+    return setBit(number, bitPosition - 1);
   };
 
-  /**
-   * add 32bit decode func
-   * @author soubok
-   */
-  BmpDecoder.prototype.bit32 = function() {
-    //when height > 0
-    for (var y = this.height - 1; y >= 0; y--) {
-      var line = this.bottom_up ? y : this.height - 1 - y;
-      for (var x = 0; x < this.width; x++) {
-        var blue = this.datav.getUint8(this.pos++, true);      var green = this.datav.getUint8(this.pos++, true);      var red = this.datav.getUint8(this.pos++, true);      var alpha = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x * 4;
-        this.data[location] = red;
-        this.data[location + 1] = green;
-        this.data[location + 2] = blue;
-        this.data[location + 3] = alpha;
-      }
-      //skip extra bytes
-      //this.pos += (this.width % 4);
+  var clearBitForPdf = jsPDFAPI.__acroform__.clearBitForPdf = function (number, bitPosition) {
+    if (isNaN(number) || isNaN(bitPosition)) {
+      throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.clearBitForPdf");
     }
 
+    return clearBit(number, bitPosition - 1);
   };
 
-  BmpDecoder.prototype.getData = function() {
-    return this.data;
+  var calculateCoordinates = jsPDFAPI.__acroform__.calculateCoordinates = function (args, scope) {
+    var getHorizontalCoordinate = scope.internal.getHorizontalCoordinate;
+    var getVerticalCoordinate = scope.internal.getVerticalCoordinate;
+    var x = args[0];
+    var y = args[1];
+    var w = args[2];
+    var h = args[3];
+    var coordinates = {};
+    coordinates.lowerLeft_X = getHorizontalCoordinate(x) || 0;
+    coordinates.lowerLeft_Y = getVerticalCoordinate(y + h) || 0;
+    coordinates.upperRight_X = getHorizontalCoordinate(x + w) || 0;
+    coordinates.upperRight_Y = getVerticalCoordinate(y) || 0;
+    return [Number(f2(coordinates.lowerLeft_X)), Number(f2(coordinates.lowerLeft_Y)), Number(f2(coordinates.upperRight_X)), Number(f2(coordinates.upperRight_Y))];
   };
 
-  try { 
-  	module.exports = function(bmpData) {
-  		  var decoder = new BmpDecoder(bmpData);
-  		  return {
-  		    data: decoder.getData(),
-  		    width: decoder.width,
-  		    height: decoder.height
-  		  };
-  		};
-  } catch(e) { }  // CommonJS.
-  
+  var calculateAppearanceStream = function calculateAppearanceStream(formObject) {
+    if (formObject.appearanceStreamContent) {
+      return formObject.appearanceStreamContent;
+    }
 
-  /*
-   Copyright (c) 2013 Gildas Lormeau. All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-
-   1. Redistributions of source code must retain the above copyright notice,
-   this list of conditions and the following disclaimer.
-
-   2. Redistributions in binary form must reproduce the above copyright 
-   notice, this list of conditions and the following disclaimer in 
-   the documentation and/or other materials provided with the distribution.
-
-   3. The names of the authors may not be used to endorse or promote products
-   derived from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
-   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
-   INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
-   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-   OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-   EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-   */
+    if (!formObject.V && !formObject.DV) {
+      return;
+    } // else calculate it
 
-  /*
-   * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc.
-   * JZlib is based on zlib-1.1.3, so all credit should go authors
-   * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
-   * and contributors of zlib.
-   */
 
-  (function(global) {
-
-  	// Global
-
-  	var MAX_BITS = 15;
-  	var D_CODES = 30;
-  	var BL_CODES = 19;
-
-  	var LENGTH_CODES = 29;
-  	var LITERALS = 256;
-  	var L_CODES = (LITERALS + 1 + LENGTH_CODES);
-  	var HEAP_SIZE = (2 * L_CODES + 1);
-
-  	var END_BLOCK = 256;
-
-  	// Bit length codes must not exceed MAX_BL_BITS bits
-  	var MAX_BL_BITS = 7;
-
-  	// repeat previous bit length 3-6 times (2 bits of repeat count)
-  	var REP_3_6 = 16;
-
-  	// repeat a zero length 3-10 times (3 bits of repeat count)
-  	var REPZ_3_10 = 17;
-
-  	// repeat a zero length 11-138 times (7 bits of repeat count)
-  	var REPZ_11_138 = 18;
-
-  	// The lengths of the bit length codes are sent in order of decreasing
-  	// probability, to avoid transmitting the lengths for unused bit
-  	// length codes.
-
-  	var Buf_size = 8 * 2;
-
-  	// JZlib version : "1.0.2"
-  	var Z_DEFAULT_COMPRESSION = -1;
-
-  	// compression strategy
-  	var Z_FILTERED = 1;
-  	var Z_HUFFMAN_ONLY = 2;
-  	var Z_DEFAULT_STRATEGY = 0;
-
-  	var Z_NO_FLUSH = 0;
-  	var Z_PARTIAL_FLUSH = 1;
-  	var Z_FULL_FLUSH = 3;
-  	var Z_FINISH = 4;
-
-  	var Z_OK = 0;
-  	var Z_STREAM_END = 1;
-  	var Z_NEED_DICT = 2;
-  	var Z_STREAM_ERROR = -2;
-  	var Z_DATA_ERROR = -3;
-  	var Z_BUF_ERROR = -5;
-
-  	// Tree
-
-  	// see definition of array dist_code below
-  	var _dist_code = [ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  			10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  			12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  			13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  			14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  			14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  			15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19,
-  			20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-  			24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-  			26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-  			27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-  			28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29,
-  			29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-  			29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 ];
-
-  	function Tree() {
-  		var that = this;
-
-  		// dyn_tree; // the dynamic tree
-  		// max_code; // largest code with non zero frequency
-  		// stat_desc; // the corresponding static tree
-
-  		// Compute the optimal bit lengths for a tree and update the total bit
-  		// length
-  		// for the current block.
-  		// IN assertion: the fields freq and dad are set, heap[heap_max] and
-  		// above are the tree nodes sorted by increasing frequency.
-  		// OUT assertions: the field len is set to the optimal bit length, the
-  		// array bl_count contains the frequencies for each bit length.
-  		// The length opt_len is updated; static_len is also updated if stree is
-  		// not null.
-  		function gen_bitlen(s) {
-  			var tree = that.dyn_tree;
-  			var stree = that.stat_desc.static_tree;
-  			var extra = that.stat_desc.extra_bits;
-  			var base = that.stat_desc.extra_base;
-  			var max_length = that.stat_desc.max_length;
-  			var h; // heap index
-  			var n, m; // iterate over the tree elements
-  			var bits; // bit length
-  			var xbits; // extra bits
-  			var f; // frequency
-  			var overflow = 0; // number of elements with bit length too large
-
-  			for (bits = 0; bits <= MAX_BITS; bits++)
-  				s.bl_count[bits] = 0;
-
-  			// In a first pass, compute the optimal bit lengths (which may
-  			// overflow in the case of the bit length tree).
-  			tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap
-
-  			for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {
-  				n = s.heap[h];
-  				bits = tree[tree[n * 2 + 1] * 2 + 1] + 1;
-  				if (bits > max_length) {
-  					bits = max_length;
-  					overflow++;
-  				}
-  				tree[n * 2 + 1] = bits;
-  				// We overwrite tree[n*2+1] which is no longer needed
-
-  				if (n > that.max_code)
-  					continue; // not a leaf node
-
-  				s.bl_count[bits]++;
-  				xbits = 0;
-  				if (n >= base)
-  					xbits = extra[n - base];
-  				f = tree[n * 2];
-  				s.opt_len += f * (bits + xbits);
-  				if (stree)
-  					s.static_len += f * (stree[n * 2 + 1] + xbits);
-  			}
-  			if (overflow === 0)
-  				return;
-
-  			// This happens for example on obj2 and pic of the Calgary corpus
-  			// Find the first bit length which could increase:
-  			do {
-  				bits = max_length - 1;
-  				while (s.bl_count[bits] === 0)
-  					bits--;
-  				s.bl_count[bits]--; // move one leaf down the tree
-  				s.bl_count[bits + 1] += 2; // move one overflow item as its brother
-  				s.bl_count[max_length]--;
-  				// The brother of the overflow item also moves one step up,
-  				// but this does not affect bl_count[max_length]
-  				overflow -= 2;
-  			} while (overflow > 0);
-
-  			for (bits = max_length; bits !== 0; bits--) {
-  				n = s.bl_count[bits];
-  				while (n !== 0) {
-  					m = s.heap[--h];
-  					if (m > that.max_code)
-  						continue;
-  					if (tree[m * 2 + 1] != bits) {
-  						s.opt_len += (bits - tree[m * 2 + 1]) * tree[m * 2];
-  						tree[m * 2 + 1] = bits;
-  					}
-  					n--;
-  				}
-  			}
-  		}
-
-  		// Reverse the first len bits of a code, using straightforward code (a
-  		// faster
-  		// method would use a table)
-  		// IN assertion: 1 <= len <= 15
-  		function bi_reverse(code, // the value to invert
-  		len // its bit length
-  		) {
-  			var res = 0;
-  			do {
-  				res |= code & 1;
-  				code >>>= 1;
-  				res <<= 1;
-  			} while (--len > 0);
-  			return res >>> 1;
-  		}
-
-  		// Generate the codes for a given tree and bit counts (which need not be
-  		// optimal).
-  		// IN assertion: the array bl_count contains the bit length statistics for
-  		// the given tree and the field len is set for all tree elements.
-  		// OUT assertion: the field code is set for all tree elements of non
-  		// zero code length.
-  		function gen_codes(tree, // the tree to decorate
-  		max_code, // largest code with non zero frequency
-  		bl_count // number of codes at each bit length
-  		) {
-  			var next_code = []; // next code value for each
-  			// bit length
-  			var code = 0; // running code value
-  			var bits; // bit index
-  			var n; // code index
-  			var len;
-
-  			// The distribution counts are first used to generate the code values
-  			// without bit reversal.
-  			for (bits = 1; bits <= MAX_BITS; bits++) {
-  				next_code[bits] = code = ((code + bl_count[bits - 1]) << 1);
-  			}
-
-  			// Check that the bit counts in bl_count are consistent. The last code
-  			// must be all ones.
-  			// Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
-  			// "inconsistent bit counts");
-  			// Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
-  			for (n = 0; n <= max_code; n++) {
-  				len = tree[n * 2 + 1];
-  				if (len === 0)
-  					continue;
-  				// Now reverse the bits
-  				tree[n * 2] = bi_reverse(next_code[len]++, len);
-  			}
-  		}
-
-  		// Construct one Huffman tree and assigns the code bit strings and lengths.
-  		// Update the total bit length for the current block.
-  		// IN assertion: the field freq is set for all tree elements.
-  		// OUT assertions: the fields len and code are set to the optimal bit length
-  		// and corresponding code. The length opt_len is updated; static_len is
-  		// also updated if stree is not null. The field max_code is set.
-  		that.build_tree = function(s) {
-  			var tree = that.dyn_tree;
-  			var stree = that.stat_desc.static_tree;
-  			var elems = that.stat_desc.elems;
-  			var n, m; // iterate over heap elements
-  			var max_code = -1; // largest code with non zero frequency
-  			var node; // new node being created
-
-  			// Construct the initial heap, with least frequent element in
-  			// heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
-  			// heap[0] is not used.
-  			s.heap_len = 0;
-  			s.heap_max = HEAP_SIZE;
-
-  			for (n = 0; n < elems; n++) {
-  				if (tree[n * 2] !== 0) {
-  					s.heap[++s.heap_len] = max_code = n;
-  					s.depth[n] = 0;
-  				} else {
-  					tree[n * 2 + 1] = 0;
-  				}
-  			}
-
-  			// The pkzip format requires that at least one distance code exists,
-  			// and that at least one bit should be sent even if there is only one
-  			// possible code. So to avoid special checks later on we force at least
-  			// two codes of non zero frequency.
-  			while (s.heap_len < 2) {
-  				node = s.heap[++s.heap_len] = max_code < 2 ? ++max_code : 0;
-  				tree[node * 2] = 1;
-  				s.depth[node] = 0;
-  				s.opt_len--;
-  				if (stree)
-  					s.static_len -= stree[node * 2 + 1];
-  				// node is 0 or 1 so it does not have extra bits
-  			}
-  			that.max_code = max_code;
-
-  			// The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
-  			// establish sub-heaps of increasing lengths:
-
-  			for (n = Math.floor(s.heap_len / 2); n >= 1; n--)
-  				s.pqdownheap(tree, n);
-
-  			// Construct the Huffman tree by repeatedly combining the least two
-  			// frequent nodes.
-
-  			node = elems; // next internal node of the tree
-  			do {
-  				// n = node of least frequency
-  				n = s.heap[1];
-  				s.heap[1] = s.heap[s.heap_len--];
-  				s.pqdownheap(tree, 1);
-  				m = s.heap[1]; // m = node of next least frequency
-
-  				s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency
-  				s.heap[--s.heap_max] = m;
-
-  				// Create a new node father of n and m
-  				tree[node * 2] = (tree[n * 2] + tree[m * 2]);
-  				s.depth[node] = Math.max(s.depth[n], s.depth[m]) + 1;
-  				tree[n * 2 + 1] = tree[m * 2 + 1] = node;
-
-  				// and insert the new node in the heap
-  				s.heap[1] = node++;
-  				s.pqdownheap(tree, 1);
-  			} while (s.heap_len >= 2);
-
-  			s.heap[--s.heap_max] = s.heap[1];
-
-  			// At this point, the fields freq and dad are set. We can now
-  			// generate the bit lengths.
-
-  			gen_bitlen(s);
-
-  			// The field len is now set, we can generate the bit codes
-  			gen_codes(tree, that.max_code, s.bl_count);
-  		};
-
-  	}
-
-  	Tree._length_code = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16,
-  			16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-  			20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
-  			22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-  			24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-  			25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-  			26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 ];
-
-  	Tree.base_length = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 ];
-
-  	Tree.base_dist = [ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384,
-  			24576 ];
-
-  	// Mapping from a distance to a distance code. dist is the distance - 1 and
-  	// must not have side effects. _dist_code[256] and _dist_code[257] are never
-  	// used.
-  	Tree.d_code = function(dist) {
-  		return ((dist) < 256 ? _dist_code[dist] : _dist_code[256 + ((dist) >>> 7)]);
-  	};
-
-  	// extra bits for each length code
-  	Tree.extra_lbits = [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 ];
-
-  	// extra bits for each distance code
-  	Tree.extra_dbits = [ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 ];
-
-  	// extra bits for each bit length code
-  	Tree.extra_blbits = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 ];
-
-  	Tree.bl_order = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
-
-  	// StaticTree
-
-  	function StaticTree(static_tree, extra_bits, extra_base, elems, max_length) {
-  		var that = this;
-  		that.static_tree = static_tree;
-  		that.extra_bits = extra_bits;
-  		that.extra_base = extra_base;
-  		that.elems = elems;
-  		that.max_length = max_length;
-  	}
-
-  	StaticTree.static_ltree = [ 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, 2, 8,
-  			130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, 202, 8, 42,
-  			8, 170, 8, 106, 8, 234, 8, 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8,
-  			22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, 30, 8, 158, 8, 94, 8,
-  			222, 8, 62, 8, 190, 8, 126, 8, 254, 8, 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113,
-  			8, 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, 5, 8, 133, 8,
-  			69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, 77, 8, 205, 8, 45, 8,
-  			173, 8, 109, 8, 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9,
-  			51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, 171, 9,
-  			427, 9, 107, 9, 363, 9, 235, 9, 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379,
-  			9, 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, 23,
-  			9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, 271, 9, 143, 9,
-  			399, 9, 79, 9, 335, 9, 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9,
-  			223, 9, 479, 9, 63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, 72, 7,
-  			40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8,
-  			99, 8, 227, 8 ];
-
-  	StaticTree.static_dtree = [ 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, 1, 5, 17, 5, 9, 5,
-  			25, 5, 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 ];
-
-  	StaticTree.static_l_desc = new StaticTree(StaticTree.static_ltree, Tree.extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
-
-  	StaticTree.static_d_desc = new StaticTree(StaticTree.static_dtree, Tree.extra_dbits, 0, D_CODES, MAX_BITS);
-
-  	StaticTree.static_bl_desc = new StaticTree(null, Tree.extra_blbits, 0, BL_CODES, MAX_BL_BITS);
-
-  	// Deflate
-
-  	var MAX_MEM_LEVEL = 9;
-  	var DEF_MEM_LEVEL = 8;
-
-  	function Config(good_length, max_lazy, nice_length, max_chain, func) {
-  		var that = this;
-  		that.good_length = good_length;
-  		that.max_lazy = max_lazy;
-  		that.nice_length = nice_length;
-  		that.max_chain = max_chain;
-  		that.func = func;
-  	}
-
-  	var STORED = 0;
-  	var FAST = 1;
-  	var SLOW = 2;
-  	var config_table = [ new Config(0, 0, 0, 0, STORED), new Config(4, 4, 8, 4, FAST), new Config(4, 5, 16, 8, FAST), new Config(4, 6, 32, 32, FAST),
-  			new Config(4, 4, 16, 16, SLOW), new Config(8, 16, 32, 32, SLOW), new Config(8, 16, 128, 128, SLOW), new Config(8, 32, 128, 256, SLOW),
-  			new Config(32, 128, 258, 1024, SLOW), new Config(32, 258, 258, 4096, SLOW) ];
-
-  	var z_errmsg = [ "need dictionary", // Z_NEED_DICT
-  	// 2
-  	"stream end", // Z_STREAM_END 1
-  	"", // Z_OK 0
-  	"", // Z_ERRNO (-1)
-  	"stream error", // Z_STREAM_ERROR (-2)
-  	"data error", // Z_DATA_ERROR (-3)
-  	"", // Z_MEM_ERROR (-4)
-  	"buffer error", // Z_BUF_ERROR (-5)
-  	"",// Z_VERSION_ERROR (-6)
-  	"" ];
-
-  	// block not completed, need more input or more output
-  	var NeedMore = 0;
-
-  	// block flush performed
-  	var BlockDone = 1;
-
-  	// finish started, need only more output at next deflate
-  	var FinishStarted = 2;
-
-  	// finish done, accept no more input or output
-  	var FinishDone = 3;
-
-  	// preset dictionary flag in zlib header
-  	var PRESET_DICT = 0x20;
-
-  	var INIT_STATE = 42;
-  	var BUSY_STATE = 113;
-  	var FINISH_STATE = 666;
-
-  	// The deflate compression method
-  	var Z_DEFLATED = 8;
-
-  	var STORED_BLOCK = 0;
-  	var STATIC_TREES = 1;
-  	var DYN_TREES = 2;
-
-  	var MIN_MATCH = 3;
-  	var MAX_MATCH = 258;
-  	var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
-
-  	function smaller(tree, n, m, depth) {
-  		var tn2 = tree[n * 2];
-  		var tm2 = tree[m * 2];
-  		return (tn2 < tm2 || (tn2 == tm2 && depth[n] <= depth[m]));
-  	}
-
-  	function Deflate() {
-
-  		var that = this;
-  		var strm; // pointer back to this zlib stream
-  		var status; // as the name implies
-  		// pending_buf; // output still pending
-  		var pending_buf_size; // size of pending_buf
-  		var last_flush; // value of flush param for previous deflate call
-
-  		var w_size; // LZ77 window size (32K by default)
-  		var w_bits; // log2(w_size) (8..16)
-  		var w_mask; // w_size - 1
-
-  		var window;
-  		// Sliding window. Input bytes are read into the second half of the window,
-  		// and move to the first half later to keep a dictionary of at least wSize
-  		// bytes. With this organization, matches are limited to a distance of
-  		// wSize-MAX_MATCH bytes, but this ensures that IO is always
-  		// performed with a length multiple of the block size. Also, it limits
-  		// the window size to 64K, which is quite useful on MSDOS.
-  		// To do: use the user input buffer as sliding window.
-
-  		var window_size;
-  		// Actual size of window: 2*wSize, except when the user input buffer
-  		// is directly used as sliding window.
-
-  		var prev;
-  		// Link to older string with same hash index. To limit the size of this
-  		// array to 64K, this link is maintained only for the last 32K strings.
-  		// An index in this array is thus a window index modulo 32K.
-
-  		var head; // Heads of the hash chains or NIL.
-
-  		var ins_h; // hash index of string to be inserted
-  		var hash_size; // number of elements in hash table
-  		var hash_bits; // log2(hash_size)
-  		var hash_mask; // hash_size-1
-
-  		// Number of bits by which ins_h must be shifted at each input
-  		// step. It must be such that after MIN_MATCH steps, the oldest
-  		// byte no longer takes part in the hash key, that is:
-  		// hash_shift * MIN_MATCH >= hash_bits
-  		var hash_shift;
-
-  		// Window position at the beginning of the current output block. Gets
-  		// negative when the window is moved backwards.
-
-  		var block_start;
-
-  		var match_length; // length of best match
-  		var prev_match; // previous match
-  		var match_available; // set if previous match exists
-  		var strstart; // start of string to insert
-  		var match_start; // start of matching string
-  		var lookahead; // number of valid bytes ahead in window
-
-  		// Length of the best match at previous step. Matches not greater than this
-  		// are discarded. This is used in the lazy match evaluation.
-  		var prev_length;
-
-  		// To speed up deflation, hash chains are never searched beyond this
-  		// length. A higher limit improves compression ratio but degrades the speed.
-  		var max_chain_length;
-
-  		// Attempt to find a better match only when the current match is strictly
-  		// smaller than this value. This mechanism is used only for compression
-  		// levels >= 4.
-  		var max_lazy_match;
-
-  		// Insert new strings in the hash table only if the match length is not
-  		// greater than this length. This saves time but degrades compression.
-  		// max_insert_length is used only for compression levels <= 3.
-
-  		var level; // compression level (1..9)
-  		var strategy; // favor or force Huffman coding
-
-  		// Use a faster search when the previous match is longer than this
-  		var good_match;
-
-  		// Stop searching when current match exceeds this
-  		var nice_match;
-
-  		var dyn_ltree; // literal and length tree
-  		var dyn_dtree; // distance tree
-  		var bl_tree; // Huffman tree for bit lengths
-
-  		var l_desc = new Tree(); // desc for literal tree
-  		var d_desc = new Tree(); // desc for distance tree
-  		var bl_desc = new Tree(); // desc for bit length tree
-
-  		// that.heap_len; // number of elements in the heap
-  		// that.heap_max; // element of largest frequency
-  		// The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
-  		// The same heap array is used to build all trees.
-
-  		// Depth of each subtree used as tie breaker for trees of equal frequency
-  		that.depth = [];
-
-  		var l_buf; // index for literals or lengths */
-
-  		// Size of match buffer for literals/lengths. There are 4 reasons for
-  		// limiting lit_bufsize to 64K:
-  		// - frequencies can be kept in 16 bit counters
-  		// - if compression is not successful for the first block, all input
-  		// data is still in the window so we can still emit a stored block even
-  		// when input comes from standard input. (This can also be done for
-  		// all blocks if lit_bufsize is not greater than 32K.)
-  		// - if compression is not successful for a file smaller than 64K, we can
-  		// even emit a stored file instead of a stored block (saving 5 bytes).
-  		// This is applicable only for zip (not gzip or zlib).
-  		// - creating new Huffman trees less frequently may not provide fast
-  		// adaptation to changes in the input data statistics. (Take for
-  		// example a binary file with poorly compressible code followed by
-  		// a highly compressible string table.) Smaller buffer sizes give
-  		// fast adaptation but have of course the overhead of transmitting
-  		// trees more frequently.
-  		// - I can't count above 4
-  		var lit_bufsize;
-
-  		var last_lit; // running index in l_buf
-
-  		// Buffer for distances. To simplify the code, d_buf and l_buf have
-  		// the same number of elements. To use different lengths, an extra flag
-  		// array would be necessary.
-
-  		var d_buf; // index of pendig_buf
-
-  		// that.opt_len; // bit length of current block with optimal trees
-  		// that.static_len; // bit length of current block with static trees
-  		var matches; // number of string matches in current block
-  		var last_eob_len; // bit length of EOB code for last block
-
-  		// Output buffer. bits are inserted starting at the bottom (least
-  		// significant bits).
-  		var bi_buf;
-
-  		// Number of valid bits in bi_buf. All bits above the last valid bit
-  		// are always zero.
-  		var bi_valid;
-
-  		// number of codes at each bit length for an optimal tree
-  		that.bl_count = [];
-
-  		// heap used to build the Huffman trees
-  		that.heap = [];
-
-  		dyn_ltree = [];
-  		dyn_dtree = [];
-  		bl_tree = [];
-
-  		function lm_init() {
-  			var i;
-  			window_size = 2 * w_size;
-
-  			head[hash_size - 1] = 0;
-  			for (i = 0; i < hash_size - 1; i++) {
-  				head[i] = 0;
-  			}
-
-  			// Set the default configuration parameters:
-  			max_lazy_match = config_table[level].max_lazy;
-  			good_match = config_table[level].good_length;
-  			nice_match = config_table[level].nice_length;
-  			max_chain_length = config_table[level].max_chain;
-
-  			strstart = 0;
-  			block_start = 0;
-  			lookahead = 0;
-  			match_length = prev_length = MIN_MATCH - 1;
-  			match_available = 0;
-  			ins_h = 0;
-  		}
-
-  		function init_block() {
-  			var i;
-  			// Initialize the trees.
-  			for (i = 0; i < L_CODES; i++)
-  				dyn_ltree[i * 2] = 0;
-  			for (i = 0; i < D_CODES; i++)
-  				dyn_dtree[i * 2] = 0;
-  			for (i = 0; i < BL_CODES; i++)
-  				bl_tree[i * 2] = 0;
-
-  			dyn_ltree[END_BLOCK * 2] = 1;
-  			that.opt_len = that.static_len = 0;
-  			last_lit = matches = 0;
-  		}
-
-  		// Initialize the tree data structures for a new zlib stream.
-  		function tr_init() {
-
-  			l_desc.dyn_tree = dyn_ltree;
-  			l_desc.stat_desc = StaticTree.static_l_desc;
-
-  			d_desc.dyn_tree = dyn_dtree;
-  			d_desc.stat_desc = StaticTree.static_d_desc;
-
-  			bl_desc.dyn_tree = bl_tree;
-  			bl_desc.stat_desc = StaticTree.static_bl_desc;
-
-  			bi_buf = 0;
-  			bi_valid = 0;
-  			last_eob_len = 8; // enough lookahead for inflate
-
-  			// Initialize the first block of the first file:
-  			init_block();
-  		}
-
-  		// Restore the heap property by moving down the tree starting at node k,
-  		// exchanging a node with the smallest of its two sons if necessary,
-  		// stopping
-  		// when the heap property is re-established (each father smaller than its
-  		// two sons).
-  		that.pqdownheap = function(tree, // the tree to restore
-  		k // node to move down
-  		) {
-  			var heap = that.heap;
-  			var v = heap[k];
-  			var j = k << 1; // left son of k
-  			while (j <= that.heap_len) {
-  				// Set j to the smallest of the two sons:
-  				if (j < that.heap_len && smaller(tree, heap[j + 1], heap[j], that.depth)) {
-  					j++;
-  				}
-  				// Exit if v is smaller than both sons
-  				if (smaller(tree, v, heap[j], that.depth))
-  					break;
-
-  				// Exchange v with the smallest son
-  				heap[k] = heap[j];
-  				k = j;
-  				// And continue down the tree, setting j to the left son of k
-  				j <<= 1;
-  			}
-  			heap[k] = v;
-  		};
-
-  		// Scan a literal or distance tree to determine the frequencies of the codes
-  		// in the bit length tree.
-  		function scan_tree(tree,// the tree to be scanned
-  		max_code // and its largest code of non zero frequency
-  		) {
-  			var n; // iterates over all tree elements
-  			var prevlen = -1; // last emitted length
-  			var curlen; // length of current code
-  			var nextlen = tree[0 * 2 + 1]; // length of next code
-  			var count = 0; // repeat count of the current code
-  			var max_count = 7; // max repeat count
-  			var min_count = 4; // min repeat count
-
-  			if (nextlen === 0) {
-  				max_count = 138;
-  				min_count = 3;
-  			}
-  			tree[(max_code + 1) * 2 + 1] = 0xffff; // guard
-
-  			for (n = 0; n <= max_code; n++) {
-  				curlen = nextlen;
-  				nextlen = tree[(n + 1) * 2 + 1];
-  				if (++count < max_count && curlen == nextlen) {
-  					continue;
-  				} else if (count < min_count) {
-  					bl_tree[curlen * 2] += count;
-  				} else if (curlen !== 0) {
-  					if (curlen != prevlen)
-  						bl_tree[curlen * 2]++;
-  					bl_tree[REP_3_6 * 2]++;
-  				} else if (count <= 10) {
-  					bl_tree[REPZ_3_10 * 2]++;
-  				} else {
-  					bl_tree[REPZ_11_138 * 2]++;
-  				}
-  				count = 0;
-  				prevlen = curlen;
-  				if (nextlen === 0) {
-  					max_count = 138;
-  					min_count = 3;
-  				} else if (curlen == nextlen) {
-  					max_count = 6;
-  					min_count = 3;
-  				} else {
-  					max_count = 7;
-  					min_count = 4;
-  				}
-  			}
-  		}
-
-  		// Construct the Huffman tree for the bit lengths and return the index in
-  		// bl_order of the last bit length code to send.
-  		function build_bl_tree() {
-  			var max_blindex; // index of last bit length code of non zero freq
-
-  			// Determine the bit length frequencies for literal and distance trees
-  			scan_tree(dyn_ltree, l_desc.max_code);
-  			scan_tree(dyn_dtree, d_desc.max_code);
-
-  			// Build the bit length tree:
-  			bl_desc.build_tree(that);
-  			// opt_len now includes the length of the tree representations, except
-  			// the lengths of the bit lengths codes and the 5+5+4 bits for the
-  			// counts.
-
-  			// Determine the number of bit length codes to send. The pkzip format
-  			// requires that at least 4 bit length codes be sent. (appnote.txt says
-  			// 3 but the actual value used is 4.)
-  			for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
-  				if (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] !== 0)
-  					break;
-  			}
-  			// Update opt_len to include the bit length tree and counts
-  			that.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
-
-  			return max_blindex;
-  		}
-
-  		// Output a byte on the stream.
-  		// IN assertion: there is enough room in pending_buf.
-  		function put_byte(p) {
-  			that.pending_buf[that.pending++] = p;
-  		}
-
-  		function put_short(w) {
-  			put_byte(w & 0xff);
-  			put_byte((w >>> 8) & 0xff);
-  		}
-
-  		function putShortMSB(b) {
-  			put_byte((b >> 8) & 0xff);
-  			put_byte((b & 0xff) & 0xff);
-  		}
-
-  		function send_bits(value, length) {
-  			var val, len = length;
-  			if (bi_valid > Buf_size - len) {
-  				val = value;
-  				// bi_buf |= (val << bi_valid);
-  				bi_buf |= ((val << bi_valid) & 0xffff);
-  				put_short(bi_buf);
-  				bi_buf = val >>> (Buf_size - bi_valid);
-  				bi_valid += len - Buf_size;
-  			} else {
-  				// bi_buf |= (value) << bi_valid;
-  				bi_buf |= (((value) << bi_valid) & 0xffff);
-  				bi_valid += len;
-  			}
-  		}
-
-  		function send_code(c, tree) {
-  			var c2 = c * 2;
-  			send_bits(tree[c2] & 0xffff, tree[c2 + 1] & 0xffff);
-  		}
-
-  		// Send a literal or distance tree in compressed form, using the codes in
-  		// bl_tree.
-  		function send_tree(tree,// the tree to be sent
-  		max_code // and its largest code of non zero frequency
-  		) {
-  			var n; // iterates over all tree elements
-  			var prevlen = -1; // last emitted length
-  			var curlen; // length of current code
-  			var nextlen = tree[0 * 2 + 1]; // length of next code
-  			var count = 0; // repeat count of the current code
-  			var max_count = 7; // max repeat count
-  			var min_count = 4; // min repeat count
-
-  			if (nextlen === 0) {
-  				max_count = 138;
-  				min_count = 3;
-  			}
-
-  			for (n = 0; n <= max_code; n++) {
-  				curlen = nextlen;
-  				nextlen = tree[(n + 1) * 2 + 1];
-  				if (++count < max_count && curlen == nextlen) {
-  					continue;
-  				} else if (count < min_count) {
-  					do {
-  						send_code(curlen, bl_tree);
-  					} while (--count !== 0);
-  				} else if (curlen !== 0) {
-  					if (curlen != prevlen) {
-  						send_code(curlen, bl_tree);
-  						count--;
-  					}
-  					send_code(REP_3_6, bl_tree);
-  					send_bits(count - 3, 2);
-  				} else if (count <= 10) {
-  					send_code(REPZ_3_10, bl_tree);
-  					send_bits(count - 3, 3);
-  				} else {
-  					send_code(REPZ_11_138, bl_tree);
-  					send_bits(count - 11, 7);
-  				}
-  				count = 0;
-  				prevlen = curlen;
-  				if (nextlen === 0) {
-  					max_count = 138;
-  					min_count = 3;
-  				} else if (curlen == nextlen) {
-  					max_count = 6;
-  					min_count = 3;
-  				} else {
-  					max_count = 7;
-  					min_count = 4;
-  				}
-  			}
-  		}
-
-  		// Send the header for a block using dynamic Huffman trees: the counts, the
-  		// lengths of the bit length codes, the literal tree and the distance tree.
-  		// IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
-  		function send_all_trees(lcodes, dcodes, blcodes) {
-  			var rank; // index in bl_order
-
-  			send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt
-  			send_bits(dcodes - 1, 5);
-  			send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt
-  			for (rank = 0; rank < blcodes; rank++) {
-  				send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3);
-  			}
-  			send_tree(dyn_ltree, lcodes - 1); // literal tree
-  			send_tree(dyn_dtree, dcodes - 1); // distance tree
-  		}
-
-  		// Flush the bit buffer, keeping at most 7 bits in it.
-  		function bi_flush() {
-  			if (bi_valid == 16) {
-  				put_short(bi_buf);
-  				bi_buf = 0;
-  				bi_valid = 0;
-  			} else if (bi_valid >= 8) {
-  				put_byte(bi_buf & 0xff);
-  				bi_buf >>>= 8;
-  				bi_valid -= 8;
-  			}
-  		}
-
-  		// Send one empty static block to give enough lookahead for inflate.
-  		// This takes 10 bits, of which 7 may remain in the bit buffer.
-  		// The current inflate code requires 9 bits of lookahead. If the
-  		// last two codes for the previous block (real code plus EOB) were coded
-  		// on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
-  		// the last real code. In this case we send two empty static blocks instead
-  		// of one. (There are no problems if the previous block is stored or fixed.)
-  		// To simplify the code, we assume the worst case of last real code encoded
-  		// on one bit only.
-  		function _tr_align() {
-  			send_bits(STATIC_TREES << 1, 3);
-  			send_code(END_BLOCK, StaticTree.static_ltree);
-
-  			bi_flush();
-
-  			// Of the 10 bits for the empty block, we have already sent
-  			// (10 - bi_valid) bits. The lookahead for the last real code (before
-  			// the EOB of the previous block) was thus at least one plus the length
-  			// of the EOB plus what we have just sent of the empty static block.
-  			if (1 + last_eob_len + 10 - bi_valid < 9) {
-  				send_bits(STATIC_TREES << 1, 3);
-  				send_code(END_BLOCK, StaticTree.static_ltree);
-  				bi_flush();
-  			}
-  			last_eob_len = 7;
-  		}
-
-  		// Save the match info and tally the frequency counts. Return true if
-  		// the current block must be flushed.
-  		function _tr_tally(dist, // distance of matched string
-  		lc // match length-MIN_MATCH or unmatched char (if dist==0)
-  		) {
-  			var out_length, in_length, dcode;
-  			that.pending_buf[d_buf + last_lit * 2] = (dist >>> 8) & 0xff;
-  			that.pending_buf[d_buf + last_lit * 2 + 1] = dist & 0xff;
-
-  			that.pending_buf[l_buf + last_lit] = lc & 0xff;
-  			last_lit++;
-
-  			if (dist === 0) {
-  				// lc is the unmatched char
-  				dyn_ltree[lc * 2]++;
-  			} else {
-  				matches++;
-  				// Here, lc is the match length - MIN_MATCH
-  				dist--; // dist = match distance - 1
-  				dyn_ltree[(Tree._length_code[lc] + LITERALS + 1) * 2]++;
-  				dyn_dtree[Tree.d_code(dist) * 2]++;
-  			}
-
-  			if ((last_lit & 0x1fff) === 0 && level > 2) {
-  				// Compute an upper bound for the compressed length
-  				out_length = last_lit * 8;
-  				in_length = strstart - block_start;
-  				for (dcode = 0; dcode < D_CODES; dcode++) {
-  					out_length += dyn_dtree[dcode * 2] * (5 + Tree.extra_dbits[dcode]);
-  				}
-  				out_length >>>= 3;
-  				if ((matches < Math.floor(last_lit / 2)) && out_length < Math.floor(in_length / 2))
-  					return true;
-  			}
-
-  			return (last_lit == lit_bufsize - 1);
-  			// We avoid equality with lit_bufsize because of wraparound at 64K
-  			// on 16 bit machines and because stored blocks are restricted to
-  			// 64K-1 bytes.
-  		}
-
-  		// Send the block data compressed using the given Huffman trees
-  		function compress_block(ltree, dtree) {
-  			var dist; // distance of matched string
-  			var lc; // match length or unmatched char (if dist === 0)
-  			var lx = 0; // running index in l_buf
-  			var code; // the code to send
-  			var extra; // number of extra bits to send
-
-  			if (last_lit !== 0) {
-  				do {
-  					dist = ((that.pending_buf[d_buf + lx * 2] << 8) & 0xff00) | (that.pending_buf[d_buf + lx * 2 + 1] & 0xff);
-  					lc = (that.pending_buf[l_buf + lx]) & 0xff;
-  					lx++;
-
-  					if (dist === 0) {
-  						send_code(lc, ltree); // send a literal byte
-  					} else {
-  						// Here, lc is the match length - MIN_MATCH
-  						code = Tree._length_code[lc];
-
-  						send_code(code + LITERALS + 1, ltree); // send the length
-  						// code
-  						extra = Tree.extra_lbits[code];
-  						if (extra !== 0) {
-  							lc -= Tree.base_length[code];
-  							send_bits(lc, extra); // send the extra length bits
-  						}
-  						dist--; // dist is now the match distance - 1
-  						code = Tree.d_code(dist);
-
-  						send_code(code, dtree); // send the distance code
-  						extra = Tree.extra_dbits[code];
-  						if (extra !== 0) {
-  							dist -= Tree.base_dist[code];
-  							send_bits(dist, extra); // send the extra distance bits
-  						}
-  					} // literal or match pair ?
-
-  					// Check that the overlay between pending_buf and d_buf+l_buf is
-  					// ok:
-  				} while (lx < last_lit);
-  			}
-
-  			send_code(END_BLOCK, ltree);
-  			last_eob_len = ltree[END_BLOCK * 2 + 1];
-  		}
-
-  		// Flush the bit buffer and align the output on a byte boundary
-  		function bi_windup() {
-  			if (bi_valid > 8) {
-  				put_short(bi_buf);
-  			} else if (bi_valid > 0) {
-  				put_byte(bi_buf & 0xff);
-  			}
-  			bi_buf = 0;
-  			bi_valid = 0;
-  		}
-
-  		// Copy a stored block, storing first the length and its
-  		// one's complement if requested.
-  		function copy_block(buf, // the input data
-  		len, // its length
-  		header // true if block header must be written
-  		) {
-  			bi_windup(); // align on byte boundary
-  			last_eob_len = 8; // enough lookahead for inflate
-
-  			if (header) {
-  				put_short(len);
-  				put_short(~len);
-  			}
-
-  			that.pending_buf.set(window.subarray(buf, buf + len), that.pending);
-  			that.pending += len;
-  		}
-
-  		// Send a stored block
-  		function _tr_stored_block(buf, // input block
-  		stored_len, // length of input block
-  		eof // true if this is the last block for a file
-  		) {
-  			send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type
-  			copy_block(buf, stored_len, true); // with header
-  		}
-
-  		// Determine the best encoding for the current block: dynamic trees, static
-  		// trees or store, and output the encoded block to the zip file.
-  		function _tr_flush_block(buf, // input block, or NULL if too old
-  		stored_len, // length of input block
-  		eof // true if this is the last block for a file
-  		) {
-  			var opt_lenb, static_lenb;// opt_len and static_len in bytes
-  			var max_blindex = 0; // index of last bit length code of non zero freq
-
-  			// Build the Huffman trees unless a stored block is forced
-  			if (level > 0) {
-  				// Construct the literal and distance trees
-  				l_desc.build_tree(that);
-
-  				d_desc.build_tree(that);
-
-  				// At this point, opt_len and static_len are the total bit lengths
-  				// of
-  				// the compressed block data, excluding the tree representations.
-
-  				// Build the bit length tree for the above two trees, and get the
-  				// index
-  				// in bl_order of the last bit length code to send.
-  				max_blindex = build_bl_tree();
-
-  				// Determine the best encoding. Compute first the block length in
-  				// bytes
-  				opt_lenb = (that.opt_len + 3 + 7) >>> 3;
-  				static_lenb = (that.static_len + 3 + 7) >>> 3;
-
-  				if (static_lenb <= opt_lenb)
-  					opt_lenb = static_lenb;
-  			} else {
-  				opt_lenb = static_lenb = stored_len + 5; // force a stored block
-  			}
-
-  			if ((stored_len + 4 <= opt_lenb) && buf != -1) {
-  				// 4: two words for the lengths
-  				// The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
-  				// Otherwise we can't have processed more than WSIZE input bytes
-  				// since
-  				// the last block flush, because compression would have been
-  				// successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
-  				// transform a block into a stored block.
-  				_tr_stored_block(buf, stored_len, eof);
-  			} else if (static_lenb == opt_lenb) {
-  				send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3);
-  				compress_block(StaticTree.static_ltree, StaticTree.static_dtree);
-  			} else {
-  				send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3);
-  				send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, max_blindex + 1);
-  				compress_block(dyn_ltree, dyn_dtree);
-  			}
-
-  			// The above check is made mod 2^32, for files larger than 512 MB
-  			// and uLong implemented on 32 bits.
-
-  			init_block();
-
-  			if (eof) {
-  				bi_windup();
-  			}
-  		}
-
-  		function flush_block_only(eof) {
-  			_tr_flush_block(block_start >= 0 ? block_start : -1, strstart - block_start, eof);
-  			block_start = strstart;
-  			strm.flush_pending();
-  		}
-
-  		// Fill the window when the lookahead becomes insufficient.
-  		// Updates strstart and lookahead.
-  		//
-  		// IN assertion: lookahead < MIN_LOOKAHEAD
-  		// OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
-  		// At least one byte has been read, or avail_in === 0; reads are
-  		// performed for at least two bytes (required for the zip translate_eol
-  		// option -- not supported here).
-  		function fill_window() {
-  			var n, m;
-  			var p;
-  			var more; // Amount of free space at the end of the window.
-
-  			do {
-  				more = (window_size - lookahead - strstart);
-
-  				// Deal with !@#$% 64K limit:
-  				if (more === 0 && strstart === 0 && lookahead === 0) {
-  					more = w_size;
-  				} else if (more == -1) {
-  					// Very unlikely, but possible on 16 bit machine if strstart ==
-  					// 0
-  					// and lookahead == 1 (input done one byte at time)
-  					more--;
-
-  					// If the window is almost full and there is insufficient
-  					// lookahead,
-  					// move the upper half to the lower one to make room in the
-  					// upper half.
-  				} else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) {
-  					window.set(window.subarray(w_size, w_size + w_size), 0);
-
-  					match_start -= w_size;
-  					strstart -= w_size; // we now have strstart >= MAX_DIST
-  					block_start -= w_size;
-
-  					// Slide the hash table (could be avoided with 32 bit values
-  					// at the expense of memory usage). We slide even when level ==
-  					// 0
-  					// to keep the hash table consistent if we switch back to level
-  					// > 0
-  					// later. (Using level 0 permanently is not an optimal usage of
-  					// zlib, so we don't care about this pathological case.)
-
-  					n = hash_size;
-  					p = n;
-  					do {
-  						m = (head[--p] & 0xffff);
-  						head[p] = (m >= w_size ? m - w_size : 0);
-  					} while (--n !== 0);
-
-  					n = w_size;
-  					p = n;
-  					do {
-  						m = (prev[--p] & 0xffff);
-  						prev[p] = (m >= w_size ? m - w_size : 0);
-  						// If n is not on any hash chain, prev[n] is garbage but
-  						// its value will never be used.
-  					} while (--n !== 0);
-  					more += w_size;
-  				}
-
-  				if (strm.avail_in === 0)
-  					return;
-
-  				// If there was no sliding:
-  				// strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
-  				// more == window_size - lookahead - strstart
-  				// => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
-  				// => more >= window_size - 2*WSIZE + 2
-  				// In the BIG_MEM or MMAP case (not yet supported),
-  				// window_size == input_size + MIN_LOOKAHEAD &&
-  				// strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
-  				// Otherwise, window_size == 2*WSIZE so more >= 2.
-  				// If there was sliding, more >= WSIZE. So in all cases, more >= 2.
-
-  				n = strm.read_buf(window, strstart + lookahead, more);
-  				lookahead += n;
-
-  				// Initialize the hash value now that we have some input:
-  				if (lookahead >= MIN_MATCH) {
-  					ins_h = window[strstart] & 0xff;
-  					ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
-  				}
-  				// If the whole input has less than MIN_MATCH bytes, ins_h is
-  				// garbage,
-  				// but this is not important since only literal bytes will be
-  				// emitted.
-  			} while (lookahead < MIN_LOOKAHEAD && strm.avail_in !== 0);
-  		}
-
-  		// Copy without compression as much as possible from the input stream,
-  		// return
-  		// the current block state.
-  		// This function does not insert new strings in the dictionary since
-  		// uncompressible data is probably not useful. This function is used
-  		// only for the level=0 compression option.
-  		// NOTE: this function should be optimized to avoid extra copying from
-  		// window to pending_buf.
-  		function deflate_stored(flush) {
-  			// Stored blocks are limited to 0xffff bytes, pending_buf is limited
-  			// to pending_buf_size, and each stored block has a 5 byte header:
-
-  			var max_block_size = 0xffff;
-  			var max_start;
-
-  			if (max_block_size > pending_buf_size - 5) {
-  				max_block_size = pending_buf_size - 5;
-  			}
-
-  			// Copy as much as possible from input to output:
-  			while (true) {
-  				// Fill the window as much as possible:
-  				if (lookahead <= 1) {
-  					fill_window();
-  					if (lookahead === 0 && flush == Z_NO_FLUSH)
-  						return NeedMore;
-  					if (lookahead === 0)
-  						break; // flush the current block
-  				}
-
-  				strstart += lookahead;
-  				lookahead = 0;
-
-  				// Emit a stored block if pending_buf will be full:
-  				max_start = block_start + max_block_size;
-  				if (strstart === 0 || strstart >= max_start) {
-  					// strstart === 0 is possible when wraparound on 16-bit machine
-  					lookahead = (strstart - max_start);
-  					strstart = max_start;
-
-  					flush_block_only(false);
-  					if (strm.avail_out === 0)
-  						return NeedMore;
-
-  				}
-
-  				// Flush if we may have to slide, otherwise block_start may become
-  				// negative and the data will be gone:
-  				if (strstart - block_start >= w_size - MIN_LOOKAHEAD) {
-  					flush_block_only(false);
-  					if (strm.avail_out === 0)
-  						return NeedMore;
-  				}
-  			}
-
-  			flush_block_only(flush == Z_FINISH);
-  			if (strm.avail_out === 0)
-  				return (flush == Z_FINISH) ? FinishStarted : NeedMore;
-
-  			return flush == Z_FINISH ? FinishDone : BlockDone;
-  		}
-
-  		function longest_match(cur_match) {
-  			var chain_length = max_chain_length; // max hash chain length
-  			var scan = strstart; // current string
-  			var match; // matched string
-  			var len; // length of current match
-  			var best_len = prev_length; // best match length so far
-  			var limit = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0;
-  			var _nice_match = nice_match;
-
-  			// Stop when cur_match becomes <= limit. To simplify the code,
-  			// we prevent matches with the string of window index 0.
-
-  			var wmask = w_mask;
-
-  			var strend = strstart + MAX_MATCH;
-  			var scan_end1 = window[scan + best_len - 1];
-  			var scan_end = window[scan + best_len];
-
-  			// The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of
-  			// 16.
-  			// It is easy to get rid of this optimization if necessary.
-
-  			// Do not waste too much time if we already have a good match:
-  			if (prev_length >= good_match) {
-  				chain_length >>= 2;
-  			}
-
-  			// Do not look for matches beyond the end of the input. This is
-  			// necessary
-  			// to make deflate deterministic.
-  			if (_nice_match > lookahead)
-  				_nice_match = lookahead;
-
-  			do {
-  				match = cur_match;
-
-  				// Skip to next match if the match length cannot increase
-  				// or if the match length is less than 2:
-  				if (window[match + best_len] != scan_end || window[match + best_len - 1] != scan_end1 || window[match] != window[scan]
-  						|| window[++match] != window[scan + 1])
-  					continue;
-
-  				// The check at best_len-1 can be removed because it will be made
-  				// again later. (This heuristic is not always a win.)
-  				// It is not necessary to compare scan[2] and match[2] since they
-  				// are always equal when the other bytes match, given that
-  				// the hash keys are equal and that HASH_BITS >= 8.
-  				scan += 2;
-  				match++;
-
-  				// We check for insufficient lookahead only every 8th comparison;
-  				// the 256th check will be made at strstart+258.
-  				do {
-  				} while (window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match]
-  						&& window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match]
-  						&& window[++scan] == window[++match] && window[++scan] == window[++match] && scan < strend);
-
-  				len = MAX_MATCH - (strend - scan);
-  				scan = strend - MAX_MATCH;
-
-  				if (len > best_len) {
-  					match_start = cur_match;
-  					best_len = len;
-  					if (len >= _nice_match)
-  						break;
-  					scan_end1 = window[scan + best_len - 1];
-  					scan_end = window[scan + best_len];
-  				}
-
-  			} while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length !== 0);
-
-  			if (best_len <= lookahead)
-  				return best_len;
-  			return lookahead;
-  		}
-
-  		// Compress as much as possible from the input stream, return the current
-  		// block state.
-  		// This function does not perform lazy evaluation of matches and inserts
-  		// new strings in the dictionary only for unmatched strings or for short
-  		// matches. It is used only for the fast compression options.
-  		function deflate_fast(flush) {
-  			// short hash_head = 0; // head of the hash chain
-  			var hash_head = 0; // head of the hash chain
-  			var bflush; // set if current block must be flushed
-
-  			while (true) {
-  				// Make sure that we always have enough lookahead, except
-  				// at the end of the input file. We need MAX_MATCH bytes
-  				// for the next match, plus MIN_MATCH bytes to insert the
-  				// string following the next match.
-  				if (lookahead < MIN_LOOKAHEAD) {
-  					fill_window();
-  					if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-  						return NeedMore;
-  					}
-  					if (lookahead === 0)
-  						break; // flush the current block
-  				}
-
-  				// Insert the string window[strstart .. strstart+2] in the
-  				// dictionary, and set hash_head to the head of the hash chain:
-  				if (lookahead >= MIN_MATCH) {
-  					ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-
-  					// prev[strstart&w_mask]=hash_head=head[ins_h];
-  					hash_head = (head[ins_h] & 0xffff);
-  					prev[strstart & w_mask] = head[ins_h];
-  					head[ins_h] = strstart;
-  				}
-
-  				// Find the longest match, discarding those <= prev_length.
-  				// At this point we have always match_length < MIN_MATCH
-
-  				if (hash_head !== 0 && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) {
-  					// To simplify the code, we prevent matches with the string
-  					// of window index 0 (in particular we have to avoid a match
-  					// of the string with itself at the start of the input file).
-  					if (strategy != Z_HUFFMAN_ONLY) {
-  						match_length = longest_match(hash_head);
-  					}
-  					// longest_match() sets match_start
-  				}
-  				if (match_length >= MIN_MATCH) {
-  					// check_match(strstart, match_start, match_length);
-
-  					bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH);
-
-  					lookahead -= match_length;
-
-  					// Insert new strings in the hash table only if the match length
-  					// is not too large. This saves time but degrades compression.
-  					if (match_length <= max_lazy_match && lookahead >= MIN_MATCH) {
-  						match_length--; // string at strstart already in hash table
-  						do {
-  							strstart++;
-
-  							ins_h = ((ins_h << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-  							// prev[strstart&w_mask]=hash_head=head[ins_h];
-  							hash_head = (head[ins_h] & 0xffff);
-  							prev[strstart & w_mask] = head[ins_h];
-  							head[ins_h] = strstart;
-
-  							// strstart never exceeds WSIZE-MAX_MATCH, so there are
-  							// always MIN_MATCH bytes ahead.
-  						} while (--match_length !== 0);
-  						strstart++;
-  					} else {
-  						strstart += match_length;
-  						match_length = 0;
-  						ins_h = window[strstart] & 0xff;
-
-  						ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
-  						// If lookahead < MIN_MATCH, ins_h is garbage, but it does
-  						// not
-  						// matter since it will be recomputed at next deflate call.
-  					}
-  				} else {
-  					// No match, output a literal byte
-
-  					bflush = _tr_tally(0, window[strstart] & 0xff);
-  					lookahead--;
-  					strstart++;
-  				}
-  				if (bflush) {
-
-  					flush_block_only(false);
-  					if (strm.avail_out === 0)
-  						return NeedMore;
-  				}
-  			}
-
-  			flush_block_only(flush == Z_FINISH);
-  			if (strm.avail_out === 0) {
-  				if (flush == Z_FINISH)
-  					return FinishStarted;
-  				else
-  					return NeedMore;
-  			}
-  			return flush == Z_FINISH ? FinishDone : BlockDone;
-  		}
-
-  		// Same as above, but achieves better compression. We use a lazy
-  		// evaluation for matches: a match is finally adopted only if there is
-  		// no better match at the next window position.
-  		function deflate_slow(flush) {
-  			// short hash_head = 0; // head of hash chain
-  			var hash_head = 0; // head of hash chain
-  			var bflush; // set if current block must be flushed
-  			var max_insert;
-
-  			// Process the input block.
-  			while (true) {
-  				// Make sure that we always have enough lookahead, except
-  				// at the end of the input file. We need MAX_MATCH bytes
-  				// for the next match, plus MIN_MATCH bytes to insert the
-  				// string following the next match.
-
-  				if (lookahead < MIN_LOOKAHEAD) {
-  					fill_window();
-  					if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-  						return NeedMore;
-  					}
-  					if (lookahead === 0)
-  						break; // flush the current block
-  				}
-
-  				// Insert the string window[strstart .. strstart+2] in the
-  				// dictionary, and set hash_head to the head of the hash chain:
-
-  				if (lookahead >= MIN_MATCH) {
-  					ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-  					// prev[strstart&w_mask]=hash_head=head[ins_h];
-  					hash_head = (head[ins_h] & 0xffff);
-  					prev[strstart & w_mask] = head[ins_h];
-  					head[ins_h] = strstart;
-  				}
-
-  				// Find the longest match, discarding those <= prev_length.
-  				prev_length = match_length;
-  				prev_match = match_start;
-  				match_length = MIN_MATCH - 1;
-
-  				if (hash_head !== 0 && prev_length < max_lazy_match && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) {
-  					// To simplify the code, we prevent matches with the string
-  					// of window index 0 (in particular we have to avoid a match
-  					// of the string with itself at the start of the input file).
-
-  					if (strategy != Z_HUFFMAN_ONLY) {
-  						match_length = longest_match(hash_head);
-  					}
-  					// longest_match() sets match_start
-
-  					if (match_length <= 5 && (strategy == Z_FILTERED || (match_length == MIN_MATCH && strstart - match_start > 4096))) {
-
-  						// If prev_match is also MIN_MATCH, match_start is garbage
-  						// but we will ignore the current match anyway.
-  						match_length = MIN_MATCH - 1;
-  					}
-  				}
-
-  				// If there was a match at the previous step and the current
-  				// match is not better, output the previous match:
-  				if (prev_length >= MIN_MATCH && match_length <= prev_length) {
-  					max_insert = strstart + lookahead - MIN_MATCH;
-  					// Do not insert strings in hash table beyond this.
-
-  					// check_match(strstart-1, prev_match, prev_length);
-
-  					bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);
-
-  					// Insert in hash table all strings up to the end of the match.
-  					// strstart-1 and strstart are already inserted. If there is not
-  					// enough lookahead, the last two strings are not inserted in
-  					// the hash table.
-  					lookahead -= prev_length - 1;
-  					prev_length -= 2;
-  					do {
-  						if (++strstart <= max_insert) {
-  							ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-  							// prev[strstart&w_mask]=hash_head=head[ins_h];
-  							hash_head = (head[ins_h] & 0xffff);
-  							prev[strstart & w_mask] = head[ins_h];
-  							head[ins_h] = strstart;
-  						}
-  					} while (--prev_length !== 0);
-  					match_available = 0;
-  					match_length = MIN_MATCH - 1;
-  					strstart++;
-
-  					if (bflush) {
-  						flush_block_only(false);
-  						if (strm.avail_out === 0)
-  							return NeedMore;
-  					}
-  				} else if (match_available !== 0) {
-
-  					// If there was no match at the previous position, output a
-  					// single literal. If there was a match but the current match
-  					// is longer, truncate the previous match to a single literal.
-
-  					bflush = _tr_tally(0, window[strstart - 1] & 0xff);
-
-  					if (bflush) {
-  						flush_block_only(false);
-  					}
-  					strstart++;
-  					lookahead--;
-  					if (strm.avail_out === 0)
-  						return NeedMore;
-  				} else {
-  					// There is no previous match to compare with, wait for
-  					// the next step to decide.
-
-  					match_available = 1;
-  					strstart++;
-  					lookahead--;
-  				}
-  			}
-
-  			if (match_available !== 0) {
-  				bflush = _tr_tally(0, window[strstart - 1] & 0xff);
-  				match_available = 0;
-  			}
-  			flush_block_only(flush == Z_FINISH);
-
-  			if (strm.avail_out === 0) {
-  				if (flush == Z_FINISH)
-  					return FinishStarted;
-  				else
-  					return NeedMore;
-  			}
-
-  			return flush == Z_FINISH ? FinishDone : BlockDone;
-  		}
-
-  		function deflateReset(strm) {
-  			strm.total_in = strm.total_out = 0;
-  			strm.msg = null; //
-  			
-  			that.pending = 0;
-  			that.pending_out = 0;
-
-  			status = BUSY_STATE;
-
-  			last_flush = Z_NO_FLUSH;
-
-  			tr_init();
-  			lm_init();
-  			return Z_OK;
-  		}
-
-  		that.deflateInit = function(strm, _level, bits, _method, memLevel, _strategy) {
-  			if (!_method)
-  				_method = Z_DEFLATED;
-  			if (!memLevel)
-  				memLevel = DEF_MEM_LEVEL;
-  			if (!_strategy)
-  				_strategy = Z_DEFAULT_STRATEGY;
-
-  			// byte[] my_version=ZLIB_VERSION;
-
-  			//
-  			// if (!version || version[0] != my_version[0]
-  			// || stream_size != sizeof(z_stream)) {
-  			// return Z_VERSION_ERROR;
-  			// }
-
-  			strm.msg = null;
-
-  			if (_level == Z_DEFAULT_COMPRESSION)
-  				_level = 6;
-
-  			if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || _method != Z_DEFLATED || bits < 9 || bits > 15 || _level < 0 || _level > 9 || _strategy < 0
-  					|| _strategy > Z_HUFFMAN_ONLY) {
-  				return Z_STREAM_ERROR;
-  			}
-
-  			strm.dstate = that;
-
-  			w_bits = bits;
-  			w_size = 1 << w_bits;
-  			w_mask = w_size - 1;
-
-  			hash_bits = memLevel + 7;
-  			hash_size = 1 << hash_bits;
-  			hash_mask = hash_size - 1;
-  			hash_shift = Math.floor((hash_bits + MIN_MATCH - 1) / MIN_MATCH);
-
-  			window = new Uint8Array(w_size * 2);
-  			prev = [];
-  			head = [];
-
-  			lit_bufsize = 1 << (memLevel + 6); // 16K elements by default
-
-  			// We overlay pending_buf and d_buf+l_buf. This works since the average
-  			// output size for (length,distance) codes is <= 24 bits.
-  			that.pending_buf = new Uint8Array(lit_bufsize * 4);
-  			pending_buf_size = lit_bufsize * 4;
-
-  			d_buf = Math.floor(lit_bufsize / 2);
-  			l_buf = (1 + 2) * lit_bufsize;
-
-  			level = _level;
-
-  			strategy = _strategy;
-
-  			return deflateReset(strm);
-  		};
-
-  		that.deflateEnd = function() {
-  			if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) {
-  				return Z_STREAM_ERROR;
-  			}
-  			// Deallocate in reverse order of allocations:
-  			that.pending_buf = null;
-  			head = null;
-  			prev = null;
-  			window = null;
-  			// free
-  			that.dstate = null;
-  			return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-  		};
-
-  		that.deflateParams = function(strm, _level, _strategy) {
-  			var err = Z_OK;
-
-  			if (_level == Z_DEFAULT_COMPRESSION) {
-  				_level = 6;
-  			}
-  			if (_level < 0 || _level > 9 || _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) {
-  				return Z_STREAM_ERROR;
-  			}
-
-  			if (config_table[level].func != config_table[_level].func && strm.total_in !== 0) {
-  				// Flush the last buffer:
-  				err = strm.deflate(Z_PARTIAL_FLUSH);
-  			}
-
-  			if (level != _level) {
-  				level = _level;
-  				max_lazy_match = config_table[level].max_lazy;
-  				good_match = config_table[level].good_length;
-  				nice_match = config_table[level].nice_length;
-  				max_chain_length = config_table[level].max_chain;
-  			}
-  			strategy = _strategy;
-  			return err;
-  		};
-
-  		that.deflateSetDictionary = function(strm, dictionary, dictLength) {
-  			var length = dictLength;
-  			var n, index = 0;
-
-  			if (!dictionary || status != INIT_STATE)
-  				return Z_STREAM_ERROR;
-
-  			if (length < MIN_MATCH)
-  				return Z_OK;
-  			if (length > w_size - MIN_LOOKAHEAD) {
-  				length = w_size - MIN_LOOKAHEAD;
-  				index = dictLength - length; // use the tail of the dictionary
-  			}
-  			window.set(dictionary.subarray(index, index + length), 0);
-
-  			strstart = length;
-  			block_start = length;
-
-  			// Insert all strings in the hash table (except for the last two bytes).
-  			// s->lookahead stays null, so s->ins_h will be recomputed at the next
-  			// call of fill_window.
-
-  			ins_h = window[0] & 0xff;
-  			ins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask;
-
-  			for (n = 0; n <= length - MIN_MATCH; n++) {
-  				ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-  				prev[n & w_mask] = head[ins_h];
-  				head[ins_h] = n;
-  			}
-  			return Z_OK;
-  		};
-
-  		that.deflate = function(_strm, flush) {
-  			var i, header, level_flags, old_flush, bstate;
-
-  			if (flush > Z_FINISH || flush < 0) {
-  				return Z_STREAM_ERROR;
-  			}
-
-  			if (!_strm.next_out || (!_strm.next_in && _strm.avail_in !== 0) || (status == FINISH_STATE && flush != Z_FINISH)) {
-  				_strm.msg = z_errmsg[Z_NEED_DICT - (Z_STREAM_ERROR)];
-  				return Z_STREAM_ERROR;
-  			}
-  			if (_strm.avail_out === 0) {
-  				_strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
-  				return Z_BUF_ERROR;
-  			}
-
-  			strm = _strm; // just in case
-  			old_flush = last_flush;
-  			last_flush = flush;
-
-  			// Write the zlib header
-  			if (status == INIT_STATE) {
-  				header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8;
-  				level_flags = ((level - 1) & 0xff) >> 1;
-
-  				if (level_flags > 3)
-  					level_flags = 3;
-  				header |= (level_flags << 6);
-  				if (strstart !== 0)
-  					header |= PRESET_DICT;
-  				header += 31 - (header % 31);
-
-  				status = BUSY_STATE;
-  				putShortMSB(header);
-  			}
-
-  			// Flush as much pending output as possible
-  			if (that.pending !== 0) {
-  				strm.flush_pending();
-  				if (strm.avail_out === 0) {
-  					// console.log(" avail_out==0");
-  					// Since avail_out is 0, deflate will be called again with
-  					// more output space, but possibly with both pending and
-  					// avail_in equal to zero. There won't be anything to do,
-  					// but this is not an error situation so make sure we
-  					// return OK instead of BUF_ERROR at next call of deflate:
-  					last_flush = -1;
-  					return Z_OK;
-  				}
-
-  				// Make sure there is something to do and avoid duplicate
-  				// consecutive
-  				// flushes. For repeated and useless calls with Z_FINISH, we keep
-  				// returning Z_STREAM_END instead of Z_BUFF_ERROR.
-  			} else if (strm.avail_in === 0 && flush <= old_flush && flush != Z_FINISH) {
-  				strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
-  				return Z_BUF_ERROR;
-  			}
-
-  			// User must not provide more input after the first FINISH:
-  			if (status == FINISH_STATE && strm.avail_in !== 0) {
-  				_strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
-  				return Z_BUF_ERROR;
-  			}
-
-  			// Start a new block or continue the current one.
-  			if (strm.avail_in !== 0 || lookahead !== 0 || (flush != Z_NO_FLUSH && status != FINISH_STATE)) {
-  				bstate = -1;
-  				switch (config_table[level].func) {
-  				case STORED:
-  					bstate = deflate_stored(flush);
-  					break;
-  				case FAST:
-  					bstate = deflate_fast(flush);
-  					break;
-  				case SLOW:
-  					bstate = deflate_slow(flush);
-  					break;
-  				default:
-  				}
-
-  				if (bstate == FinishStarted || bstate == FinishDone) {
-  					status = FINISH_STATE;
-  				}
-  				if (bstate == NeedMore || bstate == FinishStarted) {
-  					if (strm.avail_out === 0) {
-  						last_flush = -1; // avoid BUF_ERROR next call, see above
-  					}
-  					return Z_OK;
-  					// If flush != Z_NO_FLUSH && avail_out === 0, the next call
-  					// of deflate should use the same flush parameter to make sure
-  					// that the flush is complete. So we don't have to output an
-  					// empty block here, this will be done at next call. This also
-  					// ensures that for a very small output buffer, we emit at most
-  					// one empty block.
-  				}
-
-  				if (bstate == BlockDone) {
-  					if (flush == Z_PARTIAL_FLUSH) {
-  						_tr_align();
-  					} else { // FULL_FLUSH or SYNC_FLUSH
-  						_tr_stored_block(0, 0, false);
-  						// For a full flush, this empty block will be recognized
-  						// as a special marker by inflate_sync().
-  						if (flush == Z_FULL_FLUSH) {
-  							// state.head[s.hash_size-1]=0;
-  							for (i = 0; i < hash_size/*-1*/; i++)
-  								// forget history
-  								head[i] = 0;
-  						}
-  					}
-  					strm.flush_pending();
-  					if (strm.avail_out === 0) {
-  						last_flush = -1; // avoid BUF_ERROR at next call, see above
-  						return Z_OK;
-  					}
-  				}
-  			}
-
-  			if (flush != Z_FINISH)
-  				return Z_OK;
-  			return Z_STREAM_END;
-  		};
-  	}
-
-  	// ZStream
-
-  	function ZStream() {
-  		var that = this;
-  		that.next_in_index = 0;
-  		that.next_out_index = 0;
-  		// that.next_in; // next input byte
-  		that.avail_in = 0; // number of bytes available at next_in
-  		that.total_in = 0; // total nb of input bytes read so far
-  		// that.next_out; // next output byte should be put there
-  		that.avail_out = 0; // remaining free space at next_out
-  		that.total_out = 0; // total nb of bytes output so far
-  		// that.msg;
-  		// that.dstate;
-  	}
-
-  	ZStream.prototype = {
-  		deflateInit : function(level, bits) {
-  			var that = this;
-  			that.dstate = new Deflate();
-  			if (!bits)
-  				bits = MAX_BITS;
-  			return that.dstate.deflateInit(that, level, bits);
-  		},
-
-  		deflate : function(flush) {
-  			var that = this;
-  			if (!that.dstate) {
-  				return Z_STREAM_ERROR;
-  			}
-  			return that.dstate.deflate(that, flush);
-  		},
-
-  		deflateEnd : function() {
-  			var that = this;
-  			if (!that.dstate)
-  				return Z_STREAM_ERROR;
-  			var ret = that.dstate.deflateEnd();
-  			that.dstate = null;
-  			return ret;
-  		},
-
-  		deflateParams : function(level, strategy) {
-  			var that = this;
-  			if (!that.dstate)
-  				return Z_STREAM_ERROR;
-  			return that.dstate.deflateParams(that, level, strategy);
-  		},
-
-  		deflateSetDictionary : function(dictionary, dictLength) {
-  			var that = this;
-  			if (!that.dstate)
-  				return Z_STREAM_ERROR;
-  			return that.dstate.deflateSetDictionary(that, dictionary, dictLength);
-  		},
-
-  		// Read a new buffer from the current input stream, update the
-  		// total number of bytes read. All deflate() input goes through
-  		// this function so some applications may wish to modify it to avoid
-  		// allocating a large strm->next_in buffer and copying from it.
-  		// (See also flush_pending()).
-  		read_buf : function(buf, start, size) {
-  			var that = this;
-  			var len = that.avail_in;
-  			if (len > size)
-  				len = size;
-  			if (len === 0)
-  				return 0;
-  			that.avail_in -= len;
-  			buf.set(that.next_in.subarray(that.next_in_index, that.next_in_index + len), start);
-  			that.next_in_index += len;
-  			that.total_in += len;
-  			return len;
-  		},
-
-  		// Flush as much pending output as possible. All deflate() output goes
-  		// through this function so some applications may wish to modify it
-  		// to avoid allocating a large strm->next_out buffer and copying into it.
-  		// (See also read_buf()).
-  		flush_pending : function() {
-  			var that = this;
-  			var len = that.dstate.pending;
-
-  			if (len > that.avail_out)
-  				len = that.avail_out;
-  			if (len === 0)
-  				return;
-
-  			// if (that.dstate.pending_buf.length <= that.dstate.pending_out || that.next_out.length <= that.next_out_index
-  			// || that.dstate.pending_buf.length < (that.dstate.pending_out + len) || that.next_out.length < (that.next_out_index +
-  			// len)) {
-  			// console.log(that.dstate.pending_buf.length + ", " + that.dstate.pending_out + ", " + that.next_out.length + ", " +
-  			// that.next_out_index + ", " + len);
-  			// console.log("avail_out=" + that.avail_out);
-  			// }
-
-  			that.next_out.set(that.dstate.pending_buf.subarray(that.dstate.pending_out, that.dstate.pending_out + len), that.next_out_index);
-
-  			that.next_out_index += len;
-  			that.dstate.pending_out += len;
-  			that.total_out += len;
-  			that.avail_out -= len;
-  			that.dstate.pending -= len;
-  			if (that.dstate.pending === 0) {
-  				that.dstate.pending_out = 0;
-  			}
-  		}
-  	};
-
-  	// Deflater
-
-  	function Deflater(options) {
-  		var that = this;
-  		var z = new ZStream();
-  		var bufsize = 512;
-  		var flush = Z_NO_FLUSH;
-  		var buf = new Uint8Array(bufsize);
-  		var level = options ? options.level : Z_DEFAULT_COMPRESSION;
-  		if (typeof level == "undefined")
-  			level = Z_DEFAULT_COMPRESSION;
-  		z.deflateInit(level);
-  		z.next_out = buf;
-
-  		that.append = function(data, onprogress) {
-  			var err, buffers = [], lastIndex = 0, bufferIndex = 0, bufferSize = 0, array;
-  			if (!data.length)
-  				return;
-  			z.next_in_index = 0;
-  			z.next_in = data;
-  			z.avail_in = data.length;
-  			do {
-  				z.next_out_index = 0;
-  				z.avail_out = bufsize;
-  				err = z.deflate(flush);
-  				if (err != Z_OK)
-  					throw new Error("deflating: " + z.msg);
-  				if (z.next_out_index)
-  					if (z.next_out_index == bufsize)
-  						buffers.push(new Uint8Array(buf));
-  					else
-  						buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
-  				bufferSize += z.next_out_index;
-  				if (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) {
-  					onprogress(z.next_in_index);
-  					lastIndex = z.next_in_index;
-  				}
-  			} while (z.avail_in > 0 || z.avail_out === 0);
-  			array = new Uint8Array(bufferSize);
-  			buffers.forEach(function(chunk) {
-  				array.set(chunk, bufferIndex);
-  				bufferIndex += chunk.length;
-  			});
-  			return array;
-  		};
-  		that.flush = function() {
-  			var err, buffers = [], bufferIndex = 0, bufferSize = 0, array;
-  			do {
-  				z.next_out_index = 0;
-  				z.avail_out = bufsize;
-  				err = z.deflate(Z_FINISH);
-  				if (err != Z_STREAM_END && err != Z_OK)
-  					throw new Error("deflating: " + z.msg);
-  				if (bufsize - z.avail_out > 0)
-  					buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
-  				bufferSize += z.next_out_index;
-  			} while (z.avail_in > 0 || z.avail_out === 0);
-  			z.deflateEnd();
-  			array = new Uint8Array(bufferSize);
-  			buffers.forEach(function(chunk) {
-  				array.set(chunk, bufferIndex);
-  				bufferIndex += chunk.length;
-  			});
-  			return array;
-  		};
-  	}
-
-  	// 'zip' may not be defined in z-worker and some tests
-  	var env = global.zip || global;
-  	env.Deflater = env._jzlib_Deflater = Deflater;
-  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global ||  Function('return typeof this === "object" && this.content')() || Function('return this')()));
-  // `self` is undefined in Firefox for Android content script context
-  // while `this` is nsIContentFrameMessageManager
-  // with an attribute `content` that corresponds to the window
+    var stream = [];
+    var text = formObject._V || formObject.DV;
+    var calcRes = calculateX(formObject, text);
+    var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id; //PDF 32000-1:2008, page 444
 
-  /**
-   * A class to parse color values
-   * @author Stoyan Stefanov <sstoo@gmail.com>
-   * @link   http://www.phpied.com/rgb-color-parser-in-javascript/
-   * @license Use it if you like it
-   */
-   
-  (function ( global ) {
-   
-  	function RGBColor(color_string)
-  	{
-  		this.ok = false;
-
-  		// strip any leading #
-  		if (color_string.charAt(0) == '#') { // remove # if any
-  			color_string = color_string.substr(1,6);
-  		}
-
-  		color_string = color_string.replace(/ /g,'');
-  		color_string = color_string.toLowerCase();
-
-  		var channels;
-
-  		// before getting into regexps, try simple matches
-  		// and overwrite the input
-  		var simple_colors = {
-  			aliceblue: 'f0f8ff',
-  			antiquewhite: 'faebd7',
-  			aqua: '00ffff',
-  			aquamarine: '7fffd4',
-  			azure: 'f0ffff',
-  			beige: 'f5f5dc',
-  			bisque: 'ffe4c4',
-  			black: '000000',
-  			blanchedalmond: 'ffebcd',
-  			blue: '0000ff',
-  			blueviolet: '8a2be2',
-  			brown: 'a52a2a',
-  			burlywood: 'deb887',
-  			cadetblue: '5f9ea0',
-  			chartreuse: '7fff00',
-  			chocolate: 'd2691e',
-  			coral: 'ff7f50',
-  			cornflowerblue: '6495ed',
-  			cornsilk: 'fff8dc',
-  			crimson: 'dc143c',
-  			cyan: '00ffff',
-  			darkblue: '00008b',
-  			darkcyan: '008b8b',
-  			darkgoldenrod: 'b8860b',
-  			darkgray: 'a9a9a9',
-  			darkgreen: '006400',
-  			darkkhaki: 'bdb76b',
-  			darkmagenta: '8b008b',
-  			darkolivegreen: '556b2f',
-  			darkorange: 'ff8c00',
-  			darkorchid: '9932cc',
-  			darkred: '8b0000',
-  			darksalmon: 'e9967a',
-  			darkseagreen: '8fbc8f',
-  			darkslateblue: '483d8b',
-  			darkslategray: '2f4f4f',
-  			darkturquoise: '00ced1',
-  			darkviolet: '9400d3',
-  			deeppink: 'ff1493',
-  			deepskyblue: '00bfff',
-  			dimgray: '696969',
-  			dodgerblue: '1e90ff',
-  			feldspar: 'd19275',
-  			firebrick: 'b22222',
-  			floralwhite: 'fffaf0',
-  			forestgreen: '228b22',
-  			fuchsia: 'ff00ff',
-  			gainsboro: 'dcdcdc',
-  			ghostwhite: 'f8f8ff',
-  			gold: 'ffd700',
-  			goldenrod: 'daa520',
-  			gray: '808080',
-  			green: '008000',
-  			greenyellow: 'adff2f',
-  			honeydew: 'f0fff0',
-  			hotpink: 'ff69b4',
-  			indianred : 'cd5c5c',
-  			indigo : '4b0082',
-  			ivory: 'fffff0',
-  			khaki: 'f0e68c',
-  			lavender: 'e6e6fa',
-  			lavenderblush: 'fff0f5',
-  			lawngreen: '7cfc00',
-  			lemonchiffon: 'fffacd',
-  			lightblue: 'add8e6',
-  			lightcoral: 'f08080',
-  			lightcyan: 'e0ffff',
-  			lightgoldenrodyellow: 'fafad2',
-  			lightgrey: 'd3d3d3',
-  			lightgreen: '90ee90',
-  			lightpink: 'ffb6c1',
-  			lightsalmon: 'ffa07a',
-  			lightseagreen: '20b2aa',
-  			lightskyblue: '87cefa',
-  			lightslateblue: '8470ff',
-  			lightslategray: '778899',
-  			lightsteelblue: 'b0c4de',
-  			lightyellow: 'ffffe0',
-  			lime: '00ff00',
-  			limegreen: '32cd32',
-  			linen: 'faf0e6',
-  			magenta: 'ff00ff',
-  			maroon: '800000',
-  			mediumaquamarine: '66cdaa',
-  			mediumblue: '0000cd',
-  			mediumorchid: 'ba55d3',
-  			mediumpurple: '9370d8',
-  			mediumseagreen: '3cb371',
-  			mediumslateblue: '7b68ee',
-  			mediumspringgreen: '00fa9a',
-  			mediumturquoise: '48d1cc',
-  			mediumvioletred: 'c71585',
-  			midnightblue: '191970',
-  			mintcream: 'f5fffa',
-  			mistyrose: 'ffe4e1',
-  			moccasin: 'ffe4b5',
-  			navajowhite: 'ffdead',
-  			navy: '000080',
-  			oldlace: 'fdf5e6',
-  			olive: '808000',
-  			olivedrab: '6b8e23',
-  			orange: 'ffa500',
-  			orangered: 'ff4500',
-  			orchid: 'da70d6',
-  			palegoldenrod: 'eee8aa',
-  			palegreen: '98fb98',
-  			paleturquoise: 'afeeee',
-  			palevioletred: 'd87093',
-  			papayawhip: 'ffefd5',
-  			peachpuff: 'ffdab9',
-  			peru: 'cd853f',
-  			pink: 'ffc0cb',
-  			plum: 'dda0dd',
-  			powderblue: 'b0e0e6',
-  			purple: '800080',
-  			red: 'ff0000',
-  			rosybrown: 'bc8f8f',
-  			royalblue: '4169e1',
-  			saddlebrown: '8b4513',
-  			salmon: 'fa8072',
-  			sandybrown: 'f4a460',
-  			seagreen: '2e8b57',
-  			seashell: 'fff5ee',
-  			sienna: 'a0522d',
-  			silver: 'c0c0c0',
-  			skyblue: '87ceeb',
-  			slateblue: '6a5acd',
-  			slategray: '708090',
-  			snow: 'fffafa',
-  			springgreen: '00ff7f',
-  			steelblue: '4682b4',
-  			tan: 'd2b48c',
-  			teal: '008080',
-  			thistle: 'd8bfd8',
-  			tomato: 'ff6347',
-  			turquoise: '40e0d0',
-  			violet: 'ee82ee',
-  			violetred: 'd02090',
-  			wheat: 'f5deb3',
-  			white: 'ffffff',
-  			whitesmoke: 'f5f5f5',
-  			yellow: 'ffff00',
-  			yellowgreen: '9acd32'
-  		};
-  		for (var key in simple_colors) {
-  			if (color_string == key) {
-  				color_string = simple_colors[key];
-  			}
-  		}
-  		// emd of simple type-in colors
-
-  		// array of color definition objects
-  		var color_defs = [
-  			{
-  				re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
-  				example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'],
-  				process: function (bits){
-  					return [
-  						parseInt(bits[1]),
-  						parseInt(bits[2]),
-  						parseInt(bits[3])
-  					];
-  				}
-  			},
-  			{
-  				re: /^(\w{2})(\w{2})(\w{2})$/,
-  				example: ['#00ff00', '336699'],
-  				process: function (bits){
-  					return [
-  						parseInt(bits[1], 16),
-  						parseInt(bits[2], 16),
-  						parseInt(bits[3], 16)
-  					];
-  				}
-  			},
-  			{
-  				re: /^(\w{1})(\w{1})(\w{1})$/,
-  				example: ['#fb0', 'f0f'],
-  				process: function (bits){
-  					return [
-  						parseInt(bits[1] + bits[1], 16),
-  						parseInt(bits[2] + bits[2], 16),
-  						parseInt(bits[3] + bits[3], 16)
-  					];
-  				}
-  			}
-  		];
-
-  		// search through the definitions to find a match
-  		for (var i = 0; i < color_defs.length; i++) {
-  			var re = color_defs[i].re;
-  			var processor = color_defs[i].process;
-  			var bits = re.exec(color_string);
-  			if (bits) {
-  				channels = processor(bits);
-  				this.r = channels[0];
-  				this.g = channels[1];
-  				this.b = channels[2];
-  				this.ok = true;
-  			}
-
-  		}
-
-  		// validate/cleanup values
-  		this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);
-  		this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g);
-  		this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b);
-
-  		// some getters
-  		this.toRGB = function () {
-  			return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')';
-  		};
-  		this.toHex = function () {
-  			var r = this.r.toString(16);
-  			var g = this.g.toString(16);
-  			var b = this.b.toString(16);
-  			if (r.length == 1) r = '0' + r;
-  			if (g.length == 1) g = '0' + g;
-  			if (b.length == 1) b = '0' + b;
-  			return '#' + r + g + b;
-  		};
-
-  		// help
-  		this.getHelpXML = function () {
-
-  			var examples = new Array();
-  			// add regexps
-  			for (var i = 0; i < color_defs.length; i++) {
-  				var example = color_defs[i].example;
-  				for (var j = 0; j < example.length; j++) {
-  					examples[examples.length] = example[j];
-  				}
-  			}
-  			// add type-in colors
-  			for (var sc in simple_colors) {
-  				examples[examples.length] = sc;
-  			}
-
-  			var xml = document.createElement('ul');
-  			xml.setAttribute('id', 'rgbcolor-examples');
-  			for (var i = 0; i < examples.length; i++) {
-  				try {
-  					var list_item = document.createElement('li');
-  					var list_color = new RGBColor(examples[i]);
-  					var example_div = document.createElement('div');
-  					example_div.style.cssText =
-  							'margin: 3px; '
-  							+ 'border: 1px solid black; '
-  							+ 'background:' + list_color.toHex() + '; '
-  							+ 'color:' + list_color.toHex()
-  					;
-  					example_div.appendChild(document.createTextNode('test'));
-  					var list_item_value = document.createTextNode(
-  						' ' + examples[i] + ' -> ' + list_color.toRGB() + ' -> ' + list_color.toHex()
-  					);
-  					list_item.appendChild(example_div);
-  					list_item.appendChild(list_item_value);
-  					xml.appendChild(list_item);
-
-  				} catch(e){}
-  			}
-  			return xml;
-
-  		};
-
-  	}
-
-      // export as AMD...
-      if ( typeof define !== 'undefined' && define.amd ) {
-          define('RGBColor', function () { return RGBColor; });
-      }
-
-      // ...or as browserify
-      else if (typeof module !== 'undefined' && module.exports ) {
-          module.exports = RGBColor;
-      }
-
-      global.RGBColor = RGBColor;
-  	
-  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global ||  Function('return typeof this === "object" && this.content')() || Function('return this')()));
-  // `self` is undefined in Firefox for Android content script context
-  // while `this` is nsIContentFrameMessageManager
-  // with an attribute `content` that corresponds to the window
+    stream.push("/Tx BMC");
+    stream.push("q");
+    stream.push("BT"); // Begin Text
 
-  /*
-    html2canvas 0.5.0-beta3 <http://html2canvas.hertzen.com>
-    Copyright (c) 2016 Niklas von Hertzen
+    stream.push(formObject.scope.__private__.encodeColorString(formObject.color));
+    stream.push("/" + fontKey + " " + f2(calcRes.fontSize) + " Tf");
+    stream.push("1 0 0 1 0 0 Tm"); // Transformation Matrix
 
-    Released under  License
-  */
+    stream.push(calcRes.text);
+    stream.push("ET"); // End Text
 
-  !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define("html2canvas",[],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.html2canvas=e();}}(function(){var define;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r);}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
-  (function (global){
-  (function(root) {
-
-  	/** Detect free variables */
-  	var freeExports = typeof exports == 'object' && exports;
-  	var freeModule = typeof module == 'object' && module &&
-  		module.exports == freeExports && module;
-  	var freeGlobal = typeof global == 'object' && global;
-  	if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
-  		root = freeGlobal;
-  	}
-
-  	/**
-  	 * The `punycode` object.
-  	 * @name punycode
-  	 * @type Object
-  	 */
-  	var punycode,
-
-  	/** Highest positive signed 32-bit float value */
-  	maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
-
-  	/** Bootstring parameters */
-  	base = 36,
-  	tMin = 1,
-  	tMax = 26,
-  	skew = 38,
-  	damp = 700,
-  	initialBias = 72,
-  	initialN = 128, // 0x80
-  	delimiter = '-', // '\x2D'
-
-  	/** Regular expressions */
-  	regexPunycode = /^xn--/,
-  	regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars
-  	regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators
-
-  	/** Error messages */
-  	errors = {
-  		'overflow': 'Overflow: input needs wider integers to process',
-  		'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
-  		'invalid-input': 'Invalid input'
-  	},
-
-  	/** Convenience shortcuts */
-  	baseMinusTMin = base - tMin,
-  	floor = Math.floor,
-  	stringFromCharCode = String.fromCharCode,
-
-  	/** Temporary variable */
-  	key;
-
-  	/*--------------------------------------------------------------------------*/
-
-  	/**
-  	 * A generic error utility function.
-  	 * @private
-  	 * @param {String} type The error type.
-  	 * @returns {Error} Throws a `RangeError` with the applicable error message.
-  	 */
-  	function error(type) {
-  		throw RangeError(errors[type]);
-  	}
-
-  	/**
-  	 * A generic `Array#map` utility function.
-  	 * @private
-  	 * @param {Array} array The array to iterate over.
-  	 * @param {Function} callback The function that gets called for every array
-  	 * item.
-  	 * @returns {Array} A new array of values returned by the callback function.
-  	 */
-  	function map(array, fn) {
-  		var length = array.length;
-  		while (length--) {
-  			array[length] = fn(array[length]);
-  		}
-  		return array;
-  	}
-
-  	/**
-  	 * A simple `Array#map`-like wrapper to work with domain name strings.
-  	 * @private
-  	 * @param {String} domain The domain name.
-  	 * @param {Function} callback The function that gets called for every
-  	 * character.
-  	 * @returns {Array} A new string of characters returned by the callback
-  	 * function.
-  	 */
-  	function mapDomain(string, fn) {
-  		return map(string.split(regexSeparators), fn).join('.');
-  	}
-
-  	/**
-  	 * Creates an array containing the numeric code points of each Unicode
-  	 * character in the string. While JavaScript uses UCS-2 internally,
-  	 * this function will convert a pair of surrogate halves (each of which
-  	 * UCS-2 exposes as separate characters) into a single code point,
-  	 * matching UTF-16.
-  	 * @see `punycode.ucs2.encode`
-  	 * @see <http://mathiasbynens.be/notes/javascript-encoding>
-  	 * @memberOf punycode.ucs2
-  	 * @name decode
-  	 * @param {String} string The Unicode input string (UCS-2).
-  	 * @returns {Array} The new array of code points.
-  	 */
-  	function ucs2decode(string) {
-  		var output = [],
-  		    counter = 0,
-  		    length = string.length,
-  		    value,
-  		    extra;
-  		while (counter < length) {
-  			value = string.charCodeAt(counter++);
-  			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
-  				// high surrogate, and there is a next character
-  				extra = string.charCodeAt(counter++);
-  				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
-  					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
-  				} else {
-  					// unmatched surrogate; only append this code unit, in case the next
-  					// code unit is the high surrogate of a surrogate pair
-  					output.push(value);
-  					counter--;
-  				}
-  			} else {
-  				output.push(value);
-  			}
-  		}
-  		return output;
-  	}
-
-  	/**
-  	 * Creates a string based on an array of numeric code points.
-  	 * @see `punycode.ucs2.decode`
-  	 * @memberOf punycode.ucs2
-  	 * @name encode
-  	 * @param {Array} codePoints The array of numeric code points.
-  	 * @returns {String} The new Unicode string (UCS-2).
-  	 */
-  	function ucs2encode(array) {
-  		return map(array, function(value) {
-  			var output = '';
-  			if (value > 0xFFFF) {
-  				value -= 0x10000;
-  				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
-  				value = 0xDC00 | value & 0x3FF;
-  			}
-  			output += stringFromCharCode(value);
-  			return output;
-  		}).join('');
-  	}
-
-  	/**
-  	 * Converts a basic code point into a digit/integer.
-  	 * @see `digitToBasic()`
-  	 * @private
-  	 * @param {Number} codePoint The basic numeric code point value.
-  	 * @returns {Number} The numeric value of a basic code point (for use in
-  	 * representing integers) in the range `0` to `base - 1`, or `base` if
-  	 * the code point does not represent a value.
-  	 */
-  	function basicToDigit(codePoint) {
-  		if (codePoint - 48 < 10) {
-  			return codePoint - 22;
-  		}
-  		if (codePoint - 65 < 26) {
-  			return codePoint - 65;
-  		}
-  		if (codePoint - 97 < 26) {
-  			return codePoint - 97;
-  		}
-  		return base;
-  	}
-
-  	/**
-  	 * Converts a digit/integer into a basic code point.
-  	 * @see `basicToDigit()`
-  	 * @private
-  	 * @param {Number} digit The numeric value of a basic code point.
-  	 * @returns {Number} The basic code point whose value (when used for
-  	 * representing integers) is `digit`, which needs to be in the range
-  	 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
-  	 * used; else, the lowercase form is used. The behavior is undefined
-  	 * if `flag` is non-zero and `digit` has no uppercase form.
-  	 */
-  	function digitToBasic(digit, flag) {
-  		//  0..25 map to ASCII a..z or A..Z
-  		// 26..35 map to ASCII 0..9
-  		return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
-  	}
-
-  	/**
-  	 * Bias adaptation function as per section 3.4 of RFC 3492.
-  	 * http://tools.ietf.org/html/rfc3492#section-3.4
-  	 * @private
-  	 */
-  	function adapt(delta, numPoints, firstTime) {
-  		var k = 0;
-  		delta = firstTime ? floor(delta / damp) : delta >> 1;
-  		delta += floor(delta / numPoints);
-  		for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
-  			delta = floor(delta / baseMinusTMin);
-  		}
-  		return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
-  	}
-
-  	/**
-  	 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
-  	 * symbols.
-  	 * @memberOf punycode
-  	 * @param {String} input The Punycode string of ASCII-only symbols.
-  	 * @returns {String} The resulting string of Unicode symbols.
-  	 */
-  	function decode(input) {
-  		// Don't use UCS-2
-  		var output = [],
-  		    inputLength = input.length,
-  		    out,
-  		    i = 0,
-  		    n = initialN,
-  		    bias = initialBias,
-  		    basic,
-  		    j,
-  		    index,
-  		    oldi,
-  		    w,
-  		    k,
-  		    digit,
-  		    t,
-  		    /** Cached calculation results */
-  		    baseMinusT;
-
-  		// Handle the basic code points: let `basic` be the number of input code
-  		// points before the last delimiter, or `0` if there is none, then copy
-  		// the first basic code points to the output.
-
-  		basic = input.lastIndexOf(delimiter);
-  		if (basic < 0) {
-  			basic = 0;
-  		}
-
-  		for (j = 0; j < basic; ++j) {
-  			// if it's not a basic code point
-  			if (input.charCodeAt(j) >= 0x80) {
-  				error('not-basic');
-  			}
-  			output.push(input.charCodeAt(j));
-  		}
-
-  		// Main decoding loop: start just after the last delimiter if any basic code
-  		// points were copied; start at the beginning otherwise.
-
-  		for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
-
-  			// `index` is the index of the next character to be consumed.
-  			// Decode a generalized variable-length integer into `delta`,
-  			// which gets added to `i`. The overflow checking is easier
-  			// if we increase `i` as we go, then subtract off its starting
-  			// value at the end to obtain `delta`.
-  			for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
-
-  				if (index >= inputLength) {
-  					error('invalid-input');
-  				}
-
-  				digit = basicToDigit(input.charCodeAt(index++));
-
-  				if (digit >= base || digit > floor((maxInt - i) / w)) {
-  					error('overflow');
-  				}
-
-  				i += digit * w;
-  				t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
-
-  				if (digit < t) {
-  					break;
-  				}
-
-  				baseMinusT = base - t;
-  				if (w > floor(maxInt / baseMinusT)) {
-  					error('overflow');
-  				}
-
-  				w *= baseMinusT;
-
-  			}
-
-  			out = output.length + 1;
-  			bias = adapt(i - oldi, out, oldi == 0);
-
-  			// `i` was supposed to wrap around from `out` to `0`,
-  			// incrementing `n` each time, so we'll fix that now:
-  			if (floor(i / out) > maxInt - n) {
-  				error('overflow');
-  			}
-
-  			n += floor(i / out);
-  			i %= out;
-
-  			// Insert `n` at position `i` of the output
-  			output.splice(i++, 0, n);
-
-  		}
-
-  		return ucs2encode(output);
-  	}
-
-  	/**
-  	 * Converts a string of Unicode symbols to a Punycode string of ASCII-only
-  	 * symbols.
-  	 * @memberOf punycode
-  	 * @param {String} input The string of Unicode symbols.
-  	 * @returns {String} The resulting Punycode string of ASCII-only symbols.
-  	 */
-  	function encode(input) {
-  		var n,
-  		    delta,
-  		    handledCPCount,
-  		    basicLength,
-  		    bias,
-  		    j,
-  		    m,
-  		    q,
-  		    k,
-  		    t,
-  		    currentValue,
-  		    output = [],
-  		    /** `inputLength` will hold the number of code points in `input`. */
-  		    inputLength,
-  		    /** Cached calculation results */
-  		    handledCPCountPlusOne,
-  		    baseMinusT,
-  		    qMinusT;
-
-  		// Convert the input in UCS-2 to Unicode
-  		input = ucs2decode(input);
-
-  		// Cache the length
-  		inputLength = input.length;
-
-  		// Initialize the state
-  		n = initialN;
-  		delta = 0;
-  		bias = initialBias;
-
-  		// Handle the basic code points
-  		for (j = 0; j < inputLength; ++j) {
-  			currentValue = input[j];
-  			if (currentValue < 0x80) {
-  				output.push(stringFromCharCode(currentValue));
-  			}
-  		}
-
-  		handledCPCount = basicLength = output.length;
-
-  		// `handledCPCount` is the number of code points that have been handled;
-  		// `basicLength` is the number of basic code points.
-
-  		// Finish the basic string - if it is not empty - with a delimiter
-  		if (basicLength) {
-  			output.push(delimiter);
-  		}
-
-  		// Main encoding loop:
-  		while (handledCPCount < inputLength) {
-
-  			// All non-basic code points < n have been handled already. Find the next
-  			// larger one:
-  			for (m = maxInt, j = 0; j < inputLength; ++j) {
-  				currentValue = input[j];
-  				if (currentValue >= n && currentValue < m) {
-  					m = currentValue;
-  				}
-  			}
-
-  			// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
-  			// but guard against overflow
-  			handledCPCountPlusOne = handledCPCount + 1;
-  			if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
-  				error('overflow');
-  			}
-
-  			delta += (m - n) * handledCPCountPlusOne;
-  			n = m;
-
-  			for (j = 0; j < inputLength; ++j) {
-  				currentValue = input[j];
-
-  				if (currentValue < n && ++delta > maxInt) {
-  					error('overflow');
-  				}
-
-  				if (currentValue == n) {
-  					// Represent delta as a generalized variable-length integer
-  					for (q = delta, k = base; /* no condition */; k += base) {
-  						t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
-  						if (q < t) {
-  							break;
-  						}
-  						qMinusT = q - t;
-  						baseMinusT = base - t;
-  						output.push(
-  							stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
-  						);
-  						q = floor(qMinusT / baseMinusT);
-  					}
-
-  					output.push(stringFromCharCode(digitToBasic(q, 0)));
-  					bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
-  					delta = 0;
-  					++handledCPCount;
-  				}
-  			}
-
-  			++delta;
-  			++n;
-
-  		}
-  		return output.join('');
-  	}
-
-  	/**
-  	 * Converts a Punycode string representing a domain name to Unicode. Only the
-  	 * Punycoded parts of the domain name will be converted, i.e. it doesn't
-  	 * matter if you call it on a string that has already been converted to
-  	 * Unicode.
-  	 * @memberOf punycode
-  	 * @param {String} domain The Punycode domain name to convert to Unicode.
-  	 * @returns {String} The Unicode representation of the given Punycode
-  	 * string.
-  	 */
-  	function toUnicode(domain) {
-  		return mapDomain(domain, function(string) {
-  			return regexPunycode.test(string)
-  				? decode(string.slice(4).toLowerCase())
-  				: string;
-  		});
-  	}
-
-  	/**
-  	 * Converts a Unicode string representing a domain name to Punycode. Only the
-  	 * non-ASCII parts of the domain name will be converted, i.e. it doesn't
-  	 * matter if you call it with a domain that's already in ASCII.
-  	 * @memberOf punycode
-  	 * @param {String} domain The domain name to convert, as a Unicode string.
-  	 * @returns {String} The Punycode representation of the given domain name.
-  	 */
-  	function toASCII(domain) {
-  		return mapDomain(domain, function(string) {
-  			return regexNonASCII.test(string)
-  				? 'xn--' + encode(string)
-  				: string;
-  		});
-  	}
-
-  	/*--------------------------------------------------------------------------*/
-
-  	/** Define the public API */
-  	punycode = {
-  		/**
-  		 * A string representing the current Punycode.js version number.
-  		 * @memberOf punycode
-  		 * @type String
-  		 */
-  		'version': '1.2.4',
-  		/**
-  		 * An object of methods to convert from JavaScript's internal character
-  		 * representation (UCS-2) to Unicode code points, and back.
-  		 * @see <http://mathiasbynens.be/notes/javascript-encoding>
-  		 * @memberOf punycode
-  		 * @type Object
-  		 */
-  		'ucs2': {
-  			'decode': ucs2decode,
-  			'encode': ucs2encode
-  		},
-  		'decode': decode,
-  		'encode': encode,
-  		'toASCII': toASCII,
-  		'toUnicode': toUnicode
-  	};
-
-  	/** Expose `punycode` */
-  	// Some AMD build optimizers, like r.js, check for specific condition patterns
-  	// like the following:
-  	if (
-  		typeof define == 'function' &&
-  		typeof define.amd == 'object' && define.amd && false
-  	) {
-  		define('punycode', function() {
-  			return punycode;
-  		});
-  	} else if (freeExports && !freeExports.nodeType) {
-  		if (freeModule) { // in Node.js or RingoJS v0.8.0+
-  			freeModule.exports = punycode;
-  		} else { // in Narwhal or RingoJS v0.7.0-
-  			for (key in punycode) {
-  				punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
-  			}
-  		}
-  	} else { // in Rhino or a web browser
-  		root.punycode = punycode;
-  	}
-
-  }(this));
-
-  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
-  },{}],2:[function(_dereq_,module,exports){
-  var log = _dereq_('./log');
-
-  function restoreOwnerScroll(ownerDocument, x, y) {
-      if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {
-          ownerDocument.defaultView.scrollTo(x, y);
-      }
-  }
+    stream.push("Q");
+    stream.push("EMC");
+    var appearanceStreamContent = createFormXObject(formObject);
+    appearanceStreamContent.scope = formObject.scope;
+    appearanceStreamContent.stream = stream.join("\n");
+    return appearanceStreamContent;
+  };
 
-  function cloneCanvasContents(canvas, clonedCanvas) {
-      try {
-          if (clonedCanvas) {
-              clonedCanvas.width = canvas.width;
-              clonedCanvas.height = canvas.height;
-              clonedCanvas.getContext("2d").putImageData(canvas.getContext("2d").getImageData(0, 0, canvas.width, canvas.height), 0, 0);
-          }
-      } catch(e) {
-          log("Unable to copy canvas content from", canvas, e);
-      }
-  }
+  var calculateX = function calculateX(formObject, text) {
+    var maxFontSize = formObject.fontSize === 0 ? formObject.maxFontSize : formObject.fontSize;
+    var returnValue = {
+      text: "",
+      fontSize: ""
+    }; // Remove Brackets
 
-  function cloneNode(node, javascriptEnabled) {
-      var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
+    text = text.substr(0, 1) == "(" ? text.substr(1) : text;
+    text = text.substr(text.length - 1) == ")" ? text.substr(0, text.length - 1) : text; // split into array of words
 
-      var child = node.firstChild;
-      while(child) {
-          if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {
-              clone.appendChild(cloneNode(child, javascriptEnabled));
-          }
-          child = child.nextSibling;
+    var textSplit = text.split(" ");
+
+    if (formObject.multiline) {
+      textSplit = textSplit.map(function (word) {
+        return word.split("\n");
+      });
+    } else {
+      textSplit = textSplit.map(function (word) {
+        return [word];
+      });
+    }
+
+    var fontSize = maxFontSize; // The Starting fontSize (The Maximum)
+
+    var lineSpacing = 2;
+    var borderPadding = 2;
+    var height = AcroFormAppearance.internal.getHeight(formObject) || 0;
+    height = height < 0 ? -height : height;
+    var width = AcroFormAppearance.internal.getWidth(formObject) || 0;
+    width = width < 0 ? -width : width;
+
+    var isSmallerThanWidth = function isSmallerThanWidth(i, lastLine, fontSize) {
+      if (i + 1 < textSplit.length) {
+        var tmp = lastLine + " " + textSplit[i + 1][0];
+        var TextWidth = calculateFontSpace(tmp, formObject, fontSize).width;
+        var FieldWidth = width - 2 * borderPadding;
+        return TextWidth <= FieldWidth;
+      } else {
+        return false;
       }
+    };
 
-      if (node.nodeType === 1) {
-          clone._scrollTop = node.scrollTop;
-          clone._scrollLeft = node.scrollLeft;
-          if (node.nodeName === "CANVAS") {
-              cloneCanvasContents(node, clone);
-          } else if (node.nodeName === "TEXTAREA" || node.nodeName === "SELECT") {
-              clone.value = node.value;
-          }
+    fontSize++;
+
+    FontSize: while (fontSize > 0) {
+      text = "";
+      fontSize--;
+      var textHeight = calculateFontSpace("3", formObject, fontSize).height;
+      var startY = formObject.multiline ? height - fontSize : (height - textHeight) / 2;
+      startY += lineSpacing;
+      var startX;
+      var lastY = startY;
+      var firstWordInLine = 0,
+          lastWordInLine = 0;
+      var lastLength;
+      var currWord = 0;
+
+      if (fontSize <= 0) {
+        // In case, the Text doesn't fit at all
+        fontSize = 12;
+        text = "(...) Tj\n";
+        text += "% Width of Text: " + calculateFontSpace(text, formObject, fontSize).width + ", FieldWidth:" + width + "\n";
+        break;
       }
 
-      return clone;
-  }
+      var lastLine = "";
+      var lineCount = 0;
 
-  function initNode(node) {
-      if (node.nodeType === 1) {
-          node.scrollTop = node._scrollTop;
-          node.scrollLeft = node._scrollLeft;
+      Line: for (var i = 0; i < textSplit.length; i++) {
+        if (textSplit.hasOwnProperty(i)) {
+          var isWithNewLine = false;
 
-          var child = node.firstChild;
-          while(child) {
-              initNode(child);
-              child = child.nextSibling;
-          }
-      }
-  }
+          if (textSplit[i].length !== 1 && currWord !== textSplit[i].length - 1) {
+            if ((textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {
+              continue FontSize;
+            }
 
-  module.exports = function(ownerDocument, containerDocument, width, height, options, x ,y) {
-      var documentElement = cloneNode(ownerDocument.documentElement, options.javascriptEnabled);
-      var container = containerDocument.createElement("iframe");
-
-      container.className = "html2canvas-container";
-      container.style.visibility = "hidden";
-      container.style.position = "fixed";
-      container.style.left = "-10000px";
-      container.style.top = "0px";
-      container.style.border = "0";
-      container.width = width;
-      container.height = height;
-      container.scrolling = "no"; // ios won't scroll without it
-      containerDocument.body.appendChild(container);
-
-      return new Promise(function(resolve) {
-          var documentClone = container.contentWindow.document;
-
-          /* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle
-           if window url is about:blank, we can assign the url to current by writing onto the document
-           */
-          container.contentWindow.onload = container.onload = function() {
-              var interval = setInterval(function() {
-                  if (documentClone.body.childNodes.length > 0) {
-                      initNode(documentClone.documentElement);
-                      clearInterval(interval);
-                      if (options.type === "view") {
-                          container.contentWindow.scrollTo(x, y);
-                          if ((/(iPad|iPhone|iPod)/g).test(navigator.userAgent) && (container.contentWindow.scrollY !== y || container.contentWindow.scrollX !== x)) {
-                              documentClone.documentElement.style.top = (-y) + "px";
-                              documentClone.documentElement.style.left = (-x) + "px";
-                              documentClone.documentElement.style.position = 'absolute';
-                          }
-                      }
-                      resolve(container);
-                  }
-              }, 50);
-          };
+            lastLine += textSplit[i][currWord];
+            isWithNewLine = true;
+            lastWordInLine = i;
+            i--;
+          } else {
+            lastLine += textSplit[i][currWord] + " ";
+            lastLine = lastLine.substr(lastLine.length - 1) == " " ? lastLine.substr(0, lastLine.length - 1) : lastLine;
+            var key = parseInt(i);
+            var nextLineIsSmaller = isSmallerThanWidth(key, lastLine, fontSize);
+            var isLastWord = i >= textSplit.length - 1;
+
+            if (nextLineIsSmaller && !isLastWord) {
+              lastLine += " ";
+              currWord = 0;
+              continue; // Line
+            } else if (!nextLineIsSmaller && !isLastWord) {
+              if (!formObject.multiline) {
+                continue FontSize;
+              } else {
+                if ((textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {
+                  // If the Text is higher than the
+                  // FieldObject
+                  continue FontSize;
+                }
 
-          documentClone.open();
-          documentClone.write("<!DOCTYPE html><html></html>");
-          // Chrome scrolls the parent document for some reason after the write to the cloned window???
-          restoreOwnerScroll(ownerDocument, x, y);
-          documentClone.replaceChild(documentClone.adoptNode(documentElement), documentClone.documentElement);
-          documentClone.close();
-      });
-  };
+                lastWordInLine = key; // go on
+              }
+            } else if (isLastWord) {
+              lastWordInLine = key;
+            } else {
+              if (formObject.multiline && (textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {
+                // If the Text is higher than the FieldObject
+                continue FontSize;
+              }
+            }
+          } // Remove last blank
 
-  },{"./log":13}],3:[function(_dereq_,module,exports){
-  // http://dev.w3.org/csswg/css-color/
-
-  function Color(value) {
-      this.r = 0;
-      this.g = 0;
-      this.b = 0;
-      this.a = null;
-      var result = this.fromArray(value) ||
-          this.namedColor(value) ||
-          this.rgb(value) ||
-          this.rgba(value) ||
-          this.hex6(value) ||
-          this.hex3(value);
-  }
 
-  Color.prototype.darken = function(amount) {
-      var a = 1 - amount;
-      return  new Color([
-          Math.round(this.r * a),
-          Math.round(this.g * a),
-          Math.round(this.b * a),
-          this.a
-      ]);
-  };
+          var line = "";
 
-  Color.prototype.isTransparent = function() {
-      return this.a === 0;
-  };
+          for (var x = firstWordInLine; x <= lastWordInLine; x++) {
+            var currLine = textSplit[x];
+
+            if (formObject.multiline) {
+              if (x === lastWordInLine) {
+                line += currLine[currWord] + " ";
+                currWord = (currWord + 1) % currLine.length;
+                continue;
+              }
+
+              if (x === firstWordInLine) {
+                line += currLine[currLine.length - 1] + " ";
+                continue;
+              }
+            }
+
+            line += currLine[0] + " ";
+          } // Remove last blank
 
-  Color.prototype.isBlack = function() {
-      return this.r === 0 && this.g === 0 && this.b === 0;
-  };
 
-  Color.prototype.fromArray = function(array) {
-      if (Array.isArray(array)) {
-          this.r = Math.min(array[0], 255);
-          this.g = Math.min(array[1], 255);
-          this.b = Math.min(array[2], 255);
-          if (array.length > 3) {
-              this.a = array[3];
+          line = line.substr(line.length - 1) == " " ? line.substr(0, line.length - 1) : line; // lastLength -= blankSpace.width;
+
+          lastLength = calculateFontSpace(line, formObject, fontSize).width; // Calculate startX
+
+          switch (formObject.textAlign) {
+            case "right":
+              startX = width - lastLength - borderPadding;
+              break;
+
+            case "center":
+              startX = (width - lastLength) / 2;
+              break;
+
+            case "left":
+            default:
+              startX = borderPadding;
+              break;
           }
-      }
 
-      return (Array.isArray(array));
-  };
+          text += f2(startX) + " " + f2(lastY) + " Td\n";
+          text += "(" + pdfEscape(line) + ") Tj\n"; // reset X in PDF
+
+          text += -f2(startX) + " 0 Td\n"; // After a Line, adjust y position
 
-  var _hex3 = /^#([a-f0-9]{3})$/i;
+          lastY = -(fontSize + lineSpacing); // Reset for next iteration step
 
-  Color.prototype.hex3 = function(value) {
-      var match = null;
-      if ((match = value.match(_hex3)) !== null) {
-          this.r = parseInt(match[1][0] + match[1][0], 16);
-          this.g = parseInt(match[1][1] + match[1][1], 16);
-          this.b = parseInt(match[1][2] + match[1][2], 16);
+          lastLength = 0;
+          firstWordInLine = isWithNewLine ? lastWordInLine : lastWordInLine + 1;
+          lineCount++;
+          lastLine = "";
+          continue Line;
+        }
       }
-      return match !== null;
+
+      break;
+    }
+
+    returnValue.text = text;
+    returnValue.fontSize = fontSize;
+    return returnValue;
   };
+  /**
+   * Small workaround for calculating the TextMetric approximately.
+   *
+   * @param text
+   * @param fontsize
+   * @returns {TextMetrics} (Has Height and Width)
+   */
 
-  var _hex6 = /^#([a-f0-9]{6})$/i;
 
-  Color.prototype.hex6 = function(value) {
-      var match = null;
-      if ((match = value.match(_hex6)) !== null) {
-          this.r = parseInt(match[1].substring(0, 2), 16);
-          this.g = parseInt(match[1].substring(2, 4), 16);
-          this.b = parseInt(match[1].substring(4, 6), 16);
-      }
-      return match !== null;
+  var calculateFontSpace = function calculateFontSpace(text, formObject, fontSize) {
+    var font = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle);
+    var width = formObject.scope.getStringUnitWidth(text, {
+      font: font,
+      fontSize: parseFloat(fontSize),
+      charSpace: 0
+    }) * parseFloat(fontSize);
+    var height = formObject.scope.getStringUnitWidth("3", {
+      font: font,
+      fontSize: parseFloat(fontSize),
+      charSpace: 0
+    }) * parseFloat(fontSize) * 1.5;
+    return {
+      height: height,
+      width: width
+    };
   };
 
+  var acroformPluginTemplate = {
+    fields: [],
+    xForms: [],
 
-  var _rgb = /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/;
+    /**
+     * acroFormDictionaryRoot contains information about the AcroForm
+     * Dictionary 0: The Event-Token, the AcroFormDictionaryCallback has
+     * 1: The Object ID of the Root
+     */
+    acroFormDictionaryRoot: null,
 
-  Color.prototype.rgb = function(value) {
-      var match = null;
-      if ((match = value.match(_rgb)) !== null) {
-          this.r = Number(match[1]);
-          this.g = Number(match[2]);
-          this.b = Number(match[3]);
-      }
-      return match !== null;
+    /**
+     * After the PDF gets evaluated, the reference to the root has to be
+     * reset, this indicates, whether the root has already been printed
+     * out
+     */
+    printedOut: false,
+    internal: null,
+    isInitialized: false
   };
 
-  var _rgba = /^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d?\.?\d+)\s*\)$/;
+  var annotReferenceCallback = function annotReferenceCallback(scope) {
+    //set objId to undefined and force it to get a new objId on buildDocument
+    scope.internal.acroformPlugin.acroFormDictionaryRoot.objId = undefined;
+    var fields = scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields;
 
-  Color.prototype.rgba = function(value) {
-      var match = null;
-      if ((match = value.match(_rgba)) !== null) {
-          this.r = Number(match[1]);
-          this.g = Number(match[2]);
-          this.b = Number(match[3]);
-          this.a = Number(match[4]);
+    for (var i in fields) {
+      if (fields.hasOwnProperty(i)) {
+        var formObject = fields[i]; //set objId to undefined and force it to get a new objId on buildDocument
+
+        formObject.objId = undefined; // add Annot Reference!
+
+        if (formObject.hasAnnotation) {
+          // If theres an Annotation Widget in the Form Object, put the
+          // Reference in the /Annot array
+          createAnnotationReference(formObject, scope);
+        }
       }
-      return match !== null;
+    }
   };
 
-  Color.prototype.toString = function() {
-      return this.a !== null && this.a !== 1 ?
-      "rgba(" + [this.r, this.g, this.b, this.a].join(",") + ")" :
-      "rgb(" + [this.r, this.g, this.b].join(",") + ")";
+  var putForm = function putForm(formObject) {
+    if (formObject.scope.internal.acroformPlugin.printedOut) {
+      formObject.scope.internal.acroformPlugin.printedOut = false;
+      formObject.scope.internal.acroformPlugin.acroFormDictionaryRoot = null;
+    }
+
+    formObject.scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields.push(formObject);
   };
+  /**
+   * Create the Reference to the widgetAnnotation, so that it gets referenced
+   * in the Annot[] int the+ (Requires the Annotation Plugin)
+   */
+
+
+  var createAnnotationReference = function createAnnotationReference(object, scope) {
+    var options = {
+      type: "reference",
+      object: object
+    };
+
+    var findEntry = function findEntry(entry) {
+      return entry.type === options.type && entry.object === options.object;
+    };
+
+    if (scope.internal.getPageInfo(object.page).pageContext.annotations.find(findEntry) === undefined) {
+      scope.internal.getPageInfo(object.page).pageContext.annotations.push(options);
+    }
+  }; // Callbacks
 
-  Color.prototype.namedColor = function(value) {
-      value = value.toLowerCase();
-      var color = colors[value];
-      if (color) {
-          this.r = color[0];
-          this.g = color[1];
-          this.b = color[2];
-      } else if (value === "transparent") {
-          this.r = this.g = this.b = this.a = 0;
-          return true;
-      }
 
-      return !!color;
+  var putCatalogCallback = function putCatalogCallback(scope) {
+    // Put reference to AcroForm to DocumentCatalog
+    if (typeof scope.internal.acroformPlugin.acroFormDictionaryRoot !== "undefined") {
+      // for safety, shouldn't normally be the case
+      scope.internal.write("/AcroForm " + scope.internal.acroformPlugin.acroFormDictionaryRoot.objId + " " + 0 + " R");
+    } else {
+      throw new Error("putCatalogCallback: Root missing.");
+    }
   };
+  /**
+   * Adds /Acroform X 0 R to Document Catalog, and creates the AcroForm
+   * Dictionary
+   */
 
-  Color.prototype.isColor = true;
-
-  // JSON.stringify([].slice.call($$('.named-color-table tr'), 1).map(function(row) { return [row.childNodes[3].textContent, row.childNodes[5].textContent.trim().split(",").map(Number)] }).reduce(function(data, row) {data[row[0]] = row[1]; return data}, {}))
-  var colors = {
-      "aliceblue": [240, 248, 255],
-      "antiquewhite": [250, 235, 215],
-      "aqua": [0, 255, 255],
-      "aquamarine": [127, 255, 212],
-      "azure": [240, 255, 255],
-      "beige": [245, 245, 220],
-      "bisque": [255, 228, 196],
-      "black": [0, 0, 0],
-      "blanchedalmond": [255, 235, 205],
-      "blue": [0, 0, 255],
-      "blueviolet": [138, 43, 226],
-      "brown": [165, 42, 42],
-      "burlywood": [222, 184, 135],
-      "cadetblue": [95, 158, 160],
-      "chartreuse": [127, 255, 0],
-      "chocolate": [210, 105, 30],
-      "coral": [255, 127, 80],
-      "cornflowerblue": [100, 149, 237],
-      "cornsilk": [255, 248, 220],
-      "crimson": [220, 20, 60],
-      "cyan": [0, 255, 255],
-      "darkblue": [0, 0, 139],
-      "darkcyan": [0, 139, 139],
-      "darkgoldenrod": [184, 134, 11],
-      "darkgray": [169, 169, 169],
-      "darkgreen": [0, 100, 0],
-      "darkgrey": [169, 169, 169],
-      "darkkhaki": [189, 183, 107],
-      "darkmagenta": [139, 0, 139],
-      "darkolivegreen": [85, 107, 47],
-      "darkorange": [255, 140, 0],
-      "darkorchid": [153, 50, 204],
-      "darkred": [139, 0, 0],
-      "darksalmon": [233, 150, 122],
-      "darkseagreen": [143, 188, 143],
-      "darkslateblue": [72, 61, 139],
-      "darkslategray": [47, 79, 79],
-      "darkslategrey": [47, 79, 79],
-      "darkturquoise": [0, 206, 209],
-      "darkviolet": [148, 0, 211],
-      "deeppink": [255, 20, 147],
-      "deepskyblue": [0, 191, 255],
-      "dimgray": [105, 105, 105],
-      "dimgrey": [105, 105, 105],
-      "dodgerblue": [30, 144, 255],
-      "firebrick": [178, 34, 34],
-      "floralwhite": [255, 250, 240],
-      "forestgreen": [34, 139, 34],
-      "fuchsia": [255, 0, 255],
-      "gainsboro": [220, 220, 220],
-      "ghostwhite": [248, 248, 255],
-      "gold": [255, 215, 0],
-      "goldenrod": [218, 165, 32],
-      "gray": [128, 128, 128],
-      "green": [0, 128, 0],
-      "greenyellow": [173, 255, 47],
-      "grey": [128, 128, 128],
-      "honeydew": [240, 255, 240],
-      "hotpink": [255, 105, 180],
-      "indianred": [205, 92, 92],
-      "indigo": [75, 0, 130],
-      "ivory": [255, 255, 240],
-      "khaki": [240, 230, 140],
-      "lavender": [230, 230, 250],
-      "lavenderblush": [255, 240, 245],
-      "lawngreen": [124, 252, 0],
-      "lemonchiffon": [255, 250, 205],
-      "lightblue": [173, 216, 230],
-      "lightcoral": [240, 128, 128],
-      "lightcyan": [224, 255, 255],
-      "lightgoldenrodyellow": [250, 250, 210],
-      "lightgray": [211, 211, 211],
-      "lightgreen": [144, 238, 144],
-      "lightgrey": [211, 211, 211],
-      "lightpink": [255, 182, 193],
-      "lightsalmon": [255, 160, 122],
-      "lightseagreen": [32, 178, 170],
-      "lightskyblue": [135, 206, 250],
-      "lightslategray": [119, 136, 153],
-      "lightslategrey": [119, 136, 153],
-      "lightsteelblue": [176, 196, 222],
-      "lightyellow": [255, 255, 224],
-      "lime": [0, 255, 0],
-      "limegreen": [50, 205, 50],
-      "linen": [250, 240, 230],
-      "magenta": [255, 0, 255],
-      "maroon": [128, 0, 0],
-      "mediumaquamarine": [102, 205, 170],
-      "mediumblue": [0, 0, 205],
-      "mediumorchid": [186, 85, 211],
-      "mediumpurple": [147, 112, 219],
-      "mediumseagreen": [60, 179, 113],
-      "mediumslateblue": [123, 104, 238],
-      "mediumspringgreen": [0, 250, 154],
-      "mediumturquoise": [72, 209, 204],
-      "mediumvioletred": [199, 21, 133],
-      "midnightblue": [25, 25, 112],
-      "mintcream": [245, 255, 250],
-      "mistyrose": [255, 228, 225],
-      "moccasin": [255, 228, 181],
-      "navajowhite": [255, 222, 173],
-      "navy": [0, 0, 128],
-      "oldlace": [253, 245, 230],
-      "olive": [128, 128, 0],
-      "olivedrab": [107, 142, 35],
-      "orange": [255, 165, 0],
-      "orangered": [255, 69, 0],
-      "orchid": [218, 112, 214],
-      "palegoldenrod": [238, 232, 170],
-      "palegreen": [152, 251, 152],
-      "paleturquoise": [175, 238, 238],
-      "palevioletred": [219, 112, 147],
-      "papayawhip": [255, 239, 213],
-      "peachpuff": [255, 218, 185],
-      "peru": [205, 133, 63],
-      "pink": [255, 192, 203],
-      "plum": [221, 160, 221],
-      "powderblue": [176, 224, 230],
-      "purple": [128, 0, 128],
-      "rebeccapurple": [102, 51, 153],
-      "red": [255, 0, 0],
-      "rosybrown": [188, 143, 143],
-      "royalblue": [65, 105, 225],
-      "saddlebrown": [139, 69, 19],
-      "salmon": [250, 128, 114],
-      "sandybrown": [244, 164, 96],
-      "seagreen": [46, 139, 87],
-      "seashell": [255, 245, 238],
-      "sienna": [160, 82, 45],
-      "silver": [192, 192, 192],
-      "skyblue": [135, 206, 235],
-      "slateblue": [106, 90, 205],
-      "slategray": [112, 128, 144],
-      "slategrey": [112, 128, 144],
-      "snow": [255, 250, 250],
-      "springgreen": [0, 255, 127],
-      "steelblue": [70, 130, 180],
-      "tan": [210, 180, 140],
-      "teal": [0, 128, 128],
-      "thistle": [216, 191, 216],
-      "tomato": [255, 99, 71],
-      "turquoise": [64, 224, 208],
-      "violet": [238, 130, 238],
-      "wheat": [245, 222, 179],
-      "white": [255, 255, 255],
-      "whitesmoke": [245, 245, 245],
-      "yellow": [255, 255, 0],
-      "yellowgreen": [154, 205, 50]
+
+  var AcroFormDictionaryCallback = function AcroFormDictionaryCallback(scope) {
+    // Remove event
+    scope.internal.events.unsubscribe(scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID);
+    delete scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID;
+    scope.internal.acroformPlugin.printedOut = true;
   };
+  /**
+   * Creates the single Fields and writes them into the Document
+   *
+   * If fieldArray is set, use the fields that are inside it instead of the
+   * fields from the AcroRoot (for the FormXObjects...)
+   */
 
-  module.exports = Color;
-
-  },{}],4:[function(_dereq_,module,exports){
-  var Support = _dereq_('./support');
-  var CanvasRenderer = _dereq_('./renderers/canvas');
-  var ImageLoader = _dereq_('./imageloader');
-  var NodeParser = _dereq_('./nodeparser');
-  var NodeContainer = _dereq_('./nodecontainer');
-  var log = _dereq_('./log');
-  var utils = _dereq_('./utils');
-  var createWindowClone = _dereq_('./clone');
-  var loadUrlDocument = _dereq_('./proxy').loadUrlDocument;
-  var getBounds = utils.getBounds;
-
-  var html2canvasNodeAttribute = "data-html2canvas-node";
-  var html2canvasCloneIndex = 0;
-
-  function html2canvas(nodeList, options) {
-      var index = html2canvasCloneIndex++;
-      options = options || {};
-      if (options.logging) {
-          log.options.logging = true;
-          log.options.start = Date.now();
-      }
-
-      options.async = typeof(options.async) === "undefined" ? true : options.async;
-      options.allowTaint = typeof(options.allowTaint) === "undefined" ? false : options.allowTaint;
-      options.removeContainer = typeof(options.removeContainer) === "undefined" ? true : options.removeContainer;
-      options.javascriptEnabled = typeof(options.javascriptEnabled) === "undefined" ? false : options.javascriptEnabled;
-      options.imageTimeout = typeof(options.imageTimeout) === "undefined" ? 10000 : options.imageTimeout;
-      options.renderer = typeof(options.renderer) === "function" ? options.renderer : CanvasRenderer;
-      options.strict = !!options.strict;
-
-      if (typeof(nodeList) === "string") {
-          if (typeof(options.proxy) !== "string") {
-              return Promise.reject("Proxy must be used when rendering url");
-          }
-          var width = options.width != null ? options.width : window.innerWidth;
-          var height = options.height != null ? options.height : window.innerHeight;
-          return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, width, height, options).then(function(container) {
-              return renderWindow(container.contentWindow.document.documentElement, container, options, width, height);
-          });
-      }
 
-      var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0];
-      node.setAttribute(html2canvasNodeAttribute + index, index);
-      return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) {
-          if (typeof(options.onrendered) === "function") {
-              log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
-              options.onrendered(canvas);
-          }
-          return canvas;
-      });
-  }
+  var createFieldCallback = function createFieldCallback(fieldArray, scope) {
+    var standardFields = !fieldArray;
+
+    if (!fieldArray) {
+      // in case there is no fieldArray specified, we want to print out
+      // the Fields of the AcroForm
+      // Print out Root
+      scope.internal.newObjectDeferredBegin(scope.internal.acroformPlugin.acroFormDictionaryRoot.objId, true);
+      scope.internal.acroformPlugin.acroFormDictionaryRoot.putStream();
+    }
 
-  html2canvas.CanvasRenderer = CanvasRenderer;
-  html2canvas.NodeContainer = NodeContainer;
-  html2canvas.log = log;
-  html2canvas.utils = utils;
+    fieldArray = fieldArray || scope.internal.acroformPlugin.acroFormDictionaryRoot.Kids;
 
-  var html2canvasExport = (typeof(document) === "undefined" || typeof(Object.create) !== "function" || typeof(document.createElement("canvas").getContext) !== "function") ? function() {
-      return Promise.reject("No canvas support");
-  } : html2canvas;
+    for (var i in fieldArray) {
+      if (fieldArray.hasOwnProperty(i)) {
+        var fieldObject = fieldArray[i];
+        var keyValueList = [];
+        var oldRect = fieldObject.Rect;
 
-  module.exports = html2canvasExport;
+        if (fieldObject.Rect) {
+          fieldObject.Rect = calculateCoordinates(fieldObject.Rect, scope);
+        } // Start Writing the Object
 
-  if (typeof(define) === 'function' && define.amd && false) {
-      define('html2canvas', [], function() {
-          return html2canvasExport;
-      });
-  }
 
-  function renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) {
-      return createWindowClone(document, document, windowWidth, windowHeight, options, document.defaultView.pageXOffset, document.defaultView.pageYOffset).then(function(container) {
-          log("Document cloned");
-          var attributeName = html2canvasNodeAttribute + html2canvasIndex;
-          var selector = "[" + attributeName + "='" + html2canvasIndex + "']";
-          document.querySelector(selector).removeAttribute(attributeName);
-          var clonedWindow = container.contentWindow;
-          var node = clonedWindow.document.querySelector(selector);
-          var oncloneHandler = (typeof(options.onclone) === "function") ? Promise.resolve(options.onclone(clonedWindow.document)) : Promise.resolve(true);
-          return oncloneHandler.then(function() {
-              return renderWindow(node, container, options, windowWidth, windowHeight);
+        scope.internal.newObjectDeferredBegin(fieldObject.objId, true);
+        fieldObject.DA = AcroFormAppearance.createDefaultAppearanceStream(fieldObject);
+
+        if (_typeof(fieldObject) === "object" && typeof fieldObject.getKeyValueListForStream === "function") {
+          keyValueList = fieldObject.getKeyValueListForStream();
+        }
+
+        fieldObject.Rect = oldRect;
+
+        if (fieldObject.hasAppearanceStream && !fieldObject.appearanceStreamContent) {
+          // Calculate Appearance
+          var appearance = calculateAppearanceStream(fieldObject);
+          keyValueList.push({
+            key: "AP",
+            value: "<</N " + appearance + ">>"
           });
-      });
-  }
+          scope.internal.acroformPlugin.xForms.push(appearance);
+        } // Assume AppearanceStreamContent is a Array with N,R,D (at least
+        // one of them!)
 
-  function renderWindow(node, container, options, windowWidth, windowHeight) {
-      var clonedWindow = container.contentWindow;
-      var support = new Support(clonedWindow.document);
-      var imageLoader = new ImageLoader(options, support);
-      var bounds = getBounds(node);
-      var width = options.type === "view" ? windowWidth : documentWidth(clonedWindow.document);
-      var height = options.type === "view" ? windowHeight : documentHeight(clonedWindow.document);
-      var renderer = new options.renderer(width, height, imageLoader, options, document);
-      var parser = new NodeParser(node, renderer, support, imageLoader, options);
-      return parser.ready.then(function() {
-          log("Finished rendering");
-          var canvas;
-
-          if (options.type === "view") {
-              canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0});
-          } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement || options.canvas != null) {
-              canvas = renderer.canvas;
-          } else {
-              canvas = crop(renderer.canvas, {width:  options.width != null ? options.width : bounds.width, height: options.height != null ? options.height : bounds.height, top: bounds.top, left: bounds.left, x: 0, y: 0});
-          }
 
-          cleanupContainer(container, options);
-          return canvas;
-      });
-  }
+        if (fieldObject.appearanceStreamContent) {
+          var appearanceStreamString = ""; // Iterate over N,R and D
 
-  function cleanupContainer(container, options) {
-      if (options.removeContainer) {
-          container.parentNode.removeChild(container);
-          log("Cleaned up container");
-      }
-  }
+          for (var k in fieldObject.appearanceStreamContent) {
+            if (fieldObject.appearanceStreamContent.hasOwnProperty(k)) {
+              var value = fieldObject.appearanceStreamContent[k];
+              appearanceStreamString += "/" + k + " ";
+              appearanceStreamString += "<<";
 
-  function crop(canvas, bounds) {
-      var croppedCanvas = document.createElement("canvas");
-      var x1 = Math.min(canvas.width - 1, Math.max(0, bounds.left));
-      var x2 = Math.min(canvas.width, Math.max(1, bounds.left + bounds.width));
-      var y1 = Math.min(canvas.height - 1, Math.max(0, bounds.top));
-      var y2 = Math.min(canvas.height, Math.max(1, bounds.top + bounds.height));
-      croppedCanvas.width = bounds.width;
-      croppedCanvas.height =  bounds.height;
-      var width = x2-x1;
-      var height = y2-y1;
-      log("Cropping canvas at:", "left:", bounds.left, "top:", bounds.top, "width:", width, "height:", height);
-      log("Resulting crop with width", bounds.width, "and height", bounds.height, "with x", x1, "and y", y1);
-      croppedCanvas.getContext("2d").drawImage(canvas, x1, y1, width, height, bounds.x, bounds.y, width, height);
-      return croppedCanvas;
-  }
+              if (Object.keys(value).length >= 1 || Array.isArray(value)) {
+                // appearanceStream is an Array or Object!
+                for (var i in value) {
+                  if (value.hasOwnProperty(i)) {
+                    var obj = value[i];
 
-  function documentWidth (doc) {
-      return Math.max(
-          Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth),
-          Math.max(doc.body.offsetWidth, doc.documentElement.offsetWidth),
-          Math.max(doc.body.clientWidth, doc.documentElement.clientWidth)
-      );
-  }
+                    if (typeof obj === "function") {
+                      // if Function is referenced, call it in order
+                      // to get the FormXObject
+                      obj = obj.call(scope, fieldObject);
+                    }
 
-  function documentHeight (doc) {
-      return Math.max(
-          Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight),
-          Math.max(doc.body.offsetHeight, doc.documentElement.offsetHeight),
-          Math.max(doc.body.clientHeight, doc.documentElement.clientHeight)
-      );
-  }
+                    appearanceStreamString += "/" + i + " " + obj + " "; // In case the XForm is already used, e.g. OffState
+                    // of CheckBoxes, don't add it
 
-  function absoluteUrl(url) {
-      var link = document.createElement("a");
-      link.href = url;
-      link.href = link.href;
-      return link;
-  }
+                    if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj);
+                  }
+                }
+              } else {
+                obj = value;
+
+                if (typeof obj === "function") {
+                  // if Function is referenced, call it in order to
+                  // get the FormXObject
+                  obj = obj.call(scope, fieldObject);
+                }
 
-  },{"./clone":2,"./imageloader":11,"./log":13,"./nodecontainer":14,"./nodeparser":15,"./proxy":16,"./renderers/canvas":20,"./support":22,"./utils":26}],5:[function(_dereq_,module,exports){
-  var log = _dereq_('./log');
-  var smallImage = _dereq_('./utils').smallImage;
-
-  function DummyImageContainer(src) {
-      this.src = src;
-      log("DummyImageContainer for", src);
-      if (!this.promise || !this.image) {
-          log("Initiating DummyImageContainer");
-          DummyImageContainer.prototype.image = new Image();
-          var image = this.image;
-          DummyImageContainer.prototype.promise = new Promise(function(resolve, reject) {
-              image.onload = resolve;
-              image.onerror = reject;
-              image.src = smallImage();
-              if (image.complete === true) {
-                  resolve(image);
+                appearanceStreamString += "/" + i + " " + obj;
+                if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj);
               }
+
+              appearanceStreamString += ">>";
+            }
+          } // appearance stream is a normal Object..
+
+
+          keyValueList.push({
+            key: "AP",
+            value: "<<\n" + appearanceStreamString + ">>"
           });
+        }
+
+        scope.internal.putStream({
+          additionalKeyValues: keyValueList,
+          objectId: fieldObject.objId
+        });
+        scope.internal.out("endobj");
       }
-  }
+    }
 
-  module.exports = DummyImageContainer;
+    if (standardFields) {
+      createXFormObjectCallback(scope.internal.acroformPlugin.xForms, scope);
+    }
+  };
 
-  },{"./log":13,"./utils":26}],6:[function(_dereq_,module,exports){
-  var smallImage = _dereq_('./utils').smallImage;
+  var createXFormObjectCallback = function createXFormObjectCallback(fieldArray, scope) {
+    for (var i in fieldArray) {
+      if (fieldArray.hasOwnProperty(i)) {
+        var key = i;
+        var fieldObject = fieldArray[i]; // Start Writing the Object
 
-  function Font(family, size) {
-      var container = document.createElement('div'),
-          img = document.createElement('img'),
-          span = document.createElement('span'),
-          sampleText = 'Hidden Text',
-          baseline,
-          middle;
+        scope.internal.newObjectDeferredBegin(fieldObject.objId, true);
 
-      container.style.visibility = "hidden";
-      container.style.fontFamily = family;
-      container.style.fontSize = size;
-      container.style.margin = 0;
-      container.style.padding = 0;
+        if (_typeof(fieldObject) === "object" && typeof fieldObject.putStream === "function") {
+          fieldObject.putStream();
+        }
 
-      document.body.appendChild(container);
+        delete fieldArray[key];
+      }
+    }
+  };
 
-      img.src = smallImage();
-      img.width = 1;
-      img.height = 1;
+  var initializeAcroForm = function initializeAcroForm(scope, formObject) {
+    formObject.scope = scope;
 
-      img.style.margin = 0;
-      img.style.padding = 0;
-      img.style.verticalAlign = "baseline";
+    if (scope.internal !== undefined && (scope.internal.acroformPlugin === undefined || scope.internal.acroformPlugin.isInitialized === false)) {
+      AcroFormField.FieldNum = 0;
+      scope.internal.acroformPlugin = JSON.parse(JSON.stringify(acroformPluginTemplate));
 
-      span.style.fontFamily = family;
-      span.style.fontSize = size;
-      span.style.margin = 0;
-      span.style.padding = 0;
+      if (scope.internal.acroformPlugin.acroFormDictionaryRoot) {
+        throw new Error("Exception while creating AcroformDictionary");
+      }
 
-      span.appendChild(document.createTextNode(sampleText));
-      container.appendChild(span);
-      container.appendChild(img);
-      baseline = (img.offsetTop - span.offsetTop) + 1;
+      scaleFactor = scope.internal.scaleFactor; // The Object Number of the AcroForm Dictionary
 
-      container.removeChild(span);
-      container.appendChild(document.createTextNode(sampleText));
+      scope.internal.acroformPlugin.acroFormDictionaryRoot = new AcroFormDictionary();
+      scope.internal.acroformPlugin.acroFormDictionaryRoot.scope = scope; // add Callback for creating the AcroForm Dictionary
 
-      container.style.lineHeight = "normal";
-      img.style.verticalAlign = "super";
+      scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID = scope.internal.events.subscribe("postPutResources", function () {
+        AcroFormDictionaryCallback(scope);
+      });
+      scope.internal.events.subscribe("buildDocument", function () {
+        annotReferenceCallback(scope);
+      }); // buildDocument
+      // Register event, that is triggered when the DocumentCatalog is
+      // written, in order to add /AcroForm
+
+      scope.internal.events.subscribe("putCatalog", function () {
+        putCatalogCallback(scope);
+      }); // Register event, that creates all Fields
+
+      scope.internal.events.subscribe("postPutPages", function (fieldArray) {
+        createFieldCallback(fieldArray, scope);
+      });
+      scope.internal.acroformPlugin.isInitialized = true;
+    }
+  }; //PDF 32000-1:2008, page 26, 7.3.6
 
-      middle = (img.offsetTop-container.offsetTop) + 1;
 
-      document.body.removeChild(container);
+  var arrayToPdfArray = jsPDFAPI.__acroform__.arrayToPdfArray = function (array, objId, scope) {
+    var encryptor = function encryptor(data) {
+      return data;
+    };
 
-      this.baseline = baseline;
-      this.lineWidth = 1;
-      this.middle = middle;
-  }
+    if (Array.isArray(array)) {
+      var content = "[";
 
-  module.exports = Font;
+      for (var i = 0; i < array.length; i++) {
+        if (i !== 0) {
+          content += " ";
+        }
 
-  },{"./utils":26}],7:[function(_dereq_,module,exports){
-  var Font = _dereq_('./font');
+        switch (_typeof(array[i])) {
+          case "boolean":
+          case "number":
+          case "object":
+            content += array[i].toString();
+            break;
 
-  function FontMetrics() {
-      this.data = {};
-  }
+          case "string":
+            if (array[i].substr(0, 1) !== "/") {
+              if (typeof objId !== "undefined" && scope) encryptor = scope.internal.getEncryptor(objId);
+              content += "(" + pdfEscape(encryptor(array[i].toString())) + ")";
+            } else {
+              content += array[i].toString();
+            }
 
-  FontMetrics.prototype.getMetrics = function(family, size) {
-      if (this.data[family + "-" + size] === undefined) {
-          this.data[family + "-" + size] = new Font(family, size);
+            break;
+        }
       }
-      return this.data[family + "-" + size];
+
+      content += "]";
+      return content;
+    }
+
+    throw new Error("Invalid argument passed to jsPDF.__acroform__.arrayToPdfArray");
   };
 
-  module.exports = FontMetrics;
+  function getMatches(string, regex, index) {
+    index || (index = 1); // default to the first capturing group
 
-  },{"./font":6}],8:[function(_dereq_,module,exports){
-  var utils = _dereq_('./utils');
-  var getBounds = utils.getBounds;
-  var loadUrlDocument = _dereq_('./proxy').loadUrlDocument;
+    var matches = [];
+    var match;
 
-  function FrameContainer(container, sameOrigin, options) {
-      this.image = null;
-      this.src = container;
-      var self = this;
-      var bounds = getBounds(container);
-      this.promise = (!sameOrigin ? this.proxyLoad(options.proxy, bounds, options) : new Promise(function(resolve) {
-          if (container.contentWindow.document.URL === "about:blank" || container.contentWindow.document.documentElement == null) {
-              container.contentWindow.onload = container.onload = function() {
-                  resolve(container);
-              };
-          } else {
-              resolve(container);
-          }
-      })).then(function(container) {
-          var html2canvas = _dereq_('./core');
-          return html2canvas(container.contentWindow.document.documentElement, {type: 'view', width: container.width, height: container.height, proxy: options.proxy, javascriptEnabled: options.javascriptEnabled, removeContainer: options.removeContainer, allowTaint: options.allowTaint, imageTimeout: options.imageTimeout / 2});
-      }).then(function(canvas) {
-          return self.image = canvas;
-      });
+    while (match = regex.exec(string)) {
+      matches.push(match[index]);
+    }
+
+    return matches;
   }
 
-  FrameContainer.prototype.proxyLoad = function(proxy, bounds, options) {
-      var container = this.src;
-      return loadUrlDocument(container.src, proxy, container.ownerDocument, bounds.width, bounds.height, options);
-  };
+  var pdfArrayToStringArray = function pdfArrayToStringArray(array) {
+    var result = [];
 
-  module.exports = FrameContainer;
-
-  },{"./core":4,"./proxy":16,"./utils":26}],9:[function(_dereq_,module,exports){
-  function GradientContainer(imageData) {
-      this.src = imageData.value;
-      this.colorStops = [];
-      this.type = null;
-      this.x0 = 0.5;
-      this.y0 = 0.5;
-      this.x1 = 0.5;
-      this.y1 = 0.5;
-      this.promise = Promise.resolve(true);
-  }
+    if (typeof array === "string") {
+      result = getMatches(array, /\((.*?)\)/g);
+    }
 
-  GradientContainer.TYPES = {
-      LINEAR: 1,
-      RADIAL: 2
+    return result;
   };
 
-  // TODO: support hsl[a], negative %/length values
-  // TODO: support <angle> (e.g. -?\d{1,3}(?:\.\d+)deg, etc. : https://developer.mozilla.org/docs/Web/CSS/angle )
-  GradientContainer.REGEXP_COLORSTOP = /^\s*(rgba?\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3}(?:,\s*[0-9\.]+)?\s*\)|[a-z]{3,20}|#[a-f0-9]{3,6})(?:\s+(\d{1,3}(?:\.\d+)?)(%|px)?)?(?:\s|$)/i;
+  var toPdfString = function toPdfString(string, objId, scope) {
+    var encryptor = function encryptor(data) {
+      return data;
+    };
 
-  module.exports = GradientContainer;
+    if (typeof objId !== "undefined" && scope) encryptor = scope.internal.getEncryptor(objId);
+    string = string || "";
+    string.toString();
+    string = "(" + pdfEscape(encryptor(string)) + ")";
+    return string;
+  }; // ##########################
+  // Classes
+  // ##########################
 
-  },{}],10:[function(_dereq_,module,exports){
-  function ImageContainer(src, cors) {
-      this.src = src;
-      this.image = new Image();
-      var self = this;
-      this.tainted = null;
-      this.promise = new Promise(function(resolve, reject) {
-          self.image.onload = resolve;
-          self.image.onerror = reject;
-          if (cors) {
-              self.image.crossOrigin = "anonymous";
-          }
-          self.image.src = src;
-          if (self.image.complete === true) {
-              resolve(self.image);
-          }
-      });
-  }
+  /**
+   * @class AcroFormPDFObject
+   * @classdesc A AcroFormPDFObject
+   */
 
-  module.exports = ImageContainer;
-
-  },{}],11:[function(_dereq_,module,exports){
-  var log = _dereq_('./log');
-  var ImageContainer = _dereq_('./imagecontainer');
-  var DummyImageContainer = _dereq_('./dummyimagecontainer');
-  var ProxyImageContainer = _dereq_('./proxyimagecontainer');
-  var FrameContainer = _dereq_('./framecontainer');
-  var SVGContainer = _dereq_('./svgcontainer');
-  var SVGNodeContainer = _dereq_('./svgnodecontainer');
-  var LinearGradientContainer = _dereq_('./lineargradientcontainer');
-  var WebkitGradientContainer = _dereq_('./webkitgradientcontainer');
-  var bind = _dereq_('./utils').bind;
-
-  function ImageLoader(options, support) {
-      this.link = null;
-      this.options = options;
-      this.support = support;
-      this.origin = this.getOrigin(window.location.href);
-  }
 
-  ImageLoader.prototype.findImages = function(nodes) {
-      var images = [];
-      nodes.reduce(function(imageNodes, container) {
-          switch(container.node.nodeName) {
-          case "IMG":
-              return imageNodes.concat([{
-                  args: [container.node.src],
-                  method: "url"
-              }]);
-          case "svg":
-          case "IFRAME":
-              return imageNodes.concat([{
-                  args: [container.node],
-                  method: container.node.nodeName
-              }]);
+  var AcroFormPDFObject = function AcroFormPDFObject() {
+    this._objId = undefined;
+    this._scope = undefined;
+    /**
+     * @name AcroFormPDFObject#objId
+     * @type {any}
+     */
+
+    Object.defineProperty(this, "objId", {
+      get: function get() {
+        if (typeof this._objId === "undefined") {
+          if (typeof this.scope === "undefined") {
+            return undefined;
           }
-          return imageNodes;
-      }, []).forEach(this.addImage(images, this.loadImage), this);
-      return images;
-  };
 
-  ImageLoader.prototype.findBackgroundImage = function(images, container) {
-      container.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(images, this.loadImage), this);
-      return images;
-  };
+          this._objId = this.scope.internal.newObjectDeferred();
+        }
 
-  ImageLoader.prototype.addImage = function(images, callback) {
-      return function(newImage) {
-          newImage.args.forEach(function(image) {
-              if (!this.imageExists(images, image)) {
-                  images.splice(0, 0, callback.call(this, newImage));
-                  log('Added image #' + (images.length), typeof(image) === "string" ? image.substring(0, 100) : image);
-              }
-          }, this);
-      };
+        return this._objId;
+      },
+      set: function set(value) {
+        this._objId = value;
+      }
+    });
+    Object.defineProperty(this, "scope", {
+      value: this._scope,
+      writable: true
+    });
   };
+  /**
+   * @function AcroFormPDFObject.toString
+   */
 
-  ImageLoader.prototype.hasImageBackground = function(imageData) {
-      return imageData.method !== "none";
-  };
 
-  ImageLoader.prototype.loadImage = function(imageData) {
-      if (imageData.method === "url") {
-          var src = imageData.args[0];
-          if (this.isSVG(src) && !this.support.svg && !this.options.allowTaint) {
-              return new SVGContainer(src);
-          } else if (src.match(/data:image\/.*;base64,/i)) {
-              return new ImageContainer(src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''), false);
-          } else if (this.isSameOrigin(src) || this.options.allowTaint === true || this.isSVG(src)) {
-              return new ImageContainer(src, false);
-          } else if (this.support.cors && !this.options.allowTaint && this.options.useCORS) {
-              return new ImageContainer(src, true);
-          } else if (this.options.proxy) {
-              return new ProxyImageContainer(src, this.options.proxy);
-          } else {
-              return new DummyImageContainer(src);
-          }
-      } else if (imageData.method === "linear-gradient") {
-          return new LinearGradientContainer(imageData);
-      } else if (imageData.method === "gradient") {
-          return new WebkitGradientContainer(imageData);
-      } else if (imageData.method === "svg") {
-          return new SVGNodeContainer(imageData.args[0], this.support.svg);
-      } else if (imageData.method === "IFRAME") {
-          return new FrameContainer(imageData.args[0], this.isSameOrigin(imageData.args[0].src), this.options);
-      } else {
-          return new DummyImageContainer(imageData);
-      }
+  AcroFormPDFObject.prototype.toString = function () {
+    return this.objId + " 0 R";
   };
 
-  ImageLoader.prototype.isSVG = function(src) {
-      return src.substring(src.length - 3).toLowerCase() === "svg" || SVGContainer.prototype.isInline(src);
+  AcroFormPDFObject.prototype.putStream = function () {
+    var keyValueList = this.getKeyValueListForStream();
+    this.scope.internal.putStream({
+      data: this.stream,
+      additionalKeyValues: keyValueList,
+      objectId: this.objId
+    });
+    this.scope.internal.out("endobj");
   };
+  /**
+   * Returns an key-value-List of all non-configurable Variables from the Object
+   *
+   * @name getKeyValueListForStream
+   * @returns {string}
+   */
 
-  ImageLoader.prototype.imageExists = function(images, src) {
-      return images.some(function(image) {
-          return image.src === src;
-      });
-  };
 
-  ImageLoader.prototype.isSameOrigin = function(url) {
-      return (this.getOrigin(url) === this.origin);
-  };
+  AcroFormPDFObject.prototype.getKeyValueListForStream = function () {
+    var keyValueList = [];
+    var keys = Object.getOwnPropertyNames(this).filter(function (key) {
+      return key != "content" && key != "appearanceStreamContent" && key != "scope" && key != "objId" && key.substring(0, 1) != "_";
+    });
 
-  ImageLoader.prototype.getOrigin = function(url) {
-      var link = this.link || (this.link = document.createElement("a"));
-      link.href = url;
-      link.href = link.href; // IE9, LOL! - http://jsfiddle.net/niklasvh/2e48b/
-      return link.protocol + link.hostname + link.port;
-  };
+    for (var i in keys) {
+      if (Object.getOwnPropertyDescriptor(this, keys[i]).configurable === false) {
+        var key = keys[i];
+        var value = this[key];
 
-  ImageLoader.prototype.getPromise = function(container) {
-      return this.timeout(container, this.options.imageTimeout)['catch'](function() {
-          var dummy = new DummyImageContainer(container.src);
-          return dummy.promise.then(function(image) {
-              container.image = image;
-          });
-      });
-  };
+        if (value) {
+          if (Array.isArray(value)) {
+            keyValueList.push({
+              key: key,
+              value: arrayToPdfArray(value, this.objId, this.scope)
+            });
+          } else if (value instanceof AcroFormPDFObject) {
+            // In case it is a reference to another PDFObject,
+            // take the reference number
+            value.scope = this.scope;
+            keyValueList.push({
+              key: key,
+              value: value.objId + " 0 R"
+            });
+          } else if (typeof value !== "function") {
+            keyValueList.push({
+              key: key,
+              value: value
+            });
+          }
+        }
+      }
+    }
 
-  ImageLoader.prototype.get = function(src) {
-      var found = null;
-      return this.images.some(function(img) {
-          return (found = img).src === src;
-      }) ? found : null;
+    return keyValueList;
   };
 
-  ImageLoader.prototype.fetch = function(nodes) {
-      this.images = nodes.reduce(bind(this.findBackgroundImage, this), this.findImages(nodes));
-      this.images.forEach(function(image, index) {
-          image.promise.then(function() {
-              log("Succesfully loaded image #"+ (index+1), image);
-          }, function(e) {
-              log("Failed loading image #"+ (index+1), image, e);
-          });
-      });
-      this.ready = Promise.all(this.images.map(this.getPromise, this));
-      log("Finished searching images");
-      return this;
-  };
-
-  ImageLoader.prototype.timeout = function(container, timeout) {
-      var timer;
-      var promise = Promise.race([container.promise, new Promise(function(res, reject) {
-          timer = setTimeout(function() {
-              log("Timed out loading image", container);
-              reject(container);
-          }, timeout);
-      })]).then(function(container) {
-          clearTimeout(timer);
-          return container;
-      });
-      promise['catch'](function() {
-          clearTimeout(timer);
-      });
-      return promise;
-  };
-
-  module.exports = ImageLoader;
-
-  },{"./dummyimagecontainer":5,"./framecontainer":8,"./imagecontainer":10,"./lineargradientcontainer":12,"./log":13,"./proxyimagecontainer":17,"./svgcontainer":23,"./svgnodecontainer":24,"./utils":26,"./webkitgradientcontainer":27}],12:[function(_dereq_,module,exports){
-  var GradientContainer = _dereq_('./gradientcontainer');
-  var Color = _dereq_('./color');
-
-  function LinearGradientContainer(imageData) {
-      GradientContainer.apply(this, arguments);
-      this.type = GradientContainer.TYPES.LINEAR;
+  var AcroFormXObject = function AcroFormXObject() {
+    AcroFormPDFObject.call(this);
+    Object.defineProperty(this, "Type", {
+      value: "/XObject",
+      configurable: false,
+      writable: true
+    });
+    Object.defineProperty(this, "Subtype", {
+      value: "/Form",
+      configurable: false,
+      writable: true
+    });
+    Object.defineProperty(this, "FormType", {
+      value: 1,
+      configurable: false,
+      writable: true
+    });
+    var _BBox = [];
+    Object.defineProperty(this, "BBox", {
+      configurable: false,
+      get: function get() {
+        return _BBox;
+      },
+      set: function set(value) {
+        _BBox = value;
+      }
+    });
+    Object.defineProperty(this, "Resources", {
+      value: "2 0 R",
+      configurable: false,
+      writable: true
+    });
 
-      var hasDirection = LinearGradientContainer.REGEXP_DIRECTION.test( imageData.args[0] ) ||
-          !GradientContainer.REGEXP_COLORSTOP.test( imageData.args[0] );
+    var _stream;
 
-      if (hasDirection) {
-          imageData.args[0].split(/\s+/).reverse().forEach(function(position, index) {
-              switch(position) {
-              case "left":
-                  this.x0 = 0;
-                  this.x1 = 1;
-                  break;
-              case "top":
-                  this.y0 = 0;
-                  this.y1 = 1;
-                  break;
-              case "right":
-                  this.x0 = 1;
-                  this.x1 = 0;
-                  break;
-              case "bottom":
-                  this.y0 = 1;
-                  this.y1 = 0;
-                  break;
-              case "to":
-                  var y0 = this.y0;
-                  var x0 = this.x0;
-                  this.y0 = this.y1;
-                  this.x0 = this.x1;
-                  this.x1 = x0;
-                  this.y1 = y0;
-                  break;
-              case "center":
-                  break; // centered by default
-              // Firefox internally converts position keywords to percentages:
-              // http://www.w3.org/TR/2010/WD-CSS2-20101207/colors.html#propdef-background-position
-              default: // percentage or absolute length
-                  // TODO: support absolute start point positions (e.g., use bounds to convert px to a ratio)
-                  var ratio = parseFloat(position, 10) * 1e-2;
-                  if (isNaN(ratio)) { // invalid or unhandled value
-                      break;
-                  }
-                  if (index === 0) {
-                      this.y0 = ratio;
-                      this.y1 = 1 - this.y0;
-                  } else {
-                      this.x0 = ratio;
-                      this.x1 = 1 - this.x0;
-                  }
-                  break;
-              }
-          }, this);
-      } else {
-          this.y0 = 0;
-          this.y1 = 1;
+    Object.defineProperty(this, "stream", {
+      enumerable: false,
+      configurable: true,
+      set: function set(value) {
+        _stream = value.trim();
+      },
+      get: function get() {
+        if (_stream) {
+          return _stream;
+        } else {
+          return null;
+        }
       }
+    });
+  };
 
-      this.colorStops = imageData.args.slice(hasDirection ? 1 : 0).map(function(colorStop) {
-          var colorStopMatch = colorStop.match(GradientContainer.REGEXP_COLORSTOP);
-          var value = +colorStopMatch[2];
-          var unit = value === 0 ? "%" : colorStopMatch[3]; // treat "0" as "0%"
-          return {
-              color: new Color(colorStopMatch[1]),
-              // TODO: support absolute stop positions (e.g., compute gradient line length & convert px to ratio)
-              stop: unit === "%" ? value / 100 : null
-          };
-      });
+  inherit(AcroFormXObject, AcroFormPDFObject);
 
-      if (this.colorStops[0].stop === null) {
-          this.colorStops[0].stop = 0;
+  var AcroFormDictionary = function AcroFormDictionary() {
+    AcroFormPDFObject.call(this);
+    var _Kids = [];
+    Object.defineProperty(this, "Kids", {
+      enumerable: false,
+      configurable: true,
+      get: function get() {
+        if (_Kids.length > 0) {
+          return _Kids;
+        } else {
+          return undefined;
+        }
       }
-
-      if (this.colorStops[this.colorStops.length - 1].stop === null) {
-          this.colorStops[this.colorStops.length - 1].stop = 1;
+    });
+    Object.defineProperty(this, "Fields", {
+      enumerable: false,
+      configurable: false,
+      get: function get() {
+        return _Kids;
       }
+    }); // Default Appearance
 
-      // calculates and fills-in explicit stop positions when omitted from rule
-      this.colorStops.forEach(function(colorStop, index) {
-          if (colorStop.stop === null) {
-              this.colorStops.slice(index).some(function(find, count) {
-                  if (find.stop !== null) {
-                      colorStop.stop = ((find.stop - this.colorStops[index - 1].stop) / (count + 1)) + this.colorStops[index - 1].stop;
-                      return true;
-                  } else {
-                      return false;
-                  }
-              }, this);
-          }
-      }, this);
-  }
-
-  LinearGradientContainer.prototype = Object.create(GradientContainer.prototype);
+    var _DA;
 
-  // TODO: support <angle> (e.g. -?\d{1,3}(?:\.\d+)deg, etc. : https://developer.mozilla.org/docs/Web/CSS/angle )
-  LinearGradientContainer.REGEXP_DIRECTION = /^\s*(?:to|left|right|top|bottom|center|\d{1,3}(?:\.\d+)?%?)(?:\s|$)/i;
+    Object.defineProperty(this, "DA", {
+      enumerable: false,
+      configurable: false,
+      get: function get() {
+        if (!_DA) {
+          return undefined;
+        }
 
-  module.exports = LinearGradientContainer;
+        var encryptor = function encryptor(data) {
+          return data;
+        };
 
-  },{"./color":3,"./gradientcontainer":9}],13:[function(_dereq_,module,exports){
-  var logger = function() {
-      if (logger.options.logging && window.console && window.console.log) {
-          Function.prototype.bind.call(window.console.log, (window.console)).apply(window.console, [(Date.now() - logger.options.start) + "ms", "html2canvas:"].concat([].slice.call(arguments, 0)));
+        if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId);
+        return "(" + pdfEscape(encryptor(_DA)) + ")";
+      },
+      set: function set(value) {
+        _DA = value;
       }
+    });
   };
 
-  logger.options = {logging: false};
-  module.exports = logger;
-
-  },{}],14:[function(_dereq_,module,exports){
-  var Color = _dereq_('./color');
-  var utils = _dereq_('./utils');
-  var getBounds = utils.getBounds;
-  var parseBackgrounds = utils.parseBackgrounds;
-  var offsetBounds = utils.offsetBounds;
-
-  function NodeContainer(node, parent) {
-      this.node = node;
-      this.parent = parent;
-      this.stack = null;
-      this.bounds = null;
-      this.borders = null;
-      this.clip = [];
-      this.backgroundClip = [];
-      this.offsetBounds = null;
-      this.visible = null;
-      this.computedStyles = null;
-      this.colors = {};
-      this.styles = {};
-      this.backgroundImages = null;
-      this.transformData = null;
-      this.transformMatrix = null;
-      this.isPseudoElement = false;
-      this.opacity = null;
-  }
-
-  NodeContainer.prototype.cloneTo = function(stack) {
-      stack.visible = this.visible;
-      stack.borders = this.borders;
-      stack.bounds = this.bounds;
-      stack.clip = this.clip;
-      stack.backgroundClip = this.backgroundClip;
-      stack.computedStyles = this.computedStyles;
-      stack.styles = this.styles;
-      stack.backgroundImages = this.backgroundImages;
-      stack.opacity = this.opacity;
-  };
+  inherit(AcroFormDictionary, AcroFormPDFObject);
+  /**
+   * The Field Object contains the Variables, that every Field needs
+   *
+   * @class AcroFormField
+   * @classdesc An AcroForm FieldObject
+   */
 
-  NodeContainer.prototype.getOpacity = function() {
-      return this.opacity === null ? (this.opacity = this.cssFloat('opacity')) : this.opacity;
-  };
+  var AcroFormField = function AcroFormField() {
+    AcroFormPDFObject.call(this); //Annotation-Flag See Table 165
 
-  NodeContainer.prototype.assignStack = function(stack) {
-      this.stack = stack;
-      stack.children.push(this);
-  };
+    var _F = 4;
+    Object.defineProperty(this, "F", {
+      enumerable: false,
+      configurable: false,
+      get: function get() {
+        return _F;
+      },
+      set: function set(value) {
+        if (!isNaN(value)) {
+          _F = value;
+        } else {
+          throw new Error('Invalid value "' + value + '" for attribute F supplied.');
+        }
+      }
+    });
+    /**
+     * (PDF 1.2) If set, print the annotation when the page is printed. If clear, never print the annotation, regardless of wether is is displayed on the screen.
+     * NOTE 2 This can be useful for annotations representing interactive pushbuttons, which would serve no meaningful purpose on the printed page.
+     *
+     * @name AcroFormField#showWhenPrinted
+     * @default true
+     * @type {boolean}
+     */
 
-  NodeContainer.prototype.isElementVisible = function() {
-      return this.node.nodeType === Node.TEXT_NODE ? this.parent.visible : (
-          this.css('display') !== "none" &&
-          this.css('visibility') !== "hidden" &&
-          !this.node.hasAttribute("data-html2canvas-ignore") &&
-          (this.node.nodeName !== "INPUT" || this.node.getAttribute("type") !== "hidden")
-      );
-  };
+    Object.defineProperty(this, "showWhenPrinted", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(_F, 3));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.F = setBitForPdf(_F, 3);
+        } else {
+          this.F = clearBitForPdf(_F, 3);
+        }
+      }
+    });
+    var _Ff = 0;
+    Object.defineProperty(this, "Ff", {
+      enumerable: false,
+      configurable: false,
+      get: function get() {
+        return _Ff;
+      },
+      set: function set(value) {
+        if (!isNaN(value)) {
+          _Ff = value;
+        } else {
+          throw new Error('Invalid value "' + value + '" for attribute Ff supplied.');
+        }
+      }
+    });
+    var _Rect = [];
+    Object.defineProperty(this, "Rect", {
+      enumerable: false,
+      configurable: false,
+      get: function get() {
+        if (_Rect.length === 0) {
+          return undefined;
+        }
 
-  NodeContainer.prototype.css = function(attribute) {
-      if (!this.computedStyles) {
-          this.computedStyles = this.isPseudoElement ? this.parent.computedStyle(this.before ? ":before" : ":after") : this.computedStyle(null);
+        return _Rect;
+      },
+      set: function set(value) {
+        if (typeof value !== "undefined") {
+          _Rect = value;
+        } else {
+          _Rect = [];
+        }
       }
+    });
+    /**
+     * The x-position of the field.
+     *
+     * @name AcroFormField#x
+     * @default null
+     * @type {number}
+     */
 
-      return this.styles[attribute] || (this.styles[attribute] = this.computedStyles[attribute]);
-  };
+    Object.defineProperty(this, "x", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        if (!_Rect || isNaN(_Rect[0])) {
+          return 0;
+        }
 
-  NodeContainer.prototype.prefixedCss = function(attribute) {
-      var prefixes = ["webkit", "moz", "ms", "o"];
-      var value = this.css(attribute);
-      if (value === undefined) {
-          prefixes.some(function(prefix) {
-              value = this.css(prefix + attribute.substr(0, 1).toUpperCase() + attribute.substr(1));
-              return value !== undefined;
-          }, this);
+        return _Rect[0];
+      },
+      set: function set(value) {
+        _Rect[0] = value;
       }
-      return value === undefined ? null : value;
-  };
-
-  NodeContainer.prototype.computedStyle = function(type) {
-      return this.node.ownerDocument.defaultView.getComputedStyle(this.node, type);
-  };
+    });
+    /**
+     * The y-position of the field.
+     *
+     * @name AcroFormField#y
+     * @default null
+     * @type {number}
+     */
 
-  NodeContainer.prototype.cssInt = function(attribute) {
-      var value = parseInt(this.css(attribute), 10);
-      return (isNaN(value)) ? 0 : value; // borders in old IE are throwing 'medium' for demo.html
-  };
+    Object.defineProperty(this, "y", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        if (!_Rect || isNaN(_Rect[1])) {
+          return 0;
+        }
 
-  NodeContainer.prototype.color = function(attribute) {
-      return this.colors[attribute] || (this.colors[attribute] = new Color(this.css(attribute)));
-  };
+        return _Rect[1];
+      },
+      set: function set(value) {
+        _Rect[1] = value;
+      }
+    });
+    /**
+     * The width of the field.
+     *
+     * @name AcroFormField#width
+     * @default null
+     * @type {number}
+     */
 
-  NodeContainer.prototype.cssFloat = function(attribute) {
-      var value = parseFloat(this.css(attribute));
-      return (isNaN(value)) ? 0 : value;
-  };
+    Object.defineProperty(this, "width", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        if (!_Rect || isNaN(_Rect[2])) {
+          return 0;
+        }
 
-  NodeContainer.prototype.fontWeight = function() {
-      var weight = this.css("fontWeight");
-      switch(parseInt(weight, 10)){
-      case 401:
-          weight = "bold";
-          break;
-      case 400:
-          weight = "normal";
-          break;
+        return _Rect[2];
+      },
+      set: function set(value) {
+        _Rect[2] = value;
       }
-      return weight;
-  };
+    });
+    /**
+     * The height of the field.
+     *
+     * @name AcroFormField#height
+     * @default null
+     * @type {number}
+     */
 
-  NodeContainer.prototype.parseClip = function() {
-      var matches = this.css('clip').match(this.CLIP);
-      if (matches) {
-          return {
-              top: parseInt(matches[1], 10),
-              right: parseInt(matches[2], 10),
-              bottom: parseInt(matches[3], 10),
-              left: parseInt(matches[4], 10)
-          };
-      }
-      return null;
-  };
+    Object.defineProperty(this, "height", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        if (!_Rect || isNaN(_Rect[3])) {
+          return 0;
+        }
 
-  NodeContainer.prototype.parseBackgroundImages = function() {
-      return this.backgroundImages || (this.backgroundImages = parseBackgrounds(this.css("backgroundImage")));
-  };
+        return _Rect[3];
+      },
+      set: function set(value) {
+        _Rect[3] = value;
+      }
+    });
+    var _FT = "";
+    Object.defineProperty(this, "FT", {
+      enumerable: true,
+      configurable: false,
+      get: function get() {
+        return _FT;
+      },
+      set: function set(value) {
+        switch (value) {
+          case "/Btn":
+          case "/Tx":
+          case "/Ch":
+          case "/Sig":
+            _FT = value;
+            break;
 
-  NodeContainer.prototype.cssList = function(property, index) {
-      var value = (this.css(property) || '').split(',');
-      value = value[index || 0] || value[0] || 'auto';
-      value = value.trim().split(' ');
-      if (value.length === 1) {
-          value = [value[0], isPercentage(value[0]) ? 'auto' : value[0]];
+          default:
+            throw new Error('Invalid value "' + value + '" for attribute FT supplied.');
+        }
       }
-      return value;
-  };
+    });
+    var _T = null;
+    Object.defineProperty(this, "T", {
+      enumerable: true,
+      configurable: false,
+      get: function get() {
+        if (!_T || _T.length < 1) {
+          // In case of a Child from a Radio´Group, you don't need a FieldName
+          if (this instanceof AcroFormChildClass) {
+            return undefined;
+          }
 
-  NodeContainer.prototype.parseBackgroundSize = function(bounds, image, index) {
-      var size = this.cssList("backgroundSize", index);
-      var width, height;
+          _T = "FieldObject" + AcroFormField.FieldNum++;
+        }
 
-      if (isPercentage(size[0])) {
-          width = bounds.width * parseFloat(size[0]) / 100;
-      } else if (/contain|cover/.test(size[0])) {
-          var targetRatio = bounds.width / bounds.height, currentRatio = image.width / image.height;
-          return (targetRatio < currentRatio ^ size[0] === 'contain') ?  {width: bounds.height * currentRatio, height: bounds.height} : {width: bounds.width, height: bounds.width / currentRatio};
-      } else {
-          width = parseInt(size[0], 10);
+        var encryptor = function encryptor(data) {
+          return data;
+        };
+
+        if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId);
+        return "(" + pdfEscape(encryptor(_T)) + ")";
+      },
+      set: function set(value) {
+        _T = value.toString();
       }
+    });
+    /**
+     * (Optional) The partial field name (see 12.7.3.2, “Field Names”).
+     *
+     * @name AcroFormField#fieldName
+     * @default null
+     * @type {string}
+     */
 
-      if (size[0] === 'auto' && size[1] === 'auto') {
-          height = image.height;
-      } else if (size[1] === 'auto') {
-          height = width / image.width * image.height;
-      } else if (isPercentage(size[1])) {
-          height =  bounds.height * parseFloat(size[1]) / 100;
-      } else {
-          height = parseInt(size[1], 10);
+    Object.defineProperty(this, "fieldName", {
+      configurable: true,
+      enumerable: true,
+      get: function get() {
+        return _T;
+      },
+      set: function set(value) {
+        _T = value;
       }
+    });
+    var _fontName = "helvetica";
+    /**
+     * The fontName of the font to be used.
+     *
+     * @name AcroFormField#fontName
+     * @default 'helvetica'
+     * @type {string}
+     */
 
-      if (size[0] === 'auto') {
-          width = height / image.height * image.width;
+    Object.defineProperty(this, "fontName", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return _fontName;
+      },
+      set: function set(value) {
+        _fontName = value;
       }
+    });
+    var _fontStyle = "normal";
+    /**
+     * The fontStyle of the font to be used.
+     *
+     * @name AcroFormField#fontStyle
+     * @default 'normal'
+     * @type {string}
+     */
 
-      return {width: width, height: height};
-  };
+    Object.defineProperty(this, "fontStyle", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return _fontStyle;
+      },
+      set: function set(value) {
+        _fontStyle = value;
+      }
+    });
+    var _fontSize = 0;
+    /**
+     * The fontSize of the font to be used.
+     *
+     * @name AcroFormField#fontSize
+     * @default 0 (for auto)
+     * @type {number}
+     */
 
-  NodeContainer.prototype.parseBackgroundPosition = function(bounds, image, index, backgroundSize) {
-      var position = this.cssList('backgroundPosition', index);
-      var left, top;
+    Object.defineProperty(this, "fontSize", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return _fontSize;
+      },
+      set: function set(value) {
+        _fontSize = value;
+      }
+    });
+    var _maxFontSize = undefined;
+    /**
+     * The maximum fontSize of the font to be used.
+     *
+     * @name AcroFormField#maxFontSize
+     * @default 0 (for auto)
+     * @type {number}
+     */
 
-      if (isPercentage(position[0])){
-          left = (bounds.width - (backgroundSize || image).width) * (parseFloat(position[0]) / 100);
-      } else {
-          left = parseInt(position[0], 10);
+    Object.defineProperty(this, "maxFontSize", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        if (_maxFontSize === undefined) {
+          // use the old default value here - the value is some kind of random as it depends on the scaleFactor (user unit)
+          // ("50" is transformed to the "user space" but then used in "pdf space")
+          return 50 / scaleFactor;
+        } else {
+          return _maxFontSize;
+        }
+      },
+      set: function set(value) {
+        _maxFontSize = value;
       }
+    });
+    var _color = "black";
+    /**
+     * The color of the text
+     *
+     * @name AcroFormField#color
+     * @default 'black'
+     * @type {string|rgba}
+     */
 
-      if (position[1] === 'auto') {
-          top = left / image.width * image.height;
-      } else if (isPercentage(position[1])){
-          top =  (bounds.height - (backgroundSize || image).height) * parseFloat(position[1]) / 100;
-      } else {
-          top = parseInt(position[1], 10);
+    Object.defineProperty(this, "color", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return _color;
+      },
+      set: function set(value) {
+        _color = value;
       }
+    });
+    var _DA = "/F1 0 Tf 0 g"; // Defines the default appearance (Needed for variable Text)
+
+    Object.defineProperty(this, "DA", {
+      enumerable: true,
+      configurable: false,
+      get: function get() {
+        if (!_DA || this instanceof AcroFormChildClass || this instanceof AcroFormTextField) {
+          return undefined;
+        }
 
-      if (position[0] === 'auto') {
-          left = top / image.height * image.width;
+        return toPdfString(_DA, this.objId, this.scope);
+      },
+      set: function set(value) {
+        value = value.toString();
+        _DA = value;
       }
+    });
+    var _DV = null;
+    Object.defineProperty(this, "DV", {
+      enumerable: false,
+      configurable: false,
+      get: function get() {
+        if (!_DV) {
+          return undefined;
+        }
 
-      return {left: left, top: top};
-  };
+        if (this instanceof AcroFormButton === false) {
+          return toPdfString(_DV, this.objId, this.scope);
+        }
 
-  NodeContainer.prototype.parseBackgroundRepeat = function(index) {
-      return this.cssList("backgroundRepeat", index)[0];
-  };
+        return _DV;
+      },
+      set: function set(value) {
+        value = value.toString();
 
-  NodeContainer.prototype.parseTextShadows = function() {
-      var textShadow = this.css("textShadow");
-      var results = [];
-
-      if (textShadow && textShadow !== 'none') {
-          var shadows = textShadow.match(this.TEXT_SHADOW_PROPERTY);
-          for (var i = 0; shadows && (i < shadows.length); i++) {
-              var s = shadows[i].match(this.TEXT_SHADOW_VALUES);
-              results.push({
-                  color: new Color(s[0]),
-                  offsetX: s[1] ? parseFloat(s[1].replace('px', '')) : 0,
-                  offsetY: s[2] ? parseFloat(s[2].replace('px', '')) : 0,
-                  blur: s[3] ? s[3].replace('px', '') : 0
-              });
+        if (this instanceof AcroFormButton === false) {
+          if (value.substr(0, 1) === "(") {
+            _DV = pdfUnescape(value.substr(1, value.length - 2));
+          } else {
+            _DV = pdfUnescape(value);
           }
+        } else {
+          _DV = value;
+        }
       }
-      return results;
-  };
+    });
+    /**
+     * (Optional; inheritable) The default value to which the field reverts when a reset-form action is executed (see 12.7.5.3, “Reset-Form Action”). The format of this value is the same as that of value.
+     *
+     * @name AcroFormField#defaultValue
+     * @default null
+     * @type {any}
+     */
 
-  NodeContainer.prototype.parseTransform = function() {
-      if (!this.transformData) {
-          if (this.hasTransform()) {
-              var offset = this.parseBounds();
-              var origin = this.prefixedCss("transformOrigin").split(" ").map(removePx).map(asFloat);
-              origin[0] += offset.left;
-              origin[1] += offset.top;
-              this.transformData = {
-                  origin: origin,
-                  matrix: this.parseTransformMatrix()
-              };
-          } else {
-              this.transformData = {
-                  origin: [0, 0],
-                  matrix: [1, 0, 0, 1, 0, 0]
-              };
-          }
+    Object.defineProperty(this, "defaultValue", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        if (this instanceof AcroFormButton === true) {
+          return pdfUnescape(_DV.substr(1, _DV.length - 1));
+        } else {
+          return _DV;
+        }
+      },
+      set: function set(value) {
+        value = value.toString();
+
+        if (this instanceof AcroFormButton === true) {
+          _DV = "/" + value;
+        } else {
+          _DV = value;
+        }
       }
-      return this.transformData;
-  };
+    });
+    var _V = null;
+    Object.defineProperty(this, "_V", {
+      enumerable: false,
+      configurable: false,
+      get: function get() {
+        if (!_V) {
+          return undefined;
+        }
 
-  NodeContainer.prototype.parseTransformMatrix = function() {
-      if (!this.transformMatrix) {
-          var transform = this.prefixedCss("transform");
-          var matrix = transform ? parseMatrix(transform.match(this.MATRIX_PROPERTY)) : null;
-          this.transformMatrix = matrix ? matrix : [1, 0, 0, 1, 0, 0];
+        return _V;
+      },
+      set: function set(value) {
+        this.V = value;
       }
-      return this.transformMatrix;
-  };
+    });
+    Object.defineProperty(this, "V", {
+      enumerable: false,
+      configurable: false,
+      get: function get() {
+        if (!_V) {
+          return undefined;
+        }
 
-  NodeContainer.prototype.parseBounds = function() {
-      return this.bounds || (this.bounds = this.hasTransform() ? offsetBounds(this.node) : getBounds(this.node));
-  };
+        if (this instanceof AcroFormButton === false) {
+          return toPdfString(_V, this.objId, this.scope);
+        }
 
-  NodeContainer.prototype.hasTransform = function() {
-      return this.parseTransformMatrix().join(",") !== "1,0,0,1,0,0" || (this.parent && this.parent.hasTransform());
-  };
+        return _V;
+      },
+      set: function set(value) {
+        value = value.toString();
 
-  NodeContainer.prototype.getValue = function() {
-      var value = this.node.value || "";
-      if (this.node.tagName === "SELECT") {
-          value = selectionValue(this.node);
-      } else if (this.node.type === "password") {
-          value = Array(value.length + 1).join('\u2022'); // jshint ignore:line
+        if (this instanceof AcroFormButton === false) {
+          if (value.substr(0, 1) === "(") {
+            _V = pdfUnescape(value.substr(1, value.length - 2));
+          } else {
+            _V = pdfUnescape(value);
+          }
+        } else {
+          _V = value;
+        }
       }
-      return value.length === 0 ? (this.node.placeholder || "") : value;
-  };
+    });
+    /**
+     * (Optional; inheritable) The field’s value, whose format varies depending on the field type. See the descriptions of individual field types for further information.
+     *
+     * @name AcroFormField#value
+     * @default null
+     * @type {any}
+     */
 
-  NodeContainer.prototype.MATRIX_PROPERTY = /(matrix|matrix3d)\((.+)\)/;
-  NodeContainer.prototype.TEXT_SHADOW_PROPERTY = /((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g;
-  NodeContainer.prototype.TEXT_SHADOW_VALUES = /(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g;
-  NodeContainer.prototype.CLIP = /^rect\((\d+)px,? (\d+)px,? (\d+)px,? (\d+)px\)$/;
+    Object.defineProperty(this, "value", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        if (this instanceof AcroFormButton === true) {
+          return pdfUnescape(_V.substr(1, _V.length - 1));
+        } else {
+          return _V;
+        }
+      },
+      set: function set(value) {
+        value = value.toString();
 
-  function selectionValue(node) {
-      var option = node.options[node.selectedIndex || 0];
-      return option ? (option.text || "") : "";
-  }
+        if (this instanceof AcroFormButton === true) {
+          _V = "/" + value;
+        } else {
+          _V = value;
+        }
+      }
+    });
+    /**
+     * Check if field has annotations
+     *
+     * @name AcroFormField#hasAnnotation
+     * @readonly
+     * @type {boolean}
+     */
 
-  function parseMatrix(match) {
-      if (match && match[1] === "matrix") {
-          return match[2].split(",").map(function(s) {
-              return parseFloat(s.trim());
-          });
-      } else if (match && match[1] === "matrix3d") {
-          var matrix3d = match[2].split(",").map(function(s) {
-            return parseFloat(s.trim());
-          });
-          return [matrix3d[0], matrix3d[1], matrix3d[4], matrix3d[5], matrix3d[12], matrix3d[13]];
+    Object.defineProperty(this, "hasAnnotation", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return this.Rect;
       }
-  }
+    });
+    Object.defineProperty(this, "Type", {
+      enumerable: true,
+      configurable: false,
+      get: function get() {
+        return this.hasAnnotation ? "/Annot" : null;
+      }
+    });
+    Object.defineProperty(this, "Subtype", {
+      enumerable: true,
+      configurable: false,
+      get: function get() {
+        return this.hasAnnotation ? "/Widget" : null;
+      }
+    });
+    var _hasAppearanceStream = false;
+    /**
+     * true if field has an appearanceStream
+     *
+     * @name AcroFormField#hasAppearanceStream
+     * @readonly
+     * @type {boolean}
+     */
 
-  function isPercentage(value) {
-      return value.toString().indexOf("%") !== -1;
-  }
+    Object.defineProperty(this, "hasAppearanceStream", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return _hasAppearanceStream;
+      },
+      set: function set(value) {
+        value = Boolean(value);
+        _hasAppearanceStream = value;
+      }
+    });
+    /**
+     * The page on which the AcroFormField is placed
+     *
+     * @name AcroFormField#page
+     * @type {number}
+     */
 
-  function removePx(str) {
-      return str.replace("px", "");
-  }
+    var _page;
 
-  function asFloat(str) {
-      return parseFloat(str);
-  }
+    Object.defineProperty(this, "page", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        if (!_page) {
+          return undefined;
+        }
 
-  module.exports = NodeContainer;
-
-  },{"./color":3,"./utils":26}],15:[function(_dereq_,module,exports){
-  var log = _dereq_('./log');
-  var punycode = _dereq_('punycode');
-  var NodeContainer = _dereq_('./nodecontainer');
-  var TextContainer = _dereq_('./textcontainer');
-  var PseudoElementContainer = _dereq_('./pseudoelementcontainer');
-  var FontMetrics = _dereq_('./fontmetrics');
-  var Color = _dereq_('./color');
-  var StackingContext = _dereq_('./stackingcontext');
-  var utils = _dereq_('./utils');
-  var bind = utils.bind;
-  var getBounds = utils.getBounds;
-  var parseBackgrounds = utils.parseBackgrounds;
-  var offsetBounds = utils.offsetBounds;
-
-  function NodeParser(element, renderer, support, imageLoader, options) {
-      log("Starting NodeParser");
-      this.renderer = renderer;
-      this.options = options;
-      this.range = null;
-      this.support = support;
-      this.renderQueue = [];
-      this.stack = new StackingContext(true, 1, element.ownerDocument, null);
-      var parent = new NodeContainer(element, null);
-      if (options.background) {
-          renderer.rectangle(0, 0, renderer.width, renderer.height, new Color(options.background));
-      }
-      if (element === element.ownerDocument.documentElement) {
-          // http://www.w3.org/TR/css3-background/#special-backgrounds
-          var canvasBackground = new NodeContainer(parent.color('backgroundColor').isTransparent() ? element.ownerDocument.body : element.ownerDocument.documentElement, null);
-          renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.color('backgroundColor'));
-      }
-      parent.visibile = parent.isElementVisible();
-      this.createPseudoHideStyles(element.ownerDocument);
-      this.disableAnimations(element.ownerDocument);
-      this.nodes = flatten([parent].concat(this.getChildren(parent)).filter(function(container) {
-          return container.visible = container.isElementVisible();
-      }).map(this.getPseudoElements, this));
-      this.fontMetrics = new FontMetrics();
-      log("Fetched nodes, total:", this.nodes.length);
-      log("Calculate overflow clips");
-      this.calculateOverflowClips();
-      log("Start fetching images");
-      this.images = imageLoader.fetch(this.nodes.filter(isElement));
-      this.ready = this.images.ready.then(bind(function() {
-          log("Images loaded, starting parsing");
-          log("Creating stacking contexts");
-          this.createStackingContexts();
-          log("Sorting stacking contexts");
-          this.sortStackingContexts(this.stack);
-          this.parse(this.stack);
-          log("Render queue created with " + this.renderQueue.length + " items");
-          return new Promise(bind(function(resolve) {
-              if (!options.async) {
-                  this.renderQueue.forEach(this.paint, this);
-                  resolve();
-              } else if (typeof(options.async) === "function") {
-                  options.async.call(this, this.renderQueue, resolve);
-              } else if (this.renderQueue.length > 0){
-                  this.renderIndex = 0;
-                  this.asyncRenderer(this.renderQueue, resolve);
-              } else {
-                  resolve();
-              }
-          }, this));
-      }, this));
-  }
+        return _page;
+      },
+      set: function set(value) {
+        _page = value;
+      }
+    });
+    /**
+     * If set, the user may not change the value of the field. Any associated widget annotations will not interact with the user; that is, they will not respond to mouse clicks or change their appearance in response to mouse motions. This flag is useful for fields whose values are computed or imported from a database.
+     *
+     * @name AcroFormField#readOnly
+     * @default false
+     * @type {boolean}
+     */
 
-  NodeParser.prototype.calculateOverflowClips = function() {
-      this.nodes.forEach(function(container) {
-          if (isElement(container)) {
-              if (isPseudoElement(container)) {
-                  container.appendToDOM();
-              }
-              container.borders = this.parseBorders(container);
-              var clip = (container.css('overflow') === "hidden") ? [container.borders.clip] : [];
-              var cssClip = container.parseClip();
-              if (cssClip && ["absolute", "fixed"].indexOf(container.css('position')) !== -1) {
-                  clip.push([["rect",
-                          container.bounds.left + cssClip.left,
-                          container.bounds.top + cssClip.top,
-                          cssClip.right - cssClip.left,
-                          cssClip.bottom - cssClip.top
-                  ]]);
-              }
-              container.clip = hasParentClip(container) ? container.parent.clip.concat(clip) : clip;
-              container.backgroundClip = (container.css('overflow') !== "hidden") ? container.clip.concat([container.borders.clip]) : container.clip;
-              if (isPseudoElement(container)) {
-                  container.cleanDOM();
-              }
-          } else if (isTextNode(container)) {
-              container.clip = hasParentClip(container) ? container.parent.clip : [];
-          }
-          if (!isPseudoElement(container)) {
-              container.bounds = null;
-          }
-      }, this);
-  };
+    Object.defineProperty(this, "readOnly", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 1));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 1);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 1);
+        }
+      }
+    });
+    /**
+     * If set, the field shall have a value at the time it is exported by a submitform action (see 12.7.5.2, “Submit-Form Action”).
+     *
+     * @name AcroFormField#required
+     * @default false
+     * @type {boolean}
+     */
 
-  function hasParentClip(container) {
-      return container.parent && container.parent.clip.length;
-  }
+    Object.defineProperty(this, "required", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 2));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 2);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 2);
+        }
+      }
+    });
+    /**
+     * If set, the field shall not be exported by a submit-form action (see 12.7.5.2, “Submit-Form Action”)
+     *
+     * @name AcroFormField#noExport
+     * @default false
+     * @type {boolean}
+     */
 
-  NodeParser.prototype.asyncRenderer = function(queue, resolve, asyncTimer) {
-      asyncTimer = asyncTimer || Date.now();
-      this.paint(queue[this.renderIndex++]);
-      if (queue.length === this.renderIndex) {
-          resolve();
-      } else if (asyncTimer + 20 > Date.now()) {
-          this.asyncRenderer(queue, resolve, asyncTimer);
-      } else {
-          setTimeout(bind(function() {
-              this.asyncRenderer(queue, resolve);
-          }, this), 0);
+    Object.defineProperty(this, "noExport", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 3));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 3);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 3);
+        }
       }
-  };
+    });
+    var _Q = null;
+    Object.defineProperty(this, "Q", {
+      enumerable: true,
+      configurable: false,
+      get: function get() {
+        if (_Q === null) {
+          return undefined;
+        }
 
-  NodeParser.prototype.createPseudoHideStyles = function(document) {
-      this.createStyles(document, '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + ':before { content: "" !important; display: none !important; }' +
-          '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER + ':after { content: "" !important; display: none !important; }');
-  };
+        return _Q;
+      },
+      set: function set(value) {
+        if ([0, 1, 2].indexOf(value) !== -1) {
+          _Q = value;
+        } else {
+          throw new Error('Invalid value "' + value + '" for attribute Q supplied.');
+        }
+      }
+    });
+    /**
+     * (Optional; inheritable) A code specifying the form of quadding (justification) that shall be used in displaying the text:
+     * 'left', 'center', 'right'
+     *
+     * @name AcroFormField#textAlign
+     * @default 'left'
+     * @type {string}
+     */
 
-  NodeParser.prototype.disableAnimations = function(document) {
-      this.createStyles(document, '* { -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; animation: none !important; ' +
-          '-webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important;}');
-  };
+    Object.defineProperty(this, "textAlign", {
+      get: function get() {
+        var result;
 
-  NodeParser.prototype.createStyles = function(document, styles) {
-      var hidePseudoElements = document.createElement('style');
-      hidePseudoElements.innerHTML = styles;
-      document.body.appendChild(hidePseudoElements);
-  };
+        switch (_Q) {
+          case 0:
+          default:
+            result = "left";
+            break;
 
-  NodeParser.prototype.getPseudoElements = function(container) {
-      var nodes = [[container]];
-      if (container.node.nodeType === Node.ELEMENT_NODE) {
-          var before = this.getPseudoElement(container, ":before");
-          var after = this.getPseudoElement(container, ":after");
+          case 1:
+            result = "center";
+            break;
 
-          if (before) {
-              nodes.push(before);
-          }
+          case 2:
+            result = "right";
+            break;
+        }
 
-          if (after) {
-              nodes.push(after);
-          }
+        return result;
+      },
+      configurable: true,
+      enumerable: true,
+      set: function set(value) {
+        switch (value) {
+          case "right":
+          case 2:
+            _Q = 2;
+            break;
+
+          case "center":
+          case 1:
+            _Q = 1;
+            break;
+
+          case "left":
+          case 0:
+          default:
+            _Q = 0;
+        }
       }
-      return flatten(nodes);
+    });
   };
 
-  function toCamelCase(str) {
-      return str.replace(/(\-[a-z])/g, function(match){
-          return match.toUpperCase().replace('-','');
-      });
-  }
+  inherit(AcroFormField, AcroFormPDFObject);
+  /**
+   * @class AcroFormChoiceField
+   * @extends AcroFormField
+   */
 
-  NodeParser.prototype.getPseudoElement = function(container, type) {
-      var style = container.computedStyle(type);
-      if(!style || !style.content || style.content === "none" || style.content === "-moz-alt-content" || style.display === "none") {
-          return null;
-      }
+  var AcroFormChoiceField = function AcroFormChoiceField() {
+    AcroFormField.call(this); // Field Type = Choice Field
 
-      var content = stripQuotes(style.content);
-      var isImage = content.substr(0, 3) === 'url';
-      var pseudoNode = document.createElement(isImage ? 'img' : 'html2canvaspseudoelement');
-      var pseudoContainer = new PseudoElementContainer(pseudoNode, container, type);
+    this.FT = "/Ch"; // options
 
-      for (var i = style.length-1; i >= 0; i--) {
-          var property = toCamelCase(style.item(i));
-          pseudoNode.style[property] = style[property];
-      }
+    this.V = "()";
+    this.fontName = "zapfdingbats"; // Top Index
 
-      pseudoNode.className = PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + " " + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER;
+    var _TI = 0;
+    Object.defineProperty(this, "TI", {
+      enumerable: true,
+      configurable: false,
+      get: function get() {
+        return _TI;
+      },
+      set: function set(value) {
+        _TI = value;
+      }
+    });
+    /**
+     * (Optional) For scrollable list boxes, the top index (the index in the Opt array of the first option visible in the list). Default value: 0.
+     *
+     * @name AcroFormChoiceField#topIndex
+     * @default 0
+     * @type {number}
+     */
 
-      if (isImage) {
-          pseudoNode.src = parseBackgrounds(content)[0].args[0];
-          return [pseudoContainer];
-      } else {
-          var text = document.createTextNode(content);
-          pseudoNode.appendChild(text);
-          return [pseudoContainer, new TextContainer(text, pseudoContainer)];
+    Object.defineProperty(this, "topIndex", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return _TI;
+      },
+      set: function set(value) {
+        _TI = value;
       }
-  };
+    });
+    var _Opt = [];
+    Object.defineProperty(this, "Opt", {
+      enumerable: true,
+      configurable: false,
+      get: function get() {
+        return arrayToPdfArray(_Opt, this.objId, this.scope);
+      },
+      set: function set(value) {
+        _Opt = pdfArrayToStringArray(value);
+      }
+    });
+    /**
+     * @memberof AcroFormChoiceField
+     * @name getOptions
+     * @function
+     * @instance
+     * @returns {array} array of Options
+     */
 
+    this.getOptions = function () {
+      return _Opt;
+    };
+    /**
+     * @memberof AcroFormChoiceField
+     * @name setOptions
+     * @function
+     * @instance
+     * @param {array} value
+     */
 
-  NodeParser.prototype.getChildren = function(parentContainer) {
-      return flatten([].filter.call(parentContainer.node.childNodes, renderableNode).map(function(node) {
-          var container = [node.nodeType === Node.TEXT_NODE ? new TextContainer(node, parentContainer) : new NodeContainer(node, parentContainer)].filter(nonIgnoredElement);
-          return node.nodeType === Node.ELEMENT_NODE && container.length && node.tagName !== "TEXTAREA" ? (container[0].isElementVisible() ? container.concat(this.getChildren(container[0])) : []) : container;
-      }, this));
-  };
 
-  NodeParser.prototype.newStackingContext = function(container, hasOwnStacking) {
-      var stack = new StackingContext(hasOwnStacking, container.getOpacity(), container.node, container.parent);
-      container.cloneTo(stack);
-      var parentStack = hasOwnStacking ? stack.getParentStack(this) : stack.parent.stack;
-      parentStack.contexts.push(stack);
-      container.stack = stack;
-  };
+    this.setOptions = function (value) {
+      _Opt = value;
 
-  NodeParser.prototype.createStackingContexts = function() {
-      this.nodes.forEach(function(container) {
-          if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || container.hasTransform())) {
-              this.newStackingContext(container, true);
-          } else if (isElement(container) && ((isPositioned(container) && zIndex0(container)) || isInlineBlock(container) || isFloating(container))) {
-              this.newStackingContext(container, false);
-          } else {
-              container.assignStack(container.parent.stack);
-          }
-      }, this);
-  };
+      if (this.sort) {
+        _Opt.sort();
+      }
+    };
+    /**
+     * @memberof AcroFormChoiceField
+     * @name addOption
+     * @function
+     * @instance
+     * @param {string} value
+     */
 
-  NodeParser.prototype.isBodyWithTransparentRoot = function(container) {
-      return container.node.nodeName === "BODY" && container.parent.color('backgroundColor').isTransparent();
-  };
 
-  NodeParser.prototype.isRootElement = function(container) {
-      return container.parent === null;
-  };
+    this.addOption = function (value) {
+      value = value || "";
+      value = value.toString();
 
-  NodeParser.prototype.sortStackingContexts = function(stack) {
-      stack.contexts.sort(zIndexSort(stack.contexts.slice(0)));
-      stack.contexts.forEach(this.sortStackingContexts, this);
-  };
+      _Opt.push(value);
 
-  NodeParser.prototype.parseTextBounds = function(container) {
-      return function(text, index, textList) {
-          if (container.parent.css("textDecoration").substr(0, 4) !== "none" || text.trim().length !== 0) {
-              if (this.support.rangeBounds && !container.parent.hasTransform()) {
-                  var offset = textList.slice(0, index).join("").length;
-                  return this.getRangeBounds(container.node, offset, text.length);
-              } else if (container.node && typeof(container.node.data) === "string") {
-                  var replacementNode = container.node.splitText(text.length);
-                  var bounds = this.getWrapperBounds(container.node, container.parent.hasTransform());
-                  container.node = replacementNode;
-                  return bounds;
-              }
-          } else if(!this.support.rangeBounds || container.parent.hasTransform()){
-              container.node = container.node.splitText(text.length);
-          }
-          return {};
-      };
-  };
+      if (this.sort) {
+        _Opt.sort();
+      }
+    };
+    /**
+     * @memberof AcroFormChoiceField
+     * @name removeOption
+     * @function
+     * @instance
+     * @param {string} value
+     * @param {boolean} allEntries (default: false)
+     */
 
-  NodeParser.prototype.getWrapperBounds = function(node, transform) {
-      var wrapper = node.ownerDocument.createElement('html2canvaswrapper');
-      var parent = node.parentNode,
-          backupText = node.cloneNode(true);
 
-      wrapper.appendChild(node.cloneNode(true));
-      parent.replaceChild(wrapper, node);
-      var bounds = transform ? offsetBounds(wrapper) : getBounds(wrapper);
-      parent.replaceChild(backupText, wrapper);
-      return bounds;
-  };
+    this.removeOption = function (value, allEntries) {
+      allEntries = allEntries || false;
+      value = value || "";
+      value = value.toString();
 
-  NodeParser.prototype.getRangeBounds = function(node, offset, length) {
-      var range = this.range || (this.range = node.ownerDocument.createRange());
-      range.setStart(node, offset);
-      range.setEnd(node, offset + length);
-      return range.getBoundingClientRect();
-  };
+      while (_Opt.indexOf(value) !== -1) {
+        _Opt.splice(_Opt.indexOf(value), 1);
 
-  function ClearTransform() {}
-
-  NodeParser.prototype.parse = function(stack) {
-      // http://www.w3.org/TR/CSS21/visuren.html#z-index
-      var negativeZindex = stack.contexts.filter(negativeZIndex); // 2. the child stacking contexts with negative stack levels (most negative first).
-      var descendantElements = stack.children.filter(isElement);
-      var descendantNonFloats = descendantElements.filter(not(isFloating));
-      var nonInlineNonPositionedDescendants = descendantNonFloats.filter(not(isPositioned)).filter(not(inlineLevel)); // 3 the in-flow, non-inline-level, non-positioned descendants.
-      var nonPositionedFloats = descendantElements.filter(not(isPositioned)).filter(isFloating); // 4. the non-positioned floats.
-      var inFlow = descendantNonFloats.filter(not(isPositioned)).filter(inlineLevel); // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
-      var stackLevel0 = stack.contexts.concat(descendantNonFloats.filter(isPositioned)).filter(zIndex0); // 6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
-      var text = stack.children.filter(isTextNode).filter(hasText);
-      var positiveZindex = stack.contexts.filter(positiveZIndex); // 7. the child stacking contexts with positive stack levels (least positive first).
-      negativeZindex.concat(nonInlineNonPositionedDescendants).concat(nonPositionedFloats)
-          .concat(inFlow).concat(stackLevel0).concat(text).concat(positiveZindex).forEach(function(container) {
-              this.renderQueue.push(container);
-              if (isStackingContext(container)) {
-                  this.parse(container);
-                  this.renderQueue.push(new ClearTransform());
-              }
-          }, this);
-  };
+        if (allEntries === false) {
+          break;
+        }
+      }
+    };
+    /**
+     * If set, the field is a combo box; if clear, the field is a list box.
+     *
+     * @name AcroFormChoiceField#combo
+     * @default false
+     * @type {boolean}
+     */
 
-  NodeParser.prototype.paint = function(container) {
-      try {
-          if (container instanceof ClearTransform) {
-              this.renderer.ctx.restore();
-          } else if (isTextNode(container)) {
-              if (isPseudoElement(container.parent)) {
-                  container.parent.appendToDOM();
-              }
-              this.paintText(container);
-              if (isPseudoElement(container.parent)) {
-                  container.parent.cleanDOM();
-              }
+
+    Object.defineProperty(this, "combo", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 18));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 18);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 18);
+        }
+      }
+    });
+    /**
+     * If set, the combo box shall include an editable text box as well as a drop-down list; if clear, it shall include only a drop-down list. This flag shall be used only if the Combo flag is set.
+     *
+     * @name AcroFormChoiceField#edit
+     * @default false
+     * @type {boolean}
+     */
+
+    Object.defineProperty(this, "edit", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 19));
+      },
+      set: function set(value) {
+        //PDF 32000-1:2008, page 444
+        if (this.combo === true) {
+          if (Boolean(value) === true) {
+            this.Ff = setBitForPdf(this.Ff, 19);
           } else {
-              this.paintNode(container);
-          }
-      } catch(e) {
-          log(e);
-          if (this.options.strict) {
-              throw e;
+            this.Ff = clearBitForPdf(this.Ff, 19);
           }
+        }
       }
-  };
+    });
+    /**
+     * If set, the field’s option items shall be sorted alphabetically. This flag is intended for use by writers, not by readers. Conforming readers shall display the options in the order in which they occur in the Opt array (see Table 231).
+     *
+     * @name AcroFormChoiceField#sort
+     * @default false
+     * @type {boolean}
+     */
 
-  NodeParser.prototype.paintNode = function(container) {
-      if (isStackingContext(container)) {
-          this.renderer.setOpacity(container.opacity);
-          this.renderer.ctx.save();
-          if (container.hasTransform()) {
-              this.renderer.setTransform(container.parseTransform());
-          }
+    Object.defineProperty(this, "sort", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 20));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 20);
+
+          _Opt.sort();
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 20);
+        }
       }
+    });
+    /**
+     * (PDF 1.4) If set, more than one of the field’s option items may be selected simultaneously; if clear, at most one item shall be selected
+     *
+     * @name AcroFormChoiceField#multiSelect
+     * @default false
+     * @type {boolean}
+     */
 
-      if (container.node.nodeName === "INPUT" && container.node.type === "checkbox") {
-          this.paintCheckbox(container);
-      } else if (container.node.nodeName === "INPUT" && container.node.type === "radio") {
-          this.paintRadio(container);
-      } else {
-          this.paintElement(container);
+    Object.defineProperty(this, "multiSelect", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 22));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 22);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 22);
+        }
       }
-  };
+    });
+    /**
+     * (PDF 1.4) If set, text entered in the field shall not be spellchecked. This flag shall not be used unless the Combo and Edit flags are both set.
+     *
+     * @name AcroFormChoiceField#doNotSpellCheck
+     * @default false
+     * @type {boolean}
+     */
 
-  NodeParser.prototype.paintElement = function(container) {
-      var bounds = container.parseBounds();
-      this.renderer.clip(container.backgroundClip, function() {
-          this.renderer.renderBackground(container, bounds, container.borders.borders.map(getWidth));
-      }, this);
-
-      this.renderer.clip(container.clip, function() {
-          this.renderer.renderBorders(container.borders.borders);
-      }, this);
-
-      this.renderer.clip(container.backgroundClip, function() {
-          switch (container.node.nodeName) {
-          case "svg":
-          case "IFRAME":
-              var imgContainer = this.images.get(container.node);
-              if (imgContainer) {
-                  this.renderer.renderImage(container, bounds, container.borders, imgContainer);
-              } else {
-                  log("Error loading <" + container.node.nodeName + ">", container.node);
-              }
-              break;
-          case "IMG":
-              var imageContainer = this.images.get(container.node.src);
-              if (imageContainer) {
-                  this.renderer.renderImage(container, bounds, container.borders, imageContainer);
-              } else {
-                  log("Error loading <img>", container.node.src);
-              }
-              break;
-          case "CANVAS":
-              this.renderer.renderImage(container, bounds, container.borders, {image: container.node});
-              break;
-          case "SELECT":
-          case "INPUT":
-          case "TEXTAREA":
-              this.paintFormValue(container);
-              break;
-          }
-      }, this);
-  };
+    Object.defineProperty(this, "doNotSpellCheck", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 23));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 23);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 23);
+        }
+      }
+    });
+    /**
+     * (PDF 1.5) If set, the new value shall be committed as soon as a selection is made (commonly with the pointing device). In this case, supplying a value for a field involves three actions: selecting the field for fill-in, selecting a choice for the fill-in value, and leaving that field, which finalizes or “commits” the data choice and triggers any actions associated with the entry or changing of this data. If this flag is on, then processing does not wait for leaving the field action to occur, but immediately proceeds to the third step.
+     * This option enables applications to perform an action once a selection is made, without requiring the user to exit the field. If clear, the new value is not committed until the user exits the field.
+     *
+     * @name AcroFormChoiceField#commitOnSelChange
+     * @default false
+     * @type {boolean}
+     */
 
-  NodeParser.prototype.paintCheckbox = function(container) {
-      var b = container.parseBounds();
+    Object.defineProperty(this, "commitOnSelChange", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 27));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 27);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 27);
+        }
+      }
+    });
+    this.hasAppearanceStream = false;
+  };
 
-      var size = Math.min(b.width, b.height);
-      var bounds = {width: size - 1, height: size - 1, top: b.top, left: b.left};
-      var r = [3, 3];
-      var radius = [r, r, r, r];
-      var borders = [1,1,1,1].map(function(w) {
-          return {color: new Color('#A5A5A5'), width: w};
-      });
+  inherit(AcroFormChoiceField, AcroFormField);
+  /**
+   * @class AcroFormListBox
+   * @extends AcroFormChoiceField
+   * @extends AcroFormField
+   */
 
-      var borderPoints = calculateCurvePoints(bounds, radius, borders);
+  var AcroFormListBox = function AcroFormListBox() {
+    AcroFormChoiceField.call(this);
+    this.fontName = "helvetica"; //PDF 32000-1:2008, page 444
 
-      this.renderer.clip(container.backgroundClip, function() {
-          this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, new Color("#DEDEDE"));
-          this.renderer.renderBorders(calculateBorders(borders, bounds, borderPoints, radius));
-          if (container.node.checked) {
-              this.renderer.font(new Color('#424242'), 'normal', 'normal', 'bold', (size - 3) + "px", 'arial');
-              this.renderer.text("\u2714", bounds.left + size / 6, bounds.top + size - 1);
-          }
-      }, this);
+    this.combo = false;
   };
 
-  NodeParser.prototype.paintRadio = function(container) {
-      var bounds = container.parseBounds();
-
-      var size = Math.min(bounds.width, bounds.height) - 2;
+  inherit(AcroFormListBox, AcroFormChoiceField);
+  /**
+   * @class AcroFormComboBox
+   * @extends AcroFormListBox
+   * @extends AcroFormChoiceField
+   * @extends AcroFormField
+   */
 
-      this.renderer.clip(container.backgroundClip, function() {
-          this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, new Color('#DEDEDE'), 1, new Color('#A5A5A5'));
-          if (container.node.checked) {
-              this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), new Color('#424242'));
-          }
-      }, this);
+  var AcroFormComboBox = function AcroFormComboBox() {
+    AcroFormListBox.call(this);
+    this.combo = true;
   };
 
-  NodeParser.prototype.paintFormValue = function(container) {
-      var value = container.getValue();
-      if (value.length > 0) {
-          var document = container.node.ownerDocument;
-          var wrapper = document.createElement('html2canvaswrapper');
-          var properties = ['lineHeight', 'textAlign', 'fontFamily', 'fontWeight', 'fontSize', 'color',
-              'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom',
-              'width', 'height', 'borderLeftStyle', 'borderTopStyle', 'borderLeftWidth', 'borderTopWidth',
-              'boxSizing', 'whiteSpace', 'wordWrap'];
-
-          properties.forEach(function(property) {
-              try {
-                  wrapper.style[property] = container.css(property);
-              } catch(e) {
-                  // Older IE has issues with "border"
-                  log("html2canvas: Parse: Exception caught in renderFormValue: " + e.message);
-              }
-          });
-          var bounds = container.parseBounds();
-          wrapper.style.position = "fixed";
-          wrapper.style.left = bounds.left + "px";
-          wrapper.style.top = bounds.top + "px";
-          wrapper.textContent = value;
-          document.body.appendChild(wrapper);
-          this.paintText(new TextContainer(wrapper.firstChild, container));
-          document.body.removeChild(wrapper);
-      }
+  inherit(AcroFormComboBox, AcroFormListBox);
+  /**
+   * @class AcroFormEditBox
+   * @extends AcroFormComboBox
+   * @extends AcroFormListBox
+   * @extends AcroFormChoiceField
+   * @extends AcroFormField
+   */
+
+  var AcroFormEditBox = function AcroFormEditBox() {
+    AcroFormComboBox.call(this);
+    this.edit = true;
   };
 
-  NodeParser.prototype.paintText = function(container) {
-      container.applyTextTransform();
-      var characters = punycode.ucs2.decode(container.node.data);
-      var textList = (!this.options.letterRendering || noLetterSpacing(container)) && !hasUnicode(container.node.data) ? getWords(characters) : characters.map(function(character) {
-          return punycode.ucs2.encode([character]);
-      });
+  inherit(AcroFormEditBox, AcroFormComboBox);
+  /**
+   * @class AcroFormButton
+   * @extends AcroFormField
+   */
 
-      var weight = container.parent.fontWeight();
-      var size = container.parent.css('fontSize');
-      var family = container.parent.css('fontFamily');
-      var shadows = container.parent.parseTextShadows();
+  var AcroFormButton = function AcroFormButton() {
+    AcroFormField.call(this);
+    this.FT = "/Btn";
+    /**
+     * (Radio buttons only) If set, exactly one radio button shall be selected at all times; selecting the currently selected button has no effect. If clear, clicking the selected button deselects it, leaving no button selected.
+     *
+     * @name AcroFormButton#noToggleToOff
+     * @type {boolean}
+     */
 
-      this.renderer.font(container.parent.color('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);
-      if (shadows.length) {
-          // TODO: support multiple text shadows
-          this.renderer.fontShadow(shadows[0].color, shadows[0].offsetX, shadows[0].offsetY, shadows[0].blur);
-      } else {
-          this.renderer.clearShadow();
+    Object.defineProperty(this, "noToggleToOff", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 15));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 15);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 15);
+        }
       }
+    });
+    /**
+     * If set, the field is a set of radio buttons; if clear, the field is a checkbox. This flag may be set only if the Pushbutton flag is clear.
+     *
+     * @name AcroFormButton#radio
+     * @type {boolean}
+     */
 
-      this.renderer.clip(container.parent.clip, function() {
-          textList.map(this.parseTextBounds(container), this).forEach(function(bounds, index) {
-              if (bounds && /^\s*$/.test(textList[index]) === false) {
-                  this.renderer.text(textList[index], bounds.left, bounds.bottom);
-                  this.renderTextDecoration(container.parent, bounds, this.fontMetrics.getMetrics(family, size));
-              }
-          }, this);
-      }, this);
-  };
+    Object.defineProperty(this, "radio", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 16));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 16);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 16);
+        }
+      }
+    });
+    /**
+     * If set, the field is a pushbutton that does not retain a permanent value.
+     *
+     * @name AcroFormButton#pushButton
+     * @type {boolean}
+     */
 
-  NodeParser.prototype.renderTextDecoration = function(container, bounds, metrics) {
-      switch(container.css("textDecoration").split(" ")[0]) {
-      case "underline":
-          // Draws a line at the baseline of the font
-          // TODO As some browsers display the line as more than 1px if the font-size is big, need to take that into account both in position and size
-          this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.color("color"));
-          break;
-      case "overline":
-          this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.color("color"));
-          break;
-      case "line-through":
-          // TODO try and find exact position for line-through
-          this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.color("color"));
-          break;
+    Object.defineProperty(this, "pushButton", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 17));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 17);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 17);
+        }
       }
-  };
+    });
+    /**
+     * (PDF 1.5) If set, a group of radio buttons within a radio button field that use the same value for the on state will turn on and off in unison; that is if one is checked, they are all checked. If clear, the buttons are mutually exclusive (the same behavior as HTML radio buttons).
+     *
+     * @name AcroFormButton#radioIsUnison
+     * @type {boolean}
+     */
 
-  var borderColorTransforms = {
-      inset: [
-          ["darken", 0.60],
-          ["darken", 0.10],
-          ["darken", 0.10],
-          ["darken", 0.60]
-      ]
-  };
+    Object.defineProperty(this, "radioIsUnison", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 26));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 26);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 26);
+        }
+      }
+    });
+    var _MK = {};
+    Object.defineProperty(this, "MK", {
+      enumerable: false,
+      configurable: false,
+      get: function get() {
+        var encryptor = function encryptor(data) {
+          return data;
+        };
 
-  NodeParser.prototype.parseBorders = function(container) {
-      var nodeBounds = container.parseBounds();
-      var radius = getBorderRadiusData(container);
-      var borders = ["Top", "Right", "Bottom", "Left"].map(function(side, index) {
-          var style = container.css('border' + side + 'Style');
-          var color = container.color('border' + side + 'Color');
-          if (style === "inset" && color.isBlack()) {
-              color = new Color([255, 255, 255, color.a]); // this is wrong, but
-          }
-          var colorTransform = borderColorTransforms[style] ? borderColorTransforms[style][index] : null;
-          return {
-              width: container.cssInt('border' + side + 'Width'),
-              color: colorTransform ? color[colorTransform[0]](colorTransform[1]) : color,
-              args: null
-          };
-      });
-      var borderPoints = calculateCurvePoints(nodeBounds, radius, borders);
-
-      return {
-          clip: this.parseBackgroundClip(container, borderPoints, borders, radius, nodeBounds),
-          borders: calculateBorders(borders, nodeBounds, borderPoints, radius)
-      };
-  };
+        if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId);
 
-  function calculateBorders(borders, nodeBounds, borderPoints, radius) {
-      return borders.map(function(border, borderSide) {
-          if (border.width > 0) {
-              var bx = nodeBounds.left;
-              var by = nodeBounds.top;
-              var bw = nodeBounds.width;
-              var bh = nodeBounds.height - (borders[2].width);
+        if (Object.keys(_MK).length !== 0) {
+          var result = [];
+          result.push("<<");
+          var key;
 
-              switch(borderSide) {
-              case 0:
-                  // top border
-                  bh = borders[0].width;
-                  border.args = drawSide({
-                          c1: [bx, by],
-                          c2: [bx + bw, by],
-                          c3: [bx + bw - borders[1].width, by + bh],
-                          c4: [bx + borders[3].width, by + bh]
-                      }, radius[0], radius[1],
-                      borderPoints.topLeftOuter, borderPoints.topLeftInner, borderPoints.topRightOuter, borderPoints.topRightInner);
-                  break;
-              case 1:
-                  // right border
-                  bx = nodeBounds.left + nodeBounds.width - (borders[1].width);
-                  bw = borders[1].width;
-
-                  border.args = drawSide({
-                          c1: [bx + bw, by],
-                          c2: [bx + bw, by + bh + borders[2].width],
-                          c3: [bx, by + bh],
-                          c4: [bx, by + borders[0].width]
-                      }, radius[1], radius[2],
-                      borderPoints.topRightOuter, borderPoints.topRightInner, borderPoints.bottomRightOuter, borderPoints.bottomRightInner);
-                  break;
-              case 2:
-                  // bottom border
-                  by = (by + nodeBounds.height) - (borders[2].width);
-                  bh = borders[2].width;
-                  border.args = drawSide({
-                          c1: [bx + bw, by + bh],
-                          c2: [bx, by + bh],
-                          c3: [bx + borders[3].width, by],
-                          c4: [bx + bw - borders[3].width, by]
-                      }, radius[2], radius[3],
-                      borderPoints.bottomRightOuter, borderPoints.bottomRightInner, borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner);
-                  break;
-              case 3:
-                  // left border
-                  bw = borders[3].width;
-                  border.args = drawSide({
-                          c1: [bx, by + bh + borders[2].width],
-                          c2: [bx, by],
-                          c3: [bx + bw, by + borders[0].width],
-                          c4: [bx + bw, by + bh]
-                      }, radius[3], radius[0],
-                      borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner, borderPoints.topLeftOuter, borderPoints.topLeftInner);
-                  break;
-              }
+          for (key in _MK) {
+            result.push("/" + key + " (" + pdfEscape(encryptor(_MK[key])) + ")");
           }
-          return border;
-      });
-  }
 
-  NodeParser.prototype.parseBackgroundClip = function(container, borderPoints, borders, radius, bounds) {
-      var backgroundClip = container.css('backgroundClip'),
-          borderArgs = [];
-
-      switch(backgroundClip) {
-      case "content-box":
-      case "padding-box":
-          parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftInner, borderPoints.topRightInner, bounds.left + borders[3].width, bounds.top + borders[0].width);
-          parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightInner, borderPoints.bottomRightInner, bounds.left + bounds.width - borders[1].width, bounds.top + borders[0].width);
-          parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightInner, borderPoints.bottomLeftInner, bounds.left + bounds.width - borders[1].width, bounds.top + bounds.height - borders[2].width);
-          parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftInner, borderPoints.topLeftInner, bounds.left + borders[3].width, bounds.top + bounds.height - borders[2].width);
-          break;
+          result.push(">>");
+          return result.join("\n");
+        }
 
-      default:
-          parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftOuter, borderPoints.topRightOuter, bounds.left, bounds.top);
-          parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightOuter, borderPoints.bottomRightOuter, bounds.left + bounds.width, bounds.top);
-          parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightOuter, borderPoints.bottomLeftOuter, bounds.left + bounds.width, bounds.top + bounds.height);
-          parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftOuter, borderPoints.topLeftOuter, bounds.left, bounds.top + bounds.height);
-          break;
+        return undefined;
+      },
+      set: function set(value) {
+        if (_typeof(value) === "object") {
+          _MK = value;
+        }
       }
+    });
+    /**
+     * From the PDF reference:
+     * (Optional, button fields only) The widget annotation's normal caption which shall be displayed when it is not interacting with the user.
+     * Unlike the remaining entries listed in this Table which apply only to widget annotations associated with pushbutton fields (see Pushbuttons in 12.7.4.2, "Button Fields"), the CA entry may be used with any type of button field, including check boxes (see Check Boxes in 12.7.4.2, "Button Fields") and radio buttons (Radio Buttons in 12.7.4.2, "Button Fields").
+     *
+     * - '8' = Cross,
+     * - 'l' =  Circle,
+     * - '' = nothing
+     * @name AcroFormButton#caption
+     * @type {string}
+     */
 
-      return borderArgs;
-  };
-
-  function getCurvePoints(x, y, r1, r2) {
-      var kappa = 4 * ((Math.sqrt(2) - 1) / 3);
-      var ox = (r1) * kappa, // control point offset horizontal
-          oy = (r2) * kappa, // control point offset vertical
-          xm = x + r1, // x-middle
-          ym = y + r2; // y-middle
-      return {
-          topLeft: bezierCurve({x: x, y: ym}, {x: x, y: ym - oy}, {x: xm - ox, y: y}, {x: xm, y: y}),
-          topRight: bezierCurve({x: x, y: y}, {x: x + ox,y: y}, {x: xm, y: ym - oy}, {x: xm, y: ym}),
-          bottomRight: bezierCurve({x: xm, y: y}, {x: xm, y: y + oy}, {x: x + ox, y: ym}, {x: x, y: ym}),
-          bottomLeft: bezierCurve({x: xm, y: ym}, {x: xm - ox, y: ym}, {x: x, y: y + oy}, {x: x, y:y})
-      };
-  }
-
-  function calculateCurvePoints(bounds, borderRadius, borders) {
-      var x = bounds.left,
-          y = bounds.top,
-          width = bounds.width,
-          height = bounds.height,
-
-          tlh = borderRadius[0][0] < width / 2 ? borderRadius[0][0] : width / 2,
-          tlv = borderRadius[0][1] < height / 2 ? borderRadius[0][1] : height / 2,
-          trh = borderRadius[1][0] < width / 2 ? borderRadius[1][0] : width / 2,
-          trv = borderRadius[1][1] < height / 2 ? borderRadius[1][1] : height / 2,
-          brh = borderRadius[2][0] < width / 2 ? borderRadius[2][0] : width / 2,
-          brv = borderRadius[2][1] < height / 2 ? borderRadius[2][1] : height / 2,
-          blh = borderRadius[3][0] < width / 2 ? borderRadius[3][0] : width / 2,
-          blv = borderRadius[3][1] < height / 2 ? borderRadius[3][1] : height / 2;
-
-      var topWidth = width - trh,
-          rightHeight = height - brv,
-          bottomWidth = width - brh,
-          leftHeight = height - blv;
-
-      return {
-          topLeftOuter: getCurvePoints(x, y, tlh, tlv).topLeft.subdivide(0.5),
-          topLeftInner: getCurvePoints(x + borders[3].width, y + borders[0].width, Math.max(0, tlh - borders[3].width), Math.max(0, tlv - borders[0].width)).topLeft.subdivide(0.5),
-          topRightOuter: getCurvePoints(x + topWidth, y, trh, trv).topRight.subdivide(0.5),
-          topRightInner: getCurvePoints(x + Math.min(topWidth, width + borders[3].width), y + borders[0].width, (topWidth > width + borders[3].width) ? 0 :trh - borders[3].width, trv - borders[0].width).topRight.subdivide(0.5),
-          bottomRightOuter: getCurvePoints(x + bottomWidth, y + rightHeight, brh, brv).bottomRight.subdivide(0.5),
-          bottomRightInner: getCurvePoints(x + Math.min(bottomWidth, width - borders[3].width), y + Math.min(rightHeight, height + borders[0].width), Math.max(0, brh - borders[1].width),  brv - borders[2].width).bottomRight.subdivide(0.5),
-          bottomLeftOuter: getCurvePoints(x, y + leftHeight, blh, blv).bottomLeft.subdivide(0.5),
-          bottomLeftInner: getCurvePoints(x + borders[3].width, y + leftHeight, Math.max(0, blh - borders[3].width), blv - borders[2].width).bottomLeft.subdivide(0.5)
-      };
-  }
-
-  function bezierCurve(start, startControl, endControl, end) {
-      var lerp = function (a, b, t) {
-          return {
-              x: a.x + (b.x - a.x) * t,
-              y: a.y + (b.y - a.y) * t
-          };
-      };
-
-      return {
-          start: start,
-          startControl: startControl,
-          endControl: endControl,
-          end: end,
-          subdivide: function(t) {
-              var ab = lerp(start, startControl, t),
-                  bc = lerp(startControl, endControl, t),
-                  cd = lerp(endControl, end, t),
-                  abbc = lerp(ab, bc, t),
-                  bccd = lerp(bc, cd, t),
-                  dest = lerp(abbc, bccd, t);
-              return [bezierCurve(start, ab, abbc, dest), bezierCurve(dest, bccd, cd, end)];
-          },
-          curveTo: function(borderArgs) {
-              borderArgs.push(["bezierCurve", startControl.x, startControl.y, endControl.x, endControl.y, end.x, end.y]);
-          },
-          curveToReversed: function(borderArgs) {
-              borderArgs.push(["bezierCurve", endControl.x, endControl.y, startControl.x, startControl.y, start.x, start.y]);
-          }
-      };
-  }
+    Object.defineProperty(this, "caption", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return _MK.CA || "";
+      },
+      set: function set(value) {
+        if (typeof value === "string") {
+          _MK.CA = value;
+        }
+      }
+    });
 
-  function drawSide(borderData, radius1, radius2, outer1, inner1, outer2, inner2) {
-      var borderArgs = [];
+    var _AS;
 
-      if (radius1[0] > 0 || radius1[1] > 0) {
-          borderArgs.push(["line", outer1[1].start.x, outer1[1].start.y]);
-          outer1[1].curveTo(borderArgs);
-      } else {
-          borderArgs.push([ "line", borderData.c1[0], borderData.c1[1]]);
+    Object.defineProperty(this, "AS", {
+      enumerable: false,
+      configurable: false,
+      get: function get() {
+        return _AS;
+      },
+      set: function set(value) {
+        _AS = value;
       }
+    });
+    /**
+     * (Required if the appearance dictionary AP contains one or more subdictionaries; PDF 1.2) The annotation's appearance state, which selects the applicable appearance stream from an appearance subdictionary (see Section 12.5.5, "Appearance Streams")
+     *
+     * @name AcroFormButton#appearanceState
+     * @type {any}
+     */
 
-      if (radius2[0] > 0 || radius2[1] > 0) {
-          borderArgs.push(["line", outer2[0].start.x, outer2[0].start.y]);
-          outer2[0].curveTo(borderArgs);
-          borderArgs.push(["line", inner2[0].end.x, inner2[0].end.y]);
-          inner2[0].curveToReversed(borderArgs);
-      } else {
-          borderArgs.push(["line", borderData.c2[0], borderData.c2[1]]);
-          borderArgs.push(["line", borderData.c3[0], borderData.c3[1]]);
+    Object.defineProperty(this, "appearanceState", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return _AS.substr(1, _AS.length - 1);
+      },
+      set: function set(value) {
+        _AS = "/" + value;
       }
+    });
+  };
 
-      if (radius1[0] > 0 || radius1[1] > 0) {
-          borderArgs.push(["line", inner1[1].end.x, inner1[1].end.y]);
-          inner1[1].curveToReversed(borderArgs);
-      } else {
-          borderArgs.push(["line", borderData.c4[0], borderData.c4[1]]);
-      }
+  inherit(AcroFormButton, AcroFormField);
+  /**
+   * @class AcroFormPushButton
+   * @extends AcroFormButton
+   * @extends AcroFormField
+   */
 
-      return borderArgs;
-  }
+  var AcroFormPushButton = function AcroFormPushButton() {
+    AcroFormButton.call(this);
+    this.pushButton = true;
+  };
 
-  function parseCorner(borderArgs, radius1, radius2, corner1, corner2, x, y) {
-      if (radius1[0] > 0 || radius1[1] > 0) {
-          borderArgs.push(["line", corner1[0].start.x, corner1[0].start.y]);
-          corner1[0].curveTo(borderArgs);
-          corner1[1].curveTo(borderArgs);
-      } else {
-          borderArgs.push(["line", x, y]);
-      }
+  inherit(AcroFormPushButton, AcroFormButton);
+  /**
+   * @class AcroFormRadioButton
+   * @extends AcroFormButton
+   * @extends AcroFormField
+   */
 
-      if (radius2[0] > 0 || radius2[1] > 0) {
-          borderArgs.push(["line", corner2[0].start.x, corner2[0].start.y]);
+  var AcroFormRadioButton = function AcroFormRadioButton() {
+    AcroFormButton.call(this);
+    this.radio = true;
+    this.pushButton = false;
+    var _Kids = [];
+    Object.defineProperty(this, "Kids", {
+      enumerable: true,
+      configurable: false,
+      get: function get() {
+        return _Kids;
+      },
+      set: function set(value) {
+        if (typeof value !== "undefined") {
+          _Kids = value;
+        } else {
+          _Kids = [];
+        }
       }
-  }
+    });
+  };
 
-  function negativeZIndex(container) {
-      return container.cssInt("zIndex") < 0;
-  }
+  inherit(AcroFormRadioButton, AcroFormButton);
+  /**
+   * The Child class of a RadioButton (the radioGroup) -> The single Buttons
+   *
+   * @class AcroFormChildClass
+   * @extends AcroFormField
+   * @ignore
+   */
 
-  function positiveZIndex(container) {
-      return container.cssInt("zIndex") > 0;
-  }
+  var AcroFormChildClass = function AcroFormChildClass() {
+    AcroFormField.call(this);
 
-  function zIndex0(container) {
-      return container.cssInt("zIndex") === 0;
-  }
+    var _parent;
 
-  function inlineLevel(container) {
-      return ["inline", "inline-block", "inline-table"].indexOf(container.css("display")) !== -1;
-  }
+    Object.defineProperty(this, "Parent", {
+      enumerable: false,
+      configurable: false,
+      get: function get() {
+        return _parent;
+      },
+      set: function set(value) {
+        _parent = value;
+      }
+    });
 
-  function isStackingContext(container) {
-      return (container instanceof StackingContext);
-  }
+    var _optionName;
 
-  function hasText(container) {
-      return container.node.data.trim().length > 0;
-  }
+    Object.defineProperty(this, "optionName", {
+      enumerable: false,
+      configurable: true,
+      get: function get() {
+        return _optionName;
+      },
+      set: function set(value) {
+        _optionName = value;
+      }
+    });
+    var _MK = {};
+    Object.defineProperty(this, "MK", {
+      enumerable: false,
+      configurable: false,
+      get: function get() {
+        var encryptor = function encryptor(data) {
+          return data;
+        };
 
-  function noLetterSpacing(container) {
-      return (/^(normal|none|0px)$/.test(container.parent.css("letterSpacing")));
-  }
+        if (this.scope) encryptor = this.scope.internal.getEncryptor(this.objId);
+        var result = [];
+        result.push("<<");
+        var key;
 
-  function getBorderRadiusData(container) {
-      return ["TopLeft", "TopRight", "BottomRight", "BottomLeft"].map(function(side) {
-          var value = container.css('border' + side + 'Radius');
-          var arr = value.split(" ");
-          if (arr.length <= 1) {
-              arr[1] = arr[0];
-          }
-          return arr.map(asInt);
-      });
-  }
+        for (key in _MK) {
+          result.push("/" + key + " (" + pdfEscape(encryptor(_MK[key])) + ")");
+        }
 
-  function renderableNode(node) {
-      return (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.ELEMENT_NODE);
-  }
+        result.push(">>");
+        return result.join("\n");
+      },
+      set: function set(value) {
+        if (_typeof(value) === "object") {
+          _MK = value;
+        }
+      }
+    });
+    /**
+     * From the PDF reference:
+     * (Optional, button fields only) The widget annotation's normal caption which shall be displayed when it is not interacting with the user.
+     * Unlike the remaining entries listed in this Table which apply only to widget annotations associated with pushbutton fields (see Pushbuttons in 12.7.4.2, "Button Fields"), the CA entry may be used with any type of button field, including check boxes (see Check Boxes in 12.7.4.2, "Button Fields") and radio buttons (Radio Buttons in 12.7.4.2, "Button Fields").
+     *
+     * - '8' = Cross,
+     * - 'l' =  Circle,
+     * - '' = nothing
+     * @name AcroFormButton#caption
+     * @type {string}
+     */
 
-  function isPositionedForStacking(container) {
-      var position = container.css("position");
-      var zIndex = (["absolute", "relative", "fixed"].indexOf(position) !== -1) ? container.css("zIndex") : "auto";
-      return zIndex !== "auto";
-  }
+    Object.defineProperty(this, "caption", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return _MK.CA || "";
+      },
+      set: function set(value) {
+        if (typeof value === "string") {
+          _MK.CA = value;
+        }
+      }
+    });
 
-  function isPositioned(container) {
-      return container.css("position") !== "static";
-  }
+    var _AS;
 
-  function isFloating(container) {
-      return container.css("float") !== "none";
-  }
+    Object.defineProperty(this, "AS", {
+      enumerable: false,
+      configurable: false,
+      get: function get() {
+        return _AS;
+      },
+      set: function set(value) {
+        _AS = value;
+      }
+    });
+    /**
+     * (Required if the appearance dictionary AP contains one or more subdictionaries; PDF 1.2) The annotation's appearance state, which selects the applicable appearance stream from an appearance subdictionary (see Section 12.5.5, "Appearance Streams")
+     *
+     * @name AcroFormButton#appearanceState
+     * @type {any}
+     */
 
-  function isInlineBlock(container) {
-      return ["inline-block", "inline-table"].indexOf(container.css("display")) !== -1;
-  }
+    Object.defineProperty(this, "appearanceState", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return _AS.substr(1, _AS.length - 1);
+      },
+      set: function set(value) {
+        _AS = "/" + value;
+      }
+    });
+    this.caption = "l";
+    this.appearanceState = "Off"; // todo: set AppearanceType as variable that can be set from the
+    // outside...
 
-  function not(callback) {
-      var context = this;
-      return function() {
-          return !callback.apply(context, arguments);
-      };
-  }
+    this._AppearanceType = AcroFormAppearance.RadioButton.Circle; // The Default appearanceType is the Circle
 
-  function isElement(container) {
-      return container.node.nodeType === Node.ELEMENT_NODE;
-  }
+    this.appearanceStreamContent = this._AppearanceType.createAppearanceStream(this.optionName);
+  };
 
-  function isPseudoElement(container) {
-      return container.isPseudoElement === true;
-  }
+  inherit(AcroFormChildClass, AcroFormField);
 
-  function isTextNode(container) {
-      return container.node.nodeType === Node.TEXT_NODE;
-  }
+  AcroFormRadioButton.prototype.setAppearance = function (appearance) {
+    if (!("createAppearanceStream" in appearance && "getCA" in appearance)) {
+      throw new Error("Couldn't assign Appearance to RadioButton. Appearance was Invalid!");
+    }
 
-  function zIndexSort(contexts) {
-      return function(a, b) {
-          return (a.cssInt("zIndex") + (contexts.indexOf(a) / contexts.length)) - (b.cssInt("zIndex") + (contexts.indexOf(b) / contexts.length));
-      };
-  }
+    for (var objId in this.Kids) {
+      if (this.Kids.hasOwnProperty(objId)) {
+        var child = this.Kids[objId];
+        child.appearanceStreamContent = appearance.createAppearanceStream(child.optionName);
+        child.caption = appearance.getCA();
+      }
+    }
+  };
 
-  function hasOpacity(container) {
-      return container.getOpacity() < 1;
-  }
+  AcroFormRadioButton.prototype.createOption = function (name) {
+    // Create new Child for RadioGroup
+    var child = new AcroFormChildClass();
+    child.Parent = this;
+    child.optionName = name; // Add to Parent
 
-  function asInt(value) {
-      return parseInt(value, 10);
-  }
+    this.Kids.push(child);
+    addField.call(this.scope, child);
+    return child;
+  };
+  /**
+   * @class AcroFormCheckBox
+   * @extends AcroFormButton
+   * @extends AcroFormField
+   */
 
-  function getWidth(border) {
-      return border.width;
-  }
 
-  function nonIgnoredElement(nodeContainer) {
-      return (nodeContainer.node.nodeType !== Node.ELEMENT_NODE || ["SCRIPT", "HEAD", "TITLE", "OBJECT", "BR", "OPTION"].indexOf(nodeContainer.node.nodeName) === -1);
-  }
+  var AcroFormCheckBox = function AcroFormCheckBox() {
+    AcroFormButton.call(this);
+    this.fontName = "zapfdingbats";
+    this.caption = "3";
+    this.appearanceState = "On";
+    this.value = "On";
+    this.textAlign = "center";
+    this.appearanceStreamContent = AcroFormAppearance.CheckBox.createAppearanceStream();
+  };
 
-  function flatten(arrays) {
-      return [].concat.apply([], arrays);
-  }
+  inherit(AcroFormCheckBox, AcroFormButton);
+  /**
+   * @class AcroFormTextField
+   * @extends AcroFormField
+   */
 
-  function stripQuotes(content) {
-      var first = content.substr(0, 1);
-      return (first === content.substr(content.length - 1) && first.match(/'|"/)) ? content.substr(1, content.length - 2) : content;
-  }
+  var AcroFormTextField = function AcroFormTextField() {
+    AcroFormField.call(this);
+    this.FT = "/Tx";
+    /**
+     * If set, the field may contain multiple lines of text; if clear, the field’s text shall be restricted to a single line.
+     *
+     * @name AcroFormTextField#multiline
+     * @type {boolean}
+     */
 
-  function getWords(characters) {
-      var words = [], i = 0, onWordBoundary = false, word;
-      while(characters.length) {
-          if (isWordBoundary(characters[i]) === onWordBoundary) {
-              word = characters.splice(0, i);
-              if (word.length) {
-                  words.push(punycode.ucs2.encode(word));
-              }
-              onWordBoundary =! onWordBoundary;
-              i = 0;
-          } else {
-              i++;
-          }
+    Object.defineProperty(this, "multiline", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 13));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 13);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 13);
+        }
+      }
+    });
+    /**
+     * (PDF 1.4) If set, the text entered in the field represents the pathname of a file whose contents shall be submitted as the value of the field.
+     *
+     * @name AcroFormTextField#fileSelect
+     * @type {boolean}
+     */
 
-          if (i >= characters.length) {
-              word = characters.splice(0, i);
-              if (word.length) {
-                  words.push(punycode.ucs2.encode(word));
-              }
-          }
+    Object.defineProperty(this, "fileSelect", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 21));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 21);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 21);
+        }
       }
-      return words;
-  }
+    });
+    /**
+     * (PDF 1.4) If set, text entered in the field shall not be spell-checked.
+     *
+     * @name AcroFormTextField#doNotSpellCheck
+     * @type {boolean}
+     */
 
-  function isWordBoundary(characterCode) {
-      return [
-          32, // <space>
-          13, // \r
-          10, // \n
-          9, // \t
-          45 // -
-      ].indexOf(characterCode) !== -1;
-  }
+    Object.defineProperty(this, "doNotSpellCheck", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 23));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 23);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 23);
+        }
+      }
+    });
+    /**
+     * (PDF 1.4) If set, the field shall not scroll (horizontally for single-line fields, vertically for multiple-line fields) to accommodate more text than fits within its annotation rectangle. Once the field is full, no further text shall be accepted for interactive form filling; for noninteractive form filling, the filler should take care not to add more character than will visibly fit in the defined area.
+     *
+     * @name AcroFormTextField#doNotScroll
+     * @type {boolean}
+     */
 
-  function hasUnicode(string) {
-      return (/[^\u0000-\u00ff]/).test(string);
-  }
+    Object.defineProperty(this, "doNotScroll", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 24));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 24);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 24);
+        }
+      }
+    });
+    /**
+     * (PDF 1.5) May be set only if the MaxLen entry is present in the text field dictionary (see Table 229) and if the Multiline, Password, and FileSelect flags are clear. If set, the field shall be automatically divided into as many equally spaced positions, or combs, as the value of MaxLen, and the text is laid out into those combs.
+     *
+     * @name AcroFormTextField#comb
+     * @type {boolean}
+     */
 
-  module.exports = NodeParser;
+    Object.defineProperty(this, "comb", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 25));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 25);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 25);
+        }
+      }
+    });
+    /**
+     * (PDF 1.5) If set, the value of this field shall be a rich text string (see 12.7.3.4, “Rich Text Strings”). If the field has a value, the RV entry of the field dictionary (Table 222) shall specify the rich text string.
+     *
+     * @name AcroFormTextField#richText
+     * @type {boolean}
+     */
 
-  },{"./color":3,"./fontmetrics":7,"./log":13,"./nodecontainer":14,"./pseudoelementcontainer":18,"./stackingcontext":21,"./textcontainer":25,"./utils":26,"punycode":1}],16:[function(_dereq_,module,exports){
-  var XHR = _dereq_('./xhr');
-  var utils = _dereq_('./utils');
-  var log = _dereq_('./log');
-  var createWindowClone = _dereq_('./clone');
-  var decode64 = utils.decode64;
+    Object.defineProperty(this, "richText", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 26));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 26);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 26);
+        }
+      }
+    });
+    var _MaxLen = null;
+    Object.defineProperty(this, "MaxLen", {
+      enumerable: true,
+      configurable: false,
+      get: function get() {
+        return _MaxLen;
+      },
+      set: function set(value) {
+        _MaxLen = value;
+      }
+    });
+    /**
+     * (Optional; inheritable) The maximum length of the field’s text, in characters.
+     *
+     * @name AcroFormTextField#maxLength
+     * @type {number}
+     */
 
-  function Proxy(src, proxyUrl, document) {
-      var supportsCORS = ('withCredentials' in new XMLHttpRequest());
-      if (!proxyUrl) {
-          return Promise.reject("No proxy configured");
+    Object.defineProperty(this, "maxLength", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return _MaxLen;
+      },
+      set: function set(value) {
+        if (Number.isInteger(value)) {
+          _MaxLen = value;
+        }
+      }
+    });
+    Object.defineProperty(this, "hasAppearanceStream", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return this.V || this.DV;
       }
-      var callback = createCallback(supportsCORS);
-      var url = createProxyUrl(proxyUrl, src, callback);
+    });
+  };
 
-      return supportsCORS ? XHR(url) : (jsonp(document, url, callback).then(function(response) {
-          return decode64(response.content);
-      }));
-  }
-  var proxyCount = 0;
-
-  function ProxyURL(src, proxyUrl, document) {
-      var supportsCORSImage = ('crossOrigin' in new Image());
-      var callback = createCallback(supportsCORSImage);
-      var url = createProxyUrl(proxyUrl, src, callback);
-      return (supportsCORSImage ? Promise.resolve(url) : jsonp(document, url, callback).then(function(response) {
-          return "data:" + response.type + ";base64," + response.content;
-      }));
-  }
+  inherit(AcroFormTextField, AcroFormField);
+  /**
+   * @class AcroFormPasswordField
+   * @extends AcroFormTextField
+   * @extends AcroFormField
+   */
 
-  function jsonp(document, url, callback) {
-      return new Promise(function(resolve, reject) {
-          var s = document.createElement("script");
-          var cleanup = function() {
-              delete window.html2canvas.proxy[callback];
-              document.body.removeChild(s);
-          };
-          window.html2canvas.proxy[callback] = function(response) {
-              cleanup();
-              resolve(response);
-          };
-          s.src = url;
-          s.onerror = function(e) {
-              cleanup();
-              reject(e);
-          };
-          document.body.appendChild(s);
-      });
-  }
+  var AcroFormPasswordField = function AcroFormPasswordField() {
+    AcroFormTextField.call(this);
+    /**
+     * If set, the field is intended for entering a secure password that should not be echoed visibly to the screen. Characters typed from the keyboard shall instead be echoed in some unreadable form, such as asterisks or bullet characters.
+     * NOTE To protect password confidentiality, readers should never store the value of the text field in the PDF file if this flag is set.
+     *
+     * @name AcroFormTextField#password
+     * @type {boolean}
+     */
 
-  function createCallback(useCORS) {
-      return !useCORS ? "html2canvas_" + Date.now() + "_" + (++proxyCount) + "_" + Math.round(Math.random() * 100000) : "";
-  }
+    Object.defineProperty(this, "password", {
+      enumerable: true,
+      configurable: true,
+      get: function get() {
+        return Boolean(getBitForPdf(this.Ff, 14));
+      },
+      set: function set(value) {
+        if (Boolean(value) === true) {
+          this.Ff = setBitForPdf(this.Ff, 14);
+        } else {
+          this.Ff = clearBitForPdf(this.Ff, 14);
+        }
+      }
+    });
+    this.password = true;
+  };
 
-  function createProxyUrl(proxyUrl, src, callback) {
-      return proxyUrl + "?url=" + encodeURIComponent(src) + (callback.length ? "&callback=html2canvas.proxy." + callback : "");
-  }
+  inherit(AcroFormPasswordField, AcroFormTextField); // Contains Methods for creating standard appearances
 
-  function documentFromHTML(src) {
-      return function(html) {
-          var parser = new DOMParser(), doc;
-          try {
-              doc = parser.parseFromString(html, "text/html");
-          } catch(e) {
-              log("DOMParser not supported, falling back to createHTMLDocument");
-              doc = document.implementation.createHTMLDocument("");
-              try {
-                  doc.open();
-                  doc.write(html);
-                  doc.close();
-              } catch(ee) {
-                  log("createHTMLDocument write not supported, falling back to document.body.innerHTML");
-                  doc.body.innerHTML = html; // ie9 doesnt support writing to documentElement
-              }
+  var AcroFormAppearance = {
+    CheckBox: {
+      createAppearanceStream: function createAppearanceStream() {
+        var appearance = {
+          N: {
+            On: AcroFormAppearance.CheckBox.YesNormal
+          },
+          D: {
+            On: AcroFormAppearance.CheckBox.YesPushDown,
+            Off: AcroFormAppearance.CheckBox.OffPushDown
           }
+        };
+        return appearance;
+      },
 
-          var b = doc.querySelector("base");
-          if (!b || !b.href.host) {
-              var base = doc.createElement("base");
-              base.href = src;
-              doc.head.insertBefore(base, doc.head.firstChild);
-          }
+      /**
+       * Returns the standard On Appearance for a CheckBox
+       *
+       * @returns {AcroFormXObject}
+       */
+      YesPushDown: function YesPushDown(formObject) {
+        var xobj = createFormXObject(formObject);
+        xobj.scope = formObject.scope;
+        var stream = [];
+        var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id;
+
+        var encodedColor = formObject.scope.__private__.encodeColorString(formObject.color);
+
+        var calcRes = calculateX(formObject, formObject.caption);
+        stream.push("0.749023 g");
+        stream.push("0 0 " + f2(AcroFormAppearance.internal.getWidth(formObject)) + " " + f2(AcroFormAppearance.internal.getHeight(formObject)) + " re");
+        stream.push("f");
+        stream.push("BMC");
+        stream.push("q");
+        stream.push("0 0 1 rg");
+        stream.push("/" + fontKey + " " + f2(calcRes.fontSize) + " Tf " + encodedColor);
+        stream.push("BT");
+        stream.push(calcRes.text);
+        stream.push("ET");
+        stream.push("Q");
+        stream.push("EMC");
+        xobj.stream = stream.join("\n");
+        return xobj;
+      },
+      YesNormal: function YesNormal(formObject) {
+        var xobj = createFormXObject(formObject);
+        xobj.scope = formObject.scope;
+        var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id;
 
-          return doc;
-      };
-  }
+        var encodedColor = formObject.scope.__private__.encodeColorString(formObject.color);
 
-  function loadUrlDocument(src, proxy, document, width, height, options) {
-      return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) {
-          return createWindowClone(doc, document, width, height, options, 0, 0);
-      });
-  }
+        var stream = [];
+        var height = AcroFormAppearance.internal.getHeight(formObject);
+        var width = AcroFormAppearance.internal.getWidth(formObject);
+        var calcRes = calculateX(formObject, formObject.caption);
+        stream.push("1 g");
+        stream.push("0 0 " + f2(width) + " " + f2(height) + " re");
+        stream.push("f");
+        stream.push("q");
+        stream.push("0 0 1 rg");
+        stream.push("0 0 " + f2(width - 1) + " " + f2(height - 1) + " re");
+        stream.push("W");
+        stream.push("n");
+        stream.push("0 g");
+        stream.push("BT");
+        stream.push("/" + fontKey + " " + f2(calcRes.fontSize) + " Tf " + encodedColor);
+        stream.push(calcRes.text);
+        stream.push("ET");
+        stream.push("Q");
+        xobj.stream = stream.join("\n");
+        return xobj;
+      },
 
-  exports.Proxy = Proxy;
-  exports.ProxyURL = ProxyURL;
-  exports.loadUrlDocument = loadUrlDocument;
-
-  },{"./clone":2,"./log":13,"./utils":26,"./xhr":28}],17:[function(_dereq_,module,exports){
-  var ProxyURL = _dereq_('./proxy').ProxyURL;
+      /**
+       * Returns the standard Off Appearance for a CheckBox
+       *
+       * @returns {AcroFormXObject}
+       */
+      OffPushDown: function OffPushDown(formObject) {
+        var xobj = createFormXObject(formObject);
+        xobj.scope = formObject.scope;
+        var stream = [];
+        stream.push("0.749023 g");
+        stream.push("0 0 " + f2(AcroFormAppearance.internal.getWidth(formObject)) + " " + f2(AcroFormAppearance.internal.getHeight(formObject)) + " re");
+        stream.push("f");
+        xobj.stream = stream.join("\n");
+        return xobj;
+      }
+    },
+    RadioButton: {
+      Circle: {
+        createAppearanceStream: function createAppearanceStream(name) {
+          var appearanceStreamContent = {
+            D: {
+              Off: AcroFormAppearance.RadioButton.Circle.OffPushDown
+            },
+            N: {}
+          };
+          appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Circle.YesNormal;
+          appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Circle.YesPushDown;
+          return appearanceStreamContent;
+        },
+        getCA: function getCA() {
+          return "l";
+        },
+        YesNormal: function YesNormal(formObject) {
+          var xobj = createFormXObject(formObject);
+          xobj.scope = formObject.scope;
+          var stream = []; // Make the Radius of the Circle relative to min(height, width) of formObject
 
-  function ProxyImageContainer(src, proxy) {
-      var link = document.createElement("a");
-      link.href = src;
-      src = link.href;
-      this.src = src;
-      this.image = new Image();
-      var self = this;
-      this.promise = new Promise(function(resolve, reject) {
-          self.image.crossOrigin = "Anonymous";
-          self.image.onload = resolve;
-          self.image.onerror = reject;
-
-          new ProxyURL(src, proxy, document).then(function(url) {
-              self.image.src = url;
-          })['catch'](reject);
-      });
-  }
+          var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4; // The Borderpadding...
 
-  module.exports = ProxyImageContainer;
+          DotRadius = Number((DotRadius * 0.9).toFixed(5));
+          var c = AcroFormAppearance.internal.Bezier_C;
+          var DotRadiusBezier = Number((DotRadius * c).toFixed(5));
+          /*
+           * The Following is a Circle created with Bezier-Curves.
+           */
 
-  },{"./proxy":16}],18:[function(_dereq_,module,exports){
-  var NodeContainer = _dereq_('./nodecontainer');
+          stream.push("q");
+          stream.push("1 0 0 1 " + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + " " + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + " cm");
+          stream.push(DotRadius + " 0 m");
+          stream.push(DotRadius + " " + DotRadiusBezier + " " + DotRadiusBezier + " " + DotRadius + " 0 " + DotRadius + " c");
+          stream.push("-" + DotRadiusBezier + " " + DotRadius + " -" + DotRadius + " " + DotRadiusBezier + " -" + DotRadius + " 0 c");
+          stream.push("-" + DotRadius + " -" + DotRadiusBezier + " -" + DotRadiusBezier + " -" + DotRadius + " 0 -" + DotRadius + " c");
+          stream.push(DotRadiusBezier + " -" + DotRadius + " " + DotRadius + " -" + DotRadiusBezier + " " + DotRadius + " 0 c");
+          stream.push("f");
+          stream.push("Q");
+          xobj.stream = stream.join("\n");
+          return xobj;
+        },
+        YesPushDown: function YesPushDown(formObject) {
+          var xobj = createFormXObject(formObject);
+          xobj.scope = formObject.scope;
+          var stream = [];
+          var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4; // The Borderpadding...
 
-  function PseudoElementContainer(node, parent, type) {
-      NodeContainer.call(this, node, parent);
-      this.isPseudoElement = true;
-      this.before = type === ":before";
-  }
+          DotRadius = Number((DotRadius * 0.9).toFixed(5)); // Save results for later use; no need to waste
+          // processor ticks on doing math
 
-  PseudoElementContainer.prototype.cloneTo = function(stack) {
-      PseudoElementContainer.prototype.cloneTo.call(this, stack);
-      stack.isPseudoElement = true;
-      stack.before = this.before;
-  };
+          var k = Number((DotRadius * 2).toFixed(5));
+          var kc = Number((k * AcroFormAppearance.internal.Bezier_C).toFixed(5));
+          var dc = Number((DotRadius * AcroFormAppearance.internal.Bezier_C).toFixed(5));
+          stream.push("0.749023 g");
+          stream.push("q");
+          stream.push("1 0 0 1 " + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + " " + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + " cm");
+          stream.push(k + " 0 m");
+          stream.push(k + " " + kc + " " + kc + " " + k + " 0 " + k + " c");
+          stream.push("-" + kc + " " + k + " -" + k + " " + kc + " -" + k + " 0 c");
+          stream.push("-" + k + " -" + kc + " -" + kc + " -" + k + " 0 -" + k + " c");
+          stream.push(kc + " -" + k + " " + k + " -" + kc + " " + k + " 0 c");
+          stream.push("f");
+          stream.push("Q");
+          stream.push("0 g");
+          stream.push("q");
+          stream.push("1 0 0 1 " + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + " " + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + " cm");
+          stream.push(DotRadius + " 0 m");
+          stream.push("" + DotRadius + " " + dc + " " + dc + " " + DotRadius + " 0 " + DotRadius + " c");
+          stream.push("-" + dc + " " + DotRadius + " -" + DotRadius + " " + dc + " -" + DotRadius + " 0 c");
+          stream.push("-" + DotRadius + " -" + dc + " -" + dc + " -" + DotRadius + " 0 -" + DotRadius + " c");
+          stream.push(dc + " -" + DotRadius + " " + DotRadius + " -" + dc + " " + DotRadius + " 0 c");
+          stream.push("f");
+          stream.push("Q");
+          xobj.stream = stream.join("\n");
+          return xobj;
+        },
+        OffPushDown: function OffPushDown(formObject) {
+          var xobj = createFormXObject(formObject);
+          xobj.scope = formObject.scope;
+          var stream = [];
+          var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4; // The Borderpadding...
 
-  PseudoElementContainer.prototype = Object.create(NodeContainer.prototype);
+          DotRadius = Number((DotRadius * 0.9).toFixed(5)); // Save results for later use; no need to waste
+          // processor ticks on doing math
 
-  PseudoElementContainer.prototype.appendToDOM = function() {
-      if (this.before) {
-          this.parent.node.insertBefore(this.node, this.parent.node.firstChild);
-      } else {
-          this.parent.node.appendChild(this.node);
+          var k = Number((DotRadius * 2).toFixed(5));
+          var kc = Number((k * AcroFormAppearance.internal.Bezier_C).toFixed(5));
+          stream.push("0.749023 g");
+          stream.push("q");
+          stream.push("1 0 0 1 " + f5(AcroFormAppearance.internal.getWidth(formObject) / 2) + " " + f5(AcroFormAppearance.internal.getHeight(formObject) / 2) + " cm");
+          stream.push(k + " 0 m");
+          stream.push(k + " " + kc + " " + kc + " " + k + " 0 " + k + " c");
+          stream.push("-" + kc + " " + k + " -" + k + " " + kc + " -" + k + " 0 c");
+          stream.push("-" + k + " -" + kc + " -" + kc + " -" + k + " 0 -" + k + " c");
+          stream.push(kc + " -" + k + " " + k + " -" + kc + " " + k + " 0 c");
+          stream.push("f");
+          stream.push("Q");
+          xobj.stream = stream.join("\n");
+          return xobj;
+        }
+      },
+      Cross: {
+        /**
+         * Creates the Actual AppearanceDictionary-References
+         *
+         * @param {string} name
+         * @returns {Object}
+         * @ignore
+         */
+        createAppearanceStream: function createAppearanceStream(name) {
+          var appearanceStreamContent = {
+            D: {
+              Off: AcroFormAppearance.RadioButton.Cross.OffPushDown
+            },
+            N: {}
+          };
+          appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Cross.YesNormal;
+          appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Cross.YesPushDown;
+          return appearanceStreamContent;
+        },
+        getCA: function getCA() {
+          return "8";
+        },
+        YesNormal: function YesNormal(formObject) {
+          var xobj = createFormXObject(formObject);
+          xobj.scope = formObject.scope;
+          var stream = [];
+          var cross = AcroFormAppearance.internal.calculateCross(formObject);
+          stream.push("q");
+          stream.push("1 1 " + f2(AcroFormAppearance.internal.getWidth(formObject) - 2) + " " + f2(AcroFormAppearance.internal.getHeight(formObject) - 2) + " re");
+          stream.push("W");
+          stream.push("n");
+          stream.push(f2(cross.x1.x) + " " + f2(cross.x1.y) + " m");
+          stream.push(f2(cross.x2.x) + " " + f2(cross.x2.y) + " l");
+          stream.push(f2(cross.x4.x) + " " + f2(cross.x4.y) + " m");
+          stream.push(f2(cross.x3.x) + " " + f2(cross.x3.y) + " l");
+          stream.push("s");
+          stream.push("Q");
+          xobj.stream = stream.join("\n");
+          return xobj;
+        },
+        YesPushDown: function YesPushDown(formObject) {
+          var xobj = createFormXObject(formObject);
+          xobj.scope = formObject.scope;
+          var cross = AcroFormAppearance.internal.calculateCross(formObject);
+          var stream = [];
+          stream.push("0.749023 g");
+          stream.push("0 0 " + f2(AcroFormAppearance.internal.getWidth(formObject)) + " " + f2(AcroFormAppearance.internal.getHeight(formObject)) + " re");
+          stream.push("f");
+          stream.push("q");
+          stream.push("1 1 " + f2(AcroFormAppearance.internal.getWidth(formObject) - 2) + " " + f2(AcroFormAppearance.internal.getHeight(formObject) - 2) + " re");
+          stream.push("W");
+          stream.push("n");
+          stream.push(f2(cross.x1.x) + " " + f2(cross.x1.y) + " m");
+          stream.push(f2(cross.x2.x) + " " + f2(cross.x2.y) + " l");
+          stream.push(f2(cross.x4.x) + " " + f2(cross.x4.y) + " m");
+          stream.push(f2(cross.x3.x) + " " + f2(cross.x3.y) + " l");
+          stream.push("s");
+          stream.push("Q");
+          xobj.stream = stream.join("\n");
+          return xobj;
+        },
+        OffPushDown: function OffPushDown(formObject) {
+          var xobj = createFormXObject(formObject);
+          xobj.scope = formObject.scope;
+          var stream = [];
+          stream.push("0.749023 g");
+          stream.push("0 0 " + f2(AcroFormAppearance.internal.getWidth(formObject)) + " " + f2(AcroFormAppearance.internal.getHeight(formObject)) + " re");
+          stream.push("f");
+          xobj.stream = stream.join("\n");
+          return xobj;
+        }
       }
-      this.parent.node.className += " " + this.getHideClass();
-  };
+    },
 
-  PseudoElementContainer.prototype.cleanDOM = function() {
-      this.node.parentNode.removeChild(this.node);
-      this.parent.node.className = this.parent.node.className.replace(this.getHideClass(), "");
-  };
+    /**
+     * Returns the standard Appearance
+     *
+     * @returns {AcroFormXObject}
+     */
+    createDefaultAppearanceStream: function createDefaultAppearanceStream(formObject) {
+      // Set Helvetica to Standard Font (size: auto)
+      // Color: Black
+      var fontKey = formObject.scope.internal.getFont(formObject.fontName, formObject.fontStyle).id;
 
-  PseudoElementContainer.prototype.getHideClass = function() {
-      return this["PSEUDO_HIDE_ELEMENT_CLASS_" + (this.before ? "BEFORE" : "AFTER")];
-  };
+      var encodedColor = formObject.scope.__private__.encodeColorString(formObject.color);
 
-  PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE = "___html2canvas___pseudoelement_before";
-  PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER = "___html2canvas___pseudoelement_after";
+      var fontSize = formObject.fontSize;
+      var result = "/" + fontKey + " " + fontSize + " Tf " + encodedColor;
+      return result;
+    }
+  };
+  AcroFormAppearance.internal = {
+    Bezier_C: 0.551915024494,
+    calculateCross: function calculateCross(formObject) {
+      var width = AcroFormAppearance.internal.getWidth(formObject);
+      var height = AcroFormAppearance.internal.getHeight(formObject);
+      var a = Math.min(width, height);
+      var cross = {
+        x1: {
+          // upperLeft
+          x: (width - a) / 2,
+          y: (height - a) / 2 + a // height - borderPadding
 
-  module.exports = PseudoElementContainer;
+        },
+        x2: {
+          // lowerRight
+          x: (width - a) / 2 + a,
+          y: (height - a) / 2 // borderPadding
 
-  },{"./nodecontainer":14}],19:[function(_dereq_,module,exports){
-  var log = _dereq_('./log');
+        },
+        x3: {
+          // lowerLeft
+          x: (width - a) / 2,
+          y: (height - a) / 2 // borderPadding
 
-  function Renderer(width, height, images, options, document) {
-      this.width = width;
-      this.height = height;
-      this.images = images;
-      this.options = options;
-      this.document = document;
-  }
+        },
+        x4: {
+          // upperRight
+          x: (width - a) / 2 + a,
+          y: (height - a) / 2 + a // height - borderPadding
 
-  Renderer.prototype.renderImage = function(container, bounds, borderData, imageContainer) {
-      var paddingLeft = container.cssInt('paddingLeft'),
-          paddingTop = container.cssInt('paddingTop'),
-          paddingRight = container.cssInt('paddingRight'),
-          paddingBottom = container.cssInt('paddingBottom'),
-          borders = borderData.borders;
-
-      var width = bounds.width - (borders[1].width + borders[3].width + paddingLeft + paddingRight);
-      var height = bounds.height - (borders[0].width + borders[2].width + paddingTop + paddingBottom);
-      this.drawImage(
-          imageContainer,
-          0,
-          0,
-          imageContainer.image.width || width,
-          imageContainer.image.height || height,
-          bounds.left + paddingLeft + borders[3].width,
-          bounds.top + paddingTop + borders[0].width,
-          width,
-          height
-      );
+        }
+      };
+      return cross;
+    }
   };
 
-  Renderer.prototype.renderBackground = function(container, bounds, borderData) {
-      if (bounds.height > 0 && bounds.width > 0) {
-          this.renderBackgroundColor(container, bounds);
-          this.renderBackgroundImage(container, bounds, borderData);
-      }
-  };
+  AcroFormAppearance.internal.getWidth = function (formObject) {
+    var result = 0;
 
-  Renderer.prototype.renderBackgroundColor = function(container, bounds) {
-      var color = container.color("backgroundColor");
-      if (!color.isTransparent()) {
-          this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, color);
-      }
-  };
+    if (_typeof(formObject) === "object") {
+      result = scale(formObject.Rect[2]);
+    }
 
-  Renderer.prototype.renderBorders = function(borders) {
-      borders.forEach(this.renderBorder, this);
+    return result;
   };
 
-  Renderer.prototype.renderBorder = function(data) {
-      if (!data.color.isTransparent() && data.args !== null) {
-          this.drawShape(data.args, data.color);
-      }
-  };
+  AcroFormAppearance.internal.getHeight = function (formObject) {
+    var result = 0;
 
-  Renderer.prototype.renderBackgroundImage = function(container, bounds, borderData) {
-      var backgroundImages = container.parseBackgroundImages();
-      backgroundImages.reverse().forEach(function(backgroundImage, index, arr) {
-          switch(backgroundImage.method) {
-          case "url":
-              var image = this.images.get(backgroundImage.args[0]);
-              if (image) {
-                  this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);
-              } else {
-                  log("Error loading background-image", backgroundImage.args[0]);
-              }
-              break;
-          case "linear-gradient":
-          case "gradient":
-              var gradientImage = this.images.get(backgroundImage.value);
-              if (gradientImage) {
-                  this.renderBackgroundGradient(gradientImage, bounds, borderData);
-              } else {
-                  log("Error loading background-image", backgroundImage.args[0]);
-              }
-              break;
-          case "none":
-              break;
-          default:
-              log("Unknown background-image type", backgroundImage.args[0]);
-          }
-      }, this);
-  };
+    if (_typeof(formObject) === "object") {
+      result = scale(formObject.Rect[3]);
+    }
 
-  Renderer.prototype.renderBackgroundRepeating = function(container, bounds, imageContainer, index, borderData) {
-      var size = container.parseBackgroundSize(bounds, imageContainer.image, index);
-      var position = container.parseBackgroundPosition(bounds, imageContainer.image, index, size);
-      var repeat = container.parseBackgroundRepeat(index);
-      switch (repeat) {
-      case "repeat-x":
-      case "repeat no-repeat":
-          this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + borderData[3], bounds.top + position.top + borderData[0], 99999, size.height, borderData);
-          break;
-      case "repeat-y":
-      case "no-repeat repeat":
-          this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + borderData[0], size.width, 99999, borderData);
-          break;
-      case "no-repeat":
-          this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + position.top + borderData[0], size.width, size.height, borderData);
-          break;
-      default:
-          this.renderBackgroundRepeat(imageContainer, position, size, {top: bounds.top, left: bounds.left}, borderData[3], borderData[0]);
-          break;
-      }
-  };
+    return result;
+  }; // Public:
 
-  module.exports = Renderer;
-
-  },{"./log":13}],20:[function(_dereq_,module,exports){
-  var Renderer = _dereq_('../renderer');
-  var LinearGradientContainer = _dereq_('../lineargradientcontainer');
-  var log = _dereq_('../log');
-
-  function CanvasRenderer(width, height) {
-      Renderer.apply(this, arguments);
-      this.canvas = this.options.canvas || this.document.createElement("canvas");
-      if (!this.options.canvas) {
-          this.canvas.width = width;
-          this.canvas.height = height;
-      }
-      this.ctx = this.canvas.getContext("2d");
-      this.taintCtx = this.document.createElement("canvas").getContext("2d");
-      this.ctx.textBaseline = "bottom";
-      this.variables = {};
-      log("Initialized CanvasRenderer with size", width, "x", height);
-  }
+  /**
+   * Add an AcroForm-Field to the jsPDF-instance
+   *
+   * @name addField
+   * @function
+   * @instance
+   * @param {Object} fieldObject
+   * @returns {jsPDF}
+   */
 
-  CanvasRenderer.prototype = Object.create(Renderer.prototype);
 
-  CanvasRenderer.prototype.setFillStyle = function(fillStyle) {
-      this.ctx.fillStyle = typeof(fillStyle) === "object" && !!fillStyle.isColor ? fillStyle.toString() : fillStyle;
-      return this.ctx;
-  };
+  var addField = jsPDFAPI.addField = function (fieldObject) {
+    initializeAcroForm(this, fieldObject);
 
-  CanvasRenderer.prototype.rectangle = function(left, top, width, height, color) {
-      this.setFillStyle(color).fillRect(left, top, width, height);
-  };
+    if (fieldObject instanceof AcroFormField) {
+      putForm(fieldObject);
+    } else {
+      throw new Error("Invalid argument passed to jsPDF.addField.");
+    }
 
-  CanvasRenderer.prototype.circle = function(left, top, size, color) {
-      this.setFillStyle(color);
-      this.ctx.beginPath();
-      this.ctx.arc(left + size / 2, top + size / 2, size / 2, 0, Math.PI*2, true);
-      this.ctx.closePath();
-      this.ctx.fill();
+    fieldObject.page = fieldObject.scope.internal.getCurrentPageInfo().pageNumber;
+    return this;
   };
 
-  CanvasRenderer.prototype.circleStroke = function(left, top, size, color, stroke, strokeColor) {
-      this.circle(left, top, size, color);
-      this.ctx.strokeStyle = strokeColor.toString();
-      this.ctx.stroke();
+  jsPDFAPI.AcroFormChoiceField = AcroFormChoiceField;
+  jsPDFAPI.AcroFormListBox = AcroFormListBox;
+  jsPDFAPI.AcroFormComboBox = AcroFormComboBox;
+  jsPDFAPI.AcroFormEditBox = AcroFormEditBox;
+  jsPDFAPI.AcroFormButton = AcroFormButton;
+  jsPDFAPI.AcroFormPushButton = AcroFormPushButton;
+  jsPDFAPI.AcroFormRadioButton = AcroFormRadioButton;
+  jsPDFAPI.AcroFormCheckBox = AcroFormCheckBox;
+  jsPDFAPI.AcroFormTextField = AcroFormTextField;
+  jsPDFAPI.AcroFormPasswordField = AcroFormPasswordField;
+  jsPDFAPI.AcroFormAppearance = AcroFormAppearance;
+  jsPDFAPI.AcroForm = {
+    ChoiceField: AcroFormChoiceField,
+    ListBox: AcroFormListBox,
+    ComboBox: AcroFormComboBox,
+    EditBox: AcroFormEditBox,
+    Button: AcroFormButton,
+    PushButton: AcroFormPushButton,
+    RadioButton: AcroFormRadioButton,
+    CheckBox: AcroFormCheckBox,
+    TextField: AcroFormTextField,
+    PasswordField: AcroFormPasswordField,
+    Appearance: AcroFormAppearance
   };
-
-  CanvasRenderer.prototype.drawShape = function(shape, color) {
-      this.shape(shape);
-      this.setFillStyle(color).fill();
+  jsPDF.AcroForm = {
+    ChoiceField: AcroFormChoiceField,
+    ListBox: AcroFormListBox,
+    ComboBox: AcroFormComboBox,
+    EditBox: AcroFormEditBox,
+    Button: AcroFormButton,
+    PushButton: AcroFormPushButton,
+    RadioButton: AcroFormRadioButton,
+    CheckBox: AcroFormCheckBox,
+    TextField: AcroFormTextField,
+    PasswordField: AcroFormPasswordField,
+    Appearance: AcroFormAppearance
   };
+  var AcroForm = jsPDF.AcroForm;
 
-  CanvasRenderer.prototype.taints = function(imageContainer) {
-      if (imageContainer.tainted === null) {
-          this.taintCtx.drawImage(imageContainer.image, 0, 0);
-          try {
-              this.taintCtx.getImageData(0, 0, 1, 1);
-              imageContainer.tainted = false;
-          } catch(e) {
-              this.taintCtx = document.createElement("canvas").getContext("2d");
-              imageContainer.tainted = true;
-          }
-      }
+  (function (jsPDFAPI) {
 
-      return imageContainer.tainted;
-  };
+    var namespace = "addImage_";
+    jsPDFAPI.__addimage__ = {};
+    var UNKNOWN = "UNKNOWN"; // Heuristic selection of a good batch for large array .apply. Not limiting make the call overflow.
+    // With too small batch iteration will be slow as more calls are made,
+    // higher values cause larger and slower garbage collection.
+
+    var ARRAY_APPLY_BATCH = 8192;
+    var imageFileTypeHeaders = {
+      PNG: [[0x89, 0x50, 0x4e, 0x47]],
+      TIFF: [[0x4d, 0x4d, 0x00, 0x2a], //Motorola
+      [0x49, 0x49, 0x2a, 0x00] //Intel
+      ],
+      JPEG: [[0xff, 0xd8, 0xff, 0xe0, undefined, undefined, 0x4a, 0x46, 0x49, 0x46, 0x00], //JFIF
+      [0xff, 0xd8, 0xff, 0xe1, undefined, undefined, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00], //Exif
+      [0xff, 0xd8, 0xff, 0xdb], //JPEG RAW
+      [0xff, 0xd8, 0xff, 0xee] //EXIF RAW
+      ],
+      JPEG2000: [[0x00, 0x00, 0x00, 0x0c, 0x6a, 0x50, 0x20, 0x20]],
+      GIF87a: [[0x47, 0x49, 0x46, 0x38, 0x37, 0x61]],
+      GIF89a: [[0x47, 0x49, 0x46, 0x38, 0x39, 0x61]],
+      WEBP: [[0x52, 0x49, 0x46, 0x46, undefined, undefined, undefined, undefined, 0x57, 0x45, 0x42, 0x50]],
+      BMP: [[0x42, 0x4d], //BM - Windows 3.1x, 95, NT, ... etc.
+      [0x42, 0x41], //BA - OS/2 struct bitmap array
+      [0x43, 0x49], //CI - OS/2 struct color icon
+      [0x43, 0x50], //CP - OS/2 const color pointer
+      [0x49, 0x43], //IC - OS/2 struct icon
+      [0x50, 0x54] //PT - OS/2 pointer
+      ]
+    };
+    /**
+     * Recognize filetype of Image by magic-bytes
+     *
+     * https://en.wikipedia.org/wiki/List_of_file_signatures
+     *
+     * @name getImageFileTypeByImageData
+     * @public
+     * @function
+     * @param {string|arraybuffer} imageData imageData as binary String or arraybuffer
+     * @param {string} format format of file if filetype-recognition fails, e.g. 'JPEG'
+     *
+     * @returns {string} filetype of Image
+     */
 
-  CanvasRenderer.prototype.drawImage = function(imageContainer, sx, sy, sw, sh, dx, dy, dw, dh) {
-      if (!this.taints(imageContainer) || this.options.allowTaint) {
-          this.ctx.drawImage(imageContainer.image, sx, sy, sw, sh, dx, dy, dw, dh);
+    var getImageFileTypeByImageData = jsPDFAPI.__addimage__.getImageFileTypeByImageData = function (imageData, fallbackFormat) {
+      fallbackFormat = fallbackFormat || UNKNOWN;
+      var i;
+      var j;
+      var result = UNKNOWN;
+      var headerSchemata;
+      var compareResult;
+      var fileType;
+
+      if (fallbackFormat === "RGBA" || imageData.data !== undefined && imageData.data instanceof Uint8ClampedArray && "height" in imageData && "width" in imageData) {
+        return "RGBA";
       }
-  };
 
-  CanvasRenderer.prototype.clip = function(shapes, callback, context) {
-      this.ctx.save();
-      shapes.filter(hasEntries).forEach(function(shape) {
-          this.shape(shape).clip();
-      }, this);
-      callback.call(context);
-      this.ctx.restore();
-  };
+      if (isArrayBufferView(imageData)) {
+        for (fileType in imageFileTypeHeaders) {
+          headerSchemata = imageFileTypeHeaders[fileType];
 
-  CanvasRenderer.prototype.shape = function(shape) {
-      this.ctx.beginPath();
-      shape.forEach(function(point, index) {
-          if (point[0] === "rect") {
-              this.ctx.rect.apply(this.ctx, point.slice(1));
-          } else {
-              this.ctx[(index === 0) ? "moveTo" : point[0] + "To" ].apply(this.ctx, point.slice(1));
-          }
-      }, this);
-      this.ctx.closePath();
-      return this.ctx;
-  };
+          for (i = 0; i < headerSchemata.length; i += 1) {
+            compareResult = true;
 
-  CanvasRenderer.prototype.font = function(color, style, variant, weight, size, family) {
-      this.setFillStyle(color).font = [style, variant, weight, size, family].join(" ").split(",")[0];
-  };
+            for (j = 0; j < headerSchemata[i].length; j += 1) {
+              if (headerSchemata[i][j] === undefined) {
+                continue;
+              }
 
-  CanvasRenderer.prototype.fontShadow = function(color, offsetX, offsetY, blur) {
-      this.setVariable("shadowColor", color.toString())
-          .setVariable("shadowOffsetY", offsetX)
-          .setVariable("shadowOffsetX", offsetY)
-          .setVariable("shadowBlur", blur);
-  };
+              if (headerSchemata[i][j] !== imageData[j]) {
+                compareResult = false;
+                break;
+              }
+            }
 
-  CanvasRenderer.prototype.clearShadow = function() {
-      this.setVariable("shadowColor", "rgba(0,0,0,0)");
-  };
+            if (compareResult === true) {
+              result = fileType;
+              break;
+            }
+          }
+        }
+      } else {
+        for (fileType in imageFileTypeHeaders) {
+          headerSchemata = imageFileTypeHeaders[fileType];
 
-  CanvasRenderer.prototype.setOpacity = function(opacity) {
-      this.ctx.globalAlpha = opacity;
-  };
+          for (i = 0; i < headerSchemata.length; i += 1) {
+            compareResult = true;
 
-  CanvasRenderer.prototype.setTransform = function(transform) {
-      this.ctx.translate(transform.origin[0], transform.origin[1]);
-      this.ctx.transform.apply(this.ctx, transform.matrix);
-      this.ctx.translate(-transform.origin[0], -transform.origin[1]);
-  };
+            for (j = 0; j < headerSchemata[i].length; j += 1) {
+              if (headerSchemata[i][j] === undefined) {
+                continue;
+              }
 
-  CanvasRenderer.prototype.setVariable = function(property, value) {
-      if (this.variables[property] !== value) {
-          this.variables[property] = this.ctx[property] = value;
+              if (headerSchemata[i][j] !== imageData.charCodeAt(j)) {
+                compareResult = false;
+                break;
+              }
+            }
+
+            if (compareResult === true) {
+              result = fileType;
+              break;
+            }
+          }
+        }
       }
 
-      return this;
-  };
+      if (result === UNKNOWN && fallbackFormat !== UNKNOWN) {
+        result = fallbackFormat;
+      }
 
-  CanvasRenderer.prototype.text = function(text, left, bottom) {
-      this.ctx.fillText(text, left, bottom);
-  };
+      return result;
+    }; // Image functionality ported from pdf.js
 
-  CanvasRenderer.prototype.backgroundRepeatShape = function(imageContainer, backgroundPosition, size, bounds, left, top, width, height, borderData) {
-      var shape = [
-          ["line", Math.round(left), Math.round(top)],
-          ["line", Math.round(left + width), Math.round(top)],
-          ["line", Math.round(left + width), Math.round(height + top)],
-          ["line", Math.round(left), Math.round(height + top)]
-      ];
-      this.clip([shape], function() {
-          this.renderBackgroundRepeat(imageContainer, backgroundPosition, size, bounds, borderData[3], borderData[0]);
-      }, this);
-  };
 
-  CanvasRenderer.prototype.renderBackgroundRepeat = function(imageContainer, backgroundPosition, size, bounds, borderLeft, borderTop) {
-      var offsetX = Math.round(bounds.left + backgroundPosition.left + borderLeft), offsetY = Math.round(bounds.top + backgroundPosition.top + borderTop);
-      this.setFillStyle(this.ctx.createPattern(this.resizeImage(imageContainer, size), "repeat"));
-      this.ctx.translate(offsetX, offsetY);
-      this.ctx.fill();
-      this.ctx.translate(-offsetX, -offsetY);
-  };
+    var putImage = function putImage(image) {
+      var out = this.internal.write;
+      var putStream = this.internal.putStream;
+      var getFilters = this.internal.getFilters;
+      var filter = getFilters();
 
-  CanvasRenderer.prototype.renderBackgroundGradient = function(gradientImage, bounds) {
-      if (gradientImage instanceof LinearGradientContainer) {
-          var gradient = this.ctx.createLinearGradient(
-              bounds.left + bounds.width * gradientImage.x0,
-              bounds.top + bounds.height * gradientImage.y0,
-              bounds.left +  bounds.width * gradientImage.x1,
-              bounds.top +  bounds.height * gradientImage.y1);
-          gradientImage.colorStops.forEach(function(colorStop) {
-              gradient.addColorStop(colorStop.stop, colorStop.color.toString());
-          });
-          this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, gradient);
+      while (filter.indexOf("FlateEncode") !== -1) {
+        filter.splice(filter.indexOf("FlateEncode"), 1);
       }
-  };
 
-  CanvasRenderer.prototype.resizeImage = function(imageContainer, size) {
-      var image = imageContainer.image;
-      if(image.width === size.width && image.height === size.height) {
-          return image;
+      image.objectId = this.internal.newObject();
+      var additionalKeyValues = [];
+      additionalKeyValues.push({
+        key: "Type",
+        value: "/XObject"
+      });
+      additionalKeyValues.push({
+        key: "Subtype",
+        value: "/Image"
+      });
+      additionalKeyValues.push({
+        key: "Width",
+        value: image.width
+      });
+      additionalKeyValues.push({
+        key: "Height",
+        value: image.height
+      });
+
+      if (image.colorSpace === color_spaces.INDEXED) {
+        additionalKeyValues.push({
+          key: "ColorSpace",
+          value: "[/Indexed /DeviceRGB " + ( // if an indexed png defines more than one colour with transparency, we've created a sMask
+          image.palette.length / 3 - 1) + " " + ("sMask" in image && typeof image.sMask !== "undefined" ? image.objectId + 2 : image.objectId + 1) + " 0 R]"
+        });
+      } else {
+        additionalKeyValues.push({
+          key: "ColorSpace",
+          value: "/" + image.colorSpace
+        });
+
+        if (image.colorSpace === color_spaces.DEVICE_CMYK) {
+          additionalKeyValues.push({
+            key: "Decode",
+            value: "[1 0 1 0 1 0 1 0]"
+          });
+        }
       }
 
-      var ctx, canvas = document.createElement('canvas');
-      canvas.width = size.width;
-      canvas.height = size.height;
-      ctx = canvas.getContext("2d");
-      ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, size.width, size.height );
-      return canvas;
-  };
+      additionalKeyValues.push({
+        key: "BitsPerComponent",
+        value: image.bitsPerComponent
+      });
 
-  function hasEntries(array) {
-      return array.length > 0;
-  }
+      if ("decodeParameters" in image && typeof image.decodeParameters !== "undefined") {
+        additionalKeyValues.push({
+          key: "DecodeParms",
+          value: "<<" + image.decodeParameters + ">>"
+        });
+      }
 
-  module.exports = CanvasRenderer;
+      if ("transparency" in image && Array.isArray(image.transparency)) {
+        var transparency = "",
+            i = 0,
+            len = image.transparency.length;
 
-  },{"../lineargradientcontainer":12,"../log":13,"../renderer":19}],21:[function(_dereq_,module,exports){
-  var NodeContainer = _dereq_('./nodecontainer');
+        for (; i < len; i++) {
+          transparency += image.transparency[i] + " " + image.transparency[i] + " ";
+        }
 
-  function StackingContext(hasOwnStacking, opacity, element, parent) {
-      NodeContainer.call(this, element, parent);
-      this.ownStacking = hasOwnStacking;
-      this.contexts = [];
-      this.children = [];
-      this.opacity = (this.parent ? this.parent.stack.opacity : 1) * opacity;
-  }
+        additionalKeyValues.push({
+          key: "Mask",
+          value: "[" + transparency + "]"
+        });
+      }
+
+      if (typeof image.sMask !== "undefined") {
+        additionalKeyValues.push({
+          key: "SMask",
+          value: image.objectId + 1 + " 0 R"
+        });
+      }
 
-  StackingContext.prototype = Object.create(NodeContainer.prototype);
+      var alreadyAppliedFilters = typeof image.filter !== "undefined" ? ["/" + image.filter] : undefined;
+      putStream({
+        data: image.data,
+        additionalKeyValues: additionalKeyValues,
+        alreadyAppliedFilters: alreadyAppliedFilters,
+        objectId: image.objectId
+      });
+      out("endobj"); // Soft mask
+
+      if ("sMask" in image && typeof image.sMask !== "undefined") {
+        var decodeParameters = "/Predictor " + image.predictor + " /Colors 1 /BitsPerComponent " + image.bitsPerComponent + " /Columns " + image.width;
+        var sMask = {
+          width: image.width,
+          height: image.height,
+          colorSpace: "DeviceGray",
+          bitsPerComponent: image.bitsPerComponent,
+          decodeParameters: decodeParameters,
+          data: image.sMask
+        };
 
-  StackingContext.prototype.getParentStack = function(context) {
-      var parentStack = (this.parent) ? this.parent.stack : null;
-      return parentStack ? (parentStack.ownStacking ? parentStack : parentStack.getParentStack(context)) : context.stack;
-  };
+        if ("filter" in image) {
+          sMask.filter = image.filter;
+        }
 
-  module.exports = StackingContext;
+        putImage.call(this, sMask);
+      } //Palette
 
-  },{"./nodecontainer":14}],22:[function(_dereq_,module,exports){
-  function Support(document) {
-      this.rangeBounds = this.testRangeBounds(document);
-      this.cors = this.testCORS();
-      this.svg = this.testSVG();
-  }
 
-  Support.prototype.testRangeBounds = function(document) {
-      var range, testElement, rangeBounds, rangeHeight, support = false;
+      if (image.colorSpace === color_spaces.INDEXED) {
+        var objId = this.internal.newObject(); //out('<< /Filter / ' + img['f'] +' /Length ' + img['pal'].length + '>>');
+        //putStream(zlib.compress(img['pal']));
 
-      if (document.createRange) {
-          range = document.createRange();
-          if (range.getBoundingClientRect) {
-              testElement = document.createElement('boundtest');
-              testElement.style.height = "123px";
-              testElement.style.display = "block";
-              document.body.appendChild(testElement);
+        putStream({
+          data: arrayBufferToBinaryString(new Uint8Array(image.palette)),
+          objectId: objId
+        });
+        out("endobj");
+      }
+    };
 
-              range.selectNode(testElement);
-              rangeBounds = range.getBoundingClientRect();
-              rangeHeight = rangeBounds.height;
+    var putResourcesCallback = function putResourcesCallback() {
+      var images = this.internal.collections[namespace + "images"];
 
-              if (rangeHeight === 123) {
-                  support = true;
-              }
-              document.body.removeChild(testElement);
-          }
+      for (var i in images) {
+        putImage.call(this, images[i]);
       }
+    };
 
-      return support;
-  };
+    var putXObjectsDictCallback = function putXObjectsDictCallback() {
+      var images = this.internal.collections[namespace + "images"],
+          out = this.internal.write,
+          image;
 
-  Support.prototype.testCORS = function() {
-      return typeof((new Image()).crossOrigin) !== "undefined";
-  };
+      for (var i in images) {
+        image = images[i];
+        out("/I" + image.index, image.objectId, "0", "R");
+      }
+    };
 
-  Support.prototype.testSVG = function() {
-      var img = new Image();
-      var canvas = document.createElement("canvas");
-      var ctx =  canvas.getContext("2d");
-      img.src = "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>";
+    var checkCompressValue = function checkCompressValue(value) {
+      if (value && typeof value === "string") value = value.toUpperCase();
+      return value in jsPDFAPI.image_compression ? value : image_compression.NONE;
+    };
 
-      try {
-          ctx.drawImage(img, 0, 0);
-          canvas.toDataURL();
-      } catch(e) {
-          return false;
+    var initialize = function initialize() {
+      if (!this.internal.collections[namespace + "images"]) {
+        this.internal.collections[namespace + "images"] = {};
+        this.internal.events.subscribe("putResources", putResourcesCallback);
+        this.internal.events.subscribe("putXobjectDict", putXObjectsDictCallback);
       }
-      return true;
-  };
+    };
 
-  module.exports = Support;
+    var getImages = function getImages() {
+      var images = this.internal.collections[namespace + "images"];
+      initialize.call(this);
+      return images;
+    };
 
-  },{}],23:[function(_dereq_,module,exports){
-  var XHR = _dereq_('./xhr');
-  var decode64 = _dereq_('./utils').decode64;
+    var getImageIndex = function getImageIndex() {
+      return Object.keys(this.internal.collections[namespace + "images"]).length;
+    };
 
-  function SVGContainer(src) {
-      this.src = src;
-      this.image = null;
-      var self = this;
+    var notDefined = function notDefined(value) {
+      return typeof value === "undefined" || value === null || value.length === 0;
+    };
 
-      this.promise = this.hasFabric().then(function() {
-          return (self.isInline(src) ? Promise.resolve(self.inlineFormatting(src)) : XHR(src));
-      }).then(function(svg) {
-          return new Promise(function(resolve) {
-              window.html2canvas.svg.fabric.loadSVGFromString(svg, self.createCanvas.call(self, resolve));
-          });
-      });
-  }
+    var generateAliasFromImageData = function generateAliasFromImageData(imageData) {
+      if (typeof imageData === "string" || isArrayBufferView(imageData)) {
+        return sHashCode(imageData);
+      } else if (isArrayBufferView(imageData.data)) {
+        return sHashCode(imageData.data);
+      }
 
-  SVGContainer.prototype.hasFabric = function() {
-      return !window.html2canvas.svg || !window.html2canvas.svg.fabric ? Promise.reject(new Error("html2canvas.svg.js is not loaded, cannot render svg")) : Promise.resolve();
-  };
+      return null;
+    };
 
-  SVGContainer.prototype.inlineFormatting = function(src) {
-      return (/^data:image\/svg\+xml;base64,/.test(src)) ? this.decode64(this.removeContentType(src)) : this.removeContentType(src);
-  };
+    var isImageTypeSupported = function isImageTypeSupported(type) {
+      return typeof jsPDFAPI["process" + type.toUpperCase()] === "function";
+    };
 
-  SVGContainer.prototype.removeContentType = function(src) {
-      return src.replace(/^data:image\/svg\+xml(;base64)?,/,'');
-  };
+    var isDOMElement = function isDOMElement(object) {
+      return _typeof(object) === "object" && object.nodeType === 1;
+    };
 
-  SVGContainer.prototype.isInline = function(src) {
-      return (/^data:image\/svg\+xml/i.test(src));
-  };
+    var getImageDataFromElement = function getImageDataFromElement(element, format) {
+      //if element is an image which uses data url definition, just return the dataurl
+      if (element.nodeName === "IMG" && element.hasAttribute("src")) {
+        var src = "" + element.getAttribute("src"); //is base64 encoded dataUrl, directly process it
 
-  SVGContainer.prototype.createCanvas = function(resolve) {
-      var self = this;
-      return function (objects, options) {
-          var canvas = new window.html2canvas.svg.fabric.StaticCanvas('c');
-          self.image = canvas.lowerCanvasEl;
-          canvas
-              .setWidth(options.width)
-              .setHeight(options.height)
-              .add(window.html2canvas.svg.fabric.util.groupSVGElements(objects, options))
-              .renderAll();
-          resolve(canvas.lowerCanvasEl);
-      };
-  };
+        if (src.indexOf("data:image/") === 0) {
+          return atob(unescape(src).split("base64,").pop());
+        } //it is probably an url, try to load it
 
-  SVGContainer.prototype.decode64 = function(str) {
-      return (typeof(window.atob) === "function") ? window.atob(str) : decode64(str);
-  };
 
-  module.exports = SVGContainer;
+        var tmpImageData = jsPDFAPI.loadFile(src, true);
 
-  },{"./utils":26,"./xhr":28}],24:[function(_dereq_,module,exports){
-  var SVGContainer = _dereq_('./svgcontainer');
+        if (tmpImageData !== undefined) {
+          return tmpImageData;
+        }
+      }
 
-  function SVGNodeContainer(node, _native) {
-      this.src = node;
-      this.image = null;
-      var self = this;
+      if (element.nodeName === "CANVAS") {
+        if (element.width === 0 || element.height === 0) {
+          throw new Error("Given canvas must have data. Canvas width: " + element.width + ", height: " + element.height);
+        }
 
-      this.promise = _native ? new Promise(function(resolve, reject) {
-          self.image = new Image();
-          self.image.onload = resolve;
-          self.image.onerror = reject;
-          self.image.src = "data:image/svg+xml," + (new XMLSerializer()).serializeToString(node);
-          if (self.image.complete === true) {
-              resolve(self.image);
-          }
-      }) : this.hasFabric().then(function() {
-          return new Promise(function(resolve) {
-              window.html2canvas.svg.fabric.parseSVGDocument(node, self.createCanvas.call(self, resolve));
-          });
-      });
-  }
+        var mimeType;
 
-  SVGNodeContainer.prototype = Object.create(SVGContainer.prototype);
+        switch (format) {
+          case "PNG":
+            mimeType = "image/png";
+            break;
 
-  module.exports = SVGNodeContainer;
+          case "WEBP":
+            mimeType = "image/webp";
+            break;
 
-  },{"./svgcontainer":23}],25:[function(_dereq_,module,exports){
-  var NodeContainer = _dereq_('./nodecontainer');
+          case "JPEG":
+          case "JPG":
+          default:
+            mimeType = "image/jpeg";
+            break;
+        }
 
-  function TextContainer(node, parent) {
-      NodeContainer.call(this, node, parent);
-  }
+        return atob(element.toDataURL(mimeType, 1.0).split("base64,").pop());
+      }
+    };
 
-  TextContainer.prototype = Object.create(NodeContainer.prototype);
+    var checkImagesForAlias = function checkImagesForAlias(alias) {
+      var images = this.internal.collections[namespace + "images"];
 
-  TextContainer.prototype.applyTextTransform = function() {
-      this.node.data = this.transform(this.parent.css("textTransform"));
-  };
+      if (images) {
+        for (var e in images) {
+          if (alias === images[e].alias) {
+            return images[e];
+          }
+        }
+      }
+    };
 
-  TextContainer.prototype.transform = function(transform) {
-      var text = this.node.data;
-      switch(transform){
-          case "lowercase":
-              return text.toLowerCase();
-          case "capitalize":
-              return text.replace(/(^|\s|:|-|\(|\))([a-z])/g, capitalize);
-          case "uppercase":
-              return text.toUpperCase();
-          default:
-              return text;
+    var determineWidthAndHeight = function determineWidthAndHeight(width, height, image) {
+      if (!width && !height) {
+        width = -96;
+        height = -96;
       }
-  };
 
-  function capitalize(m, p1, p2) {
-      if (m.length > 0) {
-          return p1 + p2.toUpperCase();
+      if (width < 0) {
+        width = -1 * image.width * 72 / width / this.internal.scaleFactor;
       }
-  }
 
-  module.exports = TextContainer;
+      if (height < 0) {
+        height = -1 * image.height * 72 / height / this.internal.scaleFactor;
+      }
 
-  },{"./nodecontainer":14}],26:[function(_dereq_,module,exports){
-  exports.smallImage = function smallImage() {
-      return "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
-  };
+      if (width === 0) {
+        width = height * image.width / image.height;
+      }
 
-  exports.bind = function(callback, context) {
-      return function() {
-          return callback.apply(context, arguments);
-      };
-  };
+      if (height === 0) {
+        height = width * image.height / image.width;
+      }
 
-  /*
-   * base64-arraybuffer
-   * https://github.com/niklasvh/base64-arraybuffer
-   *
-   * Copyright (c) 2012 Niklas von Hertzen
-   * Licensed under the MIT license.
-   */
+      return [width, height];
+    };
 
-  exports.decode64 = function(base64) {
-      var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-      var len = base64.length, i, encoded1, encoded2, encoded3, encoded4, byte1, byte2, byte3;
-
-      var output = "";
-
-      for (i = 0; i < len; i+=4) {
-          encoded1 = chars.indexOf(base64[i]);
-          encoded2 = chars.indexOf(base64[i+1]);
-          encoded3 = chars.indexOf(base64[i+2]);
-          encoded4 = chars.indexOf(base64[i+3]);
-
-          byte1 = (encoded1 << 2) | (encoded2 >> 4);
-          byte2 = ((encoded2 & 15) << 4) | (encoded3 >> 2);
-          byte3 = ((encoded3 & 3) << 6) | encoded4;
-          if (encoded3 === 64) {
-              output += String.fromCharCode(byte1);
-          } else if (encoded4 === 64 || encoded4 === -1) {
-              output += String.fromCharCode(byte1, byte2);
-          } else{
-              output += String.fromCharCode(byte1, byte2, byte3);
-          }
+    var writeImageToPDF = function writeImageToPDF(x, y, width, height, image, rotation) {
+      var dims = determineWidthAndHeight.call(this, width, height, image),
+          coord = this.internal.getCoordinateString,
+          vcoord = this.internal.getVerticalCoordinateString;
+      var images = getImages.call(this);
+      width = dims[0];
+      height = dims[1];
+      images[image.index] = image;
+
+      if (rotation) {
+        rotation *= Math.PI / 180;
+        var c = Math.cos(rotation);
+        var s = Math.sin(rotation); //like in pdf Reference do it 4 digits instead of 2
+
+        var f4 = function f4(number) {
+          return number.toFixed(4);
+        };
+
+        var rotationTransformationMatrix = [f4(c), f4(s), f4(s * -1), f4(c), 0, 0, "cm"];
       }
 
-      return output;
-  };
+      this.internal.write("q"); //Save graphics state
 
-  exports.getBounds = function(node) {
-      if (node.getBoundingClientRect) {
-          var clientRect = node.getBoundingClientRect();
-          var width = node.offsetWidth == null ? clientRect.width : node.offsetWidth;
-          return {
-              top: clientRect.top,
-              bottom: clientRect.bottom || (clientRect.top + clientRect.height),
-              right: clientRect.left + width,
-              left: clientRect.left,
-              width:  width,
-              height: node.offsetHeight == null ? clientRect.height : node.offsetHeight
-          };
+      if (rotation) {
+        this.internal.write([1, "0", "0", 1, coord(x), vcoord(y + height), "cm"].join(" ")); //Translate
+
+        this.internal.write(rotationTransformationMatrix.join(" ")); //Rotate
+
+        this.internal.write([coord(width), "0", "0", coord(height), "0", "0", "cm"].join(" ")); //Scale
+      } else {
+        this.internal.write([coord(width), "0", "0", coord(height), coord(x), vcoord(y + height), "cm"].join(" ")); //Translate and Scale
       }
-      return {};
-  };
 
-  exports.offsetBounds = function(node) {
-      var parent = node.offsetParent ? exports.offsetBounds(node.offsetParent) : {top: 0, left: 0};
+      if (this.isAdvancedAPI()) {
+        // draw image bottom up when in "advanced" API mode
+        this.internal.write([1, 0, 0, -1, 0, 0, "cm"].join(" "));
+      }
 
-      return {
-          top: node.offsetTop + parent.top,
-          bottom: node.offsetTop + node.offsetHeight + parent.top,
-          right: node.offsetLeft + parent.left + node.offsetWidth,
-          left: node.offsetLeft + parent.left,
-          width: node.offsetWidth,
-          height: node.offsetHeight
-      };
-  };
+      this.internal.write("/I" + image.index + " Do"); //Paint Image
 
-  exports.parseBackgrounds = function(backgroundImage) {
-      var whitespace = ' \r\n\t',
-          method, definition, prefix, prefix_i, block, results = [],
-          mode = 0, numParen = 0, quote, args;
-      var appendResult = function() {
-          if(method) {
-              if (definition.substr(0, 1) === '"') {
-                  definition = definition.substr(1, definition.length - 2);
-              }
-              if (definition) {
-                  args.push(definition);
-              }
-              if (method.substr(0, 1) === '-' && (prefix_i = method.indexOf('-', 1 ) + 1) > 0) {
-                  prefix = method.substr(0, prefix_i);
-                  method = method.substr(prefix_i);
-              }
-              results.push({
-                  prefix: prefix,
-                  method: method.toLowerCase(),
-                  value: block,
-                  args: args,
-                  image: null
-              });
-          }
-          args = [];
-          method = prefix = definition = block = '';
-      };
-      args = [];
-      method = prefix = definition = block = '';
-      backgroundImage.split("").forEach(function(c) {
-          if (mode === 0 && whitespace.indexOf(c) > -1) {
-              return;
-          }
-          switch(c) {
-          case '"':
-              if(!quote) {
-                  quote = c;
-              } else if(quote === c) {
-                  quote = null;
-              }
-              break;
-          case '(':
-              if(quote) {
-                  break;
-              } else if(mode === 0) {
-                  mode = 1;
-                  block += c;
-                  return;
-              } else {
-                  numParen++;
-              }
-              break;
-          case ')':
-              if (quote) {
-                  break;
-              } else if(mode === 1) {
-                  if(numParen === 0) {
-                      mode = 0;
-                      block += c;
-                      appendResult();
-                      return;
-                  } else {
-                      numParen--;
-                  }
-              }
-              break;
+      this.internal.write("Q"); //Restore graphics state
+    };
+    /**
+     * COLOR SPACES
+     */
 
-          case ',':
-              if (quote) {
-                  break;
-              } else if(mode === 0) {
-                  appendResult();
-                  return;
-              } else if (mode === 1) {
-                  if (numParen === 0 && !method.match(/^url$/i)) {
-                      args.push(definition);
-                      definition = '';
-                      block += c;
-                      return;
-                  }
-              }
-              break;
-          }
 
-          block += c;
-          if (mode === 0) {
-              method += c;
-          } else {
-              definition += c;
-          }
-      });
+    var color_spaces = jsPDFAPI.color_spaces = {
+      DEVICE_RGB: "DeviceRGB",
+      DEVICE_GRAY: "DeviceGray",
+      DEVICE_CMYK: "DeviceCMYK",
+      CAL_GREY: "CalGray",
+      CAL_RGB: "CalRGB",
+      LAB: "Lab",
+      ICC_BASED: "ICCBased",
+      INDEXED: "Indexed",
+      PATTERN: "Pattern",
+      SEPARATION: "Separation",
+      DEVICE_N: "DeviceN"
+    };
+    /**
+     * DECODE METHODS
+     */
 
-      appendResult();
-      return results;
-  };
+    jsPDFAPI.decode = {
+      DCT_DECODE: "DCTDecode",
+      FLATE_DECODE: "FlateDecode",
+      LZW_DECODE: "LZWDecode",
+      JPX_DECODE: "JPXDecode",
+      JBIG2_DECODE: "JBIG2Decode",
+      ASCII85_DECODE: "ASCII85Decode",
+      ASCII_HEX_DECODE: "ASCIIHexDecode",
+      RUN_LENGTH_DECODE: "RunLengthDecode",
+      CCITT_FAX_DECODE: "CCITTFaxDecode"
+    };
+    /**
+     * IMAGE COMPRESSION TYPES
+     */
 
-  },{}],27:[function(_dereq_,module,exports){
-  var GradientContainer = _dereq_('./gradientcontainer');
+    var image_compression = jsPDFAPI.image_compression = {
+      NONE: "NONE",
+      FAST: "FAST",
+      MEDIUM: "MEDIUM",
+      SLOW: "SLOW"
+    };
+    /**
+     * @name sHashCode
+     * @function
+     * @param {string} data
+     * @returns {string}
+     */
 
-  function WebkitGradientContainer(imageData) {
-      GradientContainer.apply(this, arguments);
-      this.type = imageData.args[0] === "linear" ? GradientContainer.TYPES.LINEAR : GradientContainer.TYPES.RADIAL;
-  }
+    var sHashCode = jsPDFAPI.__addimage__.sHashCode = function (data) {
+      var hash = 0,
+          i,
+          len;
 
-  WebkitGradientContainer.prototype = Object.create(GradientContainer.prototype);
+      if (typeof data === "string") {
+        len = data.length;
 
-  module.exports = WebkitGradientContainer;
+        for (i = 0; i < len; i++) {
+          hash = (hash << 5) - hash + data.charCodeAt(i);
+          hash |= 0; // Convert to 32bit integer
+        }
+      } else if (isArrayBufferView(data)) {
+        len = data.byteLength / 2;
 
-  },{"./gradientcontainer":9}],28:[function(_dereq_,module,exports){
-  function XHR(url) {
-      return new Promise(function(resolve, reject) {
-          var xhr = new XMLHttpRequest();
-          xhr.open('GET', url);
+        for (i = 0; i < len; i++) {
+          hash = (hash << 5) - hash + data[i];
+          hash |= 0; // Convert to 32bit integer
+        }
+      }
 
-          xhr.onload = function() {
-              if (xhr.status === 200) {
-                  resolve(xhr.responseText);
-              } else {
-                  reject(new Error(xhr.statusText));
-              }
-          };
+      return hash;
+    };
+    /**
+     * Validates if given String is a valid Base64-String
+     *
+     * @name validateStringAsBase64
+     * @public
+     * @function
+     * @param {String} possible Base64-String
+     *
+     * @returns {boolean}
+     */
 
-          xhr.onerror = function() {
-              reject(new Error("Network Error"));
-          };
 
-          xhr.send();
-      });
-  }
+    var validateStringAsBase64 = jsPDFAPI.__addimage__.validateStringAsBase64 = function (possibleBase64String) {
+      possibleBase64String = possibleBase64String || "";
+      possibleBase64String.toString().trim();
+      var result = true;
 
-  module.exports = XHR;
+      if (possibleBase64String.length === 0) {
+        result = false;
+      }
 
-  },{}]},{},[4])(4)
-  });
+      if (possibleBase64String.length % 4 !== 0) {
+        result = false;
+      }
 
-  /************************************************
-   * Title : custom font                          *
-   * Start Data : 2017. 01. 22.                   *
-   * Comment : TEXT API                           *
-   ************************************************/
-
-  /******************************
-   * jsPDF extension API Design *
-   * ****************************/
-  (function(jsPDF){
-      var PLUS = '+'.charCodeAt(0);
-      var SLASH = '/'.charCodeAt(0);
-      var NUMBER = '0'.charCodeAt(0);
-      var LOWER = 'a'.charCodeAt(0);
-      var UPPER = 'A'.charCodeAt(0);
-      var PLUS_URL_SAFE = '-'.charCodeAt(0);
-      var SLASH_URL_SAFE = '_'.charCodeAt(0);
-
-      /*****************************************************************/
-      /* function : b64ToByteArray                                     */
-      /* comment : Base64 encoded TTF file contents (b64) are decoded  */
-      /*     by Byte array and stored.                                 */
-      /*****************************************************************/
-      var b64ToByteArray = function(b64) {
-          var i, j, l, tmp, placeHolders, arr;
-          if (b64.length % 4 > 0) {
-              throw new Error('Invalid string. Length must be a multiple of 4')
-          }
-          // the number of equal signs (place holders)
-          // if there are two placeholders, than the two characters before it
-          // represent one byte
-          // if there is only one, then the three characters before it represent 2 bytes
-          // this is just a cheap hack to not do indexOf twice
-          var len = b64.length;
-          placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0;
-              // base64 is 4/3 + up to two characters of the original data
-          arr = new Uint8Array(b64.length * 3 / 4 - placeHolders);
-              // if there are placeholders, only get up to the last complete 4 chars
-          l = placeHolders > 0 ? b64.length - 4 : b64.length;
-          var L = 0;
-
-          function push(v) {
-              arr[L++] = v;
-          }
-          for (i = 0, j = 0; i < l; i += 4, j += 3) {
-              tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3));
-              push((tmp & 0xFF0000) >> 16);
-              push((tmp & 0xFF00) >> 8);
-              push(tmp & 0xFF);
-          }
-          if (placeHolders === 2) {
-              tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4);
-              push(tmp & 0xFF);
-          }
-          else if (placeHolders === 1) {
-              tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2);
-              push((tmp >> 8) & 0xFF);
-              push(tmp & 0xFF);
-          }
-          return arr
-      };
+      if (/^[A-Za-z0-9+/]+$/.test(possibleBase64String.substr(0, possibleBase64String.length - 2)) === false) {
+        result = false;
+      }
 
-      /***************************************************************/
-      /* function : decode                                           */
-      /* comment : Change the base64 encoded font's content to match */
-      /*   the base64 index value.                                   */
-      /***************************************************************/
-      var decode = function(elt) {
-          var code = elt.charCodeAt(0);
-          if (code === PLUS || code === PLUS_URL_SAFE) return 62 // '+'
-          if (code === SLASH || code === SLASH_URL_SAFE) return 63 // '/'
-          if (code < NUMBER) return -1 //no match
-          if (code < NUMBER + 10) return code - NUMBER + 26 + 26
-          if (code < UPPER + 26) return code - UPPER
-          if (code < LOWER + 26) return code - LOWER + 26
-      };
+      if (/^[A-Za-z0-9/][A-Za-z0-9+/]|[A-Za-z0-9+/]=|==$/.test(possibleBase64String.substr(-2)) === false) {
+        result = false;
+      }
 
-      jsPDF.API.TTFFont = (function () {
-          /************************************************************************/
-          /* function : open                                                       */
-          /* comment : Decode the encoded ttf content and create a TTFFont object. */
-          /************************************************************************/
-          TTFFont.open = function (filename, name, vfs, encoding) {
-              var contents;
-              contents = b64ToByteArray(vfs);
-              return new TTFFont(contents, name, encoding);
-          };
-          /***************************************************************/
-          /* function : TTFFont gernerator                               */
-          /* comment : Decode TTF contents are parsed, Data,             */
-          /* Subset object is created, and registerTTF function is called.*/
-          /***************************************************************/
-          function TTFFont(rawData, name, encoding) {
-              var data;
-              this.rawData = rawData;
-              data = this.contents = new Data(rawData);
-              this.contents.pos = 4;
-              if (data.readString(4) === 'ttcf') {
-                  if (!name) {
-                      throw new Error("Must specify a font name for TTC files.");
-                  }
-                  throw new Error("Font " + name + " not found in TTC file.");
-              }
-              else {
-                  data.pos = 0;
-                  this.parse();
-                  this.subset = new Subset(this);
-                  this.registerTTF();
-              }
-          }
-          /********************************************************/
-          /* function : parse                                     */
-          /* comment : TTF Parses the file contents by each table.*/
-          /********************************************************/
-          TTFFont.prototype.parse = function () {
-              this.directory = new Directory(this.contents);
-              this.head = new HeadTable(this);
-              this.name = new NameTable(this);
-              this.cmap = new CmapTable(this);
-              this.hhea = new HheaTable(this);
-              this.maxp = new MaxpTable(this);
-              this.hmtx = new HmtxTable(this);
-              this.post = new PostTable(this);
-              this.os2 = new OS2Table(this);
-              this.loca = new LocaTable(this);
-              this.glyf = new GlyfTable(this);
-              this.ascender = (this.os2.exists && this.os2.ascender) || this.hhea.ascender;
-              this.decender = (this.os2.exists && this.os2.decender) || this.hhea.decender;
-              this.lineGap = (this.os2.exists && this.os2.lineGap) || this.hhea.lineGap;
-              return this.bbox = [this.head.xMin, this.head.yMin, this.head.xMax, this.head.yMax];
-          };
-          /***************************************************************/
-          /* function : registerTTF                                      */
-          /* comment : Get the value to assign pdf font descriptors.     */
-          /***************************************************************/
-          TTFFont.prototype.registerTTF = function () {
-              var e, hi, low, raw, _ref;
-              this.scaleFactor = 1000.0 / this.head.unitsPerEm;
-              this.bbox = (function () {
-                  var _i, _len, _ref, _results;
-                  _ref = this.bbox;
-                  _results = [];
-                  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-                      e = _ref[_i];
-                      _results.push(Math.round(e * this.scaleFactor));
-                  }
-                  return _results;
-              }).call(this);
-              this.stemV = 0;
-              if (this.post.exists) {
-                  raw = this.post.italic_angle;
-                  hi = raw >> 16;
-                  low = raw & 0xFF;
-                  if (hi & 0x8000 !== 0) {
-                      hi = -((hi ^ 0xFFFF) + 1);
-                  }
-                  this.italicAngle = +("" + hi + "." + low);
-              }
-              else {
-                  this.italicAngle = 0;
-              }
-              this.ascender = Math.round(this.ascender * this.scaleFactor);
-              this.decender = Math.round(this.decender * this.scaleFactor);
-              this.lineGap = Math.round(this.lineGap * this.scaleFactor);
-              this.capHeight = (this.os2.exists && this.os2.capHeight) || this.ascender;
-              this.xHeight = (this.os2.exists && this.os2.xHeight) || 0;
-              this.familyClass = (this.os2.exists && this.os2.familyClass || 0) >> 8;
-              this.isSerif = (_ref = this.familyClass) === 1 || _ref === 2 || _ref === 3 || _ref === 4 || _ref === 5 || _ref === 7;
-              this.isScript = this.familyClass === 10;
-              this.flags = 0;
-              if (this.post.isFixedPitch) {
-                  this.flags |= 1 << 0;
-              }
-              if (this.isSerif) {
-                  this.flags |= 1 << 1;
-              }
-              if (this.isScript) {
-                  this.flags |= 1 << 3;
-              }
-              if (this.italicAngle !== 0) {
-                  this.flags |= 1 << 6;
-              }
-              this.flags |= 1 << 5;
-              if (!this.cmap.unicode) {
-                  throw new Error('No unicode cmap for font');
-              }
-          };
-          TTFFont.prototype.characterToGlyph = function (character) {
-              var _ref;
-              return ((_ref = this.cmap.unicode) != null ? _ref.codeMap[character] : void 0) || 0;
-          };
-          TTFFont.prototype.widthOfGlyph = function (glyph) {
-              var scale;
-              scale = 1000.0 / this.head.unitsPerEm;
-              return this.hmtx.forGlyph(glyph).advance * scale;
-          };
-          TTFFont.prototype.widthOfString = function (string, size, charSpace) {
-              var charCode, i, scale, width, _i, _ref, charSpace;
-              string = '' + string;
-              width = 0;
-              for (i = _i = 0, _ref = string.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
-                  charCode = string.charCodeAt(i);
-                  width += (this.widthOfGlyph(this.characterToGlyph(charCode)) + charSpace * (1000/ size)) || 0;
-              }
-              scale = size / 1000;
-              return width * scale;
-          };
-          TTFFont.prototype.lineHeight = function (size, includeGap) {
-              var gap;
-              if (includeGap == null) {
-                  includeGap = false;
-              }
-              gap = includeGap ? this.lineGap : 0;
-              return (this.ascender + gap - this.decender) / 1000 * size;
-          };
-          return TTFFont;
-      })();
+      return result;
+    };
+    /**
+     * Strips out and returns info from a valid base64 data URI
+     *
+     * @name extractImageFromDataUrl
+     * @function
+     * @param {string} dataUrl a valid data URI of format 'data:[<MIME-type>][;base64],<data>'
+     * @returns {Array}an Array containing the following
+     * [0] the complete data URI
+     * [1] <MIME-type>
+     * [2] format - the second part of the mime-type i.e 'png' in 'image/png'
+     * [4] <data>
+     */
 
-      /************************************************************************************************/
-      /* function : Data                                                                              */
-      /* comment : The ttf data decoded and stored in an array is read and written to the Data object.*/
-      /************************************************************************************************/
-      var Data = (function () {
-          function Data(data) {
-              this.data = data != null ? data : [];
-              this.pos = 0;
-              this.length = this.data.length;
-          }
-          Data.prototype.readByte = function () {
-              return this.data[this.pos++];
-          };
-          Data.prototype.writeByte = function (byte) {
-              return this.data[this.pos++] = byte;
-          };
-          Data.prototype.readUInt32 = function () {
-              var b1, b2, b3, b4;
-              b1 = this.readByte() * 0x1000000;
-              b2 = this.readByte() << 16;
-              b3 = this.readByte() << 8;
-              b4 = this.readByte();
-              return b1 + b2 + b3 + b4;
-          };
-          Data.prototype.writeUInt32 = function (val) {
-              this.writeByte((val >>> 24) & 0xff);
-              this.writeByte((val >> 16) & 0xff);
-              this.writeByte((val >> 8) & 0xff);
-              return this.writeByte(val & 0xff);
-          };
-          Data.prototype.readInt32 = function () {
-              var int;
-              int = this.readUInt32();
-              if (int >= 0x80000000) {
-                  return int - 0x100000000;
-              }
-              else {
-                  return int;
-              }
-          };
-          Data.prototype.writeInt32 = function (val) {
-              if (val < 0) {
-                  val += 0x100000000;
-              }
-              return this.writeUInt32(val);
-          };
-          Data.prototype.readUInt16 = function () {
-              var b1, b2;
-              b1 = this.readByte() << 8;
-              b2 = this.readByte();
-              return b1 | b2;
-          };
-          Data.prototype.writeUInt16 = function (val) {
-              this.writeByte((val >> 8) & 0xff);
-              return this.writeByte(val & 0xff);
-          };
-          Data.prototype.readInt16 = function () {
-              var int;
-              int = this.readUInt16();
-              if (int >= 0x8000) {
-                  return int - 0x10000;
-              }
-              else {
-                  return int;
-              }
-          };
-          Data.prototype.writeInt16 = function (val) {
-              if (val < 0) {
-                  val += 0x10000;
-              }
-              return this.writeUInt16(val);
-          };
-          Data.prototype.readString = function (length) {
-              var i, ret, _i;
-              ret = [];
-              for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) {
-                  ret[i] = String.fromCharCode(this.readByte());
-              }
-              return ret.join('');
-          };
-          Data.prototype.writeString = function (val) {
-              var i, _i, _ref, _results;
-              _results = [];
-              for (i = _i = 0, _ref = val.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
-                  _results.push(this.writeByte(val.charCodeAt(i)));
-              }
-              return _results;
-          };
-          /*Data.prototype.stringAt = function (pos, length) {
-              this.pos = pos;
-              return this.readString(length);
-          };*/
-          Data.prototype.readShort = function () {
-              return this.readInt16();
-          };
-          Data.prototype.writeShort = function (val) {
-              return this.writeInt16(val);
-          };
-          Data.prototype.readLongLong = function () {
-              var b1, b2, b3, b4, b5, b6, b7, b8;
-              b1 = this.readByte();
-              b2 = this.readByte();
-              b3 = this.readByte();
-              b4 = this.readByte();
-              b5 = this.readByte();
-              b6 = this.readByte();
-              b7 = this.readByte();
-              b8 = this.readByte();
-              if (b1 & 0x80) {
-                  return ((b1 ^ 0xff) * 0x100000000000000 + (b2 ^ 0xff) * 0x1000000000000 + (b3 ^ 0xff) * 0x10000000000 + (b4 ^ 0xff) * 0x100000000 + (b5 ^ 0xff) * 0x1000000 + (b6 ^ 0xff) * 0x10000 + (b7 ^ 0xff) * 0x100 + (b8 ^ 0xff) + 1) * -1;
-              }
-              return b1 * 0x100000000000000 + b2 * 0x1000000000000 + b3 * 0x10000000000 + b4 * 0x100000000 + b5 * 0x1000000 + b6 * 0x10000 + b7 * 0x100 + b8;
-          };
-          /*Data.prototype.writeLongLong = function (val) {
-              var high, low;
-              high = Math.floor(val / 0x100000000);
-              low = val & 0xffffffff;
-              this.writeByte((high >> 24) & 0xff);
-              this.writeByte((high >> 16) & 0xff);
-              this.writeByte((high >> 8) & 0xff);
-              this.writeByte(high & 0xff);
-              this.writeByte((low >> 24) & 0xff);
-              this.writeByte((low >> 16) & 0xff);
-              this.writeByte((low >> 8) & 0xff);
-              return this.writeByte(low & 0xff);
-          };*/
-          Data.prototype.readInt = function () {
-              return this.readInt32();
-          };
-          Data.prototype.writeInt = function (val) {
-              return this.writeInt32(val);
-          };
-          /*Data.prototype.slice = function (start, end) {
-              return this.data.slice(start, end);
-          };*/
-          Data.prototype.read = function (bytes) {
-              var buf, i, _i;
-              buf = [];
-              for (i = _i = 0; 0 <= bytes ? _i < bytes : _i > bytes; i = 0 <= bytes ? ++_i : --_i) {
-                  buf.push(this.readByte());
-              }
-              return buf;
-          };
-          Data.prototype.write = function (bytes) {
-              var byte, _i, _len, _results;
-              _results = [];
-              for (_i = 0, _len = bytes.length; _i < _len; _i++) {
-                  byte = bytes[_i];
-                  _results.push(this.writeByte(byte));
-              }
-              return _results;
-          };
-          return Data;
-      })();
 
-      var Directory = (function () {
-          var checksum;
-
-          /*****************************************************************************************************/
-          /* function : Directory generator                                                                    */
-          /* comment : Initialize the offset, tag, length, and checksum for each table for the font to be used.*/
-          /*****************************************************************************************************/
-          function Directory(data) {
-              var entry, i, _i, _ref;
-              this.scalarType = data.readInt();
-              this.tableCount = data.readShort();
-              this.searchRange = data.readShort();
-              this.entrySelector = data.readShort();
-              this.rangeShift = data.readShort();
-              this.tables = {};
-              for (i = _i = 0, _ref = this.tableCount; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
-                  entry = {
-                      tag: data.readString(4)
-                      , checksum: data.readInt()
-                      , offset: data.readInt()
-                      , length: data.readInt()
-                  };
-                  this.tables[entry.tag] = entry;
-              }
-          }
-          /********************************************************************************************************/
-          /* function : encode                                                                                    */
-          /* comment : It encodes and stores the font table object and information used for the directory object. */
-          /********************************************************************************************************/
-          Directory.prototype.encode = function (tables) {
-              var adjustment, directory, directoryLength, entrySelector, headOffset, log2, offset, rangeShift, searchRange, sum, table, tableCount, tableData, tag;
-              tableCount = Object.keys(tables).length;
-              log2 = Math.log(2);
-              searchRange = Math.floor(Math.log(tableCount) / log2) * 16;
-              entrySelector = Math.floor(searchRange / log2);
-              rangeShift = tableCount * 16 - searchRange;
-              directory = new Data;
-              directory.writeInt(this.scalarType);
-              directory.writeShort(tableCount);
-              directory.writeShort(searchRange);
-              directory.writeShort(entrySelector);
-              directory.writeShort(rangeShift);
-              directoryLength = tableCount * 16;
-              offset = directory.pos + directoryLength;
-              headOffset = null;
-              tableData = [];
-              for (tag in tables) {
-                  table = tables[tag];
-                  directory.writeString(tag);
-                  directory.writeInt(checksum(table));
-                  directory.writeInt(offset);
-                  directory.writeInt(table.length);
-                  tableData = tableData.concat(table);
-                  if (tag === 'head') {
-                      headOffset = offset;
-                  }
-                  offset += table.length;
-                  while (offset % 4) {
-                      tableData.push(0);
-                      offset++;
-                  }
-              }
-              directory.write(tableData);
-              sum = checksum(directory.data);
-              adjustment = 0xB1B0AFBA - sum;
-              directory.pos = headOffset + 8;
-              directory.writeUInt32(adjustment);
-              return directory.data;
-          };
-          /***************************************************************/
-          /* function : checksum                                         */
-          /* comment : Duplicate the table for the tag.                  */
-          /***************************************************************/
-          checksum = function (data) {
-              var i, sum, tmp, _i, _ref;
-              data = __slice.call(data);
-              while (data.length % 4) {
-                  data.push(0);
-              }
-              tmp = new Data(data);
-              sum = 0;
-              for (i = _i = 0, _ref = data.length; _i < _ref; i = _i += 4) {
-                  sum += tmp.readUInt32();
-              }
-              return sum & 0xFFFFFFFF;
-          };
-          return Directory;
-      })();
+    var extractImageFromDataUrl = jsPDFAPI.__addimage__.extractImageFromDataUrl = function (dataUrl) {
+      dataUrl = dataUrl || "";
+      var dataUrlParts = dataUrl.split("base64,");
+      var result = null;
 
-      var Table, __hasProp = {}.hasOwnProperty
-          , __extends = function (child, parent) {
-              for (var key in parent) {
-                  if (__hasProp.call(parent, key)) child[key] = parent[key];
-              }
+      if (dataUrlParts.length === 2) {
+        var extractedInfo = /^data:(\w*\/\w*);*(charset=(?!charset=)[\w=-]*)*;*$/.exec(dataUrlParts[0]);
 
-              function ctor() {
-                  this.constructor = child;
-              }
-              ctor.prototype = parent.prototype;
-              child.prototype = new ctor();
-              child.__super__ = parent.prototype;
-              return child;
-      };
-      /***************************************************************/
-      /* function : Table                                            */
-      /* comment : Save info for each table, and parse the table.    */
-      /***************************************************************/
-      Table = (function () {
-          function Table(file) {
-              var info;
-              this.file = file;
-              info = this.file.directory.tables[this.tag];
-              this.exists = !!info;
-              if (info) {
-                  this.offset = info.offset, this.length = info.length;
-                  this.parse(this.file.contents);
-              }
-          }
-          Table.prototype.parse = function () {};
-          Table.prototype.encode = function () {};
-          Table.prototype.raw = function () {
-              if (!this.exists) {
-                  return null;
-              }
-              this.file.contents.pos = this.offset;
-              return this.file.contents.read(this.length);
+        if (Array.isArray(extractedInfo)) {
+          result = {
+            mimeType: extractedInfo[1],
+            charset: extractedInfo[2],
+            data: dataUrlParts[1]
           };
-          return Table;
-      })();
+        }
+      }
 
-      var HeadTable = (function (_super) {
-          __extends(HeadTable, _super);
+      return result;
+    };
+    /**
+     * Check to see if ArrayBuffer is supported
+     *
+     * @name supportsArrayBuffer
+     * @function
+     * @returns {boolean}
+     */
 
-          function HeadTable() {
-              return HeadTable.__super__.constructor.apply(this, arguments);
-          }
-          HeadTable.prototype.tag = 'head';
-          HeadTable.prototype.parse = function (data) {
-              data.pos = this.offset;
-              this.version = data.readInt();
-              this.revision = data.readInt();
-              this.checkSumAdjustment = data.readInt();
-              this.magicNumber = data.readInt();
-              this.flags = data.readShort();
-              this.unitsPerEm = data.readShort();
-              this.created = data.readLongLong();
-              this.modified = data.readLongLong();
-              this.xMin = data.readShort();
-              this.yMin = data.readShort();
-              this.xMax = data.readShort();
-              this.yMax = data.readShort();
-              this.macStyle = data.readShort();
-              this.lowestRecPPEM = data.readShort();
-              this.fontDirectionHint = data.readShort();
-              this.indexToLocFormat = data.readShort();
-              return this.glyphDataFormat = data.readShort();
-          };
-          /*HeadTable.prototype.encode = function (loca) {
-              var table;
-              table = new Data;
-              table.writeInt(this.version);
-              table.writeInt(this.revision);
-              table.writeInt(this.checkSumAdjustment);
-              table.writeInt(this.magicNumber);
-              table.writeShort(this.flags);
-              table.writeShort(this.unitsPerEm);
-              table.writeLongLong(this.created);
-              table.writeLongLong(this.modified);
-              table.writeShort(this.xMin);
-              table.writeShort(this.yMin);
-              table.writeShort(this.xMax);
-              table.writeShort(this.yMax);
-              table.writeShort(this.macStyle);
-              table.writeShort(this.lowestRecPPEM);
-              table.writeShort(this.fontDirectionHint);
-              table.writeShort(loca.type);
-              table.writeShort(this.glyphDataFormat);
-              return table.data;
-          };*/
-          return HeadTable;
-      })(Table);
-
-      /************************************************************************************/
-      /* function : CmapEntry                                                             */
-      /* comment : Cmap Initializes and encodes object information (required by pdf spec).*/
-      /************************************************************************************/
-      var CmapEntry = (function () {
-          function CmapEntry(data, offset) {
-              var code, count, endCode, glyphId, glyphIds, i, idDelta, idRangeOffset, index, saveOffset, segCount, segCountX2, start, startCode, tail, _i, _j, _k, _len;
-              this.platformID = data.readUInt16();
-              this.encodingID = data.readShort();
-              this.offset = offset + data.readInt();
-              saveOffset = data.pos;
-              data.pos = this.offset;
-              this.format = data.readUInt16();
-              this.length = data.readUInt16();
-              this.language = data.readUInt16();
-              this.isUnicode = (this.platformID === 3 && this.encodingID === 1 && this.format === 4) || this.platformID === 0 && this.format === 4;
-              this.codeMap = {};
-              switch (this.format) {
-              case 0:
-                  for (i = _i = 0; _i < 256; i = ++_i) {
-                      this.codeMap[i] = data.readByte();
-                  }
-                  break;
-              case 4:
-                  segCountX2 = data.readUInt16();
-                  segCount = segCountX2 / 2;
-                  data.pos += 6;
-                  endCode = (function () {
-                      var _j, _results;
-                      _results = [];
-                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
-                          _results.push(data.readUInt16());
-                      }
-                      return _results;
-                  })();
-                  data.pos += 2;
-                  startCode = (function () {
-                      var _j, _results;
-                      _results = [];
-                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
-                          _results.push(data.readUInt16());
-                      }
-                      return _results;
-                  })();
-                  idDelta = (function () {
-                      var _j, _results;
-                      _results = [];
-                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
-                          _results.push(data.readUInt16());
-                      }
-                      return _results;
-                  })();
-                  idRangeOffset = (function () {
-                      var _j, _results;
-                      _results = [];
-                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
-                          _results.push(data.readUInt16());
-                      }
-                      return _results;
-                  })();
-                  count = (this.length - data.pos + this.offset) / 2;
-                  glyphIds = (function () {
-                      var _j, _results;
-                      _results = [];
-                      for (i = _j = 0; 0 <= count ? _j < count : _j > count; i = 0 <= count ? ++_j : --_j) {
-                          _results.push(data.readUInt16());
-                      }
-                      return _results;
-                  })();
-                  for (i = _j = 0, _len = endCode.length; _j < _len; i = ++_j) {
-                      tail = endCode[i];
-                      start = startCode[i];
-                      for (code = _k = start; start <= tail ? _k <= tail : _k >= tail; code = start <= tail ? ++_k : --_k) {
-                          if (idRangeOffset[i] === 0) {
-                              glyphId = code + idDelta[i];
-                          }
-                          else {
-                              index = idRangeOffset[i] / 2 + (code - start) - (segCount - i);
-                              glyphId = glyphIds[index] || 0;
-                              if (glyphId !== 0) {
-                                  glyphId += idDelta[i];
-                              }
-                          }
-                          this.codeMap[code] = glyphId & 0xFFFF;
-                      }
-                  }
-              }
-              data.pos = saveOffset;
-          }
-          CmapEntry.encode = function (charmap, encoding) {
-              var charMap, code, codeMap, codes, delta, deltas, diff, endCode, endCodes, entrySelector, glyphIDs, i, id, indexes, last, map, nextID, offset, old, rangeOffsets, rangeShift, result, searchRange, segCount, segCountX2, startCode, startCodes, startGlyph, subtable, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _len6, _len7, _m, _n, _name, _o, _p, _q;
-              subtable = new Data;
-              codes = Object.keys(charmap).sort(function (a, b) {
-                  return a - b;
-              });
-              switch (encoding) {
-              case 'macroman':
-                  id = 0;
-                  indexes = (function () {
-                      var _i, _results;
-                      _results = [];
-                      for (i = _i = 0; _i < 256; i = ++_i) {
-                          _results.push(0);
-                      }
-                      return _results;
-                  })();
-                  map = {
-                      0: 0
-                  };
-                  codeMap = {};
-                  for (_i = 0, _len = codes.length; _i < _len; _i++) {
-                      code = codes[_i];
-                      if (map[_name = charmap[code]] == null) {
-                          map[_name] = ++id;
-                      }
-                      codeMap[code] = {
-                          old: charmap[code]
-                          , "new": map[charmap[code]]
-                      };
-                      indexes[code] = map[charmap[code]];
-                  }
-                  subtable.writeUInt16(1);
-                  subtable.writeUInt16(0);
-                  subtable.writeUInt32(12);
-                  subtable.writeUInt16(0);
-                  subtable.writeUInt16(262);
-                  subtable.writeUInt16(0);
-                  subtable.write(indexes);
-                  return result = {
-                      charMap: codeMap
-                      , subtable: subtable.data
-                      , maxGlyphID: id + 1
-                  };
-              case 'unicode':
-                  startCodes = [];
-                  endCodes = [];
-                  nextID = 0;
-                  map = {};
-                  charMap = {};
-                  last = diff = null;
-                  for (_j = 0, _len1 = codes.length; _j < _len1; _j++) {
-                      code = codes[_j];
-                      old = charmap[code];
-                      if (map[old] == null) {
-                          map[old] = ++nextID;
-                      }
-                      charMap[code] = {
-                          old: old
-                          , "new": map[old]
-                      };
-                      delta = map[old] - code;
-                      if ((last == null) || delta !== diff) {
-                          if (last) {
-                              endCodes.push(last);
-                          }
-                          startCodes.push(code);
-                          diff = delta;
-                      }
-                      last = code;
-                  }
-                  if (last) {
-                      endCodes.push(last);
-                  }
-                  endCodes.push(0xFFFF);
-                  startCodes.push(0xFFFF);
-                  segCount = startCodes.length;
-                  segCountX2 = segCount * 2;
-                  searchRange = 2 * Math.pow(Math.log(segCount) / Math.LN2, 2);
-                  entrySelector = Math.log(searchRange / 2) / Math.LN2;
-                  rangeShift = 2 * segCount - searchRange;
-                  deltas = [];
-                  rangeOffsets = [];
-                  glyphIDs = [];
-                  for (i = _k = 0, _len2 = startCodes.length; _k < _len2; i = ++_k) {
-                      startCode = startCodes[i];
-                      endCode = endCodes[i];
-                      if (startCode === 0xFFFF) {
-                          deltas.push(0);
-                          rangeOffsets.push(0);
-                          break;
-                      }
-                      startGlyph = charMap[startCode]["new"];
-                      if (startCode - startGlyph >= 0x8000) {
-                          deltas.push(0);
-                          rangeOffsets.push(2 * (glyphIDs.length + segCount - i));
-                          for (code = _l = startCode; startCode <= endCode ? _l <= endCode : _l >= endCode; code = startCode <= endCode ? ++_l : --_l) {
-                              glyphIDs.push(charMap[code]["new"]);
-                          }
-                      }
-                      else {
-                          deltas.push(startGlyph - startCode);
-                          rangeOffsets.push(0);
-                      }
-                  }
-                  subtable.writeUInt16(3);
-                  subtable.writeUInt16(1);
-                  subtable.writeUInt32(12);
-                  subtable.writeUInt16(4);
-                  subtable.writeUInt16(16 + segCount * 8 + glyphIDs.length * 2);
-                  subtable.writeUInt16(0);
-                  subtable.writeUInt16(segCountX2);
-                  subtable.writeUInt16(searchRange);
-                  subtable.writeUInt16(entrySelector);
-                  subtable.writeUInt16(rangeShift);
-                  for (_m = 0, _len3 = endCodes.length; _m < _len3; _m++) {
-                      code = endCodes[_m];
-                      subtable.writeUInt16(code);
-                  }
-                  subtable.writeUInt16(0);
-                  for (_n = 0, _len4 = startCodes.length; _n < _len4; _n++) {
-                      code = startCodes[_n];
-                      subtable.writeUInt16(code);
-                  }
-                  for (_o = 0, _len5 = deltas.length; _o < _len5; _o++) {
-                      delta = deltas[_o];
-                      subtable.writeUInt16(delta);
-                  }
-                  for (_p = 0, _len6 = rangeOffsets.length; _p < _len6; _p++) {
-                      offset = rangeOffsets[_p];
-                      subtable.writeUInt16(offset);
-                  }
-                  for (_q = 0, _len7 = glyphIDs.length; _q < _len7; _q++) {
-                      id = glyphIDs[_q];
-                      subtable.writeUInt16(id);
+
+    var supportsArrayBuffer = jsPDFAPI.__addimage__.supportsArrayBuffer = function () {
+      return typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined";
+    };
+    /**
+     * Tests supplied object to determine if ArrayBuffer
+     *
+     * @name isArrayBuffer
+     * @function
+     * @param {Object} object an Object
+     *
+     * @returns {boolean}
+     */
+
+
+    jsPDFAPI.__addimage__.isArrayBuffer = function (object) {
+      return supportsArrayBuffer() && object instanceof ArrayBuffer;
+    };
+    /**
+     * Tests supplied object to determine if it implements the ArrayBufferView (TypedArray) interface
+     *
+     * @name isArrayBufferView
+     * @function
+     * @param {Object} object an Object
+     * @returns {boolean}
+     */
+
+
+    var isArrayBufferView = jsPDFAPI.__addimage__.isArrayBufferView = function (object) {
+      return supportsArrayBuffer() && typeof Uint32Array !== "undefined" && (object instanceof Int8Array || object instanceof Uint8Array || typeof Uint8ClampedArray !== "undefined" && object instanceof Uint8ClampedArray || object instanceof Int16Array || object instanceof Uint16Array || object instanceof Int32Array || object instanceof Uint32Array || object instanceof Float32Array || object instanceof Float64Array);
+    };
+    /**
+     * Convert Binary String to ArrayBuffer
+     *
+     * @name binaryStringToUint8Array
+     * @public
+     * @function
+     * @param {string} BinaryString with ImageData
+     * @returns {Uint8Array}
+     */
+
+
+    var binaryStringToUint8Array = jsPDFAPI.__addimage__.binaryStringToUint8Array = function (binary_string) {
+      var len = binary_string.length;
+      var bytes = new Uint8Array(len);
+
+      for (var i = 0; i < len; i++) {
+        bytes[i] = binary_string.charCodeAt(i);
+      }
+
+      return bytes;
+    };
+    /**
+     * Convert the Buffer to a Binary String
+     *
+     * @name arrayBufferToBinaryString
+     * @public
+     * @function
+     * @param {ArrayBuffer|ArrayBufferView} ArrayBuffer buffer or bufferView with ImageData
+     *
+     * @returns {String}
+     */
+
+
+    var arrayBufferToBinaryString = jsPDFAPI.__addimage__.arrayBufferToBinaryString = function (buffer) {
+      var out = ""; // There are calls with both ArrayBuffer and already converted Uint8Array or other BufferView.
+      // Do not copy the array if input is already an array.
+
+      var buf = isArrayBufferView(buffer) ? buffer : new Uint8Array(buffer);
+
+      for (var i = 0; i < buf.length; i += ARRAY_APPLY_BATCH) {
+        // Limit the amount of characters being parsed to prevent overflow.
+        // Note that while TextDecoder would be faster, it does not have the same
+        // functionality as fromCharCode with any provided encodings as of 3/2021.
+        out += String.fromCharCode.apply(null, buf.subarray(i, i + ARRAY_APPLY_BATCH));
+      }
+
+      return out;
+    };
+    /**
+     * Possible parameter for addImage, an RGBA buffer with size.
+     *
+     * @typedef {Object} RGBAData
+     * @property {Uint8ClampedArray} data - Single dimensional array of RGBA values. For example from canvas getImageData.
+     * @property {number} width - Image width as the data does not carry this information in itself.
+     * @property {number} height - Image height as the data does not carry this information in itself.
+     */
+
+    /**
+     * Adds an Image to the PDF.
+     *
+     * @name addImage
+     * @public
+     * @function
+     * @param {string|HTMLImageElement|HTMLCanvasElement|Uint8Array|RGBAData} imageData imageData as base64 encoded DataUrl or Image-HTMLElement or Canvas-HTMLElement or object containing RGBA array (like output from canvas.getImageData).
+     * @param {string} format format of file if filetype-recognition fails or in case of a Canvas-Element needs to be specified (default for Canvas is JPEG), e.g. 'JPEG', 'PNG', 'WEBP'
+     * @param {number} x x Coordinate (in units declared at inception of PDF document) against left edge of the page
+     * @param {number} y y Coordinate (in units declared at inception of PDF document) against upper edge of the page
+     * @param {number} width width of the image (in units declared at inception of PDF document)
+     * @param {number} height height of the Image (in units declared at inception of PDF document)
+     * @param {string} alias alias of the image (if used multiple times)
+     * @param {string} compression compression of the generated JPEG, can have the values 'NONE', 'FAST', 'MEDIUM' and 'SLOW'
+     * @param {number} rotation rotation of the image in degrees (0-359)
+     *
+     * @returns jsPDF
+     */
+
+
+    jsPDFAPI.addImage = function () {
+      var imageData, format, x, y, w, h, alias, compression, rotation;
+      imageData = arguments[0];
+
+      if (typeof arguments[1] === "number") {
+        format = UNKNOWN;
+        x = arguments[1];
+        y = arguments[2];
+        w = arguments[3];
+        h = arguments[4];
+        alias = arguments[5];
+        compression = arguments[6];
+        rotation = arguments[7];
+      } else {
+        format = arguments[1];
+        x = arguments[2];
+        y = arguments[3];
+        w = arguments[4];
+        h = arguments[5];
+        alias = arguments[6];
+        compression = arguments[7];
+        rotation = arguments[8];
+      }
+
+      if (_typeof(imageData) === "object" && !isDOMElement(imageData) && "imageData" in imageData) {
+        var options = imageData;
+        imageData = options.imageData;
+        format = options.format || format || UNKNOWN;
+        x = options.x || x || 0;
+        y = options.y || y || 0;
+        w = options.w || options.width || w;
+        h = options.h || options.height || h;
+        alias = options.alias || alias;
+        compression = options.compression || compression;
+        rotation = options.rotation || options.angle || rotation;
+      } //If compression is not explicitly set, determine if we should use compression
+
+
+      var filter = this.internal.getFilters();
+
+      if (compression === undefined && filter.indexOf("FlateEncode") !== -1) {
+        compression = "SLOW";
+      }
+
+      if (isNaN(x) || isNaN(y)) {
+        throw new Error("Invalid coordinates passed to jsPDF.addImage");
+      }
+
+      initialize.call(this);
+      var image = processImageData.call(this, imageData, format, alias, compression);
+      writeImageToPDF.call(this, x, y, w, h, image, rotation);
+      return this;
+    };
+
+    var processImageData = function processImageData(imageData, format, alias, compression) {
+      var result, dataAsBinaryString;
+
+      if (typeof imageData === "string" && getImageFileTypeByImageData(imageData) === UNKNOWN) {
+        imageData = unescape(imageData);
+        var tmpImageData = convertBase64ToBinaryString(imageData, false);
+
+        if (tmpImageData !== "") {
+          imageData = tmpImageData;
+        } else {
+          tmpImageData = jsPDFAPI.loadFile(imageData, true);
+
+          if (tmpImageData !== undefined) {
+            imageData = tmpImageData;
+          }
+        }
+      }
+
+      if (isDOMElement(imageData)) {
+        imageData = getImageDataFromElement(imageData, format);
+      }
+
+      format = getImageFileTypeByImageData(imageData, format);
+
+      if (!isImageTypeSupported(format)) {
+        throw new Error("addImage does not support files of type '" + format + "', please ensure that a plugin for '" + format + "' support is added.");
+      } // now do the heavy lifting
+
+
+      if (notDefined(alias)) {
+        alias = generateAliasFromImageData(imageData);
+      }
+
+      result = checkImagesForAlias.call(this, alias);
+
+      if (!result) {
+        if (supportsArrayBuffer()) {
+          // no need to convert if imageData is already uint8array
+          if (!(imageData instanceof Uint8Array) && format !== "RGBA") {
+            dataAsBinaryString = imageData;
+            imageData = binaryStringToUint8Array(imageData);
+          }
+        }
+
+        result = this["process" + format.toUpperCase()](imageData, getImageIndex.call(this), alias, checkCompressValue(compression), dataAsBinaryString);
+      }
+
+      if (!result) {
+        throw new Error("An unknown error occurred whilst processing the image.");
+      }
+
+      return result;
+    };
+    /**
+     * @name convertBase64ToBinaryString
+     * @function
+     * @param {string} stringData
+     * @returns {string} binary string
+     */
+
+
+    var convertBase64ToBinaryString = jsPDFAPI.__addimage__.convertBase64ToBinaryString = function (stringData, throwError) {
+      throwError = typeof throwError === "boolean" ? throwError : true;
+      var base64Info;
+      var imageData = "";
+      var rawData;
+
+      if (typeof stringData === "string") {
+        base64Info = extractImageFromDataUrl(stringData);
+        rawData = base64Info !== null ? base64Info.data : stringData;
+
+        try {
+          imageData = atob(rawData);
+        } catch (e) {
+          if (throwError) {
+            if (!validateStringAsBase64(rawData)) {
+              throw new Error("Supplied Data is not a valid base64-String jsPDF.convertBase64ToBinaryString ");
+            } else {
+              throw new Error("atob-Error in jsPDF.convertBase64ToBinaryString " + e.message);
+            }
+          }
+        }
+      }
+
+      return imageData;
+    };
+    /**
+     * @name getImageProperties
+     * @function
+     * @param {Object} imageData
+     * @returns {Object}
+     */
+
+
+    jsPDFAPI.getImageProperties = function (imageData) {
+      var image;
+      var tmpImageData = "";
+      var format;
+
+      if (isDOMElement(imageData)) {
+        imageData = getImageDataFromElement(imageData);
+      }
+
+      if (typeof imageData === "string" && getImageFileTypeByImageData(imageData) === UNKNOWN) {
+        tmpImageData = convertBase64ToBinaryString(imageData, false);
+
+        if (tmpImageData === "") {
+          tmpImageData = jsPDFAPI.loadFile(imageData) || "";
+        }
+
+        imageData = tmpImageData;
+      }
+
+      format = getImageFileTypeByImageData(imageData);
+
+      if (!isImageTypeSupported(format)) {
+        throw new Error("addImage does not support files of type '" + format + "', please ensure that a plugin for '" + format + "' support is added.");
+      }
+
+      if (supportsArrayBuffer() && !(imageData instanceof Uint8Array)) {
+        imageData = binaryStringToUint8Array(imageData);
+      }
+
+      image = this["process" + format.toUpperCase()](imageData);
+
+      if (!image) {
+        throw new Error("An unknown error occurred whilst processing the image");
+      }
+
+      image.fileType = format;
+      return image;
+    };
+  })(jsPDF.API);
+
+  /**
+   * @license
+   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+
+  (function (jsPDFAPI) {
+
+    var notEmpty = function notEmpty(obj) {
+      if (typeof obj != "undefined") {
+        if (obj != "") {
+          return true;
+        }
+      }
+    };
+
+    jsPDF.API.events.push(["addPage", function (addPageData) {
+      var pageInfo = this.internal.getPageInfo(addPageData.pageNumber);
+      pageInfo.pageContext.annotations = [];
+    }]);
+    jsPDFAPI.events.push(["putPage", function (putPageData) {
+      var getHorizontalCoordinateString = this.internal.getCoordinateString;
+      var getVerticalCoordinateString = this.internal.getVerticalCoordinateString;
+      var pageInfo = this.internal.getPageInfoByObjId(putPageData.objId);
+      var pageAnnos = putPageData.pageContext.annotations;
+      var anno, rect, line;
+      var found = false;
+
+      for (var a = 0; a < pageAnnos.length && !found; a++) {
+        anno = pageAnnos[a];
+
+        switch (anno.type) {
+          case "link":
+            if (notEmpty(anno.options.url) || notEmpty(anno.options.pageNumber)) {
+              found = true;
+            }
+
+            break;
+
+          case "reference":
+          case "text":
+          case "freetext":
+            found = true;
+            break;
+        }
+      }
+
+      if (found == false) {
+        return;
+      }
+
+      this.internal.write("/Annots [");
+
+      for (var i = 0; i < pageAnnos.length; i++) {
+        anno = pageAnnos[i];
+        var escape = this.internal.pdfEscape;
+        var encryptor = this.internal.getEncryptor(putPageData.objId);
+
+        switch (anno.type) {
+          case "reference":
+            // References to Widget Annotations (for AcroForm Fields)
+            this.internal.write(" " + anno.object.objId + " 0 R ");
+            break;
+
+          case "text":
+            // Create a an object for both the text and the popup
+            var objText = this.internal.newAdditionalObject();
+            var objPopup = this.internal.newAdditionalObject();
+            var encryptorText = this.internal.getEncryptor(objText.objId);
+            var title = anno.title || "Note";
+            rect = "/Rect [" + getHorizontalCoordinateString(anno.bounds.x) + " " + getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) + " " + getHorizontalCoordinateString(anno.bounds.x + anno.bounds.w) + " " + getVerticalCoordinateString(anno.bounds.y) + "] ";
+            line = "<</Type /Annot /Subtype /" + "Text" + " " + rect + "/Contents (" + escape(encryptorText(anno.contents)) + ")";
+            line += " /Popup " + objPopup.objId + " 0 R";
+            line += " /P " + pageInfo.objId + " 0 R";
+            line += " /T (" + escape(encryptorText(title)) + ") >>";
+            objText.content = line;
+            var parent = objText.objId + " 0 R";
+            var popoff = 30;
+            rect = "/Rect [" + getHorizontalCoordinateString(anno.bounds.x + popoff) + " " + getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) + " " + getHorizontalCoordinateString(anno.bounds.x + anno.bounds.w + popoff) + " " + getVerticalCoordinateString(anno.bounds.y) + "] ";
+            line = "<</Type /Annot /Subtype /" + "Popup" + " " + rect + " /Parent " + parent;
+
+            if (anno.open) {
+              line += " /Open true";
+            }
+
+            line += " >>";
+            objPopup.content = line;
+            this.internal.write(objText.objId, "0 R", objPopup.objId, "0 R");
+            break;
+
+          case "freetext":
+            rect = "/Rect [" + getHorizontalCoordinateString(anno.bounds.x) + " " + getVerticalCoordinateString(anno.bounds.y) + " " + getHorizontalCoordinateString(anno.bounds.x + anno.bounds.w) + " " + getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) + "] ";
+            var color = anno.color || "#000000";
+            line = "<</Type /Annot /Subtype /" + "FreeText" + " " + rect + "/Contents (" + escape(encryptor(anno.contents)) + ")";
+            line += " /DS(font: Helvetica,sans-serif 12.0pt; text-align:left; color:#" + color + ")";
+            line += " /Border [0 0 0]";
+            line += " >>";
+            this.internal.write(line);
+            break;
+
+          case "link":
+            if (anno.options.name) {
+              var loc = this.annotations._nameMap[anno.options.name];
+              anno.options.pageNumber = loc.page;
+              anno.options.top = loc.y;
+            } else {
+              if (!anno.options.top) {
+                anno.options.top = 0;
+              }
+            }
+
+            rect = "/Rect [" + anno.finalBounds.x + " " + anno.finalBounds.y + " " + anno.finalBounds.w + " " + anno.finalBounds.h + "] ";
+            line = "";
+
+            if (anno.options.url) {
+              line = "<</Type /Annot /Subtype /Link " + rect + "/Border [0 0 0] /A <</S /URI /URI (" + escape(encryptor(anno.options.url)) + ") >>";
+            } else if (anno.options.pageNumber) {
+              // first page is 0
+              var info = this.internal.getPageInfo(anno.options.pageNumber);
+              line = "<</Type /Annot /Subtype /Link " + rect + "/Border [0 0 0] /Dest [" + info.objId + " 0 R";
+              anno.options.magFactor = anno.options.magFactor || "XYZ";
+
+              switch (anno.options.magFactor) {
+                case "Fit":
+                  line += " /Fit]";
+                  break;
+
+                case "FitH":
+                  line += " /FitH " + anno.options.top + "]";
+                  break;
+
+                case "FitV":
+                  anno.options.left = anno.options.left || 0;
+                  line += " /FitV " + anno.options.left + "]";
+                  break;
+
+                case "XYZ":
+                default:
+                  var top = getVerticalCoordinateString(anno.options.top);
+                  anno.options.left = anno.options.left || 0; // 0 or null zoom will not change zoom factor
+
+                  if (typeof anno.options.zoom === "undefined") {
+                    anno.options.zoom = 0;
                   }
-                  return result = {
-                      charMap: charMap
-                      , subtable: subtable.data
-                      , maxGlyphID: nextID + 1
-                  };
+
+                  line += " /XYZ " + anno.options.left + " " + top + " " + anno.options.zoom + "]";
+                  break;
+              }
+            }
+
+            if (line != "") {
+              line += " >>";
+              this.internal.write(line);
+            }
+
+            break;
+        }
+      }
+
+      this.internal.write("]");
+    }]);
+    /**
+     * @name createAnnotation
+     * @function
+     * @param {Object} options
+     */
+
+    jsPDFAPI.createAnnotation = function (options) {
+      var pageInfo = this.internal.getCurrentPageInfo();
+
+      switch (options.type) {
+        case "link":
+          this.link(options.bounds.x, options.bounds.y, options.bounds.w, options.bounds.h, options);
+          break;
+
+        case "text":
+        case "freetext":
+          pageInfo.pageContext.annotations.push(options);
+          break;
+      }
+    };
+    /**
+     * Create a link
+     *
+     * valid options
+     * <li> pageNumber or url [required]
+     * <p>If pageNumber is specified, top and zoom may also be specified</p>
+     * @name link
+     * @function
+     * @param {number} x
+     * @param {number} y
+     * @param {number} w
+     * @param {number} h
+     * @param {Object} options
+     */
+
+
+    jsPDFAPI.link = function (x, y, w, h, options) {
+      var pageInfo = this.internal.getCurrentPageInfo();
+      var getHorizontalCoordinateString = this.internal.getCoordinateString;
+      var getVerticalCoordinateString = this.internal.getVerticalCoordinateString;
+      pageInfo.pageContext.annotations.push({
+        finalBounds: {
+          x: getHorizontalCoordinateString(x),
+          y: getVerticalCoordinateString(y),
+          w: getHorizontalCoordinateString(x + w),
+          h: getVerticalCoordinateString(y + h)
+        },
+        options: options,
+        type: "link"
+      });
+    };
+    /**
+     * Currently only supports single line text.
+     * Returns the width of the text/link
+     *
+     * @name textWithLink
+     * @function
+     * @param {string} text
+     * @param {number} x
+     * @param {number} y
+     * @param {Object} options
+     * @returns {number} width the width of the text/link
+     */
+
+
+    jsPDFAPI.textWithLink = function (text, x, y, options) {
+      var totalLineWidth = this.getTextWidth(text);
+      var lineHeight = this.internal.getLineHeight() / this.internal.scaleFactor;
+      var linkHeight, linkWidth; // Checking if maxWidth option is passed to determine lineWidth and number of lines for each line
+
+      if (options.maxWidth !== undefined) {
+        var maxWidth = options.maxWidth;
+        linkWidth = maxWidth;
+        var numOfLines = this.splitTextToSize(text, linkWidth).length;
+        linkHeight = Math.ceil(lineHeight * numOfLines);
+      } else {
+        linkWidth = totalLineWidth;
+        linkHeight = lineHeight;
+      }
+
+      this.text(text, x, y, options); //TODO We really need the text baseline height to do this correctly.
+      // Or ability to draw text on top, bottom, center, or baseline.
+
+      y += lineHeight * 0.2; //handle x position based on the align option
+
+      if (options.align === "center") {
+        x = x - totalLineWidth / 2; //since starting from center move the x position by half of text width
+      }
+
+      if (options.align === "right") {
+        x = x - totalLineWidth;
+      }
+
+      this.link(x, y - lineHeight, linkWidth, linkHeight, options);
+      return totalLineWidth;
+    }; //TODO move into external library
+
+    /**
+     * @name getTextWidth
+     * @function
+     * @param {string} text
+     * @returns {number} txtWidth
+     */
+
+
+    jsPDFAPI.getTextWidth = function (text) {
+      var fontSize = this.internal.getFontSize();
+      var txtWidth = this.getStringUnitWidth(text) * fontSize / this.internal.scaleFactor;
+      return txtWidth;
+    };
+
+    return this;
+  })(jsPDF.API);
+
+  /**
+   * @license
+   * Copyright (c) 2017 Aras Abbasi
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+  /**
+   * jsPDF arabic parser PlugIn
+   *
+   * @name arabic
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+    /**
+     * Arabic shape substitutions: char code => (isolated, final, initial, medial).
+     * Arabic Substition A
+     */
+
+    var arabicSubstitionA = {
+      0x0621: [0xfe80],
+      // ARABIC LETTER HAMZA
+      0x0622: [0xfe81, 0xfe82],
+      // ARABIC LETTER ALEF WITH MADDA ABOVE
+      0x0623: [0xfe83, 0xfe84],
+      // ARABIC LETTER ALEF WITH HAMZA ABOVE
+      0x0624: [0xfe85, 0xfe86],
+      // ARABIC LETTER WAW WITH HAMZA ABOVE
+      0x0625: [0xfe87, 0xfe88],
+      // ARABIC LETTER ALEF WITH HAMZA BELOW
+      0x0626: [0xfe89, 0xfe8a, 0xfe8b, 0xfe8c],
+      // ARABIC LETTER YEH WITH HAMZA ABOVE
+      0x0627: [0xfe8d, 0xfe8e],
+      // ARABIC LETTER ALEF
+      0x0628: [0xfe8f, 0xfe90, 0xfe91, 0xfe92],
+      // ARABIC LETTER BEH
+      0x0629: [0xfe93, 0xfe94],
+      // ARABIC LETTER TEH MARBUTA
+      0x062a: [0xfe95, 0xfe96, 0xfe97, 0xfe98],
+      // ARABIC LETTER TEH
+      0x062b: [0xfe99, 0xfe9a, 0xfe9b, 0xfe9c],
+      // ARABIC LETTER THEH
+      0x062c: [0xfe9d, 0xfe9e, 0xfe9f, 0xfea0],
+      // ARABIC LETTER JEEM
+      0x062d: [0xfea1, 0xfea2, 0xfea3, 0xfea4],
+      // ARABIC LETTER HAH
+      0x062e: [0xfea5, 0xfea6, 0xfea7, 0xfea8],
+      // ARABIC LETTER KHAH
+      0x062f: [0xfea9, 0xfeaa],
+      // ARABIC LETTER DAL
+      0x0630: [0xfeab, 0xfeac],
+      // ARABIC LETTER THAL
+      0x0631: [0xfead, 0xfeae],
+      // ARABIC LETTER REH
+      0x0632: [0xfeaf, 0xfeb0],
+      // ARABIC LETTER ZAIN
+      0x0633: [0xfeb1, 0xfeb2, 0xfeb3, 0xfeb4],
+      // ARABIC LETTER SEEN
+      0x0634: [0xfeb5, 0xfeb6, 0xfeb7, 0xfeb8],
+      // ARABIC LETTER SHEEN
+      0x0635: [0xfeb9, 0xfeba, 0xfebb, 0xfebc],
+      // ARABIC LETTER SAD
+      0x0636: [0xfebd, 0xfebe, 0xfebf, 0xfec0],
+      // ARABIC LETTER DAD
+      0x0637: [0xfec1, 0xfec2, 0xfec3, 0xfec4],
+      // ARABIC LETTER TAH
+      0x0638: [0xfec5, 0xfec6, 0xfec7, 0xfec8],
+      // ARABIC LETTER ZAH
+      0x0639: [0xfec9, 0xfeca, 0xfecb, 0xfecc],
+      // ARABIC LETTER AIN
+      0x063a: [0xfecd, 0xfece, 0xfecf, 0xfed0],
+      // ARABIC LETTER GHAIN
+      0x0641: [0xfed1, 0xfed2, 0xfed3, 0xfed4],
+      // ARABIC LETTER FEH
+      0x0642: [0xfed5, 0xfed6, 0xfed7, 0xfed8],
+      // ARABIC LETTER QAF
+      0x0643: [0xfed9, 0xfeda, 0xfedb, 0xfedc],
+      // ARABIC LETTER KAF
+      0x0644: [0xfedd, 0xfede, 0xfedf, 0xfee0],
+      // ARABIC LETTER LAM
+      0x0645: [0xfee1, 0xfee2, 0xfee3, 0xfee4],
+      // ARABIC LETTER MEEM
+      0x0646: [0xfee5, 0xfee6, 0xfee7, 0xfee8],
+      // ARABIC LETTER NOON
+      0x0647: [0xfee9, 0xfeea, 0xfeeb, 0xfeec],
+      // ARABIC LETTER HEH
+      0x0648: [0xfeed, 0xfeee],
+      // ARABIC LETTER WAW
+      0x0649: [0xfeef, 0xfef0, 64488, 64489],
+      // ARABIC LETTER ALEF MAKSURA
+      0x064a: [0xfef1, 0xfef2, 0xfef3, 0xfef4],
+      // ARABIC LETTER YEH
+      0x0671: [0xfb50, 0xfb51],
+      // ARABIC LETTER ALEF WASLA
+      0x0677: [0xfbdd],
+      // ARABIC LETTER U WITH HAMZA ABOVE
+      0x0679: [0xfb66, 0xfb67, 0xfb68, 0xfb69],
+      // ARABIC LETTER TTEH
+      0x067a: [0xfb5e, 0xfb5f, 0xfb60, 0xfb61],
+      // ARABIC LETTER TTEHEH
+      0x067b: [0xfb52, 0xfb53, 0xfb54, 0xfb55],
+      // ARABIC LETTER BEEH
+      0x067e: [0xfb56, 0xfb57, 0xfb58, 0xfb59],
+      // ARABIC LETTER PEH
+      0x067f: [0xfb62, 0xfb63, 0xfb64, 0xfb65],
+      // ARABIC LETTER TEHEH
+      0x0680: [0xfb5a, 0xfb5b, 0xfb5c, 0xfb5d],
+      // ARABIC LETTER BEHEH
+      0x0683: [0xfb76, 0xfb77, 0xfb78, 0xfb79],
+      // ARABIC LETTER NYEH
+      0x0684: [0xfb72, 0xfb73, 0xfb74, 0xfb75],
+      // ARABIC LETTER DYEH
+      0x0686: [0xfb7a, 0xfb7b, 0xfb7c, 0xfb7d],
+      // ARABIC LETTER TCHEH
+      0x0687: [0xfb7e, 0xfb7f, 0xfb80, 0xfb81],
+      // ARABIC LETTER TCHEHEH
+      0x0688: [0xfb88, 0xfb89],
+      // ARABIC LETTER DDAL
+      0x068c: [0xfb84, 0xfb85],
+      // ARABIC LETTER DAHAL
+      0x068d: [0xfb82, 0xfb83],
+      // ARABIC LETTER DDAHAL
+      0x068e: [0xfb86, 0xfb87],
+      // ARABIC LETTER DUL
+      0x0691: [0xfb8c, 0xfb8d],
+      // ARABIC LETTER RREH
+      0x0698: [0xfb8a, 0xfb8b],
+      // ARABIC LETTER JEH
+      0x06a4: [0xfb6a, 0xfb6b, 0xfb6c, 0xfb6d],
+      // ARABIC LETTER VEH
+      0x06a6: [0xfb6e, 0xfb6f, 0xfb70, 0xfb71],
+      // ARABIC LETTER PEHEH
+      0x06a9: [0xfb8e, 0xfb8f, 0xfb90, 0xfb91],
+      // ARABIC LETTER KEHEH
+      0x06ad: [0xfbd3, 0xfbd4, 0xfbd5, 0xfbd6],
+      // ARABIC LETTER NG
+      0x06af: [0xfb92, 0xfb93, 0xfb94, 0xfb95],
+      // ARABIC LETTER GAF
+      0x06b1: [0xfb9a, 0xfb9b, 0xfb9c, 0xfb9d],
+      // ARABIC LETTER NGOEH
+      0x06b3: [0xfb96, 0xfb97, 0xfb98, 0xfb99],
+      // ARABIC LETTER GUEH
+      0x06ba: [0xfb9e, 0xfb9f],
+      // ARABIC LETTER NOON GHUNNA
+      0x06bb: [0xfba0, 0xfba1, 0xfba2, 0xfba3],
+      // ARABIC LETTER RNOON
+      0x06be: [0xfbaa, 0xfbab, 0xfbac, 0xfbad],
+      // ARABIC LETTER HEH DOACHASHMEE
+      0x06c0: [0xfba4, 0xfba5],
+      // ARABIC LETTER HEH WITH YEH ABOVE
+      0x06c1: [0xfba6, 0xfba7, 0xfba8, 0xfba9],
+      // ARABIC LETTER HEH GOAL
+      0x06c5: [0xfbe0, 0xfbe1],
+      // ARABIC LETTER KIRGHIZ OE
+      0x06c6: [0xfbd9, 0xfbda],
+      // ARABIC LETTER OE
+      0x06c7: [0xfbd7, 0xfbd8],
+      // ARABIC LETTER U
+      0x06c8: [0xfbdb, 0xfbdc],
+      // ARABIC LETTER YU
+      0x06c9: [0xfbe2, 0xfbe3],
+      // ARABIC LETTER KIRGHIZ YU
+      0x06cb: [0xfbde, 0xfbdf],
+      // ARABIC LETTER VE
+      0x06cc: [0xfbfc, 0xfbfd, 0xfbfe, 0xfbff],
+      // ARABIC LETTER FARSI YEH
+      0x06d0: [0xfbe4, 0xfbe5, 0xfbe6, 0xfbe7],
+      //ARABIC LETTER E
+      0x06d2: [0xfbae, 0xfbaf],
+      // ARABIC LETTER YEH BARREE
+      0x06d3: [0xfbb0, 0xfbb1] // ARABIC LETTER YEH BARREE WITH HAMZA ABOVE
+
+    };
+    /*
+      var ligaturesSubstitutionA = {
+          0xFBEA: []// ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM
+      };
+      */
+
+    var ligatures = {
+      0xfedf: {
+        0xfe82: 0xfef5,
+        // ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
+        0xfe84: 0xfef7,
+        // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
+        0xfe88: 0xfef9,
+        // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM
+        0xfe8e: 0xfefb // ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
+
+      },
+      0xfee0: {
+        0xfe82: 0xfef6,
+        // ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM
+        0xfe84: 0xfef8,
+        // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM
+        0xfe88: 0xfefa,
+        // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM
+        0xfe8e: 0xfefc // ARABIC LIGATURE LAM WITH ALEF FINAL FORM
+
+      },
+      0xfe8d: {
+        0xfedf: {
+          0xfee0: {
+            0xfeea: 0xfdf2
+          }
+        }
+      },
+      // ALLAH
+      0x0651: {
+        0x064c: 0xfc5e,
+        // Shadda + Dammatan
+        0x064d: 0xfc5f,
+        // Shadda + Kasratan
+        0x064e: 0xfc60,
+        // Shadda + Fatha
+        0x064f: 0xfc61,
+        // Shadda + Damma
+        0x0650: 0xfc62 // Shadda + Kasra
+
+      }
+    };
+    var arabic_diacritics = {
+      1612: 64606,
+      // Shadda + Dammatan
+      1613: 64607,
+      // Shadda + Kasratan
+      1614: 64608,
+      // Shadda + Fatha
+      1615: 64609,
+      // Shadda + Damma
+      1616: 64610 // Shadda + Kasra
+
+    };
+    var alfletter = [1570, 1571, 1573, 1575];
+    var noChangeInForm = -1;
+    var isolatedForm = 0;
+    var finalForm = 1;
+    var initialForm = 2;
+    var medialForm = 3;
+    jsPDFAPI.__arabicParser__ = {}; //private
+
+    var isInArabicSubstitutionA = jsPDFAPI.__arabicParser__.isInArabicSubstitutionA = function (letter) {
+      return typeof arabicSubstitionA[letter.charCodeAt(0)] !== "undefined";
+    };
+
+    var isArabicLetter = jsPDFAPI.__arabicParser__.isArabicLetter = function (letter) {
+      return typeof letter === "string" && /^[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]+$/.test(letter);
+    };
+
+    var isArabicEndLetter = jsPDFAPI.__arabicParser__.isArabicEndLetter = function (letter) {
+      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length <= 2;
+    };
+
+    var isArabicAlfLetter = jsPDFAPI.__arabicParser__.isArabicAlfLetter = function (letter) {
+      return isArabicLetter(letter) && alfletter.indexOf(letter.charCodeAt(0)) >= 0;
+    };
+
+    jsPDFAPI.__arabicParser__.arabicLetterHasIsolatedForm = function (letter) {
+      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length >= 1;
+    };
+
+    var arabicLetterHasFinalForm = jsPDFAPI.__arabicParser__.arabicLetterHasFinalForm = function (letter) {
+      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length >= 2;
+    };
+
+    jsPDFAPI.__arabicParser__.arabicLetterHasInitialForm = function (letter) {
+      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length >= 3;
+    };
+
+    var arabicLetterHasMedialForm = jsPDFAPI.__arabicParser__.arabicLetterHasMedialForm = function (letter) {
+      return isArabicLetter(letter) && isInArabicSubstitutionA(letter) && arabicSubstitionA[letter.charCodeAt(0)].length == 4;
+    };
+
+    var resolveLigatures = jsPDFAPI.__arabicParser__.resolveLigatures = function (letters) {
+      var i = 0;
+      var tmpLigatures = ligatures;
+      var result = "";
+      var effectedLetters = 0;
+
+      for (i = 0; i < letters.length; i += 1) {
+        if (typeof tmpLigatures[letters.charCodeAt(i)] !== "undefined") {
+          effectedLetters++;
+          tmpLigatures = tmpLigatures[letters.charCodeAt(i)];
+
+          if (typeof tmpLigatures === "number") {
+            result += String.fromCharCode(tmpLigatures);
+            tmpLigatures = ligatures;
+            effectedLetters = 0;
+          }
+
+          if (i === letters.length - 1) {
+            tmpLigatures = ligatures;
+            result += letters.charAt(i - (effectedLetters - 1));
+            i = i - (effectedLetters - 1);
+            effectedLetters = 0;
+          }
+        } else {
+          tmpLigatures = ligatures;
+          result += letters.charAt(i - effectedLetters);
+          i = i - effectedLetters;
+          effectedLetters = 0;
+        }
+      }
+
+      return result;
+    };
+
+    jsPDFAPI.__arabicParser__.isArabicDiacritic = function (letter) {
+      return letter !== undefined && arabic_diacritics[letter.charCodeAt(0)] !== undefined;
+    };
+
+    var getCorrectForm = jsPDFAPI.__arabicParser__.getCorrectForm = function (currentChar, beforeChar, nextChar) {
+      if (!isArabicLetter(currentChar)) {
+        return -1;
+      }
+
+      if (isInArabicSubstitutionA(currentChar) === false) {
+        return noChangeInForm;
+      }
+
+      if (!arabicLetterHasFinalForm(currentChar) || !isArabicLetter(beforeChar) && !isArabicLetter(nextChar) || !isArabicLetter(nextChar) && isArabicEndLetter(beforeChar) || isArabicEndLetter(currentChar) && !isArabicLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicAlfLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicEndLetter(beforeChar)) {
+        return isolatedForm;
+      }
+
+      if (arabicLetterHasMedialForm(currentChar) && isArabicLetter(beforeChar) && !isArabicEndLetter(beforeChar) && isArabicLetter(nextChar) && arabicLetterHasFinalForm(nextChar)) {
+        return medialForm;
+      }
+
+      if (isArabicEndLetter(currentChar) || !isArabicLetter(nextChar)) {
+        return finalForm;
+      }
+
+      return initialForm;
+    };
+    /**
+     * @name processArabic
+     * @function
+     * @param {string} text
+     * @returns {string}
+     */
+
+
+    var parseArabic = function parseArabic(text) {
+      text = text || "";
+      var result = "";
+      var i = 0;
+      var j = 0;
+      var position = 0;
+      var currentLetter = "";
+      var prevLetter = "";
+      var nextLetter = "";
+      var words = text.split("\\s+");
+      var newWords = [];
+
+      for (i = 0; i < words.length; i += 1) {
+        newWords.push("");
+
+        for (j = 0; j < words[i].length; j += 1) {
+          currentLetter = words[i][j];
+          prevLetter = words[i][j - 1];
+          nextLetter = words[i][j + 1];
+
+          if (isArabicLetter(currentLetter)) {
+            position = getCorrectForm(currentLetter, prevLetter, nextLetter);
+
+            if (position !== -1) {
+              newWords[i] += String.fromCharCode(arabicSubstitionA[currentLetter.charCodeAt(0)][position]);
+            } else {
+              newWords[i] += currentLetter;
+            }
+          } else {
+            newWords[i] += currentLetter;
+          }
+        }
+
+        newWords[i] = resolveLigatures(newWords[i]);
+      }
+
+      result = newWords.join(" ");
+      return result;
+    };
+
+    var processArabic = jsPDFAPI.__arabicParser__.processArabic = jsPDFAPI.processArabic = function () {
+      var text = typeof arguments[0] === "string" ? arguments[0] : arguments[0].text;
+      var tmpText = [];
+      var result;
+
+      if (Array.isArray(text)) {
+        var i = 0;
+        tmpText = [];
+
+        for (i = 0; i < text.length; i += 1) {
+          if (Array.isArray(text[i])) {
+            tmpText.push([parseArabic(text[i][0]), text[i][1], text[i][2]]);
+          } else {
+            tmpText.push([parseArabic(text[i])]);
+          }
+        }
+
+        result = tmpText;
+      } else {
+        result = parseArabic(text);
+      }
+
+      if (typeof arguments[0] === "string") {
+        return result;
+      } else {
+        arguments[0].text = result;
+        return arguments[0];
+      }
+    };
+
+    jsPDFAPI.events.push(["preProcessText", processArabic]);
+  })(jsPDF.API);
+
+  /** @license
+   * jsPDF Autoprint Plugin
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+  /**
+   * @name autoprint
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+    /**
+     * Makes the PDF automatically open the print-Dialog when opened in a PDF-viewer.
+     *
+     * @name autoPrint
+     * @function
+     * @param {Object} options (optional) Set the attribute variant to 'non-conform' (default) or 'javascript' to activate different methods of automatic printing when opening in a PDF-viewer .
+     * @returns {jsPDF}
+     * @example
+     * var doc = new jsPDF();
+     * doc.text(10, 10, 'This is a test');
+     * doc.autoPrint({variant: 'non-conform'});
+     * doc.save('autoprint.pdf');
+     */
+
+    jsPDFAPI.autoPrint = function (options) {
+
+      var refAutoPrintTag;
+      options = options || {};
+      options.variant = options.variant || "non-conform";
+
+      switch (options.variant) {
+        case "javascript":
+          //https://github.com/Rob--W/pdf.js/commit/c676ecb5a0f54677b9f3340c3ef2cf42225453bb
+          this.addJS("print({});");
+          break;
+
+        case "non-conform":
+        default:
+          this.internal.events.subscribe("postPutResources", function () {
+            refAutoPrintTag = this.internal.newObject();
+            this.internal.out("<<");
+            this.internal.out("/S /Named");
+            this.internal.out("/Type /Action");
+            this.internal.out("/N /Print");
+            this.internal.out(">>");
+            this.internal.out("endobj");
+          });
+          this.internal.events.subscribe("putCatalog", function () {
+            this.internal.out("/OpenAction " + refAutoPrintTag + " 0 R");
+          });
+          break;
+      }
+
+      return this;
+    };
+  })(jsPDF.API);
+
+  /**
+   * @license
+   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+  /**
+   * jsPDF Canvas PlugIn
+   * This plugin mimics the HTML5 Canvas
+   *
+   * The goal is to provide a way for current canvas users to print directly to a PDF.
+   * @name canvas
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+    /**
+     * @class Canvas
+     * @classdesc A Canvas Wrapper for jsPDF
+     */
+
+    var Canvas = function Canvas() {
+      var jsPdfInstance = undefined;
+      Object.defineProperty(this, "pdf", {
+        get: function get() {
+          return jsPdfInstance;
+        },
+        set: function set(value) {
+          jsPdfInstance = value;
+        }
+      });
+      var _width = 150;
+      /**
+       * The height property is a positive integer reflecting the height HTML attribute of the <canvas> element interpreted in CSS pixels. When the attribute is not specified, or if it is set to an invalid value, like a negative, the default value of 150 is used.
+       * This is one of the two properties, the other being width, that controls the size of the canvas.
+       *
+       * @name width
+       */
+
+      Object.defineProperty(this, "width", {
+        get: function get() {
+          return _width;
+        },
+        set: function set(value) {
+          if (isNaN(value) || Number.isInteger(value) === false || value < 0) {
+            _width = 150;
+          } else {
+            _width = value;
+          }
+
+          if (this.getContext("2d").pageWrapXEnabled) {
+            this.getContext("2d").pageWrapX = _width + 1;
+          }
+        }
+      });
+      var _height = 300;
+      /**
+       * The width property is a positive integer reflecting the width HTML attribute of the <canvas> element interpreted in CSS pixels. When the attribute is not specified, or if it is set to an invalid value, like a negative, the default value of 300 is used.
+       * This is one of the two properties, the other being height, that controls the size of the canvas.
+       *
+       * @name height
+       */
+
+      Object.defineProperty(this, "height", {
+        get: function get() {
+          return _height;
+        },
+        set: function set(value) {
+          if (isNaN(value) || Number.isInteger(value) === false || value < 0) {
+            _height = 300;
+          } else {
+            _height = value;
+          }
+
+          if (this.getContext("2d").pageWrapYEnabled) {
+            this.getContext("2d").pageWrapY = _height + 1;
+          }
+        }
+      });
+      var _childNodes = [];
+      Object.defineProperty(this, "childNodes", {
+        get: function get() {
+          return _childNodes;
+        },
+        set: function set(value) {
+          _childNodes = value;
+        }
+      });
+      var _style = {};
+      Object.defineProperty(this, "style", {
+        get: function get() {
+          return _style;
+        },
+        set: function set(value) {
+          _style = value;
+        }
+      });
+      Object.defineProperty(this, "parentNode", {});
+    };
+    /**
+     * The getContext() method returns a drawing context on the canvas, or null if the context identifier is not supported.
+     *
+     * @name getContext
+     * @function
+     * @param {string} contextType Is a String containing the context identifier defining the drawing context associated to the canvas. Possible value is "2d", leading to the creation of a Context2D object representing a two-dimensional rendering context.
+     * @param {object} contextAttributes
+     */
+
+
+    Canvas.prototype.getContext = function (contextType, contextAttributes) {
+      contextType = contextType || "2d";
+      var key;
+
+      if (contextType !== "2d") {
+        return null;
+      }
+
+      for (key in contextAttributes) {
+        if (this.pdf.context2d.hasOwnProperty(key)) {
+          this.pdf.context2d[key] = contextAttributes[key];
+        }
+      }
+
+      this.pdf.context2d._canvas = this;
+      return this.pdf.context2d;
+    };
+    /**
+     * The toDataURL() method is just a stub to throw an error if accidently called.
+     *
+     * @name toDataURL
+     * @function
+     */
+
+
+    Canvas.prototype.toDataURL = function () {
+      throw new Error("toDataURL is not implemented.");
+    };
+
+    jsPDFAPI.events.push(["initialized", function () {
+      this.canvas = new Canvas();
+      this.canvas.pdf = this;
+    }]);
+    return this;
+  })(jsPDF.API);
+
+  /**
+   * @name cell
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+
+    var NO_MARGINS = {
+      left: 0,
+      top: 0,
+      bottom: 0,
+      right: 0
+    };
+    var px2pt = 0.264583 * 72 / 25.4;
+    var printingHeaderRow = false;
+
+    var _initialize = function _initialize() {
+      if (typeof this.internal.__cell__ === "undefined") {
+        this.internal.__cell__ = {};
+        this.internal.__cell__.padding = 3;
+        this.internal.__cell__.headerFunction = undefined;
+        this.internal.__cell__.margins = Object.assign({}, NO_MARGINS);
+        this.internal.__cell__.margins.width = this.getPageWidth();
+
+        _reset.call(this);
+      }
+    };
+
+    var _reset = function _reset() {
+      this.internal.__cell__.lastCell = new Cell();
+      this.internal.__cell__.pages = 1;
+    };
+
+    var Cell = function Cell() {
+      var _x = arguments[0];
+      Object.defineProperty(this, "x", {
+        enumerable: true,
+        get: function get() {
+          return _x;
+        },
+        set: function set(value) {
+          _x = value;
+        }
+      });
+      var _y = arguments[1];
+      Object.defineProperty(this, "y", {
+        enumerable: true,
+        get: function get() {
+          return _y;
+        },
+        set: function set(value) {
+          _y = value;
+        }
+      });
+      var _width = arguments[2];
+      Object.defineProperty(this, "width", {
+        enumerable: true,
+        get: function get() {
+          return _width;
+        },
+        set: function set(value) {
+          _width = value;
+        }
+      });
+      var _height = arguments[3];
+      Object.defineProperty(this, "height", {
+        enumerable: true,
+        get: function get() {
+          return _height;
+        },
+        set: function set(value) {
+          _height = value;
+        }
+      });
+      var _text = arguments[4];
+      Object.defineProperty(this, "text", {
+        enumerable: true,
+        get: function get() {
+          return _text;
+        },
+        set: function set(value) {
+          _text = value;
+        }
+      });
+      var _lineNumber = arguments[5];
+      Object.defineProperty(this, "lineNumber", {
+        enumerable: true,
+        get: function get() {
+          return _lineNumber;
+        },
+        set: function set(value) {
+          _lineNumber = value;
+        }
+      });
+      var _align = arguments[6];
+      Object.defineProperty(this, "align", {
+        enumerable: true,
+        get: function get() {
+          return _align;
+        },
+        set: function set(value) {
+          _align = value;
+        }
+      });
+      return this;
+    };
+
+    Cell.prototype.clone = function () {
+      return new Cell(this.x, this.y, this.width, this.height, this.text, this.lineNumber, this.align);
+    };
+
+    Cell.prototype.toArray = function () {
+      return [this.x, this.y, this.width, this.height, this.text, this.lineNumber, this.align];
+    };
+    /**
+     * @name setHeaderFunction
+     * @function
+     * @param {function} func
+     */
+
+
+    jsPDFAPI.setHeaderFunction = function (func) {
+      _initialize.call(this);
+
+      this.internal.__cell__.headerFunction = typeof func === "function" ? func : undefined;
+      return this;
+    };
+    /**
+     * @name getTextDimensions
+     * @function
+     * @param {string} txt
+     * @returns {Object} dimensions
+     */
+
+
+    jsPDFAPI.getTextDimensions = function (text, options) {
+      _initialize.call(this);
+
+      options = options || {};
+      var fontSize = options.fontSize || this.getFontSize();
+      var font = options.font || this.getFont();
+      var scaleFactor = options.scaleFactor || this.internal.scaleFactor;
+      var width = 0;
+      var amountOfLines = 0;
+      var height = 0;
+      var tempWidth = 0;
+      var scope = this;
+
+      if (!Array.isArray(text) && typeof text !== "string") {
+        if (typeof text === "number") {
+          text = String(text);
+        } else {
+          throw new Error("getTextDimensions expects text-parameter to be of type String or type Number or an Array of Strings.");
+        }
+      }
+
+      var maxWidth = options.maxWidth;
+
+      if (maxWidth > 0) {
+        if (typeof text === "string") {
+          text = this.splitTextToSize(text, maxWidth);
+        } else if (Object.prototype.toString.call(text) === "[object Array]") {
+          text = text.reduce(function (acc, textLine) {
+            return acc.concat(scope.splitTextToSize(textLine, maxWidth));
+          }, []);
+        }
+      } else {
+        // Without the else clause, it will not work if you do not pass along maxWidth
+        text = Array.isArray(text) ? text : [text];
+      }
+
+      for (var i = 0; i < text.length; i++) {
+        tempWidth = this.getStringUnitWidth(text[i], {
+          font: font
+        }) * fontSize;
+
+        if (width < tempWidth) {
+          width = tempWidth;
+        }
+      }
+
+      if (width !== 0) {
+        amountOfLines = text.length;
+      }
+
+      width = width / scaleFactor;
+      height = Math.max((amountOfLines * fontSize * this.getLineHeightFactor() - fontSize * (this.getLineHeightFactor() - 1)) / scaleFactor, 0);
+      return {
+        w: width,
+        h: height
+      };
+    };
+    /**
+     * @name cellAddPage
+     * @function
+     */
+
+
+    jsPDFAPI.cellAddPage = function () {
+      _initialize.call(this);
+
+      this.addPage();
+      var margins = this.internal.__cell__.margins || NO_MARGINS;
+      this.internal.__cell__.lastCell = new Cell(margins.left, margins.top, undefined, undefined);
+      this.internal.__cell__.pages += 1;
+      return this;
+    };
+    /**
+     * @name cell
+     * @function
+     * @param {number} x
+     * @param {number} y
+     * @param {number} width
+     * @param {number} height
+     * @param {string} text
+     * @param {number} lineNumber lineNumber
+     * @param {string} align
+     * @return {jsPDF} jsPDF-instance
+     */
+
+
+    var cell = jsPDFAPI.cell = function () {
+      var currentCell;
+
+      if (arguments[0] instanceof Cell) {
+        currentCell = arguments[0];
+      } else {
+        currentCell = new Cell(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
+      }
+
+      _initialize.call(this);
+
+      var lastCell = this.internal.__cell__.lastCell;
+      var padding = this.internal.__cell__.padding;
+      var margins = this.internal.__cell__.margins || NO_MARGINS;
+      var tableHeaderRow = this.internal.__cell__.tableHeaderRow;
+      var printHeaders = this.internal.__cell__.printHeaders; // If this is not the first cell, we must change its position
+
+      if (typeof lastCell.lineNumber !== "undefined") {
+        if (lastCell.lineNumber === currentCell.lineNumber) {
+          //Same line
+          currentCell.x = (lastCell.x || 0) + (lastCell.width || 0);
+          currentCell.y = lastCell.y || 0;
+        } else {
+          //New line
+          if (lastCell.y + lastCell.height + currentCell.height + margins.bottom > this.getPageHeight()) {
+            this.cellAddPage();
+            currentCell.y = margins.top;
+
+            if (printHeaders && tableHeaderRow) {
+              this.printHeaderRow(currentCell.lineNumber, true);
+              currentCell.y += tableHeaderRow[0].height;
+            }
+          } else {
+            currentCell.y = lastCell.y + lastCell.height || currentCell.y;
+          }
+        }
+      }
+
+      if (typeof currentCell.text[0] !== "undefined") {
+        this.rect(currentCell.x, currentCell.y, currentCell.width, currentCell.height, printingHeaderRow === true ? "FD" : undefined);
+
+        if (currentCell.align === "right") {
+          this.text(currentCell.text, currentCell.x + currentCell.width - padding, currentCell.y + padding, {
+            align: "right",
+            baseline: "top"
+          });
+        } else if (currentCell.align === "center") {
+          this.text(currentCell.text, currentCell.x + currentCell.width / 2, currentCell.y + padding, {
+            align: "center",
+            baseline: "top",
+            maxWidth: currentCell.width - padding - padding
+          });
+        } else {
+          this.text(currentCell.text, currentCell.x + padding, currentCell.y + padding, {
+            align: "left",
+            baseline: "top",
+            maxWidth: currentCell.width - padding - padding
+          });
+        }
+      }
+
+      this.internal.__cell__.lastCell = currentCell;
+      return this;
+    };
+    /**
+       * Create a table from a set of data.
+       * @name table
+       * @function
+       * @param {Integer} [x] : left-position for top-left corner of table
+       * @param {Integer} [y] top-position for top-left corner of table
+       * @param {Object[]} [data] An array of objects containing key-value pairs corresponding to a row of data.
+       * @param {String[]} [headers] Omit or null to auto-generate headers at a performance cost
+        * @param {Object} [config.printHeaders] True to print column headers at the top of every page
+       * @param {Object} [config.autoSize] True to dynamically set the column widths to match the widest cell value
+       * @param {Object} [config.margins] margin values for left, top, bottom, and width
+       * @param {Object} [config.fontSize] Integer fontSize to use (optional)
+       * @param {Object} [config.padding] cell-padding in pt to use (optional)
+       * @param {Object} [config.headerBackgroundColor] default is #c8c8c8 (optional)
+       * @param {Object} [config.headerTextColor] default is #000 (optional)
+       * @param {Object} [config.rowStart] callback to handle before print each row (optional)
+       * @param {Object} [config.cellStart] callback to handle before print each cell (optional)
+       * @returns {jsPDF} jsPDF-instance
+       */
+
+
+    jsPDFAPI.table = function (x, y, data, headers, config) {
+      _initialize.call(this);
+
+      if (!data) {
+        throw new Error("No data for PDF table.");
+      }
+
+      config = config || {};
+      var headerNames = [],
+          headerLabels = [],
+          headerAligns = [],
+          i,
+          columnMatrix = {},
+          columnWidths = {},
+          column,
+          columnMinWidths = [],
+          j,
+          tableHeaderConfigs = [],
+          //set up defaults. If a value is provided in config, defaults will be overwritten:
+      autoSize = config.autoSize || false,
+          printHeaders = config.printHeaders === false ? false : true,
+          fontSize = config.css && typeof config.css["font-size"] !== "undefined" ? config.css["font-size"] * 16 : config.fontSize || 12,
+          margins = config.margins || Object.assign({
+        width: this.getPageWidth()
+      }, NO_MARGINS),
+          padding = typeof config.padding === "number" ? config.padding : 3,
+          headerBackgroundColor = config.headerBackgroundColor || "#c8c8c8",
+          headerTextColor = config.headerTextColor || "#000";
+
+      _reset.call(this);
+
+      this.internal.__cell__.printHeaders = printHeaders;
+      this.internal.__cell__.margins = margins;
+      this.internal.__cell__.table_font_size = fontSize;
+      this.internal.__cell__.padding = padding;
+      this.internal.__cell__.headerBackgroundColor = headerBackgroundColor;
+      this.internal.__cell__.headerTextColor = headerTextColor;
+      this.setFontSize(fontSize); // Set header values
+
+      if (headers === undefined || headers === null) {
+        // No headers defined so we derive from data
+        headerNames = Object.keys(data[0]);
+        headerLabels = headerNames;
+        headerAligns = headerNames.map(function () {
+          return "left";
+        });
+      } else if (Array.isArray(headers) && _typeof(headers[0]) === "object") {
+        headerNames = headers.map(function (header) {
+          return header.name;
+        });
+        headerLabels = headers.map(function (header) {
+          return header.prompt || header.name || "";
+        });
+        headerAligns = headers.map(function (header) {
+          return header.align || "left";
+        }); // Split header configs into names and prompts
+
+        for (i = 0; i < headers.length; i += 1) {
+          columnWidths[headers[i].name] = headers[i].width * px2pt;
+        }
+      } else if (Array.isArray(headers) && typeof headers[0] === "string") {
+        headerNames = headers;
+        headerLabels = headerNames;
+        headerAligns = headerNames.map(function () {
+          return "left";
+        });
+      }
+
+      if (autoSize || Array.isArray(headers) && typeof headers[0] === "string") {
+        var headerName;
+
+        for (i = 0; i < headerNames.length; i += 1) {
+          headerName = headerNames[i]; // Create a matrix of columns e.g., {column_title: [row1_Record, row2_Record]}
+
+          columnMatrix[headerName] = data.map(function (rec) {
+            return rec[headerName];
+          }); // get header width
+
+          this.setFont(undefined, "bold");
+          columnMinWidths.push(this.getTextDimensions(headerLabels[i], {
+            fontSize: this.internal.__cell__.table_font_size,
+            scaleFactor: this.internal.scaleFactor
+          }).w);
+          column = columnMatrix[headerName]; // get cell widths
+
+          this.setFont(undefined, "normal");
+
+          for (j = 0; j < column.length; j += 1) {
+            columnMinWidths.push(this.getTextDimensions(column[j], {
+              fontSize: this.internal.__cell__.table_font_size,
+              scaleFactor: this.internal.scaleFactor
+            }).w);
+          } // get final column width
+
+
+          columnWidths[headerName] = Math.max.apply(null, columnMinWidths) + padding + padding; //have to reset
+
+          columnMinWidths = [];
+        }
+      } // -- Construct the table
+
+
+      if (printHeaders) {
+        var row = {};
+
+        for (i = 0; i < headerNames.length; i += 1) {
+          row[headerNames[i]] = {};
+          row[headerNames[i]].text = headerLabels[i];
+          row[headerNames[i]].align = headerAligns[i];
+        }
+
+        var rowHeight = calculateLineHeight.call(this, row, columnWidths); // Construct the header row
+
+        tableHeaderConfigs = headerNames.map(function (value) {
+          return new Cell(x, y, columnWidths[value], rowHeight, row[value].text, undefined, row[value].align);
+        }); // Store the table header config
+
+        this.setTableHeaderRow(tableHeaderConfigs); // Print the header for the start of the table
+
+        this.printHeaderRow(1, false);
+      } // Construct the data rows
+
+
+      var align = headers.reduce(function (pv, cv) {
+        pv[cv.name] = cv.align;
+        return pv;
+      }, {});
+
+      for (i = 0; i < data.length; i += 1) {
+        if ("rowStart" in config && config.rowStart instanceof Function) {
+          config.rowStart({
+            row: i,
+            data: data[i]
+          }, this);
+        }
+
+        var lineHeight = calculateLineHeight.call(this, data[i], columnWidths);
+
+        for (j = 0; j < headerNames.length; j += 1) {
+          var cellData = data[i][headerNames[j]];
+
+          if ("cellStart" in config && config.cellStart instanceof Function) {
+            config.cellStart({
+              row: i,
+              col: j,
+              data: cellData
+            }, this);
+          }
+
+          cell.call(this, new Cell(x, y, columnWidths[headerNames[j]], lineHeight, cellData, i + 2, align[headerNames[j]]));
+        }
+      }
+
+      this.internal.__cell__.table_x = x;
+      this.internal.__cell__.table_y = y;
+      return this;
+    };
+    /**
+     * Calculate the height for containing the highest column
+     *
+     * @name calculateLineHeight
+     * @function
+     * @param {Object[]} model is the line of data we want to calculate the height of
+     * @param {Integer[]} columnWidths is size of each column
+     * @returns {number} lineHeight
+     * @private
+     */
+
+
+    var calculateLineHeight = function calculateLineHeight(model, columnWidths) {
+      var padding = this.internal.__cell__.padding;
+      var fontSize = this.internal.__cell__.table_font_size;
+      var scaleFactor = this.internal.scaleFactor;
+      return Object.keys(model).map(function (key) {
+        var value = model[key];
+        return this.splitTextToSize(value.hasOwnProperty("text") ? value.text : value, columnWidths[key] - padding - padding);
+      }, this).map(function (value) {
+        return this.getLineHeightFactor() * value.length * fontSize / scaleFactor + padding + padding;
+      }, this).reduce(function (pv, cv) {
+        return Math.max(pv, cv);
+      }, 0);
+    };
+    /**
+     * Store the config for outputting a table header
+     *
+     * @name setTableHeaderRow
+     * @function
+     * @param {Object[]} config
+     * An array of cell configs that would define a header row: Each config matches the config used by jsPDFAPI.cell
+     * except the lineNumber parameter is excluded
+     */
+
+
+    jsPDFAPI.setTableHeaderRow = function (config) {
+      _initialize.call(this);
+
+      this.internal.__cell__.tableHeaderRow = config;
+    };
+    /**
+     * Output the store header row
+     *
+     * @name printHeaderRow
+     * @function
+     * @param {number} lineNumber The line number to output the header at
+     * @param {boolean} new_page
+     */
+
+
+    jsPDFAPI.printHeaderRow = function (lineNumber, new_page) {
+      _initialize.call(this);
+
+      if (!this.internal.__cell__.tableHeaderRow) {
+        throw new Error("Property tableHeaderRow does not exist.");
+      }
+
+      var tableHeaderCell;
+      printingHeaderRow = true;
+
+      if (typeof this.internal.__cell__.headerFunction === "function") {
+        var position = this.internal.__cell__.headerFunction(this, this.internal.__cell__.pages);
+
+        this.internal.__cell__.lastCell = new Cell(position[0], position[1], position[2], position[3], undefined, -1);
+      }
+
+      this.setFont(undefined, "bold");
+      var tempHeaderConf = [];
+
+      for (var i = 0; i < this.internal.__cell__.tableHeaderRow.length; i += 1) {
+        tableHeaderCell = this.internal.__cell__.tableHeaderRow[i].clone();
+
+        if (new_page) {
+          tableHeaderCell.y = this.internal.__cell__.margins.top || 0;
+          tempHeaderConf.push(tableHeaderCell);
+        }
+
+        tableHeaderCell.lineNumber = lineNumber;
+        var currentTextColor = this.getTextColor();
+        this.setTextColor(this.internal.__cell__.headerTextColor);
+        this.setFillColor(this.internal.__cell__.headerBackgroundColor);
+        cell.call(this, tableHeaderCell);
+        this.setTextColor(currentTextColor);
+      }
+
+      if (tempHeaderConf.length > 0) {
+        this.setTableHeaderRow(tempHeaderConf);
+      }
+
+      this.setFont(undefined, "normal");
+      printingHeaderRow = false;
+    };
+  })(jsPDF.API);
+
+  function toLookup(arr) {
+    return arr.reduce(function (lookup, name, index) {
+      lookup[name] = index;
+      return lookup;
+    }, {});
+  }
+
+  var fontStyleOrder = {
+    italic: ["italic", "oblique", "normal"],
+    oblique: ["oblique", "italic", "normal"],
+    normal: ["normal", "oblique", "italic"]
+  };
+  var fontStretchOrder = ["ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "normal", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded"]; // For a given font-stretch value, we need to know where to start our search
+  // from in the fontStretchOrder list.
+
+  var fontStretchLookup = toLookup(fontStretchOrder);
+  var fontWeights = [100, 200, 300, 400, 500, 600, 700, 800, 900];
+  var fontWeightsLookup = toLookup(fontWeights);
+
+  function normalizeFontStretch(stretch) {
+    stretch = stretch || "normal";
+    return typeof fontStretchLookup[stretch] === "number" ? stretch : "normal";
+  }
+
+  function normalizeFontStyle(style) {
+    style = style || "normal";
+    return fontStyleOrder[style] ? style : "normal";
+  }
+
+  function normalizeFontWeight(weight) {
+    if (!weight) {
+      return 400;
+    }
+
+    if (typeof weight === "number") {
+      // Ignore values which aren't valid font-weights.
+      return weight >= 100 && weight <= 900 && weight % 100 === 0 ? weight : 400;
+    }
+
+    if (/^\d00$/.test(weight)) {
+      return parseInt(weight);
+    }
+
+    switch (weight) {
+      case "bold":
+        return 700;
+
+      case "normal":
+      default:
+        return 400;
+    }
+  }
+
+  function normalizeFontFace(fontFace) {
+    var family = fontFace.family.replace(/"|'/g, "").toLowerCase();
+    var style = normalizeFontStyle(fontFace.style);
+    var weight = normalizeFontWeight(fontFace.weight);
+    var stretch = normalizeFontStretch(fontFace.stretch);
+    return {
+      family: family,
+      style: style,
+      weight: weight,
+      stretch: stretch,
+      src: fontFace.src || [],
+      // The ref property maps this font-face to the font
+      // added by the .addFont() method.
+      ref: fontFace.ref || {
+        name: family,
+        style: [stretch, style, weight].join(" ")
+      }
+    };
+  }
+  /**
+   * Turns a list of font-faces into a map, for easier lookup when resolving
+   * fonts.
+   * @private
+   */
+
+  function buildFontFaceMap(fontFaces) {
+    var map = {};
+
+    for (var i = 0; i < fontFaces.length; ++i) {
+      var normalized = normalizeFontFace(fontFaces[i]);
+      var name = normalized.family;
+      var stretch = normalized.stretch;
+      var style = normalized.style;
+      var weight = normalized.weight;
+      map[name] = map[name] || {};
+      map[name][stretch] = map[name][stretch] || {};
+      map[name][stretch][style] = map[name][stretch][style] || {};
+      map[name][stretch][style][weight] = normalized;
+    }
+
+    return map;
+  }
+  /**
+   * Searches a map of stretches, weights, etc. in the given direction and
+   * then, if no match has been found, in the opposite directions.
+   *
+   * @param {Object.<string, any>} matchingSet A map of the various font variations.
+   * @param {any[]} order The order of the different variations
+   * @param {number} pivot The starting point of the search in the order list.
+   * @param {number} dir The initial direction of the search (desc = -1, asc = 1)
+   * @private
+   */
+
+  function searchFromPivot(matchingSet, order, pivot, dir) {
+    var i;
+
+    for (i = pivot; i >= 0 && i < order.length; i += dir) {
+      if (matchingSet[order[i]]) {
+        return matchingSet[order[i]];
+      }
+    }
+
+    for (i = pivot; i >= 0 && i < order.length; i -= dir) {
+      if (matchingSet[order[i]]) {
+        return matchingSet[order[i]];
+      }
+    }
+  }
+
+  function resolveFontStretch(stretch, matchingSet) {
+    if (matchingSet[stretch]) {
+      return matchingSet[stretch];
+    }
+
+    var pivot = fontStretchLookup[stretch]; // If the font-stretch value is normal or more condensed, we want to
+    // start with a descending search, otherwise we should do ascending.
+
+    var dir = pivot <= fontStretchLookup["normal"] ? -1 : 1;
+    var match = searchFromPivot(matchingSet, fontStretchOrder, pivot, dir);
+
+    if (!match) {
+      // Since a font-family cannot exist without having at least one stretch value
+      // we should never reach this point.
+      throw new Error("Could not find a matching font-stretch value for " + stretch);
+    }
+
+    return match;
+  }
+
+  function resolveFontStyle(fontStyle, matchingSet) {
+    if (matchingSet[fontStyle]) {
+      return matchingSet[fontStyle];
+    }
+
+    var ordering = fontStyleOrder[fontStyle];
+
+    for (var i = 0; i < ordering.length; ++i) {
+      if (matchingSet[ordering[i]]) {
+        return matchingSet[ordering[i]];
+      }
+    } // Since a font-family cannot exist without having at least one style value
+    // we should never reach this point.
+
+
+    throw new Error("Could not find a matching font-style for " + fontStyle);
+  }
+
+  function resolveFontWeight(weight, matchingSet) {
+    if (matchingSet[weight]) {
+      return matchingSet[weight];
+    }
+
+    if (weight === 400 && matchingSet[500]) {
+      return matchingSet[500];
+    }
+
+    if (weight === 500 && matchingSet[400]) {
+      return matchingSet[400];
+    }
+
+    var pivot = fontWeightsLookup[weight]; // If the font-stretch value is normal or more condensed, we want to
+    // start with a descending search, otherwise we should do ascending.
+
+    var dir = weight < 400 ? -1 : 1;
+    var match = searchFromPivot(matchingSet, fontWeights, pivot, dir);
+
+    if (!match) {
+      // Since a font-family cannot exist without having at least one stretch value
+      // we should never reach this point.
+      throw new Error("Could not find a matching font-weight for value " + weight);
+    }
+
+    return match;
+  }
+
+  var defaultGenericFontFamilies = {
+    "sans-serif": "helvetica",
+    fixed: "courier",
+    monospace: "courier",
+    terminal: "courier",
+    cursive: "times",
+    fantasy: "times",
+    serif: "times"
+  };
+  var systemFonts = {
+    caption: "times",
+    icon: "times",
+    menu: "times",
+    "message-box": "times",
+    "small-caption": "times",
+    "status-bar": "times"
+  };
+
+  function ruleToString(rule) {
+    return [rule.stretch, rule.style, rule.weight, rule.family].join(" ");
+  }
+
+  function resolveFontFace(fontFaceMap, rules, opts) {
+    opts = opts || {};
+    var defaultFontFamily = opts.defaultFontFamily || "times";
+    var genericFontFamilies = Object.assign({}, defaultGenericFontFamilies, opts.genericFontFamilies || {});
+    var rule = null;
+    var matches = null;
+
+    for (var i = 0; i < rules.length; ++i) {
+      rule = normalizeFontFace(rules[i]);
+
+      if (genericFontFamilies[rule.family]) {
+        rule.family = genericFontFamilies[rule.family];
+      }
+
+      if (fontFaceMap.hasOwnProperty(rule.family)) {
+        matches = fontFaceMap[rule.family];
+        break;
+      }
+    } // Always fallback to a known font family.
+
+
+    matches = matches || fontFaceMap[defaultFontFamily];
+
+    if (!matches) {
+      // At this point we should definitiely have a font family, but if we
+      // don't there is something wrong with our configuration
+      throw new Error("Could not find a font-family for the rule '" + ruleToString(rule) + "' and default family '" + defaultFontFamily + "'.");
+    }
+
+    matches = resolveFontStretch(rule.stretch, matches);
+    matches = resolveFontStyle(rule.style, matches);
+    matches = resolveFontWeight(rule.weight, matches);
+
+    if (!matches) {
+      // We should've fount
+      throw new Error("Failed to resolve a font for the rule '" + ruleToString(rule) + "'.");
+    }
+
+    return matches;
+  }
+
+  function eatWhiteSpace(input) {
+    return input.trimLeft();
+  }
+
+  function parseQuotedFontFamily(input, quote) {
+    var index = 0;
+
+    while (index < input.length) {
+      var current = input.charAt(index);
+
+      if (current === quote) {
+        return [input.substring(0, index), input.substring(index + 1)];
+      }
+
+      index += 1;
+    } // Unexpected end of input
+
+
+    return null;
+  }
+
+  function parseNonQuotedFontFamily(input) {
+    // It implements part of the identifier parser here: https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+    //
+    // NOTE: This parser pretty much ignores escaped identifiers and that there is a thing called unicode.
+    //
+    // Breakdown of regexp:
+    // -[a-z_]     - when identifier starts with a hyphen, you're not allowed to have another hyphen or a digit
+    // [a-z_]      - allow a-z and underscore at beginning of input
+    // [a-z0-9_-]* - after that, anything goes
+    var match = input.match(/^(-[a-z_]|[a-z_])[a-z0-9_-]*/i); // non quoted value contains illegal characters
+
+    if (match === null) {
+      return null;
+    }
+
+    return [match[0], input.substring(match[0].length)];
+  }
+
+  var defaultFont = ["times"];
+  function parseFontFamily(input) {
+    var result = [];
+    var ch, parsed;
+    var remaining = input.trim();
+
+    if (remaining === "") {
+      return defaultFont;
+    }
+
+    if (remaining in systemFonts) {
+      return [systemFonts[remaining]];
+    }
+
+    while (remaining !== "") {
+      parsed = null;
+      remaining = eatWhiteSpace(remaining);
+      ch = remaining.charAt(0);
+
+      switch (ch) {
+        case '"':
+        case "'":
+          parsed = parseQuotedFontFamily(remaining.substring(1), ch);
+          break;
+
+        default:
+          parsed = parseNonQuotedFontFamily(remaining);
+          break;
+      }
+
+      if (parsed === null) {
+        return defaultFont;
+      }
+
+      result.push(parsed[0]);
+      remaining = eatWhiteSpace(parsed[1]); // We expect end of input or a comma separator here
+
+      if (remaining !== "" && remaining.charAt(0) !== ",") {
+        return defaultFont;
+      }
+
+      remaining = remaining.replace(/^,/, "");
+    }
+
+    return result;
+  }
+
+  /**
+   * This plugin mimics the HTML5 CanvasRenderingContext2D.
+   *
+   * The goal is to provide a way for current canvas implementations to print directly to a PDF.
+   *
+   * @name context2d
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+
+    var ContextLayer = function ContextLayer(ctx) {
+      ctx = ctx || {};
+      this.isStrokeTransparent = ctx.isStrokeTransparent || false;
+      this.strokeOpacity = ctx.strokeOpacity || 1;
+      this.strokeStyle = ctx.strokeStyle || "#000000";
+      this.fillStyle = ctx.fillStyle || "#000000";
+      this.isFillTransparent = ctx.isFillTransparent || false;
+      this.fillOpacity = ctx.fillOpacity || 1;
+      this.font = ctx.font || "10px sans-serif";
+      this.textBaseline = ctx.textBaseline || "alphabetic";
+      this.textAlign = ctx.textAlign || "left";
+      this.lineWidth = ctx.lineWidth || 1;
+      this.lineJoin = ctx.lineJoin || "miter";
+      this.lineCap = ctx.lineCap || "butt";
+      this.path = ctx.path || [];
+      this.transform = typeof ctx.transform !== "undefined" ? ctx.transform.clone() : new Matrix();
+      this.globalCompositeOperation = ctx.globalCompositeOperation || "normal";
+      this.globalAlpha = ctx.globalAlpha || 1.0;
+      this.clip_path = ctx.clip_path || [];
+      this.currentPoint = ctx.currentPoint || new Point();
+      this.miterLimit = ctx.miterLimit || 10.0;
+      this.lastPoint = ctx.lastPoint || new Point();
+      this.lineDashOffset = ctx.lineDashOffset || 0.0;
+      this.lineDash = ctx.lineDash || [];
+      this.margin = ctx.margin || [0, 0, 0, 0];
+      this.prevPageLastElemOffset = ctx.prevPageLastElemOffset || 0;
+      this.ignoreClearRect = typeof ctx.ignoreClearRect === "boolean" ? ctx.ignoreClearRect : true;
+      return this;
+    }; //stub
+
+
+    var f2, getHorizontalCoordinateString, getVerticalCoordinateString, getHorizontalCoordinate, getVerticalCoordinate, Point, Rectangle, Matrix, _ctx;
+
+    jsPDFAPI.events.push(["initialized", function () {
+      this.context2d = new Context2D(this);
+      f2 = this.internal.f2;
+      getHorizontalCoordinateString = this.internal.getCoordinateString;
+      getVerticalCoordinateString = this.internal.getVerticalCoordinateString;
+      getHorizontalCoordinate = this.internal.getHorizontalCoordinate;
+      getVerticalCoordinate = this.internal.getVerticalCoordinate;
+      Point = this.internal.Point;
+      Rectangle = this.internal.Rectangle;
+      Matrix = this.internal.Matrix;
+      _ctx = new ContextLayer();
+    }]);
+
+    var Context2D = function Context2D(pdf) {
+      Object.defineProperty(this, "canvas", {
+        get: function get() {
+          return {
+            parentNode: false,
+            style: false
+          };
+        }
+      });
+      var _pdf = pdf;
+      Object.defineProperty(this, "pdf", {
+        get: function get() {
+          return _pdf;
+        }
+      });
+      var _pageWrapXEnabled = false;
+      /**
+       * @name pageWrapXEnabled
+       * @type {boolean}
+       * @default false
+       */
+
+      Object.defineProperty(this, "pageWrapXEnabled", {
+        get: function get() {
+          return _pageWrapXEnabled;
+        },
+        set: function set(value) {
+          _pageWrapXEnabled = Boolean(value);
+        }
+      });
+      var _pageWrapYEnabled = false;
+      /**
+       * @name pageWrapYEnabled
+       * @type {boolean}
+       * @default true
+       */
+
+      Object.defineProperty(this, "pageWrapYEnabled", {
+        get: function get() {
+          return _pageWrapYEnabled;
+        },
+        set: function set(value) {
+          _pageWrapYEnabled = Boolean(value);
+        }
+      });
+      var _posX = 0;
+      /**
+       * @name posX
+       * @type {number}
+       * @default 0
+       */
+
+      Object.defineProperty(this, "posX", {
+        get: function get() {
+          return _posX;
+        },
+        set: function set(value) {
+          if (!isNaN(value)) {
+            _posX = value;
+          }
+        }
+      });
+      var _posY = 0;
+      /**
+       * @name posY
+       * @type {number}
+       * @default 0
+       */
+
+      Object.defineProperty(this, "posY", {
+        get: function get() {
+          return _posY;
+        },
+        set: function set(value) {
+          if (!isNaN(value)) {
+            _posY = value;
+          }
+        }
+      });
+      /**
+       * Gets or sets the page margin when using auto paging. Has no effect when {@link autoPaging} is off.
+       * @name margin
+       * @type {number|number[]}
+       * @default [0, 0, 0, 0]
+       */
+
+      Object.defineProperty(this, "margin", {
+        get: function get() {
+          return _ctx.margin;
+        },
+        set: function set(value) {
+          var margin;
+
+          if (typeof value === "number") {
+            margin = [value, value, value, value];
+          } else {
+            margin = new Array(4);
+            margin[0] = value[0];
+            margin[1] = value.length >= 2 ? value[1] : margin[0];
+            margin[2] = value.length >= 3 ? value[2] : margin[0];
+            margin[3] = value.length >= 4 ? value[3] : margin[1];
+          }
+
+          _ctx.margin = margin;
+        }
+      });
+      var _autoPaging = false;
+      /**
+       * Gets or sets the auto paging mode. When auto paging is enabled, the context2d will automatically draw on the
+       * next page if a shape or text chunk doesn't fit entirely on the current page. The context2d will create new
+       * pages if required.
+       *
+       * Context2d supports different modes:
+       * <ul>
+       * <li>
+       *   <code>false</code>: Auto paging is disabled.
+       * </li>
+       * <li>
+       *   <code>true</code> or <code>'slice'</code>: Will cut shapes or text chunks across page breaks. Will possibly
+       *   slice text in half, making it difficult to read.
+       * </li>
+       * <li>
+       *   <code>'text'</code>: Trys not to cut text in half across page breaks. Works best for documents consisting
+       *   mostly of a single column of text.
+       * </li>
+       * </ul>
+       * @name Context2D#autoPaging
+       * @type {boolean|"slice"|"text"}
+       * @default false
+       */
+
+      Object.defineProperty(this, "autoPaging", {
+        get: function get() {
+          return _autoPaging;
+        },
+        set: function set(value) {
+          _autoPaging = value;
+        }
+      });
+      var lastBreak = 0;
+      /**
+       * @name lastBreak
+       * @type {number}
+       * @default 0
+       */
+
+      Object.defineProperty(this, "lastBreak", {
+        get: function get() {
+          return lastBreak;
+        },
+        set: function set(value) {
+          lastBreak = value;
+        }
+      });
+      var pageBreaks = [];
+      /**
+       * Y Position of page breaks.
+       * @name pageBreaks
+       * @type {number}
+       * @default 0
+       */
+
+      Object.defineProperty(this, "pageBreaks", {
+        get: function get() {
+          return pageBreaks;
+        },
+        set: function set(value) {
+          pageBreaks = value;
+        }
+      });
+      /**
+       * @name ctx
+       * @type {object}
+       * @default {}
+       */
+
+      Object.defineProperty(this, "ctx", {
+        get: function get() {
+          return _ctx;
+        },
+        set: function set(value) {
+          if (value instanceof ContextLayer) {
+            _ctx = value;
+          }
+        }
+      });
+      /**
+       * @name path
+       * @type {array}
+       * @default []
+       */
+
+      Object.defineProperty(this, "path", {
+        get: function get() {
+          return _ctx.path;
+        },
+        set: function set(value) {
+          _ctx.path = value;
+        }
+      });
+      /**
+       * @name ctxStack
+       * @type {array}
+       * @default []
+       */
+
+      var _ctxStack = [];
+      Object.defineProperty(this, "ctxStack", {
+        get: function get() {
+          return _ctxStack;
+        },
+        set: function set(value) {
+          _ctxStack = value;
+        }
+      });
+      /**
+       * Sets or returns the color, gradient, or pattern used to fill the drawing
+       *
+       * @name fillStyle
+       * @default #000000
+       * @property {(color|gradient|pattern)} value The color of the drawing. Default value is #000000<br />
+       * A gradient object (linear or radial) used to fill the drawing (not supported by context2d)<br />
+       * A pattern object to use to fill the drawing (not supported by context2d)
+       */
+
+      Object.defineProperty(this, "fillStyle", {
+        get: function get() {
+          return this.ctx.fillStyle;
+        },
+        set: function set(value) {
+          var rgba;
+          rgba = getRGBA(value);
+          this.ctx.fillStyle = rgba.style;
+          this.ctx.isFillTransparent = rgba.a === 0;
+          this.ctx.fillOpacity = rgba.a;
+          this.pdf.setFillColor(rgba.r, rgba.g, rgba.b, {
+            a: rgba.a
+          });
+          this.pdf.setTextColor(rgba.r, rgba.g, rgba.b, {
+            a: rgba.a
+          });
+        }
+      });
+      /**
+       * Sets or returns the color, gradient, or pattern used for strokes
+       *
+       * @name strokeStyle
+       * @default #000000
+       * @property {color} color A CSS color value that indicates the stroke color of the drawing. Default value is #000000 (not supported by context2d)
+       * @property {gradient} gradient A gradient object (linear or radial) used to create a gradient stroke (not supported by context2d)
+       * @property {pattern} pattern A pattern object used to create a pattern stroke (not supported by context2d)
+       */
+
+      Object.defineProperty(this, "strokeStyle", {
+        get: function get() {
+          return this.ctx.strokeStyle;
+        },
+        set: function set(value) {
+          var rgba = getRGBA(value);
+          this.ctx.strokeStyle = rgba.style;
+          this.ctx.isStrokeTransparent = rgba.a === 0;
+          this.ctx.strokeOpacity = rgba.a;
+
+          if (rgba.a === 0) {
+            this.pdf.setDrawColor(255, 255, 255);
+          } else if (rgba.a === 1) {
+            this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b);
+          } else {
+            this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b);
+          }
+        }
+      });
+      /**
+       * Sets or returns the style of the end caps for a line
+       *
+       * @name lineCap
+       * @default butt
+       * @property {(butt|round|square)} lineCap butt A flat edge is added to each end of the line <br/>
+       * round A rounded end cap is added to each end of the line<br/>
+       * square A square end cap is added to each end of the line<br/>
+       */
+
+      Object.defineProperty(this, "lineCap", {
+        get: function get() {
+          return this.ctx.lineCap;
+        },
+        set: function set(value) {
+          if (["butt", "round", "square"].indexOf(value) !== -1) {
+            this.ctx.lineCap = value;
+            this.pdf.setLineCap(value);
+          }
+        }
+      });
+      /**
+       * Sets or returns the current line width
+       *
+       * @name lineWidth
+       * @default 1
+       * @property {number} lineWidth The current line width, in pixels
+       */
+
+      Object.defineProperty(this, "lineWidth", {
+        get: function get() {
+          return this.ctx.lineWidth;
+        },
+        set: function set(value) {
+          if (!isNaN(value)) {
+            this.ctx.lineWidth = value;
+            this.pdf.setLineWidth(value);
+          }
+        }
+      });
+      /**
+       * Sets or returns the type of corner created, when two lines meet
+       */
+
+      Object.defineProperty(this, "lineJoin", {
+        get: function get() {
+          return this.ctx.lineJoin;
+        },
+        set: function set(value) {
+          if (["bevel", "round", "miter"].indexOf(value) !== -1) {
+            this.ctx.lineJoin = value;
+            this.pdf.setLineJoin(value);
+          }
+        }
+      });
+      /**
+       * A number specifying the miter limit ratio in coordinate space units. Zero, negative, Infinity, and NaN values are ignored. The default value is 10.0.
+       *
+       * @name miterLimit
+       * @default 10
+       */
+
+      Object.defineProperty(this, "miterLimit", {
+        get: function get() {
+          return this.ctx.miterLimit;
+        },
+        set: function set(value) {
+          if (!isNaN(value)) {
+            this.ctx.miterLimit = value;
+            this.pdf.setMiterLimit(value);
+          }
+        }
+      });
+      Object.defineProperty(this, "textBaseline", {
+        get: function get() {
+          return this.ctx.textBaseline;
+        },
+        set: function set(value) {
+          this.ctx.textBaseline = value;
+        }
+      });
+      Object.defineProperty(this, "textAlign", {
+        get: function get() {
+          return this.ctx.textAlign;
+        },
+        set: function set(value) {
+          if (["right", "end", "center", "left", "start"].indexOf(value) !== -1) {
+            this.ctx.textAlign = value;
+          }
+        }
+      });
+      var _fontFaceMap = null;
+
+      function getFontFaceMap(pdf, fontFaces) {
+        if (_fontFaceMap === null) {
+          var fontMap = pdf.getFontList();
+          var convertedFontFaces = convertToFontFaces(fontMap);
+          _fontFaceMap = buildFontFaceMap(convertedFontFaces.concat(fontFaces));
+        }
+
+        return _fontFaceMap;
+      }
+
+      function convertToFontFaces(fontMap) {
+        var fontFaces = [];
+        Object.keys(fontMap).forEach(function (family) {
+          var styles = fontMap[family];
+          styles.forEach(function (style) {
+            var fontFace = null;
+
+            switch (style) {
+              case "bold":
+                fontFace = {
+                  family: family,
+                  weight: "bold"
+                };
+                break;
+
+              case "italic":
+                fontFace = {
+                  family: family,
+                  style: "italic"
+                };
+                break;
+
+              case "bolditalic":
+                fontFace = {
+                  family: family,
+                  weight: "bold",
+                  style: "italic"
+                };
+                break;
+
+              case "":
+              case "normal":
+                fontFace = {
+                  family: family
+                };
+                break;
+            } // If font-face is still null here, it is a font with some styling we don't recognize and
+            // cannot map or it is a font added via the fontFaces option of .html().
+
+
+            if (fontFace !== null) {
+              fontFace.ref = {
+                name: family,
+                style: style
+              };
+              fontFaces.push(fontFace);
+            }
+          });
+        });
+        return fontFaces;
+      }
+
+      var _fontFaces = null;
+      /**
+       * A map of available font-faces, as passed in the options of
+       * .html(). If set a limited implementation of the font style matching
+       * algorithm defined by https://www.w3.org/TR/css-fonts-3/#font-matching-algorithm
+       * will be used. If not set it will fallback to previous behavior.
+       */
+
+      Object.defineProperty(this, "fontFaces", {
+        get: function get() {
+          return _fontFaces;
+        },
+        set: function set(value) {
+          _fontFaceMap = null;
+          _fontFaces = value;
+        }
+      });
+      Object.defineProperty(this, "font", {
+        get: function get() {
+          return this.ctx.font;
+        },
+        set: function set(value) {
+          this.ctx.font = value;
+          var rx, matches; //source: https://stackoverflow.com/a/10136041
+          // eslint-disable-next-line no-useless-escape
+
+          rx = /^\s*(?=(?:(?:[-a-z]+\s*){0,2}(italic|oblique))?)(?=(?:(?:[-a-z]+\s*){0,2}(small-caps))?)(?=(?:(?:[-a-z]+\s*){0,2}(bold(?:er)?|lighter|[1-9]00))?)(?:(?:normal|\1|\2|\3)\s*){0,3}((?:xx?-)?(?:small|large)|medium|smaller|larger|[.\d]+(?:\%|in|[cem]m|ex|p[ctx]))(?:\s*\/\s*(normal|[.\d]+(?:\%|in|[cem]m|ex|p[ctx])))?\s*([-_,\"\'\sa-z]+?)\s*$/i;
+          matches = rx.exec(value);
+
+          if (matches !== null) {
+            var fontStyle = matches[1];
+            var fontVariant = matches[2];
+            var fontWeight = matches[3];
+            var fontSize = matches[4];
+            var lineHeight = matches[5];
+            var fontFamily = matches[6];
+          } else {
+            return;
+          }
+
+          var rxFontSize = /^([.\d]+)((?:%|in|[cem]m|ex|p[ctx]))$/i;
+          var fontSizeUnit = rxFontSize.exec(fontSize)[2];
+
+          if ("px" === fontSizeUnit) {
+            fontSize = Math.floor(parseFloat(fontSize) * this.pdf.internal.scaleFactor);
+          } else if ("em" === fontSizeUnit) {
+            fontSize = Math.floor(parseFloat(fontSize) * this.pdf.getFontSize());
+          } else {
+            fontSize = Math.floor(parseFloat(fontSize) * this.pdf.internal.scaleFactor);
+          }
+
+          this.pdf.setFontSize(fontSize);
+          var parts = parseFontFamily(fontFamily);
+
+          if (this.fontFaces) {
+            var fontFaceMap = getFontFaceMap(this.pdf, this.fontFaces);
+            var rules = parts.map(function (ff) {
+              return {
+                family: ff,
+                stretch: "normal",
+                // TODO: Extract font-stretch from font rule (perhaps write proper parser for it?)
+                weight: fontWeight,
+                style: fontStyle
+              };
+            });
+            var font = resolveFontFace(fontFaceMap, rules);
+            this.pdf.setFont(font.ref.name, font.ref.style);
+            return;
+          }
+
+          var style = "";
+
+          if (fontWeight === "bold" || parseInt(fontWeight, 10) >= 700 || fontStyle === "bold") {
+            style = "bold";
+          }
+
+          if (fontStyle === "italic") {
+            style += "italic";
+          }
+
+          if (style.length === 0) {
+            style = "normal";
+          }
+
+          var jsPdfFontName = "";
+          var fallbackFonts = {
+            arial: "Helvetica",
+            Arial: "Helvetica",
+            verdana: "Helvetica",
+            Verdana: "Helvetica",
+            helvetica: "Helvetica",
+            Helvetica: "Helvetica",
+            "sans-serif": "Helvetica",
+            fixed: "Courier",
+            monospace: "Courier",
+            terminal: "Courier",
+            cursive: "Times",
+            fantasy: "Times",
+            serif: "Times"
+          };
+
+          for (var i = 0; i < parts.length; i++) {
+            if (this.pdf.internal.getFont(parts[i], style, {
+              noFallback: true,
+              disableWarning: true
+            }) !== undefined) {
+              jsPdfFontName = parts[i];
+              break;
+            } else if (style === "bolditalic" && this.pdf.internal.getFont(parts[i], "bold", {
+              noFallback: true,
+              disableWarning: true
+            }) !== undefined) {
+              jsPdfFontName = parts[i];
+              style = "bold";
+            } else if (this.pdf.internal.getFont(parts[i], "normal", {
+              noFallback: true,
+              disableWarning: true
+            }) !== undefined) {
+              jsPdfFontName = parts[i];
+              style = "normal";
+              break;
+            }
+          }
+
+          if (jsPdfFontName === "") {
+            for (var j = 0; j < parts.length; j++) {
+              if (fallbackFonts[parts[j]]) {
+                jsPdfFontName = fallbackFonts[parts[j]];
+                break;
+              }
+            }
+          }
+
+          jsPdfFontName = jsPdfFontName === "" ? "Times" : jsPdfFontName;
+          this.pdf.setFont(jsPdfFontName, style);
+        }
+      });
+      Object.defineProperty(this, "globalCompositeOperation", {
+        get: function get() {
+          return this.ctx.globalCompositeOperation;
+        },
+        set: function set(value) {
+          this.ctx.globalCompositeOperation = value;
+        }
+      });
+      Object.defineProperty(this, "globalAlpha", {
+        get: function get() {
+          return this.ctx.globalAlpha;
+        },
+        set: function set(value) {
+          this.ctx.globalAlpha = value;
+        }
+      });
+      /**
+       * A float specifying the amount of the line dash offset. The default value is 0.0.
+       *
+       * @name lineDashOffset
+       * @default 0.0
+       */
+
+      Object.defineProperty(this, "lineDashOffset", {
+        get: function get() {
+          return this.ctx.lineDashOffset;
+        },
+        set: function set(value) {
+          this.ctx.lineDashOffset = value;
+          setLineDash.call(this);
+        }
+      }); // Not HTML API
+
+      Object.defineProperty(this, "lineDash", {
+        get: function get() {
+          return this.ctx.lineDash;
+        },
+        set: function set(value) {
+          this.ctx.lineDash = value;
+          setLineDash.call(this);
+        }
+      }); // Not HTML API
+
+      Object.defineProperty(this, "ignoreClearRect", {
+        get: function get() {
+          return this.ctx.ignoreClearRect;
+        },
+        set: function set(value) {
+          this.ctx.ignoreClearRect = Boolean(value);
+        }
+      });
+    };
+    /**
+     * Sets the line dash pattern used when stroking lines.
+     * @name setLineDash
+     * @function
+     * @description It uses an array of values that specify alternating lengths of lines and gaps which describe the pattern.
+     */
+
+
+    Context2D.prototype.setLineDash = function (dashArray) {
+      this.lineDash = dashArray;
+    };
+    /**
+     * gets the current line dash pattern.
+     * @name getLineDash
+     * @function
+     * @returns {Array} An Array of numbers that specify distances to alternately draw a line and a gap (in coordinate space units). If the number, when setting the elements, is odd, the elements of the array get copied and concatenated. For example, setting the line dash to [5, 15, 25] will result in getting back [5, 15, 25, 5, 15, 25].
+     */
+
+
+    Context2D.prototype.getLineDash = function () {
+      if (this.lineDash.length % 2) {
+        // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getLineDash#return_value
+        return this.lineDash.concat(this.lineDash);
+      } else {
+        // The copied value is returned to prevent contamination from outside.
+        return this.lineDash.slice();
+      }
+    };
+
+    Context2D.prototype.fill = function () {
+      pathPreProcess.call(this, "fill", false);
+    };
+    /**
+     * Actually draws the path you have defined
+     *
+     * @name stroke
+     * @function
+     * @description The stroke() method actually draws the path you have defined with all those moveTo() and lineTo() methods. The default color is black.
+     */
+
+
+    Context2D.prototype.stroke = function () {
+      pathPreProcess.call(this, "stroke", false);
+    };
+    /**
+     * Begins a path, or resets the current
+     *
+     * @name beginPath
+     * @function
+     * @description The beginPath() method begins a path, or resets the current path.
+     */
+
+
+    Context2D.prototype.beginPath = function () {
+      this.path = [{
+        type: "begin"
+      }];
+    };
+    /**
+     * Moves the path to the specified point in the canvas, without creating a line
+     *
+     * @name moveTo
+     * @function
+     * @param x {Number} The x-coordinate of where to move the path to
+     * @param y {Number} The y-coordinate of where to move the path to
+     */
+
+
+    Context2D.prototype.moveTo = function (x, y) {
+      if (isNaN(x) || isNaN(y)) {
+        console.error("jsPDF.context2d.moveTo: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.moveTo");
+      }
+
+      var pt = this.ctx.transform.applyToPoint(new Point(x, y));
+      this.path.push({
+        type: "mt",
+        x: pt.x,
+        y: pt.y
+      });
+      this.ctx.lastPoint = new Point(x, y);
+    };
+    /**
+     * Creates a path from the current point back to the starting point
+     *
+     * @name closePath
+     * @function
+     * @description The closePath() method creates a path from the current point back to the starting point.
+     */
+
+
+    Context2D.prototype.closePath = function () {
+      var pathBegin = new Point(0, 0);
+      var i = 0;
+
+      for (i = this.path.length - 1; i !== -1; i--) {
+        if (this.path[i].type === "begin") {
+          if (_typeof(this.path[i + 1]) === "object" && typeof this.path[i + 1].x === "number") {
+            pathBegin = new Point(this.path[i + 1].x, this.path[i + 1].y);
+            break;
+          }
+        }
+      }
+
+      this.path.push({
+        type: "close"
+      });
+      this.ctx.lastPoint = new Point(pathBegin.x, pathBegin.y);
+    };
+    /**
+     * Adds a new point and creates a line to that point from the last specified point in the canvas
+     *
+     * @name lineTo
+     * @function
+     * @param x The x-coordinate of where to create the line to
+     * @param y The y-coordinate of where to create the line to
+     * @description The lineTo() method adds a new point and creates a line TO that point FROM the last specified point in the canvas (this method does not draw the line).
+     */
+
+
+    Context2D.prototype.lineTo = function (x, y) {
+      if (isNaN(x) || isNaN(y)) {
+        console.error("jsPDF.context2d.lineTo: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.lineTo");
+      }
+
+      var pt = this.ctx.transform.applyToPoint(new Point(x, y));
+      this.path.push({
+        type: "lt",
+        x: pt.x,
+        y: pt.y
+      });
+      this.ctx.lastPoint = new Point(pt.x, pt.y);
+    };
+    /**
+     * Clips a region of any shape and size from the original canvas
+     *
+     * @name clip
+     * @function
+     * @description The clip() method clips a region of any shape and size from the original canvas.
+     */
+
+
+    Context2D.prototype.clip = function () {
+      this.ctx.clip_path = JSON.parse(JSON.stringify(this.path));
+      pathPreProcess.call(this, null, true);
+    };
+    /**
+     * Creates a cubic Bézier curve
+     *
+     * @name quadraticCurveTo
+     * @function
+     * @param cpx {Number} The x-coordinate of the Bézier control point
+     * @param cpy {Number} The y-coordinate of the Bézier control point
+     * @param x {Number} The x-coordinate of the ending point
+     * @param y {Number} The y-coordinate of the ending point
+     * @description The quadraticCurveTo() method adds a point to the current path by using the specified control points that represent a quadratic Bézier curve.<br /><br /> A quadratic Bézier curve requires two points. The first point is a control point that is used in the quadratic Bézier calculation and the second point is the ending point for the curve. The starting point for the curve is the last point in the current path. If a path does not exist, use the beginPath() and moveTo() methods to define a starting point.
+     */
+
+
+    Context2D.prototype.quadraticCurveTo = function (cpx, cpy, x, y) {
+      if (isNaN(x) || isNaN(y) || isNaN(cpx) || isNaN(cpy)) {
+        console.error("jsPDF.context2d.quadraticCurveTo: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.quadraticCurveTo");
+      }
+
+      var pt0 = this.ctx.transform.applyToPoint(new Point(x, y));
+      var pt1 = this.ctx.transform.applyToPoint(new Point(cpx, cpy));
+      this.path.push({
+        type: "qct",
+        x1: pt1.x,
+        y1: pt1.y,
+        x: pt0.x,
+        y: pt0.y
+      });
+      this.ctx.lastPoint = new Point(pt0.x, pt0.y);
+    };
+    /**
+     * Creates a cubic Bézier curve
+     *
+     * @name bezierCurveTo
+     * @function
+     * @param cp1x {Number} The x-coordinate of the first Bézier control point
+     * @param cp1y {Number} The y-coordinate of the first Bézier control point
+     * @param cp2x {Number} The x-coordinate of the second Bézier control point
+     * @param cp2y {Number} The y-coordinate of the second Bézier control point
+     * @param x {Number} The x-coordinate of the ending point
+     * @param y {Number} The y-coordinate of the ending point
+     * @description The bezierCurveTo() method adds a point to the current path by using the specified control points that represent a cubic Bézier curve. <br /><br />A cubic bezier curve requires three points. The first two points are control points that are used in the cubic Bézier calculation and the last point is the ending point for the curve.  The starting point for the curve is the last point in the current path. If a path does not exist, use the beginPath() and moveTo() methods to define a starting point.
+     */
+
+
+    Context2D.prototype.bezierCurveTo = function (cp1x, cp1y, cp2x, cp2y, x, y) {
+      if (isNaN(x) || isNaN(y) || isNaN(cp1x) || isNaN(cp1y) || isNaN(cp2x) || isNaN(cp2y)) {
+        console.error("jsPDF.context2d.bezierCurveTo: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.bezierCurveTo");
+      }
+
+      var pt0 = this.ctx.transform.applyToPoint(new Point(x, y));
+      var pt1 = this.ctx.transform.applyToPoint(new Point(cp1x, cp1y));
+      var pt2 = this.ctx.transform.applyToPoint(new Point(cp2x, cp2y));
+      this.path.push({
+        type: "bct",
+        x1: pt1.x,
+        y1: pt1.y,
+        x2: pt2.x,
+        y2: pt2.y,
+        x: pt0.x,
+        y: pt0.y
+      });
+      this.ctx.lastPoint = new Point(pt0.x, pt0.y);
+    };
+    /**
+     * Creates an arc/curve (used to create circles, or parts of circles)
+     *
+     * @name arc
+     * @function
+     * @param x {Number} The x-coordinate of the center of the circle
+     * @param y {Number} The y-coordinate of the center of the circle
+     * @param radius {Number} The radius of the circle
+     * @param startAngle {Number} The starting angle, in radians (0 is at the 3 o'clock position of the arc's circle)
+     * @param endAngle {Number} The ending angle, in radians
+     * @param counterclockwise {Boolean} Optional. Specifies whether the drawing should be counterclockwise or clockwise. False is default, and indicates clockwise, while true indicates counter-clockwise.
+     * @description The arc() method creates an arc/curve (used to create circles, or parts of circles).
+     */
+
+
+    Context2D.prototype.arc = function (x, y, radius, startAngle, endAngle, counterclockwise) {
+      if (isNaN(x) || isNaN(y) || isNaN(radius) || isNaN(startAngle) || isNaN(endAngle)) {
+        console.error("jsPDF.context2d.arc: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.arc");
+      }
+
+      counterclockwise = Boolean(counterclockwise);
+
+      if (!this.ctx.transform.isIdentity) {
+        var xpt = this.ctx.transform.applyToPoint(new Point(x, y));
+        x = xpt.x;
+        y = xpt.y;
+        var x_radPt = this.ctx.transform.applyToPoint(new Point(0, radius));
+        var x_radPt0 = this.ctx.transform.applyToPoint(new Point(0, 0));
+        radius = Math.sqrt(Math.pow(x_radPt.x - x_radPt0.x, 2) + Math.pow(x_radPt.y - x_radPt0.y, 2));
+      }
+
+      if (Math.abs(endAngle - startAngle) >= 2 * Math.PI) {
+        startAngle = 0;
+        endAngle = 2 * Math.PI;
+      }
+
+      this.path.push({
+        type: "arc",
+        x: x,
+        y: y,
+        radius: radius,
+        startAngle: startAngle,
+        endAngle: endAngle,
+        counterclockwise: counterclockwise
+      }); // this.ctx.lastPoint(new Point(pt.x,pt.y));
+    };
+    /**
+     * Creates an arc/curve between two tangents
+     *
+     * @name arcTo
+     * @function
+     * @param x1 {Number} The x-coordinate of the first tangent
+     * @param y1 {Number} The y-coordinate of the first tangent
+     * @param x2 {Number} The x-coordinate of the second tangent
+     * @param y2 {Number} The y-coordinate of the second tangent
+     * @param radius The radius of the arc
+     * @description The arcTo() method creates an arc/curve between two tangents on the canvas.
+     */
+    // eslint-disable-next-line no-unused-vars
+
+
+    Context2D.prototype.arcTo = function (x1, y1, x2, y2, radius) {
+      throw new Error("arcTo not implemented.");
+    };
+    /**
+     * Creates a rectangle
+     *
+     * @name rect
+     * @function
+     * @param x {Number} The x-coordinate of the upper-left corner of the rectangle
+     * @param y {Number} The y-coordinate of the upper-left corner of the rectangle
+     * @param w {Number} The width of the rectangle, in pixels
+     * @param h {Number} The height of the rectangle, in pixels
+     * @description The rect() method creates a rectangle.
+     */
+
+
+    Context2D.prototype.rect = function (x, y, w, h) {
+      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) {
+        console.error("jsPDF.context2d.rect: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.rect");
+      }
+
+      this.moveTo(x, y);
+      this.lineTo(x + w, y);
+      this.lineTo(x + w, y + h);
+      this.lineTo(x, y + h);
+      this.lineTo(x, y);
+      this.lineTo(x + w, y);
+      this.lineTo(x, y);
+    };
+    /**
+     * Draws a "filled" rectangle
+     *
+     * @name fillRect
+     * @function
+     * @param x {Number} The x-coordinate of the upper-left corner of the rectangle
+     * @param y {Number} The y-coordinate of the upper-left corner of the rectangle
+     * @param w {Number} The width of the rectangle, in pixels
+     * @param h {Number} The height of the rectangle, in pixels
+     * @description The fillRect() method draws a "filled" rectangle. The default color of the fill is black.
+     */
+
+
+    Context2D.prototype.fillRect = function (x, y, w, h) {
+      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) {
+        console.error("jsPDF.context2d.fillRect: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.fillRect");
+      }
+
+      if (isFillTransparent.call(this)) {
+        return;
+      }
+
+      var tmp = {};
+
+      if (this.lineCap !== "butt") {
+        tmp.lineCap = this.lineCap;
+        this.lineCap = "butt";
+      }
+
+      if (this.lineJoin !== "miter") {
+        tmp.lineJoin = this.lineJoin;
+        this.lineJoin = "miter";
+      }
+
+      this.beginPath();
+      this.rect(x, y, w, h);
+      this.fill();
+
+      if (tmp.hasOwnProperty("lineCap")) {
+        this.lineCap = tmp.lineCap;
+      }
+
+      if (tmp.hasOwnProperty("lineJoin")) {
+        this.lineJoin = tmp.lineJoin;
+      }
+    };
+    /**
+     *     Draws a rectangle (no fill)
+     *
+     * @name strokeRect
+     * @function
+     * @param x {Number} The x-coordinate of the upper-left corner of the rectangle
+     * @param y {Number} The y-coordinate of the upper-left corner of the rectangle
+     * @param w {Number} The width of the rectangle, in pixels
+     * @param h {Number} The height of the rectangle, in pixels
+     * @description The strokeRect() method draws a rectangle (no fill). The default color of the stroke is black.
+     */
+
+
+    Context2D.prototype.strokeRect = function strokeRect(x, y, w, h) {
+      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) {
+        console.error("jsPDF.context2d.strokeRect: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.strokeRect");
+      }
+
+      if (isStrokeTransparent.call(this)) {
+        return;
+      }
+
+      this.beginPath();
+      this.rect(x, y, w, h);
+      this.stroke();
+    };
+    /**
+     * Clears the specified pixels within a given rectangle
+     *
+     * @name clearRect
+     * @function
+     * @param x {Number} The x-coordinate of the upper-left corner of the rectangle
+     * @param y {Number} The y-coordinate of the upper-left corner of the rectangle
+     * @param w {Number} The width of the rectangle to clear, in pixels
+     * @param h {Number} The height of the rectangle to clear, in pixels
+     * @description We cannot clear PDF commands that were already written to PDF, so we use white instead. <br />
+     * As a special case, read a special flag (ignoreClearRect) and do nothing if it is set.
+     * This results in all calls to clearRect() to do nothing, and keep the canvas transparent.
+     * This flag is stored in the save/restore context and is managed the same way as other drawing states.
+     *
+     */
+
+
+    Context2D.prototype.clearRect = function (x, y, w, h) {
+      if (isNaN(x) || isNaN(y) || isNaN(w) || isNaN(h)) {
+        console.error("jsPDF.context2d.clearRect: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.clearRect");
+      }
+
+      if (this.ignoreClearRect) {
+        return;
+      }
+
+      this.fillStyle = "#ffffff";
+      this.fillRect(x, y, w, h);
+    };
+    /**
+     * Saves the state of the current context
+     *
+     * @name save
+     * @function
+     */
+
+
+    Context2D.prototype.save = function (doStackPush) {
+      doStackPush = typeof doStackPush === "boolean" ? doStackPush : true;
+      var tmpPageNumber = this.pdf.internal.getCurrentPageInfo().pageNumber;
+
+      for (var i = 0; i < this.pdf.internal.getNumberOfPages(); i++) {
+        this.pdf.setPage(i + 1);
+        this.pdf.internal.out("q");
+      }
+
+      this.pdf.setPage(tmpPageNumber);
+
+      if (doStackPush) {
+        this.ctx.fontSize = this.pdf.internal.getFontSize();
+        var ctx = new ContextLayer(this.ctx);
+        this.ctxStack.push(this.ctx);
+        this.ctx = ctx;
+      }
+    };
+    /**
+     * Returns previously saved path state and attributes
+     *
+     * @name restore
+     * @function
+     */
+
+
+    Context2D.prototype.restore = function (doStackPop) {
+      doStackPop = typeof doStackPop === "boolean" ? doStackPop : true;
+      var tmpPageNumber = this.pdf.internal.getCurrentPageInfo().pageNumber;
+
+      for (var i = 0; i < this.pdf.internal.getNumberOfPages(); i++) {
+        this.pdf.setPage(i + 1);
+        this.pdf.internal.out("Q");
+      }
+
+      this.pdf.setPage(tmpPageNumber);
+
+      if (doStackPop && this.ctxStack.length !== 0) {
+        this.ctx = this.ctxStack.pop();
+        this.fillStyle = this.ctx.fillStyle;
+        this.strokeStyle = this.ctx.strokeStyle;
+        this.font = this.ctx.font;
+        this.lineCap = this.ctx.lineCap;
+        this.lineWidth = this.ctx.lineWidth;
+        this.lineJoin = this.ctx.lineJoin;
+        this.lineDash = this.ctx.lineDash;
+        this.lineDashOffset = this.ctx.lineDashOffset;
+      }
+    };
+    /**
+     * @name toDataURL
+     * @function
+     */
+
+
+    Context2D.prototype.toDataURL = function () {
+      throw new Error("toDataUrl not implemented.");
+    }; //helper functions
+
+    /**
+     * Get the decimal values of r, g, b and a
+     *
+     * @name getRGBA
+     * @function
+     * @private
+     * @ignore
+     */
+
+
+    var getRGBA = function getRGBA(style) {
+      var rxRgb = /rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/;
+      var rxRgba = /rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d.]+)\s*\)/;
+      var rxTransparent = /transparent|rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*0+\s*\)/;
+      var r, g, b, a;
+
+      if (style.isCanvasGradient === true) {
+        style = style.getColor();
+      }
+
+      if (!style) {
+        return {
+          r: 0,
+          g: 0,
+          b: 0,
+          a: 0,
+          style: style
+        };
+      }
+
+      if (rxTransparent.test(style)) {
+        r = 0;
+        g = 0;
+        b = 0;
+        a = 0;
+      } else {
+        var matches = rxRgb.exec(style);
+
+        if (matches !== null) {
+          r = parseInt(matches[1]);
+          g = parseInt(matches[2]);
+          b = parseInt(matches[3]);
+          a = 1;
+        } else {
+          matches = rxRgba.exec(style);
+
+          if (matches !== null) {
+            r = parseInt(matches[1]);
+            g = parseInt(matches[2]);
+            b = parseInt(matches[3]);
+            a = parseFloat(matches[4]);
+          } else {
+            a = 1;
+
+            if (typeof style === "string" && style.charAt(0) !== "#") {
+              var rgbColor = new RGBColor(style);
+
+              if (rgbColor.ok) {
+                style = rgbColor.toHex();
+              } else {
+                style = "#000000";
+              }
+            }
+
+            if (style.length === 4) {
+              r = style.substring(1, 2);
+              r += r;
+              g = style.substring(2, 3);
+              g += g;
+              b = style.substring(3, 4);
+              b += b;
+            } else {
+              r = style.substring(1, 3);
+              g = style.substring(3, 5);
+              b = style.substring(5, 7);
+            }
+
+            r = parseInt(r, 16);
+            g = parseInt(g, 16);
+            b = parseInt(b, 16);
+          }
+        }
+      }
+
+      return {
+        r: r,
+        g: g,
+        b: b,
+        a: a,
+        style: style
+      };
+    };
+    /**
+     * @name isFillTransparent
+     * @function
+     * @private
+     * @ignore
+     * @returns {Boolean}
+     */
+
+
+    var isFillTransparent = function isFillTransparent() {
+      return this.ctx.isFillTransparent || this.globalAlpha == 0;
+    };
+    /**
+     * @name isStrokeTransparent
+     * @function
+     * @private
+     * @ignore
+     * @returns {Boolean}
+     */
+
+
+    var isStrokeTransparent = function isStrokeTransparent() {
+      return Boolean(this.ctx.isStrokeTransparent || this.globalAlpha == 0);
+    };
+    /**
+     * Draws "filled" text on the canvas
+     *
+     * @name fillText
+     * @function
+     * @param text {String} Specifies the text that will be written on the canvas
+     * @param x {Number} The x coordinate where to start painting the text (relative to the canvas)
+     * @param y {Number} The y coordinate where to start painting the text (relative to the canvas)
+     * @param maxWidth {Number} Optional. The maximum allowed width of the text, in pixels
+     * @description The fillText() method draws filled text on the canvas. The default color of the text is black.
+     */
+
+
+    Context2D.prototype.fillText = function (text, x, y, maxWidth) {
+      if (isNaN(x) || isNaN(y) || typeof text !== "string") {
+        console.error("jsPDF.context2d.fillText: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.fillText");
+      }
+
+      maxWidth = isNaN(maxWidth) ? undefined : maxWidth;
+
+      if (isFillTransparent.call(this)) {
+        return;
+      }
+
+      var degs = rad2deg(this.ctx.transform.rotation); // We only use X axis as scale hint
+
+      var scale = this.ctx.transform.scaleX;
+      putText.call(this, {
+        text: text,
+        x: x,
+        y: y,
+        scale: scale,
+        angle: degs,
+        align: this.textAlign,
+        maxWidth: maxWidth
+      });
+    };
+    /**
+     * Draws text on the canvas (no fill)
+     *
+     * @name strokeText
+     * @function
+     * @param text {String} Specifies the text that will be written on the canvas
+     * @param x {Number} The x coordinate where to start painting the text (relative to the canvas)
+     * @param y {Number} The y coordinate where to start painting the text (relative to the canvas)
+     * @param maxWidth {Number} Optional. The maximum allowed width of the text, in pixels
+     * @description The strokeText() method draws text (with no fill) on the canvas. The default color of the text is black.
+     */
+
+
+    Context2D.prototype.strokeText = function (text, x, y, maxWidth) {
+      if (isNaN(x) || isNaN(y) || typeof text !== "string") {
+        console.error("jsPDF.context2d.strokeText: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.strokeText");
+      }
+
+      if (isStrokeTransparent.call(this)) {
+        return;
+      }
+
+      maxWidth = isNaN(maxWidth) ? undefined : maxWidth;
+      var degs = rad2deg(this.ctx.transform.rotation);
+      var scale = this.ctx.transform.scaleX;
+      putText.call(this, {
+        text: text,
+        x: x,
+        y: y,
+        scale: scale,
+        renderingMode: "stroke",
+        angle: degs,
+        align: this.textAlign,
+        maxWidth: maxWidth
+      });
+    };
+    /**
+     * Returns an object that contains the width of the specified text
+     *
+     * @name measureText
+     * @function
+     * @param text {String} The text to be measured
+     * @description The measureText() method returns an object that contains the width of the specified text, in pixels.
+     * @returns {Number}
+     */
+
+
+    Context2D.prototype.measureText = function (text) {
+      if (typeof text !== "string") {
+        console.error("jsPDF.context2d.measureText: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.measureText");
+      }
+
+      var pdf = this.pdf;
+      var k = this.pdf.internal.scaleFactor;
+      var fontSize = pdf.internal.getFontSize();
+      var txtWidth = pdf.getStringUnitWidth(text) * fontSize / pdf.internal.scaleFactor;
+      txtWidth *= Math.round(k * 96 / 72 * 10000) / 10000;
+
+      var TextMetrics = function TextMetrics(options) {
+        options = options || {};
+
+        var _width = options.width || 0;
+
+        Object.defineProperty(this, "width", {
+          get: function get() {
+            return _width;
+          }
+        });
+        return this;
+      };
+
+      return new TextMetrics({
+        width: txtWidth
+      });
+    }; //Transformations
+
+    /**
+     * Scales the current drawing bigger or smaller
+     *
+     * @name scale
+     * @function
+     * @param scalewidth {Number} Scales the width of the current drawing (1=100%, 0.5=50%, 2=200%, etc.)
+     * @param scaleheight {Number} Scales the height of the current drawing (1=100%, 0.5=50%, 2=200%, etc.)
+     * @description The scale() method scales the current drawing, bigger or smaller.
+     */
+
+
+    Context2D.prototype.scale = function (scalewidth, scaleheight) {
+      if (isNaN(scalewidth) || isNaN(scaleheight)) {
+        console.error("jsPDF.context2d.scale: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.scale");
+      }
+
+      var matrix = new Matrix(scalewidth, 0.0, 0.0, scaleheight, 0.0, 0.0);
+      this.ctx.transform = this.ctx.transform.multiply(matrix);
+    };
+    /**
+     * Rotates the current drawing
+     *
+     * @name rotate
+     * @function
+     * @param angle {Number} The rotation angle, in radians.
+     * @description To calculate from degrees to radians: degrees*Math.PI/180. <br />
+     * Example: to rotate 5 degrees, specify the following: 5*Math.PI/180
+     */
+
+
+    Context2D.prototype.rotate = function (angle) {
+      if (isNaN(angle)) {
+        console.error("jsPDF.context2d.rotate: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.rotate");
+      }
+
+      var matrix = new Matrix(Math.cos(angle), Math.sin(angle), -Math.sin(angle), Math.cos(angle), 0.0, 0.0);
+      this.ctx.transform = this.ctx.transform.multiply(matrix);
+    };
+    /**
+     * Remaps the (0,0) position on the canvas
+     *
+     * @name translate
+     * @function
+     * @param x {Number} The value to add to horizontal (x) coordinates
+     * @param y {Number} The value to add to vertical (y) coordinates
+     * @description The translate() method remaps the (0,0) position on the canvas.
+     */
+
+
+    Context2D.prototype.translate = function (x, y) {
+      if (isNaN(x) || isNaN(y)) {
+        console.error("jsPDF.context2d.translate: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.translate");
+      }
+
+      var matrix = new Matrix(1.0, 0.0, 0.0, 1.0, x, y);
+      this.ctx.transform = this.ctx.transform.multiply(matrix);
+    };
+    /**
+     * Replaces the current transformation matrix for the drawing
+     *
+     * @name transform
+     * @function
+     * @param a {Number} Horizontal scaling
+     * @param b {Number} Horizontal skewing
+     * @param c {Number} Vertical skewing
+     * @param d {Number} Vertical scaling
+     * @param e {Number} Horizontal moving
+     * @param f {Number} Vertical moving
+     * @description Each object on the canvas has a current transformation matrix.<br /><br />The transform() method replaces the current transformation matrix. It multiplies the current transformation matrix with the matrix described by:<br /><br /><br /><br />a    c    e<br /><br />b    d    f<br /><br />0    0    1<br /><br />In other words, the transform() method lets you scale, rotate, move, and skew the current context.
+     */
+
+
+    Context2D.prototype.transform = function (a, b, c, d, e, f) {
+      if (isNaN(a) || isNaN(b) || isNaN(c) || isNaN(d) || isNaN(e) || isNaN(f)) {
+        console.error("jsPDF.context2d.transform: Invalid arguments", arguments);
+        throw new Error("Invalid arguments passed to jsPDF.context2d.transform");
+      }
+
+      var matrix = new Matrix(a, b, c, d, e, f);
+      this.ctx.transform = this.ctx.transform.multiply(matrix);
+    };
+    /**
+     * Resets the current transform to the identity matrix. Then runs transform()
+     *
+     * @name setTransform
+     * @function
+     * @param a {Number} Horizontal scaling
+     * @param b {Number} Horizontal skewing
+     * @param c {Number} Vertical skewing
+     * @param d {Number} Vertical scaling
+     * @param e {Number} Horizontal moving
+     * @param f {Number} Vertical moving
+     * @description Each object on the canvas has a current transformation matrix. <br /><br />The setTransform() method resets the current transform to the identity matrix, and then runs transform() with the same arguments.<br /><br />In other words, the setTransform() method lets you scale, rotate, move, and skew the current context.
+     */
+
+
+    Context2D.prototype.setTransform = function (a, b, c, d, e, f) {
+      a = isNaN(a) ? 1 : a;
+      b = isNaN(b) ? 0 : b;
+      c = isNaN(c) ? 0 : c;
+      d = isNaN(d) ? 1 : d;
+      e = isNaN(e) ? 0 : e;
+      f = isNaN(f) ? 0 : f;
+      this.ctx.transform = new Matrix(a, b, c, d, e, f);
+    };
+
+    var hasMargins = function hasMargins() {
+      return this.margin[0] > 0 || this.margin[1] > 0 || this.margin[2] > 0 || this.margin[3] > 0;
+    };
+    /**
+     * Draws an image, canvas, or video onto the canvas
+     *
+     * @function
+     * @param img {} Specifies the image, canvas, or video element to use
+     * @param sx {Number} Optional. The x coordinate where to start clipping
+     * @param sy {Number} Optional. The y coordinate where to start clipping
+     * @param swidth {Number} Optional. The width of the clipped image
+     * @param sheight {Number} Optional. The height of the clipped image
+     * @param x {Number} The x coordinate where to place the image on the canvas
+     * @param y {Number} The y coordinate where to place the image on the canvas
+     * @param width {Number} Optional. The width of the image to use (stretch or reduce the image)
+     * @param height {Number} Optional. The height of the image to use (stretch or reduce the image)
+     */
+
+
+    Context2D.prototype.drawImage = function (img, sx, sy, swidth, sheight, x, y, width, height) {
+      var imageProperties = this.pdf.getImageProperties(img);
+      var factorX = 1;
+      var factorY = 1;
+      var clipFactorX = 1;
+      var clipFactorY = 1;
+
+      if (typeof swidth !== "undefined" && typeof width !== "undefined") {
+        clipFactorX = width / swidth;
+        clipFactorY = height / sheight;
+        factorX = imageProperties.width / swidth * width / swidth;
+        factorY = imageProperties.height / sheight * height / sheight;
+      } //is sx and sy are set and x and y not, set x and y with values of sx and sy
+
+
+      if (typeof x === "undefined") {
+        x = sx;
+        y = sy;
+        sx = 0;
+        sy = 0;
+      }
+
+      if (typeof swidth !== "undefined" && typeof width === "undefined") {
+        width = swidth;
+        height = sheight;
+      }
+
+      if (typeof swidth === "undefined" && typeof width === "undefined") {
+        width = imageProperties.width;
+        height = imageProperties.height;
+      }
+
+      var decomposedTransformationMatrix = this.ctx.transform.decompose();
+      var angle = rad2deg(decomposedTransformationMatrix.rotate.shx);
+      var matrix = new Matrix();
+      matrix = matrix.multiply(decomposedTransformationMatrix.translate);
+      matrix = matrix.multiply(decomposedTransformationMatrix.skew);
+      matrix = matrix.multiply(decomposedTransformationMatrix.scale);
+      var xRect = matrix.applyToRectangle(new Rectangle(x - sx * clipFactorX, y - sy * clipFactorY, swidth * factorX, sheight * factorY));
+      var pageArray = getPagesByPath.call(this, xRect);
+      var pages = [];
+
+      for (var ii = 0; ii < pageArray.length; ii += 1) {
+        if (pages.indexOf(pageArray[ii]) === -1) {
+          pages.push(pageArray[ii]);
+        }
+      }
+
+      sortPages(pages);
+      var clipPath;
+
+      if (this.autoPaging) {
+        var min = pages[0];
+        var max = pages[pages.length - 1];
+
+        for (var i = min; i < max + 1; i++) {
+          this.pdf.setPage(i);
+          var pageWidthMinusMargins = this.pdf.internal.pageSize.width - this.margin[3] - this.margin[1];
+          var topMargin = i === 1 ? this.posY + this.margin[0] : this.margin[0];
+          var firstPageHeight = this.pdf.internal.pageSize.height - this.posY - this.margin[0] - this.margin[2];
+          var pageHeightMinusMargins = this.pdf.internal.pageSize.height - this.margin[0] - this.margin[2];
+          var previousPageHeightSum = i === 1 ? 0 : firstPageHeight + (i - 2) * pageHeightMinusMargins;
+
+          if (this.ctx.clip_path.length !== 0) {
+            var tmpPaths = this.path;
+            clipPath = JSON.parse(JSON.stringify(this.ctx.clip_path));
+            this.path = pathPositionRedo(clipPath, this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset);
+            drawPaths.call(this, "fill", true);
+            this.path = tmpPaths;
+          }
+
+          var tmpRect = JSON.parse(JSON.stringify(xRect));
+          tmpRect = pathPositionRedo([tmpRect], this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset)[0];
+          var needsClipping = (i > min || i < max) && hasMargins.call(this);
+
+          if (needsClipping) {
+            this.pdf.saveGraphicsState();
+            this.pdf.rect(this.margin[3], this.margin[0], pageWidthMinusMargins, pageHeightMinusMargins, null).clip().discardPath();
+          }
+
+          this.pdf.addImage(img, "JPEG", tmpRect.x, tmpRect.y, tmpRect.w, tmpRect.h, null, null, angle);
+
+          if (needsClipping) {
+            this.pdf.restoreGraphicsState();
+          }
+        }
+      } else {
+        this.pdf.addImage(img, "JPEG", xRect.x, xRect.y, xRect.w, xRect.h, null, null, angle);
+      }
+    };
+
+    var getPagesByPath = function getPagesByPath(path, pageWrapX, pageWrapY) {
+      var result = [];
+      pageWrapX = pageWrapX || this.pdf.internal.pageSize.width;
+      pageWrapY = pageWrapY || this.pdf.internal.pageSize.height - this.margin[0] - this.margin[2];
+      var yOffset = this.posY + this.ctx.prevPageLastElemOffset;
+
+      switch (path.type) {
+        default:
+        case "mt":
+        case "lt":
+          result.push(Math.floor((path.y + yOffset) / pageWrapY) + 1);
+          break;
+
+        case "arc":
+          result.push(Math.floor((path.y + yOffset - path.radius) / pageWrapY) + 1);
+          result.push(Math.floor((path.y + yOffset + path.radius) / pageWrapY) + 1);
+          break;
+
+        case "qct":
+          var rectOfQuadraticCurve = getQuadraticCurveBoundary(this.ctx.lastPoint.x, this.ctx.lastPoint.y, path.x1, path.y1, path.x, path.y);
+          result.push(Math.floor((rectOfQuadraticCurve.y + yOffset) / pageWrapY) + 1);
+          result.push(Math.floor((rectOfQuadraticCurve.y + rectOfQuadraticCurve.h + yOffset) / pageWrapY) + 1);
+          break;
+
+        case "bct":
+          var rectOfBezierCurve = getBezierCurveBoundary(this.ctx.lastPoint.x, this.ctx.lastPoint.y, path.x1, path.y1, path.x2, path.y2, path.x, path.y);
+          result.push(Math.floor((rectOfBezierCurve.y + yOffset) / pageWrapY) + 1);
+          result.push(Math.floor((rectOfBezierCurve.y + rectOfBezierCurve.h + yOffset) / pageWrapY) + 1);
+          break;
+
+        case "rect":
+          result.push(Math.floor((path.y + yOffset) / pageWrapY) + 1);
+          result.push(Math.floor((path.y + path.h + yOffset) / pageWrapY) + 1);
+      }
+
+      for (var i = 0; i < result.length; i += 1) {
+        while (this.pdf.internal.getNumberOfPages() < result[i]) {
+          addPage.call(this);
+        }
+      }
+
+      return result;
+    };
+
+    var addPage = function addPage() {
+      var fillStyle = this.fillStyle;
+      var strokeStyle = this.strokeStyle;
+      var font = this.font;
+      var lineCap = this.lineCap;
+      var lineWidth = this.lineWidth;
+      var lineJoin = this.lineJoin;
+      this.pdf.addPage();
+      this.fillStyle = fillStyle;
+      this.strokeStyle = strokeStyle;
+      this.font = font;
+      this.lineCap = lineCap;
+      this.lineWidth = lineWidth;
+      this.lineJoin = lineJoin;
+    };
+
+    var pathPositionRedo = function pathPositionRedo(paths, x, y) {
+      for (var i = 0; i < paths.length; i++) {
+        switch (paths[i].type) {
+          case "bct":
+            paths[i].x2 += x;
+            paths[i].y2 += y;
+
+          case "qct":
+            paths[i].x1 += x;
+            paths[i].y1 += y;
+
+          case "mt":
+          case "lt":
+          case "arc":
+          default:
+            paths[i].x += x;
+            paths[i].y += y;
+        }
+      }
+
+      return paths;
+    };
+
+    var sortPages = function sortPages(pages) {
+      return pages.sort(function (a, b) {
+        return a - b;
+      });
+    };
+
+    var pathPreProcess = function pathPreProcess(rule, isClip) {
+      var fillStyle = this.fillStyle;
+      var strokeStyle = this.strokeStyle;
+      var lineCap = this.lineCap;
+      var oldLineWidth = this.lineWidth;
+      var lineWidth = Math.abs(oldLineWidth * this.ctx.transform.scaleX);
+      var lineJoin = this.lineJoin;
+      var origPath = JSON.parse(JSON.stringify(this.path));
+      var xPath = JSON.parse(JSON.stringify(this.path));
+      var clipPath;
+      var tmpPath;
+      var pages = [];
+
+      for (var i = 0; i < xPath.length; i++) {
+        if (typeof xPath[i].x !== "undefined") {
+          var page = getPagesByPath.call(this, xPath[i]);
+
+          for (var ii = 0; ii < page.length; ii += 1) {
+            if (pages.indexOf(page[ii]) === -1) {
+              pages.push(page[ii]);
+            }
+          }
+        }
+      }
+
+      for (var j = 0; j < pages.length; j++) {
+        while (this.pdf.internal.getNumberOfPages() < pages[j]) {
+          addPage.call(this);
+        }
+      }
+
+      sortPages(pages);
+
+      if (this.autoPaging) {
+        var min = pages[0];
+        var max = pages[pages.length - 1];
+
+        for (var k = min; k < max + 1; k++) {
+          this.pdf.setPage(k);
+          this.fillStyle = fillStyle;
+          this.strokeStyle = strokeStyle;
+          this.lineCap = lineCap;
+          this.lineWidth = lineWidth;
+          this.lineJoin = lineJoin;
+          var pageWidthMinusMargins = this.pdf.internal.pageSize.width - this.margin[3] - this.margin[1];
+          var topMargin = k === 1 ? this.posY + this.margin[0] : this.margin[0];
+          var firstPageHeight = this.pdf.internal.pageSize.height - this.posY - this.margin[0] - this.margin[2];
+          var pageHeightMinusMargins = this.pdf.internal.pageSize.height - this.margin[0] - this.margin[2];
+          var previousPageHeightSum = k === 1 ? 0 : firstPageHeight + (k - 2) * pageHeightMinusMargins;
+
+          if (this.ctx.clip_path.length !== 0) {
+            var tmpPaths = this.path;
+            clipPath = JSON.parse(JSON.stringify(this.ctx.clip_path));
+            this.path = pathPositionRedo(clipPath, this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset);
+            drawPaths.call(this, rule, true);
+            this.path = tmpPaths;
+          }
+
+          tmpPath = JSON.parse(JSON.stringify(origPath));
+          this.path = pathPositionRedo(tmpPath, this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset);
+
+          if (isClip === false || k === 0) {
+            var needsClipping = (k > min || k < max) && hasMargins.call(this);
+
+            if (needsClipping) {
+              this.pdf.saveGraphicsState();
+              this.pdf.rect(this.margin[3], this.margin[0], pageWidthMinusMargins, pageHeightMinusMargins, null).clip().discardPath();
+            }
+
+            drawPaths.call(this, rule, isClip);
+
+            if (needsClipping) {
+              this.pdf.restoreGraphicsState();
+            }
+          }
+
+          this.lineWidth = oldLineWidth;
+        }
+      } else {
+        this.lineWidth = lineWidth;
+        drawPaths.call(this, rule, isClip);
+        this.lineWidth = oldLineWidth;
+      }
+
+      this.path = origPath;
+    };
+    /**
+     * Processes the paths
+     *
+     * @function
+     * @param rule {String}
+     * @param isClip {Boolean}
+     * @private
+     * @ignore
+     */
+
+
+    var drawPaths = function drawPaths(rule, isClip) {
+      if (rule === "stroke" && !isClip && isStrokeTransparent.call(this)) {
+        return;
+      }
+
+      if (rule !== "stroke" && !isClip && isFillTransparent.call(this)) {
+        return;
+      }
+
+      var moves = []; //var alpha = (this.ctx.fillOpacity < 1) ? this.ctx.fillOpacity : this.ctx.globalAlpha;
+
+      var delta;
+      var xPath = this.path;
+
+      for (var i = 0; i < xPath.length; i++) {
+        var pt = xPath[i];
+
+        switch (pt.type) {
+          case "begin":
+            moves.push({
+              begin: true
+            });
+            break;
+
+          case "close":
+            moves.push({
+              close: true
+            });
+            break;
+
+          case "mt":
+            moves.push({
+              start: pt,
+              deltas: [],
+              abs: []
+            });
+            break;
+
+          case "lt":
+            var iii = moves.length;
+
+            if (xPath[i - 1] && !isNaN(xPath[i - 1].x)) {
+              delta = [pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
+
+              if (iii > 0) {
+                for (iii; iii >= 0; iii--) {
+                  if (moves[iii - 1].close !== true && moves[iii - 1].begin !== true) {
+                    moves[iii - 1].deltas.push(delta);
+                    moves[iii - 1].abs.push(pt);
+                    break;
+                  }
+                }
+              }
+            }
+
+            break;
+
+          case "bct":
+            delta = [pt.x1 - xPath[i - 1].x, pt.y1 - xPath[i - 1].y, pt.x2 - xPath[i - 1].x, pt.y2 - xPath[i - 1].y, pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
+            moves[moves.length - 1].deltas.push(delta);
+            break;
+
+          case "qct":
+            var x1 = xPath[i - 1].x + 2.0 / 3.0 * (pt.x1 - xPath[i - 1].x);
+            var y1 = xPath[i - 1].y + 2.0 / 3.0 * (pt.y1 - xPath[i - 1].y);
+            var x2 = pt.x + 2.0 / 3.0 * (pt.x1 - pt.x);
+            var y2 = pt.y + 2.0 / 3.0 * (pt.y1 - pt.y);
+            var x3 = pt.x;
+            var y3 = pt.y;
+            delta = [x1 - xPath[i - 1].x, y1 - xPath[i - 1].y, x2 - xPath[i - 1].x, y2 - xPath[i - 1].y, x3 - xPath[i - 1].x, y3 - xPath[i - 1].y];
+            moves[moves.length - 1].deltas.push(delta);
+            break;
+
+          case "arc":
+            moves.push({
+              deltas: [],
+              abs: [],
+              arc: true
+            });
+
+            if (Array.isArray(moves[moves.length - 1].abs)) {
+              moves[moves.length - 1].abs.push(pt);
+            }
+
+            break;
+        }
+      }
+
+      var style;
+
+      if (!isClip) {
+        if (rule === "stroke") {
+          style = "stroke";
+        } else {
+          style = "fill";
+        }
+      } else {
+        style = null;
+      }
+
+      var began = false;
+
+      for (var k = 0; k < moves.length; k++) {
+        if (moves[k].arc) {
+          var arcs = moves[k].abs;
+
+          for (var ii = 0; ii < arcs.length; ii++) {
+            var arc = arcs[ii];
+
+            if (arc.type === "arc") {
+              drawArc.call(this, arc.x, arc.y, arc.radius, arc.startAngle, arc.endAngle, arc.counterclockwise, undefined, isClip, !began);
+            } else {
+              drawLine.call(this, arc.x, arc.y);
+            }
+
+            began = true;
+          }
+        } else if (moves[k].close === true) {
+          this.pdf.internal.out("h");
+          began = false;
+        } else if (moves[k].begin !== true) {
+          var x = moves[k].start.x;
+          var y = moves[k].start.y;
+          drawLines.call(this, moves[k].deltas, x, y);
+          began = true;
+        }
+      }
+
+      if (style) {
+        putStyle.call(this, style);
+      }
+
+      if (isClip) {
+        doClip.call(this);
+      }
+    };
+
+    var getBaseline = function getBaseline(y) {
+      var height = this.pdf.internal.getFontSize() / this.pdf.internal.scaleFactor;
+      var descent = height * (this.pdf.internal.getLineHeightFactor() - 1);
+
+      switch (this.ctx.textBaseline) {
+        case "bottom":
+          return y - descent;
+
+        case "top":
+          return y + height - descent;
+
+        case "hanging":
+          return y + height - 2 * descent;
+
+        case "middle":
+          return y + height / 2 - descent;
+
+        case "ideographic":
+          // TODO not implemented
+          return y;
+
+        case "alphabetic":
+        default:
+          return y;
+      }
+    };
+
+    var getTextBottom = function getTextBottom(yBaseLine) {
+      var height = this.pdf.internal.getFontSize() / this.pdf.internal.scaleFactor;
+      var descent = height * (this.pdf.internal.getLineHeightFactor() - 1);
+      return yBaseLine + descent;
+    };
+
+    Context2D.prototype.createLinearGradient = function createLinearGradient() {
+      var canvasGradient = function canvasGradient() {};
+
+      canvasGradient.colorStops = [];
+
+      canvasGradient.addColorStop = function (offset, color) {
+        this.colorStops.push([offset, color]);
+      };
+
+      canvasGradient.getColor = function () {
+        if (this.colorStops.length === 0) {
+          return "#000000";
+        }
+
+        return this.colorStops[0][1];
+      };
+
+      canvasGradient.isCanvasGradient = true;
+      return canvasGradient;
+    };
+
+    Context2D.prototype.createPattern = function createPattern() {
+      return this.createLinearGradient();
+    };
+
+    Context2D.prototype.createRadialGradient = function createRadialGradient() {
+      return this.createLinearGradient();
+    };
+    /**
+     *
+     * @param x Edge point X
+     * @param y Edge point Y
+     * @param r Radius
+     * @param a1 start angle
+     * @param a2 end angle
+     * @param counterclockwise
+     * @param style
+     * @param isClip
+     */
+
+
+    var drawArc = function drawArc(x, y, r, a1, a2, counterclockwise, style, isClip, includeMove) {
+      // http://hansmuller-flex.blogspot.com/2011/10/more-about-approximating-circular-arcs.html
+      var curves = createArc.call(this, r, a1, a2, counterclockwise);
+
+      for (var i = 0; i < curves.length; i++) {
+        var curve = curves[i];
+
+        if (i === 0) {
+          if (includeMove) {
+            doMove.call(this, curve.x1 + x, curve.y1 + y);
+          } else {
+            drawLine.call(this, curve.x1 + x, curve.y1 + y);
+          }
+        }
+
+        drawCurve.call(this, x, y, curve.x2, curve.y2, curve.x3, curve.y3, curve.x4, curve.y4);
+      }
+
+      if (!isClip) {
+        putStyle.call(this, style);
+      } else {
+        doClip.call(this);
+      }
+    };
+
+    var putStyle = function putStyle(style) {
+      switch (style) {
+        case "stroke":
+          this.pdf.internal.out("S");
+          break;
+
+        case "fill":
+          this.pdf.internal.out("f");
+          break;
+      }
+    };
+
+    var doClip = function doClip() {
+      this.pdf.clip();
+      this.pdf.discardPath();
+    };
+
+    var doMove = function doMove(x, y) {
+      this.pdf.internal.out(getHorizontalCoordinateString(x) + " " + getVerticalCoordinateString(y) + " m");
+    };
+
+    var putText = function putText(options) {
+      var textAlign;
+
+      switch (options.align) {
+        case "right":
+        case "end":
+          textAlign = "right";
+          break;
+
+        case "center":
+          textAlign = "center";
+          break;
+
+        case "left":
+        case "start":
+        default:
+          textAlign = "left";
+          break;
+      }
+
+      var textDimensions = this.pdf.getTextDimensions(options.text);
+      var yBaseLine = getBaseline.call(this, options.y);
+      var yBottom = getTextBottom.call(this, yBaseLine);
+      var yTop = yBottom - textDimensions.h;
+      var pt = this.ctx.transform.applyToPoint(new Point(options.x, yBaseLine));
+      var decomposedTransformationMatrix = this.ctx.transform.decompose();
+      var matrix = new Matrix();
+      matrix = matrix.multiply(decomposedTransformationMatrix.translate);
+      matrix = matrix.multiply(decomposedTransformationMatrix.skew);
+      matrix = matrix.multiply(decomposedTransformationMatrix.scale);
+      var baselineRect = this.ctx.transform.applyToRectangle(new Rectangle(options.x, yBaseLine, textDimensions.w, textDimensions.h));
+      var textBounds = matrix.applyToRectangle(new Rectangle(options.x, yTop, textDimensions.w, textDimensions.h));
+      var pageArray = getPagesByPath.call(this, textBounds);
+      var pages = [];
+
+      for (var ii = 0; ii < pageArray.length; ii += 1) {
+        if (pages.indexOf(pageArray[ii]) === -1) {
+          pages.push(pageArray[ii]);
+        }
+      }
+
+      sortPages(pages);
+      var clipPath, oldSize, oldLineWidth;
+
+      if (this.autoPaging) {
+        var min = pages[0];
+        var max = pages[pages.length - 1];
+
+        for (var i = min; i < max + 1; i++) {
+          this.pdf.setPage(i);
+          var topMargin = i === 1 ? this.posY + this.margin[0] : this.margin[0];
+          var firstPageHeight = this.pdf.internal.pageSize.height - this.posY - this.margin[0] - this.margin[2];
+          var pageHeightMinusBottomMargin = this.pdf.internal.pageSize.height - this.margin[2];
+          var pageHeightMinusMargins = pageHeightMinusBottomMargin - this.margin[0];
+          var pageWidthMinusRightMargin = this.pdf.internal.pageSize.width - this.margin[1];
+          var pageWidthMinusMargins = pageWidthMinusRightMargin - this.margin[3];
+          var previousPageHeightSum = i === 1 ? 0 : firstPageHeight + (i - 2) * pageHeightMinusMargins;
+
+          if (this.ctx.clip_path.length !== 0) {
+            var tmpPaths = this.path;
+            clipPath = JSON.parse(JSON.stringify(this.ctx.clip_path));
+            this.path = pathPositionRedo(clipPath, this.posX + this.margin[3], -1 * previousPageHeightSum + topMargin);
+            drawPaths.call(this, "fill", true);
+            this.path = tmpPaths;
+          }
+
+          var textBoundsOnPage = pathPositionRedo([JSON.parse(JSON.stringify(textBounds))], this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset)[0];
+
+          if (options.scale >= 0.01) {
+            oldSize = this.pdf.internal.getFontSize();
+            this.pdf.setFontSize(oldSize * options.scale);
+            oldLineWidth = this.lineWidth;
+            this.lineWidth = oldLineWidth * options.scale;
+          }
+
+          var doSlice = this.autoPaging !== "text";
+
+          if (doSlice || textBoundsOnPage.y + textBoundsOnPage.h <= pageHeightMinusBottomMargin) {
+            if (doSlice || textBoundsOnPage.y >= topMargin && textBoundsOnPage.x <= pageWidthMinusRightMargin) {
+              var croppedText = doSlice ? options.text : this.pdf.splitTextToSize(options.text, options.maxWidth || pageWidthMinusRightMargin - textBoundsOnPage.x)[0];
+              var baseLineRectOnPage = pathPositionRedo([JSON.parse(JSON.stringify(baselineRect))], this.posX + this.margin[3], -previousPageHeightSum + topMargin + this.ctx.prevPageLastElemOffset)[0];
+              var needsClipping = doSlice && (i > min || i < max) && hasMargins.call(this);
+
+              if (needsClipping) {
+                this.pdf.saveGraphicsState();
+                this.pdf.rect(this.margin[3], this.margin[0], pageWidthMinusMargins, pageHeightMinusMargins, null).clip().discardPath();
+              }
+
+              this.pdf.text(croppedText, baseLineRectOnPage.x, baseLineRectOnPage.y, {
+                angle: options.angle,
+                align: textAlign,
+                renderingMode: options.renderingMode
+              });
+
+              if (needsClipping) {
+                this.pdf.restoreGraphicsState();
+              }
+            }
+          } else {
+            // This text is the last element of the page, but it got cut off due to the margin
+            // so we render it in the next page
+            if (textBoundsOnPage.y < pageHeightMinusBottomMargin) {
+              // As a result, all other elements have their y offset increased
+              this.ctx.prevPageLastElemOffset += pageHeightMinusBottomMargin - textBoundsOnPage.y;
+            }
+          }
+
+          if (options.scale >= 0.01) {
+            this.pdf.setFontSize(oldSize);
+            this.lineWidth = oldLineWidth;
+          }
+        }
+      } else {
+        if (options.scale >= 0.01) {
+          oldSize = this.pdf.internal.getFontSize();
+          this.pdf.setFontSize(oldSize * options.scale);
+          oldLineWidth = this.lineWidth;
+          this.lineWidth = oldLineWidth * options.scale;
+        }
+
+        this.pdf.text(options.text, pt.x + this.posX, pt.y + this.posY, {
+          angle: options.angle,
+          align: textAlign,
+          renderingMode: options.renderingMode,
+          maxWidth: options.maxWidth
+        });
+
+        if (options.scale >= 0.01) {
+          this.pdf.setFontSize(oldSize);
+          this.lineWidth = oldLineWidth;
+        }
+      }
+    };
+
+    var drawLine = function drawLine(x, y, prevX, prevY) {
+      prevX = prevX || 0;
+      prevY = prevY || 0;
+      this.pdf.internal.out(getHorizontalCoordinateString(x + prevX) + " " + getVerticalCoordinateString(y + prevY) + " l");
+    };
+
+    var drawLines = function drawLines(lines, x, y) {
+      return this.pdf.lines(lines, x, y, null, null);
+    };
+
+    var drawCurve = function drawCurve(x, y, x1, y1, x2, y2, x3, y3) {
+      this.pdf.internal.out([f2(getHorizontalCoordinate(x1 + x)), f2(getVerticalCoordinate(y1 + y)), f2(getHorizontalCoordinate(x2 + x)), f2(getVerticalCoordinate(y2 + y)), f2(getHorizontalCoordinate(x3 + x)), f2(getVerticalCoordinate(y3 + y)), "c"].join(" "));
+    };
+    /**
+     * Return a array of objects that represent bezier curves which approximate the circular arc centered at the origin, from startAngle to endAngle (radians) with the specified radius.
+     *
+     * Each bezier curve is an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points.
+     * @function createArc
+     */
+
+
+    var createArc = function createArc(radius, startAngle, endAngle, anticlockwise) {
+      var EPSILON = 0.00001; // Roughly 1/1000th of a degree, see below
+
+      var twoPi = Math.PI * 2;
+      var halfPi = Math.PI / 2.0;
+
+      while (startAngle > endAngle) {
+        startAngle = startAngle - twoPi;
+      }
+
+      var totalAngle = Math.abs(endAngle - startAngle);
+
+      if (totalAngle < twoPi) {
+        if (anticlockwise) {
+          totalAngle = twoPi - totalAngle;
+        }
+      } // Compute the sequence of arc curves, up to PI/2 at a time.
+
+
+      var curves = []; // clockwise or counterclockwise
+
+      var sgn = anticlockwise ? -1 : +1;
+      var a1 = startAngle;
+
+      for (; totalAngle > EPSILON;) {
+        var remain = sgn * Math.min(totalAngle, halfPi);
+        var a2 = a1 + remain;
+        curves.push(createSmallArc.call(this, radius, a1, a2));
+        totalAngle -= Math.abs(a2 - a1);
+        a1 = a2;
+      }
+
+      return curves;
+    };
+    /**
+     * Cubic bezier approximation of a circular arc centered at the origin, from (radians) a1 to a2, where a2-a1 < pi/2. The arc's radius is r.
+     *
+     * Returns an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points.
+     *
+     * This algorithm is based on the approach described in: A. Riškus, "Approximation of a Cubic Bezier Curve by Circular Arcs and Vice Versa," Information Technology and Control, 35(4), 2006 pp. 371-378.
+     */
+
+
+    var createSmallArc = function createSmallArc(r, a1, a2) {
+      var a = (a2 - a1) / 2.0;
+      var x4 = r * Math.cos(a);
+      var y4 = r * Math.sin(a);
+      var x1 = x4;
+      var y1 = -y4;
+      var q1 = x1 * x1 + y1 * y1;
+      var q2 = q1 + x1 * x4 + y1 * y4;
+      var k2 = 4 / 3 * (Math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4);
+      var x2 = x1 - k2 * y1;
+      var y2 = y1 + k2 * x1;
+      var x3 = x2;
+      var y3 = -y2;
+      var ar = a + a1;
+      var cos_ar = Math.cos(ar);
+      var sin_ar = Math.sin(ar);
+      return {
+        x1: r * Math.cos(a1),
+        y1: r * Math.sin(a1),
+        x2: x2 * cos_ar - y2 * sin_ar,
+        y2: x2 * sin_ar + y2 * cos_ar,
+        x3: x3 * cos_ar - y3 * sin_ar,
+        y3: x3 * sin_ar + y3 * cos_ar,
+        x4: r * Math.cos(a2),
+        y4: r * Math.sin(a2)
+      };
+    };
+
+    var rad2deg = function rad2deg(value) {
+      return value * 180 / Math.PI;
+    };
+
+    var getQuadraticCurveBoundary = function getQuadraticCurveBoundary(sx, sy, cpx, cpy, ex, ey) {
+      var midX1 = sx + (cpx - sx) * 0.5;
+      var midY1 = sy + (cpy - sy) * 0.5;
+      var midX2 = ex + (cpx - ex) * 0.5;
+      var midY2 = ey + (cpy - ey) * 0.5;
+      var resultX1 = Math.min(sx, ex, midX1, midX2);
+      var resultX2 = Math.max(sx, ex, midX1, midX2);
+      var resultY1 = Math.min(sy, ey, midY1, midY2);
+      var resultY2 = Math.max(sy, ey, midY1, midY2);
+      return new Rectangle(resultX1, resultY1, resultX2 - resultX1, resultY2 - resultY1);
+    }; //De Casteljau algorithm
+
+
+    var getBezierCurveBoundary = function getBezierCurveBoundary(ax, ay, bx, by, cx, cy, dx, dy) {
+      var tobx = bx - ax;
+      var toby = by - ay;
+      var tocx = cx - bx;
+      var tocy = cy - by;
+      var todx = dx - cx;
+      var tody = dy - cy;
+      var precision = 40;
+      var d, i, px, py, qx, qy, rx, ry, tx, ty, sx, sy, x, y, minx, miny, maxx, maxy, toqx, toqy, torx, tory, totx, toty;
+
+      for (i = 0; i < precision + 1; i++) {
+        d = i / precision;
+        px = ax + d * tobx;
+        py = ay + d * toby;
+        qx = bx + d * tocx;
+        qy = by + d * tocy;
+        rx = cx + d * todx;
+        ry = cy + d * tody;
+        toqx = qx - px;
+        toqy = qy - py;
+        torx = rx - qx;
+        tory = ry - qy;
+        sx = px + d * toqx;
+        sy = py + d * toqy;
+        tx = qx + d * torx;
+        ty = qy + d * tory;
+        totx = tx - sx;
+        toty = ty - sy;
+        x = sx + d * totx;
+        y = sy + d * toty;
+
+        if (i == 0) {
+          minx = x;
+          miny = y;
+          maxx = x;
+          maxy = y;
+        } else {
+          minx = Math.min(minx, x);
+          miny = Math.min(miny, y);
+          maxx = Math.max(maxx, x);
+          maxy = Math.max(maxy, y);
+        }
+      }
+
+      return new Rectangle(Math.round(minx), Math.round(miny), Math.round(maxx - minx), Math.round(maxy - miny));
+    };
+
+    var getPrevLineDashValue = function getPrevLineDashValue(lineDash, lineDashOffset) {
+      return JSON.stringify({
+        lineDash: lineDash,
+        lineDashOffset: lineDashOffset
+      });
+    };
+
+    var setLineDash = function setLineDash() {
+      // Avoid unnecessary line dash declarations.
+      if (!this.prevLineDash && !this.ctx.lineDash.length && !this.ctx.lineDashOffset) {
+        return;
+      } // Avoid unnecessary line dash declarations.
+
+
+      var nextLineDash = getPrevLineDashValue(this.ctx.lineDash, this.ctx.lineDashOffset);
+
+      if (this.prevLineDash !== nextLineDash) {
+        this.pdf.setLineDash(this.ctx.lineDash, this.ctx.lineDashOffset);
+        this.prevLineDash = nextLineDash;
+      }
+    };
+  })(jsPDF.API);
+
+  // DEFLATE is a complex format; to read this code, you should probably check the RFC first:
+  // https://tools.ietf.org/html/rfc1951
+  // You may also wish to take a look at the guide I made about this program:
+  // https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad
+  // Much of the following code is similar to that of UZIP.js:
+  // https://github.com/photopea/UZIP.js
+  // Many optimizations have been made, so the bundle size is ultimately smaller but performance is similar.
+  // Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint
+  // is better for memory in most engines (I *think*).
+  // Mediocre shim
+  var Worker;
+
+  try {
+    Worker = require('worker_threads').Worker;
+  } catch (e) {}
+
+  var u8 = Uint8Array,
+      u16 = Uint16Array,
+      u32 = Uint32Array; // fixed length extra bits
+
+  var fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0,
+  /* unused */
+  0, 0,
+  /* impossible */
+  0]); // fixed distance extra bits
+  // see fleb note
+
+  var fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
+  /* unused */
+  0, 0]); // code length index map
+
+  var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); // get base, reverse index map from extra bits
+
+  var freb = function (eb, start) {
+    var b = new u16(31);
+
+    for (var i = 0; i < 31; ++i) {
+      b[i] = start += 1 << eb[i - 1];
+    } // numbers here are at max 18 bits
+
+
+    var r = new u32(b[30]);
+
+    for (var i = 1; i < 30; ++i) {
+      for (var j = b[i]; j < b[i + 1]; ++j) {
+        r[j] = j - b[i] << 5 | i;
+      }
+    }
+
+    return [b, r];
+  };
+
+  var _a = freb(fleb, 2),
+      fl = _a[0],
+      revfl = _a[1]; // we can ignore the fact that the other numbers are wrong; they never happen anyway
+
+
+  fl[28] = 258, revfl[258] = 28;
+
+  var _b = freb(fdeb, 0),
+      fd = _b[0],
+      revfd = _b[1]; // map of value to reverse (assuming 16 bits)
+
+
+  var rev = new u16(32768);
+
+  for (var i = 0; i < 32768; ++i) {
+    // reverse table algorithm from SO
+    var x = (i & 0xAAAA) >>> 1 | (i & 0x5555) << 1;
+    x = (x & 0xCCCC) >>> 2 | (x & 0x3333) << 2;
+    x = (x & 0xF0F0) >>> 4 | (x & 0x0F0F) << 4;
+    rev[i] = ((x & 0xFF00) >>> 8 | (x & 0x00FF) << 8) >>> 1;
+  } // create huffman tree from u8 "map": index -> code length for code index
+  // mb (max bits) must be at most 15
+  // TODO: optimize/split up?
+
+
+  var hMap = function (cd, mb, r) {
+    var s = cd.length; // index
+
+    var i = 0; // u16 "map": index -> # of codes with bit length = index
+
+    var l = new u16(mb); // length of cd must be 288 (total # of codes)
+
+    for (; i < s; ++i) ++l[cd[i] - 1]; // u16 "map": index -> minimum code for bit length = index
+
+
+    var le = new u16(mb);
+
+    for (i = 0; i < mb; ++i) {
+      le[i] = le[i - 1] + l[i - 1] << 1;
+    }
+
+    var co;
+
+    if (r) {
+      // u16 "map": index -> number of actual bits, symbol for code
+      co = new u16(1 << mb); // bits to remove for reverser
+
+      var rvb = 15 - mb;
+
+      for (i = 0; i < s; ++i) {
+        // ignore 0 lengths
+        if (cd[i]) {
+          // num encoding both symbol and bits read
+          var sv = i << 4 | cd[i]; // free bits
+
+          var r_1 = mb - cd[i]; // start value
+
+          var v = le[cd[i] - 1]++ << r_1; // m is end value
+
+          for (var m = v | (1 << r_1) - 1; v <= m; ++v) {
+            // every 16 bit value starting with the code yields the same result
+            co[rev[v] >>> rvb] = sv;
+          }
+        }
+      }
+    } else {
+      co = new u16(s);
+
+      for (i = 0; i < s; ++i) co[i] = rev[le[cd[i] - 1]++] >>> 15 - cd[i];
+    }
+
+    return co;
+  }; // fixed length tree
+
+
+  var flt = new u8(288);
+
+  for (var i = 0; i < 144; ++i) flt[i] = 8;
+
+  for (var i = 144; i < 256; ++i) flt[i] = 9;
+
+  for (var i = 256; i < 280; ++i) flt[i] = 7;
+
+  for (var i = 280; i < 288; ++i) flt[i] = 8; // fixed distance tree
+
+
+  var fdt = new u8(32);
+
+  for (var i = 0; i < 32; ++i) fdt[i] = 5; // fixed length map
+
+
+  var flm = /*#__PURE__*/hMap(flt, 9, 0),
+      flrm = /*#__PURE__*/hMap(flt, 9, 1); // fixed distance map
+
+  var fdm = /*#__PURE__*/hMap(fdt, 5, 0),
+      fdrm = /*#__PURE__*/hMap(fdt, 5, 1); // find max of array
+
+  var max = function (a) {
+    var m = a[0];
+
+    for (var i = 1; i < a.length; ++i) {
+      if (a[i] > m) m = a[i];
+    }
+
+    return m;
+  }; // read d, starting at bit p and mask with m
+
+
+  var bits = function (d, p, m) {
+    var o = p / 8 >> 0;
+    return (d[o] | d[o + 1] << 8) >>> (p & 7) & m;
+  }; // read d, starting at bit p continuing for at least 16 bits
+
+
+  var bits16 = function (d, p) {
+    var o = p / 8 >> 0;
+    return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >>> (p & 7);
+  }; // get end of byte
+
+
+  var shft = function (p) {
+    return (p / 8 >> 0) + (p & 7 && 1);
+  }; // typed array slice - allows garbage collector to free original reference,
+  // while being more compatible than .slice
+
+
+  var slc = function (v, s, e) {
+    if (s == null || s < 0) s = 0;
+    if (e == null || e > v.length) e = v.length; // can't use .constructor in case user-supplied
+
+    var n = new (v instanceof u16 ? u16 : v instanceof u32 ? u32 : u8)(e - s);
+    n.set(v.subarray(s, e));
+    return n;
+  }; // expands raw DEFLATE data
+
+
+  var inflt = function (dat, buf, st) {
+    // source length
+    var sl = dat.length; // have to estimate size
+
+    var noBuf = !buf || st; // no state
+
+    var noSt = !st || st.i;
+    if (!st) st = {}; // Assumes roughly 33% compression ratio average
+
+    if (!buf) buf = new u8(sl * 3); // ensure buffer can fit at least l elements
+
+    var cbuf = function (l) {
+      var bl = buf.length; // need to increase size to fit
+
+      if (l > bl) {
+        // Double or set to necessary, whichever is greater
+        var nbuf = new u8(Math.max(bl * 2, l));
+        nbuf.set(buf);
+        buf = nbuf;
+      }
+    }; //  last chunk         bitpos           bytes
+
+
+    var final = st.f || 0,
+        pos = st.p || 0,
+        bt = st.b || 0,
+        lm = st.l,
+        dm = st.d,
+        lbt = st.m,
+        dbt = st.n; // total bits
+
+    var tbts = sl * 8;
+
+    do {
+      if (!lm) {
+        // BFINAL - this is only 1 when last chunk is next
+        st.f = final = bits(dat, pos, 1); // type: 0 = no compression, 1 = fixed huffman, 2 = dynamic huffman
+
+        var type = bits(dat, pos + 1, 3);
+        pos += 3;
+
+        if (!type) {
+          // go to end of byte boundary
+          var s = shft(pos) + 4,
+              l = dat[s - 4] | dat[s - 3] << 8,
+              t = s + l;
+
+          if (t > sl) {
+            if (noSt) throw 'unexpected EOF';
+            break;
+          } // ensure size
+
+
+          if (noBuf) cbuf(bt + l); // Copy over uncompressed data
+
+          buf.set(dat.subarray(s, t), bt); // Get new bitpos, update byte count
+
+          st.b = bt += l, st.p = pos = t * 8;
+          continue;
+        } else if (type == 1) lm = flrm, dm = fdrm, lbt = 9, dbt = 5;else if (type == 2) {
+          //  literal                            lengths
+          var hLit = bits(dat, pos, 31) + 257,
+              hcLen = bits(dat, pos + 10, 15) + 4;
+          var tl = hLit + bits(dat, pos + 5, 31) + 1;
+          pos += 14; // length+distance tree
+
+          var ldt = new u8(tl); // code length tree
+
+          var clt = new u8(19);
+
+          for (var i = 0; i < hcLen; ++i) {
+            // use index map to get real code
+            clt[clim[i]] = bits(dat, pos + i * 3, 7);
+          }
+
+          pos += hcLen * 3; // code lengths bits
+
+          var clb = max(clt),
+              clbmsk = (1 << clb) - 1;
+          if (!noSt && pos + tl * (clb + 7) > tbts) break; // code lengths map
+
+          var clm = hMap(clt, clb, 1);
+
+          for (var i = 0; i < tl;) {
+            var r = clm[bits(dat, pos, clbmsk)]; // bits read
+
+            pos += r & 15; // symbol
+
+            var s = r >>> 4; // code length to copy
+
+            if (s < 16) {
+              ldt[i++] = s;
+            } else {
+              //  copy   count
+              var c = 0,
+                  n = 0;
+              if (s == 16) n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];else if (s == 17) n = 3 + bits(dat, pos, 7), pos += 3;else if (s == 18) n = 11 + bits(dat, pos, 127), pos += 7;
+
+              while (n--) ldt[i++] = c;
+            }
+          } //    length tree                 distance tree
+
+
+          var lt = ldt.subarray(0, hLit),
+              dt = ldt.subarray(hLit); // max length bits
+
+          lbt = max(lt); // max dist bits
+
+          dbt = max(dt);
+          lm = hMap(lt, lbt, 1);
+          dm = hMap(dt, dbt, 1);
+        } else throw 'invalid block type';
+
+        if (pos > tbts) throw 'unexpected EOF';
+      } // Make sure the buffer can hold this + the largest possible addition
+      // Maximum chunk size (practically, theoretically infinite) is 2^17;
+
+
+      if (noBuf) cbuf(bt + 131072);
+      var lms = (1 << lbt) - 1,
+          dms = (1 << dbt) - 1;
+      var mxa = lbt + dbt + 18;
+
+      while (noSt || pos + mxa < tbts) {
+        // bits read, code
+        var c = lm[bits16(dat, pos) & lms],
+            sym = c >>> 4;
+        pos += c & 15;
+        if (pos > tbts) throw 'unexpected EOF';
+        if (!c) throw 'invalid length/literal';
+        if (sym < 256) buf[bt++] = sym;else if (sym == 256) {
+          lm = null;
+          break;
+        } else {
+          var add = sym - 254; // no extra bits needed if less
+
+          if (sym > 264) {
+            // index
+            var i = sym - 257,
+                b = fleb[i];
+            add = bits(dat, pos, (1 << b) - 1) + fl[i];
+            pos += b;
+          } // dist
+
+
+          var d = dm[bits16(dat, pos) & dms],
+              dsym = d >>> 4;
+          if (!d) throw 'invalid distance';
+          pos += d & 15;
+          var dt = fd[dsym];
+
+          if (dsym > 3) {
+            var b = fdeb[dsym];
+            dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
+          }
+
+          if (pos > tbts) throw 'unexpected EOF';
+          if (noBuf) cbuf(bt + 131072);
+          var end = bt + add;
+
+          for (; bt < end; bt += 4) {
+            buf[bt] = buf[bt - dt];
+            buf[bt + 1] = buf[bt + 1 - dt];
+            buf[bt + 2] = buf[bt + 2 - dt];
+            buf[bt + 3] = buf[bt + 3 - dt];
+          }
+
+          bt = end;
+        }
+      }
+
+      st.l = lm, st.p = pos, st.b = bt;
+      if (lm) final = 1, st.m = lbt, st.d = dm, st.n = dbt;
+    } while (!final);
+
+    return bt == buf.length ? buf : slc(buf, 0, bt);
+  }; // starting at p, write the minimum number of bits that can hold v to d
+
+
+  var wbits = function (d, p, v) {
+    v <<= p & 7;
+    var o = p / 8 >> 0;
+    d[o] |= v;
+    d[o + 1] |= v >>> 8;
+  }; // starting at p, write the minimum number of bits (>8) that can hold v to d
+
+
+  var wbits16 = function (d, p, v) {
+    v <<= p & 7;
+    var o = p / 8 >> 0;
+    d[o] |= v;
+    d[o + 1] |= v >>> 8;
+    d[o + 2] |= v >>> 16;
+  }; // creates code lengths from a frequency table
+
+
+  var hTree = function (d, mb) {
+    // Need extra info to make a tree
+    var t = [];
+
+    for (var i = 0; i < d.length; ++i) {
+      if (d[i]) t.push({
+        s: i,
+        f: d[i]
+      });
+    }
+
+    var s = t.length;
+    var t2 = t.slice();
+    if (!s) return [new u8(0), 0];
+
+    if (s == 1) {
+      var v = new u8(t[0].s + 1);
+      v[t[0].s] = 1;
+      return [v, 1];
+    }
+
+    t.sort(function (a, b) {
+      return a.f - b.f;
+    }); // after i2 reaches last ind, will be stopped
+    // freq must be greater than largest possible number of symbols
+
+    t.push({
+      s: -1,
+      f: 25001
+    });
+    var l = t[0],
+        r = t[1],
+        i0 = 0,
+        i1 = 1,
+        i2 = 2;
+    t[0] = {
+      s: -1,
+      f: l.f + r.f,
+      l: l,
+      r: r
+    }; // efficient algorithm from UZIP.js
+    // i0 is lookbehind, i2 is lookahead - after processing two low-freq
+    // symbols that combined have high freq, will start processing i2 (high-freq,
+    // non-composite) symbols instead
+    // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/
+
+    while (i1 != s - 1) {
+      l = t[t[i0].f < t[i2].f ? i0++ : i2++];
+      r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];
+      t[i1++] = {
+        s: -1,
+        f: l.f + r.f,
+        l: l,
+        r: r
+      };
+    }
+
+    var maxSym = t2[0].s;
+
+    for (var i = 1; i < s; ++i) {
+      if (t2[i].s > maxSym) maxSym = t2[i].s;
+    } // code lengths
+
+
+    var tr = new u16(maxSym + 1); // max bits in tree
+
+    var mbt = ln(t[i1 - 1], tr, 0);
+
+    if (mbt > mb) {
+      // more algorithms from UZIP.js
+      // TODO: find out how this code works (debt)
+      //  ind    debt
+      var i = 0,
+          dt = 0; //    left            cost
+
+      var lft = mbt - mb,
+          cst = 1 << lft;
+      t2.sort(function (a, b) {
+        return tr[b.s] - tr[a.s] || a.f - b.f;
+      });
+
+      for (; i < s; ++i) {
+        var i2_1 = t2[i].s;
+
+        if (tr[i2_1] > mb) {
+          dt += cst - (1 << mbt - tr[i2_1]);
+          tr[i2_1] = mb;
+        } else break;
+      }
+
+      dt >>>= lft;
+
+      while (dt > 0) {
+        var i2_2 = t2[i].s;
+        if (tr[i2_2] < mb) dt -= 1 << mb - tr[i2_2]++ - 1;else ++i;
+      }
+
+      for (; i >= 0 && dt; --i) {
+        var i2_3 = t2[i].s;
+
+        if (tr[i2_3] == mb) {
+          --tr[i2_3];
+          ++dt;
+        }
+      }
+
+      mbt = mb;
+    }
+
+    return [new u8(tr), mbt];
+  }; // get the max length and assign length codes
+
+
+  var ln = function (n, l, d) {
+    return n.s == -1 ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1)) : l[n.s] = d;
+  }; // length codes generation
+
+
+  var lc = function (c) {
+    var s = c.length; // Note that the semicolon was intentional
+
+    while (s && !c[--s]);
+
+    var cl = new u16(++s); //  ind      num         streak
+
+    var cli = 0,
+        cln = c[0],
+        cls = 1;
+
+    var w = function (v) {
+      cl[cli++] = v;
+    };
+
+    for (var i = 1; i <= s; ++i) {
+      if (c[i] == cln && i != s) ++cls;else {
+        if (!cln && cls > 2) {
+          for (; cls > 138; cls -= 138) w(32754);
+
+          if (cls > 2) {
+            w(cls > 10 ? cls - 11 << 5 | 28690 : cls - 3 << 5 | 12305);
+            cls = 0;
+          }
+        } else if (cls > 3) {
+          w(cln), --cls;
+
+          for (; cls > 6; cls -= 6) w(8304);
+
+          if (cls > 2) w(cls - 3 << 5 | 8208), cls = 0;
+        }
+
+        while (cls--) w(cln);
+
+        cls = 1;
+        cln = c[i];
+      }
+    }
+
+    return [cl.subarray(0, cli), s];
+  }; // calculate the length of output from tree, code lengths
+
+
+  var clen = function (cf, cl) {
+    var l = 0;
+
+    for (var i = 0; i < cl.length; ++i) l += cf[i] * cl[i];
+
+    return l;
+  }; // writes a fixed block
+  // returns the new bit pos
+
+
+  var wfblk = function (out, pos, dat) {
+    // no need to write 00 as type: TypedArray defaults to 0
+    var s = dat.length;
+    var o = shft(pos + 2);
+    out[o] = s & 255;
+    out[o + 1] = s >>> 8;
+    out[o + 2] = out[o] ^ 255;
+    out[o + 3] = out[o + 1] ^ 255;
+
+    for (var i = 0; i < s; ++i) out[o + i + 4] = dat[i];
+
+    return (o + 4 + s) * 8;
+  }; // writes a block
+
+
+  var wblk = function (dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
+    wbits(out, p++, final);
+    ++lf[256];
+
+    var _a = hTree(lf, 15),
+        dlt = _a[0],
+        mlb = _a[1];
+
+    var _b = hTree(df, 15),
+        ddt = _b[0],
+        mdb = _b[1];
+
+    var _c = lc(dlt),
+        lclt = _c[0],
+        nlc = _c[1];
+
+    var _d = lc(ddt),
+        lcdt = _d[0],
+        ndc = _d[1];
+
+    var lcfreq = new u16(19);
+
+    for (var i = 0; i < lclt.length; ++i) lcfreq[lclt[i] & 31]++;
+
+    for (var i = 0; i < lcdt.length; ++i) lcfreq[lcdt[i] & 31]++;
+
+    var _e = hTree(lcfreq, 7),
+        lct = _e[0],
+        mlcb = _e[1];
+
+    var nlcc = 19;
+
+    for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc);
+
+    var flen = bl + 5 << 3;
+    var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
+    var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + (2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18]);
+    if (flen <= ftlen && flen <= dtlen) return wfblk(out, p, dat.subarray(bs, bs + bl));
+    var lm, ll, dm, dl;
+    wbits(out, p, 1 + (dtlen < ftlen)), p += 2;
+
+    if (dtlen < ftlen) {
+      lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;
+      var llm = hMap(lct, mlcb, 0);
+      wbits(out, p, nlc - 257);
+      wbits(out, p + 5, ndc - 1);
+      wbits(out, p + 10, nlcc - 4);
+      p += 14;
+
+      for (var i = 0; i < nlcc; ++i) wbits(out, p + 3 * i, lct[clim[i]]);
+
+      p += 3 * nlcc;
+      var lcts = [lclt, lcdt];
+
+      for (var it = 0; it < 2; ++it) {
+        var clct = lcts[it];
+
+        for (var i = 0; i < clct.length; ++i) {
+          var len = clct[i] & 31;
+          wbits(out, p, llm[len]), p += lct[len];
+          if (len > 15) wbits(out, p, clct[i] >>> 5 & 127), p += clct[i] >>> 12;
+        }
+      }
+    } else {
+      lm = flm, ll = flt, dm = fdm, dl = fdt;
+    }
+
+    for (var i = 0; i < li; ++i) {
+      if (syms[i] > 255) {
+        var len = syms[i] >>> 18 & 31;
+        wbits16(out, p, lm[len + 257]), p += ll[len + 257];
+        if (len > 7) wbits(out, p, syms[i] >>> 23 & 31), p += fleb[len];
+        var dst = syms[i] & 31;
+        wbits16(out, p, dm[dst]), p += dl[dst];
+        if (dst > 3) wbits16(out, p, syms[i] >>> 5 & 8191), p += fdeb[dst];
+      } else {
+        wbits16(out, p, lm[syms[i]]), p += ll[syms[i]];
+      }
+    }
+
+    wbits16(out, p, lm[256]);
+    return p + ll[256];
+  }; // deflate options (nice << 13) | chain
+
+
+  var deo = /*#__PURE__*/new u32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]); // empty
+
+  var et = /*#__PURE__*/new u8(0); // compresses data into a raw DEFLATE buffer
+
+  var dflt = function (dat, lvl, plvl, pre, post, lst) {
+    var s = dat.length;
+    var o = new u8(pre + s + 5 * (1 + Math.floor(s / 7000)) + post); // writing to this writes to the output buffer
+
+    var w = o.subarray(pre, o.length - post);
+    var pos = 0;
+
+    if (!lvl || s < 8) {
+      for (var i = 0; i <= s; i += 65535) {
+        // end
+        var e = i + 65535;
+
+        if (e < s) {
+          // write full block
+          pos = wfblk(w, pos, dat.subarray(i, e));
+        } else {
+          // write final block
+          w[i] = lst;
+          pos = wfblk(w, pos, dat.subarray(i, s));
+        }
+      }
+    } else {
+      var opt = deo[lvl - 1];
+      var n = opt >>> 13,
+          c = opt & 8191;
+      var msk_1 = (1 << plvl) - 1; //    prev 2-byte val map    curr 2-byte val map
+
+      var prev = new u16(32768),
+          head = new u16(msk_1 + 1);
+      var bs1_1 = Math.ceil(plvl / 3),
+          bs2_1 = 2 * bs1_1;
+
+      var hsh = function (i) {
+        return (dat[i] ^ dat[i + 1] << bs1_1 ^ dat[i + 2] << bs2_1) & msk_1;
+      }; // 24576 is an arbitrary number of maximum symbols per block
+      // 424 buffer for last block
+
+
+      var syms = new u32(25000); // length/literal freq   distance freq
+
+      var lf = new u16(288),
+          df = new u16(32); //  l/lcnt  exbits  index  l/lind  waitdx  bitpos
+
+      var lc_1 = 0,
+          eb = 0,
+          i = 0,
+          li = 0,
+          wi = 0,
+          bs = 0;
+
+      for (; i < s; ++i) {
+        // hash value
+        var hv = hsh(i); // index mod 32768
+
+        var imod = i & 32767; // previous index with this value
+
+        var pimod = head[hv];
+        prev[imod] = pimod;
+        head[hv] = imod; // We always should modify head and prev, but only add symbols if
+        // this data is not yet processed ("wait" for wait index)
+
+        if (wi <= i) {
+          // bytes remaining
+          var rem = s - i;
+
+          if ((lc_1 > 7000 || li > 24576) && rem > 423) {
+            pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);
+            li = lc_1 = eb = 0, bs = i;
+
+            for (var j = 0; j < 286; ++j) lf[j] = 0;
+
+            for (var j = 0; j < 30; ++j) df[j] = 0;
+          } //  len    dist   chain
+
+
+          var l = 2,
+              d = 0,
+              ch_1 = c,
+              dif = imod - pimod & 32767;
+
+          if (rem > 2 && hv == hsh(i - dif)) {
+            var maxn = Math.min(n, rem) - 1;
+            var maxd = Math.min(32767, i); // max possible length
+            // not capped at dif because decompressors implement "rolling" index population
+
+            var ml = Math.min(258, rem);
+
+            while (dif <= maxd && --ch_1 && imod != pimod) {
+              if (dat[i + l] == dat[i + l - dif]) {
+                var nl = 0;
+
+                for (; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl);
+
+                if (nl > l) {
+                  l = nl, d = dif; // break out early when we reach "nice" (we are satisfied enough)
+
+                  if (nl > maxn) break; // now, find the rarest 2-byte sequence within this
+                  // length of literals and search for that instead.
+                  // Much faster than just using the start
+
+                  var mmd = Math.min(dif, nl - 2);
+                  var md = 0;
+
+                  for (var j = 0; j < mmd; ++j) {
+                    var ti = i - dif + j + 32768 & 32767;
+                    var pti = prev[ti];
+                    var cd = ti - pti + 32768 & 32767;
+                    if (cd > md) md = cd, pimod = ti;
+                  }
+                }
+              } // check the previous match
+
+
+              imod = pimod, pimod = prev[imod];
+              dif += imod - pimod + 32768 & 32767;
+            }
+          } // d will be nonzero only when a match was found
+
+
+          if (d) {
+            // store both dist and len data in one Uint32
+            // Make sure this is recognized as a len/dist with 28th bit (2^28)
+            syms[li++] = 268435456 | revfl[l] << 18 | revfd[d];
+            var lin = revfl[l] & 31,
+                din = revfd[d] & 31;
+            eb += fleb[lin] + fdeb[din];
+            ++lf[257 + lin];
+            ++df[din];
+            wi = i + l;
+            ++lc_1;
+          } else {
+            syms[li++] = dat[i];
+            ++lf[dat[i]];
+          }
+        }
+      }
+
+      pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos); // this is the easiest way to avoid needing to maintain state
+
+      if (!lst) pos = wfblk(w, pos, et);
+    }
+
+    return slc(o, 0, pre + shft(pos) + post);
+  }; // CRC32 table
+
+
+  var adler = function () {
+    var a = 1,
+        b = 0;
+    return {
+      p: function (d) {
+        // closures have awful performance
+        var n = a,
+            m = b;
+        var l = d.length;
+
+        for (var i = 0; i != l;) {
+          var e = Math.min(i + 5552, l);
+
+          for (; i < e; ++i) n += d[i], m += n;
+
+          n %= 65521, m %= 65521;
+        }
+
+        a = n, b = m;
+      },
+      d: function () {
+        return (a >>> 8 << 16 | (b & 255) << 8 | b >>> 8) + ((a & 255) << 23) * 2;
+      }
+    };
+  };
+
+  var dopt = function (dat, opt, pre, post, st) {
+    return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 12 + opt.mem, pre, post, !st);
+  }; // Walmart object spread
+
+
+  var wbytes = function (d, b, v) {
+    for (; v; ++b) d[b] = v, v >>>= 8;
+  }; // gzip header
+
+
+  var zlh = function (c, o) {
+    var lv = o.level,
+        fl = lv == 0 ? 0 : lv < 6 ? 1 : lv == 9 ? 3 : 2;
+    c[0] = 120, c[1] = fl << 6 | (fl ? 32 - 2 * fl : 1);
+  }; // zlib valid
+
+
+  var zlv = function (d) {
+    if ((d[0] & 15) != 8 || d[0] >>> 4 > 7 || (d[0] << 8 | d[1]) % 31) throw 'invalid zlib data';
+    if (d[1] & 32) throw 'invalid zlib data: preset dictionaries not supported';
+  };
+  /**
+   * Compress data with Zlib
+   * @param data The data to compress
+   * @param opts The compression options
+   * @returns The zlib-compressed version of the data
+   */
+
+  function zlibSync(data, opts) {
+    if (opts === void 0) {
+      opts = {};
+    }
+
+    var a = adler();
+    a.p(data);
+    var d = dopt(data, opts, 2, 4);
+    return zlh(d, opts), wbytes(d, d.length - 4, a.d()), d;
+  }
+  /**
+   * Expands Zlib data
+   * @param data The data to decompress
+   * @param out Where to write the data. Saves memory if you know the decompressed size and provide an output buffer of that length.
+   * @returns The decompressed version of the data
+   */
+
+  function unzlibSync(data, out) {
+    return inflt((zlv(data), data.subarray(2, -4)), out);
+  } // Default algorithm for compression (used because having a known output size allows faster decompression)
+
+  /**
+   * @license
+   * jsPDF filters PlugIn
+   * Copyright (c) 2014 Aras Abbasi
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+
+  (function (jsPDFAPI) {
+
+    var ASCII85Encode = function ASCII85Encode(a) {
+      var b, c, d, e, f, g, h, i, j, k; // eslint-disable-next-line no-control-regex
+
+      for (!/[^\x00-\xFF]/.test(a), b = "\x00\x00\x00\x00".slice(a.length % 4 || 4), a += b, c = [], d = 0, e = a.length; e > d; d += 4) {
+        f = (a.charCodeAt(d) << 24) + (a.charCodeAt(d + 1) << 16) + (a.charCodeAt(d + 2) << 8) + a.charCodeAt(d + 3), 0 !== f ? (k = f % 85, f = (f - k) / 85, j = f % 85, f = (f - j) / 85, i = f % 85, f = (f - i) / 85, h = f % 85, f = (f - h) / 85, g = f % 85, c.push(g + 33, h + 33, i + 33, j + 33, k + 33)) : c.push(122);
+      }
+
+      return function (a, b) {
+        for (var c = b; c > 0; c--) {
+          a.pop();
+        }
+      }(c, b.length), String.fromCharCode.apply(String, c) + "~>";
+    };
+
+    var ASCII85Decode = function ASCII85Decode(a) {
+      var c,
+          d,
+          e,
+          f,
+          g,
+          h = String,
+          l = "length",
+          w = 255,
+          x = "charCodeAt",
+          y = "slice",
+          z = "replace";
+
+      for ("~>" === a[y](-2), a = a[y](0, -2)[z](/\s/g, "")[z]("z", "!!!!!"), c = "uuuuu"[y](a[l] % 5 || 5), a += c, e = [], f = 0, g = a[l]; g > f; f += 5) {
+        d = 52200625 * (a[x](f) - 33) + 614125 * (a[x](f + 1) - 33) + 7225 * (a[x](f + 2) - 33) + 85 * (a[x](f + 3) - 33) + (a[x](f + 4) - 33), e.push(w & d >> 24, w & d >> 16, w & d >> 8, w & d);
+      }
+
+      return function (a, b) {
+        for (var c = b; c > 0; c--) {
+          a.pop();
+        }
+      }(e, c[l]), h.fromCharCode.apply(h, e);
+    };
+
+    var ASCIIHexEncode = function ASCIIHexEncode(value) {
+      return value.split("").map(function (value) {
+        return ("0" + value.charCodeAt().toString(16)).slice(-2);
+      }).join("") + ">";
+    };
+
+    var ASCIIHexDecode = function ASCIIHexDecode(value) {
+      var regexCheckIfHex = new RegExp(/^([0-9A-Fa-f]{2})+$/);
+      value = value.replace(/\s/g, "");
+
+      if (value.indexOf(">") !== -1) {
+        value = value.substr(0, value.indexOf(">"));
+      }
+
+      if (value.length % 2) {
+        value += "0";
+      }
+
+      if (regexCheckIfHex.test(value) === false) {
+        return "";
+      }
+
+      var result = "";
+
+      for (var i = 0; i < value.length; i += 2) {
+        result += String.fromCharCode("0x" + (value[i] + value[i + 1]));
+      }
+
+      return result;
+    };
+    /*
+    var FlatePredictors = {
+        None: 1,
+        TIFF: 2,
+        PNG_None: 10,
+        PNG_Sub: 11,
+        PNG_Up: 12,
+        PNG_Average: 13,
+        PNG_Paeth: 14,
+        PNG_Optimum: 15
+    };
+    */
+
+
+    var FlateEncode = function FlateEncode(data) {
+      var arr = new Uint8Array(data.length);
+      var i = data.length;
+
+      while (i--) {
+        arr[i] = data.charCodeAt(i);
+      }
+
+      arr = zlibSync(arr);
+      data = arr.reduce(function (data, byte) {
+        return data + String.fromCharCode(byte);
+      }, "");
+      return data;
+    };
+
+    jsPDFAPI.processDataByFilters = function (origData, filterChain) {
+
+      var i = 0;
+      var data = origData || "";
+      var reverseChain = [];
+      filterChain = filterChain || [];
+
+      if (typeof filterChain === "string") {
+        filterChain = [filterChain];
+      }
+
+      for (i = 0; i < filterChain.length; i += 1) {
+        switch (filterChain[i]) {
+          case "ASCII85Decode":
+          case "/ASCII85Decode":
+            data = ASCII85Decode(data);
+            reverseChain.push("/ASCII85Encode");
+            break;
+
+          case "ASCII85Encode":
+          case "/ASCII85Encode":
+            data = ASCII85Encode(data);
+            reverseChain.push("/ASCII85Decode");
+            break;
+
+          case "ASCIIHexDecode":
+          case "/ASCIIHexDecode":
+            data = ASCIIHexDecode(data);
+            reverseChain.push("/ASCIIHexEncode");
+            break;
+
+          case "ASCIIHexEncode":
+          case "/ASCIIHexEncode":
+            data = ASCIIHexEncode(data);
+            reverseChain.push("/ASCIIHexDecode");
+            break;
+
+          case "FlateEncode":
+          case "/FlateEncode":
+            data = FlateEncode(data);
+            reverseChain.push("/FlateDecode");
+            break;
+
+          default:
+            throw new Error('The filter: "' + filterChain[i] + '" is not implemented');
+        }
+      }
+
+      return {
+        data: data,
+        reverseChain: reverseChain.reverse().join(" ")
+      };
+    };
+  })(jsPDF.API);
+
+  /**
+   * @license
+   * jsPDF fileloading PlugIn
+   * Copyright (c) 2018 Aras Abbasi (aras.abbasi@gmail.com)
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+  /**
+   * @name fileloading
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+    /**
+     * @name loadFile
+     * @function
+     * @param {string} url
+     * @param {boolean} sync
+     * @param {function} callback
+     * @returns {string|undefined} result
+     */
+
+    jsPDFAPI.loadFile = function (url, sync, callback) {
+      return browserRequest(url, sync, callback);
+    };
+    /**
+     * @name loadImageFile
+     * @function
+     * @param {string} path
+     * @param {boolean} sync
+     * @param {function} callback
+     */
+
+
+    jsPDFAPI.loadImageFile = jsPDFAPI.loadFile;
+
+    function browserRequest(url, sync, callback) {
+      sync = sync === false ? false : true;
+      callback = typeof callback === "function" ? callback : function () {};
+      var result = undefined;
+
+      var xhr = function xhr(url, sync, callback) {
+        var request = new XMLHttpRequest();
+        var i = 0;
+
+        var sanitizeUnicode = function sanitizeUnicode(data) {
+          var dataLength = data.length;
+          var charArray = [];
+          var StringFromCharCode = String.fromCharCode; //Transform Unicode to ASCII
+
+          for (i = 0; i < dataLength; i += 1) {
+            charArray.push(StringFromCharCode(data.charCodeAt(i) & 0xff));
+          }
+
+          return charArray.join("");
+        };
+
+        request.open("GET", url, !sync); // XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
+
+        request.overrideMimeType("text/plain; charset=x-user-defined");
+
+        if (sync === false) {
+          request.onload = function () {
+            if (request.status === 200) {
+              callback(sanitizeUnicode(this.responseText));
+            } else {
+              callback(undefined);
+            }
+          };
+        }
+
+        request.send(null);
+
+        if (sync && request.status === 200) {
+          return sanitizeUnicode(request.responseText);
+        }
+      };
+
+      try {
+        result = xhr(url, sync, callback); // eslint-disable-next-line no-empty
+      } catch (e) {}
+
+      return result;
+    }
+  })(jsPDF.API);
+
+  /**
+   * jsPDF html PlugIn
+   *
+   * @name html
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+
+    function loadHtml2Canvas() {
+      return function () {
+        if (globalObject["html2canvas"]) {
+          return Promise.resolve(globalObject["html2canvas"]);
+        }
+
+        if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && typeof module !== "undefined") {
+          return new Promise(function (resolve, reject) {
+            try {
+              resolve(require("html2canvas"));
+            } catch (e) {
+              reject(e);
+            }
+          });
+        }
+
+        if (typeof define === "function" && define.amd) {
+          return new Promise(function (resolve, reject) {
+            try {
+              require(["html2canvas"], resolve);
+            } catch (e) {
+              reject(e);
+            }
+          });
+        }
+
+        return Promise.reject(new Error("Could not load html2canvas"));
+      }().catch(function (e) {
+        return Promise.reject(new Error("Could not load html2canvas: " + e));
+      }).then(function (html2canvas) {
+        return html2canvas.default ? html2canvas.default : html2canvas;
+      });
+    }
+
+    function loadDomPurify() {
+      return function () {
+        if (globalObject["DOMPurify"]) {
+          return Promise.resolve(globalObject["DOMPurify"]);
+        }
+
+        if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && typeof module !== "undefined") {
+          return new Promise(function (resolve, reject) {
+            try {
+              resolve(require("dompurify"));
+            } catch (e) {
+              reject(e);
+            }
+          });
+        }
+
+        if (typeof define === "function" && define.amd) {
+          return new Promise(function (resolve, reject) {
+            try {
+              require(["dompurify"], resolve);
+            } catch (e) {
+              reject(e);
+            }
+          });
+        }
+
+        return Promise.reject(new Error("Could not load dompurify"));
+      }().catch(function (e) {
+        return Promise.reject(new Error("Could not load dompurify: " + e));
+      }).then(function (dompurify) {
+        return dompurify.default ? dompurify.default : dompurify;
+      });
+    }
+    /**
+     * Determine the type of a variable/object.
+     *
+     * @private
+     * @ignore
+     */
+
+
+    var objType = function objType(obj) {
+      var type = _typeof(obj);
+
+      if (type === "undefined") return "undefined";else if (type === "string" || obj instanceof String) return "string";else if (type === "number" || obj instanceof Number) return "number";else if (type === "function" || obj instanceof Function) return "function";else if (!!obj && obj.constructor === Array) return "array";else if (obj && obj.nodeType === 1) return "element";else if (type === "object") return "object";else return "unknown";
+    };
+    /**
+     * Create an HTML element with optional className, innerHTML, and style.
+     *
+     * @private
+     * @ignore
+     */
+
+
+    var createElement = function createElement(tagName, opt) {
+      var el = document.createElement(tagName);
+      if (opt.className) el.className = opt.className;
+
+      if (opt.innerHTML && opt.dompurify) {
+        el.innerHTML = opt.dompurify.sanitize(opt.innerHTML);
+      }
+
+      for (var key in opt.style) {
+        el.style[key] = opt.style[key];
+      }
+
+      return el;
+    };
+    /**
+     * Deep-clone a node and preserve contents/properties.
+     *
+     * @private
+     * @ignore
+     */
+
+
+    var cloneNode = function cloneNode(node, javascriptEnabled) {
+      // Recursively clone the node.
+      var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
+
+      for (var child = node.firstChild; child; child = child.nextSibling) {
+        if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== "SCRIPT") {
+          clone.appendChild(cloneNode(child, javascriptEnabled));
+        }
+      }
+
+      if (node.nodeType === 1) {
+        // Preserve contents/properties of special nodes.
+        if (node.nodeName === "CANVAS") {
+          clone.width = node.width;
+          clone.height = node.height;
+          clone.getContext("2d").drawImage(node, 0, 0);
+        } else if (node.nodeName === "TEXTAREA" || node.nodeName === "SELECT") {
+          clone.value = node.value;
+        } // Preserve the node's scroll position when it loads.
+
+
+        clone.addEventListener("load", function () {
+          clone.scrollTop = node.scrollTop;
+          clone.scrollLeft = node.scrollLeft;
+        }, true);
+      } // Return the cloned node.
+
+
+      return clone;
+    };
+    /* ----- CONSTRUCTOR ----- */
+
+
+    var Worker = function Worker(opt) {
+      // Create the root parent for the proto chain, and the starting Worker.
+      var root = Object.assign(Worker.convert(Promise.resolve()), JSON.parse(JSON.stringify(Worker.template)));
+      var self = Worker.convert(Promise.resolve(), root); // Set progress, optional settings, and return.
+
+      self = self.setProgress(1, Worker, 1, [Worker]);
+      self = self.set(opt);
+      return self;
+    }; // Boilerplate for subclassing Promise.
+
+
+    Worker.prototype = Object.create(Promise.prototype);
+    Worker.prototype.constructor = Worker; // Converts/casts promises into Workers.
+
+    Worker.convert = function convert(promise, inherit) {
+      // Uses prototypal inheritance to receive changes made to ancestors' properties.
+      promise.__proto__ = inherit || Worker.prototype;
+      return promise;
+    };
+
+    Worker.template = {
+      prop: {
+        src: null,
+        container: null,
+        overlay: null,
+        canvas: null,
+        img: null,
+        pdf: null,
+        pageSize: null,
+        callback: function callback() {}
+      },
+      progress: {
+        val: 0,
+        state: null,
+        n: 0,
+        stack: []
+      },
+      opt: {
+        filename: "file.pdf",
+        margin: [0, 0, 0, 0],
+        enableLinks: true,
+        x: 0,
+        y: 0,
+        html2canvas: {},
+        jsPDF: {},
+        backgroundColor: "transparent"
+      }
+    };
+    /* ----- FROM / TO ----- */
+
+    Worker.prototype.from = function from(src, type) {
+      function getType(src) {
+        switch (objType(src)) {
+          case "string":
+            return "string";
+
+          case "element":
+            return src.nodeName.toLowerCase() === "canvas" ? "canvas" : "element";
+
+          default:
+            return "unknown";
+        }
+      }
+
+      return this.then(function from_main() {
+        type = type || getType(src);
+
+        switch (type) {
+          case "string":
+            return this.then(loadDomPurify).then(function (dompurify) {
+              return this.set({
+                src: createElement("div", {
+                  innerHTML: src,
+                  dompurify: dompurify
+                })
+              });
+            });
+
+          case "element":
+            return this.set({
+              src: src
+            });
+
+          case "canvas":
+            return this.set({
+              canvas: src
+            });
+
+          case "img":
+            return this.set({
+              img: src
+            });
+
+          default:
+            return this.error("Unknown source type.");
+        }
+      });
+    };
+
+    Worker.prototype.to = function to(target) {
+      // Route the 'to' request to the appropriate method.
+      switch (target) {
+        case "container":
+          return this.toContainer();
+
+        case "canvas":
+          return this.toCanvas();
+
+        case "img":
+          return this.toImg();
+
+        case "pdf":
+          return this.toPdf();
+
+        default:
+          return this.error("Invalid target.");
+      }
+    };
+
+    Worker.prototype.toContainer = function toContainer() {
+      // Set up function prerequisites.
+      var prereqs = [function checkSrc() {
+        return this.prop.src || this.error("Cannot duplicate - no source HTML.");
+      }, function checkPageSize() {
+        return this.prop.pageSize || this.setPageSize();
+      }];
+      return this.thenList(prereqs).then(function toContainer_main() {
+        // Define the CSS styles for the container and its overlay parent.
+        var overlayCSS = {
+          position: "fixed",
+          overflow: "hidden",
+          zIndex: 1000,
+          left: "-100000px",
+          right: 0,
+          bottom: 0,
+          top: 0
+        };
+        var containerCSS = {
+          position: "relative",
+          display: "inline-block",
+          width: (typeof this.opt.width === "number" && !isNaN(this.opt.width) && typeof this.opt.windowWidth === "number" && !isNaN(this.opt.windowWidth) ? this.opt.windowWidth : Math.max(this.prop.src.clientWidth, this.prop.src.scrollWidth, this.prop.src.offsetWidth)) + "px",
+          left: 0,
+          right: 0,
+          top: 0,
+          margin: "auto",
+          backgroundColor: this.opt.backgroundColor
+        }; // Set the overlay to hidden (could be changed in the future to provide a print preview).
+
+        var source = cloneNode(this.prop.src, this.opt.html2canvas.javascriptEnabled);
+
+        if (source.tagName === "BODY") {
+          containerCSS.height = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight) + "px";
+        }
+
+        this.prop.overlay = createElement("div", {
+          className: "html2pdf__overlay",
+          style: overlayCSS
+        });
+        this.prop.container = createElement("div", {
+          className: "html2pdf__container",
+          style: containerCSS
+        });
+        this.prop.container.appendChild(source);
+        this.prop.container.firstChild.appendChild(createElement("div", {
+          style: {
+            clear: "both",
+            border: "0 none transparent",
+            margin: 0,
+            padding: 0,
+            height: 0
+          }
+        }));
+        this.prop.container.style.float = "none";
+        this.prop.overlay.appendChild(this.prop.container);
+        document.body.appendChild(this.prop.overlay);
+        this.prop.container.firstChild.style.position = "relative";
+        this.prop.container.height = Math.max(this.prop.container.firstChild.clientHeight, this.prop.container.firstChild.scrollHeight, this.prop.container.firstChild.offsetHeight) + "px";
+      });
+    };
+
+    Worker.prototype.toCanvas = function toCanvas() {
+      // Set up function prerequisites.
+      var prereqs = [function checkContainer() {
+        return document.body.contains(this.prop.container) || this.toContainer();
+      }]; // Fulfill prereqs then create the canvas.
+
+      return this.thenList(prereqs).then(loadHtml2Canvas).then(function toCanvas_main(html2canvas) {
+        // Handle old-fashioned 'onrendered' argument.
+        var options = Object.assign({}, this.opt.html2canvas);
+        delete options.onrendered;
+        return html2canvas(this.prop.container, options);
+      }).then(function toCanvas_post(canvas) {
+        // Handle old-fashioned 'onrendered' argument.
+        var onRendered = this.opt.html2canvas.onrendered || function () {};
+
+        onRendered(canvas);
+        this.prop.canvas = canvas;
+        document.body.removeChild(this.prop.overlay);
+      });
+    };
+
+    Worker.prototype.toContext2d = function toContext2d() {
+      // Set up function prerequisites.
+      var prereqs = [function checkContainer() {
+        return document.body.contains(this.prop.container) || this.toContainer();
+      }]; // Fulfill prereqs then create the canvas.
+
+      return this.thenList(prereqs).then(loadHtml2Canvas).then(function toContext2d_main(html2canvas) {
+        // Handle old-fashioned 'onrendered' argument.
+        var pdf = this.opt.jsPDF;
+        var fontFaces = this.opt.fontFaces;
+        var scale = typeof this.opt.width === "number" && !isNaN(this.opt.width) && typeof this.opt.windowWidth === "number" && !isNaN(this.opt.windowWidth) ? this.opt.width / this.opt.windowWidth : 1;
+        var options = Object.assign({
+          async: true,
+          allowTaint: true,
+          scale: scale,
+          scrollX: this.opt.scrollX || 0,
+          scrollY: this.opt.scrollY || 0,
+          backgroundColor: "#ffffff",
+          imageTimeout: 15000,
+          logging: true,
+          proxy: null,
+          removeContainer: true,
+          foreignObjectRendering: false,
+          useCORS: false
+        }, this.opt.html2canvas);
+        delete options.onrendered;
+        pdf.context2d.autoPaging = typeof this.opt.autoPaging === "undefined" ? true : this.opt.autoPaging;
+        pdf.context2d.posX = this.opt.x;
+        pdf.context2d.posY = this.opt.y;
+        pdf.context2d.margin = this.opt.margin;
+        pdf.context2d.fontFaces = fontFaces;
+
+        if (fontFaces) {
+          for (var i = 0; i < fontFaces.length; ++i) {
+            var font = fontFaces[i];
+            var src = font.src.find(function (src) {
+              return src.format === "truetype";
+            });
+
+            if (src) {
+              pdf.addFont(src.url, font.ref.name, font.ref.style);
+            }
+          }
+        }
+
+        options.windowHeight = options.windowHeight || 0;
+        options.windowHeight = options.windowHeight == 0 ? Math.max(this.prop.container.clientHeight, this.prop.container.scrollHeight, this.prop.container.offsetHeight) : options.windowHeight;
+        pdf.context2d.save(true);
+        return html2canvas(this.prop.container, options);
+      }).then(function toContext2d_post(canvas) {
+        this.opt.jsPDF.context2d.restore(true); // Handle old-fashioned 'onrendered' argument.
+
+        var onRendered = this.opt.html2canvas.onrendered || function () {};
+
+        onRendered(canvas);
+        this.prop.canvas = canvas;
+        document.body.removeChild(this.prop.overlay);
+      });
+    };
+
+    Worker.prototype.toImg = function toImg() {
+      // Set up function prerequisites.
+      var prereqs = [function checkCanvas() {
+        return this.prop.canvas || this.toCanvas();
+      }]; // Fulfill prereqs then create the image.
+
+      return this.thenList(prereqs).then(function toImg_main() {
+        var imgData = this.prop.canvas.toDataURL("image/" + this.opt.image.type, this.opt.image.quality);
+        this.prop.img = document.createElement("img");
+        this.prop.img.src = imgData;
+      });
+    };
+
+    Worker.prototype.toPdf = function toPdf() {
+      // Set up function prerequisites.
+      var prereqs = [function checkContext2d() {
+        return this.toContext2d();
+      } //function checkCanvas() { return this.prop.canvas || this.toCanvas(); }
+      ]; // Fulfill prereqs then create the image.
+
+      return this.thenList(prereqs).then(function toPdf_main() {
+        // Create local copies of frequently used properties.
+        this.prop.pdf = this.prop.pdf || this.opt.jsPDF;
+      });
+    };
+    /* ----- OUTPUT / SAVE ----- */
+
+
+    Worker.prototype.output = function output(type, options, src) {
+      // Redirect requests to the correct function (outputPdf / outputImg).
+      src = src || "pdf";
+
+      if (src.toLowerCase() === "img" || src.toLowerCase() === "image") {
+        return this.outputImg(type, options);
+      } else {
+        return this.outputPdf(type, options);
+      }
+    };
+
+    Worker.prototype.outputPdf = function outputPdf(type, options) {
+      // Set up function prerequisites.
+      var prereqs = [function checkPdf() {
+        return this.prop.pdf || this.toPdf();
+      }]; // Fulfill prereqs then perform the appropriate output.
+
+      return this.thenList(prereqs).then(function outputPdf_main() {
+        /* Currently implemented output types:
+         *    https://rawgit.com/MrRio/jsPDF/master/docs/jspdf.js.html#line992
+         *  save(options), arraybuffer, blob, bloburi/bloburl,
+         *  datauristring/dataurlstring, dataurlnewwindow, datauri/dataurl
+         */
+        return this.prop.pdf.output(type, options);
+      });
+    };
+
+    Worker.prototype.outputImg = function outputImg(type) {
+      // Set up function prerequisites.
+      var prereqs = [function checkImg() {
+        return this.prop.img || this.toImg();
+      }]; // Fulfill prereqs then perform the appropriate output.
+
+      return this.thenList(prereqs).then(function outputImg_main() {
+        switch (type) {
+          case undefined:
+          case "img":
+            return this.prop.img;
+
+          case "datauristring":
+          case "dataurlstring":
+            return this.prop.img.src;
+
+          case "datauri":
+          case "dataurl":
+            return document.location.href = this.prop.img.src;
+
+          default:
+            throw 'Image output type "' + type + '" is not supported.';
+        }
+      });
+    };
+
+    Worker.prototype.save = function save(filename) {
+      // Set up function prerequisites.
+      var prereqs = [function checkPdf() {
+        return this.prop.pdf || this.toPdf();
+      }]; // Fulfill prereqs, update the filename (if provided), and save the PDF.
+
+      return this.thenList(prereqs).set(filename ? {
+        filename: filename
+      } : null).then(function save_main() {
+        this.prop.pdf.save(this.opt.filename);
+      });
+    };
+
+    Worker.prototype.doCallback = function doCallback() {
+      // Set up function prerequisites.
+      var prereqs = [function checkPdf() {
+        return this.prop.pdf || this.toPdf();
+      }]; // Fulfill prereqs, update the filename (if provided), and save the PDF.
+
+      return this.thenList(prereqs).then(function doCallback_main() {
+        this.prop.callback(this.prop.pdf);
+      });
+    };
+    /* ----- SET / GET ----- */
+
+
+    Worker.prototype.set = function set(opt) {
+      // TODO: Implement ordered pairs?
+      // Silently ignore invalid or empty input.
+      if (objType(opt) !== "object") {
+        return this;
+      } // Build an array of setter functions to queue.
+
+
+      var fns = Object.keys(opt || {}).map(function (key) {
+        if (key in Worker.template.prop) {
+          // Set pre-defined properties.
+          return function set_prop() {
+            this.prop[key] = opt[key];
+          };
+        } else {
+          switch (key) {
+            case "margin":
+              return this.setMargin.bind(this, opt.margin);
+
+            case "jsPDF":
+              return function set_jsPDF() {
+                this.opt.jsPDF = opt.jsPDF;
+                return this.setPageSize();
+              };
+
+            case "pageSize":
+              return this.setPageSize.bind(this, opt.pageSize);
+
+            default:
+              // Set any other properties in opt.
+              return function set_opt() {
+                this.opt[key] = opt[key];
+              };
+          }
+        }
+      }, this); // Set properties within the promise chain.
+
+      return this.then(function set_main() {
+        return this.thenList(fns);
+      });
+    };
+
+    Worker.prototype.get = function get(key, cbk) {
+      return this.then(function get_main() {
+        // Fetch the requested property, either as a predefined prop or in opt.
+        var val = key in Worker.template.prop ? this.prop[key] : this.opt[key];
+        return cbk ? cbk(val) : val;
+      });
+    };
+
+    Worker.prototype.setMargin = function setMargin(margin) {
+      return this.then(function setMargin_main() {
+        // Parse the margin property.
+        switch (objType(margin)) {
+          case "number":
+            margin = [margin, margin, margin, margin];
+          // eslint-disable-next-line no-fallthrough
+
+          case "array":
+            if (margin.length === 2) {
+              margin = [margin[0], margin[1], margin[0], margin[1]];
+            }
+
+            if (margin.length === 4) {
+              break;
+            }
+
+          // eslint-disable-next-line no-fallthrough
+
+          default:
+            return this.error("Invalid margin array.");
+        } // Set the margin property, then update pageSize.
+
+
+        this.opt.margin = margin;
+      }).then(this.setPageSize);
+    };
+
+    Worker.prototype.setPageSize = function setPageSize(pageSize) {
+      function toPx(val, k) {
+        return Math.floor(val * k / 72 * 96);
+      }
+
+      return this.then(function setPageSize_main() {
+        // Retrieve page-size based on jsPDF settings, if not explicitly provided.
+        pageSize = pageSize || jsPDF.getPageSize(this.opt.jsPDF); // Add 'inner' field if not present.
+
+        if (!pageSize.hasOwnProperty("inner")) {
+          pageSize.inner = {
+            width: pageSize.width - this.opt.margin[1] - this.opt.margin[3],
+            height: pageSize.height - this.opt.margin[0] - this.opt.margin[2]
+          };
+          pageSize.inner.px = {
+            width: toPx(pageSize.inner.width, pageSize.k),
+            height: toPx(pageSize.inner.height, pageSize.k)
+          };
+          pageSize.inner.ratio = pageSize.inner.height / pageSize.inner.width;
+        } // Attach pageSize to this.
+
+
+        this.prop.pageSize = pageSize;
+      });
+    };
+
+    Worker.prototype.setProgress = function setProgress(val, state, n, stack) {
+      // Immediately update all progress values.
+      if (val != null) this.progress.val = val;
+      if (state != null) this.progress.state = state;
+      if (n != null) this.progress.n = n;
+      if (stack != null) this.progress.stack = stack;
+      this.progress.ratio = this.progress.val / this.progress.state; // Return this for command chaining.
+
+      return this;
+    };
+
+    Worker.prototype.updateProgress = function updateProgress(val, state, n, stack) {
+      // Immediately update all progress values, using setProgress.
+      return this.setProgress(val ? this.progress.val + val : null, state ? state : null, n ? this.progress.n + n : null, stack ? this.progress.stack.concat(stack) : null);
+    };
+    /* ----- PROMISE MAPPING ----- */
+
+
+    Worker.prototype.then = function then(onFulfilled, onRejected) {
+      // Wrap `this` for encapsulation.
+      var self = this;
+      return this.thenCore(onFulfilled, onRejected, function then_main(onFulfilled, onRejected) {
+        // Update progress while queuing, calling, and resolving `then`.
+        self.updateProgress(null, null, 1, [onFulfilled]);
+        return Promise.prototype.then.call(this, function then_pre(val) {
+          self.updateProgress(null, onFulfilled);
+          return val;
+        }).then(onFulfilled, onRejected).then(function then_post(val) {
+          self.updateProgress(1);
+          return val;
+        });
+      });
+    };
+
+    Worker.prototype.thenCore = function thenCore(onFulfilled, onRejected, thenBase) {
+      // Handle optional thenBase parameter.
+      thenBase = thenBase || Promise.prototype.then; // Wrap `this` for encapsulation and bind it to the promise handlers.
+
+      var self = this;
+
+      if (onFulfilled) {
+        onFulfilled = onFulfilled.bind(self);
+      }
+
+      if (onRejected) {
+        onRejected = onRejected.bind(self);
+      } // Cast self into a Promise to avoid polyfills recursively defining `then`.
+
+
+      var isNative = Promise.toString().indexOf("[native code]") !== -1 && Promise.name === "Promise";
+      var selfPromise = isNative ? self : Worker.convert(Object.assign({}, self), Promise.prototype); // Return the promise, after casting it into a Worker and preserving props.
+
+      var returnVal = thenBase.call(selfPromise, onFulfilled, onRejected);
+      return Worker.convert(returnVal, self.__proto__);
+    };
+
+    Worker.prototype.thenExternal = function thenExternal(onFulfilled, onRejected) {
+      // Call `then` and return a standard promise (exits the Worker chain).
+      return Promise.prototype.then.call(this, onFulfilled, onRejected);
+    };
+
+    Worker.prototype.thenList = function thenList(fns) {
+      // Queue a series of promise 'factories' into the promise chain.
+      var self = this;
+      fns.forEach(function thenList_forEach(fn) {
+        self = self.thenCore(fn);
+      });
+      return self;
+    };
+
+    Worker.prototype["catch"] = function (onRejected) {
+      // Bind `this` to the promise handler, call `catch`, and return a Worker.
+      if (onRejected) {
+        onRejected = onRejected.bind(this);
+      }
+
+      var returnVal = Promise.prototype["catch"].call(this, onRejected);
+      return Worker.convert(returnVal, this);
+    };
+
+    Worker.prototype.catchExternal = function catchExternal(onRejected) {
+      // Call `catch` and return a standard promise (exits the Worker chain).
+      return Promise.prototype["catch"].call(this, onRejected);
+    };
+
+    Worker.prototype.error = function error(msg) {
+      // Throw the error in the Promise chain.
+      return this.then(function error_main() {
+        throw new Error(msg);
+      });
+    };
+    /* ----- ALIASES ----- */
+
+
+    Worker.prototype.using = Worker.prototype.set;
+    Worker.prototype.saveAs = Worker.prototype.save;
+    Worker.prototype.export = Worker.prototype.output;
+    Worker.prototype.run = Worker.prototype.then; // Get dimensions of a PDF page, as determined by jsPDF.
+
+    jsPDF.getPageSize = function (orientation, unit, format) {
+      // Decode options object
+      if (_typeof(orientation) === "object") {
+        var options = orientation;
+        orientation = options.orientation;
+        unit = options.unit || unit;
+        format = options.format || format;
+      } // Default options
+
+
+      unit = unit || "mm";
+      format = format || "a4";
+      orientation = ("" + (orientation || "P")).toLowerCase();
+      var format_as_string = ("" + format).toLowerCase(); // Size in pt of various paper formats
+
+      var pageFormats = {
+        a0: [2383.94, 3370.39],
+        a1: [1683.78, 2383.94],
+        a2: [1190.55, 1683.78],
+        a3: [841.89, 1190.55],
+        a4: [595.28, 841.89],
+        a5: [419.53, 595.28],
+        a6: [297.64, 419.53],
+        a7: [209.76, 297.64],
+        a8: [147.4, 209.76],
+        a9: [104.88, 147.4],
+        a10: [73.7, 104.88],
+        b0: [2834.65, 4008.19],
+        b1: [2004.09, 2834.65],
+        b2: [1417.32, 2004.09],
+        b3: [1000.63, 1417.32],
+        b4: [708.66, 1000.63],
+        b5: [498.9, 708.66],
+        b6: [354.33, 498.9],
+        b7: [249.45, 354.33],
+        b8: [175.75, 249.45],
+        b9: [124.72, 175.75],
+        b10: [87.87, 124.72],
+        c0: [2599.37, 3676.54],
+        c1: [1836.85, 2599.37],
+        c2: [1298.27, 1836.85],
+        c3: [918.43, 1298.27],
+        c4: [649.13, 918.43],
+        c5: [459.21, 649.13],
+        c6: [323.15, 459.21],
+        c7: [229.61, 323.15],
+        c8: [161.57, 229.61],
+        c9: [113.39, 161.57],
+        c10: [79.37, 113.39],
+        dl: [311.81, 623.62],
+        letter: [612, 792],
+        "government-letter": [576, 756],
+        legal: [612, 1008],
+        "junior-legal": [576, 360],
+        ledger: [1224, 792],
+        tabloid: [792, 1224],
+        "credit-card": [153, 243]
+      };
+      var k; // Unit conversion
+
+      switch (unit) {
+        case "pt":
+          k = 1;
+          break;
+
+        case "mm":
+          k = 72 / 25.4;
+          break;
+
+        case "cm":
+          k = 72 / 2.54;
+          break;
+
+        case "in":
+          k = 72;
+          break;
+
+        case "px":
+          k = 72 / 96;
+          break;
+
+        case "pc":
+          k = 12;
+          break;
+
+        case "em":
+          k = 12;
+          break;
+
+        case "ex":
+          k = 6;
+          break;
+
+        default:
+          throw "Invalid unit: " + unit;
+      }
+
+      var pageHeight = 0;
+      var pageWidth = 0; // Dimensions are stored as user units and converted to points on output
+
+      if (pageFormats.hasOwnProperty(format_as_string)) {
+        pageHeight = pageFormats[format_as_string][1] / k;
+        pageWidth = pageFormats[format_as_string][0] / k;
+      } else {
+        try {
+          pageHeight = format[1];
+          pageWidth = format[0];
+        } catch (err) {
+          throw new Error("Invalid format: " + format);
+        }
+      }
+
+      var tmp; // Handle page orientation
+
+      if (orientation === "p" || orientation === "portrait") {
+        orientation = "p";
+
+        if (pageWidth > pageHeight) {
+          tmp = pageWidth;
+          pageWidth = pageHeight;
+          pageHeight = tmp;
+        }
+      } else if (orientation === "l" || orientation === "landscape") {
+        orientation = "l";
+
+        if (pageHeight > pageWidth) {
+          tmp = pageWidth;
+          pageWidth = pageHeight;
+          pageHeight = tmp;
+        }
+      } else {
+        throw "Invalid orientation: " + orientation;
+      } // Return information (k is the unit conversion ratio from pts)
+
+
+      var info = {
+        width: pageWidth,
+        height: pageHeight,
+        unit: unit,
+        k: k,
+        orientation: orientation
+      };
+      return info;
+    };
+    /**
+     * @typedef FontFace
+     *
+     * The font-face type implements an interface similar to that of the font-face CSS rule,
+     * and is used by jsPDF to match fonts when the font property of CanvasRenderingContext2D
+     * is updated.
+     *
+     * All properties expect values similar to those in the font-face CSS rule. A difference
+     * is the font-family, which do not need to be enclosed in double-quotes when containing
+     * spaces like in CSS.
+     *
+     * @property {string} family The name of the font-family.
+     * @property {string|undefined} style The style that this font-face defines, e.g. 'italic'.
+     * @property {string|number|undefined} weight The weight of the font, either as a string or a number (400, 500, 600, e.g.)
+     * @property {string|undefined} stretch The stretch of the font, e.g. condensed, normal, expanded.
+     * @property {Object[]} src A list of URLs from where fonts of various formats can be fetched.
+     * @property {string} [src] url A URL to a font of a specific format.
+     * @property {string} [src] format Format of the font referenced by the URL.
+     */
+
+    /**
+     * Generate a PDF from an HTML element or string using.
+     *
+     * @name html
+     * @function
+     * @param {HTMLElement|string} source The source HTMLElement or a string containing HTML.
+     * @param {Object} [options] Collection of settings
+     * @param {function} [options.callback] The mandatory callback-function gets as first parameter the current jsPDF instance
+     * @param {(number|number[])=} [options.margin] Page margins [top, right, bottom, left]. Default is 0.
+     * @param {(boolean|'slice'|'text')=} [options.autoPaging] The auto paging mode.
+     * <ul>
+     * <li>
+     *   <code>false</code>: Auto paging is disabled.
+     * </li>
+     * <li>
+     *   <code>true</code> or <code>'slice'</code>: Will cut shapes or text chunks across page breaks. Will possibly
+     *   slice text in half, making it difficult to read.
+     * </li>
+     * <li>
+     *   <code>'text'</code>: Trys not to cut text in half across page breaks. Works best for documents consisting
+     *   mostly of a single column of text.
+     * </li>
+     * </ul>
+     * Default is <code>true</code>.
+     * @param {string} [options.filename] name of the file
+     * @param {HTMLOptionImage} [options.image] image settings when converting HTML to image
+     * @param {Html2CanvasOptions} [options.html2canvas] html2canvas options
+     * @param {FontFace[]} [options.fontFaces] A list of font-faces to match when resolving fonts. Fonts will be added to the PDF based on the specified URL. If omitted, the font match algorithm falls back to old algorithm.
+     * @param {jsPDF} [options.jsPDF] jsPDF instance
+     * @param {number=} [options.x] x position on the PDF document in jsPDF units.
+     * @param {number=} [options.y] y position on the PDF document in jsPDF units.
+     * @param {number=} [options.width] The target width in the PDF document in jsPDF units. The rendered element will be
+     * scaled such that it fits into the specified width. Has no effect if either the <code>html2canvas.scale<code> is
+     * specified or the <code>windowWidth</code> option is NOT specified.
+     * @param {number=} [options.windowWidth] The window width in CSS pixels. In contrast to the
+     * <code>html2canvas.windowWidth</code> option, this option affects the actual container size while rendering and
+     * does NOT affect CSS media queries. This option only has an effect, if the <code>width<code> option is also specified.
+     *
+     * @example
+     * var doc = new jsPDF();
+     *
+     * doc.html(document.body, {
+     *    callback: function (doc) {
+     *      doc.save();
+     *    },
+     *    x: 10,
+     *    y: 10
+     * });
+     */
+
+
+    jsPDFAPI.html = function (src, options) {
+
+      options = options || {};
+
+      options.callback = options.callback || function () {};
+
+      options.html2canvas = options.html2canvas || {};
+      options.html2canvas.canvas = options.html2canvas.canvas || this.canvas;
+      options.jsPDF = options.jsPDF || this;
+      options.fontFaces = options.fontFaces ? options.fontFaces.map(normalizeFontFace) : null; // Create a new worker with the given options.
+
+      var worker = new Worker(options);
+
+      if (!options.worker) {
+        // If worker is not set to true, perform the traditional 'simple' operation.
+        return worker.from(src).doCallback();
+      } else {
+        // Otherwise, return the worker for new Promise-based operation.
+        return worker;
+      }
+    };
+  })(jsPDF.API);
+
+  /**
+   * @license
+   * ====================================================================
+   * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
+   *
+   * Permission is hereby granted, free of charge, to any person obtaining
+   * a copy of this software and associated documentation files (the
+   * "Software"), to deal in the Software without restriction, including
+   * without limitation the rights to use, copy, modify, merge, publish,
+   * distribute, sublicense, and/or sell copies of the Software, and to
+   * permit persons to whom the Software is furnished to do so, subject to
+   * the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be
+   * included in all copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+   * ====================================================================
+   */
+  /**
+   * jsPDF JavaScript plugin
+   *
+   * @name javascript
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+
+    var jsNamesObj, jsJsObj, text;
+    /**
+     * @name addJS
+     * @function
+     * @param {string} javascript The javascript to be embedded into the PDF-file.
+     * @returns {jsPDF}
+     */
+
+    jsPDFAPI.addJS = function (javascript) {
+      text = javascript;
+      this.internal.events.subscribe("postPutResources", function () {
+        jsNamesObj = this.internal.newObject();
+        this.internal.out("<<");
+        this.internal.out("/Names [(EmbeddedJS) " + (jsNamesObj + 1) + " 0 R]");
+        this.internal.out(">>");
+        this.internal.out("endobj");
+        jsJsObj = this.internal.newObject();
+        this.internal.out("<<");
+        this.internal.out("/S /JavaScript");
+        this.internal.out("/JS (" + text + ")");
+        this.internal.out(">>");
+        this.internal.out("endobj");
+      });
+      this.internal.events.subscribe("putCatalog", function () {
+        if (jsNamesObj !== undefined && jsJsObj !== undefined) {
+          this.internal.out("/Names <</JavaScript " + jsNamesObj + " 0 R>>");
+        }
+      });
+      return this;
+    };
+  })(jsPDF.API);
+
+  /**
+   * @license
+   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+  /**
+   * jsPDF Outline PlugIn
+   *
+   * Generates a PDF Outline
+   * @name outline
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+
+    var namesOid; //var destsGoto = [];
+
+    jsPDFAPI.events.push(["postPutResources", function () {
+      var pdf = this;
+      var rx = /^(\d+) 0 obj$/; // Write action goto objects for each page
+      // this.outline.destsGoto = [];
+      // for (var i = 0; i < totalPages; i++) {
+      // var id = pdf.internal.newObject();
+      // this.outline.destsGoto.push(id);
+      // pdf.internal.write("<</D[" + (i * 2 + 3) + " 0 R /XYZ null
+      // null null]/S/GoTo>> endobj");
+      // }
+      //
+      // for (var i = 0; i < dests.length; i++) {
+      // pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0
+      // R");
+      // }
+      //
+
+      if (this.outline.root.children.length > 0) {
+        var lines = pdf.outline.render().split(/\r\n/);
+
+        for (var i = 0; i < lines.length; i++) {
+          var line = lines[i];
+          var m = rx.exec(line);
+
+          if (m != null) {
+            var oid = m[1];
+            pdf.internal.newObjectDeferredBegin(oid, false);
+          }
+
+          pdf.internal.write(line);
+        }
+      } // This code will write named destination for each page reference
+      // (page_1, etc)
+
+
+      if (this.outline.createNamedDestinations) {
+        var totalPages = this.internal.pages.length; // WARNING: this assumes jsPDF starts on page 3 and pageIDs
+        // follow 5, 7, 9, etc
+        // Write destination objects for each page
+
+        var dests = [];
+
+        for (var i = 0; i < totalPages; i++) {
+          var id = pdf.internal.newObject();
+          dests.push(id);
+          var info = pdf.internal.getPageInfo(i + 1);
+          pdf.internal.write("<< /D[" + info.objId + " 0 R /XYZ null null null]>> endobj");
+        } // assign a name for each destination
+
+
+        var names2Oid = pdf.internal.newObject();
+        pdf.internal.write("<< /Names [ ");
+
+        for (var i = 0; i < dests.length; i++) {
+          pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0 R");
+        }
+
+        pdf.internal.write(" ] >>", "endobj"); // var kids = pdf.internal.newObject();
+        // pdf.internal.write('<< /Kids [ ' + names2Oid + ' 0 R');
+        // pdf.internal.write(' ] >>', 'endobj');
+
+        namesOid = pdf.internal.newObject();
+        pdf.internal.write("<< /Dests " + names2Oid + " 0 R");
+        pdf.internal.write(">>", "endobj");
+      }
+    }]);
+    jsPDFAPI.events.push(["putCatalog", function () {
+      var pdf = this;
+
+      if (pdf.outline.root.children.length > 0) {
+        pdf.internal.write("/Outlines", this.outline.makeRef(this.outline.root));
+
+        if (this.outline.createNamedDestinations) {
+          pdf.internal.write("/Names " + namesOid + " 0 R");
+        } // Open with Bookmarks showing
+        // pdf.internal.write("/PageMode /UseOutlines");
+
+      }
+    }]);
+    jsPDFAPI.events.push(["initialized", function () {
+      var pdf = this;
+      pdf.outline = {
+        createNamedDestinations: false,
+        root: {
+          children: []
+        }
+      };
+      /**
+       * Options: pageNumber
+       */
+
+      pdf.outline.add = function (parent, title, options) {
+        var item = {
+          title: title,
+          options: options,
+          children: []
+        };
+
+        if (parent == null) {
+          parent = this.root;
+        }
+
+        parent.children.push(item);
+        return item;
+      };
+
+      pdf.outline.render = function () {
+        this.ctx = {};
+        this.ctx.val = "";
+        this.ctx.pdf = pdf;
+        this.genIds_r(this.root);
+        this.renderRoot(this.root);
+        this.renderItems(this.root);
+        return this.ctx.val;
+      };
+
+      pdf.outline.genIds_r = function (node) {
+        node.id = pdf.internal.newObjectDeferred();
+
+        for (var i = 0; i < node.children.length; i++) {
+          this.genIds_r(node.children[i]);
+        }
+      };
+
+      pdf.outline.renderRoot = function (node) {
+        this.objStart(node);
+        this.line("/Type /Outlines");
+
+        if (node.children.length > 0) {
+          this.line("/First " + this.makeRef(node.children[0]));
+          this.line("/Last " + this.makeRef(node.children[node.children.length - 1]));
+        }
+
+        this.line("/Count " + this.count_r({
+          count: 0
+        }, node));
+        this.objEnd();
+      };
+
+      pdf.outline.renderItems = function (node) {
+        var getVerticalCoordinateString = this.ctx.pdf.internal.getVerticalCoordinateString;
+
+        for (var i = 0; i < node.children.length; i++) {
+          var item = node.children[i];
+          this.objStart(item);
+          this.line("/Title " + this.makeString(item.title));
+          this.line("/Parent " + this.makeRef(node));
+
+          if (i > 0) {
+            this.line("/Prev " + this.makeRef(node.children[i - 1]));
+          }
+
+          if (i < node.children.length - 1) {
+            this.line("/Next " + this.makeRef(node.children[i + 1]));
+          }
+
+          if (item.children.length > 0) {
+            this.line("/First " + this.makeRef(item.children[0]));
+            this.line("/Last " + this.makeRef(item.children[item.children.length - 1]));
+          }
+
+          var count = this.count = this.count_r({
+            count: 0
+          }, item);
+
+          if (count > 0) {
+            this.line("/Count " + count);
+          }
+
+          if (item.options) {
+            if (item.options.pageNumber) {
+              // Explicit Destination
+              //WARNING this assumes page ids are 3,5,7, etc.
+              var info = pdf.internal.getPageInfo(item.options.pageNumber);
+              this.line("/Dest " + "[" + info.objId + " 0 R /XYZ 0 " + getVerticalCoordinateString(0) + " 0]"); // this line does not work on all clients (pageNumber instead of page ref)
+              //this.line('/Dest ' + '[' + (item.options.pageNumber - 1) + ' /XYZ 0 ' + this.ctx.pdf.internal.pageSize.getHeight() + ' 0]');
+              // Named Destination
+              // this.line('/Dest (page_' + (item.options.pageNumber) + ')');
+              // Action Destination
+              // var id = pdf.internal.newObject();
+              // pdf.internal.write('<</D[' + (item.options.pageNumber - 1) + ' /XYZ null null null]/S/GoTo>> endobj');
+              // this.line('/A ' + id + ' 0 R' );
+            }
+          }
+
+          this.objEnd();
+        }
+
+        for (var z = 0; z < node.children.length; z++) {
+          this.renderItems(node.children[z]);
+        }
+      };
+
+      pdf.outline.line = function (text) {
+        this.ctx.val += text + "\r\n";
+      };
+
+      pdf.outline.makeRef = function (node) {
+        return node.id + " 0 R";
+      };
+
+      pdf.outline.makeString = function (val) {
+        return "(" + pdf.internal.pdfEscape(val) + ")";
+      };
+
+      pdf.outline.objStart = function (node) {
+        this.ctx.val += "\r\n" + node.id + " 0 obj" + "\r\n<<\r\n";
+      };
+
+      pdf.outline.objEnd = function () {
+        this.ctx.val += ">> \r\n" + "endobj" + "\r\n";
+      };
+
+      pdf.outline.count_r = function (ctx, node) {
+        for (var i = 0; i < node.children.length; i++) {
+          ctx.count++;
+          this.count_r(ctx, node.children[i]);
+        }
+
+        return ctx.count;
+      };
+    }]);
+    return this;
+  })(jsPDF.API);
+
+  /**
+   * @license
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+  /**
+   * jsPDF jpeg Support PlugIn
+   *
+   * @name jpeg_support
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+    /**
+     * 0xc0 (SOF) Huffman  - Baseline DCT
+     * 0xc1 (SOF) Huffman  - Extended sequential DCT
+     * 0xc2 Progressive DCT (SOF2)
+     * 0xc3 Spatial (sequential) lossless (SOF3)
+     * 0xc4 Differential sequential DCT (SOF5)
+     * 0xc5 Differential progressive DCT (SOF6)
+     * 0xc6 Differential spatial (SOF7)
+     * 0xc7
+     */
+
+    var markers = [0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7]; //takes a string imgData containing the raw bytes of
+    //a jpeg image and returns [width, height]
+    //Algorithm from: http://www.64lines.com/jpeg-width-height
+
+    var getJpegInfo = function getJpegInfo(imgData) {
+      var width, height, numcomponents;
+      var blockLength = imgData.charCodeAt(4) * 256 + imgData.charCodeAt(5);
+      var len = imgData.length;
+      var result = {
+        width: 0,
+        height: 0,
+        numcomponents: 1
+      };
+
+      for (var i = 4; i < len; i += 2) {
+        i += blockLength;
+
+        if (markers.indexOf(imgData.charCodeAt(i + 1)) !== -1) {
+          height = imgData.charCodeAt(i + 5) * 256 + imgData.charCodeAt(i + 6);
+          width = imgData.charCodeAt(i + 7) * 256 + imgData.charCodeAt(i + 8);
+          numcomponents = imgData.charCodeAt(i + 9);
+          result = {
+            width: width,
+            height: height,
+            numcomponents: numcomponents
+          };
+          break;
+        } else {
+          blockLength = imgData.charCodeAt(i + 2) * 256 + imgData.charCodeAt(i + 3);
+        }
+      }
+
+      return result;
+    };
+    /**
+     * @ignore
+     */
+
+
+    jsPDFAPI.processJPEG = function (data, index, alias, compression, dataAsBinaryString, colorSpace) {
+      var filter = this.decode.DCT_DECODE,
+          bpc = 8,
+          dims,
+          result = null;
+
+      if (typeof data === "string" || this.__addimage__.isArrayBuffer(data) || this.__addimage__.isArrayBufferView(data)) {
+        // if we already have a stored binary string rep use that
+        data = dataAsBinaryString || data;
+        data = this.__addimage__.isArrayBuffer(data) ? new Uint8Array(data) : data;
+        data = this.__addimage__.isArrayBufferView(data) ? this.__addimage__.arrayBufferToBinaryString(data) : data;
+        dims = getJpegInfo(data);
+
+        switch (dims.numcomponents) {
+          case 1:
+            colorSpace = this.color_spaces.DEVICE_GRAY;
+            break;
+
+          case 4:
+            colorSpace = this.color_spaces.DEVICE_CMYK;
+            break;
+
+          case 3:
+            colorSpace = this.color_spaces.DEVICE_RGB;
+            break;
+        }
+
+        result = {
+          data: data,
+          width: dims.width,
+          height: dims.height,
+          colorSpace: colorSpace,
+          bitsPerComponent: bpc,
+          filter: filter,
+          index: index,
+          alias: alias
+        };
+      }
+
+      return result;
+    };
+  })(jsPDF.API);
+
+  // Generated by CoffeeScript 1.4.0
+
+  var PNG = function () {
+    var APNG_BLEND_OP_SOURCE, APNG_DISPOSE_OP_BACKGROUND, APNG_DISPOSE_OP_PREVIOUS, makeImage, scratchCanvas, scratchCtx;
+    APNG_DISPOSE_OP_BACKGROUND = 1;
+    APNG_DISPOSE_OP_PREVIOUS = 2;
+    APNG_BLEND_OP_SOURCE = 0;
+
+    function PNG(data) {
+      var chunkSize, colors, palLen, delayDen, delayNum, frame, i, index, key, section, palShort, text, _i, _j, _ref;
+
+      this.data = data;
+      this.pos = 8;
+      this.palette = [];
+      this.imgData = [];
+      this.transparency = {};
+      this.animation = null;
+      this.text = {};
+      frame = null;
+
+      while (true) {
+        chunkSize = this.readUInt32();
+
+        section = function () {
+          var _i, _results;
+
+          _results = [];
+
+          for (i = _i = 0; _i < 4; i = ++_i) {
+            _results.push(String.fromCharCode(this.data[this.pos++]));
+          }
+
+          return _results;
+        }.call(this).join("");
+
+        switch (section) {
+          case "IHDR":
+            this.width = this.readUInt32();
+            this.height = this.readUInt32();
+            this.bits = this.data[this.pos++];
+            this.colorType = this.data[this.pos++];
+            this.compressionMethod = this.data[this.pos++];
+            this.filterMethod = this.data[this.pos++];
+            this.interlaceMethod = this.data[this.pos++];
+            break;
+
+          case "acTL":
+            this.animation = {
+              numFrames: this.readUInt32(),
+              numPlays: this.readUInt32() || Infinity,
+              frames: []
+            };
+            break;
+
+          case "PLTE":
+            this.palette = this.read(chunkSize);
+            break;
+
+          case "fcTL":
+            if (frame) {
+              this.animation.frames.push(frame);
+            }
+
+            this.pos += 4;
+            frame = {
+              width: this.readUInt32(),
+              height: this.readUInt32(),
+              xOffset: this.readUInt32(),
+              yOffset: this.readUInt32()
+            };
+            delayNum = this.readUInt16();
+            delayDen = this.readUInt16() || 100;
+            frame.delay = 1000 * delayNum / delayDen;
+            frame.disposeOp = this.data[this.pos++];
+            frame.blendOp = this.data[this.pos++];
+            frame.data = [];
+            break;
+
+          case "IDAT":
+          case "fdAT":
+            if (section === "fdAT") {
+              this.pos += 4;
+              chunkSize -= 4;
+            }
+
+            data = (frame != null ? frame.data : void 0) || this.imgData;
+
+            for (i = _i = 0; 0 <= chunkSize ? _i < chunkSize : _i > chunkSize; i = 0 <= chunkSize ? ++_i : --_i) {
+              data.push(this.data[this.pos++]);
+            }
+
+            break;
+
+          case "tRNS":
+            this.transparency = {};
+
+            switch (this.colorType) {
+              case 3:
+                palLen = this.palette.length / 3;
+                this.transparency.indexed = this.read(chunkSize);
+                if (this.transparency.indexed.length > palLen) throw new Error("More transparent colors than palette size");
+                /*
+                 * According to the PNG spec trns should be increased to the same size as palette if shorter
+                 */
+                //palShort = 255 - this.transparency.indexed.length;
+
+                palShort = palLen - this.transparency.indexed.length;
+
+                if (palShort > 0) {
+                  for (i = _j = 0; 0 <= palShort ? _j < palShort : _j > palShort; i = 0 <= palShort ? ++_j : --_j) {
+                    this.transparency.indexed.push(255);
+                  }
+                }
+
+                break;
+
+              case 0:
+                this.transparency.grayscale = this.read(chunkSize)[0];
+                break;
+
+              case 2:
+                this.transparency.rgb = this.read(chunkSize);
+            }
+
+            break;
+
+          case "tEXt":
+            text = this.read(chunkSize);
+            index = text.indexOf(0);
+            key = String.fromCharCode.apply(String, text.slice(0, index));
+            this.text[key] = String.fromCharCode.apply(String, text.slice(index + 1));
+            break;
+
+          case "IEND":
+            if (frame) {
+              this.animation.frames.push(frame);
+            }
+
+            this.colors = function () {
+              switch (this.colorType) {
+                case 0:
+                case 3:
+                case 4:
+                  return 1;
+
+                case 2:
+                case 6:
+                  return 3;
+              }
+            }.call(this);
+
+            this.hasAlphaChannel = (_ref = this.colorType) === 4 || _ref === 6;
+            colors = this.colors + (this.hasAlphaChannel ? 1 : 0);
+            this.pixelBitlength = this.bits * colors;
+
+            this.colorSpace = function () {
+              switch (this.colors) {
+                case 1:
+                  return "DeviceGray";
+
+                case 3:
+                  return "DeviceRGB";
+              }
+            }.call(this);
+
+            this.imgData = new Uint8Array(this.imgData);
+            return;
+
+          default:
+            this.pos += chunkSize;
+        }
+
+        this.pos += 4;
+
+        if (this.pos > this.data.length) {
+          throw new Error("Incomplete or corrupt PNG file");
+        }
+      }
+    }
+
+    PNG.prototype.read = function (bytes) {
+      var i, _i, _results;
+
+      _results = [];
+
+      for (i = _i = 0; 0 <= bytes ? _i < bytes : _i > bytes; i = 0 <= bytes ? ++_i : --_i) {
+        _results.push(this.data[this.pos++]);
+      }
+
+      return _results;
+    };
+
+    PNG.prototype.readUInt32 = function () {
+      var b1, b2, b3, b4;
+      b1 = this.data[this.pos++] << 24;
+      b2 = this.data[this.pos++] << 16;
+      b3 = this.data[this.pos++] << 8;
+      b4 = this.data[this.pos++];
+      return b1 | b2 | b3 | b4;
+    };
+
+    PNG.prototype.readUInt16 = function () {
+      var b1, b2;
+      b1 = this.data[this.pos++] << 8;
+      b2 = this.data[this.pos++];
+      return b1 | b2;
+    };
+
+    PNG.prototype.decodePixels = function (data) {
+      var pixelBytes = this.pixelBitlength / 8;
+      var fullPixels = new Uint8Array(this.width * this.height * pixelBytes);
+      var pos = 0;
+
+      var _this = this;
+
+      if (data == null) {
+        data = this.imgData;
+      }
+
+      if (data.length === 0) {
+        return new Uint8Array(0);
+      }
+
+      data = unzlibSync(data);
+
+      function pass(x0, y0, dx, dy) {
+        var abyte, c, col, i, left, length, p, pa, paeth, pb, pc, pixels, row, scanlineLength, upper, upperLeft, _i, _j, _k, _l, _m;
+
+        var w = Math.ceil((_this.width - x0) / dx),
+            h = Math.ceil((_this.height - y0) / dy);
+        var isFull = _this.width == w && _this.height == h;
+        scanlineLength = pixelBytes * w;
+        pixels = isFull ? fullPixels : new Uint8Array(scanlineLength * h);
+        length = data.length;
+        row = 0;
+        c = 0;
+
+        while (row < h && pos < length) {
+          switch (data[pos++]) {
+            case 0:
+              for (i = _i = 0; _i < scanlineLength; i = _i += 1) {
+                pixels[c++] = data[pos++];
+              }
+
+              break;
+
+            case 1:
+              for (i = _j = 0; _j < scanlineLength; i = _j += 1) {
+                abyte = data[pos++];
+                left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
+                pixels[c++] = (abyte + left) % 256;
+              }
+
+              break;
+
+            case 2:
+              for (i = _k = 0; _k < scanlineLength; i = _k += 1) {
+                abyte = data[pos++];
+                col = (i - i % pixelBytes) / pixelBytes;
+                upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + i % pixelBytes];
+                pixels[c++] = (upper + abyte) % 256;
+              }
+
+              break;
+
+            case 3:
+              for (i = _l = 0; _l < scanlineLength; i = _l += 1) {
+                abyte = data[pos++];
+                col = (i - i % pixelBytes) / pixelBytes;
+                left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
+                upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + i % pixelBytes];
+                pixels[c++] = (abyte + Math.floor((left + upper) / 2)) % 256;
+              }
+
+              break;
+
+            case 4:
+              for (i = _m = 0; _m < scanlineLength; i = _m += 1) {
+                abyte = data[pos++];
+                col = (i - i % pixelBytes) / pixelBytes;
+                left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
+
+                if (row === 0) {
+                  upper = upperLeft = 0;
+                } else {
+                  upper = pixels[(row - 1) * scanlineLength + col * pixelBytes + i % pixelBytes];
+                  upperLeft = col && pixels[(row - 1) * scanlineLength + (col - 1) * pixelBytes + i % pixelBytes];
+                }
+
+                p = left + upper - upperLeft;
+                pa = Math.abs(p - left);
+                pb = Math.abs(p - upper);
+                pc = Math.abs(p - upperLeft);
+
+                if (pa <= pb && pa <= pc) {
+                  paeth = left;
+                } else if (pb <= pc) {
+                  paeth = upper;
+                } else {
+                  paeth = upperLeft;
+                }
+
+                pixels[c++] = (abyte + paeth) % 256;
+              }
+
+              break;
+
+            default:
+              throw new Error("Invalid filter algorithm: " + data[pos - 1]);
+          }
+
+          if (!isFull) {
+            var fullPos = ((y0 + row * dy) * _this.width + x0) * pixelBytes;
+            var partPos = row * scanlineLength;
+
+            for (i = 0; i < w; i += 1) {
+              for (var j = 0; j < pixelBytes; j += 1) {
+                fullPixels[fullPos++] = pixels[partPos++];
+              }
+
+              fullPos += (dx - 1) * pixelBytes;
+            }
+          }
+
+          row++;
+        }
+      }
+
+      if (_this.interlaceMethod == 1) {
+        /*
+            1 6 4 6 2 6 4 6
+            7 7 7 7 7 7 7 7
+            5 6 5 6 5 6 5 6
+            7 7 7 7 7 7 7 7
+            3 6 4 6 3 6 4 6
+            7 7 7 7 7 7 7 7
+            5 6 5 6 5 6 5 6
+            7 7 7 7 7 7 7 7
+          */
+        pass(0, 0, 8, 8); // 1
+
+        /* NOTE these seem to follow the pattern:
+         * pass(x, 0, 2*x, 2*x);
+         * pass(0, x,   x, 2*x);
+         * with x being 4, 2, 1.
+         */
+
+        pass(4, 0, 8, 8); // 2
+
+        pass(0, 4, 4, 8); // 3
+
+        pass(2, 0, 4, 4); // 4
+
+        pass(0, 2, 2, 4); // 5
+
+        pass(1, 0, 2, 2); // 6
+
+        pass(0, 1, 1, 2); // 7
+      } else {
+        pass(0, 0, 1, 1);
+      }
+
+      return fullPixels;
+    };
+
+    PNG.prototype.decodePalette = function () {
+      var c, i, length, palette, pos, ret, transparency, _i, _ref, _ref1;
+
+      palette = this.palette;
+      transparency = this.transparency.indexed || [];
+      ret = new Uint8Array((transparency.length || 0) + palette.length);
+      pos = 0;
+      length = palette.length;
+      c = 0;
+
+      for (i = _i = 0, _ref = length; _i < _ref; i = _i += 3) {
+        ret[pos++] = palette[i];
+        ret[pos++] = palette[i + 1];
+        ret[pos++] = palette[i + 2];
+        ret[pos++] = (_ref1 = transparency[c++]) != null ? _ref1 : 255;
+      }
+
+      return ret;
+    };
+
+    PNG.prototype.copyToImageData = function (imageData, pixels) {
+      var alpha, colors, data, i, input, j, k, length, palette, v, _ref;
+
+      colors = this.colors;
+      palette = null;
+      alpha = this.hasAlphaChannel;
+
+      if (this.palette.length) {
+        palette = (_ref = this._decodedPalette) != null ? _ref : this._decodedPalette = this.decodePalette();
+        colors = 4;
+        alpha = true;
+      }
+
+      data = imageData.data || imageData;
+      length = data.length;
+      input = palette || pixels;
+      i = j = 0;
+
+      if (colors === 1) {
+        while (i < length) {
+          k = palette ? pixels[i / 4] * 4 : j;
+          v = input[k++];
+          data[i++] = v;
+          data[i++] = v;
+          data[i++] = v;
+          data[i++] = alpha ? input[k++] : 255;
+          j = k;
+        }
+      } else {
+        while (i < length) {
+          k = palette ? pixels[i / 4] * 4 : j;
+          data[i++] = input[k++];
+          data[i++] = input[k++];
+          data[i++] = input[k++];
+          data[i++] = alpha ? input[k++] : 255;
+          j = k;
+        }
+      }
+    };
+
+    PNG.prototype.decode = function () {
+      var ret;
+      ret = new Uint8Array(this.width * this.height * 4);
+      this.copyToImageData(ret, this.decodePixels());
+      return ret;
+    };
+
+    var hasBrowserCanvas = function hasBrowserCanvas() {
+      if (Object.prototype.toString.call(globalObject) === "[object Window]") {
+        try {
+          scratchCanvas = globalObject.document.createElement("canvas");
+          scratchCtx = scratchCanvas.getContext("2d");
+        } catch (e) {
+          return false;
+        }
+
+        return true;
+      }
+
+      return false;
+    };
+
+    hasBrowserCanvas();
+
+    makeImage = function makeImage(imageData) {
+      if (hasBrowserCanvas() === true) {
+        var img;
+        scratchCtx.width = imageData.width;
+        scratchCtx.height = imageData.height;
+        scratchCtx.clearRect(0, 0, imageData.width, imageData.height);
+        scratchCtx.putImageData(imageData, 0, 0);
+        img = new Image();
+        img.src = scratchCanvas.toDataURL();
+        return img;
+      }
+
+      throw new Error("This method requires a Browser with Canvas-capability.");
+    };
+
+    PNG.prototype.decodeFrames = function (ctx) {
+      var frame, i, imageData, pixels, _i, _len, _ref, _results;
+
+      if (!this.animation) {
+        return;
+      }
+
+      _ref = this.animation.frames;
+      _results = [];
+
+      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
+        frame = _ref[i];
+        imageData = ctx.createImageData(frame.width, frame.height);
+        pixels = this.decodePixels(new Uint8Array(frame.data));
+        this.copyToImageData(imageData, pixels);
+        frame.imageData = imageData;
+
+        _results.push(frame.image = makeImage(imageData));
+      }
+
+      return _results;
+    };
+
+    PNG.prototype.renderFrame = function (ctx, number) {
+      var frame, frames, prev;
+      frames = this.animation.frames;
+      frame = frames[number];
+      prev = frames[number - 1];
+
+      if (number === 0) {
+        ctx.clearRect(0, 0, this.width, this.height);
+      }
+
+      if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_BACKGROUND) {
+        ctx.clearRect(prev.xOffset, prev.yOffset, prev.width, prev.height);
+      } else if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_PREVIOUS) {
+        ctx.putImageData(prev.imageData, prev.xOffset, prev.yOffset);
+      }
+
+      if (frame.blendOp === APNG_BLEND_OP_SOURCE) {
+        ctx.clearRect(frame.xOffset, frame.yOffset, frame.width, frame.height);
+      }
+
+      return ctx.drawImage(frame.image, frame.xOffset, frame.yOffset);
+    };
+
+    PNG.prototype.animate = function (ctx) {
+      var _doFrame,
+          frameNumber,
+          frames,
+          numFrames,
+          numPlays,
+          _ref,
+          _this = this;
+
+      frameNumber = 0;
+      _ref = this.animation, numFrames = _ref.numFrames, frames = _ref.frames, numPlays = _ref.numPlays;
+      return (_doFrame = function doFrame() {
+        var f, frame;
+        f = frameNumber++ % numFrames;
+        frame = frames[f];
+
+        _this.renderFrame(ctx, f);
+
+        if (numFrames > 1 && frameNumber / numFrames < numPlays) {
+          return _this.animation._timeout = setTimeout(_doFrame, frame.delay);
+        }
+      })();
+    };
+
+    PNG.prototype.stopAnimation = function () {
+      var _ref;
+
+      return clearTimeout((_ref = this.animation) != null ? _ref._timeout : void 0);
+    };
+
+    PNG.prototype.render = function (canvas) {
+      var ctx, data;
+
+      if (canvas._png) {
+        canvas._png.stopAnimation();
+      }
+
+      canvas._png = this;
+      canvas.width = this.width;
+      canvas.height = this.height;
+      ctx = canvas.getContext("2d");
+
+      if (this.animation) {
+        this.decodeFrames(ctx);
+        return this.animate(ctx);
+      } else {
+        data = ctx.createImageData(this.width, this.height);
+        this.copyToImageData(data, this.decodePixels());
+        return ctx.putImageData(data, 0, 0);
+      }
+    };
+
+    return PNG;
+  }();
+
+  /**
+   * @license
+   *
+   * Copyright (c) 2014 James Robb, https://github.com/jamesbrobb
+   *
+   * Permission is hereby granted, free of charge, to any person obtaining
+   * a copy of this software and associated documentation files (the
+   * "Software"), to deal in the Software without restriction, including
+   * without limitation the rights to use, copy, modify, merge, publish,
+   * distribute, sublicense, and/or sell copies of the Software, and to
+   * permit persons to whom the Software is furnished to do so, subject to
+   * the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be
+   * included in all copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+   * ====================================================================
+   */
+  /**
+   * jsPDF PNG PlugIn
+   * @name png_support
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+    /*
+     * @see http://www.w3.org/TR/PNG-Chunks.html
+     *
+     Color    Allowed      Interpretation
+     Type     Bit Depths
+        0       1,2,4,8,16  Each pixel is a grayscale sample.
+        2       8,16        Each pixel is an R,G,B triple.
+        3       1,2,4,8     Each pixel is a palette index;
+                           a PLTE chunk must appear.
+        4       8,16        Each pixel is a grayscale sample,
+                           followed by an alpha sample.
+        6       8,16        Each pixel is an R,G,B triple,
+                           followed by an alpha sample.
+    */
+
+    /*
+     * PNG filter method types
+     *
+     * @see http://www.w3.org/TR/PNG-Filters.html
+     * @see http://www.libpng.org/pub/png/book/chapter09.html
+     *
+     * This is what the value 'Predictor' in decode params relates to
+     *
+     * 15 is "optimal prediction", which means the prediction algorithm can change from line to line.
+     * In that case, you actually have to read the first byte off each line for the prediction algorthim (which should be 0-4, corresponding to PDF 10-14) and select the appropriate unprediction algorithm based on that byte.
+     *
+       0       None
+       1       Sub
+       2       Up
+       3       Average
+       4       Paeth
+     */
+
+    var canCompress = function canCompress(value) {
+      return value !== jsPDFAPI.image_compression.NONE && hasCompressionJS();
+    };
+
+    var hasCompressionJS = function hasCompressionJS() {
+      return typeof zlibSync === "function";
+    };
+
+    var compressBytes = function compressBytes(bytes, lineLength, colorsPerPixel, compression) {
+      var level = 4;
+      var filter_method = filterUp;
+
+      switch (compression) {
+        case jsPDFAPI.image_compression.FAST:
+          level = 1;
+          filter_method = filterSub;
+          break;
+
+        case jsPDFAPI.image_compression.MEDIUM:
+          level = 6;
+          filter_method = filterAverage;
+          break;
+
+        case jsPDFAPI.image_compression.SLOW:
+          level = 9;
+          filter_method = filterPaeth;
+          break;
+      }
+
+      bytes = applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method);
+      var dat = zlibSync(bytes, {
+        level: level
+      });
+      return jsPDFAPI.__addimage__.arrayBufferToBinaryString(dat);
+    };
+
+    var applyPngFilterMethod = function applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method) {
+      var lines = bytes.length / lineLength,
+          result = new Uint8Array(bytes.length + lines),
+          filter_methods = getFilterMethods(),
+          line,
+          prevLine,
+          offset;
+
+      for (var i = 0; i < lines; i += 1) {
+        offset = i * lineLength;
+        line = bytes.subarray(offset, offset + lineLength);
+
+        if (filter_method) {
+          result.set(filter_method(line, colorsPerPixel, prevLine), offset + i);
+        } else {
+          var len = filter_methods.length,
+              results = [];
+
+          for (var j; j < len; j += 1) {
+            results[j] = filter_methods[j](line, colorsPerPixel, prevLine);
+          }
+
+          var ind = getIndexOfSmallestSum(results.concat());
+          result.set(results[ind], offset + i);
+        }
+
+        prevLine = line;
+      }
+
+      return result;
+    };
+
+    var filterNone = function filterNone(line) {
+      /*var result = new Uint8Array(line.length + 1);
+      result[0] = 0;
+      result.set(line, 1);*/
+      var result = Array.apply([], line);
+      result.unshift(0);
+      return result;
+    };
+
+    var filterSub = function filterSub(line, colorsPerPixel) {
+      var result = [],
+          len = line.length,
+          left;
+      result[0] = 1;
+
+      for (var i = 0; i < len; i += 1) {
+        left = line[i - colorsPerPixel] || 0;
+        result[i + 1] = line[i] - left + 0x0100 & 0xff;
+      }
+
+      return result;
+    };
+
+    var filterUp = function filterUp(line, colorsPerPixel, prevLine) {
+      var result = [],
+          len = line.length,
+          up;
+      result[0] = 2;
+
+      for (var i = 0; i < len; i += 1) {
+        up = prevLine && prevLine[i] || 0;
+        result[i + 1] = line[i] - up + 0x0100 & 0xff;
+      }
+
+      return result;
+    };
+
+    var filterAverage = function filterAverage(line, colorsPerPixel, prevLine) {
+      var result = [],
+          len = line.length,
+          left,
+          up;
+      result[0] = 3;
+
+      for (var i = 0; i < len; i += 1) {
+        left = line[i - colorsPerPixel] || 0;
+        up = prevLine && prevLine[i] || 0;
+        result[i + 1] = line[i] + 0x0100 - (left + up >>> 1) & 0xff;
+      }
+
+      return result;
+    };
+
+    var filterPaeth = function filterPaeth(line, colorsPerPixel, prevLine) {
+      var result = [],
+          len = line.length,
+          left,
+          up,
+          upLeft,
+          paeth;
+      result[0] = 4;
+
+      for (var i = 0; i < len; i += 1) {
+        left = line[i - colorsPerPixel] || 0;
+        up = prevLine && prevLine[i] || 0;
+        upLeft = prevLine && prevLine[i - colorsPerPixel] || 0;
+        paeth = paethPredictor(left, up, upLeft);
+        result[i + 1] = line[i] - paeth + 0x0100 & 0xff;
+      }
+
+      return result;
+    };
+
+    var paethPredictor = function paethPredictor(left, up, upLeft) {
+      if (left === up && up === upLeft) {
+        return left;
+      }
+
+      var pLeft = Math.abs(up - upLeft),
+          pUp = Math.abs(left - upLeft),
+          pUpLeft = Math.abs(left + up - upLeft - upLeft);
+      return pLeft <= pUp && pLeft <= pUpLeft ? left : pUp <= pUpLeft ? up : upLeft;
+    };
+
+    var getFilterMethods = function getFilterMethods() {
+      return [filterNone, filterSub, filterUp, filterAverage, filterPaeth];
+    };
+
+    var getIndexOfSmallestSum = function getIndexOfSmallestSum(arrays) {
+      var sum = arrays.map(function (value) {
+        return value.reduce(function (pv, cv) {
+          return pv + Math.abs(cv);
+        }, 0);
+      });
+      return sum.indexOf(Math.min.apply(null, sum));
+    };
+
+    var getPredictorFromCompression = function getPredictorFromCompression(compression) {
+      var predictor;
+
+      switch (compression) {
+        case jsPDFAPI.image_compression.FAST:
+          predictor = 11;
+          break;
+
+        case jsPDFAPI.image_compression.MEDIUM:
+          predictor = 13;
+          break;
+
+        case jsPDFAPI.image_compression.SLOW:
+          predictor = 14;
+          break;
+
+        default:
+          predictor = 12;
+          break;
+      }
+
+      return predictor;
+    };
+    /**
+     * @name processPNG
+     * @function
+     * @ignore
+     */
+
+
+    jsPDFAPI.processPNG = function (imageData, index, alias, compression) {
+
+      var colorSpace,
+          filter = this.decode.FLATE_DECODE,
+          bitsPerComponent,
+          image,
+          decodeParameters = "",
+          trns,
+          colors,
+          pal,
+          smask,
+          pixels,
+          len,
+          alphaData,
+          imgData,
+          hasColors,
+          pixel,
+          i,
+          n;
+      if (this.__addimage__.isArrayBuffer(imageData)) imageData = new Uint8Array(imageData);
+
+      if (this.__addimage__.isArrayBufferView(imageData)) {
+        image = new PNG(imageData);
+        imageData = image.imgData;
+        bitsPerComponent = image.bits;
+        colorSpace = image.colorSpace;
+        colors = image.colors;
+        /*
+         * colorType 6 - Each pixel is an R,G,B triple, followed by an alpha sample.
+         *
+         * colorType 4 - Each pixel is a grayscale sample, followed by an alpha sample.
+         *
+         * Extract alpha to create two separate images, using the alpha as a sMask
+         */
+
+        if ([4, 6].indexOf(image.colorType) !== -1) {
+          /*
+           * processes 8 bit RGBA and grayscale + alpha images
+           */
+          if (image.bits === 8) {
+            pixels = image.pixelBitlength == 32 ? new Uint32Array(image.decodePixels().buffer) : image.pixelBitlength == 16 ? new Uint16Array(image.decodePixels().buffer) : new Uint8Array(image.decodePixels().buffer);
+            len = pixels.length;
+            imgData = new Uint8Array(len * image.colors);
+            alphaData = new Uint8Array(len);
+            var pDiff = image.pixelBitlength - image.bits;
+            i = 0;
+            n = 0;
+            var pbl;
+
+            for (; i < len; i++) {
+              pixel = pixels[i];
+              pbl = 0;
+
+              while (pbl < pDiff) {
+                imgData[n++] = pixel >>> pbl & 0xff;
+                pbl = pbl + image.bits;
+              }
+
+              alphaData[i] = pixel >>> pbl & 0xff;
+            }
+          }
+          /*
+           * processes 16 bit RGBA and grayscale + alpha images
+           */
+
+
+          if (image.bits === 16) {
+            pixels = new Uint32Array(image.decodePixels().buffer);
+            len = pixels.length;
+            imgData = new Uint8Array(len * (32 / image.pixelBitlength) * image.colors);
+            alphaData = new Uint8Array(len * (32 / image.pixelBitlength));
+            hasColors = image.colors > 1;
+            i = 0;
+            n = 0;
+            var a = 0;
+
+            while (i < len) {
+              pixel = pixels[i++];
+              imgData[n++] = pixel >>> 0 & 0xff;
+
+              if (hasColors) {
+                imgData[n++] = pixel >>> 16 & 0xff;
+                pixel = pixels[i++];
+                imgData[n++] = pixel >>> 0 & 0xff;
+              }
+
+              alphaData[a++] = pixel >>> 16 & 0xff;
+            }
+
+            bitsPerComponent = 8;
+          }
+
+          if (canCompress(compression)) {
+            imageData = compressBytes(imgData, image.width * image.colors, image.colors, compression);
+            smask = compressBytes(alphaData, image.width, 1, compression);
+          } else {
+            imageData = imgData;
+            smask = alphaData;
+            filter = undefined;
+          }
+        }
+        /*
+         * Indexed png. Each pixel is a palette index.
+         */
+
+
+        if (image.colorType === 3) {
+          colorSpace = this.color_spaces.INDEXED;
+          pal = image.palette;
+
+          if (image.transparency.indexed) {
+            var trans = image.transparency.indexed;
+            var total = 0;
+            i = 0;
+            len = trans.length;
+
+            for (; i < len; ++i) {
+              total += trans[i];
+            }
+
+            total = total / 255;
+            /*
+             * a single color is specified as 100% transparent (0),
+             * so we set trns to use a /Mask with that index
+             */
+
+            if (total === len - 1 && trans.indexOf(0) !== -1) {
+              trns = [trans.indexOf(0)];
+              /*
+               * there's more than one colour within the palette that specifies
+               * a transparency value less than 255, so we unroll the pixels to create an image sMask
+               */
+            } else if (total !== len) {
+              pixels = image.decodePixels();
+              alphaData = new Uint8Array(pixels.length);
+              i = 0;
+              len = pixels.length;
+
+              for (; i < len; i++) {
+                alphaData[i] = trans[pixels[i]];
+              }
+
+              smask = compressBytes(alphaData, image.width, 1);
+            }
+          }
+        }
+
+        var predictor = getPredictorFromCompression(compression);
+
+        if (filter === this.decode.FLATE_DECODE) {
+          decodeParameters = "/Predictor " + predictor + " ";
+        }
+
+        decodeParameters += "/Colors " + colors + " /BitsPerComponent " + bitsPerComponent + " /Columns " + image.width;
+
+        if (this.__addimage__.isArrayBuffer(imageData) || this.__addimage__.isArrayBufferView(imageData)) {
+          imageData = this.__addimage__.arrayBufferToBinaryString(imageData);
+        }
+
+        if (smask && this.__addimage__.isArrayBuffer(smask) || this.__addimage__.isArrayBufferView(smask)) {
+          smask = this.__addimage__.arrayBufferToBinaryString(smask);
+        }
+
+        return {
+          alias: alias,
+          data: imageData,
+          index: index,
+          filter: filter,
+          decodeParameters: decodeParameters,
+          transparency: trns,
+          palette: pal,
+          sMask: smask,
+          predictor: predictor,
+          width: image.width,
+          height: image.height,
+          bitsPerComponent: bitsPerComponent,
+          colorSpace: colorSpace
+        };
+      }
+    };
+  })(jsPDF.API);
+
+  /**
+   * @license
+   * (c) Dean McNamee <dean@gmail.com>, 2013.
+   *
+   * https://github.com/deanm/omggif
+   *
+   * Permission is hereby granted, free of charge, to any person obtaining a copy
+   * of this software and associated documentation files (the "Software"), to
+   * deal in the Software without restriction, including without limitation the
+   * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+   * sell copies of the Software, and to permit persons to whom the Software is
+   * furnished to do so, subject to the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be included in
+   * all copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+   * IN THE SOFTWARE.
+   *
+   * omggif is a JavaScript implementation of a GIF 89a encoder and decoder,
+   * including animation and compression.  It does not rely on any specific
+   * underlying system, so should run in the browser, Node, or Plask.
+   */
+
+  function GifReader(buf) {
+    var p = 0; // - Header (GIF87a or GIF89a).
+
+    if (buf[p++] !== 0x47 || buf[p++] !== 0x49 || buf[p++] !== 0x46 || buf[p++] !== 0x38 || (buf[p++] + 1 & 0xfd) !== 0x38 || buf[p++] !== 0x61) {
+      throw new Error("Invalid GIF 87a/89a header.");
+    } // - Logical Screen Descriptor.
+
+
+    var width = buf[p++] | buf[p++] << 8;
+    var height = buf[p++] | buf[p++] << 8;
+    var pf0 = buf[p++]; // <Packed Fields>.
+
+    var global_palette_flag = pf0 >> 7;
+    var num_global_colors_pow2 = pf0 & 0x7;
+    var num_global_colors = 1 << num_global_colors_pow2 + 1;
+    var background = buf[p++];
+    buf[p++]; // Pixel aspect ratio (unused?).
+
+    var global_palette_offset = null;
+    var global_palette_size = null;
+
+    if (global_palette_flag) {
+      global_palette_offset = p;
+      global_palette_size = num_global_colors;
+      p += num_global_colors * 3; // Seek past palette.
+    }
+
+    var no_eof = true;
+    var frames = [];
+    var delay = 0;
+    var transparent_index = null;
+    var disposal = 0; // 0 - No disposal specified.
+
+    var loop_count = null;
+    this.width = width;
+    this.height = height;
+
+    while (no_eof && p < buf.length) {
+      switch (buf[p++]) {
+        case 0x21:
+          // Graphics Control Extension Block
+          switch (buf[p++]) {
+            case 0xff:
+              // Application specific block
+              // Try if it's a Netscape block (with animation loop counter).
+              if (buf[p] !== 0x0b || // 21 FF already read, check block size.
+              // NETSCAPE2.0
+              buf[p + 1] == 0x4e && buf[p + 2] == 0x45 && buf[p + 3] == 0x54 && buf[p + 4] == 0x53 && buf[p + 5] == 0x43 && buf[p + 6] == 0x41 && buf[p + 7] == 0x50 && buf[p + 8] == 0x45 && buf[p + 9] == 0x32 && buf[p + 10] == 0x2e && buf[p + 11] == 0x30 && // Sub-block
+              buf[p + 12] == 0x03 && buf[p + 13] == 0x01 && buf[p + 16] == 0) {
+                p += 14;
+                loop_count = buf[p++] | buf[p++] << 8;
+                p++; // Skip terminator.
+              } else {
+                // We don't know what it is, just try to get past it.
+                p += 12;
+
+                while (true) {
+                  // Seek through subblocks.
+                  var block_size = buf[p++]; // Bad block size (ex: undefined from an out of bounds read).
+
+                  if (!(block_size >= 0)) throw Error("Invalid block size");
+                  if (block_size === 0) break; // 0 size is terminator
+
+                  p += block_size;
+                }
+              }
+
+              break;
+
+            case 0xf9:
+              // Graphics Control Extension
+              if (buf[p++] !== 0x4 || buf[p + 4] !== 0) throw new Error("Invalid graphics extension block.");
+              var pf1 = buf[p++];
+              delay = buf[p++] | buf[p++] << 8;
+              transparent_index = buf[p++];
+              if ((pf1 & 1) === 0) transparent_index = null;
+              disposal = pf1 >> 2 & 0x7;
+              p++; // Skip terminator.
+
+              break;
+
+            case 0xfe:
+              // Comment Extension.
+              while (true) {
+                // Seek through subblocks.
+                var block_size = buf[p++]; // Bad block size (ex: undefined from an out of bounds read).
+
+                if (!(block_size >= 0)) throw Error("Invalid block size");
+                if (block_size === 0) break; // 0 size is terminator
+                // console.log(buf.slice(p, p+block_size).toString('ascii'));
+
+                p += block_size;
+              }
+
+              break;
+
+            default:
+              throw new Error("Unknown graphic control label: 0x" + buf[p - 1].toString(16));
+          }
+
+          break;
+
+        case 0x2c:
+          // Image Descriptor.
+          var x = buf[p++] | buf[p++] << 8;
+          var y = buf[p++] | buf[p++] << 8;
+          var w = buf[p++] | buf[p++] << 8;
+          var h = buf[p++] | buf[p++] << 8;
+          var pf2 = buf[p++];
+          var local_palette_flag = pf2 >> 7;
+          var interlace_flag = pf2 >> 6 & 1;
+          var num_local_colors_pow2 = pf2 & 0x7;
+          var num_local_colors = 1 << num_local_colors_pow2 + 1;
+          var palette_offset = global_palette_offset;
+          var palette_size = global_palette_size;
+          var has_local_palette = false;
+
+          if (local_palette_flag) {
+            var has_local_palette = true;
+            palette_offset = p; // Override with local palette.
+
+            palette_size = num_local_colors;
+            p += num_local_colors * 3; // Seek past palette.
+          }
+
+          var data_offset = p;
+          p++; // codesize
+
+          while (true) {
+            var block_size = buf[p++]; // Bad block size (ex: undefined from an out of bounds read).
+
+            if (!(block_size >= 0)) throw Error("Invalid block size");
+            if (block_size === 0) break; // 0 size is terminator
+
+            p += block_size;
+          }
+
+          frames.push({
+            x: x,
+            y: y,
+            width: w,
+            height: h,
+            has_local_palette: has_local_palette,
+            palette_offset: palette_offset,
+            palette_size: palette_size,
+            data_offset: data_offset,
+            data_length: p - data_offset,
+            transparent_index: transparent_index,
+            interlaced: !!interlace_flag,
+            delay: delay,
+            disposal: disposal
+          });
+          break;
+
+        case 0x3b:
+          // Trailer Marker (end of file).
+          no_eof = false;
+          break;
+
+        default:
+          throw new Error("Unknown gif block: 0x" + buf[p - 1].toString(16));
+      }
+    }
+
+    this.numFrames = function () {
+      return frames.length;
+    };
+
+    this.loopCount = function () {
+      return loop_count;
+    };
+
+    this.frameInfo = function (frame_num) {
+      if (frame_num < 0 || frame_num >= frames.length) throw new Error("Frame index out of range.");
+      return frames[frame_num];
+    };
+
+    this.decodeAndBlitFrameBGRA = function (frame_num, pixels) {
+      var frame = this.frameInfo(frame_num);
+      var num_pixels = frame.width * frame.height;
+      var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices.
+
+      GifReaderLZWOutputIndexStream(buf, frame.data_offset, index_stream, num_pixels);
+      var palette_offset = frame.palette_offset; // NOTE(deanm): It seems to be much faster to compare index to 256 than
+      // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in
+      // the profile, not sure if it's related to using a Uint8Array.
+
+      var trans = frame.transparent_index;
+      if (trans === null) trans = 256; // We are possibly just blitting to a portion of the entire frame.
+      // That is a subrect within the framerect, so the additional pixels
+      // must be skipped over after we finished a scanline.
+
+      var framewidth = frame.width;
+      var framestride = width - framewidth;
+      var xleft = framewidth; // Number of subrect pixels left in scanline.
+      // Output indices of the top left and bottom right corners of the subrect.
+
+      var opbeg = (frame.y * width + frame.x) * 4;
+      var opend = ((frame.y + frame.height) * width + frame.x) * 4;
+      var op = opbeg;
+      var scanstride = framestride * 4; // Use scanstride to skip past the rows when interlacing.  This is skipping
+      // 7 rows for the first two passes, then 3 then 1.
+
+      if (frame.interlaced === true) {
+        scanstride += width * 4 * 7; // Pass 1.
+      }
+
+      var interlaceskip = 8; // Tracking the row interval in the current pass.
+
+      for (var i = 0, il = index_stream.length; i < il; ++i) {
+        var index = index_stream[i];
+
+        if (xleft === 0) {
+          // Beginning of new scan line
+          op += scanstride;
+          xleft = framewidth;
+
+          if (op >= opend) {
+            // Catch the wrap to switch passes when interlacing.
+            scanstride = framestride * 4 + width * 4 * (interlaceskip - 1); // interlaceskip / 2 * 4 is interlaceskip << 1.
+
+            op = opbeg + (framewidth + framestride) * (interlaceskip << 1);
+            interlaceskip >>= 1;
+          }
+        }
+
+        if (index === trans) {
+          op += 4;
+        } else {
+          var r = buf[palette_offset + index * 3];
+          var g = buf[palette_offset + index * 3 + 1];
+          var b = buf[palette_offset + index * 3 + 2];
+          pixels[op++] = b;
+          pixels[op++] = g;
+          pixels[op++] = r;
+          pixels[op++] = 255;
+        }
+
+        --xleft;
+      }
+    }; // I will go to copy and paste hell one day...
+
+
+    this.decodeAndBlitFrameRGBA = function (frame_num, pixels) {
+      var frame = this.frameInfo(frame_num);
+      var num_pixels = frame.width * frame.height;
+      var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices.
+
+      GifReaderLZWOutputIndexStream(buf, frame.data_offset, index_stream, num_pixels);
+      var palette_offset = frame.palette_offset; // NOTE(deanm): It seems to be much faster to compare index to 256 than
+      // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in
+      // the profile, not sure if it's related to using a Uint8Array.
+
+      var trans = frame.transparent_index;
+      if (trans === null) trans = 256; // We are possibly just blitting to a portion of the entire frame.
+      // That is a subrect within the framerect, so the additional pixels
+      // must be skipped over after we finished a scanline.
+
+      var framewidth = frame.width;
+      var framestride = width - framewidth;
+      var xleft = framewidth; // Number of subrect pixels left in scanline.
+      // Output indices of the top left and bottom right corners of the subrect.
+
+      var opbeg = (frame.y * width + frame.x) * 4;
+      var opend = ((frame.y + frame.height) * width + frame.x) * 4;
+      var op = opbeg;
+      var scanstride = framestride * 4; // Use scanstride to skip past the rows when interlacing.  This is skipping
+      // 7 rows for the first two passes, then 3 then 1.
+
+      if (frame.interlaced === true) {
+        scanstride += width * 4 * 7; // Pass 1.
+      }
+
+      var interlaceskip = 8; // Tracking the row interval in the current pass.
+
+      for (var i = 0, il = index_stream.length; i < il; ++i) {
+        var index = index_stream[i];
+
+        if (xleft === 0) {
+          // Beginning of new scan line
+          op += scanstride;
+          xleft = framewidth;
+
+          if (op >= opend) {
+            // Catch the wrap to switch passes when interlacing.
+            scanstride = framestride * 4 + width * 4 * (interlaceskip - 1); // interlaceskip / 2 * 4 is interlaceskip << 1.
+
+            op = opbeg + (framewidth + framestride) * (interlaceskip << 1);
+            interlaceskip >>= 1;
+          }
+        }
+
+        if (index === trans) {
+          op += 4;
+        } else {
+          var r = buf[palette_offset + index * 3];
+          var g = buf[palette_offset + index * 3 + 1];
+          var b = buf[palette_offset + index * 3 + 2];
+          pixels[op++] = r;
+          pixels[op++] = g;
+          pixels[op++] = b;
+          pixels[op++] = 255;
+        }
+
+        --xleft;
+      }
+    };
+  }
+
+  function GifReaderLZWOutputIndexStream(code_stream, p, output, output_length) {
+    var min_code_size = code_stream[p++];
+    var clear_code = 1 << min_code_size;
+    var eoi_code = clear_code + 1;
+    var next_code = eoi_code + 1;
+    var cur_code_size = min_code_size + 1; // Number of bits per code.
+    // NOTE: This shares the same name as the encoder, but has a different
+    // meaning here.  Here this masks each code coming from the code stream.
+
+    var code_mask = (1 << cur_code_size) - 1;
+    var cur_shift = 0;
+    var cur = 0;
+    var op = 0; // Output pointer.
+
+    var subblock_size = code_stream[p++]; // TODO(deanm): Would using a TypedArray be any faster?  At least it would
+    // solve the fast mode / backing store uncertainty.
+    // var code_table = Array(4096);
+
+    var code_table = new Int32Array(4096); // Can be signed, we only use 20 bits.
+
+    var prev_code = null; // Track code-1.
+
+    while (true) {
+      // Read up to two bytes, making sure we always 12-bits for max sized code.
+      while (cur_shift < 16) {
+        if (subblock_size === 0) break; // No more data to be read.
+
+        cur |= code_stream[p++] << cur_shift;
+        cur_shift += 8;
+
+        if (subblock_size === 1) {
+          // Never let it get to 0 to hold logic above.
+          subblock_size = code_stream[p++]; // Next subblock.
+        } else {
+          --subblock_size;
+        }
+      } // TODO(deanm): We should never really get here, we should have received
+      // and EOI.
+
+
+      if (cur_shift < cur_code_size) break;
+      var code = cur & code_mask;
+      cur >>= cur_code_size;
+      cur_shift -= cur_code_size; // TODO(deanm): Maybe should check that the first code was a clear code,
+      // at least this is what you're supposed to do.  But actually our encoder
+      // now doesn't emit a clear code first anyway.
+
+      if (code === clear_code) {
+        // We don't actually have to clear the table.  This could be a good idea
+        // for greater error checking, but we don't really do any anyway.  We
+        // will just track it with next_code and overwrite old entries.
+        next_code = eoi_code + 1;
+        cur_code_size = min_code_size + 1;
+        code_mask = (1 << cur_code_size) - 1; // Don't update prev_code ?
+
+        prev_code = null;
+        continue;
+      } else if (code === eoi_code) {
+        break;
+      } // We have a similar situation as the decoder, where we want to store
+      // variable length entries (code table entries), but we want to do in a
+      // faster manner than an array of arrays.  The code below stores sort of a
+      // linked list within the code table, and then "chases" through it to
+      // construct the dictionary entries.  When a new entry is created, just the
+      // last byte is stored, and the rest (prefix) of the entry is only
+      // referenced by its table entry.  Then the code chases through the
+      // prefixes until it reaches a single byte code.  We have to chase twice,
+      // first to compute the length, and then to actually copy the data to the
+      // output (backwards, since we know the length).  The alternative would be
+      // storing something in an intermediate stack, but that doesn't make any
+      // more sense.  I implemented an approach where it also stored the length
+      // in the code table, although it's a bit tricky because you run out of
+      // bits (12 + 12 + 8), but I didn't measure much improvements (the table
+      // entries are generally not the long).  Even when I created benchmarks for
+      // very long table entries the complexity did not seem worth it.
+      // The code table stores the prefix entry in 12 bits and then the suffix
+      // byte in 8 bits, so each entry is 20 bits.
+
+
+      var chase_code = code < next_code ? code : prev_code; // Chase what we will output, either {CODE} or {CODE-1}.
+
+      var chase_length = 0;
+      var chase = chase_code;
+
+      while (chase > clear_code) {
+        chase = code_table[chase] >> 8;
+        ++chase_length;
+      }
+
+      var k = chase;
+      var op_end = op + chase_length + (chase_code !== code ? 1 : 0);
+
+      if (op_end > output_length) {
+        console.log("Warning, gif stream longer than expected.");
+        return;
+      } // Already have the first byte from the chase, might as well write it fast.
+
+
+      output[op++] = k;
+      op += chase_length;
+      var b = op; // Track pointer, writing backwards.
+
+      if (chase_code !== code) // The case of emitting {CODE-1} + k.
+        output[op++] = k;
+      chase = chase_code;
+
+      while (chase_length--) {
+        chase = code_table[chase];
+        output[--b] = chase & 0xff; // Write backwards.
+
+        chase >>= 8; // Pull down to the prefix code.
+      }
+
+      if (prev_code !== null && next_code < 4096) {
+        code_table[next_code++] = prev_code << 8 | k; // TODO(deanm): Figure out this clearing vs code growth logic better.  I
+        // have an feeling that it should just happen somewhere else, for now it
+        // is awkward between when we grow past the max and then hit a clear code.
+        // For now just check if we hit the max 12-bits (then a clear code should
+        // follow, also of course encoded in 12-bits).
+
+        if (next_code >= code_mask + 1 && cur_code_size < 12) {
+          ++cur_code_size;
+          code_mask = code_mask << 1 | 1;
+        }
+      }
+
+      prev_code = code;
+    }
+
+    if (op !== output_length) {
+      console.log("Warning, gif stream shorter than expected.");
+    }
+
+    return output;
+  }
+
+  /**
+   * @license
+    Copyright (c) 2008, Adobe Systems Incorporated
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without 
+    modification, are permitted provided that the following conditions are
+    met:
+
+    * Redistributions of source code must retain the above copyright notice, 
+      this list of conditions and the following disclaimer.
+    
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the 
+      documentation and/or other materials provided with the distribution.
+    
+    * Neither the name of Adobe Systems Incorporated nor the names of its 
+      contributors may be used to endorse or promote products derived from 
+      this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
+    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  */
+
+  /*
+  JPEG encoder ported to JavaScript and optimized by Andreas Ritter, www.bytestrom.eu, 11/2009
+
+  Basic GUI blocking jpeg encoder
+  */
+  function JPEGEncoder(quality) {
+    var ffloor = Math.floor;
+    var YTable = new Array(64);
+    var UVTable = new Array(64);
+    var fdtbl_Y = new Array(64);
+    var fdtbl_UV = new Array(64);
+    var YDC_HT;
+    var UVDC_HT;
+    var YAC_HT;
+    var UVAC_HT;
+    var bitcode = new Array(65535);
+    var category = new Array(65535);
+    var outputfDCTQuant = new Array(64);
+    var DU = new Array(64);
+    var byteout = [];
+    var bytenew = 0;
+    var bytepos = 7;
+    var YDU = new Array(64);
+    var UDU = new Array(64);
+    var VDU = new Array(64);
+    var clt = new Array(256);
+    var RGB_YUV_TABLE = new Array(2048);
+    var currentQuality;
+    var ZigZag = [0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63];
+    var std_dc_luminance_nrcodes = [0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0];
+    var std_dc_luminance_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
+    var std_ac_luminance_nrcodes = [0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d];
+    var std_ac_luminance_values = [0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa];
+    var std_dc_chrominance_nrcodes = [0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0];
+    var std_dc_chrominance_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
+    var std_ac_chrominance_nrcodes = [0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77];
+    var std_ac_chrominance_values = [0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa];
+
+    function initQuantTables(sf) {
+      var YQT = [16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99];
+
+      for (var i = 0; i < 64; i++) {
+        var t = ffloor((YQT[i] * sf + 50) / 100);
+        t = Math.min(Math.max(t, 1), 255);
+        YTable[ZigZag[i]] = t;
+      }
+
+      var UVQT = [17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99];
+
+      for (var j = 0; j < 64; j++) {
+        var u = ffloor((UVQT[j] * sf + 50) / 100);
+        u = Math.min(Math.max(u, 1), 255);
+        UVTable[ZigZag[j]] = u;
+      }
+
+      var aasf = [1.0, 1.387039845, 1.306562965, 1.175875602, 1.0, 0.785694958, 0.5411961, 0.275899379];
+      var k = 0;
+
+      for (var row = 0; row < 8; row++) {
+        for (var col = 0; col < 8; col++) {
+          fdtbl_Y[k] = 1.0 / (YTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0);
+          fdtbl_UV[k] = 1.0 / (UVTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0);
+          k++;
+        }
+      }
+    }
+
+    function computeHuffmanTbl(nrcodes, std_table) {
+      var codevalue = 0;
+      var pos_in_table = 0;
+      var HT = new Array();
+
+      for (var k = 1; k <= 16; k++) {
+        for (var j = 1; j <= nrcodes[k]; j++) {
+          HT[std_table[pos_in_table]] = [];
+          HT[std_table[pos_in_table]][0] = codevalue;
+          HT[std_table[pos_in_table]][1] = k;
+          pos_in_table++;
+          codevalue++;
+        }
+
+        codevalue *= 2;
+      }
+
+      return HT;
+    }
+
+    function initHuffmanTbl() {
+      YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes, std_dc_luminance_values);
+      UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes, std_dc_chrominance_values);
+      YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes, std_ac_luminance_values);
+      UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes, std_ac_chrominance_values);
+    }
+
+    function initCategoryNumber() {
+      var nrlower = 1;
+      var nrupper = 2;
+
+      for (var cat = 1; cat <= 15; cat++) {
+        //Positive numbers
+        for (var nr = nrlower; nr < nrupper; nr++) {
+          category[32767 + nr] = cat;
+          bitcode[32767 + nr] = [];
+          bitcode[32767 + nr][1] = cat;
+          bitcode[32767 + nr][0] = nr;
+        } //Negative numbers
+
+
+        for (var nrneg = -(nrupper - 1); nrneg <= -nrlower; nrneg++) {
+          category[32767 + nrneg] = cat;
+          bitcode[32767 + nrneg] = [];
+          bitcode[32767 + nrneg][1] = cat;
+          bitcode[32767 + nrneg][0] = nrupper - 1 + nrneg;
+        }
+
+        nrlower <<= 1;
+        nrupper <<= 1;
+      }
+    }
+
+    function initRGBYUVTable() {
+      for (var i = 0; i < 256; i++) {
+        RGB_YUV_TABLE[i] = 19595 * i;
+        RGB_YUV_TABLE[i + 256 >> 0] = 38470 * i;
+        RGB_YUV_TABLE[i + 512 >> 0] = 7471 * i + 0x8000;
+        RGB_YUV_TABLE[i + 768 >> 0] = -11059 * i;
+        RGB_YUV_TABLE[i + 1024 >> 0] = -21709 * i;
+        RGB_YUV_TABLE[i + 1280 >> 0] = 32768 * i + 0x807fff;
+        RGB_YUV_TABLE[i + 1536 >> 0] = -27439 * i;
+        RGB_YUV_TABLE[i + 1792 >> 0] = -5329 * i;
+      }
+    } // IO functions
+
+
+    function writeBits(bs) {
+      var value = bs[0];
+      var posval = bs[1] - 1;
+
+      while (posval >= 0) {
+        if (value & 1 << posval) {
+          bytenew |= 1 << bytepos;
+        }
+
+        posval--;
+        bytepos--;
+
+        if (bytepos < 0) {
+          if (bytenew == 0xff) {
+            writeByte(0xff);
+            writeByte(0);
+          } else {
+            writeByte(bytenew);
+          }
+
+          bytepos = 7;
+          bytenew = 0;
+        }
+      }
+    }
+
+    function writeByte(value) {
+      //byteout.push(clt[value]); // write char directly instead of converting later
+      byteout.push(value);
+    }
+
+    function writeWord(value) {
+      writeByte(value >> 8 & 0xff);
+      writeByte(value & 0xff);
+    } // DCT & quantization core
+
+
+    function fDCTQuant(data, fdtbl) {
+      var d0, d1, d2, d3, d4, d5, d6, d7;
+      /* Pass 1: process rows. */
+
+      var dataOff = 0;
+      var i;
+      var I8 = 8;
+      var I64 = 64;
+
+      for (i = 0; i < I8; ++i) {
+        d0 = data[dataOff];
+        d1 = data[dataOff + 1];
+        d2 = data[dataOff + 2];
+        d3 = data[dataOff + 3];
+        d4 = data[dataOff + 4];
+        d5 = data[dataOff + 5];
+        d6 = data[dataOff + 6];
+        d7 = data[dataOff + 7];
+        var tmp0 = d0 + d7;
+        var tmp7 = d0 - d7;
+        var tmp1 = d1 + d6;
+        var tmp6 = d1 - d6;
+        var tmp2 = d2 + d5;
+        var tmp5 = d2 - d5;
+        var tmp3 = d3 + d4;
+        var tmp4 = d3 - d4;
+        /* Even part */
+
+        var tmp10 = tmp0 + tmp3;
+        /* phase 2 */
+
+        var tmp13 = tmp0 - tmp3;
+        var tmp11 = tmp1 + tmp2;
+        var tmp12 = tmp1 - tmp2;
+        data[dataOff] = tmp10 + tmp11;
+        /* phase 3 */
+
+        data[dataOff + 4] = tmp10 - tmp11;
+        var z1 = (tmp12 + tmp13) * 0.707106781;
+        /* c4 */
+
+        data[dataOff + 2] = tmp13 + z1;
+        /* phase 5 */
+
+        data[dataOff + 6] = tmp13 - z1;
+        /* Odd part */
+
+        tmp10 = tmp4 + tmp5;
+        /* phase 2 */
+
+        tmp11 = tmp5 + tmp6;
+        tmp12 = tmp6 + tmp7;
+        /* The rotator is modified from fig 4-8 to avoid extra negations. */
+
+        var z5 = (tmp10 - tmp12) * 0.382683433;
+        /* c6 */
+
+        var z2 = 0.5411961 * tmp10 + z5;
+        /* c2-c6 */
+
+        var z4 = 1.306562965 * tmp12 + z5;
+        /* c2+c6 */
+
+        var z3 = tmp11 * 0.707106781;
+        /* c4 */
+
+        var z11 = tmp7 + z3;
+        /* phase 5 */
+
+        var z13 = tmp7 - z3;
+        data[dataOff + 5] = z13 + z2;
+        /* phase 6 */
+
+        data[dataOff + 3] = z13 - z2;
+        data[dataOff + 1] = z11 + z4;
+        data[dataOff + 7] = z11 - z4;
+        dataOff += 8;
+        /* advance pointer to next row */
+      }
+      /* Pass 2: process columns. */
+
+
+      dataOff = 0;
+
+      for (i = 0; i < I8; ++i) {
+        d0 = data[dataOff];
+        d1 = data[dataOff + 8];
+        d2 = data[dataOff + 16];
+        d3 = data[dataOff + 24];
+        d4 = data[dataOff + 32];
+        d5 = data[dataOff + 40];
+        d6 = data[dataOff + 48];
+        d7 = data[dataOff + 56];
+        var tmp0p2 = d0 + d7;
+        var tmp7p2 = d0 - d7;
+        var tmp1p2 = d1 + d6;
+        var tmp6p2 = d1 - d6;
+        var tmp2p2 = d2 + d5;
+        var tmp5p2 = d2 - d5;
+        var tmp3p2 = d3 + d4;
+        var tmp4p2 = d3 - d4;
+        /* Even part */
+
+        var tmp10p2 = tmp0p2 + tmp3p2;
+        /* phase 2 */
+
+        var tmp13p2 = tmp0p2 - tmp3p2;
+        var tmp11p2 = tmp1p2 + tmp2p2;
+        var tmp12p2 = tmp1p2 - tmp2p2;
+        data[dataOff] = tmp10p2 + tmp11p2;
+        /* phase 3 */
+
+        data[dataOff + 32] = tmp10p2 - tmp11p2;
+        var z1p2 = (tmp12p2 + tmp13p2) * 0.707106781;
+        /* c4 */
+
+        data[dataOff + 16] = tmp13p2 + z1p2;
+        /* phase 5 */
+
+        data[dataOff + 48] = tmp13p2 - z1p2;
+        /* Odd part */
+
+        tmp10p2 = tmp4p2 + tmp5p2;
+        /* phase 2 */
+
+        tmp11p2 = tmp5p2 + tmp6p2;
+        tmp12p2 = tmp6p2 + tmp7p2;
+        /* The rotator is modified from fig 4-8 to avoid extra negations. */
+
+        var z5p2 = (tmp10p2 - tmp12p2) * 0.382683433;
+        /* c6 */
+
+        var z2p2 = 0.5411961 * tmp10p2 + z5p2;
+        /* c2-c6 */
+
+        var z4p2 = 1.306562965 * tmp12p2 + z5p2;
+        /* c2+c6 */
+
+        var z3p2 = tmp11p2 * 0.707106781;
+        /* c4 */
+
+        var z11p2 = tmp7p2 + z3p2;
+        /* phase 5 */
+
+        var z13p2 = tmp7p2 - z3p2;
+        data[dataOff + 40] = z13p2 + z2p2;
+        /* phase 6 */
+
+        data[dataOff + 24] = z13p2 - z2p2;
+        data[dataOff + 8] = z11p2 + z4p2;
+        data[dataOff + 56] = z11p2 - z4p2;
+        dataOff++;
+        /* advance pointer to next column */
+      } // Quantize/descale the coefficients
+
+
+      var fDCTQuant;
+
+      for (i = 0; i < I64; ++i) {
+        // Apply the quantization and scaling factor & Round to nearest integer
+        fDCTQuant = data[i] * fdtbl[i];
+        outputfDCTQuant[i] = fDCTQuant > 0.0 ? fDCTQuant + 0.5 | 0 : fDCTQuant - 0.5 | 0; //outputfDCTQuant[i] = fround(fDCTQuant);
+      }
+
+      return outputfDCTQuant;
+    }
+
+    function writeAPP0() {
+      writeWord(0xffe0); // marker
+
+      writeWord(16); // length
+
+      writeByte(0x4a); // J
+
+      writeByte(0x46); // F
+
+      writeByte(0x49); // I
+
+      writeByte(0x46); // F
+
+      writeByte(0); // = "JFIF",'\0'
+
+      writeByte(1); // versionhi
+
+      writeByte(1); // versionlo
+
+      writeByte(0); // xyunits
+
+      writeWord(1); // xdensity
+
+      writeWord(1); // ydensity
+
+      writeByte(0); // thumbnwidth
+
+      writeByte(0); // thumbnheight
+    }
+
+    function writeSOF0(width, height) {
+      writeWord(0xffc0); // marker
+
+      writeWord(17); // length, truecolor YUV JPG
+
+      writeByte(8); // precision
+
+      writeWord(height);
+      writeWord(width);
+      writeByte(3); // nrofcomponents
+
+      writeByte(1); // IdY
+
+      writeByte(0x11); // HVY
+
+      writeByte(0); // QTY
+
+      writeByte(2); // IdU
+
+      writeByte(0x11); // HVU
+
+      writeByte(1); // QTU
+
+      writeByte(3); // IdV
+
+      writeByte(0x11); // HVV
+
+      writeByte(1); // QTV
+    }
+
+    function writeDQT() {
+      writeWord(0xffdb); // marker
+
+      writeWord(132); // length
+
+      writeByte(0);
+
+      for (var i = 0; i < 64; i++) {
+        writeByte(YTable[i]);
+      }
+
+      writeByte(1);
+
+      for (var j = 0; j < 64; j++) {
+        writeByte(UVTable[j]);
+      }
+    }
+
+    function writeDHT() {
+      writeWord(0xffc4); // marker
+
+      writeWord(0x01a2); // length
+
+      writeByte(0); // HTYDCinfo
+
+      for (var i = 0; i < 16; i++) {
+        writeByte(std_dc_luminance_nrcodes[i + 1]);
+      }
+
+      for (var j = 0; j <= 11; j++) {
+        writeByte(std_dc_luminance_values[j]);
+      }
+
+      writeByte(0x10); // HTYACinfo
+
+      for (var k = 0; k < 16; k++) {
+        writeByte(std_ac_luminance_nrcodes[k + 1]);
+      }
+
+      for (var l = 0; l <= 161; l++) {
+        writeByte(std_ac_luminance_values[l]);
+      }
+
+      writeByte(1); // HTUDCinfo
+
+      for (var m = 0; m < 16; m++) {
+        writeByte(std_dc_chrominance_nrcodes[m + 1]);
+      }
+
+      for (var n = 0; n <= 11; n++) {
+        writeByte(std_dc_chrominance_values[n]);
+      }
+
+      writeByte(0x11); // HTUACinfo
+
+      for (var o = 0; o < 16; o++) {
+        writeByte(std_ac_chrominance_nrcodes[o + 1]);
+      }
+
+      for (var p = 0; p <= 161; p++) {
+        writeByte(std_ac_chrominance_values[p]);
+      }
+    }
+
+    function writeSOS() {
+      writeWord(0xffda); // marker
+
+      writeWord(12); // length
+
+      writeByte(3); // nrofcomponents
+
+      writeByte(1); // IdY
+
+      writeByte(0); // HTY
+
+      writeByte(2); // IdU
+
+      writeByte(0x11); // HTU
+
+      writeByte(3); // IdV
+
+      writeByte(0x11); // HTV
+
+      writeByte(0); // Ss
+
+      writeByte(0x3f); // Se
+
+      writeByte(0); // Bf
+    }
+
+    function processDU(CDU, fdtbl, DC, HTDC, HTAC) {
+      var EOB = HTAC[0x00];
+      var M16zeroes = HTAC[0xf0];
+      var pos;
+      var I16 = 16;
+      var I63 = 63;
+      var I64 = 64;
+      var DU_DCT = fDCTQuant(CDU, fdtbl); //ZigZag reorder
+
+      for (var j = 0; j < I64; ++j) {
+        DU[ZigZag[j]] = DU_DCT[j];
+      }
+
+      var Diff = DU[0] - DC;
+      DC = DU[0]; //Encode DC
+
+      if (Diff == 0) {
+        writeBits(HTDC[0]); // Diff might be 0
+      } else {
+        pos = 32767 + Diff;
+        writeBits(HTDC[category[pos]]);
+        writeBits(bitcode[pos]);
+      } //Encode ACs
+
+
+      var end0pos = 63; // was const... which is crazy
+
+      while (end0pos > 0 && DU[end0pos] == 0) {
+        end0pos--;
+      } //end0pos = first element in reverse order !=0
+
+
+      if (end0pos == 0) {
+        writeBits(EOB);
+        return DC;
+      }
+
+      var i = 1;
+      var lng;
+
+      while (i <= end0pos) {
+        var startpos = i;
+
+        while (DU[i] == 0 && i <= end0pos) {
+          ++i;
+        }
+
+        var nrzeroes = i - startpos;
+
+        if (nrzeroes >= I16) {
+          lng = nrzeroes >> 4;
+
+          for (var nrmarker = 1; nrmarker <= lng; ++nrmarker) {
+            writeBits(M16zeroes);
+          }
+
+          nrzeroes = nrzeroes & 0xf;
+        }
+
+        pos = 32767 + DU[i];
+        writeBits(HTAC[(nrzeroes << 4) + category[pos]]);
+        writeBits(bitcode[pos]);
+        i++;
+      }
+
+      if (end0pos != I63) {
+        writeBits(EOB);
+      }
+
+      return DC;
+    }
+
+    function initCharLookupTable() {
+      var sfcc = String.fromCharCode;
+
+      for (var i = 0; i < 256; i++) {
+        ///// ACHTUNG // 255
+        clt[i] = sfcc(i);
+      }
+    }
+
+    this.encode = function (image, quality // image data object
+    ) {
+      if (quality) setQuality(quality); // Initialize bit writer
+
+      byteout = new Array();
+      bytenew = 0;
+      bytepos = 7; // Add JPEG headers
+
+      writeWord(0xffd8); // SOI
+
+      writeAPP0();
+      writeDQT();
+      writeSOF0(image.width, image.height);
+      writeDHT();
+      writeSOS(); // Encode 8x8 macroblocks
+
+      var DCY = 0;
+      var DCU = 0;
+      var DCV = 0;
+      bytenew = 0;
+      bytepos = 7;
+      this.encode.displayName = "_encode_";
+      var imageData = image.data;
+      var width = image.width;
+      var height = image.height;
+      var quadWidth = width * 4;
+      var x,
+          y = 0;
+      var r, g, b;
+      var start, p, col, row, pos;
+
+      while (y < height) {
+        x = 0;
+
+        while (x < quadWidth) {
+          start = quadWidth * y + x;
+          col = -1;
+          row = 0;
+
+          for (pos = 0; pos < 64; pos++) {
+            row = pos >> 3; // /8
+
+            col = (pos & 7) * 4; // %8
+
+            p = start + row * quadWidth + col;
+
+            if (y + row >= height) {
+              // padding bottom
+              p -= quadWidth * (y + 1 + row - height);
+            }
+
+            if (x + col >= quadWidth) {
+              // padding right
+              p -= x + col - quadWidth + 4;
+            }
+
+            r = imageData[p++];
+            g = imageData[p++];
+            b = imageData[p++];
+            /* // calculate YUV values dynamically
+            YDU[pos]=((( 0.29900)*r+( 0.58700)*g+( 0.11400)*b))-128; //-0x80
+            UDU[pos]=(((-0.16874)*r+(-0.33126)*g+( 0.50000)*b));
+            VDU[pos]=((( 0.50000)*r+(-0.41869)*g+(-0.08131)*b));
+            */
+            // use lookup table (slightly faster)
+
+            YDU[pos] = (RGB_YUV_TABLE[r] + RGB_YUV_TABLE[g + 256 >> 0] + RGB_YUV_TABLE[b + 512 >> 0] >> 16) - 128;
+            UDU[pos] = (RGB_YUV_TABLE[r + 768 >> 0] + RGB_YUV_TABLE[g + 1024 >> 0] + RGB_YUV_TABLE[b + 1280 >> 0] >> 16) - 128;
+            VDU[pos] = (RGB_YUV_TABLE[r + 1280 >> 0] + RGB_YUV_TABLE[g + 1536 >> 0] + RGB_YUV_TABLE[b + 1792 >> 0] >> 16) - 128;
+          }
+
+          DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
+          DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
+          DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
+          x += 32;
+        }
+
+        y += 8;
+      } ////////////////////////////////////////////////////////////////
+      // Do the bit alignment of the EOI marker
+
+
+      if (bytepos >= 0) {
+        var fillbits = [];
+        fillbits[1] = bytepos + 1;
+        fillbits[0] = (1 << bytepos + 1) - 1;
+        writeBits(fillbits);
+      }
+
+      writeWord(0xffd9); //EOI
+
+      return new Uint8Array(byteout);
+    };
+
+    function setQuality(quality) {
+      quality = Math.min(Math.max(quality, 1), 100);
+      if (currentQuality == quality) return; // don't recalc if unchanged
+
+      var sf = quality < 50 ? Math.floor(5000 / quality) : Math.floor(200 - quality * 2);
+      initQuantTables(sf);
+      currentQuality = quality; //console.log('Quality set to: '+quality +'%');
+    }
+
+    function init() {
+      quality = quality || 50; // Create tables
+
+      initCharLookupTable();
+      initHuffmanTbl();
+      initCategoryNumber();
+      initRGBYUVTable();
+      setQuality(quality);
+    }
+
+    init();
+  }
+
+  /**
+   * @license
+   * Copyright (c) 2017 Aras Abbasi
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+  /**
+   * jsPDF Gif Support PlugIn
+   *
+   * @name gif_support
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+
+    jsPDFAPI.processGIF89A = function (imageData, index, alias, compression) {
+      var reader = new GifReader(imageData);
+      var width = reader.width,
+          height = reader.height;
+      var qu = 100;
+      var pixels = [];
+      reader.decodeAndBlitFrameRGBA(0, pixels);
+      var rawImageData = {
+        data: pixels,
+        width: width,
+        height: height
+      };
+      var encoder = new JPEGEncoder(qu);
+      var data = encoder.encode(rawImageData, qu);
+      return jsPDFAPI.processJPEG.call(this, data, index, alias, compression);
+    };
+
+    jsPDFAPI.processGIF87A = jsPDFAPI.processGIF89A;
+  })(jsPDF.API);
+
+  /**
+   * @author shaozilee
+   *
+   * Bmp format decoder,support 1bit 4bit 8bit 24bit bmp
+   *
+   */
+
+  function BmpDecoder(buffer, is_with_alpha) {
+    this.pos = 0;
+    this.buffer = buffer;
+    this.datav = new DataView(buffer.buffer);
+    this.is_with_alpha = !!is_with_alpha;
+    this.bottom_up = true;
+    this.flag = String.fromCharCode(this.buffer[0]) + String.fromCharCode(this.buffer[1]);
+    this.pos += 2;
+    if (["BM", "BA", "CI", "CP", "IC", "PT"].indexOf(this.flag) === -1) throw new Error("Invalid BMP File");
+    this.parseHeader();
+    this.parseBGR();
+  }
+
+  BmpDecoder.prototype.parseHeader = function () {
+    this.fileSize = this.datav.getUint32(this.pos, true);
+    this.pos += 4;
+    this.reserved = this.datav.getUint32(this.pos, true);
+    this.pos += 4;
+    this.offset = this.datav.getUint32(this.pos, true);
+    this.pos += 4;
+    this.headerSize = this.datav.getUint32(this.pos, true);
+    this.pos += 4;
+    this.width = this.datav.getUint32(this.pos, true);
+    this.pos += 4;
+    this.height = this.datav.getInt32(this.pos, true);
+    this.pos += 4;
+    this.planes = this.datav.getUint16(this.pos, true);
+    this.pos += 2;
+    this.bitPP = this.datav.getUint16(this.pos, true);
+    this.pos += 2;
+    this.compress = this.datav.getUint32(this.pos, true);
+    this.pos += 4;
+    this.rawSize = this.datav.getUint32(this.pos, true);
+    this.pos += 4;
+    this.hr = this.datav.getUint32(this.pos, true);
+    this.pos += 4;
+    this.vr = this.datav.getUint32(this.pos, true);
+    this.pos += 4;
+    this.colors = this.datav.getUint32(this.pos, true);
+    this.pos += 4;
+    this.importantColors = this.datav.getUint32(this.pos, true);
+    this.pos += 4;
+
+    if (this.bitPP === 16 && this.is_with_alpha) {
+      this.bitPP = 15;
+    }
+
+    if (this.bitPP < 15) {
+      var len = this.colors === 0 ? 1 << this.bitPP : this.colors;
+      this.palette = new Array(len);
+
+      for (var i = 0; i < len; i++) {
+        var blue = this.datav.getUint8(this.pos++, true);
+        var green = this.datav.getUint8(this.pos++, true);
+        var red = this.datav.getUint8(this.pos++, true);
+        var quad = this.datav.getUint8(this.pos++, true);
+        this.palette[i] = {
+          red: red,
+          green: green,
+          blue: blue,
+          quad: quad
+        };
+      }
+    }
+
+    if (this.height < 0) {
+      this.height *= -1;
+      this.bottom_up = false;
+    }
+  };
+
+  BmpDecoder.prototype.parseBGR = function () {
+    this.pos = this.offset;
+
+    try {
+      var bitn = "bit" + this.bitPP;
+      var len = this.width * this.height * 4;
+      this.data = new Uint8Array(len);
+      this[bitn]();
+    } catch (e) {
+      console.log("bit decode error:" + e);
+    }
+  };
+
+  BmpDecoder.prototype.bit1 = function () {
+    var xlen = Math.ceil(this.width / 8);
+    var mode = xlen % 4;
+    var y;
+
+    for (y = this.height - 1; y >= 0; y--) {
+      var line = this.bottom_up ? y : this.height - 1 - y;
+
+      for (var x = 0; x < xlen; x++) {
+        var b = this.datav.getUint8(this.pos++, true);
+        var location = line * this.width * 4 + x * 8 * 4;
+
+        for (var i = 0; i < 8; i++) {
+          if (x * 8 + i < this.width) {
+            var rgb = this.palette[b >> 7 - i & 0x1];
+            this.data[location + i * 4] = rgb.blue;
+            this.data[location + i * 4 + 1] = rgb.green;
+            this.data[location + i * 4 + 2] = rgb.red;
+            this.data[location + i * 4 + 3] = 0xff;
+          } else {
+            break;
+          }
+        }
+      }
+
+      if (mode !== 0) {
+        this.pos += 4 - mode;
+      }
+    }
+  };
+
+  BmpDecoder.prototype.bit4 = function () {
+    var xlen = Math.ceil(this.width / 2);
+    var mode = xlen % 4;
+
+    for (var y = this.height - 1; y >= 0; y--) {
+      var line = this.bottom_up ? y : this.height - 1 - y;
+
+      for (var x = 0; x < xlen; x++) {
+        var b = this.datav.getUint8(this.pos++, true);
+        var location = line * this.width * 4 + x * 2 * 4;
+        var before = b >> 4;
+        var after = b & 0x0f;
+        var rgb = this.palette[before];
+        this.data[location] = rgb.blue;
+        this.data[location + 1] = rgb.green;
+        this.data[location + 2] = rgb.red;
+        this.data[location + 3] = 0xff;
+        if (x * 2 + 1 >= this.width) break;
+        rgb = this.palette[after];
+        this.data[location + 4] = rgb.blue;
+        this.data[location + 4 + 1] = rgb.green;
+        this.data[location + 4 + 2] = rgb.red;
+        this.data[location + 4 + 3] = 0xff;
+      }
+
+      if (mode !== 0) {
+        this.pos += 4 - mode;
+      }
+    }
+  };
+
+  BmpDecoder.prototype.bit8 = function () {
+    var mode = this.width % 4;
+
+    for (var y = this.height - 1; y >= 0; y--) {
+      var line = this.bottom_up ? y : this.height - 1 - y;
+
+      for (var x = 0; x < this.width; x++) {
+        var b = this.datav.getUint8(this.pos++, true);
+        var location = line * this.width * 4 + x * 4;
+
+        if (b < this.palette.length) {
+          var rgb = this.palette[b];
+          this.data[location] = rgb.red;
+          this.data[location + 1] = rgb.green;
+          this.data[location + 2] = rgb.blue;
+          this.data[location + 3] = 0xff;
+        } else {
+          this.data[location] = 0xff;
+          this.data[location + 1] = 0xff;
+          this.data[location + 2] = 0xff;
+          this.data[location + 3] = 0xff;
+        }
+      }
+
+      if (mode !== 0) {
+        this.pos += 4 - mode;
+      }
+    }
+  };
+
+  BmpDecoder.prototype.bit15 = function () {
+    var dif_w = this.width % 3;
+
+    var _11111 = parseInt("11111", 2),
+        _1_5 = _11111;
+
+    for (var y = this.height - 1; y >= 0; y--) {
+      var line = this.bottom_up ? y : this.height - 1 - y;
+
+      for (var x = 0; x < this.width; x++) {
+        var B = this.datav.getUint16(this.pos, true);
+        this.pos += 2;
+        var blue = (B & _1_5) / _1_5 * 255 | 0;
+        var green = (B >> 5 & _1_5) / _1_5 * 255 | 0;
+        var red = (B >> 10 & _1_5) / _1_5 * 255 | 0;
+        var alpha = B >> 15 ? 0xff : 0x00;
+        var location = line * this.width * 4 + x * 4;
+        this.data[location] = red;
+        this.data[location + 1] = green;
+        this.data[location + 2] = blue;
+        this.data[location + 3] = alpha;
+      } //skip extra bytes
+
+
+      this.pos += dif_w;
+    }
+  };
+
+  BmpDecoder.prototype.bit16 = function () {
+    var dif_w = this.width % 3;
+
+    var _11111 = parseInt("11111", 2),
+        _1_5 = _11111;
+
+    var _111111 = parseInt("111111", 2),
+        _1_6 = _111111;
+
+    for (var y = this.height - 1; y >= 0; y--) {
+      var line = this.bottom_up ? y : this.height - 1 - y;
+
+      for (var x = 0; x < this.width; x++) {
+        var B = this.datav.getUint16(this.pos, true);
+        this.pos += 2;
+        var alpha = 0xff;
+        var blue = (B & _1_5) / _1_5 * 255 | 0;
+        var green = (B >> 5 & _1_6) / _1_6 * 255 | 0;
+        var red = (B >> 11) / _1_5 * 255 | 0;
+        var location = line * this.width * 4 + x * 4;
+        this.data[location] = red;
+        this.data[location + 1] = green;
+        this.data[location + 2] = blue;
+        this.data[location + 3] = alpha;
+      } //skip extra bytes
+
+
+      this.pos += dif_w;
+    }
+  };
+
+  BmpDecoder.prototype.bit24 = function () {
+    //when height > 0
+    for (var y = this.height - 1; y >= 0; y--) {
+      var line = this.bottom_up ? y : this.height - 1 - y;
+
+      for (var x = 0; x < this.width; x++) {
+        var blue = this.datav.getUint8(this.pos++, true);
+        var green = this.datav.getUint8(this.pos++, true);
+        var red = this.datav.getUint8(this.pos++, true);
+        var location = line * this.width * 4 + x * 4;
+        this.data[location] = red;
+        this.data[location + 1] = green;
+        this.data[location + 2] = blue;
+        this.data[location + 3] = 0xff;
+      } //skip extra bytes
+
+
+      this.pos += this.width % 4;
+    }
+  };
+  /**
+   * add 32bit decode func
+   * @author soubok
+   */
+
+
+  BmpDecoder.prototype.bit32 = function () {
+    //when height > 0
+    for (var y = this.height - 1; y >= 0; y--) {
+      var line = this.bottom_up ? y : this.height - 1 - y;
+
+      for (var x = 0; x < this.width; x++) {
+        var blue = this.datav.getUint8(this.pos++, true);
+        var green = this.datav.getUint8(this.pos++, true);
+        var red = this.datav.getUint8(this.pos++, true);
+        var alpha = this.datav.getUint8(this.pos++, true);
+        var location = line * this.width * 4 + x * 4;
+        this.data[location] = red;
+        this.data[location + 1] = green;
+        this.data[location + 2] = blue;
+        this.data[location + 3] = alpha;
+      } //skip extra bytes
+      //this.pos += (this.width % 4);
+
+    }
+  };
+
+  BmpDecoder.prototype.getData = function () {
+    return this.data;
+  };
+
+  /**
+   * @license
+   * Copyright (c) 2018 Aras Abbasi
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+
+  /**
+   * jsPDF bmp Support PlugIn
+   * @name bmp_support
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+
+    jsPDFAPI.processBMP = function (imageData, index, alias, compression) {
+      var reader = new BmpDecoder(imageData, false);
+      var width = reader.width,
+          height = reader.height;
+      var qu = 100;
+      var pixels = reader.getData();
+      var rawImageData = {
+        data: pixels,
+        width: width,
+        height: height
+      };
+      var encoder = new JPEGEncoder(qu);
+      var data = encoder.encode(rawImageData, qu);
+      return jsPDFAPI.processJPEG.call(this, data, index, alias, compression);
+    };
+  })(jsPDF.API);
+
+  function WebPDecoder(imageData) {
+
+    function x(F) {
+      if (!F) throw Error("assert :P");
+    }
+
+    function fa(F, L, J) {
+      for (var H = 0; 4 > H; H++) {
+        if (F[L + H] != J.charCodeAt(H)) return !0;
+      }
+
+      return !1;
+    }
+
+    function I(F, L, J, H, Z) {
+      for (var O = 0; O < Z; O++) {
+        F[L + O] = J[H + O];
+      }
+    }
+
+    function M(F, L, J, H) {
+      for (var Z = 0; Z < H; Z++) {
+        F[L + Z] = J;
+      }
+    }
+
+    function V(F) {
+      return new Int32Array(F);
+    }
+
+    function wa(F, L) {
+      for (var J = [], H = 0; H < F; H++) {
+        J.push(new L());
+      }
+
+      return J;
+    }
+
+    function wb() {
+      function F(J, H, Z) {
+        for (var O = Z[H], L = 0; L < O; L++) {
+          J.push(Z.length > H + 1 ? [] : 0);
+          if (Z.length < H + 1) break;
+          F(J[L], H + 1, Z);
+        }
+      }
+
+      var L = [];
+      F(L, 0, [3, 11]);
+      return L;
+    }
+
+    function Ed(F, L) {
+      function J(H, O, F) {
+        for (var Z = F[O], ma = 0; ma < Z; ma++) {
+          H.push(F.length > O + 1 ? [] : new L());
+          if (F.length < O + 1) break;
+          J(H[ma], O + 1, F);
+        }
+      }
+
+      var H = [];
+      J(H, 0, F);
+      return H;
+    }
+
+    var _WebPDecoder = function _WebPDecoder() {
+      var self = this;
+
+      function L(a, b) {
+        for (var c = 1 << b - 1 >>> 0; a & c;) {
+          c >>>= 1;
+        }
+
+        return c ? (a & c - 1) + c : a;
+      }
+
+      function J(a, b, c, d, e) {
+        x(!(d % c));
+
+        do {
+          d -= c, a[b + d] = e;
+        } while (0 < d);
+      }
+
+      function H(a, b, c, d, e, f) {
+        var g = b,
+            h = 1 << c,
+            k,
+            l,
+            m = V(16),
+            n = V(16);
+        x(0 != e);
+        x(null != d);
+        x(null != a);
+        x(0 < c);
+
+        for (l = 0; l < e; ++l) {
+          if (15 < d[l]) return 0;
+          ++m[d[l]];
+        }
+
+        if (m[0] == e) return 0;
+        n[1] = 0;
+
+        for (k = 1; 15 > k; ++k) {
+          if (m[k] > 1 << k) return 0;
+          n[k + 1] = n[k] + m[k];
+        }
+
+        for (l = 0; l < e; ++l) {
+          k = d[l], 0 < d[l] && (f[n[k]++] = l);
+        }
+
+        if (1 == n[15]) return d = new O(), d.g = 0, d.value = f[0], J(a, g, 1, h, d), h;
+        var r = -1,
+            q = h - 1,
+            t = 0,
+            v = 1,
+            p = 1,
+            u,
+            w = 1 << c;
+        l = 0;
+        k = 1;
+
+        for (e = 2; k <= c; ++k, e <<= 1) {
+          p <<= 1;
+          v += p;
+          p -= m[k];
+          if (0 > p) return 0;
+
+          for (; 0 < m[k]; --m[k]) {
+            d = new O(), d.g = k, d.value = f[l++], J(a, g + t, e, w, d), t = L(t, k);
+          }
+        }
+
+        k = c + 1;
+
+        for (e = 2; 15 >= k; ++k, e <<= 1) {
+          p <<= 1;
+          v += p;
+          p -= m[k];
+          if (0 > p) return 0;
+
+          for (; 0 < m[k]; --m[k]) {
+            d = new O();
+
+            if ((t & q) != r) {
+              g += w;
+              r = k;
+
+              for (u = 1 << r - c; 15 > r;) {
+                u -= m[r];
+                if (0 >= u) break;
+                ++r;
+                u <<= 1;
+              }
+
+              u = r - c;
+              w = 1 << u;
+              h += w;
+              r = t & q;
+              a[b + r].g = u + c;
+              a[b + r].value = g - b - r;
+            }
+
+            d.g = k - c;
+            d.value = f[l++];
+            J(a, g + (t >> c), e, w, d);
+            t = L(t, k);
+          }
+        }
+
+        return v != 2 * n[15] - 1 ? 0 : h;
+      }
+
+      function Z(a, b, c, d, e) {
+        x(2328 >= e);
+        if (512 >= e) var f = V(512);else if (f = V(e), null == f) return 0;
+        return H(a, b, c, d, e, f);
+      }
+
+      function O() {
+        this.value = this.g = 0;
+      }
+
+      function Fd() {
+        this.value = this.g = 0;
+      }
+
+      function Ub() {
+        this.G = wa(5, O);
+        this.H = V(5);
+        this.jc = this.Qb = this.qb = this.nd = 0;
+        this.pd = wa(xb, Fd);
+      }
+
+      function ma(a, b, c, d) {
+        x(null != a);
+        x(null != b);
+        x(2147483648 > d);
+        a.Ca = 254;
+        a.I = 0;
+        a.b = -8;
+        a.Ka = 0;
+        a.oa = b;
+        a.pa = c;
+        a.Jd = b;
+        a.Yc = c + d;
+        a.Zc = 4 <= d ? c + d - 4 + 1 : c;
+        Qa(a);
+      }
+
+      function na(a, b) {
+        for (var c = 0; 0 < b--;) {
+          c |= K(a, 128) << b;
+        }
+
+        return c;
+      }
+
+      function ca(a, b) {
+        var c = na(a, b);
+        return G(a) ? -c : c;
+      }
+
+      function cb(a, b, c, d) {
+        var e,
+            f = 0;
+        x(null != a);
+        x(null != b);
+        x(4294967288 > d);
+        a.Sb = d;
+        a.Ra = 0;
+        a.u = 0;
+        a.h = 0;
+        4 < d && (d = 4);
+
+        for (e = 0; e < d; ++e) {
+          f += b[c + e] << 8 * e;
+        }
+
+        a.Ra = f;
+        a.bb = d;
+        a.oa = b;
+        a.pa = c;
+      }
+
+      function Vb(a) {
+        for (; 8 <= a.u && a.bb < a.Sb;) {
+          a.Ra >>>= 8, a.Ra += a.oa[a.pa + a.bb] << ob - 8 >>> 0, ++a.bb, a.u -= 8;
+        }
+
+        db(a) && (a.h = 1, a.u = 0);
+      }
+
+      function D(a, b) {
+        x(0 <= b);
+
+        if (!a.h && b <= Gd) {
+          var c = pb(a) & Hd[b];
+          a.u += b;
+          Vb(a);
+          return c;
+        }
+
+        a.h = 1;
+        return a.u = 0;
+      }
+
+      function Wb() {
+        this.b = this.Ca = this.I = 0;
+        this.oa = [];
+        this.pa = 0;
+        this.Jd = [];
+        this.Yc = 0;
+        this.Zc = [];
+        this.Ka = 0;
+      }
+
+      function Ra() {
+        this.Ra = 0;
+        this.oa = [];
+        this.h = this.u = this.bb = this.Sb = this.pa = 0;
+      }
+
+      function pb(a) {
+        return a.Ra >>> (a.u & ob - 1) >>> 0;
+      }
+
+      function db(a) {
+        x(a.bb <= a.Sb);
+        return a.h || a.bb == a.Sb && a.u > ob;
+      }
+
+      function qb(a, b) {
+        a.u = b;
+        a.h = db(a);
+      }
+
+      function Sa(a) {
+        a.u >= Xb && (x(a.u >= Xb), Vb(a));
+      }
+
+      function Qa(a) {
+        x(null != a && null != a.oa);
+        a.pa < a.Zc ? (a.I = (a.oa[a.pa++] | a.I << 8) >>> 0, a.b += 8) : (x(null != a && null != a.oa), a.pa < a.Yc ? (a.b += 8, a.I = a.oa[a.pa++] | a.I << 8) : a.Ka ? a.b = 0 : (a.I <<= 8, a.b += 8, a.Ka = 1));
+      }
+
+      function G(a) {
+        return na(a, 1);
+      }
+
+      function K(a, b) {
+        var c = a.Ca;
+        0 > a.b && Qa(a);
+        var d = a.b,
+            e = c * b >>> 8,
+            f = (a.I >>> d > e) + 0;
+        f ? (c -= e, a.I -= e + 1 << d >>> 0) : c = e + 1;
+        d = c;
+
+        for (e = 0; 256 <= d;) {
+          e += 8, d >>= 8;
+        }
+
+        d = 7 ^ e + Id[d];
+        a.b -= d;
+        a.Ca = (c << d) - 1;
+        return f;
+      }
+
+      function ra(a, b, c) {
+        a[b + 0] = c >> 24 & 255;
+        a[b + 1] = c >> 16 & 255;
+        a[b + 2] = c >> 8 & 255;
+        a[b + 3] = c >> 0 & 255;
+      }
+
+      function Ta(a, b) {
+        return a[b + 0] << 0 | a[b + 1] << 8;
+      }
+
+      function Yb(a, b) {
+        return Ta(a, b) | a[b + 2] << 16;
+      }
+
+      function Ha(a, b) {
+        return Ta(a, b) | Ta(a, b + 2) << 16;
+      }
+
+      function Zb(a, b) {
+        var c = 1 << b;
+        x(null != a);
+        x(0 < b);
+        a.X = V(c);
+        if (null == a.X) return 0;
+        a.Mb = 32 - b;
+        a.Xa = b;
+        return 1;
+      }
+
+      function $b(a, b) {
+        x(null != a);
+        x(null != b);
+        x(a.Xa == b.Xa);
+        I(b.X, 0, a.X, 0, 1 << b.Xa);
+      }
+
+      function ac() {
+        this.X = [];
+        this.Xa = this.Mb = 0;
+      }
+
+      function bc(a, b, c, d) {
+        x(null != c);
+        x(null != d);
+        var e = c[0],
+            f = d[0];
+        0 == e && (e = (a * f + b / 2) / b);
+        0 == f && (f = (b * e + a / 2) / a);
+        if (0 >= e || 0 >= f) return 0;
+        c[0] = e;
+        d[0] = f;
+        return 1;
+      }
+
+      function xa(a, b) {
+        return a + (1 << b) - 1 >>> b;
+      }
+
+      function yb(a, b) {
+        return ((a & 4278255360) + (b & 4278255360) >>> 0 & 4278255360) + ((a & 16711935) + (b & 16711935) >>> 0 & 16711935) >>> 0;
+      }
+
+      function X(a, b) {
+        self[b] = function (b, d, e, f, g, h, k) {
+          var c;
+
+          for (c = 0; c < g; ++c) {
+            var m = self[a](h[k + c - 1], e, f + c);
+            h[k + c] = yb(b[d + c], m);
+          }
+        };
+      }
+
+      function Jd() {
+        this.ud = this.hd = this.jd = 0;
+      }
+
+      function aa(a, b) {
+        return (((a ^ b) & 4278124286) >>> 1) + (a & b) >>> 0;
+      }
+
+      function sa(a) {
+        if (0 <= a && 256 > a) return a;
+        if (0 > a) return 0;
+        if (255 < a) return 255;
+      }
+
+      function eb(a, b) {
+        return sa(a + (a - b + 0.5 >> 1));
+      }
+
+      function Ia(a, b, c) {
+        return Math.abs(b - c) - Math.abs(a - c);
+      }
+
+      function cc(a, b, c, d, e, f, g) {
+        d = f[g - 1];
+
+        for (c = 0; c < e; ++c) {
+          f[g + c] = d = yb(a[b + c], d);
+        }
+      }
+
+      function Kd(a, b, c, d, e) {
+        var f;
+
+        for (f = 0; f < c; ++f) {
+          var g = a[b + f],
+              h = g >> 8 & 255,
+              k = g & 16711935,
+              k = k + ((h << 16) + h),
+              k = k & 16711935;
+          d[e + f] = (g & 4278255360) + k >>> 0;
+        }
+      }
+
+      function dc(a, b) {
+        b.jd = a >> 0 & 255;
+        b.hd = a >> 8 & 255;
+        b.ud = a >> 16 & 255;
+      }
+
+      function Ld(a, b, c, d, e, f) {
+        var g;
+
+        for (g = 0; g < d; ++g) {
+          var h = b[c + g],
+              k = h >>> 8,
+              l = h >>> 16,
+              m = h,
+              l = l + ((a.jd << 24 >> 24) * (k << 24 >> 24) >>> 5),
+              l = l & 255,
+              m = m + ((a.hd << 24 >> 24) * (k << 24 >> 24) >>> 5),
+              m = m + ((a.ud << 24 >> 24) * (l << 24 >> 24) >>> 5),
+              m = m & 255;
+          e[f + g] = (h & 4278255360) + (l << 16) + m;
+        }
+      }
+
+      function ec(a, b, c, d, e) {
+        self[b] = function (a, b, c, k, l, m, n, r, q) {
+          for (k = n; k < r; ++k) {
+            for (n = 0; n < q; ++n) {
+              l[m++] = e(c[d(a[b++])]);
+            }
+          }
+        };
+
+        self[a] = function (a, b, h, k, l, m, n) {
+          var f = 8 >> a.b,
+              g = a.Ea,
+              t = a.K[0],
+              v = a.w;
+          if (8 > f) for (a = (1 << a.b) - 1, v = (1 << f) - 1; b < h; ++b) {
+            var p = 0,
+                u;
+
+            for (u = 0; u < g; ++u) {
+              u & a || (p = d(k[l++])), m[n++] = e(t[p & v]), p >>= f;
+            }
+          } else self["VP8LMapColor" + c](k, l, t, v, m, n, b, h, g);
+        };
+      }
+
+      function Md(a, b, c, d, e) {
+        for (c = b + c; b < c;) {
+          var f = a[b++];
+          d[e++] = f >> 16 & 255;
+          d[e++] = f >> 8 & 255;
+          d[e++] = f >> 0 & 255;
+        }
+      }
+
+      function Nd(a, b, c, d, e) {
+        for (c = b + c; b < c;) {
+          var f = a[b++];
+          d[e++] = f >> 16 & 255;
+          d[e++] = f >> 8 & 255;
+          d[e++] = f >> 0 & 255;
+          d[e++] = f >> 24 & 255;
+        }
+      }
+
+      function Od(a, b, c, d, e) {
+        for (c = b + c; b < c;) {
+          var f = a[b++],
+              g = f >> 16 & 240 | f >> 12 & 15,
+              f = f >> 0 & 240 | f >> 28 & 15;
+          d[e++] = g;
+          d[e++] = f;
+        }
+      }
+
+      function Pd(a, b, c, d, e) {
+        for (c = b + c; b < c;) {
+          var f = a[b++],
+              g = f >> 16 & 248 | f >> 13 & 7,
+              f = f >> 5 & 224 | f >> 3 & 31;
+          d[e++] = g;
+          d[e++] = f;
+        }
+      }
+
+      function Qd(a, b, c, d, e) {
+        for (c = b + c; b < c;) {
+          var f = a[b++];
+          d[e++] = f >> 0 & 255;
+          d[e++] = f >> 8 & 255;
+          d[e++] = f >> 16 & 255;
+        }
+      }
+
+      function fb(a, b, c, d, e, f) {
+        if (0 == f) for (c = b + c; b < c;) {
+          f = a[b++], ra(d, (f[0] >> 24 | f[1] >> 8 & 65280 | f[2] << 8 & 16711680 | f[3] << 24) >>> 0), e += 32;
+        } else I(d, e, a, b, c);
+      }
+
+      function gb(a, b) {
+        self[b][0] = self[a + "0"];
+        self[b][1] = self[a + "1"];
+        self[b][2] = self[a + "2"];
+        self[b][3] = self[a + "3"];
+        self[b][4] = self[a + "4"];
+        self[b][5] = self[a + "5"];
+        self[b][6] = self[a + "6"];
+        self[b][7] = self[a + "7"];
+        self[b][8] = self[a + "8"];
+        self[b][9] = self[a + "9"];
+        self[b][10] = self[a + "10"];
+        self[b][11] = self[a + "11"];
+        self[b][12] = self[a + "12"];
+        self[b][13] = self[a + "13"];
+        self[b][14] = self[a + "0"];
+        self[b][15] = self[a + "0"];
+      }
+
+      function hb(a) {
+        return a == zb || a == Ab || a == Ja || a == Bb;
+      }
+
+      function Rd() {
+        this.eb = [];
+        this.size = this.A = this.fb = 0;
+      }
+
+      function Sd() {
+        this.y = [];
+        this.f = [];
+        this.ea = [];
+        this.F = [];
+        this.Tc = this.Ed = this.Cd = this.Fd = this.lb = this.Db = this.Ab = this.fa = this.J = this.W = this.N = this.O = 0;
+      }
+
+      function Cb() {
+        this.Rd = this.height = this.width = this.S = 0;
+        this.f = {};
+        this.f.RGBA = new Rd();
+        this.f.kb = new Sd();
+        this.sd = null;
+      }
+
+      function Td() {
+        this.width = [0];
+        this.height = [0];
+        this.Pd = [0];
+        this.Qd = [0];
+        this.format = [0];
+      }
+
+      function Ud() {
+        this.Id = this.fd = this.Md = this.hb = this.ib = this.da = this.bd = this.cd = this.j = this.v = this.Da = this.Sd = this.ob = 0;
+      }
+
+      function Vd(a) {
+        alert("todo:WebPSamplerProcessPlane");
+        return a.T;
+      }
+
+      function Wd(a, b) {
+        var c = a.T,
+            d = b.ba.f.RGBA,
+            e = d.eb,
+            f = d.fb + a.ka * d.A,
+            g = P[b.ba.S],
+            h = a.y,
+            k = a.O,
+            l = a.f,
+            m = a.N,
+            n = a.ea,
+            r = a.W,
+            q = b.cc,
+            t = b.dc,
+            v = b.Mc,
+            p = b.Nc,
+            u = a.ka,
+            w = a.ka + a.T,
+            y = a.U,
+            A = y + 1 >> 1;
+        0 == u ? g(h, k, null, null, l, m, n, r, l, m, n, r, e, f, null, null, y) : (g(b.ec, b.fc, h, k, q, t, v, p, l, m, n, r, e, f - d.A, e, f, y), ++c);
+
+        for (; u + 2 < w; u += 2) {
+          q = l, t = m, v = n, p = r, m += a.Rc, r += a.Rc, f += 2 * d.A, k += 2 * a.fa, g(h, k - a.fa, h, k, q, t, v, p, l, m, n, r, e, f - d.A, e, f, y);
+        }
+
+        k += a.fa;
+        a.j + w < a.o ? (I(b.ec, b.fc, h, k, y), I(b.cc, b.dc, l, m, A), I(b.Mc, b.Nc, n, r, A), c--) : w & 1 || g(h, k, null, null, l, m, n, r, l, m, n, r, e, f + d.A, null, null, y);
+        return c;
+      }
+
+      function Xd(a, b, c) {
+        var d = a.F,
+            e = [a.J];
+
+        if (null != d) {
+          var f = a.U,
+              g = b.ba.S,
+              h = g == ya || g == Ja;
+          b = b.ba.f.RGBA;
+          var k = [0],
+              l = a.ka;
+          k[0] = a.T;
+          a.Kb && (0 == l ? --k[0] : (--l, e[0] -= a.width), a.j + a.ka + a.T == a.o && (k[0] = a.o - a.j - l));
+          var m = b.eb,
+              l = b.fb + l * b.A;
+          a = fc(d, e[0], a.width, f, k, m, l + (h ? 0 : 3), b.A);
+          x(c == k);
+          a && hb(g) && za(m, l, h, f, k, b.A);
+        }
+
+        return 0;
+      }
+
+      function gc(a) {
+        var b = a.ma,
+            c = b.ba.S,
+            d = 11 > c,
+            e = c == Ua || c == Va || c == ya || c == Db || 12 == c || hb(c);
+        b.memory = null;
+        b.Ib = null;
+        b.Jb = null;
+        b.Nd = null;
+        if (!hc(b.Oa, a, e ? 11 : 12)) return 0;
+        e && hb(c) && ic();
+        if (a.da) alert("todo:use_scaling");else {
+          if (d) {
+            if (b.Ib = Vd, a.Kb) {
+              c = a.U + 1 >> 1;
+              b.memory = V(a.U + 2 * c);
+              if (null == b.memory) return 0;
+              b.ec = b.memory;
+              b.fc = 0;
+              b.cc = b.ec;
+              b.dc = b.fc + a.U;
+              b.Mc = b.cc;
+              b.Nc = b.dc + c;
+              b.Ib = Wd;
+              ic();
+            }
+          } else alert("todo:EmitYUV");
+
+          e && (b.Jb = Xd, d && Aa());
+        }
+
+        if (d && !jc) {
+          for (a = 0; 256 > a; ++a) {
+            Yd[a] = 89858 * (a - 128) + Ba >> Wa, Zd[a] = -22014 * (a - 128) + Ba, $d[a] = -45773 * (a - 128), ae[a] = 113618 * (a - 128) + Ba >> Wa;
+          }
+
+          for (a = ta; a < Eb; ++a) {
+            b = 76283 * (a - 16) + Ba >> Wa, be[a - ta] = ga(b, 255), ce[a - ta] = ga(b + 8 >> 4, 15);
+          }
+
+          jc = 1;
+        }
+
+        return 1;
+      }
+
+      function kc(a) {
+        var b = a.ma,
+            c = a.U,
+            d = a.T;
+        x(!(a.ka & 1));
+        if (0 >= c || 0 >= d) return 0;
+        c = b.Ib(a, b);
+        null != b.Jb && b.Jb(a, b, c);
+        b.Dc += c;
+        return 1;
+      }
+
+      function lc(a) {
+        a.ma.memory = null;
+      }
+
+      function mc(a, b, c, d) {
+        if (47 != D(a, 8)) return 0;
+        b[0] = D(a, 14) + 1;
+        c[0] = D(a, 14) + 1;
+        d[0] = D(a, 1);
+        return 0 != D(a, 3) ? 0 : !a.h;
+      }
+
+      function ib(a, b) {
+        if (4 > a) return a + 1;
+        var c = a - 2 >> 1;
+        return (2 + (a & 1) << c) + D(b, c) + 1;
+      }
+
+      function nc(a, b) {
+        if (120 < b) return b - 120;
+        var c = de[b - 1],
+            c = (c >> 4) * a + (8 - (c & 15));
+        return 1 <= c ? c : 1;
+      }
+
+      function ua(a, b, c) {
+        var d = pb(c);
+        b += d & 255;
+        var e = a[b].g - 8;
+        0 < e && (qb(c, c.u + 8), d = pb(c), b += a[b].value, b += d & (1 << e) - 1);
+        qb(c, c.u + a[b].g);
+        return a[b].value;
+      }
+
+      function ub(a, b, c) {
+        c.g += a.g;
+        c.value += a.value << b >>> 0;
+        x(8 >= c.g);
+        return a.g;
+      }
+
+      function ha(a, b, c) {
+        var d = a.xc;
+        b = 0 == d ? 0 : a.vc[a.md * (c >> d) + (b >> d)];
+        x(b < a.Wb);
+        return a.Ya[b];
+      }
+
+      function oc(a, b, c, d) {
+        var e = a.ab,
+            f = a.c * b,
+            g = a.C;
+        b = g + b;
+        var h = c,
+            k = d;
+        d = a.Ta;
+
+        for (c = a.Ua; 0 < e--;) {
+          var l = a.gc[e],
+              m = g,
+              n = b,
+              r = h,
+              q = k,
+              k = d,
+              h = c,
+              t = l.Ea;
+          x(m < n);
+          x(n <= l.nc);
+
+          switch (l.hc) {
+            case 2:
+              pc(r, q, (n - m) * t, k, h);
+              break;
+
+            case 0:
+              var v = l,
+                  p = m,
+                  u = n,
+                  w = k,
+                  y = h,
+                  A = v.Ea;
+              0 == p && (ee(r, q, null, null, 1, w, y), cc(r, q + 1, 0, 0, A - 1, w, y + 1), q += A, y += A, ++p);
+
+              for (var E = 1 << v.b, B = E - 1, C = xa(A, v.b), N = v.K, v = v.w + (p >> v.b) * C; p < u;) {
+                var z = N,
+                    Q = v,
+                    S = 1;
+
+                for (fe(r, q, w, y - A, 1, w, y); S < A;) {
+                  var K = qc[z[Q++] >> 8 & 15],
+                      D = (S & ~B) + E;
+                  D > A && (D = A);
+                  K(r, q + +S, w, y + S - A, D - S, w, y + S);
+                  S = D;
+                }
+
+                q += A;
+                y += A;
+                ++p;
+                p & B || (v += C);
+              }
+
+              n != l.nc && I(k, h - t, k, h + (n - m - 1) * t, t);
+              break;
+
+            case 1:
+              t = r;
+              u = q;
+              r = l.Ea;
+              q = 1 << l.b;
+              w = q - 1;
+              y = r & ~w;
+              A = r - y;
+              p = xa(r, l.b);
+              E = l.K;
+
+              for (l = l.w + (m >> l.b) * p; m < n;) {
+                B = E;
+                C = l;
+                N = new Jd();
+                v = u + y;
+
+                for (z = u + r; u < v;) {
+                  dc(B[C++], N), Fb(N, t, u, q, k, h), u += q, h += q;
+                }
+
+                u < z && (dc(B[C++], N), Fb(N, t, u, A, k, h), u += A, h += A);
+                ++m;
+                m & w || (l += p);
+              }
+
+              break;
+
+            case 3:
+              if (r == k && q == h && 0 < l.b) {
+                y = (n - m) * xa(l.Ea, l.b);
+                t = h + (n - m) * t - y;
+                u = k;
+                r = t;
+                q = k;
+                w = h;
+                A = y;
+                p = [];
+
+                for (y = A - 1; 0 <= y; --y) {
+                  p[y] = q[w + y];
+                }
+
+                for (y = A - 1; 0 <= y; --y) {
+                  u[r + y] = p[y];
+                }
+
+                rc(l, m, n, k, t, k, h);
+              } else rc(l, m, n, r, q, k, h);
+
+          }
+
+          h = d;
+          k = c;
+        }
+
+        k != c && I(d, c, h, k, f);
+      }
+
+      function ge(a, b) {
+        var c = a.V,
+            d = a.Ba + a.c * a.C,
+            e = b - a.C;
+        x(b <= a.l.o);
+        x(16 >= e);
+
+        if (0 < e) {
+          var f = a.l,
+              g = a.Ta,
+              h = a.Ua,
+              k = f.width;
+          oc(a, e, c, d);
+          h = [h];
+          c = a.C;
+          d = b;
+          e = h;
+          x(c < d);
+          x(f.v < f.va);
+          d > f.o && (d = f.o);
+
+          if (c < f.j) {
+            var l = f.j - c,
+                c = f.j;
+            e[0] += l * k;
+          }
+
+          c >= d ? c = 0 : (e[0] += 4 * f.v, f.ka = c - f.j, f.U = f.va - f.v, f.T = d - c, c = 1);
+
+          if (c) {
+            h = h[0];
+            c = a.ca;
+
+            if (11 > c.S) {
+              for (var m = c.f.RGBA, d = c.S, e = f.U, f = f.T, l = m.eb, n = m.A, r = f, m = m.fb + a.Ma * m.A; 0 < r--;) {
+                var q = g,
+                    t = h,
+                    v = e,
+                    p = l,
+                    u = m;
+
+                switch (d) {
+                  case Ca:
+                    sc(q, t, v, p, u);
+                    break;
+
+                  case Ua:
+                    Gb(q, t, v, p, u);
+                    break;
+
+                  case zb:
+                    Gb(q, t, v, p, u);
+                    za(p, u, 0, v, 1, 0);
+                    break;
+
+                  case tc:
+                    uc(q, t, v, p, u);
+                    break;
+
+                  case Va:
+                    fb(q, t, v, p, u, 1);
+                    break;
+
+                  case Ab:
+                    fb(q, t, v, p, u, 1);
+                    za(p, u, 0, v, 1, 0);
+                    break;
+
+                  case ya:
+                    fb(q, t, v, p, u, 0);
+                    break;
+
+                  case Ja:
+                    fb(q, t, v, p, u, 0);
+                    za(p, u, 1, v, 1, 0);
+                    break;
+
+                  case Db:
+                    Hb(q, t, v, p, u);
+                    break;
+
+                  case Bb:
+                    Hb(q, t, v, p, u);
+                    vc(p, u, v, 1, 0);
+                    break;
+
+                  case wc:
+                    xc(q, t, v, p, u);
+                    break;
+
+                  default:
+                    x(0);
+                }
+
+                h += k;
+                m += n;
+              }
+
+              a.Ma += f;
+            } else alert("todo:EmitRescaledRowsYUVA");
+
+            x(a.Ma <= c.height);
+          }
+        }
+
+        a.C = b;
+        x(a.C <= a.i);
+      }
+
+      function yc(a) {
+        var b;
+        if (0 < a.ua) return 0;
+
+        for (b = 0; b < a.Wb; ++b) {
+          var c = a.Ya[b].G,
+              d = a.Ya[b].H;
+          if (0 < c[1][d[1] + 0].g || 0 < c[2][d[2] + 0].g || 0 < c[3][d[3] + 0].g) return 0;
+        }
+
+        return 1;
+      }
+
+      function zc(a, b, c, d, e, f) {
+        if (0 != a.Z) {
+          var g = a.qd,
+              h = a.rd;
+
+          for (x(null != ia[a.Z]); b < c; ++b) {
+            ia[a.Z](g, h, d, e, d, e, f), g = d, h = e, e += f;
+          }
+
+          a.qd = g;
+          a.rd = h;
+        }
+      }
+
+      function Ib(a, b) {
+        var c = a.l.ma,
+            d = 0 == c.Z || 1 == c.Z ? a.l.j : a.C,
+            d = a.C < d ? d : a.C;
+        x(b <= a.l.o);
+
+        if (b > d) {
+          var e = a.l.width,
+              f = c.ca,
+              g = c.tb + e * d,
+              h = a.V,
+              k = a.Ba + a.c * d,
+              l = a.gc;
+          x(1 == a.ab);
+          x(3 == l[0].hc);
+          he(l[0], d, b, h, k, f, g);
+          zc(c, d, b, f, g, e);
+        }
+
+        a.C = a.Ma = b;
+      }
+
+      function Jb(a, b, c, d, e, f, g) {
+        var h = a.$ / d,
+            k = a.$ % d,
+            l = a.m,
+            m = a.s,
+            n = c + a.$,
+            r = n;
+        e = c + d * e;
+        var q = c + d * f,
+            t = 280 + m.ua,
+            v = a.Pb ? h : 16777216,
+            p = 0 < m.ua ? m.Wa : null,
+            u = m.wc,
+            w = n < q ? ha(m, k, h) : null;
+        x(a.C < f);
+        x(q <= e);
+        var y = !1;
+
+        a: for (;;) {
+          for (; y || n < q;) {
+            var A = 0;
+
+            if (h >= v) {
+              var v = a,
+                  E = n - c;
+              x(v.Pb);
+              v.wd = v.m;
+              v.xd = E;
+              0 < v.s.ua && $b(v.s.Wa, v.s.vb);
+              v = h + ie;
+            }
+
+            k & u || (w = ha(m, k, h));
+            x(null != w);
+            w.Qb && (b[n] = w.qb, y = !0);
+            if (!y) if (Sa(l), w.jc) {
+              var A = l,
+                  E = b,
+                  B = n,
+                  C = w.pd[pb(A) & xb - 1];
+              x(w.jc);
+              256 > C.g ? (qb(A, A.u + C.g), E[B] = C.value, A = 0) : (qb(A, A.u + C.g - 256), x(256 <= C.value), A = C.value);
+              0 == A && (y = !0);
+            } else A = ua(w.G[0], w.H[0], l);
+            if (l.h) break;
+
+            if (y || 256 > A) {
+              if (!y) if (w.nd) b[n] = (w.qb | A << 8) >>> 0;else {
+                Sa(l);
+                y = ua(w.G[1], w.H[1], l);
+                Sa(l);
+                E = ua(w.G[2], w.H[2], l);
+                B = ua(w.G[3], w.H[3], l);
+                if (l.h) break;
+                b[n] = (B << 24 | y << 16 | A << 8 | E) >>> 0;
+              }
+              y = !1;
+              ++n;
+              ++k;
+              if (k >= d && (k = 0, ++h, null != g && h <= f && !(h % 16) && g(a, h), null != p)) for (; r < n;) {
+                A = b[r++], p.X[(506832829 * A & 4294967295) >>> p.Mb] = A;
+              }
+            } else if (280 > A) {
+              A = ib(A - 256, l);
+              E = ua(w.G[4], w.H[4], l);
+              Sa(l);
+              E = ib(E, l);
+              E = nc(d, E);
+              if (l.h) break;
+              if (n - c < E || e - n < A) break a;else for (B = 0; B < A; ++B) {
+                b[n + B] = b[n + B - E];
+              }
+              n += A;
+
+              for (k += A; k >= d;) {
+                k -= d, ++h, null != g && h <= f && !(h % 16) && g(a, h);
+              }
+
+              x(n <= e);
+              k & u && (w = ha(m, k, h));
+              if (null != p) for (; r < n;) {
+                A = b[r++], p.X[(506832829 * A & 4294967295) >>> p.Mb] = A;
+              }
+            } else if (A < t) {
+              y = A - 280;
+
+              for (x(null != p); r < n;) {
+                A = b[r++], p.X[(506832829 * A & 4294967295) >>> p.Mb] = A;
+              }
+
+              A = n;
+              E = p;
+              x(!(y >>> E.Xa));
+              b[A] = E.X[y];
+              y = !0;
+            } else break a;
+
+            y || x(l.h == db(l));
+          }
+
+          if (a.Pb && l.h && n < e) x(a.m.h), a.a = 5, a.m = a.wd, a.$ = a.xd, 0 < a.s.ua && $b(a.s.vb, a.s.Wa);else if (l.h) break a;else null != g && g(a, h > f ? f : h), a.a = 0, a.$ = n - c;
+          return 1;
+        }
+
+        a.a = 3;
+        return 0;
+      }
+
+      function Ac(a) {
+        x(null != a);
+        a.vc = null;
+        a.yc = null;
+        a.Ya = null;
+        var b = a.Wa;
+        null != b && (b.X = null);
+        a.vb = null;
+        x(null != a);
+      }
+
+      function Bc() {
+        var a = new je();
+        if (null == a) return null;
+        a.a = 0;
+        a.xb = Cc;
+        gb("Predictor", "VP8LPredictors");
+        gb("Predictor", "VP8LPredictors_C");
+        gb("PredictorAdd", "VP8LPredictorsAdd");
+        gb("PredictorAdd", "VP8LPredictorsAdd_C");
+        pc = Kd;
+        Fb = Ld;
+        sc = Md;
+        Gb = Nd;
+        Hb = Od;
+        xc = Pd;
+        uc = Qd;
+        self.VP8LMapColor32b = ke;
+        self.VP8LMapColor8b = le;
+        return a;
+      }
+
+      function rb(a, b, c, d, e) {
+        var f = 1,
+            g = [a],
+            h = [b],
+            k = d.m,
+            l = d.s,
+            m = null,
+            n = 0;
+
+        a: for (;;) {
+          if (c) for (; f && D(k, 1);) {
+            var r = g,
+                q = h,
+                t = d,
+                v = 1,
+                p = t.m,
+                u = t.gc[t.ab],
+                w = D(p, 2);
+            if (t.Oc & 1 << w) f = 0;else {
+              t.Oc |= 1 << w;
+              u.hc = w;
+              u.Ea = r[0];
+              u.nc = q[0];
+              u.K = [null];
+              ++t.ab;
+              x(4 >= t.ab);
+
+              switch (w) {
+                case 0:
+                case 1:
+                  u.b = D(p, 3) + 2;
+                  v = rb(xa(u.Ea, u.b), xa(u.nc, u.b), 0, t, u.K);
+                  u.K = u.K[0];
+                  break;
+
+                case 3:
+                  var y = D(p, 8) + 1,
+                      A = 16 < y ? 0 : 4 < y ? 1 : 2 < y ? 2 : 3;
+                  r[0] = xa(u.Ea, A);
+                  u.b = A;
+                  var v = rb(y, 1, 0, t, u.K),
+                      E;
+
+                  if (E = v) {
+                    var B,
+                        C = y,
+                        N = u,
+                        z = 1 << (8 >> N.b),
+                        Q = V(z);
+                    if (null == Q) E = 0;else {
+                      var S = N.K[0],
+                          K = N.w;
+                      Q[0] = N.K[0][0];
+
+                      for (B = 1; B < 1 * C; ++B) {
+                        Q[B] = yb(S[K + B], Q[B - 1]);
+                      }
+
+                      for (; B < 4 * z; ++B) {
+                        Q[B] = 0;
+                      }
+
+                      N.K[0] = null;
+                      N.K[0] = Q;
+                      E = 1;
+                    }
+                  }
+
+                  v = E;
+                  break;
+
+                case 2:
+                  break;
+
+                default:
+                  x(0);
+              }
+
+              f = v;
+            }
+          }
+          g = g[0];
+          h = h[0];
+
+          if (f && D(k, 1) && (n = D(k, 4), f = 1 <= n && 11 >= n, !f)) {
+            d.a = 3;
+            break a;
+          }
+
+          var H;
+          if (H = f) b: {
+            var F = d,
+                G = g,
+                L = h,
+                J = n,
+                T = c,
+                Da,
+                ba,
+                X = F.m,
+                R = F.s,
+                P = [null],
+                U,
+                W = 1,
+                aa = 0,
+                na = me[J];
+
+            c: for (;;) {
+              if (T && D(X, 1)) {
+                var ca = D(X, 3) + 2,
+                    ga = xa(G, ca),
+                    ka = xa(L, ca),
+                    qa = ga * ka;
+                if (!rb(ga, ka, 0, F, P)) break c;
+                P = P[0];
+                R.xc = ca;
+
+                for (Da = 0; Da < qa; ++Da) {
+                  var ia = P[Da] >> 8 & 65535;
+                  P[Da] = ia;
+                  ia >= W && (W = ia + 1);
+                }
+              }
+
+              if (X.h) break c;
+
+              for (ba = 0; 5 > ba; ++ba) {
+                var Y = Dc[ba];
+                !ba && 0 < J && (Y += 1 << J);
+                aa < Y && (aa = Y);
+              }
+
+              var ma = wa(W * na, O);
+              var ua = W,
+                  va = wa(ua, Ub);
+              if (null == va) var la = null;else x(65536 >= ua), la = va;
+              var ha = V(aa);
+
+              if (null == la || null == ha || null == ma) {
+                F.a = 1;
+                break c;
+              }
+
+              var pa = ma;
+
+              for (Da = U = 0; Da < W; ++Da) {
+                var ja = la[Da],
+                    da = ja.G,
+                    ea = ja.H,
+                    Fa = 0,
+                    ra = 1,
+                    Ha = 0;
+
+                for (ba = 0; 5 > ba; ++ba) {
+                  Y = Dc[ba];
+                  da[ba] = pa;
+                  ea[ba] = U;
+                  !ba && 0 < J && (Y += 1 << J);
+
+                  d: {
+                    var sa,
+                        za = Y,
+                        ta = F,
+                        oa = ha,
+                        db = pa,
+                        eb = U,
+                        Ia = 0,
+                        Ka = ta.m,
+                        fb = D(Ka, 1);
+                    M(oa, 0, 0, za);
+
+                    if (fb) {
+                      var gb = D(Ka, 1) + 1,
+                          hb = D(Ka, 1),
+                          Ja = D(Ka, 0 == hb ? 1 : 8);
+                      oa[Ja] = 1;
+                      2 == gb && (Ja = D(Ka, 8), oa[Ja] = 1);
+                      var ya = 1;
+                    } else {
+                      var Ua = V(19),
+                          Va = D(Ka, 4) + 4;
+
+                      if (19 < Va) {
+                        ta.a = 3;
+                        var Aa = 0;
+                        break d;
+                      }
+
+                      for (sa = 0; sa < Va; ++sa) {
+                        Ua[ne[sa]] = D(Ka, 3);
+                      }
+
+                      var Ba = void 0,
+                          sb = void 0,
+                          Wa = ta,
+                          ib = Ua,
+                          Ca = za,
+                          Xa = oa,
+                          Oa = 0,
+                          La = Wa.m,
+                          Ya = 8,
+                          Za = wa(128, O);
+
+                      e: for (;;) {
+                        if (!Z(Za, 0, 7, ib, 19)) break e;
+
+                        if (D(La, 1)) {
+                          var kb = 2 + 2 * D(La, 3),
+                              Ba = 2 + D(La, kb);
+                          if (Ba > Ca) break e;
+                        } else Ba = Ca;
+
+                        for (sb = 0; sb < Ca && Ba--;) {
+                          Sa(La);
+                          var $a = Za[0 + (pb(La) & 127)];
+                          qb(La, La.u + $a.g);
+                          var jb = $a.value;
+                          if (16 > jb) Xa[sb++] = jb, 0 != jb && (Ya = jb);else {
+                            var lb = 16 == jb,
+                                ab = jb - 16,
+                                mb = oe[ab],
+                                bb = D(La, pe[ab]) + mb;
+                            if (sb + bb > Ca) break e;else for (var nb = lb ? Ya : 0; 0 < bb--;) {
+                              Xa[sb++] = nb;
+                            }
+                          }
+                        }
+
+                        Oa = 1;
+                        break e;
+                      }
+
+                      Oa || (Wa.a = 3);
+                      ya = Oa;
+                    }
+
+                    (ya = ya && !Ka.h) && (Ia = Z(db, eb, 8, oa, za));
+                    ya && 0 != Ia ? Aa = Ia : (ta.a = 3, Aa = 0);
+                  }
+
+                  if (0 == Aa) break c;
+                  ra && 1 == qe[ba] && (ra = 0 == pa[U].g);
+                  Fa += pa[U].g;
+                  U += Aa;
+
+                  if (3 >= ba) {
+                    var Pa = ha[0],
+                        tb;
+
+                    for (tb = 1; tb < Y; ++tb) {
+                      ha[tb] > Pa && (Pa = ha[tb]);
+                    }
+
+                    Ha += Pa;
+                  }
+                }
+
+                ja.nd = ra;
+                ja.Qb = 0;
+                ra && (ja.qb = (da[3][ea[3] + 0].value << 24 | da[1][ea[1] + 0].value << 16 | da[2][ea[2] + 0].value) >>> 0, 0 == Fa && 256 > da[0][ea[0] + 0].value && (ja.Qb = 1, ja.qb += da[0][ea[0] + 0].value << 8));
+                ja.jc = !ja.Qb && 6 > Ha;
+
+                if (ja.jc) {
+                  var Ga,
+                      Ea = ja;
+
+                  for (Ga = 0; Ga < xb; ++Ga) {
+                    var Ma = Ga,
+                        Na = Ea.pd[Ma],
+                        vb = Ea.G[0][Ea.H[0] + Ma];
+                    256 <= vb.value ? (Na.g = vb.g + 256, Na.value = vb.value) : (Na.g = 0, Na.value = 0, Ma >>= ub(vb, 8, Na), Ma >>= ub(Ea.G[1][Ea.H[1] + Ma], 16, Na), Ma >>= ub(Ea.G[2][Ea.H[2] + Ma], 0, Na), ub(Ea.G[3][Ea.H[3] + Ma], 24, Na));
+                  }
+                }
+              }
+
+              R.vc = P;
+              R.Wb = W;
+              R.Ya = la;
+              R.yc = ma;
+              H = 1;
+              break b;
+            }
+
+            H = 0;
+          }
+          f = H;
+
+          if (!f) {
+            d.a = 3;
+            break a;
+          }
+
+          if (0 < n) {
+            if (l.ua = 1 << n, !Zb(l.Wa, n)) {
+              d.a = 1;
+              f = 0;
+              break a;
+            }
+          } else l.ua = 0;
+
+          var Qa = d,
+              cb = g,
+              ob = h,
+              Ra = Qa.s,
+              Ta = Ra.xc;
+          Qa.c = cb;
+          Qa.i = ob;
+          Ra.md = xa(cb, Ta);
+          Ra.wc = 0 == Ta ? -1 : (1 << Ta) - 1;
+
+          if (c) {
+            d.xb = re;
+            break a;
+          }
+
+          m = V(g * h);
+
+          if (null == m) {
+            d.a = 1;
+            f = 0;
+            break a;
+          }
+
+          f = (f = Jb(d, m, 0, g, h, h, null)) && !k.h;
+          break a;
+        }
+
+        f ? (null != e ? e[0] = m : (x(null == m), x(c)), d.$ = 0, c || Ac(l)) : Ac(l);
+        return f;
+      }
+
+      function Ec(a, b) {
+        var c = a.c * a.i,
+            d = c + b + 16 * b;
+        x(a.c <= b);
+        a.V = V(d);
+        if (null == a.V) return a.Ta = null, a.Ua = 0, a.a = 1, 0;
+        a.Ta = a.V;
+        a.Ua = a.Ba + c + b;
+        return 1;
+      }
+
+      function se(a, b) {
+        var c = a.C,
+            d = b - c,
+            e = a.V,
+            f = a.Ba + a.c * c;
+
+        for (x(b <= a.l.o); 0 < d;) {
+          var g = 16 < d ? 16 : d,
+              h = a.l.ma,
+              k = a.l.width,
+              l = k * g,
+              m = h.ca,
+              n = h.tb + k * c,
+              r = a.Ta,
+              q = a.Ua;
+          oc(a, g, e, f);
+          Fc(r, q, m, n, l);
+          zc(h, c, c + g, m, n, k);
+          d -= g;
+          e += g * a.c;
+          c += g;
+        }
+
+        x(c == b);
+        a.C = a.Ma = b;
+      }
+
+      function te(a, b) {
+        var c = [0],
+            d = [0],
+            e = [0];
+
+        a: for (;;) {
+          if (null == a) return 0;
+          if (null == b) return a.a = 2, 0;
+          a.l = b;
+          a.a = 0;
+          cb(a.m, b.data, b.w, b.ha);
+
+          if (!mc(a.m, c, d, e)) {
+            a.a = 3;
+            break a;
+          }
+
+          a.xb = Cc;
+          b.width = c[0];
+          b.height = d[0];
+          if (!rb(c[0], d[0], 1, a, null)) break a;
+          return 1;
+        }
+
+        x(0 != a.a);
+        return 0;
+      }
+
+      function ue() {
+        this.ub = this.yd = this.td = this.Rb = 0;
+      }
+
+      function ve() {
+        this.Kd = this.Ld = this.Ud = this.Td = this.i = this.c = 0;
+      }
+
+      function we() {
+        this.Fb = this.Bb = this.Cb = 0;
+        this.Zb = V(4);
+        this.Lb = V(4);
+      }
+
+      function Gc() {
+        this.Yb = wb();
+      }
+
+      function xe() {
+        this.jb = V(3);
+        this.Wc = Ed([4, 8], Gc);
+        this.Xc = Ed([4, 17], Gc);
+      }
+
+      function ye() {
+        this.Pc = this.wb = this.Tb = this.zd = 0;
+        this.vd = new V(4);
+        this.od = new V(4);
+      }
+
+      function Xa() {
+        this.ld = this.La = this.dd = this.tc = 0;
+      }
+
+      function Hc() {
+        this.Na = this.la = 0;
+      }
+
+      function ze() {
+        this.Sc = [0, 0];
+        this.Eb = [0, 0];
+        this.Qc = [0, 0];
+        this.ia = this.lc = 0;
+      }
+
+      function Kb() {
+        this.ad = V(384);
+        this.Za = 0;
+        this.Ob = V(16);
+        this.$b = this.Ad = this.ia = this.Gc = this.Hc = this.Dd = 0;
+      }
+
+      function Ae() {
+        this.uc = this.M = this.Nb = 0;
+        this.wa = Array(new Xa());
+        this.Y = 0;
+        this.ya = Array(new Kb());
+        this.aa = 0;
+        this.l = new Oa();
+      }
+
+      function Ic() {
+        this.y = V(16);
+        this.f = V(8);
+        this.ea = V(8);
+      }
+
+      function Be() {
+        this.cb = this.a = 0;
+        this.sc = "";
+        this.m = new Wb();
+        this.Od = new ue();
+        this.Kc = new ve();
+        this.ed = new ye();
+        this.Qa = new we();
+        this.Ic = this.$c = this.Aa = 0;
+        this.D = new Ae();
+        this.Xb = this.Va = this.Hb = this.zb = this.yb = this.Ub = this.za = 0;
+        this.Jc = wa(8, Wb);
+        this.ia = 0;
+        this.pb = wa(4, ze);
+        this.Pa = new xe();
+        this.Bd = this.kc = 0;
+        this.Ac = [];
+        this.Bc = 0;
+        this.zc = [0, 0, 0, 0];
+        this.Gd = Array(new Ic());
+        this.Hd = 0;
+        this.rb = Array(new Hc());
+        this.sb = 0;
+        this.wa = Array(new Xa());
+        this.Y = 0;
+        this.oc = [];
+        this.pc = 0;
+        this.sa = [];
+        this.ta = 0;
+        this.qa = [];
+        this.ra = 0;
+        this.Ha = [];
+        this.B = this.R = this.Ia = 0;
+        this.Ec = [];
+        this.M = this.ja = this.Vb = this.Fc = 0;
+        this.ya = Array(new Kb());
+        this.L = this.aa = 0;
+        this.gd = Ed([4, 2], Xa);
+        this.ga = null;
+        this.Fa = [];
+        this.Cc = this.qc = this.P = 0;
+        this.Gb = [];
+        this.Uc = 0;
+        this.mb = [];
+        this.nb = 0;
+        this.rc = [];
+        this.Ga = this.Vc = 0;
+      }
+
+      function ga(a, b) {
+        return 0 > a ? 0 : a > b ? b : a;
+      }
+
+      function Oa() {
+        this.T = this.U = this.ka = this.height = this.width = 0;
+        this.y = [];
+        this.f = [];
+        this.ea = [];
+        this.Rc = this.fa = this.W = this.N = this.O = 0;
+        this.ma = "void";
+        this.put = "VP8IoPutHook";
+        this.ac = "VP8IoSetupHook";
+        this.bc = "VP8IoTeardownHook";
+        this.ha = this.Kb = 0;
+        this.data = [];
+        this.hb = this.ib = this.da = this.o = this.j = this.va = this.v = this.Da = this.ob = this.w = 0;
+        this.F = [];
+        this.J = 0;
+      }
+
+      function Ce() {
+        var a = new Be();
+        null != a && (a.a = 0, a.sc = "OK", a.cb = 0, a.Xb = 0, oa || (oa = De));
+        return a;
+      }
+
+      function T(a, b, c) {
+        0 == a.a && (a.a = b, a.sc = c, a.cb = 0);
+        return 0;
+      }
+
+      function Jc(a, b, c) {
+        return 3 <= c && 157 == a[b + 0] && 1 == a[b + 1] && 42 == a[b + 2];
+      }
+
+      function Kc(a, b) {
+        if (null == a) return 0;
+        a.a = 0;
+        a.sc = "OK";
+        if (null == b) return T(a, 2, "null VP8Io passed to VP8GetHeaders()");
+        var c = b.data;
+        var d = b.w;
+        var e = b.ha;
+        if (4 > e) return T(a, 7, "Truncated header.");
+        var f = c[d + 0] | c[d + 1] << 8 | c[d + 2] << 16;
+        var g = a.Od;
+        g.Rb = !(f & 1);
+        g.td = f >> 1 & 7;
+        g.yd = f >> 4 & 1;
+        g.ub = f >> 5;
+        if (3 < g.td) return T(a, 3, "Incorrect keyframe parameters.");
+        if (!g.yd) return T(a, 4, "Frame not displayable.");
+        d += 3;
+        e -= 3;
+        var h = a.Kc;
+
+        if (g.Rb) {
+          if (7 > e) return T(a, 7, "cannot parse picture header");
+          if (!Jc(c, d, e)) return T(a, 3, "Bad code word");
+          h.c = (c[d + 4] << 8 | c[d + 3]) & 16383;
+          h.Td = c[d + 4] >> 6;
+          h.i = (c[d + 6] << 8 | c[d + 5]) & 16383;
+          h.Ud = c[d + 6] >> 6;
+          d += 7;
+          e -= 7;
+          a.za = h.c + 15 >> 4;
+          a.Ub = h.i + 15 >> 4;
+          b.width = h.c;
+          b.height = h.i;
+          b.Da = 0;
+          b.j = 0;
+          b.v = 0;
+          b.va = b.width;
+          b.o = b.height;
+          b.da = 0;
+          b.ib = b.width;
+          b.hb = b.height;
+          b.U = b.width;
+          b.T = b.height;
+          f = a.Pa;
+          M(f.jb, 0, 255, f.jb.length);
+          f = a.Qa;
+          x(null != f);
+          f.Cb = 0;
+          f.Bb = 0;
+          f.Fb = 1;
+          M(f.Zb, 0, 0, f.Zb.length);
+          M(f.Lb, 0, 0, f.Lb);
+        }
+
+        if (g.ub > e) return T(a, 7, "bad partition length");
+        f = a.m;
+        ma(f, c, d, g.ub);
+        d += g.ub;
+        e -= g.ub;
+        g.Rb && (h.Ld = G(f), h.Kd = G(f));
+        h = a.Qa;
+        var k = a.Pa,
+            l;
+        x(null != f);
+        x(null != h);
+        h.Cb = G(f);
+
+        if (h.Cb) {
+          h.Bb = G(f);
+
+          if (G(f)) {
+            h.Fb = G(f);
+
+            for (l = 0; 4 > l; ++l) {
+              h.Zb[l] = G(f) ? ca(f, 7) : 0;
+            }
+
+            for (l = 0; 4 > l; ++l) {
+              h.Lb[l] = G(f) ? ca(f, 6) : 0;
+            }
+          }
+
+          if (h.Bb) for (l = 0; 3 > l; ++l) {
+            k.jb[l] = G(f) ? na(f, 8) : 255;
+          }
+        } else h.Bb = 0;
+
+        if (f.Ka) return T(a, 3, "cannot parse segment header");
+        h = a.ed;
+        h.zd = G(f);
+        h.Tb = na(f, 6);
+        h.wb = na(f, 3);
+        h.Pc = G(f);
+
+        if (h.Pc && G(f)) {
+          for (k = 0; 4 > k; ++k) {
+            G(f) && (h.vd[k] = ca(f, 6));
+          }
+
+          for (k = 0; 4 > k; ++k) {
+            G(f) && (h.od[k] = ca(f, 6));
+          }
+        }
+
+        a.L = 0 == h.Tb ? 0 : h.zd ? 1 : 2;
+        if (f.Ka) return T(a, 3, "cannot parse filter header");
+        l = d;
+        var m = e;
+        e = l;
+        d = l + m;
+        h = m;
+        a.Xb = (1 << na(a.m, 2)) - 1;
+        k = a.Xb;
+        if (m < 3 * k) c = 7;else {
+          l += 3 * k;
+          h -= 3 * k;
+
+          for (m = 0; m < k; ++m) {
+            var n = c[e + 0] | c[e + 1] << 8 | c[e + 2] << 16;
+            n > h && (n = h);
+            ma(a.Jc[+m], c, l, n);
+            l += n;
+            h -= n;
+            e += 3;
+          }
+
+          ma(a.Jc[+k], c, l, h);
+          c = l < d ? 0 : 5;
+        }
+        if (0 != c) return T(a, c, "cannot parse partitions");
+        l = a.m;
+        c = na(l, 7);
+        e = G(l) ? ca(l, 4) : 0;
+        d = G(l) ? ca(l, 4) : 0;
+        h = G(l) ? ca(l, 4) : 0;
+        k = G(l) ? ca(l, 4) : 0;
+        l = G(l) ? ca(l, 4) : 0;
+        m = a.Qa;
+
+        for (n = 0; 4 > n; ++n) {
+          if (m.Cb) {
+            var r = m.Zb[n];
+            m.Fb || (r += c);
+          } else if (0 < n) {
+            a.pb[n] = a.pb[0];
+            continue;
+          } else r = c;
+
+          var q = a.pb[n];
+          q.Sc[0] = Lb[ga(r + e, 127)];
+          q.Sc[1] = Mb[ga(r + 0, 127)];
+          q.Eb[0] = 2 * Lb[ga(r + d, 127)];
+          q.Eb[1] = 101581 * Mb[ga(r + h, 127)] >> 16;
+          8 > q.Eb[1] && (q.Eb[1] = 8);
+          q.Qc[0] = Lb[ga(r + k, 117)];
+          q.Qc[1] = Mb[ga(r + l, 127)];
+          q.lc = r + l;
+        }
+
+        if (!g.Rb) return T(a, 4, "Not a key frame.");
+        G(f);
+        g = a.Pa;
+
+        for (c = 0; 4 > c; ++c) {
+          for (e = 0; 8 > e; ++e) {
+            for (d = 0; 3 > d; ++d) {
+              for (h = 0; 11 > h; ++h) {
+                k = K(f, Ee[c][e][d][h]) ? na(f, 8) : Fe[c][e][d][h], g.Wc[c][e].Yb[d][h] = k;
+              }
+            }
+          }
+
+          for (e = 0; 17 > e; ++e) {
+            g.Xc[c][e] = g.Wc[c][Ge[e]];
+          }
+        }
+
+        a.kc = G(f);
+        a.kc && (a.Bd = na(f, 8));
+        return a.cb = 1;
+      }
+
+      function De(a, b, c, d, e, f, g) {
+        var h = b[e].Yb[c];
+
+        for (c = 0; 16 > e; ++e) {
+          if (!K(a, h[c + 0])) return e;
+
+          for (; !K(a, h[c + 1]);) {
+            if (h = b[++e].Yb[0], c = 0, 16 == e) return 16;
+          }
+
+          var k = b[e + 1].Yb;
+
+          if (K(a, h[c + 2])) {
+            var l = a,
+                m = h,
+                n = c;
+            var r = 0;
+            if (K(l, m[n + 3])) {
+              if (K(l, m[n + 6])) {
+                h = 0;
+                r = K(l, m[n + 8]);
+                m = K(l, m[n + 9 + r]);
+                n = 2 * r + m;
+                r = 0;
+
+                for (m = He[n]; m[h]; ++h) {
+                  r += r + K(l, m[h]);
+                }
+
+                r += 3 + (8 << n);
+              } else K(l, m[n + 7]) ? (r = 7 + 2 * K(l, 165), r += K(l, 145)) : r = 5 + K(l, 159);
+            } else K(l, m[n + 4]) ? r = 3 + K(l, m[n + 5]) : r = 2;
+            h = k[2];
+          } else r = 1, h = k[1];
+
+          k = g + Ie[e];
+          l = a;
+          0 > l.b && Qa(l);
+          var m = l.b,
+              n = l.Ca >> 1,
+              q = n - (l.I >> m) >> 31;
+          --l.b;
+          l.Ca += q;
+          l.Ca |= 1;
+          l.I -= (n + 1 & q) << m;
+          f[k] = ((r ^ q) - q) * d[(0 < e) + 0];
+        }
+
+        return 16;
+      }
+
+      function Lc(a) {
+        var b = a.rb[a.sb - 1];
+        b.la = 0;
+        b.Na = 0;
+        M(a.zc, 0, 0, a.zc.length);
+        a.ja = 0;
+      }
+
+      function Je(a, b) {
+        for (a.M = 0; a.M < a.Va; ++a.M) {
+          var c = a.Jc[a.M & a.Xb],
+              d = a.m,
+              e = a,
+              f;
+
+          for (f = 0; f < e.za; ++f) {
+            var g = d;
+            var h = e;
+            var k = h.Ac,
+                l = h.Bc + 4 * f,
+                m = h.zc,
+                n = h.ya[h.aa + f];
+            h.Qa.Bb ? n.$b = K(g, h.Pa.jb[0]) ? 2 + K(g, h.Pa.jb[2]) : K(g, h.Pa.jb[1]) : n.$b = 0;
+            h.kc && (n.Ad = K(g, h.Bd));
+            n.Za = !K(g, 145) + 0;
+
+            if (n.Za) {
+              var r = n.Ob,
+                  q = 0;
+
+              for (h = 0; 4 > h; ++h) {
+                var t = m[0 + h];
+                var v;
+
+                for (v = 0; 4 > v; ++v) {
+                  t = Ke[k[l + v]][t];
+
+                  for (var p = Mc[K(g, t[0])]; 0 < p;) {
+                    p = Mc[2 * p + K(g, t[p])];
+                  }
+
+                  t = -p;
+                  k[l + v] = t;
+                }
+
+                I(r, q, k, l, 4);
+                q += 4;
+                m[0 + h] = t;
+              }
+            } else t = K(g, 156) ? K(g, 128) ? 1 : 3 : K(g, 163) ? 2 : 0, n.Ob[0] = t, M(k, l, t, 4), M(m, 0, t, 4);
+
+            n.Dd = K(g, 142) ? K(g, 114) ? K(g, 183) ? 1 : 3 : 2 : 0;
+          }
+
+          if (e.m.Ka) return T(a, 7, "Premature end-of-partition0 encountered.");
+
+          for (; a.ja < a.za; ++a.ja) {
+            d = a;
+            e = c;
+            g = d.rb[d.sb - 1];
+            k = d.rb[d.sb + d.ja];
+            f = d.ya[d.aa + d.ja];
+            if (l = d.kc ? f.Ad : 0) g.la = k.la = 0, f.Za || (g.Na = k.Na = 0), f.Hc = 0, f.Gc = 0, f.ia = 0;else {
+              var u,
+                  w,
+                  g = k,
+                  k = e,
+                  l = d.Pa.Xc,
+                  m = d.ya[d.aa + d.ja],
+                  n = d.pb[m.$b];
+              h = m.ad;
+              r = 0;
+              q = d.rb[d.sb - 1];
+              t = v = 0;
+              M(h, r, 0, 384);
+
+              if (m.Za) {
+                var y = 0;
+                var A = l[3];
+              } else {
+                p = V(16);
+                var E = g.Na + q.Na;
+                E = oa(k, l[1], E, n.Eb, 0, p, 0);
+                g.Na = q.Na = (0 < E) + 0;
+                if (1 < E) Nc(p, 0, h, r);else {
+                  var B = p[0] + 3 >> 3;
+
+                  for (p = 0; 256 > p; p += 16) {
+                    h[r + p] = B;
+                  }
+                }
+                y = 1;
+                A = l[0];
+              }
+
+              var C = g.la & 15;
+              var N = q.la & 15;
+
+              for (p = 0; 4 > p; ++p) {
+                var z = N & 1;
+
+                for (B = w = 0; 4 > B; ++B) {
+                  E = z + (C & 1), E = oa(k, A, E, n.Sc, y, h, r), z = E > y, C = C >> 1 | z << 7, w = w << 2 | (3 < E ? 3 : 1 < E ? 2 : 0 != h[r + 0]), r += 16;
+                }
+
+                C >>= 4;
+                N = N >> 1 | z << 7;
+                v = (v << 8 | w) >>> 0;
+              }
+
+              A = C;
+              y = N >> 4;
+
+              for (u = 0; 4 > u; u += 2) {
+                w = 0;
+                C = g.la >> 4 + u;
+                N = q.la >> 4 + u;
+
+                for (p = 0; 2 > p; ++p) {
+                  z = N & 1;
+
+                  for (B = 0; 2 > B; ++B) {
+                    E = z + (C & 1), E = oa(k, l[2], E, n.Qc, 0, h, r), z = 0 < E, C = C >> 1 | z << 3, w = w << 2 | (3 < E ? 3 : 1 < E ? 2 : 0 != h[r + 0]), r += 16;
+                  }
+
+                  C >>= 2;
+                  N = N >> 1 | z << 5;
+                }
+
+                t |= w << 4 * u;
+                A |= C << 4 << u;
+                y |= (N & 240) << u;
+              }
+
+              g.la = A;
+              q.la = y;
+              m.Hc = v;
+              m.Gc = t;
+              m.ia = t & 43690 ? 0 : n.ia;
+              l = !(v | t);
+            }
+            0 < d.L && (d.wa[d.Y + d.ja] = d.gd[f.$b][f.Za], d.wa[d.Y + d.ja].La |= !l);
+            if (e.Ka) return T(a, 7, "Premature end-of-file encountered.");
+          }
+
+          Lc(a);
+          c = a;
+          d = b;
+          e = 1;
+          f = c.D;
+          g = 0 < c.L && c.M >= c.zb && c.M <= c.Va;
+          if (0 == c.Aa) a: {
+            f.M = c.M, f.uc = g, Oc(c, f), e = 1;
+            w = c.D;
+            f = w.Nb;
+            t = Ya[c.L];
+            g = t * c.R;
+            k = t / 2 * c.B;
+            p = 16 * f * c.R;
+            B = 8 * f * c.B;
+            l = c.sa;
+            m = c.ta - g + p;
+            n = c.qa;
+            h = c.ra - k + B;
+            r = c.Ha;
+            q = c.Ia - k + B;
+            C = w.M;
+            N = 0 == C;
+            v = C >= c.Va - 1;
+            2 == c.Aa && Oc(c, w);
+            if (w.uc) for (E = c, z = E.D.M, x(E.D.uc), w = E.yb; w < E.Hb; ++w) {
+              var Q = E;
+              y = w;
+              A = z;
+              var S = Q.D,
+                  D = S.Nb;
+              u = Q.R;
+              var S = S.wa[S.Y + y],
+                  F = Q.sa,
+                  H = Q.ta + 16 * D * u + 16 * y,
+                  J = S.dd,
+                  G = S.tc;
+              if (0 != G) if (x(3 <= G), 1 == Q.L) 0 < y && Pc(F, H, u, G + 4), S.La && Qc(F, H, u, G), 0 < A && Rc(F, H, u, G + 4), S.La && Sc(F, H, u, G);else {
+                var L = Q.B,
+                    O = Q.qa,
+                    P = Q.ra + 8 * D * L + 8 * y,
+                    R = Q.Ha,
+                    Q = Q.Ia + 8 * D * L + 8 * y,
+                    D = S.ld;
+                0 < y && (Tc(F, H, u, G + 4, J, D), Uc(O, P, R, Q, L, G + 4, J, D));
+                S.La && (Vc(F, H, u, G, J, D), Wc(O, P, R, Q, L, G, J, D));
+                0 < A && (Xc(F, H, u, G + 4, J, D), Yc(O, P, R, Q, L, G + 4, J, D));
+                S.La && (Zc(F, H, u, G, J, D), $c(O, P, R, Q, L, G, J, D));
+              }
+            }
+            c.ia && alert("todo:DitherRow");
+
+            if (null != d.put) {
+              w = 16 * C;
+              C = 16 * (C + 1);
+              N ? (d.y = c.sa, d.O = c.ta + p, d.f = c.qa, d.N = c.ra + B, d.ea = c.Ha, d.W = c.Ia + B) : (w -= t, d.y = l, d.O = m, d.f = n, d.N = h, d.ea = r, d.W = q);
+              v || (C -= t);
+              C > d.o && (C = d.o);
+              d.F = null;
+              d.J = null;
+
+              if (null != c.Fa && 0 < c.Fa.length && w < C && (d.J = Le(c, d, w, C - w), d.F = c.mb, null == d.F && 0 == d.F.length)) {
+                e = T(c, 3, "Could not decode alpha data.");
+                break a;
+              }
+
+              w < d.j && (t = d.j - w, w = d.j, x(!(t & 1)), d.O += c.R * t, d.N += c.B * (t >> 1), d.W += c.B * (t >> 1), null != d.F && (d.J += d.width * t));
+              w < C && (d.O += d.v, d.N += d.v >> 1, d.W += d.v >> 1, null != d.F && (d.J += d.v), d.ka = w - d.j, d.U = d.va - d.v, d.T = C - w, e = d.put(d));
+            }
+
+            f + 1 != c.Ic || v || (I(c.sa, c.ta - g, l, m + 16 * c.R, g), I(c.qa, c.ra - k, n, h + 8 * c.B, k), I(c.Ha, c.Ia - k, r, q + 8 * c.B, k));
+          }
+          if (!e) return T(a, 6, "Output aborted.");
+        }
+
+        return 1;
+      }
+
+      function Me(a, b) {
+        if (null == a) return 0;
+        if (null == b) return T(a, 2, "NULL VP8Io parameter in VP8Decode().");
+        if (!a.cb && !Kc(a, b)) return 0;
+        x(a.cb);
+
+        if (null == b.ac || b.ac(b)) {
+          b.ob && (a.L = 0);
+          var c = Ya[a.L];
+          2 == a.L ? (a.yb = 0, a.zb = 0) : (a.yb = b.v - c >> 4, a.zb = b.j - c >> 4, 0 > a.yb && (a.yb = 0), 0 > a.zb && (a.zb = 0));
+          a.Va = b.o + 15 + c >> 4;
+          a.Hb = b.va + 15 + c >> 4;
+          a.Hb > a.za && (a.Hb = a.za);
+          a.Va > a.Ub && (a.Va = a.Ub);
+
+          if (0 < a.L) {
+            var d = a.ed;
+
+            for (c = 0; 4 > c; ++c) {
+              var e;
+
+              if (a.Qa.Cb) {
+                var f = a.Qa.Lb[c];
+                a.Qa.Fb || (f += d.Tb);
+              } else f = d.Tb;
+
+              for (e = 0; 1 >= e; ++e) {
+                var g = a.gd[c][e],
+                    h = f;
+                d.Pc && (h += d.vd[0], e && (h += d.od[0]));
+                h = 0 > h ? 0 : 63 < h ? 63 : h;
+
+                if (0 < h) {
+                  var k = h;
+                  0 < d.wb && (k = 4 < d.wb ? k >> 2 : k >> 1, k > 9 - d.wb && (k = 9 - d.wb));
+                  1 > k && (k = 1);
+                  g.dd = k;
+                  g.tc = 2 * h + k;
+                  g.ld = 40 <= h ? 2 : 15 <= h ? 1 : 0;
+                } else g.tc = 0;
+
+                g.La = e;
+              }
+            }
+          }
+
+          c = 0;
+        } else T(a, 6, "Frame setup failed"), c = a.a;
+
+        if (c = 0 == c) {
+          if (c) {
+            a.$c = 0;
+            0 < a.Aa || (a.Ic = Ne);
+
+            b: {
+              c = a.Ic;
+              var k = a.za,
+                  d = 4 * k,
+                  l = 32 * k,
+                  m = k + 1,
+                  n = 0 < a.L ? k * (0 < a.Aa ? 2 : 1) : 0,
+                  r = (2 == a.Aa ? 2 : 1) * k;
+              e = 3 * (16 * c + Ya[a.L]) / 2 * l;
+              f = null != a.Fa && 0 < a.Fa.length ? a.Kc.c * a.Kc.i : 0;
+              g = d + 832 + e + f;
+              if (g != g) c = 0;else {
+                if (g > a.Vb) {
+                  a.Vb = 0;
+                  a.Ec = V(g);
+                  a.Fc = 0;
+
+                  if (null == a.Ec) {
+                    c = T(a, 1, "no memory during frame initialization.");
+                    break b;
+                  }
+
+                  a.Vb = g;
+                }
+
+                g = a.Ec;
+                h = a.Fc;
+                a.Ac = g;
+                a.Bc = h;
+                h += d;
+                a.Gd = wa(l, Ic);
+                a.Hd = 0;
+                a.rb = wa(m + 1, Hc);
+                a.sb = 1;
+                a.wa = n ? wa(n, Xa) : null;
+                a.Y = 0;
+                a.D.Nb = 0;
+                a.D.wa = a.wa;
+                a.D.Y = a.Y;
+                0 < a.Aa && (a.D.Y += k);
+                x(!0);
+                a.oc = g;
+                a.pc = h;
+                h += 832;
+                a.ya = wa(r, Kb);
+                a.aa = 0;
+                a.D.ya = a.ya;
+                a.D.aa = a.aa;
+                2 == a.Aa && (a.D.aa += k);
+                a.R = 16 * k;
+                a.B = 8 * k;
+                l = Ya[a.L];
+                k = l * a.R;
+                l = l / 2 * a.B;
+                a.sa = g;
+                a.ta = h + k;
+                a.qa = a.sa;
+                a.ra = a.ta + 16 * c * a.R + l;
+                a.Ha = a.qa;
+                a.Ia = a.ra + 8 * c * a.B + l;
+                a.$c = 0;
+                h += e;
+                a.mb = f ? g : null;
+                a.nb = f ? h : null;
+                x(h + f <= a.Fc + a.Vb);
+                Lc(a);
+                M(a.Ac, a.Bc, 0, d);
+                c = 1;
+              }
+            }
+
+            if (c) {
+              b.ka = 0;
+              b.y = a.sa;
+              b.O = a.ta;
+              b.f = a.qa;
+              b.N = a.ra;
+              b.ea = a.Ha;
+              b.Vd = a.Ia;
+              b.fa = a.R;
+              b.Rc = a.B;
+              b.F = null;
+              b.J = 0;
+
+              if (!ad) {
+                for (c = -255; 255 >= c; ++c) {
+                  bd[255 + c] = 0 > c ? -c : c;
+                }
+
+                for (c = -1020; 1020 >= c; ++c) {
+                  cd[1020 + c] = -128 > c ? -128 : 127 < c ? 127 : c;
+                }
+
+                for (c = -112; 112 >= c; ++c) {
+                  dd[112 + c] = -16 > c ? -16 : 15 < c ? 15 : c;
+                }
+
+                for (c = -255; 510 >= c; ++c) {
+                  ed[255 + c] = 0 > c ? 0 : 255 < c ? 255 : c;
+                }
+
+                ad = 1;
+              }
+
+              Nc = Oe;
+              Za = Pe;
+              Nb = Qe;
+              pa = Re;
+              Ob = Se;
+              fd = Te;
+              Xc = Ue;
+              Tc = Ve;
+              Yc = We;
+              Uc = Xe;
+              Zc = Ye;
+              Vc = Ze;
+              $c = $e;
+              Wc = af;
+              Rc = gd;
+              Pc = hd;
+              Sc = bf;
+              Qc = cf;
+              W[0] = df;
+              W[1] = ef;
+              W[2] = ff;
+              W[3] = gf;
+              W[4] = hf;
+              W[5] = jf;
+              W[6] = kf;
+              W[7] = lf;
+              W[8] = mf;
+              W[9] = nf;
+              Y[0] = of;
+              Y[1] = pf;
+              Y[2] = qf;
+              Y[3] = rf;
+              Y[4] = sf;
+              Y[5] = tf;
+              Y[6] = uf;
+              ka[0] = vf;
+              ka[1] = wf;
+              ka[2] = xf;
+              ka[3] = yf;
+              ka[4] = zf;
+              ka[5] = Af;
+              ka[6] = Bf;
+              c = 1;
+            } else c = 0;
+          }
+
+          c && (c = Je(a, b));
+          null != b.bc && b.bc(b);
+          c &= 1;
+        }
+
+        if (!c) return 0;
+        a.cb = 0;
+        return c;
+      }
+
+      function qa(a, b, c, d, e) {
+        e = a[b + c + 32 * d] + (e >> 3);
+        a[b + c + 32 * d] = e & -256 ? 0 > e ? 0 : 255 : e;
+      }
+
+      function kb(a, b, c, d, e, f) {
+        qa(a, b, 0, c, d + e);
+        qa(a, b, 1, c, d + f);
+        qa(a, b, 2, c, d - f);
+        qa(a, b, 3, c, d - e);
+      }
+
+      function da(a) {
+        return (20091 * a >> 16) + a;
+      }
+
+      function id(a, b, c, d) {
+        var e = 0,
+            f;
+        var g = V(16);
+
+        for (f = 0; 4 > f; ++f) {
+          var h = a[b + 0] + a[b + 8];
+          var k = a[b + 0] - a[b + 8];
+          var l = (35468 * a[b + 4] >> 16) - da(a[b + 12]);
+          var m = da(a[b + 4]) + (35468 * a[b + 12] >> 16);
+          g[e + 0] = h + m;
+          g[e + 1] = k + l;
+          g[e + 2] = k - l;
+          g[e + 3] = h - m;
+          e += 4;
+          b++;
+        }
+
+        for (f = e = 0; 4 > f; ++f) {
+          a = g[e + 0] + 4, h = a + g[e + 8], k = a - g[e + 8], l = (35468 * g[e + 4] >> 16) - da(g[e + 12]), m = da(g[e + 4]) + (35468 * g[e + 12] >> 16), qa(c, d, 0, 0, h + m), qa(c, d, 1, 0, k + l), qa(c, d, 2, 0, k - l), qa(c, d, 3, 0, h - m), e++, d += 32;
+        }
+      }
+
+      function Te(a, b, c, d) {
+        var e = a[b + 0] + 4,
+            f = 35468 * a[b + 4] >> 16,
+            g = da(a[b + 4]),
+            h = 35468 * a[b + 1] >> 16;
+        a = da(a[b + 1]);
+        kb(c, d, 0, e + g, a, h);
+        kb(c, d, 1, e + f, a, h);
+        kb(c, d, 2, e - f, a, h);
+        kb(c, d, 3, e - g, a, h);
+      }
+
+      function Pe(a, b, c, d, e) {
+        id(a, b, c, d);
+        e && id(a, b + 16, c, d + 4);
+      }
+
+      function Qe(a, b, c, d) {
+        Za(a, b + 0, c, d, 1);
+        Za(a, b + 32, c, d + 128, 1);
+      }
+
+      function Re(a, b, c, d) {
+        a = a[b + 0] + 4;
+        var e;
+
+        for (e = 0; 4 > e; ++e) {
+          for (b = 0; 4 > b; ++b) {
+            qa(c, d, b, e, a);
+          }
+        }
+      }
+
+      function Se(a, b, c, d) {
+        a[b + 0] && pa(a, b + 0, c, d);
+        a[b + 16] && pa(a, b + 16, c, d + 4);
+        a[b + 32] && pa(a, b + 32, c, d + 128);
+        a[b + 48] && pa(a, b + 48, c, d + 128 + 4);
+      }
+
+      function Oe(a, b, c, d) {
+        var e = V(16),
+            f;
+
+        for (f = 0; 4 > f; ++f) {
+          var g = a[b + 0 + f] + a[b + 12 + f];
+          var h = a[b + 4 + f] + a[b + 8 + f];
+          var k = a[b + 4 + f] - a[b + 8 + f];
+          var l = a[b + 0 + f] - a[b + 12 + f];
+          e[0 + f] = g + h;
+          e[8 + f] = g - h;
+          e[4 + f] = l + k;
+          e[12 + f] = l - k;
+        }
+
+        for (f = 0; 4 > f; ++f) {
+          a = e[0 + 4 * f] + 3, g = a + e[3 + 4 * f], h = e[1 + 4 * f] + e[2 + 4 * f], k = e[1 + 4 * f] - e[2 + 4 * f], l = a - e[3 + 4 * f], c[d + 0] = g + h >> 3, c[d + 16] = l + k >> 3, c[d + 32] = g - h >> 3, c[d + 48] = l - k >> 3, d += 64;
+        }
+      }
+
+      function Pb(a, b, c) {
+        var d = b - 32,
+            e = R,
+            f = 255 - a[d - 1],
+            g;
+
+        for (g = 0; g < c; ++g) {
+          var h = e,
+              k = f + a[b - 1],
+              l;
+
+          for (l = 0; l < c; ++l) {
+            a[b + l] = h[k + a[d + l]];
+          }
+
+          b += 32;
+        }
+      }
+
+      function ef(a, b) {
+        Pb(a, b, 4);
+      }
+
+      function wf(a, b) {
+        Pb(a, b, 8);
+      }
+
+      function pf(a, b) {
+        Pb(a, b, 16);
+      }
+
+      function qf(a, b) {
+        var c;
+
+        for (c = 0; 16 > c; ++c) {
+          I(a, b + 32 * c, a, b - 32, 16);
+        }
+      }
+
+      function rf(a, b) {
+        var c;
+
+        for (c = 16; 0 < c; --c) {
+          M(a, b, a[b - 1], 16), b += 32;
+        }
+      }
+
+      function $a(a, b, c) {
+        var d;
+
+        for (d = 0; 16 > d; ++d) {
+          M(b, c + 32 * d, a, 16);
+        }
+      }
+
+      function of(a, b) {
+        var c = 16,
+            d;
+
+        for (d = 0; 16 > d; ++d) {
+          c += a[b - 1 + 32 * d] + a[b + d - 32];
+        }
+
+        $a(c >> 5, a, b);
+      }
+
+      function sf(a, b) {
+        var c = 8,
+            d;
+
+        for (d = 0; 16 > d; ++d) {
+          c += a[b - 1 + 32 * d];
+        }
+
+        $a(c >> 4, a, b);
+      }
+
+      function tf(a, b) {
+        var c = 8,
+            d;
+
+        for (d = 0; 16 > d; ++d) {
+          c += a[b + d - 32];
+        }
+
+        $a(c >> 4, a, b);
+      }
+
+      function uf(a, b) {
+        $a(128, a, b);
+      }
+
+      function z(a, b, c) {
+        return a + 2 * b + c + 2 >> 2;
+      }
+
+      function ff(a, b) {
+        var c = b - 32,
+            c = new Uint8Array([z(a[c - 1], a[c + 0], a[c + 1]), z(a[c + 0], a[c + 1], a[c + 2]), z(a[c + 1], a[c + 2], a[c + 3]), z(a[c + 2], a[c + 3], a[c + 4])]),
+            d;
+
+        for (d = 0; 4 > d; ++d) {
+          I(a, b + 32 * d, c, 0, c.length);
+        }
+      }
+
+      function gf(a, b) {
+        var c = a[b - 1],
+            d = a[b - 1 + 32],
+            e = a[b - 1 + 64],
+            f = a[b - 1 + 96];
+        ra(a, b + 0, 16843009 * z(a[b - 1 - 32], c, d));
+        ra(a, b + 32, 16843009 * z(c, d, e));
+        ra(a, b + 64, 16843009 * z(d, e, f));
+        ra(a, b + 96, 16843009 * z(e, f, f));
+      }
+
+      function df(a, b) {
+        var c = 4,
+            d;
+
+        for (d = 0; 4 > d; ++d) {
+          c += a[b + d - 32] + a[b - 1 + 32 * d];
+        }
+
+        c >>= 3;
+
+        for (d = 0; 4 > d; ++d) {
+          M(a, b + 32 * d, c, 4);
+        }
+      }
+
+      function hf(a, b) {
+        var c = a[b - 1 + 0],
+            d = a[b - 1 + 32],
+            e = a[b - 1 + 64],
+            f = a[b - 1 - 32],
+            g = a[b + 0 - 32],
+            h = a[b + 1 - 32],
+            k = a[b + 2 - 32],
+            l = a[b + 3 - 32];
+        a[b + 0 + 96] = z(d, e, a[b - 1 + 96]);
+        a[b + 1 + 96] = a[b + 0 + 64] = z(c, d, e);
+        a[b + 2 + 96] = a[b + 1 + 64] = a[b + 0 + 32] = z(f, c, d);
+        a[b + 3 + 96] = a[b + 2 + 64] = a[b + 1 + 32] = a[b + 0 + 0] = z(g, f, c);
+        a[b + 3 + 64] = a[b + 2 + 32] = a[b + 1 + 0] = z(h, g, f);
+        a[b + 3 + 32] = a[b + 2 + 0] = z(k, h, g);
+        a[b + 3 + 0] = z(l, k, h);
+      }
+
+      function kf(a, b) {
+        var c = a[b + 1 - 32],
+            d = a[b + 2 - 32],
+            e = a[b + 3 - 32],
+            f = a[b + 4 - 32],
+            g = a[b + 5 - 32],
+            h = a[b + 6 - 32],
+            k = a[b + 7 - 32];
+        a[b + 0 + 0] = z(a[b + 0 - 32], c, d);
+        a[b + 1 + 0] = a[b + 0 + 32] = z(c, d, e);
+        a[b + 2 + 0] = a[b + 1 + 32] = a[b + 0 + 64] = z(d, e, f);
+        a[b + 3 + 0] = a[b + 2 + 32] = a[b + 1 + 64] = a[b + 0 + 96] = z(e, f, g);
+        a[b + 3 + 32] = a[b + 2 + 64] = a[b + 1 + 96] = z(f, g, h);
+        a[b + 3 + 64] = a[b + 2 + 96] = z(g, h, k);
+        a[b + 3 + 96] = z(h, k, k);
+      }
+
+      function jf(a, b) {
+        var c = a[b - 1 + 0],
+            d = a[b - 1 + 32],
+            e = a[b - 1 + 64],
+            f = a[b - 1 - 32],
+            g = a[b + 0 - 32],
+            h = a[b + 1 - 32],
+            k = a[b + 2 - 32],
+            l = a[b + 3 - 32];
+        a[b + 0 + 0] = a[b + 1 + 64] = f + g + 1 >> 1;
+        a[b + 1 + 0] = a[b + 2 + 64] = g + h + 1 >> 1;
+        a[b + 2 + 0] = a[b + 3 + 64] = h + k + 1 >> 1;
+        a[b + 3 + 0] = k + l + 1 >> 1;
+        a[b + 0 + 96] = z(e, d, c);
+        a[b + 0 + 64] = z(d, c, f);
+        a[b + 0 + 32] = a[b + 1 + 96] = z(c, f, g);
+        a[b + 1 + 32] = a[b + 2 + 96] = z(f, g, h);
+        a[b + 2 + 32] = a[b + 3 + 96] = z(g, h, k);
+        a[b + 3 + 32] = z(h, k, l);
+      }
+
+      function lf(a, b) {
+        var c = a[b + 0 - 32],
+            d = a[b + 1 - 32],
+            e = a[b + 2 - 32],
+            f = a[b + 3 - 32],
+            g = a[b + 4 - 32],
+            h = a[b + 5 - 32],
+            k = a[b + 6 - 32],
+            l = a[b + 7 - 32];
+        a[b + 0 + 0] = c + d + 1 >> 1;
+        a[b + 1 + 0] = a[b + 0 + 64] = d + e + 1 >> 1;
+        a[b + 2 + 0] = a[b + 1 + 64] = e + f + 1 >> 1;
+        a[b + 3 + 0] = a[b + 2 + 64] = f + g + 1 >> 1;
+        a[b + 0 + 32] = z(c, d, e);
+        a[b + 1 + 32] = a[b + 0 + 96] = z(d, e, f);
+        a[b + 2 + 32] = a[b + 1 + 96] = z(e, f, g);
+        a[b + 3 + 32] = a[b + 2 + 96] = z(f, g, h);
+        a[b + 3 + 64] = z(g, h, k);
+        a[b + 3 + 96] = z(h, k, l);
+      }
+
+      function nf(a, b) {
+        var c = a[b - 1 + 0],
+            d = a[b - 1 + 32],
+            e = a[b - 1 + 64],
+            f = a[b - 1 + 96];
+        a[b + 0 + 0] = c + d + 1 >> 1;
+        a[b + 2 + 0] = a[b + 0 + 32] = d + e + 1 >> 1;
+        a[b + 2 + 32] = a[b + 0 + 64] = e + f + 1 >> 1;
+        a[b + 1 + 0] = z(c, d, e);
+        a[b + 3 + 0] = a[b + 1 + 32] = z(d, e, f);
+        a[b + 3 + 32] = a[b + 1 + 64] = z(e, f, f);
+        a[b + 3 + 64] = a[b + 2 + 64] = a[b + 0 + 96] = a[b + 1 + 96] = a[b + 2 + 96] = a[b + 3 + 96] = f;
+      }
+
+      function mf(a, b) {
+        var c = a[b - 1 + 0],
+            d = a[b - 1 + 32],
+            e = a[b - 1 + 64],
+            f = a[b - 1 + 96],
+            g = a[b - 1 - 32],
+            h = a[b + 0 - 32],
+            k = a[b + 1 - 32],
+            l = a[b + 2 - 32];
+        a[b + 0 + 0] = a[b + 2 + 32] = c + g + 1 >> 1;
+        a[b + 0 + 32] = a[b + 2 + 64] = d + c + 1 >> 1;
+        a[b + 0 + 64] = a[b + 2 + 96] = e + d + 1 >> 1;
+        a[b + 0 + 96] = f + e + 1 >> 1;
+        a[b + 3 + 0] = z(h, k, l);
+        a[b + 2 + 0] = z(g, h, k);
+        a[b + 1 + 0] = a[b + 3 + 32] = z(c, g, h);
+        a[b + 1 + 32] = a[b + 3 + 64] = z(d, c, g);
+        a[b + 1 + 64] = a[b + 3 + 96] = z(e, d, c);
+        a[b + 1 + 96] = z(f, e, d);
+      }
+
+      function xf(a, b) {
+        var c;
+
+        for (c = 0; 8 > c; ++c) {
+          I(a, b + 32 * c, a, b - 32, 8);
+        }
+      }
+
+      function yf(a, b) {
+        var c;
+
+        for (c = 0; 8 > c; ++c) {
+          M(a, b, a[b - 1], 8), b += 32;
+        }
+      }
+
+      function lb(a, b, c) {
+        var d;
+
+        for (d = 0; 8 > d; ++d) {
+          M(b, c + 32 * d, a, 8);
+        }
+      }
+
+      function vf(a, b) {
+        var c = 8,
+            d;
+
+        for (d = 0; 8 > d; ++d) {
+          c += a[b + d - 32] + a[b - 1 + 32 * d];
+        }
+
+        lb(c >> 4, a, b);
+      }
+
+      function Af(a, b) {
+        var c = 4,
+            d;
+
+        for (d = 0; 8 > d; ++d) {
+          c += a[b + d - 32];
+        }
+
+        lb(c >> 3, a, b);
+      }
+
+      function zf(a, b) {
+        var c = 4,
+            d;
+
+        for (d = 0; 8 > d; ++d) {
+          c += a[b - 1 + 32 * d];
+        }
+
+        lb(c >> 3, a, b);
+      }
+
+      function Bf(a, b) {
+        lb(128, a, b);
+      }
+
+      function ab(a, b, c) {
+        var d = a[b - c],
+            e = a[b + 0],
+            f = 3 * (e - d) + Qb[1020 + a[b - 2 * c] - a[b + c]],
+            g = mb[112 + (f + 4 >> 3)];
+        a[b - c] = R[255 + d + mb[112 + (f + 3 >> 3)]];
+        a[b + 0] = R[255 + e - g];
+      }
+
+      function jd(a, b, c, d) {
+        var e = a[b + 0],
+            f = a[b + c];
+        return U[255 + a[b - 2 * c] - a[b - c]] > d || U[255 + f - e] > d;
+      }
+
+      function kd(a, b, c, d) {
+        return 4 * U[255 + a[b - c] - a[b + 0]] + U[255 + a[b - 2 * c] - a[b + c]] <= d;
+      }
+
+      function ld(a, b, c, d, e) {
+        var f = a[b - 3 * c],
+            g = a[b - 2 * c],
+            h = a[b - c],
+            k = a[b + 0],
+            l = a[b + c],
+            m = a[b + 2 * c],
+            n = a[b + 3 * c];
+        return 4 * U[255 + h - k] + U[255 + g - l] > d ? 0 : U[255 + a[b - 4 * c] - f] <= e && U[255 + f - g] <= e && U[255 + g - h] <= e && U[255 + n - m] <= e && U[255 + m - l] <= e && U[255 + l - k] <= e;
+      }
+
+      function gd(a, b, c, d) {
+        var e = 2 * d + 1;
+
+        for (d = 0; 16 > d; ++d) {
+          kd(a, b + d, c, e) && ab(a, b + d, c);
+        }
+      }
+
+      function hd(a, b, c, d) {
+        var e = 2 * d + 1;
+
+        for (d = 0; 16 > d; ++d) {
+          kd(a, b + d * c, 1, e) && ab(a, b + d * c, 1);
+        }
+      }
+
+      function bf(a, b, c, d) {
+        var e;
+
+        for (e = 3; 0 < e; --e) {
+          b += 4 * c, gd(a, b, c, d);
+        }
+      }
+
+      function cf(a, b, c, d) {
+        var e;
+
+        for (e = 3; 0 < e; --e) {
+          b += 4, hd(a, b, c, d);
+        }
+      }
+
+      function ea(a, b, c, d, e, f, g, h) {
+        for (f = 2 * f + 1; 0 < e--;) {
+          if (ld(a, b, c, f, g)) if (jd(a, b, c, h)) ab(a, b, c);else {
+            var k = a,
+                l = b,
+                m = c,
+                n = k[l - 2 * m],
+                r = k[l - m],
+                q = k[l + 0],
+                t = k[l + m],
+                v = k[l + 2 * m],
+                p = Qb[1020 + 3 * (q - r) + Qb[1020 + n - t]],
+                u = 27 * p + 63 >> 7,
+                w = 18 * p + 63 >> 7,
+                p = 9 * p + 63 >> 7;
+            k[l - 3 * m] = R[255 + k[l - 3 * m] + p];
+            k[l - 2 * m] = R[255 + n + w];
+            k[l - m] = R[255 + r + u];
+            k[l + 0] = R[255 + q - u];
+            k[l + m] = R[255 + t - w];
+            k[l + 2 * m] = R[255 + v - p];
+          }
+          b += d;
+        }
+      }
+
+      function Fa(a, b, c, d, e, f, g, h) {
+        for (f = 2 * f + 1; 0 < e--;) {
+          if (ld(a, b, c, f, g)) if (jd(a, b, c, h)) ab(a, b, c);else {
+            var k = a,
+                l = b,
+                m = c,
+                n = k[l - m],
+                r = k[l + 0],
+                q = k[l + m],
+                t = 3 * (r - n),
+                v = mb[112 + (t + 4 >> 3)],
+                t = mb[112 + (t + 3 >> 3)],
+                p = v + 1 >> 1;
+            k[l - 2 * m] = R[255 + k[l - 2 * m] + p];
+            k[l - m] = R[255 + n + t];
+            k[l + 0] = R[255 + r - v];
+            k[l + m] = R[255 + q - p];
+          }
+          b += d;
+        }
+      }
+
+      function Ue(a, b, c, d, e, f) {
+        ea(a, b, c, 1, 16, d, e, f);
+      }
+
+      function Ve(a, b, c, d, e, f) {
+        ea(a, b, 1, c, 16, d, e, f);
+      }
+
+      function Ye(a, b, c, d, e, f) {
+        var g;
+
+        for (g = 3; 0 < g; --g) {
+          b += 4 * c, Fa(a, b, c, 1, 16, d, e, f);
+        }
+      }
+
+      function Ze(a, b, c, d, e, f) {
+        var g;
+
+        for (g = 3; 0 < g; --g) {
+          b += 4, Fa(a, b, 1, c, 16, d, e, f);
+        }
+      }
+
+      function We(a, b, c, d, e, f, g, h) {
+        ea(a, b, e, 1, 8, f, g, h);
+        ea(c, d, e, 1, 8, f, g, h);
+      }
+
+      function Xe(a, b, c, d, e, f, g, h) {
+        ea(a, b, 1, e, 8, f, g, h);
+        ea(c, d, 1, e, 8, f, g, h);
+      }
+
+      function $e(a, b, c, d, e, f, g, h) {
+        Fa(a, b + 4 * e, e, 1, 8, f, g, h);
+        Fa(c, d + 4 * e, e, 1, 8, f, g, h);
+      }
+
+      function af(a, b, c, d, e, f, g, h) {
+        Fa(a, b + 4, 1, e, 8, f, g, h);
+        Fa(c, d + 4, 1, e, 8, f, g, h);
+      }
+
+      function Cf() {
+        this.ba = new Cb();
+        this.ec = [];
+        this.cc = [];
+        this.Mc = [];
+        this.Dc = this.Nc = this.dc = this.fc = 0;
+        this.Oa = new Ud();
+        this.memory = 0;
+        this.Ib = "OutputFunc";
+        this.Jb = "OutputAlphaFunc";
+        this.Nd = "OutputRowFunc";
+      }
+
+      function md() {
+        this.data = [];
+        this.offset = this.kd = this.ha = this.w = 0;
+        this.na = [];
+        this.xa = this.gb = this.Ja = this.Sa = this.P = 0;
+      }
+
+      function Df() {
+        this.nc = this.Ea = this.b = this.hc = 0;
+        this.K = [];
+        this.w = 0;
+      }
+
+      function Ef() {
+        this.ua = 0;
+        this.Wa = new ac();
+        this.vb = new ac();
+        this.md = this.xc = this.wc = 0;
+        this.vc = [];
+        this.Wb = 0;
+        this.Ya = new Ub();
+        this.yc = new O();
+      }
+
+      function je() {
+        this.xb = this.a = 0;
+        this.l = new Oa();
+        this.ca = new Cb();
+        this.V = [];
+        this.Ba = 0;
+        this.Ta = [];
+        this.Ua = 0;
+        this.m = new Ra();
+        this.Pb = 0;
+        this.wd = new Ra();
+        this.Ma = this.$ = this.C = this.i = this.c = this.xd = 0;
+        this.s = new Ef();
+        this.ab = 0;
+        this.gc = wa(4, Df);
+        this.Oc = 0;
+      }
+
+      function Ff() {
+        this.Lc = this.Z = this.$a = this.i = this.c = 0;
+        this.l = new Oa();
+        this.ic = 0;
+        this.ca = [];
+        this.tb = 0;
+        this.qd = null;
+        this.rd = 0;
+      }
+
+      function Rb(a, b, c, d, e, f, g) {
+        a = null == a ? 0 : a[b + 0];
+
+        for (b = 0; b < g; ++b) {
+          e[f + b] = a + c[d + b] & 255, a = e[f + b];
+        }
+      }
+
+      function Gf(a, b, c, d, e, f, g) {
+        if (null == a) Rb(null, null, c, d, e, f, g);else {
+          var h;
+
+          for (h = 0; h < g; ++h) {
+            e[f + h] = a[b + h] + c[d + h] & 255;
+          }
+        }
+      }
+
+      function Hf(a, b, c, d, e, f, g) {
+        if (null == a) Rb(null, null, c, d, e, f, g);else {
+          var h = a[b + 0],
+              k = h,
+              l = h,
+              m;
+
+          for (m = 0; m < g; ++m) {
+            h = a[b + m], k = l + h - k, l = c[d + m] + (k & -256 ? 0 > k ? 0 : 255 : k) & 255, k = h, e[f + m] = l;
+          }
+        }
+      }
+
+      function Le(a, b, c, d) {
+        var e = b.width,
+            f = b.o;
+        x(null != a && null != b);
+        if (0 > c || 0 >= d || c + d > f) return null;
+
+        if (!a.Cc) {
+          if (null == a.ga) {
+            a.ga = new Ff();
+            var g;
+            (g = null == a.ga) || (g = b.width * b.o, x(0 == a.Gb.length), a.Gb = V(g), a.Uc = 0, null == a.Gb ? g = 0 : (a.mb = a.Gb, a.nb = a.Uc, a.rc = null, g = 1), g = !g);
+
+            if (!g) {
+              g = a.ga;
+              var h = a.Fa,
+                  k = a.P,
+                  l = a.qc,
+                  m = a.mb,
+                  n = a.nb,
+                  r = k + 1,
+                  q = l - 1,
+                  t = g.l;
+              x(null != h && null != m && null != b);
+              ia[0] = null;
+              ia[1] = Rb;
+              ia[2] = Gf;
+              ia[3] = Hf;
+              g.ca = m;
+              g.tb = n;
+              g.c = b.width;
+              g.i = b.height;
+              x(0 < g.c && 0 < g.i);
+              if (1 >= l) b = 0;else if (g.$a = h[k + 0] >> 0 & 3, g.Z = h[k + 0] >> 2 & 3, g.Lc = h[k + 0] >> 4 & 3, k = h[k + 0] >> 6 & 3, 0 > g.$a || 1 < g.$a || 4 <= g.Z || 1 < g.Lc || k) b = 0;else if (t.put = kc, t.ac = gc, t.bc = lc, t.ma = g, t.width = b.width, t.height = b.height, t.Da = b.Da, t.v = b.v, t.va = b.va, t.j = b.j, t.o = b.o, g.$a) b: {
+                x(1 == g.$a), b = Bc();
+
+                c: for (;;) {
+                  if (null == b) {
+                    b = 0;
+                    break b;
+                  }
+
+                  x(null != g);
+                  g.mc = b;
+                  b.c = g.c;
+                  b.i = g.i;
+                  b.l = g.l;
+                  b.l.ma = g;
+                  b.l.width = g.c;
+                  b.l.height = g.i;
+                  b.a = 0;
+                  cb(b.m, h, r, q);
+                  if (!rb(g.c, g.i, 1, b, null)) break c;
+                  1 == b.ab && 3 == b.gc[0].hc && yc(b.s) ? (g.ic = 1, h = b.c * b.i, b.Ta = null, b.Ua = 0, b.V = V(h), b.Ba = 0, null == b.V ? (b.a = 1, b = 0) : b = 1) : (g.ic = 0, b = Ec(b, g.c));
+                  if (!b) break c;
+                  b = 1;
+                  break b;
+                }
+
+                g.mc = null;
+                b = 0;
+              } else b = q >= g.c * g.i;
+              g = !b;
+            }
+
+            if (g) return null;
+            1 != a.ga.Lc ? a.Ga = 0 : d = f - c;
+          }
+
+          x(null != a.ga);
+          x(c + d <= f);
+
+          a: {
+            h = a.ga;
+            b = h.c;
+            f = h.l.o;
+
+            if (0 == h.$a) {
+              r = a.rc;
+              q = a.Vc;
+              t = a.Fa;
+              k = a.P + 1 + c * b;
+              l = a.mb;
+              m = a.nb + c * b;
+              x(k <= a.P + a.qc);
+              if (0 != h.Z) for (x(null != ia[h.Z]), g = 0; g < d; ++g) {
+                ia[h.Z](r, q, t, k, l, m, b), r = l, q = m, m += b, k += b;
+              } else for (g = 0; g < d; ++g) {
+                I(l, m, t, k, b), r = l, q = m, m += b, k += b;
+              }
+              a.rc = r;
+              a.Vc = q;
+            } else {
+              x(null != h.mc);
+              b = c + d;
+              g = h.mc;
+              x(null != g);
+              x(b <= g.i);
+              if (g.C >= b) b = 1;else if (h.ic || Aa(), h.ic) {
+                var h = g.V,
+                    r = g.Ba,
+                    q = g.c,
+                    v = g.i,
+                    t = 1,
+                    k = g.$ / q,
+                    l = g.$ % q,
+                    m = g.m,
+                    n = g.s,
+                    p = g.$,
+                    u = q * v,
+                    w = q * b,
+                    y = n.wc,
+                    A = p < w ? ha(n, l, k) : null;
+                x(p <= u);
+                x(b <= v);
+                x(yc(n));
+
+                c: for (;;) {
+                  for (; !m.h && p < w;) {
+                    l & y || (A = ha(n, l, k));
+                    x(null != A);
+                    Sa(m);
+                    v = ua(A.G[0], A.H[0], m);
+                    if (256 > v) h[r + p] = v, ++p, ++l, l >= q && (l = 0, ++k, k <= b && !(k % 16) && Ib(g, k));else if (280 > v) {
+                      var v = ib(v - 256, m);
+                      var E = ua(A.G[4], A.H[4], m);
+                      Sa(m);
+                      E = ib(E, m);
+                      E = nc(q, E);
+
+                      if (p >= E && u - p >= v) {
+                        var B;
+
+                        for (B = 0; B < v; ++B) {
+                          h[r + p + B] = h[r + p + B - E];
+                        }
+                      } else {
+                        t = 0;
+                        break c;
+                      }
+
+                      p += v;
+
+                      for (l += v; l >= q;) {
+                        l -= q, ++k, k <= b && !(k % 16) && Ib(g, k);
+                      }
+
+                      p < w && l & y && (A = ha(n, l, k));
+                    } else {
+                      t = 0;
+                      break c;
+                    }
+                    x(m.h == db(m));
+                  }
+
+                  Ib(g, k > b ? b : k);
+                  break c;
+                }
+
+                !t || m.h && p < u ? (t = 0, g.a = m.h ? 5 : 3) : g.$ = p;
+                b = t;
+              } else b = Jb(g, g.V, g.Ba, g.c, g.i, b, se);
+
+              if (!b) {
+                d = 0;
+                break a;
+              }
+            }
+
+            c + d >= f && (a.Cc = 1);
+            d = 1;
+          }
+
+          if (!d) return null;
+          if (a.Cc && (d = a.ga, null != d && (d.mc = null), a.ga = null, 0 < a.Ga)) return alert("todo:WebPDequantizeLevels"), null;
+        }
+
+        return a.nb + c * e;
+      }
+
+      function If(a, b, c, d, e, f) {
+        for (; 0 < e--;) {
+          var g = a,
+              h = b + (c ? 1 : 0),
+              k = a,
+              l = b + (c ? 0 : 3),
+              m;
+
+          for (m = 0; m < d; ++m) {
+            var n = k[l + 4 * m];
+            255 != n && (n *= 32897, g[h + 4 * m + 0] = g[h + 4 * m + 0] * n >> 23, g[h + 4 * m + 1] = g[h + 4 * m + 1] * n >> 23, g[h + 4 * m + 2] = g[h + 4 * m + 2] * n >> 23);
+          }
+
+          b += f;
+        }
+      }
+
+      function Jf(a, b, c, d, e) {
+        for (; 0 < d--;) {
+          var f;
+
+          for (f = 0; f < c; ++f) {
+            var g = a[b + 2 * f + 0],
+                h = a[b + 2 * f + 1],
+                k = h & 15,
+                l = 4369 * k,
+                h = (h & 240 | h >> 4) * l >> 16;
+            a[b + 2 * f + 0] = (g & 240 | g >> 4) * l >> 16 & 240 | (g & 15 | g << 4) * l >> 16 >> 4 & 15;
+            a[b + 2 * f + 1] = h & 240 | k;
+          }
+
+          b += e;
+        }
+      }
+
+      function Kf(a, b, c, d, e, f, g, h) {
+        var k = 255,
+            l,
+            m;
+
+        for (m = 0; m < e; ++m) {
+          for (l = 0; l < d; ++l) {
+            var n = a[b + l];
+            f[g + 4 * l] = n;
+            k &= n;
+          }
+
+          b += c;
+          g += h;
+        }
+
+        return 255 != k;
+      }
+
+      function Lf(a, b, c, d, e) {
+        var f;
+
+        for (f = 0; f < e; ++f) {
+          c[d + f] = a[b + f] >> 8;
+        }
+      }
+
+      function Aa() {
+        za = If;
+        vc = Jf;
+        fc = Kf;
+        Fc = Lf;
+      }
+
+      function va(a, b, c) {
+        self[a] = function (a, e, f, g, h, k, l, m, n, r, q, t, v, p, u, w, y) {
+          var d,
+              E = y - 1 >> 1;
+          var B = h[k + 0] | l[m + 0] << 16;
+          var C = n[r + 0] | q[t + 0] << 16;
+          x(null != a);
+          var z = 3 * B + C + 131074 >> 2;
+          b(a[e + 0], z & 255, z >> 16, v, p);
+          null != f && (z = 3 * C + B + 131074 >> 2, b(f[g + 0], z & 255, z >> 16, u, w));
+
+          for (d = 1; d <= E; ++d) {
+            var D = h[k + d] | l[m + d] << 16;
+            var G = n[r + d] | q[t + d] << 16;
+            var F = B + D + C + G + 524296;
+            var H = F + 2 * (D + C) >> 3;
+            F = F + 2 * (B + G) >> 3;
+            z = H + B >> 1;
+            B = F + D >> 1;
+            b(a[e + 2 * d - 1], z & 255, z >> 16, v, p + (2 * d - 1) * c);
+            b(a[e + 2 * d - 0], B & 255, B >> 16, v, p + (2 * d - 0) * c);
+            null != f && (z = F + C >> 1, B = H + G >> 1, b(f[g + 2 * d - 1], z & 255, z >> 16, u, w + (2 * d - 1) * c), b(f[g + 2 * d + 0], B & 255, B >> 16, u, w + (2 * d + 0) * c));
+            B = D;
+            C = G;
+          }
+
+          y & 1 || (z = 3 * B + C + 131074 >> 2, b(a[e + y - 1], z & 255, z >> 16, v, p + (y - 1) * c), null != f && (z = 3 * C + B + 131074 >> 2, b(f[g + y - 1], z & 255, z >> 16, u, w + (y - 1) * c)));
+        };
+      }
+
+      function ic() {
+        P[Ca] = Mf;
+        P[Ua] = nd;
+        P[tc] = Nf;
+        P[Va] = od;
+        P[ya] = pd;
+        P[Db] = qd;
+        P[wc] = Of;
+        P[zb] = nd;
+        P[Ab] = od;
+        P[Ja] = pd;
+        P[Bb] = qd;
+      }
+
+      function Sb(a) {
+        return a & ~Pf ? 0 > a ? 0 : 255 : a >> rd;
+      }
+
+      function bb(a, b) {
+        return Sb((19077 * a >> 8) + (26149 * b >> 8) - 14234);
+      }
+
+      function nb(a, b, c) {
+        return Sb((19077 * a >> 8) - (6419 * b >> 8) - (13320 * c >> 8) + 8708);
+      }
+
+      function Pa(a, b) {
+        return Sb((19077 * a >> 8) + (33050 * b >> 8) - 17685);
+      }
+
+      function Ga(a, b, c, d, e) {
+        d[e + 0] = bb(a, c);
+        d[e + 1] = nb(a, b, c);
+        d[e + 2] = Pa(a, b);
+      }
+
+      function Tb(a, b, c, d, e) {
+        d[e + 0] = Pa(a, b);
+        d[e + 1] = nb(a, b, c);
+        d[e + 2] = bb(a, c);
+      }
+
+      function sd(a, b, c, d, e) {
+        var f = nb(a, b, c);
+        b = f << 3 & 224 | Pa(a, b) >> 3;
+        d[e + 0] = bb(a, c) & 248 | f >> 5;
+        d[e + 1] = b;
+      }
+
+      function td(a, b, c, d, e) {
+        var f = Pa(a, b) & 240 | 15;
+        d[e + 0] = bb(a, c) & 240 | nb(a, b, c) >> 4;
+        d[e + 1] = f;
+      }
+
+      function ud(a, b, c, d, e) {
+        d[e + 0] = 255;
+        Ga(a, b, c, d, e + 1);
+      }
+
+      function vd(a, b, c, d, e) {
+        Tb(a, b, c, d, e);
+        d[e + 3] = 255;
+      }
+
+      function wd(a, b, c, d, e) {
+        Ga(a, b, c, d, e);
+        d[e + 3] = 255;
+      }
+
+      function ga(a, b) {
+        return 0 > a ? 0 : a > b ? b : a;
+      }
+
+      function la(a, b, c) {
+        self[a] = function (a, e, f, g, h, k, l, m, n) {
+          for (var d = m + (n & -2) * c; m != d;) {
+            b(a[e + 0], f[g + 0], h[k + 0], l, m), b(a[e + 1], f[g + 0], h[k + 0], l, m + c), e += 2, ++g, ++k, m += 2 * c;
+          }
+
+          n & 1 && b(a[e + 0], f[g + 0], h[k + 0], l, m);
+        };
+      }
+
+      function xd(a, b, c) {
+        return 0 == c ? 0 == a ? 0 == b ? 6 : 5 : 0 == b ? 4 : 0 : c;
+      }
+
+      function yd(a, b, c, d, e) {
+        switch (a >>> 30) {
+          case 3:
+            Za(b, c, d, e, 0);
+            break;
+
+          case 2:
+            fd(b, c, d, e);
+            break;
+
+          case 1:
+            pa(b, c, d, e);
+        }
+      }
+
+      function Oc(a, b) {
+        var c,
+            d,
+            e = b.M,
+            f = b.Nb,
+            g = a.oc,
+            h = a.pc + 40,
+            k = a.oc,
+            l = a.pc + 584,
+            m = a.oc,
+            n = a.pc + 600;
+
+        for (c = 0; 16 > c; ++c) {
+          g[h + 32 * c - 1] = 129;
+        }
+
+        for (c = 0; 8 > c; ++c) {
+          k[l + 32 * c - 1] = 129, m[n + 32 * c - 1] = 129;
+        }
+
+        0 < e ? g[h - 1 - 32] = k[l - 1 - 32] = m[n - 1 - 32] = 129 : (M(g, h - 32 - 1, 127, 21), M(k, l - 32 - 1, 127, 9), M(m, n - 32 - 1, 127, 9));
+
+        for (d = 0; d < a.za; ++d) {
+          var r = b.ya[b.aa + d];
+
+          if (0 < d) {
+            for (c = -1; 16 > c; ++c) {
+              I(g, h + 32 * c - 4, g, h + 32 * c + 12, 4);
+            }
+
+            for (c = -1; 8 > c; ++c) {
+              I(k, l + 32 * c - 4, k, l + 32 * c + 4, 4), I(m, n + 32 * c - 4, m, n + 32 * c + 4, 4);
+            }
+          }
+
+          var q = a.Gd,
+              t = a.Hd + d,
+              v = r.ad,
+              p = r.Hc;
+          0 < e && (I(g, h - 32, q[t].y, 0, 16), I(k, l - 32, q[t].f, 0, 8), I(m, n - 32, q[t].ea, 0, 8));
+
+          if (r.Za) {
+            var u = g;
+            var w = h - 32 + 16;
+            0 < e && (d >= a.za - 1 ? M(u, w, q[t].y[15], 4) : I(u, w, q[t + 1].y, 0, 4));
+
+            for (c = 0; 4 > c; c++) {
+              u[w + 128 + c] = u[w + 256 + c] = u[w + 384 + c] = u[w + 0 + c];
+            }
+
+            for (c = 0; 16 > c; ++c, p <<= 2) {
+              u = g, w = h + zd[c], W[r.Ob[c]](u, w), yd(p, v, 16 * +c, u, w);
+            }
+          } else if (u = xd(d, e, r.Ob[0]), Y[u](g, h), 0 != p) for (c = 0; 16 > c; ++c, p <<= 2) {
+            yd(p, v, 16 * +c, g, h + zd[c]);
+          }
+
+          c = r.Gc;
+          u = xd(d, e, r.Dd);
+          ka[u](k, l);
+          ka[u](m, n);
+          r = c >> 0;
+          p = v;
+          u = k;
+          w = l;
+          r & 255 && (r & 170 ? Nb(p, 256, u, w) : Ob(p, 256, u, w));
+          c >>= 8;
+          r = m;
+          p = n;
+          c & 255 && (c & 170 ? Nb(v, 320, r, p) : Ob(v, 320, r, p));
+          e < a.Ub - 1 && (I(q[t].y, 0, g, h + 480, 16), I(q[t].f, 0, k, l + 224, 8), I(q[t].ea, 0, m, n + 224, 8));
+          c = 8 * f * a.B;
+          q = a.sa;
+          t = a.ta + 16 * d + 16 * f * a.R;
+          v = a.qa;
+          r = a.ra + 8 * d + c;
+          p = a.Ha;
+          u = a.Ia + 8 * d + c;
+
+          for (c = 0; 16 > c; ++c) {
+            I(q, t + c * a.R, g, h + 32 * c, 16);
+          }
+
+          for (c = 0; 8 > c; ++c) {
+            I(v, r + c * a.B, k, l + 32 * c, 8), I(p, u + c * a.B, m, n + 32 * c, 8);
+          }
+        }
+      }
+
+      function Ad(a, b, c, d, e, f, g, h, k) {
+        var l = [0],
+            m = [0],
+            n = 0,
+            r = null != k ? k.kd : 0,
+            q = null != k ? k : new md();
+        if (null == a || 12 > c) return 7;
+        q.data = a;
+        q.w = b;
+        q.ha = c;
+        b = [b];
+        c = [c];
+        q.gb = [q.gb];
+
+        a: {
+          var t = b;
+          var v = c;
+          var p = q.gb;
+          x(null != a);
+          x(null != v);
+          x(null != p);
+          p[0] = 0;
+
+          if (12 <= v[0] && !fa(a, t[0], "RIFF")) {
+            if (fa(a, t[0] + 8, "WEBP")) {
+              p = 3;
+              break a;
+            }
+
+            var u = Ha(a, t[0] + 4);
+
+            if (12 > u || 4294967286 < u) {
+              p = 3;
+              break a;
+            }
+
+            if (r && u > v[0] - 8) {
+              p = 7;
+              break a;
+            }
+
+            p[0] = u;
+            t[0] += 12;
+            v[0] -= 12;
+          }
+
+          p = 0;
+        }
+
+        if (0 != p) return p;
+        u = 0 < q.gb[0];
+
+        for (c = c[0];;) {
+          t = [0];
+          n = [n];
+
+          a: {
+            var w = a;
+            v = b;
+            p = c;
+            var y = n,
+                A = l,
+                z = m,
+                B = t;
+            y[0] = 0;
+            if (8 > p[0]) p = 7;else {
+              if (!fa(w, v[0], "VP8X")) {
+                if (10 != Ha(w, v[0] + 4)) {
+                  p = 3;
+                  break a;
+                }
+
+                if (18 > p[0]) {
+                  p = 7;
+                  break a;
+                }
+
+                var C = Ha(w, v[0] + 8);
+                var D = 1 + Yb(w, v[0] + 12);
+                w = 1 + Yb(w, v[0] + 15);
+
+                if (2147483648 <= D * w) {
+                  p = 3;
+                  break a;
+                }
+
+                null != B && (B[0] = C);
+                null != A && (A[0] = D);
+                null != z && (z[0] = w);
+                v[0] += 18;
+                p[0] -= 18;
+                y[0] = 1;
+              }
+
+              p = 0;
+            }
+          }
+
+          n = n[0];
+          t = t[0];
+          if (0 != p) return p;
+          v = !!(t & 2);
+          if (!u && n) return 3;
+          null != f && (f[0] = !!(t & 16));
+          null != g && (g[0] = v);
+          null != h && (h[0] = 0);
+          g = l[0];
+          t = m[0];
+
+          if (n && v && null == k) {
+            p = 0;
+            break;
+          }
+
+          if (4 > c) {
+            p = 7;
+            break;
+          }
+
+          if (u && n || !u && !n && !fa(a, b[0], "ALPH")) {
+            c = [c];
+            q.na = [q.na];
+            q.P = [q.P];
+            q.Sa = [q.Sa];
+
+            a: {
+              C = a;
+              p = b;
+              u = c;
+              var y = q.gb,
+                  A = q.na,
+                  z = q.P,
+                  B = q.Sa;
+              D = 22;
+              x(null != C);
+              x(null != u);
+              w = p[0];
+              var F = u[0];
+              x(null != A);
+              x(null != B);
+              A[0] = null;
+              z[0] = null;
+
+              for (B[0] = 0;;) {
+                p[0] = w;
+                u[0] = F;
+
+                if (8 > F) {
+                  p = 7;
+                  break a;
+                }
+
+                var G = Ha(C, w + 4);
+
+                if (4294967286 < G) {
+                  p = 3;
+                  break a;
+                }
+
+                var H = 8 + G + 1 & -2;
+                D += H;
+
+                if (0 < y && D > y) {
+                  p = 3;
+                  break a;
+                }
+
+                if (!fa(C, w, "VP8 ") || !fa(C, w, "VP8L")) {
+                  p = 0;
+                  break a;
+                }
+
+                if (F[0] < H) {
+                  p = 7;
+                  break a;
+                }
+
+                fa(C, w, "ALPH") || (A[0] = C, z[0] = w + 8, B[0] = G);
+                w += H;
+                F -= H;
+              }
+            }
+
+            c = c[0];
+            q.na = q.na[0];
+            q.P = q.P[0];
+            q.Sa = q.Sa[0];
+            if (0 != p) break;
+          }
+
+          c = [c];
+          q.Ja = [q.Ja];
+          q.xa = [q.xa];
+
+          a: if (y = a, p = b, u = c, A = q.gb[0], z = q.Ja, B = q.xa, C = p[0], w = !fa(y, C, "VP8 "), D = !fa(y, C, "VP8L"), x(null != y), x(null != u), x(null != z), x(null != B), 8 > u[0]) p = 7;else {
+            if (w || D) {
+              y = Ha(y, C + 4);
+
+              if (12 <= A && y > A - 12) {
+                p = 3;
+                break a;
+              }
+
+              if (r && y > u[0] - 8) {
+                p = 7;
+                break a;
+              }
+
+              z[0] = y;
+              p[0] += 8;
+              u[0] -= 8;
+              B[0] = D;
+            } else B[0] = 5 <= u[0] && 47 == y[C + 0] && !(y[C + 4] >> 5), z[0] = u[0];
+
+            p = 0;
+          }
+
+          c = c[0];
+          q.Ja = q.Ja[0];
+          q.xa = q.xa[0];
+          b = b[0];
+          if (0 != p) break;
+          if (4294967286 < q.Ja) return 3;
+          null == h || v || (h[0] = q.xa ? 2 : 1);
+          g = [g];
+          t = [t];
+
+          if (q.xa) {
+            if (5 > c) {
+              p = 7;
+              break;
+            }
+
+            h = g;
+            r = t;
+            v = f;
+            null == a || 5 > c ? a = 0 : 5 <= c && 47 == a[b + 0] && !(a[b + 4] >> 5) ? (u = [0], y = [0], A = [0], z = new Ra(), cb(z, a, b, c), mc(z, u, y, A) ? (null != h && (h[0] = u[0]), null != r && (r[0] = y[0]), null != v && (v[0] = A[0]), a = 1) : a = 0) : a = 0;
+          } else {
+            if (10 > c) {
+              p = 7;
+              break;
+            }
+
+            h = t;
+            null == a || 10 > c || !Jc(a, b + 3, c - 3) ? a = 0 : (r = a[b + 0] | a[b + 1] << 8 | a[b + 2] << 16, v = (a[b + 7] << 8 | a[b + 6]) & 16383, a = (a[b + 9] << 8 | a[b + 8]) & 16383, r & 1 || 3 < (r >> 1 & 7) || !(r >> 4 & 1) || r >> 5 >= q.Ja || !v || !a ? a = 0 : (g && (g[0] = v), h && (h[0] = a), a = 1));
+          }
+
+          if (!a) return 3;
+          g = g[0];
+          t = t[0];
+          if (n && (l[0] != g || m[0] != t)) return 3;
+          null != k && (k[0] = q, k.offset = b - k.w, x(4294967286 > b - k.w), x(k.offset == k.ha - c));
+          break;
+        }
+
+        return 0 == p || 7 == p && n && null == k ? (null != f && (f[0] |= null != q.na && 0 < q.na.length), null != d && (d[0] = g), null != e && (e[0] = t), 0) : p;
+      }
+
+      function hc(a, b, c) {
+        var d = b.width,
+            e = b.height,
+            f = 0,
+            g = 0,
+            h = d,
+            k = e;
+        b.Da = null != a && 0 < a.Da;
+        if (b.Da && (h = a.cd, k = a.bd, f = a.v, g = a.j, 11 > c || (f &= -2, g &= -2), 0 > f || 0 > g || 0 >= h || 0 >= k || f + h > d || g + k > e)) return 0;
+        b.v = f;
+        b.j = g;
+        b.va = f + h;
+        b.o = g + k;
+        b.U = h;
+        b.T = k;
+        b.da = null != a && 0 < a.da;
+
+        if (b.da) {
+          c = [a.ib];
+          f = [a.hb];
+          if (!bc(h, k, c, f)) return 0;
+          b.ib = c[0];
+          b.hb = f[0];
+        }
+
+        b.ob = null != a && a.ob;
+        b.Kb = null == a || !a.Sd;
+        b.da && (b.ob = b.ib < 3 * d / 4 && b.hb < 3 * e / 4, b.Kb = 0);
+        return 1;
+      }
+
+      function Bd(a) {
+        if (null == a) return 2;
+
+        if (11 > a.S) {
+          var b = a.f.RGBA;
+          b.fb += (a.height - 1) * b.A;
+          b.A = -b.A;
+        } else b = a.f.kb, a = a.height, b.O += (a - 1) * b.fa, b.fa = -b.fa, b.N += (a - 1 >> 1) * b.Ab, b.Ab = -b.Ab, b.W += (a - 1 >> 1) * b.Db, b.Db = -b.Db, null != b.F && (b.J += (a - 1) * b.lb, b.lb = -b.lb);
+
+        return 0;
+      }
+
+      function Cd(a, b, c, d) {
+        if (null == d || 0 >= a || 0 >= b) return 2;
+
+        if (null != c) {
+          if (c.Da) {
+            var e = c.cd,
+                f = c.bd,
+                g = c.v & -2,
+                h = c.j & -2;
+            if (0 > g || 0 > h || 0 >= e || 0 >= f || g + e > a || h + f > b) return 2;
+            a = e;
+            b = f;
+          }
+
+          if (c.da) {
+            e = [c.ib];
+            f = [c.hb];
+            if (!bc(a, b, e, f)) return 2;
+            a = e[0];
+            b = f[0];
+          }
+        }
+
+        d.width = a;
+        d.height = b;
+
+        a: {
+          var k = d.width;
+          var l = d.height;
+          a = d.S;
+          if (0 >= k || 0 >= l || !(a >= Ca && 13 > a)) a = 2;else {
+            if (0 >= d.Rd && null == d.sd) {
+              var g = f = e = b = 0,
+                  h = k * Dd[a],
+                  m = h * l;
+              11 > a || (b = (k + 1) / 2, f = (l + 1) / 2 * b, 12 == a && (e = k, g = e * l));
+              l = V(m + 2 * f + g);
+
+              if (null == l) {
+                a = 1;
+                break a;
+              }
+
+              d.sd = l;
+              11 > a ? (k = d.f.RGBA, k.eb = l, k.fb = 0, k.A = h, k.size = m) : (k = d.f.kb, k.y = l, k.O = 0, k.fa = h, k.Fd = m, k.f = l, k.N = 0 + m, k.Ab = b, k.Cd = f, k.ea = l, k.W = 0 + m + f, k.Db = b, k.Ed = f, 12 == a && (k.F = l, k.J = 0 + m + 2 * f), k.Tc = g, k.lb = e);
+            }
+
+            b = 1;
+            e = d.S;
+            f = d.width;
+            g = d.height;
+            if (e >= Ca && 13 > e) {
+              if (11 > e) a = d.f.RGBA, h = Math.abs(a.A), b &= h * (g - 1) + f <= a.size, b &= h >= f * Dd[e], b &= null != a.eb;else {
+                a = d.f.kb;
+                h = (f + 1) / 2;
+                m = (g + 1) / 2;
+                k = Math.abs(a.fa);
+                var l = Math.abs(a.Ab),
+                    n = Math.abs(a.Db),
+                    r = Math.abs(a.lb),
+                    q = r * (g - 1) + f;
+                b &= k * (g - 1) + f <= a.Fd;
+                b &= l * (m - 1) + h <= a.Cd;
+                b &= n * (m - 1) + h <= a.Ed;
+                b = b & k >= f & l >= h & n >= h;
+                b &= null != a.y;
+                b &= null != a.f;
+                b &= null != a.ea;
+                12 == e && (b &= r >= f, b &= q <= a.Tc, b &= null != a.F);
+              }
+            } else b = 0;
+            a = b ? 0 : 2;
+          }
+        }
+
+        if (0 != a) return a;
+        null != c && c.fd && (a = Bd(d));
+        return a;
+      }
+
+      var xb = 64,
+          Hd = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215],
+          Gd = 24,
+          ob = 32,
+          Xb = 8,
+          Id = [0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7];
+      X("Predictor0", "PredictorAdd0");
+
+      self.Predictor0 = function () {
+        return 4278190080;
+      };
+
+      self.Predictor1 = function (a) {
+        return a;
+      };
+
+      self.Predictor2 = function (a, b, c) {
+        return b[c + 0];
+      };
+
+      self.Predictor3 = function (a, b, c) {
+        return b[c + 1];
+      };
+
+      self.Predictor4 = function (a, b, c) {
+        return b[c - 1];
+      };
+
+      self.Predictor5 = function (a, b, c) {
+        return aa(aa(a, b[c + 1]), b[c + 0]);
+      };
+
+      self.Predictor6 = function (a, b, c) {
+        return aa(a, b[c - 1]);
+      };
+
+      self.Predictor7 = function (a, b, c) {
+        return aa(a, b[c + 0]);
+      };
+
+      self.Predictor8 = function (a, b, c) {
+        return aa(b[c - 1], b[c + 0]);
+      };
+
+      self.Predictor9 = function (a, b, c) {
+        return aa(b[c + 0], b[c + 1]);
+      };
+
+      self.Predictor10 = function (a, b, c) {
+        return aa(aa(a, b[c - 1]), aa(b[c + 0], b[c + 1]));
+      };
+
+      self.Predictor11 = function (a, b, c) {
+        var d = b[c + 0];
+        b = b[c - 1];
+        return 0 >= Ia(d >> 24 & 255, a >> 24 & 255, b >> 24 & 255) + Ia(d >> 16 & 255, a >> 16 & 255, b >> 16 & 255) + Ia(d >> 8 & 255, a >> 8 & 255, b >> 8 & 255) + Ia(d & 255, a & 255, b & 255) ? d : a;
+      };
+
+      self.Predictor12 = function (a, b, c) {
+        var d = b[c + 0];
+        b = b[c - 1];
+        return (sa((a >> 24 & 255) + (d >> 24 & 255) - (b >> 24 & 255)) << 24 | sa((a >> 16 & 255) + (d >> 16 & 255) - (b >> 16 & 255)) << 16 | sa((a >> 8 & 255) + (d >> 8 & 255) - (b >> 8 & 255)) << 8 | sa((a & 255) + (d & 255) - (b & 255))) >>> 0;
+      };
+
+      self.Predictor13 = function (a, b, c) {
+        var d = b[c - 1];
+        a = aa(a, b[c + 0]);
+        return (eb(a >> 24 & 255, d >> 24 & 255) << 24 | eb(a >> 16 & 255, d >> 16 & 255) << 16 | eb(a >> 8 & 255, d >> 8 & 255) << 8 | eb(a >> 0 & 255, d >> 0 & 255)) >>> 0;
+      };
+
+      var ee = self.PredictorAdd0;
+      self.PredictorAdd1 = cc;
+      X("Predictor2", "PredictorAdd2");
+      X("Predictor3", "PredictorAdd3");
+      X("Predictor4", "PredictorAdd4");
+      X("Predictor5", "PredictorAdd5");
+      X("Predictor6", "PredictorAdd6");
+      X("Predictor7", "PredictorAdd7");
+      X("Predictor8", "PredictorAdd8");
+      X("Predictor9", "PredictorAdd9");
+      X("Predictor10", "PredictorAdd10");
+      X("Predictor11", "PredictorAdd11");
+      X("Predictor12", "PredictorAdd12");
+      X("Predictor13", "PredictorAdd13");
+      var fe = self.PredictorAdd2;
+      ec("ColorIndexInverseTransform", "MapARGB", "32b", function (a) {
+        return a >> 8 & 255;
+      }, function (a) {
+        return a;
+      });
+      ec("VP8LColorIndexInverseTransformAlpha", "MapAlpha", "8b", function (a) {
+        return a;
+      }, function (a) {
+        return a >> 8 & 255;
+      });
+      var rc = self.ColorIndexInverseTransform,
+          ke = self.MapARGB,
+          he = self.VP8LColorIndexInverseTransformAlpha,
+          le = self.MapAlpha,
+          pc,
+          qc = self.VP8LPredictorsAdd = [];
+      qc.length = 16;
+      (self.VP8LPredictors = []).length = 16;
+      (self.VP8LPredictorsAdd_C = []).length = 16;
+      (self.VP8LPredictors_C = []).length = 16;
+      var Fb,
+          sc,
+          Gb,
+          Hb,
+          xc,
+          uc,
+          bd = V(511),
+          cd = V(2041),
+          dd = V(225),
+          ed = V(767),
+          ad = 0,
+          Qb = cd,
+          mb = dd,
+          R = ed,
+          U = bd,
+          Ca = 0,
+          Ua = 1,
+          tc = 2,
+          Va = 3,
+          ya = 4,
+          Db = 5,
+          wc = 6,
+          zb = 7,
+          Ab = 8,
+          Ja = 9,
+          Bb = 10,
+          pe = [2, 3, 7],
+          oe = [3, 3, 11],
+          Dc = [280, 256, 256, 256, 40],
+          qe = [0, 1, 1, 1, 0],
+          ne = [17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
+          de = [24, 7, 23, 25, 40, 6, 39, 41, 22, 26, 38, 42, 56, 5, 55, 57, 21, 27, 54, 58, 37, 43, 72, 4, 71, 73, 20, 28, 53, 59, 70, 74, 36, 44, 88, 69, 75, 52, 60, 3, 87, 89, 19, 29, 86, 90, 35, 45, 68, 76, 85, 91, 51, 61, 104, 2, 103, 105, 18, 30, 102, 106, 34, 46, 84, 92, 67, 77, 101, 107, 50, 62, 120, 1, 119, 121, 83, 93, 17, 31, 100, 108, 66, 78, 118, 122, 33, 47, 117, 123, 49, 63, 99, 109, 82, 94, 0, 116, 124, 65, 79, 16, 32, 98, 110, 48, 115, 125, 81, 95, 64, 114, 126, 97, 111, 80, 113, 127, 96, 112],
+          me = [2954, 2956, 2958, 2962, 2970, 2986, 3018, 3082, 3212, 3468, 3980, 5004],
+          ie = 8,
+          Lb = [4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 25, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 91, 93, 95, 96, 98, 100, 101, 102, 104, 106, 108, 110, 112, 114, 116, 118, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 143, 145, 148, 151, 154, 157],
+          Mb = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 119, 122, 125, 128, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173, 177, 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284],
+          oa = null,
+          He = [[173, 148, 140, 0], [176, 155, 140, 135, 0], [180, 157, 141, 134, 130, 0], [254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0]],
+          Ie = [0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15],
+          Mc = [-0, 1, -1, 2, -2, 3, 4, 6, -3, 5, -4, -5, -6, 7, -7, 8, -8, -9],
+          Fe = [[[[128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128]], [[253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128], [189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128], [106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128]], [[1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128], [181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128], [78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128]], [[1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128], [184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128], [77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128]], [[1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128], [170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128], [37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128]], [[1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128], [207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128], [102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128]], [[1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128], [177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128], [80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128]], [[1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128]]], [[[198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62], [131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1], [68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128]], [[1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128], [184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128], [81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128]], [[1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128], [99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128], [23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128]], [[1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128], [109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128], [44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128]], [[1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128], [94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128], [22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128]], [[1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128], [124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128], [35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128]], [[1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128], [121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128], [45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128]], [[1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128], [203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128], [137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128]]], [[[253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128], [175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128], [73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128]], [[1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128], [239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128], [155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128]], [[1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128], [201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128], [69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128]], [[1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128], [223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128], [141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128]], [[1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128], [190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128], [149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128]], [[1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128], [247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128], [240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128]], [[1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128], [213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128], [55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128]], [[128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128]]], [[[202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255], [126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128], [61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128]], [[1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128], [166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128], [39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128]], [[1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128], [124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128], [24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128]], [[1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128], [149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128], [28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128]], [[1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128], [123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128], [20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128]], [[1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128], [168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128], [47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128]], [[1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128], [141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128], [42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128]], [[1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128], [238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128]]]],
+          Ke = [[[231, 120, 48, 89, 115, 113, 120, 152, 112], [152, 179, 64, 126, 170, 118, 46, 70, 95], [175, 69, 143, 80, 85, 82, 72, 155, 103], [56, 58, 10, 171, 218, 189, 17, 13, 152], [114, 26, 17, 163, 44, 195, 21, 10, 173], [121, 24, 80, 195, 26, 62, 44, 64, 85], [144, 71, 10, 38, 171, 213, 144, 34, 26], [170, 46, 55, 19, 136, 160, 33, 206, 71], [63, 20, 8, 114, 114, 208, 12, 9, 226], [81, 40, 11, 96, 182, 84, 29, 16, 36]], [[134, 183, 89, 137, 98, 101, 106, 165, 148], [72, 187, 100, 130, 157, 111, 32, 75, 80], [66, 102, 167, 99, 74, 62, 40, 234, 128], [41, 53, 9, 178, 241, 141, 26, 8, 107], [74, 43, 26, 146, 73, 166, 49, 23, 157], [65, 38, 105, 160, 51, 52, 31, 115, 128], [104, 79, 12, 27, 217, 255, 87, 17, 7], [87, 68, 71, 44, 114, 51, 15, 186, 23], [47, 41, 14, 110, 182, 183, 21, 17, 194], [66, 45, 25, 102, 197, 189, 23, 18, 22]], [[88, 88, 147, 150, 42, 46, 45, 196, 205], [43, 97, 183, 117, 85, 38, 35, 179, 61], [39, 53, 200, 87, 26, 21, 43, 232, 171], [56, 34, 51, 104, 114, 102, 29, 93, 77], [39, 28, 85, 171, 58, 165, 90, 98, 64], [34, 22, 116, 206, 23, 34, 43, 166, 73], [107, 54, 32, 26, 51, 1, 81, 43, 31], [68, 25, 106, 22, 64, 171, 36, 225, 114], [34, 19, 21, 102, 132, 188, 16, 76, 124], [62, 18, 78, 95, 85, 57, 50, 48, 51]], [[193, 101, 35, 159, 215, 111, 89, 46, 111], [60, 148, 31, 172, 219, 228, 21, 18, 111], [112, 113, 77, 85, 179, 255, 38, 120, 114], [40, 42, 1, 196, 245, 209, 10, 25, 109], [88, 43, 29, 140, 166, 213, 37, 43, 154], [61, 63, 30, 155, 67, 45, 68, 1, 209], [100, 80, 8, 43, 154, 1, 51, 26, 71], [142, 78, 78, 16, 255, 128, 34, 197, 171], [41, 40, 5, 102, 211, 183, 4, 1, 221], [51, 50, 17, 168, 209, 192, 23, 25, 82]], [[138, 31, 36, 171, 27, 166, 38, 44, 229], [67, 87, 58, 169, 82, 115, 26, 59, 179], [63, 59, 90, 180, 59, 166, 93, 73, 154], [40, 40, 21, 116, 143, 209, 34, 39, 175], [47, 15, 16, 183, 34, 223, 49, 45, 183], [46, 17, 33, 183, 6, 98, 15, 32, 183], [57, 46, 22, 24, 128, 1, 54, 17, 37], [65, 32, 73, 115, 28, 128, 23, 128, 205], [40, 3, 9, 115, 51, 192, 18, 6, 223], [87, 37, 9, 115, 59, 77, 64, 21, 47]], [[104, 55, 44, 218, 9, 54, 53, 130, 226], [64, 90, 70, 205, 40, 41, 23, 26, 57], [54, 57, 112, 184, 5, 41, 38, 166, 213], [30, 34, 26, 133, 152, 116, 10, 32, 134], [39, 19, 53, 221, 26, 114, 32, 73, 255], [31, 9, 65, 234, 2, 15, 1, 118, 73], [75, 32, 12, 51, 192, 255, 160, 43, 51], [88, 31, 35, 67, 102, 85, 55, 186, 85], [56, 21, 23, 111, 59, 205, 45, 37, 192], [55, 38, 70, 124, 73, 102, 1, 34, 98]], [[125, 98, 42, 88, 104, 85, 117, 175, 82], [95, 84, 53, 89, 128, 100, 113, 101, 45], [75, 79, 123, 47, 51, 128, 81, 171, 1], [57, 17, 5, 71, 102, 57, 53, 41, 49], [38, 33, 13, 121, 57, 73, 26, 1, 85], [41, 10, 67, 138, 77, 110, 90, 47, 114], [115, 21, 2, 10, 102, 255, 166, 23, 6], [101, 29, 16, 10, 85, 128, 101, 196, 26], [57, 18, 10, 102, 102, 213, 34, 20, 43], [117, 20, 15, 36, 163, 128, 68, 1, 26]], [[102, 61, 71, 37, 34, 53, 31, 243, 192], [69, 60, 71, 38, 73, 119, 28, 222, 37], [68, 45, 128, 34, 1, 47, 11, 245, 171], [62, 17, 19, 70, 146, 85, 55, 62, 70], [37, 43, 37, 154, 100, 163, 85, 160, 1], [63, 9, 92, 136, 28, 64, 32, 201, 85], [75, 15, 9, 9, 64, 255, 184, 119, 16], [86, 6, 28, 5, 64, 255, 25, 248, 1], [56, 8, 17, 132, 137, 255, 55, 116, 128], [58, 15, 20, 82, 135, 57, 26, 121, 40]], [[164, 50, 31, 137, 154, 133, 25, 35, 218], [51, 103, 44, 131, 131, 123, 31, 6, 158], [86, 40, 64, 135, 148, 224, 45, 183, 128], [22, 26, 17, 131, 240, 154, 14, 1, 209], [45, 16, 21, 91, 64, 222, 7, 1, 197], [56, 21, 39, 155, 60, 138, 23, 102, 213], [83, 12, 13, 54, 192, 255, 68, 47, 28], [85, 26, 85, 85, 128, 128, 32, 146, 171], [18, 11, 7, 63, 144, 171, 4, 4, 246], [35, 27, 10, 146, 174, 171, 12, 26, 128]], [[190, 80, 35, 99, 180, 80, 126, 54, 45], [85, 126, 47, 87, 176, 51, 41, 20, 32], [101, 75, 128, 139, 118, 146, 116, 128, 85], [56, 41, 15, 176, 236, 85, 37, 9, 62], [71, 30, 17, 119, 118, 255, 17, 18, 138], [101, 38, 60, 138, 55, 70, 43, 26, 142], [146, 36, 19, 30, 171, 255, 97, 27, 20], [138, 45, 61, 62, 219, 1, 81, 188, 64], [32, 41, 20, 117, 151, 142, 20, 21, 163], [112, 19, 12, 61, 195, 128, 48, 4, 24]]],
+          Ee = [[[[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255], [223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255], [249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255], [234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255], [239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255], [251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255], [250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]], [[[217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255], [234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255]], [[255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255]], [[255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255], [249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255], [247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255], [250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]], [[[186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255], [234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255], [251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255]], [[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255]], [[255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]], [[[248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255], [248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255]], [[255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255], [246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255], [252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255]], [[255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255], [248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255], [253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255]], [[255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255], [245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255], [253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255], [252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255], [249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255], [250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]], [[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]]]],
+          Ge = [0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 0],
+          Nc,
+          Y = [],
+          W = [],
+          ka = [],
+          Za,
+          fd,
+          Nb,
+          pa,
+          Ob,
+          Xc,
+          Tc,
+          Yc,
+          Uc,
+          Zc,
+          Vc,
+          $c,
+          Wc,
+          Rc,
+          Pc,
+          Sc,
+          Qc,
+          re = 1,
+          Cc = 2,
+          ia = [],
+          za,
+          vc,
+          fc,
+          Fc,
+          P = [];
+      va("UpsampleRgbLinePair", Ga, 3);
+      va("UpsampleBgrLinePair", Tb, 3);
+      va("UpsampleRgbaLinePair", wd, 4);
+      va("UpsampleBgraLinePair", vd, 4);
+      va("UpsampleArgbLinePair", ud, 4);
+      va("UpsampleRgba4444LinePair", td, 2);
+      va("UpsampleRgb565LinePair", sd, 2);
+      var Mf = self.UpsampleRgbLinePair,
+          Nf = self.UpsampleBgrLinePair,
+          nd = self.UpsampleRgbaLinePair,
+          od = self.UpsampleBgraLinePair,
+          pd = self.UpsampleArgbLinePair,
+          qd = self.UpsampleRgba4444LinePair,
+          Of = self.UpsampleRgb565LinePair,
+          Wa = 16,
+          Ba = 1 << Wa - 1,
+          ta = -227,
+          Eb = 482,
+          rd = 6,
+          Pf = (256 << rd) - 1,
+          jc = 0,
+          Yd = V(256),
+          ae = V(256),
+          $d = V(256),
+          Zd = V(256),
+          be = V(Eb - ta),
+          ce = V(Eb - ta);
+      la("YuvToRgbRow", Ga, 3);
+      la("YuvToBgrRow", Tb, 3);
+      la("YuvToRgbaRow", wd, 4);
+      la("YuvToBgraRow", vd, 4);
+      la("YuvToArgbRow", ud, 4);
+      la("YuvToRgba4444Row", td, 2);
+      la("YuvToRgb565Row", sd, 2);
+      var zd = [0, 4, 8, 12, 128, 132, 136, 140, 256, 260, 264, 268, 384, 388, 392, 396],
+          Ya = [0, 2, 8],
+          Qf = [8, 7, 6, 4, 4, 2, 2, 2, 1, 1, 1, 1],
+          Ne = 1;
+
+      this.WebPDecodeRGBA = function (a, b, c, d, e) {
+        var f = Ua;
+        var g = new Cf(),
+            h = new Cb();
+        g.ba = h;
+        h.S = f;
+        h.width = [h.width];
+        h.height = [h.height];
+        var k = h.width;
+        var l = h.height,
+            m = new Td();
+        if (null == m || null == a) var n = 2;else x(null != m), n = Ad(a, b, c, m.width, m.height, m.Pd, m.Qd, m.format, null);
+        0 != n ? k = 0 : (null != k && (k[0] = m.width[0]), null != l && (l[0] = m.height[0]), k = 1);
+
+        if (k) {
+          h.width = h.width[0];
+          h.height = h.height[0];
+          null != d && (d[0] = h.width);
+          null != e && (e[0] = h.height);
+
+          b: {
+            d = new Oa();
+            e = new md();
+            e.data = a;
+            e.w = b;
+            e.ha = c;
+            e.kd = 1;
+            b = [0];
+            x(null != e);
+            a = Ad(e.data, e.w, e.ha, null, null, null, b, null, e);
+            (0 == a || 7 == a) && b[0] && (a = 4);
+            b = a;
+
+            if (0 == b) {
+              x(null != g);
+              d.data = e.data;
+              d.w = e.w + e.offset;
+              d.ha = e.ha - e.offset;
+              d.put = kc;
+              d.ac = gc;
+              d.bc = lc;
+              d.ma = g;
+
+              if (e.xa) {
+                a = Bc();
+
+                if (null == a) {
+                  g = 1;
+                  break b;
+                }
+
+                if (te(a, d)) {
+                  b = Cd(d.width, d.height, g.Oa, g.ba);
+
+                  if (d = 0 == b) {
+                    c: {
+                      d = a;
+
+                      d: for (;;) {
+                        if (null == d) {
+                          d = 0;
+                          break c;
+                        }
+
+                        x(null != d.s.yc);
+                        x(null != d.s.Ya);
+                        x(0 < d.s.Wb);
+                        c = d.l;
+                        x(null != c);
+                        e = c.ma;
+                        x(null != e);
+
+                        if (0 != d.xb) {
+                          d.ca = e.ba;
+                          d.tb = e.tb;
+                          x(null != d.ca);
+
+                          if (!hc(e.Oa, c, Va)) {
+                            d.a = 2;
+                            break d;
+                          }
+
+                          if (!Ec(d, c.width)) break d;
+                          if (c.da) break d;
+                          (c.da || hb(d.ca.S)) && Aa();
+                          11 > d.ca.S || (alert("todo:WebPInitConvertARGBToYUV"), null != d.ca.f.kb.F && Aa());
+
+                          if (d.Pb && 0 < d.s.ua && null == d.s.vb.X && !Zb(d.s.vb, d.s.Wa.Xa)) {
+                            d.a = 1;
+                            break d;
+                          }
+
+                          d.xb = 0;
+                        }
+
+                        if (!Jb(d, d.V, d.Ba, d.c, d.i, c.o, ge)) break d;
+                        e.Dc = d.Ma;
+                        d = 1;
+                        break c;
+                      }
+
+                      x(0 != d.a);
+                      d = 0;
+                    }
+
+                    d = !d;
+                  }
+
+                  d && (b = a.a);
+                } else b = a.a;
+              } else {
+                a = new Ce();
+
+                if (null == a) {
+                  g = 1;
+                  break b;
+                }
+
+                a.Fa = e.na;
+                a.P = e.P;
+                a.qc = e.Sa;
+
+                if (Kc(a, d)) {
+                  if (b = Cd(d.width, d.height, g.Oa, g.ba), 0 == b) {
+                    a.Aa = 0;
+                    c = g.Oa;
+                    e = a;
+                    x(null != e);
+
+                    if (null != c) {
+                      k = c.Md;
+                      k = 0 > k ? 0 : 100 < k ? 255 : 255 * k / 100;
+
+                      if (0 < k) {
+                        for (l = m = 0; 4 > l; ++l) {
+                          n = e.pb[l], 12 > n.lc && (n.ia = k * Qf[0 > n.lc ? 0 : n.lc] >> 3), m |= n.ia;
+                        }
+
+                        m && (alert("todo:VP8InitRandom"), e.ia = 1);
+                      }
+
+                      e.Ga = c.Id;
+                      100 < e.Ga ? e.Ga = 100 : 0 > e.Ga && (e.Ga = 0);
+                    }
+
+                    Me(a, d) || (b = a.a);
+                  }
+                } else b = a.a;
+              }
+
+              0 == b && null != g.Oa && g.Oa.fd && (b = Bd(g.ba));
+            }
+
+            g = b;
+          }
+
+          f = 0 != g ? null : 11 > f ? h.f.RGBA.eb : h.f.kb.y;
+        } else f = null;
+
+        return f;
+      };
+
+      var Dd = [3, 4, 3, 4, 4, 2, 2, 4, 4, 4, 2, 1, 1];
+    };
+
+    new _WebPDecoder();
+    /** @license
+     * Copyright (c) 2017 Dominik Homberger
+    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+    https://webpjs.appspot.com
+    WebPRiffParser dominikhlbg@gmail.com
+    */
+
+    function memcmp(data, data_off, str, size) {
+      for (var i = 0; i < size; i++) {
+        if (data[data_off + i] != str.charCodeAt(i)) return true;
+      }
+
+      return false;
+    }
+
+    function GetTag(data, data_off) {
+      var str = "";
+
+      for (var i = 0; i < 4; i++) {
+        str += String.fromCharCode(data[data_off++]);
+      }
+
+      return str;
+    }
+
+    function GetLE16(data, data_off) {
+      return data[data_off + 0] << 0 | data[data_off + 1] << 8;
+    }
+
+    function GetLE24(data, data_off) {
+      return (data[data_off + 0] << 0 | data[data_off + 1] << 8 | data[data_off + 2] << 16) >>> 0;
+    }
+
+    function GetLE32(data, data_off) {
+      return (data[data_off + 0] << 0 | data[data_off + 1] << 8 | data[data_off + 2] << 16 | data[data_off + 3] << 24) >>> 0;
+    }
+
+    function WebPRiffParser(src, src_off) {
+      var imagearray = {};
+      var i = 0;
+      var alpha_chunk = false;
+      var alpha_size = 0;
+      var alpha_offset = 0;
+      imagearray["frames"] = [];
+      if (memcmp(src, src_off, "RIFF", 4)) return;
+      src_off += 4;
+      var riff_size = GetLE32(src, src_off) + 8;
+      src_off += 8;
+
+      while (src_off < src.length) {
+        var fourcc = GetTag(src, src_off);
+        src_off += 4;
+        var payload_size = GetLE32(src, src_off);
+        src_off += 4;
+        var payload_size_padded = payload_size + (payload_size & 1);
+
+        switch (fourcc) {
+          case "VP8 ":
+          case "VP8L":
+            if (typeof imagearray["frames"][i] === "undefined") imagearray["frames"][i] = {};
+            var obj = imagearray["frames"][i];
+            var height = [0];
+            var width = [0];
+            obj["src_off"] = alpha_chunk ? alpha_offset : src_off - 8;
+            obj["src_size"] = alpha_size + payload_size + 8; //var rgba = webpdecoder.WebPDecodeRGBA(src,(alpha_chunk?alpha_offset:src_off-8),alpha_size+payload_size+8,width,height);
+            //imagearray[i]={'rgba':rgba,'width':width[0],'height':height[0]};
+
+            i++;
+
+            if (alpha_chunk) {
+              alpha_chunk = false;
+              alpha_size = 0;
+              alpha_offset = 0;
+            }
+
+            break;
+
+          case "VP8X":
+            var obj = imagearray["header"] = {};
+            var feature_flags = obj["feature_flags"] = src[src_off];
+            var src_off_ = src_off + 4;
+            var canvas_width = obj["canvas_width"] = 1 + GetLE24(src, src_off_);
+            src_off_ += 3;
+            var canvas_height = obj["canvas_height"] = 1 + GetLE24(src, src_off_);
+            src_off_ += 3;
+            break;
+
+          case "ALPH":
+            alpha_chunk = true;
+            alpha_size = payload_size_padded + 8;
+            alpha_offset = src_off - 8;
+            break;
+
+          case "ANIM":
+            var obj = imagearray["header"];
+            var bgcolor = obj["bgcolor"] = GetLE32(src, src_off);
+            src_off_ = src_off + 4;
+            var loop_count = obj["loop_count"] = GetLE16(src, src_off_);
+            src_off_ += 2;
+            break;
+
+          case "ANMF":
+            var offset_x = 0,
+                offset_y = 0,
+                width = 0,
+                height = 0,
+                duration = 0,
+                blend = 0,
+                dispose = 0,
+                temp = 0;
+            var obj = imagearray["frames"][i] = {};
+            obj["offset_x"] = offset_x = 2 * GetLE24(src, src_off);
+            src_off += 3;
+            obj["offset_y"] = offset_y = 2 * GetLE24(src, src_off);
+            src_off += 3;
+            obj["width"] = width = 1 + GetLE24(src, src_off);
+            src_off += 3;
+            obj["height"] = height = 1 + GetLE24(src, src_off);
+            src_off += 3;
+            obj["duration"] = duration = GetLE24(src, src_off);
+            src_off += 3;
+            temp = src[src_off++];
+            obj["dispose"] = dispose = temp & 1;
+            obj["blend"] = blend = temp >> 1 & 1;
+            break;
+        }
+
+        if (fourcc != "ANMF") src_off += payload_size_padded;
+      }
+
+      return imagearray;
+    }
+
+    var height = [0];
+    var width = [0];
+    var pixels = [];
+    var webpdecoder = new _WebPDecoder();
+    var response = imageData;
+    var imagearray = WebPRiffParser(response, 0);
+    imagearray["response"] = response;
+    imagearray["rgbaoutput"] = true;
+    imagearray["dataurl"] = false;
+    var header = imagearray["header"] ? imagearray["header"] : null;
+    var frames = imagearray["frames"] ? imagearray["frames"] : null;
+
+    if (header) {
+      header["loop_counter"] = header["loop_count"];
+      height = [header["canvas_height"]];
+      width = [header["canvas_width"]];
+
+      for (var f = 0; f < frames.length; f++) {
+        if (frames[f]["blend"] == 0) {
+          break;
+        }
+      }
+    }
+
+    var frame = frames[0];
+    var rgba = webpdecoder.WebPDecodeRGBA(response, frame["src_off"], frame["src_size"], width, height);
+    frame["rgba"] = rgba;
+    frame["imgwidth"] = width[0];
+    frame["imgheight"] = height[0];
+
+    for (var i = 0; i < width[0] * height[0] * 4; i++) {
+      pixels[i] = rgba[i];
+    }
+
+    this.width = width;
+    this.height = height;
+    this.data = pixels;
+    return this;
+  }
+
+  WebPDecoder.prototype.getData = function () {
+    return this.data;
+  };
+
+  /**
+   * @license
+   * Copyright (c) 2019 Aras Abbasi
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+  /**
+   * jsPDF webp Support PlugIn
+   *
+   * @name webp_support
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+
+    jsPDFAPI.processWEBP = function (imageData, index, alias, compression) {
+      var reader = new WebPDecoder(imageData, false);
+      var width = reader.width,
+          height = reader.height;
+      var qu = 100;
+      var pixels = reader.getData();
+      var rawImageData = {
+        data: pixels,
+        width: width,
+        height: height
+      };
+      var encoder = new JPEGEncoder(qu);
+      var data = encoder.encode(rawImageData, qu);
+      return jsPDFAPI.processJPEG.call(this, data, index, alias, compression);
+    };
+  })(jsPDF.API);
+
+  /**
+   * @license
+   *
+   * Copyright (c) 2021 Antti Palola, https://github.com/Pantura
+   *
+   * Permission is hereby granted, free of charge, to any person obtaining
+   * a copy of this software and associated documentation files (the
+   * "Software"), to deal in the Software without restriction, including
+   * without limitation the rights to use, copy, modify, merge, publish,
+   * distribute, sublicense, and/or sell copies of the Software, and to
+   * permit persons to whom the Software is furnished to do so, subject to
+   * the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be
+   * included in all copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+   * ====================================================================
+   */
+  /**
+   * jsPDF RGBA array PlugIn
+   * @name rgba_support
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+    /**
+     * @name processRGBA
+     * @function
+     *
+     * Process RGBA Array. This is a one-dimension array with pixel data [red, green, blue, alpha, red, green, ...].
+     * RGBA array data can be obtained from DOM canvas getImageData.
+     * @ignore
+     */
+
+    jsPDFAPI.processRGBA = function (imageData, index, alias) {
+
+      var imagePixels = imageData.data;
+      var length = imagePixels.length; // jsPDF takes alpha data separately so extract that.
+
+      var rgbOut = new Uint8Array(length / 4 * 3);
+      var alphaOut = new Uint8Array(length / 4);
+      var outIndex = 0;
+      var alphaIndex = 0;
+
+      for (var i = 0; i < length; i += 4) {
+        var r = imagePixels[i];
+        var g = imagePixels[i + 1];
+        var b = imagePixels[i + 2];
+        var alpha = imagePixels[i + 3];
+        rgbOut[outIndex++] = r;
+        rgbOut[outIndex++] = g;
+        rgbOut[outIndex++] = b;
+        alphaOut[alphaIndex++] = alpha;
+      }
+
+      var rgbData = this.__addimage__.arrayBufferToBinaryString(rgbOut);
+
+      var alphaData = this.__addimage__.arrayBufferToBinaryString(alphaOut);
+
+      return {
+        alpha: alphaData,
+        data: rgbData,
+        index: index,
+        alias: alias,
+        colorSpace: "DeviceRGB",
+        bitsPerComponent: 8,
+        width: imageData.width,
+        height: imageData.height
+      };
+    };
+  })(jsPDF.API);
+
+  /**
+   * @license
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+  /**
+   * jsPDF setLanguage Plugin
+   *
+   * @name setLanguage
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+    /**
+     * Add Language Tag to the generated PDF
+     *
+     * @name setLanguage
+     * @function
+     * @param {string} langCode The Language code as ISO-639-1 (e.g. 'en') or as country language code (e.g. 'en-GB').
+     * @returns {jsPDF}
+     * @example
+     * var doc = new jsPDF()
+     * doc.text(10, 10, 'This is a test')
+     * doc.setLanguage("en-US")
+     * doc.save('english.pdf')
+     */
+
+    jsPDFAPI.setLanguage = function (langCode) {
+
+      var langCodes = {
+        af: "Afrikaans",
+        sq: "Albanian",
+        ar: "Arabic (Standard)",
+        "ar-DZ": "Arabic (Algeria)",
+        "ar-BH": "Arabic (Bahrain)",
+        "ar-EG": "Arabic (Egypt)",
+        "ar-IQ": "Arabic (Iraq)",
+        "ar-JO": "Arabic (Jordan)",
+        "ar-KW": "Arabic (Kuwait)",
+        "ar-LB": "Arabic (Lebanon)",
+        "ar-LY": "Arabic (Libya)",
+        "ar-MA": "Arabic (Morocco)",
+        "ar-OM": "Arabic (Oman)",
+        "ar-QA": "Arabic (Qatar)",
+        "ar-SA": "Arabic (Saudi Arabia)",
+        "ar-SY": "Arabic (Syria)",
+        "ar-TN": "Arabic (Tunisia)",
+        "ar-AE": "Arabic (U.A.E.)",
+        "ar-YE": "Arabic (Yemen)",
+        an: "Aragonese",
+        hy: "Armenian",
+        as: "Assamese",
+        ast: "Asturian",
+        az: "Azerbaijani",
+        eu: "Basque",
+        be: "Belarusian",
+        bn: "Bengali",
+        bs: "Bosnian",
+        br: "Breton",
+        bg: "Bulgarian",
+        my: "Burmese",
+        ca: "Catalan",
+        ch: "Chamorro",
+        ce: "Chechen",
+        zh: "Chinese",
+        "zh-HK": "Chinese (Hong Kong)",
+        "zh-CN": "Chinese (PRC)",
+        "zh-SG": "Chinese (Singapore)",
+        "zh-TW": "Chinese (Taiwan)",
+        cv: "Chuvash",
+        co: "Corsican",
+        cr: "Cree",
+        hr: "Croatian",
+        cs: "Czech",
+        da: "Danish",
+        nl: "Dutch (Standard)",
+        "nl-BE": "Dutch (Belgian)",
+        en: "English",
+        "en-AU": "English (Australia)",
+        "en-BZ": "English (Belize)",
+        "en-CA": "English (Canada)",
+        "en-IE": "English (Ireland)",
+        "en-JM": "English (Jamaica)",
+        "en-NZ": "English (New Zealand)",
+        "en-PH": "English (Philippines)",
+        "en-ZA": "English (South Africa)",
+        "en-TT": "English (Trinidad & Tobago)",
+        "en-GB": "English (United Kingdom)",
+        "en-US": "English (United States)",
+        "en-ZW": "English (Zimbabwe)",
+        eo: "Esperanto",
+        et: "Estonian",
+        fo: "Faeroese",
+        fj: "Fijian",
+        fi: "Finnish",
+        fr: "French (Standard)",
+        "fr-BE": "French (Belgium)",
+        "fr-CA": "French (Canada)",
+        "fr-FR": "French (France)",
+        "fr-LU": "French (Luxembourg)",
+        "fr-MC": "French (Monaco)",
+        "fr-CH": "French (Switzerland)",
+        fy: "Frisian",
+        fur: "Friulian",
+        gd: "Gaelic (Scots)",
+        "gd-IE": "Gaelic (Irish)",
+        gl: "Galacian",
+        ka: "Georgian",
+        de: "German (Standard)",
+        "de-AT": "German (Austria)",
+        "de-DE": "German (Germany)",
+        "de-LI": "German (Liechtenstein)",
+        "de-LU": "German (Luxembourg)",
+        "de-CH": "German (Switzerland)",
+        el: "Greek",
+        gu: "Gujurati",
+        ht: "Haitian",
+        he: "Hebrew",
+        hi: "Hindi",
+        hu: "Hungarian",
+        is: "Icelandic",
+        id: "Indonesian",
+        iu: "Inuktitut",
+        ga: "Irish",
+        it: "Italian (Standard)",
+        "it-CH": "Italian (Switzerland)",
+        ja: "Japanese",
+        kn: "Kannada",
+        ks: "Kashmiri",
+        kk: "Kazakh",
+        km: "Khmer",
+        ky: "Kirghiz",
+        tlh: "Klingon",
+        ko: "Korean",
+        "ko-KP": "Korean (North Korea)",
+        "ko-KR": "Korean (South Korea)",
+        la: "Latin",
+        lv: "Latvian",
+        lt: "Lithuanian",
+        lb: "Luxembourgish",
+        mk: "North Macedonia",
+        ms: "Malay",
+        ml: "Malayalam",
+        mt: "Maltese",
+        mi: "Maori",
+        mr: "Marathi",
+        mo: "Moldavian",
+        nv: "Navajo",
+        ng: "Ndonga",
+        ne: "Nepali",
+        no: "Norwegian",
+        nb: "Norwegian (Bokmal)",
+        nn: "Norwegian (Nynorsk)",
+        oc: "Occitan",
+        or: "Oriya",
+        om: "Oromo",
+        fa: "Persian",
+        "fa-IR": "Persian/Iran",
+        pl: "Polish",
+        pt: "Portuguese",
+        "pt-BR": "Portuguese (Brazil)",
+        pa: "Punjabi",
+        "pa-IN": "Punjabi (India)",
+        "pa-PK": "Punjabi (Pakistan)",
+        qu: "Quechua",
+        rm: "Rhaeto-Romanic",
+        ro: "Romanian",
+        "ro-MO": "Romanian (Moldavia)",
+        ru: "Russian",
+        "ru-MO": "Russian (Moldavia)",
+        sz: "Sami (Lappish)",
+        sg: "Sango",
+        sa: "Sanskrit",
+        sc: "Sardinian",
+        sd: "Sindhi",
+        si: "Singhalese",
+        sr: "Serbian",
+        sk: "Slovak",
+        sl: "Slovenian",
+        so: "Somani",
+        sb: "Sorbian",
+        es: "Spanish",
+        "es-AR": "Spanish (Argentina)",
+        "es-BO": "Spanish (Bolivia)",
+        "es-CL": "Spanish (Chile)",
+        "es-CO": "Spanish (Colombia)",
+        "es-CR": "Spanish (Costa Rica)",
+        "es-DO": "Spanish (Dominican Republic)",
+        "es-EC": "Spanish (Ecuador)",
+        "es-SV": "Spanish (El Salvador)",
+        "es-GT": "Spanish (Guatemala)",
+        "es-HN": "Spanish (Honduras)",
+        "es-MX": "Spanish (Mexico)",
+        "es-NI": "Spanish (Nicaragua)",
+        "es-PA": "Spanish (Panama)",
+        "es-PY": "Spanish (Paraguay)",
+        "es-PE": "Spanish (Peru)",
+        "es-PR": "Spanish (Puerto Rico)",
+        "es-ES": "Spanish (Spain)",
+        "es-UY": "Spanish (Uruguay)",
+        "es-VE": "Spanish (Venezuela)",
+        sx: "Sutu",
+        sw: "Swahili",
+        sv: "Swedish",
+        "sv-FI": "Swedish (Finland)",
+        "sv-SV": "Swedish (Sweden)",
+        ta: "Tamil",
+        tt: "Tatar",
+        te: "Teluga",
+        th: "Thai",
+        tig: "Tigre",
+        ts: "Tsonga",
+        tn: "Tswana",
+        tr: "Turkish",
+        tk: "Turkmen",
+        uk: "Ukrainian",
+        hsb: "Upper Sorbian",
+        ur: "Urdu",
+        ve: "Venda",
+        vi: "Vietnamese",
+        vo: "Volapuk",
+        wa: "Walloon",
+        cy: "Welsh",
+        xh: "Xhosa",
+        ji: "Yiddish",
+        zu: "Zulu"
+      };
+
+      if (this.internal.languageSettings === undefined) {
+        this.internal.languageSettings = {};
+        this.internal.languageSettings.isSubscribed = false;
+      }
+
+      if (langCodes[langCode] !== undefined) {
+        this.internal.languageSettings.languageCode = langCode;
+
+        if (this.internal.languageSettings.isSubscribed === false) {
+          this.internal.events.subscribe("putCatalog", function () {
+            this.internal.write("/Lang (" + this.internal.languageSettings.languageCode + ")");
+          });
+          this.internal.languageSettings.isSubscribed = true;
+        }
+      }
+
+      return this;
+    };
+  })(jsPDF.API);
+
+  /**
+   * jsPDF split_text_to_size plugin
+   *
+   * @name split_text_to_size
+   * @module
+   */
+
+  (function (API) {
+    /**
+     * Returns an array of length matching length of the 'word' string, with each
+     * cell occupied by the width of the char in that position.
+     *
+     * @name getCharWidthsArray
+     * @function
+     * @param {string} text
+     * @param {Object} options
+     * @returns {Array}
+     */
+
+    var getCharWidthsArray = API.getCharWidthsArray = function (text, options) {
+      options = options || {};
+      var activeFont = options.font || this.internal.getFont();
+      var fontSize = options.fontSize || this.internal.getFontSize();
+      var charSpace = options.charSpace || this.internal.getCharSpace();
+      var widths = options.widths ? options.widths : activeFont.metadata.Unicode.widths;
+      var widthsFractionOf = widths.fof ? widths.fof : 1;
+      var kerning = options.kerning ? options.kerning : activeFont.metadata.Unicode.kerning;
+      var kerningFractionOf = kerning.fof ? kerning.fof : 1;
+      var doKerning = options.doKerning === false ? false : true;
+      var kerningValue = 0;
+      var i;
+      var length = text.length;
+      var char_code;
+      var prior_char_code = 0; //for kerning
+
+      var default_char_width = widths[0] || widthsFractionOf;
+      var output = [];
+
+      for (i = 0; i < length; i++) {
+        char_code = text.charCodeAt(i);
+
+        if (typeof activeFont.metadata.widthOfString === "function") {
+          output.push((activeFont.metadata.widthOfGlyph(activeFont.metadata.characterToGlyph(char_code)) + charSpace * (1000 / fontSize) || 0) / 1000);
+        } else {
+          if (doKerning && _typeof(kerning[char_code]) === "object" && !isNaN(parseInt(kerning[char_code][prior_char_code], 10))) {
+            kerningValue = kerning[char_code][prior_char_code] / kerningFractionOf;
+          } else {
+            kerningValue = 0;
+          }
+
+          output.push((widths[char_code] || default_char_width) / widthsFractionOf + kerningValue);
+        }
+
+        prior_char_code = char_code;
+      }
+
+      return output;
+    };
+    /**
+     * Returns a widths of string in a given font, if the font size is set as 1 point.
+     *
+     * In other words, this is "proportional" value. For 1 unit of font size, the length
+     * of the string will be that much.
+     *
+     * Multiply by font size to get actual width in *points*
+     * Then divide by 72 to get inches or divide by (72/25.6) to get 'mm' etc.
+     *
+     * @name getStringUnitWidth
+     * @public
+     * @function
+     * @param {string} text
+     * @param {string} options
+     * @returns {number} result
+     */
+
+
+    var getStringUnitWidth = API.getStringUnitWidth = function (text, options) {
+      options = options || {};
+      var fontSize = options.fontSize || this.internal.getFontSize();
+      var font = options.font || this.internal.getFont();
+      var charSpace = options.charSpace || this.internal.getCharSpace();
+      var result = 0;
+
+      if (API.processArabic) {
+        text = API.processArabic(text);
+      }
+
+      if (typeof font.metadata.widthOfString === "function") {
+        result = font.metadata.widthOfString(text, fontSize, charSpace) / fontSize;
+      } else {
+        result = getCharWidthsArray.apply(this, arguments).reduce(function (pv, cv) {
+          return pv + cv;
+        }, 0);
+      }
+
+      return result;
+    };
+    /**
+    returns array of lines
+    */
+
+
+    var splitLongWord = function splitLongWord(word, widths_array, firstLineMaxLen, maxLen) {
+      var answer = []; // 1st, chop off the piece that can fit on the hanging line.
+
+      var i = 0,
+          l = word.length,
+          workingLen = 0;
+
+      while (i !== l && workingLen + widths_array[i] < firstLineMaxLen) {
+        workingLen += widths_array[i];
+        i++;
+      } // this is first line.
+
+
+      answer.push(word.slice(0, i)); // 2nd. Split the rest into maxLen pieces.
+
+      var startOfLine = i;
+      workingLen = 0;
+
+      while (i !== l) {
+        if (workingLen + widths_array[i] > maxLen) {
+          answer.push(word.slice(startOfLine, i));
+          workingLen = 0;
+          startOfLine = i;
+        }
+
+        workingLen += widths_array[i];
+        i++;
+      }
+
+      if (startOfLine !== i) {
+        answer.push(word.slice(startOfLine, i));
+      }
+
+      return answer;
+    }; // Note, all sizing inputs for this function must be in "font measurement units"
+    // By default, for PDF, it's "point".
+
+
+    var splitParagraphIntoLines = function splitParagraphIntoLines(text, maxlen, options) {
+      // at this time works only on Western scripts, ones with space char
+      // separating the words. Feel free to expand.
+      if (!options) {
+        options = {};
+      }
+
+      var line = [],
+          lines = [line],
+          line_length = options.textIndent || 0,
+          separator_length = 0,
+          current_word_length = 0,
+          word,
+          widths_array,
+          words = text.split(" "),
+          spaceCharWidth = getCharWidthsArray.apply(this, [" ", options])[0],
+          i,
+          l,
+          tmp,
+          lineIndent;
+
+      if (options.lineIndent === -1) {
+        lineIndent = words[0].length + 2;
+      } else {
+        lineIndent = options.lineIndent || 0;
+      }
+
+      if (lineIndent) {
+        var pad = Array(lineIndent).join(" "),
+            wrds = [];
+        words.map(function (wrd) {
+          wrd = wrd.split(/\s*\n/);
+
+          if (wrd.length > 1) {
+            wrds = wrds.concat(wrd.map(function (wrd, idx) {
+              return (idx && wrd.length ? "\n" : "") + wrd;
+            }));
+          } else {
+            wrds.push(wrd[0]);
+          }
+        });
+        words = wrds;
+        lineIndent = getStringUnitWidth.apply(this, [pad, options]);
+      }
+
+      for (i = 0, l = words.length; i < l; i++) {
+        var force = 0;
+        word = words[i];
+
+        if (lineIndent && word[0] == "\n") {
+          word = word.substr(1);
+          force = 1;
+        }
+
+        widths_array = getCharWidthsArray.apply(this, [word, options]);
+        current_word_length = widths_array.reduce(function (pv, cv) {
+          return pv + cv;
+        }, 0);
+
+        if (line_length + separator_length + current_word_length > maxlen || force) {
+          if (current_word_length > maxlen) {
+            // this happens when you have space-less long URLs for example.
+            // we just chop these to size. We do NOT insert hiphens
+            tmp = splitLongWord.apply(this, [word, widths_array, maxlen - (line_length + separator_length), maxlen]); // first line we add to existing line object
+
+            line.push(tmp.shift()); // it's ok to have extra space indicator there
+            // last line we make into new line object
+
+            line = [tmp.pop()]; // lines in the middle we apped to lines object as whole lines
+
+            while (tmp.length) {
+              lines.push([tmp.shift()]); // single fragment occupies whole line
+            }
+
+            current_word_length = widths_array.slice(word.length - (line[0] ? line[0].length : 0)).reduce(function (pv, cv) {
+              return pv + cv;
+            }, 0);
+          } else {
+            // just put it on a new line
+            line = [word];
+          } // now we attach new line to lines
+
+
+          lines.push(line);
+          line_length = current_word_length + lineIndent;
+          separator_length = spaceCharWidth;
+        } else {
+          line.push(word);
+          line_length += separator_length + current_word_length;
+          separator_length = spaceCharWidth;
+        }
+      }
+
+      var postProcess;
+
+      if (lineIndent) {
+        postProcess = function postProcess(ln, idx) {
+          return (idx ? pad : "") + ln.join(" ");
+        };
+      } else {
+        postProcess = function postProcess(ln) {
+          return ln.join(" ");
+        };
+      }
+
+      return lines.map(postProcess);
+    };
+    /**
+     * Splits a given string into an array of strings. Uses 'size' value
+     * (in measurement units declared as default for the jsPDF instance)
+     * and the font's "widths" and "Kerning" tables, where available, to
+     * determine display length of a given string for a given font.
+     *
+     * We use character's 100% of unit size (height) as width when Width
+     * table or other default width is not available.
+     *
+     * @name splitTextToSize
+     * @public
+     * @function
+     * @param {string} text Unencoded, regular JavaScript (Unicode, UTF-16 / UCS-2) string.
+     * @param {number} size Nominal number, measured in units default to this instance of jsPDF.
+     * @param {Object} options Optional flags needed for chopper to do the right thing.
+     * @returns {Array} array Array with strings chopped to size.
+     */
+
+
+    API.splitTextToSize = function (text, maxlen, options) {
+
+      options = options || {};
+
+      var fsize = options.fontSize || this.internal.getFontSize(),
+          newOptions = function (options) {
+        var widths = {
+          0: 1
+        },
+            kerning = {};
+
+        if (!options.widths || !options.kerning) {
+          var f = this.internal.getFont(options.fontName, options.fontStyle),
+              encoding = "Unicode"; // NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE
+          // Actual JavaScript-native String's 16bit char codes used.
+          // no multi-byte logic here
+
+          if (f.metadata[encoding]) {
+            return {
+              widths: f.metadata[encoding].widths || widths,
+              kerning: f.metadata[encoding].kerning || kerning
+            };
+          } else {
+            return {
+              font: f.metadata,
+              fontSize: this.internal.getFontSize(),
+              charSpace: this.internal.getCharSpace()
+            };
+          }
+        } else {
+          return {
+            widths: options.widths,
+            kerning: options.kerning
+          };
+        }
+      }.call(this, options); // first we split on end-of-line chars
+
+
+      var paragraphs;
+
+      if (Array.isArray(text)) {
+        paragraphs = text;
+      } else {
+        paragraphs = String(text).split(/\r?\n/);
+      } // now we convert size (max length of line) into "font size units"
+      // at present time, the "font size unit" is always 'point'
+      // 'proportional' means, "in proportion to font size"
+
+
+      var fontUnit_maxLen = 1.0 * this.internal.scaleFactor * maxlen / fsize; // at this time, fsize is always in "points" regardless of the default measurement unit of the doc.
+      // this may change in the future?
+      // until then, proportional_maxlen is likely to be in 'points'
+      // If first line is to be indented (shorter or longer) than maxLen
+      // we indicate that by using CSS-style "text-indent" option.
+      // here it's in font units too (which is likely 'points')
+      // it can be negative (which makes the first line longer than maxLen)
+
+      newOptions.textIndent = options.textIndent ? options.textIndent * 1.0 * this.internal.scaleFactor / fsize : 0;
+      newOptions.lineIndent = options.lineIndent;
+      var i,
+          l,
+          output = [];
+
+      for (i = 0, l = paragraphs.length; i < l; i++) {
+        output = output.concat(splitParagraphIntoLines.apply(this, [paragraphs[i], fontUnit_maxLen, newOptions]));
+      }
+
+      return output;
+    };
+  })(jsPDF.API);
+
+  /**
+   * This file adds the standard font metrics to jsPDF.
+   *
+   * Font metrics data is reprocessed derivative of contents of
+   * "Font Metrics for PDF Core 14 Fonts" package, which exhibits the following copyright and license:
+   *
+   * Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
+   *
+   * This file and the 14 PostScript(R) AFM files it accompanies may be used,
+   * copied, and distributed for any purpose and without charge, with or without
+   * modification, provided that all copyright notices are retained; that the AFM
+   * files are not distributed without this file; that all modifications to this
+   * file or any of the AFM files are prominently noted in the modified file(s);
+   * and that this paragraph is not modified. Adobe Systems has no responsibility
+   * or obligation to support the use of the AFM files.
+   *
+   * @name standard_fonts_metrics
+   * @module
+   */
+
+  (function (API) {
+
+    API.__fontmetrics__ = API.__fontmetrics__ || {};
+    var decoded = "0123456789abcdef",
+        encoded = "klmnopqrstuvwxyz",
+        mappingUncompress = {},
+        mappingCompress = {};
+
+    for (var i = 0; i < encoded.length; i++) {
+      mappingUncompress[encoded[i]] = decoded[i];
+      mappingCompress[decoded[i]] = encoded[i];
+    }
+
+    var hex = function hex(value) {
+      return "0x" + parseInt(value, 10).toString(16);
+    };
+
+    var compress = API.__fontmetrics__.compress = function (data) {
+      var vals = ["{"];
+      var value, keystring, valuestring, numberprefix;
+
+      for (var key in data) {
+        value = data[key];
+
+        if (!isNaN(parseInt(key, 10))) {
+          key = parseInt(key, 10);
+          keystring = hex(key).slice(2);
+          keystring = keystring.slice(0, -1) + mappingCompress[keystring.slice(-1)];
+        } else {
+          keystring = "'" + key + "'";
+        }
+
+        if (typeof value == "number") {
+          if (value < 0) {
+            valuestring = hex(value).slice(3);
+            numberprefix = "-";
+          } else {
+            valuestring = hex(value).slice(2);
+            numberprefix = "";
+          }
+
+          valuestring = numberprefix + valuestring.slice(0, -1) + mappingCompress[valuestring.slice(-1)];
+        } else {
+          if (_typeof(value) === "object") {
+            valuestring = compress(value);
+          } else {
+            throw new Error("Don't know what to do with value type " + _typeof(value) + ".");
+          }
+        }
+
+        vals.push(keystring + valuestring);
+      }
+
+      vals.push("}");
+      return vals.join("");
+    };
+    /**
+     * Uncompresses data compressed into custom, base16-like format.
+     *
+     * @public
+     * @function
+     * @param
+     * @returns {Type}
+     */
+
+
+    var uncompress = API.__fontmetrics__.uncompress = function (data) {
+      if (typeof data !== "string") {
+        throw new Error("Invalid argument passed to uncompress.");
+      }
+
+      var output = {},
+          sign = 1,
+          stringparts,
+          // undef. will be [] in string mode
+      activeobject = output,
+          parentchain = [],
+          parent_key_pair,
+          keyparts = "",
+          valueparts = "",
+          key,
+          // undef. will be Truthy when Key is resolved.
+      datalen = data.length - 1,
+          // stripping ending }
+      ch;
+
+      for (var i = 1; i < datalen; i += 1) {
+        // - { } ' are special.
+        ch = data[i];
+
+        if (ch == "'") {
+          if (stringparts) {
+            // end of string mode
+            key = stringparts.join("");
+            stringparts = undefined;
+          } else {
+            // start of string mode
+            stringparts = [];
+          }
+        } else if (stringparts) {
+          stringparts.push(ch);
+        } else if (ch == "{") {
+          // start of object
+          parentchain.push([activeobject, key]);
+          activeobject = {};
+          key = undefined;
+        } else if (ch == "}") {
+          // end of object
+          parent_key_pair = parentchain.pop();
+          parent_key_pair[0][parent_key_pair[1]] = activeobject;
+          key = undefined;
+          activeobject = parent_key_pair[0];
+        } else if (ch == "-") {
+          sign = -1;
+        } else {
+          // must be number
+          if (key === undefined) {
+            if (mappingUncompress.hasOwnProperty(ch)) {
+              keyparts += mappingUncompress[ch];
+              key = parseInt(keyparts, 16) * sign;
+              sign = +1;
+              keyparts = "";
+            } else {
+              keyparts += ch;
+            }
+          } else {
+            if (mappingUncompress.hasOwnProperty(ch)) {
+              valueparts += mappingUncompress[ch];
+              activeobject[key] = parseInt(valueparts, 16) * sign;
+              sign = +1;
+              key = undefined;
+              valueparts = "";
+            } else {
+              valueparts += ch;
+            }
+          }
+        }
+      }
+
+      return output;
+    }; // encoding = 'Unicode'
+    // NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE. NO clever BOM behavior
+    // Actual 16bit char codes used.
+    // no multi-byte logic here
+    // Unicode characters to WinAnsiEncoding:
+    // {402: 131, 8211: 150, 8212: 151, 8216: 145, 8217: 146, 8218: 130, 8220: 147, 8221: 148, 8222: 132, 8224: 134, 8225: 135, 8226: 149, 8230: 133, 8364: 128, 8240:137, 8249: 139, 8250: 155, 710: 136, 8482: 153, 338: 140, 339: 156, 732: 152, 352: 138, 353: 154, 376: 159, 381: 142, 382: 158}
+    // as you can see, all Unicode chars are outside of 0-255 range. No char code conflicts.
+    // this means that you can give Win cp1252 encoded strings to jsPDF for rendering directly
+    // as well as give strings with some (supported by these fonts) Unicode characters and
+    // these will be mapped to win cp1252
+    // for example, you can send char code (cp1252) 0x80 or (unicode) 0x20AC, getting "Euro" glyph displayed in both cases.
+
+
+    var encodingBlock = {
+      codePages: ["WinAnsiEncoding"],
+      WinAnsiEncoding: uncompress("{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}")
+    };
+    var encodings = {
+      Unicode: {
+        Courier: encodingBlock,
+        "Courier-Bold": encodingBlock,
+        "Courier-BoldOblique": encodingBlock,
+        "Courier-Oblique": encodingBlock,
+        Helvetica: encodingBlock,
+        "Helvetica-Bold": encodingBlock,
+        "Helvetica-BoldOblique": encodingBlock,
+        "Helvetica-Oblique": encodingBlock,
+        "Times-Roman": encodingBlock,
+        "Times-Bold": encodingBlock,
+        "Times-BoldItalic": encodingBlock,
+        "Times-Italic": encodingBlock //	, 'Symbol'
+        //	, 'ZapfDingbats'
+
+      }
+    };
+    var fontMetrics = {
+      Unicode: {
+        // all sizing numbers are n/fontMetricsFractionOf = one font size unit
+        // this means that if fontMetricsFractionOf = 1000, and letter A's width is 476, it's
+        // width is 476/1000 or 47.6% of its height (regardless of font size)
+        // At this time this value applies to "widths" and "kerning" numbers.
+        // char code 0 represents "default" (average) width - use it for chars missing in this table.
+        // key 'fof' represents the "fontMetricsFractionOf" value
+        "Courier-Oblique": uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
+        "Times-BoldItalic": uncompress("{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'kerning'{cl{4qu5kt5qt5rs17ss5ts}201s{201ss}201t{cks4lscmscnscoscpscls2wu2yu201ts}201x{2wu2yu}2k{201ts}2w{4qx5kx5ou5qx5rs17su5tu}2x{17su5tu5ou}2y{4qx5kx5ou5qx5rs17ss5ts}'fof'-6ofn{17sw5tw5ou5qw5rs}7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qs}3v{17su5tu5os5qs}7p{17su5tu}ck{4qu5kt5qt5rs17ss5ts}4l{4qu5kt5qt5rs17ss5ts}cm{4qu5kt5qt5rs17ss5ts}cn{4qu5kt5qt5rs17ss5ts}co{4qu5kt5qt5rs17ss5ts}cp{4qu5kt5qt5rs17ss5ts}6l{4qu5ou5qw5rt17su5tu}5q{ckuclucmucnucoucpu4lu}5r{ckuclucmucnucoucpu4lu}7q{cksclscmscnscoscps4ls}6p{4qu5ou5qw5rt17sw5tw}ek{4qu5ou5qw5rt17su5tu}el{4qu5ou5qw5rt17su5tu}em{4qu5ou5qw5rt17su5tu}en{4qu5ou5qw5rt17su5tu}eo{4qu5ou5qw5rt17su5tu}ep{4qu5ou5qw5rt17su5tu}es{17ss5ts5qs4qu}et{4qu5ou5qw5rt17sw5tw}eu{4qu5ou5qw5rt17ss5ts}ev{17ss5ts5qs4qu}6z{17sw5tw5ou5qw5rs}fm{17sw5tw5ou5qw5rs}7n{201ts}fo{17sw5tw5ou5qw5rs}fp{17sw5tw5ou5qw5rs}fq{17sw5tw5ou5qw5rs}7r{cksclscmscnscoscps4ls}fs{17sw5tw5ou5qw5rs}ft{17su5tu}fu{17su5tu}fv{17su5tu}fw{17su5tu}fz{cksclscmscnscoscps4ls}}}"),
+        "Helvetica-Bold": uncompress("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),
+        Courier: uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
+        "Courier-BoldOblique": uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
+        "Times-Bold": uncompress("{'widths'{k3q2q5ncx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2l202m2n2n3m2o3m2p6o202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5x4l4s4m4m4n4s4o4s4p4m4q3x4r4y4s4y4t2r4u3m4v4y4w4m4x5y4y4s4z4y5k3x5l4y5m4s5n3r5o4m5p4s5q4s5r6o5s4s5t4s5u4m5v2l5w1w5x2l5y3u5z3m6k2l6l3m6m3r6n2w6o3r6p2w6q2l6r3m6s3r6t1w6u2l6v3r6w1w6x5n6y3r6z3m7k3r7l3r7m2w7n2r7o2l7p3r7q3m7r4s7s3m7t3m7u2w7v2r7w1q7x2r7y3o202l3mcl4sal2lam3man3mao3map3mar3mas2lat4uau1yav3maw3tay4uaz2lbk2sbl3t'fof'6obo2lbp3rbr1tbs2lbu2lbv3mbz3mck4s202k3mcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3rek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3m3u2l17s4s19m3m}'kerning'{cl{4qt5ks5ot5qy5rw17sv5tv}201t{cks4lscmscnscoscpscls4wv}2k{201ts}2w{4qu5ku7mu5os5qx5ru17su5tu}2x{17su5tu5ou5qs}2y{4qv5kv7mu5ot5qz5ru17su5tu}'fof'-6o7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qu}3v{17su5tu5os5qu}fu{17su5tu5ou5qu}7p{17su5tu5ou5qu}ck{4qt5ks5ot5qy5rw17sv5tv}4l{4qt5ks5ot5qy5rw17sv5tv}cm{4qt5ks5ot5qy5rw17sv5tv}cn{4qt5ks5ot5qy5rw17sv5tv}co{4qt5ks5ot5qy5rw17sv5tv}cp{4qt5ks5ot5qy5rw17sv5tv}6l{17st5tt5ou5qu}17s{ckuclucmucnucoucpu4lu4wu}5o{ckuclucmucnucoucpu4lu4wu}5q{ckzclzcmzcnzcozcpz4lz4wu}5r{ckxclxcmxcnxcoxcpx4lx4wu}5t{ckuclucmucnucoucpu4lu4wu}7q{ckuclucmucnucoucpu4lu}6p{17sw5tw5ou5qu}ek{17st5tt5qu}el{17st5tt5ou5qu}em{17st5tt5qu}en{17st5tt5qu}eo{17st5tt5qu}ep{17st5tt5ou5qu}es{17ss5ts5qu}et{17sw5tw5ou5qu}eu{17sw5tw5ou5qu}ev{17ss5ts5qu}6z{17sw5tw5ou5qu5rs}fm{17sw5tw5ou5qu5rs}fn{17sw5tw5ou5qu5rs}fo{17sw5tw5ou5qu5rs}fp{17sw5tw5ou5qu5rs}fq{17sw5tw5ou5qu5rs}7r{cktcltcmtcntcotcpt4lt5os}fs{17sw5tw5ou5qu5rs}ft{17su5tu5ou5qu}7m{5os}fv{17su5tu5ou5qu}fw{17su5tu5ou5qu}fz{cksclscmscnscoscps4ls}}}"),
+        Symbol: uncompress("{'widths'{k3uaw4r19m3m2k1t2l2l202m2y2n3m2p5n202q6o3k3m2s2l2t2l2v3r2w1t3m3m2y1t2z1wbk2sbl3r'fof'6o3n3m3o3m3p3m3q3m3r3m3s3m3t3m3u1w3v1w3w3r3x3r3y3r3z2wbp3t3l3m5v2l5x2l5z3m2q4yfr3r7v3k7w1o7x3k}'kerning'{'fof'-6o}}"),
+        Helvetica: uncompress("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}"),
+        "Helvetica-BoldOblique": uncompress("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),
+        ZapfDingbats: uncompress("{'widths'{k4u2k1w'fof'6o}'kerning'{'fof'-6o}}"),
+        "Courier-Bold": uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
+        "Times-Italic": uncompress("{'widths'{k3n2q4ycx2l201n3m201o5t201s2l201t2l201u2l201w3r201x3r201y3r2k1t2l2l202m2n2n3m2o3m2p5n202q5t2r1p2s2l2t2l2u3m2v4n2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w4n3x4n3y4n3z3m4k5w4l3x4m3x4n4m4o4s4p3x4q3x4r4s4s4s4t2l4u2w4v4m4w3r4x5n4y4m4z4s5k3x5l4s5m3x5n3m5o3r5p4s5q3x5r5n5s3x5t3r5u3r5v2r5w1w5x2r5y2u5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q1w6r3m6s3m6t1w6u1w6v2w6w1w6x4s6y3m6z3m7k3m7l3m7m2r7n2r7o1w7p3m7q2w7r4m7s2w7t2w7u2r7v2s7w1v7x2s7y3q202l3mcl3xal2ram3man3mao3map3mar3mas2lat4wau1vav3maw4nay4waz2lbk2sbl4n'fof'6obo2lbp3mbq3obr1tbs2lbu1zbv3mbz3mck3x202k3mcm3xcn3xco3xcp3xcq5tcr4mcs3xct3xcu3xcv3xcw2l2m2ucy2lcz2ldl4mdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr4nfs3mft3mfu3mfv3mfw3mfz2w203k6o212m6m2dw2l2cq2l3t3m3u2l17s3r19m3m}'kerning'{cl{5kt4qw}201s{201sw}201t{201tw2wy2yy6q-t}201x{2wy2yy}2k{201tw}2w{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}2x{17ss5ts5os}2y{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}'fof'-6o6t{17ss5ts5qs}7t{5os}3v{5qs}7p{17su5tu5qs}ck{5kt4qw}4l{5kt4qw}cm{5kt4qw}cn{5kt4qw}co{5kt4qw}cp{5kt4qw}6l{4qs5ks5ou5qw5ru17su5tu}17s{2ks}5q{ckvclvcmvcnvcovcpv4lv}5r{ckuclucmucnucoucpu4lu}5t{2ks}6p{4qs5ks5ou5qw5ru17su5tu}ek{4qs5ks5ou5qw5ru17su5tu}el{4qs5ks5ou5qw5ru17su5tu}em{4qs5ks5ou5qw5ru17su5tu}en{4qs5ks5ou5qw5ru17su5tu}eo{4qs5ks5ou5qw5ru17su5tu}ep{4qs5ks5ou5qw5ru17su5tu}es{5ks5qs4qs}et{4qs5ks5ou5qw5ru17su5tu}eu{4qs5ks5qw5ru17su5tu}ev{5ks5qs4qs}ex{17ss5ts5qs}6z{4qv5ks5ou5qw5ru17su5tu}fm{4qv5ks5ou5qw5ru17su5tu}fn{4qv5ks5ou5qw5ru17su5tu}fo{4qv5ks5ou5qw5ru17su5tu}fp{4qv5ks5ou5qw5ru17su5tu}fq{4qv5ks5ou5qw5ru17su5tu}7r{5os}fs{4qv5ks5ou5qw5ru17su5tu}ft{17su5tu5qs}fu{17su5tu5qs}fv{17su5tu5qs}fw{17su5tu5qs}}}"),
+        "Times-Roman": uncompress("{'widths'{k3n2q4ycx2l201n3m201o6o201s2l201t2l201u2l201w2w201x2w201y2w2k1t2l2l202m2n2n3m2o3m2p5n202q6o2r1m2s2l2t2l2u3m2v3s2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v1w3w3s3x3s3y3s3z2w4k5w4l4s4m4m4n4m4o4s4p3x4q3r4r4s4s4s4t2l4u2r4v4s4w3x4x5t4y4s4z4s5k3r5l4s5m4m5n3r5o3x5p4s5q4s5r5y5s4s5t4s5u3x5v2l5w1w5x2l5y2z5z3m6k2l6l2w6m3m6n2w6o3m6p2w6q2l6r3m6s3m6t1w6u1w6v3m6w1w6x4y6y3m6z3m7k3m7l3m7m2l7n2r7o1w7p3m7q3m7r4s7s3m7t3m7u2w7v3k7w1o7x3k7y3q202l3mcl4sal2lam3man3mao3map3mar3mas2lat4wau1vav3maw3say4waz2lbk2sbl3s'fof'6obo2lbp3mbq2xbr1tbs2lbu1zbv3mbz2wck4s202k3mcm4scn4sco4scp4scq5tcr4mcs3xct3xcu3xcv3xcw2l2m2tcy2lcz2ldl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek2wel2wem2wen2weo2wep2weq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr3sfs3mft3mfu3mfv3mfw3mfz3m203k6o212m6m2dw2l2cq2l3t3m3u1w17s4s19m3m}'kerning'{cl{4qs5ku17sw5ou5qy5rw201ss5tw201ws}201s{201ss}201t{ckw4lwcmwcnwcowcpwclw4wu201ts}2k{201ts}2w{4qs5kw5os5qx5ru17sx5tx}2x{17sw5tw5ou5qu}2y{4qs5kw5os5qx5ru17sx5tx}'fof'-6o7t{ckuclucmucnucoucpu4lu5os5rs}3u{17su5tu5qs}3v{17su5tu5qs}7p{17sw5tw5qs}ck{4qs5ku17sw5ou5qy5rw201ss5tw201ws}4l{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cm{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cn{4qs5ku17sw5ou5qy5rw201ss5tw201ws}co{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cp{4qs5ku17sw5ou5qy5rw201ss5tw201ws}6l{17su5tu5os5qw5rs}17s{2ktclvcmvcnvcovcpv4lv4wuckv}5o{ckwclwcmwcnwcowcpw4lw4wu}5q{ckyclycmycnycoycpy4ly4wu5ms}5r{cktcltcmtcntcotcpt4lt4ws}5t{2ktclvcmvcnvcovcpv4lv4wuckv}7q{cksclscmscnscoscps4ls}6p{17su5tu5qw5rs}ek{5qs5rs}el{17su5tu5os5qw5rs}em{17su5tu5os5qs5rs}en{17su5qs5rs}eo{5qs5rs}ep{17su5tu5os5qw5rs}es{5qs}et{17su5tu5qw5rs}eu{17su5tu5qs5rs}ev{5qs}6z{17sv5tv5os5qx5rs}fm{5os5qt5rs}fn{17sv5tv5os5qx5rs}fo{17sv5tv5os5qx5rs}fp{5os5qt5rs}fq{5os5qt5rs}7r{ckuclucmucnucoucpu4lu5os}fs{17sv5tv5os5qx5rs}ft{17ss5ts5qs}fu{17sw5tw5qs}fv{17sw5tw5qs}fw{17ss5ts5qs}fz{ckuclucmucnucoucpu4lu5os5rs}}}"),
+        "Helvetica-Oblique": uncompress("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}")
+      }
+    };
+    /*
+    This event handler is fired when a new jsPDF object is initialized
+    This event handler appends metrics data to standard fonts within
+    that jsPDF instance. The metrics are mapped over Unicode character
+    codes, NOT CIDs or other codes matching the StandardEncoding table of the
+    standard PDF fonts.
+    Future:
+    Also included is the encoding maping table, converting Unicode (UCS-2, UTF-16)
+    char codes to StandardEncoding character codes. The encoding table is to be used
+    somewhere around "pdfEscape" call.
+    */
+
+    API.events.push(["addFont", function (data) {
+      var font = data.font;
+      var metrics = fontMetrics["Unicode"][font.postScriptName];
+
+      if (metrics) {
+        font.metadata["Unicode"] = {};
+        font.metadata["Unicode"].widths = metrics.widths;
+        font.metadata["Unicode"].kerning = metrics.kerning;
+      }
+
+      var encodingBlock = encodings["Unicode"][font.postScriptName];
+
+      if (encodingBlock) {
+        font.metadata["Unicode"].encoding = encodingBlock;
+        font.encoding = encodingBlock.codePages[0];
+      }
+    }]); // end of adding event handler
+  })(jsPDF.API);
+
+  /**
+   * @license
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+  /**
+   * @name ttfsupport
+   * @module
+   */
+
+  (function (jsPDF) {
+
+    var binaryStringToUint8Array = function binaryStringToUint8Array(binary_string) {
+      var len = binary_string.length;
+      var bytes = new Uint8Array(len);
+
+      for (var i = 0; i < len; i++) {
+        bytes[i] = binary_string.charCodeAt(i);
+      }
+
+      return bytes;
+    };
+
+    var addFont = function addFont(font, file) {
+      // eslint-disable-next-line no-control-regex
+      if (/^\x00\x01\x00\x00/.test(file)) {
+        file = binaryStringToUint8Array(file);
+      } else {
+        file = binaryStringToUint8Array(atob(file));
+      }
+
+      font.metadata = jsPDF.API.TTFFont.open(file);
+      font.metadata.Unicode = font.metadata.Unicode || {
+        encoding: {},
+        kerning: {},
+        widths: []
+      };
+      font.metadata.glyIdsUsed = [0];
+    };
+
+    jsPDF.API.events.push(["addFont", function (data) {
+      var file = undefined;
+      var font = data.font;
+      var instance = data.instance;
+
+      if (font.isStandardFont) {
+        return;
+      }
+
+      if (typeof instance !== "undefined") {
+        if (instance.existsFileInVFS(font.postScriptName) === false) {
+          file = instance.loadFile(font.postScriptName);
+        } else {
+          file = instance.getFileFromVFS(font.postScriptName);
+        }
+
+        if (typeof file !== "string") {
+          throw new Error("Font is not stored as string-data in vFS, import fonts or remove declaration doc.addFont('" + font.postScriptName + "').");
+        }
+
+        addFont(font, file);
+      } else {
+        throw new Error("Font does not exist in vFS, import fonts or remove declaration doc.addFont('" + font.postScriptName + "').");
+      }
+    }]); // end of adding event handler
+  })(jsPDF);
+
+  /**
+   * jsPDF SVG plugin
+   *
+   * @name svg
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+
+    function loadCanvg() {
+      return function () {
+        if (globalObject["canvg"]) {
+          return Promise.resolve(globalObject["canvg"]);
+        }
+
+        if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === "object" && typeof module !== "undefined") {
+          return new Promise(function (resolve, reject) {
+            try {
+              resolve(require("canvg"));
+            } catch (e) {
+              reject(e);
+            }
+          });
+        }
+
+        if (typeof define === "function" && define.amd) {
+          return new Promise(function (resolve, reject) {
+            try {
+              require(["canvg"], resolve);
+            } catch (e) {
+              reject(e);
+            }
+          });
+        }
+
+        return Promise.reject(new Error("Could not load canvg"));
+      }().catch(function (e) {
+        return Promise.reject(new Error("Could not load canvg: " + e));
+      }).then(function (canvg) {
+        return canvg.default ? canvg.default : canvg;
+      });
+    }
+    /**
+     * Parses SVG XML and saves it as image into the PDF.
+     *
+     * Depends on canvas-element and canvg
+     *
+     * @name addSvgAsImage
+     * @public
+     * @function
+     * @param {string} SVG-Data as Text
+     * @param {number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
+     * @param {number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
+     * @param {number} width of SVG-Image (in units declared at inception of PDF document)
+     * @param {number} height of SVG-Image (in units declared at inception of PDF document)
+     * @param {string} alias of SVG-Image (if used multiple times)
+     * @param {string} compression of the generated JPEG, can have the values 'NONE', 'FAST', 'MEDIUM' and 'SLOW'
+     * @param {number} rotation of the image in degrees (0-359)
+     *
+     * @returns jsPDF jsPDF-instance
+     */
+
+
+    jsPDFAPI.addSvgAsImage = function (svg, x, y, w, h, alias, compression, rotation) {
+      if (isNaN(x) || isNaN(y)) {
+        console.error("jsPDF.addSvgAsImage: Invalid coordinates", arguments);
+        throw new Error("Invalid coordinates passed to jsPDF.addSvgAsImage");
+      }
+
+      if (isNaN(w) || isNaN(h)) {
+        console.error("jsPDF.addSvgAsImage: Invalid measurements", arguments);
+        throw new Error("Invalid measurements (width and/or height) passed to jsPDF.addSvgAsImage");
+      }
+
+      var canvas = document.createElement("canvas");
+      canvas.width = w;
+      canvas.height = h;
+      var ctx = canvas.getContext("2d");
+      ctx.fillStyle = "#fff"; /// set white fill style
+
+      ctx.fillRect(0, 0, canvas.width, canvas.height);
+      var options = {
+        ignoreMouse: true,
+        ignoreAnimation: true,
+        ignoreDimensions: true
+      };
+      var doc = this;
+      return loadCanvg().then(function (canvg) {
+        return canvg.fromString(ctx, svg, options);
+      }, function () {
+        return Promise.reject(new Error("Could not load canvg."));
+      }).then(function (instance) {
+        return instance.render(options);
+      }).then(function () {
+        doc.addImage(canvas.toDataURL("image/jpeg", 1.0), x, y, w, h, compression, rotation);
+      });
+    };
+  })(jsPDF.API);
+
+  /**
+   * @license
+   * ====================================================================
+   * Copyright (c) 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
+   *
+   * Permission is hereby granted, free of charge, to any person obtaining
+   * a copy of this software and associated documentation files (the
+   * "Software"), to deal in the Software without restriction, including
+   * without limitation the rights to use, copy, modify, merge, publish,
+   * distribute, sublicense, and/or sell copies of the Software, and to
+   * permit persons to whom the Software is furnished to do so, subject to
+   * the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be
+   * included in all copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+   * ====================================================================
+   */
+  /**
+   * jsPDF total_pages plugin
+   * @name total_pages
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+    /**
+     * @name putTotalPages
+     * @function
+     * @param {string} pageExpression Regular Expression
+     * @returns {jsPDF} jsPDF-instance
+     */
+
+    jsPDFAPI.putTotalPages = function (pageExpression) {
+
+      var replaceExpression;
+      var totalNumberOfPages = 0;
+
+      if (parseInt(this.internal.getFont().id.substr(1), 10) < 15) {
+        replaceExpression = new RegExp(pageExpression, "g");
+        totalNumberOfPages = this.internal.getNumberOfPages();
+      } else {
+        replaceExpression = new RegExp(this.pdfEscape16(pageExpression, this.internal.getFont()), "g");
+        totalNumberOfPages = this.pdfEscape16(this.internal.getNumberOfPages() + "", this.internal.getFont());
+      }
+
+      for (var n = 1; n <= this.internal.getNumberOfPages(); n++) {
+        for (var i = 0; i < this.internal.pages[n].length; i++) {
+          this.internal.pages[n][i] = this.internal.pages[n][i].replace(replaceExpression, totalNumberOfPages);
+        }
+      }
+
+      return this;
+    };
+  })(jsPDF.API);
+
+  /**
+   * Adds the ability to set ViewerPreferences and by thus
+   * controlling the way the document is to be presented on the
+   * screen or in print.
+   * @name viewerpreferences
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+    /**
+     * Set the ViewerPreferences of the generated PDF
+     *
+     * @name viewerPreferences
+     * @function
+     * @public
+     * @param {Object} options Array with the ViewerPreferences<br />
+     * Example: doc.viewerPreferences({"FitWindow":true});<br />
+     * <br />
+     * You can set following preferences:<br />
+     * <br/>
+     * <b>HideToolbar</b> <i>(boolean)</i><br />
+     * Default value: false<br />
+     * <br />
+     * <b>HideMenubar</b> <i>(boolean)</i><br />
+     * Default value: false.<br />
+     * <br />
+     * <b>HideWindowUI</b> <i>(boolean)</i><br />
+     * Default value: false.<br />
+     * <br />
+     * <b>FitWindow</b> <i>(boolean)</i><br />
+     * Default value: false.<br />
+     * <br />
+     * <b>CenterWindow</b> <i>(boolean)</i><br />
+     * Default value: false<br />
+     * <br />
+     * <b>DisplayDocTitle</b> <i>(boolean)</i><br />
+     * Default value: false.<br />
+     * <br />
+     * <b>NonFullScreenPageMode</b> <i>(string)</i><br />
+     * Possible values: UseNone, UseOutlines, UseThumbs, UseOC<br />
+     * Default value: UseNone<br/>
+     * <br />
+     * <b>Direction</b> <i>(string)</i><br />
+     * Possible values: L2R, R2L<br />
+     * Default value: L2R.<br />
+     * <br />
+     * <b>ViewArea</b> <i>(string)</i><br />
+     * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
+     * Default value: CropBox.<br />
+     * <br />
+     * <b>ViewClip</b> <i>(string)</i><br />
+     * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
+     * Default value: CropBox<br />
+     * <br />
+     * <b>PrintArea</b> <i>(string)</i><br />
+     * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
+     * Default value: CropBox<br />
+     * <br />
+     * <b>PrintClip</b> <i>(string)</i><br />
+     * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
+     * Default value: CropBox.<br />
+     * <br />
+     * <b>PrintScaling</b> <i>(string)</i><br />
+     * Possible values: AppDefault, None<br />
+     * Default value: AppDefault.<br />
+     * <br />
+     * <b>Duplex</b> <i>(string)</i><br />
+     * Possible values: Simplex, DuplexFlipLongEdge, DuplexFlipShortEdge
+     * Default value: none<br />
+     * <br />
+     * <b>PickTrayByPDFSize</b> <i>(boolean)</i><br />
+     * Default value: false<br />
+     * <br />
+     * <b>PrintPageRange</b> <i>(Array)</i><br />
+     * Example: [[1,5], [7,9]]<br />
+     * Default value: as defined by PDF viewer application<br />
+     * <br />
+     * <b>NumCopies</b> <i>(Number)</i><br />
+     * Possible values: 1, 2, 3, 4, 5<br />
+     * Default value: 1<br />
+     * <br />
+     * For more information see the PDF Reference, sixth edition on Page 577
+     * @param {boolean} doReset True to reset the settings
+     * @function
+     * @returns jsPDF jsPDF-instance
+     * @example
+     * var doc = new jsPDF()
+     * doc.text('This is a test', 10, 10)
+     * doc.viewerPreferences({'FitWindow': true}, true)
+     * doc.save("viewerPreferences.pdf")
+     *
+     * // Example printing 10 copies, using cropbox, and hiding UI.
+     * doc.viewerPreferences({
+     *   'HideWindowUI': true,
+     *   'PrintArea': 'CropBox',
+     *   'NumCopies': 10
+     * })
+     */
+
+    jsPDFAPI.viewerPreferences = function (options, doReset) {
+      options = options || {};
+      doReset = doReset || false;
+      var configuration;
+      var configurationTemplate = {
+        HideToolbar: {
+          defaultValue: false,
+          value: false,
+          type: "boolean",
+          explicitSet: false,
+          valueSet: [true, false],
+          pdfVersion: 1.3
+        },
+        HideMenubar: {
+          defaultValue: false,
+          value: false,
+          type: "boolean",
+          explicitSet: false,
+          valueSet: [true, false],
+          pdfVersion: 1.3
+        },
+        HideWindowUI: {
+          defaultValue: false,
+          value: false,
+          type: "boolean",
+          explicitSet: false,
+          valueSet: [true, false],
+          pdfVersion: 1.3
+        },
+        FitWindow: {
+          defaultValue: false,
+          value: false,
+          type: "boolean",
+          explicitSet: false,
+          valueSet: [true, false],
+          pdfVersion: 1.3
+        },
+        CenterWindow: {
+          defaultValue: false,
+          value: false,
+          type: "boolean",
+          explicitSet: false,
+          valueSet: [true, false],
+          pdfVersion: 1.3
+        },
+        DisplayDocTitle: {
+          defaultValue: false,
+          value: false,
+          type: "boolean",
+          explicitSet: false,
+          valueSet: [true, false],
+          pdfVersion: 1.4
+        },
+        NonFullScreenPageMode: {
+          defaultValue: "UseNone",
+          value: "UseNone",
+          type: "name",
+          explicitSet: false,
+          valueSet: ["UseNone", "UseOutlines", "UseThumbs", "UseOC"],
+          pdfVersion: 1.3
+        },
+        Direction: {
+          defaultValue: "L2R",
+          value: "L2R",
+          type: "name",
+          explicitSet: false,
+          valueSet: ["L2R", "R2L"],
+          pdfVersion: 1.3
+        },
+        ViewArea: {
+          defaultValue: "CropBox",
+          value: "CropBox",
+          type: "name",
+          explicitSet: false,
+          valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"],
+          pdfVersion: 1.4
+        },
+        ViewClip: {
+          defaultValue: "CropBox",
+          value: "CropBox",
+          type: "name",
+          explicitSet: false,
+          valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"],
+          pdfVersion: 1.4
+        },
+        PrintArea: {
+          defaultValue: "CropBox",
+          value: "CropBox",
+          type: "name",
+          explicitSet: false,
+          valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"],
+          pdfVersion: 1.4
+        },
+        PrintClip: {
+          defaultValue: "CropBox",
+          value: "CropBox",
+          type: "name",
+          explicitSet: false,
+          valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"],
+          pdfVersion: 1.4
+        },
+        PrintScaling: {
+          defaultValue: "AppDefault",
+          value: "AppDefault",
+          type: "name",
+          explicitSet: false,
+          valueSet: ["AppDefault", "None"],
+          pdfVersion: 1.6
+        },
+        Duplex: {
+          defaultValue: "",
+          value: "none",
+          type: "name",
+          explicitSet: false,
+          valueSet: ["Simplex", "DuplexFlipShortEdge", "DuplexFlipLongEdge", "none"],
+          pdfVersion: 1.7
+        },
+        PickTrayByPDFSize: {
+          defaultValue: false,
+          value: false,
+          type: "boolean",
+          explicitSet: false,
+          valueSet: [true, false],
+          pdfVersion: 1.7
+        },
+        PrintPageRange: {
+          defaultValue: "",
+          value: "",
+          type: "array",
+          explicitSet: false,
+          valueSet: null,
+          pdfVersion: 1.7
+        },
+        NumCopies: {
+          defaultValue: 1,
+          value: 1,
+          type: "integer",
+          explicitSet: false,
+          valueSet: null,
+          pdfVersion: 1.7
+        }
+      };
+      var configurationKeys = Object.keys(configurationTemplate);
+      var rangeArray = [];
+      var i = 0;
+      var j = 0;
+      var k = 0;
+      var isValid;
+      var method;
+      var value;
+
+      function arrayContainsElement(array, element) {
+        var iterator;
+        var result = false;
+
+        for (iterator = 0; iterator < array.length; iterator += 1) {
+          if (array[iterator] === element) {
+            result = true;
+          }
+        }
+
+        return result;
+      }
+
+      if (this.internal.viewerpreferences === undefined) {
+        this.internal.viewerpreferences = {};
+        this.internal.viewerpreferences.configuration = JSON.parse(JSON.stringify(configurationTemplate));
+        this.internal.viewerpreferences.isSubscribed = false;
+      }
+
+      configuration = this.internal.viewerpreferences.configuration;
+
+      if (options === "reset" || doReset === true) {
+        var len = configurationKeys.length;
+
+        for (k = 0; k < len; k += 1) {
+          configuration[configurationKeys[k]].value = configuration[configurationKeys[k]].defaultValue;
+          configuration[configurationKeys[k]].explicitSet = false;
+        }
+      }
+
+      if (_typeof(options) === "object") {
+        for (method in options) {
+          value = options[method];
+
+          if (arrayContainsElement(configurationKeys, method) && value !== undefined) {
+            if (configuration[method].type === "boolean" && typeof value === "boolean") {
+              configuration[method].value = value;
+            } else if (configuration[method].type === "name" && arrayContainsElement(configuration[method].valueSet, value)) {
+              configuration[method].value = value;
+            } else if (configuration[method].type === "integer" && Number.isInteger(value)) {
+              configuration[method].value = value;
+            } else if (configuration[method].type === "array") {
+              for (i = 0; i < value.length; i += 1) {
+                isValid = true;
+
+                if (value[i].length === 1 && typeof value[i][0] === "number") {
+                  rangeArray.push(String(value[i] - 1));
+                } else if (value[i].length > 1) {
+                  for (j = 0; j < value[i].length; j += 1) {
+                    if (typeof value[i][j] !== "number") {
+                      isValid = false;
+                    }
+                  }
+
+                  if (isValid === true) {
+                    rangeArray.push([value[i][0] - 1, value[i][1] - 1].join(" "));
+                  }
+                }
+              }
+
+              configuration[method].value = "[" + rangeArray.join(" ") + "]";
+            } else {
+              configuration[method].value = configuration[method].defaultValue;
+            }
+
+            configuration[method].explicitSet = true;
+          }
+        }
+      }
+
+      if (this.internal.viewerpreferences.isSubscribed === false) {
+        this.internal.events.subscribe("putCatalog", function () {
+          var pdfDict = [];
+          var vPref;
+
+          for (vPref in configuration) {
+            if (configuration[vPref].explicitSet === true) {
+              if (configuration[vPref].type === "name") {
+                pdfDict.push("/" + vPref + " /" + configuration[vPref].value);
+              } else {
+                pdfDict.push("/" + vPref + " " + configuration[vPref].value);
+              }
+            }
+          }
+
+          if (pdfDict.length !== 0) {
+            this.internal.write("/ViewerPreferences\n<<\n" + pdfDict.join("\n") + "\n>>");
+          }
+        });
+        this.internal.viewerpreferences.isSubscribed = true;
+      }
+
+      this.internal.viewerpreferences.configuration = configuration;
+      return this;
+    };
+  })(jsPDF.API);
+
+  /** ====================================================================
+   * @license
+   * jsPDF XMP metadata plugin
+   * Copyright (c) 2016 Jussi Utunen, u-jussi@suomi24.fi
+   *
+   * Permission is hereby granted, free of charge, to any person obtaining
+   * a copy of this software and associated documentation files (the
+   * "Software"), to deal in the Software without restriction, including
+   * without limitation the rights to use, copy, modify, merge, publish,
+   * distribute, sublicense, and/or sell copies of the Software, and to
+   * permit persons to whom the Software is furnished to do so, subject to
+   * the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be
+   * included in all copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+   * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+   * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+   * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+   * ====================================================================
+   */
+  /**
+   * @name xmp_metadata
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+
+    var postPutResources = function postPutResources() {
+      var xmpmeta_beginning = '<x:xmpmeta xmlns:x="adobe:ns:meta/">';
+      var rdf_beginning = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:jspdf="' + this.internal.__metadata__.namespaceuri + '"><jspdf:metadata>';
+      var rdf_ending = "</jspdf:metadata></rdf:Description></rdf:RDF>";
+      var xmpmeta_ending = "</x:xmpmeta>";
+      var utf8_xmpmeta_beginning = unescape(encodeURIComponent(xmpmeta_beginning));
+      var utf8_rdf_beginning = unescape(encodeURIComponent(rdf_beginning));
+      var utf8_metadata = unescape(encodeURIComponent(this.internal.__metadata__.metadata));
+      var utf8_rdf_ending = unescape(encodeURIComponent(rdf_ending));
+      var utf8_xmpmeta_ending = unescape(encodeURIComponent(xmpmeta_ending));
+      var total_len = utf8_rdf_beginning.length + utf8_metadata.length + utf8_rdf_ending.length + utf8_xmpmeta_beginning.length + utf8_xmpmeta_ending.length;
+      this.internal.__metadata__.metadata_object_number = this.internal.newObject();
+      this.internal.write("<< /Type /Metadata /Subtype /XML /Length " + total_len + " >>");
+      this.internal.write("stream");
+      this.internal.write(utf8_xmpmeta_beginning + utf8_rdf_beginning + utf8_metadata + utf8_rdf_ending + utf8_xmpmeta_ending);
+      this.internal.write("endstream");
+      this.internal.write("endobj");
+    };
+
+    var putCatalog = function putCatalog() {
+      if (this.internal.__metadata__.metadata_object_number) {
+        this.internal.write("/Metadata " + this.internal.__metadata__.metadata_object_number + " 0 R");
+      }
+    };
+    /**
+     * Adds XMP formatted metadata to PDF
+     *
+     * @name addMetadata
+     * @function
+     * @param {String} metadata The actual metadata to be added. The metadata shall be stored as XMP simple value. Note that if the metadata string contains XML markup characters "<", ">" or "&", those characters should be written using XML entities.
+     * @param {String} namespaceuri Sets the namespace URI for the metadata. Last character should be slash or hash.
+     * @returns {jsPDF} jsPDF-instance
+     */
+
+
+    jsPDFAPI.addMetadata = function (metadata, namespaceuri) {
+      if (typeof this.internal.__metadata__ === "undefined") {
+        this.internal.__metadata__ = {
+          metadata: metadata,
+          namespaceuri: namespaceuri || "http://jspdf.default.namespaceuri/"
+        };
+        this.internal.events.subscribe("putCatalog", putCatalog);
+        this.internal.events.subscribe("postPutResources", postPutResources);
+      }
+
+      return this;
+    };
+  })(jsPDF.API);
+
+  /**
+   * @name utf8
+   * @module
+   */
+
+  (function (jsPDF) {
+
+    var jsPDFAPI = jsPDF.API;
+    /***************************************************************************************************/
+
+    /* function : pdfEscape16                                                                          */
+
+    /* comment : The character id of a 2-byte string is converted to a hexadecimal number by obtaining */
+
+    /*   the corresponding glyph id and width, and then adding padding to the string.                  */
+
+    /***************************************************************************************************/
+
+    var pdfEscape16 = jsPDFAPI.pdfEscape16 = function (text, font) {
+      var widths = font.metadata.Unicode.widths;
+      var padz = ["", "0", "00", "000", "0000"];
+      var ar = [""];
+
+      for (var i = 0, l = text.length, t; i < l; ++i) {
+        t = font.metadata.characterToGlyph(text.charCodeAt(i));
+        font.metadata.glyIdsUsed.push(t);
+        font.metadata.toUnicode[t] = text.charCodeAt(i);
+
+        if (widths.indexOf(t) == -1) {
+          widths.push(t);
+          widths.push([parseInt(font.metadata.widthOfGlyph(t), 10)]);
+        }
+
+        if (t == "0") {
+          //Spaces are not allowed in cmap.
+          return ar.join("");
+        } else {
+          t = t.toString(16);
+          ar.push(padz[4 - t.length], t);
+        }
+      }
+
+      return ar.join("");
+    };
+
+    var toUnicodeCmap = function toUnicodeCmap(map) {
+      var code, codes, range, unicode, unicodeMap, _i, _len;
+
+      unicodeMap = "/CIDInit /ProcSet findresource begin\n12 dict begin\nbegincmap\n/CIDSystemInfo <<\n  /Registry (Adobe)\n  /Ordering (UCS)\n  /Supplement 0\n>> def\n/CMapName /Adobe-Identity-UCS def\n/CMapType 2 def\n1 begincodespacerange\n<0000><ffff>\nendcodespacerange";
+      codes = Object.keys(map).sort(function (a, b) {
+        return a - b;
+      });
+      range = [];
+
+      for (_i = 0, _len = codes.length; _i < _len; _i++) {
+        code = codes[_i];
+
+        if (range.length >= 100) {
+          unicodeMap += "\n" + range.length + " beginbfchar\n" + range.join("\n") + "\nendbfchar";
+          range = [];
+        }
+
+        if (map[code] !== undefined && map[code] !== null && typeof map[code].toString === "function") {
+          unicode = ("0000" + map[code].toString(16)).slice(-4);
+          code = ("0000" + (+code).toString(16)).slice(-4);
+          range.push("<" + code + "><" + unicode + ">");
+        }
+      }
+
+      if (range.length) {
+        unicodeMap += "\n" + range.length + " beginbfchar\n" + range.join("\n") + "\nendbfchar\n";
+      }
+
+      unicodeMap += "endcmap\nCMapName currentdict /CMap defineresource pop\nend\nend";
+      return unicodeMap;
+    };
+
+    var identityHFunction = function identityHFunction(options) {
+      var font = options.font;
+      var out = options.out;
+      var newObject = options.newObject;
+      var putStream = options.putStream;
+
+      if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === "Identity-H") {
+        //Tag with Identity-H
+        var widths = font.metadata.Unicode.widths;
+        var data = font.metadata.subset.encode(font.metadata.glyIdsUsed, 1);
+        var pdfOutput = data;
+        var pdfOutput2 = "";
+
+        for (var i = 0; i < pdfOutput.length; i++) {
+          pdfOutput2 += String.fromCharCode(pdfOutput[i]);
+        }
+
+        var fontTable = newObject();
+        putStream({
+          data: pdfOutput2,
+          addLength1: true,
+          objectId: fontTable
+        });
+        out("endobj");
+        var cmap = newObject();
+        var cmapData = toUnicodeCmap(font.metadata.toUnicode);
+        putStream({
+          data: cmapData,
+          addLength1: true,
+          objectId: cmap
+        });
+        out("endobj");
+        var fontDescriptor = newObject();
+        out("<<");
+        out("/Type /FontDescriptor");
+        out("/FontName /" + toPDFName(font.fontName));
+        out("/FontFile2 " + fontTable + " 0 R");
+        out("/FontBBox " + jsPDF.API.PDFObject.convert(font.metadata.bbox));
+        out("/Flags " + font.metadata.flags);
+        out("/StemV " + font.metadata.stemV);
+        out("/ItalicAngle " + font.metadata.italicAngle);
+        out("/Ascent " + font.metadata.ascender);
+        out("/Descent " + font.metadata.decender);
+        out("/CapHeight " + font.metadata.capHeight);
+        out(">>");
+        out("endobj");
+        var DescendantFont = newObject();
+        out("<<");
+        out("/Type /Font");
+        out("/BaseFont /" + toPDFName(font.fontName));
+        out("/FontDescriptor " + fontDescriptor + " 0 R");
+        out("/W " + jsPDF.API.PDFObject.convert(widths));
+        out("/CIDToGIDMap /Identity");
+        out("/DW 1000");
+        out("/Subtype /CIDFontType2");
+        out("/CIDSystemInfo");
+        out("<<");
+        out("/Supplement 0");
+        out("/Registry (Adobe)");
+        out("/Ordering (" + font.encoding + ")");
+        out(">>");
+        out(">>");
+        out("endobj");
+        font.objectNumber = newObject();
+        out("<<");
+        out("/Type /Font");
+        out("/Subtype /Type0");
+        out("/ToUnicode " + cmap + " 0 R");
+        out("/BaseFont /" + toPDFName(font.fontName));
+        out("/Encoding /" + font.encoding);
+        out("/DescendantFonts [" + DescendantFont + " 0 R]");
+        out(">>");
+        out("endobj");
+        font.isAlreadyPutted = true;
+      }
+    };
+
+    jsPDFAPI.events.push(["putFont", function (args) {
+      identityHFunction(args);
+    }]);
+
+    var winAnsiEncodingFunction = function winAnsiEncodingFunction(options) {
+      var font = options.font;
+      var out = options.out;
+      var newObject = options.newObject;
+      var putStream = options.putStream;
+
+      if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === "WinAnsiEncoding") {
+        //Tag with WinAnsi encoding
+        var data = font.metadata.rawData;
+        var pdfOutput = data;
+        var pdfOutput2 = "";
+
+        for (var i = 0; i < pdfOutput.length; i++) {
+          pdfOutput2 += String.fromCharCode(pdfOutput[i]);
+        }
+
+        var fontTable = newObject();
+        putStream({
+          data: pdfOutput2,
+          addLength1: true,
+          objectId: fontTable
+        });
+        out("endobj");
+        var cmap = newObject();
+        var cmapData = toUnicodeCmap(font.metadata.toUnicode);
+        putStream({
+          data: cmapData,
+          addLength1: true,
+          objectId: cmap
+        });
+        out("endobj");
+        var fontDescriptor = newObject();
+        out("<<");
+        out("/Descent " + font.metadata.decender);
+        out("/CapHeight " + font.metadata.capHeight);
+        out("/StemV " + font.metadata.stemV);
+        out("/Type /FontDescriptor");
+        out("/FontFile2 " + fontTable + " 0 R");
+        out("/Flags 96");
+        out("/FontBBox " + jsPDF.API.PDFObject.convert(font.metadata.bbox));
+        out("/FontName /" + toPDFName(font.fontName));
+        out("/ItalicAngle " + font.metadata.italicAngle);
+        out("/Ascent " + font.metadata.ascender);
+        out(">>");
+        out("endobj");
+        font.objectNumber = newObject();
+
+        for (var j = 0; j < font.metadata.hmtx.widths.length; j++) {
+          font.metadata.hmtx.widths[j] = parseInt(font.metadata.hmtx.widths[j] * (1000 / font.metadata.head.unitsPerEm)); //Change the width of Em units to Point units.
+        }
+
+        out("<</Subtype/TrueType/Type/Font/ToUnicode " + cmap + " 0 R/BaseFont/" + toPDFName(font.fontName) + "/FontDescriptor " + fontDescriptor + " 0 R" + "/Encoding/" + font.encoding + " /FirstChar 29 /LastChar 255 /Widths " + jsPDF.API.PDFObject.convert(font.metadata.hmtx.widths) + ">>");
+        out("endobj");
+        font.isAlreadyPutted = true;
+      }
+    };
+
+    jsPDFAPI.events.push(["putFont", function (args) {
+      winAnsiEncodingFunction(args);
+    }]);
+
+    var utf8TextFunction = function utf8TextFunction(args) {
+      var text = args.text || "";
+      var x = args.x;
+      var y = args.y;
+      var options = args.options || {};
+      var mutex = args.mutex || {};
+      var pdfEscape = mutex.pdfEscape;
+      var activeFontKey = mutex.activeFontKey;
+      var fonts = mutex.fonts;
+      var key = activeFontKey;
+      var str = "",
+          s = 0,
+          cmapConfirm;
+      var strText = "";
+      var encoding = fonts[key].encoding;
+
+      if (fonts[key].encoding !== "Identity-H") {
+        return {
+          text: text,
+          x: x,
+          y: y,
+          options: options,
+          mutex: mutex
+        };
+      }
+
+      strText = text;
+      key = activeFontKey;
+
+      if (Array.isArray(text)) {
+        strText = text[0];
+      }
+
+      for (s = 0; s < strText.length; s += 1) {
+        if (fonts[key].metadata.hasOwnProperty("cmap")) {
+          cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)];
+          /*
+               if (Object.prototype.toString.call(text) === '[object Array]') {
+                  var i = 0;
+                 // for (i = 0; i < text.length; i += 1) {
+                      if (Object.prototype.toString.call(text[s]) === '[object Array]') {
+                          cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s][0].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id
+                      } else {
+                       }
+                  //}
+               } else {
+                  cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id
+              }*/
+        }
+
+        if (!cmapConfirm) {
+          if (strText[s].charCodeAt(0) < 256 && fonts[key].metadata.hasOwnProperty("Unicode")) {
+            str += strText[s];
+          } else {
+            str += "";
+          }
+        } else {
+          str += strText[s];
+        }
+      }
+
+      var result = "";
+
+      if (parseInt(key.slice(1)) < 14 || encoding === "WinAnsiEncoding") {
+        //For the default 13 font
+        result = pdfEscape(str, key).split("").map(function (cv) {
+          return cv.charCodeAt(0).toString(16);
+        }).join("");
+      } else if (encoding === "Identity-H") {
+        result = pdfEscape16(str, fonts[key]);
+      }
+
+      mutex.isHex = true;
+      return {
+        text: result,
+        x: x,
+        y: y,
+        options: options,
+        mutex: mutex
+      };
+    };
+
+    var utf8EscapeFunction = function utf8EscapeFunction(parms) {
+      var text = parms.text || "",
+          x = parms.x,
+          y = parms.y,
+          options = parms.options,
+          mutex = parms.mutex;
+      var tmpText = [];
+      var args = {
+        text: text,
+        x: x,
+        y: y,
+        options: options,
+        mutex: mutex
+      };
+
+      if (Array.isArray(text)) {
+        var i = 0;
+
+        for (i = 0; i < text.length; i += 1) {
+          if (Array.isArray(text[i])) {
+            if (text[i].length === 3) {
+              tmpText.push([utf8TextFunction(Object.assign({}, args, {
+                text: text[i][0]
+              })).text, text[i][1], text[i][2]]);
+            } else {
+              tmpText.push(utf8TextFunction(Object.assign({}, args, {
+                text: text[i]
+              })).text);
+            }
+          } else {
+            tmpText.push(utf8TextFunction(Object.assign({}, args, {
+              text: text[i]
+            })).text);
+          }
+        }
+
+        parms.text = tmpText;
+      } else {
+        parms.text = utf8TextFunction(Object.assign({}, args, {
+          text: text
+        })).text;
+      }
+    };
+
+    jsPDFAPI.events.push(["postProcessText", utf8EscapeFunction]);
+  })(jsPDF);
+
+  /**
+   * @license
+   * jsPDF virtual FileSystem functionality
+   *
+   * Licensed under the MIT License.
+   * http://opensource.org/licenses/mit-license
+   */
+  /**
+   * Use the vFS to handle files
+   *
+   * @name vFS
+   * @module
+   */
+
+  (function (jsPDFAPI) {
+
+    var _initializeVFS = function _initializeVFS() {
+      if (typeof this.internal.vFS === "undefined") {
+        this.internal.vFS = {};
+      }
+
+      return true;
+    };
+    /**
+     * Check if the file exists in the vFS
+     *
+     * @name existsFileInVFS
+     * @function
+     * @param {string} Possible filename in the vFS.
+     * @returns {boolean}
+     * @example
+     * doc.existsFileInVFS("someFile.txt");
+     */
+
+
+    jsPDFAPI.existsFileInVFS = function (filename) {
+      _initializeVFS.call(this);
+
+      return typeof this.internal.vFS[filename] !== "undefined";
+    };
+    /**
+     * Add a file to the vFS
+     *
+     * @name addFileToVFS
+     * @function
+     * @param {string} filename The name of the file which should be added.
+     * @param {string} filecontent The content of the file.
+     * @returns {jsPDF}
+     * @example
+     * doc.addFileToVFS("someFile.txt", "BADFACE1");
+     */
+
+
+    jsPDFAPI.addFileToVFS = function (filename, filecontent) {
+      _initializeVFS.call(this);
+
+      this.internal.vFS[filename] = filecontent;
+      return this;
+    };
+    /**
+     * Get the file from the vFS
+     *
+     * @name getFileFromVFS
+     * @function
+     * @param {string} The name of the file which gets requested.
+     * @returns {string}
+     * @example
+     * doc.getFileFromVFS("someFile.txt");
+     */
+
+
+    jsPDFAPI.getFileFromVFS = function (filename) {
+      _initializeVFS.call(this);
+
+      if (typeof this.internal.vFS[filename] !== "undefined") {
+        return this.internal.vFS[filename];
+      }
+
+      return null;
+    };
+  })(jsPDF.API);
+
+  /**
+   * @license
+   * Unicode Bidi Engine based on the work of Alex Shensis (@asthensis)
+   * MIT License
+   */
+
+  (function (jsPDF) {
+    /**
+     * Table of Unicode types.
+     *
+     * Generated by:
+     *
+     * var bidi = require("./bidi/index");
+     * var bidi_accumulate = bidi.slice(0, 256).concat(bidi.slice(0x0500, 0x0500 + 256 * 3)).
+     * concat(bidi.slice(0x2000, 0x2000 + 256)).concat(bidi.slice(0xFB00, 0xFB00 + 256)).
+     * concat(bidi.slice(0xFE00, 0xFE00 + 2 * 256));
+     *
+     * for( var i = 0; i < bidi_accumulate.length; i++) {
+     * 	if(bidi_accumulate[i] === undefined || bidi_accumulate[i] === 'ON')
+     * 		bidi_accumulate[i] = 'N'; //mark as neutral to conserve space and substitute undefined
+     * }
+     * var bidiAccumulateStr = 'return [ "' + bidi_accumulate.toString().replace(/,/g, '", "') + '" ];';
+     * require("fs").writeFile('unicode-types.js', bidiAccumulateStr);
+     *
+     * Based on:
+     * https://github.com/mathiasbynens/unicode-8.0.0
+     */
+
+    var bidiUnicodeTypes = ["BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "S", "B", "S", "WS", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "B", "B", "B", "S", "WS", "N", "N", "ET", "ET", "ET", "N", "N", "N", "N", "N", "ES", "CS", "ES", "CS", "CS", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "CS", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "BN", "BN", "BN", "BN", "BN", "BN", "B", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "BN", "CS", "N", "ET", "ET", "ET", "ET", "N", "N", "N", "N", "L", "N", "N", "BN", "N", "N", "ET", "ET", "EN", "EN", "N", "L", "N", "N", "N", "EN", "L", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "L", "L", "L", "L", "L", "L", "L", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "L", "N", "N", "N", "N", "N", "ET", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "R", "NSM", "R", "NSM", "NSM", "R", "NSM", "NSM", "R", "NSM", "N", "N", "N", "N", "N", "N", "N", "N", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "N", "N", "N", "N", "N", "R", "R", "R", "R", "R", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "AN", "AN", "AN", "AN", "AN", "AN", "N", "N", "AL", "ET", "ET", "AL", "CS", "AL", "N", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "N", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "AN", "ET", "AN", "AN", "AL", "AL", "AL", "NSM", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AN", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "NSM", "NSM", "N", "NSM", "NSM", "NSM", "NSM", "AL", "AL", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "N", "AL", "AL", "NSM", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "N", "N", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "AL", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "R", "R", "N", "N", "N", "N", "R", "N", "N", "N", "N", "N", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "WS", "BN", "BN", "BN", "L", "R", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "WS", "B", "LRE", "RLE", "PDF", "LRO", "RLO", "CS", "ET", "ET", "ET", "ET", "ET", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "CS", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "WS", "BN", "BN", "BN", "BN", "BN", "N", "LRI", "RLI", "FSI", "PDI", "BN", "BN", "BN", "BN", "BN", "BN", "EN", "L", "N", "N", "EN", "EN", "EN", "EN", "EN", "EN", "ES", "ES", "N", "N", "N", "L", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "ES", "ES", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "ET", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "R", "NSM", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "ES", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "N", "R", "R", "R", "R", "R", "N", "R", "N", "R", "R", "N", "R", "R", "N", "R", "R", "R", "R", "R", "R", "R", "R", "R", "R", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "NSM", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "CS", "N", "CS", "N", "N", "CS", "N", "N", "N", "N", "N", "N", "N", "N", "N", "ET", "N", "N", "ES", "ES", "N", "N", "N", "N", "N", "ET", "ET", "N", "N", "N", "N", "N", "AL", "AL", "AL", "AL", "AL", "N", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "AL", "N", "N", "BN", "N", "N", "N", "ET", "ET", "ET", "N", "N", "N", "N", "N", "ES", "CS", "ES", "CS", "CS", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "EN", "CS", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "L", "N", "N", "N", "L", "L", "L", "L", "L", "L", "N", "N", "L", "L", "L", "L", "L", "L", "N", "N", "L", "L", "L", "L", "L", "L", "N", "N", "L", "L", "L", "N", "N", "N", "ET", "ET", "N", "N", "N", "ET", "ET", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", "N"];
+    /**
+     * Unicode Bidi algorithm compliant Bidi engine.
+     * For reference see http://unicode.org/reports/tr9/
+     */
+
+    /**
+     * constructor ( options )
+     *
+     * Initializes Bidi engine
+     *
+     * @param {Object} See 'setOptions' below for detailed description.
+     * options are cashed between invocation of 'doBidiReorder' method
+     *
+     * sample usage pattern of BidiEngine:
+     * var opt = {
+     * 	isInputVisual: true,
+     * 	isInputRtl: false,
+     * 	isOutputVisual: false,
+     * 	isOutputRtl: false,
+     * 	isSymmetricSwapping: true
+     * }
+     * var sourceToTarget = [], levels = [];
+     * var bidiEng = Globalize.bidiEngine(opt);
+     * var src = "text string to be reordered";
+     * var ret = bidiEng.doBidiReorder(src, sourceToTarget, levels);
+     */
+
+    jsPDF.__bidiEngine__ = jsPDF.prototype.__bidiEngine__ = function (options) {
+      var _UNICODE_TYPES = _bidiUnicodeTypes;
+      var _STATE_TABLE_LTR = [[0, 3, 0, 1, 0, 0, 0], [0, 3, 0, 1, 2, 2, 0], [0, 3, 0, 0x11, 2, 0, 1], [0, 3, 5, 5, 4, 1, 0], [0, 3, 0x15, 0x15, 4, 0, 1], [0, 3, 5, 5, 4, 2, 0]];
+      var _STATE_TABLE_RTL = [[2, 0, 1, 1, 0, 1, 0], [2, 0, 1, 1, 0, 2, 0], [2, 0, 2, 1, 3, 2, 0], [2, 0, 2, 0x21, 3, 1, 1]];
+      var _TYPE_NAMES_MAP = {
+        L: 0,
+        R: 1,
+        EN: 2,
+        AN: 3,
+        N: 4,
+        B: 5,
+        S: 6
+      };
+      var _UNICODE_RANGES_MAP = {
+        0: 0,
+        5: 1,
+        6: 2,
+        7: 3,
+        0x20: 4,
+        0xfb: 5,
+        0xfe: 6,
+        0xff: 7
+      };
+      var _SWAP_TABLE = ["(", ")", "(", "<", ">", "<", "[", "]", "[", "{", "}", "{", "\xAB", "\xBB", "\xAB", "\u2039", "\u203A", "\u2039", "\u2045", "\u2046", "\u2045", "\u207D", "\u207E", "\u207D", "\u208D", "\u208E", "\u208D", "\u2264", "\u2265", "\u2264", "\u2329", "\u232A", "\u2329", "\uFE59", "\uFE5A", "\uFE59", "\uFE5B", "\uFE5C", "\uFE5B", "\uFE5D", "\uFE5E", "\uFE5D", "\uFE64", "\uFE65", "\uFE64"];
+
+      var _LTR_RANGES_REG_EXPR = new RegExp(/^([1-4|9]|1[0-9]|2[0-9]|3[0168]|4[04589]|5[012]|7[78]|159|16[0-9]|17[0-2]|21[569]|22[03489]|250)$/);
+
+      var _lastArabic = false,
+          _hasUbatB,
+          _hasUbatS,
+          DIR_LTR = 0,
+          DIR_RTL = 1,
+          _isInVisual,
+          _isInRtl,
+          _isOutVisual,
+          _isOutRtl,
+          _isSymmetricSwapping,
+          _dir = DIR_LTR;
+
+      this.__bidiEngine__ = {};
+
+      var _init = function _init(text, sourceToTargetMap) {
+        if (sourceToTargetMap) {
+          for (var i = 0; i < text.length; i++) {
+            sourceToTargetMap[i] = i;
+          }
+        }
+
+        if (_isInRtl === undefined) {
+          _isInRtl = _isContextualDirRtl(text);
+        }
+
+        if (_isOutRtl === undefined) {
+          _isOutRtl = _isContextualDirRtl(text);
+        }
+      }; // for reference see 3.2 in http://unicode.org/reports/tr9/
+      //
+
+
+      var _getCharType = function _getCharType(ch) {
+        var charCode = ch.charCodeAt(),
+            range = charCode >> 8,
+            rangeIdx = _UNICODE_RANGES_MAP[range];
+
+        if (rangeIdx !== undefined) {
+          return _UNICODE_TYPES[rangeIdx * 256 + (charCode & 0xff)];
+        } else if (range === 0xfc || range === 0xfd) {
+          return "AL";
+        } else if (_LTR_RANGES_REG_EXPR.test(range)) {
+          //unlikely case
+          return "L";
+        } else if (range === 8) {
+          // even less likely
+          return "R";
+        }
+
+        return "N"; //undefined type, mark as neutral
+      };
+
+      var _isContextualDirRtl = function _isContextualDirRtl(text) {
+        for (var i = 0, charType; i < text.length; i++) {
+          charType = _getCharType(text.charAt(i));
+
+          if (charType === "L") {
+            return false;
+          } else if (charType === "R") {
+            return true;
+          }
+        }
+
+        return false;
+      }; // for reference see 3.3.4 & 3.3.5 in http://unicode.org/reports/tr9/
+      //
+
+
+      var _resolveCharType = function _resolveCharType(chars, types, resolvedTypes, index) {
+        var cType = types[index],
+            wType,
+            nType,
+            i,
+            len;
+
+        switch (cType) {
+          case "L":
+          case "R":
+            _lastArabic = false;
+            break;
+
+          case "N":
+          case "AN":
+            break;
+
+          case "EN":
+            if (_lastArabic) {
+              cType = "AN";
+            }
+
+            break;
+
+          case "AL":
+            _lastArabic = true;
+            cType = "R";
+            break;
+
+          case "WS":
+            cType = "N";
+            break;
+
+          case "CS":
+            if (index < 1 || index + 1 >= types.length || (wType = resolvedTypes[index - 1]) !== "EN" && wType !== "AN" || (nType = types[index + 1]) !== "EN" && nType !== "AN") {
+              cType = "N";
+            } else if (_lastArabic) {
+              nType = "AN";
+            }
+
+            cType = nType === wType ? nType : "N";
+            break;
+
+          case "ES":
+            wType = index > 0 ? resolvedTypes[index - 1] : "B";
+            cType = wType === "EN" && index + 1 < types.length && types[index + 1] === "EN" ? "EN" : "N";
+            break;
+
+          case "ET":
+            if (index > 0 && resolvedTypes[index - 1] === "EN") {
+              cType = "EN";
+              break;
+            } else if (_lastArabic) {
+              cType = "N";
+              break;
+            }
+
+            i = index + 1;
+            len = types.length;
+
+            while (i < len && types[i] === "ET") {
+              i++;
+            }
+
+            if (i < len && types[i] === "EN") {
+              cType = "EN";
+            } else {
+              cType = "N";
+            }
+
+            break;
+
+          case "NSM":
+            if (_isInVisual && !_isInRtl) {
+              //V->L
+              len = types.length;
+              i = index + 1;
+
+              while (i < len && types[i] === "NSM") {
+                i++;
+              }
+
+              if (i < len) {
+                var c = chars[index];
+                var rtlCandidate = c >= 0x0591 && c <= 0x08ff || c === 0xfb1e;
+                wType = types[i];
+
+                if (rtlCandidate && (wType === "R" || wType === "AL")) {
+                  cType = "R";
+                  break;
+                }
+              }
+            }
+
+            if (index < 1 || (wType = types[index - 1]) === "B") {
+              cType = "N";
+            } else {
+              cType = resolvedTypes[index - 1];
+            }
+
+            break;
+
+          case "B":
+            _lastArabic = false;
+            _hasUbatB = true;
+            cType = _dir;
+            break;
+
+          case "S":
+            _hasUbatS = true;
+            cType = "N";
+            break;
+
+          case "LRE":
+          case "RLE":
+          case "LRO":
+          case "RLO":
+          case "PDF":
+            _lastArabic = false;
+            break;
+
+          case "BN":
+            cType = "N";
+            break;
+        }
+
+        return cType;
+      };
+
+      var _handleUbatS = function _handleUbatS(types, levels, length) {
+        for (var i = 0; i < length; i++) {
+          if (types[i] === "S") {
+            levels[i] = _dir;
+
+            for (var j = i - 1; j >= 0; j--) {
+              if (types[j] === "WS") {
+                levels[j] = _dir;
+              } else {
+                break;
+              }
+            }
+          }
+        }
+      };
+
+      var _invertString = function _invertString(text, sourceToTargetMap, levels) {
+        var charArray = text.split("");
+
+        if (levels) {
+          _computeLevels(charArray, levels, {
+            hiLevel: _dir
+          });
+        }
+
+        charArray.reverse();
+        sourceToTargetMap && sourceToTargetMap.reverse();
+        return charArray.join("");
+      }; // For reference see 3.3 in http://unicode.org/reports/tr9/
+      //
+
+
+      var _computeLevels = function _computeLevels(chars, levels, params) {
+        var action,
+            condition,
+            i,
+            index,
+            newLevel,
+            prevState,
+            condPos = -1,
+            len = chars.length,
+            newState = 0,
+            resolvedTypes = [],
+            stateTable = _dir ? _STATE_TABLE_RTL : _STATE_TABLE_LTR,
+            types = [];
+        _lastArabic = false;
+        _hasUbatB = false;
+        _hasUbatS = false;
+
+        for (i = 0; i < len; i++) {
+          types[i] = _getCharType(chars[i]);
+        }
+
+        for (index = 0; index < len; index++) {
+          prevState = newState;
+          resolvedTypes[index] = _resolveCharType(chars, types, resolvedTypes, index);
+          newState = stateTable[prevState][_TYPE_NAMES_MAP[resolvedTypes[index]]];
+          action = newState & 0xf0;
+          newState &= 0x0f;
+          levels[index] = newLevel = stateTable[newState][5];
+
+          if (action > 0) {
+            if (action === 0x10) {
+              for (i = condPos; i < index; i++) {
+                levels[i] = 1;
+              }
+
+              condPos = -1;
+            } else {
+              condPos = -1;
+            }
+          }
+
+          condition = stateTable[newState][6];
+
+          if (condition) {
+            if (condPos === -1) {
+              condPos = index;
+            }
+          } else {
+            if (condPos > -1) {
+              for (i = condPos; i < index; i++) {
+                levels[i] = newLevel;
+              }
+
+              condPos = -1;
+            }
+          }
+
+          if (types[index] === "B") {
+            levels[index] = 0;
+          }
+
+          params.hiLevel |= newLevel;
+        }
+
+        if (_hasUbatS) {
+          _handleUbatS(types, levels, len);
+        }
+      }; // for reference see 3.4 in http://unicode.org/reports/tr9/
+      //
+
+
+      var _invertByLevel = function _invertByLevel(level, charArray, sourceToTargetMap, levels, params) {
+        if (params.hiLevel < level) {
+          return;
+        }
+
+        if (level === 1 && _dir === DIR_RTL && !_hasUbatB) {
+          charArray.reverse();
+          sourceToTargetMap && sourceToTargetMap.reverse();
+          return;
+        }
+
+        var ch,
+            high,
+            end,
+            low,
+            len = charArray.length,
+            start = 0;
+
+        while (start < len) {
+          if (levels[start] >= level) {
+            end = start + 1;
+
+            while (end < len && levels[end] >= level) {
+              end++;
+            }
+
+            for (low = start, high = end - 1; low < high; low++, high--) {
+              ch = charArray[low];
+              charArray[low] = charArray[high];
+              charArray[high] = ch;
+
+              if (sourceToTargetMap) {
+                ch = sourceToTargetMap[low];
+                sourceToTargetMap[low] = sourceToTargetMap[high];
+                sourceToTargetMap[high] = ch;
+              }
+            }
+
+            start = end;
+          }
+
+          start++;
+        }
+      }; // for reference see 7 & BD16 in http://unicode.org/reports/tr9/
+      //
+
+
+      var _symmetricSwap = function _symmetricSwap(charArray, levels, params) {
+        if (params.hiLevel !== 0 && _isSymmetricSwapping) {
+          for (var i = 0, index; i < charArray.length; i++) {
+            if (levels[i] === 1) {
+              index = _SWAP_TABLE.indexOf(charArray[i]);
+
+              if (index >= 0) {
+                charArray[i] = _SWAP_TABLE[index + 1];
+              }
+            }
+          }
+        }
+      };
+
+      var _reorder = function _reorder(text, sourceToTargetMap, levels) {
+        var charArray = text.split(""),
+            params = {
+          hiLevel: _dir
+        };
+
+        if (!levels) {
+          levels = [];
+        }
+
+        _computeLevels(charArray, levels, params);
+
+        _symmetricSwap(charArray, levels, params);
+
+        _invertByLevel(DIR_RTL + 1, charArray, sourceToTargetMap, levels, params);
+
+        _invertByLevel(DIR_RTL, charArray, sourceToTargetMap, levels, params);
+
+        return charArray.join("");
+      }; // doBidiReorder( text, sourceToTargetMap, levels )
+      // Performs Bidi reordering by implementing Unicode Bidi algorithm.
+      // Returns reordered string
+      // @text [String]:
+      // - input string to be reordered, this is input parameter
+      // $sourceToTargetMap [Array] (optional)
+      // - resultant mapping between input and output strings, this is output parameter
+      // $levels [Array] (optional)
+      // - array of calculated Bidi levels, , this is output parameter
+
+
+      this.__bidiEngine__.doBidiReorder = function (text, sourceToTargetMap, levels) {
+        _init(text, sourceToTargetMap);
+
+        if (!_isInVisual && _isOutVisual && !_isOutRtl) {
+          // LLTR->VLTR, LRTL->VLTR
+          _dir = _isInRtl ? DIR_RTL : DIR_LTR;
+          text = _reorder(text, sourceToTargetMap, levels);
+        } else if (_isInVisual && _isOutVisual && _isInRtl ^ _isOutRtl) {
+          // VRTL->VLTR, VLTR->VRTL
+          _dir = _isInRtl ? DIR_RTL : DIR_LTR;
+          text = _invertString(text, sourceToTargetMap, levels);
+        } else if (!_isInVisual && _isOutVisual && _isOutRtl) {
+          // LLTR->VRTL, LRTL->VRTL
+          _dir = _isInRtl ? DIR_RTL : DIR_LTR;
+          text = _reorder(text, sourceToTargetMap, levels);
+          text = _invertString(text, sourceToTargetMap);
+        } else if (_isInVisual && !_isInRtl && !_isOutVisual && !_isOutRtl) {
+          // VLTR->LLTR
+          _dir = DIR_LTR;
+          text = _reorder(text, sourceToTargetMap, levels);
+        } else if (_isInVisual && !_isOutVisual && _isInRtl ^ _isOutRtl) {
+          // VLTR->LRTL, VRTL->LLTR
+          text = _invertString(text, sourceToTargetMap);
+
+          if (_isInRtl) {
+            //LLTR -> VLTR
+            _dir = DIR_LTR;
+            text = _reorder(text, sourceToTargetMap, levels);
+          } else {
+            //LRTL -> VRTL
+            _dir = DIR_RTL;
+            text = _reorder(text, sourceToTargetMap, levels);
+            text = _invertString(text, sourceToTargetMap);
+          }
+        } else if (_isInVisual && _isInRtl && !_isOutVisual && _isOutRtl) {
+          //  VRTL->LRTL
+          _dir = DIR_RTL;
+          text = _reorder(text, sourceToTargetMap, levels);
+          text = _invertString(text, sourceToTargetMap);
+        } else if (!_isInVisual && !_isOutVisual && _isInRtl ^ _isOutRtl) {
+          // LRTL->LLTR, LLTR->LRTL
+          var isSymmetricSwappingOrig = _isSymmetricSwapping;
+
+          if (_isInRtl) {
+            //LRTL->LLTR
+            _dir = DIR_RTL;
+            text = _reorder(text, sourceToTargetMap, levels);
+            _dir = DIR_LTR;
+            _isSymmetricSwapping = false;
+            text = _reorder(text, sourceToTargetMap, levels);
+            _isSymmetricSwapping = isSymmetricSwappingOrig;
+          } else {
+            //LLTR->LRTL
+            _dir = DIR_LTR;
+            text = _reorder(text, sourceToTargetMap, levels);
+            text = _invertString(text, sourceToTargetMap);
+            _dir = DIR_RTL;
+            _isSymmetricSwapping = false;
+            text = _reorder(text, sourceToTargetMap, levels);
+            _isSymmetricSwapping = isSymmetricSwappingOrig;
+            text = _invertString(text, sourceToTargetMap);
+          }
+        }
+
+        return text;
+      };
+      /**
+       * @name setOptions( options )
+       * @function
+       * Sets options for Bidi conversion
+       * @param {Object}:
+       * - isInputVisual {boolean} (defaults to false): allowed values: true(Visual mode), false(Logical mode)
+       * - isInputRtl {boolean}: allowed values true(Right-to-left direction), false (Left-to-right directiion), undefined(Contectual direction, i.e.direction defined by first strong character of input string)
+       * - isOutputVisual {boolean} (defaults to false): allowed values: true(Visual mode), false(Logical mode)
+       * - isOutputRtl {boolean}: allowed values true(Right-to-left direction), false (Left-to-right directiion), undefined(Contectual direction, i.e.direction defined by first strong characterof input string)
+       * - isSymmetricSwapping {boolean} (defaults to false): allowed values true(needs symmetric swapping), false (no need in symmetric swapping),
+       */
+
+
+      this.__bidiEngine__.setOptions = function (options) {
+        if (options) {
+          _isInVisual = options.isInputVisual;
+          _isOutVisual = options.isOutputVisual;
+          _isInRtl = options.isInputRtl;
+          _isOutRtl = options.isOutputRtl;
+          _isSymmetricSwapping = options.isSymmetricSwapping;
+        }
+      };
+
+      this.__bidiEngine__.setOptions(options);
+
+      return this.__bidiEngine__;
+    };
+
+    var _bidiUnicodeTypes = bidiUnicodeTypes;
+    var bidiEngine = new jsPDF.__bidiEngine__({
+      isInputVisual: true
+    });
+
+    var bidiEngineFunction = function bidiEngineFunction(args) {
+      var text = args.text;
+      var x = args.x;
+      var y = args.y;
+      var options = args.options || {};
+      var mutex = args.mutex || {};
+      var lang = options.lang;
+      var tmpText = [];
+      options.isInputVisual = typeof options.isInputVisual === "boolean" ? options.isInputVisual : true;
+      bidiEngine.setOptions(options);
+
+      if (Object.prototype.toString.call(text) === "[object Array]") {
+        var i = 0;
+        tmpText = [];
+
+        for (i = 0; i < text.length; i += 1) {
+          if (Object.prototype.toString.call(text[i]) === "[object Array]") {
+            tmpText.push([bidiEngine.doBidiReorder(text[i][0]), text[i][1], text[i][2]]);
+          } else {
+            tmpText.push([bidiEngine.doBidiReorder(text[i])]);
+          }
+        }
+
+        args.text = tmpText;
+      } else {
+        args.text = bidiEngine.doBidiReorder(text);
+      }
+
+      bidiEngine.setOptions({
+        isInputVisual: true
+      });
+    };
+
+    jsPDF.API.events.push(["postProcessText", bidiEngineFunction]);
+  })(jsPDF);
+
+  /* eslint-disable no-control-regex */
+
+  jsPDF.API.TTFFont = function () {
+    /************************************************************************/
+
+    /* function : open                                                       */
+
+    /* comment : Decode the encoded ttf content and create a TTFFont object. */
+
+    /************************************************************************/
+    TTFFont.open = function (file) {
+      return new TTFFont(file);
+    };
+    /***************************************************************/
+
+    /* function : TTFFont gernerator                               */
+
+    /* comment : Decode TTF contents are parsed, Data,             */
+
+    /* Subset object is created, and registerTTF function is called.*/
+
+    /***************************************************************/
+
+
+    function TTFFont(rawData) {
+      var data;
+      this.rawData = rawData;
+      data = this.contents = new Data(rawData);
+      this.contents.pos = 4;
+
+      if (data.readString(4) === "ttcf") {
+        throw new Error("TTCF not supported.");
+      } else {
+        data.pos = 0;
+        this.parse();
+        this.subset = new Subset(this);
+        this.registerTTF();
+      }
+    }
+    /********************************************************/
+
+    /* function : parse                                     */
+
+    /* comment : TTF Parses the file contents by each table.*/
+
+    /********************************************************/
+
+
+    TTFFont.prototype.parse = function () {
+      this.directory = new Directory(this.contents);
+      this.head = new HeadTable(this);
+      this.name = new NameTable(this);
+      this.cmap = new CmapTable(this);
+      this.toUnicode = {};
+      this.hhea = new HheaTable(this);
+      this.maxp = new MaxpTable(this);
+      this.hmtx = new HmtxTable(this);
+      this.post = new PostTable(this);
+      this.os2 = new OS2Table(this);
+      this.loca = new LocaTable(this);
+      this.glyf = new GlyfTable(this);
+      this.ascender = this.os2.exists && this.os2.ascender || this.hhea.ascender;
+      this.decender = this.os2.exists && this.os2.decender || this.hhea.decender;
+      this.lineGap = this.os2.exists && this.os2.lineGap || this.hhea.lineGap;
+      return this.bbox = [this.head.xMin, this.head.yMin, this.head.xMax, this.head.yMax];
+    };
+    /***************************************************************/
+
+    /* function : registerTTF                                      */
+
+    /* comment : Get the value to assign pdf font descriptors.     */
+
+    /***************************************************************/
+
+
+    TTFFont.prototype.registerTTF = function () {
+      var e, hi, low, raw, _ref;
+
+      this.scaleFactor = 1000.0 / this.head.unitsPerEm;
+
+      this.bbox = function () {
+        var _i, _len, _ref, _results;
+
+        _ref = this.bbox;
+        _results = [];
+
+        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+          e = _ref[_i];
+
+          _results.push(Math.round(e * this.scaleFactor));
+        }
+
+        return _results;
+      }.call(this);
+
+      this.stemV = 0;
+
+      if (this.post.exists) {
+        raw = this.post.italic_angle;
+        hi = raw >> 16;
+        low = raw & 0xff;
+
+        if ((hi & 0x8000) !== 0) {
+          hi = -((hi ^ 0xffff) + 1);
+        }
+
+        this.italicAngle = +("" + hi + "." + low);
+      } else {
+        this.italicAngle = 0;
+      }
+
+      this.ascender = Math.round(this.ascender * this.scaleFactor);
+      this.decender = Math.round(this.decender * this.scaleFactor);
+      this.lineGap = Math.round(this.lineGap * this.scaleFactor);
+      this.capHeight = this.os2.exists && this.os2.capHeight || this.ascender;
+      this.xHeight = this.os2.exists && this.os2.xHeight || 0;
+      this.familyClass = (this.os2.exists && this.os2.familyClass || 0) >> 8;
+      this.isSerif = (_ref = this.familyClass) === 1 || _ref === 2 || _ref === 3 || _ref === 4 || _ref === 5 || _ref === 7;
+      this.isScript = this.familyClass === 10;
+      this.flags = 0;
+
+      if (this.post.isFixedPitch) {
+        this.flags |= 1 << 0;
+      }
+
+      if (this.isSerif) {
+        this.flags |= 1 << 1;
+      }
+
+      if (this.isScript) {
+        this.flags |= 1 << 3;
+      }
+
+      if (this.italicAngle !== 0) {
+        this.flags |= 1 << 6;
+      }
+
+      this.flags |= 1 << 5;
+
+      if (!this.cmap.unicode) {
+        throw new Error("No unicode cmap for font");
+      }
+    };
+
+    TTFFont.prototype.characterToGlyph = function (character) {
+      var _ref;
+
+      return ((_ref = this.cmap.unicode) != null ? _ref.codeMap[character] : void 0) || 0;
+    };
+
+    TTFFont.prototype.widthOfGlyph = function (glyph) {
+      var scale;
+      scale = 1000.0 / this.head.unitsPerEm;
+      return this.hmtx.forGlyph(glyph).advance * scale;
+    };
+
+    TTFFont.prototype.widthOfString = function (string, size, charSpace) {
+      var charCode, i, scale, width, _ref;
+
+      string = "" + string;
+      width = 0;
+
+      for (i = 0, _ref = string.length; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) {
+        charCode = string.charCodeAt(i);
+        width += this.widthOfGlyph(this.characterToGlyph(charCode)) + charSpace * (1000 / size) || 0;
+      }
+
+      scale = size / 1000;
+      return width * scale;
+    };
+
+    TTFFont.prototype.lineHeight = function (size, includeGap) {
+      var gap;
+
+      if (includeGap == null) {
+        includeGap = false;
+      }
+
+      gap = includeGap ? this.lineGap : 0;
+      return (this.ascender + gap - this.decender) / 1000 * size;
+    };
+
+    return TTFFont;
+  }();
+  /************************************************************************************************/
+
+  /* function : Data                                                                              */
+
+  /* comment : The ttf data decoded and stored in an array is read and written to the Data object.*/
+
+  /************************************************************************************************/
+
+
+  var Data = function () {
+    function Data(data) {
+      this.data = data != null ? data : [];
+      this.pos = 0;
+      this.length = this.data.length;
+    }
+
+    Data.prototype.readByte = function () {
+      return this.data[this.pos++];
+    };
+
+    Data.prototype.writeByte = function (byte) {
+      return this.data[this.pos++] = byte;
+    };
+
+    Data.prototype.readUInt32 = function () {
+      var b1, b2, b3, b4;
+      b1 = this.readByte() * 0x1000000;
+      b2 = this.readByte() << 16;
+      b3 = this.readByte() << 8;
+      b4 = this.readByte();
+      return b1 + b2 + b3 + b4;
+    };
+
+    Data.prototype.writeUInt32 = function (val) {
+      this.writeByte(val >>> 24 & 0xff);
+      this.writeByte(val >> 16 & 0xff);
+      this.writeByte(val >> 8 & 0xff);
+      return this.writeByte(val & 0xff);
+    };
+
+    Data.prototype.readInt32 = function () {
+      var int;
+      int = this.readUInt32();
+
+      if (int >= 0x80000000) {
+        return int - 0x100000000;
+      } else {
+        return int;
+      }
+    };
+
+    Data.prototype.writeInt32 = function (val) {
+      if (val < 0) {
+        val += 0x100000000;
+      }
+
+      return this.writeUInt32(val);
+    };
+
+    Data.prototype.readUInt16 = function () {
+      var b1, b2;
+      b1 = this.readByte() << 8;
+      b2 = this.readByte();
+      return b1 | b2;
+    };
+
+    Data.prototype.writeUInt16 = function (val) {
+      this.writeByte(val >> 8 & 0xff);
+      return this.writeByte(val & 0xff);
+    };
+
+    Data.prototype.readInt16 = function () {
+      var int;
+      int = this.readUInt16();
+
+      if (int >= 0x8000) {
+        return int - 0x10000;
+      } else {
+        return int;
+      }
+    };
+
+    Data.prototype.writeInt16 = function (val) {
+      if (val < 0) {
+        val += 0x10000;
+      }
+
+      return this.writeUInt16(val);
+    };
+
+    Data.prototype.readString = function (length) {
+      var i, ret;
+      ret = [];
+
+      for (i = 0; 0 <= length ? i < length : i > length; i = 0 <= length ? ++i : --i) {
+        ret[i] = String.fromCharCode(this.readByte());
+      }
+
+      return ret.join("");
+    };
+
+    Data.prototype.writeString = function (val) {
+      var i, _ref, _results;
+
+      _results = [];
+
+      for (i = 0, _ref = val.length; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) {
+        _results.push(this.writeByte(val.charCodeAt(i)));
+      }
+
+      return _results;
+    };
+    /*Data.prototype.stringAt = function (pos, length) {
+              this.pos = pos;
+              return this.readString(length);
+          };*/
+
+
+    Data.prototype.readShort = function () {
+      return this.readInt16();
+    };
+
+    Data.prototype.writeShort = function (val) {
+      return this.writeInt16(val);
+    };
+
+    Data.prototype.readLongLong = function () {
+      var b1, b2, b3, b4, b5, b6, b7, b8;
+      b1 = this.readByte();
+      b2 = this.readByte();
+      b3 = this.readByte();
+      b4 = this.readByte();
+      b5 = this.readByte();
+      b6 = this.readByte();
+      b7 = this.readByte();
+      b8 = this.readByte();
+
+      if (b1 & 0x80) {
+        return ((b1 ^ 0xff) * 0x100000000000000 + (b2 ^ 0xff) * 0x1000000000000 + (b3 ^ 0xff) * 0x10000000000 + (b4 ^ 0xff) * 0x100000000 + (b5 ^ 0xff) * 0x1000000 + (b6 ^ 0xff) * 0x10000 + (b7 ^ 0xff) * 0x100 + (b8 ^ 0xff) + 1) * -1;
+      }
+
+      return b1 * 0x100000000000000 + b2 * 0x1000000000000 + b3 * 0x10000000000 + b4 * 0x100000000 + b5 * 0x1000000 + b6 * 0x10000 + b7 * 0x100 + b8;
+    };
+
+    Data.prototype.writeLongLong = function (val) {
+      var high, low;
+      high = Math.floor(val / 0x100000000);
+      low = val & 0xffffffff;
+      this.writeByte(high >> 24 & 0xff);
+      this.writeByte(high >> 16 & 0xff);
+      this.writeByte(high >> 8 & 0xff);
+      this.writeByte(high & 0xff);
+      this.writeByte(low >> 24 & 0xff);
+      this.writeByte(low >> 16 & 0xff);
+      this.writeByte(low >> 8 & 0xff);
+      return this.writeByte(low & 0xff);
+    };
+
+    Data.prototype.readInt = function () {
+      return this.readInt32();
+    };
+
+    Data.prototype.writeInt = function (val) {
+      return this.writeInt32(val);
+    };
+    /*Data.prototype.slice = function (start, end) {
+              return this.data.slice(start, end);
+          };*/
+
+
+    Data.prototype.read = function (bytes) {
+      var buf, i;
+      buf = [];
+
+      for (i = 0; 0 <= bytes ? i < bytes : i > bytes; i = 0 <= bytes ? ++i : --i) {
+        buf.push(this.readByte());
+      }
+
+      return buf;
+    };
+
+    Data.prototype.write = function (bytes) {
+      var byte, i, _len, _results;
+
+      _results = [];
+
+      for (i = 0, _len = bytes.length; i < _len; i++) {
+        byte = bytes[i];
+
+        _results.push(this.writeByte(byte));
+      }
+
+      return _results;
+    };
+
+    return Data;
+  }();
+
+  var Directory = function () {
+    var checksum;
+    /*****************************************************************************************************/
+
+    /* function : Directory generator                                                                    */
+
+    /* comment : Initialize the offset, tag, length, and checksum for each table for the font to be used.*/
+
+    /*****************************************************************************************************/
+
+    function Directory(data) {
+      var entry, i, _ref;
+
+      this.scalarType = data.readInt();
+      this.tableCount = data.readShort();
+      this.searchRange = data.readShort();
+      this.entrySelector = data.readShort();
+      this.rangeShift = data.readShort();
+      this.tables = {};
+
+      for (i = 0, _ref = this.tableCount; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) {
+        entry = {
+          tag: data.readString(4),
+          checksum: data.readInt(),
+          offset: data.readInt(),
+          length: data.readInt()
+        };
+        this.tables[entry.tag] = entry;
+      }
+    }
+    /********************************************************************************************************/
+
+    /* function : encode                                                                                    */
+
+    /* comment : It encodes and stores the font table object and information used for the directory object. */
+
+    /********************************************************************************************************/
+
+
+    Directory.prototype.encode = function (tables) {
+      var adjustment, directory, directoryLength, entrySelector, headOffset, log2, offset, rangeShift, searchRange, sum, table, tableCount, tableData, tag;
+      tableCount = Object.keys(tables).length;
+      log2 = Math.log(2);
+      searchRange = Math.floor(Math.log(tableCount) / log2) * 16;
+      entrySelector = Math.floor(searchRange / log2);
+      rangeShift = tableCount * 16 - searchRange;
+      directory = new Data();
+      directory.writeInt(this.scalarType);
+      directory.writeShort(tableCount);
+      directory.writeShort(searchRange);
+      directory.writeShort(entrySelector);
+      directory.writeShort(rangeShift);
+      directoryLength = tableCount * 16;
+      offset = directory.pos + directoryLength;
+      headOffset = null;
+      tableData = [];
+
+      for (tag in tables) {
+        table = tables[tag];
+        directory.writeString(tag);
+        directory.writeInt(checksum(table));
+        directory.writeInt(offset);
+        directory.writeInt(table.length);
+        tableData = tableData.concat(table);
+
+        if (tag === "head") {
+          headOffset = offset;
+        }
+
+        offset += table.length;
+
+        while (offset % 4) {
+          tableData.push(0);
+          offset++;
+        }
+      }
+
+      directory.write(tableData);
+      sum = checksum(directory.data);
+      adjustment = 0xb1b0afba - sum;
+      directory.pos = headOffset + 8;
+      directory.writeUInt32(adjustment);
+      return directory.data;
+    };
+    /***************************************************************/
+
+    /* function : checksum                                         */
+
+    /* comment : Duplicate the table for the tag.                  */
+
+    /***************************************************************/
+
+
+    checksum = function checksum(data) {
+      var i, sum, tmp, _ref;
+
+      data = __slice.call(data);
+
+      while (data.length % 4) {
+        data.push(0);
+      }
+
+      tmp = new Data(data);
+      sum = 0;
+
+      for (i = 0, _ref = data.length; i < _ref; i = i += 4) {
+        sum += tmp.readUInt32();
+      }
+
+      return sum & 0xffffffff;
+    };
+
+    return Directory;
+  }();
+
+  var Table,
+      __hasProp = {}.hasOwnProperty,
+      __extends = function __extends(child, parent) {
+    for (var key in parent) {
+      if (__hasProp.call(parent, key)) child[key] = parent[key];
+    }
+
+    function ctor() {
+      this.constructor = child;
+    }
+
+    ctor.prototype = parent.prototype;
+    child.prototype = new ctor();
+    child.__super__ = parent.prototype;
+    return child;
+  };
+  /***************************************************************/
+
+  /* function : Table                                            */
+
+  /* comment : Save info for each table, and parse the table.    */
+
+  /***************************************************************/
+
+
+  Table = function () {
+    function Table(file) {
+      var info;
+      this.file = file;
+      info = this.file.directory.tables[this.tag];
+      this.exists = !!info;
+
+      if (info) {
+        this.offset = info.offset, this.length = info.length;
+        this.parse(this.file.contents);
+      }
+    }
+
+    Table.prototype.parse = function () {};
+
+    Table.prototype.encode = function () {};
+
+    Table.prototype.raw = function () {
+      if (!this.exists) {
+        return null;
+      }
+
+      this.file.contents.pos = this.offset;
+      return this.file.contents.read(this.length);
+    };
+
+    return Table;
+  }();
+
+  var HeadTable = function (_super) {
+    __extends(HeadTable, _super);
+
+    function HeadTable() {
+      return HeadTable.__super__.constructor.apply(this, arguments);
+    }
+
+    HeadTable.prototype.tag = "head";
+
+    HeadTable.prototype.parse = function (data) {
+      data.pos = this.offset;
+      this.version = data.readInt();
+      this.revision = data.readInt();
+      this.checkSumAdjustment = data.readInt();
+      this.magicNumber = data.readInt();
+      this.flags = data.readShort();
+      this.unitsPerEm = data.readShort();
+      this.created = data.readLongLong();
+      this.modified = data.readLongLong();
+      this.xMin = data.readShort();
+      this.yMin = data.readShort();
+      this.xMax = data.readShort();
+      this.yMax = data.readShort();
+      this.macStyle = data.readShort();
+      this.lowestRecPPEM = data.readShort();
+      this.fontDirectionHint = data.readShort();
+      this.indexToLocFormat = data.readShort();
+      return this.glyphDataFormat = data.readShort();
+    };
+
+    HeadTable.prototype.encode = function (indexToLocFormat) {
+      var table;
+      table = new Data();
+      table.writeInt(this.version);
+      table.writeInt(this.revision);
+      table.writeInt(this.checkSumAdjustment);
+      table.writeInt(this.magicNumber);
+      table.writeShort(this.flags);
+      table.writeShort(this.unitsPerEm);
+      table.writeLongLong(this.created);
+      table.writeLongLong(this.modified);
+      table.writeShort(this.xMin);
+      table.writeShort(this.yMin);
+      table.writeShort(this.xMax);
+      table.writeShort(this.yMax);
+      table.writeShort(this.macStyle);
+      table.writeShort(this.lowestRecPPEM);
+      table.writeShort(this.fontDirectionHint);
+      table.writeShort(indexToLocFormat);
+      table.writeShort(this.glyphDataFormat);
+      return table.data;
+    };
+
+    return HeadTable;
+  }(Table);
+  /************************************************************************************/
+
+  /* function : CmapEntry                                                             */
+
+  /* comment : Cmap Initializes and encodes object information (required by pdf spec).*/
+
+  /************************************************************************************/
+
+
+  var CmapEntry = function () {
+    function CmapEntry(data, offset) {
+      var code, count, endCode, glyphId, glyphIds, i, idDelta, idRangeOffset, index, saveOffset, segCount, segCountX2, start, startCode, tail, _j, _k, _len;
+
+      this.platformID = data.readUInt16();
+      this.encodingID = data.readShort();
+      this.offset = offset + data.readInt();
+      saveOffset = data.pos;
+      data.pos = this.offset;
+      this.format = data.readUInt16();
+      this.length = data.readUInt16();
+      this.language = data.readUInt16();
+      this.isUnicode = this.platformID === 3 && this.encodingID === 1 && this.format === 4 || this.platformID === 0 && this.format === 4;
+      this.codeMap = {};
+
+      switch (this.format) {
+        case 0:
+          for (i = 0; i < 256; ++i) {
+            this.codeMap[i] = data.readByte();
+          }
+
+          break;
+
+        case 4:
+          segCountX2 = data.readUInt16();
+          segCount = segCountX2 / 2;
+          data.pos += 6;
+
+          endCode = function () {
+            var _j, _results;
+
+            _results = [];
+
+            for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
+              _results.push(data.readUInt16());
+            }
+
+            return _results;
+          }();
+
+          data.pos += 2;
+
+          startCode = function () {
+            var _j, _results;
+
+            _results = [];
+
+            for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
+              _results.push(data.readUInt16());
+            }
+
+            return _results;
+          }();
+
+          idDelta = function () {
+            var _j, _results;
+
+            _results = [];
+
+            for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
+              _results.push(data.readUInt16());
+            }
+
+            return _results;
+          }();
+
+          idRangeOffset = function () {
+            var _j, _results;
+
+            _results = [];
+
+            for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
+              _results.push(data.readUInt16());
+            }
+
+            return _results;
+          }();
+
+          count = (this.length - data.pos + this.offset) / 2;
+
+          glyphIds = function () {
+            var _j, _results;
+
+            _results = [];
+
+            for (i = _j = 0; 0 <= count ? _j < count : _j > count; i = 0 <= count ? ++_j : --_j) {
+              _results.push(data.readUInt16());
+            }
+
+            return _results;
+          }();
+
+          for (i = _j = 0, _len = endCode.length; _j < _len; i = ++_j) {
+            tail = endCode[i];
+            start = startCode[i];
+
+            for (code = _k = start; start <= tail ? _k <= tail : _k >= tail; code = start <= tail ? ++_k : --_k) {
+              if (idRangeOffset[i] === 0) {
+                glyphId = code + idDelta[i];
+              } else {
+                index = idRangeOffset[i] / 2 + (code - start) - (segCount - i);
+                glyphId = glyphIds[index] || 0;
+
+                if (glyphId !== 0) {
+                  glyphId += idDelta[i];
+                }
               }
+
+              this.codeMap[code] = glyphId & 0xffff;
+            }
+          }
+
+      }
+
+      data.pos = saveOffset;
+    }
+
+    CmapEntry.encode = function (charmap, encoding) {
+      var charMap, code, codeMap, codes, delta, deltas, diff, endCode, endCodes, entrySelector, glyphIDs, i, id, indexes, last, map, nextID, offset, old, rangeOffsets, rangeShift, searchRange, segCount, segCountX2, startCode, startCodes, startGlyph, subtable, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _len6, _len7, _m, _n, _name, _o, _p, _q;
+
+      subtable = new Data();
+      codes = Object.keys(charmap).sort(function (a, b) {
+        return a - b;
+      });
+
+      switch (encoding) {
+        case "macroman":
+          id = 0;
+
+          indexes = function () {
+            var _results = [];
+
+            for (i = 0; i < 256; ++i) {
+              _results.push(0);
+            }
+
+            return _results;
+          }();
+
+          map = {
+            0: 0
           };
-          return CmapEntry;
-      })();
+          codeMap = {};
+
+          for (_i = 0, _len = codes.length; _i < _len; _i++) {
+            code = codes[_i];
+
+            if (map[_name = charmap[code]] == null) {
+              map[_name] = ++id;
+            }
+
+            codeMap[code] = {
+              old: charmap[code],
+              new: map[charmap[code]]
+            };
+            indexes[code] = map[charmap[code]];
+          }
+
+          subtable.writeUInt16(1);
+          subtable.writeUInt16(0);
+          subtable.writeUInt32(12);
+          subtable.writeUInt16(0);
+          subtable.writeUInt16(262);
+          subtable.writeUInt16(0);
+          subtable.write(indexes);
+          return {
+            charMap: codeMap,
+            subtable: subtable.data,
+            maxGlyphID: id + 1
+          };
+
+        case "unicode":
+          startCodes = [];
+          endCodes = [];
+          nextID = 0;
+          map = {};
+          charMap = {};
+          last = diff = null;
+
+          for (_j = 0, _len1 = codes.length; _j < _len1; _j++) {
+            code = codes[_j];
+            old = charmap[code];
+
+            if (map[old] == null) {
+              map[old] = ++nextID;
+            }
+
+            charMap[code] = {
+              old: old,
+              new: map[old]
+            };
+            delta = map[old] - code;
+
+            if (last == null || delta !== diff) {
+              if (last) {
+                endCodes.push(last);
+              }
+
+              startCodes.push(code);
+              diff = delta;
+            }
+
+            last = code;
+          }
+
+          if (last) {
+            endCodes.push(last);
+          }
+
+          endCodes.push(0xffff);
+          startCodes.push(0xffff);
+          segCount = startCodes.length;
+          segCountX2 = segCount * 2;
+          searchRange = 2 * Math.pow(Math.log(segCount) / Math.LN2, 2);
+          entrySelector = Math.log(searchRange / 2) / Math.LN2;
+          rangeShift = 2 * segCount - searchRange;
+          deltas = [];
+          rangeOffsets = [];
+          glyphIDs = [];
+
+          for (i = _k = 0, _len2 = startCodes.length; _k < _len2; i = ++_k) {
+            startCode = startCodes[i];
+            endCode = endCodes[i];
+
+            if (startCode === 0xffff) {
+              deltas.push(0);
+              rangeOffsets.push(0);
+              break;
+            }
+
+            startGlyph = charMap[startCode]["new"];
+
+            if (startCode - startGlyph >= 0x8000) {
+              deltas.push(0);
+              rangeOffsets.push(2 * (glyphIDs.length + segCount - i));
+
+              for (code = _l = startCode; startCode <= endCode ? _l <= endCode : _l >= endCode; code = startCode <= endCode ? ++_l : --_l) {
+                glyphIDs.push(charMap[code]["new"]);
+              }
+            } else {
+              deltas.push(startGlyph - startCode);
+              rangeOffsets.push(0);
+            }
+          }
+
+          subtable.writeUInt16(3);
+          subtable.writeUInt16(1);
+          subtable.writeUInt32(12);
+          subtable.writeUInt16(4);
+          subtable.writeUInt16(16 + segCount * 8 + glyphIDs.length * 2);
+          subtable.writeUInt16(0);
+          subtable.writeUInt16(segCountX2);
+          subtable.writeUInt16(searchRange);
+          subtable.writeUInt16(entrySelector);
+          subtable.writeUInt16(rangeShift);
+
+          for (_m = 0, _len3 = endCodes.length; _m < _len3; _m++) {
+            code = endCodes[_m];
+            subtable.writeUInt16(code);
+          }
+
+          subtable.writeUInt16(0);
+
+          for (_n = 0, _len4 = startCodes.length; _n < _len4; _n++) {
+            code = startCodes[_n];
+            subtable.writeUInt16(code);
+          }
+
+          for (_o = 0, _len5 = deltas.length; _o < _len5; _o++) {
+            delta = deltas[_o];
+            subtable.writeUInt16(delta);
+          }
+
+          for (_p = 0, _len6 = rangeOffsets.length; _p < _len6; _p++) {
+            offset = rangeOffsets[_p];
+            subtable.writeUInt16(offset);
+          }
+
+          for (_q = 0, _len7 = glyphIDs.length; _q < _len7; _q++) {
+            id = glyphIDs[_q];
+            subtable.writeUInt16(id);
+          }
+
+          return {
+            charMap: charMap,
+            subtable: subtable.data,
+            maxGlyphID: nextID + 1
+          };
+      }
+    };
+
+    return CmapEntry;
+  }();
+
+  var CmapTable = function (_super) {
+    __extends(CmapTable, _super);
+
+    function CmapTable() {
+      return CmapTable.__super__.constructor.apply(this, arguments);
+    }
+
+    CmapTable.prototype.tag = "cmap";
+
+    CmapTable.prototype.parse = function (data) {
+      var entry, i, tableCount;
+      data.pos = this.offset;
+      this.version = data.readUInt16();
+      tableCount = data.readUInt16();
+      this.tables = [];
+      this.unicode = null;
+
+      for (i = 0; 0 <= tableCount ? i < tableCount : i > tableCount; i = 0 <= tableCount ? ++i : --i) {
+        entry = new CmapEntry(data, this.offset);
+        this.tables.push(entry);
+
+        if (entry.isUnicode) {
+          if (this.unicode == null) {
+            this.unicode = entry;
+          }
+        }
+      }
+
+      return true;
+    };
+    /*************************************************************************/
+
+    /* function : encode                                                     */
+
+    /* comment : Encode the cmap table corresponding to the input character. */
+
+    /*************************************************************************/
+
+
+    CmapTable.encode = function (charmap, encoding) {
+      var result, table;
+
+      if (encoding == null) {
+        encoding = "macroman";
+      }
+
+      result = CmapEntry.encode(charmap, encoding);
+      table = new Data();
+      table.writeUInt16(0);
+      table.writeUInt16(1);
+      result.table = table.data.concat(result.subtable);
+      return result;
+    };
+
+    return CmapTable;
+  }(Table);
+
+  var HheaTable = function (_super) {
+    __extends(HheaTable, _super);
+
+    function HheaTable() {
+      return HheaTable.__super__.constructor.apply(this, arguments);
+    }
+
+    HheaTable.prototype.tag = "hhea";
+
+    HheaTable.prototype.parse = function (data) {
+      data.pos = this.offset;
+      this.version = data.readInt();
+      this.ascender = data.readShort();
+      this.decender = data.readShort();
+      this.lineGap = data.readShort();
+      this.advanceWidthMax = data.readShort();
+      this.minLeftSideBearing = data.readShort();
+      this.minRightSideBearing = data.readShort();
+      this.xMaxExtent = data.readShort();
+      this.caretSlopeRise = data.readShort();
+      this.caretSlopeRun = data.readShort();
+      this.caretOffset = data.readShort();
+      data.pos += 4 * 2;
+      this.metricDataFormat = data.readShort();
+      return this.numberOfMetrics = data.readUInt16();
+    };
+    /*HheaTable.prototype.encode = function (ids) {
+              var i, table, _i, _ref;
+              table = new Data;
+              table.writeInt(this.version);
+              table.writeShort(this.ascender);
+              table.writeShort(this.decender);
+              table.writeShort(this.lineGap);
+              table.writeShort(this.advanceWidthMax);
+              table.writeShort(this.minLeftSideBearing);
+              table.writeShort(this.minRightSideBearing);
+              table.writeShort(this.xMaxExtent);
+              table.writeShort(this.caretSlopeRise);
+              table.writeShort(this.caretSlopeRun);
+              table.writeShort(this.caretOffset);
+              for (i = _i = 0, _ref = 4 * 2; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
+                  table.writeByte(0);
+              }
+              table.writeShort(this.metricDataFormat);
+              table.writeUInt16(ids.length);
+              return table.data;
+          };*/
+
+
+    return HheaTable;
+  }(Table);
+
+  var OS2Table = function (_super) {
+    __extends(OS2Table, _super);
+
+    function OS2Table() {
+      return OS2Table.__super__.constructor.apply(this, arguments);
+    }
+
+    OS2Table.prototype.tag = "OS/2";
+
+    OS2Table.prototype.parse = function (data) {
+      data.pos = this.offset;
+      this.version = data.readUInt16();
+      this.averageCharWidth = data.readShort();
+      this.weightClass = data.readUInt16();
+      this.widthClass = data.readUInt16();
+      this.type = data.readShort();
+      this.ySubscriptXSize = data.readShort();
+      this.ySubscriptYSize = data.readShort();
+      this.ySubscriptXOffset = data.readShort();
+      this.ySubscriptYOffset = data.readShort();
+      this.ySuperscriptXSize = data.readShort();
+      this.ySuperscriptYSize = data.readShort();
+      this.ySuperscriptXOffset = data.readShort();
+      this.ySuperscriptYOffset = data.readShort();
+      this.yStrikeoutSize = data.readShort();
+      this.yStrikeoutPosition = data.readShort();
+      this.familyClass = data.readShort();
+
+      this.panose = function () {
+        var i, _results;
+
+        _results = [];
+
+        for (i = 0; i < 10; ++i) {
+          _results.push(data.readByte());
+        }
+
+        return _results;
+      }();
+
+      this.charRange = function () {
+        var i, _results;
+
+        _results = [];
+
+        for (i = 0; i < 4; ++i) {
+          _results.push(data.readInt());
+        }
+
+        return _results;
+      }();
+
+      this.vendorID = data.readString(4);
+      this.selection = data.readShort();
+      this.firstCharIndex = data.readShort();
+      this.lastCharIndex = data.readShort();
+
+      if (this.version > 0) {
+        this.ascent = data.readShort();
+        this.descent = data.readShort();
+        this.lineGap = data.readShort();
+        this.winAscent = data.readShort();
+        this.winDescent = data.readShort();
+
+        this.codePageRange = function () {
+          var i, _results;
+
+          _results = [];
+
+          for (i = 0; i < 2; i = ++i) {
+            _results.push(data.readInt());
+          }
+
+          return _results;
+        }();
+
+        if (this.version > 1) {
+          this.xHeight = data.readShort();
+          this.capHeight = data.readShort();
+          this.defaultChar = data.readShort();
+          this.breakChar = data.readShort();
+          return this.maxContext = data.readShort();
+        }
+      }
+    };
+    /*OS2Table.prototype.encode = function () {
+              return this.raw();
+          };*/
+
+
+    return OS2Table;
+  }(Table);
+
+  var PostTable = function (_super) {
+
+    __extends(PostTable, _super);
+
+    function PostTable() {
+      return PostTable.__super__.constructor.apply(this, arguments);
+    }
 
-      var CmapTable = (function (_super) {
-          __extends(CmapTable, _super);
+    PostTable.prototype.tag = "post";
 
-          function CmapTable() {
-              return CmapTable.__super__.constructor.apply(this, arguments);
-          }
-          CmapTable.prototype.tag = 'cmap';
-          CmapTable.prototype.parse = function (data) {
-              var entry, i, tableCount, _i;
-              data.pos = this.offset;
-              this.version = data.readUInt16();
-              tableCount = data.readUInt16();
-              this.tables = [];
-              this.unicode = null;
-              for (i = _i = 0; 0 <= tableCount ? _i < tableCount : _i > tableCount; i = 0 <= tableCount ? ++_i : --_i) {
-                  entry = new CmapEntry(data, this.offset);
-                  this.tables.push(entry);
-                  if (entry.isUnicode) {
-                      if (this.unicode == null) {
-                          this.unicode = entry;
-                      }
-                  }
-              }
-              return true;
-          };
-          /*************************************************************************/
-          /* function : encode                                                     */
-          /* comment : Encode the cmap table corresponding to the input character. */
-          /*************************************************************************/
-          CmapTable.encode = function (charmap, encoding) {
-              var result, table;
-              if (encoding == null) {
-                  encoding = 'macroman';
-              }
-              result = CmapEntry.encode(charmap, encoding);
-              table = new Data;
-              table.writeUInt16(0);
-              table.writeUInt16(1);
-              result.table = table.data.concat(result.subtable);
-              return result;
-          };
-          return CmapTable;
-      })(Table);
+    PostTable.prototype.parse = function (data) {
+      var length, numberOfGlyphs, _results;
 
-      var HheaTable = (function (_super) {
-          __extends(HheaTable, _super);
+      data.pos = this.offset;
+      this.format = data.readInt();
+      this.italicAngle = data.readInt();
+      this.underlinePosition = data.readShort();
+      this.underlineThickness = data.readShort();
+      this.isFixedPitch = data.readInt();
+      this.minMemType42 = data.readInt();
+      this.maxMemType42 = data.readInt();
+      this.minMemType1 = data.readInt();
+      this.maxMemType1 = data.readInt();
 
-          function HheaTable() {
-              return HheaTable.__super__.constructor.apply(this, arguments);
-          }
-          HheaTable.prototype.tag = 'hhea';
-          HheaTable.prototype.parse = function (data) {
-              data.pos = this.offset;
-              this.version = data.readInt();
-              this.ascender = data.readShort();
-              this.decender = data.readShort();
-              this.lineGap = data.readShort();
-              this.advanceWidthMax = data.readShort();
-              this.minLeftSideBearing = data.readShort();
-              this.minRightSideBearing = data.readShort();
-              this.xMaxExtent = data.readShort();
-              this.caretSlopeRise = data.readShort();
-              this.caretSlopeRun = data.readShort();
-              this.caretOffset = data.readShort();
-              data.pos += 4 * 2;
-              this.metricDataFormat = data.readShort();
-              return this.numberOfMetrics = data.readUInt16();
-          };
-          /*HheaTable.prototype.encode = function (ids) {
-              var i, table, _i, _ref;
-              table = new Data;
-              table.writeInt(this.version);
-              table.writeShort(this.ascender);
-              table.writeShort(this.decender);
-              table.writeShort(this.lineGap);
-              table.writeShort(this.advanceWidthMax);
-              table.writeShort(this.minLeftSideBearing);
-              table.writeShort(this.minRightSideBearing);
-              table.writeShort(this.xMaxExtent);
-              table.writeShort(this.caretSlopeRise);
-              table.writeShort(this.caretSlopeRun);
-              table.writeShort(this.caretOffset);
-              for (i = _i = 0, _ref = 4 * 2; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
-                  table.writeByte(0);
-              }
-              table.writeShort(this.metricDataFormat);
-              table.writeUInt16(ids.length);
-              return table.data;
-          };*/
-          return HheaTable;
-      })(Table);
+      switch (this.format) {
+        case 0x00010000:
+          break;
 
-      var OS2Table = (function (_super) {
-          __extends(OS2Table, _super);
+        case 0x00020000:
+          numberOfGlyphs = data.readUInt16();
+          this.glyphNameIndex = [];
+          var i;
 
-          function OS2Table() {
-              return OS2Table.__super__.constructor.apply(this, arguments);
+          for (i = 0; 0 <= numberOfGlyphs ? i < numberOfGlyphs : i > numberOfGlyphs; i = 0 <= numberOfGlyphs ? ++i : --i) {
+            this.glyphNameIndex.push(data.readUInt16());
           }
-          OS2Table.prototype.tag = 'OS/2';
-          OS2Table.prototype.parse = function (data) {
-              var i;
-              data.pos = this.offset;
-              this.version = data.readUInt16();
-              this.averageCharWidth = data.readShort();
-              this.weightClass = data.readUInt16();
-              this.widthClass = data.readUInt16();
-              this.type = data.readShort();
-              this.ySubscriptXSize = data.readShort();
-              this.ySubscriptYSize = data.readShort();
-              this.ySubscriptXOffset = data.readShort();
-              this.ySubscriptYOffset = data.readShort();
-              this.ySuperscriptXSize = data.readShort();
-              this.ySuperscriptYSize = data.readShort();
-              this.ySuperscriptXOffset = data.readShort();
-              this.ySuperscriptYOffset = data.readShort();
-              this.yStrikeoutSize = data.readShort();
-              this.yStrikeoutPosition = data.readShort();
-              this.familyClass = data.readShort();
-              this.panose = (function () {
-                  var _i, _results;
-                  _results = [];
-                  for (i = _i = 0; _i < 10; i = ++_i) {
-                      _results.push(data.readByte());
-                  }
-                  return _results;
-              })();
-              this.charRange = (function () {
-                  var _i, _results;
-                  _results = [];
-                  for (i = _i = 0; _i < 4; i = ++_i) {
-                      _results.push(data.readInt());
-                  }
-                  return _results;
-              })();
-              this.vendorID = data.readString(4);
-              this.selection = data.readShort();
-              this.firstCharIndex = data.readShort();
-              this.lastCharIndex = data.readShort();
-              if (this.version > 0) {
-                  this.ascent = data.readShort();
-                  this.descent = data.readShort();
-                  this.lineGap = data.readShort();
-                  this.winAscent = data.readShort();
-                  this.winDescent = data.readShort();
-                  this.codePageRange = (function () {
-                      var _i, _results;
-                      _results = [];
-                      for (i = _i = 0; _i < 2; i = ++_i) {
-                          _results.push(data.readInt());
-                      }
-                      return _results;
-                  })();
-                  if (this.version > 1) {
-                      this.xHeight = data.readShort();
-                      this.capHeight = data.readShort();
-                      this.defaultChar = data.readShort();
-                      this.breakChar = data.readShort();
-                      return this.maxContext = data.readShort();
-                  }
-              }
-          };
-          /*OS2Table.prototype.encode = function () {
-              return this.raw();
-          };*/
-          return OS2Table;
-      })(Table);
 
-      var PostTable = (function (_super) {
-          __extends(PostTable, _super);
+          this.names = [];
+          _results = [];
 
-          function PostTable() {
-              return PostTable.__super__.constructor.apply(this, arguments);
-          }
-          PostTable.prototype.tag = 'post';
-          PostTable.prototype.parse = function (data) {
-              var i, length, numberOfGlyphs, _i, _results;
-              data.pos = this.offset;
-              this.format = data.readInt();
-              this.italicAngle = data.readInt();
-              this.underlinePosition = data.readShort();
-              this.underlineThickness = data.readShort();
-              this.isFixedPitch = data.readInt();
-              this.minMemType42 = data.readInt();
-              this.maxMemType42 = data.readInt();
-              this.minMemType1 = data.readInt();
-              this.maxMemType1 = data.readInt();
-              switch (this.format) {
-              case 0x00010000:
-                  break;
-              case 0x00020000:
-                  numberOfGlyphs = data.readUInt16();
-                  this.glyphNameIndex = [];
-                  for (i = _i = 0; 0 <= numberOfGlyphs ? _i < numberOfGlyphs : _i > numberOfGlyphs; i = 0 <= numberOfGlyphs ? ++_i : --_i) {
-                      this.glyphNameIndex.push(data.readUInt16());
-                  }
-                  this.names = [];
-                  _results = [];
-                  while (data.pos < this.offset + this.length) {
-                      length = data.readByte();
-                      _results.push(this.names.push(data.readString(length)));
-                  }
-                  return _results;
-                  break;
-              case 0x00025000:
-                  numberOfGlyphs = data.readUInt16();
-                  return this.offsets = data.read(numberOfGlyphs);
-              case 0x00030000:
-                  break;
-              case 0x00040000:
-                  return this.map = (function () {
-                      var _j, _ref, _results1;
-                      _results1 = [];
-                      for (i = _j = 0, _ref = this.file.maxp.numGlyphs; 0 <= _ref ? _j < _ref : _j > _ref; i = 0 <= _ref ? ++_j : --_j) {
-                          _results1.push(data.readUInt32());
-                      }
-                      return _results1;
-                  }).call(this);
-              }
-          };
-          return PostTable;
-      })(Table);
-
-      /*********************************************************************************************************/
-      /* function : NameEntry                                                                                  */
-      /* comment : Store copyright information, platformID, encodingID, and languageID in the NameEntry object.*/
-      /*********************************************************************************************************/
-      var NameEntry = (function () {
-          function NameEntry(raw, entry) {
-              this.raw = raw;
-              this.length = raw.length;
-              this.platformID = entry.platformID;
-              this.encodingID = entry.encodingID;
-              this.languageID = entry.languageID;
+          while (data.pos < this.offset + this.length) {
+            length = data.readByte();
+
+            _results.push(this.names.push(data.readString(length)));
           }
-          return NameEntry;
-      })();
 
-      var NameTable = (function (_super) {
-          __extends(NameTable, _super);
+          return _results;
 
-          function NameTable() {
-              return NameTable.__super__.constructor.apply(this, arguments);
-          }
-          NameTable.prototype.tag = 'name';
-          NameTable.prototype.parse = function (data) {
-              var count, entries, entry, format, i, name, stringOffset, strings, text, _i, _j, _len, _name;
-              data.pos = this.offset;
-              format = data.readShort();
-              count = data.readShort();
-              stringOffset = data.readShort();
-              entries = [];
-              for (i = _i = 0; 0 <= count ? _i < count : _i > count; i = 0 <= count ? ++_i : --_i) {
-                  entries.push({
-                      platformID: data.readShort()
-                      , encodingID: data.readShort()
-                      , languageID: data.readShort()
-                      , nameID: data.readShort()
-                      , length: data.readShort()
-                      , offset: this.offset + stringOffset + data.readShort()
-                  });
-              }
-              strings = {};
-              for (i = _j = 0, _len = entries.length; _j < _len; i = ++_j) {
-                  entry = entries[i];
-                  data.pos = entry.offset;
-                  text = data.readString(entry.length);
-                  name = new NameEntry(text, entry);
-                  if (strings[_name = entry.nameID] == null) {
-                      strings[_name] = [];
-                  }
-                  strings[entry.nameID].push(name);
-              }
-              this.strings = strings;
-              this.copyright = strings[0];
-              this.fontFamily = strings[1];
-              this.fontSubfamily = strings[2];
-              this.uniqueSubfamily = strings[3];
-              this.fontName = strings[4];
-              this.version = strings[5];
-              this.postscriptName = strings[6][0].raw.replace(/[\x00-\x19\x80-\xff]/g, "");
-              this.trademark = strings[7];
-              this.manufacturer = strings[8];
-              this.designer = strings[9];
-              this.description = strings[10];
-              this.vendorUrl = strings[11];
-              this.designerUrl = strings[12];
-              this.license = strings[13];
-              this.licenseUrl = strings[14];
-              this.preferredFamily = strings[15];
-              this.preferredSubfamily = strings[17];
-              this.compatibleFull = strings[18];
-              return this.sampleText = strings[19];
-          };
-          /*NameTable.prototype.encode = function () {
-              var id, list, nameID, nameTable, postscriptName, strCount, strTable, string, strings, table, val, _i, _len, _ref;
-              strings = {};
-              _ref = this.strings;
-              for (id in _ref) {
-                  val = _ref[id];
-                  strings[id] = val;
-              }
-              postscriptName = new NameEntry("" + subsetTag + "+" + this.postscriptName, {
-                  platformID: 1
-                  , encodingID: 0
-                  , languageID: 0
-              });
-              strings[6] = [postscriptName];
-              subsetTag = successorOf(subsetTag);
-              strCount = 0;
-              for (id in strings) {
-                  list = strings[id];
-                  if (list != null) {
-                      strCount += list.length;
-                  }
-              }
-              table = new Data;
-              strTable = new Data;
-              table.writeShort(0);
-              table.writeShort(strCount);
-              table.writeShort(6 + 12 * strCount);
-              for (nameID in strings) {
-                  list = strings[nameID];
-                  if (list != null) {
-                      for (_i = 0, _len = list.length; _i < _len; _i++) {
-                          string = list[_i];
-                          table.writeShort(string.platformID);
-                          table.writeShort(string.encodingID);
-                          table.writeShort(string.languageID);
-                          table.writeShort(nameID);
-                          table.writeShort(string.length);
-                          table.writeShort(strTable.pos);
-                          strTable.writeString(string.raw);
-                      }
-                  }
-              }
-              return nameTable = {
-                  postscriptName: postscriptName.raw
-                  , table: table.data.concat(strTable.data)
-              };
-          };*/
-          return NameTable;
-      })(Table);
+        case 0x00025000:
+          numberOfGlyphs = data.readUInt16();
+          return this.offsets = data.read(numberOfGlyphs);
 
-      var MaxpTable = (function (_super) {
-          __extends(MaxpTable, _super);
+        case 0x00030000:
+          break;
 
-          function MaxpTable() {
-              return MaxpTable.__super__.constructor.apply(this, arguments);
-          }
-          MaxpTable.prototype.tag = 'maxp';
-          MaxpTable.prototype.parse = function (data) {
-              data.pos = this.offset;
-              this.version = data.readInt();
-              this.numGlyphs = data.readUInt16();
-              this.maxPoints = data.readUInt16();
-              this.maxContours = data.readUInt16();
-              this.maxCompositePoints = data.readUInt16();
-              this.maxComponentContours = data.readUInt16();
-              this.maxZones = data.readUInt16();
-              this.maxTwilightPoints = data.readUInt16();
-              this.maxStorage = data.readUInt16();
-              this.maxFunctionDefs = data.readUInt16();
-              this.maxInstructionDefs = data.readUInt16();
-              this.maxStackElements = data.readUInt16();
-              this.maxSizeOfInstructions = data.readUInt16();
-              this.maxComponentElements = data.readUInt16();
-              return this.maxComponentDepth = data.readUInt16();
-          };
-          /*MaxpTable.prototype.encode = function (ids) {
-              var table;
-              table = new Data;
-              table.writeInt(this.version);
-              table.writeUInt16(ids.length);
-              table.writeUInt16(this.maxPoints);
-              table.writeUInt16(this.maxContours);
-              table.writeUInt16(this.maxCompositePoints);
-              table.writeUInt16(this.maxComponentContours);
-              table.writeUInt16(this.maxZones);
-              table.writeUInt16(this.maxTwilightPoints);
-              table.writeUInt16(this.maxStorage);
-              table.writeUInt16(this.maxFunctionDefs);
-              table.writeUInt16(this.maxInstructionDefs);
-              table.writeUInt16(this.maxStackElements);
-              table.writeUInt16(this.maxSizeOfInstructions);
-              table.writeUInt16(this.maxComponentElements);
-              table.writeUInt16(this.maxComponentDepth);
-              return table.data;
-          };*/
-          return MaxpTable;
-      })(Table);
+        case 0x00040000:
+          return this.map = function () {
+            var _j, _ref, _results1;
 
-      var HmtxTable = (function (_super) {
-          __extends(HmtxTable, _super);
+            _results1 = [];
 
-          function HmtxTable() {
-              return HmtxTable.__super__.constructor.apply(this, arguments);
-          }
-          HmtxTable.prototype.tag = 'hmtx';
-          HmtxTable.prototype.parse = function (data) {
-              var i, last, lsbCount, m, _i, _j, _ref, _results;
-              data.pos = this.offset;
-              this.metrics = [];
-              for (i = _i = 0, _ref = this.file.hhea.numberOfMetrics; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
-                  this.metrics.push({
-                      advance: data.readUInt16()
-                      , lsb: data.readInt16()
-                  });
-              }
-              lsbCount = this.file.maxp.numGlyphs - this.file.hhea.numberOfMetrics;
-              this.leftSideBearings = (function () {
-                  var _j, _results;
-                  _results = [];
-                  for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) {
-                      _results.push(data.readInt16());
-                  }
-                  return _results;
-              })();
-              this.widths = (function () {
-                  var _j, _len, _ref1, _results;
-                  _ref1 = this.metrics;
-                  _results = [];
-                  for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
-                      m = _ref1[_j];
-                      _results.push(m.advance);
-                  }
-                  return _results;
-              }).call(this);
-              last = this.widths[this.widths.length - 1];
-              _results = [];
-              for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) {
-                  _results.push(this.widths.push(last));
-              }
-              return _results;
-          };
-          /***************************************************************/
-          /* function : forGlyph                                         */
-          /* comment : Returns the advance width and lsb for this glyph. */
-          /***************************************************************/
-          HmtxTable.prototype.forGlyph = function (id) {
-              var metrics;
-              if (id in this.metrics) {
-                  return this.metrics[id];
-              }
-              return metrics = {
-                  advance: this.metrics[this.metrics.length - 1].advance
-                  , lsb: this.leftSideBearings[id - this.metrics.length]
-              };
-          };
-          /*HmtxTable.prototype.encode = function (mapping) {
-              var id, metric, table, _i, _len;
-              table = new Data;
-              for (_i = 0, _len = mapping.length; _i < _len; _i++) {
-                  id = mapping[_i];
-                  metric = this.forGlyph(id);
-                  table.writeUInt16(metric.advance);
-                  table.writeUInt16(metric.lsb);
-              }
-              return table.data;
-          };*/
-          return HmtxTable;
-      })(Table);
+            for (i = _j = 0, _ref = this.file.maxp.numGlyphs; 0 <= _ref ? _j < _ref : _j > _ref; i = 0 <= _ref ? ++_j : --_j) {
+              _results1.push(data.readUInt32());
+            }
 
-      var __slice = [].slice;
+            return _results1;
+          }.call(this);
+      }
+    };
+    return PostTable;
+  }(Table);
+  /*********************************************************************************************************/
 
-      var GlyfTable = (function (_super) {
-          __extends(GlyfTable, _super);
+  /* function : NameEntry                                                                                  */
 
-          function GlyfTable() {
-              return GlyfTable.__super__.constructor.apply(this, arguments);
-          }
-          GlyfTable.prototype.tag = 'glyf';
-          GlyfTable.prototype.parse = function (data) {
-              return this.cache = {};
-          };
-          GlyfTable.prototype.glyphFor = function (id) {
-              id = id;
-              var data, index, length, loca, numberOfContours, raw, xMax, xMin, yMax, yMin;
-              if (id in this.cache) {
-                  return this.cache[id];
-              }
-              loca = this.file.loca;
-              data = this.file.contents;
-              index = loca.indexOf(id);
-              length = loca.lengthOf(id);
-              if (length === 0) {
-                  return this.cache[id] = null;
-              }
-              data.pos = this.offset + index;
-              raw = new Data(data.read(length));
-              numberOfContours = raw.readShort();
-              xMin = raw.readShort();
-              yMin = raw.readShort();
-              xMax = raw.readShort();
-              yMax = raw.readShort();
-              if (numberOfContours === -1) {
-                  this.cache[id] = new CompoundGlyph(raw, xMin, yMin, xMax, yMax);
-              }
-              else {
-                  this.cache[id] = new SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax);
-              }
-              return this.cache[id];
-          };
-          GlyfTable.prototype.encode = function (glyphs, mapping, old2new) {
-              var glyph, id, offsets, table, _i, _len;
-              table = [];
-              offsets = [];
-              for (_i = 0, _len = mapping.length; _i < _len; _i++) {
-                  id = mapping[_i];
-                  glyph = glyphs[id];
-                  offsets.push(table.length);
-                  if (glyph) {
-                      table = table.concat(glyph.encode(old2new));
-                  }
-              }
-              offsets.push(table.length);
-              return {
-                  table: table
-                  , offsets: offsets
-              };
-          };
-          return GlyfTable;
-      })(Table);
-
-      var SimpleGlyph = (function () {
-          /**************************************************************************/
-          /* function : SimpleGlyph                                                 */
-          /* comment : Stores raw, xMin, yMin, xMax, and yMax values for this glyph.*/
-          /**************************************************************************/
-          function SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax) {
-              this.raw = raw;
-              this.numberOfContours = numberOfContours;
-              this.xMin = xMin;
-              this.yMin = yMin;
-              this.xMax = xMax;
-              this.yMax = yMax;
-              this.compound = false;
-          }
-          SimpleGlyph.prototype.encode = function () {
-              return this.raw.data;
-          };
-          return SimpleGlyph;
-      })();
+  /* comment : Store copyright information, platformID, encodingID, and languageID in the NameEntry object.*/
 
-      var CompoundGlyph = (function () {
-          var ARG_1_AND_2_ARE_WORDS, MORE_COMPONENTS, WE_HAVE_AN_X_AND_Y_SCALE, WE_HAVE_A_SCALE, WE_HAVE_A_TWO_BY_TWO;
-          ARG_1_AND_2_ARE_WORDS = 0x0001;
-          WE_HAVE_A_SCALE = 0x0008;
-          MORE_COMPONENTS = 0x0020;
-          WE_HAVE_AN_X_AND_Y_SCALE = 0x0040;
-          WE_HAVE_A_TWO_BY_TWO = 0x0080;
-
-          /********************************************************************************************************************/
-          /* function : CompoundGlypg generator                                                                               */
-          /* comment : It stores raw, xMin, yMin, xMax, yMax, glyph id, and glyph offset for the corresponding compound glyph.*/
-          /********************************************************************************************************************/
-          function CompoundGlyph(raw, xMin, yMin, xMax, yMax) {
-              var data, flags;
-              this.raw = raw;
-              this.xMin = xMin;
-              this.yMin = yMin;
-              this.xMax = xMax;
-              this.yMax = yMax;
-              this.compound = true;
-              this.glyphIDs = [];
-              this.glyphOffsets = [];
-              data = this.raw;
-              while (true) {
-                  flags = data.readShort();
-                  this.glyphOffsets.push(data.pos);
-                  this.glyphIDs.push(data.readShort());
-                  if (!(flags & MORE_COMPONENTS)) {
-                      break;
-                  }
-                  if (flags & ARG_1_AND_2_ARE_WORDS) {
-                      data.pos += 4;
-                  }
-                  else {
-                      data.pos += 2;
-                  }
-                  if (flags & WE_HAVE_A_TWO_BY_TWO) {
-                      data.pos += 8;
-                  }
-                  else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
-                      data.pos += 4;
-                  }
-                  else if (flags & WE_HAVE_A_SCALE) {
-                      data.pos += 2;
-                  }
-              }
-          }
-          /****************************************************************************************************************/
-          /* function : CompoundGlypg encode                                                                              */
-          /* comment : After creating a table for the characters you typed, you call directory.encode to encode the table.*/
-          /****************************************************************************************************************/
-          CompoundGlyph.prototype.encode = function (mapping) {
-              var i, id, result, _i, _len, _ref;
-              result = new Data(__slice.call(this.raw.data));
-              _ref = this.glyphIDs;
-              for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
-                  id = _ref[i];
-                  result.pos = this.glyphOffsets[i];
-              }
-              return result.data;
-          };
-          return CompoundGlyph;
-      })();
+  /*********************************************************************************************************/
 
-      var LocaTable = (function (_super) {
-          __extends(LocaTable, _super);
 
-          function LocaTable() {
-              return LocaTable.__super__.constructor.apply(this, arguments);
-          }
-          LocaTable.prototype.tag = 'loca';
-          LocaTable.prototype.parse = function (data) {
-              var format, i;
-              data.pos = this.offset;
-              format = this.file.head.indexToLocFormat;
-              if (format === 0) {
-                  return this.offsets = (function () {
-                      var _i, _ref, _results;
-                      _results = [];
-                      for (i = _i = 0, _ref = this.length; _i < _ref; i = _i += 2) {
-                          _results.push(data.readUInt16() * 2);
-                      }
-                      return _results;
-                  }).call(this);
-              }
-              else {
-                  return this.offsets = (function () {
-                      var _i, _ref, _results;
-                      _results = [];
-                      for (i = _i = 0, _ref = this.length; _i < _ref; i = _i += 4) {
-                          _results.push(data.readUInt32());
-                      }
-                      return _results;
-                  }).call(this);
-              }
-          };
-          LocaTable.prototype.indexOf = function (id) {
-              return this.offsets[id];
-          };
-          LocaTable.prototype.lengthOf = function (id) {
-              return this.offsets[id + 1] - this.offsets[id];
-          };
-          LocaTable.prototype.encode = function (offsets, activeGlyphs) {
-              var LocaTable = new Uint32Array(this.offsets.length);
-              var glyfPtr = 0;
-              var listGlyf = 0;
-              for (var k = 0; k < LocaTable.length; ++k) {
-                  LocaTable[k] = glyfPtr;
-                  if (listGlyf < activeGlyphs.length && activeGlyphs[listGlyf] == k) {
-                      ++listGlyf;
-                      LocaTable[k] = glyfPtr;
-                      var start = this.offsets[k];
-                      var len = this.offsets[k + 1] - start;
-                      if (len > 0) {
-                          glyfPtr += len;
-                      }
-                  }
-              }
-              var newLocaTable = new Array(LocaTable.length * 4);
-              for (var j = 0; j < LocaTable.length; ++j) {
-                  newLocaTable[4 * j + 3] = (LocaTable[j] & 0x000000ff);
-                  newLocaTable[4 * j + 2] = (LocaTable[j] & 0x0000ff00) >> 8;
-                  newLocaTable[4 * j + 1] = (LocaTable[j] & 0x00ff0000) >> 16;
-                  newLocaTable[4 * j] = (LocaTable[j] & 0xff000000) >> 24;
-              }
-              return newLocaTable;
-          };
-          return LocaTable;
-      })(Table);
-
-      /************************************************************************************/
-      /* function : invert                                                                */
-      /* comment : Change the object's (key: value) to create an object with (value: key).*/
-      /************************************************************************************/
-      var invert = function (object) {
-          var key, ret, val;
-          ret = {};
-          for (key in object) {
-              val = object[key];
-              ret[val] = key;
-          }
-          return ret;
-      };
+  var NameEntry = function () {
+    function NameEntry(raw, entry) {
+      this.raw = raw;
+      this.length = raw.length;
+      this.platformID = entry.platformID;
+      this.encodingID = entry.encodingID;
+      this.languageID = entry.languageID;
+    }
 
-      /*var successorOf = function (input) {
-          var added, alphabet, carry, i, index, isUpperCase, last, length, next, result;
-          alphabet = 'abcdefghijklmnopqrstuvwxyz';
-          length = alphabet.length;
-          result = input;
-          i = input.length;
-          while (i >= 0) {
-              last = input.charAt(--i);
-              if (isNaN(last)) {
-                  index = alphabet.indexOf(last.toLowerCase());
-                  if (index === -1) {
-                      next = last;
-                      carry = true;
-                  }
-                  else {
-                      next = alphabet.charAt((index + 1) % length);
-                      isUpperCase = last === last.toUpperCase();
-                      if (isUpperCase) {
-                          next = next.toUpperCase();
-                      }
-                      carry = index + 1 >= length;
-                      if (carry && i === 0) {
-                          added = isUpperCase ? 'A' : 'a';
-                          result = added + next + result.slice(1);
-                          break;
-                      }
-                  }
-              }
-              else {
-                  next = +last + 1;
-                  carry = next > 9;
-                  if (carry) {
-                      next = 0;
-                  }
-                  if (carry && i === 0) {
-                      result = '1' + next + result.slice(1);
-                      break;
-                  }
-              }
-              result = result.slice(0, i) + next + result.slice(i + 1);
-              if (!carry) {
-                  break;
-              }
-          }
-          return result;
-      };*/
+    return NameEntry;
+  }();
+
+  var NameTable = function (_super) {
+
+    __extends(NameTable, _super);
+
+    function NameTable() {
+      return NameTable.__super__.constructor.apply(this, arguments);
+    }
+
+    NameTable.prototype.tag = "name";
+
+    NameTable.prototype.parse = function (data) {
+      var count, entries, entry, i, name, stringOffset, strings, text, _j, _len, _name;
+
+      data.pos = this.offset;
+      data.readShort(); //format
+
+      count = data.readShort();
+      stringOffset = data.readShort();
+      entries = [];
+
+      for (i = 0; 0 <= count ? i < count : i > count; i = 0 <= count ? ++i : --i) {
+        entries.push({
+          platformID: data.readShort(),
+          encodingID: data.readShort(),
+          languageID: data.readShort(),
+          nameID: data.readShort(),
+          length: data.readShort(),
+          offset: this.offset + stringOffset + data.readShort()
+        });
+      }
+
+      strings = {};
+
+      for (i = _j = 0, _len = entries.length; _j < _len; i = ++_j) {
+        entry = entries[i];
+        data.pos = entry.offset;
+        text = data.readString(entry.length);
+        name = new NameEntry(text, entry);
+
+        if (strings[_name = entry.nameID] == null) {
+          strings[_name] = [];
+        }
+
+        strings[entry.nameID].push(name);
+      }
 
-      var Subset = (function () {
-          function Subset(font) {
-              this.font = font;
-              this.subset = {};
-              this.unicodes = {};
-              this.next = 33;
-          }
-          /*Subset.prototype.use = function (character) {
-              var i, _i, _ref;
-              if (typeof character === 'string') {
-                  for (i = _i = 0, _ref = character.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
-                      this.use(character.charCodeAt(i));
-                  }
-                  return;
-              }
-              if (!this.unicodes[character]) {
-                  this.subset[this.next] = character;
-                  return this.unicodes[character] = this.next++;
-              }
-          };*/
-          /*Subset.prototype.encodeText = function (text) {
-              var char, i, string, _i, _ref;
-              string = '';
-              for (i = _i = 0, _ref = text.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
-                  char = this.unicodes[text.charCodeAt(i)];
-                  string += String.fromCharCode(char);
-              }
-              return string;
-          };*/
-          /***************************************************************/
-          /* function : generateCmap                                     */
-          /* comment : Returns the unicode cmap for this font.         */
-          /***************************************************************/
-          Subset.prototype.generateCmap = function () {
-              var mapping, roman, unicode, unicodeCmap, _ref;
-              unicodeCmap = this.font.cmap.tables[0].codeMap;
-              mapping = {};
-              _ref = this.subset;
-              for (roman in _ref) {
-                  unicode = _ref[roman];
-                  mapping[roman] = unicodeCmap[unicode];
-              }
-              return mapping;
-          };
-          /*Subset.prototype.glyphIDs = function () {
-              var ret, roman, unicode, unicodeCmap, val, _ref;
-              unicodeCmap = this.font.cmap.tables[0].codeMap;
-              ret = [0];
-              _ref = this.subset;
-              for (roman in _ref) {
-                  unicode = _ref[roman];
-                  val = unicodeCmap[unicode];
-                  if ((val != null) && __indexOf.call(ret, val) < 0) {
-                      ret.push(val);
-                  }
-              }
-              return ret.sort();
-          };*/
-          /******************************************************************/
-          /* function : glyphsFor                                           */
-          /* comment : Returns simple glyph objects for the input character.*/
-          /******************************************************************/
-          Subset.prototype.glyphsFor = function (glyphIDs) {
-              var additionalIDs, glyph, glyphs, id, _i, _len, _ref;
-              glyphs = {};
-              for (_i = 0, _len = glyphIDs.length; _i < _len; _i++) {
-                  id = glyphIDs[_i];
-                  glyphs[id] = this.font.glyf.glyphFor(id);
-              }
-              additionalIDs = [];
-              for (id in glyphs) {
-                  glyph = glyphs[id];
-                  if (glyph != null ? glyph.compound : void 0) {
-                      additionalIDs.push.apply(additionalIDs, glyph.glyphIDs);
-                  }
+      this.strings = strings;
+      this.copyright = strings[0];
+      this.fontFamily = strings[1];
+      this.fontSubfamily = strings[2];
+      this.uniqueSubfamily = strings[3];
+      this.fontName = strings[4];
+      this.version = strings[5];
+
+      try {
+        this.postscriptName = strings[6][0].raw.replace(/[\x00-\x19\x80-\xff]/g, "");
+      } catch (e) {
+        this.postscriptName = strings[4][0].raw.replace(/[\x00-\x19\x80-\xff]/g, "");
+      }
+
+      this.trademark = strings[7];
+      this.manufacturer = strings[8];
+      this.designer = strings[9];
+      this.description = strings[10];
+      this.vendorUrl = strings[11];
+      this.designerUrl = strings[12];
+      this.license = strings[13];
+      this.licenseUrl = strings[14];
+      this.preferredFamily = strings[15];
+      this.preferredSubfamily = strings[17];
+      this.compatibleFull = strings[18];
+      return this.sampleText = strings[19];
+    };
+    /*NameTable.prototype.encode = function () {
+              var id, list, nameID, nameTable, postscriptName, strCount, strTable, string, strings, table, val, _i, _len, _ref;
+              strings = {};
+              _ref = this.strings;
+              for (id in _ref) {
+                  val = _ref[id];
+                  strings[id] = val;
               }
-              if (additionalIDs.length > 0) {
-                  _ref = this.glyphsFor(additionalIDs);
-                  for (id in _ref) {
-                      glyph = _ref[id];
-                      glyphs[id] = glyph;
+              postscriptName = new NameEntry("" + subsetTag + "+" + this.postscriptName, {
+                  platformID: 1
+                  , encodingID: 0
+                  , languageID: 0
+              });
+              strings[6] = [postscriptName];
+              subsetTag = successorOf(subsetTag);
+              strCount = 0;
+              for (id in strings) {
+                  list = strings[id];
+                  if (list != null) {
+                      strCount += list.length;
                   }
               }
-              return glyphs;
-          };
-          /***************************************************************/
-          /* function : encode                                           */
-          /* comment : Encode various tables for the characters you use. */
-          /***************************************************************/
-          Subset.prototype.encode = function (glyID) {
-              var cmap, code, glyf, glyphs, id, ids, loca, new2old, newIDs, nextGlyphID, old2new, oldID, oldIDs, tables, _ref;
-              cmap = CmapTable.encode(this.generateCmap(), 'unicode');
-              glyphs = this.glyphsFor(glyID);
-              old2new = {
-                  0: 0
-              };
-              _ref = cmap.charMap;
-              for (code in _ref) {
-                  ids = _ref[code];
-                  old2new[ids.old] = ids["new"];
-              }
-              nextGlyphID = cmap.maxGlyphID;
-              for (oldID in glyphs) {
-                  if (!(oldID in old2new)) {
-                      old2new[oldID] = nextGlyphID++;
+              table = new Data;
+              strTable = new Data;
+              table.writeShort(0);
+              table.writeShort(strCount);
+              table.writeShort(6 + 12 * strCount);
+              for (nameID in strings) {
+                  list = strings[nameID];
+                  if (list != null) {
+                      for (_i = 0, _len = list.length; _i < _len; _i++) {
+                          string = list[_i];
+                          table.writeShort(string.platformID);
+                          table.writeShort(string.encodingID);
+                          table.writeShort(string.languageID);
+                          table.writeShort(nameID);
+                          table.writeShort(string.length);
+                          table.writeShort(strTable.pos);
+                          strTable.writeString(string.raw);
+                      }
                   }
               }
-              new2old = invert(old2new);
-              newIDs = Object.keys(new2old).sort(function (a, b) {
-                  return a - b;
-              });
-              oldIDs = (function () {
-                  var _i, _len, _results;
-                  _results = [];
-                  for (_i = 0, _len = newIDs.length; _i < _len; _i++) {
-                      id = newIDs[_i];
-                      _results.push(new2old[id]);
-                  }
-                  return _results;
-              })();
-              glyf = this.font.glyf.encode(glyphs, oldIDs, old2new);
-              loca = this.font.loca.encode(glyf.offsets, oldIDs);
-              tables = {
-                  cmap: this.font.cmap.raw()
-                  , glyf: glyf.table
-                  , loca: loca
-                  , hmtx: this.font.hmtx.raw()
-                  , hhea: this.font.hhea.raw()
-                  , maxp: this.font.maxp.raw()
-                  , post: this.font.post.raw()
-                  , name: this.font.name.raw()
-                  , head: this.font.head.raw()
+              return nameTable = {
+                  postscriptName: postscriptName.raw
+                  , table: table.data.concat(strTable.data)
               };
-              if (this.font.os2.exists) {
-                  tables['OS/2'] = this.font.os2.raw();
-              }
-              return this.font.directory.encode(tables);
-          };
-          return Subset;
-      })();
+          };*/
 
-      jsPDF.API.PDFObject = (function () {
-          var pad;
+    return NameTable;
+  }(Table);
 
-          function PDFObject() {}
-          pad = function (str, length) {
-              return (Array(length + 1).join('0') + str).slice(-length);
-          };
-          /*****************************************************************************/
-          /* function : convert                                                        */
-          /* comment :Converts pdf tag's / FontBBox and array values in / W to strings */
-          /*****************************************************************************/
-          PDFObject.convert = function (object) {
-              var e, items, key, out, val;
-              if (Array.isArray(object)) {
-                  items = ((function () {
-                      var _i, _len, _results;
-                      _results = [];
-                      for (_i = 0, _len = object.length; _i < _len; _i++) {
-                          e = object[_i];
-                          _results.push(PDFObject.convert(e));
-                      }
-                      return _results;
-                  })()).join(' ');
-                  return '[' + items + ']';
-              }
-              else if (typeof object === 'string') {
-                  return '/' + object;
-              }
-              else if (object != null ? object.isString : void 0) {
-                  return '(' + object + ')';
-              }
-              else if (object instanceof Date) {
-                  return '(D:' + pad(object.getUTCFullYear(), 4) + pad(object.getUTCMonth(), 2) + pad(object.getUTCDate(), 2) + pad(object.getUTCHours(), 2) + pad(object.getUTCMinutes(), 2) + pad(object.getUTCSeconds(), 2) + 'Z)';
-              }
-              else if ({}.toString.call(object) === '[object Object]') {
-                  out = ['<<'];
-                  for (key in object) {
-                      val = object[key];
-                      out.push('/' + key + ' ' + PDFObject.convert(val));
-                  }
-                  out.push('>>');
-                  return out.join('\n');
-              }
-              else {
-                  return '' + object;
-              }
-          };
-          return PDFObject;
-      })();
-  })(jsPDF);
+  var MaxpTable = function (_super) {
+    __extends(MaxpTable, _super);
 
-  // Generated by CoffeeScript 1.4.0
+    function MaxpTable() {
+      return MaxpTable.__super__.constructor.apply(this, arguments);
+    }
 
-  /*
-  # PNG.js
-  # Copyright (c) 2011 Devon Govett
-  # MIT LICENSE
-  # 
-  # 
-  */
+    MaxpTable.prototype.tag = "maxp";
+
+    MaxpTable.prototype.parse = function (data) {
+      data.pos = this.offset;
+      this.version = data.readInt();
+      this.numGlyphs = data.readUInt16();
+      this.maxPoints = data.readUInt16();
+      this.maxContours = data.readUInt16();
+      this.maxCompositePoints = data.readUInt16();
+      this.maxComponentContours = data.readUInt16();
+      this.maxZones = data.readUInt16();
+      this.maxTwilightPoints = data.readUInt16();
+      this.maxStorage = data.readUInt16();
+      this.maxFunctionDefs = data.readUInt16();
+      this.maxInstructionDefs = data.readUInt16();
+      this.maxStackElements = data.readUInt16();
+      this.maxSizeOfInstructions = data.readUInt16();
+      this.maxComponentElements = data.readUInt16();
+      return this.maxComponentDepth = data.readUInt16();
+    };
+    /*MaxpTable.prototype.encode = function (ids) {
+              var table;
+              table = new Data;
+              table.writeInt(this.version);
+              table.writeUInt16(ids.length);
+              table.writeUInt16(this.maxPoints);
+              table.writeUInt16(this.maxContours);
+              table.writeUInt16(this.maxCompositePoints);
+              table.writeUInt16(this.maxComponentContours);
+              table.writeUInt16(this.maxZones);
+              table.writeUInt16(this.maxTwilightPoints);
+              table.writeUInt16(this.maxStorage);
+              table.writeUInt16(this.maxFunctionDefs);
+              table.writeUInt16(this.maxInstructionDefs);
+              table.writeUInt16(this.maxStackElements);
+              table.writeUInt16(this.maxSizeOfInstructions);
+              table.writeUInt16(this.maxComponentElements);
+              table.writeUInt16(this.maxComponentDepth);
+              return table.data;
+          };*/
 
 
-  (function(global) {
-    var PNG;
+    return MaxpTable;
+  }(Table);
 
-    PNG = (function() {
-      var APNG_BLEND_OP_SOURCE, APNG_DISPOSE_OP_BACKGROUND, APNG_DISPOSE_OP_PREVIOUS, makeImage, scratchCanvas, scratchCtx;
+  var HmtxTable = function (_super) {
+    __extends(HmtxTable, _super);
 
-      PNG.load = function(url, canvas, callback) {
-        var xhr;
-        if (typeof canvas === 'function') {
-          callback = canvas;
-        }
-        xhr = new XMLHttpRequest;
-        xhr.open("GET", url, true);
-        xhr.responseType = "arraybuffer";
-        xhr.onload = function() {
-          var data, png;
-          data = new Uint8Array(xhr.response || xhr.mozResponseArrayBuffer);
-          png = new PNG(data);
-          if (typeof (canvas != null ? canvas.getContext : void 0) === 'function') {
-            png.render(canvas);
-          }
-          return typeof callback === "function" ? callback(png) : void 0;
-        };
-        return xhr.send(null);
-      };
+    function HmtxTable() {
+      return HmtxTable.__super__.constructor.apply(this, arguments);
+    }
 
-      APNG_DISPOSE_OP_BACKGROUND = 1;
-
-      APNG_DISPOSE_OP_PREVIOUS = 2;
-
-      APNG_BLEND_OP_SOURCE = 0;
-
-      function PNG(data) {
-        var chunkSize, colors, palLen, delayDen, delayNum, frame, i, index, key, section, palShort, text, _i, _j, _ref;
-        this.data = data;
-        this.pos = 8;
-        this.palette = [];
-        this.imgData = [];
-        this.transparency = {};
-        this.animation = null;
-        this.text = {};
-        frame = null;
-        while (true) {
-          chunkSize = this.readUInt32();
-          section = ((function() {
-            var _i, _results;
-            _results = [];
-            for (i = _i = 0; _i < 4; i = ++_i) {
-              _results.push(String.fromCharCode(this.data[this.pos++]));
-            }
-            return _results;
-          }).call(this)).join('');
-          switch (section) {
-            case 'IHDR':
-              this.width = this.readUInt32();
-              this.height = this.readUInt32();
-              this.bits = this.data[this.pos++];
-              this.colorType = this.data[this.pos++];
-              this.compressionMethod = this.data[this.pos++];
-              this.filterMethod = this.data[this.pos++];
-              this.interlaceMethod = this.data[this.pos++];
-              break;
-            case 'acTL':
-              this.animation = {
-                numFrames: this.readUInt32(),
-                numPlays: this.readUInt32() || Infinity,
-                frames: []
-              };
-              break;
-            case 'PLTE':
-              this.palette = this.read(chunkSize);
-              break;
-            case 'fcTL':
-              if (frame) {
-                this.animation.frames.push(frame);
-              }
-              this.pos += 4;
-              frame = {
-                width: this.readUInt32(),
-                height: this.readUInt32(),
-                xOffset: this.readUInt32(),
-                yOffset: this.readUInt32()
-              };
-              delayNum = this.readUInt16();
-              delayDen = this.readUInt16() || 100;
-              frame.delay = 1000 * delayNum / delayDen;
-              frame.disposeOp = this.data[this.pos++];
-              frame.blendOp = this.data[this.pos++];
-              frame.data = [];
-              break;
-            case 'IDAT':
-            case 'fdAT':
-              if (section === 'fdAT') {
-                this.pos += 4;
-                chunkSize -= 4;
-              }
-              data = (frame != null ? frame.data : void 0) || this.imgData;
-              for (i = _i = 0; 0 <= chunkSize ? _i < chunkSize : _i > chunkSize; i = 0 <= chunkSize ? ++_i : --_i) {
-                data.push(this.data[this.pos++]);
-              }
-              break;
-            case 'tRNS':
-              this.transparency = {};
-              switch (this.colorType) {
-                case 3:
-              	palLen = this.palette.length/3;
-                  this.transparency.indexed = this.read(chunkSize);
-                  if(this.transparency.indexed.length > palLen)
-                  	throw new Error('More transparent colors than palette size');
-                  /*
-                   * According to the PNG spec trns should be increased to the same size as palette if shorter
-                   */
-                  //palShort = 255 - this.transparency.indexed.length;
-                  palShort = palLen - this.transparency.indexed.length;
-                  if (palShort > 0) {
-                    for (i = _j = 0; 0 <= palShort ? _j < palShort : _j > palShort; i = 0 <= palShort ? ++_j : --_j) {
-                      this.transparency.indexed.push(255);
-                    }
-                  }
-                  break;
-                case 0:
-                  this.transparency.grayscale = this.read(chunkSize)[0];
-                  break;
-                case 2:
-                  this.transparency.rgb = this.read(chunkSize);
-              }
-              break;
-            case 'tEXt':
-              text = this.read(chunkSize);
-              index = text.indexOf(0);
-              key = String.fromCharCode.apply(String, text.slice(0, index));
-              this.text[key] = String.fromCharCode.apply(String, text.slice(index + 1));
-              break;
-            case 'IEND':
-              if (frame) {
-                this.animation.frames.push(frame);
-              }
-              this.colors = (function() {
-                switch (this.colorType) {
-                  case 0:
-                  case 3:
-                  case 4:
-                    return 1;
-                  case 2:
-                  case 6:
-                    return 3;
-                }
-              }).call(this);
-              this.hasAlphaChannel = (_ref = this.colorType) === 4 || _ref === 6;
-              colors = this.colors + (this.hasAlphaChannel ? 1 : 0);
-              this.pixelBitlength = this.bits * colors;
-              this.colorSpace = (function() {
-                switch (this.colors) {
-                  case 1:
-                    return 'DeviceGray';
-                  case 3:
-                    return 'DeviceRGB';
-                }
-              }).call(this);
-              this.imgData = new Uint8Array(this.imgData);
-              return;
-            default:
-              this.pos += chunkSize;
-          }
-          this.pos += 4;
-          if (this.pos > this.data.length) {
-            throw new Error("Incomplete or corrupt PNG file");
-          }
-        }
-        return;
+    HmtxTable.prototype.tag = "hmtx";
+
+    HmtxTable.prototype.parse = function (data) {
+      var i, last, lsbCount, m, _j, _ref, _results;
+
+      data.pos = this.offset;
+      this.metrics = [];
+
+      for (i = 0, _ref = this.file.hhea.numberOfMetrics; 0 <= _ref ? i < _ref : i > _ref; i = 0 <= _ref ? ++i : --i) {
+        this.metrics.push({
+          advance: data.readUInt16(),
+          lsb: data.readInt16()
+        });
       }
 
-      PNG.prototype.read = function(bytes) {
-        var i, _i, _results;
+      lsbCount = this.file.maxp.numGlyphs - this.file.hhea.numberOfMetrics;
+
+      this.leftSideBearings = function () {
+        var _j, _results;
+
         _results = [];
-        for (i = _i = 0; 0 <= bytes ? _i < bytes : _i > bytes; i = 0 <= bytes ? ++_i : --_i) {
-          _results.push(this.data[this.pos++]);
+
+        for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) {
+          _results.push(data.readInt16());
         }
+
         return _results;
-      };
+      }();
 
-      PNG.prototype.readUInt32 = function() {
-        var b1, b2, b3, b4;
-        b1 = this.data[this.pos++] << 24;
-        b2 = this.data[this.pos++] << 16;
-        b3 = this.data[this.pos++] << 8;
-        b4 = this.data[this.pos++];
-        return b1 | b2 | b3 | b4;
-      };
+      this.widths = function () {
+        var _j, _len, _ref1, _results;
 
-      PNG.prototype.readUInt16 = function() {
-        var b1, b2;
-        b1 = this.data[this.pos++] << 8;
-        b2 = this.data[this.pos++];
-        return b1 | b2;
-      };
+        _ref1 = this.metrics;
+        _results = [];
 
+        for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
+          m = _ref1[_j];
 
-      PNG.prototype.decodePixels = function(data) {
-        var pixelBytes = this.pixelBitlength / 8;
-        var fullPixels = new Uint8Array(this.width * this.height * pixelBytes);
-        var pos = 0;
-        var _this = this;
-        
-        if (data == null) {
-            data = this.imgData;
-        }
-        if (data.length === 0) {
-            return new Uint8Array(0);
-        }
-        
-        data = new FlateStream(data);
-        data = data.getBytes();
-        function pass (x0, y0, dx, dy) {
-            var abyte, c, col, i, left, length, p, pa, paeth, pb, pc, pixels, row, scanlineLength, upper, upperLeft, _i, _j, _k, _l, _m;
-            var w = Math.ceil((_this.width - x0) / dx), h = Math.ceil((_this.height - y0) / dy);
-            var isFull = _this.width == w && _this.height == h;
-            scanlineLength = pixelBytes * w;
-            pixels = isFull ? fullPixels : new Uint8Array(scanlineLength * h);
-            length = data.length;
-            row = 0;
-            c = 0;
-            while (row < h && pos < length) {
-              switch (data[pos++]) {
-                case 0:
-                  for (i = _i = 0; _i < scanlineLength; i = _i += 1) {
-                    pixels[c++] = data[pos++];
-                  }
-                  break;
-                case 1:
-                  for (i = _j = 0; _j < scanlineLength; i = _j += 1) {
-                    abyte = data[pos++];
-                    left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
-                    pixels[c++] = (abyte + left) % 256;
-                  }
-                  break;
-                case 2:
-                  for (i = _k = 0; _k < scanlineLength; i = _k += 1) {
-                    abyte = data[pos++];
-                    col = (i - (i % pixelBytes)) / pixelBytes;
-                    upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
-                    pixels[c++] = (upper + abyte) % 256;
-                  }
-                  break;
-                case 3:
-                  for (i = _l = 0; _l < scanlineLength; i = _l += 1) {
-                    abyte = data[pos++];
-                    col = (i - (i % pixelBytes)) / pixelBytes;
-                    left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
-                    upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
-                    pixels[c++] = (abyte + Math.floor((left + upper) / 2)) % 256;
-                  }
-                  break;
-                case 4:
-                  for (i = _m = 0; _m < scanlineLength; i = _m += 1) {
-                    abyte = data[pos++];
-                    col = (i - (i % pixelBytes)) / pixelBytes;
-                    left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
-                    if (row === 0) {
-                      upper = upperLeft = 0;
-                    } else {
-                      upper = pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
-                      upperLeft = col && pixels[(row - 1) * scanlineLength + (col - 1) * pixelBytes + (i % pixelBytes)];
-                    }
-                    p = left + upper - upperLeft;
-                    pa = Math.abs(p - left);
-                    pb = Math.abs(p - upper);
-                    pc = Math.abs(p - upperLeft);
-                    if (pa <= pb && pa <= pc) {
-                      paeth = left;
-                    } else if (pb <= pc) {
-                      paeth = upper;
-                    } else {
-                      paeth = upperLeft;
-                    }
-                    pixels[c++] = (abyte + paeth) % 256;
-                  }
-                  break;
-                default:
-                  throw new Error("Invalid filter algorithm: " + data[pos - 1]);
-              }
-              if (!isFull) {
-                  var fullPos = ((y0 + row * dy) * _this.width + x0) * pixelBytes;
-                  var partPos = row * scanlineLength;
-                  for (i = 0; i < w; i += 1) {
-                    for (var j = 0; j < pixelBytes; j += 1)
-                      fullPixels[fullPos++] = pixels[partPos++];
-                    fullPos += (dx - 1) * pixelBytes;
-                  }
-                }
-              row++;
-            }
+          _results.push(m.advance);
         }
-        if (_this.interlaceMethod == 1) {
-            /*
-              1 6 4 6 2 6 4 6
-              7 7 7 7 7 7 7 7
-              5 6 5 6 5 6 5 6
-              7 7 7 7 7 7 7 7
-              3 6 4 6 3 6 4 6
-              7 7 7 7 7 7 7 7
-              5 6 5 6 5 6 5 6
-              7 7 7 7 7 7 7 7
-            */
-            pass(0, 0, 8, 8); // 1
-            /* NOTE these seem to follow the pattern:
-             * pass(x, 0, 2*x, 2*x);
-             * pass(0, x,   x, 2*x);
-             * with x being 4, 2, 1.
-             */
-            pass(4, 0, 8, 8); // 2
-            pass(0, 4, 4, 8); // 3
 
-            pass(2, 0, 4, 4); // 4
-            pass(0, 2, 2, 4); // 5
+        return _results;
+      }.call(this);
 
-            pass(1, 0, 2, 2); // 6
-            pass(0, 1, 1, 2); // 7
-          } else {
-            pass(0, 0, 1, 1);
-          }
-        return fullPixels;
-      };
+      last = this.widths[this.widths.length - 1];
+      _results = [];
 
-      PNG.prototype.decodePalette = function() {
-        var c, i, length, palette, pos, ret, transparency, _i, _ref, _ref1;
-        palette = this.palette;
-        transparency = this.transparency.indexed || [];
-        ret = new Uint8Array((transparency.length || 0) + palette.length);
-        pos = 0;
-        length = palette.length;
-        c = 0;
-        for (i = _i = 0, _ref = palette.length; _i < _ref; i = _i += 3) {
-          ret[pos++] = palette[i];
-          ret[pos++] = palette[i + 1];
-          ret[pos++] = palette[i + 2];
-          ret[pos++] = (_ref1 = transparency[c++]) != null ? _ref1 : 255;
-        }
-        return ret;
-      };
+      for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) {
+        _results.push(this.widths.push(last));
+      }
 
-      PNG.prototype.copyToImageData = function(imageData, pixels) {
-        var alpha, colors, data, i, input, j, k, length, palette, v, _ref;
-        colors = this.colors;
-        palette = null;
-        alpha = this.hasAlphaChannel;
-        if (this.palette.length) {
-          palette = (_ref = this._decodedPalette) != null ? _ref : this._decodedPalette = this.decodePalette();
-          colors = 4;
-          alpha = true;
-        }
-        data = imageData.data || imageData;
-        length = data.length;
-        input = palette || pixels;
-        i = j = 0;
-        if (colors === 1) {
-          while (i < length) {
-            k = palette ? pixels[i / 4] * 4 : j;
-            v = input[k++];
-            data[i++] = v;
-            data[i++] = v;
-            data[i++] = v;
-            data[i++] = alpha ? input[k++] : 255;
-            j = k;
-          }
-        } else {
-          while (i < length) {
-            k = palette ? pixels[i / 4] * 4 : j;
-            data[i++] = input[k++];
-            data[i++] = input[k++];
-            data[i++] = input[k++];
-            data[i++] = alpha ? input[k++] : 255;
-            j = k;
-          }
-        }
+      return _results;
+    };
+    /***************************************************************/
+
+    /* function : forGlyph                                         */
+
+    /* comment : Returns the advance width and lsb for this glyph. */
+
+    /***************************************************************/
+
+
+    HmtxTable.prototype.forGlyph = function (id) {
+      if (id in this.metrics) {
+        return this.metrics[id];
+      }
+
+      return {
+        advance: this.metrics[this.metrics.length - 1].advance,
+        lsb: this.leftSideBearings[id - this.metrics.length]
       };
+    };
+    /*HmtxTable.prototype.encode = function (mapping) {
+              var id, metric, table, _i, _len;
+              table = new Data;
+              for (_i = 0, _len = mapping.length; _i < _len; _i++) {
+                  id = mapping[_i];
+                  metric = this.forGlyph(id);
+                  table.writeUInt16(metric.advance);
+                  table.writeUInt16(metric.lsb);
+              }
+              return table.data;
+          };*/
+
+
+    return HmtxTable;
+  }(Table);
+
+  var __slice = [].slice;
+
+  var GlyfTable = function (_super) {
+    __extends(GlyfTable, _super);
+
+    function GlyfTable() {
+      return GlyfTable.__super__.constructor.apply(this, arguments);
+    }
+
+    GlyfTable.prototype.tag = "glyf";
+
+    GlyfTable.prototype.parse = function () {
+      return this.cache = {};
+    };
+
+    GlyfTable.prototype.glyphFor = function (id) {
+      var data, index, length, loca, numberOfContours, raw, xMax, xMin, yMax, yMin;
+
+      if (id in this.cache) {
+        return this.cache[id];
+      }
+
+      loca = this.file.loca;
+      data = this.file.contents;
+      index = loca.indexOf(id);
+      length = loca.lengthOf(id);
 
-      PNG.prototype.decode = function() {
-        var ret;
-        ret = new Uint8Array(this.width * this.height * 4);
-        this.copyToImageData(ret, this.decodePixels());
-        return ret;
-      };
+      if (length === 0) {
+        return this.cache[id] = null;
+      }
 
-      try {
-          scratchCanvas = global.document.createElement('canvas');
-          scratchCtx = scratchCanvas.getContext('2d');
-      } catch(e) {
-          return -1;
+      data.pos = this.offset + index;
+      raw = new Data(data.read(length));
+      numberOfContours = raw.readShort();
+      xMin = raw.readShort();
+      yMin = raw.readShort();
+      xMax = raw.readShort();
+      yMax = raw.readShort();
+
+      if (numberOfContours === -1) {
+        this.cache[id] = new CompoundGlyph(raw, xMin, yMin, xMax, yMax);
+      } else {
+        this.cache[id] = new SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax);
       }
 
-      makeImage = function(imageData) {
-        var img;
-        scratchCtx.width = imageData.width;
-        scratchCtx.height = imageData.height;
-        scratchCtx.clearRect(0, 0, imageData.width, imageData.height);
-        scratchCtx.putImageData(imageData, 0, 0);
-        img = new Image;
-        img.src = scratchCanvas.toDataURL();
-        return img;
-      };
+      return this.cache[id];
+    };
 
-      PNG.prototype.decodeFrames = function(ctx) {
-        var frame, i, imageData, pixels, _i, _len, _ref, _results;
-        if (!this.animation) {
-          return;
-        }
-        _ref = this.animation.frames;
-        _results = [];
-        for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
-          frame = _ref[i];
-          imageData = ctx.createImageData(frame.width, frame.height);
-          pixels = this.decodePixels(new Uint8Array(frame.data));
-          this.copyToImageData(imageData, pixels);
-          frame.imageData = imageData;
-          _results.push(frame.image = makeImage(imageData));
-        }
-        return _results;
-      };
+    GlyfTable.prototype.encode = function (glyphs, mapping, old2new) {
+      var glyph, id, offsets, table, _i, _len;
 
-      PNG.prototype.renderFrame = function(ctx, number) {
-        var frame, frames, prev;
-        frames = this.animation.frames;
-        frame = frames[number];
-        prev = frames[number - 1];
-        if (number === 0) {
-          ctx.clearRect(0, 0, this.width, this.height);
-        }
-        if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_BACKGROUND) {
-          ctx.clearRect(prev.xOffset, prev.yOffset, prev.width, prev.height);
-        } else if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_PREVIOUS) {
-          ctx.putImageData(prev.imageData, prev.xOffset, prev.yOffset);
-        }
-        if (frame.blendOp === APNG_BLEND_OP_SOURCE) {
-          ctx.clearRect(frame.xOffset, frame.yOffset, frame.width, frame.height);
+      table = [];
+      offsets = [];
+
+      for (_i = 0, _len = mapping.length; _i < _len; _i++) {
+        id = mapping[_i];
+        glyph = glyphs[id];
+        offsets.push(table.length);
+
+        if (glyph) {
+          table = table.concat(glyph.encode(old2new));
         }
-        return ctx.drawImage(frame.image, frame.xOffset, frame.yOffset);
-      };
+      }
 
-      PNG.prototype.animate = function(ctx) {
-        var doFrame, frameNumber, frames, numFrames, numPlays, _ref,
-          _this = this;
-        frameNumber = 0;
-        _ref = this.animation, numFrames = _ref.numFrames, frames = _ref.frames, numPlays = _ref.numPlays;
-        return (doFrame = function() {
-          var f, frame;
-          f = frameNumber++ % numFrames;
-          frame = frames[f];
-          _this.renderFrame(ctx, f);
-          if (numFrames > 1 && frameNumber / numFrames < numPlays) {
-            return _this.animation._timeout = setTimeout(doFrame, frame.delay);
-          }
-        })();
+      offsets.push(table.length);
+      return {
+        table: table,
+        offsets: offsets
       };
+    };
 
-      PNG.prototype.stopAnimation = function() {
-        var _ref;
-        return clearTimeout((_ref = this.animation) != null ? _ref._timeout : void 0);
-      };
+    return GlyfTable;
+  }(Table);
 
-      PNG.prototype.render = function(canvas) {
-        var ctx, data;
-        if (canvas._png) {
-          canvas._png.stopAnimation();
-        }
-        canvas._png = this;
-        canvas.width = this.width;
-        canvas.height = this.height;
-        ctx = canvas.getContext("2d");
-        if (this.animation) {
-          this.decodeFrames(ctx);
-          return this.animate(ctx);
-        } else {
-          data = ctx.createImageData(this.width, this.height);
-          this.copyToImageData(data, this.decodePixels());
-          return ctx.putImageData(data, 0, 0);
-        }
-      };
+  var SimpleGlyph = function () {
+    /**************************************************************************/
 
-      return PNG;
+    /* function : SimpleGlyph                                                 */
 
-    })();
+    /* comment : Stores raw, xMin, yMin, xMax, and yMax values for this glyph.*/
 
-    global.PNG = PNG;
+    /**************************************************************************/
+    function SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax) {
+      this.raw = raw;
+      this.numberOfContours = numberOfContours;
+      this.xMin = xMin;
+      this.yMin = yMin;
+      this.xMax = xMax;
+      this.yMax = yMax;
+      this.compound = false;
+    }
 
-  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global ||  Function('return typeof this === "object" && this.content')() || Function('return this')()));
-  // `self` is undefined in Firefox for Android content script context
-  // while `this` is nsIContentFrameMessageManager
-  // with an attribute `content` that corresponds to the window
+    SimpleGlyph.prototype.encode = function () {
+      return this.raw.data;
+    };
 
-  /*
-   * Extracted from pdf.js
-   * https://github.com/andreasgal/pdf.js
-   *
-   * Copyright (c) 2011 Mozilla Foundation
-   *
-   * Contributors: Andreas Gal <gal@mozilla.com>
-   *               Chris G Jones <cjones@mozilla.com>
-   *               Shaon Barman <shaon.barman@gmail.com>
-   *               Vivien Nicolas <21@vingtetun.org>
-   *               Justin D'Arcangelo <justindarc@gmail.com>
-   *               Yury Delendik
-   *
-   * 
-   */
+    return SimpleGlyph;
+  }();
 
-  var DecodeStream = (function() {
-    function constructor() {
-      this.pos = 0;
-      this.bufferLength = 0;
-      this.eof = false;
-      this.buffer = null;
-    }
+  var CompoundGlyph = function () {
+    var ARG_1_AND_2_ARE_WORDS, MORE_COMPONENTS, WE_HAVE_AN_X_AND_Y_SCALE, WE_HAVE_A_SCALE, WE_HAVE_A_TWO_BY_TWO;
+    ARG_1_AND_2_ARE_WORDS = 0x0001;
+    WE_HAVE_A_SCALE = 0x0008;
+    MORE_COMPONENTS = 0x0020;
+    WE_HAVE_AN_X_AND_Y_SCALE = 0x0040;
+    WE_HAVE_A_TWO_BY_TWO = 0x0080;
+    /********************************************************************************************************************/
 
-    constructor.prototype = {
-      ensureBuffer: function decodestream_ensureBuffer(requested) {
-        var buffer = this.buffer;
-        var current = buffer ? buffer.byteLength : 0;
-        if (requested < current)
-          return buffer;
-        var size = 512;
-        while (size < requested)
-          size <<= 1;
-        var buffer2 = new Uint8Array(size);
-        for (var i = 0; i < current; ++i)
-          buffer2[i] = buffer[i];
-        return this.buffer = buffer2;
-      },
-      getByte: function decodestream_getByte() {
-        var pos = this.pos;
-        while (this.bufferLength <= pos) {
-          if (this.eof)
-            return null;
-          this.readBlock();
-        }
-        return this.buffer[this.pos++];
-      },
-      getBytes: function decodestream_getBytes(length) {
-        var pos = this.pos;
+    /* function : CompoundGlypg generator                                                                               */
+
+    /* comment : It stores raw, xMin, yMin, xMax, yMax, glyph id, and glyph offset for the corresponding compound glyph.*/
+
+    /********************************************************************************************************************/
+
+    function CompoundGlyph(raw, xMin, yMin, xMax, yMax) {
+      var data, flags;
+      this.raw = raw;
+      this.xMin = xMin;
+      this.yMin = yMin;
+      this.xMax = xMax;
+      this.yMax = yMax;
+      this.compound = true;
+      this.glyphIDs = [];
+      this.glyphOffsets = [];
+      data = this.raw;
 
-        if (length) {
-          this.ensureBuffer(pos + length);
-          var end = pos + length;
+      while (true) {
+        flags = data.readShort();
+        this.glyphOffsets.push(data.pos);
+        this.glyphIDs.push(data.readUInt16());
 
-          while (!this.eof && this.bufferLength < end)
-            this.readBlock();
+        if (!(flags & MORE_COMPONENTS)) {
+          break;
+        }
 
-          var bufEnd = this.bufferLength;
-          if (end > bufEnd)
-            end = bufEnd;
+        if (flags & ARG_1_AND_2_ARE_WORDS) {
+          data.pos += 4;
         } else {
-          while (!this.eof)
-            this.readBlock();
+          data.pos += 2;
+        }
 
-          var end = this.bufferLength;
+        if (flags & WE_HAVE_A_TWO_BY_TWO) {
+          data.pos += 8;
+        } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
+          data.pos += 4;
+        } else if (flags & WE_HAVE_A_SCALE) {
+          data.pos += 2;
         }
+      }
+    }
+    /****************************************************************************************************************/
 
-        this.pos = end;
-        return this.buffer.subarray(pos, end);
-      },
-      lookChar: function decodestream_lookChar() {
-        var pos = this.pos;
-        while (this.bufferLength <= pos) {
-          if (this.eof)
-            return null;
-          this.readBlock();
-        }
-        return String.fromCharCode(this.buffer[this.pos]);
-      },
-      getChar: function decodestream_getChar() {
-        var pos = this.pos;
-        while (this.bufferLength <= pos) {
-          if (this.eof)
-            return null;
-          this.readBlock();
-        }
-        return String.fromCharCode(this.buffer[this.pos++]);
-      },
-      makeSubStream: function decodestream_makeSubstream(start, length, dict) {
-        var end = start + length;
-        while (this.bufferLength <= end && !this.eof)
-          this.readBlock();
-        return new Stream(this.buffer, start, length, dict);
-      },
-      skip: function decodestream_skip(n) {
-        if (!n)
-          n = 1;
-        this.pos += n;
-      },
-      reset: function decodestream_reset() {
-        this.pos = 0;
+    /* function : CompoundGlypg encode                                                                              */
+
+    /* comment : After creating a table for the characters you typed, you call directory.encode to encode the table.*/
+
+    /****************************************************************************************************************/
+
+
+    CompoundGlyph.prototype.encode = function () {
+      var i, result, _len, _ref;
+
+      result = new Data(__slice.call(this.raw.data));
+      _ref = this.glyphIDs;
+
+      for (i = 0, _len = _ref.length; i < _len; ++i) {
+        result.pos = this.glyphOffsets[i];
       }
+
+      return result.data;
     };
 
-    return constructor;
-  })();
+    return CompoundGlyph;
+  }();
 
-  var FlateStream = (function() {
-    if (typeof Uint32Array === 'undefined') {
-      return undefined;
-    }
-    var codeLenCodeMap = new Uint32Array([
-      16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
-    ]);
-
-    var lengthDecode = new Uint32Array([
-      0x00003, 0x00004, 0x00005, 0x00006, 0x00007, 0x00008, 0x00009, 0x0000a,
-      0x1000b, 0x1000d, 0x1000f, 0x10011, 0x20013, 0x20017, 0x2001b, 0x2001f,
-      0x30023, 0x3002b, 0x30033, 0x3003b, 0x40043, 0x40053, 0x40063, 0x40073,
-      0x50083, 0x500a3, 0x500c3, 0x500e3, 0x00102, 0x00102, 0x00102
-    ]);
-
-    var distDecode = new Uint32Array([
-      0x00001, 0x00002, 0x00003, 0x00004, 0x10005, 0x10007, 0x20009, 0x2000d,
-      0x30011, 0x30019, 0x40021, 0x40031, 0x50041, 0x50061, 0x60081, 0x600c1,
-      0x70101, 0x70181, 0x80201, 0x80301, 0x90401, 0x90601, 0xa0801, 0xa0c01,
-      0xb1001, 0xb1801, 0xc2001, 0xc3001, 0xd4001, 0xd6001
-    ]);
-
-    var fixedLitCodeTab = [new Uint32Array([
-      0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c0,
-      0x70108, 0x80060, 0x80020, 0x900a0, 0x80000, 0x80080, 0x80040, 0x900e0,
-      0x70104, 0x80058, 0x80018, 0x90090, 0x70114, 0x80078, 0x80038, 0x900d0,
-      0x7010c, 0x80068, 0x80028, 0x900b0, 0x80008, 0x80088, 0x80048, 0x900f0,
-      0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c8,
-      0x7010a, 0x80064, 0x80024, 0x900a8, 0x80004, 0x80084, 0x80044, 0x900e8,
-      0x70106, 0x8005c, 0x8001c, 0x90098, 0x70116, 0x8007c, 0x8003c, 0x900d8,
-      0x7010e, 0x8006c, 0x8002c, 0x900b8, 0x8000c, 0x8008c, 0x8004c, 0x900f8,
-      0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c4,
-      0x70109, 0x80062, 0x80022, 0x900a4, 0x80002, 0x80082, 0x80042, 0x900e4,
-      0x70105, 0x8005a, 0x8001a, 0x90094, 0x70115, 0x8007a, 0x8003a, 0x900d4,
-      0x7010d, 0x8006a, 0x8002a, 0x900b4, 0x8000a, 0x8008a, 0x8004a, 0x900f4,
-      0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cc,
-      0x7010b, 0x80066, 0x80026, 0x900ac, 0x80006, 0x80086, 0x80046, 0x900ec,
-      0x70107, 0x8005e, 0x8001e, 0x9009c, 0x70117, 0x8007e, 0x8003e, 0x900dc,
-      0x7010f, 0x8006e, 0x8002e, 0x900bc, 0x8000e, 0x8008e, 0x8004e, 0x900fc,
-      0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c2,
-      0x70108, 0x80061, 0x80021, 0x900a2, 0x80001, 0x80081, 0x80041, 0x900e2,
-      0x70104, 0x80059, 0x80019, 0x90092, 0x70114, 0x80079, 0x80039, 0x900d2,
-      0x7010c, 0x80069, 0x80029, 0x900b2, 0x80009, 0x80089, 0x80049, 0x900f2,
-      0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900ca,
-      0x7010a, 0x80065, 0x80025, 0x900aa, 0x80005, 0x80085, 0x80045, 0x900ea,
-      0x70106, 0x8005d, 0x8001d, 0x9009a, 0x70116, 0x8007d, 0x8003d, 0x900da,
-      0x7010e, 0x8006d, 0x8002d, 0x900ba, 0x8000d, 0x8008d, 0x8004d, 0x900fa,
-      0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c6,
-      0x70109, 0x80063, 0x80023, 0x900a6, 0x80003, 0x80083, 0x80043, 0x900e6,
-      0x70105, 0x8005b, 0x8001b, 0x90096, 0x70115, 0x8007b, 0x8003b, 0x900d6,
-      0x7010d, 0x8006b, 0x8002b, 0x900b6, 0x8000b, 0x8008b, 0x8004b, 0x900f6,
-      0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900ce,
-      0x7010b, 0x80067, 0x80027, 0x900ae, 0x80007, 0x80087, 0x80047, 0x900ee,
-      0x70107, 0x8005f, 0x8001f, 0x9009e, 0x70117, 0x8007f, 0x8003f, 0x900de,
-      0x7010f, 0x8006f, 0x8002f, 0x900be, 0x8000f, 0x8008f, 0x8004f, 0x900fe,
-      0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c1,
-      0x70108, 0x80060, 0x80020, 0x900a1, 0x80000, 0x80080, 0x80040, 0x900e1,
-      0x70104, 0x80058, 0x80018, 0x90091, 0x70114, 0x80078, 0x80038, 0x900d1,
-      0x7010c, 0x80068, 0x80028, 0x900b1, 0x80008, 0x80088, 0x80048, 0x900f1,
-      0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c9,
-      0x7010a, 0x80064, 0x80024, 0x900a9, 0x80004, 0x80084, 0x80044, 0x900e9,
-      0x70106, 0x8005c, 0x8001c, 0x90099, 0x70116, 0x8007c, 0x8003c, 0x900d9,
-      0x7010e, 0x8006c, 0x8002c, 0x900b9, 0x8000c, 0x8008c, 0x8004c, 0x900f9,
-      0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c5,
-      0x70109, 0x80062, 0x80022, 0x900a5, 0x80002, 0x80082, 0x80042, 0x900e5,
-      0x70105, 0x8005a, 0x8001a, 0x90095, 0x70115, 0x8007a, 0x8003a, 0x900d5,
-      0x7010d, 0x8006a, 0x8002a, 0x900b5, 0x8000a, 0x8008a, 0x8004a, 0x900f5,
-      0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cd,
-      0x7010b, 0x80066, 0x80026, 0x900ad, 0x80006, 0x80086, 0x80046, 0x900ed,
-      0x70107, 0x8005e, 0x8001e, 0x9009d, 0x70117, 0x8007e, 0x8003e, 0x900dd,
-      0x7010f, 0x8006e, 0x8002e, 0x900bd, 0x8000e, 0x8008e, 0x8004e, 0x900fd,
-      0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c3,
-      0x70108, 0x80061, 0x80021, 0x900a3, 0x80001, 0x80081, 0x80041, 0x900e3,
-      0x70104, 0x80059, 0x80019, 0x90093, 0x70114, 0x80079, 0x80039, 0x900d3,
-      0x7010c, 0x80069, 0x80029, 0x900b3, 0x80009, 0x80089, 0x80049, 0x900f3,
-      0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900cb,
-      0x7010a, 0x80065, 0x80025, 0x900ab, 0x80005, 0x80085, 0x80045, 0x900eb,
-      0x70106, 0x8005d, 0x8001d, 0x9009b, 0x70116, 0x8007d, 0x8003d, 0x900db,
-      0x7010e, 0x8006d, 0x8002d, 0x900bb, 0x8000d, 0x8008d, 0x8004d, 0x900fb,
-      0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c7,
-      0x70109, 0x80063, 0x80023, 0x900a7, 0x80003, 0x80083, 0x80043, 0x900e7,
-      0x70105, 0x8005b, 0x8001b, 0x90097, 0x70115, 0x8007b, 0x8003b, 0x900d7,
-      0x7010d, 0x8006b, 0x8002b, 0x900b7, 0x8000b, 0x8008b, 0x8004b, 0x900f7,
-      0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900cf,
-      0x7010b, 0x80067, 0x80027, 0x900af, 0x80007, 0x80087, 0x80047, 0x900ef,
-      0x70107, 0x8005f, 0x8001f, 0x9009f, 0x70117, 0x8007f, 0x8003f, 0x900df,
-      0x7010f, 0x8006f, 0x8002f, 0x900bf, 0x8000f, 0x8008f, 0x8004f, 0x900ff
-    ]), 9];
-
-    var fixedDistCodeTab = [new Uint32Array([
-      0x50000, 0x50010, 0x50008, 0x50018, 0x50004, 0x50014, 0x5000c, 0x5001c,
-      0x50002, 0x50012, 0x5000a, 0x5001a, 0x50006, 0x50016, 0x5000e, 0x00000,
-      0x50001, 0x50011, 0x50009, 0x50019, 0x50005, 0x50015, 0x5000d, 0x5001d,
-      0x50003, 0x50013, 0x5000b, 0x5001b, 0x50007, 0x50017, 0x5000f, 0x00000
-    ]), 5];
-    
-    function error(e) {
-        throw new Error(e)
+  var LocaTable = function (_super) {
+    __extends(LocaTable, _super);
+
+    function LocaTable() {
+      return LocaTable.__super__.constructor.apply(this, arguments);
     }
 
-    function constructor(bytes) {
-      //var bytes = stream.getBytes();
-      var bytesPos = 0;
+    LocaTable.prototype.tag = "loca";
 
-      var cmf = bytes[bytesPos++];
-      var flg = bytes[bytesPos++];
-      if (cmf == -1 || flg == -1)
-        error('Invalid header in flate stream');
-      if ((cmf & 0x0f) != 0x08)
-        error('Unknown compression method in flate stream');
-      if ((((cmf << 8) + flg) % 31) != 0)
-        error('Bad FCHECK in flate stream');
-      if (flg & 0x20)
-        error('FDICT bit set in flate stream');
+    LocaTable.prototype.parse = function (data) {
+      var format, i;
+      data.pos = this.offset;
+      format = this.file.head.indexToLocFormat;
 
-      this.bytes = bytes;
-      this.bytesPos = bytesPos;
+      if (format === 0) {
+        return this.offsets = function () {
+          var _ref, _results;
 
-      this.codeSize = 0;
-      this.codeBuf = 0;
+          _results = [];
 
-      DecodeStream.call(this);
-    }
+          for (i = 0, _ref = this.length; i < _ref; i += 2) {
+            _results.push(data.readUInt16() * 2);
+          }
 
-    constructor.prototype = Object.create(DecodeStream.prototype);
-
-    constructor.prototype.getBits = function(bits) {
-      var codeSize = this.codeSize;
-      var codeBuf = this.codeBuf;
-      var bytes = this.bytes;
-      var bytesPos = this.bytesPos;
-
-      var b;
-      while (codeSize < bits) {
-        if (typeof (b = bytes[bytesPos++]) == 'undefined')
-          error('Bad encoding in flate stream');
-        codeBuf |= b << codeSize;
-        codeSize += 8;
-      }
-      b = codeBuf & ((1 << bits) - 1);
-      this.codeBuf = codeBuf >> bits;
-      this.codeSize = codeSize -= bits;
-      this.bytesPos = bytesPos;
-      return b;
-    };
-
-    constructor.prototype.getCode = function(table) {
-      var codes = table[0];
-      var maxLen = table[1];
-      var codeSize = this.codeSize;
-      var codeBuf = this.codeBuf;
-      var bytes = this.bytes;
-      var bytesPos = this.bytesPos;
-
-      while (codeSize < maxLen) {
-        var b;
-        if (typeof (b = bytes[bytesPos++]) == 'undefined')
-          error('Bad encoding in flate stream');
-        codeBuf |= (b << codeSize);
-        codeSize += 8;
-      }
-      var code = codes[codeBuf & ((1 << maxLen) - 1)];
-      var codeLen = code >> 16;
-      var codeVal = code & 0xffff;
-      if (codeSize == 0 || codeSize < codeLen || codeLen == 0)
-        error('Bad encoding in flate stream');
-      this.codeBuf = (codeBuf >> codeLen);
-      this.codeSize = (codeSize - codeLen);
-      this.bytesPos = bytesPos;
-      return codeVal;
-    };
-
-    constructor.prototype.generateHuffmanTable = function(lengths) {
-      var n = lengths.length;
-
-      // find max code length
-      var maxLen = 0;
-      for (var i = 0; i < n; ++i) {
-        if (lengths[i] > maxLen)
-          maxLen = lengths[i];
-      }
-
-      // build the table
-      var size = 1 << maxLen;
-      var codes = new Uint32Array(size);
-      for (var len = 1, code = 0, skip = 2;
-           len <= maxLen;
-           ++len, code <<= 1, skip <<= 1) {
-        for (var val = 0; val < n; ++val) {
-          if (lengths[val] == len) {
-            // bit-reverse the code
-            var code2 = 0;
-            var t = code;
-            for (var i = 0; i < len; ++i) {
-              code2 = (code2 << 1) | (t & 1);
-              t >>= 1;
-            }
+          return _results;
+        }.call(this);
+      } else {
+        return this.offsets = function () {
+          var _ref, _results;
 
-            // fill the table entries
-            for (var i = code2; i < size; i += skip)
-              codes[i] = (len << 16) | val;
+          _results = [];
 
-            ++code;
+          for (i = 0, _ref = this.length; i < _ref; i += 4) {
+            _results.push(data.readUInt32());
           }
-        }
+
+          return _results;
+        }.call(this);
       }
+    };
 
-      return [codes, maxLen];
+    LocaTable.prototype.indexOf = function (id) {
+      return this.offsets[id];
     };
 
-    constructor.prototype.readBlock = function() {
-      function repeat(stream, array, len, offset, what) {
-        var repeat = stream.getBits(len) + offset;
-        while (repeat-- > 0)
-          array[i++] = what;
-      }
+    LocaTable.prototype.lengthOf = function (id) {
+      return this.offsets[id + 1] - this.offsets[id];
+    };
 
-      // read block header
-      var hdr = this.getBits(3);
-      if (hdr & 1)
-        this.eof = true;
-      hdr >>= 1;
+    LocaTable.prototype.encode = function (offsets, activeGlyphs) {
+      var LocaTable = new Uint32Array(this.offsets.length);
+      var glyfPtr = 0;
+      var listGlyf = 0;
 
-      if (hdr == 0) { // uncompressed block
-        var bytes = this.bytes;
-        var bytesPos = this.bytesPos;
-        var b;
+      for (var k = 0; k < LocaTable.length; ++k) {
+        LocaTable[k] = glyfPtr;
 
-        if (typeof (b = bytes[bytesPos++]) == 'undefined')
-          error('Bad block header in flate stream');
-        var blockLen = b;
-        if (typeof (b = bytes[bytesPos++]) == 'undefined')
-          error('Bad block header in flate stream');
-        blockLen |= (b << 8);
-        if (typeof (b = bytes[bytesPos++]) == 'undefined')
-          error('Bad block header in flate stream');
-        var check = b;
-        if (typeof (b = bytes[bytesPos++]) == 'undefined')
-          error('Bad block header in flate stream');
-        check |= (b << 8);
-        if (check != (~blockLen & 0xffff))
-          error('Bad uncompressed block length in flate stream');
-
-        this.codeBuf = 0;
-        this.codeSize = 0;
-
-        var bufferLength = this.bufferLength;
-        var buffer = this.ensureBuffer(bufferLength + blockLen);
-        var end = bufferLength + blockLen;
-        this.bufferLength = end;
-        for (var n = bufferLength; n < end; ++n) {
-          if (typeof (b = bytes[bytesPos++]) == 'undefined') {
-            this.eof = true;
-            break;
+        if (listGlyf < activeGlyphs.length && activeGlyphs[listGlyf] == k) {
+          ++listGlyf;
+          LocaTable[k] = glyfPtr;
+          var start = this.offsets[k];
+          var len = this.offsets[k + 1] - start;
+
+          if (len > 0) {
+            glyfPtr += len;
           }
-          buffer[n] = b;
         }
-        this.bytesPos = bytesPos;
-        return;
       }
 
-      var litCodeTable;
-      var distCodeTable;
-      if (hdr == 1) { // compressed block, fixed codes
-        litCodeTable = fixedLitCodeTab;
-        distCodeTable = fixedDistCodeTab;
-      } else if (hdr == 2) { // compressed block, dynamic codes
-        var numLitCodes = this.getBits(5) + 257;
-        var numDistCodes = this.getBits(5) + 1;
-        var numCodeLenCodes = this.getBits(4) + 4;
+      var newLocaTable = new Array(LocaTable.length * 4);
 
-        // build the code lengths code table
-        var codeLenCodeLengths = Array(codeLenCodeMap.length);
-        var i = 0;
-        while (i < numCodeLenCodes)
-          codeLenCodeLengths[codeLenCodeMap[i++]] = this.getBits(3);
-        var codeLenCodeTab = this.generateHuffmanTable(codeLenCodeLengths);
+      for (var j = 0; j < LocaTable.length; ++j) {
+        newLocaTable[4 * j + 3] = LocaTable[j] & 0x000000ff;
+        newLocaTable[4 * j + 2] = (LocaTable[j] & 0x0000ff00) >> 8;
+        newLocaTable[4 * j + 1] = (LocaTable[j] & 0x00ff0000) >> 16;
+        newLocaTable[4 * j] = (LocaTable[j] & 0xff000000) >> 24;
+      }
 
-        // build the literal and distance code tables
-        var len = 0;
-        var i = 0;
-        var codes = numLitCodes + numDistCodes;
-        var codeLengths = new Array(codes);
-        while (i < codes) {
-          var code = this.getCode(codeLenCodeTab);
-          if (code == 16) {
-            repeat(this, codeLengths, 2, 3, len);
-          } else if (code == 17) {
-            repeat(this, codeLengths, 3, 3, len = 0);
-          } else if (code == 18) {
-            repeat(this, codeLengths, 7, 11, len = 0);
-          } else {
-            codeLengths[i++] = len = code;
-          }
-        }
+      return newLocaTable;
+    };
 
-        litCodeTable =
-          this.generateHuffmanTable(codeLengths.slice(0, numLitCodes));
-        distCodeTable =
-          this.generateHuffmanTable(codeLengths.slice(numLitCodes, codes));
-      } else {
-        error('Unknown block type in flate stream');
-      }
+    return LocaTable;
+  }(Table);
+  /************************************************************************************/
 
-      var buffer = this.buffer;
-      var limit = buffer ? buffer.length : 0;
-      var pos = this.bufferLength;
-      while (true) {
-        var code1 = this.getCode(litCodeTable);
-        if (code1 < 256) {
-          if (pos + 1 >= limit) {
-            buffer = this.ensureBuffer(pos + 1);
-            limit = buffer.length;
+  /* function : invert                                                                */
+
+  /* comment : Change the object's (key: value) to create an object with (value: key).*/
+
+  /************************************************************************************/
+
+
+  var invert = function invert(object) {
+    var key, ret, val;
+    ret = {};
+
+    for (key in object) {
+      val = object[key];
+      ret[val] = key;
+    }
+
+    return ret;
+  };
+  /*var successorOf = function (input) {
+          var added, alphabet, carry, i, index, isUpperCase, last, length, next, result;
+          alphabet = 'abcdefghijklmnopqrstuvwxyz';
+          length = alphabet.length;
+          result = input;
+          i = input.length;
+          while (i >= 0) {
+              last = input.charAt(--i);
+              if (isNaN(last)) {
+                  index = alphabet.indexOf(last.toLowerCase());
+                  if (index === -1) {
+                      next = last;
+                      carry = true;
+                  }
+                  else {
+                      next = alphabet.charAt((index + 1) % length);
+                      isUpperCase = last === last.toUpperCase();
+                      if (isUpperCase) {
+                          next = next.toUpperCase();
+                      }
+                      carry = index + 1 >= length;
+                      if (carry && i === 0) {
+                          added = isUpperCase ? 'A' : 'a';
+                          result = added + next + result.slice(1);
+                          break;
+                      }
+                  }
+              }
+              else {
+                  next = +last + 1;
+                  carry = next > 9;
+                  if (carry) {
+                      next = 0;
+                  }
+                  if (carry && i === 0) {
+                      result = '1' + next + result.slice(1);
+                      break;
+                  }
+              }
+              result = result.slice(0, i) + next + result.slice(i + 1);
+              if (!carry) {
+                  break;
+              }
           }
-          buffer[pos++] = code1;
-          continue;
-        }
-        if (code1 == 256) {
-          this.bufferLength = pos;
-          return;
-        }
-        code1 -= 257;
-        code1 = lengthDecode[code1];
-        var code2 = code1 >> 16;
-        if (code2 > 0)
-          code2 = this.getBits(code2);
-        var len = (code1 & 0xffff) + code2;
-        code1 = this.getCode(distCodeTable);
-        code1 = distDecode[code1];
-        code2 = code1 >> 16;
-        if (code2 > 0)
-          code2 = this.getBits(code2);
-        var dist = (code1 & 0xffff) + code2;
-        if (pos + len >= limit) {
-          buffer = this.ensureBuffer(pos + len);
-          limit = buffer.length;
-        }
-        for (var k = 0; k < len; ++k, ++pos)
-          buffer[pos] = buffer[pos - dist];
-      }
-    };
+          return result;
+      };*/
 
-    return constructor;
-  })();
 
-  /**
-   * JavaScript Polyfill functions for jsPDF
-   * Collected from public resources by
-   * https://github.com/diegocr
-   */
+  var Subset = function () {
+    function Subset(font) {
+      this.font = font;
+      this.subset = {};
+      this.unicodes = {};
+      this.next = 33;
+    }
+    /*Subset.prototype.use = function (character) {
+              var i, _i, _ref;
+              if (typeof character === 'string') {
+                  for (i = _i = 0, _ref = character.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
+                      this.use(character.charCodeAt(i));
+                  }
+                  return;
+              }
+              if (!this.unicodes[character]) {
+                  this.subset[this.next] = character;
+                  return this.unicodes[character] = this.next++;
+              }
+          };*/
 
-  (function (global) {
-      
-      if (typeof global.console !== "object") {
-          // Console-polyfill. MIT license.
-          // https://github.com/paulmillr/console-polyfill
-          // Make it safe to do console.log() always.
-          global.console = {};
-          
-          var con = global.console;
-          var prop, method;
-          var dummy = function() {};
-          var properties = ['memory'];
-          var methods = ('assert,clear,count,debug,dir,dirxml,error,exception,group,' +
-           'groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,' +
-           'show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn').split(',');
-          while (prop = properties.pop()) if (!con[prop]) con[prop] = {};
-          while (method = methods.pop()) if (!con[method]) con[method] = dummy;
-      }
-
-      var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
-
-      if (typeof global.btoa === 'undefined') {
-          global.btoa = function(data) {
-              //  discuss at: http://phpjs.org/functions/base64_encode/
-              // original by: Tyler Akins (http://rumkin.com)
-              // improved by: Bayron Guevara
-              // improved by: Thunder.m
-              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
-              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
-              // improved by: Rafal Kukawski (http://kukawski.pl)
-              // bugfixed by: Pellentesque Malesuada
-              //   example 1: base64_encode('Kevin van Zonneveld');
-              //   returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA=='
-
-              var o1,o2,o3,h1,h2,h3,h4,bits,i = 0,ac = 0,enc = '',tmp_arr = [];
-
-              if (!data) {
-                  return data;
+    /*Subset.prototype.encodeText = function (text) {
+              var char, i, string, _i, _ref;
+              string = '';
+              for (i = _i = 0, _ref = text.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
+                  char = this.unicodes[text.charCodeAt(i)];
+                  string += String.fromCharCode(char);
               }
+              return string;
+          };*/
 
-              do { // pack three octets into four hexets
-                  o1 = data.charCodeAt(i++);
-                  o2 = data.charCodeAt(i++);
-                  o3 = data.charCodeAt(i++);
+    /***************************************************************/
 
-                  bits = o1 << 16 | o2 << 8 | o3;
+    /* function : generateCmap                                     */
 
-                  h1 = bits >> 18 & 0x3f;
-                  h2 = bits >> 12 & 0x3f;
-                  h3 = bits >> 6 & 0x3f;
-                  h4 = bits & 0x3f;
+    /* comment : Returns the unicode cmap for this font.         */
 
-                  // use hexets to index into b64, and append result to encoded string
-                  tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
-              } while (i < data.length);
+    /***************************************************************/
 
-              enc = tmp_arr.join('');
 
-              var r = data.length % 3;
+    Subset.prototype.generateCmap = function () {
+      var mapping, roman, unicode, unicodeCmap, _ref;
 
-              return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3);
-          };
+      unicodeCmap = this.font.cmap.tables[0].codeMap;
+      mapping = {};
+      _ref = this.subset;
+
+      for (roman in _ref) {
+        unicode = _ref[roman];
+        mapping[roman] = unicodeCmap[unicode];
       }
 
-      if (typeof global.atob === 'undefined') {
-          global.atob = function(data) {
-              //  discuss at: http://phpjs.org/functions/base64_decode/
-              // original by: Tyler Akins (http://rumkin.com)
-              // improved by: Thunder.m
-              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
-              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
-              //    input by: Aman Gupta
-              //    input by: Brett Zamir (http://brett-zamir.me)
-              // bugfixed by: Onno Marsman
-              // bugfixed by: Pellentesque Malesuada
-              // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
-              //   example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA==');
-              //   returns 1: 'Kevin van Zonneveld'
-
-              var o1,o2,o3,h1,h2,h3,h4,bits,i = 0,ac = 0,dec = '',tmp_arr = [];
-
-              if (!data) {
-                  return data;
+      return mapping;
+    };
+    /*Subset.prototype.glyphIDs = function () {
+              var ret, roman, unicode, unicodeCmap, val, _ref;
+              unicodeCmap = this.font.cmap.tables[0].codeMap;
+              ret = [0];
+              _ref = this.subset;
+              for (roman in _ref) {
+                  unicode = _ref[roman];
+                  val = unicodeCmap[unicode];
+                  if ((val != null) && __indexOf.call(ret, val) < 0) {
+                      ret.push(val);
+                  }
               }
+              return ret.sort();
+          };*/
 
-              data += '';
+    /******************************************************************/
 
-              do { // unpack four hexets into three octets using index points in b64
-                  h1 = b64.indexOf(data.charAt(i++));
-                  h2 = b64.indexOf(data.charAt(i++));
-                  h3 = b64.indexOf(data.charAt(i++));
-                  h4 = b64.indexOf(data.charAt(i++));
+    /* function : glyphsFor                                           */
 
-                  bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
+    /* comment : Returns simple glyph objects for the input character.*/
 
-                  o1 = bits >> 16 & 0xff;
-                  o2 = bits >> 8 & 0xff;
-                  o3 = bits & 0xff;
+    /******************************************************************/
 
-                  if (h3 == 64) {
-                      tmp_arr[ac++] = String.fromCharCode(o1);
-                  } else if (h4 == 64) {
-                      tmp_arr[ac++] = String.fromCharCode(o1, o2);
-                  } else {
-                      tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
-                  }
-              } while (i < data.length);
 
-              dec = tmp_arr.join('');
+    Subset.prototype.glyphsFor = function (glyphIDs) {
+      var additionalIDs, glyph, glyphs, id, _i, _len, _ref;
 
-              return dec;
-          };
+      glyphs = {};
+
+      for (_i = 0, _len = glyphIDs.length; _i < _len; _i++) {
+        id = glyphIDs[_i];
+        glyphs[id] = this.font.glyf.glyphFor(id);
       }
 
-      if (!Array.prototype.map) {
-          Array.prototype.map = function(fun /*, thisArg */) {
-              if (this === void 0 || this === null || typeof fun !== "function")
-                  throw new TypeError();
-
-              var t = Object(this), len = t.length >>> 0, res = new Array(len);
-              var thisArg = arguments.length > 1 ? arguments[1] : void 0;
-              for (var i = 0; i < len; i++) {
-                  // NOTE: Absolute correctness would demand Object.defineProperty
-                  //       be used.  But this method is fairly new, and failure is
-                  //       possible only if Object.prototype or Array.prototype
-                  //       has a property |i| (very unlikely), so use a less-correct
-                  //       but more portable alternative.
-                  if (i in t)
-                      res[i] = fun.call(thisArg, t[i], i, t);
-              }
+      additionalIDs = [];
 
-              return res;
-          };
+      for (id in glyphs) {
+        glyph = glyphs[id];
+
+        if (glyph != null ? glyph.compound : void 0) {
+          additionalIDs.push.apply(additionalIDs, glyph.glyphIDs);
+        }
       }
 
+      if (additionalIDs.length > 0) {
+        _ref = this.glyphsFor(additionalIDs);
 
-      if(!Array.isArray) {
-          Array.isArray = function(arg) {
-              return Object.prototype.toString.call(arg) === '[object Array]';
-          };
+        for (id in _ref) {
+          glyph = _ref[id];
+          glyphs[id] = glyph;
+        }
       }
 
-      if (!Array.prototype.forEach) {
-          Array.prototype.forEach = function(fun, thisArg) {
+      return glyphs;
+    };
+    /***************************************************************/
 
-              if (this === void 0 || this === null || typeof fun !== "function")
-                  throw new TypeError();
+    /* function : encode                                           */
 
-              var t = Object(this), len = t.length >>> 0;
-              for (var i = 0; i < len; i++) {
-                  if (i in t)
-                      fun.call(thisArg, t[i], i, t);
-              }
-          };
-      }
-      
-      if (!Object.keys) {
-          Object.keys = (function () {
+    /* comment : Encode various tables for the characters you use. */
 
-              var hasOwnProperty = Object.prototype.hasOwnProperty,
-                  hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
-                  dontEnums = ['toString','toLocaleString','valueOf','hasOwnProperty',
-                      'isPrototypeOf','propertyIsEnumerable','constructor'],
-                  dontEnumsLength = dontEnums.length;
+    /***************************************************************/
 
-              return function (obj) {
-                  if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
-                      throw new TypeError();
-                  }
-                  var result = [], prop, i;
 
-                  for (prop in obj) {
-                      if (hasOwnProperty.call(obj, prop)) {
-                          result.push(prop);
-                      }
-                  }
+    Subset.prototype.encode = function (glyID, indexToLocFormat) {
+      var cmap, code, glyf, glyphs, id, ids, loca, new2old, newIDs, nextGlyphID, old2new, oldID, oldIDs, tables, _ref;
 
-                  if (hasDontEnumBug) {
-                      for (i = 0; i < dontEnumsLength; i++) {
-                          if (hasOwnProperty.call(obj, dontEnums[i])) {
-                              result.push(dontEnums[i]);
-                          }
-                      }
-                  }
-                  return result;
-              };
-          }());
+      cmap = CmapTable.encode(this.generateCmap(), "unicode");
+      glyphs = this.glyphsFor(glyID);
+      old2new = {
+        0: 0
+      };
+      _ref = cmap.charMap;
+
+      for (code in _ref) {
+        ids = _ref[code];
+        old2new[ids.old] = ids["new"];
       }
-      
-      if (typeof Object.assign != 'function') {
-            Object.assign = function(target) {
-              if (target == null) {
-                throw new TypeError('Cannot convert undefined or null to object');
-              }
 
-              target = Object(target);
-              for (var index = 1; index < arguments.length; index++) {
-                var source = arguments[index];
-                if (source != null) {
-                  for (var key in source) {
-                    if (Object.prototype.hasOwnProperty.call(source, key)) {
-                      target[key] = source[key];
-                    }
-                  }
-                }
-              }
-              return target;
-            };
-          }
+      nextGlyphID = cmap.maxGlyphID;
 
-      if (!String.prototype.trim) {
-          String.prototype.trim = function () {
-              return this.replace(/^\s+|\s+$/g, '');
-          };
-      }
-      if (!String.prototype.trimLeft) {
-          String.prototype.trimLeft = function() {
-              return this.replace(/^\s+/g, "");
-          };
+      for (oldID in glyphs) {
+        if (!(oldID in old2new)) {
+          old2new[oldID] = nextGlyphID++;
+        }
       }
-      if (!String.prototype.trimRight) {
-          String.prototype.trimRight = function() {
-              return this.replace(/\s+$/g, "");
-          };
+
+      new2old = invert(old2new);
+      newIDs = Object.keys(new2old).sort(function (a, b) {
+        return a - b;
+      });
+
+      oldIDs = function () {
+        var _i, _len, _results;
+
+        _results = [];
+
+        for (_i = 0, _len = newIDs.length; _i < _len; _i++) {
+          id = newIDs[_i];
+
+          _results.push(new2old[id]);
+        }
+
+        return _results;
+      }();
+
+      glyf = this.font.glyf.encode(glyphs, oldIDs, old2new);
+      loca = this.font.loca.encode(glyf.offsets, oldIDs);
+      tables = {
+        cmap: this.font.cmap.raw(),
+        glyf: glyf.table,
+        loca: loca,
+        hmtx: this.font.hmtx.raw(),
+        hhea: this.font.hhea.raw(),
+        maxp: this.font.maxp.raw(),
+        post: this.font.post.raw(),
+        name: this.font.name.raw(),
+        head: this.font.head.encode(indexToLocFormat)
+      };
+
+      if (this.font.os2.exists) {
+        tables["OS/2"] = this.font.os2.raw();
       }
 
+      return this.font.directory.encode(tables);
+    };
+
+    return Subset;
+  }();
+
+  jsPDF.API.PDFObject = function () {
+    var pad;
 
-  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global ||  Function('return typeof this === "object" && this.content')() || Function('return this')()));
-  // `self` is undefined in Firefox for Android content script context
-  // while `this` is nsIContentFrameMessageManager
-  // with an attribute `content` that corresponds to the window
+    function PDFObject() {}
 
-  return jsPDF;
+    pad = function pad(str, length) {
+      return (Array(length + 1).join("0") + str).slice(-length);
+    };
+    /*****************************************************************************/
+
+    /* function : convert                                                        */
+
+    /* comment :Converts pdf tag's / FontBBox and array values in / W to strings */
+
+    /*****************************************************************************/
+
+
+    PDFObject.convert = function (object) {
+      var e, items, key, out, val;
+
+      if (Array.isArray(object)) {
+        items = function () {
+          var _i, _len, _results;
+
+          _results = [];
 
+          for (_i = 0, _len = object.length; _i < _len; _i++) {
+            e = object[_i];
+
+            _results.push(PDFObject.convert(e));
+          }
+
+          return _results;
+        }().join(" ");
+
+        return "[" + items + "]";
+      } else if (typeof object === "string") {
+        return "/" + object;
+      } else if (object != null ? object.isString : void 0) {
+        return "(" + object + ")";
+      } else if (object instanceof Date) {
+        return "(D:" + pad(object.getUTCFullYear(), 4) + pad(object.getUTCMonth(), 2) + pad(object.getUTCDate(), 2) + pad(object.getUTCHours(), 2) + pad(object.getUTCMinutes(), 2) + pad(object.getUTCSeconds(), 2) + "Z)";
+      } else if ({}.toString.call(object) === "[object Object]") {
+        out = ["<<"];
+
+        for (key in object) {
+          val = object[key];
+          out.push("/" + key + " " + PDFObject.convert(val));
+        }
+
+        out.push(">>");
+        return out.join("\n");
+      } else {
+        return "" + object;
+      }
+    };
 
-});
\ No newline at end of file
+    return PDFObject;
+  }();
+
+  exports.AcroForm = AcroForm;
+  exports.AcroFormAppearance = AcroFormAppearance;
+  exports.AcroFormButton = AcroFormButton;
+  exports.AcroFormCheckBox = AcroFormCheckBox;
+  exports.AcroFormChoiceField = AcroFormChoiceField;
+  exports.AcroFormComboBox = AcroFormComboBox;
+  exports.AcroFormEditBox = AcroFormEditBox;
+  exports.AcroFormListBox = AcroFormListBox;
+  exports.AcroFormPasswordField = AcroFormPasswordField;
+  exports.AcroFormPushButton = AcroFormPushButton;
+  exports.AcroFormRadioButton = AcroFormRadioButton;
+  exports.AcroFormTextField = AcroFormTextField;
+  exports.GState = GState;
+  exports.ShadingPattern = ShadingPattern;
+  exports.TilingPattern = TilingPattern;
+  exports.default = jsPDF;
+  exports.jsPDF = jsPDF;
+
+  Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
+//# sourceMappingURL=jspdf.umd.js.map
diff --git a/amd/src/jspdf.js.ori b/amd/src/jspdf.js.ori
deleted file mode 100644
index 66810c9370e458ad112de2a339a6bb968f3f33ef..0000000000000000000000000000000000000000
--- a/amd/src/jspdf.js.ori
+++ /dev/null
@@ -1,22721 +0,0 @@
-define(function() {
- 
- 
-  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
-    return typeof obj;
-  } : function (obj) {
-    return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
-  };
-
-
-  /** @preserve
-   * jsPDF - PDF Document creation from JavaScript
-   * Version 1.4.1 Built on 2018-06-06T07:49:28.721Z
-   *                           CommitID 3233f44044
-   *
-   * Copyright (c) 2010-2016 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF
-   *               2010 Aaron Spike, https://github.com/acspike
-   *               2012 Willow Systems Corporation, willow-systems.com
-   *               2012 Pablo Hess, https://github.com/pablohess
-   *               2012 Florian Jenett, https://github.com/fjenett
-   *               2013 Warren Weckesser, https://github.com/warrenweckesser
-   *               2013 Youssef Beddad, https://github.com/lifof
-   *               2013 Lee Driscoll, https://github.com/lsdriscoll
-   *               2013 Stefan Slonevskiy, https://github.com/stefslon
-   *               2013 Jeremy Morel, https://github.com/jmorel
-   *               2013 Christoph Hartmann, https://github.com/chris-rock
-   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
-   *               2014 James Makes, https://github.com/dollaruw
-   *               2014 Diego Casorran, https://github.com/diegocr
-   *               2014 Steven Spungin, https://github.com/Flamenco
-   *               2014 Kenneth Glassey, https://github.com/Gavvers
-   *
-   * Licensed under the MIT License
-   *
-   * Contributor(s):
-   *    siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango,
-   *    kim3er, mfo, alnorth, Flamenco
-   */
-
-  /**
-   * Creates new jsPDF document object instance.
-   * @name jsPDF
-   * @class
-   * @param orientation {String/Object} Orientation of the first page. Possible values are "portrait" or "landscape" (or shortcuts "p" (Default), "l") <br />
-   * Can also be an options object.
-   * @param unit {String}  Measurement unit to be used when coordinates are specified.<br />
-   * Possible values are "pt" (points), "mm" (Default), "cm", "in" or "px".
-   * @param format {String/Array} The format of the first page. Can be <ul><li>a0 - a10</li><li>b0 - b10</li><li>c0 - c10</li><li>c0 - c10</li><li>dl</li><li>letter</li><li>government-letter</li><li>legal</li><li>junior-legal</li><li>ledger</li><li>tabloid</li><li>credit-card</li></ul><br />
-   * Default is "a4". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array , e.g. [595.28, 841.89]
-   * @returns {jsPDF}
-   * @description
-   * If the first parameter (orientation) is an object, it will be interpreted as an object of named parameters
-   * ```
-   * {
-   *  orientation: 'p',
-   *  unit: 'mm',
-   *  format: 'a4',
-   *  hotfixes: [] // an array of hotfix strings to enable
-   * }
-   * ```
-   */
-  var jsPDF = function (global) {
-
-    var pdfVersion = '1.3',
-        pageFormats = { // Size in pt of various paper formats
-      'a0': [2383.94, 3370.39],
-      'a1': [1683.78, 2383.94],
-      'a2': [1190.55, 1683.78],
-      'a3': [841.89, 1190.55],
-      'a4': [595.28, 841.89],
-      'a5': [419.53, 595.28],
-      'a6': [297.64, 419.53],
-      'a7': [209.76, 297.64],
-      'a8': [147.40, 209.76],
-      'a9': [104.88, 147.40],
-      'a10': [73.70, 104.88],
-      'b0': [2834.65, 4008.19],
-      'b1': [2004.09, 2834.65],
-      'b2': [1417.32, 2004.09],
-      'b3': [1000.63, 1417.32],
-      'b4': [708.66, 1000.63],
-      'b5': [498.90, 708.66],
-      'b6': [354.33, 498.90],
-      'b7': [249.45, 354.33],
-      'b8': [175.75, 249.45],
-      'b9': [124.72, 175.75],
-      'b10': [87.87, 124.72],
-      'c0': [2599.37, 3676.54],
-      'c1': [1836.85, 2599.37],
-      'c2': [1298.27, 1836.85],
-      'c3': [918.43, 1298.27],
-      'c4': [649.13, 918.43],
-      'c5': [459.21, 649.13],
-      'c6': [323.15, 459.21],
-      'c7': [229.61, 323.15],
-      'c8': [161.57, 229.61],
-      'c9': [113.39, 161.57],
-      'c10': [79.37, 113.39],
-      'dl': [311.81, 623.62],
-      'letter': [612, 792],
-      'government-letter': [576, 756],
-      'legal': [612, 1008],
-      'junior-legal': [576, 360],
-      'ledger': [1224, 792],
-      'tabloid': [792, 1224],
-      'credit-card': [153, 243]
-    };
-
-    /**
-     * jsPDF's Internal PubSub Implementation.
-     * See mrrio.github.io/jsPDF/doc/symbols/PubSub.html
-     * Backward compatible rewritten on 2014 by
-     * Diego Casorran, https://github.com/diegocr
-     *
-     * @class
-     * @name PubSub
-     * @ignore This should not be in the public docs.
-     */
-    function PubSub(context) {
-      var topics = {};
-
-      this.subscribe = function (topic, callback, once) {
-        if (typeof callback !== 'function') {
-          return false;
-        }
-
-        if (!topics.hasOwnProperty(topic)) {
-          topics[topic] = {};
-        }
-
-        var id = Math.random().toString(35);
-        topics[topic][id] = [callback, !!once];
-
-        return id;
-      };
-
-      this.unsubscribe = function (token) {
-        for (var topic in topics) {
-          if (topics[topic][token]) {
-            delete topics[topic][token];
-            return true;
-          }
-        }
-        return false;
-      };
-
-      this.publish = function (topic) {
-        if (topics.hasOwnProperty(topic)) {
-          var args = Array.prototype.slice.call(arguments, 1),
-              idr = [];
-
-          for (var id in topics[topic]) {
-            var sub = topics[topic][id];
-            try {
-              sub[0].apply(context, args);
-            } catch (ex) {
-              if (global.console) {
-                console.error('jsPDF PubSub Error', ex.message, ex);
-              }
-            }
-            if (sub[1]) idr.push(id);
-          }
-          if (idr.length) idr.forEach(this.unsubscribe);
-        }
-      };
-    }
-
-    /**
-     * @constructor
-     * @private
-     */
-    function jsPDF(orientation, unit, format, compressPdf) {
-      var options = {};
-
-      if ((typeof orientation === 'undefined' ? 'undefined' : _typeof(orientation)) === 'object') {
-        options = orientation;
-
-        orientation = options.orientation;
-        unit = options.unit || unit;
-        format = options.format || format;
-        compressPdf = options.compress || options.compressPdf || compressPdf;
-      }
-
-      // Default options
-      unit = unit || 'mm';
-      format = format || 'a4';
-      orientation = ('' + (orientation || 'P')).toLowerCase();
-
-      var format_as_string = ('' + format).toLowerCase(),
-          compress = !!compressPdf && typeof Uint8Array === 'function',
-          textColor = options.textColor || '0 g',
-          drawColor = options.drawColor || '0 G',
-          activeFontSize = options.fontSize || 16,
-          activeCharSpace = options.charSpace || 0,
-          R2L = options.R2L || false,
-          lineHeightProportion = options.lineHeight || 1.15,
-          lineWidth = options.lineWidth || 0.200025,
-          // 2mm
-      fileId = '00000000000000000000000000000000',
-          objectNumber = 2,
-          // 'n' Current object number
-      outToPages = !1,
-          // switches where out() prints. outToPages true = push to pages obj. outToPages false = doc builder content
-      offsets = [],
-          // List of offsets. Activated and reset by buildDocument(). Pupulated by various calls buildDocument makes.
-      fonts = {},
-          // collection of font objects, where key is fontKey - a dynamically created label for a given font.
-      fontmap = {},
-          // mapping structure fontName > fontStyle > font key - performance layer. See addFont()
-      activeFontKey,
-          // will be string representing the KEY of the font as combination of fontName + fontStyle
-      k,
-          // Scale factor
-      tmp,
-          page = 0,
-          currentPage,
-          pages = [],
-          pagesContext = [],
-          // same index as pages and pagedim
-      pagedim = [],
-          content = [],
-          additionalObjects = [],
-          lineCapID = 0,
-          lineJoinID = 0,
-          content_length = 0,
-          pageWidth,
-          pageHeight,
-          pageMode,
-          zoomMode,
-          layoutMode,
-          creationDate,
-          documentProperties = {
-        'title': '',
-        'subject': '',
-        'author': '',
-        'keywords': '',
-        'creator': ''
-      },
-          API = {},
-          events = new PubSub(API),
-          hotfixes = options.hotfixes || [],
-
-
-      /////////////////////
-      // Private functions
-      /////////////////////
-      generateColorString = function generateColorString(options) {
-        var color;
-
-        var ch1 = options.ch1;
-        var ch2 = options.ch2;
-        var ch3 = options.ch3;
-        var ch4 = options.ch4;
-        var precision = options.precision;
-        var letterArray = options.pdfColorType === "draw" ? ['G', 'RG', 'K'] : ['g', 'rg', 'k'];
-
-        if (typeof ch1 === "string" && ch1.charAt(0) !== '#') {
-          var rgbColor = new RGBColor(ch1);
-          if (rgbColor.ok) {
-            ch1 = rgbColor.toHex();
-          }
-        }
-        //convert short rgb to long form
-        if (typeof ch1 === "string" && /^#[0-9A-Fa-f]{3}$/.test(ch1)) {
-          ch1 = '#' + ch1[1] + ch1[1] + ch1[2] + ch1[2] + ch1[3] + ch1[3];
-        }
-
-        if (typeof ch1 === "string" && /^#[0-9A-Fa-f]{6}$/.test(ch1)) {
-          var hex = parseInt(ch1.substr(1), 16);
-          ch1 = hex >> 16 & 255;
-          ch2 = hex >> 8 & 255;
-          ch3 = hex & 255;
-        }
-
-        if (typeof ch2 === "undefined" || typeof ch4 === "undefined" && ch1 === ch2 && ch2 === ch3) {
-          // Gray color space.
-          if (typeof ch1 === "string") {
-            color = ch1 + " " + letterArray[0];
-          } else {
-            switch (options.precision) {
-              case 2:
-                color = f2(ch1 / 255) + " " + letterArray[0];
-                break;
-              case 3:
-              default:
-                color = f3(ch1 / 255) + " " + letterArray[0];
-            }
-          }
-        } else if (typeof ch4 === "undefined" || (typeof ch4 === 'undefined' ? 'undefined' : _typeof(ch4)) === "object") {
-          // assume RGB
-          if (typeof ch1 === "string") {
-            color = [ch1, ch2, ch3, letterArray[1]].join(" ");
-          } else {
-            switch (options.precision) {
-              case 2:
-                color = [f2(ch1 / 255), f2(ch2 / 255), f2(ch3 / 255), letterArray[1]].join(" ");
-                break;
-              default:
-              case 3:
-                color = [f3(ch1 / 255), f3(ch2 / 255), f3(ch3 / 255), letterArray[1]].join(" ");
-            }
-          }
-          // assume RGBA
-          if (ch4 && ch4.a === 0) {
-            //TODO Implement transparency.
-            //WORKAROUND use white for now
-            color = ['255', '255', '255', letterArray[1]].join(" ");
-          }
-        } else {
-          // assume CMYK
-          if (typeof ch1 === 'string') {
-            color = [ch1, ch2, ch3, ch4, letterArray[2]].join(" ");
-          } else {
-            switch (options.precision) {
-              case 2:
-                color = [f2(ch1), f2(ch2), f2(ch3), f2(ch4), letterArray[2]].join(" ");
-                break;
-              case 3:
-              default:
-                color = [f3(ch1), f3(ch2), f3(ch3), f3(ch4), letterArray[2]].join(" ");
-            }
-          }
-        }
-        return color;
-      },
-          convertDateToPDFDate = function convertDateToPDFDate(parmDate) {
-        var padd2 = function padd2(number) {
-          return ('0' + parseInt(number)).slice(-2);
-        };
-        var result = '';
-        var tzoffset = parmDate.getTimezoneOffset(),
-            tzsign = tzoffset < 0 ? '+' : '-',
-            tzhour = Math.floor(Math.abs(tzoffset / 60)),
-            tzmin = Math.abs(tzoffset % 60),
-            timeZoneString = [tzsign, padd2(tzhour), "'", padd2(tzmin), "'"].join('');
-
-        result = ['D:', parmDate.getFullYear(), padd2(parmDate.getMonth() + 1), padd2(parmDate.getDate()), padd2(parmDate.getHours()), padd2(parmDate.getMinutes()), padd2(parmDate.getSeconds()), timeZoneString].join('');
-        return result;
-      },
-          convertPDFDateToDate = function convertPDFDateToDate(parmPDFDate) {
-        var year = parseInt(parmPDFDate.substr(2, 4), 10);
-        var month = parseInt(parmPDFDate.substr(6, 2), 10) - 1;
-        var date = parseInt(parmPDFDate.substr(8, 2), 10);
-        var hour = parseInt(parmPDFDate.substr(10, 2), 10);
-        var minutes = parseInt(parmPDFDate.substr(12, 2), 10);
-        var seconds = parseInt(parmPDFDate.substr(14, 2), 10);
-        var timeZoneHour = parseInt(parmPDFDate.substr(16, 2), 10);
-        var timeZoneMinutes = parseInt(parmPDFDate.substr(20, 2), 10);
-
-        var resultingDate = new Date(year, month, date, hour, minutes, seconds, 0);
-        return resultingDate;
-      },
-          setCreationDate = function setCreationDate(date) {
-        var tmpCreationDateString;
-        var regexPDFCreationDate = /^D:(20[0-2][0-9]|203[0-7]|19[7-9][0-9])(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])(0[0-9]|1[0-9]|2[0-3])(0[0-9]|[1-5][0-9])(0[0-9]|[1-5][0-9])(\+0[0-9]|\+1[0-4]|\-0[0-9]|\-1[0-1])\'(0[0-9]|[1-5][0-9])\'?$/;
-        if ((typeof date === 'undefined' ? 'undefined' : _typeof(date)) === undefined) {
-          date = new Date();
-        }
-
-        if ((typeof date === 'undefined' ? 'undefined' : _typeof(date)) === "object" && Object.prototype.toString.call(date) === "[object Date]") {
-          tmpCreationDateString = convertDateToPDFDate(date);
-        } else if (regexPDFCreationDate.test(date)) {
-          tmpCreationDateString = date;
-        } else {
-          tmpCreationDateString = convertDateToPDFDate(new Date());
-        }
-        creationDate = tmpCreationDateString;
-        return creationDate;
-      },
-          getCreationDate = function getCreationDate(type) {
-        var result = creationDate;
-        if (type === "jsDate") {
-          result = convertPDFDateToDate(creationDate);
-        }
-        return result;
-      },
-          setFileId = function setFileId(value) {
-        value = value || "12345678901234567890123456789012".split('').map(function () {
-          return "ABCDEF0123456789".charAt(Math.floor(Math.random() * 16));
-        }).join('');
-        fileId = value;
-        return fileId;
-      },
-          getFileId = function getFileId() {
-        return fileId;
-      },
-          f2 = function f2(number) {
-        return number.toFixed(2); // Ie, %.2f
-      },
-          f3 = function f3(number) {
-        return number.toFixed(3); // Ie, %.3f
-      },
-          out = function out(string) {
-        string = typeof string === "string" ? string : string.toString();
-        if (outToPages) {
-          /* set by beginPage */
-          pages[currentPage].push(string);
-        } else {
-          // +1 for '\n' that will be used to join 'content'
-          content_length += string.length + 1;
-          content.push(string);
-        }
-      },
-          newObject = function newObject() {
-        // Begin a new object
-        objectNumber++;
-        offsets[objectNumber] = content_length;
-        out(objectNumber + ' 0 obj');
-        return objectNumber;
-      },
-
-      // Does not output the object until after the pages have been output.
-      // Returns an object containing the objectId and content.
-      // All pages have been added so the object ID can be estimated to start right after.
-      // This does not modify the current objectNumber;  It must be updated after the newObjects are output.
-      newAdditionalObject = function newAdditionalObject() {
-        var objId = pages.length * 2 + 1;
-        objId += additionalObjects.length;
-        var obj = {
-          objId: objId,
-          content: ''
-        };
-        additionalObjects.push(obj);
-        return obj;
-      },
-
-      // Does not output the object.  The caller must call newObjectDeferredBegin(oid) before outputing any data
-      newObjectDeferred = function newObjectDeferred() {
-        objectNumber++;
-        offsets[objectNumber] = function () {
-          return content_length;
-        };
-        return objectNumber;
-      },
-          newObjectDeferredBegin = function newObjectDeferredBegin(oid) {
-        offsets[oid] = content_length;
-      },
-          putStream = function putStream(str) {
-        out('stream');
-        out(str);
-        out('endstream');
-      },
-          putPages = function putPages() {
-        var n,
-            p,
-            arr,
-            i,
-            deflater,
-            adler32,
-            adler32cs,
-            wPt,
-            hPt,
-            pageObjectNumbers = [];
-
-        adler32cs = global.adler32cs || jsPDF.API.adler32cs;
-        if (compress && typeof adler32cs === 'undefined') {
-          compress = false;
-        }
-
-        // outToPages = false as set in endDocument(). out() writes to content.
-
-        for (n = 1; n <= page; n++) {
-          pageObjectNumbers.push(newObject());
-          wPt = (pageWidth = pagedim[n].width) * k;
-          hPt = (pageHeight = pagedim[n].height) * k;
-          out('<</Type /Page');
-          out('/Parent 1 0 R');
-          out('/Resources 2 0 R');
-          out('/MediaBox [0 0 ' + f2(wPt) + ' ' + f2(hPt) + ']');
-          // Added for annotation plugin
-          events.publish('putPage', {
-            pageNumber: n,
-            page: pages[n]
-          });
-          out('/Contents ' + (objectNumber + 1) + ' 0 R');
-          out('>>');
-          out('endobj');
-
-          // Page content
-          p = pages[n].join('\n');
-          newObject();
-          if (compress) {
-            arr = [];
-            i = p.length;
-            while (i--) {
-              arr[i] = p.charCodeAt(i);
-            }
-            adler32 = adler32cs.from(p);
-            deflater = new Deflater(6);
-            deflater.append(new Uint8Array(arr));
-            p = deflater.flush();
-            arr = new Uint8Array(p.length + 6);
-            arr.set(new Uint8Array([120, 156])), arr.set(p, 2);
-            arr.set(new Uint8Array([adler32 & 0xFF, adler32 >> 8 & 0xFF, adler32 >> 16 & 0xFF, adler32 >> 24 & 0xFF]), p.length + 2);
-            p = String.fromCharCode.apply(null, arr);
-            out('<</Length ' + p.length + ' /Filter [/FlateDecode]>>');
-          } else {
-            out('<</Length ' + p.length + '>>');
-          }
-          putStream(p);
-          out('endobj');
-        }
-        offsets[1] = content_length;
-        out('1 0 obj');
-        out('<</Type /Pages');
-        var kids = '/Kids [';
-        for (i = 0; i < page; i++) {
-          kids += pageObjectNumbers[i] + ' 0 R ';
-        }
-        out(kids + ']');
-        out('/Count ' + page);
-        out('>>');
-        out('endobj');
-        events.publish('postPutPages');
-      },
-          putFont = function putFont(font) {
-
-        events.publish('putFont', {
-          font: font,
-          out: out,
-          newObject: newObject
-        });
-        if (font.isAlreadyPutted !== true) {
-          font.objectNumber = newObject();
-          out('<<');
-          out('/Type /Font');
-          out('/BaseFont /' + font.postScriptName);
-          out('/Subtype /Type1');
-          if (typeof font.encoding === 'string') {
-            out('/Encoding /' + font.encoding);
-          }
-          out('/FirstChar 32');
-          out('/LastChar 255');
-          out('>>');
-          out('endobj');
-        }
-      },
-          putFonts = function putFonts() {
-        for (var fontKey in fonts) {
-          if (fonts.hasOwnProperty(fontKey)) {
-            putFont(fonts[fontKey]);
-          }
-        }
-      },
-          putXobjectDict = function putXobjectDict() {
-        // Loop through images, or other data objects
-        events.publish('putXobjectDict');
-      },
-          putResourceDictionary = function putResourceDictionary() {
-        out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
-        out('/Font <<');
-
-        // Do this for each font, the '1' bit is the index of the font
-        for (var fontKey in fonts) {
-          if (fonts.hasOwnProperty(fontKey)) {
-            out('/' + fontKey + ' ' + fonts[fontKey].objectNumber + ' 0 R');
-          }
-        }
-        out('>>');
-        out('/XObject <<');
-        putXobjectDict();
-        out('>>');
-      },
-          putResources = function putResources() {
-        putFonts();
-        events.publish('putResources');
-        // Resource dictionary
-        offsets[2] = content_length;
-        out('2 0 obj');
-        out('<<');
-        putResourceDictionary();
-        out('>>');
-        out('endobj');
-        events.publish('postPutResources');
-      },
-          putAdditionalObjects = function putAdditionalObjects() {
-        events.publish('putAdditionalObjects');
-        for (var i = 0; i < additionalObjects.length; i++) {
-          var obj = additionalObjects[i];
-          offsets[obj.objId] = content_length;
-          out(obj.objId + ' 0 obj');
-          out(obj.content);        out('endobj');
-        }
-        objectNumber += additionalObjects.length;
-        events.publish('postPutAdditionalObjects');
-      },
-          addToFontDictionary = function addToFontDictionary(fontKey, fontName, fontStyle) {
-        // this is mapping structure for quick font key lookup.
-        // returns the KEY of the font (ex: "F1") for a given
-        // pair of font name and type (ex: "Arial". "Italic")
-        if (!fontmap.hasOwnProperty(fontName)) {
-          fontmap[fontName] = {};
-        }
-        fontmap[fontName][fontStyle] = fontKey;
-      },
-
-      /**
-       * FontObject describes a particular font as member of an instnace of jsPDF
-       *
-       * It's a collection of properties like 'id' (to be used in PDF stream),
-       * 'fontName' (font's family name), 'fontStyle' (font's style variant label)
-       *
-       * @class
-       * @public
-       * @property id {String} PDF-document-instance-specific label assinged to the font.
-       * @property postScriptName {String} PDF specification full name for the font
-       * @property encoding {Object} Encoding_name-to-Font_metrics_object mapping.
-       * @name FontObject
-       * @ignore This should not be in the public docs.
-       */
-      addFont = function addFont(postScriptName, fontName, fontStyle, encoding) {
-        var fontKey = 'F' + (Object.keys(fonts).length + 1).toString(10),
-
-        // This is FontObject
-        font = fonts[fontKey] = {
-          'id': fontKey,
-          'postScriptName': postScriptName,
-          'fontName': fontName,
-          'fontStyle': fontStyle,
-          'encoding': encoding,
-          'metadata': {}
-        };
-        addToFontDictionary(fontKey, fontName, fontStyle);
-        events.publish('addFont', font);
-
-        return fontKey;
-      },
-          addFonts = function addFonts() {
-
-        var HELVETICA = "helvetica",
-            TIMES = "times",
-            COURIER = "courier",
-            NORMAL = "normal",
-            BOLD = "bold",
-            ITALIC = "italic",
-            BOLD_ITALIC = "bolditalic",
-            ZAPF = "zapfdingbats",
-            SYMBOL = "symbol",
-            standardFonts = [['Helvetica', HELVETICA, NORMAL, 'WinAnsiEncoding'], ['Helvetica-Bold', HELVETICA, BOLD, 'WinAnsiEncoding'], ['Helvetica-Oblique', HELVETICA, ITALIC, 'WinAnsiEncoding'], ['Helvetica-BoldOblique', HELVETICA, BOLD_ITALIC, 'WinAnsiEncoding'], ['Courier', COURIER, NORMAL, 'WinAnsiEncoding'], ['Courier-Bold', COURIER, BOLD, 'WinAnsiEncoding'], ['Courier-Oblique', COURIER, ITALIC, 'WinAnsiEncoding'], ['Courier-BoldOblique', COURIER, BOLD_ITALIC, 'WinAnsiEncoding'], ['Times-Roman', TIMES, NORMAL, 'WinAnsiEncoding'], ['Times-Bold', TIMES, BOLD, 'WinAnsiEncoding'], ['Times-Italic', TIMES, ITALIC, 'WinAnsiEncoding'], ['Times-BoldItalic', TIMES, BOLD_ITALIC, 'WinAnsiEncoding'], ['ZapfDingbats', ZAPF, NORMAL, null], ['Symbol', SYMBOL, NORMAL, null]];
-
-        for (var i = 0, l = standardFonts.length; i < l; i++) {
-          var fontKey = addFont(standardFonts[i][0], standardFonts[i][1], standardFonts[i][2], standardFonts[i][3]);
-
-          // adding aliases for standard fonts, this time matching the capitalization
-          var parts = standardFonts[i][0].split('-');
-          addToFontDictionary(fontKey, parts[0], parts[1] || '');
-        }
-        events.publish('addFonts', {
-          fonts: fonts,
-          dictionary: fontmap
-        });
-      },
-          SAFE = function __safeCall(fn) {
-        fn.foo = function __safeCallWrapper() {
-          try {
-            return fn.apply(this, arguments);
-          } catch (e) {
-            var stack = e.stack || '';
-            if (~stack.indexOf(' at ')) stack = stack.split(" at ")[1];
-            var m = "Error in function " + stack.split("\n")[0].split('<')[0] + ": " + e.message;
-            if (global.console) {
-              global.console.error(m, e);
-              if (global.alert) alert(m);
-            } else {
-              throw new Error(m);
-            }
-          }
-        };
-        fn.foo.bar = fn;
-        return fn.foo;
-      },
-          to8bitStream = function to8bitStream(text, flags) {
-        /**
-         * PDF 1.3 spec:
-         * "For text strings encoded in Unicode, the first two bytes must be 254 followed by
-         * 255, representing the Unicode byte order marker, U+FEFF. (This sequence conflicts
-         * with the PDFDocEncoding character sequence thorn ydieresis, which is unlikely
-         * to be a meaningful beginning of a word or phrase.) The remainder of the
-         * string consists of Unicode character codes, according to the UTF-16 encoding
-         * specified in the Unicode standard, version 2.0. Commonly used Unicode values
-         * are represented as 2 bytes per character, with the high-order byte appearing first
-         * in the string."
-         *
-         * In other words, if there are chars in a string with char code above 255, we
-         * recode the string to UCS2 BE - string doubles in length and BOM is prepended.
-         *
-         * HOWEVER!
-         * Actual *content* (body) text (as opposed to strings used in document properties etc)
-         * does NOT expect BOM. There, it is treated as a literal GID (Glyph ID)
-         *
-         * Because of Adobe's focus on "you subset your fonts!" you are not supposed to have
-         * a font that maps directly Unicode (UCS2 / UTF16BE) code to font GID, but you could
-         * fudge it with "Identity-H" encoding and custom CIDtoGID map that mimics Unicode
-         * code page. There, however, all characters in the stream are treated as GIDs,
-         * including BOM, which is the reason we need to skip BOM in content text (i.e. that
-         * that is tied to a font).
-         *
-         * To signal this "special" PDFEscape / to8bitStream handling mode,
-         * API.text() function sets (unless you overwrite it with manual values
-         * given to API.text(.., flags) )
-         * flags.autoencode = true
-         * flags.noBOM = true
-         *
-         * ===================================================================================
-         * `flags` properties relied upon:
-         *   .sourceEncoding = string with encoding label.
-         *                     "Unicode" by default. = encoding of the incoming text.
-         *                     pass some non-existing encoding name
-         *                     (ex: 'Do not touch my strings! I know what I am doing.')
-         *                     to make encoding code skip the encoding step.
-         *   .outputEncoding = Either valid PDF encoding name
-         *                     (must be supported by jsPDF font metrics, otherwise no encoding)
-         *                     or a JS object, where key = sourceCharCode, value = outputCharCode
-         *                     missing keys will be treated as: sourceCharCode === outputCharCode
-         *   .noBOM
-         *       See comment higher above for explanation for why this is important
-         *   .autoencode
-         *       See comment higher above for explanation for why this is important
-         */
-
-        var i, l, sourceEncoding, encodingBlock, outputEncoding, newtext, isUnicode, ch, bch;
-
-        flags = flags || {};
-        sourceEncoding = flags.sourceEncoding || 'Unicode';
-        outputEncoding = flags.outputEncoding;
-
-        // This 'encoding' section relies on font metrics format
-        // attached to font objects by, among others,
-        // "Willow Systems' standard_font_metrics plugin"
-        // see jspdf.plugin.standard_font_metrics.js for format
-        // of the font.metadata.encoding Object.
-        // It should be something like
-        //   .encoding = {'codePages':['WinANSI....'], 'WinANSI...':{code:code, ...}}
-        //   .widths = {0:width, code:width, ..., 'fof':divisor}
-        //   .kerning = {code:{previous_char_code:shift, ..., 'fof':-divisor},...}
-        if ((flags.autoencode || outputEncoding) && fonts[activeFontKey].metadata && fonts[activeFontKey].metadata[sourceEncoding] && fonts[activeFontKey].metadata[sourceEncoding].encoding) {
-          encodingBlock = fonts[activeFontKey].metadata[sourceEncoding].encoding;
-
-          // each font has default encoding. Some have it clearly defined.
-          if (!outputEncoding && fonts[activeFontKey].encoding) {
-            outputEncoding = fonts[activeFontKey].encoding;
-          }
-
-          // Hmmm, the above did not work? Let's try again, in different place.
-          if (!outputEncoding && encodingBlock.codePages) {
-            outputEncoding = encodingBlock.codePages[0]; // let's say, first one is the default
-          }
-
-          if (typeof outputEncoding === 'string') {
-            outputEncoding = encodingBlock[outputEncoding];
-          }
-          // we want output encoding to be a JS Object, where
-          // key = sourceEncoding's character code and
-          // value = outputEncoding's character code.
-          if (outputEncoding) {
-            isUnicode = false;
-            newtext = [];
-            for (i = 0, l = text.length; i < l; i++) {
-              ch = outputEncoding[text.charCodeAt(i)];
-              if (ch) {
-                newtext.push(String.fromCharCode(ch));
-              } else {
-                newtext.push(text[i]);
-              }
-
-              // since we are looping over chars anyway, might as well
-              // check for residual unicodeness
-              if (newtext[i].charCodeAt(0) >> 8) {
-                /* more than 255 */
-                isUnicode = true;
-              }
-            }
-            text = newtext.join('');
-          }
-        }
-
-        i = text.length;
-        // isUnicode may be set to false above. Hence the triple-equal to undefined
-        while (isUnicode === undefined && i !== 0) {
-          if (text.charCodeAt(i - 1) >> 8) {
-            /* more than 255 */
-            isUnicode = true;
-          }
-          i--;
-        }
-        if (!isUnicode) {
-          return text;
-        }
-
-        newtext = flags.noBOM ? [] : [254, 255];
-        for (i = 0, l = text.length; i < l; i++) {
-          ch = text.charCodeAt(i);
-          bch = ch >> 8; // divide by 256
-          if (bch >> 8) {
-            /* something left after dividing by 256 second time */
-            throw new Error("Character at position " + i + " of string '" + text + "' exceeds 16bits. Cannot be encoded into UCS-2 BE");
-          }
-          newtext.push(bch);
-          newtext.push(ch - (bch << 8));
-        }
-        return String.fromCharCode.apply(undefined, newtext);
-      },
-          pdfEscape = function pdfEscape(text, flags) {
-        /**
-         * Replace '/', '(', and ')' with pdf-safe versions
-         *
-         * Doing to8bitStream does NOT make this PDF display unicode text. For that
-         * we also need to reference a unicode font and embed it - royal pain in the rear.
-         *
-         * There is still a benefit to to8bitStream - PDF simply cannot handle 16bit chars,
-         * which JavaScript Strings are happy to provide. So, while we still cannot display
-         * 2-byte characters property, at least CONDITIONALLY converting (entire string containing)
-         * 16bit chars to (USC-2-BE) 2-bytes per char + BOM streams we ensure that entire PDF
-         * is still parseable.
-         * This will allow immediate support for unicode in document properties strings.
-         */
-        return to8bitStream(text, flags).replace(/\\/g, '\\\\').replace(/\(/g, '\\(').replace(/\)/g, '\\)');
-      },
-          putInfo = function putInfo() {
-        out('/Producer (jsPDF ' + jsPDF.version + ')');
-        for (var key in documentProperties) {
-          if (documentProperties.hasOwnProperty(key) && documentProperties[key]) {
-            out('/' + key.substr(0, 1).toUpperCase() + key.substr(1) + ' (' + pdfEscape(documentProperties[key]) + ')');
-          }
-        }
-        out('/CreationDate (' + creationDate + ')');
-      },
-          putCatalog = function putCatalog() {
-        out('/Type /Catalog');
-        out('/Pages 1 0 R');
-        // PDF13ref Section 7.2.1
-        if (!zoomMode) zoomMode = 'fullwidth';
-        switch (zoomMode) {
-          case 'fullwidth':
-            out('/OpenAction [3 0 R /FitH null]');
-            break;
-          case 'fullheight':
-            out('/OpenAction [3 0 R /FitV null]');
-            break;
-          case 'fullpage':
-            out('/OpenAction [3 0 R /Fit]');
-            break;
-          case 'original':
-            out('/OpenAction [3 0 R /XYZ null null 1]');
-            break;
-          default:
-            var pcn = '' + zoomMode;
-            if (pcn.substr(pcn.length - 1) === '%') zoomMode = parseInt(zoomMode) / 100;
-            if (typeof zoomMode === 'number') {
-              out('/OpenAction [3 0 R /XYZ null null ' + f2(zoomMode) + ']');
-            }
-        }
-        if (!layoutMode) layoutMode = 'continuous';
-        switch (layoutMode) {
-          case 'continuous':
-            out('/PageLayout /OneColumn');
-            break;
-          case 'single':
-            out('/PageLayout /SinglePage');
-            break;
-          case 'two':
-          case 'twoleft':
-            out('/PageLayout /TwoColumnLeft');
-            break;
-          case 'tworight':
-            out('/PageLayout /TwoColumnRight');
-            break;
-        }
-        if (pageMode) {
-          /**
-           * A name object specifying how the document should be displayed when opened:
-           * UseNone      : Neither document outline nor thumbnail images visible -- DEFAULT
-           * UseOutlines  : Document outline visible
-           * UseThumbs    : Thumbnail images visible
-           * FullScreen   : Full-screen mode, with no menu bar, window controls, or any other window visible
-           */
-          out('/PageMode /' + pageMode);
-        }
-        events.publish('putCatalog');
-      },
-          putTrailer = function putTrailer() {
-        out('/Size ' + (objectNumber + 1));
-        out('/Root ' + objectNumber + ' 0 R');
-        out('/Info ' + (objectNumber - 1) + ' 0 R');
-        out("/ID [ <" + fileId + "> <" + fileId + "> ]");
-      },
-          beginPage = function beginPage(width, height) {
-        // Dimensions are stored as user units and converted to points on output
-        var orientation = typeof height === 'string' && height.toLowerCase();
-        if (typeof width === 'string') {
-          var format = width.toLowerCase();
-          if (pageFormats.hasOwnProperty(format)) {
-            width = pageFormats[format][0] / k;
-            height = pageFormats[format][1] / k;
-          }
-        }
-        if (Array.isArray(width)) {
-          height = width[1];
-          width = width[0];
-        }
-        if (orientation) {
-          switch (orientation.substr(0, 1)) {
-            case 'l':
-              if (height > width) orientation = 's';
-              break;
-            case 'p':
-              if (width > height) orientation = 's';
-              break;
-          }
-          if (orientation === 's') {
-            tmp = width;
-            width = height;
-            height = tmp;
-          }
-        }
-        outToPages = true;
-        pages[++page] = [];
-        pagedim[page] = {
-          width: Number(width) || pageWidth,
-          height: Number(height) || pageHeight
-        };
-        pagesContext[page] = {};
-        _setPage(page);
-      },
-          _addPage = function _addPage() {
-        beginPage.apply(this, arguments);
-        // Set line width
-        out(f2(lineWidth * k) + ' w');
-        // Set draw color
-        out(drawColor);
-        // resurrecting non-default line caps, joins
-        if (lineCapID !== 0) {
-          out(lineCapID + ' J');
-        }
-        if (lineJoinID !== 0) {
-          out(lineJoinID + ' j');
-        }
-        events.publish('addPage', {
-          pageNumber: page
-        });
-      },
-          _deletePage = function _deletePage(n) {
-        if (n > 0 && n <= page) {
-          pages.splice(n, 1);
-          pagedim.splice(n, 1);
-          page--;
-          if (currentPage > page) {
-            currentPage = page;
-          }
-          this.setPage(currentPage);
-        }
-      },
-          _setPage = function _setPage(n) {
-        if (n > 0 && n <= page) {
-          currentPage = n;
-          pageWidth = pagedim[n].width;
-          pageHeight = pagedim[n].height;
-        }
-      },
-
-      /**
-       * Returns a document-specific font key - a label assigned to a
-       * font name + font type combination at the time the font was added
-       * to the font inventory.
-       *
-       * Font key is used as label for the desired font for a block of text
-       * to be added to the PDF document stream.
-       * @private
-       * @function
-       * @param fontName {String} can be undefined on "falthy" to indicate "use current"
-       * @param fontStyle {String} can be undefined on "falthy" to indicate "use current"
-       * @returns {String} Font key.
-       */
-      _getFont = function _getFont(fontName, fontStyle, options) {
-        var key = undefined,
-            fontNameLowerCase;
-        options = options || {};
-
-        fontName = fontName !== undefined ? fontName : fonts[activeFontKey].fontName;
-        fontStyle = fontStyle !== undefined ? fontStyle : fonts[activeFontKey].fontStyle;
-        fontNameLowerCase = fontName.toLowerCase();
-
-        if (fontmap[fontNameLowerCase] !== undefined && fontmap[fontNameLowerCase][fontStyle] !== undefined) {
-          key = fontmap[fontNameLowerCase][fontStyle];
-        } else if (fontmap[fontName] !== undefined && fontmap[fontName][fontStyle] !== undefined) {
-          key = fontmap[fontName][fontStyle];
-        } else {
-          if (options.disableWarning === false) {
-            console.warn("Unable to look up font label for font '" + fontName + "', '" + fontStyle + "'. Refer to getFontList() for available fonts.");
-          }
-        }
-
-        if (!key && !options.noFallback) {
-          key = fontmap['times'][fontStyle];
-          if (key == null) {
-            key = fontmap['times']['normal'];
-          }
-        }
-        return key;
-      },
-          buildDocument = function buildDocument() {
-        outToPages = false; // switches out() to content
-
-        objectNumber = 2;
-        content_length = 0;
-        content = [];
-        offsets = [];
-        additionalObjects = [];
-        // Added for AcroForm
-        events.publish('buildDocument');
-
-        // putHeader()
-        out('%PDF-' + pdfVersion);
-        out("%\xBA\xDF\xAC\xE0");
-
-        putPages();
-
-        // Must happen after putPages
-        // Modifies current object Id
-        putAdditionalObjects();
-
-        putResources();
-
-        // Info
-        newObject();
-        out('<<');
-        putInfo();
-        out('>>');
-        out('endobj');
-
-        // Catalog
-        newObject();
-        out('<<');
-        putCatalog();
-        out('>>');
-        out('endobj');
-
-        // Cross-ref
-        var o = content_length,
-            i,
-            p = "0000000000";
-        out('xref');
-        out('0 ' + (objectNumber + 1));
-        out(p + ' 65535 f ');
-        for (i = 1; i <= objectNumber; i++) {
-          var offset = offsets[i];
-          if (typeof offset === 'function') {
-            out((p + offsets[i]()).slice(-10) + ' 00000 n ');
-          } else {
-            out((p + offsets[i]).slice(-10) + ' 00000 n ');
-          }
-        }
-        // Trailer
-        out('trailer');
-        out('<<');
-        putTrailer();
-        out('>>');
-        out('startxref');
-        out('' + o);
-        out('%%EOF');
-
-        outToPages = true;
-
-        return content.join('\n');
-      },
-          getStyle = function getStyle(style) {
-        // see path-painting operators in PDF spec
-        var op = 'S'; // stroke
-        if (style === 'F') {
-          op = 'f'; // fill
-        } else if (style === 'FD' || style === 'DF') {
-          op = 'B'; // both
-        } else if (style === 'f' || style === 'f*' || style === 'B' || style === 'B*') {
-          /*
-           Allow direct use of these PDF path-painting operators:
-           - f    fill using nonzero winding number rule
-           - f*    fill using even-odd rule
-           - B    fill then stroke with fill using non-zero winding number rule
-           - B*    fill then stroke with fill using even-odd rule
-           */
-          op = style;
-        }
-        return op;
-      },
-          getArrayBuffer = function getArrayBuffer() {
-        var data = buildDocument(),
-            len = data.length,
-            ab = new ArrayBuffer(len),
-            u8 = new Uint8Array(ab);
-
-        while (len--) {
-          u8[len] = data.charCodeAt(len);
-        }return ab;
-      },
-          getBlob = function getBlob() {
-        return new Blob([getArrayBuffer()], {
-          type: "application/pdf"
-        });
-      },
-
-      /**
-       * Generates the PDF document.
-       *
-       * If `type` argument is undefined, output is raw body of resulting PDF returned as a string.
-       *
-       * @param {String} type A string identifying one of the possible output types.
-       * @param {Object} options An object providing some additional signalling to PDF generator.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name output
-       */
-      _output = SAFE(function (type, options) {
-        var datauri = ('' + type).substr(0, 6) === 'dataur' ? 'data:application/pdf;base64,' + btoa(buildDocument()) : 0;
-
-        switch (type) {
-          case undefined:
-            return buildDocument();
-          case 'save':
-            if ((typeof navigator === 'undefined' ? 'undefined' : _typeof(navigator)) === "object" && navigator.getUserMedia) {
-              if (global.URL === undefined || global.URL.createObjectURL === undefined) {
-                return API.output('dataurlnewwindow');
-              }
-            }
-            saveAs(getBlob(), options);
-            if (typeof saveAs.unload === 'function') {
-              if (global.setTimeout) {
-                setTimeout(saveAs.unload, 911);
-              }
-            }
-            break;
-          case 'arraybuffer':
-            return getArrayBuffer();
-          case 'blob':
-            return getBlob();
-          case 'bloburi':
-          case 'bloburl':
-            // User is responsible of calling revokeObjectURL
-            return global.URL && global.URL.createObjectURL(getBlob()) || void 0;
-          case 'datauristring':
-          case 'dataurlstring':
-            return datauri;
-          case 'dataurlnewwindow':
-            var nW = global.open(datauri);
-            if (nW || typeof safari === "undefined") return nW;
-          /* pass through */
-          case 'datauri':
-          case 'dataurl':
-            return global.document.location.href = datauri;
-          default:
-            throw new Error('Output type "' + type + '" is not supported.');
-        }
-        // @TODO: Add different output options
-      }),
-
-
-      /**
-       * Used to see if a supplied hotfix was requested when the pdf instance was created.
-       * @param {String} hotfixName - The name of the hotfix to check.
-       * @returns {boolean}
-       */
-      hasHotfix = function hasHotfix(hotfixName) {
-        return Array.isArray(hotfixes) === true && hotfixes.indexOf(hotfixName) > -1;
-      };
-
-      switch (unit) {
-        case 'pt':
-          k = 1;
-          break;
-        case 'mm':
-          k = 72 / 25.4;
-          break;
-        case 'cm':
-          k = 72 / 2.54;
-          break;
-        case 'in':
-          k = 72;
-          break;
-        case 'px':
-          if (hasHotfix('px_scaling') == true) {
-            k = 72 / 96;
-          } else {
-            k = 96 / 72;
-          }
-          break;
-        case 'pc':
-          k = 12;
-          break;
-        case 'em':
-          k = 12;
-          break;
-        case 'ex':
-          k = 6;
-          break;
-        default:
-          throw 'Invalid unit: ' + unit;
-      }
-
-      setCreationDate();
-      setFileId();
-
-      //---------------------------------------
-      // Public API
-
-      /**
-       * Object exposing internal API to plugins
-       * @public
-       */
-      API.internal = {
-        'pdfEscape': pdfEscape,
-        'getStyle': getStyle,
-        /**
-         * Returns {FontObject} describing a particular font.
-         * @public
-         * @function
-         * @param fontName {String} (Optional) Font's family name
-         * @param fontStyle {String} (Optional) Font's style variation name (Example:"Italic")
-         * @returns {FontObject}
-         */
-        'getFont': function getFont() {
-          return fonts[_getFont.apply(API, arguments)];
-        },
-        'getFontSize': function getFontSize() {
-          return activeFontSize;
-        },
-        'getCharSpace': function getCharSpace() {
-          return activeCharSpace;
-        },
-        'getTextColor': function getTextColor() {
-          var colorEncoded = textColor.split(' ');
-          if (colorEncoded.length === 2 && colorEncoded[1] === 'g') {
-            // convert grayscale value to rgb so that it can be converted to hex for consistency
-            var floatVal = parseFloat(colorEncoded[0]);
-            colorEncoded = [floatVal, floatVal, floatVal, 'r'];
-          }
-          var colorAsHex = '#';
-          for (var i = 0; i < 3; i++) {
-            colorAsHex += ('0' + Math.floor(parseFloat(colorEncoded[i]) * 255).toString(16)).slice(-2);
-          }
-          return colorAsHex;
-        },
-        'getLineHeight': function getLineHeight() {
-          return activeFontSize * lineHeightProportion;
-        },
-        'write': function write(string1 /*, string2, string3, etc */) {
-          out(arguments.length === 1 ? string1 : Array.prototype.join.call(arguments, ' '));
-        },
-        'getCoordinateString': function getCoordinateString(value) {
-          return f2(value * k);
-        },
-        'getVerticalCoordinateString': function getVerticalCoordinateString(value) {
-          return f2((pageHeight - value) * k);
-        },
-        'collections': {},
-        'newObject': newObject,
-        'newAdditionalObject': newAdditionalObject,
-        'newObjectDeferred': newObjectDeferred,
-        'newObjectDeferredBegin': newObjectDeferredBegin,
-        'putStream': putStream,
-        'events': events,
-        // ratio that you use in multiplication of a given "size" number to arrive to 'point'
-        // units of measurement.
-        // scaleFactor is set at initialization of the document and calculated against the stated
-        // default measurement units for the document.
-        // If default is "mm", k is the number that will turn number in 'mm' into 'points' number.
-        // through multiplication.
-        'scaleFactor': k,
-        'pageSize': {
-          getWidth: function getWidth() {
-            return pageWidth;
-          },
-          getHeight: function getHeight() {
-            return pageHeight;
-          }
-        },
-        'output': function output(type, options) {
-          return _output(type, options);
-        },
-        'getNumberOfPages': function getNumberOfPages() {
-          return pages.length - 1;
-        },
-        'pages': pages,
-        'out': out,
-        'f2': f2,
-        'getPageInfo': function getPageInfo(pageNumberOneBased) {
-          var objId = (pageNumberOneBased - 1) * 2 + 3;
-          return {
-            objId: objId,
-            pageNumber: pageNumberOneBased,
-            pageContext: pagesContext[pageNumberOneBased]
-          };
-        },
-        'getCurrentPageInfo': function getCurrentPageInfo() {
-          var objId = (currentPage - 1) * 2 + 3;
-          return {
-            objId: objId,
-            pageNumber: currentPage,
-            pageContext: pagesContext[currentPage]
-          };
-        },
-        'getPDFVersion': function getPDFVersion() {
-          return pdfVersion;
-        },
-        'hasHotfix': hasHotfix //Expose the hasHotfix check so plugins can also check them.
-      };
-
-      /**
-       * Adds (and transfers the focus to) new page to the PDF document.
-       * @param format {String/Array} The format of the new page. Can be <ul><li>a0 - a10</li><li>b0 - b10</li><li>c0 - c10</li><li>c0 - c10</li><li>dl</li><li>letter</li><li>government-letter</li><li>legal</li><li>junior-legal</li><li>ledger</li><li>tabloid</li><li>credit-card</li></ul><br />
-       * Default is "a4". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array , e.g. [595.28, 841.89]
-       * @param orientation {String} Orientation of the new page. Possible values are "portrait" or "landscape" (or shortcuts "p" (Default), "l") 
-       * @function
-       * @returns {jsPDF}
-       *
-       * @methodOf jsPDF#
-       * @name addPage
-       */
-      API.addPage = function () {
-        _addPage.apply(this, arguments);
-        return this;
-      };
-      /**
-       * Adds (and transfers the focus to) new page to the PDF document.
-       * @function
-       * @returns {jsPDF}
-       *
-       * @methodOf jsPDF#
-       * @name setPage
-       * @param {Number} page Switch the active page to the page number specified
-       * @example
-       * doc = jsPDF()
-       * doc.addPage()
-       * doc.addPage()
-       * doc.text('I am on page 3', 10, 10)
-       * doc.setPage(1)
-       * doc.text('I am on page 1', 10, 10)
-       */
-      API.setPage = function () {
-        _setPage.apply(this, arguments);
-        return this;
-      };
-      API.insertPage = function (beforePage) {
-        this.addPage();
-        this.movePage(currentPage, beforePage);
-        return this;
-      };
-      API.movePage = function (targetPage, beforePage) {
-        if (targetPage > beforePage) {
-          var tmpPages = pages[targetPage];
-          var tmpPagedim = pagedim[targetPage];
-          var tmpPagesContext = pagesContext[targetPage];
-          for (var i = targetPage; i > beforePage; i--) {
-            pages[i] = pages[i - 1];
-            pagedim[i] = pagedim[i - 1];
-            pagesContext[i] = pagesContext[i - 1];
-          }
-          pages[beforePage] = tmpPages;
-          pagedim[beforePage] = tmpPagedim;
-          pagesContext[beforePage] = tmpPagesContext;
-          this.setPage(beforePage);
-        } else if (targetPage < beforePage) {
-          var tmpPages = pages[targetPage];
-          var tmpPagedim = pagedim[targetPage];
-          var tmpPagesContext = pagesContext[targetPage];
-          for (var i = targetPage; i < beforePage; i++) {
-            pages[i] = pages[i + 1];
-            pagedim[i] = pagedim[i + 1];
-            pagesContext[i] = pagesContext[i + 1];
-          }
-          pages[beforePage] = tmpPages;
-          pagedim[beforePage] = tmpPagedim;
-          pagesContext[beforePage] = tmpPagesContext;
-          this.setPage(beforePage);
-        }
-        return this;
-      };
-
-      API.deletePage = function () {
-        _deletePage.apply(this, arguments);
-        return this;
-      };
-
-      API.setCreationDate = function (date) {
-        setCreationDate(date);
-        return this;
-      };
-
-      API.getCreationDate = function (type) {
-        return getCreationDate(type);
-      };
-
-      API.setFileId = function (value) {
-        setFileId(value);
-        return this;
-      };
-
-      API.getFileId = function () {
-        return getFileId();
-      };
-
-      /**
-       * Set the display mode options of the page like zoom and layout.
-       *
-       * @param {integer|String} zoom   You can pass an integer or percentage as
-       * a string. 2 will scale the document up 2x, '200%' will scale up by the
-       * same amount. You can also set it to 'fullwidth', 'fullheight',
-       * 'fullpage', or 'original'.
-       *
-       * Only certain PDF readers support this, such as Adobe Acrobat
-       *
-       * @param {String} layout Layout mode can be: 'continuous' - this is the
-       * default continuous scroll. 'single' - the single page mode only shows one
-       * page at a time. 'twoleft' - two column left mode, first page starts on
-       * the left, and 'tworight' - pages are laid out in two columns, with the
-       * first page on the right. This would be used for books.
-       * @param {String} pmode 'UseOutlines' - it shows the
-       * outline of the document on the left. 'UseThumbs' - shows thumbnails along
-       * the left. 'FullScreen' - prompts the user to enter fullscreen mode.
-       *
-       * @function
-       * @returns {jsPDF}
-       * @name setDisplayMode
-       */
-      API.setDisplayMode = function (zoom, layout, pmode) {
-        zoomMode = zoom;
-        layoutMode = layout;
-        pageMode = pmode;
-
-        var validPageModes = [undefined, null, 'UseNone', 'UseOutlines', 'UseThumbs', 'FullScreen'];
-        if (validPageModes.indexOf(pmode) == -1) {
-          throw new Error('Page mode must be one of UseNone, UseOutlines, UseThumbs, or FullScreen. "' + pmode + '" is not recognized.');
-        }
-        return this;
-      };
-
-      /**
-       * Adds text to page. Supports adding multiline text when 'text' argument is an Array of Strings.
-       *
-       * @function
-       * @param {String|Array} text String or array of strings to be added to the page. Each line is shifted one line down per font, spacing settings declared before this call.
-       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Object} options Collection of settings signalling how the text must be encoded. Defaults are sane. If you think you want to pass some flags, you likely can read the source.
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name text
-       */
-      API.text = function (text, x, y, options) {
-        /**
-         * Inserts something like this into PDF
-         *   BT
-         *    /F1 16 Tf  % Font name + size
-         *    16 TL % How many units down for next line in multiline text
-         *    0 g % color
-         *    28.35 813.54 Td % position
-         *    (line one) Tj
-         *    T* (line two) Tj
-         *    T* (line three) Tj
-         *   ET
-         */
-
-        var xtra = '';
-        var isHex = false;
-        var lineHeight = lineHeightProportion;
-
-        var scope = this;
-
-        function ESC(s) {
-          s = s.split("\t").join(Array(options.TabLen || 9).join(" "));
-          return pdfEscape(s, flags);
-        }
-
-        function transformTextToSpecialArray(text) {
-          //we don't want to destroy original text array, so cloning it
-          var sa = text.concat();
-          var da = [];
-          var len = sa.length;
-          var curDa;
-          //we do array.join('text that must not be PDFescaped")
-          //thus, pdfEscape each component separately
-          while (len--) {
-            curDa = sa.shift();
-            if (typeof curDa === "string") {
-              da.push(curDa);
-            } else {
-              if (Object.prototype.toString.call(text) === '[object Array]' && curDa.length === 1) {
-                da.push(curDa[0]);
-              } else {
-                da.push([curDa[0], curDa[1], curDa[2]]);
-              }
-            }
-          }
-          return da;
-        }
-
-        function processTextByFunction(text, processingFunction) {
-          var result;
-          if (typeof text === 'string') {
-            result = processingFunction(text)[0];
-          } else if (Object.prototype.toString.call(text) === '[object Array]') {
-            //we don't want to destroy original text array, so cloning it
-            var sa = text.concat();
-            var da = [];
-            var len = sa.length;
-            var curDa;
-            var tmpResult;
-            //we do array.join('text that must not be PDFescaped")
-            //thus, pdfEscape each component separately
-            while (len--) {
-              curDa = sa.shift();
-              if (typeof curDa === "string") {
-                da.push(processingFunction(curDa)[0]);
-              } else if (Object.prototype.toString.call(curDa) === '[object Array]' && curDa[0] === "string") {
-                tmpResult = processingFunction(curDa[0], curDa[1], curDa[2]);
-                da.push([tmpResult[0], tmpResult[1], tmpResult[2]]);
-              }
-            }
-            result = da;
-          }
-          return result;
-        }
-
-        //backwardsCompatibility
-        var tmp;
-
-        // Pre-August-2012 the order of arguments was function(x, y, text, flags)
-        // in effort to make all calls have similar signature like
-        //   function(data, coordinates... , miscellaneous)
-        // this method had its args flipped.
-        // code below allows backward compatibility with old arg order.
-        if (typeof text === 'number') {
-          tmp = y;
-          y = x;
-          x = text;
-          text = tmp;
-        }
-
-        var flags = arguments[3];
-        var angle = arguments[4];
-        var align = arguments[5];
-
-        if ((typeof flags === 'undefined' ? 'undefined' : _typeof(flags)) !== "object" || flags === null) {
-          if (typeof angle === 'string') {
-            align = angle;
-            angle = null;
-          }
-          if (typeof flags === 'string') {
-            align = flags;
-            flags = null;
-          }
-          if (typeof flags === 'number') {
-            angle = flags;
-            flags = null;
-          }
-          options = { flags: flags, angle: angle, align: align };
-        }
-
-        //Check if text is of type String
-        var textIsOfTypeString = false;
-        var tmpTextIsOfTypeString = true;
-
-        if (typeof text === 'string') {
-          textIsOfTypeString = true;
-        } else if (Object.prototype.toString.call(text) === '[object Array]') {
-          //we don't want to destroy original text array, so cloning it
-          var sa = text.concat();
-          var da = [];
-          var len = sa.length;
-          var curDa;
-          //we do array.join('text that must not be PDFescaped")
-          //thus, pdfEscape each component separately
-          while (len--) {
-            curDa = sa.shift();
-            if (typeof curDa !== "string" || Object.prototype.toString.call(curDa) === '[object Array]' && typeof curDa[0] !== "string") {
-              tmpTextIsOfTypeString = false;
-            }
-          }
-          textIsOfTypeString = tmpTextIsOfTypeString;
-        }
-        if (textIsOfTypeString === false) {
-          throw new Error('Type of text must be string or Array. "' + text + '" is not recognized.');
-        }
-
-        //Escaping 
-        var activeFontEncoding = fonts[activeFontKey].encoding;
-
-        if (activeFontEncoding === "WinAnsiEncoding" || activeFontEncoding === "StandardEncoding") {
-          text = processTextByFunction(text, function (text, posX, posY) {
-            return [ESC(text), posX, posY];
-          });
-        }
-        //If there are any newlines in text, we assume
-        //the user wanted to print multiple lines, so break the
-        //text up into an array. If the text is already an array,
-        //we assume the user knows what they are doing.
-        //Convert text into an array anyway to simplify
-        //later code.
-
-        if (typeof text === 'string') {
-          if (text.match(/[\r?\n]/)) {
-            text = text.split(/\r\n|\r|\n/g);
-          } else {
-            text = [text];
-          }
-        }
-
-        //multiline
-        var maxWidth = options.maxWidth || 0;
-
-        if (maxWidth > 0) {
-          if (typeof text === 'string') {
-            text = scope.splitTextToSize(text, maxWidth);
-          } else if (Object.prototype.toString.call(text) === '[object Array]') {
-            text = scope.splitTextToSize(text.join(" "), maxWidth);
-          }
-        }
-
-        //creating Payload-Object to make text byRef
-        var payload = {
-          text: text,
-          x: x,
-          y: y,
-          options: options,
-          mutex: {
-            pdfEscape: pdfEscape,
-            activeFontKey: activeFontKey,
-            fonts: fonts,
-            activeFontSize: activeFontSize
-          }
-        };
-        events.publish('preProcessText', payload);
-
-        text = payload.text;
-        options = payload.options;
-        //angle
-
-        var angle = options.angle;
-        var k = scope.internal.scaleFactor;
-        var curY = (scope.internal.pageSize.getHeight() - y) * k;
-        var transformationMatrix = [];
-
-        if (angle) {
-          angle *= Math.PI / 180;
-          var c = Math.cos(angle),
-              s = Math.sin(angle);
-          var f2 = function f2(number) {
-            return number.toFixed(2);
-          };
-          transformationMatrix = [f2(c), f2(s), f2(s * -1), f2(c)];
-        }
-
-        //charSpace
-
-        var charSpace = options.charSpace;
-
-        if (charSpace !== undefined) {
-          xtra += charSpace + " Tc\n";
-        }
-
-        //lang
-
-        var lang = options.lang;
-        var tmpRenderingMode = -1;
-        var parmRenderingMode = options.renderingMode || options.stroke;
-        var pageContext = scope.internal.getCurrentPageInfo().pageContext;
-
-        switch (parmRenderingMode) {
-          case 0:
-          case false:
-          case 'fill':
-            tmpRenderingMode = 0;
-            break;
-          case 1:
-          case true:
-          case 'stroke':
-            tmpRenderingMode = 1;
-            break;
-          case 2:
-          case 'fillThenStroke':
-            tmpRenderingMode = 2;
-            break;
-          case 3:
-          case 'invisible':
-            tmpRenderingMode = 3;
-            break;
-          case 4:
-          case 'fillAndAddForClipping':
-            tmpRenderingMode = 4;
-            break;
-          case 5:
-          case 'strokeAndAddPathForClipping':
-            tmpRenderingMode = 5;
-            break;
-          case 6:
-          case 'fillThenStrokeAndAddToPathForClipping':
-            tmpRenderingMode = 6;
-            break;
-          case 7:
-          case 'addToPathForClipping':
-            tmpRenderingMode = 7;
-            break;
-        }
-
-        var usedRenderingMode = pageContext.usedRenderingMode || -1;
-
-        //if the coder wrote it explicitly to use a specific 
-        //renderingMode, then use it
-        if (tmpRenderingMode !== -1) {
-          xtra += tmpRenderingMode + " Tr\n";
-          //otherwise check if we used the rendering Mode already
-          //if so then set the rendering Mode...
-        } else if (usedRenderingMode !== -1) {
-          xtra += "0 Tr\n";
-        }
-
-        if (tmpRenderingMode !== -1) {
-          pageContext.usedRenderingMode = tmpRenderingMode;
-        }
-
-        //align
-
-        var align = options.align || 'left';
-        var leading = activeFontSize * lineHeight;
-        var pageHeight = scope.internal.pageSize.getHeight();
-        var pageWidth = scope.internal.pageSize.getWidth();
-        var k = scope.internal.scaleFactor;
-        var activeFont = fonts[activeFontKey];
-        var charSpace = options.charSpace || activeCharSpace;
-        var maxWidth = options.maxWidth || 0;
-
-        var lineWidths;
-        var flags = {};
-        var wordSpacingPerLine = [];
-
-        if (Object.prototype.toString.call(text) === '[object Array]') {
-          var da = transformTextToSpecialArray(text);
-          var newY;
-          var maxLineLength;
-          var lineWidths;
-          if (align !== "left") {
-            lineWidths = da.map(function (v) {
-              return scope.getStringUnitWidth(v, { font: activeFont, charSpace: charSpace, fontSize: activeFontSize }) * activeFontSize / k;
-            });
-          }
-          var maxLineLength = Math.max.apply(Math, lineWidths);
-          //The first line uses the "main" Td setting,
-          //and the subsequent lines are offset by the
-          //previous line's x coordinate.
-          var prevWidth = 0;
-          var delta;
-          var newX;
-          if (align === "right") {
-            x -= lineWidths[0];
-            text = [];
-            for (var i = 0, len = da.length; i < len; i++) {
-              delta = maxLineLength - lineWidths[i];
-              if (i === 0) {
-                newX = x * k;
-                newY = (pageHeight - y) * k;
-              } else {
-                newX = (prevWidth - lineWidths[i]) * k;
-                newY = -leading;
-              }
-              text.push([da[i], newX, newY]);
-              prevWidth = lineWidths[i];
-            }
-          } else if (align === "center") {
-            x -= lineWidths[0] / 2;
-            text = [];
-            for (var i = 0, len = da.length; i < len; i++) {
-              delta = (maxLineLength - lineWidths[i]) / 2;
-              if (i === 0) {
-                newX = x * k;
-                newY = (pageHeight - y) * k;
-              } else {
-                newX = (prevWidth - lineWidths[i]) / 2 * k;
-                newY = -leading;
-              }
-              text.push([da[i], newX, newY]);
-              prevWidth = lineWidths[i];
-            }
-          } else if (align === "left") {
-            text = [];
-            for (var i = 0, len = da.length; i < len; i++) {
-              newY = i === 0 ? (pageHeight - y) * k : -leading;
-              newX = i === 0 ? x * k : 0;
-              //text.push([da[i], newX, newY]);
-              text.push(da[i]);
-            }
-          } else if (align === "justify") {
-            text = [];
-            var maxWidth = maxWidth !== 0 ? maxWidth : pageWidth;
-
-            for (var i = 0, len = da.length; i < len; i++) {
-              newY = i === 0 ? (pageHeight - y) * k : -leading;
-              newX = i === 0 ? x * k : 0;
-              if (i < len - 1) {
-                wordSpacingPerLine.push(((maxWidth - lineWidths[i]) / (da[i].split(" ").length - 1) * k).toFixed(2));
-              }
-              text.push([da[i], newX, newY]);
-            }
-          } else {
-            throw new Error('Unrecognized alignment option, use "left", "center", "right" or "justify".');
-          }
-        }
-
-        //R2L
-        var doReversing = typeof options.R2L === "boolean" ? options.R2L : R2L;
-        if (doReversing === true) {
-          text = processTextByFunction(text, function (text, posX, posY) {
-            return [text.split("").reverse().join(""), posX, posY];
-          });
-        }
-
-        //creating Payload-Object to make text byRef
-        var payload = {
-          text: text,
-          x: x,
-          y: y,
-          options: options,
-          mutex: {
-            pdfEscape: pdfEscape,
-            activeFontKey: activeFontKey,
-            fonts: fonts,
-            activeFontSize: activeFontSize
-          }
-        };
-        events.publish('postProcessText', payload);
-
-        text = payload.text;
-        isHex = payload.mutex.isHex;
-
-        var da = transformTextToSpecialArray(text);
-
-        text = [];
-        var variant = 0;
-        var len = da.length;
-        var posX;
-        var posY;
-        var content;
-        var wordSpacing = '';
-
-        for (var i = 0; i < len; i++) {
-
-          wordSpacing = '';
-          if (Object.prototype.toString.call(da[i]) !== '[object Array]') {
-            posX = parseFloat(x * k).toFixed(2);
-            posY = parseFloat((pageHeight - y) * k).toFixed(2);
-            content = (isHex ? "<" : "(") + da[i] + (isHex ? ">" : ")");
-          } else if (Object.prototype.toString.call(da[i]) === '[object Array]') {
-            posX = parseFloat(da[i][1]).toFixed(2);
-            posY = parseFloat(da[i][2]).toFixed(2);
-            content = (isHex ? "<" : "(") + da[i][0] + (isHex ? ">" : ")");
-            variant = 1;
-          }
-          if (wordSpacingPerLine !== undefined && wordSpacingPerLine[i] !== undefined) {
-            wordSpacing = wordSpacingPerLine[i] + " Tw\n";
-          }
-          //TODO: Kind of a hack?
-          if (transformationMatrix.length !== 0 && i === 0) {
-            text.push(wordSpacing + transformationMatrix.join(" ") + " " + posX + " " + posY + " Tm\n" + content);
-          } else if (variant === 1 || variant === 0 && i === 0) {
-            text.push(wordSpacing + posX + " " + posY + " Td\n" + content);
-          } else {
-            text.push(wordSpacing + content);
-          }
-        }
-        if (variant === 0) {
-          text = text.join(" Tj\nT* ");
-        } else {
-          text = text.join(" Tj\n");
-        }
-
-        text += " Tj\n";
-
-        var result = 'BT\n/' + activeFontKey + ' ' + activeFontSize + ' Tf\n' + // font face, style, size
-        (activeFontSize * lineHeight).toFixed(2) + ' TL\n' + // line spacing
-        textColor + '\n';
-        result += xtra;
-        result += text;
-        result += "ET";
-
-        out(result);
-        return scope;
-      };
-
-      /**
-       * Letter spacing method to print text with gaps
-       *
-       * @function
-       * @param {String|Array} text String to be added to the page.
-       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} spacing Spacing (in units declared at inception)
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name lstext
-       * @deprecated We'll be removing this function. It doesn't take character width into account.
-       */
-      API.lstext = function (text, x, y, spacing) {
-        console.warn('jsPDF.lstext is deprecated');
-        for (var i = 0, len = text.length; i < len; i++, x += spacing) {
-          this.text(text[i], x, y);
-        }return this;
-      };
-
-      API.line = function (x1, y1, x2, y2) {
-        return this.lines([[x2 - x1, y2 - y1]], x1, y1);
-      };
-
-      API.clip = function () {
-        // By patrick-roberts, github.com/MrRio/jsPDF/issues/328
-        // Call .clip() after calling .rect() with a style argument of null
-        out('W'); // clip
-        out('S'); // stroke path; necessary for clip to work
-      };
-
-      /**
-       * This fixes the previous function clip(). Perhaps the 'stroke path' hack was due to the missing 'n' instruction?
-       * We introduce the fixed version so as to not break API.
-       * @param fillRule
-       */
-      API.clip_fixed = function (fillRule) {
-        // Call .clip() after calling drawing ops with a style argument of null
-        // W is the PDF clipping op
-        if ('evenodd' === fillRule) {
-          out('W*');
-        } else {
-          out('W');
-        }
-        // End the path object without filling or stroking it.
-        // This operator is a path-painting no-op, used primarily for the side effect of changing the current clipping path
-        // (see Section 4.4.3, “Clipping Path Operators”)
-        out('n');
-      };
-
-      /**
-       * Adds series of curves (straight lines or cubic bezier curves) to canvas, starting at `x`, `y` coordinates.
-       * All data points in `lines` are relative to last line origin.
-       * `x`, `y` become x1,y1 for first line / curve in the set.
-       * For lines you only need to specify [x2, y2] - (ending point) vector against x1, y1 starting point.
-       * For bezier curves you need to specify [x2,y2,x3,y3,x4,y4] - vectors to control points 1, 2, ending point. All vectors are against the start of the curve - x1,y1.
-       *
-       * @example .lines([[2,2],[-2,2],[1,1,2,2,3,3],[2,1]], 212,110, 10) // line, line, bezier curve, line
-       * @param {Array} lines Array of *vector* shifts as pairs (lines) or sextets (cubic bezier curves).
-       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} scale (Defaults to [1.0,1.0]) x,y Scaling factor for all vectors. Elements can be any floating number Sub-one makes drawing smaller. Over-one grows the drawing. Negative flips the direction.
-       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
-       * @param {Boolean} closed If true, the path is closed with a straight line from the end of the last curve to the starting point.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name lines
-       */
-      API.lines = function (lines, x, y, scale, style, closed) {
-        var scalex, scaley, i, l, leg, x2, y2, x3, y3, x4, y4;
-
-        // Pre-August-2012 the order of arguments was function(x, y, lines, scale, style)
-        // in effort to make all calls have similar signature like
-        //   function(content, coordinateX, coordinateY , miscellaneous)
-        // this method had its args flipped.
-        // code below allows backward compatibility with old arg order.
-        if (typeof lines === 'number') {
-          tmp = y;
-          y = x;
-          x = lines;
-          lines = tmp;
-        }
-
-        scale = scale || [1, 1];
-
-        // starting point
-        out(f3(x * k) + ' ' + f3((pageHeight - y) * k) + ' m ');
-
-        scalex = scale[0];
-        scaley = scale[1];
-        l = lines.length;
-        //, x2, y2 // bezier only. In page default measurement "units", *after* scaling
-        //, x3, y3 // bezier only. In page default measurement "units", *after* scaling
-        // ending point for all, lines and bezier. . In page default measurement "units", *after* scaling
-        x4 = x; // last / ending point = starting point for first item.
-        y4 = y; // last / ending point = starting point for first item.
-
-        for (i = 0; i < l; i++) {
-          leg = lines[i];
-          if (leg.length === 2) {
-            // simple line
-            x4 = leg[0] * scalex + x4; // here last x4 was prior ending point
-            y4 = leg[1] * scaley + y4; // here last y4 was prior ending point
-            out(f3(x4 * k) + ' ' + f3((pageHeight - y4) * k) + ' l');
-          } else {
-            // bezier curve
-            x2 = leg[0] * scalex + x4; // here last x4 is prior ending point
-            y2 = leg[1] * scaley + y4; // here last y4 is prior ending point
-            x3 = leg[2] * scalex + x4; // here last x4 is prior ending point
-            y3 = leg[3] * scaley + y4; // here last y4 is prior ending point
-            x4 = leg[4] * scalex + x4; // here last x4 was prior ending point
-            y4 = leg[5] * scaley + y4; // here last y4 was prior ending point
-            out(f3(x2 * k) + ' ' + f3((pageHeight - y2) * k) + ' ' + f3(x3 * k) + ' ' + f3((pageHeight - y3) * k) + ' ' + f3(x4 * k) + ' ' + f3((pageHeight - y4) * k) + ' c');
-          }
-        }
-
-        if (closed) {
-          out(' h');
-        }
-
-        // stroking / filling / both the path
-        if (style !== null) {
-          out(getStyle(style));
-        }
-        return this;
-      };
-
-      /**
-       * Adds a rectangle to PDF
-       *
-       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} w Width (in units declared at inception of PDF document)
-       * @param {Number} h Height (in units declared at inception of PDF document)
-       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name rect
-       */
-      API.rect = function (x, y, w, h, style) {
-        var op = getStyle(style);
-        out([f2(x * k), f2((pageHeight - y) * k), f2(w * k), f2(-h * k), 're'].join(' '));
-
-        if (style !== null) {
-          out(getStyle(style));
-        }
-
-        return this;
-      };
-
-      /**
-       * Adds a triangle to PDF
-       *
-       * @param {Number} x1 Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y1 Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} x2 Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y2 Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} x3 Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y3 Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name triangle
-       */
-      API.triangle = function (x1, y1, x2, y2, x3, y3, style) {
-        this.lines([[x2 - x1, y2 - y1], // vector to point 2
-        [x3 - x2, y3 - y2], // vector to point 3
-        [x1 - x3, y1 - y3] // closing vector back to point 1
-        ], x1, y1, // start of path
-        [1, 1], style, true);
-        return this;
-      };
-
-      /**
-       * Adds a rectangle with rounded corners to PDF
-       *
-       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} w Width (in units declared at inception of PDF document)
-       * @param {Number} h Height (in units declared at inception of PDF document)
-       * @param {Number} rx Radius along x axis (in units declared at inception of PDF document)
-       * @param {Number} rx Radius along y axis (in units declared at inception of PDF document)
-       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name roundedRect
-       */
-      API.roundedRect = function (x, y, w, h, rx, ry, style) {
-        var MyArc = 4 / 3 * (Math.SQRT2 - 1);
-        this.lines([[w - 2 * rx, 0], [rx * MyArc, 0, rx, ry - ry * MyArc, rx, ry], [0, h - 2 * ry], [0, ry * MyArc, -(rx * MyArc), ry, -rx, ry], [-w + 2 * rx, 0], [-(rx * MyArc), 0, -rx, -(ry * MyArc), -rx, -ry], [0, -h + 2 * ry], [0, -(ry * MyArc), rx * MyArc, -ry, rx, -ry]], x + rx, y, // start of path
-        [1, 1], style);
-        return this;
-      };
-
-      /**
-       * Adds an ellipse to PDF
-       *
-       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} rx Radius along x axis (in units declared at inception of PDF document)
-       * @param {Number} rx Radius along y axis (in units declared at inception of PDF document)
-       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name ellipse
-       */
-      API.ellipse = function (x, y, rx, ry, style) {
-        var lx = 4 / 3 * (Math.SQRT2 - 1) * rx,
-            ly = 4 / 3 * (Math.SQRT2 - 1) * ry;
-
-        out([f2((x + rx) * k), f2((pageHeight - y) * k), 'm', f2((x + rx) * k), f2((pageHeight - (y - ly)) * k), f2((x + lx) * k), f2((pageHeight - (y - ry)) * k), f2(x * k), f2((pageHeight - (y - ry)) * k), 'c'].join(' '));
-        out([f2((x - lx) * k), f2((pageHeight - (y - ry)) * k), f2((x - rx) * k), f2((pageHeight - (y - ly)) * k), f2((x - rx) * k), f2((pageHeight - y) * k), 'c'].join(' '));
-        out([f2((x - rx) * k), f2((pageHeight - (y + ly)) * k), f2((x - lx) * k), f2((pageHeight - (y + ry)) * k), f2(x * k), f2((pageHeight - (y + ry)) * k), 'c'].join(' '));
-        out([f2((x + lx) * k), f2((pageHeight - (y + ry)) * k), f2((x + rx) * k), f2((pageHeight - (y + ly)) * k), f2((x + rx) * k), f2((pageHeight - y) * k), 'c'].join(' '));
-
-        if (style !== null) {
-          out(getStyle(style));
-        }
-
-        return this;
-      };
-
-      /**
-       * Adds an circle to PDF
-       *
-       * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-       * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-       * @param {Number} r Radius (in units declared at inception of PDF document)
-       * @param {String} style A string specifying the painting style or null.  Valid styles include: 'S' [default] - stroke, 'F' - fill,  and 'DF' (or 'FD') -  fill then stroke. A null value postpones setting the style so that a shape may be composed using multiple method calls. The last drawing method call used to define the shape should not have a null style argument.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name circle
-       */
-      API.circle = function (x, y, r, style) {
-        return this.ellipse(x, y, r, r, style);
-      };
-
-      /**
-       * Adds a properties to the PDF document
-       *
-       * @param {Object} A property_name-to-property_value object structure.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setProperties
-       */
-      API.setProperties = function (properties) {
-        // copying only those properties we can render.
-        for (var property in documentProperties) {
-          if (documentProperties.hasOwnProperty(property) && properties[property]) {
-            documentProperties[property] = properties[property];
-          }
-        }
-        return this;
-      };
-
-      /**
-       * Sets font size for upcoming text elements.
-       *
-       * @param {Number} size Font size in points.
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setFontSize
-       */
-      API.setFontSize = function (size) {
-        activeFontSize = size;
-        return this;
-      };
-
-      /**
-       * Sets text font face, variant for upcoming text elements.
-       * See output of jsPDF.getFontList() for possible font names, styles.
-       *
-       * @param {String} fontName Font name or family. Example: "times"
-       * @param {String} fontStyle Font style or variant. Example: "italic"
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setFont
-       */
-      API.setFont = function (fontName, fontStyle) {
-        activeFontKey = _getFont(fontName, fontStyle);
-        // if font is not found, the above line blows up and we never go further
-        return this;
-      };
-
-      /**
-       * Switches font style or variant for upcoming text elements,
-       * while keeping the font face or family same.
-       * See output of jsPDF.getFontList() for possible font names, styles.
-       *
-       * @param {String} style Font style or variant. Example: "italic"
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setFontStyle
-       */
-      API.setFontStyle = API.setFontType = function (style) {
-        activeFontKey = _getFont(undefined, style);
-        // if font is not found, the above line blows up and we never go further
-        return this;
-      };
-
-      /**
-       * Returns an object - a tree of fontName to fontStyle relationships available to
-       * active PDF document.
-       *
-       * @public
-       * @function
-       * @returns {Object} Like {'times':['normal', 'italic', ... ], 'arial':['normal', 'bold', ... ], ... }
-       * @methodOf jsPDF#
-       * @name getFontList
-       */
-      API.getFontList = function () {
-        // TODO: iterate over fonts array or return copy of fontmap instead in case more are ever added.
-        var list = {},
-            fontName,
-            fontStyle,
-            tmp;
-
-        for (fontName in fontmap) {
-          if (fontmap.hasOwnProperty(fontName)) {
-            list[fontName] = tmp = [];
-            for (fontStyle in fontmap[fontName]) {
-              if (fontmap[fontName].hasOwnProperty(fontStyle)) {
-                tmp.push(fontStyle);
-              }
-            }
-          }
-        }
-
-        return list;
-      };
-
-      /**
-       * Add a custom font.
-       *
-       * @param {String} Postscript name of the Font.  Example: "Menlo-Regular"
-       * @param {String} Name of font-family from @font-face definition.  Example: "Menlo Regular"
-       * @param {String} Font style.  Example: "normal"
-       * @function
-       * @returns the {fontKey} (same as the internal method)
-       * @methodOf jsPDF#
-       * @name addFont
-       */
-      API.addFont = function (postScriptName, fontName, fontStyle, encoding) {
-        encoding = encoding || 'Identity-H';
-        addFont(postScriptName, fontName, fontStyle, encoding);
-      };
-
-      /**
-       * Sets line width for upcoming lines.
-       *
-       * @param {Number} width Line width (in units declared at inception of PDF document)
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setLineWidth
-       */
-      API.setLineWidth = function (width) {
-        out((width * k).toFixed(2) + ' w');
-        return this;
-      };
-
-      /**
-       * Sets the stroke color for upcoming elements.
-       *
-       * Depending on the number of arguments given, Gray, RGB, or CMYK
-       * color space is implied.
-       *
-       * When only ch1 is given, "Gray" color space is implied and it
-       * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
-       * if values are communicated as String types, or in range from 0 (black)
-       * to 255 (white) if communicated as Number type.
-       * The RGB-like 0-255 range is provided for backward compatibility.
-       *
-       * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
-       * value must be in the range from 0.00 (minimum intensity) to to 1.00
-       * (max intensity) if values are communicated as String types, or
-       * from 0 (min intensity) to to 255 (max intensity) if values are communicated
-       * as Number types.
-       * The RGB-like 0-255 range is provided for backward compatibility.
-       *
-       * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
-       * value must be a in the range from 0.00 (0% concentration) to to
-       * 1.00 (100% concentration)
-       *
-       * Because JavaScript treats fixed point numbers badly (rounds to
-       * floating point nearest to binary representation) it is highly advised to
-       * communicate the fractional numbers as String types, not JavaScript Number type.
-       *
-       * @param {Number|String} ch1 Color channel value or {String} ch1 color value in hexadecimal, example: '#FFFFFF'
-       * @param {Number|String} ch2 Color channel value
-       * @param {Number|String} ch3 Color channel value
-       * @param {Number|String} ch4 Color channel value
-       *
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setDrawColor
-       */
-      API.setDrawColor = function (ch1, ch2, ch3, ch4) {
-        var options = {
-          "ch1": ch1,
-          "ch2": ch2,
-          "ch3": ch3,
-          "ch4": ch4,
-          "pdfColorType": "draw",
-          "precision": 2
-        };
-
-        out(generateColorString(options));
-        return this;
-      };
-
-      /**
-       * Sets the fill color for upcoming elements.
-       *
-       * Depending on the number of arguments given, Gray, RGB, or CMYK
-       * color space is implied.
-       *
-       * When only ch1 is given, "Gray" color space is implied and it
-       * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
-       * if values are communicated as String types, or in range from 0 (black)
-       * to 255 (white) if communicated as Number type.
-       * The RGB-like 0-255 range is provided for backward compatibility.
-       *
-       * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
-       * value must be in the range from 0.00 (minimum intensity) to to 1.00
-       * (max intensity) if values are communicated as String types, or
-       * from 0 (min intensity) to to 255 (max intensity) if values are communicated
-       * as Number types.
-       * The RGB-like 0-255 range is provided for backward compatibility.
-       *
-       * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
-       * value must be a in the range from 0.00 (0% concentration) to to
-       * 1.00 (100% concentration)
-       *
-       * Because JavaScript treats fixed point numbers badly (rounds to
-       * floating point nearest to binary representation) it is highly advised to
-       * communicate the fractional numbers as String types, not JavaScript Number type.
-       *
-       * @param {Number|String} ch1 Color channel value or {String} ch1 color value in hexadecimal, example: '#FFFFFF'
-       * @param {Number|String} ch2 Color channel value
-       * @param {Number|String} ch3 Color channel value
-       * @param {Number|String} ch4 Color channel value
-       *
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setFillColor
-       */
-
-      API.setFillColor = function (ch1, ch2, ch3, ch4) {
-        var options = {
-          "ch1": ch1,
-          "ch2": ch2,
-          "ch3": ch3,
-          "ch4": ch4,
-          "pdfColorType": "fill",
-          "precision": 2
-        };
-
-        out(generateColorString(options));
-        return this;
-      };
-
-      /**
-       * Sets the text color for upcoming elements.
-       *
-       * Depending on the number of arguments given, Gray, RGB, or CMYK
-       * color space is implied.
-       *
-       * When only ch1 is given, "Gray" color space is implied and it
-       * must be a value in the range from 0.00 (solid black) to to 1.00 (white)
-       * if values are communicated as String types, or in range from 0 (black)
-       * to 255 (white) if communicated as Number type.
-       * The RGB-like 0-255 range is provided for backward compatibility.
-       *
-       * When only ch1,ch2,ch3 are given, "RGB" color space is implied and each
-       * value must be in the range from 0.00 (minimum intensity) to to 1.00
-       * (max intensity) if values are communicated as String types, or
-       * from 0 (min intensity) to to 255 (max intensity) if values are communicated
-       * as Number types.
-       * The RGB-like 0-255 range is provided for backward compatibility.
-       *
-       * When ch1,ch2,ch3,ch4 are given, "CMYK" color space is implied and each
-       * value must be a in the range from 0.00 (0% concentration) to to
-       * 1.00 (100% concentration)
-       *
-       * Because JavaScript treats fixed point numbers badly (rounds to
-       * floating point nearest to binary representation) it is highly advised to
-       * communicate the fractional numbers as String types, not JavaScript Number type.
-       *
-       * @param {Number|String} ch1 Color channel value or {String} ch1 color value in hexadecimal, example: '#FFFFFF'
-       * @param {Number|String} ch2 Color channel value
-       * @param {Number|String} ch3 Color channel value
-       * @param {Number|String} ch4 Color channel value
-       *
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setTextColor
-       */
-      API.setTextColor = function (ch1, ch2, ch3, ch4) {
-        var options = {
-          "ch1": ch1,
-          "ch2": ch2,
-          "ch3": ch3,
-          "ch4": ch4,
-          "pdfColorType": "text",
-          "precision": 3
-        };
-        textColor = generateColorString(options);
-
-        return this;
-      };
-
-      /**
-       * Initializes the default character set that the user wants to be global..
-       *
-       * @param {Number} charSpace
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setCharSpace
-       */
-
-      API.setCharSpace = function (charSpace) {
-        activeCharSpace = charSpace;
-        return this;
-      };
-
-      /**
-       * Initializes the default character set that the user wants to be global..
-       *
-       * @param {Boolean} boolean
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setR2L
-       */
-
-      API.setR2L = function (boolean) {
-        R2L = boolean;
-        return this;
-      };
-
-      /**
-       * Is an Object providing a mapping from human-readable to
-       * integer flag values designating the varieties of line cap
-       * and join styles.
-       *
-       * @returns {Object}
-       * @fieldOf jsPDF#
-       * @name CapJoinStyles
-       */
-      API.CapJoinStyles = {
-        0: 0,
-        'butt': 0,
-        'but': 0,
-        'miter': 0,
-        1: 1,
-        'round': 1,
-        'rounded': 1,
-        'circle': 1,
-        2: 2,
-        'projecting': 2,
-        'project': 2,
-        'square': 2,
-        'bevel': 2
-      };
-
-      /**
-       * Sets the line cap styles
-       * See {jsPDF.CapJoinStyles} for variants
-       *
-       * @param {String|Number} style A string or number identifying the type of line cap
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setLineCap
-       */
-      API.setLineCap = function (style) {
-        var id = this.CapJoinStyles[style];
-        if (id === undefined) {
-          throw new Error("Line cap style of '" + style + "' is not recognized. See or extend .CapJoinStyles property for valid styles");
-        }
-        lineCapID = id;
-        out(id + ' J');
-
-        return this;
-      };
-
-      /**
-       * Sets the line join styles
-       * See {jsPDF.CapJoinStyles} for variants
-       *
-       * @param {String|Number} style A string or number identifying the type of line join
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name setLineJoin
-       */
-      API.setLineJoin = function (style) {
-        var id = this.CapJoinStyles[style];
-        if (id === undefined) {
-          throw new Error("Line join style of '" + style + "' is not recognized. See or extend .CapJoinStyles property for valid styles");
-        }
-        lineJoinID = id;
-        out(id + ' j');
-
-        return this;
-      };
-
-      // Output is both an internal (for plugins) and external function
-      API.output = _output;
-
-      /**
-       * Saves as PDF document. An alias of jsPDF.output('save', 'filename.pdf')
-       * @param  {String} filename The filename including extension.
-       *
-       * @function
-       * @returns {jsPDF}
-       * @methodOf jsPDF#
-       * @name save
-       */
-      API.save = function (filename) {
-        API.output('save', filename);
-      };
-
-      // applying plugins (more methods) ON TOP of built-in API.
-      // this is intentional as we allow plugins to override
-      // built-ins
-      for (var plugin in jsPDF.API) {
-        if (jsPDF.API.hasOwnProperty(plugin)) {
-          if (plugin === 'events' && jsPDF.API.events.length) {
-            (function (events, newEvents) {
-
-              // jsPDF.API.events is a JS Array of Arrays
-              // where each Array is a pair of event name, handler
-              // Events were added by plugins to the jsPDF instantiator.
-              // These are always added to the new instance and some ran
-              // during instantiation.
-              var eventname, handler_and_args, i;
-
-              for (i = newEvents.length - 1; i !== -1; i--) {
-                // subscribe takes 3 args: 'topic', function, runonce_flag
-                // if undefined, runonce is false.
-                // users can attach callback directly,
-                // or they can attach an array with [callback, runonce_flag]
-                // that's what the "apply" magic is for below.
-                eventname = newEvents[i][0];
-                handler_and_args = newEvents[i][1];
-                events.subscribe.apply(events, [eventname].concat(typeof handler_and_args === 'function' ? [handler_and_args] : handler_and_args));
-              }
-            })(events, jsPDF.API.events);
-          } else {
-            API[plugin] = jsPDF.API[plugin];
-          }
-        }
-      }
-
-      //////////////////////////////////////////////////////
-      // continuing initialization of jsPDF Document object
-      //////////////////////////////////////////////////////
-      // Add the first page automatically
-      addFonts();
-      activeFontKey = 'F1';
-      _addPage(format, orientation);
-
-      events.publish('initialized');
-      return API;
-    }
-
-    /**
-     * jsPDF.API is a STATIC property of jsPDF class.
-     * jsPDF.API is an object you can add methods and properties to.
-     * The methods / properties you add will show up in new jsPDF objects.
-     *
-     * One property is prepopulated. It is the 'events' Object. Plugin authors can add topics,
-     * callbacks to this object. These will be reassigned to all new instances of jsPDF.
-     * Examples:
-     * jsPDF.API.events['initialized'] = function(){ 'this' is API object }
-     * jsPDF.API.events['addFont'] = function(added_font_object){ 'this' is API object }
-     *
-     * @static
-     * @public
-     * @memberOf jsPDF
-     * @name API
-     *
-     * @example
-     * jsPDF.API.mymethod = function(){
-     *   // 'this' will be ref to internal API object. see jsPDF source
-     *   // , so you can refer to built-in methods like so:
-     *   //     this.line(....)
-     *   //     this.text(....)
-     * }
-     * var pdfdoc = new jsPDF()
-     * pdfdoc.mymethod() // <- !!!!!!
-     */
-    jsPDF.API = {
-      events: []
-    };
-    jsPDF.version = "0.0.0";
-
-    if (typeof define === 'function' && define.amd) {
-      define('jsPDF', function () {
-        return jsPDF;
-      });
-    } else if (typeof module !== 'undefined' && module.exports) {
-      module.exports = jsPDF;
-      module.exports.jsPDF = jsPDF;
-    } else {
-      global.jsPDF = jsPDF;
-    }
-    return jsPDF;
-  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global || Function('return typeof this === "object" && this.content')() || Function('return this')());
-  // `self` is undefined in Firefox for Android content script context
-  // while `this` is nsIContentFrameMessageManager
-  // with an attribute `content` that corresponds to the window
-  
-
-  /**
-   * jsPDF AcroForm Plugin Copyright (c) 2016 Alexander Weidt,
-   * https://github.com/BiggA94
-   * 
-   * Licensed under the MIT License. http://opensource.org/licenses/mit-license
-   */
-
-  (function (jsPDFAPI, globalObj) {
-
-    var scope;
-    var pageHeight;
-    var scaleFactor = 1;
-    var inherit = function inherit(child, parent) {
-      child.prototype = Object.create(parent.prototype);
-      child.prototype.constructor = child;
-    };
-    var scale = function scale(x) {
-      return x * (scaleFactor / 1); // 1 = (96 / 72)
-    };
-
-    var createFormXObject = function createFormXObject(formObject) {
-      var xobj = new AcroFormXObject();
-      var height = AcroFormAppearance.internal.getHeight(formObject) || 0;
-      var width = AcroFormAppearance.internal.getWidth(formObject) || 0;
-      xobj.BBox = [0, 0, width.toFixed(2), height.toFixed(2)];
-      return xobj;
-    };
-
-    var setBitPosition = function setBitPosition(variable, position, value) {
-      variable = variable || 0;
-      value = value || 1;
-
-      var bitMask = 1;
-      bitMask = bitMask << position - 1;
-
-      if (value == 1) {
-        // Set the Bit to 1
-        var variable = variable | bitMask;
-      } else {
-        // Set the Bit to 0
-        var variable = variable & ~bitMask;
-      }
-
-      return variable;
-    };
-
-    /**
-    * Calculating the Ff entry:
-    * 
-    * The Ff entry contains flags, that have to be set bitwise In the Following
-    * the number in the Comment is the BitPosition
-    */
-    var calculateFlagsOnOptions = function calculateFlagsOnOptions(flags, opts, PDFVersion) {
-      var PDFVersion = PDFVersion || 1.3;
-      var flags = flags || 0;
-
-      // 1, readOnly
-      if (opts.readOnly == true) {
-        flags = setBitPosition(flags, 1);
-      }
-
-      // 2, required
-      if (opts.required == true) {
-        flags = setBitPosition(flags, 2);
-      }
-
-      // 4, noExport
-      if (opts.noExport == true) {
-        flags = setBitPosition(flags, 3);
-      }
-
-      // 13, multiline
-      if (opts.multiline == true) {
-        flags = setBitPosition(flags, 13);
-      }
-
-      // 14, Password
-      if (opts.password) {
-        flags = setBitPosition(flags, 14);
-      }
-
-      // 15, NoToggleToOff (Radio buttons only
-      if (opts.noToggleToOff) {
-        flags = setBitPosition(flags, 15);
-      }
-
-      // 16, Radio
-      if (opts.radio) {
-        flags = setBitPosition(flags, 16);
-      }
-
-      // 17, Pushbutton
-      if (opts.pushbutton) {
-        flags = setBitPosition(flags, 17);
-      }
-
-      // 18, Combo (If not set, the choiceField is a listBox!!)
-      if (opts.combo) {
-        flags = setBitPosition(flags, 18);
-      }
-
-      // 19, Edit
-      if (opts.edit) {
-        flags = setBitPosition(flags, 19);
-      }
-
-      // 20, Sort
-      if (opts.sort) {
-        flags = setBitPosition(flags, 20);
-      }
-
-      // 21, FileSelect, PDF 1.4...
-      if (opts.fileSelect && PDFVersion >= 1.4) {
-        flags = setBitPosition(flags, 21);
-      }
-
-      // 22, MultiSelect (PDF 1.4)
-      if (opts.multiSelect && PDFVersion >= 1.4) {
-        flags = setBitPosition(flags, 22);
-      }
-
-      // 23, DoNotSpellCheck (PDF 1.4)
-      if (opts.doNotSpellCheck && PDFVersion >= 1.4) {
-        flags = setBitPosition(flags, 23);
-      }
-
-      // 24, DoNotScroll (PDF 1.4)
-      if (opts.doNotScroll == true && PDFVersion >= 1.4) {
-        flags = setBitPosition(flags, 24);
-      }
-
-      // 25, RichText (PDF 1.4)
-      if (opts.richText && PDFVersion >= 1.4) {
-        flags = setBitPosition(flags, 25);
-      }
-
-      return flags;
-    };
-
-    var calculateCoordinates = function calculateCoordinates(args) {
-      var x = args[0];
-      var y = args[1];
-      var w = args[2];
-      var h = args[3];
-
-      var coordinates = {};
-
-      if (Array.isArray(x)) {
-        x[0] = scale(x[0]);
-        x[1] = scale(x[1]);
-        x[2] = scale(x[2]);
-        x[3] = scale(x[3]);
-      } else {
-        x = scale(x);
-        y = scale(y);
-        w = scale(w);
-        h = scale(h);
-      }
-      coordinates.lowerLeft_X = x || 0;
-      coordinates.lowerLeft_Y = scale(pageHeight) - y - h || 0;
-      coordinates.upperRight_X = x + w || 0;
-      coordinates.upperRight_Y = scale(pageHeight) - y || 0;
-
-      return [coordinates.lowerLeft_X.toFixed(2), coordinates.lowerLeft_Y.toFixed(2), coordinates.upperRight_X.toFixed(2), coordinates.upperRight_Y.toFixed(2)];
-    };
-
-    var calculateAppearanceStream = function calculateAppearanceStream(formObject) {
-      if (formObject.appearanceStreamContent) {
-        // If appearanceStream is already set, use it
-        return formObject.appearanceStreamContent;
-      }
-
-      if (!formObject.V && !formObject.DV) {
-        return;
-      }
-
-      // else calculate it
-
-      var stream = [];
-      var text = formObject.V || formObject.DV;
-      var calcRes = calculateX(formObject, text);
-
-      stream.push('/Tx BMC');
-      stream.push('q');
-      stream.push('/F1 ' + calcRes.fontSize.toFixed(2) + ' Tf');
-      stream.push('1 0 0 1 0 0 Tm'); // Text Matrix
-
-      stream.push('BT'); // Begin Text
-      stream.push(calcRes.text);
-
-      stream.push('ET'); // End Text
-      stream.push('Q');
-      stream.push('EMC');
-
-      var appearanceStreamContent = new createFormXObject(formObject);
-      appearanceStreamContent.stream = stream.join("\n");
-
-      return appearanceStreamContent;
-    };
-
-    var calculateX = function calculateX(formObject, text, font, maxFontSize) {
-      var maxFontSize = maxFontSize || 12;
-      var font = font || "helvetica";
-      var returnValue = {
-        text: "",
-        fontSize: ""
-      };
-      // Remove Brackets
-      text = text.substr(0, 1) == '(' ? text.substr(1) : text;
-      text = text.substr(text.length - 1) == ')' ? text.substr(0, text.length - 1) : text;
-      // split into array of words
-      var textSplit = text.split(' ');
-      var fontSize = maxFontSize; // The Starting fontSize (The Maximum)
-      var lineSpacing = 2;
-      var borderPadding = 2;
-
-      var height = AcroFormAppearance.internal.getHeight(formObject) || 0;
-      height = height < 0 ? -height : height;
-      var width = AcroFormAppearance.internal.getWidth(formObject) || 0;
-      width = width < 0 ? -width : width;
-
-      var isSmallerThanWidth = function isSmallerThanWidth(i, lastLine, fontSize) {
-        if (i + 1 < textSplit.length) {
-          var tmp = lastLine + " " + textSplit[i + 1];
-          var TextWidth = calculateFontSpace(tmp, fontSize + "px", font).width;
-          var FieldWidth = width - 2 * borderPadding;
-          return TextWidth <= FieldWidth;
-        } else {
-          return false;
-        }
-      };
-
-      fontSize++;
-      FontSize: while (true) {
-        var text = "";
-        fontSize--;
-        var textHeight = calculateFontSpace("3", fontSize + "px", font).height;
-        var startY = formObject.multiline ? height - fontSize : (height - textHeight) / 2;
-        startY += lineSpacing;
-        var startX = -borderPadding;
-
-        var lastY = startY;
-        var firstWordInLine = 0,
-            lastWordInLine = 0;
-        var lastLength = 0;
-        if (fontSize <= 0) {
-          // In case, the Text doesn't fit at all
-          fontSize = 12;
-          text = "(...) Tj\n";
-          text += "% Width of Text: " + calculateFontSpace(text, "1px").width + ", FieldWidth:" + width + "\n";
-          break;
-        }
-
-        lastLength = calculateFontSpace(textSplit[0] + " ", fontSize + "px", font).width;
-
-        var lastLine = "";
-        var lineCount = 0;
-        Line: for (var i in textSplit) {
-          lastLine += textSplit[i] + " ";
-          // Remove last blank
-          lastLine = lastLine.substr(lastLine.length - 1) == " " ? lastLine.substr(0, lastLine.length - 1) : lastLine;
-          var key = parseInt(i);
-          lastLength = calculateFontSpace(lastLine + " ", fontSize + "px", font).width;
-          var nextLineIsSmaller = isSmallerThanWidth(key, lastLine, fontSize);
-          var isLastWord = i >= textSplit.length - 1;
-          if (nextLineIsSmaller && !isLastWord) {
-            lastLine += " ";
-            continue; // Line
-          } else if (!nextLineIsSmaller && !isLastWord) {
-            if (!formObject.multiline) {
-              continue FontSize;
-            } else {
-              if ((textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {
-                // If the Text is higher than the
-                // FieldObject
-                continue FontSize;
-              }
-              lastWordInLine = key;
-              // go on
-            }
-          } else if (isLastWord) {
-            lastWordInLine = key;
-          } else {
-            if (formObject.multiline && (textHeight + lineSpacing) * (lineCount + 2) + lineSpacing > height) {
-              // If the Text is higher than the FieldObject
-              continue FontSize;
-            }
-          }
-
-          var line = '';
-
-          for (var x = firstWordInLine; x <= lastWordInLine; x++) {
-            line += textSplit[x] + ' ';
-          }
-
-          // Remove last blank
-          line = line.substr(line.length - 1) == " " ? line.substr(0, line.length - 1) : line;
-          // lastLength -= blankSpace.width;
-          lastLength = calculateFontSpace(line, fontSize + "px", font).width;
-
-          // Calculate startX
-          switch (formObject.Q) {
-            case 2:
-              // Right justified
-              startX = width - lastLength - borderPadding;
-              break;
-            case 1:
-              // Q = 1 := Text-Alignment: Center
-              startX = (width - lastLength) / 2;
-              break;
-            case 0:
-            default:
-              startX = borderPadding;
-              break;
-          }
-          text += startX.toFixed(2) + ' ' + lastY.toFixed(2) + ' Td\n';
-          text += '(' + line + ') Tj\n';
-          // reset X in PDF
-          text += -startX.toFixed(2) + ' 0 Td\n';
-
-          // After a Line, adjust y position
-          lastY = -(fontSize + lineSpacing);
-
-          // Reset for next iteration step
-          lastLength = 0;
-          firstWordInLine = lastWordInLine + 1;
-          lineCount++;
-
-          lastLine = "";
-          continue Line;
-        }
-        break;
-      }
-
-      returnValue.text = text;
-      returnValue.fontSize = fontSize;
-
-      return returnValue;
-    };
-
-    /**
-    * small workaround for calculating the TextMetric approximately
-    * 
-    * @param text
-    * @param fontsize
-    * @returns {TextMetrics} (Has Height and Width)
-    */
-    var calculateFontSpace = function calculateFontSpace(text, fontSize, fontType) {
-      fontType = fontType || "helvetica";
-      var font = scope.internal.getFont(fontType);
-      var width = scope.getStringUnitWidth(text, { font: font, fontSize: parseFloat(fontSize), charSpace: 0 }) * parseFloat(fontSize);
-      var height = scope.getStringUnitWidth("3", { font: font, fontSize: parseFloat(fontSize), charSpace: 0 }) * parseFloat(fontSize) * 1.5;
-      var result = { height: height, width: width };
-      return result;
-    };
-
-    var acroformPluginTemplate = {
-      fields: [],
-      xForms: [],
-      /**
-      * acroFormDictionaryRoot contains information about the AcroForm
-      * Dictionary 0: The Event-Token, the AcroFormDictionaryCallback has
-      * 1: The Object ID of the Root
-      */
-      acroFormDictionaryRoot: null,
-      /**
-      * After the PDF gets evaluated, the reference to the root has to be
-      * reset, this indicates, whether the root has already been printed
-      * out
-      */
-      printedOut: false,
-      internal: null,
-      isInitialized: false
-    };
-
-    var annotReferenceCallback = function annotReferenceCallback() {
-      for (var i in scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields) {
-        var formObject = scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields[i];
-        // add Annot Reference!
-        if (formObject.hasAnnotation) {
-          // If theres an Annotation Widget in the Form Object, put the
-          // Reference in the /Annot array
-          createAnnotationReference.call(scope, formObject);
-        }
-      }
-    };
-
-    var putForm = function putForm(formObject) {
-      if (scope.internal.acroformPlugin.printedOut) {
-        scope.internal.acroformPlugin.printedOut = false;
-        scope.internal.acroformPlugin.acroFormDictionaryRoot = null;
-      }
-      if (!scope.internal.acroformPlugin.acroFormDictionaryRoot) {
-        initializeAcroForm.call(scope);
-      }
-      scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields.push(formObject);
-    };
-    /**
-    * Create the Reference to the widgetAnnotation, so that it gets referenced
-    * in the Annot[] int the+ (Requires the Annotation Plugin)
-    */
-    var createAnnotationReference = function createAnnotationReference(object) {
-      var options = {
-        type: 'reference',
-        object: object
-      };
-      scope.annotationPlugin.annotations[scope.internal.getPageInfo(object.page).pageNumber].push(options);
-    };
-
-    // Callbacks
-
-    var putCatalogCallback = function putCatalogCallback() {
-      // Put reference to AcroForm to DocumentCatalog
-      if (typeof scope.internal.acroformPlugin.acroFormDictionaryRoot != 'undefined') {
-        // for safety, shouldn't normally be the case
-        scope.internal.write('/AcroForm ' + scope.internal.acroformPlugin.acroFormDictionaryRoot.objId + ' ' + 0 + ' R');
-      } else {
-        console.log('Root missing...');
-      }
-    };
-
-    /**
-    * Adds /Acroform X 0 R to Document Catalog, and creates the AcroForm
-    * Dictionary
-    */
-    var AcroFormDictionaryCallback = function AcroFormDictionaryCallback() {
-      // Remove event
-      scope.internal.events.unsubscribe(scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID);
-      delete scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID;
-      scope.internal.acroformPlugin.printedOut = true;
-    };
-
-    /**
-    * Creates the single Fields and writes them into the Document
-    * 
-    * If fieldArray is set, use the fields that are inside it instead of the
-    * fields from the AcroRoot (for the FormXObjects...)
-    */
-    var createFieldCallback = function createFieldCallback(fieldArray) {
-      var standardFields = !fieldArray;
-
-      if (!fieldArray) {
-        // in case there is no fieldArray specified, we want to print out
-        // the Fields of the AcroForm
-        // Print out Root
-        scope.internal.newObjectDeferredBegin(scope.internal.acroformPlugin.acroFormDictionaryRoot.objId);
-        scope.internal.out(scope.internal.acroformPlugin.acroFormDictionaryRoot.getString());
-      }
-
-      var fieldArray = fieldArray || scope.internal.acroformPlugin.acroFormDictionaryRoot.Kids;
-
-      for (var i in fieldArray) {
-        var form = fieldArray[i];
-
-        var oldRect = form.Rect;
-
-        if (form.Rect) {
-          form.Rect = calculateCoordinates.call(this, form.Rect);
-        }
-
-        // Start Writing the Object
-        scope.internal.newObjectDeferredBegin(form.objId);
-
-        var content = form.objId + " 0 obj\n<<\n";
-
-        if ((typeof form === 'undefined' ? 'undefined' : _typeof(form)) === "object" && typeof form.getContent === "function") {
-          content += form.getContent();
-        }
-
-        form.Rect = oldRect;
-
-        if (form.hasAppearanceStream && !form.appearanceStreamContent) {
-          // Calculate Appearance
-          var appearance = calculateAppearanceStream.call(this, form);
-          content += "/AP << /N " + appearance + " >>\n";
-
-          scope.internal.acroformPlugin.xForms.push(appearance);
-        }
-
-        // Assume AppearanceStreamContent is a Array with N,R,D (at least
-        // one of them!)
-        if (form.appearanceStreamContent) {
-          content += "/AP << ";
-          // Iterate over N,R and D
-          for (var k in form.appearanceStreamContent) {
-            var value = form.appearanceStreamContent[k];
-            content += "/" + k + " ";
-            content += "<< ";
-            if (Object.keys(value).length >= 1 || Array.isArray(value)) {
-              // appearanceStream is an Array or Object!
-              for (var i in value) {
-                var obj = value[i];
-                if (typeof obj === 'function') {
-                  // if Function is referenced, call it in order
-                  // to get the FormXObject
-                  obj = obj.call(this, form);
-                }
-                content += "/" + i + " " + obj + " ";
-
-                // In case the XForm is already used, e.g. OffState
-                // of CheckBoxes, don't add it
-                if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj);
-              }
-            } else {
-              var obj = value;
-              if (typeof obj === 'function') {
-                // if Function is referenced, call it in order to
-                // get the FormXObject
-                obj = obj.call(this, form);
-              }
-              content += "/" + i + " " + obj + " \n";
-              if (!(scope.internal.acroformPlugin.xForms.indexOf(obj) >= 0)) scope.internal.acroformPlugin.xForms.push(obj);
-            }
-            content += " >>\n";
-          }
-
-          // appearance stream is a normal Object..
-          content += ">>\n";
-        }
-
-        content += ">>\nendobj\n";
-
-        scope.internal.out(content);
-      }
-      if (standardFields) {
-        createXFormObjectCallback.call(this, scope.internal.acroformPlugin.xForms);
-      }
-    };
-
-    var createXFormObjectCallback = function createXFormObjectCallback(fieldArray) {
-      for (var i in fieldArray) {
-        var key = i;
-        var form = fieldArray[i];
-        // Start Writing the Object
-        scope.internal.newObjectDeferredBegin(form && form.objId);
-
-        var content = "";
-        if ((typeof form === 'undefined' ? 'undefined' : _typeof(form)) === "object" && typeof form.getString === "function") {
-          content = form.getString();
-        }
-        scope.internal.out(content);
-
-        delete fieldArray[key];
-      }
-    };
-
-    var initializeAcroForm = function initializeAcroForm() {
-      if (this.internal !== undefined && (this.internal.acroformPlugin === undefined || this.internal.acroformPlugin.isInitialized === false)) {
-
-        scope = this;
-
-        AcroFormField.FieldNum = 0;
-        this.internal.acroformPlugin = JSON.parse(JSON.stringify(acroformPluginTemplate));
-        if (this.internal.acroformPlugin.acroFormDictionaryRoot) {
-          // return;
-          throw new Error("Exception while creating AcroformDictionary");
-        }
-        scaleFactor = scope.internal.scaleFactor;
-        pageHeight = scope.internal.pageSize.getHeight();
-
-        // The Object Number of the AcroForm Dictionary
-        scope.internal.acroformPlugin.acroFormDictionaryRoot = new AcroFormDictionary();
-
-        // add Callback for creating the AcroForm Dictionary
-        scope.internal.acroformPlugin.acroFormDictionaryRoot._eventID = scope.internal.events.subscribe('postPutResources', AcroFormDictionaryCallback);
-
-        scope.internal.events.subscribe('buildDocument', annotReferenceCallback); // buildDocument
-
-        // Register event, that is triggered when the DocumentCatalog is
-        // written, in order to add /AcroForm
-        scope.internal.events.subscribe('putCatalog', putCatalogCallback);
-
-        // Register event, that creates all Fields
-        scope.internal.events.subscribe('postPutPages', createFieldCallback);
-
-        scope.internal.acroformPlugin.isInitialized = true;
-      }
-    };
-
-    var arrayToPdfArray = function arrayToPdfArray(array) {
-      if (Array.isArray(array)) {
-        var content = ' [';
-        for (var i in array) {
-          var element = array[i].toString();
-          content += element;
-          content += i < array.length - 1 ? ' ' : '';
-        }
-        content += ']';
-
-        return content;
-      }
-    };
-
-    var toPdfString = function toPdfString(string) {
-      string = string || "";
-
-      // put Bracket at the Beginning of the String
-      if (string.indexOf('(') !== 0) {
-        string = '(' + string;
-      }
-
-      if (string.substring(string.length - 1) != ')') {
-        string += ')';
-      }
-      return string;
-    };
-
-    // ##########################
-    // Classes
-    // ##########################
-
-    var AcroFormPDFObject = function AcroFormPDFObject() {
-      // The Object ID in the PDF Object Model
-      // todo
-      var _objId;
-      Object.defineProperty(this, 'objId', {
-        get: function get$$1() {
-          if (!_objId) {
-            _objId = scope.internal.newObjectDeferred();
-          }
-          if (!_objId) {
-            console.log("Couldn't create Object ID");
-          }
-          return _objId;
-        },
-        configurable: false
-      });
-    };
-
-    AcroFormPDFObject.prototype.toString = function () {
-      return this.objId + " 0 R";
-    };
-
-    AcroFormPDFObject.prototype.getString = function () {
-      var res = this.objId + " 0 obj\n<<";
-      var content = this.getContent();
-
-      res += content + ">>\n";
-      if (this.stream) {
-        res += "stream\n";
-        res += this.stream;
-        res += "\nendstream\n";
-      }
-      res += "endobj\n";
-      return res;
-    };
-
-    AcroFormPDFObject.prototype.getContent = function () {
-      /**
-      * Prints out all enumerable Variables from the Object
-      * 
-      * @param fieldObject
-      * @returns {string}
-      */
-      var createContentFromFieldObject = function createContentFromFieldObject(fieldObject) {
-        var content = '';
-
-        var keys = Object.keys(fieldObject).filter(function (key) {
-          return key != 'content' && key != 'appearanceStreamContent' && key.substring(0, 1) != "_";
-        });
-
-        for (var i in keys) {
-          var key = keys[i];
-          var value = fieldObject[key];
-
-          /*
-          * if (key == 'Rect' && value) { value =
-          * AcroForm.internal.calculateCoordinates.call(jsPDF.API.acroformPlugin.internal,
-          * value); }
-          */
-
-          if (value) {
-            if (Array.isArray(value)) {
-              content += '/' + key + ' ' + arrayToPdfArray(value) + "\n";
-            } else if (value instanceof AcroFormPDFObject) {
-              // In case it is a reference to another PDFObject,
-              // take the referennce number
-              content += '/' + key + ' ' + value.objId + " 0 R" + "\n";
-            } else {
-              content += '/' + key + ' ' + value + '\n';
-            }
-          }
-        }
-        return content;
-      };
-
-      var object = "";
-
-      object += createContentFromFieldObject(this);
-      return object;
-    };
-
-    var AcroFormXObject = function AcroFormXObject() {
-      AcroFormPDFObject.call(this);
-      this.Type = "/XObject";
-      this.Subtype = "/Form";
-      this.FormType = 1;
-      this.BBox;
-      this.Matrix;
-      this.Resources = "2 0 R";
-      this.PieceInfo;
-      var _stream;
-      Object.defineProperty(this, 'Length', {
-        enumerable: true,
-        get: function get$$1() {
-          return _stream !== undefined ? _stream.length : 0;
-        }
-      });
-      Object.defineProperty(this, 'stream', {
-        enumerable: false,
-        set: function set$$1(val) {
-          _stream = val.trim();
-        },
-        get: function get$$1() {
-          if (_stream) {
-            return _stream;
-          } else {
-            return null;
-          }
-        }
-      });
-    };
-
-    inherit(AcroFormXObject, AcroFormPDFObject);
-    // ##### The Objects, the User can Create:
-
-    var AcroFormDictionary = function AcroFormDictionary() {
-      AcroFormPDFObject.call(this);
-      var _Kids = [];
-      Object.defineProperty(this, 'Kids', {
-        enumerable: false,
-        configurable: true,
-        get: function get$$1() {
-          if (_Kids.length > 0) {
-            return _Kids;
-          } else {
-            return;
-          }
-        }
-      });
-      Object.defineProperty(this, 'Fields', {
-        enumerable: true,
-        configurable: true,
-        get: function get$$1() {
-          return _Kids;
-        }
-      });
-      // Default Appearance
-      this.DA;
-    };
-
-    inherit(AcroFormDictionary, AcroFormPDFObject);
-
-    // The Field Object contains the Variables, that every Field needs
-    // Rectangle for Appearance: lower_left_X, lower_left_Y, width, height
-    var AcroFormField = function AcroFormField() {
-
-      AcroFormPDFObject.call(this);
-
-      var _Rect;
-      Object.defineProperty(this, 'Rect', {
-        enumerable: true,
-        configurable: false,
-        get: function get$$1() {
-          if (!_Rect) {
-            return;
-          }
-          var tmp = _Rect;
-          // var calculatedRes =
-          // AcroForm.internal.calculateCoordinates(_Rect); // do
-          // later!
-          return tmp;
-        },
-        set: function set$$1(val) {
-          _Rect = val;
-        }
-      });
-
-      var _FT = "";
-      Object.defineProperty(this, 'FT', {
-        enumerable: true,
-        set: function set$$1(val) {
-          _FT = val;
-        },
-        get: function get$$1() {
-          return _FT;
-        }
-      });
-      /**
-      * The Partial name of the Field Object. It has to be unique.
-      */
-      var _T;
-
-      Object.defineProperty(this, 'T', {
-        enumerable: true,
-        configurable: false,
-        set: function set$$1(val) {
-          _T = val;
-        },
-        get: function get$$1() {
-          if (!_T || _T.length < 1) {
-            if (this instanceof AcroFormChildClass) {
-              // In case of a Child from a Radio´Group, you don't
-              // need a FieldName!!!
-              return;
-            }
-            return "(FieldObject" + AcroFormField.FieldNum++ + ")";
-          }
-          if (_T.substring(0, 1) == "(" && _T.substring(_T.length - 1)) {
-            return _T;
-          }
-          return "(" + _T + ")";
-        }
-      });
-
-      var _DA;
-      // Defines the default appearance (Needed for variable Text)
-      Object.defineProperty(this, 'DA', {
-        enumerable: true,
-        get: function get$$1() {
-          if (!_DA) {
-            return;
-          }
-          return '(' + _DA + ')';
-        },
-        set: function set$$1(val) {
-          _DA = val;
-        }
-      });
-
-      var _DV;
-      // Defines the default value
-      Object.defineProperty(this, 'DV', {
-        enumerable: true,
-        configurable: true,
-        get: function get$$1() {
-          if (!_DV) {
-            return;
-          }
-          return _DV;
-        },
-        set: function set$$1(val) {
-          _DV = val;
-        }
-      });
-
-      var _V;
-      // Defines the default value
-      Object.defineProperty(this, 'V', {
-        enumerable: true,
-        configurable: true,
-        get: function get$$1() {
-          if (!_V) {
-            return;
-          }
-          return _V;
-        },
-        set: function set$$1(val) {
-          _V = val;
-        }
-      });
-
-      // this.Type = "/Annot";
-      // this.Subtype = "/Widget";
-      Object.defineProperty(this, 'Type', {
-        enumerable: true,
-        get: function get$$1() {
-          return this.hasAnnotation ? "/Annot" : null;
-        }
-      });
-
-      Object.defineProperty(this, 'Subtype', {
-        enumerable: true,
-        get: function get$$1() {
-          return this.hasAnnotation ? "/Widget" : null;
-        }
-      });
-
-      /**
-      * 
-      * @type {Array}
-      */
-      this.BG;
-
-      Object.defineProperty(this, 'hasAnnotation', {
-        enumerable: false,
-        get: function get$$1() {
-          if (this.Rect || this.BC || this.BG) {
-            return true;
-          }
-          return false;
-        }
-      });
-
-      Object.defineProperty(this, 'hasAppearanceStream', {
-        enumerable: false,
-        configurable: true,
-        writable: true
-      });
-
-      Object.defineProperty(this, 'page', {
-        enumerable: false,
-        configurable: true,
-        writable: true
-      });
-    };
-
-    inherit(AcroFormField, AcroFormPDFObject);
-
-    var AcroFormChoiceField = function AcroFormChoiceField() {
-      AcroFormField.call(this);
-      // Field Type = Choice Field
-      this.FT = "/Ch";
-      // options
-      this.Opt = [];
-      this.V = '()';
-      // Top Index
-      this.TI = 0;
-      /**
-      * Defines, whether the
-      * 
-      * @type {boolean}
-      */
-
-      var _combo = false;
-
-      Object.defineProperty(this, 'combo', {
-        enumerable: false,
-        get: function get$$1() {
-          return _combo;
-        },
-        set: function set$$1(val) {
-          _combo = val;
-        }
-      });
-      /**
-      * Defines, whether the Choice Field is an Edit Field. An Edit Field
-      * is automatically an Combo Field.
-      */
-      Object.defineProperty(this, 'edit', {
-        enumerable: true,
-        set: function set$$1(val) {
-          if (val == true) {
-            this._edit = true;
-            // ComboBox has to be true
-            this.combo = true;
-          } else {
-            this._edit = false;
-          }
-        },
-        get: function get$$1() {
-          if (!this._edit) {
-            return false;
-          }
-          return this._edit;
-        },
-        configurable: false
-      });
-      this.hasAppearanceStream = true;
-    };
-    inherit(AcroFormChoiceField, AcroFormField);
-
-    var AcroFormListBox = function AcroFormListBox() {
-      AcroFormChoiceField.call(this);
-      this.combo = false;
-    };
-    inherit(AcroFormListBox, AcroFormChoiceField);
-
-    var AcroFormComboBox = function AcroFormComboBox() {
-      AcroFormListBox.call(this);
-      this.combo = true;
-    };
-    inherit(AcroFormComboBox, AcroFormListBox);
-
-    var AcroFormEditBox = function AcroFormEditBox() {
-      AcroFormComboBox.call(this);
-      this.edit = true;
-    };
-    inherit(AcroFormEditBox, AcroFormComboBox);
-
-    var AcroFormButton = function AcroFormButton() {
-      AcroFormField.call(this);
-      this.FT = "/Btn";
-      // this.hasAnnotation = true;
-    };
-    inherit(AcroFormButton, AcroFormField);
-
-    var AcroFormPushButton = function AcroFormPushButton() {
-      AcroFormButton.call(this);
-
-      var _pushbutton = true;
-      Object.defineProperty(this, 'pushbutton', {
-        enumerable: false,
-        get: function get$$1() {
-          return _pushbutton;
-        },
-        set: function set$$1(val) {
-          _pushbutton = val;
-        }
-      });
-    };
-    inherit(AcroFormPushButton, AcroFormButton);
-
-    var AcroFormRadioButton = function AcroFormRadioButton() {
-      AcroFormButton.call(this);
-
-      var _radio = true;
-      Object.defineProperty(this, 'radio', {
-        enumerable: false,
-        get: function get$$1() {
-          return _radio;
-        },
-        set: function set$$1(val) {
-          _radio = val;
-        }
-      });
-
-      var _Kids = [];
-      Object.defineProperty(this, 'Kids', {
-        enumerable: true,
-        get: function get$$1() {
-          if (_Kids.length > 0) {
-            return _Kids;
-          }
-        }
-      });
-
-      Object.defineProperty(this, '__Kids', {
-        get: function get$$1() {
-          return _Kids;
-        }
-      });
-
-      var _noToggleToOff;
-
-      Object.defineProperty(this, 'noToggleToOff', {
-        enumerable: false,
-        get: function get$$1() {
-          return _noToggleToOff;
-        },
-        set: function set$$1(val) {
-          _noToggleToOff = val;
-        }
-      });
-
-      // this.hasAnnotation = false;
-    };
-    inherit(AcroFormRadioButton, AcroFormButton);
-
-    /*
-    * The Child classs of a RadioButton (the radioGroup) -> The single
-    * Buttons
-    */
-    var AcroFormChildClass = function AcroFormChildClass(parent, name) {
-      AcroFormField.call(this);
-      this.Parent = parent;
-
-      // todo: set AppearanceType as variable that can be set from the
-      // outside...
-      this._AppearanceType = AcroFormAppearance.RadioButton.Circle;
-      // The Default appearanceType is the Circle
-      this.appearanceStreamContent = this._AppearanceType.createAppearanceStream(name);
-
-      // Set Print in the Annot Flag
-      this.F = setBitPosition(this.F, 3, 1);
-
-      // Set AppearanceCharacteristicsDictionary with default appearance
-      // if field is not interacting with user
-      this.MK = this._AppearanceType.createMK();
-      // (8) -> Cross, (1)->  Circle, ()-> nothing
-
-      // Default Appearance is Off
-      this.AS = "/Off"; // + name;
-
-      this._Name = name;
-    };
-    inherit(AcroFormChildClass, AcroFormField);
-
-    AcroFormRadioButton.prototype.setAppearance = function (appearance) {
-      if (!('createAppearanceStream' in appearance && 'createMK' in appearance)) {
-        console.log("Couldn't assign Appearance to RadioButton. Appearance was Invalid!");
-        return;
-      }
-      for (var i in this.__Kids) {
-        var child = this.__Kids[i];
-
-        child.appearanceStreamContent = appearance.createAppearanceStream(child._Name);
-        child.MK = appearance.createMK();
-      }
-    };
-
-    AcroFormRadioButton.prototype.createOption = function (name) {
-      var parent = this;
-      var kidCount = this.__Kids.length;
-
-      // Create new Child for RadioGroup
-      var child = new AcroFormChildClass(parent, name);
-      // Add to Parent
-      this.__Kids.push(child);
-
-      jsPDFAPI.addField(child);
-
-      return child;
-    };
-
-    var AcroFormCheckBox = function AcroFormCheckBox() {
-      AcroFormButton.call(this);
-      this.appearanceStreamContent = AcroFormAppearance.CheckBox.createAppearanceStream();
-      this.MK = AcroFormAppearance.CheckBox.createMK();
-      this.AS = "/On";
-      this.V = "/On";
-    };
-    inherit(AcroFormCheckBox, AcroFormButton);
-
-    var AcroFormTextField = function AcroFormTextField() {
-      AcroFormField.call(this);
-      this.DA = AcroFormAppearance.createDefaultAppearanceStream();
-      this.F = 4;
-      var _V;
-      Object.defineProperty(this, 'V', {
-        get: function get$$1() {
-          if (_V) {
-            return toPdfString(_V);
-          } else {
-            return _V;
-          }
-        },
-        enumerable: true,
-        set: function set$$1(val) {
-          _V = val;
-        }
-      });
-
-      var _DV;
-      Object.defineProperty(this, 'DV', {
-        get: function get$$1() {
-          if (_DV) {
-            return toPdfString(_DV);
-          } else {
-            return _DV;
-          }
-        },
-        enumerable: true,
-        set: function set$$1(val) {
-          _DV = val;
-        }
-      });
-
-      var _multiline = false;
-      Object.defineProperty(this, 'multiline', {
-        enumerable: false,
-        get: function get$$1() {
-          return _multiline;
-        },
-        set: function set$$1(val) {
-          _multiline = val;
-        }
-      });
-
-      /**
-      * For PDF 1.4
-      * 
-      * @type {boolean}
-      */
-      var _fileSelect = false;
-      Object.defineProperty(this, 'fileSelect', {
-        enumerable: false,
-        get: function get$$1() {
-          return _fileSelect;
-        },
-        set: function set$$1(val) {
-          _fileSelect = val;
-        }
-      });
-      /**
-      * For PDF 1.4
-      * 
-      * @type {boolean}
-      */
-      var _doNotSpellCheck = false;
-      Object.defineProperty(this, 'doNotSpellCheck', {
-        enumerable: false,
-        get: function get$$1() {
-          return _doNotSpellCheck;
-        },
-        set: function set$$1(val) {
-          _doNotSpellCheck = val;
-        }
-      });
-      /**
-      * For PDF 1.4
-      * 
-      * @type {boolean}
-      */
-      var _doNotScroll = false;
-      Object.defineProperty(this, 'doNotScroll', {
-        enumerable: false,
-        get: function get$$1() {
-          return _doNotScroll;
-        },
-        set: function set$$1(val) {
-          _doNotScroll = val;
-        }
-      });
-
-      var _MaxLen = false;
-      Object.defineProperty(this, 'MaxLen', {
-        enumerable: true,
-        get: function get$$1() {
-          return _MaxLen;
-        },
-        set: function set$$1(val) {
-          _MaxLen = val;
-        }
-      });
-
-      Object.defineProperty(this, 'hasAppearanceStream', {
-        enumerable: false,
-        get: function get$$1() {
-          return this.V || this.DV;
-        }
-      });
-    };
-    inherit(AcroFormTextField, AcroFormField);
-
-    var AcroFormPasswordField = function AcroFormPasswordField() {
-      AcroFormTextField.call(this);
-
-      var _password = true;
-      Object.defineProperty(this, 'password', {
-        enumerable: false,
-        get: function get$$1() {
-          return _password;
-        },
-        set: function set$$1(val) {
-          _password = val;
-        }
-      });
-    };
-    inherit(AcroFormPasswordField, AcroFormTextField);
-
-    // Contains Methods for creating standard appearances
-    var AcroFormAppearance = {
-      CheckBox: {
-        createAppearanceStream: function createAppearanceStream() {
-          var appearance = {
-            N: {
-              On: AcroFormAppearance.CheckBox.YesNormal
-            },
-            D: {
-              On: AcroFormAppearance.CheckBox.YesPushDown,
-              Off: AcroFormAppearance.CheckBox.OffPushDown
-            }
-          };
-
-          return appearance;
-        },
-        /**
-          * If any other icons are needed, the number between the
-          * brackets can be changed
-          * 
-          * @returns {string}
-          */
-        createMK: function createMK() {
-          return "<< /CA (3)>>";
-        },
-        /**
-          * Returns the standard On Appearance for a CheckBox
-          * 
-          * @returns {AcroFormXObject}
-          */
-        YesPushDown: function YesPushDown(formObject) {
-          var xobj = createFormXObject(formObject);
-          var stream = [];
-          var zapfDingbatsId = scope.internal.getFont("zapfdingbats", "normal").id;
-          formObject.Q = 1; // set text-alignment as centered
-          var calcRes = calculateX(formObject, "3", "ZapfDingbats", 50);
-          stream.push("0.749023 g");
-          stream.push("0 0 " + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + " " + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + " re");
-          stream.push("f");
-          stream.push("BMC");
-          stream.push("q");
-          stream.push("0 0 1 rg");
-          stream.push("/" + zapfDingbatsId + " " + calcRes.fontSize.toFixed(2) + " Tf 0 g");
-          stream.push("BT");
-          stream.push(calcRes.text);
-          stream.push("ET");
-          stream.push("Q");
-          stream.push("EMC");
-          xobj.stream = stream.join("\n");
-          return xobj;
-        },
-
-        YesNormal: function YesNormal(formObject) {
-          var xobj = createFormXObject(formObject);
-          var zapfDingbatsId = scope.internal.getFont("zapfdingbats", "normal").id;
-          var stream = [];
-          formObject.Q = 1; // set text-alignment as centered
-          var height = AcroFormAppearance.internal.getHeight(formObject);
-          var width = AcroFormAppearance.internal.getWidth(formObject);
-          var calcRes = calculateX(formObject, "3", "ZapfDingbats", height * 0.9);
-          stream.push("1 g");
-          stream.push("0 0 " + width.toFixed(2) + " " + height.toFixed(2) + " re");
-          stream.push("f");
-          stream.push("q");
-          stream.push("0 0 1 rg");
-          stream.push("0 0 " + (width - 1).toFixed(2) + " " + (height - 1).toFixed(2) + " re");
-          stream.push("W");
-          stream.push("n");
-          stream.push("0 g");
-          stream.push("BT");
-          stream.push("/" + zapfDingbatsId + " " + calcRes.fontSize.toFixed(2) + " Tf 0 g");
-          stream.push(calcRes.text);
-          stream.push("ET");
-          stream.push("Q");
-          xobj.stream = stream.join("\n");
-          return xobj;
-        },
-
-        /**
-          * Returns the standard Off Appearance for a CheckBox
-          * 
-          * @returns {AcroFormXObject}
-          */
-        OffPushDown: function OffPushDown(formObject) {
-          var xobj = createFormXObject(formObject);
-          var stream = [];
-          stream.push("0.749023 g");
-          stream.push("0 0 " + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + " " + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + " re");
-          stream.push("f");
-          xobj.stream = stream.join("\n");
-          return xobj;
-        }
-      },
-
-      RadioButton: {
-        Circle: {
-          createAppearanceStream: function createAppearanceStream(name) {
-            var appearanceStreamContent = {
-              D: {
-                'Off': AcroFormAppearance.RadioButton.Circle.OffPushDown
-              },
-              N: {}
-            };
-            appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Circle.YesNormal;
-            appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Circle.YesPushDown;
-            return appearanceStreamContent;
-          },
-          createMK: function createMK() {
-            return "<< /CA (l)>>";
-          },
-
-          YesNormal: function YesNormal(formObject) {
-            var xobj = createFormXObject(formObject);
-            var stream = [];
-            // Make the Radius of the Circle relative to min(height,
-            // width) of formObject
-            var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4;
-            // The Borderpadding...
-            DotRadius *= 0.9;
-            var c = AcroFormAppearance.internal.Bezier_C;
-            /*
-              * The Following is a Circle created with Bezier-Curves.
-              */
-            stream.push("q");
-            stream.push("1 0 0 1 " + AcroFormAppearance.internal.getWidth(formObject) / 2 + " " + AcroFormAppearance.internal.getHeight(formObject) / 2 + " cm");
-            stream.push(DotRadius + " 0 m");
-            stream.push(DotRadius + " " + DotRadius * c + " " + DotRadius * c + " " + DotRadius + " 0 " + DotRadius + " c");
-            stream.push("-" + DotRadius * c + " " + DotRadius + " -" + DotRadius + " " + DotRadius * c + " -" + DotRadius + " 0 c");
-            stream.push("-" + DotRadius + " -" + DotRadius * c + " -" + DotRadius * c + " -" + DotRadius + " 0 -" + DotRadius + " c");
-            stream.push(DotRadius * c + " -" + DotRadius + " " + DotRadius + " -" + DotRadius * c + " " + DotRadius + " 0 c");
-            stream.push("f");
-            stream.push("Q");
-            xobj.stream = stream.join("\n");
-            return xobj;
-          },
-          YesPushDown: function YesPushDown(formObject) {
-            var xobj = createFormXObject(formObject);
-            var stream = [];
-            var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4;
-            // The Borderpadding...
-            DotRadius *= 0.9;
-            // Save results for later use; no need to waste
-            // processor ticks on doing math
-            var k = DotRadius * 2;
-            // var c = AcroFormAppearance.internal.Bezier_C;
-            var kc = k * AcroFormAppearance.internal.Bezier_C;
-            var dc = DotRadius * AcroFormAppearance.internal.Bezier_C;
-
-            stream.push("0.749023 g");
-            stream.push("q");
-            stream.push("1 0 0 1 " + (AcroFormAppearance.internal.getWidth(formObject) / 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) / 2).toFixed(2) + " cm");
-            stream.push(k + " 0 m");
-            stream.push(k + " " + kc + " " + kc + " " + k + " 0 " + k + " c");
-            stream.push("-" + kc + " " + k + " -" + k + " " + kc + " -" + k + " 0 c");
-            stream.push("-" + k + " -" + kc + " -" + kc + " -" + k + " 0 -" + k + " c");
-            stream.push(kc + " -" + k + " " + k + " -" + kc + " " + k + " 0 c");
-            stream.push("f");
-            stream.push("Q");
-            stream.push("0 g");
-            stream.push("q");
-            stream.push("1 0 0 1 " + (AcroFormAppearance.internal.getWidth(formObject) / 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) / 2).toFixed(2) + " cm");
-            stream.push(DotRadius + " 0 m");
-            stream.push("" + DotRadius + " " + dc + " " + dc + " " + DotRadius + " 0 " + DotRadius + " c");
-            stream.push("-" + dc + " " + DotRadius + " -" + DotRadius + " " + dc + " -" + DotRadius + " 0 c");
-            stream.push("-" + DotRadius + " -" + dc + " -" + dc + " -" + DotRadius + " 0 -" + DotRadius + " c");
-            stream.push(dc + " -" + DotRadius + " " + DotRadius + " -" + dc + " " + DotRadius + " 0 c");
-            stream.push("f");
-            stream.push("Q");
-            xobj.stream = stream.join("\n");
-            return xobj;
-          },
-          OffPushDown: function OffPushDown(formObject) {
-            var xobj = createFormXObject(formObject);
-            var stream = [];
-            var DotRadius = AcroFormAppearance.internal.getWidth(formObject) <= AcroFormAppearance.internal.getHeight(formObject) ? AcroFormAppearance.internal.getWidth(formObject) / 4 : AcroFormAppearance.internal.getHeight(formObject) / 4;
-            // The Borderpadding...
-            DotRadius *= 0.9;
-            // Save results for later use; no need to waste
-            // processor ticks on doing math
-            var k = DotRadius * 2;
-            // var c = AcroFormAppearance.internal.Bezier_C;
-            var kc = k * AcroFormAppearance.internal.Bezier_C;
-
-            stream.push("0.749023 g");
-            stream.push("q");
-            stream.push("1 0 0 1 " + (AcroFormAppearance.internal.getWidth(formObject) / 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) / 2).toFixed(2) + " cm");
-            stream.push(k + " 0 m");
-            stream.push(k + " " + kc + " " + kc + " " + k + " 0 " + k + " c");
-            stream.push("-" + kc + " " + k + " -" + k + " " + kc + " -" + k + " 0 c");
-            stream.push("-" + k + " -" + kc + " -" + kc + " -" + k + " 0 -" + k + " c");
-            stream.push(kc + " -" + k + " " + k + " -" + kc + " " + k + " 0 c");
-            stream.push("f");
-            stream.push("Q");
-            xobj.stream = stream.join("\n");
-            return xobj;
-          }
-        },
-
-        Cross: {
-          /**
-            * Creates the Actual AppearanceDictionary-References
-            * 
-            * @param name
-            * @returns
-            */
-          createAppearanceStream: function createAppearanceStream(name) {
-            var appearanceStreamContent = {
-              D: {
-                'Off': AcroFormAppearance.RadioButton.Cross.OffPushDown
-              },
-              N: {}
-            };
-            appearanceStreamContent.N[name] = AcroFormAppearance.RadioButton.Cross.YesNormal;
-            appearanceStreamContent.D[name] = AcroFormAppearance.RadioButton.Cross.YesPushDown;
-            return appearanceStreamContent;
-          },
-          createMK: function createMK() {
-            return "<< /CA (8)>>";
-          },
-
-          YesNormal: function YesNormal(formObject) {
-            var xobj = createFormXObject(formObject);
-            var stream = [];
-            var cross = AcroFormAppearance.internal.calculateCross(formObject);
-            stream.push("q");
-            stream.push("1 1 " + (AcroFormAppearance.internal.getWidth(formObject) - 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) - 2).toFixed(2) + " re");
-            stream.push("W");
-            stream.push("n");
-            stream.push(cross.x1.x.toFixed(2) + " " + cross.x1.y.toFixed(2) + " m");
-            stream.push(cross.x2.x.toFixed(2) + " " + cross.x2.y.toFixed(2) + " l");
-            stream.push(cross.x4.x.toFixed(2) + " " + cross.x4.y.toFixed(2) + " m");
-            stream.push(cross.x3.x.toFixed(2) + " " + cross.x3.y.toFixed(2) + " l");
-            stream.push("s");
-            stream.push("Q");
-            xobj.stream = stream.join("\n");
-            return xobj;
-          },
-          YesPushDown: function YesPushDown(formObject) {
-            var xobj = createFormXObject(formObject);
-            var cross = AcroFormAppearance.internal.calculateCross(formObject);
-            var stream = [];
-            stream.push("0.749023 g");
-            stream.push("0 0 " + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + " " + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + " re");
-            stream.push("f");
-            stream.push("q");
-            stream.push("1 1 " + (AcroFormAppearance.internal.getWidth(formObject) - 2).toFixed(2) + " " + (AcroFormAppearance.internal.getHeight(formObject) - 2).toFixed(2) + " re");
-            stream.push("W");
-            stream.push("n");
-            stream.push(cross.x1.x.toFixed(2) + " " + cross.x1.y.toFixed(2) + " m");
-            stream.push(cross.x2.x.toFixed(2) + " " + cross.x2.y.toFixed(2) + " l");
-            stream.push(cross.x4.x.toFixed(2) + " " + cross.x4.y.toFixed(2) + " m");
-            stream.push(cross.x3.x.toFixed(2) + " " + cross.x3.y.toFixed(2) + " l");
-            stream.push("s");
-            stream.push("Q");
-            xobj.stream = stream.join("\n");
-            return xobj;
-          },
-          OffPushDown: function OffPushDown(formObject) {
-            var xobj = createFormXObject(formObject);
-            var stream = [];
-            stream.push("0.749023 g");
-            stream.push("0 0 " + AcroFormAppearance.internal.getWidth(formObject).toFixed(2) + " " + AcroFormAppearance.internal.getHeight(formObject).toFixed(2) + " re");
-            stream.push("f");
-            xobj.stream = stream.join("\n");
-            return xobj;
-          }
-        }
-      },
-
-      /**
-        * Returns the standard Appearance
-        * 
-        * @returns {AcroFormXObject}
-        */
-      createDefaultAppearanceStream: function createDefaultAppearanceStream(formObject) {
-        // Set Helvetica to Standard Font (size: auto)
-        // Color: Black
-        return "/F1 0 Tf 0 g";
-      }
-    };
-
-    AcroFormAppearance.internal = {
-      Bezier_C: 0.551915024494,
-
-      calculateCross: function calculateCross(formObject) {
-        var min = function min(x, y) {
-          return x > y ? y : x;
-        };
-
-        var width = AcroFormAppearance.internal.getWidth(formObject);
-        var height = AcroFormAppearance.internal.getHeight(formObject);
-        var a = min(width, height);
-
-
-        var cross = {
-          x1: { // upperLeft
-            x: (width - a) / 2,
-            y: (height - a) / 2 + a // height - borderPadding
-          },
-          x2: { // lowerRight
-            x: (width - a) / 2 + a,
-            y: (height - a) / 2 // borderPadding
-          },
-          x3: { // lowerLeft
-            x: (width - a) / 2,
-            y: (height - a) / 2 // borderPadding
-          },
-          x4: { // upperRight
-            x: (width - a) / 2 + a,
-            y: (height - a) / 2 + a // height - borderPadding
-          }
-        };
-
-        return cross;
-      }
-    };
-    AcroFormAppearance.internal.getWidth = function (formObject) {
-      var result = 0;
-      if ((typeof formObject === 'undefined' ? 'undefined' : _typeof(formObject)) === "object") {
-        result = scale(formObject.Rect[2]); // (formObject.Rect[2] -
-        // formObject.Rect[0]) || 0;
-      }
-      return result;
-    };
-    AcroFormAppearance.internal.getHeight = function (formObject) {
-      var result = 0;
-      if ((typeof formObject === 'undefined' ? 'undefined' : _typeof(formObject)) === "object") {
-        result = scale(formObject.Rect[3]); // (formObject.Rect[1] -
-        // formObject.Rect[3]) || 0;
-      }
-      return result;
-    };
-
-    // Public:
-
-    jsPDFAPI.addField = function (fieldObject) {
-      initializeAcroForm.call(this);
-      // var opt = parseOptions(fieldObject);
-      if (fieldObject instanceof AcroFormTextField) {
-        this.addTextField.call(this, fieldObject);
-      } else if (fieldObject instanceof AcroFormChoiceField) {
-        this.addChoiceField.call(this, fieldObject);
-      } else if (fieldObject instanceof AcroFormButton) {
-        this.addButton.call(this, fieldObject);
-      } else if (fieldObject instanceof AcroFormChildClass) {
-        putForm.call(this, fieldObject);
-      } else if (fieldObject) {
-        // try to put..
-        putForm.call(this, fieldObject);
-      }
-      fieldObject.page = scope.internal.getCurrentPageInfo().pageNumber;
-      return this;
-    };
-
-    /**
-    * Button FT = Btn
-    */
-    jsPDFAPI.addButton = function (opts) {
-      initializeAcroForm.call(this);
-      var options = opts || new AcroFormField();
-
-      options.FT = '/Btn';
-      options.Ff = calculateFlagsOnOptions(options.Ff, opts, scope.internal.getPDFVersion());
-
-      putForm.call(this, options);
-    };
-
-    jsPDFAPI.addTextField = function (opts) {
-      initializeAcroForm.call(this);
-      var options = opts || new AcroFormField();
-
-      options.FT = '/Tx';
-
-      options.Ff = calculateFlagsOnOptions(options.Ff, opts, scope.internal.getPDFVersion());
-
-      // Add field
-      putForm.call(this, options);
-    };
-
-    jsPDFAPI.addChoiceField = function (opts) {
-      initializeAcroForm.call(this);
-      var options = opts || new AcroFormField();
-
-      options.FT = '/Ch';
-
-      options.Ff = calculateFlagsOnOptions(options.Ff, opts, scope.internal.getPDFVersion());
-      // options.hasAnnotation = true;
-
-      // Add field
-      putForm.call(this, options);
-    };
-
-    if ((typeof globalObj === 'undefined' ? 'undefined' : _typeof(globalObj)) == "object") {
-      globalObj["ChoiceField"] = AcroFormChoiceField;
-      globalObj["ListBox"] = AcroFormListBox;
-      globalObj["ComboBox"] = AcroFormComboBox;
-      globalObj["EditBox"] = AcroFormEditBox;
-      globalObj["Button"] = AcroFormButton;
-      globalObj["PushButton"] = AcroFormPushButton;
-      globalObj["RadioButton"] = AcroFormRadioButton;
-      globalObj["CheckBox"] = AcroFormCheckBox;
-      globalObj["TextField"] = AcroFormTextField;
-      globalObj["PasswordField"] = AcroFormPasswordField;
-
-      // backwardsCompatibility
-      globalObj["AcroForm"] = { Appearance: AcroFormAppearance };
-    }
-
-    jsPDFAPI.AcroFormChoiceField = AcroFormChoiceField;
-    jsPDFAPI.AcroFormListBox = AcroFormListBox;
-    jsPDFAPI.AcroFormComboBox = AcroFormComboBox;
-    jsPDFAPI.AcroFormEditBox = AcroFormEditBox;
-    jsPDFAPI.AcroFormButton = AcroFormButton;
-    jsPDFAPI.AcroFormPushButton = AcroFormPushButton;
-    jsPDFAPI.AcroFormRadioButton = AcroFormRadioButton;
-    jsPDFAPI.AcroFormCheckBox = AcroFormCheckBox;
-    jsPDFAPI.AcroFormTextField = AcroFormTextField;
-    jsPDFAPI.AcroFormPasswordField = AcroFormPasswordField;
-
-    jsPDFAPI.AcroForm = {
-      ChoiceField: AcroFormChoiceField,
-      ListBox: AcroFormListBox,
-      ComboBox: AcroFormComboBox,
-      EditBox: AcroFormEditBox,
-      Button: AcroFormButton,
-      PushButton: AcroFormPushButton,
-      RadioButton: AcroFormRadioButton,
-      CheckBox: AcroFormCheckBox,
-      TextField: AcroFormTextField,
-      PasswordField: AcroFormPasswordField
-    };
-  })(jsPDF.API, typeof window !== "undefined" && window || typeof global !== "undefined" && global);
-
-  /**
-   * jsPDF addHTML PlugIn
-   * Copyright (c) 2014 Diego Casorran
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
-
-  (function (jsPDFAPI) {
-
-      /**
-       * Renders an HTML element to canvas object which added to the PDF
-       *
-       * This feature requires [html2canvas](https://github.com/niklasvh/html2canvas)
-       * or [rasterizeHTML](https://github.com/cburgmer/rasterizeHTML.js)
-       *
-       * @returns {jsPDF}
-       * @name addHTML
-       * @param element {Mixed} HTML Element, or anything supported by html2canvas.
-       * @param x {Number} starting X coordinate in jsPDF instance's declared units.
-       * @param y {Number} starting Y coordinate in jsPDF instance's declared units.
-       * @param options {Object} Additional options, check the code below.
-       * @param callback {Function} to call when the rendering has finished.
-       * NOTE: Every parameter is optional except 'element' and 'callback', in such
-       *       case the image is positioned at 0x0 covering the whole PDF document
-       *       size. Ie, to easily take screenshots of webpages saving them to PDF.
-       * @deprecated This is being replace with a vector-supporting API. See
-       * [this link](https://cdn.rawgit.com/MrRio/jsPDF/master/examples/html2pdf/showcase_supported_html.html)
-       */
-
-      jsPDFAPI.addHTML = function (element, x, y, options, callback) {
-
-          if (typeof html2canvas === 'undefined' && typeof rasterizeHTML === 'undefined') throw new Error('You need either ' + 'https://github.com/niklasvh/html2canvas' + ' or https://github.com/cburgmer/rasterizeHTML.js');
-
-          if (typeof x !== 'number') {
-              options = x;
-              callback = y;
-          }
-
-          if (typeof options === 'function') {
-              callback = options;
-              options = null;
-          }
-
-          if (typeof callback !== 'function') {
-              callback = function callback() {};
-          }
-
-          var I = this.internal,
-              K = I.scaleFactor,
-              W = I.pageSize.getWidth(),
-              H = I.pageSize.getHeight();
-
-          options = options || {};
-          options.onrendered = function (obj) {
-              x = parseInt(x) || 0;
-              y = parseInt(y) || 0;
-              var dim = options.dim || {};
-              var margin = Object.assign({ top: 0, right: 0, bottom: 0, left: 0, useFor: 'content' }, options.margin);
-              var h = dim.h || Math.min(H, obj.height / K);
-              var w = dim.w || Math.min(W, obj.width / K) - x;
-
-              var format = options.format || 'JPEG';
-              var imageCompression = options.imageCompression || 'SLOW';
-
-              var notFittingHeight = obj.height > H - margin.top - margin.bottom;
-
-              if (notFittingHeight && options.pagesplit) {
-                  var cropArea = function cropArea(parmObj, parmX, parmY, parmWidth, parmHeight) {
-                      var canvas = document.createElement('canvas');
-                      canvas.height = parmHeight;
-                      canvas.width = parmWidth;
-                      var ctx = canvas.getContext('2d');
-                      ctx.mozImageSmoothingEnabled = false;
-                      ctx.webkitImageSmoothingEnabled = false;
-                      ctx.msImageSmoothingEnabled = false;
-                      ctx.imageSmoothingEnabled = false;
-                      ctx.fillStyle = options.backgroundColor || '#ffffff';
-                      ctx.fillRect(0, 0, parmWidth, parmHeight);
-                      ctx.drawImage(parmObj, parmX, parmY, parmWidth, parmHeight, 0, 0, parmWidth, parmHeight);
-                      return canvas;
-                  };
-                  var crop = function () {
-                      var cy = 0;
-                      var cx = 0;
-                      var position = {};
-                      var isOverWide = false;
-                      var width;
-                      var height;
-                      while (1) {
-                          cx = 0;
-                          position.top = cy !== 0 ? margin.top : y;
-                          position.left = cy !== 0 ? margin.left : x;
-                          isOverWide = (W - margin.left - margin.right) * K < obj.width;
-                          if (margin.useFor === "content") {
-                              if (cy === 0) {
-                                  width = Math.min((W - margin.left) * K, obj.width);
-                                  height = Math.min((H - margin.top) * K, obj.height - cy);
-                              } else {
-                                  width = Math.min(W * K, obj.width);
-                                  height = Math.min(H * K, obj.height - cy);
-                                  position.top = 0;
-                              }
-                          } else {
-                              width = Math.min((W - margin.left - margin.right) * K, obj.width);
-                              height = Math.min((H - margin.bottom - margin.top) * K, obj.height - cy);
-                          }
-                          if (isOverWide) {
-                              while (1) {
-                                  if (margin.useFor === "content") {
-                                      if (cx === 0) {
-                                          width = Math.min((W - margin.left) * K, obj.width);
-                                      } else {
-                                          width = Math.min(W * K, obj.width - cx);
-                                          position.left = 0;
-                                      }
-                                  }
-                                  var canvas = cropArea(obj, cx, cy, width, height);
-                                  var args = [canvas, position.left, position.top, canvas.width / K, canvas.height / K, format, null, imageCompression];
-                                  this.addImage.apply(this, args);
-                                  cx += width;
-                                  if (cx >= obj.width) {
-                                      break;
-                                  }
-                                  this.addPage();
-                              }
-                          } else {
-                              var canvas = cropArea(obj, 0, cy, width, height);
-                              var args = [canvas, position.left, position.top, canvas.width / K, canvas.height / K, format, null, imageCompression];
-                              this.addImage.apply(this, args);
-                          }
-                          cy += height;
-                          if (cy >= obj.height) {
-                              break;
-                          }
-                          this.addPage();
-                      }
-                      callback(w, cy, null, args);
-                  }.bind(this);
-                  if (obj.nodeName === 'CANVAS') {
-                      var img = new Image();
-                      img.onload = crop;
-                      img.src = obj.toDataURL("image/png");
-                      obj = img;
-                  } else {
-                      crop();
-                  }
-              } else {
-                  var alias = Math.random().toString(35);
-                  var args = [obj, x, y, w, h, format, alias, imageCompression];
-
-                  this.addImage.apply(this, args);
-
-                  callback(w, h, alias, args);
-              }
-          }.bind(this);
-
-          if (typeof html2canvas !== 'undefined' && !options.rstz) {
-              return html2canvas(element, options);
-          }
-
-          if (typeof rasterizeHTML !== 'undefined') {
-              var meth = 'drawDocument';
-              if (typeof element === 'string') {
-                  meth = /^http/.test(element) ? 'drawURL' : 'drawHTML';
-              }
-              options.width = options.width || W * K;
-              return rasterizeHTML[meth](element, void 0, options).then(function (r) {
-                  options.onrendered(r.image);
-              }, function (e) {
-                  callback(null, e);
-              });
-          }
-
-          return null;
-      };
-  })(jsPDF.API);
-
-  /** @preserve
-   * jsPDF addImage plugin
-   * Copyright (c) 2012 Jason Siefken, https://github.com/siefkenj/
-   *               2013 Chris Dowling, https://github.com/gingerchris
-   *               2013 Trinh Ho, https://github.com/ineedfat
-   *               2013 Edwin Alejandro Perez, https://github.com/eaparango
-   *               2013 Norah Smith, https://github.com/burnburnrocket
-   *               2014 Diego Casorran, https://github.com/diegocr
-   *               2014 James Robb, https://github.com/jamesbrobb
-   *
-   * 
-   */
-  (function (jsPDFAPI) {
-
-  	var namespace = 'addImage_';
-
-  	var imageFileTypeHeaders = {
-  		PNG: [[0x89, 0x50, 0x4e, 0x47]],
-  		TIFF: [[0x4D, 0x4D, 0x00, 0x2A], //Motorola
-  		[0x49, 0x49, 0x2A, 0x00] //Intel
-  		],
-  		JPEG: [[0xFF, 0xD8, 0xFF, 0xE0, undefined, undefined, 0x4A, 0x46, 0x49, 0x46, 0x00], //JFIF
-  		[0xFF, 0xD8, 0xFF, 0xE1, undefined, undefined, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00] //Exif
-  		],
-  		JPEG2000: [[0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20]],
-  		GIF87a: [[0x47, 0x49, 0x46, 0x38, 0x37, 0x61]],
-  		GIF89a: [[0x47, 0x49, 0x46, 0x38, 0x39, 0x61]],
-  		BMP: [[0x42, 0x4D], //BM - Windows 3.1x, 95, NT, ... etc.
-  		[0x42, 0x41], //BA - OS/2 struct bitmap array
-  		[0x43, 0x49], //CI - OS/2 struct color icon
-  		[0x43, 0x50], //CP - OS/2 const color pointer
-  		[0x49, 0x43], //IC - OS/2 struct icon
-  		[0x50, 0x54] //PT - OS/2 pointer
-  		]
-  		/**
-    * Recognize filetype of Image by magic-bytes
-    * 
-    * https://en.wikipedia.org/wiki/List_of_file_signatures
-    *
-    * @name getImageFileTypeByImageData
-    * @public
-    * @function
-    * @param {String} imageData as base64 encoded DataUrl
-    * @param {String} format of file if filetype-recognition fails, e.g. 'JPEG'
-    * 
-    * @returns {String} filetype of Image
-    * @methodOf jsPDF#
-    */
-  	};jsPDFAPI.getImageFileTypeByImageData = function (imageData, fallbackFormat) {
-  		fallbackFormat = fallbackFormat || 'UNKNOWN';
-  		var i;
-  		var j;
-  		var result = 'UNKNOWN';
-  		var headerSchemata;
-  		var compareResult;
-  		var fileType;
-
-  		for (fileType in imageFileTypeHeaders) {
-  			headerSchemata = imageFileTypeHeaders[fileType];
-  			for (i = 0; i < headerSchemata.length; i += 1) {
-  				compareResult = true;
-  				for (j = 0; j < headerSchemata[i].length; j += 1) {
-  					if (headerSchemata[i][j] === undefined) {
-  						continue;
-  					}
-  					if (headerSchemata[i][j] !== imageData.charCodeAt(j)) {
-  						compareResult = false;
-  						break;
-  					}
-  				}
-  				if (compareResult === true) {
-  					result = fileType;
-  					break;
-  				}
-  			}
-  		}
-  		if (result === 'UNKNOWN' && fallbackFormat !== 'UNKNOWN') {
-  			console.warn('FileType of Image not recognized. Processing image as "' + fallbackFormat + '".');
-  			result = fallbackFormat;
-  		}
-  		return result;
-  	};
-
-  	// Image functionality ported from pdf.js
-  	var putImage = function putImage(img) {
-
-  		var objectNumber = this.internal.newObject(),
-  		    out = this.internal.write,
-  		    putStream = this.internal.putStream;
-
-  		img['n'] = objectNumber;
-
-  		out('<</Type /XObject');
-  		out('/Subtype /Image');
-  		out('/Width ' + img['w']);
-  		out('/Height ' + img['h']);
-  		if (img['cs'] === this.color_spaces.INDEXED) {
-  			out('/ColorSpace [/Indexed /DeviceRGB '
-  			// if an indexed png defines more than one colour with transparency, we've created a smask
-  			+ (img['pal'].length / 3 - 1) + ' ' + ('smask' in img ? objectNumber + 2 : objectNumber + 1) + ' 0 R]');
-  		} else {
-  			out('/ColorSpace /' + img['cs']);
-  			if (img['cs'] === this.color_spaces.DEVICE_CMYK) {
-  				out('/Decode [1 0 1 0 1 0 1 0]');
-  			}
-  		}
-  		out('/BitsPerComponent ' + img['bpc']);
-  		if ('f' in img) {
-  			out('/Filter /' + img['f']);
-  		}
-  		if ('dp' in img) {
-  			out('/DecodeParms <<' + img['dp'] + '>>');
-  		}
-  		if ('trns' in img && img['trns'].constructor == Array) {
-  			var trns = '',
-  			    i = 0,
-  			    len = img['trns'].length;
-  			for (; i < len; i++) {
-  				trns += img['trns'][i] + ' ' + img['trns'][i] + ' ';
-  			}out('/Mask [' + trns + ']');
-  		}
-  		if ('smask' in img) {
-  			out('/SMask ' + (objectNumber + 1) + ' 0 R');
-  		}
-  		out('/Length ' + img['data'].length + '>>');
-
-  		putStream(img['data']);
-
-  		out('endobj');
-
-  		// Soft mask
-  		if ('smask' in img) {
-  			var dp = '/Predictor ' + img['p'] + ' /Colors 1 /BitsPerComponent ' + img['bpc'] + ' /Columns ' + img['w'];
-  			var smask = { 'w': img['w'], 'h': img['h'], 'cs': 'DeviceGray', 'bpc': img['bpc'], 'dp': dp, 'data': img['smask'] };
-  			if ('f' in img) smask.f = img['f'];
-  			putImage.call(this, smask);
-  		}
-
-  		//Palette
-  		if (img['cs'] === this.color_spaces.INDEXED) {
-
-  			this.internal.newObject();
-  			//out('<< /Filter / ' + img['f'] +' /Length ' + img['pal'].length + '>>');
-  			//putStream(zlib.compress(img['pal']));
-  			out('<< /Length ' + img['pal'].length + '>>');
-  			putStream(this.arrayBufferToBinaryString(new Uint8Array(img['pal'])));
-  			out('endobj');
-  		}
-  	},
-  	    putResourcesCallback = function putResourcesCallback() {
-  		var images = this.internal.collections[namespace + 'images'];
-  		for (var i in images) {
-  			putImage.call(this, images[i]);
-  		}
-  	},
-  	    putXObjectsDictCallback = function putXObjectsDictCallback() {
-  		var images = this.internal.collections[namespace + 'images'],
-  		    out = this.internal.write,
-  		    image;
-  		for (var i in images) {
-  			image = images[i];
-  			out('/I' + image['i'], image['n'], '0', 'R');
-  		}
-  	},
-  	    checkCompressValue = function checkCompressValue(value) {
-  		if (value && typeof value === 'string') value = value.toUpperCase();
-  		return value in jsPDFAPI.image_compression ? value : jsPDFAPI.image_compression.NONE;
-  	},
-  	    getImages = function getImages() {
-  		var images = this.internal.collections[namespace + 'images'];
-  		//first run, so initialise stuff
-  		if (!images) {
-  			this.internal.collections[namespace + 'images'] = images = {};
-  			this.internal.events.subscribe('putResources', putResourcesCallback);
-  			this.internal.events.subscribe('putXobjectDict', putXObjectsDictCallback);
-  		}
-
-  		return images;
-  	},
-  	    getImageIndex = function getImageIndex(images) {
-  		var imageIndex = 0;
-
-  		if (images) {
-  			// this is NOT the first time this method is ran on this instance of jsPDF object.
-  			imageIndex = Object.keys ? Object.keys(images).length : function (o) {
-  				var i = 0;
-  				for (var e in o) {
-  					if (o.hasOwnProperty(e)) {
-  						i++;
-  					}
-  				}
-  				return i;
-  			}(images);
-  		}
-
-  		return imageIndex;
-  	},
-  	    notDefined = function notDefined(value) {
-  		return typeof value === 'undefined' || value === null || value.length === 0;
-  	},
-  	    generateAliasFromData = function generateAliasFromData(data) {
-  		return typeof data === 'string' && jsPDFAPI.sHashCode(data);
-  	},
-  	    isImageTypeSupported = function isImageTypeSupported(type) {
-  		return typeof jsPDFAPI["process" + type.toUpperCase()] === "function";
-  	},
-  	    isDOMElement = function isDOMElement(object) {
-  		return (typeof object === 'undefined' ? 'undefined' : _typeof(object)) === 'object' && object.nodeType === 1;
-  	},
-  	    createDataURIFromElement = function createDataURIFromElement(element, format) {
-
-  		//if element is an image which uses data url definition, just return the dataurl
-  		if (element.nodeName === 'IMG' && element.hasAttribute('src')) {
-  			var src = '' + element.getAttribute('src');
-  			if (src.indexOf('data:image/') === 0) return src;
-
-  			// only if the user doesn't care about a format
-  			if (!format && /\.png(?:[?#].*)?$/i.test(src)) format = 'png';
-  		}
-
-  		if (element.nodeName === 'CANVAS') {
-  			var canvas = element;
-  		} else {
-  			var canvas = document.createElement('canvas');
-  			canvas.width = element.clientWidth || element.width;
-  			canvas.height = element.clientHeight || element.height;
-
-  			var ctx = canvas.getContext('2d');
-  			if (!ctx) {
-  				throw 'addImage requires canvas to be supported by browser.';
-  			}
-  			ctx.drawImage(element, 0, 0, canvas.width, canvas.height);
-  		}
-  		return canvas.toDataURL(('' + format).toLowerCase() == 'png' ? 'image/png' : 'image/jpeg');
-  	},
-  	    checkImagesForAlias = function checkImagesForAlias(alias, images) {
-  		var cached_info;
-  		if (images) {
-  			for (var e in images) {
-  				if (alias === images[e].alias) {
-  					cached_info = images[e];
-  					break;
-  				}
-  			}
-  		}
-  		return cached_info;
-  	},
-  	    determineWidthAndHeight = function determineWidthAndHeight(w, h, info) {
-  		if (!w && !h) {
-  			w = -96;
-  			h = -96;
-  		}
-  		if (w < 0) {
-  			w = -1 * info['w'] * 72 / w / this.internal.scaleFactor;
-  		}
-  		if (h < 0) {
-  			h = -1 * info['h'] * 72 / h / this.internal.scaleFactor;
-  		}
-  		if (w === 0) {
-  			w = h * info['w'] / info['h'];
-  		}
-  		if (h === 0) {
-  			h = w * info['h'] / info['w'];
-  		}
-
-  		return [w, h];
-  	},
-  	    writeImageToPDF = function writeImageToPDF(x, y, w, h, info, index, images, rotation) {
-  		var dims = determineWidthAndHeight.call(this, w, h, info),
-  		    coord = this.internal.getCoordinateString,
-  		    vcoord = this.internal.getVerticalCoordinateString;
-
-  		w = dims[0];
-  		h = dims[1];
-
-  		images[index] = info;
-
-  		if (rotation) {
-  			rotation *= Math.PI / 180;
-  			var c = Math.cos(rotation);
-  			var s = Math.sin(rotation);
-  			//like in pdf Reference do it 4 digits instead of 2
-  			var f4 = function f4(number) {
-  				return number.toFixed(4);
-  			};
-  			var rotationTransformationMatrix = [f4(c), f4(s), f4(s * -1), f4(c), 0, 0, 'cm'];
-  		}
-  		this.internal.write('q'); //Save graphics state
-  		if (rotation) {
-  			this.internal.write([1, '0', '0', 1, coord(x), vcoord(y + h), 'cm'].join(' ')); //Translate
-  			this.internal.write(rotationTransformationMatrix.join(' ')); //Rotate
-  			this.internal.write([coord(w), '0', '0', coord(h), '0', '0', 'cm'].join(' ')); //Scale
-  		} else {
-  			this.internal.write([coord(w), '0', '0', coord(h), coord(x), vcoord(y + h), 'cm'].join(' ')); //Translate and Scale
-  		}
-  		this.internal.write('/I' + info['i'] + ' Do'); //Paint Image
-  		this.internal.write('Q'); //Restore graphics state
-  	};
-
-  	/**
-    * COLOR SPACES
-    */
-  	jsPDFAPI.color_spaces = {
-  		DEVICE_RGB: 'DeviceRGB',
-  		DEVICE_GRAY: 'DeviceGray',
-  		DEVICE_CMYK: 'DeviceCMYK',
-  		CAL_GREY: 'CalGray',
-  		CAL_RGB: 'CalRGB',
-  		LAB: 'Lab',
-  		ICC_BASED: 'ICCBased',
-  		INDEXED: 'Indexed',
-  		PATTERN: 'Pattern',
-  		SEPARATION: 'Separation',
-  		DEVICE_N: 'DeviceN'
-  	};
-
-  	/**
-    * DECODE METHODS
-    */
-  	jsPDFAPI.decode = {
-  		DCT_DECODE: 'DCTDecode',
-  		FLATE_DECODE: 'FlateDecode',
-  		LZW_DECODE: 'LZWDecode',
-  		JPX_DECODE: 'JPXDecode',
-  		JBIG2_DECODE: 'JBIG2Decode',
-  		ASCII85_DECODE: 'ASCII85Decode',
-  		ASCII_HEX_DECODE: 'ASCIIHexDecode',
-  		RUN_LENGTH_DECODE: 'RunLengthDecode',
-  		CCITT_FAX_DECODE: 'CCITTFaxDecode'
-  	};
-
-  	/**
-    * IMAGE COMPRESSION TYPES
-    */
-  	jsPDFAPI.image_compression = {
-  		NONE: 'NONE',
-  		FAST: 'FAST',
-  		MEDIUM: 'MEDIUM',
-  		SLOW: 'SLOW'
-  	};
-
-  	jsPDFAPI.sHashCode = function (str) {
-  		str = str || "";
-  		return Array.prototype.reduce && str.split("").reduce(function (a, b) {
-  			a = (a << 5) - a + b.charCodeAt(0);return a & a;
-  		}, 0);
-  	};
-
-  	jsPDFAPI.isString = function (object) {
-  		return typeof object === 'string';
-  	};
-  	/**
-   * Validates if given String is a valid Base64-String
-   *
-   * @name validateStringAsBase64
-   * @public
-   * @function
-   * @param {String} possible Base64-String
-   * 
-   * @returns {boolean}
-   * @methodOf jsPDF#
-   */
-  	jsPDFAPI.validateStringAsBase64 = function (possibleBase64String) {
-  		possibleBase64String = possibleBase64String || '';
-
-  		var result = true;
-
-  		if (possibleBase64String.length % 4 !== 0) {
-  			result = false;
-  		}
-
-  		if (/[A-Za-z0-9\/]+/.test(possibleBase64String.substr(0, possibleBase64String.length - 2)) === false) {
-  			result = false;
-  		}
-
-  		if (/[A-Za-z0-9\/][A-Za-z0-9+\/]|[A-Za-z0-9+\/]=|==/.test(possibleBase64String.substr(-2)) === false) {
-  			result = false;
-  		}
-  		return result;
-  	};
-
-  	/**
-    * Strips out and returns info from a valid base64 data URI
-    * @param {String[dataURI]} a valid data URI of format 'data:[<MIME-type>][;base64],<data>'
-    * @returns an Array containing the following
-    * [0] the complete data URI
-    * [1] <MIME-type>
-    * [2] format - the second part of the mime-type i.e 'png' in 'image/png'
-    * [4] <data>
-    */
-  	jsPDFAPI.extractInfoFromBase64DataURI = function (dataURI) {
-  		return (/^data:([\w]+?\/([\w]+?));base64,(.+)$/g.exec(dataURI)
-  		);
-  	};
-
-  	/**
-    * Check to see if ArrayBuffer is supported
-    * 
-    * @returns {boolean}
-      * @methodOf jsPDF#
-    */
-  	jsPDFAPI.supportsArrayBuffer = function () {
-  		return typeof ArrayBuffer !== 'undefined' && typeof Uint8Array !== 'undefined';
-  	};
-
-  	/**
-    * Tests supplied object to determine if ArrayBuffer
-    * @param {Object[object]}
-    * 
-    * @returns {boolean}
-    * @methodOf jsPDF#
-    */
-  	jsPDFAPI.isArrayBuffer = function (object) {
-  		if (!this.supportsArrayBuffer()) return false;
-  		return object instanceof ArrayBuffer;
-  	};
-
-  	/**
-    * Tests supplied object to determine if it implements the ArrayBufferView (TypedArray) interface
-    * @param {Object[object]}
-    */
-  	jsPDFAPI.isArrayBufferView = function (object) {
-  		if (!this.supportsArrayBuffer()) return false;
-  		if (typeof Uint32Array === 'undefined') return false;
-  		return object instanceof Int8Array || object instanceof Uint8Array || typeof Uint8ClampedArray !== 'undefined' && object instanceof Uint8ClampedArray || object instanceof Int16Array || object instanceof Uint16Array || object instanceof Int32Array || object instanceof Uint32Array || object instanceof Float32Array || object instanceof Float64Array;
-  	};
-
-  	/**
-   * Convert the Buffer to a Binary String
-   *
-   * @name binaryStringToUint8Array
-   * @public
-   * @function
-   * @param {ArrayBuffer} BinaryString with ImageData
-   * 
-   * @returns {Uint8Array}
-   */
-  	jsPDFAPI.binaryStringToUint8Array = function (binary_string) {
-  		/*
-     * not sure how efficient this will be will bigger files. Is there a native method?
-     */
-  		var len = binary_string.length;
-  		var bytes = new Uint8Array(len);
-  		for (var i = 0; i < len; i++) {
-  			bytes[i] = binary_string.charCodeAt(i);
-  		}
-  		return bytes;
-  	};
-
-  	/**
-   * Convert the Buffer to a Binary String
-   *
-   * @name arrayBufferToBinaryString
-   * @public
-   * @function
-   * @param {ArrayBuffer} ArrayBuffer with ImageData
-   * 
-   * @returns {String}
-   */
-  	jsPDFAPI.arrayBufferToBinaryString = function (buffer) {
-
-  		if (typeof atob === "function") {
-  			return atob(this.arrayBufferToBase64(buffer));
-  		}
-
-  		if (typeof TextDecoder === "function") {
-  			var decoder = new TextDecoder('ascii');
-  			// test if the encoding is supported
-  			if (decoder.encoding === 'ascii') {
-  				return decoder.decode(buffer);
-  			}
-  		}
-
-  		//Fallback-solution
-  		var data = this.isArrayBuffer(buffer) ? buffer : new Uint8Array(buffer);
-  		var chunkSizeForSlice = 0x5000;
-  		var binary_string = '';
-  		var slicesCount = Math.ceil(data.byteLength / chunkSizeForSlice);
-  		for (var i = 0; i < slicesCount; i++) {
-  			binary_string += String.fromCharCode.apply(null, data.slice(i * chunkSizeForSlice, i * chunkSizeForSlice + chunkSizeForSlice));
-  		}
-  		return binary_string;
-  	};
-
-  	/**
-      * Converts an ArrayBuffer directly to base64
-      *
-      * Taken from  http://jsperf.com/encoding-xhr-image-data/31
-      *
-      * Need to test if this is a better solution for larger files
-      *
-      * @name arrayBufferToBase64
-      * @public
-      * @function
-      * 
-      * @returns {String}
-      */
-  	jsPDFAPI.arrayBufferToBase64 = function (arrayBuffer) {
-  		var base64 = '';
-  		var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
-
-  		var bytes = new Uint8Array(arrayBuffer);
-  		var byteLength = bytes.byteLength;
-  		var byteRemainder = byteLength % 3;
-  		var mainLength = byteLength - byteRemainder;
-
-  		var a, b, c, d;
-  		var chunk;
-
-  		// Main loop deals with bytes in chunks of 3
-  		for (var i = 0; i < mainLength; i = i + 3) {
-  			// Combine the three bytes into a single integer
-  			chunk = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
-
-  			// Use bitmasks to extract 6-bit segments from the triplet
-  			a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18
-  			b = (chunk & 258048) >> 12; // 258048   = (2^6 - 1) << 12
-  			c = (chunk & 4032) >> 6; // 4032     = (2^6 - 1) << 6
-  			d = chunk & 63; // 63       = 2^6 - 1
-
-  			// Convert the raw binary segments to the appropriate ASCII encoding
-  			base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d];
-  		}
-
-  		// Deal with the remaining bytes and padding
-  		if (byteRemainder == 1) {
-  			chunk = bytes[mainLength];
-
-  			a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2
-
-  			// Set the 4 least significant bits to zero
-  			b = (chunk & 3) << 4; // 3   = 2^2 - 1
-
-  			base64 += encodings[a] + encodings[b] + '==';
-  		} else if (byteRemainder == 2) {
-  			chunk = bytes[mainLength] << 8 | bytes[mainLength + 1];
-
-  			a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10
-  			b = (chunk & 1008) >> 4; // 1008  = (2^6 - 1) << 4
-
-  			// Set the 2 least significant bits to zero
-  			c = (chunk & 15) << 2; // 15    = 2^4 - 1
-
-  			base64 += encodings[a] + encodings[b] + encodings[c] + '=';
-  		}
-
-  		return base64;
-  	};
-
-  	/**
-      * Converts an ArrayBuffer directly to base64
-      *
-      * Taken from  http://jsperf.com/encoding-xhr-image-data/31
-      *
-      * Need to test if this is a better solution for larger files
-      *
-      * @public
-      * @function
-      * 
-      * @returns {String}
-      */
-  	jsPDFAPI.createImageInfo = function (data, wd, ht, cs, bpc, f, imageIndex, alias, dp, trns, pal, smask, p) {
-  		var info = {
-  			alias: alias,
-  			w: wd,
-  			h: ht,
-  			cs: cs,
-  			bpc: bpc,
-  			i: imageIndex,
-  			data: data
-  			// n: objectNumber will be added by putImage code
-  		};
-
-  		if (f) info.f = f;
-  		if (dp) info.dp = dp;
-  		if (trns) info.trns = trns;
-  		if (pal) info.pal = pal;
-  		if (smask) info.smask = smask;
-  		if (p) info.p = p; // predictor parameter for PNG compression
-
-  		return info;
-  	};
-  	/**
-   * Adds an Image to the PDF.
-   *
-   * @name addImage
-   * @public
-   * @function
-   * @param {String/Image-Element/Canvas-Element/Uint8Array} imageData as base64 encoded DataUrl or Image-HTMLElement or Canvas-HTMLElement
-   * @param {String} format of file if filetype-recognition fails, e.g. 'JPEG'
-   * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-   * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-   * @param {Number} width of the image (in units declared at inception of PDF document)
-   * @param {Number} height of the Image (in units declared at inception of PDF document)
-   * @param {String} alias of the image (if used multiple times)
-   * @param {String} compression of the generated JPEG, can have the values 'NONE', 'FAST', 'MEDIUM' and 'SLOW'
-   * @param {Number} rotation of the image in degrees (0-359)
-   * 
-   * @returns jsPDF
-   * @methodOf jsPDF#
-   */
-  	jsPDFAPI.addImage = function (imageData, format, x, y, w, h, alias, compression, rotation) {
-
-  		var tmpImageData = '';
-
-  		if (typeof format !== 'string') {
-  			var tmp = h;
-  			h = w;
-  			w = y;
-  			y = x;
-  			x = format;
-  			format = tmp;
-  		}
-
-  		if ((typeof imageData === 'undefined' ? 'undefined' : _typeof(imageData)) === 'object' && !isDOMElement(imageData) && "imageData" in imageData) {
-  			var options = imageData;
-
-  			imageData = options.imageData;
-  			format = options.format || format;
-  			x = options.x || x || 0;
-  			y = options.y || y || 0;
-  			w = options.w || w;
-  			h = options.h || h;
-  			alias = options.alias || alias;
-  			compression = options.compression || compression;
-  			rotation = options.rotation || options.angle || rotation;
-  		}
-
-  		if (isNaN(x) || isNaN(y)) {
-  			console.error('jsPDF.addImage: Invalid coordinates', arguments);
-  			throw new Error('Invalid coordinates passed to jsPDF.addImage');
-  		}
-
-  		var images = getImages.call(this),
-  		    info;
-
-  		if (!(info = checkImagesForAlias(imageData, images))) {
-  			var dataAsBinaryString;
-
-  			if (isDOMElement(imageData)) imageData = createDataURIFromElement(imageData, format);
-
-  			if (notDefined(alias)) alias = generateAliasFromData(imageData);
-
-  			if (!(info = checkImagesForAlias(alias, images))) {
-  				if (this.isString(imageData)) {
-  					tmpImageData = this.convertStringToImageData(imageData);
-
-  					if (tmpImageData !== '') {
-  						imageData = tmpImageData;
-  					} else {
-  						tmpImageData = this.loadImageFile(imageData);
-  						if (tmpImageData !== undefined) {
-  							imageData = tmpImageData;
-  						}
-  					}
-  				}
-  				format = this.getImageFileTypeByImageData(imageData, format);
-
-  				if (!isImageTypeSupported(format)) throw new Error('addImage does not support files of type \'' + format + '\', please ensure that a plugin for \'' + format + '\' support is added.');
-
-  				/**
-       * need to test if it's more efficient to convert all binary strings
-       * to TypedArray - or should we just leave and process as string?
-       */
-  				if (this.supportsArrayBuffer()) {
-  					// no need to convert if imageData is already uint8array
-  					if (!(imageData instanceof Uint8Array)) {
-  						dataAsBinaryString = imageData;
-  						imageData = this.binaryStringToUint8Array(imageData);
-  					}
-  				}
-
-  				info = this['process' + format.toUpperCase()](imageData, getImageIndex(images), alias, checkCompressValue(compression), dataAsBinaryString);
-
-  				if (!info) throw new Error('An unkwown error occurred whilst processing the image');
-  			}
-  		}
-  		writeImageToPDF.call(this, x, y, w, h, info, info.i, images, rotation);
-
-  		return this;
-  	};
-
-  	jsPDFAPI.convertStringToImageData = function (stringData) {
-  		var base64Info;
-  		var imageData = '';
-  		if (this.isString(stringData)) {
-  			var base64Info = this.extractInfoFromBase64DataURI(stringData);
-
-  			if (base64Info !== null) {
-  				if (jsPDFAPI.validateStringAsBase64(base64Info[3])) {
-  					imageData = atob(base64Info[3]); //convert to binary string
-  				}
-  			} else if (jsPDFAPI.validateStringAsBase64(stringData)) {
-  				imageData = atob(stringData);
-  			}
-  		}
-  		return imageData;
-  	};
-  	/**
-    * JPEG SUPPORT
-    **/
-
-  	//takes a string imgData containing the raw bytes of
-  	//a jpeg image and returns [width, height]
-  	//Algorithm from: http://www.64lines.com/jpeg-width-height
-  	var getJpegSize = function getJpegSize(imgData) {
-
-  		var width, height, numcomponents;
-  		// Verify we have a valid jpeg header 0xff,0xd8,0xff,0xe0,?,?,'J','F','I','F',0x00
-  		if (!imgData.charCodeAt(0) === 0xff || !imgData.charCodeAt(1) === 0xd8 || !imgData.charCodeAt(2) === 0xff || !imgData.charCodeAt(3) === 0xe0 || !imgData.charCodeAt(6) === 'J'.charCodeAt(0) || !imgData.charCodeAt(7) === 'F'.charCodeAt(0) || !imgData.charCodeAt(8) === 'I'.charCodeAt(0) || !imgData.charCodeAt(9) === 'F'.charCodeAt(0) || !imgData.charCodeAt(10) === 0x00) {
-  			throw new Error('getJpegSize requires a binary string jpeg file');
-  		}
-  		var blockLength = imgData.charCodeAt(4) * 256 + imgData.charCodeAt(5);
-  		var i = 4,
-  		    len = imgData.length;
-  		while (i < len) {
-  			i += blockLength;
-  			if (imgData.charCodeAt(i) !== 0xff) {
-  				throw new Error('getJpegSize could not find the size of the image');
-  			}
-  			if (imgData.charCodeAt(i + 1) === 0xc0 || //(SOF) Huffman  - Baseline DCT
-  			imgData.charCodeAt(i + 1) === 0xc1 || //(SOF) Huffman  - Extended sequential DCT
-  			imgData.charCodeAt(i + 1) === 0xc2 || // Progressive DCT (SOF2)
-  			imgData.charCodeAt(i + 1) === 0xc3 || // Spatial (sequential) lossless (SOF3)
-  			imgData.charCodeAt(i + 1) === 0xc4 || // Differential sequential DCT (SOF5)
-  			imgData.charCodeAt(i + 1) === 0xc5 || // Differential progressive DCT (SOF6)
-  			imgData.charCodeAt(i + 1) === 0xc6 || // Differential spatial (SOF7)
-  			imgData.charCodeAt(i + 1) === 0xc7) {
-  				height = imgData.charCodeAt(i + 5) * 256 + imgData.charCodeAt(i + 6);
-  				width = imgData.charCodeAt(i + 7) * 256 + imgData.charCodeAt(i + 8);
-  				numcomponents = imgData.charCodeAt(i + 9);
-  				return [width, height, numcomponents];
-  			} else {
-  				i += 2;
-  				blockLength = imgData.charCodeAt(i) * 256 + imgData.charCodeAt(i + 1);
-  			}
-  		}
-  	},
-  	    getJpegSizeFromBytes = function getJpegSizeFromBytes(data) {
-
-  		var hdr = data[0] << 8 | data[1];
-
-  		if (hdr !== 0xFFD8) throw new Error('Supplied data is not a JPEG');
-
-  		var len = data.length,
-  		    block = (data[4] << 8) + data[5],
-  		    pos = 4,
-  		    bytes,
-  		    width,
-  		    height,
-  		    numcomponents;
-
-  		while (pos < len) {
-  			pos += block;
-  			bytes = readBytes(data, pos);
-  			block = (bytes[2] << 8) + bytes[3];
-  			if ((bytes[1] === 0xC0 || bytes[1] === 0xC2) && bytes[0] === 0xFF && block > 7) {
-  				bytes = readBytes(data, pos + 5);
-  				width = (bytes[2] << 8) + bytes[3];
-  				height = (bytes[0] << 8) + bytes[1];
-  				numcomponents = bytes[4];
-  				return { width: width, height: height, numcomponents: numcomponents };
-  			}
-
-  			pos += 2;
-  		}
-
-  		throw new Error('getJpegSizeFromBytes could not find the size of the image');
-  	},
-  	    readBytes = function readBytes(data, offset) {
-  		return data.subarray(offset, offset + 5);
-  	};
-
-  	jsPDFAPI.processJPEG = function (data, index, alias, compression, dataAsBinaryString, colorSpace) {
-
-  		var filter = this.decode.DCT_DECODE,
-  		    bpc = 8,
-  		    dims;
-
-  		if (!this.isString(data) && !this.isArrayBuffer(data) && !this.isArrayBufferView(data)) {
-  			return null;
-  		}
-
-  		if (this.isString(data)) {
-  			dims = getJpegSize(data);
-  		}
-
-  		if (this.isArrayBuffer(data)) {
-  			data = new Uint8Array(data);
-  		}
-  		if (this.isArrayBufferView(data)) {
-
-  			dims = getJpegSizeFromBytes(data);
-
-  			// if we already have a stored binary string rep use that
-  			data = dataAsBinaryString || this.arrayBufferToBinaryString(data);
-  		}
-
-  		if (colorSpace === undefined) {
-  			switch (dims.numcomponents) {
-  				case 1:
-  					colorSpace = this.color_spaces.DEVICE_GRAY;
-  					break;
-  				case 4:
-  					colorSpace = this.color_spaces.DEVICE_CMYK;
-  					break;
-  				default:
-  				case 3:
-  					colorSpace = this.color_spaces.DEVICE_RGB;
-  					break;
-  			}
-  		}
-
-  		return this.createImageInfo(data, dims.width, dims.height, colorSpace, bpc, filter, index, alias);
-  	};
-
-  	jsPDFAPI.processJPG = function () /*data, index, alias, compression, dataAsBinaryString*/{
-  		return this.processJPEG.apply(this, arguments);
-  	};
-
-  	jsPDFAPI.loadImageFile = function (path, sync, callback) {
-  		sync = sync || true;
-  		callback = callback || function () {};
-  		var isNode = Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
-
-  		var xhrMethod = function xhrMethod(url, sync, callback) {
-  			var req = new XMLHttpRequest();
-  			var byteArray = [];
-  			var i = 0;
-
-  			var sanitizeUnicode = function sanitizeUnicode(data) {
-  				var dataLength = data.length;
-  				var StringFromCharCode = String.fromCharCode;
-
-  				//Transform Unicode to ASCII
-  				for (i = 0; i < dataLength; i += 1) {
-  					byteArray.push(StringFromCharCode(data.charCodeAt(i) & 0xff));
-  				}
-  				return byteArray.join("");
-  			};
-
-  			req.open('GET', url, !sync);
-  			// XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
-  			req.overrideMimeType('text\/plain; charset=x-user-defined');
-
-  			if (sync === false) {
-  				req.onload = function () {
-  					return sanitizeUnicode(this.responseText);
-  				};
-  			}
-  			req.send(null);
-
-  			if (req.status !== 200) {
-  				console.warn('Unable to load file "' + url + '"');
-  				return;
-  			}
-
-  			if (sync) {
-  				return sanitizeUnicode(req.responseText);
-  			}
-  		};
-
-  		//we have a browser and probably no CORS-Problem
-  		if ((typeof window === 'undefined' ? 'undefined' : _typeof(window)) !== undefined && (typeof location === 'undefined' ? 'undefined' : _typeof(location)) === "object" && location.protocol.substr(0, 4) === "http") {
-  			return xhrMethod(path, sync, callback);
-  		}
-  	};
-
-  	jsPDFAPI.getImageProperties = function (imageData) {
-  		var info;
-  		var tmpImageData = '';
-  		var format;
-
-  		if (isDOMElement(imageData)) {
-  			imageData = createDataURIFromElement(imageData);
-  		}
-
-  		if (this.isString(imageData)) {
-  			tmpImageData = this.convertStringToImageData(imageData);
-
-  			if (tmpImageData !== '') {
-  				imageData = tmpImageData;
-  			} else {
-  				tmpImageData = this.loadImageFile(imageData);
-  				if (tmpImageData !== undefined) {
-  					imageData = tmpImageData;
-  				}
-  			}
-  		}
-  		format = this.getImageFileTypeByImageData(imageData);
-
-  		if (!isImageTypeSupported(format)) throw new Error('addImage does not support files of type \'' + format + '\', please ensure that a plugin for \'' + format + '\' support is added.');
-
-  		/**
-     * need to test if it's more efficient to convert all binary strings
-     * to TypedArray - or should we just leave and process as string?
-     */
-  		if (this.supportsArrayBuffer()) {
-  			// no need to convert if imageData is already uint8array
-  			if (!(imageData instanceof Uint8Array)) {
-  				imageData = this.binaryStringToUint8Array(imageData);
-  			}
-  		}
-
-  		info = this['process' + format.toUpperCase()](imageData);
-
-  		if (!info) {
-  			throw new Error('An unkwown error occurred whilst processing the image');
-  		}
-
-  		return {
-  			fileType: format,
-  			width: info.w,
-  			height: info.h,
-  			colorSpace: info.cs,
-  			compressionMode: info.f,
-  			bitsPerComponent: info.bpc
-  		};
-  	};
-  })(jsPDF.API);
-
-  /**
-   * jsPDF Annotations PlugIn
-   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
-
-  /**
-   * There are many types of annotations in a PDF document. Annotations are placed
-   * on a page at a particular location. They are not 'attached' to an object.
-   * <br />
-   * This plugin current supports <br />
-   * <li> Goto Page (set pageNumber and top in options)
-   * <li> Goto Name (set name and top in options)
-   * <li> Goto URL (set url in options)
-   * <p>
-   * 	The destination magnification factor can also be specified when goto is a page number or a named destination. (see documentation below)
-   *  (set magFactor in options).  XYZ is the default.
-   * </p>
-   * <p>
-   *  Links, Text, Popup, and FreeText are supported.
-   * </p>
-   * <p>
-   * Options In PDF spec Not Implemented Yet
-   * <li> link border
-   * <li> named target
-   * <li> page coordinates
-   * <li> destination page scaling and layout
-   * <li> actions other than URL and GotoPage
-   * <li> background / hover actions
-   * </p>
-   */
-
-  /*
-      Destination Magnification Factors
-      See PDF 1.3 Page 386 for meanings and options
-
-      [supported]
-  	XYZ (options; left top zoom)
-  	Fit (no options)
-  	FitH (options: top)
-  	FitV (options: left)
-
-  	[not supported]
-  	FitR
-  	FitB
-  	FitBH
-  	FitBV
-   */
-
-  (function (jsPDFAPI) {
-
-  	var annotationPlugin = {
-
-  		/**
-     * An array of arrays, indexed by <em>pageNumber</em>.
-     */
-  		annotations: [],
-
-  		f2: function f2(number) {
-  			return number.toFixed(2);
-  		},
-
-  		notEmpty: function notEmpty(obj) {
-  			if (typeof obj != 'undefined') {
-  				if (obj != '') {
-  					return true;
-  				}
-  			}
-  		}
-  	};
-
-  	jsPDF.API.annotationPlugin = annotationPlugin;
-
-  	jsPDF.API.events.push(['addPage', function (info) {
-  		this.annotationPlugin.annotations[info.pageNumber] = [];
-  	}]);
-
-  	jsPDFAPI.events.push(['putPage', function (info) {
-  		//TODO store annotations in pageContext so reorder/remove will not affect them.
-  		var pageAnnos = this.annotationPlugin.annotations[info.pageNumber];
-
-  		var found = false;
-  		for (var a = 0; a < pageAnnos.length && !found; a++) {
-  			var anno = pageAnnos[a];
-  			switch (anno.type) {
-  				case 'link':
-  					if (annotationPlugin.notEmpty(anno.options.url) || annotationPlugin.notEmpty(anno.options.pageNumber)) {
-  						found = true;
-  						break;
-  					}
-  				case 'reference':
-  				case 'text':
-  				case 'freetext':
-  					found = true;
-  					break;
-  			}
-  		}
-  		if (found == false) {
-  			return;
-  		}
-
-  		this.internal.write("/Annots [");
-  		var f2 = this.annotationPlugin.f2;
-  		var k = this.internal.scaleFactor;
-  		var pageHeight = this.internal.pageSize.getHeight();
-  		var pageInfo = this.internal.getPageInfo(info.pageNumber);
-  		for (var a = 0; a < pageAnnos.length; a++) {
-  			var anno = pageAnnos[a];
-
-  			switch (anno.type) {
-  				case 'reference':
-  					// References to Widget Anotations (for AcroForm Fields)
-  					this.internal.write(' ' + anno.object.objId + ' 0 R ');
-  					break;
-  				case 'text':
-  					// Create a an object for both the text and the popup
-  					var objText = this.internal.newAdditionalObject();
-  					var objPopup = this.internal.newAdditionalObject();
-
-  					var title = anno.title || 'Note';
-  					var rect = "/Rect [" + f2(anno.bounds.x * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + " " + f2((anno.bounds.x + anno.bounds.w) * k) + " " + f2((pageHeight - anno.bounds.y) * k) + "] ";
-  					line = '<</Type /Annot /Subtype /' + 'Text' + ' ' + rect + '/Contents (' + anno.contents + ')';
-  					line += ' /Popup ' + objPopup.objId + " 0 R";
-  					line += ' /P ' + pageInfo.objId + " 0 R";
-  					line += ' /T (' + title + ') >>';
-  					objText.content = line;
-
-  					var parent = objText.objId + ' 0 R';
-  					var popoff = 30;
-  					var rect = "/Rect [" + f2((anno.bounds.x + popoff) * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + " " + f2((anno.bounds.x + anno.bounds.w + popoff) * k) + " " + f2((pageHeight - anno.bounds.y) * k) + "] ";
-  					//var rect2 = "/Rect [" + f2(anno.bounds.x * k) + " " + f2((pageHeight - anno.bounds.y) * k) + " " + f2(anno.bounds.x + anno.bounds.w * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + "] ";
-  					line = '<</Type /Annot /Subtype /' + 'Popup' + ' ' + rect + ' /Parent ' + parent;
-  					if (anno.open) {
-  						line += ' /Open true';
-  					}
-  					line += ' >>';
-  					objPopup.content = line;
-
-  					this.internal.write(objText.objId, '0 R', objPopup.objId, '0 R');
-
-  					break;
-  				case 'freetext':
-  					var rect = "/Rect [" + f2(anno.bounds.x * k) + " " + f2((pageHeight - anno.bounds.y) * k) + " " + f2(anno.bounds.x + anno.bounds.w * k) + " " + f2(pageHeight - (anno.bounds.y + anno.bounds.h) * k) + "] ";
-  					var color = anno.color || '#000000';
-  					line = '<</Type /Annot /Subtype /' + 'FreeText' + ' ' + rect + '/Contents (' + anno.contents + ')';
-  					line += ' /DS(font: Helvetica,sans-serif 12.0pt; text-align:left; color:#' + color + ')';
-  					line += ' /Border [0 0 0]';
-  					line += ' >>';
-  					this.internal.write(line);
-  					break;
-  				case 'link':
-  					if (anno.options.name) {
-  						var loc = this.annotations._nameMap[anno.options.name];
-  						anno.options.pageNumber = loc.page;
-  						anno.options.top = loc.y;
-  					} else {
-  						if (!anno.options.top) {
-  							anno.options.top = 0;
-  						}
-  					}
-
-  					var rect = "/Rect [" + f2(anno.x * k) + " " + f2((pageHeight - anno.y) * k) + " " + f2((anno.x + anno.w) * k) + " " + f2((pageHeight - (anno.y + anno.h)) * k) + "] ";
-
-  					var line = '';
-  					if (anno.options.url) {
-  						line = '<</Type /Annot /Subtype /Link ' + rect + '/Border [0 0 0] /A <</S /URI /URI (' + anno.options.url + ') >>';
-  					} else if (anno.options.pageNumber) {
-  						// first page is 0
-  						var info = this.internal.getPageInfo(anno.options.pageNumber);
-  						line = '<</Type /Annot /Subtype /Link ' + rect + '/Border [0 0 0] /Dest [' + info.objId + " 0 R";
-  						anno.options.magFactor = anno.options.magFactor || "XYZ";
-  						switch (anno.options.magFactor) {
-  							case 'Fit':
-  								line += ' /Fit]';
-  								break;
-  							case 'FitH':
-  								//anno.options.top = anno.options.top || f2(pageHeight * k);
-  								line += ' /FitH ' + anno.options.top + ']';
-  								break;
-  							case 'FitV':
-  								anno.options.left = anno.options.left || 0;
-  								line += ' /FitV ' + anno.options.left + ']';
-  								break;
-  							case 'XYZ':
-  							default:
-  								var top = f2((pageHeight - anno.options.top) * k); // || f2(pageHeight * k);
-  								anno.options.left = anno.options.left || 0;
-  								// 0 or null zoom will not change zoom factor
-  								if (typeof anno.options.zoom === 'undefined') {
-  									anno.options.zoom = 0;
-  								}
-  								line += ' /XYZ ' + anno.options.left + ' ' + top + ' ' + anno.options.zoom + ']';
-  								break;
-  						}
-  					}
-  					if (line != '') {
-  						line += " >>";
-  						this.internal.write(line);
-  					}
-  					break;
-  			}
-  		}
-  		this.internal.write("]");
-  	}]);
-
-  	jsPDFAPI.createAnnotation = function (options) {
-  		switch (options.type) {
-  			case 'link':
-  				this.link(options.bounds.x, options.bounds.y, options.bounds.w, options.bounds.h, options);
-  				break;
-  			case 'text':
-  			case 'freetext':
-  				this.annotationPlugin.annotations[this.internal.getCurrentPageInfo().pageNumber].push(options);
-  				break;
-  		}
-  	};
-
-  	/**
-    * valid options
-    * <li> pageNumber or url [required]
-    * <p>If pageNumber is specified, top and zoom may also be specified</p>
-    */
-  	jsPDFAPI.link = function (x, y, w, h, options) {
-
-  		this.annotationPlugin.annotations[this.internal.getCurrentPageInfo().pageNumber].push({
-  			x: x,
-  			y: y,
-  			w: w,
-  			h: h,
-  			options: options,
-  			type: 'link'
-  		});
-  	};
-
-  	/**
-    * Currently only supports single line text.
-    * Returns the width of the text/link
-    */
-  	jsPDFAPI.textWithLink = function (text, x, y, options) {
-
-  		var width = this.getTextWidth(text);
-  		var height = this.internal.getLineHeight() / this.internal.scaleFactor;
-  		this.text(text, x, y);
-  		//TODO We really need the text baseline height to do this correctly.
-  		// Or ability to draw text on top, bottom, center, or baseline.
-  		y += height * .2;
-  		this.link(x, y - height, width, height, options);
-  		return width;
-  	};
-
-  	//TODO move into external library
-  	jsPDFAPI.getTextWidth = function (text) {
-
-  		var fontSize = this.internal.getFontSize();
-  		var txtWidth = this.getStringUnitWidth(text) * fontSize / this.internal.scaleFactor;
-  		return txtWidth;
-  	};
-
-  	//TODO move into external library
-  	jsPDFAPI.getLineHeight = function () {
-  		return this.internal.getLineHeight();
-  	};
-
-  	return this;
-  })(jsPDF.API);
-
-  (function (jsPDFAPI) {
-
-      var arLangCodes = {
-          "ar": "Arabic (Standard)",
-          "ar-DZ": "Arabic (Algeria)",
-          "ar-BH": "Arabic (Bahrain)",
-          "ar-EG": "Arabic (Egypt)",
-          "ar-IQ": "Arabic (Iraq)",
-          "ar-JO": "Arabic (Jordan)",
-          "ar-KW": "Arabic (Kuwait)",
-          "ar-LB": "Arabic (Lebanon)",
-          "ar-LY": "Arabic (Libya)",
-          "ar-MA": "Arabic (Morocco)",
-          "ar-OM": "Arabic (Oman)",
-          "ar-QA": "Arabic (Qatar)",
-          "ar-SA": "Arabic (Saudi Arabia)",
-          "ar-SY": "Arabic (Syria)",
-          "ar-TN": "Arabic (Tunisia)",
-          "ar-AE": "Arabic (U.A.E.)",
-          "ar-YE": "Arabic (Yemen)",
-          "fa": "Persian",
-          "fa-IR": "Persian/Iran",
-          "ur": "Urdu"
-      };
-
-      var arLangCodesKeys = Object.keys(arLangCodes);
-
-      /**
-       * Arabic shape substitutions: char code => (isolated, final, initial, medial).
-       */
-      var arabicSubst = {
-          1569: [65152],
-          1570: [65153, 65154, 65153, 65154],
-          1571: [65155, 65156, 65155, 65156],
-          1572: [65157, 65158],
-          1573: [65159, 65160, 65159, 65160],
-          1574: [65161, 65162, 65163, 65164],
-          1575: [65165, 65166, 65165, 65166],
-          1576: [65167, 65168, 65169, 65170],
-          1577: [65171, 65172],
-          1578: [65173, 65174, 65175, 65176],
-          1579: [65177, 65178, 65179, 65180],
-          1580: [65181, 65182, 65183, 65184],
-          1581: [65185, 65186, 65187, 65188],
-          1582: [65189, 65190, 65191, 65192],
-          1583: [65193, 65194, 65193],
-          1584: [65195, 65196, 65195],
-          1585: [65197, 65198, 65197],
-          1586: [65199, 65200, 65199],
-          1587: [65201, 65202, 65203, 65204],
-          1588: [65205, 65206, 65207, 65208],
-          1589: [65209, 65210, 65211, 65212],
-          1590: [65213, 65214, 65215, 65216],
-          1591: [65217, 65218, 65219, 65220],
-          1592: [65221, 65222, 65223, 65224],
-          1593: [65225, 65226, 65227, 65228],
-          1594: [65229, 65230, 65231, 65232],
-          1601: [65233, 65234, 65235, 65236],
-          1602: [65237, 65238, 65239, 65240],
-          1603: [65241, 65242, 65243, 65244],
-          1604: [65245, 65246, 65247, 65248],
-          1605: [65249, 65250, 65251, 65252],
-          1606: [65253, 65254, 65255, 65256],
-          1607: [65257, 65258, 65259, 65260],
-          1608: [65261, 65262, 65261],
-          1609: [65263, 65264, 64488, 64489],
-          1610: [65265, 65266, 65267, 65268],
-          1649: [64336, 64337],
-          1655: [64477],
-          1657: [64358, 64359, 64360, 64361],
-          1658: [64350, 64351, 64352, 64353],
-          1659: [64338, 64339, 64340, 64341],
-          1662: [64342, 64343, 64344, 64345],
-          1663: [64354, 64355, 64356, 64357],
-          1664: [64346, 64347, 64348, 64349],
-          1667: [64374, 64375, 64376, 64377],
-          1668: [64370, 64371, 64372, 64373],
-          1670: [64378, 64379, 64380, 64381],
-          1671: [64382, 64383, 64384, 64385],
-          1672: [64392, 64393],
-          1676: [64388, 64389],
-          1677: [64386, 64387],
-          1678: [64390, 64391],
-          1681: [64396, 64397],
-          1688: [64394, 64395, 64394],
-          1700: [64362, 64363, 64364, 64365],
-          1702: [64366, 64367, 64368, 64369],
-          1705: [64398, 64399, 64400, 64401],
-          1709: [64467, 64468, 64469, 64470],
-          1711: [64402, 64403, 64404, 64405],
-          1713: [64410, 64411, 64412, 64413],
-          1715: [64406, 64407, 64408, 64409],
-          1722: [64414, 64415],
-          1723: [64416, 64417, 64418, 64419],
-          1726: [64426, 64427, 64428, 64429],
-          1728: [64420, 64421],
-          1729: [64422, 64423, 64424, 64425],
-          1733: [64480, 64481],
-          1734: [64473, 64474],
-          1735: [64471, 64472],
-          1736: [64475, 64476],
-          1737: [64482, 64483],
-          1739: [64478, 64479],
-          1740: [64508, 64509, 64510, 64511],
-          1744: [64484, 64485, 64486, 64487],
-          1746: [64430, 64431],
-          1747: [64432, 64433]
-      };
-      var arabiclaasubst = {
-          1570: [65269, 65270, 65269, 65270],
-          1571: [65271, 65272, 65271, 65272],
-          1573: [65273, 65274, 65273, 65274],
-          1575: [65275, 65276, 65275, 65276]
-      };
-      var arabicorigsubst = {
-          1570: [65153, 65154, 65153, 65154],
-          1571: [65155, 65156, 65155, 65156],
-          1573: [65159, 65160, 65159, 65160],
-          1575: [65165, 65166, 65165, 65166]
-      };
-      var arabic_diacritics = {
-          1612: 64606, // Shadda + Dammatan
-          1613: 64607, // Shadda + Kasratan
-          1614: 64608, // Shadda + Fatha
-          1615: 64609, // Shadda + Damma
-          1616: 64610 // Shadda + Kasra
-      };
-
-      var alfletter = [1570, 1571, 1573, 1575];
-      var endedletter = [1569, 1570, 1571, 1572, 1573, 1575, 1577, 1583, 1584, 1585, 1586, 1608, 1688];
-
-      var isolatedForm = 0;
-      var finalForm = 1;
-      var initialForm = 2;
-      var medialForm = 3;
-
-      //private
-      function isArabicLetter(letter) {
-          return letter !== undefined && arabicSubst[letter.charCodeAt(0)] !== undefined;
-      }
-
-      function isArabicEndLetter(letter) {
-          return letter !== undefined && endedletter.indexOf(letter.charCodeAt(0)) >= 0;
-      }
-
-      function isArabicAlfLetter(letter) {
-          return letter !== undefined && alfletter.indexOf(letter.charCodeAt(0)) >= 0;
-      }
-
-      function arabicLetterHasFinalForm(letter) {
-          return isArabicLetter(letter) && arabicSubst[letter.charCodeAt(0)].length >= 2;
-      }
-
-      function arabicLetterHasMedialForm(letter) {
-          return isArabicLetter(letter) && arabicSubst[letter.charCodeAt(0)].length == 4;
-      }
-
-      function isArabicDiacritic(letter) {
-          return letter !== undefined && arabic_diacritics[letter.charCodeAt(0)] !== undefined;
-      }
-
-      function getCorrectForm(currentChar, beforeChar, nextChar, arabicSubstition) {
-          if (!isArabicLetter(currentChar)) {
-              return -1;
-          }
-
-          arabicSubstition = arabicSubstition || {};
-          arabicSubst = Object.assign(arabicSubst, arabicSubstition);
-
-          if (!arabicLetterHasFinalForm(currentChar) || !isArabicLetter(beforeChar) && !isArabicLetter(nextChar) || !isArabicLetter(nextChar) && isArabicEndLetter(beforeChar) || isArabicEndLetter(currentChar) && !isArabicLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicAlfLetter(beforeChar) || isArabicEndLetter(currentChar) && isArabicEndLetter(beforeChar)) {
-              arabicSubst = Object.assign(arabicSubst, arabicorigsubst);
-              return isolatedForm;
-          }
-
-          if (arabicLetterHasMedialForm(currentChar) && isArabicLetter(beforeChar) && !isArabicEndLetter(beforeChar) && isArabicLetter(nextChar) && arabicLetterHasFinalForm(nextChar)) {
-              arabicSubst = Object.assign(arabicSubst, arabicorigsubst);
-              return medialForm;
-          }
-
-          if (isArabicEndLetter(currentChar) || !isArabicLetter(nextChar)) {
-              arabicSubst = Object.assign(arabicSubst, arabicorigsubst);
-              return finalForm;
-          }
-
-          arabicSubst = Object.assign(arabicSubst, arabicorigsubst);
-          return initialForm;
-      }
-
-      var commonSubstition = function commonSubstition(character) {
-          var replacementTable = {
-              '(': ')',
-              ')': '('
-          };
-          return replacementTable[character] || character;
-      };
-
-      var processArabic = jsPDFAPI.processArabic = function (text, reverse) {
-          text = text || "";
-          reverse = reverse || false;
-
-          var result = "";
-          var i = 0;
-          var position = 0;
-          var currentLetter = "";
-          var prevLetter = "";
-          var nextLetter = "";
-          var resultingLetter;
-
-          var localPrevLetter;
-          var localCurrentLetter;
-          var localNextLetter;
-
-          for (i = 0; i < text.length; i += 1) {
-              currentLetter = text[i];
-              prevLetter = text[i - 1];
-              nextLetter = text[i + 1];
-              if (!isArabicLetter(currentLetter)) {
-                  result += reverse ? commonSubstition(currentLetter) : currentLetter;
-              } else {
-                  if (prevLetter !== undefined && prevLetter.charCodeAt(0) === 1604 && isArabicAlfLetter(currentLetter)) {
-                      localPrevLetter = text[i - 2];
-                      localCurrentLetter = currentLetter;
-                      localNextLetter = text[i + 1];
-                      position = getCorrectForm(localCurrentLetter, localPrevLetter, localNextLetter, arabiclaasubst);
-                      resultingLetter = String.fromCharCode(arabiclaasubst[currentLetter.charCodeAt(0)][position]);
-                      result = result.substr(0, result.length - 1) + resultingLetter;
-                  } else if (prevLetter !== undefined && prevLetter.charCodeAt(0) === 1617 && isArabicDiacritic(currentLetter)) {
-                      localPrevLetter = text[i - 2];
-                      localCurrentLetter = currentLetter;
-                      localNextLetter = text[i + 1];
-                      position = getCorrectForm(localCurrentLetter, localPrevLetter, localNextLetter, arabicorigsubst);
-                      resultingLetter = String.fromCharCode(arabic_diacritics[currentLetter.charCodeAt(0)][position]);
-                      result = result.substr(0, result.length - 1) + resultingLetter;
-                  } else {
-                      position = getCorrectForm(currentLetter, prevLetter, nextLetter, arabicorigsubst);
-                      result += String.fromCharCode(arabicSubst[currentLetter.charCodeAt(0)][position]);
-                  }
-              }
-          }
-          return reverse ? result.split("").reverse().join("") : result;
-      };
-
-      var arabicParserFunction = function arabicParserFunction(args) {
-          var text = args.text;
-          var x = args.x;
-          var y = args.y;
-          var options = args.options || {};
-          var mutex = args.mutex || {};
-          var lang = options.lang;
-          var tmpText = [];
-
-          if (arLangCodesKeys.indexOf(lang) >= 0) {
-              if (Object.prototype.toString.call(text) === '[object Array]') {
-                  var i = 0;
-                  tmpText = [];
-                  for (i = 0; i < text.length; i += 1) {
-                      if (Object.prototype.toString.call(text[i]) === '[object Array]') {
-                          tmpText.push([processArabic(text[i][0], true), text[i][1], text[i][2]]);
-                      } else {
-                          tmpText.push([processArabic(text[i], true)]);
-                      }
-                  }
-                  args.text = tmpText;
-              } else {
-                  args.text = processArabic(text, true);
-              }
-              //force charSpace if not given.
-              if (options.charSpace === undefined) {
-                  args.options.charSpace = 0;
-              }
-              //if R2L is true, set it false.
-              if (options.R2L === true) {
-                  args.options.R2L = false;
-              }
-          }
-      };
-
-      jsPDFAPI.events.push(['preProcessText', arabicParserFunction]);
-  })(jsPDF.API);
-
-  /**
-   * jsPDF Autoprint Plugin
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
-
-  /**
-  * Makes the PDF automatically print. This works in Chrome, Firefox, Acrobat
-  * Reader.
-  *
-  * @returns {jsPDF}
-  * @name autoPrint
-  * @example
-  * var doc = new jsPDF()
-  * doc.text(10, 10, 'This is a test')
-  * doc.autoPrint()
-  * doc.save('autoprint.pdf')
-  */
-
-  (function (jsPDFAPI) {
-
-    jsPDFAPI.autoPrint = function (options) {
-
-      var refAutoPrintTag;
-      options = options || {};
-      options.variant = options.variant || 'non-conform';
-
-      switch (options.variant) {
-        case 'javascript':
-          //https://github.com/Rob--W/pdf.js/commit/c676ecb5a0f54677b9f3340c3ef2cf42225453bb
-          this.addJS('print({});');
-          break;
-        case 'non-conform':
-        default:
-          this.internal.events.subscribe('postPutResources', function () {
-            refAutoPrintTag = this.internal.newObject();
-            this.internal.out("<<");
-            this.internal.out("/S /Named");
-            this.internal.out("/Type /Action");
-            this.internal.out("/N /Print");
-            this.internal.out(">>");
-            this.internal.out("endobj");
-          });
-
-          this.internal.events.subscribe("putCatalog", function () {
-            this.internal.out("/OpenAction " + refAutoPrintTag + " 0 R");
-          });
-          break;
-      }
-      return this;
-    };
-  })(jsPDF.API);
-
-  /**
-   * jsPDF Canvas PlugIn
-   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
-
-  /**
-   * This plugin mimics the HTML5 Canvas
-   * 
-   * The goal is to provide a way for current canvas users to print directly to a PDF.
-   */
-
-  (function (jsPDFAPI) {
-
-  	jsPDFAPI.events.push(['initialized', function () {
-  		this.canvas.pdf = this;
-  	}]);
-
-  	jsPDFAPI.canvas = {
-  		getContext: function getContext(name) {
-  			this.pdf.context2d._canvas = this;
-  			return this.pdf.context2d;
-  		},
-  		childNodes: []
-  	};
-
-  	Object.defineProperty(jsPDFAPI.canvas, 'width', {
-  		get: function get() {
-  			return this._width;
-  		},
-  		set: function set(value) {
-  			this._width = value;
-  			this.getContext('2d').pageWrapX = value + 1;
-  		}
-  	});
-
-  	Object.defineProperty(jsPDFAPI.canvas, 'height', {
-  		get: function get() {
-  			return this._height;
-  		},
-  		set: function set(value) {
-  			this._height = value;
-  			this.getContext('2d').pageWrapY = value + 1;
-  		}
-  	});
-
-  	return this;
-  })(jsPDF.API);
-
-  /** ====================================================================
-   * jsPDF Cell plugin
-   * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
-   *               2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
-   *               2013 Lee Driscoll, https://github.com/lsdriscoll
-   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
-   *               2014 James Hall, james@parall.ax
-   *               2014 Diego Casorran, https://github.com/diegocr
-   *
-   * 
-   * ====================================================================
-   */
-
-  (function (jsPDFAPI) {
-      /*jslint browser:true */
-      /*global document: false, jsPDF */
-
-      var fontName,
-          fontSize,
-          fontStyle,
-          padding = 3,
-          margin = 13,
-          headerFunction,
-          lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined },
-          pages = 1,
-          setLastCellPosition = function setLastCellPosition(x, y, w, h, ln) {
-          lastCellPos = { 'x': x, 'y': y, 'w': w, 'h': h, 'ln': ln };
-      },
-          getLastCellPosition = function getLastCellPosition() {
-          return lastCellPos;
-      },
-          NO_MARGINS = { left: 0, top: 0, bottom: 0 };
-
-      jsPDFAPI.setHeaderFunction = function (func) {
-          headerFunction = func;
-      };
-
-      jsPDFAPI.getTextDimensions = function (txt) {
-          fontName = this.internal.getFont().fontName;
-          fontSize = this.table_font_size || this.internal.getFontSize();
-          fontStyle = this.internal.getFont().fontStyle;
-          // 1 pixel = 0.264583 mm and 1 mm = 72/25.4 point
-          var px2pt = 0.264583 * 72 / 25.4,
-              dimensions,
-              text;
-
-          text = document.createElement('font');
-          text.id = "jsPDFCell";
-
-          try {
-              text.style.fontStyle = fontStyle;
-          } catch (e) {
-              text.style.fontWeight = fontStyle;
-          }
-
-          text.style.fontSize = fontSize + 'pt';
-          text.style.fontFamily = fontName;
-          try {
-              text.textContent = txt;
-          } catch (e) {
-              text.innerText = txt;
-          }
-
-          document.body.appendChild(text);
-
-          dimensions = { w: (text.offsetWidth + 1) * px2pt, h: (text.offsetHeight + 1) * px2pt };
-
-          document.body.removeChild(text);
-
-          return dimensions;
-      };
-
-      jsPDFAPI.cellAddPage = function () {
-          var margins = this.margins || NO_MARGINS;
-
-          this.addPage();
-
-          setLastCellPosition(margins.left, margins.top, undefined, undefined);
-          //setLastCellPosition(undefined, undefined, undefined, undefined, undefined);
-          pages += 1;
-      };
-
-      jsPDFAPI.cellInitialize = function () {
-          lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined };
-          pages = 1;
-      };
-
-      jsPDFAPI.cell = function (x, y, w, h, txt, ln, align) {
-          var curCell = getLastCellPosition();
-          var pgAdded = false;
-
-          // If this is not the first cell, we must change its position
-          if (curCell.ln !== undefined) {
-              if (curCell.ln === ln) {
-                  //Same line
-                  x = curCell.x + curCell.w;
-                  y = curCell.y;
-              } else {
-                  //New line
-                  var margins = this.margins || NO_MARGINS;
-                  if (curCell.y + curCell.h + h + margin >= this.internal.pageSize.getHeight() - margins.bottom) {
-                      this.cellAddPage();
-                      pgAdded = true;
-                      if (this.printHeaders && this.tableHeaderRow) {
-                          this.printHeaderRow(ln, true);
-                      }
-                  }
-                  //We ignore the passed y: the lines may have different heights
-                  y = getLastCellPosition().y + getLastCellPosition().h;
-                  if (pgAdded) y = margin + 10;
-              }
-          }
-
-          if (txt[0] !== undefined) {
-              if (this.printingHeaderRow) {
-                  this.rect(x, y, w, h, 'FD');
-              } else {
-                  this.rect(x, y, w, h);
-              }
-              if (align === 'right') {
-                  if (!(txt instanceof Array)) {
-                      txt = [txt];
-                  }
-                  for (var i = 0; i < txt.length; i++) {
-                      var currentLine = txt[i];
-                      var textSize = this.getStringUnitWidth(currentLine) * this.internal.getFontSize();
-                      this.text(currentLine, x + w - textSize - padding, y + this.internal.getLineHeight() * (i + 1));
-                  }
-              } else {
-                  this.text(txt, x + padding, y + this.internal.getLineHeight());
-              }
-          }
-          setLastCellPosition(x, y, w, h, ln);
-          return this;
-      };
-
-      /**
-       * Return the maximum value from an array
-       * @param array
-       * @param comparisonFn
-       * @returns {*}
-       */
-      jsPDFAPI.arrayMax = function (array, comparisonFn) {
-          var max = array[0],
-              i,
-              ln,
-              item;
-
-          for (i = 0, ln = array.length; i < ln; i += 1) {
-              item = array[i];
-
-              if (comparisonFn) {
-                  if (comparisonFn(max, item) === -1) {
-                      max = item;
-                  }
-              } else {
-                  if (item > max) {
-                      max = item;
-                  }
-              }
-          }
-
-          return max;
-      };
-
-      /**
-       * Create a table from a set of data.
-       * @param {Integer} [x] : left-position for top-left corner of table
-       * @param {Integer} [y] top-position for top-left corner of table
-       * @param {Object[]} [data] As array of objects containing key-value pairs corresponding to a row of data.
-       * @param {String[]} [headers] Omit or null to auto-generate headers at a performance cost
-        * @param {Object} [config.printHeaders] True to print column headers at the top of every page
-       * @param {Object} [config.autoSize] True to dynamically set the column widths to match the widest cell value
-       * @param {Object} [config.margins] margin values for left, top, bottom, and width
-       * @param {Object} [config.fontSize] Integer fontSize to use (optional)
-       */
-
-      jsPDFAPI.table = function (x, y, data, headers, config) {
-          if (!data) {
-              throw 'No data for PDF table';
-          }
-
-          var headerNames = [],
-              headerPrompts = [],
-              header,
-              i,
-              ln,
-              cln,
-              columnMatrix = {},
-              columnWidths = {},
-              columnData,
-              column,
-              columnMinWidths = [],
-              j,
-              tableHeaderConfigs = [],
-              model,
-              jln,
-              func,
-
-
-          //set up defaults. If a value is provided in config, defaults will be overwritten:
-          autoSize = false,
-              printHeaders = true,
-              fontSize = 12,
-              margins = NO_MARGINS;
-
-          margins.width = this.internal.pageSize.getWidth();
-
-          if (config) {
-              //override config defaults if the user has specified non-default behavior:
-              if (config.autoSize === true) {
-                  autoSize = true;
-              }
-              if (config.printHeaders === false) {
-                  printHeaders = false;
-              }
-              if (config.fontSize) {
-                  fontSize = config.fontSize;
-              }
-              if (config.css && typeof config.css['font-size'] !== "undefined") {
-                  fontSize = config.css['font-size'] * 16;
-              }
-              if (config.margins) {
-                  margins = config.margins;
-              }
-          }
-
-          /**
-           * @property {Number} lnMod
-           * Keep track of the current line number modifier used when creating cells
-           */
-          this.lnMod = 0;
-          lastCellPos = { x: undefined, y: undefined, w: undefined, h: undefined, ln: undefined }, pages = 1;
-
-          this.printHeaders = printHeaders;
-          this.margins = margins;
-          this.setFontSize(fontSize);
-          this.table_font_size = fontSize;
-
-          // Set header values
-          if (headers === undefined || headers === null) {
-              // No headers defined so we derive from data
-              headerNames = Object.keys(data[0]);
-          } else if (headers[0] && typeof headers[0] !== 'string') {
-              var px2pt = 0.264583 * 72 / 25.4;
-
-              // Split header configs into names and prompts
-              for (i = 0, ln = headers.length; i < ln; i += 1) {
-                  header = headers[i];
-                  headerNames.push(header.name);
-                  headerPrompts.push(header.prompt);
-                  columnWidths[header.name] = header.width * px2pt;
-              }
-          } else {
-              headerNames = headers;
-          }
-
-          if (autoSize) {
-              // Create a matrix of columns e.g., {column_title: [row1_Record, row2_Record]}
-              func = function func(rec) {
-                  return rec[header];
-              };
-
-              for (i = 0, ln = headerNames.length; i < ln; i += 1) {
-                  header = headerNames[i];
-
-                  columnMatrix[header] = data.map(func);
-
-                  // get header width
-                  columnMinWidths.push(this.getTextDimensions(headerPrompts[i] || header).w);
-                  column = columnMatrix[header];
-
-                  // get cell widths
-                  for (j = 0, cln = column.length; j < cln; j += 1) {
-                      columnData = column[j];
-                      columnMinWidths.push(this.getTextDimensions(columnData).w);
-                  }
-
-                  // get final column width
-                  columnWidths[header] = jsPDFAPI.arrayMax(columnMinWidths);
-
-                  //have to reset
-                  columnMinWidths = [];
-              }
-          }
-
-          // -- Construct the table
-
-          if (printHeaders) {
-              var lineHeight = this.calculateLineHeight(headerNames, columnWidths, headerPrompts.length ? headerPrompts : headerNames);
-
-              // Construct the header row
-              for (i = 0, ln = headerNames.length; i < ln; i += 1) {
-                  header = headerNames[i];
-                  tableHeaderConfigs.push([x, y, columnWidths[header], lineHeight, String(headerPrompts.length ? headerPrompts[i] : header)]);
-              }
-
-              // Store the table header config
-              this.setTableHeaderRow(tableHeaderConfigs);
-
-              // Print the header for the start of the table
-              this.printHeaderRow(1, false);
-          }
-
-          // Construct the data rows
-          for (i = 0, ln = data.length; i < ln; i += 1) {
-              var lineHeight;
-              model = data[i];
-              lineHeight = this.calculateLineHeight(headerNames, columnWidths, model);
-
-              for (j = 0, jln = headerNames.length; j < jln; j += 1) {
-                  header = headerNames[j];
-                  this.cell(x, y, columnWidths[header], lineHeight, model[header], i + 2, header.align);
-              }
-          }
-          this.lastCellPos = lastCellPos;
-          this.table_x = x;
-          this.table_y = y;
-          return this;
-      };
-      /**
-       * Calculate the height for containing the highest column
-       * @param {String[]} headerNames is the header, used as keys to the data
-       * @param {Integer[]} columnWidths is size of each column
-       * @param {Object[]} model is the line of data we want to calculate the height of
-       */
-      jsPDFAPI.calculateLineHeight = function (headerNames, columnWidths, model) {
-          var header,
-              lineHeight = 0;
-          for (var j = 0; j < headerNames.length; j++) {
-              header = headerNames[j];
-              model[header] = this.splitTextToSize(String(model[header]), columnWidths[header] - padding);
-              var h = this.internal.getLineHeight() * model[header].length + padding;
-              if (h > lineHeight) lineHeight = h;
-          }
-          return lineHeight;
-      };
-
-      /**
-       * Store the config for outputting a table header
-       * @param {Object[]} config
-       * An array of cell configs that would define a header row: Each config matches the config used by jsPDFAPI.cell
-       * except the ln parameter is excluded
-       */
-      jsPDFAPI.setTableHeaderRow = function (config) {
-          this.tableHeaderRow = config;
-      };
-
-      /**
-       * Output the store header row
-       * @param lineNumber The line number to output the header at
-       */
-      jsPDFAPI.printHeaderRow = function (lineNumber, new_page) {
-          if (!this.tableHeaderRow) {
-              throw 'Property tableHeaderRow does not exist.';
-          }
-
-          var tableHeaderCell, tmpArray, i, ln;
-
-          this.printingHeaderRow = true;
-          if (headerFunction !== undefined) {
-              var position = headerFunction(this, pages);
-              setLastCellPosition(position[0], position[1], position[2], position[3], -1);
-          }
-          this.setFontStyle('bold');
-          var tempHeaderConf = [];
-          for (i = 0, ln = this.tableHeaderRow.length; i < ln; i += 1) {
-              this.setFillColor(200, 200, 200);
-
-              tableHeaderCell = this.tableHeaderRow[i];
-              if (new_page) {
-                  this.margins.top = margin;
-                  tableHeaderCell[1] = this.margins && this.margins.top || 0;
-                  tempHeaderConf.push(tableHeaderCell);
-              }
-              tmpArray = [].concat(tableHeaderCell);
-              this.cell.apply(this, tmpArray.concat(lineNumber));
-          }
-          if (tempHeaderConf.length > 0) {
-              this.setTableHeaderRow(tempHeaderConf);
-          }
-          this.setFontStyle('normal');
-          this.printingHeaderRow = false;
-      };
-  })(jsPDF.API);
-
-  /**
-   * jsPDF Context2D PlugIn Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv
-   *
-   * Licensed under the MIT License. http://opensource.org/licenses/mit-license
-   */
-
-  /**
-   * This plugin mimics the HTML5 Canvas's context2d.
-   *
-   * The goal is to provide a way for current canvas implementations to print directly to a PDF.
-   */
-
-  /**
-   * TODO implement stroke opacity (refactor from fill() method )
-   * TODO transform angle and radii parameters
-   */
-
-  /**
-   * require('jspdf.js'); require('lib/css_colors.js');
-   */
-
-  (function (jsPDFAPI) {
-
-      jsPDFAPI.events.push(['initialized', function () {
-          this.context2d.pdf = this;
-          this.context2d.internal.pdf = this;
-          this.context2d.ctx = new context();
-          this.context2d.ctxStack = [];
-          this.context2d.path = [];
-      }]);
-
-      jsPDFAPI.context2d = {
-          pageWrapXEnabled: false,
-          pageWrapYEnabled: false,
-          pageWrapX: 9999999,
-          pageWrapY: 9999999,
-          ctx: new context(),
-          f2: function f2(number) {
-              return number.toFixed(2);
-          },
-
-          fillRect: function fillRect(x, y, w, h) {
-              if (this._isFillTransparent()) {
-                  return;
-              }
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });
-              this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, "f");
-          },
-
-          strokeRect: function strokeRect(x, y, w, h) {
-              if (this._isStrokeTransparent()) {
-                  return;
-              }
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });
-              this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, "s");
-          },
-
-          /**
-           * We cannot clear PDF commands that were already written to PDF, so we use white instead. <br />
-           * As a special case, read a special flag (ignoreClearRect) and do nothing if it is set.
-           * This results in all calls to clearRect() to do nothing, and keep the canvas transparent.
-           * This flag is stored in the save/restore context and is managed the same way as other drawing states.
-           * @param x
-           * @param y
-           * @param w
-           * @param h
-           */
-          clearRect: function clearRect(x, y, w, h) {
-              if (this.ctx.ignoreClearRect) {
-                  return;
-              }
-
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });
-              this.save();
-              this.setFillStyle('#ffffff');
-              //TODO This is hack to fill with white.
-              this.pdf.rect(xRect.x, xRect.y, xRect.w, xRect.h, "f");
-              this.restore();
-          },
-
-          save: function save() {
-              this.ctx._fontSize = this.pdf.internal.getFontSize();
-              var ctx = new context();
-              ctx.copy(this.ctx);
-              this.ctxStack.push(this.ctx);
-              this.ctx = ctx;
-          },
-
-          restore: function restore() {
-              this.ctx = this.ctxStack.pop();
-              this.setFillStyle(this.ctx.fillStyle);
-              this.setStrokeStyle(this.ctx.strokeStyle);
-              this.setFont(this.ctx.font);
-              this.pdf.setFontSize(this.ctx._fontSize);
-              this.setLineCap(this.ctx.lineCap);
-              this.setLineWidth(this.ctx.lineWidth);
-              this.setLineJoin(this.ctx.lineJoin);
-          },
-
-          rect: function rect(x, y, w, h) {
-              this.moveTo(x, y);
-              this.lineTo(x + w, y);
-              this.lineTo(x + w, y + h);
-              this.lineTo(x, y + h);
-              this.lineTo(x, y); //TODO not needed
-              this.closePath();
-          },
-
-          beginPath: function beginPath() {
-              this.path = [];
-          },
-
-          closePath: function closePath() {
-              this.path.push({
-                  type: 'close'
-              });
-          },
-
-          _getRGBA: function _getRGBA(style) {
-              // get the decimal values of r, g, and b;
-              var r, g, b, a;
-              var rgbColor = new RGBColor(style);
-
-              if (!style) {
-                  return { r: 0, g: 0, b: 0, a: 0, style: style };
-              }
-
-              if (this.internal.rxTransparent.test(style)) {
-                  r = 0;
-                  g = 0;
-                  b = 0;
-                  a = 0;
-              } else {
-                  var m = this.internal.rxRgb.exec(style);
-                  if (m != null) {
-                      r = parseInt(m[1]);
-                      g = parseInt(m[2]);
-                      b = parseInt(m[3]);
-                      a = 1;
-                  } else {
-                      m = this.internal.rxRgba.exec(style);
-                      if (m != null) {
-                          r = parseInt(m[1]);
-                          g = parseInt(m[2]);
-                          b = parseInt(m[3]);
-                          a = parseFloat(m[4]);
-                      } else {
-                          a = 1;
-                          if (style.charAt(0) != '#') {
-                              if (rgbColor.ok) {
-                                  style = rgbColor.toHex();
-                              } else {
-                                  style = '#000000';
-                              }
-                          }
-
-                          if (style.length === 4) {
-                              r = style.substring(1, 2);
-                              r += r;
-                              g = style.substring(2, 3);
-                              g += g;
-                              b = style.substring(3, 4);
-                              b += b;
-                          } else {
-                              r = style.substring(1, 3);
-                              g = style.substring(3, 5);
-                              b = style.substring(5, 7);
-                          }
-                          r = parseInt(r, 16);
-                          g = parseInt(g, 16);
-                          b = parseInt(b, 16);
-                      }
-                  }
-              }
-              return { r: r, g: g, b: b, a: a, style: style };
-          },
-
-          setFillStyle: function setFillStyle(style) {
-              var rgba = this._getRGBA(style);
-
-              this.ctx.fillStyle = style;
-              this.ctx._isFillTransparent = rgba.a === 0;
-              this.ctx._fillOpacity = rgba.a;
-
-              this.pdf.setFillColor(rgba.r, rgba.g, rgba.b, {
-                  a: rgba.a
-              });
-              this.pdf.setTextColor(rgba.r, rgba.g, rgba.b, {
-                  a: rgba.a
-              });
-          },
-
-          setStrokeStyle: function setStrokeStyle(style) {
-              var rgba = this._getRGBA(style);
-
-              this.ctx.strokeStyle = rgba.style;
-              this.ctx._isStrokeTransparent = rgba.a === 0;
-              this.ctx._strokeOpacity = rgba.a;
-
-              //TODO jsPDF to handle rgba
-              if (rgba.a === 0) {
-                  this.pdf.setDrawColor(255, 255, 255);
-              } else if (rgba.a === 1) {
-                  this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b);
-              } else {
-                  //this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b, {a: rgba.a});
-                  this.pdf.setDrawColor(rgba.r, rgba.g, rgba.b);
-              }
-          },
-
-          fillText: function fillText(text, x, y, maxWidth) {
-              if (this._isFillTransparent()) {
-                  return;
-              }
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
-              x = xpt[0];
-              y = xpt[1];
-              var rads = this._matrix_rotation(this.ctx._transform);
-              var degs = rads * 57.2958;
-
-              //TODO only push the clip if it has not been applied to the current PDF context
-              if (this.ctx._clip_path.length > 0) {
-                  var lines;
-                  if (window.outIntercept) {
-                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
-                  } else {
-                      lines = this.internal.getCurrentPage();
-                  }
-                  lines.push("q");
-                  var origPath = this.path;
-                  this.path = this.ctx._clip_path;
-                  this.ctx._clip_path = [];
-                  this._fill(null, true);
-                  this.ctx._clip_path = this.path;
-                  this.path = origPath;
-              }
-
-              // We only use X axis as scale hint 
-              var scale = 1;
-              try {
-                  scale = this._matrix_decompose(this._getTransform()).scale[0];
-              } catch (e) {
-                  console.warn(e);
-              }
-
-              // In some cases the transform was very small (5.715760606202283e-17).  Most likely a canvg rounding error.
-              if (scale < 0.01) {
-                  this.pdf.text(text, x, this._getBaseline(y), null, degs);
-              } else {
-                  var oldSize = this.pdf.internal.getFontSize();
-                  this.pdf.setFontSize(oldSize * scale);
-                  this.pdf.text(text, x, this._getBaseline(y), null, degs);
-                  this.pdf.setFontSize(oldSize);
-              }
-
-              if (this.ctx._clip_path.length > 0) {
-                  lines.push('Q');
-              }
-          },
-
-          strokeText: function strokeText(text, x, y, maxWidth) {
-              if (this._isStrokeTransparent()) {
-                  return;
-              }
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
-              x = xpt[0];
-              y = xpt[1];
-              var rads = this._matrix_rotation(this.ctx._transform);
-              var degs = rads * 57.2958;
-
-              //TODO only push the clip if it has not been applied to the current PDF context
-              if (this.ctx._clip_path.length > 0) {
-                  var lines;
-                  if (window.outIntercept) {
-                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
-                  } else {
-                      lines = this.internal.getCurrentPage();
-                  }
-                  lines.push("q");
-                  var origPath = this.path;
-                  this.path = this.ctx._clip_path;
-                  this.ctx._clip_path = [];
-                  this._fill(null, true);
-                  this.ctx._clip_path = this.path;
-                  this.path = origPath;
-              }
-
-              var scale = 1;
-              // We only use the X axis as scale hint 
-              try {
-                  scale = this._matrix_decompose(this._getTransform()).scale[0];
-              } catch (e) {
-                  console.warn(e);
-              }
-
-              if (scale === 1) {
-                  this.pdf.text(text, x, this._getBaseline(y), {
-                      stroke: true
-                  }, degs);
-              } else {
-                  var oldSize = this.pdf.internal.getFontSize();
-                  this.pdf.setFontSize(oldSize * scale);
-                  this.pdf.text(text, x, this._getBaseline(y), {
-                      stroke: true
-                  }, degs);
-                  this.pdf.setFontSize(oldSize);
-              }
-
-              if (this.ctx._clip_path.length > 0) {
-                  lines.push('Q');
-              }
-          },
-
-          setFont: function setFont(font) {
-              this.ctx.font = font;
-
-              //var rx = /\s*(\w+)\s+(\w+)\s+(\w+)\s+([\d\.]+)(px|pt|em)\s+["']?(\w+)['"]?/;
-              var rx = /\s*(\w+)\s+(\w+)\s+(\w+)\s+([\d\.]+)(px|pt|em)\s+(.*)?/;
-              m = rx.exec(font);
-              if (m != null) {
-                  var fontStyle = m[1];
-                  var fontVariant = m[2];
-                  var fontWeight = m[3];
-                  var fontSize = m[4];
-                  var fontSizeUnit = m[5];
-                  var fontFamily = m[6];
-
-                  if ('px' === fontSizeUnit) {
-                      fontSize = Math.floor(parseFloat(fontSize));
-                      // fontSize = fontSize * 1.25;
-                  } else if ('em' === fontSizeUnit) {
-                      fontSize = Math.floor(parseFloat(fontSize) * this.pdf.getFontSize());
-                  } else {
-                      fontSize = Math.floor(parseFloat(fontSize));
-                  }
-
-                  this.pdf.setFontSize(fontSize);
-
-                  if (fontWeight === 'bold' || fontWeight === '700') {
-                      this.pdf.setFontStyle('bold');
-                  } else {
-                      if (fontStyle === 'italic') {
-                          this.pdf.setFontStyle('italic');
-                      } else {
-                          this.pdf.setFontStyle('normal');
-                      }
-                  }
-                  var style;
-                  if ('bold' === fontWeight || fontWeight === '700') {
-                      style = fontStyle === 'italic' ? 'bolditalic' : 'bold';
-                  } else if (fontStyle === 'italic') {
-                      style = 'italic';
-                  } else {
-                      style = 'normal';
-                  }
-
-                  var parts = fontFamily.toLowerCase().split(/\s*,\s*/);
-                  var jsPdfFontName = 'Times';
-
-                  for (var i = 0; i < parts.length; i++) {
-                      if (this.pdf.internal.getFont(parts[i], style, { noFallback: true, disableWarning: true }) !== undefined) {
-                          jsPdfFontName = parts[i];
-                          break;
-                      } else if (style === 'bolditalic' && this.pdf.internal.getFont(parts[i], 'bold', { noFallback: true, disableWarning: true }) !== undefined) {
-                          jsPdfFontName = parts[i];
-                          style = 'bold';
-                      } else if (this.pdf.internal.getFont(parts[i], 'normal', { noFallback: true, disableWarning: true }) !== undefined) {
-                          jsPdfFontName = parts[i];
-                          style = 'normal';
-                          break;
-                      }
-                  }
-
-                  this.pdf.setFont(jsPdfFontName, style);
-              } else {
-                  var rx = /\s*(\d+)(pt|px|em)\s+([\w "]+)\s*([\w "]+)?/;
-                  var m = rx.exec(font);
-                  if (m != null) {
-                      var size = m[1];
-                      var unit = m[2];
-                      var name = m[3];
-                      var style = m[4];
-                      if (!style) {
-                          style = 'normal';
-                      }
-                      if ('em' === fontSizeUnit) {
-                          size = Math.floor(parseFloat(fontSize) * this.pdf.getFontSize());
-                      } else {
-                          size = Math.floor(parseFloat(size));
-                      }
-                      this.pdf.setFontSize(size);
-                      this.pdf.setFont(name, style);
-                  }
-              }
-          },
-
-          setTextBaseline: function setTextBaseline(baseline) {
-              this.ctx.textBaseline = baseline;
-          },
-
-          getTextBaseline: function getTextBaseline() {
-              return this.ctx.textBaseline;
-          },
-
-          //TODO implement textAlign
-          setTextAlign: function setTextAlign(align) {
-              this.ctx.textAlign = align;
-          },
-
-          getTextAlign: function getTextAlign() {
-              return this.ctx.textAlign;
-          },
-
-          setLineWidth: function setLineWidth(width) {
-              this.ctx.lineWidth = width;
-              this.pdf.setLineWidth(width);
-          },
-
-          setLineCap: function setLineCap(style) {
-              this.ctx.lineCap = style;
-              this.pdf.setLineCap(style);
-          },
-
-          setLineJoin: function setLineJoin(style) {
-              this.ctx.lineJoin = style;
-              this.pdf.setLineJoin(style);
-          },
-
-          moveTo: function moveTo(x, y) {
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
-              x = xpt[0];
-              y = xpt[1];
-
-              var obj = {
-                  type: 'mt',
-                  x: x,
-                  y: y
-              };
-              this.path.push(obj);
-          },
-
-          _wrapX: function _wrapX(x) {
-              if (this.pageWrapXEnabled) {
-                  return x % this.pageWrapX;
-              } else {
-                  return x;
-              }
-          },
-
-          _wrapY: function _wrapY(y) {
-              if (this.pageWrapYEnabled) {
-                  this._gotoPage(this._page(y));
-                  return (y - this.lastBreak) % this.pageWrapY;
-              } else {
-                  return y;
-              }
-          },
-
-          transform: function transform(a, b, c, d, e, f) {
-              this.ctx._transform = this._matrix_multiply(this.ctx._transform, [a, b, c, d, e, f]);
-          },
-
-          setTransform: function setTransform(a, b, c, d, e, f) {
-              this.ctx._transform = [a, b, c, d, e, f];
-          },
-
-          _getTransform: function _getTransform() {
-              return this.ctx._transform;
-          },
-
-          lastBreak: 0,
-          // Y Position of page breaks.
-          pageBreaks: [],
-          // returns: One-based Page Number
-          // Should only be used if pageWrapYEnabled is true
-          _page: function _page(y) {
-              if (this.pageWrapYEnabled) {
-                  this.lastBreak = 0;
-                  var manualBreaks = 0;
-                  var autoBreaks = 0;
-                  for (var i = 0; i < this.pageBreaks.length; i++) {
-                      if (y >= this.pageBreaks[i]) {
-                          manualBreaks++;
-                          if (this.lastBreak === 0) {
-                              autoBreaks++;
-                          }
-                          var spaceBetweenLastBreak = this.pageBreaks[i] - this.lastBreak;
-                          this.lastBreak = this.pageBreaks[i];
-                          var pagesSinceLastBreak = Math.floor(spaceBetweenLastBreak / this.pageWrapY);
-                          autoBreaks += pagesSinceLastBreak;
-                      }
-                  }
-                  if (this.lastBreak === 0) {
-                      var pagesSinceLastBreak = Math.floor(y / this.pageWrapY) + 1;
-                      autoBreaks += pagesSinceLastBreak;
-                  }
-                  return autoBreaks + manualBreaks;
-              } else {
-                  return this.pdf.internal.getCurrentPageInfo().pageNumber;
-              }
-          },
-
-          _gotoPage: function _gotoPage(pageOneBased) {
-              // This is a stub to be overriden if needed
-          },
-
-          lineTo: function lineTo(x, y) {
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
-              x = xpt[0];
-              y = xpt[1];
-
-              var obj = {
-                  type: 'lt',
-                  x: x,
-                  y: y
-              };
-              this.path.push(obj);
-          },
-
-          bezierCurveTo: function bezierCurveTo(x1, y1, x2, y2, x, y) {
-              x1 = this._wrapX(x1);
-              y1 = this._wrapY(y1);
-              x2 = this._wrapX(x2);
-              y2 = this._wrapY(y2);
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xpt;
-              xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
-              x = xpt[0];
-              y = xpt[1];
-              xpt = this._matrix_map_point(this.ctx._transform, [x1, y1]);
-              x1 = xpt[0];
-              y1 = xpt[1];
-              xpt = this._matrix_map_point(this.ctx._transform, [x2, y2]);
-              x2 = xpt[0];
-              y2 = xpt[1];
-
-              var obj = {
-                  type: 'bct',
-                  x1: x1,
-                  y1: y1,
-                  x2: x2,
-                  y2: y2,
-                  x: x,
-                  y: y
-              };
-              this.path.push(obj);
-          },
-
-          quadraticCurveTo: function quadraticCurveTo(x1, y1, x, y) {
-              x1 = this._wrapX(x1);
-              y1 = this._wrapY(y1);
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xpt;
-              xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
-              x = xpt[0];
-              y = xpt[1];
-              xpt = this._matrix_map_point(this.ctx._transform, [x1, y1]);
-              x1 = xpt[0];
-              y1 = xpt[1];
-
-              var obj = {
-                  type: 'qct',
-                  x1: x1,
-                  y1: y1,
-                  x: x,
-                  y: y
-              };
-              this.path.push(obj);
-          },
-
-          arc: function arc(x, y, radius, startAngle, endAngle, anticlockwise) {
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              if (!this._matrix_is_identity(this.ctx._transform)) {
-                  var xpt = this._matrix_map_point(this.ctx._transform, [x, y]);
-                  x = xpt[0];
-                  y = xpt[1];
-
-                  var x_radPt0 = this._matrix_map_point(this.ctx._transform, [0, 0]);
-                  var x_radPt = this._matrix_map_point(this.ctx._transform, [0, radius]);
-                  radius = Math.sqrt(Math.pow(x_radPt[0] - x_radPt0[0], 2) + Math.pow(x_radPt[1] - x_radPt0[1], 2));
-
-                  //TODO angles need to be transformed
-              }
-
-              var obj = {
-                  type: 'arc',
-                  x: x,
-                  y: y,
-                  radius: radius,
-                  startAngle: startAngle,
-                  endAngle: endAngle,
-                  anticlockwise: anticlockwise
-              };
-              this.path.push(obj);
-          },
-
-          drawImage: function drawImage(img, x, y, w, h, x2, y2, w2, h2) {
-              if (x2 !== undefined) {
-                  x = x2;
-                  y = y2;
-                  w = w2;
-                  h = h2;
-              }
-              x = this._wrapX(x);
-              y = this._wrapY(y);
-
-              var xRect = this._matrix_map_rect(this.ctx._transform, { x: x, y: y, w: w, h: h });
-              var xRect2 = this._matrix_map_rect(this.ctx._transform, { x: x2, y: y2, w: w2, h: h2 });
-
-              // TODO implement source clipping and image scaling
-              var format;
-              var rx = /data:image\/(\w+).*/i;
-              var m = rx.exec(img);
-              if (m != null) {
-                  format = m[1];
-              } else {
-                  // format = "jpeg";
-                  format = "png";
-              }
-
-              this.pdf.addImage(img, format, xRect.x, xRect.y, xRect.w, xRect.h);
-          },
-
-          /**
-           * Multiply the first matrix by the second
-           * @param m1
-           * @param m2
-           * @returns {*[]}
-           * @private
-           */
-          _matrix_multiply: function _matrix_multiply(m2, m1) {
-              var sx = m1[0];
-              var shy = m1[1];
-              var shx = m1[2];
-              var sy = m1[3];
-              var tx = m1[4];
-              var ty = m1[5];
-
-              var t0 = sx * m2[0] + shy * m2[2];
-              var t2 = shx * m2[0] + sy * m2[2];
-              var t4 = tx * m2[0] + ty * m2[2] + m2[4];
-              shy = sx * m2[1] + shy * m2[3];
-              sy = shx * m2[1] + sy * m2[3];
-              ty = tx * m2[1] + ty * m2[3] + m2[5];
-              sx = t0;
-              shx = t2;
-              tx = t4;
-
-              return [sx, shy, shx, sy, tx, ty];
-          },
-
-          _matrix_rotation: function _matrix_rotation(m) {
-              return Math.atan2(m[2], m[0]);
-          },
-
-          _matrix_decompose: function _matrix_decompose(matrix) {
-
-              var a = matrix[0];
-              var b = matrix[1];
-              var c = matrix[2];
-              var d = matrix[3];
-
-              var scaleX = Math.sqrt(a * a + b * b);
-              a /= scaleX;
-              b /= scaleX;
-
-              var shear = a * c + b * d;
-              c -= a * shear;
-              d -= b * shear;
-
-              var scaleY = Math.sqrt(c * c + d * d);
-              c /= scaleY;
-              d /= scaleY;
-              shear /= scaleY;
-
-              if (a * d < b * c) {
-                  a = -a;
-                  b = -b;
-                  shear = -shear;
-                  scaleX = -scaleX;
-              }
-
-              return {
-                  scale: [scaleX, 0, 0, scaleY, 0, 0],
-                  translate: [1, 0, 0, 1, matrix[4], matrix[5]],
-                  rotate: [a, b, -b, a, 0, 0],
-                  skew: [1, 0, shear, 1, 0, 0]
-              };
-          },
-
-          _matrix_map_point: function _matrix_map_point(m1, pt) {
-              var sx = m1[0];
-              var shy = m1[1];
-              var shx = m1[2];
-              var sy = m1[3];
-              var tx = m1[4];
-              var ty = m1[5];
-
-              var px = pt[0];
-              var py = pt[1];
-
-              var x = px * sx + py * shx + tx;
-              var y = px * shy + py * sy + ty;
-              return [x, y];
-          },
-
-          _matrix_map_point_obj: function _matrix_map_point_obj(m1, pt) {
-              var xpt = this._matrix_map_point(m1, [pt.x, pt.y]);
-              return { x: xpt[0], y: xpt[1] };
-          },
-
-          _matrix_map_rect: function _matrix_map_rect(m1, rect) {
-              var p1 = this._matrix_map_point(m1, [rect.x, rect.y]);
-              var p2 = this._matrix_map_point(m1, [rect.x + rect.w, rect.y + rect.h]);
-              return { x: p1[0], y: p1[1], w: p2[0] - p1[0], h: p2[1] - p1[1] };
-          },
-
-          _matrix_is_identity: function _matrix_is_identity(m1) {
-              if (m1[0] != 1) {
-                  return false;
-              }
-              if (m1[1] != 0) {
-                  return false;
-              }
-              if (m1[2] != 0) {
-                  return false;
-              }
-              if (m1[3] != 1) {
-                  return false;
-              }
-              if (m1[4] != 0) {
-                  return false;
-              }
-              if (m1[5] != 0) {
-                  return false;
-              }
-              return true;
-          },
-
-          rotate: function rotate(angle) {
-              var matrix = [Math.cos(angle), Math.sin(angle), -Math.sin(angle), Math.cos(angle), 0.0, 0.0];
-              this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix);
-          },
-
-          scale: function scale(sx, sy) {
-              var matrix = [sx, 0.0, 0.0, sy, 0.0, 0.0];
-              this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix);
-          },
-
-          translate: function translate(x, y) {
-              var matrix = [1.0, 0.0, 0.0, 1.0, x, y];
-              this.ctx._transform = this._matrix_multiply(this.ctx._transform, matrix);
-          },
-
-          stroke: function stroke() {
-              if (this.ctx._clip_path.length > 0) {
-
-                  var lines;
-                  if (window.outIntercept) {
-                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
-                  } else {
-                      lines = this.internal.getCurrentPage();
-                  }
-                  lines.push("q");
-
-                  var origPath = this.path;
-                  this.path = this.ctx._clip_path;
-                  this.ctx._clip_path = [];
-                  this._stroke(true);
-
-                  this.ctx._clip_path = this.path;
-                  this.path = origPath;
-                  this._stroke(false);
-
-                  lines.push("Q");
-              } else {
-                  this._stroke(false);
-              }
-          },
-
-          _stroke: function _stroke(isClip) {
-              if (!isClip && this._isStrokeTransparent()) {
-                  return;
-              }
-
-              //TODO opacity
-
-              var moves = [];
-
-              var xPath = this.path;
-
-              for (var i = 0; i < xPath.length; i++) {
-                  var pt = xPath[i];
-                  switch (pt.type) {
-                      case 'mt':
-                          moves.push({ start: pt, deltas: [], abs: [] });
-                          break;
-                      case 'lt':
-                          var delta = [pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
-                          moves[moves.length - 1].deltas.push(delta);
-                          moves[moves.length - 1].abs.push(pt);
-                          break;
-                      case 'bct':
-                          var delta = [pt.x1 - xPath[i - 1].x, pt.y1 - xPath[i - 1].y, pt.x2 - xPath[i - 1].x, pt.y2 - xPath[i - 1].y, pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
-                          moves[moves.length - 1].deltas.push(delta);
-                          break;
-                      case 'qct':
-                          // convert to bezier
-                          var x1 = xPath[i - 1].x + 2.0 / 3.0 * (pt.x1 - xPath[i - 1].x);
-                          var y1 = xPath[i - 1].y + 2.0 / 3.0 * (pt.y1 - xPath[i - 1].y);
-                          var x2 = pt.x + 2.0 / 3.0 * (pt.x1 - pt.x);
-                          var y2 = pt.y + 2.0 / 3.0 * (pt.y1 - pt.y);
-                          var x3 = pt.x;
-                          var y3 = pt.y;
-                          var delta = [x1 - xPath[i - 1].x, y1 - xPath[i - 1].y, x2 - xPath[i - 1].x, y2 - xPath[i - 1].y, x3 - xPath[i - 1].x, y3 - xPath[i - 1].y];
-                          moves[moves.length - 1].deltas.push(delta);
-                          break;
-                      case 'arc':
-                          //TODO this was hack to avoid out-of-bounds issue
-                          // No move-to before drawing the arc
-                          if (moves.length == 0) {
-                              moves.push({ start: { x: 0, y: 0 }, deltas: [], abs: [] });
-                          }
-                          moves[moves.length - 1].arc = true;
-                          if (Array.isArray(moves[moves.length - 1].abs)) {
-                              moves[moves.length - 1].abs.push(pt);
-                          }
-                          break;
-                      case 'close':
-                          break;
-                  }
-              }
-
-              for (var i = 0; i < moves.length; i++) {
-                  var style;
-                  if (i == moves.length - 1) {
-                      style = 's';
-                  } else {
-                      style = null;
-                  }
-                  if (moves[i].arc) {
-                      var arcs = moves[i].abs;
-                      for (var ii = 0; ii < arcs.length; ii++) {
-                          var arc = arcs[ii];
-                          var start = arc.startAngle * 360 / (2 * Math.PI);
-                          var end = arc.endAngle * 360 / (2 * Math.PI);
-                          var x = arc.x;
-                          var y = arc.y;
-                          this.internal.arc2(this, x, y, arc.radius, start, end, arc.anticlockwise, style, isClip);
-                      }
-                  } else {
-                      var x = moves[i].start.x;
-                      var y = moves[i].start.y;
-                      if (!isClip) {
-                          this.pdf.lines(moves[i].deltas, x, y, null, style);
-                      } else {
-                          this.pdf.lines(moves[i].deltas, x, y, null, null);
-                          this.pdf.clip_fixed();
-                      }
-                  }
-              }
-          },
-
-          _isFillTransparent: function _isFillTransparent() {
-              return this.ctx._isFillTransparent || this.globalAlpha == 0;
-          },
-
-          _isStrokeTransparent: function _isStrokeTransparent() {
-              return this.ctx._isStrokeTransparent || this.globalAlpha == 0;
-          },
-
-          fill: function fill(fillRule) {
-              //evenodd or nonzero (default)
-              if (this.ctx._clip_path.length > 0) {
-
-                  var lines;
-                  if (window.outIntercept) {
-                      lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
-                  } else {
-                      lines = this.internal.getCurrentPage();
-                  }
-                  lines.push("q");
-
-                  var origPath = this.path;
-                  this.path = this.ctx._clip_path;
-                  this.ctx._clip_path = [];
-                  this._fill(fillRule, true);
-
-                  this.ctx._clip_path = this.path;
-                  this.path = origPath;
-                  this._fill(fillRule, false);
-
-                  lines.push('Q');
-              } else {
-                  this._fill(fillRule, false);
-              }
-          },
-
-          _fill: function _fill(fillRule, isClip) {
-              if (this._isFillTransparent()) {
-                  return;
-              }
-              var v2Support = typeof this.pdf.internal.newObject2 === 'function';
-
-              var lines;
-              if (window.outIntercept) {
-                  lines = window.outIntercept.type === 'group' ? window.outIntercept.stream : window.outIntercept;
-              } else {
-                  lines = this.internal.getCurrentPage();
-              }
-
-              // if (this.ctx._clip_path.length > 0) {
-              //     lines.push('q');
-              //     var oldPath = this.path;
-              //     this.path = this.ctx._clip_path;
-              //     this.ctx._clip_path = [];
-              //     this._fill(fillRule, true);
-              //     this.ctx._clip_path = this.path;
-              //     this.path = oldPath;
-              //     lines.push('Q');
-              // }
-
-              var moves = [];
-              var outInterceptOld = window.outIntercept;
-
-              if (v2Support) {
-                  // Blend and Mask
-                  switch (this.ctx.globalCompositeOperation) {
-                      case 'normal':
-                      case 'source-over':
-                          break;
-                      case 'destination-in':
-                      case 'destination-out':
-                          //TODO this need to be added to the current group or page
-                          // define a mask stream
-                          var obj = this.pdf.internal.newStreamObject();
-
-                          // define a mask state
-                          var obj2 = this.pdf.internal.newObject2();
-                          obj2.push('<</Type /ExtGState');
-                          obj2.push('/SMask <</S /Alpha /G ' + obj.objId + ' 0 R>>'); // /S /Luminosity will need to define color space
-                          obj2.push('>>');
-
-                          // add mask to page resources
-                          var gsName = 'MASK' + obj2.objId;
-                          this.pdf.internal.addGraphicsState(gsName, obj2.objId);
-
-                          var instruction = '/' + gsName + ' gs';
-                          // add mask to page, group, or stream
-                          lines.splice(0, 0, 'q');
-                          lines.splice(1, 0, instruction);
-                          lines.push('Q');
-
-                          window.outIntercept = obj;
-                          break;
-                      default:
-                          var dictionaryEntry = '/' + this.pdf.internal.blendModeMap[this.ctx.globalCompositeOperation.toUpperCase()];
-                          if (dictionaryEntry) {
-                              this.pdf.internal.out(dictionaryEntry + ' gs');
-                          }
-                          break;
-                  }
-              }
-
-              var alpha = this.ctx.globalAlpha;
-              if (this.ctx._fillOpacity < 1) {
-                  // TODO combine this with global opacity
-                  alpha = this.ctx._fillOpacity;
-              }
-
-              //TODO check for an opacity graphics state that was already created
-              //TODO do not set opacity if current value is already active
-              if (v2Support) {
-                  var objOpac = this.pdf.internal.newObject2();
-                  objOpac.push('<</Type /ExtGState');
-                  //objOpac.push(this.ctx.globalAlpha + " CA"); // Stroke
-                  //objOpac.push(this.ctx.globalAlpha + " ca"); // Not Stroke
-                  objOpac.push('/CA ' + alpha); // Stroke
-                  objOpac.push('/ca ' + alpha); // Not Stroke
-                  objOpac.push('>>');
-                  var gsName = 'GS_O_' + objOpac.objId;
-                  this.pdf.internal.addGraphicsState(gsName, objOpac.objId);
-                  this.pdf.internal.out('/' + gsName + ' gs');
-              }
-
-              var xPath = this.path;
-
-              for (var i = 0; i < xPath.length; i++) {
-                  var pt = xPath[i];
-                  switch (pt.type) {
-                      case 'mt':
-                          moves.push({ start: pt, deltas: [], abs: [] });
-                          break;
-                      case 'lt':
-                          var delta = [pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
-                          moves[moves.length - 1].deltas.push(delta);
-                          moves[moves.length - 1].abs.push(pt);
-                          break;
-                      case 'bct':
-                          var delta = [pt.x1 - xPath[i - 1].x, pt.y1 - xPath[i - 1].y, pt.x2 - xPath[i - 1].x, pt.y2 - xPath[i - 1].y, pt.x - xPath[i - 1].x, pt.y - xPath[i - 1].y];
-                          moves[moves.length - 1].deltas.push(delta);
-                          break;
-                      case 'qct':
-                          // convert to bezier
-                          var x1 = xPath[i - 1].x + 2.0 / 3.0 * (pt.x1 - xPath[i - 1].x);
-                          var y1 = xPath[i - 1].y + 2.0 / 3.0 * (pt.y1 - xPath[i - 1].y);
-                          var x2 = pt.x + 2.0 / 3.0 * (pt.x1 - pt.x);
-                          var y2 = pt.y + 2.0 / 3.0 * (pt.y1 - pt.y);
-                          var x3 = pt.x;
-                          var y3 = pt.y;
-                          var delta = [x1 - xPath[i - 1].x, y1 - xPath[i - 1].y, x2 - xPath[i - 1].x, y2 - xPath[i - 1].y, x3 - xPath[i - 1].x, y3 - xPath[i - 1].y];
-                          moves[moves.length - 1].deltas.push(delta);
-                          break;
-                      case 'arc':
-                          //TODO this was hack to avoid out-of-bounds issue when drawing circle
-                          // No move-to before drawing the arc
-                          if (moves.length === 0) {
-                              moves.push({ deltas: [], abs: [] });
-                          }
-                          moves[moves.length - 1].arc = true;
-                          if (Array.isArray(moves[moves.length - 1].abs)) {
-                              moves[moves.length - 1].abs.push(pt);
-                          }
-                          break;
-                      case 'close':
-                          moves.push({ close: true });
-                          break;
-                  }
-              }
-
-              for (var i = 0; i < moves.length; i++) {
-                  var style;
-                  if (i == moves.length - 1) {
-                      style = 'f';
-                      if (fillRule === 'evenodd') {
-                          style += '*';
-                      }
-                  } else {
-                      style = null;
-                  }
-
-                  if (moves[i].close) {
-                      this.pdf.internal.out('h');
-                      if (style) {
-                          // only fill at final path move
-                          this.pdf.internal.out(style);
-                      }
-                  } else if (moves[i].arc) {
-                      if (moves[i].start) {
-                          this.internal.move2(this, moves[i].start.x, moves[i].start.y);
-                      }
-                      var arcs = moves[i].abs;
-                      for (var ii = 0; ii < arcs.length; ii++) {
-                          var arc = arcs[ii];
-                          //TODO lines deltas were getting in here
-                          if (typeof arc.startAngle !== 'undefined') {
-                              var start = arc.startAngle * 360 / (2 * Math.PI);
-                              var end = arc.endAngle * 360 / (2 * Math.PI);
-                              var x = arc.x;
-                              var y = arc.y;
-                              if (ii === 0) {
-                                  this.internal.move2(this, x, y);
-                              }
-                              this.internal.arc2(this, x, y, arc.radius, start, end, arc.anticlockwise, null, isClip);
-                              if (ii === arcs.length - 1) {
-                                  // The original arc move did not occur because of the algorithm
-                                  if (moves[i].start) {
-                                      var x = moves[i].start.x;
-                                      var y = moves[i].start.y;
-                                      this.internal.line2(c2d, x, y);
-                                  }
-                              }
-                          } else {
-                              this.internal.line2(c2d, arc.x, arc.y);
-                          }
-                      }
-                  } else {
-                      var x = moves[i].start.x;
-                      var y = moves[i].start.y;
-                      if (!isClip) {
-                          this.pdf.lines(moves[i].deltas, x, y, null, style);
-                      } else {
-                          this.pdf.lines(moves[i].deltas, x, y, null, null);
-                          this.pdf.clip_fixed();
-                      }
-                  }
-              }
-
-              window.outIntercept = outInterceptOld;
-
-              // if (this.ctx._clip_path.length > 0) {
-              //     lines.push('Q');
-              // }
-          },
-
-          pushMask: function pushMask() {
-              var v2Support = typeof this.pdf.internal.newObject2 === 'function';
-
-              if (!v2Support) {
-                  console.log('jsPDF v2 not enabled');
-                  return;
-              }
-
-              // define a mask stream
-              var obj = this.pdf.internal.newStreamObject();
-
-              // define a mask state
-              var obj2 = this.pdf.internal.newObject2();
-              obj2.push('<</Type /ExtGState');
-              obj2.push('/SMask <</S /Alpha /G ' + obj.objId + ' 0 R>>'); // /S /Luminosity will need to define color space
-              obj2.push('>>');
-
-              // add mask to page resources
-              var gsName = 'MASK' + obj2.objId;
-              this.pdf.internal.addGraphicsState(gsName, obj2.objId);
-
-              var instruction = '/' + gsName + ' gs';
-              this.pdf.internal.out(instruction);
-          },
-
-          clip: function clip() {
-              //TODO do we reset the path, or just copy it?
-              if (this.ctx._clip_path.length > 0) {
-                  for (var i = 0; i < this.path.length; i++) {
-                      this.ctx._clip_path.push(this.path[i]);
-                  }
-              } else {
-                  this.ctx._clip_path = this.path;
-              }
-              this.path = [];
-          },
-
-          measureText: function measureText(text) {
-              var pdf = this.pdf;
-              return {
-                  getWidth: function getWidth() {
-                      var fontSize = pdf.internal.getFontSize();
-                      var txtWidth = pdf.getStringUnitWidth(text) * fontSize / pdf.internal.scaleFactor;
-                      // Convert points to pixels
-                      txtWidth *= 1.3333;
-                      return txtWidth;
-                  },
-
-                  get width() {
-                      return this.getWidth(text);
-                  }
-              };
-          },
-          _getBaseline: function _getBaseline(y) {
-              var height = parseInt(this.pdf.internal.getFontSize());
-              // TODO Get descent from font descriptor
-              var descent = height * 0.25;
-              switch (this.ctx.textBaseline) {
-                  case 'bottom':
-                      return y - descent;
-                  case 'top':
-                      return y + height;
-                  case 'hanging':
-                      return y + height - descent;
-                  case 'middle':
-                      return y + height / 2 - descent;
-                  case 'ideographic':
-                      // TODO not implemented
-                      return y;
-                  case 'alphabetic':
-                  default:
-                      return y;
-              }
-          }
-      };
-
-      var c2d = jsPDFAPI.context2d;
-
-      // accessor methods
-      Object.defineProperty(c2d, 'fillStyle', {
-          set: function set(value) {
-              this.setFillStyle(value);
-          },
-          get: function get() {
-              return this.ctx.fillStyle;
-          }
-      });
-      Object.defineProperty(c2d, 'strokeStyle', {
-          set: function set(value) {
-              this.setStrokeStyle(value);
-          },
-          get: function get() {
-              return this.ctx.strokeStyle;
-          }
-      });
-      Object.defineProperty(c2d, 'lineWidth', {
-          set: function set(value) {
-              this.setLineWidth(value);
-          },
-          get: function get() {
-              return this.ctx.lineWidth;
-          }
-      });
-      Object.defineProperty(c2d, 'lineCap', {
-          set: function set(val) {
-              this.setLineCap(val);
-          },
-          get: function get() {
-              return this.ctx.lineCap;
-          }
-      });
-      Object.defineProperty(c2d, 'lineJoin', {
-          set: function set(val) {
-              this.setLineJoin(val);
-          },
-          get: function get() {
-              return this.ctx.lineJoin;
-          }
-      });
-      Object.defineProperty(c2d, 'miterLimit', {
-          set: function set(val) {
-              this.ctx.miterLimit = val;
-          },
-          get: function get() {
-              return this.ctx.miterLimit;
-          }
-      });
-      Object.defineProperty(c2d, 'textBaseline', {
-          set: function set(value) {
-              this.setTextBaseline(value);
-          },
-          get: function get() {
-              return this.getTextBaseline();
-          }
-      });
-      Object.defineProperty(c2d, 'textAlign', {
-          set: function set(value) {
-              this.setTextAlign(value);
-          },
-          get: function get() {
-              return this.getTextAlign();
-          }
-      });
-      Object.defineProperty(c2d, 'font', {
-          set: function set(value) {
-              this.setFont(value);
-          },
-          get: function get() {
-              return this.ctx.font;
-          }
-      });
-      Object.defineProperty(c2d, 'globalCompositeOperation', {
-          set: function set(value) {
-              this.ctx.globalCompositeOperation = value;
-          },
-          get: function get() {
-              return this.ctx.globalCompositeOperation;
-          }
-      });
-      Object.defineProperty(c2d, 'globalAlpha', {
-          set: function set(value) {
-              this.ctx.globalAlpha = value;
-          },
-          get: function get() {
-              return this.ctx.globalAlpha;
-          }
-      });
-      Object.defineProperty(c2d, 'canvas', {
-          get: function get() {
-              return { parentNode: false, style: false };
-          }
-      });
-      // Not HTML API
-      Object.defineProperty(c2d, 'ignoreClearRect', {
-          set: function set(value) {
-              this.ctx.ignoreClearRect = value;
-          },
-          get: function get() {
-              return this.ctx.ignoreClearRect;
-          }
-      });
-      // End Not HTML API
-
-      c2d.internal = {};
-
-      c2d.internal.rxRgb = /rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/;
-      c2d.internal.rxRgba = /rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/;
-      c2d.internal.rxTransparent = /transparent|rgba\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*0+\s*\)/;
-
-      // http://hansmuller-flex.blogspot.com/2011/10/more-about-approximating-circular-arcs.html
-      c2d.internal.arc = function (c2d, xc, yc, r, a1, a2, anticlockwise, style) {
-
-          var k = this.pdf.internal.scaleFactor;
-          var pageHeight = this.pdf.internal.pageSize.getHeight();
-          var f2 = this.pdf.internal.f2;
-
-          var a1r = a1 * (Math.PI / 180);
-          var a2r = a2 * (Math.PI / 180);
-          var curves = this.createArc(r, a1r, a2r, anticlockwise);
-
-          for (var i = 0; i < curves.length; i++) {
-              var curve = curves[i];
-              if (i === 0) {
-                  this.pdf.internal.out([f2((curve.x1 + xc) * k), f2((pageHeight - (curve.y1 + yc)) * k), 'm', f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c'].join(' '));
-              } else {
-                  this.pdf.internal.out([f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c'].join(' '));
-              }
-
-              //c2d._lastPoint = {x: curve.x1 + xc, y: curve.y1 + yc};
-              c2d._lastPoint = { x: xc, y: yc };
-              // f2((curve.x1 + xc) * k), f2((pageHeight - (curve.y1 + yc)) * k), 'm', f2((curve.x2 + xc) * k), f2((pageHeight - (curve.y2 + yc)) * k), f2((curve.x3 + xc) * k), f2((pageHeight - (curve.y3 + yc)) * k), f2((curve.x4 + xc) * k), f2((pageHeight - (curve.y4 + yc)) * k), 'c'
-          }
-
-          if (style !== null) {
-              this.pdf.internal.out(this.pdf.internal.getStyle(style));
-          }
-      };
-
-      /**
-       *
-       * @param x Edge point X
-       * @param y Edge point Y
-       * @param r Radius
-       * @param a1 start angle
-       * @param a2 end angle
-       * @param anticlockwise
-       * @param style
-       * @param isClip
-       */
-      c2d.internal.arc2 = function (c2d, x, y, r, a1, a2, anticlockwise, style, isClip) {
-          // we need to convert from cartesian to polar here methinks.
-          var centerX = x; // + r;
-          var centerY = y;
-
-          if (!isClip) {
-              this.arc(c2d, centerX, centerY, r, a1, a2, anticlockwise, style);
-          } else {
-              this.arc(c2d, centerX, centerY, r, a1, a2, anticlockwise, null);
-              this.pdf.clip_fixed();
-          }
-      };
-
-      c2d.internal.move2 = function (c2d, x, y) {
-          var k = this.pdf.internal.scaleFactor;
-          var pageHeight = this.pdf.internal.pageSize.getHeight();
-          var f2 = this.pdf.internal.f2;
-
-          this.pdf.internal.out([f2(x * k), f2((pageHeight - y) * k), 'm'].join(' '));
-          c2d._lastPoint = { x: x, y: y };
-      };
-
-      c2d.internal.line2 = function (c2d, dx, dy) {
-          var k = this.pdf.internal.scaleFactor;
-          var pageHeight = this.pdf.internal.pageSize.getHeight();
-          var f2 = this.pdf.internal.f2;
-
-          //var pt = {x: c2d._lastPoint.x + dx, y: c2d._lastPoint.y + dy};
-          var pt = { x: dx, y: dy };
-
-          this.pdf.internal.out([f2(pt.x * k), f2((pageHeight - pt.y) * k), 'l'].join(' '));
-          //this.pdf.internal.out('f');
-          c2d._lastPoint = pt;
-      };
-
-      /**
-       * Return a array of objects that represent bezier curves which approximate the circular arc centered at the origin, from startAngle to endAngle (radians) with the specified radius.
-       *
-       * Each bezier curve is an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points.
-       */
-
-      c2d.internal.createArc = function (radius, startAngle, endAngle, anticlockwise) {
-          var EPSILON = 0.00001; // Roughly 1/1000th of a degree, see below
-          var twoPI = Math.PI * 2;
-          var piOverTwo = Math.PI / 2.0;
-
-          // normalize startAngle, endAngle to [0, 2PI]
-          var startAngleN = startAngle;
-          if (startAngleN < twoPI || startAngleN > twoPI) {
-              startAngleN = startAngleN % twoPI;
-          }
-          if (startAngleN < 0) {
-              startAngleN = twoPI + startAngleN;
-          }
-
-          while (startAngle > endAngle) {
-              startAngle = startAngle - twoPI;
-          }
-          var totalAngle = Math.abs(endAngle - startAngle);
-          if (totalAngle < twoPI) {
-              if (anticlockwise) {
-                  totalAngle = twoPI - totalAngle;
-              }
-          }
-
-          // Compute the sequence of arc curves, up to PI/2 at a time.
-          var curves = [];
-          var sgn = anticlockwise ? -1 : +1;
-
-          var a1 = startAngleN;
-          for (; totalAngle > EPSILON;) {
-              var remain = sgn * Math.min(totalAngle, piOverTwo);
-              var a2 = a1 + remain;
-              curves.push(this.createSmallArc(radius, a1, a2));
-              totalAngle -= Math.abs(a2 - a1);
-              a1 = a2;
-          }
-
-          return curves;
-      };
-
-      c2d.internal.getCurrentPage = function () {
-          return this.pdf.internal.pages[this.pdf.internal.getCurrentPageInfo().pageNumber];
-      };
-
-      /**
-       * Cubic bezier approximation of a circular arc centered at the origin, from (radians) a1 to a2, where a2-a1 < pi/2. The arc's radius is r.
-       *
-       * Returns an object with four points, where x1,y1 and x4,y4 are the arc's end points and x2,y2 and x3,y3 are the cubic bezier's control points.
-       *
-       * This algorithm is based on the approach described in: A. Riškus, "Approximation of a Cubic Bezier Curve by Circular Arcs and Vice Versa," Information Technology and Control, 35(4), 2006 pp. 371-378.
-       */
-
-      c2d.internal.createSmallArc = function (r, a1, a2) {
-          // Compute all four points for an arc that subtends the same total angle
-          // but is centered on the X-axis
-
-          var a = (a2 - a1) / 2.0;
-
-          var x4 = r * Math.cos(a);
-          var y4 = r * Math.sin(a);
-          var x1 = x4;
-          var y1 = -y4;
-
-          var q1 = x1 * x1 + y1 * y1;
-          var q2 = q1 + x1 * x4 + y1 * y4;
-          var k2 = 4 / 3 * (Math.sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4);
-
-          var x2 = x1 - k2 * y1;
-          var y2 = y1 + k2 * x1;
-          var x3 = x2;
-          var y3 = -y2;
-
-          // Find the arc points' actual locations by computing x1,y1 and x4,y4
-          // and rotating the control points by a + a1
-
-          var ar = a + a1;
-          var cos_ar = Math.cos(ar);
-          var sin_ar = Math.sin(ar);
-
-          return {
-              x1: r * Math.cos(a1),
-              y1: r * Math.sin(a1),
-              x2: x2 * cos_ar - y2 * sin_ar,
-              y2: x2 * sin_ar + y2 * cos_ar,
-              x3: x3 * cos_ar - y3 * sin_ar,
-              y3: x3 * sin_ar + y3 * cos_ar,
-              x4: r * Math.cos(a2),
-              y4: r * Math.sin(a2)
-          };
-      };
-
-      function context() {
-          this._isStrokeTransparent = false;
-          this._strokeOpacity = 1;
-          this.strokeStyle = '#000000';
-          this.fillStyle = '#000000';
-          this._isFillTransparent = false;
-          this._fillOpacity = 1;
-          this.font = "12pt times";
-          this.textBaseline = 'alphabetic'; // top,bottom,middle,ideographic,alphabetic,hanging
-          this.textAlign = 'start';
-          this.lineWidth = 1;
-          this.lineJoin = 'miter'; // round, bevel, miter
-          this.lineCap = 'butt'; // butt, round, square
-          this._transform = [1, 0, 0, 1, 0, 0]; // sx, shy, shx, sy, tx, ty
-          this.globalCompositeOperation = 'normal';
-          this.globalAlpha = 1.0;
-          this._clip_path = [];
-
-          // TODO miter limit //default 10
-
-          // Not HTML API
-          this.ignoreClearRect = false;
-
-          this.copy = function (ctx) {
-              this._isStrokeTransparent = ctx._isStrokeTransparent;
-              this._strokeOpacity = ctx._strokeOpacity;
-              this.strokeStyle = ctx.strokeStyle;
-              this._isFillTransparent = ctx._isFillTransparent;
-              this._fillOpacity = ctx._fillOpacity;
-              this.fillStyle = ctx.fillStyle;
-              this.font = ctx.font;
-              this.lineWidth = ctx.lineWidth;
-              this.lineJoin = ctx.lineJoin;
-              this.lineCap = ctx.lineCap;
-              this.textBaseline = ctx.textBaseline;
-              this.textAlign = ctx.textAlign;
-              this._fontSize = ctx._fontSize;
-              this._transform = ctx._transform.slice(0);
-              this.globalCompositeOperation = ctx.globalCompositeOperation;
-              this.globalAlpha = ctx.globalAlpha;
-              this._clip_path = ctx._clip_path.slice(0); //TODO deep copy?
-
-              // Not HTML API
-              this.ignoreClearRect = ctx.ignoreClearRect;
-          };
-      }
-
-      return this;
-  })(jsPDF.API, typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global || Function('return typeof this === "object" && this.content')() || Function('return this')());
-
-  /** @preserve
-   * jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser
-   * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
-   *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
-   *               2014 Diego Casorran, https://github.com/diegocr
-   *               2014 Daniel Husar, https://github.com/danielhusar
-   *               2014 Wolfgang Gassler, https://github.com/woolfg
-   *               2014 Steven Spungin, https://github.com/flamenco
-   *
-   * 
-   * ====================================================================
-   */
-
-  (function (jsPDFAPI) {
-  	var clone, _DrillForContent, FontNameDB, FontStyleMap, TextAlignMap, FontWeightMap, FloatMap, ClearMap, GetCSS, PurgeWhiteSpace, Renderer, ResolveFont, ResolveUnitedNumber, UnitedNumberMap, elementHandledElsewhere, images, loadImgs, checkForFooter, process, tableToJson;
-  	clone = function () {
-  		return function (obj) {
-  			Clone.prototype = obj;
-  			return new Clone();
-  		};
-  		function Clone() {}
-  	}();
-  	PurgeWhiteSpace = function PurgeWhiteSpace(array) {
-  		var fragment, i, l, lTrimmed, r, rTrimmed, trailingSpace;
-  		i = 0;
-  		l = array.length;
-  		fragment = void 0;
-  		lTrimmed = false;
-  		rTrimmed = false;
-  		while (!lTrimmed && i !== l) {
-  			fragment = array[i] = array[i].trimLeft();
-  			if (fragment) {
-  				lTrimmed = true;
-  			}
-  			i++;
-  		}
-  		i = l - 1;
-  		while (l && !rTrimmed && i !== -1) {
-  			fragment = array[i] = array[i].trimRight();
-  			if (fragment) {
-  				rTrimmed = true;
-  			}
-  			i--;
-  		}
-  		r = /\s+$/g;
-  		trailingSpace = true;
-  		i = 0;
-  		while (i !== l) {
-  			// Leave the line breaks intact
-  			if (array[i] != "\u2028") {
-  				fragment = array[i].replace(/\s+/g, " ");
-  				if (trailingSpace) {
-  					fragment = fragment.trimLeft();
-  				}
-  				if (fragment) {
-  					trailingSpace = r.test(fragment);
-  				}
-  				array[i] = fragment;
-  			}
-  			i++;
-  		}
-  		return array;
-  	};
-  	Renderer = function Renderer(pdf, x, y, settings) {
-  		this.pdf = pdf;
-  		this.x = x;
-  		this.y = y;
-  		this.settings = settings;
-  		//list of functions which are called after each element-rendering process
-  		this.watchFunctions = [];
-  		this.init();
-  		return this;
-  	};
-  	ResolveFont = function ResolveFont(css_font_family_string) {
-  		var name, part, parts;
-  		name = void 0;
-  		parts = css_font_family_string.split(",");
-  		part = parts.shift();
-  		while (!name && part) {
-  			name = FontNameDB[part.trim().toLowerCase()];
-  			part = parts.shift();
-  		}
-  		return name;
-  	};
-  	ResolveUnitedNumber = function ResolveUnitedNumber(css_line_height_string) {
-
-  		//IE8 issues
-  		css_line_height_string = css_line_height_string === "auto" ? "0px" : css_line_height_string;
-  		if (css_line_height_string.indexOf("em") > -1 && !isNaN(Number(css_line_height_string.replace("em", "")))) {
-  			css_line_height_string = Number(css_line_height_string.replace("em", "")) * 18.719 + "px";
-  		}
-  		if (css_line_height_string.indexOf("pt") > -1 && !isNaN(Number(css_line_height_string.replace("pt", "")))) {
-  			css_line_height_string = Number(css_line_height_string.replace("pt", "")) * 1.333 + "px";
-  		}
-
-  		var normal, undef, value;
-  		undef = void 0;
-  		normal = 16.00;
-  		value = UnitedNumberMap[css_line_height_string];
-  		if (value) {
-  			return value;
-  		}
-  		value = {
-  			"xx-small": 9,
-  			"x-small": 11,
-  			small: 13,
-  			medium: 16,
-  			large: 19,
-  			"x-large": 23,
-  			"xx-large": 28,
-  			auto: 0
-  		}[css_line_height_string];
-
-  		if (value !== undef) {
-  			return UnitedNumberMap[css_line_height_string] = value / normal;
-  		}
-  		if (value = parseFloat(css_line_height_string)) {
-  			return UnitedNumberMap[css_line_height_string] = value / normal;
-  		}
-  		value = css_line_height_string.match(/([\d\.]+)(px)/);
-  		if (Array.isArray(value) && value.length === 3) {
-  			return UnitedNumberMap[css_line_height_string] = parseFloat(value[1]) / normal;
-  		}
-  		return UnitedNumberMap[css_line_height_string] = 1;
-  	};
-  	GetCSS = function GetCSS(element) {
-  		var css, tmp, computedCSSElement;
-  		computedCSSElement = function (el) {
-  			var compCSS;
-  			compCSS = function (el) {
-  				if (document.defaultView && document.defaultView.getComputedStyle) {
-  					return document.defaultView.getComputedStyle(el, null);
-  				} else if (el.currentStyle) {
-  					return el.currentStyle;
-  				} else {
-  					return el.style;
-  				}
-  			}(el);
-  			return function (prop) {
-  				prop = prop.replace(/-\D/g, function (match) {
-  					return match.charAt(1).toUpperCase();
-  				});
-  				return compCSS[prop];
-  			};
-  		}(element);
-  		css = {};
-  		tmp = void 0;
-  		css["font-family"] = ResolveFont(computedCSSElement("font-family")) || "times";
-  		css["font-style"] = FontStyleMap[computedCSSElement("font-style")] || "normal";
-  		css["text-align"] = TextAlignMap[computedCSSElement("text-align")] || "left";
-  		tmp = FontWeightMap[computedCSSElement("font-weight")] || "normal";
-  		if (tmp === "bold") {
-  			if (css["font-style"] === "normal") {
-  				css["font-style"] = tmp;
-  			} else {
-  				css["font-style"] = tmp + css["font-style"];
-  			}
-  		}
-  		css["font-size"] = ResolveUnitedNumber(computedCSSElement("font-size")) || 1;
-  		css["line-height"] = ResolveUnitedNumber(computedCSSElement("line-height")) || 1;
-  		css["display"] = computedCSSElement("display") === "inline" ? "inline" : "block";
-
-  		tmp = css["display"] === "block";
-  		css["margin-top"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-top")) || 0;
-  		css["margin-bottom"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-bottom")) || 0;
-  		css["padding-top"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-top")) || 0;
-  		css["padding-bottom"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-bottom")) || 0;
-  		css["margin-left"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-left")) || 0;
-  		css["margin-right"] = tmp && ResolveUnitedNumber(computedCSSElement("margin-right")) || 0;
-  		css["padding-left"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-left")) || 0;
-  		css["padding-right"] = tmp && ResolveUnitedNumber(computedCSSElement("padding-right")) || 0;
-
-  		css["page-break-before"] = computedCSSElement("page-break-before") || "auto";
-
-  		//float and clearing of floats
-  		css["float"] = FloatMap[computedCSSElement("cssFloat")] || "none";
-  		css["clear"] = ClearMap[computedCSSElement("clear")] || "none";
-
-  		css["color"] = computedCSSElement("color");
-
-  		return css;
-  	};
-  	elementHandledElsewhere = function elementHandledElsewhere(element, renderer, elementHandlers) {
-  		var handlers, i, isHandledElsewhere, l, classNames;
-  		isHandledElsewhere = false;
-  		i = void 0;
-  		l = void 0;
-  		handlers = elementHandlers["#" + element.id];
-  		if (handlers) {
-  			if (typeof handlers === "function") {
-  				isHandledElsewhere = handlers(element, renderer);
-  			} else {
-  				i = 0;
-  				l = handlers.length;
-  				while (!isHandledElsewhere && i !== l) {
-  					isHandledElsewhere = handlers[i](element, renderer);
-  					i++;
-  				}
-  			}
-  		}
-  		handlers = elementHandlers[element.nodeName];
-  		if (!isHandledElsewhere && handlers) {
-  			if (typeof handlers === "function") {
-  				isHandledElsewhere = handlers(element, renderer);
-  			} else {
-  				i = 0;
-  				l = handlers.length;
-  				while (!isHandledElsewhere && i !== l) {
-  					isHandledElsewhere = handlers[i](element, renderer);
-  					i++;
-  				}
-  			}
-  		}
-
-  		// Try class names
-  		classNames = typeof element.className === 'string' ? element.className.split(' ') : [];
-  		for (i = 0; i < classNames.length; i++) {
-  			handlers = elementHandlers['.' + classNames[i]];
-  			if (!isHandledElsewhere && handlers) {
-  				if (typeof handlers === "function") {
-  					isHandledElsewhere = handlers(element, renderer);
-  				} else {
-  					i = 0;
-  					l = handlers.length;
-  					while (!isHandledElsewhere && i !== l) {
-  						isHandledElsewhere = handlers[i](element, renderer);
-  						i++;
-  					}
-  				}
-  			}
-  		}
-
-  		return isHandledElsewhere;
-  	};
-  	tableToJson = function tableToJson(table, renderer) {
-  		var data, headers, i, j, rowData, tableRow, table_obj, table_with, cell, l;
-  		data = [];
-  		headers = [];
-  		i = 0;
-  		l = table.rows[0].cells.length;
-  		table_with = table.clientWidth;
-  		while (i < l) {
-  			cell = table.rows[0].cells[i];
-  			headers[i] = {
-  				name: cell.textContent.toLowerCase().replace(/\s+/g, ''),
-  				prompt: cell.textContent.replace(/\r?\n/g, ''),
-  				width: cell.clientWidth / table_with * renderer.pdf.internal.pageSize.getWidth()
-  			};
-  			i++;
-  		}
-  		i = 1;
-  		while (i < table.rows.length) {
-  			tableRow = table.rows[i];
-  			rowData = {};
-  			j = 0;
-  			while (j < tableRow.cells.length) {
-  				rowData[headers[j].name] = tableRow.cells[j].textContent.replace(/\r?\n/g, '');
-  				j++;
-  			}
-  			data.push(rowData);
-  			i++;
-  		}
-  		return table_obj = {
-  			rows: data,
-  			headers: headers
-  		};
-  	};
-  	var SkipNode = {
-  		SCRIPT: 1,
-  		STYLE: 1,
-  		NOSCRIPT: 1,
-  		OBJECT: 1,
-  		EMBED: 1,
-  		SELECT: 1
-  	};
-  	var listCount = 1;
-  	_DrillForContent = function DrillForContent(element, renderer, elementHandlers) {
-  		var cn, cns, fragmentCSS, i, isBlock, l, table2json, cb;
-  		cns = element.childNodes;
-  		cn = void 0;
-  		fragmentCSS = GetCSS(element);
-  		isBlock = fragmentCSS.display === "block";
-  		if (isBlock) {
-  			renderer.setBlockBoundary();
-  			renderer.setBlockStyle(fragmentCSS);
-  		}
-  		i = 0;
-  		l = cns.length;
-  		while (i < l) {
-  			cn = cns[i];
-  			if ((typeof cn === "undefined" ? "undefined" : _typeof(cn)) === "object") {
-
-  				//execute all watcher functions to e.g. reset floating
-  				renderer.executeWatchFunctions(cn);
-
-  				/*** HEADER rendering **/
-  				if (cn.nodeType === 1 && cn.nodeName === 'HEADER') {
-  					var header = cn;
-  					//store old top margin
-  					var oldMarginTop = renderer.pdf.margins_doc.top;
-  					//subscribe for new page event and render header first on every page
-  					renderer.pdf.internal.events.subscribe('addPage', function (pageInfo) {
-  						//set current y position to old margin
-  						renderer.y = oldMarginTop;
-  						//render all child nodes of the header element
-  						_DrillForContent(header, renderer, elementHandlers);
-  						//set margin to old margin + rendered header + 10 space to prevent overlapping
-  						//important for other plugins (e.g. table) to start rendering at correct position after header
-  						renderer.pdf.margins_doc.top = renderer.y + 10;
-  						renderer.y += 10;
-  					}, false);
-  				}
-
-  				if (cn.nodeType === 8 && cn.nodeName === "#comment") {
-  					if (~cn.textContent.indexOf("ADD_PAGE")) {
-  						renderer.pdf.addPage();
-  						renderer.y = renderer.pdf.margins_doc.top;
-  					}
-  				} else if (cn.nodeType === 1 && !SkipNode[cn.nodeName]) {
-  					/*** IMAGE RENDERING ***/
-  					var cached_image;
-  					if (cn.nodeName === "IMG") {
-  						var url = cn.getAttribute("src");
-  						cached_image = images[renderer.pdf.sHashCode(url) || url];
-  					}
-  					if (cached_image) {
-  						if (renderer.pdf.internal.pageSize.getHeight() - renderer.pdf.margins_doc.bottom < renderer.y + cn.height && renderer.y > renderer.pdf.margins_doc.top) {
-  							renderer.pdf.addPage();
-  							renderer.y = renderer.pdf.margins_doc.top;
-  							//check if we have to set back some values due to e.g. header rendering for new page
-  							renderer.executeWatchFunctions(cn);
-  						}
-
-  						var imagesCSS = GetCSS(cn);
-  						var imageX = renderer.x;
-  						var fontToUnitRatio = 12 / renderer.pdf.internal.scaleFactor;
-
-  						//define additional paddings, margins which have to be taken into account for margin calculations
-  						var additionalSpaceLeft = (imagesCSS["margin-left"] + imagesCSS["padding-left"]) * fontToUnitRatio;
-  						var additionalSpaceRight = (imagesCSS["margin-right"] + imagesCSS["padding-right"]) * fontToUnitRatio;
-  						var additionalSpaceTop = (imagesCSS["margin-top"] + imagesCSS["padding-top"]) * fontToUnitRatio;
-  						var additionalSpaceBottom = (imagesCSS["margin-bottom"] + imagesCSS["padding-bottom"]) * fontToUnitRatio;
-
-  						//if float is set to right, move the image to the right border
-  						//add space if margin is set
-  						if (imagesCSS['float'] !== undefined && imagesCSS['float'] === 'right') {
-  							imageX += renderer.settings.width - cn.width - additionalSpaceRight;
-  						} else {
-  							imageX += additionalSpaceLeft;
-  						}
-
-  						renderer.pdf.addImage(cached_image, imageX, renderer.y + additionalSpaceTop, cn.width, cn.height);
-  						cached_image = undefined;
-  						//if the float prop is specified we have to float the text around the image
-  						if (imagesCSS['float'] === 'right' || imagesCSS['float'] === 'left') {
-  							//add functiont to set back coordinates after image rendering
-  							renderer.watchFunctions.push(function (diffX, thresholdY, diffWidth, el) {
-  								//undo drawing box adaptions which were set by floating
-  								if (renderer.y >= thresholdY) {
-  									renderer.x += diffX;
-  									renderer.settings.width += diffWidth;
-  									return true;
-  								} else if (el && el.nodeType === 1 && !SkipNode[el.nodeName] && renderer.x + el.width > renderer.pdf.margins_doc.left + renderer.pdf.margins_doc.width) {
-  									renderer.x += diffX;
-  									renderer.y = thresholdY;
-  									renderer.settings.width += diffWidth;
-  									return true;
-  								} else {
-  									return false;
-  								}
-  							}.bind(this, imagesCSS['float'] === 'left' ? -cn.width - additionalSpaceLeft - additionalSpaceRight : 0, renderer.y + cn.height + additionalSpaceTop + additionalSpaceBottom, cn.width));
-  							//reset floating by clear:both divs
-  							//just set cursorY after the floating element
-  							renderer.watchFunctions.push(function (yPositionAfterFloating, pages, el) {
-  								if (renderer.y < yPositionAfterFloating && pages === renderer.pdf.internal.getNumberOfPages()) {
-  									if (el.nodeType === 1 && GetCSS(el).clear === 'both') {
-  										renderer.y = yPositionAfterFloating;
-  										return true;
-  									} else {
-  										return false;
-  									}
-  								} else {
-  									return true;
-  								}
-  							}.bind(this, renderer.y + cn.height, renderer.pdf.internal.getNumberOfPages()));
-
-  							//if floating is set we decrease the available width by the image width
-  							renderer.settings.width -= cn.width + additionalSpaceLeft + additionalSpaceRight;
-  							//if left just add the image width to the X coordinate
-  							if (imagesCSS['float'] === 'left') {
-  								renderer.x += cn.width + additionalSpaceLeft + additionalSpaceRight;
-  							}
-  						} else {
-  							//if no floating is set, move the rendering cursor after the image height
-  							renderer.y += cn.height + additionalSpaceTop + additionalSpaceBottom;
-  						}
-
-  						/*** TABLE RENDERING ***/
-  					} else if (cn.nodeName === "TABLE") {
-  						table2json = tableToJson(cn, renderer);
-  						renderer.y += 10;
-  						renderer.pdf.table(renderer.x, renderer.y, table2json.rows, table2json.headers, {
-  							autoSize: false,
-  							printHeaders: elementHandlers.printHeaders,
-  							margins: renderer.pdf.margins_doc,
-  							css: GetCSS(cn)
-  						});
-  						renderer.y = renderer.pdf.lastCellPos.y + renderer.pdf.lastCellPos.h + 20;
-  					} else if (cn.nodeName === "OL" || cn.nodeName === "UL") {
-  						listCount = 1;
-  						if (!elementHandledElsewhere(cn, renderer, elementHandlers)) {
-  							_DrillForContent(cn, renderer, elementHandlers);
-  						}
-  						renderer.y += 10;
-  					} else if (cn.nodeName === "LI") {
-  						var temp = renderer.x;
-  						renderer.x += 20 / renderer.pdf.internal.scaleFactor;
-  						renderer.y += 3;
-  						if (!elementHandledElsewhere(cn, renderer, elementHandlers)) {
-  							_DrillForContent(cn, renderer, elementHandlers);
-  						}
-  						renderer.x = temp;
-  					} else if (cn.nodeName === "BR") {
-  						renderer.y += fragmentCSS["font-size"] * renderer.pdf.internal.scaleFactor;
-  						renderer.addText("\u2028", clone(fragmentCSS));
-  					} else {
-  						if (!elementHandledElsewhere(cn, renderer, elementHandlers)) {
-  							_DrillForContent(cn, renderer, elementHandlers);
-  						}
-  					}
-  				} else if (cn.nodeType === 3) {
-  					var value = cn.nodeValue;
-  					if (cn.nodeValue && cn.parentNode.nodeName === "LI") {
-  						if (cn.parentNode.parentNode.nodeName === "OL") {
-  							value = listCount++ + '. ' + value;
-  						} else {
-  							var fontSize = fragmentCSS["font-size"];
-  							var offsetX = (3 - fontSize * 0.75) * renderer.pdf.internal.scaleFactor;
-  							var offsetY = fontSize * 0.75 * renderer.pdf.internal.scaleFactor;
-  							var radius = fontSize * 1.74 / renderer.pdf.internal.scaleFactor;
-  							cb = function cb(x, y) {
-  								this.pdf.circle(x + offsetX, y + offsetY, radius, 'FD');
-  							};
-  						}
-  					}
-  					// Only add the text if the text node is in the body element
-  					// Add compatibility with IE11
-  					if (!!(cn.ownerDocument.body.compareDocumentPosition(cn) & 16)) {
-  						renderer.addText(value, fragmentCSS);
-  					}
-  				} else if (typeof cn === "string") {
-  					renderer.addText(cn, fragmentCSS);
-  				}
-  			}
-  			i++;
-  		}
-  		elementHandlers.outY = renderer.y;
-
-  		if (isBlock) {
-  			return renderer.setBlockBoundary(cb);
-  		}
-  	};
-  	images = {};
-  	loadImgs = function loadImgs(element, renderer, elementHandlers, cb) {
-  		var imgs = element.getElementsByTagName('img'),
-  		    l = imgs.length,
-  		    found_images,
-  		    x = 0;
-  		function done() {
-  			renderer.pdf.internal.events.publish('imagesLoaded');
-  			cb(found_images);
-  		}
-  		function loadImage(url, width, height) {
-  			if (!url) return;
-  			var img = new Image();
-  			found_images = ++x;
-  			img.crossOrigin = '';
-  			img.onerror = img.onload = function () {
-  				if (img.complete) {
-  					//to support data urls in images, set width and height
-  					//as those values are not recognized automatically
-  					if (img.src.indexOf('data:image/') === 0) {
-  						img.width = width || img.width || 0;
-  						img.height = height || img.height || 0;
-  					}
-  					//if valid image add to known images array
-  					if (img.width + img.height) {
-  						var hash = renderer.pdf.sHashCode(url) || url;
-  						images[hash] = images[hash] || img;
-  					}
-  				}
-  				if (! --x) {
-  					done();
-  				}
-  			};
-  			img.src = url;
-  		}
-  		while (l--) {
-  			loadImage(imgs[l].getAttribute("src"), imgs[l].width, imgs[l].height);
-  		}return x || done();
-  	};
-  	checkForFooter = function checkForFooter(elem, renderer, elementHandlers) {
-  		//check if we can found a <footer> element
-  		var footer = elem.getElementsByTagName("footer");
-  		if (footer.length > 0) {
-
-  			footer = footer[0];
-
-  			//bad hack to get height of footer
-  			//creat dummy out and check new y after fake rendering
-  			var oldOut = renderer.pdf.internal.write;
-  			var oldY = renderer.y;
-  			renderer.pdf.internal.write = function () {};
-  			_DrillForContent(footer, renderer, elementHandlers);
-  			var footerHeight = Math.ceil(renderer.y - oldY) + 5;
-  			renderer.y = oldY;
-  			renderer.pdf.internal.write = oldOut;
-
-  			//add 20% to prevent overlapping
-  			renderer.pdf.margins_doc.bottom += footerHeight;
-
-  			//Create function render header on every page
-  			var renderFooter = function renderFooter(pageInfo) {
-  				var pageNumber = pageInfo !== undefined ? pageInfo.pageNumber : 1;
-  				//set current y position to old margin
-  				var oldPosition = renderer.y;
-  				//render all child nodes of the header element
-  				renderer.y = renderer.pdf.internal.pageSize.getHeight() - renderer.pdf.margins_doc.bottom;
-  				renderer.pdf.margins_doc.bottom -= footerHeight;
-
-  				//check if we have to add page numbers
-  				var spans = footer.getElementsByTagName('span');
-  				for (var i = 0; i < spans.length; ++i) {
-  					//if we find some span element with class pageCounter, set the page
-  					if ((" " + spans[i].className + " ").replace(/[\n\t]/g, " ").indexOf(" pageCounter ") > -1) {
-  						spans[i].innerHTML = pageNumber;
-  					}
-  					//if we find some span element with class totalPages, set a variable which is replaced after rendering of all pages
-  					if ((" " + spans[i].className + " ").replace(/[\n\t]/g, " ").indexOf(" totalPages ") > -1) {
-  						spans[i].innerHTML = '###jsPDFVarTotalPages###';
-  					}
-  				}
-
-  				//render footer content
-  				_DrillForContent(footer, renderer, elementHandlers);
-  				//set bottom margin to previous height including the footer height
-  				renderer.pdf.margins_doc.bottom += footerHeight;
-  				//important for other plugins (e.g. table) to start rendering at correct position after header
-  				renderer.y = oldPosition;
-  			};
-
-  			//check if footer contains totalPages which should be replace at the disoposal of the document
-  			var spans = footer.getElementsByTagName('span');
-  			for (var i = 0; i < spans.length; ++i) {
-  				if ((" " + spans[i].className + " ").replace(/[\n\t]/g, " ").indexOf(" totalPages ") > -1) {
-  					renderer.pdf.internal.events.subscribe('htmlRenderingFinished', renderer.pdf.putTotalPages.bind(renderer.pdf, '###jsPDFVarTotalPages###'), true);
-  				}
-  			}
-
-  			//register event to render footer on every new page
-  			renderer.pdf.internal.events.subscribe('addPage', renderFooter, false);
-  			//render footer on first page
-  			renderFooter();
-
-  			//prevent footer rendering
-  			SkipNode['FOOTER'] = 1;
-  		}
-  	};
-  	process = function process(pdf, element, x, y, settings, callback) {
-  		if (!element) return false;
-  		if (typeof element !== "string" && !element.parentNode) element = '' + element.innerHTML;
-  		if (typeof element === "string") {
-  			element = function (element) {
-  				var $frame, $hiddendiv, framename, visuallyhidden;
-  				framename = "jsPDFhtmlText" + Date.now().toString() + (Math.random() * 1000).toFixed(0);
-  				visuallyhidden = "position: absolute !important;" + "clip: rect(1px 1px 1px 1px); /* IE6, IE7 */" + "clip: rect(1px, 1px, 1px, 1px);" + "padding:0 !important;" + "border:0 !important;" + "height: 1px !important;" + "width: 1px !important; " + "top:auto;" + "left:-100px;" + "overflow: hidden;";
-  				$hiddendiv = document.createElement('div');
-  				$hiddendiv.style.cssText = visuallyhidden;
-  				$hiddendiv.innerHTML = "<iframe style=\"height:1px;width:1px\" name=\"" + framename + "\" />";
-  				document.body.appendChild($hiddendiv);
-  				$frame = window.frames[framename];
-  				$frame.document.open();
-  				$frame.document.writeln(element);
-  				$frame.document.close();
-  				return $frame.document.body;
-  			}(element.replace(/<\/?script[^>]*?>/gi, ''));
-  		}
-  		var r = new Renderer(pdf, x, y, settings),
-  		    out;
-
-  		// 1. load images
-  		// 2. prepare optional footer elements
-  		// 3. render content
-  		loadImgs.call(this, element, r, settings.elementHandlers, function (found_images) {
-  			checkForFooter(element, r, settings.elementHandlers);
-  			_DrillForContent(element, r, settings.elementHandlers);
-  			//send event dispose for final taks (e.g. footer totalpage replacement)
-  			r.pdf.internal.events.publish('htmlRenderingFinished');
-  			out = r.dispose();
-  			if (typeof callback === 'function') callback(out);else if (found_images) console.error('jsPDF Warning: rendering issues? provide a callback to fromHTML!');
-  		});
-  		return out || { x: r.x, y: r.y };
-  	};
-  	Renderer.prototype.init = function () {
-  		this.paragraph = {
-  			text: [],
-  			style: []
-  		};
-  		return this.pdf.internal.write("q");
-  	};
-  	Renderer.prototype.dispose = function () {
-  		this.pdf.internal.write("Q");
-  		return {
-  			x: this.x,
-  			y: this.y,
-  			ready: true
-  		};
-  	};
-
-  	//Checks if we have to execute some watcher functions
-  	//e.g. to end text floating around an image
-  	Renderer.prototype.executeWatchFunctions = function (el) {
-  		var ret = false;
-  		var narray = [];
-  		if (this.watchFunctions.length > 0) {
-  			for (var i = 0; i < this.watchFunctions.length; ++i) {
-  				if (this.watchFunctions[i](el) === true) {
-  					ret = true;
-  				} else {
-  					narray.push(this.watchFunctions[i]);
-  				}
-  			}
-  			this.watchFunctions = narray;
-  		}
-  		return ret;
-  	};
-
-  	Renderer.prototype.splitFragmentsIntoLines = function (fragments, styles) {
-  		var currentLineLength, defaultFontSize, ff, fontMetrics, fontMetricsCache, fragment, fragmentChopped, fragmentLength, fragmentSpecificMetrics, fs, k, line, lines, maxLineLength, style;
-  		defaultFontSize = 12;
-  		k = this.pdf.internal.scaleFactor;
-  		fontMetricsCache = {};
-  		ff = void 0;
-  		fs = void 0;
-  		fontMetrics = void 0;
-  		fragment = void 0;
-  		style = void 0;
-  		fragmentSpecificMetrics = void 0;
-  		fragmentLength = void 0;
-  		fragmentChopped = void 0;
-  		line = [];
-  		lines = [line];
-  		currentLineLength = 0;
-  		maxLineLength = this.settings.width;
-  		while (fragments.length) {
-  			fragment = fragments.shift();
-  			style = styles.shift();
-  			if (fragment) {
-  				ff = style["font-family"];
-  				fs = style["font-style"];
-  				fontMetrics = fontMetricsCache[ff + fs];
-  				if (!fontMetrics) {
-  					fontMetrics = this.pdf.internal.getFont(ff, fs).metadata.Unicode;
-  					fontMetricsCache[ff + fs] = fontMetrics;
-  				}
-  				fragmentSpecificMetrics = {
-  					widths: fontMetrics.widths,
-  					kerning: fontMetrics.kerning,
-  					fontSize: style["font-size"] * defaultFontSize,
-  					textIndent: currentLineLength
-  				};
-  				fragmentLength = this.pdf.getStringUnitWidth(fragment, fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k;
-  				if (fragment == "\u2028") {
-  					line = [];
-  					lines.push(line);
-  				} else if (currentLineLength + fragmentLength > maxLineLength) {
-  					fragmentChopped = this.pdf.splitTextToSize(fragment, maxLineLength, fragmentSpecificMetrics);
-  					line.push([fragmentChopped.shift(), style]);
-  					while (fragmentChopped.length) {
-  						line = [[fragmentChopped.shift(), style]];
-  						lines.push(line);
-  					}
-  					currentLineLength = this.pdf.getStringUnitWidth(line[0][0], fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k;
-  				} else {
-  					line.push([fragment, style]);
-  					currentLineLength += fragmentLength;
-  				}
-  			}
-  		}
-
-  		//if text alignment was set, set margin/indent of each line
-  		if (style['text-align'] !== undefined && (style['text-align'] === 'center' || style['text-align'] === 'right' || style['text-align'] === 'justify')) {
-  			for (var i = 0; i < lines.length; ++i) {
-  				var length = this.pdf.getStringUnitWidth(lines[i][0][0], fragmentSpecificMetrics) * fragmentSpecificMetrics.fontSize / k;
-  				//if there is more than on line we have to clone the style object as all lines hold a reference on this object
-  				if (i > 0) {
-  					lines[i][0][1] = clone(lines[i][0][1]);
-  				}
-  				var space = maxLineLength - length;
-
-  				if (style['text-align'] === 'right') {
-  					lines[i][0][1]['margin-left'] = space;
-  					//if alignment is not right, it has to be center so split the space to the left and the right
-  				} else if (style['text-align'] === 'center') {
-  					lines[i][0][1]['margin-left'] = space / 2;
-  					//if justify was set, calculate the word spacing and define in by using the css property
-  				} else if (style['text-align'] === 'justify') {
-  					var countSpaces = lines[i][0][0].split(' ').length - 1;
-  					lines[i][0][1]['word-spacing'] = space / countSpaces;
-  					//ignore the last line in justify mode
-  					if (i === lines.length - 1) {
-  						lines[i][0][1]['word-spacing'] = 0;
-  					}
-  				}
-  			}
-  		}
-
-  		return lines;
-  	};
-  	Renderer.prototype.RenderTextFragment = function (text, style) {
-  		var defaultFontSize, font, maxLineHeight;
-
-  		maxLineHeight = 0;
-  		defaultFontSize = 12;
-
-  		if (this.pdf.internal.pageSize.getHeight() - this.pdf.margins_doc.bottom < this.y + this.pdf.internal.getFontSize()) {
-  			this.pdf.internal.write("ET", "Q");
-  			this.pdf.addPage();
-  			this.y = this.pdf.margins_doc.top;
-  			this.pdf.internal.write("q", "BT", this.getPdfColor(style.color), this.pdf.internal.getCoordinateString(this.x), this.pdf.internal.getVerticalCoordinateString(this.y), "Td");
-  			//move cursor by one line on new page
-  			maxLineHeight = Math.max(maxLineHeight, style["line-height"], style["font-size"]);
-  			this.pdf.internal.write(0, (-1 * defaultFontSize * maxLineHeight).toFixed(2), "Td");
-  		}
-
-  		font = this.pdf.internal.getFont(style["font-family"], style["font-style"]);
-
-  		// text color
-  		var pdfTextColor = this.getPdfColor(style["color"]);
-  		if (pdfTextColor !== this.lastTextColor) {
-  			this.pdf.internal.write(pdfTextColor);
-  			this.lastTextColor = pdfTextColor;
-  		}
-
-  		//set the word spacing for e.g. justify style
-  		if (style['word-spacing'] !== undefined && style['word-spacing'] > 0) {
-  			this.pdf.internal.write(style['word-spacing'].toFixed(2), "Tw");
-  		}
-
-  		this.pdf.internal.write("/" + font.id, (defaultFontSize * style["font-size"]).toFixed(2), "Tf", "(" + this.pdf.internal.pdfEscape(text) + ") Tj");
-
-  		//set the word spacing back to neutral => 0
-  		if (style['word-spacing'] !== undefined) {
-  			this.pdf.internal.write(0, "Tw");
-  		}
-  	};
-
-  	// Accepts #FFFFFF, rgb(int,int,int), or CSS Color Name
-  	Renderer.prototype.getPdfColor = function (style) {
-  		var textColor;
-  		var r, g, b;
-
-  		var rgbColor = new RGBColor(style);
-  		var rx = /rgb\s*\(\s*(\d+),\s*(\d+),\s*(\d+\s*)\)/;
-  		var m = rx.exec(style);
-  		if (m != null) {
-  			r = parseInt(m[1]);
-  			g = parseInt(m[2]);
-  			b = parseInt(m[3]);
-  		} else {
-  			if (style.charAt(0) != '#') {
-  				if (rgbColor.ok) {
-  					style = rgbColor.toHex();
-  				} else {
-  					style = '#000000';
-  				}
-  			}
-  			r = style.substring(1, 3);
-  			r = parseInt(r, 16);
-  			g = style.substring(3, 5);
-  			g = parseInt(g, 16);
-  			b = style.substring(5, 7);
-  			b = parseInt(b, 16);
-  		}
-
-  		if (typeof r === 'string' && /^#[0-9A-Fa-f]{6}$/.test(r)) {
-  			var hex = parseInt(r.substr(1), 16);
-  			r = hex >> 16 & 255;
-  			g = hex >> 8 & 255;
-  			b = hex & 255;
-  		}
-
-  		var f3 = this.f3;
-  		if (r === 0 && g === 0 && b === 0 || typeof g === 'undefined') {
-  			textColor = f3(r / 255) + ' g';
-  		} else {
-  			textColor = [f3(r / 255), f3(g / 255), f3(b / 255), 'rg'].join(' ');
-  		}
-  		return textColor;
-  	};
-
-  	Renderer.prototype.f3 = function (number) {
-  		return number.toFixed(3); // Ie, %.3f
-  	}, Renderer.prototype.renderParagraph = function (cb) {
-  		var blockstyle, defaultFontSize, fontToUnitRatio, fragments, i, l, line, lines, maxLineHeight, out, paragraphspacing_after, paragraphspacing_before, priorblockstyle, styles, fontSize;
-  		fragments = PurgeWhiteSpace(this.paragraph.text);
-  		styles = this.paragraph.style;
-  		blockstyle = this.paragraph.blockstyle;
-  		priorblockstyle = this.paragraph.priorblockstyle || {};
-  		this.paragraph = {
-  			text: [],
-  			style: [],
-  			blockstyle: {},
-  			priorblockstyle: blockstyle
-  		};
-  		if (!fragments.join("").trim()) {
-  			return;
-  		}
-  		lines = this.splitFragmentsIntoLines(fragments, styles);
-  		line = void 0;
-  		maxLineHeight = void 0;
-  		defaultFontSize = 12;
-  		fontToUnitRatio = defaultFontSize / this.pdf.internal.scaleFactor;
-  		this.priorMarginBottom = this.priorMarginBottom || 0;
-  		paragraphspacing_before = (Math.max((blockstyle["margin-top"] || 0) - this.priorMarginBottom, 0) + (blockstyle["padding-top"] || 0)) * fontToUnitRatio;
-  		paragraphspacing_after = ((blockstyle["margin-bottom"] || 0) + (blockstyle["padding-bottom"] || 0)) * fontToUnitRatio;
-  		this.priorMarginBottom = blockstyle["margin-bottom"] || 0;
-
-  		if (blockstyle['page-break-before'] === 'always') {
-  			this.pdf.addPage();
-  			this.y = 0;
-  			paragraphspacing_before = ((blockstyle["margin-top"] || 0) + (blockstyle["padding-top"] || 0)) * fontToUnitRatio;
-  		}
-
-  		out = this.pdf.internal.write;
-  		i = void 0;
-  		l = void 0;
-  		this.y += paragraphspacing_before;
-  		out("q", "BT 0 g", this.pdf.internal.getCoordinateString(this.x), this.pdf.internal.getVerticalCoordinateString(this.y), "Td");
-
-  		//stores the current indent of cursor position
-  		var currentIndent = 0;
-
-  		while (lines.length) {
-  			line = lines.shift();
-  			maxLineHeight = 0;
-  			i = 0;
-  			l = line.length;
-  			while (i !== l) {
-  				if (line[i][0].trim()) {
-  					maxLineHeight = Math.max(maxLineHeight, line[i][1]["line-height"], line[i][1]["font-size"]);
-  					fontSize = line[i][1]["font-size"] * 7;
-  				}
-  				i++;
-  			}
-  			//if we have to move the cursor to adapt the indent
-  			var indentMove = 0;
-  			var wantedIndent = 0;
-  			//if a margin was added (by e.g. a text-alignment), move the cursor
-  			if (line[0][1]["margin-left"] !== undefined && line[0][1]["margin-left"] > 0) {
-  				wantedIndent = this.pdf.internal.getCoordinateString(line[0][1]["margin-left"]);
-  				indentMove = wantedIndent - currentIndent;
-  				currentIndent = wantedIndent;
-  			}
-  			var indentMore = Math.max(blockstyle["margin-left"] || 0, 0) * fontToUnitRatio;
-  			//move the cursor
-  			out(indentMove + indentMore, (-1 * defaultFontSize * maxLineHeight).toFixed(2), "Td");
-  			i = 0;
-  			l = line.length;
-  			while (i !== l) {
-  				if (line[i][0]) {
-  					this.RenderTextFragment(line[i][0], line[i][1]);
-  				}
-  				i++;
-  			}
-  			this.y += maxLineHeight * fontToUnitRatio;
-
-  			//if some watcher function was executed successful, so e.g. margin and widths were changed,
-  			//reset line drawing and calculate position and lines again
-  			//e.g. to stop text floating around an image
-  			if (this.executeWatchFunctions(line[0][1]) && lines.length > 0) {
-  				var localFragments = [];
-  				var localStyles = [];
-  				//create fragment array of
-  				lines.forEach(function (localLine) {
-  					var i = 0;
-  					var l = localLine.length;
-  					while (i !== l) {
-  						if (localLine[i][0]) {
-  							localFragments.push(localLine[i][0] + ' ');
-  							localStyles.push(localLine[i][1]);
-  						}
-  						++i;
-  					}
-  				});
-  				//split lines again due to possible coordinate changes
-  				lines = this.splitFragmentsIntoLines(PurgeWhiteSpace(localFragments), localStyles);
-  				//reposition the current cursor
-  				out("ET", "Q");
-  				out("q", "BT 0 g", this.pdf.internal.getCoordinateString(this.x), this.pdf.internal.getVerticalCoordinateString(this.y), "Td");
-  			}
-  		}
-  		if (cb && typeof cb === "function") {
-  			cb.call(this, this.x - 9, this.y - fontSize / 2);
-  		}
-  		out("ET", "Q");
-  		return this.y += paragraphspacing_after;
-  	};
-  	Renderer.prototype.setBlockBoundary = function (cb) {
-  		return this.renderParagraph(cb);
-  	};
-  	Renderer.prototype.setBlockStyle = function (css) {
-  		return this.paragraph.blockstyle = css;
-  	};
-  	Renderer.prototype.addText = function (text, css) {
-  		this.paragraph.text.push(text);
-  		return this.paragraph.style.push(css);
-  	};
-  	FontNameDB = {
-  		helvetica: "helvetica",
-  		"sans-serif": "helvetica",
-  		"times new roman": "times",
-  		serif: "times",
-  		times: "times",
-  		monospace: "courier",
-  		courier: "courier"
-  	};
-  	FontWeightMap = {
-  		100: "normal",
-  		200: "normal",
-  		300: "normal",
-  		400: "normal",
-  		500: "bold",
-  		600: "bold",
-  		700: "bold",
-  		800: "bold",
-  		900: "bold",
-  		normal: "normal",
-  		bold: "bold",
-  		bolder: "bold",
-  		lighter: "normal"
-  	};
-  	FontStyleMap = {
-  		normal: "normal",
-  		italic: "italic",
-  		oblique: "italic"
-  	};
-  	TextAlignMap = {
-  		left: "left",
-  		right: "right",
-  		center: "center",
-  		justify: "justify"
-  	};
-  	FloatMap = {
-  		none: 'none',
-  		right: 'right',
-  		left: 'left'
-  	};
-  	ClearMap = {
-  		none: 'none',
-  		both: 'both'
-  	};
-  	UnitedNumberMap = {
-  		normal: 1
-  	};
-  	/**
-    * Converts HTML-formatted text into formatted PDF text.
-    *
-    * Notes:
-    * 2012-07-18
-    * Plugin relies on having browser, DOM around. The HTML is pushed into dom and traversed.
-    * Plugin relies on jQuery for CSS extraction.
-    * Targeting HTML output from Markdown templating, which is a very simple
-    * markup - div, span, em, strong, p. No br-based paragraph separation supported explicitly (but still may work.)
-    * Images, tables are NOT supported.
-    *
-    * @public
-    * @function
-    * @param HTML {String or DOM Element} HTML-formatted text, or pointer to DOM element that is to be rendered into PDF.
-    * @param x {Number} starting X coordinate in jsPDF instance's declared units.
-    * @param y {Number} starting Y coordinate in jsPDF instance's declared units.
-    * @param settings {Object} Additional / optional variables controlling parsing, rendering.
-    * @returns {Object} jsPDF instance
-    */
-  	jsPDFAPI.fromHTML = function (HTML, x, y, settings, callback, margins) {
-
-  		this.margins_doc = margins || {
-  			top: 0,
-  			bottom: 0
-  		};
-  		if (!settings) settings = {};
-  		if (!settings.elementHandlers) settings.elementHandlers = {};
-
-  		return process(this, HTML, isNaN(x) ? 4 : x, isNaN(y) ? 4 : y, settings, callback);
-  	};
-  })(jsPDF.API);
-
-  /** ==================================================================== 
-   * jsPDF JavaScript plugin
-   * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
-   * 
-   * 
-   * ====================================================================
-   */
-
-  /*global jsPDF */
-
-  (function (jsPDFAPI) {
-
-      var jsNamesObj, jsJsObj, text;
-      jsPDFAPI.addJS = function (txt) {
-          text = txt;
-          this.internal.events.subscribe('postPutResources', function (txt) {
-              jsNamesObj = this.internal.newObject();
-              this.internal.out('<<');
-              this.internal.out('/Names [(EmbeddedJS) ' + (jsNamesObj + 1) + ' 0 R]');
-              this.internal.out('>>');
-              this.internal.out('endobj');
-
-              jsJsObj = this.internal.newObject();
-              this.internal.out('<<');
-              this.internal.out('/S /JavaScript');
-              this.internal.out('/JS (' + text + ')');
-              this.internal.out('>>');
-              this.internal.out('endobj');
-          });
-          this.internal.events.subscribe('putCatalog', function () {
-              if (jsNamesObj !== undefined && jsJsObj !== undefined) {
-                  this.internal.out('/Names <</JavaScript ' + jsNamesObj + ' 0 R>>');
-              }
-          });
-          return this;
-      };
-  })(jsPDF.API);
-
-  /**
-   * jsPDF Outline PlugIn
-   * Copyright (c) 2014 Steven Spungin (TwelveTone LLC)  steven@twelvetone.tv
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
-  (function (jsPDFAPI) {
-
-  	jsPDFAPI.events.push(['postPutResources', function () {
-  		var pdf = this;
-  		var rx = /^(\d+) 0 obj$/;
-
-  		// Write action goto objects for each page
-  		// this.outline.destsGoto = [];
-  		// for (var i = 0; i < totalPages; i++) {
-  		// var id = pdf.internal.newObject();
-  		// this.outline.destsGoto.push(id);
-  		// pdf.internal.write("<</D[" + (i * 2 + 3) + " 0 R /XYZ null
-  		// null null]/S/GoTo>> endobj");
-  		// }
-  		//
-  		// for (var i = 0; i < dests.length; i++) {
-  		// pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0
-  		// R");
-  		// }
-  		//				
-  		if (this.outline.root.children.length > 0) {
-  			var lines = pdf.outline.render().split(/\r\n/);
-  			for (var i = 0; i < lines.length; i++) {
-  				var line = lines[i];
-  				var m = rx.exec(line);
-  				if (m != null) {
-  					var oid = m[1];
-  					pdf.internal.newObjectDeferredBegin(oid);
-  				}
-  				pdf.internal.write(line);
-  			}
-  		}
-
-  		// This code will write named destination for each page reference
-  		// (page_1, etc)
-  		if (this.outline.createNamedDestinations) {
-  			var totalPages = this.internal.pages.length;
-  			// WARNING: this assumes jsPDF starts on page 3 and pageIDs
-  			// follow 5, 7, 9, etc
-  			// Write destination objects for each page
-  			var dests = [];
-  			for (var i = 0; i < totalPages; i++) {
-  				var id = pdf.internal.newObject();
-  				dests.push(id);
-  				var info = pdf.internal.getPageInfo(i + 1);
-  				pdf.internal.write("<< /D[" + info.objId + " 0 R /XYZ null null null]>> endobj");
-  			}
-
-  			// assign a name for each destination
-  			var names2Oid = pdf.internal.newObject();
-  			pdf.internal.write('<< /Names [ ');
-  			for (var i = 0; i < dests.length; i++) {
-  				pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0 R");
-  			}
-  			pdf.internal.write(' ] >>', 'endobj');
-
-  			// var kids = pdf.internal.newObject();
-  			// pdf.internal.write('<< /Kids [ ' + names2Oid + ' 0 R');
-  			// pdf.internal.write(' ] >>', 'endobj');
-
-  			var namesOid = pdf.internal.newObject();
-  			pdf.internal.write('<< /Dests ' + names2Oid + " 0 R");
-  			pdf.internal.write('>>', 'endobj');
-  		}
-  	}]);
-
-  	jsPDFAPI.events.push(['putCatalog', function () {
-  		var pdf = this;
-  		if (pdf.outline.root.children.length > 0) {
-  			pdf.internal.write("/Outlines", this.outline.makeRef(this.outline.root));
-  			if (this.outline.createNamedDestinations) {
-  				pdf.internal.write("/Names " + namesOid + " 0 R");
-  			}
-  			// Open with Bookmarks showing
-  			// pdf.internal.write("/PageMode /UseOutlines");
-  		}
-  	}]);
-
-  	jsPDFAPI.events.push(['initialized', function () {
-  		var pdf = this;
-
-  		pdf.outline = {
-  			createNamedDestinations: false,
-  			root: {
-  				children: []
-  			}
-  		};
-
-  		/**
-     * Options: pageNumber
-     */
-  		pdf.outline.add = function (parent, title, options) {
-  			var item = {
-  				title: title,
-  				options: options,
-  				children: []
-  			};
-  			if (parent == null) {
-  				parent = this.root;
-  			}
-  			parent.children.push(item);
-  			return item;
-  		};
-
-  		pdf.outline.render = function () {
-  			this.ctx = {};
-  			this.ctx.val = '';
-  			this.ctx.pdf = pdf;
-
-  			this.genIds_r(this.root);
-  			this.renderRoot(this.root);
-  			this.renderItems(this.root);
-
-  			return this.ctx.val;
-  		};
-
-  		pdf.outline.genIds_r = function (node) {
-  			node.id = pdf.internal.newObjectDeferred();
-  			for (var i = 0; i < node.children.length; i++) {
-  				this.genIds_r(node.children[i]);
-  			}
-  		};
-
-  		pdf.outline.renderRoot = function (node) {
-  			this.objStart(node);
-  			this.line('/Type /Outlines');
-  			if (node.children.length > 0) {
-  				this.line('/First ' + this.makeRef(node.children[0]));
-  				this.line('/Last ' + this.makeRef(node.children[node.children.length - 1]));
-  			}
-  			this.line('/Count ' + this.count_r({
-  				count: 0
-  			}, node));
-  			this.objEnd();
-  		};
-
-  		pdf.outline.renderItems = function (node) {
-  			for (var i = 0; i < node.children.length; i++) {
-  				var item = node.children[i];
-  				this.objStart(item);
-
-  				this.line('/Title ' + this.makeString(item.title));
-
-  				this.line('/Parent ' + this.makeRef(node));
-  				if (i > 0) {
-  					this.line('/Prev ' + this.makeRef(node.children[i - 1]));
-  				}
-  				if (i < node.children.length - 1) {
-  					this.line('/Next ' + this.makeRef(node.children[i + 1]));
-  				}
-  				if (item.children.length > 0) {
-  					this.line('/First ' + this.makeRef(item.children[0]));
-  					this.line('/Last ' + this.makeRef(item.children[item.children.length - 1]));
-  				}
-
-  				var count = this.count = this.count_r({
-  					count: 0
-  				}, item);
-  				if (count > 0) {
-  					this.line('/Count ' + count);
-  				}
-
-  				if (item.options) {
-  					if (item.options.pageNumber) {
-  						// Explicit Destination
-  						//WARNING this assumes page ids are 3,5,7, etc.
-  						var info = pdf.internal.getPageInfo(item.options.pageNumber);
-  						this.line('/Dest ' + '[' + info.objId + ' 0 R /XYZ 0 ' + this.ctx.pdf.internal.pageSize.getHeight() * this.ctx.pdf.internal.scaleFactor + ' 0]');
-  						// this line does not work on all clients (pageNumber instead of page ref)
-  						//this.line('/Dest ' + '[' + (item.options.pageNumber - 1) + ' /XYZ 0 ' + this.ctx.pdf.internal.pageSize.getHeight() + ' 0]');
-
-  						// Named Destination
-  						// this.line('/Dest (page_' + (item.options.pageNumber) + ')');
-
-  						// Action Destination
-  						// var id = pdf.internal.newObject();
-  						// pdf.internal.write('<</D[' + (item.options.pageNumber - 1) + ' /XYZ null null null]/S/GoTo>> endobj');
-  						// this.line('/A ' + id + ' 0 R' );
-  					}
-  				}
-  				this.objEnd();
-  			}
-  			for (var i = 0; i < node.children.length; i++) {
-  				var item = node.children[i];
-  				this.renderItems(item);
-  			}
-  		};
-
-  		pdf.outline.line = function (text) {
-  			this.ctx.val += text + '\r\n';
-  		};
-
-  		pdf.outline.makeRef = function (node) {
-  			return node.id + ' 0 R';
-  		};
-
-  		pdf.outline.makeString = function (val) {
-  			return '(' + pdf.internal.pdfEscape(val) + ')';
-  		};
-
-  		pdf.outline.objStart = function (node) {
-  			this.ctx.val += '\r\n' + node.id + ' 0 obj' + '\r\n<<\r\n';
-  		};
-
-  		pdf.outline.objEnd = function (node) {
-  			this.ctx.val += '>> \r\n' + 'endobj' + '\r\n';
-  		};
-
-  		pdf.outline.count_r = function (ctx, node) {
-  			for (var i = 0; i < node.children.length; i++) {
-  				ctx.count++;
-  				this.count_r(ctx, node.children[i]);
-  			}
-  			return ctx.count;
-  		};
-  	}]);
-
-  	return this;
-  })(jsPDF.API);
-
-  /**@preserve
-   *  ====================================================================
-   * jsPDF PNG PlugIn
-   * Copyright (c) 2014 James Robb, https://github.com/jamesbrobb
-   *
-   * 
-   * ====================================================================
-   */
-
-  (function (jsPDFAPI) {
-
-  	/*
-    * @see http://www.w3.org/TR/PNG-Chunks.html
-    *
-    Color    Allowed      Interpretation
-    Type     Bit Depths
-   	   0       1,2,4,8,16  Each pixel is a grayscale sample.
-   	   2       8,16        Each pixel is an R,G,B triple.
-   	   3       1,2,4,8     Each pixel is a palette index;
-                          a PLTE chunk must appear.
-   	   4       8,16        Each pixel is a grayscale sample,
-                          followed by an alpha sample.
-   	   6       8,16        Each pixel is an R,G,B triple,
-                          followed by an alpha sample.
-   */
-
-  	/*
-    * PNG filter method types
-    *
-    * @see http://www.w3.org/TR/PNG-Filters.html
-    * @see http://www.libpng.org/pub/png/book/chapter09.html
-    *
-    * This is what the value 'Predictor' in decode params relates to
-    *
-    * 15 is "optimal prediction", which means the prediction algorithm can change from line to line.
-    * In that case, you actually have to read the first byte off each line for the prediction algorthim (which should be 0-4, corresponding to PDF 10-14) and select the appropriate unprediction algorithm based on that byte.
-    *
-      0       None
-      1       Sub
-      2       Up
-      3       Average
-      4       Paeth
-    */
-
-  	var doesNotHavePngJS = function doesNotHavePngJS() {
-  		return typeof PNG !== 'function' || typeof FlateStream !== 'function';
-  	},
-  	    canCompress = function canCompress(value) {
-  		return value !== jsPDFAPI.image_compression.NONE && hasCompressionJS();
-  	},
-  	    hasCompressionJS = function hasCompressionJS() {
-  		var inst = typeof Deflater === 'function';
-  		if (!inst) throw new Error("requires deflate.js for compression");
-  		return inst;
-  	},
-  	    compressBytes = function compressBytes(bytes, lineLength, colorsPerPixel, compression) {
-
-  		var level = 5,
-  		    filter_method = filterUp;
-
-  		switch (compression) {
-
-  			case jsPDFAPI.image_compression.FAST:
-
-  				level = 3;
-  				filter_method = filterSub;
-  				break;
-
-  			case jsPDFAPI.image_compression.MEDIUM:
-
-  				level = 6;
-  				filter_method = filterAverage;
-  				break;
-
-  			case jsPDFAPI.image_compression.SLOW:
-
-  				level = 9;
-  				filter_method = filterPaeth; //uses to sum to choose best filter for each line
-  				break;
-  		}
-
-  		bytes = applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method);
-
-  		var header = new Uint8Array(createZlibHeader(level));
-  		var checksum = adler32(bytes);
-
-  		var deflate = new Deflater(level);
-  		var a = deflate.append(bytes);
-  		var cBytes = deflate.flush();
-
-  		var len = header.length + a.length + cBytes.length;
-
-  		var cmpd = new Uint8Array(len + 4);
-  		cmpd.set(header);
-  		cmpd.set(a, header.length);
-  		cmpd.set(cBytes, header.length + a.length);
-
-  		cmpd[len++] = checksum >>> 24 & 0xff;
-  		cmpd[len++] = checksum >>> 16 & 0xff;
-  		cmpd[len++] = checksum >>> 8 & 0xff;
-  		cmpd[len++] = checksum & 0xff;
-
-  		return jsPDFAPI.arrayBufferToBinaryString(cmpd);
-  	},
-  	    createZlibHeader = function createZlibHeader(bytes, level) {
-  		/*
-     * @see http://www.ietf.org/rfc/rfc1950.txt for zlib header
-     */
-  		var cm = 8;
-  		var cinfo = Math.LOG2E * Math.log(0x8000) - 8;
-  		var cmf = cinfo << 4 | cm;
-
-  		var hdr = cmf << 8;
-  		var flevel = Math.min(3, (level - 1 & 0xff) >> 1);
-
-  		hdr |= flevel << 6;
-  		hdr |= 0; //FDICT
-  		hdr += 31 - hdr % 31;
-
-  		return [cmf, hdr & 0xff & 0xff];
-  	},
-  	    adler32 = function adler32(array, param) {
-  		var adler = 1;
-  		var s1 = adler & 0xffff,
-  		    s2 = adler >>> 16 & 0xffff;
-  		var len = array.length;
-  		var tlen;
-  		var i = 0;
-
-  		while (len > 0) {
-  			tlen = len > param ? param : len;
-  			len -= tlen;
-  			do {
-  				s1 += array[i++];
-  				s2 += s1;
-  			} while (--tlen);
-
-  			s1 %= 65521;
-  			s2 %= 65521;
-  		}
-
-  		return (s2 << 16 | s1) >>> 0;
-  	},
-  	    applyPngFilterMethod = function applyPngFilterMethod(bytes, lineLength, colorsPerPixel, filter_method) {
-  		var lines = bytes.length / lineLength,
-  		    result = new Uint8Array(bytes.length + lines),
-  		    filter_methods = getFilterMethods(),
-  		    i = 0,
-  		    line,
-  		    prevLine,
-  		    offset;
-
-  		for (; i < lines; i++) {
-  			offset = i * lineLength;
-  			line = bytes.subarray(offset, offset + lineLength);
-
-  			if (filter_method) {
-  				result.set(filter_method(line, colorsPerPixel, prevLine), offset + i);
-  			} else {
-
-  				var j = 0,
-  				    len = filter_methods.length,
-  				    results = [];
-
-  				for (; j < len; j++) {
-  					results[j] = filter_methods[j](line, colorsPerPixel, prevLine);
-  				}var ind = getIndexOfSmallestSum(results.concat());
-
-  				result.set(results[ind], offset + i);
-  			}
-
-  			prevLine = line;
-  		}
-
-  		return result;
-  	},
-  	    filterNone = function filterNone(line, colorsPerPixel, prevLine) {
-  		/*var result = new Uint8Array(line.length + 1);
-    result[0] = 0;
-    result.set(line, 1);*/
-
-  		var result = Array.apply([], line);
-  		result.unshift(0);
-
-  		return result;
-  	},
-  	    filterSub = function filterSub(line, colorsPerPixel, prevLine) {
-  		var result = [],
-  		    i = 0,
-  		    len = line.length,
-  		    left;
-
-  		result[0] = 1;
-
-  		for (; i < len; i++) {
-  			left = line[i - colorsPerPixel] || 0;
-  			result[i + 1] = line[i] - left + 0x0100 & 0xff;
-  		}
-
-  		return result;
-  	},
-  	    filterUp = function filterUp(line, colorsPerPixel, prevLine) {
-  		var result = [],
-  		    i = 0,
-  		    len = line.length,
-  		    up;
-
-  		result[0] = 2;
-
-  		for (; i < len; i++) {
-  			up = prevLine && prevLine[i] || 0;
-  			result[i + 1] = line[i] - up + 0x0100 & 0xff;
-  		}
-
-  		return result;
-  	},
-  	    filterAverage = function filterAverage(line, colorsPerPixel, prevLine) {
-  		var result = [],
-  		    i = 0,
-  		    len = line.length,
-  		    left,
-  		    up;
-
-  		result[0] = 3;
-
-  		for (; i < len; i++) {
-  			left = line[i - colorsPerPixel] || 0;
-  			up = prevLine && prevLine[i] || 0;
-  			result[i + 1] = line[i] + 0x0100 - (left + up >>> 1) & 0xff;
-  		}
-
-  		return result;
-  	},
-  	    filterPaeth = function filterPaeth(line, colorsPerPixel, prevLine) {
-  		var result = [],
-  		    i = 0,
-  		    len = line.length,
-  		    left,
-  		    up,
-  		    upLeft,
-  		    paeth;
-
-  		result[0] = 4;
-
-  		for (; i < len; i++) {
-  			left = line[i - colorsPerPixel] || 0;
-  			up = prevLine && prevLine[i] || 0;
-  			upLeft = prevLine && prevLine[i - colorsPerPixel] || 0;
-  			paeth = paethPredictor(left, up, upLeft);
-  			result[i + 1] = line[i] - paeth + 0x0100 & 0xff;
-  		}
-
-  		return result;
-  	},
-  	    paethPredictor = function paethPredictor(left, up, upLeft) {
-
-  		var p = left + up - upLeft,
-  		    pLeft = Math.abs(p - left),
-  		    pUp = Math.abs(p - up),
-  		    pUpLeft = Math.abs(p - upLeft);
-
-  		return pLeft <= pUp && pLeft <= pUpLeft ? left : pUp <= pUpLeft ? up : upLeft;
-  	},
-  	    getFilterMethods = function getFilterMethods() {
-  		return [filterNone, filterSub, filterUp, filterAverage, filterPaeth];
-  	},
-  	    getIndexOfSmallestSum = function getIndexOfSmallestSum(arrays) {
-  		var i = 0,
-  		    len = arrays.length,
-  		    sum,
-  		    min,
-  		    ind;
-
-  		while (i < len) {
-  			sum = absSum(arrays[i].slice(1));
-
-  			if (sum < min || !min) {
-  				min = sum;
-  				ind = i;
-  			}
-
-  			i++;
-  		}
-
-  		return ind;
-  	},
-  	    absSum = function absSum(array) {
-  		var i = 0,
-  		    len = array.length,
-  		    sum = 0;
-
-  		while (i < len) {
-  			sum += Math.abs(array[i++]);
-  		}return sum;
-  	},
-  	    getPredictorFromCompression = function getPredictorFromCompression(compression) {
-  		var predictor;
-  		switch (compression) {
-  			case jsPDFAPI.image_compression.FAST:
-  				predictor = 11;
-  				break;
-
-  			case jsPDFAPI.image_compression.MEDIUM:
-  				predictor = 13;
-  				break;
-
-  			case jsPDFAPI.image_compression.SLOW:
-  				predictor = 14;
-  				break;
-
-  			default:
-  				predictor = 12;
-  				break;
-  		}
-  		return predictor;
-  	};
-
-  	jsPDFAPI.processPNG = function (imageData, imageIndex, alias, compression, dataAsBinaryString) {
-
-  		var colorSpace = this.color_spaces.DEVICE_RGB,
-  		    decode = this.decode.FLATE_DECODE,
-  		    bpc = 8,
-  		    img,
-  		    dp,
-  		    trns,
-  		    colors,
-  		    pal,
-  		    smask;
-
-  		/*	if(this.isString(imageData)) {
-    		}*/
-
-  		if (this.isArrayBuffer(imageData)) imageData = new Uint8Array(imageData);
-
-  		if (this.isArrayBufferView(imageData)) {
-
-  			if (doesNotHavePngJS()) throw new Error("PNG support requires png.js and zlib.js");
-
-  			img = new PNG(imageData);
-  			imageData = img.imgData;
-  			bpc = img.bits;
-  			colorSpace = img.colorSpace;
-  			colors = img.colors;
-
-  			//logImg(img);
-
-  			/*
-      * colorType 6 - Each pixel is an R,G,B triple, followed by an alpha sample.
-      *
-      * colorType 4 - Each pixel is a grayscale sample, followed by an alpha sample.
-      *
-      * Extract alpha to create two separate images, using the alpha as a sMask
-      */
-  			if ([4, 6].indexOf(img.colorType) !== -1) {
-
-  				/*
-       * processes 8 bit RGBA and grayscale + alpha images
-       */
-  				if (img.bits === 8) {
-
-  					var pixels = img.pixelBitlength == 32 ? new Uint32Array(img.decodePixels().buffer) : img.pixelBitlength == 16 ? new Uint16Array(img.decodePixels().buffer) : new Uint8Array(img.decodePixels().buffer),
-  					    len = pixels.length,
-  					    imgData = new Uint8Array(len * img.colors),
-  					    alphaData = new Uint8Array(len),
-  					    pDiff = img.pixelBitlength - img.bits,
-  					    i = 0,
-  					    n = 0,
-  					    pixel,
-  					    pbl;
-
-  					for (; i < len; i++) {
-  						pixel = pixels[i];
-  						pbl = 0;
-
-  						while (pbl < pDiff) {
-
-  							imgData[n++] = pixel >>> pbl & 0xff;
-  							pbl = pbl + img.bits;
-  						}
-
-  						alphaData[i] = pixel >>> pbl & 0xff;
-  					}
-  				}
-
-  				/*
-       * processes 16 bit RGBA and grayscale + alpha images
-       */
-  				if (img.bits === 16) {
-
-  					var pixels = new Uint32Array(img.decodePixels().buffer),
-  					    len = pixels.length,
-  					    imgData = new Uint8Array(len * (32 / img.pixelBitlength) * img.colors),
-  					    alphaData = new Uint8Array(len * (32 / img.pixelBitlength)),
-  					    hasColors = img.colors > 1,
-  					    i = 0,
-  					    n = 0,
-  					    a = 0,
-  					    pixel;
-
-  					while (i < len) {
-  						pixel = pixels[i++];
-
-  						imgData[n++] = pixel >>> 0 & 0xFF;
-
-  						if (hasColors) {
-  							imgData[n++] = pixel >>> 16 & 0xFF;
-
-  							pixel = pixels[i++];
-  							imgData[n++] = pixel >>> 0 & 0xFF;
-  						}
-
-  						alphaData[a++] = pixel >>> 16 & 0xFF;
-  					}
-
-  					bpc = 8;
-  				}
-
-  				if (canCompress(compression)) {
-
-  					imageData = compressBytes(imgData, img.width * img.colors, img.colors, compression);
-  					smask = compressBytes(alphaData, img.width, 1, compression);
-  				} else {
-
-  					imageData = imgData;
-  					smask = alphaData;
-  					decode = null;
-  				}
-  			}
-
-  			/*
-      * Indexed png. Each pixel is a palette index.
-      */
-  			if (img.colorType === 3) {
-
-  				colorSpace = this.color_spaces.INDEXED;
-  				pal = img.palette;
-
-  				if (img.transparency.indexed) {
-
-  					var trans = img.transparency.indexed;
-
-  					var total = 0,
-  					    i = 0,
-  					    len = trans.length;
-
-  					for (; i < len; ++i) {
-  						total += trans[i];
-  					}total = total / 255;
-
-  					/*
-        * a single color is specified as 100% transparent (0),
-        * so we set trns to use a /Mask with that index
-        */
-  					if (total === len - 1 && trans.indexOf(0) !== -1) {
-  						trns = [trans.indexOf(0)];
-
-  						/*
-         * there's more than one colour within the palette that specifies
-         * a transparency value less than 255, so we unroll the pixels to create an image sMask
-         */
-  					} else if (total !== len) {
-
-  						var pixels = img.decodePixels(),
-  						    alphaData = new Uint8Array(pixels.length),
-  						    i = 0,
-  						    len = pixels.length;
-
-  						for (; i < len; i++) {
-  							alphaData[i] = trans[pixels[i]];
-  						}smask = compressBytes(alphaData, img.width, 1);
-  					}
-  				}
-  			}
-
-  			var predictor = getPredictorFromCompression(compression);
-
-  			if (decode === this.decode.FLATE_DECODE) dp = '/Predictor ' + predictor + ' /Colors ' + colors + ' /BitsPerComponent ' + bpc + ' /Columns ' + img.width;else
-  				//remove 'Predictor' as it applies to the type of png filter applied to its IDAT - we only apply with compression
-  				dp = '/Colors ' + colors + ' /BitsPerComponent ' + bpc + ' /Columns ' + img.width;
-
-  			if (this.isArrayBuffer(imageData) || this.isArrayBufferView(imageData)) imageData = this.arrayBufferToBinaryString(imageData);
-
-  			if (smask && this.isArrayBuffer(smask) || this.isArrayBufferView(smask)) smask = this.arrayBufferToBinaryString(smask);
-
-  			return this.createImageInfo(imageData, img.width, img.height, colorSpace, bpc, decode, imageIndex, alias, dp, trns, pal, smask, predictor);
-  		}
-
-  		throw new Error("Unsupported PNG image data, try using JPEG instead.");
-  	};
-  })(jsPDF.API);
-
-  /**
-   * jsPDF gif Support PlugIn
-   * Copyright (c) 2017 Aras Abbasi 
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
-
-  (function (jsPDFAPI) {
-
-  	jsPDFAPI.processGIF89A = function (imageData, imageIndex, alias, compression, dataAsBinaryString) {
-  		var reader = new GifReader(imageData);
-  		var width = reader.width,
-  		    height = reader.height;
-  		var qu = 100;
-  		var pixels = [];
-
-  		reader.decodeAndBlitFrameRGBA(0, pixels);
-  		var rawImageData = {
-  			data: pixels,
-  			width: width,
-  			height: height
-  		};
-
-  		var encoder = new JPEGEncoder(qu);
-  		var data = encoder.encode(rawImageData, qu);
-  		return jsPDFAPI.processJPEG.call(this, data, imageIndex, alias, compression);
-  	};
-
-  	jsPDFAPI.processGIF87A = jsPDFAPI.processGIF89A;
-  })(jsPDF.API);
-
-  /**
-   * jsPDF bmp Support PlugIn
-   * Copyright (c) 2018 Aras Abbasi 
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
-
-  (function (jsPDFAPI) {
-
-  	jsPDFAPI.processBMP = function (imageData, imageIndex, alias, compression, dataAsBinaryString) {
-  		var reader = new BmpDecoder(imageData, false);
-  		var width = reader.width,
-  		    height = reader.height;
-  		var qu = 100;
-  		var pixels = reader.getData();
-
-  		var rawImageData = {
-  			data: pixels,
-  			width: width,
-  			height: height
-  		};
-
-  		var encoder = new JPEGEncoder(qu);
-  		var data = encoder.encode(rawImageData, qu);
-  		return jsPDFAPI.processJPEG.call(this, data, imageIndex, alias, compression);
-  	};
-  })(jsPDF.API);
-
-  /**
-   * jsPDF setLanguage Plugin
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
-
-  (function (jsPDFAPI) {
-
-      /**
-      * Add Language Tag to PDF
-      *
-      * @returns {jsPDF}
-      * @name setLanguage
-      * @example
-      * var doc = new jsPDF()
-      * doc.text(10, 10, 'This is a test')
-      * doc.setLanguage("en-US")
-      * doc.save('english.pdf')
-      */
-
-      jsPDFAPI.setLanguage = function (langCode) {
-
-          var langCodes = {
-              "af": "Afrikaans",
-              "sq": "Albanian",
-              "ar": "Arabic (Standard)",
-              "ar-DZ": "Arabic (Algeria)",
-              "ar-BH": "Arabic (Bahrain)",
-              "ar-EG": "Arabic (Egypt)",
-              "ar-IQ": "Arabic (Iraq)",
-              "ar-JO": "Arabic (Jordan)",
-              "ar-KW": "Arabic (Kuwait)",
-              "ar-LB": "Arabic (Lebanon)",
-              "ar-LY": "Arabic (Libya)",
-              "ar-MA": "Arabic (Morocco)",
-              "ar-OM": "Arabic (Oman)",
-              "ar-QA": "Arabic (Qatar)",
-              "ar-SA": "Arabic (Saudi Arabia)",
-              "ar-SY": "Arabic (Syria)",
-              "ar-TN": "Arabic (Tunisia)",
-              "ar-AE": "Arabic (U.A.E.)",
-              "ar-YE": "Arabic (Yemen)",
-              "an": "Aragonese",
-              "hy": "Armenian",
-              "as": "Assamese",
-              "ast": "Asturian",
-              "az": "Azerbaijani",
-              "eu": "Basque",
-              "be": "Belarusian",
-              "bn": "Bengali",
-              "bs": "Bosnian",
-              "br": "Breton",
-              "bg": "Bulgarian",
-              "my": "Burmese",
-              "ca": "Catalan",
-              "ch": "Chamorro",
-              "ce": "Chechen",
-              "zh": "Chinese",
-              "zh-HK": "Chinese (Hong Kong)",
-              "zh-CN": "Chinese (PRC)",
-              "zh-SG": "Chinese (Singapore)",
-              "zh-TW": "Chinese (Taiwan)",
-              "cv": "Chuvash",
-              "co": "Corsican",
-              "cr": "Cree",
-              "hr": "Croatian",
-              "cs": "Czech",
-              "da": "Danish",
-              "nl": "Dutch (Standard)",
-              "nl-BE": "Dutch (Belgian)",
-              "en": "English",
-              "en-AU": "English (Australia)",
-              "en-BZ": "English (Belize)",
-              "en-CA": "English (Canada)",
-              "en-IE": "English (Ireland)",
-              "en-JM": "English (Jamaica)",
-              "en-NZ": "English (New Zealand)",
-              "en-PH": "English (Philippines)",
-              "en-ZA": "English (South Africa)",
-              "en-TT": "English (Trinidad & Tobago)",
-              "en-GB": "English (United Kingdom)",
-              "en-US": "English (United States)",
-              "en-ZW": "English (Zimbabwe)",
-              "eo": "Esperanto",
-              "et": "Estonian",
-              "fo": "Faeroese",
-              "fj": "Fijian",
-              "fi": "Finnish",
-              "fr": "French (Standard)",
-              "fr-BE": "French (Belgium)",
-              "fr-CA": "French (Canada)",
-              "fr-FR": "French (France)",
-              "fr-LU": "French (Luxembourg)",
-              "fr-MC": "French (Monaco)",
-              "fr-CH": "French (Switzerland)",
-              "fy": "Frisian",
-              "fur": "Friulian",
-              "gd": "Gaelic (Scots)",
-              "gd-IE": "Gaelic (Irish)",
-              "gl": "Galacian",
-              "ka": "Georgian",
-              "de": "German (Standard)",
-              "de-AT": "German (Austria)",
-              "de-DE": "German (Germany)",
-              "de-LI": "German (Liechtenstein)",
-              "de-LU": "German (Luxembourg)",
-              "de-CH": "German (Switzerland)",
-              "el": "Greek",
-              "gu": "Gujurati",
-              "ht": "Haitian",
-              "he": "Hebrew",
-              "hi": "Hindi",
-              "hu": "Hungarian",
-              "is": "Icelandic",
-              "id": "Indonesian",
-              "iu": "Inuktitut",
-              "ga": "Irish",
-              "it": "Italian (Standard)",
-              "it-CH": "Italian (Switzerland)",
-              "ja": "Japanese",
-              "kn": "Kannada",
-              "ks": "Kashmiri",
-              "kk": "Kazakh",
-              "km": "Khmer",
-              "ky": "Kirghiz",
-              "tlh": "Klingon",
-              "ko": "Korean",
-              "ko-KP": "Korean (North Korea)",
-              "ko-KR": "Korean (South Korea)",
-              "la": "Latin",
-              "lv": "Latvian",
-              "lt": "Lithuanian",
-              "lb": "Luxembourgish",
-              "mk": "FYRO Macedonian",
-              "ms": "Malay",
-              "ml": "Malayalam",
-              "mt": "Maltese",
-              "mi": "Maori",
-              "mr": "Marathi",
-              "mo": "Moldavian",
-              "nv": "Navajo",
-              "ng": "Ndonga",
-              "ne": "Nepali",
-              "no": "Norwegian",
-              "nb": "Norwegian (Bokmal)",
-              "nn": "Norwegian (Nynorsk)",
-              "oc": "Occitan",
-              "or": "Oriya",
-              "om": "Oromo",
-              "fa": "Persian",
-              "fa-IR": "Persian/Iran",
-              "pl": "Polish",
-              "pt": "Portuguese",
-              "pt-BR": "Portuguese (Brazil)",
-              "pa": "Punjabi",
-              "pa-IN": "Punjabi (India)",
-              "pa-PK": "Punjabi (Pakistan)",
-              "qu": "Quechua",
-              "rm": "Rhaeto-Romanic",
-              "ro": "Romanian",
-              "ro-MO": "Romanian (Moldavia)",
-              "ru": "Russian",
-              "ru-MO": "Russian (Moldavia)",
-              "sz": "Sami (Lappish)",
-              "sg": "Sango",
-              "sa": "Sanskrit",
-              "sc": "Sardinian",
-              "sd": "Sindhi",
-              "si": "Singhalese",
-              "sr": "Serbian",
-              "sk": "Slovak",
-              "sl": "Slovenian",
-              "so": "Somani",
-              "sb": "Sorbian",
-              "es": "Spanish",
-              "es-AR": "Spanish (Argentina)",
-              "es-BO": "Spanish (Bolivia)",
-              "es-CL": "Spanish (Chile)",
-              "es-CO": "Spanish (Colombia)",
-              "es-CR": "Spanish (Costa Rica)",
-              "es-DO": "Spanish (Dominican Republic)",
-              "es-EC": "Spanish (Ecuador)",
-              "es-SV": "Spanish (El Salvador)",
-              "es-GT": "Spanish (Guatemala)",
-              "es-HN": "Spanish (Honduras)",
-              "es-MX": "Spanish (Mexico)",
-              "es-NI": "Spanish (Nicaragua)",
-              "es-PA": "Spanish (Panama)",
-              "es-PY": "Spanish (Paraguay)",
-              "es-PE": "Spanish (Peru)",
-              "es-PR": "Spanish (Puerto Rico)",
-              "es-ES": "Spanish (Spain)",
-              "es-UY": "Spanish (Uruguay)",
-              "es-VE": "Spanish (Venezuela)",
-              "sx": "Sutu",
-              "sw": "Swahili",
-              "sv": "Swedish",
-              "sv-FI": "Swedish (Finland)",
-              "sv-SV": "Swedish (Sweden)",
-              "ta": "Tamil",
-              "tt": "Tatar",
-              "te": "Teluga",
-              "th": "Thai",
-              "tig": "Tigre",
-              "ts": "Tsonga",
-              "tn": "Tswana",
-              "tr": "Turkish",
-              "tk": "Turkmen",
-              "uk": "Ukrainian",
-              "hsb": "Upper Sorbian",
-              "ur": "Urdu",
-              "ve": "Venda",
-              "vi": "Vietnamese",
-              "vo": "Volapuk",
-              "wa": "Walloon",
-              "cy": "Welsh",
-              "xh": "Xhosa",
-              "ji": "Yiddish",
-              "zu": "Zulu"
-          };
-
-          if (this.internal.languageSettings === undefined) {
-              this.internal.languageSettings = {};
-              this.internal.languageSettings.isSubscribed = false;
-          }
-
-          if (langCodes[langCode] !== undefined) {
-              this.internal.languageSettings.languageCode = langCode;
-              if (this.internal.languageSettings.isSubscribed === false) {
-                  this.internal.events.subscribe("putCatalog", function () {
-                      this.internal.write("/Lang (" + this.internal.languageSettings.languageCode + ")");
-                  });
-                  this.internal.languageSettings.isSubscribed = true;
-              }
-          }
-          return this;
-      };
-  })(jsPDF.API);
-
-  /** @preserve
-   * jsPDF split_text_to_size plugin - MIT license.
-   * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
-   *               2014 Diego Casorran, https://github.com/diegocr
-   */
-  /**
-   * 
-   * ====================================================================
-   */
-
-  (function (API) {
-    /**
-     * Returns an array of length matching length of the 'word' string, with each
-     * cell occupied by the width of the char in that position.
-     * 
-     * @function
-     * @param word {String}
-     * @param widths {Object}
-     * @param kerning {Object}
-     * @returns {Array}
-     */
-
-    var getCharWidthsArray = API.getCharWidthsArray = function (text, options) {
-      options = options || {};
-
-      var activeFont = options.font || this.internal.getFont();
-      var fontSize = options.fontSize || this.internal.getFontSize();
-      var charSpace = options.charSpace || this.internal.getCharSpace();
-
-      var widths = options.widths ? options.widths : activeFont.metadata.Unicode.widths;
-      var widthsFractionOf = widths.fof ? widths.fof : 1;
-      var kerning = options.kerning ? options.kerning : activeFont.metadata.Unicode.kerning;
-      var kerningFractionOf = kerning.fof ? kerning.fof : 1;
-
-      var i;
-      var l;
-      var char_code;
-      var prior_char_code = 0; //for kerning
-      var default_char_width = widths[0] || widthsFractionOf;
-      var output = [];
-
-      for (i = 0, l = text.length; i < l; i++) {
-        char_code = text.charCodeAt(i);
-
-        if (typeof activeFont.metadata.widthOfString === "function") {
-          output.push((activeFont.metadata.widthOfGlyph(activeFont.metadata.characterToGlyph(char_code)) + charSpace * (1000 / fontSize) || 0) / 1000);
-        } else {
-          output.push((widths[char_code] || default_char_width) / widthsFractionOf + (kerning[char_code] && kerning[char_code][prior_char_code] || 0) / kerningFractionOf);
-        }
-        prior_char_code = char_code;
-      }
-
-      return output;
-    };
-
-    /**
-     * Calculate the sum of a number-array
-     * 
-     * @name getArraySum
-     * @public
-     * @function
-     * @param {array} array of numbers
-     * @returns {Number}
-     */
-    var getArraySum = API.getArraySum = function (array) {
-      var i = array.length,
-          output = 0;
-      while (i) {
-        i--;
-        output += array[i];
-      }
-      return output;
-    };
-    /**
-    Returns a widths of string in a given font, if the font size is set as 1 point.
-     In other words, this is "proportional" value. For 1 unit of font size, the length
-    of the string will be that much.
-     Multiply by font size to get actual width in *points*
-    Then divide by 72 to get inches or divide by (72/25.6) to get 'mm' etc.
-     @public
-    @function
-    @param
-    @returns {Type}
-    */
-    var getStringUnitWidth = API.getStringUnitWidth = function (text, options) {
-      options = options || {};
-
-      var fontSize = options.fontSize || this.internal.getFontSize();
-      var font = options.font || this.internal.getFont();
-      var charSpace = options.charSpace || this.internal.getCharSpace();
-      var result = 0;
-      if (typeof font.metadata.widthOfString === "function") {
-        result = font.metadata.widthOfString(text, fontSize, charSpace) / fontSize;
-      } else {
-        result = getArraySum(getCharWidthsArray.apply(this, arguments));
-      }
-      return result;
-    };
-
-    /**
-    returns array of lines
-    */
-    var splitLongWord = function splitLongWord(word, widths_array, firstLineMaxLen, maxLen) {
-      var answer = [];
-
-      // 1st, chop off the piece that can fit on the hanging line.
-      var i = 0,
-          l = word.length,
-          workingLen = 0;
-      while (i !== l && workingLen + widths_array[i] < firstLineMaxLen) {
-        workingLen += widths_array[i];
-        i++;
-      }
-      // this is first line.
-      answer.push(word.slice(0, i));
-
-      // 2nd. Split the rest into maxLen pieces.
-      var startOfLine = i;
-      workingLen = 0;
-      while (i !== l) {
-        if (workingLen + widths_array[i] > maxLen) {
-          answer.push(word.slice(startOfLine, i));
-          workingLen = 0;
-          startOfLine = i;
-        }
-        workingLen += widths_array[i];
-        i++;
-      }
-      if (startOfLine !== i) {
-        answer.push(word.slice(startOfLine, i));
-      }
-
-      return answer;
-    };
-
-    // Note, all sizing inputs for this function must be in "font measurement units"
-    // By default, for PDF, it's "point".
-    var splitParagraphIntoLines = function splitParagraphIntoLines(text, maxlen, options) {
-      // at this time works only on Western scripts, ones with space char
-      // separating the words. Feel free to expand.
-
-      if (!options) {
-        options = {};
-      }
-
-      var line = [],
-          lines = [line],
-          line_length = options.textIndent || 0,
-          separator_length = 0,
-          current_word_length = 0,
-          word,
-          widths_array,
-          words = text.split(' '),
-          spaceCharWidth = getCharWidthsArray.apply(this, [' ', options])[0],
-          i,
-          l,
-          tmp,
-          lineIndent;
-
-      if (options.lineIndent === -1) {
-        lineIndent = words[0].length + 2;
-      } else {
-        lineIndent = options.lineIndent || 0;
-      }
-      if (lineIndent) {
-        var pad = Array(lineIndent).join(" "),
-            wrds = [];
-        words.map(function (wrd) {
-          wrd = wrd.split(/\s*\n/);
-          if (wrd.length > 1) {
-            wrds = wrds.concat(wrd.map(function (wrd, idx) {
-              return (idx && wrd.length ? "\n" : "") + wrd;
-            }));
-          } else {
-            wrds.push(wrd[0]);
-          }
-        });
-        words = wrds;
-        lineIndent = getStringUnitWidth.apply(this, [pad, options]);
-      }
-
-      for (i = 0, l = words.length; i < l; i++) {
-        var force = 0;
-
-        word = words[i];
-        if (lineIndent && word[0] == "\n") {
-          word = word.substr(1);
-          force = 1;
-        }
-        widths_array = getCharWidthsArray.apply(this, [word, options]);
-        current_word_length = getArraySum(widths_array);
-
-        if (line_length + separator_length + current_word_length > maxlen || force) {
-          if (current_word_length > maxlen) {
-            // this happens when you have space-less long URLs for example.
-            // we just chop these to size. We do NOT insert hiphens
-            tmp = splitLongWord.apply(this, [word, widths_array, maxlen - (line_length + separator_length), maxlen]);
-            // first line we add to existing line object
-            line.push(tmp.shift()); // it's ok to have extra space indicator there
-            // last line we make into new line object
-            line = [tmp.pop()];
-            // lines in the middle we apped to lines object as whole lines
-            while (tmp.length) {
-              lines.push([tmp.shift()]); // single fragment occupies whole line
-            }
-            current_word_length = getArraySum(widths_array.slice(word.length - (line[0] ? line[0].length : 0)));
-          } else {
-            // just put it on a new line
-            line = [word];
-          }
-
-          // now we attach new line to lines
-          lines.push(line);
-          line_length = current_word_length + lineIndent;
-          separator_length = spaceCharWidth;
-        } else {
-          line.push(word);
-
-          line_length += separator_length + current_word_length;
-          separator_length = spaceCharWidth;
-        }
-      }
-
-      if (lineIndent) {
-        var postProcess = function postProcess(ln, idx) {
-          return (idx ? pad : '') + ln.join(" ");
-        };
-      } else {
-        var postProcess = function postProcess(ln) {
-          return ln.join(" ");
-        };
-      }
-
-      return lines.map(postProcess);
-    };
-
-    /**
-    Splits a given string into an array of strings. Uses 'size' value
-    (in measurement units declared as default for the jsPDF instance)
-    and the font's "widths" and "Kerning" tables, where available, to
-    determine display length of a given string for a given font.
-     We use character's 100% of unit size (height) as width when Width
-    table or other default width is not available.
-     @public
-    @function
-    @param text {String} Unencoded, regular JavaScript (Unicode, UTF-16 / UCS-2) string.
-    @param size {Number} Nominal number, measured in units default to this instance of jsPDF.
-    @param options {Object} Optional flags needed for chopper to do the right thing.
-    @returns {Array} with strings chopped to size.
-    */
-    API.splitTextToSize = function (text, maxlen, options) {
-
-      options = options || {};
-
-      var fsize = options.fontSize || this.internal.getFontSize(),
-          newOptions = function (options) {
-        var widths = {
-          0: 1
-        },
-            kerning = {};
-
-        if (!options.widths || !options.kerning) {
-          var f = this.internal.getFont(options.fontName, options.fontStyle),
-              encoding = 'Unicode';
-          // NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE
-          // Actual JavaScript-native String's 16bit char codes used.
-          // no multi-byte logic here
-
-          if (f.metadata[encoding]) {
-            return {
-              widths: f.metadata[encoding].widths || widths,
-              kerning: f.metadata[encoding].kerning || kerning
-            };
-          } else {
-            return {
-              font: f.metadata,
-              fontSize: this.internal.getFontSize(),
-              charSpace: this.internal.getCharSpace()
-            };
-          }
-        } else {
-          return {
-            widths: options.widths,
-            kerning: options.kerning
-          };
-        }
-
-        // then use default values
-        return {
-          widths: widths,
-          kerning: kerning
-        };
-      }.call(this, options);
-
-      // first we split on end-of-line chars
-      var paragraphs;
-      if (Array.isArray(text)) {
-        paragraphs = text;
-      } else {
-        paragraphs = text.split(/\r?\n/);
-      }
-
-      // now we convert size (max length of line) into "font size units"
-      // at present time, the "font size unit" is always 'point'
-      // 'proportional' means, "in proportion to font size"
-      var fontUnit_maxLen = 1.0 * this.internal.scaleFactor * maxlen / fsize;
-      // at this time, fsize is always in "points" regardless of the default measurement unit of the doc.
-      // this may change in the future?
-      // until then, proportional_maxlen is likely to be in 'points'
-
-      // If first line is to be indented (shorter or longer) than maxLen
-      // we indicate that by using CSS-style "text-indent" option.
-      // here it's in font units too (which is likely 'points')
-      // it can be negative (which makes the first line longer than maxLen)
-      newOptions.textIndent = options.textIndent ? options.textIndent * 1.0 * this.internal.scaleFactor / fsize : 0;
-      newOptions.lineIndent = options.lineIndent;
-
-      var i,
-          l,
-          output = [];
-      for (i = 0, l = paragraphs.length; i < l; i++) {
-        output = output.concat(splitParagraphIntoLines.apply(this, [paragraphs[i], fontUnit_maxLen, newOptions]));
-      }
-
-      return output;
-    };
-  })(jsPDF.API);
-
-  /** @preserve 
-  jsPDF standard_fonts_metrics plugin
-  Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
-  MIT license.
-  */
-  (function (API) {
-
-  	/*
-   # reference (Python) versions of 'compress' and 'uncompress'
-   # only 'uncompress' function is featured lower as JavaScript
-   # if you want to unit test "roundtrip", just transcribe the reference
-   # 'compress' function from Python into JavaScript
-   
-   def compress(data):
-   
-   	keys =   '0123456789abcdef'
-   	values = 'klmnopqrstuvwxyz'
-   	mapping = dict(zip(keys, values))
-   	vals = []
-   	for key in data.keys():
-   		value = data[key]
-   		try:
-   			keystring = hex(key)[2:]
-   			keystring = keystring[:-1] + mapping[keystring[-1:]]
-   		except:
-   			keystring = key.join(["'","'"])
-   			#print('Keystring is %s' % keystring)
-   
-   		try:
-   			if value < 0:
-   				valuestring = hex(value)[3:]
-   				numberprefix = '-'
-   			else:
-   				valuestring = hex(value)[2:]
-   				numberprefix = ''
-   			valuestring = numberprefix + valuestring[:-1] + mapping[valuestring[-1:]]
-   		except:
-   			if type(value) == dict:
-   				valuestring = compress(value)
-   			else:
-   				raise Exception("Don't know what to do with value type %s" % type(value))
-   
-   		vals.append(keystring+valuestring)
-   	
-   	return '{' + ''.join(vals) + '}'
-   
-   def uncompress(data):
-   
-   	decoded = '0123456789abcdef'
-   	encoded = 'klmnopqrstuvwxyz'
-   	mapping = dict(zip(encoded, decoded))
-   
-   	sign = +1
-   	stringmode = False
-   	stringparts = []
-   
-   	output = {}
-   
-   	activeobject = output
-   	parentchain = []
-   
-   	keyparts = ''
-   	valueparts = ''
-   
-   	key = None
-   
-   	ending = set(encoded)
-   
-   	i = 1
-   	l = len(data) - 1 # stripping starting, ending {}
-   	while i != l: # stripping {}
-   		# -, {, }, ' are special.
-   
-   		ch = data[i]
-   		i += 1
-   
-   		if ch == "'":
-   			if stringmode:
-   				# end of string mode
-   				stringmode = False
-   				key = ''.join(stringparts)
-   			else:
-   				# start of string mode
-   				stringmode = True
-   				stringparts = []
-   		elif stringmode == True:
-   			#print("Adding %s to stringpart" % ch)
-   			stringparts.append(ch)
-   
-   		elif ch == '{':
-   			# start of object
-   			parentchain.append( [activeobject, key] )
-   			activeobject = {}
-   			key = None
-   			#DEBUG = True
-   		elif ch == '}':
-   			# end of object
-   			parent, key = parentchain.pop()
-   			parent[key] = activeobject
-   			key = None
-   			activeobject = parent
-   			#DEBUG = False
-   
-   		elif ch == '-':
-   			sign = -1
-   		else:
-   			# must be number
-   			if key == None:
-   				#debug("In Key. It is '%s', ch is '%s'" % (keyparts, ch))
-   				if ch in ending:
-   					#debug("End of key")
-   					keyparts += mapping[ch]
-   					key = int(keyparts, 16) * sign
-   					sign = +1
-   					keyparts = ''
-   				else:
-   					keyparts += ch
-   			else:
-   				#debug("In value. It is '%s', ch is '%s'" % (valueparts, ch))
-   				if ch in ending:
-   					#debug("End of value")
-   					valueparts += mapping[ch]
-   					activeobject[key] = int(valueparts, 16) * sign
-   					sign = +1
-   					key = None
-   					valueparts = ''
-   				else:
-   					valueparts += ch
-   
-   			#debug(activeobject)
-   
-   	return output
-   
-   */
-
-  	/**
-   Uncompresses data compressed into custom, base16-like format. 
-   @public
-   @function
-   @param
-   @returns {Type}
-   */
-
-  	var uncompress = function uncompress(data) {
-
-  		var decoded = '0123456789abcdef',
-  		    encoded = 'klmnopqrstuvwxyz',
-  		    mapping = {};
-
-  		for (var i = 0; i < encoded.length; i++) {
-  			mapping[encoded[i]] = decoded[i];
-  		}
-
-  		var undef,
-  		    output = {},
-  		    sign = 1,
-  		    stringparts // undef. will be [] in string mode
-
-  		,
-  		    activeobject = output,
-  		    parentchain = [],
-  		    parent_key_pair,
-  		    keyparts = '',
-  		    valueparts = '',
-  		    key // undef. will be Truthy when Key is resolved.
-  		,
-  		    datalen = data.length - 1 // stripping ending }
-  		,
-  		    ch;
-
-  		i = 1; // stripping starting {
-
-  		while (i != datalen) {
-  			// - { } ' are special.
-
-  			ch = data[i];
-  			i += 1;
-
-  			if (ch == "'") {
-  				if (stringparts) {
-  					// end of string mode
-  					key = stringparts.join('');
-  					stringparts = undef;
-  				} else {
-  					// start of string mode
-  					stringparts = [];
-  				}
-  			} else if (stringparts) {
-  				stringparts.push(ch);
-  			} else if (ch == '{') {
-  				// start of object
-  				parentchain.push([activeobject, key]);
-  				activeobject = {};
-  				key = undef;
-  			} else if (ch == '}') {
-  				// end of object
-  				parent_key_pair = parentchain.pop();
-  				parent_key_pair[0][parent_key_pair[1]] = activeobject;
-  				key = undef;
-  				activeobject = parent_key_pair[0];
-  			} else if (ch == '-') {
-  				sign = -1;
-  			} else {
-  				// must be number
-  				if (key === undef) {
-  					if (mapping.hasOwnProperty(ch)) {
-  						keyparts += mapping[ch];
-  						key = parseInt(keyparts, 16) * sign;
-  						sign = +1;
-  						keyparts = '';
-  					} else {
-  						keyparts += ch;
-  					}
-  				} else {
-  					if (mapping.hasOwnProperty(ch)) {
-  						valueparts += mapping[ch];
-  						activeobject[key] = parseInt(valueparts, 16) * sign;
-  						sign = +1;
-  						key = undef;
-  						valueparts = '';
-  					} else {
-  						valueparts += ch;
-  					}
-  				}
-  			}
-  		} // end while
-
-  		return output;
-  	};
-
-  	// encoding = 'Unicode' 
-  	// NOT UTF8, NOT UTF16BE/LE, NOT UCS2BE/LE. NO clever BOM behavior
-  	// Actual 16bit char codes used.
-  	// no multi-byte logic here
-
-  	// Unicode characters to WinAnsiEncoding:
-  	// {402: 131, 8211: 150, 8212: 151, 8216: 145, 8217: 146, 8218: 130, 8220: 147, 8221: 148, 8222: 132, 8224: 134, 8225: 135, 8226: 149, 8230: 133, 8364: 128, 8240:137, 8249: 139, 8250: 155, 710: 136, 8482: 153, 338: 140, 339: 156, 732: 152, 352: 138, 353: 154, 376: 159, 381: 142, 382: 158}
-  	// as you can see, all Unicode chars are outside of 0-255 range. No char code conflicts.
-  	// this means that you can give Win cp1252 encoded strings to jsPDF for rendering directly
-  	// as well as give strings with some (supported by these fonts) Unicode characters and 
-  	// these will be mapped to win cp1252 
-  	// for example, you can send char code (cp1252) 0x80 or (unicode) 0x20AC, getting "Euro" glyph displayed in both cases.
-
-  	var encodingBlock = {
-  		'codePages': ['WinAnsiEncoding'],
-  		'WinAnsiEncoding': uncompress("{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}")
-  	},
-  	    encodings = { 'Unicode': {
-  			'Courier': encodingBlock,
-  			'Courier-Bold': encodingBlock,
-  			'Courier-BoldOblique': encodingBlock,
-  			'Courier-Oblique': encodingBlock,
-  			'Helvetica': encodingBlock,
-  			'Helvetica-Bold': encodingBlock,
-  			'Helvetica-BoldOblique': encodingBlock,
-  			'Helvetica-Oblique': encodingBlock,
-  			'Times-Roman': encodingBlock,
-  			'Times-Bold': encodingBlock,
-  			'Times-BoldItalic': encodingBlock,
-  			'Times-Italic': encodingBlock
-  			//	, 'Symbol'
-  			//	, 'ZapfDingbats'
-  		}
-  		/** 
-    Resources:
-    Font metrics data is reprocessed derivative of contents of
-    "Font Metrics for PDF Core 14 Fonts" package, which exhibits the following copyright and license:
-    
-    Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
-    
-    This file and the 14 PostScript(R) AFM files it accompanies may be used,
-    copied, and distributed for any purpose and without charge, with or without
-    modification, provided that all copyright notices are retained; that the AFM
-    files are not distributed without this file; that all modifications to this
-    file or any of the AFM files are prominently noted in the modified file(s);
-    and that this paragraph is not modified. Adobe Systems has no responsibility
-    or obligation to support the use of the AFM files.
-    
-    */
-  	},
-  	    fontMetrics = { 'Unicode': {
-  			// all sizing numbers are n/fontMetricsFractionOf = one font size unit
-  			// this means that if fontMetricsFractionOf = 1000, and letter A's width is 476, it's
-  			// width is 476/1000 or 47.6% of its height (regardless of font size)
-  			// At this time this value applies to "widths" and "kerning" numbers.
-
-  			// char code 0 represents "default" (average) width - use it for chars missing in this table.
-  			// key 'fof' represents the "fontMetricsFractionOf" value
-
-  			'Courier-Oblique': uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
-  			'Times-BoldItalic': uncompress("{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'kerning'{cl{4qu5kt5qt5rs17ss5ts}201s{201ss}201t{cks4lscmscnscoscpscls2wu2yu201ts}201x{2wu2yu}2k{201ts}2w{4qx5kx5ou5qx5rs17su5tu}2x{17su5tu5ou}2y{4qx5kx5ou5qx5rs17ss5ts}'fof'-6ofn{17sw5tw5ou5qw5rs}7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qs}3v{17su5tu5os5qs}7p{17su5tu}ck{4qu5kt5qt5rs17ss5ts}4l{4qu5kt5qt5rs17ss5ts}cm{4qu5kt5qt5rs17ss5ts}cn{4qu5kt5qt5rs17ss5ts}co{4qu5kt5qt5rs17ss5ts}cp{4qu5kt5qt5rs17ss5ts}6l{4qu5ou5qw5rt17su5tu}5q{ckuclucmucnucoucpu4lu}5r{ckuclucmucnucoucpu4lu}7q{cksclscmscnscoscps4ls}6p{4qu5ou5qw5rt17sw5tw}ek{4qu5ou5qw5rt17su5tu}el{4qu5ou5qw5rt17su5tu}em{4qu5ou5qw5rt17su5tu}en{4qu5ou5qw5rt17su5tu}eo{4qu5ou5qw5rt17su5tu}ep{4qu5ou5qw5rt17su5tu}es{17ss5ts5qs4qu}et{4qu5ou5qw5rt17sw5tw}eu{4qu5ou5qw5rt17ss5ts}ev{17ss5ts5qs4qu}6z{17sw5tw5ou5qw5rs}fm{17sw5tw5ou5qw5rs}7n{201ts}fo{17sw5tw5ou5qw5rs}fp{17sw5tw5ou5qw5rs}fq{17sw5tw5ou5qw5rs}7r{cksclscmscnscoscps4ls}fs{17sw5tw5ou5qw5rs}ft{17su5tu}fu{17su5tu}fv{17su5tu}fw{17su5tu}fz{cksclscmscnscoscps4ls}}}"),
-  			'Helvetica-Bold': uncompress("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),
-  			'Courier': uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
-  			'Courier-BoldOblique': uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
-  			'Times-Bold': uncompress("{'widths'{k3q2q5ncx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2l202m2n2n3m2o3m2p6o202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5x4l4s4m4m4n4s4o4s4p4m4q3x4r4y4s4y4t2r4u3m4v4y4w4m4x5y4y4s4z4y5k3x5l4y5m4s5n3r5o4m5p4s5q4s5r6o5s4s5t4s5u4m5v2l5w1w5x2l5y3u5z3m6k2l6l3m6m3r6n2w6o3r6p2w6q2l6r3m6s3r6t1w6u2l6v3r6w1w6x5n6y3r6z3m7k3r7l3r7m2w7n2r7o2l7p3r7q3m7r4s7s3m7t3m7u2w7v2r7w1q7x2r7y3o202l3mcl4sal2lam3man3mao3map3mar3mas2lat4uau1yav3maw3tay4uaz2lbk2sbl3t'fof'6obo2lbp3rbr1tbs2lbu2lbv3mbz3mck4s202k3mcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3rek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3m3u2l17s4s19m3m}'kerning'{cl{4qt5ks5ot5qy5rw17sv5tv}201t{cks4lscmscnscoscpscls4wv}2k{201ts}2w{4qu5ku7mu5os5qx5ru17su5tu}2x{17su5tu5ou5qs}2y{4qv5kv7mu5ot5qz5ru17su5tu}'fof'-6o7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qu}3v{17su5tu5os5qu}fu{17su5tu5ou5qu}7p{17su5tu5ou5qu}ck{4qt5ks5ot5qy5rw17sv5tv}4l{4qt5ks5ot5qy5rw17sv5tv}cm{4qt5ks5ot5qy5rw17sv5tv}cn{4qt5ks5ot5qy5rw17sv5tv}co{4qt5ks5ot5qy5rw17sv5tv}cp{4qt5ks5ot5qy5rw17sv5tv}6l{17st5tt5ou5qu}17s{ckuclucmucnucoucpu4lu4wu}5o{ckuclucmucnucoucpu4lu4wu}5q{ckzclzcmzcnzcozcpz4lz4wu}5r{ckxclxcmxcnxcoxcpx4lx4wu}5t{ckuclucmucnucoucpu4lu4wu}7q{ckuclucmucnucoucpu4lu}6p{17sw5tw5ou5qu}ek{17st5tt5qu}el{17st5tt5ou5qu}em{17st5tt5qu}en{17st5tt5qu}eo{17st5tt5qu}ep{17st5tt5ou5qu}es{17ss5ts5qu}et{17sw5tw5ou5qu}eu{17sw5tw5ou5qu}ev{17ss5ts5qu}6z{17sw5tw5ou5qu5rs}fm{17sw5tw5ou5qu5rs}fn{17sw5tw5ou5qu5rs}fo{17sw5tw5ou5qu5rs}fp{17sw5tw5ou5qu5rs}fq{17sw5tw5ou5qu5rs}7r{cktcltcmtcntcotcpt4lt5os}fs{17sw5tw5ou5qu5rs}ft{17su5tu5ou5qu}7m{5os}fv{17su5tu5ou5qu}fw{17su5tu5ou5qu}fz{cksclscmscnscoscps4ls}}}"),
-  			'Symbol': uncompress("{'widths'{k3uaw4r19m3m2k1t2l2l202m2y2n3m2p5n202q6o3k3m2s2l2t2l2v3r2w1t3m3m2y1t2z1wbk2sbl3r'fof'6o3n3m3o3m3p3m3q3m3r3m3s3m3t3m3u1w3v1w3w3r3x3r3y3r3z2wbp3t3l3m5v2l5x2l5z3m2q4yfr3r7v3k7w1o7x3k}'kerning'{'fof'-6o}}"),
-  			'Helvetica': uncompress("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}"),
-  			'Helvetica-BoldOblique': uncompress("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),
-  			'ZapfDingbats': uncompress("{'widths'{k4u2k1w'fof'6o}'kerning'{'fof'-6o}}"),
-  			'Courier-Bold': uncompress("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),
-  			'Times-Italic': uncompress("{'widths'{k3n2q4ycx2l201n3m201o5t201s2l201t2l201u2l201w3r201x3r201y3r2k1t2l2l202m2n2n3m2o3m2p5n202q5t2r1p2s2l2t2l2u3m2v4n2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w4n3x4n3y4n3z3m4k5w4l3x4m3x4n4m4o4s4p3x4q3x4r4s4s4s4t2l4u2w4v4m4w3r4x5n4y4m4z4s5k3x5l4s5m3x5n3m5o3r5p4s5q3x5r5n5s3x5t3r5u3r5v2r5w1w5x2r5y2u5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q1w6r3m6s3m6t1w6u1w6v2w6w1w6x4s6y3m6z3m7k3m7l3m7m2r7n2r7o1w7p3m7q2w7r4m7s2w7t2w7u2r7v2s7w1v7x2s7y3q202l3mcl3xal2ram3man3mao3map3mar3mas2lat4wau1vav3maw4nay4waz2lbk2sbl4n'fof'6obo2lbp3mbq3obr1tbs2lbu1zbv3mbz3mck3x202k3mcm3xcn3xco3xcp3xcq5tcr4mcs3xct3xcu3xcv3xcw2l2m2ucy2lcz2ldl4mdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr4nfs3mft3mfu3mfv3mfw3mfz2w203k6o212m6m2dw2l2cq2l3t3m3u2l17s3r19m3m}'kerning'{cl{5kt4qw}201s{201sw}201t{201tw2wy2yy6q-t}201x{2wy2yy}2k{201tw}2w{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}2x{17ss5ts5os}2y{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}'fof'-6o6t{17ss5ts5qs}7t{5os}3v{5qs}7p{17su5tu5qs}ck{5kt4qw}4l{5kt4qw}cm{5kt4qw}cn{5kt4qw}co{5kt4qw}cp{5kt4qw}6l{4qs5ks5ou5qw5ru17su5tu}17s{2ks}5q{ckvclvcmvcnvcovcpv4lv}5r{ckuclucmucnucoucpu4lu}5t{2ks}6p{4qs5ks5ou5qw5ru17su5tu}ek{4qs5ks5ou5qw5ru17su5tu}el{4qs5ks5ou5qw5ru17su5tu}em{4qs5ks5ou5qw5ru17su5tu}en{4qs5ks5ou5qw5ru17su5tu}eo{4qs5ks5ou5qw5ru17su5tu}ep{4qs5ks5ou5qw5ru17su5tu}es{5ks5qs4qs}et{4qs5ks5ou5qw5ru17su5tu}eu{4qs5ks5qw5ru17su5tu}ev{5ks5qs4qs}ex{17ss5ts5qs}6z{4qv5ks5ou5qw5ru17su5tu}fm{4qv5ks5ou5qw5ru17su5tu}fn{4qv5ks5ou5qw5ru17su5tu}fo{4qv5ks5ou5qw5ru17su5tu}fp{4qv5ks5ou5qw5ru17su5tu}fq{4qv5ks5ou5qw5ru17su5tu}7r{5os}fs{4qv5ks5ou5qw5ru17su5tu}ft{17su5tu5qs}fu{17su5tu5qs}fv{17su5tu5qs}fw{17su5tu5qs}}}"),
-  			'Times-Roman': uncompress("{'widths'{k3n2q4ycx2l201n3m201o6o201s2l201t2l201u2l201w2w201x2w201y2w2k1t2l2l202m2n2n3m2o3m2p5n202q6o2r1m2s2l2t2l2u3m2v3s2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v1w3w3s3x3s3y3s3z2w4k5w4l4s4m4m4n4m4o4s4p3x4q3r4r4s4s4s4t2l4u2r4v4s4w3x4x5t4y4s4z4s5k3r5l4s5m4m5n3r5o3x5p4s5q4s5r5y5s4s5t4s5u3x5v2l5w1w5x2l5y2z5z3m6k2l6l2w6m3m6n2w6o3m6p2w6q2l6r3m6s3m6t1w6u1w6v3m6w1w6x4y6y3m6z3m7k3m7l3m7m2l7n2r7o1w7p3m7q3m7r4s7s3m7t3m7u2w7v3k7w1o7x3k7y3q202l3mcl4sal2lam3man3mao3map3mar3mas2lat4wau1vav3maw3say4waz2lbk2sbl3s'fof'6obo2lbp3mbq2xbr1tbs2lbu1zbv3mbz2wck4s202k3mcm4scn4sco4scp4scq5tcr4mcs3xct3xcu3xcv3xcw2l2m2tcy2lcz2ldl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek2wel2wem2wen2weo2wep2weq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr3sfs3mft3mfu3mfv3mfw3mfz3m203k6o212m6m2dw2l2cq2l3t3m3u1w17s4s19m3m}'kerning'{cl{4qs5ku17sw5ou5qy5rw201ss5tw201ws}201s{201ss}201t{ckw4lwcmwcnwcowcpwclw4wu201ts}2k{201ts}2w{4qs5kw5os5qx5ru17sx5tx}2x{17sw5tw5ou5qu}2y{4qs5kw5os5qx5ru17sx5tx}'fof'-6o7t{ckuclucmucnucoucpu4lu5os5rs}3u{17su5tu5qs}3v{17su5tu5qs}7p{17sw5tw5qs}ck{4qs5ku17sw5ou5qy5rw201ss5tw201ws}4l{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cm{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cn{4qs5ku17sw5ou5qy5rw201ss5tw201ws}co{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cp{4qs5ku17sw5ou5qy5rw201ss5tw201ws}6l{17su5tu5os5qw5rs}17s{2ktclvcmvcnvcovcpv4lv4wuckv}5o{ckwclwcmwcnwcowcpw4lw4wu}5q{ckyclycmycnycoycpy4ly4wu5ms}5r{cktcltcmtcntcotcpt4lt4ws}5t{2ktclvcmvcnvcovcpv4lv4wuckv}7q{cksclscmscnscoscps4ls}6p{17su5tu5qw5rs}ek{5qs5rs}el{17su5tu5os5qw5rs}em{17su5tu5os5qs5rs}en{17su5qs5rs}eo{5qs5rs}ep{17su5tu5os5qw5rs}es{5qs}et{17su5tu5qw5rs}eu{17su5tu5qs5rs}ev{5qs}6z{17sv5tv5os5qx5rs}fm{5os5qt5rs}fn{17sv5tv5os5qx5rs}fo{17sv5tv5os5qx5rs}fp{5os5qt5rs}fq{5os5qt5rs}7r{ckuclucmucnucoucpu4lu5os}fs{17sv5tv5os5qx5rs}ft{17ss5ts5qs}fu{17sw5tw5qs}fv{17sw5tw5qs}fw{17ss5ts5qs}fz{ckuclucmucnucoucpu4lu5os5rs}}}"),
-  			'Helvetica-Oblique': uncompress("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}")
-  		} };
-
-  	/*
-   This event handler is fired when a new jsPDF object is initialized
-   This event handler appends metrics data to standard fonts within
-   that jsPDF instance. The metrics are mapped over Unicode character
-   codes, NOT CIDs or other codes matching the StandardEncoding table of the
-   standard PDF fonts.
-   Future:
-   Also included is the encoding maping table, converting Unicode (UCS-2, UTF-16)
-   char codes to StandardEncoding character codes. The encoding table is to be used
-   somewhere around "pdfEscape" call.
-   */
-
-  	API.events.push(['addFont', function (font) {
-  		var metrics,
-  		    unicode_section,
-  		    encoding = 'Unicode',
-  		    encodingBlock;
-
-  		metrics = fontMetrics[encoding][font.postScriptName];
-  		if (metrics) {
-  			if (font.metadata[encoding]) {
-  				unicode_section = font.metadata[encoding];
-  			} else {
-  				unicode_section = font.metadata[encoding] = {};
-  			}
-
-  			unicode_section.widths = metrics.widths;
-  			unicode_section.kerning = metrics.kerning;
-  		}
-
-  		encodingBlock = encodings[encoding][font.postScriptName];
-  		if (encodingBlock) {
-  			if (font.metadata[encoding]) {
-  				unicode_section = font.metadata[encoding];
-  			} else {
-  				unicode_section = font.metadata[encoding] = {};
-  			}
-
-  			unicode_section.encoding = encodingBlock;
-  			if (encodingBlock.codePages && encodingBlock.codePages.length) {
-  				font.encoding = encodingBlock.codePages[0];
-  			}
-  		}
-  	}]); // end of adding event handler
-  })(jsPDF.API);
-
-  /**
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
-  (function (jsPDF, global) {
-
-      jsPDF.API.events.push(['addFont', function (font) {
-          if (jsPDF.API.existsFileInVFS(font.postScriptName)) {
-              font.metadata = jsPDF.API.TTFFont.open(font.postScriptName, font.fontName, jsPDF.API.getFileFromVFS(font.postScriptName), font.encoding);
-              font.metadata.Unicode = font.metadata.Unicode || { encoding: {}, kerning: {}, widths: [] };
-          } else if (font.id.slice(1) > 14) {
-              console.error("Font does not exist in FileInVFS, import fonts or remove declaration doc.addFont('" + font.postScriptName + "').");
-          }
-      }]); // end of adding event handler
-  })(jsPDF, typeof self !== "undefined" && self || typeof global !== "undefined" && global || typeof window !== "undefined" && window || Function("return this")());
-
-  /** @preserve
-  jsPDF SVG plugin
-  Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
-  */
-  (function (jsPDFAPI) {
-
-      /**
-      * Parses SVG XML and converts only some of the SVG elements into
-      * PDF elements.
-      *
-      * Supports:
-      * paths
-      * 
-      * @name addSvg
-      * @public
-      * @function
-      * @param {String} SVG-Data as Text
-      * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-      * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-      * @param {Number} width of SVG (in units declared at inception of PDF document)
-      * @param {Number} height of SVG (in units declared at inception of PDF document)
-      * @returns {Object} jsPDF-instance
-      */
-
-      jsPDFAPI.addSvg = function (svgtext, x, y, w, h) {
-          // 'this' is _jsPDF object returned when jsPDF is inited (new jsPDF())
-
-          var undef;
-
-          if (x === undef || y === undef) {
-              throw new Error("addSVG needs values for 'x' and 'y'");
-          }
-
-          function InjectCSS(cssbody, document) {
-              var styletag = document.createElement('style');
-              styletag.type = 'text/css';
-              if (styletag.styleSheet) {
-                  // ie
-                  styletag.styleSheet.cssText = cssbody;
-              } else {
-                  // others
-                  styletag.appendChild(document.createTextNode(cssbody));
-              }
-              document.getElementsByTagName("head")[0].appendChild(styletag);
-          }
-
-          function createWorkerNode(document) {
-
-              var frameID = 'childframe' // Date.now().toString() + '_' + (Math.random() * 100).toString()
-              ,
-                  frame = document.createElement('iframe');
-
-              InjectCSS('.jsPDF_sillysvg_iframe {display:none;position:absolute;}', document);
-
-              frame.name = frameID;
-              frame.setAttribute("width", 0);
-              frame.setAttribute("height", 0);
-              frame.setAttribute("frameborder", "0");
-              frame.setAttribute("scrolling", "no");
-              frame.setAttribute("seamless", "seamless");
-              frame.setAttribute("class", "jsPDF_sillysvg_iframe");
-
-              document.body.appendChild(frame);
-
-              return frame;
-          }
-
-          function attachSVGToWorkerNode(svgtext, frame) {
-              var framedoc = (frame.contentWindow || frame.contentDocument).document;
-              framedoc.write(svgtext);
-              framedoc.close();
-              return framedoc.getElementsByTagName('svg')[0];
-          }
-
-          function convertPathToPDFLinesArgs(path) {
-              // we will use 'lines' method call. it needs:
-              // - starting coordinate pair
-              // - array of arrays of vector shifts (2-len for line, 6 len for bezier)
-              // - scale array [horizontal, vertical] ratios
-              // - style (stroke, fill, both)
-
-              var x = parseFloat(path[1]),
-                  y = parseFloat(path[2]),
-                  vectors = [],
-                  position = 3,
-                  len = path.length;
-
-              while (position < len) {
-                  if (path[position] === 'c') {
-                      vectors.push([parseFloat(path[position + 1]), parseFloat(path[position + 2]), parseFloat(path[position + 3]), parseFloat(path[position + 4]), parseFloat(path[position + 5]), parseFloat(path[position + 6])]);
-                      position += 7;
-                  } else if (path[position] === 'l') {
-                      vectors.push([parseFloat(path[position + 1]), parseFloat(path[position + 2])]);
-                      position += 3;
-                  } else {
-                      position += 1;
-                  }
-              }
-              return [x, y, vectors];
-          }
-
-          var workernode = createWorkerNode(document),
-              svgnode = attachSVGToWorkerNode(svgtext, workernode),
-              scale = [1, 1],
-              svgw = parseFloat(svgnode.getAttribute('width')),
-              svgh = parseFloat(svgnode.getAttribute('height'));
-
-          if (svgw && svgh) {
-              // setting both w and h makes image stretch to size.
-              // this may distort the image, but fits your demanded size
-              if (w && h) {
-                  scale = [w / svgw, h / svgh];
-              }
-              // if only one is set, that value is set as max and SVG
-              // is scaled proportionately.
-              else if (w) {
-                      scale = [w / svgw, w / svgw];
-                  } else if (h) {
-                      scale = [h / svgh, h / svgh];
-                  }
-          }
-
-          var i,
-              l,
-              tmp,
-              linesargs,
-              items = svgnode.childNodes;
-          for (i = 0, l = items.length; i < l; i++) {
-              tmp = items[i];
-              if (tmp.tagName && tmp.tagName.toUpperCase() === 'PATH') {
-                  linesargs = convertPathToPDFLinesArgs(tmp.getAttribute("d").split(' '));
-                  // path start x coordinate
-                  linesargs[0] = linesargs[0] * scale[0] + x; // where x is upper left X of image
-                  // path start y coordinate
-                  linesargs[1] = linesargs[1] * scale[1] + y; // where y is upper left Y of image
-                  // the rest of lines are vectors. these will adjust with scale value auto.
-                  this.lines.call(this, linesargs[2] // lines
-                  , linesargs[0] // starting x
-                  , linesargs[1] // starting y
-                  , scale);
-              }
-          }
-
-          // clean up
-          // workernode.parentNode.removeChild(workernode)
-
-          return this;
-      };
-
-      //fallback
-      jsPDFAPI.addSVG = jsPDFAPI.addSvg;
-
-      /**
-      * Parses SVG XML and saves it as image into the PDF.
-      *
-      * Depends on canvas-element and canvg
-      *
-      * @name addSvgAsImage
-      * @public
-      * @function
-      * @param {String} SVG-Data as Text
-      * @param {Number} x Coordinate (in units declared at inception of PDF document) against left edge of the page
-      * @param {Number} y Coordinate (in units declared at inception of PDF document) against upper edge of the page
-      * @param {Number} width of SVG-Image (in units declared at inception of PDF document)
-      * @param {Number} height of SVG-Image (in units declared at inception of PDF document)
-      * @param {String} alias of SVG-Image (if used multiple times)
-      * @param {String} compression of the generated JPEG, can have the values 'NONE', 'FAST', 'MEDIUM' and 'SLOW'
-      * @param {Number} rotation of the image in degrees (0-359)
-      * 
-      * @returns jsPDF
-      * @methodOf jsPDF#
-      */
-      jsPDFAPI.addSvgAsImage = function (svg, x, y, w, h, alias, compression, rotation) {
-
-          if (isNaN(x) || isNaN(y)) {
-              console.error('jsPDF.addSvgAsImage: Invalid coordinates', arguments);
-              throw new Error('Invalid coordinates passed to jsPDF.addSvgAsImage');
-          }
-
-          if (isNaN(w) || isNaN(h)) {
-              console.error('jsPDF.addSvgAsImage: Invalid measurements', arguments);
-              throw new Error('Invalid measurements (width and/or height) passed to jsPDF.addSvgAsImage');
-          }
-
-          var canvas = document.createElement('canvas');
-          canvas.width = w;
-          canvas.height = h;
-          var ctx = canvas.getContext('2d');
-          ctx.fillStyle = '#fff'; /// set white fill style
-          ctx.fillRect(0, 0, canvas.width, canvas.height);
-
-          //load a svg snippet in the canvas with id = 'drawingArea'
-          canvg(canvas, svg, {
-              ignoreMouse: true,
-              ignoreAnimation: true,
-              ignoreDimensions: true,
-              ignoreClear: true
-          });
-
-          this.addImage(canvas.toDataURL("image/jpeg", 1.0), x, y, w, h, compression, rotation);
-          return this;
-      };
-  })(jsPDF.API);
-
-  /** ==================================================================== 
-   * jsPDF total_pages plugin
-   * Copyright (c) 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
-   * 
-   * 
-   * ====================================================================
-   */
-
-  (function (jsPDFAPI) {
-
-    jsPDFAPI.putTotalPages = function (pageExpression) {
-
-      var replaceExpression = new RegExp(pageExpression, 'g');
-      for (var n = 1; n <= this.internal.getNumberOfPages(); n++) {
-        for (var i = 0; i < this.internal.pages[n].length; i++) {
-          this.internal.pages[n][i] = this.internal.pages[n][i].replace(replaceExpression, this.internal.getNumberOfPages());
-        }
-      }
-      return this;
-    };
-  })(jsPDF.API);
-
-  /**
-   * jsPDF viewerPreferences Plugin
-   * @author Aras Abbasi (github.com/arasabbasi)
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
-
-  /**
-  * Adds the ability to set ViewerPreferences and by thus
-  * controlling the way the document is to be presented on the
-  * screen or in print.
-  */
-
-  (function (jsPDFAPI) {
-      /**
-       * Set the ViewerPreferences of the generated PDF
-       *
-       * @param {Object} options Array with the ViewerPreferences<br />
-       * Example: doc.viewerPreferences({"FitWindow":true});<br />
-       * <br />
-       * You can set following preferences:<br />
-       * <br/>
-       * <b>HideToolbar</b> <i>(boolean)</i><br />
-       * Default value: false<br />
-       * <br />
-       * <b>HideMenubar</b> <i>(boolean)</i><br />
-       * Default value: false.<br />
-       * <br />
-       * <b>HideWindowUI</b> <i>(boolean)</i><br />
-       * Default value: false.<br />
-       * <br />
-       * <b>FitWindow</b> <i>(boolean)</i><br />
-       * Default value: false.<br />
-       * <br />
-       * <b>CenterWindow</b> <i>(boolean)</i><br />
-       * Default value: false<br />
-       * <br />
-       * <b>DisplayDocTitle</b> <i>(boolean)</i><br />
-       * Default value: false.<br />
-       * <br />
-       * <b>NonFullScreenPageMode</b> <i>(String)</i><br />
-       * Possible values: UseNone, UseOutlines, UseThumbs, UseOC<br />
-       * Default value: UseNone<br/>
-       * <br />
-       * <b>Direction</b> <i>(String)</i><br />
-       * Possible values: L2R, R2L<br />
-       * Default value: L2R.<br />
-       * <br />
-       * <b>ViewArea</b> <i>(String)</i><br />
-       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
-       * Default value: CropBox.<br />
-       * <br />
-       * <b>ViewClip</b> <i>(String)</i><br />
-       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
-       * Default value: CropBox<br />
-       * <br />
-       * <b>PrintArea</b> <i>(String)</i><br />
-       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
-       * Default value: CropBox<br />
-       * <br />
-       * <b>PrintClip</b> <i>(String)</i><br />
-       * Possible values: MediaBox, CropBox, TrimBox, BleedBox, ArtBox<br />
-       * Default value: CropBox.<br />
-       * <br />
-       * <b>PrintScaling</b> <i>(String)</i><br />
-       * Possible values: AppDefault, None<br />
-       * Default value: AppDefault.<br />
-       * <br />
-       * <b>Duplex</b> <i>(String)</i><br />
-       * Possible values: Simplex, DuplexFlipLongEdge, DuplexFlipShortEdge
-       * Default value: none<br />
-       * <br />
-       * <b>PickTrayByPDFSize</b> <i>(boolean)</i><br />
-       * Default value: false<br />
-       * <br />
-       * <b>PrintPageRange</b> <i>(Array)</i><br />
-       * Example: [[1,5], [7,9]]<br />
-       * Default value: as defined by PDF viewer application<br />
-       * <br />
-       * <b>NumCopies</b> <i>(Number)</i><br />
-       * Possible values: 1, 2, 3, 4, 5<br />
-       * Default value: 1<br />
-       * <br />
-       * For more information see the PDF Reference, sixth edition on Page 577
-       * @param {boolean} doReset True to reset the settings
-       * @function
-       * @returns jsPDF
-       * @methodOf jsPDF#
-       * @example
-       * var doc = new jsPDF()
-       * doc.text('This is a test', 10, 10)
-       * doc.viewerPreferences({'FitWindow': true}, true)
-       * doc.save("viewerPreferences.pdf")
-       *
-       * // Example printing 10 copies, using cropbox, and hiding UI.
-       * doc.viewerPreferences({
-       *   'HideWindowUI': true,
-       *   'PrintArea': 'CropBox',
-       *   'NumCopies': 10
-       * })
-       * @name viewerPreferences
-       */
-
-      jsPDFAPI.viewerPreferences = function (options, doReset) {
-          options = options || {};
-          doReset = doReset || false;
-
-          var configuration;
-          var configurationTemplate = {
-              "HideToolbar": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
-              "HideMenubar": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
-              "HideWindowUI": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
-              "FitWindow": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
-              "CenterWindow": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.3 },
-              "DisplayDocTitle": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.4 },
-              "NonFullScreenPageMode": { defaultValue: "UseNone", value: "UseNone", type: "name", explicitSet: false, valueSet: ["UseNone", "UseOutlines", "UseThumbs", "UseOC"], pdfVersion: 1.3 },
-              "Direction": { defaultValue: "L2R", value: "L2R", type: "name", explicitSet: false, valueSet: ["L2R", "R2L"], pdfVersion: 1.3 },
-              "ViewArea": { defaultValue: "CropBox", value: "CropBox", type: "name", explicitSet: false, valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], pdfVersion: 1.4 },
-              "ViewClip": { defaultValue: "CropBox", value: "CropBox", type: "name", explicitSet: false, valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], pdfVersion: 1.4 },
-              "PrintArea": { defaultValue: "CropBox", value: "CropBox", type: "name", explicitSet: false, valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], pdfVersion: 1.4 },
-              "PrintClip": { defaultValue: "CropBox", value: "CropBox", type: "name", explicitSet: false, valueSet: ["MediaBox", "CropBox", "TrimBox", "BleedBox", "ArtBox"], pdfVersion: 1.4 },
-              "PrintScaling": { defaultValue: "AppDefault", value: "AppDefault", type: "name", explicitSet: false, valueSet: ["AppDefault", "None"], pdfVersion: 1.6 },
-              "Duplex": { defaultValue: "", value: "none", type: "name", explicitSet: false, valueSet: ["Simplex", "DuplexFlipShortEdge", "DuplexFlipLongEdge", "none"], pdfVersion: 1.7 },
-              "PickTrayByPDFSize": { defaultValue: false, value: false, type: "boolean", explicitSet: false, valueSet: [true, false], pdfVersion: 1.7 },
-              "PrintPageRange": { defaultValue: "", value: "", type: "array", explicitSet: false, valueSet: null, pdfVersion: 1.7 },
-              "NumCopies": { defaultValue: 1, value: 1, type: "integer", explicitSet: false, valueSet: null, pdfVersion: 1.7 }
-          };
-
-          var configurationKeys = Object.keys(configurationTemplate);
-
-          var rangeArray = [];
-          var i = 0;
-          var j = 0;
-          var k = 0;
-          var isValid = true;
-
-          var method;
-          var value;
-
-          function arrayContainsElement(array, element) {
-              var iterator;
-              var result = false;
-
-              for (iterator = 0; iterator < array.length; iterator += 1) {
-                  if (array[iterator] === element) {
-                      result = true;
-                  }
-              }
-              return result;
-          }
-
-          if (this.internal.viewerpreferences === undefined) {
-              this.internal.viewerpreferences = {};
-              this.internal.viewerpreferences.configuration = JSON.parse(JSON.stringify(configurationTemplate));
-              this.internal.viewerpreferences.isSubscribed = false;
-          }
-          configuration = this.internal.viewerpreferences.configuration;
-
-          if (options === "reset" || doReset === true) {
-              var len = configurationKeys.length;
-
-              for (k = 0; k < len; k += 1) {
-                  configuration[configurationKeys[k]].value = configuration[configurationKeys[k]].defaultValue;
-                  configuration[configurationKeys[k]].explicitSet = false;
-              }
-          }
-
-          if ((typeof options === "undefined" ? "undefined" : _typeof(options)) === "object") {
-              for (method in options) {
-                  value = options[method];
-                  if (arrayContainsElement(configurationKeys, method) && value !== undefined) {
-
-                      if (configuration[method].type === "boolean" && typeof value === "boolean") {
-                          configuration[method].value = value;
-                      } else if (configuration[method].type === "name" && arrayContainsElement(configuration[method].valueSet, value)) {
-                          configuration[method].value = value;
-                      } else if (configuration[method].type === "integer" && Number.isInteger(value)) {
-                          configuration[method].value = value;
-                      } else if (configuration[method].type === "array") {
-
-                          for (i = 0; i < value.length; i += 1) {
-                              isValid = true;
-                              if (value[i].length === 1 && typeof value[i][0] === "number") {
-                                  rangeArray.push(String(value[i]));
-                              } else if (value[i].length > 1) {
-                                  for (j = 0; j < value[i].length; j += 1) {
-                                      if (typeof value[i][j] !== "number") {
-                                          isValid = false;
-                                      }
-                                  }
-                                  if (isValid === true) {
-                                      rangeArray.push(String(value[i].join("-")));
-                                  }
-                              }
-                          }
-                          configuration[method].value = String(rangeArray);
-                      } else {
-                          configuration[method].value = configuration[method].defaultValue;
-                      }
-
-                      configuration[method].explicitSet = true;
-                  }
-              }
-          }
-
-          if (this.internal.viewerpreferences.isSubscribed === false) {
-              this.internal.events.subscribe("putCatalog", function () {
-                  var pdfDict = [];
-                  var vPref;
-                  for (vPref in configuration) {
-                      if (configuration[vPref].explicitSet === true) {
-                          if (configuration[vPref].type === "name") {
-                              pdfDict.push("/" + vPref + " /" + configuration[vPref].value);
-                          } else {
-                              pdfDict.push("/" + vPref + " " + configuration[vPref].value);
-                          }
-                      }
-                  }
-                  if (pdfDict.length !== 0) {
-                      this.internal.write("/ViewerPreferences\n<<\n" + pdfDict.join("\n") + "\n>>");
-                  }
-              });
-              this.internal.viewerpreferences.isSubscribed = true;
-          }
-
-          this.internal.viewerpreferences.configuration = configuration;
-          return this;
-      };
-  })(jsPDF.API);
-
-  /** ==================================================================== 
-   * jsPDF XMP metadata plugin
-   * Copyright (c) 2016 Jussi Utunen, u-jussi@suomi24.fi
-   * 
-   * 
-   * ====================================================================
-   */
-
-  /*global jsPDF */
-
-  /**
-  * Adds XMP formatted metadata to PDF
-  *
-  * @param {String} metadata The actual metadata to be added. The metadata shall be stored as XMP simple value. Note that if the metadata string contains XML markup characters "<", ">" or "&", those characters should be written using XML entities.
-  * @param {String} namespaceuri Sets the namespace URI for the metadata. Last character should be slash or hash.
-  * @function
-  * @returns {jsPDF}
-  * @methodOf jsPDF#
-  * @name addMetadata
-  */
-
-  (function (jsPDFAPI) {
-
-      var xmpmetadata = "";
-      var xmpnamespaceuri = "";
-      var metadata_object_number = "";
-
-      jsPDFAPI.addMetadata = function (metadata, namespaceuri) {
-          xmpnamespaceuri = namespaceuri || "http://jspdf.default.namespaceuri/"; //The namespace URI for an XMP name shall not be empty
-          xmpmetadata = metadata;
-          this.internal.events.subscribe('postPutResources', function () {
-              if (!xmpmetadata) {
-                  metadata_object_number = "";
-              } else {
-                  var xmpmeta_beginning = '<x:xmpmeta xmlns:x="adobe:ns:meta/">';
-                  var rdf_beginning = '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:jspdf="' + xmpnamespaceuri + '"><jspdf:metadata>';
-                  var rdf_ending = '</jspdf:metadata></rdf:Description></rdf:RDF>';
-                  var xmpmeta_ending = '</x:xmpmeta>';
-                  var utf8_xmpmeta_beginning = unescape(encodeURIComponent(xmpmeta_beginning));
-                  var utf8_rdf_beginning = unescape(encodeURIComponent(rdf_beginning));
-                  var utf8_metadata = unescape(encodeURIComponent(xmpmetadata));
-                  var utf8_rdf_ending = unescape(encodeURIComponent(rdf_ending));
-                  var utf8_xmpmeta_ending = unescape(encodeURIComponent(xmpmeta_ending));
-
-                  var total_len = utf8_rdf_beginning.length + utf8_metadata.length + utf8_rdf_ending.length + utf8_xmpmeta_beginning.length + utf8_xmpmeta_ending.length;
-
-                  metadata_object_number = this.internal.newObject();
-                  this.internal.write('<< /Type /Metadata /Subtype /XML /Length ' + total_len + ' >>');
-                  this.internal.write('stream');
-                  this.internal.write(utf8_xmpmeta_beginning + utf8_rdf_beginning + utf8_metadata + utf8_rdf_ending + utf8_xmpmeta_ending);
-                  this.internal.write('endstream');
-                  this.internal.write('endobj');
-              }
-          });
-          this.internal.events.subscribe('putCatalog', function () {
-              if (metadata_object_number) {
-                  this.internal.write('/Metadata ' + metadata_object_number + ' 0 R');
-              }
-          });
-          return this;
-      };
-  })(jsPDF.API);
-
-  (function (jsPDF, global) {
-
-      var jsPDFAPI = jsPDF.API;
-
-      var glyID = [0];
-      /**************************************************/
-      /* function : toHex                               */
-      /* comment : Replace str with a hex string.       */
-      /**************************************************/
-      function toHex(str) {
-          var hex = '';
-          for (var i = 0; i < str.length; i++) {
-              hex += '' + str.charCodeAt(i).toString(16);
-          }
-          return hex;
-      }
-
-      /***************************************************************************************************/
-      /* function : pdfEscape16                                                                          */
-      /* comment : The character id of a 2-byte string is converted to a hexadecimal number by obtaining */
-      /*   the corresponding glyph id and width, and then adding padding to the string.                  */
-      /***************************************************************************************************/
-      var pdfEscape16 = function pdfEscape16(text, font) {
-          var widths = font.metadata.Unicode.widths;        var padz = ["", "0", "00", "000", "0000"];
-          var ar = [""];
-          for (var i = 0, l = text.length, t; i < l; ++i) {
-              t = font.metadata.characterToGlyph(text.charCodeAt(i));
-              glyID.push(t);
-              if (widths.indexOf(t) == -1) {
-                  widths.push(t);
-                  widths.push([parseInt(font.metadata.widthOfGlyph(t), 10)]);
-              }
-              if (t == '0') {
-                  //Spaces are not allowed in cmap.
-                  return ar.join("");
-              } else {
-                  t = t.toString(16);
-                  ar.push(padz[4 - t.length], t);
-              }
-          }
-          return ar.join("");
-      };
-
-      var identityHFunction = function identityHFunction(font, out, newObject) {
-
-          if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === 'Identity-H') {
-              //Tag with Identity-H
-              var widths = font.metadata.Unicode.widths;
-              var data = font.metadata.subset.encode(glyID);
-              var pdfOutput = data;
-              var pdfOutput2 = "";
-              for (var i = 0; i < pdfOutput.length; i++) {
-                  pdfOutput2 += String.fromCharCode(pdfOutput[i]);
-              }
-              var fontTable = newObject();
-              out('<<');
-              out('/Length ' + pdfOutput2.length);
-              out('/Length1 ' + pdfOutput2.length);
-              out('>>');
-
-              out('stream');
-              out(pdfOutput2);
-              out('endstream');
-              out('endobj');
-
-              var fontDescriptor = newObject();
-              out('<<');
-              out('/Type /FontDescriptor');
-              out('/FontName /' + font.fontName);
-              out('/FontFile2 ' + fontTable + ' 0 R');
-              out('/FontBBox ' + jsPDF.API.PDFObject.convert(font.metadata.bbox));
-              out('/Flags ' + font.metadata.flags);
-              out('/StemV ' + font.metadata.stemV);
-              out('/ItalicAngle ' + font.metadata.italicAngle);
-              out('/Ascent ' + font.metadata.ascender);
-              out('/Descent ' + font.metadata.decender);
-              out('/CapHeight ' + font.metadata.capHeight);
-              out('>>');
-              out('endobj');
-
-              var DescendantFont = newObject();
-              out('<<');
-              out('/Type /Font');
-              out('/BaseFont /' + font.fontName);
-              out('/FontDescriptor ' + fontDescriptor + ' 0 R');
-              out('/W ' + jsPDF.API.PDFObject.convert(widths));
-              out('/CIDToGIDMap /Identity');
-              out('/DW 1000');
-              out('/Subtype /CIDFontType2');
-              out('/CIDSystemInfo');
-              out('<<');
-              out('/Supplement 0');
-              out('/Registry (Adobe)');
-              out('/Ordering (' + font.encoding + ')');
-              out('>>');
-              out('>>');
-              out('endobj');
-
-              font.objectNumber = newObject();
-              out('<<');
-              out('/Type /Font');
-              out('/Subtype /Type0');
-              out('/BaseFont /' + font.fontName);
-              out('/Encoding /' + font.encoding);
-              out('/DescendantFonts [' + DescendantFont + ' 0 R]');
-              out('>>');
-              out('endobj');
-
-              font.isAlreadyPutted = true;
-          }
-      };
-
-      jsPDFAPI.events.push(['putFont', function (args) {
-          identityHFunction(args.font, args.out, args.newObject);
-      }]);
-
-      var winAnsiEncodingFunction = function winAnsiEncodingFunction(font, out, newObject) {
-
-          if (font.metadata instanceof jsPDF.API.TTFFont && font.encoding === 'WinAnsiEncoding') {
-              //Tag with WinAnsi encoding
-              var widths = font.metadata.Unicode.widths;
-              var data = font.metadata.rawData;
-              var pdfOutput = data;
-              var pdfOutput2 = "";
-              for (var i = 0; i < pdfOutput.length; i++) {
-                  pdfOutput2 += String.fromCharCode(pdfOutput[i]);
-              }
-              var fontTable = newObject();
-              out('<<');
-              out('/Length ' + pdfOutput2.length);
-              out('/Length1 ' + pdfOutput2.length);
-              out('>>');
-              out('stream');
-              out(pdfOutput2);
-              out('endstream');
-              out('endobj');
-              var fontDescriptor = newObject();
-              out('<<');
-              out('/Descent ' + font.metadata.decender);
-              out('/CapHeight ' + font.metadata.capHeight);
-              out('/StemV ' + font.metadata.stemV);
-              out('/Type /FontDescriptor');
-              out('/FontFile2 ' + fontTable + ' 0 R');
-              out('/Flags 96');
-              out('/FontBBox ' + jsPDF.API.PDFObject.convert(font.metadata.bbox));
-              out('/FontName /' + font.fontName);
-              out('/ItalicAngle ' + font.metadata.italicAngle);
-              out('/Ascent ' + font.metadata.ascender);
-              out('>>');
-              out('endobj');
-              font.objectNumber = newObject();
-              for (var i = 0; i < font.metadata.hmtx.widths.length; i++) {
-                  font.metadata.hmtx.widths[i] = parseInt(font.metadata.hmtx.widths[i] * (1000 / font.metadata.head.unitsPerEm)); //Change the width of Em units to Point units.
-              }
-              out('<</Subtype/TrueType/Type/Font/BaseFont/' + font.fontName + '/FontDescriptor ' + fontDescriptor + ' 0 R' + '/Encoding/' + font.encoding + ' /FirstChar 29 /LastChar 255 /Widths ' + jsPDF.API.PDFObject.convert(font.metadata.hmtx.widths) + '>>');
-              out('endobj');
-              font.isAlreadyPutted = true;
-          }
-      };
-
-      jsPDFAPI.events.push(['putFont', function (args) {
-          winAnsiEncodingFunction(args.font, args.out, args.newObject);
-      }]);
-
-      var utf8TextFunction = function utf8TextFunction(args) {
-          var text = args.text || '';
-          var x = args.x;
-          var y = args.y;
-          var options = args.options || {};
-          var mutex = args.mutex || {};
-
-          var pdfEscape = mutex.pdfEscape;
-          var activeFontKey = mutex.activeFontKey;
-          var fonts = mutex.fonts;
-          var key,
-              fontSize = mutex.activeFontSize;
-
-          var str = '',
-              s = 0,
-              cmapConfirm;
-          var strText = '';
-          var attr;
-          var key = activeFontKey;
-          var encoding = fonts[key].encoding;
-
-          if (fonts[key].encoding !== 'Identity-H') {
-              return {
-                  text: text,
-                  x: x,
-                  y: y,
-                  options: options,
-                  mutex: mutex
-              };
-          }
-          strText = text;
-
-          key = attr ? getFont(attr.font, attr.fontStyle) : activeFontKey;
-          if (Object.prototype.toString.call(text) === '[object Array]') {
-              strText = text[0];
-          }
-          for (s = 0; s < strText.length; s += 1) {
-              if (fonts[key].metadata.hasOwnProperty('cmap')) {
-                  cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)];
-                  /*
-                  if (Object.prototype.toString.call(text) === '[object Array]') {
-                             var i = 0;
-                            // for (i = 0; i < text.length; i += 1) {
-                                 if (Object.prototype.toString.call(text[s]) === '[object Array]') {
-                  	cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s][0].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id
-                                 } else {
-                                     
-                                 }
-                             //}
-                  
-                         } else {
-                  cmapConfirm = fonts[key].metadata.cmap.unicode.codeMap[strText[s].charCodeAt(0)]; //Make sure the cmap has the corresponding glyph id
-                         }*/
-              }
-              if (!cmapConfirm) {
-                  if (strText[s].charCodeAt(0) < 256 && fonts[key].metadata.hasOwnProperty('Unicode')) {
-                      str += strText[s];
-                  } else {
-                      str += '';
-                  }
-              } else {
-                  str += strText[s];
-              }
-          }
-          var result = '';
-          if (parseInt(key.slice(1)) < 14 || encoding === 'WinAnsiEncoding') {
-              //For the default 13 font
-              result = toHex(pdfEscape(str, key));
-          } else if (encoding === 'Identity-H') {
-              result = pdfEscape16(str, fonts[key]);
-          }
-          mutex.isHex = true;
-
-          return {
-              text: result,
-              x: x,
-              y: y,
-              options: options,
-              mutex: mutex
-          };
-      };
-
-      var utf8EscapeFunction = function utf8EscapeFunction(parms) {
-          var text = parms.text || '',
-              x = parms.x,
-              y = parms.y,
-              options = parms.options,
-              mutex = parms.mutex;
-          var lang = options.lang;
-          var tmpText = [];
-          var args = {
-              text: text,
-              x: x,
-              y: y,
-              options: options,
-              mutex: mutex
-          };
-
-          if (Object.prototype.toString.call(text) === '[object Array]') {
-              var i = 0;
-              for (i = 0; i < text.length; i += 1) {
-                  if (Object.prototype.toString.call(text[i]) === '[object Array]') {
-                      if (text[i].length === 3) {
-                          tmpText.push([utf8TextFunction(Object.assign({}, args, { text: text[i][0] })).text, text[i][1], text[i][2]]);
-                      } else {
-                          tmpText.push(utf8TextFunction(Object.assign({}, args, { text: text[i] })).text);
-                      }
-                  } else {
-                      tmpText.push(utf8TextFunction(Object.assign({}, args, { text: text[i] })).text);
-                  }
-              }
-              parms.text = tmpText;
-          } else {
-              parms.text = utf8TextFunction(Object.assign({}, args, { text: text })).text;
-          }
-      };
-
-      jsPDFAPI.events.push(['postProcessText', utf8EscapeFunction]);
-  })(jsPDF, typeof self !== "undefined" && self || typeof global !== "undefined" && global || typeof window !== "undefined" && window || Function("return this")());
-
-  /**
-   * jsPDF virtual FileSystem functionality
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
-
-  /**
-  * Use the vFS to handle files
-  */
-
-  (function (jsPDFAPI) {
-
-      var vFS = {};
-
-      /* Check if the file exists in the vFS
-      * @returns {boolean}
-      * @name existsFileInVFS
-      * @example
-      * doc.existsFileInVFS("someFile.txt");
-      */
-      jsPDFAPI.existsFileInVFS = function (filename) {
-          return vFS.hasOwnProperty(filename);
-      };
-
-      /* Add a file to the vFS
-      * @returns {jsPDF}
-      * @name addFileToVFS
-      * @example
-      * doc.addFileToVFS("someFile.txt", "BADFACE1");
-      */
-      jsPDFAPI.addFileToVFS = function (filename, filecontent) {
-          vFS[filename] = filecontent;
-          return this;
-      };
-
-      /* Get the file from the vFS
-      * @returns {string}
-      * @name addFileToVFS
-      * @example
-      * doc.getFileFromVFS("someFile.txt");
-      */
-      jsPDFAPI.getFileFromVFS = function (filename) {
-          if (vFS.hasOwnProperty(filename)) {
-              return vFS[filename];
-          }
-          return null;
-      };
-  })(jsPDF.API);
-
-  /* Blob.js
-   * A Blob implementation.
-   * 2014-07-24
-   *
-   * By Eli Grey, http://eligrey.com
-   * By Devin Samarin, https://github.com/dsamarin
-   * License: X11/MIT
-   *   See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md
-   */
-
-  /*global self, unescape */
-  /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
-    plusplus: true */
-
-  /*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
-
-  (function (view) {
-
-  	view.URL = view.URL || view.webkitURL;
-
-  	if (view.Blob && view.URL) {
-  		try {
-  			new Blob;
-  			return;
-  		} catch (e) {}
-  	}
-
-  	// Internally we use a BlobBuilder implementation to base Blob off of
-  	// in order to support older browsers that only have BlobBuilder
-  	var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {
-  		var
-  			  get_class = function(object) {
-  				return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
-  			}
-  			, FakeBlobBuilder = function BlobBuilder() {
-  				this.data = [];
-  			}
-  			, FakeBlob = function Blob(data, type, encoding) {
-  				this.data = data;
-  				this.size = data.length;
-  				this.type = type;
-  				this.encoding = encoding;
-  			}
-  			, FBB_proto = FakeBlobBuilder.prototype
-  			, FB_proto = FakeBlob.prototype
-  			, FileReaderSync = view.FileReaderSync
-  			, FileException = function(type) {
-  				this.code = this[this.name = type];
-  			}
-  			, file_ex_codes = (
-  				  "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
-  				+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
-  			).split(" ")
-  			, file_ex_code = file_ex_codes.length
-  			, real_URL = view.URL || view.webkitURL || view
-  			, real_create_object_URL = real_URL.createObjectURL
-  			, real_revoke_object_URL = real_URL.revokeObjectURL
-  			, URL = real_URL
-  			, btoa = view.btoa
-  			, atob = view.atob
-
-  			, ArrayBuffer = view.ArrayBuffer
-  			, Uint8Array = view.Uint8Array
-
-  			, origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/
-  		;
-  		FakeBlob.fake = FB_proto.fake = true;
-  		while (file_ex_code--) {
-  			FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
-  		}
-  		// Polyfill URL
-  		if (!real_URL.createObjectURL) {
-  			URL = view.URL = function(uri) {
-  				var
-  					  uri_info = document.createElementNS("http://www.w3.org/1999/xhtml", "a")
-  					, uri_origin
-  				;
-  				uri_info.href = uri;
-  				if (!("origin" in uri_info)) {
-  					if (uri_info.protocol.toLowerCase() === "data:") {
-  						uri_info.origin = null;
-  					} else {
-  						uri_origin = uri.match(origin);
-  						uri_info.origin = uri_origin && uri_origin[1];
-  					}
-  				}
-  				return uri_info;
-  			};
-  		}
-  		URL.createObjectURL = function(blob) {
-  			var
-  				  type = blob.type
-  				, data_URI_header
-  			;
-  			if (type === null) {
-  				type = "application/octet-stream";
-  			}
-  			if (blob instanceof FakeBlob) {
-  				data_URI_header = "data:" + type;
-  				if (blob.encoding === "base64") {
-  					return data_URI_header + ";base64," + blob.data;
-  				} else if (blob.encoding === "URI") {
-  					return data_URI_header + "," + decodeURIComponent(blob.data);
-  				} if (btoa) {
-  					return data_URI_header + ";base64," + btoa(blob.data);
-  				} else {
-  					return data_URI_header + "," + encodeURIComponent(blob.data);
-  				}
-  			} else if (real_create_object_URL) {
-  				return real_create_object_URL.call(real_URL, blob);
-  			}
-  		};
-  		URL.revokeObjectURL = function(object_URL) {
-  			if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
-  				real_revoke_object_URL.call(real_URL, object_URL);
-  			}
-  		};
-  		FBB_proto.append = function(data/*, endings*/) {
-  			var bb = this.data;
-  			// decode data to a binary string
-  			if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
-  				var
-  					  str = ""
-  					, buf = new Uint8Array(data)
-  					, i = 0
-  					, buf_len = buf.length
-  				;
-  				for (; i < buf_len; i++) {
-  					str += String.fromCharCode(buf[i]);
-  				}
-  				bb.push(str);
-  			} else if (get_class(data) === "Blob" || get_class(data) === "File") {
-  				if (FileReaderSync) {
-  					var fr = new FileReaderSync;
-  					bb.push(fr.readAsBinaryString(data));
-  				} else {
-  					// async FileReader won't work as BlobBuilder is sync
-  					throw new FileException("NOT_READABLE_ERR");
-  				}
-  			} else if (data instanceof FakeBlob) {
-  				if (data.encoding === "base64" && atob) {
-  					bb.push(atob(data.data));
-  				} else if (data.encoding === "URI") {
-  					bb.push(decodeURIComponent(data.data));
-  				} else if (data.encoding === "raw") {
-  					bb.push(data.data);
-  				}
-  			} else {
-  				if (typeof data !== "string") {
-  					data += ""; // convert unsupported types to strings
-  				}
-  				// decode UTF-16 to binary string
-  				bb.push(unescape(encodeURIComponent(data)));
-  			}
-  		};
-  		FBB_proto.getBlob = function(type) {
-  			if (!arguments.length) {
-  				type = null;
-  			}
-  			return new FakeBlob(this.data.join(""), type, "raw");
-  		};
-  		FBB_proto.toString = function() {
-  			return "[object BlobBuilder]";
-  		};
-  		FB_proto.slice = function(start, end, type) {
-  			var args = arguments.length;
-  			if (args < 3) {
-  				type = null;
-  			}
-  			return new FakeBlob(
-  				  this.data.slice(start, args > 1 ? end : this.data.length)
-  				, type
-  				, this.encoding
-  			);
-  		};
-  		FB_proto.toString = function() {
-  			return "[object Blob]";
-  		};
-  		FB_proto.close = function() {
-  			this.size = 0;
-  			delete this.data;
-  		};
-  		return FakeBlobBuilder;
-  	}(view));
-
-  	view.Blob = function(blobParts, options) {
-  		var type = options ? (options.type || "") : "";
-  		var builder = new BlobBuilder();
-  		if (blobParts) {
-  			for (var i = 0, len = blobParts.length; i < len; i++) {
-  				if (Uint8Array && blobParts[i] instanceof Uint8Array) {
-  					builder.append(blobParts[i].buffer);
-  				}
-  				else {
-  					builder.append(blobParts[i]);
-  				}
-  			}
-  		}
-  		var blob = builder.getBlob(type);
-  		if (!blob.slice && blob.webkitSlice) {
-  			blob.slice = blob.webkitSlice;
-  		}
-  		return blob;
-  	};
-
-  	var getPrototypeOf = Object.getPrototypeOf || function(object) {
-  		return object.__proto__;
-  	};
-  	view.Blob.prototype = getPrototypeOf(new view.Blob());
-  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || window.content || window));
-
-  /* FileSaver.js
-   * A saveAs() FileSaver implementation.
-   * 1.3.2
-   * 2016-06-16 18:25:19
-   *
-   * By Eli Grey, http://eligrey.com
-   * License: MIT
-   *   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
-   */
-
-  /*global self */
-  /*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
-
-  /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
-
-  var saveAs = saveAs || (function(view) {
-  	// IE <10 is explicitly unsupported
-  	if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
-  		return;
-  	}
-  	var
-  		  doc = view.document
-  		  // only get URL when necessary in case Blob.js hasn't overridden it yet
-  		, get_URL = function() {
-  			return view.URL || view.webkitURL || view;
-  		}
-  		, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
-  		, can_use_save_link = "download" in save_link
-  		, click = function(node) {
-  			var event = new MouseEvent("click");
-  			node.dispatchEvent(event);
-  		}
-  		, is_safari = /constructor/i.test(view.HTMLElement) || view.safari
-  		, is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent)
-  		, throw_outside = function(ex) {
-  			(view.setImmediate || view.setTimeout)(function() {
-  				throw ex;
-  			}, 0);
-  		}
-  		, force_saveable_type = "application/octet-stream"
-  		// the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
-  		, arbitrary_revoke_timeout = 1000 * 40 // in ms
-  		, revoke = function(file) {
-  			var revoker = function() {
-  				if (typeof file === "string") { // file is an object URL
-  					get_URL().revokeObjectURL(file);
-  				} else { // file is a File
-  					file.remove();
-  				}
-  			};
-  			setTimeout(revoker, arbitrary_revoke_timeout);
-  		}
-  		, dispatch = function(filesaver, event_types, event) {
-  			event_types = [].concat(event_types);
-  			var i = event_types.length;
-  			while (i--) {
-  				var listener = filesaver["on" + event_types[i]];
-  				if (typeof listener === "function") {
-  					try {
-  						listener.call(filesaver, event || filesaver);
-  					} catch (ex) {
-  						throw_outside(ex);
-  					}
-  				}
-  			}
-  		}
-  		, auto_bom = function(blob) {
-  			// prepend BOM for UTF-8 XML and text/* types (including HTML)
-  			// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
-  			if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
-  				return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});
-  			}
-  			return blob;
-  		}
-  		, FileSaver = function(blob, name, no_auto_bom) {
-  			if (!no_auto_bom) {
-  				blob = auto_bom(blob);
-  			}
-  			// First try a.download, then web filesystem, then object URLs
-  			var
-  				  filesaver = this
-  				, type = blob.type
-  				, force = type === force_saveable_type
-  				, object_url
-  				, dispatch_all = function() {
-  					dispatch(filesaver, "writestart progress write writeend".split(" "));
-  				}
-  				// on any filesys errors revert to saving with object URLs
-  				, fs_error = function() {
-  					if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {
-  						// Safari doesn't allow downloading of blob urls
-  						var reader = new FileReader();
-  						reader.onloadend = function() {
-  							var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');
-  							var popup = view.open(url, '_blank');
-  							if(!popup) view.location.href = url;
-  							url=undefined; // release reference before dispatching
-  							filesaver.readyState = filesaver.DONE;
-  							dispatch_all();
-  						};
-  						reader.readAsDataURL(blob);
-  						filesaver.readyState = filesaver.INIT;
-  						return;
-  					}
-  					// don't create more object URLs than needed
-  					if (!object_url) {
-  						object_url = get_URL().createObjectURL(blob);
-  					}
-  					if (force) {
-  						view.location.href = object_url;
-  					} else {
-  						var opened = view.open(object_url, "_blank");
-  						if (!opened) {
-  							// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
-  							view.location.href = object_url;
-  						}
-  					}
-  					filesaver.readyState = filesaver.DONE;
-  					dispatch_all();
-  					revoke(object_url);
-  				}
-  			;
-  			filesaver.readyState = filesaver.INIT;
-
-  			if (can_use_save_link) {
-  				object_url = get_URL().createObjectURL(blob);
-  				setTimeout(function() {
-  					save_link.href = object_url;
-  					save_link.download = name;
-  					click(save_link);
-  					dispatch_all();
-  					revoke(object_url);
-  					filesaver.readyState = filesaver.DONE;
-  				});
-  				return;
-  			}
-
-  			fs_error();
-  		}
-  		, FS_proto = FileSaver.prototype
-  		, saveAs = function(blob, name, no_auto_bom) {
-  			return new FileSaver(blob, name || blob.name || "download", no_auto_bom);
-  		}
-  	;
-  	// IE 10+ (native saveAs)
-  	if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
-  		return function(blob, name, no_auto_bom) {
-  			name = name || blob.name || "download";
-
-  			if (!no_auto_bom) {
-  				blob = auto_bom(blob);
-  			}
-  			return navigator.msSaveOrOpenBlob(blob, name);
-  		};
-  	}
-
-  	FS_proto.abort = function(){};
-  	FS_proto.readyState = FS_proto.INIT = 0;
-  	FS_proto.WRITING = 1;
-  	FS_proto.DONE = 2;
-
-  	FS_proto.error =
-  	FS_proto.onwritestart =
-  	FS_proto.onprogress =
-  	FS_proto.onwrite =
-  	FS_proto.onabort =
-  	FS_proto.onerror =
-  	FS_proto.onwriteend =
-  		null;
-
-  	return saveAs;
-  }(
-  	   typeof self !== "undefined" && self
-  	|| typeof window !== "undefined" && window
-  	|| window.content
-  ));
-  // `self` is undefined in Firefox for Android content script context
-  // while `this` is nsIContentFrameMessageManager
-  // with an attribute `content` that corresponds to the window
-
-  if (typeof module !== "undefined" && module.exports) {
-    module.exports.saveAs = saveAs;
-  } else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) {
-    define("FileSaver.js", function() {
-      return saveAs;
-    });
-  }
-
-  /*
-   * Copyright (c) 2012 chick307 <chick307@gmail.com>
-   *
-   * Licensed under the MIT License.
-   * http://opensource.org/licenses/mit-license
-   */
-
-  (function(jsPDF, callback) {
-    jsPDF.API.adler32cs = callback();
-  })(jsPDF, function() {
-    var _hasArrayBuffer = typeof ArrayBuffer === 'function' &&
-      typeof Uint8Array === 'function';
-
-    var _Buffer = null, _isBuffer = (function() {
-      if (!_hasArrayBuffer)
-        return function _isBuffer() { return false };
-
-      try {
-        var buffer = {};
-        if (typeof buffer.Buffer === 'function')
-          _Buffer = buffer.Buffer;
-      } catch (error) {}
-
-      return function _isBuffer(value) {
-        return value instanceof ArrayBuffer ||
-          _Buffer !== null && value instanceof _Buffer;
-      };
-    }());
-
-    var _utf8ToBinary = (function() {
-      if (_Buffer !== null) {
-        return function _utf8ToBinary(utf8String) {
-          return new _Buffer(utf8String, 'utf8').toString('binary');
-        };
-      } else {
-        return function _utf8ToBinary(utf8String) {
-          return unescape(encodeURIComponent(utf8String));
-        };
-      }
-    }());
-
-    var MOD = 65521;
-
-    var _update = function _update(checksum, binaryString) {
-      var a = checksum & 0xFFFF, b = checksum >>> 16;
-      for (var i = 0, length = binaryString.length; i < length; i++) {
-        a = (a + (binaryString.charCodeAt(i) & 0xFF)) % MOD;
-        b = (b + a) % MOD;
-      }
-      return (b << 16 | a) >>> 0;
-    };
-
-    var _updateUint8Array = function _updateUint8Array(checksum, uint8Array) {
-      var a = checksum & 0xFFFF, b = checksum >>> 16;
-      for (var i = 0, length = uint8Array.length; i < length; i++) {
-        a = (a + uint8Array[i]) % MOD;
-        b = (b + a) % MOD;
-      }
-      return (b << 16 | a) >>> 0
-    };
-
-    var exports = {};
-
-    var Adler32 = exports.Adler32 = (function() {
-      var ctor = function Adler32(checksum) {
-        if (!(this instanceof ctor)) {
-          throw new TypeError(
-            'Constructor cannot called be as a function.');
-        }
-        if (!isFinite(checksum = checksum == null ? 1 : +checksum)) {
-          throw new Error(
-            'First arguments needs to be a finite number.');
-        }
-        this.checksum = checksum >>> 0;
-      };
-
-      var proto = ctor.prototype = {};
-      proto.constructor = ctor;
-
-      ctor.from = function(from) {
-        from.prototype = proto;
-        return from;
-      }(function from(binaryString) {
-        if (!(this instanceof ctor)) {
-          throw new TypeError(
-            'Constructor cannot called be as a function.');
-        }
-        if (binaryString == null)
-          throw new Error('First argument needs to be a string.');
-        this.checksum = _update(1, binaryString.toString());
-      });
-
-      ctor.fromUtf8 = function(fromUtf8) {
-        fromUtf8.prototype = proto;
-        return fromUtf8;
-      }(function fromUtf8(utf8String) {
-        if (!(this instanceof ctor)) {
-          throw new TypeError(
-            'Constructor cannot called be as a function.');
-        }
-        if (utf8String == null)
-          throw new Error('First argument needs to be a string.');
-        var binaryString = _utf8ToBinary(utf8String.toString());
-        this.checksum = _update(1, binaryString);
-      });
-
-      if (_hasArrayBuffer) {
-        ctor.fromBuffer = function(fromBuffer) {
-          fromBuffer.prototype = proto;
-          return fromBuffer;
-        }(function fromBuffer(buffer) {
-          if (!(this instanceof ctor)) {
-            throw new TypeError(
-              'Constructor cannot called be as a function.');
-          }
-          if (!_isBuffer(buffer))
-            throw new Error('First argument needs to be ArrayBuffer.');
-          var array = new Uint8Array(buffer);
-          return this.checksum = _updateUint8Array(1, array);
-        });
-      }
-
-      proto.update = function update(binaryString) {
-        if (binaryString == null)
-          throw new Error('First argument needs to be a string.');
-        binaryString = binaryString.toString();
-        return this.checksum = _update(this.checksum, binaryString);
-      };
-
-      proto.updateUtf8 = function updateUtf8(utf8String) {
-        if (utf8String == null)
-          throw new Error('First argument needs to be a string.');
-        var binaryString = _utf8ToBinary(utf8String.toString());
-        return this.checksum = _update(this.checksum, binaryString);
-      };
-
-      if (_hasArrayBuffer) {
-        proto.updateBuffer = function updateBuffer(buffer) {
-          if (!_isBuffer(buffer))
-            throw new Error('First argument needs to be ArrayBuffer.');
-          var array = new Uint8Array(buffer);
-          return this.checksum = _updateUint8Array(this.checksum, array);
-        };
-      }
-
-      proto.clone = function clone() {
-        return new Adler32(this.checksum);
-      };
-
-      return ctor;
-    }());
-
-    exports.from = function from(binaryString) {
-      if (binaryString == null)
-        throw new Error('First argument needs to be a string.');
-      return _update(1, binaryString.toString());
-    };
-
-    exports.fromUtf8 = function fromUtf8(utf8String) {
-      if (utf8String == null)
-        throw new Error('First argument needs to be a string.');
-      var binaryString = _utf8ToBinary(utf8String.toString());
-      return _update(1, binaryString);
-    };
-
-    if (_hasArrayBuffer) {
-      exports.fromBuffer = function fromBuffer(buffer) {
-        if (!_isBuffer(buffer))
-          throw new Error('First argument need to be ArrayBuffer.');
-        var array = new Uint8Array(buffer);
-        return _updateUint8Array(1, array);
-      };
-    }
-
-    return exports;
-  });
-
-  // (c) Dean McNamee <dean@gmail.com>, 2013.
-  //
-  // https://github.com/deanm/omggif
-  //
-  // 
-  //
-  // omggif is a JavaScript implementation of a GIF 89a encoder and decoder,
-  // including animation and compression.  It does not rely on any specific
-  // underlying system, so should run in the browser, Node, or Plask.
-
-  function GifWriter(buf, width, height, gopts) {
-    var p = 0;
-
-    var gopts = gopts === undefined ? { } : gopts;
-    var loop_count = gopts.loop === undefined ? null : gopts.loop;
-    var global_palette = gopts.palette === undefined ? null : gopts.palette;
-
-    if (width <= 0 || height <= 0 || width > 65535 || height > 65535)
-      throw "Width/Height invalid."
-
-    function check_palette_and_num_colors(palette) {
-      var num_colors = palette.length;
-      if (num_colors < 2 || num_colors > 256 ||  num_colors & (num_colors-1))
-        throw "Invalid code/color length, must be power of 2 and 2 .. 256.";
-      return num_colors;
-    }
-
-    // - Header.
-    buf[p++] = 0x47; buf[p++] = 0x49; buf[p++] = 0x46;  // GIF
-    buf[p++] = 0x38; buf[p++] = 0x39; buf[p++] = 0x61;  // 89a
-
-    // Handling of Global Color Table (palette) and background index.
-    var gp_num_colors_pow2 = 0;
-    var background = 0;
-    if (global_palette !== null) {
-      var gp_num_colors = check_palette_and_num_colors(global_palette);
-      while (gp_num_colors >>= 1) ++gp_num_colors_pow2;
-      gp_num_colors = 1 << gp_num_colors_pow2;
-      --gp_num_colors_pow2;
-      if (gopts.background !== undefined) {
-        background = gopts.background;
-        if (background >= gp_num_colors) throw "Background index out of range.";
-        // The GIF spec states that a background index of 0 should be ignored, so
-        // this is probably a mistake and you really want to set it to another
-        // slot in the palette.  But actually in the end most browsers, etc end
-        // up ignoring this almost completely (including for dispose background).
-        if (background === 0)
-          throw "Background index explicitly passed as 0.";
-      }
-    }
-
-    // - Logical Screen Descriptor.
-    // NOTE(deanm): w/h apparently ignored by implementations, but set anyway.
-    buf[p++] = width & 0xff; buf[p++] = width >> 8 & 0xff;
-    buf[p++] = height & 0xff; buf[p++] = height >> 8 & 0xff;
-    // NOTE: Indicates 0-bpp original color resolution (unused?).
-    buf[p++] = (global_palette !== null ? 0x80 : 0) |  // Global Color Table Flag.
-               gp_num_colors_pow2;  // NOTE: No sort flag (unused?).
-    buf[p++] = background;  // Background Color Index.
-    buf[p++] = 0;  // Pixel aspect ratio (unused?).
-
-    // - Global Color Table
-    if (global_palette !== null) {
-      for (var i = 0, il = global_palette.length; i < il; ++i) {
-        var rgb = global_palette[i];
-        buf[p++] = rgb >> 16 & 0xff;
-        buf[p++] = rgb >> 8 & 0xff;
-        buf[p++] = rgb & 0xff;
-      }
-    }
-
-    if (loop_count !== null) {  // Netscape block for looping.
-      if (loop_count < 0 || loop_count > 65535)
-        throw "Loop count invalid."
-      // Extension code, label, and length.
-      buf[p++] = 0x21; buf[p++] = 0xff; buf[p++] = 0x0b;
-      // NETSCAPE2.0
-      buf[p++] = 0x4e; buf[p++] = 0x45; buf[p++] = 0x54; buf[p++] = 0x53;
-      buf[p++] = 0x43; buf[p++] = 0x41; buf[p++] = 0x50; buf[p++] = 0x45;
-      buf[p++] = 0x32; buf[p++] = 0x2e; buf[p++] = 0x30;
-      // Sub-block
-      buf[p++] = 0x03; buf[p++] = 0x01;
-      buf[p++] = loop_count & 0xff; buf[p++] = loop_count >> 8 & 0xff;
-      buf[p++] = 0x00;  // Terminator.
-    }
-
-
-    var ended = false;
-
-    this.addFrame = function(x, y, w, h, indexed_pixels, opts) {
-      if (ended === true) { --p; ended = false; }  // Un-end.
-
-      opts = opts === undefined ? { } : opts;
-
-      // TODO(deanm): Bounds check x, y.  Do they need to be within the virtual
-      // canvas width/height, I imagine?
-      if (x < 0 || y < 0 || x > 65535 || y > 65535)
-        throw "x/y invalid."
-
-      if (w <= 0 || h <= 0 || w > 65535 || h > 65535)
-        throw "Width/Height invalid."
-
-      if (indexed_pixels.length < w * h)
-        throw "Not enough pixels for the frame size.";
-
-      var using_local_palette = true;
-      var palette = opts.palette;
-      if (palette === undefined || palette === null) {
-        using_local_palette = false;
-        palette = global_palette;
-      }
-
-      if (palette === undefined || palette === null)
-        throw "Must supply either a local or global palette.";
-
-      var num_colors = check_palette_and_num_colors(palette);
-
-      // Compute the min_code_size (power of 2), destroying num_colors.
-      var min_code_size = 0;
-      while (num_colors >>= 1) ++min_code_size;
-      num_colors = 1 << min_code_size;  // Now we can easily get it back.
-
-      var delay = opts.delay === undefined ? 0 : opts.delay;
-
-      // From the spec:
-      //     0 -   No disposal specified. The decoder is
-      //           not required to take any action.
-      //     1 -   Do not dispose. The graphic is to be left
-      //           in place.
-      //     2 -   Restore to background color. The area used by the
-      //           graphic must be restored to the background color.
-      //     3 -   Restore to previous. The decoder is required to
-      //           restore the area overwritten by the graphic with
-      //           what was there prior to rendering the graphic.
-      //  4-7 -    To be defined.
-      // NOTE(deanm): Dispose background doesn't really work, apparently most
-      // browsers ignore the background palette index and clear to transparency.
-      var disposal = opts.disposal === undefined ? 0 : opts.disposal;
-      if (disposal < 0 || disposal > 3)  // 4-7 is reserved.
-        throw "Disposal out of range.";
-
-      var use_transparency = false;
-      var transparent_index = 0;
-      if (opts.transparent !== undefined && opts.transparent !== null) {
-        use_transparency = true;
-        transparent_index = opts.transparent;
-        if (transparent_index < 0 || transparent_index >= num_colors)
-          throw "Transparent color index.";
-      }
-
-      if (disposal !== 0 || use_transparency || delay !== 0) {
-        // - Graphics Control Extension
-        buf[p++] = 0x21; buf[p++] = 0xf9;  // Extension / Label.
-        buf[p++] = 4;  // Byte size.
-
-        buf[p++] = disposal << 2 | (use_transparency === true ? 1 : 0);
-        buf[p++] = delay & 0xff; buf[p++] = delay >> 8 & 0xff;
-        buf[p++] = transparent_index;  // Transparent color index.
-        buf[p++] = 0;  // Block Terminator.
-      }
-
-      // - Image Descriptor
-      buf[p++] = 0x2c;  // Image Seperator.
-      buf[p++] = x & 0xff; buf[p++] = x >> 8 & 0xff;  // Left.
-      buf[p++] = y & 0xff; buf[p++] = y >> 8 & 0xff;  // Top.
-      buf[p++] = w & 0xff; buf[p++] = w >> 8 & 0xff;
-      buf[p++] = h & 0xff; buf[p++] = h >> 8 & 0xff;
-      // NOTE: No sort flag (unused?).
-      // TODO(deanm): Support interlace.
-      buf[p++] = using_local_palette === true ? (0x80 | (min_code_size-1)) : 0;
-
-      // - Local Color Table
-      if (using_local_palette === true) {
-        for (var i = 0, il = palette.length; i < il; ++i) {
-          var rgb = palette[i];
-          buf[p++] = rgb >> 16 & 0xff;
-          buf[p++] = rgb >> 8 & 0xff;
-          buf[p++] = rgb & 0xff;
-        }
-      }
-
-      p = GifWriterOutputLZWCodeStream(
-              buf, p, min_code_size < 2 ? 2 : min_code_size, indexed_pixels);
-    };
-
-    this.end = function() {
-      if (ended === false) {
-        buf[p++] = 0x3b;  // Trailer.
-        ended = true;
-      }
-      return p;
-    };
-  }
-
-  // Main compression routine, palette indexes -> LZW code stream.
-  // |index_stream| must have at least one entry.
-  function GifWriterOutputLZWCodeStream(buf, p, min_code_size, index_stream) {
-    buf[p++] = min_code_size;
-    var cur_subblock = p++;  // Pointing at the length field.
-
-    var clear_code = 1 << min_code_size;
-    var code_mask = clear_code - 1;
-    var eoi_code = clear_code + 1;
-    var next_code = eoi_code + 1;
-
-    var cur_code_size = min_code_size + 1;  // Number of bits per code.
-    var cur_shift = 0;
-    // We have at most 12-bit codes, so we should have to hold a max of 19
-    // bits here (and then we would write out).
-    var cur = 0;
-
-    function emit_bytes_to_buffer(bit_block_size) {
-      while (cur_shift >= bit_block_size) {
-        buf[p++] = cur & 0xff;
-        cur >>= 8; cur_shift -= 8;
-        if (p === cur_subblock + 256) {  // Finished a subblock.
-          buf[cur_subblock] = 255;
-          cur_subblock = p++;
-        }
-      }
-    }
-
-    function emit_code(c) {
-      cur |= c << cur_shift;
-      cur_shift += cur_code_size;
-      emit_bytes_to_buffer(8);
-    }
-
-    // I am not an expert on the topic, and I don't want to write a thesis.
-    // However, it is good to outline here the basic algorithm and the few data
-    // structures and optimizations here that make this implementation fast.
-    // The basic idea behind LZW is to build a table of previously seen runs
-    // addressed by a short id (herein called output code).  All data is
-    // referenced by a code, which represents one or more values from the
-    // original input stream.  All input bytes can be referenced as the same
-    // value as an output code.  So if you didn't want any compression, you
-    // could more or less just output the original bytes as codes (there are
-    // some details to this, but it is the idea).  In order to achieve
-    // compression, values greater then the input range (codes can be up to
-    // 12-bit while input only 8-bit) represent a sequence of previously seen
-    // inputs.  The decompressor is able to build the same mapping while
-    // decoding, so there is always a shared common knowledge between the
-    // encoding and decoder, which is also important for "timing" aspects like
-    // how to handle variable bit width code encoding.
-    //
-    // One obvious but very important consequence of the table system is there
-    // is always a unique id (at most 12-bits) to map the runs.  'A' might be
-    // 4, then 'AA' might be 10, 'AAA' 11, 'AAAA' 12, etc.  This relationship
-    // can be used for an effecient lookup strategy for the code mapping.  We
-    // need to know if a run has been seen before, and be able to map that run
-    // to the output code.  Since we start with known unique ids (input bytes),
-    // and then from those build more unique ids (table entries), we can
-    // continue this chain (almost like a linked list) to always have small
-    // integer values that represent the current byte chains in the encoder.
-    // This means instead of tracking the input bytes (AAAABCD) to know our
-    // current state, we can track the table entry for AAAABC (it is guaranteed
-    // to exist by the nature of the algorithm) and the next character D.
-    // Therefor the tuple of (table_entry, byte) is guaranteed to also be
-    // unique.  This allows us to create a simple lookup key for mapping input
-    // sequences to codes (table indices) without having to store or search
-    // any of the code sequences.  So if 'AAAA' has a table entry of 12, the
-    // tuple of ('AAAA', K) for any input byte K will be unique, and can be our
-    // key.  This leads to a integer value at most 20-bits, which can always
-    // fit in an SMI value and be used as a fast sparse array / object key.
-
-    // Output code for the current contents of the index buffer.
-    var ib_code = index_stream[0] & code_mask;  // Load first input index.
-    var code_table = { };  // Key'd on our 20-bit "tuple".
-
-    emit_code(clear_code);  // Spec says first code should be a clear code.
-
-    // First index already loaded, process the rest of the stream.
-    for (var i = 1, il = index_stream.length; i < il; ++i) {
-      var k = index_stream[i] & code_mask;
-      var cur_key = ib_code << 8 | k;  // (prev, k) unique tuple.
-      var cur_code = code_table[cur_key];  // buffer + k.
-
-      // Check if we have to create a new code table entry.
-      if (cur_code === undefined) {  // We don't have buffer + k.
-        // Emit index buffer (without k).
-        // This is an inline version of emit_code, because this is the core
-        // writing routine of the compressor (and V8 cannot inline emit_code
-        // because it is a closure here in a different context).  Additionally
-        // we can call emit_byte_to_buffer less often, because we can have
-        // 30-bits (from our 31-bit signed SMI), and we know our codes will only
-        // be 12-bits, so can safely have 18-bits there without overflow.
-        // emit_code(ib_code);
-        cur |= ib_code << cur_shift;
-        cur_shift += cur_code_size;
-        while (cur_shift >= 8) {
-          buf[p++] = cur & 0xff;
-          cur >>= 8; cur_shift -= 8;
-          if (p === cur_subblock + 256) {  // Finished a subblock.
-            buf[cur_subblock] = 255;
-            cur_subblock = p++;
-          }
-        }
-
-        if (next_code === 4096) {  // Table full, need a clear.
-          emit_code(clear_code);
-          next_code = eoi_code + 1;
-          cur_code_size = min_code_size + 1;
-          code_table = { };
-        } else {  // Table not full, insert a new entry.
-          // Increase our variable bit code sizes if necessary.  This is a bit
-          // tricky as it is based on "timing" between the encoding and
-          // decoder.  From the encoders perspective this should happen after
-          // we've already emitted the index buffer and are about to create the
-          // first table entry that would overflow our current code bit size.
-          if (next_code >= (1 << cur_code_size)) ++cur_code_size;
-          code_table[cur_key] = next_code++;  // Insert into code table.
-        }
-
-        ib_code = k;  // Index buffer to single input k.
-      } else {
-        ib_code = cur_code;  // Index buffer to sequence in code table.
-      }
-    }
-
-    emit_code(ib_code);  // There will still be something in the index buffer.
-    emit_code(eoi_code);  // End Of Information.
-
-    // Flush / finalize the sub-blocks stream to the buffer.
-    emit_bytes_to_buffer(1);
-
-    // Finish the sub-blocks, writing out any unfinished lengths and
-    // terminating with a sub-block of length 0.  If we have already started
-    // but not yet used a sub-block it can just become the terminator.
-    if (cur_subblock + 1 === p) {  // Started but unused.
-      buf[cur_subblock] = 0;
-    } else {  // Started and used, write length and additional terminator block.
-      buf[cur_subblock] = p - cur_subblock - 1;
-      buf[p++] = 0;
-    }
-    return p;
-  }
-
-  function GifReader(buf) {
-    var p = 0;
-
-    // - Header (GIF87a or GIF89a).
-    if (buf[p++] !== 0x47 ||            buf[p++] !== 0x49 || buf[p++] !== 0x46 ||
-        buf[p++] !== 0x38 || (buf[p++]+1 & 0xfd) !== 0x38 || buf[p++] !== 0x61) {
-      throw "Invalid GIF 87a/89a header.";
-    }
-
-    // - Logical Screen Descriptor.
-    var width = buf[p++] | buf[p++] << 8;
-    var height = buf[p++] | buf[p++] << 8;
-    var pf0 = buf[p++];  // <Packed Fields>.
-    var global_palette_flag = pf0 >> 7;
-    var num_global_colors_pow2 = pf0 & 0x7;
-    var num_global_colors = 1 << (num_global_colors_pow2 + 1);
-    var background = buf[p++];
-    buf[p++];  // Pixel aspect ratio (unused?).
-
-    var global_palette_offset = null;
-
-    if (global_palette_flag) {
-      global_palette_offset = p;
-      p += num_global_colors * 3;  // Seek past palette.
-    }
-
-    var no_eof = true;
-
-    var frames = [ ];
-
-    var delay = 0;
-    var transparent_index = null;
-    var disposal = 0;  // 0 - No disposal specified.
-    var loop_count = null;
-
-    this.width = width;
-    this.height = height;
-
-    while (no_eof && p < buf.length) {
-      switch (buf[p++]) {
-        case 0x21:  // Graphics Control Extension Block
-          switch (buf[p++]) {
-            case 0xff:  // Application specific block
-              // Try if it's a Netscape block (with animation loop counter).
-              if (buf[p   ] !== 0x0b ||  // 21 FF already read, check block size.
-                  // NETSCAPE2.0
-                  buf[p+1 ] == 0x4e && buf[p+2 ] == 0x45 && buf[p+3 ] == 0x54 &&
-                  buf[p+4 ] == 0x53 && buf[p+5 ] == 0x43 && buf[p+6 ] == 0x41 &&
-                  buf[p+7 ] == 0x50 && buf[p+8 ] == 0x45 && buf[p+9 ] == 0x32 &&
-                  buf[p+10] == 0x2e && buf[p+11] == 0x30 &&
-                  // Sub-block
-                  buf[p+12] == 0x03 && buf[p+13] == 0x01 && buf[p+16] == 0) {
-                p += 14;
-                loop_count = buf[p++] | buf[p++] << 8;
-                p++;  // Skip terminator.
-              } else {  // We don't know what it is, just try to get past it.
-                p += 12;
-                while (true) {  // Seek through subblocks.
-                  var block_size = buf[p++];
-                  if (block_size === 0) break;
-                  p += block_size;
-                }
-              }
-              break;
-
-            case 0xf9:  // Graphics Control Extension
-              if (buf[p++] !== 0x4 || buf[p+4] !== 0)
-                throw "Invalid graphics extension block.";
-              var pf1 = buf[p++];
-              delay = buf[p++] | buf[p++] << 8;
-              transparent_index = buf[p++];
-              if ((pf1 & 1) === 0) transparent_index = null;
-              disposal = pf1 >> 2 & 0x7;
-              p++;  // Skip terminator.
-              break;
-
-            case 0xfe:  // Comment Extension.
-              while (true) {  // Seek through subblocks.
-                var block_size = buf[p++];
-                if (block_size === 0) break;
-                // console.log(buf.slice(p, p+block_size).toString('ascii'));
-                p += block_size;
-              }
-              break;
-
-            default:
-              throw "Unknown graphic control label: 0x" + buf[p-1].toString(16);
-          }
-          break;
-
-        case 0x2c:  // Image Descriptor.
-          var x = buf[p++] | buf[p++] << 8;
-          var y = buf[p++] | buf[p++] << 8;
-          var w = buf[p++] | buf[p++] << 8;
-          var h = buf[p++] | buf[p++] << 8;
-          var pf2 = buf[p++];
-          var local_palette_flag = pf2 >> 7;
-          var interlace_flag = pf2 >> 6 & 1;
-          var num_local_colors_pow2 = pf2 & 0x7;
-          var num_local_colors = 1 << (num_local_colors_pow2 + 1);
-          var palette_offset = global_palette_offset;
-          var has_local_palette = false;
-          if (local_palette_flag) {
-            var has_local_palette = true;
-            palette_offset = p;  // Override with local palette.
-            p += num_local_colors * 3;  // Seek past palette.
-          }
-
-          var data_offset = p;
-
-          p++;  // codesize
-          while (true) {
-            var block_size = buf[p++];
-            if (block_size === 0) break;
-            p += block_size;
-          }
-
-          frames.push({x: x, y: y, width: w, height: h,
-                       has_local_palette: has_local_palette,
-                       palette_offset: palette_offset,
-                       data_offset: data_offset,
-                       data_length: p - data_offset,
-                       transparent_index: transparent_index,
-                       interlaced: !!interlace_flag,
-                       delay: delay,
-                       disposal: disposal});
-          break;
-
-        case 0x3b:  // Trailer Marker (end of file).
-          no_eof = false;
-          break;
-
-        default:
-          throw "Unknown gif block: 0x" + buf[p-1].toString(16);
-          break;
-      }
-    }
-
-    this.numFrames = function() {
-      return frames.length;
-    };
-
-    this.loopCount = function() {
-      return loop_count;
-    };
-
-    this.frameInfo = function(frame_num) {
-      if (frame_num < 0 || frame_num >= frames.length)
-        throw "Frame index out of range.";
-      return frames[frame_num];
-    };
-
-    this.decodeAndBlitFrameBGRA = function(frame_num, pixels) {
-      var frame = this.frameInfo(frame_num);
-      var num_pixels = frame.width * frame.height;
-      var index_stream = new Uint8Array(num_pixels);  // At most 8-bit indices.
-      GifReaderLZWOutputIndexStream(
-          buf, frame.data_offset, index_stream, num_pixels);
-      var palette_offset = frame.palette_offset;
-
-      // NOTE(deanm): It seems to be much faster to compare index to 256 than
-      // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in
-      // the profile, not sure if it's related to using a Uint8Array.
-      var trans = frame.transparent_index;
-      if (trans === null) trans = 256;
-
-      // We are possibly just blitting to a portion of the entire frame.
-      // That is a subrect within the framerect, so the additional pixels
-      // must be skipped over after we finished a scanline.
-      var framewidth  = frame.width;
-      var framestride = width - framewidth;
-      var xleft       = framewidth;  // Number of subrect pixels left in scanline.
-
-      // Output indicies of the top left and bottom right corners of the subrect.
-      var opbeg = ((frame.y * width) + frame.x) * 4;
-      var opend = ((frame.y + frame.height) * width + frame.x) * 4;
-      var op    = opbeg;
-
-      var scanstride = framestride * 4;
-
-      // Use scanstride to skip past the rows when interlacing.  This is skipping
-      // 7 rows for the first two passes, then 3 then 1.
-      if (frame.interlaced === true) {
-        scanstride += (framewidth + framestride) * 4 * 7;  // Pass 1.
-      }
-
-      var interlaceskip = 8;  // Tracking the row interval in the current pass.
-
-      for (var i = 0, il = index_stream.length; i < il; ++i) {
-        var index = index_stream[i];
-
-        if (xleft === 0) {  // Beginning of new scan line
-          op += scanstride;
-          xleft = framewidth;
-          if (op >= opend) { // Catch the wrap to switch passes when interlacing.
-            scanstride =
-                framestride + (framewidth + framestride) * 4 * (interlaceskip-1);
-            // interlaceskip / 2 * 4 is interlaceskip << 1.
-            op = opbeg + (framewidth + framestride) * (interlaceskip << 1);
-            interlaceskip >>= 1;
-          }
-        }
-
-        if (index === trans) {
-          op += 4;
-        } else {
-          var r = buf[palette_offset + index * 3];
-          var g = buf[palette_offset + index * 3 + 1];
-          var b = buf[palette_offset + index * 3 + 2];
-          pixels[op++] = b;
-          pixels[op++] = g;
-          pixels[op++] = r;
-          pixels[op++] = 255;
-        }
-        --xleft;
-      }
-    };
-
-    // I will go to copy and paste hell one day...
-    this.decodeAndBlitFrameRGBA = function(frame_num, pixels) {
-      var frame = this.frameInfo(frame_num);
-      var num_pixels = frame.width * frame.height;
-      var index_stream = new Uint8Array(num_pixels);  // At most 8-bit indices.
-      GifReaderLZWOutputIndexStream(
-          buf, frame.data_offset, index_stream, num_pixels);
-      var palette_offset = frame.palette_offset;
-
-      // NOTE(deanm): It seems to be much faster to compare index to 256 than
-      // to === null.  Not sure why, but CompareStub_EQ_STRICT shows up high in
-      // the profile, not sure if it's related to using a Uint8Array.
-      var trans = frame.transparent_index;
-      if (trans === null) trans = 256;
-
-      // We are possibly just blitting to a portion of the entire frame.
-      // That is a subrect within the framerect, so the additional pixels
-      // must be skipped over after we finished a scanline.
-      var framewidth  = frame.width;
-      var framestride = width - framewidth;
-      var xleft       = framewidth;  // Number of subrect pixels left in scanline.
-
-      // Output indicies of the top left and bottom right corners of the subrect.
-      var opbeg = ((frame.y * width) + frame.x) * 4;
-      var opend = ((frame.y + frame.height) * width + frame.x) * 4;
-      var op    = opbeg;
-
-      var scanstride = framestride * 4;
-
-      // Use scanstride to skip past the rows when interlacing.  This is skipping
-      // 7 rows for the first two passes, then 3 then 1.
-      if (frame.interlaced === true) {
-        scanstride += (framewidth + framestride) * 4 * 7;  // Pass 1.
-      }
-
-      var interlaceskip = 8;  // Tracking the row interval in the current pass.
-
-      for (var i = 0, il = index_stream.length; i < il; ++i) {
-        var index = index_stream[i];
-
-        if (xleft === 0) {  // Beginning of new scan line
-          op += scanstride;
-          xleft = framewidth;
-          if (op >= opend) { // Catch the wrap to switch passes when interlacing.
-            scanstride =
-                framestride + (framewidth + framestride) * 4 * (interlaceskip-1);
-            // interlaceskip / 2 * 4 is interlaceskip << 1.
-            op = opbeg + (framewidth + framestride) * (interlaceskip << 1);
-            interlaceskip >>= 1;
-          }
-        }
-
-        if (index === trans) {
-          op += 4;
-        } else {
-          var r = buf[palette_offset + index * 3];
-          var g = buf[palette_offset + index * 3 + 1];
-          var b = buf[palette_offset + index * 3 + 2];
-          pixels[op++] = r;
-          pixels[op++] = g;
-          pixels[op++] = b;
-          pixels[op++] = 255;
-        }
-        --xleft;
-      }
-    };
-  }
-
-  function GifReaderLZWOutputIndexStream(code_stream, p, output, output_length) {
-    var min_code_size = code_stream[p++];
-
-    var clear_code = 1 << min_code_size;
-    var eoi_code = clear_code + 1;
-    var next_code = eoi_code + 1;
-
-    var cur_code_size = min_code_size + 1;  // Number of bits per code.
-    // NOTE: This shares the same name as the encoder, but has a different
-    // meaning here.  Here this masks each code coming from the code stream.
-    var code_mask = (1 << cur_code_size) - 1;
-    var cur_shift = 0;
-    var cur = 0;
-
-    var op = 0;  // Output pointer.
-    
-    var subblock_size = code_stream[p++];
-
-    // TODO(deanm): Would using a TypedArray be any faster?  At least it would
-    // solve the fast mode / backing store uncertainty.
-    // var code_table = Array(4096);
-    var code_table = new Int32Array(4096);  // Can be signed, we only use 20 bits.
-
-    var prev_code = null;  // Track code-1.
-
-    while (true) {
-      // Read up to two bytes, making sure we always 12-bits for max sized code.
-      while (cur_shift < 16) {
-        if (subblock_size === 0) break;  // No more data to be read.
-
-        cur |= code_stream[p++] << cur_shift;
-        cur_shift += 8;
-
-        if (subblock_size === 1) {  // Never let it get to 0 to hold logic above.
-          subblock_size = code_stream[p++];  // Next subblock.
-        } else {
-          --subblock_size;
-        }
-      }
-
-      // TODO(deanm): We should never really get here, we should have received
-      // and EOI.
-      if (cur_shift < cur_code_size)
-        break;
-
-      var code = cur & code_mask;
-      cur >>= cur_code_size;
-      cur_shift -= cur_code_size;
-
-      // TODO(deanm): Maybe should check that the first code was a clear code,
-      // at least this is what you're supposed to do.  But actually our encoder
-      // now doesn't emit a clear code first anyway.
-      if (code === clear_code) {
-        // We don't actually have to clear the table.  This could be a good idea
-        // for greater error checking, but we don't really do any anyway.  We
-        // will just track it with next_code and overwrite old entries.
-
-        next_code = eoi_code + 1;
-        cur_code_size = min_code_size + 1;
-        code_mask = (1 << cur_code_size) - 1;
-
-        // Don't update prev_code ?
-        prev_code = null;
-        continue;
-      } else if (code === eoi_code) {
-        break;
-      }
-
-      // We have a similar situation as the decoder, where we want to store
-      // variable length entries (code table entries), but we want to do in a
-      // faster manner than an array of arrays.  The code below stores sort of a
-      // linked list within the code table, and then "chases" through it to
-      // construct the dictionary entries.  When a new entry is created, just the
-      // last byte is stored, and the rest (prefix) of the entry is only
-      // referenced by its table entry.  Then the code chases through the
-      // prefixes until it reaches a single byte code.  We have to chase twice,
-      // first to compute the length, and then to actually copy the data to the
-      // output (backwards, since we know the length).  The alternative would be
-      // storing something in an intermediate stack, but that doesn't make any
-      // more sense.  I implemented an approach where it also stored the length
-      // in the code table, although it's a bit tricky because you run out of
-      // bits (12 + 12 + 8), but I didn't measure much improvements (the table
-      // entries are generally not the long).  Even when I created benchmarks for
-      // very long table entries the complexity did not seem worth it.
-      // The code table stores the prefix entry in 12 bits and then the suffix
-      // byte in 8 bits, so each entry is 20 bits.
-
-      var chase_code = code < next_code ? code : prev_code;
-
-      // Chase what we will output, either {CODE} or {CODE-1}.
-      var chase_length = 0;
-      var chase = chase_code;
-      while (chase > clear_code) {
-        chase = code_table[chase] >> 8;
-        ++chase_length;
-      }
-
-      var k = chase;
-      
-      var op_end = op + chase_length + (chase_code !== code ? 1 : 0);
-      if (op_end > output_length) {
-        console.log("Warning, gif stream longer than expected.");
-        return;
-      }
-
-      // Already have the first byte from the chase, might as well write it fast.
-      output[op++] = k;
-
-      op += chase_length;
-      var b = op;  // Track pointer, writing backwards.
-
-      if (chase_code !== code)  // The case of emitting {CODE-1} + k.
-        output[op++] = k;
-
-      chase = chase_code;
-      while (chase_length--) {
-        chase = code_table[chase];
-        output[--b] = chase & 0xff;  // Write backwards.
-        chase >>= 8;  // Pull down to the prefix code.
-      }
-
-      if (prev_code !== null && next_code < 4096) {
-        code_table[next_code++] = prev_code << 8 | k;
-        // TODO(deanm): Figure out this clearing vs code growth logic better.  I
-        // have an feeling that it should just happen somewhere else, for now it
-        // is awkward between when we grow past the max and then hit a clear code.
-        // For now just check if we hit the max 12-bits (then a clear code should
-        // follow, also of course encoded in 12-bits).
-        if (next_code >= code_mask+1 && cur_code_size < 12) {
-          ++cur_code_size;
-          code_mask = code_mask << 1 | 1;
-        }
-      }
-
-      prev_code = code;
-    }
-
-    if (op !== output_length) {
-      console.log("Warning, gif stream shorter than expected.");
-    }
-
-    return output;
-  }
-
-  try { exports.GifWriter = GifWriter; exports.GifReader = GifReader; } catch(e) { }  // CommonJS.
-  
-
-  /*
-    Copyright (c) 2008, Adobe Systems Incorporated
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without 
-    modification, are permitted provided that the following conditions are
-    met:
-
-    * Redistributions of source code must retain the above copyright notice, 
-      this list of conditions and the following disclaimer.
-    
-    * Redistributions in binary form must reproduce the above copyright
-      notice, this list of conditions and the following disclaimer in the 
-      documentation and/or other materials provided with the distribution.
-    
-    * Neither the name of Adobe Systems Incorporated nor the names of its 
-      contributors may be used to endorse or promote products derived from 
-      this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
-    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-  */
-  /*
-  JPEG encoder ported to JavaScript and optimized by Andreas Ritter, www.bytestrom.eu, 11/2009
-
-  Basic GUI blocking jpeg encoder
-  */
-
-  function JPEGEncoder(quality) {
-  	var ffloor = Math.floor;
-  	var YTable = new Array(64);
-  	var UVTable = new Array(64);
-  	var fdtbl_Y = new Array(64);
-  	var fdtbl_UV = new Array(64);
-  	var YDC_HT;
-  	var UVDC_HT;
-  	var YAC_HT;
-  	var UVAC_HT;
-  	
-  	var bitcode = new Array(65535);
-  	var category = new Array(65535);
-  	var outputfDCTQuant = new Array(64);
-  	var DU = new Array(64);
-  	var byteout = [];
-  	var bytenew = 0;
-  	var bytepos = 7;
-  	
-  	var YDU = new Array(64);
-  	var UDU = new Array(64);
-  	var VDU = new Array(64);
-  	var clt = new Array(256);
-  	var RGB_YUV_TABLE = new Array(2048);
-  	var currentQuality;
-  	
-  	var ZigZag = [
-  			 0, 1, 5, 6,14,15,27,28,
-  			 2, 4, 7,13,16,26,29,42,
-  			 3, 8,12,17,25,30,41,43,
-  			 9,11,18,24,31,40,44,53,
-  			10,19,23,32,39,45,52,54,
-  			20,22,33,38,46,51,55,60,
-  			21,34,37,47,50,56,59,61,
-  			35,36,48,49,57,58,62,63
-  		];
-  	
-  	var std_dc_luminance_nrcodes = [0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0];
-  	var std_dc_luminance_values = [0,1,2,3,4,5,6,7,8,9,10,11];
-  	var std_ac_luminance_nrcodes = [0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d];
-  	var std_ac_luminance_values = [
-  			0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,
-  			0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
-  			0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,
-  			0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,
-  			0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,
-  			0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,
-  			0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,
-  			0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
-  			0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
-  			0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
-  			0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
-  			0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
-  			0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,
-  			0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
-  			0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,
-  			0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,
-  			0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,
-  			0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,
-  			0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,
-  			0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,
-  			0xf9,0xfa
-  		];
-  	
-  	var std_dc_chrominance_nrcodes = [0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0];
-  	var std_dc_chrominance_values = [0,1,2,3,4,5,6,7,8,9,10,11];
-  	var std_ac_chrominance_nrcodes = [0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77];
-  	var std_ac_chrominance_values = [
-  			0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,
-  			0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
-  			0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,
-  			0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,
-  			0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,
-  			0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,
-  			0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,
-  			0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,
-  			0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,
-  			0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,
-  			0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,
-  			0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,
-  			0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,
-  			0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,
-  			0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,
-  			0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,
-  			0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,
-  			0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,
-  			0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,
-  			0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,
-  			0xf9,0xfa
-  		];
-  	
-  	function initQuantTables(sf){
-  			var YQT = [
-  				16, 11, 10, 16, 24, 40, 51, 61,
-  				12, 12, 14, 19, 26, 58, 60, 55,
-  				14, 13, 16, 24, 40, 57, 69, 56,
-  				14, 17, 22, 29, 51, 87, 80, 62,
-  				18, 22, 37, 56, 68,109,103, 77,
-  				24, 35, 55, 64, 81,104,113, 92,
-  				49, 64, 78, 87,103,121,120,101,
-  				72, 92, 95, 98,112,100,103, 99
-  			];
-  			
-  			for (var i = 0; i < 64; i++) {
-  				var t = ffloor((YQT[i]*sf+50)/100);
-  				if (t < 1) {
-  					t = 1;
-  				} else if (t > 255) {
-  					t = 255;
-  				}
-  				YTable[ZigZag[i]] = t;
-  			}
-  			var UVQT = [
-  				17, 18, 24, 47, 99, 99, 99, 99,
-  				18, 21, 26, 66, 99, 99, 99, 99,
-  				24, 26, 56, 99, 99, 99, 99, 99,
-  				47, 66, 99, 99, 99, 99, 99, 99,
-  				99, 99, 99, 99, 99, 99, 99, 99,
-  				99, 99, 99, 99, 99, 99, 99, 99,
-  				99, 99, 99, 99, 99, 99, 99, 99,
-  				99, 99, 99, 99, 99, 99, 99, 99
-  			];
-  			for (var j = 0; j < 64; j++) {
-  				var u = ffloor((UVQT[j]*sf+50)/100);
-  				if (u < 1) {
-  					u = 1;
-  				} else if (u > 255) {
-  					u = 255;
-  				}
-  				UVTable[ZigZag[j]] = u;
-  			}
-  			var aasf = [
-  				1.0, 1.387039845, 1.306562965, 1.175875602,
-  				1.0, 0.785694958, 0.541196100, 0.275899379
-  			];
-  			var k = 0;
-  			for (var row = 0; row < 8; row++)
-  			{
-  				for (var col = 0; col < 8; col++)
-  				{
-  					fdtbl_Y[k]  = (1.0 / (YTable [ZigZag[k]] * aasf[row] * aasf[col] * 8.0));
-  					fdtbl_UV[k] = (1.0 / (UVTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0));
-  					k++;
-  				}
-  			}
-  		}
-  		
-  		function computeHuffmanTbl(nrcodes, std_table){
-  			var codevalue = 0;
-  			var pos_in_table = 0;
-  			var HT = new Array();
-  			for (var k = 1; k <= 16; k++) {
-  				for (var j = 1; j <= nrcodes[k]; j++) {
-  					HT[std_table[pos_in_table]] = [];
-  					HT[std_table[pos_in_table]][0] = codevalue;
-  					HT[std_table[pos_in_table]][1] = k;
-  					pos_in_table++;
-  					codevalue++;
-  				}
-  				codevalue*=2;
-  			}
-  			return HT;
-  		}
-  		
-  		function initHuffmanTbl()
-  		{
-  			YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values);
-  			UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values);
-  			YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values);
-  			UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values);
-  		}
-  	
-  		function initCategoryNumber()
-  		{
-  			var nrlower = 1;
-  			var nrupper = 2;
-  			for (var cat = 1; cat <= 15; cat++) {
-  				//Positive numbers
-  				for (var nr = nrlower; nr<nrupper; nr++) {
-  					category[32767+nr] = cat;
-  					bitcode[32767+nr] = [];
-  					bitcode[32767+nr][1] = cat;
-  					bitcode[32767+nr][0] = nr;
-  				}
-  				//Negative numbers
-  				for (var nrneg =-(nrupper-1); nrneg<=-nrlower; nrneg++) {
-  					category[32767+nrneg] = cat;
-  					bitcode[32767+nrneg] = [];
-  					bitcode[32767+nrneg][1] = cat;
-  					bitcode[32767+nrneg][0] = nrupper-1+nrneg;
-  				}
-  				nrlower <<= 1;
-  				nrupper <<= 1;
-  			}
-  		}
-  		
-  		function initRGBYUVTable() {
-  			for(var i = 0; i < 256;i++) {
-  				RGB_YUV_TABLE[i]      		=  19595 * i;
-  				RGB_YUV_TABLE[(i+ 256)>>0] 	=  38470 * i;
-  				RGB_YUV_TABLE[(i+ 512)>>0] 	=   7471 * i + 0x8000;
-  				RGB_YUV_TABLE[(i+ 768)>>0] 	= -11059 * i;
-  				RGB_YUV_TABLE[(i+1024)>>0] 	= -21709 * i;
-  				RGB_YUV_TABLE[(i+1280)>>0] 	=  32768 * i + 0x807FFF;
-  				RGB_YUV_TABLE[(i+1536)>>0] 	= -27439 * i;
-  				RGB_YUV_TABLE[(i+1792)>>0] 	= - 5329 * i;
-  			}
-  		}
-  		
-  		// IO functions
-  		function writeBits(bs)
-  		{
-  			var value = bs[0];
-  			var posval = bs[1]-1;
-  			while ( posval >= 0 ) {
-  				if (value & (1 << posval) ) {
-  					bytenew |= (1 << bytepos);
-  				}
-  				posval--;
-  				bytepos--;
-  				if (bytepos < 0) {
-  					if (bytenew == 0xFF) {
-  						writeByte(0xFF);
-  						writeByte(0);
-  					}
-  					else {
-  						writeByte(bytenew);
-  					}
-  					bytepos=7;
-  					bytenew=0;
-  				}
-  			}
-  		}
-  	
-  		function writeByte(value)
-  		{
-  			//byteout.push(clt[value]); // write char directly instead of converting later
-        byteout.push(value);
-  		}
-  	
-  		function writeWord(value)
-  		{
-  			writeByte((value>>8)&0xFF);
-  			writeByte((value   )&0xFF);
-  		}
-  		
-  		// DCT & quantization core
-  		function fDCTQuant(data, fdtbl)
-  		{
-  			var d0, d1, d2, d3, d4, d5, d6, d7;
-  			/* Pass 1: process rows. */
-  			var dataOff=0;
-  			var i;
-  			var I8 = 8;
-  			var I64 = 64;
-  			for (i=0; i<I8; ++i)
-  			{
-  				d0 = data[dataOff];
-  				d1 = data[dataOff+1];
-  				d2 = data[dataOff+2];
-  				d3 = data[dataOff+3];
-  				d4 = data[dataOff+4];
-  				d5 = data[dataOff+5];
-  				d6 = data[dataOff+6];
-  				d7 = data[dataOff+7];
-  				
-  				var tmp0 = d0 + d7;
-  				var tmp7 = d0 - d7;
-  				var tmp1 = d1 + d6;
-  				var tmp6 = d1 - d6;
-  				var tmp2 = d2 + d5;
-  				var tmp5 = d2 - d5;
-  				var tmp3 = d3 + d4;
-  				var tmp4 = d3 - d4;
-  	
-  				/* Even part */
-  				var tmp10 = tmp0 + tmp3;	/* phase 2 */
-  				var tmp13 = tmp0 - tmp3;
-  				var tmp11 = tmp1 + tmp2;
-  				var tmp12 = tmp1 - tmp2;
-  	
-  				data[dataOff] = tmp10 + tmp11; /* phase 3 */
-  				data[dataOff+4] = tmp10 - tmp11;
-  	
-  				var z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */
-  				data[dataOff+2] = tmp13 + z1; /* phase 5 */
-  				data[dataOff+6] = tmp13 - z1;
-  	
-  				/* Odd part */
-  				tmp10 = tmp4 + tmp5; /* phase 2 */
-  				tmp11 = tmp5 + tmp6;
-  				tmp12 = tmp6 + tmp7;
-  	
-  				/* The rotator is modified from fig 4-8 to avoid extra negations. */
-  				var z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */
-  				var z2 = 0.541196100 * tmp10 + z5; /* c2-c6 */
-  				var z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */
-  				var z3 = tmp11 * 0.707106781; /* c4 */
-  	
-  				var z11 = tmp7 + z3;	/* phase 5 */
-  				var z13 = tmp7 - z3;
-  	
-  				data[dataOff+5] = z13 + z2;	/* phase 6 */
-  				data[dataOff+3] = z13 - z2;
-  				data[dataOff+1] = z11 + z4;
-  				data[dataOff+7] = z11 - z4;
-  	
-  				dataOff += 8; /* advance pointer to next row */
-  			}
-  	
-  			/* Pass 2: process columns. */
-  			dataOff = 0;
-  			for (i=0; i<I8; ++i)
-  			{
-  				d0 = data[dataOff];
-  				d1 = data[dataOff + 8];
-  				d2 = data[dataOff + 16];
-  				d3 = data[dataOff + 24];
-  				d4 = data[dataOff + 32];
-  				d5 = data[dataOff + 40];
-  				d6 = data[dataOff + 48];
-  				d7 = data[dataOff + 56];
-  				
-  				var tmp0p2 = d0 + d7;
-  				var tmp7p2 = d0 - d7;
-  				var tmp1p2 = d1 + d6;
-  				var tmp6p2 = d1 - d6;
-  				var tmp2p2 = d2 + d5;
-  				var tmp5p2 = d2 - d5;
-  				var tmp3p2 = d3 + d4;
-  				var tmp4p2 = d3 - d4;
-  	
-  				/* Even part */
-  				var tmp10p2 = tmp0p2 + tmp3p2;	/* phase 2 */
-  				var tmp13p2 = tmp0p2 - tmp3p2;
-  				var tmp11p2 = tmp1p2 + tmp2p2;
-  				var tmp12p2 = tmp1p2 - tmp2p2;
-  	
-  				data[dataOff] = tmp10p2 + tmp11p2; /* phase 3 */
-  				data[dataOff+32] = tmp10p2 - tmp11p2;
-  	
-  				var z1p2 = (tmp12p2 + tmp13p2) * 0.707106781; /* c4 */
-  				data[dataOff+16] = tmp13p2 + z1p2; /* phase 5 */
-  				data[dataOff+48] = tmp13p2 - z1p2;
-  	
-  				/* Odd part */
-  				tmp10p2 = tmp4p2 + tmp5p2; /* phase 2 */
-  				tmp11p2 = tmp5p2 + tmp6p2;
-  				tmp12p2 = tmp6p2 + tmp7p2;
-  	
-  				/* The rotator is modified from fig 4-8 to avoid extra negations. */
-  				var z5p2 = (tmp10p2 - tmp12p2) * 0.382683433; /* c6 */
-  				var z2p2 = 0.541196100 * tmp10p2 + z5p2; /* c2-c6 */
-  				var z4p2 = 1.306562965 * tmp12p2 + z5p2; /* c2+c6 */
-  				var z3p2 = tmp11p2 * 0.707106781; /* c4 */
-  	
-  				var z11p2 = tmp7p2 + z3p2;	/* phase 5 */
-  				var z13p2 = tmp7p2 - z3p2;
-  	
-  				data[dataOff+40] = z13p2 + z2p2; /* phase 6 */
-  				data[dataOff+24] = z13p2 - z2p2;
-  				data[dataOff+ 8] = z11p2 + z4p2;
-  				data[dataOff+56] = z11p2 - z4p2;
-  	
-  				dataOff++; /* advance pointer to next column */
-  			}
-  	
-  			// Quantize/descale the coefficients
-  			var fDCTQuant;
-  			for (i=0; i<I64; ++i)
-  			{
-  				// Apply the quantization and scaling factor & Round to nearest integer
-  				fDCTQuant = data[i]*fdtbl[i];
-  				outputfDCTQuant[i] = (fDCTQuant > 0.0) ? ((fDCTQuant + 0.5)|0) : ((fDCTQuant - 0.5)|0);
-  				//outputfDCTQuant[i] = fround(fDCTQuant);
-
-  			}
-  			return outputfDCTQuant;
-  		}
-  		
-  		function writeAPP0()
-  		{
-  			writeWord(0xFFE0); // marker
-  			writeWord(16); // length
-  			writeByte(0x4A); // J
-  			writeByte(0x46); // F
-  			writeByte(0x49); // I
-  			writeByte(0x46); // F
-  			writeByte(0); // = "JFIF",'\0'
-  			writeByte(1); // versionhi
-  			writeByte(1); // versionlo
-  			writeByte(0); // xyunits
-  			writeWord(1); // xdensity
-  			writeWord(1); // ydensity
-  			writeByte(0); // thumbnwidth
-  			writeByte(0); // thumbnheight
-  		}
-  	
-  		function writeSOF0(width, height)
-  		{
-  			writeWord(0xFFC0); // marker
-  			writeWord(17);   // length, truecolor YUV JPG
-  			writeByte(8);    // precision
-  			writeWord(height);
-  			writeWord(width);
-  			writeByte(3);    // nrofcomponents
-  			writeByte(1);    // IdY
-  			writeByte(0x11); // HVY
-  			writeByte(0);    // QTY
-  			writeByte(2);    // IdU
-  			writeByte(0x11); // HVU
-  			writeByte(1);    // QTU
-  			writeByte(3);    // IdV
-  			writeByte(0x11); // HVV
-  			writeByte(1);    // QTV
-  		}
-  	
-  		function writeDQT()
-  		{
-  			writeWord(0xFFDB); // marker
-  			writeWord(132);	   // length
-  			writeByte(0);
-  			for (var i=0; i<64; i++) {
-  				writeByte(YTable[i]);
-  			}
-  			writeByte(1);
-  			for (var j=0; j<64; j++) {
-  				writeByte(UVTable[j]);
-  			}
-  		}
-  	
-  		function writeDHT()
-  		{
-  			writeWord(0xFFC4); // marker
-  			writeWord(0x01A2); // length
-  	
-  			writeByte(0); // HTYDCinfo
-  			for (var i=0; i<16; i++) {
-  				writeByte(std_dc_luminance_nrcodes[i+1]);
-  			}
-  			for (var j=0; j<=11; j++) {
-  				writeByte(std_dc_luminance_values[j]);
-  			}
-  	
-  			writeByte(0x10); // HTYACinfo
-  			for (var k=0; k<16; k++) {
-  				writeByte(std_ac_luminance_nrcodes[k+1]);
-  			}
-  			for (var l=0; l<=161; l++) {
-  				writeByte(std_ac_luminance_values[l]);
-  			}
-  	
-  			writeByte(1); // HTUDCinfo
-  			for (var m=0; m<16; m++) {
-  				writeByte(std_dc_chrominance_nrcodes[m+1]);
-  			}
-  			for (var n=0; n<=11; n++) {
-  				writeByte(std_dc_chrominance_values[n]);
-  			}
-  	
-  			writeByte(0x11); // HTUACinfo
-  			for (var o=0; o<16; o++) {
-  				writeByte(std_ac_chrominance_nrcodes[o+1]);
-  			}
-  			for (var p=0; p<=161; p++) {
-  				writeByte(std_ac_chrominance_values[p]);
-  			}
-  		}
-  	
-  		function writeSOS()
-  		{
-  			writeWord(0xFFDA); // marker
-  			writeWord(12); // length
-  			writeByte(3); // nrofcomponents
-  			writeByte(1); // IdY
-  			writeByte(0); // HTY
-  			writeByte(2); // IdU
-  			writeByte(0x11); // HTU
-  			writeByte(3); // IdV
-  			writeByte(0x11); // HTV
-  			writeByte(0); // Ss
-  			writeByte(0x3f); // Se
-  			writeByte(0); // Bf
-  		}
-  		
-  		function processDU(CDU, fdtbl, DC, HTDC, HTAC){
-  			var EOB = HTAC[0x00];
-  			var M16zeroes = HTAC[0xF0];
-  			var pos;
-  			var I16 = 16;
-  			var I63 = 63;
-  			var I64 = 64;
-  			var DU_DCT = fDCTQuant(CDU, fdtbl);
-  			//ZigZag reorder
-  			for (var j=0;j<I64;++j) {
-  				DU[ZigZag[j]]=DU_DCT[j];
-  			}
-  			var Diff = DU[0] - DC; DC = DU[0];
-  			//Encode DC
-  			if (Diff==0) {
-  				writeBits(HTDC[0]); // Diff might be 0
-  			} else {
-  				pos = 32767+Diff;
-  				writeBits(HTDC[category[pos]]);
-  				writeBits(bitcode[pos]);
-  			}
-  			//Encode ACs
-  			var end0pos = 63; // was const... which is crazy
-  			for (; (end0pos>0)&&(DU[end0pos]==0); end0pos--) {}			//end0pos = first element in reverse order !=0
-  			if ( end0pos == 0) {
-  				writeBits(EOB);
-  				return DC;
-  			}
-  			var i = 1;
-  			var lng;
-  			while ( i <= end0pos ) {
-  				var startpos = i;
-  				for (; (DU[i]==0) && (i<=end0pos); ++i) {}
-  				var nrzeroes = i-startpos;
-  				if ( nrzeroes >= I16 ) {
-  					lng = nrzeroes>>4;
-  					for (var nrmarker=1; nrmarker <= lng; ++nrmarker)
-  						writeBits(M16zeroes);
-  					nrzeroes = nrzeroes&0xF;
-  				}
-  				pos = 32767+DU[i];
-  				writeBits(HTAC[(nrzeroes<<4)+category[pos]]);
-  				writeBits(bitcode[pos]);
-  				i++;
-  			}
-  			if ( end0pos != I63 ) {
-  				writeBits(EOB);
-  			}
-  			return DC;
-  		}
-
-  		function initCharLookupTable(){
-  			var sfcc = String.fromCharCode;
-  			for(var i=0; i < 256; i++){ ///// ACHTUNG // 255
-  				clt[i] = sfcc(i);
-  			}
-  		}
-  		
-  		this.encode = function(image,quality) // image data object
-  		{
-  			var time_start = new Date().getTime();
-  			
-  			if(quality) setQuality(quality);
-  			
-  			// Initialize bit writer
-  			byteout = new Array();
-  			bytenew=0;
-  			bytepos=7;
-  	
-  			// Add JPEG headers
-  			writeWord(0xFFD8); // SOI
-  			writeAPP0();
-  			writeDQT();
-  			writeSOF0(image.width,image.height);
-  			writeDHT();
-  			writeSOS();
-
-  	
-  			// Encode 8x8 macroblocks
-  			var DCY=0;
-  			var DCU=0;
-  			var DCV=0;
-  			
-  			bytenew=0;
-  			bytepos=7;
-  			
-  			
-  			this.encode.displayName = "_encode_";
-
-  			var imageData = image.data;
-  			var width = image.width;
-  			var height = image.height;
-
-  			var quadWidth = width*4;
-  			
-  			var x, y = 0;
-  			var r, g, b;
-  			var start,p, col,row,pos;
-  			while(y < height){
-  				x = 0;
-  				while(x < quadWidth){
-  				start = quadWidth * y + x;
-  				p = start;
-  				col = -1;
-  				row = 0;
-  				
-  				for(pos=0; pos < 64; pos++){
-  					row = pos >> 3;// /8
-  					col = ( pos & 7 ) * 4; // %8
-  					p = start + ( row * quadWidth ) + col;		
-  					
-  					if(y+row >= height){ // padding bottom
-  						p-= (quadWidth*(y+1+row-height));
-  					}
-
-  					if(x+col >= quadWidth){ // padding right	
-  						p-= ((x+col) - quadWidth +4);
-  					}
-  					
-  					r = imageData[ p++ ];
-  					g = imageData[ p++ ];
-  					b = imageData[ p++ ];
-  					
-  					
-  					/* // calculate YUV values dynamically
-  					YDU[pos]=((( 0.29900)*r+( 0.58700)*g+( 0.11400)*b))-128; //-0x80
-  					UDU[pos]=(((-0.16874)*r+(-0.33126)*g+( 0.50000)*b));
-  					VDU[pos]=((( 0.50000)*r+(-0.41869)*g+(-0.08131)*b));
-  					*/
-  					
-  					// use lookup table (slightly faster)
-  					YDU[pos] = ((RGB_YUV_TABLE[r]             + RGB_YUV_TABLE[(g +  256)>>0] + RGB_YUV_TABLE[(b +  512)>>0]) >> 16)-128;
-  					UDU[pos] = ((RGB_YUV_TABLE[(r +  768)>>0] + RGB_YUV_TABLE[(g + 1024)>>0] + RGB_YUV_TABLE[(b + 1280)>>0]) >> 16)-128;
-  					VDU[pos] = ((RGB_YUV_TABLE[(r + 1280)>>0] + RGB_YUV_TABLE[(g + 1536)>>0] + RGB_YUV_TABLE[(b + 1792)>>0]) >> 16)-128;
-
-  				}
-  				
-  				DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
-  				DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
-  				DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
-  				x+=32;
-  				}
-  				y+=8;
-  			}
-  			
-  			
-  			////////////////////////////////////////////////////////////////
-  	
-  			// Do the bit alignment of the EOI marker
-  			if ( bytepos >= 0 ) {
-  				var fillbits = [];
-  				fillbits[1] = bytepos+1;
-  				fillbits[0] = (1<<(bytepos+1))-1;
-  				writeBits(fillbits);
-  			}
-  	
-  			writeWord(0xFFD9); //EOI
-
-        return new Uint8Array(byteout);
-        //return new Buffer(byteout);
-
-  			var jpegDataUri = 'data:image/jpeg;base64,' + btoa(byteout.join(''));
-  			
-  			byteout = [];
-  			
-  			// benchmarking
-  			var duration = new Date().getTime() - time_start;
-      		//console.log('Encoding time: '+ duration + 'ms');
-      		//
-  			
-  			return jpegDataUri			
-  	};
-  	
-  	function setQuality(quality){
-  		if (quality <= 0) {
-  			quality = 1;
-  		}
-  		if (quality > 100) {
-  			quality = 100;
-  		}
-  		
-  		if(currentQuality == quality) return // don't recalc if unchanged
-  		
-  		var sf = 0;
-  		if (quality < 50) {
-  			sf = Math.floor(5000 / quality);
-  		} else {
-  			sf = Math.floor(200 - quality*2);
-  		}
-  		
-  		initQuantTables(sf);
-  		currentQuality = quality;
-  		//console.log('Quality set to: '+quality +'%');
-  	}
-  	
-  	function init(){
-  		var time_start = new Date().getTime();
-  		if(!quality) quality = 50;
-  		// Create tables
-  		initCharLookupTable();
-  		initHuffmanTbl();
-  		initCategoryNumber();
-  		initRGBYUVTable();
-  		
-  		setQuality(quality);
-  		var duration = new Date().getTime() - time_start;
-      	//console.log('Initialization '+ duration + 'ms');
-  	}
-  	
-  	init();
-  	
-  }
-
-
-  try { module.exports = JPEGEncoder; } catch(e) { }  // CommonJS.
-
-  /**
-   * @author shaozilee
-   *
-   * Bmp format decoder,support 1bit 4bit 8bit 24bit bmp
-   *
-   */
-
-  function BmpDecoder(buffer,is_with_alpha) {
-    this.pos = 0;
-    this.buffer = buffer;
-    this.datav = new DataView(buffer.buffer);
-    this.is_with_alpha = !!is_with_alpha;
-    this.bottom_up = true;
-    this.flag = String.fromCharCode(this.buffer[0]) + String.fromCharCode(this.buffer[1]);
-    this.pos += 2;
-    if (["BM","BA", "CI", "CP", "IC", "PT"].indexOf(this.flag) === -1) throw new Error("Invalid BMP File");
-    this.parseHeader();
-    this.parseBGR();
-  }
-
-  BmpDecoder.prototype.parseHeader = function() {
-    this.fileSize = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.reserved = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.offset = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.headerSize = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.width = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.height = this.datav.getInt32(this.pos, true);  this.pos += 4;
-    this.planes = this.datav.getUint16(this.pos, true); 
-    this.pos += 2;
-    this.bitPP = this.datav.getUint16(this.pos, true); 
-    this.pos += 2;
-    this.compress = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.rawSize = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.hr = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.vr = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.colors = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-    this.importantColors = this.datav.getUint32(this.pos, true); 
-    this.pos += 4;
-
-    if(this.bitPP === 16 && this.is_with_alpha){
-      this.bitPP = 15;
-    }
-    if (this.bitPP < 15) {
-      var len = this.colors === 0 ? 1 << this.bitPP : this.colors;
-      this.palette = new Array(len);
-      for (var i = 0; i < len; i++) {
-        var blue = this.datav.getUint8(this.pos++, true);      var green = this.datav.getUint8(this.pos++, true);      var red = this.datav.getUint8(this.pos++, true);      var quad = this.datav.getUint8(this.pos++, true);      this.palette[i] = {
-          red: red,
-          green: green,
-          blue: blue,
-          quad: quad
-        };
-      }
-    }
-    if(this.height < 0) {
-      this.height *= -1;
-      this.bottom_up = false;
-    }
-
-  };
-
-  BmpDecoder.prototype.parseBGR = function() {
-    this.pos = this.offset;
-    try {
-      var bitn = "bit" + this.bitPP;
-      var len = this.width * this.height * 4;
-      this.data = new Uint8Array(len);
-
-      this[bitn]();
-    } catch (e) {
-      console.log("bit decode error:" + e);
-    }
-
-  };
-
-  BmpDecoder.prototype.bit1 = function() {
-    var xlen = Math.ceil(this.width / 8);
-    var mode = xlen%4;
-    var y = this.height >= 0 ? this.height - 1 : -this.height;
-    for (var y = this.height - 1; y >= 0; y--) {
-      var line = this.bottom_up ? y : this.height - 1 - y;
-      for (var x = 0; x < xlen; x++) {
-        var b = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x*8*4;
-        for (var i = 0; i < 8; i++) {
-          if(x*8+i<this.width){
-            var rgb = this.palette[((b>>(7-i))&0x1)];
-            this.data[location+i*4] = rgb.blue;
-            this.data[location+i*4 + 1] = rgb.green;
-            this.data[location+i*4 + 2] = rgb.red;
-            this.data[location+i*4 + 3] = 0xFF;
-          }else{
-            break;
-          }
-        }
-      }
-
-      if (mode != 0){
-        this.pos+=(4 - mode);
-      }
-    }
-  };
-
-  BmpDecoder.prototype.bit4 = function() {
-    var xlen = Math.ceil(this.width/2);
-    var mode = xlen%4;
-    for (var y = this.height - 1; y >= 0; y--) {
-      var line = this.bottom_up ? y : this.height - 1 - y;
-      for (var x = 0; x < xlen; x++) {
-        var b = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x*2*4;
-
-        var before = b>>4;
-        var after = b&0x0F;
-
-        var rgb = this.palette[before];
-        this.data[location] = rgb.blue;
-        this.data[location + 1] = rgb.green;
-        this.data[location + 2] = rgb.red;
-        this.data[location + 3] = 0xFF;
-
-        if(x*2+1>=this.width)break;
-
-        rgb = this.palette[after];
-        this.data[location+4] = rgb.blue;
-        this.data[location+4 + 1] = rgb.green;
-        this.data[location+4 + 2] = rgb.red;
-        this.data[location+4 + 3] = 0xFF;
-      }
-
-      if (mode != 0){
-        this.pos+=(4 - mode);
-      }
-    }
-
-  };
-
-  BmpDecoder.prototype.bit8 = function() {
-    var mode = this.width%4;
-    for (var y = this.height - 1; y >= 0; y--) {
-      var line = this.bottom_up ? y : this.height - 1 - y;
-      for (var x = 0; x < this.width; x++) {
-        var b = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x*4;
-        if(b < this.palette.length) {
-          var rgb = this.palette[b];
-          this.data[location] = rgb.red;
-          this.data[location + 1] = rgb.green;
-          this.data[location + 2] = rgb.blue;
-          this.data[location + 3] = 0xFF;
-        } else {
-          this.data[location] = 0xFF;
-          this.data[location + 1] = 0xFF;
-          this.data[location + 2] = 0xFF;
-          this.data[location + 3] = 0xFF;
-        }
-      }
-      if (mode != 0){
-        this.pos+=(4 - mode);
-      }
-    }
-  };
-
-  BmpDecoder.prototype.bit15 = function() {
-    var dif_w =this.width % 3;
-    var _11111 = parseInt("11111", 2),_1_5 = _11111;
-    for (var y = this.height - 1; y >= 0; y--) {
-      var line = this.bottom_up ? y : this.height - 1 - y;
-      for (var x = 0; x < this.width; x++) {
-
-        var B = this.datav.getUint16(this.pos, true); 
-        this.pos+=2;
-        var blue = (B & _1_5) / _1_5 * 255 | 0;
-        var green = (B >> 5 & _1_5 ) / _1_5 * 255 | 0;
-        var red = (B >> 10 & _1_5) / _1_5 * 255 | 0;
-        var alpha = (B>>15)?0xFF:0x00;
-
-        var location = line * this.width * 4 + x * 4;
-        this.data[location] = red;
-        this.data[location + 1] = green;
-        this.data[location + 2] = blue;
-        this.data[location + 3] = alpha;
-      }
-      //skip extra bytes
-      this.pos += dif_w;
-    }
-  };
-
-  BmpDecoder.prototype.bit16 = function() {
-    var dif_w =this.width % 3;
-    var _11111 = parseInt("11111", 2),_1_5 = _11111;
-    var _111111 = parseInt("111111", 2),_1_6 = _111111;
-    for (var y = this.height - 1; y >= 0; y--) {
-      var line = this.bottom_up ? y : this.height - 1 - y;
-      for (var x = 0; x < this.width; x++) {
-
-        var B = this.datav.getUint16(this.pos, true); 
-        this.pos+=2;
-        var alpha = 0xFF;
-        var blue = (B & _1_5) / _1_5 * 255 | 0;
-        var green = (B >> 5 & _1_6 ) / _1_6 * 255 | 0;
-        var red = (B >> 11) / _1_5 * 255 | 0;
-
-        var location = line * this.width * 4 + x * 4;
-        this.data[location] = red;
-        this.data[location + 1] = green;
-        this.data[location + 2] = blue;
-        this.data[location + 3] = alpha;
-      }
-      //skip extra bytes
-      this.pos += dif_w;
-    }
-  };
-
-  BmpDecoder.prototype.bit24 = function() {
-    //when height > 0
-    for (var y = this.height - 1; y >= 0; y--) {
-      var line = this.bottom_up ? y : this.height - 1 - y;
-      for (var x = 0; x < this.width; x++) {
-        var blue = this.datav.getUint8(this.pos++, true);      var green = this.datav.getUint8(this.pos++, true);      var red = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x * 4;
-        this.data[location] = red;
-        this.data[location + 1] = green;
-        this.data[location + 2] = blue;
-        this.data[location + 3] = 0xFF;
-      }
-      //skip extra bytes
-      this.pos += (this.width % 4);
-    }
-
-  };
-
-  /**
-   * add 32bit decode func
-   * @author soubok
-   */
-  BmpDecoder.prototype.bit32 = function() {
-    //when height > 0
-    for (var y = this.height - 1; y >= 0; y--) {
-      var line = this.bottom_up ? y : this.height - 1 - y;
-      for (var x = 0; x < this.width; x++) {
-        var blue = this.datav.getUint8(this.pos++, true);      var green = this.datav.getUint8(this.pos++, true);      var red = this.datav.getUint8(this.pos++, true);      var alpha = this.datav.getUint8(this.pos++, true);      var location = line * this.width * 4 + x * 4;
-        this.data[location] = red;
-        this.data[location + 1] = green;
-        this.data[location + 2] = blue;
-        this.data[location + 3] = alpha;
-      }
-      //skip extra bytes
-      //this.pos += (this.width % 4);
-    }
-
-  };
-
-  BmpDecoder.prototype.getData = function() {
-    return this.data;
-  };
-
-  try { 
-  	module.exports = function(bmpData) {
-  		  var decoder = new BmpDecoder(bmpData);
-  		  return {
-  		    data: decoder.getData(),
-  		    width: decoder.width,
-  		    height: decoder.height
-  		  };
-  		};
-  } catch(e) { }  // CommonJS.
-  
-
-  /*
-   Copyright (c) 2013 Gildas Lormeau. All rights reserved.
-
-   Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions are met:
-
-   1. Redistributions of source code must retain the above copyright notice,
-   this list of conditions and the following disclaimer.
-
-   2. Redistributions in binary form must reproduce the above copyright 
-   notice, this list of conditions and the following disclaimer in 
-   the documentation and/or other materials provided with the distribution.
-
-   3. The names of the authors may not be used to endorse or promote products
-   derived from this software without specific prior written permission.
-
-   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
-   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-   FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
-   INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
-   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
-   OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-   EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-   */
-
-  /*
-   * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc.
-   * JZlib is based on zlib-1.1.3, so all credit should go authors
-   * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
-   * and contributors of zlib.
-   */
-
-  (function(global) {
-
-  	// Global
-
-  	var MAX_BITS = 15;
-  	var D_CODES = 30;
-  	var BL_CODES = 19;
-
-  	var LENGTH_CODES = 29;
-  	var LITERALS = 256;
-  	var L_CODES = (LITERALS + 1 + LENGTH_CODES);
-  	var HEAP_SIZE = (2 * L_CODES + 1);
-
-  	var END_BLOCK = 256;
-
-  	// Bit length codes must not exceed MAX_BL_BITS bits
-  	var MAX_BL_BITS = 7;
-
-  	// repeat previous bit length 3-6 times (2 bits of repeat count)
-  	var REP_3_6 = 16;
-
-  	// repeat a zero length 3-10 times (3 bits of repeat count)
-  	var REPZ_3_10 = 17;
-
-  	// repeat a zero length 11-138 times (7 bits of repeat count)
-  	var REPZ_11_138 = 18;
-
-  	// The lengths of the bit length codes are sent in order of decreasing
-  	// probability, to avoid transmitting the lengths for unused bit
-  	// length codes.
-
-  	var Buf_size = 8 * 2;
-
-  	// JZlib version : "1.0.2"
-  	var Z_DEFAULT_COMPRESSION = -1;
-
-  	// compression strategy
-  	var Z_FILTERED = 1;
-  	var Z_HUFFMAN_ONLY = 2;
-  	var Z_DEFAULT_STRATEGY = 0;
-
-  	var Z_NO_FLUSH = 0;
-  	var Z_PARTIAL_FLUSH = 1;
-  	var Z_FULL_FLUSH = 3;
-  	var Z_FINISH = 4;
-
-  	var Z_OK = 0;
-  	var Z_STREAM_END = 1;
-  	var Z_NEED_DICT = 2;
-  	var Z_STREAM_ERROR = -2;
-  	var Z_DATA_ERROR = -3;
-  	var Z_BUF_ERROR = -5;
-
-  	// Tree
-
-  	// see definition of array dist_code below
-  	var _dist_code = [ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-  			10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-  			12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-  			13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  			14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-  			14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-  			15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, 18, 18, 19, 19,
-  			20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-  			24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-  			26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-  			27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-  			28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29,
-  			29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-  			29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 ];
-
-  	function Tree() {
-  		var that = this;
-
-  		// dyn_tree; // the dynamic tree
-  		// max_code; // largest code with non zero frequency
-  		// stat_desc; // the corresponding static tree
-
-  		// Compute the optimal bit lengths for a tree and update the total bit
-  		// length
-  		// for the current block.
-  		// IN assertion: the fields freq and dad are set, heap[heap_max] and
-  		// above are the tree nodes sorted by increasing frequency.
-  		// OUT assertions: the field len is set to the optimal bit length, the
-  		// array bl_count contains the frequencies for each bit length.
-  		// The length opt_len is updated; static_len is also updated if stree is
-  		// not null.
-  		function gen_bitlen(s) {
-  			var tree = that.dyn_tree;
-  			var stree = that.stat_desc.static_tree;
-  			var extra = that.stat_desc.extra_bits;
-  			var base = that.stat_desc.extra_base;
-  			var max_length = that.stat_desc.max_length;
-  			var h; // heap index
-  			var n, m; // iterate over the tree elements
-  			var bits; // bit length
-  			var xbits; // extra bits
-  			var f; // frequency
-  			var overflow = 0; // number of elements with bit length too large
-
-  			for (bits = 0; bits <= MAX_BITS; bits++)
-  				s.bl_count[bits] = 0;
-
-  			// In a first pass, compute the optimal bit lengths (which may
-  			// overflow in the case of the bit length tree).
-  			tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap
-
-  			for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {
-  				n = s.heap[h];
-  				bits = tree[tree[n * 2 + 1] * 2 + 1] + 1;
-  				if (bits > max_length) {
-  					bits = max_length;
-  					overflow++;
-  				}
-  				tree[n * 2 + 1] = bits;
-  				// We overwrite tree[n*2+1] which is no longer needed
-
-  				if (n > that.max_code)
-  					continue; // not a leaf node
-
-  				s.bl_count[bits]++;
-  				xbits = 0;
-  				if (n >= base)
-  					xbits = extra[n - base];
-  				f = tree[n * 2];
-  				s.opt_len += f * (bits + xbits);
-  				if (stree)
-  					s.static_len += f * (stree[n * 2 + 1] + xbits);
-  			}
-  			if (overflow === 0)
-  				return;
-
-  			// This happens for example on obj2 and pic of the Calgary corpus
-  			// Find the first bit length which could increase:
-  			do {
-  				bits = max_length - 1;
-  				while (s.bl_count[bits] === 0)
-  					bits--;
-  				s.bl_count[bits]--; // move one leaf down the tree
-  				s.bl_count[bits + 1] += 2; // move one overflow item as its brother
-  				s.bl_count[max_length]--;
-  				// The brother of the overflow item also moves one step up,
-  				// but this does not affect bl_count[max_length]
-  				overflow -= 2;
-  			} while (overflow > 0);
-
-  			for (bits = max_length; bits !== 0; bits--) {
-  				n = s.bl_count[bits];
-  				while (n !== 0) {
-  					m = s.heap[--h];
-  					if (m > that.max_code)
-  						continue;
-  					if (tree[m * 2 + 1] != bits) {
-  						s.opt_len += (bits - tree[m * 2 + 1]) * tree[m * 2];
-  						tree[m * 2 + 1] = bits;
-  					}
-  					n--;
-  				}
-  			}
-  		}
-
-  		// Reverse the first len bits of a code, using straightforward code (a
-  		// faster
-  		// method would use a table)
-  		// IN assertion: 1 <= len <= 15
-  		function bi_reverse(code, // the value to invert
-  		len // its bit length
-  		) {
-  			var res = 0;
-  			do {
-  				res |= code & 1;
-  				code >>>= 1;
-  				res <<= 1;
-  			} while (--len > 0);
-  			return res >>> 1;
-  		}
-
-  		// Generate the codes for a given tree and bit counts (which need not be
-  		// optimal).
-  		// IN assertion: the array bl_count contains the bit length statistics for
-  		// the given tree and the field len is set for all tree elements.
-  		// OUT assertion: the field code is set for all tree elements of non
-  		// zero code length.
-  		function gen_codes(tree, // the tree to decorate
-  		max_code, // largest code with non zero frequency
-  		bl_count // number of codes at each bit length
-  		) {
-  			var next_code = []; // next code value for each
-  			// bit length
-  			var code = 0; // running code value
-  			var bits; // bit index
-  			var n; // code index
-  			var len;
-
-  			// The distribution counts are first used to generate the code values
-  			// without bit reversal.
-  			for (bits = 1; bits <= MAX_BITS; bits++) {
-  				next_code[bits] = code = ((code + bl_count[bits - 1]) << 1);
-  			}
-
-  			// Check that the bit counts in bl_count are consistent. The last code
-  			// must be all ones.
-  			// Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
-  			// "inconsistent bit counts");
-  			// Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
-  			for (n = 0; n <= max_code; n++) {
-  				len = tree[n * 2 + 1];
-  				if (len === 0)
-  					continue;
-  				// Now reverse the bits
-  				tree[n * 2] = bi_reverse(next_code[len]++, len);
-  			}
-  		}
-
-  		// Construct one Huffman tree and assigns the code bit strings and lengths.
-  		// Update the total bit length for the current block.
-  		// IN assertion: the field freq is set for all tree elements.
-  		// OUT assertions: the fields len and code are set to the optimal bit length
-  		// and corresponding code. The length opt_len is updated; static_len is
-  		// also updated if stree is not null. The field max_code is set.
-  		that.build_tree = function(s) {
-  			var tree = that.dyn_tree;
-  			var stree = that.stat_desc.static_tree;
-  			var elems = that.stat_desc.elems;
-  			var n, m; // iterate over heap elements
-  			var max_code = -1; // largest code with non zero frequency
-  			var node; // new node being created
-
-  			// Construct the initial heap, with least frequent element in
-  			// heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
-  			// heap[0] is not used.
-  			s.heap_len = 0;
-  			s.heap_max = HEAP_SIZE;
-
-  			for (n = 0; n < elems; n++) {
-  				if (tree[n * 2] !== 0) {
-  					s.heap[++s.heap_len] = max_code = n;
-  					s.depth[n] = 0;
-  				} else {
-  					tree[n * 2 + 1] = 0;
-  				}
-  			}
-
-  			// The pkzip format requires that at least one distance code exists,
-  			// and that at least one bit should be sent even if there is only one
-  			// possible code. So to avoid special checks later on we force at least
-  			// two codes of non zero frequency.
-  			while (s.heap_len < 2) {
-  				node = s.heap[++s.heap_len] = max_code < 2 ? ++max_code : 0;
-  				tree[node * 2] = 1;
-  				s.depth[node] = 0;
-  				s.opt_len--;
-  				if (stree)
-  					s.static_len -= stree[node * 2 + 1];
-  				// node is 0 or 1 so it does not have extra bits
-  			}
-  			that.max_code = max_code;
-
-  			// The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
-  			// establish sub-heaps of increasing lengths:
-
-  			for (n = Math.floor(s.heap_len / 2); n >= 1; n--)
-  				s.pqdownheap(tree, n);
-
-  			// Construct the Huffman tree by repeatedly combining the least two
-  			// frequent nodes.
-
-  			node = elems; // next internal node of the tree
-  			do {
-  				// n = node of least frequency
-  				n = s.heap[1];
-  				s.heap[1] = s.heap[s.heap_len--];
-  				s.pqdownheap(tree, 1);
-  				m = s.heap[1]; // m = node of next least frequency
-
-  				s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency
-  				s.heap[--s.heap_max] = m;
-
-  				// Create a new node father of n and m
-  				tree[node * 2] = (tree[n * 2] + tree[m * 2]);
-  				s.depth[node] = Math.max(s.depth[n], s.depth[m]) + 1;
-  				tree[n * 2 + 1] = tree[m * 2 + 1] = node;
-
-  				// and insert the new node in the heap
-  				s.heap[1] = node++;
-  				s.pqdownheap(tree, 1);
-  			} while (s.heap_len >= 2);
-
-  			s.heap[--s.heap_max] = s.heap[1];
-
-  			// At this point, the fields freq and dad are set. We can now
-  			// generate the bit lengths.
-
-  			gen_bitlen(s);
-
-  			// The field len is now set, we can generate the bit codes
-  			gen_codes(tree, that.max_code, s.bl_count);
-  		};
-
-  	}
-
-  	Tree._length_code = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16,
-  			16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-  			20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
-  			22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-  			24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-  			25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-  			26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 ];
-
-  	Tree.base_length = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 ];
-
-  	Tree.base_dist = [ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384,
-  			24576 ];
-
-  	// Mapping from a distance to a distance code. dist is the distance - 1 and
-  	// must not have side effects. _dist_code[256] and _dist_code[257] are never
-  	// used.
-  	Tree.d_code = function(dist) {
-  		return ((dist) < 256 ? _dist_code[dist] : _dist_code[256 + ((dist) >>> 7)]);
-  	};
-
-  	// extra bits for each length code
-  	Tree.extra_lbits = [ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 ];
-
-  	// extra bits for each distance code
-  	Tree.extra_dbits = [ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 ];
-
-  	// extra bits for each bit length code
-  	Tree.extra_blbits = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 ];
-
-  	Tree.bl_order = [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
-
-  	// StaticTree
-
-  	function StaticTree(static_tree, extra_bits, extra_base, elems, max_length) {
-  		var that = this;
-  		that.static_tree = static_tree;
-  		that.extra_bits = extra_bits;
-  		that.extra_base = extra_base;
-  		that.elems = elems;
-  		that.max_length = max_length;
-  	}
-
-  	StaticTree.static_ltree = [ 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, 2, 8,
-  			130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, 202, 8, 42,
-  			8, 170, 8, 106, 8, 234, 8, 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8,
-  			22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, 30, 8, 158, 8, 94, 8,
-  			222, 8, 62, 8, 190, 8, 126, 8, 254, 8, 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113,
-  			8, 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, 5, 8, 133, 8,
-  			69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, 77, 8, 205, 8, 45, 8,
-  			173, 8, 109, 8, 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9,
-  			51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, 171, 9,
-  			427, 9, 107, 9, 363, 9, 235, 9, 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379,
-  			9, 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, 23,
-  			9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, 271, 9, 143, 9,
-  			399, 9, 79, 9, 335, 9, 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9,
-  			223, 9, 479, 9, 63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, 72, 7,
-  			40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8,
-  			99, 8, 227, 8 ];
-
-  	StaticTree.static_dtree = [ 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, 1, 5, 17, 5, 9, 5,
-  			25, 5, 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 ];
-
-  	StaticTree.static_l_desc = new StaticTree(StaticTree.static_ltree, Tree.extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
-
-  	StaticTree.static_d_desc = new StaticTree(StaticTree.static_dtree, Tree.extra_dbits, 0, D_CODES, MAX_BITS);
-
-  	StaticTree.static_bl_desc = new StaticTree(null, Tree.extra_blbits, 0, BL_CODES, MAX_BL_BITS);
-
-  	// Deflate
-
-  	var MAX_MEM_LEVEL = 9;
-  	var DEF_MEM_LEVEL = 8;
-
-  	function Config(good_length, max_lazy, nice_length, max_chain, func) {
-  		var that = this;
-  		that.good_length = good_length;
-  		that.max_lazy = max_lazy;
-  		that.nice_length = nice_length;
-  		that.max_chain = max_chain;
-  		that.func = func;
-  	}
-
-  	var STORED = 0;
-  	var FAST = 1;
-  	var SLOW = 2;
-  	var config_table = [ new Config(0, 0, 0, 0, STORED), new Config(4, 4, 8, 4, FAST), new Config(4, 5, 16, 8, FAST), new Config(4, 6, 32, 32, FAST),
-  			new Config(4, 4, 16, 16, SLOW), new Config(8, 16, 32, 32, SLOW), new Config(8, 16, 128, 128, SLOW), new Config(8, 32, 128, 256, SLOW),
-  			new Config(32, 128, 258, 1024, SLOW), new Config(32, 258, 258, 4096, SLOW) ];
-
-  	var z_errmsg = [ "need dictionary", // Z_NEED_DICT
-  	// 2
-  	"stream end", // Z_STREAM_END 1
-  	"", // Z_OK 0
-  	"", // Z_ERRNO (-1)
-  	"stream error", // Z_STREAM_ERROR (-2)
-  	"data error", // Z_DATA_ERROR (-3)
-  	"", // Z_MEM_ERROR (-4)
-  	"buffer error", // Z_BUF_ERROR (-5)
-  	"",// Z_VERSION_ERROR (-6)
-  	"" ];
-
-  	// block not completed, need more input or more output
-  	var NeedMore = 0;
-
-  	// block flush performed
-  	var BlockDone = 1;
-
-  	// finish started, need only more output at next deflate
-  	var FinishStarted = 2;
-
-  	// finish done, accept no more input or output
-  	var FinishDone = 3;
-
-  	// preset dictionary flag in zlib header
-  	var PRESET_DICT = 0x20;
-
-  	var INIT_STATE = 42;
-  	var BUSY_STATE = 113;
-  	var FINISH_STATE = 666;
-
-  	// The deflate compression method
-  	var Z_DEFLATED = 8;
-
-  	var STORED_BLOCK = 0;
-  	var STATIC_TREES = 1;
-  	var DYN_TREES = 2;
-
-  	var MIN_MATCH = 3;
-  	var MAX_MATCH = 258;
-  	var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
-
-  	function smaller(tree, n, m, depth) {
-  		var tn2 = tree[n * 2];
-  		var tm2 = tree[m * 2];
-  		return (tn2 < tm2 || (tn2 == tm2 && depth[n] <= depth[m]));
-  	}
-
-  	function Deflate() {
-
-  		var that = this;
-  		var strm; // pointer back to this zlib stream
-  		var status; // as the name implies
-  		// pending_buf; // output still pending
-  		var pending_buf_size; // size of pending_buf
-  		var last_flush; // value of flush param for previous deflate call
-
-  		var w_size; // LZ77 window size (32K by default)
-  		var w_bits; // log2(w_size) (8..16)
-  		var w_mask; // w_size - 1
-
-  		var window;
-  		// Sliding window. Input bytes are read into the second half of the window,
-  		// and move to the first half later to keep a dictionary of at least wSize
-  		// bytes. With this organization, matches are limited to a distance of
-  		// wSize-MAX_MATCH bytes, but this ensures that IO is always
-  		// performed with a length multiple of the block size. Also, it limits
-  		// the window size to 64K, which is quite useful on MSDOS.
-  		// To do: use the user input buffer as sliding window.
-
-  		var window_size;
-  		// Actual size of window: 2*wSize, except when the user input buffer
-  		// is directly used as sliding window.
-
-  		var prev;
-  		// Link to older string with same hash index. To limit the size of this
-  		// array to 64K, this link is maintained only for the last 32K strings.
-  		// An index in this array is thus a window index modulo 32K.
-
-  		var head; // Heads of the hash chains or NIL.
-
-  		var ins_h; // hash index of string to be inserted
-  		var hash_size; // number of elements in hash table
-  		var hash_bits; // log2(hash_size)
-  		var hash_mask; // hash_size-1
-
-  		// Number of bits by which ins_h must be shifted at each input
-  		// step. It must be such that after MIN_MATCH steps, the oldest
-  		// byte no longer takes part in the hash key, that is:
-  		// hash_shift * MIN_MATCH >= hash_bits
-  		var hash_shift;
-
-  		// Window position at the beginning of the current output block. Gets
-  		// negative when the window is moved backwards.
-
-  		var block_start;
-
-  		var match_length; // length of best match
-  		var prev_match; // previous match
-  		var match_available; // set if previous match exists
-  		var strstart; // start of string to insert
-  		var match_start; // start of matching string
-  		var lookahead; // number of valid bytes ahead in window
-
-  		// Length of the best match at previous step. Matches not greater than this
-  		// are discarded. This is used in the lazy match evaluation.
-  		var prev_length;
-
-  		// To speed up deflation, hash chains are never searched beyond this
-  		// length. A higher limit improves compression ratio but degrades the speed.
-  		var max_chain_length;
-
-  		// Attempt to find a better match only when the current match is strictly
-  		// smaller than this value. This mechanism is used only for compression
-  		// levels >= 4.
-  		var max_lazy_match;
-
-  		// Insert new strings in the hash table only if the match length is not
-  		// greater than this length. This saves time but degrades compression.
-  		// max_insert_length is used only for compression levels <= 3.
-
-  		var level; // compression level (1..9)
-  		var strategy; // favor or force Huffman coding
-
-  		// Use a faster search when the previous match is longer than this
-  		var good_match;
-
-  		// Stop searching when current match exceeds this
-  		var nice_match;
-
-  		var dyn_ltree; // literal and length tree
-  		var dyn_dtree; // distance tree
-  		var bl_tree; // Huffman tree for bit lengths
-
-  		var l_desc = new Tree(); // desc for literal tree
-  		var d_desc = new Tree(); // desc for distance tree
-  		var bl_desc = new Tree(); // desc for bit length tree
-
-  		// that.heap_len; // number of elements in the heap
-  		// that.heap_max; // element of largest frequency
-  		// The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
-  		// The same heap array is used to build all trees.
-
-  		// Depth of each subtree used as tie breaker for trees of equal frequency
-  		that.depth = [];
-
-  		var l_buf; // index for literals or lengths */
-
-  		// Size of match buffer for literals/lengths. There are 4 reasons for
-  		// limiting lit_bufsize to 64K:
-  		// - frequencies can be kept in 16 bit counters
-  		// - if compression is not successful for the first block, all input
-  		// data is still in the window so we can still emit a stored block even
-  		// when input comes from standard input. (This can also be done for
-  		// all blocks if lit_bufsize is not greater than 32K.)
-  		// - if compression is not successful for a file smaller than 64K, we can
-  		// even emit a stored file instead of a stored block (saving 5 bytes).
-  		// This is applicable only for zip (not gzip or zlib).
-  		// - creating new Huffman trees less frequently may not provide fast
-  		// adaptation to changes in the input data statistics. (Take for
-  		// example a binary file with poorly compressible code followed by
-  		// a highly compressible string table.) Smaller buffer sizes give
-  		// fast adaptation but have of course the overhead of transmitting
-  		// trees more frequently.
-  		// - I can't count above 4
-  		var lit_bufsize;
-
-  		var last_lit; // running index in l_buf
-
-  		// Buffer for distances. To simplify the code, d_buf and l_buf have
-  		// the same number of elements. To use different lengths, an extra flag
-  		// array would be necessary.
-
-  		var d_buf; // index of pendig_buf
-
-  		// that.opt_len; // bit length of current block with optimal trees
-  		// that.static_len; // bit length of current block with static trees
-  		var matches; // number of string matches in current block
-  		var last_eob_len; // bit length of EOB code for last block
-
-  		// Output buffer. bits are inserted starting at the bottom (least
-  		// significant bits).
-  		var bi_buf;
-
-  		// Number of valid bits in bi_buf. All bits above the last valid bit
-  		// are always zero.
-  		var bi_valid;
-
-  		// number of codes at each bit length for an optimal tree
-  		that.bl_count = [];
-
-  		// heap used to build the Huffman trees
-  		that.heap = [];
-
-  		dyn_ltree = [];
-  		dyn_dtree = [];
-  		bl_tree = [];
-
-  		function lm_init() {
-  			var i;
-  			window_size = 2 * w_size;
-
-  			head[hash_size - 1] = 0;
-  			for (i = 0; i < hash_size - 1; i++) {
-  				head[i] = 0;
-  			}
-
-  			// Set the default configuration parameters:
-  			max_lazy_match = config_table[level].max_lazy;
-  			good_match = config_table[level].good_length;
-  			nice_match = config_table[level].nice_length;
-  			max_chain_length = config_table[level].max_chain;
-
-  			strstart = 0;
-  			block_start = 0;
-  			lookahead = 0;
-  			match_length = prev_length = MIN_MATCH - 1;
-  			match_available = 0;
-  			ins_h = 0;
-  		}
-
-  		function init_block() {
-  			var i;
-  			// Initialize the trees.
-  			for (i = 0; i < L_CODES; i++)
-  				dyn_ltree[i * 2] = 0;
-  			for (i = 0; i < D_CODES; i++)
-  				dyn_dtree[i * 2] = 0;
-  			for (i = 0; i < BL_CODES; i++)
-  				bl_tree[i * 2] = 0;
-
-  			dyn_ltree[END_BLOCK * 2] = 1;
-  			that.opt_len = that.static_len = 0;
-  			last_lit = matches = 0;
-  		}
-
-  		// Initialize the tree data structures for a new zlib stream.
-  		function tr_init() {
-
-  			l_desc.dyn_tree = dyn_ltree;
-  			l_desc.stat_desc = StaticTree.static_l_desc;
-
-  			d_desc.dyn_tree = dyn_dtree;
-  			d_desc.stat_desc = StaticTree.static_d_desc;
-
-  			bl_desc.dyn_tree = bl_tree;
-  			bl_desc.stat_desc = StaticTree.static_bl_desc;
-
-  			bi_buf = 0;
-  			bi_valid = 0;
-  			last_eob_len = 8; // enough lookahead for inflate
-
-  			// Initialize the first block of the first file:
-  			init_block();
-  		}
-
-  		// Restore the heap property by moving down the tree starting at node k,
-  		// exchanging a node with the smallest of its two sons if necessary,
-  		// stopping
-  		// when the heap property is re-established (each father smaller than its
-  		// two sons).
-  		that.pqdownheap = function(tree, // the tree to restore
-  		k // node to move down
-  		) {
-  			var heap = that.heap;
-  			var v = heap[k];
-  			var j = k << 1; // left son of k
-  			while (j <= that.heap_len) {
-  				// Set j to the smallest of the two sons:
-  				if (j < that.heap_len && smaller(tree, heap[j + 1], heap[j], that.depth)) {
-  					j++;
-  				}
-  				// Exit if v is smaller than both sons
-  				if (smaller(tree, v, heap[j], that.depth))
-  					break;
-
-  				// Exchange v with the smallest son
-  				heap[k] = heap[j];
-  				k = j;
-  				// And continue down the tree, setting j to the left son of k
-  				j <<= 1;
-  			}
-  			heap[k] = v;
-  		};
-
-  		// Scan a literal or distance tree to determine the frequencies of the codes
-  		// in the bit length tree.
-  		function scan_tree(tree,// the tree to be scanned
-  		max_code // and its largest code of non zero frequency
-  		) {
-  			var n; // iterates over all tree elements
-  			var prevlen = -1; // last emitted length
-  			var curlen; // length of current code
-  			var nextlen = tree[0 * 2 + 1]; // length of next code
-  			var count = 0; // repeat count of the current code
-  			var max_count = 7; // max repeat count
-  			var min_count = 4; // min repeat count
-
-  			if (nextlen === 0) {
-  				max_count = 138;
-  				min_count = 3;
-  			}
-  			tree[(max_code + 1) * 2 + 1] = 0xffff; // guard
-
-  			for (n = 0; n <= max_code; n++) {
-  				curlen = nextlen;
-  				nextlen = tree[(n + 1) * 2 + 1];
-  				if (++count < max_count && curlen == nextlen) {
-  					continue;
-  				} else if (count < min_count) {
-  					bl_tree[curlen * 2] += count;
-  				} else if (curlen !== 0) {
-  					if (curlen != prevlen)
-  						bl_tree[curlen * 2]++;
-  					bl_tree[REP_3_6 * 2]++;
-  				} else if (count <= 10) {
-  					bl_tree[REPZ_3_10 * 2]++;
-  				} else {
-  					bl_tree[REPZ_11_138 * 2]++;
-  				}
-  				count = 0;
-  				prevlen = curlen;
-  				if (nextlen === 0) {
-  					max_count = 138;
-  					min_count = 3;
-  				} else if (curlen == nextlen) {
-  					max_count = 6;
-  					min_count = 3;
-  				} else {
-  					max_count = 7;
-  					min_count = 4;
-  				}
-  			}
-  		}
-
-  		// Construct the Huffman tree for the bit lengths and return the index in
-  		// bl_order of the last bit length code to send.
-  		function build_bl_tree() {
-  			var max_blindex; // index of last bit length code of non zero freq
-
-  			// Determine the bit length frequencies for literal and distance trees
-  			scan_tree(dyn_ltree, l_desc.max_code);
-  			scan_tree(dyn_dtree, d_desc.max_code);
-
-  			// Build the bit length tree:
-  			bl_desc.build_tree(that);
-  			// opt_len now includes the length of the tree representations, except
-  			// the lengths of the bit lengths codes and the 5+5+4 bits for the
-  			// counts.
-
-  			// Determine the number of bit length codes to send. The pkzip format
-  			// requires that at least 4 bit length codes be sent. (appnote.txt says
-  			// 3 but the actual value used is 4.)
-  			for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
-  				if (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] !== 0)
-  					break;
-  			}
-  			// Update opt_len to include the bit length tree and counts
-  			that.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
-
-  			return max_blindex;
-  		}
-
-  		// Output a byte on the stream.
-  		// IN assertion: there is enough room in pending_buf.
-  		function put_byte(p) {
-  			that.pending_buf[that.pending++] = p;
-  		}
-
-  		function put_short(w) {
-  			put_byte(w & 0xff);
-  			put_byte((w >>> 8) & 0xff);
-  		}
-
-  		function putShortMSB(b) {
-  			put_byte((b >> 8) & 0xff);
-  			put_byte((b & 0xff) & 0xff);
-  		}
-
-  		function send_bits(value, length) {
-  			var val, len = length;
-  			if (bi_valid > Buf_size - len) {
-  				val = value;
-  				// bi_buf |= (val << bi_valid);
-  				bi_buf |= ((val << bi_valid) & 0xffff);
-  				put_short(bi_buf);
-  				bi_buf = val >>> (Buf_size - bi_valid);
-  				bi_valid += len - Buf_size;
-  			} else {
-  				// bi_buf |= (value) << bi_valid;
-  				bi_buf |= (((value) << bi_valid) & 0xffff);
-  				bi_valid += len;
-  			}
-  		}
-
-  		function send_code(c, tree) {
-  			var c2 = c * 2;
-  			send_bits(tree[c2] & 0xffff, tree[c2 + 1] & 0xffff);
-  		}
-
-  		// Send a literal or distance tree in compressed form, using the codes in
-  		// bl_tree.
-  		function send_tree(tree,// the tree to be sent
-  		max_code // and its largest code of non zero frequency
-  		) {
-  			var n; // iterates over all tree elements
-  			var prevlen = -1; // last emitted length
-  			var curlen; // length of current code
-  			var nextlen = tree[0 * 2 + 1]; // length of next code
-  			var count = 0; // repeat count of the current code
-  			var max_count = 7; // max repeat count
-  			var min_count = 4; // min repeat count
-
-  			if (nextlen === 0) {
-  				max_count = 138;
-  				min_count = 3;
-  			}
-
-  			for (n = 0; n <= max_code; n++) {
-  				curlen = nextlen;
-  				nextlen = tree[(n + 1) * 2 + 1];
-  				if (++count < max_count && curlen == nextlen) {
-  					continue;
-  				} else if (count < min_count) {
-  					do {
-  						send_code(curlen, bl_tree);
-  					} while (--count !== 0);
-  				} else if (curlen !== 0) {
-  					if (curlen != prevlen) {
-  						send_code(curlen, bl_tree);
-  						count--;
-  					}
-  					send_code(REP_3_6, bl_tree);
-  					send_bits(count - 3, 2);
-  				} else if (count <= 10) {
-  					send_code(REPZ_3_10, bl_tree);
-  					send_bits(count - 3, 3);
-  				} else {
-  					send_code(REPZ_11_138, bl_tree);
-  					send_bits(count - 11, 7);
-  				}
-  				count = 0;
-  				prevlen = curlen;
-  				if (nextlen === 0) {
-  					max_count = 138;
-  					min_count = 3;
-  				} else if (curlen == nextlen) {
-  					max_count = 6;
-  					min_count = 3;
-  				} else {
-  					max_count = 7;
-  					min_count = 4;
-  				}
-  			}
-  		}
-
-  		// Send the header for a block using dynamic Huffman trees: the counts, the
-  		// lengths of the bit length codes, the literal tree and the distance tree.
-  		// IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
-  		function send_all_trees(lcodes, dcodes, blcodes) {
-  			var rank; // index in bl_order
-
-  			send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt
-  			send_bits(dcodes - 1, 5);
-  			send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt
-  			for (rank = 0; rank < blcodes; rank++) {
-  				send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3);
-  			}
-  			send_tree(dyn_ltree, lcodes - 1); // literal tree
-  			send_tree(dyn_dtree, dcodes - 1); // distance tree
-  		}
-
-  		// Flush the bit buffer, keeping at most 7 bits in it.
-  		function bi_flush() {
-  			if (bi_valid == 16) {
-  				put_short(bi_buf);
-  				bi_buf = 0;
-  				bi_valid = 0;
-  			} else if (bi_valid >= 8) {
-  				put_byte(bi_buf & 0xff);
-  				bi_buf >>>= 8;
-  				bi_valid -= 8;
-  			}
-  		}
-
-  		// Send one empty static block to give enough lookahead for inflate.
-  		// This takes 10 bits, of which 7 may remain in the bit buffer.
-  		// The current inflate code requires 9 bits of lookahead. If the
-  		// last two codes for the previous block (real code plus EOB) were coded
-  		// on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
-  		// the last real code. In this case we send two empty static blocks instead
-  		// of one. (There are no problems if the previous block is stored or fixed.)
-  		// To simplify the code, we assume the worst case of last real code encoded
-  		// on one bit only.
-  		function _tr_align() {
-  			send_bits(STATIC_TREES << 1, 3);
-  			send_code(END_BLOCK, StaticTree.static_ltree);
-
-  			bi_flush();
-
-  			// Of the 10 bits for the empty block, we have already sent
-  			// (10 - bi_valid) bits. The lookahead for the last real code (before
-  			// the EOB of the previous block) was thus at least one plus the length
-  			// of the EOB plus what we have just sent of the empty static block.
-  			if (1 + last_eob_len + 10 - bi_valid < 9) {
-  				send_bits(STATIC_TREES << 1, 3);
-  				send_code(END_BLOCK, StaticTree.static_ltree);
-  				bi_flush();
-  			}
-  			last_eob_len = 7;
-  		}
-
-  		// Save the match info and tally the frequency counts. Return true if
-  		// the current block must be flushed.
-  		function _tr_tally(dist, // distance of matched string
-  		lc // match length-MIN_MATCH or unmatched char (if dist==0)
-  		) {
-  			var out_length, in_length, dcode;
-  			that.pending_buf[d_buf + last_lit * 2] = (dist >>> 8) & 0xff;
-  			that.pending_buf[d_buf + last_lit * 2 + 1] = dist & 0xff;
-
-  			that.pending_buf[l_buf + last_lit] = lc & 0xff;
-  			last_lit++;
-
-  			if (dist === 0) {
-  				// lc is the unmatched char
-  				dyn_ltree[lc * 2]++;
-  			} else {
-  				matches++;
-  				// Here, lc is the match length - MIN_MATCH
-  				dist--; // dist = match distance - 1
-  				dyn_ltree[(Tree._length_code[lc] + LITERALS + 1) * 2]++;
-  				dyn_dtree[Tree.d_code(dist) * 2]++;
-  			}
-
-  			if ((last_lit & 0x1fff) === 0 && level > 2) {
-  				// Compute an upper bound for the compressed length
-  				out_length = last_lit * 8;
-  				in_length = strstart - block_start;
-  				for (dcode = 0; dcode < D_CODES; dcode++) {
-  					out_length += dyn_dtree[dcode * 2] * (5 + Tree.extra_dbits[dcode]);
-  				}
-  				out_length >>>= 3;
-  				if ((matches < Math.floor(last_lit / 2)) && out_length < Math.floor(in_length / 2))
-  					return true;
-  			}
-
-  			return (last_lit == lit_bufsize - 1);
-  			// We avoid equality with lit_bufsize because of wraparound at 64K
-  			// on 16 bit machines and because stored blocks are restricted to
-  			// 64K-1 bytes.
-  		}
-
-  		// Send the block data compressed using the given Huffman trees
-  		function compress_block(ltree, dtree) {
-  			var dist; // distance of matched string
-  			var lc; // match length or unmatched char (if dist === 0)
-  			var lx = 0; // running index in l_buf
-  			var code; // the code to send
-  			var extra; // number of extra bits to send
-
-  			if (last_lit !== 0) {
-  				do {
-  					dist = ((that.pending_buf[d_buf + lx * 2] << 8) & 0xff00) | (that.pending_buf[d_buf + lx * 2 + 1] & 0xff);
-  					lc = (that.pending_buf[l_buf + lx]) & 0xff;
-  					lx++;
-
-  					if (dist === 0) {
-  						send_code(lc, ltree); // send a literal byte
-  					} else {
-  						// Here, lc is the match length - MIN_MATCH
-  						code = Tree._length_code[lc];
-
-  						send_code(code + LITERALS + 1, ltree); // send the length
-  						// code
-  						extra = Tree.extra_lbits[code];
-  						if (extra !== 0) {
-  							lc -= Tree.base_length[code];
-  							send_bits(lc, extra); // send the extra length bits
-  						}
-  						dist--; // dist is now the match distance - 1
-  						code = Tree.d_code(dist);
-
-  						send_code(code, dtree); // send the distance code
-  						extra = Tree.extra_dbits[code];
-  						if (extra !== 0) {
-  							dist -= Tree.base_dist[code];
-  							send_bits(dist, extra); // send the extra distance bits
-  						}
-  					} // literal or match pair ?
-
-  					// Check that the overlay between pending_buf and d_buf+l_buf is
-  					// ok:
-  				} while (lx < last_lit);
-  			}
-
-  			send_code(END_BLOCK, ltree);
-  			last_eob_len = ltree[END_BLOCK * 2 + 1];
-  		}
-
-  		// Flush the bit buffer and align the output on a byte boundary
-  		function bi_windup() {
-  			if (bi_valid > 8) {
-  				put_short(bi_buf);
-  			} else if (bi_valid > 0) {
-  				put_byte(bi_buf & 0xff);
-  			}
-  			bi_buf = 0;
-  			bi_valid = 0;
-  		}
-
-  		// Copy a stored block, storing first the length and its
-  		// one's complement if requested.
-  		function copy_block(buf, // the input data
-  		len, // its length
-  		header // true if block header must be written
-  		) {
-  			bi_windup(); // align on byte boundary
-  			last_eob_len = 8; // enough lookahead for inflate
-
-  			if (header) {
-  				put_short(len);
-  				put_short(~len);
-  			}
-
-  			that.pending_buf.set(window.subarray(buf, buf + len), that.pending);
-  			that.pending += len;
-  		}
-
-  		// Send a stored block
-  		function _tr_stored_block(buf, // input block
-  		stored_len, // length of input block
-  		eof // true if this is the last block for a file
-  		) {
-  			send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type
-  			copy_block(buf, stored_len, true); // with header
-  		}
-
-  		// Determine the best encoding for the current block: dynamic trees, static
-  		// trees or store, and output the encoded block to the zip file.
-  		function _tr_flush_block(buf, // input block, or NULL if too old
-  		stored_len, // length of input block
-  		eof // true if this is the last block for a file
-  		) {
-  			var opt_lenb, static_lenb;// opt_len and static_len in bytes
-  			var max_blindex = 0; // index of last bit length code of non zero freq
-
-  			// Build the Huffman trees unless a stored block is forced
-  			if (level > 0) {
-  				// Construct the literal and distance trees
-  				l_desc.build_tree(that);
-
-  				d_desc.build_tree(that);
-
-  				// At this point, opt_len and static_len are the total bit lengths
-  				// of
-  				// the compressed block data, excluding the tree representations.
-
-  				// Build the bit length tree for the above two trees, and get the
-  				// index
-  				// in bl_order of the last bit length code to send.
-  				max_blindex = build_bl_tree();
-
-  				// Determine the best encoding. Compute first the block length in
-  				// bytes
-  				opt_lenb = (that.opt_len + 3 + 7) >>> 3;
-  				static_lenb = (that.static_len + 3 + 7) >>> 3;
-
-  				if (static_lenb <= opt_lenb)
-  					opt_lenb = static_lenb;
-  			} else {
-  				opt_lenb = static_lenb = stored_len + 5; // force a stored block
-  			}
-
-  			if ((stored_len + 4 <= opt_lenb) && buf != -1) {
-  				// 4: two words for the lengths
-  				// The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
-  				// Otherwise we can't have processed more than WSIZE input bytes
-  				// since
-  				// the last block flush, because compression would have been
-  				// successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
-  				// transform a block into a stored block.
-  				_tr_stored_block(buf, stored_len, eof);
-  			} else if (static_lenb == opt_lenb) {
-  				send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3);
-  				compress_block(StaticTree.static_ltree, StaticTree.static_dtree);
-  			} else {
-  				send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3);
-  				send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, max_blindex + 1);
-  				compress_block(dyn_ltree, dyn_dtree);
-  			}
-
-  			// The above check is made mod 2^32, for files larger than 512 MB
-  			// and uLong implemented on 32 bits.
-
-  			init_block();
-
-  			if (eof) {
-  				bi_windup();
-  			}
-  		}
-
-  		function flush_block_only(eof) {
-  			_tr_flush_block(block_start >= 0 ? block_start : -1, strstart - block_start, eof);
-  			block_start = strstart;
-  			strm.flush_pending();
-  		}
-
-  		// Fill the window when the lookahead becomes insufficient.
-  		// Updates strstart and lookahead.
-  		//
-  		// IN assertion: lookahead < MIN_LOOKAHEAD
-  		// OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
-  		// At least one byte has been read, or avail_in === 0; reads are
-  		// performed for at least two bytes (required for the zip translate_eol
-  		// option -- not supported here).
-  		function fill_window() {
-  			var n, m;
-  			var p;
-  			var more; // Amount of free space at the end of the window.
-
-  			do {
-  				more = (window_size - lookahead - strstart);
-
-  				// Deal with !@#$% 64K limit:
-  				if (more === 0 && strstart === 0 && lookahead === 0) {
-  					more = w_size;
-  				} else if (more == -1) {
-  					// Very unlikely, but possible on 16 bit machine if strstart ==
-  					// 0
-  					// and lookahead == 1 (input done one byte at time)
-  					more--;
-
-  					// If the window is almost full and there is insufficient
-  					// lookahead,
-  					// move the upper half to the lower one to make room in the
-  					// upper half.
-  				} else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) {
-  					window.set(window.subarray(w_size, w_size + w_size), 0);
-
-  					match_start -= w_size;
-  					strstart -= w_size; // we now have strstart >= MAX_DIST
-  					block_start -= w_size;
-
-  					// Slide the hash table (could be avoided with 32 bit values
-  					// at the expense of memory usage). We slide even when level ==
-  					// 0
-  					// to keep the hash table consistent if we switch back to level
-  					// > 0
-  					// later. (Using level 0 permanently is not an optimal usage of
-  					// zlib, so we don't care about this pathological case.)
-
-  					n = hash_size;
-  					p = n;
-  					do {
-  						m = (head[--p] & 0xffff);
-  						head[p] = (m >= w_size ? m - w_size : 0);
-  					} while (--n !== 0);
-
-  					n = w_size;
-  					p = n;
-  					do {
-  						m = (prev[--p] & 0xffff);
-  						prev[p] = (m >= w_size ? m - w_size : 0);
-  						// If n is not on any hash chain, prev[n] is garbage but
-  						// its value will never be used.
-  					} while (--n !== 0);
-  					more += w_size;
-  				}
-
-  				if (strm.avail_in === 0)
-  					return;
-
-  				// If there was no sliding:
-  				// strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
-  				// more == window_size - lookahead - strstart
-  				// => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
-  				// => more >= window_size - 2*WSIZE + 2
-  				// In the BIG_MEM or MMAP case (not yet supported),
-  				// window_size == input_size + MIN_LOOKAHEAD &&
-  				// strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
-  				// Otherwise, window_size == 2*WSIZE so more >= 2.
-  				// If there was sliding, more >= WSIZE. So in all cases, more >= 2.
-
-  				n = strm.read_buf(window, strstart + lookahead, more);
-  				lookahead += n;
-
-  				// Initialize the hash value now that we have some input:
-  				if (lookahead >= MIN_MATCH) {
-  					ins_h = window[strstart] & 0xff;
-  					ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
-  				}
-  				// If the whole input has less than MIN_MATCH bytes, ins_h is
-  				// garbage,
-  				// but this is not important since only literal bytes will be
-  				// emitted.
-  			} while (lookahead < MIN_LOOKAHEAD && strm.avail_in !== 0);
-  		}
-
-  		// Copy without compression as much as possible from the input stream,
-  		// return
-  		// the current block state.
-  		// This function does not insert new strings in the dictionary since
-  		// uncompressible data is probably not useful. This function is used
-  		// only for the level=0 compression option.
-  		// NOTE: this function should be optimized to avoid extra copying from
-  		// window to pending_buf.
-  		function deflate_stored(flush) {
-  			// Stored blocks are limited to 0xffff bytes, pending_buf is limited
-  			// to pending_buf_size, and each stored block has a 5 byte header:
-
-  			var max_block_size = 0xffff;
-  			var max_start;
-
-  			if (max_block_size > pending_buf_size - 5) {
-  				max_block_size = pending_buf_size - 5;
-  			}
-
-  			// Copy as much as possible from input to output:
-  			while (true) {
-  				// Fill the window as much as possible:
-  				if (lookahead <= 1) {
-  					fill_window();
-  					if (lookahead === 0 && flush == Z_NO_FLUSH)
-  						return NeedMore;
-  					if (lookahead === 0)
-  						break; // flush the current block
-  				}
-
-  				strstart += lookahead;
-  				lookahead = 0;
-
-  				// Emit a stored block if pending_buf will be full:
-  				max_start = block_start + max_block_size;
-  				if (strstart === 0 || strstart >= max_start) {
-  					// strstart === 0 is possible when wraparound on 16-bit machine
-  					lookahead = (strstart - max_start);
-  					strstart = max_start;
-
-  					flush_block_only(false);
-  					if (strm.avail_out === 0)
-  						return NeedMore;
-
-  				}
-
-  				// Flush if we may have to slide, otherwise block_start may become
-  				// negative and the data will be gone:
-  				if (strstart - block_start >= w_size - MIN_LOOKAHEAD) {
-  					flush_block_only(false);
-  					if (strm.avail_out === 0)
-  						return NeedMore;
-  				}
-  			}
-
-  			flush_block_only(flush == Z_FINISH);
-  			if (strm.avail_out === 0)
-  				return (flush == Z_FINISH) ? FinishStarted : NeedMore;
-
-  			return flush == Z_FINISH ? FinishDone : BlockDone;
-  		}
-
-  		function longest_match(cur_match) {
-  			var chain_length = max_chain_length; // max hash chain length
-  			var scan = strstart; // current string
-  			var match; // matched string
-  			var len; // length of current match
-  			var best_len = prev_length; // best match length so far
-  			var limit = strstart > (w_size - MIN_LOOKAHEAD) ? strstart - (w_size - MIN_LOOKAHEAD) : 0;
-  			var _nice_match = nice_match;
-
-  			// Stop when cur_match becomes <= limit. To simplify the code,
-  			// we prevent matches with the string of window index 0.
-
-  			var wmask = w_mask;
-
-  			var strend = strstart + MAX_MATCH;
-  			var scan_end1 = window[scan + best_len - 1];
-  			var scan_end = window[scan + best_len];
-
-  			// The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of
-  			// 16.
-  			// It is easy to get rid of this optimization if necessary.
-
-  			// Do not waste too much time if we already have a good match:
-  			if (prev_length >= good_match) {
-  				chain_length >>= 2;
-  			}
-
-  			// Do not look for matches beyond the end of the input. This is
-  			// necessary
-  			// to make deflate deterministic.
-  			if (_nice_match > lookahead)
-  				_nice_match = lookahead;
-
-  			do {
-  				match = cur_match;
-
-  				// Skip to next match if the match length cannot increase
-  				// or if the match length is less than 2:
-  				if (window[match + best_len] != scan_end || window[match + best_len - 1] != scan_end1 || window[match] != window[scan]
-  						|| window[++match] != window[scan + 1])
-  					continue;
-
-  				// The check at best_len-1 can be removed because it will be made
-  				// again later. (This heuristic is not always a win.)
-  				// It is not necessary to compare scan[2] and match[2] since they
-  				// are always equal when the other bytes match, given that
-  				// the hash keys are equal and that HASH_BITS >= 8.
-  				scan += 2;
-  				match++;
-
-  				// We check for insufficient lookahead only every 8th comparison;
-  				// the 256th check will be made at strstart+258.
-  				do {
-  				} while (window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match]
-  						&& window[++scan] == window[++match] && window[++scan] == window[++match] && window[++scan] == window[++match]
-  						&& window[++scan] == window[++match] && window[++scan] == window[++match] && scan < strend);
-
-  				len = MAX_MATCH - (strend - scan);
-  				scan = strend - MAX_MATCH;
-
-  				if (len > best_len) {
-  					match_start = cur_match;
-  					best_len = len;
-  					if (len >= _nice_match)
-  						break;
-  					scan_end1 = window[scan + best_len - 1];
-  					scan_end = window[scan + best_len];
-  				}
-
-  			} while ((cur_match = (prev[cur_match & wmask] & 0xffff)) > limit && --chain_length !== 0);
-
-  			if (best_len <= lookahead)
-  				return best_len;
-  			return lookahead;
-  		}
-
-  		// Compress as much as possible from the input stream, return the current
-  		// block state.
-  		// This function does not perform lazy evaluation of matches and inserts
-  		// new strings in the dictionary only for unmatched strings or for short
-  		// matches. It is used only for the fast compression options.
-  		function deflate_fast(flush) {
-  			// short hash_head = 0; // head of the hash chain
-  			var hash_head = 0; // head of the hash chain
-  			var bflush; // set if current block must be flushed
-
-  			while (true) {
-  				// Make sure that we always have enough lookahead, except
-  				// at the end of the input file. We need MAX_MATCH bytes
-  				// for the next match, plus MIN_MATCH bytes to insert the
-  				// string following the next match.
-  				if (lookahead < MIN_LOOKAHEAD) {
-  					fill_window();
-  					if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-  						return NeedMore;
-  					}
-  					if (lookahead === 0)
-  						break; // flush the current block
-  				}
-
-  				// Insert the string window[strstart .. strstart+2] in the
-  				// dictionary, and set hash_head to the head of the hash chain:
-  				if (lookahead >= MIN_MATCH) {
-  					ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-
-  					// prev[strstart&w_mask]=hash_head=head[ins_h];
-  					hash_head = (head[ins_h] & 0xffff);
-  					prev[strstart & w_mask] = head[ins_h];
-  					head[ins_h] = strstart;
-  				}
-
-  				// Find the longest match, discarding those <= prev_length.
-  				// At this point we have always match_length < MIN_MATCH
-
-  				if (hash_head !== 0 && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) {
-  					// To simplify the code, we prevent matches with the string
-  					// of window index 0 (in particular we have to avoid a match
-  					// of the string with itself at the start of the input file).
-  					if (strategy != Z_HUFFMAN_ONLY) {
-  						match_length = longest_match(hash_head);
-  					}
-  					// longest_match() sets match_start
-  				}
-  				if (match_length >= MIN_MATCH) {
-  					// check_match(strstart, match_start, match_length);
-
-  					bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH);
-
-  					lookahead -= match_length;
-
-  					// Insert new strings in the hash table only if the match length
-  					// is not too large. This saves time but degrades compression.
-  					if (match_length <= max_lazy_match && lookahead >= MIN_MATCH) {
-  						match_length--; // string at strstart already in hash table
-  						do {
-  							strstart++;
-
-  							ins_h = ((ins_h << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-  							// prev[strstart&w_mask]=hash_head=head[ins_h];
-  							hash_head = (head[ins_h] & 0xffff);
-  							prev[strstart & w_mask] = head[ins_h];
-  							head[ins_h] = strstart;
-
-  							// strstart never exceeds WSIZE-MAX_MATCH, so there are
-  							// always MIN_MATCH bytes ahead.
-  						} while (--match_length !== 0);
-  						strstart++;
-  					} else {
-  						strstart += match_length;
-  						match_length = 0;
-  						ins_h = window[strstart] & 0xff;
-
-  						ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
-  						// If lookahead < MIN_MATCH, ins_h is garbage, but it does
-  						// not
-  						// matter since it will be recomputed at next deflate call.
-  					}
-  				} else {
-  					// No match, output a literal byte
-
-  					bflush = _tr_tally(0, window[strstart] & 0xff);
-  					lookahead--;
-  					strstart++;
-  				}
-  				if (bflush) {
-
-  					flush_block_only(false);
-  					if (strm.avail_out === 0)
-  						return NeedMore;
-  				}
-  			}
-
-  			flush_block_only(flush == Z_FINISH);
-  			if (strm.avail_out === 0) {
-  				if (flush == Z_FINISH)
-  					return FinishStarted;
-  				else
-  					return NeedMore;
-  			}
-  			return flush == Z_FINISH ? FinishDone : BlockDone;
-  		}
-
-  		// Same as above, but achieves better compression. We use a lazy
-  		// evaluation for matches: a match is finally adopted only if there is
-  		// no better match at the next window position.
-  		function deflate_slow(flush) {
-  			// short hash_head = 0; // head of hash chain
-  			var hash_head = 0; // head of hash chain
-  			var bflush; // set if current block must be flushed
-  			var max_insert;
-
-  			// Process the input block.
-  			while (true) {
-  				// Make sure that we always have enough lookahead, except
-  				// at the end of the input file. We need MAX_MATCH bytes
-  				// for the next match, plus MIN_MATCH bytes to insert the
-  				// string following the next match.
-
-  				if (lookahead < MIN_LOOKAHEAD) {
-  					fill_window();
-  					if (lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-  						return NeedMore;
-  					}
-  					if (lookahead === 0)
-  						break; // flush the current block
-  				}
-
-  				// Insert the string window[strstart .. strstart+2] in the
-  				// dictionary, and set hash_head to the head of the hash chain:
-
-  				if (lookahead >= MIN_MATCH) {
-  					ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-  					// prev[strstart&w_mask]=hash_head=head[ins_h];
-  					hash_head = (head[ins_h] & 0xffff);
-  					prev[strstart & w_mask] = head[ins_h];
-  					head[ins_h] = strstart;
-  				}
-
-  				// Find the longest match, discarding those <= prev_length.
-  				prev_length = match_length;
-  				prev_match = match_start;
-  				match_length = MIN_MATCH - 1;
-
-  				if (hash_head !== 0 && prev_length < max_lazy_match && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD) {
-  					// To simplify the code, we prevent matches with the string
-  					// of window index 0 (in particular we have to avoid a match
-  					// of the string with itself at the start of the input file).
-
-  					if (strategy != Z_HUFFMAN_ONLY) {
-  						match_length = longest_match(hash_head);
-  					}
-  					// longest_match() sets match_start
-
-  					if (match_length <= 5 && (strategy == Z_FILTERED || (match_length == MIN_MATCH && strstart - match_start > 4096))) {
-
-  						// If prev_match is also MIN_MATCH, match_start is garbage
-  						// but we will ignore the current match anyway.
-  						match_length = MIN_MATCH - 1;
-  					}
-  				}
-
-  				// If there was a match at the previous step and the current
-  				// match is not better, output the previous match:
-  				if (prev_length >= MIN_MATCH && match_length <= prev_length) {
-  					max_insert = strstart + lookahead - MIN_MATCH;
-  					// Do not insert strings in hash table beyond this.
-
-  					// check_match(strstart-1, prev_match, prev_length);
-
-  					bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);
-
-  					// Insert in hash table all strings up to the end of the match.
-  					// strstart-1 and strstart are already inserted. If there is not
-  					// enough lookahead, the last two strings are not inserted in
-  					// the hash table.
-  					lookahead -= prev_length - 1;
-  					prev_length -= 2;
-  					do {
-  						if (++strstart <= max_insert) {
-  							ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-  							// prev[strstart&w_mask]=hash_head=head[ins_h];
-  							hash_head = (head[ins_h] & 0xffff);
-  							prev[strstart & w_mask] = head[ins_h];
-  							head[ins_h] = strstart;
-  						}
-  					} while (--prev_length !== 0);
-  					match_available = 0;
-  					match_length = MIN_MATCH - 1;
-  					strstart++;
-
-  					if (bflush) {
-  						flush_block_only(false);
-  						if (strm.avail_out === 0)
-  							return NeedMore;
-  					}
-  				} else if (match_available !== 0) {
-
-  					// If there was no match at the previous position, output a
-  					// single literal. If there was a match but the current match
-  					// is longer, truncate the previous match to a single literal.
-
-  					bflush = _tr_tally(0, window[strstart - 1] & 0xff);
-
-  					if (bflush) {
-  						flush_block_only(false);
-  					}
-  					strstart++;
-  					lookahead--;
-  					if (strm.avail_out === 0)
-  						return NeedMore;
-  				} else {
-  					// There is no previous match to compare with, wait for
-  					// the next step to decide.
-
-  					match_available = 1;
-  					strstart++;
-  					lookahead--;
-  				}
-  			}
-
-  			if (match_available !== 0) {
-  				bflush = _tr_tally(0, window[strstart - 1] & 0xff);
-  				match_available = 0;
-  			}
-  			flush_block_only(flush == Z_FINISH);
-
-  			if (strm.avail_out === 0) {
-  				if (flush == Z_FINISH)
-  					return FinishStarted;
-  				else
-  					return NeedMore;
-  			}
-
-  			return flush == Z_FINISH ? FinishDone : BlockDone;
-  		}
-
-  		function deflateReset(strm) {
-  			strm.total_in = strm.total_out = 0;
-  			strm.msg = null; //
-  			
-  			that.pending = 0;
-  			that.pending_out = 0;
-
-  			status = BUSY_STATE;
-
-  			last_flush = Z_NO_FLUSH;
-
-  			tr_init();
-  			lm_init();
-  			return Z_OK;
-  		}
-
-  		that.deflateInit = function(strm, _level, bits, _method, memLevel, _strategy) {
-  			if (!_method)
-  				_method = Z_DEFLATED;
-  			if (!memLevel)
-  				memLevel = DEF_MEM_LEVEL;
-  			if (!_strategy)
-  				_strategy = Z_DEFAULT_STRATEGY;
-
-  			// byte[] my_version=ZLIB_VERSION;
-
-  			//
-  			// if (!version || version[0] != my_version[0]
-  			// || stream_size != sizeof(z_stream)) {
-  			// return Z_VERSION_ERROR;
-  			// }
-
-  			strm.msg = null;
-
-  			if (_level == Z_DEFAULT_COMPRESSION)
-  				_level = 6;
-
-  			if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || _method != Z_DEFLATED || bits < 9 || bits > 15 || _level < 0 || _level > 9 || _strategy < 0
-  					|| _strategy > Z_HUFFMAN_ONLY) {
-  				return Z_STREAM_ERROR;
-  			}
-
-  			strm.dstate = that;
-
-  			w_bits = bits;
-  			w_size = 1 << w_bits;
-  			w_mask = w_size - 1;
-
-  			hash_bits = memLevel + 7;
-  			hash_size = 1 << hash_bits;
-  			hash_mask = hash_size - 1;
-  			hash_shift = Math.floor((hash_bits + MIN_MATCH - 1) / MIN_MATCH);
-
-  			window = new Uint8Array(w_size * 2);
-  			prev = [];
-  			head = [];
-
-  			lit_bufsize = 1 << (memLevel + 6); // 16K elements by default
-
-  			// We overlay pending_buf and d_buf+l_buf. This works since the average
-  			// output size for (length,distance) codes is <= 24 bits.
-  			that.pending_buf = new Uint8Array(lit_bufsize * 4);
-  			pending_buf_size = lit_bufsize * 4;
-
-  			d_buf = Math.floor(lit_bufsize / 2);
-  			l_buf = (1 + 2) * lit_bufsize;
-
-  			level = _level;
-
-  			strategy = _strategy;
-
-  			return deflateReset(strm);
-  		};
-
-  		that.deflateEnd = function() {
-  			if (status != INIT_STATE && status != BUSY_STATE && status != FINISH_STATE) {
-  				return Z_STREAM_ERROR;
-  			}
-  			// Deallocate in reverse order of allocations:
-  			that.pending_buf = null;
-  			head = null;
-  			prev = null;
-  			window = null;
-  			// free
-  			that.dstate = null;
-  			return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-  		};
-
-  		that.deflateParams = function(strm, _level, _strategy) {
-  			var err = Z_OK;
-
-  			if (_level == Z_DEFAULT_COMPRESSION) {
-  				_level = 6;
-  			}
-  			if (_level < 0 || _level > 9 || _strategy < 0 || _strategy > Z_HUFFMAN_ONLY) {
-  				return Z_STREAM_ERROR;
-  			}
-
-  			if (config_table[level].func != config_table[_level].func && strm.total_in !== 0) {
-  				// Flush the last buffer:
-  				err = strm.deflate(Z_PARTIAL_FLUSH);
-  			}
-
-  			if (level != _level) {
-  				level = _level;
-  				max_lazy_match = config_table[level].max_lazy;
-  				good_match = config_table[level].good_length;
-  				nice_match = config_table[level].nice_length;
-  				max_chain_length = config_table[level].max_chain;
-  			}
-  			strategy = _strategy;
-  			return err;
-  		};
-
-  		that.deflateSetDictionary = function(strm, dictionary, dictLength) {
-  			var length = dictLength;
-  			var n, index = 0;
-
-  			if (!dictionary || status != INIT_STATE)
-  				return Z_STREAM_ERROR;
-
-  			if (length < MIN_MATCH)
-  				return Z_OK;
-  			if (length > w_size - MIN_LOOKAHEAD) {
-  				length = w_size - MIN_LOOKAHEAD;
-  				index = dictLength - length; // use the tail of the dictionary
-  			}
-  			window.set(dictionary.subarray(index, index + length), 0);
-
-  			strstart = length;
-  			block_start = length;
-
-  			// Insert all strings in the hash table (except for the last two bytes).
-  			// s->lookahead stays null, so s->ins_h will be recomputed at the next
-  			// call of fill_window.
-
-  			ins_h = window[0] & 0xff;
-  			ins_h = (((ins_h) << hash_shift) ^ (window[1] & 0xff)) & hash_mask;
-
-  			for (n = 0; n <= length - MIN_MATCH; n++) {
-  				ins_h = (((ins_h) << hash_shift) ^ (window[(n) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
-  				prev[n & w_mask] = head[ins_h];
-  				head[ins_h] = n;
-  			}
-  			return Z_OK;
-  		};
-
-  		that.deflate = function(_strm, flush) {
-  			var i, header, level_flags, old_flush, bstate;
-
-  			if (flush > Z_FINISH || flush < 0) {
-  				return Z_STREAM_ERROR;
-  			}
-
-  			if (!_strm.next_out || (!_strm.next_in && _strm.avail_in !== 0) || (status == FINISH_STATE && flush != Z_FINISH)) {
-  				_strm.msg = z_errmsg[Z_NEED_DICT - (Z_STREAM_ERROR)];
-  				return Z_STREAM_ERROR;
-  			}
-  			if (_strm.avail_out === 0) {
-  				_strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
-  				return Z_BUF_ERROR;
-  			}
-
-  			strm = _strm; // just in case
-  			old_flush = last_flush;
-  			last_flush = flush;
-
-  			// Write the zlib header
-  			if (status == INIT_STATE) {
-  				header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8;
-  				level_flags = ((level - 1) & 0xff) >> 1;
-
-  				if (level_flags > 3)
-  					level_flags = 3;
-  				header |= (level_flags << 6);
-  				if (strstart !== 0)
-  					header |= PRESET_DICT;
-  				header += 31 - (header % 31);
-
-  				status = BUSY_STATE;
-  				putShortMSB(header);
-  			}
-
-  			// Flush as much pending output as possible
-  			if (that.pending !== 0) {
-  				strm.flush_pending();
-  				if (strm.avail_out === 0) {
-  					// console.log(" avail_out==0");
-  					// Since avail_out is 0, deflate will be called again with
-  					// more output space, but possibly with both pending and
-  					// avail_in equal to zero. There won't be anything to do,
-  					// but this is not an error situation so make sure we
-  					// return OK instead of BUF_ERROR at next call of deflate:
-  					last_flush = -1;
-  					return Z_OK;
-  				}
-
-  				// Make sure there is something to do and avoid duplicate
-  				// consecutive
-  				// flushes. For repeated and useless calls with Z_FINISH, we keep
-  				// returning Z_STREAM_END instead of Z_BUFF_ERROR.
-  			} else if (strm.avail_in === 0 && flush <= old_flush && flush != Z_FINISH) {
-  				strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
-  				return Z_BUF_ERROR;
-  			}
-
-  			// User must not provide more input after the first FINISH:
-  			if (status == FINISH_STATE && strm.avail_in !== 0) {
-  				_strm.msg = z_errmsg[Z_NEED_DICT - (Z_BUF_ERROR)];
-  				return Z_BUF_ERROR;
-  			}
-
-  			// Start a new block or continue the current one.
-  			if (strm.avail_in !== 0 || lookahead !== 0 || (flush != Z_NO_FLUSH && status != FINISH_STATE)) {
-  				bstate = -1;
-  				switch (config_table[level].func) {
-  				case STORED:
-  					bstate = deflate_stored(flush);
-  					break;
-  				case FAST:
-  					bstate = deflate_fast(flush);
-  					break;
-  				case SLOW:
-  					bstate = deflate_slow(flush);
-  					break;
-  				default:
-  				}
-
-  				if (bstate == FinishStarted || bstate == FinishDone) {
-  					status = FINISH_STATE;
-  				}
-  				if (bstate == NeedMore || bstate == FinishStarted) {
-  					if (strm.avail_out === 0) {
-  						last_flush = -1; // avoid BUF_ERROR next call, see above
-  					}
-  					return Z_OK;
-  					// If flush != Z_NO_FLUSH && avail_out === 0, the next call
-  					// of deflate should use the same flush parameter to make sure
-  					// that the flush is complete. So we don't have to output an
-  					// empty block here, this will be done at next call. This also
-  					// ensures that for a very small output buffer, we emit at most
-  					// one empty block.
-  				}
-
-  				if (bstate == BlockDone) {
-  					if (flush == Z_PARTIAL_FLUSH) {
-  						_tr_align();
-  					} else { // FULL_FLUSH or SYNC_FLUSH
-  						_tr_stored_block(0, 0, false);
-  						// For a full flush, this empty block will be recognized
-  						// as a special marker by inflate_sync().
-  						if (flush == Z_FULL_FLUSH) {
-  							// state.head[s.hash_size-1]=0;
-  							for (i = 0; i < hash_size/*-1*/; i++)
-  								// forget history
-  								head[i] = 0;
-  						}
-  					}
-  					strm.flush_pending();
-  					if (strm.avail_out === 0) {
-  						last_flush = -1; // avoid BUF_ERROR at next call, see above
-  						return Z_OK;
-  					}
-  				}
-  			}
-
-  			if (flush != Z_FINISH)
-  				return Z_OK;
-  			return Z_STREAM_END;
-  		};
-  	}
-
-  	// ZStream
-
-  	function ZStream() {
-  		var that = this;
-  		that.next_in_index = 0;
-  		that.next_out_index = 0;
-  		// that.next_in; // next input byte
-  		that.avail_in = 0; // number of bytes available at next_in
-  		that.total_in = 0; // total nb of input bytes read so far
-  		// that.next_out; // next output byte should be put there
-  		that.avail_out = 0; // remaining free space at next_out
-  		that.total_out = 0; // total nb of bytes output so far
-  		// that.msg;
-  		// that.dstate;
-  	}
-
-  	ZStream.prototype = {
-  		deflateInit : function(level, bits) {
-  			var that = this;
-  			that.dstate = new Deflate();
-  			if (!bits)
-  				bits = MAX_BITS;
-  			return that.dstate.deflateInit(that, level, bits);
-  		},
-
-  		deflate : function(flush) {
-  			var that = this;
-  			if (!that.dstate) {
-  				return Z_STREAM_ERROR;
-  			}
-  			return that.dstate.deflate(that, flush);
-  		},
-
-  		deflateEnd : function() {
-  			var that = this;
-  			if (!that.dstate)
-  				return Z_STREAM_ERROR;
-  			var ret = that.dstate.deflateEnd();
-  			that.dstate = null;
-  			return ret;
-  		},
-
-  		deflateParams : function(level, strategy) {
-  			var that = this;
-  			if (!that.dstate)
-  				return Z_STREAM_ERROR;
-  			return that.dstate.deflateParams(that, level, strategy);
-  		},
-
-  		deflateSetDictionary : function(dictionary, dictLength) {
-  			var that = this;
-  			if (!that.dstate)
-  				return Z_STREAM_ERROR;
-  			return that.dstate.deflateSetDictionary(that, dictionary, dictLength);
-  		},
-
-  		// Read a new buffer from the current input stream, update the
-  		// total number of bytes read. All deflate() input goes through
-  		// this function so some applications may wish to modify it to avoid
-  		// allocating a large strm->next_in buffer and copying from it.
-  		// (See also flush_pending()).
-  		read_buf : function(buf, start, size) {
-  			var that = this;
-  			var len = that.avail_in;
-  			if (len > size)
-  				len = size;
-  			if (len === 0)
-  				return 0;
-  			that.avail_in -= len;
-  			buf.set(that.next_in.subarray(that.next_in_index, that.next_in_index + len), start);
-  			that.next_in_index += len;
-  			that.total_in += len;
-  			return len;
-  		},
-
-  		// Flush as much pending output as possible. All deflate() output goes
-  		// through this function so some applications may wish to modify it
-  		// to avoid allocating a large strm->next_out buffer and copying into it.
-  		// (See also read_buf()).
-  		flush_pending : function() {
-  			var that = this;
-  			var len = that.dstate.pending;
-
-  			if (len > that.avail_out)
-  				len = that.avail_out;
-  			if (len === 0)
-  				return;
-
-  			// if (that.dstate.pending_buf.length <= that.dstate.pending_out || that.next_out.length <= that.next_out_index
-  			// || that.dstate.pending_buf.length < (that.dstate.pending_out + len) || that.next_out.length < (that.next_out_index +
-  			// len)) {
-  			// console.log(that.dstate.pending_buf.length + ", " + that.dstate.pending_out + ", " + that.next_out.length + ", " +
-  			// that.next_out_index + ", " + len);
-  			// console.log("avail_out=" + that.avail_out);
-  			// }
-
-  			that.next_out.set(that.dstate.pending_buf.subarray(that.dstate.pending_out, that.dstate.pending_out + len), that.next_out_index);
-
-  			that.next_out_index += len;
-  			that.dstate.pending_out += len;
-  			that.total_out += len;
-  			that.avail_out -= len;
-  			that.dstate.pending -= len;
-  			if (that.dstate.pending === 0) {
-  				that.dstate.pending_out = 0;
-  			}
-  		}
-  	};
-
-  	// Deflater
-
-  	function Deflater(options) {
-  		var that = this;
-  		var z = new ZStream();
-  		var bufsize = 512;
-  		var flush = Z_NO_FLUSH;
-  		var buf = new Uint8Array(bufsize);
-  		var level = options ? options.level : Z_DEFAULT_COMPRESSION;
-  		if (typeof level == "undefined")
-  			level = Z_DEFAULT_COMPRESSION;
-  		z.deflateInit(level);
-  		z.next_out = buf;
-
-  		that.append = function(data, onprogress) {
-  			var err, buffers = [], lastIndex = 0, bufferIndex = 0, bufferSize = 0, array;
-  			if (!data.length)
-  				return;
-  			z.next_in_index = 0;
-  			z.next_in = data;
-  			z.avail_in = data.length;
-  			do {
-  				z.next_out_index = 0;
-  				z.avail_out = bufsize;
-  				err = z.deflate(flush);
-  				if (err != Z_OK)
-  					throw new Error("deflating: " + z.msg);
-  				if (z.next_out_index)
-  					if (z.next_out_index == bufsize)
-  						buffers.push(new Uint8Array(buf));
-  					else
-  						buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
-  				bufferSize += z.next_out_index;
-  				if (onprogress && z.next_in_index > 0 && z.next_in_index != lastIndex) {
-  					onprogress(z.next_in_index);
-  					lastIndex = z.next_in_index;
-  				}
-  			} while (z.avail_in > 0 || z.avail_out === 0);
-  			array = new Uint8Array(bufferSize);
-  			buffers.forEach(function(chunk) {
-  				array.set(chunk, bufferIndex);
-  				bufferIndex += chunk.length;
-  			});
-  			return array;
-  		};
-  		that.flush = function() {
-  			var err, buffers = [], bufferIndex = 0, bufferSize = 0, array;
-  			do {
-  				z.next_out_index = 0;
-  				z.avail_out = bufsize;
-  				err = z.deflate(Z_FINISH);
-  				if (err != Z_STREAM_END && err != Z_OK)
-  					throw new Error("deflating: " + z.msg);
-  				if (bufsize - z.avail_out > 0)
-  					buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
-  				bufferSize += z.next_out_index;
-  			} while (z.avail_in > 0 || z.avail_out === 0);
-  			z.deflateEnd();
-  			array = new Uint8Array(bufferSize);
-  			buffers.forEach(function(chunk) {
-  				array.set(chunk, bufferIndex);
-  				bufferIndex += chunk.length;
-  			});
-  			return array;
-  		};
-  	}
-
-  	// 'zip' may not be defined in z-worker and some tests
-  	var env = global.zip || global;
-  	env.Deflater = env._jzlib_Deflater = Deflater;
-  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global ||  Function('return typeof this === "object" && this.content')() || Function('return this')()));
-  // `self` is undefined in Firefox for Android content script context
-  // while `this` is nsIContentFrameMessageManager
-  // with an attribute `content` that corresponds to the window
-
-  /**
-   * A class to parse color values
-   * @author Stoyan Stefanov <sstoo@gmail.com>
-   * @link   http://www.phpied.com/rgb-color-parser-in-javascript/
-   * @license Use it if you like it
-   */
-   
-  (function ( global ) {
-   
-  	function RGBColor(color_string)
-  	{
-  		this.ok = false;
-
-  		// strip any leading #
-  		if (color_string.charAt(0) == '#') { // remove # if any
-  			color_string = color_string.substr(1,6);
-  		}
-
-  		color_string = color_string.replace(/ /g,'');
-  		color_string = color_string.toLowerCase();
-
-  		var channels;
-
-  		// before getting into regexps, try simple matches
-  		// and overwrite the input
-  		var simple_colors = {
-  			aliceblue: 'f0f8ff',
-  			antiquewhite: 'faebd7',
-  			aqua: '00ffff',
-  			aquamarine: '7fffd4',
-  			azure: 'f0ffff',
-  			beige: 'f5f5dc',
-  			bisque: 'ffe4c4',
-  			black: '000000',
-  			blanchedalmond: 'ffebcd',
-  			blue: '0000ff',
-  			blueviolet: '8a2be2',
-  			brown: 'a52a2a',
-  			burlywood: 'deb887',
-  			cadetblue: '5f9ea0',
-  			chartreuse: '7fff00',
-  			chocolate: 'd2691e',
-  			coral: 'ff7f50',
-  			cornflowerblue: '6495ed',
-  			cornsilk: 'fff8dc',
-  			crimson: 'dc143c',
-  			cyan: '00ffff',
-  			darkblue: '00008b',
-  			darkcyan: '008b8b',
-  			darkgoldenrod: 'b8860b',
-  			darkgray: 'a9a9a9',
-  			darkgreen: '006400',
-  			darkkhaki: 'bdb76b',
-  			darkmagenta: '8b008b',
-  			darkolivegreen: '556b2f',
-  			darkorange: 'ff8c00',
-  			darkorchid: '9932cc',
-  			darkred: '8b0000',
-  			darksalmon: 'e9967a',
-  			darkseagreen: '8fbc8f',
-  			darkslateblue: '483d8b',
-  			darkslategray: '2f4f4f',
-  			darkturquoise: '00ced1',
-  			darkviolet: '9400d3',
-  			deeppink: 'ff1493',
-  			deepskyblue: '00bfff',
-  			dimgray: '696969',
-  			dodgerblue: '1e90ff',
-  			feldspar: 'd19275',
-  			firebrick: 'b22222',
-  			floralwhite: 'fffaf0',
-  			forestgreen: '228b22',
-  			fuchsia: 'ff00ff',
-  			gainsboro: 'dcdcdc',
-  			ghostwhite: 'f8f8ff',
-  			gold: 'ffd700',
-  			goldenrod: 'daa520',
-  			gray: '808080',
-  			green: '008000',
-  			greenyellow: 'adff2f',
-  			honeydew: 'f0fff0',
-  			hotpink: 'ff69b4',
-  			indianred : 'cd5c5c',
-  			indigo : '4b0082',
-  			ivory: 'fffff0',
-  			khaki: 'f0e68c',
-  			lavender: 'e6e6fa',
-  			lavenderblush: 'fff0f5',
-  			lawngreen: '7cfc00',
-  			lemonchiffon: 'fffacd',
-  			lightblue: 'add8e6',
-  			lightcoral: 'f08080',
-  			lightcyan: 'e0ffff',
-  			lightgoldenrodyellow: 'fafad2',
-  			lightgrey: 'd3d3d3',
-  			lightgreen: '90ee90',
-  			lightpink: 'ffb6c1',
-  			lightsalmon: 'ffa07a',
-  			lightseagreen: '20b2aa',
-  			lightskyblue: '87cefa',
-  			lightslateblue: '8470ff',
-  			lightslategray: '778899',
-  			lightsteelblue: 'b0c4de',
-  			lightyellow: 'ffffe0',
-  			lime: '00ff00',
-  			limegreen: '32cd32',
-  			linen: 'faf0e6',
-  			magenta: 'ff00ff',
-  			maroon: '800000',
-  			mediumaquamarine: '66cdaa',
-  			mediumblue: '0000cd',
-  			mediumorchid: 'ba55d3',
-  			mediumpurple: '9370d8',
-  			mediumseagreen: '3cb371',
-  			mediumslateblue: '7b68ee',
-  			mediumspringgreen: '00fa9a',
-  			mediumturquoise: '48d1cc',
-  			mediumvioletred: 'c71585',
-  			midnightblue: '191970',
-  			mintcream: 'f5fffa',
-  			mistyrose: 'ffe4e1',
-  			moccasin: 'ffe4b5',
-  			navajowhite: 'ffdead',
-  			navy: '000080',
-  			oldlace: 'fdf5e6',
-  			olive: '808000',
-  			olivedrab: '6b8e23',
-  			orange: 'ffa500',
-  			orangered: 'ff4500',
-  			orchid: 'da70d6',
-  			palegoldenrod: 'eee8aa',
-  			palegreen: '98fb98',
-  			paleturquoise: 'afeeee',
-  			palevioletred: 'd87093',
-  			papayawhip: 'ffefd5',
-  			peachpuff: 'ffdab9',
-  			peru: 'cd853f',
-  			pink: 'ffc0cb',
-  			plum: 'dda0dd',
-  			powderblue: 'b0e0e6',
-  			purple: '800080',
-  			red: 'ff0000',
-  			rosybrown: 'bc8f8f',
-  			royalblue: '4169e1',
-  			saddlebrown: '8b4513',
-  			salmon: 'fa8072',
-  			sandybrown: 'f4a460',
-  			seagreen: '2e8b57',
-  			seashell: 'fff5ee',
-  			sienna: 'a0522d',
-  			silver: 'c0c0c0',
-  			skyblue: '87ceeb',
-  			slateblue: '6a5acd',
-  			slategray: '708090',
-  			snow: 'fffafa',
-  			springgreen: '00ff7f',
-  			steelblue: '4682b4',
-  			tan: 'd2b48c',
-  			teal: '008080',
-  			thistle: 'd8bfd8',
-  			tomato: 'ff6347',
-  			turquoise: '40e0d0',
-  			violet: 'ee82ee',
-  			violetred: 'd02090',
-  			wheat: 'f5deb3',
-  			white: 'ffffff',
-  			whitesmoke: 'f5f5f5',
-  			yellow: 'ffff00',
-  			yellowgreen: '9acd32'
-  		};
-  		for (var key in simple_colors) {
-  			if (color_string == key) {
-  				color_string = simple_colors[key];
-  			}
-  		}
-  		// emd of simple type-in colors
-
-  		// array of color definition objects
-  		var color_defs = [
-  			{
-  				re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
-  				example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'],
-  				process: function (bits){
-  					return [
-  						parseInt(bits[1]),
-  						parseInt(bits[2]),
-  						parseInt(bits[3])
-  					];
-  				}
-  			},
-  			{
-  				re: /^(\w{2})(\w{2})(\w{2})$/,
-  				example: ['#00ff00', '336699'],
-  				process: function (bits){
-  					return [
-  						parseInt(bits[1], 16),
-  						parseInt(bits[2], 16),
-  						parseInt(bits[3], 16)
-  					];
-  				}
-  			},
-  			{
-  				re: /^(\w{1})(\w{1})(\w{1})$/,
-  				example: ['#fb0', 'f0f'],
-  				process: function (bits){
-  					return [
-  						parseInt(bits[1] + bits[1], 16),
-  						parseInt(bits[2] + bits[2], 16),
-  						parseInt(bits[3] + bits[3], 16)
-  					];
-  				}
-  			}
-  		];
-
-  		// search through the definitions to find a match
-  		for (var i = 0; i < color_defs.length; i++) {
-  			var re = color_defs[i].re;
-  			var processor = color_defs[i].process;
-  			var bits = re.exec(color_string);
-  			if (bits) {
-  				channels = processor(bits);
-  				this.r = channels[0];
-  				this.g = channels[1];
-  				this.b = channels[2];
-  				this.ok = true;
-  			}
-
-  		}
-
-  		// validate/cleanup values
-  		this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);
-  		this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g);
-  		this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b);
-
-  		// some getters
-  		this.toRGB = function () {
-  			return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')';
-  		};
-  		this.toHex = function () {
-  			var r = this.r.toString(16);
-  			var g = this.g.toString(16);
-  			var b = this.b.toString(16);
-  			if (r.length == 1) r = '0' + r;
-  			if (g.length == 1) g = '0' + g;
-  			if (b.length == 1) b = '0' + b;
-  			return '#' + r + g + b;
-  		};
-
-  		// help
-  		this.getHelpXML = function () {
-
-  			var examples = new Array();
-  			// add regexps
-  			for (var i = 0; i < color_defs.length; i++) {
-  				var example = color_defs[i].example;
-  				for (var j = 0; j < example.length; j++) {
-  					examples[examples.length] = example[j];
-  				}
-  			}
-  			// add type-in colors
-  			for (var sc in simple_colors) {
-  				examples[examples.length] = sc;
-  			}
-
-  			var xml = document.createElement('ul');
-  			xml.setAttribute('id', 'rgbcolor-examples');
-  			for (var i = 0; i < examples.length; i++) {
-  				try {
-  					var list_item = document.createElement('li');
-  					var list_color = new RGBColor(examples[i]);
-  					var example_div = document.createElement('div');
-  					example_div.style.cssText =
-  							'margin: 3px; '
-  							+ 'border: 1px solid black; '
-  							+ 'background:' + list_color.toHex() + '; '
-  							+ 'color:' + list_color.toHex()
-  					;
-  					example_div.appendChild(document.createTextNode('test'));
-  					var list_item_value = document.createTextNode(
-  						' ' + examples[i] + ' -> ' + list_color.toRGB() + ' -> ' + list_color.toHex()
-  					);
-  					list_item.appendChild(example_div);
-  					list_item.appendChild(list_item_value);
-  					xml.appendChild(list_item);
-
-  				} catch(e){}
-  			}
-  			return xml;
-
-  		};
-
-  	}
-
-      // export as AMD...
-      if ( typeof define !== 'undefined' && define.amd ) {
-          define('RGBColor', function () { return RGBColor; });
-      }
-
-      // ...or as browserify
-      else if (typeof module !== 'undefined' && module.exports ) {
-          module.exports = RGBColor;
-      }
-
-      global.RGBColor = RGBColor;
-  	
-  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global ||  Function('return typeof this === "object" && this.content')() || Function('return this')()));
-  // `self` is undefined in Firefox for Android content script context
-  // while `this` is nsIContentFrameMessageManager
-  // with an attribute `content` that corresponds to the window
-
-  /*
-    html2canvas 0.5.0-beta3 <http://html2canvas.hertzen.com>
-    Copyright (c) 2016 Niklas von Hertzen
-
-    Released under  License
-  */
-
-  !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define("html2canvas",[],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.html2canvas=e();}}(function(){var define;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r);}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
-  (function (global){
-  (function(root) {
-
-  	/** Detect free variables */
-  	var freeExports = typeof exports == 'object' && exports;
-  	var freeModule = typeof module == 'object' && module &&
-  		module.exports == freeExports && module;
-  	var freeGlobal = typeof global == 'object' && global;
-  	if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
-  		root = freeGlobal;
-  	}
-
-  	/**
-  	 * The `punycode` object.
-  	 * @name punycode
-  	 * @type Object
-  	 */
-  	var punycode,
-
-  	/** Highest positive signed 32-bit float value */
-  	maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
-
-  	/** Bootstring parameters */
-  	base = 36,
-  	tMin = 1,
-  	tMax = 26,
-  	skew = 38,
-  	damp = 700,
-  	initialBias = 72,
-  	initialN = 128, // 0x80
-  	delimiter = '-', // '\x2D'
-
-  	/** Regular expressions */
-  	regexPunycode = /^xn--/,
-  	regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars
-  	regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators
-
-  	/** Error messages */
-  	errors = {
-  		'overflow': 'Overflow: input needs wider integers to process',
-  		'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
-  		'invalid-input': 'Invalid input'
-  	},
-
-  	/** Convenience shortcuts */
-  	baseMinusTMin = base - tMin,
-  	floor = Math.floor,
-  	stringFromCharCode = String.fromCharCode,
-
-  	/** Temporary variable */
-  	key;
-
-  	/*--------------------------------------------------------------------------*/
-
-  	/**
-  	 * A generic error utility function.
-  	 * @private
-  	 * @param {String} type The error type.
-  	 * @returns {Error} Throws a `RangeError` with the applicable error message.
-  	 */
-  	function error(type) {
-  		throw RangeError(errors[type]);
-  	}
-
-  	/**
-  	 * A generic `Array#map` utility function.
-  	 * @private
-  	 * @param {Array} array The array to iterate over.
-  	 * @param {Function} callback The function that gets called for every array
-  	 * item.
-  	 * @returns {Array} A new array of values returned by the callback function.
-  	 */
-  	function map(array, fn) {
-  		var length = array.length;
-  		while (length--) {
-  			array[length] = fn(array[length]);
-  		}
-  		return array;
-  	}
-
-  	/**
-  	 * A simple `Array#map`-like wrapper to work with domain name strings.
-  	 * @private
-  	 * @param {String} domain The domain name.
-  	 * @param {Function} callback The function that gets called for every
-  	 * character.
-  	 * @returns {Array} A new string of characters returned by the callback
-  	 * function.
-  	 */
-  	function mapDomain(string, fn) {
-  		return map(string.split(regexSeparators), fn).join('.');
-  	}
-
-  	/**
-  	 * Creates an array containing the numeric code points of each Unicode
-  	 * character in the string. While JavaScript uses UCS-2 internally,
-  	 * this function will convert a pair of surrogate halves (each of which
-  	 * UCS-2 exposes as separate characters) into a single code point,
-  	 * matching UTF-16.
-  	 * @see `punycode.ucs2.encode`
-  	 * @see <http://mathiasbynens.be/notes/javascript-encoding>
-  	 * @memberOf punycode.ucs2
-  	 * @name decode
-  	 * @param {String} string The Unicode input string (UCS-2).
-  	 * @returns {Array} The new array of code points.
-  	 */
-  	function ucs2decode(string) {
-  		var output = [],
-  		    counter = 0,
-  		    length = string.length,
-  		    value,
-  		    extra;
-  		while (counter < length) {
-  			value = string.charCodeAt(counter++);
-  			if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
-  				// high surrogate, and there is a next character
-  				extra = string.charCodeAt(counter++);
-  				if ((extra & 0xFC00) == 0xDC00) { // low surrogate
-  					output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
-  				} else {
-  					// unmatched surrogate; only append this code unit, in case the next
-  					// code unit is the high surrogate of a surrogate pair
-  					output.push(value);
-  					counter--;
-  				}
-  			} else {
-  				output.push(value);
-  			}
-  		}
-  		return output;
-  	}
-
-  	/**
-  	 * Creates a string based on an array of numeric code points.
-  	 * @see `punycode.ucs2.decode`
-  	 * @memberOf punycode.ucs2
-  	 * @name encode
-  	 * @param {Array} codePoints The array of numeric code points.
-  	 * @returns {String} The new Unicode string (UCS-2).
-  	 */
-  	function ucs2encode(array) {
-  		return map(array, function(value) {
-  			var output = '';
-  			if (value > 0xFFFF) {
-  				value -= 0x10000;
-  				output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
-  				value = 0xDC00 | value & 0x3FF;
-  			}
-  			output += stringFromCharCode(value);
-  			return output;
-  		}).join('');
-  	}
-
-  	/**
-  	 * Converts a basic code point into a digit/integer.
-  	 * @see `digitToBasic()`
-  	 * @private
-  	 * @param {Number} codePoint The basic numeric code point value.
-  	 * @returns {Number} The numeric value of a basic code point (for use in
-  	 * representing integers) in the range `0` to `base - 1`, or `base` if
-  	 * the code point does not represent a value.
-  	 */
-  	function basicToDigit(codePoint) {
-  		if (codePoint - 48 < 10) {
-  			return codePoint - 22;
-  		}
-  		if (codePoint - 65 < 26) {
-  			return codePoint - 65;
-  		}
-  		if (codePoint - 97 < 26) {
-  			return codePoint - 97;
-  		}
-  		return base;
-  	}
-
-  	/**
-  	 * Converts a digit/integer into a basic code point.
-  	 * @see `basicToDigit()`
-  	 * @private
-  	 * @param {Number} digit The numeric value of a basic code point.
-  	 * @returns {Number} The basic code point whose value (when used for
-  	 * representing integers) is `digit`, which needs to be in the range
-  	 * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
-  	 * used; else, the lowercase form is used. The behavior is undefined
-  	 * if `flag` is non-zero and `digit` has no uppercase form.
-  	 */
-  	function digitToBasic(digit, flag) {
-  		//  0..25 map to ASCII a..z or A..Z
-  		// 26..35 map to ASCII 0..9
-  		return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
-  	}
-
-  	/**
-  	 * Bias adaptation function as per section 3.4 of RFC 3492.
-  	 * http://tools.ietf.org/html/rfc3492#section-3.4
-  	 * @private
-  	 */
-  	function adapt(delta, numPoints, firstTime) {
-  		var k = 0;
-  		delta = firstTime ? floor(delta / damp) : delta >> 1;
-  		delta += floor(delta / numPoints);
-  		for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
-  			delta = floor(delta / baseMinusTMin);
-  		}
-  		return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
-  	}
-
-  	/**
-  	 * Converts a Punycode string of ASCII-only symbols to a string of Unicode
-  	 * symbols.
-  	 * @memberOf punycode
-  	 * @param {String} input The Punycode string of ASCII-only symbols.
-  	 * @returns {String} The resulting string of Unicode symbols.
-  	 */
-  	function decode(input) {
-  		// Don't use UCS-2
-  		var output = [],
-  		    inputLength = input.length,
-  		    out,
-  		    i = 0,
-  		    n = initialN,
-  		    bias = initialBias,
-  		    basic,
-  		    j,
-  		    index,
-  		    oldi,
-  		    w,
-  		    k,
-  		    digit,
-  		    t,
-  		    /** Cached calculation results */
-  		    baseMinusT;
-
-  		// Handle the basic code points: let `basic` be the number of input code
-  		// points before the last delimiter, or `0` if there is none, then copy
-  		// the first basic code points to the output.
-
-  		basic = input.lastIndexOf(delimiter);
-  		if (basic < 0) {
-  			basic = 0;
-  		}
-
-  		for (j = 0; j < basic; ++j) {
-  			// if it's not a basic code point
-  			if (input.charCodeAt(j) >= 0x80) {
-  				error('not-basic');
-  			}
-  			output.push(input.charCodeAt(j));
-  		}
-
-  		// Main decoding loop: start just after the last delimiter if any basic code
-  		// points were copied; start at the beginning otherwise.
-
-  		for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
-
-  			// `index` is the index of the next character to be consumed.
-  			// Decode a generalized variable-length integer into `delta`,
-  			// which gets added to `i`. The overflow checking is easier
-  			// if we increase `i` as we go, then subtract off its starting
-  			// value at the end to obtain `delta`.
-  			for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
-
-  				if (index >= inputLength) {
-  					error('invalid-input');
-  				}
-
-  				digit = basicToDigit(input.charCodeAt(index++));
-
-  				if (digit >= base || digit > floor((maxInt - i) / w)) {
-  					error('overflow');
-  				}
-
-  				i += digit * w;
-  				t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
-
-  				if (digit < t) {
-  					break;
-  				}
-
-  				baseMinusT = base - t;
-  				if (w > floor(maxInt / baseMinusT)) {
-  					error('overflow');
-  				}
-
-  				w *= baseMinusT;
-
-  			}
-
-  			out = output.length + 1;
-  			bias = adapt(i - oldi, out, oldi == 0);
-
-  			// `i` was supposed to wrap around from `out` to `0`,
-  			// incrementing `n` each time, so we'll fix that now:
-  			if (floor(i / out) > maxInt - n) {
-  				error('overflow');
-  			}
-
-  			n += floor(i / out);
-  			i %= out;
-
-  			// Insert `n` at position `i` of the output
-  			output.splice(i++, 0, n);
-
-  		}
-
-  		return ucs2encode(output);
-  	}
-
-  	/**
-  	 * Converts a string of Unicode symbols to a Punycode string of ASCII-only
-  	 * symbols.
-  	 * @memberOf punycode
-  	 * @param {String} input The string of Unicode symbols.
-  	 * @returns {String} The resulting Punycode string of ASCII-only symbols.
-  	 */
-  	function encode(input) {
-  		var n,
-  		    delta,
-  		    handledCPCount,
-  		    basicLength,
-  		    bias,
-  		    j,
-  		    m,
-  		    q,
-  		    k,
-  		    t,
-  		    currentValue,
-  		    output = [],
-  		    /** `inputLength` will hold the number of code points in `input`. */
-  		    inputLength,
-  		    /** Cached calculation results */
-  		    handledCPCountPlusOne,
-  		    baseMinusT,
-  		    qMinusT;
-
-  		// Convert the input in UCS-2 to Unicode
-  		input = ucs2decode(input);
-
-  		// Cache the length
-  		inputLength = input.length;
-
-  		// Initialize the state
-  		n = initialN;
-  		delta = 0;
-  		bias = initialBias;
-
-  		// Handle the basic code points
-  		for (j = 0; j < inputLength; ++j) {
-  			currentValue = input[j];
-  			if (currentValue < 0x80) {
-  				output.push(stringFromCharCode(currentValue));
-  			}
-  		}
-
-  		handledCPCount = basicLength = output.length;
-
-  		// `handledCPCount` is the number of code points that have been handled;
-  		// `basicLength` is the number of basic code points.
-
-  		// Finish the basic string - if it is not empty - with a delimiter
-  		if (basicLength) {
-  			output.push(delimiter);
-  		}
-
-  		// Main encoding loop:
-  		while (handledCPCount < inputLength) {
-
-  			// All non-basic code points < n have been handled already. Find the next
-  			// larger one:
-  			for (m = maxInt, j = 0; j < inputLength; ++j) {
-  				currentValue = input[j];
-  				if (currentValue >= n && currentValue < m) {
-  					m = currentValue;
-  				}
-  			}
-
-  			// Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
-  			// but guard against overflow
-  			handledCPCountPlusOne = handledCPCount + 1;
-  			if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
-  				error('overflow');
-  			}
-
-  			delta += (m - n) * handledCPCountPlusOne;
-  			n = m;
-
-  			for (j = 0; j < inputLength; ++j) {
-  				currentValue = input[j];
-
-  				if (currentValue < n && ++delta > maxInt) {
-  					error('overflow');
-  				}
-
-  				if (currentValue == n) {
-  					// Represent delta as a generalized variable-length integer
-  					for (q = delta, k = base; /* no condition */; k += base) {
-  						t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
-  						if (q < t) {
-  							break;
-  						}
-  						qMinusT = q - t;
-  						baseMinusT = base - t;
-  						output.push(
-  							stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
-  						);
-  						q = floor(qMinusT / baseMinusT);
-  					}
-
-  					output.push(stringFromCharCode(digitToBasic(q, 0)));
-  					bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
-  					delta = 0;
-  					++handledCPCount;
-  				}
-  			}
-
-  			++delta;
-  			++n;
-
-  		}
-  		return output.join('');
-  	}
-
-  	/**
-  	 * Converts a Punycode string representing a domain name to Unicode. Only the
-  	 * Punycoded parts of the domain name will be converted, i.e. it doesn't
-  	 * matter if you call it on a string that has already been converted to
-  	 * Unicode.
-  	 * @memberOf punycode
-  	 * @param {String} domain The Punycode domain name to convert to Unicode.
-  	 * @returns {String} The Unicode representation of the given Punycode
-  	 * string.
-  	 */
-  	function toUnicode(domain) {
-  		return mapDomain(domain, function(string) {
-  			return regexPunycode.test(string)
-  				? decode(string.slice(4).toLowerCase())
-  				: string;
-  		});
-  	}
-
-  	/**
-  	 * Converts a Unicode string representing a domain name to Punycode. Only the
-  	 * non-ASCII parts of the domain name will be converted, i.e. it doesn't
-  	 * matter if you call it with a domain that's already in ASCII.
-  	 * @memberOf punycode
-  	 * @param {String} domain The domain name to convert, as a Unicode string.
-  	 * @returns {String} The Punycode representation of the given domain name.
-  	 */
-  	function toASCII(domain) {
-  		return mapDomain(domain, function(string) {
-  			return regexNonASCII.test(string)
-  				? 'xn--' + encode(string)
-  				: string;
-  		});
-  	}
-
-  	/*--------------------------------------------------------------------------*/
-
-  	/** Define the public API */
-  	punycode = {
-  		/**
-  		 * A string representing the current Punycode.js version number.
-  		 * @memberOf punycode
-  		 * @type String
-  		 */
-  		'version': '1.2.4',
-  		/**
-  		 * An object of methods to convert from JavaScript's internal character
-  		 * representation (UCS-2) to Unicode code points, and back.
-  		 * @see <http://mathiasbynens.be/notes/javascript-encoding>
-  		 * @memberOf punycode
-  		 * @type Object
-  		 */
-  		'ucs2': {
-  			'decode': ucs2decode,
-  			'encode': ucs2encode
-  		},
-  		'decode': decode,
-  		'encode': encode,
-  		'toASCII': toASCII,
-  		'toUnicode': toUnicode
-  	};
-
-  	/** Expose `punycode` */
-  	// Some AMD build optimizers, like r.js, check for specific condition patterns
-  	// like the following:
-  	if (
-  		typeof define == 'function' &&
-  		typeof define.amd == 'object' && define.amd && false
-  	) {
-  		define('punycode', function() {
-  			return punycode;
-  		});
-  	} else if (freeExports && !freeExports.nodeType) {
-  		if (freeModule) { // in Node.js or RingoJS v0.8.0+
-  			freeModule.exports = punycode;
-  		} else { // in Narwhal or RingoJS v0.7.0-
-  			for (key in punycode) {
-  				punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
-  			}
-  		}
-  	} else { // in Rhino or a web browser
-  		root.punycode = punycode;
-  	}
-
-  }(this));
-
-  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {});
-  },{}],2:[function(_dereq_,module,exports){
-  var log = _dereq_('./log');
-
-  function restoreOwnerScroll(ownerDocument, x, y) {
-      if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {
-          ownerDocument.defaultView.scrollTo(x, y);
-      }
-  }
-
-  function cloneCanvasContents(canvas, clonedCanvas) {
-      try {
-          if (clonedCanvas) {
-              clonedCanvas.width = canvas.width;
-              clonedCanvas.height = canvas.height;
-              clonedCanvas.getContext("2d").putImageData(canvas.getContext("2d").getImageData(0, 0, canvas.width, canvas.height), 0, 0);
-          }
-      } catch(e) {
-          log("Unable to copy canvas content from", canvas, e);
-      }
-  }
-
-  function cloneNode(node, javascriptEnabled) {
-      var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false);
-
-      var child = node.firstChild;
-      while(child) {
-          if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') {
-              clone.appendChild(cloneNode(child, javascriptEnabled));
-          }
-          child = child.nextSibling;
-      }
-
-      if (node.nodeType === 1) {
-          clone._scrollTop = node.scrollTop;
-          clone._scrollLeft = node.scrollLeft;
-          if (node.nodeName === "CANVAS") {
-              cloneCanvasContents(node, clone);
-          } else if (node.nodeName === "TEXTAREA" || node.nodeName === "SELECT") {
-              clone.value = node.value;
-          }
-      }
-
-      return clone;
-  }
-
-  function initNode(node) {
-      if (node.nodeType === 1) {
-          node.scrollTop = node._scrollTop;
-          node.scrollLeft = node._scrollLeft;
-
-          var child = node.firstChild;
-          while(child) {
-              initNode(child);
-              child = child.nextSibling;
-          }
-      }
-  }
-
-  module.exports = function(ownerDocument, containerDocument, width, height, options, x ,y) {
-      var documentElement = cloneNode(ownerDocument.documentElement, options.javascriptEnabled);
-      var container = containerDocument.createElement("iframe");
-
-      container.className = "html2canvas-container";
-      container.style.visibility = "hidden";
-      container.style.position = "fixed";
-      container.style.left = "-10000px";
-      container.style.top = "0px";
-      container.style.border = "0";
-      container.width = width;
-      container.height = height;
-      container.scrolling = "no"; // ios won't scroll without it
-      containerDocument.body.appendChild(container);
-
-      return new Promise(function(resolve) {
-          var documentClone = container.contentWindow.document;
-
-          /* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle
-           if window url is about:blank, we can assign the url to current by writing onto the document
-           */
-          container.contentWindow.onload = container.onload = function() {
-              var interval = setInterval(function() {
-                  if (documentClone.body.childNodes.length > 0) {
-                      initNode(documentClone.documentElement);
-                      clearInterval(interval);
-                      if (options.type === "view") {
-                          container.contentWindow.scrollTo(x, y);
-                          if ((/(iPad|iPhone|iPod)/g).test(navigator.userAgent) && (container.contentWindow.scrollY !== y || container.contentWindow.scrollX !== x)) {
-                              documentClone.documentElement.style.top = (-y) + "px";
-                              documentClone.documentElement.style.left = (-x) + "px";
-                              documentClone.documentElement.style.position = 'absolute';
-                          }
-                      }
-                      resolve(container);
-                  }
-              }, 50);
-          };
-
-          documentClone.open();
-          documentClone.write("<!DOCTYPE html><html></html>");
-          // Chrome scrolls the parent document for some reason after the write to the cloned window???
-          restoreOwnerScroll(ownerDocument, x, y);
-          documentClone.replaceChild(documentClone.adoptNode(documentElement), documentClone.documentElement);
-          documentClone.close();
-      });
-  };
-
-  },{"./log":13}],3:[function(_dereq_,module,exports){
-  // http://dev.w3.org/csswg/css-color/
-
-  function Color(value) {
-      this.r = 0;
-      this.g = 0;
-      this.b = 0;
-      this.a = null;
-      var result = this.fromArray(value) ||
-          this.namedColor(value) ||
-          this.rgb(value) ||
-          this.rgba(value) ||
-          this.hex6(value) ||
-          this.hex3(value);
-  }
-
-  Color.prototype.darken = function(amount) {
-      var a = 1 - amount;
-      return  new Color([
-          Math.round(this.r * a),
-          Math.round(this.g * a),
-          Math.round(this.b * a),
-          this.a
-      ]);
-  };
-
-  Color.prototype.isTransparent = function() {
-      return this.a === 0;
-  };
-
-  Color.prototype.isBlack = function() {
-      return this.r === 0 && this.g === 0 && this.b === 0;
-  };
-
-  Color.prototype.fromArray = function(array) {
-      if (Array.isArray(array)) {
-          this.r = Math.min(array[0], 255);
-          this.g = Math.min(array[1], 255);
-          this.b = Math.min(array[2], 255);
-          if (array.length > 3) {
-              this.a = array[3];
-          }
-      }
-
-      return (Array.isArray(array));
-  };
-
-  var _hex3 = /^#([a-f0-9]{3})$/i;
-
-  Color.prototype.hex3 = function(value) {
-      var match = null;
-      if ((match = value.match(_hex3)) !== null) {
-          this.r = parseInt(match[1][0] + match[1][0], 16);
-          this.g = parseInt(match[1][1] + match[1][1], 16);
-          this.b = parseInt(match[1][2] + match[1][2], 16);
-      }
-      return match !== null;
-  };
-
-  var _hex6 = /^#([a-f0-9]{6})$/i;
-
-  Color.prototype.hex6 = function(value) {
-      var match = null;
-      if ((match = value.match(_hex6)) !== null) {
-          this.r = parseInt(match[1].substring(0, 2), 16);
-          this.g = parseInt(match[1].substring(2, 4), 16);
-          this.b = parseInt(match[1].substring(4, 6), 16);
-      }
-      return match !== null;
-  };
-
-
-  var _rgb = /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/;
-
-  Color.prototype.rgb = function(value) {
-      var match = null;
-      if ((match = value.match(_rgb)) !== null) {
-          this.r = Number(match[1]);
-          this.g = Number(match[2]);
-          this.b = Number(match[3]);
-      }
-      return match !== null;
-  };
-
-  var _rgba = /^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d?\.?\d+)\s*\)$/;
-
-  Color.prototype.rgba = function(value) {
-      var match = null;
-      if ((match = value.match(_rgba)) !== null) {
-          this.r = Number(match[1]);
-          this.g = Number(match[2]);
-          this.b = Number(match[3]);
-          this.a = Number(match[4]);
-      }
-      return match !== null;
-  };
-
-  Color.prototype.toString = function() {
-      return this.a !== null && this.a !== 1 ?
-      "rgba(" + [this.r, this.g, this.b, this.a].join(",") + ")" :
-      "rgb(" + [this.r, this.g, this.b].join(",") + ")";
-  };
-
-  Color.prototype.namedColor = function(value) {
-      value = value.toLowerCase();
-      var color = colors[value];
-      if (color) {
-          this.r = color[0];
-          this.g = color[1];
-          this.b = color[2];
-      } else if (value === "transparent") {
-          this.r = this.g = this.b = this.a = 0;
-          return true;
-      }
-
-      return !!color;
-  };
-
-  Color.prototype.isColor = true;
-
-  // JSON.stringify([].slice.call($$('.named-color-table tr'), 1).map(function(row) { return [row.childNodes[3].textContent, row.childNodes[5].textContent.trim().split(",").map(Number)] }).reduce(function(data, row) {data[row[0]] = row[1]; return data}, {}))
-  var colors = {
-      "aliceblue": [240, 248, 255],
-      "antiquewhite": [250, 235, 215],
-      "aqua": [0, 255, 255],
-      "aquamarine": [127, 255, 212],
-      "azure": [240, 255, 255],
-      "beige": [245, 245, 220],
-      "bisque": [255, 228, 196],
-      "black": [0, 0, 0],
-      "blanchedalmond": [255, 235, 205],
-      "blue": [0, 0, 255],
-      "blueviolet": [138, 43, 226],
-      "brown": [165, 42, 42],
-      "burlywood": [222, 184, 135],
-      "cadetblue": [95, 158, 160],
-      "chartreuse": [127, 255, 0],
-      "chocolate": [210, 105, 30],
-      "coral": [255, 127, 80],
-      "cornflowerblue": [100, 149, 237],
-      "cornsilk": [255, 248, 220],
-      "crimson": [220, 20, 60],
-      "cyan": [0, 255, 255],
-      "darkblue": [0, 0, 139],
-      "darkcyan": [0, 139, 139],
-      "darkgoldenrod": [184, 134, 11],
-      "darkgray": [169, 169, 169],
-      "darkgreen": [0, 100, 0],
-      "darkgrey": [169, 169, 169],
-      "darkkhaki": [189, 183, 107],
-      "darkmagenta": [139, 0, 139],
-      "darkolivegreen": [85, 107, 47],
-      "darkorange": [255, 140, 0],
-      "darkorchid": [153, 50, 204],
-      "darkred": [139, 0, 0],
-      "darksalmon": [233, 150, 122],
-      "darkseagreen": [143, 188, 143],
-      "darkslateblue": [72, 61, 139],
-      "darkslategray": [47, 79, 79],
-      "darkslategrey": [47, 79, 79],
-      "darkturquoise": [0, 206, 209],
-      "darkviolet": [148, 0, 211],
-      "deeppink": [255, 20, 147],
-      "deepskyblue": [0, 191, 255],
-      "dimgray": [105, 105, 105],
-      "dimgrey": [105, 105, 105],
-      "dodgerblue": [30, 144, 255],
-      "firebrick": [178, 34, 34],
-      "floralwhite": [255, 250, 240],
-      "forestgreen": [34, 139, 34],
-      "fuchsia": [255, 0, 255],
-      "gainsboro": [220, 220, 220],
-      "ghostwhite": [248, 248, 255],
-      "gold": [255, 215, 0],
-      "goldenrod": [218, 165, 32],
-      "gray": [128, 128, 128],
-      "green": [0, 128, 0],
-      "greenyellow": [173, 255, 47],
-      "grey": [128, 128, 128],
-      "honeydew": [240, 255, 240],
-      "hotpink": [255, 105, 180],
-      "indianred": [205, 92, 92],
-      "indigo": [75, 0, 130],
-      "ivory": [255, 255, 240],
-      "khaki": [240, 230, 140],
-      "lavender": [230, 230, 250],
-      "lavenderblush": [255, 240, 245],
-      "lawngreen": [124, 252, 0],
-      "lemonchiffon": [255, 250, 205],
-      "lightblue": [173, 216, 230],
-      "lightcoral": [240, 128, 128],
-      "lightcyan": [224, 255, 255],
-      "lightgoldenrodyellow": [250, 250, 210],
-      "lightgray": [211, 211, 211],
-      "lightgreen": [144, 238, 144],
-      "lightgrey": [211, 211, 211],
-      "lightpink": [255, 182, 193],
-      "lightsalmon": [255, 160, 122],
-      "lightseagreen": [32, 178, 170],
-      "lightskyblue": [135, 206, 250],
-      "lightslategray": [119, 136, 153],
-      "lightslategrey": [119, 136, 153],
-      "lightsteelblue": [176, 196, 222],
-      "lightyellow": [255, 255, 224],
-      "lime": [0, 255, 0],
-      "limegreen": [50, 205, 50],
-      "linen": [250, 240, 230],
-      "magenta": [255, 0, 255],
-      "maroon": [128, 0, 0],
-      "mediumaquamarine": [102, 205, 170],
-      "mediumblue": [0, 0, 205],
-      "mediumorchid": [186, 85, 211],
-      "mediumpurple": [147, 112, 219],
-      "mediumseagreen": [60, 179, 113],
-      "mediumslateblue": [123, 104, 238],
-      "mediumspringgreen": [0, 250, 154],
-      "mediumturquoise": [72, 209, 204],
-      "mediumvioletred": [199, 21, 133],
-      "midnightblue": [25, 25, 112],
-      "mintcream": [245, 255, 250],
-      "mistyrose": [255, 228, 225],
-      "moccasin": [255, 228, 181],
-      "navajowhite": [255, 222, 173],
-      "navy": [0, 0, 128],
-      "oldlace": [253, 245, 230],
-      "olive": [128, 128, 0],
-      "olivedrab": [107, 142, 35],
-      "orange": [255, 165, 0],
-      "orangered": [255, 69, 0],
-      "orchid": [218, 112, 214],
-      "palegoldenrod": [238, 232, 170],
-      "palegreen": [152, 251, 152],
-      "paleturquoise": [175, 238, 238],
-      "palevioletred": [219, 112, 147],
-      "papayawhip": [255, 239, 213],
-      "peachpuff": [255, 218, 185],
-      "peru": [205, 133, 63],
-      "pink": [255, 192, 203],
-      "plum": [221, 160, 221],
-      "powderblue": [176, 224, 230],
-      "purple": [128, 0, 128],
-      "rebeccapurple": [102, 51, 153],
-      "red": [255, 0, 0],
-      "rosybrown": [188, 143, 143],
-      "royalblue": [65, 105, 225],
-      "saddlebrown": [139, 69, 19],
-      "salmon": [250, 128, 114],
-      "sandybrown": [244, 164, 96],
-      "seagreen": [46, 139, 87],
-      "seashell": [255, 245, 238],
-      "sienna": [160, 82, 45],
-      "silver": [192, 192, 192],
-      "skyblue": [135, 206, 235],
-      "slateblue": [106, 90, 205],
-      "slategray": [112, 128, 144],
-      "slategrey": [112, 128, 144],
-      "snow": [255, 250, 250],
-      "springgreen": [0, 255, 127],
-      "steelblue": [70, 130, 180],
-      "tan": [210, 180, 140],
-      "teal": [0, 128, 128],
-      "thistle": [216, 191, 216],
-      "tomato": [255, 99, 71],
-      "turquoise": [64, 224, 208],
-      "violet": [238, 130, 238],
-      "wheat": [245, 222, 179],
-      "white": [255, 255, 255],
-      "whitesmoke": [245, 245, 245],
-      "yellow": [255, 255, 0],
-      "yellowgreen": [154, 205, 50]
-  };
-
-  module.exports = Color;
-
-  },{}],4:[function(_dereq_,module,exports){
-  var Support = _dereq_('./support');
-  var CanvasRenderer = _dereq_('./renderers/canvas');
-  var ImageLoader = _dereq_('./imageloader');
-  var NodeParser = _dereq_('./nodeparser');
-  var NodeContainer = _dereq_('./nodecontainer');
-  var log = _dereq_('./log');
-  var utils = _dereq_('./utils');
-  var createWindowClone = _dereq_('./clone');
-  var loadUrlDocument = _dereq_('./proxy').loadUrlDocument;
-  var getBounds = utils.getBounds;
-
-  var html2canvasNodeAttribute = "data-html2canvas-node";
-  var html2canvasCloneIndex = 0;
-
-  function html2canvas(nodeList, options) {
-      var index = html2canvasCloneIndex++;
-      options = options || {};
-      if (options.logging) {
-          log.options.logging = true;
-          log.options.start = Date.now();
-      }
-
-      options.async = typeof(options.async) === "undefined" ? true : options.async;
-      options.allowTaint = typeof(options.allowTaint) === "undefined" ? false : options.allowTaint;
-      options.removeContainer = typeof(options.removeContainer) === "undefined" ? true : options.removeContainer;
-      options.javascriptEnabled = typeof(options.javascriptEnabled) === "undefined" ? false : options.javascriptEnabled;
-      options.imageTimeout = typeof(options.imageTimeout) === "undefined" ? 10000 : options.imageTimeout;
-      options.renderer = typeof(options.renderer) === "function" ? options.renderer : CanvasRenderer;
-      options.strict = !!options.strict;
-
-      if (typeof(nodeList) === "string") {
-          if (typeof(options.proxy) !== "string") {
-              return Promise.reject("Proxy must be used when rendering url");
-          }
-          var width = options.width != null ? options.width : window.innerWidth;
-          var height = options.height != null ? options.height : window.innerHeight;
-          return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, width, height, options).then(function(container) {
-              return renderWindow(container.contentWindow.document.documentElement, container, options, width, height);
-          });
-      }
-
-      var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0];
-      node.setAttribute(html2canvasNodeAttribute + index, index);
-      return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) {
-          if (typeof(options.onrendered) === "function") {
-              log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
-              options.onrendered(canvas);
-          }
-          return canvas;
-      });
-  }
-
-  html2canvas.CanvasRenderer = CanvasRenderer;
-  html2canvas.NodeContainer = NodeContainer;
-  html2canvas.log = log;
-  html2canvas.utils = utils;
-
-  var html2canvasExport = (typeof(document) === "undefined" || typeof(Object.create) !== "function" || typeof(document.createElement("canvas").getContext) !== "function") ? function() {
-      return Promise.reject("No canvas support");
-  } : html2canvas;
-
-  module.exports = html2canvasExport;
-
-  if (typeof(define) === 'function' && define.amd && false) {
-      define('html2canvas', [], function() {
-          return html2canvasExport;
-      });
-  }
-
-  function renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) {
-      return createWindowClone(document, document, windowWidth, windowHeight, options, document.defaultView.pageXOffset, document.defaultView.pageYOffset).then(function(container) {
-          log("Document cloned");
-          var attributeName = html2canvasNodeAttribute + html2canvasIndex;
-          var selector = "[" + attributeName + "='" + html2canvasIndex + "']";
-          document.querySelector(selector).removeAttribute(attributeName);
-          var clonedWindow = container.contentWindow;
-          var node = clonedWindow.document.querySelector(selector);
-          var oncloneHandler = (typeof(options.onclone) === "function") ? Promise.resolve(options.onclone(clonedWindow.document)) : Promise.resolve(true);
-          return oncloneHandler.then(function() {
-              return renderWindow(node, container, options, windowWidth, windowHeight);
-          });
-      });
-  }
-
-  function renderWindow(node, container, options, windowWidth, windowHeight) {
-      var clonedWindow = container.contentWindow;
-      var support = new Support(clonedWindow.document);
-      var imageLoader = new ImageLoader(options, support);
-      var bounds = getBounds(node);
-      var width = options.type === "view" ? windowWidth : documentWidth(clonedWindow.document);
-      var height = options.type === "view" ? windowHeight : documentHeight(clonedWindow.document);
-      var renderer = new options.renderer(width, height, imageLoader, options, document);
-      var parser = new NodeParser(node, renderer, support, imageLoader, options);
-      return parser.ready.then(function() {
-          log("Finished rendering");
-          var canvas;
-
-          if (options.type === "view") {
-              canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0});
-          } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement || options.canvas != null) {
-              canvas = renderer.canvas;
-          } else {
-              canvas = crop(renderer.canvas, {width:  options.width != null ? options.width : bounds.width, height: options.height != null ? options.height : bounds.height, top: bounds.top, left: bounds.left, x: 0, y: 0});
-          }
-
-          cleanupContainer(container, options);
-          return canvas;
-      });
-  }
-
-  function cleanupContainer(container, options) {
-      if (options.removeContainer) {
-          container.parentNode.removeChild(container);
-          log("Cleaned up container");
-      }
-  }
-
-  function crop(canvas, bounds) {
-      var croppedCanvas = document.createElement("canvas");
-      var x1 = Math.min(canvas.width - 1, Math.max(0, bounds.left));
-      var x2 = Math.min(canvas.width, Math.max(1, bounds.left + bounds.width));
-      var y1 = Math.min(canvas.height - 1, Math.max(0, bounds.top));
-      var y2 = Math.min(canvas.height, Math.max(1, bounds.top + bounds.height));
-      croppedCanvas.width = bounds.width;
-      croppedCanvas.height =  bounds.height;
-      var width = x2-x1;
-      var height = y2-y1;
-      log("Cropping canvas at:", "left:", bounds.left, "top:", bounds.top, "width:", width, "height:", height);
-      log("Resulting crop with width", bounds.width, "and height", bounds.height, "with x", x1, "and y", y1);
-      croppedCanvas.getContext("2d").drawImage(canvas, x1, y1, width, height, bounds.x, bounds.y, width, height);
-      return croppedCanvas;
-  }
-
-  function documentWidth (doc) {
-      return Math.max(
-          Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth),
-          Math.max(doc.body.offsetWidth, doc.documentElement.offsetWidth),
-          Math.max(doc.body.clientWidth, doc.documentElement.clientWidth)
-      );
-  }
-
-  function documentHeight (doc) {
-      return Math.max(
-          Math.max(doc.body.scrollHeight, doc.documentElement.scrollHeight),
-          Math.max(doc.body.offsetHeight, doc.documentElement.offsetHeight),
-          Math.max(doc.body.clientHeight, doc.documentElement.clientHeight)
-      );
-  }
-
-  function absoluteUrl(url) {
-      var link = document.createElement("a");
-      link.href = url;
-      link.href = link.href;
-      return link;
-  }
-
-  },{"./clone":2,"./imageloader":11,"./log":13,"./nodecontainer":14,"./nodeparser":15,"./proxy":16,"./renderers/canvas":20,"./support":22,"./utils":26}],5:[function(_dereq_,module,exports){
-  var log = _dereq_('./log');
-  var smallImage = _dereq_('./utils').smallImage;
-
-  function DummyImageContainer(src) {
-      this.src = src;
-      log("DummyImageContainer for", src);
-      if (!this.promise || !this.image) {
-          log("Initiating DummyImageContainer");
-          DummyImageContainer.prototype.image = new Image();
-          var image = this.image;
-          DummyImageContainer.prototype.promise = new Promise(function(resolve, reject) {
-              image.onload = resolve;
-              image.onerror = reject;
-              image.src = smallImage();
-              if (image.complete === true) {
-                  resolve(image);
-              }
-          });
-      }
-  }
-
-  module.exports = DummyImageContainer;
-
-  },{"./log":13,"./utils":26}],6:[function(_dereq_,module,exports){
-  var smallImage = _dereq_('./utils').smallImage;
-
-  function Font(family, size) {
-      var container = document.createElement('div'),
-          img = document.createElement('img'),
-          span = document.createElement('span'),
-          sampleText = 'Hidden Text',
-          baseline,
-          middle;
-
-      container.style.visibility = "hidden";
-      container.style.fontFamily = family;
-      container.style.fontSize = size;
-      container.style.margin = 0;
-      container.style.padding = 0;
-
-      document.body.appendChild(container);
-
-      img.src = smallImage();
-      img.width = 1;
-      img.height = 1;
-
-      img.style.margin = 0;
-      img.style.padding = 0;
-      img.style.verticalAlign = "baseline";
-
-      span.style.fontFamily = family;
-      span.style.fontSize = size;
-      span.style.margin = 0;
-      span.style.padding = 0;
-
-      span.appendChild(document.createTextNode(sampleText));
-      container.appendChild(span);
-      container.appendChild(img);
-      baseline = (img.offsetTop - span.offsetTop) + 1;
-
-      container.removeChild(span);
-      container.appendChild(document.createTextNode(sampleText));
-
-      container.style.lineHeight = "normal";
-      img.style.verticalAlign = "super";
-
-      middle = (img.offsetTop-container.offsetTop) + 1;
-
-      document.body.removeChild(container);
-
-      this.baseline = baseline;
-      this.lineWidth = 1;
-      this.middle = middle;
-  }
-
-  module.exports = Font;
-
-  },{"./utils":26}],7:[function(_dereq_,module,exports){
-  var Font = _dereq_('./font');
-
-  function FontMetrics() {
-      this.data = {};
-  }
-
-  FontMetrics.prototype.getMetrics = function(family, size) {
-      if (this.data[family + "-" + size] === undefined) {
-          this.data[family + "-" + size] = new Font(family, size);
-      }
-      return this.data[family + "-" + size];
-  };
-
-  module.exports = FontMetrics;
-
-  },{"./font":6}],8:[function(_dereq_,module,exports){
-  var utils = _dereq_('./utils');
-  var getBounds = utils.getBounds;
-  var loadUrlDocument = _dereq_('./proxy').loadUrlDocument;
-
-  function FrameContainer(container, sameOrigin, options) {
-      this.image = null;
-      this.src = container;
-      var self = this;
-      var bounds = getBounds(container);
-      this.promise = (!sameOrigin ? this.proxyLoad(options.proxy, bounds, options) : new Promise(function(resolve) {
-          if (container.contentWindow.document.URL === "about:blank" || container.contentWindow.document.documentElement == null) {
-              container.contentWindow.onload = container.onload = function() {
-                  resolve(container);
-              };
-          } else {
-              resolve(container);
-          }
-      })).then(function(container) {
-          var html2canvas = _dereq_('./core');
-          return html2canvas(container.contentWindow.document.documentElement, {type: 'view', width: container.width, height: container.height, proxy: options.proxy, javascriptEnabled: options.javascriptEnabled, removeContainer: options.removeContainer, allowTaint: options.allowTaint, imageTimeout: options.imageTimeout / 2});
-      }).then(function(canvas) {
-          return self.image = canvas;
-      });
-  }
-
-  FrameContainer.prototype.proxyLoad = function(proxy, bounds, options) {
-      var container = this.src;
-      return loadUrlDocument(container.src, proxy, container.ownerDocument, bounds.width, bounds.height, options);
-  };
-
-  module.exports = FrameContainer;
-
-  },{"./core":4,"./proxy":16,"./utils":26}],9:[function(_dereq_,module,exports){
-  function GradientContainer(imageData) {
-      this.src = imageData.value;
-      this.colorStops = [];
-      this.type = null;
-      this.x0 = 0.5;
-      this.y0 = 0.5;
-      this.x1 = 0.5;
-      this.y1 = 0.5;
-      this.promise = Promise.resolve(true);
-  }
-
-  GradientContainer.TYPES = {
-      LINEAR: 1,
-      RADIAL: 2
-  };
-
-  // TODO: support hsl[a], negative %/length values
-  // TODO: support <angle> (e.g. -?\d{1,3}(?:\.\d+)deg, etc. : https://developer.mozilla.org/docs/Web/CSS/angle )
-  GradientContainer.REGEXP_COLORSTOP = /^\s*(rgba?\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3}(?:,\s*[0-9\.]+)?\s*\)|[a-z]{3,20}|#[a-f0-9]{3,6})(?:\s+(\d{1,3}(?:\.\d+)?)(%|px)?)?(?:\s|$)/i;
-
-  module.exports = GradientContainer;
-
-  },{}],10:[function(_dereq_,module,exports){
-  function ImageContainer(src, cors) {
-      this.src = src;
-      this.image = new Image();
-      var self = this;
-      this.tainted = null;
-      this.promise = new Promise(function(resolve, reject) {
-          self.image.onload = resolve;
-          self.image.onerror = reject;
-          if (cors) {
-              self.image.crossOrigin = "anonymous";
-          }
-          self.image.src = src;
-          if (self.image.complete === true) {
-              resolve(self.image);
-          }
-      });
-  }
-
-  module.exports = ImageContainer;
-
-  },{}],11:[function(_dereq_,module,exports){
-  var log = _dereq_('./log');
-  var ImageContainer = _dereq_('./imagecontainer');
-  var DummyImageContainer = _dereq_('./dummyimagecontainer');
-  var ProxyImageContainer = _dereq_('./proxyimagecontainer');
-  var FrameContainer = _dereq_('./framecontainer');
-  var SVGContainer = _dereq_('./svgcontainer');
-  var SVGNodeContainer = _dereq_('./svgnodecontainer');
-  var LinearGradientContainer = _dereq_('./lineargradientcontainer');
-  var WebkitGradientContainer = _dereq_('./webkitgradientcontainer');
-  var bind = _dereq_('./utils').bind;
-
-  function ImageLoader(options, support) {
-      this.link = null;
-      this.options = options;
-      this.support = support;
-      this.origin = this.getOrigin(window.location.href);
-  }
-
-  ImageLoader.prototype.findImages = function(nodes) {
-      var images = [];
-      nodes.reduce(function(imageNodes, container) {
-          switch(container.node.nodeName) {
-          case "IMG":
-              return imageNodes.concat([{
-                  args: [container.node.src],
-                  method: "url"
-              }]);
-          case "svg":
-          case "IFRAME":
-              return imageNodes.concat([{
-                  args: [container.node],
-                  method: container.node.nodeName
-              }]);
-          }
-          return imageNodes;
-      }, []).forEach(this.addImage(images, this.loadImage), this);
-      return images;
-  };
-
-  ImageLoader.prototype.findBackgroundImage = function(images, container) {
-      container.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(images, this.loadImage), this);
-      return images;
-  };
-
-  ImageLoader.prototype.addImage = function(images, callback) {
-      return function(newImage) {
-          newImage.args.forEach(function(image) {
-              if (!this.imageExists(images, image)) {
-                  images.splice(0, 0, callback.call(this, newImage));
-                  log('Added image #' + (images.length), typeof(image) === "string" ? image.substring(0, 100) : image);
-              }
-          }, this);
-      };
-  };
-
-  ImageLoader.prototype.hasImageBackground = function(imageData) {
-      return imageData.method !== "none";
-  };
-
-  ImageLoader.prototype.loadImage = function(imageData) {
-      if (imageData.method === "url") {
-          var src = imageData.args[0];
-          if (this.isSVG(src) && !this.support.svg && !this.options.allowTaint) {
-              return new SVGContainer(src);
-          } else if (src.match(/data:image\/.*;base64,/i)) {
-              return new ImageContainer(src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''), false);
-          } else if (this.isSameOrigin(src) || this.options.allowTaint === true || this.isSVG(src)) {
-              return new ImageContainer(src, false);
-          } else if (this.support.cors && !this.options.allowTaint && this.options.useCORS) {
-              return new ImageContainer(src, true);
-          } else if (this.options.proxy) {
-              return new ProxyImageContainer(src, this.options.proxy);
-          } else {
-              return new DummyImageContainer(src);
-          }
-      } else if (imageData.method === "linear-gradient") {
-          return new LinearGradientContainer(imageData);
-      } else if (imageData.method === "gradient") {
-          return new WebkitGradientContainer(imageData);
-      } else if (imageData.method === "svg") {
-          return new SVGNodeContainer(imageData.args[0], this.support.svg);
-      } else if (imageData.method === "IFRAME") {
-          return new FrameContainer(imageData.args[0], this.isSameOrigin(imageData.args[0].src), this.options);
-      } else {
-          return new DummyImageContainer(imageData);
-      }
-  };
-
-  ImageLoader.prototype.isSVG = function(src) {
-      return src.substring(src.length - 3).toLowerCase() === "svg" || SVGContainer.prototype.isInline(src);
-  };
-
-  ImageLoader.prototype.imageExists = function(images, src) {
-      return images.some(function(image) {
-          return image.src === src;
-      });
-  };
-
-  ImageLoader.prototype.isSameOrigin = function(url) {
-      return (this.getOrigin(url) === this.origin);
-  };
-
-  ImageLoader.prototype.getOrigin = function(url) {
-      var link = this.link || (this.link = document.createElement("a"));
-      link.href = url;
-      link.href = link.href; // IE9, LOL! - http://jsfiddle.net/niklasvh/2e48b/
-      return link.protocol + link.hostname + link.port;
-  };
-
-  ImageLoader.prototype.getPromise = function(container) {
-      return this.timeout(container, this.options.imageTimeout)['catch'](function() {
-          var dummy = new DummyImageContainer(container.src);
-          return dummy.promise.then(function(image) {
-              container.image = image;
-          });
-      });
-  };
-
-  ImageLoader.prototype.get = function(src) {
-      var found = null;
-      return this.images.some(function(img) {
-          return (found = img).src === src;
-      }) ? found : null;
-  };
-
-  ImageLoader.prototype.fetch = function(nodes) {
-      this.images = nodes.reduce(bind(this.findBackgroundImage, this), this.findImages(nodes));
-      this.images.forEach(function(image, index) {
-          image.promise.then(function() {
-              log("Succesfully loaded image #"+ (index+1), image);
-          }, function(e) {
-              log("Failed loading image #"+ (index+1), image, e);
-          });
-      });
-      this.ready = Promise.all(this.images.map(this.getPromise, this));
-      log("Finished searching images");
-      return this;
-  };
-
-  ImageLoader.prototype.timeout = function(container, timeout) {
-      var timer;
-      var promise = Promise.race([container.promise, new Promise(function(res, reject) {
-          timer = setTimeout(function() {
-              log("Timed out loading image", container);
-              reject(container);
-          }, timeout);
-      })]).then(function(container) {
-          clearTimeout(timer);
-          return container;
-      });
-      promise['catch'](function() {
-          clearTimeout(timer);
-      });
-      return promise;
-  };
-
-  module.exports = ImageLoader;
-
-  },{"./dummyimagecontainer":5,"./framecontainer":8,"./imagecontainer":10,"./lineargradientcontainer":12,"./log":13,"./proxyimagecontainer":17,"./svgcontainer":23,"./svgnodecontainer":24,"./utils":26,"./webkitgradientcontainer":27}],12:[function(_dereq_,module,exports){
-  var GradientContainer = _dereq_('./gradientcontainer');
-  var Color = _dereq_('./color');
-
-  function LinearGradientContainer(imageData) {
-      GradientContainer.apply(this, arguments);
-      this.type = GradientContainer.TYPES.LINEAR;
-
-      var hasDirection = LinearGradientContainer.REGEXP_DIRECTION.test( imageData.args[0] ) ||
-          !GradientContainer.REGEXP_COLORSTOP.test( imageData.args[0] );
-
-      if (hasDirection) {
-          imageData.args[0].split(/\s+/).reverse().forEach(function(position, index) {
-              switch(position) {
-              case "left":
-                  this.x0 = 0;
-                  this.x1 = 1;
-                  break;
-              case "top":
-                  this.y0 = 0;
-                  this.y1 = 1;
-                  break;
-              case "right":
-                  this.x0 = 1;
-                  this.x1 = 0;
-                  break;
-              case "bottom":
-                  this.y0 = 1;
-                  this.y1 = 0;
-                  break;
-              case "to":
-                  var y0 = this.y0;
-                  var x0 = this.x0;
-                  this.y0 = this.y1;
-                  this.x0 = this.x1;
-                  this.x1 = x0;
-                  this.y1 = y0;
-                  break;
-              case "center":
-                  break; // centered by default
-              // Firefox internally converts position keywords to percentages:
-              // http://www.w3.org/TR/2010/WD-CSS2-20101207/colors.html#propdef-background-position
-              default: // percentage or absolute length
-                  // TODO: support absolute start point positions (e.g., use bounds to convert px to a ratio)
-                  var ratio = parseFloat(position, 10) * 1e-2;
-                  if (isNaN(ratio)) { // invalid or unhandled value
-                      break;
-                  }
-                  if (index === 0) {
-                      this.y0 = ratio;
-                      this.y1 = 1 - this.y0;
-                  } else {
-                      this.x0 = ratio;
-                      this.x1 = 1 - this.x0;
-                  }
-                  break;
-              }
-          }, this);
-      } else {
-          this.y0 = 0;
-          this.y1 = 1;
-      }
-
-      this.colorStops = imageData.args.slice(hasDirection ? 1 : 0).map(function(colorStop) {
-          var colorStopMatch = colorStop.match(GradientContainer.REGEXP_COLORSTOP);
-          var value = +colorStopMatch[2];
-          var unit = value === 0 ? "%" : colorStopMatch[3]; // treat "0" as "0%"
-          return {
-              color: new Color(colorStopMatch[1]),
-              // TODO: support absolute stop positions (e.g., compute gradient line length & convert px to ratio)
-              stop: unit === "%" ? value / 100 : null
-          };
-      });
-
-      if (this.colorStops[0].stop === null) {
-          this.colorStops[0].stop = 0;
-      }
-
-      if (this.colorStops[this.colorStops.length - 1].stop === null) {
-          this.colorStops[this.colorStops.length - 1].stop = 1;
-      }
-
-      // calculates and fills-in explicit stop positions when omitted from rule
-      this.colorStops.forEach(function(colorStop, index) {
-          if (colorStop.stop === null) {
-              this.colorStops.slice(index).some(function(find, count) {
-                  if (find.stop !== null) {
-                      colorStop.stop = ((find.stop - this.colorStops[index - 1].stop) / (count + 1)) + this.colorStops[index - 1].stop;
-                      return true;
-                  } else {
-                      return false;
-                  }
-              }, this);
-          }
-      }, this);
-  }
-
-  LinearGradientContainer.prototype = Object.create(GradientContainer.prototype);
-
-  // TODO: support <angle> (e.g. -?\d{1,3}(?:\.\d+)deg, etc. : https://developer.mozilla.org/docs/Web/CSS/angle )
-  LinearGradientContainer.REGEXP_DIRECTION = /^\s*(?:to|left|right|top|bottom|center|\d{1,3}(?:\.\d+)?%?)(?:\s|$)/i;
-
-  module.exports = LinearGradientContainer;
-
-  },{"./color":3,"./gradientcontainer":9}],13:[function(_dereq_,module,exports){
-  var logger = function() {
-      if (logger.options.logging && window.console && window.console.log) {
-          Function.prototype.bind.call(window.console.log, (window.console)).apply(window.console, [(Date.now() - logger.options.start) + "ms", "html2canvas:"].concat([].slice.call(arguments, 0)));
-      }
-  };
-
-  logger.options = {logging: false};
-  module.exports = logger;
-
-  },{}],14:[function(_dereq_,module,exports){
-  var Color = _dereq_('./color');
-  var utils = _dereq_('./utils');
-  var getBounds = utils.getBounds;
-  var parseBackgrounds = utils.parseBackgrounds;
-  var offsetBounds = utils.offsetBounds;
-
-  function NodeContainer(node, parent) {
-      this.node = node;
-      this.parent = parent;
-      this.stack = null;
-      this.bounds = null;
-      this.borders = null;
-      this.clip = [];
-      this.backgroundClip = [];
-      this.offsetBounds = null;
-      this.visible = null;
-      this.computedStyles = null;
-      this.colors = {};
-      this.styles = {};
-      this.backgroundImages = null;
-      this.transformData = null;
-      this.transformMatrix = null;
-      this.isPseudoElement = false;
-      this.opacity = null;
-  }
-
-  NodeContainer.prototype.cloneTo = function(stack) {
-      stack.visible = this.visible;
-      stack.borders = this.borders;
-      stack.bounds = this.bounds;
-      stack.clip = this.clip;
-      stack.backgroundClip = this.backgroundClip;
-      stack.computedStyles = this.computedStyles;
-      stack.styles = this.styles;
-      stack.backgroundImages = this.backgroundImages;
-      stack.opacity = this.opacity;
-  };
-
-  NodeContainer.prototype.getOpacity = function() {
-      return this.opacity === null ? (this.opacity = this.cssFloat('opacity')) : this.opacity;
-  };
-
-  NodeContainer.prototype.assignStack = function(stack) {
-      this.stack = stack;
-      stack.children.push(this);
-  };
-
-  NodeContainer.prototype.isElementVisible = function() {
-      return this.node.nodeType === Node.TEXT_NODE ? this.parent.visible : (
-          this.css('display') !== "none" &&
-          this.css('visibility') !== "hidden" &&
-          !this.node.hasAttribute("data-html2canvas-ignore") &&
-          (this.node.nodeName !== "INPUT" || this.node.getAttribute("type") !== "hidden")
-      );
-  };
-
-  NodeContainer.prototype.css = function(attribute) {
-      if (!this.computedStyles) {
-          this.computedStyles = this.isPseudoElement ? this.parent.computedStyle(this.before ? ":before" : ":after") : this.computedStyle(null);
-      }
-
-      return this.styles[attribute] || (this.styles[attribute] = this.computedStyles[attribute]);
-  };
-
-  NodeContainer.prototype.prefixedCss = function(attribute) {
-      var prefixes = ["webkit", "moz", "ms", "o"];
-      var value = this.css(attribute);
-      if (value === undefined) {
-          prefixes.some(function(prefix) {
-              value = this.css(prefix + attribute.substr(0, 1).toUpperCase() + attribute.substr(1));
-              return value !== undefined;
-          }, this);
-      }
-      return value === undefined ? null : value;
-  };
-
-  NodeContainer.prototype.computedStyle = function(type) {
-      return this.node.ownerDocument.defaultView.getComputedStyle(this.node, type);
-  };
-
-  NodeContainer.prototype.cssInt = function(attribute) {
-      var value = parseInt(this.css(attribute), 10);
-      return (isNaN(value)) ? 0 : value; // borders in old IE are throwing 'medium' for demo.html
-  };
-
-  NodeContainer.prototype.color = function(attribute) {
-      return this.colors[attribute] || (this.colors[attribute] = new Color(this.css(attribute)));
-  };
-
-  NodeContainer.prototype.cssFloat = function(attribute) {
-      var value = parseFloat(this.css(attribute));
-      return (isNaN(value)) ? 0 : value;
-  };
-
-  NodeContainer.prototype.fontWeight = function() {
-      var weight = this.css("fontWeight");
-      switch(parseInt(weight, 10)){
-      case 401:
-          weight = "bold";
-          break;
-      case 400:
-          weight = "normal";
-          break;
-      }
-      return weight;
-  };
-
-  NodeContainer.prototype.parseClip = function() {
-      var matches = this.css('clip').match(this.CLIP);
-      if (matches) {
-          return {
-              top: parseInt(matches[1], 10),
-              right: parseInt(matches[2], 10),
-              bottom: parseInt(matches[3], 10),
-              left: parseInt(matches[4], 10)
-          };
-      }
-      return null;
-  };
-
-  NodeContainer.prototype.parseBackgroundImages = function() {
-      return this.backgroundImages || (this.backgroundImages = parseBackgrounds(this.css("backgroundImage")));
-  };
-
-  NodeContainer.prototype.cssList = function(property, index) {
-      var value = (this.css(property) || '').split(',');
-      value = value[index || 0] || value[0] || 'auto';
-      value = value.trim().split(' ');
-      if (value.length === 1) {
-          value = [value[0], isPercentage(value[0]) ? 'auto' : value[0]];
-      }
-      return value;
-  };
-
-  NodeContainer.prototype.parseBackgroundSize = function(bounds, image, index) {
-      var size = this.cssList("backgroundSize", index);
-      var width, height;
-
-      if (isPercentage(size[0])) {
-          width = bounds.width * parseFloat(size[0]) / 100;
-      } else if (/contain|cover/.test(size[0])) {
-          var targetRatio = bounds.width / bounds.height, currentRatio = image.width / image.height;
-          return (targetRatio < currentRatio ^ size[0] === 'contain') ?  {width: bounds.height * currentRatio, height: bounds.height} : {width: bounds.width, height: bounds.width / currentRatio};
-      } else {
-          width = parseInt(size[0], 10);
-      }
-
-      if (size[0] === 'auto' && size[1] === 'auto') {
-          height = image.height;
-      } else if (size[1] === 'auto') {
-          height = width / image.width * image.height;
-      } else if (isPercentage(size[1])) {
-          height =  bounds.height * parseFloat(size[1]) / 100;
-      } else {
-          height = parseInt(size[1], 10);
-      }
-
-      if (size[0] === 'auto') {
-          width = height / image.height * image.width;
-      }
-
-      return {width: width, height: height};
-  };
-
-  NodeContainer.prototype.parseBackgroundPosition = function(bounds, image, index, backgroundSize) {
-      var position = this.cssList('backgroundPosition', index);
-      var left, top;
-
-      if (isPercentage(position[0])){
-          left = (bounds.width - (backgroundSize || image).width) * (parseFloat(position[0]) / 100);
-      } else {
-          left = parseInt(position[0], 10);
-      }
-
-      if (position[1] === 'auto') {
-          top = left / image.width * image.height;
-      } else if (isPercentage(position[1])){
-          top =  (bounds.height - (backgroundSize || image).height) * parseFloat(position[1]) / 100;
-      } else {
-          top = parseInt(position[1], 10);
-      }
-
-      if (position[0] === 'auto') {
-          left = top / image.height * image.width;
-      }
-
-      return {left: left, top: top};
-  };
-
-  NodeContainer.prototype.parseBackgroundRepeat = function(index) {
-      return this.cssList("backgroundRepeat", index)[0];
-  };
-
-  NodeContainer.prototype.parseTextShadows = function() {
-      var textShadow = this.css("textShadow");
-      var results = [];
-
-      if (textShadow && textShadow !== 'none') {
-          var shadows = textShadow.match(this.TEXT_SHADOW_PROPERTY);
-          for (var i = 0; shadows && (i < shadows.length); i++) {
-              var s = shadows[i].match(this.TEXT_SHADOW_VALUES);
-              results.push({
-                  color: new Color(s[0]),
-                  offsetX: s[1] ? parseFloat(s[1].replace('px', '')) : 0,
-                  offsetY: s[2] ? parseFloat(s[2].replace('px', '')) : 0,
-                  blur: s[3] ? s[3].replace('px', '') : 0
-              });
-          }
-      }
-      return results;
-  };
-
-  NodeContainer.prototype.parseTransform = function() {
-      if (!this.transformData) {
-          if (this.hasTransform()) {
-              var offset = this.parseBounds();
-              var origin = this.prefixedCss("transformOrigin").split(" ").map(removePx).map(asFloat);
-              origin[0] += offset.left;
-              origin[1] += offset.top;
-              this.transformData = {
-                  origin: origin,
-                  matrix: this.parseTransformMatrix()
-              };
-          } else {
-              this.transformData = {
-                  origin: [0, 0],
-                  matrix: [1, 0, 0, 1, 0, 0]
-              };
-          }
-      }
-      return this.transformData;
-  };
-
-  NodeContainer.prototype.parseTransformMatrix = function() {
-      if (!this.transformMatrix) {
-          var transform = this.prefixedCss("transform");
-          var matrix = transform ? parseMatrix(transform.match(this.MATRIX_PROPERTY)) : null;
-          this.transformMatrix = matrix ? matrix : [1, 0, 0, 1, 0, 0];
-      }
-      return this.transformMatrix;
-  };
-
-  NodeContainer.prototype.parseBounds = function() {
-      return this.bounds || (this.bounds = this.hasTransform() ? offsetBounds(this.node) : getBounds(this.node));
-  };
-
-  NodeContainer.prototype.hasTransform = function() {
-      return this.parseTransformMatrix().join(",") !== "1,0,0,1,0,0" || (this.parent && this.parent.hasTransform());
-  };
-
-  NodeContainer.prototype.getValue = function() {
-      var value = this.node.value || "";
-      if (this.node.tagName === "SELECT") {
-          value = selectionValue(this.node);
-      } else if (this.node.type === "password") {
-          value = Array(value.length + 1).join('\u2022'); // jshint ignore:line
-      }
-      return value.length === 0 ? (this.node.placeholder || "") : value;
-  };
-
-  NodeContainer.prototype.MATRIX_PROPERTY = /(matrix|matrix3d)\((.+)\)/;
-  NodeContainer.prototype.TEXT_SHADOW_PROPERTY = /((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g;
-  NodeContainer.prototype.TEXT_SHADOW_VALUES = /(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g;
-  NodeContainer.prototype.CLIP = /^rect\((\d+)px,? (\d+)px,? (\d+)px,? (\d+)px\)$/;
-
-  function selectionValue(node) {
-      var option = node.options[node.selectedIndex || 0];
-      return option ? (option.text || "") : "";
-  }
-
-  function parseMatrix(match) {
-      if (match && match[1] === "matrix") {
-          return match[2].split(",").map(function(s) {
-              return parseFloat(s.trim());
-          });
-      } else if (match && match[1] === "matrix3d") {
-          var matrix3d = match[2].split(",").map(function(s) {
-            return parseFloat(s.trim());
-          });
-          return [matrix3d[0], matrix3d[1], matrix3d[4], matrix3d[5], matrix3d[12], matrix3d[13]];
-      }
-  }
-
-  function isPercentage(value) {
-      return value.toString().indexOf("%") !== -1;
-  }
-
-  function removePx(str) {
-      return str.replace("px", "");
-  }
-
-  function asFloat(str) {
-      return parseFloat(str);
-  }
-
-  module.exports = NodeContainer;
-
-  },{"./color":3,"./utils":26}],15:[function(_dereq_,module,exports){
-  var log = _dereq_('./log');
-  var punycode = _dereq_('punycode');
-  var NodeContainer = _dereq_('./nodecontainer');
-  var TextContainer = _dereq_('./textcontainer');
-  var PseudoElementContainer = _dereq_('./pseudoelementcontainer');
-  var FontMetrics = _dereq_('./fontmetrics');
-  var Color = _dereq_('./color');
-  var StackingContext = _dereq_('./stackingcontext');
-  var utils = _dereq_('./utils');
-  var bind = utils.bind;
-  var getBounds = utils.getBounds;
-  var parseBackgrounds = utils.parseBackgrounds;
-  var offsetBounds = utils.offsetBounds;
-
-  function NodeParser(element, renderer, support, imageLoader, options) {
-      log("Starting NodeParser");
-      this.renderer = renderer;
-      this.options = options;
-      this.range = null;
-      this.support = support;
-      this.renderQueue = [];
-      this.stack = new StackingContext(true, 1, element.ownerDocument, null);
-      var parent = new NodeContainer(element, null);
-      if (options.background) {
-          renderer.rectangle(0, 0, renderer.width, renderer.height, new Color(options.background));
-      }
-      if (element === element.ownerDocument.documentElement) {
-          // http://www.w3.org/TR/css3-background/#special-backgrounds
-          var canvasBackground = new NodeContainer(parent.color('backgroundColor').isTransparent() ? element.ownerDocument.body : element.ownerDocument.documentElement, null);
-          renderer.rectangle(0, 0, renderer.width, renderer.height, canvasBackground.color('backgroundColor'));
-      }
-      parent.visibile = parent.isElementVisible();
-      this.createPseudoHideStyles(element.ownerDocument);
-      this.disableAnimations(element.ownerDocument);
-      this.nodes = flatten([parent].concat(this.getChildren(parent)).filter(function(container) {
-          return container.visible = container.isElementVisible();
-      }).map(this.getPseudoElements, this));
-      this.fontMetrics = new FontMetrics();
-      log("Fetched nodes, total:", this.nodes.length);
-      log("Calculate overflow clips");
-      this.calculateOverflowClips();
-      log("Start fetching images");
-      this.images = imageLoader.fetch(this.nodes.filter(isElement));
-      this.ready = this.images.ready.then(bind(function() {
-          log("Images loaded, starting parsing");
-          log("Creating stacking contexts");
-          this.createStackingContexts();
-          log("Sorting stacking contexts");
-          this.sortStackingContexts(this.stack);
-          this.parse(this.stack);
-          log("Render queue created with " + this.renderQueue.length + " items");
-          return new Promise(bind(function(resolve) {
-              if (!options.async) {
-                  this.renderQueue.forEach(this.paint, this);
-                  resolve();
-              } else if (typeof(options.async) === "function") {
-                  options.async.call(this, this.renderQueue, resolve);
-              } else if (this.renderQueue.length > 0){
-                  this.renderIndex = 0;
-                  this.asyncRenderer(this.renderQueue, resolve);
-              } else {
-                  resolve();
-              }
-          }, this));
-      }, this));
-  }
-
-  NodeParser.prototype.calculateOverflowClips = function() {
-      this.nodes.forEach(function(container) {
-          if (isElement(container)) {
-              if (isPseudoElement(container)) {
-                  container.appendToDOM();
-              }
-              container.borders = this.parseBorders(container);
-              var clip = (container.css('overflow') === "hidden") ? [container.borders.clip] : [];
-              var cssClip = container.parseClip();
-              if (cssClip && ["absolute", "fixed"].indexOf(container.css('position')) !== -1) {
-                  clip.push([["rect",
-                          container.bounds.left + cssClip.left,
-                          container.bounds.top + cssClip.top,
-                          cssClip.right - cssClip.left,
-                          cssClip.bottom - cssClip.top
-                  ]]);
-              }
-              container.clip = hasParentClip(container) ? container.parent.clip.concat(clip) : clip;
-              container.backgroundClip = (container.css('overflow') !== "hidden") ? container.clip.concat([container.borders.clip]) : container.clip;
-              if (isPseudoElement(container)) {
-                  container.cleanDOM();
-              }
-          } else if (isTextNode(container)) {
-              container.clip = hasParentClip(container) ? container.parent.clip : [];
-          }
-          if (!isPseudoElement(container)) {
-              container.bounds = null;
-          }
-      }, this);
-  };
-
-  function hasParentClip(container) {
-      return container.parent && container.parent.clip.length;
-  }
-
-  NodeParser.prototype.asyncRenderer = function(queue, resolve, asyncTimer) {
-      asyncTimer = asyncTimer || Date.now();
-      this.paint(queue[this.renderIndex++]);
-      if (queue.length === this.renderIndex) {
-          resolve();
-      } else if (asyncTimer + 20 > Date.now()) {
-          this.asyncRenderer(queue, resolve, asyncTimer);
-      } else {
-          setTimeout(bind(function() {
-              this.asyncRenderer(queue, resolve);
-          }, this), 0);
-      }
-  };
-
-  NodeParser.prototype.createPseudoHideStyles = function(document) {
-      this.createStyles(document, '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + ':before { content: "" !important; display: none !important; }' +
-          '.' + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER + ':after { content: "" !important; display: none !important; }');
-  };
-
-  NodeParser.prototype.disableAnimations = function(document) {
-      this.createStyles(document, '* { -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; animation: none !important; ' +
-          '-webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important;}');
-  };
-
-  NodeParser.prototype.createStyles = function(document, styles) {
-      var hidePseudoElements = document.createElement('style');
-      hidePseudoElements.innerHTML = styles;
-      document.body.appendChild(hidePseudoElements);
-  };
-
-  NodeParser.prototype.getPseudoElements = function(container) {
-      var nodes = [[container]];
-      if (container.node.nodeType === Node.ELEMENT_NODE) {
-          var before = this.getPseudoElement(container, ":before");
-          var after = this.getPseudoElement(container, ":after");
-
-          if (before) {
-              nodes.push(before);
-          }
-
-          if (after) {
-              nodes.push(after);
-          }
-      }
-      return flatten(nodes);
-  };
-
-  function toCamelCase(str) {
-      return str.replace(/(\-[a-z])/g, function(match){
-          return match.toUpperCase().replace('-','');
-      });
-  }
-
-  NodeParser.prototype.getPseudoElement = function(container, type) {
-      var style = container.computedStyle(type);
-      if(!style || !style.content || style.content === "none" || style.content === "-moz-alt-content" || style.display === "none") {
-          return null;
-      }
-
-      var content = stripQuotes(style.content);
-      var isImage = content.substr(0, 3) === 'url';
-      var pseudoNode = document.createElement(isImage ? 'img' : 'html2canvaspseudoelement');
-      var pseudoContainer = new PseudoElementContainer(pseudoNode, container, type);
-
-      for (var i = style.length-1; i >= 0; i--) {
-          var property = toCamelCase(style.item(i));
-          pseudoNode.style[property] = style[property];
-      }
-
-      pseudoNode.className = PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE + " " + PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER;
-
-      if (isImage) {
-          pseudoNode.src = parseBackgrounds(content)[0].args[0];
-          return [pseudoContainer];
-      } else {
-          var text = document.createTextNode(content);
-          pseudoNode.appendChild(text);
-          return [pseudoContainer, new TextContainer(text, pseudoContainer)];
-      }
-  };
-
-
-  NodeParser.prototype.getChildren = function(parentContainer) {
-      return flatten([].filter.call(parentContainer.node.childNodes, renderableNode).map(function(node) {
-          var container = [node.nodeType === Node.TEXT_NODE ? new TextContainer(node, parentContainer) : new NodeContainer(node, parentContainer)].filter(nonIgnoredElement);
-          return node.nodeType === Node.ELEMENT_NODE && container.length && node.tagName !== "TEXTAREA" ? (container[0].isElementVisible() ? container.concat(this.getChildren(container[0])) : []) : container;
-      }, this));
-  };
-
-  NodeParser.prototype.newStackingContext = function(container, hasOwnStacking) {
-      var stack = new StackingContext(hasOwnStacking, container.getOpacity(), container.node, container.parent);
-      container.cloneTo(stack);
-      var parentStack = hasOwnStacking ? stack.getParentStack(this) : stack.parent.stack;
-      parentStack.contexts.push(stack);
-      container.stack = stack;
-  };
-
-  NodeParser.prototype.createStackingContexts = function() {
-      this.nodes.forEach(function(container) {
-          if (isElement(container) && (this.isRootElement(container) || hasOpacity(container) || isPositionedForStacking(container) || this.isBodyWithTransparentRoot(container) || container.hasTransform())) {
-              this.newStackingContext(container, true);
-          } else if (isElement(container) && ((isPositioned(container) && zIndex0(container)) || isInlineBlock(container) || isFloating(container))) {
-              this.newStackingContext(container, false);
-          } else {
-              container.assignStack(container.parent.stack);
-          }
-      }, this);
-  };
-
-  NodeParser.prototype.isBodyWithTransparentRoot = function(container) {
-      return container.node.nodeName === "BODY" && container.parent.color('backgroundColor').isTransparent();
-  };
-
-  NodeParser.prototype.isRootElement = function(container) {
-      return container.parent === null;
-  };
-
-  NodeParser.prototype.sortStackingContexts = function(stack) {
-      stack.contexts.sort(zIndexSort(stack.contexts.slice(0)));
-      stack.contexts.forEach(this.sortStackingContexts, this);
-  };
-
-  NodeParser.prototype.parseTextBounds = function(container) {
-      return function(text, index, textList) {
-          if (container.parent.css("textDecoration").substr(0, 4) !== "none" || text.trim().length !== 0) {
-              if (this.support.rangeBounds && !container.parent.hasTransform()) {
-                  var offset = textList.slice(0, index).join("").length;
-                  return this.getRangeBounds(container.node, offset, text.length);
-              } else if (container.node && typeof(container.node.data) === "string") {
-                  var replacementNode = container.node.splitText(text.length);
-                  var bounds = this.getWrapperBounds(container.node, container.parent.hasTransform());
-                  container.node = replacementNode;
-                  return bounds;
-              }
-          } else if(!this.support.rangeBounds || container.parent.hasTransform()){
-              container.node = container.node.splitText(text.length);
-          }
-          return {};
-      };
-  };
-
-  NodeParser.prototype.getWrapperBounds = function(node, transform) {
-      var wrapper = node.ownerDocument.createElement('html2canvaswrapper');
-      var parent = node.parentNode,
-          backupText = node.cloneNode(true);
-
-      wrapper.appendChild(node.cloneNode(true));
-      parent.replaceChild(wrapper, node);
-      var bounds = transform ? offsetBounds(wrapper) : getBounds(wrapper);
-      parent.replaceChild(backupText, wrapper);
-      return bounds;
-  };
-
-  NodeParser.prototype.getRangeBounds = function(node, offset, length) {
-      var range = this.range || (this.range = node.ownerDocument.createRange());
-      range.setStart(node, offset);
-      range.setEnd(node, offset + length);
-      return range.getBoundingClientRect();
-  };
-
-  function ClearTransform() {}
-
-  NodeParser.prototype.parse = function(stack) {
-      // http://www.w3.org/TR/CSS21/visuren.html#z-index
-      var negativeZindex = stack.contexts.filter(negativeZIndex); // 2. the child stacking contexts with negative stack levels (most negative first).
-      var descendantElements = stack.children.filter(isElement);
-      var descendantNonFloats = descendantElements.filter(not(isFloating));
-      var nonInlineNonPositionedDescendants = descendantNonFloats.filter(not(isPositioned)).filter(not(inlineLevel)); // 3 the in-flow, non-inline-level, non-positioned descendants.
-      var nonPositionedFloats = descendantElements.filter(not(isPositioned)).filter(isFloating); // 4. the non-positioned floats.
-      var inFlow = descendantNonFloats.filter(not(isPositioned)).filter(inlineLevel); // 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
-      var stackLevel0 = stack.contexts.concat(descendantNonFloats.filter(isPositioned)).filter(zIndex0); // 6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
-      var text = stack.children.filter(isTextNode).filter(hasText);
-      var positiveZindex = stack.contexts.filter(positiveZIndex); // 7. the child stacking contexts with positive stack levels (least positive first).
-      negativeZindex.concat(nonInlineNonPositionedDescendants).concat(nonPositionedFloats)
-          .concat(inFlow).concat(stackLevel0).concat(text).concat(positiveZindex).forEach(function(container) {
-              this.renderQueue.push(container);
-              if (isStackingContext(container)) {
-                  this.parse(container);
-                  this.renderQueue.push(new ClearTransform());
-              }
-          }, this);
-  };
-
-  NodeParser.prototype.paint = function(container) {
-      try {
-          if (container instanceof ClearTransform) {
-              this.renderer.ctx.restore();
-          } else if (isTextNode(container)) {
-              if (isPseudoElement(container.parent)) {
-                  container.parent.appendToDOM();
-              }
-              this.paintText(container);
-              if (isPseudoElement(container.parent)) {
-                  container.parent.cleanDOM();
-              }
-          } else {
-              this.paintNode(container);
-          }
-      } catch(e) {
-          log(e);
-          if (this.options.strict) {
-              throw e;
-          }
-      }
-  };
-
-  NodeParser.prototype.paintNode = function(container) {
-      if (isStackingContext(container)) {
-          this.renderer.setOpacity(container.opacity);
-          this.renderer.ctx.save();
-          if (container.hasTransform()) {
-              this.renderer.setTransform(container.parseTransform());
-          }
-      }
-
-      if (container.node.nodeName === "INPUT" && container.node.type === "checkbox") {
-          this.paintCheckbox(container);
-      } else if (container.node.nodeName === "INPUT" && container.node.type === "radio") {
-          this.paintRadio(container);
-      } else {
-          this.paintElement(container);
-      }
-  };
-
-  NodeParser.prototype.paintElement = function(container) {
-      var bounds = container.parseBounds();
-      this.renderer.clip(container.backgroundClip, function() {
-          this.renderer.renderBackground(container, bounds, container.borders.borders.map(getWidth));
-      }, this);
-
-      this.renderer.clip(container.clip, function() {
-          this.renderer.renderBorders(container.borders.borders);
-      }, this);
-
-      this.renderer.clip(container.backgroundClip, function() {
-          switch (container.node.nodeName) {
-          case "svg":
-          case "IFRAME":
-              var imgContainer = this.images.get(container.node);
-              if (imgContainer) {
-                  this.renderer.renderImage(container, bounds, container.borders, imgContainer);
-              } else {
-                  log("Error loading <" + container.node.nodeName + ">", container.node);
-              }
-              break;
-          case "IMG":
-              var imageContainer = this.images.get(container.node.src);
-              if (imageContainer) {
-                  this.renderer.renderImage(container, bounds, container.borders, imageContainer);
-              } else {
-                  log("Error loading <img>", container.node.src);
-              }
-              break;
-          case "CANVAS":
-              this.renderer.renderImage(container, bounds, container.borders, {image: container.node});
-              break;
-          case "SELECT":
-          case "INPUT":
-          case "TEXTAREA":
-              this.paintFormValue(container);
-              break;
-          }
-      }, this);
-  };
-
-  NodeParser.prototype.paintCheckbox = function(container) {
-      var b = container.parseBounds();
-
-      var size = Math.min(b.width, b.height);
-      var bounds = {width: size - 1, height: size - 1, top: b.top, left: b.left};
-      var r = [3, 3];
-      var radius = [r, r, r, r];
-      var borders = [1,1,1,1].map(function(w) {
-          return {color: new Color('#A5A5A5'), width: w};
-      });
-
-      var borderPoints = calculateCurvePoints(bounds, radius, borders);
-
-      this.renderer.clip(container.backgroundClip, function() {
-          this.renderer.rectangle(bounds.left + 1, bounds.top + 1, bounds.width - 2, bounds.height - 2, new Color("#DEDEDE"));
-          this.renderer.renderBorders(calculateBorders(borders, bounds, borderPoints, radius));
-          if (container.node.checked) {
-              this.renderer.font(new Color('#424242'), 'normal', 'normal', 'bold', (size - 3) + "px", 'arial');
-              this.renderer.text("\u2714", bounds.left + size / 6, bounds.top + size - 1);
-          }
-      }, this);
-  };
-
-  NodeParser.prototype.paintRadio = function(container) {
-      var bounds = container.parseBounds();
-
-      var size = Math.min(bounds.width, bounds.height) - 2;
-
-      this.renderer.clip(container.backgroundClip, function() {
-          this.renderer.circleStroke(bounds.left + 1, bounds.top + 1, size, new Color('#DEDEDE'), 1, new Color('#A5A5A5'));
-          if (container.node.checked) {
-              this.renderer.circle(Math.ceil(bounds.left + size / 4) + 1, Math.ceil(bounds.top + size / 4) + 1, Math.floor(size / 2), new Color('#424242'));
-          }
-      }, this);
-  };
-
-  NodeParser.prototype.paintFormValue = function(container) {
-      var value = container.getValue();
-      if (value.length > 0) {
-          var document = container.node.ownerDocument;
-          var wrapper = document.createElement('html2canvaswrapper');
-          var properties = ['lineHeight', 'textAlign', 'fontFamily', 'fontWeight', 'fontSize', 'color',
-              'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom',
-              'width', 'height', 'borderLeftStyle', 'borderTopStyle', 'borderLeftWidth', 'borderTopWidth',
-              'boxSizing', 'whiteSpace', 'wordWrap'];
-
-          properties.forEach(function(property) {
-              try {
-                  wrapper.style[property] = container.css(property);
-              } catch(e) {
-                  // Older IE has issues with "border"
-                  log("html2canvas: Parse: Exception caught in renderFormValue: " + e.message);
-              }
-          });
-          var bounds = container.parseBounds();
-          wrapper.style.position = "fixed";
-          wrapper.style.left = bounds.left + "px";
-          wrapper.style.top = bounds.top + "px";
-          wrapper.textContent = value;
-          document.body.appendChild(wrapper);
-          this.paintText(new TextContainer(wrapper.firstChild, container));
-          document.body.removeChild(wrapper);
-      }
-  };
-
-  NodeParser.prototype.paintText = function(container) {
-      container.applyTextTransform();
-      var characters = punycode.ucs2.decode(container.node.data);
-      var textList = (!this.options.letterRendering || noLetterSpacing(container)) && !hasUnicode(container.node.data) ? getWords(characters) : characters.map(function(character) {
-          return punycode.ucs2.encode([character]);
-      });
-
-      var weight = container.parent.fontWeight();
-      var size = container.parent.css('fontSize');
-      var family = container.parent.css('fontFamily');
-      var shadows = container.parent.parseTextShadows();
-
-      this.renderer.font(container.parent.color('color'), container.parent.css('fontStyle'), container.parent.css('fontVariant'), weight, size, family);
-      if (shadows.length) {
-          // TODO: support multiple text shadows
-          this.renderer.fontShadow(shadows[0].color, shadows[0].offsetX, shadows[0].offsetY, shadows[0].blur);
-      } else {
-          this.renderer.clearShadow();
-      }
-
-      this.renderer.clip(container.parent.clip, function() {
-          textList.map(this.parseTextBounds(container), this).forEach(function(bounds, index) {
-              if (bounds && /^\s*$/.test(textList[index]) === false) {
-                  this.renderer.text(textList[index], bounds.left, bounds.bottom);
-                  this.renderTextDecoration(container.parent, bounds, this.fontMetrics.getMetrics(family, size));
-              }
-          }, this);
-      }, this);
-  };
-
-  NodeParser.prototype.renderTextDecoration = function(container, bounds, metrics) {
-      switch(container.css("textDecoration").split(" ")[0]) {
-      case "underline":
-          // Draws a line at the baseline of the font
-          // TODO As some browsers display the line as more than 1px if the font-size is big, need to take that into account both in position and size
-          this.renderer.rectangle(bounds.left, Math.round(bounds.top + metrics.baseline + metrics.lineWidth), bounds.width, 1, container.color("color"));
-          break;
-      case "overline":
-          this.renderer.rectangle(bounds.left, Math.round(bounds.top), bounds.width, 1, container.color("color"));
-          break;
-      case "line-through":
-          // TODO try and find exact position for line-through
-          this.renderer.rectangle(bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, container.color("color"));
-          break;
-      }
-  };
-
-  var borderColorTransforms = {
-      inset: [
-          ["darken", 0.60],
-          ["darken", 0.10],
-          ["darken", 0.10],
-          ["darken", 0.60]
-      ]
-  };
-
-  NodeParser.prototype.parseBorders = function(container) {
-      var nodeBounds = container.parseBounds();
-      var radius = getBorderRadiusData(container);
-      var borders = ["Top", "Right", "Bottom", "Left"].map(function(side, index) {
-          var style = container.css('border' + side + 'Style');
-          var color = container.color('border' + side + 'Color');
-          if (style === "inset" && color.isBlack()) {
-              color = new Color([255, 255, 255, color.a]); // this is wrong, but
-          }
-          var colorTransform = borderColorTransforms[style] ? borderColorTransforms[style][index] : null;
-          return {
-              width: container.cssInt('border' + side + 'Width'),
-              color: colorTransform ? color[colorTransform[0]](colorTransform[1]) : color,
-              args: null
-          };
-      });
-      var borderPoints = calculateCurvePoints(nodeBounds, radius, borders);
-
-      return {
-          clip: this.parseBackgroundClip(container, borderPoints, borders, radius, nodeBounds),
-          borders: calculateBorders(borders, nodeBounds, borderPoints, radius)
-      };
-  };
-
-  function calculateBorders(borders, nodeBounds, borderPoints, radius) {
-      return borders.map(function(border, borderSide) {
-          if (border.width > 0) {
-              var bx = nodeBounds.left;
-              var by = nodeBounds.top;
-              var bw = nodeBounds.width;
-              var bh = nodeBounds.height - (borders[2].width);
-
-              switch(borderSide) {
-              case 0:
-                  // top border
-                  bh = borders[0].width;
-                  border.args = drawSide({
-                          c1: [bx, by],
-                          c2: [bx + bw, by],
-                          c3: [bx + bw - borders[1].width, by + bh],
-                          c4: [bx + borders[3].width, by + bh]
-                      }, radius[0], radius[1],
-                      borderPoints.topLeftOuter, borderPoints.topLeftInner, borderPoints.topRightOuter, borderPoints.topRightInner);
-                  break;
-              case 1:
-                  // right border
-                  bx = nodeBounds.left + nodeBounds.width - (borders[1].width);
-                  bw = borders[1].width;
-
-                  border.args = drawSide({
-                          c1: [bx + bw, by],
-                          c2: [bx + bw, by + bh + borders[2].width],
-                          c3: [bx, by + bh],
-                          c4: [bx, by + borders[0].width]
-                      }, radius[1], radius[2],
-                      borderPoints.topRightOuter, borderPoints.topRightInner, borderPoints.bottomRightOuter, borderPoints.bottomRightInner);
-                  break;
-              case 2:
-                  // bottom border
-                  by = (by + nodeBounds.height) - (borders[2].width);
-                  bh = borders[2].width;
-                  border.args = drawSide({
-                          c1: [bx + bw, by + bh],
-                          c2: [bx, by + bh],
-                          c3: [bx + borders[3].width, by],
-                          c4: [bx + bw - borders[3].width, by]
-                      }, radius[2], radius[3],
-                      borderPoints.bottomRightOuter, borderPoints.bottomRightInner, borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner);
-                  break;
-              case 3:
-                  // left border
-                  bw = borders[3].width;
-                  border.args = drawSide({
-                          c1: [bx, by + bh + borders[2].width],
-                          c2: [bx, by],
-                          c3: [bx + bw, by + borders[0].width],
-                          c4: [bx + bw, by + bh]
-                      }, radius[3], radius[0],
-                      borderPoints.bottomLeftOuter, borderPoints.bottomLeftInner, borderPoints.topLeftOuter, borderPoints.topLeftInner);
-                  break;
-              }
-          }
-          return border;
-      });
-  }
-
-  NodeParser.prototype.parseBackgroundClip = function(container, borderPoints, borders, radius, bounds) {
-      var backgroundClip = container.css('backgroundClip'),
-          borderArgs = [];
-
-      switch(backgroundClip) {
-      case "content-box":
-      case "padding-box":
-          parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftInner, borderPoints.topRightInner, bounds.left + borders[3].width, bounds.top + borders[0].width);
-          parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightInner, borderPoints.bottomRightInner, bounds.left + bounds.width - borders[1].width, bounds.top + borders[0].width);
-          parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightInner, borderPoints.bottomLeftInner, bounds.left + bounds.width - borders[1].width, bounds.top + bounds.height - borders[2].width);
-          parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftInner, borderPoints.topLeftInner, bounds.left + borders[3].width, bounds.top + bounds.height - borders[2].width);
-          break;
-
-      default:
-          parseCorner(borderArgs, radius[0], radius[1], borderPoints.topLeftOuter, borderPoints.topRightOuter, bounds.left, bounds.top);
-          parseCorner(borderArgs, radius[1], radius[2], borderPoints.topRightOuter, borderPoints.bottomRightOuter, bounds.left + bounds.width, bounds.top);
-          parseCorner(borderArgs, radius[2], radius[3], borderPoints.bottomRightOuter, borderPoints.bottomLeftOuter, bounds.left + bounds.width, bounds.top + bounds.height);
-          parseCorner(borderArgs, radius[3], radius[0], borderPoints.bottomLeftOuter, borderPoints.topLeftOuter, bounds.left, bounds.top + bounds.height);
-          break;
-      }
-
-      return borderArgs;
-  };
-
-  function getCurvePoints(x, y, r1, r2) {
-      var kappa = 4 * ((Math.sqrt(2) - 1) / 3);
-      var ox = (r1) * kappa, // control point offset horizontal
-          oy = (r2) * kappa, // control point offset vertical
-          xm = x + r1, // x-middle
-          ym = y + r2; // y-middle
-      return {
-          topLeft: bezierCurve({x: x, y: ym}, {x: x, y: ym - oy}, {x: xm - ox, y: y}, {x: xm, y: y}),
-          topRight: bezierCurve({x: x, y: y}, {x: x + ox,y: y}, {x: xm, y: ym - oy}, {x: xm, y: ym}),
-          bottomRight: bezierCurve({x: xm, y: y}, {x: xm, y: y + oy}, {x: x + ox, y: ym}, {x: x, y: ym}),
-          bottomLeft: bezierCurve({x: xm, y: ym}, {x: xm - ox, y: ym}, {x: x, y: y + oy}, {x: x, y:y})
-      };
-  }
-
-  function calculateCurvePoints(bounds, borderRadius, borders) {
-      var x = bounds.left,
-          y = bounds.top,
-          width = bounds.width,
-          height = bounds.height,
-
-          tlh = borderRadius[0][0] < width / 2 ? borderRadius[0][0] : width / 2,
-          tlv = borderRadius[0][1] < height / 2 ? borderRadius[0][1] : height / 2,
-          trh = borderRadius[1][0] < width / 2 ? borderRadius[1][0] : width / 2,
-          trv = borderRadius[1][1] < height / 2 ? borderRadius[1][1] : height / 2,
-          brh = borderRadius[2][0] < width / 2 ? borderRadius[2][0] : width / 2,
-          brv = borderRadius[2][1] < height / 2 ? borderRadius[2][1] : height / 2,
-          blh = borderRadius[3][0] < width / 2 ? borderRadius[3][0] : width / 2,
-          blv = borderRadius[3][1] < height / 2 ? borderRadius[3][1] : height / 2;
-
-      var topWidth = width - trh,
-          rightHeight = height - brv,
-          bottomWidth = width - brh,
-          leftHeight = height - blv;
-
-      return {
-          topLeftOuter: getCurvePoints(x, y, tlh, tlv).topLeft.subdivide(0.5),
-          topLeftInner: getCurvePoints(x + borders[3].width, y + borders[0].width, Math.max(0, tlh - borders[3].width), Math.max(0, tlv - borders[0].width)).topLeft.subdivide(0.5),
-          topRightOuter: getCurvePoints(x + topWidth, y, trh, trv).topRight.subdivide(0.5),
-          topRightInner: getCurvePoints(x + Math.min(topWidth, width + borders[3].width), y + borders[0].width, (topWidth > width + borders[3].width) ? 0 :trh - borders[3].width, trv - borders[0].width).topRight.subdivide(0.5),
-          bottomRightOuter: getCurvePoints(x + bottomWidth, y + rightHeight, brh, brv).bottomRight.subdivide(0.5),
-          bottomRightInner: getCurvePoints(x + Math.min(bottomWidth, width - borders[3].width), y + Math.min(rightHeight, height + borders[0].width), Math.max(0, brh - borders[1].width),  brv - borders[2].width).bottomRight.subdivide(0.5),
-          bottomLeftOuter: getCurvePoints(x, y + leftHeight, blh, blv).bottomLeft.subdivide(0.5),
-          bottomLeftInner: getCurvePoints(x + borders[3].width, y + leftHeight, Math.max(0, blh - borders[3].width), blv - borders[2].width).bottomLeft.subdivide(0.5)
-      };
-  }
-
-  function bezierCurve(start, startControl, endControl, end) {
-      var lerp = function (a, b, t) {
-          return {
-              x: a.x + (b.x - a.x) * t,
-              y: a.y + (b.y - a.y) * t
-          };
-      };
-
-      return {
-          start: start,
-          startControl: startControl,
-          endControl: endControl,
-          end: end,
-          subdivide: function(t) {
-              var ab = lerp(start, startControl, t),
-                  bc = lerp(startControl, endControl, t),
-                  cd = lerp(endControl, end, t),
-                  abbc = lerp(ab, bc, t),
-                  bccd = lerp(bc, cd, t),
-                  dest = lerp(abbc, bccd, t);
-              return [bezierCurve(start, ab, abbc, dest), bezierCurve(dest, bccd, cd, end)];
-          },
-          curveTo: function(borderArgs) {
-              borderArgs.push(["bezierCurve", startControl.x, startControl.y, endControl.x, endControl.y, end.x, end.y]);
-          },
-          curveToReversed: function(borderArgs) {
-              borderArgs.push(["bezierCurve", endControl.x, endControl.y, startControl.x, startControl.y, start.x, start.y]);
-          }
-      };
-  }
-
-  function drawSide(borderData, radius1, radius2, outer1, inner1, outer2, inner2) {
-      var borderArgs = [];
-
-      if (radius1[0] > 0 || radius1[1] > 0) {
-          borderArgs.push(["line", outer1[1].start.x, outer1[1].start.y]);
-          outer1[1].curveTo(borderArgs);
-      } else {
-          borderArgs.push([ "line", borderData.c1[0], borderData.c1[1]]);
-      }
-
-      if (radius2[0] > 0 || radius2[1] > 0) {
-          borderArgs.push(["line", outer2[0].start.x, outer2[0].start.y]);
-          outer2[0].curveTo(borderArgs);
-          borderArgs.push(["line", inner2[0].end.x, inner2[0].end.y]);
-          inner2[0].curveToReversed(borderArgs);
-      } else {
-          borderArgs.push(["line", borderData.c2[0], borderData.c2[1]]);
-          borderArgs.push(["line", borderData.c3[0], borderData.c3[1]]);
-      }
-
-      if (radius1[0] > 0 || radius1[1] > 0) {
-          borderArgs.push(["line", inner1[1].end.x, inner1[1].end.y]);
-          inner1[1].curveToReversed(borderArgs);
-      } else {
-          borderArgs.push(["line", borderData.c4[0], borderData.c4[1]]);
-      }
-
-      return borderArgs;
-  }
-
-  function parseCorner(borderArgs, radius1, radius2, corner1, corner2, x, y) {
-      if (radius1[0] > 0 || radius1[1] > 0) {
-          borderArgs.push(["line", corner1[0].start.x, corner1[0].start.y]);
-          corner1[0].curveTo(borderArgs);
-          corner1[1].curveTo(borderArgs);
-      } else {
-          borderArgs.push(["line", x, y]);
-      }
-
-      if (radius2[0] > 0 || radius2[1] > 0) {
-          borderArgs.push(["line", corner2[0].start.x, corner2[0].start.y]);
-      }
-  }
-
-  function negativeZIndex(container) {
-      return container.cssInt("zIndex") < 0;
-  }
-
-  function positiveZIndex(container) {
-      return container.cssInt("zIndex") > 0;
-  }
-
-  function zIndex0(container) {
-      return container.cssInt("zIndex") === 0;
-  }
-
-  function inlineLevel(container) {
-      return ["inline", "inline-block", "inline-table"].indexOf(container.css("display")) !== -1;
-  }
-
-  function isStackingContext(container) {
-      return (container instanceof StackingContext);
-  }
-
-  function hasText(container) {
-      return container.node.data.trim().length > 0;
-  }
-
-  function noLetterSpacing(container) {
-      return (/^(normal|none|0px)$/.test(container.parent.css("letterSpacing")));
-  }
-
-  function getBorderRadiusData(container) {
-      return ["TopLeft", "TopRight", "BottomRight", "BottomLeft"].map(function(side) {
-          var value = container.css('border' + side + 'Radius');
-          var arr = value.split(" ");
-          if (arr.length <= 1) {
-              arr[1] = arr[0];
-          }
-          return arr.map(asInt);
-      });
-  }
-
-  function renderableNode(node) {
-      return (node.nodeType === Node.TEXT_NODE || node.nodeType === Node.ELEMENT_NODE);
-  }
-
-  function isPositionedForStacking(container) {
-      var position = container.css("position");
-      var zIndex = (["absolute", "relative", "fixed"].indexOf(position) !== -1) ? container.css("zIndex") : "auto";
-      return zIndex !== "auto";
-  }
-
-  function isPositioned(container) {
-      return container.css("position") !== "static";
-  }
-
-  function isFloating(container) {
-      return container.css("float") !== "none";
-  }
-
-  function isInlineBlock(container) {
-      return ["inline-block", "inline-table"].indexOf(container.css("display")) !== -1;
-  }
-
-  function not(callback) {
-      var context = this;
-      return function() {
-          return !callback.apply(context, arguments);
-      };
-  }
-
-  function isElement(container) {
-      return container.node.nodeType === Node.ELEMENT_NODE;
-  }
-
-  function isPseudoElement(container) {
-      return container.isPseudoElement === true;
-  }
-
-  function isTextNode(container) {
-      return container.node.nodeType === Node.TEXT_NODE;
-  }
-
-  function zIndexSort(contexts) {
-      return function(a, b) {
-          return (a.cssInt("zIndex") + (contexts.indexOf(a) / contexts.length)) - (b.cssInt("zIndex") + (contexts.indexOf(b) / contexts.length));
-      };
-  }
-
-  function hasOpacity(container) {
-      return container.getOpacity() < 1;
-  }
-
-  function asInt(value) {
-      return parseInt(value, 10);
-  }
-
-  function getWidth(border) {
-      return border.width;
-  }
-
-  function nonIgnoredElement(nodeContainer) {
-      return (nodeContainer.node.nodeType !== Node.ELEMENT_NODE || ["SCRIPT", "HEAD", "TITLE", "OBJECT", "BR", "OPTION"].indexOf(nodeContainer.node.nodeName) === -1);
-  }
-
-  function flatten(arrays) {
-      return [].concat.apply([], arrays);
-  }
-
-  function stripQuotes(content) {
-      var first = content.substr(0, 1);
-      return (first === content.substr(content.length - 1) && first.match(/'|"/)) ? content.substr(1, content.length - 2) : content;
-  }
-
-  function getWords(characters) {
-      var words = [], i = 0, onWordBoundary = false, word;
-      while(characters.length) {
-          if (isWordBoundary(characters[i]) === onWordBoundary) {
-              word = characters.splice(0, i);
-              if (word.length) {
-                  words.push(punycode.ucs2.encode(word));
-              }
-              onWordBoundary =! onWordBoundary;
-              i = 0;
-          } else {
-              i++;
-          }
-
-          if (i >= characters.length) {
-              word = characters.splice(0, i);
-              if (word.length) {
-                  words.push(punycode.ucs2.encode(word));
-              }
-          }
-      }
-      return words;
-  }
-
-  function isWordBoundary(characterCode) {
-      return [
-          32, // <space>
-          13, // \r
-          10, // \n
-          9, // \t
-          45 // -
-      ].indexOf(characterCode) !== -1;
-  }
-
-  function hasUnicode(string) {
-      return (/[^\u0000-\u00ff]/).test(string);
-  }
-
-  module.exports = NodeParser;
-
-  },{"./color":3,"./fontmetrics":7,"./log":13,"./nodecontainer":14,"./pseudoelementcontainer":18,"./stackingcontext":21,"./textcontainer":25,"./utils":26,"punycode":1}],16:[function(_dereq_,module,exports){
-  var XHR = _dereq_('./xhr');
-  var utils = _dereq_('./utils');
-  var log = _dereq_('./log');
-  var createWindowClone = _dereq_('./clone');
-  var decode64 = utils.decode64;
-
-  function Proxy(src, proxyUrl, document) {
-      var supportsCORS = ('withCredentials' in new XMLHttpRequest());
-      if (!proxyUrl) {
-          return Promise.reject("No proxy configured");
-      }
-      var callback = createCallback(supportsCORS);
-      var url = createProxyUrl(proxyUrl, src, callback);
-
-      return supportsCORS ? XHR(url) : (jsonp(document, url, callback).then(function(response) {
-          return decode64(response.content);
-      }));
-  }
-  var proxyCount = 0;
-
-  function ProxyURL(src, proxyUrl, document) {
-      var supportsCORSImage = ('crossOrigin' in new Image());
-      var callback = createCallback(supportsCORSImage);
-      var url = createProxyUrl(proxyUrl, src, callback);
-      return (supportsCORSImage ? Promise.resolve(url) : jsonp(document, url, callback).then(function(response) {
-          return "data:" + response.type + ";base64," + response.content;
-      }));
-  }
-
-  function jsonp(document, url, callback) {
-      return new Promise(function(resolve, reject) {
-          var s = document.createElement("script");
-          var cleanup = function() {
-              delete window.html2canvas.proxy[callback];
-              document.body.removeChild(s);
-          };
-          window.html2canvas.proxy[callback] = function(response) {
-              cleanup();
-              resolve(response);
-          };
-          s.src = url;
-          s.onerror = function(e) {
-              cleanup();
-              reject(e);
-          };
-          document.body.appendChild(s);
-      });
-  }
-
-  function createCallback(useCORS) {
-      return !useCORS ? "html2canvas_" + Date.now() + "_" + (++proxyCount) + "_" + Math.round(Math.random() * 100000) : "";
-  }
-
-  function createProxyUrl(proxyUrl, src, callback) {
-      return proxyUrl + "?url=" + encodeURIComponent(src) + (callback.length ? "&callback=html2canvas.proxy." + callback : "");
-  }
-
-  function documentFromHTML(src) {
-      return function(html) {
-          var parser = new DOMParser(), doc;
-          try {
-              doc = parser.parseFromString(html, "text/html");
-          } catch(e) {
-              log("DOMParser not supported, falling back to createHTMLDocument");
-              doc = document.implementation.createHTMLDocument("");
-              try {
-                  doc.open();
-                  doc.write(html);
-                  doc.close();
-              } catch(ee) {
-                  log("createHTMLDocument write not supported, falling back to document.body.innerHTML");
-                  doc.body.innerHTML = html; // ie9 doesnt support writing to documentElement
-              }
-          }
-
-          var b = doc.querySelector("base");
-          if (!b || !b.href.host) {
-              var base = doc.createElement("base");
-              base.href = src;
-              doc.head.insertBefore(base, doc.head.firstChild);
-          }
-
-          return doc;
-      };
-  }
-
-  function loadUrlDocument(src, proxy, document, width, height, options) {
-      return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) {
-          return createWindowClone(doc, document, width, height, options, 0, 0);
-      });
-  }
-
-  exports.Proxy = Proxy;
-  exports.ProxyURL = ProxyURL;
-  exports.loadUrlDocument = loadUrlDocument;
-
-  },{"./clone":2,"./log":13,"./utils":26,"./xhr":28}],17:[function(_dereq_,module,exports){
-  var ProxyURL = _dereq_('./proxy').ProxyURL;
-
-  function ProxyImageContainer(src, proxy) {
-      var link = document.createElement("a");
-      link.href = src;
-      src = link.href;
-      this.src = src;
-      this.image = new Image();
-      var self = this;
-      this.promise = new Promise(function(resolve, reject) {
-          self.image.crossOrigin = "Anonymous";
-          self.image.onload = resolve;
-          self.image.onerror = reject;
-
-          new ProxyURL(src, proxy, document).then(function(url) {
-              self.image.src = url;
-          })['catch'](reject);
-      });
-  }
-
-  module.exports = ProxyImageContainer;
-
-  },{"./proxy":16}],18:[function(_dereq_,module,exports){
-  var NodeContainer = _dereq_('./nodecontainer');
-
-  function PseudoElementContainer(node, parent, type) {
-      NodeContainer.call(this, node, parent);
-      this.isPseudoElement = true;
-      this.before = type === ":before";
-  }
-
-  PseudoElementContainer.prototype.cloneTo = function(stack) {
-      PseudoElementContainer.prototype.cloneTo.call(this, stack);
-      stack.isPseudoElement = true;
-      stack.before = this.before;
-  };
-
-  PseudoElementContainer.prototype = Object.create(NodeContainer.prototype);
-
-  PseudoElementContainer.prototype.appendToDOM = function() {
-      if (this.before) {
-          this.parent.node.insertBefore(this.node, this.parent.node.firstChild);
-      } else {
-          this.parent.node.appendChild(this.node);
-      }
-      this.parent.node.className += " " + this.getHideClass();
-  };
-
-  PseudoElementContainer.prototype.cleanDOM = function() {
-      this.node.parentNode.removeChild(this.node);
-      this.parent.node.className = this.parent.node.className.replace(this.getHideClass(), "");
-  };
-
-  PseudoElementContainer.prototype.getHideClass = function() {
-      return this["PSEUDO_HIDE_ELEMENT_CLASS_" + (this.before ? "BEFORE" : "AFTER")];
-  };
-
-  PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE = "___html2canvas___pseudoelement_before";
-  PseudoElementContainer.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER = "___html2canvas___pseudoelement_after";
-
-  module.exports = PseudoElementContainer;
-
-  },{"./nodecontainer":14}],19:[function(_dereq_,module,exports){
-  var log = _dereq_('./log');
-
-  function Renderer(width, height, images, options, document) {
-      this.width = width;
-      this.height = height;
-      this.images = images;
-      this.options = options;
-      this.document = document;
-  }
-
-  Renderer.prototype.renderImage = function(container, bounds, borderData, imageContainer) {
-      var paddingLeft = container.cssInt('paddingLeft'),
-          paddingTop = container.cssInt('paddingTop'),
-          paddingRight = container.cssInt('paddingRight'),
-          paddingBottom = container.cssInt('paddingBottom'),
-          borders = borderData.borders;
-
-      var width = bounds.width - (borders[1].width + borders[3].width + paddingLeft + paddingRight);
-      var height = bounds.height - (borders[0].width + borders[2].width + paddingTop + paddingBottom);
-      this.drawImage(
-          imageContainer,
-          0,
-          0,
-          imageContainer.image.width || width,
-          imageContainer.image.height || height,
-          bounds.left + paddingLeft + borders[3].width,
-          bounds.top + paddingTop + borders[0].width,
-          width,
-          height
-      );
-  };
-
-  Renderer.prototype.renderBackground = function(container, bounds, borderData) {
-      if (bounds.height > 0 && bounds.width > 0) {
-          this.renderBackgroundColor(container, bounds);
-          this.renderBackgroundImage(container, bounds, borderData);
-      }
-  };
-
-  Renderer.prototype.renderBackgroundColor = function(container, bounds) {
-      var color = container.color("backgroundColor");
-      if (!color.isTransparent()) {
-          this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, color);
-      }
-  };
-
-  Renderer.prototype.renderBorders = function(borders) {
-      borders.forEach(this.renderBorder, this);
-  };
-
-  Renderer.prototype.renderBorder = function(data) {
-      if (!data.color.isTransparent() && data.args !== null) {
-          this.drawShape(data.args, data.color);
-      }
-  };
-
-  Renderer.prototype.renderBackgroundImage = function(container, bounds, borderData) {
-      var backgroundImages = container.parseBackgroundImages();
-      backgroundImages.reverse().forEach(function(backgroundImage, index, arr) {
-          switch(backgroundImage.method) {
-          case "url":
-              var image = this.images.get(backgroundImage.args[0]);
-              if (image) {
-                  this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1), borderData);
-              } else {
-                  log("Error loading background-image", backgroundImage.args[0]);
-              }
-              break;
-          case "linear-gradient":
-          case "gradient":
-              var gradientImage = this.images.get(backgroundImage.value);
-              if (gradientImage) {
-                  this.renderBackgroundGradient(gradientImage, bounds, borderData);
-              } else {
-                  log("Error loading background-image", backgroundImage.args[0]);
-              }
-              break;
-          case "none":
-              break;
-          default:
-              log("Unknown background-image type", backgroundImage.args[0]);
-          }
-      }, this);
-  };
-
-  Renderer.prototype.renderBackgroundRepeating = function(container, bounds, imageContainer, index, borderData) {
-      var size = container.parseBackgroundSize(bounds, imageContainer.image, index);
-      var position = container.parseBackgroundPosition(bounds, imageContainer.image, index, size);
-      var repeat = container.parseBackgroundRepeat(index);
-      switch (repeat) {
-      case "repeat-x":
-      case "repeat no-repeat":
-          this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + borderData[3], bounds.top + position.top + borderData[0], 99999, size.height, borderData);
-          break;
-      case "repeat-y":
-      case "no-repeat repeat":
-          this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + borderData[0], size.width, 99999, borderData);
-          break;
-      case "no-repeat":
-          this.backgroundRepeatShape(imageContainer, position, size, bounds, bounds.left + position.left + borderData[3], bounds.top + position.top + borderData[0], size.width, size.height, borderData);
-          break;
-      default:
-          this.renderBackgroundRepeat(imageContainer, position, size, {top: bounds.top, left: bounds.left}, borderData[3], borderData[0]);
-          break;
-      }
-  };
-
-  module.exports = Renderer;
-
-  },{"./log":13}],20:[function(_dereq_,module,exports){
-  var Renderer = _dereq_('../renderer');
-  var LinearGradientContainer = _dereq_('../lineargradientcontainer');
-  var log = _dereq_('../log');
-
-  function CanvasRenderer(width, height) {
-      Renderer.apply(this, arguments);
-      this.canvas = this.options.canvas || this.document.createElement("canvas");
-      if (!this.options.canvas) {
-          this.canvas.width = width;
-          this.canvas.height = height;
-      }
-      this.ctx = this.canvas.getContext("2d");
-      this.taintCtx = this.document.createElement("canvas").getContext("2d");
-      this.ctx.textBaseline = "bottom";
-      this.variables = {};
-      log("Initialized CanvasRenderer with size", width, "x", height);
-  }
-
-  CanvasRenderer.prototype = Object.create(Renderer.prototype);
-
-  CanvasRenderer.prototype.setFillStyle = function(fillStyle) {
-      this.ctx.fillStyle = typeof(fillStyle) === "object" && !!fillStyle.isColor ? fillStyle.toString() : fillStyle;
-      return this.ctx;
-  };
-
-  CanvasRenderer.prototype.rectangle = function(left, top, width, height, color) {
-      this.setFillStyle(color).fillRect(left, top, width, height);
-  };
-
-  CanvasRenderer.prototype.circle = function(left, top, size, color) {
-      this.setFillStyle(color);
-      this.ctx.beginPath();
-      this.ctx.arc(left + size / 2, top + size / 2, size / 2, 0, Math.PI*2, true);
-      this.ctx.closePath();
-      this.ctx.fill();
-  };
-
-  CanvasRenderer.prototype.circleStroke = function(left, top, size, color, stroke, strokeColor) {
-      this.circle(left, top, size, color);
-      this.ctx.strokeStyle = strokeColor.toString();
-      this.ctx.stroke();
-  };
-
-  CanvasRenderer.prototype.drawShape = function(shape, color) {
-      this.shape(shape);
-      this.setFillStyle(color).fill();
-  };
-
-  CanvasRenderer.prototype.taints = function(imageContainer) {
-      if (imageContainer.tainted === null) {
-          this.taintCtx.drawImage(imageContainer.image, 0, 0);
-          try {
-              this.taintCtx.getImageData(0, 0, 1, 1);
-              imageContainer.tainted = false;
-          } catch(e) {
-              this.taintCtx = document.createElement("canvas").getContext("2d");
-              imageContainer.tainted = true;
-          }
-      }
-
-      return imageContainer.tainted;
-  };
-
-  CanvasRenderer.prototype.drawImage = function(imageContainer, sx, sy, sw, sh, dx, dy, dw, dh) {
-      if (!this.taints(imageContainer) || this.options.allowTaint) {
-          this.ctx.drawImage(imageContainer.image, sx, sy, sw, sh, dx, dy, dw, dh);
-      }
-  };
-
-  CanvasRenderer.prototype.clip = function(shapes, callback, context) {
-      this.ctx.save();
-      shapes.filter(hasEntries).forEach(function(shape) {
-          this.shape(shape).clip();
-      }, this);
-      callback.call(context);
-      this.ctx.restore();
-  };
-
-  CanvasRenderer.prototype.shape = function(shape) {
-      this.ctx.beginPath();
-      shape.forEach(function(point, index) {
-          if (point[0] === "rect") {
-              this.ctx.rect.apply(this.ctx, point.slice(1));
-          } else {
-              this.ctx[(index === 0) ? "moveTo" : point[0] + "To" ].apply(this.ctx, point.slice(1));
-          }
-      }, this);
-      this.ctx.closePath();
-      return this.ctx;
-  };
-
-  CanvasRenderer.prototype.font = function(color, style, variant, weight, size, family) {
-      this.setFillStyle(color).font = [style, variant, weight, size, family].join(" ").split(",")[0];
-  };
-
-  CanvasRenderer.prototype.fontShadow = function(color, offsetX, offsetY, blur) {
-      this.setVariable("shadowColor", color.toString())
-          .setVariable("shadowOffsetY", offsetX)
-          .setVariable("shadowOffsetX", offsetY)
-          .setVariable("shadowBlur", blur);
-  };
-
-  CanvasRenderer.prototype.clearShadow = function() {
-      this.setVariable("shadowColor", "rgba(0,0,0,0)");
-  };
-
-  CanvasRenderer.prototype.setOpacity = function(opacity) {
-      this.ctx.globalAlpha = opacity;
-  };
-
-  CanvasRenderer.prototype.setTransform = function(transform) {
-      this.ctx.translate(transform.origin[0], transform.origin[1]);
-      this.ctx.transform.apply(this.ctx, transform.matrix);
-      this.ctx.translate(-transform.origin[0], -transform.origin[1]);
-  };
-
-  CanvasRenderer.prototype.setVariable = function(property, value) {
-      if (this.variables[property] !== value) {
-          this.variables[property] = this.ctx[property] = value;
-      }
-
-      return this;
-  };
-
-  CanvasRenderer.prototype.text = function(text, left, bottom) {
-      this.ctx.fillText(text, left, bottom);
-  };
-
-  CanvasRenderer.prototype.backgroundRepeatShape = function(imageContainer, backgroundPosition, size, bounds, left, top, width, height, borderData) {
-      var shape = [
-          ["line", Math.round(left), Math.round(top)],
-          ["line", Math.round(left + width), Math.round(top)],
-          ["line", Math.round(left + width), Math.round(height + top)],
-          ["line", Math.round(left), Math.round(height + top)]
-      ];
-      this.clip([shape], function() {
-          this.renderBackgroundRepeat(imageContainer, backgroundPosition, size, bounds, borderData[3], borderData[0]);
-      }, this);
-  };
-
-  CanvasRenderer.prototype.renderBackgroundRepeat = function(imageContainer, backgroundPosition, size, bounds, borderLeft, borderTop) {
-      var offsetX = Math.round(bounds.left + backgroundPosition.left + borderLeft), offsetY = Math.round(bounds.top + backgroundPosition.top + borderTop);
-      this.setFillStyle(this.ctx.createPattern(this.resizeImage(imageContainer, size), "repeat"));
-      this.ctx.translate(offsetX, offsetY);
-      this.ctx.fill();
-      this.ctx.translate(-offsetX, -offsetY);
-  };
-
-  CanvasRenderer.prototype.renderBackgroundGradient = function(gradientImage, bounds) {
-      if (gradientImage instanceof LinearGradientContainer) {
-          var gradient = this.ctx.createLinearGradient(
-              bounds.left + bounds.width * gradientImage.x0,
-              bounds.top + bounds.height * gradientImage.y0,
-              bounds.left +  bounds.width * gradientImage.x1,
-              bounds.top +  bounds.height * gradientImage.y1);
-          gradientImage.colorStops.forEach(function(colorStop) {
-              gradient.addColorStop(colorStop.stop, colorStop.color.toString());
-          });
-          this.rectangle(bounds.left, bounds.top, bounds.width, bounds.height, gradient);
-      }
-  };
-
-  CanvasRenderer.prototype.resizeImage = function(imageContainer, size) {
-      var image = imageContainer.image;
-      if(image.width === size.width && image.height === size.height) {
-          return image;
-      }
-
-      var ctx, canvas = document.createElement('canvas');
-      canvas.width = size.width;
-      canvas.height = size.height;
-      ctx = canvas.getContext("2d");
-      ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, size.width, size.height );
-      return canvas;
-  };
-
-  function hasEntries(array) {
-      return array.length > 0;
-  }
-
-  module.exports = CanvasRenderer;
-
-  },{"../lineargradientcontainer":12,"../log":13,"../renderer":19}],21:[function(_dereq_,module,exports){
-  var NodeContainer = _dereq_('./nodecontainer');
-
-  function StackingContext(hasOwnStacking, opacity, element, parent) {
-      NodeContainer.call(this, element, parent);
-      this.ownStacking = hasOwnStacking;
-      this.contexts = [];
-      this.children = [];
-      this.opacity = (this.parent ? this.parent.stack.opacity : 1) * opacity;
-  }
-
-  StackingContext.prototype = Object.create(NodeContainer.prototype);
-
-  StackingContext.prototype.getParentStack = function(context) {
-      var parentStack = (this.parent) ? this.parent.stack : null;
-      return parentStack ? (parentStack.ownStacking ? parentStack : parentStack.getParentStack(context)) : context.stack;
-  };
-
-  module.exports = StackingContext;
-
-  },{"./nodecontainer":14}],22:[function(_dereq_,module,exports){
-  function Support(document) {
-      this.rangeBounds = this.testRangeBounds(document);
-      this.cors = this.testCORS();
-      this.svg = this.testSVG();
-  }
-
-  Support.prototype.testRangeBounds = function(document) {
-      var range, testElement, rangeBounds, rangeHeight, support = false;
-
-      if (document.createRange) {
-          range = document.createRange();
-          if (range.getBoundingClientRect) {
-              testElement = document.createElement('boundtest');
-              testElement.style.height = "123px";
-              testElement.style.display = "block";
-              document.body.appendChild(testElement);
-
-              range.selectNode(testElement);
-              rangeBounds = range.getBoundingClientRect();
-              rangeHeight = rangeBounds.height;
-
-              if (rangeHeight === 123) {
-                  support = true;
-              }
-              document.body.removeChild(testElement);
-          }
-      }
-
-      return support;
-  };
-
-  Support.prototype.testCORS = function() {
-      return typeof((new Image()).crossOrigin) !== "undefined";
-  };
-
-  Support.prototype.testSVG = function() {
-      var img = new Image();
-      var canvas = document.createElement("canvas");
-      var ctx =  canvas.getContext("2d");
-      img.src = "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>";
-
-      try {
-          ctx.drawImage(img, 0, 0);
-          canvas.toDataURL();
-      } catch(e) {
-          return false;
-      }
-      return true;
-  };
-
-  module.exports = Support;
-
-  },{}],23:[function(_dereq_,module,exports){
-  var XHR = _dereq_('./xhr');
-  var decode64 = _dereq_('./utils').decode64;
-
-  function SVGContainer(src) {
-      this.src = src;
-      this.image = null;
-      var self = this;
-
-      this.promise = this.hasFabric().then(function() {
-          return (self.isInline(src) ? Promise.resolve(self.inlineFormatting(src)) : XHR(src));
-      }).then(function(svg) {
-          return new Promise(function(resolve) {
-              window.html2canvas.svg.fabric.loadSVGFromString(svg, self.createCanvas.call(self, resolve));
-          });
-      });
-  }
-
-  SVGContainer.prototype.hasFabric = function() {
-      return !window.html2canvas.svg || !window.html2canvas.svg.fabric ? Promise.reject(new Error("html2canvas.svg.js is not loaded, cannot render svg")) : Promise.resolve();
-  };
-
-  SVGContainer.prototype.inlineFormatting = function(src) {
-      return (/^data:image\/svg\+xml;base64,/.test(src)) ? this.decode64(this.removeContentType(src)) : this.removeContentType(src);
-  };
-
-  SVGContainer.prototype.removeContentType = function(src) {
-      return src.replace(/^data:image\/svg\+xml(;base64)?,/,'');
-  };
-
-  SVGContainer.prototype.isInline = function(src) {
-      return (/^data:image\/svg\+xml/i.test(src));
-  };
-
-  SVGContainer.prototype.createCanvas = function(resolve) {
-      var self = this;
-      return function (objects, options) {
-          var canvas = new window.html2canvas.svg.fabric.StaticCanvas('c');
-          self.image = canvas.lowerCanvasEl;
-          canvas
-              .setWidth(options.width)
-              .setHeight(options.height)
-              .add(window.html2canvas.svg.fabric.util.groupSVGElements(objects, options))
-              .renderAll();
-          resolve(canvas.lowerCanvasEl);
-      };
-  };
-
-  SVGContainer.prototype.decode64 = function(str) {
-      return (typeof(window.atob) === "function") ? window.atob(str) : decode64(str);
-  };
-
-  module.exports = SVGContainer;
-
-  },{"./utils":26,"./xhr":28}],24:[function(_dereq_,module,exports){
-  var SVGContainer = _dereq_('./svgcontainer');
-
-  function SVGNodeContainer(node, _native) {
-      this.src = node;
-      this.image = null;
-      var self = this;
-
-      this.promise = _native ? new Promise(function(resolve, reject) {
-          self.image = new Image();
-          self.image.onload = resolve;
-          self.image.onerror = reject;
-          self.image.src = "data:image/svg+xml," + (new XMLSerializer()).serializeToString(node);
-          if (self.image.complete === true) {
-              resolve(self.image);
-          }
-      }) : this.hasFabric().then(function() {
-          return new Promise(function(resolve) {
-              window.html2canvas.svg.fabric.parseSVGDocument(node, self.createCanvas.call(self, resolve));
-          });
-      });
-  }
-
-  SVGNodeContainer.prototype = Object.create(SVGContainer.prototype);
-
-  module.exports = SVGNodeContainer;
-
-  },{"./svgcontainer":23}],25:[function(_dereq_,module,exports){
-  var NodeContainer = _dereq_('./nodecontainer');
-
-  function TextContainer(node, parent) {
-      NodeContainer.call(this, node, parent);
-  }
-
-  TextContainer.prototype = Object.create(NodeContainer.prototype);
-
-  TextContainer.prototype.applyTextTransform = function() {
-      this.node.data = this.transform(this.parent.css("textTransform"));
-  };
-
-  TextContainer.prototype.transform = function(transform) {
-      var text = this.node.data;
-      switch(transform){
-          case "lowercase":
-              return text.toLowerCase();
-          case "capitalize":
-              return text.replace(/(^|\s|:|-|\(|\))([a-z])/g, capitalize);
-          case "uppercase":
-              return text.toUpperCase();
-          default:
-              return text;
-      }
-  };
-
-  function capitalize(m, p1, p2) {
-      if (m.length > 0) {
-          return p1 + p2.toUpperCase();
-      }
-  }
-
-  module.exports = TextContainer;
-
-  },{"./nodecontainer":14}],26:[function(_dereq_,module,exports){
-  exports.smallImage = function smallImage() {
-      return "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
-  };
-
-  exports.bind = function(callback, context) {
-      return function() {
-          return callback.apply(context, arguments);
-      };
-  };
-
-  /*
-   * base64-arraybuffer
-   * https://github.com/niklasvh/base64-arraybuffer
-   *
-   * Copyright (c) 2012 Niklas von Hertzen
-   * Licensed under the MIT license.
-   */
-
-  exports.decode64 = function(base64) {
-      var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-      var len = base64.length, i, encoded1, encoded2, encoded3, encoded4, byte1, byte2, byte3;
-
-      var output = "";
-
-      for (i = 0; i < len; i+=4) {
-          encoded1 = chars.indexOf(base64[i]);
-          encoded2 = chars.indexOf(base64[i+1]);
-          encoded3 = chars.indexOf(base64[i+2]);
-          encoded4 = chars.indexOf(base64[i+3]);
-
-          byte1 = (encoded1 << 2) | (encoded2 >> 4);
-          byte2 = ((encoded2 & 15) << 4) | (encoded3 >> 2);
-          byte3 = ((encoded3 & 3) << 6) | encoded4;
-          if (encoded3 === 64) {
-              output += String.fromCharCode(byte1);
-          } else if (encoded4 === 64 || encoded4 === -1) {
-              output += String.fromCharCode(byte1, byte2);
-          } else{
-              output += String.fromCharCode(byte1, byte2, byte3);
-          }
-      }
-
-      return output;
-  };
-
-  exports.getBounds = function(node) {
-      if (node.getBoundingClientRect) {
-          var clientRect = node.getBoundingClientRect();
-          var width = node.offsetWidth == null ? clientRect.width : node.offsetWidth;
-          return {
-              top: clientRect.top,
-              bottom: clientRect.bottom || (clientRect.top + clientRect.height),
-              right: clientRect.left + width,
-              left: clientRect.left,
-              width:  width,
-              height: node.offsetHeight == null ? clientRect.height : node.offsetHeight
-          };
-      }
-      return {};
-  };
-
-  exports.offsetBounds = function(node) {
-      var parent = node.offsetParent ? exports.offsetBounds(node.offsetParent) : {top: 0, left: 0};
-
-      return {
-          top: node.offsetTop + parent.top,
-          bottom: node.offsetTop + node.offsetHeight + parent.top,
-          right: node.offsetLeft + parent.left + node.offsetWidth,
-          left: node.offsetLeft + parent.left,
-          width: node.offsetWidth,
-          height: node.offsetHeight
-      };
-  };
-
-  exports.parseBackgrounds = function(backgroundImage) {
-      var whitespace = ' \r\n\t',
-          method, definition, prefix, prefix_i, block, results = [],
-          mode = 0, numParen = 0, quote, args;
-      var appendResult = function() {
-          if(method) {
-              if (definition.substr(0, 1) === '"') {
-                  definition = definition.substr(1, definition.length - 2);
-              }
-              if (definition) {
-                  args.push(definition);
-              }
-              if (method.substr(0, 1) === '-' && (prefix_i = method.indexOf('-', 1 ) + 1) > 0) {
-                  prefix = method.substr(0, prefix_i);
-                  method = method.substr(prefix_i);
-              }
-              results.push({
-                  prefix: prefix,
-                  method: method.toLowerCase(),
-                  value: block,
-                  args: args,
-                  image: null
-              });
-          }
-          args = [];
-          method = prefix = definition = block = '';
-      };
-      args = [];
-      method = prefix = definition = block = '';
-      backgroundImage.split("").forEach(function(c) {
-          if (mode === 0 && whitespace.indexOf(c) > -1) {
-              return;
-          }
-          switch(c) {
-          case '"':
-              if(!quote) {
-                  quote = c;
-              } else if(quote === c) {
-                  quote = null;
-              }
-              break;
-          case '(':
-              if(quote) {
-                  break;
-              } else if(mode === 0) {
-                  mode = 1;
-                  block += c;
-                  return;
-              } else {
-                  numParen++;
-              }
-              break;
-          case ')':
-              if (quote) {
-                  break;
-              } else if(mode === 1) {
-                  if(numParen === 0) {
-                      mode = 0;
-                      block += c;
-                      appendResult();
-                      return;
-                  } else {
-                      numParen--;
-                  }
-              }
-              break;
-
-          case ',':
-              if (quote) {
-                  break;
-              } else if(mode === 0) {
-                  appendResult();
-                  return;
-              } else if (mode === 1) {
-                  if (numParen === 0 && !method.match(/^url$/i)) {
-                      args.push(definition);
-                      definition = '';
-                      block += c;
-                      return;
-                  }
-              }
-              break;
-          }
-
-          block += c;
-          if (mode === 0) {
-              method += c;
-          } else {
-              definition += c;
-          }
-      });
-
-      appendResult();
-      return results;
-  };
-
-  },{}],27:[function(_dereq_,module,exports){
-  var GradientContainer = _dereq_('./gradientcontainer');
-
-  function WebkitGradientContainer(imageData) {
-      GradientContainer.apply(this, arguments);
-      this.type = imageData.args[0] === "linear" ? GradientContainer.TYPES.LINEAR : GradientContainer.TYPES.RADIAL;
-  }
-
-  WebkitGradientContainer.prototype = Object.create(GradientContainer.prototype);
-
-  module.exports = WebkitGradientContainer;
-
-  },{"./gradientcontainer":9}],28:[function(_dereq_,module,exports){
-  function XHR(url) {
-      return new Promise(function(resolve, reject) {
-          var xhr = new XMLHttpRequest();
-          xhr.open('GET', url);
-
-          xhr.onload = function() {
-              if (xhr.status === 200) {
-                  resolve(xhr.responseText);
-              } else {
-                  reject(new Error(xhr.statusText));
-              }
-          };
-
-          xhr.onerror = function() {
-              reject(new Error("Network Error"));
-          };
-
-          xhr.send();
-      });
-  }
-
-  module.exports = XHR;
-
-  },{}]},{},[4])(4)
-  });
-
-  /************************************************
-   * Title : custom font                          *
-   * Start Data : 2017. 01. 22.                   *
-   * Comment : TEXT API                           *
-   ************************************************/
-
-  /******************************
-   * jsPDF extension API Design *
-   * ****************************/
-  (function(jsPDF){
-      var PLUS = '+'.charCodeAt(0);
-      var SLASH = '/'.charCodeAt(0);
-      var NUMBER = '0'.charCodeAt(0);
-      var LOWER = 'a'.charCodeAt(0);
-      var UPPER = 'A'.charCodeAt(0);
-      var PLUS_URL_SAFE = '-'.charCodeAt(0);
-      var SLASH_URL_SAFE = '_'.charCodeAt(0);
-
-      /*****************************************************************/
-      /* function : b64ToByteArray                                     */
-      /* comment : Base64 encoded TTF file contents (b64) are decoded  */
-      /*     by Byte array and stored.                                 */
-      /*****************************************************************/
-      var b64ToByteArray = function(b64) {
-          var i, j, l, tmp, placeHolders, arr;
-          if (b64.length % 4 > 0) {
-              throw new Error('Invalid string. Length must be a multiple of 4')
-          }
-          // the number of equal signs (place holders)
-          // if there are two placeholders, than the two characters before it
-          // represent one byte
-          // if there is only one, then the three characters before it represent 2 bytes
-          // this is just a cheap hack to not do indexOf twice
-          var len = b64.length;
-          placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0;
-              // base64 is 4/3 + up to two characters of the original data
-          arr = new Uint8Array(b64.length * 3 / 4 - placeHolders);
-              // if there are placeholders, only get up to the last complete 4 chars
-          l = placeHolders > 0 ? b64.length - 4 : b64.length;
-          var L = 0;
-
-          function push(v) {
-              arr[L++] = v;
-          }
-          for (i = 0, j = 0; i < l; i += 4, j += 3) {
-              tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3));
-              push((tmp & 0xFF0000) >> 16);
-              push((tmp & 0xFF00) >> 8);
-              push(tmp & 0xFF);
-          }
-          if (placeHolders === 2) {
-              tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4);
-              push(tmp & 0xFF);
-          }
-          else if (placeHolders === 1) {
-              tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2);
-              push((tmp >> 8) & 0xFF);
-              push(tmp & 0xFF);
-          }
-          return arr
-      };
-
-      /***************************************************************/
-      /* function : decode                                           */
-      /* comment : Change the base64 encoded font's content to match */
-      /*   the base64 index value.                                   */
-      /***************************************************************/
-      var decode = function(elt) {
-          var code = elt.charCodeAt(0);
-          if (code === PLUS || code === PLUS_URL_SAFE) return 62 // '+'
-          if (code === SLASH || code === SLASH_URL_SAFE) return 63 // '/'
-          if (code < NUMBER) return -1 //no match
-          if (code < NUMBER + 10) return code - NUMBER + 26 + 26
-          if (code < UPPER + 26) return code - UPPER
-          if (code < LOWER + 26) return code - LOWER + 26
-      };
-
-      jsPDF.API.TTFFont = (function () {
-          /************************************************************************/
-          /* function : open                                                       */
-          /* comment : Decode the encoded ttf content and create a TTFFont object. */
-          /************************************************************************/
-          TTFFont.open = function (filename, name, vfs, encoding) {
-              var contents;
-              contents = b64ToByteArray(vfs);
-              return new TTFFont(contents, name, encoding);
-          };
-          /***************************************************************/
-          /* function : TTFFont gernerator                               */
-          /* comment : Decode TTF contents are parsed, Data,             */
-          /* Subset object is created, and registerTTF function is called.*/
-          /***************************************************************/
-          function TTFFont(rawData, name, encoding) {
-              var data;
-              this.rawData = rawData;
-              data = this.contents = new Data(rawData);
-              this.contents.pos = 4;
-              if (data.readString(4) === 'ttcf') {
-                  if (!name) {
-                      throw new Error("Must specify a font name for TTC files.");
-                  }
-                  throw new Error("Font " + name + " not found in TTC file.");
-              }
-              else {
-                  data.pos = 0;
-                  this.parse();
-                  this.subset = new Subset(this);
-                  this.registerTTF();
-              }
-          }
-          /********************************************************/
-          /* function : parse                                     */
-          /* comment : TTF Parses the file contents by each table.*/
-          /********************************************************/
-          TTFFont.prototype.parse = function () {
-              this.directory = new Directory(this.contents);
-              this.head = new HeadTable(this);
-              this.name = new NameTable(this);
-              this.cmap = new CmapTable(this);
-              this.hhea = new HheaTable(this);
-              this.maxp = new MaxpTable(this);
-              this.hmtx = new HmtxTable(this);
-              this.post = new PostTable(this);
-              this.os2 = new OS2Table(this);
-              this.loca = new LocaTable(this);
-              this.glyf = new GlyfTable(this);
-              this.ascender = (this.os2.exists && this.os2.ascender) || this.hhea.ascender;
-              this.decender = (this.os2.exists && this.os2.decender) || this.hhea.decender;
-              this.lineGap = (this.os2.exists && this.os2.lineGap) || this.hhea.lineGap;
-              return this.bbox = [this.head.xMin, this.head.yMin, this.head.xMax, this.head.yMax];
-          };
-          /***************************************************************/
-          /* function : registerTTF                                      */
-          /* comment : Get the value to assign pdf font descriptors.     */
-          /***************************************************************/
-          TTFFont.prototype.registerTTF = function () {
-              var e, hi, low, raw, _ref;
-              this.scaleFactor = 1000.0 / this.head.unitsPerEm;
-              this.bbox = (function () {
-                  var _i, _len, _ref, _results;
-                  _ref = this.bbox;
-                  _results = [];
-                  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-                      e = _ref[_i];
-                      _results.push(Math.round(e * this.scaleFactor));
-                  }
-                  return _results;
-              }).call(this);
-              this.stemV = 0;
-              if (this.post.exists) {
-                  raw = this.post.italic_angle;
-                  hi = raw >> 16;
-                  low = raw & 0xFF;
-                  if (hi & 0x8000 !== 0) {
-                      hi = -((hi ^ 0xFFFF) + 1);
-                  }
-                  this.italicAngle = +("" + hi + "." + low);
-              }
-              else {
-                  this.italicAngle = 0;
-              }
-              this.ascender = Math.round(this.ascender * this.scaleFactor);
-              this.decender = Math.round(this.decender * this.scaleFactor);
-              this.lineGap = Math.round(this.lineGap * this.scaleFactor);
-              this.capHeight = (this.os2.exists && this.os2.capHeight) || this.ascender;
-              this.xHeight = (this.os2.exists && this.os2.xHeight) || 0;
-              this.familyClass = (this.os2.exists && this.os2.familyClass || 0) >> 8;
-              this.isSerif = (_ref = this.familyClass) === 1 || _ref === 2 || _ref === 3 || _ref === 4 || _ref === 5 || _ref === 7;
-              this.isScript = this.familyClass === 10;
-              this.flags = 0;
-              if (this.post.isFixedPitch) {
-                  this.flags |= 1 << 0;
-              }
-              if (this.isSerif) {
-                  this.flags |= 1 << 1;
-              }
-              if (this.isScript) {
-                  this.flags |= 1 << 3;
-              }
-              if (this.italicAngle !== 0) {
-                  this.flags |= 1 << 6;
-              }
-              this.flags |= 1 << 5;
-              if (!this.cmap.unicode) {
-                  throw new Error('No unicode cmap for font');
-              }
-          };
-          TTFFont.prototype.characterToGlyph = function (character) {
-              var _ref;
-              return ((_ref = this.cmap.unicode) != null ? _ref.codeMap[character] : void 0) || 0;
-          };
-          TTFFont.prototype.widthOfGlyph = function (glyph) {
-              var scale;
-              scale = 1000.0 / this.head.unitsPerEm;
-              return this.hmtx.forGlyph(glyph).advance * scale;
-          };
-          TTFFont.prototype.widthOfString = function (string, size, charSpace) {
-              var charCode, i, scale, width, _i, _ref, charSpace;
-              string = '' + string;
-              width = 0;
-              for (i = _i = 0, _ref = string.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
-                  charCode = string.charCodeAt(i);
-                  width += (this.widthOfGlyph(this.characterToGlyph(charCode)) + charSpace * (1000/ size)) || 0;
-              }
-              scale = size / 1000;
-              return width * scale;
-          };
-          TTFFont.prototype.lineHeight = function (size, includeGap) {
-              var gap;
-              if (includeGap == null) {
-                  includeGap = false;
-              }
-              gap = includeGap ? this.lineGap : 0;
-              return (this.ascender + gap - this.decender) / 1000 * size;
-          };
-          return TTFFont;
-      })();
-
-      /************************************************************************************************/
-      /* function : Data                                                                              */
-      /* comment : The ttf data decoded and stored in an array is read and written to the Data object.*/
-      /************************************************************************************************/
-      var Data = (function () {
-          function Data(data) {
-              this.data = data != null ? data : [];
-              this.pos = 0;
-              this.length = this.data.length;
-          }
-          Data.prototype.readByte = function () {
-              return this.data[this.pos++];
-          };
-          Data.prototype.writeByte = function (byte) {
-              return this.data[this.pos++] = byte;
-          };
-          Data.prototype.readUInt32 = function () {
-              var b1, b2, b3, b4;
-              b1 = this.readByte() * 0x1000000;
-              b2 = this.readByte() << 16;
-              b3 = this.readByte() << 8;
-              b4 = this.readByte();
-              return b1 + b2 + b3 + b4;
-          };
-          Data.prototype.writeUInt32 = function (val) {
-              this.writeByte((val >>> 24) & 0xff);
-              this.writeByte((val >> 16) & 0xff);
-              this.writeByte((val >> 8) & 0xff);
-              return this.writeByte(val & 0xff);
-          };
-          Data.prototype.readInt32 = function () {
-              var int;
-              int = this.readUInt32();
-              if (int >= 0x80000000) {
-                  return int - 0x100000000;
-              }
-              else {
-                  return int;
-              }
-          };
-          Data.prototype.writeInt32 = function (val) {
-              if (val < 0) {
-                  val += 0x100000000;
-              }
-              return this.writeUInt32(val);
-          };
-          Data.prototype.readUInt16 = function () {
-              var b1, b2;
-              b1 = this.readByte() << 8;
-              b2 = this.readByte();
-              return b1 | b2;
-          };
-          Data.prototype.writeUInt16 = function (val) {
-              this.writeByte((val >> 8) & 0xff);
-              return this.writeByte(val & 0xff);
-          };
-          Data.prototype.readInt16 = function () {
-              var int;
-              int = this.readUInt16();
-              if (int >= 0x8000) {
-                  return int - 0x10000;
-              }
-              else {
-                  return int;
-              }
-          };
-          Data.prototype.writeInt16 = function (val) {
-              if (val < 0) {
-                  val += 0x10000;
-              }
-              return this.writeUInt16(val);
-          };
-          Data.prototype.readString = function (length) {
-              var i, ret, _i;
-              ret = [];
-              for (i = _i = 0; 0 <= length ? _i < length : _i > length; i = 0 <= length ? ++_i : --_i) {
-                  ret[i] = String.fromCharCode(this.readByte());
-              }
-              return ret.join('');
-          };
-          Data.prototype.writeString = function (val) {
-              var i, _i, _ref, _results;
-              _results = [];
-              for (i = _i = 0, _ref = val.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
-                  _results.push(this.writeByte(val.charCodeAt(i)));
-              }
-              return _results;
-          };
-          /*Data.prototype.stringAt = function (pos, length) {
-              this.pos = pos;
-              return this.readString(length);
-          };*/
-          Data.prototype.readShort = function () {
-              return this.readInt16();
-          };
-          Data.prototype.writeShort = function (val) {
-              return this.writeInt16(val);
-          };
-          Data.prototype.readLongLong = function () {
-              var b1, b2, b3, b4, b5, b6, b7, b8;
-              b1 = this.readByte();
-              b2 = this.readByte();
-              b3 = this.readByte();
-              b4 = this.readByte();
-              b5 = this.readByte();
-              b6 = this.readByte();
-              b7 = this.readByte();
-              b8 = this.readByte();
-              if (b1 & 0x80) {
-                  return ((b1 ^ 0xff) * 0x100000000000000 + (b2 ^ 0xff) * 0x1000000000000 + (b3 ^ 0xff) * 0x10000000000 + (b4 ^ 0xff) * 0x100000000 + (b5 ^ 0xff) * 0x1000000 + (b6 ^ 0xff) * 0x10000 + (b7 ^ 0xff) * 0x100 + (b8 ^ 0xff) + 1) * -1;
-              }
-              return b1 * 0x100000000000000 + b2 * 0x1000000000000 + b3 * 0x10000000000 + b4 * 0x100000000 + b5 * 0x1000000 + b6 * 0x10000 + b7 * 0x100 + b8;
-          };
-          /*Data.prototype.writeLongLong = function (val) {
-              var high, low;
-              high = Math.floor(val / 0x100000000);
-              low = val & 0xffffffff;
-              this.writeByte((high >> 24) & 0xff);
-              this.writeByte((high >> 16) & 0xff);
-              this.writeByte((high >> 8) & 0xff);
-              this.writeByte(high & 0xff);
-              this.writeByte((low >> 24) & 0xff);
-              this.writeByte((low >> 16) & 0xff);
-              this.writeByte((low >> 8) & 0xff);
-              return this.writeByte(low & 0xff);
-          };*/
-          Data.prototype.readInt = function () {
-              return this.readInt32();
-          };
-          Data.prototype.writeInt = function (val) {
-              return this.writeInt32(val);
-          };
-          /*Data.prototype.slice = function (start, end) {
-              return this.data.slice(start, end);
-          };*/
-          Data.prototype.read = function (bytes) {
-              var buf, i, _i;
-              buf = [];
-              for (i = _i = 0; 0 <= bytes ? _i < bytes : _i > bytes; i = 0 <= bytes ? ++_i : --_i) {
-                  buf.push(this.readByte());
-              }
-              return buf;
-          };
-          Data.prototype.write = function (bytes) {
-              var byte, _i, _len, _results;
-              _results = [];
-              for (_i = 0, _len = bytes.length; _i < _len; _i++) {
-                  byte = bytes[_i];
-                  _results.push(this.writeByte(byte));
-              }
-              return _results;
-          };
-          return Data;
-      })();
-
-      var Directory = (function () {
-          var checksum;
-
-          /*****************************************************************************************************/
-          /* function : Directory generator                                                                    */
-          /* comment : Initialize the offset, tag, length, and checksum for each table for the font to be used.*/
-          /*****************************************************************************************************/
-          function Directory(data) {
-              var entry, i, _i, _ref;
-              this.scalarType = data.readInt();
-              this.tableCount = data.readShort();
-              this.searchRange = data.readShort();
-              this.entrySelector = data.readShort();
-              this.rangeShift = data.readShort();
-              this.tables = {};
-              for (i = _i = 0, _ref = this.tableCount; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
-                  entry = {
-                      tag: data.readString(4)
-                      , checksum: data.readInt()
-                      , offset: data.readInt()
-                      , length: data.readInt()
-                  };
-                  this.tables[entry.tag] = entry;
-              }
-          }
-          /********************************************************************************************************/
-          /* function : encode                                                                                    */
-          /* comment : It encodes and stores the font table object and information used for the directory object. */
-          /********************************************************************************************************/
-          Directory.prototype.encode = function (tables) {
-              var adjustment, directory, directoryLength, entrySelector, headOffset, log2, offset, rangeShift, searchRange, sum, table, tableCount, tableData, tag;
-              tableCount = Object.keys(tables).length;
-              log2 = Math.log(2);
-              searchRange = Math.floor(Math.log(tableCount) / log2) * 16;
-              entrySelector = Math.floor(searchRange / log2);
-              rangeShift = tableCount * 16 - searchRange;
-              directory = new Data;
-              directory.writeInt(this.scalarType);
-              directory.writeShort(tableCount);
-              directory.writeShort(searchRange);
-              directory.writeShort(entrySelector);
-              directory.writeShort(rangeShift);
-              directoryLength = tableCount * 16;
-              offset = directory.pos + directoryLength;
-              headOffset = null;
-              tableData = [];
-              for (tag in tables) {
-                  table = tables[tag];
-                  directory.writeString(tag);
-                  directory.writeInt(checksum(table));
-                  directory.writeInt(offset);
-                  directory.writeInt(table.length);
-                  tableData = tableData.concat(table);
-                  if (tag === 'head') {
-                      headOffset = offset;
-                  }
-                  offset += table.length;
-                  while (offset % 4) {
-                      tableData.push(0);
-                      offset++;
-                  }
-              }
-              directory.write(tableData);
-              sum = checksum(directory.data);
-              adjustment = 0xB1B0AFBA - sum;
-              directory.pos = headOffset + 8;
-              directory.writeUInt32(adjustment);
-              return directory.data;
-          };
-          /***************************************************************/
-          /* function : checksum                                         */
-          /* comment : Duplicate the table for the tag.                  */
-          /***************************************************************/
-          checksum = function (data) {
-              var i, sum, tmp, _i, _ref;
-              data = __slice.call(data);
-              while (data.length % 4) {
-                  data.push(0);
-              }
-              tmp = new Data(data);
-              sum = 0;
-              for (i = _i = 0, _ref = data.length; _i < _ref; i = _i += 4) {
-                  sum += tmp.readUInt32();
-              }
-              return sum & 0xFFFFFFFF;
-          };
-          return Directory;
-      })();
-
-      var Table, __hasProp = {}.hasOwnProperty
-          , __extends = function (child, parent) {
-              for (var key in parent) {
-                  if (__hasProp.call(parent, key)) child[key] = parent[key];
-              }
-
-              function ctor() {
-                  this.constructor = child;
-              }
-              ctor.prototype = parent.prototype;
-              child.prototype = new ctor();
-              child.__super__ = parent.prototype;
-              return child;
-      };
-      /***************************************************************/
-      /* function : Table                                            */
-      /* comment : Save info for each table, and parse the table.    */
-      /***************************************************************/
-      Table = (function () {
-          function Table(file) {
-              var info;
-              this.file = file;
-              info = this.file.directory.tables[this.tag];
-              this.exists = !!info;
-              if (info) {
-                  this.offset = info.offset, this.length = info.length;
-                  this.parse(this.file.contents);
-              }
-          }
-          Table.prototype.parse = function () {};
-          Table.prototype.encode = function () {};
-          Table.prototype.raw = function () {
-              if (!this.exists) {
-                  return null;
-              }
-              this.file.contents.pos = this.offset;
-              return this.file.contents.read(this.length);
-          };
-          return Table;
-      })();
-
-      var HeadTable = (function (_super) {
-          __extends(HeadTable, _super);
-
-          function HeadTable() {
-              return HeadTable.__super__.constructor.apply(this, arguments);
-          }
-          HeadTable.prototype.tag = 'head';
-          HeadTable.prototype.parse = function (data) {
-              data.pos = this.offset;
-              this.version = data.readInt();
-              this.revision = data.readInt();
-              this.checkSumAdjustment = data.readInt();
-              this.magicNumber = data.readInt();
-              this.flags = data.readShort();
-              this.unitsPerEm = data.readShort();
-              this.created = data.readLongLong();
-              this.modified = data.readLongLong();
-              this.xMin = data.readShort();
-              this.yMin = data.readShort();
-              this.xMax = data.readShort();
-              this.yMax = data.readShort();
-              this.macStyle = data.readShort();
-              this.lowestRecPPEM = data.readShort();
-              this.fontDirectionHint = data.readShort();
-              this.indexToLocFormat = data.readShort();
-              return this.glyphDataFormat = data.readShort();
-          };
-          /*HeadTable.prototype.encode = function (loca) {
-              var table;
-              table = new Data;
-              table.writeInt(this.version);
-              table.writeInt(this.revision);
-              table.writeInt(this.checkSumAdjustment);
-              table.writeInt(this.magicNumber);
-              table.writeShort(this.flags);
-              table.writeShort(this.unitsPerEm);
-              table.writeLongLong(this.created);
-              table.writeLongLong(this.modified);
-              table.writeShort(this.xMin);
-              table.writeShort(this.yMin);
-              table.writeShort(this.xMax);
-              table.writeShort(this.yMax);
-              table.writeShort(this.macStyle);
-              table.writeShort(this.lowestRecPPEM);
-              table.writeShort(this.fontDirectionHint);
-              table.writeShort(loca.type);
-              table.writeShort(this.glyphDataFormat);
-              return table.data;
-          };*/
-          return HeadTable;
-      })(Table);
-
-      /************************************************************************************/
-      /* function : CmapEntry                                                             */
-      /* comment : Cmap Initializes and encodes object information (required by pdf spec).*/
-      /************************************************************************************/
-      var CmapEntry = (function () {
-          function CmapEntry(data, offset) {
-              var code, count, endCode, glyphId, glyphIds, i, idDelta, idRangeOffset, index, saveOffset, segCount, segCountX2, start, startCode, tail, _i, _j, _k, _len;
-              this.platformID = data.readUInt16();
-              this.encodingID = data.readShort();
-              this.offset = offset + data.readInt();
-              saveOffset = data.pos;
-              data.pos = this.offset;
-              this.format = data.readUInt16();
-              this.length = data.readUInt16();
-              this.language = data.readUInt16();
-              this.isUnicode = (this.platformID === 3 && this.encodingID === 1 && this.format === 4) || this.platformID === 0 && this.format === 4;
-              this.codeMap = {};
-              switch (this.format) {
-              case 0:
-                  for (i = _i = 0; _i < 256; i = ++_i) {
-                      this.codeMap[i] = data.readByte();
-                  }
-                  break;
-              case 4:
-                  segCountX2 = data.readUInt16();
-                  segCount = segCountX2 / 2;
-                  data.pos += 6;
-                  endCode = (function () {
-                      var _j, _results;
-                      _results = [];
-                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
-                          _results.push(data.readUInt16());
-                      }
-                      return _results;
-                  })();
-                  data.pos += 2;
-                  startCode = (function () {
-                      var _j, _results;
-                      _results = [];
-                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
-                          _results.push(data.readUInt16());
-                      }
-                      return _results;
-                  })();
-                  idDelta = (function () {
-                      var _j, _results;
-                      _results = [];
-                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
-                          _results.push(data.readUInt16());
-                      }
-                      return _results;
-                  })();
-                  idRangeOffset = (function () {
-                      var _j, _results;
-                      _results = [];
-                      for (i = _j = 0; 0 <= segCount ? _j < segCount : _j > segCount; i = 0 <= segCount ? ++_j : --_j) {
-                          _results.push(data.readUInt16());
-                      }
-                      return _results;
-                  })();
-                  count = (this.length - data.pos + this.offset) / 2;
-                  glyphIds = (function () {
-                      var _j, _results;
-                      _results = [];
-                      for (i = _j = 0; 0 <= count ? _j < count : _j > count; i = 0 <= count ? ++_j : --_j) {
-                          _results.push(data.readUInt16());
-                      }
-                      return _results;
-                  })();
-                  for (i = _j = 0, _len = endCode.length; _j < _len; i = ++_j) {
-                      tail = endCode[i];
-                      start = startCode[i];
-                      for (code = _k = start; start <= tail ? _k <= tail : _k >= tail; code = start <= tail ? ++_k : --_k) {
-                          if (idRangeOffset[i] === 0) {
-                              glyphId = code + idDelta[i];
-                          }
-                          else {
-                              index = idRangeOffset[i] / 2 + (code - start) - (segCount - i);
-                              glyphId = glyphIds[index] || 0;
-                              if (glyphId !== 0) {
-                                  glyphId += idDelta[i];
-                              }
-                          }
-                          this.codeMap[code] = glyphId & 0xFFFF;
-                      }
-                  }
-              }
-              data.pos = saveOffset;
-          }
-          CmapEntry.encode = function (charmap, encoding) {
-              var charMap, code, codeMap, codes, delta, deltas, diff, endCode, endCodes, entrySelector, glyphIDs, i, id, indexes, last, map, nextID, offset, old, rangeOffsets, rangeShift, result, searchRange, segCount, segCountX2, startCode, startCodes, startGlyph, subtable, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _len6, _len7, _m, _n, _name, _o, _p, _q;
-              subtable = new Data;
-              codes = Object.keys(charmap).sort(function (a, b) {
-                  return a - b;
-              });
-              switch (encoding) {
-              case 'macroman':
-                  id = 0;
-                  indexes = (function () {
-                      var _i, _results;
-                      _results = [];
-                      for (i = _i = 0; _i < 256; i = ++_i) {
-                          _results.push(0);
-                      }
-                      return _results;
-                  })();
-                  map = {
-                      0: 0
-                  };
-                  codeMap = {};
-                  for (_i = 0, _len = codes.length; _i < _len; _i++) {
-                      code = codes[_i];
-                      if (map[_name = charmap[code]] == null) {
-                          map[_name] = ++id;
-                      }
-                      codeMap[code] = {
-                          old: charmap[code]
-                          , "new": map[charmap[code]]
-                      };
-                      indexes[code] = map[charmap[code]];
-                  }
-                  subtable.writeUInt16(1);
-                  subtable.writeUInt16(0);
-                  subtable.writeUInt32(12);
-                  subtable.writeUInt16(0);
-                  subtable.writeUInt16(262);
-                  subtable.writeUInt16(0);
-                  subtable.write(indexes);
-                  return result = {
-                      charMap: codeMap
-                      , subtable: subtable.data
-                      , maxGlyphID: id + 1
-                  };
-              case 'unicode':
-                  startCodes = [];
-                  endCodes = [];
-                  nextID = 0;
-                  map = {};
-                  charMap = {};
-                  last = diff = null;
-                  for (_j = 0, _len1 = codes.length; _j < _len1; _j++) {
-                      code = codes[_j];
-                      old = charmap[code];
-                      if (map[old] == null) {
-                          map[old] = ++nextID;
-                      }
-                      charMap[code] = {
-                          old: old
-                          , "new": map[old]
-                      };
-                      delta = map[old] - code;
-                      if ((last == null) || delta !== diff) {
-                          if (last) {
-                              endCodes.push(last);
-                          }
-                          startCodes.push(code);
-                          diff = delta;
-                      }
-                      last = code;
-                  }
-                  if (last) {
-                      endCodes.push(last);
-                  }
-                  endCodes.push(0xFFFF);
-                  startCodes.push(0xFFFF);
-                  segCount = startCodes.length;
-                  segCountX2 = segCount * 2;
-                  searchRange = 2 * Math.pow(Math.log(segCount) / Math.LN2, 2);
-                  entrySelector = Math.log(searchRange / 2) / Math.LN2;
-                  rangeShift = 2 * segCount - searchRange;
-                  deltas = [];
-                  rangeOffsets = [];
-                  glyphIDs = [];
-                  for (i = _k = 0, _len2 = startCodes.length; _k < _len2; i = ++_k) {
-                      startCode = startCodes[i];
-                      endCode = endCodes[i];
-                      if (startCode === 0xFFFF) {
-                          deltas.push(0);
-                          rangeOffsets.push(0);
-                          break;
-                      }
-                      startGlyph = charMap[startCode]["new"];
-                      if (startCode - startGlyph >= 0x8000) {
-                          deltas.push(0);
-                          rangeOffsets.push(2 * (glyphIDs.length + segCount - i));
-                          for (code = _l = startCode; startCode <= endCode ? _l <= endCode : _l >= endCode; code = startCode <= endCode ? ++_l : --_l) {
-                              glyphIDs.push(charMap[code]["new"]);
-                          }
-                      }
-                      else {
-                          deltas.push(startGlyph - startCode);
-                          rangeOffsets.push(0);
-                      }
-                  }
-                  subtable.writeUInt16(3);
-                  subtable.writeUInt16(1);
-                  subtable.writeUInt32(12);
-                  subtable.writeUInt16(4);
-                  subtable.writeUInt16(16 + segCount * 8 + glyphIDs.length * 2);
-                  subtable.writeUInt16(0);
-                  subtable.writeUInt16(segCountX2);
-                  subtable.writeUInt16(searchRange);
-                  subtable.writeUInt16(entrySelector);
-                  subtable.writeUInt16(rangeShift);
-                  for (_m = 0, _len3 = endCodes.length; _m < _len3; _m++) {
-                      code = endCodes[_m];
-                      subtable.writeUInt16(code);
-                  }
-                  subtable.writeUInt16(0);
-                  for (_n = 0, _len4 = startCodes.length; _n < _len4; _n++) {
-                      code = startCodes[_n];
-                      subtable.writeUInt16(code);
-                  }
-                  for (_o = 0, _len5 = deltas.length; _o < _len5; _o++) {
-                      delta = deltas[_o];
-                      subtable.writeUInt16(delta);
-                  }
-                  for (_p = 0, _len6 = rangeOffsets.length; _p < _len6; _p++) {
-                      offset = rangeOffsets[_p];
-                      subtable.writeUInt16(offset);
-                  }
-                  for (_q = 0, _len7 = glyphIDs.length; _q < _len7; _q++) {
-                      id = glyphIDs[_q];
-                      subtable.writeUInt16(id);
-                  }
-                  return result = {
-                      charMap: charMap
-                      , subtable: subtable.data
-                      , maxGlyphID: nextID + 1
-                  };
-              }
-          };
-          return CmapEntry;
-      })();
-
-      var CmapTable = (function (_super) {
-          __extends(CmapTable, _super);
-
-          function CmapTable() {
-              return CmapTable.__super__.constructor.apply(this, arguments);
-          }
-          CmapTable.prototype.tag = 'cmap';
-          CmapTable.prototype.parse = function (data) {
-              var entry, i, tableCount, _i;
-              data.pos = this.offset;
-              this.version = data.readUInt16();
-              tableCount = data.readUInt16();
-              this.tables = [];
-              this.unicode = null;
-              for (i = _i = 0; 0 <= tableCount ? _i < tableCount : _i > tableCount; i = 0 <= tableCount ? ++_i : --_i) {
-                  entry = new CmapEntry(data, this.offset);
-                  this.tables.push(entry);
-                  if (entry.isUnicode) {
-                      if (this.unicode == null) {
-                          this.unicode = entry;
-                      }
-                  }
-              }
-              return true;
-          };
-          /*************************************************************************/
-          /* function : encode                                                     */
-          /* comment : Encode the cmap table corresponding to the input character. */
-          /*************************************************************************/
-          CmapTable.encode = function (charmap, encoding) {
-              var result, table;
-              if (encoding == null) {
-                  encoding = 'macroman';
-              }
-              result = CmapEntry.encode(charmap, encoding);
-              table = new Data;
-              table.writeUInt16(0);
-              table.writeUInt16(1);
-              result.table = table.data.concat(result.subtable);
-              return result;
-          };
-          return CmapTable;
-      })(Table);
-
-      var HheaTable = (function (_super) {
-          __extends(HheaTable, _super);
-
-          function HheaTable() {
-              return HheaTable.__super__.constructor.apply(this, arguments);
-          }
-          HheaTable.prototype.tag = 'hhea';
-          HheaTable.prototype.parse = function (data) {
-              data.pos = this.offset;
-              this.version = data.readInt();
-              this.ascender = data.readShort();
-              this.decender = data.readShort();
-              this.lineGap = data.readShort();
-              this.advanceWidthMax = data.readShort();
-              this.minLeftSideBearing = data.readShort();
-              this.minRightSideBearing = data.readShort();
-              this.xMaxExtent = data.readShort();
-              this.caretSlopeRise = data.readShort();
-              this.caretSlopeRun = data.readShort();
-              this.caretOffset = data.readShort();
-              data.pos += 4 * 2;
-              this.metricDataFormat = data.readShort();
-              return this.numberOfMetrics = data.readUInt16();
-          };
-          /*HheaTable.prototype.encode = function (ids) {
-              var i, table, _i, _ref;
-              table = new Data;
-              table.writeInt(this.version);
-              table.writeShort(this.ascender);
-              table.writeShort(this.decender);
-              table.writeShort(this.lineGap);
-              table.writeShort(this.advanceWidthMax);
-              table.writeShort(this.minLeftSideBearing);
-              table.writeShort(this.minRightSideBearing);
-              table.writeShort(this.xMaxExtent);
-              table.writeShort(this.caretSlopeRise);
-              table.writeShort(this.caretSlopeRun);
-              table.writeShort(this.caretOffset);
-              for (i = _i = 0, _ref = 4 * 2; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
-                  table.writeByte(0);
-              }
-              table.writeShort(this.metricDataFormat);
-              table.writeUInt16(ids.length);
-              return table.data;
-          };*/
-          return HheaTable;
-      })(Table);
-
-      var OS2Table = (function (_super) {
-          __extends(OS2Table, _super);
-
-          function OS2Table() {
-              return OS2Table.__super__.constructor.apply(this, arguments);
-          }
-          OS2Table.prototype.tag = 'OS/2';
-          OS2Table.prototype.parse = function (data) {
-              var i;
-              data.pos = this.offset;
-              this.version = data.readUInt16();
-              this.averageCharWidth = data.readShort();
-              this.weightClass = data.readUInt16();
-              this.widthClass = data.readUInt16();
-              this.type = data.readShort();
-              this.ySubscriptXSize = data.readShort();
-              this.ySubscriptYSize = data.readShort();
-              this.ySubscriptXOffset = data.readShort();
-              this.ySubscriptYOffset = data.readShort();
-              this.ySuperscriptXSize = data.readShort();
-              this.ySuperscriptYSize = data.readShort();
-              this.ySuperscriptXOffset = data.readShort();
-              this.ySuperscriptYOffset = data.readShort();
-              this.yStrikeoutSize = data.readShort();
-              this.yStrikeoutPosition = data.readShort();
-              this.familyClass = data.readShort();
-              this.panose = (function () {
-                  var _i, _results;
-                  _results = [];
-                  for (i = _i = 0; _i < 10; i = ++_i) {
-                      _results.push(data.readByte());
-                  }
-                  return _results;
-              })();
-              this.charRange = (function () {
-                  var _i, _results;
-                  _results = [];
-                  for (i = _i = 0; _i < 4; i = ++_i) {
-                      _results.push(data.readInt());
-                  }
-                  return _results;
-              })();
-              this.vendorID = data.readString(4);
-              this.selection = data.readShort();
-              this.firstCharIndex = data.readShort();
-              this.lastCharIndex = data.readShort();
-              if (this.version > 0) {
-                  this.ascent = data.readShort();
-                  this.descent = data.readShort();
-                  this.lineGap = data.readShort();
-                  this.winAscent = data.readShort();
-                  this.winDescent = data.readShort();
-                  this.codePageRange = (function () {
-                      var _i, _results;
-                      _results = [];
-                      for (i = _i = 0; _i < 2; i = ++_i) {
-                          _results.push(data.readInt());
-                      }
-                      return _results;
-                  })();
-                  if (this.version > 1) {
-                      this.xHeight = data.readShort();
-                      this.capHeight = data.readShort();
-                      this.defaultChar = data.readShort();
-                      this.breakChar = data.readShort();
-                      return this.maxContext = data.readShort();
-                  }
-              }
-          };
-          /*OS2Table.prototype.encode = function () {
-              return this.raw();
-          };*/
-          return OS2Table;
-      })(Table);
-
-      var PostTable = (function (_super) {
-          __extends(PostTable, _super);
-
-          function PostTable() {
-              return PostTable.__super__.constructor.apply(this, arguments);
-          }
-          PostTable.prototype.tag = 'post';
-          PostTable.prototype.parse = function (data) {
-              var i, length, numberOfGlyphs, _i, _results;
-              data.pos = this.offset;
-              this.format = data.readInt();
-              this.italicAngle = data.readInt();
-              this.underlinePosition = data.readShort();
-              this.underlineThickness = data.readShort();
-              this.isFixedPitch = data.readInt();
-              this.minMemType42 = data.readInt();
-              this.maxMemType42 = data.readInt();
-              this.minMemType1 = data.readInt();
-              this.maxMemType1 = data.readInt();
-              switch (this.format) {
-              case 0x00010000:
-                  break;
-              case 0x00020000:
-                  numberOfGlyphs = data.readUInt16();
-                  this.glyphNameIndex = [];
-                  for (i = _i = 0; 0 <= numberOfGlyphs ? _i < numberOfGlyphs : _i > numberOfGlyphs; i = 0 <= numberOfGlyphs ? ++_i : --_i) {
-                      this.glyphNameIndex.push(data.readUInt16());
-                  }
-                  this.names = [];
-                  _results = [];
-                  while (data.pos < this.offset + this.length) {
-                      length = data.readByte();
-                      _results.push(this.names.push(data.readString(length)));
-                  }
-                  return _results;
-                  break;
-              case 0x00025000:
-                  numberOfGlyphs = data.readUInt16();
-                  return this.offsets = data.read(numberOfGlyphs);
-              case 0x00030000:
-                  break;
-              case 0x00040000:
-                  return this.map = (function () {
-                      var _j, _ref, _results1;
-                      _results1 = [];
-                      for (i = _j = 0, _ref = this.file.maxp.numGlyphs; 0 <= _ref ? _j < _ref : _j > _ref; i = 0 <= _ref ? ++_j : --_j) {
-                          _results1.push(data.readUInt32());
-                      }
-                      return _results1;
-                  }).call(this);
-              }
-          };
-          return PostTable;
-      })(Table);
-
-      /*********************************************************************************************************/
-      /* function : NameEntry                                                                                  */
-      /* comment : Store copyright information, platformID, encodingID, and languageID in the NameEntry object.*/
-      /*********************************************************************************************************/
-      var NameEntry = (function () {
-          function NameEntry(raw, entry) {
-              this.raw = raw;
-              this.length = raw.length;
-              this.platformID = entry.platformID;
-              this.encodingID = entry.encodingID;
-              this.languageID = entry.languageID;
-          }
-          return NameEntry;
-      })();
-
-      var NameTable = (function (_super) {
-          __extends(NameTable, _super);
-
-          function NameTable() {
-              return NameTable.__super__.constructor.apply(this, arguments);
-          }
-          NameTable.prototype.tag = 'name';
-          NameTable.prototype.parse = function (data) {
-              var count, entries, entry, format, i, name, stringOffset, strings, text, _i, _j, _len, _name;
-              data.pos = this.offset;
-              format = data.readShort();
-              count = data.readShort();
-              stringOffset = data.readShort();
-              entries = [];
-              for (i = _i = 0; 0 <= count ? _i < count : _i > count; i = 0 <= count ? ++_i : --_i) {
-                  entries.push({
-                      platformID: data.readShort()
-                      , encodingID: data.readShort()
-                      , languageID: data.readShort()
-                      , nameID: data.readShort()
-                      , length: data.readShort()
-                      , offset: this.offset + stringOffset + data.readShort()
-                  });
-              }
-              strings = {};
-              for (i = _j = 0, _len = entries.length; _j < _len; i = ++_j) {
-                  entry = entries[i];
-                  data.pos = entry.offset;
-                  text = data.readString(entry.length);
-                  name = new NameEntry(text, entry);
-                  if (strings[_name = entry.nameID] == null) {
-                      strings[_name] = [];
-                  }
-                  strings[entry.nameID].push(name);
-              }
-              this.strings = strings;
-              this.copyright = strings[0];
-              this.fontFamily = strings[1];
-              this.fontSubfamily = strings[2];
-              this.uniqueSubfamily = strings[3];
-              this.fontName = strings[4];
-              this.version = strings[5];
-              this.postscriptName = strings[6][0].raw.replace(/[\x00-\x19\x80-\xff]/g, "");
-              this.trademark = strings[7];
-              this.manufacturer = strings[8];
-              this.designer = strings[9];
-              this.description = strings[10];
-              this.vendorUrl = strings[11];
-              this.designerUrl = strings[12];
-              this.license = strings[13];
-              this.licenseUrl = strings[14];
-              this.preferredFamily = strings[15];
-              this.preferredSubfamily = strings[17];
-              this.compatibleFull = strings[18];
-              return this.sampleText = strings[19];
-          };
-          /*NameTable.prototype.encode = function () {
-              var id, list, nameID, nameTable, postscriptName, strCount, strTable, string, strings, table, val, _i, _len, _ref;
-              strings = {};
-              _ref = this.strings;
-              for (id in _ref) {
-                  val = _ref[id];
-                  strings[id] = val;
-              }
-              postscriptName = new NameEntry("" + subsetTag + "+" + this.postscriptName, {
-                  platformID: 1
-                  , encodingID: 0
-                  , languageID: 0
-              });
-              strings[6] = [postscriptName];
-              subsetTag = successorOf(subsetTag);
-              strCount = 0;
-              for (id in strings) {
-                  list = strings[id];
-                  if (list != null) {
-                      strCount += list.length;
-                  }
-              }
-              table = new Data;
-              strTable = new Data;
-              table.writeShort(0);
-              table.writeShort(strCount);
-              table.writeShort(6 + 12 * strCount);
-              for (nameID in strings) {
-                  list = strings[nameID];
-                  if (list != null) {
-                      for (_i = 0, _len = list.length; _i < _len; _i++) {
-                          string = list[_i];
-                          table.writeShort(string.platformID);
-                          table.writeShort(string.encodingID);
-                          table.writeShort(string.languageID);
-                          table.writeShort(nameID);
-                          table.writeShort(string.length);
-                          table.writeShort(strTable.pos);
-                          strTable.writeString(string.raw);
-                      }
-                  }
-              }
-              return nameTable = {
-                  postscriptName: postscriptName.raw
-                  , table: table.data.concat(strTable.data)
-              };
-          };*/
-          return NameTable;
-      })(Table);
-
-      var MaxpTable = (function (_super) {
-          __extends(MaxpTable, _super);
-
-          function MaxpTable() {
-              return MaxpTable.__super__.constructor.apply(this, arguments);
-          }
-          MaxpTable.prototype.tag = 'maxp';
-          MaxpTable.prototype.parse = function (data) {
-              data.pos = this.offset;
-              this.version = data.readInt();
-              this.numGlyphs = data.readUInt16();
-              this.maxPoints = data.readUInt16();
-              this.maxContours = data.readUInt16();
-              this.maxCompositePoints = data.readUInt16();
-              this.maxComponentContours = data.readUInt16();
-              this.maxZones = data.readUInt16();
-              this.maxTwilightPoints = data.readUInt16();
-              this.maxStorage = data.readUInt16();
-              this.maxFunctionDefs = data.readUInt16();
-              this.maxInstructionDefs = data.readUInt16();
-              this.maxStackElements = data.readUInt16();
-              this.maxSizeOfInstructions = data.readUInt16();
-              this.maxComponentElements = data.readUInt16();
-              return this.maxComponentDepth = data.readUInt16();
-          };
-          /*MaxpTable.prototype.encode = function (ids) {
-              var table;
-              table = new Data;
-              table.writeInt(this.version);
-              table.writeUInt16(ids.length);
-              table.writeUInt16(this.maxPoints);
-              table.writeUInt16(this.maxContours);
-              table.writeUInt16(this.maxCompositePoints);
-              table.writeUInt16(this.maxComponentContours);
-              table.writeUInt16(this.maxZones);
-              table.writeUInt16(this.maxTwilightPoints);
-              table.writeUInt16(this.maxStorage);
-              table.writeUInt16(this.maxFunctionDefs);
-              table.writeUInt16(this.maxInstructionDefs);
-              table.writeUInt16(this.maxStackElements);
-              table.writeUInt16(this.maxSizeOfInstructions);
-              table.writeUInt16(this.maxComponentElements);
-              table.writeUInt16(this.maxComponentDepth);
-              return table.data;
-          };*/
-          return MaxpTable;
-      })(Table);
-
-      var HmtxTable = (function (_super) {
-          __extends(HmtxTable, _super);
-
-          function HmtxTable() {
-              return HmtxTable.__super__.constructor.apply(this, arguments);
-          }
-          HmtxTable.prototype.tag = 'hmtx';
-          HmtxTable.prototype.parse = function (data) {
-              var i, last, lsbCount, m, _i, _j, _ref, _results;
-              data.pos = this.offset;
-              this.metrics = [];
-              for (i = _i = 0, _ref = this.file.hhea.numberOfMetrics; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
-                  this.metrics.push({
-                      advance: data.readUInt16()
-                      , lsb: data.readInt16()
-                  });
-              }
-              lsbCount = this.file.maxp.numGlyphs - this.file.hhea.numberOfMetrics;
-              this.leftSideBearings = (function () {
-                  var _j, _results;
-                  _results = [];
-                  for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) {
-                      _results.push(data.readInt16());
-                  }
-                  return _results;
-              })();
-              this.widths = (function () {
-                  var _j, _len, _ref1, _results;
-                  _ref1 = this.metrics;
-                  _results = [];
-                  for (_j = 0, _len = _ref1.length; _j < _len; _j++) {
-                      m = _ref1[_j];
-                      _results.push(m.advance);
-                  }
-                  return _results;
-              }).call(this);
-              last = this.widths[this.widths.length - 1];
-              _results = [];
-              for (i = _j = 0; 0 <= lsbCount ? _j < lsbCount : _j > lsbCount; i = 0 <= lsbCount ? ++_j : --_j) {
-                  _results.push(this.widths.push(last));
-              }
-              return _results;
-          };
-          /***************************************************************/
-          /* function : forGlyph                                         */
-          /* comment : Returns the advance width and lsb for this glyph. */
-          /***************************************************************/
-          HmtxTable.prototype.forGlyph = function (id) {
-              var metrics;
-              if (id in this.metrics) {
-                  return this.metrics[id];
-              }
-              return metrics = {
-                  advance: this.metrics[this.metrics.length - 1].advance
-                  , lsb: this.leftSideBearings[id - this.metrics.length]
-              };
-          };
-          /*HmtxTable.prototype.encode = function (mapping) {
-              var id, metric, table, _i, _len;
-              table = new Data;
-              for (_i = 0, _len = mapping.length; _i < _len; _i++) {
-                  id = mapping[_i];
-                  metric = this.forGlyph(id);
-                  table.writeUInt16(metric.advance);
-                  table.writeUInt16(metric.lsb);
-              }
-              return table.data;
-          };*/
-          return HmtxTable;
-      })(Table);
-
-      var __slice = [].slice;
-
-      var GlyfTable = (function (_super) {
-          __extends(GlyfTable, _super);
-
-          function GlyfTable() {
-              return GlyfTable.__super__.constructor.apply(this, arguments);
-          }
-          GlyfTable.prototype.tag = 'glyf';
-          GlyfTable.prototype.parse = function (data) {
-              return this.cache = {};
-          };
-          GlyfTable.prototype.glyphFor = function (id) {
-              id = id;
-              var data, index, length, loca, numberOfContours, raw, xMax, xMin, yMax, yMin;
-              if (id in this.cache) {
-                  return this.cache[id];
-              }
-              loca = this.file.loca;
-              data = this.file.contents;
-              index = loca.indexOf(id);
-              length = loca.lengthOf(id);
-              if (length === 0) {
-                  return this.cache[id] = null;
-              }
-              data.pos = this.offset + index;
-              raw = new Data(data.read(length));
-              numberOfContours = raw.readShort();
-              xMin = raw.readShort();
-              yMin = raw.readShort();
-              xMax = raw.readShort();
-              yMax = raw.readShort();
-              if (numberOfContours === -1) {
-                  this.cache[id] = new CompoundGlyph(raw, xMin, yMin, xMax, yMax);
-              }
-              else {
-                  this.cache[id] = new SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax);
-              }
-              return this.cache[id];
-          };
-          GlyfTable.prototype.encode = function (glyphs, mapping, old2new) {
-              var glyph, id, offsets, table, _i, _len;
-              table = [];
-              offsets = [];
-              for (_i = 0, _len = mapping.length; _i < _len; _i++) {
-                  id = mapping[_i];
-                  glyph = glyphs[id];
-                  offsets.push(table.length);
-                  if (glyph) {
-                      table = table.concat(glyph.encode(old2new));
-                  }
-              }
-              offsets.push(table.length);
-              return {
-                  table: table
-                  , offsets: offsets
-              };
-          };
-          return GlyfTable;
-      })(Table);
-
-      var SimpleGlyph = (function () {
-          /**************************************************************************/
-          /* function : SimpleGlyph                                                 */
-          /* comment : Stores raw, xMin, yMin, xMax, and yMax values for this glyph.*/
-          /**************************************************************************/
-          function SimpleGlyph(raw, numberOfContours, xMin, yMin, xMax, yMax) {
-              this.raw = raw;
-              this.numberOfContours = numberOfContours;
-              this.xMin = xMin;
-              this.yMin = yMin;
-              this.xMax = xMax;
-              this.yMax = yMax;
-              this.compound = false;
-          }
-          SimpleGlyph.prototype.encode = function () {
-              return this.raw.data;
-          };
-          return SimpleGlyph;
-      })();
-
-      var CompoundGlyph = (function () {
-          var ARG_1_AND_2_ARE_WORDS, MORE_COMPONENTS, WE_HAVE_AN_X_AND_Y_SCALE, WE_HAVE_A_SCALE, WE_HAVE_A_TWO_BY_TWO;
-          ARG_1_AND_2_ARE_WORDS = 0x0001;
-          WE_HAVE_A_SCALE = 0x0008;
-          MORE_COMPONENTS = 0x0020;
-          WE_HAVE_AN_X_AND_Y_SCALE = 0x0040;
-          WE_HAVE_A_TWO_BY_TWO = 0x0080;
-
-          /********************************************************************************************************************/
-          /* function : CompoundGlypg generator                                                                               */
-          /* comment : It stores raw, xMin, yMin, xMax, yMax, glyph id, and glyph offset for the corresponding compound glyph.*/
-          /********************************************************************************************************************/
-          function CompoundGlyph(raw, xMin, yMin, xMax, yMax) {
-              var data, flags;
-              this.raw = raw;
-              this.xMin = xMin;
-              this.yMin = yMin;
-              this.xMax = xMax;
-              this.yMax = yMax;
-              this.compound = true;
-              this.glyphIDs = [];
-              this.glyphOffsets = [];
-              data = this.raw;
-              while (true) {
-                  flags = data.readShort();
-                  this.glyphOffsets.push(data.pos);
-                  this.glyphIDs.push(data.readShort());
-                  if (!(flags & MORE_COMPONENTS)) {
-                      break;
-                  }
-                  if (flags & ARG_1_AND_2_ARE_WORDS) {
-                      data.pos += 4;
-                  }
-                  else {
-                      data.pos += 2;
-                  }
-                  if (flags & WE_HAVE_A_TWO_BY_TWO) {
-                      data.pos += 8;
-                  }
-                  else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
-                      data.pos += 4;
-                  }
-                  else if (flags & WE_HAVE_A_SCALE) {
-                      data.pos += 2;
-                  }
-              }
-          }
-          /****************************************************************************************************************/
-          /* function : CompoundGlypg encode                                                                              */
-          /* comment : After creating a table for the characters you typed, you call directory.encode to encode the table.*/
-          /****************************************************************************************************************/
-          CompoundGlyph.prototype.encode = function (mapping) {
-              var i, id, result, _i, _len, _ref;
-              result = new Data(__slice.call(this.raw.data));
-              _ref = this.glyphIDs;
-              for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
-                  id = _ref[i];
-                  result.pos = this.glyphOffsets[i];
-              }
-              return result.data;
-          };
-          return CompoundGlyph;
-      })();
-
-      var LocaTable = (function (_super) {
-          __extends(LocaTable, _super);
-
-          function LocaTable() {
-              return LocaTable.__super__.constructor.apply(this, arguments);
-          }
-          LocaTable.prototype.tag = 'loca';
-          LocaTable.prototype.parse = function (data) {
-              var format, i;
-              data.pos = this.offset;
-              format = this.file.head.indexToLocFormat;
-              if (format === 0) {
-                  return this.offsets = (function () {
-                      var _i, _ref, _results;
-                      _results = [];
-                      for (i = _i = 0, _ref = this.length; _i < _ref; i = _i += 2) {
-                          _results.push(data.readUInt16() * 2);
-                      }
-                      return _results;
-                  }).call(this);
-              }
-              else {
-                  return this.offsets = (function () {
-                      var _i, _ref, _results;
-                      _results = [];
-                      for (i = _i = 0, _ref = this.length; _i < _ref; i = _i += 4) {
-                          _results.push(data.readUInt32());
-                      }
-                      return _results;
-                  }).call(this);
-              }
-          };
-          LocaTable.prototype.indexOf = function (id) {
-              return this.offsets[id];
-          };
-          LocaTable.prototype.lengthOf = function (id) {
-              return this.offsets[id + 1] - this.offsets[id];
-          };
-          LocaTable.prototype.encode = function (offsets, activeGlyphs) {
-              var LocaTable = new Uint32Array(this.offsets.length);
-              var glyfPtr = 0;
-              var listGlyf = 0;
-              for (var k = 0; k < LocaTable.length; ++k) {
-                  LocaTable[k] = glyfPtr;
-                  if (listGlyf < activeGlyphs.length && activeGlyphs[listGlyf] == k) {
-                      ++listGlyf;
-                      LocaTable[k] = glyfPtr;
-                      var start = this.offsets[k];
-                      var len = this.offsets[k + 1] - start;
-                      if (len > 0) {
-                          glyfPtr += len;
-                      }
-                  }
-              }
-              var newLocaTable = new Array(LocaTable.length * 4);
-              for (var j = 0; j < LocaTable.length; ++j) {
-                  newLocaTable[4 * j + 3] = (LocaTable[j] & 0x000000ff);
-                  newLocaTable[4 * j + 2] = (LocaTable[j] & 0x0000ff00) >> 8;
-                  newLocaTable[4 * j + 1] = (LocaTable[j] & 0x00ff0000) >> 16;
-                  newLocaTable[4 * j] = (LocaTable[j] & 0xff000000) >> 24;
-              }
-              return newLocaTable;
-          };
-          return LocaTable;
-      })(Table);
-
-      /************************************************************************************/
-      /* function : invert                                                                */
-      /* comment : Change the object's (key: value) to create an object with (value: key).*/
-      /************************************************************************************/
-      var invert = function (object) {
-          var key, ret, val;
-          ret = {};
-          for (key in object) {
-              val = object[key];
-              ret[val] = key;
-          }
-          return ret;
-      };
-
-      /*var successorOf = function (input) {
-          var added, alphabet, carry, i, index, isUpperCase, last, length, next, result;
-          alphabet = 'abcdefghijklmnopqrstuvwxyz';
-          length = alphabet.length;
-          result = input;
-          i = input.length;
-          while (i >= 0) {
-              last = input.charAt(--i);
-              if (isNaN(last)) {
-                  index = alphabet.indexOf(last.toLowerCase());
-                  if (index === -1) {
-                      next = last;
-                      carry = true;
-                  }
-                  else {
-                      next = alphabet.charAt((index + 1) % length);
-                      isUpperCase = last === last.toUpperCase();
-                      if (isUpperCase) {
-                          next = next.toUpperCase();
-                      }
-                      carry = index + 1 >= length;
-                      if (carry && i === 0) {
-                          added = isUpperCase ? 'A' : 'a';
-                          result = added + next + result.slice(1);
-                          break;
-                      }
-                  }
-              }
-              else {
-                  next = +last + 1;
-                  carry = next > 9;
-                  if (carry) {
-                      next = 0;
-                  }
-                  if (carry && i === 0) {
-                      result = '1' + next + result.slice(1);
-                      break;
-                  }
-              }
-              result = result.slice(0, i) + next + result.slice(i + 1);
-              if (!carry) {
-                  break;
-              }
-          }
-          return result;
-      };*/
-
-      var Subset = (function () {
-          function Subset(font) {
-              this.font = font;
-              this.subset = {};
-              this.unicodes = {};
-              this.next = 33;
-          }
-          /*Subset.prototype.use = function (character) {
-              var i, _i, _ref;
-              if (typeof character === 'string') {
-                  for (i = _i = 0, _ref = character.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
-                      this.use(character.charCodeAt(i));
-                  }
-                  return;
-              }
-              if (!this.unicodes[character]) {
-                  this.subset[this.next] = character;
-                  return this.unicodes[character] = this.next++;
-              }
-          };*/
-          /*Subset.prototype.encodeText = function (text) {
-              var char, i, string, _i, _ref;
-              string = '';
-              for (i = _i = 0, _ref = text.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
-                  char = this.unicodes[text.charCodeAt(i)];
-                  string += String.fromCharCode(char);
-              }
-              return string;
-          };*/
-          /***************************************************************/
-          /* function : generateCmap                                     */
-          /* comment : Returns the unicode cmap for this font.         */
-          /***************************************************************/
-          Subset.prototype.generateCmap = function () {
-              var mapping, roman, unicode, unicodeCmap, _ref;
-              unicodeCmap = this.font.cmap.tables[0].codeMap;
-              mapping = {};
-              _ref = this.subset;
-              for (roman in _ref) {
-                  unicode = _ref[roman];
-                  mapping[roman] = unicodeCmap[unicode];
-              }
-              return mapping;
-          };
-          /*Subset.prototype.glyphIDs = function () {
-              var ret, roman, unicode, unicodeCmap, val, _ref;
-              unicodeCmap = this.font.cmap.tables[0].codeMap;
-              ret = [0];
-              _ref = this.subset;
-              for (roman in _ref) {
-                  unicode = _ref[roman];
-                  val = unicodeCmap[unicode];
-                  if ((val != null) && __indexOf.call(ret, val) < 0) {
-                      ret.push(val);
-                  }
-              }
-              return ret.sort();
-          };*/
-          /******************************************************************/
-          /* function : glyphsFor                                           */
-          /* comment : Returns simple glyph objects for the input character.*/
-          /******************************************************************/
-          Subset.prototype.glyphsFor = function (glyphIDs) {
-              var additionalIDs, glyph, glyphs, id, _i, _len, _ref;
-              glyphs = {};
-              for (_i = 0, _len = glyphIDs.length; _i < _len; _i++) {
-                  id = glyphIDs[_i];
-                  glyphs[id] = this.font.glyf.glyphFor(id);
-              }
-              additionalIDs = [];
-              for (id in glyphs) {
-                  glyph = glyphs[id];
-                  if (glyph != null ? glyph.compound : void 0) {
-                      additionalIDs.push.apply(additionalIDs, glyph.glyphIDs);
-                  }
-              }
-              if (additionalIDs.length > 0) {
-                  _ref = this.glyphsFor(additionalIDs);
-                  for (id in _ref) {
-                      glyph = _ref[id];
-                      glyphs[id] = glyph;
-                  }
-              }
-              return glyphs;
-          };
-          /***************************************************************/
-          /* function : encode                                           */
-          /* comment : Encode various tables for the characters you use. */
-          /***************************************************************/
-          Subset.prototype.encode = function (glyID) {
-              var cmap, code, glyf, glyphs, id, ids, loca, new2old, newIDs, nextGlyphID, old2new, oldID, oldIDs, tables, _ref;
-              cmap = CmapTable.encode(this.generateCmap(), 'unicode');
-              glyphs = this.glyphsFor(glyID);
-              old2new = {
-                  0: 0
-              };
-              _ref = cmap.charMap;
-              for (code in _ref) {
-                  ids = _ref[code];
-                  old2new[ids.old] = ids["new"];
-              }
-              nextGlyphID = cmap.maxGlyphID;
-              for (oldID in glyphs) {
-                  if (!(oldID in old2new)) {
-                      old2new[oldID] = nextGlyphID++;
-                  }
-              }
-              new2old = invert(old2new);
-              newIDs = Object.keys(new2old).sort(function (a, b) {
-                  return a - b;
-              });
-              oldIDs = (function () {
-                  var _i, _len, _results;
-                  _results = [];
-                  for (_i = 0, _len = newIDs.length; _i < _len; _i++) {
-                      id = newIDs[_i];
-                      _results.push(new2old[id]);
-                  }
-                  return _results;
-              })();
-              glyf = this.font.glyf.encode(glyphs, oldIDs, old2new);
-              loca = this.font.loca.encode(glyf.offsets, oldIDs);
-              tables = {
-                  cmap: this.font.cmap.raw()
-                  , glyf: glyf.table
-                  , loca: loca
-                  , hmtx: this.font.hmtx.raw()
-                  , hhea: this.font.hhea.raw()
-                  , maxp: this.font.maxp.raw()
-                  , post: this.font.post.raw()
-                  , name: this.font.name.raw()
-                  , head: this.font.head.raw()
-              };
-              if (this.font.os2.exists) {
-                  tables['OS/2'] = this.font.os2.raw();
-              }
-              return this.font.directory.encode(tables);
-          };
-          return Subset;
-      })();
-
-      jsPDF.API.PDFObject = (function () {
-          var pad;
-
-          function PDFObject() {}
-          pad = function (str, length) {
-              return (Array(length + 1).join('0') + str).slice(-length);
-          };
-          /*****************************************************************************/
-          /* function : convert                                                        */
-          /* comment :Converts pdf tag's / FontBBox and array values in / W to strings */
-          /*****************************************************************************/
-          PDFObject.convert = function (object) {
-              var e, items, key, out, val;
-              if (Array.isArray(object)) {
-                  items = ((function () {
-                      var _i, _len, _results;
-                      _results = [];
-                      for (_i = 0, _len = object.length; _i < _len; _i++) {
-                          e = object[_i];
-                          _results.push(PDFObject.convert(e));
-                      }
-                      return _results;
-                  })()).join(' ');
-                  return '[' + items + ']';
-              }
-              else if (typeof object === 'string') {
-                  return '/' + object;
-              }
-              else if (object != null ? object.isString : void 0) {
-                  return '(' + object + ')';
-              }
-              else if (object instanceof Date) {
-                  return '(D:' + pad(object.getUTCFullYear(), 4) + pad(object.getUTCMonth(), 2) + pad(object.getUTCDate(), 2) + pad(object.getUTCHours(), 2) + pad(object.getUTCMinutes(), 2) + pad(object.getUTCSeconds(), 2) + 'Z)';
-              }
-              else if ({}.toString.call(object) === '[object Object]') {
-                  out = ['<<'];
-                  for (key in object) {
-                      val = object[key];
-                      out.push('/' + key + ' ' + PDFObject.convert(val));
-                  }
-                  out.push('>>');
-                  return out.join('\n');
-              }
-              else {
-                  return '' + object;
-              }
-          };
-          return PDFObject;
-      })();
-  })(jsPDF);
-
-  // Generated by CoffeeScript 1.4.0
-
-  /*
-  # PNG.js
-  # Copyright (c) 2011 Devon Govett
-  # MIT LICENSE
-  # 
-  # 
-  */
-
-
-  (function(global) {
-    var PNG;
-
-    PNG = (function() {
-      var APNG_BLEND_OP_SOURCE, APNG_DISPOSE_OP_BACKGROUND, APNG_DISPOSE_OP_PREVIOUS, makeImage, scratchCanvas, scratchCtx;
-
-      PNG.load = function(url, canvas, callback) {
-        var xhr;
-        if (typeof canvas === 'function') {
-          callback = canvas;
-        }
-        xhr = new XMLHttpRequest;
-        xhr.open("GET", url, true);
-        xhr.responseType = "arraybuffer";
-        xhr.onload = function() {
-          var data, png;
-          data = new Uint8Array(xhr.response || xhr.mozResponseArrayBuffer);
-          png = new PNG(data);
-          if (typeof (canvas != null ? canvas.getContext : void 0) === 'function') {
-            png.render(canvas);
-          }
-          return typeof callback === "function" ? callback(png) : void 0;
-        };
-        return xhr.send(null);
-      };
-
-      APNG_DISPOSE_OP_BACKGROUND = 1;
-
-      APNG_DISPOSE_OP_PREVIOUS = 2;
-
-      APNG_BLEND_OP_SOURCE = 0;
-
-      function PNG(data) {
-        var chunkSize, colors, palLen, delayDen, delayNum, frame, i, index, key, section, palShort, text, _i, _j, _ref;
-        this.data = data;
-        this.pos = 8;
-        this.palette = [];
-        this.imgData = [];
-        this.transparency = {};
-        this.animation = null;
-        this.text = {};
-        frame = null;
-        while (true) {
-          chunkSize = this.readUInt32();
-          section = ((function() {
-            var _i, _results;
-            _results = [];
-            for (i = _i = 0; _i < 4; i = ++_i) {
-              _results.push(String.fromCharCode(this.data[this.pos++]));
-            }
-            return _results;
-          }).call(this)).join('');
-          switch (section) {
-            case 'IHDR':
-              this.width = this.readUInt32();
-              this.height = this.readUInt32();
-              this.bits = this.data[this.pos++];
-              this.colorType = this.data[this.pos++];
-              this.compressionMethod = this.data[this.pos++];
-              this.filterMethod = this.data[this.pos++];
-              this.interlaceMethod = this.data[this.pos++];
-              break;
-            case 'acTL':
-              this.animation = {
-                numFrames: this.readUInt32(),
-                numPlays: this.readUInt32() || Infinity,
-                frames: []
-              };
-              break;
-            case 'PLTE':
-              this.palette = this.read(chunkSize);
-              break;
-            case 'fcTL':
-              if (frame) {
-                this.animation.frames.push(frame);
-              }
-              this.pos += 4;
-              frame = {
-                width: this.readUInt32(),
-                height: this.readUInt32(),
-                xOffset: this.readUInt32(),
-                yOffset: this.readUInt32()
-              };
-              delayNum = this.readUInt16();
-              delayDen = this.readUInt16() || 100;
-              frame.delay = 1000 * delayNum / delayDen;
-              frame.disposeOp = this.data[this.pos++];
-              frame.blendOp = this.data[this.pos++];
-              frame.data = [];
-              break;
-            case 'IDAT':
-            case 'fdAT':
-              if (section === 'fdAT') {
-                this.pos += 4;
-                chunkSize -= 4;
-              }
-              data = (frame != null ? frame.data : void 0) || this.imgData;
-              for (i = _i = 0; 0 <= chunkSize ? _i < chunkSize : _i > chunkSize; i = 0 <= chunkSize ? ++_i : --_i) {
-                data.push(this.data[this.pos++]);
-              }
-              break;
-            case 'tRNS':
-              this.transparency = {};
-              switch (this.colorType) {
-                case 3:
-              	palLen = this.palette.length/3;
-                  this.transparency.indexed = this.read(chunkSize);
-                  if(this.transparency.indexed.length > palLen)
-                  	throw new Error('More transparent colors than palette size');
-                  /*
-                   * According to the PNG spec trns should be increased to the same size as palette if shorter
-                   */
-                  //palShort = 255 - this.transparency.indexed.length;
-                  palShort = palLen - this.transparency.indexed.length;
-                  if (palShort > 0) {
-                    for (i = _j = 0; 0 <= palShort ? _j < palShort : _j > palShort; i = 0 <= palShort ? ++_j : --_j) {
-                      this.transparency.indexed.push(255);
-                    }
-                  }
-                  break;
-                case 0:
-                  this.transparency.grayscale = this.read(chunkSize)[0];
-                  break;
-                case 2:
-                  this.transparency.rgb = this.read(chunkSize);
-              }
-              break;
-            case 'tEXt':
-              text = this.read(chunkSize);
-              index = text.indexOf(0);
-              key = String.fromCharCode.apply(String, text.slice(0, index));
-              this.text[key] = String.fromCharCode.apply(String, text.slice(index + 1));
-              break;
-            case 'IEND':
-              if (frame) {
-                this.animation.frames.push(frame);
-              }
-              this.colors = (function() {
-                switch (this.colorType) {
-                  case 0:
-                  case 3:
-                  case 4:
-                    return 1;
-                  case 2:
-                  case 6:
-                    return 3;
-                }
-              }).call(this);
-              this.hasAlphaChannel = (_ref = this.colorType) === 4 || _ref === 6;
-              colors = this.colors + (this.hasAlphaChannel ? 1 : 0);
-              this.pixelBitlength = this.bits * colors;
-              this.colorSpace = (function() {
-                switch (this.colors) {
-                  case 1:
-                    return 'DeviceGray';
-                  case 3:
-                    return 'DeviceRGB';
-                }
-              }).call(this);
-              this.imgData = new Uint8Array(this.imgData);
-              return;
-            default:
-              this.pos += chunkSize;
-          }
-          this.pos += 4;
-          if (this.pos > this.data.length) {
-            throw new Error("Incomplete or corrupt PNG file");
-          }
-        }
-        return;
-      }
-
-      PNG.prototype.read = function(bytes) {
-        var i, _i, _results;
-        _results = [];
-        for (i = _i = 0; 0 <= bytes ? _i < bytes : _i > bytes; i = 0 <= bytes ? ++_i : --_i) {
-          _results.push(this.data[this.pos++]);
-        }
-        return _results;
-      };
-
-      PNG.prototype.readUInt32 = function() {
-        var b1, b2, b3, b4;
-        b1 = this.data[this.pos++] << 24;
-        b2 = this.data[this.pos++] << 16;
-        b3 = this.data[this.pos++] << 8;
-        b4 = this.data[this.pos++];
-        return b1 | b2 | b3 | b4;
-      };
-
-      PNG.prototype.readUInt16 = function() {
-        var b1, b2;
-        b1 = this.data[this.pos++] << 8;
-        b2 = this.data[this.pos++];
-        return b1 | b2;
-      };
-
-
-      PNG.prototype.decodePixels = function(data) {
-        var pixelBytes = this.pixelBitlength / 8;
-        var fullPixels = new Uint8Array(this.width * this.height * pixelBytes);
-        var pos = 0;
-        var _this = this;
-        
-        if (data == null) {
-            data = this.imgData;
-        }
-        if (data.length === 0) {
-            return new Uint8Array(0);
-        }
-        
-        data = new FlateStream(data);
-        data = data.getBytes();
-        function pass (x0, y0, dx, dy) {
-            var abyte, c, col, i, left, length, p, pa, paeth, pb, pc, pixels, row, scanlineLength, upper, upperLeft, _i, _j, _k, _l, _m;
-            var w = Math.ceil((_this.width - x0) / dx), h = Math.ceil((_this.height - y0) / dy);
-            var isFull = _this.width == w && _this.height == h;
-            scanlineLength = pixelBytes * w;
-            pixels = isFull ? fullPixels : new Uint8Array(scanlineLength * h);
-            length = data.length;
-            row = 0;
-            c = 0;
-            while (row < h && pos < length) {
-              switch (data[pos++]) {
-                case 0:
-                  for (i = _i = 0; _i < scanlineLength; i = _i += 1) {
-                    pixels[c++] = data[pos++];
-                  }
-                  break;
-                case 1:
-                  for (i = _j = 0; _j < scanlineLength; i = _j += 1) {
-                    abyte = data[pos++];
-                    left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
-                    pixels[c++] = (abyte + left) % 256;
-                  }
-                  break;
-                case 2:
-                  for (i = _k = 0; _k < scanlineLength; i = _k += 1) {
-                    abyte = data[pos++];
-                    col = (i - (i % pixelBytes)) / pixelBytes;
-                    upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
-                    pixels[c++] = (upper + abyte) % 256;
-                  }
-                  break;
-                case 3:
-                  for (i = _l = 0; _l < scanlineLength; i = _l += 1) {
-                    abyte = data[pos++];
-                    col = (i - (i % pixelBytes)) / pixelBytes;
-                    left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
-                    upper = row && pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
-                    pixels[c++] = (abyte + Math.floor((left + upper) / 2)) % 256;
-                  }
-                  break;
-                case 4:
-                  for (i = _m = 0; _m < scanlineLength; i = _m += 1) {
-                    abyte = data[pos++];
-                    col = (i - (i % pixelBytes)) / pixelBytes;
-                    left = i < pixelBytes ? 0 : pixels[c - pixelBytes];
-                    if (row === 0) {
-                      upper = upperLeft = 0;
-                    } else {
-                      upper = pixels[(row - 1) * scanlineLength + col * pixelBytes + (i % pixelBytes)];
-                      upperLeft = col && pixels[(row - 1) * scanlineLength + (col - 1) * pixelBytes + (i % pixelBytes)];
-                    }
-                    p = left + upper - upperLeft;
-                    pa = Math.abs(p - left);
-                    pb = Math.abs(p - upper);
-                    pc = Math.abs(p - upperLeft);
-                    if (pa <= pb && pa <= pc) {
-                      paeth = left;
-                    } else if (pb <= pc) {
-                      paeth = upper;
-                    } else {
-                      paeth = upperLeft;
-                    }
-                    pixels[c++] = (abyte + paeth) % 256;
-                  }
-                  break;
-                default:
-                  throw new Error("Invalid filter algorithm: " + data[pos - 1]);
-              }
-              if (!isFull) {
-                  var fullPos = ((y0 + row * dy) * _this.width + x0) * pixelBytes;
-                  var partPos = row * scanlineLength;
-                  for (i = 0; i < w; i += 1) {
-                    for (var j = 0; j < pixelBytes; j += 1)
-                      fullPixels[fullPos++] = pixels[partPos++];
-                    fullPos += (dx - 1) * pixelBytes;
-                  }
-                }
-              row++;
-            }
-        }
-        if (_this.interlaceMethod == 1) {
-            /*
-              1 6 4 6 2 6 4 6
-              7 7 7 7 7 7 7 7
-              5 6 5 6 5 6 5 6
-              7 7 7 7 7 7 7 7
-              3 6 4 6 3 6 4 6
-              7 7 7 7 7 7 7 7
-              5 6 5 6 5 6 5 6
-              7 7 7 7 7 7 7 7
-            */
-            pass(0, 0, 8, 8); // 1
-            /* NOTE these seem to follow the pattern:
-             * pass(x, 0, 2*x, 2*x);
-             * pass(0, x,   x, 2*x);
-             * with x being 4, 2, 1.
-             */
-            pass(4, 0, 8, 8); // 2
-            pass(0, 4, 4, 8); // 3
-
-            pass(2, 0, 4, 4); // 4
-            pass(0, 2, 2, 4); // 5
-
-            pass(1, 0, 2, 2); // 6
-            pass(0, 1, 1, 2); // 7
-          } else {
-            pass(0, 0, 1, 1);
-          }
-        return fullPixels;
-      };
-
-      PNG.prototype.decodePalette = function() {
-        var c, i, length, palette, pos, ret, transparency, _i, _ref, _ref1;
-        palette = this.palette;
-        transparency = this.transparency.indexed || [];
-        ret = new Uint8Array((transparency.length || 0) + palette.length);
-        pos = 0;
-        length = palette.length;
-        c = 0;
-        for (i = _i = 0, _ref = palette.length; _i < _ref; i = _i += 3) {
-          ret[pos++] = palette[i];
-          ret[pos++] = palette[i + 1];
-          ret[pos++] = palette[i + 2];
-          ret[pos++] = (_ref1 = transparency[c++]) != null ? _ref1 : 255;
-        }
-        return ret;
-      };
-
-      PNG.prototype.copyToImageData = function(imageData, pixels) {
-        var alpha, colors, data, i, input, j, k, length, palette, v, _ref;
-        colors = this.colors;
-        palette = null;
-        alpha = this.hasAlphaChannel;
-        if (this.palette.length) {
-          palette = (_ref = this._decodedPalette) != null ? _ref : this._decodedPalette = this.decodePalette();
-          colors = 4;
-          alpha = true;
-        }
-        data = imageData.data || imageData;
-        length = data.length;
-        input = palette || pixels;
-        i = j = 0;
-        if (colors === 1) {
-          while (i < length) {
-            k = palette ? pixels[i / 4] * 4 : j;
-            v = input[k++];
-            data[i++] = v;
-            data[i++] = v;
-            data[i++] = v;
-            data[i++] = alpha ? input[k++] : 255;
-            j = k;
-          }
-        } else {
-          while (i < length) {
-            k = palette ? pixels[i / 4] * 4 : j;
-            data[i++] = input[k++];
-            data[i++] = input[k++];
-            data[i++] = input[k++];
-            data[i++] = alpha ? input[k++] : 255;
-            j = k;
-          }
-        }
-      };
-
-      PNG.prototype.decode = function() {
-        var ret;
-        ret = new Uint8Array(this.width * this.height * 4);
-        this.copyToImageData(ret, this.decodePixels());
-        return ret;
-      };
-
-      try {
-          scratchCanvas = global.document.createElement('canvas');
-          scratchCtx = scratchCanvas.getContext('2d');
-      } catch(e) {
-          return -1;
-      }
-
-      makeImage = function(imageData) {
-        var img;
-        scratchCtx.width = imageData.width;
-        scratchCtx.height = imageData.height;
-        scratchCtx.clearRect(0, 0, imageData.width, imageData.height);
-        scratchCtx.putImageData(imageData, 0, 0);
-        img = new Image;
-        img.src = scratchCanvas.toDataURL();
-        return img;
-      };
-
-      PNG.prototype.decodeFrames = function(ctx) {
-        var frame, i, imageData, pixels, _i, _len, _ref, _results;
-        if (!this.animation) {
-          return;
-        }
-        _ref = this.animation.frames;
-        _results = [];
-        for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
-          frame = _ref[i];
-          imageData = ctx.createImageData(frame.width, frame.height);
-          pixels = this.decodePixels(new Uint8Array(frame.data));
-          this.copyToImageData(imageData, pixels);
-          frame.imageData = imageData;
-          _results.push(frame.image = makeImage(imageData));
-        }
-        return _results;
-      };
-
-      PNG.prototype.renderFrame = function(ctx, number) {
-        var frame, frames, prev;
-        frames = this.animation.frames;
-        frame = frames[number];
-        prev = frames[number - 1];
-        if (number === 0) {
-          ctx.clearRect(0, 0, this.width, this.height);
-        }
-        if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_BACKGROUND) {
-          ctx.clearRect(prev.xOffset, prev.yOffset, prev.width, prev.height);
-        } else if ((prev != null ? prev.disposeOp : void 0) === APNG_DISPOSE_OP_PREVIOUS) {
-          ctx.putImageData(prev.imageData, prev.xOffset, prev.yOffset);
-        }
-        if (frame.blendOp === APNG_BLEND_OP_SOURCE) {
-          ctx.clearRect(frame.xOffset, frame.yOffset, frame.width, frame.height);
-        }
-        return ctx.drawImage(frame.image, frame.xOffset, frame.yOffset);
-      };
-
-      PNG.prototype.animate = function(ctx) {
-        var doFrame, frameNumber, frames, numFrames, numPlays, _ref,
-          _this = this;
-        frameNumber = 0;
-        _ref = this.animation, numFrames = _ref.numFrames, frames = _ref.frames, numPlays = _ref.numPlays;
-        return (doFrame = function() {
-          var f, frame;
-          f = frameNumber++ % numFrames;
-          frame = frames[f];
-          _this.renderFrame(ctx, f);
-          if (numFrames > 1 && frameNumber / numFrames < numPlays) {
-            return _this.animation._timeout = setTimeout(doFrame, frame.delay);
-          }
-        })();
-      };
-
-      PNG.prototype.stopAnimation = function() {
-        var _ref;
-        return clearTimeout((_ref = this.animation) != null ? _ref._timeout : void 0);
-      };
-
-      PNG.prototype.render = function(canvas) {
-        var ctx, data;
-        if (canvas._png) {
-          canvas._png.stopAnimation();
-        }
-        canvas._png = this;
-        canvas.width = this.width;
-        canvas.height = this.height;
-        ctx = canvas.getContext("2d");
-        if (this.animation) {
-          this.decodeFrames(ctx);
-          return this.animate(ctx);
-        } else {
-          data = ctx.createImageData(this.width, this.height);
-          this.copyToImageData(data, this.decodePixels());
-          return ctx.putImageData(data, 0, 0);
-        }
-      };
-
-      return PNG;
-
-    })();
-
-    global.PNG = PNG;
-
-  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global ||  Function('return typeof this === "object" && this.content')() || Function('return this')()));
-  // `self` is undefined in Firefox for Android content script context
-  // while `this` is nsIContentFrameMessageManager
-  // with an attribute `content` that corresponds to the window
-
-  /*
-   * Extracted from pdf.js
-   * https://github.com/andreasgal/pdf.js
-   *
-   * Copyright (c) 2011 Mozilla Foundation
-   *
-   * Contributors: Andreas Gal <gal@mozilla.com>
-   *               Chris G Jones <cjones@mozilla.com>
-   *               Shaon Barman <shaon.barman@gmail.com>
-   *               Vivien Nicolas <21@vingtetun.org>
-   *               Justin D'Arcangelo <justindarc@gmail.com>
-   *               Yury Delendik
-   *
-   * 
-   */
-
-  var DecodeStream = (function() {
-    function constructor() {
-      this.pos = 0;
-      this.bufferLength = 0;
-      this.eof = false;
-      this.buffer = null;
-    }
-
-    constructor.prototype = {
-      ensureBuffer: function decodestream_ensureBuffer(requested) {
-        var buffer = this.buffer;
-        var current = buffer ? buffer.byteLength : 0;
-        if (requested < current)
-          return buffer;
-        var size = 512;
-        while (size < requested)
-          size <<= 1;
-        var buffer2 = new Uint8Array(size);
-        for (var i = 0; i < current; ++i)
-          buffer2[i] = buffer[i];
-        return this.buffer = buffer2;
-      },
-      getByte: function decodestream_getByte() {
-        var pos = this.pos;
-        while (this.bufferLength <= pos) {
-          if (this.eof)
-            return null;
-          this.readBlock();
-        }
-        return this.buffer[this.pos++];
-      },
-      getBytes: function decodestream_getBytes(length) {
-        var pos = this.pos;
-
-        if (length) {
-          this.ensureBuffer(pos + length);
-          var end = pos + length;
-
-          while (!this.eof && this.bufferLength < end)
-            this.readBlock();
-
-          var bufEnd = this.bufferLength;
-          if (end > bufEnd)
-            end = bufEnd;
-        } else {
-          while (!this.eof)
-            this.readBlock();
-
-          var end = this.bufferLength;
-        }
-
-        this.pos = end;
-        return this.buffer.subarray(pos, end);
-      },
-      lookChar: function decodestream_lookChar() {
-        var pos = this.pos;
-        while (this.bufferLength <= pos) {
-          if (this.eof)
-            return null;
-          this.readBlock();
-        }
-        return String.fromCharCode(this.buffer[this.pos]);
-      },
-      getChar: function decodestream_getChar() {
-        var pos = this.pos;
-        while (this.bufferLength <= pos) {
-          if (this.eof)
-            return null;
-          this.readBlock();
-        }
-        return String.fromCharCode(this.buffer[this.pos++]);
-      },
-      makeSubStream: function decodestream_makeSubstream(start, length, dict) {
-        var end = start + length;
-        while (this.bufferLength <= end && !this.eof)
-          this.readBlock();
-        return new Stream(this.buffer, start, length, dict);
-      },
-      skip: function decodestream_skip(n) {
-        if (!n)
-          n = 1;
-        this.pos += n;
-      },
-      reset: function decodestream_reset() {
-        this.pos = 0;
-      }
-    };
-
-    return constructor;
-  })();
-
-  var FlateStream = (function() {
-    if (typeof Uint32Array === 'undefined') {
-      return undefined;
-    }
-    var codeLenCodeMap = new Uint32Array([
-      16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
-    ]);
-
-    var lengthDecode = new Uint32Array([
-      0x00003, 0x00004, 0x00005, 0x00006, 0x00007, 0x00008, 0x00009, 0x0000a,
-      0x1000b, 0x1000d, 0x1000f, 0x10011, 0x20013, 0x20017, 0x2001b, 0x2001f,
-      0x30023, 0x3002b, 0x30033, 0x3003b, 0x40043, 0x40053, 0x40063, 0x40073,
-      0x50083, 0x500a3, 0x500c3, 0x500e3, 0x00102, 0x00102, 0x00102
-    ]);
-
-    var distDecode = new Uint32Array([
-      0x00001, 0x00002, 0x00003, 0x00004, 0x10005, 0x10007, 0x20009, 0x2000d,
-      0x30011, 0x30019, 0x40021, 0x40031, 0x50041, 0x50061, 0x60081, 0x600c1,
-      0x70101, 0x70181, 0x80201, 0x80301, 0x90401, 0x90601, 0xa0801, 0xa0c01,
-      0xb1001, 0xb1801, 0xc2001, 0xc3001, 0xd4001, 0xd6001
-    ]);
-
-    var fixedLitCodeTab = [new Uint32Array([
-      0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c0,
-      0x70108, 0x80060, 0x80020, 0x900a0, 0x80000, 0x80080, 0x80040, 0x900e0,
-      0x70104, 0x80058, 0x80018, 0x90090, 0x70114, 0x80078, 0x80038, 0x900d0,
-      0x7010c, 0x80068, 0x80028, 0x900b0, 0x80008, 0x80088, 0x80048, 0x900f0,
-      0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c8,
-      0x7010a, 0x80064, 0x80024, 0x900a8, 0x80004, 0x80084, 0x80044, 0x900e8,
-      0x70106, 0x8005c, 0x8001c, 0x90098, 0x70116, 0x8007c, 0x8003c, 0x900d8,
-      0x7010e, 0x8006c, 0x8002c, 0x900b8, 0x8000c, 0x8008c, 0x8004c, 0x900f8,
-      0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c4,
-      0x70109, 0x80062, 0x80022, 0x900a4, 0x80002, 0x80082, 0x80042, 0x900e4,
-      0x70105, 0x8005a, 0x8001a, 0x90094, 0x70115, 0x8007a, 0x8003a, 0x900d4,
-      0x7010d, 0x8006a, 0x8002a, 0x900b4, 0x8000a, 0x8008a, 0x8004a, 0x900f4,
-      0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cc,
-      0x7010b, 0x80066, 0x80026, 0x900ac, 0x80006, 0x80086, 0x80046, 0x900ec,
-      0x70107, 0x8005e, 0x8001e, 0x9009c, 0x70117, 0x8007e, 0x8003e, 0x900dc,
-      0x7010f, 0x8006e, 0x8002e, 0x900bc, 0x8000e, 0x8008e, 0x8004e, 0x900fc,
-      0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c2,
-      0x70108, 0x80061, 0x80021, 0x900a2, 0x80001, 0x80081, 0x80041, 0x900e2,
-      0x70104, 0x80059, 0x80019, 0x90092, 0x70114, 0x80079, 0x80039, 0x900d2,
-      0x7010c, 0x80069, 0x80029, 0x900b2, 0x80009, 0x80089, 0x80049, 0x900f2,
-      0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900ca,
-      0x7010a, 0x80065, 0x80025, 0x900aa, 0x80005, 0x80085, 0x80045, 0x900ea,
-      0x70106, 0x8005d, 0x8001d, 0x9009a, 0x70116, 0x8007d, 0x8003d, 0x900da,
-      0x7010e, 0x8006d, 0x8002d, 0x900ba, 0x8000d, 0x8008d, 0x8004d, 0x900fa,
-      0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c6,
-      0x70109, 0x80063, 0x80023, 0x900a6, 0x80003, 0x80083, 0x80043, 0x900e6,
-      0x70105, 0x8005b, 0x8001b, 0x90096, 0x70115, 0x8007b, 0x8003b, 0x900d6,
-      0x7010d, 0x8006b, 0x8002b, 0x900b6, 0x8000b, 0x8008b, 0x8004b, 0x900f6,
-      0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900ce,
-      0x7010b, 0x80067, 0x80027, 0x900ae, 0x80007, 0x80087, 0x80047, 0x900ee,
-      0x70107, 0x8005f, 0x8001f, 0x9009e, 0x70117, 0x8007f, 0x8003f, 0x900de,
-      0x7010f, 0x8006f, 0x8002f, 0x900be, 0x8000f, 0x8008f, 0x8004f, 0x900fe,
-      0x70100, 0x80050, 0x80010, 0x80118, 0x70110, 0x80070, 0x80030, 0x900c1,
-      0x70108, 0x80060, 0x80020, 0x900a1, 0x80000, 0x80080, 0x80040, 0x900e1,
-      0x70104, 0x80058, 0x80018, 0x90091, 0x70114, 0x80078, 0x80038, 0x900d1,
-      0x7010c, 0x80068, 0x80028, 0x900b1, 0x80008, 0x80088, 0x80048, 0x900f1,
-      0x70102, 0x80054, 0x80014, 0x8011c, 0x70112, 0x80074, 0x80034, 0x900c9,
-      0x7010a, 0x80064, 0x80024, 0x900a9, 0x80004, 0x80084, 0x80044, 0x900e9,
-      0x70106, 0x8005c, 0x8001c, 0x90099, 0x70116, 0x8007c, 0x8003c, 0x900d9,
-      0x7010e, 0x8006c, 0x8002c, 0x900b9, 0x8000c, 0x8008c, 0x8004c, 0x900f9,
-      0x70101, 0x80052, 0x80012, 0x8011a, 0x70111, 0x80072, 0x80032, 0x900c5,
-      0x70109, 0x80062, 0x80022, 0x900a5, 0x80002, 0x80082, 0x80042, 0x900e5,
-      0x70105, 0x8005a, 0x8001a, 0x90095, 0x70115, 0x8007a, 0x8003a, 0x900d5,
-      0x7010d, 0x8006a, 0x8002a, 0x900b5, 0x8000a, 0x8008a, 0x8004a, 0x900f5,
-      0x70103, 0x80056, 0x80016, 0x8011e, 0x70113, 0x80076, 0x80036, 0x900cd,
-      0x7010b, 0x80066, 0x80026, 0x900ad, 0x80006, 0x80086, 0x80046, 0x900ed,
-      0x70107, 0x8005e, 0x8001e, 0x9009d, 0x70117, 0x8007e, 0x8003e, 0x900dd,
-      0x7010f, 0x8006e, 0x8002e, 0x900bd, 0x8000e, 0x8008e, 0x8004e, 0x900fd,
-      0x70100, 0x80051, 0x80011, 0x80119, 0x70110, 0x80071, 0x80031, 0x900c3,
-      0x70108, 0x80061, 0x80021, 0x900a3, 0x80001, 0x80081, 0x80041, 0x900e3,
-      0x70104, 0x80059, 0x80019, 0x90093, 0x70114, 0x80079, 0x80039, 0x900d3,
-      0x7010c, 0x80069, 0x80029, 0x900b3, 0x80009, 0x80089, 0x80049, 0x900f3,
-      0x70102, 0x80055, 0x80015, 0x8011d, 0x70112, 0x80075, 0x80035, 0x900cb,
-      0x7010a, 0x80065, 0x80025, 0x900ab, 0x80005, 0x80085, 0x80045, 0x900eb,
-      0x70106, 0x8005d, 0x8001d, 0x9009b, 0x70116, 0x8007d, 0x8003d, 0x900db,
-      0x7010e, 0x8006d, 0x8002d, 0x900bb, 0x8000d, 0x8008d, 0x8004d, 0x900fb,
-      0x70101, 0x80053, 0x80013, 0x8011b, 0x70111, 0x80073, 0x80033, 0x900c7,
-      0x70109, 0x80063, 0x80023, 0x900a7, 0x80003, 0x80083, 0x80043, 0x900e7,
-      0x70105, 0x8005b, 0x8001b, 0x90097, 0x70115, 0x8007b, 0x8003b, 0x900d7,
-      0x7010d, 0x8006b, 0x8002b, 0x900b7, 0x8000b, 0x8008b, 0x8004b, 0x900f7,
-      0x70103, 0x80057, 0x80017, 0x8011f, 0x70113, 0x80077, 0x80037, 0x900cf,
-      0x7010b, 0x80067, 0x80027, 0x900af, 0x80007, 0x80087, 0x80047, 0x900ef,
-      0x70107, 0x8005f, 0x8001f, 0x9009f, 0x70117, 0x8007f, 0x8003f, 0x900df,
-      0x7010f, 0x8006f, 0x8002f, 0x900bf, 0x8000f, 0x8008f, 0x8004f, 0x900ff
-    ]), 9];
-
-    var fixedDistCodeTab = [new Uint32Array([
-      0x50000, 0x50010, 0x50008, 0x50018, 0x50004, 0x50014, 0x5000c, 0x5001c,
-      0x50002, 0x50012, 0x5000a, 0x5001a, 0x50006, 0x50016, 0x5000e, 0x00000,
-      0x50001, 0x50011, 0x50009, 0x50019, 0x50005, 0x50015, 0x5000d, 0x5001d,
-      0x50003, 0x50013, 0x5000b, 0x5001b, 0x50007, 0x50017, 0x5000f, 0x00000
-    ]), 5];
-    
-    function error(e) {
-        throw new Error(e)
-    }
-
-    function constructor(bytes) {
-      //var bytes = stream.getBytes();
-      var bytesPos = 0;
-
-      var cmf = bytes[bytesPos++];
-      var flg = bytes[bytesPos++];
-      if (cmf == -1 || flg == -1)
-        error('Invalid header in flate stream');
-      if ((cmf & 0x0f) != 0x08)
-        error('Unknown compression method in flate stream');
-      if ((((cmf << 8) + flg) % 31) != 0)
-        error('Bad FCHECK in flate stream');
-      if (flg & 0x20)
-        error('FDICT bit set in flate stream');
-
-      this.bytes = bytes;
-      this.bytesPos = bytesPos;
-
-      this.codeSize = 0;
-      this.codeBuf = 0;
-
-      DecodeStream.call(this);
-    }
-
-    constructor.prototype = Object.create(DecodeStream.prototype);
-
-    constructor.prototype.getBits = function(bits) {
-      var codeSize = this.codeSize;
-      var codeBuf = this.codeBuf;
-      var bytes = this.bytes;
-      var bytesPos = this.bytesPos;
-
-      var b;
-      while (codeSize < bits) {
-        if (typeof (b = bytes[bytesPos++]) == 'undefined')
-          error('Bad encoding in flate stream');
-        codeBuf |= b << codeSize;
-        codeSize += 8;
-      }
-      b = codeBuf & ((1 << bits) - 1);
-      this.codeBuf = codeBuf >> bits;
-      this.codeSize = codeSize -= bits;
-      this.bytesPos = bytesPos;
-      return b;
-    };
-
-    constructor.prototype.getCode = function(table) {
-      var codes = table[0];
-      var maxLen = table[1];
-      var codeSize = this.codeSize;
-      var codeBuf = this.codeBuf;
-      var bytes = this.bytes;
-      var bytesPos = this.bytesPos;
-
-      while (codeSize < maxLen) {
-        var b;
-        if (typeof (b = bytes[bytesPos++]) == 'undefined')
-          error('Bad encoding in flate stream');
-        codeBuf |= (b << codeSize);
-        codeSize += 8;
-      }
-      var code = codes[codeBuf & ((1 << maxLen) - 1)];
-      var codeLen = code >> 16;
-      var codeVal = code & 0xffff;
-      if (codeSize == 0 || codeSize < codeLen || codeLen == 0)
-        error('Bad encoding in flate stream');
-      this.codeBuf = (codeBuf >> codeLen);
-      this.codeSize = (codeSize - codeLen);
-      this.bytesPos = bytesPos;
-      return codeVal;
-    };
-
-    constructor.prototype.generateHuffmanTable = function(lengths) {
-      var n = lengths.length;
-
-      // find max code length
-      var maxLen = 0;
-      for (var i = 0; i < n; ++i) {
-        if (lengths[i] > maxLen)
-          maxLen = lengths[i];
-      }
-
-      // build the table
-      var size = 1 << maxLen;
-      var codes = new Uint32Array(size);
-      for (var len = 1, code = 0, skip = 2;
-           len <= maxLen;
-           ++len, code <<= 1, skip <<= 1) {
-        for (var val = 0; val < n; ++val) {
-          if (lengths[val] == len) {
-            // bit-reverse the code
-            var code2 = 0;
-            var t = code;
-            for (var i = 0; i < len; ++i) {
-              code2 = (code2 << 1) | (t & 1);
-              t >>= 1;
-            }
-
-            // fill the table entries
-            for (var i = code2; i < size; i += skip)
-              codes[i] = (len << 16) | val;
-
-            ++code;
-          }
-        }
-      }
-
-      return [codes, maxLen];
-    };
-
-    constructor.prototype.readBlock = function() {
-      function repeat(stream, array, len, offset, what) {
-        var repeat = stream.getBits(len) + offset;
-        while (repeat-- > 0)
-          array[i++] = what;
-      }
-
-      // read block header
-      var hdr = this.getBits(3);
-      if (hdr & 1)
-        this.eof = true;
-      hdr >>= 1;
-
-      if (hdr == 0) { // uncompressed block
-        var bytes = this.bytes;
-        var bytesPos = this.bytesPos;
-        var b;
-
-        if (typeof (b = bytes[bytesPos++]) == 'undefined')
-          error('Bad block header in flate stream');
-        var blockLen = b;
-        if (typeof (b = bytes[bytesPos++]) == 'undefined')
-          error('Bad block header in flate stream');
-        blockLen |= (b << 8);
-        if (typeof (b = bytes[bytesPos++]) == 'undefined')
-          error('Bad block header in flate stream');
-        var check = b;
-        if (typeof (b = bytes[bytesPos++]) == 'undefined')
-          error('Bad block header in flate stream');
-        check |= (b << 8);
-        if (check != (~blockLen & 0xffff))
-          error('Bad uncompressed block length in flate stream');
-
-        this.codeBuf = 0;
-        this.codeSize = 0;
-
-        var bufferLength = this.bufferLength;
-        var buffer = this.ensureBuffer(bufferLength + blockLen);
-        var end = bufferLength + blockLen;
-        this.bufferLength = end;
-        for (var n = bufferLength; n < end; ++n) {
-          if (typeof (b = bytes[bytesPos++]) == 'undefined') {
-            this.eof = true;
-            break;
-          }
-          buffer[n] = b;
-        }
-        this.bytesPos = bytesPos;
-        return;
-      }
-
-      var litCodeTable;
-      var distCodeTable;
-      if (hdr == 1) { // compressed block, fixed codes
-        litCodeTable = fixedLitCodeTab;
-        distCodeTable = fixedDistCodeTab;
-      } else if (hdr == 2) { // compressed block, dynamic codes
-        var numLitCodes = this.getBits(5) + 257;
-        var numDistCodes = this.getBits(5) + 1;
-        var numCodeLenCodes = this.getBits(4) + 4;
-
-        // build the code lengths code table
-        var codeLenCodeLengths = Array(codeLenCodeMap.length);
-        var i = 0;
-        while (i < numCodeLenCodes)
-          codeLenCodeLengths[codeLenCodeMap[i++]] = this.getBits(3);
-        var codeLenCodeTab = this.generateHuffmanTable(codeLenCodeLengths);
-
-        // build the literal and distance code tables
-        var len = 0;
-        var i = 0;
-        var codes = numLitCodes + numDistCodes;
-        var codeLengths = new Array(codes);
-        while (i < codes) {
-          var code = this.getCode(codeLenCodeTab);
-          if (code == 16) {
-            repeat(this, codeLengths, 2, 3, len);
-          } else if (code == 17) {
-            repeat(this, codeLengths, 3, 3, len = 0);
-          } else if (code == 18) {
-            repeat(this, codeLengths, 7, 11, len = 0);
-          } else {
-            codeLengths[i++] = len = code;
-          }
-        }
-
-        litCodeTable =
-          this.generateHuffmanTable(codeLengths.slice(0, numLitCodes));
-        distCodeTable =
-          this.generateHuffmanTable(codeLengths.slice(numLitCodes, codes));
-      } else {
-        error('Unknown block type in flate stream');
-      }
-
-      var buffer = this.buffer;
-      var limit = buffer ? buffer.length : 0;
-      var pos = this.bufferLength;
-      while (true) {
-        var code1 = this.getCode(litCodeTable);
-        if (code1 < 256) {
-          if (pos + 1 >= limit) {
-            buffer = this.ensureBuffer(pos + 1);
-            limit = buffer.length;
-          }
-          buffer[pos++] = code1;
-          continue;
-        }
-        if (code1 == 256) {
-          this.bufferLength = pos;
-          return;
-        }
-        code1 -= 257;
-        code1 = lengthDecode[code1];
-        var code2 = code1 >> 16;
-        if (code2 > 0)
-          code2 = this.getBits(code2);
-        var len = (code1 & 0xffff) + code2;
-        code1 = this.getCode(distCodeTable);
-        code1 = distDecode[code1];
-        code2 = code1 >> 16;
-        if (code2 > 0)
-          code2 = this.getBits(code2);
-        var dist = (code1 & 0xffff) + code2;
-        if (pos + len >= limit) {
-          buffer = this.ensureBuffer(pos + len);
-          limit = buffer.length;
-        }
-        for (var k = 0; k < len; ++k, ++pos)
-          buffer[pos] = buffer[pos - dist];
-      }
-    };
-
-    return constructor;
-  })();
-
-  /**
-   * JavaScript Polyfill functions for jsPDF
-   * Collected from public resources by
-   * https://github.com/diegocr
-   */
-
-  (function (global) {
-      
-      if (typeof global.console !== "object") {
-          // Console-polyfill. MIT license.
-          // https://github.com/paulmillr/console-polyfill
-          // Make it safe to do console.log() always.
-          global.console = {};
-          
-          var con = global.console;
-          var prop, method;
-          var dummy = function() {};
-          var properties = ['memory'];
-          var methods = ('assert,clear,count,debug,dir,dirxml,error,exception,group,' +
-           'groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,' +
-           'show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn').split(',');
-          while (prop = properties.pop()) if (!con[prop]) con[prop] = {};
-          while (method = methods.pop()) if (!con[method]) con[method] = dummy;
-      }
-
-      var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
-
-      if (typeof global.btoa === 'undefined') {
-          global.btoa = function(data) {
-              //  discuss at: http://phpjs.org/functions/base64_encode/
-              // original by: Tyler Akins (http://rumkin.com)
-              // improved by: Bayron Guevara
-              // improved by: Thunder.m
-              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
-              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
-              // improved by: Rafal Kukawski (http://kukawski.pl)
-              // bugfixed by: Pellentesque Malesuada
-              //   example 1: base64_encode('Kevin van Zonneveld');
-              //   returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA=='
-
-              var o1,o2,o3,h1,h2,h3,h4,bits,i = 0,ac = 0,enc = '',tmp_arr = [];
-
-              if (!data) {
-                  return data;
-              }
-
-              do { // pack three octets into four hexets
-                  o1 = data.charCodeAt(i++);
-                  o2 = data.charCodeAt(i++);
-                  o3 = data.charCodeAt(i++);
-
-                  bits = o1 << 16 | o2 << 8 | o3;
-
-                  h1 = bits >> 18 & 0x3f;
-                  h2 = bits >> 12 & 0x3f;
-                  h3 = bits >> 6 & 0x3f;
-                  h4 = bits & 0x3f;
-
-                  // use hexets to index into b64, and append result to encoded string
-                  tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
-              } while (i < data.length);
-
-              enc = tmp_arr.join('');
-
-              var r = data.length % 3;
-
-              return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3);
-          };
-      }
-
-      if (typeof global.atob === 'undefined') {
-          global.atob = function(data) {
-              //  discuss at: http://phpjs.org/functions/base64_decode/
-              // original by: Tyler Akins (http://rumkin.com)
-              // improved by: Thunder.m
-              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
-              // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
-              //    input by: Aman Gupta
-              //    input by: Brett Zamir (http://brett-zamir.me)
-              // bugfixed by: Onno Marsman
-              // bugfixed by: Pellentesque Malesuada
-              // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
-              //   example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA==');
-              //   returns 1: 'Kevin van Zonneveld'
-
-              var o1,o2,o3,h1,h2,h3,h4,bits,i = 0,ac = 0,dec = '',tmp_arr = [];
-
-              if (!data) {
-                  return data;
-              }
-
-              data += '';
-
-              do { // unpack four hexets into three octets using index points in b64
-                  h1 = b64.indexOf(data.charAt(i++));
-                  h2 = b64.indexOf(data.charAt(i++));
-                  h3 = b64.indexOf(data.charAt(i++));
-                  h4 = b64.indexOf(data.charAt(i++));
-
-                  bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
-
-                  o1 = bits >> 16 & 0xff;
-                  o2 = bits >> 8 & 0xff;
-                  o3 = bits & 0xff;
-
-                  if (h3 == 64) {
-                      tmp_arr[ac++] = String.fromCharCode(o1);
-                  } else if (h4 == 64) {
-                      tmp_arr[ac++] = String.fromCharCode(o1, o2);
-                  } else {
-                      tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
-                  }
-              } while (i < data.length);
-
-              dec = tmp_arr.join('');
-
-              return dec;
-          };
-      }
-
-      if (!Array.prototype.map) {
-          Array.prototype.map = function(fun /*, thisArg */) {
-              if (this === void 0 || this === null || typeof fun !== "function")
-                  throw new TypeError();
-
-              var t = Object(this), len = t.length >>> 0, res = new Array(len);
-              var thisArg = arguments.length > 1 ? arguments[1] : void 0;
-              for (var i = 0; i < len; i++) {
-                  // NOTE: Absolute correctness would demand Object.defineProperty
-                  //       be used.  But this method is fairly new, and failure is
-                  //       possible only if Object.prototype or Array.prototype
-                  //       has a property |i| (very unlikely), so use a less-correct
-                  //       but more portable alternative.
-                  if (i in t)
-                      res[i] = fun.call(thisArg, t[i], i, t);
-              }
-
-              return res;
-          };
-      }
-
-
-      if(!Array.isArray) {
-          Array.isArray = function(arg) {
-              return Object.prototype.toString.call(arg) === '[object Array]';
-          };
-      }
-
-      if (!Array.prototype.forEach) {
-          Array.prototype.forEach = function(fun, thisArg) {
-
-              if (this === void 0 || this === null || typeof fun !== "function")
-                  throw new TypeError();
-
-              var t = Object(this), len = t.length >>> 0;
-              for (var i = 0; i < len; i++) {
-                  if (i in t)
-                      fun.call(thisArg, t[i], i, t);
-              }
-          };
-      }
-      
-      if (!Object.keys) {
-          Object.keys = (function () {
-
-              var hasOwnProperty = Object.prototype.hasOwnProperty,
-                  hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
-                  dontEnums = ['toString','toLocaleString','valueOf','hasOwnProperty',
-                      'isPrototypeOf','propertyIsEnumerable','constructor'],
-                  dontEnumsLength = dontEnums.length;
-
-              return function (obj) {
-                  if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
-                      throw new TypeError();
-                  }
-                  var result = [], prop, i;
-
-                  for (prop in obj) {
-                      if (hasOwnProperty.call(obj, prop)) {
-                          result.push(prop);
-                      }
-                  }
-
-                  if (hasDontEnumBug) {
-                      for (i = 0; i < dontEnumsLength; i++) {
-                          if (hasOwnProperty.call(obj, dontEnums[i])) {
-                              result.push(dontEnums[i]);
-                          }
-                      }
-                  }
-                  return result;
-              };
-          }());
-      }
-      
-      if (typeof Object.assign != 'function') {
-            Object.assign = function(target) {
-              if (target == null) {
-                throw new TypeError('Cannot convert undefined or null to object');
-              }
-
-              target = Object(target);
-              for (var index = 1; index < arguments.length; index++) {
-                var source = arguments[index];
-                if (source != null) {
-                  for (var key in source) {
-                    if (Object.prototype.hasOwnProperty.call(source, key)) {
-                      target[key] = source[key];
-                    }
-                  }
-                }
-              }
-              return target;
-            };
-          }
-
-      if (!String.prototype.trim) {
-          String.prototype.trim = function () {
-              return this.replace(/^\s+|\s+$/g, '');
-          };
-      }
-      if (!String.prototype.trimLeft) {
-          String.prototype.trimLeft = function() {
-              return this.replace(/^\s+/g, "");
-          };
-      }
-      if (!String.prototype.trimRight) {
-          String.prototype.trimRight = function() {
-              return this.replace(/\s+$/g, "");
-          };
-      }
-
-
-  }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || typeof global !== "undefined" && global ||  Function('return typeof this === "object" && this.content')() || Function('return this')()));
-  // `self` is undefined in Firefox for Android content script context
-  // while `this` is nsIContentFrameMessageManager
-  // with an attribute `content` that corresponds to the window
-
-  return jsPDF;
-
-
-});
\ No newline at end of file
diff --git a/locallib.php b/locallib.php
index ed52858e51feb67fb18059480e8c1fcf9e7cd0d2..00732d8c87ed4ad79af94bbf663f9d9d14b20625 100644
--- a/locallib.php
+++ b/locallib.php
@@ -64,7 +64,7 @@ function pdfannotator_display_embed($pdfannotator, $cm, $course, $file, $page =
     // Load and execute the javascript files.
     $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/pdf.js?ver=00002"));
     $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/textclipper.js"));
-    $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/index.js?ver=00036"));
+    $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/index.js?ver=00037"));
     $PAGE->requires->js(new moodle_url("/mod/pdfannotator/shared/locallib.js?ver=00006"));
 
     // Pass parameters from PHP to JavaScript.
diff --git a/shared/index.js b/shared/index.js
index d5143a85be906524cf7c06ef1866c23c86fe4dd1..e822f68dfbc2d205a179fbeec5a0e1256fd43659 100644
--- a/shared/index.js
+++ b/shared/index.js
@@ -760,14 +760,14 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                                             // Add page number each time it changes.
                                             if (page !== post['page']) {
                                                 page = post['page'];
-                                                doc.setFontType("bold");
+                                                doc.setFont(undefined, "bold");
                                                 doc.setTextColor(0,84,159);
                                                 if (count >= a4height) {
                                                     doc.addPage();
                                                     count = contentTopBottomMargin;
                                                 }
                                                 doc.text(15, count, M.util.get_string('page', 'pdfannotator') + " " + page);
-                                                doc.setFontType("normal");
+                                                doc.setFont(undefined, "normal");
                                                 count += 5;
                                             };
                                             // Add icon to each question depending on its annotation type and increment count by 5 or 7.
@@ -826,8 +826,8 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                                         var stringarray = doc.splitTextToSize(text, characters);
                                         var textbit;
                                         for (var j = 0; j < stringarray.length; j++) {
-                                            doc.setFont('NotoSans');
-                                            doc.setFontType("normal");
+                                            //doc.setFont('NotoSans');
+                                            doc.setFont(undefined, "normal");
                                             textbit = stringarray[j];
                                             if (count >= a4height) {
                                                 doc.addPage();
@@ -899,7 +899,7 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                                      * @returns {undefined}
                                      */
                                     function printAuthor(author, timemodified=null) {
-                                        doc.setFontType("bold");
+                                        doc.setFont(undefined, "bold");
                                         if (timemodified !== null) {
                                             doc.text(120, count, timemodified);
                                         }
@@ -907,7 +907,7 @@ function startIndex(Y,_cm,_documentObject,_contextId, _userid,_capabilities, _to
                                             count += 5;
                                         }
                                         doc.text(contentRightMargin, count, author);
-                                        doc.setFontType("normal");
+                                        doc.setFont(undefined, "normal");
                                         count += 5;
                                     }
                                     /**
diff --git a/thirdpartylibs.xml b/thirdpartylibs.xml
index c86e1a183c0042dea684d35d2e6f20e533c9080f..c7b19ddfd626e5a70c46aee5caaba50e853d659f 100644
--- a/thirdpartylibs.xml
+++ b/thirdpartylibs.xml
@@ -39,7 +39,7 @@
     <library>
         <location>amd/src/jspdf.js</location>
         <name>jsPDF</name>
-        <version>1.4.1</version>
+        <version>2.5.1</version>
         <license>MIT</license>
         <licenseversion></licenseversion>
     </library>
diff --git a/version.php b/version.php
index f32575cbb480183f8b60b35a4035a21f8f9c6df8..7e6c84fccb824dc3d7732c8ad195510b4d5ee6b4 100644
--- a/version.php
+++ b/version.php
@@ -25,7 +25,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $plugin->component = 'mod_pdfannotator';
-$plugin->version   = 2022112800;
+$plugin->version   = 2022112900;
 $plugin->release  = 'PDF Annotator v1.5 release 2';
 $plugin->requires  = 2021051700;
 $plugin->maturity  = MATURITY_STABLE;