Loading Quick Oil Change...

";function Hm(e,r){var t=e.match(/[\s\S]*?<\/table>/gi);if(!t||t.length==0)throw new Error("Invalid HTML: could not find ");if(t.length==1)return La(Mm(t[0],r),r);var a=Nw();t.forEach(function(e,t){Dw(a,Mm(e,r),"Sheet"+(t+1))});return a}function zm(e,r,t){var a=[];return a.join("")+""}function Vm(e,r){var t=r||{};var a=t.header!=null?t.header:Bm;var n=t.footer!=null?t.footer:Wm;var i=[a];var s=Ia(e["!ref"]);t.dense=Array.isArray(e);i.push(zm(e,s,t));for(var f=s.s.r;f<=s.e.r;++f)i.push(Um(e,s,f,t));i.push("
"+n);return i.join("")}function Gm(e,r,t){var a=t||{};if(g!=null)a.dense=g;var n=0,i=0;if(a.origin!=null){if(typeof a.origin=="number")n=a.origin;else{var s=typeof a.origin=="string"?Oa(a.origin):a.origin;n=s.r;i=s.c}}var f=r.getElementsByTagName("tr"); var o=Math.min(a.sheetRows||1e7,f.length);var l={s:{r:0,c:0},e:{r:n,c:i}};if(e["!ref"]){var c=Ia(e["!ref"]);l.s.r=Math.min(l.s.r,c.s.r);l.s.c=Math.min(l.s.c,c.s.c);l.e.r=Math.max(l.e.r,c.e.r);l.e.c=Math.max(l.e.c,c.e.c);if(n==-1)l.e.r=n=c.e.r+1}var h=[],u=0;var d=e["!rows"]||(e["!rows"]=[]);var v=0,p=0,m=0,b=0,w=0,k=0;if(!e["!cols"])e["!cols"]=[];for(;v1||k>1)h.push({s:{r:p+n,c:b+i},e:{r:p+n+(w||1)-1,c:b+i+(k||1)-1}});var _={t:"s",v:C};var x=E.getAttribute("data-t")||E.getAttribute("t")||"";if(C!=null){if(C.length==0)_.t=x||"z";else if(a.raw||C.trim().length==0||x=="s"){}else if(C==="TRUE")_={t:"b",v:true};else if(C==="FALSE")_={t:"b",v:false};else if(!isNaN(kr(C)))_={t:"n",v:kr(C)};else if(!isNaN(Ar(C).getDate())){_={t:"d",v:gr(C)};if(!a.cellDates)_={t:"n",v:fr(_.v)};_.z=a.dateNF||X[14]}}if(_.z===undefined&&y!=null)_.z=y;var O="",R=E.getElementsByTagName("A");if(R&&R.length)for(var I=0;I=o)e["!fullref"]=Na((l.e.r=f.length-v+p-1+n,l));return e}function jm(e,r){var t=r||{};var a=t.dense?[]:{};return Gm(a,e,r)}function Xm(e,r){return La(jm(e,r),r)}function $m(e){var r="";var t=Ym(e);if(t)r=t(e).getPropertyValue("display");if(!r)r=e.style&&e.style.display;return r==="none"}function Ym(e){if(e.ownerDocument.defaultView&&typeof e.ownerDocument.defaultView.getComputedStyle==="function")return e.ownerDocument.defaultView.getComputedStyle;if(typeof getComputedStyle==="function")return getComputedStyle;return null}function Km(e){var r=e.replace(/[\t\r\n]/g," ").trim().replace(/ +/g," ").replace(//g," ").replace(//g,function(e,r){return Array(parseInt(r,10)+1).join(" ")}).replace(/]*\/>/g,"\t").replace(//g,"\n");var t=Yr(r.replace(/<[^>]*>/g,""));return[t]}var Jm={day:["d","dd"],month:["m","mm"],year:["y","yy"],hours:["h","hh"],minutes:["m","mm"],seconds:["s","ss"],"am-pm":["A/P","AM/PM"],"day-of-week":["ddd","dddd"],era:["e","ee"],quarter:["\\Qm",'m\\"th quarter"']};function qm(e,r){var t=r||{};if(g!=null&&t.dense==null)t.dense=g;var a=Et(e);var n=[],i;var s;var f={name:""},o="",l=0;var c;var h;var u={},d=[];var v=t.dense?[]:{};var p,m;var b={value:""};var w="",k=0,T;var A=[];var E=-1,C=-1,y={s:{r:1e6,c:1e7},e:{r:0,c:0}};var S=0;var _={};var x=[],O={},R=0,I=0;var N=[],D=1,F=1;var P=[];var L={Names:[]};var M={};var U=["",""];var B=[],W={};var H="",z=0;var V=false,G=false;var j=0;Ct.lastIndex=0;a=a.replace(//gm,"").replace(//gm,"");while(p=Ct.exec(a))switch(p[3]=p[3].replace(/_.*$/,"")){case"table":;case"工作表":if(p[1]==="/"){if(y.e.c>=y.s.c&&y.e.r>=y.s.r)v["!ref"]=Na(y);else v["!ref"]="A1:A1";if(t.sheetRows>0&&t.sheetRows<=y.e.r){v["!fullref"]=v["!ref"];y.e.r=t.sheetRows-1;v["!ref"]=Na(y)}if(x.length)v["!merges"]=x;if(N.length)v["!rows"]=N;c.name=c["名称"]||c.name;if(typeof JSON!=="undefined")JSON.stringify(c);d.push(c.name);u[c.name]=v;G=false}else if(p[0].charAt(p[0].length-2)!=="/"){c=Gr(p[0],false);E=C=-1;y.s.r=y.s.c=1e7;y.e.r=y.e.c=0;v=t.dense?[]:{};x=[];N=[];G=true}break;case"table-row-group":if(p[1]==="/")--S;else++S;break;case"table-row":;case"行":if(p[1]==="/"){E+=D;D=1;break}h=Gr(p[0],false);if(h["行号"])E=h["行号"]-1;else if(E==-1)E=0;D=+h["number-rows-repeated"]||1;if(D<10)for(j=0;j0)N[E+j]={level:S};C=-1;break;case"covered-table-cell":if(p[1]!=="/")++C;if(t.sheetStubs){if(t.dense){if(!v[E])v[E]=[];v[E][C]={t:"z"}}else v[Ra({r:E,c:C})]={t:"z"}}w="";A=[];break;case"table-cell":;case"数据":if(p[0].charAt(p[0].length-2)==="/"){++C;b=Gr(p[0],false);F=parseInt(b["number-columns-repeated"]||"1",10);m={t:"z",v:null};if(b.formula&&t.cellFormula!=false)m.f=Cd(Yr(b.formula));if((b["数据类型"]||b["value-type"])=="string"){m.t="s";m.v=Yr(b["string-value"]||"");if(t.dense){if(!v[E])v[E]=[];v[E][C]=m}else{v[Ra({r:E,c:C})]=m}}C+=F-1}else if(p[1]!=="/"){++C;w="";k=0;A=[];F=1;var X=D?E+D-1:E;if(C>y.e.c)y.e.c=C;if(Cy.e.r)y.e.r=X;b=Gr(p[0],false);B=[];W={};m={t:b["数据类型"]||b["value-type"],v:null};if(t.cellFormula){if(b.formula)b.formula=Yr(b.formula);if(b["number-matrix-columns-spanned"]&&b["number-matrix-rows-spanned"]){R=parseInt(b["number-matrix-rows-spanned"],10)||0;I=parseInt(b["number-matrix-columns-spanned"],10)||0;O={s:{r:E,c:C},e:{r:E+R-1,c:C+I-1}};m.F=Na(O);P.push([O,m.F])}if(b.formula)m.f=Cd(b.formula);else for(j=0;j=P[j][0].s.r&&E<=P[j][0].e.r)if(C>=P[j][0].s.c&&C<=P[j][0].e.c)m.F=P[j][1]}if(b["number-columns-spanned"]||b["number-rows-spanned"]){R=parseInt(b["number-rows-spanned"],10)||0;I=parseInt(b["number-columns-spanned"],10)||0;O={s:{r:E,c:C},e:{r:E+R-1,c:C+I-1}};x.push(O)}if(b["number-columns-repeated"])F=parseInt(b["number-columns-repeated"],10);switch(m.t){case"boolean":m.t="b";m.v=nt(b["boolean-value"]);break;case"float":m.t="n";m.v=parseFloat(b.value);break;case"percentage":m.t="n";m.v=parseFloat(b.value);break;case"currency":m.t="n";m.v=parseFloat(b.value);break;case"date":m.t="d";m.v=gr(b["date-value"]);if(!t.cellDates){m.t="n";m.v=fr(m.v)}m.z="m/d/yy";break;case"time":m.t="n";m.v=ur(b["time-value"])/86400;if(t.cellDates){m.t="d";m.v=hr(m.v)}m.z="HH:MM:SS";break;case"number":m.t="n";m.v=parseFloat(b["数据数值"]);break;default:if(m.t==="string"||m.t==="text"||!m.t){m.t="s";if(b["string-value"]!=null){w=Yr(b["string-value"]);A=[]}}else throw new Error("Unsupported value type "+m.t);}}else{V=false;if(m.t==="s"){m.v=w||"";if(A.length)m.R=A;V=k==0}if(M.Target)m.l=M;if(B.length>0){m.c=B;B=[]}if(w&&t.cellText!==false)m.w=w;if(V){m.t="z";delete m.v}if(!V||t.sheetStubs){if(!(t.sheetRows&&t.sheetRows<=E)){for(var $=0;$0)v[E+$][C+F]=br(m)}else{v[Ra({r:E+$,c:C})]=m;while(--F>0)v[Ra({r:E+$,c:C+F})]=br(m)}if(y.e.c<=C)y.e.c=C}}}F=parseInt(b["number-columns-repeated"]||"1",10);C+=F-1;F=0;m={};w="";A=[]}M={};break;case"document":;case"document-content":;case"电子表格文档":;case"spreadsheet":;case"主体":;case"scripts":;case"styles":;case"font-face-decls":;case"master-styles":if(p[1]==="/"){if((i=n.pop())[0]!==p[3])throw"Bad state: "+i}else if(p[0].charAt(p[0].length-2)!=="/")n.push([p[3],true]);break;case"annotation":if(p[1]==="/"){if((i=n.pop())[0]!==p[3])throw"Bad state: "+i;W.t=w;if(A.length)W.R=A;W.a=H;B.push(W)}else if(p[0].charAt(p[0].length-2)!=="/"){n.push([p[3],false])}H="";z=0;w="";k=0;A=[];break;case"creator":if(p[1]==="/"){H=a.slice(z,p.index)}else z=p.index+p[0].length;break;case"meta":;case"元数据":;case"settings":;case"config-item-set":;case"config-item-map-indexed":;case"config-item-map-entry":;case"config-item-map-named":;case"shapes":;case"frame":;case"text-box":;case"image":;case"data-pilot-tables":;case"list-style":;case"form":;case"dde-links":;case"event-listeners":;case"chart":if(p[1]==="/"){if((i=n.pop())[0]!==p[3])throw"Bad state: "+i}else if(p[0].charAt(p[0].length-2)!=="/")n.push([p[3],false]);w="";k=0;A=[];break;case"scientific-number":break;case"currency-symbol":break;case"currency-style":break;case"number-style":;case"percentage-style":;case"date-style":;case"time-style":if(p[1]==="/"){_[f.name]=o;if((i=n.pop())[0]!==p[3])throw"Bad state: "+i}else if(p[0].charAt(p[0].length-2)!=="/"){o="";f=Gr(p[0],false);n.push([p[3],true])}break;case"script":break;case"libraries":break;case"automatic-styles":break;case"default-style":;case"page-layout":break;case"style":break;case"map":break;case"font-face":break;case"paragraph-properties":break;case"table-properties":break;case"table-column-properties":break;case"table-row-properties":break;case"table-cell-properties":break;case"number":switch(n[n.length-1][0]){case"time-style":;case"date-style":s=Gr(p[0],false);o+=Jm[p[3]][s.style==="long"?1:0];break;}break;case"fraction":break;case"day":;case"month":;case"year":;case"era":;case"day-of-week":;case"week-of-year":;case"quarter":;case"hours":;case"minutes":;case"seconds":;case"am-pm":switch(n[n.length-1][0]){case"time-style":;case"date-style":s=Gr(p[0],false);o+=Jm[p[3]][s.style==="long"?1:0];break;}break;case"boolean-style":break;case"boolean":break;case"text-style":break;case"text":if(p[0].slice(-2)==="/>")break;else if(p[1]==="/")switch(n[n.length-1][0]){case"number-style":;case"date-style":;case"time-style":o+=a.slice(l,p.index);break;}else l=p.index+p[0].length;break;case"named-range":s=Gr(p[0],false);U=Sd(s["cell-range-address"]);var Y={Name:s.name,Ref:U[0]+"!"+U[1]};if(G)Y.Sheet=d.length;L.Names.push(Y);break;case"text-content":break;case"text-properties":break;case"embedded-text":break;case"body":;case"电子表格":break;case"forms":break;case"table-column":break;case"table-header-rows":break;case"table-rows":break;case"table-column-group":break;case"table-header-columns":break;case"table-columns":break;case"null-date":break;case"graphic-properties":break;case"calculation-settings":break;case"named-expressions":break;case"label-range":break;case"label-ranges":break;case"named-expression":break;case"sort":break;case"sort-by":break;case"sort-groups":break;case"tab":break;case"line-break":break;case"span":break;case"p":;case"文本串":if(["master-styles"].indexOf(n[n.length-1][0])>-1)break;if(p[1]==="/"&&(!b||!b["string-value"])){var K=Km(a.slice(k,p.index),T);w=(w.length>0?w+"\n":"")+K[0]}else{T=Gr(p[0],false);k=p.index+p[0].length}break;case"s":break;case"database-range":if(p[1]==="/")break;try{U=Sd(Gr(p[0])["target-range-address"]);u[U[0]]["!autofilter"]={ref:U[1]}}catch(J){}break;case"date":break;case"object":break;case"title":;case"标题":break;case"desc":break;case"binary-data":break;case"table-source":break;case"scenario":break;case"iteration":break;case"content-validations":break;case"content-validation":break;case"help-message":break;case"error-message":break;case"database-ranges":break;case"filter":break;case"filter-and":break;case"filter-or":break;case"filter-condition":break;case"list-level-style-bullet":break;case"list-level-style-number":break;case"list-level-properties":break;case"sender-firstname":;case"sender-lastname":;case"sender-initials":;case"sender-title":;case"sender-position":;case"sender-email":;case"sender-phone-private":;case"sender-fax":;case"sender-company":;case"sender-phone-work":;case"sender-street":;case"sender-city":;case"sender-postal-code":;case"sender-country":;case"sender-state-or-province":;case"author-name":;case"author-initials":;case"chapter":;case"file-name":;case"template-name":;case"sheet-name":break;case"event-listener":break;case"initial-creator":;case"creation-date":;case"print-date":;case"generator":;case"document-statistic":;case"user-defined":;case"editing-duration":;case"editing-cycles":break;case"config-item":break;case"page-number":break;case"page-count":break;case"time":break;case"cell-range-source":break;case"detective":break;case"operation":break;case"highlighted-range":break;case"data-pilot-table":;case"source-cell-range":;case"source-service":;case"data-pilot-field":;case"data-pilot-level":;case"data-pilot-subtotals":;case"data-pilot-subtotal":;case"data-pilot-members":;case"data-pilot-member":;case"data-pilot-display-info":;case"data-pilot-sort-info":;case"data-pilot-layout-info":;case"data-pilot-field-reference":;case"data-pilot-groups":;case"data-pilot-group":;case"data-pilot-group-member":break;case"rect":break;case"dde-connection-decls":;case"dde-connection-decl":;case"dde-link":;case"dde-source":break;case"properties":break;case"property":break;case"a":if(p[1]!=="/"){M=Gr(p[0],false);if(!M.href)break;M.Target=Yr(M.href);delete M.href;if(M.Target.charAt(0)=="#"&&M.Target.indexOf(".")>-1){U=Sd(M.Target.slice(1));M.Target="#"+U[0]+"!"+U[1]}else if(M.Target.match(/^\.\.[\\\/]/))M.Target=M.Target.slice(3)}break;case"table-protection":break;case"data-pilot-grand-total":break;case"office-document-common-attrs":break;default:switch(p[2]){case"dc:":;case"calcext:":;case"loext:":;case"ooo:":;case"chartooo:":;case"draw:":;case"style:":;case"chart:":;case"form:":;case"uof:":;case"表:":;case"字:":break;default:if(t.WTF)throw new Error(p);};}var q={Sheets:u,SheetNames:d,Workbook:L};if(t.bookSheets)delete q.Sheets;return q}function Zm(e,r){r=r||{};if(_r(e,"META-INF/manifest.xml"))ai(Or(e,"META-INF/manifest.xml"),r);var t=Rr(e,"content.xml");if(!t)throw new Error("Missing content.xml in ODS / UOF file");var a=qm(lt(t),r);if(_r(e,"meta.xml"))a.Props=hi(Or(e,"meta.xml"));return a}function Qm(e,r){return qm(e,r)}var eb=function(){var e=["",'',"",'',"",'',"",""].join("");var r=""+e+"";return function t(){return Mr+r}}();var rb=function(){var e=function(e){return qr(e).replace(/ +/g,function(e){return''}).replace(/\t/g,"").replace(/\n/g,"").replace(/^ /,"").replace(/ $/,"")};var r=" \n";var t=" \n";var a=function(a,n,i){var s=[];s.push(' \n');var f=0,o=0,l=Ia(a["!ref"]||"A1");var c=a["!merges"]||[],h=0;var u=Array.isArray(a);if(a["!cols"]){for(o=0;o<=l.e.c;++o)s.push(" \n")}var d="",v=a["!rows"]||[];for(f=0;f\n")}for(;f<=l.e.r;++f){d=v[f]?' table:style-name="ro'+v[f].ods+'"':"";s.push(" \n");for(o=0;oo)continue;if(c[h].s.r>f)continue;if(c[h].e.c\n")}s.push(" \n");return s.join("")};var n=function(e,r){e.push(" \n");e.push(' \n');e.push(' \n');e.push(" /\n");e.push(' \n');e.push(" /\n");e.push(" \n");e.push(" \n");var t=0;r.SheetNames.map(function(e){return r.Sheets[e]}).forEach(function(r){if(!r)return;if(r["!cols"]){for(var a=0;a\n');e.push(' \n');e.push(" \n");++t}}});var a=0;r.SheetNames.map(function(e){return r.Sheets[e]}).forEach(function(r){if(!r)return;if(r["!rows"]){for(var t=0;t\n');e.push(' \n');e.push(" \n");++a}}});e.push(' \n');e.push(' \n');e.push(" \n");e.push(' \n');e.push(" \n")};return function i(e,r){var t=[Mr];var i=wt({"xmlns:office":"urn:oasis:names:tc:opendocument:xmlns:office:1.0","xmlns:table":"urn:oasis:names:tc:opendocument:xmlns:table:1.0","xmlns:style":"urn:oasis:names:tc:opendocument:xmlns:style:1.0","xmlns:text":"urn:oasis:names:tc:opendocument:xmlns:text:1.0","xmlns:draw":"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0","xmlns:fo":"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0","xmlns:xlink":"http://www.w3.org/1999/xlink","xmlns:dc":"http://purl.org/dc/elements/1.1/","xmlns:meta":"urn:oasis:names:tc:opendocument:xmlns:meta:1.0","xmlns:number":"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0","xmlns:presentation":"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0","xmlns:svg":"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0","xmlns:chart":"urn:oasis:names:tc:opendocument:xmlns:chart:1.0","xmlns:dr3d":"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0","xmlns:math":"http://www.w3.org/1998/Math/MathML","xmlns:form":"urn:oasis:names:tc:opendocument:xmlns:form:1.0","xmlns:script":"urn:oasis:names:tc:opendocument:xmlns:script:1.0","xmlns:ooo":"http://openoffice.org/2004/office","xmlns:ooow":"http://openoffice.org/2004/writer","xmlns:oooc":"http://openoffice.org/2004/calc","xmlns:dom":"http://www.w3.org/2001/xml-events","xmlns:xforms":"http://www.w3.org/2002/xforms","xmlns:xsd":"http://www.w3.org/2001/XMLSchema","xmlns:xsi":"http://www.w3.org/2001/XMLSchema-instance","xmlns:sheet":"urn:oasis:names:tc:opendocument:sh33tjs:1.0","xmlns:rpt":"http://openoffice.org/2005/report","xmlns:of":"urn:oasis:names:tc:opendocument:xmlns:of:1.2","xmlns:xhtml":"http://www.w3.org/1999/xhtml","xmlns:grddl":"http://www.w3.org/2003/g/data-view#","xmlns:tableooo":"http://openoffice.org/2009/table","xmlns:drawooo":"http://openoffice.org/2010/draw","xmlns:calcext":"urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0","xmlns:loext":"urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0","xmlns:field":"urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0","xmlns:formx":"urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0","xmlns:css3t":"http://www.w3.org/TR/css3-text/","office:version":"1.2"});var s=wt({"xmlns:config":"urn:oasis:names:tc:opendocument:xmlns:config:1.0","office:mimetype":"application/vnd.oasis.opendocument.spreadsheet"});if(r.bookType=="fods"){t.push("\n");t.push(oi().replace(/office:document-meta/g,"office:meta"))}else t.push("\n");n(t,e);t.push(" \n");t.push(" \n");for(var f=0;f!=e.SheetNames.length;++f)t.push(a(e.Sheets[e.SheetNames[f]],e,f,r));t.push(" \n");t.push(" \n");if(r.bookType=="fods")t.push("");else t.push("");return t.join("")}}();function tb(e,r){if(r.bookType=="fods")return rb(e,r);var t=Fr();var a="";var n=[];var i=[];a="mimetype";Dr(t,a,"application/vnd.oasis.opendocument.spreadsheet");a="content.xml";Dr(t,a,rb(e,r));n.push([a,"text/xml"]);i.push([a,"ContentFile"]);a="styles.xml";Dr(t,a,eb(e,r));n.push([a,"text/xml"]);i.push([a,"StylesFile"]);a="meta.xml";Dr(t,a,Mr+oi());n.push([a,"text/xml"]);i.push([a,"MetadataFile"]);a="manifest.rdf";Dr(t,a,fi(i));n.push([a,"application/rdf+xml"]);a="META-INF/manifest.xml";Dr(t,a,ni(n));return t}function ab(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}function nb(e){return typeof TextDecoder!="undefined"?(new TextDecoder).decode(e):lt(_(e))}function ib(e){return typeof TextEncoder!="undefined"?(new TextEncoder).encode(e):y(ct(e))}function sb(e,r){e:for(var t=0;t<=e.length-r.length;++t){for(var a=0;a>1&1431655765;e=(e&858993459)+(e>>2&858993459);return(e+(e>>4)&252645135)*16843009>>>24}function lb(e,r){var t=(e[r+15]&127)<<7|e[r+14]>>1;var a=e[r+14]&1;for(var n=r+13;n>=r;--n)a=a*256+e[n];return(e[r+15]&128?-a:a)*Math.pow(10,t-6176)}function cb(e,r,t){var a=Math.floor(t==0?0:Math.LOG10E*Math.log(Math.abs(t)))+6176-20;var n=t/Math.pow(10,a-6176);e[r+15]|=a>>7;e[r+14]|=(a&127)<<1;for(var i=0;n>=1;++i,n/=256)e[r+i]=n&255;e[r+15]|=t>=0?0:128}function hb(e,r){var t=r?r[0]:0;var a=e[t]&127;e:if(e[t++]>=128){a|=(e[t]&127)<<7;if(e[t++]<128)break e;a|=(e[t]&127)<<14;if(e[t++]<128)break e;a|=(e[t]&127)<<21;if(e[t++]<128)break e;a+=(e[t]&127)*Math.pow(2,28);++t;if(e[t++]<128)break e;a+=(e[t]&127)*Math.pow(2,35);++t;if(e[t++]<128)break e;a+=(e[t]&127)*Math.pow(2,42);++t;if(e[t++]<128)break e}if(r)r[0]=t;return a}function ub(e){var r=new Uint8Array(7);r[0]=e&127;var t=1;e:if(e>127){r[t-1]|=128;r[t]=e>>7&127;++t;if(e<=16383)break e;r[t-1]|=128;r[t]=e>>14&127;++t;if(e<=2097151)break e;r[t-1]|=128;r[t]=e>>21&127;++t;if(e<=268435455)break e;r[t-1]|=128;r[t]=e/256>>>21&127;++t;if(e<=34359738367)break e;r[t-1]|=128;r[t]=e/65536>>>21&127;++t;if(e<=4398046511103)break e;r[t-1]|=128;r[t]=e/16777216>>>21&127;++t}return r.slice(0,t)}function db(e){var r=0,t=e[r]&127;e:if(e[r++]>=128){t|=(e[r]&127)<<7;if(e[r++]<128)break e;t|=(e[r]&127)<<14;if(e[r++]<128)break e;t|=(e[r]&127)<<21;if(e[r++]<128)break e;t|=(e[r]&127)<<28}return t}function vb(e){var r=[],t=[0];while(t[0]=128);f=e.slice(o,t[0])}break;case 5:s=4;f=e.slice(t[0],t[0]+s);t[0]+=s;break;case 1:s=8;f=e.slice(t[0],t[0]+s);t[0]+=s;break;case 2:s=hb(e,t);f=e.slice(t[0],t[0]+s);t[0]+=s;break;case 3:;case 4:;default:throw new Error("PB Type ".concat(i," for Field ").concat(n," at offset ").concat(a));}var l={data:f,type:i};if(r[n]==null)r[n]=[l];else r[n].push(l)}return r}function pb(e){var r=[];e.forEach(function(e,t){e.forEach(function(e){if(!e.data)return;r.push(ub(t*8+e.type));if(e.type==2)r.push(ub(e.data.length));r.push(e.data)})});return fb(r)}function gb(e,r){return(e==null?void 0:e.map(function(e){return r(e.data)}))||[]}function mb(e){var r;var t=[],a=[0];while(a[0]>>0>0;t.push(s)}return t}function bb(e){var r=[];e.forEach(function(e){var t=[];t[1]=[{data:ub(e.id),type:0}];t[2]=[];if(e.merge!=null)t[3]=[{data:ub(+!!e.merge),type:0}];var a=[];e.messages.forEach(function(e){a.push(e.data);e.meta[3]=[{type:0,data:ub(e.data.length)}];t[2].push({data:pb(e.meta),type:2})});var n=pb(t);r.push(ub(n.length));r.push(n);a.forEach(function(e){return r.push(e)})});return fb(r)}function wb(e,r){if(e!=0)throw new Error("Unexpected Snappy chunk type ".concat(e));var t=[0];var a=hb(r,t);var n=[];while(t[0]>2;if(s<60)++s;else{var f=s-59;s=r[t[0]];if(f>1)s|=r[t[0]+1]<<8;if(f>2)s|=r[t[0]+2]<<16;if(f>3)s|=r[t[0]+3]<<24;s>>>=0;s++;t[0]+=f}n.push(r.slice(t[0],t[0]+s));t[0]+=s;continue}else{var o=0,l=0;if(i==1){l=(r[t[0]]>>2&7)+4;o=(r[t[0]++]&224)<<3;o|=r[t[0]++]}else{l=(r[t[0]++]>>2)+1;if(i==2){o=r[t[0]]|r[t[0]+1]<<8;t[0]+=2}else{o=(r[t[0]]|r[t[0]+1]<<8|r[t[0]+2]<<16|r[t[0]+3]<<24)>>>0;t[0]+=4}}n=[fb(n)];if(o==0)throw new Error("Invalid offset 0");if(o>n[0].length)throw new Error("Invalid offset beyond length");if(l>=o){n.push(n[0].slice(-o));l-=o;while(l>=n[n.length-1].length){n.push(n[n.length-1]);l-=n[n.length-1].length}}n.push(n[0].slice(-o,-o+l))}}var c=fb(n);if(c.length!=a)throw new Error("Unexpected length: ".concat(c.length," != ").concat(a));return c}function kb(e){var r=[];var t=0;while(t>8&255]))}else if(a<=16777216){s+=4;r.push(new Uint8Array([248,a-1&255,a-1>>8&255,a-1>>16&255]))}else if(a<=4294967296){s+=5;r.push(new Uint8Array([252,a-1&255,a-1>>8&255,a-1>>16&255,a-1>>>24&255]))}r.push(e.slice(t,t+a));s+=a;n[0]=0;n[1]=s&255;n[2]=s>>8&255;n[3]=s>>16&255;t+=a}return fb(r)}function Ab(e,r,t,a){var n=ab(e);var i=n.getUint32(4,true);var s=(a>1?12:8)+ob(i&(a>1?3470:398))*4;var f=-1,o=-1,l=NaN,c=new Date(2001,0,1);if(i&512){f=n.getUint32(s,true);s+=4}s+=ob(i&(a>1?12288:4096))*4;if(i&16){o=n.getUint32(s,true);s+=4}if(i&32){l=n.getFloat64(s,true);s+=8}if(i&64){c.setTime(c.getTime()+n.getFloat64(s,true)*1e3);s+=8}var h;switch(e[2]){case 0:break;case 2:h={t:"n",v:l};break;case 3:h={t:"s",v:r[o]};break;case 5:h={t:"d",v:c};break;case 6:h={t:"b",v:l>0};break;case 7:h={t:"n",v:l/86400};break;case 8:h={t:"e",v:0};break;case 9:{if(f>-1)h={t:"s",v:t[f]};else if(o>-1)h={t:"s",v:r[o]};else if(!isNaN(l))h={t:"n",v:l};else throw new Error("Unsupported cell type ".concat(e.slice(0,4)))}break;default:throw new Error("Unsupported cell type ".concat(e.slice(0,4)));}return h}function Eb(e,r,t){var a=ab(e);var n=a.getUint32(8,true);var i=12;var s=-1,f=-1,o=NaN,l=NaN,c=new Date(2001,0,1);if(n&1){o=lb(e,i);i+=16}if(n&2){l=a.getFloat64(i,true);i+=8}if(n&4){c.setTime(c.getTime()+a.getFloat64(i,true)*1e3);i+=8}if(n&8){f=a.getUint32(i,true);i+=4}if(n&16){s=a.getUint32(i,true);i+=4}var h;switch(e[1]){case 0:break;case 2:h={t:"n",v:o};break;case 3:h={t:"s",v:r[f]};break;case 5:h={t:"d",v:c};break;case 6:h={t:"b",v:l>0};break;case 7:h={t:"n",v:l/86400};break;case 8:h={t:"e",v:0};break;case 9:{if(s>-1)h={t:"s",v:t[s]};else throw new Error("Unsupported cell type ".concat(e[1]," : ").concat(n&31," : ").concat(e.slice(0,4)))}break;case 10:h={t:"n",v:o};break;default:throw new Error("Unsupported cell type ".concat(e[1]," : ").concat(n&31," : ").concat(e.slice(0,4)));}return h}function Cb(e,r){var t=new Uint8Array(32),a=ab(t),n=12,i=0;t[0]=5;switch(e.t){case"n":t[1]=2;cb(t,n,e.v);i|=1;n+=16;break;case"b":t[1]=6;a.setFloat64(n,e.v?1:0,true);i|=2;n+=8;break;case"s":if(r.indexOf(e.v)==-1)throw new Error("Value ".concat(e.v," missing from SST!"));t[1]=3;a.setUint32(n,r.indexOf(e.v),true);i|=8;n+=4;break;default:throw"unsupported cell type "+e.t;}a.setUint32(8,i,true);return t.slice(0,n)}function yb(e,r){var t=new Uint8Array(32),a=ab(t),n=12,i=0;t[0]=3;switch(e.t){case"n":t[2]=2;a.setFloat64(n,e.v,true);i|=32;n+=8;break;case"b":t[2]=6;a.setFloat64(n,e.v?1:0,true);i|=32;n+=8;break;case"s":if(r.indexOf(e.v)==-1)throw new Error("Value ".concat(e.v," missing from SST!"));t[2]=3;a.setUint32(n,r.indexOf(e.v),true);i|=16;n+=4;break;default:throw"unsupported cell type "+e.t;}a.setUint32(4,i,true);return t.slice(0,n)}function Sb(e,r,t){switch(e[0]){case 0:;case 1:;case 2:;case 3:return Ab(e,r,t,e[0]);case 5:return Eb(e,r,t);default:throw new Error("Unsupported payload version ".concat(e[0]));}}function _b(e){var r=vb(e);return hb(r[1][0].data)}function xb(e){var r=[];r[1]=[{type:0,data:ub(e)}];return pb(r)}function Ob(e,r){var t=vb(r.data);var a=db(t[1][0].data);var n=t[3];var i=[];(n||[]).forEach(function(r){var t=vb(r.data);var n=db(t[1][0].data)>>>0;switch(a){case 1:i[n]=nb(t[3][0].data);break;case 8:{var s=e[_b(t[9][0].data)][0];var f=vb(s.data);var o=e[_b(f[1][0].data)][0];var l=db(o.meta[1][0].data);if(l!=2001)throw new Error("2000 unexpected reference to ".concat(l));var c=vb(o.data);i[n]=c[3].map(function(e){return nb(e.data)}).join("")}break;}});return i}function Rb(e,r){var t,a,n,i,s,f,o,l,c,h,u,d,v,p;var g=vb(e);var m=db(g[1][0].data)>>>0;var b=db(g[2][0].data)>>>0;var w=((a=(t=g[8])==null?void 0:t[0])==null?void 0:a.data)&&db(g[8][0].data)>0||false;var k,T;if(((i=(n=g[7])==null?void 0:n[0])==null?void 0:i.data)&&r!=0){k=(f=(s=g[7])==null?void 0:s[0])==null?void 0:f.data;T=(l=(o=g[6])==null?void 0:o[0])==null?void 0:l.data}else if(((h=(c=g[4])==null?void 0:c[0])==null?void 0:h.data)&&r!=1){k=(d=(u=g[4])==null?void 0:u[0])==null?void 0:d.data;T=(p=(v=g[3])==null?void 0:v[0])==null?void 0:p.data}else throw"NUMBERS Tile missing ".concat(r," cell storage");var A=w?4:1;var E=ab(k);var C=[];for(var y=0;y=1)_[C[C.length-1][0]]=T.subarray(C[C.length-1][1]*A);return{R:m,cells:_}}function Ib(e,r){var t;var a=vb(r.data);var n=((t=a==null?void 0:a[7])==null?void 0:t[0])?db(a[7][0].data)>>>0>0?1:0:-1;var i=gb(a[5],function(e){return Rb(e,n)});return{nrows:db(a[4][0].data)>>>0,data:i.reduce(function(e,r){if(!e[r.R])e[r.R]=[];r.cells.forEach(function(t,a){if(e[r.R][a])throw new Error("Duplicate cell r=".concat(r.R," c=").concat(a));e[r.R][a]=t});return e},[])}}function Nb(e,r,t){var a;var n=vb(r.data);var i={s:{r:0,c:0},e:{r:0,c:0}};i.e.r=(db(n[6][0].data)>>>0)-1;if(i.e.r<0)throw new Error("Invalid row varint ".concat(n[6][0].data));i.e.c=(db(n[7][0].data)>>>0)-1;if(i.e.c<0)throw new Error("Invalid col varint ".concat(n[7][0].data));t["!ref"]=Na(i);var s=vb(n[4][0].data);var f=Ob(e,e[_b(s[4][0].data)][0]); var o=((a=s[17])==null?void 0:a[0])?Ob(e,e[_b(s[17][0].data)][0]):[];var l=vb(s[3][0].data);var c=0;l[1].forEach(function(r){var a=vb(r.data);var n=e[_b(a[2][0].data)][0];var i=db(n.meta[1][0].data);if(i!=6002)throw new Error("6001 unexpected reference to ".concat(i));var s=Ib(e,n);s.data.forEach(function(e,r){e.forEach(function(e,a){var n=Ra({r:c+r,c:a});var i=Sb(e,f,o);if(i)t[n]=i})});c+=s.nrows})}function Db(e,r){var t=vb(r.data);var a={"!ref":"A1"};var n=e[_b(t[2][0].data)];var i=db(n[0].meta[1][0].data);if(i!=6001)throw new Error("6000 unexpected reference to ".concat(i));Nb(e,n[0],a);return a}function Fb(e,r){var t;var a=vb(r.data);var n={name:((t=a[1])==null?void 0:t[0])?nb(a[1][0].data):"",sheets:[]};var i=gb(a[2],_b);i.forEach(function(r){e[r].forEach(function(r){var t=db(r.meta[1][0].data);if(t==6e3)n.sheets.push(Db(e,r))})});return n}function Pb(e,r){var t=Nw();var a=vb(r.data);var n=gb(a[1],_b);n.forEach(function(r){e[r].forEach(function(r){var a=db(r.meta[1][0].data);if(a==2){var n=Fb(e,r);n.sheets.forEach(function(e,r){Dw(t,e,r==0?n.name:n.name+"_"+r,true)})}})});if(t.SheetNames.length==0)throw new Error("Empty NUMBERS file");return t}function Lb(e){var r,t,a,n;var i={},s=[];e.FullPaths.forEach(function(e){if(e.match(/\.iwpv2/))throw new Error("Unsupported password protection")});e.FileIndex.forEach(function(e){if(!e.name.match(/\.iwa$/))return;var r;try{r=kb(e.content)}catch(t){return console.log("?? "+e.content.length+" "+(t.message||t))}var a;try{a=mb(r)}catch(t){return console.log("## "+(t.message||t))}a.forEach(function(e){i[e.id]=e.messages;s.push(e.id)})});if(!s.length)throw new Error("File has no messages");var f=((n=(a=(t=(r=i==null?void 0:i[1])==null?void 0:r[0])==null?void 0:t.meta)==null?void 0:a[1])==null?void 0:n[0].data)&&db(i[1][0].meta[1][0].data)==1&&i[1][0];if(!f)s.forEach(function(e){i[e].forEach(function(e){var r=db(e.meta[1][0].data)>>>0;if(r==1){if(!f)f=e;else throw new Error("Document has multiple roots")}})});if(!f)throw new Error("Cannot find Document root");return Pb(i,f)}function Mb(e,r,t){var a,n,i,s;if(!((a=e[6])==null?void 0:a[0])||!((n=e[7])==null?void 0:n[0]))throw"Mutation only works on post-BNC storages!";var f=((s=(i=e[8])==null?void 0:i[0])==null?void 0:s.data)&&db(e[8][0].data)>0||false;if(f)throw"Math only works with normal offsets";var o=0;var l=ab(e[7][0].data),c=0,h=[];var u=ab(e[4][0].data),d=0,v=[];for(var p=0;p1)console.error("The Numbers writer currently writes only the first table");var a=Ia(t["!ref"]);a.s.r=a.s.c=0;var n=false;if(a.e.c>9){n=true;a.e.c=9}if(a.e.r>49){n=true;a.e.r=49}if(n)console.error("The Numbers writer is currently limited to ".concat(Na(a)));var i=Aw(t,{range:a,header:1});var s=["~Sh33tJ5~"];i.forEach(function(e){return e.forEach(function(e){if(typeof e=="string")s.push(e)})});var f={};var o=[];var l=Ke.read(r.numbers,{type:"base64"});l.FileIndex.map(function(e,r){return[e,l.FullPaths[r]]}).forEach(function(e){var r=e[0],t=e[1];if(r.type!=2)return;if(!r.name.match(/\.iwa/))return;var a=r.content;var n=kb(a);var i=mb(n);i.forEach(function(e){o.push(e.id);f[e.id]={deps:[],location:t,type:db(e.messages[0].meta[1][0].data)}})});o.sort(function(e,r){return e-r});var c=o.filter(function(e){return e>1}).map(function(e){return[e,ub(e)]});l.FileIndex.map(function(e,r){return[e,l.FullPaths[r]]}).forEach(function(e){var r=e[0],t=e[1];if(!r.name.match(/\.iwa/))return;var a=mb(kb(r.content));a.forEach(function(e){e.messages.forEach(function(r){c.forEach(function(r){if(e.messages.some(function(e){return db(e.meta[1][0].data)!=11006&&sb(e.data,r[1])})){f[r[0]].deps.push(e.id)}})})})});function h(){for(var e=927262;e<2e6;++e)if(!f[e])return e;throw new Error("Too many messages")}var u=Ke.find(l,f[1].location);var d=mb(kb(u.content));var v;for(var p=0;p-1)return"sheet";if(qn.CS&&e==qn.CS)return"chart";if(qn.DS&&e==qn.DS)return"dialog";if(qn.MS&&e==qn.MS)return"macro";return e&&e.length?e:"sheet"}function Vb(e,r){if(!e)return 0;try{e=r.map(function a(r){if(!r.id)r.id=r.strRelID;return[r.name,e["!id"][r.id].Target,zb(e["!id"][r.id].Type)]})}catch(t){return null}return!e||e.length===0?null:e}function Gb(e,r,t,a,n,i,s,f,o,l,c,h){try{i[a]=Qn(Rr(e,t,true),r);var u=Or(e,r);var d;switch(f){case"sheet":d=pg(u,r,n,o,i[a],l,c,h);break;case"chart":d=gg(u,r,n,o,i[a],l,c,h);if(!d||!d["!drawel"])break;var v=Lr(d["!drawel"].Target,r);var p=Zn(v);var g=th(Rr(e,v,true),Qn(Rr(e,p,true),v));var m=Lr(g,v);var b=Zn(m);d=Pp(Rr(e,m,true),m,o,Qn(Rr(e,b,true),m),l,d);break;case"macro":d=mg(u,r,n,o,i[a],l,c,h);break;case"dialog":d=bg(u,r,n,o,i[a],l,c,h);break;default:throw new Error("Unrecognized sheet type "+f);}s[a]=d;var w=[];if(i&&i[a])rr(i[a]).forEach(function(t){var n="";if(i[a][t].Type==qn.CMNT){n=Lr(i[a][t].Target,r);var s=Ag(Or(e,n,true),n,o);if(!s||!s.length)return;ih(d,s,false)}if(i[a][t].Type==qn.TCMNT){n=Lr(i[a][t].Target,r);w=w.concat(oh(Or(e,n,true),o))}});if(w&&w.length)ih(d,w,true,o.people||[])}catch(k){if(o.WTF)throw k}}function jb(e){return e.charAt(0)=="/"?e.slice(1):e}function Xb(e,r){ze();r=r||{};Wb(r);if(_r(e,"META-INF/manifest.xml"))return Zm(e,r);if(_r(e,"objectdata.xml"))return Zm(e,r);if(_r(e,"Index/Document.iwa")){if(typeof Uint8Array=="undefined")throw new Error("NUMBERS file parsing requires Uint8Array support");if(typeof Lb!="undefined"){if(e.FileIndex)return Lb(e);var t=Ke.utils.cfb_new();Nr(e).forEach(function(r){Dr(t,r,Ir(e,r))});return Lb(t)}throw new Error("Unsupported NUMBERS file")}if(!_r(e,"[Content_Types].xml")){if(_r(e,"index.xml.gz"))throw new Error("Unsupported NUMBERS 08 file");if(_r(e,"index.xml"))throw new Error("Unsupported NUMBERS 09 file");throw new Error("Unsupported ZIP file")}var a=Nr(e);var n=Kn(Rr(e,"[Content_Types].xml"));var i=false;var s,f;if(n.workbooks.length===0){f="xl/workbook.xml";if(Or(e,f,true))n.workbooks.push(f)}if(n.workbooks.length===0){f="xl/workbook.bin";if(!Or(e,f,true))throw new Error("Could not find workbook");n.workbooks.push(f);i=true}if(n.workbooks[0].slice(-3)=="bin")i=true;var o={};var l={};if(!r.bookSheets&&!r.bookProps){xd=[];if(n.sst)try{xd=Tg(Or(e,jb(n.sst)),n.sst,r)}catch(c){if(r.WTF)throw c}if(r.cellStyles&&n.themes.length)o=kg(Rr(e,n.themes[0].replace(/^\//,""),true)||"",n.themes[0],r);if(n.style)l=wg(Or(e,jb(n.style)),n.style,o,r)}n.links.map(function(t){try{var a=Qn(Rr(e,Zn(jb(t))),t);return Cg(Or(e,jb(t)),a,t,r)}catch(n){}});var h=vg(Or(e,jb(n.workbooks[0])),n.workbooks[0],r);var u={},d="";if(n.coreprops.length){d=Or(e,jb(n.coreprops[0]),true);if(d)u=hi(d);if(n.extprops.length!==0){d=Or(e,jb(n.extprops[0]),true);if(d)mi(d,u,r)}}var v={};if(!r.bookSheets||r.bookProps){if(n.custprops.length!==0){d=Rr(e,jb(n.custprops[0]),true);if(d)v=ki(d,r)}}var p={};if(r.bookSheets||r.bookProps){if(h.Sheets)s=h.Sheets.map(function I(e){return e.name});else if(u.Worksheets&&u.SheetNames.length>0)s=u.SheetNames;if(r.bookProps){p.Props=u;p.Custprops=v}if(r.bookSheets&&typeof s!=="undefined")p.SheetNames=s;if(r.bookSheets?p.SheetNames:r.bookProps)return p}s={};var g={};if(r.bookDeps&&n.calcchain)g=Eg(Or(e,jb(n.calcchain)),n.calcchain,r);var m=0;var b={};var w,k;{var T=h.Sheets;u.Worksheets=T.length;u.SheetNames=[];for(var A=0;A!=T.length;++A){u.SheetNames[A]=T[A].name}}var E=i?"bin":"xml";var C=n.workbooks[0].lastIndexOf("/");var y=(n.workbooks[0].slice(0,C+1)+"_rels/"+n.workbooks[0].slice(C+1)+".rels").replace(/^\//,"");if(!_r(e,y))y="xl/_rels/workbook."+E+".rels";var S=Qn(Rr(e,y,true),y.replace(/_rels.*/,"s5s"));if((n.metadata||[]).length>=1){r.xlmeta=yg(Or(e,jb(n.metadata[0])),n.metadata[0],r)}if((n.people||[]).length>=1){r.people=ch(Or(e,jb(n.people[0])),r)}if(S)S=Vb(S,h.Sheets);var _=Or(e,"xl/worksheets/sheet.xml",true)?1:0;e:for(m=0;m!=u.Worksheets;++m){var x="sheet";if(S&&S[m]){w="xl/"+S[m][1].replace(/[\/]?xl\//,"");if(!_r(e,w))w=S[m][1];if(!_r(e,w))w=y.replace(/_rels\/.*$/,"")+S[m][1];x=S[m][2]}else{w="xl/worksheets/sheet"+(m+1-_)+"."+E;w=w.replace(/sheet0\./,"sheet.")}k=w.replace(/^(.*)(\/)([^\/]*)$/,"$1/_rels/$3.rels");if(r&&r.sheets!=null)switch(typeof r.sheets){case"number":if(m!=r.sheets)continue e;break;case"string":if(u.SheetNames[m].toLowerCase()!=r.sheets.toLowerCase())continue e;break;default:if(Array.isArray&&Array.isArray(r.sheets)){var O=false;for(var R=0;R!=r.sheets.length;++R){if(typeof r.sheets[R]=="number"&&r.sheets[R]==m)O=1;if(typeof r.sheets[R]=="string"&&r.sheets[R].toLowerCase()==u.SheetNames[m].toLowerCase())O=1}if(!O)continue e};}Gb(e,w,k,u.SheetNames[m],m,b,s,x,r,h,o,l)}p={Directory:n,Workbook:h,Props:u,Custprops:v,Deps:g,Sheets:s,SheetNames:u.SheetNames,Strings:xd,Styles:l,Themes:o,SSF:br(X)};if(r&&r.bookFiles){if(e.files){p.keys=a;p.files=e.files}else{p.keys=[];p.files={};e.FullPaths.forEach(function(r,t){r=r.replace(/^Root Entry[\/]/,"");p.keys.push(r);p.files[r]=e.FileIndex[t]})}}if(r&&r.bookVBA){if(n.vba.length>0)p.vbaraw=Or(e,jb(n.vba[0]),true);else if(n.defaults&&n.defaults.bin===bh)p.vbaraw=Or(e,"xl/vbaProject.bin",true)}return p}function $b(e,r){var t=r||{};var a="Workbook",n=Ke.find(e,a);try{a="/!DataSpaces/Version";n=Ke.find(e,a);if(!n||!n.content)throw new Error("ECMA-376 Encrypted file missing "+a);Ko(n.content);a="/!DataSpaces/DataSpaceMap";n=Ke.find(e,a);if(!n||!n.content)throw new Error("ECMA-376 Encrypted file missing "+a);var i=qo(n.content);if(i.length!==1||i[0].comps.length!==1||i[0].comps[0].t!==0||i[0].name!=="StrongEncryptionDataSpace"||i[0].comps[0].v!=="EncryptedPackage")throw new Error("ECMA-376 Encrypted file bad "+a);a="/!DataSpaces/DataSpaceInfo/StrongEncryptionDataSpace";n=Ke.find(e,a);if(!n||!n.content)throw new Error("ECMA-376 Encrypted file missing "+a);var s=Zo(n.content);if(s.length!=1||s[0]!="StrongEncryptionTransform")throw new Error("ECMA-376 Encrypted file bad "+a);a="/!DataSpaces/TransformInfo/StrongEncryptionTransform/!Primary";n=Ke.find(e,a);if(!n||!n.content)throw new Error("ECMA-376 Encrypted file missing "+a);el(n.content)}catch(f){}a="/EncryptionInfo";n=Ke.find(e,a);if(!n||!n.content)throw new Error("ECMA-376 Encrypted file missing "+a);var o=al(n.content);a="/EncryptedPackage";n=Ke.find(e,a);if(!n||!n.content)throw new Error("ECMA-376 Encrypted file missing "+a);if(o[0]==4&&typeof decrypt_agile!=="undefined")return decrypt_agile(o[1],n.content,t.password||"",t);if(o[0]==2&&typeof decrypt_std76!=="undefined")return decrypt_std76(o[1],n.content,t.password||"",t);throw new Error("File is password-protected")}function Yb(e,r){if(r.bookType=="ods")return tb(e,r);if(r.bookType=="numbers")return Ub(e,r);if(r.bookType=="xlsb")return Kb(e,r);return Jb(e,r)}function Kb(e,r){ah=1024;if(e&&!e.SSF){e.SSF=br(X)}if(e&&e.SSF){ze();He(e.SSF);r.revssf=nr(e.SSF);r.revssf[e.SSF[65535]]=0;r.ssf=e.SSF}r.rels={};r.wbrels={};r.Strings=[];r.Strings.Count=0;r.Strings.Unique=0;if(Rd)r.revStrings=new Map;else{r.revStrings={};r.revStrings.foo=[];delete r.revStrings.foo}var t=r.bookType=="xlsb"?"bin":"xml";var a=Th.indexOf(r.bookType)>-1;var n=Yn();Hb(r=r||{});var i=Fr();var s="",f=0;r.cellXfs=[];Fd(r.cellXfs,{},{revssf:{General:0}});if(!e.Props)e.Props={};s="docProps/core.xml";Dr(i,s,di(e.Props,r));n.coreprops.push(s);ri(r.rels,2,s,qn.CORE_PROPS);s="docProps/app.xml";if(e.Props&&e.Props.SheetNames){}else if(!e.Workbook||!e.Workbook.Sheets)e.Props.SheetNames=e.SheetNames;else{var o=[];for(var l=0;l0){s="docProps/custom.xml";Dr(i,s,Ti(e.Custprops,r));n.custprops.push(s);ri(r.rels,4,s,qn.CUST_PROPS)}for(f=1;f<=e.SheetNames.length;++f){var c={"!id":{}};var h=e.Sheets[e.SheetNames[f-1]];var u=(h||{})["!type"]||"sheet";switch(u){case"chart":;default:s="xl/worksheets/sheet"+f+"."+t;Dr(i,s,_g(f-1,s,r,e,c));n.sheets.push(s);ri(r.wbrels,-1,"worksheets/sheet"+f+"."+t,qn.WS[0]);}if(h){var d=h["!comments"];var v=false;var p="";if(d&&d.length>0){p="xl/comments"+f+"."+t;Dr(i,p,Ig(d,p,r));n.comments.push(p);ri(c,-1,"../comments"+f+"."+t,qn.CMNT);v=true}if(h["!legacy"]){if(v)Dr(i,"xl/drawings/vmlDrawing"+f+".vml",nh(f,h["!comments"]))}delete h["!comments"];delete h["!legacy"]}if(c["!id"].rId1)Dr(i,Zn(s),ei(c))}if(r.Strings!=null&&r.Strings.length>0){s="xl/sharedStrings."+t;Dr(i,s,Rg(r.Strings,s,r));n.strs.push(s);ri(r.wbrels,-1,"sharedStrings."+t,qn.SST)}s="xl/workbook."+t;Dr(i,s,Sg(e,s,r));n.workbooks.push(s);ri(r.rels,1,s,qn.WB);s="xl/theme/theme1.xml";Dr(i,s,Ic(e.Themes,r));n.themes.push(s);ri(r.wbrels,-1,"theme/theme1.xml",qn.THEME);s="xl/styles."+t;Dr(i,s,Og(e,s,r));n.styles.push(s);ri(r.wbrels,-1,"styles."+t,qn.STY);if(e.vbaraw&&a){s="xl/vbaProject.bin";Dr(i,s,e.vbaraw);n.vba.push(s);ri(r.wbrels,-1,"vbaProject.bin",qn.VBA)}s="xl/metadata."+t;Dr(i,s,Ng(s));n.metadata.push(s);ri(r.wbrels,-1,"metadata."+t,qn.XLMETA);Dr(i,"[Content_Types].xml",Jn(n,r));Dr(i,"_rels/.rels",ei(r.rels));Dr(i,"xl/_rels/workbook."+t+".rels",ei(r.wbrels));delete r.revssf;delete r.ssf;return i}function Jb(e,r){ah=1024;if(e&&!e.SSF){e.SSF=br(X)}if(e&&e.SSF){ze();He(e.SSF);r.revssf=nr(e.SSF);r.revssf[e.SSF[65535]]=0;r.ssf=e.SSF}r.rels={};r.wbrels={};r.Strings=[];r.Strings.Count=0;r.Strings.Unique=0;if(Rd)r.revStrings=new Map;else{r.revStrings={};r.revStrings.foo=[];delete r.revStrings.foo}var t="xml";var a=Th.indexOf(r.bookType)>-1;var n=Yn();Hb(r=r||{});var i=Fr();var s="",f=0;r.cellXfs=[];Fd(r.cellXfs,{},{revssf:{General:0}});if(!e.Props)e.Props={};s="docProps/core.xml";Dr(i,s,di(e.Props,r));n.coreprops.push(s);ri(r.rels,2,s,qn.CORE_PROPS);s="docProps/app.xml";if(e.Props&&e.Props.SheetNames){}else if(!e.Workbook||!e.Workbook.Sheets)e.Props.SheetNames=e.SheetNames;else{var o=[];for(var l=0;l0){s="docProps/custom.xml";Dr(i,s,Ti(e.Custprops,r));n.custprops.push(s);ri(r.rels,4,s,qn.CUST_PROPS)}var c=["SheetJ5"];r.tcid=0;for(f=1;f<=e.SheetNames.length;++f){var h={"!id":{}};var u=e.Sheets[e.SheetNames[f-1]];var d=(u||{})["!type"]||"sheet";switch(d){case"chart":;default:s="xl/worksheets/sheet"+f+"."+t;Dr(i,s,pv(f-1,r,e,h));n.sheets.push(s);ri(r.wbrels,-1,"worksheets/sheet"+f+"."+t,qn.WS[0]);}if(u){var v=u["!comments"];var p=false;var g="";if(v&&v.length>0){var m=false;v.forEach(function(e){e[1].forEach(function(e){if(e.T==true)m=true})});if(m){g="xl/threadedComments/threadedComment"+f+"."+t;Dr(i,g,lh(v,c,r));n.threadedcomments.push(g);ri(h,-1,"../threadedComments/threadedComment"+f+"."+t,qn.TCMNT)}g="xl/comments"+f+"."+t;Dr(i,g,fh(v,r));n.comments.push(g);ri(h,-1,"../comments"+f+"."+t,qn.CMNT);p=true}if(u["!legacy"]){if(p)Dr(i,"xl/drawings/vmlDrawing"+f+".vml",nh(f,u["!comments"]))}delete u["!comments"];delete u["!legacy"]}if(h["!id"].rId1)Dr(i,Zn(s),ei(h))}if(r.Strings!=null&&r.Strings.length>0){s="xl/sharedStrings."+t;Dr(i,s,Ho(r.Strings,r));n.strs.push(s);ri(r.wbrels,-1,"sharedStrings."+t,qn.SST)}s="xl/workbook."+t;Dr(i,s,rg(e,r));n.workbooks.push(s);ri(r.rels,1,s,qn.WB);s="xl/theme/theme1.xml";Dr(i,s,Ic(e.Themes,r));n.themes.push(s);ri(r.wbrels,-1,"theme/theme1.xml",qn.THEME);s="xl/styles."+t;Dr(i,s,$l(e,r));n.styles.push(s);ri(r.wbrels,-1,"styles."+t,qn.STY);if(e.vbaraw&&a){s="xl/vbaProject.bin";Dr(i,s,e.vbaraw);n.vba.push(s);ri(r.wbrels,-1,"vbaProject.bin",qn.VBA)}s="xl/metadata."+t;Dr(i,s,Jc());n.metadata.push(s);ri(r.wbrels,-1,"metadata."+t,qn.XLMETA);if(c.length>1){s="xl/persons/person.xml";Dr(i,s,hh(c,r));n.people.push(s);ri(r.wbrels,-1,"persons/person.xml",qn.PEOPLE)}Dr(i,"[Content_Types].xml",Jn(n,r));Dr(i,"_rels/.rels",ei(r.rels));Dr(i,"xl/_rels/workbook."+t+".rels",ei(r.wbrels));delete r.revssf;delete r.ssf;return i}function qb(e,r){var t="";switch((r||{}).type||"base64"){case"buffer":return[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7]];case"base64":t=k(e.slice(0,12));break;case"binary":t=e;break;case"array":return[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7]];default:throw new Error("Unrecognized type "+(r&&r.type||"undefined"));}return[t.charCodeAt(0),t.charCodeAt(1),t.charCodeAt(2),t.charCodeAt(3),t.charCodeAt(4),t.charCodeAt(5),t.charCodeAt(6),t.charCodeAt(7)]}function Zb(e,r){if(Ke.find(e,"EncryptedPackage"))return $b(e,r);return vm(e,r)}function Qb(e,r){var t,a=e;var n=r||{};if(!n.type)n.type=T&&Buffer.isBuffer(e)?"buffer":"base64";t=Pr(a,n);return Xb(t,n)}function ew(e,r){var t=0;e:while(t=2&&n[3]===0)return xo.to_workbook(a,t);if(n[2]===0&&(n[3]===8||n[3]===9))return xo.to_workbook(a,t)}break;case 3:;case 131:;case 139:;case 140:return Ao.to_workbook(a,t);case 123:if(n[1]===92&&n[2]===114&&n[3]===116)return gl.to_workbook(a,t);break;case 10:;case 13:;case 32:return rw(a,t);case 137:if(n[1]===80&&n[2]===78&&n[3]===71)throw new Error("PNG Image File is not a spreadsheet");break;}if(To.indexOf(n[0])>-1&&n[2]<=12&&n[3]<=31)return Ao.to_workbook(a,t);return nw(e,a,t,i)}function sw(e,r){var t=r||{};t.type="file";return iw(e,t)}function fw(e,r){switch(r.type){case"base64":;case"binary":break;case"buffer":;case"array":r.type="";break;case"file":return Qe(r.file,Ke.write(e,{type:T?"buffer":""}));case"string":throw new Error("'string' output type invalid for '"+r.bookType+"' files");default:throw new Error("Unrecognized type "+r.type);}return Ke.write(e,r)}function ow(e,r){var t=br(r||{});var a=Yb(e,t);return cw(a,t)}function lw(e,r){var t=br(r||{});var a=Jb(e,t);return cw(a,t)}function cw(e,r){var t={};var a=T?"nodebuffer":typeof Uint8Array!=="undefined"?"array":"string";if(r.compression)t.compression="DEFLATE";if(r.password)t.type=a;else switch(r.type){case"base64":t.type="base64";break;case"binary":t.type="string";break;case"string":throw new Error("'string' output type invalid for '"+r.bookType+"' files");case"buffer":;case"file":t.type=a;break;default:throw new Error("Unrecognized type "+r.type);}var n=e.FullPaths?Ke.write(e,{fileType:"zip",type:{nodebuffer:"buffer",string:"binary"}[t.type]||t.type,compression:!!r.compression}):e.generate(t);if(typeof Deno!=="undefined"){if(typeof n=="string"){if(r.type=="binary"||r.type=="base64")return n;n=new Uint8Array(S(n))}}if(r.password&&typeof encrypt_agile!=="undefined")return fw(encrypt_agile(n,r.password),r);if(r.type==="file")return Qe(r.file,n);return r.type=="string"?lt(n):n}function hw(e,r){var t=r||{};var a=pm(e,t);return fw(a,t)}function uw(e,r,t){if(!t)t="";var a=t+e;switch(r.type){case"base64":return w(ct(a));case"binary":return ct(a);case"string":return e;case"file":return Qe(r.file,a,"utf8");case"buffer":{if(T)return A(a,"utf8");else if(typeof TextEncoder!=="undefined")return(new TextEncoder).encode(a);else return uw(a,{type:"binary"}).split("").map(function(e){return e.charCodeAt(0)})};}throw new Error("Unrecognized type "+r.type)}function dw(e,r){switch(r.type){case"base64":return w(e);case"binary":return e;case"string":return e;case"file":return Qe(r.file,e,"binary");case"buffer":{if(T)return A(e,"binary");else return e.split("").map(function(e){return e.charCodeAt(0)})};}throw new Error("Unrecognized type "+r.type)}function vw(e,r){switch(r.type){case"string":;case"base64":;case"binary":var t="";for(var a=0;a0)n=0;var h=Ta(o.s.r);var u=[];var d=[];var v=0,p=0;var g=Array.isArray(e);var m=o.s.r,b=0;var w={};if(g&&!e[m])e[m]=[];var k=l.skipHidden&&e["!cols"]||[];var T=l.skipHidden&&e["!rows"]||[];for(b=o.s.c;b<=o.e.c;++b){if((k[b]||{}).hidden)continue;u[b]=ya(b);t=g?e[m][b]:e[u[b]+h];switch(a){case 1:i[b]=b-o.s.c;break;case 2:i[b]=u[b];break;case 3:i[b]=l.header[b-o.s.c];break;default:if(t==null)t={w:"__EMPTY",t:"s"};f=s=Pa(t,null,l);p=w[s]||0;if(!p)w[s]=1;else{do{f=s+"_"+p++}while(w[f]);w[s]=p;w[f]=1}i[b]=f;}}for(m=o.s.r+n;m<=o.e.r;++m){if((T[m]||{}).hidden)continue;var A=Tw(e,o,m,u,a,i,g,l);if(A.isempty===false||(a===1?l.blankrows!==false:!!l.blankrows))d[v++]=A.row}d.length=v;return d}var Ew=/"/g;function Cw(e,r,t,a,n,i,s,f){var o=true;var l=[],c="",h=Ta(t);for(var u=r.s.c;u<=r.e.c;++u){if(!a[u])continue;var d=f.dense?(e[t]||[])[u]:e[a[u]+h];if(d==null)c="";else if(d.v!=null){o=false;c=""+(f.rawNumbers&&d.t=="n"?d.v:Pa(d,null,f));for(var v=0,p=0;v!==c.length;++v)if((p=c.charCodeAt(v))===n||p===i||p===34||f.forceQuotes){c='"'+c.replace(Ew,'""')+'"';break}if(c=="ID")c='"ID"'}else if(d.f!=null&&!d.F){o=false;c="="+d.f;if(c.indexOf(",")>=0)c='"'+c.replace(Ew,'""')+'"'}else c="";l.push(c)}if(f.blankrows===false&&o)return null;return l.join(s)}function yw(e,r){var t=[];var a=r==null?{}:r;if(e==null||e["!ref"]==null)return"";var n=Da(e["!ref"]);var i=a.FS!==undefined?a.FS:",",s=i.charCodeAt(0);var f=a.RS!==undefined?a.RS:"\n",o=f.charCodeAt(0);var l=new RegExp((i=="|"?"\\|":i)+"+$");var c="",h=[];a.dense=Array.isArray(e);var u=a.skipHidden&&e["!cols"]||[];var d=a.skipHidden&&e["!rows"]||[];for(var v=n.s.c;v<=n.e.c;++v)if(!(u[v]||{}).hidden)h[v]=ya(v);var p=0;for(var g=n.s.r;g<=n.e.r;++g){if((d[g]||{}).hidden)continue;c=Cw(e,n,g,h,s,o,i,a);if(c==null){continue}if(a.strip)c=c.replace(l,"");if(c||a.blankrows!==false)t.push((p++?f:"")+c)}delete a.dense;return t.join("")}function Sw(e,r){if(!r)r={};r.FS="\t";r.RS="\n";var t=yw(e,r);if(typeof a=="undefined"||r.type=="string")return t;var n=a.utils.encode(1200,t,"str");return String.fromCharCode(255)+String.fromCharCode(254)+n}function _w(e){var r="",t,a="";if(e==null||e["!ref"]==null)return[];var n=Da(e["!ref"]),i="",s=[],f; var o=[];var l=Array.isArray(e);for(f=n.s.c;f<=n.e.c;++f)s[f]=ya(f);for(var c=n.s.r;c<=n.e.r;++c){i=Ta(c);for(f=n.s.c;f<=n.e.c;++f){r=s[f]+i;t=l?(e[c]||[])[f]:e[r];a="";if(t===undefined)continue;else if(t.F!=null){r=t.F;if(!t.f)continue;a=t.f;if(r.indexOf(":")==-1)r=r+":"+r}if(t.f!=null)a=t.f;else if(t.t=="z")continue;else if(t.t=="n"&&t.v!=null)a=""+t.v;else if(t.t=="b")a=t.v?"TRUE":"FALSE";else if(t.w!==undefined)a="'"+t.w;else if(t.v===undefined)continue;else if(t.t=="s")a="'"+t.v;else a=""+t.v;o[o.length]=r+"="+a}}return o}function xw(e,r,t){var a=t||{};var n=+!a.skipHeader;var i=e||{};var s=0,f=0;if(i&&a.origin!=null){if(typeof a.origin=="number")s=a.origin;else{var o=typeof a.origin=="string"?Oa(a.origin):a.origin;s=o.r;f=o.c}}var l;var c={s:{c:0,r:0},e:{c:f,r:s+r.length-1+n}};if(i["!ref"]){var h=Da(i["!ref"]);c.e.c=Math.max(c.e.c,h.e.c);c.e.r=Math.max(c.e.r,h.e.r);if(s==-1){s=h.e.r+1;c.e.r=s+r.length-1+n}}else{if(s==-1){s=0;c.e.r=r.length-1+n}}var u=a.header||[],d=0;r.forEach(function(e,r){rr(e).forEach(function(t){if((d=u.indexOf(t))==-1)u[d=u.length]=t;var o=e[t];var c="z";var h="";var v=Ra({c:f+d,r:s+r+n});l=Rw(i,v);if(o&&typeof o==="object"&&!(o instanceof Date)){i[v]=o}else{if(typeof o=="number")c="n";else if(typeof o=="boolean")c="b";else if(typeof o=="string")c="s";else if(o instanceof Date){c="d";if(!a.cellDates){c="n";o=fr(o)}h=a.dateNF||X[14]}else if(o===null&&a.nullError){c="e";o=0}if(!l)i[v]=l={t:c,v:o};else{l.t=c;l.v=o;delete l.w;delete l.R;if(h)l.z=h}if(h)l.z=h}})});c.e.c=Math.max(c.e.c,f+u.length-1);var v=Ta(s);if(n)for(d=0;d=0&&e.SheetNames.length>r)return r;throw new Error("Cannot find sheet # "+r)}else if(typeof r=="string"){var t=e.SheetNames.indexOf(r);if(t>-1)return t;throw new Error("Cannot find sheet name |"+r+"|")}else throw new Error("Cannot find sheet |"+r+"|")}function Nw(){return{SheetNames:[],Sheets:{}}}function Dw(e,r,t,a){var n=1;if(!t)for(;n<=65535;++n,t=undefined)if(e.SheetNames.indexOf(t="Sheet"+n)==-1)break;if(!t||e.SheetNames.length>=65535)throw new Error("Too many worksheets");if(a&&e.SheetNames.indexOf(t)>=0){var i=t.match(/(^.*?)(\d+)$/);n=i&&+i[2]||0;var s=i&&i[1]||t;for(++n;n<=65535;++n)if(e.SheetNames.indexOf(t=s+n)==-1)break}Jp(t);if(e.SheetNames.indexOf(t)>=0)throw new Error("Worksheet with name |"+t+"| already exists!");e.SheetNames.push(t);e.Sheets[t]=r;return t}function Fw(e,r,t){if(!e.Workbook)e.Workbook={};if(!e.Workbook.Sheets)e.Workbook.Sheets=[];var a=Iw(e,r);if(!e.Workbook.Sheets[a])e.Workbook.Sheets[a]={};switch(t){case 0:;case 1:;case 2:break;default:throw new Error("Bad sheet visibility setting "+t);}e.Workbook.Sheets[a].Hidden=t}function Pw(e,r){e.z=r;return e}function Lw(e,r,t){if(!r){delete e.l}else{e.l={Target:r};if(t)e.l.Tooltip=t}return e}function Mw(e,r,t){return Lw(e,"#"+r,t)}function Uw(e,r,t){if(!e.c)e.c=[];e.c.push({t:r,a:t||"SheetJS"})}function Bw(e,r,t,a){var n=typeof r!="string"?r:Da(r);var i=typeof r=="string"?r:Na(r);for(var s=n.s.r;s<=n.e.r;++s)for(var f=n.s.c;f<=n.e.c;++f){var o=Rw(e,s,f);o.t="n";o.F=i;delete o.v;if(s==n.s.r&&f==n.s.c){o.f=t;if(a)o.D=true}}return e}var Ww={encode_col:ya,encode_row:Ta,encode_cell:Ra,encode_range:Na,decode_col:Ca,decode_row:ka,split_cell:xa,decode_cell:Oa,decode_range:Ia,format_cell:Pa,sheet_add_aoa:Ma,sheet_add_json:xw,sheet_add_dom:Gm,aoa_to_sheet:Ua,json_to_sheet:Ow,table_to_sheet:jm,table_to_book:Xm,sheet_to_csv:yw,sheet_to_txt:Sw,sheet_to_json:Aw,sheet_to_html:Vm,sheet_to_formulae:_w,sheet_to_row_object_array:Aw,sheet_get_cell:Rw,book_new:Nw,book_append_sheet:Dw,book_set_sheet_visibility:Fw,cell_set_number_format:Pw,cell_set_hyperlink:Lw,cell_set_internal_link:Mw,cell_add_comment:Uw,sheet_set_array_formula:Bw,consts:{SHEET_VISIBLE:0,SHEET_HIDDEN:1,SHEET_VERY_HIDDEN:2}};var Hw;function zw(e){Hw=e}function Vw(e,r){var t=Hw();var a=r==null?{}:r;if(e==null||e["!ref"]==null){t.push(null);return t}var n=Da(e["!ref"]);var i=a.FS!==undefined?a.FS:",",s=i.charCodeAt(0);var f=a.RS!==undefined?a.RS:"\n",o=f.charCodeAt(0);var l=new RegExp((i=="|"?"\\|":i)+"+$");var c="",h=[];a.dense=Array.isArray(e);var u=a.skipHidden&&e["!cols"]||[];var d=a.skipHidden&&e["!rows"]||[];for(var v=n.s.c;v<=n.e.c;++v)if(!(u[v]||{}).hidden)h[v]=ya(v);var p=n.s.r;var g=false,m=0;t._read=function(){if(!g){g=true;return t.push("\ufeff")}while(p<=n.e.r){++p;if((d[p-1]||{}).hidden)continue;c=Cw(e,n,p-1,h,s,o,i,a);if(c!=null){if(a.strip)c=c.replace(l,"");if(c||a.blankrows!==false)return t.push((m++?f:"")+c)}}return t.push(null)};return t}function Gw(e,r){var t=Hw();var a=r||{};var n=a.header!=null?a.header:Bm;var i=a.footer!=null?a.footer:Wm;t.push(n);var s=Ia(e["!ref"]);a.dense=Array.isArray(e);t.push(zm(e,s,a));var f=s.s.r;var o=false;t._read=function(){if(f>s.e.r){if(!o){o=true;t.push(""+i)}return t.push(null)}while(f<=s.e.r){t.push(Um(e,s,f,a));++f;break}};return t}function jw(e,r){var t=Hw({objectMode:true});if(e==null||e["!ref"]==null){t.push(null);return t}var a={t:"n",v:0},n=0,i=1,s=[],f=0,o="";var l={s:{r:0,c:0},e:{r:0,c:0}};var c=r||{};var h=c.range!=null?c.range:e["!ref"];if(c.header===1)n=1;else if(c.header==="A")n=2;else if(Array.isArray(c.header))n=3;switch(typeof h){case"string":l=Da(h);break;case"number":l=Da(e["!ref"]);l.s.r=h;break;default:l=h;}if(n>0)i=0;var u=Ta(l.s.r);var d=[];var v=0;var p=Array.isArray(e);var g=l.s.r,m=0;var b={};if(p&&!e[g])e[g]=[];var w=c.skipHidden&&e["!cols"]||[];var k=c.skipHidden&&e["!rows"]||[];for(m=l.s.c;m<=l.e.c;++m){if((w[m]||{}).hidden)continue;d[m]=ya(m);a=p?e[g][m]:e[d[m]+u];switch(n){case 1:s[m]=m-l.s.c;break;case 2:s[m]=d[m];break;case 3:s[m]=c.header[m-l.s.c];break;default:if(a==null)a={w:"__EMPTY",t:"s"};o=f=Pa(a,null,c);v=b[f]||0;if(!v)b[f]=1;else{do{o=f+"_"+v++}while(b[o]);b[f]=v;b[o]=1}s[m]=o;}}g=l.s.r+i;t._read=function(){while(g<=l.e.r){if((k[g-1]||{}).hidden)continue;var r=Tw(e,l,g,d,n,s,p,c);++g;if(r.isempty===false||(n===1?c.blankrows!==false:!!c.blankrows)){t.push(r.row);return}}return t.push(null)};return t}var Xw={to_json:jw,to_html:Gw,to_csv:Vw,set_readable:zw};if(typeof vm!=="undefined")e.parse_xlscfb=vm;e.parse_zip=Xb;e.read=iw;e.readFile=sw;e.readFileSync=sw;e.write=gw;e.writeFile=bw;e.writeFileSync=bw;e.writeFileAsync=kw;e.utils=Ww;e.writeXLSX=pw;e.writeFileXLSX=ww;e.SSF=Ve;if(typeof Xw!=="undefined")e.stream=Xw;if(typeof Ke!=="undefined")e.CFB=Ke;if(typeof require!=="undefined"){var $w=undefined;if(($w||{}).Readable)zw($w.Readable)}}if(typeof exports!=="undefined")make_xlsx_lib(exports);else if(typeof module!=="undefined"&&module.exports)make_xlsx_lib(module.exports);else if(typeof define==="function"&&define.amd)define("xlsx",function(){if(!XLSX.version)make_xlsx_lib(XLSX);return XLSX});else make_xlsx_lib(XLSX);if(typeof window!=="undefined"&&!window.XLSX)try{window.XLSX=XLSX}catch(e){} ",l=r.open();return null!==l&&l.document.write(c),l}throw new Error("The option pdfobjectnewwindow just works in a browser-environment.");case"pdfjsnewwindow":if("[object Window]"===Object.prototype.toString.call(r)){var h='',g=r.open();if(null!==g&&(g.document.write(p),g.document.title=e.filename),g||"undefined"==typeof safari)return g;break;case"datauri":case"dataurl":return r.document.location.href=this.output("datauristring",e);default:return null}})),Ge=function(t){return!0===Array.isArray(Ut)&&Ut.indexOf(t)>-1};switch(o){case"pt":_t=1;break;case"mm":_t=72/25.4;break;case"cm":_t=72/2.54;break;case"in":_t=72;break;case"px":_t=1==Ge("px_scaling")?.75:96/72;break;case"pc":case"em":_t=12;break;case"ex":_t=6;break;default:if("number"!=typeof o)throw new Error("Invalid unit: "+o);_t=o}var Ye=null;K(),Y();var Je=function(t){return null!==m?Ye.encryptor(t,0):function(t){return t}},Xe=y.__private__.getPageInfo=y.getPageInfo=function(t){if(isNaN(t)||t%1!=0)throw new Error("Invalid argument passed to jsPDF.getPageInfo");return{objId:Rt[t].objId,pageNumber:t,pageContext:Rt[t]}},Ke=y.__private__.getPageInfoByObjId=function(t){if(isNaN(t)||t%1!=0)throw new Error("Invalid argument passed to jsPDF.getPageInfoByObjId");for(var e in Rt)if(Rt[e].objId===t)break;return Xe(e)},Ze=y.__private__.getCurrentPageInfo=y.getCurrentPageInfo=function(){return{objId:Rt[$].objId,pageNumber:$,pageContext:Rt[$]}};y.addPage=function(){return Oe.apply(this,arguments),this},y.setPage=function(){return Me.apply(this,arguments),lt.call(this,ot[$]),this},y.insertPage=function(t){return this.addPage(),this.movePage($,t),this},y.movePage=function(t,e){var r,n;if(t>e){r=ot[t],n=Rt[t];for(var i=t;i>e;i--)ot[i]=ot[i-1],Rt[i]=Rt[i-1];ot[e]=r,Rt[e]=n,this.setPage(e)}else if(t0&&("string"==typeof t?t=g.splitTextToSize(t,h):"[object Array]"===Object.prototype.toString.call(t)&&(t=t.reduce((function(t,e){return t.concat(g.splitTextToSize(e,h))}),[]))),o={text:t,x:r,y:n,options:i,mutex:{pdfEscape:Ce,activeFontKey:St,fonts:It,activeFontSize:gt}},Tt.publish("preProcessText",o),t=o.text,c=(i=o.options).angle,p instanceof Vt==!1&&c&&"number"==typeof c){c*=Math.PI/180,0===i.rotationDirection&&(c=-c),S===x.ADVANCED&&(c=-c);var B=Math.cos(c),M=Math.sin(c);p=new Vt(B,M,-M,B,0,0)}else c&&c instanceof Vt&&(p=c);S!==x.ADVANCED||p||(p=Yt),void 0!==(l=i.charSpace||_r)&&(v+=E(U(l))+" Tc\n",this.setCharSpace(this.getCharSpace()||0)),void 0!==(d=i.horizontalScale)&&(v+=E(100*d)+" Tz\n");i.lang;var D=-1,R=void 0!==i.renderingMode?i.renderingMode:i.stroke,T=g.internal.getCurrentPageInfo().pageContext;switch(R){case 0:case!1:case"fill":D=0;break;case 1:case!0:case"stroke":D=1;break;case 2:case"fillThenStroke":D=2;break;case 3:case"invisible":D=3;break;case 4:case"fillAndAddForClipping":D=4;break;case 5:case"strokeAndAddPathForClipping":D=5;break;case 6:case"fillThenStrokeAndAddToPathForClipping":D=6;break;case 7:case"addToPathForClipping":D=7}var z=void 0!==T.usedRenderingMode?T.usedRenderingMode:-1;-1!==D?v+=D+" Tr\n":-1!==z&&(v+="0 Tr\n"),-1!==D&&(T.usedRenderingMode=D),u=i.align||"left";var H,W=gt*w,V=g.internal.pageSize.getWidth(),G=It[St];l=i.charSpace||_r,h=i.maxWidth||0,f=Object.assign({autoencode:!0,noBOM:!0},i.flags);var Y=[];if("[object Array]"===Object.prototype.toString.call(t)){var J;s=A(t),"left"!==u&&(H=s.map((function(t){return g.getStringUnitWidth(t,{font:G,charSpace:l,fontSize:gt,doKerning:!1})*gt/N})));var X,K=0;if("right"===u){r-=H[0],t=[],C=s.length;for(var Z=0;Z":")"),nt=parseFloat(s[ft][1]),it=parseFloat(s[ft][2]);break;case ot:at=(y?"<":"(")+s[ft]+(y?">":")"),nt=br(r),it=yr(n)}void 0!==Y&&void 0!==Y[ft]&&(ut=Y[ft]+" Tw\n"),0===ft?t.push(ut+lt(nt,it,p)+at):ct===ot?t.push(ut+at):ct===st&&t.push(ut+lt(nt,it,p)+at)}t=ct===ot?t.join(" Tj\nT* "):t.join(" Tj\n"),t+=" Tj\n";var dt="BT\n/";return dt+=St+" "+gt+" Tf\n",dt+=E(gt*w)+" TL\n",dt+=xr+"\n",dt+=v,dt+=t,ht(dt+="ET"),b[St]=!0,g};var $e=y.__private__.clip=y.clip=function(t){return ht("evenodd"===t?"W*":"W"),this};y.clipEvenOdd=function(){return $e("evenodd")},y.__private__.discardPath=y.discardPath=function(){return ht("n"),this};var Qe=y.__private__.isValidStyle=function(t){var e=!1;return-1!==[void 0,null,"S","D","F","DF","FD","f","f*","B","B*","n"].indexOf(t)&&(e=!0),e};y.__private__.setDefaultPathOperation=y.setDefaultPathOperation=function(t){return Qe(t)&&(g=t),this};var tr=y.__private__.getStyle=y.getStyle=function(t){var e=g;switch(t){case"D":case"S":e="S";break;case"F":e="f";break;case"FD":case"DF":e="B";break;case"f":case"f*":case"B":case"B*":e=t}return e},er=y.close=function(){return ht("h"),this};y.stroke=function(){return ht("S"),this},y.fill=function(t){return rr("f",t),this},y.fillEvenOdd=function(t){return rr("f*",t),this},y.fillStroke=function(t){return rr("B",t),this},y.fillStrokeEvenOdd=function(t){return rr("B*",t),this};var rr=function(t,r){"object"===e(r)?ar(r,t):ht(t)},nr=function(t){null===t||S===x.ADVANCED&&void 0===t||(t=tr(t),ht(t))};function ir(t,e,r,n,i){var a=new B(e||this.boundingBox,r||this.xStep,n||this.yStep,this.gState,i||this.matrix);a.stream=this.stream;var o=t+"$$"+this.cloneIndex+++"$$";return Jt(o,a),a}var ar=function(t,e){var r=Bt[t.key],n=Ot[r];if(n instanceof O)ht("q"),ht(or(e)),n.gState&&y.setGState(n.gState),ht(t.matrix.toString()+" cm"),ht("/"+r+" sh"),ht("Q");else if(n instanceof B){var i=new Vt(1,0,0,-1,0,Rr());t.matrix&&(i=i.multiply(t.matrix||Yt),r=ir.call(n,t.key,t.boundingBox,t.xStep,t.yStep,i).id),ht("q"),ht("/Pattern cs"),ht("/"+r+" scn"),n.gState&&y.setGState(n.gState),ht(e),ht("Q")}},or=function(t){switch(t){case"f":case"F":return"W n";case"f*":return"W* n";case"B":return"W S";case"B*":return"W* S";case"S":return"W S";case"n":return"W n"}},sr=y.moveTo=function(t,e){return ht(E(U(t))+" "+E(H(e))+" m"),this},cr=y.lineTo=function(t,e){return ht(E(U(t))+" "+E(H(e))+" l"),this},ur=y.curveTo=function(t,e,r,n,i,a){return ht([E(U(t)),E(H(e)),E(U(r)),E(H(n)),E(U(i)),E(H(a)),"c"].join(" ")),this};y.__private__.line=y.line=function(t,e,r,n,i){if(isNaN(t)||isNaN(e)||isNaN(r)||isNaN(n)||!Qe(i))throw new Error("Invalid arguments passed to jsPDF.line");return S===x.COMPAT?this.lines([[r-t,n-e]],t,e,[1,1],i||"S"):this.lines([[r-t,n-e]],t,e,[1,1]).stroke()},y.__private__.lines=y.lines=function(t,e,r,n,i,a){var o,s,c,u,l,h,f,d,p,g,m,v;if("number"==typeof t&&(v=r,r=e,e=t,t=v),n=n||[1,1],a=a||!1,isNaN(e)||isNaN(r)||!Array.isArray(t)||!Array.isArray(n)||!Qe(i)||"boolean"!=typeof a)throw new Error("Invalid arguments passed to jsPDF.lines");for(sr(e,r),o=n[0],s=n[1],u=t.length,g=e,m=r,c=0;c>0&255,t>>8&255,t>>16&255,t>>24&255)},k.prototype.toHexString=function(t){return t.split("").map((function(t){return("0"+(255&t.charCodeAt(0)).toString(16)).slice(-2)})).join("")},k.prototype.hexToBytes=function(t){for(var e=[],r=0;r>8&255,t>>16&255,255&e,e>>8&255)).substr(0,10);return function(t){return _(r,t)}},C.prototype.equals=function(t){var r,n="id,objectNumber,equals";if(!t||e(t)!==e(this))return!1;var i=0;for(r in this)if(!(n.indexOf(r)>=0)){if(this.hasOwnProperty(r)&&!t.hasOwnProperty(r))return!1;if(this[r]!==t[r])return!1;i++}for(r in t)t.hasOwnProperty(r)&&n.indexOf(r)<0&&i--;return 0===i},M.API={events:[]},M.version="2.5.1";var E=M.API,q=1,D=function(t){return t.replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")},R=function(t){return t.replace(/\\\\/g,"\\").replace(/\\\(/g,"(").replace(/\\\)/g,")")},T=function(t){return t.toFixed(2)},U=function(t){return t.toFixed(5)};E.__acroform__={};var z=function(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t},H=function(t){return t*q},W=function(t){var e=new ct,r=Lt.internal.getHeight(t)||0,n=Lt.internal.getWidth(t)||0;return e.BBox=[0,0,Number(T(n)),Number(T(r))],e},V=E.__acroform__.setBit=function(t,e){if(t=t||0,e=e||0,isNaN(t)||isNaN(e))throw new Error("Invalid arguments passed to jsPDF.API.__acroform__.setBit");return t|=1<0;){e="",a--;var u,l,h=tt("3",t,a).height,f=t.multiline?o-a:(o-h)/2,d=f+=2,p=0,g=0,m=0;if(a<=0){e="(...) Tj\n",e+="% Width of Text: "+tt(e,t,a=12).width+", FieldWidth:"+s+"\n";break}for(var v="",b=0,y=0;yo)continue t;v+=i[y][m],w=!0,g=y,y--}else{v=" "==(v+=i[y][m]+" ").substr(v.length-1)?v.substr(0,v.length-1):v;var N=parseInt(y),L=c(N,v,a),A=y>=i.length-1;if(L&&!A){v+=" ",m=0;continue}if(L||A){if(A)g=N;else if(t.multiline&&(h+2)*(b+2)+2>o)continue t}else{if(!t.multiline)continue t;if((h+2)*(b+2)+2>o)continue t;g=N}}for(var x="",S=p;S<=g;S++){var _=i[S];if(t.multiline){if(S===g){x+=_[m]+" ",m=(m+1)%_.length;continue}if(S===p){x+=_[_.length-1]+" ";continue}}x+=_[0]+" "}switch(x=" "==x.substr(x.length-1)?x.substr(0,x.length-1):x,l=tt(x,t,a).width,t.textAlign){case"right":u=s-l-2;break;case"center":u=(s-l)/2;break;case"left":default:u=2}e+=T(u)+" "+T(d)+" Td\n",e+="("+D(x)+") Tj\n",e+=-T(u)+" 0 Td\n",d=-(a+2),l=0,p=w?g:g+1,b++,v=""}else;break}return n.text=e,n.fontSize=a,n},tt=function(t,e,r){var n=e.scope.internal.getFont(e.fontName,e.fontStyle),i=e.scope.getStringUnitWidth(t,{font:n,fontSize:parseFloat(r),charSpace:0})*parseFloat(r);return{height:e.scope.getStringUnitWidth("3",{font:n,fontSize:parseFloat(r),charSpace:0})*parseFloat(r)*1.5,width:i}},et={fields:[],xForms:[],acroFormDictionaryRoot:null,printedOut:!1,internal:null,isInitialized:!1},rt=function(t,e){var r={type:"reference",object:t};void 0===e.internal.getPageInfo(t.page).pageContext.annotations.find((function(t){return t.type===r.type&&t.object===r.object}))&&e.internal.getPageInfo(t.page).pageContext.annotations.push(r)},nt=function(t,r){for(var n in t)if(t.hasOwnProperty(n)){var i=n,a=t[n];r.internal.newObjectDeferredBegin(a.objId,!0),"object"===e(a)&&"function"==typeof a.putStream&&a.putStream(),delete t[i]}},it=function(t,r){if(r.scope=t,void 0!==t.internal&&(void 0===t.internal.acroformPlugin||!1===t.internal.acroformPlugin.isInitialized)){if(lt.FieldNum=0,t.internal.acroformPlugin=JSON.parse(JSON.stringify(et)),t.internal.acroformPlugin.acroFormDictionaryRoot)throw new Error("Exception while creating AcroformDictionary");q=t.internal.scaleFactor,t.internal.acroformPlugin.acroFormDictionaryRoot=new ut,t.internal.acroformPlugin.acroFormDictionaryRoot.scope=t,t.internal.acroformPlugin.acroFormDictionaryRoot._eventID=t.internal.events.subscribe("postPutResources",(function(){!function(t){t.internal.events.unsubscribe(t.internal.acroformPlugin.acroFormDictionaryRoot._eventID),delete t.internal.acroformPlugin.acroFormDictionaryRoot._eventID,t.internal.acroformPlugin.printedOut=!0}(t)})),t.internal.events.subscribe("buildDocument",(function(){!function(t){t.internal.acroformPlugin.acroFormDictionaryRoot.objId=void 0;var e=t.internal.acroformPlugin.acroFormDictionaryRoot.Fields;for(var r in e)if(e.hasOwnProperty(r)){var n=e[r];n.objId=void 0,n.hasAnnotation&&rt(n,t)}}(t)})),t.internal.events.subscribe("putCatalog",(function(){!function(t){if(void 0===t.internal.acroformPlugin.acroFormDictionaryRoot)throw new Error("putCatalogCallback: Root missing.");t.internal.write("/AcroForm "+t.internal.acroformPlugin.acroFormDictionaryRoot.objId+" 0 R")}(t)})),t.internal.events.subscribe("postPutPages",(function(r){!function(t,r){var n=!t;for(var i in t||(r.internal.newObjectDeferredBegin(r.internal.acroformPlugin.acroFormDictionaryRoot.objId,!0),r.internal.acroformPlugin.acroFormDictionaryRoot.putStream()),t=t||r.internal.acroformPlugin.acroFormDictionaryRoot.Kids)if(t.hasOwnProperty(i)){var a=t[i],o=[],s=a.Rect;if(a.Rect&&(a.Rect=Z(a.Rect,r)),r.internal.newObjectDeferredBegin(a.objId,!0),a.DA=Lt.createDefaultAppearanceStream(a),"object"===e(a)&&"function"==typeof a.getKeyValueListForStream&&(o=a.getKeyValueListForStream()),a.Rect=s,a.hasAppearanceStream&&!a.appearanceStreamContent){var c=$(a);o.push({key:"AP",value:"<>"}),r.internal.acroformPlugin.xForms.push(c)}if(a.appearanceStreamContent){var u="";for(var l in a.appearanceStreamContent)if(a.appearanceStreamContent.hasOwnProperty(l)){var h=a.appearanceStreamContent[l];if(u+="/"+l+" ",u+="<<",Object.keys(h).length>=1||Array.isArray(h)){for(var i in h)if(h.hasOwnProperty(i)){var f=h[i];"function"==typeof f&&(f=f.call(r,a)),u+="/"+i+" "+f+" ",r.internal.acroformPlugin.xForms.indexOf(f)>=0||r.internal.acroformPlugin.xForms.push(f)}}else"function"==typeof(f=h)&&(f=f.call(r,a)),u+="/"+i+" "+f,r.internal.acroformPlugin.xForms.indexOf(f)>=0||r.internal.acroformPlugin.xForms.push(f);u+=">>"}o.push({key:"AP",value:"<<\n"+u+">>"})}r.internal.putStream({additionalKeyValues:o,objectId:a.objId}),r.internal.out("endobj")}n&&nt(r.internal.acroformPlugin.xForms,r)}(r,t)})),t.internal.acroformPlugin.isInitialized=!0}},at=E.__acroform__.arrayToPdfArray=function(t,r,n){var i=function(t){return t};if(Array.isArray(t)){for(var a="[",o=0;o0?e:void 0}}),Object.defineProperty(this,"Fields",{enumerable:!1,configurable:!1,get:function(){return e}}),Object.defineProperty(this,"DA",{enumerable:!1,configurable:!1,get:function(){if(t){var e=function(t){return t};return this.scope&&(e=this.scope.internal.getEncryptor(this.objId)),"("+D(e(t))+")"}},set:function(e){t=e}})};z(ut,st);var lt=function t(){st.call(this);var e=4;Object.defineProperty(this,"F",{enumerable:!1,configurable:!1,get:function(){return e},set:function(t){if(isNaN(t))throw new Error('Invalid value "'+t+'" for attribute F supplied.');e=t}}),Object.defineProperty(this,"showWhenPrinted",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(e,3))},set:function(t){!0===Boolean(t)?this.F=X(e,3):this.F=K(e,3)}});var r=0;Object.defineProperty(this,"Ff",{enumerable:!1,configurable:!1,get:function(){return r},set:function(t){if(isNaN(t))throw new Error('Invalid value "'+t+'" for attribute Ff supplied.');r=t}});var n=[];Object.defineProperty(this,"Rect",{enumerable:!1,configurable:!1,get:function(){if(0!==n.length)return n},set:function(t){n=void 0!==t?t:[]}}),Object.defineProperty(this,"x",{enumerable:!0,configurable:!0,get:function(){return!n||isNaN(n[0])?0:n[0]},set:function(t){n[0]=t}}),Object.defineProperty(this,"y",{enumerable:!0,configurable:!0,get:function(){return!n||isNaN(n[1])?0:n[1]},set:function(t){n[1]=t}}),Object.defineProperty(this,"width",{enumerable:!0,configurable:!0,get:function(){return!n||isNaN(n[2])?0:n[2]},set:function(t){n[2]=t}}),Object.defineProperty(this,"height",{enumerable:!0,configurable:!0,get:function(){return!n||isNaN(n[3])?0:n[3]},set:function(t){n[3]=t}});var i="";Object.defineProperty(this,"FT",{enumerable:!0,configurable:!1,get:function(){return i},set:function(t){switch(t){case"/Btn":case"/Tx":case"/Ch":case"/Sig":i=t;break;default:throw new Error('Invalid value "'+t+'" for attribute FT supplied.')}}});var a=null;Object.defineProperty(this,"T",{enumerable:!0,configurable:!1,get:function(){if(!a||a.length<1){if(this instanceof bt)return;a="FieldObject"+t.FieldNum++}var e=function(t){return t};return this.scope&&(e=this.scope.internal.getEncryptor(this.objId)),"("+D(e(a))+")"},set:function(t){a=t.toString()}}),Object.defineProperty(this,"fieldName",{configurable:!0,enumerable:!0,get:function(){return a},set:function(t){a=t}});var o="helvetica";Object.defineProperty(this,"fontName",{enumerable:!0,configurable:!0,get:function(){return o},set:function(t){o=t}});var s="normal";Object.defineProperty(this,"fontStyle",{enumerable:!0,configurable:!0,get:function(){return s},set:function(t){s=t}});var c=0;Object.defineProperty(this,"fontSize",{enumerable:!0,configurable:!0,get:function(){return c},set:function(t){c=t}});var u=void 0;Object.defineProperty(this,"maxFontSize",{enumerable:!0,configurable:!0,get:function(){return void 0===u?50/q:u},set:function(t){u=t}});var l="black";Object.defineProperty(this,"color",{enumerable:!0,configurable:!0,get:function(){return l},set:function(t){l=t}});var h="/F1 0 Tf 0 g";Object.defineProperty(this,"DA",{enumerable:!0,configurable:!1,get:function(){if(!(!h||this instanceof bt||this instanceof wt))return ot(h,this.objId,this.scope)},set:function(t){t=t.toString(),h=t}});var f=null;Object.defineProperty(this,"DV",{enumerable:!1,configurable:!1,get:function(){if(f)return this instanceof gt==!1?ot(f,this.objId,this.scope):f},set:function(t){t=t.toString(),f=this instanceof gt==!1?"("===t.substr(0,1)?R(t.substr(1,t.length-2)):R(t):t}}),Object.defineProperty(this,"defaultValue",{enumerable:!0,configurable:!0,get:function(){return this instanceof gt==!0?R(f.substr(1,f.length-1)):f},set:function(t){t=t.toString(),f=this instanceof gt==!0?"/"+t:t}});var d=null;Object.defineProperty(this,"_V",{enumerable:!1,configurable:!1,get:function(){if(d)return d},set:function(t){this.V=t}}),Object.defineProperty(this,"V",{enumerable:!1,configurable:!1,get:function(){if(d)return this instanceof gt==!1?ot(d,this.objId,this.scope):d},set:function(t){t=t.toString(),d=this instanceof gt==!1?"("===t.substr(0,1)?R(t.substr(1,t.length-2)):R(t):t}}),Object.defineProperty(this,"value",{enumerable:!0,configurable:!0,get:function(){return this instanceof gt==!0?R(d.substr(1,d.length-1)):d},set:function(t){t=t.toString(),d=this instanceof gt==!0?"/"+t:t}}),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 p,g=!1;Object.defineProperty(this,"hasAppearanceStream",{enumerable:!0,configurable:!0,get:function(){return g},set:function(t){t=Boolean(t),g=t}}),Object.defineProperty(this,"page",{enumerable:!0,configurable:!0,get:function(){if(p)return p},set:function(t){p=t}}),Object.defineProperty(this,"readOnly",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,1))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,1):this.Ff=K(this.Ff,1)}}),Object.defineProperty(this,"required",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,2))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,2):this.Ff=K(this.Ff,2)}}),Object.defineProperty(this,"noExport",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,3))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,3):this.Ff=K(this.Ff,3)}});var m=null;Object.defineProperty(this,"Q",{enumerable:!0,configurable:!1,get:function(){if(null!==m)return m},set:function(t){if(-1===[0,1,2].indexOf(t))throw new Error('Invalid value "'+t+'" for attribute Q supplied.');m=t}}),Object.defineProperty(this,"textAlign",{get:function(){var t;switch(m){case 0:default:t="left";break;case 1:t="center";break;case 2:t="right"}return t},configurable:!0,enumerable:!0,set:function(t){switch(t){case"right":case 2:m=2;break;case"center":case 1:m=1;break;case"left":case 0:default:m=0}}})};z(lt,st);var ht=function(){lt.call(this),this.FT="/Ch",this.V="()",this.fontName="zapfdingbats";var t=0;Object.defineProperty(this,"TI",{enumerable:!0,configurable:!1,get:function(){return t},set:function(e){t=e}}),Object.defineProperty(this,"topIndex",{enumerable:!0,configurable:!0,get:function(){return t},set:function(e){t=e}});var e=[];Object.defineProperty(this,"Opt",{enumerable:!0,configurable:!1,get:function(){return at(e,this.objId,this.scope)},set:function(t){var r,n;n=[],"string"==typeof(r=t)&&(n=function(t,e,r){r||(r=1);for(var n,i=[];n=e.exec(t);)i.push(n[r]);return i}(r,/\((.*?)\)/g)),e=n}}),this.getOptions=function(){return e},this.setOptions=function(t){e=t,this.sort&&e.sort()},this.addOption=function(t){t=(t=t||"").toString(),e.push(t),this.sort&&e.sort()},this.removeOption=function(t,r){for(r=r||!1,t=(t=t||"").toString();-1!==e.indexOf(t)&&(e.splice(e.indexOf(t),1),!1!==r););},Object.defineProperty(this,"combo",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,18))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,18):this.Ff=K(this.Ff,18)}}),Object.defineProperty(this,"edit",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,19))},set:function(t){!0===this.combo&&(!0===Boolean(t)?this.Ff=X(this.Ff,19):this.Ff=K(this.Ff,19))}}),Object.defineProperty(this,"sort",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,20))},set:function(t){!0===Boolean(t)?(this.Ff=X(this.Ff,20),e.sort()):this.Ff=K(this.Ff,20)}}),Object.defineProperty(this,"multiSelect",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,22))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,22):this.Ff=K(this.Ff,22)}}),Object.defineProperty(this,"doNotSpellCheck",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,23))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,23):this.Ff=K(this.Ff,23)}}),Object.defineProperty(this,"commitOnSelChange",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,27))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,27):this.Ff=K(this.Ff,27)}}),this.hasAppearanceStream=!1};z(ht,lt);var ft=function(){ht.call(this),this.fontName="helvetica",this.combo=!1};z(ft,ht);var dt=function(){ft.call(this),this.combo=!0};z(dt,ft);var pt=function(){dt.call(this),this.edit=!0};z(pt,dt);var gt=function(){lt.call(this),this.FT="/Btn",Object.defineProperty(this,"noToggleToOff",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,15))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,15):this.Ff=K(this.Ff,15)}}),Object.defineProperty(this,"radio",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,16))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,16):this.Ff=K(this.Ff,16)}}),Object.defineProperty(this,"pushButton",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,17))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,17):this.Ff=K(this.Ff,17)}}),Object.defineProperty(this,"radioIsUnison",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,26))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,26):this.Ff=K(this.Ff,26)}});var t,r={};Object.defineProperty(this,"MK",{enumerable:!1,configurable:!1,get:function(){var t=function(t){return t};if(this.scope&&(t=this.scope.internal.getEncryptor(this.objId)),0!==Object.keys(r).length){var e,n=[];for(e in n.push("<<"),r)n.push("/"+e+" ("+D(t(r[e]))+")");return n.push(">>"),n.join("\n")}},set:function(t){"object"===e(t)&&(r=t)}}),Object.defineProperty(this,"caption",{enumerable:!0,configurable:!0,get:function(){return r.CA||""},set:function(t){"string"==typeof t&&(r.CA=t)}}),Object.defineProperty(this,"AS",{enumerable:!1,configurable:!1,get:function(){return t},set:function(e){t=e}}),Object.defineProperty(this,"appearanceState",{enumerable:!0,configurable:!0,get:function(){return t.substr(1,t.length-1)},set:function(e){t="/"+e}})};z(gt,lt);var mt=function(){gt.call(this),this.pushButton=!0};z(mt,gt);var vt=function(){gt.call(this),this.radio=!0,this.pushButton=!1;var t=[];Object.defineProperty(this,"Kids",{enumerable:!0,configurable:!1,get:function(){return t},set:function(e){t=void 0!==e?e:[]}})};z(vt,gt);var bt=function(){var t,r;lt.call(this),Object.defineProperty(this,"Parent",{enumerable:!1,configurable:!1,get:function(){return t},set:function(e){t=e}}),Object.defineProperty(this,"optionName",{enumerable:!1,configurable:!0,get:function(){return r},set:function(t){r=t}});var n,i={};Object.defineProperty(this,"MK",{enumerable:!1,configurable:!1,get:function(){var t=function(t){return t};this.scope&&(t=this.scope.internal.getEncryptor(this.objId));var e,r=[];for(e in r.push("<<"),i)r.push("/"+e+" ("+D(t(i[e]))+")");return r.push(">>"),r.join("\n")},set:function(t){"object"===e(t)&&(i=t)}}),Object.defineProperty(this,"caption",{enumerable:!0,configurable:!0,get:function(){return i.CA||""},set:function(t){"string"==typeof t&&(i.CA=t)}}),Object.defineProperty(this,"AS",{enumerable:!1,configurable:!1,get:function(){return n},set:function(t){n=t}}),Object.defineProperty(this,"appearanceState",{enumerable:!0,configurable:!0,get:function(){return n.substr(1,n.length-1)},set:function(t){n="/"+t}}),this.caption="l",this.appearanceState="Off",this._AppearanceType=Lt.RadioButton.Circle,this.appearanceStreamContent=this._AppearanceType.createAppearanceStream(this.optionName)};z(bt,lt),vt.prototype.setAppearance=function(t){if(!("createAppearanceStream"in t)||!("getCA"in t))throw new Error("Couldn't assign Appearance to RadioButton. Appearance was Invalid!");for(var e in this.Kids)if(this.Kids.hasOwnProperty(e)){var r=this.Kids[e];r.appearanceStreamContent=t.createAppearanceStream(r.optionName),r.caption=t.getCA()}},vt.prototype.createOption=function(t){var e=new bt;return e.Parent=this,e.optionName=t,this.Kids.push(e),At.call(this.scope,e),e};var yt=function(){gt.call(this),this.fontName="zapfdingbats",this.caption="3",this.appearanceState="On",this.value="On",this.textAlign="center",this.appearanceStreamContent=Lt.CheckBox.createAppearanceStream()};z(yt,gt);var wt=function(){lt.call(this),this.FT="/Tx",Object.defineProperty(this,"multiline",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,13))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,13):this.Ff=K(this.Ff,13)}}),Object.defineProperty(this,"fileSelect",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,21))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,21):this.Ff=K(this.Ff,21)}}),Object.defineProperty(this,"doNotSpellCheck",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,23))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,23):this.Ff=K(this.Ff,23)}}),Object.defineProperty(this,"doNotScroll",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,24))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,24):this.Ff=K(this.Ff,24)}}),Object.defineProperty(this,"comb",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,25))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,25):this.Ff=K(this.Ff,25)}}),Object.defineProperty(this,"richText",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,26))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,26):this.Ff=K(this.Ff,26)}});var t=null;Object.defineProperty(this,"MaxLen",{enumerable:!0,configurable:!1,get:function(){return t},set:function(e){t=e}}),Object.defineProperty(this,"maxLength",{enumerable:!0,configurable:!0,get:function(){return t},set:function(e){Number.isInteger(e)&&(t=e)}}),Object.defineProperty(this,"hasAppearanceStream",{enumerable:!0,configurable:!0,get:function(){return this.V||this.DV}})};z(wt,lt);var Nt=function(){wt.call(this),Object.defineProperty(this,"password",{enumerable:!0,configurable:!0,get:function(){return Boolean(J(this.Ff,14))},set:function(t){!0===Boolean(t)?this.Ff=X(this.Ff,14):this.Ff=K(this.Ff,14)}}),this.password=!0};z(Nt,wt);var Lt={CheckBox:{createAppearanceStream:function(){return{N:{On:Lt.CheckBox.YesNormal},D:{On:Lt.CheckBox.YesPushDown,Off:Lt.CheckBox.OffPushDown}}},YesPushDown:function(t){var e=W(t);e.scope=t.scope;var r=[],n=t.scope.internal.getFont(t.fontName,t.fontStyle).id,i=t.scope.__private__.encodeColorString(t.color),a=Q(t,t.caption);return r.push("0.749023 g"),r.push("0 0 "+T(Lt.internal.getWidth(t))+" "+T(Lt.internal.getHeight(t))+" re"),r.push("f"),r.push("BMC"),r.push("q"),r.push("0 0 1 rg"),r.push("/"+n+" "+T(a.fontSize)+" Tf "+i),r.push("BT"),r.push(a.text),r.push("ET"),r.push("Q"),r.push("EMC"),e.stream=r.join("\n"),e},YesNormal:function(t){var e=W(t);e.scope=t.scope;var r=t.scope.internal.getFont(t.fontName,t.fontStyle).id,n=t.scope.__private__.encodeColorString(t.color),i=[],a=Lt.internal.getHeight(t),o=Lt.internal.getWidth(t),s=Q(t,t.caption);return i.push("1 g"),i.push("0 0 "+T(o)+" "+T(a)+" re"),i.push("f"),i.push("q"),i.push("0 0 1 rg"),i.push("0 0 "+T(o-1)+" "+T(a-1)+" re"),i.push("W"),i.push("n"),i.push("0 g"),i.push("BT"),i.push("/"+r+" "+T(s.fontSize)+" Tf "+n),i.push(s.text),i.push("ET"),i.push("Q"),e.stream=i.join("\n"),e},OffPushDown:function(t){var e=W(t);e.scope=t.scope;var r=[];return r.push("0.749023 g"),r.push("0 0 "+T(Lt.internal.getWidth(t))+" "+T(Lt.internal.getHeight(t))+" re"),r.push("f"),e.stream=r.join("\n"),e}},RadioButton:{Circle:{createAppearanceStream:function(t){var e={D:{Off:Lt.RadioButton.Circle.OffPushDown},N:{}};return e.N[t]=Lt.RadioButton.Circle.YesNormal,e.D[t]=Lt.RadioButton.Circle.YesPushDown,e},getCA:function(){return"l"},YesNormal:function(t){var e=W(t);e.scope=t.scope;var r=[],n=Lt.internal.getWidth(t)<=Lt.internal.getHeight(t)?Lt.internal.getWidth(t)/4:Lt.internal.getHeight(t)/4;n=Number((.9*n).toFixed(5));var i=Lt.internal.Bezier_C,a=Number((n*i).toFixed(5));return r.push("q"),r.push("1 0 0 1 "+U(Lt.internal.getWidth(t)/2)+" "+U(Lt.internal.getHeight(t)/2)+" cm"),r.push(n+" 0 m"),r.push(n+" "+a+" "+a+" "+n+" 0 "+n+" c"),r.push("-"+a+" "+n+" -"+n+" "+a+" -"+n+" 0 c"),r.push("-"+n+" -"+a+" -"+a+" -"+n+" 0 -"+n+" c"),r.push(a+" -"+n+" "+n+" -"+a+" "+n+" 0 c"),r.push("f"),r.push("Q"),e.stream=r.join("\n"),e},YesPushDown:function(t){var e=W(t);e.scope=t.scope;var r=[],n=Lt.internal.getWidth(t)<=Lt.internal.getHeight(t)?Lt.internal.getWidth(t)/4:Lt.internal.getHeight(t)/4;n=Number((.9*n).toFixed(5));var i=Number((2*n).toFixed(5)),a=Number((i*Lt.internal.Bezier_C).toFixed(5)),o=Number((n*Lt.internal.Bezier_C).toFixed(5));return r.push("0.749023 g"),r.push("q"),r.push("1 0 0 1 "+U(Lt.internal.getWidth(t)/2)+" "+U(Lt.internal.getHeight(t)/2)+" cm"),r.push(i+" 0 m"),r.push(i+" "+a+" "+a+" "+i+" 0 "+i+" c"),r.push("-"+a+" "+i+" -"+i+" "+a+" -"+i+" 0 c"),r.push("-"+i+" -"+a+" -"+a+" -"+i+" 0 -"+i+" c"),r.push(a+" -"+i+" "+i+" -"+a+" "+i+" 0 c"),r.push("f"),r.push("Q"),r.push("0 g"),r.push("q"),r.push("1 0 0 1 "+U(Lt.internal.getWidth(t)/2)+" "+U(Lt.internal.getHeight(t)/2)+" cm"),r.push(n+" 0 m"),r.push(n+" "+o+" "+o+" "+n+" 0 "+n+" c"),r.push("-"+o+" "+n+" -"+n+" "+o+" -"+n+" 0 c"),r.push("-"+n+" -"+o+" -"+o+" -"+n+" 0 -"+n+" c"),r.push(o+" -"+n+" "+n+" -"+o+" "+n+" 0 c"),r.push("f"),r.push("Q"),e.stream=r.join("\n"),e},OffPushDown:function(t){var e=W(t);e.scope=t.scope;var r=[],n=Lt.internal.getWidth(t)<=Lt.internal.getHeight(t)?Lt.internal.getWidth(t)/4:Lt.internal.getHeight(t)/4;n=Number((.9*n).toFixed(5));var i=Number((2*n).toFixed(5)),a=Number((i*Lt.internal.Bezier_C).toFixed(5));return r.push("0.749023 g"),r.push("q"),r.push("1 0 0 1 "+U(Lt.internal.getWidth(t)/2)+" "+U(Lt.internal.getHeight(t)/2)+" cm"),r.push(i+" 0 m"),r.push(i+" "+a+" "+a+" "+i+" 0 "+i+" c"),r.push("-"+a+" "+i+" -"+i+" "+a+" -"+i+" 0 c"),r.push("-"+i+" -"+a+" -"+a+" -"+i+" 0 -"+i+" c"),r.push(a+" -"+i+" "+i+" -"+a+" "+i+" 0 c"),r.push("f"),r.push("Q"),e.stream=r.join("\n"),e}},Cross:{createAppearanceStream:function(t){var e={D:{Off:Lt.RadioButton.Cross.OffPushDown},N:{}};return e.N[t]=Lt.RadioButton.Cross.YesNormal,e.D[t]=Lt.RadioButton.Cross.YesPushDown,e},getCA:function(){return"8"},YesNormal:function(t){var e=W(t);e.scope=t.scope;var r=[],n=Lt.internal.calculateCross(t);return r.push("q"),r.push("1 1 "+T(Lt.internal.getWidth(t)-2)+" "+T(Lt.internal.getHeight(t)-2)+" re"),r.push("W"),r.push("n"),r.push(T(n.x1.x)+" "+T(n.x1.y)+" m"),r.push(T(n.x2.x)+" "+T(n.x2.y)+" l"),r.push(T(n.x4.x)+" "+T(n.x4.y)+" m"),r.push(T(n.x3.x)+" "+T(n.x3.y)+" l"),r.push("s"),r.push("Q"),e.stream=r.join("\n"),e},YesPushDown:function(t){var e=W(t);e.scope=t.scope;var r=Lt.internal.calculateCross(t),n=[];return n.push("0.749023 g"),n.push("0 0 "+T(Lt.internal.getWidth(t))+" "+T(Lt.internal.getHeight(t))+" re"),n.push("f"),n.push("q"),n.push("1 1 "+T(Lt.internal.getWidth(t)-2)+" "+T(Lt.internal.getHeight(t)-2)+" re"),n.push("W"),n.push("n"),n.push(T(r.x1.x)+" "+T(r.x1.y)+" m"),n.push(T(r.x2.x)+" "+T(r.x2.y)+" l"),n.push(T(r.x4.x)+" "+T(r.x4.y)+" m"),n.push(T(r.x3.x)+" "+T(r.x3.y)+" l"),n.push("s"),n.push("Q"),e.stream=n.join("\n"),e},OffPushDown:function(t){var e=W(t);e.scope=t.scope;var r=[];return r.push("0.749023 g"),r.push("0 0 "+T(Lt.internal.getWidth(t))+" "+T(Lt.internal.getHeight(t))+" re"),r.push("f"),e.stream=r.join("\n"),e}}},createDefaultAppearanceStream:function(t){var e=t.scope.internal.getFont(t.fontName,t.fontStyle).id,r=t.scope.__private__.encodeColorString(t.color);return"/"+e+" "+t.fontSize+" Tf "+r}};Lt.internal={Bezier_C:.551915024494,calculateCross:function(t){var e=Lt.internal.getWidth(t),r=Lt.internal.getHeight(t),n=Math.min(e,r);return{x1:{x:(e-n)/2,y:(r-n)/2+n},x2:{x:(e-n)/2+n,y:(r-n)/2},x3:{x:(e-n)/2,y:(r-n)/2},x4:{x:(e-n)/2+n,y:(r-n)/2+n}}}},Lt.internal.getWidth=function(t){var r=0;return"object"===e(t)&&(r=H(t.Rect[2])),r},Lt.internal.getHeight=function(t){var r=0;return"object"===e(t)&&(r=H(t.Rect[3])),r};var At=E.addField=function(t){if(it(this,t),!(t instanceof lt))throw new Error("Invalid argument passed to jsPDF.addField.");var e;return(e=t).scope.internal.acroformPlugin.printedOut&&(e.scope.internal.acroformPlugin.printedOut=!1,e.scope.internal.acroformPlugin.acroFormDictionaryRoot=null),e.scope.internal.acroformPlugin.acroFormDictionaryRoot.Fields.push(e),t.page=t.scope.internal.getCurrentPageInfo().pageNumber,this};E.AcroFormChoiceField=ht,E.AcroFormListBox=ft,E.AcroFormComboBox=dt,E.AcroFormEditBox=pt,E.AcroFormButton=gt,E.AcroFormPushButton=mt,E.AcroFormRadioButton=vt,E.AcroFormCheckBox=yt,E.AcroFormTextField=wt,E.AcroFormPasswordField=Nt,E.AcroFormAppearance=Lt,E.AcroForm={ChoiceField:ht,ListBox:ft,ComboBox:dt,EditBox:pt,Button:gt,PushButton:mt,RadioButton:vt,CheckBox:yt,TextField:wt,PasswordField:Nt,Appearance:Lt},M.AcroForm={ChoiceField:ht,ListBox:ft,ComboBox:dt,EditBox:pt,Button:gt,PushButton:mt,RadioButton:vt,CheckBox:yt,TextField:wt,PasswordField:Nt,Appearance:Lt};var xt=M.AcroForm;function St(t){return t.reduce((function(t,e,r){return t[e]=r,t}),{})}!function(t){t.__addimage__={};var r="UNKNOWN",n={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]]},i=t.__addimage__.getImageFileTypeByImageData=function(t,e){var i,a,o,s,c,u=r;if("RGBA"===(e=e||r)||void 0!==t.data&&t.data instanceof Uint8ClampedArray&&"height"in t&&"width"in t)return"RGBA";if(x(t))for(c in n)for(o=n[c],i=0;i>"}),"transparency"in e&&Array.isArray(e.transparency)){for(var o="",s=0,c=e.transparency.length;s>",p.content=i;var b=p.objId+" 0 R";i="<>";else if(r.options.pageNumber){switch(i="<>",this.internal.write(i))}}this.internal.write("]")}}]),t.createAnnotation=function(t){var e=this.internal.getCurrentPageInfo();switch(t.type){case"link":this.link(t.bounds.x,t.bounds.y,t.bounds.w,t.bounds.h,t);break;case"text":case"freetext":e.pageContext.annotations.push(t)}},t.link=function(t,e,r,n,i){var a=this.internal.getCurrentPageInfo(),o=this.internal.getCoordinateString,s=this.internal.getVerticalCoordinateString;a.pageContext.annotations.push({finalBounds:{x:o(t),y:s(e),w:o(t+r),h:s(e+n)},options:i,type:"link"})},t.textWithLink=function(t,e,r,n){var i,a,o=this.getTextWidth(t),s=this.internal.getLineHeight()/this.internal.scaleFactor;if(void 0!==n.maxWidth){a=n.maxWidth;var c=this.splitTextToSize(t,a).length;i=Math.ceil(s*c)}else a=o,i=s;return this.text(t,e,r,n),r+=.2*s,"center"===n.align&&(e-=o/2),"right"===n.align&&(e-=o),this.link(e,r-s,a,i,n),o},t.getTextWidth=function(t){var e=this.internal.getFontSize();return this.getStringUnitWidth(t)*e/this.internal.scaleFactor}}(M.API), /** * @license * Copyright (c) 2017 Aras Abbasi * * Licensed under the MIT License. * http://opensource.org/licenses/mit-license */ function(t){var e={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]},r={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}},n={1612:64606,1613:64607,1614:64608,1615:64609,1616:64610},i=[1570,1571,1573,1575];t.__arabicParser__={};var a=t.__arabicParser__.isInArabicSubstitutionA=function(t){return void 0!==e[t.charCodeAt(0)]},o=t.__arabicParser__.isArabicLetter=function(t){return"string"==typeof t&&/^[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]+$/.test(t)},s=t.__arabicParser__.isArabicEndLetter=function(t){return o(t)&&a(t)&&e[t.charCodeAt(0)].length<=2},c=t.__arabicParser__.isArabicAlfLetter=function(t){return o(t)&&i.indexOf(t.charCodeAt(0))>=0};t.__arabicParser__.arabicLetterHasIsolatedForm=function(t){return o(t)&&a(t)&&e[t.charCodeAt(0)].length>=1};var u=t.__arabicParser__.arabicLetterHasFinalForm=function(t){return o(t)&&a(t)&&e[t.charCodeAt(0)].length>=2};t.__arabicParser__.arabicLetterHasInitialForm=function(t){return o(t)&&a(t)&&e[t.charCodeAt(0)].length>=3};var l=t.__arabicParser__.arabicLetterHasMedialForm=function(t){return o(t)&&a(t)&&4==e[t.charCodeAt(0)].length},h=t.__arabicParser__.resolveLigatures=function(t){var e=0,n=r,i="",a=0;for(e=0;e>"),this.internal.out("endobj")})),this.internal.events.subscribe("putCatalog",(function(){this.internal.out("/OpenAction "+e+" 0 R")}))}return this}}(M.API), /** * @license * Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv * * Licensed under the MIT License. * http://opensource.org/licenses/mit-license */ function(t){var e=function(){var t=void 0;Object.defineProperty(this,"pdf",{get:function(){return t},set:function(e){t=e}});var e=150;Object.defineProperty(this,"width",{get:function(){return e},set:function(t){e=isNaN(t)||!1===Number.isInteger(t)||t<0?150:t,this.getContext("2d").pageWrapXEnabled&&(this.getContext("2d").pageWrapX=e+1)}});var r=300;Object.defineProperty(this,"height",{get:function(){return r},set:function(t){r=isNaN(t)||!1===Number.isInteger(t)||t<0?300:t,this.getContext("2d").pageWrapYEnabled&&(this.getContext("2d").pageWrapY=r+1)}});var n=[];Object.defineProperty(this,"childNodes",{get:function(){return n},set:function(t){n=t}});var i={};Object.defineProperty(this,"style",{get:function(){return i},set:function(t){i=t}}),Object.defineProperty(this,"parentNode",{})};e.prototype.getContext=function(t,e){var r;if("2d"!==(t=t||"2d"))return null;for(r in e)this.pdf.context2d.hasOwnProperty(r)&&(this.pdf.context2d[r]=e[r]);return this.pdf.context2d._canvas=this,this.pdf.context2d},e.prototype.toDataURL=function(){throw new Error("toDataURL is not implemented.")},t.events.push(["initialized",function(){this.canvas=new e,this.canvas.pdf=this}])}(M.API),function(t){var r={left:0,top:0,bottom:0,right:0},n=!1,i=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({},r),this.internal.__cell__.margins.width=this.getPageWidth(),a.call(this))},a=function(){this.internal.__cell__.lastCell=new o,this.internal.__cell__.pages=1},o=function(){var t=arguments[0];Object.defineProperty(this,"x",{enumerable:!0,get:function(){return t},set:function(e){t=e}});var e=arguments[1];Object.defineProperty(this,"y",{enumerable:!0,get:function(){return e},set:function(t){e=t}});var r=arguments[2];Object.defineProperty(this,"width",{enumerable:!0,get:function(){return r},set:function(t){r=t}});var n=arguments[3];Object.defineProperty(this,"height",{enumerable:!0,get:function(){return n},set:function(t){n=t}});var i=arguments[4];Object.defineProperty(this,"text",{enumerable:!0,get:function(){return i},set:function(t){i=t}});var a=arguments[5];Object.defineProperty(this,"lineNumber",{enumerable:!0,get:function(){return a},set:function(t){a=t}});var o=arguments[6];return Object.defineProperty(this,"align",{enumerable:!0,get:function(){return o},set:function(t){o=t}}),this};o.prototype.clone=function(){return new o(this.x,this.y,this.width,this.height,this.text,this.lineNumber,this.align)},o.prototype.toArray=function(){return[this.x,this.y,this.width,this.height,this.text,this.lineNumber,this.align]},t.setHeaderFunction=function(t){return i.call(this),this.internal.__cell__.headerFunction="function"==typeof t?t:void 0,this},t.getTextDimensions=function(t,e){i.call(this);var r=(e=e||{}).fontSize||this.getFontSize(),n=e.font||this.getFont(),a=e.scaleFactor||this.internal.scaleFactor,o=0,s=0,c=0,u=this;if(!Array.isArray(t)&&"string"!=typeof t){if("number"!=typeof t)throw new Error("getTextDimensions expects text-parameter to be of type String or type Number or an Array of Strings.");t=String(t)}var l=e.maxWidth;l>0?"string"==typeof t?t=this.splitTextToSize(t,l):"[object Array]"===Object.prototype.toString.call(t)&&(t=t.reduce((function(t,e){return t.concat(u.splitTextToSize(e,l))}),[])):t=Array.isArray(t)?t:[t];for(var h=0;hthis.getPageHeight()?(this.cellAddPage(),t.y=s.top,u&&c&&(this.printHeaderRow(t.lineNumber,!0),t.y+=c[0].height)):t.y=e.y+e.height||t.y),void 0!==t.text[0]&&(this.rect(t.x,t.y,t.width,t.height,!0===n?"FD":void 0),"right"===t.align?this.text(t.text,t.x+t.width-a,t.y+a,{align:"right",baseline:"top"}):"center"===t.align?this.text(t.text,t.x+t.width/2,t.y+a,{align:"center",baseline:"top",maxWidth:t.width-a-a}):this.text(t.text,t.x+a,t.y+a,{align:"left",baseline:"top",maxWidth:t.width-a-a})),this.internal.__cell__.lastCell=t,this};t.table=function(t,n,u,l,h){if(i.call(this),!u)throw new Error("No data for PDF table.");var f,d,p,g,m=[],v=[],b=[],y={},w={},N=[],L=[],A=(h=h||{}).autoSize||!1,x=!1!==h.printHeaders,S=h.css&&void 0!==h.css["font-size"]?16*h.css["font-size"]:h.fontSize||12,_=h.margins||Object.assign({width:this.getPageWidth()},r),P="number"==typeof h.padding?h.padding:3,k=h.headerBackgroundColor||"#c8c8c8",F=h.headerTextColor||"#000";if(a.call(this),this.internal.__cell__.printHeaders=x,this.internal.__cell__.margins=_,this.internal.__cell__.table_font_size=S,this.internal.__cell__.padding=P,this.internal.__cell__.headerBackgroundColor=k,this.internal.__cell__.headerTextColor=F,this.setFontSize(S),null==l)v=m=Object.keys(u[0]),b=m.map((function(){return"left"}));else if(Array.isArray(l)&&"object"===e(l[0]))for(m=l.map((function(t){return t.name})),v=l.map((function(t){return t.prompt||t.name||""})),b=l.map((function(t){return t.align||"left"})),f=0;f0&&this.setTableHeaderRow(c),this.setFont(void 0,"normal"),n=!1}}(M.API);var _t={italic:["italic","oblique","normal"],oblique:["oblique","italic","normal"],normal:["normal","oblique","italic"]},Pt=["ultra-condensed","extra-condensed","condensed","semi-condensed","normal","semi-expanded","expanded","extra-expanded","ultra-expanded"],kt=St(Pt),Ft=[100,200,300,400,500,600,700,800,900],It=St(Ft);function Ct(t){var e=t.family.replace(/"|'/g,"").toLowerCase(),r=function(t){return _t[t=t||"normal"]?t:"normal"}(t.style),n=function(t){if(!t)return 400;if("number"==typeof t)return t>=100&&t<=900&&t%100==0?t:400;if(/^\d00$/.test(t))return parseInt(t);switch(t){case"bold":return 700;case"normal":default:return 400}}(t.weight),i=function(t){return"number"==typeof kt[t=t||"normal"]?t:"normal"}(t.stretch);return{family:e,style:r,weight:n,stretch:i,src:t.src||[],ref:t.ref||{name:e,style:[i,r,n].join(" ")}}}function jt(t,e,r,n){var i;for(i=r;i>=0&&i=0&&i=2?t[1]:e[0],e[2]=t.length>=3?t[2]:e[0],e[3]=t.length>=4?t[3]:e[1]),f.margin=e}});var o=!1;Object.defineProperty(this,"autoPaging",{get:function(){return o},set:function(t){o=t}});var s=0;Object.defineProperty(this,"lastBreak",{get:function(){return s},set:function(t){s=t}});var c=[];Object.defineProperty(this,"pageBreaks",{get:function(){return c},set:function(t){c=t}}),Object.defineProperty(this,"ctx",{get:function(){return f},set:function(t){t instanceof d&&(f=t)}}),Object.defineProperty(this,"path",{get:function(){return f.path},set:function(t){f.path=t}});var u=[];Object.defineProperty(this,"ctxStack",{get:function(){return u},set:function(t){u=t}}),Object.defineProperty(this,"fillStyle",{get:function(){return this.ctx.fillStyle},set:function(t){var e;e=g(t),this.ctx.fillStyle=e.style,this.ctx.isFillTransparent=0===e.a,this.ctx.fillOpacity=e.a,this.pdf.setFillColor(e.r,e.g,e.b,{a:e.a}),this.pdf.setTextColor(e.r,e.g,e.b,{a:e.a})}}),Object.defineProperty(this,"strokeStyle",{get:function(){return this.ctx.strokeStyle},set:function(t){var e=g(t);this.ctx.strokeStyle=e.style,this.ctx.isStrokeTransparent=0===e.a,this.ctx.strokeOpacity=e.a,0===e.a?this.pdf.setDrawColor(255,255,255):(e.a,this.pdf.setDrawColor(e.r,e.g,e.b))}}),Object.defineProperty(this,"lineCap",{get:function(){return this.ctx.lineCap},set:function(t){-1!==["butt","round","square"].indexOf(t)&&(this.ctx.lineCap=t,this.pdf.setLineCap(t))}}),Object.defineProperty(this,"lineWidth",{get:function(){return this.ctx.lineWidth},set:function(t){isNaN(t)||(this.ctx.lineWidth=t,this.pdf.setLineWidth(t))}}),Object.defineProperty(this,"lineJoin",{get:function(){return this.ctx.lineJoin},set:function(t){-1!==["bevel","round","miter"].indexOf(t)&&(this.ctx.lineJoin=t,this.pdf.setLineJoin(t))}}),Object.defineProperty(this,"miterLimit",{get:function(){return this.ctx.miterLimit},set:function(t){isNaN(t)||(this.ctx.miterLimit=t,this.pdf.setMiterLimit(t))}}),Object.defineProperty(this,"textBaseline",{get:function(){return this.ctx.textBaseline},set:function(t){this.ctx.textBaseline=t}}),Object.defineProperty(this,"textAlign",{get:function(){return this.ctx.textAlign},set:function(t){-1!==["right","end","center","left","start"].indexOf(t)&&(this.ctx.textAlign=t)}});var l=null;function h(t,e){if(null===l){var r=function(t){var e=[];return Object.keys(t).forEach((function(r){t[r].forEach((function(t){var n=null;switch(t){case"bold":n={family:r,weight:"bold"};break;case"italic":n={family:r,style:"italic"};break;case"bolditalic":n={family:r,weight:"bold",style:"italic"};break;case"":case"normal":n={family:r}}null!==n&&(n.ref={name:r,style:t},e.push(n))}))})),e}(t.getFontList());l=function(t){for(var e={},r=0;r=700||"bold"===r)&&(u="bold"),"italic"===r&&(u+="italic"),0===u.length&&(u="normal");for(var l="",f={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"},d=0;d=2*Math.PI&&(n=0,a=2*Math.PI),this.path.push({type:"arc",x:t,y:e,radius:r,startAngle:n,endAngle:a,counterclockwise:o})},p.prototype.arcTo=function(t,e,r,n,i){throw new Error("arcTo not implemented.")},p.prototype.rect=function(t,e,r,n){if(isNaN(t)||isNaN(e)||isNaN(r)||isNaN(n))throw i.error("jsPDF.context2d.rect: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.rect");this.moveTo(t,e),this.lineTo(t+r,e),this.lineTo(t+r,e+n),this.lineTo(t,e+n),this.lineTo(t,e),this.lineTo(t+r,e),this.lineTo(t,e)},p.prototype.fillRect=function(t,e,r,n){if(isNaN(t)||isNaN(e)||isNaN(r)||isNaN(n))throw i.error("jsPDF.context2d.fillRect: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.fillRect");if(!m.call(this)){var a={};"butt"!==this.lineCap&&(a.lineCap=this.lineCap,this.lineCap="butt"),"miter"!==this.lineJoin&&(a.lineJoin=this.lineJoin,this.lineJoin="miter"),this.beginPath(),this.rect(t,e,r,n),this.fill(),a.hasOwnProperty("lineCap")&&(this.lineCap=a.lineCap),a.hasOwnProperty("lineJoin")&&(this.lineJoin=a.lineJoin)}},p.prototype.strokeRect=function(t,e,r,n){if(isNaN(t)||isNaN(e)||isNaN(r)||isNaN(n))throw i.error("jsPDF.context2d.strokeRect: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.strokeRect");v.call(this)||(this.beginPath(),this.rect(t,e,r,n),this.stroke())},p.prototype.clearRect=function(t,e,r,n){if(isNaN(t)||isNaN(e)||isNaN(r)||isNaN(n))throw i.error("jsPDF.context2d.clearRect: Invalid arguments",arguments),new Error("Invalid arguments passed to jsPDF.context2d.clearRect");this.ignoreClearRect||(this.fillStyle="#ffffff",this.fillRect(t,e,r,n))},p.prototype.save=function(t){t="boolean"!=typeof t||t;for(var e=this.pdf.internal.getCurrentPageInfo().pageNumber,r=0;r0||this.margin[1]>0||this.margin[2]>0||this.margin[3]>0};p.prototype.drawImage=function(t,e,r,n,i,a,o,s,c){var h=this.pdf.getImageProperties(t),f=1,d=1,p=1,g=1;void 0!==n&&void 0!==s&&(p=s/n,g=c/i,f=h.width/n*s/n,d=h.height/i*c/i),void 0===a&&(a=e,o=r,e=0,r=0),void 0!==n&&void 0===s&&(s=n,c=i),void 0===n&&void 0===s&&(s=h.width,c=h.height);for(var m,v=this.ctx.transform.decompose(),w=q(v.rotate.shx),A=new l,S=(A=(A=(A=A.multiply(v.translate)).multiply(v.skew)).multiply(v.scale)).applyToRectangle(new u(a-e*p,o-r*g,n*f,i*d)),_=y.call(this,S),P=[],k=0;k<_.length;k+=1)-1===P.indexOf(_[k])&&P.push(_[k]);if(L(P),this.autoPaging)for(var F=P[0],I=P[P.length-1],C=F;CF||Cv||S0))for(;c>=0;c--)if(!0!==i[c-1].close&&!0!==i[c-1].begin){i[c-1].deltas.push(r),i[c-1].abs.push(s);break}break;case"bct":r=[s.x1-a[o-1].x,s.y1-a[o-1].y,s.x2-a[o-1].x,s.y2-a[o-1].y,s.x-a[o-1].x,s.y-a[o-1].y],i[i.length-1].deltas.push(r);break;case"qct":var u=a[o-1].x+2/3*(s.x1-a[o-1].x),l=a[o-1].y+2/3*(s.y1-a[o-1].y),h=s.x+2/3*(s.x1-s.x),f=s.y+2/3*(s.y1-s.y),d=s.x,p=s.y;r=[u-a[o-1].x,l-a[o-1].y,h-a[o-1].x,f-a[o-1].y,d-a[o-1].x,p-a[o-1].y],i[i.length-1].deltas.push(r);break;case"arc":i.push({deltas:[],abs:[],arc:!0}),Array.isArray(i[i.length-1].abs)&&i[i.length-1].abs.push(s)}}n=e?null:"stroke"===t?"stroke":"fill";for(var g=!1,b=0;b=.01&&(f=this.pdf.internal.getFontSize(),this.pdf.setFontSize(f*t.scale),d=this.lineWidth,this.lineWidth=d*t.scale);var D="text"!==this.autoPaging;if(D||q.y+q.h<=C){if(D||q.y>=F&&q.x<=O){var R=D?t.text:this.pdf.splitTextToSize(t.text,t.maxWidth||O-q.x)[0],T=N([JSON.parse(JSON.stringify(p))],this.posX+this.margin[3],-M+F+this.ctx.prevPageLastElemOffset)[0],U=D&&(k>A||k=.01&&(this.pdf.setFontSize(f),this.lineWidth=d)}else t.scale>=.01&&(f=this.pdf.internal.getFontSize(),this.pdf.setFontSize(f*t.scale),d=this.lineWidth,this.lineWidth=d*t.scale),this.pdf.text(t.text,a.x+this.posX,a.y+this.posY,{angle:t.angle,align:e,renderingMode:t.renderingMode,maxWidth:t.maxWidth}),t.scale>=.01&&(this.pdf.setFontSize(f),this.lineWidth=d)},j=function(t,e,r,i){r=r||0,i=i||0,this.pdf.internal.out(n(t+r)+" "+a(e+i)+" l")},O=function(t,e,r){return this.pdf.lines(t,e,r,null,null)},B=function(t,e,n,i,a,c,u,l){this.pdf.internal.out([r(o(n+t)),r(s(i+e)),r(o(a+t)),r(s(c+e)),r(o(u+t)),r(s(l+e)),"c"].join(" "))},M=function(t,e,r,n){for(var i=2*Math.PI,a=Math.PI/2;e>r;)e-=i;var o=Math.abs(r-e);o1e-5;){var l=u+c*Math.min(o,a);s.push(E.call(this,t,u,l)),o-=Math.abs(l-u),u=l}return s},E=function(t,e,r){var n=(r-e)/2,i=t*Math.cos(n),a=t*Math.sin(n),o=i,s=-a,c=o*o+s*s,u=c+o*i+s*a,l=4/3*(Math.sqrt(2*c*u)-u)/(o*a-s*i),h=o-l*s,f=s+l*o,d=h,p=-f,g=n+e,m=Math.cos(g),v=Math.sin(g);return{x1:t*Math.cos(e),y1:t*Math.sin(e),x2:h*m-f*v,y2:h*v+f*m,x3:d*m-p*v,y3:d*v+p*m,x4:t*Math.cos(r),y4:t*Math.sin(r)}},q=function(t){return 180*t/Math.PI},D=function(t,e,r,n,i,a){var o=t+.5*(r-t),s=e+.5*(n-e),c=i+.5*(r-i),l=a+.5*(n-a),h=Math.min(t,i,o,c),f=Math.max(t,i,o,c),d=Math.min(e,a,s,l),p=Math.max(e,a,s,l);return new u(h,d,f-h,p-d)},R=function(t,e,r,n,i,a,o,s){var c,l,h,f,d,p,g,m,v,b,y,w,N,L,A=r-t,x=n-e,S=i-r,_=a-n,P=o-i,k=s-a;for(l=0;l<41;l++)v=(g=(h=t+(c=l/40)*A)+c*((d=r+c*S)-h))+c*(d+c*(i+c*P-d)-g),b=(m=(f=e+c*x)+c*((p=n+c*_)-f))+c*(p+c*(a+c*k-p)-m),0==l?(y=v,w=b,N=v,L=b):(y=Math.min(y,v),w=Math.min(w,b),N=Math.max(N,v),L=Math.max(L,b));return new u(Math.round(y),Math.round(w),Math.round(N-y),Math.round(L-w))},T=function(){if(this.prevLineDash||this.ctx.lineDash.length||this.ctx.lineDashOffset){var t,e,r=(t=this.ctx.lineDash,e=this.ctx.lineDashOffset,JSON.stringify({lineDash:t,lineDashOffset:e}));this.prevLineDash!==r&&(this.pdf.setLineDash(this.ctx.lineDash,this.ctx.lineDashOffset),this.prevLineDash=r)}}}(M.API);try{require("worker_threads").Worker}catch(t){}var Ut=Uint8Array,zt=Uint16Array,Ht=Uint32Array,Wt=new Ut([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]),Vt=new Ut([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]),Gt=new Ut([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Yt=function(t,e){for(var r=new zt(31),n=0;n<31;++n)r[n]=e+=1<>>1|(21845&ee)<<1;re=(61680&(re=(52428&re)>>>2|(13107&re)<<2))>>>4|(3855&re)<<4,te[ee]=((65280&re)>>>8|(255&re)<<8)>>>1}var ne=function(t,e,r){for(var n=t.length,i=0,a=new zt(e);i>>c]=u}else for(o=new zt(n),i=0;i>>15-t[i];return o},ie=new Ut(288);for(ee=0;ee<144;++ee)ie[ee]=8;for(ee=144;ee<256;++ee)ie[ee]=9;for(ee=256;ee<280;++ee)ie[ee]=7;for(ee=280;ee<288;++ee)ie[ee]=8;var ae=new Ut(32);for(ee=0;ee<32;++ee)ae[ee]=5;var oe=ne(ie,9,0),se=ne(ie,9,1),ce=ne(ae,5,0),ue=ne(ae,5,1),le=function(t){for(var e=t[0],r=1;re&&(e=t[r]);return e},he=function(t,e,r){var n=e/8>>0;return(t[n]|t[n+1]<<8)>>>(7&e)&r},fe=function(t,e){var r=e/8>>0;return(t[r]|t[r+1]<<8|t[r+2]<<16)>>>(7&e)},de=function(t){return(t/8>>0)+(7&t&&1)},pe=function(t,e,r){(null==e||e<0)&&(e=0),(null==r||r>t.length)&&(r=t.length);var n=new(t instanceof zt?zt:t instanceof Ht?Ht:Ut)(r-e);return n.set(t.subarray(e,r)),n},ge=function(t,e,r){r<<=7&e;var n=e/8>>0;t[n]|=r,t[n+1]|=r>>>8},me=function(t,e,r){r<<=7&e;var n=e/8>>0;t[n]|=r,t[n+1]|=r>>>8,t[n+2]|=r>>>16},ve=function(t,e){for(var r=[],n=0;nf&&(f=a[n].s);var d=new zt(f+1),p=be(r[l-1],d,0);if(p>e){n=0;var g=0,m=p-e,v=1<e))break;g+=v-(1<>>=m;g>0;){var y=a[n].s;d[y]=0&&g;--n){var w=a[n].s;d[w]==e&&(--d[w],++g)}p=e}return[new Ut(d),p]},be=function(t,e,r){return-1==t.s?Math.max(be(t.l,e,r+1),be(t.r,e,r+1)):e[t.s]=r},ye=function(t){for(var e=t.length;e&&!t[--e];);for(var r=new zt(++e),n=0,i=t[0],a=1,o=function(t){r[n++]=t},s=1;s<=e;++s)if(t[s]==i&&s!=e)++a;else{if(!i&&a>2){for(;a>138;a-=138)o(32754);a>2&&(o(a>10?a-11<<5|28690:a-3<<5|12305),a=0)}else if(a>3){for(o(i),--a;a>6;a-=6)o(8304);a>2&&(o(a-3<<5|8208),a=0)}for(;a--;)o(i);a=1,i=t[s]}return[r.subarray(0,n),e]},we=function(t,e){for(var r=0,n=0;n>>8,t[i+2]=255^t[i],t[i+3]=255^t[i+1];for(var a=0;a4&&!_[Gt[k-1]];--k);var F,I,C,j,O=u+5<<3,B=we(i,ie)+we(a,ae)+o,M=we(i,f)+we(a,g)+o+14+3*k+we(A,_)+(2*A[16]+3*A[17]+7*A[18]);if(O<=B&&O<=M)return Ne(e,l,t.subarray(c,c+u));if(ge(e,l,1+(M15&&(ge(e,l,R[x]>>>5&127),l+=R[x]>>>12)}}}else F=oe,I=ie,C=ce,j=ae;for(x=0;x255){T=n[x]>>>18&31;me(e,l,F[T+257]),l+=I[T+257],T>7&&(ge(e,l,n[x]>>>23&31),l+=Wt[T]);var U=31&n[x];me(e,l,C[U]),l+=j[U],U>3&&(me(e,l,n[x]>>>5&8191),l+=Vt[U])}else me(e,l,F[n[x]]),l+=I[n[x]];return me(e,l,F[256]),l+I[256]},Ae=new Ht([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),xe=new Ut(0),Se=function(t,e,r,n,i){return function(t,e,r,n,i,a){var o=t.length,s=new Ut(n+o+5*(1+Math.floor(o/7e3))+i),c=s.subarray(n,s.length-i),u=0;if(!e||o<8)for(var l=0;l<=o;l+=65535){var h=l+65535;h>>13,p=8191&f,g=(1<7e3||_>24576)&&j>423){u=Le(t,c,0,N,L,A,S,_,k,l-k,u),_=x=S=0,k=l;for(var O=0;O<286;++O)L[O]=0;for(O=0;O<30;++O)A[O]=0}var B=2,M=0,E=p,q=I-C&32767;if(j>2&&F==w(l-q))for(var D=Math.min(d,j)-1,R=Math.min(32767,l),T=Math.min(258,j);q<=R&&--E&&I!=C;){if(t[l+B]==t[l+B-q]){for(var U=0;UB){if(B=U,M=q,U>D)break;var z=Math.min(q,U-2),H=0;for(O=0;OH&&(H=V,C=W)}}}q+=(I=C)-(C=m[I])+32768&32767}if(M){N[_++]=268435456|Kt[B]<<18|Qt[M];var G=31&Kt[B],Y=31&Qt[M];S+=Wt[G]+Vt[Y],++L[257+G],++A[Y],P=l+B,++x}else N[_++]=t[l],++L[t[l]]}}u=Le(t,c,a,N,L,A,S,_,k,l-k,u),a||(u=Ne(c,u,xe))}return pe(s,0,n+de(u)+i)}(t,null==e.level?6:e.level,null==e.mem?Math.ceil(1.5*Math.max(8,Math.min(13,Math.log(t.length)))):12+e.mem,r,n,!i)};function _e(t,e){void 0===e&&(e={});var r=function(){var t=1,e=0;return{p:function(r){for(var n=t,i=e,a=r.length,o=0;o!=a;){for(var s=Math.min(o+5552,a);o>>8<<16|(255&e)<<8|e>>>8)+2*((255&t)<<23)}}}();r.p(t);var n=Se(t,e,2,4);return function(t,e){var r=e.level,n=0==r?0:r<6?1:9==r?3:2;t[0]=120,t[1]=n<<6|(n?32-2*n:1)}(n,e),function(t,e,r){for(;r;++e)t[e]=r,r>>>=8}(n,n.length-4,r.d()),n}function Pe(t,e){return function(t,e,r){var n=t.length,i=!e||r,a=!r||r.i;r||(r={}),e||(e=new Ut(3*n));var o=function(t){var r=e.length;if(t>r){var n=new Ut(Math.max(2*r,t));n.set(e),e=n}},s=r.f||0,c=r.p||0,u=r.b||0,l=r.l,h=r.d,f=r.m,d=r.n,p=8*n;do{if(!l){r.f=s=he(t,c,1);var g=he(t,c+1,3);if(c+=3,!g){var m=t[(P=de(c)+4)-4]|t[P-3]<<8,v=P+m;if(v>n){if(a)throw"unexpected EOF";break}i&&o(u+m),e.set(t.subarray(P,v),u),r.b=u+=m,r.p=c=8*v;continue}if(1==g)l=se,h=ue,f=9,d=5;else{if(2!=g)throw"invalid block type";var b=he(t,c,31)+257,y=he(t,c+10,15)+4,w=b+he(t,c+5,31)+1;c+=14;for(var N=new Ut(w),L=new Ut(19),A=0;Ap)break;var _=ne(L,x,1);for(A=0;A>>4)<16)N[A++]=P;else{var F=0,I=0;for(16==P?(I=3+he(t,c,3),c+=2,F=N[A-1]):17==P?(I=3+he(t,c,7),c+=3):18==P&&(I=11+he(t,c,127),c+=7);I--;)N[A++]=F}}var C=N.subarray(0,b),j=N.subarray(b);f=le(C),d=le(j),l=ne(C,f,1),h=ne(j,d,1)}if(c>p)throw"unexpected EOF"}i&&o(u+131072);for(var O=(1<>>4;if((c+=15&F)>p)throw"unexpected EOF";if(!F)throw"invalid length/literal";if(E<256)e[u++]=E;else{if(256==E){l=null;break}var q=E-254;if(E>264){var D=Wt[A=E-257];q=he(t,c,(1<>>4;if(!R)throw"invalid distance";c+=15&R;j=$t[T];if(T>3){D=Vt[T];j+=fe(t,c)&(1<p)throw"unexpected EOF";i&&o(u+131072);for(var U=u+q;u>>4>7||(t[0]<<8|t[1])%31)throw"invalid zlib data";if(32&t[1])throw"invalid zlib data: preset dictionaries not supported"}(t),t.subarray(2,-4)),e)} /** * @license * jsPDF filters PlugIn * Copyright (c) 2014 Aras Abbasi * * Licensed under the MIT License. * http://opensource.org/licenses/mit-license */!function(t){var e=function(t){var e,r,n,i,a,o,s,c,u,l;for(/[^\x00-\xFF]/.test(t),r=[],n=0,i=(t+=e="\0\0\0\0".slice(t.length%4||4)).length;i>n;n+=4)0!==(a=(t.charCodeAt(n)<<24)+(t.charCodeAt(n+1)<<16)+(t.charCodeAt(n+2)<<8)+t.charCodeAt(n+3))?(o=(a=((a=((a=((a=(a-(l=a%85))/85)-(u=a%85))/85)-(c=a%85))/85)-(s=a%85))/85)%85,r.push(o+33,s+33,c+33,u+33,l+33)):r.push(122);return function(t,e){for(var r=e;r>0;r--)t.pop()}(r,e.length),String.fromCharCode.apply(String,r)+"~>"},r=function(t){var e,r,n,i,a,o=String,s="length",c=255,u="charCodeAt",l="slice",h="replace";for(t[l](-2),t=t[l](0,-2)[h](/\s/g,"")[h]("z","!!!!!"),n=[],i=0,a=(t+=e="uuuuu"[l](t[s]%5||5))[s];a>i;i+=5)r=52200625*(t[u](i)-33)+614125*(t[u](i+1)-33)+7225*(t[u](i+2)-33)+85*(t[u](i+3)-33)+(t[u](i+4)-33),n.push(c&r>>24,c&r>>16,c&r>>8,c&r);return function(t,e){for(var r=e;r>0;r--)t.pop()}(n,e[s]),o.fromCharCode.apply(o,n)},n=function(t){var e=new RegExp(/^([0-9A-Fa-f]{2})+$/);if(-1!==(t=t.replace(/\s/g,"")).indexOf(">")&&(t=t.substr(0,t.indexOf(">"))),t.length%2&&(t+="0"),!1===e.test(t))return"";for(var r="",n=0;n",c.push("/ASCIIHexDecode");break;case"FlateEncode":case"/FlateEncode":s=i(s),c.push("/FlateDecode");break;default:throw new Error('The filter: "'+a[o]+'" is not implemented')}return{data:s,reverseChain:c.reverse().join(" ")}}}(M.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(t){t.loadFile=function(t,e,r){return function(t,e,r){e=!1!==e,r="function"==typeof r?r:function(){};var n=void 0;try{n=function(t,e,r){var n=new XMLHttpRequest,i=0,a=function(t){var e=t.length,r=[],n=String.fromCharCode;for(i=0;iu&&(c=l,l=u,u=c);else{if("l"!==t&&"landscape"!==t)throw"Invalid orientation: "+t;t="l",u>l&&(c=l,l=u,u=c)}return{width:l,height:u,unit:r,k:a,orientation:t}},n.html=function(t,e){(e=e||{}).callback=e.callback||function(){},e.html2canvas=e.html2canvas||{},e.html2canvas.canvas=e.html2canvas.canvas||this.canvas,e.jsPDF=e.jsPDF||this,e.fontFaces=e.fontFaces?e.fontFaces.map(Ct):null;var r=new c(e);return e.worker?r:r.from(t).doCallback()}}(M.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(t){var e,r,n;t.addJS=function(t){return n=t,this.internal.events.subscribe("postPutResources",(function(){e=this.internal.newObject(),this.internal.out("<<"),this.internal.out("/Names [(EmbeddedJS) "+(e+1)+" 0 R]"),this.internal.out(">>"),this.internal.out("endobj"),r=this.internal.newObject(),this.internal.out("<<"),this.internal.out("/S /JavaScript"),this.internal.out("/JS ("+n+")"),this.internal.out(">>"),this.internal.out("endobj")})),this.internal.events.subscribe("putCatalog",(function(){void 0!==e&&void 0!==r&&this.internal.out("/Names <>")})),this}}(M.API), /** * @license * Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv * * Licensed under the MIT License. * http://opensource.org/licenses/mit-license */ function(t){var e;t.events.push(["postPutResources",function(){var t=this,r=/^(\d+) 0 obj$/;if(this.outline.root.children.length>0)for(var n=t.outline.render().split(/\r\n/),i=0;i> endobj")}var f=t.internal.newObject();t.internal.write("<< /Names [ ");for(i=0;i>","endobj"),e=t.internal.newObject(),t.internal.write("<< /Dests "+f+" 0 R"),t.internal.write(">>","endobj")}}]),t.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 "+e+" 0 R"))}]),t.events.push(["initialized",function(){var t=this;t.outline={createNamedDestinations:!1,root:{children:[]}},t.outline.add=function(t,e,r){var n={title:e,options:r,children:[]};return null==t&&(t=this.root),t.children.push(n),n},t.outline.render=function(){return this.ctx={},this.ctx.val="",this.ctx.pdf=t,this.genIds_r(this.root),this.renderRoot(this.root),this.renderItems(this.root),this.ctx.val},t.outline.genIds_r=function(e){e.id=t.internal.newObjectDeferred();for(var r=0;r0&&(this.line("/First "+this.makeRef(t.children[0])),this.line("/Last "+this.makeRef(t.children[t.children.length-1]))),this.line("/Count "+this.count_r({count:0},t)),this.objEnd()},t.outline.renderItems=function(e){for(var r=this.ctx.pdf.internal.getVerticalCoordinateString,n=0;n0&&this.line("/Prev "+this.makeRef(e.children[n-1])),n0&&(this.line("/First "+this.makeRef(i.children[0])),this.line("/Last "+this.makeRef(i.children[i.children.length-1])));var a=this.count=this.count_r({count:0},i);if(a>0&&this.line("/Count "+a),i.options&&i.options.pageNumber){var o=t.internal.getPageInfo(i.options.pageNumber);this.line("/Dest ["+o.objId+" 0 R /XYZ 0 "+r(0)+" 0]")}this.objEnd()}for(var s=0;s> \r\nendobj\r\n"},t.outline.count_r=function(t,e){for(var r=0;re;0<=e?++f:--f)t.push(this.data[this.pos++]);break;case"tRNS":switch(this.transparency={},this.colorType){case 3:if(n=this.palette.length/3,this.transparency.indexed=this.read(e),this.transparency.indexed.length>n)throw new Error("More transparent colors than palette size");if((l=n-this.transparency.indexed.length)>0)for(d=0;0<=l?dl;0<=l?++d:--d)this.transparency.indexed.push(255);break;case 0:this.transparency.grayscale=this.read(e)[0];break;case 2:this.transparency.rgb=this.read(e)}break;case"tEXt":s=(h=this.read(e)).indexOf(0),c=String.fromCharCode.apply(String,h.slice(0,s)),this.text[c]=String.fromCharCode.apply(String,h.slice(s+1));break;case"IEND":return o&&this.animation.frames.push(o),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===(p=this.colorType)||6===p,r=this.colors+(this.hasAlphaChannel?1:0),this.pixelBitlength=this.bits*r,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+=e}if(this.pos+=4,this.pos>this.data.length)throw new Error("Incomplete or corrupt PNG file")}}i.prototype.read=function(t){var e,r;for(r=[],e=0;0<=t?et;0<=t?++e:--e)r.push(this.data[this.pos++]);return r},i.prototype.readUInt32=function(){return this.data[this.pos++]<<24|this.data[this.pos++]<<16|this.data[this.pos++]<<8|this.data[this.pos++]},i.prototype.readUInt16=function(){return this.data[this.pos++]<<8|this.data[this.pos++]},i.prototype.decodePixels=function(t){var e=this.pixelBitlength/8,r=new Uint8Array(this.width*this.height*e),n=0,i=this;if(null==t&&(t=this.imgData),0===t.length)return new Uint8Array(0);function a(a,o,s,c){var u,l,h,f,d,p,g,m,v,b,y,w,N,L,A,x,S,_,P,k,F,I=Math.ceil((i.width-a)/s),C=Math.ceil((i.height-o)/c),j=i.width==I&&i.height==C;for(L=e*I,w=j?r:new Uint8Array(L*C),p=t.length,N=0,l=0;N1&&r/i, 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 Be(t){var e=0;if(71!==t[e++]||73!==t[e++]||70!==t[e++]||56!==t[e++]||56!=(t[e++]+1&253)||97!==t[e++])throw new Error("Invalid GIF 87a/89a header.");var r=t[e++]|t[e++]<<8,n=t[e++]|t[e++]<<8,i=t[e++],a=i>>7,o=1<<(7&i)+1;t[e++];t[e++];var s=null,c=null;a&&(s=e,c=o,e+=3*o);var u=!0,l=[],h=0,f=null,d=0,p=null;for(this.width=r,this.height=n;u&&e=0))throw Error("Invalid block size");if(0===P)break;e+=P}break;case 249:if(4!==t[e++]||0!==t[e+4])throw new Error("Invalid graphics extension block.");var g=t[e++];h=t[e++]|t[e++]<<8,f=t[e++],0==(1&g)&&(f=null),d=g>>2&7,e++;break;case 254:for(;;){if(!((P=t[e++])>=0))throw Error("Invalid block size");if(0===P)break;e+=P}break;default:throw new Error("Unknown graphic control label: 0x"+t[e-1].toString(16))}break;case 44:var m=t[e++]|t[e++]<<8,v=t[e++]|t[e++]<<8,b=t[e++]|t[e++]<<8,y=t[e++]|t[e++]<<8,w=t[e++],N=w>>6&1,L=1<<(7&w)+1,A=s,x=c,S=!1;if(w>>7){S=!0;A=e,x=L,e+=3*L}var _=e;for(e++;;){var P;if(!((P=t[e++])>=0))throw Error("Invalid block size");if(0===P)break;e+=P}l.push({x:m,y:v,width:b,height:y,has_local_palette:S,palette_offset:A,palette_size:x,data_offset:_,data_length:e-_,transparent_index:f,interlaced:!!N,delay:h,disposal:d});break;case 59:u=!1;break;default:throw new Error("Unknown gif block: 0x"+t[e-1].toString(16))}this.numFrames=function(){return l.length},this.loopCount=function(){return p},this.frameInfo=function(t){if(t<0||t>=l.length)throw new Error("Frame index out of range.");return l[t]},this.decodeAndBlitFrameBGRA=function(e,n){var i=this.frameInfo(e),a=i.width*i.height,o=new Uint8Array(a);Me(t,i.data_offset,o,a);var s=i.palette_offset,c=i.transparent_index;null===c&&(c=256);var u=i.width,l=r-u,h=u,f=4*(i.y*r+i.x),d=4*((i.y+i.height)*r+i.x),p=f,g=4*l;!0===i.interlaced&&(g+=4*r*7);for(var m=8,v=0,b=o.length;v=d&&(g=4*l+4*r*(m-1),p=f+(u+l)*(m<<1),m>>=1)),y===c)p+=4;else{var w=t[s+3*y],N=t[s+3*y+1],L=t[s+3*y+2];n[p++]=L,n[p++]=N,n[p++]=w,n[p++]=255}--h}},this.decodeAndBlitFrameRGBA=function(e,n){var i=this.frameInfo(e),a=i.width*i.height,o=new Uint8Array(a);Me(t,i.data_offset,o,a);var s=i.palette_offset,c=i.transparent_index;null===c&&(c=256);var u=i.width,l=r-u,h=u,f=4*(i.y*r+i.x),d=4*((i.y+i.height)*r+i.x),p=f,g=4*l;!0===i.interlaced&&(g+=4*r*7);for(var m=8,v=0,b=o.length;v=d&&(g=4*l+4*r*(m-1),p=f+(u+l)*(m<<1),m>>=1)),y===c)p+=4;else{var w=t[s+3*y],N=t[s+3*y+1],L=t[s+3*y+2];n[p++]=w,n[p++]=N,n[p++]=L,n[p++]=255}--h}}}function Me(t,e,r,n){for(var a=t[e++],o=1<>=u,h-=u,v!==o){if(v===s)break;for(var b=vo;)w=g[w]>>8,++y;var N=w;if(d+y+(b!==v?1:0)>n)return void i.log("Warning, gif stream longer than expected.");r[d++]=N;var L=d+=y;for(b!==v&&(r[d++]=N),w=b;y--;)w=g[w],r[--L]=255&w,w>>=8;null!==m&&c<4096&&(g[c++]=m<<8|N,c>=l+1&&u<12&&(++u,l=l<<1|1)),m=v}else c=s+1,l=(1<<(u=a+1))-1,m=null}return d!==n&&i.log("Warning, gif stream shorter than expected."),r} /** * @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 Ee(t){var e,r,n,i,a,o=Math.floor,s=new Array(64),c=new Array(64),u=new Array(64),l=new Array(64),h=new Array(65535),f=new Array(65535),d=new Array(64),p=new Array(64),g=[],m=0,v=7,b=new Array(64),y=new Array(64),w=new Array(64),N=new Array(256),L=new Array(2048),A=[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],x=[0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0],S=[0,1,2,3,4,5,6,7,8,9,10,11],_=[0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,125],P=[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],k=[0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0],F=[0,1,2,3,4,5,6,7,8,9,10,11],I=[0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,119],C=[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 j(t,e){for(var r=0,n=0,i=new Array,a=1;a<=16;a++){for(var o=1;o<=t[a];o++)i[e[n]]=[],i[e[n]][0]=r,i[e[n]][1]=a,n++,r++;r*=2}return i}function O(t){for(var e=t[0],r=t[1]-1;r>=0;)e&1<>8&255),B(255&t)}function E(t,e,r,n,i){for(var a,o=i[0],s=i[240],c=function(t,e){var r,n,i,a,o,s,c,u,l,h,f=0;for(l=0;l<8;++l){r=t[f],n=t[f+1],i=t[f+2],a=t[f+3],o=t[f+4],s=t[f+5],c=t[f+6];var p=r+(u=t[f+7]),g=r-u,m=n+c,v=n-c,b=i+s,y=i-s,w=a+o,N=a-o,L=p+w,A=p-w,x=m+b,S=m-b;t[f]=L+x,t[f+4]=L-x;var _=.707106781*(S+A);t[f+2]=A+_,t[f+6]=A-_;var P=.382683433*((L=N+y)-(S=v+g)),k=.5411961*L+P,F=1.306562965*S+P,I=.707106781*(x=y+v),C=g+I,j=g-I;t[f+5]=j+k,t[f+3]=j-k,t[f+1]=C+F,t[f+7]=C-F,f+=8}for(f=0,l=0;l<8;++l){r=t[f],n=t[f+8],i=t[f+16],a=t[f+24],o=t[f+32],s=t[f+40],c=t[f+48];var O=r+(u=t[f+56]),B=r-u,M=n+c,E=n-c,q=i+s,D=i-s,R=a+o,T=a-o,U=O+R,z=O-R,H=M+q,W=M-q;t[f]=U+H,t[f+32]=U-H;var V=.707106781*(W+z);t[f+16]=z+V,t[f+48]=z-V;var G=.382683433*((U=T+D)-(W=E+B)),Y=.5411961*U+G,J=1.306562965*W+G,X=.707106781*(H=D+E),K=B+X,Z=B-X;t[f+40]=Z+Y,t[f+24]=Z-Y,t[f+8]=K+J,t[f+56]=K-J,f++}for(l=0;l<64;++l)h=t[l]*e[l],d[l]=h>0?h+.5|0:h-.5|0;return d}(t,e),u=0;u<64;++u)p[A[u]]=c[u];var l=p[0]-r;r=p[0],0==l?O(n[0]):(O(n[f[a=32767+l]]),O(h[a]));for(var g=63;g>0&&0==p[g];)g--;if(0==g)return O(o),r;for(var m,v=1;v<=g;){for(var b=v;0==p[v]&&v<=g;)++v;var y=v-b;if(y>=16){m=y>>4;for(var w=1;w<=m;++w)O(s);y&=15}a=32767+p[v],O(i[(y<<4)+f[a]]),O(h[a]),v++}return 63!=g&&O(o),r}function q(t){(t=Math.min(Math.max(t,1),100),a!=t)&&(!function(t){for(var e=[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],r=0;r<64;r++){var n=o((e[r]*t+50)/100);n=Math.min(Math.max(n,1),255),s[A[r]]=n}for(var i=[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],a=0;a<64;a++){var h=o((i[a]*t+50)/100);h=Math.min(Math.max(h,1),255),c[A[a]]=h}for(var f=[1,1.387039845,1.306562965,1.175875602,1,.785694958,.5411961,.275899379],d=0,p=0;p<8;p++)for(var g=0;g<8;g++)u[d]=1/(s[A[d]]*f[p]*f[g]*8),l[d]=1/(c[A[d]]*f[p]*f[g]*8),d++}(t<50?Math.floor(5e3/t):Math.floor(200-2*t)),a=t)}this.encode=function(t,a){a&&q(a),g=new Array,m=0,v=7,M(65496),M(65504),M(16),B(74),B(70),B(73),B(70),B(0),B(1),B(1),B(0),M(1),M(1),B(0),B(0),function(){M(65499),M(132),B(0);for(var t=0;t<64;t++)B(s[t]);B(1);for(var e=0;e<64;e++)B(c[e])}(),function(t,e){M(65472),M(17),B(8),M(e),M(t),B(3),B(1),B(17),B(0),B(2),B(17),B(1),B(3),B(17),B(1)}(t.width,t.height),function(){M(65476),M(418),B(0);for(var t=0;t<16;t++)B(x[t+1]);for(var e=0;e<=11;e++)B(S[e]);B(16);for(var r=0;r<16;r++)B(_[r+1]);for(var n=0;n<=161;n++)B(P[n]);B(1);for(var i=0;i<16;i++)B(k[i+1]);for(var a=0;a<=11;a++)B(F[a]);B(17);for(var o=0;o<16;o++)B(I[o+1]);for(var s=0;s<=161;s++)B(C[s])}(),M(65498),M(12),B(3),B(1),B(0),B(2),B(17),B(3),B(17),B(0),B(63),B(0);var o=0,h=0,f=0;m=0,v=7,this.encode.displayName="_encode_";for(var d,p,N,A,j,D,R,T,U,z=t.data,H=t.width,W=t.height,V=4*H,G=0;G>3)*V+(R=4*(7&U)),G+T>=W&&(D-=V*(G+1+T-W)),d+R>=V&&(D-=d+R-V+4),p=z[D++],N=z[D++],A=z[D++],b[U]=(L[p]+L[N+256>>0]+L[A+512>>0]>>16)-128,y[U]=(L[p+768>>0]+L[N+1024>>0]+L[A+1280>>0]>>16)-128,w[U]=(L[p+1280>>0]+L[N+1536>>0]+L[A+1792>>0]>>16)-128;o=E(b,u,o,e,n),h=E(y,l,h,r,i),f=E(w,l,f,r,i),d+=32}G+=8}if(v>=0){var Y=[];Y[1]=v+1,Y[0]=(1<>0]=38470*t,L[t+512>>0]=7471*t+32768,L[t+768>>0]=-11059*t,L[t+1024>>0]=-21709*t,L[t+1280>>0]=32768*t+8421375,L[t+1536>>0]=-27439*t,L[t+1792>>0]=-5329*t}(),q(t)} /** * @license * Copyright (c) 2017 Aras Abbasi * * Licensed under the MIT License. * http://opensource.org/licenses/mit-license */function qe(t,e){if(this.pos=0,this.buffer=t,this.datav=new DataView(t.buffer),this.is_with_alpha=!!e,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 De(t){function e(t){if(!t)throw Error("assert :P")}function r(t,e,r){for(var n=0;4>n;n++)if(t[e+n]!=r.charCodeAt(n))return!0;return!1}function n(t,e,r,n,i){for(var a=0;an+1?[]:new e),!(i.length>>0;t&r;)r>>>=1;return r?(t&r-1)+r:t}function u(t,r,n,i,a){e(!(i%n));do{t[r+(i-=n)]=a}while(0=o),512>=o)var s=a(512);else if(null==(s=a(o)))return 0;return function(t,r,n,i,o,s){var l,f,d=r,p=1<l;++l){if(g[l]>1<(L-=g[l]))return 0;for(;0=l;++l,o<<=1){if(N+=L<<=1,0>(L-=g[l]))return 0;for(;0b&&!(0>=(v-=g[b]));)++b,v<<=1;p+=A=1<<(v=b-n),t[r+(b=w&y)].g=v+n,t[r+b].value=d-r-b}i.g=l-n,i.value=s[f++],u(t,d+(w>>n),o,A,i),w=c(w,l)}}return N!=2*m[15]-1?0:p}(t,r,n,i,o,s)}function h(){this.value=this.g=0}function f(){this.value=this.g=0}function d(){this.G=o(5,h),this.H=a(5),this.jc=this.Qb=this.qb=this.nd=0,this.pd=o(Dr,f)}function p(t,r,n,i){e(null!=t),e(null!=r),e(2147483648>i),t.Ca=254,t.I=0,t.b=-8,t.Ka=0,t.oa=r,t.pa=n,t.Jd=r,t.Yc=n+i,t.Zc=4<=i?n+i-4+1:n,_(t)}function g(t,e){for(var r=0;0i),t.Sb=i,t.Ra=0,t.u=0,t.h=0,4>>=8,t.Ra+=t.oa[t.pa+t.bb]<>>0,++t.bb,t.u-=8;A(t)&&(t.h=1,t.u=0)}function y(t,r){if(e(0<=r),!t.h&&r<=Tr){var n=L(t)&Rr[r];return t.u+=r,b(t),n}return t.h=1,t.u=0}function w(){this.b=this.Ca=this.I=0,this.oa=[],this.pa=0,this.Jd=[],this.Yc=0,this.Zc=[],this.Ka=0}function N(){this.Ra=0,this.oa=[],this.h=this.u=this.bb=this.Sb=this.pa=0}function L(t){return t.Ra>>>(t.u&Ur-1)>>>0}function A(t){return e(t.bb<=t.Sb),t.h||t.bb==t.Sb&&t.u>Ur}function x(t,e){t.u=e,t.h=A(t)}function S(t){t.u>=zr&&(e(t.u>=zr),b(t))}function _(t){e(null!=t&&null!=t.oa),t.pa>>0,t.b+=8):(e(null!=t&&null!=t.oa),t.pat.b&&_(t);var n=t.b,i=r*e>>>8,a=(t.I>>>n>i)+0;for(a?(r-=i,t.I-=i+1<>>0):r=i+1,n=r,i=0;256<=n;)i+=8,n>>=8;return n=7^i+Hr[n],t.b-=n,t.Ca=(r<>24&255,t[e+1]=r>>16&255,t[e+2]=r>>8&255,t[e+3]=r>>0&255}function I(t,e){return t[e+0]<<0|t[e+1]<<8}function C(t,e){return I(t,e)|t[e+2]<<16}function j(t,e){return I(t,e)|I(t,e+2)<<16}function O(t,r){var n=1<=a||0>=o?0:(n[0]=a,i[0]=o,1)}function q(t,e){return t+(1<>>e}function D(t,e){return((4278255360&t)+(4278255360&e)>>>0&4278255360)+((16711935&t)+(16711935&e)>>>0&16711935)>>>0}function R(e,r){t[r]=function(r,n,i,a,o,s,c){var u;for(u=0;u>>1)+(t&e)>>>0}function z(t){return 0<=t&&256>t?t:0>t?0:255>1))}function W(t,e,r){return Math.abs(e-r)-Math.abs(t-r)}function V(t,e,r,n,i,a,o){for(n=a[o-1],r=0;r>8&255,c=16711935&(c=(c=16711935&o)+((s<<16)+s));n[i+a]=(4278255360&o)+c>>>0}}function Y(t,e){e.jd=t>>0&255,e.hd=t>>8&255,e.ud=t>>16&255}function J(t,e,r,n,i,a){var o;for(o=0;o>>8,u=s,l=255&(l=(l=s>>>16)+((t.jd<<24>>24)*(c<<24>>24)>>>5));u=255&(u=(u=u+((t.hd<<24>>24)*(c<<24>>24)>>>5))+((t.ud<<24>>24)*(l<<24>>24)>>>5));i[a+o]=(4278255360&s)+(l<<16)+u}}function X(e,r,n,i,a){t[r]=function(t,e,r,n,o,s,c,u,l){for(n=c;n>e.b,f=e.Ea,d=e.K[0],p=e.w;if(8>h)for(e=(1<>=h}else t["VP8LMapColor"+n](s,c,d,p,u,l,r,o,f)}}function K(t,e,r,n,i){for(r=e+r;e>16&255,n[i++]=a>>8&255,n[i++]=a>>0&255}}function Z(t,e,r,n,i){for(r=e+r;e>16&255,n[i++]=a>>8&255,n[i++]=a>>0&255,n[i++]=a>>24&255}}function $(t,e,r,n,i){for(r=e+r;e>16&240|o>>12&15,o=o>>0&240|o>>28&15;n[i++]=a,n[i++]=o}}function Q(t,e,r,n,i){for(r=e+r;e>16&248|o>>13&7,o=o>>5&224|o>>3&31;n[i++]=a,n[i++]=o}}function tt(t,e,r,n,i){for(r=e+r;e>0&255,n[i++]=a>>8&255,n[i++]=a>>16&255}}function et(t,e,r,i,a,o){if(0==o)for(r=e+r;e>24|o[1]>>8&65280|o[2]<<8&16711680|o[3]<<24)>>>0),a+=32;else n(i,a,t,e,r)}function rt(e,r){t[r][0]=t[e+"0"],t[r][1]=t[e+"1"],t[r][2]=t[e+"2"],t[r][3]=t[e+"3"],t[r][4]=t[e+"4"],t[r][5]=t[e+"5"],t[r][6]=t[e+"6"],t[r][7]=t[e+"7"],t[r][8]=t[e+"8"],t[r][9]=t[e+"9"],t[r][10]=t[e+"10"],t[r][11]=t[e+"11"],t[r][12]=t[e+"12"],t[r][13]=t[e+"13"],t[r][14]=t[e+"0"],t[r][15]=t[e+"0"]}function nt(t){return t==Hn||t==Wn||t==Vn||t==Gn}function it(){this.eb=[],this.size=this.A=this.fb=0}function at(){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 ot(){this.Rd=this.height=this.width=this.S=0,this.f={},this.f.RGBA=new it,this.f.kb=new at,this.sd=null}function st(){this.width=[0],this.height=[0],this.Pd=[0],this.Qd=[0],this.format=[0]}function ct(){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 ut(t){return alert("todo:WebPSamplerProcessPlane"),t.T}function lt(t,e){var r=t.T,i=e.ba.f.RGBA,a=i.eb,o=i.fb+t.ka*i.A,s=vi[e.ba.S],c=t.y,u=t.O,l=t.f,h=t.N,f=t.ea,d=t.W,p=e.cc,g=e.dc,m=e.Mc,v=e.Nc,b=t.ka,y=t.ka+t.T,w=t.U,N=w+1>>1;for(0==b?s(c,u,null,null,l,h,f,d,l,h,f,d,a,o,null,null,w):(s(e.ec,e.fc,c,u,p,g,m,v,l,h,f,d,a,o-i.A,a,o,w),++r);b+2r,i=r==qn||r==Rn||r==Tn||r==Un||12==r||nt(r);if(e.memory=null,e.Ib=null,e.Jb=null,e.Nd=null,!Mr(e.Oa,t,i?11:12))return 0;if(i&&nt(r)&&br(),t.da)alert("todo:use_scaling");else{if(n){if(e.Ib=ut,t.Kb){if(r=t.U+1>>1,e.memory=a(t.U+2*r),null==e.memory)return 0;e.ec=e.memory,e.fc=0,e.cc=e.ec,e.dc=e.fc+t.U,e.Mc=e.cc,e.Nc=e.dc+r,e.Ib=lt,br()}}else alert("todo:EmitYUV");i&&(e.Jb=ht,n&&mr())}if(n&&!Ci){for(t=0;256>t;++t)ji[t]=89858*(t-128)+_i>>Si,Mi[t]=-22014*(t-128)+_i,Bi[t]=-45773*(t-128),Oi[t]=113618*(t-128)+_i>>Si;for(t=Pi;t>Si,Ei[t-Pi]=Vt(e,255),qi[t-Pi]=Vt(e+8>>4,15);Ci=1}return 1}function dt(t){var r=t.ma,n=t.U,i=t.T;return e(!(1&t.ka)),0>=n||0>=i?0:(n=r.Ib(t,r),null!=r.Jb&&r.Jb(t,r,n),r.Dc+=n,1)}function pt(t){t.ma.memory=null}function gt(t,e,r,n){return 47!=y(t,8)?0:(e[0]=y(t,14)+1,r[0]=y(t,14)+1,n[0]=y(t,1),0!=y(t,3)?0:!t.h)}function mt(t,e){if(4>t)return t+1;var r=t-2>>1;return(2+(1&t)<>4)*t+(8-(15&r)))?r:1;var r}function bt(t,e,r){var n=L(r),i=t[e+=255&n].g-8;return 0>>0,e(8>=n.g),t.g}function wt(t,r,n){var i=t.xc;return e((r=0==i?0:t.vc[t.md*(n>>i)+(r>>i)])>_.b)*x;vN&&(I=N),(0,Zr[P[k++]>>8&15])(p,g+ +F,y,w+F-N,I-F,y,w+F),F=I}g+=N,w+=N,++v&A||(_+=x)}d!=h.nc&&n(l,u-m,l,u+(d-f-1)*m,m);break;case 1:for(m=p,b=g,N=(p=h.Ea)-(w=p&~(y=(g=1<>h.b)*v;f=a),0o.o&&(i=o.o),n=i?n=0:(a[0]+=4*o.v,o.ka=n-o.j,o.U=o.va-o.v,o.T=i-n,n=1),n){if(c=c[0],11>(n=t.ca).S){var h=n.f.RGBA,f=(i=n.S,a=o.U,o=o.T,l=h.eb,h.A),d=o;for(h=h.fb+t.Ma*h.A;0i){var a=t.l.width,o=n.ca,s=n.tb+a*i,c=t.V,u=t.Ba+t.c*i,l=t.gc;e(1==t.ab),e(3==l[0].hc),Xr(l[0],i,r,c,u,o,s),xt(n,i,r,o,s,a)}t.C=t.Ma=r}function _t(t,r,n,i,a,o,s){var c=t.$/i,u=t.$%i,l=t.m,h=t.s,f=n+t.$,d=f;a=n+i*a;var p=n+i*o,g=280+h.ua,m=t.Pb?c:16777216,v=0=m){var _=f-n;e((m=t).Pb),m.wd=m.m,m.xd=_,0k.g?(x(N,N.u+k.g),_[P]=k.value,N=0):(x(N,N.u+k.g-256),e(256<=k.value),N=k.value),0==N&&(w=!0)}else N=bt(y.G[0],y.H[0],l);if(l.h)break;if(w||256>N){if(!w)if(y.nd)r[f]=(y.qb|N<<8)>>>0;else{if(S(l),w=bt(y.G[1],y.H[1],l),S(l),_=bt(y.G[2],y.H[2],l),P=bt(y.G[3],y.H[3],l),l.h)break;r[f]=(P<<24|w<<16|N<<8|_)>>>0}if(w=!1,++f,++u>=i&&(u=0,++c,null!=s&&c<=o&&!(c%16)&&s(t,c),null!=v))for(;d>>v.Mb]=N}else if(280>N){if(N=mt(N-256,l),_=bt(y.G[4],y.H[4],l),S(l),_=vt(i,_=mt(_,l)),l.h)break;if(f-n<_||a-f=i;)u-=i,++c,null!=s&&c<=o&&!(c%16)&&s(t,c);if(e(f<=a),u&b&&(y=wt(h,u,c)),null!=v)for(;d>>v.Mb]=N}else{if(!(N>>v.Mb]=N;N=f,e(!(w>>>(_=v).Xa)),r[N]=_.X[w],w=!0}w||e(l.h==A(l))}if(t.Pb&&l.h&&fo?o:c),t.a=0,t.$=f-n}return 1}return t.a=3,0}function Pt(t){e(null!=t),t.vc=null,t.yc=null,t.Ya=null;var r=t.Wa;null!=r&&(r.X=null),t.vb=null,e(null!=t)}function kt(){var e=new or;return null==e?null:(e.a=0,e.xb=gi,rt("Predictor","VP8LPredictors"),rt("Predictor","VP8LPredictors_C"),rt("PredictorAdd","VP8LPredictorsAdd"),rt("PredictorAdd","VP8LPredictorsAdd_C"),Gr=G,$r=J,Qr=K,tn=Z,en=$,rn=Q,nn=tt,t.VP8LMapColor32b=Jr,t.VP8LMapColor8b=Kr,e)}function Ft(t,r,n,s,c){var u=1,f=[t],p=[r],g=s.m,m=s.s,v=null,b=0;t:for(;;){if(n)for(;u&&y(g,1);){var w=f,N=p,A=s,_=1,P=A.m,k=A.gc[A.ab],F=y(P,2);if(A.Oc&1<=A.ab),F){case 0:case 1:k.b=y(P,3)+2,_=Ft(q(k.Ea,k.b),q(k.nc,k.b),0,A,k.K),k.K=k.K[0];break;case 3:var I,C=y(P,8)+1,j=16>E.b),T=a(R);if(null==T)I=0;else{var U=E.K[0],z=E.w;for(T[0]=E.K[0][0],B=1;B<1*M;++B)T[B]=D(U[z+B],T[B-1]);for(;B<4*R;++B)T[B]=0;E.K[0]=null,E.K[0]=T,I=1}}_=I;break;case 2:break;default:e(0)}u=_}}if(f=f[0],p=p[0],u&&y(g,1)&&!(u=1<=(b=y(g,4))&&11>=b)){s.a=3;break t}var H;if(H=u)e:{var W,V,G,Y=s,J=f,X=p,K=b,Z=n,$=Y.m,Q=Y.s,tt=[null],et=1,rt=0,nt=Qn[K];r:for(;;){if(Z&&y($,1)){var it=y($,3)+2,at=q(J,it),ot=q(X,it),st=at*ot;if(!Ft(at,ot,0,Y,tt))break r;for(tt=tt[0],Q.xc=it,W=0;W>8&65535;tt[W]=ct,ct>=et&&(et=ct+1)}}if($.h)break r;for(V=0;5>V;++V){var ut=Xn[V];!V&&0=ht),dt=ft;var pt=a(rt);if(null==dt||null==pt||null==lt){Y.a=1;break r}var gt=lt;for(W=G=0;WV;++V){ut=Xn[V],vt[V]=gt,bt[V]=G,!V&&0Gt)break i}else zt=Gt;for(Ht=0;Htte)Yt[Ht++]=te,0!=te&&(Kt=te);else{var ee=16==te,re=te-16,ne=Jn[re],ie=y(Xt,Yn[re])+ne;if(Ht+ie>Gt)break i;for(var ae=ee?Kt:0;0=V){var oe,se=pt[0];for(oe=1;oese&&(se=pt[oe]);Lt+=se}}if(mt.nd=Nt,mt.Qb=0,Nt&&(mt.qb=(vt[3][bt[3]+0].value<<24|vt[1][bt[1]+0].value<<16|vt[2][bt[2]+0].value)>>>0,0==wt&&256>vt[0][bt[0]+0].value&&(mt.Qb=1,mt.qb+=vt[0][bt[0]+0].value<<8)),mt.jc=!mt.Qb&&6>Lt,mt.jc){var ce,ue=mt;for(ce=0;ce>=yt(fe,8,he),le>>=yt(ue.G[1][ue.H[1]+le],16,he),le>>=yt(ue.G[2][ue.H[2]+le],0,he),yt(ue.G[3][ue.H[3]+le],24,he))}}}Q.vc=tt,Q.Wb=et,Q.Ya=dt,Q.yc=lt,H=1;break e}H=0}if(!(u=H)){s.a=3;break t}if(0r+1?[]:0),!(n.lengtht?0:t>e?e:t}function Gt(){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 Yt(){var t=new Wt;return null!=t&&(t.a=0,t.sc="OK",t.cb=0,t.Xb=0,ni||(ni=Zt)),t}function Jt(t,e,r){return 0==t.a&&(t.a=e,t.sc=r,t.cb=0),0}function Xt(t,e,r){return 3<=r&&157==t[e+0]&&1==t[e+1]&&42==t[e+2]}function Kt(t,r){if(null==t)return 0;if(t.a=0,t.sc="OK",null==r)return Jt(t,2,"null VP8Io passed to VP8GetHeaders()");var n=r.data,a=r.w,o=r.ha;if(4>o)return Jt(t,7,"Truncated header.");var s=n[a+0]|n[a+1]<<8|n[a+2]<<16,c=t.Od;if(c.Rb=!(1&s),c.td=s>>1&7,c.yd=s>>4&1,c.ub=s>>5,3o)return Jt(t,7,"cannot parse picture header");if(!Xt(n,a,o))return Jt(t,3,"Bad code word");u.c=16383&(n[a+4]<<8|n[a+3]),u.Td=n[a+4]>>6,u.i=16383&(n[a+6]<<8|n[a+5]),u.Ud=n[a+6]>>6,a+=7,o-=7,t.za=u.c+15>>4,t.Ub=u.i+15>>4,r.width=u.c,r.height=u.i,r.Da=0,r.j=0,r.v=0,r.va=r.width,r.o=r.height,r.da=0,r.ib=r.width,r.hb=r.height,r.U=r.width,r.T=r.height,i((s=t.Pa).jb,0,255,s.jb.length),e(null!=(s=t.Qa)),s.Cb=0,s.Bb=0,s.Fb=1,i(s.Zb,0,0,s.Zb.length),i(s.Lb,0,0,s.Lb)}if(c.ub>o)return Jt(t,7,"bad partition length");p(s=t.m,n,a,c.ub),a+=c.ub,o-=c.ub,c.Rb&&(u.Ld=P(s),u.Kd=P(s)),u=t.Qa;var l,h=t.Pa;if(e(null!=s),e(null!=u),u.Cb=P(s),u.Cb){if(u.Bb=P(s),P(s)){for(u.Fb=P(s),l=0;4>l;++l)u.Zb[l]=P(s)?m(s,7):0;for(l=0;4>l;++l)u.Lb[l]=P(s)?m(s,6):0}if(u.Bb)for(l=0;3>l;++l)h.jb[l]=P(s)?g(s,8):255}else u.Bb=0;if(s.Ka)return Jt(t,3,"cannot parse segment header");if((u=t.ed).zd=P(s),u.Tb=g(s,6),u.wb=g(s,3),u.Pc=P(s),u.Pc&&P(s)){for(h=0;4>h;++h)P(s)&&(u.vd[h]=m(s,6));for(h=0;4>h;++h)P(s)&&(u.od[h]=m(s,6))}if(t.L=0==u.Tb?0:u.zd?1:2,s.Ka)return Jt(t,3,"cannot parse filter header");var f=o;if(o=l=a,a=l+f,u=f,t.Xb=(1<u&&(d=u),p(t.Jc[+f],n,l,d),l+=d,u-=d,o+=3}p(t.Jc[+h],n,l,u),n=ld;++d){if(f.Cb){var v=f.Zb[d];f.Fb||(v+=n)}else{if(0>16,8>b.Eb[1]&&(b.Eb[1]=8),b.Qc[0]=ei[Vt(v+h,117)],b.Qc[1]=ri[Vt(v+l,127)],b.lc=v+l}if(!c.Rb)return Jt(t,4,"Not a key frame.");for(P(s),c=t.Pa,n=0;4>n;++n){for(o=0;8>o;++o)for(a=0;3>a;++a)for(u=0;11>u;++u)h=k(s,ui[n][o][a][u])?g(s,8):si[n][o][a][u],c.Wc[n][o].Yb[a][u]=h;for(o=0;17>o;++o)c.Xc[n][o]=c.Wc[n][li[o]]}return t.kc=P(s),t.kc&&(t.Bd=g(s,8)),t.cb=1}function Zt(t,e,r,n,i,a,o){var s=e[i].Yb[r];for(r=0;16>i;++i){if(!k(t,s[r+0]))return i;for(;!k(t,s[r+1]);)if(s=e[++i].Yb[0],r=0,16==i)return 16;var c=e[i+1].Yb;if(k(t,s[r+2])){var u=t,l=0;if(k(u,(f=s)[(h=r)+3]))if(k(u,f[h+6])){for(s=0,h=2*(l=k(u,f[h+8]))+(f=k(u,f[h+9+l])),l=0,f=ii[h];f[s];++s)l+=l+k(u,f[s]);l+=3+(8<(u=t).b&&_(u);var h,f=u.b,d=(h=u.Ca>>1)-(u.I>>f)>>31;--u.b,u.Ca+=d,u.Ca|=1,u.I-=(h+1&d)<>4,t.zb=r.j-s>>4,0>t.yb&&(t.yb=0),0>t.zb&&(t.zb=0)),t.Va=r.o+15+s>>4,t.Hb=r.va+15+s>>4,t.Hb>t.za&&(t.Hb=t.za),t.Va>t.Ub&&(t.Va=t.Ub),0s;++s){var u;if(t.Qa.Cb){var l=t.Qa.Lb[s];t.Qa.Fb||(l+=c.Tb)}else l=c.Tb;for(u=0;1>=u;++u){var h=t.gd[s][u],f=l;if(c.Pc&&(f+=c.vd[0],u&&(f+=c.od[0])),0<(f=0>f?0:63>2:d>>1)>9-c.wb&&(d=9-c.wb)),1>d&&(d=1),h.dd=d,h.tc=2*f+d,h.ld=40<=f?2:15<=f?1:0}else h.tc=0;h.La=u}}}s=0}else Jt(t,6,"Frame setup failed"),s=t.a;if(s=0==s){if(s){t.$c=0,0t.Vb){if(t.Vb=0,t.Ec=a(h),t.Fc=0,null==t.Ec){s=Jt(t,1,"no memory during frame initialization.");break t}t.Vb=h}h=t.Ec,f=t.Fc,t.Ac=h,t.Bc=f,f+=c,t.Gd=o(p,Ht),t.Hd=0,t.rb=o(g+1,Rt),t.sb=1,t.wa=m?o(m,Dt):null,t.Y=0,t.D.Nb=0,t.D.wa=t.wa,t.D.Y=t.Y,0=s;++s)Pn[255+s]=0>s?-s:s;for(s=-1020;1020>=s;++s)kn[1020+s]=-128>s?-128:127=s;++s)Fn[112+s]=-16>s?-16:15=s;++s)In[255+s]=0>s?0:255h;++h){var b,y=p[0+h];for(b=0;4>b;++b){y=ci[f[d+b]][y];for(var w=oi[k(l,y[0])];0>3;for(w=0;256>w;w+=16)h[m+w]=_}A=1,x=d[0]}var P=15&l.la,F=15&v.la;for(w=0;4>w;++w){var I=1&F;for(_=L=0;4>_;++_)P=P>>1|(I=(S=ni(f,x,S=I+(1&P),g.Sc,A,h,m))>A)<<7,L=L<<2|(3>=4,F=F>>1|I<<7,b=(b<<8|L)>>>0}for(x=P,A=F>>4,N=0;4>N;N+=2){for(L=0,P=l.la>>4+N,F=v.la>>4+N,w=0;2>w;++w){for(I=1&F,_=0;2>_;++_)S=I+(1&P),P=P>>1|(I=0<(S=ni(f,d[2],S,g.Qc,0,h,m)))<<3,L=L<<2|(3>=2,F=F>>1|I<<5}y|=L<<4*N,x|=P<<4<=s.zb&&s.M<=s.Va,0==s.Aa)t:{if(o.M=s.M,o.uc=l,Or(s,o),u=1,o=(L=s.D).Nb,l=(y=Ri[s.L])*s.R,f=y/2*s.B,w=16*o*s.R,_=8*o*s.B,d=s.sa,p=s.ta-l+w,g=s.qa,h=s.ra-f+_,m=s.Ha,v=s.Ia-f+_,F=0==(P=L.M),b=P>=s.Va-1,2==s.Aa&&Or(s,L),L.uc)for(I=(S=s).D.M,e(S.D.uc),L=S.yb;Lc.o&&(P=c.o),c.F=null,c.J=null,null!=s.Fa&&0>1),c.W+=s.B*(y>>1),null!=c.F&&(c.J+=c.width*y)),L>1,c.W+=c.v>>1,null!=c.F&&(c.J+=c.v),c.ka=L-c.j,c.U=c.va-c.v,c.T=P-L,u=c.put(c))}o+1!=s.Ic||b||(n(s.sa,s.ta-l,d,p+16*s.R,l),n(s.qa,s.ra-f,g,h+8*s.B,f),n(s.Ha,s.Ia-f,m,v+8*s.B,f))}if(!u)return Jt(t,6,"Output aborted.")}return 1}(t,r)),null!=r.bc&&r.bc(r),s&=1}return s?(t.cb=0,s):0}function te(t,e,r,n,i){i=t[e+r+32*n]+(i>>3),t[e+r+32*n]=-256&i?0>i?0:255:i}function ee(t,e,r,n,i,a){te(t,e,0,r,n+i),te(t,e,1,r,n+a),te(t,e,2,r,n-a),te(t,e,3,r,n-i)}function re(t){return(20091*t>>16)+t}function ne(t,e,r,n){var i,o=0,s=a(16);for(i=0;4>i;++i){var c=t[e+0]+t[e+8],u=t[e+0]-t[e+8],l=(35468*t[e+4]>>16)-re(t[e+12]),h=re(t[e+4])+(35468*t[e+12]>>16);s[o+0]=c+h,s[o+1]=u+l,s[o+2]=u-l,s[o+3]=c-h,o+=4,e++}for(i=o=0;4>i;++i)c=(t=s[o+0]+4)+s[o+8],u=t-s[o+8],l=(35468*s[o+4]>>16)-re(s[o+12]),te(r,n,0,0,c+(h=re(s[o+4])+(35468*s[o+12]>>16))),te(r,n,1,0,u+l),te(r,n,2,0,u-l),te(r,n,3,0,c-h),o++,n+=32}function ie(t,e,r,n){var i=t[e+0]+4,a=35468*t[e+4]>>16,o=re(t[e+4]),s=35468*t[e+1]>>16;ee(r,n,0,i+o,t=re(t[e+1]),s),ee(r,n,1,i+a,t,s),ee(r,n,2,i-a,t,s),ee(r,n,3,i-o,t,s)}function ae(t,e,r,n,i){ne(t,e,r,n),i&&ne(t,e+16,r,n+4)}function oe(t,e,r,n){on(t,e+0,r,n,1),on(t,e+32,r,n+128,1)}function se(t,e,r,n){var i;for(t=t[e+0]+4,i=0;4>i;++i)for(e=0;4>e;++e)te(r,n,e,i,t)}function ce(t,e,r,n){t[e+0]&&un(t,e+0,r,n),t[e+16]&&un(t,e+16,r,n+4),t[e+32]&&un(t,e+32,r,n+128),t[e+48]&&un(t,e+48,r,n+128+4)}function ue(t,e,r,n){var i,o=a(16);for(i=0;4>i;++i){var s=t[e+0+i]+t[e+12+i],c=t[e+4+i]+t[e+8+i],u=t[e+4+i]-t[e+8+i],l=t[e+0+i]-t[e+12+i];o[0+i]=s+c,o[8+i]=s-c,o[4+i]=l+u,o[12+i]=l-u}for(i=0;4>i;++i)s=(t=o[0+4*i]+3)+o[3+4*i],c=o[1+4*i]+o[2+4*i],u=o[1+4*i]-o[2+4*i],l=t-o[3+4*i],r[n+0]=s+c>>3,r[n+16]=l+u>>3,r[n+32]=s-c>>3,r[n+48]=l-u>>3,n+=64}function le(t,e,r){var n,i=e-32,a=Bn,o=255-t[i-1];for(n=0;nr;++r)n(t,e+32*r,t,e-32,16)}function ge(t,e){var r;for(r=16;0n;++n)i(e,r+32*n,t,16)}function ve(t,e){var r,n=16;for(r=0;16>r;++r)n+=t[e-1+32*r]+t[e+r-32];me(n>>5,t,e)}function be(t,e){var r,n=8;for(r=0;16>r;++r)n+=t[e-1+32*r];me(n>>4,t,e)}function ye(t,e){var r,n=8;for(r=0;16>r;++r)n+=t[e+r-32];me(n>>4,t,e)}function we(t,e){me(128,t,e)}function Ne(t,e,r){return t+2*e+r+2>>2}function Le(t,e){var r,i=e-32;i=new Uint8Array([Ne(t[i-1],t[i+0],t[i+1]),Ne(t[i+0],t[i+1],t[i+2]),Ne(t[i+1],t[i+2],t[i+3]),Ne(t[i+2],t[i+3],t[i+4])]);for(r=0;4>r;++r)n(t,e+32*r,i,0,i.length)}function Ae(t,e){var r=t[e-1],n=t[e-1+32],i=t[e-1+64],a=t[e-1+96];F(t,e+0,16843009*Ne(t[e-1-32],r,n)),F(t,e+32,16843009*Ne(r,n,i)),F(t,e+64,16843009*Ne(n,i,a)),F(t,e+96,16843009*Ne(i,a,a))}function xe(t,e){var r,n=4;for(r=0;4>r;++r)n+=t[e+r-32]+t[e-1+32*r];for(n>>=3,r=0;4>r;++r)i(t,e+32*r,n,4)}function Se(t,e){var r=t[e-1+0],n=t[e-1+32],i=t[e-1+64],a=t[e-1-32],o=t[e+0-32],s=t[e+1-32],c=t[e+2-32],u=t[e+3-32];t[e+0+96]=Ne(n,i,t[e-1+96]),t[e+1+96]=t[e+0+64]=Ne(r,n,i),t[e+2+96]=t[e+1+64]=t[e+0+32]=Ne(a,r,n),t[e+3+96]=t[e+2+64]=t[e+1+32]=t[e+0+0]=Ne(o,a,r),t[e+3+64]=t[e+2+32]=t[e+1+0]=Ne(s,o,a),t[e+3+32]=t[e+2+0]=Ne(c,s,o),t[e+3+0]=Ne(u,c,s)}function _e(t,e){var r=t[e+1-32],n=t[e+2-32],i=t[e+3-32],a=t[e+4-32],o=t[e+5-32],s=t[e+6-32],c=t[e+7-32];t[e+0+0]=Ne(t[e+0-32],r,n),t[e+1+0]=t[e+0+32]=Ne(r,n,i),t[e+2+0]=t[e+1+32]=t[e+0+64]=Ne(n,i,a),t[e+3+0]=t[e+2+32]=t[e+1+64]=t[e+0+96]=Ne(i,a,o),t[e+3+32]=t[e+2+64]=t[e+1+96]=Ne(a,o,s),t[e+3+64]=t[e+2+96]=Ne(o,s,c),t[e+3+96]=Ne(s,c,c)}function Pe(t,e){var r=t[e-1+0],n=t[e-1+32],i=t[e-1+64],a=t[e-1-32],o=t[e+0-32],s=t[e+1-32],c=t[e+2-32],u=t[e+3-32];t[e+0+0]=t[e+1+64]=a+o+1>>1,t[e+1+0]=t[e+2+64]=o+s+1>>1,t[e+2+0]=t[e+3+64]=s+c+1>>1,t[e+3+0]=c+u+1>>1,t[e+0+96]=Ne(i,n,r),t[e+0+64]=Ne(n,r,a),t[e+0+32]=t[e+1+96]=Ne(r,a,o),t[e+1+32]=t[e+2+96]=Ne(a,o,s),t[e+2+32]=t[e+3+96]=Ne(o,s,c),t[e+3+32]=Ne(s,c,u)}function ke(t,e){var r=t[e+0-32],n=t[e+1-32],i=t[e+2-32],a=t[e+3-32],o=t[e+4-32],s=t[e+5-32],c=t[e+6-32],u=t[e+7-32];t[e+0+0]=r+n+1>>1,t[e+1+0]=t[e+0+64]=n+i+1>>1,t[e+2+0]=t[e+1+64]=i+a+1>>1,t[e+3+0]=t[e+2+64]=a+o+1>>1,t[e+0+32]=Ne(r,n,i),t[e+1+32]=t[e+0+96]=Ne(n,i,a),t[e+2+32]=t[e+1+96]=Ne(i,a,o),t[e+3+32]=t[e+2+96]=Ne(a,o,s),t[e+3+64]=Ne(o,s,c),t[e+3+96]=Ne(s,c,u)}function Fe(t,e){var r=t[e-1+0],n=t[e-1+32],i=t[e-1+64],a=t[e-1+96];t[e+0+0]=r+n+1>>1,t[e+2+0]=t[e+0+32]=n+i+1>>1,t[e+2+32]=t[e+0+64]=i+a+1>>1,t[e+1+0]=Ne(r,n,i),t[e+3+0]=t[e+1+32]=Ne(n,i,a),t[e+3+32]=t[e+1+64]=Ne(i,a,a),t[e+3+64]=t[e+2+64]=t[e+0+96]=t[e+1+96]=t[e+2+96]=t[e+3+96]=a}function Ie(t,e){var r=t[e-1+0],n=t[e-1+32],i=t[e-1+64],a=t[e-1+96],o=t[e-1-32],s=t[e+0-32],c=t[e+1-32],u=t[e+2-32];t[e+0+0]=t[e+2+32]=r+o+1>>1,t[e+0+32]=t[e+2+64]=n+r+1>>1,t[e+0+64]=t[e+2+96]=i+n+1>>1,t[e+0+96]=a+i+1>>1,t[e+3+0]=Ne(s,c,u),t[e+2+0]=Ne(o,s,c),t[e+1+0]=t[e+3+32]=Ne(r,o,s),t[e+1+32]=t[e+3+64]=Ne(n,r,o),t[e+1+64]=t[e+3+96]=Ne(i,n,r),t[e+1+96]=Ne(a,i,n)}function Ce(t,e){var r;for(r=0;8>r;++r)n(t,e+32*r,t,e-32,8)}function je(t,e){var r;for(r=0;8>r;++r)i(t,e,t[e-1],8),e+=32}function Oe(t,e,r){var n;for(n=0;8>n;++n)i(e,r+32*n,t,8)}function Be(t,e){var r,n=8;for(r=0;8>r;++r)n+=t[e+r-32]+t[e-1+32*r];Oe(n>>4,t,e)}function Me(t,e){var r,n=4;for(r=0;8>r;++r)n+=t[e+r-32];Oe(n>>3,t,e)}function Ee(t,e){var r,n=4;for(r=0;8>r;++r)n+=t[e-1+32*r];Oe(n>>3,t,e)}function qe(t,e){Oe(128,t,e)}function De(t,e,r){var n=t[e-r],i=t[e+0],a=3*(i-n)+jn[1020+t[e-2*r]-t[e+r]],o=On[112+(a+4>>3)];t[e-r]=Bn[255+n+On[112+(a+3>>3)]],t[e+0]=Bn[255+i-o]}function Re(t,e,r,n){var i=t[e+0],a=t[e+r];return Mn[255+t[e-2*r]-t[e-r]]>n||Mn[255+a-i]>n}function Te(t,e,r,n){return 4*Mn[255+t[e-r]-t[e+0]]+Mn[255+t[e-2*r]-t[e+r]]<=n}function Ue(t,e,r,n,i){var a=t[e-3*r],o=t[e-2*r],s=t[e-r],c=t[e+0],u=t[e+r],l=t[e+2*r],h=t[e+3*r];return 4*Mn[255+s-c]+Mn[255+o-u]>n?0:Mn[255+t[e-4*r]-a]<=i&&Mn[255+a-o]<=i&&Mn[255+o-s]<=i&&Mn[255+h-l]<=i&&Mn[255+l-u]<=i&&Mn[255+u-c]<=i}function ze(t,e,r,n){var i=2*n+1;for(n=0;16>n;++n)Te(t,e+n,r,i)&&De(t,e+n,r)}function He(t,e,r,n){var i=2*n+1;for(n=0;16>n;++n)Te(t,e+n*r,1,i)&&De(t,e+n*r,1)}function We(t,e,r,n){var i;for(i=3;0>7,v=18*b+63>>7,b=9*b+63>>7;c[u-3*l]=Bn[255+c[u-3*l]+b],c[u-2*l]=Bn[255+h+v],c[u-l]=Bn[255+f+m],c[u+0]=Bn[255+d-m],c[u+l]=Bn[255+p-v],c[u+2*l]=Bn[255+g-b]}e+=n}}function Ye(t,e,r,n,i,a,o,s){for(a=2*a+1;0>3)],g=On[112+(g+3>>3)],m=p+1>>1;c[u-2*l]=Bn[255+c[u-2*l]+m],c[u-l]=Bn[255+h+g],c[u+0]=Bn[255+f-p],c[u+l]=Bn[255+d-m]}e+=n}}function Je(t,e,r,n,i,a){Ge(t,e,r,1,16,n,i,a)}function Xe(t,e,r,n,i,a){Ge(t,e,1,r,16,n,i,a)}function Ke(t,e,r,n,i,a){var o;for(o=3;0u?0:255:u)&255,u=c,i[a+s]=l}}function hr(t,r,i,o){var s=r.width,c=r.o;if(e(null!=t&&null!=r),0>i||0>=o||i+o>c)return null;if(!t.Cc){if(null==t.ga){var u;if(t.ga=new sr,(u=null==t.ga)||(u=r.width*r.o,e(0==t.Gb.length),t.Gb=a(u),t.Uc=0,null==t.Gb?u=0:(t.mb=t.Gb,t.nb=t.Uc,t.rc=null,u=1),u=!u),!u){u=t.ga;var l=t.Fa,h=t.P,f=t.qc,d=t.mb,p=t.nb,g=h+1,m=f-1,b=u.l;if(e(null!=l&&null!=d&&null!=r),mi[0]=null,mi[1]=cr,mi[2]=ur,mi[3]=lr,u.ca=d,u.tb=p,u.c=r.width,u.i=r.height,e(0=f)r=0;else if(u.$a=l[h+0]>>0&3,u.Z=l[h+0]>>2&3,u.Lc=l[h+0]>>4&3,h=l[h+0]>>6&3,0>u.$a||1=u.c*u.i;u=!r}if(u)return null;1!=t.ga.Lc?t.Ga=0:o=c-i}e(null!=t.ga),e(i+o<=c);t:{if(r=(l=t.ga).c,c=l.l.o,0==l.$a){if(g=t.rc,m=t.Vc,b=t.Fa,h=t.P+1+i*r,f=t.mb,d=t.nb+i*r,e(h<=t.P+t.qc),0!=l.Z)for(e(null!=mi[l.Z]),u=0;u=r)r=1;else if(l.ic||mr(),l.ic){l=u.V,g=u.Ba,m=u.c;var y=u.i,w=(b=1,h=u.$/m,f=u.$%m,d=u.m,p=u.s,u.$),N=m*y,L=m*r,x=p.wc,_=w(y=bt(_.G[0],_.H[0],d)))l[g+w]=y,++w,++f>=m&&(f=0,++h<=r&&!(h%16)&&St(u,h));else{if(!(280>y)){b=0;break e}y=mt(y-256,d);var P,k=bt(_.G[4],_.H[4],d);if(S(d),!(w>=(k=vt(m,k=mt(k,d)))&&N-w>=y)){b=0;break e}for(P=0;P=m;)f-=m,++h<=r&&!(h%16)&&St(u,h);wr?r:h);break e}!b||d.h&&w=c&&(t.Cc=1),o=1}if(!o)return null;if(t.Cc&&(null!=(o=t.ga)&&(o.mc=null),t.ga=null,0>23,s[c+4*o+1]=s[c+4*o+1]*h>>23,s[c+4*o+2]=s[c+4*o+2]*h>>23)}e+=a}}function dr(t,e,r,n,i){for(;0>4)*c>>16;t[e+2*a+0]=(240&o|o>>4)*c>>16&240|(15&o|o<<4)*c>>16>>4&15,t[e+2*a+1]=240&u|s}e+=i}}function pr(t,e,r,n,i,a,o,s){var c,u,l=255;for(u=0;u>8}function mr(){An=fr,xn=dr,Sn=pr,_n=gr}function vr(r,n,i){t[r]=function(t,r,a,o,s,c,u,l,h,f,d,p,g,m,v,b,y){var w,N=y-1>>1,L=s[c+0]|u[l+0]<<16,A=h[f+0]|d[p+0]<<16;e(null!=t);var x=3*L+A+131074>>2;for(n(t[r+0],255&x,x>>16,g,m),null!=a&&(x=3*A+L+131074>>2,n(a[o+0],255&x,x>>16,v,b)),w=1;w<=N;++w){var S=s[c+w]|u[l+w]<<16,_=h[f+w]|d[p+w]<<16,P=L+S+A+_+524296,k=P+2*(S+A)>>3;x=k+L>>1,L=(P=P+2*(L+_)>>3)+S>>1,n(t[r+2*w-1],255&x,x>>16,g,m+(2*w-1)*i),n(t[r+2*w-0],255&L,L>>16,g,m+(2*w-0)*i),null!=a&&(x=P+A>>1,L=k+_>>1,n(a[o+2*w-1],255&x,x>>16,v,b+(2*w-1)*i),n(a[o+2*w+0],255&L,L>>16,v,b+(2*w+0)*i)),L=S,A=_}1&y||(x=3*L+A+131074>>2,n(t[r+y-1],255&x,x>>16,g,m+(y-1)*i),null!=a&&(x=3*A+L+131074>>2,n(a[o+y-1],255&x,x>>16,v,b+(y-1)*i)))}}function br(){vi[En]=bi,vi[qn]=wi,vi[Dn]=yi,vi[Rn]=Ni,vi[Tn]=Li,vi[Un]=Ai,vi[zn]=xi,vi[Hn]=wi,vi[Wn]=Ni,vi[Vn]=Li,vi[Gn]=Ai}function yr(t){return t&~Ii?0>t?0:255:t>>Fi}function wr(t,e){return yr((19077*t>>8)+(26149*e>>8)-14234)}function Nr(t,e,r){return yr((19077*t>>8)-(6419*e>>8)-(13320*r>>8)+8708)}function Lr(t,e){return yr((19077*t>>8)+(33050*e>>8)-17685)}function Ar(t,e,r,n,i){n[i+0]=wr(t,r),n[i+1]=Nr(t,e,r),n[i+2]=Lr(t,e)}function xr(t,e,r,n,i){n[i+0]=Lr(t,e),n[i+1]=Nr(t,e,r),n[i+2]=wr(t,r)}function Sr(t,e,r,n,i){var a=Nr(t,e,r);e=a<<3&224|Lr(t,e)>>3,n[i+0]=248&wr(t,r)|a>>5,n[i+1]=e}function _r(t,e,r,n,i){var a=240&Lr(t,e)|15;n[i+0]=240&wr(t,r)|Nr(t,e,r)>>4,n[i+1]=a}function Pr(t,e,r,n,i){n[i+0]=255,Ar(t,e,r,n,i+1)}function kr(t,e,r,n,i){xr(t,e,r,n,i),n[i+3]=255}function Fr(t,e,r,n,i){Ar(t,e,r,n,i),n[i+3]=255}function Vt(t,e){return 0>t?0:t>e?e:t}function Ir(e,r,n){t[e]=function(t,e,i,a,o,s,c,u,l){for(var h=u+(-2&l)*n;u!=h;)r(t[e+0],i[a+0],o[s+0],c,u),r(t[e+1],i[a+0],o[s+0],c,u+n),e+=2,++a,++s,u+=2*n;1&l&&r(t[e+0],i[a+0],o[s+0],c,u)}}function Cr(t,e,r){return 0==r?0==t?0==e?6:5:0==e?4:0:r}function jr(t,e,r,n,i){switch(t>>>30){case 3:on(e,r,n,i,0);break;case 2:sn(e,r,n,i);break;case 1:un(e,r,n,i)}}function Or(t,e){var r,a,o=e.M,s=e.Nb,c=t.oc,u=t.pc+40,l=t.oc,h=t.pc+584,f=t.oc,d=t.pc+600;for(r=0;16>r;++r)c[u+32*r-1]=129;for(r=0;8>r;++r)l[h+32*r-1]=129,f[d+32*r-1]=129;for(0r;++r)n(c,u+32*r-4,c,u+32*r+12,4);for(r=-1;8>r;++r)n(l,h+32*r-4,l,h+32*r+4,4),n(f,d+32*r-4,f,d+32*r+4,4)}var g=t.Gd,m=t.Hd+a,v=p.ad,b=p.Hc;if(0=t.za-1?i(y,w,g[m].y[15],4):n(y,w,g[m+1].y,0,4)),r=0;4>r;r++)y[w+128+r]=y[w+256+r]=y[w+384+r]=y[w+0+r];for(r=0;16>r;++r,b<<=2)y=c,w=u+Di[r],fi[p.Ob[r]](y,w),jr(b,v,16*+r,y,w)}else if(y=Cr(a,o,p.Ob[0]),hi[y](c,u),0!=b)for(r=0;16>r;++r,b<<=2)jr(b,v,16*+r,c,u+Di[r]);for(r=p.Gc,y=Cr(a,o,p.Dd),di[y](l,h),di[y](f,d),b=v,y=l,w=h,255&(p=r>>0)&&(170&p?cn(b,256,y,w):ln(b,256,y,w)),p=f,b=d,255&(r>>=8)&&(170&r?cn(v,320,p,b):ln(v,320,p,b)),or;++r)n(g,m+r*t.R,c,u+32*r,16);for(r=0;8>r;++r)n(v,p+r*t.B,l,h+32*r,8),n(b,y+r*t.B,f,d+32*r,8)}}function Br(t,n,i,a,o,s,c,u,l){var h=[0],f=[0],d=0,p=null!=l?l.kd:0,g=null!=l?l:new nr;if(null==t||12>i)return 7;g.data=t,g.w=n,g.ha=i,n=[n],i=[i],g.gb=[g.gb];t:{var m=n,b=i,y=g.gb;if(e(null!=t),e(null!=b),e(null!=y),y[0]=0,12<=b[0]&&!r(t,m[0],"RIFF")){if(r(t,m[0]+8,"WEBP")){y=3;break t}var w=j(t,m[0]+4);if(12>w||4294967286b[0]-8){y=7;break t}y[0]=w,m[0]+=12,b[0]-=12}y=0}if(0!=y)return y;for(w=0y[0])y=7;else{if(!r(L,b[0],"VP8X")){if(10!=j(L,b[0]+4)){y=3;break t}if(18>y[0]){y=7;break t}var _=j(L,b[0]+8),P=1+C(L,b[0]+12);if(2147483648<=P*(L=1+C(L,b[0]+15))){y=3;break t}null!=S&&(S[0]=_),null!=A&&(A[0]=P),null!=x&&(x[0]=L),b[0]+=18,y[0]-=18,k[0]=1}y=0}}if(d=d[0],m=m[0],0!=y)return y;if(b=!!(2&m),!w&&d)return 3;if(null!=s&&(s[0]=!!(16&m)),null!=c&&(c[0]=b),null!=u&&(u[0]=0),c=h[0],m=f[0],d&&b&&null==l){y=0;break}if(4>i){y=7;break}if(w&&d||!w&&!d&&!r(t,n[0],"ALPH")){i=[i],g.na=[g.na],g.P=[g.P],g.Sa=[g.Sa];t:{_=t,y=n,w=i;var k=g.gb;A=g.na,x=g.P,S=g.Sa;P=22,e(null!=_),e(null!=w),L=y[0];var F=w[0];for(e(null!=A),e(null!=S),A[0]=null,x[0]=null,S[0]=0;;){if(y[0]=L,w[0]=F,8>F){y=7;break t}var I=j(_,L+4);if(4294967286k){y=3;break t}if(!r(_,L,"VP8 ")||!r(_,L,"VP8L")){y=0;break t}if(F[0]w[0])y=7;else{if(L||P){if(k=j(k,_+4),12<=A&&k>A-12){y=3;break t}if(p&&k>w[0]-8){y=7;break t}x[0]=k,y[0]+=8,w[0]-=8,S[0]=P}else S[0]=5<=w[0]&&47==k[_+0]&&!(k[_+4]>>5),x[0]=w[0];y=0}if(i=i[0],g.Ja=g.Ja[0],g.xa=g.xa[0],n=n[0],0!=y)break;if(4294967286i){y=7;break}u=c,p=m,b=s,null==t||5>i?t=0:5<=i&&47==t[n+0]&&!(t[n+4]>>5)?(w=[0],k=[0],A=[0],v(x=new N,t,n,i),gt(x,w,k,A)?(null!=u&&(u[0]=w[0]),null!=p&&(p[0]=k[0]),null!=b&&(b[0]=A[0]),t=1):t=0):t=0}else{if(10>i){y=7;break}u=m,null==t||10>i||!Xt(t,n+3,i-3)?t=0:(p=t[n+0]|t[n+1]<<8|t[n+2]<<16,b=16383&(t[n+7]<<8|t[n+6]),t=16383&(t[n+9]<<8|t[n+8]),1&p||3<(p>>1&7)||!(p>>4&1)||p>>5>=g.Ja||!b||!t?t=0:(c&&(c[0]=b),u&&(u[0]=t),t=1))}if(!t)return 3;if(c=c[0],m=m[0],d&&(h[0]!=c||f[0]!=m))return 3;null!=l&&(l[0]=g,l.offset=n-l.w,e(4294967286>n-l.w),e(l.offset==l.ha-i));break}return 0==y||7==y&&d&&null==l?(null!=s&&(s[0]|=null!=g.na&&0r||(a&=-2,o&=-2),0>a||0>o||0>=s||0>=c||a+s>n||o+c>i))return 0;if(e.v=a,e.j=o,e.va=a+s,e.o=o+c,e.U=s,e.T=c,e.da=null!=t&&0t.S){var e=t.f.RGBA;e.fb+=(t.height-1)*e.A,e.A=-e.A}else e=t.f.kb,t=t.height,e.O+=(t-1)*e.fa,e.fa=-e.fa,e.N+=(t-1>>1)*e.Ab,e.Ab=-e.Ab,e.W+=(t-1>>1)*e.Db,e.Db=-e.Db,null!=e.F&&(e.J+=(t-1)*e.lb,e.lb=-e.lb);return 0}function qr(t,e,r,n){if(null==n||0>=t||0>=e)return 2;if(null!=r){if(r.Da){var i=r.cd,o=r.bd,s=-2&r.v,c=-2&r.j;if(0>s||0>c||0>=i||0>=o||s+i>t||c+o>e)return 2;t=i,e=o}if(r.da){if(!E(t,e,i=[r.ib],o=[r.hb]))return 2;t=i[0],e=o[0]}}n.width=t,n.height=e;t:{var u=n.width,l=n.height;if(t=n.S,0>=u||0>=l||!(t>=En&&13>t))t=2;else{if(0>=n.Rd&&null==n.sd){s=o=i=e=0;var h=(c=u*zi[t])*l;if(11>t||(o=(l+1)/2*(e=(u+1)/2),12==t&&(s=(i=u)*l)),null==(l=a(h+2*o+s))){t=1;break t}n.sd=l,11>t?((u=n.f.RGBA).eb=l,u.fb=0,u.A=c,u.size=h):((u=n.f.kb).y=l,u.O=0,u.fa=c,u.Fd=h,u.f=l,u.N=0+h,u.Ab=e,u.Cd=o,u.ea=l,u.W=0+h+o,u.Db=e,u.Ed=o,12==t&&(u.F=l,u.J=0+h+2*o),u.Tc=s,u.lb=i)}if(e=1,i=n.S,o=n.width,s=n.height,i>=En&&13>i)if(11>i)t=n.f.RGBA,e&=(c=Math.abs(t.A))*(s-1)+o<=t.size,e&=c>=o*zi[i],e&=null!=t.eb;else{t=n.f.kb,c=(o+1)/2,h=(s+1)/2,u=Math.abs(t.fa);l=Math.abs(t.Ab);var f=Math.abs(t.Db),d=Math.abs(t.lb),p=d*(s-1)+o;e&=u*(s-1)+o<=t.Fd,e&=l*(h-1)+c<=t.Cd,e=(e&=f*(h-1)+c<=t.Ed)&u>=o&l>=c&f>=c,e&=null!=t.y,e&=null!=t.f,e&=null!=t.ea,12==i&&(e&=d>=o,e&=p<=t.Tc,e&=null!=t.F)}else e=0;t=e?0:2}}return 0!=t||null!=r&&r.fd&&(t=Er(n)),t}var Dr=64,Rr=[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],Tr=24,Ur=32,zr=8,Hr=[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];R("Predictor0","PredictorAdd0"),t.Predictor0=function(){return 4278190080},t.Predictor1=function(t){return t},t.Predictor2=function(t,e,r){return e[r+0]},t.Predictor3=function(t,e,r){return e[r+1]},t.Predictor4=function(t,e,r){return e[r-1]},t.Predictor5=function(t,e,r){return U(U(t,e[r+1]),e[r+0])},t.Predictor6=function(t,e,r){return U(t,e[r-1])},t.Predictor7=function(t,e,r){return U(t,e[r+0])},t.Predictor8=function(t,e,r){return U(e[r-1],e[r+0])},t.Predictor9=function(t,e,r){return U(e[r+0],e[r+1])},t.Predictor10=function(t,e,r){return U(U(t,e[r-1]),U(e[r+0],e[r+1]))},t.Predictor11=function(t,e,r){var n=e[r+0];return 0>=W(n>>24&255,t>>24&255,(e=e[r-1])>>24&255)+W(n>>16&255,t>>16&255,e>>16&255)+W(n>>8&255,t>>8&255,e>>8&255)+W(255&n,255&t,255&e)?n:t},t.Predictor12=function(t,e,r){var n=e[r+0];return(z((t>>24&255)+(n>>24&255)-((e=e[r-1])>>24&255))<<24|z((t>>16&255)+(n>>16&255)-(e>>16&255))<<16|z((t>>8&255)+(n>>8&255)-(e>>8&255))<<8|z((255&t)+(255&n)-(255&e)))>>>0},t.Predictor13=function(t,e,r){var n=e[r-1];return(H((t=U(t,e[r+0]))>>24&255,n>>24&255)<<24|H(t>>16&255,n>>16&255)<<16|H(t>>8&255,n>>8&255)<<8|H(t>>0&255,n>>0&255))>>>0};var Wr=t.PredictorAdd0;t.PredictorAdd1=V,R("Predictor2","PredictorAdd2"),R("Predictor3","PredictorAdd3"),R("Predictor4","PredictorAdd4"),R("Predictor5","PredictorAdd5"),R("Predictor6","PredictorAdd6"),R("Predictor7","PredictorAdd7"),R("Predictor8","PredictorAdd8"),R("Predictor9","PredictorAdd9"),R("Predictor10","PredictorAdd10"),R("Predictor11","PredictorAdd11"),R("Predictor12","PredictorAdd12"),R("Predictor13","PredictorAdd13");var Vr=t.PredictorAdd2;X("ColorIndexInverseTransform","MapARGB","32b",(function(t){return t>>8&255}),(function(t){return t})),X("VP8LColorIndexInverseTransformAlpha","MapAlpha","8b",(function(t){return t}),(function(t){return t>>8&255}));var Gr,Yr=t.ColorIndexInverseTransform,Jr=t.MapARGB,Xr=t.VP8LColorIndexInverseTransformAlpha,Kr=t.MapAlpha,Zr=t.VP8LPredictorsAdd=[];Zr.length=16,(t.VP8LPredictors=[]).length=16,(t.VP8LPredictorsAdd_C=[]).length=16,(t.VP8LPredictors_C=[]).length=16;var $r,Qr,tn,en,rn,nn,an,on,sn,cn,un,ln,hn,fn,dn,pn,gn,mn,vn,bn,yn,wn,Nn,Ln,An,xn,Sn,_n,Pn=a(511),kn=a(2041),Fn=a(225),In=a(767),Cn=0,jn=kn,On=Fn,Bn=In,Mn=Pn,En=0,qn=1,Dn=2,Rn=3,Tn=4,Un=5,zn=6,Hn=7,Wn=8,Vn=9,Gn=10,Yn=[2,3,7],Jn=[3,3,11],Xn=[280,256,256,256,40],Kn=[0,1,1,1,0],Zn=[17,18,0,1,2,3,4,5,16,6,7,8,9,10,11,12,13,14,15],$n=[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],Qn=[2954,2956,2958,2962,2970,2986,3018,3082,3212,3468,3980,5004],ti=8,ei=[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],ri=[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],ni=null,ii=[[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]],ai=[0,1,4,8,5,2,3,6,9,12,13,10,7,11,14,15],oi=[-0,1,-1,2,-2,3,4,6,-3,5,-4,-5,-6,7,-7,8,-8,-9],si=[[[[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]]]],ci=[[[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]]],ui=[[[[255,255,255,255,255,255,255,255,255,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]]]],li=[0,1,2,3,6,4,5,6,6,6,6,6,6,6,6,7,0],hi=[],fi=[],di=[],pi=1,gi=2,mi=[],vi=[];vr("UpsampleRgbLinePair",Ar,3),vr("UpsampleBgrLinePair",xr,3),vr("UpsampleRgbaLinePair",Fr,4),vr("UpsampleBgraLinePair",kr,4),vr("UpsampleArgbLinePair",Pr,4),vr("UpsampleRgba4444LinePair",_r,2),vr("UpsampleRgb565LinePair",Sr,2);var bi=t.UpsampleRgbLinePair,yi=t.UpsampleBgrLinePair,wi=t.UpsampleRgbaLinePair,Ni=t.UpsampleBgraLinePair,Li=t.UpsampleArgbLinePair,Ai=t.UpsampleRgba4444LinePair,xi=t.UpsampleRgb565LinePair,Si=16,_i=1<i.ca.S||(alert("todo:WebPInitConvertARGBToYUV"),null!=i.ca.f.kb.F&&mr()),i.Pb&&0(u=n.Md)?0:100l;++l)12>(f=a.pb[l]).lc&&(f.ia=u*Ti[0>f.lc?0:f.lc]>>3),h|=f.ia;h&&(alert("todo:VP8InitRandom"),a.ia=1)}a.Ga=n.Id,100a.Ga&&(a.Ga=0)}Qt(t,i)||(r=t.a)}}else r=t.a}0==r&&null!=s.Oa&&s.Oa.fd&&(r=Er(s.ba))}s=r}o=0!=s?null:11>o?c.f.RGBA.eb:c.f.kb.y}else o=null;return o};var zi=[3,4,3,4,4,2,2,4,4,4,2,1,1]};function u(t,e){for(var r="",n=0;n<4;n++)r+=String.fromCharCode(t[e++]);return r}function l(t,e){return(t[e+0]<<0|t[e+1]<<8|t[e+2]<<16)>>>0}function h(t,e){return(t[e+0]<<0|t[e+1]<<8|t[e+2]<<16|t[e+3]<<24)>>>0}new c;var f=[0],d=[0],p=[],g=new c,m=t,v=function(t,e){var r={},n=0,i=!1,a=0,o=0;if(r.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(t,e,r,n){for(var i=0;i>1&1}"ANMF"!=f&&(e+=p)}return r}}(m,0);v.response=m,v.rgbaoutput=!0,v.dataurl=!1;var b=v.header?v.header:null,y=v.frames?v.frames:null;if(b){b.loop_counter=b.loop_count,f=[b.canvas_height],d=[b.canvas_width];for(var w=0;w>>1)&255;return a},c=function(t,e,r){var n,i,a,o,s=[],c=t.length;s[0]=4;for(var l=0;l>>x&255,x+=u.bits;m[w]=y>>>x&255}}if(16===u.bits){g=(p=new Uint32Array(u.decodePixels().buffer)).length,v=new Uint8Array(g*(32/u.pixelBitlength)*u.colors),m=new Uint8Array(g*(32/u.pixelBitlength)),b=u.colors>1,w=0,N=0;for(var _=0;w>>0&255,b&&(v[N++]=y>>>16&255,y=p[w++],v[N++]=y>>>0&255),m[_++]=y>>>16&255;c=8}o!==t.image_compression.NONE&&e()?(n=r(v,u.width*u.colors,u.colors,o),d=r(m,u.width,1,o)):(n=v,d=m,L=void 0)}if(3===u.colorType&&(s=this.color_spaces.INDEXED,f=u.palette,u.transparency.indexed)){var P=u.transparency.indexed,k=0;for(w=0,g=P.length;w=0;t--){for(var n=this.bottom_up?t:this.height-1-t,i=0;i>7-s&1];this.data[o+4*s]=c.blue,this.data[o+4*s+1]=c.green,this.data[o+4*s+2]=c.red,this.data[o+4*s+3]=255}0!==r&&(this.pos+=4-r)}},qe.prototype.bit4=function(){for(var t=Math.ceil(this.width/2),e=t%4,r=this.height-1;r>=0;r--){for(var n=this.bottom_up?r:this.height-1-r,i=0;i>4,c=15&a,u=this.palette[s];if(this.data[o]=u.blue,this.data[o+1]=u.green,this.data[o+2]=u.red,this.data[o+3]=255,2*i+1>=this.width)break;u=this.palette[c],this.data[o+4]=u.blue,this.data[o+4+1]=u.green,this.data[o+4+2]=u.red,this.data[o+4+3]=255}0!==e&&(this.pos+=4-e)}},qe.prototype.bit8=function(){for(var t=this.width%4,e=this.height-1;e>=0;e--){for(var r=this.bottom_up?e:this.height-1-e,n=0;n=0;r--){for(var n=this.bottom_up?r:this.height-1-r,i=0;i>5&e)/e*255|0,c=(a>>10&e)/e*255|0,u=a>>15?255:0,l=n*this.width*4+4*i;this.data[l]=c,this.data[l+1]=s,this.data[l+2]=o,this.data[l+3]=u}this.pos+=t}},qe.prototype.bit16=function(){for(var t=this.width%3,e=parseInt("11111",2),r=parseInt("111111",2),n=this.height-1;n>=0;n--){for(var i=this.bottom_up?n:this.height-1-n,a=0;a>5&r)/r*255|0,u=(o>>11)/e*255|0,l=i*this.width*4+4*a;this.data[l]=u,this.data[l+1]=c,this.data[l+2]=s,this.data[l+3]=255}this.pos+=t}},qe.prototype.bit24=function(){for(var t=this.height-1;t>=0;t--){for(var e=this.bottom_up?t:this.height-1-t,r=0;r=0;t--)for(var e=this.bottom_up?t:this.height-1-t,r=0;rn&&(i.push(t.slice(c,a)),s=0,c=a),s+=e[a],a++;return c!==a&&i.push(t.slice(c,a)),i},je=function(t,e,r){r||(r={});var n,i,a,o,s,c,u,l=[],h=[l],f=r.textIndent||0,d=0,p=0,g=t.split(" "),m=Fe.apply(this,[" ",r])[0];if(c=-1===r.lineIndent?g[0].length+2:r.lineIndent||0){var v=Array(c).join(" "),b=[];g.map((function(t){(t=t.split(/\s*\n/)).length>1?b=b.concat(t.map((function(t,e){return(e&&t.length?"\n":"")+t}))):b.push(t[0])})),g=b,c=Ie.apply(this,[v,r])}for(a=0,o=g.length;ae||y){if(p>e){for(s=Ce.apply(this,[n,i,e-(f+d),e]),l.push(s.shift()),l=[s.pop()];s.length;)h.push([s.shift()]);p=i.slice(n.length-(l[0]?l[0].length:0)).reduce((function(t,e){return t+e}),0)}else l=[n];h.push(l),f=p+c,d=m}else l.push(n),f+=d+p,d=m}return u=c?function(t,e){return(e?v:"")+t.join(" ")}:function(t){return t.join(" ")},h.map(u)},ke.splitTextToSize=function(t,e,r){var n,i=(r=r||{}).fontSize||this.internal.getFontSize(),a=function(t){if(t.widths&&t.kerning)return{widths:t.widths,kerning:t.kerning};var e=this.internal.getFont(t.fontName,t.fontStyle);return e.metadata.Unicode?{widths:e.metadata.Unicode.widths||{0:1},kerning:e.metadata.Unicode.kerning||{}}:{font:e.metadata,fontSize:this.internal.getFontSize(),charSpace:this.internal.getCharSpace()}}.call(this,r);n=Array.isArray(t)?t:String(t).split(/\r?\n/);var o=1*this.internal.scaleFactor*e/i;a.textIndent=r.textIndent?1*r.textIndent*this.internal.scaleFactor/i:0,a.lineIndent=r.lineIndent;var s,c,u=[];for(s=0,c=n.length;s1){for(h=0;h>")})),this.internal.viewerpreferences.isSubscribed=!0),this.internal.viewerpreferences.configuration=n,this}}(M.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(t){var e=function(){var t='',e=unescape(encodeURIComponent('')),r=unescape(encodeURIComponent(t)),n=unescape(encodeURIComponent(this.internal.__metadata__.metadata)),i=unescape(encodeURIComponent("")),a=unescape(encodeURIComponent("")),o=r.length+n.length+i.length+e.length+a.length;this.internal.__metadata__.metadata_object_number=this.internal.newObject(),this.internal.write("<< /Type /Metadata /Subtype /XML /Length "+o+" >>"),this.internal.write("stream"),this.internal.write(e+r+n+i+a),this.internal.write("endstream"),this.internal.write("endobj")},r=function(){this.internal.__metadata__.metadata_object_number&&this.internal.write("/Metadata "+this.internal.__metadata__.metadata_object_number+" 0 R")};t.addMetadata=function(t,n){return void 0===this.internal.__metadata__&&(this.internal.__metadata__={metadata:t,namespaceuri:n||"http://jspdf.default.namespaceuri/"},this.internal.events.subscribe("putCatalog",r),this.internal.events.subscribe("postPutResources",e)),this}}(M.API),function(t){var e=t.API,r=e.pdfEscape16=function(t,e){for(var r,n=e.metadata.Unicode.widths,i=["","0","00","000","0000"],a=[""],o=0,s=t.length;o=100&&(a+="\n"+n.length+" beginbfchar\n"+n.join("\n")+"\nendbfchar",n=[]),void 0!==t[e]&&null!==t[e]&&"function"==typeof t[e].toString&&(i=("0000"+t[e].toString(16)).slice(-4),e=("0000"+(+e).toString(16)).slice(-4),n.push("<"+e+"><"+i+">"));return n.length&&(a+="\n"+n.length+" beginbfchar\n"+n.join("\n")+"\nendbfchar\n"),a+="endcmap\nCMapName currentdict /CMap defineresource pop\nend\nend"};e.events.push(["putFont",function(e){!function(e){var r=e.font,i=e.out,a=e.newObject,o=e.putStream;if(r.metadata instanceof t.API.TTFFont&&"Identity-H"===r.encoding){for(var s=r.metadata.Unicode.widths,c=r.metadata.subset.encode(r.metadata.glyIdsUsed,1),u="",l=0;l>"),i("endobj");var p=a();i("<<"),i("/Type /Font"),i("/BaseFont /"+F(r.fontName)),i("/FontDescriptor "+d+" 0 R"),i("/W "+t.API.PDFObject.convert(s)),i("/CIDToGIDMap /Identity"),i("/DW 1000"),i("/Subtype /CIDFontType2"),i("/CIDSystemInfo"),i("<<"),i("/Supplement 0"),i("/Registry (Adobe)"),i("/Ordering ("+r.encoding+")"),i(">>"),i(">>"),i("endobj"),r.objectNumber=a(),i("<<"),i("/Type /Font"),i("/Subtype /Type0"),i("/ToUnicode "+f+" 0 R"),i("/BaseFont /"+F(r.fontName)),i("/Encoding /"+r.encoding),i("/DescendantFonts ["+p+" 0 R]"),i(">>"),i("endobj"),r.isAlreadyPutted=!0}}(e)}]);e.events.push(["putFont",function(e){!function(e){var r=e.font,i=e.out,a=e.newObject,o=e.putStream;if(r.metadata instanceof t.API.TTFFont&&"WinAnsiEncoding"===r.encoding){for(var s=r.metadata.rawData,c="",u=0;u>"),i("endobj"),r.objectNumber=a();for(var d=0;d>"),i("endobj"),r.isAlreadyPutted=!0}}(e)}]);var i=function(t){var e,n=t.text||"",i=t.x,a=t.y,o=t.options||{},s=t.mutex||{},c=s.pdfEscape,u=s.activeFontKey,l=s.fonts,h=u,f="",d=0,p="",g=l[h].encoding;if("Identity-H"!==l[h].encoding)return{text:n,x:i,y:a,options:o,mutex:s};for(p=n,h=u,Array.isArray(n)&&(p=n[0]),d=0;d","<","[","]","[","{","}","{","«","»","«","‹","›","‹","⁅","⁆","⁅","⁽","⁾","⁽","₍","₎","₍","≤","≥","≤","〈","〉","〈","﹙","﹚","﹙","﹛","﹜","﹛","﹝","﹞","﹝","﹤","﹥","﹤"],g=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)$/),m=!1,v=0;this.__bidiEngine__={};var b=function(t){var e=t.charCodeAt(),r=e>>8,n=d[r];return void 0!==n?u[256*n+(255&e)]:252===r||253===r?"AL":g.test(r)?"L":8===r?"R":"N"},y=function(t){for(var e,r=0;r=e.length||"EN"!==(c=o[s-1])&&"AN"!==c||"EN"!==(u=e[s+1])&&"AN"!==u?f="N":m&&(u="AN"),f=u===c?u:"N";break;case"ES":f="EN"===(c=s>0?o[s-1]:"B")&&s+10&&"EN"===o[s-1]){f="EN";break}if(m){f="N";break}for(l=s+1,h=e.length;l=1425&&d<=2303||64286===d;if(c=e[l],p&&("R"===c||"AL"===c)){f="R";break}}}f=s<1||"B"===(c=e[s-1])?"N":o[s-1];break;case"B":m=!1,r=!0,f=v;break;case"S":n=!0,f="N";break;case"LRE":case"RLE":case"LRO":case"RLO":case"PDF":m=!1;break;case"BN":f="N"}return f},N=function(t,e,r){var n=t.split("");return r&&L(n,r,{hiLevel:v}),n.reverse(),e&&e.reverse(),n.join("")},L=function(t,e,i){var a,o,s,c,u,d=-1,p=t.length,g=0,y=[],N=v?h:l,L=[];for(m=!1,r=!1,n=!1,o=0;o0)if(16===a){for(o=d;o-1){for(o=d;o=0&&"WS"===t[i];i--)e[i]=v}}(L,e,p)},A=function(t,e,n,i,a){if(!(a.hiLevel=t){for(c=h+1;c=t;)c++;for(u=h,s=c-1;u=0&&(t[i]=p[n+1])}(n,r,i),A(2,n,e,r,i),A(1,n,e,r,i),n.join("")};return this.__bidiEngine__.doBidiReorder=function(t,e,r){if(function(t,e){if(e)for(var r=0;r>16))&&(e=-(1+(65535^e))),this.italicAngle=+(e+"."+r)):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===(i=this.familyClass)||2===i||3===i||4===i||5===i||7===i,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")},t.prototype.characterToGlyph=function(t){var e;return(null!=(e=this.cmap.unicode)?e.codeMap[t]:void 0)||0},t.prototype.widthOfGlyph=function(t){var e;return e=1e3/this.head.unitsPerEm,this.hmtx.forGlyph(t).advance*e},t.prototype.widthOfString=function(t,e,r){var n,i,a,o;for(a=0,i=0,o=(t=""+t).length;0<=o?io;i=0<=o?++i:--i)n=t.charCodeAt(i),a+=this.widthOfGlyph(this.characterToGlyph(n))+r*(1e3/e)||0;return a*(e/1e3)},t.prototype.lineHeight=function(t,e){var r;return null==e&&(e=!1),r=e?this.lineGap:0,(this.ascender+r-this.decender)/1e3*t},t}();var Re,Te=function(){function t(t){this.data=null!=t?t:[],this.pos=0,this.length=this.data.length}return t.prototype.readByte=function(){return this.data[this.pos++]},t.prototype.writeByte=function(t){return this.data[this.pos++]=t},t.prototype.readUInt32=function(){return 16777216*this.readByte()+(this.readByte()<<16)+(this.readByte()<<8)+this.readByte()},t.prototype.writeUInt32=function(t){return this.writeByte(t>>>24&255),this.writeByte(t>>16&255),this.writeByte(t>>8&255),this.writeByte(255&t)},t.prototype.readInt32=function(){var t;return(t=this.readUInt32())>=2147483648?t-4294967296:t},t.prototype.writeInt32=function(t){return t<0&&(t+=4294967296),this.writeUInt32(t)},t.prototype.readUInt16=function(){return this.readByte()<<8|this.readByte()},t.prototype.writeUInt16=function(t){return this.writeByte(t>>8&255),this.writeByte(255&t)},t.prototype.readInt16=function(){var t;return(t=this.readUInt16())>=32768?t-65536:t},t.prototype.writeInt16=function(t){return t<0&&(t+=65536),this.writeUInt16(t)},t.prototype.readString=function(t){var e,r;for(r=[],e=0;0<=t?et;e=0<=t?++e:--e)r[e]=String.fromCharCode(this.readByte());return r.join("")},t.prototype.writeString=function(t){var e,r,n;for(n=[],e=0,r=t.length;0<=r?er;e=0<=r?++e:--e)n.push(this.writeByte(t.charCodeAt(e)));return n},t.prototype.readShort=function(){return this.readInt16()},t.prototype.writeShort=function(t){return this.writeInt16(t)},t.prototype.readLongLong=function(){var t,e,r,n,i,a,o,s;return t=this.readByte(),e=this.readByte(),r=this.readByte(),n=this.readByte(),i=this.readByte(),a=this.readByte(),o=this.readByte(),s=this.readByte(),128&t?-1*(72057594037927940*(255^t)+281474976710656*(255^e)+1099511627776*(255^r)+4294967296*(255^n)+16777216*(255^i)+65536*(255^a)+256*(255^o)+(255^s)+1):72057594037927940*t+281474976710656*e+1099511627776*r+4294967296*n+16777216*i+65536*a+256*o+s},t.prototype.writeLongLong=function(t){var e,r;return e=Math.floor(t/4294967296),r=4294967295&t,this.writeByte(e>>24&255),this.writeByte(e>>16&255),this.writeByte(e>>8&255),this.writeByte(255&e),this.writeByte(r>>24&255),this.writeByte(r>>16&255),this.writeByte(r>>8&255),this.writeByte(255&r)},t.prototype.readInt=function(){return this.readInt32()},t.prototype.writeInt=function(t){return this.writeInt32(t)},t.prototype.read=function(t){var e,r;for(e=[],r=0;0<=t?rt;r=0<=t?++r:--r)e.push(this.readByte());return e},t.prototype.write=function(t){var e,r,n,i;for(i=[],r=0,n=t.length;rn;r=0<=n?++r:--r)e={tag:t.readString(4),checksum:t.readInt(),offset:t.readInt(),length:t.readInt()},this.tables[e.tag]=e}return e.prototype.encode=function(e){var r,n,i,a,o,s,c,u,l,h,f,d,p;for(p in f=Object.keys(e).length,s=Math.log(2),l=16*Math.floor(Math.log(f)/s),a=Math.floor(l/s),u=16*f-l,(n=new Te).writeInt(this.scalarType),n.writeShort(f),n.writeShort(l),n.writeShort(a),n.writeShort(u),i=16*f,c=n.pos+i,o=null,d=[],e)for(h=e[p],n.writeString(p),n.writeInt(t(h)),n.writeInt(c),n.writeInt(h.length),d=d.concat(h),"head"===p&&(o=c),c+=h.length;c%4;)d.push(0),c++;return n.write(d),r=2981146554-t(n.data),n.pos=o+8,n.writeUInt32(r),n.data},t=function(t){var e,r,n,i;for(t=tr.call(t);t.length%4;)t.push(0);for(n=new Te(t),r=0,e=0,i=t.length;eh;s=0<=h?++e:--e)r.push(t.readUInt16());return r}(),t.pos+=2,p=function(){var e,r;for(r=[],s=e=0;0<=h?eh;s=0<=h?++e:--e)r.push(t.readUInt16());return r}(),c=function(){var e,r;for(r=[],s=e=0;0<=h?eh;s=0<=h?++e:--e)r.push(t.readUInt16());return r}(),u=function(){var e,r;for(r=[],s=e=0;0<=h?eh;s=0<=h?++e:--e)r.push(t.readUInt16());return r}(),n=(this.length-t.pos+this.offset)/2,o=function(){var e,r;for(r=[],s=e=0;0<=n?en;s=0<=n?++e:--e)r.push(t.readUInt16());return r}(),s=m=0,b=i.length;m=g;r=d<=g?++v:--v)0===u[s]?a=r+c[s]:0!==(a=o[u[s]/2+(r-d)-(h-s)]||0)&&(a+=c[s]),this.codeMap[r]=65535&a}t.pos=l}return t.encode=function(t,e){var r,n,i,a,o,s,c,u,l,h,f,d,p,g,m,v,b,y,w,N,L,A,x,S,_,P,k,F,I,C,j,O,B,M,E,q,D,R,T,U,z,H,W,V,G,Y;switch(F=new Te,a=Object.keys(t).sort((function(t,e){return t-e})),e){case"macroman":for(p=0,g=function(){var t=[];for(d=0;d<256;++d)t.push(0);return t}(),v={0:0},i={},I=0,B=a.length;I=32768)for(s.push(0),N.push(2*(f.length+x-d)),n=O=_;_<=u?O<=u:O>=u;n=_<=u?++O:--O)f.push(r[n].new);else s.push(k-_),N.push(0)}for(F.writeUInt16(3),F.writeUInt16(1),F.writeUInt32(12),F.writeUInt16(4),F.writeUInt16(16+8*x+2*f.length),F.writeUInt16(0),F.writeUInt16(S),F.writeUInt16(A),F.writeUInt16(h),F.writeUInt16(L),z=0,q=l.length;zn;r=0<=n?++r:--r)e=new Ve(t,this.offset),this.tables.push(e),e.isUnicode&&null==this.unicode&&(this.unicode=e);return!0},e.encode=function(t,e){var r,n;return null==e&&(e="macroman"),r=Ve.encode(t,e),(n=new Te).writeUInt16(0),n.writeUInt16(1),r.table=n.data.concat(r.subtable),r},e}(Re),Ye=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="hhea",e.prototype.parse=function(t){return t.pos=this.offset,this.version=t.readInt(),this.ascender=t.readShort(),this.decender=t.readShort(),this.lineGap=t.readShort(),this.advanceWidthMax=t.readShort(),this.minLeftSideBearing=t.readShort(),this.minRightSideBearing=t.readShort(),this.xMaxExtent=t.readShort(),this.caretSlopeRise=t.readShort(),this.caretSlopeRun=t.readShort(),this.caretOffset=t.readShort(),t.pos+=8,this.metricDataFormat=t.readShort(),this.numberOfMetrics=t.readUInt16()},e}(Re),Je=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="OS/2",e.prototype.parse=function(t){if(t.pos=this.offset,this.version=t.readUInt16(),this.averageCharWidth=t.readShort(),this.weightClass=t.readUInt16(),this.widthClass=t.readUInt16(),this.type=t.readShort(),this.ySubscriptXSize=t.readShort(),this.ySubscriptYSize=t.readShort(),this.ySubscriptXOffset=t.readShort(),this.ySubscriptYOffset=t.readShort(),this.ySuperscriptXSize=t.readShort(),this.ySuperscriptYSize=t.readShort(),this.ySuperscriptXOffset=t.readShort(),this.ySuperscriptYOffset=t.readShort(),this.yStrikeoutSize=t.readShort(),this.yStrikeoutPosition=t.readShort(),this.familyClass=t.readShort(),this.panose=function(){var e,r;for(r=[],e=0;e<10;++e)r.push(t.readByte());return r}(),this.charRange=function(){var e,r;for(r=[],e=0;e<4;++e)r.push(t.readInt());return r}(),this.vendorID=t.readString(4),this.selection=t.readShort(),this.firstCharIndex=t.readShort(),this.lastCharIndex=t.readShort(),this.version>0&&(this.ascent=t.readShort(),this.descent=t.readShort(),this.lineGap=t.readShort(),this.winAscent=t.readShort(),this.winDescent=t.readShort(),this.codePageRange=function(){var e,r;for(r=[],e=0;e<2;e=++e)r.push(t.readInt());return r}(),this.version>1))return this.xHeight=t.readShort(),this.capHeight=t.readShort(),this.defaultChar=t.readShort(),this.breakChar=t.readShort(),this.maxContext=t.readShort()},e}(Re),Xe=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="post",e.prototype.parse=function(t){var e,r,n;switch(t.pos=this.offset,this.format=t.readInt(),this.italicAngle=t.readInt(),this.underlinePosition=t.readShort(),this.underlineThickness=t.readShort(),this.isFixedPitch=t.readInt(),this.minMemType42=t.readInt(),this.maxMemType42=t.readInt(),this.minMemType1=t.readInt(),this.maxMemType1=t.readInt(),this.format){case 65536:break;case 131072:var i;for(r=t.readUInt16(),this.glyphNameIndex=[],i=0;0<=r?ir;i=0<=r?++i:--i)this.glyphNameIndex.push(t.readUInt16());for(this.names=[],n=[];t.posr;i=0<=r?++e:--e)n.push(t.readUInt32());return n}.call(this)}},e}(Re),Ke=function(t,e){this.raw=t,this.length=t.length,this.platformID=e.platformID,this.encodingID=e.encodingID,this.languageID=e.languageID},Ze=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="name",e.prototype.parse=function(t){var e,r,n,i,a,o,s,c,u,l,h;for(t.pos=this.offset,t.readShort(),e=t.readShort(),o=t.readShort(),r=[],i=0;0<=e?ie;i=0<=e?++i:--i)r.push({platformID:t.readShort(),encodingID:t.readShort(),languageID:t.readShort(),nameID:t.readShort(),length:t.readShort(),offset:this.offset+o+t.readShort()});for(s={},i=u=0,l=r.length;uo;e=0<=o?++e:--e)this.metrics.push({advance:t.readUInt16(),lsb:t.readInt16()});for(n=this.file.maxp.numGlyphs-this.file.hhea.numberOfMetrics,this.leftSideBearings=function(){var r,i;for(i=[],e=r=0;0<=n?rn;e=0<=n?++r:--r)i.push(t.readInt16());return i}(),this.widths=function(){var t,e,r,n;for(n=[],t=0,e=(r=this.metrics).length;tn;e=0<=n?++a:--a)s.push(this.widths.push(r));return s},e.prototype.forGlyph=function(t){return t in this.metrics?this.metrics[t]:{advance:this.metrics[this.metrics.length-1].advance,lsb:this.leftSideBearings[t-this.metrics.length]}},e}(Re),tr=[].slice,er=function(t){function e(){return e.__super__.constructor.apply(this,arguments)}return He(e,t),e.prototype.tag="glyf",e.prototype.parse=function(){return this.cache={}},e.prototype.glyphFor=function(t){var e,r,n,i,a,o,s,c,u,l;return t in this.cache?this.cache[t]:(i=this.file.loca,e=this.file.contents,r=i.indexOf(t),0===(n=i.lengthOf(t))?this.cache[t]=null:(e.pos=this.offset+r,a=(o=new Te(e.read(n))).readShort(),c=o.readShort(),l=o.readShort(),s=o.readShort(),u=o.readShort(),this.cache[t]=-1===a?new nr(o,c,l,s,u):new rr(o,a,c,l,s,u),this.cache[t]))},e.prototype.encode=function(t,e,r){var n,i,a,o,s;for(a=[],i=[],o=0,s=e.length;o0&&(n+=s)}for(var c=new Array(4*r.length),u=0;u>8,c[4*u+1]=(16711680&r[u])>>16,c[4*u]=(4278190080&r[u])>>24;return c},e}(Re),ar=function(){function t(t){this.font=t,this.subset={},this.unicodes={},this.next=33}return t.prototype.generateCmap=function(){var t,e,r,n,i;for(e in n=this.font.cmap.tables[0].codeMap,t={},i=this.subset)r=i[e],t[e]=n[r];return t},t.prototype.glyphsFor=function(t){var e,r,n,i,a,o,s;for(n={},a=0,o=t.length;a0)for(i in s=this.glyphsFor(e))r=s[i],n[i]=r;return n},t.prototype.encode=function(t,e){var r,n,i,a,o,s,c,u,l,h,f,d,p,g,m;for(n in r=Ge.encode(this.generateCmap(),"unicode"),a=this.glyphsFor(t),f={0:0},m=r.charMap)f[(s=m[n]).old]=s.new;for(d in h=r.maxGlyphID,a)d in f||(f[d]=h++);return u=function(t){var e,r;for(e in r={},t)r[t[e]]=e;return r}(f),l=Object.keys(u).sort((function(t,e){return t-e})),p=function(){var t,e,r;for(r=[],t=0,e=l.length;t>"),a.join("\n")}return""+r},e}(),t.AcroForm=xt,t.AcroFormAppearance=Lt,t.AcroFormButton=gt,t.AcroFormCheckBox=yt,t.AcroFormChoiceField=ht,t.AcroFormComboBox=dt,t.AcroFormEditBox=pt,t.AcroFormListBox=ft,t.AcroFormPasswordField=Nt,t.AcroFormPushButton=mt,t.AcroFormRadioButton=vt,t.AcroFormTextField=wt,t.GState=C,t.ShadingPattern=O,t.TilingPattern=B,t.default=M,t.jsPDF=M,Object.defineProperty(t,"__esModule",{value:!0})})); //# sourceMappingURL=jspdf.umd.min.js.map `);w.document.close();} function printDoc(id){const d=doc(id);printHTML(d.no,docBody(d),d.locId);log("Printed "+d.no);save();} function wordFile(name,body){const html=`${letterhead()}${body}${lfooter()}`;dl(String(name).replace(/[^\w\- ]/g,"")+".doc",new Blob(["\ufeff"+html],{type:"application/msword"}));} function emailDoc(id){const d=doc(id),c=cust(d.custId);if(!c||!c.email){toast("This customer has no email. Add one on the customer record.");return;} const body=`Hello ${c.first||""},\n\nHere is your ${d.type} ${d.no} for your ${vname(veh(d.vehId))}. The total is ${money(totals(d).total)}${d.type==="invoice"?" and the balance due is "+money(totals(d).due):""}.\n\n${S.settings.footer}\n${S.settings.name}\n${S.settings.phone}`; openModal(`

Review before sending

Demo: Send opens your email app. Live: the server sends from the shop address with the PDF attached and saves a copy on the customer.

`);} function sendMail(id){const d=doc(id);location.href="mailto:"+encodeURIComponent($("#em_to").value)+"?subject="+encodeURIComponent($("#em_sub").value)+"&body="+encodeURIComponent($("#em_body").value);if(d.status==="draft")d.status="sent";log("Emailed "+d.no);save();closeModal();render();} /* ---------- dictation and notes ---------- */ function dictate(targetId,btn){const SR=window.SpeechRecognition||window.webkitSpeechRecognition;if(!SR){toast("This browser has no voice typing. Use Chrome, Edge, or Safari, or the microphone key on the phone keyboard.");return;} if(recog){stopDictation();return;}const el=document.getElementById(targetId),start=el.value?el.value+" ":"";let fin=""; recog=new SR();recog.lang="en-US";recog.continuous=true;recog.interimResults=true; recog.onresult=e=>{let it="";for(let i=e.resultIndex;i{toast("Voice typing stopped: "+e.error+". Allow the microphone.");stopDictation();};recog.onend=()=>{if(recog)stopDictation();}; recog.start();btn.textContent="Stop";btn.classList.add("rec");recog._btn=btn;toast("Listening. Press Stop when done.");} function stopDictation(){if(!recog)return;const r=recog;recog=null;try{r.stop();}catch(_){}if(r._btn){r._btn.textContent="Dictate";r._btn.classList.remove("rec");}} function noteModal(){openModal(`

Voice note

Press Dictate and talk through what the customer describes. Edit, then save.

`);} function saveNote(){const t=$("#nt_t").value.trim();if(!t){toast("The note is empty.");return;}const jid=$("#nt_j").value,j=jid?S.jobs.find(x=>x.id===jid):null;S.notes.unshift({id:uid(),t:new Date().toISOString(),by:me.id,text:t,jobId:jid,vehId:j?j.vehId:""});if(j)j.events.push({t:new Date().toISOString(),by:me.username,msg:"Voice note: "+t.slice(0,120)});log("Saved voice note");save();closeModal();render();toast("Note saved.");} /* ---------- documents ---------- */ const TEMPLATES={blank:["Blank document",""],auth:["Repair authorization","

Repair authorization

I, ______________________, authorize the repair work on estimate number ________ for my vehicle, VIN ______________________. The shop will contact me before doing work beyond the approved amount.

Signature: ______________________ Date: __________

"],release:["Vehicle release","

Vehicle release

The vehicle below was returned to the owner on __________.

Vehicle: ______________________ VIN: ______________________

Owner signature: ______________________

"],warranty:["Warranty letter","

Repair warranty

Parts and labor on invoice ________ are covered for ____ months or ______ miles, whichever comes first. The warranty does not cover accident, abuse, or outside repairs.

"],storage:["Storage fee notice","

Storage fee notice

Your vehicle has been ready since __________. Storage of $_____ per day begins on __________.

"],asis:["As-is used car disclosure","

Used vehicle sold as is

Vehicle: ______________________ VIN: ______________________. The buyer accepts the vehicle as is, with no warranty from the dealer, except as stated here: ______________________.

Buyer signature: ______________________ Date: __________

"]}; V.documents=()=>`
${Object.entries(TEMPLATES).filter(([k])=>k!=="asis"||feat("dealer")).map(([k,v])=>``).join("")}
${S.letters.map(l=>``).join("")||``}
TitleUpdatedBy
${esc(l.title)}${fmtD(l.date)}${esc(l.by)}
No documents yet. Start from a template. Every document prints with the letterhead.
`; function letterModal(id,tpl){const l=id?S.letters.find(x=>x.id===id):{title:TEMPLATES[tpl][0],html:TEMPLATES[tpl][1]}; openModal(`

${esc(l.title)}

${letterhead()}
${l.html}
${id&&canDel()?``:""}
`);} function saveLetter(id){let l=id?S.letters.find(x=>x.id===id):null;if(!l){l={id:uid()};S.letters.unshift(l);}Object.assign(l,{title:$("#lt_t").value.trim()||"Untitled",html:$("#lt_h").innerHTML,date:today(),by:me.username});log("Saved document "+l.title);save();closeModal();render();toast("Document saved.");} /* ---------- AI assistant ---------- */ const OBD={P0011:"Intake camshaft timing over-advanced, bank 1",P0016:"Crankshaft and camshaft position correlation, bank 1",P0101:"Mass air flow sensor range or performance",P0102:"Mass air flow sensor low input",P0113:"Intake air temperature sensor high input",P0117:"Engine coolant temperature sensor low input",P0118:"Engine coolant temperature sensor high input",P0121:"Throttle position sensor range or performance",P0128:"Coolant temperature below thermostat regulating temperature",P0130:"O2 sensor circuit, bank 1 sensor 1",P0131:"O2 sensor low voltage, bank 1 sensor 1",P0133:"O2 sensor slow response, bank 1 sensor 1",P0135:"O2 sensor heater circuit, bank 1 sensor 1",P0141:"O2 sensor heater circuit, bank 1 sensor 2",P0171:"System too lean, bank 1",P0172:"System too rich, bank 1",P0174:"System too lean, bank 2",P0175:"System too rich, bank 2",P0300:"Random or multiple cylinder misfire",P0301:"Cylinder 1 misfire",P0302:"Cylinder 2 misfire",P0303:"Cylinder 3 misfire",P0304:"Cylinder 4 misfire",P0305:"Cylinder 5 misfire",P0306:"Cylinder 6 misfire",P0325:"Knock sensor 1 circuit, bank 1",P0335:"Crankshaft position sensor A circuit",P0340:"Camshaft position sensor A circuit, bank 1",P0401:"EGR flow insufficient",P0402:"EGR flow excessive",P0420:"Catalyst efficiency below threshold, bank 1",P0430:"Catalyst efficiency below threshold, bank 2",P0440:"EVAP system malfunction",P0441:"EVAP incorrect purge flow",P0442:"EVAP small leak detected",P0446:"EVAP vent control circuit",P0455:"EVAP large leak detected",P0456:"EVAP very small leak detected",P0500:"Vehicle speed sensor",P0505:"Idle air control system",P0506:"Idle speed lower than expected",P0507:"Idle speed higher than expected",P0562:"System voltage low",P0606:"Control module processor fault",P0700:"Transmission control system fault",P0715:"Input or turbine speed sensor circuit",P0730:"Incorrect gear ratio",P0740:"Torque converter clutch circuit",P0741:"Torque converter clutch stuck off or performance",P0750:"Shift solenoid A",U0100:"Lost communication with ECM/PCM",U0121:"Lost communication with ABS module",C0035:"Left front wheel speed sensor circuit"}; const AI_PRESETS={off:["Off (built-in code lookup only)","",""],openrouter:["OpenRouter (has free models)","https://openrouter.ai/api/v1/chat/completions","pick a model ending in :free"],groq:["Groq (free tier)","https://api.groq.com/openai/v1/chat/completions","llama-3.3-70b-versatile"],deepseek:["DeepSeek (low cost, not free)","https://api.deepseek.com/chat/completions","deepseek-chat"],ollama:["Ollama on your own computer (free)","http://localhost:11434/v1/chat/completions","llama3.1"],custom:["Other OpenAI-compatible service","",""]}; V.ai=()=>{const a=S.settings.ai;return `

Provider: ${esc(AI_PRESETS[a.provider][0])}. Type a code like P0420 or describe a symptom. Treat answers as a starting point and confirm with factory service information before replacing parts.

${feat("dictation")?``:""}
`;}; function drawChat(){const c=$("#chat");if(!c)return;c.innerHTML=aiMsgs.map(m=>`
${esc(m.content)}
`).join("")||`

No questions yet.

`;c.scrollTop=c.scrollHeight;} function offlineAnswer(q){const codes=q.toUpperCase().match(/[PBCU][0-9]{4}/g)||[];if(codes.length)return codes.map(c=>c+": "+(OBD[c]||"Not in the built-in list. Turn on an AI provider or check your service information.")).join("\n");return "The AI provider is off, so only the built-in trouble code list works. Type a code like P0300, or ask the administrator to turn on a provider in Admin panel, AI assistant.";} async function aiSend(){const q=$("#ai_q").value.trim();if(!q)return;aiMsgs.push({role:"user",content:q});$("#ai_q").value="";drawChat();const a=S.settings.ai; if(a.provider==="off"||!a.endpoint){aiMsgs.push({role:"assistant",content:offlineAnswer(q)});drawChat();return;} const v=veh($("#ai_v").value),sys="You assist technicians at an independent auto repair shop in New Jersey. Give likely causes ranked by probability, quickest confirming tests, and safety warnings. Say when OEM service information must confirm. Be brief."+(v?` Vehicle: ${vname(v)}, engine ${v.engine||"unknown"}, VIN ${v.vin||"unknown"}, ${v.miles||"?"} miles.`:""); aiMsgs.push({role:"assistant",content:"Thinking..."});drawChat(); try{const r=await fetch(a.endpoint,{method:"POST",headers:Object.assign({"Content-Type":"application/json"},a.key?{Authorization:"Bearer "+a.key}:{}),body:JSON.stringify({model:a.model,messages:[{role:"system",content:sys}].concat(aiMsgs.slice(0,-1).slice(-10))})});if(!r.ok)throw new Error("the service answered "+r.status);aiMsgs[aiMsgs.length-1].content=(await r.json()).choices[0].message.content;} catch(e){aiMsgs[aiMsgs.length-1].content="Could not reach the AI service ("+e.message+"). Check provider, model, and key in Admin panel. Some services refuse calls straight from a browser; the server version routes them through the server.";}drawChat();} /* ---------- CSV import/export ---------- */ function parseCSV(t){const rows=[];let r=[],f="",q=false;for(let i=0;ix.some(v=>v.trim()));} const csvCell=v=>{v=String(v==null?"":v);return /[",\n]/.test(v)?'"'+v.replace(/"/g,'""')+'"':v;}; function exportCSV(key){const E=ENT[key],fs=E.fields.filter(f=>!f.pii||seePII());const rows=[fs.map(f=>f.k)].concat(S[key].map(r=>fs.map(f=>f.t==="ref"?fieldVal(f,r):r[f.k])));dl(key+".csv",new Blob([rows.map(r=>r.map(csvCell).join(",")).join("\n")],{type:"text/csv"}));log("Exported "+key);save();} function importCSV(inp,key){const file=inp.files[0];if(!file)return;readRows(file).then(rows=>{if(rows.length<2){toast("That file has no data rows.");return;}const h=rows[0].map(x=>x.trim().toLowerCase());let n=0,dup=0; if(key==="customers"){const ix=k=>h.findIndex(x=>x.includes(k)),fi=ix("first"),li=ix("last"),ni=h.findIndex(x=>x==="name"||x==="full name"),pi=ix("phone"),ei=ix("mail"),ai=ix("addr"),ci=ix("city"),si=h.findIndex(x=>x==="state"),zi=ix("zip"); rows.slice(1).forEach(r=>{let first=fi>=0?r[fi]:"",last=li>=0?r[li]:"";if(!first&&!last&&ni>=0){const p=(r[ni]||"").trim().split(/\s+/);first=p.shift()||"";last=p.join(" ");}const email=ei>=0?(r[ei]||"").trim():"",phone=pi>=0?(r[pi]||"").trim():"";if(!first&&!last&&!email&&!phone)return; if(S.customers.some(c=>(email&&c.email&&c.email.toLowerCase()===email.toLowerCase())||(phone&&digits(c.phone)===digits(phone)))){dup++;return;} S.customers.push({id:uid(),first:(first||"").trim(),last:(last||"").trim(),phone,phone2:"",email,address:ai>=0?r[ai]:"",city:ci>=0?r[ci]:"",state:si>=0?r[si]:"",zip:zi>=0?r[zi]:"",pref:"Text",dlNo:"",dlState:"",dlExp:"",tags:"Imported",notes:"",created:today()});n++;});} else{const E=ENT[key];rows.slice(1).forEach(r=>{const o={id:uid()};E.fields.forEach(f=>{const i=h.indexOf(f.k)>=0?h.indexOf(f.k):h.indexOf(f.l.toLowerCase());if(i>=0)o[f.k]=f.t==="money"||f.t==="num"?+String(r[i]).replace(/[$,]/g,"")||0:r[i];});if(E.loc&&!o.locId)o.locId=defLoc();S[key].push(o);n++;});} log("Imported "+n+" "+key);save();render();toast(`Imported ${n}. Skipped ${dup} duplicates.`);}).catch(e=>toast("Could not read that file: "+e.message));} /* ---------- admin ---------- */ V.admin=()=>{const tabs=[["users","Users"],["locations","Locations"],["roles","Roles"],["features","Features"],["branding","Name, logo, letterhead"],["themes","Themes"],["ai","AI assistant"],["data","Import and export"],["health","System health"],["security","Security"],["connections","Connections and API"],["audit","Activity log"],["about","About Urbnix"]]; return `
${tabs.map(t=>``).join("")}
`+A[adminTab]();}; const A={}; A.users=()=>`
${S.users.length} users. Each person signs in with their own account and lands on their own dashboard.
${S.users.map(u=>``).join("")}
UsernameNameRoleLocationsStatus
${esc(u.username)}${esc(u.display)}${esc(ROLES[u.role])}${ALL_LOC.includes(u.role)||!u.locIds||!u.locIds.length?"All":u.locIds.map(locName).map(esc).join(", ")}${esc(u.status)} ${u.id!==me.id?` `:""}
`; function userModal(id){const u=id?user(id):{username:"",display:"",role:"tech",locIds:[],email:"",phone:""}; openModal(`

${id?"Edit "+esc(u.username):"Create user"}

${id?"":``}

Locations this person works at (owners and administrators see all):

${S.locations.map(l=>``).join("")}

`);} async function saveUser(id){const locs=[...document.querySelectorAll(".us_loc:checked")].map(x=>x.value); if(id){const u=user(id);u.display=$("#us_d").value.trim()||u.display;if(id!==me.id)u.role=$("#us_r").value;u.email=$("#us_e").value.trim();u.phone=$("#us_ph").value.trim();u.locIds=locs;log("Edited user "+u.username);} else{const n=$("#us_u").value.trim().toLowerCase();if(!/^[a-z0-9._-]{3,30}$/.test(n)){$("#userr").textContent="Username: 3 to 30 letters, numbers, dot, dash, or underscore.";return;}if(S.users.some(u=>u.username===n)){$("#userr").textContent="That username is taken.";return;}const p=$("#us_p").value;if(p.length<8){$("#userr").textContent="Password needs 8 or more characters.";return;} S.users.push({id:uid(),username:n,display:$("#us_d").value.trim()||n,role:$("#us_r").value,status:"active",locIds:locs,email:$("#us_e").value.trim(),phone:$("#us_ph").value.trim(),hash:await sha(n+":"+p),created:today()});log("Created user "+n);} save();closeModal();render();toast("User saved.");} async function resetPw(id){const u=user(id),p="Shop-"+Math.random().toString(36).slice(2,8);u.hash=await sha(u.username+":"+p);u.fails=0;u.lockUntil=0;if(u.username==="admin")S.demoMode=false;log("Reset password for "+u.username);save();openModal(`

New password for ${esc(u.username)}

Temporary password: ${esc(p)}

Give it to the person directly. It is not shown again.

`);} function toggleUser(id){const u=user(id);if(u.role==="admin"&&u.status==="active"&&S.users.filter(x=>x.role==="admin"&&x.status==="active").length<2){toast("Keep at least one active administrator.");return;}u.status=u.status==="active"?"suspended":"active";log((u.status==="active"?"Reactivated ":"Suspended ")+u.username);save();render();} function delUser(id){const u=user(id);if(u.role==="admin"&&S.users.filter(x=>x.role==="admin").length<2){toast("Keep at least one administrator.");return;}if(!confirm("Delete user "+u.username+"? Their past work stays in the records."))return;S.users=S.users.filter(x=>x.id!==id);S.jobs.forEach(j=>{if(j.techId===id)j.techId="";});log("Deleted user "+u.username);save();render();} A.locations=()=>`
Each franchise location gets its own repair board, stock, invoices, and letterhead address. Customers are shared across all locations.
${listView("locations")}`; A.roles=()=>`
${Object.values(ROLES).map(r=>``).join("")}${MODULES.map(m=>`${Object.keys(ROLES).map(r=>``).join("")}`).join("")} ${Object.keys(ROLES).map(r=>``).join("")}${Object.keys(ROLES).map(r=>``).join("")}${Object.keys(ROLES).map(r=>``).join("")}${Object.keys(ROLES).map(r=>``).join("")}
Section${esc(r)}
${esc(m.label)}${PERMS[r].includes(m.id)?'Yes':""}
See money and margins${MONEY_ROLES.includes(r)?'Yes':""}
See license and registration numbers${SEE_PII.includes(r)?'Yes':""}
Change prices${EDIT_PRICES.includes(r)?'Yes':""}
Delete records${DELETERS.includes(r)?'Yes':""}

In the live version the administrator can edit this table. The demo shows the starting setup.

`; A.features=()=>`

Turn a section off and it disappears for everyone, menu item and buttons included. Data is kept. A tire-only shop can turn off car sales; a dealer can turn off appointments.

${FEATURES.map(([k,v])=>`
${v}
`).join("")}
`; A.branding=()=>{const s=S.settings,h=s.hours,sec=s.security;return `

Business details

Billing and fees

Shop hours and security

Logo, login photo, letterhead

Preview updates as you type. Saving applies it everywhere.

${s.logo?``:""}${s.logo!==ORIG_LOGO?``:""}
${letterhead()}

Document content

${lfooter()}
`;}; function setLoginBg(inp){const f=inp.files[0];if(!f)return;shrinkImage(f).then(d=>{S.settings.loginBg=d;S.settings.loginBgKind="upload";log("Changed login photo");save();render();toast("Login photo updated.");});} function setLogo(inp){const f=inp.files[0];if(!f)return;const r=new FileReader();r.onload=()=>{const img=new Image();img.onload=()=>{const sc=Math.min(1,400/Math.max(img.width,img.height)),cv=document.createElement("canvas");cv.width=Math.round(img.width*sc);cv.height=Math.round(img.height*sc);cv.getContext("2d").drawImage(img,0,0,cv.width,cv.height);S.settings.logo=S.settings.logoUpload=cv.toDataURL("image/png");S.settings.logoMode="upload";log("Changed logo");save();render();toast("Logo updated everywhere.");};img.src=r.result;};r.readAsDataURL(f);} function saveBrand(){const s=S.settings,n=k=>{const v=parseFloat($(k).value);return isNaN(v)?0:v;}; if($("#br_ho").value>=$("#br_hc").value){toast("Closing time must be after opening time.");return;} Object.assign(s,{name:$("#br_n").value.trim()||s.name,orgName:$("#br_o").value.trim(),address:$("#br_a").value.trim(),phone:$("#br_p").value.trim(),email:$("#br_e").value.trim(),footer:$("#br_f").value.trim(),tax:n("#br_t"),suppliesPct:n("#br_sp"),suppliesCap:$("#br_sc").value.trim()===""?"":n("#br_sc"),envFee:n("#br_ef"),laborRate:n("#br_lr"),rateEasy:n("#br_re"),rateMed:n("#br_rm"),rateHard:n("#br_rh"),docFee:n("#br_df"),taxLabor:$("#br_tl").checked,tradeCredit:$("#br_tc").checked}); s.hours={open:$("#br_ho").value,close:$("#br_hc").value};s.security={idleMins:Math.max(0,n("#br_im")),maxTries:Math.max(3,n("#br_mt")||5),lockMins:Math.max(1,n("#br_lm")||10)}; s.logoMode=$("#br_logo").value;s.logoColor=$("#br_logoc").value;s.logoLayout=$("#br_logol").value;s.loginBgKind=$("#br_bg").value;applyLogo().then(()=>{log("Updated business name, logo, billing, and security settings");save();render();toast("Saved. The name and logo now show everywhere, including invoices and PDFs.");});} const tprev=t=>`
`; A.themes=()=>{const t=S.settings.theme;return `${me&&me.theme&&THEMES[me.theme]?`
You are looking at your personal theme (${esc(THEMES[me.theme].name)}). Picking a shop theme below switches you back to it.
`:""}

Theme for everyone

Click a theme and it applies right away, on every screen and device.

${Object.entries(THEMES).map(([k,th])=>``).join("")}

Fine tuning

Preview

${kpi("Vehicles in the shop",7,"br")}${kpi("Late",1,"bad")}
Paid Late
Lift 1
2018 Honda Accord
In repair
`;}; A.ai=()=>{const a=S.settings.ai;return `

Demo: the key sits in this browser. Live: the key stays on the server and staff never see it.

`;}; A.data=()=>`

Excel (opens in LibreOffice Calc and Excel)

Import reads the first sheet of an Excel, LibreOffice, or CSV file. Duplicates by phone or email are skipped.

${["customers","vehicles","tires","vendors","pricebook"].map(k=>``).join("")}

Full backup

Everything in the system, all locations. ${storageMode==="server"?"The shop computer also keeps automatic copies in the data\\backups folder.":"Data lives in this browser only, so download a backup weekly."}

CSV files

${["customers","vehicles","parts","tires","vendors","pricebook","appts"].map(k=>``).join("")}

Start over

Erase all data and reload the sample shop. Download a backup first.

`; function restore(inp){const f=inp.files[0];if(!f)return;if(!confirm("Replace everything with this backup? Download a backup of the current data first."))return;const r=new FileReader();r.onload=async()=>{try{const d=JSON.parse(r.result),keep=SYNC.on?S.users.find(u=>u.username==="admin"):null; if(d.v===4&&d.users&&d.settings){S=d;}else if(d.customers&&!d.v){S=await seed();migrateOriginal(d);}else throw new Error("this is not a backup from this system or the original Shop Manager"); normalize();if(keep)await restoreGuard(keep);log("Restored backup");save();me=null;render();toast("Backup restored. Sign in again.");}catch(e){toast("Could not restore: "+e.message);}};r.readAsText(f);} async function resetAll(){if(!confirm(SYNC.on?"Erase every customer, vehicle, and invoice for this shop? Download a backup first.":"Erase all data in this demo?"))return;const keep=SYNC.on?S.users.find(u=>u.username==="admin"):null;localStorage.removeItem(KEY);S=await seed();normalize();if(keep){cleanStart(S);S.users[0].hash=keep.hash;S.demoMode=false;}save();me=null;render();} function dupCustomers(){const groups={};S.customers.forEach(c=>{[digits(c.phone),(c.email||"").toLowerCase()].filter(k=>k&&k.length>3).forEach(k=>{(groups[k]=groups[k]||new Set()).add(c.id);});});return Object.values(groups).filter(g=>g.size>1).map(g=>[...g]);} A.health=()=>{const dups=dupCustomers();return `

System check

Tests storage, links between records, online services, and phone features. Repair data fixes broken links.

Possible duplicate customers (${dups.length})

${dups.map(g=>`
${g.map(id=>esc(cname(cust(id))+" "+cust(id).phone)).join(" and ")}
`).join("")||`

None found.

`}

Recent errors (${S.errors.length})

${S.errors.slice(0,30).map(e=>`
${new Date(e.t).toLocaleString()} ${esc(e.msg)}
`).join("")||`

No errors recorded.

`}
`;}; function mergeCust(keep,rest){rest.split(",").forEach(id=>{S.vehicles.forEach(v=>{if(v.custId===id)v.custId=keep;});S.docs.forEach(d=>{if(d.custId===id)d.custId=keep;});S.jobs.forEach(j=>{if(j.custId===id)j.custId=keep;});S.appts.forEach(a=>{if(a.custId===id)a.custId=keep;});S.deals.forEach(d=>{if(d.buyerId===id)d.buyerId=keep;});S.lot.forEach(l=>{if(l.sellerId===id)l.sellerId=keep;});S.files.forEach(f=>{if(f.custId===id)f.custId=keep;});S.customers=S.customers.filter(c=>c.id!==id);});log("Merged duplicate customers into "+cname(cust(keep)));save();render();toast("Merged. All vehicles and invoices now sit on one record.");} async function runHealth(){const out=[],ok=(b,t)=>out.push(`
${b?'OK':'Check'} ${t}
`); const size=JSON.stringify(S).length;let quota=0;try{quota=(await navigator.storage.estimate()).quota||0;}catch(e){}ok(storageMode!=="local"||!quota||size!cust(d.custId)).length,ov=S.vehicles.filter(v=>!cust(v.custId)).length,oj=S.jobs.filter(j=>!veh(j.vehId)).length,bf=S.docs.reduce((n,d)=>n+(d.files||[]).filter(f=>!S.files.some(x=>x.id===f)).length,0),nl=["jobs","docs","appts","parts","tires","lot"].reduce((n,k)=>n+S[k].filter(r=>r.locId&&!byId("locations",r.locId)).length,0); ok(!od,`${od} documents without a customer`);ok(!ov,`${ov} vehicles without an owner`);ok(!oj,`${oj} jobs without a vehicle`);ok(!bf,`${bf} missing file links`);ok(!nl,`${nl} records pointing to a deleted location`);ok(!dupCustomers().length,`${dupCustomers().length} possible duplicate customers`); ok(S.users.some(u=>u.role==="admin"&&u.status==="active"),"At least one active administrator");ok(!!(window.crypto&&crypto.subtle),"Secure password hashing available");ok(!!(window.SpeechRecognition||window.webkitSpeechRecognition),"Voice typing available in this browser");ok("BarcodeDetector" in window,"VIN barcode reading available (Chrome on Android)"); try{ok((await fetch("https://vpic.nhtsa.dot.gov/api/vehicles/GetMakesForVehicleType/car?format=json")).ok,"NHTSA VIN service reachable");}catch(e){ok(false,"NHTSA VIN service not reachable from here");} $("#hc").innerHTML=out.join("");log("Ran system check");save();} function repairData(){let n=0;const fl=S.files.map(f=>f.id);S.docs.forEach(d=>{const b=(d.files||[]).length;d.files=(d.files||[]).filter(f=>fl.includes(f));n+=b-d.files.length;if(!d.payments){d.payments=[];n++;}});[S.vehicles,S.lot].forEach(L=>L.forEach(v=>{const b=(v.photos||[]).length;v.photos=(v.photos||[]).filter(f=>fl.includes(f));n+=b-v.photos.length;})); S.jobs.forEach(j=>{if(j.techId&&!user(j.techId)){j.techId="";n++;}if(!STATUSES.includes(j.status)){j.status="Checked in";n++;}});const L0=(S.locations[0]||{}).id;["jobs","docs","appts","parts","tires","lot"].forEach(k=>S[k].forEach(r=>{if(r.locId&&!byId("locations",r.locId)){r.locId=L0;n++;}})); log("Repaired data, "+n+" fixes");save();render();toast(n?`Fixed ${n} problems. Records without a customer are kept for you to reassign.`:"No problems found.");} A.security=()=>`

How customer data is protected

This demo: passwords are stored as SHA-256 hashes. License, registration, and policy numbers are masked on screen and hidden from mechanics, and every reveal is logged. The data itself sits in this browser unencrypted, so use sample data only.
Live, in transit: HTTPS only, using the SSL certificate GoDaddy cPanel provides.
Live, at rest: names, phones, emails, addresses, VINs, driver's license, registration, and policy numbers are encrypted field by field with libsodium (built into PHP). The key is stored outside the website folder.
Phone and email lookup on encrypted data: a keyed hash of the phone and email is stored beside the encrypted value, so the system can find a customer by phone without decrypting everyone.
Passwords: Argon2id hashing, lockout after repeated failures, two-step sign-in for administrators.
Access: role and location rules on every request, not just on screen. Every sign-in, change, export, reveal, and email goes to the activity log.
Backups: nightly encrypted backup stored outside the website folder.
`; A.audit=()=>`
${S.audit.slice(0,300).map(a=>``).join("")||``}
WhenWhoLocationWhat
${new Date(a.t).toLocaleString()}${esc(a.by)}${esc(locName(a.loc||"all"))}${esc(a.msg)}
Nothing logged yet.
`; /* ---------- boot ---------- */ /* ======================= v3.2: built for 5 years of data (tested at 25,000 invoices + 25,000 estimates) ======================= */ /* ---------- instant lookups: one index per collection, rebuilt only when data changes ---------- */ let SV=0,IX=null; function touch(){SV++;} function ix(){if(!IX||IX.v!==SV)IX={v:SV,maps:{},groups:{}};return IX;} function mapOf(k){const I=ix();let m=I.maps[k];if(!m){m=new Map();for(const r of (S[k]||[]))if(r&&r.id)m.set(r.id,r);I.maps[k]=m;}return m;} function groupOf(k,field){const I=ix(),key=k+"."+field;let g=I.groups[key];if(!g){g=new Map();for(const r of (S[k]||[])){const v=r[field];if(!v)continue;let a=g.get(v);if(!a)g.set(v,a=[]);a.push(r);}I.groups[key]=g;}return g;} const docsOfCust=id=>groupOf("docs","custId").get(id)||[]; const docsOfJob=id=>groupOf("docs","jobId").get(id)||[]; const vehsOfCust=id=>groupOf("vehicles","custId").get(id)||[]; /* ---------- pages of 50 rows, so a list of 25,000 draws as fast as a list of 50 ---------- */ const PAGE=50,PG={};let invF="all",partLow=false; function pageOf(key,arr){const n=Math.max(1,Math.ceil(arr.length/PAGE));let p=PG[key]||0;if(p>=n)p=n-1;if(p<0)p=0;PG[key]=p;return arr.slice(p*PAGE,p*PAGE+PAGE);} function pager(key,total){if(total<=PAGE)return "";const p=PG[key]||0,n=Math.ceil(total/PAGE); return `
Page ${(p+1).toLocaleString()} of ${n.toLocaleString()}
`;} /* ---------- type-to-search pickers (replace dropdowns that listed every customer or car) ---------- */ function pkLabel(kind,id){if(!id)return "";if(kind==="customers"){const c=cust(id);return c?cname(c)+(c.phone?" | "+c.phone:""):"";}const v=veh(id);return v?vname(v)+(v.plate?" | "+v.plate:"")+" | "+cname(cust(v.custId)):"";} function picker(id,kind,val,onpick){return ``;} function pkInput(id,kind){const h=document.getElementById(id);if(h&&h.value){h.value="";const on=document.getElementById(id+"_q").dataset.on;if(on&&window[on])window[on]();}pkSearch(id,kind);} function pkSearch(id,kind){const qi=document.getElementById(id+"_q"),box=document.getElementById(id+"_r");if(!qi||!box)return;const q=qi.value.trim().toLowerCase(),qd=digits(q); if(q.length<1||document.getElementById(id).value){box.style.display="none";return;} const hits=[]; if(kind==="customers"){for(const c of S.customers){if(hits.length>=12)break;if((cname(c)+" "+(c.email||"")+" "+(c.company||"")).toLowerCase().includes(q)||(qd.length>=3&&digits((c.phone||"")+" "+(c.phone2||"")).includes(qd)))hits.push(c.id);}} else{for(const v of S.vehicles){if(hits.length>=12)break;if((vname(v)+" "+(v.plate||"")+" "+(v.vin||"")+" "+cname(cust(v.custId))).toLowerCase().includes(q))hits.push(v.id);}} box.innerHTML=hits.map(h=>``).join("")||`No match${kind==="customers"?". Add them with New intake.":""}`;box.style.display="block";} function pkKey(e,id,kind){if(e.key==="Enter"){const b=document.querySelector("#"+id+"_r button");if(b){e.preventDefault();b.dispatchEvent(new MouseEvent("mousedown"));}}if(e.key==="Escape"){const b=document.getElementById(id+"_r");if(b)b.style.display="none";}} function pkSet(id,kind,rid){const h=document.getElementById(id),q=document.getElementById(id+"_q");if(!h)return;h.value=rid;q.value=pkLabel(kind,rid);document.getElementById(id+"_r").style.display="none";const on=q.dataset.on;if(on&&window[on])window[on]();} /* ---------- this-browser storage: IndexedDB holds hundreds of MB (the old 5 MB limit is gone) ---------- */ const IDB={db:null, open(){return new Promise((res,rej)=>{if(!window.indexedDB)return rej(new Error("IndexedDB not available"));const r=indexedDB.open("qoc_shop",1);r.onupgradeneeded=()=>r.result.createObjectStore("kv");r.onsuccess=()=>{this.db=r.result;res(r.result);};r.onerror=()=>rej(r.error);});}, async get(k){const db=this.db||await this.open();return new Promise((res,rej)=>{const q=db.transaction("kv").objectStore("kv").get(k);q.onsuccess=()=>res(q.result);q.onerror=()=>rej(q.error);});}, async put(k,v){const db=this.db||await this.open();return new Promise((res,rej)=>{const tx=db.transaction("kv","readwrite");tx.objectStore("kv").put(v,k);tx.oncomplete=()=>res();tx.onerror=()=>rej(tx.error);tx.onabort=()=>rej(tx.error||new Error("save aborted"));});}}; async function localSave(){saveTimer=null;const txt=JSON.stringify(S);try{await IDB.put(KEY,txt);setSync("ok");}catch(e){try{localStorage.setItem(KEY,txt);setSync("ok");}catch(e2){setSync("fail");toast("This browser could not save. Download a backup in Admin panel now.");}}} async function localLoad(){let d=null;try{const raw=await IDB.get(KEY);d=raw?JSON.parse(raw):null;}catch(e){d=null;} if(!d){try{const raw=localStorage.getItem(KEY);d=raw?JSON.parse(raw):null;}catch(e){d=null;}} try{if(navigator.storage&&navigator.storage.persist)navigator.storage.persist();}catch(e){}return d;} function flushSave(){if(!saveTimer||!S)return;clearTimeout(saveTimer);saveTimer=null;if(storageMode==="server")(SYNC.on?hostSync:serverSave)();else localSave();} document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="hidden")flushSave();}); window.addEventListener("pagehide",flushSave); /* ---------- shop-computer mode: check a tiny change stamp before downloading the whole database ---------- */ let lastStamp=""; async function serverStamp(){try{const r=await fetch("api/stamp",{headers:apiHeaders(),cache:"no-store"});if(!r.ok)return null;return (await r.text()).trim();}catch(e){return null;}} /* ======================= v3.4: shop artwork, Urbnix branding and support, clean production start ======================= */ const APP_VERSION="3.4",URBNIX={name:"Urbnix",site:"https://urbnix.com",email:"9084824165@pm.me"}; /* Shop logo drawn from the business name: tire-and-wrench emblem, sports car on real tires, name and tagline. */ const LOGO_COLORS={ gold:{name:"Gold",bg1:"#2b2a27",bg2:"#0d0d0c",g1:"#fff1b8",g2:"#e2bd55",g3:"#a77b1c",g4:"#6e4f0c",line:"#d9b44a"}, silver:{name:"Chrome",bg1:"#2c3036",bg2:"#0b0d10",g1:"#ffffff",g2:"#d5dbe2",g3:"#8f99a6",g4:"#59626e",line:"#c9d1da"}, red:{name:"Racing red",bg1:"#2a1d1d",bg2:"#0e0909",g1:"#ffd6cf",g2:"#ef5a43",g3:"#b3261e",g4:"#6e140f",line:"#e4513d"}, blue:{name:"Steel blue",bg1:"#1d2633",bg2:"#080c12",g1:"#e3f1ff",g2:"#5fa8f0",g3:"#2b6cb8",g4:"#173f70",line:"#5a9fe6"}}; function logoSVG(name,tagline,color){color=LOGO_COLORS[color]?color:"gold";const c=LOGO_COLORS[color]||LOGO_COLORS.gold,E=s=>String(s||"").replace(/[&<>"]/g,m=>({"&":"&","<":"<",">":">",'"':"""}[m])); const nm=String(name||"Your Shop").toUpperCase(),tg=String(tagline||"").toUpperCase(),W=440,fs=Math.max(24,Math.min(50,Math.floor(W/(nm.length*0.66)))); const tire=(cx,cy,r,tw)=>{const tread=[...Array(28)].map((_,i)=>{const a=i*Math.PI*2/28,x1=cx+Math.cos(a)*(r-tw),y1=cy+Math.sin(a)*(r-tw),x2=cx+Math.cos(a)*r,y2=cy+Math.sin(a)*r;return ``;}).join(""); const sp=[...Array(5)].map((_,i)=>{const a=-Math.PI/2+i*Math.PI*2/5;return ``;}).join(""); return `${tread}${sp}`;}; const wrench=``; const car=``; return ` ${tire(95,118,64,15)}${wrench}${car}${tire(313,116,27,7)}${tire(551,116,27,7)} W?`textLength="${W}" lengthAdjust="spacingAndGlyphs"`:""}>${E(nm)} ${tg?`${E(tg)}`:""}`;} /* Extra logo layouts and sign-in backgrounds. All drawn from the shop name and color. */ const LOGO_LAYOUTS={classic:"Classic: emblem, car, name",crest:"Crest: round badge",tire:"Tire shop: big tire and name",minimal:"Minimal: car line and name"}; function logoArt(layout,name,tagline,color){if(!layout||layout==="classic")return logoSVG(name,tagline,color); color=LOGO_COLORS[color]?color:"gold";const c=LOGO_COLORS[color],E=s=>String(s||"").replace(/[&<>"]/g,m=>({"&":"&","<":"<",">":">",'"':"""}[m])); const nm=String(name||"Your Shop").toUpperCase(),tg=String(tagline||"").toUpperCase(),id=color+layout,G=`url(#g${id})`; const defs=``; const frame=``; const tire=(cx,cy,r,n)=>{let g="";for(let i=0;i[(cx+Math.cos(a+da)*rr).toFixed(1),(cy+Math.sin(a+da)*rr).toFixed(1)],[x1,y1]=p(r*.97,0),[x2,y2]=p(r*.8,.12);g+=``;} let sp="";for(let i=0;i<5;i++){const a=-Math.PI/2+i*Math.PI*2/5;sp+=``;} return `${g}${sp}`;}; const wrench=(x,y,s)=>``; const carLine=(x,y,s,w)=>``; const fit=(n,max,w)=>Math.max(18,Math.min(max,Math.floor(w/(n.length*0.66)))); const txt=(x,y,s,w,t,anchor)=>`w?`textLength="${w}" lengthAdjust="spacingAndGlyphs"`:""}>${E(t)}`; const sub=(x,y,t,anchor)=>t?`${E(t)}`:""; let body=""; if(layout==="crest"){const fs=Math.min(22,Math.floor(300/(nm.length*0.62))); body=` ${E(nm)} ${tg?`${E(tg.slice(0,34))}`:""} ${carLine(256,104,.32,7)} ${[-1,1].map(d=>``).join("")}`;} if(layout==="tire"){const fs=fit(nm,46,380); body=`${tire(118,120,92,22)}${wrench(118,120,.95)} ${txt(428,118,fs,380,nm)}${sub(428,166,tg)} ${[...Array(12)].map((_,i)=>``).join("")}`;} if(layout==="minimal"){const fs=fit(nm,44,520); body=`${carLine(220,46,.5,4)}${txt(320,168,fs,540,nm)}${sub(320,206,tg)}`;} return `${defs}${frame}${body}`;} const LOGIN_BGS={photo:"Storefront photo",garage:"Garage with lift",tread:"Tire tread pattern",road:"Night road",carbon:"Carbon fiber",plain:"Plain dark",upload:"Uploaded picture"}; function bgArt(kind,color){const c=LOGO_COLORS[color]||LOGO_COLORS.gold,L=c.line,u=kind+(LOGO_COLORS[color]?color:"gold");const w=1600,h=900;let b=""; if(kind==="garage"){b=` ${[...Array(14)].map((_,i)=>``).join("")}${[0,1,2,3].map(i=>``).join("")} ${[300,1300].map(x=>``).join("")} ${[400,800,1200].map(x=>``).join("")} `;} if(kind==="tread"){b=``;} if(kind==="road"){b=` ${[...Array(26)].map((_,i)=>{const x=i*64,hh=60+((i*37)%7)*28;return ``+[...Array(4)].map((_,k)=>``).join("");}).join("")} ${[0,1,2,3,4].map(i=>``).join("")} `;} if(kind==="carbon"){b=``;} if(!b)return "";return `${b}`;} /* logo to PNG for the sidebar, printouts, and PDF invoices */ function logoPNG(){const s=S.settings;return new Promise((res,rej)=>{const img=new Image();img.onload=()=>{try{const cv=document.createElement("canvas");cv.width=960;cv.height=360;cv.getContext("2d").drawImage(img,0,0,960,360);res(cv.toDataURL("image/png"));}catch(e){rej(e);}};img.onerror=()=>rej(new Error("The logo could not be drawn."));img.src="data:image/svg+xml;charset=utf-8,"+encodeURIComponent(logoArt(s.logoLayout,s.name,s.orgName,s.logoColor));});} async function applyLogo(){const s=S.settings;try{if(s.logoMode==="auto")s.logo=await logoPNG();else if(s.logoMode==="upload")s.logo=s.logoUpload||s.logo||"";else s.logo="";}catch(e){toast(e.message);}} function loginBgURL(){const s=S.settings,k=s.loginBgKind;if(k==="photo")return ORIG_BG;if(k==="upload")return s.loginBg||"";if(k==="plain"||!k)return "";const svg=bgArt(k,s.logoColor);return svg?"data:image/svg+xml;charset=utf-8,"+encodeURIComponent(svg):"";} function loginBgCSS(){const u=loginBgURL();return u?`background-image:linear-gradient(rgba(0,0,0,.35),rgba(0,0,0,.55)),url('${u.replace(/'/g,"%27").replace(/"/g,"%22")}');`:"";} function lgPrev(){const b=$("#lg_prev");if(!b)return;const m=$("#br_logo").value,s=S.settings;["br_logoc","br_logol"].forEach(i=>{const e=$("#"+i);if(e)e.disabled=m!=="auto";}); b.innerHTML=m==="auto"?logoArt($("#br_logol").value,$("#br_n").value,$("#br_o").value,$("#br_logoc").value):m==="upload"?(s.logoUpload?`Uploaded logo`:`

No picture uploaded yet. Use Upload logo below.

`):`

No logo. The name shows as text.

`; const bp=$("#bg_prev");if(bp){const k=$("#br_bg").value,c=$("#br_logoc").value,u=k==="photo"?ORIG_BG:k==="upload"?s.loginBg:k==="plain"?"":"data:image/svg+xml;charset=utf-8,"+encodeURIComponent(bgArt(k,c));bp.style.backgroundImage=u?`url("${u}")`:"none";}} /* Urbnix: product credit and a direct line to support */ const urbnixLine=()=>`Shop software by Urbnix | urbnix.com`; function supportModal(){openModal(`

Contact Urbnix

Questions, problems, ideas, or changes you want made. Your message goes straight to the Urbnix team.

The message includes your shop name, software version, and screen size so we can help faster. No customer information is included.

Visit urbnix.com${serverCaps.mail?``:""}
`);} async function supportSend(viaServer){const m=$("#sp_m").value.trim();if(!m){toast("Write a short message first.");return;}const t=$("#sp_t").value,subj=`[${S.settings.name}] ${t}`, body=`${m}\n\n---\nFrom: ${$("#sp_n").value}\nReach me at: ${$("#sp_c").value}\nShop: ${S.settings.name}\nRole: ${me?ROLES[me.role]:"not signed in"}\nSoftware: Shop Manager ${APP_VERSION} (${storageMode==="server"?(serverCaps.hosted?"web host":"shop computer"):"this browser"})\nScreen: ${innerWidth}x${innerHeight}\nBrowser: ${navigator.userAgent}`; if(viaServer){const r=await serverMail(URBNIX.email,subj,body);if(!r.ok){toast("Could not send: "+(r.error||"server error")+". Use Open in my email app.");return;}toast("Sent to Urbnix. We will reply to you directly.");} else{location.href="mailto:"+URBNIX.email+"?subject="+encodeURIComponent(subj)+"&body="+encodeURIComponent(body);toast("Your email app opened with the message. Press send there.");} log("Contacted Urbnix support ("+t+")");save();closeModal();} A.about=()=>`

About this software

Shop Manager ${APP_VERSION}, a product of Urbnix (RV LLC).
Running on: ${storageMode==="server"?(serverCaps.hosted?"the web host":"the shop computer"):"this browser only"}
Licensed to: ${esc(S.settings.name)}
Owned and developed by Urbnix (RV LLC). © ${new Date().getFullYear()} All rights reserved. For a copy for another shop, changes, or other Urbnix services (IT, networks, cybersecurity, automation, websites) use the buttons below.
urbnix.com

What to send us

Problems: what you clicked and what you expected to happen.
Ideas and changes: what would save your shop time.
Urgent: say so in the first line.

Support email: ${esc(URBNIX.email)}

`; /* production start: no sample customers and no demo passwords */ function cleanStart(d){["customers","vehicles","jobs","appts","docs","lot","deals","files","notes","letters","vendors","parts","tires"].forEach(k=>{if(Array.isArray(d[k]))d[k]=[];}); (d.packages||[]).forEach(p=>p.lines.forEach(l=>{delete l.ref;delete l.c;}));d.locations=d.locations.slice(0,1);Object.assign(d.locations[0],{name:"Main shop",address:"",phone:"",email:""}); d.users=d.users.filter(u=>u.username==="admin");d.users[0].locIds=[];d.audit=[];d.demoMode=false;Object.assign(d.settings,{name:"Your Shop",orgName:"Auto Repair and Tires",address:"",phone:"",email:""});return d;} /* ======================= v3.4: web host (GoDaddy cPanel, PHP + MySQL), saved one record at a time ======================= */ /* Each customer, vehicle, invoice, etc. is its own encrypted row on the server. A save sends only what changed, and every open device pulls other people's changes every 10 seconds. */ const REC_SEP="\u0001",REC_KNOWN=new Set(["locations","users","customers","vehicles","jobs","appts","docs","pricebook","vendors","parts","tires","lot","deals","packages","files","notes","letters"]); const SYNC={on:false,rev:0,snap:new Map(),busy:false,again:false}; let SETUP_RESULT=null; const isRecList=(k,v)=>Array.isArray(v)&&(v.length||REC_KNOWN.has(k))&&v.every(x=>x&&typeof x==="object"&&!Array.isArray(x)&&typeof x.id==="string"&&x.id.length>0&&x.id.length<=64)&&new Set(v.map(x=>x.id)).size===v.length; function recEntries(){const out=new Map(),keys=[]; for(const k of Object.keys(S)){const v=S[k];if(isRecList(k,v)){keys.push(k);for(const r of v)out.set(k+REC_SEP+r.id,JSON.stringify(r));}else out.set("_"+REC_SEP+k,JSON.stringify(v===undefined?null:v));} out.set("_"+REC_SEP+"_keys",JSON.stringify(keys.sort()));return out;} function applyUp(c,id,d){if(c==="_"){if(id==="_keys"){(d||[]).forEach(k=>{if(!Array.isArray(S[k]))S[k]=[];});return;}S[id]=d;return;}const a=Array.isArray(S[c])?S[c]:(S[c]=[]);const i=a.findIndex(x=>x.id===id);if(i>=0)a[i]=d;else a.push(d);} function applyDel(c,id){if(c==="_"){if(id!=="_keys")delete S[id];return;}if(Array.isArray(S[c]))S[c]=S[c].filter(x=>x.id!==id);} async function hostLoad(){let msg=""; for(;;){const r=await fetch("api/load",{headers:apiHeaders(),cache:"no-store"}); if(r.status===401){localStorage.setItem(SKEY,await askKey(msg||"Type the shop access key you saved during setup (it is in your password manager)."));msg="That key did not work. Check your password manager and try again.";continue;} if(r.status===429)throw new Error("Too many wrong keys from this network. Wait 15 minutes, then try again."); if(!r.ok)throw new Error("The web host answered "+r.status+". Wait a minute and reload."); const j=await r.json();SYNC.on=true;SYNC.rev=+j.rev||0;SYNC.snap=new Map();const d={}; for(const x of (j.records||[])){SYNC.snap.set(x.c+REC_SEP+x.id,JSON.stringify(x.d));if(x.c==="_")d[x.id]=x.d;else(d[x.c]||(d[x.c]=[])).push(x.d);} (d._keys||[]).forEach(k=>{if(!Array.isArray(d[k]))d[k]=[];});delete d._keys; const opt=new Set(j.optouts||[]);if(opt.size&&Array.isArray(d.customers))d.customers.forEach(c=>{if(c.unsubToken&&opt.has(c.unsubToken))c.optOut=true;}); return d;}} async function hostSync(){if(SYNC.busy){SYNC.again=true;return;}SYNC.busy=true;saveTimer=null; try{const now=recEntries(),ups=[],dels=[]; for(const [k,v] of now)if(SYNC.snap.get(k)!==v){const i=k.indexOf(REC_SEP);ups.push({c:k.slice(0,i),id:k.slice(i+1),d:v});} for(const k of SYNC.snap.keys())if(!now.has(k)){const i=k.indexOf(REC_SEP);dels.push({c:k.slice(0,i),id:k.slice(i+1)});} const big=ups.find(u=>u.d.length>4*1048576);if(big)throw new Error("One record is larger than 4 MB ("+big.c+"). Remove a large attached file."); const post=async(u,d)=>{const r=await fetch("api/sync",{method:"POST",headers:Object.assign({"Content-Type":"application/json"},apiHeaders()),body:JSON.stringify({upserts:u,deletes:d})});const j=await r.json().catch(()=>({}));if(!r.ok||!j.ok)throw new Error(j.error||("the web host answered "+r.status));}; let batch=[],size=0;for(const u of ups){if(batch.length&&size+u.d.length>1.5*1048576){await post(batch,[]);batch=[];size=0;}batch.push(u);size+=u.d.length+80;} if(batch.length||dels.length)await post(batch,dels); SYNC.snap=now;dirty=false;setSync("ok");} catch(e){setSync("fail");toast("Not saved to the web host: "+e.message+" It will retry on the next change.");} finally{SYNC.busy=false;if(SYNC.again){SYNC.again=false;dirty=true;setTimeout(hostSync,300);}}} async function hostPoll(){if(!SYNC.on||dirty||SYNC.busy||!S||$("#modal").classList.contains("show")||view==="intake")return;const ae=document.activeElement;if(ae&&/INPUT|TEXTAREA|SELECT/.test(ae.tagName))return; try{const r=await fetch("api/changes?since="+SYNC.rev,{headers:apiHeaders(),cache:"no-store"});if(!r.ok)return;const j=await r.json();if(j.reload){location.reload();return;}if(dirty)return; let changed=false;for(const ch of (j.changes||[])){const key=ch.c+REC_SEP+ch.id; if(ch.d===null){if(SYNC.snap.has(key)){applyDel(ch.c,ch.id);SYNC.snap.delete(key);changed=true;}} else{const txt=JSON.stringify(ch.d);if(SYNC.snap.get(key)!==txt){applyUp(ch.c,ch.id,ch.d);SYNC.snap.set(key,txt);changed=true;}}} SYNC.rev=+j.rev||SYNC.rev; if(changed){const myId=me&&me.id;normalize();if(myId){me=user(myId);if(!me||me.status!=="active")me=null;}const y=window.scrollY;render();window.scrollTo(0,y);}}catch(e){}} setInterval(hostPoll,10000); /* ---------- first-time setup on the web host (runs once) ---------- */ function setupScreen(){return new Promise(res=>{const F=(id,l,t,v,ex)=>``; $("#app").innerHTML=``; const val=i=>$("#"+i).value.trim(); $("#su_t").onclick=async()=>{$("#su_r").innerHTML=`

Checking...

`;try{const r=await fetch("api/selftest",{headers:{"X-Setup-Code":val("su_c")}}),j=await r.json().catch(()=>({})); $("#su_r").innerHTML=j.checks?j.checks.map(c=>`
${c[1]?'OK':'Fix'} ${esc(c[0])}${c[2]?` ${esc(c[2])}`:""}
`).join(""):`

${esc(j.error||"The check did not run (answer "+r.status+").")}

`;}catch(e){$("#su_r").innerHTML=`

${esc(e.message)}

`;}}; $("#su_b").onclick=async()=>{const e=$("#su_e");e.textContent="";const pw=$("#su_a").value; if(pw.length<12){e.textContent="Use an admin password of 12 or more characters.";return;}if(pw!==$("#su_a2").value){e.textContent="The admin passwords do not match.";return;} if(!/^[A-Za-z0-9_]{1,20}$/.test(val("su_x"))){e.textContent="Table prefix: letters, numbers, and _ only.";return;} $("#su_b").disabled=true;$("#su_b").textContent="Setting up..."; try{const r=await fetch("api/setup",{method:"POST",headers:{"Content-Type":"application/json","X-Setup-Code":val("su_c")},body:JSON.stringify({dbHost:val("su_h"),dbName:val("su_n"),dbUser:val("su_u"),dbPass:$("#su_p").value,prefix:val("su_x")})}),j=await r.json().catch(()=>({})); if(!r.ok||!j.accessKey){e.textContent=j.error||("Setup failed (answer "+r.status+").");$("#su_b").disabled=false;$("#su_b").textContent="Set up the shop";return;} localStorage.setItem(SKEY,j.accessKey);SETUP_RESULT={sample:$("#su_sample").checked,adminPw:pw,shop:val("su_s")||"Your Shop"}; $(".lgc").innerHTML=`

Setup done

Your shop access key:

Save it in your password manager now. Every new computer, tablet, or phone asks for it once. It is not shown again.

Sign in as admin with the password you just chose.

`;$("#su_go").onclick=()=>res();} catch(err){e.textContent=err.message;$("#su_b").disabled=false;$("#su_b").textContent="Set up the shop";}};});} async function applySetupResult(){if(!SETUP_RESULT)return;if(!SETUP_RESULT.sample)cleanStart(S);S.settings.name=SETUP_RESULT.shop;const a=S.users.find(u=>u.username==="admin");a.hash=await sha("admin:"+SETUP_RESULT.adminPw);S.demoMode=false;S.settings.logo="";SETUP_RESULT=null;} /* moving a shop-computer backup onto the web host: keep the admin password chosen at setup, suspend any account still on a demo password */ async function restoreGuard(keep){const demo=new Set();for(const [u,p] of [["admin","admin123"],["user1","changeme1"],["user2","changeme2"],["user3","changeme3"],["user4","changeme4"],["user5","changeme5"]])demo.add(await sha(u+":"+p)); let a=S.users.find(u=>u.username==="admin");if(!a){a=Object.assign({},keep);S.users.unshift(a);}a.hash=keep.hash;a.status="active";a.fails=0;a.lockUntil=0;let n=0; S.users.forEach(u=>{if(u!==a&&u.status==="active"&&demo.has(u.hash)){u.status="suspended";u.note="Suspended after moving to the web host: still had a demo password. Reset it, then reactivate.";n++;}}); S.demoMode=false;if(n)setTimeout(()=>toast(n+" account(s) still had demo passwords and were suspended. Admin panel, Users: reset and reactivate them."),3800);} /* ======================= v3 MERGE: modules carried over from the original Quick Oil Change Shop Manager and new office workflow ======================= */ /* ---------- storage: shop computer (portable folder server) or this browser ---------- */ function setSync(st){const e=$("#sync");if(!e)return;e.textContent=storageMode==="server"?(SYNC.on?(st==="fail"?"Not saved: web host not answering":"Data: saved on the web host (encrypted)"):(st==="fail"?"Not saved: shop computer not answering":"Data: saved on the shop computer")):"Data: saved in this browser only";e.style.color=st==="fail"?"#ff8a80":"";} function apiHeaders(){const k=localStorage.getItem(SKEY);return k?{"X-Shop-Key":k}:{};} async function serverSave(){saveTimer=null;try{S.savedAt=Date.now();const r=await fetch("api/save",{method:"POST",headers:Object.assign({"Content-Type":"application/json"},apiHeaders()),body:JSON.stringify(S)});if(!r.ok)throw new Error("server answered "+r.status);dirty=false;setSync("ok");lastStamp=(await serverStamp())||lastStamp;}catch(e){setSync("fail");toast("Could not save to the shop computer. Check that its black server window is still open.");}} async function hasServer(){if(location.protocol==="file:")return false;try{const c=new AbortController(),t=setTimeout(()=>c.abort(),2500),r=await fetch("api/ping",{signal:c.signal,cache:"no-store"});clearTimeout(t);if(!r.ok)return false;const tx=(await r.text()).trim();try{serverCaps=JSON.parse(tx);}catch(e){serverCaps={ok:tx==="ok"};}return !!serverCaps.ok;}catch(e){return false;}} async function serverLoad(){const r=await fetch("api/load",{headers:apiHeaders(),cache:"no-store"});if(r.status===401)return {needKey:true};if(!r.ok)throw new Error("load failed "+r.status);const txt=await r.text();return {data:txt.trim()?JSON.parse(txt):{}};} function askKey(msg){return new Promise(res=>{$("#app").innerHTML=``;const done=()=>{const v=$("#akey").value.trim();if(v)res(v);};$("#akb").onclick=done;$("#akey").onkeydown=e=>{if(e.key==="Enter")done();};$("#akey").focus();});} async function pollServer(){if(storageMode!=="server"||SYNC.on||dirty||!S||$("#modal").classList.contains("show")||view==="intake")return;const ae=document.activeElement;if(ae&&/INPUT|TEXTAREA|SELECT/.test(ae.tagName))return; try{const st=await serverStamp();if(st!==null&&st===lastStamp)return;const r=await serverLoad();if(st!==null)lastStamp=st;if(r.data&&r.data.v===4&&(r.data.savedAt||0)>(S.savedAt||0)){const myId=me&&me.id;S=r.data;normalize();if(myId){me=user(myId);if(!me||me.status!=="active")me=null;}const y=window.scrollY;render();window.scrollTo(0,y);}}catch(e){}} /* ---------- defaults and repair of older data ---------- */ function defaultsSettings(){return {name:"Quick Oil Change",orgName:"Auto and Truck Repair",address:"495 JFK Blvd, Bayonne, NJ 07002",phone:"(347) 469-2622",email:"service@yourshop.com", tax:6.625,taxLabor:true,suppliesPct:5,suppliesCap:"",envFee:3,laborRate:110,rateEasy:95,rateMed:110,rateHard:135,docFee:499,tradeCredit:true, logo:"",loginBg:"",logoMode:"auto",logoColor:"gold",logoUpload:"",logoLayout:"classic",loginBgKind:"garage",footer:"Thank you for your business.",reviewUrl:"",autoReady:true,msg:{},hours:{open:"07:30",close:"18:00"},security:{maxTries:5,lockMins:10,idleMins:30}, theme:{preset:"gold",brand:"",side:"",accent:"",radius:6,font:"Barlow",density:"comfortable",allowUser:true}, features:Object.fromEntries(FEATURES.map(f=>[f[0],true])),ai:{provider:"off",endpoint:"",model:"",key:""}};} function normalize(){touch();if(S.settings&&S.settings.logoMode===undefined){S.settings.logoMode=S.settings.logo?"upload":"auto";S.settings.logoUpload=S.settings.logo||"";}if(S.settings&&S.settings.loginBgKind===undefined)S.settings.loginBgKind=S.settings.loginBg===ORIG_BG?"photo":S.settings.loginBg?"upload":"garage";const d=defaultsSettings(),s=S.settings||{};S.settings=Object.assign({},d,s);["hours","security","theme","ai"].forEach(k=>S.settings[k]=Object.assign({},d[k],s[k]||{}));S.settings.features=Object.assign({},d.features,s.features||{}); ["locations","users","customers","vehicles","jobs","appts","docs","pricebook","vendors","parts","tires","lot","deals","packages","files","notes","letters","audit","errors"].forEach(k=>{if(!Array.isArray(S[k]))S[k]=[];}); S.counters=Object.assign({estimate:1000,invoice:2000,deal:500},S.counters||{}); S.locations.forEach(l=>{if(!l.bays)l.bays="Lift 1, Lift 2, Lift 3";}); S.appts.forEach(a=>{if(!a.start)a.start=a.time||"09:00";if(!a.dur)a.dur=60;if(a.bay==null)a.bay="";}); S.docs.forEach(d=>{d.lines=d.lines||[];d.files=d.files||[];d.payments=d.payments||[];}); S.vehicles.forEach(v=>{v.photos=v.photos||[];});S.lot.forEach(v=>{v.photos=v.photos||[];v.recon=v.recon||[];}); S.users.forEach(u=>{u.locIds=u.locIds||[];u.fails=u.fails||0;});S.packages.forEach(p=>{p.lines=p.lines||[];}); if(!Array.isArray(S.campaigns))S.campaigns=[];if(!Array.isArray(S.apiKeys))S.apiKeys=[];S.campaigns.forEach(c=>{c.sent=c.sent||[];c.discount=c.discount||{kind:"none"};c.discount.uses=c.discount.uses||[];}); S.customers.forEach(c=>{if(!c.unsubToken)c.unsubToken=rnd(16);if(!Array.isArray(c.greetings))c.greetings=[];});} /* ---------- import from the original Shop Manager (rv_shop_v3) ---------- */ function oldLocal(){try{const r=localStorage.getItem(OLD_KEY);return r?JSON.parse(r):null;}catch(e){return null;}} function migrateOriginal(o){ const os=o.settings||{},L=S.locations[0]; ["customers","vehicles","jobs","appts","docs","parts","vendors","packages","lot","deals","files","notes"].forEach(k=>S[k]=[]); S.locations=[L]; Object.assign(S.settings,{name:os.shopName||S.settings.name,phone:os.phone||S.settings.phone,tax:os.taxRate!=null?+(os.taxRate*100).toFixed(4):S.settings.tax,suppliesPct:os.suppliesPct!=null?+(os.suppliesPct*100).toFixed(2):S.settings.suppliesPct,envFee:os.envFee!=null?+os.envFee:S.settings.envFee,rateEasy:+os.rateEasy||S.settings.rateEasy,rateMed:+os.rateMed||S.settings.rateMed,rateHard:+os.rateHard||S.settings.rateHard}); const cm={},vm={},vend={},pm={},jm={},photo=(data,name,link)=>{const f=Object.assign({id:uid(),name,type:/^data:image\/png/.test(data)?"image/png":"image/jpeg",size:Math.round(data.length*.75),data,by:"import",date:today()},link);S.files.push(f);return f.id;}; (o.vendors||[]).forEach(v=>{const n={id:uid(),name:v.name||"Vendor",contact:v.person||"",phone:v.phone||"",email:v.email||"",account:"",terms:v.terms||"",markup:40,portal:v.url||"",notes:"Imported from the original Shop Manager"};vend[v.name]=n.id;S.vendors.push(n);}); (o.customers||[]).forEach(c=>{const n={id:uid(),first:c.first||"",last:c.last||"",company:"",phone:c.phone||"",phone2:"",email:c.email||"",pref:"Text",address:"",city:c.city||"",state:"NJ",zip:"",dlNo:"",dlState:"",dlExp:"",tags:"",notes:"",created:today()};cm[c.id]=n.id;S.customers.push(n);}); (o.vehicles||[]).forEach(v=>{const n={id:uid(),custId:cm[v.custId]||"",type:v.type||"Car",fuel:v.fuel||"Gas",vin:/^SAMPLE/i.test(v.vin||"")?"":(v.vin||""),year:String(v.year||""),make:v.make||"",model:v.model||"",trim:"",engine:"",color:"",miles:v.miles||"",plate:v.plate||"",plateState:"NJ",regNo:"",regExp:"",insCarrier:"",insPolicy:"",insExp:"",tireSize:"",codes:v.codes||"",photos:[]}; if(v.photo)n.photos.push(photo(v.photo,"vehicle photo.jpg",{vehId:n.id,custId:n.custId}));vm[v.id]=n.id;S.vehicles.push(n);}); (o.parts||[]).forEach((p,i)=>{const n={id:uid(),sku:p.sku||("P-"+(p.id||i+1)),name:p.name||"Part",cat:"",vendorId:vend[p.vendor]||"",cost:+p.cost||0,price:+p.price||0,qty:+p.qty||0,reorder:+p.reorder||0,bin:p.shelf||"",locId:L.id};pm[p.name]=n;S.parts.push(n);}); (o.kits||[]).forEach(k=>{const lines=[{t:"Labor",d:k.name,q:+(k.labor&&k.labor.hours)||1,p:+(k.labor&&k.labor.price)||0}];(k.parts||[]).forEach(x=>{const p=pm[x.name];lines.push({t:"Part",d:x.name,q:+x.qty||1,p:p?+p.price:0,c:p?+p.cost:0,ref:p?"pt:"+p.id:""});});S.packages.push({id:uid(),name:k.name,cat:k.category||"",applies:k.applies||"Both",lines});}); const stMap={"Waiting For Approval":"Waiting approval","Working On It":"In repair","Waiting For Parts":"Waiting parts","Done":"Ready","Paid":"Picked up"}; (o.workOrders||[]).forEach(w=>{const j={id:uid(),locId:L.id,vehId:vm[w.vehId]||"",custId:cm[w.custId]||"",complaint:w.complaint||"",status:stMap[w.status]||"Checked in",bay:"",techId:"",dateIn:w.dateIn||today(),promised:"",events:[{t:new Date().toISOString(),by:"import",msg:"Imported from original work order #"+w.id}]};jm[w.id]=j.id;S.jobs.push(j); const isEst=!w.paid&&w.status==="Waiting For Approval",type=isEst?"estimate":"invoice";S.counters[type]++; const d={id:uid(),type,no:(isEst?"E-":"I-")+S.counters[type],locId:L.id,custId:j.custId,vehId:j.vehId,jobId:j.id,date:w.dateIn||today(),status:isEst?"sent":"open",lines:(w.lines||[]).map(l=>({t:l.type==="Part"?"Part":"Labor",d:l.desc||"",q:+l.qty||0,p:+l.price||0,c:+l.cost||0})),notes:w.codes?("Codes: "+w.codes):"",files:[],payments:[],by:"import"}; (w.photos||[]).forEach((ph,i)=>d.files.push(photo(ph,"job photo "+(i+1)+".jpg",{docId:d.id,custId:d.custId}))); if(w.paid){d.payments.push({date:w.dateIn||today(),amt:+totals(d).total.toFixed(2),method:"Imported"});d.status="paid";}S.docs.push(d);}); const t24=s=>{const m=String(s||"").match(/(\d{1,2}):(\d{2})\s*(AM|PM)?/i);if(!m)return "09:00";let h=+m[1];if(m[3]){if(/pm/i.test(m[3])&&h<12)h+=12;if(/am/i.test(m[3])&&h===12)h=0;}return String(h).padStart(2,"0")+":"+m[2];}; (o.schedule||[]).forEach(s=>{const w=(o.workOrders||[]).find(x=>x.id===s.woId);S.appts.push({id:uid(),locId:L.id,date:s.day||today(),start:t24(s.timeIn),dur:60,bay:s.bay||"",custId:w?cm[w.custId]:"",vehId:w?vm[w.vehId]:"",service:w?w.complaint:"Open bay",packageId:"",techId:"",status:s.status==="Open"?"Booked":"Arrived",jobId:w?jm[w.id]:"",notes:"Imported"});}); const lotSt={"Acquired":"In reconditioning","In Repair":"In reconditioning","Ready":"For sale","Listed":"For sale","Sold":"Sold"}; (o.flips||[]).forEach(f=>{const n={id:uid(),locId:L.id,vin:"",year:String(f.year||""),make:f.make||"",model:f.model||"",miles:"",color:"",acquired:today(),source:f.source||"Auction",sellerId:"",cost:+f.acqCost||0,recon:(f.build||[]).map(b=>({d:b.desc,amt:+b.cost||0})),list:+f.targetPrice||0,status:lotSt[f.status]||"In reconditioning",photos:[],notes:f.notes||""};if(f.photo)n.photos.push(photo(f.photo,"car photo.jpg",{lotId:n.id}));S.lot.push(n);}); (o.employees||[]).forEach(e=>{if(S.users.some(u=>u.display===e.name))return;let un=String(e.name||"tech").toLowerCase().replace(/[^a-z0-9]+/g,".").replace(/^\.+|\.+$/g,"").slice(0,30)||"tech";while(S.users.some(u=>u.username===un))un+="1"; S.users.push({id:uid(),username:un,display:e.name||un,role:"tech",status:"suspended",locIds:[],email:"",phone:e.phone||"",hash:"",created:today(),fails:0,note:"Imported. Use Reset password, then Reactivate."});}); S.users.forEach(u=>{u.locIds=[];}); Object.assign(S.settings,{logo:ORIG_LOGO,logoUpload:ORIG_LOGO,loginBg:ORIG_BG,loginBgKind:"photo",logoMode:"upload"});log("Imported data from the original Quick Oil Change Shop Manager");S.migratedFrom=OLD_KEY;} /* ---------- schedule calendar ---------- */ let calDate=today(),calMode="day"; const SLOT=30,SLOT_PX=30; const toMin=t=>{const m=String(t||"").match(/^(\d{1,2}):(\d{2})/);return m?(+m[1])*60+(+m[2]):0;}; const fromMin=n=>String(Math.floor(n/60)).padStart(2,"0")+":"+String(n%60).padStart(2,"0"); const fmtT=t=>{const n=toMin(t),h=Math.floor(n/60),m=n%60;return (h%12||12)+":"+String(m).padStart(2,"0")+(h<12?" AM":" PM");}; const durTxt=m=>m<60?m+" minutes":(m/60)+(m===60?" hour":" hours"); function calLoc(){return curLoc!=="all"?byId("locations",curLoc):myLocs()[0];} const baysOf=l=>String((l&&l.bays)||"Lift 1").split(",").map(x=>x.trim()).filter(Boolean); const liveAppt=a=>!["Cancelled","No-show"].includes(a.status); function apptConflict(a,ignoreId){return S.appts.filter(b=>b.id!==ignoreId&&liveAppt(b)&&b.date===a.date&&b.locId===a.locId&&toMin(b.start)(a.bay&&b.bay===a.bay)||(a.techId&&b.techId===a.techId));} function nextFree(locId,bay,dur,fromDate,techId){const h=S.settings.hours,open=toMin(h.open),close=toMin(h.close),nowM=new Date().getHours()*60+new Date().getMinutes();let d=fromDate{const L=calLoc();if(!L)return `

Add a location first, in Admin panel, Locations.

`; const step=calMode==="day"?1:7; return `

${esc(L.name)}, ${calMode==="day"?new Date(calDate+"T12:00:00").toLocaleDateString("en-US",{weekday:"long",month:"long",day:"numeric",year:"numeric"}):"week of "+fmtD(weekStart(calDate))}

${curLoc==="all"&&myLocs().length>1?`

Showing ${esc(L.name)}. Pick a location at the top to see its bays.

`:""}${calMode==="day"?calDay(L):calWeek(L)}`;}; function calDay(L){const h=S.settings.hours,open=toMin(h.open),close=toMin(h.close),bays=baysOf(L),day=S.appts.filter(a=>a.date===calDate&&a.locId===L.id),rows=[];for(let m=open;m=open&&nowM<=close; const inBay=b=>S.jobs.filter(j=>j.locId===L.id&&j.bay===b&&j.status!=="Picked up"); const col=(b,bi)=>{const aps=day.filter(a=>a.bay===b),hrs=aps.filter(liveAppt).reduce((s,a)=>s+(+a.dur),0)/60,ib=inBay(b); return `
${esc(b)}
${hrs?hrs.toFixed(1)+" h booked":"Open all day"}${ib.length?`
In bay: ${esc(vname(veh(ib[0].vehId)))}`:""}
${rows.map(m=>``).join("")} ${aps.map(a=>{const top=Math.max(0,(toMin(a.start)-open)/SLOT*SLOT_PX),ht=Math.max(SLOT_PX-2,(+a.dur)/SLOT*SLOT_PX-3),t=user(a.techId);return (+a.dur)<=30?``:``;}).join("")} ${showNow?`
`:""}
`;}; const unbayed=day.filter(a=>!bays.includes(a.bay)); return `
${rows.map(m=>`
${m%60?"":fmtT(fromMin(m))}
`).join("")}
${bays.map(col).join("")}
${unbayed.length?`

Booked with no bay (${unbayed.length})

${unbayed.map(a=>`
${fmtT(a.start)} ${esc(cname(cust(a.custId)))}, ${esc(a.service)}
`).join("")}
`:""}

Click any empty space to book that bay at that time. Shop hours ${fmtT(h.open)} to ${fmtT(h.close)}; change them in Admin panel, Name, logo, letterhead.

`;} function weekStart(d){const x=new Date(d+"T12:00:00");x.setDate(x.getDate()-((x.getDay()+6)%7));return x.toISOString().slice(0,10);} function calWeek(L){const ws=weekStart(calDate),ds=[0,1,2,3,4,5,6].map(i=>prevDay(ws,i)); return `
${ds.map(d=>{const aps=S.appts.filter(a=>a.date===d&&a.locId===L.id).sort((a,b)=>toMin(a.start)-toMin(b.start)),hrs=aps.filter(liveAppt).reduce((s,a)=>s+(+a.dur),0)/60; return `
${aps.filter(liveAppt).length} booked, ${hrs.toFixed(1)} h
${aps.map(a=>``).join("")}
`;}).join("")}
`;} function apptModal(id,preset){const L0=calLoc(); const a=id?byId("appts",id):Object.assign({id:"",date:today(),start:"",dur:60,bay:"",custId:"",vehId:"",service:"",packageId:"",techId:"",status:"Booked",notes:"",locId:(L0||{}).id||defLoc()},preset||{}); const L=byId("locations",a.locId)||L0,bays=baysOf(L);if(!id&&preset&&preset.bayIdx!=null)a.bay=bays[preset.bayIdx]||""; const times=slotTimes();if(!a.start)a.start=times[0]; const techs=S.users.filter(u=>u.status==="active"&&["tech","tire","manager","owner"].includes(u.role)); openModal(`

${id?"Appointment":"Book a car"}

${id?"":`

New customer or new car? books it in one step.

`}
${id&&canDel()?``:""}${id&&!a.jobId&&can("board")&&liveAppt(a)?``:""}${a.jobId?``:""}${id&&liveAppt(a)?``:""}
`);apVeh();apBays();} function slotTimes(){const h=S.settings.hours,t=[];for(let m=toMin(h.open);mPick a vehicle`+S.vehicles.filter(v=>v.custId===c).map(v=>``).join("");} function apBays(){const sel=$("#ap_b"),cur=sel.value||sel.dataset.sel,L=byId("locations",$("#ap_l").value);sel.innerHTML=``+baysOf(L).map(b=>``).join("");} function pkgMinutes(p){const h=(p.lines||[]).filter(l=>l.t==="Labor").reduce((s,l)=>s+(+l.q||0),0);return Math.max(30,Math.ceil(h*60/30)*30);} function apPkg(){const p=byId("packages",$("#ap_pk").value);if(!p)return;$("#ap_s").value=p.name;const m=pkgMinutes(p),o=[...$("#ap_du").options].find(x=>+x.value>=m);if(o)$("#ap_du").value=o.value;} function readAppt(){return {custId:$("#ap_c").value,vehId:$("#ap_v").value,packageId:$("#ap_pk").value,service:$("#ap_s").value.trim(),date:$("#ap_d").value,start:$("#ap_t").value,dur:+$("#ap_du").value,locId:$("#ap_l").value,bay:$("#ap_b").value,techId:$("#ap_tc").value,status:$("#ap_st").value,notes:$("#ap_n").value};} function conflictMsg(v,c,errEl,applyFn){const nf=nextFree(v.locId,v.bay,v.dur,v.date,v.techId);errEl.innerHTML=`${esc(c.bay===v.bay&&v.bay?c.bay:(user(c.techId)||{}).display||"That slot")} is already booked ${fmtT(c.start)} to ${fmtT(fromMin(toMin(c.start)+(+c.dur)))} for ${esc(cname(cust(c.custId)))}.${nf?` Next open: ${esc(nf.bay)} on ${fmtD(nf.date)} at ${fmtT(nf.start)}. `:""}`;} function apUse(d,t,b){$("#ap_d").value=d;$("#ap_t").value=t;$("#ap_b").value=b;$("#ap_err").textContent="";} function saveAppt(id){const v=readAppt();if(!v.custId){$("#ap_err").textContent="Pick a customer.";return;}if(!v.date){$("#ap_err").textContent="Pick a date.";return;} if(toMin(v.start)+v.dur>toMin(S.settings.hours.close)){$("#ap_err").textContent="That runs past closing time. Pick an earlier start or a shorter time.";return;} if(liveAppt(v)){const c=apptConflict(v,id);if(c){conflictMsg(v,c,$("#ap_err"),"apUse");return;}} let a=id?byId("appts",id):null;if(!a){a={id:uid(),jobId:""};S.appts.push(a);}Object.assign(a,v); log((id?"Updated":"Booked")+" appointment "+cname(cust(a.custId))+" "+a.date+" "+a.start);save();closeModal();calDate=a.date;render();toast(id?"Appointment saved.":"Booked "+fmtD(a.date)+" at "+fmtT(a.start)+".");} function delAppt(id){if(!confirm("Delete this appointment? To keep a record, set the status to Cancelled instead."))return;S.appts=S.appts.filter(a=>a.id!==id);log("Deleted appointment");save();closeModal();render();} function apptCheckIn(id){const a=byId("appts",id);if(!a.vehId){toast("Pick the vehicle on this appointment first.");return;}closeModal();jobModal(null,{vehId:a.vehId,custId:a.custId,complaint:a.service,locId:a.locId,bay:a.bay,techId:a.techId,apptId:a.id,packageId:a.packageId,promised:a.date});} function findSlot(){const L=calLoc();openModal(`

Find the next open time

Press Search.
`);} function fsRun(){const L=calLoc(),nf=nextFree(L.id,$("#fs_b").value,+$("#fs_d").value,$("#fs_f").value);$("#fs_out").innerHTML=nf?`First opening: ${esc(nf.bay)}, ${fmtD(nf.date)} at ${fmtT(nf.start)}. `:"Nothing open in the next 30 days for that length. Try a shorter time or another bay.";} const msgTpl=k=>((S.settings.msg||{})[k])||MSG_DEF[k]; function remindText(a){const c=cust(a.custId);return fillMsg(msgTpl("reminder"),Object.assign(baseVars(c,a.locId),{when:new Date(a.date+"T12:00:00").toLocaleDateString("en-US",{weekday:"long",month:"short",day:"numeric"})+" at "+fmtT(a.start),service:a.service?" for "+a.service:"",vehicle:vname(veh(a.vehId))}));} function apptRemind(id){const a=byId("appts",id);sendModal("Remind "+cname(cust(a.custId)),cust(a.custId),remindText(a),"Appointment reminder",how=>{a.reminded=true;log("Sent appointment reminder ("+how+")");save();});} /* ---------- send helpers (text, WhatsApp, email) : nothing goes out until the user presses send in their own app ---------- */ let sendCb=null; async function sendNowEmail(cid,subject){const c=cust(cid),r=await serverMail(c.email,subject,$('#sd_m').value+`\n\n${S.settings.name}\n${S.settings.phone}`);if(r.ok){sendCb&&sendCb('email (sent)');toast('Email sent to '+c.email+'.');closeModal();}else toast('Email failed: '+r.error);} function sendModal(title,c,msg,subject,cb){if(!c){toast("No customer on this record.");return;}sendCb=how=>{c.msgs=c.msgs||[];c.msgs.unshift({at:new Date().toISOString(),ch:how,what:subject});if(cb)cb(how);else save();};const ph=digits(c.phone),wa=ph.length===10?"1"+ph:ph; openModal(`

${esc(title)}

Each button opens your own text, WhatsApp, or email app with this message ready. Nothing is sent until you press send there.

${c.email&&serverCaps.mail?``:""}${ph?`Text messageWhatsApp`:""}${c.email?`Email`:""}${!ph&&!c.email?`This customer has no phone or email on file.`:""}
`);} function readyText(j){const c=cust(j.custId),inv=S.docs.find(d=>d.jobId===j.id&&d.type==="invoice"),due=inv?totals(inv).due:0;return fillMsg(msgTpl("ready"),Object.assign(baseVars(c,j.locId),{vehicle:vname(veh(j.vehId)),balance:due>0.004?" Balance due: "+money(due)+".":""}));} function thanksModal(id){const j=S.jobs.find(x=>x.id===id),c=cust(j.custId);sendModal("Thank "+cname(c),c,fillMsg(msgTpl("thanks"),Object.assign(baseVars(c,j.locId),{vehicle:vname(veh(j.vehId))})),"Thank you from "+S.settings.name,how=>{j.thanked=true;j.events.push({t:new Date().toISOString(),by:me.username,msg:"Thank-you sent ("+how+")"});log("Sent thank-you ("+how+")");save();});} function notifyModal(id){const j=S.jobs.find(x=>x.id===id);sendModal("Tell "+cname(cust(j.custId))+" the car is ready",cust(j.custId),readyText(j),"Your vehicle is ready",how=>{j.notified=true;j.events.push({t:new Date().toISOString(),by:me.username,msg:"Customer told the car is ready ("+how+")"});log("Told customer the car is ready ("+how+")");save();});} /* ---------- one-screen intake ---------- */ let iq={custId:"",vehId:"new",when:"now"}; const dictBtn=id=>feat("dictation")?``:""; V.intake=()=>{iq={custId:"",vehId:"new",when:"now"};const L=calLoc(); return `

For a walk-in or a phone call: find or add the customer, pick or add the car, then check it in now or put it on the calendar. Everything is created once and linked together.

1. Customer

${iqNewCust()}

2. Vehicle

${iqNewVeh()}

3. Visit

${feat("appts")&&can("schedule")?``:""}
`;}; function iqNewCust(){return `
`;} function iqNewVeh(){return `
${feat("vinscan")?``:""}

`;} function iqFind(){const q=$("#iq_find").value.trim().toLowerCase(),qd=digits(q),box=$("#iq_hits");if(q.length<2){box.innerHTML="";return;} const hits=S.customers.filter(c=>(cname(c)+" "+c.email+" "+(c.company||"")).toLowerCase().includes(q)||(qd.length>=3&&digits(c.phone+" "+c.phone2).includes(qd))).slice(0,6); box.innerHTML=hits.map(c=>``).join("")||`

No match. Fill in the new customer below.

`; if(!hits.length&&qd.length>=7&&$("#iq_phone")&&!$("#iq_phone").value)$("#iq_phone").value=q;} function iqPick(id){iq.custId=id;const c=cust(id),due=S.docs.filter(d=>d.custId===id&&d.type==="invoice").reduce((s,d)=>s+totals(d).due,0);$("#iq_hits").innerHTML=""; $("#iq_cust").innerHTML=`
${esc(cname(c))}
${esc(c.phone)} ${esc(c.email)}${due>0.004&&seeMoney()?`
Owes ${money(due)} from earlier visits`:""}
`; const vs=S.vehicles.filter(v=>v.custId===id);iq.vehId=vs.length?vs[0].id:"new";$("#iq_veh").innerHTML=iqVehSection();} function iqVehSection(){const vs=S.vehicles.filter(v=>v.custId===iq.custId);if(!vs.length){iq.vehId="new";return iqNewVeh();} return vs.map(v=>``).join("")+ `
${iq.vehId==="new"?iqNewVeh():""}
`;} async function iqDecode(){const vin=cleanVin($("#iq_vin").value),m=$("#iq_vmsg");$("#iq_vin").value=vin;if(!vinOk(vin)){m.textContent="A VIN is 17 characters and never uses I, O, or Q.";return;}m.textContent="Decoding with NHTSA..."; try{const d=(await (await fetch("https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVinValues/"+vin+"?format=json")).json()).Results[0];if(!d.Make){m.textContent="NHTSA did not recognize this VIN.";return;}$("#iq_year").value=d.ModelYear||"";$("#iq_make").value=d.Make||"";$("#iq_model").value=[d.Model,d.Trim].filter(Boolean).join(" ");m.textContent="Decoded: "+[d.DisplacementL?(+d.DisplacementL).toFixed(1)+"L":"",d.EngineCylinders?d.EngineCylinders+" cyl":"",d.DriveType].filter(Boolean).join(", ");}catch(e){m.textContent="Could not reach NHTSA. Type the details in.";}} async function iqVinPhoto(inp){const f=inp.files[0],m=$("#iq_vmsg");if(!f)return;if(!("BarcodeDetector" in window)){m.textContent="This browser cannot read barcodes. Type the VIN.";return;}try{const r=await new BarcodeDetector({formats:["code_39","code_128","data_matrix","qr_code"]}).detect(await createImageBitmap(f)),hit=r.map(x=>cleanVin(x.rawValue)).find(vinOk);if(hit){$("#iq_vin").value=hit;iqDecode();}else m.textContent="No VIN barcode found. Aim at the door jamb barcode, or type it.";}catch(e){m.textContent="Could not read the photo. Type the VIN.";}} function iqPkg(){const p=byId("packages",$("#iq_pk").value);if(p&&!$("#iq_cmp").value.trim())$("#iq_cmp").value=p.name;const du=$("#iq_du");if(p&&du){const m=pkgMinutes(p),o=[...du.options].find(x=>+x.value>=m);if(o)du.value=o.value;}} function iqWhen(){const L=byId("locations",$("#iq_l").value)||calLoc(),bays=baysOf(L),techs=S.users.filter(u=>u.status==="active"&&["tech","tire","manager","owner"].includes(u.role)),bo=``+bays.map(b=>``).join(""),to=``+techs.map(u=>``).join(""); const n=$("#iq_now"),l=$("#iq_later");if(n)n.classList.toggle("on",iq.when==="now");if(l)l.classList.toggle("on",iq.when==="later"); $("#iq_when").innerHTML=iq.when==="now"?`
` :`
`;iqPkg();} function iqNext(){const nf=nextFree($("#iq_l").value,$("#iq_b").value,+$("#iq_du").value,$("#iq_d").value,$("#iq_t").value);if(!nf){toast("Nothing open in the next 30 days for that length.");return;}iqUse(nf.date,nf.start,nf.bay);} function iqUse(d,t,b){$("#iq_d").value=d;$("#iq_s").value=t;$("#iq_b").value=b;$("#iq_err").textContent="";toast("Set to "+b+", "+fmtD(d)+" at "+fmtT(t)+".");} function iqCreate(){const err=m=>{$("#iq_err").innerHTML=m;return false;};let c=iq.custId?cust(iq.custId):null,newC=null,v=null,newV=null; if(!c){const first=$("#iq_first").value.trim(),last=$("#iq_last").value.trim(),phone=$("#iq_phone").value.trim(),email=$("#iq_email").value.trim(); if(!first&&!last)return err("Enter the customer's name, or pick them from the search.");if(!phone&&!email)return err("Enter a phone number or email so this customer is easy to find next time."); const dup=S.customers.find(x=>(phone&&digits(x.phone)===digits(phone))||(email&&x.email&&x.email.toLowerCase()===email.toLowerCase())); if(dup){iqPick(dup.id);return err(esc(cname(dup))+" already has that "+(phone&&digits(dup.phone)===digits(phone)?"phone number":"email")+". Their record is now picked so nothing is duplicated. Check the vehicle, then press Create again.");} newC={id:uid(),first,last,company:"",phone,phone2:"",email,pref:$("#iq_pref").value,address:"",city:"",state:"NJ",zip:"",dlNo:"",dlState:"",dlExp:"",tags:"",notes:"",created:today()};c=newC;} if(iq.vehId!=="new")v=veh(iq.vehId); else{const vin=cleanVin($("#iq_vin").value),make=$("#iq_make").value.trim();if(!make&&!vin)return err("Enter the vehicle make, or a VIN.");if(vin&&!vinOk(vin))return err("That VIN does not look right: 17 characters, no I, O, or Q."); const ex=vin&&S.vehicles.find(x=>x.vin===vin);if(ex){if(ex.custId!==c.id)return err("That VIN is already on file for "+esc(cname(cust(ex.custId)))+". If the car changed owners, open the vehicle and change the owner first.");v=ex;} else newV={id:uid(),custId:c.id,type:"Car",fuel:"Gas",vin,year:$("#iq_year").value.trim(),make,model:$("#iq_model").value.trim(),trim:"",engine:"",color:$("#iq_color").value.trim(),miles:$("#iq_miles").value,plate:$("#iq_plate").value.trim().toUpperCase(),plateState:"NJ",regNo:"",regExp:"",insCarrier:"",insPolicy:"",insExp:"",tireSize:"",codes:"",photos:[]};} const locId=$("#iq_l").value,cmp=$("#iq_cmp").value.trim(),pk=$("#iq_pk").value,bay=$("#iq_b").value,tech=$("#iq_t").value;let appt=null; if(iq.when==="later"){appt={id:uid(),locId,date:$("#iq_d").value,start:$("#iq_s").value,dur:+$("#iq_du").value,bay,techId:tech,custId:c.id,vehId:(v||newV).id,service:cmp||(byId("packages",pk)||{}).name||"",packageId:pk,status:"Booked",jobId:"",notes:""}; if(!appt.date)return err("Pick a date.");if(toMin(appt.start)+appt.dur>toMin(S.settings.hours.close))return err("That runs past closing time.");const cf=apptConflict(appt);if(cf){conflictMsg(appt,cf,$("#iq_err"),"iqUse");return false;}} if(newC)S.customers.push(newC);if(newV){S.vehicles.push(newV);v=newV;} if(appt){S.appts.push(appt);log("Intake booked "+cname(c)+" "+appt.date+" "+appt.start);save();calDate=appt.date;calMode="day";if(myLocs().some(l=>l.id===locId))curLoc=locId;go("schedule");toast("Booked "+cname(c)+" on "+fmtD(appt.date)+" at "+fmtT(appt.start)+".");return true;} const j={id:uid(),locId,vehId:v.id,custId:c.id,complaint:cmp,status:"Checked in",bay,techId:tech,dateIn:today(),promised:$("#iq_due").value,events:[{t:new Date().toISOString(),by:me.username,msg:"Checked in at intake"}]};S.jobs.push(j); let e=null;if(pk&&byId("packages",pk)){e=estimateFromPackage(pk,c.id,v.id,j.id,locId);j.events.push({t:new Date().toISOString(),by:me.username,msg:"Estimate "+e.no+" started from package"});} log("Intake checked in "+vname(v)+" for "+cname(c));save();if(myLocs().some(l=>l.id===locId))curLoc=locId;go("board");toast("Checked in."+(e?" Estimate "+e.no+" is ready to review.":""));jobModal(j.id);return true;} /* ---------- service packages (the original Shop Manager kits) ---------- */ V.packages=()=>`
${EDIT_PRICES.includes(me.role)?``:""}A package is a ready-made set of labor and parts. Pick it at intake, on an appointment, or on an estimate and the lines fill in.
${seeMoney()?'':""}${S.packages.map(p=>`${seeMoney()?``:""}`).join("")||``}
PackageCategoryForLinesTimePrice before fees
${esc(p.name)}${esc(p.cat)}${esc(p.applies)}${p.lines.length}${durTxt(pkgMinutes(p))}${money(p.lines.reduce((s,l)=>s+(+l.q||0)*(+l.p||0),0))}
No packages yet.
`; function pkgModal(id){const p=id?byId("packages",id):{name:"",cat:"",applies:"Both",lines:[]},ed=EDIT_PRICES.includes(me.role);lineDraft=JSON.parse(JSON.stringify(p.lines));docDraftPay=[]; const pick=[["","Add from price book, parts, or tires..."]].concat(S.pricebook.map(x=>["pb:"+x.id,"Service: "+x.name]),S.parts.map(x=>["pt:"+x.id,"Part: "+x.sku+" "+x.name]),S.tires.map(x=>["tr:"+x.id,"Tire: "+x.size+" "+x.brand+" "+x.model])); openModal(`

${id?esc(p.name):"New service package"}

${ed?``:""}
TypeDescriptionQty or hoursPriceLine
${ed?``:""}
${id&&canDel()?``:""}${ed?``:""}
`);drawLines();} function pkgSave(id){const n=$("#pk_n").value.trim();if(!n){toast("Name the package.");return;}let p=id?byId("packages",id):null;if(!p){p={id:uid()};S.packages.push(p);} Object.assign(p,{name:n,cat:$("#pk_c").value.trim(),applies:$("#pk_a").value,lines:lineDraft.filter(l=>l.d||+l.p).map(l=>({t:l.t,d:l.d,q:+l.q||0,p:+l.p||0,c:+l.c||0,ref:l.ref||""}))});log("Saved package "+n);save();closeModal();render();toast("Package saved.");} function estimateFromPackage(pkId,custId,vehId,jobId,locId){const p=byId("packages",pkId);S.counters.estimate++;const d={id:uid(),type:"estimate",no:"E-"+S.counters.estimate,custId,vehId,jobId,locId,date:today(),status:"draft",lines:JSON.parse(JSON.stringify(p.lines)),notes:"",files:[],payments:[],by:me.username};S.docs.push(d);return d;} /* ---------- diagnostics (from the original Diagnostics tab) ---------- */ V.diagnostics=()=>`

Vehicle lookup

Trouble code lookup

Generic OBD-II code meanings (SAE standard). Maker-specific codes and repair steps need licensed service information. Codes saved on a vehicle show here when you pick it.

Live data comes from NHTSA (US Department of Transportation, public). Recall and complaint lookups need the CRM running from the shop computer or the web host; a file opened directly is blocked by the browser.

`; function dgFill(){const v=veh($("#dg_v").value);if(!v)return;$("#dg_vin").value=v.vin||"";$("#dg_y").value=v.year||"";$("#dg_mk").value=v.make||"";$("#dg_md").value=v.model||"";if(v.codes){$("#dg_q").value=v.codes;dgCodes();}} async function dgVin(){const vin=cleanVin($("#dg_vin").value),o=$("#dg_vinout");$("#dg_vin").value=vin;if(!vinOk(vin)){o.innerHTML=`

A VIN is 17 characters and never uses I, O, or Q.

`;return;}o.innerHTML=`

Decoding...

`; try{const d=(await (await fetch("https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVinValues/"+vin+"?format=json")).json()).Results[0];if(!d.Make){o.innerHTML=`

NHTSA did not recognize this VIN.

`;return;}$("#dg_y").value=d.ModelYear||"";$("#dg_mk").value=d.Make||"";$("#dg_md").value=d.Model||""; o.innerHTML=`
${[["Year",d.ModelYear],["Make",d.Make],["Model",d.Model],["Trim",d.Trim],["Body",d.BodyClass],["Drive",d.DriveType],["Engine",[d.DisplacementL?(+d.DisplacementL).toFixed(1)+"L":"",d.EngineCylinders?d.EngineCylinders+" cyl":"",d.EngineModel].filter(Boolean).join(" ")],["Fuel",d.FuelTypePrimary],["Transmission",d.TransmissionStyle],["Built in",[d.PlantCity,d.PlantCountry].filter(Boolean).join(", ")]].filter(x=>x[1]).map(x=>`
${x[0]}: ${esc(x[1])}
`).join("")}
`;} catch(e){o.innerHTML=`

Could not reach NHTSA. Check the internet connection.

`;}} function dgYMM(){const y=$("#dg_y").value.trim(),m=$("#dg_mk").value.trim(),md=$("#dg_md").value.trim();if(!y||!m||!md){$("#dg_out").innerHTML=`

Enter year, make, and model first (or pick a vehicle).

`;return null;}return {y,m,md};} async function dgRecalls(){const v=dgYMM();if(!v)return;const o=$("#dg_out");o.innerHTML=`

Checking recalls...

`; try{const l=(await (await fetch(`https://api.nhtsa.gov/recalls/recallsByVehicle?make=${encodeURIComponent(v.m)}&model=${encodeURIComponent(v.md)}&modelYear=${encodeURIComponent(v.y)}`)).json()).results||[]; o.innerHTML=`

${l.length} recall campaign${l.length===1?"":"s"} for ${esc(v.y+" "+v.m+" "+v.md)}

`+l.slice(0,15).map(x=>`
${esc(x.Component||"")} (${esc(x.NHTSACampaignNumber||"")})
${esc((x.Summary||"").slice(0,300))}${x.Remedy?`
Remedy: ${esc(x.Remedy.slice(0,200))}`:""}
`).join("");} catch(e){o.innerHTML=`

The recall service refused the request. Run the CRM from the shop computer (Start Quick Oil Change) or the web host.

`;}} async function dgComplaints(){const v=dgYMM();if(!v)return;const o=$("#dg_out");o.innerHTML=`

Loading owner complaints...

`; try{const l=(await (await fetch(`https://api.nhtsa.gov/complaints/complaintsByVehicle?make=${encodeURIComponent(v.m)}&model=${encodeURIComponent(v.md)}&modelYear=${encodeURIComponent(v.y)}`)).json()).results||[];const by={};l.forEach(c=>String(c.components||"Other").split(",").forEach(k=>{k=k.trim();by[k]=(by[k]||0)+1;})); o.innerHTML=`

${l.length} owner complaints filed with NHTSA. Most reported: ${Object.entries(by).sort((a,b)=>b[1]-a[1]).slice(0,5).map(x=>esc(x[0])+" ("+x[1]+")").join(", ")||"none"}

`+l.slice(0,12).map(c=>`
${esc(String(c.components||"").split(",").slice(0,2).join(", "))}${c.crash?' Crash':""}${c.fire?' Fire':""}
${esc((c.summary||"").slice(0,320))}
`).join("");} catch(e){o.innerHTML=`

The complaint service refused the request. Run the CRM from the shop computer or the web host.

`;}} function dgCodes(){const q=($("#dg_q").value||"").trim().toUpperCase(),parts=q.split(/[\s,]+/).filter(Boolean),out=$("#dg_codes"); const keys=Object.keys(OBD).filter(k=>!q||parts.some(p=>k.includes(p)||OBD[k].toUpperCase().includes(p))); const extra=parts.filter(p=>/^[PBCU][0-9A-F]{4}$/.test(p)&&!OBD[p]).map(p=>`
${esc(p)}: ${/^P030[1-9]$/.test(p)?"Cylinder "+p.slice(4)+" misfire":"Not in the built-in list. It may be maker-specific; check service information or ask the AI assistant."}
`); out.innerHTML=extra.join("")+keys.slice(0,60).map(k=>`
${k}: ${esc(OBD[k])}
`).join("")||`

No match.

`;} /* ---------- office to-do queue: one list of what needs a person, so nothing is done twice or forgotten ---------- */ function todos(){const T=[],add=(pri,txt,btn,act)=>T.push({pri,txt,btn,act}),tech=["tech","tire"].includes(me.role),nowM=new Date().getHours()*60+new Date().getMinutes(); S.jobs.filter(j=>inLoc(j)&&j.status!=="Picked up"&&(!tech||j.techId===me.id)).forEach(j=>{const v=esc(vname(veh(j.vehId))),c=esc(cname(cust(j.custId))),ds=docsOfJob(j.id),est=ds.filter(d=>d.type==="estimate").pop(),inv=ds.find(d=>d.type==="invoice"); if(isLate(j))add(1,`${v} for ${c} is past its promised date (${fmtD(j.promised)})`,"Open job",`jobModal('${j.id}')`); if(tech){if(["Checked in","Diagnosing"].includes(j.status))add(2,`Diagnose ${v}: ${esc(j.complaint||"no notes")}`,"Open job",`jobModal('${j.id}')`);if(j.status==="In repair")add(3,`Repair ${v}`,"Open job",`jobModal('${j.id}')`);return;} if(!est&&!inv&&["Checked in","Diagnosing"].includes(j.status)&&can("estimates"))add(3,`Write the estimate for ${v} (${c})`,"Write estimate",`docModal('estimate',null,'${j.id}')`); if(est&&est.status==="draft")add(3,`${esc(est.no)} for ${c} is still a draft. Review it and send for approval`,"Open",`docModal('estimate','${est.id}')`); if(est&&est.status==="sent"&&days(est.date)>=1)add(2,`${esc(est.no)} went to ${c} ${days(est.date)} day(s) ago with no answer`,"Call",`openCustomer('${j.custId}')`); if(["Ready","Quality check"].includes(j.status)&&!inv&&est&&est.status!=="declined"&&can("invoices"))add(2,`${v} is done. Make the invoice from ${esc(est.no)}`,"Make invoice",`toInvoice('${est.id}')`); if(j.status==="Ready"&&!j.notified)add(2,`Tell ${c} the ${v} is ready`,"Notify",`notifyModal('${j.id}')`); if(j.status==="Ready"&&inv&&totals(inv).due<0.005&&j.notified)add(4,`${c} is paid and notified. Mark the ${v} picked up when it leaves`,"Open job",`jobModal('${j.id}')`);}); if(!tech&&seeMoney()){const ow=[];for(const d of S.docs){if(d.type!=="invoice"||d.status==="void"||!inLoc(d)||days(d.date)<7)continue;const due=totals(d).due;if(due>0.004)ow.push([d,due]);} if(ow.length>5)add(2,`${ow.length.toLocaleString()} invoices are unpaid more than 7 days, ${money(ow.reduce((s,x)=>s+x[1],0))} in total`,"See the list",`invF='unpaid';docQ.invoice='';PG.doc_invoice=0;go('invoices')`); else ow.forEach(([d,due])=>add(2,`${esc(d.no)}: ${esc(cname(cust(d.custId)))} owes ${money(due)} (${days(d.date)} days)`,"Open",`docModal('invoice','${d.id}')`));} if(can("schedule")){S.appts.filter(a=>inLoc(a)&&a.date===today()&&["Booked","Confirmed"].includes(a.status)&&toMin(a.start)+15add(1,`${esc(cname(cust(a.custId)))} was due at ${fmtT(a.start)} and is not checked in`,"Open",`apptModal('${a.id}')`)); if(!tech)S.appts.filter(a=>inLoc(a)&&a.date===prevDay(today(),1)&&a.status==="Booked"&&!a.reminded).forEach(a=>add(3,`Remind ${esc(cname(cust(a.custId)))} about tomorrow at ${fmtT(a.start)}`,"Remind",`apptRemind('${a.id}')`));} if(!tech&&can("customers"))S.jobs.filter(j=>inLoc(j)&&j.status==="Picked up"&&!j.thanked&&S.settings.reviewUrl&&j.events.some(e=>/Status: Picked up/.test(e.msg)&&days(e.t.slice(0,10))<=7)).forEach(j=>add(4,`Thank ${esc(cname(cust(j.custId)))} and ask for a review`,"Thank",`thanksModal('${j.id}')`)); if(can("schedule"))S.appts.filter(a=>inLoc(a)&&a.status==="Requested").forEach(a=>add(1,`Website booking request: ${esc(cname(cust(a.custId)))} wants ${fmtD(a.date)} at ${fmtT(a.start)}`,"Confirm",`apptModal('${a.id}')`)); if(can("parts")){const lo=S.parts.filter(p=>inLoc(p)&&+p.qty<=+p.reorder);if(lo.length>5)add(3,`${lo.length.toLocaleString()} parts are at or below their reorder level`,"See the list",`partLow=true;partQ='';PG.parts=0;go('parts')`);else lo.forEach(p=>add(3,`Reorder ${esc(p.name)} (${p.qty} left)`,"Open",`formModal('parts','${p.id}')`));} if(!tech&&can("customers")){const soon=prevDay(today(),30);S.vehicles.forEach(v=>{if(v.regExp&&v.regExp>=today()&&v.regExp<=soon)add(4,`Registration on ${esc(cname(cust(v.custId)))}'s ${esc(vname(v))} expires ${fmtD(v.regExp)}`,"Open",`openCustomer('${v.custId}')`);}); {const ds=dueService();if(ds.length>5&&can("marketing"))add(4,`${ds.length.toLocaleString()} customers may be due for an oil change (no oil change in 5 months)`,"Plan a reminder campaign",`go('marketing')`);else ds.forEach(x=>add(4,`${esc(cname(x.c))} may be due for an oil change (last one ${fmtD(x.last)})`,"Contact",`sendModal('Service reminder for ${esc(cname(x.c)).replace(/'/g,"")}',cust('${x.c.id}'),serviceText('${x.c.id}'),'Time for service',null)`));}} if(can("lot"))S.lot.filter(l=>inLoc(l)&&l.status==="For sale"&&days(l.acquired)>45).forEach(l=>add(4,`${esc(l.year+" "+l.make+" "+l.model)} has been for sale ${days(l.acquired)} days. Review the price`,"Open",`lotModal('${l.id}')`)); return T.sort((a,b)=>a.pri-b.pri);} function dueService(){const out=[];S.customers.forEach(c=>{const ds=docsOfCust(c.id).filter(d=>d.type==="invoice"&&d.lines.some(l=>/oil/i.test(l.d)));if(!ds.length)return;const last=ds.map(d=>d.date).sort().pop();if(days(last)>=150)out.push({c,last});});return out;} function serviceText(cid){const c=cust(cid);return fillMsg(msgTpl("service"),baseVars(c));} let showAllTodo=false; function todoPanel(){const T=todos(),list=showAllTodo?T:T.slice(0,10);const dot={1:"var(--bad)",2:"var(--warn)",3:"var(--accent)",4:"var(--muted)"}; return `

Needs attention (${T.length})

${list.map(t=>`
${t.txt}
`).join("")||`

All caught up. New tasks appear here on their own as cars move through the shop.

`}${T.length>10?``:""}
`;} function nextStep(j){if(!j||!j.id)return "";const ds=docsOfJob(j.id),est=ds.filter(d=>d.type==="estimate").pop(),inv=ds.find(d=>d.type==="invoice"); if(j.status==="Picked up")return "Done. This job is closed.";if(!est&&!inv)return "Next: diagnose and write the estimate.";if(est&&est.status==="draft")return "Next: review "+est.no+" and send it to the customer.";if(est&&est.status==="sent")return "Waiting for the customer to approve "+est.no+".";if(est&&est.status==="declined")return est.no+" was declined. Talk to the customer or close the job."; if(["Waiting parts"].includes(j.status))return "Waiting on parts. Add a timeline update when they arrive.";if(["In repair","Quality check"].includes(j.status))return "Repair in progress. Set the status to Ready when done.";if(j.status==="Ready"&&!inv)return "Next: make the invoice from "+est.no+".";if(j.status==="Ready"&&!j.notified)return "Next: tell the customer the car is ready.";if(inv&&totals(inv).due>0.004)return "Next: collect "+money(totals(inv).due)+" on "+inv.no+".";return "Next: mark it picked up when the customer leaves.";} /* ---------- real PDF (jsPDF, from the original app) with the letterhead ---------- */ function pdfDoc(id){const d=doc(id);if(!window.jspdf){toast("The PDF engine did not load. Use Print, then Save as PDF.");return;} const {jsPDF}=window.jspdf,p=new jsPDF({unit:"pt",format:"letter"}),s=S.settings,L=byId("locations",d.locId),c=cust(d.custId),v=veh(d.vehId),t=totals(d),M=40,R=572;let y=36; if(s.logo){try{const ip=p.getImageProperties(s.logo),h=50,w=Math.min(180,ip.width*h/ip.height);p.addImage(s.logo,/^data:image\/png/.test(s.logo)?"PNG":"JPEG",M,y,w,h);}catch(e){}} p.setFont("helvetica","bold");p.setFontSize(16);p.text(s.name,R,y+14,{align:"right"});p.setFont("helvetica","normal");p.setFontSize(9);p.setTextColor(90);p.text((L&&L.address)||s.address,R,y+28,{align:"right"});p.text([(L&&L.phone)||s.phone,(L&&L.email)||s.email].filter(Boolean).join(" "),R,y+40,{align:"right"});p.setTextColor(20); y+=60;p.setDrawColor(201,162,58);p.setLineWidth(2);p.line(M,y,R,y);p.setLineWidth(.5);p.setDrawColor(180);y+=26; p.setFont("helvetica","bold");p.setFontSize(15);p.text((d.type==="estimate"?"Estimate ":"Invoice ")+d.no,M,y);p.setFont("helvetica","normal");p.setFontSize(10);p.text("Date: "+fmtD(d.date),R,y,{align:"right"});y+=22; p.setFont("helvetica","bold");p.text("Customer",M,y);p.text("Vehicle",320,y);p.setFont("helvetica","normal");y+=14; const cl=[cname(c),c&&c.phone,c&&c.email,c&&[c.address,c.city,c.state,c.zip].filter(Boolean).join(", ")].filter(Boolean),vl=[vname(v),v&&v.vin&&"VIN "+v.vin,v&&v.plate&&"Plate "+v.plate,v&&v.miles&&Number(v.miles).toLocaleString()+" miles"].filter(Boolean); for(let i=0;i{p.setFillColor(240,238,232);p.rect(M,y-12,R-M,18,"F");p.setFont("helvetica","bold");p.text("Type",M+4,y);p.text("Description",96,y);p.text("Qty",400,y,{align:"right"});p.text("Price",480,y,{align:"right"});p.text("Amount",R-4,y,{align:"right"});p.setFont("helvetica","normal");y+=18;};th(); d.lines.forEach(l=>{const ds=p.splitTextToSize(String(l.d||""),290);if(y+ds.length*12>720){p.addPage();y=50;th();}p.text(String(l.t),M+4,y);p.text(ds,96,y);p.text(String(l.q),400,y,{align:"right"});p.text(money(l.p),480,y,{align:"right"});p.text(money(l.q*l.p),R-4,y,{align:"right"});y+=ds.length*12+5;}); if(y>600){p.addPage();y=50;}y+=4;p.line(330,y,R,y);y+=16;const row=(a,b,bold)=>{p.setFont("helvetica",bold?"bold":"normal");p.text(a,470,y,{align:"right"});p.text(b,R-4,y,{align:"right"});y+=15;}; row("Parts and tires",money(t.parts));row("Labor",money(t.labor));if(t.supplies)row("Shop supplies",money(t.supplies));if(t.env)row("Environmental fee",money(t.env));row("Sales tax ("+s.tax+"%)",money(t.tax));row("Total",money(t.total),1);if(d.type==="invoice"){row("Paid",money(t.paid));row("Balance due",money(t.due),1);} if(d.notes){const nl=p.splitTextToSize(d.notes,R-M).slice(0,10);if(y+nl.length*12>720){p.addPage();y=50;}y+=6;p.setFont("helvetica","bold");p.text("Notes",M,y);y+=13;p.setFont("helvetica","normal");p.text(nl,M,y);y+=nl.length*12;} if(d.type==="estimate"){if(y>700){p.addPage();y=50;}y+=24;p.text("Customer approval: ______________________________ Date: ____________",M,y);} const n=p.getNumberOfPages();for(let i=1;i<=n;i++){p.setPage(i);p.setFontSize(8);p.setTextColor(110);p.text(String(s.footer+" "+s.name+", "+s.phone).slice(0,110),M,755);p.setFontSize(7);p.text(urbnixLine(),M,767);p.setFontSize(8);p.text("Page "+i+" of "+n,R,762,{align:"right"});} p.save((d.type==="estimate"?"Estimate ":"Invoice ")+d.no+" - "+cname(c).replace(/[^\w ]/g,"")+".pdf");log("Downloaded PDF "+d.no);save();} /* ---------- Excel (SheetJS, from the original app) ---------- */ function readRows(file){return new Promise((res,rej)=>{const isText=/\.(csv|txt)$/i.test(file.name)||!window.XLSX,r=new FileReader(); r.onload=()=>{try{if(isText)res(parseCSV(r.result));else{const wb=XLSX.read(new Uint8Array(r.result),{type:"array"}),ws=wb.Sheets[wb.SheetNames[0]];res(XLSX.utils.sheet_to_json(ws,{header:1,raw:false,defval:""}).map(row=>row.map(x=>String(x))).filter(x=>x.some(v=>v.trim())));}}catch(e){rej(e);}}; r.onerror=()=>rej(r.error||new Error("read failed"));if(isText)r.readAsText(file);else r.readAsArrayBuffer(file);});} function exportXlsx(){if(!window.XLSX){toast("The Excel engine did not load. Use the CSV buttons instead.");return;}const wb=XLSX.utils.book_new(),pii=seePII(),mon=seeMoney(),add=(n,rows)=>XLSX.utils.book_append_sheet(wb,XLSX.utils.aoa_to_sheet(rows),n); add("Customers",[["First","Last","Company","Phone","Other phone","Email","Address","City","State","ZIP","Contact by"].concat(pii?["License number","License state","License expires"]:[])].concat(S.customers.map(c=>[c.first,c.last,c.company,c.phone,c.phone2,c.email,c.address,c.city,c.state,c.zip,c.pref].concat(pii?[c.dlNo,c.dlState,c.dlExp]:[])))); add("Vehicles",[["Owner","Owner phone","Year","Make","Model","Trim","Type","VIN","Plate","Mileage","Tire size"].concat(pii?["Registration","Reg expires","Insurance","Policy","Ins expires"]:[])].concat(S.vehicles.map(v=>{const c=cust(v.custId);return [cname(c),c?c.phone:"",v.year,v.make,v.model,v.trim,v.type,v.vin,v.plate,v.miles,v.tireSize].concat(pii?[v.regNo,v.regExp,v.insCarrier,v.insPolicy,v.insExp]:[]);}))); if(mon){add("Invoices",[["Number","Date","Location","Customer","Phone","Vehicle","Status","Parts","Labor","Supplies","Env fee","Tax","Total","Paid","Due"]].concat(S.docs.filter(d=>d.type==="invoice").map(d=>{const t=totals(d),c=cust(d.custId);return [d.no,d.date,locName(d.locId),cname(c),c?c.phone:"",vname(veh(d.vehId)),d.status,t.parts,t.labor,t.supplies,t.env,+t.tax.toFixed(2),+t.total.toFixed(2),t.paid,+t.due.toFixed(2)];}))); add("Estimates",[["Number","Date","Customer","Vehicle","Status","Total"]].concat(S.docs.filter(d=>d.type==="estimate").map(d=>[d.no,d.date,cname(cust(d.custId)),vname(veh(d.vehId)),d.status,+totals(d).total.toFixed(2)]))); add("Document lines",[["Document","Type","Description","Qty","Price","Amount"]].concat(S.docs.flatMap(d=>d.lines.map(l=>[d.no,l.t,l.d,l.q,l.p,+(l.q*l.p).toFixed(2)]))));} add("Schedule",[["Date","Start","Minutes","Bay","Customer","Vehicle","Service","Technician","Status","Location"]].concat(S.appts.map(a=>[a.date,a.start,a.dur,a.bay,cname(cust(a.custId)),vname(veh(a.vehId)),a.service,(user(a.techId)||{}).display||"",a.status,locName(a.locId)]))); add("Repair jobs",[["Date in","Promised","Status","Customer","Vehicle","Bay","Technician","Complaint","Location"]].concat(S.jobs.map(j=>[j.dateIn,j.promised,j.status,cname(cust(j.custId)),vname(veh(j.vehId)),j.bay,(user(j.techId)||{}).display||"",j.complaint,locName(j.locId)]))); add("Parts",[["Part number","Description","Category","Vendor"].concat(mon?["Cost"]:[],["Price","On hand","Reorder at","Bin","Location"])].concat(S.parts.map(p=>[p.sku,p.name,p.cat,(byId("vendors",p.vendorId)||{}).name||""].concat(mon?[p.cost]:[],[p.price,p.qty,p.reorder,p.bin,locName(p.locId)])))); add("Tires",[["Brand","Model","Size","Type","On hand"].concat(mon?["Cost"]:[],["Price","Location"])].concat(S.tires.map(t=>[t.brand,t.model,t.size,t.season,t.qty].concat(mon?[t.cost]:[],[t.price,locName(t.locId)])))); add("Vendors",[["Name","Contact","Phone","Email","Terms","Markup %"]].concat(S.vendors.map(v=>[v.name,v.contact,v.phone,v.email,v.terms,v.markup]))); add("Packages",[["Package","Category","For","Type","Description","Qty","Price"]].concat(S.packages.flatMap(p=>p.lines.map(l=>[p.name,p.cat,p.applies,l.t,l.d,l.q,l.p])))); add("Price book",[["Category","Service","Hours","Our price","Market low","Market high","Source"]].concat(S.pricebook.map(p=>[p.cat,p.name,p.hours,p.price,p.low,p.high,p.src]))); if(can("lot"))add("Cars for sale",[["Year","Make","Model","VIN","Miles","Status","Asking"].concat(mon?["Paid","Reconditioning"]:[])].concat(S.lot.map(l=>[l.year,l.make,l.model,l.vin,l.miles,l.status,l.list].concat(mon?[l.cost,lotCost(l)-(+l.cost||0)]:[])))); XLSX.writeFile(wb,String(S.settings.name).replace(/[^\w ]/g,"")+" export "+today()+".xlsx");log("Exported everything to Excel");save();} function xlsxTemplate(){if(!window.XLSX){toast("The Excel engine did not load.");return;}const wb=XLSX.utils.book_new(),add=(n,h,ex)=>XLSX.utils.book_append_sheet(wb,XLSX.utils.aoa_to_sheet([h,ex]),n); add("Customers",["first","last","phone","email","address","city","state","zip"],["Jane","Doe","(201) 555-0123","jane@example.com","1 Main St","Bayonne","NJ","07002"]); XLSX.writeFile(wb,"Customer import template.xlsx");toast("Template downloaded. Fill it in, keep the first row, then use Import.");} /* ---------- inactivity sign-out and background refresh ---------- */ let lastAct=Date.now();["mousemove","keydown","touchstart","click","scroll"].forEach(ev=>document.addEventListener(ev,()=>{lastAct=Date.now();},{passive:true})); setInterval(()=>{if(me&&S&&+S.settings.security.idleMins>0&&Date.now()-lastAct>S.settings.security.idleMins*60000){closeModal();logout();toast("Signed out after "+S.settings.security.idleMins+" minutes with no activity.");}},30000); setInterval(pollServer,20000); /* ======================= v3.1: marketing, holidays, discount codes, messages, connections, API keys ======================= */ /* ---------- SHA-256 in plain JavaScript: phones and tablets on the shop network (plain http) have no secure hashing in the browser ---------- */ const SHA_K=new Uint32Array([0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2]); function sha256js(str){const m=new TextEncoder().encode(str),l=m.length,n=((l+9+63)>>6)<<6,buf=new Uint8Array(n);buf.set(m);buf[l]=0x80;const dv=new DataView(buf.buffer),bits=l*8;dv.setUint32(n-4,bits>>>0);dv.setUint32(n-8,Math.floor(bits/4294967296)); const H=new Uint32Array([0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19]),W=new Uint32Array(64),r=(x,k)=>(x>>>k)|(x<<(32-k)); for(let i=0;i>>3),s1=r(W[t-2],17)^r(W[t-2],19)^(W[t-2]>>>10);W[t]=(W[t-16]+s0+W[t-7]+s1)>>>0;} let a=H[0],b=H[1],c=H[2],d=H[3],e=H[4],f=H[5],g=H[6],h=H[7]; for(let t=0;t<64;t++){const t1=(h+(r(e,6)^r(e,11)^r(e,25))+((e&f)^(~e&g))+SHA_K[t]+W[t])>>>0,t2=((r(a,2)^r(a,13)^r(a,22))+((a&b)^(a&c)^(b&c)))>>>0;h=g;g=f;f=e;e=(d+t1)>>>0;d=c;c=b;b=a;a=(t1+t2)>>>0;} H[0]+=a;H[1]+=b;H[2]+=c;H[3]+=d;H[4]+=e;H[5]+=f;H[6]+=g;H[7]+=h;} return Array.from(H,x=>x.toString(16).padStart(8,"0")).join("");} const rnd=n=>Array.from(crypto.getRandomValues(new Uint8Array(n)),b=>b.toString(16).padStart(2,"0")).join(""); /* ---------- shop theme selection: picking a theme always takes effect ---------- */ function setShopTheme(k){const t=S.settings.theme;t.preset=k;t.brand="";t.side="";t.accent="";if(me)me.theme="";log("Shop theme: "+THEMES[k].name);save();render();toast(THEMES[k].name+" is now the theme for everyone.");} function liveColor(k,v){document.documentElement.style.setProperty("--"+k,v);} /* ---------- holidays: fixed-rule dates are calculated; moon-based dates are published estimates ---------- */ const HOLI_FIXED={hanukkah:{2026:"2026-12-04",2027:"2027-12-24",2028:"2028-12-12"},ramadan:{2027:"2027-02-08",2028:"2028-01-28"},eid_fitr:{2027:"2027-03-09",2028:"2028-02-27"},eid_adha:{2027:"2027-05-16"}}; const HOLI_INFO={newyear:["New Year's Day","Everyone",0],thanksgiving:["Thanksgiving","Everyone",0],christmas:["Christmas","Christian",0],hanukkah:["Hanukkah (begins at sundown)","Jewish",1],easter:["Easter","Christian",0],ramadan:["Ramadan begins","Muslim",1],eid_fitr:["Eid al-Fitr","Muslim",1],eid_adha:["Eid al-Adha","Muslim",1],memorial:["Memorial Day","Everyone",0],july4:["Independence Day","Everyone",0],labor:["Labor Day","Everyone",0],season:["Season's greetings","Everyone",0]}; const FAITH=["christmas","hanukkah","easter","ramadan","eid_fitr","eid_adha"]; function nthWeekday(y,mo,wd,n){const d=new Date(y,mo,1);let c=0;while(true){if(d.getDay()===wd&&++c===n)break;d.setDate(d.getDate()+1);}return d;} function lastWeekday(y,mo,wd){const d=new Date(y,mo+1,0);while(d.getDay()!==wd)d.setDate(d.getDate()-1);return d;} function easter(y){const a=y%19,b=Math.floor(y/100),c=y%100,d=Math.floor(b/4),e=b%4,f=Math.floor((b+8)/25),g=Math.floor((b-f+1)/3),h=(19*a+b-d-g+15)%30,i=Math.floor(c/4),k=c%4,l=(32+2*e+2*i-h-k)%7,m=Math.floor((a+11*h+22*l)/451),mo=Math.floor((h+l-7*m+114)/31),dy=((h+l-7*m+114)%31)+1;return new Date(y,mo-1,dy);} const ymd=d=>d.getFullYear()+"-"+String(d.getMonth()+1).padStart(2,"0")+"-"+String(d.getDate()).padStart(2,"0"); function holidays(){const out=[],y0=new Date().getFullYear(),start=today(),end=prevDay(today(),400); for(const y of [y0,y0+1]){const add=(k,d,exp)=>{const s=typeof d==="string"?d:ymd(d);if(s>=start&&s<=end)out.push({k,date:s,name:HOLI_INFO[k][0],who:HOLI_INFO[k][1],expected:!!exp});}; add("newyear",new Date(y,0,1));add("easter",easter(y));add("memorial",lastWeekday(y,4,1));add("july4",new Date(y,6,4));add("labor",nthWeekday(y,8,1,1));add("thanksgiving",nthWeekday(y,10,4,4));add("christmas",new Date(y,11,25)); ["hanukkah","ramadan","eid_fitr","eid_adha"].forEach(k=>{if(HOLI_FIXED[k][y])add(k,HOLI_FIXED[k][y],HOLI_INFO[k][2]);});} const seen={};return out.filter(h=>{const id=h.k+h.date;if(seen[id])return false;seen[id]=1;return true;}).sort((a,b)=>a.date.localeCompare(b.date));} const TPL={ christmas:["Merry Christmas from {shop}","Hi {first},\n\nMerry Christmas from all of us at {shop}! Thank you for trusting us with your vehicle this year.{offer_line}\n\nWishing you and your family a safe and joyful holiday."], hanukkah:["Happy Hanukkah from {shop}","Hi {first},\n\nWishing you and your family a happy and bright Hanukkah from all of us at {shop}.{offer_line}\n\nThank you for being part of our shop family."], newyear:["Happy New Year from {shop}","Hi {first},\n\nThank you for a great year. Everyone at {shop} wishes you a happy, healthy, and safe New Year.{offer_line}\n\nSee you on the road in the new year!"], thanksgiving:["Thank you, {first}","Hi {first},\n\nThis Thanksgiving, we are grateful for customers like you. Thank you for choosing {shop}.{offer_line}\n\nHappy Thanksgiving to you and your family."], easter:["Happy Easter from {shop}","Hi {first},\n\nWishing you and your loved ones a blessed and joyful Easter from all of us at {shop}.{offer_line}"], ramadan:["Ramadan Mubarak from {shop}","Hi {first},\n\nRamadan Mubarak! Wishing you and your family a blessed and peaceful Ramadan from all of us at {shop}.{offer_line}"], eid_fitr:["Eid Mubarak from {shop}","Hi {first},\n\nEid Mubarak! Wishing you and your loved ones a joyful Eid al-Fitr from all of us at {shop}.{offer_line}"], eid_adha:["Eid al-Adha Mubarak from {shop}","Hi {first},\n\nWishing you and your family a blessed Eid al-Adha from all of us at {shop}.{offer_line}"], memorial:["Road-trip ready for Memorial Day?","Hi {first},\n\nHeading out this Memorial Day weekend? Let {shop} check your tires, brakes, and fluids before you go.{offer_line}"], july4:["Happy Fourth of July from {shop}","Hi {first},\n\nHappy Independence Day from {shop}! Driving to a cookout or the shore? We can check your car before the trip.{offer_line}"], labor:["Labor Day car check","Hi {first},\n\nHappy Labor Day from {shop}! Thank you for your hard work all year.{offer_line}"], season:["Season's greetings from {shop}","Hi {first},\n\nWarm wishes for the holiday season from everyone at {shop}. Thank you for your trust this year.{offer_line}"], repeat:["A thank-you for you, {first}","Hi {first},\n\nYou have trusted {shop} with {visits} visits, and we appreciate it.{offer_line}\n\nCall us at {phone} or just stop by."], winback:["We miss you, {first}","Hi {first},\n\nIt has been a while since we saw your {vehicle} at {shop}. Is it due for an oil change or a check-up?{offer_line}\n\nCall {phone} to book a time that works for you."], service:["Time for service, {first}","Hi {first},\n\nYour {vehicle} may be due for an oil change. Call {shop} at {phone} to book.{offer_line}"], custom:["",""]}; const PURPOSES=[["holiday","Holiday greeting"],["repeat","Thank-you discount for repeat customers"],["winback","Win back customers we have not seen"],["service","Service reminder"],["custom","Custom message"]]; /* ---------- message templates for single customers (car ready, reminder, thank-you) ---------- */ const MSG_DEF={ready:"Hi {first}, your {vehicle} is ready for pickup at {shop}, {address}.{balance} Questions? Call {phone}.",reminder:"Hi {first}, this is {shop}. Reminder: your appointment is {when}{service}, {address}. Reply to confirm or call {phone}.",thanks:"Hi {first}, thank you for choosing {shop} for your {vehicle}. If we earned it, a quick review helps a lot: {review}",service:"Hi {first}, it has been a while since your last oil change at {shop}. Reply or call {phone} to book a time that works for you."}; function fillMsg(tpl,v){return String(tpl||"").replace(/\{(\w+)\}/g,(m,k)=>v[k]!=null?v[k]:"").replace(/[ \t]+\n/g,"\n").replace(/ {2,}/g," ").trim();} function baseVars(c,locId){const s=S.settings,L=locId?byId("locations",locId):S.locations[0];return {first:c?c.first||"":"",last:c?c.last||"":"",name:cname(c),shop:s.name,phone:(L&&L.phone)||s.phone,address:(L&&L.address)||s.address,review:s.reviewUrl||""};} /* ---------- audience, consent, discount ---------- */ const visitsOf=id=>docsOfCust(id).reduce((n,d)=>n+(d.type==="invoice"&&d.status!=="void"?1:0),0); const lastVisit=id=>docsOfCust(id).reduce((m,d)=>d.type==="invoice"&&d.status!=="void"&&d.date>m?d.date:m,""); function audienceOf(cp){const a=cp.audience||{},kind=a.kind||"all"; return S.customers.filter(c=>{if(c.optOut)return false; if(kind==="repeat")return visitsOf(c.id)>=(+a.minVisits||2); if(kind==="lapsed"){const lv=lastVisit(c.id);return lv&&days(lv)>=(+a.days||180);} if(kind==="tag")return String(c.tags||"").toLowerCase().split(",").map(x=>x.trim()).includes(String(a.tag||"").toLowerCase().trim()); if(kind==="greeting")return (c.greetings||[]).includes(cp.holiday); return true;});} function reach(cp){const list=audienceOf(cp),em=[],sm=[],skip=[];list.forEach(c=>{const e=(cp.channel!=="sms")&&c.mktEmail&&c.email,t=(cp.channel!=="email")&&c.mktSms&&digits(c.phone).length>=10;if(e)em.push(c);if(t)sm.push(c);if(!e&&!t)skip.push(c);});return {list,em,sm,skip};} function offerText(dc){if(!dc||!dc.kind||dc.kind==="none"||!(+dc.value))return "";return (dc.kind==="pct"?(+dc.value)+"% off":money(+dc.value)+" off")+(+dc.minSpend?" orders over "+money(+dc.minSpend):"");} function campVars(cp,c){const dc=cp.discount||{},v=baseVars(c),veh0=c?vehsOfCust(c.id)[0]:undefined;const off=offerText(dc); return Object.assign(v,{visits:c?visitsOf(c.id):"",vehicle:veh0?vname(veh0):"car",code:dc.code||"",offer:off,expires:dc.expires?fmtD(dc.expires):"",offer_line:off?`\n\nAs a thank-you, enjoy ${off} on your next visit with code ${dc.code}${dc.expires?" (good until "+fmtD(dc.expires)+")":""}.`:""});} function unsubLink(c){return serverCaps.hosted&&c.unsubToken?location.origin+location.pathname.replace(/[^/]*$/,"")+"api/unsub?t="+c.unsubToken:"";} function emailFooter(c){const s=S.settings,u=unsubLink(c);return `\n\n${s.name}\n${s.address}\n${s.phone}\n\nYou are getting this because you are a customer of ${s.name}. ${u?"To stop these emails, open: "+u:"To stop these emails, reply STOP."}`;} const smsFooter="\nReply STOP to opt out."; /* ---------- Marketing module ---------- */ let mkTab="campaigns"; V.marketing=()=>{const tabs=[["campaigns","Campaigns"],["holidays","Holiday calendar"],["messages","Customer messages"],["consent","Consent and opt-outs"]]; return `
${tabs.map(t=>``).join("")}
`+MK[mkTab]();}; const MK={}; MK.campaigns=()=>{const rows=S.campaigns.slice().sort((a,b)=>(b.created||"").localeCompare(a.created||"")); return `
${seeMoney()?'':""} ${rows.map(cp=>{const r=reach(cp),uses=(cp.discount&&cp.discount.uses)||[],rev=uses.reduce((s,u)=>{const d=doc(u.docId);return s+(d?totals(d).total:0);},0); return `${seeMoney()?``:""}`;}).join("")||``}
CampaignPurposeChannelReachStatusSentCodes usedInvoices with code
${esc(cp.name)}${cp.holiday?`
${esc((HOLI_INFO[cp.holiday]||[""])[0])}`:""}
${esc((PURPOSES.find(p=>p[0]===cp.purpose)||["",""])[1])}${esc(cp.channel)}${r.em.length+r.sm.length}${esc(cp.status)}${(cp.sent||[]).length}${uses.length}${money(rev)}
No campaigns yet. Start with a holiday greeting or a thank-you discount for repeat customers.

Only customers who agreed to receive marketing get campaigns, and anyone who opts out is skipped automatically. Every email carries your address and a way to stop. Texts carry "Reply STOP to opt out." Marketing texts need the customer's written consent; record it on the customer record.

`;}; MK.holidays=()=>`
${holidays().map(h=>``).join("")}
DateHolidayFor
${fmtD(h.date)}${h.expected?' Expected':""}${esc(h.name)}${esc(h.who)}

Hanukkah 2026 begins at sundown on Friday, December 4. Ramadan and the two Eids follow the moon, so their dates are published estimates; confirm locally a few days before sending. Faith-specific greetings go only to customers who asked for that greeting on their customer record. Everyone else can get "Season's greetings" or "Happy New Year".

`; MK.messages=()=>{const m=Object.assign({},MSG_DEF,S.settings.msg||{}); return `

Messages to single customers

Used for car-ready notices, appointment reminders, and thank-you notes. Words in braces fill in on their own: {first}, {vehicle}, {shop}, {phone}, {address}, {when}, {service}, {balance}, {review}.

`;}; function saveMsgs(){S.settings.msg={ready:$("#ms_ready").value,reminder:$("#ms_reminder").value,thanks:$("#ms_thanks").value,service:$("#ms_service").value};S.settings.reviewUrl=$("#ms_rev").value.trim();S.settings.autoReady=$("#ms_auto").checked;log("Updated customer message wording");save();toast("Messages saved.");} MK.consent=()=>{const cs=S.customers,emY=cs.filter(c=>c.mktEmail&&!c.optOut).length,smY=cs.filter(c=>c.mktSms&&!c.optOut).length,out=cs.filter(c=>c.optOut); return `
${kpi("Agreed to marketing emails",emY,"ok")}${kpi("Agreed to marketing texts",smY,"ok")}${kpi("Opted out",out.length,out.length?"bad":"")}${kpi("No answer yet",cs.filter(c=>!c.mktEmail&&!c.mktSms&&!c.optOut).length)}

Record a STOP reply

Opted out (${out.length})

${out.map(c=>`
${esc(cname(c))} ${esc(c.phone)} ${esc(c.email)}${c.optOutAt?" | since "+fmtD(c.optOutAt.slice(0,10)):""}
`).join("")||`

Nobody has opted out.

`}

Ask at intake: "Can we send you holiday greetings and the occasional discount?" Tick the boxes on the customer record. For texts, keep proof of the yes (a signed form or the customer texting YES).

`;}; function optOut(id){if(!id){toast("Pick a customer.");return;}const c=cust(id);c.optOut=true;c.mktEmail=false;c.mktSms=false;c.optOutAt=new Date().toISOString();log("Opted out "+cname(c));save();render();toast(cname(c)+" will not get marketing.");} function optIn(id){const c=cust(id);if(!confirm("Only do this if "+cname(c)+" asked to receive marketing again. Continue?"))return;c.optOut=false;log("Opted back in "+cname(c));save();render();} let cpDraft=null; function campModal(id,preset){const cp=id?byId("campaigns",id):Object.assign({name:"",purpose:"holiday",holiday:"season",channel:"email",audience:{kind:"all",minVisits:2,days:180,tag:""},subject:"",body:"",discount:{kind:"none",value:"",code:"",expires:"",minSpend:""},status:"draft",sent:[],sendOn:today()},preset||{}); if(!id){if(cp.purpose==="holiday"&&FAITH.includes(cp.holiday))cp.audience={kind:"greeting"};if(cp.purpose==="repeat"){cp.audience={kind:"repeat",minVisits:2};cp.discount={kind:"pct",value:10,code:"THANKS"+String(new Date().getFullYear()).slice(2),expires:prevDay(today(),45),minSpend:""};} if(cp.purpose==="winback")cp.audience={kind:"lapsed",days:180};const k=cp.purpose==="holiday"?cp.holiday:cp.purpose,t=TPL[k]||TPL.custom;if(!cp.subject)cp.subject=t[0];if(!cp.body)cp.body=t[1]; if(!cp.name)cp.name=cp.purpose==="holiday"?(HOLI_INFO[cp.holiday]||["Holiday"])[0]+" "+new Date().getFullYear():(PURPOSES.find(p=>p[0]===cp.purpose)||["","Campaign"])[1];} cpDraft=JSON.parse(JSON.stringify(cp));cpDraft.id=id||"";const a=cpDraft.audience,dc=cpDraft.discount||{},locked=cp.status==="sent"; openModal(`

${id?esc(cp.name):"New campaign"}

${locked?`

This campaign was sent. You can still see who got it and how many used the code.

`:""}
Discount (optional)

The front desk types the code on the estimate or invoice. Each use is counted here.

Fills in on its own: {first}, {shop}, {phone}, {vehicle}, {visits}, {offer}, {code}, {expires}, {offer_line}. Your address and a way to stop are added to every email automatically.

${(cp.sent||[]).length?`
Sent to ${cp.sent.length}${cp.sent.map(x=>`
${esc(cname(cust(x.custId)))} by ${esc(x.ch)} ${new Date(x.at).toLocaleString()} ${esc(x.status||"")}
`).join("")}
`:""}
${id&&canDel()?``:""}${locked?"":``}
`);cpPurpose(2);} function cpRead(){const d=cpDraft;Object.assign(d,{name:$("#cp_n").value.trim()||"Campaign",purpose:$("#cp_p").value,holiday:$("#cp_h").value,channel:$("#cp_ch").value,subject:$("#cp_s").value,body:$("#cp_b").value,audience:{kind:$("#cp_a").value,minVisits:+$("#cp_mv").value||2,days:+$("#cp_d").value||180,tag:$("#cp_t").value.trim()}}); d.discount=Object.assign(d.discount||{},{kind:$("#cp_dk").value,value:+$("#cp_dv").value||0,code:$("#cp_dc").value.trim().toUpperCase().replace(/[^A-Z0-9-]/g,""),expires:$("#cp_de").value,minSpend:+$("#cp_dm").value||0});d.discount.uses=d.discount.uses||[];return d;} function cpPurpose(mode){const p=$("#cp_p").value,h=$("#cp_h").value;$("#cp_hw").style.display=p==="holiday"?"":"none"; if(mode!==2){const k=p==="holiday"?h:p,t=TPL[k]||TPL.custom;if(t[0]){$("#cp_s").value=t[0];$("#cp_b").value=t[1];}if(p==="holiday")$("#cp_a").value=FAITH.includes(h)?"greeting":"all";if(p==="repeat")$("#cp_a").value="repeat";if(p==="winback")$("#cp_a").value="lapsed"; $("#cp_n").value=p==="holiday"?(HOLI_INFO[h]||["Holiday"])[0]+" "+new Date().getFullYear():(PURPOSES.find(x=>x[0]===p)||["","Campaign"])[1];} cpPreview();} function cpPreview(){const d=cpRead(),r=reach(d),c=r.em[0]||r.sm[0]||r.list[0]||S.customers[0],v=campVars(d,c),dc=d.discount; const warn=[];if(dc.kind!=="none"&&(!dc.code||!(+dc.value)))warn.push("Give the discount an amount and a code.");if(dc.kind!=="none"&&dc.code&&S.campaigns.some(x=>x.id!==d.id&&x.discount&&x.discount.code===dc.code))warn.push("Another campaign already uses code "+dc.code+".");if(d.purpose==="holiday"&&FAITH.includes(d.holiday)&&d.audience.kind!=="greeting")warn.push("This is a faith holiday. Consider sending it only to customers who asked for this greeting."); $("#cp_prev").innerHTML=`Will reach ${r.em.length} by email and ${r.sm.length} by text. ${r.skip.length?`${r.skip.length} in this group are skipped (no consent or no contact).`:""}${warn.map(w=>`

${esc(w)}

`).join("")} ${c?`

Preview for ${esc(cname(c))}:

${d.channel!=="sms"?`
${esc(fillMsg(d.subject,v))}\n\n${esc(fillMsg(d.body,v)+emailFooter(c))}
`:""}${d.channel!=="email"?`
${esc(fillMsg(d.body,v).replace(/\n\n+/g," ")+smsFooter)}
`:""}`:""}`;} function cpStore(){const d=cpRead();let cp=d.id?byId("campaigns",d.id):null;if(!cp){cp={id:uid(),created:new Date().toISOString(),status:"draft",sent:[],by:me.username};S.campaigns.push(cp);d.id=cp.id;}const keep={id:cp.id,created:cp.created,status:cp.status,sent:cp.sent,by:cp.by};Object.assign(cp,d,keep);cp.discount.uses=(byId("campaigns",cp.id).discount||{}).uses||[];return cp;} function cpSave(){const cp=cpStore();log("Saved campaign "+cp.name);save();closeModal();render();toast("Campaign saved as a draft.");} async function cpTest(){const d=cpRead(),to=S.settings.email,me0={first:me.display.split(" ")[0],last:"",email:to,phone:S.settings.phone,id:"test"},v=campVars(d,me0),subj="[TEST] "+fillMsg(d.subject,v),body=fillMsg(d.body,v)+emailFooter(me0); if(!to){toast("Add the shop email in Admin panel first.");return;} if(serverCaps.mail){const r=await serverMail(to,subj,body);toast(r.ok?"Test sent to "+to+".":"Test failed: "+r.error);}else{location.href="mailto:"+encodeURIComponent(to)+"?subject="+encodeURIComponent(subj)+"&body="+encodeURIComponent(body);}} function cpSend(){const d=cpRead(),r=reach(d);if(!r.em.length&&!r.sm.length){toast("Nobody in this group agreed to marketing yet.");return;}if(d.discount.kind!=="none"&&(!d.discount.code||!(+d.discount.value))){toast("Finish the discount (amount and code) or set it to No discount.");return;} const cp=cpStore();save(); openModal(`

Send "${esc(cp.name)}"

${r.em.length} email${r.em.length===1?"":"s"} and ${r.sm.length} text${r.sm.length===1?"":"s"}.

${r.em.length?(serverCaps.mail?`

Emails go out one by one from the web host, each with the customer's name and an unsubscribe link.

Not started.
` :`

This copy of the system cannot send email by itself (that works on the web-hosted version). Choose one:

The BCC email uses the message without names filled in. The download has one row per customer with the message filled in.

`):""} ${r.sm.length?`

Text messages

Each button opens a text with the message ready on this phone. Press send there, then the next one.

${r.sm.map(c=>`
${esc(cname(c))} ${esc(c.phone)}Open text
`).join("")}`:""}
`);} function cpSmsHref(cpId,cId){const cp=byId("campaigns",cpId),c=cust(cId);return "sms:"+digits(c.phone)+"?&body="+encodeURIComponent(fillMsg(cp.body,campVars(cp,c)).replace(/\n\n+/g," ")+smsFooter);} function cpMark(cpId,cId,ch,status){const cp=byId("campaigns",cpId);if(!cp.sent.some(x=>x.custId===cId&&x.ch===ch))cp.sent.push({custId:cId,ch,at:new Date().toISOString(),status:status||"opened"});cp.status="sent";cp.sentAt=cp.sentAt||new Date().toISOString();const c=cust(cId);c.msgs=c.msgs||[];c.msgs.unshift({at:new Date().toISOString(),ch,what:cp.name});save();} async function cpSendEmails(cpId){const cp=byId("campaigns",cpId),list=reach(cp).em.filter(c=>!cp.sent.some(x=>x.custId===c.id&&x.ch==="email")),p=$("#cp_prog"); if(!confirm("Send "+list.length+" emails now? This cannot be undone."))return;let ok=0,bad=0; for(const c of list){const v=campVars(cp,c),r=await serverMail(c.email,fillMsg(cp.subject,v),fillMsg(cp.body,v)+emailFooter(c),unsubLink(c));if(r.ok){ok++;cpMark(cp.id,c.id,"email","sent");}else{bad++;}if(p)p.textContent=`Sent ${ok} of ${list.length}${bad?", "+bad+" failed":""}...`;} log(`Campaign ${cp.name}: ${ok} emails sent, ${bad} failed`);save();if(p)p.textContent=`Done. ${ok} sent${bad?", "+bad+" failed (see Admin panel, Activity log)":""}.`;} function cpBcc(cpId){const cp=byId("campaigns",cpId),list=reach(cp).em,neutral=Object.assign(campVars(cp,null),{first:"there",vehicle:"car",visits:"many"}); const body=fillMsg(cp.body,neutral)+`\n\n${S.settings.name}\n${S.settings.address}\n${S.settings.phone}\n\nTo stop these emails, reply STOP.`; if(list.length>40)toast("Large lists can be cut off by email apps. The download for Mailchimp or Brevo is safer."); list.forEach(c=>cpMark(cp.id,c.id,"email","bcc"));location.href="mailto:"+encodeURIComponent(S.settings.email||"")+"?bcc="+encodeURIComponent(list.map(c=>c.email).join(","))+"&subject="+encodeURIComponent(fillMsg(cp.subject,neutral))+"&body="+encodeURIComponent(body);} function cpCsv(cpId){const cp=byId("campaigns",cpId),rows=[["email","first","last","subject","message"]].concat(reach(cp).em.map(c=>{const v=campVars(cp,c);return [c.email,c.first,c.last,fillMsg(cp.subject,v),fillMsg(cp.body,v)+emailFooter(c)];})); dl(cp.name.replace(/[^\w ]/g,"")+" email list.csv",new Blob([rows.map(r=>r.map(csvCell).join(",")).join("\n")],{type:"text/csv"}));log("Downloaded email list for "+cp.name);save();} /* ---------- discount codes on estimates and invoices ---------- */ function applyCode(){const code=($("#dc_code").value||"").trim().toUpperCase();if(!code)return;const cp=S.campaigns.find(x=>x.discount&&x.discount.kind!=="none"&&x.discount.code===code); if(!cp){toast("No discount with code "+code+".");return;}const dc=cp.discount,date=$("#dc_d").value||today();if(dc.expires&&date>dc.expires){toast("Code "+code+" ended on "+fmtD(dc.expires)+".");return;} if(lineDraft.some(l=>l.ref==="dc:"+cp.id)){toast("That code is already on this document.");return;} const cid=$("#dc_c").value;if(cid&&cp.discount.uses.some(u=>u.custId===cid)&&!confirm(cname(cust(cid))+" already used this code once. Apply it again?"))return; const base=lineDraft.filter(l=>l.t!=="Discount").reduce((s,l)=>s+(+l.q||0)*(+l.p||0),0);if(+dc.minSpend&&base<+dc.minSpend){toast("This code needs a bill of at least "+money(+dc.minSpend)+".");return;} const amt=dc.kind==="pct"?Math.round(base*(+dc.value))/100:Math.min(base,+dc.value);lineDraft.push({t:"Discount",d:"Code "+code+": "+offerText(dc),q:1,p:-amt,ref:"dc:"+cp.id});$("#dc_code").value="";drawLines();toast("Discount applied: "+money(amt)+".");} function recordCodeUse(d){if(d.type!=="invoice"||d.status==="void")return;d.lines.filter(l=>l.ref&&l.ref.startsWith("dc:")).forEach(l=>{const cp=byId("campaigns",l.ref.slice(3));if(!cp||!cp.discount)return;cp.discount.uses=cp.discount.uses||[];if(!cp.discount.uses.some(u=>u.docId===d.id))cp.discount.uses.push({docId:d.id,custId:d.custId,date:d.date,amount:-l.p});});} /* ---------- connections: email, SSL, API keys, website booking ---------- */ async function serverMail(to,subject,text,unsub){try{const r=await fetch("api/mail",{method:"POST",headers:Object.assign({"Content-Type":"application/json"},apiHeaders()),body:JSON.stringify({to,subject,text,fromName:S.settings.name,replyTo:S.settings.email,unsub:unsub||""})});const j=await r.json().catch(()=>({}));return r.ok&&j.ok?{ok:true}:{ok:false,error:j.error||("server answered "+r.status)};}catch(e){return {ok:false,error:e.message};}} A.connections=()=>{const mode=serverCaps.hosted?"Web host":storageMode==="server"?"Shop computer (portable folder)":"This browser only",https=location.protocol==="https:",keys=S.apiKeys||[]; return `

Where the system runs

Mode: ${esc(mode)}
Encrypted connection (SSL/HTTPS): ${https?'On':serverCaps.hosted?'Off. Turn on SSL for this domain in cPanel':'Not used on the shop network The web-hosted version runs on HTTPS only.'}
Data stored encrypted: ${serverCaps.hosted?'Yes, on the web host':'No (local folder; keep the PC behind a Windows password)'}
Email sending: ${serverCaps.mail?'Ready from the web host':'Through your email app (automatic sending works on the web-hosted version)'}

API for other programs

${serverCaps.api?`

Let another program (website, accounting, a texting service) read data or send booking requests. Each key is shown once; store it in your password manager.

${keys.map(k=>`
${esc(k.label)} ${esc(k.scope)} | ends in ${esc(k.last4)} | made ${fmtD(k.created)}
`).join("")||`

No keys yet.

`}
How to call it
${esc(apiDoc())}
` :`

The API runs on the web-hosted version (HTTPS). This copy does not expose one, which keeps the shop computer closed to the internet.

`}
`;}; function apiDoc(){const base=location.origin+location.pathname.replace(/[^/]*$/,"")+"api/v1/";return `Send the key in a header: Authorization: Bearer YOUR_KEY Read (scope "read"): GET ${base}customers GET ${base}vehicles GET ${base}appointments?from=2026-12-01&to=2026-12-31 GET ${base}jobs GET ${base}invoices GET ${base}parts Booking request from your website (scope "booking"): POST ${base}appointment-requests JSON: {"first":"Jane","last":"Doe","phone":"2015550123","email":"jane@example.com","date":"2026-12-03","time":"10:00","service":"Oil change","vehicle":"2019 Toyota Corolla","notes":""} The request shows up on the Schedule as "Requested" for the front desk to confirm. Limits: 120 calls per hour per key. HTTPS only.`;} async function newApiKey(){const label=$("#ak_l").value.trim()||"API key",scope=$("#ak_s").value,token="qoc_"+rnd(24);S.apiKeys=S.apiKeys||[];S.apiKeys.push({id:uid(),label,scope,hash:sha256js(token),last4:token.slice(-4),created:today()});log("Created API key "+label);save();render(); openModal(`

New API key

Copy it now. It is not shown again.

`);} function revokeKey(id){if(!confirm("Revoke this key? Programs using it stop working right away."))return;S.apiKeys=S.apiKeys.filter(k=>k.id!==id);log("Revoked an API key");save();render();} /* ---------- web host first-time setup ---------- */ /* setupScreen: see the web host module */ (async function boot(){ let data=null; try{ if(await hasServer()){storageMode="server";if(serverCaps.hosted&&serverCaps.setup===false)await setupScreen(); if(serverCaps.sync==="records"){data=await hostLoad();}else{let res=await serverLoad(),msg=""; while(res.needKey){const k=await askKey(msg);localStorage.setItem(SKEY,k);res=await serverLoad();msg="That key did not work. Check the black server window on the shop computer and try again.";} data=res.data;lastStamp=(await serverStamp())||"";}} else{data=await localLoad();} }catch(e){$("#app").innerHTML=``;return;} if(data&&data.v===4&&data.users){S=data;normalize();} else{S=await seed();normalize();await applySetupResult();const old=(data&&data.customers&&!data.v)?data:(storageMode==="local"?oldLocal():null);if(old)migrateOriginal(old);save();} if(S.settings.logoMode==="auto"&&!S.settings.logo){await applyLogo();save();} render();setSync(); })();